@oh-my-ai-sdk/omakase 0.1.1 → 0.1.3
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 +217 -9
- 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/cell-declarations.d.ts +1 -1
- package/dist/cell-declarations.js +7 -2
- package/dist/cli.js +2 -1
- package/dist/code-mode.js +12 -2
- package/dist/decision.d.ts +28 -0
- package/dist/decision.js +193 -0
- 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/execution-policy.d.ts +4 -0
- package/dist/execution-policy.js +17 -0
- 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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/skills-cli.js +16 -3
- package/dist/skills-host.d.ts +3 -0
- package/dist/skills-host.js +5 -1
- 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 +3 -1
- 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
|
@@ -12,15 +12,16 @@ configured URI sources. No model-facing registry-management tools.
|
|
|
12
12
|
## CLI setup
|
|
13
13
|
|
|
14
14
|
Requires Node.js 22.13 or newer. The host itself needs no model key; your calling
|
|
15
|
-
Claude/Codex session supplies its own model. Registered child agents
|
|
16
|
-
|
|
17
|
-
(see below). Configuration stays outside
|
|
15
|
+
Claude/Codex session supplies its own model. Registered child agents and decision
|
|
16
|
+
tools use their own configured credentials. Child agents additionally need Bun
|
|
17
|
+
and their bootstrap prerequisites (see below). Configuration stays outside
|
|
18
|
+
harness MCP registration.
|
|
18
19
|
|
|
19
|
-
For a local
|
|
20
|
+
For a local candidate, install its packed `.tgz` with `bun add /absolute/path/to/archive.tgz`
|
|
20
21
|
and configure your MCP client with the absolute path to that installation's
|
|
21
|
-
`node_modules/.bin/omakase`. The registry commands below
|
|
22
|
-
|
|
23
|
-
not publish it.
|
|
22
|
+
`node_modules/.bin/omakase`. The registry commands below install the published
|
|
23
|
+
`latest` release on the `0.1.x` line. Building or installing a local candidate
|
|
24
|
+
does not publish it.
|
|
24
25
|
|
|
25
26
|
Create `~/.config/omakase/host.config.mjs` (or
|
|
26
27
|
`$XDG_CONFIG_HOME/omakase/host.config.mjs`):
|
|
@@ -57,6 +58,17 @@ Use `--help` for CLI options. Each invocation owns one live host. The durable
|
|
|
57
58
|
worker is included in the same installation and starts only on the first durable
|
|
58
59
|
call; ordinary calls and catalog inspection do not start it.
|
|
59
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
|
+
|
|
60
72
|
## Execution modes (beta)
|
|
61
73
|
|
|
62
74
|
```ts
|
|
@@ -188,7 +200,9 @@ Registered agent runs are available below; the old Flow DSL is not imported.
|
|
|
188
200
|
`createAgentHost(options)`. Registration reuses Flow's `agent.yaml` directories,
|
|
189
201
|
named profiles, ordinary AI SDK tools under `tools/`, and runtime-download cache.
|
|
190
202
|
There is no new `run` DSL or separate agent MCP server: each trusted registration
|
|
191
|
-
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.
|
|
192
206
|
|
|
193
207
|
The agent feature needs **Bun >=1.3.14** on PATH in addition to Node. Bridge-backed
|
|
194
208
|
Claude, Codex and OpenCode bootstraps also need **pnpm** and first-use registry
|
|
@@ -314,13 +328,207 @@ absolute Bun path.
|
|
|
314
328
|
|
|
315
329
|
This ports registration and running agents, not Flow's verb set. JS loops,
|
|
316
330
|
branches, `Promise.all`, dependent calls and unrelated host tools remain available.
|
|
317
|
-
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
|
|
318
334
|
deferred. Automatic native decisions are honored; an unresolved child approval
|
|
319
335
|
fails closed. The cell host's existing approval transport is unchanged.
|
|
320
336
|
The private OMP adapter is not bundled: OMP **as a child backend** requires its
|
|
321
337
|
separately installed/built adapter; using an MCP-capable harness as the caller
|
|
322
338
|
does not require that child adapter.
|
|
323
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
|
+
|
|
450
|
+
## Decision controller in ordinary or durable cells
|
|
451
|
+
|
|
452
|
+
`createDecisionTool({ model, configurationId })` returns an ordinary AI SDK tool.
|
|
453
|
+
Register it as `tools.decision` in a custom host, or set the optional `decision`
|
|
454
|
+
configuration on `createSkillsHost` to add it alongside `tools.read`. The existing
|
|
455
|
+
MCP server still exposes one `cell` tool; no separate decision server is needed.
|
|
456
|
+
|
|
457
|
+
Example `host.config.mjs` (install the provider beside this config, not inside
|
|
458
|
+
Omakase):
|
|
459
|
+
|
|
460
|
+
```js
|
|
461
|
+
import { createTypeSafeAi } from '@ai-sdk/typesafe-ai';
|
|
462
|
+
|
|
463
|
+
export default async ({ createSkillsHost }) => createSkillsHost({
|
|
464
|
+
collections: [],
|
|
465
|
+
cwd: '/absolute/path/to/workspace',
|
|
466
|
+
decision: {
|
|
467
|
+
model: createTypeSafeAi().decisionModel('jev-1.13.0'),
|
|
468
|
+
configurationId: 'review-controller-v1',
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
This example uses `TYPESAFE_AI_API_KEY` and the tested
|
|
474
|
+
`@ai-sdk/typesafe-ai@3.0.13` adapter with Omakase's pinned `ai@7.0.128`.
|
|
475
|
+
The experimental decision protocol can change in patch releases: adapter
|
|
476
|
+
`3.0.17` expects a newer state representation and is not compatible with this
|
|
477
|
+
core version. No provider is installed, selected, or silently substituted by
|
|
478
|
+
Omakase. Other SDK decision-model instances may be supplied, but their provider
|
|
479
|
+
compatibility must be verified; this release does not include a Clef adapter.
|
|
480
|
+
|
|
481
|
+
Native custom hosts import `createDecisionTool` from `@oh-my-ai-sdk/omakase` and
|
|
482
|
+
use `await host.register('tools', { decision: createDecisionTool(options) })`.
|
|
483
|
+
Include other `tools` leaves in that same registration: namespaces cannot be
|
|
484
|
+
registered twice. The CLI also supplies `createDecisionTool` to its host factory.
|
|
485
|
+
|
|
486
|
+
Submit this body through the existing `cell` API:
|
|
487
|
+
|
|
488
|
+
```ts
|
|
489
|
+
const { answers } = await tools.decision({
|
|
490
|
+
state: { reviews: ["No blocking defects"], tests: "passed" },
|
|
491
|
+
questions: {
|
|
492
|
+
blocked: { type: "boolean", instructions: "Is there a blocking defect?" },
|
|
493
|
+
next: {
|
|
494
|
+
type: "choice",
|
|
495
|
+
instructions: "Choose the next action.",
|
|
496
|
+
criteria: { fix: "Repair a defect", finish: "Verified completion" },
|
|
497
|
+
},
|
|
498
|
+
quality: {
|
|
499
|
+
type: "score",
|
|
500
|
+
instructions: "Rate completeness.",
|
|
501
|
+
criteria: ["Incomplete", "Partly complete", "Complete"],
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
const { blocked, next, quality } = answers;
|
|
506
|
+
if (!blocked || !next || !quality ||
|
|
507
|
+
blocked.type !== "boolean" || next.type !== "choice" || quality.type !== "score")
|
|
508
|
+
throw new Error("Unexpected decision answer types");
|
|
509
|
+
return { blocked: blocked.probability, next: next.choice, quality: quality.score };
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
- State and instructions accept a JSON string, object or array. Question names
|
|
513
|
+
identify answers. Criteria descriptions can additionally be `null`.
|
|
514
|
+
- `boolean` returns P(true), not a Boolean flag. `choice` returns an option name.
|
|
515
|
+
`score` returns a fractional position from zero through the last rubric index.
|
|
516
|
+
Choice/score distributions are optional; calibration is not portable across
|
|
517
|
+
providers. The result contains `{ answers, modelId }`, not SDK transport data.
|
|
518
|
+
- JavaScript owns branching. A judgment never grants tool permissions or bypasses
|
|
519
|
+
native approval. Malformed answers and provider errors fail the tool call;
|
|
520
|
+
no fallback judgment or automatic inference retry is supplied.
|
|
521
|
+
- Ordinary cells execute directly. Durable cells record each decision invocation;
|
|
522
|
+
all questions in one call share that checkpoint. Separate calls can progress
|
|
523
|
+
independently. Recorded answers are reused; an interrupted inference without a
|
|
524
|
+
committed receipt fails `OUTCOME_UNKNOWN` rather than silently re-inferencing.
|
|
525
|
+
- The configured provider/model and `configurationId` contribute to durable
|
|
526
|
+
catalog identity via `metadata.omakase.executionIdentity`. Change the revision
|
|
527
|
+
whenever endpoint, adapter or hidden settings change, and keep model instances
|
|
528
|
+
immutable. Pending runs reject configuration drift with `RECOVERY_BLOCKED`;
|
|
529
|
+
retain the admitted configuration to recover them. Do not use secrets in this
|
|
530
|
+
revision or a moving model alias when reproducibility matters.
|
|
531
|
+
|
|
324
532
|
## Skill reads through Code Mode
|
|
325
533
|
|
|
326
534
|
Call `cell({})` to inspect the current full leaf catalog. Submit the following
|
|
@@ -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>;
|