[WIP/reference] CAS migration: interrupt → event-based tool confirmation#105
Closed
JoshParkSJ wants to merge 1 commit intomainfrom
Closed
[WIP/reference] CAS migration: interrupt → event-based tool confirmation#105JoshParkSJ wants to merge 1 commit intomainfrom
JoshParkSJ wants to merge 1 commit intomainfrom
Conversation
Migrates the dev console from the old interrupt-based tool-confirmation flow to the event-based flow that landed in uipath-python#1558, uipath-langchain-python#703, and uipath-agents-python#420. Status: closed as a reference. Approve flow E2E-verified; reject path fixes shipped late and were not E2E-verified before scope was reset.
Contributor
Author
|
Closing as reference. Restarting from main with a minimum-delta scope; will reopen this scope as a separate PR once the floor changes are in. |
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.
Status: draft, will be closed immediately. This PR exists as a reference snapshot of an in-progress migration. Scope grew larger than wanted; restarting from
mainwith a minimal-diff approach. Branch will not be deleted so this is recoverable later.What this migrates
Old: agent runtime emits an
interruptevent carryingUiPathConversationToolCallConfirmationValue; bridge waits viawait_for_resume; UI sendschat.interrupt_response; bridge resumes viaresume(...).New (matches recently merged PRs in sibling repos): agent emits
startToolCallwithrequireConfirmation=trueandinputSchemadirectly on the start event; runtime yieldsSUSPENDEDwith a placeholder API trigger soUiPathChatRuntimecallsbridge.wait_for_resume(); user clicks Approve/Reject inline on the tool chip; UI sendschat.confirm_tool_call; backend callsbridge.set_tool_confirmation(UiPathConversationToolCallConfirmationEvent(...))which unblockswait_for_resume.UiPathChatRuntimethen resumes the runtime withcurrent_input = {interrupt_id: {approved, input}}.Reference PRs (all merged):
7fc96acBackend changes
pyproject.toml— version 0.0.78 → 0.0.79;uipathfloor tightened to>=2.10.57, <2.11.0.uv.lockrefreshed.services/chat_bridge.py— full rewrite mirroringSocketIOChatBridge. Adds_tool_confirmation_event/_tool_confirmation_value,set_tool_confirmation(),wait_for_resume()returning a dict viamodel_dump.emit_interrupt_eventis documented no-op.resume()/on_interruptremoved.services/run_service.py— addsconfirm_tool_call(run_id, approved, input); removes_handle_interrupt,resume_chat,on_interruptcallback,InterruptCallbackalias,UiPathResumeTriggerimport.server/ws/protocol.py— addsClientCommand.CHAT_CONFIRM_TOOL_CALL = \"chat.confirm_tool_call\"; removesCHAT_INTERRUPT_RESPONSEandServerEvent.CHAT_INTERRUPT.server/ws/handler.py— adds_handle_confirm_tool_call; removes_handle_interrupt_response.server/ws/manager.py— removesbroadcast_interrupt.server/serializers.py— removesserialize_interrupt.server/__init__.py— dropson_interrupt=kwarg.models/data.py— removesInterruptData.models/chat.py— removes the now-unsupportedinterrupts=[]arg fromUiPathConversationMessage(mypy).Frontend changes (
src/uipath/dev/server/frontend/)types/run.ts—ToolCallextended withrequire_confirmation,input_schema,confirmation.InterruptEventremoved.types/ws.ts— addschat.confirm_tool_call; removeschat.interruptandchat.interrupt_response.api/websocket.ts—sendConfirmToolCall(runId, toolCallId, approved, input?); removessendInterruptResponse.store/useRunStore.ts—ChatToolCallinterface;projectToolCallhelper that surfaces camelCase→snake.addChatEventreadsevent.toolCall.startToolCallforrequireConfirmation/inputSchema/input(which are absent from the persistedmessage.toolCallsentry) and merges with prior in-store state across subsequent events. Surfacesresult.cancelled. RemovesactiveInterrupt/setActiveInterrupt.store/useWebSocket.ts— removeschat.interruptcase.App.tsx— usesprojectToolCall.components/chat/ChatInterrupt.tsx— DELETED.components/chat/ChatMessage.tsx— addsToolCallConfirmPanelrendered inline below the tool chip whenrequire_confirmation && !confirmation && !has_result. Chip renders red `✗` whencancelled === true.components/chat/ChatPanel.tsx— wireshandleConfirmToolCall; derivesawaitingConfirmationfrom messages.components/runs/RunDetailsPanel.tsx—awaitingConfirmationderived fromchatMessages.Demo (
demo/mock_support_runtime.py)For
needs_approval=Trueturns: emitsstartToolCall(requireConfirmation=true, inputSchema=...), then yieldsSUSPENDEDwith an APIUiPathResumeTrigger. On resume readsinput.get(interrupt_id, {}).get(\"approved\")and emitstoolCallEnd(cancelled=not approved). On rejection now yieldsUiPathRuntimeResult(SUCCESSFUL)soUiPathChatRuntimeexits cleanly — without this it loops back intodelegate.stream()and falls through to the next turn.Tests
tests/test_chat_bridge.py— 5 tests covering the new bridge contract (happy path, reject, no-op interrupt, multi-confirm, disconnect unblocks waiter).uv run ruff check src/ tests/clean.uv run ruff format --check .clean.uv run mypy src/clean.E2E status
chat.confirm_tool_calloutbound on Approvechat.confirm_tool_calloutbound on Rejectexecutechip turns red✗on RejectWhy this is being closed
Migration scope outgrew the appetite for a single change. Restarting from
mainwith the minimum delta needed to keep cross-repo tests green and the dev console functional, then layering the migration on later as a smaller follow-up.Backup tag
backup/main-20260427-135849was created onmainbefore this work began.