From 1eee49d9fe3bd222f71ca8547d2c93829cdae65a Mon Sep 17 00:00:00 2001 From: VictorGjn <56982152+VictorGjn@users.noreply.github.com> Date: Thu, 2 Apr 2026 11:54:42 +0200 Subject: [PATCH 1/4] fix: address Codex review from PR #148 (3 P1 + 1 P2) - Fix PromptRouter regex: \s not s for whitespace splitting - Fix ReactiveCompaction: downgrade least-relevant half, not most-relevant - Fix reactivePackerWrapper: truncate content after depth adjustment - Fix agentSearchIntegration: include metadata in cache key for freshness --- src/context/PromptRouter.ts | 4 ++-- src/context/ReactiveCompaction.ts | 4 ++-- src/graph/reactivePackerWrapper.ts | 9 ++++++++- src/services/agentSearchIntegration.ts | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/context/PromptRouter.ts b/src/context/PromptRouter.ts index c4932fd..6165c21 100644 --- a/src/context/PromptRouter.ts +++ b/src/context/PromptRouter.ts @@ -30,8 +30,8 @@ export function tokenizePrompt(prompt: string): Set { return new Set( prompt .toLowerCase() - .replace(/[^a-z0-9s/_-]/g, '') - .split(/[s/_-]+/) + .replace(/[^a-z0-9\s\/_-]/g, '') + .split(/[\s\/_-]+/) .filter(t => t.length >= 2) ); } diff --git a/src/context/ReactiveCompaction.ts b/src/context/ReactiveCompaction.ts index 70aa2df..321d2ff 100644 --- a/src/context/ReactiveCompaction.ts +++ b/src/context/ReactiveCompaction.ts @@ -68,9 +68,9 @@ export class ReactiveCompaction { } } } else if (signal.ratio >= this.config.pressureThreshold) { - // Pressure: downgrade bottom half by one level + // Pressure: downgrade least-relevant half by one level const half = Math.ceil(sorted.length / 2); - for (let i = half; i < sorted.length; i++) { + for (let i = 0; i < half; i++) { const f = sorted[i]; const next = this.nextDepth(f.depth); if (next) adjustments.push({ fileId: f.fileId, currentDepth: f.depth, newDepth: next, reason: 'token_pressure' }); diff --git a/src/graph/reactivePackerWrapper.ts b/src/graph/reactivePackerWrapper.ts index a0f7557..d5ce9dc 100644 --- a/src/graph/reactivePackerWrapper.ts +++ b/src/graph/reactivePackerWrapper.ts @@ -127,7 +127,14 @@ export function withReactiveCompaction( const baseTokens = oldRatio > 0 ? item.tokens / oldRatio : item.tokens; const newTokens = Math.max(1, Math.ceil(baseTokens * newRatio)); newTotal += newTokens; - return { ...item, depth: newDepthNumeric, tokens: newTokens }; + // Truncate content proportionally to new depth + const contentStr = typeof item.content === 'string' ? item.content : ''; + const truncatedLength = oldRatio > 0 ? Math.ceil(contentStr.length * (newRatio / oldRatio)) : contentStr.length; + const truncatedContent = contentStr.length > truncatedLength + ? contentStr.slice(0, truncatedLength) + ' +[... truncated by reactive compaction]' + : contentStr; + return { ...item, depth: newDepthNumeric, tokens: newTokens, content: truncatedContent }; } newTotal += item.tokens; return item; diff --git a/src/services/agentSearchIntegration.ts b/src/services/agentSearchIntegration.ts index d1b9c4d..e9590b3 100644 --- a/src/services/agentSearchIntegration.ts +++ b/src/services/agentSearchIntegration.ts @@ -43,7 +43,7 @@ export function createAgentSearchService( agents: AgentConfig[], knowledge: KnowledgeSource[] = [], ): AgentSearchService { - const hash = JSON.stringify(agents.map(a => a.id).sort()); + const hash = JSON.stringify(agents.map(a => [a.id, a.description, a.role, ...(a.tags ?? [])].join('|')).sort()); if (!_searchInstance || hash !== _lastIndexHash) { _searchInstance = new AgentSearch(agents, knowledge); _lastIndexHash = hash; From 7c9586d4f2a4ddf726eaeb00dd9fc4c69278226f Mon Sep 17 00:00:00 2001 From: VictorGjn <56982152+VictorGjn@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:38:59 +0200 Subject: [PATCH 2/4] fix: address Codex review round 2 (P1+P2) - Fix unterminated string literal: escape newline in truncation marker - Fix reindex() hash: use same format as createAgentSearchService() --- src/graph/reactivePackerWrapper.ts | 3 +-- src/services/agentSearchIntegration.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/graph/reactivePackerWrapper.ts b/src/graph/reactivePackerWrapper.ts index d5ce9dc..4f5dd6e 100644 --- a/src/graph/reactivePackerWrapper.ts +++ b/src/graph/reactivePackerWrapper.ts @@ -131,8 +131,7 @@ export function withReactiveCompaction( const contentStr = typeof item.content === 'string' ? item.content : ''; const truncatedLength = oldRatio > 0 ? Math.ceil(contentStr.length * (newRatio / oldRatio)) : contentStr.length; const truncatedContent = contentStr.length > truncatedLength - ? contentStr.slice(0, truncatedLength) + ' -[... truncated by reactive compaction]' + ? contentStr.slice(0, truncatedLength) + '\n[... truncated by reactive compaction]' : contentStr; return { ...item, depth: newDepthNumeric, tokens: newTokens, content: truncatedContent }; } diff --git a/src/services/agentSearchIntegration.ts b/src/services/agentSearchIntegration.ts index e9590b3..1b435c0 100644 --- a/src/services/agentSearchIntegration.ts +++ b/src/services/agentSearchIntegration.ts @@ -64,7 +64,7 @@ export function createAgentSearchService( reindex(newAgents: AgentConfig[], newKnowledge?: KnowledgeSource[]): void { _searchInstance = new AgentSearch(newAgents, newKnowledge ?? knowledge); - _lastIndexHash = JSON.stringify(newAgents.map(a => a.id).sort()); + _lastIndexHash = JSON.stringify(newAgents.map(a => [a.id, a.description, a.role, ...(a.tags ?? [])].join('|')).sort()); }, }; } From 096f11b353eeca870356f615dc41135d61dcb658 Mon Sep 17 00:00:00 2001 From: VictorGjn <56982152+VictorGjn@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:56:51 +0200 Subject: [PATCH 3/4] fix: escape newlines in string literals (build breaker) All join('\n') calls had raw newlines instead of escaped. Fixes TS1002 Unterminated string literal in 3 files. --- src/context/PromptRouter.ts | 3 +-- src/context/TranscriptCompaction.ts | 3 +-- src/services/systemFrameBuilder.ts | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/context/PromptRouter.ts b/src/context/PromptRouter.ts index 6165c21..39b09c7 100644 --- a/src/context/PromptRouter.ts +++ b/src/context/PromptRouter.ts @@ -133,6 +133,5 @@ export function renderRoutedTools(matches: RoutedMatch m.metadata?.toolName ?? 'unknown').join(', ')}`); } - return parts.join(' -'); + return parts.join('\n'); } /** Estimate tokens for a string (rough approximation). */ diff --git a/src/services/systemFrameBuilder.ts b/src/services/systemFrameBuilder.ts index fc14167..1bb6de1 100644 --- a/src/services/systemFrameBuilder.ts +++ b/src/services/systemFrameBuilder.ts @@ -46,8 +46,7 @@ export function buildProvenanceSection(provenance: ProvenanceSummary): string { lines.push(''); } - return lines.join(' -'); + return lines.join('\n'); } export function buildSystemFrame(provenance?: ProvenanceSummary): string { From c227c104be49b0577e37469dbb3ece371ea1a73d Mon Sep 17 00:00:00 2001 From: VictorGjn <56982152+VictorGjn@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:59:22 +0200 Subject: [PATCH 4/4] fix: escape remaining newlines in systemFrameBuilder.ts Fixes .join('\n\n') double-newline patterns that also had raw newlines. --- src/services/systemFrameBuilder.ts | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/services/systemFrameBuilder.ts b/src/services/systemFrameBuilder.ts index 1bb6de1..1696d81 100644 --- a/src/services/systemFrameBuilder.ts +++ b/src/services/systemFrameBuilder.ts @@ -61,8 +61,7 @@ export function buildSystemFrame(provenance?: ProvenanceSummary): string { if (agentMeta.avatar) identity.push(`Avatar: ${agentMeta.avatar}`); if (agentMeta.tags?.length) identity.push(`Tags: ${agentMeta.tags.join(', ')}`); parts.push(` -${identity.join(' -')} +${identity.join('\n')} `); } @@ -79,17 +78,13 @@ ${identity.join(' lines.push(`Primary Objective: ${instructionState.objectives.primary}`); if (instructionState.objectives.successCriteria.length > 0) lines.push(`Success Criteria: -${instructionState.objectives.successCriteria.map(c => `- ${c}`).join(' -')}`); +${instructionState.objectives.successCriteria.map(c => `- ${c}`).join('\n')}`); if (instructionState.objectives.failureModes.length > 0) lines.push(`Failure Modes to Avoid: -${instructionState.objectives.failureModes.map(f => `- ${f}`).join(' -')}`); +${instructionState.objectives.failureModes.map(f => `- ${f}`).join('\n')}`); } parts.push(` -${lines.join(' - -')} +${lines.join('\n\n')} `); } @@ -105,8 +100,7 @@ ${lines.join(' if (instructionState.constraints.customConstraints) constraints.push(`Additional constraints: ${instructionState.constraints.customConstraints}`); if (constraints.length > 0) parts.push(` -${constraints.map(c => `- ${c}`).join(' -')} +${constraints.map(c => `- ${c}`).join('\n')} `); // Workflow @@ -127,9 +121,7 @@ ${compiled} parts.push(provenanceSection); } - return parts.join(' - -'); + return parts.join('\n\n'); } /** @@ -316,7 +308,6 @@ export function buildToolGuide(): string { } return ` -${lines.join(' -')} +${lines.join('\n')} `; }