@uipath/maestro-builder-sdk 6.21.2 → 6.23.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.
Files changed (42) hide show
  1. package/dist/api-index.md +138 -138
  2. package/dist/api-members.md +407 -407
  3. package/dist/check.js +43 -331
  4. package/dist/core/actions.d.ts +0 -287
  5. package/dist/core/actions.js +0 -95
  6. package/dist/core/expr.d.ts +1 -1
  7. package/dist/core/expr.js +2 -2
  8. package/dist/core/nodes/node-type.d.ts +15 -0
  9. package/dist/core/step-ports.js +7 -23
  10. package/dist/core/typed-raw-node.js +0 -4
  11. package/dist/decompile.js +44 -115
  12. package/dist/flow-node-registry.js +3 -1
  13. package/dist/flow-node-type.d.ts +59 -0
  14. package/dist/flow-sdk.d.ts +2 -0
  15. package/dist/flow-sdk.js +2 -0
  16. package/dist/flow-step-exits.d.ts +12 -0
  17. package/dist/flow-step-exits.js +30 -0
  18. package/dist/nodes/ai-patterns/flow/factories.d.ts +83 -0
  19. package/dist/nodes/ai-patterns/flow/factories.js +86 -0
  20. package/dist/nodes/ai-patterns/flow/family.d.ts +3 -0
  21. package/dist/nodes/ai-patterns/flow/family.js +8 -0
  22. package/dist/nodes/ai-patterns/flow/index.d.ts +3 -0
  23. package/dist/nodes/ai-patterns/flow/index.js +3 -0
  24. package/dist/nodes/ai-patterns/flow/node-type.d.ts +11 -0
  25. package/dist/nodes/ai-patterns/flow/node-type.js +106 -0
  26. package/dist/nodes/ai-patterns/flow/spec.d.ts +75 -0
  27. package/dist/nodes/ai-patterns/flow/spec.js +1 -0
  28. package/dist/nodes/http/flow/check.d.ts +58 -0
  29. package/dist/nodes/http/flow/check.js +248 -0
  30. package/dist/nodes/http/flow/factories.d.ts +14 -0
  31. package/dist/nodes/http/flow/factories.js +20 -0
  32. package/dist/nodes/http/flow/family.d.ts +8 -0
  33. package/dist/nodes/http/flow/family.js +13 -0
  34. package/dist/nodes/http/flow/index.d.ts +3 -0
  35. package/dist/nodes/http/flow/index.js +3 -0
  36. package/dist/nodes/http/flow/node-type.d.ts +7 -0
  37. package/dist/nodes/http/flow/node-type.js +411 -0
  38. package/dist/nodes/http/flow/spec.d.ts +151 -0
  39. package/dist/nodes/http/flow/spec.js +1 -0
  40. package/dist/serialize.d.ts +2 -2
  41. package/dist/serialize.js +20 -316
  42. package/package.json +2 -2
@@ -10,141 +10,6 @@
10
10
  import type { Expr } from './expr.js';
11
11
  import type { LookupToken } from './lookups.js';
12
12
  import { type ConnectorDescriptor, type TriggerDescriptor } from './connectors.js';
13
- /** One conditional response branch on an HTTP node — a designer-visible side exit. */
14
- export interface HttpBranch {
15
- /**
16
- * The branch's name — it becomes the node's `branch-<name>` source port, so
17
- * keep it port-safe (letters, digits, `_`, `-`). Route it with
18
- * `.stepToList('branch-<name>', ...)` after the step; the main path continues
19
- * from the default port as always.
20
- */
21
- name: string;
22
- /**
23
- * When to take this exit, evaluated against the response — e.g.
24
- * js-tagged: `$vars.fetch.output.statusCode === 429`. Branches are checked in
25
- * order; the first truthy one wins, else the default port fires.
26
- */
27
- condition: Expr;
28
- }
29
- interface HttpInputsBase {
30
- /**
31
- * Conditional response branches — extra source ports (`branch-<name>`)
32
- * beside the default. See {@link HttpBranch}; both HTTP node families
33
- * declare them.
34
- */
35
- branches?: HttpBranch[];
36
- method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
37
- url: string | Expr;
38
- headers?: Record<string, string | Expr>;
39
- query?: Record<string, string | Expr>;
40
- body?: string | Expr;
41
- contentType?: string;
42
- /**
43
- * Choose the HTTP node explicitly. `false` emits the standalone
44
- * `core.action.http`; `true` emits the managed `core.action.http.v2`, routed
45
- * through Integration Service's HTTP connector.
46
- *
47
- * This has no default because these are different platform nodes, not two
48
- * modes of one node. A silent `false` made an omitted field compile and
49
- * validate as the wrong node while changing failure routing and connection
50
- * behavior.
51
- *
52
- * It is not a version bump, it changes two things you can see:
53
- *
54
- * - **a 4xx/5xx FAILS the step**, so `.onError(…)` fires on it. On the plain
55
- * node the same 404 comes back on the SUCCESS path as
56
- * `out('fetch','statusCode')` and no error handler ever runs — which is why
57
- * an error port only makes sense here (`check` says so: HTTP_ONERROR_V1).
58
- * The handler can answer the flow (`.return`), stop the run
59
- * (`.terminate`), or compensate and continue at a step the success path
60
- * also reaches (`h.stepToRef('<step>')` — see `references/error-handling.md`);
61
- * - both nodes expose JSON responses as parsed values in the live product;
62
- * use `returns` to declare fields before reading them. The node choice does
63
- * not decide whether application/json is parsed.
64
- *
65
- * With `managed: true`, omit `connection` and `folder` for the platform's
66
- * manual/implicit mode, or provide both symbolic names to reuse an Integration
67
- * Service HTTP connection. A local run remains unauthenticated.
68
- *
69
- * @enforcedBy HTTP_ONERROR_V1 `.onError()` on an http step needs `managed: true`; on
70
- * the standalone node a 4xx arrives on the SUCCESS path and no handler runs.
71
- */
72
- managed: boolean;
73
- /**
74
- * The response BODY's top-level fields and their types — e.g.
75
- * `{ items: 'array' }`. Required for either HTTP node if anything reads a
76
- * field off a parsed JSON body.
77
- *
78
- * Why you have to say: the platform's own definition declares the response as
79
- * a bare object, because only the API being called knows its shape. Without
80
- * this, `out('fetch','body','items')` reads from an object with no declared
81
- * fields, and nothing downstream can tell a real field from a typo. Same rule,
82
- * and the same word, as
83
- * `rpaWorkflow`'s `returns`.
84
- *
85
- * **Where a declared field is read:** under `body`, never beside it. The
86
- * response is an envelope — `{ body, statusCode, headers }` — and these are the
87
- * body's fields, so `returns: { items: 'array' }` is read as
88
- * `out('fetch', 'body.items')`, which is `$vars.fetch.output.body.items`.
89
- * `$vars.fetch.output.items` is undefined at run time.
90
- *
91
- * @enforcedBy HTTP_READ_UNKNOWN_FIELD A read must be `output.body.<declared field>`,
92
- * `output.statusCode` or `output.headers`.
93
- * @enforcedBy HTTP_READ_WITHOUT_RETURNS Reading a body field requires declaring it here.
94
- */
95
- returns?: Record<string, ReturnFieldType>;
96
- /**
97
- * How long to wait for the response before giving up, as an **ISO-8601
98
- * duration** — `'PT30S'` is "give up after 30 seconds", `'PT1M'` one minute,
99
- * `'PT15M'` fifteen.
100
- *
101
- * Both http node types carry this, and both definitions declare the same
102
- * default (`PT15M`), so leaving it unset is not "no timeout" — it is fifteen
103
- * minutes. Omitted from the emitted node unless you set it, which keeps a flow
104
- * that doesn't care byte-identical to the platform's own default shape (~99%
105
- * of the 808 deployed http nodes are on the defaults).
106
- *
107
- * `check` rejects a string the platform cannot parse as a duration —
108
- * `'30s'`, `'PT'` and `'30'` are all errors that name the expected form.
109
- *
110
- * @defaultValue `'PT15M'`
111
- * @enforcedBy HTTP_TIMEOUT_NOT_DURATION Must be an ISO-8601 duration.
112
- */
113
- timeout?: string;
114
- /**
115
- * How many times to RETRY a retryable failure (5xx, 429, a network error) —
116
- * `0`, the definitions' default, means "try once, don't retry". `2` means up
117
- * to three attempts in total.
118
- *
119
- * Must be a non-negative integer. Above **5** `check` warns rather than
120
- * errors: the deployed corpus's
121
- * largest author-set value is 3, and the platform's own ceiling is not
122
- * measured — so a bigger number may well work, and refusing it outright would
123
- * fence off something we have no evidence is wrong.
124
- *
125
- * @defaultValue `0`
126
- * @enforcedBy HTTP_RETRY_COUNT_INVALID Must be a non-negative integer.
127
- */
128
- retryCount?: number;
129
- }
130
- export type HttpInputs = HttpInputsBase & ({
131
- managed: false;
132
- connection?: never;
133
- folder?: never;
134
- } | {
135
- managed: true;
136
- /** Symbolic HTTP connection name declared in bindings.json. */
137
- connection?: string;
138
- /** Symbolic folder name declared in bindings.json. */
139
- folder?: string;
140
- /**
141
- * Connector key whose authentication the HTTP proxy should reuse.
142
- * Defaults to `uipath-uipath-http`. Set this for a connector-specific
143
- * fallback endpoint, for example `uipath-salesforce-slack`.
144
- * Requires both `connection` and `folder`.
145
- */
146
- targetConnector?: string;
147
- });
148
13
  export interface ConnectorOpts {
149
14
  /** Connector action version (defaults to the library's newest match). */
150
15
  version?: string;
@@ -671,62 +536,6 @@ export interface VoiceAgentInputs {
671
536
  */
672
537
  source?: string;
673
538
  }
674
- export interface SummarizeInputs {
675
- /**
676
- * The document to summarize — a whole **Flow Attachment** object
677
- * (`{ ID, FullName, MimeType, Metadata }`), not a path, id or URL.
678
- *
679
- * In practice that is a `file`-typed flow input:
680
- *
681
- * ```ts
682
- * flow('SummarizeDemo')
683
- * .input({ documentFile: types.file })
684
- * .step('summarizeContract', summarize({ attachment: input('documentFile'), … }))
685
- * ```
686
- *
687
- * `out('start', 'documentFile')` is the same value written the way the CANVAS
688
- * writes it (`$vars.start.output.documentFile`, resolved through the input's
689
- * `triggerNodeId` binding). Both forms run — measured on the real service —
690
- * so prefer whichever the task asks for; `out('start', …)` is what a
691
- * designer-made flow looks like.
692
- *
693
- * The service reads the file's CONTENT, and refuses one it cannot treat as a
694
- * document: a PDF summarizes, a plain `.txt` comes back
695
- * `[460005] … "No valid files to use for Summarization."`
696
- */
697
- attachment: Expr;
698
- /** What the summary should cover, e.g. `'Write a 5-bullet executive summary…'`. */
699
- prompt: string | Expr;
700
- /**
701
- * Ask the service for per-claim citations. Each is
702
- * `{ Ordinal, PageNumber, Source, Reference }` and lands in
703
- * `out('<step>', 'content.Citations')`. Defaults to `false`.
704
- */
705
- returnCitations?: boolean;
706
- }
707
- /** One column Batch Transform appends to the CSV. */
708
- export interface OutputColumn {
709
- /** The new column's header, e.g. `'Category'`. */
710
- name: string;
711
- /** What the model should put in it, e.g. `'One of: Utility, Software, Travel, Other'`. */
712
- description: string;
713
- }
714
- export interface BatchTransformInputs {
715
- /**
716
- * The CSV to enrich — a whole **Flow Attachment** object, same shape and same
717
- * two ways of referencing it as {@link SummarizeInputs.attachment}.
718
- */
719
- attachment: Expr;
720
- /** How to process each row, e.g. `'Classify each row and write a one-line summary.'`. */
721
- prompt: string | Expr;
722
- /**
723
- * The columns to add, in order. The node's own field name — an array of
724
- * `{ name, description }`, one per new column.
725
- */
726
- outputColumns: OutputColumn[];
727
- /** Let the model use web search while transforming. Defaults to `false`. */
728
- enableWebSearchGrounding?: boolean;
729
- }
730
539
  /**
731
540
  * Split an extractor's node type into the two GUIDs its tail packs.
732
541
  *
@@ -1928,10 +1737,6 @@ export interface ContextIndexRef {
1928
1737
  * whole body rather than an inputs payload.
1929
1738
  */
1930
1739
  export interface FlowActionSpecs {
1931
- /** The spec {@link http} builds. */
1932
- http: {
1933
- inputs: HttpInputs;
1934
- };
1935
1740
  /** The spec {@link hitl} builds. */
1936
1741
  hitl: {
1937
1742
  inputs: HitlInputs;
@@ -1988,14 +1793,6 @@ export interface FlowActionSpecs {
1988
1793
  inlineAgent: {
1989
1794
  inputs: InlineAgentInputs;
1990
1795
  };
1991
- /** The spec {@link summarize} builds. */
1992
- summarize: {
1993
- inputs: SummarizeInputs;
1994
- };
1995
- /** The spec {@link batchTransform} builds. */
1996
- batchTransform: {
1997
- inputs: BatchTransformInputs;
1998
- };
1999
1796
  /** The spec {@link ixpExtract} builds. */
2000
1797
  ixpExtract: {
2001
1798
  inputs: IxpExtractInputs;
@@ -2059,14 +1856,6 @@ export declare function builtinActionSpec<S extends object>(spec: S): S;
2059
1856
  * @returns The same spec, as a `FlowTrigger` instance.
2060
1857
  */
2061
1858
  export declare function builtinTriggerSpec<S extends object>(spec: S): S;
2062
- /**
2063
- * Declare an HTTP request action, explicitly choosing standalone or managed.
2064
- *
2065
- * @param inputs - The request: `url`, `method`, `body`, the response fields you
2066
- * read back via `returns`, and the `managed` node choice.
2067
- * @returns An action spec to pass to `.step(name, …)`.
2068
- */
2069
- export declare function http(inputs: HttpInputs): ActionSpec;
2070
1859
  /**
2071
1860
  * Declare a human task — a step that pauses for a person to read some values,
2072
1861
  * fill others in, and press one of the outcome buttons.
@@ -2119,82 +1908,6 @@ export declare function http(inputs: HttpInputs): ActionSpec;
2119
1908
  * @example example-eval/GallerySubmission.flow.ts
2120
1909
  */
2121
1910
  export declare function hitl(inputs: HitlInputs): ActionSpec;
2122
- /**
2123
- * Summarize a document with citations — the platform's **Summarize** node.
2124
- *
2125
- * @remarks
2126
- * **The node type is `uipath.pattern.deep-rag`.** The canvas calls it
2127
- * *Summarize*, its properties panel is titled *Summarize Configuration*, and
2128
- * the wire type stays `deep-rag` — it is the same node, under the name the
2129
- * backend service contract uses (`ECS.DeepRag`). There is no
2130
- * `uipath.pattern.summarize`. (A same-named inline-agent TOOL,
2131
- * `uipath.agent.resource.tool.builtin.summarize`, is a different family.)
2132
- *
2133
- * The answer's fields are **PascalCase** — `content.Text`,
2134
- * `content.Citations[].{Ordinal, PageNumber, Source, Reference}`. Lowercase
2135
- * `content.text` resolves to nothing at run time.
2136
- *
2137
- * A local run cannot reach the service: it returns the baked
2138
- * fixture shape, and only a real platform run (`uip maestro flow debug
2139
- * --attachment <var>=<file>`) calls the model.
2140
- *
2141
- * @example
2142
- * **Summarize an attached contract, with citations**
2143
- * ```ts
2144
- * flow('SummarizeDemo')
2145
- * .input({ documentFile: types.file })
2146
- * .output({ summary: types.string, citations: types.array })
2147
- * .step('summarizeContract', summarize({
2148
- * attachment: out('start', 'documentFile'),
2149
- * prompt: 'Write a 5-bullet executive summary covering scope, term and SLAs.',
2150
- * returnCitations: true,
2151
- * }))
2152
- * .return({
2153
- * summary: out('summarizeContract', 'content.Text'),
2154
- * citations: out('summarizeContract', 'content.Citations'),
2155
- * })
2156
- * ```
2157
- *
2158
- * @param inputs - The document (`attachment`), the question to answer (`prompt`),
2159
- * and whether to return citations.
2160
- * @returns An action spec to pass to `.step(name, …)`.
2161
- */
2162
- export declare function summarize(inputs: SummarizeInputs): ActionSpec;
2163
- /**
2164
- * Add AI-generated columns to a CSV — the platform's **Batch transform** node,
2165
- * `uipath.pattern.batch-transform` (service contract `ECS.BatchTransform`).
2166
- *
2167
- * @remarks
2168
- * The output is a **file handle for the enriched CSV**, not the rows:
2169
- * `{ ID, FullName, MimeType }` — the service writes a new
2170
- * `batch-transform-<uuid>.csv` and hands back its attachment. Note `ID`, two
2171
- * capitals: that is what the platform returns.
2172
- *
2173
- * Same dispatch story as {@link summarize} — dry-run fixture locally, a real
2174
- * model call only on a platform run.
2175
- *
2176
- * @example
2177
- * **Categorize each CSV row with two generated columns**
2178
- * ```ts
2179
- * flow('BatchTransformDemo')
2180
- * .input({ csvFile: types.file })
2181
- * .output({ result: types.file })
2182
- * .step('categorizeRows', batchTransform({
2183
- * attachment: out('start', 'csvFile'),
2184
- * prompt: 'Classify each row by category and write a one-line summary.',
2185
- * outputColumns: [
2186
- * { name: 'Category', description: 'One of: Utility, Software, Travel, Other' },
2187
- * { name: 'Summary', description: 'Plain-English one-line summary of the row' },
2188
- * ],
2189
- * }))
2190
- * .return({ result: out('categorizeRows') })
2191
- * ```
2192
- *
2193
- * @param inputs - The CSV (`attachment`), the instruction (`prompt`), and the
2194
- * `outputColumns` to add to each row.
2195
- * @returns An action spec to pass to `.step(name, …)`.
2196
- */
2197
- export declare function batchTransform(inputs: BatchTransformInputs): ActionSpec;
2198
1911
  /**
2199
1912
  * Extract fields from a document with a published IxP project — the platform's
2200
1913
  * **Extract** node (`uipath.ixp.*`, service contract `IXP.Extraction`).
@@ -88,21 +88,6 @@ export function builtinActionSpec(spec) {
88
88
  export function builtinTriggerSpec(spec) {
89
89
  return new BuiltinTrigger(spec);
90
90
  }
91
- /**
92
- * Declare an HTTP request action, explicitly choosing standalone or managed.
93
- *
94
- * @param inputs - The request: `url`, `method`, `body`, the response fields you
95
- * read back via `returns`, and the `managed` node choice.
96
- * @returns An action spec to pass to `.step(name, …)`.
97
- */
98
- export function http(inputs) {
99
- if (typeof inputs.managed !== 'boolean') {
100
- throw new Error('http() requires managed: true or managed: false because they emit different platform nodes. '
101
- + 'Use true for Managed HTTP Request/core.action.http.v2 or when non-2xx statuses must reach .onError(); '
102
- + 'use false for the standalone core.action.http node.');
103
- }
104
- return builtinActionSpec({ kind: 'http', inputs });
105
- }
106
91
  /**
107
92
  * Declare a human task — a step that pauses for a person to read some values,
108
93
  * fill others in, and press one of the outcome buttons.
@@ -157,86 +142,6 @@ export function http(inputs) {
157
142
  export function hitl(inputs) {
158
143
  return builtinActionSpec({ kind: 'hitl', inputs });
159
144
  }
160
- /**
161
- * Summarize a document with citations — the platform's **Summarize** node.
162
- *
163
- * @remarks
164
- * **The node type is `uipath.pattern.deep-rag`.** The canvas calls it
165
- * *Summarize*, its properties panel is titled *Summarize Configuration*, and
166
- * the wire type stays `deep-rag` — it is the same node, under the name the
167
- * backend service contract uses (`ECS.DeepRag`). There is no
168
- * `uipath.pattern.summarize`. (A same-named inline-agent TOOL,
169
- * `uipath.agent.resource.tool.builtin.summarize`, is a different family.)
170
- *
171
- * The answer's fields are **PascalCase** — `content.Text`,
172
- * `content.Citations[].{Ordinal, PageNumber, Source, Reference}`. Lowercase
173
- * `content.text` resolves to nothing at run time.
174
- *
175
- * A local run cannot reach the service: it returns the baked
176
- * fixture shape, and only a real platform run (`uip maestro flow debug
177
- * --attachment <var>=<file>`) calls the model.
178
- *
179
- * @example
180
- * **Summarize an attached contract, with citations**
181
- * ```ts
182
- * flow('SummarizeDemo')
183
- * .input({ documentFile: types.file })
184
- * .output({ summary: types.string, citations: types.array })
185
- * .step('summarizeContract', summarize({
186
- * attachment: out('start', 'documentFile'),
187
- * prompt: 'Write a 5-bullet executive summary covering scope, term and SLAs.',
188
- * returnCitations: true,
189
- * }))
190
- * .return({
191
- * summary: out('summarizeContract', 'content.Text'),
192
- * citations: out('summarizeContract', 'content.Citations'),
193
- * })
194
- * ```
195
- *
196
- * @param inputs - The document (`attachment`), the question to answer (`prompt`),
197
- * and whether to return citations.
198
- * @returns An action spec to pass to `.step(name, …)`.
199
- */
200
- export function summarize(inputs) {
201
- return builtinActionSpec({ kind: 'summarize', inputs });
202
- }
203
- /**
204
- * Add AI-generated columns to a CSV — the platform's **Batch transform** node,
205
- * `uipath.pattern.batch-transform` (service contract `ECS.BatchTransform`).
206
- *
207
- * @remarks
208
- * The output is a **file handle for the enriched CSV**, not the rows:
209
- * `{ ID, FullName, MimeType }` — the service writes a new
210
- * `batch-transform-<uuid>.csv` and hands back its attachment. Note `ID`, two
211
- * capitals: that is what the platform returns.
212
- *
213
- * Same dispatch story as {@link summarize} — dry-run fixture locally, a real
214
- * model call only on a platform run.
215
- *
216
- * @example
217
- * **Categorize each CSV row with two generated columns**
218
- * ```ts
219
- * flow('BatchTransformDemo')
220
- * .input({ csvFile: types.file })
221
- * .output({ result: types.file })
222
- * .step('categorizeRows', batchTransform({
223
- * attachment: out('start', 'csvFile'),
224
- * prompt: 'Classify each row by category and write a one-line summary.',
225
- * outputColumns: [
226
- * { name: 'Category', description: 'One of: Utility, Software, Travel, Other' },
227
- * { name: 'Summary', description: 'Plain-English one-line summary of the row' },
228
- * ],
229
- * }))
230
- * .return({ result: out('categorizeRows') })
231
- * ```
232
- *
233
- * @param inputs - The CSV (`attachment`), the instruction (`prompt`), and the
234
- * `outputColumns` to add to each row.
235
- * @returns An action spec to pass to `.step(name, …)`.
236
- */
237
- export function batchTransform(inputs) {
238
- return builtinActionSpec({ kind: 'batchTransform', inputs });
239
- }
240
145
  /**
241
146
  * Extract fields from a document with a published IxP project — the platform's
242
147
  * **Extract** node (`uipath.ixp.*`, service contract `IXP.Extraction`).
@@ -196,7 +196,7 @@ export type ErrorEnvelopeField = 'code' | 'message' | 'detail' | 'category' | 's
196
196
  *
197
197
  * So the author writes one shape, `.error.<field>`, and `serialize` rewrites it
198
198
  * to `.output.<field>` for the one family that publishes it there
199
- * (`ERROR_ENVELOPE_VAR` in `serialize.ts`). Do not hand-write either prefix: which
199
+ * (a node type's `errorEnvelope`). Do not hand-write either prefix: which
200
200
  * one is right is not a property of the expression, it is a property of the node
201
201
  * the step happens to be, and only the builder knows that.
202
202
  *
package/dist/core/expr.js CHANGED
@@ -209,7 +209,7 @@ export function ran(step) {
209
209
  *
210
210
  * So the author writes one shape, `.error.<field>`, and `serialize` rewrites it
211
211
  * to `.output.<field>` for the one family that publishes it there
212
- * (`ERROR_ENVELOPE_VAR` in `serialize.ts`). Do not hand-write either prefix: which
212
+ * (a node type's `errorEnvelope`). Do not hand-write either prefix: which
213
213
  * one is right is not a property of the expression, it is a property of the node
214
214
  * the step happens to be, and only the builder knows that.
215
215
  *
@@ -258,7 +258,7 @@ export function ran(step) {
258
258
  */
259
259
  export function err(step, field) {
260
260
  // ONE shape for every family. `serialize` rewrites the prefix for the families
261
- // that publish the envelope elsewhere — see `ERROR_ENVELOPE_VAR`.
261
+ // that publish the envelope elsewhere — see `FlowNodeType.errorEnvelope`.
262
262
  return new Expr(`$vars.${step}.error${field ? '.' + field : ''}`);
263
263
  }
264
264
  /**
@@ -45,6 +45,13 @@ export interface OutputRead {
45
45
  /** The step whose expression contains the read. */
46
46
  reader: string;
47
47
  }
48
+ /** A read of a node's output, split where a `reader` contract checks it. */
49
+ export interface OutputPathRead extends OutputRead {
50
+ /** The first segment after the step (`output`, `error`, …); undefined for a read of the step itself. */
51
+ field: string | undefined;
52
+ /** The path after `field`, as the reference spells it (with its leading `.`); `''` when there is none. */
53
+ rest: string;
54
+ }
48
55
  /**
49
56
  * How the artifact words a read of a `fields` output: the code prefix its read
50
57
  * diagnostics share (`<PREFIX>_READ_NOT_OUTPUT`, `_READ_WITHOUT_RETURNS`,
@@ -65,6 +72,11 @@ export interface FieldsRead {
65
72
  * states the fields a read may name — `undefined` when the author declared none,
66
73
  * which makes any field read its own mistake — and `read` keeps the wording of
67
74
  * the read rule it replaces, for the same reason. `open` admits any field.
75
+ *
76
+ * `reader` is for an output whose shape no field list states: an HTTP response is
77
+ * an envelope (`body`, `statusCode`, `headers`) whose `body` holds the author's
78
+ * `returns`. The type checks each read itself and reports through its family's
79
+ * catalog, with the codes it had before the port.
68
80
  */
69
81
  export type OutputContract = {
70
82
  readonly kind: 'none';
@@ -75,6 +87,9 @@ export type OutputContract = {
75
87
  readonly fields: Readonly<Record<string, TypeDesc>> | undefined;
76
88
  readonly open?: boolean;
77
89
  readonly read: FieldsRead;
90
+ } | {
91
+ readonly kind: 'reader';
92
+ read(read: OutputPathRead, report: (code: string, message: string, suggestion?: string) => void): void;
78
93
  } | {
79
94
  readonly kind: 'opaque';
80
95
  };
@@ -1,14 +1,15 @@
1
1
  /**
2
- * The exits an action declares that the AUTHOR named — a human task's outcomes,
3
- * an HTTP call's response branches — and the port each one leaves on.
2
+ * The exits an action declares that the AUTHOR named — a human task's outcomes —
3
+ * and the port each one leaves on. A registered node type declares its own
4
+ * (`FlowNodeType.exits`: an HTTP call's response branches); `stepExits` in
5
+ * flow-step-exits.ts asks it first and falls back here.
4
6
  *
5
7
  * This is what `.stepSwitch()` routes over, and the reason it exists as a table
6
- * rather than as two more `if (spec.kind === …)` arms: `serialize` has to turn
8
+ * rather than as more `if (spec.kind === …)` arms: `serialize` has to turn
7
9
  * an arm's `value` into a port, `check` has to say which values are legal and
8
10
  * which were left out, and `decompile` has to turn a port back into a value.
9
- * Those three read the same list here instead of each carrying their own copy
10
- * of "how a human task names its ports" and "how an HTTP branch names its
11
- * ports".
11
+ * Those three read the same list instead of each carrying their own copy of
12
+ * "how a human task names its ports".
12
13
  *
13
14
  * `undefined` means the family has no author-declared fan-out at all, which is
14
15
  * what makes `.stepSwitch()` on it an error rather than a no-op.
@@ -68,23 +69,6 @@ export function declaredExits(spec, pinnedVersion) {
68
69
  ...(e.endsProcess ? { endsProcess: true } : {}),
69
70
  }));
70
71
  }
71
- if (kind === 'http') {
72
- const branches = (spec?.inputs?.branches
73
- ?? []);
74
- if (branches.length === 0) {
75
- return {
76
- reason: 'it declares no response branches',
77
- suggestion: `branches: [{ name: 'rateLimited', condition: … }]`,
78
- };
79
- }
80
- // The fall-through is an exit like any other here — it is what `.switch()`
81
- // spells as its default arm, and leaving it out is the same omission as
82
- // leaving out a branch.
83
- return [
84
- ...branches.map((b) => ({ value: String(b?.name ?? ''), port: `branch-${b?.name ?? ''}` })),
85
- { value: 'default', port: 'default', isDefault: true },
86
- ];
87
- }
88
72
  return {
89
73
  reason: `a ${kind ?? 'custom'} step declares no author-named exits`,
90
74
  suggestion: 'Use .step(); route failures with .onError().',
@@ -21,8 +21,6 @@ import { ownEntry } from './own-entry.js';
21
21
  * themselves (the Data Fabric verbs, since Phase 3).
22
22
  */
23
23
  export const TYPED_FACTORIES = {
24
- 'core.action.http': { factory: 'http({ managed: false })' },
25
- 'core.action.http.v2': { factory: 'http({ managed: true })' },
26
24
  'core.control.end': { factory: '.return()' },
27
25
  'core.logic.decision': { factory: '.branch()' },
28
26
  'core.logic.dowhile': { factory: '.doWhile(name, condition, body, { limit, breakEnabled })' },
@@ -47,8 +45,6 @@ export const TYPED_FACTORIES = {
47
45
  factory: "hitl({ variant: 'document-validation' })",
48
46
  },
49
47
  'uipath.human-in-the-loop.quick-form': { factory: "hitl({ variant: 'quick-form' })" },
50
- 'uipath.pattern.batch-transform': { factory: 'batchTransform()' },
51
- 'uipath.pattern.deep-rag': { factory: 'summarize()' },
52
48
  };
53
49
  /**
54
50
  * A reminder, as a `warning`, that a `rawNode` stands in for a typed factory,