@cloudflare/think 0.0.0 → 0.0.2

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 ADDED
@@ -0,0 +1,241 @@
1
+ # @cloudflare/think
2
+
3
+ An Agent base class for AI assistants on Cloudflare Workers. Handles the full chat lifecycle — session management, agentic loop, streaming, persistence, workspace tools, and extensions — all backed by Durable Object SQLite.
4
+
5
+ Works as both a **top-level agent** (WebSocket chat protocol for browser clients) and a **sub-agent** (RPC streaming from a parent agent).
6
+
7
+ > **Experimental** — requires the `"experimental"` compatibility flag.
8
+
9
+ ## Quick start
10
+
11
+ ```ts
12
+ import { Think } from "@cloudflare/think";
13
+ import { createWorkersAI } from "workers-ai-provider";
14
+ import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
15
+ import { Workspace } from "agents/experimental/workspace";
16
+
17
+ export class ChatSession extends Think<Env> {
18
+ workspace = new Workspace(this);
19
+
20
+ getModel() {
21
+ return createWorkersAI({ binding: this.env.AI })(
22
+ "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
23
+ );
24
+ }
25
+
26
+ getSystemPrompt() {
27
+ return "You are a helpful coding assistant.";
28
+ }
29
+
30
+ getTools() {
31
+ return createWorkspaceTools(this.workspace);
32
+ }
33
+ }
34
+ ```
35
+
36
+ That's it. `Think` handles the WebSocket chat protocol, session persistence, the agentic loop, message sanitization, and streaming. Connect from the browser with `useAgentChat` or `useChat` + `AgentChatTransport`.
37
+
38
+ ## Exports
39
+
40
+ | Export | Description |
41
+ | ------------------------------------ | --------------------------------------------------------------- |
42
+ | `@cloudflare/think` | `Think` — the main class, plus types |
43
+ | `@cloudflare/think/session` | `SessionManager` — conversation persistence with branching |
44
+ | `@cloudflare/think/tools/workspace` | `createWorkspaceTools()` — file operation tools |
45
+ | `@cloudflare/think/tools/execute` | `createExecuteTool()` — sandboxed code execution via codemode |
46
+ | `@cloudflare/think/tools/extensions` | `createExtensionTools()` — LLM-driven extension loading |
47
+ | `@cloudflare/think/extensions` | `ExtensionManager`, `HostBridgeLoopback` — extension runtime |
48
+ | `@cloudflare/think/transport` | `AgentChatTransport` — bridges `useChat` with Agent WebSocket |
49
+ | `@cloudflare/think/message-builder` | `applyChunkToParts()` — reconstruct UIMessage parts from chunks |
50
+
51
+ ## Think
52
+
53
+ ### Override points
54
+
55
+ | Method | Default | Description |
56
+ | ------------------------- | -------------------------------- | ------------------------------------- |
57
+ | `getModel()` | throws | Return the `LanguageModel` to use |
58
+ | `getSystemPrompt()` | `"You are a helpful assistant."` | System prompt |
59
+ | `getTools()` | `{}` | AI SDK `ToolSet` for the agentic loop |
60
+ | `getMaxSteps()` | `10` | Max tool-call rounds per turn |
61
+ | `assembleContext()` | prune older tool calls | Customize what's sent to the LLM |
62
+ | `onChatMessage(options?)` | `streamText(...)` | Full control over inference |
63
+ | `onChatError(error)` | passthrough | Customize error handling |
64
+ | `getWorkspace()` | `null` | Workspace for extension host bridge |
65
+
66
+ ### Session management
67
+
68
+ Think manages multiple named sessions per agent instance. Sessions are created automatically on the first chat message, or explicitly:
69
+
70
+ ```ts
71
+ session.createSession("research");
72
+ session.switchSession(sessionId);
73
+ session.getSessions(); // Session[]
74
+ session.deleteSession(id);
75
+ session.renameSession(id, "new name");
76
+ session.getCurrentSessionId();
77
+ ```
78
+
79
+ ### Sub-agent streaming via RPC
80
+
81
+ When used as a sub-agent, the `chat()` method runs a full turn and streams events via a callback:
82
+
83
+ ```ts
84
+ // StreamCallback — implement as an RpcTarget in the parent
85
+ interface StreamCallback {
86
+ onEvent(json: string): void | Promise<void>;
87
+ onDone(): void | Promise<void>;
88
+ onError?(error: string): void | Promise<void>;
89
+ }
90
+
91
+ const session = await this.subAgent(ChatSession, "agent-abc");
92
+ await session.chat("Summarize the project", relay, {
93
+ tools: extraTools,
94
+ signal: abortController.signal
95
+ });
96
+ ```
97
+
98
+ ### Dynamic configuration
99
+
100
+ Think accepts a `Config` type parameter for per-instance configuration persisted in SQLite:
101
+
102
+ ```ts
103
+ type MyConfig = { modelTier: "fast" | "capable"; systemPrompt: string };
104
+
105
+ export class ChatSession extends Think<Env, MyConfig> {
106
+ getModel() {
107
+ const tier = this.getConfig()?.modelTier ?? "fast";
108
+ return createWorkersAI({ binding: this.env.AI })(MODEL_IDS[tier]);
109
+ }
110
+ }
111
+
112
+ // From the parent:
113
+ const session = await this.subAgent(ChatSession, "agent-abc");
114
+ await session.configure({ modelTier: "capable", systemPrompt: "..." });
115
+ ```
116
+
117
+ ### Production features
118
+
119
+ - **WebSocket protocol** — wire-compatible with `useAgentChat` / `useChat`
120
+ - **Multi-session** — create, switch, list, delete, rename conversations
121
+ - **Abort/cancel** — pass an `AbortSignal` or send a cancel message
122
+ - **Partial persistence** — on error, the partial assistant message is saved
123
+ - **Message sanitization** — strips ephemeral provider metadata before storage
124
+ - **Row size enforcement** — compacts tool outputs exceeding 1.8MB
125
+ - **Incremental persistence** — skips SQL writes for unchanged messages
126
+ - **Storage bounds** — set `maxPersistedMessages` to cap stored history
127
+
128
+ ## SessionManager
129
+
130
+ Persistent conversation storage with tree-structured messages (branching) and compaction. Used internally by Think, but also usable standalone.
131
+
132
+ ```ts
133
+ import { SessionManager } from "@cloudflare/think/session";
134
+
135
+ const sessions = new SessionManager(agent);
136
+ const session = sessions.create("my-chat");
137
+ sessions.append(session.id, userMessage);
138
+ const history = sessions.getHistory(session.id); // UIMessage[]
139
+ ```
140
+
141
+ Also exports truncation utilities (`truncateHead`, `truncateTail`, `truncateMiddle`, `truncateLines`) for managing large tool outputs.
142
+
143
+ ## Workspace tools
144
+
145
+ File operation tools backed by the Agents SDK `Workspace`:
146
+
147
+ ```ts
148
+ import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
149
+
150
+ const tools = createWorkspaceTools(this.workspace);
151
+ // Tools: read, write, edit, list, find, grep, delete
152
+ ```
153
+
154
+ Each tool is an AI SDK `tool()` with Zod schemas. The underlying operations are abstracted behind interfaces (`ReadOperations`, `WriteOperations`, etc.) so you can create tools backed by custom storage.
155
+
156
+ ## Code execution tool
157
+
158
+ Let the LLM write and run JavaScript in a sandboxed Worker:
159
+
160
+ ```ts
161
+ import { createExecuteTool } from "@cloudflare/think/tools/execute";
162
+
163
+ getTools() {
164
+ const wsTools = createWorkspaceTools(this.workspace);
165
+ return {
166
+ ...wsTools,
167
+ execute: createExecuteTool({ tools: wsTools, loader: this.env.LOADER })
168
+ };
169
+ }
170
+ ```
171
+
172
+ Requires `@cloudflare/codemode` and a `worker_loaders` binding in `wrangler.jsonc`.
173
+
174
+ ## Extensions
175
+
176
+ Dynamic tool loading at runtime. The LLM can write extension source code, load it as a sandboxed Worker, and use the new tools on the next turn.
177
+
178
+ ```ts
179
+ import { ExtensionManager } from "@cloudflare/think/extensions";
180
+ import { createExtensionTools } from "@cloudflare/think/tools/extensions";
181
+
182
+ const extensions = new ExtensionManager({
183
+ loader: this.env.LOADER,
184
+ workspace: this.workspace
185
+ });
186
+
187
+ getTools() {
188
+ return {
189
+ ...createWorkspaceTools(this.workspace),
190
+ ...createExtensionTools({ manager: extensions }),
191
+ ...extensions.getTools()
192
+ };
193
+ }
194
+ ```
195
+
196
+ Extensions get permission-gated workspace access via `HostBridgeLoopback`. Re-export it from your worker entry point:
197
+
198
+ ```ts
199
+ export { HostBridgeLoopback } from "@cloudflare/think/extensions";
200
+ ```
201
+
202
+ ## Chat transport
203
+
204
+ Client-side transport that bridges `useChat` with Agent WebSocket streaming:
205
+
206
+ ```tsx
207
+ import { AgentChatTransport } from "@cloudflare/think/transport";
208
+ import { useAgent } from "agents/react";
209
+ import { useChat } from "@ai-sdk/react";
210
+
211
+ const agent = useAgent({ agent: "ChatSession" });
212
+ const transport = useMemo(() => new AgentChatTransport(agent), [agent]);
213
+ const { messages, sendMessage, status } = useChat({ transport });
214
+ ```
215
+
216
+ Options: `sendMethod` (RPC method name, default `"sendMessage"`), `resumeTimeout` (ms, default `500`). Call `transport.detach()` before switching agents.
217
+
218
+ ## Message builder
219
+
220
+ Reconstruct `UIMessage` parts from stream chunks:
221
+
222
+ ```ts
223
+ import { applyChunkToParts } from "@cloudflare/think/message-builder";
224
+
225
+ const msg = { id: "...", role: "assistant", parts: [] };
226
+ for (const chunk of streamChunks) {
227
+ applyChunkToParts(msg.parts, chunk);
228
+ }
229
+ ```
230
+
231
+ Handles all AI SDK chunk types: `text-delta`, `reasoning-delta`, `tool-call`, `tool-result`, `source`, `file`, and more.
232
+
233
+ ## Peer dependencies
234
+
235
+ | Package | Required | Notes |
236
+ | ---------------------- | -------- | --------------------------------- |
237
+ | `agents` | yes | Cloudflare Agents SDK |
238
+ | `ai` | yes | Vercel AI SDK v6 |
239
+ | `zod` | yes | Schema validation (v3.25+ or v4) |
240
+ | `@cloudflare/codemode` | optional | For `createExecuteTool` |
241
+ | `@cloudflare/shell` | optional | For shell execution in extensions |
@@ -0,0 +1,27 @@
1
+ //#region \0@oxc-project+runtime@0.115.0/helpers/checkPrivateRedeclaration.js
2
+ function _checkPrivateRedeclaration(e, t) {
3
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
4
+ }
5
+ //#endregion
6
+ //#region \0@oxc-project+runtime@0.115.0/helpers/classPrivateFieldInitSpec.js
7
+ function _classPrivateFieldInitSpec(e, t, a) {
8
+ _checkPrivateRedeclaration(e, t), t.set(e, a);
9
+ }
10
+ //#endregion
11
+ //#region \0@oxc-project+runtime@0.115.0/helpers/assertClassBrand.js
12
+ function _assertClassBrand(e, t, n) {
13
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
14
+ throw new TypeError("Private element is not present on this object");
15
+ }
16
+ //#endregion
17
+ //#region \0@oxc-project+runtime@0.115.0/helpers/classPrivateFieldGet2.js
18
+ function _classPrivateFieldGet2(s, a) {
19
+ return s.get(_assertClassBrand(s, a));
20
+ }
21
+ //#endregion
22
+ //#region \0@oxc-project+runtime@0.115.0/helpers/classPrivateFieldSet2.js
23
+ function _classPrivateFieldSet2(s, a, r) {
24
+ return s.set(_assertClassBrand(s, a), r), r;
25
+ }
26
+ //#endregion
27
+ export { _checkPrivateRedeclaration as a, _classPrivateFieldInitSpec as i, _classPrivateFieldGet2 as n, _assertClassBrand as r, _classPrivateFieldSet2 as t };
@@ -0,0 +1,7 @@
1
+ import { a as _checkPrivateRedeclaration } from "./classPrivateFieldSet2-COLddhya.js";
2
+ //#region \0@oxc-project+runtime@0.115.0/helpers/classPrivateMethodInitSpec.js
3
+ function _classPrivateMethodInitSpec(e, a) {
4
+ _checkPrivateRedeclaration(e, a), a.add(e);
5
+ }
6
+ //#endregion
7
+ export { _classPrivateMethodInitSpec as t };
@@ -0,0 +1,20 @@
1
+ import {
2
+ a as ExtensionInfo,
3
+ c as ExtensionToolDescriptor,
4
+ i as ExtensionManagerOptions,
5
+ n as HostBridgeLoopbackProps,
6
+ o as ExtensionManifest,
7
+ r as ExtensionManager,
8
+ s as ExtensionPermissions,
9
+ t as HostBridgeLoopback
10
+ } from "../index-BlcvIdWK.js";
11
+ export {
12
+ ExtensionInfo,
13
+ ExtensionManager,
14
+ ExtensionManagerOptions,
15
+ ExtensionManifest,
16
+ ExtensionPermissions,
17
+ ExtensionToolDescriptor,
18
+ HostBridgeLoopback,
19
+ HostBridgeLoopbackProps
20
+ };
@@ -0,0 +1,62 @@
1
+ import { r as _assertClassBrand } from "../classPrivateFieldSet2-COLddhya.js";
2
+ import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-CdQXQy1O.js";
3
+ import { t as ExtensionManager } from "../manager-DIV0gQf3.js";
4
+ import { WorkerEntrypoint } from "cloudflare:workers";
5
+ //#region src/extensions/host-bridge.ts
6
+ /**
7
+ * HostBridgeLoopback — a WorkerEntrypoint that provides controlled workspace
8
+ * access to extension Workers loaded via WorkerLoader.
9
+ *
10
+ * This is a loopback: the extension worker's `env.host` binding points here,
11
+ * and each method call resolves the parent agent via `ctx.exports`, then
12
+ * delegates to the agent's workspace proxy methods (`_hostReadFile`, etc.).
13
+ *
14
+ * Props carry serializable identifiers (agent class name, agent ID, and
15
+ * permissions) so the binding survives across requests and hibernation.
16
+ *
17
+ * Users must re-export this class from their worker entry point:
18
+ *
19
+ * ```typescript
20
+ * export { HostBridgeLoopback } from "@cloudflare/think/extensions";
21
+ * ```
22
+ *
23
+ * @experimental Requires the `"experimental"` compatibility flag.
24
+ */
25
+ var _HostBridgeLoopback_brand = /* @__PURE__ */ new WeakSet();
26
+ var HostBridgeLoopback = class extends WorkerEntrypoint {
27
+ constructor(..._args) {
28
+ super(..._args);
29
+ _classPrivateMethodInitSpec(this, _HostBridgeLoopback_brand);
30
+ this._permissions = this.ctx.props.permissions;
31
+ }
32
+ _getAgent() {
33
+ const { agentClassName, agentId } = this.ctx.props;
34
+ const ns = this.ctx.exports[agentClassName];
35
+ return ns.get(ns.idFromString(agentId));
36
+ }
37
+ async readFile(path) {
38
+ _assertClassBrand(_HostBridgeLoopback_brand, this, _requirePermission).call(this, "read");
39
+ return this._getAgent()._hostReadFile(path);
40
+ }
41
+ async writeFile(path, content) {
42
+ _assertClassBrand(_HostBridgeLoopback_brand, this, _requirePermission).call(this, "read-write");
43
+ return this._getAgent()._hostWriteFile(path, content);
44
+ }
45
+ async deleteFile(path) {
46
+ _assertClassBrand(_HostBridgeLoopback_brand, this, _requirePermission).call(this, "read-write");
47
+ return this._getAgent()._hostDeleteFile(path);
48
+ }
49
+ async listFiles(dir) {
50
+ _assertClassBrand(_HostBridgeLoopback_brand, this, _requirePermission).call(this, "read");
51
+ return this._getAgent()._hostListFiles(dir);
52
+ }
53
+ };
54
+ function _requirePermission(level) {
55
+ const ws = this._permissions.workspace ?? "none";
56
+ if (ws === "none") throw new Error("Extension error: no workspace permission declared");
57
+ if (level === "read-write" && ws !== "read-write") throw new Error("Extension error: workspace write permission required, but only read granted");
58
+ }
59
+ //#endregion
60
+ export { ExtensionManager, HostBridgeLoopback };
61
+
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/extensions/host-bridge.ts"],"sourcesContent":["/**\n * HostBridgeLoopback — a WorkerEntrypoint that provides controlled workspace\n * access to extension Workers loaded via WorkerLoader.\n *\n * This is a loopback: the extension worker's `env.host` binding points here,\n * and each method call resolves the parent agent via `ctx.exports`, then\n * delegates to the agent's workspace proxy methods (`_hostReadFile`, etc.).\n *\n * Props carry serializable identifiers (agent class name, agent ID, and\n * permissions) so the binding survives across requests and hibernation.\n *\n * Users must re-export this class from their worker entry point:\n *\n * ```typescript\n * export { HostBridgeLoopback } from \"@cloudflare/think/extensions\";\n * ```\n *\n * @experimental Requires the `\"experimental\"` compatibility flag.\n */\n\nimport { WorkerEntrypoint } from \"cloudflare:workers\";\nimport type { ExtensionPermissions } from \"./types\";\n\nexport type HostBridgeLoopbackProps = {\n agentClassName: string;\n agentId: string;\n permissions: ExtensionPermissions;\n};\n\nexport class HostBridgeLoopback extends WorkerEntrypoint<\n Record<string, unknown>,\n HostBridgeLoopbackProps\n> {\n private _permissions = this.ctx.props.permissions;\n\n private _getAgent() {\n const { agentClassName, agentId } = this.ctx.props;\n // @ts-expect-error — experimental: ctx.exports on WorkerEntrypoint\n const ns = this.ctx.exports[agentClassName] as DurableObjectNamespace;\n return ns.get(ns.idFromString(agentId));\n }\n\n #requirePermission(level: \"read\" | \"read-write\"): void {\n const ws = this._permissions.workspace ?? \"none\";\n if (ws === \"none\") {\n throw new Error(\"Extension error: no workspace permission declared\");\n }\n if (level === \"read-write\" && ws !== \"read-write\") {\n throw new Error(\n \"Extension error: workspace write permission required, but only read granted\"\n );\n }\n }\n\n async readFile(path: string): Promise<string | null> {\n this.#requirePermission(\"read\");\n return (\n this._getAgent() as unknown as {\n _hostReadFile(path: string): Promise<string | null>;\n }\n )._hostReadFile(path);\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n this.#requirePermission(\"read-write\");\n return (\n this._getAgent() as unknown as {\n _hostWriteFile(path: string, content: string): Promise<void>;\n }\n )._hostWriteFile(path, content);\n }\n\n async deleteFile(path: string): Promise<boolean> {\n this.#requirePermission(\"read-write\");\n return (\n this._getAgent() as unknown as {\n _hostDeleteFile(path: string): Promise<boolean>;\n }\n )._hostDeleteFile(path);\n }\n\n async listFiles(\n dir: string\n ): Promise<\n Array<{ name: string; type: string; size: number; path: string }>\n > {\n this.#requirePermission(\"read\");\n return (\n this._getAgent() as unknown as {\n _hostListFiles(\n dir: string\n ): Promise<\n Array<{ name: string; type: string; size: number; path: string }>\n >;\n }\n )._hostListFiles(dir);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,qBAAb,cAAwC,iBAGtC;;;;AACA,OAAQ,eAAe,KAAK,IAAI,MAAM;;CAEtC,YAAoB;EAClB,MAAM,EAAE,gBAAgB,YAAY,KAAK,IAAI;EAE7C,MAAM,KAAK,KAAK,IAAI,QAAQ;AAC5B,SAAO,GAAG,IAAI,GAAG,aAAa,QAAQ,CAAC;;CAezC,MAAM,SAAS,MAAsC;AACnD,oBAAA,2BAAA,MAAA,mBAAuB,CAAA,KAAA,MAAC,OAAO;AAC/B,SACE,KAAK,WAAW,CAGhB,cAAc,KAAK;;CAGvB,MAAM,UAAU,MAAc,SAAgC;AAC5D,oBAAA,2BAAA,MAAA,mBAAuB,CAAA,KAAA,MAAC,aAAa;AACrC,SACE,KAAK,WAAW,CAGhB,eAAe,MAAM,QAAQ;;CAGjC,MAAM,WAAW,MAAgC;AAC/C,oBAAA,2BAAA,MAAA,mBAAuB,CAAA,KAAA,MAAC,aAAa;AACrC,SACE,KAAK,WAAW,CAGhB,gBAAgB,KAAK;;CAGzB,MAAM,UACJ,KAGA;AACA,oBAAA,2BAAA,MAAA,mBAAuB,CAAA,KAAA,MAAC,OAAO;AAC/B,SACE,KAAK,WAAW,CAOhB,eAAe,IAAI;;;AArDvB,SAAA,mBAAmB,OAAoC;CACrD,MAAM,KAAK,KAAK,aAAa,aAAa;AAC1C,KAAI,OAAO,OACT,OAAM,IAAI,MAAM,oDAAoD;AAEtE,KAAI,UAAU,gBAAgB,OAAO,aACnC,OAAM,IAAI,MACR,8EACD"}
@@ -0,0 +1,171 @@
1
+ import { ToolSet } from "ai";
2
+ import { WorkerEntrypoint } from "cloudflare:workers";
3
+
4
+ //#region src/extensions/types.d.ts
5
+ /**
6
+ * Extension system types.
7
+ *
8
+ * Extensions are sandboxed Workers loaded on demand via WorkerLoader.
9
+ * Each extension provides tools that the agent can use, with controlled
10
+ * access to the host (workspace, network) via permissions.
11
+ */
12
+ /**
13
+ * Manifest declaring an extension's identity and permissions.
14
+ * Passed to ExtensionManager.load() alongside the extension source.
15
+ */
16
+ interface ExtensionManifest {
17
+ /** Unique name for this extension (used as namespace prefix for tools). */
18
+ name: string;
19
+ /** Semver version string. */
20
+ version: string;
21
+ /** Human-readable description. */
22
+ description?: string;
23
+ /** Permission declarations — controls what the extension can access. */
24
+ permissions?: ExtensionPermissions;
25
+ }
26
+ interface ExtensionPermissions {
27
+ /**
28
+ * Allowed network hosts. If empty or undefined, the extension has
29
+ * no outbound network access (globalOutbound: null).
30
+ * If set, the extension inherits the parent Worker's network.
31
+ *
32
+ * Note: per-host filtering is not yet enforced at the runtime level.
33
+ * This field serves as a declaration of intent; actual enforcement
34
+ * is all-or-nothing via globalOutbound.
35
+ */
36
+ network?: string[];
37
+ /**
38
+ * Workspace access level.
39
+ * - "none" (default): no workspace access
40
+ * - "read": can read files and list directories
41
+ * - "read-write": can read, write, and delete files
42
+ */
43
+ workspace?: "read" | "read-write" | "none";
44
+ }
45
+ /**
46
+ * Tool descriptor returned by the extension's describe() method.
47
+ * Uses JSON Schema for input validation.
48
+ */
49
+ interface ExtensionToolDescriptor {
50
+ name: string;
51
+ description: string;
52
+ inputSchema: {
53
+ type: "object";
54
+ properties: Record<string, unknown>;
55
+ required?: string[];
56
+ };
57
+ }
58
+ /**
59
+ * Summary of a loaded extension, returned by ExtensionManager.list().
60
+ */
61
+ interface ExtensionInfo {
62
+ name: string;
63
+ version: string;
64
+ description?: string;
65
+ /** Names of tools provided by this extension. */
66
+ tools: string[];
67
+ permissions: ExtensionPermissions;
68
+ }
69
+ //#endregion
70
+ //#region src/extensions/manager.d.ts
71
+ interface ExtensionManagerOptions {
72
+ /** WorkerLoader binding for creating sandboxed extension Workers. */
73
+ loader: WorkerLoader;
74
+ /**
75
+ * Durable Object storage for persisting extensions across hibernation.
76
+ * If provided, loaded extensions survive DO restarts. Call `restore()`
77
+ * on each turn to rebuild in-memory state from storage.
78
+ */
79
+ storage?: DurableObjectStorage;
80
+ /**
81
+ * Factory that creates a loopback Fetcher for workspace access, given
82
+ * an extension's declared permissions. The returned binding is injected
83
+ * into the extension worker's `env.host`.
84
+ *
85
+ * If not provided, extensions receive no host binding (workspace tools
86
+ * will get `null` for the host parameter).
87
+ *
88
+ * Typically wired up using HostBridgeLoopback via `ctx.exports`:
89
+ * ```typescript
90
+ * createHostBinding: (permissions) =>
91
+ * ctx.exports.HostBridgeLoopback({
92
+ * props: { agentClassName: "ChatSession", agentId: ctx.id.toString(), permissions }
93
+ * })
94
+ * ```
95
+ */
96
+ createHostBinding?: (permissions: ExtensionPermissions) => Fetcher;
97
+ }
98
+ declare class ExtensionManager {
99
+ #private;
100
+ constructor(options: ExtensionManagerOptions);
101
+ /**
102
+ * Load an extension from source code.
103
+ *
104
+ * The source is a JS object expression defining tools. Each tool has
105
+ * `description`, `parameters` (JSON Schema properties), optional
106
+ * `required` array, and an `execute` async function.
107
+ *
108
+ * @returns Summary of the loaded extension including discovered tools.
109
+ */
110
+ /**
111
+ * Restore extensions from DO storage after hibernation.
112
+ *
113
+ * Idempotent — skips extensions already in memory. Call this at the
114
+ * start of each chat turn (e.g. in onChatMessage before getTools).
115
+ */
116
+ restore(): Promise<void>;
117
+ load(manifest: ExtensionManifest, source: string): Promise<ExtensionInfo>;
118
+ /**
119
+ * Unload an extension, removing its tools from the agent.
120
+ */
121
+ unload(name: string): Promise<boolean>;
122
+ /**
123
+ * List all loaded extensions.
124
+ */
125
+ list(): ExtensionInfo[];
126
+ /**
127
+ * Get AI SDK tools from all loaded extensions.
128
+ *
129
+ * Tool names are prefixed with the sanitized extension name to avoid
130
+ * collisions: e.g. extension "github" with tool "create_pr" → "github_create_pr".
131
+ */
132
+ getTools(): ToolSet;
133
+ }
134
+ //#endregion
135
+ //#region src/extensions/host-bridge.d.ts
136
+ type HostBridgeLoopbackProps = {
137
+ agentClassName: string;
138
+ agentId: string;
139
+ permissions: ExtensionPermissions;
140
+ };
141
+ declare class HostBridgeLoopback extends WorkerEntrypoint<
142
+ Record<string, unknown>,
143
+ HostBridgeLoopbackProps
144
+ > {
145
+ #private;
146
+ private _permissions;
147
+ private _getAgent;
148
+ readFile(path: string): Promise<string | null>;
149
+ writeFile(path: string, content: string): Promise<void>;
150
+ deleteFile(path: string): Promise<boolean>;
151
+ listFiles(dir: string): Promise<
152
+ Array<{
153
+ name: string;
154
+ type: string;
155
+ size: number;
156
+ path: string;
157
+ }>
158
+ >;
159
+ }
160
+ //#endregion
161
+ export {
162
+ ExtensionInfo as a,
163
+ ExtensionToolDescriptor as c,
164
+ ExtensionManagerOptions as i,
165
+ HostBridgeLoopbackProps as n,
166
+ ExtensionManifest as o,
167
+ ExtensionManager as r,
168
+ ExtensionPermissions as s,
169
+ HostBridgeLoopback as t
170
+ };
171
+ //# sourceMappingURL=index-BlcvIdWK.d.ts.map