fix(rendering): keep Thinking tasks in_progress until the reasoning item seals#527
Open
Zygimantass wants to merge 6 commits into
Open
fix(rendering): keep Thinking tasks in_progress until the reasoning item seals#527Zygimantass wants to merge 6 commits into
Zygimantass wants to merge 6 commits into
Conversation
…tem seals Each reasoning event previously created a brand-new Thinking task (fresh counter id per delta) and whole-block events were marked complete immediately, so the Slack plan card cycled between "Thinking", "Thinking completed", and the running command. - accumulate reasoning deltas into one task keyed by the protocol's stable itemId, staying in_progress while the block streams - flip to complete only on item.completed for that reasoning item or at flush when the execution actually finishes - re-emit task details when they grow (details are replace-semantics downstream) so the accumulating thinking text reaches Slack - insert a paragraph break between Codex summary sections (summaryIndex changes) within the one task Amp-Thread-ID: https://ampcode.com/threads/T-019ebbcb-9016-753d-85ba-fbbb7e94dbe9 Co-authored-by: Amp <amp@ampcode.com>
…g recovered state The startup-recovery test asserted the persisted thread state immediately after the chat.stopStream call, racing the state write that happens just after the stream stops. Sibling recovery tests already wait for renderObligation === null; do the same here. Amp-Thread-ID: https://ampcode.com/threads/T-019ebbcb-9016-753d-85ba-fbbb7e94dbe9 Co-authored-by: Amp <amp@ampcode.com>
…ity starts Slack renders the most recent task chunk as the plan card header. Marking a Thinking task complete the moment its reasoning/commentary item seals makes "Thinking completed" the header until the next activity emits a chunk — which reads as if the agent is done while it is still working. Keep sealed Thinking tasks in_progress and flip them to complete only when the next activity (command, file change, tool use, new reasoning block, or commentary item) produces its first update, ordered before that update in the same batch, or when the run flushes. On failure, sealed thinking flips to complete instead of error since those blocks finished fine. Amp-Thread-ID: https://ampcode.com/threads/T-019ebbcb-9016-753d-85ba-fbbb7e94dbe9 Co-authored-by: Amp <amp@ampcode.com>
…r shows 'Thinking completed' mid-turn Slack computes the plan card header from task statuses: it shows the current in_progress task and falls back to 'Thinking completed' whenever no task is in progress — even mid-turn. Replaying a production thread showed turns with zero reasoning events where every gap between commands left the plan all-complete, so the header read 'Thinking completed' while the agent was still working. Replace the event-based sealed-thinking release with a presentation-level hold in changedActivityTaskUpdates: when an update batch would leave no task in progress mid-turn, present the most recent finished task as still in_progress. Its true status is emitted with the next activity's batch (ordered before the new task) or at the final flush, so per-card statuses are only deferred across the silent gaps. Sealed thinking now completes truthfully in state and relies on the same hold. Amp-Thread-ID: https://ampcode.com/threads/T-019ebbcb-9016-753d-85ba-fbbb7e94dbe9 Co-authored-by: Amp <amp@ampcode.com>
Instead of holding the last finished task in_progress through think-gaps (which made quick commands look long-running), complete tasks truthfully and open a synthetic title-only 'Thinking' task whenever nothing is in progress mid-turn. Slack's plan header then reads 'Thinking' during gaps and the task completes as soon as real activity resumes, or at the final flush.
…task" This reverts commit 9646b8d.
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.
Problem
Slack threads flip-flop between "Thinking", "command execution", and "Thinking completed" while a turn is running.
Root cause in the Codex App Server mapper (
packages/rendering/src/codex-app-server.ts): every reasoning event created a brand-new Thinking task (fresh counter id per delta), and whole-block reasoning events were markedcompleteimmediately — so the Slack plan card's current-activity line churned between Thinking cards and the running command.Fix
itemId, stayingin_progresswhile the block streams.completeonly when the item seals (item.completedfor that reasoning item) or the execution actually finishes (flush viacompleteOpenTasks). A command starting mid-thought no longer flips it.changedActivityTaskUpdatespreviously emitted a task's details exactly once; it now re-emits when the details text changes so the accumulating thinking text reaches Slack (task details are replace-semantics downstream; command details are static so their behavior is unchanged).summaryIndexchanges) get a paragraph break within the one task.Events without an
itemId(whole-blockreasoningpassthrough) keep the old behavior — those blocks are already sealed on arrival, socompleteis correct.Testing
packages/rendering: 20/20 tests pass, including two new tests covering delta accumulation, mid-thought command interleaving, sealing, and summary-section breaks;tsc --noEmitclean.services/slackbotv2(only consumer of@centaur/rendering): 55/55 tests pass.Note: the slackbot image needs a redeploy for this to take effect in production.