@fungi.computer/shiitake 0.0.0-stage → 0.0.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.
- package/LICENSE +21 -0
- package/README.md +454 -2
- package/dist/agar-extension.d.ts +9 -0
- package/dist/agar-extension.js +38 -0
- package/dist/agent-control.d.ts +72 -0
- package/dist/agent-control.js +431 -0
- package/dist/client-entry.d.ts +211 -0
- package/dist/client-entry.js +101 -0
- package/dist/client-wire.d.ts +199 -0
- package/dist/client-wire.js +271 -0
- package/dist/client.d.ts +439 -0
- package/dist/client.js +4 -0
- package/dist/cloudflare.d.ts +220 -0
- package/dist/cloudflare.js +531 -0
- package/dist/effect.d.ts +42 -0
- package/dist/effect.js +20 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.js +81 -0
- package/dist/extension-client.d.ts +38 -0
- package/dist/extension-client.js +56 -0
- package/dist/extension-contract.d.ts +73 -0
- package/dist/extension-contract.js +11 -0
- package/dist/extensions.d.ts +589 -0
- package/dist/extensions.js +263 -0
- package/dist/fleet.d.ts +297 -0
- package/dist/fleet.js +515 -0
- package/dist/hosted.d.ts +133 -0
- package/dist/hosted.js +265 -0
- package/dist/http-routes.d.ts +772 -0
- package/dist/http-routes.js +242 -0
- package/dist/http.d.ts +1 -0
- package/dist/http.js +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +13 -0
- package/dist/internal/accepted-run-executor.d.ts +23 -0
- package/dist/internal/accepted-run-executor.js +129 -0
- package/dist/internal/admission-door.d.ts +75 -0
- package/dist/internal/admission-door.js +105 -0
- package/dist/internal/agent-close.d.ts +4 -0
- package/dist/internal/agent-close.js +42 -0
- package/dist/internal/browser-sessions.d.ts +31 -0
- package/dist/internal/browser-sessions.js +173 -0
- package/dist/internal/client-boundary.d.ts +262 -0
- package/dist/internal/client-boundary.js +202 -0
- package/dist/internal/compaction/compaction.d.ts +54 -0
- package/dist/internal/compaction/compaction.js +292 -0
- package/dist/internal/compaction/session-compaction.d.ts +69 -0
- package/dist/internal/compaction/session-compaction.js +330 -0
- package/dist/internal/compaction/settings.d.ts +11 -0
- package/dist/internal/compaction/settings.js +40 -0
- package/dist/internal/compaction/utils.d.ts +45 -0
- package/dist/internal/compaction/utils.js +319 -0
- package/dist/internal/contracts.d.ts +235 -0
- package/dist/internal/contracts.js +1 -0
- package/dist/internal/coordinator.d.ts +18 -0
- package/dist/internal/coordinator.js +362 -0
- package/dist/internal/document-codec.d.ts +11 -0
- package/dist/internal/document-codec.js +39 -0
- package/dist/internal/effect-client.d.ts +13 -0
- package/dist/internal/effect-client.js +102 -0
- package/dist/internal/effect-contracts.d.ts +236 -0
- package/dist/internal/effect-contracts.js +2 -0
- package/dist/internal/extension-command-registry.d.ts +11 -0
- package/dist/internal/extension-command-registry.js +29 -0
- package/dist/internal/extension-command-tools.d.ts +17 -0
- package/dist/internal/extension-command-tools.js +50 -0
- package/dist/internal/extension-context.d.ts +25 -0
- package/dist/internal/extension-context.js +35 -0
- package/dist/internal/extension-definitions.d.ts +5 -0
- package/dist/internal/extension-definitions.js +6 -0
- package/dist/internal/extension-hook.d.ts +25 -0
- package/dist/internal/extension-hook.js +46 -0
- package/dist/internal/extension-roster.d.ts +23 -0
- package/dist/internal/extension-roster.js +228 -0
- package/dist/internal/extension-runtime.d.ts +63 -0
- package/dist/internal/extension-runtime.js +1004 -0
- package/dist/internal/failure.d.ts +2 -0
- package/dist/internal/failure.js +9 -0
- package/dist/internal/host-meta.d.ts +41 -0
- package/dist/internal/host-meta.js +39 -0
- package/dist/internal/json-value.d.ts +4 -0
- package/dist/internal/json-value.js +3 -0
- package/dist/internal/model-acquisition.d.ts +21 -0
- package/dist/internal/model-acquisition.js +98 -0
- package/dist/internal/model-preference.d.ts +21 -0
- package/dist/internal/model-preference.js +20 -0
- package/dist/internal/observation-kernel.d.ts +28 -0
- package/dist/internal/observation-kernel.js +169 -0
- package/dist/internal/promise-facade.d.ts +18 -0
- package/dist/internal/promise-facade.js +172 -0
- package/dist/internal/run-scope.d.ts +27 -0
- package/dist/internal/run-scope.js +214 -0
- package/dist/internal/runtime-coordinator.d.ts +34 -0
- package/dist/internal/runtime-coordinator.js +233 -0
- package/dist/internal/runtime-core.d.ts +19 -0
- package/dist/internal/runtime-core.js +39 -0
- package/dist/internal/runtime-reconciliation.d.ts +18 -0
- package/dist/internal/runtime-reconciliation.js +162 -0
- package/dist/internal/session-context.d.ts +11 -0
- package/dist/internal/session-context.js +67 -0
- package/dist/internal/session-status.d.ts +10 -0
- package/dist/internal/session-status.js +52 -0
- package/dist/internal/woodstock/agent-reply.d.ts +25 -0
- package/dist/internal/woodstock/agent-reply.js +67 -0
- package/dist/internal/woodstock/client-projection.d.ts +29 -0
- package/dist/internal/woodstock/client-projection.js +512 -0
- package/dist/internal/woodstock/compaction-activity.d.ts +17 -0
- package/dist/internal/woodstock/compaction-activity.js +32 -0
- package/dist/internal/woodstock/cursor.d.ts +9 -0
- package/dist/internal/woodstock/cursor.js +44 -0
- package/dist/internal/woodstock/extension-store.d.ts +72 -0
- package/dist/internal/woodstock/extension-store.js +262 -0
- package/dist/internal/woodstock/fleet-store.d.ts +32 -0
- package/dist/internal/woodstock/fleet-store.js +93 -0
- package/dist/internal/woodstock/identities.d.ts +6 -0
- package/dist/internal/woodstock/identities.js +11 -0
- package/dist/internal/woodstock/index.d.ts +170 -0
- package/dist/internal/woodstock/index.js +546 -0
- package/dist/internal/woodstock/progress.d.ts +32 -0
- package/dist/internal/woodstock/progress.js +89 -0
- package/dist/internal/woodstock/run-recovery.d.ts +8 -0
- package/dist/internal/woodstock/run-recovery.js +95 -0
- package/dist/internal/woodstock/session-attention.d.ts +16 -0
- package/dist/internal/woodstock/session-attention.js +88 -0
- package/dist/internal/woodstock/session-documents.d.ts +18 -0
- package/dist/internal/woodstock/session-documents.js +51 -0
- package/dist/internal/woodstock/session-entry.d.ts +478 -0
- package/dist/internal/woodstock/session-entry.js +484 -0
- package/dist/internal/woodstock/session-grants.d.ts +24 -0
- package/dist/internal/woodstock/session-grants.js +84 -0
- package/dist/internal/woodstock/session-inbox.d.ts +56 -0
- package/dist/internal/woodstock/session-inbox.js +307 -0
- package/dist/internal/woodstock/session-store.d.ts +432 -0
- package/dist/internal/woodstock/session-store.js +2006 -0
- package/dist/internal/woodstock/storage-admission.d.ts +14 -0
- package/dist/internal/woodstock/storage-admission.js +44 -0
- package/dist/model-preference.d.ts +20 -0
- package/dist/model-preference.js +30 -0
- package/dist/node.d.ts +64 -0
- package/dist/node.js +256 -0
- package/dist/remote-client.d.ts +11 -0
- package/dist/remote-client.js +298 -0
- package/dist/session-attention.d.ts +35 -0
- package/dist/session-attention.js +22 -0
- package/dist/session-documents.d.ts +28 -0
- package/dist/session-documents.js +1 -0
- package/dist/testing.d.ts +54 -0
- package/dist/testing.js +215 -0
- package/docs/api/README.md +26 -0
- package/docs/api/agar-extension.md +40 -0
- package/docs/api/agent-control.md +151 -0
- package/docs/api/client-entry.md +344 -0
- package/docs/api/client.md +1112 -0
- package/docs/api/cloudflare.md +500 -0
- package/docs/api/effect.md +904 -0
- package/docs/api/extensions.md +2003 -0
- package/docs/api/fleet.md +706 -0
- package/docs/api/hosted.md +382 -0
- package/docs/api/http.md +111 -0
- package/docs/api/index.md +1116 -0
- package/docs/api/model-preference.md +151 -0
- package/docs/api/node.md +142 -0
- package/docs/api/testing.md +250 -0
- package/package.json +130 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jamstack Consulting LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,455 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Shiitake (`@fungi.computer/shiitake`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shiitake runs durable Agent conversations. A Session holds accepted work,
|
|
4
|
+
messages and observations, while the host supplies storage, models, tools and
|
|
5
|
+
the wake that runs queued work.
|
|
6
|
+
|
|
7
|
+
There are three ways to run it:
|
|
8
|
+
|
|
9
|
+
- **In your code**: install this package and host Agents yourself, on Node for
|
|
10
|
+
tests or in a
|
|
11
|
+
[Cloudflare Durable Object](https://shiitake.shiit.app/run/cloudflare/).
|
|
12
|
+
- **On your machine**: the [`fungi` CLI](https://docs.fungi.computer/install/)
|
|
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.
|
|
16
|
+
|
|
17
|
+
To add your own behaviour, start the extension guide at
|
|
18
|
+
[Your first extension](https://shiitake.shiit.app/extensions/first-extension/).
|
|
19
|
+
|
|
20
|
+
## Set up
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm install @fungi.computer/shiitake
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The package ships ESM only and depends on Effect, Zod, and Hono, plus the Fungi
|
|
27
|
+
packages [Cairn](../cairn/README.md), [Mule](../mule/README.md),
|
|
28
|
+
[Mycelium](../mycelium/README.md), [Watchdog](../watchdog/README.md),
|
|
29
|
+
[Bird Dog](../bird-dog/README.md) and Knapsack, all installed automatically.
|
|
30
|
+
|
|
31
|
+
`Shiitake.make(options)` is the Promise constructor. The Effect 4 constructor is
|
|
32
|
+
`make` from `@fungi.computer/shiitake/effect`. Both use the same owner. The host
|
|
33
|
+
supplies:
|
|
34
|
+
|
|
35
|
+
| Input | Responsibility |
|
|
36
|
+
| -------------- | ------------------------------------------------------------------------------------------------------ |
|
|
37
|
+
| `store` | A native SQLite owner with scalar rows and synchronous transactions. |
|
|
38
|
+
| `runtime` | Bind reconciliation, commit mutations with a wake guarantee, schedule work and close the registration. |
|
|
39
|
+
| `model` | Acquire a Pi model and its stream, then release them. The host owns selection and credentials. |
|
|
40
|
+
| `instructions` | Load an instruction snapshot and revision for the run. |
|
|
41
|
+
| `extensions` | An explicit roster and capability grants. Use an empty roster and grants when none are needed. |
|
|
42
|
+
| `tools` | Optional Mycelium modules, sources, the host's sandbox and `access` grants passed down as data. |
|
|
43
|
+
| `meta` | Optional schema for the opaque metadata the host attaches to prompts and operator lines. |
|
|
44
|
+
|
|
45
|
+
Construction needs an owner and a runtime host that meet their transaction and
|
|
46
|
+
wake contracts. Existing host fixtures show deterministic and native adapters.
|
|
47
|
+
|
|
48
|
+
## Quick start without a provider account
|
|
49
|
+
|
|
50
|
+
Node 24 or newer provides the SQLite database for the public testing helper.
|
|
51
|
+
This runs the real durable Agent with a deterministic faux model; no credentials
|
|
52
|
+
or background timer are needed. Drive settlement explicitly.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { memoryHost } from "@fungi.computer/shiitake/testing";
|
|
56
|
+
|
|
57
|
+
const host = await memoryHost();
|
|
58
|
+
try {
|
|
59
|
+
const receipt = await host.agent.session("example-session").send("Hello", {
|
|
60
|
+
requestId: "example-first-prompt",
|
|
61
|
+
});
|
|
62
|
+
const snapshot = await host.settle("example-session");
|
|
63
|
+
console.log(receipt.status, snapshot.terminals.at(-1)?.outcome);
|
|
64
|
+
} finally {
|
|
65
|
+
await host.close();
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`memoryHost({ owner, model, extensions, tools })` accepts canonical inputs and
|
|
70
|
+
borrows a supplied owner without closing its database. `extensions` may be a
|
|
71
|
+
plain list; the test host then grants each extension exactly what it requests
|
|
72
|
+
(`Shiitake.make` always takes explicit grants). `script` replaces `model` and
|
|
73
|
+
`tools`: strings are replies, `callTool("bookmarks.add", input)` is a tool call
|
|
74
|
+
that a scripted sandbox runs through the admitted operation, and
|
|
75
|
+
`echoSystemPrompt()` replies with the system prompt the model received.
|
|
76
|
+
`fauxModelSource(replies)` supplies deterministic responses for each model
|
|
77
|
+
acquisition. `reconcile()` drives one canonical tick;
|
|
78
|
+
`settle(sessionId, maxTicks)` accepts a 1–1,000 tick budget (default 1,000) and
|
|
79
|
+
refuses when it is exhausted. This manually driven helper does not assert host
|
|
80
|
+
wake delivery; the native runtime-law tests qualify that scheduling contract.
|
|
81
|
+
The helper is **not isolation**: trusted callbacks retain the process's
|
|
82
|
+
privileges, and submitted JavaScript is never evaluated.
|
|
83
|
+
|
|
84
|
+
Production callers use `Shiitake.make(options)` with their storage and wake
|
|
85
|
+
owner. Keep that host open while it owns active work. Closing it stops runtime
|
|
86
|
+
resources; it does not erase SQLite data or turn acceptance into a completed
|
|
87
|
+
reply.
|
|
88
|
+
|
|
89
|
+
## Accept, execute and observe
|
|
90
|
+
|
|
91
|
+
An accepted prompt returns `status: "accepted"` and an owner-issued `commandId`
|
|
92
|
+
after the durable commit. Repeating the same request identity and input replays
|
|
93
|
+
the receipt. Changing the input under that identity is a conflict.
|
|
94
|
+
|
|
95
|
+
The runtime wakes reconciliation, acquires run resources, executes the model and
|
|
96
|
+
tools, releases resources and records settlement. The host owns provider
|
|
97
|
+
configuration and retry policy. Shiitake owns durable Session facts and work.
|
|
98
|
+
|
|
99
|
+
`session.read()` returns a bounded baseline. `session.watch()` owns a baseline
|
|
100
|
+
and live changes resource. Close the watch when its consumer leaves. Addressing
|
|
101
|
+
a Session performs no I/O. A client uses `createShiitakeClient` from the
|
|
102
|
+
`/client` entry with the host's authorized transport. Releasing that client does
|
|
103
|
+
not cancel host work.
|
|
104
|
+
|
|
105
|
+
Cancellation targets an accepted `commandId`. `too_late` is an ordinary outcome
|
|
106
|
+
when that work can no longer be withdrawn. `session.abort()` atomically requests
|
|
107
|
+
cancellation of the running turn and every queued prompt in that Session.
|
|
108
|
+
Cancelled prompts retain their text for resubmission. Neither a cancelled
|
|
109
|
+
observation nor a closed browser proves a tool has stopped.
|
|
110
|
+
|
|
111
|
+
## Extensions and authority
|
|
112
|
+
|
|
113
|
+
Use `defineExtension("id")` from `/extensions`. The version defaults to `0.0.0`;
|
|
114
|
+
pass `{ id, version }` when a behaviour change is not visible in the schemas,
|
|
115
|
+
config or requested capabilities (for example a fixed hook). The version joins
|
|
116
|
+
those in the extension's revision; a recorded stop persists until the revision
|
|
117
|
+
changes or the host resumes the extension. Configuration, collections and
|
|
118
|
+
documents are declared before callbacks.
|
|
119
|
+
`.state({ name: defineCollection(...) })` declares state version 1; pass
|
|
120
|
+
`{ version, collections, migrations }` when a row schema changes. The host's
|
|
121
|
+
grants are separate from the definition's requests. Product feature names belong
|
|
122
|
+
to the host roster.
|
|
123
|
+
|
|
124
|
+
`context.state.read((s) => ...)` reads rows synchronously outside a transaction,
|
|
125
|
+
for example in a prompt section; `context.state.update` writes. A projection's
|
|
126
|
+
`read` returns the value itself (or an `Option`; `undefined` publishes none).
|
|
127
|
+
The `tools` builder's third argument exposes a declared command to the model:
|
|
128
|
+
`commands.tool("add", { description })` is a Mycelium operation that runs the
|
|
129
|
+
same handler in the same transaction, scoped to the run's Session.
|
|
130
|
+
|
|
131
|
+
Commands, settled hooks and timer hooks run synchronously within the owner
|
|
132
|
+
transaction. Prompt and tool builders run outside that write transaction.
|
|
133
|
+
Activation resources use the Effect scope. An extension failure records a stop
|
|
134
|
+
reason. Resuming it replays missed settled work through its cursor.
|
|
135
|
+
|
|
136
|
+
`context.send({ sessionId, requireExistingSession: true, ... })` opts into an
|
|
137
|
+
existing target: the admission transaction rejects an absent Session with
|
|
138
|
+
`AdmissionError` reason `closed`, without creating it. Leave the condition out
|
|
139
|
+
when creating the addressed Session is intended. Automated continuations use the
|
|
140
|
+
condition to prevent recreating a Session after deletion.
|
|
141
|
+
|
|
142
|
+
An extension declaring `attention: true` can request the `attention` grant.
|
|
143
|
+
`context.attention.set(sessionId, item)` and `clear(sessionId, id)` share its
|
|
144
|
+
owner transaction and publish after commit. Items have `id`, `kind`, `summary`
|
|
145
|
+
(at most 200 characters), `since` and optional `expiresAt`; each Session carries
|
|
146
|
+
at most 64. An owner may retain at most 4,096 outstanding items across Sessions;
|
|
147
|
+
clearing releases capacity. Public observations qualify ids with `extensionId`.
|
|
148
|
+
Open attention makes the inbox `needs_you`, ahead of running or settled work.
|
|
149
|
+
Stopped owners are excluded until resumed, and owners without a current grant
|
|
150
|
+
are excluded until the grant returns. Expiry is display metadata; the
|
|
151
|
+
extension's timer owns clearing, and restarting does not discard pending
|
|
152
|
+
attention. Clearing an absent item, including after Session deletion, is
|
|
153
|
+
idempotent; setting an item requires an existing Session.
|
|
154
|
+
|
|
155
|
+
Clients bind an extension contract with `bindSessionExtension` or
|
|
156
|
+
`bindAgentExtension` from `/client`. Projection slots describe observed state,
|
|
157
|
+
not assumed completion. See the
|
|
158
|
+
[prompt/tool test](test/extension-prompt-sections.test.ts),
|
|
159
|
+
[state binding test](test/extension-state-binding.test.ts) and
|
|
160
|
+
[close test](test/c2-extension-close-orchestrator.test.ts).
|
|
161
|
+
|
|
162
|
+
An extension may request the exclusive `files` grant and return Knapsack-minted
|
|
163
|
+
`FileTool`s from `files(context, run)`. Core captures the tools once per run,
|
|
164
|
+
passes them to Mycelium beside `execute`, and records their names in the
|
|
165
|
+
execution protocol digest. A second granted holder is refused. This contribution
|
|
166
|
+
adds no shared Files module to `execute`; explicit Computer capabilities remain
|
|
167
|
+
independent.
|
|
168
|
+
|
|
169
|
+
Shiitake holds no permission logic. Tool authors label each operation `read` or
|
|
170
|
+
`write` (and optionally `confirm`); the host owns every grant decision and
|
|
171
|
+
delivers it down as versioned data, and Mycelium decides each call.
|
|
172
|
+
`tools.access.grants` is the Agent-wide default. The in-process owner returned
|
|
173
|
+
by `Shiitake.make` delivers one Session's grants with
|
|
174
|
+
`agent.grants.deliver(sessionId, { version, grants })`, synchronously; code
|
|
175
|
+
inside a Cloudflare owner also calls `deliverSessionGrantsToStorage` while its
|
|
176
|
+
runtime is cold. Versions never move back: an older version is refused, and the
|
|
177
|
+
same version with other grants replaces the stored ones, so a host that
|
|
178
|
+
recomputes its decision never leaves the old grant in place. Delivered grants
|
|
179
|
+
override the default key by key, and Mycelium reads them at every call, so a
|
|
180
|
+
change applies to the very next call, including in queued, recovered and
|
|
181
|
+
extension-started runs. Grants are keyed by module id; a module an extension
|
|
182
|
+
built is granted by its roster grant's `grantKey` (the extension id by default),
|
|
183
|
+
and Files direct tools by `files`. Keys listed in `access.required` fail closed:
|
|
184
|
+
a Session with no delivered or default grant for them is refused. With no access
|
|
185
|
+
data at all, every tool keeps full access, so a first-time host writes no
|
|
186
|
+
permission code; a `confirm` operation is still refused unless the host supplies
|
|
187
|
+
`access.confirm`. A Files extension still requires a host tool runtime.
|
|
188
|
+
Extension tool authority and final external access remain host decisions.
|
|
189
|
+
|
|
190
|
+
## Host metadata
|
|
191
|
+
|
|
192
|
+
A host attaches its own data to a prompt or operator line, such as who sent it
|
|
193
|
+
or which channel it came from, with `agent.withMeta(meta)`. Shiitake checks the
|
|
194
|
+
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:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
const routes = createShiitakeHttpRoutes(
|
|
203
|
+
(id, meta) => (meta === undefined ? agent : agent.withMeta(meta)).session(id),
|
|
204
|
+
agent.listSessions,
|
|
205
|
+
agent.createSession,
|
|
206
|
+
agent.deleteSession,
|
|
207
|
+
() => agent.extensions,
|
|
208
|
+
);
|
|
209
|
+
const app = new Hono<ShiitakeHttpEnv>()
|
|
210
|
+
.use(async (c, next) => {
|
|
211
|
+
c.set("shiitakeMeta", await authenticatedMeta(c.req.raw));
|
|
212
|
+
await next();
|
|
213
|
+
})
|
|
214
|
+
.route("/", routes);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Every accepted command takes the same path: a prompt, a steer, an operator line,
|
|
218
|
+
a cancel and an abort each store their metadata on the entry they write, so a
|
|
219
|
+
restart loses none of it. A cancelled run's `SessionTerminal.meta` is its
|
|
220
|
+
cancellation's metadata. Addressed mail work stores the metadata its host passes
|
|
221
|
+
to `ShiitakeHost.acceptMail(mail, meta)`; a mail's sender cannot set it, and a
|
|
222
|
+
reply never carries the settled work's metadata (see
|
|
223
|
+
[Delegated replies](#delegated-replies)). A retried request id replays only with
|
|
224
|
+
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.
|
|
230
|
+
|
|
231
|
+
Cloudflare hosts may supply `initialize(extensions)` to commit an ordinary
|
|
232
|
+
Agent-scope extension command before queued or host work resumes. Failure closes
|
|
233
|
+
the incomplete runtime and leaves its durable work for a later open.
|
|
234
|
+
|
|
235
|
+
Cloudflare hosts may configure `hostJobs` to open a concurrent Watchdog lane.
|
|
236
|
+
Their `hostWork` pass stages and recovers delivery, then calls that lane's
|
|
237
|
+
`tickConcurrent`. Every wake requests Agent reconciliation and host work
|
|
238
|
+
independently; both share one durable alarm. During a live tool, its armed
|
|
239
|
+
five-second heartbeat requests delivery processing after an attention write.
|
|
240
|
+
Receiver duration and ordinary retry policy still apply. A failed pass retains
|
|
241
|
+
its retry until that pass succeeds, and close joins both active passes.
|
|
242
|
+
|
|
243
|
+
## Run it on Node
|
|
244
|
+
|
|
245
|
+
`@fungi.computer/shiitake/node` keeps one durable Agent in a SQLite file on
|
|
246
|
+
disk, on the Node event loop. `openNodeShiitake({ path, ... })` takes the same
|
|
247
|
+
model, instructions, extensions and tools as `Shiitake.make`, holds an exclusive
|
|
248
|
+
lease on the file until `close`, and returns the in-process `agent` plus its
|
|
249
|
+
Session `routes` as a Hono app to serve behind your own middleware. Reopening
|
|
250
|
+
the file resumes accepted work. `nodeRuntimeHost` and `acquireNodeStoreLease`
|
|
251
|
+
are the same pieces for a host that composes its own store. See
|
|
252
|
+
[Run it on Node](docs/site/run/node.mdx) and the
|
|
253
|
+
[Node host tests](test/node-host.test.ts).
|
|
254
|
+
|
|
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.
|
|
272
|
+
|
|
273
|
+
## API and examples
|
|
274
|
+
|
|
275
|
+
The [generated API reference](docs/api/README.md) covers the public exports in
|
|
276
|
+
[package.json](package.json):
|
|
277
|
+
|
|
278
|
+
| Entry | Use |
|
|
279
|
+
| ------------------------------------- | -------------------------------------------------------------------------------- |
|
|
280
|
+
| Root and `/effect` | Promise and Effect host construction. |
|
|
281
|
+
| `/client`, `/http` | Neutral Session clients and HTTP route composition. The host authorizes ingress. |
|
|
282
|
+
| `/cloudflare` | Durable Object storage and alarm composition, including owner-local handles. |
|
|
283
|
+
| `/extensions`, `/client-entry` | Host authoring and the independent `shiitake.client/v1` presentation contract. |
|
|
284
|
+
| `/agent-control`, `/model-preference` | Authorized Agent operations and model selection contracts. |
|
|
285
|
+
|
|
286
|
+
[Bound transport tests](test/bound-fetch-client.test.ts) exercise a client with
|
|
287
|
+
a host-supplied fetch.
|
|
288
|
+
[Restart tests](test/resume-after-restart-tool-outcomes.test.ts) exercise
|
|
289
|
+
interrupted tools against the existing replay rules. They are local proofs, not
|
|
290
|
+
a guarantee about another deployment's storage or sandbox.
|
|
291
|
+
|
|
292
|
+
## Client entries
|
|
293
|
+
|
|
294
|
+
A host selects client entries separately from its durable extension roster.
|
|
295
|
+
`defineClientEntry(contract, callbacks)` captures the projection decoder for the
|
|
296
|
+
extension. The installed entry has only `protocol`, `id`, optional `attach`, and
|
|
297
|
+
optional `contribute`. At least one callback is required. The host admits
|
|
298
|
+
exactly `shiitake.client/v1`; it does not accept the superseded client shape.
|
|
299
|
+
|
|
300
|
+
`contribute` is a synchronous, pure function of the extension's typed view. It
|
|
301
|
+
returns display-only chips, pinned panel rows, committed timeline cells, and an
|
|
302
|
+
optional waiting summary/cancel action. It has no renderer nodes, subscriptions,
|
|
303
|
+
Session transport, or action closures. Parakeet evaluates changed slots once
|
|
304
|
+
outside rendering and decodes the result at that seam. Invalid output retires
|
|
305
|
+
that entry's rows and reports its error without disabling other entries.
|
|
306
|
+
|
|
307
|
+
This illustrative author uses the same factory exercised by
|
|
308
|
+
[test/client-entry.test.ts](test/client-entry.test.ts):
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
import { ExtensionId } from "@fungi.computer/shiitake/extensions";
|
|
312
|
+
import { defineClientEntry } from "@fungi.computer/shiitake/client-entry";
|
|
313
|
+
import * as Schema from "effect/Schema";
|
|
314
|
+
|
|
315
|
+
const contract = {
|
|
316
|
+
id: ExtensionId.make("progress"),
|
|
317
|
+
commands: {},
|
|
318
|
+
projection: { schema: Schema.Struct({ title: Schema.String }) },
|
|
319
|
+
};
|
|
320
|
+
export default defineClientEntry(contract, {
|
|
321
|
+
contribute: (view) => ({
|
|
322
|
+
chips: [],
|
|
323
|
+
panel:
|
|
324
|
+
view.status === "running" && view.value !== null
|
|
325
|
+
? [{ id: "progress", title: view.value.title }]
|
|
326
|
+
: [],
|
|
327
|
+
timeline: { cells: [], omitted: 0 },
|
|
328
|
+
waiting: null,
|
|
329
|
+
}),
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Attachment authors may return `void`, a Promise, or a scoped Effect. The context
|
|
334
|
+
supplies `activity`, `signal`, and `onError`; it supplies no Session authority.
|
|
335
|
+
Each `for await` over activity creates an independent subscription with one
|
|
336
|
+
sliding latest-value slot. A slow consumer sees the latest value. The selected
|
|
337
|
+
Session's detach aborts the signal and ends every iterator, discarding buffered
|
|
338
|
+
activity. Ordinary async authors use that signal for their own resource cleanup.
|
|
339
|
+
|
|
340
|
+
Actions are `{ id, label, input? }` data from `@fungi.computer/gills`. Their IDs
|
|
341
|
+
must occur in the same entry's running advertised Whistle catalog, and input
|
|
342
|
+
must be a JSON object. Hosts execute the catalog command with its existing
|
|
343
|
+
prompts and notices; there is no second action registry. Offline and stale
|
|
344
|
+
actions refuse locally. Waiting cancellation preserves notices but rejects
|
|
345
|
+
prompts without opening a dialog. Browser rows use ordinary buttons. The TUI
|
|
346
|
+
renders current extension rows compactly below its footer hints; each row moves
|
|
347
|
+
the footer upward. Loop and its next run share one row. Ordinary notices can be
|
|
348
|
+
dismissed with Esc after interactions, queued messages, active work and
|
|
349
|
+
extension waiting controls have priority. Live extension state is not
|
|
350
|
+
dismissible. In the TUI, the **Row actions** palette command uses the existing
|
|
351
|
+
keyboard choice dialogs. Rows may also carry a typed Session open target. The
|
|
352
|
+
host supplies the generic open callback and authorizes that target before
|
|
353
|
+
navigation. The TUI opens the target through its pane registry and reports a
|
|
354
|
+
refused open as a notice.
|
|
355
|
+
|
|
356
|
+
V1 permits four chips, sixteen panel rows, thirty-two timeline cells, and two
|
|
357
|
+
hundred rows total per entry. Labels contain at most 4,096 characters. Chips
|
|
358
|
+
carry no actions or open targets. `ClientChipV1.compact` is optional label data
|
|
359
|
+
that browser and TUI renderers do not display; they use the chip row’s title. A
|
|
360
|
+
cell's ID is its positive safe integer sequence written as decimal text.
|
|
361
|
+
Producer history commits in the same owner transaction as its state change,
|
|
362
|
+
deduplicates unchanged state, and retains at most thirty-two events and 32 KiB
|
|
363
|
+
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**.
|
|
366
|
+
|
|
367
|
+
The frozen client V1 contract includes fields, placements, bounds, identities,
|
|
368
|
+
ordering, admission, dispatch, detach, and history laws. Host extension V0 and
|
|
369
|
+
client presentation V1 are independent protocols. A breaking client change
|
|
370
|
+
requires a new client protocol; supported additions require an explicit contract
|
|
371
|
+
decision and proof. Producer schema changes bump their own extension/state
|
|
372
|
+
versions. Pre-launch data uses the current contract, without a dual reader.
|
|
373
|
+
|
|
374
|
+
## Limits and errors
|
|
375
|
+
|
|
376
|
+
Use `ShiitakeError`'s boundary and cause to distinguish invalid input, conflict,
|
|
377
|
+
storage failure and unavailable execution. Preserve request identity when an
|
|
378
|
+
acknowledgement is uncertain. Do not manufacture an accepted result from an
|
|
379
|
+
unavailable owner.
|
|
380
|
+
|
|
381
|
+
Safe recovery depends on durable facts and the tool's replay contract. An
|
|
382
|
+
operation with an uncertain external effect is not made safe by retrying it.
|
|
383
|
+
Schema-incompatible extension state fails rather than using another shape.
|
|
384
|
+
Credentials, product permissions, browser delivery and deployment remain with
|
|
385
|
+
the host.
|
|
386
|
+
|
|
387
|
+
## Contribute and license
|
|
388
|
+
|
|
389
|
+
Add a regression to the nearest Session, extension or host test. From the root:
|
|
390
|
+
|
|
391
|
+
```sh
|
|
392
|
+
pnpm --dir packages/shiitake run test:unit
|
|
393
|
+
pnpm --dir packages/shiitake run test:merge
|
|
394
|
+
pnpm --dir packages/shiitake run docs
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
The native merge proof needs the configured Workers-compatible runtime. Unit
|
|
398
|
+
tests alone do not qualify that host. MIT. See [LICENSE](LICENSE).
|
|
399
|
+
|
|
400
|
+
## Agent fleet
|
|
401
|
+
|
|
402
|
+
`@fungi.computer/shiitake/fleet` owns Agent directory reservations, replay
|
|
403
|
+
receipts, erasure addresses, granted Session operations and hosted BirdDog
|
|
404
|
+
delegation. Hosts supply grants containing Agent scope, actions, expiry and
|
|
405
|
+
provenance. Fleet operations do not read Team, billing or broker policy. Usage
|
|
406
|
+
has no fleet cap; the host's inference admission remains the credit authority.
|
|
407
|
+
|
|
408
|
+
`createAgentDirectory(sql)` runs mutations inside the caller's transaction and
|
|
409
|
+
returns lifecycle facts so host projections commit with the directory change.
|
|
410
|
+
`createFleetSessions(open)` lists, creates, reads and deletes Sessions, and
|
|
411
|
+
`send(grant, agentId, sessionId, message)` admits replayable work. An omitted
|
|
412
|
+
Session is created with the message's request identity.
|
|
413
|
+
`createFleetDelegation({storage, deliver, open, readSettlement})` records the
|
|
414
|
+
grant's parent Session and freezes BirdDog mail before delivery.
|
|
415
|
+
`start(grant, task)` returns the admission receipt; `delegate(grant, task)`
|
|
416
|
+
returns Agar Pending until the exact command settles, then its terminal, final
|
|
417
|
+
text, native usage facts and tool-call count. The host-only
|
|
418
|
+
`readSettlement(sessionId, commandId)` reads exact work rows, independently of
|
|
419
|
+
transcript pagination and branch selection. Poll with the same request identity
|
|
420
|
+
and task. Closing a client never cancels work.
|
|
421
|
+
|
|
422
|
+
Host metadata stays opaque. An in-process `open` adapter applies it with
|
|
423
|
+
`agent.withMeta(meta)`; a remote host attaches it at its authenticated transport
|
|
424
|
+
edge. Cancellation returns the cancellation entry's metadata, allowing the host
|
|
425
|
+
to name the canceller in the reply text without making them its author.
|
|
426
|
+
|
|
427
|
+
### Delegated replies
|
|
428
|
+
|
|
429
|
+
A `followUp` delegation returns `{status: "accepted", commandId}` at once. The
|
|
430
|
+
child's result arrives later as one new user-role line in the parent Session. It
|
|
431
|
+
is ordinary follow-up work: an idle parent wakes a new run, and an active parent
|
|
432
|
+
queues it behind the running work, which it never interrupts, so it runs next.
|
|
433
|
+
Each fact on that line has one setter:
|
|
434
|
+
|
|
435
|
+
| Fact | Setter | Rule |
|
|
436
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
437
|
+
| Content | BirdDog `settlementReplies` | The child's last assistant text, or the host's cancellation text such as `Work cancelled by Ada.`, verbatim; with neither, one sentence naming the outcome. |
|
|
438
|
+
| `reply.commandId` | BirdDog, from the child's accepted command | Equals the parent's `agents.send` receipt `commandId`. |
|
|
439
|
+
| `reply.outcome`, `reply.diagnostic` | BirdDog, from the exact Watchdog outcome and the child Session's terminal diagnostic | `completed`, `failed`, `interrupted`, `cancelled` and `outcome_unknown` stay distinct. Only `failed`, `interrupted` and `outcome_unknown` carry a diagnostic, bounded by `boundedDiagnostic`. |
|
|
440
|
+
| Authentication | `fleet.authenticateReply(mail)` at the parent's host | The key is the frozen send's `<key>:reply:0`, `replyTo` is empty, `from`/`to` mirror the frozen send exactly, BirdDog's facts are present and, once the send's receipt is recorded, name its `commandId`. Otherwise the result is `undefined` and the host refuses the mail. |
|
|
441
|
+
| Author and `meta.delegation.reply` | The parent's host, only after authentication | The author is the replying child Agent. The settling actor, a human canceller and the parent never author a reply. |
|
|
442
|
+
| Model-visible provenance | Shiitake, from the `reply` the host passes to `acceptMail(mail, meta, reply)` | The model sees the line inside `<fungi_agent_reply agent_id=… session_id=… command_id=… outcome=… [diagnostic=…]>`. |
|
|
443
|
+
|
|
444
|
+
The provider role stays `user`. Shiitake renders the tag from the verified
|
|
445
|
+
facts, never from the text, and neutralizes the tag in every other user-role
|
|
446
|
+
line (typed prompts, unverified mail, operator lines) and inside the reply body.
|
|
447
|
+
Typed or mailed text that copies the tag therefore never reads as a verified
|
|
448
|
+
reply. The stored line keeps the child's text verbatim; clients join it to the
|
|
449
|
+
send on `meta.delegation.reply.commandId` through agar's
|
|
450
|
+
`messageDelegationReply`, never on its text. `acceptMail` refuses a `reply` that
|
|
451
|
+
does not name its mail's sender or that arrives on mail with a `replyTo`.
|
|
452
|
+
|
|
453
|
+
Apps exposing an Agent extension import `agentExtensionMethods` from
|
|
454
|
+
`@fungi.computer/shiitake/agar-extension` and spread the result into Agar's
|
|
455
|
+
`defineAppBackend({methods})`. Agar itself has no Shiitake dependency.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RosteredExtensionV0 } from "./extensions.js";
|
|
2
|
+
import { type AppBackendMethod } from "@fungi.computer/agar/backend-definition";
|
|
3
|
+
/**
|
|
4
|
+
* Serve one Shiitake extension from this App backend. Spread the result into
|
|
5
|
+
* `defineAppBackend({ methods })`; the build writes the three methods into the
|
|
6
|
+
* Release's API, which is how a Release declares itself an Agent extension.
|
|
7
|
+
* An extension requesting a capability hosting lacks fails here, at build.
|
|
8
|
+
*/
|
|
9
|
+
export declare function agentExtensionMethods<Context = void>(extension: RosteredExtensionV0): Readonly<Record<string, AppBackendMethod<Context>>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { agentExtensionMethodNames, hostAgentExtension, hostedCallInputSchema, hostedCallOutputSchema, hostedPromptInputSchema, hostedPromptOutputSchema, hostedToolsInputSchema, hostedToolsOutputSchema, } from "./hosted.js";
|
|
2
|
+
import { defineAppMethod, } from "@fungi.computer/agar/backend-definition";
|
|
3
|
+
/**
|
|
4
|
+
* Serve one Shiitake extension from this App backend. Spread the result into
|
|
5
|
+
* `defineAppBackend({ methods })`; the build writes the three methods into the
|
|
6
|
+
* Release's API, which is how a Release declares itself an Agent extension.
|
|
7
|
+
* An extension requesting a capability hosting lacks fails here, at build.
|
|
8
|
+
*/
|
|
9
|
+
export function agentExtensionMethods(extension) {
|
|
10
|
+
const hosted = hostAgentExtension(extension);
|
|
11
|
+
const id = hosted.manifest.id;
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
[agentExtensionMethodNames.prompt]: defineAppMethod({
|
|
14
|
+
description: `Prompt sections of the ${id} Agent extension.`,
|
|
15
|
+
effect: "read",
|
|
16
|
+
requires: [],
|
|
17
|
+
input: hostedPromptInputSchema,
|
|
18
|
+
output: hostedPromptOutputSchema,
|
|
19
|
+
handler: (input) => hosted.prompt(input),
|
|
20
|
+
}),
|
|
21
|
+
[agentExtensionMethodNames.tools]: defineAppMethod({
|
|
22
|
+
description: `Tools of the ${id} Agent extension for one run.`,
|
|
23
|
+
effect: "read",
|
|
24
|
+
requires: [],
|
|
25
|
+
input: hostedToolsInputSchema,
|
|
26
|
+
output: hostedToolsOutputSchema,
|
|
27
|
+
handler: (input) => hosted.tools(input),
|
|
28
|
+
}),
|
|
29
|
+
[agentExtensionMethodNames.call]: defineAppMethod({
|
|
30
|
+
description: `Run one tool of the ${id} Agent extension.`,
|
|
31
|
+
effect: "write",
|
|
32
|
+
requires: [],
|
|
33
|
+
input: hostedCallInputSchema,
|
|
34
|
+
output: hostedCallOutputSchema,
|
|
35
|
+
handler: (input) => hosted.call(input),
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type CapabilitySource, type CapabilitySession } from "@fungi.computer/mycelium";
|
|
2
|
+
import type { Accepted, ShiitakeAgent, ShiitakeSession } from "./client.js";
|
|
3
|
+
import { type ModelPreference } from "./model-preference.js";
|
|
4
|
+
/** One existing Agent visible within the caller's authorized project or Team. */
|
|
5
|
+
export type AgentControlAgent = Readonly<{
|
|
6
|
+
agentId: string;
|
|
7
|
+
name: string;
|
|
8
|
+
}>;
|
|
9
|
+
/** One host-offered model usable as an Agent's create or setModel choice. */
|
|
10
|
+
export type AgentControlModel = Readonly<{
|
|
11
|
+
/** `provider/model` address accepted by `agents.create` and `agents.setModel`. */
|
|
12
|
+
address: string;
|
|
13
|
+
/** Provider's display name for the model. */
|
|
14
|
+
name: string;
|
|
15
|
+
}>;
|
|
16
|
+
/** One host-authorized delegation, with the caller Session supplied by acquisition. */
|
|
17
|
+
export type AgentDelegationInput = Readonly<{
|
|
18
|
+
/** Target Agent in the host's authorized scope. */
|
|
19
|
+
agentId: string;
|
|
20
|
+
/** Target conversation on that Agent. */
|
|
21
|
+
sessionId: string;
|
|
22
|
+
/** Work to admit as a follow-up prompt. */
|
|
23
|
+
text: string;
|
|
24
|
+
}>;
|
|
25
|
+
/** Host-only identity and admitted command metadata for one delegated send. */
|
|
26
|
+
export type AgentDelegationInvocation = Readonly<{
|
|
27
|
+
toolCallId: string;
|
|
28
|
+
sendIndex: number;
|
|
29
|
+
commandId?: string;
|
|
30
|
+
meta?: CapabilitySession["meta"];
|
|
31
|
+
toolCallCode?: string;
|
|
32
|
+
}>;
|
|
33
|
+
/** Host-owned discovery and per-operation access to ordinary Agents. */
|
|
34
|
+
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. */
|
|
38
|
+
send?: (input: AgentDelegationInput, sourceSessionId: string, signal: AbortSignal, invocation?: AgentDelegationInvocation) => Promise<Accepted>;
|
|
39
|
+
/** Present only when this host authorizes ordinary Agent creation. */
|
|
40
|
+
create?: (input: Readonly<{
|
|
41
|
+
requestId: string;
|
|
42
|
+
model?: ModelPreference;
|
|
43
|
+
}>, signal: AbortSignal) => Promise<AgentControlAgent>;
|
|
44
|
+
/** Present only when the host authorizes changing an Agent's future default. */
|
|
45
|
+
setModel?: (input: Readonly<{
|
|
46
|
+
agentId: string;
|
|
47
|
+
model: ModelPreference;
|
|
48
|
+
}>, signal: AbortSignal) => Promise<void>;
|
|
49
|
+
/** Present only when the host can list models offered by its signed-in providers. */
|
|
50
|
+
models?: (signal: AbortSignal) => Promise<readonly AgentControlModel[]>;
|
|
51
|
+
/** Optional host admission check before accepting a model-backed send. */
|
|
52
|
+
checkModel?: (input: Readonly<{
|
|
53
|
+
agentId: string;
|
|
54
|
+
sessionId: string;
|
|
55
|
+
}>, signal: AbortSignal) => Promise<void>;
|
|
56
|
+
/** Recheck authorization and open one addressed Agent for this operation. */
|
|
57
|
+
open: (agentId: string, signal: AbortSignal) => Promise<Readonly<{
|
|
58
|
+
agent: ShiitakeAgent;
|
|
59
|
+
/** Release operation access without stopping the target Agent. */
|
|
60
|
+
release: () => Promise<void>;
|
|
61
|
+
}>>;
|
|
62
|
+
}>;
|
|
63
|
+
/** Observe one durable terminal; timeout or abort closes observation, not the work. */
|
|
64
|
+
export declare function waitForAgentTerminal(session: ShiitakeSession, commandId: string, timeoutMs: number, signal: AbortSignal, startedAt?: number): Promise<Readonly<{
|
|
65
|
+
commandId: string;
|
|
66
|
+
outcome: "completed" | "cancelled" | "failed" | "interrupted";
|
|
67
|
+
sequence: number;
|
|
68
|
+
diagnostic: string | null;
|
|
69
|
+
meta?: import("./extensions.js").Json;
|
|
70
|
+
}>>;
|
|
71
|
+
/** Compose one authorized Agent-control projection for a single run lease. */
|
|
72
|
+
export declare function createAgentControlSource(directory: AgentControlDirectory): CapabilitySource;
|