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 +91 -25
- package/dist/launcher.cjs +74 -10
- package/package.json +1 -1
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
|
|
264720
|
+
const wordCount2 = text.split(/\s+/).length;
|
|
264721
264721
|
if (task.urgency === "critical")
|
|
264722
264722
|
return "high";
|
|
264723
|
-
if (
|
|
264723
|
+
if (wordCount2 > 150 || task.successCriteria.length > 5)
|
|
264724
264724
|
return "high";
|
|
264725
|
-
if (
|
|
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
|
|
265647
|
-
if (
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
333073
|
-
|
|
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
|
-
|
|
333081
|
-
|
|
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
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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