mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-04 02:31:36 +00:00
fix(wiki): cap graph reference fields to prevent prompt overflow
generateLeafPage assembled the MODULE prompt with truncated SOURCE_CODE but uncapped INTRA_CALLS/OUTGOING_CALLS/INCOMING_CALLS/PROCESSES. In large clusters with many cross-references, the graph data alone can re-explode the assembled prompt past the model's input context (or hit the output max_completion_tokens cap on smaller models like gemini-2.5-flash with 8K output), causing deterministic module-generation failures even with --force. Symptom (browser-harness, 20 clusters): "Project Documentation" and "Browser Interaction Skills" modules fail deterministically across gemini-2.5-flash (740s, 19 page, 2 fail) and gpt-5-chat-latest (2804s, 18 page, 3 fail). SOURCE_CODE truncation alone is insufficient when the cluster has many edges. Fix: - Extract generic truncateText helper from truncateSource (label-aware notice for clarity) - Add DEFAULT_GRAPH_FIELD_BUDGET = 5_000 (≈1/6 of module budget) - Apply per-field caps to INTRA/OUTGOING/INCOMING calls + PROCESSES in generateLeafPage Tests: existing 51 wiki unit tests pass unchanged.
This commit is contained in:
parent
d69eadfb7f
commit
ca44e80c05
1 changed files with 35 additions and 6 deletions
|
|
@ -94,6 +94,14 @@ export interface WikiRunResult {
|
|||
// ─── Constants ────────────────────────────────────────────────────────
|
||||
|
||||
const DEFAULT_MAX_TOKENS_PER_MODULE = 30_000;
|
||||
/**
|
||||
* Per-field token cap for graph reference data (INTRA/OUTGOING/INCOMING/PROCESSES).
|
||||
* Each field gets ~1/6 of the module budget. Without these caps, a large cluster
|
||||
* with many cross-references can push the assembled prompt beyond the model's
|
||||
* input or output context (e.g. gemini-2.5-flash 8K output cap), causing
|
||||
* deterministic failures even after SOURCE_CODE itself is truncated.
|
||||
*/
|
||||
const DEFAULT_GRAPH_FIELD_BUDGET = 5_000;
|
||||
const WIKI_DIR = 'wiki';
|
||||
|
||||
// ─── Generator Class ──────────────────────────────────────────────────
|
||||
|
|
@ -579,13 +587,26 @@ export class WikiGenerator {
|
|||
getProcessesForFiles(filePaths, 5),
|
||||
]);
|
||||
|
||||
// Cap each graph-reference field independently. Even when SOURCE_CODE is
|
||||
// already truncated to maxTokensPerModule, uncapped call edges + processes
|
||||
// can re-explode the assembled prompt past the model's context (or hit the
|
||||
// output max_completion_tokens cap for smaller models like gemini-2.5-flash).
|
||||
const graphBudget = DEFAULT_GRAPH_FIELD_BUDGET;
|
||||
const prompt = fillTemplate(MODULE_USER_PROMPT, {
|
||||
MODULE_NAME: node.name,
|
||||
SOURCE_CODE: finalSourceCode,
|
||||
INTRA_CALLS: formatCallEdges(intraCalls),
|
||||
OUTGOING_CALLS: formatCallEdges(interCalls.outgoing),
|
||||
INCOMING_CALLS: formatCallEdges(interCalls.incoming),
|
||||
PROCESSES: formatProcesses(processes),
|
||||
INTRA_CALLS: this.truncateText(formatCallEdges(intraCalls), graphBudget, 'intra-module calls'),
|
||||
OUTGOING_CALLS: this.truncateText(
|
||||
formatCallEdges(interCalls.outgoing),
|
||||
graphBudget,
|
||||
'outgoing calls',
|
||||
),
|
||||
INCOMING_CALLS: this.truncateText(
|
||||
formatCallEdges(interCalls.incoming),
|
||||
graphBudget,
|
||||
'incoming calls',
|
||||
),
|
||||
PROCESSES: this.truncateText(formatProcesses(processes), graphBudget, 'execution flows'),
|
||||
});
|
||||
|
||||
const response = await this.invokeLLM(prompt, MODULE_SYSTEM_PROMPT, this.streamOpts(node.name));
|
||||
|
|
@ -880,10 +901,18 @@ export class WikiGenerator {
|
|||
}
|
||||
|
||||
private truncateSource(source: string, maxTokens: number): string {
|
||||
return this.truncateText(source, maxTokens, 'source');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic token-budget truncation for prompt fields. Used by both SOURCE_CODE
|
||||
* and graph reference data (INTRA/OUTGOING/INCOMING calls + PROCESSES).
|
||||
*/
|
||||
private truncateText(text: string, maxTokens: number, label = 'data'): string {
|
||||
// Rough truncation: keep first maxTokens*4 chars and add notice
|
||||
const maxChars = maxTokens * 4;
|
||||
if (source.length <= maxChars) return source;
|
||||
return source.slice(0, maxChars) + '\n\n... (source truncated for context window limits)';
|
||||
if (text.length <= maxChars) return text;
|
||||
return text.slice(0, maxChars) + `\n\n... (${label} truncated for context window limits)`;
|
||||
}
|
||||
|
||||
private async estimateModuleTokens(filePaths: string[]): Promise<number> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue