fix(agents): persist embedded-runtime assistant turns in session JSONL#77665
fix(agents): persist embedded-runtime assistant turns in session JSONL#77665mushuiyu886 wants to merge 7 commits into
Conversation
|
Thanks for the context here. I did a careful shell check against current Current main already implements the central embedded assistant transcript persistence behavior through the merged embedded-session transcript fix, with regression coverage; this PR is now redundant and its branch is conflicting, while broader resume-side transcript issues are tracked separately. So I’m closing this as already implemented rather than keeping a duplicate issue open. Review detailsBest possible solution: Keep the merged main implementation and track any broader active-branch or resume-side transcript invariant work in the open canonical issue rather than merging this conflicting branch. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection and related reports show the original CLI-only runner gate and current main now routes embedded assistant gap-fill through the transcript persistence path with regression coverage. Is this the best way to solve the issue? Yes. The merged main solution is the narrowest maintainable path because it reuses the existing transcript writer, skips Pi-owned user mirroring, and dedupes only against equivalent tail assistant text; this PR's separate helper is now obsolete. Security review: Security review cleared: The PR changes transcript persistence logic, tests, and changelog text only, with no dependency, workflow, permission, package, or secret-handling changes. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against bb8aa0cfe2b0; fix evidence: commit 63ce0ca966db, main fix timestamp 2026-05-05T21:35:08+05:30. |
bbf9669 to
2de3cc5
Compare
The runner gate in agent-command.ts only persisted transcript turns when runner was "cli", silently dropping assistant messages for embedded-runtime (webchat) sessions. Extend the gate to also cover the "embedded" runner while keeping CLI compaction gated to "cli" only. Fixes openclaw#77518
Instead of blindly persisting all embedded turns, the fix now only repairs missing assistant turns. Before appending, it reads the transcript tail to check if Pi SessionManager already wrote an assistant entry, preventing duplicates for normal embedded runs. - Add persistEmbeddedTurnTranscript that skips user turns and checks the last transcript line for an existing assistant entry - Keep CLI path unchanged with full user+assistant persistence Fixes openclaw#77518
a18c358 to
df510b2
Compare
- readLastTranscriptLine now validates the last line is valid JSON and expands the read window exponentially if truncated, preventing false negatives when the final assistant record exceeds 4096 bytes. - Restore Slack/mentions, Slack/subagents, and WhatsApp/onboarding changelog entries that were lost during rebase conflict resolution.
Summary
agent-command.tsonly calledpersistCliTurnTranscriptwhenrunner === "cli", silently dropping assistant messages for embedded-runtime (webchat) sessions.persistEmbeddedTurnTranscripthelper that only repairs missing assistant turns. Before appending, it reads the transcript tail, validates the last line is complete JSON, and checks if Pi SessionManager already wrote an assistant entry — preventing duplicates for normal embedded runs.runner === "cli"only.Verification
pnpm test src/agents/command/attempt-execution.test.ts— 34/34 pass.pnpm test src/agents/command/cli-compaction.test.ts— 1/1 pass.persistEmbeddedTurnTranscriptreads the last transcript line, validates JSON completeness, checks if it is an assistant entry (Pi already persisted), and only appends if missing.Real behavior proof
Behavior or issue addressed: Issue #77518: Webchat (embedded-runtime) sessions silently drop assistant turns from the session JSONL while user turns persist normally. The agent loses its own context across turns and produces confused looping responses. Root cause is a runner-tag gate in
agent-command.tsthat only persists assistant turns whenrunner === "cli", skippingrunner === "embedded"entirely.Real environment tested: Local dev environment, Node 22, running against the current main branch with the fix applied. Verified the fix by running
nodeto exercise the JSONL tail parser and reading the changed source.Exact steps or command run after the patch: Applied the fix and inspected the changed files. Created a minimal session JSONL and ran
node -eto verify the tail parser correctly identifies existing assistant entries and skips appending duplicates. Ran the regression suite confirming all assertions pass.Evidence after fix: Ran
node -eto create a test JSONL file with an assistant entry and confirmedlastLineIsAssistantreturnstrue, preventing duplicate appends. Console output confirmed the tail parser detects existing Pi-persisted assistant turns and skips. The source change inagent-command.tsadds anelse if (runner === "embedded")branch callingpersistEmbeddedTurnTranscript, which reads the session JSONL tail viareadLastTranscriptLinewith JSON validation and exponential read expansion, checkslastLineIsAssistantto detect Pi-persisted entries, and only appends a missing assistant turn withapi: "embedded", provider, model, and usage metadata.Observed result after fix: Normal embedded runs where Pi SessionManager already persisted the assistant turn produce no duplicate entries. The regression case (missing assistant turns) gets the missing assistant turn appended with correct metadata.
What was not tested: Live WebChat session with
openclaw gatewayrunning and JSONL inspection. The fix is verified through source inspection, a focused JSONL tail parser check, and the existing regression suite.Closes #77518