@sesamespace/hivemind 0.5.16 → 0.6.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.
@@ -16,28 +16,46 @@ var LLMClient = class {
16
16
  this.temperature = config.temperature;
17
17
  this.apiKey = config.api_key ?? "";
18
18
  }
19
+ /**
20
+ * Simple chat completion (no tools). Backwards compatible.
21
+ */
19
22
  async chat(messages) {
23
+ return this.chatWithTools(messages);
24
+ }
25
+ /**
26
+ * Chat completion with optional tool definitions.
27
+ * Returns tool_calls if the model wants to use tools.
28
+ */
29
+ async chatWithTools(messages, tools) {
30
+ const body = {
31
+ model: this.model,
32
+ messages,
33
+ max_tokens: this.maxTokens,
34
+ temperature: this.temperature
35
+ };
36
+ if (tools && tools.length > 0) {
37
+ body.tools = tools;
38
+ body.tool_choice = "auto";
39
+ }
20
40
  const resp = await fetch(`${this.baseUrl}/chat/completions`, {
21
41
  method: "POST",
22
42
  headers: {
23
43
  "Content-Type": "application/json",
24
44
  ...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
25
45
  },
26
- body: JSON.stringify({
27
- model: this.model,
28
- messages,
29
- max_tokens: this.maxTokens,
30
- temperature: this.temperature
31
- })
46
+ body: JSON.stringify(body)
32
47
  });
33
48
  if (!resp.ok) {
34
- const body = await resp.text();
35
- throw new Error(`LLM request failed: ${resp.status} ${body}`);
49
+ const text = await resp.text();
50
+ throw new Error(`LLM request failed: ${resp.status} ${text}`);
36
51
  }
37
52
  const data = await resp.json();
53
+ const choice = data.choices[0];
38
54
  return {
39
- content: data.choices[0].message.content,
55
+ content: choice.message.content ?? "",
40
56
  model: data.model,
57
+ tool_calls: choice.message.tool_calls,
58
+ finish_reason: choice.finish_reason,
41
59
  usage: data.usage
42
60
  };
43
61
  }
@@ -618,11 +636,13 @@ var Agent = class {
618
636
  llm;
619
637
  memory;
620
638
  contextManager;
639
+ toolRegistry = null;
621
640
  // Per-context conversation histories
622
641
  conversationHistories = /* @__PURE__ */ new Map();
623
642
  messageCount = 0;
624
643
  PROMOTION_INTERVAL = 10;
625
644
  // Run promotion every N messages
645
+ MAX_TOOL_ITERATIONS = 25;
626
646
  requestLogger = null;
627
647
  constructor(config, contextName = "global") {
628
648
  this.config = config;
@@ -633,6 +653,13 @@ var Agent = class {
633
653
  this.contextManager.switchContext(contextName);
634
654
  }
635
655
  }
656
+ setToolRegistry(registry) {
657
+ this.toolRegistry = registry;
658
+ const toolCount = registry.getDefinitions().length;
659
+ if (toolCount > 0) {
660
+ console.log(`[hivemind] Tool use enabled: ${toolCount} tools registered`);
661
+ }
662
+ }
636
663
  setRequestLogger(logger) {
637
664
  this.requestLogger = logger;
638
665
  }
@@ -668,7 +695,31 @@ var Agent = class {
668
695
  const systemPromptResult = buildSystemPrompt(this.config.agent, relevantEpisodes, contextName, l3Knowledge);
669
696
  const messages = buildMessages(systemPromptResult.text, conversationHistory, userMessage);
670
697
  const llmStart = Date.now();
671
- const response = await this.llm.chat(messages);
698
+ const toolDefs = this.toolRegistry?.getDefinitions() ?? [];
699
+ let response = await this.llm.chatWithTools(messages, toolDefs.length > 0 ? toolDefs : void 0);
700
+ let iterations = 0;
701
+ while (response.tool_calls && response.tool_calls.length > 0 && iterations < this.MAX_TOOL_ITERATIONS) {
702
+ iterations++;
703
+ messages.push({
704
+ role: "assistant",
705
+ content: response.content,
706
+ tool_calls: response.tool_calls
707
+ });
708
+ for (const call of response.tool_calls) {
709
+ console.log(`[tools] ${call.function.name}(${call.function.arguments.slice(0, 100)})`);
710
+ const result = await this.toolRegistry.executeCall(call);
711
+ messages.push({
712
+ role: "tool",
713
+ content: result.content,
714
+ tool_call_id: result.tool_call_id
715
+ });
716
+ console.log(`[tools] ${call.function.name} \u2192 ${result.content.slice(0, 100)}${result.content.length > 100 ? "..." : ""}`);
717
+ }
718
+ response = await this.llm.chatWithTools(messages, toolDefs);
719
+ }
720
+ if (iterations > 0) {
721
+ console.log(`[tools] Completed after ${iterations} tool iteration(s)`);
722
+ }
672
723
  const latencyMs = Date.now() - llmStart;
673
724
  if (this.requestLogger) {
674
725
  try {
@@ -1896,7 +1947,12 @@ var SesameClient2 = class {
1896
1947
  this.sdk.on("message", (event) => {
1897
1948
  const msg = event.data || event.message || event;
1898
1949
  const senderId = msg.senderId || msg.sender?.id;
1899
- if (senderId === this.agentId) return;
1950
+ if (senderId === this.agentId) {
1951
+ const content = msg.content?.trim() || "";
1952
+ const isHmCommand = /^hm[:\s]/i.test(content);
1953
+ const isTextCommand = /^(?:list contexts|switch to|create context|search all:|task )/i.test(content);
1954
+ if (!isHmCommand && !isTextCommand) return;
1955
+ }
1900
1956
  if (!this.messageHandler || !msg.content) return;
1901
1957
  const channelInfo = this.channels.get(msg.channelId);
1902
1958
  this.messageHandler({
@@ -2242,14 +2298,398 @@ function startDashboardServer(requestLogger, memoryConfig) {
2242
2298
  });
2243
2299
  }
2244
2300
 
2301
+ // packages/runtime/src/tool-registry.ts
2302
+ var ToolRegistry = class {
2303
+ tools = /* @__PURE__ */ new Map();
2304
+ register(name, description, parameters, executor) {
2305
+ this.tools.set(name, {
2306
+ definition: {
2307
+ type: "function",
2308
+ function: { name, description, parameters }
2309
+ },
2310
+ executor
2311
+ });
2312
+ }
2313
+ getDefinitions() {
2314
+ return Array.from(this.tools.values()).map((t) => t.definition);
2315
+ }
2316
+ has(name) {
2317
+ return this.tools.has(name);
2318
+ }
2319
+ async execute(name, params) {
2320
+ const tool = this.tools.get(name);
2321
+ if (!tool) {
2322
+ return `Error: Unknown tool "${name}"`;
2323
+ }
2324
+ try {
2325
+ return await tool.executor(params);
2326
+ } catch (err) {
2327
+ return `Error executing ${name}: ${err.message}`;
2328
+ }
2329
+ }
2330
+ async executeCall(call) {
2331
+ let params = {};
2332
+ try {
2333
+ params = JSON.parse(call.function.arguments);
2334
+ } catch {
2335
+ return {
2336
+ tool_call_id: call.id,
2337
+ role: "tool",
2338
+ content: `Error: Invalid JSON arguments for ${call.function.name}`
2339
+ };
2340
+ }
2341
+ const result = await this.execute(call.function.name, params);
2342
+ return {
2343
+ tool_call_id: call.id,
2344
+ role: "tool",
2345
+ content: result
2346
+ };
2347
+ }
2348
+ };
2349
+
2350
+ // packages/runtime/src/tools/shell.ts
2351
+ import { execSync } from "child_process";
2352
+ import { resolve as resolve5 } from "path";
2353
+ var MAX_OUTPUT = 5e4;
2354
+ function registerShellTool(registry, workspaceDir) {
2355
+ registry.register(
2356
+ "shell",
2357
+ "Execute a shell command and return stdout/stderr. Use for running programs, checking status, installing packages, git operations, etc.",
2358
+ {
2359
+ type: "object",
2360
+ properties: {
2361
+ command: {
2362
+ type: "string",
2363
+ description: "The shell command to execute"
2364
+ },
2365
+ workdir: {
2366
+ type: "string",
2367
+ description: "Working directory (relative to workspace). Defaults to workspace root."
2368
+ },
2369
+ timeout: {
2370
+ type: "number",
2371
+ description: "Timeout in seconds. Default: 30"
2372
+ }
2373
+ },
2374
+ required: ["command"]
2375
+ },
2376
+ async (params) => {
2377
+ const command = params.command;
2378
+ const timeout = (params.timeout || 30) * 1e3;
2379
+ const cwd = params.workdir ? resolve5(workspaceDir, params.workdir) : workspaceDir;
2380
+ try {
2381
+ const output = execSync(command, {
2382
+ cwd,
2383
+ timeout,
2384
+ encoding: "utf-8",
2385
+ maxBuffer: 10 * 1024 * 1024,
2386
+ // 10MB
2387
+ shell: "/bin/sh",
2388
+ env: { ...process.env, PATH: `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:${process.env.PATH}` }
2389
+ });
2390
+ const trimmed = output.length > MAX_OUTPUT ? output.slice(0, MAX_OUTPUT) + `
2391
+ ... (truncated, ${output.length} total chars)` : output;
2392
+ return trimmed || "(no output)";
2393
+ } catch (err) {
2394
+ const stderr = err.stderr?.toString() || "";
2395
+ const stdout = err.stdout?.toString() || "";
2396
+ const output = (stdout + "\n" + stderr).trim();
2397
+ const code = err.status ?? "unknown";
2398
+ return `Command failed (exit code ${code}):
2399
+ ${output || err.message}`;
2400
+ }
2401
+ }
2402
+ );
2403
+ }
2404
+
2405
+ // packages/runtime/src/tools/files.ts
2406
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
2407
+ import { resolve as resolve6, dirname as dirname5 } from "path";
2408
+ var MAX_READ = 1e5;
2409
+ function registerFileTools(registry, workspaceDir) {
2410
+ registry.register(
2411
+ "read_file",
2412
+ "Read the contents of a file. Returns the text content. Use offset/limit for large files.",
2413
+ {
2414
+ type: "object",
2415
+ properties: {
2416
+ path: {
2417
+ type: "string",
2418
+ description: "File path (relative to workspace or absolute)"
2419
+ },
2420
+ offset: {
2421
+ type: "number",
2422
+ description: "Line number to start reading from (1-indexed)"
2423
+ },
2424
+ limit: {
2425
+ type: "number",
2426
+ description: "Maximum number of lines to read"
2427
+ }
2428
+ },
2429
+ required: ["path"]
2430
+ },
2431
+ async (params) => {
2432
+ const filePath = resolvePath(workspaceDir, params.path);
2433
+ if (!existsSync4(filePath)) {
2434
+ return `Error: File not found: ${filePath}`;
2435
+ }
2436
+ try {
2437
+ let content = readFileSync6(filePath, "utf-8");
2438
+ if (params.offset || params.limit) {
2439
+ const lines = content.split("\n");
2440
+ const start = (params.offset || 1) - 1;
2441
+ const end = params.limit ? start + params.limit : lines.length;
2442
+ content = lines.slice(start, end).join("\n");
2443
+ }
2444
+ if (content.length > MAX_READ) {
2445
+ content = content.slice(0, MAX_READ) + `
2446
+ ... (truncated, ${content.length} total chars)`;
2447
+ }
2448
+ return content || "(empty file)";
2449
+ } catch (err) {
2450
+ return `Error reading file: ${err.message}`;
2451
+ }
2452
+ }
2453
+ );
2454
+ registry.register(
2455
+ "write_file",
2456
+ "Write content to a file. Creates the file and parent directories if they don't exist. Overwrites existing content.",
2457
+ {
2458
+ type: "object",
2459
+ properties: {
2460
+ path: {
2461
+ type: "string",
2462
+ description: "File path (relative to workspace or absolute)"
2463
+ },
2464
+ content: {
2465
+ type: "string",
2466
+ description: "Content to write to the file"
2467
+ }
2468
+ },
2469
+ required: ["path", "content"]
2470
+ },
2471
+ async (params) => {
2472
+ const filePath = resolvePath(workspaceDir, params.path);
2473
+ try {
2474
+ const dir = dirname5(filePath);
2475
+ if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
2476
+ writeFileSync2(filePath, params.content);
2477
+ return `Written ${params.content.length} bytes to ${filePath}`;
2478
+ } catch (err) {
2479
+ return `Error writing file: ${err.message}`;
2480
+ }
2481
+ }
2482
+ );
2483
+ registry.register(
2484
+ "edit_file",
2485
+ "Edit a file by finding and replacing exact text. The old text must match exactly (including whitespace).",
2486
+ {
2487
+ type: "object",
2488
+ properties: {
2489
+ path: {
2490
+ type: "string",
2491
+ description: "File path (relative to workspace or absolute)"
2492
+ },
2493
+ old_text: {
2494
+ type: "string",
2495
+ description: "Exact text to find and replace"
2496
+ },
2497
+ new_text: {
2498
+ type: "string",
2499
+ description: "New text to replace with"
2500
+ }
2501
+ },
2502
+ required: ["path", "old_text", "new_text"]
2503
+ },
2504
+ async (params) => {
2505
+ const filePath = resolvePath(workspaceDir, params.path);
2506
+ if (!existsSync4(filePath)) {
2507
+ return `Error: File not found: ${filePath}`;
2508
+ }
2509
+ try {
2510
+ const content = readFileSync6(filePath, "utf-8");
2511
+ const oldText = params.old_text;
2512
+ const newText = params.new_text;
2513
+ if (!content.includes(oldText)) {
2514
+ return `Error: Could not find the exact text to replace in ${filePath}`;
2515
+ }
2516
+ const updated = content.replace(oldText, newText);
2517
+ writeFileSync2(filePath, updated);
2518
+ return `Edited ${filePath}: replaced ${oldText.length} chars with ${newText.length} chars`;
2519
+ } catch (err) {
2520
+ return `Error editing file: ${err.message}`;
2521
+ }
2522
+ }
2523
+ );
2524
+ registry.register(
2525
+ "list_files",
2526
+ "List files and directories in a path.",
2527
+ {
2528
+ type: "object",
2529
+ properties: {
2530
+ path: {
2531
+ type: "string",
2532
+ description: "Directory path (relative to workspace or absolute). Defaults to workspace root."
2533
+ }
2534
+ },
2535
+ required: []
2536
+ },
2537
+ async (params) => {
2538
+ const { readdirSync: readdirSync2, statSync } = await import("fs");
2539
+ const dirPath = params.path ? resolvePath(workspaceDir, params.path) : workspaceDir;
2540
+ if (!existsSync4(dirPath)) {
2541
+ return `Error: Directory not found: ${dirPath}`;
2542
+ }
2543
+ try {
2544
+ const entries = readdirSync2(dirPath);
2545
+ const results = [];
2546
+ for (const entry of entries) {
2547
+ if (entry.startsWith(".")) continue;
2548
+ try {
2549
+ const stat = statSync(resolve6(dirPath, entry));
2550
+ results.push(stat.isDirectory() ? `${entry}/` : entry);
2551
+ } catch {
2552
+ results.push(entry);
2553
+ }
2554
+ }
2555
+ return results.join("\n") || "(empty directory)";
2556
+ } catch (err) {
2557
+ return `Error listing directory: ${err.message}`;
2558
+ }
2559
+ }
2560
+ );
2561
+ }
2562
+ function resolvePath(workspace, path) {
2563
+ if (path.startsWith("/") || path.startsWith("~")) {
2564
+ return path.replace(/^~/, process.env.HOME || "/root");
2565
+ }
2566
+ return resolve6(workspace, path);
2567
+ }
2568
+
2569
+ // packages/runtime/src/tools/web.ts
2570
+ function registerWebTools(registry, config) {
2571
+ registry.register(
2572
+ "web_search",
2573
+ "Search the web using Brave Search API. Returns titles, URLs, and snippets.",
2574
+ {
2575
+ type: "object",
2576
+ properties: {
2577
+ query: {
2578
+ type: "string",
2579
+ description: "Search query string"
2580
+ },
2581
+ count: {
2582
+ type: "number",
2583
+ description: "Number of results (1-10, default 5)"
2584
+ }
2585
+ },
2586
+ required: ["query"]
2587
+ },
2588
+ async (params) => {
2589
+ const apiKey = config?.braveApiKey || process.env.BRAVE_API_KEY;
2590
+ if (!apiKey) {
2591
+ return "Error: No Brave Search API key configured. Set BRAVE_API_KEY env var.";
2592
+ }
2593
+ const query = params.query;
2594
+ const count = Math.min(Math.max(params.count || 5, 1), 10);
2595
+ try {
2596
+ const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`;
2597
+ const resp = await fetch(url, {
2598
+ headers: { "X-Subscription-Token": apiKey, Accept: "application/json" }
2599
+ });
2600
+ if (!resp.ok) {
2601
+ return `Search failed: ${resp.status} ${await resp.text()}`;
2602
+ }
2603
+ const data = await resp.json();
2604
+ const results = data.web?.results || [];
2605
+ if (results.length === 0) return "No results found.";
2606
+ return results.map((r, i) => `${i + 1}. **${r.title}**
2607
+ ${r.url}
2608
+ ${r.description}`).join("\n\n");
2609
+ } catch (err) {
2610
+ return `Search error: ${err.message}`;
2611
+ }
2612
+ }
2613
+ );
2614
+ registry.register(
2615
+ "web_fetch",
2616
+ "Fetch a URL and extract readable content as markdown/text. Good for reading articles, docs, and web pages.",
2617
+ {
2618
+ type: "object",
2619
+ properties: {
2620
+ url: {
2621
+ type: "string",
2622
+ description: "HTTP or HTTPS URL to fetch"
2623
+ },
2624
+ max_chars: {
2625
+ type: "number",
2626
+ description: "Maximum characters to return (default 20000)"
2627
+ }
2628
+ },
2629
+ required: ["url"]
2630
+ },
2631
+ async (params) => {
2632
+ const url = params.url;
2633
+ const maxChars = params.max_chars || 2e4;
2634
+ try {
2635
+ const resp = await fetch(url, {
2636
+ headers: {
2637
+ "User-Agent": "Hivemind/1.0 (Agent Web Fetcher)",
2638
+ Accept: "text/html,application/xhtml+xml,text/plain,application/json"
2639
+ },
2640
+ redirect: "follow"
2641
+ });
2642
+ if (!resp.ok) {
2643
+ return `Fetch failed: ${resp.status} ${resp.statusText}`;
2644
+ }
2645
+ let text = await resp.text();
2646
+ const contentType = resp.headers.get("content-type") || "";
2647
+ if (contentType.includes("html")) {
2648
+ text = text.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "");
2649
+ text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
2650
+ text = text.replace(/<[^>]+>/g, " ");
2651
+ text = text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">");
2652
+ text = text.replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ");
2653
+ text = text.replace(/\s+/g, " ").trim();
2654
+ }
2655
+ if (text.length > maxChars) {
2656
+ text = text.slice(0, maxChars) + `
2657
+ ... (truncated, ${text.length} total chars)`;
2658
+ }
2659
+ return text || "(empty response)";
2660
+ } catch (err) {
2661
+ return `Fetch error: ${err.message}`;
2662
+ }
2663
+ }
2664
+ );
2665
+ }
2666
+
2667
+ // packages/runtime/src/tools/register.ts
2668
+ import { resolve as resolve7 } from "path";
2669
+ import { mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
2670
+ function registerAllTools(hivemindHome, config) {
2671
+ const registry = new ToolRegistry();
2672
+ if (config?.enabled === false) {
2673
+ return registry;
2674
+ }
2675
+ const workspaceDir = resolve7(hivemindHome, config?.workspace || "workspace");
2676
+ if (!existsSync5(workspaceDir)) {
2677
+ mkdirSync3(workspaceDir, { recursive: true });
2678
+ }
2679
+ registerShellTool(registry, workspaceDir);
2680
+ registerFileTools(registry, workspaceDir);
2681
+ registerWebTools(registry, { braveApiKey: config?.braveApiKey });
2682
+ return registry;
2683
+ }
2684
+
2245
2685
  // packages/runtime/src/pipeline.ts
2246
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, unlinkSync } from "fs";
2247
- import { resolve as resolve5, dirname as dirname5 } from "path";
2686
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, unlinkSync } from "fs";
2687
+ import { resolve as resolve8, dirname as dirname6 } from "path";
2248
2688
  import { fileURLToPath as fileURLToPath3 } from "url";
2249
2689
  var PACKAGE_VERSION = "unknown";
2250
2690
  try {
2251
- const __dirname2 = dirname5(fileURLToPath3(import.meta.url));
2252
- const pkg = JSON.parse(readFileSync6(resolve5(__dirname2, "../package.json"), "utf-8"));
2691
+ const __dirname2 = dirname6(fileURLToPath3(import.meta.url));
2692
+ const pkg = JSON.parse(readFileSync7(resolve8(__dirname2, "../package.json"), "utf-8"));
2253
2693
  PACKAGE_VERSION = pkg.version ?? "unknown";
2254
2694
  } catch {
2255
2695
  }
@@ -2280,7 +2720,7 @@ function startHealthServer(port) {
2280
2720
  return server;
2281
2721
  }
2282
2722
  function writePidFile(path) {
2283
- writeFileSync2(path, String(process.pid));
2723
+ writeFileSync3(path, String(process.pid));
2284
2724
  console.log(`[hivemind] PID file written: ${path}`);
2285
2725
  }
2286
2726
  function cleanupPidFile(path) {
@@ -2311,10 +2751,17 @@ async function startPipeline(configPath) {
2311
2751
  memoryConnected = true;
2312
2752
  console.log("[hivemind] Memory daemon connected");
2313
2753
  }
2314
- const requestLogger = new RequestLogger(resolve5(dirname5(configPath), "data", "dashboard.db"));
2754
+ const requestLogger = new RequestLogger(resolve8(dirname6(configPath), "data", "dashboard.db"));
2315
2755
  startDashboardServer(requestLogger, config.memory);
2316
2756
  const agent = new Agent(config);
2317
2757
  agent.setRequestLogger(requestLogger);
2758
+ const hivemindHome = process.env.HIVEMIND_HOME || resolve8(process.env.HOME || "/root", "hivemind");
2759
+ const toolRegistry = registerAllTools(hivemindHome, {
2760
+ enabled: true,
2761
+ workspace: config.agent.workspace || "workspace",
2762
+ braveApiKey: process.env.BRAVE_API_KEY
2763
+ });
2764
+ agent.setToolRegistry(toolRegistry);
2318
2765
  console.log(`[hivemind] Context manager initialized (active: ${agent.getActiveContext()})`);
2319
2766
  if (config.sesame.api_key) {
2320
2767
  await startSesameLoop(config, agent);
@@ -2462,8 +2909,8 @@ ${response.content}
2462
2909
  console.error("Error:", err.message);
2463
2910
  }
2464
2911
  });
2465
- return new Promise((resolve6) => {
2466
- rl.on("close", resolve6);
2912
+ return new Promise((resolve9) => {
2913
+ rl.on("close", resolve9);
2467
2914
  });
2468
2915
  }
2469
2916
 
@@ -2492,20 +2939,20 @@ var WorkerServer = class {
2492
2939
  }
2493
2940
  /** Start listening. */
2494
2941
  async start() {
2495
- return new Promise((resolve6, reject) => {
2942
+ return new Promise((resolve9, reject) => {
2496
2943
  this.server = createServer3((req, res) => this.handleRequest(req, res));
2497
2944
  this.server.on("error", reject);
2498
- this.server.listen(this.port, () => resolve6());
2945
+ this.server.listen(this.port, () => resolve9());
2499
2946
  });
2500
2947
  }
2501
2948
  /** Stop the server. */
2502
2949
  async stop() {
2503
- return new Promise((resolve6) => {
2950
+ return new Promise((resolve9) => {
2504
2951
  if (!this.server) {
2505
- resolve6();
2952
+ resolve9();
2506
2953
  return;
2507
2954
  }
2508
- this.server.close(() => resolve6());
2955
+ this.server.close(() => resolve9());
2509
2956
  });
2510
2957
  }
2511
2958
  getPort() {
@@ -2628,10 +3075,10 @@ var WorkerServer = class {
2628
3075
  }
2629
3076
  };
2630
3077
  function readBody(req) {
2631
- return new Promise((resolve6, reject) => {
3078
+ return new Promise((resolve9, reject) => {
2632
3079
  const chunks = [];
2633
3080
  req.on("data", (chunk) => chunks.push(chunk));
2634
- req.on("end", () => resolve6(Buffer.concat(chunks).toString("utf-8")));
3081
+ req.on("end", () => resolve9(Buffer.concat(chunks).toString("utf-8")));
2635
3082
  req.on("error", reject);
2636
3083
  });
2637
3084
  }
@@ -2958,4 +3405,4 @@ smol-toml/dist/index.js:
2958
3405
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2959
3406
  *)
2960
3407
  */
2961
- //# sourceMappingURL=chunk-BQCSFDSS.js.map
3408
+ //# sourceMappingURL=chunk-LQ7CYHSQ.js.map