fix: preserve interrupted assistant text#817
Conversation
🦋 Changeset detectedLatest commit: 400df7e The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd44ed8bfe
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| response = await chatWithRetry({ | ||
| llm, | ||
| params: chatParams, |
There was a problem hiding this comment.
Reset buffered deltas between retry attempts
In the retry path, chatWithRetry reuses these same streaming callbacks for every attempt. If an earlier attempt emits text or thinking deltas and then fails with a retryable error, the new buffers keep those discarded deltas; if a later attempt is cancelled, flushInterruptedAssistantParts() persists the stale output into content.part, so resumed history can include assistant content from a request the retry layer threw away. Scope the buffers to a single attempt or clear them when step.retrying is emitted.
Useful? React with 👍 / 👎.
bd44ed8 to
93be955
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3dbe1f0f8c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| step: currentStep, | ||
| stepUuid, | ||
| part, | ||
| part: { type: 'think', think: bufferedThink }, |
There was a problem hiding this comment.
Preserve thinking signatures on abort flush
With signed-thinking providers, this synthesizes an aborted think part from only bufferedThink. KosongLLM forwards streamed thinking through onThinkDelta(part.think) only, so any encrypted signature on the streamed ThinkPart is not available here; after cancelling once text has started, the transcript can contain unsigned thinking, and the Anthropic conversion path skips unsigned Claude thinking on the next request. That makes resume/follow-up lose the reasoning block this change is trying to preserve, so the abort buffer needs to carry the completed/signature data or avoid writing unsigned signed-provider thinking.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 400df7ea63
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Related Issue
No linked issue; this addresses interrupted assistant output being lost across session resume.
Problem
When a turn is cancelled or a session closes during streaming, visible assistant text that has already been shown can be lost if the provider has not emitted a completed content part yet. Resuming that session then continues without the partially emitted assistant message.
Thinking-only interruptions still need to avoid persisting orphaned thinking context. However, once visible assistant text has started, the preceding thinking is part of the same assistant response and should be preserved with that response.
What changed
Verification
pnpm vitest run packages/node-sdk/test/session-prompt-events.test.ts packages/agent-core/test/loop/streaming.e2e.test.tspnpm --filter @moonshot-ai/agent-core typecheckpnpm --filter @moonshot-ai/kimi-code-sdk typecheckpnpm run buildfromdocs/git diff --checkChecklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.