makeitwork1 / src /generate_traces.py
Reizxn's picture
Upload folder using huggingface_hub
803b5e8 verified
Raw
History Blame Contribute Delete
59.7 kB
"""
High-quality SFT trace generator for the search agent.
Generates diverse, dense, multi-round search traces that teach the model:
- Complex query decomposition (break big questions into sub-searches)
- Multi-round search refinement (search β†’ analyze β†’ refine β†’ search again)
- Cross-file tracing (find related code across different chunks)
- Dense reasoning (substantive analysis at each step)
- Accurate evidence extraction (grounded in real code)
15 query categories, each with code-aware trace generation:
1. Implementation Deep Dive
2. Cross-File Data Flow Tracing
3. Architecture & Component Mapping
4. Usage Pattern Analysis
5. Error Handling & Failure Paths
6. API Contract & Interface
7. Dependency Graph Mapping
8. Data Structure Analysis
9. Configuration & Parameters
10. Performance-Critical Paths
11. Security & Validation
12. Design Pattern Recognition
13. Debugging Assistance
14. Comparison & Tradeoffs
15. Change Impact Analysis
Usage:
python src/generate_traces.py --category all --count 500 --output data/sft_traces_v2/
python src/generate_traces.py --category implementation --count 200 --seed 42
"""
import argparse
import json
import os
import random
import re
import hashlib
import sys
from collections import defaultdict
from pathlib import Path
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CHUNKS_PATH = os.path.join(PROJECT_DIR, "data", "chunks.jsonl")
OUTPUT_DIR = os.path.join(PROJECT_DIR, "data", "sft_traces_v2")
SYSTEM_PROMPT = (
"You are a code search agent. Given a query from a reasoning model, "
"decompose it into subqueries, search the codebase, inspect results, "
"and return curated evidence. Use <|search|> to issue searches, "
"<|reasoning|> to analyze, and <|evidence|> to return findings. "
"Be concise. Extract only the relevant facts. End with <|finish|>."
)
# ─── Code Analysis Helpers ───────────────────────────────────────────────────
def extract_function_signature(code: str, name: str) -> str:
"""Extract a function signature from code."""
# Try to find the function definition line
lines = code.strip().split('\n')
for i, line in enumerate(lines):
if name in line and ('def ' in line or 'fn ' in line or 'function ' in line
or '(' in line and ('{' in line or ';' in line or ':' in line)):
# Collect signature lines until we hit the body
sig_lines = [line]
for j in range(i+1, min(i+5, len(lines))):
if lines[j].strip() == '' or lines[j].strip().startswith('{') or lines[j].strip().startswith('}'):
break
if '(' in lines[j] or ')' in lines[j] or ',' in lines[j]:
sig_lines.append(lines[j])
else:
break
return ' '.join(s.strip() for s in sig_lines)
return lines[0].strip() if lines else code[:100]
def extract_struct_fields(code: str) -> list[str]:
"""Extract field names from a struct/class definition."""
fields = []
for line in code.split('\n'):
line = line.strip()
# Skip braces, comments, preprocessor
if not line or line in ('{', '}', '};') or line.startswith('//') or line.startswith('#') or line.startswith('/*'):
continue
# Try to extract field name
# C/C++/Rust: type name; or type *name;
m = re.match(r'(?:static\s+)?(?:const\s+)?(?:unsigned\s+|signed\s+)?[\w_*]+\s+(\w+)\s*[;\[\{=]', line)
if m:
fields.append(m.group(1))
# Python: self.name = ... or name: type = ...
m = re.match(r'(?:self\.)?(\w+)\s*[:=]', line)
if m and m.group(1) not in fields:
fields.append(m.group(1))
return fields[:15] # Limit to 15 fields
def extract_function_calls(code: str) -> list[str]:
"""Extract function call names from code."""
calls = re.findall(r'\b([a-z_][a-z0-9_]*)\s*\(', code)
# Filter out keywords
keywords = {'if', 'for', 'while', 'switch', 'return', 'sizeof', 'typeof',
'def', 'class', 'struct', 'enum', 'union', 'case', 'catch',
'print', 'println', 'printf', 'let', 'var', 'const', 'fn'}
return [c for c in calls if c not in keywords][:10]
def extract_keywords_from_code(code: str) -> list[str]:
"""Extract searchable keywords from code."""
tokens = re.findall(r'[a-z_][a-z0-9_]*', code.lower())
# Filter common words
stop = {'the', 'for', 'and', 'not', 'this', 'self', 'that', 'with', 'from',
'into', 'void', 'int', 'char', 'bool', 'true', 'false', 'null',
'none', 'return', 'if', 'else', 'elif', 'while', 'break', 'continue',
'const', 'static', 'struct', 'class', 'def', 'fn', 'let', 'var',
'true', 'false', 'size', 'len', 'type', 'name', 'value', 'key',
'data', 'result', 'error', 'status', 'count', 'index', 'ptr',
'begin', 'end', 'start', 'stop', 'init', 'free', 'alloc'}
meaningful = [t for t in tokens if t not in stop and len(t) > 2]
# Deduplicate, preserve order
seen = set()
unique = []
for t in meaningful:
if t not in seen:
seen.add(t)
unique.append(t)
return unique[:8]
def extract_return_statements(code: str) -> list[str]:
"""Extract return statements from code."""
returns = []
for line in code.split('\n'):
line = line.strip()
if line.startswith('return ') or line == 'return;' or line.startswith('return('):
returns.append(line)
return returns[:5]
def extract_error_handling(code: str) -> list[str]:
"""Extract error handling patterns from code."""
patterns = []
for line in code.split('\n'):
line = line.strip()
if any(kw in line for kw in ['NGX_ERROR', 'NGX_AGAIN', 'NGX_DECLINED', 'throw ',
'raise ', 'panic!', 'unwrap()', 'expect(',
'errno', 'error', 'Error', 'ERR_', 'FAIL',
'assert', 'TORCH_CHECK', 'TORCH_ASSERT']):
patterns.append(line)
return patterns[:5]
def extract_imports_refs(code: str) -> list[str]:
"""Extract imported/referenced names from code."""
refs = []
for line in code.split('\n'):
line = line.strip()
if line.startswith('#include') or line.startswith('import ') or line.startswith('use '):
refs.append(line)
elif line.startswith('from ') and 'import' in line:
refs.append(line)
return refs[:5]
def summarize_code_briefly(code: str, name: str, lang: str, typ: str) -> str:
"""Generate a brief summary of what a code chunk does."""
lines = code.strip().split('\n')
first_line = lines[0].strip() if lines else ""
if typ == 'struct':
fields = extract_struct_fields(code)
if fields:
return f"a {lang} {typ} with {len(fields)} fields: {', '.join(fields[:6])}"
return f"a {lang} {typ} definition"
elif typ == 'function':
sig = extract_function_signature(code, name)
returns = extract_return_statements(code)
calls = extract_function_calls(code)
parts = [f"a {lang} function"]
if calls:
parts.append(f"that calls {', '.join(calls[:3])}")
if returns:
parts.append(f"returns: {returns[0]}")
return ' '.join(parts)
elif typ == 'class':
return f"a {lang} class definition for {name}"
elif typ == 'macro':
return f"a {lang} macro: {first_line[:60]}"
elif typ == 'enum':
return f"a {lang} enum definition"
else:
return f"a {lang} code block ({len(lines)} lines)"
# ─── Trace Format ─────────────────────────────────────────────────────────────
def make_trace(query: str, assistant_turns: list[dict]) -> dict:
"""Build a trace in the SFT format.
assistant_turns: list of dicts with 'content' (assistant text) and optional 'result' (code from retrieval)
"""
trace = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": query},
]
for turn in assistant_turns:
trace.append({"role": "assistant", "content": turn["content"]})
if "result" in turn and turn["result"]:
trace.append({"role": "result", "content": turn["result"]})
return {"query": query, "trace": trace}
# ─── Query Categories ─────────────────────────────────────────────────────────
def gen_implementation_deep_dive(chunks, rng) -> dict:
"""Category 1: Deep dive into how something is implemented."""
# Pick a function with substantial code
candidates = [c for c in chunks if c['type'] == 'function' and len(c['code']) > 200 and c['name'] not in ('unknown','struct','void')]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
lang = chunk['language']
code = chunk['code']
calls = extract_function_calls(code)
returns = extract_return_statements(code)
keywords = extract_keywords_from_code(code)
summary = summarize_code_briefly(code, name, lang, chunk['type'])
# Complex query
query_templates = [
f"Walk me through the implementation of {name}. What are the key steps, what functions does it call, and what does it return?",
f"Explain how {name} works in detail. What is the control flow and what are the important operations it performs?",
f"I need to understand the implementation of {name}. Break down what it does step by step, including any helper functions it relies on.",
f"Analyze the {name} function. What is its purpose, how does it achieve it, and what are the edge cases it handles?",
f"Give me a thorough breakdown of {name}. What does it do, what does it call, and what are the return paths?",
]
query = rng.choice(query_templates)
# Round 1: Search for the function
search_term = name if len(name) > 3 else keywords[0] if keywords else name
reasoning1 = rng.choice([
f"<|reasoning|>The user wants a detailed implementation walkthrough of {name}. I need to find the function definition first, then analyze its body to understand the control flow, function calls, and return values. Let me start by searching for the function itself.<|end|>",
f"<|reasoning|>This is a deep implementation question about {name}. I should first locate the function, then trace through its logic step by step. Let me search for it.<|end|>",
f"<|reasoning|>To explain how {name} works, I need to find its definition and examine the code. The key things to look for are: the function signature, the main logic flow, any helper function calls, and the return statements. Let me search for it.<|end|>",
])
turn1 = {
"content": f"{reasoning1}\n<|search|>{search_term}<|end|>",
"result": code[:600],
}
# Round 2: Search for a related function (one that it calls)
related_search = calls[0] if calls else keywords[0] if keywords else search_term
reasoning2 = rng.choice([
f"<|reasoning|>I found the {name} function. It's {summary}. The function calls {', '.join(calls[:3]) if calls else 'several helpers'}. Let me search for one of these called functions to understand the full call chain.<|end|>",
f"<|reasoning|>Found {name}. Looking at the code, it performs several operations and calls {calls[0] if calls else 'helper functions'}. To give a complete picture, I should also look at what {calls[0] if calls else 'these helpers'} do. Let me search for that.<|end|>",
f"<|reasoning|>The implementation of {name} is now visible. It's {summary}. The key operations involve calling {calls[0] if calls else 'internal helpers'}. Let me find that to complete the picture.<|end|>",
])
# Find a related chunk for the result
related_chunks = [c for c in chunks if related_search.lower() in c['name'].lower() and c['name'] != name]
related_result = related_chunks[0]['code'][:400] if related_chunks else ""
turn2 = {
"content": f"{reasoning2}\n<|search|>{related_search}<|end|>",
"result": related_result,
}
# Round 3: Evidence
evidence_parts = [f"`{name}` is {summary}."]
if calls:
evidence_parts.append(f"Key operations: calls {', '.join(calls[:4])}")
if returns:
evidence_parts.append(f"Return paths: {'; '.join(returns[:3])}")
evidence_parts.append(f"Source: {chunk['filepath']}")
evidence = f"<|reasoning|>Now I have a complete picture of {name}. I found the main function and a related helper. Let me compile the evidence.<|end|>\n<|evidence|>{' '.join(evidence_parts)}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_cross_file_tracing(chunks, rng) -> dict:
"""Category 2: Trace data flow across multiple files."""
# Pick two related chunks (same language, different names)
by_lang = defaultdict(list)
for c in chunks:
if c['type'] in ('function', 'struct', 'class') and c['name'] not in ('unknown','struct','void','T'):
by_lang[c['language']].append(c)
lang = rng.choice(list(by_lang.keys()))
candidates = by_lang[lang]
if len(candidates) < 2:
return None
chunk1, chunk2 = rng.sample(candidates, 2)
name1, name2 = chunk1['name'], chunk2['name']
query = rng.choice([
f"Trace how data flows from {name1} to {name2}. What transformations happen along the way?",
f"How do {name1} and {name2} interact? What data passes between them and how is it processed?",
f"Follow the data path from {name1} through {name2}. What are the intermediate steps and transformations?",
f"I need to understand the relationship between {name1} and {name2}. How does data move between them?",
])
# Round 1: Search for first component
reasoning1 = f"<|reasoning|>The user wants to understand data flow between {name1} and {name2}. I need to find both components and understand how they connect. Let me start by finding {name1}.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name1}<|end|>", "result": chunk1['code'][:500]}
# Round 2: Search for second component
reasoning2 = f"<|reasoning|>Found {name1}. Now I need to find {name2} to understand how data flows from the first to the second. Let me search for it.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name2}<|end|>", "result": chunk2['code'][:500]}
# Round 3: Evidence
summary1 = summarize_code_briefly(chunk1['code'], name1, lang, chunk1['type'])
summary2 = summarize_code_briefly(chunk2['code'], name2, lang, chunk2['type'])
evidence = f"<|reasoning|>I now have both components. {name1} is {summary1}, and {name2} is {summary2}. The data flow goes from {name1} producing output that {name2} consumes. Let me compile the evidence.<|end|>\n<|evidence|>Data flow: {name1} ({chunk1['type']}) β†’ {name2} ({chunk2['type']}). {name1} is {summary1}. {name2} is {summary2}. They are both in {lang} code. Source: {chunk1['filepath']}, {chunk2['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_architecture_mapping(chunks, rng) -> dict:
"""Category 3: Understand the architecture of a subsystem."""
# Pick chunks from the same filepath (same "module")
by_path = defaultdict(list)
for c in chunks:
if c['name'] not in ('unknown','struct','void','T'):
by_path[c['filepath']].append(c)
# Find a filepath with multiple chunks
good_paths = [p for p, cs in by_path.items() if len(cs) >= 3]
if not good_paths:
return None
filepath = rng.choice(good_paths)
module_chunks = by_path[filepath]
names = [c['name'] for c in module_chunks[:5]]
query = rng.choice([
f"What is the architecture of the module in {filepath}? What are the main components and how do they fit together?",
f"Map out the structure of {filepath}. What are the key types and functions, and how do they interact?",
f"I need to understand the overall design of the code in {filepath}. What are the main pieces and their roles?",
f"Describe the architecture of the subsystem defined in {filepath}. What patterns does it use and how is it organized?",
])
# Round 1: Search for the module
search_term = filepath.split('/')[-1].replace('.txt','')
reasoning1 = f"<|reasoning|>The user wants to understand the architecture of a module. I need to find the components in this file and understand how they relate. Let me search for the main types and functions. I can see there are several: {', '.join(names[:3])}. Let me start with the first one.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{names[0]}<|end|>", "result": module_chunks[0]['code'][:400]}
# Round 2: Search for another component
if len(names) > 1:
reasoning2 = f"<|reasoning|>Found {names[0]}. Now let me find {names[1]} to understand how these components interact within the module.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{names[1]}<|end|>", "result": module_chunks[1]['code'][:400] if len(module_chunks) > 1 else ""}
else:
reasoning2 = f"<|reasoning|>Found {names[0]}. Let me search for more components in this module.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{search_term}<|end|>", "result": module_chunks[0]['code'][:300]}
# Round 3: Evidence
components_desc = ', '.join(f"{c['type']} {c['name']}" for c in module_chunks[:4])
evidence = f"<|reasoning|>I now have a good picture of the module. It contains several components: {components_desc}. Let me compile the architectural overview.<|end|>\n<|evidence|>Module: {filepath}\nComponents: {components_desc}\nArchitecture: The module is organized around {module_chunks[0]['type']} {names[0]} as the primary component, supported by {', '.join(names[1:3])}. The code is in {module_chunks[0]['language']}.<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_usage_analysis(chunks, rng) -> dict:
"""Category 4: Where and how is something used."""
# Pick a function or class name that might be used in multiple places
candidates = [c for c in chunks if c['type'] in ('function', 'class', 'macro') and c['name'] not in ('unknown','struct','void','T') and len(c['name']) > 3]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
# Find chunks that reference this name
referencing = [c for c in chunks if name in c['code'] and c['name'] != name]
if not referencing:
return None
query = rng.choice([
f"Where is {name} used across the codebase? What patterns emerge from its usage?",
f"Find all the places where {name} is called or referenced. What are the different usage contexts?",
f"How is {name} utilized throughout the code? What are the common calling patterns?",
f"Map the usage of {name}. Where is it called from and what are the typical arguments?",
])
# Round 1: Search for the definition
reasoning1 = f"<|reasoning|>The user wants to understand how {name} is used across the codebase. I should first find its definition, then search for places where it's called. Let me start with the definition.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:400]}
# Round 2: Search for usage in a different file
usage_chunk = referencing[0]
reasoning2 = f"<|reasoning|>Found the definition of {name}. Now I need to find where it's used. Let me search for it in the context of other code that references it.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name} {usage_chunk['name']}<|end|>", "result": usage_chunk['code'][:400]}
# Round 3: Evidence
usage_count = len(referencing)
evidence = f"<|reasoning|>I found the definition and at least one usage site. {name} is referenced in approximately {usage_count} other chunks. Let me compile the usage analysis.<|end|>\n<|evidence|>`{name}` is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}. It is used in approximately {usage_count} other locations. One usage is in {usage_chunk['filepath']} where it appears alongside {usage_chunk['name']}. The usage pattern shows it is called as part of {usage_chunk['type']} operations.<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_error_handling(chunks, rng) -> dict:
"""Category 5: Error handling and failure paths."""
# Find chunks with error handling patterns
candidates = [c for c in chunks if any(kw in c['code'] for kw in
['NGX_ERROR', 'NGX_AGAIN', 'throw ', 'raise ', 'panic!', 'unwrap()',
'TORCH_CHECK', 'TORCH_ASSERT', 'assert', 'errno', 'Error']) and c['name'] not in ('unknown','struct','void')]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
error_patterns = extract_error_handling(chunk['code'])
if not error_patterns:
return None
query = rng.choice([
f"How does {name} handle errors? What are all the failure paths and error conditions?",
f"What error handling does {name} implement? What happens when things go wrong?",
f"Analyze the error handling strategy in {name}. What conditions cause failures and how are they reported?",
f"What are the failure modes of {name}? How does it detect and respond to errors?",
])
# Round 1: Search for the function
reasoning1 = f"<|reasoning|>The user wants to understand error handling in {name}. I need to find the function and look for error checking patterns, return codes, and exception handling. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 2: Search for error-related patterns
error_keyword = error_patterns[0].split()[0] if error_patterns else name
error_search = re.search(r'[A-Za-z_]+', error_patterns[0])
search_term2 = error_search.group(0) if error_search else name
reasoning2 = f"<|reasoning|>Found {name}. I can see it uses error handling patterns like {error_patterns[0][:60]}. Let me search for more context on this error pattern to understand the full error handling strategy.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{search_term2}<|end|>", "result": error_patterns[0][:200] if error_patterns else ""}
# Round 3: Evidence
error_summary = '; '.join(e[:80] for e in error_patterns[:3])
evidence = f"<|reasoning|>I now have a clear picture of the error handling in {name}. The function uses multiple error checks and return paths. Let me compile the evidence.<|end|>\n<|evidence|>`{name}` handles errors through: {error_summary}. The error handling strategy involves checking return values and propagating errors using {error_patterns[0].split('(')[0].strip() if error_patterns else 'standard patterns'}. Source: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_api_contract(chunks, rng) -> dict:
"""Category 6: API contract and interface."""
candidates = [c for c in chunks if c['type'] in ('function', 'class', 'struct') and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 100]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
sig = extract_function_signature(chunk['code'], name)
query = rng.choice([
f"What is the API contract of {name}? What are the preconditions, postconditions, and expected inputs/outputs?",
f"Describe the interface of {name}. What parameters does it take, what does it return, and what are the constraints?",
f"What is the public API of {name}? What are the input requirements and output guarantees?",
f"Explain the contract that {name} exposes. What does it expect from callers and what does it promise in return?",
])
reasoning1 = f"<|reasoning|>The user wants to understand the API contract of {name}. I need to find its signature, understand the parameters, and identify any preconditions or postconditions. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 2: Search for related types
keywords = extract_keywords_from_code(chunk['code'])
related = keywords[0] if keywords else name
reasoning2 = f"<|reasoning|>Found {name}. The signature is: {sig[:80]}. I should also check if there are related types or constants that are part of the API contract. Let me search for {related}.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{related}<|end|>", "result": ""}
# Round 3: Evidence
returns = extract_return_statements(chunk['code'])
evidence = f"<|reasoning|>I have the full API picture now. The function signature, parameters, and return values are clear. Let me compile the contract.<|end|>\n<|evidence|>API: `{name}`\nSignature: {sig[:100]}\nType: {chunk['type']} in {chunk['language']}\nReturns: {returns[0] if returns else 'see implementation'}\nPreconditions: Input parameters must be valid for {chunk['language']} {chunk['type']} operations.\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_dependency_graph(chunks, rng) -> dict:
"""Category 7: Dependency graph mapping."""
candidates = [c for c in chunks if c['type'] in ('function', 'class', 'struct') and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 150]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
calls = extract_function_calls(chunk['code'])
imports = extract_imports_refs(chunk['code'])
if not calls and not imports:
return None
query = rng.choice([
f"What does {name} depend on? Map the dependency graph of everything it calls or references.",
f"Trace the dependencies of {name}. What functions, types, or modules does it rely on?",
f"Build a dependency tree for {name}. What are its direct and indirect dependencies?",
f"What are the dependencies of {name}? What would need to be available for it to work?",
])
reasoning1 = f"<|reasoning|>The user wants to map the dependency graph of {name}. I need to find the function and identify everything it calls or references. Let me search for it first.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 2: Search for a dependency
dep = calls[0] if calls else (imports[0].split()[-1] if imports else name)
reasoning2 = f"<|reasoning|>Found {name}. It depends on: {', '.join(calls[:3]) if calls else 'several internal functions'}. Let me search for one of these dependencies to understand the full graph.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{dep}<|end|>", "result": ""}
# Round 3: Evidence
deps_list = ', '.join(calls[:5]) if calls else 'internal helpers only'
evidence = f"<|reasoning|>I now have the dependency picture. {name} calls several functions that form its dependency graph. Let me compile the full mapping.<|end|>\n<|evidence|>Dependency graph for `{name}`:\nDirect dependencies: {deps_list}\n{'Imports: ' + '; '.join(imports[:2]) if imports else ''}\nThe function is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}.\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_data_structure_analysis(chunks, rng) -> dict:
"""Category 8: Data structure analysis."""
candidates = [c for c in chunks if c['type'] in ('struct', 'class', 'enum') and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 100]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
fields = extract_struct_fields(chunk['code'])
if not fields:
return None
query = rng.choice([
f"What data structures does {name} use? Analyze the fields, their types, and the memory layout.",
f"Break down the {name} data structure. What fields does it have, what are their types, and what is each used for?",
f"Analyze the {name} structure. What is its layout, what fields does it contain, and what are the relationships between them?",
f"Examine the {name} data type. What are its components and how is it organized in memory?",
])
reasoning1 = f"<|reasoning|>The user wants a detailed analysis of the {name} data structure. I need to find its definition and examine all fields, their types, and how they're laid out. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 2: Search for a field type
field_to_search = fields[0] if fields else name
reasoning2 = f"<|reasoning|>Found {name}. It has {len(fields)} fields: {', '.join(fields[:6])}. Let me search for one of these field names to understand what type it is and how it's used elsewhere.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{field_to_search}<|end|>", "result": ""}
# Round 3: Evidence
evidence = f"<|reasoning|>I now have a complete picture of the {name} data structure. It contains {len(fields)} fields with various types. Let me compile the analysis.<|end|>\n<|evidence|>`{name}` is a {chunk['language']} {chunk['type']} with {len(fields)} fields:\n{chr(10).join(f'- `{f}`' for f in fields[:10])}\nThe structure is defined in {chunk['filepath']}. It is a {chunk['language']} {chunk['type']} used for organizing related data.<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_configuration_params(chunks, rng) -> dict:
"""Category 9: Configuration and parameters."""
candidates = [c for c in chunks if c['type'] in ('macro', 'function', 'struct') and c['name'] not in ('unknown','struct','void','T') and
any(kw in c['code'].lower() for kw in ['config', 'param', 'option', 'setting', 'default', 'enable', 'disable'])]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
query = rng.choice([
f"What configuration options are available for {name}? How do the parameters interact?",
f"Explain the parameters and configuration of {name}. What can be tuned and what are the defaults?",
f"What settings does {name} expose? What are the configuration knobs and their effects?",
f"Describe the configuration parameters for {name}. What options are available and how do they affect behavior?",
])
reasoning1 = f"<|reasoning|>The user wants to understand the configuration options for {name}. I need to find the definition and look for parameters, defaults, and configuration-related code. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
keywords = extract_keywords_from_code(chunk['code'])
related = keywords[0] if keywords else name
reasoning2 = f"<|reasoning|>Found {name}. I can see configuration-related code. Let me search for related configuration patterns to understand the full parameter space.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{related} config<|end|>", "result": ""}
evidence = f"<|reasoning|>I now have a good understanding of the configuration for {name}. Let me compile the parameter analysis.<|end|>\n<|evidence|>`{name}` is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}. Configuration is controlled through code-level parameters and compile-time options. The key configuration aspects are visible in the source at {chunk['filepath']}.<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_performance_paths(chunks, rng) -> dict:
"""Category 10: Performance-critical paths."""
candidates = [c for c in chunks if c['type'] == 'function' and len(c['code']) > 200 and c['name'] not in ('unknown','struct','void','T') and
any(kw in c['code'].lower() for kw in ['loop', 'for', 'while', 'iter', 'batch', 'cache', 'buffer', 'alloc', 'pool'])]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
query = rng.choice([
f"What are the performance-critical paths in {name}? Where are the potential bottlenecks?",
f"Analyze the performance characteristics of {name}. What operations are hot paths and where could bottlenecks occur?",
f"Identify the performance-sensitive operations in {name}. What loops, allocations, or I/O could be bottlenecks?",
f"Where are the performance hot spots in {name}? What should be optimized for better throughput?",
])
reasoning1 = f"<|reasoning|>The user wants a performance analysis of {name}. I need to look for loops, memory allocations, I/O operations, and other performance-critical patterns. Let me find the function first.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
keywords = extract_keywords_from_code(chunk['code'])
perf_keyword = next((k for k in keywords if any(p in k for p in ['loop', 'iter', 'cache', 'buffer', 'alloc', 'pool', 'batch'])), keywords[0] if keywords else name)
reasoning2 = f"<|reasoning|>Found {name}. I can see performance-relevant patterns. Let me search for related performance patterns to understand the full picture.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{perf_keyword}<|end|>", "result": ""}
evidence = f"<|reasoning|>I've analyzed the performance characteristics. The function has several performance-sensitive areas. Let me compile the analysis.<|end|>\n<|evidence|>Performance analysis of `{name}`:\n- The function is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}\n- Performance-critical patterns: loops, memory operations, and data processing\n- Potential bottlenecks: iteration over data structures and memory allocation patterns\n- Optimization opportunities: caching intermediate results and reducing allocations\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_security_validation(chunks, rng) -> dict:
"""Category 11: Security and validation."""
candidates = [c for c in chunks if c['name'] not in ('unknown','struct','void','T') and
any(kw in c['code'].lower() for kw in ['valid', 'check', 'verify', 'auth', 'sanitiz', 'escape', 'bound', 'limit', 'overflow', 'secure'])]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
query = rng.choice([
f"What security considerations are in {name}? What validation and sanitization does it perform?",
f"Analyze the security posture of {name}. What checks does it do and what could go wrong?",
f"What validation does {name} perform? Are there any potential security issues with its input handling?",
f"Review {name} for security. What protections are in place and what attack surfaces exist?",
])
reasoning1 = f"<|reasoning|>The user wants a security review of {name}. I need to look for input validation, bounds checking, sanitization, and any potential vulnerabilities. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
keywords = extract_keywords_from_code(chunk['code'])
sec_keyword = next((k for k in keywords if any(s in k for s in ['valid', 'check', 'verify', 'bound', 'limit', 'secure'])), keywords[0] if keywords else name)
reasoning2 = f"<|reasoning|>Found {name}. I can see validation and security-related code. Let me search for related validation patterns to understand the full security posture.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{sec_keyword}<|end|>", "result": ""}
evidence = f"<|reasoning|>I've reviewed the security aspects of {name}. The function includes validation and checking mechanisms. Let me compile the security analysis.<|end|>\n<|evidence|>Security review of `{name}`:\n- The function is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}\n- Validation: performs input checks and boundary validation\n- Security measures: includes guards against invalid inputs and error conditions\n- Potential concerns: ensure all input paths are validated before use\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_design_patterns(chunks, rng) -> dict:
"""Category 12: Design pattern recognition."""
candidates = [c for c in chunks if c['type'] in ('class', 'struct', 'impl') and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 150]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
query = rng.choice([
f"What design patterns are used in {name}? How do they structure the code?",
f"Identify the software design patterns present in {name}. What architectural decisions do they reflect?",
f"What patterns does {name} implement? How do they contribute to the code's structure and extensibility?",
f"Analyze {name} from a design pattern perspective. What patterns are in use and why?",
])
reasoning1 = f"<|reasoning|>The user wants to identify design patterns in {name}. I need to find the code and look for structural patterns like factories, singletons, observers, builders, etc. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
keywords = extract_keywords_from_code(chunk['code'])
reasoning2 = f"<|reasoning|>Found {name}. Looking at the structure, I can see it uses {chunk['type']}-based organization. Let me search for related patterns to confirm my analysis.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{keywords[0] if keywords else name}<|end|>", "result": ""}
evidence = f"<|reasoning|>I've analyzed the design patterns in {name}. The code structure reveals specific architectural choices. Let me compile the pattern analysis.<|end|>\n<|evidence|>Design patterns in `{name}`:\n- Primary pattern: {chunk['type']}-based abstraction with encapsulated state and behavior\n- The {chunk['language']} {chunk['type']} organizes related data and methods into a cohesive unit\n- This follows the object-oriented/encapsulation pattern common in {chunk['language']} codebases\n- The structure supports extensibility through its organized interface\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_debugging_assistance(chunks, rng) -> dict:
"""Category 13: Debugging assistance."""
candidates = [c for c in chunks if c['type'] == 'function' and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 150]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
error_patterns = extract_error_handling(chunk['code'])
returns = extract_return_statements(chunk['code'])
query = rng.choice([
f"If {name} is failing unexpectedly, what are the likely causes and how would I debug it?",
f"I'm getting an error from {name}. What are the common failure modes and how can I diagnose them?",
f"What could go wrong when calling {name}? Help me understand the failure scenarios and debugging steps.",
f"Debug {name}: what are the error conditions, what symptoms would they produce, and how can I trace them?",
])
reasoning1 = f"<|reasoning|>The user needs debugging help with {name}. I should find the function and look for error conditions, return codes, and potential failure points. Let me search for it.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 2: Search for error patterns
if error_patterns:
err_term = re.search(r'[A-Za-z_][A-Za-z0-9_]+', error_patterns[0])
search2 = err_term.group(0) if err_term else name
else:
search2 = name + " error"
reasoning2 = f"<|reasoning|>Found {name}. I can see {'error handling code with patterns like ' + error_patterns[0][:50] if error_patterns else 'the function logic'}. Let me search for the error pattern to understand common failure modes.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{search2}<|end|>", "result": ""}
evidence = f"<|reasoning|>I've identified the failure modes and debugging approach for {name}. Let me compile the debugging guide.<|end|>\n<|evidence|>Debugging `{name}`:\n- Common failure modes: {', '.join(e[:60] for e in error_patterns[:3]) if error_patterns else 'unexpected return values'}\n- Return paths: {', '.join(r[:40] for r in returns[:3]) if returns else 'standard returns'}\n- Debugging steps: 1) Check input parameters are valid 2) Verify return values match expectations 3) Look for error conditions in the code\n- The function is {summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])}\nSource: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_comparison_tradeoffs(chunks, rng) -> dict:
"""Category 14: Comparison and tradeoffs."""
by_lang = defaultdict(list)
for c in chunks:
if c['type'] in ('function', 'struct', 'class') and c['name'] not in ('unknown','struct','void','T'):
by_lang[c['language']].append(c)
lang = rng.choice([l for l, cs in by_lang.items() if len(cs) >= 2])
candidates = by_lang[lang]
if len(candidates) < 2:
return None
chunk1, chunk2 = rng.sample(candidates, 2)
name1, name2 = chunk1['name'], chunk2['name']
query = rng.choice([
f"How do {name1} and {name2} compare? What are the tradeoffs between them?",
f"Compare {name1} vs {name2}. What are the differences in approach, performance, and use cases?",
f"What are the tradeoffs between {name1} and {name2}? When would you choose one over the other?",
f"Contrast {name1} and {name2}. What are the key differences and when should each be used?",
])
reasoning1 = f"<|reasoning|>The user wants a comparison between {name1} and {name2}. I need to find both and analyze their differences, similarities, and tradeoffs. Let me start with {name1}.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name1}<|end|>", "result": chunk1['code'][:400]}
reasoning2 = f"<|reasoning|>Found {name1}. Now let me find {name2} so I can compare their approaches and characteristics.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name2}<|end|>", "result": chunk2['code'][:400]}
summary1 = summarize_code_briefly(chunk1['code'], name1, lang, chunk1['type'])
summary2 = summarize_code_briefly(chunk2['code'], name2, lang, chunk2['type'])
evidence = f"<|reasoning|>I now have both components. {name1} is {summary1}, while {name2} is {summary2}. They serve different purposes within the {lang} codebase. Let me compile the comparison.<|end|>\n<|evidence|>Comparison: `{name1}` vs `{name2}`\n{name1}: {summary1}. Located in {chunk1['filepath']}.\n{name2}: {summary2}. Located in {chunk2['filepath']}.\nKey difference: {name1} is a {chunk1['type']} while {name2} is a {chunk2['type']}, serving different roles in the {lang} codebase.\nTradeoff: Use {name1} for {chunk1['type']}-specific operations and {name2} for {chunk2['type']}-specific operations.<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
def gen_change_impact(chunks, rng) -> dict:
"""Category 15: Change impact analysis."""
candidates = [c for c in chunks if c['type'] in ('function', 'class', 'struct') and c['name'] not in ('unknown','struct','void','T') and len(c['name']) > 3]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
# Find referencing chunks
referencing = [c for c in chunks if name in c['code'] and c['name'] != name]
query = rng.choice([
f"If I need to modify {name}, what files and functions would be affected? Map the blast radius.",
f"What is the impact of changing {name}? What depends on it and what could break?",
f"I want to change the behavior of {name}. What else in the codebase would need to be updated?",
f"Analyze the change impact of modifying {name}. What are all the affected components?",
])
reasoning1 = f"<|reasoning|>The user wants to understand the impact of changing {name}. I need to find the definition and then search for all places that reference it. Let me start with the definition.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name}<|end|>", "result": chunk['code'][:400]}
# Round 2: Search for usage
if referencing:
ref_chunk = referencing[0]
reasoning2 = f"<|reasoning|>Found {name}. Now I need to find all the places that reference it to understand the blast radius. I found at least one reference in {ref_chunk['name']}. Let me search for more.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name} {ref_chunk['name']}<|end|>", "result": ref_chunk['code'][:300]}
else:
reasoning2 = f"<|reasoning|>Found {name}. Let me search for references to understand the impact radius.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name} usage<|end|>", "result": ""}
# Round 3: Evidence
impact_count = len(referencing)
affected_files = list(set(c['filepath'] for c in referencing[:5]))
evidence = f"<|reasoning|>I've mapped the change impact. {name} is referenced in approximately {impact_count} other locations. Changing it would affect multiple components. Let me compile the impact analysis.<|end|>\n<|evidence|>Change impact for `{name}`:\n- Definition: {chunk['type']} in {chunk['filepath']}\n- Referenced by: ~{impact_count} other chunks across {len(affected_files)} files\n- Affected files: {', '.join(affected_files[:3])}\n- Risk level: {'HIGH' if impact_count > 5 else 'MEDIUM' if impact_count > 2 else 'LOW'} β€” {impact_count} dependent components would need review\n- Recommendation: Update all callers and verify return value compatibility<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
# ─── Multi-Round Complex Traces (4-5 rounds) ──────────────────────────────────
def gen_complex_multi_step(chunks, rng) -> dict:
"""Generate a complex 4-5 round trace with multiple searches and refinements."""
by_lang = defaultdict(list)
for c in chunks:
if c['type'] in ('function', 'struct', 'class') and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 100:
by_lang[c['language']].append(c)
lang = rng.choice([l for l, cs in by_lang.items() if len(cs) >= 3])
candidates = by_lang[lang]
chunk1 = rng.choice(candidates)
name1 = chunk1['name']
# Find related chunks
related = [c for c in candidates if name1 in c['code'] or any(k in c['code'] for k in extract_keywords_from_code(chunk1['code'])[:3])]
related = [c for c in related if c['name'] != name1][:2]
if not related:
return None
chunk2, chunk3 = related[0], related[-1] if len(related) > 1 else related[0]
name2, name3 = chunk2['name'], chunk3['name']
query = rng.choice([
f"I need a comprehensive analysis of how {name1} works, including its relationship with {name2} and the broader system context. Walk me through the full picture.",
f"Give me a deep analysis of {name1}, its interaction with {name2}, and how they fit into the larger architecture. I need to understand the complete workflow.",
f"Analyze the {name1} subsystem: how it works, how it connects to {name2}, and what the overall data flow looks like. Be thorough.",
f"I need to understand {name1} end-to-end: its implementation, its relationship to {name2}, and its role in the system. Provide a complete breakdown.",
])
# Round 1: Initial search
reasoning1 = f"<|reasoning|>This is a complex multi-part query. I need to: 1) Find and understand {name1}, 2) Find {name2} and understand the relationship, 3) Map the broader system context. Let me start with {name1}.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{name1}<|end|>", "result": chunk1['code'][:500]}
# Round 2: Search for related component
reasoning2 = f"<|reasoning|>Found {name1}. It's {summarize_code_briefly(chunk1['code'], name1, lang, chunk1['type'])}. Now I need to find {name2} to understand how they interact. The relationship could be through function calls, shared data structures, or common interfaces.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name2}<|end|>", "result": chunk2['code'][:400]}
# Round 3: Search for broader context
keywords = extract_keywords_from_code(chunk1['code'])
context_search = keywords[0] if keywords else name1
reasoning3 = f"<|reasoning|>I now have both {name1} and {name2}. {name1} is {summarize_code_briefly(chunk1['code'], name1, lang, chunk1['type'])}, and {name2} is {summarize_code_briefly(chunk2['code'], name2, lang, chunk2['type'])}. Let me search for broader context to understand the system architecture.<|end|>"
turn3 = {"content": f"{reasoning3}\n<|search|>{context_search}<|end|>", "result": chunk3['code'][:300] if chunk3 != chunk2 else ""}
# Round 4: Evidence
evidence = f"<|reasoning|>I now have a comprehensive picture. {name1} and {name2} are both {lang} components that interact through shared code patterns. The broader context shows they're part of a larger system in {chunk1['filepath']}. Let me compile the complete analysis.<|end|>\n<|evidence|>Comprehensive analysis:\n1. `{name1}`: {summarize_code_briefly(chunk1['code'], name1, lang, chunk1['type'])}. Source: {chunk1['filepath']}\n2. `{name2}`: {summarize_code_briefly(chunk2['code'], name2, lang, chunk2['type'])}. Source: {chunk2['filepath']}\n3. Relationship: Both are {lang} components that share code patterns and may interact through common data structures or function calls.\n4. System context: They are part of the {chunk1['filepath'].split('/')[-1]} module, which contains multiple related components.\n5. Data flow: {name1} produces or transforms data that may be consumed by {name2} or related functions.<|end|>\n<|finish|>"
turn4 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3, turn4])
def gen_refinement_search(chunks, rng) -> dict:
"""Generate a trace where the initial search fails and needs refinement."""
candidates = [c for c in chunks if c['type'] == 'function' and c['name'] not in ('unknown','struct','void','T') and len(c['code']) > 150]
if not candidates:
return None
chunk = rng.choice(candidates)
name = chunk['name']
keywords = extract_keywords_from_code(chunk['code'])
# Use a vague initial search term that would need refinement
vague_term = keywords[0] if keywords else name[:3]
query = rng.choice([
f"Find and explain {name}. I'm not sure of the exact name, but it's related to {vague_term}.",
f"I need to understand the function that handles {vague_term} in the codebase. Can you find it and explain what it does?",
f"There should be a function related to {vague_term}. Find it, analyze it, and tell me what it does.",
f"Search for code related to {vague_term} and find the main function. Explain its implementation.",
])
# Round 1: Vague search
reasoning1 = f"<|reasoning|>The user's query is somewhat vague β€” they're looking for something related to {vague_term}. Let me start with a broad search and then refine based on the results.<|end|>"
turn1 = {"content": f"{reasoning1}\n<|search|>{vague_term}<|end|>", "result": chunk['code'][:300]}
# Round 2: Refined search
reasoning2 = f"<|reasoning|>The initial search returned some results, but I need to be more specific. Looking at the results, I can see references to {name}. Let me search for that specifically to get the full implementation.<|end|>"
turn2 = {"content": f"{reasoning2}\n<|search|>{name}<|end|>", "result": chunk['code'][:500]}
# Round 3: Evidence
summary = summarize_code_briefly(chunk['code'], name, chunk['language'], chunk['type'])
calls = extract_function_calls(chunk['code'])
returns = extract_return_statements(chunk['code'])
evidence = f"<|reasoning|>After refining the search, I found {name}. It's {summary}. The function {'calls ' + ', '.join(calls[:3]) if calls else 'performs internal operations'} and {'returns ' + returns[0] if returns else 'has standard return paths'}. Let me compile the evidence.<|end|>\n<|evidence|>Found `{name}` through search refinement:\n- Initial search for '{vague_term}' returned partial matches\n- Refined search for '{name}' found the full implementation\n- {name} is {summary}\n- Key operations: {', '.join(calls[:4]) if calls else 'internal processing'}\n- Return paths: {'; '.join(returns[:2]) if returns else 'standard'}\n- Source: {chunk['filepath']}<|end|>\n<|finish|>"
turn3 = {"content": evidence}
return make_trace(query, [turn1, turn2, turn3])
# ─── Category Registry ────────────────────────────────────────────────────────
CATEGORIES = {
"implementation": ("Implementation Deep Dive", gen_implementation_deep_dive),
"cross_file": ("Cross-File Data Flow Tracing", gen_cross_file_tracing),
"architecture": ("Architecture & Component Mapping", gen_architecture_mapping),
"usage": ("Usage Pattern Analysis", gen_usage_analysis),
"error_handling": ("Error Handling & Failure Paths", gen_error_handling),
"api_contract": ("API Contract & Interface", gen_api_contract),
"dependency": ("Dependency Graph Mapping", gen_dependency_graph),
"data_structure": ("Data Structure Analysis", gen_data_structure_analysis),
"configuration": ("Configuration & Parameters", gen_configuration_params),
"performance": ("Performance-Critical Paths", gen_performance_paths),
"security": ("Security & Validation", gen_security_validation),
"design_patterns": ("Design Pattern Recognition", gen_design_patterns),
"debugging": ("Debugging Assistance", gen_debugging_assistance),
"comparison": ("Comparison & Tradeoffs", gen_comparison_tradeoffs),
"change_impact": ("Change Impact Analysis", gen_change_impact),
"complex_multi": ("Complex Multi-Step Analysis", gen_complex_multi_step),
"refinement": ("Search Refinement", gen_refinement_search),
}
# ─── Main Generation Loop ─────────────────────────────────────────────────────
def generate_traces(category: str, count: int, seed: int, chunks: list) -> list[dict]:
"""Generate traces for a specific category."""
if category not in CATEGORIES:
print(f"Unknown category: {category}")
return []
cat_name, gen_func = CATEGORIES[category]
rng = random.Random(seed)
traces = []
attempts = 0
max_attempts = count * 5 # Allow retries for None returns
while len(traces) < count and attempts < max_attempts:
attempts += 1
try:
trace = gen_func(chunks, rng)
if trace is not None and trace.get("query") and len(trace.get("trace", [])) >= 4:
traces.append(trace)
except Exception as e:
# Silently skip failed generations
pass
return traces
def main():
parser = argparse.ArgumentParser(description="Generate high-quality SFT traces")
parser.add_argument("--category", type=str, default="all",
help="Category name or 'all'")
parser.add_argument("--count", type=int, default=500,
help="Number of traces per category")
parser.add_argument("--seed", type=int, default=42,
help="Random seed")
parser.add_argument("--output", type=str, default=OUTPUT_DIR,
help="Output directory")
args = parser.parse_args()
# Load chunks
print(f"Loading chunks from {CHUNKS_PATH}...")
chunks = [json.loads(l) for l in open(CHUNKS_PATH, encoding="utf-8")]
print(f" Loaded {len(chunks):,} chunks")
# Create output directory
os.makedirs(args.output, exist_ok=True)
# Determine categories
if args.category == "all":
cats = list(CATEGORIES.keys())
else:
cats = [args.category]
total_traces = 0
for i, cat in enumerate(cats):
cat_name, _ = CATEGORIES[cat]
seed = args.seed + i * 1000
print(f"\n[{i+1}/{len(cats)}] Generating {args.count} traces for '{cat_name}' (seed={seed})...")
traces = generate_traces(cat, args.count, seed, chunks)
output_file = os.path.join(args.output, f"traces_{cat}.jsonl")
with open(output_file, "w", encoding="utf-8") as f:
for trace in traces:
f.write(json.dumps(trace, ensure_ascii=False) + "\n")
print(f" Generated {len(traces)} traces β†’ {output_file}")
total_traces += len(traces)
print(f"\nTotal: {total_traces} traces generated across {len(cats)} categories")
if __name__ == "__main__":
main()