open-agents-ai 0.34.2 → 0.34.4

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 +73 -17
  2. package/dist/index.js +79 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -29,7 +29,7 @@ An autonomous multi-turn tool-calling agent that reads your code, makes changes,
29
29
 
30
30
  ## Features
31
31
 
32
- - **35+ autonomous tools** — file I/O, shell, grep, web search/fetch/crawl, memory, sub-agents, background tasks, image/OCR, git, diagnostics, vision, desktop automation, structured files, code sandbox
32
+ - **47 autonomous tools** — file I/O, shell, grep, web search/fetch/crawl, memory (read/write/search), sub-agents, background tasks, image/OCR/PDF, git, diagnostics, vision, desktop automation, structured files, code sandbox, transcription, skills
33
33
  - **Moondream vision** — see and interact with the desktop via Moondream VLM (caption, query, detect, point-and-click)
34
34
  - **Desktop automation** — vision-guided clicking: describe a UI element in natural language, the agent finds and clicks it
35
35
  - **Auto-install desktop deps** — screenshot, mouse, OCR, and image tools auto-install missing system packages (scrot, xdotool, tesseract, imagemagick) on first use
@@ -39,6 +39,7 @@ An autonomous multi-turn tool-calling agent that reads your code, makes changes,
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
41
  - **Neural TTS** — hear what the agent is doing via GLaDOS or Overwatch ONNX voices
42
+ - **Human expert speed ratio** — real-time `Exp: Nx` gauge comparing agent speed to a leading human expert, calibrated across 47 tool baselines
42
43
  - **Cost tracking** — real-time token cost estimation for 15+ cloud providers
43
44
  - **Work evaluation** — LLM-as-judge scoring with task-type-specific rubrics
44
45
  - **Session metrics** — track turns, tool calls, tokens, files modified, tasks completed per session
@@ -371,7 +372,7 @@ Launch without arguments to enter the interactive REPL:
371
372
  oa
372
373
  ```
373
374
 
374
- The TUI features an animated multilingual phrase carousel, live metrics bar with pastel-colored labels (token in/out, context window usage), rotating tips, syntax-highlighted tool output, and dynamic terminal-width cropping.
375
+ The TUI features an animated multilingual phrase carousel, live metrics bar with pastel-colored labels (token in/out, context window usage, human expert speed ratio, cost), rotating tips, syntax-highlighted tool output, and dynamic terminal-width cropping.
375
376
 
376
377
  ### Slash Commands
377
378
 
@@ -433,7 +434,7 @@ While the agent is working (shown by the `+` prompt), type to add context:
433
434
  ⎿ Edit: src/auth.ts
434
435
  ```
435
436
 
436
- ## Tools (37)
437
+ ## Tools (47)
437
438
 
438
439
  | Tool | Description |
439
440
  |------|-------------|
@@ -447,9 +448,9 @@ While the agent is working (shown by the `+` prompt), type to add context:
447
448
  | **Search & Navigation** | |
448
449
  | `grep_search` | Search file contents with regex (ripgrep with grep fallback) |
449
450
  | `find_files` | Find files by glob pattern (excludes node_modules/.git) |
450
- | `codebase_map` | High-level project structure overview with directory tree |
451
+ | `codebase_map` | High-level project structure overview with directory tree and language breakdown |
451
452
  | **Shell & Execution** | |
452
- | `shell` | Execute any shell command (non-interactive, CI=true) |
453
+ | `shell` | Execute any shell command (non-interactive, CI=true, sudo support) |
453
454
  | `code_sandbox` | Isolated code execution (JS, Python, Bash, TS) in subprocess or Docker |
454
455
  | `background_run` | Run shell command in background, returns task ID |
455
456
  | `task_status` | Check background task status |
@@ -461,26 +462,34 @@ While the agent is working (shown by the `+` prompt), type to add context:
461
462
  | `web_crawl` | Multi-page web scraping with Crawlee/Playwright for deep documentation |
462
463
  | **Structured Data** | |
463
464
  | `structured_file` | Generate CSV, TSV, JSON, Markdown tables, Excel-compatible files |
464
- | `read_structured_file` | Parse CSV, TSV, JSON, Markdown tables with binary detection |
465
+ | `structured_read` | Parse CSV, TSV, JSON, Markdown tables with binary format detection |
465
466
  | **Vision & Desktop** | |
466
467
  | `vision` | Moondream VLM — caption, query, detect, point on any image |
467
468
  | `desktop_click` | Vision-guided clicking: describe a UI element, agent finds and clicks it |
468
469
  | `desktop_describe` | Screenshot + Moondream caption/query for desktop awareness |
469
- | `image_read` | Read images (base64 + OCR) |
470
+ | `image_read` | Read images (base64 + OCR metadata) |
470
471
  | `screenshot` | Capture screen/window/active window |
471
472
  | `ocr` | Extract text from images (Tesseract with multi-variant preprocessing) |
473
+ | `ocr_image_advanced` | Advanced multi-variant OCR pipeline with preprocessing, multi-PSM, and confidence scoring |
472
474
  | `ocr_pdf` | Add searchable text layer to scanned/image PDFs |
473
- | `pdf_to_text` | Extract text from PDF using pdftotext (Poppler) |
474
- | `transcribe_file` | Transcribe audio/video to text (Whisper) |
475
+ | `pdf_to_text` | Extract text from PDF using pdftotext (Poppler) with OCR fallback |
476
+ | **Transcription** | |
477
+ | `transcribe_file` | Transcribe local audio/video files to text (Whisper) |
478
+ | `transcribe_url` | Download and transcribe audio/video from URLs |
475
479
  | **Memory & Knowledge** | |
476
- | `memory_read` | Read from persistent memory store by topic |
480
+ | `memory_read` | Read from persistent memory store by topic and key |
477
481
  | `memory_write` | Store facts/patterns in persistent memory with provenance tracking |
482
+ | `memory_search` | Semantic search across all memory entries by query |
478
483
  | `memex_retrieve` | Recover full tool output archived during context compaction by hash ID |
479
484
  | **Git & Diagnostics** | |
480
485
  | `diagnostic` | Lint/typecheck/test/build validation pipeline in one call |
481
486
  | `git_info` | Structured git status, log, diff, branch, staged/unstaged files |
482
- | **Agents & Skills** | |
483
- | `create_tool` | Create reusable custom tools from workflow at runtime |
487
+ | **Agents & Delegation** | |
488
+ | `sub_agent` | Delegate subtasks to independent agent instances (foreground or background) |
489
+ | `explore_tools` | Meta-tool: discover and unlock additional tools on demand (for small models) |
490
+ | `task_complete` | Signal task completion with summary |
491
+ | **Custom Tools & Skills** | |
492
+ | `create_tool` | Create reusable custom tools from workflow patterns at runtime |
484
493
  | `manage_tools` | List, inspect, delete custom tools |
485
494
  | `skill_list` | Discover available AIWG skills |
486
495
  | `skill_execute` | Run an AIWG skill |
@@ -510,13 +519,13 @@ Open Agents classifies models into three tiers and adapts its behavior according
510
519
 
511
520
  | Tier | Parameters | Base Tools | System Prompt | Compaction |
512
521
  |------|-----------|------------|---------------|------------|
513
- | **Large** (≥30B) | 70B, 122B | All 37 tools | Full (344 lines) | 40K threshold |
522
+ | **Large** (≥30B) | 70B, 122B | All 47 tools | Full (344 lines) | 40K threshold |
514
523
  | **Medium** (8-29B) | 9B, 27B | 15 core tools | Condensed (100 lines) | 24K threshold |
515
524
  | **Small** (≤7B) | 4B, 1.5B | 6 base tools + explore_tools | Minimal (15 lines) | 12K threshold |
516
525
 
517
526
  ### Tool Nesting for Small Models
518
527
 
519
- Small models use an **explore_tools** meta-tool pattern inspired by hierarchical API retrieval research (ToolLLM, arXiv:2307.16789). Instead of presenting all 37 tools (which overwhelms small context windows), only 6 core tools are loaded initially:
528
+ Small models use an **explore_tools** meta-tool pattern inspired by hierarchical API retrieval research (ToolLLM, arXiv:2307.16789). Instead of presenting all 47 tools (which overwhelms small context windows), only 6 core tools are loaded initially:
520
529
 
521
530
  - `file_read`, `file_write`, `file_edit`, `shell`, `task_complete`, `explore_tools`
522
531
 
@@ -549,6 +558,45 @@ All context-dependent values scale automatically with the actual context window
549
558
 
550
559
  Auto-downloads the ONNX voice model (~50MB) on first use. Install `espeak-ng` for best quality (`apt install espeak-ng` / `brew install espeak-ng`).
551
560
 
561
+ ## Human Expert Speed Ratio
562
+
563
+ 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.
564
+
565
+ ```
566
+ In: 12,345 | Out: 4,567 | Ctx: 18,000/131,072 86% | Exp: 4.2x | Cost: $0.34
567
+ ^^^^^^^^
568
+ Agent is 4.2x faster
569
+ than a human expert
570
+ ```
571
+
572
+ ### How It Works
573
+
574
+ Each tool call maps to a calibrated expert baseline time — the estimated seconds a top-tier human developer would take to perform the equivalent operation manually:
575
+
576
+ | Operation | Expert Time | Agent Equivalent |
577
+ |-----------|-------------|-----------------|
578
+ | Read a file | 12s | `file_read` |
579
+ | Write a new file | 90s | `file_write` |
580
+ | Make a precise edit | 25s | `file_edit` |
581
+ | Grep search + scan results | 15s | `grep_search` |
582
+ | Run a shell command | 20s | `shell` |
583
+ | Web search + evaluate | 60s | `web_search` |
584
+ | Survey codebase structure | 180s | `codebase_map` |
585
+
586
+ Additional overhead per action:
587
+ - **+5s context-switch** per tool call (expert switching between tools)
588
+ - **+15s planning** per reasoning turn (expert thinking about next step)
589
+
590
+ The ratio accumulates across all tasks in the session:
591
+
592
+ ```
593
+ speedRatio = totalHumanExpertTime / totalAgentWallClockTime
594
+ ```
595
+
596
+ Color coding: green (2x+ faster), yellow (1-2x, comparable), red (<1x, slower than expert).
597
+
598
+ All 47 tools have calibrated baselines ranging from 3s (`task_stop`) to 180s (`codebase_map`). Unknown tools default to 20s.
599
+
552
600
  ## Cost Tracking & Session Metrics
553
601
 
554
602
  Real-time token cost estimation for cloud providers. The status bar shows running cost when using a paid endpoint.
@@ -717,7 +765,7 @@ The agent auto-detects the provider, normalizes the URL (strips `/v1/chat/comple
717
765
 
718
766
  ## Evaluation Suite
719
767
 
720
- 33 evaluation tasks test the agent's autonomous capabilities across coding, web research, SDLC analysis, tool creation, and multi-file reasoning:
768
+ 40 evaluation tasks test the agent's autonomous capabilities across coding, web research, SDLC analysis, tool creation, multi-file reasoning, and memory systems:
721
769
 
722
770
  ```bash
723
771
  node eval/run-agentic.mjs # Run all tasks
@@ -754,15 +802,23 @@ node eval/run-agentic.mjs --model qwen2.5-coder:32b # Different model
754
802
  | 31 | Web extractor bug fixes (3 bugs) | Multi-Bug Fix |
755
803
  | 32 | CSV pipeline across 3 files | Multi-File Tracking |
756
804
  | 33 | FSM bug fixes + factory implementation | State Machine |
805
+ | 34 | Search pre-populated memories | Memory Search |
806
+ | 35 | Analyze code, write to memory, cross-reference | Memory Cross-Reference |
807
+ | 36 | Discover explore_tools, unlock grep_search | Explore Tools |
808
+ | 37 | Analyze code patterns, store and recall from memory | Memory Store & Recall |
809
+ | 38 | Read configs, write to multiple memory topics | Memory Multi-Topic |
810
+ | 39 | Search pre-loaded memories across 3 topics | Memory Pre-Loaded Search |
811
+ | 40 | Combined explore_tools + memory analysis pipeline | Explore + Memory |
757
812
 
758
- Tasks 31-33 are designed for small model (≤9B) evaluation using `file_edit` patterns instead of `file_write` to avoid JSON truncation issues with smaller models.
813
+ Tasks 31-33 are designed for small model (≤9B) evaluation using `file_edit` patterns. Tasks 34-40 test the memory system (read/write/search) and tool discovery.
759
814
 
760
815
  ### Benchmark Results
761
816
 
762
817
  ```
763
- Qwen3.5-122B: 100% pass rate (30/30 tasks)
818
+ Qwen3.5-122B: 100% pass rate (37/37 tasks, including memory tasks 34-40)
764
819
  Qwen3.5-27B: 100% pass rate (30/30 tasks)
765
820
  Qwen3.5-9B: 100% pass rate (tasks 31-33, file_edit-optimized)
821
+ 71% pass rate (5/7 memory tasks 34-40)
766
822
  ```
767
823
 
768
824
  The eval runner includes model-tier-aware features: automatic tool set filtering, HTTP 500 recovery with file_edit hints, loop detection with tool banning, and tier-based output truncation.
package/dist/index.js CHANGED
@@ -90,7 +90,7 @@ function setConfigValue(key, value) {
90
90
  const configPath = join(dir, "config.json");
91
91
  const existing = loadConfigFile();
92
92
  existing[key] = coerceConfigValue(key, value);
93
- writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf8");
93
+ writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", { encoding: "utf8", mode: 384 });
94
94
  }
95
95
  function coerceConfigValue(key, value) {
96
96
  const intKeys = /* @__PURE__ */ new Set(["maxRetries", "timeoutMs"]);
@@ -16181,6 +16181,17 @@ function initOaDirectory(repoRoot) {
16181
16181
  for (const sub of SUBDIRS) {
16182
16182
  mkdirSync6(join25(oaPath, sub), { recursive: true });
16183
16183
  }
16184
+ try {
16185
+ const gitignorePath = join25(repoRoot, ".gitignore");
16186
+ const settingsPattern = ".oa/settings.json";
16187
+ if (existsSync19(gitignorePath)) {
16188
+ const content = readFileSync13(gitignorePath, "utf-8");
16189
+ if (!content.includes(settingsPattern)) {
16190
+ writeFileSync6(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
16191
+ }
16192
+ }
16193
+ } catch {
16194
+ }
16184
16195
  return oaPath;
16185
16196
  }
16186
16197
  function hasOaDirectory(repoRoot) {
@@ -16201,7 +16212,7 @@ function saveProjectSettings(repoRoot, settings) {
16201
16212
  mkdirSync6(oaPath, { recursive: true });
16202
16213
  const existing = loadProjectSettings(repoRoot);
16203
16214
  const merged = { ...existing, ...settings };
16204
- writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16215
+ writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
16205
16216
  }
16206
16217
  function loadGlobalSettings() {
16207
16218
  const settingsPath = join25(homedir9(), ".open-agents", "settings.json");
@@ -16218,7 +16229,7 @@ function saveGlobalSettings(settings) {
16218
16229
  mkdirSync6(dir, { recursive: true });
16219
16230
  const existing = loadGlobalSettings();
16220
16231
  const merged = { ...existing, ...settings };
16221
- writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16232
+ writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
16222
16233
  }
16223
16234
  function resolveSettings(repoRoot) {
16224
16235
  const global = loadGlobalSettings();
@@ -16670,6 +16681,49 @@ function ask(rl, question) {
16670
16681
  rl.question(question, (answer) => resolve23(answer.trim()));
16671
16682
  });
16672
16683
  }
16684
+ function askSecret(rl, question) {
16685
+ return new Promise((resolve23) => {
16686
+ process.stdout.write(question);
16687
+ let secret = "";
16688
+ const stdin = process.stdin;
16689
+ const hadRawMode = stdin.isRaw;
16690
+ if (typeof stdin.setRawMode === "function") {
16691
+ stdin.setRawMode(true);
16692
+ }
16693
+ stdin.resume();
16694
+ const onData = (chunk) => {
16695
+ const ch = chunk.toString("utf8");
16696
+ for (const c3 of ch) {
16697
+ if (c3 === "\r" || c3 === "\n") {
16698
+ stdin.removeListener("data", onData);
16699
+ if (typeof stdin.setRawMode === "function") {
16700
+ stdin.setRawMode(hadRawMode ?? false);
16701
+ }
16702
+ process.stdout.write("\n");
16703
+ resolve23(secret.trim());
16704
+ return;
16705
+ } else if (c3 === "") {
16706
+ stdin.removeListener("data", onData);
16707
+ if (typeof stdin.setRawMode === "function") {
16708
+ stdin.setRawMode(hadRawMode ?? false);
16709
+ }
16710
+ process.stdout.write("\n");
16711
+ resolve23("");
16712
+ return;
16713
+ } else if (c3 === "\x7F" || c3 === "\b") {
16714
+ if (secret.length > 0) {
16715
+ secret = secret.slice(0, -1);
16716
+ process.stdout.write("\b \b");
16717
+ }
16718
+ } else if (c3.charCodeAt(0) >= 32) {
16719
+ secret += c3;
16720
+ process.stdout.write("*");
16721
+ }
16722
+ }
16723
+ };
16724
+ stdin.on("data", onData);
16725
+ });
16726
+ }
16673
16727
  async function autoInstallOllama(rl) {
16674
16728
  const plat = platform();
16675
16729
  if (plat === "linux") {
@@ -16899,7 +16953,7 @@ async function promptForCustomEndpoint(config, rl) {
16899
16953
  ${c2.bold("Does this endpoint require an API key?")} (y/n) `);
16900
16954
  let apiKey = "";
16901
16955
  if (needsKey.toLowerCase() === "y" || needsKey.toLowerCase() === "yes") {
16902
- apiKey = await ask(rl, ` ${c2.bold("API key:")} `);
16956
+ apiKey = await askSecret(rl, ` ${c2.bold("API key:")} `);
16903
16957
  }
16904
16958
  process.stdout.write(`
16905
16959
  ${c2.cyan("\u25CF")} Enter the model name for this endpoint.
@@ -18353,7 +18407,7 @@ async function handleEndpoint(arg, ctx, local = false) {
18353
18407
  process.stdout.write(` ${c2.cyan("Type".padEnd(12))} ${backendType}
18354
18408
  `);
18355
18409
  if (apiKey) {
18356
- process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} Bearer ${apiKey.slice(0, 8)}...
18410
+ process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} Bearer ${apiKey.slice(0, 4)}...
18357
18411
  `);
18358
18412
  } else {
18359
18413
  process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} ${provider.authRequired ? c2.yellow("none (may be required)") : "none"}
@@ -24654,12 +24708,18 @@ async function statusCommand(opts, config) {
24654
24708
  "OPEN_AGENTS_TIMEOUT_MS",
24655
24709
  "OPEN_AGENTS_DRY_RUN",
24656
24710
  "OPEN_AGENTS_VERBOSE",
24657
- "VLLM_BASE_URL"
24711
+ "VLLM_BASE_URL",
24712
+ "VLLM_API_KEY"
24658
24713
  ];
24714
+ const sensitiveEnvVars = /* @__PURE__ */ new Set([
24715
+ "OPEN_AGENTS_API_KEY",
24716
+ "VLLM_API_KEY"
24717
+ ]);
24659
24718
  for (const key of envVars) {
24660
24719
  const val = process.env[key];
24661
24720
  if (val !== void 0) {
24662
- printKeyValue(key, val.includes("key") || val.includes("KEY") ? "[redacted]" : val, 2);
24721
+ const display = sensitiveEnvVars.has(key) ? val.length > 4 ? `[set \u2014 ${val.slice(0, 4)}...]` : val.length > 0 ? "[set]" : "[empty]" : val;
24722
+ printKeyValue(key, display, 2);
24663
24723
  }
24664
24724
  }
24665
24725
  }
@@ -24777,6 +24837,12 @@ __export(config_exports, {
24777
24837
  import { join as join34, resolve as resolve22 } from "node:path";
24778
24838
  import { homedir as homedir13 } from "node:os";
24779
24839
  import { cwd as cwd3 } from "node:process";
24840
+ function redactIfSensitive(key, value) {
24841
+ if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
24842
+ return value.length > 4 ? `[set \u2014 ${value.slice(0, 4)}...]` : "[set]";
24843
+ }
24844
+ return String(value);
24845
+ }
24780
24846
  function coerceForSettings(key, value) {
24781
24847
  if (INT_KEYS.has(key))
24782
24848
  return parseInt(value, 10);
@@ -24812,7 +24878,7 @@ function handleShow(opts, config) {
24812
24878
  if (projectKeys.length > 0) {
24813
24879
  printSection(`Project Overrides (.oa/settings.json)`);
24814
24880
  for (const [k, v] of projectKeys) {
24815
- printKeyValue(k, String(v), 2);
24881
+ printKeyValue(k, redactIfSensitive(k, v), 2);
24816
24882
  }
24817
24883
  } else {
24818
24884
  printSection("Project Overrides");
@@ -24823,7 +24889,7 @@ function handleShow(opts, config) {
24823
24889
  if (globalKeys.length > 0) {
24824
24890
  printSection("Global Settings (~/.open-agents/settings.json)");
24825
24891
  for (const [k, v] of globalKeys) {
24826
- printKeyValue(k, String(v), 2);
24892
+ printKeyValue(k, redactIfSensitive(k, v), 2);
24827
24893
  }
24828
24894
  }
24829
24895
  printSection("Config File");
@@ -24865,7 +24931,7 @@ function handleSet(opts, _config) {
24865
24931
  initOaDirectory(repoRoot);
24866
24932
  const coerced = coerceForSettings(key, value);
24867
24933
  saveProjectSettings(repoRoot, { [key]: coerced });
24868
- printSuccess(`Project override set: ${key} = ${value}`);
24934
+ printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
24869
24935
  printInfo(`Saved to ${join34(repoRoot, ".oa", "settings.json")}`);
24870
24936
  printInfo("This override applies only when running in this workspace.");
24871
24937
  } catch (err) {
@@ -24875,7 +24941,7 @@ function handleSet(opts, _config) {
24875
24941
  } else {
24876
24942
  try {
24877
24943
  setConfigValue(key, value);
24878
- printSuccess(`Config updated: ${key} = ${value}`);
24944
+ printSuccess(`Config updated: ${key} = ${redactIfSensitive(key, value)}`);
24879
24945
  printInfo(`Saved to ~/.open-agents/config.json`);
24880
24946
  printInfo("Tip: Use --local to set project-specific overrides.");
24881
24947
  } catch (err) {
@@ -24894,7 +24960,7 @@ function handleKeys() {
24894
24960
  printInfo(" oa config set model qwen3.5:122b # global default");
24895
24961
  printInfo(" oa config set model qwen3.5:122b --local # this project only");
24896
24962
  }
24897
- var CONFIG_KEYS, INT_KEYS, BOOL_KEYS;
24963
+ var CONFIG_KEYS, SENSITIVE_KEYS, INT_KEYS, BOOL_KEYS;
24898
24964
  var init_config3 = __esm({
24899
24965
  "packages/cli/dist/commands/config.js"() {
24900
24966
  "use strict";
@@ -24916,6 +24982,7 @@ var init_config3 = __esm({
24916
24982
  stream: "Enable real-time token streaming with pastel syntax highlighting (true/false)",
24917
24983
  bruteforce: "Brute-force mode: auto re-engage agent when turn limit hit (true/false)"
24918
24984
  };
24985
+ SENSITIVE_KEYS = /* @__PURE__ */ new Set(["apiKey", "api_key", "secret", "password", "token"]);
24919
24986
  INT_KEYS = /* @__PURE__ */ new Set(["maxRetries", "timeoutMs"]);
24920
24987
  BOOL_KEYS = /* @__PURE__ */ new Set(["dryRun", "verbose", "voice", "stream", "bruteforce"]);
24921
24988
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.34.2",
3
+ "version": "0.34.4",
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",