Skip to content

Commit b1729a1

Browse files
IM.codesclaude
andcommitted
fix(memory): skip recall for P2P orchestration prompts
P2P discussion task prompts are agent-to-agent scaffolding generated by the P2P orchestrator, not real user queries. Their stable markers (round headers, run IDs, identity assignments, .imc/discussions paths) would match tons of historical entries but produce zero useful signal. Detect via 4 independent regex markers — any one sufficient: - [Round N/M — ...] round header - [P2P Discussion Task — run XXX] - "Your identity for this discussion run is" - .imc/discussions/XXX.md path reference Incorporated into isTrivialRecallQuery so the single recall-gate filter handles both trivial-word AND orchestration-prompt pollution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4e7eb93 commit b1729a1

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

src/context/memory-search.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,37 @@ export interface MemorySearchResult {
8282
* Semantic search: fetch candidates via substring match, then re-rank by embedding similarity.
8383
* Falls back to plain searchLocalMemory if embedding model is unavailable.
8484
*/
85+
/**
86+
* Detects P2P orchestration prompts — multi-agent discussion scaffolding
87+
* generated by the P2P system, not real user queries. These carry stable
88+
* markers injected by the orchestrator and should NEVER drive memory recall:
89+
* they pollute context with irrelevant historical matches while producing
90+
* no useful retrieval signal.
91+
*/
92+
export function isP2pOrchestrationPrompt(text: string): boolean {
93+
// Stable markers emitted by P2P round prompts — see p2p-orchestrator / p2p-modes.
94+
// Any one of these is sufficient to identify the prompt as orchestration.
95+
if (/\[P2P Discussion Task\s+\s+run\s+[a-f0-9-]+\]/i.test(text)) return true;
96+
if (/\[Round\s+\d+\/\d+\s+/i.test(text)) return true;
97+
if (/Your identity for this discussion run is/i.test(text)) return true;
98+
if (/\.imc\/discussions\/[a-f0-9-]+\.md/i.test(text)) return true;
99+
return false;
100+
}
101+
85102
/**
86103
* Returns true when the query text is too trivial to drive meaningful recall.
87104
* Language-agnostic: counts tokens (whitespace + punctuation separated) and
88105
* total non-whitespace characters. Covers short continuation words in any
89106
* language ("continue", "继续", "好", "ok", "next", single emoji, etc.) without
90-
* maintaining a blacklist.
107+
* maintaining a blacklist. Also filters P2P orchestration prompts.
91108
*/
92109
export function isTrivialRecallQuery(text: string | undefined | null): boolean {
93110
if (!text) return true;
94111
const trimmed = text.trim();
95112
if (!trimmed) return true;
113+
// P2P orchestration prompts are long but semantically empty for user-memory
114+
// recall — they're agent-to-agent scaffolding, not user intent.
115+
if (isP2pOrchestrationPrompt(trimmed)) return true;
96116
// Count semantic units: space-separated tokens + individual CJK characters.
97117
// CJK has no word boundaries, so each ideograph counts as its own unit.
98118
// This avoids language-specific blacklists.

test/context/trivial-recall-filter.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Language-agnostic via token count + content-char thresholds.
77
*/
88
import { describe, it, expect } from 'vitest';
9-
import { isTrivialRecallQuery } from '../../src/context/memory-search.js';
9+
import { isTrivialRecallQuery, isP2pOrchestrationPrompt } from '../../src/context/memory-search.js';
1010

1111
describe('isTrivialRecallQuery', () => {
1212
describe('trivial (should skip recall)', () => {
@@ -69,4 +69,34 @@ describe('isTrivialRecallQuery', () => {
6969
expect(isTrivialRecallQuery(input)).toBe(false);
7070
});
7171
});
72+
73+
describe('P2P orchestration prompts (should skip)', () => {
74+
it('detects [Round N/M] round header', () => {
75+
const prompt = '[Round 1/3 — Audit Phase — Initial Analysis] Provide your analysis.';
76+
expect(isP2pOrchestrationPrompt(prompt)).toBe(true);
77+
expect(isTrivialRecallQuery(prompt)).toBe(true);
78+
});
79+
80+
it('detects [P2P Discussion Task — run XXX]', () => {
81+
const prompt = 'Work on [P2P Discussion Task — run 6e5f4c30-b3b] carefully.';
82+
expect(isP2pOrchestrationPrompt(prompt)).toBe(true);
83+
expect(isTrivialRecallQuery(prompt)).toBe(true);
84+
});
85+
86+
it('detects identity assignment phrase', () => {
87+
const prompt = 'Your identity for this discussion run is "abc:codex-sdk".';
88+
expect(isP2pOrchestrationPrompt(prompt)).toBe(true);
89+
});
90+
91+
it('detects .imc/discussions path reference', () => {
92+
const prompt = 'Append to /Users/k/project/.imc/discussions/6e5f4c30-b3b.md now.';
93+
expect(isP2pOrchestrationPrompt(prompt)).toBe(true);
94+
});
95+
96+
it('does not flag unrelated text mentioning rounds or P2P', () => {
97+
expect(isP2pOrchestrationPrompt('How does P2P work?')).toBe(false);
98+
expect(isP2pOrchestrationPrompt('Round up the results.')).toBe(false);
99+
expect(isP2pOrchestrationPrompt('Going for round 2')).toBe(false);
100+
});
101+
});
72102
});

0 commit comments

Comments
 (0)