open-agents-ai 0.35.0 → 0.35.2

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 (3) hide show
  1. package/README.md +84 -1
  2. package/dist/index.js +36 -19
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -38,7 +38,8 @@ An autonomous multi-turn tool-calling agent that reads your code, makes changes,
38
38
  - **Ralph Loop** — iterative task execution that keeps retrying until completion criteria are met
39
39
  - **Dream Mode** — creative idle exploration modeled after real sleep architecture (NREM→REM cycles)
40
40
  - **Live Listen** — bidirectional voice communication with real-time Whisper transcription
41
- - **Neural TTS** — hear what the agent is doing via GLaDOS or Overwatch ONNX voices
41
+ - **Neural TTS** — hear what the agent is doing via GLaDOS or Overwatch ONNX voices, with personality-driven expressiveness
42
+ - **Personality Core** — SAC framework-based style control (concise/balanced/verbose/pedagogical) that shapes agent response depth, voice expressiveness, and system prompt behavior
42
43
  - **Human expert speed ratio** — real-time `Exp: Nx` gauge comparing agent speed to a leading human expert, calibrated across 47 tool baselines
43
44
  - **Cost tracking** — real-time token cost estimation for 15+ cloud providers
44
45
  - **Work evaluation** — LLM-as-judge scoring with task-type-specific rubrics
@@ -134,6 +135,26 @@ Compaction thresholds scale dynamically with model size:
134
135
  | Medium (8-29B) | 24,000 tokens (or 75% of context) | 8 messages |
135
136
  | Small (≤7B) | 12,000 tokens (or 75% of context) | 4-6 messages |
136
137
 
138
+ ### Status Bar Context Tracking (`Ctx:`)
139
+
140
+ The status bar displays a live `Ctx:` gauge showing estimated context window usage:
141
+
142
+ ```
143
+ In: 12,345 | Out: 4,567 | Ctx: 18,000/131,072 86% | Exp: 4.2x
144
+ ^^^^^^^^^^^^^^^^^^^^^^^^
145
+ Estimated tokens used / total context window
146
+ ```
147
+
148
+ This gauge reflects the **post-compaction** token count — when compaction fires, the `Ctx:` value drops to match the actual compressed message history. The compaction warning message shows the before/after:
149
+
150
+ ```
151
+ ⚠ Context compacted: Compacted 70 messages | ~40,279 → ~22,754 tokens (saved ~17,525)
152
+ ```
153
+
154
+ After this compaction, `Ctx:` updates to reflect ~22,754 tokens (not the pre-compaction ~40,279). Both the main inference loop and the brute-force re-engagement path calculate context tokens from the compacted message array, ensuring the status bar always represents the true context state sent to the model.
155
+
156
+ The percentage shows context **remaining** (not used) — green when >50% free, yellow at 25-50%, red below 25%.
157
+
137
158
  ### Memex Experience Archive
138
159
 
139
160
  During compaction, large tool outputs (file reads, grep results, command output) are archived with a short hash ID. The agent can recover any archived result using `memex_retrieve`:
@@ -402,6 +423,8 @@ The TUI features an animated multilingual phrase carousel, live metrics bar with
402
423
  | `/stream` | Toggle streaming token display with pastel syntax highlighting |
403
424
  | `/bruteforce` | Toggle brute-force mode (auto re-engage on turn limit) |
404
425
  | `/verbose` | Toggle verbose mode |
426
+ | `/style [preset]` | Set personality style: `concise`, `balanced`, `verbose`, `pedagogical` |
427
+ | `/personality [preset]` | Alias for `/style` |
405
428
  | **Tools & Skills** | |
406
429
  | `/tools` | List agent-created custom tools |
407
430
  | `/skills [keyword]` | List/search available AIWG skills |
@@ -558,6 +581,66 @@ All context-dependent values scale automatically with the actual context window
558
581
 
559
582
  Auto-downloads the ONNX voice model (~50MB) on first use. Install `espeak-ng` for best quality (`apt install espeak-ng` / `brew install espeak-ng`).
560
583
 
584
+ ### Personality-Aware Voice
585
+
586
+ Voice output adapts to the active personality style — the same tool call sounds different depending on the `/style` preset:
587
+
588
+ | Style | Example (file_read) | Example (npm test) |
589
+ |-------|--------------------|--------------------|
590
+ | **concise** | "Reading app.ts" | "Running tests" |
591
+ | **balanced** | "Let me take a look at app.ts" | "Let's run the tests and see how we're doing" |
592
+ | **verbose** | "Alright, let's crack open app.ts and see what we're working with" | "Alright, moment of truth, let's see if the tests pass" |
593
+
594
+ Task completion, tool failures, and all TTS announcements follow the same personality tier. Set the style with `/style verbose` and the voice output becomes conversational rather than robotic.
595
+
596
+ ## Personality Core — SAC Framework Style Control
597
+
598
+ The personality system controls how the agent communicates — from silent operator to teacher mode. It's based on the **SAC framework** (arXiv:2506.20993) which models personality along five behavioral intensity dimensions rather than binary trait toggles.
599
+
600
+ ```bash
601
+ /style concise # Silent operator — acts without explaining
602
+ /style balanced # Default — moderate narration
603
+ /style verbose # Thorough explainer — narrates reasoning
604
+ /style pedagogical # Teacher mode — maximum explanation with alternatives
605
+ ```
606
+
607
+ ### How It Works
608
+
609
+ Each personality preset maps to a `PersonalityProfile` with five dimensions scored 1-5:
610
+
611
+ | Dimension | What It Controls | concise | balanced | verbose | pedagogical |
612
+ |-----------|-----------------|---------|----------|---------|-------------|
613
+ | **Frequency** | How often the agent narrates actions | 1 | 3 | 5 | 5 |
614
+ | **Depth** | Reasoning detail exposed in output | 1 | 3 | 4 | 5 |
615
+ | **Threshold** | When to speak vs. act silently | 1 | 3 | 4 | 5 |
616
+ | **Effort** | Response formatting quality | 2 | 3 | 4 | 5 |
617
+ | **Willingness** | Proactive suggestions beyond the task | 1 | 3 | 4 | 5 |
618
+
619
+ The profile is compiled into a system prompt suffix (max 80 tokens) injected at the end of the base prompt. This follows research showing prompt-level steering dominates activation-level interventions (arXiv:2512.17639) and uses positive framing ("Be concise") over negation ("Don't be verbose") per KAIST findings.
620
+
621
+ ### What Changes Per Style
622
+
623
+ | Aspect | concise | balanced | verbose | pedagogical |
624
+ |--------|---------|----------|---------|-------------|
625
+ | System prompt | "Act silently, raw results only" | No override | "Explain reasoning, summarize" | "Thorough explanations, alternatives" |
626
+ | Voice TTS | Terse: "Reading file.ts" | Conversational: "Let me take a look" | Chatty: "Alright, let's crack it open" | Chatty + context |
627
+ | Tool calls observed | Same behavior | Same behavior | More exploration, diagnostics | Maximum exploration |
628
+ | Response length | Minimal | Moderate | Detailed | Comprehensive |
629
+
630
+ ### Persistence
631
+
632
+ The style is saved to `.oa/settings.json` (with `--local`) or `~/.open-agents/config.json` (global) and persists across sessions. Change it anytime with `/style <preset>` — takes effect on the next task.
633
+
634
+ ### Research Provenance
635
+
636
+ The personality system draws on:
637
+
638
+ - **SAC Framework** (arXiv:2506.20993) — Five behavioral intensity dimensions with adjective-based semantic anchoring for stable trait expression
639
+ - **Lost in the Middle** (arXiv:2307.03172) — U-shaped attention bias; personality suffix placed at prompt boundaries, not middle
640
+ - **Same Task, More Tokens** (arXiv:2402.14848) — LLM reasoning degrades at ~3K system prompt tokens; personality suffix stays under 80 tokens
641
+ - **Linear Personality Probing** (arXiv:2512.17639) — Prompt-level steering completely dominates activation-level interventions
642
+ - **The Prompt Report** (arXiv:2406.06608) — Positive framing outperforms negated instructions for behavioral control
643
+
561
644
  ## Human Expert Speed Ratio
562
645
 
563
646
  The status bar displays a real-time `Exp: Nx` gauge estimating how fast the agent is working relative to a leading human expert performing equivalent tasks.
package/dist/index.js CHANGED
@@ -18543,31 +18543,47 @@ async function handleUpdate(subcommand, ctx) {
18543
18543
  }
18544
18544
  } catch {
18545
18545
  }
18546
- process.stdout.write(`
18547
- ${c2.cyan("\u25CF")} Checking for updates... ${c2.dim(`(current: v${currentVersion})`)}
18546
+ const BRAILLE_CYCLE = ["\u2800", "\u2840", "\u28C0", "\u28C4", "\u28E4", "\u28E6", "\u28F6", "\u28F7", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28C4", "\u28C0", "\u2840"];
18547
+ function startInlineSpinner(prefix) {
18548
+ let frame = 0;
18549
+ const timer = setInterval(() => {
18550
+ const braille = BRAILLE_CYCLE[frame % BRAILLE_CYCLE.length];
18551
+ process.stdout.write(`\r ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(braille)}`);
18552
+ frame++;
18553
+ }, 80);
18554
+ process.stdout.write(` ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(BRAILLE_CYCLE[0])}`);
18555
+ return {
18556
+ stop(completionText) {
18557
+ clearInterval(timer);
18558
+ process.stdout.write(`\r ${c2.green("\u2714")} ${completionText}${" ".repeat(20)}
18548
18559
  `);
18560
+ }
18561
+ };
18562
+ }
18563
+ process.stdout.write("\n");
18564
+ const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
18549
18565
  const info = await checkForUpdate(currentVersion, true);
18550
18566
  if (!info) {
18551
- process.stdout.write(` ${c2.green("\u2714")} You're on the latest version (v${currentVersion}).
18552
-
18553
- `);
18567
+ checkSpinner.stop(`You're on the latest version (v${currentVersion}).`);
18568
+ process.stdout.write("\n");
18554
18569
  return;
18555
18570
  }
18556
- process.stdout.write(` ${c2.yellow("\u26A0")} Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}
18557
- `);
18558
- process.stdout.write(` ${c2.cyan("\u25CF")} Installing update...
18559
-
18560
- `);
18561
- const { execSync: execSync20 } = await import("node:child_process");
18562
- try {
18563
- execSync20(`npm cache clean --force open-agents-ai 2>/dev/null; npm install -g open-agents-ai@latest --force`, { stdio: "pipe", timeout: 18e4 });
18564
- } catch {
18565
- renderWarning("Update install failed. Try manually: npm i -g open-agents-ai");
18571
+ checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
18572
+ const installSpinner = startInlineSpinner("Installing update");
18573
+ const { exec } = await import("node:child_process");
18574
+ const installOk = await new Promise((resolve23) => {
18575
+ const child = exec(`npm cache clean --force open-agents-ai 2>/dev/null; npm install -g open-agents-ai@latest --force`, { timeout: 18e4 }, (err) => resolve23(!err));
18576
+ child.stdout?.resume();
18577
+ child.stderr?.resume();
18578
+ });
18579
+ if (!installOk) {
18580
+ installSpinner.stop("Update install failed.");
18581
+ renderWarning("Try manually: npm i -g open-agents-ai");
18566
18582
  return;
18567
18583
  }
18568
- process.stdout.write(` ${c2.green("\u2714")} Installed v${info.latestVersion}. Reloading...
18569
-
18570
- `);
18584
+ installSpinner.stop(`Update installed (v${info.latestVersion}).`);
18585
+ const reloadSpinner = startInlineSpinner("Loading");
18586
+ await new Promise((r) => setTimeout(r, 400));
18571
18587
  ctx.contextSave?.();
18572
18588
  const hadActiveTask = ctx.savePendingTaskState?.() ?? false;
18573
18589
  const resumeFlag = hadActiveTask ? "1" : "update-only";
@@ -18580,7 +18596,8 @@ async function handleUpdate(subcommand, ctx) {
18580
18596
  env: { ...process.env, __OA_RESUMED: resumeFlag }
18581
18597
  });
18582
18598
  } catch {
18583
- renderWarning("Reload failed. Restart oa manually to use the new version.");
18599
+ reloadSpinner.stop("Reload failed.");
18600
+ renderWarning("Restart oa manually to use the new version.");
18584
18601
  }
18585
18602
  }
18586
18603
  async function switchModel(query, ctx, local = false) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.35.0",
3
+ "version": "0.35.2",
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",