import { ContextAssembler, estimateTokens } from "../src/context-assembler.js"; import { planTurnContext } from "../src/context-planner.js"; import type { ToolSpec } from "../src/llm-client.js"; interface EvalCase { name: string; prompt: string; } const CASES: EvalCase[] = [ { name: "architecture", prompt: "erklär mir die agent loop logik und wo tool results komprimiert werden" }, { name: "edit", prompt: "fix den bug im command filter und patch die datei" }, { name: "runtime", prompt: "debug den runtime crash mit stack trace und finde root cause" }, { name: "review", prompt: "review die offenen code risks und test gaps" }, { name: "search", prompt: "finde wo auth token und session capsule gespeichert werden" } ]; const ALL_TOOLS = buildSyntheticTools(122); const assembler = new ContextAssembler(); const rows = CASES.map((testCase) => { const plan = planTurnContext(testCase.prompt, { configuredMaxSteps: 8, configuredMaxTokens: 8000 }); const selectedTools = selectSyntheticTools(testCase.prompt, ALL_TOOLS); const transcript = buildTranscript(testCase.prompt); const baseline = assembler.assemble({ transcript, currentTurnStart: transcript.length - 1, tools: ALL_TOOLS, systemPrompt: "system".repeat(2400), runtimeContext: "runtime".repeat(600), sessionSummary: "summary".repeat(300) }); const routed = assembler.assemble({ transcript, currentTurnStart: transcript.length - 1, tools: selectedTools, systemPrompt: "system".repeat(2400), runtimeContext: "runtime".repeat(600), sessionSummary: "summary".repeat(300) }); return { name: testCase.name, taskType: plan.route.taskType, indexMode: plan.indexMode, baselineToolsIn: baseline.report.toolsIn, baselineToolsOut: baseline.report.toolsOut, routedToolsIn: routed.report.toolsIn, routedToolsOut: routed.report.toolsOut, baselineTokens: baseline.report.totalTokens, routedTokens: routed.report.totalTokens, tokenReductionPct: pctReduction(baseline.report.totalTokens, routed.report.totalTokens), toolTokenReductionPct: pctReduction(baseline.report.toolTokensBefore, routed.report.toolTokensAfter), droppedTools: routed.report.droppedTools }; }); const summary = { generatedAt: new Date().toISOString(), cases: rows.length, avgTokenReductionPct: average(rows.map((row) => row.tokenReductionPct)), avgToolTokenReductionPct: average(rows.map((row) => row.toolTokenReductionPct)), rows }; process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`); function buildSyntheticTools(count: number): ToolSpec[] { const names = [ "workspace.open_artifact", "workspace.ask_codebase", "workspace.get_diagnostics", "workspace.git_status", "workspace.list_files", "workspace.semantic_search", "workspace.read_file", "workspace.read_slice", "workspace.patch_file", "workspace.run_command", "workspace.validate_patch", "runtime.capture_failure", "workspace.production_readiness", "agent.spawn", "workspace.timeline_create" ]; return Array.from({ length: count }, (_, index) => { const name = names[index] ?? `workspace.experimental_${index}`; return { name: name.replace(/[^a-zA-Z0-9_-]/g, "_"), description: `${name} ${"description ".repeat(18)}`, inputSchema: { type: "object", properties: Object.fromEntries( Array.from({ length: 16 }, (_unused, propIndex) => [ `field_${propIndex}`, { type: "string", description: "schema field ".repeat(16) } ]) ) } }; }); } function selectSyntheticTools(prompt: string, tools: ToolSpec[]): ToolSpec[] { const lower = prompt.toLowerCase(); const wanted = new Set([ "workspace_open_artifact", "workspace_ask_codebase", "workspace_git_status", "workspace_semantic_search", "workspace_read_file", "workspace_read_slice" ]); if (/fix|patch|edit|bug/i.test(lower)) { wanted.add("workspace_patch_file"); wanted.add("workspace_run_command"); wanted.add("workspace_validate_patch"); } if (/runtime|crash|stack|debug/i.test(lower)) { wanted.add("runtime_capture_failure"); } if (/review|risk|audit/i.test(lower)) { wanted.add("workspace_production_readiness"); } return tools.filter((tool) => wanted.has(tool.name)).slice(0, 36); } function buildTranscript(prompt: string) { return [ { role: "user" as const, content: [{ text: "previous context ".repeat(900) }] }, { role: "assistant" as const, content: [{ text: "previous answer ".repeat(900) }] }, { role: "user" as const, content: [{ text: prompt }] } ]; } function pctReduction(before: number, after: number): number { if (before <= 0) return 0; return Number((((before - after) / before) * 100).toFixed(1)); } function average(values: number[]): number { if (values.length === 0) return 0; return Number((values.reduce((sum, value) => sum + value, 0) / values.length).toFixed(1)); }