Repository navigation
Conversation
…t tool [PRODEV-1742] Resolve settings.conversation_mode (absent = "single") for the conversational agent tool. single: the model passes only a message and every call continues the tool's one conversation. A conversation that ended or that AgentHub no longer has is replaced by a new one, the message is sent again to it, and the result says so in "note". multiple: the existing conversation_id / new_conversation arguments and error results. Both modes rebuild the current conversation from the replayed history when the tool state has none: each chat message is a new job with empty tools_storage, but the earlier results of this tool are in the messages. In advanced mode the graph's messages are injected into the tool (InjectedState) and read the same way. Bump to 0.18.50 and the uipath floor to 2.14.44. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 tasks done
…e history [PRODEV-1742] The history rebuild stopped at the tool's last result even when it said nothing about a live conversation, so one failed request, a cancelled confirmation or an interrupted call at the end of a chat message dropped the thread, while a conversation whose task had ended was seeded as open. It now walks the tool's results newest first: results without a conversation are skipped, a failed request still gives its conversation, and a conversation that a later result shows as ended (terminal task_state, or conversation_closed) is not reopened. Single mode: - the description adds "Make one call at a time.", since a parallel call cannot see the other's conversation; - its notes now say the agent has no memory of earlier messages; - an info log records conversation_id / new_conversation arguments that it ignores. Tests cover the orderings and a round trip through the real chat message mapper, with names that need sanitising. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This branch has not been deployed
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.


PR stack (PRODEV-1742 conversation mode), merge in this order
settings.conversationMode(single | multiple, absent = single). https://github.com/UiPath/Agents/pull/6761Problem
The conversational agent tool always showed the model
conversation_idandnew_conversation, and its state lives intools_storage, which is empty at the start of every job. Every chat message of a low-code conversational agent is a new job, so a call with no id started a new conversation even though the hint says it continues the most recent one. Most agents only ever want one conversation with the tool.What this does
Resolves the mode as
config.settings.conversation_mode or "single"(needs [2/5]).single(default): the tool takes onlymessage(A2aSingleConversationInput, noconversation_id, nonew_conversation) and its description adds "Each call continues one ongoing conversation with this agent. Make one call at a time." Every call continues the tool's conversation, within a job, across jobs, and in advanced mode. When that conversation has ended (terminal task state) or AgentHub no longer has it (TaskNotFound/ terminal-state error), a new one is started and the result carries anote. If the request itself hit the unavailable conversation, the same message is sent once to the new one, because AgentHub refused it without acting on it. Every single-modenoteends with "The agent has no memory of earlier messages; if your message depends on earlier context, send it again with that context." The model never seesconversation_closed. The result still includesconversation_id, which the history rebuild reads.multiple: the same arguments, description, error JSON shapes and per-tool behaviour as before (itsnotetext is unchanged).Cross-message continuity (both modes). When a call starts and the tool state has no current conversation, it is rebuilt from the replayed messages (
_conversation_id_from_historyinconversational_agent_tool.py). It walksstate.messagesnewest to oldest over this tool's results, matched through the nearest precedingAIMessage.tool_callsentry (tool_call_idto tool name), withToolMessage.nameonly as a fallback because replay does not set it. Each result is read as:status="error"message, a plain error string, a cancelled confirmation{"meta": ...}, an interrupted call with empty content, invalid JSON): skipped, so the walk continues to the previous result;request_failed): itsconversation_idcounts, because the conversation is still alive;task_stateofcompleted/failed/canceled/rejected, orconversation_closed): remembered as ended and skipped, along with any older result of the same conversation;A result wrapped by the conversational-confirmation "args modified" envelope is unwrapped. A conversation the state already knows (for instance one that ended in this job) is never reopened from history.
Advanced (deepagents) mode. The tool coroutine takes
messages: Annotated[Sequence[AnyMessage], InjectedState("messages")], which the deepagents tool node injects, and derives the current conversation from those messages exactly as in 4. The injected argument is declared on the function, not onargs_schema, so the model-facing schema staysmessageonly (checked withconvert_to_openai_tool). No closure-level registry, so cached tool instances carry nothing between runs. Verified end to end with a realcreate_advanced_agentgraph.Changes beyond the title
conversationModebehaved as multiple (the model sawconversation_idandnew_conversation); once this is released they expose onlymessage. In single mode aconversation_idornew_conversationthat the model still sends (for example copied from earlier turns) is ignored: the ReAct wrapper logs it at info level; in advanced mode the tool schema drops extra arguments before the tool runs, so nothing is logged there.multiplemode now continues on a call with no id (it used to always start a new conversation, because nothing was stored). It reads the history like the ReAct path, which is what the existing hint promises. Called outside a graph, with no messages, it still starts a new one every time. Tests:test_advanced_multiple_mode_reads_the_history_and_honors_the_handles,test_conversational_stateless_no_args_starts_a_new_conversation_each_time(unchanged)._conversetail is factored into_record_reply(shared with single mode), with identical behaviour. The test helpers default the resource tomultiple, since the existing tests exercise the handle arguments.Known limits
messagesis a snapshot, so a lock would not help. The description asks the model to make one call at a time. There is no per-conversation lock inmaintoday, concurrent sends are allowed.messagesis in deepagents'_EXCLUDED_STATE_KEYS), so a subagent's first call opens its own conversation and later calls in that subagent continue it.note.After the releases
uipath>=2.14.44is not on PyPI until [2/5] is released.pyproject.tomland the version and specifier lines ofuv.lockare updated, but the lockeduipathentry still resolves 2.14.40, which lacksAgentConversationalAgentToolSettings, so CI fails until then. Once [2/5] has published 2.14.44, runuv lock --upgrade-package uipathand commituv.lock.Verification
pytestontest_conversational_agent_tool.py(163),test_a2a_tool.py,test_tool_factory.py,test_a2a_sdk_v1_migration.py,tests/agent/advancedandtest_no_circular_imports.py: 592 passed. The new tests failed before the change. They include a round trip through the realUiPathChatMessagesMapper(AIMessage and ToolMessage to CAS events, replayed back), with names that need sanitising.tests/agentas a whole (first pass): only 4 failures, none related: a Windows symlink privilege anduipCLI lookups (test_create_file_tool,test_uipath_cli_tool).uipath-pythonbranch of [2/5] (editable, not committed).ruff check,ruff format --check,mypy --config-file pyproject.toml .(424 files),scripts/lint_httpx_client.py: clean.🤖 Generated with Claude Code