@lunora/agent 1.0.0-alpha.4 → 1.0.0-alpha.5

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.
@@ -1,11 +1,11 @@
1
- import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-BhJFTvz_.mjs";
1
+ import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-boAM2Yi1.mjs";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
5
- * The model-provided input to a {@link browserTool} call — a discriminated
6
- * union on `op` so one tool exposes every headless-browser capability.
7
- * @experimental
8
- */
5
+ * The model-provided input to a {@link browserTool} call — a discriminated
6
+ * union on `op` so one tool exposes every headless-browser capability.
7
+ * @experimental
8
+ */
9
9
  type BrowserToolInput = {
10
10
  fullPage?: boolean;
11
11
  op: "screenshot";
@@ -23,12 +23,12 @@ type BrowserToolInput = {
23
23
  url: string;
24
24
  };
25
25
  /**
26
- * The model-provided input to a {@link containerTool} call — a discriminated
27
- * union on `op`. `fetch` sends an HTTP request to the container; `exec` asks it
28
- * to run a command (routed as a POST to `/exec`, since the container surface
29
- * exposes no first-class exec RPC — the container app must serve that route).
30
- * @experimental
31
- */
26
+ * The model-provided input to a {@link containerTool} call — a discriminated
27
+ * union on `op`. `fetch` sends an HTTP request to the container; `exec` asks it
28
+ * to run a command (routed as a POST to `/exec`, since the container surface
29
+ * exposes no first-class exec RPC — the container app must serve that route).
30
+ * @experimental
31
+ */
32
32
  type ContainerToolInput = {
33
33
  args?: string[];
34
34
  command?: string;
@@ -40,28 +40,28 @@ type ContainerToolInput = {
40
40
  path: string;
41
41
  };
42
42
  /**
43
- * Author-supplied config for `browserTool`.
44
- * @experimental
45
- */
43
+ * Author-supplied config for `browserTool`.
44
+ * @experimental
45
+ */
46
46
  interface BrowserToolOptions {
47
47
  /** Override the model-facing description (what the tool does). */
48
48
  description?: string;
49
49
  /**
50
- * Gate a call behind a human approval. Defaults to **unattended** (no gate),
51
- * matching the AI SDK. `browserTool` fetches a model-chosen `url` with no
52
- * allowlist, so it is an SSRF surface: a prompt-injected model can point it at
53
- * an internal/link-local address and read the response back into context. Pass
54
- * a boolean or a predicate to gate it (evaluated from replay-stable input, so
55
- * keep it deterministic).
56
- */
50
+ * Gate a call behind a human approval. Defaults to **unattended** (no gate),
51
+ * matching the AI SDK. `browserTool` fetches a model-chosen `url` with no
52
+ * allowlist, so it is an SSRF surface: a prompt-injected model can point it at
53
+ * an internal/link-local address and read the response back into context. Pass
54
+ * a boolean or a predicate to gate it (evaluated from replay-stable input, so
55
+ * keep it deterministic).
56
+ */
57
57
  needsApproval?: ((input: BrowserToolInput) => boolean) | boolean;
58
58
  }
59
59
  /**
60
- * The model-provided input to a {@link fsTool} call — a discriminated union on
61
- * `op` over an R2-backed virtual filesystem. Paths are relative to the tool's
62
- * pinned `root`; a `..` that escapes the root is rejected server-side.
63
- * @experimental
64
- */
60
+ * The model-provided input to a {@link fsTool} call — a discriminated union on
61
+ * `op` over an R2-backed virtual filesystem. Paths are relative to the tool's
62
+ * pinned `root`; a `..` that escapes the root is rejected server-side.
63
+ * @experimental
64
+ */
65
65
  type FsToolInput = {
66
66
  op: "ls";
67
67
  path?: string;
@@ -80,125 +80,125 @@ type FsToolInput = {
80
80
  path: string;
81
81
  };
82
82
  /**
83
- * Author-supplied config for `fsTool`.
84
- * @experimental
85
- */
83
+ * Author-supplied config for `fsTool`.
84
+ * @experimental
85
+ */
86
86
  interface FsToolOptions {
87
87
  /** Override the model-facing description (what the tool does). */
88
88
  description?: string;
89
89
  /**
90
- * Gate a call behind a human approval. Defaults to gating the WRITING ops
91
- * (`write`, `rm`) — a prompt-injected model shouldn't silently overwrite or
92
- * delete the sandbox — while `ls`/`read`/`stat` run unattended. Pass a boolean
93
- * or a predicate (evaluated from replay-stable input, so keep it deterministic).
94
- */
90
+ * Gate a call behind a human approval. Defaults to gating the WRITING ops
91
+ * (`write`, `rm`) — a prompt-injected model shouldn't silently overwrite or
92
+ * delete the sandbox — while `ls`/`read`/`stat` run unattended. Pass a boolean
93
+ * or a predicate (evaluated from replay-stable input, so keep it deterministic).
94
+ */
95
95
  needsApproval?: ((input: FsToolInput) => boolean) | boolean;
96
96
  /**
97
- * The key prefix every path is scoped under, isolating this tool's files from
98
- * the rest of the bucket. Either a fixed string (e.g. `"agents/support"`) or a
99
- * function of the tool context — return `` `agents/${ctx.threadKey}` `` (or an
100
- * owner-derived prefix) to give each run/user its OWN namespace in a
101
- * multi-tenant agent. Default: the bucket root (shared — set a root for
102
- * multi-tenant use). The server rejects any `..` that would escape it.
103
- */
97
+ * The key prefix every path is scoped under, isolating this tool's files from
98
+ * the rest of the bucket. Either a fixed string (e.g. `"agents/support"`) or a
99
+ * function of the tool context — return `` `agents/${ctx.threadKey}` `` (or an
100
+ * owner-derived prefix) to give each run/user its OWN namespace in a
101
+ * multi-tenant agent. Default: the bucket root (shared — set a root for
102
+ * multi-tenant use). The server rejects any `..` that would escape it.
103
+ */
104
104
  root?: ((context: AgentToolContext) => string) | string;
105
105
  }
106
106
  /**
107
- * Author-supplied config for `containerTool`.
108
- * @experimental
109
- */
107
+ * Author-supplied config for `containerTool`.
108
+ * @experimental
109
+ */
110
110
  interface ContainerToolOptions {
111
111
  /** Override the model-facing description (what the tool does). */
112
112
  description?: string;
113
113
  /**
114
- * Gate a call behind a human approval. Defaults to gating any command
115
- * execution: an `exec`, AND a `fetch` whose path resolves to the privileged
116
- * `/exec` route (both reach the same command-execution path in the container,
117
- * so gating on the `op` name alone would let a `fetch` to `/exec` run a
118
- * command unattended). A plain `fetch` to any other route runs unattended.
119
- * Pass a boolean or your own predicate to change that. Evaluated from
120
- * replay-stable input, so keep it deterministic.
121
- */
114
+ * Gate a call behind a human approval. Defaults to gating any command
115
+ * execution: an `exec`, AND a `fetch` whose path resolves to the privileged
116
+ * `/exec` route (both reach the same command-execution path in the container,
117
+ * so gating on the `op` name alone would let a `fetch` to `/exec` run a
118
+ * command unattended). A plain `fetch` to any other route runs unattended.
119
+ * Pass a boolean or your own predicate to change that. Evaluated from
120
+ * replay-stable input, so keep it deterministic.
121
+ */
122
122
  needsApproval?: ((input: ContainerToolInput) => boolean) | boolean;
123
123
  }
124
124
  /**
125
- * A batteries-included agent tool that drives Cloudflare Browser Rendering. One
126
- * tool exposes every browser op (screenshot / pdf / content / scrape); the model
127
- * picks via `op`. The call dispatches to the auto-registered `sandbox:invoke`
128
- * action — which runs on an action ctx carrying `ctx.browser`. Importing the tool
129
- * makes codegen register the dispatcher and provision the `BROWSER` binding; like
130
- * any `ctx.browser` user, the app still supplies a `config.browser` thunk
131
- * (`createBrowser({ binding: env.BROWSER, launch })` with the optional
132
- * `@cloudflare/playwright` `launch` peer) to `createShardDO()` — codegen never
133
- * injects that peer, so the browser op throws a directed error until it is wired.
134
- *
135
- * Security: the model chooses the `url` with no allowlist, so this is an SSRF
136
- * surface — pass `opts.needsApproval` to gate calls a prompt-injected model
137
- * could aim at internal/link-local endpoints.
138
- *
139
- * ```ts
140
- * import { browserTool, defineAgent } from "@lunora/agent/sandbox";
141
- *
142
- * export const researcher = defineAgent({
143
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
144
- * tools: { browser: browserTool() },
145
- * });
146
- * ```
147
- * @experimental
148
- */
125
+ * A batteries-included agent tool that drives Cloudflare Browser Rendering. One
126
+ * tool exposes every browser op (screenshot / pdf / content / scrape); the model
127
+ * picks via `op`. The call dispatches to the auto-registered `sandbox:invoke`
128
+ * action — which runs on an action ctx carrying `ctx.browser`. Importing the tool
129
+ * makes codegen register the dispatcher and provision the `BROWSER` binding; like
130
+ * any `ctx.browser` user, the app still supplies a `config.browser` thunk
131
+ * (`createBrowser({ binding: env.BROWSER, launch })` with the optional
132
+ * `@cloudflare/playwright` `launch` peer) to `createShardDO()` — codegen never
133
+ * injects that peer, so the browser op throws a directed error until it is wired.
134
+ *
135
+ * Security: the model chooses the `url` with no allowlist, so this is an SSRF
136
+ * surface — pass `opts.needsApproval` to gate calls a prompt-injected model
137
+ * could aim at internal/link-local endpoints.
138
+ *
139
+ * ```ts
140
+ * import { browserTool, defineAgent } from "@lunora/agent/sandbox";
141
+ *
142
+ * export const researcher = defineAgent({
143
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
144
+ * tools: { browser: browserTool() },
145
+ * });
146
+ * ```
147
+ * @experimental
148
+ */
149
149
  declare const browserTool: (options?: BrowserToolOptions) => AgentToolDefinition<BrowserToolInput, string>;
150
150
  /**
151
- * A batteries-included agent tool that talks to a declared Cloudflare
152
- * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
153
- * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
- * the model picks via `op`. The call dispatches to the auto-registered
155
- * `sandbox:invoke` action, which carries `ctx.containers`.
156
- *
157
- * By default a read-only (GET/HEAD/OPTIONS, or method-omitted) `fetch` runs
158
- * unattended while everything else is gated behind a human approval — an
159
- * `exec`; a `fetch` whose path resolves to the privileged `/exec` route (both
160
- * reach the same command-execution path in the container, so gating on the
161
- * `op` name alone would let a `fetch` to `/exec` run a command unattended);
162
- * and a `fetch` using a non-idempotent method (POST/PUT/PATCH/DELETE) to ANY
163
- * route, since a prompt-injected model could otherwise mutate container state
164
- * through some other privileged route just by avoiding the literal `/exec`
165
- * path. A `fetch` can still reach any *other read* route unattended, so scope
166
- * the container's GET routes accordingly. Pass `opts.needsApproval` to widen
167
- * or disable the gate.
168
- *
169
- * ```ts
170
- * import { containerTool, defineAgent } from "@lunora/agent/sandbox";
171
- *
172
- * export const ops = defineAgent({
173
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
174
- * tools: { sandbox: containerTool("sandbox") },
175
- * });
176
- * ```
177
- * @experimental
178
- */
151
+ * A batteries-included agent tool that talks to a declared Cloudflare
152
+ * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
153
+ * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
+ * the model picks via `op`. The call dispatches to the auto-registered
155
+ * `sandbox:invoke` action, which carries `ctx.containers`.
156
+ *
157
+ * By default a read-only (GET/HEAD/OPTIONS, or method-omitted) `fetch` runs
158
+ * unattended while everything else is gated behind a human approval — an
159
+ * `exec`; a `fetch` whose path resolves to the privileged `/exec` route (both
160
+ * reach the same command-execution path in the container, so gating on the
161
+ * `op` name alone would let a `fetch` to `/exec` run a command unattended);
162
+ * and a `fetch` using a non-idempotent method (POST/PUT/PATCH/DELETE) to ANY
163
+ * route, since a prompt-injected model could otherwise mutate container state
164
+ * through some other privileged route just by avoiding the literal `/exec`
165
+ * path. A `fetch` can still reach any *other read* route unattended, so scope
166
+ * the container's GET routes accordingly. Pass `opts.needsApproval` to widen
167
+ * or disable the gate.
168
+ *
169
+ * ```ts
170
+ * import { containerTool, defineAgent } from "@lunora/agent/sandbox";
171
+ *
172
+ * export const ops = defineAgent({
173
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
174
+ * tools: { sandbox: containerTool("sandbox") },
175
+ * });
176
+ * ```
177
+ * @experimental
178
+ */
179
179
  declare const containerTool: (name: string, options?: ContainerToolOptions) => AgentToolDefinition<ContainerToolInput, string>;
180
180
  /**
181
- * A batteries-included agent tool exposing a persistent, R2-backed virtual
182
- * filesystem. `bucket` is the R2 binding name; every path is scoped under the
183
- * pinned `opts.root` (a `..` that would escape it is rejected). One tool exposes
184
- * `ls`/`read`/`write`/`rm`/`stat`; the model picks via `op`. The call dispatches
185
- * to the auto-registered `sandbox:invoke` action, which reads the bucket from
186
- * `ctx.env`. workerd has no real shell — this is object-store-backed file I/O.
187
- *
188
- * By default the writing ops (`write`/`rm`) pause for a human approval while
189
- * reads run unattended; pass `opts.needsApproval` to change that. Importing the
190
- * tool registers the dispatcher; the app must declare the `r2_bucket` binding in
191
- * `wrangler.jsonc` (the fs op throws a directed error until it is wired).
192
- *
193
- * ```ts
194
- * import { defineAgent, fsTool } from "@lunora/agent/sandbox";
195
- *
196
- * export const coder = defineAgent({
197
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
198
- * tools: { fs: fsTool("SANDBOX_BUCKET", { root: "agents/coder" }) },
199
- * });
200
- * ```
201
- * @experimental
202
- */
181
+ * A batteries-included agent tool exposing a persistent, R2-backed virtual
182
+ * filesystem. `bucket` is the R2 binding name; every path is scoped under the
183
+ * pinned `opts.root` (a `..` that would escape it is rejected). One tool exposes
184
+ * `ls`/`read`/`write`/`rm`/`stat`; the model picks via `op`. The call dispatches
185
+ * to the auto-registered `sandbox:invoke` action, which reads the bucket from
186
+ * `ctx.env`. workerd has no real shell — this is object-store-backed file I/O.
187
+ *
188
+ * By default the writing ops (`write`/`rm`) pause for a human approval while
189
+ * reads run unattended; pass `opts.needsApproval` to change that. Importing the
190
+ * tool registers the dispatcher; the app must declare the `r2_bucket` binding in
191
+ * `wrangler.jsonc` (the fs op throws a directed error until it is wired).
192
+ *
193
+ * ```ts
194
+ * import { defineAgent, fsTool } from "@lunora/agent/sandbox";
195
+ *
196
+ * export const coder = defineAgent({
197
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
198
+ * tools: { fs: fsTool("SANDBOX_BUCKET", { root: "agents/coder" }) },
199
+ * });
200
+ * ```
201
+ * @experimental
202
+ */
203
203
  declare const fsTool: (bucket: string, options?: FsToolOptions) => AgentToolDefinition<FsToolInput>;
204
204
  export { type BrowserToolInput, type BrowserToolOptions, type ContainerToolInput, type ContainerToolOptions, type FsToolInput, type FsToolOptions, browserTool, containerTool, fsTool };
package/dist/sandbox.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-BhJFTvz_.js";
1
+ import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-boAM2Yi1.js";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
5
- * The model-provided input to a {@link browserTool} call — a discriminated
6
- * union on `op` so one tool exposes every headless-browser capability.
7
- * @experimental
8
- */
5
+ * The model-provided input to a {@link browserTool} call — a discriminated
6
+ * union on `op` so one tool exposes every headless-browser capability.
7
+ * @experimental
8
+ */
9
9
  type BrowserToolInput = {
10
10
  fullPage?: boolean;
11
11
  op: "screenshot";
@@ -23,12 +23,12 @@ type BrowserToolInput = {
23
23
  url: string;
24
24
  };
25
25
  /**
26
- * The model-provided input to a {@link containerTool} call — a discriminated
27
- * union on `op`. `fetch` sends an HTTP request to the container; `exec` asks it
28
- * to run a command (routed as a POST to `/exec`, since the container surface
29
- * exposes no first-class exec RPC — the container app must serve that route).
30
- * @experimental
31
- */
26
+ * The model-provided input to a {@link containerTool} call — a discriminated
27
+ * union on `op`. `fetch` sends an HTTP request to the container; `exec` asks it
28
+ * to run a command (routed as a POST to `/exec`, since the container surface
29
+ * exposes no first-class exec RPC — the container app must serve that route).
30
+ * @experimental
31
+ */
32
32
  type ContainerToolInput = {
33
33
  args?: string[];
34
34
  command?: string;
@@ -40,28 +40,28 @@ type ContainerToolInput = {
40
40
  path: string;
41
41
  };
42
42
  /**
43
- * Author-supplied config for `browserTool`.
44
- * @experimental
45
- */
43
+ * Author-supplied config for `browserTool`.
44
+ * @experimental
45
+ */
46
46
  interface BrowserToolOptions {
47
47
  /** Override the model-facing description (what the tool does). */
48
48
  description?: string;
49
49
  /**
50
- * Gate a call behind a human approval. Defaults to **unattended** (no gate),
51
- * matching the AI SDK. `browserTool` fetches a model-chosen `url` with no
52
- * allowlist, so it is an SSRF surface: a prompt-injected model can point it at
53
- * an internal/link-local address and read the response back into context. Pass
54
- * a boolean or a predicate to gate it (evaluated from replay-stable input, so
55
- * keep it deterministic).
56
- */
50
+ * Gate a call behind a human approval. Defaults to **unattended** (no gate),
51
+ * matching the AI SDK. `browserTool` fetches a model-chosen `url` with no
52
+ * allowlist, so it is an SSRF surface: a prompt-injected model can point it at
53
+ * an internal/link-local address and read the response back into context. Pass
54
+ * a boolean or a predicate to gate it (evaluated from replay-stable input, so
55
+ * keep it deterministic).
56
+ */
57
57
  needsApproval?: ((input: BrowserToolInput) => boolean) | boolean;
58
58
  }
59
59
  /**
60
- * The model-provided input to a {@link fsTool} call — a discriminated union on
61
- * `op` over an R2-backed virtual filesystem. Paths are relative to the tool's
62
- * pinned `root`; a `..` that escapes the root is rejected server-side.
63
- * @experimental
64
- */
60
+ * The model-provided input to a {@link fsTool} call — a discriminated union on
61
+ * `op` over an R2-backed virtual filesystem. Paths are relative to the tool's
62
+ * pinned `root`; a `..` that escapes the root is rejected server-side.
63
+ * @experimental
64
+ */
65
65
  type FsToolInput = {
66
66
  op: "ls";
67
67
  path?: string;
@@ -80,125 +80,125 @@ type FsToolInput = {
80
80
  path: string;
81
81
  };
82
82
  /**
83
- * Author-supplied config for `fsTool`.
84
- * @experimental
85
- */
83
+ * Author-supplied config for `fsTool`.
84
+ * @experimental
85
+ */
86
86
  interface FsToolOptions {
87
87
  /** Override the model-facing description (what the tool does). */
88
88
  description?: string;
89
89
  /**
90
- * Gate a call behind a human approval. Defaults to gating the WRITING ops
91
- * (`write`, `rm`) — a prompt-injected model shouldn't silently overwrite or
92
- * delete the sandbox — while `ls`/`read`/`stat` run unattended. Pass a boolean
93
- * or a predicate (evaluated from replay-stable input, so keep it deterministic).
94
- */
90
+ * Gate a call behind a human approval. Defaults to gating the WRITING ops
91
+ * (`write`, `rm`) — a prompt-injected model shouldn't silently overwrite or
92
+ * delete the sandbox — while `ls`/`read`/`stat` run unattended. Pass a boolean
93
+ * or a predicate (evaluated from replay-stable input, so keep it deterministic).
94
+ */
95
95
  needsApproval?: ((input: FsToolInput) => boolean) | boolean;
96
96
  /**
97
- * The key prefix every path is scoped under, isolating this tool's files from
98
- * the rest of the bucket. Either a fixed string (e.g. `"agents/support"`) or a
99
- * function of the tool context — return `` `agents/${ctx.threadKey}` `` (or an
100
- * owner-derived prefix) to give each run/user its OWN namespace in a
101
- * multi-tenant agent. Default: the bucket root (shared — set a root for
102
- * multi-tenant use). The server rejects any `..` that would escape it.
103
- */
97
+ * The key prefix every path is scoped under, isolating this tool's files from
98
+ * the rest of the bucket. Either a fixed string (e.g. `"agents/support"`) or a
99
+ * function of the tool context — return `` `agents/${ctx.threadKey}` `` (or an
100
+ * owner-derived prefix) to give each run/user its OWN namespace in a
101
+ * multi-tenant agent. Default: the bucket root (shared — set a root for
102
+ * multi-tenant use). The server rejects any `..` that would escape it.
103
+ */
104
104
  root?: ((context: AgentToolContext) => string) | string;
105
105
  }
106
106
  /**
107
- * Author-supplied config for `containerTool`.
108
- * @experimental
109
- */
107
+ * Author-supplied config for `containerTool`.
108
+ * @experimental
109
+ */
110
110
  interface ContainerToolOptions {
111
111
  /** Override the model-facing description (what the tool does). */
112
112
  description?: string;
113
113
  /**
114
- * Gate a call behind a human approval. Defaults to gating any command
115
- * execution: an `exec`, AND a `fetch` whose path resolves to the privileged
116
- * `/exec` route (both reach the same command-execution path in the container,
117
- * so gating on the `op` name alone would let a `fetch` to `/exec` run a
118
- * command unattended). A plain `fetch` to any other route runs unattended.
119
- * Pass a boolean or your own predicate to change that. Evaluated from
120
- * replay-stable input, so keep it deterministic.
121
- */
114
+ * Gate a call behind a human approval. Defaults to gating any command
115
+ * execution: an `exec`, AND a `fetch` whose path resolves to the privileged
116
+ * `/exec` route (both reach the same command-execution path in the container,
117
+ * so gating on the `op` name alone would let a `fetch` to `/exec` run a
118
+ * command unattended). A plain `fetch` to any other route runs unattended.
119
+ * Pass a boolean or your own predicate to change that. Evaluated from
120
+ * replay-stable input, so keep it deterministic.
121
+ */
122
122
  needsApproval?: ((input: ContainerToolInput) => boolean) | boolean;
123
123
  }
124
124
  /**
125
- * A batteries-included agent tool that drives Cloudflare Browser Rendering. One
126
- * tool exposes every browser op (screenshot / pdf / content / scrape); the model
127
- * picks via `op`. The call dispatches to the auto-registered `sandbox:invoke`
128
- * action — which runs on an action ctx carrying `ctx.browser`. Importing the tool
129
- * makes codegen register the dispatcher and provision the `BROWSER` binding; like
130
- * any `ctx.browser` user, the app still supplies a `config.browser` thunk
131
- * (`createBrowser({ binding: env.BROWSER, launch })` with the optional
132
- * `@cloudflare/playwright` `launch` peer) to `createShardDO()` — codegen never
133
- * injects that peer, so the browser op throws a directed error until it is wired.
134
- *
135
- * Security: the model chooses the `url` with no allowlist, so this is an SSRF
136
- * surface — pass `opts.needsApproval` to gate calls a prompt-injected model
137
- * could aim at internal/link-local endpoints.
138
- *
139
- * ```ts
140
- * import { browserTool, defineAgent } from "@lunora/agent/sandbox";
141
- *
142
- * export const researcher = defineAgent({
143
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
144
- * tools: { browser: browserTool() },
145
- * });
146
- * ```
147
- * @experimental
148
- */
125
+ * A batteries-included agent tool that drives Cloudflare Browser Rendering. One
126
+ * tool exposes every browser op (screenshot / pdf / content / scrape); the model
127
+ * picks via `op`. The call dispatches to the auto-registered `sandbox:invoke`
128
+ * action — which runs on an action ctx carrying `ctx.browser`. Importing the tool
129
+ * makes codegen register the dispatcher and provision the `BROWSER` binding; like
130
+ * any `ctx.browser` user, the app still supplies a `config.browser` thunk
131
+ * (`createBrowser({ binding: env.BROWSER, launch })` with the optional
132
+ * `@cloudflare/playwright` `launch` peer) to `createShardDO()` — codegen never
133
+ * injects that peer, so the browser op throws a directed error until it is wired.
134
+ *
135
+ * Security: the model chooses the `url` with no allowlist, so this is an SSRF
136
+ * surface — pass `opts.needsApproval` to gate calls a prompt-injected model
137
+ * could aim at internal/link-local endpoints.
138
+ *
139
+ * ```ts
140
+ * import { browserTool, defineAgent } from "@lunora/agent/sandbox";
141
+ *
142
+ * export const researcher = defineAgent({
143
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
144
+ * tools: { browser: browserTool() },
145
+ * });
146
+ * ```
147
+ * @experimental
148
+ */
149
149
  declare const browserTool: (options?: BrowserToolOptions) => AgentToolDefinition<BrowserToolInput, string>;
150
150
  /**
151
- * A batteries-included agent tool that talks to a declared Cloudflare
152
- * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
153
- * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
- * the model picks via `op`. The call dispatches to the auto-registered
155
- * `sandbox:invoke` action, which carries `ctx.containers`.
156
- *
157
- * By default a read-only (GET/HEAD/OPTIONS, or method-omitted) `fetch` runs
158
- * unattended while everything else is gated behind a human approval — an
159
- * `exec`; a `fetch` whose path resolves to the privileged `/exec` route (both
160
- * reach the same command-execution path in the container, so gating on the
161
- * `op` name alone would let a `fetch` to `/exec` run a command unattended);
162
- * and a `fetch` using a non-idempotent method (POST/PUT/PATCH/DELETE) to ANY
163
- * route, since a prompt-injected model could otherwise mutate container state
164
- * through some other privileged route just by avoiding the literal `/exec`
165
- * path. A `fetch` can still reach any *other read* route unattended, so scope
166
- * the container's GET routes accordingly. Pass `opts.needsApproval` to widen
167
- * or disable the gate.
168
- *
169
- * ```ts
170
- * import { containerTool, defineAgent } from "@lunora/agent/sandbox";
171
- *
172
- * export const ops = defineAgent({
173
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
174
- * tools: { sandbox: containerTool("sandbox") },
175
- * });
176
- * ```
177
- * @experimental
178
- */
151
+ * A batteries-included agent tool that talks to a declared Cloudflare
152
+ * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
153
+ * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
+ * the model picks via `op`. The call dispatches to the auto-registered
155
+ * `sandbox:invoke` action, which carries `ctx.containers`.
156
+ *
157
+ * By default a read-only (GET/HEAD/OPTIONS, or method-omitted) `fetch` runs
158
+ * unattended while everything else is gated behind a human approval — an
159
+ * `exec`; a `fetch` whose path resolves to the privileged `/exec` route (both
160
+ * reach the same command-execution path in the container, so gating on the
161
+ * `op` name alone would let a `fetch` to `/exec` run a command unattended);
162
+ * and a `fetch` using a non-idempotent method (POST/PUT/PATCH/DELETE) to ANY
163
+ * route, since a prompt-injected model could otherwise mutate container state
164
+ * through some other privileged route just by avoiding the literal `/exec`
165
+ * path. A `fetch` can still reach any *other read* route unattended, so scope
166
+ * the container's GET routes accordingly. Pass `opts.needsApproval` to widen
167
+ * or disable the gate.
168
+ *
169
+ * ```ts
170
+ * import { containerTool, defineAgent } from "@lunora/agent/sandbox";
171
+ *
172
+ * export const ops = defineAgent({
173
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
174
+ * tools: { sandbox: containerTool("sandbox") },
175
+ * });
176
+ * ```
177
+ * @experimental
178
+ */
179
179
  declare const containerTool: (name: string, options?: ContainerToolOptions) => AgentToolDefinition<ContainerToolInput, string>;
180
180
  /**
181
- * A batteries-included agent tool exposing a persistent, R2-backed virtual
182
- * filesystem. `bucket` is the R2 binding name; every path is scoped under the
183
- * pinned `opts.root` (a `..` that would escape it is rejected). One tool exposes
184
- * `ls`/`read`/`write`/`rm`/`stat`; the model picks via `op`. The call dispatches
185
- * to the auto-registered `sandbox:invoke` action, which reads the bucket from
186
- * `ctx.env`. workerd has no real shell — this is object-store-backed file I/O.
187
- *
188
- * By default the writing ops (`write`/`rm`) pause for a human approval while
189
- * reads run unattended; pass `opts.needsApproval` to change that. Importing the
190
- * tool registers the dispatcher; the app must declare the `r2_bucket` binding in
191
- * `wrangler.jsonc` (the fs op throws a directed error until it is wired).
192
- *
193
- * ```ts
194
- * import { defineAgent, fsTool } from "@lunora/agent/sandbox";
195
- *
196
- * export const coder = defineAgent({
197
- * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
198
- * tools: { fs: fsTool("SANDBOX_BUCKET", { root: "agents/coder" }) },
199
- * });
200
- * ```
201
- * @experimental
202
- */
181
+ * A batteries-included agent tool exposing a persistent, R2-backed virtual
182
+ * filesystem. `bucket` is the R2 binding name; every path is scoped under the
183
+ * pinned `opts.root` (a `..` that would escape it is rejected). One tool exposes
184
+ * `ls`/`read`/`write`/`rm`/`stat`; the model picks via `op`. The call dispatches
185
+ * to the auto-registered `sandbox:invoke` action, which reads the bucket from
186
+ * `ctx.env`. workerd has no real shell — this is object-store-backed file I/O.
187
+ *
188
+ * By default the writing ops (`write`/`rm`) pause for a human approval while
189
+ * reads run unattended; pass `opts.needsApproval` to change that. Importing the
190
+ * tool registers the dispatcher; the app must declare the `r2_bucket` binding in
191
+ * `wrangler.jsonc` (the fs op throws a directed error until it is wired).
192
+ *
193
+ * ```ts
194
+ * import { defineAgent, fsTool } from "@lunora/agent/sandbox";
195
+ *
196
+ * export const coder = defineAgent({
197
+ * model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
198
+ * tools: { fs: fsTool("SANDBOX_BUCKET", { root: "agents/coder" }) },
199
+ * });
200
+ * ```
201
+ * @experimental
202
+ */
203
203
  declare const fsTool: (bucket: string, options?: FsToolOptions) => AgentToolDefinition<FsToolInput>;
204
204
  export { type BrowserToolInput, type BrowserToolOptions, type ContainerToolInput, type ContainerToolOptions, type FsToolInput, type FsToolOptions, browserTool, containerTool, fsTool };