Skip to content

fix(agents): persist embedded-runtime assistant turns in session JSONL#77665

Closed
mushuiyu886 wants to merge 7 commits into
openclaw:mainfrom
mushuiyu886:fix/77518-embedded-runner-transcript-persistence
Closed

fix(agents): persist embedded-runtime assistant turns in session JSONL#77665
mushuiyu886 wants to merge 7 commits into
openclaw:mainfrom
mushuiyu886:fix/77518-embedded-runner-transcript-persistence

Conversation

@mushuiyu886

@mushuiyu886 mushuiyu886 commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The runner gate in agent-command.ts only called persistCliTurnTranscript when runner === "cli", silently dropping assistant messages for embedded-runtime (webchat) sessions.
  • Added a new persistEmbeddedTurnTranscript helper 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.
  • CLI-specific compaction lifecycle remains gated to runner === "cli" only.

Verification

  • Ran pnpm test src/agents/command/attempt-execution.test.ts — 34/34 pass.
  • Ran pnpm test src/agents/command/cli-compaction.test.ts — 1/1 pass.
  • Traced the code path: persistEmbeddedTurnTranscript reads 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.ts that only persists assistant turns when runner === "cli", skipping runner === "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 node to 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 -e to 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 -e to create a test JSONL file with an assistant entry and confirmed lastLineIsAssistant returns true, preventing duplicate appends. Console output confirmed the tail parser detects existing Pi-persisted assistant turns and skips. The source change in agent-command.ts adds an else if (runner === "embedded") branch calling persistEmbeddedTurnTranscript, which reads the session JSONL tail via readLastTranscriptLine with JSON validation and exponential read expansion, checks lastLineIsAssistant to detect Pi-persisted entries, and only appends a missing assistant turn with api: "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 gateway running and JSONL inspection. The fix is verified through source inspection, a focused JSONL tail parser check, and the existing regression suite.

Closes #77518

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels May 5, 2026
@clawsweeper

clawsweeper Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I did a careful shell check against current main, and this is already implemented.

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 details

Best 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:

  • neeravmakwana: Authored the merged implementation PR that added embedded runner transcript persistence and assistant gap-fill behavior now present on main. (role: introduced merged fix; confidence: high; commits: 84c38f6fedd9, 333de75a5193; files: src/agents/agent-command.ts, src/agents/command/attempt-execution.ts, src/config/sessions/transcript.ts)
  • obviyus: Reviewed, tightened, and landed the merged embedded transcript fix, including the tail-dedupe behavior and merge commit. (role: reviewer and merger; confidence: high; commits: e8e81078bd28, 3f7d994b61bd, 63ce0ca966db; files: src/agents/command/attempt-execution.ts, CHANGELOG.md)
  • steipete: Current-main blame in this checkout points the affected agent/session transcript lines and tests to the latest main snapshot commit, making this a reasonable routing candidate for current source provenance. (role: current area contributor; confidence: medium; commits: 3225ec43c887; files: src/agents/agent-command.ts, src/agents/command/attempt-execution.ts, src/commands/agent.test.ts)

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.

@mushuiyu886
mushuiyu886 force-pushed the fix/77518-embedded-runner-transcript-persistence branch from bbf9669 to 2de3cc5 Compare May 5, 2026 05:15
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 5, 2026
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
- 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.
@openclaw-barnacle openclaw-barnacle Bot added the proof: supplied External PR includes structured after-fix real behavior proof. label May 6, 2026
@clawsweeper clawsweeper Bot closed this May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling proof: supplied External PR includes structured after-fix real behavior proof. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webchat persistence regression: embedded-runtime turns skip persistCliTurnTranscript causing silent assistant message drops

1 participant