open-agents-ai 0.187.278 → 0.187.281

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/dist/index.js CHANGED
@@ -264717,12 +264717,12 @@ var init_taskNormalizer = __esm({
264717
264717
  // packages/orchestrator/dist/dispatcher.js
264718
264718
  function estimateComplexity(task) {
264719
264719
  const text = `${task.goal} ${task.constraints.join(" ")} ${task.successCriteria.join(" ")}`;
264720
- const wordCount = text.split(/\s+/).length;
264720
+ const wordCount2 = text.split(/\s+/).length;
264721
264721
  if (task.urgency === "critical")
264722
264722
  return "high";
264723
- if (wordCount > 150 || task.successCriteria.length > 5)
264723
+ if (wordCount2 > 150 || task.successCriteria.length > 5)
264724
264724
  return "high";
264725
- if (wordCount > 60 || task.successCriteria.length > 2)
264725
+ if (wordCount2 > 60 || task.successCriteria.length > 2)
264726
264726
  return "medium";
264727
264727
  return "low";
264728
264728
  }
@@ -265643,8 +265643,8 @@ function classifyQuery(query) {
265643
265643
  return "error";
265644
265644
  if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(trimmed))
265645
265645
  return "symbol";
265646
- const wordCount = trimmed.split(/\s+/).length;
265647
- if (wordCount <= 3)
265646
+ const wordCount2 = trimmed.split(/\s+/).length;
265647
+ if (wordCount2 <= 3)
265648
265648
  return "short";
265649
265649
  return "long";
265650
265650
  }
@@ -270703,10 +270703,10 @@ Integrate this guidance into your current approach. Continue working on the task
270703
270703
  const turnTier = this.options.modelTier ?? "large";
270704
270704
  if (turn === 0 && (turnTier === "small" || turnTier === "medium")) {
270705
270705
  const goal = this._taskState.goal || "";
270706
- const wordCount = goal.split(/\s+/).length;
270706
+ const wordCount2 = goal.split(/\s+/).length;
270707
270707
  const hasMultipleActions = /\band\b.*\band\b|then.*then|also.*also/i.test(goal);
270708
270708
  const hasMultipleFiles = /files?.*files?|\.ts.*\.ts|create.*write|modify.*create/i.test(goal);
270709
- const isComplex = wordCount > 40 || hasMultipleActions || hasMultipleFiles;
270709
+ const isComplex = wordCount2 > 40 || hasMultipleActions || hasMultipleFiles;
270710
270710
  if (isComplex) {
270711
270711
  messages2.push({
270712
270712
  role: "user",
@@ -328242,7 +328242,53 @@ __export(voicechat_exports, {
328242
328242
  VoiceChatSession: () => VoiceChatSession
328243
328243
  });
328244
328244
  import { EventEmitter as EventEmitter10 } from "node:events";
328245
- var VAD_SILENCE_MS, MAX_SEGMENT_MS, MAX_CONTEXT_TURNS, SYSTEM_PROMPT2, VoiceChatSession;
328245
+ function clamp01(x) {
328246
+ return x < 0 ? 0 : x > 1 ? 1 : x;
328247
+ }
328248
+ function alnumRatio(s2) {
328249
+ if (!s2) return 0;
328250
+ const al = (s2.match(/[\p{L}\p{N}]/gu) || []).length;
328251
+ return al / s2.length;
328252
+ }
328253
+ function wordCount(s2) {
328254
+ const words = s2.trim().match(/[\p{L}\p{N}][\p{L}\p{N}'’_-]*/gu);
328255
+ return words ? words.length : 0;
328256
+ }
328257
+ function repeatingCharPenalty(s2) {
328258
+ let maxRun = 1, cur = 1;
328259
+ for (let i2 = 1; i2 < s2.length; i2++) {
328260
+ if (s2[i2] === s2[i2 - 1]) cur++;
328261
+ else {
328262
+ if (cur > maxRun) maxRun = cur;
328263
+ cur = 1;
328264
+ }
328265
+ }
328266
+ if (cur > maxRun) maxRun = cur;
328267
+ return Math.min(1, Math.max(0, (maxRun - 3) / 10));
328268
+ }
328269
+ function computeSignalFromText(text, confidence) {
328270
+ const t2 = text.trim();
328271
+ if (!t2) return 0;
328272
+ if (NOISE_ONLY_RE.test(t2)) return 0.05;
328273
+ const len = t2.length;
328274
+ const wc = wordCount(t2);
328275
+ const alpha = alnumRatio(t2);
328276
+ let score = 0;
328277
+ if (wc >= 6 && alpha >= 0.6) score = 0.85;
328278
+ else if (wc >= 3 && alpha >= 0.5) score = 0.7;
328279
+ else if (wc >= 2 && alpha >= 0.4) score = 0.5;
328280
+ else if (wc >= 1 && alpha >= 0.3 && len >= 4) score = 0.35;
328281
+ else score = 0.15;
328282
+ score -= repeatingCharPenalty(t2) * 0.4;
328283
+ if (typeof confidence === "number" && !Number.isNaN(confidence)) {
328284
+ score = 0.7 * score + 0.3 * clamp01(confidence);
328285
+ }
328286
+ return clamp01(score);
328287
+ }
328288
+ function truncateForLog(s2, n2) {
328289
+ return s2.length <= n2 ? s2 : s2.slice(0, n2 - 1) + "…";
328290
+ }
328291
+ var VAD_SILENCE_MS, MAX_SEGMENT_MS, MAX_CONTEXT_TURNS, SYSTEM_PROMPT2, MIN_SIGNAL_SCORE, NOISE_ONLY_RE, VoiceChatSession;
328246
328292
  var init_voicechat = __esm({
328247
328293
  "packages/cli/src/tui/voicechat.ts"() {
328248
328294
  "use strict";
@@ -328250,6 +328296,8 @@ var init_voicechat = __esm({
328250
328296
  MAX_SEGMENT_MS = 6500;
328251
328297
  MAX_CONTEXT_TURNS = 20;
328252
328298
  SYSTEM_PROMPT2 = `You are a voice assistant having a live spoken conversation. Keep responses extremely brief — 1-2 sentences max. You're speaking aloud, not writing. Be conversational, direct, and helpful. Don't use markdown, bullet points, or formatting — just natural speech. If you don't know something, say so briefly. Do not over-think — respond quickly and concisely.`;
328299
+ MIN_SIGNAL_SCORE = 0.4;
328300
+ NOISE_ONLY_RE = /^(?:[.·…\s,;:!?\-–—_()\[\]{}"'`]+|(?:uh|um|erm|hmm|mm+|uhh+|umm+)[\s.!?]*)+$/i;
328253
328301
  VoiceChatSession = class extends EventEmitter10 {
328254
328302
  voice;
328255
328303
  listen;
@@ -328257,6 +328305,8 @@ var init_voicechat = __esm({
328257
328305
  model;
328258
328306
  apiKey;
328259
328307
  runner;
328308
+ verbose = false;
328309
+ debugSnr = false;
328260
328310
  // State machine
328261
328311
  _state = "IDLE";
328262
328312
  active = false;
@@ -328268,6 +328318,7 @@ var init_voicechat = __esm({
328268
328318
  captureStartTime = 0;
328269
328319
  silenceTimer = null;
328270
328320
  maxSegmentTimer = null;
328321
+ lastSignalScore = null;
328271
328322
  // Abort control for inference
328272
328323
  abortController = null;
328273
328324
  // Callbacks
@@ -328288,6 +328339,8 @@ var init_voicechat = __esm({
328288
328339
  this.model = opts.model;
328289
328340
  this.apiKey = opts.apiKey ?? "";
328290
328341
  this.runner = opts.runner ?? null;
328342
+ this.verbose = Boolean(opts.verbose);
328343
+ this.debugSnr = Boolean(opts.debugSnr);
328291
328344
  this.onStatus = opts.onStatus ?? (() => {
328292
328345
  });
328293
328346
  this.onUserSpeech = opts.onUserSpeech ?? (() => {
@@ -328327,20 +328380,24 @@ var init_voicechat = __esm({
328327
328380
  this.active = true;
328328
328381
  this.context = [{ role: "system", content: SYSTEM_PROMPT2 }];
328329
328382
  this.turnCount = 0;
328330
- this.onStatus("VoiceChat v2 active — state machine: LISTENING");
328383
+ if (this.verbose) this.onStatus("VoiceChat active — LISTENING");
328331
328384
  this._onTranscript = (...args) => {
328332
328385
  let text;
328333
328386
  let isFinal;
328387
+ let snr;
328388
+ let confidence;
328334
328389
  if (typeof args[0] === "object" && args[0] !== null) {
328335
328390
  const evt = args[0];
328336
328391
  text = evt.text ?? "";
328337
328392
  isFinal = evt.isFinal ?? false;
328393
+ snr = evt.snr;
328394
+ confidence = evt.confidence;
328338
328395
  } else {
328339
328396
  text = String(args[0] ?? "");
328340
328397
  isFinal = Boolean(args[1]);
328341
328398
  }
328342
328399
  if (!text.trim()) return;
328343
- this.handleTranscript(text.trim(), isFinal);
328400
+ this.handleTranscript(text.trim(), isFinal, snr, confidence);
328344
328401
  };
328345
328402
  this._onError = (err) => {
328346
328403
  const msg = err instanceof Error ? err.message : String(err);
@@ -328353,7 +328410,7 @@ var init_voicechat = __esm({
328353
328410
  await this.listen.stop().catch(() => {
328354
328411
  });
328355
328412
  await this.listen.start();
328356
- this.onStatus("Mic auto-recovered — LISTENING");
328413
+ if (this.verbose) this.onStatus("Mic auto-recovered — LISTENING");
328357
328414
  } catch {
328358
328415
  }
328359
328416
  }, 1e3);
@@ -328364,11 +328421,9 @@ var init_voicechat = __esm({
328364
328421
  try {
328365
328422
  await this.listen.start();
328366
328423
  this.setState("LISTENING");
328367
- this.onStatus("Mic active — LISTENING for speech...");
328424
+ if (this.verbose) this.onStatus("Mic active — LISTENING for speech...");
328368
328425
  } catch (err) {
328369
- this.onStatus(
328370
- `Mic failed: ${err instanceof Error ? err.message : String(err)}. VoiceChat active without mic.`
328371
- );
328426
+ this.onStatus(`Mic failed: ${err instanceof Error ? err.message : String(err)}. VoiceChat active without mic.`);
328372
328427
  this.setState("LISTENING");
328373
328428
  }
328374
328429
  }
@@ -328403,13 +328458,13 @@ var init_voicechat = __esm({
328403
328458
  } catch {
328404
328459
  }
328405
328460
  this.setState("IDLE");
328406
- this.onStatus("VoiceChat ended");
328461
+ if (this.verbose) this.onStatus("VoiceChat ended");
328407
328462
  this.emit("stopped");
328408
328463
  }
328409
328464
  // ---------------------------------------------------------------------------
328410
328465
  // Transcript handling — VAD-style segment capture (Voryn pattern)
328411
328466
  // ---------------------------------------------------------------------------
328412
- handleTranscript(text, isFinal) {
328467
+ handleTranscript(text, isFinal, snr, confidence) {
328413
328468
  if (!this.active) return;
328414
328469
  if (this._state !== "LISTENING" && this._state !== "CAPTURING") {
328415
328470
  return;
@@ -328425,6 +328480,8 @@ var init_voicechat = __esm({
328425
328480
  }, MAX_SEGMENT_MS);
328426
328481
  }
328427
328482
  this.captureBuffer = text;
328483
+ this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp01(snr) : computeSignalFromText(text, confidence);
328484
+ this.emit("snr", { score: this.lastSignalScore });
328428
328485
  this.onPartialTranscript(text);
328429
328486
  if (this.silenceTimer) clearTimeout(this.silenceTimer);
328430
328487
  if (isFinal) {
@@ -328455,6 +328512,15 @@ var init_voicechat = __esm({
328455
328512
  this.setState("LISTENING");
328456
328513
  return;
328457
328514
  }
328515
+ const score = this.lastSignalScore ?? computeSignalFromText(text);
328516
+ if (score < MIN_SIGNAL_SCORE || NOISE_ONLY_RE.test(text)) {
328517
+ if (this.debugSnr) this.onStatus(`Ignoring low-signal utterance (SNR:${score.toFixed(2)}): ${truncateForLog(text, 48)}`);
328518
+ this.emit("snrFiltered", { score, text });
328519
+ this.setState("LISTENING");
328520
+ this.captureBuffer = "";
328521
+ this.lastSignalScore = null;
328522
+ return;
328523
+ }
328458
328524
  this.setState("TRANSCRIBING");
328459
328525
  this.onUserSpeech(text);
328460
328526
  this.context.push({ role: "user", content: text });
@@ -328476,7 +328542,7 @@ var init_voicechat = __esm({
328476
328542
  async think() {
328477
328543
  if (!this.active) return;
328478
328544
  this.setState("THINKING");
328479
- this.onStatus("Thinking...");
328545
+ if (this.verbose) this.onStatus("Thinking...");
328480
328546
  this.abortController = new AbortController();
328481
328547
  try {
328482
328548
  const response = await this.streamOllamaInference(this.abortController.signal);
@@ -328510,7 +328576,7 @@ var init_voicechat = __esm({
328510
328576
  }
328511
328577
  if (this.active) {
328512
328578
  this.setState("LISTENING");
328513
- this.onStatus("LISTENING...");
328579
+ if (this.verbose) this.onStatus("LISTENING...");
328514
328580
  }
328515
328581
  }
328516
328582
  /**
@@ -333063,22 +333129,22 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
333063
333129
  model: currentConfig.model,
333064
333130
  apiKey: currentConfig.apiKey,
333065
333131
  runner: summaryRunner,
333132
+ verbose: false,
333133
+ debugSnr: false,
333066
333134
  onStatus(msg) {
333067
333135
  writeContent(() => renderInfo2(`[voicechat] ${msg}`));
333068
333136
  },
333069
333137
  onUserSpeech(text) {
333070
333138
  writeContent(() => renderInfo2(`\x1B[38;5;45m[you]\x1B[0m ${text}`));
333071
333139
  },
333072
- onPartialTranscript(text) {
333073
- writeContent(() => {
333074
- process.stdout.write(`\r\x1B[2K\x1B[38;5;243m [hearing] ${text.slice(0, 70)}\x1B[0m`);
333075
- });
333140
+ // Suppressed to keep main loop quiet
333141
+ onPartialTranscript(_text) {
333076
333142
  },
333077
333143
  onAgentSpeech(text) {
333078
333144
  writeContent(() => renderInfo2(`\x1B[38;5;178m[agent]\x1B[0m ${text.slice(0, 120)}`));
333079
333145
  },
333080
- onStateChange(state) {
333081
- writeContent(() => renderInfo2(`\x1B[38;5;243m[voicechat] ${state}\x1B[0m`));
333146
+ // Keep state changes silent
333147
+ onStateChange(_state2) {
333082
333148
  }
333083
333149
  });
333084
333150
  await _voiceChatSession2.start();
package/dist/launcher.cjs CHANGED
@@ -1,14 +1,78 @@
1
1
  #!/usr/bin/env node
2
- // Minimal launcher shim for open-agents CLI — forwards to bundled index.js
3
- // Use dynamic import() so ESM with top-level await can load correctly.
4
- (async () => {
2
+ // Robust launcher for open-agents CLI.
3
+ // - Runs the ESM entry as a child process
4
+ // - On exit code 120 (update), resets terminal and restarts child
5
+ // - Prevents raw-mode/mouse-tracking bleedthrough on restart or crash
6
+
7
+ const { spawn, spawnSync } = require('node:child_process');
8
+ const { resolve } = require('node:path');
9
+
10
+ function resetTerminal() {
11
+ try { if (process.stdin.isTTY && typeof process.stdin.setRawMode === 'function') process.stdin.setRawMode(false); } catch {}
12
+ // Disable mouse tracking, bracketed paste, show cursor, reset attrs, exit alt screen if active
13
+ const ESC = '\x1B';
5
14
  try {
6
- const { resolve } = require('node:path');
7
- const { pathToFileURL } = require('node:url');
8
- const entryUrl = pathToFileURL(resolve(__dirname, 'index.js')).href;
9
- await import(entryUrl);
10
- } catch (e) {
11
- console.error('Failed to launch open-agents:', e && e.message ? e.message : e);
12
- process.exit(1);
15
+ process.stdout.write(
16
+ ESC + '[?25h' + // show cursor
17
+ ESC + '[?1000l' + // X10 mouse off
18
+ ESC + '[?1002l' + // button-event mouse off
19
+ ESC + '[?1003l' + // any-event mouse off
20
+ ESC + '[?1006l' + // SGR mouse off
21
+ ESC + '[?1015l' + // urxvt mouse off
22
+ ESC + '[?2004l' + // bracketed paste off
23
+ ESC + '[?1049l' + // exit alt screen
24
+ ESC + '[0m' // reset attributes
25
+ );
26
+ } catch {}
27
+ // stty sane (POSIX)
28
+ if (process.platform !== 'win32' && process.stdin.isTTY) {
29
+ try { spawnSync('stty', ['sane'], { stdio: 'inherit' }); } catch {}
30
+ }
31
+ }
32
+
33
+ function runChild() {
34
+ const entry = resolve(__dirname, 'index.js');
35
+ const args = [entry, ...process.argv.slice(2)];
36
+ const child = spawn(process.execPath, args, {
37
+ stdio: 'inherit',
38
+ env: process.env,
39
+ });
40
+ return child;
41
+ }
42
+
43
+ (async () => {
44
+ let restarts = 0;
45
+ const MAX_RESTARTS = 3;
46
+ let child = runChild();
47
+
48
+ const forward = (sig) => {
49
+ try { child && child.kill(sig); } catch {}
50
+ };
51
+ process.on('SIGINT', () => forward('SIGINT'));
52
+ process.on('SIGTERM', () => forward('SIGTERM'));
53
+
54
+ function attach(childProc) {
55
+ childProc.on('exit', (code, signal) => {
56
+ if (signal) {
57
+ resetTerminal();
58
+ process.kill(process.pid, signal);
59
+ return;
60
+ }
61
+ if (code === 120 && restarts < MAX_RESTARTS) {
62
+ // Update-triggered restart
63
+ resetTerminal();
64
+ restarts += 1;
65
+ setTimeout(() => {
66
+ child = runChild();
67
+ attach(child);
68
+ }, 300);
69
+ return;
70
+ }
71
+ // Normal exit or too many restarts
72
+ resetTerminal();
73
+ process.exit(typeof code === 'number' ? code : 0);
74
+ });
13
75
  }
76
+
77
+ attach(child);
14
78
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.278",
3
+ "version": "0.187.281",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",