fix(ai): preserve custom tool replay during compaction#256
Open
ThewindMom wants to merge 3 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fix Codex/OpenAI Responses compaction replay so persisted custom/freeform tool calls with the |custom item-ID suffix remain custom_tool_call and custom_tool_call_output even when compaction intentionally provides no active tool definitions. Preserve call/output pairing, do not rewrite session JSONL IDs, keep normal function-call replay unchanged, add focused regression coverage, and verify the repaired behavior through a real restarted Senpi /compact flow.
What Changed
|custommarker through OpenAI Responses ID normalization so persisted freeform calls and outputs replay ascustom_tool_callpairs without active tool definitions.Risk Assessment
✅ Low: The change is narrowly scoped, fixes the previously identified cross-model/API normalization gap, preserves ordinary function-call behavior and pairing, and has focused regression coverage plus existing restarted-compaction evidence.
Testing
Focused and replay-policy tests passed after correcting an initial duplicate
--runCLI invocation; the isolated QA harness passed, and a real two-launch Senpi/compactflow produced reviewer-visible evidence confirming zero active tool definitions, preserved custom/function call pairing, unchanged persisted IDs, and successful compaction. The worktree was left clean.Evidence: Restarted /compact QA transcript
All 15 end-to-end assertions passed, including custom/function pairing, zero active tool definitions, append-only JSONL, and byte-identical persisted IDs.Evidence: Captured OpenAI Responses request
Evidence: Rendered TUI capture after restarted /compact
Evidence: Session JSONL before compaction
Evidence: Session JSONL after compaction
Evidence: Evidence summary
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
packages/ai/src/api/openai-responses-shared.ts:258- Required criterion: persisted calls with the|customsuffix must remaincustom_tool_call/custom_tool_call_outputwithout active definitions. This new check runs only aftertransformMessages; for history from a different model/API, normalization at lines 152–163 changes|customto|fc_customor a hashed|fc_*, so this condition is false and both items replay as ordinary function items. Confirm whether model-switched history is intentionally excluded; otherwise preserve the custom marker through normalization and cover that case.🔧 Fix: Preserve custom tool replay across model switches
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
cd packages/ai && npm test -- test/openai-responses-custom-tools.test.tscd packages/ai && npm test -- test/openai-responses-custom-tools.test.ts test/model-switch-replay-policy-table.test.ts test/model-switch-replay-characterization.test.tsnode .agents/skills/senpi-qa/scripts/lib/common.mjs --self-checknode /tmp/no-mistakes-evidence/01KY0V3NR98X8BY3PBWB3BMT3F/restarted-compact-qa.mjsTwo real source-CLI TUI launches against the same isolated persisted session; submitted/compactafter restart and inspected the rendered result, localhost Responses payload, and before/after JSONL.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
Summary by cubic
Preserves custom/freeform tool call replay during
/compactand model/API switches by keeping the|customitem ID suffix through OpenAI Responses normalization. Prevents misclassification to function calls and keeps call/output pairs and persisted IDs intact.custom_tool_callandcustom_tool_call_outputreplay correctly with no active tool definitions; ordinary function-call replay unchanged.packages/aiandpackages/coding-agent.Written for commit b0faab7. Summary will update on new commits.