feat(uipath-maestro-flow): add the conversational-agent plugin — text chat flows - #2974
feat(uipath-maestro-flow): add the conversational-agent plugin — text chat flows#2974andrewwan-uipath wants to merge 5 commits into
Conversation
… chat flows Teaches agents to build a text chat: `core.trigger.conversation` -> wait for message -> a conversational agent -> back to waiting, plus send-message and get-conversation-context. The agent can be inline, in-solution, or published, and the plugin says to ask rather than default — the choice decides the node type, the ports, and whether anything gets scaffolded. Inline continues on `success`; the other two use `uipath.core.agent.<id>` and continue on `output`. Registered in CAPABILITY, planning-arch, planning-impl, brownfield and node-output-wiring. The `agent` plugin picks up a Conversational section for the node type it already owns, and points here for the loop. Also covers the traps that pass `flow validate` silently: binding `context` and `conversationId` while dropping the other three settings keys ships an agent with no chat history; `waitForMessage1.output.exchangeId` and the agent's `output.response` do not exist; a `=js:` string is the pre-1.3 form and renders as literal text. Tests: one offline coder-eval task plus a checker, verified against real inline and in-solution builds and against six wrong ones. Depends on UiPath/cli#3827 — until that merges the conversational node types do not resolve on any published CLI, and the first command here fails. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @andrewwan-uipath's task in 4m 40s —— View job PR Review: feat(uipath-maestro-flow): conversational-agent plugin
SummaryAdds a Change-by-Change Review1.
|
| Area | Status | Notes |
|---|---|---|
| Frontmatter | OK | Description 733 chars, valid YAML, name matches folder |
| E2E Tests | Medium | Smoke test present and well-structured; e2e missing (blocked on CLI #3827) |
| Skill Body | OK | Bullet and description additions are terse and correctly placed |
| References & Assets | OK | Two new plugin files + thorough registration across 7 index surfaces; reference pointer discipline followed in bridge sections |
| Repo Hygiene | OK | CODEOWNERS updated, no secrets, no cross-skill deps, scoped changes |
Issues for Manual Review
- CLI dependency gate — the four text conversational node types (
core.trigger.conversation,uipath.conversational.*,uipath.agent.conversational) exist only on UiPath/cli#3827. Until that lands,registry get core.trigger.conversationreturns "Node type not found" on any publisheduip. The skill documentation is correct for the target CLI, but cannot be verified end-to-end today. - Port accuracy —
uipath.agent.conversationalis documented with portssuccess, escalation, context, tool(noerror), distinguishing it fromuipath.agent.autonomouswhich haserror. This should be verified against the registry once the CLI branch lands. - Voice keyword in SKILL.md — the PR adds
voice, phone callsto the frontmatter description. The PR author asks @JoshParkSJ to review the two voice-mentioning lines. No voice file is touched. maxIterationscap of 8 — documented as a designer enforcement, not a validator check. Should be confirmed against the conversational node manifest from the CLI once available.
Conclusion
Clean, thorough PR. The plugin follows established conventions precisely, registration is comprehensive across all index surfaces, and the test checker is well-designed with real structural validation. The only gap is the missing e2e task, which is explicitly blocked on an external CLI dependency and appropriately acknowledged. No changes requested — this is ready for domain-owner review (particularly the voice-keyword additions flagged for @JoshParkSJ).
|
Claude finished @andrewwan-uipath's task in 2m 17s —— View job Coder-eval task lint (advisory)1 task YAML changed; verdicts: 0 Critical, 1 High, 0 Medium, 0 Low, 0 OK. Rubric: .claude/commands/lint-task.md. This check is advisory and never blocks merge. Evidence of passing run❌ High — PR body explicitly states: "The eval task has never been run through coder-eval — it cannot be until #3827 is in the sandbox image." The transparency is appreciated (and the checker script was verified against real projects), but the convention requires a passing-run claim before merge. Please edit the PR description to add a line like Per-task lint
|
There was a problem hiding this comment.
🟡 Changes recommended
The new chat-loop structural checker currently doesn’t strictly verify the agent’s edge loops back to a wait-for-message node (and has a misleading docstring), which can allow incorrect flow topology to pass the task.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR extends the uipath-maestro-flow skill with first-class guidance for building text conversational chat flows (conversation trigger → wait-for-message → conversational agent → loop), including supporting documentation updates, an offline evaluation task, and ownership registration.
Changes:
- Add a new
conversational-agentauthoring plugin (planning + implementation guidance) and wire it into the skill’s planning/capability indices. - Add an offline eval task + Python structural checker to grade common “validates but fails at runtime” chat-flow mistakes.
- Update shared wiring guidance, operate/diagnose capability rows, and CODEOWNERS to include the new chat surface area.
File summaries
| File | Description |
|---|---|
| tests/tasks/uipath-maestro-flow/conversational/conversational_chat_loop.yaml | New offline task definition for generating and validating a minimal text chat loop flow. |
| tests/tasks/uipath-maestro-flow/conversational/check_conversational_flow.py | New structural checker for chat settings wiring, loop topology, and conversational agent.json requirements. |
| skills/uipath-maestro-flow/SKILL.md | Updates the skill description to explicitly include conversational/chat flows as supported work. |
| skills/uipath-maestro-flow/references/shared/node-output-wiring.md | Adds wiring rules for chat nodes (conversationId, exchangeId, conversationalAgentSettings). |
| skills/uipath-maestro-flow/references/operate/CAPABILITY.md | Adds an operate-row documenting flow debug Studio Web handoff behavior for chat flows. |
| skills/uipath-maestro-flow/references/diagnose/CAPABILITY.md | Adds diagnose rows for common chat-agent discovery/debug pitfalls. |
| skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md | New planning plugin describing node types, topology, and flavor selection for text chat agents. |
| skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md | New implementation plugin with concrete CLI/json wiring instructions and pitfalls. |
| skills/uipath-maestro-flow/references/author/plugins/agent/planning.md | Adds a “Conversational Agents” section pointing chat flows to the new plugin. |
| skills/uipath-maestro-flow/references/author/plugins/agent/impl.md | Adds a “Conversational Agents” note and linkback for implementation details. |
| skills/uipath-maestro-flow/references/author/planning-impl.md | Registers the new node types to the implementation index. |
| skills/uipath-maestro-flow/references/author/planning-arch.md | Adds trigger/node/port rows and heuristics for conversational text flows. |
| skills/uipath-maestro-flow/references/author/CAPABILITY.md | Adds “Chat” authoring inventory + navigation entry to the new plugin. |
| skills/uipath-maestro-flow/references/author/brownfield.md | Adds a brownfield recipe row for turning an existing flow into a chat loop. |
| CODEOWNERS | Adds ownership entries for the new plugin docs and conversational task folder. |
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…s port Review feedback on the checker: - `check_loop` asserted the agent's continuation port but not its target, so an agent wired to a dead end passed while the chat could never take a second turn. It now requires the edge to return to a wait-for-message node. - Checking that turned up the opposite problem: every outgoing edge was graded against the continuation port, so a legitimate `escalation`, `context` or `tool` wire failed. Only the continuation edge is graded now. - The docstring said the agent continues on `success`; it depends on the flavor, which the implementation already handled. Verified: a dead-end loop and a wrong port both fail, an escalation wire alongside the loop passes, and the real inline and in-solution builds still pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new conversational flow checker has a logic hole where check_loop() can pass without any conversational agent nodes, and the exclusions list is inconsistent with other checkers, risking unreliable grading.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
tests/tasks/uipath-maestro-flow/conversational/check_conversational_flow.py:58
EXCLUDED_PARTSis described as matching the other maestro-flow checkers, but it currently omits entries likenode_modulesthat those checkers exclude. This can cause the checker to accidentally pick up staged/cached copies and report misleading failures when a project includes those directories.
tests/tasks/uipath-maestro-flow/conversational/check_conversational_flow.py:354check_agent_json()takesflow_pathbut never uses it (and it’s only threaded through from_load_flow()). This unused parameter makes the checker harder to read and suggests a missing behavior (e.g., using the flow’s location to scope the agent.json search or for diagnostics).
- Files reviewed: 15/15 changed files
- Comments generated: 1
- Review effort level: Lite
…loop pass through send-message Two follow-ups on the loop check: - It passed vacuously when the flow had no conversational agent node, because it iterated an empty map. Unreachable through main() — _load_flow exits first — but check_settings and check_agent_json both guard, so this one now does too. - The previous fix demanded a direct edge from the agent to the wait node, which rejected agent -> send-message -> wait. That is the shape the CLI's own fixture and scenario doc use. It now walks the graph, so the wait node has to be reachable rather than adjacent. Verified: both loop shapes pass, a dead-end loop and a wrong port fail, an escalation wire alongside the loop passes, and a flow with no agent fails. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The grader accepts invalid or disconnected flows, while key documentation contains contradictory identity, ownership, binding, and offline-login guidance.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (10)
Previously missed (9) — in code that hasn't changed since the last review.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:14
- The next paragraph consumes
Data.ProjectId, so this command must request the stable JSON envelope. Omitting--output jsoncontradicts the established inline-agent and voice scaffolding examples and can leave the agent without a reliably extractable source UUID.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md:107 - This scaffolding command's returned
ProjectIdis used at line 110, so it needs--output jsonto expose the stableData.ProjectIdcontract. The neighboring inline-agent and inline-voice guides already follow this convention.
skills/uipath-maestro-flow/references/author/plugins/agent/impl.md:199 - This command regresses the terminology established earlier in this file: in-solution node types use the local solution
resource.key, not the agent project'sprojectId(agent/impl.md:95-118). With the current placeholder, readers will query a node type that does not exist.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:100 - This statement is too broad and contradicts the shared wiring contract: connector/HTTP value fields, End outputs, loops, and subflows still use
=js:strings (shared/node-output-wiring.md:57-79). Only these conversational input fields use structuredjsExpressionobjects; saying every.flowbinding does so can break unrelated nodes.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:127 - These commands conflict with the canonical ownership table, which explicitly classifies all chat nodes as user-owned and reserves
node add/node configurefor connector, event, and managed-HTTP nodes (author/CAPABILITY.md:24-49). The inline-agent guide also forbids Flow CLI graph edits (inline-agent/impl.md:519). Rework this procedure—including the agent and edge examples below—to edit the.flowstructure directly.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:158 - For an in-solution agent this placeholder must be the solution resource key, not
agent.json's project ID. The canonical agent implementation usesuipath.core.agent.<resourceKey>(agent/impl.md:95-118), so copying this example with a project ID produces an unresolvable node type.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:266 - This prohibition again applies the chat-input rule to every
.flowbinding, contradicting the canonical wiring guide where several node types require=js:. Scope it to conversational input bindings so agents do not remove required prefixes from unrelated fields in mixed flows.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md:22 - The in-solution suffix is not the agent project's
projectId; the existing agent contract identifies it as the local solutionresource.key(agent/impl.md:95-118). Keeping this placeholder directs users to construct a node type that local registry discovery will not resolve.
skills/uipath-maestro-flow/references/shared/node-output-wiring.md:75 - The newly added object-form exceptions conflict with this file's rule of thumb at line 79, which still says value-typed fields require
=js:and that conditions/script are the only exceptions. Reconcile the summary rule so readers do not apply the opposite representation to these chat bindings.
tests/tasks/uipath-maestro-flow/conversational/check_conversational_flow.py:271
- Only the agent-to-wait continuation is checked below. A disconnected conversation trigger and wait node, plus a lone agent-to-wait edge, therefore satisfy this function and the separate node-presence criterion even though no first turn can reach the agent. Add checks for the forward trigger → wait and wait → agent paths, ensuring traversal cannot use the continuation cycle to fake the required order.
edges = flow.get("edges") or []
# Only the continuation edge is graded. `escalation`, `context` and `tool`
# are legitimate wires to somewhere else.
for agent_id, expected in ports_by_id.items():
- Files reviewed: 15/15 changed files
- Comments generated: 2
- Review effort level: Balanced
…ng the task is offline Two review findings, the second consequential: - `check_settings` compared the five bindings' root against each other but never against a real node, so all five rooted at `$vars.ghost.output.conversationContext` passed. That is the same invented-path class the plugin warns about, and `flow validate` does not catch it either. The root now has to be a wait-for-message node in the flow. - The task claimed "fully offline — init / author / validate need no login". That is wrong. flow-core pushes inline agent nodes only inside `if (auth?.accessToken)` (manifest-client.ts), so with no token there is no `uipath.agent.conversational` to resolve, `definitions[]` cannot be filled, and validate cannot pass. The description now says a login is needed and the prompt no longer asserts the sandbox is logged out — it just forbids pack, upload and debug, which was the real intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new guidance conflicts with the owning agent contract, and the evaluator can accept disconnected chat flows.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (7)
Previously missed (6) — in code that hasn't changed since the last review.
skills/uipath-maestro-flow/references/author/plugins/agent/impl.md:199
- This command contradicts this file's own discovery contract at lines 7 and 116-118: local agent node types contain the solution
resource.key, not the agentprojectId. The placeholder can lead readers to query a node type that does not exist.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:14 - The next sentence requires reading
Data.ProjectId, but this command omits structured output. That violates the established parsing convention inreferences/shared/cli-conventions.md:41-48and makes the prescribed extraction dependent on human-formatted output.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:61 - The repository's canonical low-code agent contract says conversational
agent.jsonmust omitmaxIterations(skills/uipath-agents/references/lowcode/agent-definition.md:83-95,145), and its existing scaffold checker fails when the field is present. This new table instead requires8and claimsagent init --conversationalwrites it, leaving the two skills with mutually incompatible artifact contracts. Align the owning agent documentation/tests and this plugin before publishing either instruction.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md:158 - For the in-solution variant, this segment must be the solution resource key, not the agent project's
projectId; the latter will not match the node type returned byregistry list --local. Distinguish the local resource key from the published GUID in the example.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md:21 - This new inline flavor conflicts with the owning
uipath-agentsskill, which currently says conversational agents are standalone only and explicitly directs every inline-in-flow request to autonomous agents (skills/uipath-agents/references/lowcode/lowcode.md:25-33andproject-lifecycle.md:33). Unless that guidance is updated in the same change, agents routed through the agent skill will reject the exact scaffold this plugin requires.
This issue also appears on line 22 of the same file.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md:107
- This recipe immediately relies on the returned
ProjectId, so it must request JSON output under the repository's programmatic parsing convention (references/shared/cli-conventions.md:41-48). The neighboring inline-agent recipe already uses this form.
skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md:22
- This placeholder identifies an in-solution node by the agent project ID, but the existing agent contract states that
{key}is the solutionresource.keyminted byuip solution projects add(agent/impl.md:7,116-118). UsingprojectIdhere can make an author construct an unresolvable node type.
| **In-solution** | `uipath.core.agent.<projectId>` | A sibling project in the same solution | The agent is its own project, versioned separately, maybe reused by other flows in the solution. Discover it with `registry list --local`. |
- Files reviewed: 15/15 changed files
- Comments generated: 3
- Review effort level: Balanced
| wait_ids = {n.get("id") for n in _nodes_of(flow, WAIT_FOR_MESSAGE)} | ||
| edges = flow.get("edges") or [] |
| # The engine reads this, and the conversational node's manifest caps it at 8. | ||
| iterations = settings.get("maxIterations") | ||
| if not isinstance(iterations, int) or iterations > 8: | ||
| problems.append( | ||
| f"{label}: settings.maxIterations is {iterations!r}; the " | ||
| "conversational node caps it at 8" | ||
| ) |
| if not isinstance(system, str) or len(system.strip()) < 20: | ||
| problems.append( | ||
| f"{label}: the system prompt is empty or a stub — the scaffold ships " | ||
| "it blank and it has to be written" | ||
| ) |
…e prompt on text not length Two review findings on the checker: - `check_loop` graded only the loop-back edge, so a set of disconnected nodes plus a lone `agent --success--> wait` scored full marks even though no user message could reach the agent. The conversation trigger now has to reach a wait node, and a wait node has to reach each agent. - The system-prompt check used a 20-character floor, which let the canonical filler "You are a helpful assistant." through. Review suggested matching voice's 40-character bar; that rejects good short answers — "Support bot. Two sentences max." follows the task's instruction in 31 characters — so the filler set does the grading instead, with a 15-character floor left only to catch one-word junk. Comment says why this differs from voice. Checked against a 21-case harness (8 positive, 13 negative) run over two real builds: 17/17 before these changes, 21/21 after, so both are additive. Not fixed, and worth its own decision: settings.maxIterations. This checker requires it present and <= 8, while tests/tasks/uipath-agents/lowcode/conversational/scaffold/check_conversational_scaffold.py requires it absent. UiPath/cli#3827 makes `agent init --conversational` write 8, so that task breaks when the CLI lands — the reconciliation belongs with the CLI change, not here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a
conversational-agentplugin touipath-maestro-flow, plus registration rows, an offline eval task, and CODEOWNERS.Closes JAR-10152.
Not mergeable before that lands. The four text conversational feature flags live only on that branch, so on any published
uipthe first command this plugin prescribes —registry get core.trigger.conversation— returns "Node type not found". I confirmed it: a freshregistry pull --forceon the installed CLI (1.202.0-dev.8425) leaves all five node types unresolvable.What
Teaches agents to build a text chat:
core.trigger.conversation→ wait for message → a conversational agent → back to waiting, withsend-messageandget-conversation-contextalongside.The agent can be any of three flavors, and the plugin says to ask rather than default. That was deliberate — the first draft was named
inline-conversational-agentand every routing table pointed at inline before a reader got to a word of prose. It now leads with the choice, because it decides the node type, the ports, and whether anything is scaffolded at all:uipath.agent.conversationalsuccessagent init --inline-in-flow --conversationaluipath.core.agent.<projectId>outputregistry list --localuipath.core.agent.<guid>outputregistry searchIt also carries the rule the
agentplugin already states for autonomous agents: if the user names an existing agent, it is not inline — search before scaffolding.Three traps that pass
flow validatesilentlyThe plugin exists as much for these as for the happy path. All three were found by building real flows against a tenant, not by reading source:
contextandconversationIdand dropping the other three settings keys. Serialization reads all four runtime fields; validation requires one. The result validates clean and ships an agent with no chat history.waitForMessage1.output.exchangeIdand the agent'soutput.responsedo not exist — the real path isoutput.conversationContext.latestExchangeId, and the agent declares no outputs because it streams its reply.=js:string bindings. The pre-1.3 form. Studio Web renders it as literal text rather than a binding, and nothing warns.Registration
CAPABILITY.md(node inventory, task row, plugin list),planning-arch.md(plugin index, ports, a new "I need to have a text conversation" heuristic),planning-impl.md,brownfield.md,shared/node-output-wiring.md, andoperate+diagnosecapability rows for the Studio Web / VS Code debug hand-off.The
agentplugin gains a Conversational Agents section for the node type it already owns (uipath.core.agent.{key}) and points here for the loop. The settings block lives in one place.Tests
tests/tasks/uipath-maestro-flow/conversational/— one offline task pluscheck_conversational_flow.pywith three checks (settings,loop,agent-json).The checker was verified both ways against real projects, not just written:
context+conversationIdonly=js:string binding.exchangeIdinstead of.latestExchangeIdoutputsuccessmaxIterations: 25Writing it surfaced two bugs in my own checker that only running it exposed:
.flowedges aresourceNodeId/targetNodeId, notsource/target; and an in-solution node's id is a solution resource key, notagent.json'sprojectId, so id-matching could never have worked.Verification and limits
.maintenancechecks green — 907 links, 567 link texts, 276 anchors, 0 orphans, 27 plugin pairs, 0 template gaps..nupkg, the debug hand-off from a real upload.expected_turns: 30is an estimate.🤖 Generated with Claude Code