Download src/generate_traces_v2.py from Reizxn/makeitwork1: direct link, hf CLI and curl.
- Browser
- Download file 26.6 kB
-
https://huggingface.co/Reizxn/makeitwork1/resolve/main/src/generate_traces_v2.py
- Command line
-
hf download hf://Reizxn/makeitwork1/src/generate_traces_v2.py
-
curl -L -o generate_traces_v2.py https://huggingface.co/Reizxn/makeitwork1/resolve/main/src/generate_traces_v2.py
26.6 kB
| """ | |
| Diverse search-agent trace generator v2. | |
| Generates 20-50k unique, high-quality search agent traces using real code | |
| chunks from the deduplicated corpus. Each trace follows the Toast 1-style | |
| agentic search loop: reasoning -> search -> results -> analysis -> evidence -> finish. | |
| Improvements over generate_traces.py: | |
| - Combinatorial query phrasings (hundreds of unique templates) | |
| - Smarter evidence extraction (analyzes actual code structure) | |
| - More trace types: simple, noise, multi-step, decomposition, | |
| not-found, struct inspection, behavior analysis, cross-file, | |
| usage tracking, error-handling patterns | |
| - Trace-level dedup (no two traces share the same query+search combo) | |
| - Varied reasoning text (not random.choice from 5 options) | |
| - Realistic evidence packages that extract key facts, not dump code | |
| Output: data/traces/sft_traces_v2.jsonl | |
| """ | |
| import hashlib | |
| import json | |
| import os | |
| import random | |
| import re | |
| PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| DATA_DIR = os.path.join(PROJECT_DIR, "data") | |
| CHUNKS_PATH = os.path.join(DATA_DIR, "chunks", "chunks.jsonl") | |
| TRACES_DIR = os.path.join(DATA_DIR, "traces") | |
| TRACES_PATH = os.path.join(TRACES_DIR, "sft_traces_v2.jsonl") | |
| 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|>." | |
| ) | |
| random.seed(2026) | |
| # βββ Query phrasing components (combinatorial) βββββββββββββββββββββββββββββββ | |
| QUERY_VERBS = ["What does", "How does", "Where is", "Explain", "Find", | |
| "Describe", "What is", "How is", "What are", "Show me", | |
| "Locate", "Identify", "Detail"] | |
| QUERY_ACTIONS = { | |
| "function": ["do", "work", "behave", "function", "operate", "process", | |
| "handle", "compute", "return", "accept"], | |
| "struct": ["contain", "have", "store", "represent", "look like", | |
| "be structured", "be defined"], | |
| "class": ["do", "work", "be structured", "be organized", "be designed", | |
| "function", "be implemented"], | |
| "enum": ["have", "contain", "represent", "be defined", "include"], | |
| "macro": ["do", "define", "expand to", "be used for"], | |
| "trait": ["define", "require", "provide", "specify"], | |
| "interface": ["define", "require", "specify", "declare"], | |
| "impl": ["implement", "provide", "define"], | |
| "module": ["contain", "provide", "export", "define"], | |
| "typedef": ["define", "represent", "be"], | |
| "block": ["do", "work", "be used for"], | |
| } | |
| QUERY_SUFFIXES = ["?", "in the codebase?", "in this project?", | |
| "? Explain briefly.", "? Give me the details.", | |
| "", "? I need specifics.", "? Summarize the key points."] | |
| # βββ Reasoning components ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| REASONING_OPENERS = [ | |
| "I need to find {desc}.", "Looking for {desc}.", | |
| "The query is about {desc}.", "This requires locating {desc}.", | |
| "Let me search for {desc}.", "I should find {desc} first.", | |
| "Starting by searching for {desc}.", "The user wants to know about {desc}.", | |
| "I'll look up {desc}.", "First, I need to find {desc}.", | |
| ] | |
| REASONING_PLANS = [ | |
| "Let me search using '{term}'.", | |
| "I'll query the index for '{term}'.", | |
| "Searching for '{term}' should find it.", | |
| "Let me issue a search for '{term}'.", | |
| "I'll search with the term '{term}'.", | |
| "A search for '{term}' should surface the relevant code.", | |
| "Let me look for '{term}' in the codebase.", | |
| ] | |
| ANALYSIS_FOUND = [ | |
| "Found the relevant code.", "This result contains what I need.", | |
| "This is the right code.", "I found the target.", | |
| "This matches the query.", "The search returned the relevant implementation.", | |
| "This is exactly what I was looking for.", | |
| ] | |
| ANALYSIS_NOISE = [ | |
| "The first result is relevant; the others are not directly related.", | |
| "Result 1 matches. The remaining results appear to be unrelated code.", | |
| "I found the target in the first result. Ignoring the noise.", | |
| "The relevant code is in the first result; the rest don't match.", | |
| "Only the first result is pertinent to this query.", | |
| ] | |
| ANALYSIS_REFINE = [ | |
| "Found the definition. Now let me find where it's used.", | |
| "I have the implementation. Let me search for usages.", | |
| "Got the definition. Let me get more context with another search.", | |
| "Found it. Let me do one more search for completeness.", | |
| "Now I need to see how this is called. Let me search for that.", | |
| ] | |
| NOT_FOUND_REASONING = [ | |
| "No results found for '{term}'. Let me try a broader search.", | |
| "The search returned nothing for '{term}'. Let me try different terms.", | |
| "No matches for '{term}'. Let me verify with another query.", | |
| "Empty results for '{term}'. Let me rephrase the search.", | |
| ] | |
| def generate_query(chunk: dict) -> str: | |
| """Generate a diverse query for a chunk.""" | |
| name = chunk["name"] | |
| typ = chunk["type"] | |
| if name == "unknown" or name == "block": | |
| # Use a key identifier from the code | |
| ids = re.findall(r"\b(ngx_\w+|def\s+\w+|fn\s+\w+|struct\s+\w+|class\s+\w+)\b", chunk["code"]) | |
| if ids: | |
| name = ids[0].replace("def ", "").replace("fn ", "").replace("struct ", "").replace("class ", "") | |
| else: | |
| words = re.findall(r"\b[a-z_]{4,}\b", chunk["code"]) | |
| name = words[0] if words else "this code" | |
| verb = random.choice(QUERY_VERBS) | |
| actions = QUERY_ACTIONS.get(typ, QUERY_ACTIONS["block"]) | |
| action = random.choice(actions) | |
| suffix = random.choice(QUERY_SUFFIXES) | |
| if verb in ("Where is", "Locate", "Find", "Show me", "Identify"): | |
| return f"{verb} {name} {action}{suffix}".replace(f" {action}", "") | |
| return f"{verb} {name} {action}{suffix}" | |
| def generate_description(chunk: dict) -> str: | |
| name = chunk["name"] | |
| typ = chunk["type"] | |
| lang = chunk["language"] | |
| type_words = { | |
| "function": f"the {name} function", "struct": f"the {name} structure", | |
| "class": f"the {name} class", "enum": f"the {name} enum", | |
| "macro": f"the {name} macro", "trait": f"the {name} trait", | |
| "interface": f"the {name} interface", "impl": f"the {name} impl block", | |
| "module": f"the {name} module", "typedef": f"the {name} typedef", | |
| "block": f"code related to {name}", | |
| } | |
| return type_words.get(typ, f"the {name} definition") | |
| def generate_search_term(chunk: dict) -> str: | |
| name = chunk["name"] | |
| if name != "unknown" and name != "block": | |
| return name | |
| code = chunk["code"] | |
| identifiers = re.findall(r"\b(ngx_\w+|def\s+\w+|fn\s+\w+|struct\s+\w+|class\s+\w+)\b", code) | |
| if identifiers: | |
| return identifiers[0].replace("def ", "").replace("fn ", "").replace("struct ", "").replace("class ", "") | |
| words = re.findall(r"\b[a-z_]{4,}\b", code) | |
| return words[0] if words else "code" | |
| # βββ Evidence extraction (smarter) βββββββββββββββββββββββββββββββββββββββββββ | |
| def extract_function_info(code: str, name: str) -> dict: | |
| info = {"name": name, "params": [], "returns": "", "key_lines": [], "calls": []} | |
| sig_match = re.search(r"(?:def|fn|func|function)\s+" + re.escape(name) + r"\s*\(([^)]*)\)", code) | |
| if sig_match: | |
| params_raw = sig_match.group(1).strip() | |
| if params_raw: | |
| info["params"] = [p.strip() for p in params_raw.split(",") if p.strip()][:6] | |
| ret_match = re.search(r"->\s*([^{]+)", code) | |
| if ret_match: | |
| info["returns"] = ret_match.group(1).strip() | |
| calls = re.findall(r"\b(\w+)\s*\(", code) | |
| info["calls"] = [c for c in calls if c != name and c not in ("if", "for", "while", "return", "print")][:5] | |
| for line in code.split("\n"): | |
| s = line.strip() | |
| if not s or s.startswith("//") or s.startswith("#"): | |
| continue | |
| if any(kw in s for kw in ["return ", "if ", "for ", "while ", "raise ", "throw ", "Err(", "Ok(", "assert", "break", "continue"]): | |
| info["key_lines"].append(s) | |
| info["key_lines"] = info["key_lines"][:4] | |
| return info | |
| def extract_struct_info(code: str, name: str) -> dict: | |
| fields = [] | |
| for pat in [re.compile(r"^\s+(\w+)\s+(\w+);", re.M), | |
| re.compile(r"^\s+(\w+):\s+([^,;]+)", re.M), | |
| re.compile(r"^\s+(self\.)?(\w+)\s*[:=]", re.M), | |
| re.compile(r"^\s+(\w+)\s+\w+", re.M)]: | |
| for m in pat.findall(code): | |
| fn = m[-1] if isinstance(m, tuple) else m | |
| if fn and fn not in ("self", "pub", "fn", "def", "class", "struct", "const", "var"): | |
| fields.append(fn) | |
| return {"name": name, "fields": fields[:12]} | |
| def generate_evidence(chunk: dict) -> str: | |
| code = chunk["code"] | |
| name = chunk["name"] | |
| typ = chunk["type"] | |
| lang = chunk["language"] | |
| filepath = chunk["filepath"] | |
| repo = chunk.get("repo", "") | |
| if typ == "function": | |
| info = extract_function_info(code, name) | |
| parts = [f"`{name}` is a {lang} function."] | |
| if info["params"]: | |
| params_str = ", ".join(info["params"]) | |
| parts.append(f"- Parameters: {params_str}") | |
| if info["returns"]: | |
| parts.append(f"- Returns: {info['returns']}") | |
| if info["key_lines"]: | |
| parts.append("- Key behavior:") | |
| for line in info["key_lines"][:3]: | |
| parts.append(f" - `{line}`") | |
| if info["calls"]: | |
| parts.append(f"- Calls: {', '.join(info['calls'])}") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| elif typ == "struct": | |
| info = extract_struct_info(code, name) | |
| parts = [f"`{name}` is a {lang} structure with fields:"] | |
| for field in info["fields"]: | |
| parts.append(f"- `{field}`") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| elif typ == "class": | |
| methods = re.findall(r"(?:def |fn |func |function )\s*(\w+)", code) | |
| parts = [f"`{name}` is a {lang} class."] | |
| if methods: | |
| parts.append(f"- Methods: {', '.join(methods[:8])}") | |
| base = re.search(r"class\s+\w+\s*(?:\(|:\s*|extends\s+|<\s*)(\w+)", code) | |
| if base: | |
| parts.append(f"- Inherits from: {base.group(1)}") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| elif typ == "enum": | |
| variants = re.findall(r"^\s+(\w+)[,\s]*$", code, re.M) | |
| parts = [f"`{name}` is a {lang} enum with variants:"] | |
| for v in variants[:10]: | |
| parts.append(f"- `{v}`") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| elif typ == "macro": | |
| parts = [f"`{name}` is a {lang} macro/preprocessor definition:"] | |
| for line in code.strip().split("\n")[:5]: | |
| parts.append(f" `{line}`") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| elif typ in ("trait", "interface"): | |
| methods = re.findall(r"(?:fn |def |function )\s*(\w+)", code) | |
| parts = [f"`{name}` is a {lang} {typ}."] | |
| if methods: | |
| parts.append(f"- Required methods: {', '.join(methods[:8])}") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| else: | |
| parts = [f"Found code related to `{name}` ({lang}):"] | |
| for line in code.strip().split("\n")[:8]: | |
| parts.append(f" `{line}`") | |
| parts.append(f"- Source: {filepath}") | |
| return "\n".join(parts) | |
| # βββ Trace builders ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def make_reasoning(desc: str, term: str) -> str: | |
| opener = random.choice(REASONING_OPENERS).format(desc=desc) | |
| plan = random.choice(REASONING_PLANS).format(term=term) | |
| return f"{opener} {plan}" | |
| def trace_key(query: str, searches: list[str]) -> str: | |
| """Dedup key for a trace.""" | |
| return hashlib.md5((query + "|" + "|".join(searches)).encode()).hexdigest() | |
| def make_trace_simple(chunk: dict) -> dict: | |
| query = generate_query(chunk) | |
| term = generate_search_term(chunk) | |
| desc = generate_description(chunk) | |
| evidence = generate_evidence(chunk) | |
| reasoning1 = make_reasoning(desc, term) | |
| analysis = random.choice(ANALYSIS_FOUND) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>{reasoning1}<|end|>\n<|search|>{term}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>{analysis} {desc.replace('the ', 'This is ', 1)}.<|end|>\n<|evidence|>{evidence}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_with_noise(chunk: dict, noise_chunks: list) -> dict: | |
| query = generate_query(chunk) | |
| term = generate_search_term(chunk) | |
| desc = generate_description(chunk) | |
| evidence = generate_evidence(chunk) | |
| reasoning1 = make_reasoning(desc, term) | |
| n_noise = random.choice([1, 2]) | |
| noise = random.sample(noise_chunks, min(n_noise, len(noise_chunks))) | |
| analysis = random.choice(ANALYSIS_NOISE) | |
| trace = [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>{reasoning1}<|end|>\n<|search|>{term}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| ] | |
| for nc in noise: | |
| trace.append({"role": "result", "content": nc["code"]}) | |
| trace.append({"role": "assistant", "content": f"<|reasoning|>{analysis}<|end|>\n<|evidence|>{evidence}<|end|>\n<|finish|>"}) | |
| return {"query": query, "trace": trace} | |
| def make_trace_multi_step(chunk: dict, related: dict) -> dict: | |
| name = chunk["name"] | |
| rname = related["name"] | |
| query = f"What does {name} do and where is it used?" | |
| term1 = generate_search_term(chunk) | |
| term2 = generate_search_term(related) | |
| desc = generate_description(chunk) | |
| evidence1 = generate_evidence(chunk) | |
| evidence2 = generate_evidence(related) | |
| reasoning1 = make_reasoning(desc, term1) | |
| reasoning2 = random.choice(ANALYSIS_REFINE) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>{reasoning1}<|end|>\n<|search|>{term1}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found {desc}. {reasoning2}<|end|>\n<|search|>{term2}<|end|>"}, | |
| {"role": "result", "content": related["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found both the definition and a usage. I now have complete context.<|end|>\n<|evidence|>{evidence1}\n\nRelated usage:\n{evidence2}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_decomposition(chunk: dict, related: dict) -> dict: | |
| name = chunk["name"] | |
| rname = related["name"] | |
| query = f"How does {name} work and how does it relate to {rname}?" | |
| term1 = generate_search_term(chunk) | |
| term2 = generate_search_term(related) | |
| evidence1 = generate_evidence(chunk) | |
| evidence2 = generate_evidence(related) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>This query has two parts: (1) how {name} works, (2) its relationship to {rname}. Let me search for {name} first.<|end|>\n<|search|>{term1}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found {name}. Now let me search for {rname} to understand the relationship.<|end|>\n<|search|>{term2}<|end|>"}, | |
| {"role": "result", "content": related["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found both components. I can now explain how they relate.<|end|>\n<|evidence|>{evidence1}\n\nRelated: {evidence2}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_not_found() -> dict: | |
| fake_names = ["database_pool", "auth_middleware", "cache_manager", "session_store", | |
| "websocket_handler", "graphql_resolver", "redis_client", "email_service", | |
| "rate_limiter", "circuit_breaker", "event_bus", "message_queue", | |
| "load_balancer", "api_gateway", "service_mesh", "config_center"] | |
| name = random.choice(fake_names) | |
| query = f"Where is the {name} implemented?" | |
| search1 = name | |
| search2 = name.replace("_", " ") | |
| reasoning1 = make_reasoning(f"the {name}", search1) | |
| reasoning2 = random.choice(NOT_FOUND_REASONING).format(term=search1) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>{reasoning1}<|end|>\n<|search|>{search1}<|end|>"}, | |
| {"role": "result", "content": ""}, | |
| {"role": "assistant", "content": f"<|reasoning|>{reasoning2}<|end|>\n<|search|>{search2}<|end|>"}, | |
| {"role": "result", "content": ""}, | |
| {"role": "assistant", "content": f"<|reasoning|>No results found. The codebase does not contain {name}.<|end|>\n<|evidence|>No implementation of `{name}` was found in the codebase. Searched for: '{search1}', '{search2}'.<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_struct_inspection(chunk: dict) -> dict: | |
| if chunk["type"] != "struct": | |
| return make_trace_simple(chunk) | |
| name = chunk["name"] | |
| query = f"What fields does {name} have?" | |
| term = name | |
| evidence = generate_evidence(chunk) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>Looking for the {name} struct definition to enumerate its fields.<|end|>\n<|search|>{term}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found the struct definition. I can extract all fields from it.<|end|>\n<|evidence|>{evidence}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_behavior(chunk: dict) -> dict: | |
| if chunk["type"] != "function": | |
| return make_trace_simple(chunk) | |
| name = chunk["name"] | |
| query = f"What does {name} do? Explain its behavior." | |
| term = name | |
| evidence = generate_evidence(chunk) | |
| info = extract_function_info(chunk["code"], name) | |
| params = ", ".join(info["params"][:4]) if info["params"] else "no parameters" | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>I need to find and analyze the {name} function. Let me search for its definition.<|end|>\n<|search|>{term}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found the function. It takes {params}. Let me analyze its behavior from the code.<|end|>\n<|evidence|>{evidence}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| def make_trace_cross_file(chunk: dict, related: dict) -> dict: | |
| """Cross-file: definition in one file, usage in another.""" | |
| name = chunk["name"] | |
| rname = related["name"] | |
| query = f"How is {name} used across the codebase?" | |
| term1 = generate_search_term(chunk) | |
| term2 = generate_search_term(related) | |
| evidence1 = generate_evidence(chunk) | |
| evidence2 = generate_evidence(related) | |
| return { | |
| "query": query, | |
| "trace": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": query}, | |
| {"role": "assistant", "content": f"<|reasoning|>I need to find the definition of {name} and then trace its usages across files.<|end|>\n<|search|>{term1}<|end|>"}, | |
| {"role": "result", "content": chunk["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found the definition in {chunk['filepath']}. Now let me search for where it's called or referenced.<|end|>\n<|search|>{term2}<|end|>"}, | |
| {"role": "result", "content": related["code"]}, | |
| {"role": "assistant", "content": f"<|reasoning|>Found a usage in {related['filepath']}. I now have both the definition and a call site.<|end|>\n<|evidence|>Definition ({chunk['filepath']}):\n{evidence1}\n\nUsage ({related['filepath']}):\n{evidence2}<|end|>\n<|finish|>"}, | |
| ], | |
| } | |
| # βββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def main(): | |
| os.makedirs(TRACES_DIR, exist_ok=True) | |
| print(f"Loading chunks from {CHUNKS_PATH}...") | |
| with open(CHUNKS_PATH, "r", encoding="utf-8") as f: | |
| chunks = [json.loads(line) for line in f] | |
| print(f" Loaded {len(chunks):,} chunks") | |
| good_chunks = [c for c in chunks if c["name"] != "unknown" and c["name"] != "block" and 50 < len(c["code"]) < 4000] | |
| print(f" Named chunks (good): {len(good_chunks):,}") | |
| by_lang = {} | |
| for c in good_chunks: | |
| by_lang.setdefault(c["language"], []).append(c) | |
| traces = [] | |
| seen_keys = set() | |
| def add_trace(trace): | |
| searches = [m["content"] for m in trace["trace"] if m["role"] == "assistant" and "<|search|>" in m["content"]] | |
| # Extract search terms | |
| search_terms = re.findall(r"<\|search\|>(.*?)<\|end\|>", "".join(m["content"] for m in trace["trace"] if m["role"] == "assistant")) | |
| key = trace_key(trace["query"], search_terms) | |
| if key in seen_keys: | |
| return False | |
| seen_keys.add(key) | |
| traces.append(trace) | |
| return True | |
| def get_related(chunk): | |
| lang_chunks = by_lang.get(chunk["language"], good_chunks) | |
| pool = [c for c in lang_chunks if c["id"] != chunk["id"]] | |
| return random.choice(pool) if pool else chunk | |
| # Type 1: Simple lookup (25%) | |
| n_simple = min(8000, len(good_chunks)) | |
| for chunk in random.sample(good_chunks, n_simple): | |
| add_trace(make_trace_simple(chunk)) | |
| print(f" Simple lookup: {len(traces)}") | |
| # Type 2: With noise (20%) | |
| n_noise = min(6000, len(good_chunks)) | |
| for chunk in random.sample(good_chunks, n_noise): | |
| lang_chunks = by_lang.get(chunk["language"], good_chunks) | |
| noise_pool = [c for c in lang_chunks if c["id"] != chunk["id"]] | |
| if len(noise_pool) >= 2: | |
| add_trace(make_trace_with_noise(chunk, noise_pool)) | |
| print(f" With noise: {len(traces)}") | |
| # Type 3: Multi-step (15%) | |
| n_multi = min(4000, len(good_chunks) // 2) | |
| for chunk in random.sample(good_chunks, n_multi): | |
| add_trace(make_trace_multi_step(chunk, get_related(chunk))) | |
| print(f" Multi-step: {len(traces)}") | |
| # Type 4: Decomposition (10%) | |
| n_decomp = min(3000, len(good_chunks) // 3) | |
| for chunk in random.sample(good_chunks, n_decomp): | |
| add_trace(make_trace_decomposition(chunk, get_related(chunk))) | |
| print(f" Decomposition: {len(traces)}") | |
| # Type 5: Not found (5%) | |
| for _ in range(1500): | |
| add_trace(make_trace_not_found()) | |
| print(f" Not found: {len(traces)}") | |
| # Type 6: Struct inspection (10%) | |
| struct_chunks = [c for c in good_chunks if c["type"] == "struct"] | |
| for chunk in random.sample(struct_chunks, min(2000, len(struct_chunks))): | |
| add_trace(make_trace_struct_inspection(chunk)) | |
| print(f" Struct inspection: {len(traces)}") | |
| # Type 7: Behavior analysis (10%) | |
| func_chunks = [c for c in good_chunks if c["type"] == "function"] | |
| for chunk in random.sample(func_chunks, min(2000, len(func_chunks))): | |
| add_trace(make_trace_behavior(chunk)) | |
| print(f" Behavior analysis: {len(traces)}") | |
| # Type 8: Cross-file (5%) | |
| n_cross = min(1500, len(good_chunks) // 4) | |
| for chunk in random.sample(good_chunks, n_cross): | |
| add_trace(make_trace_cross_file(chunk, get_related(chunk))) | |
| print(f" Cross-file: {len(traces)}") | |
| random.shuffle(traces) | |
| # Write | |
| print(f"\nTotal unique traces: {len(traces):,}") | |
| total_size = 0 | |
| with open(TRACES_PATH, "w", encoding="utf-8") as f: | |
| for trace in traces: | |
| line = json.dumps(trace, ensure_ascii=False) | |
| f.write(line + "\n") | |
| total_size += len(line) | |
| print(f"Traces written to {TRACES_PATH}") | |
| print(f" File size: {total_size / 1e6:.2f} MB") | |
| # Show a sample | |
| print("\n" + "=" * 60) | |
| print("SAMPLE TRACE") | |
| print("=" * 60) | |
| sample = traces[0] | |
| print(f"\nQuery: {sample['query']}") | |
| for msg in sample["trace"]: | |
| content = msg["content"] | |
| if len(content) > 200: | |
| content = content[:200] + "..." | |
| print(f"\n[{msg['role']}]") | |
| print(content) | |
| # Stats | |
| stats = { | |
| "total_traces": len(traces), | |
| "file_size_mb": total_size / 1e6, | |
| "unique_queries": len(set(t["query"] for t in traces)), | |
| } | |
| stats_path = os.path.join(TRACES_DIR, "trace_stats.json") | |
| with open(stats_path, "w") as f: | |
| json.dump(stats, f, indent=2) | |
| print(f"\nStats: {stats}") | |
| if __name__ == "__main__": | |
| main() | |