lua-cli 3.49.1 โ 3.50.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/dist/api-exports.d.ts +180 -22
- package/dist/api-exports.js +375 -27
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +486 -66
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.js +220 -20
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +2 -1
- package/docs/README.md +3 -3
- package/docs/api/Agents.md +51 -9
- package/docs/api/Data.md +51 -0
- package/docs/api/Decisions.md +49 -13
- package/docs/api/LuaDecision.md +2 -2
- package/docs/api/Workflows.md +1 -0
- package/docs/workflows/schedules.md +1 -1
- package/package.json +3 -3
- package/template/package.json +1 -1
package/docs/CLI_REFERENCE.md
CHANGED
|
@@ -619,7 +619,8 @@ lua decisions [command] [name] [version] [options]
|
|
|
619
619
|
- `--force` - Skip the confirmation (`publish`, `delete`)
|
|
620
620
|
- `--state <json>` - `run`: the state to decide on
|
|
621
621
|
- `--message <text>` - `run`: sent as `{ message: <text> }`; an empty or blank message is a usage error (exit 2)
|
|
622
|
-
- `--provider <jev|openai|auto>` - `run`: override the version's provider
|
|
622
|
+
- `--provider <jev|openai|openrouter|auto>` - `run`: override the version's provider
|
|
623
|
+
- `--model <id>` - `run`: override the version's model; an OpenRouter id such as `liquid/d1` runs on OpenRouter (see [Decisions](api/Decisions.md#other-decision-models-through-openrouter))
|
|
623
624
|
- `--min-confidence <n>` - `run`: override the version's `minConfidence` (0 to 1)
|
|
624
625
|
|
|
625
626
|
**Example:**
|
package/docs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# lua-cli v3.
|
|
1
|
+
# lua-cli v3.50.0
|
|
2
2
|
|
|
3
|
-
Welcome to the comprehensive API documentation for lua-cli v3.
|
|
3
|
+
Welcome to the comprehensive API documentation for lua-cli v3.50.0. This guide covers every API, class, and function exported by the package.
|
|
4
4
|
|
|
5
5
|
## ๐ Documentation Index
|
|
6
6
|
|
|
@@ -263,7 +263,7 @@ Each API doc includes:
|
|
|
263
263
|
|
|
264
264
|
---
|
|
265
265
|
|
|
266
|
-
**Version:** 3.
|
|
266
|
+
**Version:** 3.50.0
|
|
267
267
|
**Last Updated:** October 2026
|
|
268
268
|
|
|
269
269
|
---
|
package/docs/api/Agents.md
CHANGED
|
@@ -38,13 +38,13 @@ Supervision lets one agent observe, preview or release another agent in the same
|
|
|
38
38
|
|
|
39
39
|
**Nothing in code can grant it.** An org admin creates a grant for each supervisor and target pair, with one or more actions:
|
|
40
40
|
|
|
41
|
-
| Action | Allows
|
|
42
|
-
| ----------------- |
|
|
43
|
-
| `observe` | `logs` (without message bodies), `runs`, `data` (only the collections named on the grant), `versions.list/get/diff`, `persona.versions`, `source`, `env.keys`, `workflows.get`, `deployed`
|
|
44
|
-
| `observe-content` | Log message bodies in `logs`
|
|
45
|
-
| `preview` | `versions.preview`: chat a staged version
|
|
46
|
-
| `release` | `versions.promote`, `persona.activate`, `versions.delete` (a `superseded` version
|
|
47
|
-
| `act` | The target sees `invokedBy.supervisor === true` when the supervisor invokes it
|
|
41
|
+
| Action | Allows |
|
|
42
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `observe` | `logs` (without message bodies), `runs`, `data` (only the collections named on the grant), `versions.list/get/diff`, `persona.versions`, `source`, `env.keys`, `workflows.get`, `deployed` |
|
|
44
|
+
| `observe-content` | Log message bodies in `logs` |
|
|
45
|
+
| `preview` | `versions.preview`: chat a staged version |
|
|
46
|
+
| `release` | `versions.promote`, `persona.activate`, `versions.delete` (a `superseded` version, or a stale `staged` one: never active, over 24 hours old, and not the newest staged version), `workflows.create` (an inert, inactive workflow with no human author, so it cannot carry a schedule), `workflows.push` (a new, never-activated version of an existing workflow) and `workflows.deploy`. Promote, activate and deploy always need `expectActive`. Every release op runs only from a live workflow step of the supervisor whose workflow the grant names (`releaseWorkflowIds`). |
|
|
47
|
+
| `act` | The target sees `invokedBy.supervisor === true` when the supervisor invokes it |
|
|
48
48
|
|
|
49
49
|
**Discovery.** `Agents.list()` and `Agents.get(id)` return your own organization's agents, and only to an agent that holds at least one supervision grant there. Otherwise `list()` returns `[]`.
|
|
50
50
|
|
|
@@ -61,6 +61,9 @@ const keys = await Agents.env('base_agent-tp').keys(); // names only, never valu
|
|
|
61
61
|
const live = await Agents.deployed('base_agent-tp');
|
|
62
62
|
|
|
63
63
|
const versions = await Agents.versions('base_agent-tp').list();
|
|
64
|
+
// Page past the newest 50, or filter by status (one or a list): newest first.
|
|
65
|
+
const staged = await Agents.versions('base_agent-tp').list({ status: 'staged', limit: 50 });
|
|
66
|
+
const older = await Agents.versions('base_agent-tp').list({ status: ['staged', 'superseded'], limit: 50, offset: 50 });
|
|
64
67
|
const diff = await Agents.versions('base_agent-tp').diff(7, 8);
|
|
65
68
|
const preview = await Agents.versions('base_agent-tp').preview(8, 'What can you do?'); // no tools unless allowlisted
|
|
66
69
|
|
|
@@ -77,13 +80,14 @@ await Agents.workflows('base_agent-tp').push('wf_123', definition); // the body
|
|
|
77
80
|
await Agents.workflows('base_agent-tp').deploy('wf_123', '1.4.0', { expectActive: wf.activeVersionId });
|
|
78
81
|
// Optionally name the source commit the version was built from: deploy(wf, v, { expectActive, commitHash? })
|
|
79
82
|
|
|
80
|
-
// Clean up:
|
|
83
|
+
// Clean up: a superseded version, or a staged one that was never active, is over 24 hours old and is not the newest staged one.
|
|
81
84
|
await Agents.versions('base_agent-tp').delete(5);
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
> **Experimental.** `Agents.jobs(agentId).register({ versionId, jobId })` registers job `jobId`, defined in the staged version `versionId`, on the target. It is available in a deployed agent only once the platform serves `jobs.register`, and needs the `supervision:register-job` grant (given per supervisor and target by an org owner or admin, scoped to jobs defined in the staged `versionId`). Without it the call is refused with `supervision_not_granted`. Under `lua test` / `lua dev` it is always refused with `supervision_release_offline_refused`, with no network call. An empty `versionId` or `jobId` is refused with `supervision_bad_args`, and an empty agent id with `supervision_no_target`.
|
|
85
88
|
|
|
86
89
|
- A workflow deploy also records a new active agent version. Read `versions.list` again before a later `promote`.
|
|
90
|
+
- `versions.list` takes `limit` (1โ50, default 20), and optionally `status` (`active`, `staged`, `superseded`, `deleted`, or a list of them) and `offset` (0โ10000 rows to skip). A call with only `limit` answers as before. An invalid `status` or `offset` is refused with `supervision_bad_args`. A platform that predates `status` / `offset` ignores them, so check the rows' `status` and versions before relying on them.
|
|
87
91
|
- `commitHash` on `workflows.deploy` is optional and forwarded unchanged. A call without it behaves as before, and the platform may fill it from the Job workspace.
|
|
88
92
|
|
|
89
93
|
### Platform switches
|
|
@@ -132,7 +136,8 @@ Every error is a `SupervisionError` with a `code`:
|
|
|
132
136
|
- `supervision_self_refused`
|
|
133
137
|
- `supervision_release_binding_required` and `supervision_release_binding_refused`
|
|
134
138
|
- `supervision_expect_active_required`
|
|
135
|
-
- `supervision_version_not_superseded`, when `versions.delete` targets a version that is
|
|
139
|
+
- `supervision_version_not_superseded`, when `versions.delete` targets a version that is neither superseded nor staged (the active one, or a deleted one)
|
|
140
|
+
- `supervision_version_staged_was_active`, `supervision_version_staged_too_recent` and `supervision_version_staged_newest`, when `versions.delete` targets a staged version that has promotion history, is under 24 hours old, or is the newest staged version
|
|
136
141
|
- `WORKFLOW_DEPLOY_CONFLICT` and `PROMOTE_CONFLICT`, when `expectActive` is not the live version
|
|
137
142
|
- `supervision_data_not_granted`
|
|
138
143
|
- `supervision_audit_unavailable`
|
|
@@ -377,6 +382,43 @@ await Agents.secrets('base_agent-tp').attach([requestId]); // { agentId, attache
|
|
|
377
382
|
(`secret_attach_existing_disabled`); while it is off, `agentId` in a target is ignored as before. Not available
|
|
378
383
|
offline.
|
|
379
384
|
|
|
385
|
+
## Writing a secret row into an agent's Data
|
|
386
|
+
|
|
387
|
+
Hand a supervised agent a credential without it ever passing through a model prompt: from CODE (a workflow step or a
|
|
388
|
+
job), write it straight into the agent's own Data, then nudge the agent with the fingerprint only.
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// in a workflow code step or a job of the SUPERVISOR โ mint and write in the same step, return only the receipt
|
|
392
|
+
const token = await mintTokenFor('ticket-pilot'); // your own code; never a tool argument, never a prompt
|
|
393
|
+
const receipt = await Agents.secrets('base_agent-tp').put('pilot_linear_app_token', 'access', {
|
|
394
|
+
grant: 'brokered',
|
|
395
|
+
accessToken: token.accessToken,
|
|
396
|
+
expiresAt: token.expiresAtMs,
|
|
397
|
+
refreshToken: null,
|
|
398
|
+
});
|
|
399
|
+
// { ok: true, id: '<entry id>', fingerprint: 'sha256:<16 hex>' } โ never the value
|
|
400
|
+
return { fingerprint: receipt.fingerprint };
|
|
401
|
+
|
|
402
|
+
// the agent reads it with its own Data access:
|
|
403
|
+
// await Data.get('pilot_linear_app_token', { _pk: 'access' }) โ newest row first
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
- Writes the row of `collection` whose `_pk` is `key`, replacing its WHOLE `data` (no stale field survives), or creates
|
|
407
|
+
it. `value` is flat: string, finite number, boolean or null fields (at most 32; a string at most 8 KB; 16 KB in all);
|
|
408
|
+
`_pk` is set to `key`. No search text is set, so the value is never embedded.
|
|
409
|
+
- Needs `supervision:act` on the agent AND the collection in the grant's `secretWriteCollections` (written only by an org
|
|
410
|
+
admin; absent = no secret write anywhere). Otherwise `supervision_not_granted` / `supervision_secret_write_not_granted`;
|
|
411
|
+
a malformed call is `supervision_secret_bad_args` (the message names the field, never its value).
|
|
412
|
+
- The collection is write-only for you: `Agents.data(id).get/query` refuses it (`supervision_secret_collection_write_only`),
|
|
413
|
+
and the admin cannot also list it in `dataCollections`.
|
|
414
|
+
- The agent's logs get a `supervisor_access` row and an outcome row (`secret_written`: collection, entry id and
|
|
415
|
+
fingerprint), never the value. A refusal after the grant check gets a `denied` row with its code only.
|
|
416
|
+
- Fingerprint: `sha256:` + the first 16 hex of SHA-256 over the stored row as JSON with its keys sorted (`_pk`
|
|
417
|
+
included). If the agent caches the secret in memory, a token-free message carrying the fingerprint is how you tell it
|
|
418
|
+
to reload.
|
|
419
|
+
- Keep the value out of your step's RESULT and memory: mint and `put` inside one step and return the receipt only.
|
|
420
|
+
- Never on yourself, never by a watchdog grant, never inside a test session; not available offline.
|
|
421
|
+
|
|
380
422
|
## Events about failing tools
|
|
381
423
|
|
|
382
424
|
Subscribe to two more event kinds with `Agents.events(id).subscribe({ kinds, triggerName })`:
|
package/docs/api/Data.md
CHANGED
|
@@ -278,6 +278,57 @@ if (result.status === 'success') {
|
|
|
278
278
|
}
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
+
## Org-shared collections: `Data.shared(name)`
|
|
282
|
+
|
|
283
|
+
`Data` is private to the agent. To share reference data between agents of one organization (for example an
|
|
284
|
+
architecture map one agent maintains and every other agent reads), an org admin creates a **shared collection** and
|
|
285
|
+
names which agents may read it and which may write it. Agents never create or grant one themselves.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { Data } from 'lua-cli';
|
|
289
|
+
|
|
290
|
+
const map = Data.shared('fleet_map');
|
|
291
|
+
|
|
292
|
+
// A writer:
|
|
293
|
+
const card = await map.create('repos', { repo: 'lua-core-services', tier: 1 }, { searchText: 'backend monorepo' });
|
|
294
|
+
await map.patch('repos', card.id, { set: { tier: 2 } }, { ifVersion: card._version });
|
|
295
|
+
|
|
296
|
+
// Any reader (a writer can read too):
|
|
297
|
+
const { data } = await map.get('repos', { tier: 1 });
|
|
298
|
+
const edges = await map.search('edges', 'what calls lua-agents', 10);
|
|
299
|
+
const names = await map.collections();
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
- **Same surface as `Data`.** `Data.shared(name)` returns `collections`, `create`, `get`, `getEntry`, `update`,
|
|
303
|
+
`patch`, `increment`, `search` and `delete` with the same signatures, limits, filters, managed indexes,
|
|
304
|
+
compare-and-swap and vector search. The shared collection is a namespace: it can hold several collections
|
|
305
|
+
(`'repos'`, `'edges'`). An entry it returns writes back to the shared namespace (`entry.update()`, `entry.delete()`).
|
|
306
|
+
- **Access.** Readers may call `collections`, `get`, `getEntry` and `search`. Writers may also call `create`,
|
|
307
|
+
`update`, `patch`, `increment` and `delete`. Any other call rejects with `code === 'shared_data_forbidden'`
|
|
308
|
+
(status 403). The same answer is given when the name does not exist or belongs to another organization: an agent
|
|
309
|
+
can only ever reach its own organization's shared collections.
|
|
310
|
+
- **Audit.** Every write records the agent, the collection and the entry id (never the value) in the
|
|
311
|
+
organization's audit log.
|
|
312
|
+
- **Test sessions** may read a shared collection but not write it (`shared_data_test_session_write_refused`, 409).
|
|
313
|
+
- **Local runs** (`lua test`) have no org ACL to consult: every call rejects with
|
|
314
|
+
`code === 'shared_data_unavailable_offline'`.
|
|
315
|
+
- Do not store end-customer personal data in a shared collection: it is organization reference data, and the
|
|
316
|
+
per-agent end-customer erasure does not cover it.
|
|
317
|
+
|
|
318
|
+
### Managing shared collections (org admins)
|
|
319
|
+
|
|
320
|
+
Created and managed through the admin API (`members:manage` to list, `members:assign-role` to change). Every id in
|
|
321
|
+
`readers` / `writers` must be a live agent of the organization; explicit ids only, never `*`.
|
|
322
|
+
|
|
323
|
+
```http
|
|
324
|
+
GET /admin/orgs/:orgId/shared-collections
|
|
325
|
+
POST /admin/orgs/:orgId/shared-collections { "name": "fleet_map", "readers": ["agent_a"], "writers": ["agent_b"] }
|
|
326
|
+
PUT /admin/orgs/:orgId/shared-collections/:name { "readers": [...], "writers": [...] } (replaces both lists)
|
|
327
|
+
DELETE /admin/orgs/:orgId/shared-collections/:name (access ends at once; entries are purged; irreversible)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
A change applies to the next `Data.shared` call. Re-creating a deleted name starts an empty collection.
|
|
331
|
+
|
|
281
332
|
## DataEntryInstance
|
|
282
333
|
|
|
283
334
|
Data entries have convenient methods:
|
package/docs/api/Decisions.md
CHANGED
|
@@ -120,13 +120,13 @@ Question names and option labels are at most 64 characters. Any name works, incl
|
|
|
120
120
|
interface DecisionResult {
|
|
121
121
|
decisionId: string;
|
|
122
122
|
answers: { [questionName: string]: DecisionAnswer };
|
|
123
|
-
provider: 'jev' | 'openai';
|
|
123
|
+
provider: 'jev' | 'openai' | 'openrouter';
|
|
124
124
|
model: string;
|
|
125
125
|
rule: 'pinned' | 'images' | 'region' | 'zero_retention' | 'default' | 'fallback';
|
|
126
126
|
usage: { inputTokens: number | null };
|
|
127
127
|
durationMs: number;
|
|
128
128
|
cached: boolean;
|
|
129
|
-
fallback?: { from: 'jev' | 'openai'; reason: string };
|
|
129
|
+
fallback?: { from: 'jev' | 'openai' | 'openrouter'; reason: string };
|
|
130
130
|
}
|
|
131
131
|
```
|
|
132
132
|
|
|
@@ -254,20 +254,56 @@ Under `lua test` and through the HTTP API, `decision_timeout`, `decision_unavail
|
|
|
254
254
|
|
|
255
255
|
## Options
|
|
256
256
|
|
|
257
|
-
| Option | Values
|
|
258
|
-
| --------------- |
|
|
259
|
-
| `provider` | `'auto'`, `'jev'`, `'openai'`
|
|
260
|
-
| `model` | a model id of that provider
|
|
261
|
-
| `fallback` | `'jev'`, `'openai'`, `'none'`
|
|
262
|
-
| `region` | `'eu'`
|
|
263
|
-
| `zeroRetention` | `true`, `false`
|
|
264
|
-
| `minConfidence` | 0 to 1
|
|
265
|
-
| `timeoutMs` | 100 to 15000
|
|
266
|
-
| `cache` | `{ ttlSeconds }`
|
|
267
|
-
| `logState` | `'summary'`, `'full'`, `'none'`
|
|
257
|
+
| Option | Values | Default | Description |
|
|
258
|
+
| --------------- | --------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
259
|
+
| `provider` | `'auto'`, `'jev'`, `'openai'`, `'openrouter'` | `'auto'` | Which provider answers, where `auto` lets the platform pick between Jev and OpenAI. `openrouter` needs a `model`. |
|
|
260
|
+
| `model` | a model id of that provider | provider's | The exact model to use. `jev-*` runs on Jev, `gpt-*` on OpenAI, and a `vendor/model` id runs on OpenRouter (see below). |
|
|
261
|
+
| `fallback` | `'jev'`, `'openai'`, `'none'` | other one | The provider to try when the first one fails, or `none` to never fall back, and a pinned `provider` never falls back unless you set this. |
|
|
262
|
+
| `region` | `'eu'` | none | Routes the call to OpenAI's EU endpoint. |
|
|
263
|
+
| `zeroRetention` | `true`, `false` | `false` | Routes the call to OpenAI only, and no retention flag is sent with the request. |
|
|
264
|
+
| `minConfidence` | 0 to 1 | `0.7` | Below this confidence a choice or score answer carries `uncertain: true`. |
|
|
265
|
+
| `timeoutMs` | 100 to 15000 | `3000` | How long the whole call may take, fallback included, before it fails with a timeout, and a value outside the range is clamped to it. |
|
|
266
|
+
| `cache` | `{ ttlSeconds }` | none | Reuses the answer to an identical request for this many seconds. |
|
|
267
|
+
| `logState` | `'summary'`, `'full'`, `'none'` | `'summary'` | How much of the state is kept in the decision log. |
|
|
268
268
|
|
|
269
269
|
A pinned `provider` overrides the images, `region` and `zeroRetention` rules.
|
|
270
270
|
|
|
271
|
+
### Other decision models, through OpenRouter
|
|
272
|
+
|
|
273
|
+
Beyond Jev and OpenAI, you can run a decision on any of the models below by setting `model` to its id. These models are served through OpenRouter, so the result reports `provider: 'openrouter'`.
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const r = await Decisions.ask({
|
|
277
|
+
state: { message: input.text },
|
|
278
|
+
questions: { refund: Decisions.odds('Is the customer asking for a refund?') },
|
|
279
|
+
model: 'liquid/d1',
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Requests and answers have the same shape for every model, and the result's `model` names the exact model version that answered. `auto` never picks one of these models, and `fallback` cannot name one. A call on one of them falls back to Jev or OpenAI when you set `fallback`. Jev and OpenAI are not reached this way: `typesafe/...` and `openai/...` ids fail with `decision_invalid`, so use `provider: 'jev'` or `'openai'`. Any other `vendor/model` id is accepted locally and checked when the call is made: a misspelt or unknown id fails with `decision_rejected` and the message names it, so check `model` against the list below before you ship.
|
|
284
|
+
|
|
285
|
+
Available models, October 2026:
|
|
286
|
+
|
|
287
|
+
| Model id | Input | Context | Typical latency\* | Notes |
|
|
288
|
+
| --------------------------------------- | ------------ | ------- | ----------------- | ---------------------------------------------------------------------- |
|
|
289
|
+
| `perplexity/pplx-decider-v1.1-27b` | text, images | 262k | 240 ms | Recommended |
|
|
290
|
+
| `liquid/d1` | text | 65k | 270 ms | Recommended |
|
|
291
|
+
| `microsoft/microsoft-decision-1` | text | 32k | 280 ms | Recommended |
|
|
292
|
+
| `cloudflare/clef-flash` | text, images | 65k | 330 ms | Recommended |
|
|
293
|
+
| `inception/mercury-decide` | text | 65k | 340 ms | Recommended |
|
|
294
|
+
| `togethercomputer/tev1-4b-experimental` | text | 32k | 270 ms | Recommended. At most 20 options per question and 32 questions per call |
|
|
295
|
+
| `cloudflare/clef` | text, images | 65k | 360 ms | Recommended |
|
|
296
|
+
| `upstage/solar-decide-flash` | text | 524k | 1 s | At most 26 options per question |
|
|
297
|
+
| `upstage/solar-decide` | text | 524k | 1 to 7 s | At most 26 options per question. Often slower than the default timeout |
|
|
298
|
+
| `jaredpalmer/kev-4b` | text | 8k | 1.6 s | |
|
|
299
|
+
| `nace-ai/drex-v1.5` | text | 131k | 480 ms | |
|
|
300
|
+
|
|
301
|
+
\* Median response time in Lua's internal benchmarks, October 2026. Jev answers in about 230 ms on the same calls.
|
|
302
|
+
|
|
303
|
+
Not available, because they keep request data and Lua only runs decisions on models that do not: `openai/gpt-6-luna-decisions` (use `provider: 'openai'`), `cloudflare/clef-omni`, `respan/span-01`, `respan/span-01-lite`, `inception/mercury-decide:free`. A model's own limit, such as too many options, fails with `decision_rejected` and the model's message.
|
|
304
|
+
|
|
305
|
+
The Input column is what each vendor lists. Images are sent to every model, and a model listed as text-only may still read them or may ignore them, so pick a model that lists images when an answer depends on one.
|
|
306
|
+
|
|
271
307
|
## Related APIs
|
|
272
308
|
|
|
273
309
|
- [LuaDecision](./LuaDecision.md) declares a named, versioned decision that `Decisions.run` runs.
|
package/docs/api/LuaDecision.md
CHANGED
|
@@ -24,7 +24,7 @@ type LuaDecisionConfig = {
|
|
|
24
24
|
name: string;
|
|
25
25
|
description?: string;
|
|
26
26
|
questions: Record<string, OddsQuestion | ChoiceQuestion | ScoreQuestion>;
|
|
27
|
-
provider?: 'auto' | 'jev' | 'openai';
|
|
27
|
+
provider?: 'auto' | 'jev' | 'openai' | 'openrouter';
|
|
28
28
|
model?: string;
|
|
29
29
|
fallback?: 'jev' | 'openai' | 'none';
|
|
30
30
|
region?: 'eu';
|
|
@@ -99,7 +99,7 @@ Each lua-core pod caches the current version. A promote, a publish, a rename or
|
|
|
99
99
|
|
|
100
100
|
`lua decisions` lists the named decisions on the agent with their current version. `lua decisions versions triage` shows each version newest first, with its questions, provider and `minConfidence`.
|
|
101
101
|
|
|
102
|
-
`lua decisions run triage --message 'I want a refund'` runs the current version and prints one line per answer, then the provider, rule, model, duration, tokens and fallback. Pass `--state '<json>'` to decide on structured state instead, and `--provider` or `--min-confidence` to override the version's options for that run.
|
|
102
|
+
`lua decisions run triage --message 'I want a refund'` runs the current version and prints one line per answer, then the provider, rule, model, duration, tokens and fallback. Pass `--state '<json>'` to decide on structured state instead, and `--provider`, `--model` or `--min-confidence` to override the version's options for that run. `--model liquid/d1` runs it on that model; see the model list in [Decisions](Decisions.md#other-decision-models-through-openrouter).
|
|
103
103
|
|
|
104
104
|
The first push of a decision writes 1.0.1, as for every versioned primitive: a push bumps the version in `lua.skill.yaml` (1.0.0 for a new entry) before it writes.
|
|
105
105
|
|
package/docs/api/Workflows.md
CHANGED
|
@@ -28,6 +28,7 @@ Inside a sandbox (tools, jobs, webhooks, workflow code steps) `Workflows` is als
|
|
|
28
28
|
- Starts with **different** keys run in parallel (for example one release per agent).
|
|
29
29
|
- Starts with **no** `correlationKey` share one null bucket: a second keyless start is refused while a keyless run is in flight. A keyless start and a keyed start never block each other.
|
|
30
30
|
- Without `concurrencyKey` nothing changes: the guard stays workflow-wide.
|
|
31
|
+
- The key rides the push DTO and compiled manifest, not the graph body, so declaring it never changes the `graphHash`.
|
|
31
32
|
- `concurrencyKey` requires `concurrencyPolicy: 'forbid'`; otherwise `lua compile` / `lua push` fail with `concurrency-key-requires-forbid`, and a push that reaches the server is a 400 `VALIDATION_FAILED` (`concurrency-key-requires-forbid`). Any value other than `'correlationKey'` also fails the compile.
|
|
32
33
|
- The refusal is a 409 `RUNS_IN_FLIGHT` whose body carries `blockingRunId`, `blockingStatus`, `concurrencyKey` and the colliding `correlationKey` (absent for the null bucket).
|
|
33
34
|
- `lua workflows start` names the colliding `correlationKey` in its error line (and says so when the in-flight run is the keyless one); the body is unchanged under `--json`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
_Source of truth: workflows-spec 07 ยง7.1. This page is the developer summary; the spec is normative._
|
|
4
4
|
|
|
5
|
-
`schedule: { type:'cron', expression: '0 9 * * 1', timezone: 'Europe/London' }` on `createWorkflow` fires runs on the cron grid; `scheduleInput` is the run input. `concurrencyPolicy:'forbid'` skips a fire while a run is in flight (the skip is recorded, never queued). With `concurrencyKey:'correlationKey'` a fire is skipped only when a run with the same rendered `correlationKeyTemplate` key is in flight; a fire with no key shares one null bucket. Manage with `lua workflows activate` / `deactivate`, or create and drive a schedule from the CLI without a `schedule:` block โ `lua workflows schedules create|pause|resume|patch|delete` below; a re-enable with `--backfill-now` starts the missed occurrences (deduplicated on `backfill:<workflowId>:<occurrenceIso>`).
|
|
5
|
+
`schedule: { type:'cron', expression: '0 9 * * 1', timezone: 'Europe/London' }` on `createWorkflow` fires runs on the cron grid; `scheduleInput` is the run input. `concurrencyPolicy:'forbid'` skips a fire while a run is in flight (the skip is recorded, never queued). With `concurrencyKey:'correlationKey'` a fire is skipped only when a run with the same rendered `correlationKeyTemplate` key is in flight; a fire with no key shares one null bucket (see [Concurrency](../api/LuaWorkflow.md#concurrency)). Manage with `lua workflows activate` / `deactivate`, or create and drive a schedule from the CLI without a `schedule:` block โ `lua workflows schedules create|pause|resume|patch|delete` below; a re-enable with `--backfill-now` starts the missed occurrences (deduplicated on `backfill:<workflowId>:<occurrenceIso>`).
|
|
6
6
|
|
|
7
7
|
## Schedule health
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lua-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.50.0",
|
|
4
4
|
"description": "Build, test, and deploy AI agents with custom tools, webhooks, and scheduled jobs. Features LuaAgent unified configuration, streaming chat, and batch deployment.",
|
|
5
5
|
"readmeFilename": "README.md",
|
|
6
6
|
"main": "dist/api-exports.js",
|
|
@@ -114,11 +114,11 @@
|
|
|
114
114
|
"stripe": "^19.2.0",
|
|
115
115
|
"ts-node": "^10.9.2",
|
|
116
116
|
"tsup": "^8.5.1",
|
|
117
|
-
"@lua/sandbox-runtime": "0.0.1",
|
|
118
117
|
"@lua/shared-sandbox": "0.0.1",
|
|
119
118
|
"@lua/shared-source-sync": "0.0.1",
|
|
120
119
|
"@lua/shared-types": "0.0.1",
|
|
121
|
-
"@lua/workflow-graph": "0.0.1"
|
|
120
|
+
"@lua/workflow-graph": "0.0.1",
|
|
121
|
+
"@lua/sandbox-runtime": "0.0.1"
|
|
122
122
|
},
|
|
123
123
|
"scripts": {
|
|
124
124
|
"clean": "rm -rf dist temp",
|