@lunnoa/client 2.2.0 → 2.4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunnoa/client",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "TypeScript SDK for building applications on top of Lunnoa Automate — typed client for the Public API (agents, workflows, executions, entities, knowledge, queues), SSE agent chat streaming, and deployment-specific codegen",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -222,7 +222,8 @@ await lunnoa.tables.upsertBySlug({
222
222
  - A workflow's manual-trigger input fields live on
223
223
  `workflows.get(id, { expansion: ['triggerNode'] })` →
224
224
  `triggerNode.value.customInputConfig` (each field: `id`, `label`,
225
- `inputType`, `required`, `selectOptions`).
225
+ `inputType`, `required`, `selectOptions`). Declare them at deploy time
226
+ with `defineTrigger({ id: 'flow-control_trigger_manual', inputs })`.
226
227
  - `workflowApps.list()` resolves `executionPath` step `appId`/`actionId`
227
228
  pairs to human-readable names and icons.
228
229
 
@@ -351,11 +352,14 @@ Pure typed config (no network):
351
352
  import {
352
353
  defineAction,
353
354
  defineAgent,
355
+ defineTrigger,
354
356
  defineWorkflow,
357
+ ref,
355
358
  } from '@lunnoa/client';
356
359
 
357
360
  export const ping = defineWorkflow({
358
361
  slug: 'ping',
362
+ // Omit trigger for Manually Run with no input fields.
359
363
  steps: [
360
364
  {
361
365
  use: defineAction({
@@ -366,6 +370,37 @@ export const ping = defineWorkflow({
366
370
  ],
367
371
  });
368
372
 
373
+ export const syncOrders = defineWorkflow({
374
+ slug: 'sync-orders',
375
+ trigger: defineTrigger({
376
+ id: 'flow-control_trigger_manual',
377
+ inputs: [
378
+ { id: 'invoiceId', label: 'Invoice', inputType: 'text', required: true },
379
+ ],
380
+ }),
381
+ steps: [
382
+ {
383
+ key: 'order',
384
+ use: defineAction({
385
+ id: 'http_action_send-request',
386
+ input: {
387
+ method: 'GET',
388
+ url: `https://example.com/orders/${ref.trigger('invoiceId')}`,
389
+ },
390
+ }),
391
+ },
392
+ {
393
+ use: defineAction({
394
+ id: 'http_action_send-request',
395
+ input: {
396
+ method: 'GET',
397
+ url: `https://example.com/status/${ref.step('order', 'response', 'status')}`,
398
+ },
399
+ }),
400
+ },
401
+ ],
402
+ });
403
+
369
404
  export const triage = defineAgent({
370
405
  slug: 'support-triage',
371
406
  // models[].id from `npx @lunnoa/client ai-connections list --json`
@@ -375,25 +410,66 @@ export const triage = defineAgent({
375
410
  });
376
411
  ```
377
412
 
378
- Ad-hoc multi-step run (one Execution, `source: SDK`):
413
+ Ad-hoc multi-step run (one Execution, `source: SDK`). `runs.start` sends
414
+ steps only. A `trigger` on the definition is ignored. Deploy to persist it.
379
415
 
380
416
  ```typescript
381
417
  const result = await lunnoa.runs.start(ping);
382
418
  // or lunnoa.runs.startAndWait(ping)
383
419
  ```
384
420
 
421
+ One catalogue trigger per deployed workflow:
422
+
423
+ - **Manually Run** (`flow-control_trigger_manual`): `inputs` is the caller
424
+ form. It is stored as `customInputConfig`. `workflows.execute(id, { invoiceId })`
425
+ passes those keys.
426
+ - **Listen for Webhook** (`flow-control_trigger_listen-for-webhook`):
427
+ `input: { method: 'POST' }` (`PUT` or `GET` too).
428
+ - **Recurring Schedule** (`flow-control_trigger_recurring-schedule`): `input`
429
+ from the catalogue (`start`, `rrule`). A schedule that cannot compute its
430
+ next run fails the deploy.
431
+ - **Any other trigger:** `id` from `apps get`, optional `connection`, and
432
+ `input` copied from that trigger's `inputConfig`. Do not invent ids.
433
+
434
+ ### Passing data between steps
435
+
436
+ Wire step settings in code with `ref`. Do not leave them for the builder.
437
+
438
+ - `ref.trigger('caseId')`: a trigger output field. On Manually Run that is
439
+ one of the `inputs` ids. On a webhook it is the request shape
440
+ (`ref.trigger('body', 'caseId')`).
441
+ - `ref.step('load', 'rows', 0, 'status')`: an earlier step's output. Give
442
+ that step a `key: 'load'`. Array indexes are numbers.
443
+ - A `ref` is a plain string. Use it as a whole value, inside a template
444
+ string, or inside nested settings (`args: { case_id: ref.trigger('caseId') }`).
445
+ - On deploy the server swaps each `ref` for the real node id. The builder
446
+ shows it as a mapped field from that earlier node (top-level text fields
447
+ and lists; nested settings show the reference text). `runs.start` resolves
448
+ `ref.step` too, but it has no trigger, so `ref.trigger` fails there.
449
+ - `defineWorkflow` throws, and deploy returns 400, for an unknown key, a
450
+ reference to the same or a later step, a duplicate key, or a Manually Run
451
+ field missing from `inputs`.
452
+ - To find a step's output path, run it once (`actions.run` or
453
+ `runs.startAndWait`) and read that step's output in the execution.
454
+ - Give every step another step reads from a `key`. Keyed steps keep their
455
+ node id across deploys, so run history and builder mappings stay attached.
456
+ The trigger keeps its id while its type and settings stay the same.
457
+
385
458
  Discover the catalogue **before** writing `defineAction` (do not guess ids):
386
459
 
387
460
  ```bash
388
461
  npx @lunnoa/client tools list --json --for-agent
389
462
  npx @lunnoa/client tools search email --json --for-agent
390
463
  npx @lunnoa/client tools get http_action_send-request --json
464
+ npx @lunnoa/client apps get flow-control --json
391
465
  npx @lunnoa/client connections list --app gmail --json
392
466
  npx @lunnoa/client ai-connections list --json
393
467
  ```
394
468
 
395
469
  `tools get` returns `inputConfig` / `inputFields` and a `defineAction` sketch.
396
- `tools list` is compact; use `get` for the schema. `--json` is for coding agents.
470
+ `tools list` is compact; use `get` for the schema. `apps get --json` returns
471
+ `triggers[]` with `triggerId`, `inputFields`, and a `defineTrigger` sketch.
472
+ `--json` is for coding agents. Do not invent trigger ids.
397
473
 
398
474
  `ai-connections list` returns the AI connections this key can assign to an
399
475
  agent. Set `defineAgent({ model })` to a `models[].id` from that JSON
@@ -554,7 +630,7 @@ with emails (capped; not Azure object IDs).
554
630
  3. Call `discovery.enabledFeatures()` and hide unsupported areas.
555
631
  4. Build forms/tables from `attributeSchema` / `customInputConfig` (or the generated types).
556
632
  5. Render workflow progress from `executionPath`; handle `NEEDS_INPUT` with `submitInput`.
557
- 6. For single-action calls, use `actions.run`; for linear multi-step, use `runs.start` / `defineWorkflow`. Deploy with `npx @lunnoa/client workflows|agents deploy`. Discover catalogue via `npx @lunnoa/client tools list|get|search` (or `workflowApps.list()`). Discover agent models via `npx @lunnoa/client ai-connections list --json` (or `aiConnections.list()`).
633
+ 6. For single-action calls, use `actions.run`; for linear multi-step, use `runs.start` / `defineWorkflow`. Deploy with `npx @lunnoa/client workflows|agents deploy`. Discover actions via `npx @lunnoa/client tools list|get|search` (or `workflowApps.list()`). Discover triggers via `apps get <appId> --json` and pass `defineTrigger` on `defineWorkflow` (omit it for Manually Run with no fields). `runs.start` does not save the trigger. Pass trigger inputs and earlier step outputs into step settings with `ref.trigger` / `ref.step` (key the source step). Discover agent models via `npx @lunnoa/client ai-connections list --json` (or `aiConnections.list()`).
558
634
  7. For Request Approval nodes, use `approvals.inbox` / `approvals.decide` (or `executions.submitApproval`).
559
635
  8. Chat: stream via SSE, handle resume (reconnects) and stop, load history from the task.
560
636
  9. Handle `LunnoaApiError`: 401 → re-auth; 403 → hide the capability; 429 → back off.
@@ -85,7 +85,8 @@ interrogation.
85
85
  |---|---|---|
86
86
  | One catalogue call | `actions.run` | One-step Execution (`source: SDK`) |
87
87
  | Linear multi-step, experiment | `runs.start` / `defineWorkflow` then run | One Execution; optional later deploy |
88
- | Reusable automation + triggers | Saved **Workflow** (UI or CLI deploy) | Schedules/webhooks live on workflows |
88
+ | Reusable automation + triggers | Saved **Workflow** (`defineWorkflow` + `defineTrigger`, or the UI) | Discover trigger ids with `apps get <appId> --json`. Omit `trigger` for Manually Run with no fields. `runs.start` ignores the trigger. Wire step settings to trigger fields and earlier steps with `ref.trigger` / `ref.step`. |
89
+ | Branches (approve / reject, if/else) | Builder in Lunnoa | Code deploys build straight lines only. A later code deploy replaces builder edits. |
89
90
  | Reasoning + tools + conversation | **Agent** | Tools = workflows, actions, knowledge |
90
91
  | Structured CRUD / portals | **Entities** + schemas | Codegen for typed accessors |
91
92
  | Reference / lookup data | **Tables** | `tables.upsertBySlug`; workflows use the Tables Lookup action |
@@ -115,14 +116,21 @@ interrogation.
115
116
  3. **Connections stay on Lunnoa.** Definitions only reference connection ids
116
117
  (or omit for sole/default resolution). Never ask the partner to put OAuth
117
118
  secrets in their app.
118
- 4. **Do not invent catalogue actions or model ids.** Discover actions with
119
+ 4. **Do not invent catalogue action, trigger, or model ids.** Discover actions with
119
120
  `npx @lunnoa/client tools list|get|search --json` (or `workflowApps.list()`
120
- / codegen). Discover models with
121
+ / codegen). Discover triggers with `npx @lunnoa/client apps get <appId> --json`
122
+ and use `triggers[].triggerId` in `defineTrigger`. `input` is that trigger's
123
+ catalogue config. On Manually Run, `inputs` is the caller form
124
+ (`customInputConfig`). Discover models with
121
125
  `npx @lunnoa/client ai-connections list --json` and use a returned
122
126
  `models[].id` (Lunnoa LLMs uses catalogue ids such as
123
127
  `deepseek-ai/DeepSeek-V4-Pro`). Client `defineAction` binds existing
124
128
  catalogue actions; toolkit `createAction` is a different product
125
129
  (in-platform apps).
130
+ 4b. **Every step input has a source.** In the brief, list each step's settings
131
+ as a fixed value, "from trigger `caseId`", or "from step `load` →
132
+ `rows.0.status`". The build uses `ref.trigger` / `ref.step` for these, so
133
+ "connect it in the builder" is not a fallback for data wiring.
126
134
  5. **Durable vs ephemeral:** experiments → `runs.start`; shared production
127
135
  automation → CLI `workflows deploy` / `agents deploy` by slug.
128
136
  6. **UI is headless.** `@lunnoa/client` has no design system. Optional React
@@ -142,6 +150,8 @@ interrogation.
142
150
  - Using `@lunnoa/toolkit` to build a customer portal
143
151
  - Designing a local LangChain loop instead of Lunnoa-hosted agents
144
152
  - Hardcoding `model: 'gpt-4o'` without reading `ai-connections list`
153
+ - Inventing a trigger id, or expecting `runs.start` to save a webhook or schedule
154
+ - Leaving step inputs as "map it in the builder" when `ref.trigger` / `ref.step` covers it
145
155
 
146
156
  ---
147
157
 
@@ -162,6 +172,7 @@ can execute. Use this shape:
162
172
 
163
173
  ### Discovery (run first)
164
174
  - [ ] `npx @lunnoa/client tools list --json --for-agent` then `tools get <id>`
175
+ - [ ] `npx @lunnoa/client apps get <appId> --json` before `defineTrigger`
165
176
  - [ ] `npx @lunnoa/client ai-connections list --json` before choosing an agent model
166
177
  - [ ] agents / workflows / entity-types / tables list — reuse before create
167
178
  - [ ] codegen — if building typed entity/workflow accessors
@@ -169,7 +180,7 @@ can execute. Use this shape:
169
180
  ### Resources (every row says REUSED or CREATED)
170
181
  | Kind | Slug / id | Reused / created | Notes |
171
182
  |---|---|---|---|
172
- | Workflow | … | … | steps / trigger |
183
+ | Workflow | … | … | steps (with keys) / trigger / each input's source |
173
184
  | Agent | … | … | model, tools |
174
185
  | Entity type | … | … | if portal CRUD |
175
186
  | Table | … | … | reference / lookup data |