Skip to content

ui: fix stop/continue during an agentic loop#23356

Open
ServeurpersoCom wants to merge 2 commits into
ggml-org:masterfrom
ServeurpersoCom:ui/fix-continue-mcp
Open

ui: fix stop/continue during an agentic loop#23356
ServeurpersoCom wants to merge 2 commits into
ggml-org:masterfrom
ServeurpersoCom:ui/fix-continue-mcp

Conversation

@ServeurpersoCom
Copy link
Copy Markdown
Contributor

Overview

fix: continue button preserves tool_calls and routes through the agentic loop

The Continue button was rebuilding the final assistant message by hand as role plus content plus reasoning_content, dropping tool_calls and attachments from the persisted DatabaseMessage, which broke continue_final_message for any turn carrying tool_calls.

Additional information

A pure classifier in lib/utils/agentic.ts now walks the history around the target and returns append_text, rerun_turn, or next_turn, and continueAssistantMessage dispatches accordingly: classical resume for plain text, branch via regenerateMessageWithBranching when tool_calls have no results yet, or anchor a fresh agentic turn at the last tool result.

10 unit tests cover the classifier, the full vitest suite stays at 224/224, type check and prod build are clean.

Requirements

@aldehir
Copy link
Copy Markdown
Contributor

aldehir commented May 19, 2026

Just want to mention that it is not feasible to resume a partial tool call with the chat completions API. There are too many models/templates to transform partial JSON to their respective tool calling notation. The maintenance cost is not worth it IMO.

If this is desired, then the continue logic needs to be re-imagined to one of the following:

  • A stateful backend that preserves the raw generation. This could be something built within your background task implementation.
  • Emit raw generation deltas along side the normal deltas in the SSE stream. More traffic and worse for unstable connections.

The logic here looks fine from a prompt construction view. Worse case, the tool call would need to be regenerated from scratch but could still be seeded with the reasoning/content.

@ServeurpersoCom
Copy link
Copy Markdown
Contributor Author

We can improve it a little by seeding the regenerated turn with the reasoning/content already produced before the cut, so a continue lands in the CoT of the last tool call instead of regenerating it from scratch, but we can't do any better than that.

@ServeurpersoCom
Copy link
Copy Markdown
Contributor Author

It adds quite a bit of complexity, because seeding the CoT is only useful if the regenerated turn re enters the agentic loop so the tool call actually fires, otherwise the user just sees the tool call reappear without running, so regenerating from scratch stays way simpler.

@allozaur allozaur self-assigned this May 20, 2026
Comment thread tools/ui/src/lib/stores/chat.svelte.ts Outdated
Comment thread tools/ui/src/lib/utils/agentic.ts Outdated
Address allozaur review: replace the kind string literals in the ContinueIntent
union with a ContinueIntentKind enum (append_text, rerun_turn, next_turn), next
to the other agentic enums. Producers, the chat store consumers and the unit
test all reference the enum, no magic strings left.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants