Skip to content

Commit 4e7b14e

Browse files
authored
Merge pull request #1054 from codeflash-ai/let's-see-what-we're-sending
display RO / RW context (--verbose)
2 parents 6d3b138 + 803f7ff commit 4e7b14e

4 files changed

Lines changed: 77 additions & 6 deletions

File tree

codeflash/code_utils/config_consts.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from typing import Any, Union
55

66
MAX_TEST_RUN_ITERATIONS = 5
7+
OPTIMIZATION_CONTEXT_TOKEN_LIMIT = 16000
8+
TESTGEN_CONTEXT_TOKEN_LIMIT = 16000
79
INDIVIDUAL_TESTCASE_TIMEOUT = 15
810
MAX_FUNCTION_TEST_SECONDS = 60
911
MIN_IMPROVEMENT_THRESHOLD = 0.05

codeflash/context/code_context_extractor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from codeflash.cli_cmds.console import logger
1313
from codeflash.code_utils.code_extractor import add_needed_imports_from_module, find_preexisting_objects
1414
from codeflash.code_utils.code_utils import encoded_tokens_len, get_qualified_name, path_belongs_to_site_packages
15+
from codeflash.code_utils.config_consts import OPTIMIZATION_CONTEXT_TOKEN_LIMIT, TESTGEN_CONTEXT_TOKEN_LIMIT
1516
from codeflash.context.unused_definition_remover import (
1617
collect_top_level_defs_with_usages,
1718
extract_names_from_targets,
@@ -39,8 +40,8 @@
3940
def get_code_optimization_context(
4041
function_to_optimize: FunctionToOptimize,
4142
project_root_path: Path,
42-
optim_token_limit: int = 16000,
43-
testgen_token_limit: int = 16000,
43+
optim_token_limit: int = OPTIMIZATION_CONTEXT_TOKEN_LIMIT,
44+
testgen_token_limit: int = TESTGEN_CONTEXT_TOKEN_LIMIT,
4445
) -> CodeOptimizationContext:
4546
# Get FunctionSource representation of helpers of FTO
4647
helpers_of_fto_dict, helpers_of_fto_list = get_function_sources_from_jedi(

codeflash/discovery/discover_unit_tests.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def analyze_imports_in_test_file(test_file_path: Path | str, target_functions: s
508508
return True
509509

510510
if analyzer.found_any_target_function:
511-
logger.debug(f"Test file {test_file_path} imports target function: {analyzer.found_qualified_name}")
511+
# logger.debug(f"Test file {test_file_path} imports target function: {analyzer.found_qualified_name}")
512512
return True
513513

514514
# Be conservative with dynamic imports - if __import__ is used and a target function
@@ -517,10 +517,10 @@ def analyze_imports_in_test_file(test_file_path: Path | str, target_functions: s
517517
# Check if any target function name appears as a string literal or direct usage
518518
for target_func in target_functions:
519519
if target_func in source_code:
520-
logger.debug(f"Test file {test_file_path} has dynamic imports and references {target_func}")
520+
# logger.debug(f"Test file {test_file_path} has dynamic imports and references {target_func}")
521521
return True
522522

523-
logger.debug(f"Test file {test_file_path} does not import any target functions.")
523+
# logger.debug(f"Test file {test_file_path} does not import any target functions.")
524524
return False
525525

526526

@@ -540,7 +540,7 @@ def filter_test_files_by_imports(
540540
if not target_functions:
541541
return file_to_test_map
542542

543-
logger.debug(f"Target functions for import filtering: {target_functions}")
543+
# logger.debug(f"Target functions for import filtering: {target_functions}")
544544

545545
filtered_map = {}
546546
for test_file, test_functions in file_to_test_map.items():

codeflash/optimization/function_optimizer.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import ast
44
import concurrent.futures
5+
import logging
56
import os
67
import queue
78
import random
@@ -15,6 +16,7 @@
1516
from rich.console import Group
1617
from rich.panel import Panel
1718
from rich.syntax import Syntax
19+
from rich.text import Text
1820
from rich.tree import Tree
1921

2022
from codeflash.api.aiservice import AiServiceClient, AIServiceRefinerRequest, LocalAiServiceClient
@@ -34,6 +36,7 @@
3436
create_rank_dictionary_compact,
3537
create_score_dictionary_from_metrics,
3638
diff_length,
39+
encoded_tokens_len,
3740
extract_unique_errors,
3841
file_name_from_test_module_name,
3942
get_run_tmp_file,
@@ -46,6 +49,7 @@
4649
COVERAGE_THRESHOLD,
4750
INDIVIDUAL_TESTCASE_TIMEOUT,
4851
MIN_CORRECT_CANDIDATES,
52+
OPTIMIZATION_CONTEXT_TOKEN_LIMIT,
4953
REFINED_CANDIDATE_RANKING_WEIGHTS,
5054
REPEAT_OPTIMIZATION_PROBABILITY,
5155
TOTAL_LOOPING_TIME_EFFECTIVE,
@@ -128,6 +132,69 @@
128132
from codeflash.verification.verification_utils import TestConfig
129133

130134

135+
def log_optimization_context(function_name: str, code_context: CodeOptimizationContext) -> None:
136+
"""Log optimization context details when in verbose mode using Rich formatting."""
137+
if logger.getEffectiveLevel() > logging.DEBUG:
138+
return
139+
140+
console.rule()
141+
read_writable_tokens = encoded_tokens_len(code_context.read_writable_code.markdown)
142+
read_only_tokens = (
143+
encoded_tokens_len(code_context.read_only_context_code) if code_context.read_only_context_code else 0
144+
)
145+
total_tokens = read_writable_tokens + read_only_tokens
146+
token_pct = min(total_tokens / OPTIMIZATION_CONTEXT_TOKEN_LIMIT, 1.0)
147+
148+
# Token bar color based on usage
149+
bar_color = "green" if token_pct < 0.7 else "yellow" if token_pct < 0.9 else "red"
150+
151+
# Build compact info line
152+
helper_names = [hf.qualified_name for hf in code_context.helper_functions]
153+
helpers_str = f"[magenta]{', '.join(helper_names)}[/]" if helper_names else "[dim]none[/]"
154+
read_writable_files = [str(cs.file_path) for cs in code_context.read_writable_code.code_strings]
155+
156+
# Create a tree view for the context
157+
tree = Tree(f"[bold cyan]Context for {function_name}[/]")
158+
tree.add(
159+
Text.assemble(
160+
("Tokens: ", "dim"),
161+
(f"{total_tokens:,}", "bold " + bar_color),
162+
(f"/{OPTIMIZATION_CONTEXT_TOKEN_LIMIT:,} ", "dim"),
163+
(f"({token_pct:.0%})", bar_color),
164+
(" [", "dim"),
165+
(f"{read_writable_tokens:,}", "green"),
166+
(" rw", "dim green"),
167+
(" + ", "dim"),
168+
(f"{read_only_tokens:,}", "yellow"),
169+
(" ro", "dim yellow"),
170+
("]", "dim"),
171+
)
172+
)
173+
tree.add(f"[dim]Helpers:[/] {helpers_str}")
174+
files_branch = tree.add("[dim]Files:[/]")
175+
for f in read_writable_files:
176+
files_branch.add(f"[blue]{f}[/]")
177+
178+
console.print(tree)
179+
180+
console.print(
181+
Panel(
182+
Syntax(code_context.read_writable_code.markdown, "markdown", theme="monokai", word_wrap=True),
183+
title="[green]Read-Writable Code[/]",
184+
border_style="green",
185+
)
186+
)
187+
188+
if code_context.read_only_context_code:
189+
console.print(
190+
Panel(
191+
Syntax(code_context.read_only_context_code, "markdown", theme="monokai", word_wrap=True),
192+
title="[yellow]Read-Only Dependencies[/]",
193+
border_style="yellow",
194+
)
195+
)
196+
197+
131198
class CandidateNode:
132199
__slots__ = ("candidate", "children", "parent")
133200

@@ -409,6 +476,7 @@ def can_be_optimized(self) -> Result[tuple[bool, CodeOptimizationContext, dict[P
409476
if not is_successful(ctx_result):
410477
return Failure(ctx_result.failure())
411478
code_context: CodeOptimizationContext = ctx_result.unwrap()
479+
log_optimization_context(self.function_to_optimize.function_name, code_context)
412480
original_helper_code: dict[Path, str] = {}
413481
helper_function_paths = {hf.file_path for hf in code_context.helper_functions}
414482
for helper_function_path in helper_function_paths:

0 commit comments

Comments
 (0)