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.
- package/README.md +73 -17
- package/dist/index.js +79 -12
- 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
|
-
- **
|
|
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 (
|
|
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
|
-
| `
|
|
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
|
-
|
|
|
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 &
|
|
483
|
-
| `
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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