open-agents-ai 0.187.276 → 0.187.278

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.
Files changed (2) hide show
  1. package/dist/index.js +191 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -269758,6 +269758,10 @@ var init_agenticRunner = __esm({
269758
269758
  // WO-KG-15
269759
269759
  _retrievalContextCache = null;
269760
269760
  // WO-KG-15: cache per-run
269761
+ // Observer world-model and cohort stats
269762
+ _observerMode = "both";
269763
+ _worldFacts = { files: /* @__PURE__ */ new Map(), lastTest: {}, lastLists: /* @__PURE__ */ new Map() };
269764
+ _argCohorts = /* @__PURE__ */ new Map();
269761
269765
  // ── WO-NC-07: Error pattern learning → pre-action guidance injection ──
269762
269766
  // Records error patterns (tool + error signature → learned guidance).
269763
269767
  // When the same tool+context is about to be called again, injects the
@@ -269839,8 +269843,10 @@ var init_agenticRunner = __esm({
269839
269843
  contextWindowSize: options2?.contextWindowSize ?? 0,
269840
269844
  personality: options2?.personality ?? PERSONALITY_PRESETS.balanced,
269841
269845
  personalityName: options2?.personalityName ?? "",
269842
- finalVarResolver: options2?.finalVarResolver ?? void 0
269846
+ finalVarResolver: options2?.finalVarResolver ?? void 0,
269847
+ observerMode: options2?.observerMode ?? "both"
269843
269848
  };
269849
+ this._observerMode = this.options.observerMode;
269844
269850
  }
269845
269851
  /** Update context window size (e.g. after querying Ollama /api/show) */
269846
269852
  setContextWindowSize(size) {
@@ -270206,6 +270212,27 @@ ${body}`;
270206
270212
  }
270207
270213
  }
270208
270214
  }
270215
+ /** Build a light fingerprint for arg cohort learning */
270216
+ buildArgCohortKey(tool, args) {
270217
+ const keys = Object.keys(args || {}).sort();
270218
+ const parts = [tool];
270219
+ for (const k of keys) {
270220
+ const v = args[k];
270221
+ if (typeof v === "string")
270222
+ parts.push(`${k}:${v.slice(0, 64)}`);
270223
+ else if (typeof v === "number" || typeof v === "boolean")
270224
+ parts.push(`${k}:${String(v)}`);
270225
+ else
270226
+ parts.push(`${k}:${JSON.stringify(v).slice(0, 64)}`);
270227
+ }
270228
+ let h = 2166136261;
270229
+ const s2 = parts.join("|");
270230
+ for (let i2 = 0; i2 < s2.length; i2++) {
270231
+ h ^= s2.charCodeAt(i2);
270232
+ h = Math.imul(h, 16777619);
270233
+ }
270234
+ return `${tool}#${(h >>> 0).toString(16)}`;
270235
+ }
270209
270236
  /** Register a tool for the agent to use */
270210
270237
  registerTool(tool) {
270211
270238
  this.tools.set(tool.name, tool);
@@ -270540,6 +270567,9 @@ TASK: ${task}` : task;
270540
270567
  this._hookDenyHintCount = 0;
270541
270568
  this._selfConsistencyVotes = 0;
270542
270569
  this._retrievalContextCache = null;
270570
+ this._observerMode = this.options.observerMode ?? "both";
270571
+ this._worldFacts = { files: /* @__PURE__ */ new Map(), lastTest: {}, lastLists: /* @__PURE__ */ new Map() };
270572
+ this._argCohorts.clear();
270543
270573
  this._lastTodoWriteTurn = -1;
270544
270574
  this._lastTodoReminderTurn = -1;
270545
270575
  let pendingConstraintWarnings = [];
@@ -271114,6 +271144,14 @@ ${memoryLines.join("\n")}`
271114
271144
  const executeSingle = async (tc) => {
271115
271145
  if (this.aborted)
271116
271146
  return null;
271147
+ const cohortKey = this.buildArgCohortKey(tc.name, tc.arguments);
271148
+ const cohort = this._argCohorts.get(cohortKey);
271149
+ if (cohort && cohort.failure >= 3 && cohort.success === 0) {
271150
+ this.emit({ type: "observer_reaction", timestamp: (/* @__PURE__ */ new Date()).toISOString(), observer: { class: "arg_cohort_risk", shortText: `${tc.name} with similar args has failed ${cohort.failure}× recently`, confidence: 0.85 } });
271151
+ if (this._observerMode === "skillcoach" || this._observerMode === "both") {
271152
+ this.pendingUserMessages.push(`[LITTLEMAN] ${tc.name} with similar arguments has failed ${cohort.failure}× recently. Try a different approach first: read relevant files, adjust arguments, or verify prerequisites.`);
271153
+ }
271154
+ }
271117
271155
  if (this._errorPatterns.size > 0) {
271118
271156
  for (const [sig, pattern] of this._errorPatterns) {
271119
271157
  if (pattern.tool === tc.name && pattern.count >= 2 && !this._errorGuidanceInjected.has(sig)) {
@@ -271298,6 +271336,35 @@ ${memoryLines.join("\n")}`
271298
271336
  }
271299
271337
  }
271300
271338
  }
271339
+ const updated = this._argCohorts.get(cohortKey) || { success: 0, failure: 0, lastOutcomeTurn: turn };
271340
+ if (result.success)
271341
+ updated.success++;
271342
+ else
271343
+ updated.failure++;
271344
+ updated.lastOutcomeTurn = turn;
271345
+ this._argCohorts.set(cohortKey, updated);
271346
+ try {
271347
+ if (tc.name === "file_read") {
271348
+ const p2 = String(tc.arguments?.["path"] ?? tc.arguments?.["file"] ?? "");
271349
+ if (p2)
271350
+ this._worldFacts.files.set(p2, { exists: result.success, size: (result.output || "").length, hashSample: (result.output || "").slice(0, 32), lastSeenTurn: turn });
271351
+ } else if (tc.name === "list_directory") {
271352
+ const dir = String(tc.arguments?.["path"] ?? ".");
271353
+ this._worldFacts.lastLists.set(dir, { entriesCount: (result.output.match(/\n/g) || []).length + 1, lastSeenTurn: turn });
271354
+ } else if (tc.name === "shell") {
271355
+ const cmd = String(tc.arguments?.["command"] ?? "");
271356
+ if (/\b(npm|pnpm|yarn)\s+test\b|\bjest\b|\bvitest\b/i.test(cmd)) {
271357
+ const passed = /PASS|✓\s*all/i.test(result.output) && !/FAIL|✗/i.test(result.output);
271358
+ this._worldFacts.lastTest = { passed, summary: result.output.slice(0, 200), turn };
271359
+ }
271360
+ if (/^cd\s+/.test(cmd)) {
271361
+ const m2 = cmd.match(/^cd\s+([^&;\n]+)/);
271362
+ if (m2)
271363
+ this._worldFacts.lastCwd = m2[1];
271364
+ }
271365
+ }
271366
+ } catch {
271367
+ }
271301
271368
  if (this._episodeStore) {
271302
271369
  try {
271303
271370
  const episodeContent = result.success ? `${tc.name}: ${(result.output ?? "").slice(0, 500)}` : `${tc.name} ERROR: ${(result.error ?? result.output ?? "").slice(0, 500)}`;
@@ -273086,6 +273153,9 @@ ${trimmedNew}`;
273086
273153
  }
273087
273154
  while (this._littlemanToolOutcomes.length > 20)
273088
273155
  this._littlemanToolOutcomes.shift();
273156
+ const emitReaction = (cls, shortText, confidence, details2) => {
273157
+ this.emit({ type: "observer_reaction", timestamp: (/* @__PURE__ */ new Date()).toISOString(), observer: { class: cls, shortText, confidence, details: details2 } });
273158
+ };
273089
273159
  const lastAssistant = [...recent].reverse().find((m2) => m2.role === "assistant" && typeof m2.content === "string");
273090
273160
  if (lastAssistant && typeof lastAssistant.content === "string") {
273091
273161
  const text = lastAssistant.content.toLowerCase();
@@ -273095,9 +273165,10 @@ ${trimmedNew}`;
273095
273165
  const successes = recentOutcomes.filter((o2) => o2.succeeded);
273096
273166
  if (successes.length >= 1) {
273097
273167
  const successList = successes.map((o2) => `${o2.tool}: ${o2.preview.slice(0, 60)}`).join("; ");
273098
- this.pendingUserMessages.push(`[LITTLEMAN] Correction: your recent tools DID succeed. Do not retry them.
273099
- Successful results: ${successList}
273100
- Build on these results instead of retrying. What is your NEXT step toward the goal?`);
273168
+ emitReaction("false_failure", `Claimed failure, but recent tools succeeded (${successes.length})`, 0.9, successList);
273169
+ if (this._observerMode === "skillcoach" || this._observerMode === "both") {
273170
+ this.pendingUserMessages.push(`[LITTLEMAN] Correction: recent tools DID succeed. Do not retry them. Successful results: ${successList}. Use them to advance the task.`);
273171
+ }
273101
273172
  this.emit({
273102
273173
  type: "status",
273103
273174
  content: `Littleman: corrected false failure claim (${successes.length} tools succeeded)`,
@@ -273106,6 +273177,22 @@ Build on these results instead of retrying. What is your NEXT step toward the go
273106
273177
  }
273107
273178
  }
273108
273179
  }
273180
+ if (lastAssistant && typeof lastAssistant.content === "string") {
273181
+ const text = lastAssistant.content.toLowerCase();
273182
+ const claimsSuccess = /(done|fixed|success|passed|complete)/i.test(text);
273183
+ if (claimsSuccess) {
273184
+ const recentOutcomes = this._littlemanToolOutcomes.slice(-4);
273185
+ const failures = recentOutcomes.filter((o2) => !o2.succeeded);
273186
+ const successes = recentOutcomes.filter((o2) => o2.succeeded);
273187
+ if (failures.length > 0 && successes.length === 0) {
273188
+ const failList = failures.map((o2) => `${o2.tool}: ${o2.preview.slice(0, 60)}`).join("; ");
273189
+ emitReaction("false_success", `Claimed success, but recent tools failed (${failures.length})`, 0.9, failList);
273190
+ if (this._observerMode === "skillcoach" || this._observerMode === "both") {
273191
+ this.pendingUserMessages.push(`[LITTLEMAN] Your recent tools show errors (${failures.length}). Verify the last tool output and correct the issue before claiming success.`);
273192
+ }
273193
+ }
273194
+ }
273195
+ }
273109
273196
  const lastToolCalls = recent.filter((m2) => m2.role === "assistant" && m2.tool_calls?.length).flatMap((m2) => m2.tool_calls ?? []);
273110
273197
  for (const tc of lastToolCalls) {
273111
273198
  const name10 = tc.function.name;
@@ -273117,8 +273204,10 @@ Build on these results instead of retrying. What is your NEXT step toward the go
273117
273204
  const argsKey = name10 === "shell" ? String(args.command ?? "").slice(0, 60) : name10 === "web_fetch" ? String(args.url ?? "").slice(0, 80) : String(args.path ?? args.url ?? args.query ?? "").slice(0, 60);
273118
273205
  const prior = this._littlemanToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.preview.includes(argsKey.slice(0, 30)) && o2.turn < turn);
273119
273206
  if (prior) {
273120
- this.pendingUserMessages.push(`[LITTLEMAN] You already ran ${name10} successfully on turn ${prior.turn} with similar arguments. Result was: ${prior.preview.slice(0, 100)}
273121
- Do NOT re-run it. Use the result you already have and proceed to the next step.`);
273207
+ emitReaction("redundant_action", `Already ran ${name10} successfully on turn ${prior.turn}`, 0.8, prior.preview);
273208
+ if (this._observerMode === "skillcoach" || this._observerMode === "both") {
273209
+ this.pendingUserMessages.push(`[LITTLEMAN] You already ran ${name10} successfully on turn ${prior.turn} with similar arguments. Do NOT re-run it. Use the existing result and proceed.`);
273210
+ }
273122
273211
  this.emit({
273123
273212
  type: "status",
273124
273213
  content: `Littleman: prevented redundant ${name10} call (succeeded on turn ${prior.turn})`,
@@ -273140,7 +273229,10 @@ Do NOT re-run it. Use the result you already have and proceed to the next step.`
273140
273229
  }
273141
273230
  }
273142
273231
  if (consecutiveShortResults >= 3) {
273143
- this.pendingUserMessages.push(`[LITTLEMAN] You have sent ${consecutiveShortResults} consecutive outputs without reading any input. In an interactive session, you MUST alternate: receive input, then respond, then receive again. STOP sending and call your input/listening tool NOW to hear what the other side said.`);
273232
+ emitReaction("idle_think", `Consecutive output without input: ${consecutiveShortResults}`, 0.7);
273233
+ if (this._observerMode === "skillcoach" || this._observerMode === "both") {
273234
+ this.pendingUserMessages.push(`[LITTLEMAN] You have sent ${consecutiveShortResults} consecutive outputs without reading any input. Alternate: receive input, then respond. Call your input tool now.`);
273235
+ }
273144
273236
  this.emit({
273145
273237
  type: "status",
273146
273238
  content: `Littleman: blocked runaway output (${consecutiveShortResults} consecutive sends without receive)`,
@@ -294584,6 +294676,8 @@ var init_voice = __esm({
294584
294676
  currentPlayback = null;
294585
294677
  speakQueue = [];
294586
294678
  speaking = false;
294679
+ drainPromise = null;
294680
+ drainResolve = null;
294587
294681
  phonemizeFn = null;
294588
294682
  /** True when current model uses MLX Audio backend */
294589
294683
  mlxActive = false;
@@ -294900,6 +294994,15 @@ var init_voice = __esm({
294900
294994
  const speedFactor = emotion ? emotionToSpeedFactor(emotion, this.starkMode, this.autistMode) : 1;
294901
294995
  this.enqueueSpeech(text, 0.55, 1 + pitchBias, speedFactor, 0.15);
294902
294996
  }
294997
+ /** Wait until the speak queue is fully drained (all audio played). */
294998
+ async waitUntilIdle() {
294999
+ if (!this.speaking && this.speakQueue.length === 0) return;
295000
+ if (this.drainPromise) {
295001
+ await this.drainPromise;
295002
+ } else {
295003
+ await this.sleep(100);
295004
+ }
295005
+ }
294903
295006
  enqueueSpeech(text, volume, pitchFactor, speedFactor = 1, stereoDelayMs = 0.6) {
294904
295007
  if (!this.enabled || !this.ready) return;
294905
295008
  text = sanitizeForTTS(text);
@@ -295098,6 +295201,11 @@ var init_voice = __esm({
295098
295201
  */
295099
295202
  async drainQueue() {
295100
295203
  this.speaking = true;
295204
+ if (!this.drainPromise) {
295205
+ this.drainPromise = new Promise((resolve40) => {
295206
+ this.drainResolve = resolve40;
295207
+ });
295208
+ }
295101
295209
  let isFirst = true;
295102
295210
  let prefetchedWav = null;
295103
295211
  while (this.speakQueue.length > 0) {
@@ -295149,6 +295257,14 @@ var init_voice = __esm({
295149
295257
  }
295150
295258
  }
295151
295259
  this.speaking = false;
295260
+ if (this.drainResolve) {
295261
+ try {
295262
+ this.drainResolve();
295263
+ } catch {
295264
+ }
295265
+ }
295266
+ this.drainResolve = null;
295267
+ this.drainPromise = null;
295152
295268
  }
295153
295269
  sleep(ms) {
295154
295270
  return new Promise((resolve40) => setTimeout(resolve40, ms));
@@ -328126,13 +328242,12 @@ __export(voicechat_exports, {
328126
328242
  VoiceChatSession: () => VoiceChatSession
328127
328243
  });
328128
328244
  import { EventEmitter as EventEmitter10 } from "node:events";
328129
- var VAD_SILENCE_MS, MAX_SEGMENT_MS, SUMMARY_INJECTION_INTERVAL, MAX_CONTEXT_TURNS, SYSTEM_PROMPT2, VoiceChatSession;
328245
+ var VAD_SILENCE_MS, MAX_SEGMENT_MS, MAX_CONTEXT_TURNS, SYSTEM_PROMPT2, VoiceChatSession;
328130
328246
  var init_voicechat = __esm({
328131
328247
  "packages/cli/src/tui/voicechat.ts"() {
328132
328248
  "use strict";
328133
- VAD_SILENCE_MS = 1100;
328249
+ VAD_SILENCE_MS = 2e3;
328134
328250
  MAX_SEGMENT_MS = 6500;
328135
- SUMMARY_INJECTION_INTERVAL = 4;
328136
328251
  MAX_CONTEXT_TURNS = 20;
328137
328252
  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.`;
328138
328253
  VoiceChatSession = class extends EventEmitter10 {
@@ -328164,6 +328279,7 @@ var init_voicechat = __esm({
328164
328279
  // Bound handlers for cleanup
328165
328280
  _onTranscript = null;
328166
328281
  _onError = null;
328282
+ _retryMicTimer = null;
328167
328283
  constructor(opts) {
328168
328284
  super();
328169
328285
  this.voice = opts.voice;
@@ -328229,6 +328345,19 @@ var init_voicechat = __esm({
328229
328345
  this._onError = (err) => {
328230
328346
  const msg = err instanceof Error ? err.message : String(err);
328231
328347
  this.onStatus(`ASR error (voicechat continues without mic): ${msg.slice(0, 80)}`);
328348
+ if (this.active && !this._retryMicTimer) {
328349
+ this._retryMicTimer = setTimeout(async () => {
328350
+ this._retryMicTimer = null;
328351
+ if (!this.active) return;
328352
+ try {
328353
+ await this.listen.stop().catch(() => {
328354
+ });
328355
+ await this.listen.start();
328356
+ this.onStatus("Mic auto-recovered — LISTENING");
328357
+ } catch {
328358
+ }
328359
+ }, 1e3);
328360
+ }
328232
328361
  };
328233
328362
  this.listen.on("transcript", this._onTranscript);
328234
328363
  this.listen.on("error", this._onError);
@@ -328330,6 +328459,12 @@ var init_voicechat = __esm({
328330
328459
  this.onUserSpeech(text);
328331
328460
  this.context.push({ role: "user", content: text });
328332
328461
  this.turnCount++;
328462
+ if (this.runner) {
328463
+ try {
328464
+ this.runner.injectUserMessage(`[VOICECHAT] ${text}`);
328465
+ } catch {
328466
+ }
328467
+ }
328333
328468
  while (this.context.length > MAX_CONTEXT_TURNS + 1) {
328334
328469
  this.context.splice(1, 1);
328335
328470
  }
@@ -328351,11 +328486,18 @@ var init_voicechat = __esm({
328351
328486
  this.setState("SPEAKING");
328352
328487
  this.onAgentSpeech(response.trim());
328353
328488
  this.voice.speak(response.trim());
328354
- if (this.runner && this.turnCount % SUMMARY_INJECTION_INTERVAL === 0) {
328489
+ if (this.runner) {
328355
328490
  this.injectSummary();
328356
328491
  }
328357
- const estimatedMs = Math.max(1500, response.length / 5 * (6e4 / 150));
328358
- await new Promise((r2) => setTimeout(r2, estimatedMs));
328492
+ if (typeof this.voice.waitUntilIdle === "function") {
328493
+ try {
328494
+ await this.voice.waitUntilIdle();
328495
+ } catch {
328496
+ }
328497
+ } else {
328498
+ const estimatedMs = Math.max(1500, response.length / 5 * (6e4 / 150));
328499
+ await new Promise((r2) => setTimeout(r2, estimatedMs));
328500
+ }
328359
328501
  }
328360
328502
  } catch (err) {
328361
328503
  if (!this.active) return;
@@ -328478,13 +328620,19 @@ var init_voicechat = __esm({
328478
328620
  // ---------------------------------------------------------------------------
328479
328621
  injectSummary() {
328480
328622
  if (!this.runner) return;
328481
- const recentTurns = this.context.filter((t2) => t2.role !== "system").slice(-6).map((t2) => `${t2.role === "user" ? "User" : "Assistant"}: ${t2.content}`).join("\n");
328623
+ const recentTurns = this.context.filter((t2) => t2.role !== "system").slice(-8).map((t2) => `${t2.role === "user" ? "User" : "Assistant"}: ${t2.content}`).join("\n");
328482
328624
  this.runner.injectUserMessage(
328483
- `[VOICECHAT SUMMARY] The following is a summary of the recent voice conversation happening in parallel. You don't need to respond to this directly — it's for your awareness. Continue your current task.
328625
+ `[VOICECHAT SUMMARY] Parallel voice liaison update (for awareness only). Continue your current task; do not respond to this directly.
328484
328626
 
328485
328627
  ${recentTurns}`
328486
328628
  );
328487
328629
  }
328630
+ /** Enqueue narration from main agent events into the voice channel */
328631
+ enqueueAgentNarration(text, subordinate = true) {
328632
+ if (!text || !this.active) return;
328633
+ if (subordinate) this.voice.speakSubordinate(text);
328634
+ else this.voice.speak(text);
328635
+ }
328488
328636
  };
328489
328637
  }
328490
328638
  });
@@ -330064,6 +330212,17 @@ ${entry.fullContent}`
330064
330212
  }
330065
330213
  });
330066
330214
  }
330215
+ if (voice?.enabled && voice.voiceMode === "voicechat" && _voiceChatSession?.isActive && event.toolName === "task_complete") {
330216
+ const emoStateFinal = emotionEngine?.getState();
330217
+ const emoCtxFinal = emoStateFinal ? { valence: emoStateFinal.valence, arousal: emoStateFinal.arousal, label: emoStateFinal.label, emoji: emoStateFinal.emoji } : void 0;
330218
+ const desc = describeTaskComplete(String(event.content ?? ""), true, vLevel);
330219
+ if (desc) {
330220
+ try {
330221
+ _voiceChatSession.enqueueAgentNarration(desc, false);
330222
+ } catch {
330223
+ }
330224
+ }
330225
+ }
330067
330226
  break;
330068
330227
  }
330069
330228
  case "model_response":
@@ -330145,6 +330304,15 @@ ${entry.fullContent}`
330145
330304
  voice.speak(chatText);
330146
330305
  voice._spokenStreamText = true;
330147
330306
  }
330307
+ } else if (voice?.enabled && voice.voiceMode === "voicechat" && (streamTextBuffer || event.content)) {
330308
+ const chatText = (streamTextBuffer || event.content || "").trim();
330309
+ streamTextBuffer = "";
330310
+ if (chatText.length > 10 && _voiceChatSession?.isActive) {
330311
+ try {
330312
+ _voiceChatSession.enqueueAgentNarration(chatText, false);
330313
+ } catch {
330314
+ }
330315
+ }
330148
330316
  }
330149
330317
  break;
330150
330318
  }
@@ -331182,7 +331350,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
331182
331350
  autoUpdateTimer.unref();
331183
331351
  const voiceEngine = new VoiceEngine();
331184
331352
  let voiceSession = null;
331185
- let _voiceChatSession = null;
331353
+ let _voiceChatSession2 = null;
331186
331354
  let tunnelGateway = null;
331187
331355
  let p2pGateway = null;
331188
331356
  let peerMesh = null;
@@ -332871,7 +333039,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
332871
333039
  },
332872
333040
  // --- /voicechat: Voryn-style state machine voice conversation ---
332873
333041
  async voiceChatStart() {
332874
- if (_voiceChatSession?.isActive) return;
333042
+ if (_voiceChatSession2?.isActive) return;
332875
333043
  if (!voiceEngine.enabled || !voiceEngine.ready) {
332876
333044
  writeContent(() => renderInfo2("Auto-enabling voice for voice chat..."));
332877
333045
  const voiceMsg = await voiceEngine.toggle();
@@ -332888,7 +333056,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
332888
333056
  }
332889
333057
  }
332890
333058
  };
332891
- _voiceChatSession = new VoiceChatSession2({
333059
+ _voiceChatSession2 = new VoiceChatSession2({
332892
333060
  voice: voiceEngine,
332893
333061
  listen: listenEng,
332894
333062
  backendUrl: currentConfig.backendUrl,
@@ -332913,16 +333081,16 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
332913
333081
  writeContent(() => renderInfo2(`\x1B[38;5;243m[voicechat] ${state}\x1B[0m`));
332914
333082
  }
332915
333083
  });
332916
- await _voiceChatSession.start();
333084
+ await _voiceChatSession2.start();
332917
333085
  },
332918
333086
  async voiceChatStop() {
332919
- if (_voiceChatSession?.isActive) {
332920
- await _voiceChatSession.stop();
332921
- _voiceChatSession = null;
333087
+ if (_voiceChatSession2?.isActive) {
333088
+ await _voiceChatSession2.stop();
333089
+ _voiceChatSession2 = null;
332922
333090
  }
332923
333091
  },
332924
333092
  isVoiceChatActive() {
332925
- return _voiceChatSession?.isActive ?? false;
333093
+ return _voiceChatSession2?.isActive ?? false;
332926
333094
  },
332927
333095
  async exposeStart(kindOrUrl, authKey, transport, fullAccess, passthrough, loadbalance) {
332928
333096
  const knownKinds = ["ollama", "vllm", "llvm", "passthrough"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.276",
3
+ "version": "0.187.278",
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",