@sesamespace/hivemind 0.8.4 → 0.8.6
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/.pnpmrc.json +1 -0
- package/DASHBOARD-PLAN.md +206 -0
- package/TOOL-USE-DESIGN.md +173 -0
- package/config/default.toml +6 -1
- package/dist/{chunk-3CQJQUY3.js → chunk-AYHCHIM2.js} +2 -2
- package/dist/{chunk-CSYDOZE6.js → chunk-CJ4Y2BCE.js} +2 -2
- package/dist/{chunk-66KRRXVF.js → chunk-K7YQY253.js} +3 -3
- package/dist/{chunk-DODOQGIL.js → chunk-LSLF7AGW.js} +42 -13
- package/dist/chunk-LSLF7AGW.js.map +1 -0
- package/dist/{chunk-6S5UKFTZ.js → chunk-S4QRR3ZJ.js} +917 -48
- package/dist/chunk-S4QRR3ZJ.js.map +1 -0
- package/dist/{chunk-HNXCZPSX.js → chunk-WIJHKLB3.js} +3 -3
- package/dist/commands/fleet.js +3 -4
- package/dist/commands/init.js +3 -2
- package/dist/commands/start.js +3 -4
- package/dist/commands/watchdog.js +3 -4
- package/dist/index.js +5 -4
- package/dist/main.js +6 -7
- package/dist/main.js.map +1 -1
- package/dist/start.js +1 -2
- package/dist/start.js.map +1 -1
- package/docs/TOOL-PARITY-PLAN.md +191 -0
- package/package.json +22 -25
- package/dist/chunk-6S5UKFTZ.js.map +0 -1
- package/dist/chunk-DODOQGIL.js.map +0 -1
- package/dist/chunk-GPI4RU7N.js +0 -624
- package/dist/chunk-GPI4RU7N.js.map +0 -1
- package/install.sh +0 -131
- package/packages/memory/Cargo.lock +0 -6480
- package/packages/memory/Cargo.toml +0 -21
- package/packages/memory/src/src/context.rs +0 -179
- package/packages/memory/src/src/embeddings.rs +0 -51
- package/packages/memory/src/src/main.rs +0 -626
- package/packages/memory/src/src/promotion.rs +0 -637
- package/packages/memory/src/src/scoring.rs +0 -131
- package/packages/memory/src/src/store.rs +0 -460
- package/packages/memory/src/src/tasks.rs +0 -321
- /package/dist/{chunk-3CQJQUY3.js.map → chunk-AYHCHIM2.js.map} +0 -0
- /package/dist/{chunk-CSYDOZE6.js.map → chunk-CJ4Y2BCE.js.map} +0 -0
- /package/dist/{chunk-66KRRXVF.js.map → chunk-K7YQY253.js.map} +0 -0
- /package/dist/{chunk-HNXCZPSX.js.map → chunk-WIJHKLB3.js.map} +0 -0
|
@@ -1,20 +1,123 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SesameClient
|
|
3
|
-
} from "./chunk-GPI4RU7N.js";
|
|
4
|
-
|
|
5
1
|
// packages/runtime/src/llm-client.ts
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
function convertMessagesForAnthropic(messages) {
|
|
4
|
+
let system = "";
|
|
5
|
+
const converted = [];
|
|
6
|
+
for (const msg of messages) {
|
|
7
|
+
if (msg.role === "system") {
|
|
8
|
+
system = msg.content ?? "";
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
if (msg.role === "tool") {
|
|
12
|
+
converted.push({
|
|
13
|
+
role: "user",
|
|
14
|
+
content: [{
|
|
15
|
+
type: "tool_result",
|
|
16
|
+
tool_use_id: msg.tool_call_id,
|
|
17
|
+
content: msg.content ?? ""
|
|
18
|
+
}]
|
|
19
|
+
});
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (msg.role === "assistant" && msg.tool_calls) {
|
|
23
|
+
const content = [];
|
|
24
|
+
if (msg.content) content.push({ type: "text", text: msg.content });
|
|
25
|
+
for (const tc of msg.tool_calls) {
|
|
26
|
+
content.push({
|
|
27
|
+
type: "tool_use",
|
|
28
|
+
id: tc.id,
|
|
29
|
+
name: tc.function.name,
|
|
30
|
+
input: JSON.parse(tc.function.arguments)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
converted.push({ role: "assistant", content });
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
converted.push({ role: msg.role, content: msg.content ?? "" });
|
|
37
|
+
}
|
|
38
|
+
return { system, messages: converted };
|
|
39
|
+
}
|
|
40
|
+
function convertToolsForAnthropic(tools) {
|
|
41
|
+
return tools.map((t) => ({
|
|
42
|
+
name: t.function.name,
|
|
43
|
+
description: t.function.description,
|
|
44
|
+
input_schema: t.function.parameters
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
function parseAnthropicResponse(data) {
|
|
48
|
+
let textContent = "";
|
|
49
|
+
const toolCalls = [];
|
|
50
|
+
for (const block of data.content) {
|
|
51
|
+
if (block.type === "text") textContent += block.text;
|
|
52
|
+
if (block.type === "tool_use") {
|
|
53
|
+
toolCalls.push({
|
|
54
|
+
id: block.id,
|
|
55
|
+
type: "function",
|
|
56
|
+
function: {
|
|
57
|
+
name: block.name,
|
|
58
|
+
arguments: JSON.stringify(block.input)
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
content: textContent,
|
|
65
|
+
model: data.model,
|
|
66
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
67
|
+
finish_reason: data.stop_reason === "tool_use" ? "tool_calls" : "stop",
|
|
68
|
+
usage: data.usage ? {
|
|
69
|
+
prompt_tokens: data.usage.input_tokens,
|
|
70
|
+
completion_tokens: data.usage.output_tokens,
|
|
71
|
+
total_tokens: data.usage.input_tokens + data.usage.output_tokens
|
|
72
|
+
} : void 0
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getClaudeCodeOAuthToken() {
|
|
76
|
+
try {
|
|
77
|
+
const raw = execSync(
|
|
78
|
+
'security find-generic-password -s "Claude Code-credentials" -w',
|
|
79
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
80
|
+
).trim();
|
|
81
|
+
const data = JSON.parse(raw);
|
|
82
|
+
const oauth = data?.claudeAiOauth;
|
|
83
|
+
if (!oauth?.accessToken) return null;
|
|
84
|
+
if (oauth.expiresAt && Date.now() > oauth.expiresAt) {
|
|
85
|
+
console.warn("[llm] Claude Code OAuth token expired. Run: claude auth login");
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return oauth.accessToken;
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
6
93
|
var LLMClient = class {
|
|
7
94
|
baseUrl;
|
|
8
95
|
model;
|
|
9
96
|
maxTokens;
|
|
10
97
|
temperature;
|
|
11
98
|
apiKey;
|
|
99
|
+
provider;
|
|
12
100
|
constructor(config) {
|
|
13
101
|
this.baseUrl = config.base_url;
|
|
14
102
|
this.model = config.model;
|
|
15
103
|
this.maxTokens = config.max_tokens;
|
|
16
104
|
this.temperature = config.temperature;
|
|
17
105
|
this.apiKey = config.api_key ?? "";
|
|
106
|
+
this.provider = config.provider ?? "openai";
|
|
107
|
+
if (this.provider === "anthropic" && !this.apiKey) {
|
|
108
|
+
const token = getClaudeCodeOAuthToken();
|
|
109
|
+
if (token) {
|
|
110
|
+
this.apiKey = token;
|
|
111
|
+
if (!this.baseUrl || this.baseUrl.includes("openrouter")) {
|
|
112
|
+
this.baseUrl = "https://api.anthropic.com";
|
|
113
|
+
}
|
|
114
|
+
console.log("[llm] Auth: Claude Max OAuth (from macOS Keychain)");
|
|
115
|
+
} else {
|
|
116
|
+
console.warn("[llm] Auth: No API key found for Anthropic provider");
|
|
117
|
+
}
|
|
118
|
+
} else if (this.provider === "anthropic") {
|
|
119
|
+
console.log("[llm] Auth: Anthropic API key (from config/env)");
|
|
120
|
+
}
|
|
18
121
|
}
|
|
19
122
|
/**
|
|
20
123
|
* Simple chat completion (no tools). Backwards compatible.
|
|
@@ -27,6 +130,13 @@ var LLMClient = class {
|
|
|
27
130
|
* Returns tool_calls if the model wants to use tools.
|
|
28
131
|
*/
|
|
29
132
|
async chatWithTools(messages, tools) {
|
|
133
|
+
if (this.provider === "anthropic") {
|
|
134
|
+
return this.chatAnthropic(messages, tools);
|
|
135
|
+
}
|
|
136
|
+
return this.chatOpenAI(messages, tools);
|
|
137
|
+
}
|
|
138
|
+
// --- OpenAI-compatible path (OpenRouter, etc.) ---
|
|
139
|
+
async chatOpenAI(messages, tools) {
|
|
30
140
|
const body = {
|
|
31
141
|
model: this.model,
|
|
32
142
|
messages,
|
|
@@ -75,6 +185,54 @@ var LLMClient = class {
|
|
|
75
185
|
}
|
|
76
186
|
throw lastError ?? new Error("LLM request failed after retries");
|
|
77
187
|
}
|
|
188
|
+
// --- Anthropic Messages API path ---
|
|
189
|
+
async chatAnthropic(messages, tools) {
|
|
190
|
+
const { system, messages: convertedMessages } = convertMessagesForAnthropic(messages);
|
|
191
|
+
const body = {
|
|
192
|
+
model: this.model,
|
|
193
|
+
max_tokens: this.maxTokens,
|
|
194
|
+
temperature: this.temperature,
|
|
195
|
+
messages: convertedMessages
|
|
196
|
+
};
|
|
197
|
+
if (system) {
|
|
198
|
+
body.system = system;
|
|
199
|
+
}
|
|
200
|
+
if (tools && tools.length > 0) {
|
|
201
|
+
body.tools = convertToolsForAnthropic(tools);
|
|
202
|
+
body.tool_choice = { type: "auto" };
|
|
203
|
+
}
|
|
204
|
+
const RETRYABLE_CODES = [429, 500, 502, 503, 529];
|
|
205
|
+
const MAX_RETRIES = 3;
|
|
206
|
+
let lastError = null;
|
|
207
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
208
|
+
if (attempt > 0) {
|
|
209
|
+
const delayMs = Math.pow(2, attempt) * 1e3;
|
|
210
|
+
console.log(`[llm] Retry ${attempt}/${MAX_RETRIES} after ${delayMs}ms...`);
|
|
211
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
212
|
+
}
|
|
213
|
+
const resp = await fetch(`${this.baseUrl}/v1/messages`, {
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: {
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"x-api-key": this.apiKey,
|
|
218
|
+
"anthropic-version": "2023-06-01"
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify(body)
|
|
221
|
+
});
|
|
222
|
+
if (!resp.ok) {
|
|
223
|
+
const text = await resp.text();
|
|
224
|
+
lastError = new Error(`Anthropic request failed: ${resp.status} ${text}`);
|
|
225
|
+
if (RETRYABLE_CODES.includes(resp.status) && attempt < MAX_RETRIES) {
|
|
226
|
+
console.warn(`[llm] Retryable error ${resp.status}: ${text.slice(0, 200)}`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
throw lastError;
|
|
230
|
+
}
|
|
231
|
+
const data = await resp.json();
|
|
232
|
+
return parseAnthropicResponse(data);
|
|
233
|
+
}
|
|
234
|
+
throw lastError ?? new Error("Anthropic request failed after retries");
|
|
235
|
+
}
|
|
78
236
|
};
|
|
79
237
|
|
|
80
238
|
// packages/runtime/src/memory-client.ts
|
|
@@ -2336,6 +2494,26 @@ function loadConfig(path) {
|
|
|
2336
2494
|
if (process.env.LLM_API_KEY) {
|
|
2337
2495
|
parsed.llm.api_key = process.env.LLM_API_KEY;
|
|
2338
2496
|
}
|
|
2497
|
+
if (process.env.ANTHROPIC_API_KEY && !parsed.llm.api_key) {
|
|
2498
|
+
parsed.llm.api_key = process.env.ANTHROPIC_API_KEY;
|
|
2499
|
+
if (!parsed.llm.provider) parsed.llm.provider = "anthropic";
|
|
2500
|
+
if (!process.env.LLM_BASE_URL && parsed.llm.base_url.includes("openrouter")) {
|
|
2501
|
+
parsed.llm.base_url = "https://api.anthropic.com";
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
if (parsed.llm.provider === "anthropic" && !parsed.llm.api_key) {
|
|
2505
|
+
const oauthToken = getClaudeCodeOAuthToken();
|
|
2506
|
+
if (oauthToken) {
|
|
2507
|
+
parsed.llm.api_key = oauthToken;
|
|
2508
|
+
if (!process.env.LLM_BASE_URL && parsed.llm.base_url.includes("openrouter")) {
|
|
2509
|
+
parsed.llm.base_url = "https://api.anthropic.com";
|
|
2510
|
+
}
|
|
2511
|
+
console.log("[config] Auth: Claude Max OAuth (from macOS Keychain)");
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
if (process.env.LLM_PROVIDER) {
|
|
2515
|
+
parsed.llm.provider = process.env.LLM_PROVIDER;
|
|
2516
|
+
}
|
|
2339
2517
|
if (process.env.LLM_BASE_URL) {
|
|
2340
2518
|
parsed.llm.base_url = process.env.LLM_BASE_URL;
|
|
2341
2519
|
}
|
|
@@ -2380,6 +2558,626 @@ function loadConfig(path) {
|
|
|
2380
2558
|
return parsed;
|
|
2381
2559
|
}
|
|
2382
2560
|
|
|
2561
|
+
// node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/client.js
|
|
2562
|
+
import WebSocket from "ws";
|
|
2563
|
+
|
|
2564
|
+
// node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/auth.js
|
|
2565
|
+
import { sign } from "crypto";
|
|
2566
|
+
function createAuthSignature(handle, privateKeyBase64url) {
|
|
2567
|
+
const timestamp = Date.now();
|
|
2568
|
+
const message = `AUTH:${handle}:${timestamp}`;
|
|
2569
|
+
const privateKeyDer = Buffer.from(privateKeyBase64url, "base64url");
|
|
2570
|
+
const privateKey = {
|
|
2571
|
+
key: privateKeyDer,
|
|
2572
|
+
format: "der",
|
|
2573
|
+
type: "pkcs8"
|
|
2574
|
+
};
|
|
2575
|
+
const sig = sign(null, Buffer.from(message), privateKey);
|
|
2576
|
+
return {
|
|
2577
|
+
signature: sig.toString("base64url"),
|
|
2578
|
+
timestamp
|
|
2579
|
+
};
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
// node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/client.js
|
|
2583
|
+
var SesameClient = class {
|
|
2584
|
+
config;
|
|
2585
|
+
ws = null;
|
|
2586
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
2587
|
+
reconnectAttempts = 0;
|
|
2588
|
+
reconnectTimer = null;
|
|
2589
|
+
heartbeatTimer = null;
|
|
2590
|
+
cursors = /* @__PURE__ */ new Map();
|
|
2591
|
+
authenticated = false;
|
|
2592
|
+
constructor(config) {
|
|
2593
|
+
this.config = {
|
|
2594
|
+
autoReconnect: true,
|
|
2595
|
+
maxReconnectAttempts: 10,
|
|
2596
|
+
...config
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
// ── HTTP Methods ──
|
|
2600
|
+
async fetch(path, options = {}) {
|
|
2601
|
+
const headers = {
|
|
2602
|
+
"Content-Type": "application/json",
|
|
2603
|
+
...options.headers ?? {}
|
|
2604
|
+
};
|
|
2605
|
+
if (this.config.apiKey) {
|
|
2606
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
2607
|
+
} else if (this.config.token) {
|
|
2608
|
+
headers["Authorization"] = `Bearer ${this.config.token}`;
|
|
2609
|
+
} else if (this.config.agent) {
|
|
2610
|
+
const { signature, timestamp } = createAuthSignature(this.config.agent.handle, this.config.agent.privateKey);
|
|
2611
|
+
headers["Authorization"] = `Signature ${this.config.agent.handle}.${signature}.${timestamp}`;
|
|
2612
|
+
}
|
|
2613
|
+
const response = await globalThis.fetch(`${this.config.apiUrl}${path}`, {
|
|
2614
|
+
...options,
|
|
2615
|
+
headers
|
|
2616
|
+
});
|
|
2617
|
+
if (!response.ok) {
|
|
2618
|
+
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
2619
|
+
throw new SesameApiError(response.status, error.error ?? "Request failed");
|
|
2620
|
+
}
|
|
2621
|
+
return response.json();
|
|
2622
|
+
}
|
|
2623
|
+
get(path) {
|
|
2624
|
+
return this.fetch(path);
|
|
2625
|
+
}
|
|
2626
|
+
post(path, body) {
|
|
2627
|
+
return this.fetch(path, {
|
|
2628
|
+
method: "POST",
|
|
2629
|
+
body: body ? JSON.stringify(body) : void 0
|
|
2630
|
+
});
|
|
2631
|
+
}
|
|
2632
|
+
patch(path, body) {
|
|
2633
|
+
return this.fetch(path, {
|
|
2634
|
+
method: "PATCH",
|
|
2635
|
+
body: JSON.stringify(body)
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
del(path) {
|
|
2639
|
+
return this.fetch(path, { method: "DELETE" });
|
|
2640
|
+
}
|
|
2641
|
+
// ── Auth ──
|
|
2642
|
+
async login(email, password) {
|
|
2643
|
+
const result = await this.post("/api/v1/auth/login", { email, password });
|
|
2644
|
+
this.config.token = result.accessToken;
|
|
2645
|
+
return result;
|
|
2646
|
+
}
|
|
2647
|
+
// ── Channels ──
|
|
2648
|
+
async listChannels() {
|
|
2649
|
+
const result = await this.get("/api/v1/channels");
|
|
2650
|
+
const channels = result.data ?? result.channels ?? result;
|
|
2651
|
+
return { channels: Array.isArray(channels) ? channels : [] };
|
|
2652
|
+
}
|
|
2653
|
+
async getChannel(id) {
|
|
2654
|
+
const result = await this.get(`/api/v1/channels/${id}`);
|
|
2655
|
+
const channel = result.data ?? result.channel ?? result;
|
|
2656
|
+
return { channel };
|
|
2657
|
+
}
|
|
2658
|
+
async createChannel(data) {
|
|
2659
|
+
const result = await this.post("/api/v1/channels", data);
|
|
2660
|
+
const channel = result.data ?? result.channel ?? result;
|
|
2661
|
+
return { channel };
|
|
2662
|
+
}
|
|
2663
|
+
async getOrCreateDM(principalId) {
|
|
2664
|
+
const result = await this.post("/api/v1/channels/dm", { principalId });
|
|
2665
|
+
const channel = result.data ?? result.channel ?? result;
|
|
2666
|
+
return { channel };
|
|
2667
|
+
}
|
|
2668
|
+
async getUnread() {
|
|
2669
|
+
return this.get("/api/v1/channels/unread");
|
|
2670
|
+
}
|
|
2671
|
+
// ── Messages ──
|
|
2672
|
+
async sendMessage(channelId, options) {
|
|
2673
|
+
const result = await this.post(`/api/v1/channels/${channelId}/messages`, options);
|
|
2674
|
+
const message = this.normalizeMessage(result.data ?? result.message ?? result);
|
|
2675
|
+
if (message.seq) {
|
|
2676
|
+
this.cursors.set(channelId, message.seq);
|
|
2677
|
+
}
|
|
2678
|
+
return { message };
|
|
2679
|
+
}
|
|
2680
|
+
async getMessages(channelId, options) {
|
|
2681
|
+
const params = new URLSearchParams();
|
|
2682
|
+
if (options?.cursor)
|
|
2683
|
+
params.set("cursor", options.cursor.toString());
|
|
2684
|
+
if (options?.limit)
|
|
2685
|
+
params.set("limit", options.limit.toString());
|
|
2686
|
+
if (options?.direction)
|
|
2687
|
+
params.set("direction", options.direction);
|
|
2688
|
+
if (options?.threadRootId)
|
|
2689
|
+
params.set("threadRootId", options.threadRootId);
|
|
2690
|
+
const qs = params.toString();
|
|
2691
|
+
const result = await this.get(`/api/v1/channels/${channelId}/messages${qs ? `?${qs}` : ""}`);
|
|
2692
|
+
const messages = (result.data ?? result.messages ?? []).map((m) => this.normalizeMessage(m));
|
|
2693
|
+
if (messages.length > 0) {
|
|
2694
|
+
const maxSeq = Math.max(...messages.map((m) => m.seq));
|
|
2695
|
+
const current = this.cursors.get(channelId) ?? 0;
|
|
2696
|
+
if (maxSeq > current)
|
|
2697
|
+
this.cursors.set(channelId, maxSeq);
|
|
2698
|
+
}
|
|
2699
|
+
return {
|
|
2700
|
+
messages,
|
|
2701
|
+
cursor: result.pagination?.cursor ? Number(result.pagination.cursor) : 0,
|
|
2702
|
+
hasMore: result.pagination?.hasMore ?? false
|
|
2703
|
+
};
|
|
2704
|
+
}
|
|
2705
|
+
async editMessage(channelId, messageId, content) {
|
|
2706
|
+
const result = await this.patch(`/api/v1/channels/${channelId}/messages/${messageId}`, { content });
|
|
2707
|
+
const message = this.normalizeMessage(result.data ?? result.message ?? result);
|
|
2708
|
+
return { message };
|
|
2709
|
+
}
|
|
2710
|
+
async deleteMessage(channelId, messageId) {
|
|
2711
|
+
await this.del(`/api/v1/channels/${channelId}/messages/${messageId}`);
|
|
2712
|
+
}
|
|
2713
|
+
async markRead(channelId, seq) {
|
|
2714
|
+
await this.post(`/api/v1/channels/${channelId}/messages/read`, { seq });
|
|
2715
|
+
}
|
|
2716
|
+
async addReaction(channelId, messageId, emoji) {
|
|
2717
|
+
await this.post(`/api/v1/channels/${channelId}/messages/${messageId}/reactions`, { emoji });
|
|
2718
|
+
}
|
|
2719
|
+
async removeReaction(channelId, messageId, emoji) {
|
|
2720
|
+
await this.del(`/api/v1/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`);
|
|
2721
|
+
}
|
|
2722
|
+
// ── Vault ──
|
|
2723
|
+
async listVaults() {
|
|
2724
|
+
return this.get("/api/v1/vault/vaults");
|
|
2725
|
+
}
|
|
2726
|
+
async listVaultItems(vaultId) {
|
|
2727
|
+
const qs = vaultId ? `?vaultId=${vaultId}` : "";
|
|
2728
|
+
return this.get(`/api/v1/vault/items${qs}`);
|
|
2729
|
+
}
|
|
2730
|
+
async getVaultItem(id) {
|
|
2731
|
+
return this.get(`/api/v1/vault/items/${id}`);
|
|
2732
|
+
}
|
|
2733
|
+
async createVaultItem(options) {
|
|
2734
|
+
return this.post("/api/v1/vault/items", options);
|
|
2735
|
+
}
|
|
2736
|
+
async revealItem(id, fields) {
|
|
2737
|
+
return this.post(`/api/v1/vault/items/${id}/reveal`, fields ? { fields } : void 0);
|
|
2738
|
+
}
|
|
2739
|
+
async shareItem(itemId, principalId, options) {
|
|
2740
|
+
await this.post(`/api/v1/vault/items/${itemId}/share`, {
|
|
2741
|
+
principalId,
|
|
2742
|
+
...options
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
async revokeShare(itemId, principalId) {
|
|
2746
|
+
await this.del(`/api/v1/vault/items/${itemId}/share/${principalId}`);
|
|
2747
|
+
}
|
|
2748
|
+
async getWallet() {
|
|
2749
|
+
return this.get("/api/v1/vault/wallet");
|
|
2750
|
+
}
|
|
2751
|
+
// ── Leases ──
|
|
2752
|
+
async requestLease(options) {
|
|
2753
|
+
return this.post("/api/v1/vault/leases/request", options);
|
|
2754
|
+
}
|
|
2755
|
+
async approveLease(leaseId, options) {
|
|
2756
|
+
return this.post(`/api/v1/vault/leases/${leaseId}/approve`, options ?? {});
|
|
2757
|
+
}
|
|
2758
|
+
async denyLease(leaseId) {
|
|
2759
|
+
return this.post(`/api/v1/vault/leases/${leaseId}/deny`, {});
|
|
2760
|
+
}
|
|
2761
|
+
async useSecret(leaseId) {
|
|
2762
|
+
return this.post(`/api/v1/vault/leases/${leaseId}/use`, {});
|
|
2763
|
+
}
|
|
2764
|
+
async revokeLease(leaseId) {
|
|
2765
|
+
await this.del(`/api/v1/vault/leases/${leaseId}`);
|
|
2766
|
+
}
|
|
2767
|
+
// ── HTTP helper: PUT ──
|
|
2768
|
+
put(path, body) {
|
|
2769
|
+
return this.fetch(path, {
|
|
2770
|
+
method: "PUT",
|
|
2771
|
+
body: body ? JSON.stringify(body) : void 0
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
// ── Agents ──
|
|
2775
|
+
async listAgents() {
|
|
2776
|
+
return this.get("/api/v1/agents");
|
|
2777
|
+
}
|
|
2778
|
+
async provisionAgent(data) {
|
|
2779
|
+
return this.post("/api/v1/agents", data);
|
|
2780
|
+
}
|
|
2781
|
+
async generateApiKey(agentId, label) {
|
|
2782
|
+
const res = await this.post(`/api/v1/agents/${agentId}/api-keys`, { label });
|
|
2783
|
+
return res.data ?? res;
|
|
2784
|
+
}
|
|
2785
|
+
// ── Capabilities ──
|
|
2786
|
+
async registerCapabilities(capabilities) {
|
|
2787
|
+
const agentId = this.getAgentId();
|
|
2788
|
+
const result = await this.put(`/api/v1/agents/${agentId}/capabilities`, { capabilities });
|
|
2789
|
+
return { capabilities: result.data ?? result };
|
|
2790
|
+
}
|
|
2791
|
+
async addCapability(capability) {
|
|
2792
|
+
const agentId = this.getAgentId();
|
|
2793
|
+
const result = await this.post(`/api/v1/agents/${agentId}/capabilities`, capability);
|
|
2794
|
+
return { capability: result.data ?? result };
|
|
2795
|
+
}
|
|
2796
|
+
async getCapabilities(agentId) {
|
|
2797
|
+
const id = agentId ?? this.getAgentId();
|
|
2798
|
+
const result = await this.get(`/api/v1/agents/${id}/capabilities`);
|
|
2799
|
+
return { capabilities: result.data ?? result };
|
|
2800
|
+
}
|
|
2801
|
+
async removeCapability(capabilityId) {
|
|
2802
|
+
const agentId = this.getAgentId();
|
|
2803
|
+
await this.del(`/api/v1/agents/${agentId}/capabilities/${capabilityId}`);
|
|
2804
|
+
}
|
|
2805
|
+
// ── Discovery ──
|
|
2806
|
+
async discoverAgents(query = {}) {
|
|
2807
|
+
const params = new URLSearchParams();
|
|
2808
|
+
if (query.namespace)
|
|
2809
|
+
params.set("namespace", query.namespace);
|
|
2810
|
+
if (query.name)
|
|
2811
|
+
params.set("name", query.name);
|
|
2812
|
+
if (query.capability) {
|
|
2813
|
+
const caps = Array.isArray(query.capability) ? query.capability : [query.capability];
|
|
2814
|
+
for (const cap of caps) {
|
|
2815
|
+
params.append("capability", cap);
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
if (query.active !== void 0)
|
|
2819
|
+
params.set("active", String(query.active));
|
|
2820
|
+
const qs = params.toString();
|
|
2821
|
+
const result = await this.get(`/api/v1/agents/discover${qs ? `?${qs}` : ""}`);
|
|
2822
|
+
return { agents: result.data ?? result };
|
|
2823
|
+
}
|
|
2824
|
+
// ── Manifest & Context ──
|
|
2825
|
+
async getManifest() {
|
|
2826
|
+
if (!this._principalId) {
|
|
2827
|
+
const me = await this.get("/api/v1/auth/me");
|
|
2828
|
+
this.setPrincipalId(me.data?.id ?? me.id);
|
|
2829
|
+
}
|
|
2830
|
+
const agentId = this.getAgentId();
|
|
2831
|
+
const result = await this.get(`/api/v1/agents/${agentId}/manifest`);
|
|
2832
|
+
return result.data ?? result;
|
|
2833
|
+
}
|
|
2834
|
+
async getChannelContext(channelId, options) {
|
|
2835
|
+
const agentId = this.getAgentId();
|
|
2836
|
+
const params = new URLSearchParams();
|
|
2837
|
+
if (options?.strategy)
|
|
2838
|
+
params.set("strategy", options.strategy);
|
|
2839
|
+
if (options?.window)
|
|
2840
|
+
params.set("window", String(options.window));
|
|
2841
|
+
const qs = params.toString();
|
|
2842
|
+
const result = await this.get(`/api/v1/agents/${agentId}/channels/${channelId}/context${qs ? `?${qs}` : ""}`);
|
|
2843
|
+
return result.data ?? result;
|
|
2844
|
+
}
|
|
2845
|
+
// ── Channel Config ──
|
|
2846
|
+
async setChannelConfig(channelId, config) {
|
|
2847
|
+
const agentId = this.getAgentId();
|
|
2848
|
+
const result = await this.put(`/api/v1/agents/${agentId}/channels/${channelId}/config`, config);
|
|
2849
|
+
return result.data ?? result;
|
|
2850
|
+
}
|
|
2851
|
+
async getChannelConfig(channelId) {
|
|
2852
|
+
const agentId = this.getAgentId();
|
|
2853
|
+
const result = await this.get(`/api/v1/agents/${agentId}/channels/${channelId}/config`);
|
|
2854
|
+
return result.data ?? result;
|
|
2855
|
+
}
|
|
2856
|
+
async deleteChannelConfig(channelId) {
|
|
2857
|
+
const agentId = this.getAgentId();
|
|
2858
|
+
await this.del(`/api/v1/agents/${agentId}/channels/${channelId}/config`);
|
|
2859
|
+
}
|
|
2860
|
+
// ── Collaboration ──
|
|
2861
|
+
async createCollaborationChannel(options) {
|
|
2862
|
+
const result = await this.createChannel({
|
|
2863
|
+
kind: "topic",
|
|
2864
|
+
name: options.name,
|
|
2865
|
+
description: options.description,
|
|
2866
|
+
memberIds: options.memberIds
|
|
2867
|
+
});
|
|
2868
|
+
const channel = result.data ?? result.channel ?? result;
|
|
2869
|
+
const channelId = channel.id;
|
|
2870
|
+
if (options.context) {
|
|
2871
|
+
await this.put(`/api/v1/channels/${channelId}/context`, { context: options.context });
|
|
2872
|
+
}
|
|
2873
|
+
if (options.visibility) {
|
|
2874
|
+
await this.patch(`/api/v1/channels/${channelId}`, { visibility: options.visibility });
|
|
2875
|
+
}
|
|
2876
|
+
if (options.coordinationMode) {
|
|
2877
|
+
await this.put(`/api/v1/channels/${channelId}/coordination`, {
|
|
2878
|
+
mode: options.coordinationMode
|
|
2879
|
+
});
|
|
2880
|
+
}
|
|
2881
|
+
return { channel };
|
|
2882
|
+
}
|
|
2883
|
+
// ── Tasks ──
|
|
2884
|
+
async createTask(channelId, options) {
|
|
2885
|
+
const result = await this.post(`/api/v1/channels/${channelId}/tasks`, options);
|
|
2886
|
+
return { task: result.data ?? result };
|
|
2887
|
+
}
|
|
2888
|
+
async listTasks(channelId, filters) {
|
|
2889
|
+
const params = new URLSearchParams();
|
|
2890
|
+
if (filters?.status)
|
|
2891
|
+
params.set("status", filters.status);
|
|
2892
|
+
if (filters?.priority)
|
|
2893
|
+
params.set("priority", filters.priority);
|
|
2894
|
+
if (filters?.assigneeId)
|
|
2895
|
+
params.set("assigneeId", filters.assigneeId);
|
|
2896
|
+
const qs = params.toString();
|
|
2897
|
+
const result = await this.get(`/api/v1/channels/${channelId}/tasks${qs ? `?${qs}` : ""}`);
|
|
2898
|
+
return { tasks: result.data ?? result };
|
|
2899
|
+
}
|
|
2900
|
+
async updateTask(channelId, taskId, updates) {
|
|
2901
|
+
const result = await this.patch(`/api/v1/channels/${channelId}/tasks/${taskId}`, updates);
|
|
2902
|
+
return { task: result.data ?? result };
|
|
2903
|
+
}
|
|
2904
|
+
async claimTask(channelId, taskId) {
|
|
2905
|
+
const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/claim`);
|
|
2906
|
+
return { task: result.data ?? result };
|
|
2907
|
+
}
|
|
2908
|
+
async addTaskAssignee(channelId, taskId, principalId, role) {
|
|
2909
|
+
const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/assignees`, { principalId, role });
|
|
2910
|
+
return { task: result.data ?? result };
|
|
2911
|
+
}
|
|
2912
|
+
async removeTaskAssignee(channelId, taskId, principalId) {
|
|
2913
|
+
const result = await this.del(`/api/v1/channels/${channelId}/tasks/${taskId}/assignees/${principalId}`);
|
|
2914
|
+
return { task: result.data ?? result };
|
|
2915
|
+
}
|
|
2916
|
+
async createTaskChannel(channelId, taskId, options) {
|
|
2917
|
+
const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/channel`, options ?? {});
|
|
2918
|
+
return result.data ?? result;
|
|
2919
|
+
}
|
|
2920
|
+
// ── Webhooks ──
|
|
2921
|
+
async createWebhook(options) {
|
|
2922
|
+
const agentId = this.getAgentId();
|
|
2923
|
+
const result = await this.post(`/api/v1/agents/${agentId}/webhooks`, options);
|
|
2924
|
+
return { webhook: result.data ?? result };
|
|
2925
|
+
}
|
|
2926
|
+
async listWebhooks() {
|
|
2927
|
+
const agentId = this.getAgentId();
|
|
2928
|
+
const result = await this.get(`/api/v1/agents/${agentId}/webhooks`);
|
|
2929
|
+
return { webhooks: result.data ?? result };
|
|
2930
|
+
}
|
|
2931
|
+
async updateWebhook(webhookId, updates) {
|
|
2932
|
+
const agentId = this.getAgentId();
|
|
2933
|
+
const result = await this.patch(`/api/v1/agents/${agentId}/webhooks/${webhookId}`, updates);
|
|
2934
|
+
return { webhook: result.data ?? result };
|
|
2935
|
+
}
|
|
2936
|
+
async deleteWebhook(webhookId) {
|
|
2937
|
+
const agentId = this.getAgentId();
|
|
2938
|
+
await this.del(`/api/v1/agents/${agentId}/webhooks/${webhookId}`);
|
|
2939
|
+
}
|
|
2940
|
+
async rotateWebhookSecret(webhookId) {
|
|
2941
|
+
const agentId = this.getAgentId();
|
|
2942
|
+
const result = await this.post(`/api/v1/agents/${agentId}/webhooks/${webhookId}/rotate-secret`);
|
|
2943
|
+
return result.data ?? result;
|
|
2944
|
+
}
|
|
2945
|
+
async listWebhookDeliveries(webhookId, options) {
|
|
2946
|
+
const agentId = this.getAgentId();
|
|
2947
|
+
const params = new URLSearchParams();
|
|
2948
|
+
if (options?.limit)
|
|
2949
|
+
params.set("limit", String(options.limit));
|
|
2950
|
+
if (options?.status)
|
|
2951
|
+
params.set("status", options.status);
|
|
2952
|
+
const qs = params.toString();
|
|
2953
|
+
const result = await this.get(`/api/v1/agents/${agentId}/webhooks/${webhookId}/deliveries${qs ? `?${qs}` : ""}`);
|
|
2954
|
+
return { deliveries: result.data ?? result };
|
|
2955
|
+
}
|
|
2956
|
+
// ── Profile ──
|
|
2957
|
+
async setReadReceiptEmoji(emoji) {
|
|
2958
|
+
const agentId = this.getAgentId();
|
|
2959
|
+
const result = await this.put(`/api/v1/agents/${agentId}/read-receipt-emoji`, { emoji });
|
|
2960
|
+
return { emoji: result.data?.emoji ?? emoji };
|
|
2961
|
+
}
|
|
2962
|
+
async getReadReceiptEmoji() {
|
|
2963
|
+
const agentId = this.getAgentId();
|
|
2964
|
+
const result = await this.get(`/api/v1/agents/${agentId}/read-receipt-emoji`);
|
|
2965
|
+
return { emoji: result.data?.emoji ?? "\u{1F440}" };
|
|
2966
|
+
}
|
|
2967
|
+
// ── Internal helpers ──
|
|
2968
|
+
normalizeMessage(msg) {
|
|
2969
|
+
return {
|
|
2970
|
+
...msg,
|
|
2971
|
+
content: msg.content ?? msg.plaintext ?? null
|
|
2972
|
+
};
|
|
2973
|
+
}
|
|
2974
|
+
getAgentId() {
|
|
2975
|
+
const principal = this._principalId;
|
|
2976
|
+
if (principal)
|
|
2977
|
+
return principal;
|
|
2978
|
+
throw new SesameApiError(400, "Agent ID not resolved. Call boot() or setPrincipalId(id) first.");
|
|
2979
|
+
}
|
|
2980
|
+
/**
|
|
2981
|
+
* Set the current agent's principal ID (resolved after auth).
|
|
2982
|
+
*/
|
|
2983
|
+
setPrincipalId(id) {
|
|
2984
|
+
this._principalId = id;
|
|
2985
|
+
}
|
|
2986
|
+
/**
|
|
2987
|
+
* Bootstrap the agent: resolves identity via /auth/me and loads manifest.
|
|
2988
|
+
*/
|
|
2989
|
+
async boot() {
|
|
2990
|
+
const me = await this.get("/api/v1/auth/me");
|
|
2991
|
+
const principal = me.data ?? me;
|
|
2992
|
+
this.setPrincipalId(principal.id);
|
|
2993
|
+
const manifest = await this.getManifest();
|
|
2994
|
+
return manifest;
|
|
2995
|
+
}
|
|
2996
|
+
// ── WebSocket ──
|
|
2997
|
+
/**
|
|
2998
|
+
* Connect to the real-time WebSocket gateway.
|
|
2999
|
+
*/
|
|
3000
|
+
connect() {
|
|
3001
|
+
return new Promise((resolve20, reject) => {
|
|
3002
|
+
try {
|
|
3003
|
+
this.ws = new WebSocket(`${this.config.wsUrl}/v1/connect`);
|
|
3004
|
+
this.ws.on("open", () => {
|
|
3005
|
+
this.reconnectAttempts = 0;
|
|
3006
|
+
this.sendAuth();
|
|
3007
|
+
});
|
|
3008
|
+
this.ws.on("message", (data) => {
|
|
3009
|
+
try {
|
|
3010
|
+
const event = JSON.parse(data.toString());
|
|
3011
|
+
if (event.type === "authenticated") {
|
|
3012
|
+
this.authenticated = true;
|
|
3013
|
+
this.startHeartbeat(event.heartbeatIntervalMs ?? 3e4);
|
|
3014
|
+
this.sendReplay();
|
|
3015
|
+
resolve20();
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
if (event.type === "pong")
|
|
3019
|
+
return;
|
|
3020
|
+
if (event.type === "error") {
|
|
3021
|
+
console.error("WS error:", event.message);
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
if (event.type === "message" && event.data) {
|
|
3025
|
+
event.data = this.normalizeMessage(event.data);
|
|
3026
|
+
const seq = event.data.seq;
|
|
3027
|
+
if (seq) {
|
|
3028
|
+
const channelId = event.data.channelId;
|
|
3029
|
+
const current = this.cursors.get(channelId) ?? 0;
|
|
3030
|
+
if (seq > current)
|
|
3031
|
+
this.cursors.set(channelId, seq);
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
this.emit(event);
|
|
3035
|
+
} catch {
|
|
3036
|
+
}
|
|
3037
|
+
});
|
|
3038
|
+
this.ws.on("close", () => {
|
|
3039
|
+
this.authenticated = false;
|
|
3040
|
+
this.stopHeartbeat();
|
|
3041
|
+
if (this.config.autoReconnect) {
|
|
3042
|
+
this.scheduleReconnect();
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
this.ws.on("error", (err) => {
|
|
3046
|
+
if (!this.authenticated) {
|
|
3047
|
+
reject(err);
|
|
3048
|
+
}
|
|
3049
|
+
});
|
|
3050
|
+
} catch (err) {
|
|
3051
|
+
reject(err);
|
|
3052
|
+
}
|
|
3053
|
+
});
|
|
3054
|
+
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Disconnect from the WebSocket gateway.
|
|
3057
|
+
*/
|
|
3058
|
+
disconnect() {
|
|
3059
|
+
this.config.autoReconnect = false;
|
|
3060
|
+
this.stopHeartbeat();
|
|
3061
|
+
if (this.reconnectTimer) {
|
|
3062
|
+
clearTimeout(this.reconnectTimer);
|
|
3063
|
+
this.reconnectTimer = null;
|
|
3064
|
+
}
|
|
3065
|
+
if (this.ws) {
|
|
3066
|
+
this.ws.close();
|
|
3067
|
+
this.ws = null;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
/**
|
|
3071
|
+
* Subscribe to WebSocket events.
|
|
3072
|
+
*/
|
|
3073
|
+
on(eventType, handler) {
|
|
3074
|
+
if (!this.eventHandlers.has(eventType)) {
|
|
3075
|
+
this.eventHandlers.set(eventType, /* @__PURE__ */ new Set());
|
|
3076
|
+
}
|
|
3077
|
+
this.eventHandlers.get(eventType).add(handler);
|
|
3078
|
+
return () => {
|
|
3079
|
+
this.eventHandlers.get(eventType)?.delete(handler);
|
|
3080
|
+
};
|
|
3081
|
+
}
|
|
3082
|
+
/**
|
|
3083
|
+
* Subscribe to all events.
|
|
3084
|
+
*/
|
|
3085
|
+
onAny(handler) {
|
|
3086
|
+
return this.on("*", handler);
|
|
3087
|
+
}
|
|
3088
|
+
emit(event) {
|
|
3089
|
+
this.eventHandlers.get(event.type)?.forEach((h) => h(event));
|
|
3090
|
+
this.eventHandlers.get("*")?.forEach((h) => h(event));
|
|
3091
|
+
}
|
|
3092
|
+
sendAuth() {
|
|
3093
|
+
if (!this.ws)
|
|
3094
|
+
return;
|
|
3095
|
+
if (this.config.apiKey) {
|
|
3096
|
+
this.ws.send(JSON.stringify({ type: "auth", apiKey: this.config.apiKey }));
|
|
3097
|
+
} else if (this.config.token) {
|
|
3098
|
+
this.ws.send(JSON.stringify({ type: "auth", token: this.config.token }));
|
|
3099
|
+
} else if (this.config.agent) {
|
|
3100
|
+
const { signature, timestamp } = createAuthSignature(this.config.agent.handle, this.config.agent.privateKey);
|
|
3101
|
+
this.ws.send(JSON.stringify({
|
|
3102
|
+
type: "auth",
|
|
3103
|
+
signature: {
|
|
3104
|
+
handle: this.config.agent.handle,
|
|
3105
|
+
sig: signature,
|
|
3106
|
+
timestamp
|
|
3107
|
+
}
|
|
3108
|
+
}));
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
sendReplay() {
|
|
3112
|
+
if (!this.ws || this.cursors.size === 0)
|
|
3113
|
+
return;
|
|
3114
|
+
const cursors = {};
|
|
3115
|
+
this.cursors.forEach((seq, channelId) => {
|
|
3116
|
+
cursors[channelId] = seq;
|
|
3117
|
+
});
|
|
3118
|
+
this.ws.send(JSON.stringify({ type: "replay", cursors }));
|
|
3119
|
+
}
|
|
3120
|
+
startHeartbeat(intervalMs) {
|
|
3121
|
+
this.stopHeartbeat();
|
|
3122
|
+
this.heartbeatTimer = setInterval(() => {
|
|
3123
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
3124
|
+
this.ws.send(JSON.stringify({ type: "ping" }));
|
|
3125
|
+
}
|
|
3126
|
+
}, intervalMs);
|
|
3127
|
+
}
|
|
3128
|
+
stopHeartbeat() {
|
|
3129
|
+
if (this.heartbeatTimer) {
|
|
3130
|
+
clearInterval(this.heartbeatTimer);
|
|
3131
|
+
this.heartbeatTimer = null;
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
scheduleReconnect() {
|
|
3135
|
+
if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
3136
|
+
console.error("Max reconnect attempts reached");
|
|
3137
|
+
return;
|
|
3138
|
+
}
|
|
3139
|
+
const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), 3e4);
|
|
3140
|
+
this.reconnectAttempts++;
|
|
3141
|
+
this.reconnectTimer = setTimeout(() => {
|
|
3142
|
+
this.connect().catch(() => {
|
|
3143
|
+
this.scheduleReconnect();
|
|
3144
|
+
});
|
|
3145
|
+
}, delay);
|
|
3146
|
+
}
|
|
3147
|
+
/**
|
|
3148
|
+
* Send a typing indicator for a channel.
|
|
3149
|
+
*/
|
|
3150
|
+
sendTyping(channelId) {
|
|
3151
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
3152
|
+
this.ws.send(JSON.stringify({ type: "typing", channelId }));
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Send a message via WebSocket (alternative to HTTP).
|
|
3157
|
+
*/
|
|
3158
|
+
sendWsMessage(channelId, content, options) {
|
|
3159
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
3160
|
+
this.ws.send(JSON.stringify({
|
|
3161
|
+
type: "send",
|
|
3162
|
+
channelId,
|
|
3163
|
+
content,
|
|
3164
|
+
...options
|
|
3165
|
+
}));
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
};
|
|
3169
|
+
var SesameApiError = class extends Error {
|
|
3170
|
+
status;
|
|
3171
|
+
constructor(status, message) {
|
|
3172
|
+
super(message);
|
|
3173
|
+
this.status = status;
|
|
3174
|
+
this.name = "SesameApiError";
|
|
3175
|
+
}
|
|
3176
|
+
};
|
|
3177
|
+
|
|
3178
|
+
// node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/verify-webhook.js
|
|
3179
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
3180
|
+
|
|
2383
3181
|
// packages/runtime/src/sesame.ts
|
|
2384
3182
|
import { readFileSync as readFileSync5 } from "fs";
|
|
2385
3183
|
import { resolve as resolve4, dirname as dirname3 } from "path";
|
|
@@ -2549,7 +3347,7 @@ var SesameClient2 = class {
|
|
|
2549
3347
|
};
|
|
2550
3348
|
|
|
2551
3349
|
// packages/runtime/src/skills.ts
|
|
2552
|
-
import { execSync } from "child_process";
|
|
3350
|
+
import { execSync as execSync2 } from "child_process";
|
|
2553
3351
|
import { existsSync as existsSync5, readFileSync as readFileSync6, readdirSync as readdirSync3, watch as watch2, mkdirSync as mkdirSync3 } from "fs";
|
|
2554
3352
|
import { resolve as resolve5 } from "path";
|
|
2555
3353
|
function shellEscape(value) {
|
|
@@ -2618,7 +3416,7 @@ var SkillsEngine = class {
|
|
|
2618
3416
|
const setupPath = resolve5(skillDir, "setup.sh");
|
|
2619
3417
|
if (existsSync5(setupPath)) {
|
|
2620
3418
|
try {
|
|
2621
|
-
|
|
3419
|
+
execSync2("bash setup.sh", { cwd: skillDir, timeout: 3e4, stdio: "pipe" });
|
|
2622
3420
|
console.log(`[skills] Ran setup.sh for "${name}"`);
|
|
2623
3421
|
} catch (err) {
|
|
2624
3422
|
console.warn(`[skills] setup.sh failed for "${name}":`, err.message);
|
|
@@ -2643,7 +3441,7 @@ var SkillsEngine = class {
|
|
|
2643
3441
|
async (params) => {
|
|
2644
3442
|
const cmd = renderCommand(commandTemplate, params, skillDir, this.workspaceDir);
|
|
2645
3443
|
try {
|
|
2646
|
-
const output =
|
|
3444
|
+
const output = execSync2(cmd, {
|
|
2647
3445
|
cwd: skillDir,
|
|
2648
3446
|
timeout: 6e4,
|
|
2649
3447
|
encoding: "utf-8",
|
|
@@ -2682,7 +3480,7 @@ var SkillsEngine = class {
|
|
|
2682
3480
|
const teardownPath = resolve5(skill.path, "teardown.sh");
|
|
2683
3481
|
if (existsSync5(teardownPath)) {
|
|
2684
3482
|
try {
|
|
2685
|
-
|
|
3483
|
+
execSync2("bash teardown.sh", { cwd: skill.path, timeout: 3e4, stdio: "pipe" });
|
|
2686
3484
|
console.log(`[skills] Ran teardown.sh for "${skill.name}"`);
|
|
2687
3485
|
} catch (err) {
|
|
2688
3486
|
console.warn(`[skills] teardown.sh failed for "${skill.name}":`, err.message);
|
|
@@ -3078,7 +3876,7 @@ var ToolRegistry = class {
|
|
|
3078
3876
|
};
|
|
3079
3877
|
|
|
3080
3878
|
// packages/runtime/src/tools/shell.ts
|
|
3081
|
-
import { execSync as
|
|
3879
|
+
import { execSync as execSync3 } from "child_process";
|
|
3082
3880
|
import { resolve as resolve7 } from "path";
|
|
3083
3881
|
var MAX_OUTPUT = 5e4;
|
|
3084
3882
|
function registerShellTool(registry, workspaceDir) {
|
|
@@ -3108,7 +3906,7 @@ function registerShellTool(registry, workspaceDir) {
|
|
|
3108
3906
|
const timeout = (params.timeout || 30) * 1e3;
|
|
3109
3907
|
const cwd = params.workdir ? resolve7(workspaceDir, params.workdir) : workspaceDir;
|
|
3110
3908
|
try {
|
|
3111
|
-
const output =
|
|
3909
|
+
const output = execSync3(command, {
|
|
3112
3910
|
cwd,
|
|
3113
3911
|
timeout,
|
|
3114
3912
|
encoding: "utf-8",
|
|
@@ -3981,7 +4779,7 @@ function registerVisionTools(registry) {
|
|
|
3981
4779
|
}
|
|
3982
4780
|
|
|
3983
4781
|
// packages/runtime/src/tools/git.ts
|
|
3984
|
-
import { execSync as
|
|
4782
|
+
import { execSync as execSync4 } from "child_process";
|
|
3985
4783
|
import { resolve as resolve10, normalize } from "path";
|
|
3986
4784
|
function resolveRepoPath(workspaceDir, repoPath) {
|
|
3987
4785
|
if (!repoPath) return workspaceDir;
|
|
@@ -3994,7 +4792,7 @@ function resolveRepoPath(workspaceDir, repoPath) {
|
|
|
3994
4792
|
return resolved;
|
|
3995
4793
|
}
|
|
3996
4794
|
function runGit(args, cwd) {
|
|
3997
|
-
const output =
|
|
4795
|
+
const output = execSync4(`git ${args}`, {
|
|
3998
4796
|
cwd,
|
|
3999
4797
|
timeout: 3e4,
|
|
4000
4798
|
encoding: "utf-8",
|
|
@@ -4401,7 +5199,7 @@ function registerBrowserTools(registry, workspaceDir) {
|
|
|
4401
5199
|
}
|
|
4402
5200
|
|
|
4403
5201
|
// packages/runtime/src/tools/system.ts
|
|
4404
|
-
import { execSync as
|
|
5202
|
+
import { execSync as execSync5 } from "child_process";
|
|
4405
5203
|
import * as os from "os";
|
|
4406
5204
|
var MAX_OUTPUT3 = 5e4;
|
|
4407
5205
|
function truncate(output) {
|
|
@@ -4412,7 +5210,7 @@ function truncate(output) {
|
|
|
4412
5210
|
return output;
|
|
4413
5211
|
}
|
|
4414
5212
|
function exec(cmd, timeoutS = 10) {
|
|
4415
|
-
return
|
|
5213
|
+
return execSync5(cmd, {
|
|
4416
5214
|
encoding: "utf-8",
|
|
4417
5215
|
timeout: timeoutS * 1e3,
|
|
4418
5216
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -5003,13 +5801,13 @@ ${lines.join("\n")}`;
|
|
|
5003
5801
|
}
|
|
5004
5802
|
|
|
5005
5803
|
// packages/runtime/src/tools/macos.ts
|
|
5006
|
-
import { execSync as
|
|
5804
|
+
import { execSync as execSync6 } from "child_process";
|
|
5007
5805
|
import { resolve as resolve14, normalize as normalize2 } from "path";
|
|
5008
5806
|
import { mkdirSync as mkdirSync10, existsSync as existsSync13 } from "fs";
|
|
5009
5807
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
5010
5808
|
var MAX_OUTPUT4 = 5e4;
|
|
5011
5809
|
function shellExec(command, timeoutMs) {
|
|
5012
|
-
return
|
|
5810
|
+
return execSync6(command, {
|
|
5013
5811
|
timeout: timeoutMs,
|
|
5014
5812
|
encoding: "utf-8",
|
|
5015
5813
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -5120,7 +5918,7 @@ ${output || err.message}`;
|
|
|
5120
5918
|
async (params) => {
|
|
5121
5919
|
const content = params.content;
|
|
5122
5920
|
try {
|
|
5123
|
-
|
|
5921
|
+
execSync6("pbcopy", {
|
|
5124
5922
|
input: content,
|
|
5125
5923
|
timeout: 5e3,
|
|
5126
5924
|
encoding: "utf-8",
|
|
@@ -5220,12 +6018,12 @@ function escapeAppleString(s) {
|
|
|
5220
6018
|
}
|
|
5221
6019
|
|
|
5222
6020
|
// packages/runtime/src/tools/data.ts
|
|
5223
|
-
import { execSync as
|
|
6021
|
+
import { execSync as execSync7 } from "child_process";
|
|
5224
6022
|
import { resolve as resolve15, normalize as normalize3, extname as extname2 } from "path";
|
|
5225
6023
|
import { mkdirSync as mkdirSync11, existsSync as existsSync14 } from "fs";
|
|
5226
6024
|
var MAX_OUTPUT5 = 5e4;
|
|
5227
6025
|
function shellExec2(command, cwd, timeoutMs) {
|
|
5228
|
-
return
|
|
6026
|
+
return execSync7(command, {
|
|
5229
6027
|
cwd,
|
|
5230
6028
|
timeout: timeoutMs,
|
|
5231
6029
|
encoding: "utf-8",
|
|
@@ -5465,15 +6263,83 @@ function truncate2(text) {
|
|
|
5465
6263
|
return text;
|
|
5466
6264
|
}
|
|
5467
6265
|
|
|
5468
|
-
// packages/runtime/src/tools/
|
|
6266
|
+
// packages/runtime/src/tools/coding-agent.ts
|
|
6267
|
+
import { execSync as execSync8 } from "child_process";
|
|
5469
6268
|
import { resolve as resolve16 } from "path";
|
|
6269
|
+
var MAX_OUTPUT6 = 5e4;
|
|
6270
|
+
function registerCodingAgentTools(registry, workspaceDir) {
|
|
6271
|
+
registry.register(
|
|
6272
|
+
"coding_agent",
|
|
6273
|
+
"Spawn Claude Code CLI to perform a coding task. Use for writing code, debugging, refactoring, or any task that benefits from an AI coding assistant with full filesystem access. Requires the 'claude' CLI to be installed.",
|
|
6274
|
+
{
|
|
6275
|
+
type: "object",
|
|
6276
|
+
properties: {
|
|
6277
|
+
task: {
|
|
6278
|
+
type: "string",
|
|
6279
|
+
description: "The coding task or prompt to send to Claude Code"
|
|
6280
|
+
},
|
|
6281
|
+
workdir: {
|
|
6282
|
+
type: "string",
|
|
6283
|
+
description: "Working directory (relative to workspace). Defaults to workspace root."
|
|
6284
|
+
},
|
|
6285
|
+
timeout: {
|
|
6286
|
+
type: "number",
|
|
6287
|
+
description: "Timeout in seconds. Default: 300"
|
|
6288
|
+
}
|
|
6289
|
+
},
|
|
6290
|
+
required: ["task"]
|
|
6291
|
+
},
|
|
6292
|
+
async (params) => {
|
|
6293
|
+
const task = params.task;
|
|
6294
|
+
const timeoutSeconds = params.timeout || 300;
|
|
6295
|
+
const cwd = params.workdir ? resolve16(workspaceDir, params.workdir) : workspaceDir;
|
|
6296
|
+
try {
|
|
6297
|
+
execSync8("which claude", { stdio: "ignore" });
|
|
6298
|
+
} catch {
|
|
6299
|
+
return "Error: 'claude' CLI not found. Install Claude Code first: https://docs.anthropic.com/en/docs/claude-code";
|
|
6300
|
+
}
|
|
6301
|
+
const escapedTask = task.replace(/'/g, "'\\''");
|
|
6302
|
+
const command = `claude --dangerously-skip-permissions -p '${escapedTask}'`;
|
|
6303
|
+
try {
|
|
6304
|
+
const output = execSync8(command, {
|
|
6305
|
+
cwd,
|
|
6306
|
+
timeout: timeoutSeconds * 1e3,
|
|
6307
|
+
encoding: "utf-8",
|
|
6308
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
6309
|
+
// 10MB
|
|
6310
|
+
shell: "/bin/sh",
|
|
6311
|
+
env: {
|
|
6312
|
+
...process.env,
|
|
6313
|
+
PATH: `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:${process.env.PATH}`
|
|
6314
|
+
}
|
|
6315
|
+
});
|
|
6316
|
+
const trimmed = output.length > MAX_OUTPUT6 ? output.slice(0, MAX_OUTPUT6) + `
|
|
6317
|
+
... (truncated, ${output.length} total chars)` : output;
|
|
6318
|
+
return trimmed || "(no output)";
|
|
6319
|
+
} catch (err) {
|
|
6320
|
+
if (err.killed) {
|
|
6321
|
+
return `Error: Claude Code timed out after ${timeoutSeconds}s`;
|
|
6322
|
+
}
|
|
6323
|
+
const stderr = err.stderr?.toString() || "";
|
|
6324
|
+
const stdout = err.stdout?.toString() || "";
|
|
6325
|
+
const output = (stdout + "\n" + stderr).trim();
|
|
6326
|
+
const code = err.status ?? "unknown";
|
|
6327
|
+
return `Claude Code failed (exit code ${code}):
|
|
6328
|
+
${output || err.message}`;
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
);
|
|
6332
|
+
}
|
|
6333
|
+
|
|
6334
|
+
// packages/runtime/src/tools/register.ts
|
|
6335
|
+
import { resolve as resolve17 } from "path";
|
|
5470
6336
|
import { mkdirSync as mkdirSync12, existsSync as existsSync15 } from "fs";
|
|
5471
6337
|
function registerAllTools(hivemindHome, config) {
|
|
5472
6338
|
const registry = new ToolRegistry();
|
|
5473
6339
|
if (config?.enabled === false) {
|
|
5474
6340
|
return registry;
|
|
5475
6341
|
}
|
|
5476
|
-
const workspaceDir =
|
|
6342
|
+
const workspaceDir = resolve17(hivemindHome, config?.workspace || "workspace");
|
|
5477
6343
|
if (!existsSync15(workspaceDir)) {
|
|
5478
6344
|
mkdirSync12(workspaceDir, { recursive: true });
|
|
5479
6345
|
}
|
|
@@ -5481,7 +6347,7 @@ function registerAllTools(hivemindHome, config) {
|
|
|
5481
6347
|
registerFileTools(registry, workspaceDir);
|
|
5482
6348
|
registerWebTools(registry, { braveApiKey: config?.braveApiKey });
|
|
5483
6349
|
registerMemoryTools(registry, config?.memoryDaemonUrl || "http://localhost:3434");
|
|
5484
|
-
const dataDir =
|
|
6350
|
+
const dataDir = resolve17(hivemindHome, "data");
|
|
5485
6351
|
registerEventTools(registry, dataDir);
|
|
5486
6352
|
if (config?.configPath && !process.env.SPAWN_TASK) {
|
|
5487
6353
|
registerSpawnTools(registry, hivemindHome, dataDir, config.configPath);
|
|
@@ -5494,6 +6360,7 @@ function registerAllTools(hivemindHome, config) {
|
|
|
5494
6360
|
registerWatchTools(registry, workspaceDir, dataDir);
|
|
5495
6361
|
registerMacOSTools(registry, workspaceDir);
|
|
5496
6362
|
registerDataTools(registry, workspaceDir);
|
|
6363
|
+
registerCodingAgentTools(registry, workspaceDir);
|
|
5497
6364
|
return registry;
|
|
5498
6365
|
}
|
|
5499
6366
|
|
|
@@ -5531,9 +6398,9 @@ function registerMessagingTools(registry, sesame) {
|
|
|
5531
6398
|
|
|
5532
6399
|
// packages/runtime/src/tools/skills-tools.ts
|
|
5533
6400
|
import { existsSync as existsSync16, mkdirSync as mkdirSync13, writeFileSync as writeFileSync6, rmSync } from "fs";
|
|
5534
|
-
import { resolve as
|
|
6401
|
+
import { resolve as resolve18 } from "path";
|
|
5535
6402
|
function registerSkillsTools(registry, skillsEngine, workspaceDir) {
|
|
5536
|
-
const skillsDir =
|
|
6403
|
+
const skillsDir = resolve18(workspaceDir, "skills");
|
|
5537
6404
|
registry.register(
|
|
5538
6405
|
"skill_list",
|
|
5539
6406
|
"List all loaded skills with their registered tools and status.",
|
|
@@ -5600,7 +6467,7 @@ ${lines.join("\n\n")}`;
|
|
|
5600
6467
|
const name = params.name;
|
|
5601
6468
|
const description = params.description;
|
|
5602
6469
|
const tools = params.tools;
|
|
5603
|
-
const skillDir =
|
|
6470
|
+
const skillDir = resolve18(skillsDir, name);
|
|
5604
6471
|
if (existsSync16(skillDir)) {
|
|
5605
6472
|
return `Error: Skill directory "${name}" already exists. Use skill_reload to update it.`;
|
|
5606
6473
|
}
|
|
@@ -5614,7 +6481,7 @@ description: "${description}"
|
|
|
5614
6481
|
|
|
5615
6482
|
${description}
|
|
5616
6483
|
`;
|
|
5617
|
-
writeFileSync6(
|
|
6484
|
+
writeFileSync6(resolve18(skillDir, "SKILL.md"), skillMd);
|
|
5618
6485
|
if (tools && tools.length > 0) {
|
|
5619
6486
|
const toolsDef = {
|
|
5620
6487
|
tools: tools.map((t) => ({
|
|
@@ -5624,7 +6491,7 @@ ${description}
|
|
|
5624
6491
|
command: t.command
|
|
5625
6492
|
}))
|
|
5626
6493
|
};
|
|
5627
|
-
writeFileSync6(
|
|
6494
|
+
writeFileSync6(resolve18(skillDir, "tools.json"), JSON.stringify(toolsDef, null, 2) + "\n");
|
|
5628
6495
|
}
|
|
5629
6496
|
try {
|
|
5630
6497
|
await skillsEngine.loadSkill(name);
|
|
@@ -5677,7 +6544,7 @@ Path: ${skillDir}`;
|
|
|
5677
6544
|
},
|
|
5678
6545
|
async (params) => {
|
|
5679
6546
|
const name = params.name;
|
|
5680
|
-
const skillDir =
|
|
6547
|
+
const skillDir = resolve18(skillsDir, name);
|
|
5681
6548
|
if (!existsSync16(skillDir)) {
|
|
5682
6549
|
return `Error: Skill directory "${name}" does not exist.`;
|
|
5683
6550
|
}
|
|
@@ -5698,12 +6565,12 @@ Path: ${skillDir}`;
|
|
|
5698
6565
|
|
|
5699
6566
|
// packages/runtime/src/pipeline.ts
|
|
5700
6567
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3 } from "fs";
|
|
5701
|
-
import { resolve as
|
|
6568
|
+
import { resolve as resolve19, dirname as dirname7 } from "path";
|
|
5702
6569
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
5703
6570
|
var PACKAGE_VERSION = "unknown";
|
|
5704
6571
|
try {
|
|
5705
6572
|
const __dirname2 = dirname7(fileURLToPath3(import.meta.url));
|
|
5706
|
-
const pkg = JSON.parse(readFileSync12(
|
|
6573
|
+
const pkg = JSON.parse(readFileSync12(resolve19(__dirname2, "../package.json"), "utf-8"));
|
|
5707
6574
|
PACKAGE_VERSION = pkg.version ?? "unknown";
|
|
5708
6575
|
} catch {
|
|
5709
6576
|
}
|
|
@@ -5775,11 +6642,11 @@ async function startPipeline(configPath) {
|
|
|
5775
6642
|
console.log("[hivemind] Global context already exists in memory daemon");
|
|
5776
6643
|
}
|
|
5777
6644
|
}
|
|
5778
|
-
const requestLogger = new RequestLogger(
|
|
6645
|
+
const requestLogger = new RequestLogger(resolve19(dirname7(configPath), "data", "dashboard.db"));
|
|
5779
6646
|
startDashboardServer(requestLogger, config.memory);
|
|
5780
6647
|
const agent = new Agent(config);
|
|
5781
6648
|
agent.setRequestLogger(requestLogger);
|
|
5782
|
-
const hivemindHome = process.env.HIVEMIND_HOME ||
|
|
6649
|
+
const hivemindHome = process.env.HIVEMIND_HOME || resolve19(process.env.HOME || "/root", "hivemind");
|
|
5783
6650
|
const toolRegistry = registerAllTools(hivemindHome, {
|
|
5784
6651
|
enabled: true,
|
|
5785
6652
|
workspace: config.agent.workspace || "workspace",
|
|
@@ -5787,7 +6654,7 @@ async function startPipeline(configPath) {
|
|
|
5787
6654
|
memoryDaemonUrl: config.memory.daemon_url,
|
|
5788
6655
|
configPath
|
|
5789
6656
|
});
|
|
5790
|
-
const workspaceDir =
|
|
6657
|
+
const workspaceDir = resolve19(hivemindHome, config.agent.workspace || "workspace");
|
|
5791
6658
|
const skillsEngine = new SkillsEngine(workspaceDir, toolRegistry);
|
|
5792
6659
|
await skillsEngine.loadAll();
|
|
5793
6660
|
registerSkillsTools(toolRegistry, skillsEngine, workspaceDir);
|
|
@@ -5795,7 +6662,7 @@ async function startPipeline(configPath) {
|
|
|
5795
6662
|
process.on("exit", () => skillsEngine.stopWatching());
|
|
5796
6663
|
agent.setToolRegistry(toolRegistry);
|
|
5797
6664
|
console.log(`[hivemind] Context manager initialized (active: ${agent.getActiveContext()})`);
|
|
5798
|
-
const dataDir =
|
|
6665
|
+
const dataDir = resolve19(hivemindHome, "data");
|
|
5799
6666
|
if (config.sesame.api_key) {
|
|
5800
6667
|
await startSesameLoop(config, agent, toolRegistry, dataDir);
|
|
5801
6668
|
} else {
|
|
@@ -5969,8 +6836,8 @@ ${response.content}
|
|
|
5969
6836
|
console.error("Error:", err.message);
|
|
5970
6837
|
}
|
|
5971
6838
|
});
|
|
5972
|
-
return new Promise((
|
|
5973
|
-
rl.on("close",
|
|
6839
|
+
return new Promise((resolve20) => {
|
|
6840
|
+
rl.on("close", resolve20);
|
|
5974
6841
|
});
|
|
5975
6842
|
}
|
|
5976
6843
|
async function runSpawnTask(config, configPath) {
|
|
@@ -5981,7 +6848,7 @@ async function runSpawnTask(config, configPath) {
|
|
|
5981
6848
|
const spawnDir = process.env.SPAWN_DIR;
|
|
5982
6849
|
console.log(`[spawn] Sub-agent starting (id: ${spawnId}, context: ${context})`);
|
|
5983
6850
|
const agent = new Agent(config, context);
|
|
5984
|
-
const hivemindHome = process.env.HIVEMIND_HOME ||
|
|
6851
|
+
const hivemindHome = process.env.HIVEMIND_HOME || resolve19(process.env.HOME || "/root", "hivemind");
|
|
5985
6852
|
const toolRegistry = registerAllTools(hivemindHome, {
|
|
5986
6853
|
enabled: true,
|
|
5987
6854
|
workspace: config.agent.workspace || "workspace",
|
|
@@ -5994,7 +6861,7 @@ async function runSpawnTask(config, configPath) {
|
|
|
5994
6861
|
const result = response.content;
|
|
5995
6862
|
console.log(`[spawn] Task completed (context: ${response.context})`);
|
|
5996
6863
|
if (spawnDir) {
|
|
5997
|
-
writeFileSync7(
|
|
6864
|
+
writeFileSync7(resolve19(spawnDir, "result.txt"), result);
|
|
5998
6865
|
}
|
|
5999
6866
|
if (channelId && config.sesame.api_key) {
|
|
6000
6867
|
try {
|
|
@@ -6011,7 +6878,7 @@ async function runSpawnTask(config, configPath) {
|
|
|
6011
6878
|
const errorMsg = `[SPAWN ERROR] ${err.message}`;
|
|
6012
6879
|
console.error(`[spawn] ${errorMsg}`);
|
|
6013
6880
|
if (spawnDir) {
|
|
6014
|
-
writeFileSync7(
|
|
6881
|
+
writeFileSync7(resolve19(spawnDir, "result.txt"), errorMsg);
|
|
6015
6882
|
}
|
|
6016
6883
|
process.exitCode = 1;
|
|
6017
6884
|
}
|
|
@@ -6042,20 +6909,20 @@ var WorkerServer = class {
|
|
|
6042
6909
|
}
|
|
6043
6910
|
/** Start listening. */
|
|
6044
6911
|
async start() {
|
|
6045
|
-
return new Promise((
|
|
6912
|
+
return new Promise((resolve20, reject) => {
|
|
6046
6913
|
this.server = createServer4((req, res) => this.handleRequest(req, res));
|
|
6047
6914
|
this.server.on("error", reject);
|
|
6048
|
-
this.server.listen(this.port, () =>
|
|
6915
|
+
this.server.listen(this.port, () => resolve20());
|
|
6049
6916
|
});
|
|
6050
6917
|
}
|
|
6051
6918
|
/** Stop the server. */
|
|
6052
6919
|
async stop() {
|
|
6053
|
-
return new Promise((
|
|
6920
|
+
return new Promise((resolve20) => {
|
|
6054
6921
|
if (!this.server) {
|
|
6055
|
-
|
|
6922
|
+
resolve20();
|
|
6056
6923
|
return;
|
|
6057
6924
|
}
|
|
6058
|
-
this.server.close(() =>
|
|
6925
|
+
this.server.close(() => resolve20());
|
|
6059
6926
|
});
|
|
6060
6927
|
}
|
|
6061
6928
|
getPort() {
|
|
@@ -6178,10 +7045,10 @@ var WorkerServer = class {
|
|
|
6178
7045
|
}
|
|
6179
7046
|
};
|
|
6180
7047
|
function readBody(req) {
|
|
6181
|
-
return new Promise((
|
|
7048
|
+
return new Promise((resolve20, reject) => {
|
|
6182
7049
|
const chunks = [];
|
|
6183
7050
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
6184
|
-
req.on("end", () =>
|
|
7051
|
+
req.on("end", () => resolve20(Buffer.concat(chunks).toString("utf-8")));
|
|
6185
7052
|
req.on("error", reject);
|
|
6186
7053
|
});
|
|
6187
7054
|
}
|
|
@@ -6448,6 +7315,7 @@ async function startWorker(config) {
|
|
|
6448
7315
|
}
|
|
6449
7316
|
|
|
6450
7317
|
export {
|
|
7318
|
+
getClaudeCodeOAuthToken,
|
|
6451
7319
|
LLMClient,
|
|
6452
7320
|
MemoryClient,
|
|
6453
7321
|
ContextManager,
|
|
@@ -6463,7 +7331,8 @@ export {
|
|
|
6463
7331
|
EventsWatcher,
|
|
6464
7332
|
defaultSentinelConfig,
|
|
6465
7333
|
loadConfig,
|
|
6466
|
-
|
|
7334
|
+
SesameClient,
|
|
7335
|
+
SesameClient2,
|
|
6467
7336
|
HEALTH_PATH,
|
|
6468
7337
|
SkillsEngine,
|
|
6469
7338
|
startPipeline,
|
|
@@ -6515,4 +7384,4 @@ smol-toml/dist/index.js:
|
|
|
6515
7384
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
6516
7385
|
*)
|
|
6517
7386
|
*/
|
|
6518
|
-
//# sourceMappingURL=chunk-
|
|
7387
|
+
//# sourceMappingURL=chunk-S4QRR3ZJ.js.map
|