fix: filter delivery-mirror from all consumer paths (LLM context, webchat, API)#40716
fix: filter delivery-mirror from all consumer paths (LLM context, webchat, API)#40716kiyoakii wants to merge 3 commits into
Conversation
Greptile SummaryThis PR fixes internal Key changes:
Confidence Score: 5/5
Last reviewed commit: f5c618e |
f5c618e to
1424398
Compare
f40da04 to
77a667d
Compare
This comment was marked as spam.
This comment was marked as spam.
|
@byungsker Thanks! All CI checks succeeded. Good to merge? |
This comment was marked as spam.
This comment was marked as spam.
77a667d to
a237940
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
|
Dedupe pass: keeping this as the main PR for the Track B assistant-message-shape slice under #69208. Why this one stays canonical:
This does not imply the full umbrella is fixed; it just makes this PR the clean candidate for the assistant-artifact consumer-path work. |
|
Codex review: needs changes before merge. Summary Reproducibility: yes. from source: current main writes Next step before merge Security Review findings
Review detailsBest possible solution: Refresh the canonical PR on current main, keep delivery-mirror rows as persisted audit data, and filter internal transcript artifacts from model-, WebChat-, and API-facing consumers without letting hidden rows consume visible history limits. Do we have a high-confidence way to reproduce the issue? Yes from source: current main writes Is this the best way to solve the issue? Yes, with a rebase caveat: consumer-boundary filtering is the narrow maintainable fix because it preserves the audit write path while hiding internal artifacts. The updated branch should account for current main's bounded session-history readers so filtering happens before visible limits are finalized. Full review comments:
Overall correctness: patch is correct Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 89a15fddaf84. |
…PI responses delivery-mirror entries (provider=openclaw, model=delivery-mirror) are internal cross-channel delivery audit records written by appendAssistantMessageToSessionTranscript(). They use appendMessage() which creates type:"message" entries indistinguishable from real LLM responses, causing them to leak into buildSessionContext() and API responses. This causes duplicate assistant messages in the LLM context window (escalating from 2x to 6-8x over a session), duplicate renders in webchat UI, and raw audit entries in API responses. Fix: filter delivery-mirror messages at the three consumer points: - transformContext pipeline (LLM context) - chat.history handler (webchat UI) - sessions.get handler (API) Add isDeliveryMirrorMessage() predicate co-located with the write path in transcript.ts. Add regression tests for all filter paths. The write path (appendMessage) is intentionally unchanged - delivery-mirror entries remain in the JSONL as an audit trail. appendCustomEntry() was considered but _persist() in SessionManager defers writes until an assistant message exists, making it unreliable for standalone audit entries. Fixes #33263, #38061, #39469 Related: #30316, #39795
- Move delivery-mirror filter before slice/byte-budget in chat.history so internal entries do not consume bounded window slots - Drop unnecessary .toLowerCase() on role check for consistent strict equality across all three predicate fields - Add symmetric test case for model match with provider mismatch
|
ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical. Source PR: #40716 |
a237940 to
3b99a1a
Compare
Problem
Internal
delivery-mirroraudit entries (provider=openclaw,model=delivery-mirror) leak into all three consumer paths, causing escalating duplicate assistant messages that degrade over the life of a session:thinkingblocks with errors visible to end users (BUG: Control UI (webchat) double-records assistant messages in session JSONL #39469)Fixes #33263, #38061, #39469.
Related: #30316, #39795.
Changes
tool-result-context-guard.tstransformContextpipelinechat.tssessions.tssessions.gethandlertranscript.tsisDeliveryMirrorMessage()usinginnarrowing (zero type assertions)The write path is intentionally unchanged — delivery-mirror entries remain in session JSONL as an audit trail.
appendCustomEntry()was investigated butSessionManager._persist()defers writes until atype:"message"+role:"assistant"entry exists, making it unreliable for standalone entries. Existing session files already contain old-format entries, so consumer-side filters are needed regardless.Tests
7 new tests across 2 files covering the predicate (positive match, role/provider/model mismatches, non-object input) and the
transformContextintegration (strips delivery-mirror; preserves array identity when none present).Unrelated
Commit
f5c618ebfixes a pre-existing oxfmt formatting issue insrc/cli/daemon-cli/lifecycle.test.ts.