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.
Files changed (137) hide show
  1. package/README.md +237 -93
  2. package/dist/a2a/index.d.ts +5 -7
  3. package/dist/a2a/index.js +3 -4
  4. package/dist/a2a/index.js.map +1 -1
  5. package/dist/acp/index.d.ts +5 -7
  6. package/dist/acp/index.js +0 -1
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/{agent-DWE4_P5X.d.ts → agent-D0gl-qYi.d.ts} +89 -34
  9. package/dist/{chunk-6MMYCGJQ.js → chunk-5HY4IYNT.js} +1529 -2321
  10. package/dist/chunk-5HY4IYNT.js.map +1 -0
  11. package/dist/chunk-BC5BLWBC.js +21 -0
  12. package/dist/chunk-BC5BLWBC.js.map +1 -0
  13. package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
  14. package/dist/chunk-CX4BL6PC.js.map +1 -0
  15. package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
  16. package/dist/chunk-HQISH4D7.js.map +1 -0
  17. package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
  18. package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
  19. package/dist/chunk-OPFFLQZL.js +40 -0
  20. package/dist/chunk-OPFFLQZL.js.map +1 -0
  21. package/dist/chunk-PDEAJ272.js +660 -0
  22. package/dist/chunk-PDEAJ272.js.map +1 -0
  23. package/dist/chunk-PKHLGGEC.js +115 -0
  24. package/dist/chunk-PKHLGGEC.js.map +1 -0
  25. package/dist/chunk-XQTNXRE7.js +176 -0
  26. package/dist/chunk-XQTNXRE7.js.map +1 -0
  27. package/dist/chunk-XZPAA5TO.js +817 -0
  28. package/dist/chunk-XZPAA5TO.js.map +1 -0
  29. package/dist/cli/index.js +77 -42
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/client/index.d.ts +1 -2
  32. package/dist/client/index.js +0 -2
  33. package/dist/client/index.js.map +1 -1
  34. package/dist/client-JJFLE6RT.js +9 -0
  35. package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
  36. package/dist/docker.d.ts +2 -2
  37. package/dist/docker.js +0 -1
  38. package/dist/docker.js.map +1 -1
  39. package/dist/e2b.d.ts +2 -2
  40. package/dist/e2b.js +0 -1
  41. package/dist/e2b.js.map +1 -1
  42. package/dist/freestyle.d.ts +2 -2
  43. package/dist/freestyle.js +0 -1
  44. package/dist/freestyle.js.map +1 -1
  45. package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
  46. package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
  47. package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
  48. package/dist/index.d.ts +351 -72
  49. package/dist/index.js +54 -55
  50. package/dist/jsonrpc/index.js +0 -1
  51. package/dist/local.d.ts +168 -0
  52. package/dist/local.js +40 -0
  53. package/dist/local.js.map +1 -0
  54. package/dist/lsp/index.d.ts +4 -5
  55. package/dist/lsp/index.js +0 -1
  56. package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
  57. package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
  58. package/dist/mcp/index.d.ts +16 -8
  59. package/dist/mcp/index.js +5 -6
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
  62. package/dist/{provider-factory-TUHU3DIG.js → provider-factory-KNBSHXJ6.js} +3 -3
  63. package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
  64. package/dist/{resolve-6KUZNEYW.js → resolve-AGQZFMKD.js} +3 -3
  65. package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
  66. package/dist/sandbox-index-ODNREIFA.js +32 -0
  67. package/dist/sandbox-index-ODNREIFA.js.map +1 -0
  68. package/dist/server/index.d.ts +18 -7
  69. package/dist/server/index.js +9 -5
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/{server-BzNGKTP6.d.ts → server-DFXdlqyX.d.ts} +1 -1
  72. package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
  73. package/dist/sprites.d.ts +2 -2
  74. package/dist/sprites.js +0 -1
  75. package/dist/sprites.js.map +1 -1
  76. package/dist/ssh.d.ts +2 -2
  77. package/dist/ssh.js +0 -1
  78. package/dist/ssh.js.map +1 -1
  79. package/dist/{types-DhXwOQwD.d.ts → types-BX4ALqoN.d.ts} +76 -4
  80. package/dist/{types-kiGBF35b.d.ts → types-DLZNyF5t.d.ts} +125 -1
  81. package/dist/unsandboxed.d.ts +59 -0
  82. package/dist/unsandboxed.js +32 -0
  83. package/dist/unsandboxed.js.map +1 -0
  84. package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
  85. package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
  86. package/package.json +35 -50
  87. package/dist/cache-BlBwXXPS.d.ts +0 -38
  88. package/dist/chunk-5GEX6ZSB.js.map +0 -1
  89. package/dist/chunk-6MMYCGJQ.js.map +0 -1
  90. package/dist/chunk-7IQCQI2G.js +0 -94
  91. package/dist/chunk-7IQCQI2G.js.map +0 -1
  92. package/dist/chunk-CCM2AXZG.js +0 -16
  93. package/dist/chunk-CCM2AXZG.js.map +0 -1
  94. package/dist/chunk-DGUM43GV.js +0 -11
  95. package/dist/chunk-HEQQQGK5.js +0 -131
  96. package/dist/chunk-HEQQQGK5.js.map +0 -1
  97. package/dist/chunk-I3JTUFPK.js +0 -171
  98. package/dist/chunk-I3JTUFPK.js.map +0 -1
  99. package/dist/chunk-XZN4QZLK.js.map +0 -1
  100. package/dist/chunk-ZXSDKBYB.js +0 -474
  101. package/dist/chunk-ZXSDKBYB.js.map +0 -1
  102. package/dist/client-CRRO2376.js +0 -10
  103. package/dist/providers/anthropic.d.ts +0 -19
  104. package/dist/providers/anthropic.js +0 -36
  105. package/dist/providers/anthropic.js.map +0 -1
  106. package/dist/providers/bedrock.d.ts +0 -39
  107. package/dist/providers/bedrock.js +0 -56
  108. package/dist/providers/bedrock.js.map +0 -1
  109. package/dist/providers/gemini.d.ts +0 -17
  110. package/dist/providers/gemini.js +0 -262
  111. package/dist/providers/gemini.js.map +0 -1
  112. package/dist/providers/ollama.d.ts +0 -13
  113. package/dist/providers/ollama.js +0 -20
  114. package/dist/providers/ollama.js.map +0 -1
  115. package/dist/providers/openai.d.ts +0 -21
  116. package/dist/providers/openai.js +0 -9
  117. package/dist/providers/openrouter.d.ts +0 -16
  118. package/dist/providers/openrouter.js +0 -24
  119. package/dist/providers/openrouter.js.map +0 -1
  120. package/dist/providers/vertex.d.ts +0 -42
  121. package/dist/providers/vertex.js +0 -68
  122. package/dist/providers/vertex.js.map +0 -1
  123. package/dist/sandbox-9qeMTNrD.d.ts +0 -126
  124. package/dist/types-CD0rUKKT.d.ts +0 -109
  125. package/dist/uuid-RVN2T26F.js.map +0 -1
  126. package/dist/zod-7YXKWYMC.js.map +0 -1
  127. /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
  128. /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
  129. /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
  130. /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
  131. /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
  132. /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
  133. /package/dist/{provider-factory-TUHU3DIG.js.map → render-4VEODRK7.js.map} +0 -0
  134. /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
  135. /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
  136. /package/dist/{resolve-6KUZNEYW.js.map → uuid-CVTNAPEB.js.map} +0 -0
  137. /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
@@ -0,0 +1,660 @@
1
+ import {
2
+ Agent,
3
+ NoopTracer,
4
+ SpanStatusCode,
5
+ Thread
6
+ } from "./chunk-5HY4IYNT.js";
7
+ import {
8
+ generateUUID
9
+ } from "./chunk-3HEYCV26.js";
10
+
11
+ // src/presets.ts
12
+ function codingAgent(opts) {
13
+ const cwd = opts.cwd ?? process.cwd();
14
+ return new Agent({
15
+ provider: opts.provider,
16
+ sandbox: opts.sandbox,
17
+ options: {
18
+ cwd,
19
+ model: opts.model,
20
+ systemPrompt: opts.systemPrompt,
21
+ permissions: { mode: "default" },
22
+ autoCompact: true,
23
+ enableSubagents: true,
24
+ enableTasks: true,
25
+ enablePlanMode: true,
26
+ projectContext: { cwd },
27
+ costTracking: { enabled: true },
28
+ retry: true,
29
+ hooks: opts.hooks,
30
+ mcpServers: opts.mcpServers,
31
+ autoTitle: opts.autoTitle
32
+ }
33
+ });
34
+ }
35
+ function planningAgent(opts) {
36
+ const cwd = opts.cwd ?? process.cwd();
37
+ return new Agent({
38
+ provider: opts.provider,
39
+ sandbox: opts.sandbox,
40
+ options: {
41
+ cwd,
42
+ model: opts.model,
43
+ systemPrompt: opts.systemPrompt,
44
+ permissions: { mode: "plan" },
45
+ autoCompact: true,
46
+ enableSubagents: false,
47
+ enableTasks: false,
48
+ enablePlanMode: true,
49
+ projectContext: { cwd },
50
+ costTracking: { enabled: true },
51
+ retry: true,
52
+ hooks: opts.hooks,
53
+ mcpServers: opts.mcpServers,
54
+ autoTitle: opts.autoTitle
55
+ }
56
+ });
57
+ }
58
+ function reviewAgent(opts) {
59
+ const cwd = opts.cwd ?? process.cwd();
60
+ return new Agent({
61
+ provider: opts.provider,
62
+ sandbox: opts.sandbox,
63
+ options: {
64
+ cwd,
65
+ model: opts.model,
66
+ systemPrompt: opts.systemPrompt,
67
+ permissions: { mode: "plan" },
68
+ autoCompact: true,
69
+ enableSubagents: false,
70
+ enableTasks: false,
71
+ enablePlanMode: true,
72
+ projectContext: { cwd },
73
+ costTracking: { enabled: true },
74
+ retry: true,
75
+ hooks: opts.hooks,
76
+ mcpServers: opts.mcpServers,
77
+ autoTitle: opts.autoTitle,
78
+ webSearch: {
79
+ search: async (query) => {
80
+ try {
81
+ const res = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`);
82
+ if (!res.ok) return [];
83
+ return [{ title: query, url: res.url, snippet: `Search results for: ${query}` }];
84
+ } catch {
85
+ return [];
86
+ }
87
+ }
88
+ }
89
+ }
90
+ });
91
+ }
92
+
93
+ // src/swarm/mailbox.ts
94
+ var Mailbox = class {
95
+ messages = [];
96
+ listeners = /* @__PURE__ */ new Map();
97
+ /**
98
+ * Send a message from one member to another.
99
+ */
100
+ send(from, to, content) {
101
+ const msg = {
102
+ from,
103
+ to,
104
+ content,
105
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
106
+ };
107
+ this.messages.push(msg);
108
+ const handlers = this.listeners.get(to);
109
+ if (handlers) {
110
+ for (const handler of handlers) {
111
+ handler(msg);
112
+ }
113
+ }
114
+ }
115
+ /**
116
+ * Broadcast a message to all members except the sender.
117
+ */
118
+ broadcast(from, content, memberNames) {
119
+ for (const name of memberNames) {
120
+ if (name !== from) {
121
+ this.send(from, name, content);
122
+ }
123
+ }
124
+ }
125
+ /**
126
+ * Get all messages sent to a specific member.
127
+ */
128
+ getMessagesFor(memberName) {
129
+ return this.messages.filter((m) => m.to === memberName);
130
+ }
131
+ /**
132
+ * Get all unread messages for a member since the last check.
133
+ */
134
+ getNewMessagesFor(memberName, since) {
135
+ return this.messages.filter(
136
+ (m) => m.to === memberName && m.timestamp > since
137
+ );
138
+ }
139
+ /**
140
+ * Register a listener for incoming messages to a member.
141
+ */
142
+ onMessage(memberName, handler) {
143
+ const existing = this.listeners.get(memberName) ?? [];
144
+ existing.push(handler);
145
+ this.listeners.set(memberName, existing);
146
+ return () => {
147
+ const handlers = this.listeners.get(memberName);
148
+ if (handlers) {
149
+ const idx = handlers.indexOf(handler);
150
+ if (idx !== -1) handlers.splice(idx, 1);
151
+ }
152
+ };
153
+ }
154
+ /**
155
+ * Get all messages in the mailbox.
156
+ */
157
+ getAllMessages() {
158
+ return [...this.messages];
159
+ }
160
+ };
161
+
162
+ // src/swarm/manager.ts
163
+ var SwarmManager = class {
164
+ members = /* @__PURE__ */ new Map();
165
+ backend;
166
+ mailbox = new Mailbox();
167
+ config;
168
+ runningTasks = /* @__PURE__ */ new Map();
169
+ eventHandlers = [];
170
+ constructor(backend, config) {
171
+ this.backend = backend;
172
+ this.config = config ?? {};
173
+ }
174
+ /**
175
+ * Register a handler for swarm lifecycle events.
176
+ */
177
+ onEvent(handler) {
178
+ this.eventHandlers.push(handler);
179
+ return () => {
180
+ const idx = this.eventHandlers.indexOf(handler);
181
+ if (idx !== -1) this.eventHandlers.splice(idx, 1);
182
+ };
183
+ }
184
+ emit(event) {
185
+ for (const handler of this.eventHandlers) {
186
+ handler(event);
187
+ }
188
+ }
189
+ /**
190
+ * Spawn a new swarm member. Returns the member ID.
191
+ */
192
+ async spawn(config) {
193
+ const id = generateUUID();
194
+ const member = {
195
+ id,
196
+ name: config.name,
197
+ status: "pending"
198
+ };
199
+ this.members.set(id, member);
200
+ const maxConcurrent = this.config.maxConcurrent ?? 4;
201
+ const running = Array.from(this.members.values()).filter(
202
+ (m) => m.status === "running"
203
+ ).length;
204
+ if (running >= maxConcurrent) {
205
+ await this.waitForSlot(maxConcurrent);
206
+ }
207
+ member.status = "running";
208
+ this.emit({
209
+ type: "swarm_member_start",
210
+ memberId: id,
211
+ memberName: config.name
212
+ });
213
+ const task = this.runMember(config, member);
214
+ this.runningTasks.set(id, task);
215
+ return id;
216
+ }
217
+ async runMember(config, member) {
218
+ try {
219
+ const gen = this.backend.spawn(config, member);
220
+ let next = await gen.next();
221
+ while (!next.done) {
222
+ next = await gen.next();
223
+ }
224
+ member.result = next.value;
225
+ member.status = "completed";
226
+ this.emit({
227
+ type: "swarm_member_complete",
228
+ memberId: member.id,
229
+ memberName: member.name,
230
+ content: member.result
231
+ });
232
+ } catch (err) {
233
+ member.error = err instanceof Error ? err : new Error(String(err));
234
+ member.status = "failed";
235
+ this.emit({
236
+ type: "swarm_member_failed",
237
+ memberId: member.id,
238
+ memberName: member.name,
239
+ error: member.error
240
+ });
241
+ } finally {
242
+ this.runningTasks.delete(member.id);
243
+ }
244
+ }
245
+ /**
246
+ * Spawn multiple members concurrently. Returns their IDs.
247
+ */
248
+ async spawnAll(configs) {
249
+ const ids = [];
250
+ for (const config of configs) {
251
+ ids.push(await this.spawn(config));
252
+ }
253
+ return ids;
254
+ }
255
+ /**
256
+ * Send a message between swarm members.
257
+ */
258
+ sendMessage(from, to, content) {
259
+ this.mailbox.send(from, to, content);
260
+ this.emit({
261
+ type: "swarm_message",
262
+ memberId: to,
263
+ memberName: this.getMemberName(to),
264
+ content
265
+ });
266
+ }
267
+ /**
268
+ * Kill a running member.
269
+ */
270
+ async kill(memberId) {
271
+ const member = this.members.get(memberId);
272
+ if (!member || member.status !== "running") return;
273
+ await this.backend.kill(memberId);
274
+ member.status = "killed";
275
+ this.runningTasks.delete(memberId);
276
+ }
277
+ /**
278
+ * Wait for all running members to complete.
279
+ */
280
+ async waitForAll() {
281
+ while (this.runningTasks.size > 0) {
282
+ await Promise.race(this.runningTasks.values());
283
+ }
284
+ }
285
+ /**
286
+ * Get current swarm status.
287
+ */
288
+ getStatus() {
289
+ return {
290
+ members: Array.from(this.members.values()),
291
+ messages: this.mailbox.getAllMessages()
292
+ };
293
+ }
294
+ /**
295
+ * Get a specific member.
296
+ */
297
+ getMember(id) {
298
+ return this.members.get(id);
299
+ }
300
+ /**
301
+ * Get the mailbox for direct access.
302
+ */
303
+ getMailbox() {
304
+ return this.mailbox;
305
+ }
306
+ getMemberName(id) {
307
+ return this.members.get(id)?.name ?? id;
308
+ }
309
+ async waitForSlot(maxConcurrent) {
310
+ while (true) {
311
+ const running = Array.from(this.members.values()).filter(
312
+ (m) => m.status === "running"
313
+ ).length;
314
+ if (running < maxConcurrent) return;
315
+ if (this.runningTasks.size > 0) {
316
+ await Promise.race(this.runningTasks.values());
317
+ } else {
318
+ break;
319
+ }
320
+ }
321
+ }
322
+ };
323
+
324
+ // src/swarm/backends/in-process.ts
325
+ var InProcessBackend = class {
326
+ threadConfig;
327
+ abortControllers = /* @__PURE__ */ new Map();
328
+ constructor(threadConfig) {
329
+ this.threadConfig = threadConfig;
330
+ }
331
+ async *spawn(config, member) {
332
+ const ac = new AbortController();
333
+ this.abortControllers.set(member.id, ac);
334
+ const childTools = config.allowedTools ? (this.threadConfig.tools ?? []).filter(
335
+ (t) => config.allowedTools.includes(t.name)
336
+ ) : this.threadConfig.tools;
337
+ const thread = new Thread(
338
+ {
339
+ ...this.threadConfig,
340
+ tools: childTools,
341
+ systemPrompt: config.systemPrompt,
342
+ model: config.model
343
+ },
344
+ { cwd: this.threadConfig.cwd }
345
+ );
346
+ member.sessionId = thread.sessionId;
347
+ let resultText = "";
348
+ for await (const event of thread.run(config.prompt, {
349
+ signal: ac.signal
350
+ })) {
351
+ yield event;
352
+ if (event.type === "message_complete" && event.message.content) {
353
+ resultText += event.message.content;
354
+ }
355
+ }
356
+ this.abortControllers.delete(member.id);
357
+ return resultText;
358
+ }
359
+ async kill(memberId) {
360
+ const ac = this.abortControllers.get(memberId);
361
+ if (ac) {
362
+ ac.abort();
363
+ this.abortControllers.delete(memberId);
364
+ }
365
+ }
366
+ };
367
+
368
+ // src/permissions/updates.ts
369
+ function applyPermissionUpdate(ctx, update) {
370
+ switch (update.type) {
371
+ case "addRules":
372
+ ctx.rules.push(...update.rules);
373
+ break;
374
+ case "removeRules":
375
+ ctx.rules = ctx.rules.filter((r) => {
376
+ if (r.toolName !== update.toolName) return true;
377
+ if (update.behavior && r.behavior !== update.behavior) return true;
378
+ return false;
379
+ });
380
+ break;
381
+ case "setMode":
382
+ ctx.mode = update.mode;
383
+ break;
384
+ case "addDirectories":
385
+ for (const dir of update.directories) {
386
+ if (!ctx.workingDirectories.includes(dir)) {
387
+ ctx.workingDirectories.push(dir);
388
+ }
389
+ }
390
+ break;
391
+ case "removeDirectories":
392
+ ctx.workingDirectories = ctx.workingDirectories.filter(
393
+ (d) => !update.directories.includes(d)
394
+ );
395
+ break;
396
+ }
397
+ return ctx;
398
+ }
399
+ function applyPermissionUpdates(ctx, updates) {
400
+ for (const update of updates) {
401
+ applyPermissionUpdate(ctx, update);
402
+ }
403
+ return ctx;
404
+ }
405
+
406
+ // src/tracing/otel.ts
407
+ var otelApi = null;
408
+ var otelLoadFailed = false;
409
+ async function loadOTelApi() {
410
+ if (otelApi) return otelApi;
411
+ if (otelLoadFailed) return null;
412
+ try {
413
+ otelApi = await import("@opentelemetry/api");
414
+ return otelApi;
415
+ } catch {
416
+ otelLoadFailed = true;
417
+ return null;
418
+ }
419
+ }
420
+ var OTelSpan = class {
421
+ name;
422
+ inner;
423
+ constructor(name, inner) {
424
+ this.name = name;
425
+ this.inner = inner;
426
+ }
427
+ setAttribute(key, value) {
428
+ this.inner.setAttribute(key, value);
429
+ }
430
+ addEvent(name, attributes) {
431
+ this.inner.addEvent(name, attributes);
432
+ }
433
+ setStatus(code, message) {
434
+ const otelCode = code === SpanStatusCode.ERROR ? 2 : 1;
435
+ this.inner.setStatus({ code: otelCode, message });
436
+ }
437
+ end() {
438
+ this.inner.end();
439
+ }
440
+ /** Access the underlying OTEL span for advanced use cases. */
441
+ getInnerSpan() {
442
+ return this.inner;
443
+ }
444
+ };
445
+ var OTelTracer = class _OTelTracer {
446
+ otelTracer;
447
+ api;
448
+ constructor(api, otelTracer) {
449
+ this.api = api;
450
+ this.otelTracer = otelTracer;
451
+ }
452
+ /**
453
+ * Create an `OTelTracer`. Falls back to `NoopTracer` if
454
+ * `@opentelemetry/api` is not available at runtime.
455
+ */
456
+ static async create(serviceName = "noumen", version) {
457
+ const api = await loadOTelApi();
458
+ if (!api) return new NoopTracer();
459
+ const tracer = api.trace.getTracer(serviceName, version);
460
+ return new _OTelTracer(api, tracer);
461
+ }
462
+ startSpan(name, options) {
463
+ const parentCtx = options?.parent instanceof OTelSpan ? this.api.trace.setSpan(this.api.context.active(), options.parent.getInnerSpan()) : this.api.context.active();
464
+ const otelSpan = this.otelTracer.startSpan(
465
+ name,
466
+ options?.attributes ? { attributes: options.attributes } : void 0,
467
+ parentCtx
468
+ );
469
+ return new OTelSpan(name, otelSpan);
470
+ }
471
+ };
472
+
473
+ // src/memory/file-provider.ts
474
+ var INDEX_NAME = "MEMORY.md";
475
+ var DEFAULT_MAX_LINES = 200;
476
+ var DEFAULT_MAX_BYTES = 25e3;
477
+ var MEMORY_TYPES = /* @__PURE__ */ new Set([
478
+ "user",
479
+ "project",
480
+ "feedback",
481
+ "reference"
482
+ ]);
483
+ function parseFrontmatter(raw) {
484
+ const trimmed = raw.trimStart();
485
+ if (!trimmed.startsWith("---")) {
486
+ return { rest: raw };
487
+ }
488
+ const endIdx = trimmed.indexOf("---", 3);
489
+ if (endIdx === -1) {
490
+ return { rest: raw };
491
+ }
492
+ const fmBlock = trimmed.slice(3, endIdx).trim();
493
+ const rest = trimmed.slice(endIdx + 3).trim();
494
+ let name;
495
+ let description;
496
+ let type;
497
+ for (const line of fmBlock.split("\n")) {
498
+ const colonIdx = line.indexOf(":");
499
+ if (colonIdx === -1) continue;
500
+ const key = line.slice(0, colonIdx).trim();
501
+ const value = line.slice(colonIdx + 1).trim();
502
+ if (key === "name") name = value;
503
+ else if (key === "description") description = value;
504
+ else if (key === "type" && MEMORY_TYPES.has(value)) type = value;
505
+ }
506
+ return { name, description, type, rest };
507
+ }
508
+ function serializeEntry(entry) {
509
+ const lines = [
510
+ "---",
511
+ `name: ${entry.name}`,
512
+ `description: ${entry.description}`,
513
+ `type: ${entry.type}`,
514
+ "---",
515
+ "",
516
+ entry.content
517
+ ];
518
+ return lines.join("\n");
519
+ }
520
+ function slugify(name) {
521
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 60);
522
+ }
523
+ function truncateIndex(raw, maxLines = DEFAULT_MAX_LINES, maxBytes = DEFAULT_MAX_BYTES) {
524
+ const trimmed = raw.trim();
525
+ const contentLines = trimmed.split("\n");
526
+ const lineCount = contentLines.length;
527
+ const byteCount = trimmed.length;
528
+ const wasLineTruncated = lineCount > maxLines;
529
+ const wasByteTruncated = byteCount > maxBytes;
530
+ if (!wasLineTruncated && !wasByteTruncated) {
531
+ return { content: trimmed, lineCount, byteCount, wasLineTruncated, wasByteTruncated };
532
+ }
533
+ let truncated = wasLineTruncated ? contentLines.slice(0, maxLines).join("\n") : trimmed;
534
+ if (truncated.length > maxBytes) {
535
+ const cutAt = truncated.lastIndexOf("\n", maxBytes);
536
+ truncated = truncated.slice(0, cutAt > 0 ? cutAt : maxBytes);
537
+ }
538
+ const reason = wasByteTruncated && !wasLineTruncated ? `${byteCount} bytes (limit: ${maxBytes})` : wasLineTruncated && !wasByteTruncated ? `${lineCount} lines (limit: ${maxLines})` : `${lineCount} lines and ${byteCount} bytes`;
539
+ return {
540
+ content: truncated + `
541
+
542
+ > WARNING: ${INDEX_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`,
543
+ lineCount,
544
+ byteCount,
545
+ wasLineTruncated,
546
+ wasByteTruncated
547
+ };
548
+ }
549
+ var FileMemoryProvider = class {
550
+ fs;
551
+ dir;
552
+ maxIndexLines;
553
+ constructor(fs, memoryDir, maxIndexLines = DEFAULT_MAX_LINES) {
554
+ this.fs = fs;
555
+ this.dir = memoryDir.endsWith("/") ? memoryDir : memoryDir + "/";
556
+ this.maxIndexLines = maxIndexLines;
557
+ }
558
+ indexPath() {
559
+ return this.dir + INDEX_NAME;
560
+ }
561
+ async ensureDir() {
562
+ const exists = await this.fs.exists(this.dir);
563
+ if (!exists) {
564
+ await this.fs.mkdir(this.dir, { recursive: true });
565
+ }
566
+ }
567
+ async loadIndex() {
568
+ try {
569
+ const raw = await this.fs.readFile(this.indexPath());
570
+ return truncateIndex(raw, this.maxIndexLines).content;
571
+ } catch {
572
+ return "";
573
+ }
574
+ }
575
+ async loadEntry(path) {
576
+ const fullPath = path.startsWith(this.dir) ? path : this.dir + path;
577
+ try {
578
+ const raw = await this.fs.readFile(fullPath);
579
+ const fm = parseFrontmatter(raw);
580
+ const stat = await this.fs.stat(fullPath).catch(() => null);
581
+ return {
582
+ name: fm.name ?? pathToName(path),
583
+ description: fm.description ?? "",
584
+ type: fm.type ?? "project",
585
+ content: fm.rest,
586
+ path: path.startsWith(this.dir) ? path.slice(this.dir.length) : path,
587
+ updatedAt: stat?.modifiedAt?.toISOString()
588
+ };
589
+ } catch {
590
+ return null;
591
+ }
592
+ }
593
+ async saveEntry(entry) {
594
+ await this.ensureDir();
595
+ const relativePath = entry.path ?? slugify(entry.name) + ".md";
596
+ const fullPath = this.dir + relativePath;
597
+ const content = serializeEntry({ ...entry, path: relativePath });
598
+ await this.fs.writeFile(fullPath, content);
599
+ await this.rebuildIndex();
600
+ }
601
+ async removeEntry(path) {
602
+ const fullPath = path.startsWith(this.dir) ? path : this.dir + path;
603
+ try {
604
+ await this.fs.deleteFile(fullPath);
605
+ } catch {
606
+ }
607
+ await this.rebuildIndex();
608
+ }
609
+ async listEntries() {
610
+ try {
611
+ const files = await this.fs.readdir(this.dir);
612
+ const entries = [];
613
+ for (const file of files) {
614
+ if (!file.isFile || !file.name.endsWith(".md") || file.name === INDEX_NAME) continue;
615
+ const entry = await this.loadEntry(file.name);
616
+ if (entry) entries.push(entry);
617
+ }
618
+ return entries;
619
+ } catch {
620
+ return [];
621
+ }
622
+ }
623
+ async search(query) {
624
+ const entries = await this.listEntries();
625
+ const lower = query.toLowerCase();
626
+ return entries.filter(
627
+ (e) => e.name.toLowerCase().includes(lower) || e.description.toLowerCase().includes(lower) || e.content.toLowerCase().includes(lower)
628
+ );
629
+ }
630
+ async rebuildIndex() {
631
+ const entries = await this.listEntries();
632
+ const lines = [];
633
+ for (const entry of entries) {
634
+ const relativePath = entry.path ?? slugify(entry.name) + ".md";
635
+ const desc = entry.description ? ` \u2014 ${entry.description}` : "";
636
+ lines.push(`- [${entry.name}](${relativePath})${desc}`);
637
+ }
638
+ await this.ensureDir();
639
+ await this.fs.writeFile(this.indexPath(), lines.join("\n") + "\n");
640
+ }
641
+ };
642
+ function pathToName(p) {
643
+ const base = p.split("/").pop() ?? p;
644
+ return base.replace(/\.md$/i, "").replace(/[_-]/g, " ");
645
+ }
646
+
647
+ export {
648
+ codingAgent,
649
+ planningAgent,
650
+ reviewAgent,
651
+ Mailbox,
652
+ SwarmManager,
653
+ InProcessBackend,
654
+ applyPermissionUpdate,
655
+ applyPermissionUpdates,
656
+ OTelTracer,
657
+ truncateIndex,
658
+ FileMemoryProvider
659
+ };
660
+ //# sourceMappingURL=chunk-PDEAJ272.js.map