@meistrari/tela-cli 0.7.58 → 1.0.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/README.md +24 -3
- package/dist/commands/auth.js +131 -0
- package/dist/commands/context.js +118 -0
- package/dist/commands/doctor-auth.js +41 -0
- package/dist/commands/env.js +40 -0
- package/dist/commands/ingredients.js +824 -0
- package/dist/credentials.js +7 -0
- package/dist/docs/workflow-code/api-reference.md +604 -0
- package/dist/docs/workflow-code/cli.md +210 -0
- package/dist/docs/workflow-code/config.md +69 -0
- package/dist/docs/workflow-code/guides.md +56 -0
- package/dist/docs/workflow-code/installation.md +33 -0
- package/dist/docs/workflow-code/manifest.json +50 -0
- package/dist/docs/workflow-code/overview.md +14 -0
- package/dist/docs/workflow-code/quick-start.md +124 -0
- package/dist/index.js +63720 -26470
- package/dist/output.js +18 -0
- package/dist/program.js +96 -0
- package/package.json +5 -2
- package/scripts/install-skills.cjs +120 -111
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCliCredentialAdapter = createCliCredentialAdapter;
|
|
4
|
+
const tela_local_config_1 = require("@meistrari/tela-local-config");
|
|
5
|
+
function createCliCredentialAdapter(env = process.env) {
|
|
6
|
+
return (0, tela_local_config_1.createLocalCredentialAdapter)(env);
|
|
7
|
+
}
|
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
## API Reference
|
|
2
|
+
|
|
3
|
+
Workflow Code lets you describe a Tela Workflow V3 workflow as typed, inert TypeScript. Authoring APIs create declarations only. The compiler later validates references, evaluates supported `code()` handlers from source, and produces deterministic Workflow V3 payloads.
|
|
4
|
+
|
|
5
|
+
Use this page as the complete authoring guide while writing workflow source.
|
|
6
|
+
|
|
7
|
+
### Authoring model
|
|
8
|
+
|
|
9
|
+
Import the authoring helpers from `@meistrari/workflow-code`.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
agent,
|
|
14
|
+
build,
|
|
15
|
+
canvas,
|
|
16
|
+
code,
|
|
17
|
+
input,
|
|
18
|
+
llm,
|
|
19
|
+
splitter,
|
|
20
|
+
vault,
|
|
21
|
+
remote,
|
|
22
|
+
workflow,
|
|
23
|
+
} from '@meistrari/workflow-code'
|
|
24
|
+
import type { WorkflowCodeConfig } from '@meistrari/workflow-code'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| API | Use it for |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| [`workflow()`](#workflowworkflowkey) | Naming the workflow with a stable source key. |
|
|
30
|
+
| [`build()`](#buildworkflowhandle-options) | Creating the default-exported declaration consumed by `compile`. |
|
|
31
|
+
| [`input.text()`](#inputtextoptions) | Text input supplied by a user, API caller, or run payload. |
|
|
32
|
+
| [`input.file()`](#inputfileoptions) | File input supplied by upload or Vault reference. |
|
|
33
|
+
| [`llm()`](#llmoptions) | Single model-call transformation with optional structured output. |
|
|
34
|
+
| [`splitter()`](#splitteroptions) | Splitting file inputs, compatible prior outputs, or existing Vault files. |
|
|
35
|
+
| [`vault.ref()`](#vaultrefreference) | Declaring an inert reference to an existing `vault://...` file. |
|
|
36
|
+
| [`remote()`](#remote) | Generated catalog paths and explicit ID refs for inert remote authoring. |
|
|
37
|
+
| [`canvas()`](#canvasremoteref-options) | Executable Canvas or Workflow refs from the remote catalog. |
|
|
38
|
+
| [`agent(remoteRef, options)`](#agentremoteref-options) | Published-Agent calls from the remote catalog. |
|
|
39
|
+
| [`code()`](#codeoptions) | Sandboxed runtime JavaScript/TypeScript execution. |
|
|
40
|
+
| [`ref()` / `paths()` / `formats()`](#references-ref-paths-and-formats) | References to workflow inputs or prior node output in prompt callbacks and code handlers. |
|
|
41
|
+
|
|
42
|
+
A workflow file normally creates inputs, creates nodes, then default-exports `build(workflow(...), { inputs, nodes })`.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { agent, build, input, llm, remote, workflow } from '@meistrari/workflow-code'
|
|
46
|
+
|
|
47
|
+
const topic = input.text({ name: 'topic', required: true })
|
|
48
|
+
|
|
49
|
+
const outline = llm({
|
|
50
|
+
name: 'Draft outline',
|
|
51
|
+
input: {
|
|
52
|
+
temperature: 0.2,
|
|
53
|
+
prompt: ({ ref }) => `Create an outline about ${ref(topic).formats().format}.`,
|
|
54
|
+
},
|
|
55
|
+
schema: {
|
|
56
|
+
bullets: { type: 'array', items: { type: 'string' } },
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const reviewer = remote().agent().byId('published-agent-id')
|
|
61
|
+
|
|
62
|
+
const review = agent(reviewer, {
|
|
63
|
+
name: 'Review outline',
|
|
64
|
+
input: {
|
|
65
|
+
message: ({ ref, paths }) => [
|
|
66
|
+
'Review this outline for a new Tela user.',
|
|
67
|
+
`Bullets: ${ref(outline, paths(outline).bullets).formats().format}`,
|
|
68
|
+
].join('\n'),
|
|
69
|
+
inputs: {},
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
export default build(workflow('first-workflow'), {
|
|
74
|
+
inputs: [topic],
|
|
75
|
+
nodes: [outline, review],
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Rules to keep in mind:
|
|
80
|
+
|
|
81
|
+
- Declarations are inert. They do not create remote workflows, publish versions, or run handlers.
|
|
82
|
+
- `nodes` order is execution order. Adjacent nodes compile to default Workflow V3 edges.
|
|
83
|
+
- `key` is optional on inputs and nodes. Use it when display `name` may change but identity should stay stable.
|
|
84
|
+
- References in node inputs may target workflow inputs or earlier nodes. Forward references are compile diagnostics.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### `remote()`
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { agent, build, canvas, input, remote, workflow } from '@meistrari/workflow-code'
|
|
91
|
+
|
|
92
|
+
const document = input.file({ name: 'document', required: true })
|
|
93
|
+
const extractInvoice = remote().canvas().Finance['Extract Invoice']
|
|
94
|
+
const triage = remote().agent().byId('published-agent-id')
|
|
95
|
+
|
|
96
|
+
const extract = canvas(extractInvoice, {
|
|
97
|
+
name: 'Extract invoice',
|
|
98
|
+
input: {
|
|
99
|
+
variables: ({ ref }) => ({ file: ref(document) }),
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const classify = agent(triage, {
|
|
104
|
+
name: 'Triage extraction',
|
|
105
|
+
input: {
|
|
106
|
+
message: ({ ref }) => `Classify ${ref(extract).formats().parser}`,
|
|
107
|
+
inputs: ({ ref }) => ({ document: ref(document) }),
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
export default build(workflow('remote-catalog-example'), {
|
|
112
|
+
inputs: [document],
|
|
113
|
+
nodes: [extract, classify],
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Run `tela workflow codegen` before typechecking to generate named paths. User workflow source still imports only from `@meistrari/workflow-code`; generated catalog declarations augment those public types and should not be imported from workflow files.
|
|
118
|
+
|
|
119
|
+
`remote()` values are inert path refs, not API calls or runtime resource objects. `remote().canvas()`, `.workflow()`, `.agent()`, and `.models()` expose generated namespaces. Use bracket access for names with spaces, punctuation, reserved words, or any other segment that is not a safe JavaScript identifier. `byId()` and model `raw()` are explicit escape hatches when a generated name is unavailable or an ID is clearer.
|
|
120
|
+
|
|
121
|
+
`compile` preserves remote refs symbolically and remains offline. `sync` refreshes the active catalog, validates and locks referenced resources, resolves the refs, then lowers them for remote mutation.
|
|
122
|
+
|
|
123
|
+
### References: `ref()`, `paths()`, and `formats()`
|
|
124
|
+
|
|
125
|
+
Workflow references connect node inputs to workflow inputs or earlier node outputs. Under the hood, Tela represents those links as URI references such as `input://customer_question` or `step://extract_invoice?path=total&format=...`. Workflow Code hides the URI string and exposes typed helpers instead.
|
|
126
|
+
|
|
127
|
+
The important rule is that reference compatibility is decided by the destination node input. A node input declares which value shapes it accepts and which reference formats make sense for those shapes. For example, a prompt input can accept text-oriented references, file-oriented references, object fields, numbers, or booleans, but each source may expose different formats. The helper types should guide you toward the formats that are valid for the specific input you are authoring.
|
|
128
|
+
|
|
129
|
+
| Helper | What it does |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `ref(input)` | References a workflow input. In prompt-like inputs it renders a reference token; in `code()` handlers it reads the runtime value. |
|
|
132
|
+
| `ref(node)` | References an earlier node output. Forward references to later nodes are compile diagnostics. |
|
|
133
|
+
| `paths(node).field` | Selects a typed field from a node output schema. Pass the selected path as the second argument to `ref()`. |
|
|
134
|
+
| `formats().format` | Chooses the destination-compatible representation for a prompt/reference token. Available formats depend on the destination input and referenced value shape. |
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const extractInvoice = llm({
|
|
138
|
+
name: 'Extract invoice data',
|
|
139
|
+
input: {
|
|
140
|
+
prompt: ({ ref }) => [
|
|
141
|
+
'Extract invoice data from this document.',
|
|
142
|
+
ref(invoicePdf).formats().format,
|
|
143
|
+
].join('\n'),
|
|
144
|
+
},
|
|
145
|
+
schema: {
|
|
146
|
+
vendor: { type: 'string' },
|
|
147
|
+
total: { type: 'number' },
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const reviewInvoice = llm({
|
|
152
|
+
name: 'Review invoice extraction',
|
|
153
|
+
input: {
|
|
154
|
+
prompt: ({ ref, paths }) => [
|
|
155
|
+
`Vendor: ${ref(extractInvoice, paths(extractInvoice).vendor).formats().format}`,
|
|
156
|
+
`Total: ${ref(extractInvoice, paths(extractInvoice).total).formats().format}`,
|
|
157
|
+
].join('\n'),
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const normalizeInvoice = code({
|
|
162
|
+
name: 'Normalize invoice',
|
|
163
|
+
handler: ({ ref, paths }) => {
|
|
164
|
+
const vendor = ref(extractInvoice, paths(extractInvoice).vendor)
|
|
165
|
+
const total = Number(ref(extractInvoice, paths(extractInvoice).total))
|
|
166
|
+
return { vendor: String(vendor).trim(), totalCents: Math.round(total * 100) }
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Reference rules:
|
|
172
|
+
|
|
173
|
+
- References in node inputs may target workflow inputs or earlier nodes.
|
|
174
|
+
- `paths()` only accepts node declarations, not inputs.
|
|
175
|
+
- Path tokens are branded; do not replace them with strings or arrays.
|
|
176
|
+
- A path token must come from the same node used in `ref()`, or authoring throws `ref path source must match ref target`.
|
|
177
|
+
- In prompt/reference inputs, call `formats()` on `ref(...)` when the input needs a specific representation.
|
|
178
|
+
- In code handlers, `ref(...)` returns runtime data directly, so `formats()` is not available.
|
|
179
|
+
|
|
180
|
+
### `workflow(workflowKey)`
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
function workflow(workflowKey: string): WorkflowHandle
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Creates the workflow handle passed to `build()`. The key is the stable source identity for review, config matching, and deterministic compiler output.
|
|
187
|
+
|
|
188
|
+
| Parameter | Type | Required | Description |
|
|
189
|
+
| --- | --- | --- | --- |
|
|
190
|
+
| `workflowKey` | `string` | Yes | Non-empty author-facing key such as `invoice-processing`. If `workflow-code.config.ts` sets `workflowKey`, compile reports a mismatch when values differ. |
|
|
191
|
+
|
|
192
|
+
| Returns | Description |
|
|
193
|
+
| --- | --- |
|
|
194
|
+
| `WorkflowHandle` | Frozen object with `kind: 'workflow'` and `workflowKey`. |
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
const invoiceWorkflow = workflow('invoice-processing')
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Use lowercase, stable, reviewable keys. Do not put project ids, prompt ids, secrets, or environment names in `workflowKey`.
|
|
201
|
+
|
|
202
|
+
### `build(workflowHandle, options)`
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
type BuildOptions = {
|
|
206
|
+
input?: readonly InputDeclaration[]
|
|
207
|
+
inputs?: readonly InputDeclaration[]
|
|
208
|
+
nodes: readonly NodeDeclaration[]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function build(workflow: WorkflowHandle, options: BuildOptions): WorkflowDeclaration
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Finalizes the workflow declaration. The compiled graph is derived from `inputs` and ordered `nodes`; authors should not hand-author raw Workflow V3 edge objects.
|
|
215
|
+
|
|
216
|
+
| Parameter | Type | Required | Description |
|
|
217
|
+
| --- | --- | --- | --- |
|
|
218
|
+
| `workflow` | `WorkflowHandle` | Yes | Handle returned by `workflow()`. |
|
|
219
|
+
| `options.input` | `readonly InputDeclaration[]` | No | Scaffold-friendly alias for `options.inputs`. |
|
|
220
|
+
| `options.inputs` | `readonly InputDeclaration[]` | No | Inputs available to prompts, code handlers, and runtime callers. Defaults to an empty array. |
|
|
221
|
+
| `options.nodes` | `readonly NodeDeclaration[]` | Yes | Ordered node sequence. MVP compile lowers adjacent nodes into default edges. |
|
|
222
|
+
|
|
223
|
+
| Returns | Description |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| `WorkflowDeclaration` | Frozen declaration expected as the workflow module default export. |
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
export default build(workflow('support-triage'), {
|
|
229
|
+
inputs: [message, attachment],
|
|
230
|
+
nodes: [classify, draftReply, normalizeResult],
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Author one `build()` default export per workflow entrypoint.
|
|
235
|
+
|
|
236
|
+
### `input.text(options)`
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
declare function text(options: BaseInputOptions): TextInputDeclaration
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Declares a text input. Text inputs are best for prompts, questions, small JSON snippets, URLs, or freeform user instructions.
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
| Option | Type | Required | Default | Description |
|
|
247
|
+
| --- | --- | --- | --- | --- |
|
|
248
|
+
| `name` | `string` | Yes | — | Human-readable input name. Also used as fallback identity when `key` is omitted. |
|
|
249
|
+
| `required` | `boolean` | No | `false` | Whether callers must supply the value. |
|
|
250
|
+
| `description` | `string` | No | — | Help text for UI and metadata. |
|
|
251
|
+
| `key` | `string` | No | `name` | Stable identity independent from display `name`. |
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
const customerQuestion = input.text({
|
|
255
|
+
name: 'customer question',
|
|
256
|
+
key: 'customer_question',
|
|
257
|
+
required: true,
|
|
258
|
+
description: 'Question or support request to answer.',
|
|
259
|
+
})
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### `input.file(options)`
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
declare function file(options: BaseInputOptions): FileInputDeclaration
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Declares a file input. Use it for uploaded documents, images, or PDFs passed to the workflow.
|
|
269
|
+
|
|
270
|
+
| Option | Type | Required | Default | Description |
|
|
271
|
+
| --- | --- | --- | --- | --- |
|
|
272
|
+
| `name` | `string` | Yes | — | Human-readable file input name. |
|
|
273
|
+
| `required` | `boolean` | No | `false` | Whether callers must supply the file. |
|
|
274
|
+
| `description` | `string` | No | — | UI/help text explaining supported file expectations. |
|
|
275
|
+
| `key` | `string` | No | `name` | Stable identity independent from display `name`. |
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
const invoicePdf = input.file({
|
|
279
|
+
name: 'invoice PDF',
|
|
280
|
+
key: 'invoice_pdf',
|
|
281
|
+
required: true,
|
|
282
|
+
description: 'PDF invoice to extract and review.',
|
|
283
|
+
})
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### `llm(options)`
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
type LlmOptions = {
|
|
290
|
+
name: string
|
|
291
|
+
key?: string
|
|
292
|
+
input: {
|
|
293
|
+
prompt: string | ((context: PromptFactoryContext) => string)
|
|
294
|
+
model?: string
|
|
295
|
+
temperature?: number
|
|
296
|
+
}
|
|
297
|
+
schema?: WorkflowCodeOutputSchema | null
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function llm(options: LlmOptions): LlmNodeDeclaration
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Declares a single LLM completion node. Use `llm()` for bounded transformations where one model call should produce the desired output.
|
|
304
|
+
|
|
305
|
+
| Option | Type | Required | Description |
|
|
306
|
+
| --- | --- | --- | --- |
|
|
307
|
+
| `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
|
|
308
|
+
| `key` | `string` | No | Stable identity when `name` may change. |
|
|
309
|
+
| `input.prompt` | `string \| (context) => string` | Yes | Prompt text. Callback form enables `ref()` and `paths()`. Must render to non-empty string. |
|
|
310
|
+
| `input.model` | `string` | No | Model id passed through to Workflow V3 completion input. |
|
|
311
|
+
| `input.temperature` | `number` | No | Model temperature passed through to Workflow V3 completion input. |
|
|
312
|
+
| `schema` | `WorkflowCodeOutputSchema \| null` | No | Structured output fields for the model response. Use field names mapped to JSON-schema-like field definitions; omit for default behavior or set `null` when intentionally no schema should be emitted. |
|
|
313
|
+
|
|
314
|
+
`schema` helps constrain the completion output and creates named fields that later nodes can reference with `paths()`. Keep fields small and explicit: use `type`, `description`, `enum`, `properties`, `items`, and `required` when useful.
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
const extractInvoice = llm({
|
|
318
|
+
name: 'Extract invoice data',
|
|
319
|
+
key: 'extract_invoice',
|
|
320
|
+
input: {
|
|
321
|
+
model: 'gpt-4.1-mini',
|
|
322
|
+
temperature: 0,
|
|
323
|
+
prompt: ({ ref }) => [
|
|
324
|
+
'Extract invoice data from this document.',
|
|
325
|
+
ref(invoicePdf).formats().format,
|
|
326
|
+
].join('\n'),
|
|
327
|
+
},
|
|
328
|
+
schema: {
|
|
329
|
+
vendor: { type: 'string', description: 'Supplier name.' },
|
|
330
|
+
total: { type: 'number', description: 'Invoice total.' },
|
|
331
|
+
lineItems: {
|
|
332
|
+
type: 'array',
|
|
333
|
+
items: {
|
|
334
|
+
type: 'object',
|
|
335
|
+
properties: {
|
|
336
|
+
description: { type: 'string' },
|
|
337
|
+
amount: { type: 'number' },
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### `canvas(remoteRef, options)`
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
type RemoteCanvasOptions<Ref extends WorkflowCodeRemoteExecutableRef, Environment extends RemoteEnvironment<Ref> | undefined = undefined> = {
|
|
349
|
+
name: string
|
|
350
|
+
key?: string
|
|
351
|
+
} & (Environment extends string
|
|
352
|
+
? { environment: Environment, input: { variables: RemoteReferenceRecordInput<RemoteInputObject<Ref, Environment>> } }
|
|
353
|
+
: RemoteDefaultOptions<Ref>)
|
|
354
|
+
|
|
355
|
+
function canvas<Ref extends WorkflowCodeRemoteExecutableRef, Environment extends RemoteEnvironment<Ref> | undefined = undefined>(
|
|
356
|
+
ref: Ref,
|
|
357
|
+
options: RemoteCanvasOptions<Ref, Environment>,
|
|
358
|
+
): CanvasNodeHandle<RemoteSelectedOutput<Ref, Environment>>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Declares an executable remote Canvas or Workflow node. The `remoteRef` must come from `remote().canvas()` or `remote().workflow()`. Generated metadata supplies known input variables, output fields, and environment choices when the catalog exposes them.
|
|
362
|
+
|
|
363
|
+
| Option | Type | Required | Description |
|
|
364
|
+
| --- | --- | --- | --- |
|
|
365
|
+
| `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
|
|
366
|
+
| `key` | `string` | No | Stable identity when `name` may change. |
|
|
367
|
+
| `environment` | Generated literal union | Catalog-dependent | Environment name narrowed by the generated ref, such as `'production' \| 'staging'`. A generated ref with multiple non-production targets requires `environment`; generated refs with production metadata, no target metadata, or one selectable target may omit it. |
|
|
368
|
+
| `input.variables` | `Record<string, unknown> \| (context) => Record<string, unknown>` | Yes | Variables passed to the remote executable. Callback form enables `ref()` and typed variable refs. |
|
|
369
|
+
|
|
370
|
+
Generated declarations narrow `environment` to catalog literal names and conditionally make it required; it is not an arbitrary `string` escape hatch. The signature above uses the named `RemoteCanvasOptions` shape because the exact requiredness depends on the generated ref's target metadata rather than on a universal optional or required overload. Use `byId()` only for explicit ID binding, then rely on `sync` for authenticated environment validation when generated metadata is unavailable or stale.
|
|
371
|
+
|
|
372
|
+
After sync resolution, this becomes the existing Workflow V3 Canvas action with `canvasId`, optional `environmentName`, and resolved `variables`. Compile keeps the ref symbolic until orchestration supplies the active catalog and locks.
|
|
373
|
+
|
|
374
|
+
### `splitter(options)`
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
type SplitterOptions = {
|
|
378
|
+
name: string
|
|
379
|
+
key?: string
|
|
380
|
+
input: {
|
|
381
|
+
file: WorkflowCodeExclusiveFileSource
|
|
382
|
+
chunkSize?: number
|
|
383
|
+
type?: 'pdf' | 'csv'
|
|
384
|
+
mode?: 'single-pages' | 'smart-files'
|
|
385
|
+
customPrompt?: string
|
|
386
|
+
customPromptMode?: 'always' | 'fallback'
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function splitter(options: SplitterOptions): SplitterNodeHandle
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Declares the Workflow V3 `document-splitter` action. Its `input.file` is an exclusive reference field: it accepts a compatible workflow file input or previous-node output, one `vault.ref()`, or an array of Vault refs. It does not accept arbitrary strings or text references.
|
|
394
|
+
|
|
395
|
+
| Option | Type | Required | Default | Description |
|
|
396
|
+
| --- | --- | --- | --- | --- |
|
|
397
|
+
| `name` | `string` | Yes | — | Display name and fallback node identity. |
|
|
398
|
+
| `key` | `string` | No | `name` | Stable identity when the display name may change. |
|
|
399
|
+
| `input.file` | `WorkflowCodeExclusiveFileSource` | Yes | — | File/File-array workflow reference, `vault.ref()`, or array of Vault refs. |
|
|
400
|
+
| `input.chunkSize` | `number` | No | `1` | Pages per PDF chunk or rows per CSV chunk. |
|
|
401
|
+
| `input.type` | `'pdf' \| 'csv'` | No | `'pdf'` | Splitter document type. |
|
|
402
|
+
| `input.mode` | `'single-pages' \| 'smart-files'` | No | `'single-pages'` | Fixed chunking or smart document-boundary detection. |
|
|
403
|
+
| `input.customPrompt` | `string` | No | — | Optional smart-files instruction, up to 2,000 characters. |
|
|
404
|
+
| `input.customPromptMode` | `'always' \| 'fallback'` | No | `'always'` | Whether the custom smart-files prompt is always used or only as fallback. |
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
const invoice = input.file({
|
|
408
|
+
name: 'invoice',
|
|
409
|
+
required: true,
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
const pages = splitter({
|
|
413
|
+
name: 'Split invoice',
|
|
414
|
+
input: {
|
|
415
|
+
file: ({ ref }) => ref(invoice),
|
|
416
|
+
chunkSize: 1,
|
|
417
|
+
type: 'pdf',
|
|
418
|
+
},
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
const splitFirstPageAgain = splitter({
|
|
422
|
+
name: 'Split first page again',
|
|
423
|
+
input: {
|
|
424
|
+
file: ({ ref, paths }) => ref(pages, paths(pages)[0].file),
|
|
425
|
+
},
|
|
426
|
+
})
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Structured `llm()` outputs and published Agent outputs from `agent(remoteRef, options)` are valid sources only when the selected output or path has a file-compatible schema. A file schema declares string-valued schemas for `name` and at least one locator property (`fileUrl`, `vaultReference`, or `base64`). Any other declared transport string field (`mimeType` or another locator) must also be string-valued. Arrays are compatible when their item schema is file-compatible. The `x-tela-kind: 'file'` marker is metadata only and does not bypass structural validation. Schema presence or matching property names alone is not sufficient: scalar, generic-object, missing, malformed, or otherwise incompatible paths produce `compiler.ref.incompatible`.
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
const generated = llm({
|
|
433
|
+
name: 'Generate document reference',
|
|
434
|
+
input: { prompt: 'Return the generated document reference.' },
|
|
435
|
+
schema: {
|
|
436
|
+
document: {
|
|
437
|
+
type: 'object',
|
|
438
|
+
properties: {
|
|
439
|
+
name: { type: 'string' },
|
|
440
|
+
fileUrl: { type: 'string' },
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
const generatedPages = splitter({
|
|
447
|
+
name: 'Split generated document',
|
|
448
|
+
input: {
|
|
449
|
+
file: ({ ref, paths }) => ref(generated, paths(generated).document),
|
|
450
|
+
},
|
|
451
|
+
})
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`code()` outputs can also feed `splitter.input.file`. Compile statically infers the original handler return without calling it. Transport-file objects, nested paths, file arrays, pass-through file refs, and `File`/`Blob` values are supported. Scalar, malformed, `any`, `unknown`, and mixed file/non-file returns produce `compiler.ref.incompatible`.
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
const generatedByCode = code({
|
|
458
|
+
name: 'Generate document in code',
|
|
459
|
+
handler: () => new File(['document contents'], 'generated.pdf', {
|
|
460
|
+
type: 'application/pdf',
|
|
461
|
+
}),
|
|
462
|
+
})
|
|
463
|
+
|
|
464
|
+
const generatedCodePages = splitter({
|
|
465
|
+
name: 'Split code document',
|
|
466
|
+
input: {
|
|
467
|
+
file: ({ ref }) => ref(generatedByCode),
|
|
468
|
+
},
|
|
469
|
+
})
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
The referenced runtime value still needs to describe a real file. Declaring `fileUrl` or `vaultReference` in an LLM schema does not upload or create a Vault file.
|
|
473
|
+
|
|
474
|
+
### `vault.ref(reference)`
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
const vault: {
|
|
478
|
+
ref: <Reference extends `vault://${string}`>(
|
|
479
|
+
reference: Reference,
|
|
480
|
+
) => WorkflowCodeVaultRef<Reference>
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Creates an inert declaration for a file that already exists in Vault. The reference must contain a UUID v4 or SHA-256 file id. Calling `vault.ref()` does not read credentials, contact Vault, download the file, or mutate local state during source evaluation.
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
const existingInvoice = vault.ref(
|
|
488
|
+
'vault://550e8400-e29b-41d4-a716-446655440000',
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
const existingPages = splitter({
|
|
492
|
+
name: 'Split existing invoice',
|
|
493
|
+
input: { file: existingInvoice },
|
|
494
|
+
})
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
During compile, a direct Vault ref used by `splitter.input.file` lowers to a transport-file object containing both `fileUrl` and `vaultReference`. Compile remains offline. Before remote workflow mutation, sync and publish validate access to every compiled Vault ref in the active Tela context.
|
|
498
|
+
|
|
499
|
+
### `agent(remoteRef, options)`
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
function agent<Ref extends WorkflowCodeRemoteAgentRef>(
|
|
503
|
+
ref: Ref,
|
|
504
|
+
options: {
|
|
505
|
+
name: string
|
|
506
|
+
key?: string
|
|
507
|
+
input: {
|
|
508
|
+
message: string | ((context: PromptFactoryContext) => string)
|
|
509
|
+
inputs: Record<string, unknown> | ((context: PromptFactoryContext) => Record<string, unknown>)
|
|
510
|
+
environmentVariables?: Record<string, string>
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
): AgentNodeHandle<RemoteAgentOutput<Ref>>
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Declares a published Agent invocation. The `remoteRef` must come from `remote().agent()`. Generated metadata supplies known required inputs and output types when the catalog contains an authoritative published-Agent contract.
|
|
517
|
+
|
|
518
|
+
`input.message` is prompt-like, may use `ref()` callbacks, and must render to a non-empty string. `input.inputs` supplies the published Agent's named inputs and may contain workflow input or prior-node refs. Optional `environmentVariables` remain authored strings; they are not resolved through catalog metadata.
|
|
519
|
+
|
|
520
|
+
Lowering targets the existing Workflow V3 `agent-fcc` action fields `agentId`, `message`, `inputs`, and optional `environmentVariables` only. It does not emit output schema, revision, or catalog-hash fields in the node input.
|
|
521
|
+
|
|
522
|
+
### `code(options)`
|
|
523
|
+
|
|
524
|
+
```ts
|
|
525
|
+
type CodeOptions<Handler extends CodeHandler = CodeHandler> = {
|
|
526
|
+
name: string
|
|
527
|
+
key?: string
|
|
528
|
+
handler: Handler
|
|
529
|
+
libraries?: readonly string[]
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
type CodeHandler<Output = unknown> = (
|
|
533
|
+
context: CodeHandlerContext,
|
|
534
|
+
) => Output | Promise<Output>
|
|
535
|
+
|
|
536
|
+
function code<Handler extends CodeHandler>(
|
|
537
|
+
options: CodeOptions<Handler>,
|
|
538
|
+
): CodeNodeHandle<Awaited<ReturnType<Handler>>>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
Declares a typed code-execution node. `compile` evaluates trusted declaration modules but does not call the handler. Instead, the compiler extracts supported handler source, rewrites Workflow Code `ref()` reads to runtime input access, computes library metadata, and emits sandbox code for Workflow V3 execution. The handler return type becomes the `CodeNodeHandle` output type, so downstream `paths(codeNode).field` references can autocomplete against that shape.
|
|
542
|
+
|
|
543
|
+
| Option | Type | Required | Description |
|
|
544
|
+
| --- | --- | --- | --- |
|
|
545
|
+
| `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
|
|
546
|
+
| `key` | `string` | No | Stable identity when `name` may change. |
|
|
547
|
+
| `handler` | `CodeHandler` | Yes | Runtime function. Receives `ref()` and `paths()` helpers for workflow inputs and prior nodes. |
|
|
548
|
+
| `libraries` | `readonly string[]` | No | Explicit sandbox package specs such as `zod@4.3.6`. User specs win over inferred package versions. |
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
const normalizeInvoice = code({
|
|
552
|
+
name: 'Normalize invoice',
|
|
553
|
+
key: 'normalize_invoice',
|
|
554
|
+
libraries: ['zod@4.3.6'],
|
|
555
|
+
handler: ({ ref, paths }) => {
|
|
556
|
+
const vendor = ref(extractInvoice, paths(extractInvoice).vendor)
|
|
557
|
+
const total = Number(ref(extractInvoice, paths(extractInvoice).total))
|
|
558
|
+
|
|
559
|
+
return {
|
|
560
|
+
vendor: String(vendor).trim(),
|
|
561
|
+
totalCents: Math.round(total * 100),
|
|
562
|
+
needsHumanReview: total > 10_000,
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
})
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Supported extraction patterns:
|
|
569
|
+
|
|
570
|
+
- Inline handlers or named top-level handler functions.
|
|
571
|
+
- Source-visible same-file helpers, constants, types, and classes.
|
|
572
|
+
- Supported local TypeScript imports that can be copied into the source bundle.
|
|
573
|
+
- Package imports preserved in generated source with versions resolved from lockfile/package metadata or `libraries`.
|
|
574
|
+
|
|
575
|
+
Avoid these patterns:
|
|
576
|
+
|
|
577
|
+
- Dynamic import specifiers.
|
|
578
|
+
- Runtime-created closure values that cannot be statically traced.
|
|
579
|
+
- Unsupported local imports or unresolved exports.
|
|
580
|
+
- Forward references to later nodes.
|
|
581
|
+
- Declaring generated-reserved names such as `execute` or `TelaInput` in extracted handler/helper/type code.
|
|
582
|
+
|
|
583
|
+
### Config and shared types
|
|
584
|
+
|
|
585
|
+
These types are exported for config files and integrations. See [Config](/docs/config) for full examples.
|
|
586
|
+
|
|
587
|
+
| Type | Shape | Purpose |
|
|
588
|
+
| --- | --- | --- |
|
|
589
|
+
| `WorkflowCodeConfig` | `{ version: 1; tsconfig?: string; outDir?: string; workflows: Record<string, WorkflowTarget> }` | Top-level `workflow-code.config.ts` default export shape. |
|
|
590
|
+
| `WorkflowTarget` | `{ entry: string; contexts?: Record<string, WorkflowContextBinding>; projectId?: string; export?: 'default'; promptId?: string; workflowKey?: string; title?: string }` | Per-target entrypoint and remote binding metadata. |
|
|
591
|
+
| `WorkflowContextBinding` | `{ projectId?: string; promptId?: string }` | Context-specific project/prompt ids selected by Tela Dock/CLI context. Required only by remote lifecycle commands such as `sync`. |
|
|
592
|
+
| `Diagnostic` | `{ code: string; severity: 'error' \| 'warning' \| 'info'; message: string; hint?: string; location?: { file: string; line?: number; column?: number; offset?: number; endOffset?: number }; stack?: string }` | Compiler and loader diagnostic payload. |
|
|
593
|
+
|
|
594
|
+
### Diagnostics checklist
|
|
595
|
+
|
|
596
|
+
When authoring fails, check these first:
|
|
597
|
+
|
|
598
|
+
- Empty `workflowKey`, input `name`, node `name`, or prompt output.
|
|
599
|
+
- Missing default export from the workflow entrypoint.
|
|
600
|
+
- `workflowKey` mismatch between source and config.
|
|
601
|
+
- `ref()` to a node that appears later in `nodes`.
|
|
602
|
+
- `paths()` token from one node passed to `ref()` for another node.
|
|
603
|
+
- `code()` handler uses unsupported closures, dynamic imports, unresolved local imports, or generated-reserved names.
|
|
604
|
+
- Package import version cannot be resolved from lockfile, installed package, package.json, or `libraries` override.
|