noumen 0.6.0 → 0.8.0
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 +237 -93
- package/dist/a2a/index.d.ts +5 -7
- package/dist/a2a/index.js +3 -4
- package/dist/a2a/index.js.map +1 -1
- package/dist/acp/index.d.ts +5 -7
- package/dist/acp/index.js +0 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/{agent-DWE4_P5X.d.ts → agent-D0gl-qYi.d.ts} +89 -34
- package/dist/{chunk-6MMYCGJQ.js → chunk-5HY4IYNT.js} +1529 -2321
- package/dist/chunk-5HY4IYNT.js.map +1 -0
- package/dist/chunk-BC5BLWBC.js +21 -0
- package/dist/chunk-BC5BLWBC.js.map +1 -0
- package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
- package/dist/chunk-CX4BL6PC.js.map +1 -0
- package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
- package/dist/chunk-HQISH4D7.js.map +1 -0
- package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
- package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
- package/dist/chunk-OPFFLQZL.js +40 -0
- package/dist/chunk-OPFFLQZL.js.map +1 -0
- package/dist/chunk-PDEAJ272.js +660 -0
- package/dist/chunk-PDEAJ272.js.map +1 -0
- package/dist/chunk-PKHLGGEC.js +115 -0
- package/dist/chunk-PKHLGGEC.js.map +1 -0
- package/dist/chunk-XQTNXRE7.js +176 -0
- package/dist/chunk-XQTNXRE7.js.map +1 -0
- package/dist/chunk-XZPAA5TO.js +817 -0
- package/dist/chunk-XZPAA5TO.js.map +1 -0
- package/dist/cli/index.js +77 -42
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.js +0 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client-JJFLE6RT.js +9 -0
- package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
- package/dist/docker.d.ts +2 -2
- package/dist/docker.js +0 -1
- package/dist/docker.js.map +1 -1
- package/dist/e2b.d.ts +2 -2
- package/dist/e2b.js +0 -1
- package/dist/e2b.js.map +1 -1
- package/dist/freestyle.d.ts +2 -2
- package/dist/freestyle.js +0 -1
- package/dist/freestyle.js.map +1 -1
- package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
- package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
- package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
- package/dist/index.d.ts +351 -72
- package/dist/index.js +54 -55
- package/dist/jsonrpc/index.js +0 -1
- package/dist/local.d.ts +168 -0
- package/dist/local.js +40 -0
- package/dist/local.js.map +1 -0
- package/dist/lsp/index.d.ts +4 -5
- package/dist/lsp/index.js +0 -1
- package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
- package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
- package/dist/mcp/index.d.ts +16 -8
- package/dist/mcp/index.js +5 -6
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
- package/dist/{provider-factory-TUHU3DIG.js → provider-factory-KNBSHXJ6.js} +3 -3
- package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
- package/dist/{resolve-6KUZNEYW.js → resolve-AGQZFMKD.js} +3 -3
- package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
- package/dist/sandbox-index-ODNREIFA.js +32 -0
- package/dist/sandbox-index-ODNREIFA.js.map +1 -0
- package/dist/server/index.d.ts +18 -7
- package/dist/server/index.js +9 -5
- package/dist/server/index.js.map +1 -1
- package/dist/{server-BzNGKTP6.d.ts → server-DFXdlqyX.d.ts} +1 -1
- package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
- package/dist/sprites.d.ts +2 -2
- package/dist/sprites.js +0 -1
- package/dist/sprites.js.map +1 -1
- package/dist/ssh.d.ts +2 -2
- package/dist/ssh.js +0 -1
- package/dist/ssh.js.map +1 -1
- package/dist/{types-DhXwOQwD.d.ts → types-BX4ALqoN.d.ts} +76 -4
- package/dist/{types-kiGBF35b.d.ts → types-DLZNyF5t.d.ts} +125 -1
- package/dist/unsandboxed.d.ts +59 -0
- package/dist/unsandboxed.js +32 -0
- package/dist/unsandboxed.js.map +1 -0
- package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
- package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
- package/package.json +35 -50
- package/dist/cache-BlBwXXPS.d.ts +0 -38
- package/dist/chunk-5GEX6ZSB.js.map +0 -1
- package/dist/chunk-6MMYCGJQ.js.map +0 -1
- package/dist/chunk-7IQCQI2G.js +0 -94
- package/dist/chunk-7IQCQI2G.js.map +0 -1
- package/dist/chunk-CCM2AXZG.js +0 -16
- package/dist/chunk-CCM2AXZG.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-HEQQQGK5.js +0 -131
- package/dist/chunk-HEQQQGK5.js.map +0 -1
- package/dist/chunk-I3JTUFPK.js +0 -171
- package/dist/chunk-I3JTUFPK.js.map +0 -1
- package/dist/chunk-XZN4QZLK.js.map +0 -1
- package/dist/chunk-ZXSDKBYB.js +0 -474
- package/dist/chunk-ZXSDKBYB.js.map +0 -1
- package/dist/client-CRRO2376.js +0 -10
- package/dist/providers/anthropic.d.ts +0 -19
- package/dist/providers/anthropic.js +0 -36
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/bedrock.d.ts +0 -39
- package/dist/providers/bedrock.js +0 -56
- package/dist/providers/bedrock.js.map +0 -1
- package/dist/providers/gemini.d.ts +0 -17
- package/dist/providers/gemini.js +0 -262
- package/dist/providers/gemini.js.map +0 -1
- package/dist/providers/ollama.d.ts +0 -13
- package/dist/providers/ollama.js +0 -20
- package/dist/providers/ollama.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -21
- package/dist/providers/openai.js +0 -9
- package/dist/providers/openrouter.d.ts +0 -16
- package/dist/providers/openrouter.js +0 -24
- package/dist/providers/openrouter.js.map +0 -1
- package/dist/providers/vertex.d.ts +0 -42
- package/dist/providers/vertex.js +0 -68
- package/dist/providers/vertex.js.map +0 -1
- package/dist/sandbox-9qeMTNrD.d.ts +0 -126
- package/dist/types-CD0rUKKT.d.ts +0 -109
- package/dist/uuid-RVN2T26F.js.map +0 -1
- package/dist/zod-7YXKWYMC.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
- /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
- /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
- /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
- /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
- /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
- /package/dist/{provider-factory-TUHU3DIG.js.map → render-4VEODRK7.js.map} +0 -0
- /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
- /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
- /package/dist/{resolve-6KUZNEYW.js.map → uuid-CVTNAPEB.js.map} +0 -0
- /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
package/README.md
CHANGED
|
@@ -14,28 +14,37 @@ Any provider. Any sandbox. One package.
|
|
|
14
14
|
pnpm add noumen
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Then install the
|
|
17
|
+
Then install the Vercel AI SDK package for the provider you want:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
pnpm add openai
|
|
21
|
-
pnpm add @
|
|
22
|
-
pnpm add @google
|
|
23
|
-
|
|
20
|
+
pnpm add @ai-sdk/openai # OpenAI
|
|
21
|
+
pnpm add @ai-sdk/anthropic # Anthropic
|
|
22
|
+
pnpm add @ai-sdk/google # Google Gemini
|
|
23
|
+
pnpm add @openrouter/ai-sdk-provider # OpenRouter
|
|
24
|
+
pnpm add @ai-sdk/amazon-bedrock # AWS Bedrock
|
|
25
|
+
pnpm add @ai-sdk/google-vertex # Google Vertex AI
|
|
26
|
+
pnpm add ollama-ai-provider-v2 # Ollama (local)
|
|
24
27
|
```
|
|
25
28
|
|
|
29
|
+
noumen wraps any Vercel AI SDK `LanguageModel` via a single `AiSdkProvider` adapter — install only the packages for the providers you actually use.
|
|
30
|
+
|
|
26
31
|
## Quick Start
|
|
27
32
|
|
|
28
33
|
```typescript
|
|
29
|
-
import {
|
|
34
|
+
import { LocalAgent } from "noumen/local";
|
|
30
35
|
|
|
31
|
-
const agent =
|
|
36
|
+
const agent = LocalAgent({ provider: "anthropic", cwd: "." });
|
|
32
37
|
|
|
33
38
|
for await (const event of agent.run("Add a health-check endpoint to server.ts")) {
|
|
34
39
|
if (event.type === "text_delta") process.stdout.write(event.text);
|
|
35
40
|
}
|
|
36
41
|
```
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
A working agent in three lines. `LocalAgent` is a convenience factory that constructs an [`Agent`](#embedding) wired to a `LocalSandbox` (OS-level sandboxing via `@anthropic-ai/sandbox-runtime`) — use it whenever you want the host's filesystem and shell, isolated. The string provider auto-detects your `ANTHROPIC_API_KEY` from the environment.
|
|
44
|
+
|
|
45
|
+
Want raw host access with no isolation? Swap `noumen/local` → `noumen/unsandboxed` and `LocalAgent` → `UnsandboxedAgent`. Want a remote sandbox? Use `new Agent({ provider, sandbox })` directly — see [Sandboxes](#sandboxes) for every backend.
|
|
46
|
+
|
|
47
|
+
> **Why the subpath import?** The root barrel (`import { Agent } from "noumen"`) deliberately never pulls a default sandbox into the module graph — that keeps `noumen` lightweight for apps that bundle with Next.js NFT or serverless-webpack and only use a remote sandbox. Opting into a local sandbox is an explicit import line. See [Sandboxes](#sandboxes).
|
|
39
48
|
|
|
40
49
|
### Execute (run to completion)
|
|
41
50
|
|
|
@@ -52,11 +61,14 @@ console.log(`Done — ${result.toolCalls} tool calls`);
|
|
|
52
61
|
### Full control
|
|
53
62
|
|
|
54
63
|
```typescript
|
|
55
|
-
import { Agent,
|
|
56
|
-
import {
|
|
64
|
+
import { Agent, AiSdkProvider } from "noumen";
|
|
65
|
+
import { LocalSandbox } from "noumen/local";
|
|
66
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
67
|
+
|
|
68
|
+
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
57
69
|
|
|
58
70
|
const agent = new Agent({
|
|
59
|
-
provider: new
|
|
71
|
+
provider: new AiSdkProvider({ model: openai.chat("gpt-5") }),
|
|
60
72
|
sandbox: LocalSandbox({ cwd: "/my/project" }),
|
|
61
73
|
});
|
|
62
74
|
|
|
@@ -82,12 +94,16 @@ for await (const event of thread.run("Refactor the auth module")) {
|
|
|
82
94
|
For zero-config setup, use a preset that configures everything for you:
|
|
83
95
|
|
|
84
96
|
```typescript
|
|
85
|
-
import { codingAgent } from "noumen";
|
|
86
|
-
import {
|
|
97
|
+
import { codingAgent, AiSdkProvider } from "noumen";
|
|
98
|
+
import { LocalSandbox } from "noumen/local";
|
|
99
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
100
|
+
|
|
101
|
+
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY! });
|
|
87
102
|
|
|
88
103
|
const agent = codingAgent({
|
|
89
|
-
provider: new
|
|
104
|
+
provider: new AiSdkProvider({ model: openai.chat("gpt-5") }),
|
|
90
105
|
cwd: "/my/project",
|
|
106
|
+
sandbox: LocalSandbox({ cwd: "/my/project" }),
|
|
91
107
|
});
|
|
92
108
|
|
|
93
109
|
await agent.init();
|
|
@@ -100,6 +116,8 @@ for await (const event of thread.run("Refactor the auth module")) {
|
|
|
100
116
|
await agent.close();
|
|
101
117
|
```
|
|
102
118
|
|
|
119
|
+
Presets require an explicit `sandbox` for the same bundler-hygiene reason — pick a backend from its subpath (`noumen/local`, `noumen/unsandboxed`, `noumen/docker`, …).
|
|
120
|
+
|
|
103
121
|
Three presets are available:
|
|
104
122
|
|
|
105
123
|
| Preset | Mode | Includes |
|
|
@@ -249,143 +267,234 @@ npx noumen doctor
|
|
|
249
267
|
|
|
250
268
|
## Providers
|
|
251
269
|
|
|
270
|
+
noumen wraps any [Vercel AI SDK](https://sdk.vercel.ai) `LanguageModel` via a single `AiSdkProvider` adapter. Install the `@ai-sdk/*` package for the vendor you want, hand its model instance to `AiSdkProvider`, and pass the result to `Agent`. Every provider follows the same three-line pattern:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { AiSdkProvider } from "noumen";
|
|
274
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
275
|
+
|
|
276
|
+
const provider = new AiSdkProvider({
|
|
277
|
+
model: createOpenAI({ apiKey: process.env.OPENAI_API_KEY })("gpt-5"),
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Option on `AiSdkProvider` | Description |
|
|
282
|
+
| --- | --- |
|
|
283
|
+
| `model` | Any AI SDK `LanguageModelV2` / `V3` instance. Required. |
|
|
284
|
+
| `defaultModel` | Override the model id reported by `provider.defaultModel`. |
|
|
285
|
+
| `providerFamily` | `"openai" \| "anthropic" \| "google"` — controls how noumen maps thinking / reasoning / cache options. Inferred from the model by default; set explicitly when going through a custom proxy. |
|
|
286
|
+
| `cacheConfig` | `{ enabled: true }` inserts an Anthropic `cache_control` breakpoint and honors `ChatParams.skipCacheWrite`. No-op for non-Anthropic families. |
|
|
287
|
+
|
|
288
|
+
Per-call options (`thinking`, `reasoningEffort`, `outputFormat`, `skipCacheWrite`, etc.) continue to flow through `ChatParams` / `AgentOptions` exactly like before — the adapter routes them to the right `providerOptions.*` entry for the detected family.
|
|
289
|
+
|
|
252
290
|
### OpenAI
|
|
253
291
|
|
|
292
|
+
```bash
|
|
293
|
+
pnpm add @ai-sdk/openai
|
|
294
|
+
```
|
|
295
|
+
|
|
254
296
|
```typescript
|
|
255
|
-
import {
|
|
297
|
+
import { AiSdkProvider } from "noumen";
|
|
298
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
256
299
|
|
|
257
|
-
const
|
|
258
|
-
apiKey:
|
|
259
|
-
|
|
260
|
-
baseURL: "https://...", // optional, for compatible APIs
|
|
300
|
+
const openai = createOpenAI({
|
|
301
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
302
|
+
baseURL: "https://...", // optional, for Azure / proxies / compatible APIs
|
|
261
303
|
});
|
|
304
|
+
|
|
305
|
+
// `.chat(id)` pins to chat/completions. Drop it to use the Responses API.
|
|
306
|
+
const provider = new AiSdkProvider({ model: openai.chat("gpt-5") });
|
|
262
307
|
```
|
|
263
308
|
|
|
264
309
|
### Anthropic
|
|
265
310
|
|
|
311
|
+
```bash
|
|
312
|
+
pnpm add @ai-sdk/anthropic
|
|
313
|
+
```
|
|
314
|
+
|
|
266
315
|
```typescript
|
|
267
|
-
import {
|
|
316
|
+
import { AiSdkProvider } from "noumen";
|
|
317
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
318
|
+
|
|
319
|
+
const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
268
320
|
|
|
269
|
-
const provider = new
|
|
270
|
-
|
|
271
|
-
|
|
321
|
+
const provider = new AiSdkProvider({
|
|
322
|
+
model: anthropic("claude-opus-4.6"),
|
|
323
|
+
providerFamily: "anthropic",
|
|
324
|
+
cacheConfig: { enabled: true }, // prompt caching
|
|
272
325
|
});
|
|
273
326
|
```
|
|
274
327
|
|
|
275
328
|
### Google Gemini
|
|
276
329
|
|
|
330
|
+
```bash
|
|
331
|
+
pnpm add @ai-sdk/google
|
|
332
|
+
```
|
|
333
|
+
|
|
277
334
|
```typescript
|
|
278
|
-
import {
|
|
335
|
+
import { AiSdkProvider } from "noumen";
|
|
336
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
337
|
+
|
|
338
|
+
const google = createGoogleGenerativeAI({ apiKey: process.env.GEMINI_API_KEY });
|
|
279
339
|
|
|
280
|
-
const provider = new
|
|
281
|
-
|
|
282
|
-
|
|
340
|
+
const provider = new AiSdkProvider({
|
|
341
|
+
model: google("gemini-2.5-flash"),
|
|
342
|
+
providerFamily: "google",
|
|
283
343
|
});
|
|
284
344
|
```
|
|
285
345
|
|
|
286
346
|
### OpenRouter
|
|
287
347
|
|
|
348
|
+
```bash
|
|
349
|
+
pnpm add @openrouter/ai-sdk-provider
|
|
350
|
+
```
|
|
351
|
+
|
|
288
352
|
```typescript
|
|
289
|
-
import {
|
|
353
|
+
import { AiSdkProvider } from "noumen";
|
|
354
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
355
|
+
|
|
356
|
+
const openrouter = createOpenRouter({
|
|
357
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
358
|
+
headers: {
|
|
359
|
+
"HTTP-Referer": "https://myapp.com", // optional, for openrouter.ai rankings
|
|
360
|
+
"X-Title": "My Agent", // optional
|
|
361
|
+
},
|
|
362
|
+
});
|
|
290
363
|
|
|
291
|
-
const provider = new
|
|
292
|
-
|
|
293
|
-
model: "anthropic/claude-sonnet-4", // default
|
|
294
|
-
appName: "My Agent", // optional, for openrouter.ai rankings
|
|
295
|
-
appUrl: "https://myapp.com", // optional
|
|
364
|
+
const provider = new AiSdkProvider({
|
|
365
|
+
model: openrouter.chat("anthropic/claude-opus-4.6"),
|
|
296
366
|
});
|
|
297
367
|
```
|
|
298
368
|
|
|
299
|
-
### AWS Bedrock
|
|
369
|
+
### AWS Bedrock
|
|
300
370
|
|
|
301
|
-
Route
|
|
371
|
+
Route Claude (and any other Bedrock-hosted model) through AWS Bedrock.
|
|
302
372
|
|
|
303
373
|
```bash
|
|
304
|
-
pnpm add @
|
|
374
|
+
pnpm add @ai-sdk/amazon-bedrock
|
|
305
375
|
```
|
|
306
376
|
|
|
307
377
|
```typescript
|
|
308
|
-
import {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
sessionToken: process.env.AWS_SESSION_TOKEN,
|
|
317
|
-
},
|
|
318
|
-
cacheControl: { enabled: true }, // optional prompt caching
|
|
378
|
+
import { AiSdkProvider } from "noumen";
|
|
379
|
+
import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock";
|
|
380
|
+
|
|
381
|
+
const bedrock = createAmazonBedrock({
|
|
382
|
+
region: process.env.AWS_REGION ?? "us-east-1",
|
|
383
|
+
// Credentials resolved from the standard AWS credential chain
|
|
384
|
+
// (env vars, ~/.aws/credentials, IAM roles) unless you pass
|
|
385
|
+
// explicit accessKeyId / secretAccessKey / sessionToken.
|
|
319
386
|
});
|
|
320
|
-
```
|
|
321
387
|
|
|
322
|
-
|
|
388
|
+
const provider = new AiSdkProvider({
|
|
389
|
+
model: bedrock("us.anthropic.claude-opus-4.6-v1:0"),
|
|
390
|
+
providerFamily: "anthropic",
|
|
391
|
+
cacheConfig: { enabled: true },
|
|
392
|
+
});
|
|
393
|
+
```
|
|
323
394
|
|
|
324
|
-
### Google Vertex AI
|
|
395
|
+
### Google Vertex AI
|
|
325
396
|
|
|
326
|
-
Route
|
|
397
|
+
Route Claude or native Gemini through Google Cloud Vertex AI.
|
|
327
398
|
|
|
328
399
|
```bash
|
|
329
|
-
pnpm add @
|
|
400
|
+
pnpm add @ai-sdk/google-vertex
|
|
330
401
|
```
|
|
331
402
|
|
|
332
403
|
```typescript
|
|
333
|
-
import {
|
|
404
|
+
import { AiSdkProvider } from "noumen";
|
|
405
|
+
import { createVertex } from "@ai-sdk/google-vertex";
|
|
334
406
|
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
cacheControl: { enabled: true }, // optional prompt caching
|
|
407
|
+
const vertex = createVertex({
|
|
408
|
+
project: process.env.GOOGLE_CLOUD_PROJECT,
|
|
409
|
+
location: "us-east5",
|
|
410
|
+
// googleAuthOptions: { keyFile: "/path/to/service-account.json" },
|
|
340
411
|
});
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
When `googleAuth` is omitted, the provider creates a `GoogleAuth` instance using application default credentials. You can pass your own `googleAuth` instance for custom authentication:
|
|
344
412
|
|
|
345
|
-
|
|
346
|
-
|
|
413
|
+
// Claude on Vertex
|
|
414
|
+
const claudeProvider = new AiSdkProvider({
|
|
415
|
+
model: vertex.anthropic("claude-opus-4.6"),
|
|
416
|
+
providerFamily: "anthropic",
|
|
417
|
+
cacheConfig: { enabled: true },
|
|
418
|
+
});
|
|
347
419
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
420
|
+
// Native Gemini on Vertex
|
|
421
|
+
const geminiProvider = new AiSdkProvider({
|
|
422
|
+
model: vertex("gemini-2.5-pro"),
|
|
423
|
+
providerFamily: "google",
|
|
351
424
|
});
|
|
352
425
|
```
|
|
353
426
|
|
|
354
427
|
### Ollama (Local)
|
|
355
428
|
|
|
356
|
-
Run models locally with [Ollama](https://ollama.com). No API key needed — just install Ollama
|
|
429
|
+
Run models locally with [Ollama](https://ollama.com). No API key needed — just install Ollama, pull a model, and add the Vercel AI SDK provider:
|
|
357
430
|
|
|
358
431
|
```bash
|
|
359
432
|
ollama pull qwen2.5-coder:32b
|
|
360
433
|
ollama serve
|
|
434
|
+
pnpm add ollama-ai-provider-v2
|
|
361
435
|
```
|
|
362
436
|
|
|
363
437
|
```typescript
|
|
364
|
-
import {
|
|
438
|
+
import { AiSdkProvider } from "noumen";
|
|
439
|
+
import { createOllama } from "ollama-ai-provider-v2";
|
|
365
440
|
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
baseURL: "http://localhost:11434/v1", // default
|
|
441
|
+
const ollama = createOllama({
|
|
442
|
+
// baseURL: "http://192.168.1.10:11434/api", // override for remote Ollama
|
|
369
443
|
});
|
|
444
|
+
|
|
445
|
+
const provider = new AiSdkProvider({ model: ollama("qwen2.5-coder:32b") });
|
|
370
446
|
```
|
|
371
447
|
|
|
372
448
|
The CLI auto-detects a running Ollama server when no cloud API keys are set, so you can simply run `noumen` with Ollama serving in the background.
|
|
373
449
|
|
|
450
|
+
### String shorthand
|
|
451
|
+
|
|
452
|
+
For quick setup and the CLI, pass a provider name string — noumen dynamically imports the right `@ai-sdk/*` package and wraps it in `AiSdkProvider` for you:
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
const agent = LocalAgent({ provider: "anthropic", cwd: "." });
|
|
456
|
+
// Equivalent to manually constructing AiSdkProvider with @ai-sdk/anthropic.
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Supported names: `openai`, `anthropic`, `gemini`, `openrouter`, `bedrock`, `vertex`, `ollama`.
|
|
460
|
+
|
|
461
|
+
### Custom / metered proxies
|
|
462
|
+
|
|
463
|
+
Any AI SDK factory accepts a `baseURL` and custom headers, so routing through your own metered gateway is a one-liner:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const gateway = createOpenAI({
|
|
467
|
+
baseURL: "https://my-proxy.example.com/openai",
|
|
468
|
+
apiKey: userJwt, // forwarded as Authorization: Bearer <jwt>
|
|
469
|
+
});
|
|
470
|
+
const provider = new AiSdkProvider({ model: gateway.chat("gpt-5") });
|
|
471
|
+
```
|
|
472
|
+
|
|
374
473
|
## Sandboxes
|
|
375
474
|
|
|
376
475
|
A `Sandbox` bundles a `VirtualFs` (filesystem) and `VirtualComputer` (shell execution) into one object. Every file read/write and shell command the agent executes goes through these interfaces — swap the sandbox to control what the agent can access.
|
|
377
476
|
|
|
378
|
-
|
|
477
|
+
`sandbox` is **required** on `Agent` and every preset. The root barrel (`import { Agent } from "noumen"`) never imports a sandbox factory, so callers pick a backend explicitly from its subpath. That keeps `node:child_process` and `node:fs/promises` out of the static module graph for consumers that only use a remote sandbox — critical for bundlers like Next.js NFT and serverless-webpack that trace dependencies.
|
|
379
478
|
|
|
380
479
|
| Factory | Import | Peer dep |
|
|
381
480
|
| --- | --- | --- |
|
|
382
|
-
| `LocalSandbox
|
|
481
|
+
| `LocalSandbox` | `noumen/local` | `@anthropic-ai/sandbox-runtime` (bundled) |
|
|
482
|
+
| `UnsandboxedLocal` | `noumen/unsandboxed` | — |
|
|
383
483
|
| `SpritesSandbox` | `noumen/sprites` | — |
|
|
384
484
|
| `DockerSandbox` | `noumen/docker` | `dockerode` |
|
|
385
485
|
| `E2BSandbox` | `noumen/e2b` | `e2b` |
|
|
386
486
|
| `FreestyleSandbox` | `noumen/freestyle` | `freestyle-sandboxes` |
|
|
387
487
|
| `SshSandbox` | `noumen/ssh` | `ssh2` |
|
|
388
488
|
|
|
489
|
+
For the two local backends, shortcut factories bundle `Agent` + sandbox together:
|
|
490
|
+
|
|
491
|
+
| Shortcut | Import | Equivalent to |
|
|
492
|
+
| --- | --- | --- |
|
|
493
|
+
| `LocalAgent` | `noumen/local` | `new Agent({ ..., sandbox: LocalSandbox({ cwd }) })` |
|
|
494
|
+
| `UnsandboxedAgent` | `noumen/unsandboxed` | `new Agent({ ..., sandbox: UnsandboxedLocal({ cwd }) })` |
|
|
495
|
+
|
|
496
|
+
Remote sandboxes stay on the `new Agent({ provider, sandbox })` path — there's no `DockerAgent` shortcut because remote backends carry config (tokens, templates, connection state) that's clearer at the call site.
|
|
497
|
+
|
|
389
498
|
### Local — OS-level sandboxing
|
|
390
499
|
|
|
391
500
|
Backed by `@anthropic-ai/sandbox-runtime`. Uses macOS Seatbelt or Linux bubblewrap to restrict filesystem and network access at the OS level — no containers needed:
|
|
@@ -395,20 +504,34 @@ pnpm add @anthropic-ai/sandbox-runtime
|
|
|
395
504
|
```
|
|
396
505
|
|
|
397
506
|
```typescript
|
|
398
|
-
import {
|
|
507
|
+
import { LocalAgent } from "noumen/local";
|
|
399
508
|
|
|
400
|
-
|
|
509
|
+
// Shortcut — Agent + LocalSandbox in one call:
|
|
510
|
+
const agent = LocalAgent({ provider: "anthropic", cwd: "/my/project" });
|
|
401
511
|
|
|
402
|
-
// Customize restrictions
|
|
403
|
-
const restricted =
|
|
512
|
+
// Customize sandbox restrictions via `localSandbox`:
|
|
513
|
+
const restricted = LocalAgent({
|
|
514
|
+
provider: "anthropic",
|
|
404
515
|
cwd: "/my/project",
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
516
|
+
localSandbox: {
|
|
517
|
+
sandbox: {
|
|
518
|
+
filesystem: { denyRead: ["/etc/shadow"] },
|
|
519
|
+
network: { allowedDomains: ["api.openai.com"] },
|
|
520
|
+
},
|
|
408
521
|
},
|
|
409
522
|
});
|
|
410
523
|
```
|
|
411
524
|
|
|
525
|
+
Or drop down to the sandbox factory directly when you need to share the sandbox across multiple agents / presets:
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
import { Agent } from "noumen";
|
|
529
|
+
import { LocalSandbox } from "noumen/local";
|
|
530
|
+
|
|
531
|
+
const sandbox = LocalSandbox({ cwd: "/my/project" });
|
|
532
|
+
const agent = new Agent({ provider: "anthropic", sandbox });
|
|
533
|
+
```
|
|
534
|
+
|
|
412
535
|
Defaults: writes allowed only in `cwd`, reads allowed everywhere, network unrestricted.
|
|
413
536
|
|
|
414
537
|
### UnsandboxedLocal — no isolation
|
|
@@ -416,9 +539,17 @@ Defaults: writes allowed only in `cwd`, reads allowed everywhere, network unrest
|
|
|
416
539
|
Backed by `fs/promises` and `child_process` with no OS-level restrictions. Use for development or trusted environments:
|
|
417
540
|
|
|
418
541
|
```typescript
|
|
419
|
-
import {
|
|
542
|
+
import { UnsandboxedAgent } from "noumen/unsandboxed";
|
|
543
|
+
|
|
544
|
+
// Shortcut — Agent + UnsandboxedLocal in one call:
|
|
545
|
+
const agent = UnsandboxedAgent({ provider: "anthropic", cwd: "/my/project" });
|
|
546
|
+
|
|
547
|
+
// Or compose manually:
|
|
548
|
+
import { Agent } from "noumen";
|
|
549
|
+
import { UnsandboxedLocal } from "noumen/unsandboxed";
|
|
420
550
|
|
|
421
551
|
const sandbox = UnsandboxedLocal({ cwd: "/my/project" });
|
|
552
|
+
const plain = new Agent({ provider: "anthropic", sandbox });
|
|
422
553
|
```
|
|
423
554
|
|
|
424
555
|
### sprites.dev — full sandbox
|
|
@@ -636,8 +767,10 @@ The interfaces are intentionally minimal (one method for shell, eight for filesy
|
|
|
636
767
|
|
|
637
768
|
## Options
|
|
638
769
|
|
|
770
|
+
Snippets below use `LocalAgent` (`import { LocalAgent } from "noumen/local"`) for brevity. Every option is also valid on `new Agent({ ..., sandbox })` and on the presets (`codingAgent`, `planningAgent`, `reviewAgent`) — the shape is identical, only the sandbox plumbing differs.
|
|
771
|
+
|
|
639
772
|
```typescript
|
|
640
|
-
const agent =
|
|
773
|
+
const agent = LocalAgent({
|
|
641
774
|
provider: "anthropic",
|
|
642
775
|
cwd: "/my/project",
|
|
643
776
|
options: {
|
|
@@ -648,9 +781,15 @@ const agent = new Agent({
|
|
|
648
781
|
autoCompactThreshold: 100_000, // token threshold for auto-compact
|
|
649
782
|
systemPrompt: "...", // override the built-in system prompt
|
|
650
783
|
skills: [{ name: "...", content: "..." }],
|
|
651
|
-
skillsPaths: [".claude/skills"], // paths to SKILL.md files
|
|
784
|
+
skillsPaths: [".claude/skills"], // extra paths to SKILL.md files (adds to auto-discovered .noumen/skills + .claude/skills)
|
|
652
785
|
projectContext: true, // load NOUMEN.md / CLAUDE.md from project
|
|
653
786
|
|
|
787
|
+
// Dot-directory layout (controls where .noumen / .claude state lives).
|
|
788
|
+
// Default: [".noumen", ".claude"]. First name wins for writes; all names
|
|
789
|
+
// are scanned for reads, and every name is protected by the dangerous-path
|
|
790
|
+
// permission check.
|
|
791
|
+
dotDirs: { names: [".noumen", ".claude"] },
|
|
792
|
+
|
|
654
793
|
// Extended thinking / reasoning (see below)
|
|
655
794
|
thinking: { type: "enabled", budgetTokens: 10000 },
|
|
656
795
|
|
|
@@ -770,7 +909,7 @@ Enable model reasoning/thinking for supported providers. Each provider maps the
|
|
|
770
909
|
- **Gemini**: Sets `thinkingConfig.thinkingBudget`
|
|
771
910
|
|
|
772
911
|
```typescript
|
|
773
|
-
const agent =
|
|
912
|
+
const agent = LocalAgent({
|
|
774
913
|
provider: "anthropic",
|
|
775
914
|
cwd: ".",
|
|
776
915
|
options: {
|
|
@@ -795,7 +934,7 @@ Disable explicitly with `{ type: "disabled" }`, or omit the option entirely for
|
|
|
795
934
|
Automatic retries with exponential backoff, Retry-After header support, context overflow recovery, and model fallback. Handles 429 (rate limit), 529 (overloaded), 500/502/503 (server errors), and connection failures.
|
|
796
935
|
|
|
797
936
|
```typescript
|
|
798
|
-
const agent =
|
|
937
|
+
const agent = LocalAgent({
|
|
799
938
|
provider: "anthropic",
|
|
800
939
|
cwd: ".",
|
|
801
940
|
options: {
|
|
@@ -804,7 +943,7 @@ const agent = new Agent({
|
|
|
804
943
|
});
|
|
805
944
|
|
|
806
945
|
// Or customize:
|
|
807
|
-
const agent2 =
|
|
946
|
+
const agent2 = LocalAgent({
|
|
808
947
|
provider: "anthropic",
|
|
809
948
|
cwd: ".",
|
|
810
949
|
options: {
|
|
@@ -830,7 +969,7 @@ On context overflow (input + max_tokens > context limit), the engine automatical
|
|
|
830
969
|
Track token usage and estimate USD costs across all model calls. Includes built-in pricing for Claude, GPT-4o, Gemini, and o-series models.
|
|
831
970
|
|
|
832
971
|
```typescript
|
|
833
|
-
const agent =
|
|
972
|
+
const agent = LocalAgent({
|
|
834
973
|
provider: "anthropic",
|
|
835
974
|
cwd: ".",
|
|
836
975
|
options: {
|
|
@@ -856,7 +995,7 @@ console.log(`Output tokens: ${summary.totalOutputTokens}`);
|
|
|
856
995
|
Supply custom pricing for unlisted models:
|
|
857
996
|
|
|
858
997
|
```typescript
|
|
859
|
-
const agent =
|
|
998
|
+
const agent = LocalAgent({
|
|
860
999
|
provider: "anthropic",
|
|
861
1000
|
cwd: ".",
|
|
862
1001
|
options: {
|
|
@@ -875,17 +1014,17 @@ const agent = new Agent({
|
|
|
875
1014
|
|
|
876
1015
|
## Skills
|
|
877
1016
|
|
|
878
|
-
Skills are markdown instructions injected into the system prompt.
|
|
1017
|
+
Skills are markdown instructions injected into the system prompt. They are auto-discovered from `<cwd>/.noumen/skills/` and `<cwd>/.claude/skills/` (and the same paths under `$HOME`), and can also be provided inline or loaded from explicit paths:
|
|
879
1018
|
|
|
880
1019
|
```typescript
|
|
881
|
-
const agent =
|
|
1020
|
+
const agent = LocalAgent({
|
|
882
1021
|
provider: "anthropic",
|
|
883
1022
|
cwd: ".",
|
|
884
1023
|
options: {
|
|
885
1024
|
skills: [
|
|
886
1025
|
{ name: "Testing", content: "Always write vitest tests for new code." },
|
|
887
1026
|
],
|
|
888
|
-
skillsPaths: ["
|
|
1027
|
+
skillsPaths: ["~/.config/skills"], // additive to auto-discovery
|
|
889
1028
|
},
|
|
890
1029
|
});
|
|
891
1030
|
|
|
@@ -893,6 +1032,8 @@ const agent = new Agent({
|
|
|
893
1032
|
await agent.init();
|
|
894
1033
|
```
|
|
895
1034
|
|
|
1035
|
+
Auto-discovery follows the configured `dotDirs` list (default `[".noumen", ".claude"]`). On name collisions, project skills win over home skills, and the **first** dot-dir in the list wins within a scope — so `.noumen/skills/foo` overrides `.claude/skills/foo`. Only `<dot-dir>/skills/<name>/SKILL.md` is discovered; loose `SKILL.md` files at the dot-dir root are ignored.
|
|
1036
|
+
|
|
896
1037
|
## Project Context (NOUMEN.md / CLAUDE.md)
|
|
897
1038
|
|
|
898
1039
|
Drop a `NOUMEN.md` or `CLAUDE.md` in your project root to give the agent persistent instructions:
|
|
@@ -907,6 +1048,8 @@ Enable it with `projectContext: true` in your `Agent` options. The loader discov
|
|
|
907
1048
|
|
|
908
1049
|
This is fully compatible with `CLAUDE.md`. If your project already has one, noumen picks it up automatically. Both `NOUMEN.md` and `CLAUDE.md` can coexist in the same directory. The format supports `@path` includes, conditional rules via `paths:` frontmatter in `.noumen/rules/` directories, and hierarchical overriding.
|
|
909
1050
|
|
|
1051
|
+
The set of dot-directory names is configurable via `dotDirs` (default `[".noumen", ".claude"]`). The same list drives `NOUMEN.md`/`CLAUDE.md` discovery, auto-discovered skills (under `<dot-dir>/skills/`), CLI config lookup (`<dot-dir>/config.json`), and agent-managed state (sessions, checkpoints, worktrees, OAuth tokens). Writes always go to the **first** name in the list; reads fall back through the rest in order.
|
|
1052
|
+
|
|
910
1053
|
See **[noumen.dev/docs/context](https://noumen.dev/docs/context)** for full configuration options.
|
|
911
1054
|
|
|
912
1055
|
## Sessions
|
|
@@ -924,7 +1067,7 @@ const sessions = await agent.listSessions();
|
|
|
924
1067
|
18 hook events across six categories — intercept tool calls, session lifecycle, permissions, file writes, model switches, compaction, retry, memory, and errors:
|
|
925
1068
|
|
|
926
1069
|
```typescript
|
|
927
|
-
const agent =
|
|
1070
|
+
const agent = LocalAgent({
|
|
928
1071
|
provider: "anthropic", cwd: ".",
|
|
929
1072
|
options: {
|
|
930
1073
|
hooks: [
|
|
@@ -1007,7 +1150,8 @@ await swarm.waitForAll();
|
|
|
1007
1150
|
Persist knowledge across sessions:
|
|
1008
1151
|
|
|
1009
1152
|
```typescript
|
|
1010
|
-
import { FileMemoryProvider
|
|
1153
|
+
import { FileMemoryProvider } from "noumen";
|
|
1154
|
+
import { LocalFs } from "noumen/local";
|
|
1011
1155
|
|
|
1012
1156
|
options: {
|
|
1013
1157
|
memory: {
|
package/dist/a2a/index.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as Agent } from '../agent-D0gl-qYi.js';
|
|
2
2
|
import { A as AgentSkill, a as AgentCard, T as TaskSendParams, b as Task, c as TaskStreamEvent } from '../types-NIyVwQ4h.js';
|
|
3
3
|
export { d as A2A_METHODS, e as Artifact, D as DataPart, F as FilePart, M as Message, P as Part, f as TaskState, g as TaskStatus, h as TextPart } from '../types-NIyVwQ4h.js';
|
|
4
|
-
import '../types-
|
|
5
|
-
import '../sandbox-
|
|
6
|
-
import '../computer-
|
|
7
|
-
import '../types-
|
|
8
|
-
import '../types-CD0rUKKT.js';
|
|
9
|
-
import '../cache-BlBwXXPS.js';
|
|
4
|
+
import '../types-DLZNyF5t.js';
|
|
5
|
+
import '../sandbox-DAqQo0Tj.js';
|
|
6
|
+
import '../computer-DzMR92tK.js';
|
|
7
|
+
import '../types-BX4ALqoN.js';
|
|
10
8
|
import '../types-2kTLUCnD.js';
|
|
11
9
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
12
10
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
package/dist/a2a/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateUUID
|
|
3
|
-
} from "../chunk-3HEYCV26.js";
|
|
4
1
|
import {
|
|
5
2
|
INTERNAL_ERROR,
|
|
6
3
|
INVALID_PARAMS,
|
|
@@ -12,8 +9,10 @@ import {
|
|
|
12
9
|
isRequest,
|
|
13
10
|
parseMessage
|
|
14
11
|
} from "../chunk-AMYIJSAZ.js";
|
|
12
|
+
import {
|
|
13
|
+
generateUUID
|
|
14
|
+
} from "../chunk-3HEYCV26.js";
|
|
15
15
|
import "../chunk-JACGEMTF.js";
|
|
16
|
-
import "../chunk-DGUM43GV.js";
|
|
17
16
|
|
|
18
17
|
// src/a2a/server.ts
|
|
19
18
|
import { createServer } from "http";
|