0agent 1.0.82 → 1.0.84

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/bin/0agent.js CHANGED
@@ -307,14 +307,75 @@ async function runInit() {
307
307
  ], 0);
308
308
  const seedName = seedIdx === 0 ? 'software-engineering' : null;
309
309
 
310
+ // ── Step 7: Chat channels ─────────────────────────────────────────────────
311
+ console.log('\n \x1b[1mChat channels\x1b[0m');
312
+ console.log(' \x1b[2mConnect messaging apps so you can chat with your agent from anywhere.\x1b[0m');
313
+ console.log(' \x1b[2mYou can add more later in ~/.0agent/config.yaml\x1b[0m\n');
314
+
315
+ let tgToken = '', slackBotToken = '', slackAppToken = '', slackSecret = '';
316
+ let waProvider = '', waAccountSid = '', waAuthToken = '', waFromNumber = '';
317
+ const channelChoices = [
318
+ 'Telegram bot',
319
+ 'Slack bot',
320
+ 'WhatsApp (via Twilio)',
321
+ 'Skip — set up later',
322
+ ];
323
+ const channelIdx = await arrowSelect('Connect a chat channel?', channelChoices, 3);
324
+
325
+ if (channelIdx === 0) {
326
+ // Telegram
327
+ console.log('\n \x1b[2m1. Open @BotFather on Telegram\x1b[0m');
328
+ console.log(' \x1b[2m2. Send /newbot and follow the prompts\x1b[0m');
329
+ console.log(' \x1b[2m3. Copy the token below\x1b[0m\n');
330
+ tgToken = await arrowPassword('Telegram bot token');
331
+ tgToken = tgToken.trim();
332
+ if (tgToken) {
333
+ console.log(' \x1b[32m✓\x1b[0m Telegram connected. Message your bot to chat with 0agent.');
334
+ }
335
+ } else if (channelIdx === 1) {
336
+ // Slack
337
+ console.log('\n \x1b[2m1. Create a Slack app at api.slack.com/apps\x1b[0m');
338
+ console.log(' \x1b[2m2. Enable Socket Mode + Event Subscriptions\x1b[0m');
339
+ console.log(' \x1b[2m3. Add bot scopes: chat:write, app_mentions:read, im:history\x1b[0m\n');
340
+ slackBotToken = (await arrowPassword('Slack bot token (xoxb-...)')).trim();
341
+ slackAppToken = (await arrowPassword('Slack app token (xapp-...)')).trim();
342
+ slackSecret = (await arrowPassword('Slack signing secret')).trim();
343
+ if (slackBotToken && slackAppToken) {
344
+ console.log(' \x1b[32m✓\x1b[0m Slack connected. @mention your bot or DM it.');
345
+ }
346
+ } else if (channelIdx === 2) {
347
+ // WhatsApp via Twilio
348
+ console.log('\n \x1b[2m1. Sign up at twilio.com\x1b[0m');
349
+ console.log(' \x1b[2m2. Enable WhatsApp sandbox or a production number\x1b[0m\n');
350
+ waProvider = 'twilio';
351
+ waAccountSid = (await arrowInput('Twilio Account SID')).trim();
352
+ waAuthToken = (await arrowPassword('Twilio Auth Token')).trim();
353
+ waFromNumber = (await arrowInput('WhatsApp from number (whatsapp:+1...)')).trim();
354
+ if (waAccountSid && waAuthToken) {
355
+ console.log(' \x1b[32m✓\x1b[0m WhatsApp connected via Twilio.');
356
+ }
357
+ }
358
+
359
+ // Build surfaces config YAML section
360
+ let surfacesYaml = '';
361
+ if (tgToken) {
362
+ surfacesYaml += `\nsurfaces:\n telegram:\n token: "${tgToken}"`;
363
+ } else if (slackBotToken && slackAppToken) {
364
+ surfacesYaml += `\nsurfaces:\n slack:\n bot_token: "${slackBotToken}"\n app_token: "${slackAppToken}"\n signing_secret: "${slackSecret}"`;
365
+ } else if (waAccountSid && waAuthToken) {
366
+ surfacesYaml += `\nsurfaces:\n whatsapp:\n provider: "twilio"\n account_sid: "${waAccountSid}"\n auth_token: "${waAuthToken}"\n from_number: "${waFromNumber}"`;
367
+ }
368
+
310
369
  // ── Summary ───────────────────────────────────────────────────────────────
370
+ const channelLabel = tgToken ? 'Telegram' : (slackBotToken ? 'Slack' : (waAccountSid ? 'WhatsApp' : 'none'));
311
371
  console.log('\n \x1b[1mReady to launch\x1b[0m\n');
312
372
  console.log(` LLM: \x1b[36m${providerKey}/${model}\x1b[0m`);
313
373
  console.log(` API Key: ${apiKey ? '\x1b[32m✓ set\x1b[0m (' + apiKey.slice(0, 8) + '••••)' : '\x1b[33mnot set\x1b[0m'}`);
314
374
  console.log(` Memory: ${ghToken ? `\x1b[32mgithub.com/${ghOwner}/0agent-memory\x1b[0m` : '\x1b[2mlocal only\x1b[0m'}`);
315
375
  console.log(` Workspace: \x1b[36m${workspacePath}\x1b[0m`);
316
376
  console.log(` Sandbox: \x1b[36m${sandboxChoice}\x1b[0m`);
317
- console.log(` Seed: \x1b[36m${seedName ?? 'scratch'}\x1b[0m\n`);
377
+ console.log(` Seed: \x1b[36m${seedName ?? 'scratch'}\x1b[0m`);
378
+ console.log(` Channel: \x1b[36m${channelLabel}\x1b[0m\n`);
318
379
 
319
380
  // Write config
320
381
  const dbPath = resolve(AGENT_DIR, 'graph.db');
@@ -354,6 +415,7 @@ graph:
354
415
  object_store_path: "${objPath}"
355
416
  ${seedName ? `\nseed: "${seedName}"` : ''}
356
417
  ${ghToken && ghOwner ? `\ngithub_memory:\n enabled: true\n token: "${ghToken}"\n owner: "${ghOwner}"\n repo: "${ghRepo}"` : ''}
418
+ ${surfacesYaml}
357
419
  `;
358
420
 
359
421
  writeFileSync(CONFIG_PATH, config, 'utf8');
package/dist/daemon.mjs CHANGED
@@ -2135,6 +2135,8 @@ var init_LLMExecutor = __esm({
2135
2135
  currentToolId = block.id;
2136
2136
  toolInputBuffers[currentToolId] = "";
2137
2137
  toolCalls.push({ id: currentToolId, name: block.name, input: {} });
2138
+ } else {
2139
+ currentToolId = "";
2138
2140
  }
2139
2141
  } else if (type === "content_block_delta") {
2140
2142
  const delta = evt.delta;
@@ -2142,21 +2144,26 @@ var init_LLMExecutor = __esm({
2142
2144
  const token = delta.text ?? "";
2143
2145
  textContent += token;
2144
2146
  if (onToken && token) onToken(token);
2145
- } else if (delta?.type === "input_json_delta") {
2147
+ } else if (delta?.type === "input_json_delta" && currentToolId) {
2146
2148
  toolInputBuffers[currentToolId] = (toolInputBuffers[currentToolId] ?? "") + (delta.partial_json ?? "");
2147
2149
  }
2148
2150
  } else if (type === "content_block_stop") {
2149
- if (currentToolId && toolInputBuffers[currentToolId]) {
2151
+ if (currentToolId && currentToolId in toolInputBuffers) {
2150
2152
  const tc = toolCalls.find((t) => t.id === currentToolId);
2151
2153
  if (tc) {
2152
- try {
2153
- tc.input = JSON.parse(toolInputBuffers[currentToolId]);
2154
- } catch {
2154
+ const buf2 = toolInputBuffers[currentToolId];
2155
+ if (buf2) {
2156
+ try {
2157
+ tc.input = JSON.parse(buf2);
2158
+ } catch {
2159
+ tc.input = { _parse_error: true, _raw: buf2.slice(0, 200) };
2160
+ }
2155
2161
  }
2156
- if (onToolUseBlock && tc.input && Object.keys(tc.input).length > 0) {
2162
+ if (onToolUseBlock && tc.input && Object.keys(tc.input).length > 0 && !tc.input._parse_error) {
2157
2163
  onToolUseBlock(tc);
2158
2164
  }
2159
2165
  }
2166
+ currentToolId = "";
2160
2167
  }
2161
2168
  } else if (type === "message_delta") {
2162
2169
  const usage = evt.usage;
@@ -2168,10 +2175,13 @@ var init_LLMExecutor = __esm({
2168
2175
  }
2169
2176
  }
2170
2177
  }
2178
+ const validToolCalls = toolCalls.filter(
2179
+ (tc) => tc.input && Object.keys(tc.input).length > 0 && !tc.input._parse_error
2180
+ );
2171
2181
  return {
2172
2182
  content: textContent,
2173
- tool_calls: toolCalls.length > 0 ? toolCalls : null,
2174
- stop_reason: stopReason,
2183
+ tool_calls: validToolCalls.length > 0 ? validToolCalls : null,
2184
+ stop_reason: validToolCalls.length > 0 && stopReason === "tool_use" ? "tool_use" : stopReason,
2175
2185
  tokens_used: inputTokens + outputTokens,
2176
2186
  input_tokens: inputTokens,
2177
2187
  output_tokens: outputTokens,
@@ -2856,7 +2866,7 @@ var init_FileCapability = __esm({
2856
2866
  const rel = String(input.path ?? ".");
2857
2867
  const safe = resolve2(cwd, rel);
2858
2868
  const start = Date.now();
2859
- if (!safe.startsWith(cwd)) {
2869
+ if (!safe.startsWith(cwd + "/") && safe !== cwd) {
2860
2870
  return { success: false, output: "Path outside working directory", duration_ms: 0 };
2861
2871
  }
2862
2872
  try {
@@ -4848,13 +4858,9 @@ var init_CredentialVaultCapability = __esm({
4848
4858
  }
4849
4859
  case "destroy": {
4850
4860
  const prefix = `${sessionId}:`;
4851
- let count = 0;
4852
- for (const k of credStore.keys()) {
4853
- if (k.startsWith(prefix)) {
4854
- credStore.delete(k);
4855
- count++;
4856
- }
4857
- }
4861
+ const keysToDelete = [...credStore.keys()].filter((k) => k.startsWith(prefix));
4862
+ for (const k of keysToDelete) credStore.delete(k);
4863
+ const count = keysToDelete.length;
4858
4864
  sessionKeys.delete(sessionId);
4859
4865
  return {
4860
4866
  success: true,
@@ -5090,17 +5096,21 @@ var init_SessionSearchCapability = __esm({
5090
5096
  try {
5091
5097
  const Database2 = (await import("better-sqlite3")).default;
5092
5098
  const db = new Database2(this.getDbPath());
5093
- const keywords = query.split(/\s+/).filter((w) => w.length > 2);
5094
- const likeClause = keywords.map(() => `content LIKE ?`).join(" OR ");
5095
- const likeParams = keywords.map((k) => `%${k}%`);
5096
- const rows = db.prepare(`
5097
- SELECT session_id, role, content, created_at
5098
- FROM conversations
5099
- WHERE ${likeClause || "1=1"}
5100
- ORDER BY created_at DESC
5101
- LIMIT ?
5102
- `).all(...likeParams, maxResults * 3);
5103
- db.close();
5099
+ let rows;
5100
+ try {
5101
+ const keywords = query.split(/\s+/).filter((w) => w.length > 2);
5102
+ const likeClause = keywords.map(() => `content LIKE ?`).join(" OR ");
5103
+ const likeParams = keywords.map((k) => `%${k.replace(/%/g, "\\%").replace(/_/g, "\\_")}%`);
5104
+ rows = db.prepare(`
5105
+ SELECT session_id, role, content, created_at
5106
+ FROM conversations
5107
+ WHERE ${likeClause || "1=1"}
5108
+ ORDER BY created_at DESC
5109
+ LIMIT ?
5110
+ `).all(...likeParams, maxResults * 3);
5111
+ } finally {
5112
+ db.close();
5113
+ }
5104
5114
  if (!rows.length) {
5105
5115
  return {
5106
5116
  success: true,
@@ -5284,6 +5294,9 @@ ${lines.join("\n")}`,
5284
5294
  import { execSync as execSync5 } from "node:child_process";
5285
5295
  import { readFileSync as readFileSync4, existsSync as existsSync6 } from "node:fs";
5286
5296
  import { resolve as resolve6, extname } from "node:path";
5297
+ function shellSafe(s) {
5298
+ return s.replace(/[^a-zA-Z0-9_.$ \-\/]/g, "");
5299
+ }
5287
5300
  var LSPCapability;
5288
5301
  var init_LSPCapability = __esm({
5289
5302
  "packages/daemon/src/tools/LSPCapability.ts"() {
@@ -5354,7 +5367,7 @@ var init_LSPCapability = __esm({
5354
5367
  for (const pattern of defPatterns) {
5355
5368
  try {
5356
5369
  const grep = execSync5(
5357
- `rg -n "${pattern}" --type ts --type js "${cwd}" 2>/dev/null | head -10`,
5370
+ `rg -n "${shellSafe(pattern)}" --type ts --type js "${cwd}" 2>/dev/null | head -10`,
5358
5371
  { encoding: "utf8", timeout: 5e3 }
5359
5372
  ).trim();
5360
5373
  if (grep) results.push(grep);
@@ -5378,7 +5391,7 @@ ${results.join("\n")}`,
5378
5391
  if (!word) return { success: false, output: "No symbol at that position", duration_ms: Date.now() - start };
5379
5392
  try {
5380
5393
  const grep = execSync5(
5381
- `rg -n "\\b${word}\\b" --type ts --type js "${cwd}" 2>/dev/null | head -20`,
5394
+ `rg -n "\\b${shellSafe(word)}\\b" --type ts --type js "${cwd}" 2>/dev/null | head -20`,
5382
5395
  { encoding: "utf8", timeout: 5e3 }
5383
5396
  ).trim();
5384
5397
  const refCount = grep.split("\n").filter(Boolean).length;
@@ -5437,7 +5450,7 @@ ${grep || "(no symbols found)"}`,
5437
5450
  if (!word) return { success: false, output: "No symbol to search for", duration_ms: 0 };
5438
5451
  try {
5439
5452
  const grep = execSync5(
5440
- `rg -n "\\b${word}\\b" "${cwd}" 2>/dev/null | head -20`,
5453
+ `rg -n "\\b${shellSafe(word)}\\b" "${cwd}" 2>/dev/null | head -20`,
5441
5454
  { encoding: "utf8", timeout: 5e3 }
5442
5455
  ).trim();
5443
5456
  return {
@@ -5982,7 +5995,7 @@ var init_StreamingToolExecutor = __esm({
5982
5995
  });
5983
5996
 
5984
5997
  // packages/daemon/src/AgentExecutor.ts
5985
- import { spawn as spawn6 } from "node:child_process";
5998
+ import { spawn as spawn5 } from "node:child_process";
5986
5999
  import { writeFileSync as writeFileSync4, readFileSync as readFileSync5, readdirSync as readdirSync2, mkdirSync as mkdirSync3, existsSync as existsSync7 } from "node:fs";
5987
6000
  import { resolve as resolve7, dirname as dirname2, relative } from "node:path";
5988
6001
  import { homedir as homedir2 } from "node:os";
@@ -6108,8 +6121,9 @@ var init_AgentExecutor = __esm({
6108
6121
  await new Promise((r) => setTimeout(r, waitMs));
6109
6122
  continue;
6110
6123
  }
6111
- if (this._isContextOverflow(msg) && messages.length > 3) {
6112
- this.onStep("Context limit hit \u2014 compacting history\u2026");
6124
+ if (this._isContextOverflow(msg) && messages.length > 3 && llmRetry < 2) {
6125
+ llmRetry++;
6126
+ this.onStep(`Context limit hit \u2014 compacting history (attempt ${llmRetry}/2)\u2026`);
6113
6127
  this._compactHistory(messages);
6114
6128
  continue;
6115
6129
  }
@@ -6187,40 +6201,11 @@ var init_AgentExecutor = __esm({
6187
6201
  iterations: messages.filter((m) => m.role === "assistant").length
6188
6202
  };
6189
6203
  }
6190
- // ─── Tool execution ────────────────────────────────────────────────────────
6191
- async executeTool(name, input) {
6192
- switch (name) {
6193
- case "shell_exec":
6194
- return this.shellExec(
6195
- String(input.command ?? ""),
6196
- Number(input.timeout_ms ?? this.maxCommandMs)
6197
- );
6198
- case "write_file":
6199
- return this.writeFile(String(input.path ?? ""), String(input.content ?? ""));
6200
- case "read_file":
6201
- return this.readFile(String(input.path ?? ""));
6202
- case "list_dir":
6203
- return this.listDir(input.path ? String(input.path) : void 0);
6204
- case "web_search":
6205
- return this.webSearch(
6206
- String(input.query ?? ""),
6207
- Math.min(10, Number(input.num_results ?? 5))
6208
- );
6209
- case "scrape_url":
6210
- return this.scrapeUrl(
6211
- String(input.url ?? ""),
6212
- String(input.mode ?? "text"),
6213
- input.selector ? String(input.selector) : void 0,
6214
- Number(input.wait_ms ?? 0)
6215
- );
6216
- default:
6217
- return `Unknown tool: ${name}`;
6218
- }
6219
- }
6204
+ // ─── Legacy tool execution (used by built-in tools, not capabilities) ──────
6220
6205
  shellExec(command, timeoutMs) {
6221
6206
  return new Promise((resolve19) => {
6222
6207
  const chunks = [];
6223
- const proc = spawn6("bash", ["-c", command], {
6208
+ const proc = spawn5("bash", ["-c", command], {
6224
6209
  cwd: this.cwd,
6225
6210
  env: { ...process.env, TERM: "dumb" },
6226
6211
  timeout: timeoutMs
@@ -6350,7 +6335,7 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
6350
6335
  // ─── Helpers ───────────────────────────────────────────────────────────────
6351
6336
  safePath(p) {
6352
6337
  const resolved = resolve7(this.cwd, p);
6353
- return resolved.startsWith(this.cwd) ? resolved : null;
6338
+ return resolved.startsWith(this.cwd + "/") || resolved === this.cwd ? resolved : null;
6354
6339
  }
6355
6340
  buildSystemPrompt(extra, task) {
6356
6341
  const isSelfMod = !!(task && SELF_MOD_PATTERN.test(task));
@@ -6754,7 +6739,7 @@ var init_ExecutionVerifier = __esm({
6754
6739
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync10 } from "node:fs";
6755
6740
  import { resolve as resolve9, dirname as dirname3 } from "node:path";
6756
6741
  import { fileURLToPath } from "node:url";
6757
- import { execSync as execSync7, spawn as spawn7 } from "node:child_process";
6742
+ import { execSync as execSync7, spawn as spawn6 } from "node:child_process";
6758
6743
  function isRuntimeBug(error) {
6759
6744
  if (TASK_FAILURE_PATTERNS.some((p) => p.test(error))) return false;
6760
6745
  return RUNTIME_BUG_PATTERNS.some((p) => p.test(error));
@@ -6989,7 +6974,7 @@ Rules:
6989
6974
  restartDaemon() {
6990
6975
  const bundlePath = resolve9(this.projectRoot, "dist", "daemon.mjs");
6991
6976
  if (existsSync10(bundlePath)) {
6992
- const child = spawn7(process.execPath, [bundlePath], {
6977
+ const child = spawn6(process.execPath, [bundlePath], {
6993
6978
  detached: true,
6994
6979
  stdio: "ignore",
6995
6980
  env: process.env
@@ -7910,12 +7895,6 @@ function getFastModelId(provider, _currentModel) {
7910
7895
 
7911
7896
  // packages/daemon/src/services/AutoMemoryExtractor.ts
7912
7897
  init_src();
7913
- var state = {
7914
- lastMessageIndex: 0,
7915
- inProgress: false,
7916
- pendingRun: false,
7917
- turnsSinceExtraction: 0
7918
- };
7919
7898
  var MIN_TURNS_BETWEEN = 3;
7920
7899
  var MAX_MESSAGES_PER_RUN = 20;
7921
7900
  var AutoMemoryExtractor = class {
@@ -7924,6 +7903,13 @@ var AutoMemoryExtractor = class {
7924
7903
  this.graph = graph;
7925
7904
  this.entityNodeId = entityNodeId;
7926
7905
  }
7906
+ // Instance-scoped state (not module-level — prevents cross-session contamination)
7907
+ state = {
7908
+ lastMessageIndex: 0,
7909
+ inProgress: false,
7910
+ pendingRun: false,
7911
+ turnsSinceExtraction: 0
7912
+ };
7927
7913
  /**
7928
7914
  * Called after each session turn. Decides whether to extract memories
7929
7915
  * and runs extraction in the background if needed.
@@ -7931,30 +7917,30 @@ var AutoMemoryExtractor = class {
7931
7917
  * Fire-and-forget — never blocks the main session.
7932
7918
  */
7933
7919
  async maybeExtract(messages, memoryWritesSinceLast) {
7934
- state.turnsSinceExtraction++;
7920
+ this.state.turnsSinceExtraction++;
7935
7921
  if (memoryWritesSinceLast) {
7936
- state.turnsSinceExtraction = 0;
7922
+ this.state.turnsSinceExtraction = 0;
7937
7923
  return;
7938
7924
  }
7939
- if (state.turnsSinceExtraction < MIN_TURNS_BETWEEN) return;
7940
- if (messages.length <= state.lastMessageIndex) return;
7941
- if (state.inProgress) {
7942
- state.pendingRun = true;
7925
+ if (this.state.turnsSinceExtraction < MIN_TURNS_BETWEEN) return;
7926
+ if (messages.length <= this.state.lastMessageIndex) return;
7927
+ if (this.state.inProgress) {
7928
+ this.state.pendingRun = true;
7943
7929
  return;
7944
7930
  }
7945
7931
  await this._runExtraction(messages);
7946
- if (state.pendingRun) {
7947
- state.pendingRun = false;
7932
+ if (this.state.pendingRun) {
7933
+ this.state.pendingRun = false;
7948
7934
  await this._runExtraction(messages);
7949
7935
  }
7950
7936
  }
7951
7937
  async _runExtraction(messages) {
7952
7938
  if (!this.llm?.isConfigured) return;
7953
- state.inProgress = true;
7939
+ this.state.inProgress = true;
7954
7940
  try {
7955
7941
  const newMessages = messages.slice(
7956
- state.lastMessageIndex,
7957
- state.lastMessageIndex + MAX_MESSAGES_PER_RUN
7942
+ this.state.lastMessageIndex,
7943
+ this.state.lastMessageIndex + MAX_MESSAGES_PER_RUN
7958
7944
  );
7959
7945
  if (newMessages.length === 0) return;
7960
7946
  const conversationText = newMessages.filter((m) => m.role === "user" || m.role === "assistant" && !m.tool_calls).map((m) => `${m.role}: ${m.content.slice(0, 500)}`).join("\n");
@@ -8013,19 +7999,19 @@ var AutoMemoryExtractor = class {
8013
7999
  this.graph.addNode(node);
8014
8000
  }
8015
8001
  }
8016
- state.lastMessageIndex = messages.length;
8017
- state.turnsSinceExtraction = 0;
8002
+ this.state.lastMessageIndex = messages.length;
8003
+ this.state.turnsSinceExtraction = 0;
8018
8004
  } catch {
8019
8005
  } finally {
8020
- state.inProgress = false;
8006
+ this.state.inProgress = false;
8021
8007
  }
8022
8008
  }
8023
8009
  /** Reset state (e.g., on new session). */
8024
8010
  reset() {
8025
- state.lastMessageIndex = 0;
8026
- state.inProgress = false;
8027
- state.pendingRun = false;
8028
- state.turnsSinceExtraction = 0;
8011
+ this.state.lastMessageIndex = 0;
8012
+ this.state.inProgress = false;
8013
+ this.state.pendingRun = false;
8014
+ this.state.turnsSinceExtraction = 0;
8029
8015
  }
8030
8016
  };
8031
8017
 
@@ -10503,7 +10489,7 @@ git checkout <commit> graph/ # restore graph files
10503
10489
  };
10504
10490
 
10505
10491
  // packages/daemon/src/services/CodespaceManager.ts
10506
- import { execSync as execSync8, spawn as spawn8 } from "node:child_process";
10492
+ import { execSync as execSync8, spawn as spawn7 } from "node:child_process";
10507
10493
  var BROWSER_PORT_REMOTE = 3e3;
10508
10494
  var BROWSER_PORT_LOCAL = 3001;
10509
10495
  var DISPLAY_NAME = "0agent-browser";
@@ -10598,7 +10584,7 @@ var CodespaceManager = class {
10598
10584
  async openTunnel(name) {
10599
10585
  this.closeTunnel();
10600
10586
  console.log(`[Codespace] Opening tunnel port ${BROWSER_PORT_REMOTE} \u2192 localhost:${BROWSER_PORT_LOCAL}...`);
10601
- this.forwardProcess = spawn8(
10587
+ this.forwardProcess = spawn7(
10602
10588
  "gh",
10603
10589
  ["codespace", "ports", "forward", `${BROWSER_PORT_REMOTE}:${BROWSER_PORT_LOCAL}`, "--codespace", name],
10604
10590
  { stdio: ["ignore", "ignore", "ignore"] }
@@ -10987,52 +10973,52 @@ var SurfaceRouter = class {
10987
10973
  }
10988
10974
  _handleDaemonEvent(event) {
10989
10975
  const sessionId = String(event.session_id ?? "");
10990
- const state2 = this.activeSessions.get(sessionId);
10991
- if (!state2) return;
10992
- const adapter = this.adapters.get(state2.surface);
10976
+ const state = this.activeSessions.get(sessionId);
10977
+ if (!state) return;
10978
+ const adapter = this.adapters.get(state.surface);
10993
10979
  if (!adapter) return;
10994
10980
  if (event.type === "session.token") {
10995
- state2.tokenBuffer += String(event.token ?? "");
10996
- if (state2.streamTimer) clearTimeout(state2.streamTimer);
10997
- state2.streamTimer = setTimeout(() => {
10998
- if (!state2.tokenBuffer) return;
10981
+ state.tokenBuffer += String(event.token ?? "");
10982
+ if (state.streamTimer) clearTimeout(state.streamTimer);
10983
+ state.streamTimer = setTimeout(() => {
10984
+ if (!state.tokenBuffer) return;
10999
10985
  adapter.send({
11000
- surface_channel_id: state2.channelId,
11001
- text: state2.tokenBuffer,
10986
+ surface_channel_id: state.channelId,
10987
+ text: state.tokenBuffer,
11002
10988
  format: "markdown",
11003
10989
  is_progress: true,
11004
- thread_id: state2.threadId
10990
+ thread_id: state.threadId
11005
10991
  }).catch(() => {
11006
10992
  });
11007
10993
  }, 400);
11008
10994
  } else if (event.type === "session.completed") {
11009
- if (state2.streamTimer) {
11010
- clearTimeout(state2.streamTimer);
11011
- state2.streamTimer = null;
10995
+ if (state.streamTimer) {
10996
+ clearTimeout(state.streamTimer);
10997
+ state.streamTimer = null;
11012
10998
  }
11013
10999
  const result = event.result;
11014
11000
  const output = String(result?.output ?? "").trim();
11015
11001
  if (output && output !== "(no output)") {
11016
11002
  adapter.send({
11017
- surface_channel_id: state2.channelId,
11003
+ surface_channel_id: state.channelId,
11018
11004
  text: output,
11019
11005
  format: "markdown",
11020
11006
  is_progress: false,
11021
- thread_id: state2.threadId
11007
+ thread_id: state.threadId
11022
11008
  }).catch(() => {
11023
11009
  });
11024
11010
  }
11025
11011
  this.activeSessions.delete(sessionId);
11026
11012
  } else if (event.type === "session.failed") {
11027
- if (state2.streamTimer) {
11028
- clearTimeout(state2.streamTimer);
11029
- state2.streamTimer = null;
11013
+ if (state.streamTimer) {
11014
+ clearTimeout(state.streamTimer);
11015
+ state.streamTimer = null;
11030
11016
  }
11031
11017
  adapter.send({
11032
- surface_channel_id: state2.channelId,
11018
+ surface_channel_id: state.channelId,
11033
11019
  text: `\u26A0\uFE0F ${String(event.error ?? "Task failed")}`,
11034
11020
  format: "prose",
11035
- thread_id: state2.threadId
11021
+ thread_id: state.threadId
11036
11022
  }).catch(() => {
11037
11023
  });
11038
11024
  this.activeSessions.delete(sessionId);
@@ -11097,13 +11083,13 @@ var TelegramAdapter = class {
11097
11083
  async send(msg) {
11098
11084
  const chatId = Number(msg.surface_channel_id);
11099
11085
  if (!chatId) return;
11100
- const state2 = this.streamingState.get(chatId);
11101
- if (msg.is_progress && state2) {
11102
- state2.accumulatedText = msg.text;
11103
- await this._editMessage(chatId, state2.workingMsgId, `\u23F3 ${this._truncate(msg.text, 3800)}`);
11086
+ const state = this.streamingState.get(chatId);
11087
+ if (msg.is_progress && state) {
11088
+ state.accumulatedText = msg.text;
11089
+ await this._editMessage(chatId, state.workingMsgId, `\u23F3 ${this._truncate(msg.text, 3800)}`);
11104
11090
  } else {
11105
- if (state2) {
11106
- await this._editMessage(chatId, state2.workingMsgId, msg.text);
11091
+ if (state) {
11092
+ await this._editMessage(chatId, state.workingMsgId, msg.text);
11107
11093
  this.streamingState.delete(chatId);
11108
11094
  } else {
11109
11095
  await this._sendMessage(chatId, msg.text);
@@ -11441,24 +11427,24 @@ var SlackAdapter = class {
11441
11427
  if (!this.app) return;
11442
11428
  const client = this.app["client"];
11443
11429
  const stateKey = `${msg.surface_channel_id}:${msg.thread_id ?? ""}`;
11444
- const state2 = this.streamingState.get(stateKey);
11445
- if (msg.is_progress && state2) {
11430
+ const state = this.streamingState.get(stateKey);
11431
+ if (msg.is_progress && state) {
11446
11432
  try {
11447
11433
  await client["chat.update"]({
11448
- channel: state2.channelId,
11449
- ts: state2.ts,
11434
+ channel: state.channelId,
11435
+ ts: state.ts,
11450
11436
  text: `\u23F3 ${this._truncate(msg.text, 3e3)}`
11451
11437
  });
11452
11438
  } catch {
11453
11439
  }
11454
11440
  } else {
11455
- if (state2) {
11441
+ if (state) {
11456
11442
  try {
11457
11443
  await client["chat.update"]({
11458
- channel: state2.channelId,
11459
- ts: state2.ts,
11444
+ channel: state.channelId,
11445
+ ts: state.ts,
11460
11446
  text: msg.text,
11461
- thread_ts: state2.threadTs || void 0
11447
+ thread_ts: state.threadTs || void 0
11462
11448
  });
11463
11449
  } catch {
11464
11450
  await this._postMessage(client, msg.surface_channel_id, msg.text, msg.thread_id);
@@ -11800,7 +11786,7 @@ async function recordAudio(durationSeconds) {
11800
11786
  }
11801
11787
 
11802
11788
  // packages/daemon/src/surfaces/NativeTTS.ts
11803
- import { spawnSync as spawnSync6, spawn as spawn9 } from "node:child_process";
11789
+ import { spawnSync as spawnSync6, spawn as spawn8 } from "node:child_process";
11804
11790
  var NativeTTS = class _NativeTTS {
11805
11791
  engine;
11806
11792
  voice;
@@ -11826,7 +11812,7 @@ var NativeTTS = class _NativeTTS {
11826
11812
  if (!cleaned) return;
11827
11813
  return new Promise((resolve19) => {
11828
11814
  const args = this._buildArgs(this.resolvedEngine, cleaned);
11829
- const proc = spawn9(this.resolvedEngine, args, { stdio: "ignore" });
11815
+ const proc = spawn8(this.resolvedEngine, args, { stdio: "ignore" });
11830
11816
  proc.on("close", () => resolve19());
11831
11817
  proc.on("error", () => resolve19());
11832
11818
  });
@@ -11886,7 +11872,7 @@ var NativeTTS = class _NativeTTS {
11886
11872
  }
11887
11873
  _speakWith(engine, text) {
11888
11874
  const args = this._buildArgs(engine, text);
11889
- const proc = spawn9(engine, args, { stdio: "ignore", detached: true });
11875
+ const proc = spawn8(engine, args, { stdio: "ignore", detached: true });
11890
11876
  proc.unref();
11891
11877
  }
11892
11878
  /** Remove markdown/ANSI and control chars before speaking */
@@ -12014,7 +12000,7 @@ var VoiceAdapter = class {
12014
12000
  import { existsSync as existsSync19, mkdirSync as mkdirSync9, writeFileSync as writeFileSync11 } from "node:fs";
12015
12001
  import { tmpdir as tmpdir5 } from "node:os";
12016
12002
  import { join as join6 } from "node:path";
12017
- import { spawn as spawn10 } from "node:child_process";
12003
+ import { spawn as spawn9 } from "node:child_process";
12018
12004
  var MeetingAdapter = class {
12019
12005
  name = "meeting";
12020
12006
  messageHandler = null;
@@ -12156,7 +12142,7 @@ ${msg.text}
12156
12142
  resolve19(false);
12157
12143
  return;
12158
12144
  }
12159
- const proc = spawn10("ffmpeg", args, { stdio: "pipe" });
12145
+ const proc = spawn9("ffmpeg", args, { stdio: "pipe" });
12160
12146
  this.ffmpegProcess = proc;
12161
12147
  proc.on("close", (code) => {
12162
12148
  this.ffmpegProcess = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0agent",
3
- "version": "1.0.82",
3
+ "version": "1.0.84",
4
4
  "description": "A persistent, learning AI agent that runs on your machine. An agent that learns.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",