@oh-my-ai-sdk/omakase 0.1.2 → 0.1.4
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 +157 -10
- package/dist/agent-catalog.d.ts +202 -0
- package/dist/agent-catalog.js +427 -0
- package/dist/agent-runtime/manifest.json +1 -1
- package/dist/agent-runtime/slice-worker.mjs +112 -24
- package/dist/agent-runtime/versions.json +2 -2
- package/dist/agent-runtime/worker.mjs +18 -7
- package/dist/agent-slice-client.d.ts +54 -6
- package/dist/agent-slice-client.js +151 -22
- package/dist/agent-slice-contract.d.ts +4 -0
- package/dist/agent-slice.d.ts +15 -1
- package/dist/agent-slice.js +12 -5
- package/dist/agent-tasks.d.ts +112 -0
- package/dist/agent-tasks.js +398 -0
- package/dist/agents.d.ts +8 -1
- package/dist/agents.js +138 -70
- package/dist/code-mode.js +12 -2
- package/dist/durable-engine.js +23 -2
- package/dist/durable-host.d.ts +7 -4
- package/dist/durable-host.js +279 -13
- package/dist/durable-protocol.d.ts +11 -1
- package/dist/durable-protocol.js +3 -2
- package/dist/durable-worker/steps.mjs +27 -0
- package/dist/durable-worker/versions.json +1 -1
- package/dist/durable-worker/worker.mjs +100 -12
- package/dist/durable-worker/workflows.mjs +11 -6
- package/dist/durable-worker-client.d.ts +1 -0
- package/dist/durable-worker-client.js +5 -2
- package/dist/frontend.d.ts +2 -2
- package/dist/frontend.js +2 -2
- package/dist/guest-agent-error.d.ts +11 -0
- package/dist/guest-agent-error.js +50 -0
- package/dist/skills-cli.js +16 -3
- package/dist/skills-server.js +1 -1
- package/dist/workflow-host.js +9 -1
- package/dist/workflow.d.ts +4 -0
- package/examples/agent-tasks.config.mjs +63 -0
- package/package.json +5 -2
- package/skill/omakase-codemode/SKILL.md +86 -0
- package/skill/omakase-codemode/examples/0-parallel-agents.ts +76 -0
- package/skill/omakase-codemode/examples/1-decidable-probe.ts +62 -0
- package/skill/omakase-codemode/examples/2-review-branch.ts +95 -0
- package/skill/omakase-codemode/examples/3-fix-loop.ts +163 -0
- package/skill/omakase-codemode/examples/4-unit-pipeline.ts +171 -0
- package/skill/omakase-codemode/examples/5-inline-run.ts +48 -0
- package/skill/omakase-codemode/examples/6-judge-host.ts +144 -0
- package/skill/omakase-codemode/examples/7-discover-and-steer.ts +93 -0
- package/skill/omakase-codemode/examples/README.md +38 -0
- package/skill/omakase-codemode/references/briefs.md +82 -0
- package/skill/omakase-codemode/references/evidence.md +62 -0
- package/skill/omakase-codemode/references/facts.md +68 -0
- package/skill/omakase-codemode/references/gates.md +73 -0
- package/skill/omakase-codemode/references/preflight.md +48 -0
- package/skill/omakase-codemode/references/review.md +75 -0
- package/skill/omakase-codemode/references/runbook.md +82 -0
- package/skill/omakase-codemode/references/tool-surface.md +66 -0
package/README.md
CHANGED
|
@@ -58,6 +58,17 @@ Use `--help` for CLI options. Each invocation owns one live host. The durable
|
|
|
58
58
|
worker is included in the same installation and starts only on the first durable
|
|
59
59
|
call; ordinary calls and catalog inspection do not start it.
|
|
60
60
|
|
|
61
|
+
The `omakase-skills` bin runs the same skills service as its own stdio MCP
|
|
62
|
+
server. With no arguments it serves the skill collection shipped inside the
|
|
63
|
+
package: the `omakase-codemode` skill under collection id `omakase` (the
|
|
64
|
+
`skill/` directory next to `dist/`). It teaches this orchestration workflow —
|
|
65
|
+
`agent.run` fan-out, `task.list` discovery, `agent.steer` correction, gates and
|
|
66
|
+
evidence — in ordinary JS. An explicit
|
|
67
|
+
`--config /absolute/skills-service.config.mjs` or an absolute skills directory
|
|
68
|
+
argument behaves exactly as before. The legacy `omakase-flow` skill is
|
|
69
|
+
untouched and remains only in the Claude plugin copy under
|
|
70
|
+
`plugin/omakase/skills/omakase-flow`; it is not part of this npm bundle.
|
|
71
|
+
|
|
61
72
|
## Execution modes (beta)
|
|
62
73
|
|
|
63
74
|
```ts
|
|
@@ -189,7 +200,9 @@ Registered agent runs are available below; the old Flow DSL is not imported.
|
|
|
189
200
|
`createAgentHost(options)`. Registration reuses Flow's `agent.yaml` directories,
|
|
190
201
|
named profiles, ordinary AI SDK tools under `tools/`, and runtime-download cache.
|
|
191
202
|
There is no new `run` DSL or separate agent MCP server: each trusted registration
|
|
192
|
-
becomes `agents.NAME({ prompt, workspaceDir? })` in the existing cell catalog
|
|
203
|
+
becomes `agents.NAME({ prompt, workspaceDir? })` in the existing cell catalog,
|
|
204
|
+
and the same mount adds the generic `agent.run`, `agent.steer` and `task.list`
|
|
205
|
+
leaves described below.
|
|
193
206
|
|
|
194
207
|
The agent feature needs **Bun >=1.3.14** on PATH in addition to Node. Bridge-backed
|
|
195
208
|
Claude, Codex and OpenCode bootstraps also need **pnpm** and first-use registry
|
|
@@ -315,13 +328,125 @@ absolute Bun path.
|
|
|
315
328
|
|
|
316
329
|
This ports registration and running agents, not Flow's verb set. JS loops,
|
|
317
330
|
branches, `Promise.all`, dependent calls and unrelated host tools remain available.
|
|
318
|
-
Live steering
|
|
331
|
+
Live steering of a running native turn is available through `agent.steer` for
|
|
332
|
+
adapters that support it; unsupported or inactive targets fail typed, never by
|
|
333
|
+
restart. `ask`/`pause` and forwarding a child agent's human approval remain
|
|
319
334
|
deferred. Automatic native decisions are honored; an unresolved child approval
|
|
320
335
|
fails closed. The cell host's existing approval transport is unchanged.
|
|
321
336
|
The private OMP adapter is not bundled: OMP **as a child backend** requires its
|
|
322
337
|
separately installed/built adapter; using an MCP-capable harness as the caller
|
|
323
338
|
does not require that child adapter.
|
|
324
339
|
|
|
340
|
+
## Generic agent runs, task discovery and steering
|
|
341
|
+
|
|
342
|
+
The same agent mount adds three generic leaves to the cell catalog: `agent.run`,
|
|
343
|
+
`agent.steer` and `task.list`. They are ordinary host tools: MCP callers submit
|
|
344
|
+
them as `cell({ code })` bodies, native callers drive the same host snapshots
|
|
345
|
+
and frontends with `mountAgents` imported from `/agents`, and both see identical
|
|
346
|
+
names, schemas and permission policy — the CLI config file and a native
|
|
347
|
+
`mountAgents` call take the same options object. A complete, commented config —
|
|
348
|
+
named agent plus inline catalog — ships in the package as
|
|
349
|
+
`examples/agent-tasks.config.mjs`.
|
|
350
|
+
|
|
351
|
+
`agent.run` selects a backend one of two ways, never both in one call:
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
// Named: the same execution and the same authored result as agents.reviewer.
|
|
355
|
+
const found = await agent.run({ agent: 'reviewer', prompt: 'Inspect README.md' });
|
|
356
|
+
// Inline: registered harness/provider keys plus an authorized model id.
|
|
357
|
+
const probe = await agent.run({
|
|
358
|
+
harness: 'claude', provider: 'zai', model: 'glm-5.3',
|
|
359
|
+
settings: 'deep', // optional: a preset key registered on the provider
|
|
360
|
+
prompt: 'List concrete risks in the install flow.',
|
|
361
|
+
});
|
|
362
|
+
if (probe === null || typeof probe !== 'object' ||
|
|
363
|
+
!('text' in probe) || typeof probe.text !== 'string') {
|
|
364
|
+
throw new Error('Expected text from the inline agent');
|
|
365
|
+
}
|
|
366
|
+
return { found, probe: probe.text };
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Named runs return the registration's authored structured result — the exact
|
|
370
|
+
`agents.NAME` output schema and value. Inline runs return `{ sessionId, text }`.
|
|
371
|
+
The generic tool's static result type is `unknown` because the selected agent
|
|
372
|
+
can change its shape; narrow it before accessing fields, as above. Use
|
|
373
|
+
`agents.NAME` when you want the registered output schema exposed to preflight.
|
|
374
|
+
`workspaceDir` is optional on both and follows the same inside-the-registered-
|
|
375
|
+
workspace rule as `agents.NAME`. Ordinary cells keep one-shot behavior; there
|
|
376
|
+
are no ordinary-cell run IDs.
|
|
377
|
+
|
|
378
|
+
Inline authority is the host-owned `catalog` field of `mountAgents` /
|
|
379
|
+
`createAgentHost`: each harness key names a trusted adapter id and its
|
|
380
|
+
providers; each provider owns credential pointers and options, the authorized
|
|
381
|
+
model ids, and optional named settings presets. `settings` is a preset-name
|
|
382
|
+
string, never an options object — the guest selects a key, the host composes
|
|
383
|
+
trusted options around it. No option fragment may declare `model`; model
|
|
384
|
+
authority is the registered model key. Unregistered or mixed selections fail
|
|
385
|
+
`INVALID_INPUT` before any worker starts, and the whole catalog is validated
|
|
386
|
+
before registration. `cell({})` and the `agent.run` description list the
|
|
387
|
+
registered selection keys. Inline specs carry no tool files: an inline child
|
|
388
|
+
gets the harness's native built-ins — optionally restricted by the registration's
|
|
389
|
+
`activeTools` — through the same loader, while custom tool files remain
|
|
390
|
+
exclusive to named agent directories.
|
|
391
|
+
|
|
392
|
+
### Discovering and steering durable agent tasks
|
|
393
|
+
|
|
394
|
+
`task.list` and `agent.steer` operate on **durable** runs. Submit the run with
|
|
395
|
+
`waitMs: 0`, keep the returned `runId`, then pass it back inside a separate
|
|
396
|
+
ordinary control cell:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
// Ordinary control cell, while the durable run above is still unfinished:
|
|
400
|
+
const { tasks } = await task.list({ runId: '…' });
|
|
401
|
+
// => [{ taskId, kind: 'agent', agent: 'reviewer', status: 'running' }]
|
|
402
|
+
const target = tasks.find(task => task.status === 'running' && task.agent === 'reviewer');
|
|
403
|
+
if (!target) return { steered: false, tasks };
|
|
404
|
+
const ack = await agent.steer({ taskId: target.taskId, prompt: 'Prefer the smallest fix.' });
|
|
405
|
+
return { steered: true, ack };
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
`taskId` is the admitted durable tool-call id, not a native session id; one
|
|
409
|
+
task is one invocation. Statuses: `pending` (admitted, not yet claimed for
|
|
410
|
+
execution), `running` (nonterminal resumable execution — live steering
|
|
411
|
+
availability is **not** implied), `completed`/`failed` (terminal per-slice
|
|
412
|
+
receipt, authoritative even when the run's summary is missing), and `unknown`
|
|
413
|
+
(unresolved claim without a trustworthy continuation). An unknown or foreign
|
|
414
|
+
`runId` fails typed (`NOT_FOUND`/`FORBIDDEN`); it never returns an empty list.
|
|
415
|
+
Control resolves the live task-control port for the caller's trusted
|
|
416
|
+
harness/session scope: the durable executor for that scope must be running
|
|
417
|
+
(`UNAVAILABLE` otherwise; the CLI starts it on the first durable cell and keeps
|
|
418
|
+
it for the host's lifetime).
|
|
419
|
+
|
|
420
|
+
`agent.steer` submits an additional user message into the target's active
|
|
421
|
+
native turn on the same session. `accepted` means exactly that the native
|
|
422
|
+
delivery was accepted — not that the message was applied, checkpointed or
|
|
423
|
+
completed. Refusals carry stable codes in the message prefix:
|
|
424
|
+
`STEER_UNSUPPORTED` (the pinned adapter cannot steer this agent; a steering
|
|
425
|
+
facet alone is not capability), `NOT_RUNNING` (no live slice, or the turn is
|
|
426
|
+
suspending, suspended or finished), `CONFLICT` (same steer call id with a
|
|
427
|
+
changed `{taskId, prompt}`), `OUTCOME_UNKNOWN` (interrupted delivery — never
|
|
428
|
+
retried), and `NOT_FOUND`/`FORBIDDEN` for unknown, foreign or non-agent tasks.
|
|
429
|
+
There is no cancel-and-restart fallback: a refusal never kills the agent slice,
|
|
430
|
+
and steering between slices, after completion, or on unsupported adapters stays
|
|
431
|
+
a typed refusal.
|
|
432
|
+
|
|
433
|
+
Same-intent steering is deduplicated by the trusted steering call id bound to
|
|
434
|
+
its full `{taskId, prompt}`: concurrent duplicates join one delivery, and
|
|
435
|
+
replaying an accepted delivery returns the historical acknowledgement without
|
|
436
|
+
redelivery — even after session loss, so an accepted but unapplied message is
|
|
437
|
+
not repaired.
|
|
438
|
+
|
|
439
|
+
### Upgrades and drift
|
|
440
|
+
|
|
441
|
+
The whole catalog identity — including resolved named-profile contents behind
|
|
442
|
+
unchanged refs, the inline catalog, and `sliceSeconds` — is part of each run's
|
|
443
|
+
recovery identity. Upgrading this package while pending durable agent runs were
|
|
444
|
+
admitted against a catalog that no longer matches fails closed with
|
|
445
|
+
`RECOVERY_BLOCKED`: retain the admitted configuration to finish them, or
|
|
446
|
+
reconcile and archive the state directory. There is no arbitrary in-flight
|
|
447
|
+
migration, and no guarantee that a steer accepted but not yet checkpointed into
|
|
448
|
+
native history survives a restart.
|
|
449
|
+
|
|
325
450
|
## Decision controller in ordinary or durable cells
|
|
326
451
|
|
|
327
452
|
`createDecisionTool({ model, configurationId })` returns an ordinary AI SDK tool.
|
|
@@ -580,11 +705,22 @@ exactly once.
|
|
|
580
705
|
|
|
581
706
|
## Automatic releases
|
|
582
707
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
708
|
+
An eligible merge to `main` triggers `release.yml`. CI automatically assigns the
|
|
709
|
+
next **patch** on the owner-approved release line: `0.1.3` → `0.1.4` → `0.1.5`.
|
|
710
|
+
Do not hand-bump the patch in `package.json`. Its major/minor must match the
|
|
711
|
+
`OMAKASE_RELEASE_LINE` variable in GitHub's **npm-omakase** environment; changing
|
|
712
|
+
source to `0.2.0` alone fails closed. Only Charles may authorize changing that
|
|
713
|
+
setting and the source manifest to a new major/minor line.
|
|
714
|
+
|
|
715
|
+
The publisher requires successful CI on that exact commit, reserves a
|
|
716
|
+
package-scoped `omakase@<version>` tag, installs locked dependencies, then stamps
|
|
717
|
+
the artifact's version and source commit. It builds once and runs the installed
|
|
718
|
+
ordinary/durable MCP proof before publishing the tested tarball, checks npm's
|
|
719
|
+
integrity, and repeats the proof against a registry installation.
|
|
720
|
+
Reservations are immutable: retries reuse the same version, including after a
|
|
721
|
+
publish whose registry visibility was delayed. Failed builds can leave patch
|
|
722
|
+
gaps; do not delete or move their tags. A superseded unpublished reservation
|
|
723
|
+
cannot replace a newer release on `latest`.
|
|
588
724
|
|
|
589
725
|
Omakase continues on the `0.1.x` release line: `0.1.1` includes the functionality
|
|
590
726
|
previously published as `0.2.0-beta.3`. Durable execution remains an opt-in beta
|
|
@@ -593,17 +729,28 @@ Normal installs use `@oh-my-ai-sdk/omakase` on `latest`. Previously published
|
|
|
593
729
|
prereleases remain available; existing pins or `@beta` installs must switch to
|
|
594
730
|
`0.1.1` or `@latest` to follow this release line.
|
|
595
731
|
|
|
596
|
-
|
|
597
|
-
|
|
732
|
+
Automatic publication produces stable `0.1.x` versions on `latest`; it does not
|
|
733
|
+
infer minor/major bumps or prereleases from commit messages. The early-stage
|
|
734
|
+
patch policy includes reviewed features, not just fixes; it is not a claim that
|
|
735
|
+
all APIs are stable.
|
|
598
736
|
|
|
599
737
|
One-time npm setup: in this package's **Settings → Trusted publishing**, authorize
|
|
600
738
|
GitHub owner `archeism`, repository `oh-my-ai`, workflow **`release.yml`**, environment
|
|
601
739
|
**`npm-omakase`**, with direct **`npm publish`** allowed. The GitHub environment
|
|
602
740
|
permits only branch `main`, with no required reviewers or per-release approval.
|
|
603
741
|
A staged-publish permission alone does not enable automatic releases. No npm token secret is used.
|
|
742
|
+
Set the environment variable `OMAKASE_RELEASE_LINE` to `0.1` during setup.
|
|
743
|
+
The publisher has tag-writing permission, not environment-administration
|
|
744
|
+
permission. Moving to `0.2` or `1.0` is an explicit owner decision, not a routine
|
|
745
|
+
release approval.
|
|
746
|
+
Bootstrap an existing publication with its verified `omakase@<version>` source
|
|
747
|
+
tag before enabling this allocator (Omakase's baseline is `omakase@0.1.3`).
|
|
748
|
+
New allocations must descend from the newest reservation, not necessarily equal
|
|
749
|
+
the current main tip: an unrelated main merge must not strand an eligible release.
|
|
604
750
|
See [npm's trusted-publisher setup](https://docs.npmjs.com/trusted-publishers/).
|
|
605
751
|
|
|
606
|
-
After fixing a publishing failure,
|
|
752
|
+
After fixing a publishing failure, rerun the failed Actions run to resume its
|
|
753
|
+
exact source reservation. To release or verify the current reviewed `main`:
|
|
607
754
|
|
|
608
755
|
```sh
|
|
609
756
|
gh workflow run release.yml --repo archeism/oh-my-ai --ref main
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { type JSONSchema7, type JSONValue } from 'ai';
|
|
2
|
+
import type { ToolHost } from './host.js';
|
|
3
|
+
/** Trusted inline backend spec — the object presentation of an agent the
|
|
4
|
+
* flow provider already loads (inlineManifest): one lane plus instructions
|
|
5
|
+
* text. Host-composed only; never accepted from tool arguments. There are no
|
|
6
|
+
* tool files here — tools are files and belong to named agent directories —
|
|
7
|
+
* and no sandbox rootDir: that is per-run host state. */
|
|
8
|
+
export interface InlineBackendSpec {
|
|
9
|
+
/** Adapter id (e.g. 'claude-code', 'codex', 'pi', 'omp'). */
|
|
10
|
+
readonly harness: string;
|
|
11
|
+
readonly instructions?: string;
|
|
12
|
+
readonly options?: Readonly<Record<string, JSONValue>>;
|
|
13
|
+
readonly sandbox?: {
|
|
14
|
+
readonly type?: 'local' | 'local-persistent';
|
|
15
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
16
|
+
readonly inheritEnv?: boolean;
|
|
17
|
+
readonly warm?: boolean;
|
|
18
|
+
};
|
|
19
|
+
readonly processEnv?: Readonly<Record<string, string>>;
|
|
20
|
+
readonly placement?: string;
|
|
21
|
+
readonly permissionMode?: 'allow-reads' | 'allow-edits' | 'allow-all';
|
|
22
|
+
readonly toolApproval?: Readonly<Record<string, JSONValue>>;
|
|
23
|
+
readonly activeTools?: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
/** Backend reference exactly as the bundled runtimes and the flow provider
|
|
26
|
+
* accept it: a registry-workspace ref string (named presentation) or a
|
|
27
|
+
* trusted inline spec composed by this catalog. */
|
|
28
|
+
export type AgentBackendRef = string | InlineBackendSpec;
|
|
29
|
+
/** Named, host-authored settings preset a guest may select by key. */
|
|
30
|
+
export interface AgentSettingsRegistration {
|
|
31
|
+
/** Trusted harness options merged when this key is selected. */
|
|
32
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
33
|
+
}
|
|
34
|
+
/** One authorized model on a provider. */
|
|
35
|
+
export interface AgentModelRegistration {
|
|
36
|
+
/** Trusted harness options merged only when this model runs (e.g. env
|
|
37
|
+
* pinning the model id alongside options.model). */
|
|
38
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
39
|
+
}
|
|
40
|
+
/** One provider under a harness: the route and credential unit. */
|
|
41
|
+
export interface AgentProviderRegistration {
|
|
42
|
+
readonly description?: string;
|
|
43
|
+
/** Authorized model ids; guests must pass a key verbatim as `model`. */
|
|
44
|
+
readonly models: Readonly<Record<string, AgentModelRegistration>>;
|
|
45
|
+
/** Trusted provider-wide harness options; values may carry `${file:…}` /
|
|
46
|
+
* `${VAR}` pointers resolved against the HOST environment only. */
|
|
47
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
48
|
+
/** Trusted sandbox environment (bridge harnesses read credentials here). */
|
|
49
|
+
readonly sandboxEnv?: Readonly<Record<string, string>>;
|
|
50
|
+
/** Trusted process-env declarations (host-process harnesses). */
|
|
51
|
+
readonly processEnv?: Readonly<Record<string, string>>;
|
|
52
|
+
/** Named trusted settings presets selectable through `settings`. */
|
|
53
|
+
readonly settings?: Readonly<Record<string, AgentSettingsRegistration>>;
|
|
54
|
+
}
|
|
55
|
+
/** One registered harness: the guest-visible selection unit for inline runs. */
|
|
56
|
+
export interface AgentHarnessRegistration {
|
|
57
|
+
/** Adapter id placed in the inline spec — trusted, host-only. */
|
|
58
|
+
readonly harness: string;
|
|
59
|
+
readonly description?: string;
|
|
60
|
+
/** Instructions text used for every inline run of this harness. */
|
|
61
|
+
readonly instructions?: string;
|
|
62
|
+
readonly permissionMode?: 'allow-reads' | 'allow-edits' | 'allow-all';
|
|
63
|
+
readonly toolApproval?: Readonly<Record<string, unknown>>;
|
|
64
|
+
readonly activeTools?: readonly string[];
|
|
65
|
+
readonly sandbox?: {
|
|
66
|
+
readonly type?: 'local' | 'local-persistent';
|
|
67
|
+
readonly inheritEnv?: boolean;
|
|
68
|
+
readonly warm?: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** Harness options merged under every provider of this harness. */
|
|
71
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
72
|
+
readonly providers: Readonly<Record<string, AgentProviderRegistration>>;
|
|
73
|
+
}
|
|
74
|
+
/** The `catalog` field of MountAgentsOptions. */
|
|
75
|
+
export interface AgentCatalogOptions {
|
|
76
|
+
readonly harnesses: Readonly<Record<string, AgentHarnessRegistration>>;
|
|
77
|
+
}
|
|
78
|
+
/** Validated, cloned snapshot of a catalog: what the fingerprint hashes and
|
|
79
|
+
* selection composes from. Caller mutation after mount cannot drift it. */
|
|
80
|
+
export interface NormalizedAgentCatalog {
|
|
81
|
+
readonly harnesses: Readonly<Record<string, NormalizedAgentHarness>>;
|
|
82
|
+
}
|
|
83
|
+
export interface NormalizedAgentHarness {
|
|
84
|
+
readonly key: string;
|
|
85
|
+
readonly harness: string;
|
|
86
|
+
readonly description?: string;
|
|
87
|
+
readonly instructions?: string;
|
|
88
|
+
readonly permissionMode?: 'allow-reads' | 'allow-edits' | 'allow-all';
|
|
89
|
+
readonly toolApproval?: Record<string, JSONValue>;
|
|
90
|
+
readonly activeTools?: string[];
|
|
91
|
+
readonly sandbox: {
|
|
92
|
+
readonly type?: 'local' | 'local-persistent';
|
|
93
|
+
readonly inheritEnv?: boolean;
|
|
94
|
+
readonly warm?: boolean;
|
|
95
|
+
};
|
|
96
|
+
readonly options?: Record<string, JSONValue>;
|
|
97
|
+
readonly providers: Readonly<Record<string, NormalizedAgentProvider>>;
|
|
98
|
+
}
|
|
99
|
+
export interface NormalizedAgentProvider {
|
|
100
|
+
readonly key: string;
|
|
101
|
+
readonly description?: string;
|
|
102
|
+
readonly models: Readonly<Record<string, {
|
|
103
|
+
readonly options?: Record<string, JSONValue>;
|
|
104
|
+
}>>;
|
|
105
|
+
readonly options?: Record<string, JSONValue>;
|
|
106
|
+
readonly sandboxEnv?: Record<string, string>;
|
|
107
|
+
readonly processEnv?: Record<string, string>;
|
|
108
|
+
readonly settings?: Readonly<Record<string, {
|
|
109
|
+
readonly options?: Record<string, JSONValue>;
|
|
110
|
+
}>>;
|
|
111
|
+
}
|
|
112
|
+
/** Guest input of `agent.run`: exactly one selection mode. */
|
|
113
|
+
export interface AgentRunInput {
|
|
114
|
+
/** Named mode: a registered agent name (the `agents.NAME` key). */
|
|
115
|
+
readonly agent?: string;
|
|
116
|
+
/** Inline mode: a registered harness key. */
|
|
117
|
+
readonly harness?: string;
|
|
118
|
+
/** Inline mode: a provider key registered under that harness. */
|
|
119
|
+
readonly provider?: string;
|
|
120
|
+
/** Inline mode: a model id authorized on that provider. */
|
|
121
|
+
readonly model?: string;
|
|
122
|
+
/** Inline mode: a settings key registered on that provider. */
|
|
123
|
+
readonly settings?: string;
|
|
124
|
+
readonly prompt: string;
|
|
125
|
+
readonly workspaceDir?: string;
|
|
126
|
+
}
|
|
127
|
+
/** One resolved backend selection: a named registration (authored schema and
|
|
128
|
+
* result contract) or a host-composed inline spec. */
|
|
129
|
+
export type AgentBackendSelection = {
|
|
130
|
+
readonly kind: 'named';
|
|
131
|
+
readonly name: string;
|
|
132
|
+
readonly ref: string;
|
|
133
|
+
readonly outputSchema?: JSONSchema7;
|
|
134
|
+
} | {
|
|
135
|
+
readonly kind: 'inline';
|
|
136
|
+
readonly spec: InlineBackendSpec;
|
|
137
|
+
readonly label: string;
|
|
138
|
+
};
|
|
139
|
+
/** Validates and snapshots a catalog before any host effect (namespace
|
|
140
|
+
* registration, filesystem, workers). Throws typed INVALID_INPUT naming the
|
|
141
|
+
* offending field; forbidden overrides (a `model` key in any option
|
|
142
|
+
* fragment) are rejected here, before effects, per the authority contract. */
|
|
143
|
+
export declare function validateAgentCatalog(catalog: unknown): NormalizedAgentCatalog;
|
|
144
|
+
/** Deterministic JSON with recursively sorted object keys: equal
|
|
145
|
+
* configurations hash equal regardless of authoring key order. */
|
|
146
|
+
export declare function canonicalJson(value: unknown): string;
|
|
147
|
+
/** Stable, secret-free fingerprint of the whole mounted agent authority.
|
|
148
|
+
* Inputs are the validated catalog snapshot, the trusted slice budget and —
|
|
149
|
+
* critically — each named profile's RESOLVED inspect identity, so content
|
|
150
|
+
* drift behind an unchanged ref string (an agent.yaml edit on the host)
|
|
151
|
+
* rejects admission recovery even for tools a pending cell never invoked.
|
|
152
|
+
* Inline config drift is covered the same way: the selected identity embeds
|
|
153
|
+
* the resolved manifest fingerprint of the composed spec. The result is a
|
|
154
|
+
* hex hash — no configuration object, pointer or secret is serialized. */
|
|
155
|
+
export declare function agentCatalogFingerprint(input: {
|
|
156
|
+
readonly named: ReadonlyArray<{
|
|
157
|
+
readonly name: string;
|
|
158
|
+
readonly identity: string;
|
|
159
|
+
}>;
|
|
160
|
+
readonly catalog: NormalizedAgentCatalog | undefined;
|
|
161
|
+
readonly sliceSeconds: number;
|
|
162
|
+
}): string;
|
|
163
|
+
/** In-memory memo key for one backend ref: the ref itself when named, a hash
|
|
164
|
+
* of the canonical spec otherwise. Never persisted, logged or sent. */
|
|
165
|
+
export declare function agentBackendRefKey(ref: AgentBackendRef): string;
|
|
166
|
+
/** Validates one agent.run input against the mounted authority and resolves
|
|
167
|
+
* the backend selection. Pure: no worker, no filesystem, no effects — every
|
|
168
|
+
* unregistered or mixed selection fails here, typed, before anything runs.
|
|
169
|
+
* Registration lookups are own-key: names inherited from Object.prototype
|
|
170
|
+
* (`constructor`, `toString`, `__proto__`, …) never grant authority. */
|
|
171
|
+
export declare function resolveAgentRunSelection(input: unknown, named: ReadonlyMap<string, {
|
|
172
|
+
readonly ref: string;
|
|
173
|
+
readonly outputSchema?: JSONSchema7;
|
|
174
|
+
}>, catalog: NormalizedAgentCatalog | undefined): AgentBackendSelection;
|
|
175
|
+
/** What agents.ts supplies to mount the generic surface: the validated
|
|
176
|
+
* authority snapshot plus the shared execution/identity machinery (the same
|
|
177
|
+
* ordinary one-shot and durable-slice paths behind agents.NAME). */
|
|
178
|
+
export interface AgentCatalogMount {
|
|
179
|
+
readonly host: ToolHost;
|
|
180
|
+
/** Whole-catalog identity; registered as the catalog inspector of every
|
|
181
|
+
* agent tool for admission drift rejection. */
|
|
182
|
+
readonly catalogFingerprint: () => Promise<string>;
|
|
183
|
+
readonly catalog: NormalizedAgentCatalog | undefined;
|
|
184
|
+
readonly named: ReadonlyMap<string, {
|
|
185
|
+
readonly ref: string;
|
|
186
|
+
readonly outputSchema?: JSONSchema7;
|
|
187
|
+
}>;
|
|
188
|
+
/** Selected per-input identity of one validated selection (worker inspect
|
|
189
|
+
* mode; memoized by agents.ts). */
|
|
190
|
+
identityForSelection(selection: AgentBackendSelection): Promise<string>;
|
|
191
|
+
/** Execute one selection with agents.NAME semantics: authored structured
|
|
192
|
+
* result for named selections, { sessionId, text } for inline; durable
|
|
193
|
+
* slice support and same-intent replay dedup included. */
|
|
194
|
+
runSelected(selection: AgentBackendSelection, input: AgentRunInput, execution: {
|
|
195
|
+
readonly toolCallId: string;
|
|
196
|
+
readonly abortSignal?: AbortSignal;
|
|
197
|
+
}): Promise<JSONValue>;
|
|
198
|
+
}
|
|
199
|
+
/** Registers the `agent` namespace — `run` (named or inline selection) and
|
|
200
|
+
* `steer` (routed to the task-control port) — and the recovery inspectors
|
|
201
|
+
* of `agent.run`. Called once from mountAgents after the named tools. */
|
|
202
|
+
export declare function mountAgentCatalog(mount: AgentCatalogMount): Promise<void>;
|