@uipath/skills 1.201.0-preview.637 → 1.201.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/uipath-human-in-the-loop/SKILL.md +125 -27
- package/skills/uipath-human-in-the-loop/references/hitl-casetask-action.md +415 -0
- package/skills/uipath-human-in-the-loop/references/hitl-node-apptask.md +4 -8
- package/skills/uipath-human-in-the-loop/references/hitl-node-coded-action-app.md +1 -1
- package/skills/uipath-human-in-the-loop/references/hitl-node-quickform.md +2 -2
- package/skills/uipath-human-in-the-loop/references/hitl-patterns.md +2 -4
- package/version-manifest.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/skills",
|
|
3
|
-
"version": "1.201.0
|
|
3
|
+
"version": "1.201.0",
|
|
4
4
|
"description": "UiPath agent skills for Claude Code, Codex, Cursor, Copilot, Gemini and OpenCode — RPA, UI automation, UI testing, coded agents/apps/workflows, and troubleshooting. Distributed as the UiPath Claude Code plugin.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "UiPath"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: uipath-human-in-the-loop
|
|
3
|
-
description: "UiPath Human-in-the-Loop / HITL node authoring — building approval gates, escalations, write-back validation, and data enrichment checkpoints in Flow, Maestro, or Coded Agents. NOT for managing, reassigning, or monitoring tasks at runtime (use uipath-tasks for that)."
|
|
3
|
+
description: "UiPath Human-in-the-Loop / HITL node authoring — building approval gates, escalations, write-back validation, and data enrichment checkpoints in Flow, Maestro, Case Management, or Coded Agents. NOT for managing, reassigning, or monitoring tasks at runtime (use uipath-tasks for that)."
|
|
4
4
|
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# UiPath Human-in-the-Loop Assistant
|
|
8
8
|
|
|
9
|
-
Recognizes when a business process needs a human decision point, designs the task schema through conversation, and wires the HITL node into the automation — Flow, Maestro, or Agent.
|
|
9
|
+
Recognizes when a business process needs a human decision point, designs the task schema through conversation, and wires the HITL node into the automation — Flow, Maestro, Case Management, or Agent.
|
|
10
10
|
|
|
11
11
|
> **Coded agents:** for wiring HITL inside a coded agent, use the `uipath-agents` skill — see `skills/uipath-agents/references/coded/capabilities/human-in-the-loop.md`.
|
|
12
12
|
|
|
@@ -32,7 +32,7 @@ See [references/hitl-patterns.md](references/hitl-patterns.md) for the full busi
|
|
|
32
32
|
|
|
33
33
|
## Critical Rules
|
|
34
34
|
|
|
35
|
-
1. **
|
|
35
|
+
1. **Never block on schema confirmation.** Design the schema from the prompt and any upstream `.flow`/`caseplan.json` data, write the node, and record the chosen schema prominently in the final report so the user can adjust it afterward. Asking the user is never a precondition for proceeding — if the user is present and offers input, use it, but do not wait for it. Only stop and report the open decision when the request is genuinely too ambiguous to make any reasonable inference. (A prompt that already specifies the fields, outcomes, and output shape is never too ambiguous.)
|
|
36
36
|
2. **Always wire the `completed` handle.** A HITL node with no outgoing edge on `completed` blocks the flow forever. Only `completed` is available as an output handle — **not** `output`, `success`, or any other name. This is true even when inserting into an existing flow whose other nodes use `"sourcePort": "output"`.
|
|
37
37
|
3. **Always add the definition entry when inserting into an existing flow.** Before writing the node, check `workflow.definitions[]` for the correct `nodeType` for the selected path (`"uipath.human-in-the-loop.quick-form"` for QuickForm, `"uipath.human-in-the-loop.coded-action-app"` for app-based). If absent, append the full definition entry (with `handleConfiguration` including the `completed` handle). Skipping the definition means the `completed` handle is invisible to the runtime and the wiring check fails.
|
|
38
38
|
4. **Regenerate `variables.nodes` after adding the node.** Replace the entire `workflow.variables.nodes` array — do not append. See the reference docs for the algorithm.
|
|
@@ -72,6 +72,11 @@ Run these checks in order:
|
|
|
72
72
|
# Check for a .flow file (Flow project)
|
|
73
73
|
find . -name "*.flow" -maxdepth 4 | head -5
|
|
74
74
|
|
|
75
|
+
# Check for a Case Management project. The on-disk filename varies
|
|
76
|
+
# (caseplan.json, or content/<name>.json.bpmn under a `uip maestro case init`
|
|
77
|
+
# project) — detect by content marker, not by filename.
|
|
78
|
+
find . -maxdepth 4 -iname "*.json*" -print0 2>/dev/null | xargs -0 grep -l '"case-management:root"' 2>/dev/null | head -3
|
|
79
|
+
|
|
75
80
|
# Check for agent.json (Low-Code Agent project)
|
|
76
81
|
find . -name "agent.json" -maxdepth 4 | head -3
|
|
77
82
|
|
|
@@ -82,6 +87,7 @@ find . -name "*.bpmn" -maxdepth 4 | head -3
|
|
|
82
87
|
| Found | Surface | How HITL is added |
|
|
83
88
|
|---|---|---|
|
|
84
89
|
| `.flow` file | **Flow** | Write node JSON directly — see reference docs |
|
|
90
|
+
| `caseplan.json` (any `*.json` with `root.type: "case-management:root"`) | **Case** | Write `action` task into stage — see [hitl-casetask-action.md](references/hitl-casetask-action.md) |
|
|
85
91
|
| `agent.json` | **Low Code Agent** | Escalation CLI in-flight — guide manually for now |
|
|
86
92
|
| `.bpmn` (Maestro) | **Maestro** | Write the `UserTask` XML directly — see Step 5 Surface: Maestro |
|
|
87
93
|
|
|
@@ -127,22 +133,26 @@ Read the existing `.flow` file to understand current nodes and edges. Use the Re
|
|
|
127
133
|
| "fills in missing", "validates extraction", "corrects" | Data enrichment | Automation produced incomplete data |
|
|
128
134
|
| "compliance", "regulatory", "audit trail" | Compliance checkpoint | Mandated human sign-off |
|
|
129
135
|
|
|
130
|
-
**When a signal is
|
|
136
|
+
**Never block on this.** When a signal is clear-cut (an explicit approval / review / sign-off requirement), add the HITL step and state that you did so, in this form:
|
|
131
137
|
|
|
132
|
-
> "I noticed that [quote the specific part of their description]. This is a [pattern name] — a point where [brief consequence if no human reviews]. I
|
|
138
|
+
> "I noticed that [quote the specific part of their description]. This is a [pattern name] — a point where [brief consequence if no human reviews]. I'm inserting a Human-in-the-Loop step here so that [human role] can [action] before the automation [continues/writes/sends]."
|
|
133
139
|
|
|
134
|
-
|
|
140
|
+
Proceed straight to schema design after saying this — do not wait for a reply. Record the decision prominently in the final report so the user can remove the step if they disagree. Only skip adding it and report the open decision when the signal is genuinely ambiguous (not just "no explicit HITL mention" — the signals table above is itself the ambiguity test).
|
|
135
141
|
|
|
136
142
|
**Example:**
|
|
137
143
|
> User: "Build an automation that reads support tickets, uses AI to generate an RCA, and updates the ticket in ServiceNow."
|
|
138
144
|
>
|
|
139
|
-
> Agent: "I noticed that the automation writes AI-generated content directly back to ServiceNow. This is a write-back validation pattern — if the RCA is incorrect and nobody reviews it, wrong data goes into production tickets. I
|
|
145
|
+
> Agent: "I noticed that the automation writes AI-generated content directly back to ServiceNow. This is a write-back validation pattern — if the RCA is incorrect and nobody reviews it, wrong data goes into production tickets. I'm inserting a Human-in-the-Loop step so that a support lead can review and optionally edit the RCA before the update is applied."
|
|
140
146
|
|
|
141
147
|
---
|
|
142
148
|
|
|
143
149
|
## Step 3 — Choose Task Type
|
|
144
150
|
|
|
145
|
-
|
|
151
|
+
**The options differ by surface.** Never block here — pick the option that best fits the surface and the business description, state the choice, and proceed. Only ask when the user is actually present and available; in a non-interactive run, infer and move on.
|
|
152
|
+
|
|
153
|
+
### Surface: Flow
|
|
154
|
+
|
|
155
|
+
Infer the right option from the signals below and state your choice — do not perform a registry search first, and do not wait for the user to pick before proceeding.
|
|
146
156
|
|
|
147
157
|
| # | Option | Node type | Description |
|
|
148
158
|
|---|---|---|---|
|
|
@@ -150,37 +160,65 @@ Present the user with three options. Do not choose on their behalf or perform an
|
|
|
150
160
|
| 2 | **New Coded Action App** | `uipath.human-in-the-loop.coded-action-app` | Scaffold a new React + TypeScript app inside the solution — full UI control |
|
|
151
161
|
| 3 | **Existing Deployed App** | `uipath.human-in-the-loop.coded-action-app` | Reference an app already deployed to Orchestrator |
|
|
152
162
|
|
|
153
|
-
> **
|
|
163
|
+
> **Default: QuickForm.** Pick QuickForm unless the request explicitly names a deployed app, a coded action app, or a custom UI requirement — those are the only signals that point at options 2 or 3. State the choice, do not ask: "I'll use QuickForm — it's inline, no deployment step needed, and works for most approval and review tasks. You can swap in a Coded Action App or an existing deployed app later if you need one."
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| User selects | Next step |
|
|
165
|
+
| Option chosen | Next step |
|
|
158
166
|
|---|---|
|
|
159
167
|
| QuickForm | Read [How to write a QuickForm HITL node](references/hitl-node-quickform.md) for Steps 1–2, then continue with Step 4 |
|
|
160
168
|
| New Coded Action App | Read [How to scaffold a new Coded Action App](references/hitl-node-coded-action-app.md) for Step 4c details, then continue with Step 4 |
|
|
161
|
-
| Existing Deployed App
|
|
169
|
+
| Existing Deployed App — the request must already name the app | Read [How to wire an existing deployed Action App](references/hitl-node-apptask.md) for Step 4b details, then continue with Step 4 |
|
|
162
170
|
|
|
163
|
-
**Fallback rules —
|
|
171
|
+
**Fallback rules — never block on these, fall back and state what you did:**
|
|
164
172
|
|
|
165
173
|
| Path | Blocker | Response |
|
|
166
174
|
|---|---|---|
|
|
167
|
-
| Existing Deployed App | App not found in Orchestrator | "I couldn't find
|
|
168
|
-
| New Coded Action App | No `dist/` build present in the source path | "The source folder doesn't have a `dist/` build yet
|
|
169
|
-
| New Coded Action App |
|
|
170
|
-
| Any custom app | Auth expired (401 on API call) | "The session
|
|
175
|
+
| Existing Deployed App | App not found in Orchestrator, or no app name was given | Fall back to QuickForm and proceed. State: "I couldn't find (or wasn't given) a deployed app name, so I used QuickForm instead. Point me at a real app name and I'll swap it in." |
|
|
176
|
+
| New Coded Action App | No `dist/` build present in the source path | Fall back to QuickForm and proceed. State: "The source folder doesn't have a `dist/` build yet, so I wired a QuickForm for now — run your build and ask me to swap in the Coded Action App once it's ready." |
|
|
177
|
+
| New Coded Action App | No source path given | Fall back to QuickForm and proceed. State: "No app source path was given, so I used QuickForm to wire the checkpoint now. Point me at the app code and I'll replace it with a Coded Action App." |
|
|
178
|
+
| Any custom app | Auth expired (401 on API call) | Fall back to QuickForm and proceed. State: "The session looked expired, so I used QuickForm rather than stall on re-authenticating. Run `uip login` and ask me to swap in the app when you're ready." |
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### Surface: Case
|
|
183
|
+
|
|
184
|
+
Infer the right option from the description below — do not pull the registry first, and do not wait for the user to pick before proceeding.
|
|
185
|
+
|
|
186
|
+
| # | Option | Fingerprint | Description |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| 1 | **QuickForm (file-based schema)** | separate `<TaskLabel>.hitl.json` file + `hitlType: "quick"` context entry in the action task | Structured form fields in a `.hitl.json` file alongside `caseplan.json`. Action Center renders fields at runtime. No deployed app needed. |
|
|
189
|
+
| 2 | **App-based action task** | `data.name` and `data.folderPath` as `=bindings.<id>` references + `data.actionCatalogName` | Uses a deployed Action Center app with custom input/output fields. Requires the app to exist in Orchestrator. |
|
|
190
|
+
|
|
191
|
+
> **Default: QuickForm.** Pick QuickForm unless the request explicitly names a deployed Action Center app. State the choice, do not ask: "I'll use QuickForm — it's the quickest to set up, supports structured form fields, and doesn't need a deployed app. You can upgrade to an app-based task later if you need a custom UI layout."
|
|
192
|
+
|
|
193
|
+
> **Build vs design time.** QuickForm in case management must round-trip both ways: the JSON written here is what Studio Web's case designer reads (design time), and what `uip maestro case validate` + Action Center render at runtime (build time). Always validate after writing.
|
|
194
|
+
|
|
195
|
+
| Option chosen | Next step |
|
|
196
|
+
|---|---|
|
|
197
|
+
| QuickForm (file-based schema) | Read [references/hitl-casetask-action.md — Path 1](references/hitl-casetask-action.md#path-1--quickform-file-based-schema-no-deployed-app), then continue with Step 4 |
|
|
198
|
+
| App-based action task — the request must already name the app | Read [references/hitl-casetask-action.md — Path 2](references/hitl-casetask-action.md#path-2--app-based-action-task-deployed-action-center-app), then continue with Step 4 |
|
|
199
|
+
|
|
200
|
+
**Fallback rules — never block on these, fall back and state what you did:**
|
|
201
|
+
|
|
202
|
+
| Path | Blocker | Response |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| App-based | App not found in registry or `action-apps-index.json`, or no app name was given | Fall back to QuickForm and proceed. State: "I couldn't find (or wasn't given) that app, so I used QuickForm instead. Point me at a real app name and I'll swap it in." |
|
|
205
|
+
| QuickForm | Schema design rejected on validate (e.g. duplicate field IDs, missing primary outcome) | Fix the schema yourself from the validator's error and re-validate. Apply Step 4b checks. Note the fix in the final report — do not pause to re-show the schema first. |
|
|
206
|
+
| Any | Auth expired (401 on API call) | Fall back to QuickForm and proceed. State: "The session looked expired, so I used QuickForm rather than stall on re-authenticating. Run `uip login` and ask me to swap in the app when you're ready." |
|
|
171
207
|
|
|
172
208
|
---
|
|
173
209
|
|
|
174
210
|
## Step 4 — Common configuration
|
|
175
211
|
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
Never block on these — use the stated default when no answer is available, write it into the node, and note the default in the final report so the user can change it.
|
|
213
|
+
|
|
214
|
+
| Timeout | Default: 24 hours. If the description states or implies a different duration, use that instead. |
|
|
215
|
+
| Priority | Default: Low. If the description states or implies urgency (e.g. "high priority", "urgent", "time-sensitive"), use High or Medium accordingly. Write the chosen value into the node's `priority` field — asking the question is not enough; the value must land in the node. |
|
|
178
216
|
|
|
179
217
|
---
|
|
180
218
|
|
|
181
|
-
## Step 4b — Schema Design
|
|
219
|
+
## Step 4b — Schema Design Resilience (QuickForm — Flow and Case)
|
|
182
220
|
|
|
183
|
-
Apply these
|
|
221
|
+
Apply these checks while designing the schema, before writing it — per Critical Rule 1, do not wait on the user to confirm. Applies equally to Flow QuickForm nodes and Case QuickForm action tasks — same `fields[]` + `outcomes[]` shape, same `direction` semantics.
|
|
184
222
|
|
|
185
223
|
### Field direction
|
|
186
224
|
|
|
@@ -196,14 +234,15 @@ Pick direction based on what the human does with the field:
|
|
|
196
234
|
|
|
197
235
|
### Field types
|
|
198
236
|
|
|
199
|
-
Use the JS/JSON type that fits the field: `string`, `number`, `boolean`, `date`, or `file`. These are the only valid values — do not use `text`.
|
|
237
|
+
Use the JS/JSON type that fits the field: `string`, `number`, `boolean`, `date`, or `file`. These are the only valid values — do not use `text`. Case also supports `datetime` (distinct from `date`, for full date+time values) — see [hitl-casetask-action.md](references/hitl-casetask-action.md) for the Case-specific type table.
|
|
200
238
|
|
|
201
239
|
### Vague or incomplete schema descriptions
|
|
202
240
|
|
|
203
241
|
If the user says something like "just add some fields" or "use whatever makes sense":
|
|
204
242
|
|
|
205
|
-
1. Infer sensible defaults from the upstream data and downstream needs visible in the `.flow` file.
|
|
206
|
-
2.
|
|
243
|
+
1. Infer sensible defaults from the upstream data and downstream needs visible in the `.flow` file (Flow) or in `caseplan.json` upstream task `outputs[]` and `root.data.uipath.variables` (Case).
|
|
244
|
+
2. Show the proposed schema explicitly before writing: "Here's what I'm proposing — let me know if you want to change anything."
|
|
245
|
+
3. If there is nothing upstream to bind to (Flow with only a trigger; Case with this as the first task), use output-direction fields only and note: "There are no upstream values to pull data from, so the reviewer will fill in all fields from scratch."
|
|
207
246
|
|
|
208
247
|
### Empty field labels block validation
|
|
209
248
|
|
|
@@ -266,6 +305,27 @@ After writing, validate:
|
|
|
266
305
|
uip maestro flow validate <file> --output json
|
|
267
306
|
```
|
|
268
307
|
|
|
308
|
+
### Surface: Case
|
|
309
|
+
|
|
310
|
+
Read the `caseplan.json` to identify the target stage. Write an `action` task directly into `stage.data.tasks[lane][]`. **Direct JSON write is the only supported method** — the `uipath-maestro-case` skill ships no `hitl` CLI subcommand (unlike Flow's `uip maestro flow hitl add`).
|
|
311
|
+
|
|
312
|
+
Full reference: **[references/hitl-casetask-action.md](references/hitl-casetask-action.md)** — three task JSON shapes (QuickForm, generic, app-based), field reference, assignee handling, post-write verification, and downstream output access.
|
|
313
|
+
|
|
314
|
+
| Path chosen in Step 3 | What gets written |
|
|
315
|
+
|---|---|
|
|
316
|
+
| QuickForm | A `<TaskLabel>.hitl.json` schema file (unified `fields[]` with `direction`, `outcomes[]`) + action task in `caseplan.json` with `data.context[hitlType].value: "quick"`, `_schemaFileId` (placeholder UUID), and `hitlSchemaId` (matches `schemaId` in `.hitl.json`). `data.inputs[]` and `data.outputs[]` are empty arrays. No `root.data.uipath.bindings[]` entries. Apply Step 4b schema-design checks before writing. |
|
|
317
|
+
| App-based | Action task with `data.actionCatalogName`, `data.name` and `data.folderPath` as `=bindings.<id>` references. Add 2 root-level bindings. |
|
|
318
|
+
|
|
319
|
+
After writing, validate (build-time check — must pass before reporting success):
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
uip maestro case validate <caseplan.json> --output json
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
> `uip maestro case validate` is the only `uip maestro case` CLI used by this skill on the Case surface. All authoring is direct JSON.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
269
329
|
### Surface: Low-Code Agent
|
|
270
330
|
|
|
271
331
|
The Low-Code Agent escalation CLI (`uip agent escalation add`) is currently in-flight. Until it ships, configure manually:
|
|
@@ -296,9 +356,46 @@ response = interrupt(CreateTask(
|
|
|
296
356
|
|
|
297
357
|
### Surface: Maestro
|
|
298
358
|
|
|
299
|
-
QuickForm and coded-action-app HITL nodes are both supported on Maestro BPMN processes
|
|
359
|
+
QuickForm and coded-action-app HITL nodes are both supported on Maestro BPMN processes. `uipath.human-in-the-loop.quick-form` and `uipath.human-in-the-loop.coded-action-app` are registered as **registry shortcut names** in the BPMN validator ([bpmn-spec.json](../uipath-maestro-bpmn/validator/bpmn-spec.json)) — these are palette/discovery identifiers, not literal XML to write. There is no dedicated CLI subcommand for Maestro (unlike Flow's `uip maestro flow hitl add`) — write the node directly into the `.bpmn` XML.
|
|
360
|
+
|
|
361
|
+
**Confirmed node shape (verified by direct reproduction against a real Studio Web BPMN process with a working, editable QuickForm task):**
|
|
362
|
+
|
|
363
|
+
```xml
|
|
364
|
+
<bpmn:task id="Activity_InvoiceApproval" name="Invoice Approval">
|
|
365
|
+
<bpmn:extensionElements>
|
|
366
|
+
<uipath:activity version="v1">
|
|
367
|
+
<uipath:type value="Actions.HITL" version="v2" />
|
|
368
|
+
<uipath:context>
|
|
369
|
+
<uipath:input name="hitlType" type="string" value="quick" />
|
|
370
|
+
<uipath:input name="taskTitle" type="string" value="Please review this invoice and approve or reject" />
|
|
371
|
+
<uipath:input name="labels" type="string" />
|
|
372
|
+
<uipath:input name="priority" type="string" value="Medium" />
|
|
373
|
+
<uipath:input name="actionCatalogName" type="string" />
|
|
374
|
+
<uipath:input name="enableActionableNotifications" type="boolean" value="false" />
|
|
375
|
+
<uipath:input name="assignmentCriteria" type="string" />
|
|
376
|
+
<uipath:input name="recipient" type="json" />
|
|
377
|
+
<uipath:input name="_schemaFileId" type="string" value="<see file-id callout below>" />
|
|
378
|
+
<uipath:input name="hitlSchemaId" type="string" value="<matches schemaId in the .hitl.json sidecar>" />
|
|
379
|
+
<uipath:inputSchema type="jsonSchema"><![CDATA[{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"invoiceid":{"type":"string","title":"Invoice ID"},"amount":{"type":"number","title":"Amount"}},"required":[]}]]></uipath:inputSchema>
|
|
380
|
+
</uipath:context>
|
|
381
|
+
<uipath:input name="HitlTaskArguments" type="json" target="bodyField"><![CDATA[{"invoiceid":"INV-1001","amount":500}]]></uipath:input>
|
|
382
|
+
<uipath:output name="Action" type="string" source="=Action" var="invoiceDecision" options="[{"value":"Approve","label":"Approve"},{"value":"Reject","label":"Reject"}]" />
|
|
383
|
+
</uipath:activity>
|
|
384
|
+
</bpmn:extensionElements>
|
|
385
|
+
<bpmn:incoming>edge_into_task</bpmn:incoming>
|
|
386
|
+
<bpmn:outgoing>edge_out_of_task</bpmn:outgoing>
|
|
387
|
+
</bpmn:task>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Notes on what's easy to get wrong:
|
|
391
|
+
- **Element is `bpmn:task`, not `bpmn:UserTask`.** `bpmn-spec.json`'s generic `Actions.HITL` XML template uses `bpmn:UserTask` and `version="v1"` — that template is for the app-based/coded-action-app path (its `context` fields are `appId`, `appVersion`, `actions`, `key`, `taskTitle`). A real QuickForm task exported from Studio Web is a plain `bpmn:task` with `uipath:type value="Actions.HITL" version="v2"`. Use the shape above for QuickForm; the spec's template for app-based.
|
|
392
|
+
- **`<uipath:inputSchema>` (last child of `<uipath:context>`) and `<uipath:input name="HitlTaskArguments">` (sibling of `<uipath:context>`, not inside it) are both required.** Without them the "Edit Schema" canvas in Studio Web doesn't open at all — confirmed by direct reproduction. This mirrors the Case surface's `data.inputSchema`/`data.inputs[]` requirement — see [hitl-casetask-action.md § Step 3](references/hitl-casetask-action.md) for the parallel Case shape and full field-by-field rationale.
|
|
393
|
+
- **The `Action` output requires a matching process-level variable declaration** — add `<uipath:inputOutput id="<varId>" name="Action" type="string" elementId="<taskId>" />` inside the process's top-level `<uipath:variables version="v1">` block.
|
|
394
|
+
- **A separate `<TaskLabel>.hitl.json` sidecar file is required**, same shape as the Case surface's (`title`, `fields[]` with `direction`/optional `colSpan`/`binding` or `variable`, `outcomes[]` with **no** `action` key, `schemaId`) — see [hitl-casetask-action.md § Step 2](references/hitl-casetask-action.md) for the exact shape; it's identical across both surfaces.
|
|
395
|
+
- **`_schemaFileId` cannot be authored blind — it is a server-assigned foreign key, not a UUID you invent.** A placeholder value makes "Edit Schema" fail silently (a `404` on Studio Web's internal `FileOperations/File/Rename` call, confirmed by direct reproduction). There is no `uip` CLI command that resolves this today. **Never block on this.** Write a fresh placeholder UUID v4, finish the rest of the node, validate, and move on — do not attempt the live reconciliation yourself and do not stop to ask about it. State plainly in the final report: "This task's schema was written with a placeholder `_schemaFileId`, so Studio Web's 'Edit Schema' canvas won't open for it yet. Making it editable requires resolving the real file ID Studio Web assigns to the `.hitl.json` after upload (`GET /api/Project/{projectId}/FileOperations/Structure`) and pushing it back with a targeted single-file update (`PUT /api/Project/{projectId}/FileOperations/File/{fileId}`) — not another whole-project `uip solution upload`, which mints a new random ID for every file and undoes the fix. Ask me to do this reconciliation if you want the schema editable in Studio Web." This is a real product/tooling gap the user can act on later, not something to resolve mid-task.
|
|
396
|
+
- **Diagram-interchange edges are required for the connector lines to render, even though the logical `bpmn:sequenceFlow`s already exist.** Every `bpmn:sequenceFlow` needs a matching `bpmndi:BPMNEdge` (with two `di:waypoint` points, aligned to the source/target shapes' connecting edges) in the `bpmndi:BPMNPlane` — omitting it leaves the nodes logically connected but visually disconnected in the canvas. Confirmed by direct reproduction.
|
|
300
397
|
|
|
301
|
-
Design the schema per Step 4b
|
|
398
|
+
Design the schema per Step 4b — never block waiting on the user, per Critical Rule 1 — then validate frequently (`uip maestro bpmn validate <file>.bpmn --output json`) while wiring the node so any shape mistakes surface immediately rather than at deploy time. In Maestro, field names in `outputs`/`inOuts` must exactly match declared process variable names and types.
|
|
302
399
|
|
|
303
400
|
---
|
|
304
401
|
|
|
@@ -326,3 +423,4 @@ After completing the wiring:
|
|
|
326
423
|
- **[How to scaffold a new Coded Action App](references/hitl-node-coded-action-app.md)** — Read this when the user wants to build a new React app inside the solution. Covers full project template, UUID generation, solution CLI commands, and post-creation build steps.
|
|
327
424
|
- **[HITL business pattern recognition](references/hitl-patterns.md)** — Read this during Step 2 / Step 2b to identify whether a process needs a human checkpoint and which pattern applies. Includes proactive recommendation language and when NOT to recommend HITL.
|
|
328
425
|
- **[Action Center URL patterns](../uipath-tasks/references/action-center-urls.md)** (in `uipath-tasks` skill) — Read this before surfacing any Action Center task URL to the user. Covers the missing-tenant-slug anti-pattern and the API-host vs UI-host mapping.
|
|
426
|
+
- **[Case Action Task (HITL)](references/hitl-casetask-action.md)** — Case surface: action task JSON, QuickForm vs app-based paths, `.hitl` file format, context entries, field binding, and downstream output access.
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# HITL Case Action Task — Implementation Reference
|
|
2
|
+
|
|
3
|
+
The agent writes an `action` task into a stage of `caseplan.json`. **Direct JSON write is the primary method on the Case surface.** Unlike the Flow surface (`uip maestro flow hitl add`), the `uipath-maestro-case` skill ships no single `hitl add` CLI subcommand for the HITL-specific parts (`context[]` entries, `.hitl.json` linkage) — edit `caseplan.json` directly per the path-specific JSON shapes below.
|
|
4
|
+
|
|
5
|
+
> If the stage or case predates required entry/exit/completion rules (see the checklist below), `uip maestro case` does have CLI mutation commands for those (`stage-entry-conditions`, `stage-exit-conditions`, `case-exit-conditions`, `task-entry-conditions` — each with an `add` subcommand). Prefer them over hand-writing that JSON when the case project already exists as a file you can pass to the CLI. If you're editing a caseplan.json given to you directly (not one you scaffolded yourself with these commands), it's simplest to just include the correct rule shapes directly per the examples below.
|
|
6
|
+
|
|
7
|
+
Two paths exist. **Never block on choosing — infer the path from the business description using the table below (§ Common business descriptions → path selection) and proceed. Do not wait for the user to pick.**
|
|
8
|
+
|
|
9
|
+
| Path | When to use | Requires |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| **QuickForm** | Structured form fields, no deployed app needed | A separate `.hitl.json` schema file written alongside `caseplan.json` |
|
|
12
|
+
| **App-based action task** | Existing deployed Action Center app with a custom form | `task-type-id` from registry + `tasks describe` |
|
|
13
|
+
|
|
14
|
+
> **If the user is unsure or says "just pick one":** Default to QuickForm. Say: "I'll use QuickForm — it's the quickest to set up and works for most approval and review tasks. You can always upgrade to a deployed Action Center app later."
|
|
15
|
+
|
|
16
|
+
> **Build time vs design time.** A case action task lives in two surfaces:
|
|
17
|
+
> - **Design time** — the JSON written into `caseplan.json` (what this skill produces). Studio Web's case designer round-trips this JSON; the QuickForm schema must be valid here.
|
|
18
|
+
> - **Build / runtime time** — `uip maestro case validate` accepts it, `uip solution upload` packs it, and Action Center renders the form to the assignee at runtime.
|
|
19
|
+
>
|
|
20
|
+
> Every shape documented below is required to round-trip in both. After writing, always run `uip maestro case validate <caseplan.json> --output json`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 1 — Extract the Task Configuration Through Conversation
|
|
25
|
+
|
|
26
|
+
**Never block on this.** Infer each answer below from the business description; only ask if the user is actually present and it would help. Defaults when nothing in the description settles it: recipient → a group named after the relevant team (e.g. "finance-team", "data-enrichment-team" — infer the team name from context); priority → Low, per Step 4.
|
|
27
|
+
|
|
28
|
+
| What you need to know | Where to infer it from |
|
|
29
|
+
|---|---|
|
|
30
|
+
| What the reviewer sees | Data the automation already extracted or produced upstream |
|
|
31
|
+
| What they decide or fill in | Whether the description says "approve/reject" (decision only) or "fill in", "correct", "enrich" (data entry) |
|
|
32
|
+
| Who receives the task | A named person/email or team/group mentioned in the description; otherwise infer a sensible team name from the business context |
|
|
33
|
+
| Priority | Any urgency language in the description ("urgent", "high priority") → High/Medium; otherwise Low |
|
|
34
|
+
|
|
35
|
+
**Common business descriptions → path selection:**
|
|
36
|
+
|
|
37
|
+
| Description | Path |
|
|
38
|
+
|---|---|
|
|
39
|
+
| "Reviewer approves invoice; sees ID + amount, clicks Approve/Reject" | QuickForm — `inputs[]` (read-only) + `outcomes[]` |
|
|
40
|
+
| "Human fills in missing vendor name and cost center, then submits" | QuickForm — `outputs[]` (writable) |
|
|
41
|
+
| "Reviewer edits an AI-drafted email, then sends or discards" | QuickForm — `inOuts[]` for the body |
|
|
42
|
+
| "Finance team approves expense claims before payment" | QuickForm — group assignee, outcomes are Approve/Reject |
|
|
43
|
+
| "Manager approves a leave request" | QuickForm — user email assignee, outcomes are Approve/Reject |
|
|
44
|
+
| "Legal reviews and signs off on a contract with custom fields" | App-based — deployed app with custom form layout |
|
|
45
|
+
| "Agent fills in form that a human corrects before submitting" | App-based — outputs populate downstream task inputs |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Path 1 — QuickForm (file-based schema, no deployed app)
|
|
50
|
+
|
|
51
|
+
The form schema lives in a separate `.hitl.json` file that sits alongside `caseplan.json` in the case project directory. Action Center renders the fields at runtime from the schema — no deployed app required.
|
|
52
|
+
|
|
53
|
+
> **What makes Path 1 (QuickForm) unique — checklist before you finish:**
|
|
54
|
+
> - ✅ A `<TaskLabel>.hitl.json` file is **created** alongside `caseplan.json`
|
|
55
|
+
> - ✅ `data.context[hitlType].value` is `"quick"` (not `"custom"`)
|
|
56
|
+
> - ✅ `data.context[_schemaFileId].value` is a **plain UUID v4 string** — e.g. `"f1e2d3c4-b5a6-7890-abcd-ef1234567890"`. Never an `=bindings.xxx` expression.
|
|
57
|
+
> - ✅ `data.context[hitlSchemaId].value` is a **plain UUID v4 string** matching `schemaId` in the `.hitl.json` file. Never an `=bindings.xxx` expression.
|
|
58
|
+
> - ✅ `data.inputs[]` and `data.outputs[]` are **empty arrays** (`[]`)
|
|
59
|
+
> - ❌ `data.name` and `data.folderPath` do NOT exist — those are App-based (Path 2) only
|
|
60
|
+
> - ❌ No `=bindings.xxx` expressions anywhere in the task JSON — those are App-based only
|
|
61
|
+
> - ❌ No top-level `bindings[]` entries added
|
|
62
|
+
|
|
63
|
+
### Step 1 — Design the Schema
|
|
64
|
+
|
|
65
|
+
Use these roles to plan the fields before writing:
|
|
66
|
+
|
|
67
|
+
| Role | `field.direction` | Human can… | Use for |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| Input field | `"input"` | Read only | Context the human needs to make a decision |
|
|
70
|
+
| Output field | `"output"` | Write | Data the automation needs back |
|
|
71
|
+
| InOut field | `"inOut"` | Read + modify | Data the human can see and optionally correct |
|
|
72
|
+
|
|
73
|
+
**Supported field types:** `string`, `number`, `boolean`, `date`, `datetime` (canonical — see [hitl-node-quickform.md](hitl-node-quickform.md) for the same vocabulary on the Flow surface; legacy aliases like `text`/`dateTime` are silently normalized by the runtime, but write the canonical form directly)
|
|
74
|
+
|
|
75
|
+
**Design rules:**
|
|
76
|
+
- Input fields: bind to upstream case variables via `=vars.<varId>` — never hardcode literals from runtime data
|
|
77
|
+
- Output fields: only what downstream tasks actually consume; set `required: true` for mandatory outputs
|
|
78
|
+
- `outcomes[]`: use domain-specific names (Approve/Reject, not just Submit)
|
|
79
|
+
- Keep it focused — don't add fields the case won't use
|
|
80
|
+
|
|
81
|
+
**Never block on this — write the schema, per Critical Rule 1 in SKILL.md, and record it in the final report so the user can adjust it afterward.**
|
|
82
|
+
|
|
83
|
+
### Step 2 — Write the `.hitl.json` File
|
|
84
|
+
|
|
85
|
+
Generate two UUID v4 values:
|
|
86
|
+
- `schemaId` — identity of the schema, stored inside the file and referenced from the action task
|
|
87
|
+
- `fileId` — placeholder file system ID (Studio Web assigns the real one when it processes the project; use a fresh UUID v4 as a stable placeholder)
|
|
88
|
+
|
|
89
|
+
Create a file named `<TaskLabel>.hitl.json` in the case project directory (alongside `caseplan.json`).
|
|
90
|
+
|
|
91
|
+
The file uses a **unified `fields[]` array** — every field has a `direction` property that determines its role. This is the format the sync runtime reads (`parsed?.fields`).
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"title": "Invoice Approval",
|
|
96
|
+
"fields": [
|
|
97
|
+
{
|
|
98
|
+
"id": "invoiceid",
|
|
99
|
+
"label": "Invoice ID",
|
|
100
|
+
"type": "string",
|
|
101
|
+
"direction": "input",
|
|
102
|
+
"colSpan": 6,
|
|
103
|
+
"binding": "=vars.invoiceIdVar"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "amount",
|
|
107
|
+
"label": "Amount",
|
|
108
|
+
"type": "number",
|
|
109
|
+
"direction": "input",
|
|
110
|
+
"colSpan": 6,
|
|
111
|
+
"binding": "=vars.amountVar"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "notes",
|
|
115
|
+
"label": "Notes",
|
|
116
|
+
"type": "string",
|
|
117
|
+
"direction": "output",
|
|
118
|
+
"colSpan": 6,
|
|
119
|
+
"variable": "vars.notes"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "decision",
|
|
123
|
+
"label": "Decision",
|
|
124
|
+
"type": "string",
|
|
125
|
+
"direction": "output",
|
|
126
|
+
"colSpan": 6,
|
|
127
|
+
"variable": "vars.decision"
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"outcomes": [
|
|
131
|
+
{ "id": "outcome-0", "name": "Approve", "type": "string", "isPrimary": true },
|
|
132
|
+
{ "id": "outcome-1", "name": "Reject", "type": "string", "isPrimary": false }
|
|
133
|
+
],
|
|
134
|
+
"schemaId": "a3f7c2d1-8b4e-4f9a-b2c5-6d8e1f3a7b9c"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Field shape reference:**
|
|
139
|
+
|
|
140
|
+
| Property | Required | Notes |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| `id` | Yes | lowercase label, strip spaces and non-alphanumeric characters (no separator). `"Invoice ID"` → `"invoiceid"`, `"Due Date"` → `"duedate"` |
|
|
143
|
+
| `label` | Yes | Display label in the form. Validator rejects empty. |
|
|
144
|
+
| `type` | Yes | `string`, `number`, `boolean`, `date`, `datetime` |
|
|
145
|
+
| `direction` | Yes | `"input"`, `"output"`, or `"inOut"` |
|
|
146
|
+
| `colSpan` | No | Grid width hint for the form layout (e.g. `6` of 12). Safe to omit — confirmed optional against a real Studio Web export. |
|
|
147
|
+
| `binding` | For `direction: "input"` / `"inOut"` | `"=vars.<varId>"` — reads from a case variable. A literal is also valid as an `=`-expression (e.g. `="Acme Corp"`), confirmed against a real export, but prefer a variable binding when the value comes from upstream data. |
|
|
148
|
+
| `variable` | For `direction: "output"` / `"inOut"` | The **full** `"vars.<name>"` reference (no leading `=`) the output writes to — not a bare name. Downstream tasks read it as `=vars.<name>`. |
|
|
149
|
+
| `required` | No | `true` for mandatory outputs — omit if false |
|
|
150
|
+
|
|
151
|
+
**`outcomes[]` shape:** `{ "id": "<slug>", "name": "<OutcomeName>", "type": "string", "isPrimary": <bool> }` — first entry is the primary action. **No `action` key** — confirmed against a real Studio Web export; an earlier draft of this doc invented one, do not reintroduce it.
|
|
152
|
+
|
|
153
|
+
> **`title` is required, top-level in the `.hitl.json` file** — the form's display title in Action Center, separate from both the task's `displayName` (canvas label) and `data.taskTitle` (the assignee-facing message). All three are independent strings and do not need to match.
|
|
154
|
+
|
|
155
|
+
### Step 3 — Write the Action Task in `caseplan.json`
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"id": "ta1b2c3d4",
|
|
160
|
+
"elementId": "Stage_aB3kL9-ta1b2c3d4",
|
|
161
|
+
"type": "action",
|
|
162
|
+
"displayName": "Invoice Approval",
|
|
163
|
+
"isRequired": true,
|
|
164
|
+
"shouldRunOnlyOnce": false,
|
|
165
|
+
"entryConditions": [
|
|
166
|
+
{
|
|
167
|
+
"id": "Condition_EnTk1",
|
|
168
|
+
"displayName": "Entry Rule 1",
|
|
169
|
+
"rules": [ [ { "id": "Rule_EnTk1", "rule": "current-stage-entered" } ] ]
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
"data": {
|
|
173
|
+
"taskTitle": "Please review this invoice and approve or reject",
|
|
174
|
+
"context": [
|
|
175
|
+
{ "name": "hitlType", "type": "string", "value": "quick" },
|
|
176
|
+
{ "name": "taskTitle", "type": "string", "value": "Please review this invoice and approve or reject" },
|
|
177
|
+
{ "name": "labels", "type": "string" },
|
|
178
|
+
{ "name": "priority", "type": "string", "value": "Medium" },
|
|
179
|
+
{ "name": "actionCatalogName", "type": "string" },
|
|
180
|
+
{ "name": "enableActionableNotifications","type": "boolean", "value": "false" },
|
|
181
|
+
{ "name": "assignmentCriteria", "type": "string", "value": "user" },
|
|
182
|
+
{ "name": "recipient", "type": "json", "body": { "Type": 2, "Value": "approver@company.com" } },
|
|
183
|
+
{ "name": "_schemaFileId", "type": "string", "value": "f1e2d3c4-b5a6-7890-abcd-ef1234567890" },
|
|
184
|
+
{ "name": "hitlSchemaId", "type": "string", "value": "a3f7c2d1-8b4e-4f9a-b2c5-6d8e1f3a7b9c" }
|
|
185
|
+
],
|
|
186
|
+
"inputs": [
|
|
187
|
+
{ "name": "invoiceid", "type": "string", "displayName": "Invoice ID", "target": "bodyField", "value": "=vars.invoiceIdVar" },
|
|
188
|
+
{ "name": "amount", "type": "number", "displayName": "Amount", "target": "bodyField", "value": "=vars.amountVar" }
|
|
189
|
+
],
|
|
190
|
+
"outputs": [
|
|
191
|
+
{ "name": "Action", "type": "string", "displayName": "Action", "source": "=Action", "var": "invoiceDecision",
|
|
192
|
+
"options": [ { "value": "Approve", "label": "Approve" }, { "value": "Reject", "label": "Reject" } ] }
|
|
193
|
+
],
|
|
194
|
+
"inputSchema": {
|
|
195
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
196
|
+
"type": "object",
|
|
197
|
+
"properties": {
|
|
198
|
+
"invoiceid": { "type": "string", "title": "Invoice ID" },
|
|
199
|
+
"amount": { "type": "number", "title": "Amount" }
|
|
200
|
+
},
|
|
201
|
+
"required": []
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> **`displayName`, `inputs[]`/`outputs[]`, and `inputSchema` are all required — this is the part an earlier draft of this doc got wrong.** It previously claimed `data.inputs[]`/`data.outputs[]` "are always empty arrays for QuickForm — the schema is in the `.hitl.json` file." That is false. Confirmed against a real Studio Web export and by direct reproduction: without `inputSchema` (a JSON-Schema mirror of the input fields) and populated `inputs[]`/`outputs[]` on the task node itself, Studio Web's "Edit Schema" canvas does not open at all — clicking it does nothing, silently. The `.hitl.json` file and the task's own `data.*` fields are **two parallel representations of the same schema** that must both be written; neither one alone is sufficient.
|
|
208
|
+
> - `inputs[]`: one entry per input field, `name` = field `id`, `value` = the same `=`-expression as that field's `binding` in `.hitl.json`.
|
|
209
|
+
> - `outputs[]`: one entry per **output field with a `variable`**, plus one always-present `Action` entry whose `options[]` mirrors `outcomes[]` from `.hitl.json` (`{value, label}` pairs) — this is the decision/outcome the reviewer picks, not a separate field.
|
|
210
|
+
> - `inputSchema`: a `draft-07` JSON Schema, `properties` keyed by the same field ids as `inputs[]`, each `{"type": "<field type>", "title": "<field label>"}`.
|
|
211
|
+
|
|
212
|
+
**Context entry notes:**
|
|
213
|
+
|
|
214
|
+
| `name` | Notes |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `hitlType` | Always `"quick"` for QuickForm |
|
|
217
|
+
| `_schemaFileId` | **Not a value you can invent — see the callout below.** It must be the real, backend-assigned file ID of the uploaded `.hitl.json`, not a fresh UUID. |
|
|
218
|
+
| `hitlSchemaId` | Must match the `schemaId` value inside the `.hitl.json` file exactly. |
|
|
219
|
+
| `taskTitle` | Appears both as `data.taskTitle` (top-level) and in `context[]` — **both are required**. |
|
|
220
|
+
| `labels` | No `value` — leave the entry present but empty. |
|
|
221
|
+
| `priority` | `"Low"` \| `"Medium"` (default) \| `"High"` \| `"Critical"` |
|
|
222
|
+
| `actionCatalogName` | No `value` for QuickForm — leave the entry present but empty. |
|
|
223
|
+
| `enableActionableNotifications` | Leave as `"false"` unless the user explicitly wants email notifications. |
|
|
224
|
+
| `assignmentCriteria` | `"user"` when assigning to a specific email. Omit the `value` (or omit the entry) for group rules. |
|
|
225
|
+
| `recipient` | `{ "Type": 2, "Value": "<email>" }` for email; `{ "Type": 1, "Value": "<group>" }` for group; `{ "Type": 3, "Value": "=vars.<varId>" }` for runtime-resolved assignee. |
|
|
226
|
+
|
|
227
|
+
> **`_schemaFileId` cannot be authored blind — it is a server-assigned foreign key, not a UUID you invent.** Confirmed by direct reproduction against Studio Web: a placeholder UUID here makes "Edit Schema" fail with a `404` on `FileOperations/File/Rename` (the fileId in that failed request is whatever placeholder was written) — Studio Web does **not** silently reconcile it on upload, contrary to what an earlier draft of this doc claimed. There is currently no `uip` CLI command that resolves this.
|
|
228
|
+
>
|
|
229
|
+
> **Never block on this.** Write a fresh placeholder UUID v4, finish the task, validate, and move on — do not attempt the reconciliation below yourself, and do not stop to ask about it. State plainly in the final report that this task's schema won't be editable in Studio Web until the real file ID is reconciled, and offer to do it if asked:
|
|
230
|
+
> 1. Upload the project once with any placeholder value in `_schemaFileId` (`uip solution upload`).
|
|
231
|
+
> 2. Look up the real ID Studio Web assigned to the `.hitl.json` file via `GET /api/Project/{projectId}/FileOperations/Structure` (find the entry whose `name` matches the `.hitl.json` filename — an internal Studio Web REST endpoint, not a `uip` CLI verb).
|
|
232
|
+
> 3. Patch `_schemaFileId` in `caseplan.json` to that real ID.
|
|
233
|
+
> 4. Push the corrected `caseplan.json` back with a **targeted single-file update** — `PUT /api/Project/{projectId}/FileOperations/File/{fileId}` (same file's own real ID) — **not** another whole-project `uip solution upload`. A second whole-project upload re-imports everything and mints a **new** random file ID for every file, including `.hitl.json`, immediately invalidating whatever you just patched.
|
|
234
|
+
>
|
|
235
|
+
> This is a real gap, not just a documentation gap: today there is no supported CLI path to make a freshly-authored QuickForm task's schema editable in Studio Web without dropping to this undocumented internal API. It's a follow-up the user can request, never a mid-task blocker.
|
|
236
|
+
|
|
237
|
+
### Step 4 — Discover Upstream Variables
|
|
238
|
+
|
|
239
|
+
Read available case variables from the top-level `variables` field in `caseplan.json` (current schema is flat — no `root` wrapper; see [case-schema.md](../../uipath-maestro-case/references/case-schema.md#top-level-shape) in the case skill):
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"inputs": [ { "id": "<varId>", "name": "invoiceId", "type": "string" } ],
|
|
244
|
+
"outputs": [],
|
|
245
|
+
"inputOutputs":[]
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
For cross-task references, source values come from upstream task `outputs[].var` — see [bindings-and-expressions.md](../../../uipath-maestro-case/references/bindings-and-expressions.md) in the case skill for the full discovery procedure.
|
|
250
|
+
|
|
251
|
+
> **No root-level bindings needed for QuickForm.** Unlike App-based (Path 2), QuickForm does **not** add entries to the top-level `bindings[]` array.
|
|
252
|
+
|
|
253
|
+
### Post-Write Verification (QuickForm)
|
|
254
|
+
|
|
255
|
+
Run `uip maestro case validate <caseplan.json> --output json`. Confirm:
|
|
256
|
+
|
|
257
|
+
- `.hitl.json` file exists in the project directory with `schemaId`, `fields[]` (unified array with `direction`), `outcomes[]`
|
|
258
|
+
- Action task `type === "action"`
|
|
259
|
+
- `data.taskTitle` non-empty and matches `data.context[taskTitle].value`
|
|
260
|
+
- `data.context[]` has entries for: `hitlType` (`"quick"`), `_schemaFileId`, `hitlSchemaId`, `taskTitle`, `labels`, `priority`, `actionCatalogName`, `enableActionableNotifications`
|
|
261
|
+
- `data.context[hitlSchemaId].value` matches `schemaId` in the `.hitl.json` file
|
|
262
|
+
- `data.inputs[]`/`data.outputs[]` are populated (mirroring `.hitl.json`'s fields) and `data.inputSchema` is present — see the callout in Step 3
|
|
263
|
+
- top-level `bindings[]` is **not** modified by this path
|
|
264
|
+
|
|
265
|
+
### Downstream Output Access (QuickForm)
|
|
266
|
+
|
|
267
|
+
Each field in `outputs[]` and `inOuts[]` exposes its value downstream via the field's `variable` property — the **full** `"vars.<name>"` string, not a bare name:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{ "id": "decision", "variable": "vars.decision", "type": "string", "label": "Decision" }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Downstream task input value: `"=vars.decision"`. The selected outcome is available via the task's `Action` output (see Step 3).
|
|
274
|
+
|
|
275
|
+
For the full cross-task wiring procedure, see [bindings-and-expressions.md](../../../uipath-maestro-case/references/bindings-and-expressions.md).
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Path 2 — App-Based Action Task (deployed Action Center app)
|
|
280
|
+
|
|
281
|
+
The task form is defined by a deployed Action Center app. Inputs are shown to the human; outputs are collected from the form and usable downstream via `=vars.<var>` expressions.
|
|
282
|
+
|
|
283
|
+
### Step 1 — Discover the App
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Pull the registry first (requires uip login)
|
|
287
|
+
uip maestro case registry pull
|
|
288
|
+
|
|
289
|
+
# Search for action apps
|
|
290
|
+
uip maestro case registry search --type action-apps --output json
|
|
291
|
+
|
|
292
|
+
# Get a specific app by name (check action-apps-index.json if CLI search fails)
|
|
293
|
+
uip maestro case registry get "<app-name>" --type action-apps --output json
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
> CLI search is known to fail for action-apps — always fall back to direct inspection of `~/.uipcli/case-resources/action-apps-index.json`. Use `id` (not `entityKey`), `deploymentTitle` (not `name`), and `deploymentFolder.fullyQualifiedName` for the folder path.
|
|
297
|
+
|
|
298
|
+
### Step 2 — Get the Input/Output Schema
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
uip maestro case tasks describe --type action --id "<action-app-id>" --output json
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Returns `inputs[]` and `outputs[]`. Capture both — they define what the human fills in and what the automation reads back.
|
|
305
|
+
|
|
306
|
+
### Step 3 — Write Root-Level Bindings
|
|
307
|
+
|
|
308
|
+
Add 2 entries to the top-level `bindings[]` array — one for `name` and one for `folderPath`. Deduplicate by `(default + resource + resourceKey)`.
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"id": "bG0SraLpg",
|
|
313
|
+
"name": "name",
|
|
314
|
+
"type": "string",
|
|
315
|
+
"resource": "app",
|
|
316
|
+
"resourceKey": "Shared.Contract Review App",
|
|
317
|
+
"propertyAttribute": "name",
|
|
318
|
+
"default": "Contract Review App"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"id": "bH1iJK2lm",
|
|
322
|
+
"name": "folderPath",
|
|
323
|
+
"type": "string",
|
|
324
|
+
"resource": "app",
|
|
325
|
+
"resourceKey": "Shared.Contract Review App",
|
|
326
|
+
"propertyAttribute": "folderPath",
|
|
327
|
+
"default": "Shared"
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`resourceKey` = `<folderPath>.<deploymentTitle>`. Binding IDs: `b` + 8 chars.
|
|
332
|
+
|
|
333
|
+
For the full binding procedure, see [bindings/impl-json.md](../../../uipath-maestro-case/references/plugins/variables/bindings/impl-json.md) in the case skill.
|
|
334
|
+
|
|
335
|
+
### Step 4 — Write the Task
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"id": "ta1b2c3d4",
|
|
340
|
+
"elementId": "Stage_aB3kL9-ta1b2c3d4",
|
|
341
|
+
"type": "action",
|
|
342
|
+
"isRequired": true,
|
|
343
|
+
"shouldRunOnlyOnce": false,
|
|
344
|
+
"entryConditions": [
|
|
345
|
+
{
|
|
346
|
+
"id": "Condition_EnTk1",
|
|
347
|
+
"displayName": "Entry Rule 1",
|
|
348
|
+
"rules": [ [ { "id": "Rule_EnTk1", "rule": "current-stage-entered" } ] ]
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
"data": {
|
|
352
|
+
"taskTitle": "Please review this contract and fill in the required fields",
|
|
353
|
+
"name": "=bindings.bG0SraLpg",
|
|
354
|
+
"folderPath": "=bindings.bH1iJK2lm",
|
|
355
|
+
"actionCatalogName": "Contract Review App",
|
|
356
|
+
"assignmentCriteria": "user",
|
|
357
|
+
"recipient": { "Type": 2, "Value": "reviewer@company.com" },
|
|
358
|
+
"context": [
|
|
359
|
+
{ "name": "hitlType", "type": "string", "value": "custom" }
|
|
360
|
+
],
|
|
361
|
+
"inputs": [],
|
|
362
|
+
"outputs": []
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
`data.name` and `data.folderPath` MUST be `=bindings.<id>` references — never string literals.
|
|
368
|
+
`data.inputs[]` and `data.outputs[]` are populated from the `tasks describe` response in Step 2.
|
|
369
|
+
|
|
370
|
+
> **`hitlType` is `"custom"` for app-based tasks.** App-based tasks have no schema file at all — the form is defined by the deployed app itself, not by a schema document. **Never write `_schemaFileId` or `hitlSchemaId` for an app-based task** — those two context entries exist only on the QuickForm path (Path 1), where they identify the `.hitl.json` schema file. An app-based task is fully described by `data.name`/`data.folderPath` (the bindings to the deployed app) plus `data.inputs[]`/`data.outputs[]` (from `tasks describe`) — nothing else identifies its "schema."
|
|
371
|
+
|
|
372
|
+
For the full `inputs[]`/`outputs[]` variable shapes, see [action/impl-json.md](../../../uipath-maestro-case/references/plugins/tasks/action/impl-json.md).
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Post-Write Verification (all paths)
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
uip maestro case validate <caseplan.json> --output json
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
| Path | Verify |
|
|
383
|
+
|---|---|
|
|
384
|
+
| QuickForm | `.hitl.json` file present with `title`, `fields[]`, `outcomes[]` (no `action` key), `schemaId`; task has `displayName`; `data.context[]` has `hitlType: "quick"`, `_schemaFileId`, `hitlSchemaId` (matches `.hitl.json` `schemaId`), `taskTitle`; `data.inputs[]`/`data.outputs[]` populated (not empty) and `data.inputSchema` present, mirroring `.hitl.json`'s fields; no `actionCatalogName` value; no top-level `bindings[]` entries added |
|
|
385
|
+
| App-based | `type: "action"`, `data.taskTitle` non-empty, `data.name` and `data.folderPath` start with `=bindings.`, `data.context[]` has `hitlType: "custom"` and **no** `_schemaFileId`/`hitlSchemaId` entries (app-based tasks have no schema file), top-level `bindings[]` has 2 entries with `resource: "app"` and `propertyAttribute` = `name` / `folderPath`, `data.actionCatalogName` matches the deployed `deploymentTitle` |
|
|
386
|
+
| Both | The task node has `entryConditions[]` set — e.g. `current-stage-entered` (see the Step 3/4 examples above). Without it, validate fails with `Task has no entry rules`. This is a case-structural requirement, not HITL-specific — it applies to every action task written via direct JSON. |
|
|
387
|
+
|
|
388
|
+
If validate reports errors, **never report success**. Diagnose from the JSON output and fix before reporting back. A validate error unrelated to the HITL task itself (e.g. `Case has no completion rules` on a stage/case that predates your edit) is a pre-existing gap in the case plan, not something this skill introduces — surface it to the user rather than reverse-engineering the CLI to silence it.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Downstream Output Access
|
|
393
|
+
|
|
394
|
+
| Path | Outputs available downstream? | How |
|
|
395
|
+
|---|---|---|
|
|
396
|
+
| QuickForm | Yes — every `outputs[]` and `inOuts[]` field in the `.hitl.json` | `field.variable` is already the full `=vars.<name>` reference (minus the leading `=`) |
|
|
397
|
+
| App-based | Yes — every `data.outputs[]` entry | `=vars.<output.var>` |
|
|
398
|
+
|
|
399
|
+
**QuickForm example:**
|
|
400
|
+
|
|
401
|
+
```json
|
|
402
|
+
{ "id": "decision", "variable": "vars.decision", "type": "string", "label": "Decision" }
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Downstream task input: `"value": "=vars.decision"`.
|
|
406
|
+
|
|
407
|
+
**App-based example:**
|
|
408
|
+
|
|
409
|
+
```json
|
|
410
|
+
{ "name": "decision", "type": "string", "id": "out_decision", "var": "decisionVar" }
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Downstream task input: `"value": "=vars.decisionVar"`.
|
|
414
|
+
|
|
415
|
+
For the full cross-task wiring procedure, see [bindings-and-expressions.md](../../../uipath-maestro-case/references/bindings-and-expressions.md).
|
|
@@ -97,17 +97,13 @@ Flatten both `solutionResources` and `availableResources` folder groups into a s
|
|
|
97
97
|
**Selection rules:**
|
|
98
98
|
|
|
99
99
|
- **Exactly one match** → use it, proceed to Step 3.
|
|
100
|
-
- **Multiple matches** →
|
|
100
|
+
- **Multiple matches** → never block waiting for a choice. Pick the best match automatically (prefer an exact case-insensitive name match in a `Shared` folder, else the first result), proceed, and state the choice plus the alternatives so the user can correct it:
|
|
101
101
|
|
|
102
|
-
> I found multiple apps matching that name.
|
|
103
|
-
> 1. **Invoice Approval** — Shared / Coded Action
|
|
104
|
-
> 2. **Invoice Approval** — Finance / VB Action
|
|
105
|
-
>
|
|
106
|
-
> Reply with the number of the app you want.
|
|
102
|
+
> I found multiple apps matching that name and used **Invoice Approval** (Shared / Coded Action). Other matches, if this was the wrong one: **Invoice Approval** (Finance / VB Action). Tell me to swap it if I picked wrong.
|
|
107
103
|
|
|
108
|
-
Use `nextPageCursor` to fetch additional pages if the list is truncated.
|
|
104
|
+
Use `nextPageCursor` to fetch additional pages if the list is truncated.
|
|
109
105
|
|
|
110
|
-
- **Zero matches** →
|
|
106
|
+
- **Zero matches** → never block. Fall back to QuickForm (per SKILL.md Step 3's fallback rule) and proceed. State: "No deployed app named `<APP_NAME>` was found, so I used QuickForm instead. Verify the name and that the app is deployed, then ask me to swap it in."
|
|
111
107
|
|
|
112
108
|
### Step 3 — Retrieve app configuration
|
|
113
109
|
|
|
@@ -88,7 +88,7 @@ The source path provided by the user must already contain the built `dist/` fold
|
|
|
88
88
|
rsync -a --exclude='node_modules' "<SOURCE_PATH>/" "<SOLUTION_DIR>/<APP_NAME>/source/"
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
> The `dist/` folder must exist inside `<SOURCE_PATH>` before copying — it is the compiled output that the solution packages. If it is missing,
|
|
91
|
+
> The `dist/` folder must exist inside `<SOURCE_PATH>` before copying — it is the compiled output that the solution packages. If it is missing, never block waiting for a build: fall back to QuickForm instead (per SKILL.md Step 3's fallback rule), proceed, and state that you did so — the user can ask you to swap in the Coded Action App once it's built.
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
@@ -6,7 +6,7 @@ The agent writes the `uipath.human-in-the-loop.quick-form` node directly into th
|
|
|
6
6
|
|
|
7
7
|
## Step 1 — Extract the Schema Through Conversation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Never block on this.** Infer the answers to the questions below from the prompt and any upstream `.flow` data, and proceed straight to schema design — do not wait for a reply. If the user is present and volunteers this information unprompted, use it. Only stop and report the open decision if the request is genuinely too ambiguous to pick a sensible default.
|
|
10
10
|
|
|
11
11
|
| What you need to know | Question to ask |
|
|
12
12
|
|---|---|
|
|
@@ -93,7 +93,7 @@ The node schema uses `fields[]` entries inside `inputs.schema`. Use these concep
|
|
|
93
93
|
- `outcomes`: use domain-specific names (Approve/Reject, not just Submit)
|
|
94
94
|
- Keep it focused — don't add fields the automation won't use
|
|
95
95
|
|
|
96
|
-
**
|
|
96
|
+
**Never block on this — write the node, don't wait to show the schema first.** Design the schema from the prompt and any upstream `.flow` data, write the node, and record the chosen schema prominently in the final report so the user can adjust it afterward. Only stop and report the open decision if the request is genuinely too ambiguous to pick a sensible default. (A prompt that already specifies the fields, outcomes, and output shape is never too ambiguous.)
|
|
97
97
|
|
|
98
98
|
---
|
|
99
99
|
|
|
@@ -147,8 +147,6 @@ A monetary action above a threshold or of a certain type requires human sign-off
|
|
|
147
147
|
|
|
148
148
|
## Proactive HITL Recommendation
|
|
149
149
|
|
|
150
|
-
If a business description contains any of the above signals but the user has not asked for a HITL,
|
|
150
|
+
**Never block on this.** If a business description contains any of the above signals but the user has not asked for a HITL, state it and proceed straight to Step 3 (schema design) — do not wait for a reply:
|
|
151
151
|
|
|
152
|
-
> "This process includes [signal]. Before the automation [action], a human should review [data]. I
|
|
153
|
-
|
|
154
|
-
Then proceed to Step 3 (schema design) only after the user confirms.
|
|
152
|
+
> "This process includes [signal]. Before the automation [action], a human should review [data]. I'm inserting a HITL node here — remove it if you don't want it."
|
package/version-manifest.json
CHANGED