@fungi.computer/shiitake 0.2.0 → 0.3.1

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.
Files changed (114) hide show
  1. package/README.md +155 -34
  2. package/dist/agent-control.d.ts +77 -5
  3. package/dist/agent-control.js +271 -65
  4. package/dist/client-entry.d.ts +15 -8
  5. package/dist/client-entry.js +7 -5
  6. package/dist/client-wire.d.ts +24 -8
  7. package/dist/client-wire.js +53 -11
  8. package/dist/client.d.ts +56 -11
  9. package/dist/client.js +1 -1
  10. package/dist/cloudflare.d.ts +42 -23
  11. package/dist/cloudflare.js +76 -54
  12. package/dist/cold-sessions.d.ts +28 -0
  13. package/dist/cold-sessions.js +1 -0
  14. package/dist/delegation.d.ts +214 -0
  15. package/dist/delegation.js +319 -0
  16. package/dist/effect.d.ts +1 -1
  17. package/dist/errors.d.ts +2 -2
  18. package/dist/errors.js +2 -2
  19. package/dist/extension-contract.d.ts +10 -2
  20. package/dist/extensions.d.ts +6 -2
  21. package/dist/fleet.d.ts +43 -9
  22. package/dist/fleet.js +88 -25
  23. package/dist/hosted.js +1 -0
  24. package/dist/http-routes.d.ts +113 -29
  25. package/dist/http-routes.js +18 -1
  26. package/dist/index.d.ts +3 -2
  27. package/dist/internal/accepted-run-executor.d.ts +5 -0
  28. package/dist/internal/accepted-run-executor.js +10 -4
  29. package/dist/internal/admission-door.d.ts +3 -0
  30. package/dist/internal/admission-door.js +12 -2
  31. package/dist/internal/client-boundary.js +7 -1
  32. package/dist/internal/compaction/compaction-slot.d.ts +36 -0
  33. package/dist/internal/compaction/compaction-slot.js +41 -0
  34. package/dist/internal/compaction/compaction.d.ts +11 -8
  35. package/dist/internal/compaction/compaction.js +62 -34
  36. package/dist/internal/compaction/session-compaction.d.ts +8 -16
  37. package/dist/internal/compaction/session-compaction.js +358 -119
  38. package/dist/internal/compaction/settings.d.ts +1 -1
  39. package/dist/internal/compaction/settings.js +5 -0
  40. package/dist/internal/compaction/utils.d.ts +19 -16
  41. package/dist/internal/compaction/utils.js +30 -84
  42. package/dist/internal/contracts.d.ts +40 -13
  43. package/dist/internal/coordinator.js +28 -10
  44. package/dist/internal/effect-client.d.ts +4 -2
  45. package/dist/internal/effect-client.js +29 -0
  46. package/dist/internal/effect-contracts.d.ts +17 -4
  47. package/dist/internal/extension-runtime.d.ts +5 -0
  48. package/dist/internal/extension-runtime.js +184 -89
  49. package/dist/internal/host-meta.d.ts +7 -0
  50. package/dist/internal/model-acquisition.js +7 -1
  51. package/dist/internal/model-preference.d.ts +4 -2
  52. package/dist/internal/model-preference.js +2 -1
  53. package/dist/internal/promise-facade.js +4 -16
  54. package/dist/internal/run-failure-reason.d.ts +10 -0
  55. package/dist/internal/run-failure-reason.js +19 -0
  56. package/dist/internal/run-scope.d.ts +4 -1
  57. package/dist/internal/run-scope.js +38 -5
  58. package/dist/internal/runtime-coordinator.d.ts +2 -1
  59. package/dist/internal/runtime-coordinator.js +65 -4
  60. package/dist/internal/runtime-core.js +1 -0
  61. package/dist/internal/runtime-reconciliation.js +42 -6
  62. package/dist/internal/session-context.d.ts +1 -2
  63. package/dist/internal/session-context.js +8 -30
  64. package/dist/internal/session-status.d.ts +2 -1
  65. package/dist/internal/session-status.js +4 -1
  66. package/dist/internal/woodstock/client-projection.d.ts +6 -5
  67. package/dist/internal/woodstock/client-projection.js +79 -53
  68. package/dist/internal/woodstock/cold-sessions.d.ts +4 -0
  69. package/dist/internal/woodstock/cold-sessions.js +90 -0
  70. package/dist/internal/woodstock/extension-store.d.ts +2 -0
  71. package/dist/internal/woodstock/extension-store.js +4 -0
  72. package/dist/internal/woodstock/fleet-store.d.ts +5 -1
  73. package/dist/internal/woodstock/fleet-store.js +17 -5
  74. package/dist/internal/woodstock/index.d.ts +11 -3
  75. package/dist/internal/woodstock/index.js +33 -14
  76. package/dist/internal/woodstock/progress.d.ts +14 -1
  77. package/dist/internal/woodstock/progress.js +97 -19
  78. package/dist/internal/woodstock/run-recovery.js +6 -4
  79. package/dist/internal/woodstock/session-attention.d.ts +1 -1
  80. package/dist/internal/woodstock/session-attention.js +2 -2
  81. package/dist/internal/woodstock/session-entry.d.ts +110 -43
  82. package/dist/internal/woodstock/session-entry.js +63 -20
  83. package/dist/internal/woodstock/session-inbox.js +2 -0
  84. package/dist/internal/woodstock/session-store.d.ts +104 -24
  85. package/dist/internal/woodstock/session-store.js +937 -246
  86. package/dist/internal/woodstock/storage-admission.d.ts +8 -8
  87. package/dist/internal/woodstock/storage-admission.js +8 -34
  88. package/dist/internal/woodstock/storage-conformance.d.ts +15 -0
  89. package/dist/internal/woodstock/storage-conformance.js +489 -0
  90. package/dist/model-preference.d.ts +2 -2
  91. package/dist/model-preference.js +2 -2
  92. package/dist/node.js +1 -1
  93. package/dist/remote-client.js +8 -1
  94. package/dist/session-attention.d.ts +8 -1
  95. package/dist/session-attention.js +6 -1
  96. package/dist/testing.d.ts +1 -1
  97. package/dist/testing.js +1 -0
  98. package/docs/api/README.md +18 -16
  99. package/docs/api/agent-control.md +171 -1
  100. package/docs/api/client-entry.md +26 -10
  101. package/docs/api/client.md +153 -37
  102. package/docs/api/cloudflare.md +76 -23
  103. package/docs/api/delegation.md +485 -0
  104. package/docs/api/effect.md +20 -2
  105. package/docs/api/extensions.md +21 -9
  106. package/docs/api/fleet.md +159 -104
  107. package/docs/api/http.md +4 -1
  108. package/docs/api/index.md +116 -20
  109. package/docs/api/internal/woodstock/storage-conformance.md +81 -0
  110. package/docs/api/model-preference.md +27 -10
  111. package/docs/api/testing.md +16 -4
  112. package/package.json +26 -14
  113. package/dist/internal/browser-sessions.d.ts +0 -31
  114. package/dist/internal/browser-sessions.js +0 -173
package/README.md CHANGED
@@ -8,14 +8,55 @@ There are three ways to run it:
8
8
 
9
9
  - **In your code**: install this package and host Agents yourself, on Node for
10
10
  tests or in a
11
- [Cloudflare Durable Object](https://shiitake.shiit.app/run/cloudflare/).
11
+ [Cloudflare Durable Object](https://docs.fungi.computer/shiitake/run/cloudflare/).
12
12
  - **On your machine**: the [`fungi` CLI](https://docs.fungi.computer/install/)
13
13
  is a Shiitake Agent with a terminal interface.
14
- - **Hosted**: [Fungi](https://shiitake.shiit.app/run/fungi/) runs Agents for
15
- your Team, and its models work from your own host too.
14
+ - **Hosted**: [Fungi](https://docs.fungi.computer/shiitake/run/fungi/) runs
15
+ Agents for your Team, and its models work from your own host too.
16
16
 
17
17
  To add your own behaviour, start the extension guide at
18
- [Your first extension](https://shiitake.shiit.app/extensions/first-extension/).
18
+ [Your first extension](https://docs.fungi.computer/shiitake/extensions/first-extension/).
19
+
20
+ ## Community-funded
21
+
22
+ We don't take VC money. Fungi is built in the open and proudly backed by its
23
+ community, including the **$SHIIT** community token.
24
+
25
+ $SHIT is not $SHIIT.
26
+
27
+ Official contract address (Solana):
28
+ `412ECWXN3jGbd1kn8ck7eeupWttkmrFkNm9JqfAzpump`
29
+
30
+ This is the only official address. Fungi will never DM you about the token.
31
+ Nothing here is financial advice, and the token isn't a share in Fungi. More at
32
+ [fungi.computer/funding](https://fungi.computer/funding).
33
+
34
+ ## Recover an uncertain send
35
+
36
+ Both local and HTTP Sessions expose
37
+ `session.withdraw(requestId): Promise<WithdrawResult>`:
38
+
39
+ ```ts
40
+ type WithdrawResult =
41
+ { status: "accepted"; commandId: string } | { status: "unknown" };
42
+ ```
43
+
44
+ Shiitake resolves this inside the admission owner's transaction. An existing
45
+ admission wins and is **not cancelled**. Otherwise the owner commits a durable
46
+ withdrawal fence; every later admission under that Session and request ID is
47
+ refused, including after owner restart. Calls are idempotent and Session-scoped.
48
+ A recorded operator line also wins over withdrawal, with its durable entry ID.
49
+
50
+ Restore a pending draft only after `unknown` from this committed withdrawal,
51
+ never after a failed transport or an empty observation page. If recovery itself
52
+ fails, retain the request ID and exact text and retry recovery when connected. A
53
+ user retry after withdrawal needs a **new** request ID. Recall can use this same
54
+ primitive, then call `cancel({ commandId, onlyIfPending: true })` for an
55
+ accepted queued command; withdrawal itself never cancels admitted work.
56
+
57
+ Observation messages for prompts and operator lines carry `requestId`; pending
58
+ prompts carry it too. Clients can therefore reconcile watch-first delivery
59
+ without waiting for the command response or matching text.
19
60
 
20
61
  ## Set up
21
62
 
@@ -47,7 +88,7 @@ wake contracts. Existing host fixtures show deterministic and native adapters.
47
88
 
48
89
  ## Quick start without a provider account
49
90
 
50
- Node 24 or newer provides the SQLite database for the public testing helper.
91
+ Node's built-in SQLite (Node 22.13 or newer) backs the public testing helper.
51
92
  This runs the real durable Agent with a deterministic faux model; no credentials
52
93
  or background timer are needed. Drive settlement explicitly.
53
94
 
@@ -189,14 +230,29 @@ Extension tool authority and final external access remain host decisions.
189
230
 
190
231
  ## Host metadata
191
232
 
233
+ Tool display payloads use `SessionMessage.data`, directly, not `value.details`
234
+ or a `data.details` envelope. Woodstock stores the same payload on each tool
235
+ outcome/completed-message entry's `data`; model context and compaction inputs
236
+ use only the message content. Recovery can reconstruct a tool's application
237
+ result without putting its display payload into the next model request. Images
238
+ remain model image content; their display metadata is application data. Live
239
+ output counters use the tool event's `result.data`.
240
+
241
+ `data` is independent of host `meta` even when their keys overlap. It is not
242
+ host attribution and does not inherit the 4096-byte metadata cap. The ordinary
243
+ bounded Session read still accounts for the complete projected payload.
244
+ Woodstock schema 3 refuses older preview stores instead of migrating them on
245
+ open; the host retains custody of incompatible storage. This is a storage
246
+ contract, not permission to reset or migrate any live data.
247
+
192
248
  A host attaches its own data to a prompt or operator line, such as who sent it
193
249
  or which channel it came from, with `agent.withMeta(meta)`. Shiitake checks the
194
250
  value against the host's `meta.schema`, caps it at 4096 bytes of JSON, stores it
195
- beside the message and returns it as `SessionMessage.meta`. It never reads it.
196
- Only the in-process owner returned by `Shiitake.make` has `withMeta`: no request
197
- body can carry metadata, because every command schema is closed. Over HTTP the
198
- host's own middleware sets the `shiitakeMeta` Hono variable, and the session
199
- resolver receives it:
251
+ beside the message and returns it as `SessionMessage.meta`. It does not own the
252
+ metadata's domain grammar. Only the in-process owner returned by `Shiitake.make`
253
+ has `withMeta`: no request body can carry metadata, because every command schema
254
+ is closed. Over HTTP the host's own middleware sets the `shiitakeMeta` Hono
255
+ variable, and the session resolver receives it:
200
256
 
201
257
  ```ts
202
258
  const routes = createShiitakeHttpRoutes(
@@ -222,11 +278,32 @@ to `ShiitakeHost.acceptMail(mail, meta)`; a mail's sender cannot set it, and a
222
278
  reply never carries the settled work's metadata (see
223
279
  [Delegated replies](#delegated-replies)). A retried request id replays only with
224
280
  the same metadata. A Cloudflare owner exposes its whole HTTP surface (Session
225
- routes, browser and ACP) as the protected `shiitakeApp()` Hono app, so a host
226
- mounts it behind its own identity middleware; ACP receives each request's
227
- metadata, so a host can serve each author over `withMeta`. The host's metadata
228
- schema may be an Effect schema or any synchronous Standard Schema, such as
229
- Zod 4. [Host metadata tests](test/host-meta.test.ts) cover each rule.
281
+ routes and ACP) as the protected `shiitakeApp()` Hono app, so a host mounts it
282
+ behind its own identity middleware; ACP receives each request's metadata, so a
283
+ host can serve each author over `withMeta`. The host's metadata schema may be an
284
+ Effect schema or any synchronous Standard Schema, such as Zod 4.
285
+
286
+ For a multi-author host, `meta.identityPath` selects the host's stable principal
287
+ ID using SQLite's JSON decoder (for example, `$.author.id`). On a
288
+ `withMeta`-bound Session, `latestPending()` returns just that principal's newest
289
+ owner-admitted pending prompt, or `null`. It is independent of the bounded
290
+ oldest-first pending page and preserves the exact text, supported images and
291
+ metadata. Steers and follow-ups are eligible; extension work, compactions and
292
+ started commands are not.
293
+
294
+ The same identity check protects `cancel` and raw
295
+ `command({ type: "cancel", ... })`, including Accepted replay after reopening.
296
+ Display names are not identity. The host must authenticate and bind each
297
+ request, and recheck live Agent/Session access before forwarding it. An unbound
298
+ in-process owner retains operational cancellation authority. A single-user Local
299
+ host need not configure `identityPath`. Pending-only cancellation remains
300
+ `cancel({ commandId, onlyIfPending: true })`; lookup does not reserve the work,
301
+ so a claim race can still return TooLate.
302
+ [Host metadata tests](test/host-meta.test.ts) cover each rule.
303
+
304
+ A `ShiitakeDO` subclass serves its own routes in front of Shiitake's by
305
+ overriding the protected `hostFetch(request)`: it returns a response, or
306
+ `undefined` to let Shiitake serve the request.
230
307
 
231
308
  Cloudflare hosts may supply `initialize(extensions)` to commit an ordinary
232
309
  Agent-scope extension command before queued or host work resumes. Failure closes
@@ -252,23 +329,58 @@ are the same pieces for a host that composes its own store. See
252
329
  [Run it on Node](docs/site/run/node.mdx) and the
253
330
  [Node host tests](test/node-host.test.ts).
254
331
 
255
- The `/agent-control` source exposes `agents.create({requestId, model?})`,
256
- `agents.setModel({agentId, model})` and `agents.models({})` when its host
257
- authorizes those operations. Models use `provider/model` spelling and must be
258
- offered by that host; `agents.models` returns at most 200 offered addresses from
259
- signed-in or configured providers. A host model refusal reaches the caller as a
260
- `CapabilityFailed` diagnostic such as `model:rejected: …`, while other failures
261
- propagate unchanged. The `/model-preference` resolver orders explicit Session,
262
- explicit Agent, the person's last manual switch, Team default, then available
263
- login. Hosts own those stored layers and credential admission: choosing a model
264
- never bypasses an owner's Team or Agent key-source restriction. A host can
265
- refuse an unrunnable send before acceptance; `agents.wait` includes the failed
266
- run's bounded diagnostic so callers can explain login or model-selection
267
- problems. For a completed command, `agents.wait` also returns the command's
268
- final assistant `text`, at most 16,384 characters, with `truncated` set when it
269
- was cut; failed, cancelled and interrupted commands return no text, and
270
- `agents.read` stays the full bounded Session read. Hosted ACP sessions use the
271
- Agent and Team layers; they do not select a person's saved model preference.
332
+ The bound runtime's pending-work answer includes BirdDog's Carrier-owned reply
333
+ retries. Its next wake is the earliest extension timer or owed reply delivery,
334
+ so an otherwise idle reconciliation cannot erase a mail retry timer. Reopening
335
+ before a retained reply's due time schedules its future delivery without a
336
+ client request.
337
+
338
+ The agent-control source offers
339
+ `agents.send({agentId, sessionId, requestId, text, delivery})` and
340
+ `agents.recall({agentId, sessionId, requestId})` only when the host supplies the
341
+ corresponding request-owning callback. Choose a nonempty caller request ID of at
342
+ most 256 UTF-8 bytes before sending; reuse it for retries or recovery after a
343
+ lost acceptance response. The host scopes it to the sending Agent and invoking
344
+ Session and the target Agent and Session. Model input cannot supply the invoking
345
+ Session or override the pending-only recall guard. Local replay uses that caller
346
+ identity, not the current tool ID or model program bytes. Recall cancels only
347
+ pending work: `accepted` names the known command, `too_late` names active or
348
+ settled work without aborting it, and `unknown` carries no invented command ID.
349
+ An unknown recall still retains the target owner's late-admission fence.
350
+
351
+ The `/agent-control` source exposes
352
+ `agents.create({requestId, name?, model?, reasoning?})`,
353
+ `agents.setModel({agentId, model, reasoning?})` and `agents.models({})` when its
354
+ host authorizes those operations. `name` labels the new Agent and `reasoning`
355
+ (`minimal` to `max`, one of `modelReasoningLevels`) needs a `model`.
356
+ `agents.create` returns the Agent's `name`, the requested `model` and
357
+ `reasoning` (the stored default; absent when it inherits), and the
358
+ `workingDirectory` its tools use; `agents.list` reports the same facts for
359
+ existing Agents. A host that can archive also accepts `archived: true` there to
360
+ list only the archived ones (other hosts refuse that input). A host can offer
361
+ `agents.archive({agentId})` and `agents.unarchive`: an Agent archiving an Agent
362
+ it created hides it from lists and delegation without deleting anything, and the
363
+ host refuses any other target, the caller itself, or an Agent with a running
364
+ command or delegated work still waiting. Each refusal, and a send to an archived
365
+ Agent, reaches the caller as a `CapabilityFailed` diagnostic such as
366
+ `archive:not_creator: …`, `archive:self`, `archive:running`, `archive:pending`,
367
+ `archive:unreadable` (its store predates the schema) or `archive:archived`.
368
+ `agents.wait` accepts `timeoutMs` from 1 to 30000. Models use `provider/model`
369
+ spelling and must be offered by that host; `agents.models` returns at most 200
370
+ offered addresses from signed-in or configured providers. A host model refusal
371
+ reaches the caller as a `CapabilityFailed` diagnostic such as
372
+ `model:rejected: …`, while other failures propagate unchanged. The
373
+ `/model-preference` resolver orders explicit Session, explicit Agent, the
374
+ person's last manual switch, Team default, then available login. Hosts own those
375
+ stored layers and credential admission: choosing a model never bypasses an
376
+ owner's Team or Agent key-source restriction. A host can refuse an unrunnable
377
+ send before acceptance; `agents.wait` includes the failed run's bounded
378
+ diagnostic so callers can explain login or model-selection problems. For a
379
+ completed command, `agents.wait` also returns the command's final assistant
380
+ `text`, at most 16,384 characters, with `truncated` set when it was cut; failed,
381
+ cancelled and interrupted commands return no text, and `agents.read` stays the
382
+ full bounded Session read. Hosted ACP sessions use the Agent and Team layers;
383
+ they do not select a person's saved model preference.
272
384
 
273
385
  ## API and examples
274
386
 
@@ -361,8 +473,17 @@ cell's ID is its positive safe integer sequence written as decimal text.
361
473
  Producer history commits in the same owner transaction as its state change,
362
474
  deduplicates unchanged state, and retains at most thirty-two events and 32 KiB
363
475
  with an explicit omitted count. A real command ID anchors cells after its last
364
- loaded durable row; an unloaded anchor stays hidden until its page loads. Null
365
- anchors appear under **Extension changes**.
476
+ loaded durable row; an unloaded anchor stays hidden until its page loads.
477
+ Alternatively, a cell may supply `afterSequence` with `commandId: null` to
478
+ choose a fixed committed Session position. This is not its producer-local event
479
+ sequence. Zero places it before the first Session entry; unloaded positions stay
480
+ hidden until their page loads. Without either anchor, a cell appears under
481
+ **Extension changes**. An event may not choose both anchor kinds.
482
+
483
+ Goal uses the fixed-position addition: its host reads `ctx.sessionPosition`
484
+ inside the ending transaction and persists that position. Later output from the
485
+ same running work cannot move the ending line. Renderers resolve it using the
486
+ same row visibility policy and split tool groups at that position.
366
487
 
367
488
  The frozen client V1 contract includes fields, placements, bounds, identities,
368
489
  ordering, admission, dispatch, detach, and history laws. Host extension V0 and
@@ -1,10 +1,35 @@
1
1
  import { type CapabilitySource, type CapabilitySession } from "@fungi.computer/mycelium";
2
- import type { Accepted, ShiitakeAgent, ShiitakeSession } from "./client.js";
2
+ import type { Accepted, CancelResult, ShiitakeAgent, ShiitakeSession } from "./client.js";
3
3
  import { type ModelPreference } from "./model-preference.js";
4
+ /**
5
+ * Why a host refuses an archive or restore: the caller did not create the
6
+ * Agent, is the Agent, the Agent has a running command or delegated work still
7
+ * waiting to report back, its store predates the current schema, or the Agent
8
+ * is archived.
9
+ */
10
+ export declare const archiveRefusalReasons: readonly ["not_creator", "self", "running", "pending", "unreadable", "archived"];
11
+ /** One reason in `archiveRefusalReasons`. */
12
+ export type ArchiveRefusalReason = (typeof archiveRefusalReasons)[number];
13
+ /**
14
+ * A host's refusal to archive or restore an Agent, or to work with one that is
15
+ * archived. It reaches the caller as a failure of the operation it refused.
16
+ */
17
+ export declare class AgentArchiveRefused extends Error {
18
+ readonly reason: ArchiveRefusalReason;
19
+ readonly name = "AgentArchiveRefused";
20
+ constructor(reason: ArchiveRefusalReason, message: string);
21
+ }
4
22
  /** One existing Agent visible within the caller's authorized project or Team. */
5
23
  export type AgentControlAgent = Readonly<{
6
24
  agentId: string;
25
+ /** The Agent's display name; hosts without a chosen name use the id. */
7
26
  name: string;
27
+ /** Creating Agent, not the human credential owner; absent only when unreadable. */
28
+ createdBy?: string | null;
29
+ /** The model the host reports for this Agent, when it knows one. */
30
+ model?: ModelPreference;
31
+ /** Directory the Agent's tools work in, when the host has one. */
32
+ workingDirectory?: string;
8
33
  }>;
9
34
  /** One host-offered model usable as an Agent's create or setModel choice. */
10
35
  export type AgentControlModel = Readonly<{
@@ -19,8 +44,21 @@ export type AgentDelegationInput = Readonly<{
19
44
  agentId: string;
20
45
  /** Target conversation on that Agent. */
21
46
  sessionId: string;
22
- /** Work to admit as a follow-up prompt. */
47
+ /** Work to admit with the requested delivery. */
23
48
  text: string;
49
+ /** Caller-owned identity reused for retries and request-based recall. */
50
+ requestId: string;
51
+ /** Steer the live turn or queue follow-up work with a durable reply. */
52
+ delivery: "steer" | "followUp";
53
+ }>;
54
+ /** Exact authorized destination and caller's original send identity. */
55
+ export type AgentRecallInput = Readonly<{
56
+ /** The authorized target Agent. */
57
+ agentId: string;
58
+ /** The target Session named by the original send. */
59
+ sessionId: string;
60
+ /** The original caller-owned request key, before host scoping. */
61
+ requestId: string;
24
62
  }>;
25
63
  /** Host-only identity and admitted command metadata for one delegated send. */
26
64
  export type AgentDelegationInvocation = Readonly<{
@@ -32,20 +70,44 @@ export type AgentDelegationInvocation = Readonly<{
32
70
  }>;
33
71
  /** Host-owned discovery and per-operation access to ordinary Agents. */
34
72
  export type AgentControlDirectory = Readonly<{
35
- /** Return Agents authorized by the host's current project or Team scope. */
36
- list: (signal: AbortSignal) => Promise<readonly AgentControlAgent[]>;
37
- /** Follow-up delegation with durable replies to the invoking Session. */
73
+ /**
74
+ * Return Agents authorized by the host's current project or Team scope.
75
+ * Archived Agents are left out unless `archived` asks for only those.
76
+ */
77
+ list: (signal: AbortSignal, options?: Readonly<{
78
+ archived?: boolean;
79
+ }>) => Promise<readonly AgentControlAgent[]>;
80
+ /** Host-scoped sends; follow-up work replies to the invoking Session. */
38
81
  send?: (input: AgentDelegationInput, sourceSessionId: string, signal: AbortSignal, invocation?: AgentDelegationInvocation) => Promise<Accepted>;
82
+ /** Recall under the same host-owned request identity as send. Never abort active work. */
83
+ recall?: (input: AgentRecallInput, sourceSessionId: string, signal: AbortSignal) => Promise<CancelResult>;
39
84
  /** Present only when this host authorizes ordinary Agent creation. */
40
85
  create?: (input: Readonly<{
41
86
  requestId: string;
87
+ name?: string;
42
88
  model?: ModelPreference;
89
+ /**
90
+ * Installed extensions to enable on the new Agent. The host refuses any
91
+ * the creating Agent does not itself hold; none are copied implicitly.
92
+ */
93
+ extensions?: readonly string[];
43
94
  }>, signal: AbortSignal) => Promise<AgentControlAgent>;
44
95
  /** Present only when the host authorizes changing an Agent's future default. */
45
96
  setModel?: (input: Readonly<{
46
97
  agentId: string;
47
98
  model: ModelPreference;
48
99
  }>, signal: AbortSignal) => Promise<void>;
100
+ /**
101
+ * Present only when the host lets an Agent archive an Agent it created. The
102
+ * host refuses (AgentArchiveRefused) any other target; nothing is deleted.
103
+ */
104
+ archive?: (input: Readonly<{
105
+ agentId: string;
106
+ }>, signal: AbortSignal) => Promise<void>;
107
+ /** Restore an archived Agent; the same Agent-it-created rule as `archive`. */
108
+ unarchive?: (input: Readonly<{
109
+ agentId: string;
110
+ }>, signal: AbortSignal) => Promise<void>;
49
111
  /** Present only when the host can list models offered by its signed-in providers. */
50
112
  models?: (signal: AbortSignal) => Promise<readonly AgentControlModel[]>;
51
113
  /** Optional host admission check before accepting a model-backed send. */
@@ -68,5 +130,15 @@ export declare function waitForAgentTerminal(session: ShiitakeSession, commandId
68
130
  diagnostic: string | null;
69
131
  meta?: import("./extensions.js").Json;
70
132
  }>>;
133
+ /**
134
+ * A host's refusal of an Agent creating an Agent: the creator asked to give the
135
+ * created Agent more than it holds, or the host cannot tell which Agent is
136
+ * creating. It reaches the caller as an `agents.create` failure.
137
+ */
138
+ export declare class AgentCreateRefused extends Error {
139
+ readonly reason: "exceeds_creator" | "no_creator";
140
+ readonly name = "AgentCreateRefused";
141
+ constructor(reason: "exceeds_creator" | "no_creator", message: string);
142
+ }
71
143
  /** Compose one authorized Agent-control projection for a single run lease. */
72
144
  export declare function createAgentControlSource(directory: AgentControlDirectory): CapabilitySource;