noumen 0.1.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 ADDED
@@ -0,0 +1,215 @@
1
+ # noumen
2
+
3
+ Programmatic AI coding agent library with pluggable providers and virtual infrastructure.
4
+
5
+ `noumen` gives you a headless, API-only coding agent that can read, write, edit files, run shell commands, and search codebases — all backed by swappable AI providers (OpenAI, Anthropic, Google Gemini) and virtual filesystems/computers (local Node.js, [sprites.dev](https://sprites.dev) containers).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add noumen
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import {
17
+ Code,
18
+ OpenAIProvider,
19
+ LocalFs,
20
+ LocalComputer,
21
+ } from "noumen";
22
+
23
+ const code = new Code({
24
+ aiProvider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
25
+ virtualFs: new LocalFs({ basePath: "/my/project" }),
26
+ virtualComputer: new LocalComputer({ defaultCwd: "/my/project" }),
27
+ });
28
+
29
+ const thread = code.createThread();
30
+
31
+ for await (const event of thread.run("Add a health-check endpoint to server.ts")) {
32
+ switch (event.type) {
33
+ case "text_delta":
34
+ process.stdout.write(event.text);
35
+ break;
36
+ case "tool_use_start":
37
+ console.log(`\n[tool] ${event.toolName}`);
38
+ break;
39
+ case "tool_result":
40
+ console.log(`[result] ${event.result.content.slice(0, 200)}`);
41
+ break;
42
+ }
43
+ }
44
+ ```
45
+
46
+ ## Providers
47
+
48
+ ### OpenAI
49
+
50
+ ```typescript
51
+ import { OpenAIProvider } from "noumen";
52
+
53
+ const provider = new OpenAIProvider({
54
+ apiKey: "sk-...",
55
+ model: "gpt-4o", // default
56
+ baseURL: "https://...", // optional, for compatible APIs
57
+ });
58
+ ```
59
+
60
+ ### Anthropic
61
+
62
+ ```typescript
63
+ import { AnthropicProvider } from "noumen";
64
+
65
+ const provider = new AnthropicProvider({
66
+ apiKey: "sk-ant-...",
67
+ model: "claude-sonnet-4-20250514", // default
68
+ });
69
+ ```
70
+
71
+ ### Google Gemini
72
+
73
+ ```typescript
74
+ import { GeminiProvider } from "noumen";
75
+
76
+ const provider = new GeminiProvider({
77
+ apiKey: "...", // Google AI Studio API key
78
+ model: "gemini-2.5-flash", // default
79
+ });
80
+ ```
81
+
82
+ ## Virtual Infrastructure
83
+
84
+ ### Local (Node.js)
85
+
86
+ Backed by `fs/promises` and `child_process`:
87
+
88
+ ```typescript
89
+ import { LocalFs, LocalComputer } from "noumen";
90
+
91
+ const fs = new LocalFs({ basePath: "/my/project" });
92
+ const computer = new LocalComputer({ defaultCwd: "/my/project" });
93
+ ```
94
+
95
+ ### sprites.dev
96
+
97
+ Run inside a remote [sprites.dev](https://docs.sprites.dev) container:
98
+
99
+ ```typescript
100
+ import { SpritesFs, SpritesComputer } from "noumen";
101
+
102
+ const fs = new SpritesFs({
103
+ token: process.env.SPRITE_TOKEN,
104
+ spriteName: "my-sprite",
105
+ });
106
+
107
+ const computer = new SpritesComputer({
108
+ token: process.env.SPRITE_TOKEN,
109
+ spriteName: "my-sprite",
110
+ });
111
+ ```
112
+
113
+ ## Options
114
+
115
+ ```typescript
116
+ const code = new Code({
117
+ aiProvider,
118
+ virtualFs,
119
+ virtualComputer,
120
+ options: {
121
+ sessionDir: ".noumen/sessions", // JSONL transcript storage path
122
+ model: "gpt-4o", // default model
123
+ maxTokens: 8192, // max output tokens per turn
124
+ autoCompact: true, // auto-compact when context is large
125
+ autoCompactThreshold: 100_000, // token threshold for auto-compact
126
+ systemPrompt: "...", // override the built-in system prompt
127
+ cwd: "/working/dir", // working directory for tools
128
+ skills: [{ name: "...", content: "..." }],
129
+ skillsPaths: [".claude/skills"], // paths to SKILL.md files on virtualFs
130
+ },
131
+ });
132
+ ```
133
+
134
+ ## Threads
135
+
136
+ ```typescript
137
+ // New thread
138
+ const thread = code.createThread();
139
+
140
+ // Resume an existing session
141
+ const thread = code.createThread({ sessionId: "abc-123", resume: true });
142
+
143
+ // Run a prompt (returns an async iterable of stream events)
144
+ for await (const event of thread.run("Fix the failing test")) {
145
+ // handle events
146
+ }
147
+
148
+ // Get conversation history
149
+ const messages = await thread.getMessages();
150
+
151
+ // Manually compact the conversation
152
+ await thread.compact();
153
+
154
+ // Abort a running request
155
+ thread.abort();
156
+ ```
157
+
158
+ ## Stream Events
159
+
160
+ | Event | Fields | Description |
161
+ |-------|--------|-------------|
162
+ | `text_delta` | `text` | Incremental text from the model |
163
+ | `tool_use_start` | `toolName`, `toolUseId` | Model is calling a tool |
164
+ | `tool_use_delta` | `input` | Incremental tool call arguments |
165
+ | `tool_result` | `toolUseId`, `toolName`, `result` | Tool execution result |
166
+ | `message_complete` | `message` | Full assistant message |
167
+ | `compact_start` | | Auto-compaction started |
168
+ | `compact_complete` | | Auto-compaction finished |
169
+ | `error` | `error` | An error occurred |
170
+
171
+ ## Built-in Tools
172
+
173
+ | Tool | Description |
174
+ |------|-------------|
175
+ | **ReadFile** | Read files with line numbers, offset/limit support |
176
+ | **WriteFile** | Create or overwrite files |
177
+ | **EditFile** | Find-and-replace string editing |
178
+ | **Bash** | Execute shell commands |
179
+ | **Glob** | Find files by glob pattern (via ripgrep) |
180
+ | **Grep** | Search file contents by regex (via ripgrep) |
181
+
182
+ ## Skills
183
+
184
+ Skills are markdown instructions injected into the system prompt. Provide them inline or load from `SKILL.md` files on the virtual filesystem:
185
+
186
+ ```typescript
187
+ const code = new Code({
188
+ aiProvider,
189
+ virtualFs,
190
+ virtualComputer,
191
+ options: {
192
+ skills: [
193
+ { name: "Testing", content: "Always write vitest tests for new code." },
194
+ ],
195
+ skillsPaths: [".claude/skills", "~/.config/skills"],
196
+ },
197
+ });
198
+
199
+ // If using skillsPaths, call init() to pre-load them
200
+ await code.init();
201
+ ```
202
+
203
+ ## Sessions
204
+
205
+ Conversations are persisted as JSONL files on the virtual filesystem. Each line is a serialized message entry. Compaction writes a boundary marker followed by a summary, so resumed sessions only load post-boundary messages.
206
+
207
+ ```typescript
208
+ // List all saved sessions
209
+ const sessions = await code.listSessions();
210
+ // [{ sessionId, createdAt, lastMessageAt, title?, messageCount }]
211
+ ```
212
+
213
+ ## License
214
+
215
+ MIT