open-agents-ai 0.187.8 → 0.187.10
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 +694 -225
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12980,14 +12980,23 @@ var init_skill_tools = __esm({
|
|
|
12980
12980
|
name: {
|
|
12981
12981
|
type: "string",
|
|
12982
12982
|
description: "Skill name (e.g. 'artifact-lookup', 'test-coverage', 'security-assessment')"
|
|
12983
|
+
},
|
|
12984
|
+
fork: {
|
|
12985
|
+
type: "boolean",
|
|
12986
|
+
description: "Run skill in a sub-agent instead of expanding inline (saves parent context for large skills)"
|
|
12983
12987
|
}
|
|
12984
12988
|
},
|
|
12985
12989
|
required: ["name"]
|
|
12986
12990
|
};
|
|
12987
12991
|
repoRoot;
|
|
12992
|
+
_forkCallback;
|
|
12988
12993
|
constructor(repoRoot) {
|
|
12989
12994
|
this.repoRoot = repoRoot;
|
|
12990
12995
|
}
|
|
12996
|
+
/** Set callback to handle forked skill execution via sub-agent (WO-FORK-01) */
|
|
12997
|
+
setForkCallback(cb) {
|
|
12998
|
+
this._forkCallback = cb;
|
|
12999
|
+
}
|
|
12991
13000
|
async execute(args) {
|
|
12992
13001
|
const start2 = performance.now();
|
|
12993
13002
|
const name10 = String(args["name"] ?? args["skill_name"] ?? args["skillName"] ?? args["skill"] ?? "").trim();
|
|
@@ -13021,6 +13030,15 @@ Did you mean: ${fuzzy.map((s2) => s2.name).join(", ")}?` : "\nUse skill_list to
|
|
|
13021
13030
|
durationMs: performance.now() - start2
|
|
13022
13031
|
};
|
|
13023
13032
|
}
|
|
13033
|
+
const fork = Boolean(args["fork"]);
|
|
13034
|
+
if (fork && this._forkCallback) {
|
|
13035
|
+
try {
|
|
13036
|
+
const result = await this._forkCallback(skill.name, content);
|
|
13037
|
+
return { success: true, output: result, durationMs: performance.now() - start2 };
|
|
13038
|
+
} catch (err) {
|
|
13039
|
+
return { success: false, output: "", error: `Skill fork failed: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
13040
|
+
}
|
|
13041
|
+
}
|
|
13024
13042
|
const compactionHint = skill.compactionStrategy ? `
|
|
13025
13043
|
Compaction strategy: ${skill.compactionStrategy}` : "";
|
|
13026
13044
|
return {
|
|
@@ -247600,9 +247618,9 @@ var init_vision = __esm({
|
|
|
247600
247618
|
if (ollamaResult)
|
|
247601
247619
|
return ollamaResult;
|
|
247602
247620
|
try {
|
|
247603
|
-
const { execSync:
|
|
247621
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
247604
247622
|
try {
|
|
247605
|
-
|
|
247623
|
+
execSync40("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
|
|
247606
247624
|
timeout: 12e4,
|
|
247607
247625
|
stdio: "pipe"
|
|
247608
247626
|
});
|
|
@@ -247615,7 +247633,7 @@ var init_vision = __esm({
|
|
|
247615
247633
|
} catch {
|
|
247616
247634
|
}
|
|
247617
247635
|
try {
|
|
247618
|
-
|
|
247636
|
+
execSync40("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247619
247637
|
const retryOllama = await this.tryOllamaVision(buffer2, filename, action, prompt, length4, start2);
|
|
247620
247638
|
if (retryOllama)
|
|
247621
247639
|
return retryOllama;
|
|
@@ -247723,8 +247741,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
|
|
|
247723
247741
|
const errText = await res.text().catch(() => "");
|
|
247724
247742
|
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
247725
247743
|
try {
|
|
247726
|
-
const { execSync:
|
|
247727
|
-
|
|
247744
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
247745
|
+
execSync40("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247728
247746
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
247729
247747
|
method: "POST",
|
|
247730
247748
|
headers: { "Content-Type": "application/json" },
|
|
@@ -259377,6 +259395,400 @@ var init_pressure_gate = __esm({
|
|
|
259377
259395
|
}
|
|
259378
259396
|
});
|
|
259379
259397
|
|
|
259398
|
+
// packages/orchestrator/dist/tool-batching.js
|
|
259399
|
+
function isConcurrencySafe(toolName, readOnlyHints) {
|
|
259400
|
+
if (CONCURRENT_SAFE_TOOLS.has(toolName))
|
|
259401
|
+
return true;
|
|
259402
|
+
if (SERIAL_ONLY_TOOLS.has(toolName))
|
|
259403
|
+
return false;
|
|
259404
|
+
if (toolName.startsWith("mcp__") && readOnlyHints?.get(toolName))
|
|
259405
|
+
return true;
|
|
259406
|
+
return false;
|
|
259407
|
+
}
|
|
259408
|
+
function partitionToolCalls(calls, readOnlyHints) {
|
|
259409
|
+
if (calls.length === 0)
|
|
259410
|
+
return [];
|
|
259411
|
+
if (calls.length === 1) {
|
|
259412
|
+
return [{ concurrent: false, calls }];
|
|
259413
|
+
}
|
|
259414
|
+
const batches = [];
|
|
259415
|
+
let currentConcurrent = [];
|
|
259416
|
+
for (const call of calls) {
|
|
259417
|
+
if (isConcurrencySafe(call.name, readOnlyHints)) {
|
|
259418
|
+
currentConcurrent.push(call);
|
|
259419
|
+
} else {
|
|
259420
|
+
if (currentConcurrent.length > 0) {
|
|
259421
|
+
batches.push({ concurrent: true, calls: currentConcurrent });
|
|
259422
|
+
currentConcurrent = [];
|
|
259423
|
+
}
|
|
259424
|
+
batches.push({ concurrent: false, calls: [call] });
|
|
259425
|
+
}
|
|
259426
|
+
}
|
|
259427
|
+
if (currentConcurrent.length > 0) {
|
|
259428
|
+
batches.push({ concurrent: true, calls: currentConcurrent });
|
|
259429
|
+
}
|
|
259430
|
+
return batches;
|
|
259431
|
+
}
|
|
259432
|
+
async function withConcurrencyLimit(fns, limit = 5) {
|
|
259433
|
+
const results = new Array(fns.length);
|
|
259434
|
+
let nextIdx = 0;
|
|
259435
|
+
async function runNext() {
|
|
259436
|
+
while (nextIdx < fns.length) {
|
|
259437
|
+
const idx = nextIdx++;
|
|
259438
|
+
results[idx] = await fns[idx]();
|
|
259439
|
+
}
|
|
259440
|
+
}
|
|
259441
|
+
const workers = Array.from({ length: Math.min(limit, fns.length) }, () => runNext());
|
|
259442
|
+
await Promise.all(workers);
|
|
259443
|
+
return results;
|
|
259444
|
+
}
|
|
259445
|
+
async function executeBatch(batch2, executeFn, concurrencyLimit = 5) {
|
|
259446
|
+
if (!batch2.concurrent || batch2.calls.length === 1) {
|
|
259447
|
+
const results = [];
|
|
259448
|
+
for (const call of batch2.calls) {
|
|
259449
|
+
results.push(await executeFn(call));
|
|
259450
|
+
}
|
|
259451
|
+
return results;
|
|
259452
|
+
}
|
|
259453
|
+
return withConcurrencyLimit(batch2.calls.map((call) => () => executeFn(call)), concurrencyLimit);
|
|
259454
|
+
}
|
|
259455
|
+
var CONCURRENT_SAFE_TOOLS, SERIAL_ONLY_TOOLS;
|
|
259456
|
+
var init_tool_batching = __esm({
|
|
259457
|
+
"packages/orchestrator/dist/tool-batching.js"() {
|
|
259458
|
+
"use strict";
|
|
259459
|
+
CONCURRENT_SAFE_TOOLS = /* @__PURE__ */ new Set([
|
|
259460
|
+
// Read-only file operations
|
|
259461
|
+
"file_read",
|
|
259462
|
+
"grep_search",
|
|
259463
|
+
// actual tool name (grep-search.ts)
|
|
259464
|
+
"grep",
|
|
259465
|
+
// alias (used in tests/documentation)
|
|
259466
|
+
"find_files",
|
|
259467
|
+
// actual tool name (glob-find.ts)
|
|
259468
|
+
"glob",
|
|
259469
|
+
// alias (used in tests/documentation)
|
|
259470
|
+
"list_directory",
|
|
259471
|
+
"file_explore",
|
|
259472
|
+
"read_structured_file",
|
|
259473
|
+
"git_info",
|
|
259474
|
+
"codebase_map",
|
|
259475
|
+
"repo_map",
|
|
259476
|
+
"semantic_map",
|
|
259477
|
+
// Read-only web operations
|
|
259478
|
+
"web_fetch",
|
|
259479
|
+
"web_search",
|
|
259480
|
+
// Read-only memory operations
|
|
259481
|
+
"memory_read",
|
|
259482
|
+
"memory_search",
|
|
259483
|
+
// Read-only MCP operations (all MCP reads are safe)
|
|
259484
|
+
"mcp_status",
|
|
259485
|
+
"mcp_read_resource",
|
|
259486
|
+
// Informational tools
|
|
259487
|
+
"explore_tools",
|
|
259488
|
+
"task_status",
|
|
259489
|
+
"task_output",
|
|
259490
|
+
"diagnostic",
|
|
259491
|
+
"process_health",
|
|
259492
|
+
"skill_list",
|
|
259493
|
+
"agenda",
|
|
259494
|
+
"working_notes",
|
|
259495
|
+
// Agent spawning (each gets own context)
|
|
259496
|
+
"agent",
|
|
259497
|
+
"sub_agent",
|
|
259498
|
+
"full_sub_agent",
|
|
259499
|
+
// Vision/image (read-only analysis)
|
|
259500
|
+
"vision",
|
|
259501
|
+
"image_read",
|
|
259502
|
+
"screenshot",
|
|
259503
|
+
// actual tool name (image.ts)
|
|
259504
|
+
"ocr",
|
|
259505
|
+
// actual tool name (image.ts)
|
|
259506
|
+
"ocr_image_advanced",
|
|
259507
|
+
"ocr_pdf",
|
|
259508
|
+
"pdf_to_text",
|
|
259509
|
+
"desktop_describe",
|
|
259510
|
+
// Completion signal
|
|
259511
|
+
"task_complete"
|
|
259512
|
+
]);
|
|
259513
|
+
SERIAL_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
259514
|
+
"file_write",
|
|
259515
|
+
"file_edit",
|
|
259516
|
+
"batch_edit",
|
|
259517
|
+
"file_patch",
|
|
259518
|
+
"shell",
|
|
259519
|
+
"code_sandbox",
|
|
259520
|
+
"notebook_edit",
|
|
259521
|
+
"memory_write",
|
|
259522
|
+
"enter_worktree",
|
|
259523
|
+
"exit_worktree",
|
|
259524
|
+
"create_tool",
|
|
259525
|
+
"desktop_click",
|
|
259526
|
+
"browser_action",
|
|
259527
|
+
"web_crawl",
|
|
259528
|
+
// Spawns browser session — can conflict
|
|
259529
|
+
"image_generate",
|
|
259530
|
+
// GPU resource contention
|
|
259531
|
+
"task_stop"
|
|
259532
|
+
]);
|
|
259533
|
+
}
|
|
259534
|
+
});
|
|
259535
|
+
|
|
259536
|
+
// packages/orchestrator/dist/hooks.js
|
|
259537
|
+
import { execSync as execSync27 } from "node:child_process";
|
|
259538
|
+
function executeHook(hook, env2 = {}) {
|
|
259539
|
+
const start2 = performance.now();
|
|
259540
|
+
const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
|
|
259541
|
+
try {
|
|
259542
|
+
const output = execSync27(hook.command, {
|
|
259543
|
+
timeout: timeout2,
|
|
259544
|
+
env: { ...process.env, ...env2 },
|
|
259545
|
+
encoding: "utf8",
|
|
259546
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
259547
|
+
maxBuffer: 1024 * 1024
|
|
259548
|
+
// 1MB
|
|
259549
|
+
});
|
|
259550
|
+
const directive = parseDirective(output);
|
|
259551
|
+
return {
|
|
259552
|
+
success: true,
|
|
259553
|
+
output: output.trim(),
|
|
259554
|
+
directive,
|
|
259555
|
+
durationMs: performance.now() - start2
|
|
259556
|
+
};
|
|
259557
|
+
} catch (err) {
|
|
259558
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
259559
|
+
const stderr = err?.stderr?.toString?.() ?? "";
|
|
259560
|
+
return {
|
|
259561
|
+
success: false,
|
|
259562
|
+
output: "",
|
|
259563
|
+
error: stderr || error,
|
|
259564
|
+
durationMs: performance.now() - start2
|
|
259565
|
+
};
|
|
259566
|
+
}
|
|
259567
|
+
}
|
|
259568
|
+
function parseDirective(output) {
|
|
259569
|
+
const lines = output.split("\n");
|
|
259570
|
+
for (const line of lines) {
|
|
259571
|
+
const trimmed = line.trim();
|
|
259572
|
+
if (trimmed === "HOOK:ALLOW") {
|
|
259573
|
+
return { action: "allow" };
|
|
259574
|
+
}
|
|
259575
|
+
if (trimmed.startsWith("HOOK:DENY")) {
|
|
259576
|
+
const reason = trimmed.slice("HOOK:DENY".length).trim() || "Denied by hook";
|
|
259577
|
+
return { action: "deny", reason };
|
|
259578
|
+
}
|
|
259579
|
+
if (trimmed.startsWith("HOOK:MODIFY")) {
|
|
259580
|
+
try {
|
|
259581
|
+
const json = trimmed.slice("HOOK:MODIFY".length).trim();
|
|
259582
|
+
const args = JSON.parse(json);
|
|
259583
|
+
return { action: "modify", args };
|
|
259584
|
+
} catch {
|
|
259585
|
+
}
|
|
259586
|
+
}
|
|
259587
|
+
}
|
|
259588
|
+
return void 0;
|
|
259589
|
+
}
|
|
259590
|
+
function matchesToolFilter(hook, toolName) {
|
|
259591
|
+
if (!hook.toolFilter || hook.toolFilter === "*")
|
|
259592
|
+
return true;
|
|
259593
|
+
if (hook.toolFilter === toolName)
|
|
259594
|
+
return true;
|
|
259595
|
+
if (hook.toolFilter.includes("*")) {
|
|
259596
|
+
const regex = new RegExp("^" + hook.toolFilter.replace(/\*/g, ".*") + "$");
|
|
259597
|
+
return regex.test(toolName);
|
|
259598
|
+
}
|
|
259599
|
+
return false;
|
|
259600
|
+
}
|
|
259601
|
+
var DEFAULT_HOOK_TIMEOUT, HookManager;
|
|
259602
|
+
var init_hooks = __esm({
|
|
259603
|
+
"packages/orchestrator/dist/hooks.js"() {
|
|
259604
|
+
"use strict";
|
|
259605
|
+
DEFAULT_HOOK_TIMEOUT = 1e4;
|
|
259606
|
+
HookManager = class {
|
|
259607
|
+
config;
|
|
259608
|
+
constructor(config = {}) {
|
|
259609
|
+
this.config = config;
|
|
259610
|
+
}
|
|
259611
|
+
/** Update hook configuration */
|
|
259612
|
+
setConfig(config) {
|
|
259613
|
+
this.config = config;
|
|
259614
|
+
}
|
|
259615
|
+
/** Get current hook configuration */
|
|
259616
|
+
getConfig() {
|
|
259617
|
+
return this.config;
|
|
259618
|
+
}
|
|
259619
|
+
/** Check if any hooks are configured */
|
|
259620
|
+
hasHooks() {
|
|
259621
|
+
return Object.values(this.config).some((hooks) => hooks && hooks.length > 0);
|
|
259622
|
+
}
|
|
259623
|
+
/**
|
|
259624
|
+
* Run pre_tool_use hooks.
|
|
259625
|
+
* Returns: { allowed: true } or { allowed: false, reason } or { allowed: true, modifiedArgs }
|
|
259626
|
+
*/
|
|
259627
|
+
runPreToolUse(toolName, args, sessionId) {
|
|
259628
|
+
const hooks = this.config.pre_tool_use ?? [];
|
|
259629
|
+
const matching = hooks.filter((h) => matchesToolFilter(h, toolName));
|
|
259630
|
+
let currentArgs = args;
|
|
259631
|
+
for (const hook of matching) {
|
|
259632
|
+
const result = executeHook(hook, {
|
|
259633
|
+
OA_HOOK_TYPE: "pre_tool_use",
|
|
259634
|
+
OA_TOOL_NAME: toolName,
|
|
259635
|
+
OA_TOOL_ARGS: JSON.stringify(currentArgs),
|
|
259636
|
+
OA_SESSION_ID: sessionId ?? ""
|
|
259637
|
+
});
|
|
259638
|
+
if (!result.success) {
|
|
259639
|
+
continue;
|
|
259640
|
+
}
|
|
259641
|
+
if (result.directive?.action === "deny") {
|
|
259642
|
+
return { allowed: false, reason: result.directive.reason };
|
|
259643
|
+
}
|
|
259644
|
+
if (result.directive?.action === "modify") {
|
|
259645
|
+
currentArgs = { ...currentArgs, ...result.directive.args };
|
|
259646
|
+
}
|
|
259647
|
+
}
|
|
259648
|
+
const modified = currentArgs !== args;
|
|
259649
|
+
return { allowed: true, modifiedArgs: modified ? currentArgs : void 0 };
|
|
259650
|
+
}
|
|
259651
|
+
/**
|
|
259652
|
+
* Run post_tool_use hooks (after successful execution).
|
|
259653
|
+
*/
|
|
259654
|
+
runPostToolUse(toolName, args, result, sessionId) {
|
|
259655
|
+
const hooks = this.config.post_tool_use ?? [];
|
|
259656
|
+
const matching = hooks.filter((h) => matchesToolFilter(h, toolName));
|
|
259657
|
+
for (const hook of matching) {
|
|
259658
|
+
executeHook(hook, {
|
|
259659
|
+
OA_HOOK_TYPE: "post_tool_use",
|
|
259660
|
+
OA_TOOL_NAME: toolName,
|
|
259661
|
+
OA_TOOL_ARGS: JSON.stringify(args),
|
|
259662
|
+
OA_TOOL_RESULT: result.slice(0, 1e4),
|
|
259663
|
+
// Cap at 10KB
|
|
259664
|
+
OA_SESSION_ID: sessionId ?? ""
|
|
259665
|
+
});
|
|
259666
|
+
}
|
|
259667
|
+
}
|
|
259668
|
+
/**
|
|
259669
|
+
* Run post_tool_use_failure hooks (after failed execution).
|
|
259670
|
+
*/
|
|
259671
|
+
runPostToolUseFailure(toolName, args, error, sessionId) {
|
|
259672
|
+
const hooks = this.config.post_tool_use_failure ?? [];
|
|
259673
|
+
const matching = hooks.filter((h) => matchesToolFilter(h, toolName));
|
|
259674
|
+
for (const hook of matching) {
|
|
259675
|
+
executeHook(hook, {
|
|
259676
|
+
OA_HOOK_TYPE: "post_tool_use_failure",
|
|
259677
|
+
OA_TOOL_NAME: toolName,
|
|
259678
|
+
OA_TOOL_ARGS: JSON.stringify(args),
|
|
259679
|
+
OA_TOOL_ERROR: error.slice(0, 5e3),
|
|
259680
|
+
OA_SESSION_ID: sessionId ?? ""
|
|
259681
|
+
});
|
|
259682
|
+
}
|
|
259683
|
+
}
|
|
259684
|
+
/**
|
|
259685
|
+
* Run session lifecycle hooks.
|
|
259686
|
+
*/
|
|
259687
|
+
runSessionHook(type, sessionId) {
|
|
259688
|
+
const hooks = this.config[type] ?? [];
|
|
259689
|
+
for (const hook of hooks) {
|
|
259690
|
+
executeHook(hook, {
|
|
259691
|
+
OA_HOOK_TYPE: type,
|
|
259692
|
+
OA_SESSION_ID: sessionId ?? ""
|
|
259693
|
+
});
|
|
259694
|
+
}
|
|
259695
|
+
}
|
|
259696
|
+
};
|
|
259697
|
+
}
|
|
259698
|
+
});
|
|
259699
|
+
|
|
259700
|
+
// packages/orchestrator/dist/app-state.js
|
|
259701
|
+
function createAppState(opts) {
|
|
259702
|
+
return {
|
|
259703
|
+
// Session identity
|
|
259704
|
+
sessionId: opts?.sessionId ?? `session-${Date.now()}`,
|
|
259705
|
+
sessionStartTime: Date.now(),
|
|
259706
|
+
totalTurns: 0,
|
|
259707
|
+
// Model & context
|
|
259708
|
+
model: opts?.model ?? "",
|
|
259709
|
+
modelTier: opts?.modelTier ?? "medium",
|
|
259710
|
+
contextWindowSize: opts?.contextWindowSize ?? 0,
|
|
259711
|
+
maxOutputTokens: 16384,
|
|
259712
|
+
historyLength: 0,
|
|
259713
|
+
// Tool execution
|
|
259714
|
+
toolUseCountByName: /* @__PURE__ */ new Map(),
|
|
259715
|
+
lastToolDurationMs: 0,
|
|
259716
|
+
lastError: null,
|
|
259717
|
+
fileChangesSinceLastTurn: /* @__PURE__ */ new Set(),
|
|
259718
|
+
modifiedFilesSinceStart: /* @__PURE__ */ new Set(),
|
|
259719
|
+
// Tool decisions
|
|
259720
|
+
toolDecisions: [],
|
|
259721
|
+
toolDecisionMaxHistory: 500,
|
|
259722
|
+
// Cost tracking
|
|
259723
|
+
costState: {
|
|
259724
|
+
totalInputTokens: 0,
|
|
259725
|
+
totalOutputTokens: 0,
|
|
259726
|
+
totalCostUsd: 0,
|
|
259727
|
+
cacheHits: 0,
|
|
259728
|
+
cacheMisses: 0,
|
|
259729
|
+
taskCount: 0
|
|
259730
|
+
},
|
|
259731
|
+
// MCP
|
|
259732
|
+
mcpConnections: [],
|
|
259733
|
+
// Plugins
|
|
259734
|
+
loadedPlugins: [],
|
|
259735
|
+
// Skills
|
|
259736
|
+
discoveredSkillNames: /* @__PURE__ */ new Set(),
|
|
259737
|
+
// Nexus
|
|
259738
|
+
nexusConnectionStatus: "disconnected",
|
|
259739
|
+
// Agent tasks
|
|
259740
|
+
agentTasks: /* @__PURE__ */ new Map(),
|
|
259741
|
+
// Hooks
|
|
259742
|
+
hookExecutionHistory: [],
|
|
259743
|
+
// Speculative execution
|
|
259744
|
+
speculativeExecution: {
|
|
259745
|
+
enabled: false,
|
|
259746
|
+
lastHit: false,
|
|
259747
|
+
attempts: 0,
|
|
259748
|
+
hits: 0
|
|
259749
|
+
},
|
|
259750
|
+
// UI
|
|
259751
|
+
verbose: opts?.verbose ?? false,
|
|
259752
|
+
spinnerTip: "",
|
|
259753
|
+
expandedView: false
|
|
259754
|
+
};
|
|
259755
|
+
}
|
|
259756
|
+
function recordToolDecision(state, decision) {
|
|
259757
|
+
state.toolDecisions.push({ ...decision, timestamp: Date.now() });
|
|
259758
|
+
if (state.toolDecisions.length > state.toolDecisionMaxHistory) {
|
|
259759
|
+
state.toolDecisions.splice(0, state.toolDecisions.length - state.toolDecisionMaxHistory);
|
|
259760
|
+
}
|
|
259761
|
+
}
|
|
259762
|
+
function recordToolExecution(state, toolName, durationMs, success, filePath) {
|
|
259763
|
+
state.toolUseCountByName.set(toolName, (state.toolUseCountByName.get(toolName) ?? 0) + 1);
|
|
259764
|
+
state.lastToolDurationMs = durationMs;
|
|
259765
|
+
if (!success) {
|
|
259766
|
+
state.lastError = `${toolName} failed`;
|
|
259767
|
+
}
|
|
259768
|
+
if (filePath && ["file_write", "file_edit", "batch_edit", "file_patch", "notebook_edit"].includes(toolName)) {
|
|
259769
|
+
state.fileChangesSinceLastTurn.add(filePath);
|
|
259770
|
+
state.modifiedFilesSinceStart.add(filePath);
|
|
259771
|
+
}
|
|
259772
|
+
}
|
|
259773
|
+
function clearTurnState(state) {
|
|
259774
|
+
state.fileChangesSinceLastTurn.clear();
|
|
259775
|
+
state.totalTurns++;
|
|
259776
|
+
}
|
|
259777
|
+
function recordTokenUsage(state, inputTokens, outputTokens, costUsd, cacheHit) {
|
|
259778
|
+
state.costState.totalInputTokens += inputTokens;
|
|
259779
|
+
state.costState.totalOutputTokens += outputTokens;
|
|
259780
|
+
state.costState.totalCostUsd += costUsd;
|
|
259781
|
+
if (cacheHit)
|
|
259782
|
+
state.costState.cacheHits++;
|
|
259783
|
+
else
|
|
259784
|
+
state.costState.cacheMisses++;
|
|
259785
|
+
}
|
|
259786
|
+
var init_app_state = __esm({
|
|
259787
|
+
"packages/orchestrator/dist/app-state.js"() {
|
|
259788
|
+
"use strict";
|
|
259789
|
+
}
|
|
259790
|
+
});
|
|
259791
|
+
|
|
259380
259792
|
// packages/orchestrator/dist/agenticRunner.js
|
|
259381
259793
|
function repairJson(raw) {
|
|
259382
259794
|
if (!raw || typeof raw !== "string")
|
|
@@ -259450,6 +259862,9 @@ var init_agenticRunner = __esm({
|
|
|
259450
259862
|
init_promptLoader();
|
|
259451
259863
|
init_pressure_gate();
|
|
259452
259864
|
init_dist4();
|
|
259865
|
+
init_tool_batching();
|
|
259866
|
+
init_hooks();
|
|
259867
|
+
init_app_state();
|
|
259453
259868
|
SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
|
|
259454
259869
|
SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
|
|
259455
259870
|
SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
|
|
@@ -259467,6 +259882,8 @@ var init_agenticRunner = __esm({
|
|
|
259467
259882
|
_sudoResolve = null;
|
|
259468
259883
|
_pendingCompaction = null;
|
|
259469
259884
|
_skillCompactionStrategy = null;
|
|
259885
|
+
_hookManager = new HookManager();
|
|
259886
|
+
_appState = createAppState();
|
|
259470
259887
|
// -- Task State Tracking (Priority 3) --
|
|
259471
259888
|
_taskState = {
|
|
259472
259889
|
goal: "",
|
|
@@ -259741,6 +260158,14 @@ ${this.options.dynamicContext}`,
|
|
|
259741
260158
|
get isPaused() {
|
|
259742
260159
|
return this._paused;
|
|
259743
260160
|
}
|
|
260161
|
+
/** Configure hook chains for tool execution (WO-HOOK-01) */
|
|
260162
|
+
setHooks(config) {
|
|
260163
|
+
this._hookManager.setConfig(config);
|
|
260164
|
+
}
|
|
260165
|
+
/** Get the current application state snapshot (WO-STATE-01) */
|
|
260166
|
+
get appState() {
|
|
260167
|
+
return this._appState;
|
|
260168
|
+
}
|
|
259744
260169
|
/**
|
|
259745
260170
|
* Request manual context compaction at the next turn boundary.
|
|
259746
260171
|
* The strategy controls how aggressively context is compressed:
|
|
@@ -259851,6 +260276,14 @@ Respond with your assessment, then take action.`;
|
|
|
259851
260276
|
this._fileRegistry.clear();
|
|
259852
260277
|
this._memexArchive.clear();
|
|
259853
260278
|
this._sessionId = `session-${Date.now()}`;
|
|
260279
|
+
this._appState = createAppState({
|
|
260280
|
+
sessionId: this._sessionId,
|
|
260281
|
+
model: this.backend.model ?? "",
|
|
260282
|
+
modelTier: this.options.modelTier ?? "medium",
|
|
260283
|
+
contextWindowSize: this.options.contextWindowSize ?? 0,
|
|
260284
|
+
verbose: false
|
|
260285
|
+
});
|
|
260286
|
+
this._hookManager.runSessionHook("session_start", this._sessionId);
|
|
259854
260287
|
const contextComposition = this.assembleContext(task, context);
|
|
259855
260288
|
const systemPrompt = contextComposition.assembled;
|
|
259856
260289
|
this.emit({
|
|
@@ -259918,6 +260351,7 @@ TASK: ${task}` : task;
|
|
|
259918
260351
|
toolCallBudget.set(tool, budget);
|
|
259919
260352
|
}
|
|
259920
260353
|
for (let turn = 0; turn < this.options.maxTurns; turn++) {
|
|
260354
|
+
clearTurnState(this._appState);
|
|
259921
260355
|
if (this._paused) {
|
|
259922
260356
|
const shouldContinue = await this.waitIfPaused();
|
|
259923
260357
|
if (!shouldContinue) {
|
|
@@ -260244,6 +260678,12 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
260244
260678
|
totalTokens += response.usage?.totalTokens ?? 0;
|
|
260245
260679
|
promptTokens += response.usage?.promptTokens ?? 0;
|
|
260246
260680
|
completionTokens += response.usage?.completionTokens ?? 0;
|
|
260681
|
+
const turnPromptTokens = response.usage?.promptTokens ?? 0;
|
|
260682
|
+
const turnCompletionTokens = response.usage?.completionTokens ?? 0;
|
|
260683
|
+
if (turnPromptTokens || turnCompletionTokens) {
|
|
260684
|
+
recordTokenUsage(this._appState, turnPromptTokens, turnCompletionTokens, 0, false);
|
|
260685
|
+
}
|
|
260686
|
+
this._appState.historyLength = messages2.length;
|
|
260247
260687
|
const choiceContent = response.choices[0]?.message?.content ?? "";
|
|
260248
260688
|
const choiceArgs = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
260249
260689
|
estimatedTokens += Math.ceil((choiceContent.length + choiceArgs.length) / 4);
|
|
@@ -260300,25 +260740,10 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
260300
260740
|
function: { name: tc.name, arguments: JSON.stringify(tc.arguments) }
|
|
260301
260741
|
}))
|
|
260302
260742
|
});
|
|
260303
|
-
const PARALLEL_SAFE = /* @__PURE__ */ new Set([
|
|
260304
|
-
"file_read",
|
|
260305
|
-
"grep_search",
|
|
260306
|
-
"find_files",
|
|
260307
|
-
"list_directory",
|
|
260308
|
-
"web_fetch",
|
|
260309
|
-
"web_search",
|
|
260310
|
-
"web_crawl",
|
|
260311
|
-
"memory_read",
|
|
260312
|
-
"task_status",
|
|
260313
|
-
"task_output",
|
|
260314
|
-
"image_read",
|
|
260315
|
-
"screenshot",
|
|
260316
|
-
"ocr",
|
|
260317
|
-
"browser_action"
|
|
260318
|
-
]);
|
|
260319
260743
|
const executeSingle = async (tc) => {
|
|
260320
260744
|
if (this.aborted)
|
|
260321
260745
|
return null;
|
|
260746
|
+
const toolStart = performance.now();
|
|
260322
260747
|
toolCallCount++;
|
|
260323
260748
|
const argsKey = Object.entries(tc.arguments ?? {}).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 80) : JSON.stringify(v)}`).join(",");
|
|
260324
260749
|
toolCallLog.push({ name: tc.name, argsKey });
|
|
@@ -260419,10 +260844,24 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
260419
260844
|
this.emit({ type: "status", content: `\u26A0\uFE0F ${warning}`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
260420
260845
|
pendingConstraintWarnings.push(warning);
|
|
260421
260846
|
}
|
|
260422
|
-
|
|
260423
|
-
|
|
260424
|
-
|
|
260425
|
-
|
|
260847
|
+
const hookCheck = this._hookManager.runPreToolUse(tc.name, tc.arguments, this._sessionId);
|
|
260848
|
+
if (!hookCheck.allowed) {
|
|
260849
|
+
result = { success: false, output: "", error: `Blocked by hook: ${hookCheck.reason}` };
|
|
260850
|
+
recordToolDecision(this._appState, {
|
|
260851
|
+
toolName: tc.name,
|
|
260852
|
+
decision: "deny",
|
|
260853
|
+
reason: hookCheck.reason ?? "hook",
|
|
260854
|
+
source: "hook"
|
|
260855
|
+
});
|
|
260856
|
+
} else {
|
|
260857
|
+
const finalArgs = hookCheck.modifiedArgs ?? tc.arguments;
|
|
260858
|
+
try {
|
|
260859
|
+
result = await tool.execute(finalArgs);
|
|
260860
|
+
this._hookManager.runPostToolUse(tc.name, finalArgs, (result.output ?? "").slice(0, 2e3), this._sessionId);
|
|
260861
|
+
} catch (err) {
|
|
260862
|
+
result = { success: false, output: "", error: err instanceof Error ? err.message : String(err) };
|
|
260863
|
+
this._hookManager.runPostToolUseFailure(tc.name, finalArgs, result.error ?? "", this._sessionId);
|
|
260864
|
+
}
|
|
260426
260865
|
}
|
|
260427
260866
|
}
|
|
260428
260867
|
}
|
|
@@ -260492,6 +260931,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
260492
260931
|
});
|
|
260493
260932
|
this._taskState.toolCallCount++;
|
|
260494
260933
|
const filePath = typeof tc.arguments?.path === "string" ? tc.arguments.path : "";
|
|
260934
|
+
recordToolExecution(this._appState, tc.name, performance.now() - toolStart, result.success, filePath || void 0);
|
|
260495
260935
|
if (tc.name === "file_read" || tc.name === "list_directory" || tc.name === "find_files" || tc.name === "grep_search") {
|
|
260496
260936
|
this._taskState.currentStep = `exploring: ${filePath || String(tc.arguments?.pattern ?? tc.arguments?.path ?? "").slice(0, 60)}`;
|
|
260497
260937
|
} else if (tc.name === "file_write" || tc.name === "file_edit" || tc.name === "batch_edit") {
|
|
@@ -260575,46 +261015,36 @@ Then use file_read on individual FILES inside it.`);
|
|
|
260575
261015
|
}
|
|
260576
261016
|
return { tc, output };
|
|
260577
261017
|
};
|
|
260578
|
-
const
|
|
260579
|
-
const
|
|
260580
|
-
|
|
260581
|
-
|
|
260582
|
-
|
|
260583
|
-
|
|
260584
|
-
|
|
260585
|
-
|
|
260586
|
-
}
|
|
260587
|
-
}
|
|
260588
|
-
if (parallelBatch2.length > 1) {
|
|
260589
|
-
const results = await Promise.allSettled(parallelBatch2.map((tc) => executeSingle(tc)));
|
|
260590
|
-
for (const settled of results) {
|
|
260591
|
-
if (settled.status === "fulfilled" && settled.value) {
|
|
260592
|
-
const toolMsg = this.buildToolMessage(settled.value.output, settled.value.tc.id);
|
|
260593
|
-
messages2.push(toolMsg);
|
|
260594
|
-
}
|
|
260595
|
-
}
|
|
260596
|
-
} else if (parallelBatch2.length === 1) {
|
|
260597
|
-
const r2 = await executeSingle(parallelBatch2[0]);
|
|
260598
|
-
if (r2) {
|
|
260599
|
-
messages2.push(this.buildToolMessage(r2.output, r2.tc.id));
|
|
260600
|
-
}
|
|
260601
|
-
}
|
|
260602
|
-
for (const tc of sequentialBatch) {
|
|
261018
|
+
const rawToolCalls = msg.toolCalls;
|
|
261019
|
+
const batchToolCalls = rawToolCalls.map((tc) => ({
|
|
261020
|
+
name: tc.name,
|
|
261021
|
+
args: tc.arguments,
|
|
261022
|
+
id: tc.id
|
|
261023
|
+
}));
|
|
261024
|
+
const batches = partitionToolCalls(batchToolCalls);
|
|
261025
|
+
for (const batch2 of batches) {
|
|
260603
261026
|
if (this.aborted)
|
|
260604
261027
|
break;
|
|
260605
|
-
const
|
|
260606
|
-
|
|
260607
|
-
|
|
260608
|
-
}
|
|
260609
|
-
|
|
260610
|
-
|
|
260611
|
-
|
|
260612
|
-
|
|
260613
|
-
|
|
260614
|
-
|
|
261028
|
+
const results = await executeBatch(batch2, async (call) => {
|
|
261029
|
+
const originalTc = rawToolCalls.find((tc) => tc.id === call.id);
|
|
261030
|
+
return executeSingle(originalTc);
|
|
261031
|
+
}, 5);
|
|
261032
|
+
for (const r2 of results) {
|
|
261033
|
+
if (r2) {
|
|
261034
|
+
messages2.push(this.buildToolMessage(r2.output, r2.tc.id));
|
|
261035
|
+
if (r2.tc.name === "task_complete") {
|
|
261036
|
+
completed = true;
|
|
261037
|
+
summary = r2.tc.arguments.summary || "";
|
|
261038
|
+
if (summary && !this._assistantTextEmitted) {
|
|
261039
|
+
this.emit({ type: "assistant_text", content: summary, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
261040
|
+
this._assistantTextEmitted = true;
|
|
261041
|
+
}
|
|
261042
|
+
break;
|
|
261043
|
+
}
|
|
260615
261044
|
}
|
|
260616
|
-
break;
|
|
260617
261045
|
}
|
|
261046
|
+
if (completed)
|
|
261047
|
+
break;
|
|
260618
261048
|
}
|
|
260619
261049
|
if (completed)
|
|
260620
261050
|
break;
|
|
@@ -260887,6 +261317,12 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
260887
261317
|
totalTokens += response.usage?.totalTokens ?? 0;
|
|
260888
261318
|
promptTokens += response.usage?.promptTokens ?? 0;
|
|
260889
261319
|
completionTokens += response.usage?.completionTokens ?? 0;
|
|
261320
|
+
const bfTurnPrompt = response.usage?.promptTokens ?? 0;
|
|
261321
|
+
const bfTurnCompletion = response.usage?.completionTokens ?? 0;
|
|
261322
|
+
if (bfTurnPrompt || bfTurnCompletion) {
|
|
261323
|
+
recordTokenUsage(this._appState, bfTurnPrompt, bfTurnCompletion, 0, false);
|
|
261324
|
+
}
|
|
261325
|
+
this._appState.historyLength = messages2.length;
|
|
260890
261326
|
const choiceContent2 = response.choices[0]?.message?.content ?? "";
|
|
260891
261327
|
const choiceArgs2 = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
260892
261328
|
estimatedTokens += Math.ceil((choiceContent2.length + choiceArgs2.length) / 4);
|
|
@@ -261031,6 +261467,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
261031
261467
|
success: completed,
|
|
261032
261468
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
261033
261469
|
});
|
|
261470
|
+
this._hookManager.runSessionHook("session_end", this._sessionId);
|
|
261034
261471
|
return { completed, turns: messages2.filter((m2) => m2.role === "assistant").length, toolCalls: toolCallCount, totalTokens, promptTokens, completionTokens, estimatedTokens, summary, durationMs };
|
|
261035
261472
|
}
|
|
261036
261473
|
// -------------------------------------------------------------------------
|
|
@@ -262345,7 +262782,7 @@ ${transcript}`
|
|
|
262345
262782
|
const buffer2 = Buffer.from(rawBase64, "base64");
|
|
262346
262783
|
let resizedBase64 = null;
|
|
262347
262784
|
try {
|
|
262348
|
-
const { execSync:
|
|
262785
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
262349
262786
|
const { writeFileSync: writeFileSync34, readFileSync: readFileSync52, unlinkSync: unlinkSync13 } = await import("node:fs");
|
|
262350
262787
|
const { join: join86 } = await import("node:path");
|
|
262351
262788
|
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
@@ -262355,7 +262792,7 @@ ${transcript}`
|
|
|
262355
262792
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
262356
262793
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
262357
262794
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
262358
|
-
|
|
262795
|
+
execSync40(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
262359
262796
|
const resizedBuf = readFileSync52(tmpOut);
|
|
262360
262797
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
262361
262798
|
try {
|
|
@@ -262409,8 +262846,8 @@ ${transcript}`
|
|
|
262409
262846
|
if (!res.ok && model === "moondream" && res.status === 404) {
|
|
262410
262847
|
this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
262411
262848
|
try {
|
|
262412
|
-
const { execSync:
|
|
262413
|
-
|
|
262849
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
262850
|
+
execSync40("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
262414
262851
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
262415
262852
|
method: "POST",
|
|
262416
262853
|
headers: { "Content-Type": "application/json" },
|
|
@@ -264502,20 +264939,6 @@ var init_self_critique = __esm({
|
|
|
264502
264939
|
}
|
|
264503
264940
|
});
|
|
264504
264941
|
|
|
264505
|
-
// packages/orchestrator/dist/tool-batching.js
|
|
264506
|
-
var init_tool_batching = __esm({
|
|
264507
|
-
"packages/orchestrator/dist/tool-batching.js"() {
|
|
264508
|
-
"use strict";
|
|
264509
|
-
}
|
|
264510
|
-
});
|
|
264511
|
-
|
|
264512
|
-
// packages/orchestrator/dist/hooks.js
|
|
264513
|
-
var init_hooks = __esm({
|
|
264514
|
-
"packages/orchestrator/dist/hooks.js"() {
|
|
264515
|
-
"use strict";
|
|
264516
|
-
}
|
|
264517
|
-
});
|
|
264518
|
-
|
|
264519
264942
|
// packages/orchestrator/dist/skill-fork.js
|
|
264520
264943
|
var init_skill_fork = __esm({
|
|
264521
264944
|
"packages/orchestrator/dist/skill-fork.js"() {
|
|
@@ -264563,6 +264986,7 @@ var init_dist7 = __esm({
|
|
|
264563
264986
|
init_hooks();
|
|
264564
264987
|
init_skill_fork();
|
|
264565
264988
|
init_streaming_executor();
|
|
264989
|
+
init_app_state();
|
|
264566
264990
|
}
|
|
264567
264991
|
});
|
|
264568
264992
|
|
|
@@ -264577,7 +265001,7 @@ __export(listen_exports, {
|
|
|
264577
265001
|
isVideoPath: () => isVideoPath,
|
|
264578
265002
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
264579
265003
|
});
|
|
264580
|
-
import { spawn as spawn17, execSync as
|
|
265004
|
+
import { spawn as spawn17, execSync as execSync28 } from "node:child_process";
|
|
264581
265005
|
import { existsSync as existsSync37, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readdirSync as readdirSync9 } from "node:fs";
|
|
264582
265006
|
import { join as join53, dirname as dirname15 } from "node:path";
|
|
264583
265007
|
import { homedir as homedir14 } from "node:os";
|
|
@@ -264599,7 +265023,7 @@ function findMicCaptureCommand() {
|
|
|
264599
265023
|
const platform6 = process.platform;
|
|
264600
265024
|
if (platform6 === "linux") {
|
|
264601
265025
|
try {
|
|
264602
|
-
|
|
265026
|
+
execSync28("which arecord", { stdio: "pipe" });
|
|
264603
265027
|
return {
|
|
264604
265028
|
cmd: "arecord",
|
|
264605
265029
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -264609,7 +265033,7 @@ function findMicCaptureCommand() {
|
|
|
264609
265033
|
}
|
|
264610
265034
|
if (platform6 === "darwin") {
|
|
264611
265035
|
try {
|
|
264612
|
-
|
|
265036
|
+
execSync28("which sox", { stdio: "pipe" });
|
|
264613
265037
|
return {
|
|
264614
265038
|
cmd: "sox",
|
|
264615
265039
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -264618,7 +265042,7 @@ function findMicCaptureCommand() {
|
|
|
264618
265042
|
}
|
|
264619
265043
|
}
|
|
264620
265044
|
try {
|
|
264621
|
-
|
|
265045
|
+
execSync28("which ffmpeg", { stdio: "pipe" });
|
|
264622
265046
|
if (platform6 === "linux") {
|
|
264623
265047
|
return {
|
|
264624
265048
|
cmd: "ffmpeg",
|
|
@@ -264677,7 +265101,7 @@ function findLiveWhisperScript() {
|
|
|
264677
265101
|
return p2;
|
|
264678
265102
|
}
|
|
264679
265103
|
try {
|
|
264680
|
-
const globalRoot =
|
|
265104
|
+
const globalRoot = execSync28("npm root -g", {
|
|
264681
265105
|
encoding: "utf-8",
|
|
264682
265106
|
timeout: 5e3,
|
|
264683
265107
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -264710,7 +265134,7 @@ function ensureTranscribeCliBackground() {
|
|
|
264710
265134
|
return;
|
|
264711
265135
|
_bgInstallPromise = (async () => {
|
|
264712
265136
|
try {
|
|
264713
|
-
const globalRoot =
|
|
265137
|
+
const globalRoot = execSync28("npm root -g", {
|
|
264714
265138
|
encoding: "utf-8",
|
|
264715
265139
|
timeout: 5e3,
|
|
264716
265140
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -264916,7 +265340,7 @@ var init_listen = __esm({
|
|
|
264916
265340
|
}
|
|
264917
265341
|
if (!this.transcribeCliAvailable) {
|
|
264918
265342
|
try {
|
|
264919
|
-
|
|
265343
|
+
execSync28("which transcribe-cli", { stdio: "pipe" });
|
|
264920
265344
|
this.transcribeCliAvailable = true;
|
|
264921
265345
|
} catch {
|
|
264922
265346
|
this.transcribeCliAvailable = false;
|
|
@@ -264933,7 +265357,7 @@ var init_listen = __esm({
|
|
|
264933
265357
|
} catch {
|
|
264934
265358
|
}
|
|
264935
265359
|
try {
|
|
264936
|
-
const globalRoot =
|
|
265360
|
+
const globalRoot = execSync28("npm root -g", {
|
|
264937
265361
|
encoding: "utf-8",
|
|
264938
265362
|
timeout: 5e3,
|
|
264939
265363
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -264983,7 +265407,7 @@ var init_listen = __esm({
|
|
|
264983
265407
|
}
|
|
264984
265408
|
if (!tc) {
|
|
264985
265409
|
try {
|
|
264986
|
-
|
|
265410
|
+
execSync28("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
264987
265411
|
this.transcribeCliAvailable = null;
|
|
264988
265412
|
tc = await this.loadTranscribeCli();
|
|
264989
265413
|
} catch {
|
|
@@ -265166,7 +265590,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
265166
265590
|
}
|
|
265167
265591
|
if (!tc) {
|
|
265168
265592
|
try {
|
|
265169
|
-
|
|
265593
|
+
execSync28("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
265170
265594
|
this.transcribeCliAvailable = null;
|
|
265171
265595
|
tc = await this.loadTranscribeCli();
|
|
265172
265596
|
} catch {
|
|
@@ -265220,7 +265644,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
265220
265644
|
}
|
|
265221
265645
|
if (!tc) {
|
|
265222
265646
|
try {
|
|
265223
|
-
|
|
265647
|
+
execSync28("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
265224
265648
|
this.transcribeCliAvailable = null;
|
|
265225
265649
|
tc = await this.loadTranscribeCli();
|
|
265226
265650
|
} catch {
|
|
@@ -269734,7 +270158,7 @@ var init_render = __esm({
|
|
|
269734
270158
|
|
|
269735
270159
|
// packages/cli/dist/tui/voice-session.js
|
|
269736
270160
|
import { createServer as createServer3 } from "node:http";
|
|
269737
|
-
import { spawn as spawn18, execSync as
|
|
270161
|
+
import { spawn as spawn18, execSync as execSync29 } from "node:child_process";
|
|
269738
270162
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
269739
270163
|
function generateFrontendHTML() {
|
|
269740
270164
|
return `<!DOCTYPE html>
|
|
@@ -275759,7 +276183,7 @@ __export(personaplex_exports, {
|
|
|
275759
276183
|
import { existsSync as existsSync42, writeFileSync as writeFileSync18, readFileSync as readFileSync32, mkdirSync as mkdirSync17, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync13 } from "node:fs";
|
|
275760
276184
|
import { join as join59, dirname as dirname19 } from "node:path";
|
|
275761
276185
|
import { homedir as homedir16 } from "node:os";
|
|
275762
|
-
import { execSync as
|
|
276186
|
+
import { execSync as execSync30, spawn as spawn20, execFile as execFile7 } from "node:child_process";
|
|
275763
276187
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
275764
276188
|
function execAsync(cmd, opts = {}) {
|
|
275765
276189
|
return new Promise((resolve39, reject) => {
|
|
@@ -275796,7 +276220,7 @@ function detectJetson() {
|
|
|
275796
276220
|
try {
|
|
275797
276221
|
const model = readFileSync32("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
|
|
275798
276222
|
if (/jetson|orin|tegra/i.test(model)) {
|
|
275799
|
-
const memInfo =
|
|
276223
|
+
const memInfo = execSync30("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
275800
276224
|
const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
|
|
275801
276225
|
return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
|
|
275802
276226
|
}
|
|
@@ -275831,7 +276255,7 @@ function detectPersonaPlexCapability() {
|
|
|
275831
276255
|
};
|
|
275832
276256
|
}
|
|
275833
276257
|
try {
|
|
275834
|
-
const nvsmi =
|
|
276258
|
+
const nvsmi = execSync30("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
275835
276259
|
encoding: "utf8",
|
|
275836
276260
|
timeout: 5e3,
|
|
275837
276261
|
stdio: "pipe"
|
|
@@ -275844,7 +276268,7 @@ function detectPersonaPlexCapability() {
|
|
|
275844
276268
|
return { ...fail(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
|
|
275845
276269
|
}
|
|
275846
276270
|
try {
|
|
275847
|
-
|
|
276271
|
+
execSync30('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
275848
276272
|
timeout: 1e4,
|
|
275849
276273
|
stdio: "pipe"
|
|
275850
276274
|
});
|
|
@@ -275921,7 +276345,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
275921
276345
|
mkdirSync17(PERSONAPLEX_DIR, { recursive: true });
|
|
275922
276346
|
let arch2 = "";
|
|
275923
276347
|
try {
|
|
275924
|
-
arch2 =
|
|
276348
|
+
arch2 = execSync30("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
275925
276349
|
} catch {
|
|
275926
276350
|
}
|
|
275927
276351
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
@@ -275943,16 +276367,16 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
275943
276367
|
log22("Checking system dependencies (libopus)...");
|
|
275944
276368
|
try {
|
|
275945
276369
|
if (process.platform === "linux") {
|
|
275946
|
-
|
|
276370
|
+
execSync30("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
|
|
275947
276371
|
} else if (process.platform === "darwin") {
|
|
275948
|
-
|
|
276372
|
+
execSync30("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
|
|
275949
276373
|
}
|
|
275950
276374
|
} catch {
|
|
275951
276375
|
}
|
|
275952
276376
|
if (isAarch64) {
|
|
275953
276377
|
log22("ARM64: Checking Rust toolchain for sphn build...");
|
|
275954
276378
|
try {
|
|
275955
|
-
|
|
276379
|
+
execSync30("rustc --version", { timeout: 5e3, stdio: "pipe" });
|
|
275956
276380
|
} catch {
|
|
275957
276381
|
log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
|
|
275958
276382
|
try {
|
|
@@ -276009,7 +276433,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
276009
276433
|
}
|
|
276010
276434
|
const serverPy = join59(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
276011
276435
|
try {
|
|
276012
|
-
const sitePackages =
|
|
276436
|
+
const sitePackages = execSync30(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
276013
276437
|
encoding: "utf8",
|
|
276014
276438
|
timeout: 5e3,
|
|
276015
276439
|
stdio: "pipe"
|
|
@@ -276026,7 +276450,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
276026
276450
|
} catch {
|
|
276027
276451
|
}
|
|
276028
276452
|
try {
|
|
276029
|
-
const sitePackages =
|
|
276453
|
+
const sitePackages = execSync30(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
276030
276454
|
encoding: "utf8",
|
|
276031
276455
|
timeout: 5e3,
|
|
276032
276456
|
stdio: "pipe"
|
|
@@ -276124,7 +276548,7 @@ $2if filename.endswith(".safetensors"):`);
|
|
|
276124
276548
|
} catch {
|
|
276125
276549
|
}
|
|
276126
276550
|
try {
|
|
276127
|
-
const sitePackages2 =
|
|
276551
|
+
const sitePackages2 = execSync30(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
276128
276552
|
encoding: "utf8",
|
|
276129
276553
|
timeout: 5e3,
|
|
276130
276554
|
stdio: "pipe"
|
|
@@ -276253,11 +276677,11 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
276253
276677
|
if (tier === "nf4-distilled") {
|
|
276254
276678
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
276255
276679
|
try {
|
|
276256
|
-
const weightPath =
|
|
276680
|
+
const weightPath = execSync30(`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`, { encoding: "utf8", timeout: 6e4, stdio: "pipe" }).trim();
|
|
276257
276681
|
if (existsSync42(weightPath)) {
|
|
276258
276682
|
if (!existsSync42(cachedBf16)) {
|
|
276259
276683
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
276260
|
-
|
|
276684
|
+
execSync30(`"${venvPython2}" -c "
|
|
276261
276685
|
import torch; from safetensors.torch import save_file
|
|
276262
276686
|
state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
|
|
276263
276687
|
state = {k: v.to(torch.bfloat16) if v.is_floating_point() else v for k, v in state.items()}
|
|
@@ -276287,10 +276711,10 @@ print('Converted')
|
|
|
276287
276711
|
}
|
|
276288
276712
|
}
|
|
276289
276713
|
try {
|
|
276290
|
-
const weightPath =
|
|
276714
|
+
const weightPath = execSync30(`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`, { encoding: "utf8", timeout: 3e4, stdio: "pipe" }).trim();
|
|
276291
276715
|
if (existsSync42(dequantScript) && existsSync42(weightPath)) {
|
|
276292
276716
|
try {
|
|
276293
|
-
|
|
276717
|
+
execSync30(`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`, { timeout: 3e5, stdio: "pipe" });
|
|
276294
276718
|
if (existsSync42(cachedBf16)) {
|
|
276295
276719
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
276296
276720
|
log22(`Using dequantized cache: ${(statSync13(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
@@ -276300,13 +276724,13 @@ print('Converted')
|
|
|
276300
276724
|
}
|
|
276301
276725
|
}
|
|
276302
276726
|
try {
|
|
276303
|
-
const mimiPath =
|
|
276727
|
+
const mimiPath = execSync30(`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`, { encoding: "utf8", timeout: 3e4, stdio: "pipe" }).trim();
|
|
276304
276728
|
if (existsSync42(mimiPath))
|
|
276305
276729
|
extraArgs.push("--mimi-weight", mimiPath);
|
|
276306
276730
|
} catch {
|
|
276307
276731
|
}
|
|
276308
276732
|
try {
|
|
276309
|
-
const tokPath =
|
|
276733
|
+
const tokPath = execSync30(`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`, { encoding: "utf8", timeout: 3e4, stdio: "pipe" }).trim();
|
|
276310
276734
|
if (existsSync42(tokPath))
|
|
276311
276735
|
extraArgs.push("--tokenizer", tokPath);
|
|
276312
276736
|
} catch {
|
|
@@ -276330,7 +276754,7 @@ print('Converted')
|
|
|
276330
276754
|
if (!ollamaModel)
|
|
276331
276755
|
ollamaModel = "qwen3.5:4b";
|
|
276332
276756
|
try {
|
|
276333
|
-
const ollamaCheck =
|
|
276757
|
+
const ollamaCheck = execSync30("curl -s http://localhost:11434/api/tags", {
|
|
276334
276758
|
timeout: 3e3,
|
|
276335
276759
|
stdio: "pipe",
|
|
276336
276760
|
encoding: "utf8"
|
|
@@ -276407,7 +276831,7 @@ print('Converted')
|
|
|
276407
276831
|
return null;
|
|
276408
276832
|
}
|
|
276409
276833
|
try {
|
|
276410
|
-
|
|
276834
|
+
execSync30(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
|
|
276411
276835
|
timeout: 3e3,
|
|
276412
276836
|
stdio: "pipe",
|
|
276413
276837
|
encoding: "utf8"
|
|
@@ -276433,7 +276857,7 @@ function stopPersonaPlex() {
|
|
|
276433
276857
|
return;
|
|
276434
276858
|
try {
|
|
276435
276859
|
if (process.platform === "win32") {
|
|
276436
|
-
|
|
276860
|
+
execSync30(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
276437
276861
|
} else {
|
|
276438
276862
|
process.kill(pid, "SIGTERM");
|
|
276439
276863
|
}
|
|
@@ -276747,7 +277171,7 @@ __export(setup_exports, {
|
|
|
276747
277171
|
updateOllama: () => updateOllama
|
|
276748
277172
|
});
|
|
276749
277173
|
import * as readline from "node:readline";
|
|
276750
|
-
import { execSync as
|
|
277174
|
+
import { execSync as execSync31, spawn as spawn21, exec as exec2 } from "node:child_process";
|
|
276751
277175
|
import { promisify as promisify7 } from "node:util";
|
|
276752
277176
|
import { existsSync as existsSync43, writeFileSync as writeFileSync19, readFileSync as readFileSync33, appendFileSync as appendFileSync2, mkdirSync as mkdirSync18 } from "node:fs";
|
|
276753
277177
|
import { join as join60 } from "node:path";
|
|
@@ -276786,7 +277210,7 @@ function detectSystemSpecs() {
|
|
|
276786
277210
|
let gpuVramGB = 0;
|
|
276787
277211
|
let gpuName = "";
|
|
276788
277212
|
try {
|
|
276789
|
-
const memInfo =
|
|
277213
|
+
const memInfo = execSync31("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
276790
277214
|
encoding: "utf8",
|
|
276791
277215
|
timeout: 5e3
|
|
276792
277216
|
});
|
|
@@ -276806,7 +277230,7 @@ function detectSystemSpecs() {
|
|
|
276806
277230
|
} catch {
|
|
276807
277231
|
}
|
|
276808
277232
|
try {
|
|
276809
|
-
const nvidiaSmi =
|
|
277233
|
+
const nvidiaSmi = execSync31("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
276810
277234
|
const lines = nvidiaSmi.trim().split("\n");
|
|
276811
277235
|
if (lines.length > 0) {
|
|
276812
277236
|
for (const line of lines) {
|
|
@@ -276977,7 +277401,7 @@ function ensureCurl() {
|
|
|
276977
277401
|
for (const s2 of strategies) {
|
|
276978
277402
|
if (hasCmd(s2.check)) {
|
|
276979
277403
|
try {
|
|
276980
|
-
|
|
277404
|
+
execSync31(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
276981
277405
|
if (hasCmd("curl")) {
|
|
276982
277406
|
process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
|
|
276983
277407
|
`);
|
|
@@ -276991,7 +277415,7 @@ function ensureCurl() {
|
|
|
276991
277415
|
}
|
|
276992
277416
|
if (plat === "darwin") {
|
|
276993
277417
|
try {
|
|
276994
|
-
|
|
277418
|
+
execSync31("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
276995
277419
|
if (hasCmd("curl"))
|
|
276996
277420
|
return true;
|
|
276997
277421
|
} catch {
|
|
@@ -277026,7 +277450,7 @@ function installOllamaLinux() {
|
|
|
277026
277450
|
|
|
277027
277451
|
`);
|
|
277028
277452
|
try {
|
|
277029
|
-
|
|
277453
|
+
execSync31("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
277030
277454
|
stdio: "inherit",
|
|
277031
277455
|
timeout: 3e5
|
|
277032
277456
|
});
|
|
@@ -277054,7 +277478,7 @@ async function installOllamaMac(_rl) {
|
|
|
277054
277478
|
|
|
277055
277479
|
`);
|
|
277056
277480
|
try {
|
|
277057
|
-
|
|
277481
|
+
execSync31('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
277058
277482
|
if (!hasCmd("brew")) {
|
|
277059
277483
|
try {
|
|
277060
277484
|
const brewPrefix = existsSync43("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
@@ -277087,7 +277511,7 @@ async function installOllamaMac(_rl) {
|
|
|
277087
277511
|
|
|
277088
277512
|
`);
|
|
277089
277513
|
try {
|
|
277090
|
-
|
|
277514
|
+
execSync31("brew install ollama", {
|
|
277091
277515
|
stdio: "inherit",
|
|
277092
277516
|
timeout: 3e5
|
|
277093
277517
|
});
|
|
@@ -277114,7 +277538,7 @@ function installOllamaWindows() {
|
|
|
277114
277538
|
|
|
277115
277539
|
`);
|
|
277116
277540
|
try {
|
|
277117
|
-
|
|
277541
|
+
execSync31('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
277118
277542
|
stdio: "inherit",
|
|
277119
277543
|
timeout: 3e5
|
|
277120
277544
|
});
|
|
@@ -277195,7 +277619,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
277195
277619
|
}
|
|
277196
277620
|
function getOllamaVersion() {
|
|
277197
277621
|
try {
|
|
277198
|
-
const out =
|
|
277622
|
+
const out = execSync31("ollama --version", { encoding: "utf8", timeout: 5e3 });
|
|
277199
277623
|
const match = out.match(/(\d+\.\d+\.\d+)/);
|
|
277200
277624
|
return match ? match[1] : null;
|
|
277201
277625
|
} catch {
|
|
@@ -277246,7 +277670,7 @@ function updateOllama() {
|
|
|
277246
277670
|
return false;
|
|
277247
277671
|
}
|
|
277248
277672
|
try {
|
|
277249
|
-
|
|
277673
|
+
execSync31("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
277250
277674
|
stdio: "inherit",
|
|
277251
277675
|
timeout: 3e5
|
|
277252
277676
|
});
|
|
@@ -277257,7 +277681,7 @@ function updateOllama() {
|
|
|
277257
277681
|
}
|
|
277258
277682
|
function pullModelWithAutoUpdate(tag) {
|
|
277259
277683
|
try {
|
|
277260
|
-
|
|
277684
|
+
execSync31(`ollama pull ${tag}`, {
|
|
277261
277685
|
stdio: "inherit",
|
|
277262
277686
|
timeout: 36e5
|
|
277263
277687
|
// 1 hour max
|
|
@@ -277277,7 +277701,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
277277
277701
|
|
|
277278
277702
|
`);
|
|
277279
277703
|
try {
|
|
277280
|
-
|
|
277704
|
+
execSync31("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
277281
277705
|
stdio: "inherit",
|
|
277282
277706
|
timeout: 3e5
|
|
277283
277707
|
// 5 min max for install
|
|
@@ -277288,7 +277712,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
277288
277712
|
process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
|
|
277289
277713
|
|
|
277290
277714
|
`);
|
|
277291
|
-
|
|
277715
|
+
execSync31(`ollama pull ${tag}`, {
|
|
277292
277716
|
stdio: "inherit",
|
|
277293
277717
|
timeout: 36e5
|
|
277294
277718
|
});
|
|
@@ -277390,7 +277814,7 @@ function ensurePython3() {
|
|
|
277390
277814
|
if (plat === "darwin") {
|
|
277391
277815
|
if (hasCmd("brew")) {
|
|
277392
277816
|
try {
|
|
277393
|
-
|
|
277817
|
+
execSync31("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
277394
277818
|
if (hasCmd("python3")) {
|
|
277395
277819
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
|
|
277396
277820
|
`);
|
|
@@ -277403,7 +277827,7 @@ function ensurePython3() {
|
|
|
277403
277827
|
for (const s2 of strategies) {
|
|
277404
277828
|
if (hasCmd(s2.check)) {
|
|
277405
277829
|
try {
|
|
277406
|
-
|
|
277830
|
+
execSync31(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
277407
277831
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
277408
277832
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
|
|
277409
277833
|
`);
|
|
@@ -277419,11 +277843,11 @@ function ensurePython3() {
|
|
|
277419
277843
|
}
|
|
277420
277844
|
function checkPythonVenv() {
|
|
277421
277845
|
try {
|
|
277422
|
-
|
|
277846
|
+
execSync31("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
277423
277847
|
return true;
|
|
277424
277848
|
} catch {
|
|
277425
277849
|
try {
|
|
277426
|
-
|
|
277850
|
+
execSync31("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
277427
277851
|
return true;
|
|
277428
277852
|
} catch {
|
|
277429
277853
|
return false;
|
|
@@ -277442,7 +277866,7 @@ function ensurePythonVenv() {
|
|
|
277442
277866
|
for (const s2 of strategies) {
|
|
277443
277867
|
if (hasCmd(s2.check)) {
|
|
277444
277868
|
try {
|
|
277445
|
-
|
|
277869
|
+
execSync31(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
277446
277870
|
if (checkPythonVenv()) {
|
|
277447
277871
|
process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
|
|
277448
277872
|
`);
|
|
@@ -277869,7 +278293,7 @@ async function doSetup(config, rl) {
|
|
|
277869
278293
|
const modelfilePath = join60(modelDir2, `Modelfile.${customName}`);
|
|
277870
278294
|
writeFileSync19(modelfilePath, modelfileContent + "\n", "utf8");
|
|
277871
278295
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
277872
|
-
|
|
278296
|
+
execSync31(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
277873
278297
|
stdio: "pipe",
|
|
277874
278298
|
timeout: 12e4
|
|
277875
278299
|
});
|
|
@@ -277920,7 +278344,7 @@ function isFirstRun() {
|
|
|
277920
278344
|
function hasCmd(cmd) {
|
|
277921
278345
|
try {
|
|
277922
278346
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
277923
|
-
|
|
278347
|
+
execSync31(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
277924
278348
|
return true;
|
|
277925
278349
|
} catch {
|
|
277926
278350
|
return false;
|
|
@@ -277934,7 +278358,7 @@ function detectPkgManager() {
|
|
|
277934
278358
|
if (hasCmd("winget"))
|
|
277935
278359
|
return "winget";
|
|
277936
278360
|
try {
|
|
277937
|
-
|
|
278361
|
+
execSync31(`powershell -NoProfile -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"`, { stdio: "pipe", timeout: 12e4 });
|
|
277938
278362
|
if (hasCmd("choco"))
|
|
277939
278363
|
return "choco";
|
|
277940
278364
|
} catch {
|
|
@@ -277945,7 +278369,7 @@ function detectPkgManager() {
|
|
|
277945
278369
|
if (hasCmd("brew"))
|
|
277946
278370
|
return "brew";
|
|
277947
278371
|
try {
|
|
277948
|
-
|
|
278372
|
+
execSync31('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } });
|
|
277949
278373
|
if (hasCmd("brew"))
|
|
277950
278374
|
return "brew";
|
|
277951
278375
|
} catch {
|
|
@@ -277967,7 +278391,7 @@ function getVenvDir() {
|
|
|
277967
278391
|
}
|
|
277968
278392
|
function hasVenvModule() {
|
|
277969
278393
|
try {
|
|
277970
|
-
|
|
278394
|
+
execSync31("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
277971
278395
|
return true;
|
|
277972
278396
|
} catch {
|
|
277973
278397
|
return false;
|
|
@@ -277992,8 +278416,8 @@ function ensureVenv(log22) {
|
|
|
277992
278416
|
try {
|
|
277993
278417
|
mkdirSync18(join60(homedir17(), ".open-agents"), { recursive: true });
|
|
277994
278418
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
277995
|
-
|
|
277996
|
-
|
|
278419
|
+
execSync31(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
278420
|
+
execSync31(`"${pipPath}" install --upgrade pip`, {
|
|
277997
278421
|
stdio: "pipe",
|
|
277998
278422
|
timeout: 6e4
|
|
277999
278423
|
});
|
|
@@ -278006,7 +278430,7 @@ function ensureVenv(log22) {
|
|
|
278006
278430
|
}
|
|
278007
278431
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
278008
278432
|
try {
|
|
278009
|
-
|
|
278433
|
+
execSync31(`sudo -n ${cmd}`, {
|
|
278010
278434
|
stdio: "pipe",
|
|
278011
278435
|
timeout: timeoutMs,
|
|
278012
278436
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -278019,7 +278443,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
278019
278443
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
278020
278444
|
try {
|
|
278021
278445
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
278022
|
-
|
|
278446
|
+
execSync31(`sudo -S bash -c '${escaped}'`, {
|
|
278023
278447
|
input: password + "\n",
|
|
278024
278448
|
stdio: ["pipe", "pipe", "pipe"],
|
|
278025
278449
|
timeout: timeoutMs,
|
|
@@ -278122,7 +278546,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278122
278546
|
let winNeedsElevation = false;
|
|
278123
278547
|
if (process.platform === "win32") {
|
|
278124
278548
|
try {
|
|
278125
|
-
|
|
278549
|
+
execSync31("net session", { stdio: "pipe", timeout: 3e3 });
|
|
278126
278550
|
} catch {
|
|
278127
278551
|
winNeedsElevation = true;
|
|
278128
278552
|
log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
|
|
@@ -278170,9 +278594,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278170
278594
|
if (needsSudo) {
|
|
278171
278595
|
await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
|
|
278172
278596
|
} else if (winNeedsElevation) {
|
|
278173
|
-
|
|
278597
|
+
execSync31(`powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`, { stdio: "pipe", timeout: 18e4 });
|
|
278174
278598
|
} else {
|
|
278175
|
-
|
|
278599
|
+
execSync31(installCmd, { stdio: "pipe", timeout: 18e4 });
|
|
278176
278600
|
}
|
|
278177
278601
|
} catch (e2) {
|
|
278178
278602
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -278186,7 +278610,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278186
278610
|
if (!hasCmd(d2.binary) && pipPkg) {
|
|
278187
278611
|
try {
|
|
278188
278612
|
const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
|
|
278189
|
-
|
|
278613
|
+
execSync31(pipCmd, { stdio: "pipe", timeout: 12e4 });
|
|
278190
278614
|
lastError = "";
|
|
278191
278615
|
} catch (e2) {
|
|
278192
278616
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -278198,7 +278622,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278198
278622
|
}
|
|
278199
278623
|
if (process.platform === "win32" && !hasCmd(d2.binary)) {
|
|
278200
278624
|
try {
|
|
278201
|
-
const freshPath =
|
|
278625
|
+
const freshPath = execSync31(`powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`, { encoding: "utf8", timeout: 5e3, stdio: "pipe" }).trim();
|
|
278202
278626
|
if (freshPath)
|
|
278203
278627
|
process.env.PATH = freshPath;
|
|
278204
278628
|
} catch {
|
|
@@ -278242,7 +278666,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278242
278666
|
const venvCmds = {
|
|
278243
278667
|
apt: () => {
|
|
278244
278668
|
try {
|
|
278245
|
-
const pyVer =
|
|
278669
|
+
const pyVer = execSync31(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
278246
278670
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
278247
278671
|
} catch {
|
|
278248
278672
|
return "apt-get install -y python3-venv";
|
|
@@ -278271,12 +278695,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278271
278695
|
const venvPip2 = join60(venvBin, "pip");
|
|
278272
278696
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
278273
278697
|
try {
|
|
278274
|
-
|
|
278698
|
+
execSync31(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
278275
278699
|
if (existsSync43(venvMoondream)) {
|
|
278276
278700
|
log22("moondream-station installed successfully.");
|
|
278277
278701
|
} else {
|
|
278278
278702
|
try {
|
|
278279
|
-
const check =
|
|
278703
|
+
const check = execSync31(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
278280
278704
|
if (check.includes("moondream")) {
|
|
278281
278705
|
log22("moondream-station package installed.");
|
|
278282
278706
|
}
|
|
@@ -278293,7 +278717,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278293
278717
|
const venvPip2 = join60(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
278294
278718
|
let ocrStackInstalled = false;
|
|
278295
278719
|
try {
|
|
278296
|
-
|
|
278720
|
+
execSync31(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
278297
278721
|
ocrStackInstalled = true;
|
|
278298
278722
|
} catch {
|
|
278299
278723
|
}
|
|
@@ -278301,9 +278725,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
278301
278725
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
278302
278726
|
log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
278303
278727
|
try {
|
|
278304
|
-
|
|
278728
|
+
execSync31(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
278305
278729
|
try {
|
|
278306
|
-
|
|
278730
|
+
execSync31(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
278307
278731
|
log22("OCR Python stack installed successfully.");
|
|
278308
278732
|
} catch {
|
|
278309
278733
|
log22("OCR Python stack install completed but import verification failed.");
|
|
@@ -278337,7 +278761,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
278337
278761
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
278338
278762
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
278339
278763
|
try {
|
|
278340
|
-
|
|
278764
|
+
execSync31(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir17()}/.local/bin" && mv /tmp/cloudflared "${homedir17()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
278341
278765
|
if (!process.env.PATH?.includes(`${homedir17()}/.local/bin`)) {
|
|
278342
278766
|
process.env.PATH = `${homedir17()}/.local/bin:${process.env.PATH}`;
|
|
278343
278767
|
}
|
|
@@ -278348,7 +278772,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
278348
278772
|
} catch {
|
|
278349
278773
|
}
|
|
278350
278774
|
try {
|
|
278351
|
-
|
|
278775
|
+
execSync31(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
|
|
278352
278776
|
if (hasCmd("cloudflared")) {
|
|
278353
278777
|
log22("cloudflared installed.");
|
|
278354
278778
|
return true;
|
|
@@ -278357,7 +278781,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
278357
278781
|
}
|
|
278358
278782
|
} else if (os8 === "darwin") {
|
|
278359
278783
|
try {
|
|
278360
|
-
|
|
278784
|
+
execSync31("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
278361
278785
|
if (hasCmd("cloudflared")) {
|
|
278362
278786
|
log22("cloudflared installed via Homebrew.");
|
|
278363
278787
|
return true;
|
|
@@ -278445,7 +278869,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
278445
278869
|
mkdirSync18(modelDir2, { recursive: true });
|
|
278446
278870
|
const modelfilePath = join60(modelDir2, `Modelfile.${customName}`);
|
|
278447
278871
|
writeFileSync19(modelfilePath, modelfileContent + "\n", "utf8");
|
|
278448
|
-
|
|
278872
|
+
execSync31(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
278449
278873
|
stdio: "pipe",
|
|
278450
278874
|
timeout: 12e4
|
|
278451
278875
|
});
|
|
@@ -278531,7 +278955,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
278531
278955
|
}
|
|
278532
278956
|
async function ensureNeovim() {
|
|
278533
278957
|
try {
|
|
278534
|
-
const nvimPath =
|
|
278958
|
+
const nvimPath = execSync31("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
278535
278959
|
encoding: "utf8",
|
|
278536
278960
|
stdio: "pipe",
|
|
278537
278961
|
timeout: 5e3
|
|
@@ -278553,14 +278977,14 @@ async function ensureNeovim() {
|
|
|
278553
278977
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
278554
278978
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
278555
278979
|
try {
|
|
278556
|
-
|
|
278557
|
-
|
|
278980
|
+
execSync31(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
278981
|
+
execSync31(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
278558
278982
|
} catch (err) {
|
|
278559
278983
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
278560
278984
|
return null;
|
|
278561
278985
|
}
|
|
278562
278986
|
try {
|
|
278563
|
-
const ver =
|
|
278987
|
+
const ver = execSync31(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
278564
278988
|
console.log(` Installed: ${ver}`);
|
|
278565
278989
|
} catch {
|
|
278566
278990
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -278575,8 +278999,8 @@ async function ensureNeovim() {
|
|
|
278575
278999
|
if (hasCmd("brew")) {
|
|
278576
279000
|
console.log(" Installing Neovim via Homebrew...");
|
|
278577
279001
|
try {
|
|
278578
|
-
|
|
278579
|
-
const nvimPath =
|
|
279002
|
+
execSync31("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
279003
|
+
const nvimPath = execSync31("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
278580
279004
|
return nvimPath || null;
|
|
278581
279005
|
} catch {
|
|
278582
279006
|
console.log(" brew install neovim failed.");
|
|
@@ -278590,7 +279014,7 @@ async function ensureNeovim() {
|
|
|
278590
279014
|
if (hasCmd("choco")) {
|
|
278591
279015
|
console.log(" Installing Neovim via Chocolatey...");
|
|
278592
279016
|
try {
|
|
278593
|
-
|
|
279017
|
+
execSync31("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
278594
279018
|
return "nvim";
|
|
278595
279019
|
} catch {
|
|
278596
279020
|
console.log(" choco install neovim failed.");
|
|
@@ -278599,7 +279023,7 @@ async function ensureNeovim() {
|
|
|
278599
279023
|
if (hasCmd("winget")) {
|
|
278600
279024
|
console.log(" Installing Neovim via winget...");
|
|
278601
279025
|
try {
|
|
278602
|
-
|
|
279026
|
+
execSync31("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
278603
279027
|
stdio: "inherit",
|
|
278604
279028
|
timeout: 12e4
|
|
278605
279029
|
});
|
|
@@ -278845,7 +279269,7 @@ var init_drop_panel = __esm({
|
|
|
278845
279269
|
import { existsSync as existsSync45, unlinkSync as unlinkSync8 } from "node:fs";
|
|
278846
279270
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
278847
279271
|
import { join as join61 } from "node:path";
|
|
278848
|
-
import { execSync as
|
|
279272
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
278849
279273
|
function isNeovimActive() {
|
|
278850
279274
|
return _state !== null && !_state.cleanedUp;
|
|
278851
279275
|
}
|
|
@@ -278863,7 +279287,7 @@ async function startNeovimMode(opts) {
|
|
|
278863
279287
|
}
|
|
278864
279288
|
let nvimPath;
|
|
278865
279289
|
try {
|
|
278866
|
-
nvimPath =
|
|
279290
|
+
nvimPath = execSync32("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
278867
279291
|
if (!nvimPath)
|
|
278868
279292
|
throw new Error();
|
|
278869
279293
|
} catch {
|
|
@@ -280626,7 +281050,7 @@ __export(voice_exports, {
|
|
|
280626
281050
|
import { existsSync as existsSync47, mkdirSync as mkdirSync20, writeFileSync as writeFileSync21, readFileSync as readFileSync35, unlinkSync as unlinkSync9, readdirSync as readdirSync13, renameSync, statSync as statSync14 } from "node:fs";
|
|
280627
281051
|
import { join as join63, dirname as dirname20 } from "node:path";
|
|
280628
281052
|
import { homedir as homedir18, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
280629
|
-
import { execSync as
|
|
281053
|
+
import { execSync as execSync33, spawn as nodeSpawn } from "node:child_process";
|
|
280630
281054
|
import { createRequire as createRequire2 } from "node:module";
|
|
280631
281055
|
function sanitizeForTTS(text) {
|
|
280632
281056
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -282368,7 +282792,7 @@ var init_voice = __esm({
|
|
|
282368
282792
|
}
|
|
282369
282793
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
282370
282794
|
try {
|
|
282371
|
-
|
|
282795
|
+
execSync33(`which ${player}`, { stdio: "pipe" });
|
|
282372
282796
|
return [player, path5];
|
|
282373
282797
|
} catch {
|
|
282374
282798
|
}
|
|
@@ -282397,7 +282821,7 @@ var init_voice = __esm({
|
|
|
282397
282821
|
return this.python3Path;
|
|
282398
282822
|
for (const bin of ["python3", "python"]) {
|
|
282399
282823
|
try {
|
|
282400
|
-
const path5 =
|
|
282824
|
+
const path5 = execSync33(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
282401
282825
|
if (path5) {
|
|
282402
282826
|
this.python3Path = path5;
|
|
282403
282827
|
return path5;
|
|
@@ -282463,7 +282887,7 @@ var init_voice = __esm({
|
|
|
282463
282887
|
return false;
|
|
282464
282888
|
}
|
|
282465
282889
|
try {
|
|
282466
|
-
|
|
282890
|
+
execSync33(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
282467
282891
|
this.mlxInstalled = true;
|
|
282468
282892
|
return true;
|
|
282469
282893
|
} catch {
|
|
@@ -282524,11 +282948,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
282524
282948
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
282525
282949
|
].join("; ");
|
|
282526
282950
|
try {
|
|
282527
|
-
|
|
282951
|
+
execSync33(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
282528
282952
|
} catch (err) {
|
|
282529
282953
|
try {
|
|
282530
282954
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
282531
|
-
|
|
282955
|
+
execSync33(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
282532
282956
|
} catch (err2) {
|
|
282533
282957
|
return;
|
|
282534
282958
|
}
|
|
@@ -282592,11 +283016,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
282592
283016
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
282593
283017
|
].join("; ");
|
|
282594
283018
|
try {
|
|
282595
|
-
|
|
283019
|
+
execSync33(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
282596
283020
|
} catch {
|
|
282597
283021
|
try {
|
|
282598
283022
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
282599
|
-
|
|
283023
|
+
execSync33(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
282600
283024
|
} catch {
|
|
282601
283025
|
return null;
|
|
282602
283026
|
}
|
|
@@ -287907,7 +288331,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
287907
288331
|
}
|
|
287908
288332
|
}
|
|
287909
288333
|
async function handleParallel(arg, ctx3) {
|
|
287910
|
-
const { execSync:
|
|
288334
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
287911
288335
|
const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
|
|
287912
288336
|
const isRemote = ctx3.config.backendType === "nexus";
|
|
287913
288337
|
if (isRemote) {
|
|
@@ -287931,7 +288355,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
287931
288355
|
}
|
|
287932
288356
|
let systemdVal = "";
|
|
287933
288357
|
try {
|
|
287934
|
-
const out =
|
|
288358
|
+
const out = execSync40("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
287935
288359
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
287936
288360
|
if (match)
|
|
287937
288361
|
systemdVal = match[1];
|
|
@@ -287960,7 +288384,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
287960
288384
|
}
|
|
287961
288385
|
const isSystemd = (() => {
|
|
287962
288386
|
try {
|
|
287963
|
-
const out =
|
|
288387
|
+
const out = execSync40("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
287964
288388
|
return out === "active" || out === "inactive";
|
|
287965
288389
|
} catch {
|
|
287966
288390
|
return false;
|
|
@@ -287974,10 +288398,10 @@ async function handleParallel(arg, ctx3) {
|
|
|
287974
288398
|
const overrideContent = `[Service]
|
|
287975
288399
|
Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
287976
288400
|
`;
|
|
287977
|
-
|
|
287978
|
-
|
|
287979
|
-
|
|
287980
|
-
|
|
288401
|
+
execSync40(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
288402
|
+
execSync40(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
288403
|
+
execSync40("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
288404
|
+
execSync40("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
287981
288405
|
let ready = false;
|
|
287982
288406
|
for (let i2 = 0; i2 < 30 && !ready; i2++) {
|
|
287983
288407
|
await new Promise((r2) => setTimeout(r2, 500));
|
|
@@ -288004,7 +288428,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
288004
288428
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
|
|
288005
288429
|
try {
|
|
288006
288430
|
try {
|
|
288007
|
-
|
|
288431
|
+
execSync40("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
288008
288432
|
} catch {
|
|
288009
288433
|
}
|
|
288010
288434
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
@@ -289021,18 +289445,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
289021
289445
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
289022
289446
|
let copied = false;
|
|
289023
289447
|
try {
|
|
289024
|
-
const { execSync:
|
|
289448
|
+
const { execSync: execSync40 } = __require("node:child_process");
|
|
289025
289449
|
const platform6 = process.platform;
|
|
289026
289450
|
if (platform6 === "darwin") {
|
|
289027
|
-
|
|
289451
|
+
execSync40("pbcopy", { input: cmd, timeout: 3e3 });
|
|
289028
289452
|
copied = true;
|
|
289029
289453
|
} else if (platform6 === "win32") {
|
|
289030
|
-
|
|
289454
|
+
execSync40("clip", { input: cmd, timeout: 3e3 });
|
|
289031
289455
|
copied = true;
|
|
289032
289456
|
} else {
|
|
289033
289457
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
289034
289458
|
try {
|
|
289035
|
-
|
|
289459
|
+
execSync40(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
289036
289460
|
copied = true;
|
|
289037
289461
|
break;
|
|
289038
289462
|
} catch {
|
|
@@ -289124,7 +289548,7 @@ var init_commands = __esm({
|
|
|
289124
289548
|
// packages/cli/dist/tui/project-context.js
|
|
289125
289549
|
import { existsSync as existsSync49, readFileSync as readFileSync37, readdirSync as readdirSync15 } from "node:fs";
|
|
289126
289550
|
import { join as join65, basename as basename13 } from "node:path";
|
|
289127
|
-
import { execSync as
|
|
289551
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
289128
289552
|
import { homedir as homedir20, platform as platform4, release } from "node:os";
|
|
289129
289553
|
function getModelTier(modelName) {
|
|
289130
289554
|
const m2 = modelName.toLowerCase();
|
|
@@ -289170,19 +289594,19 @@ function loadProjectMap(repoRoot) {
|
|
|
289170
289594
|
}
|
|
289171
289595
|
function getGitInfo(repoRoot) {
|
|
289172
289596
|
try {
|
|
289173
|
-
|
|
289597
|
+
execSync34("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
289174
289598
|
} catch {
|
|
289175
289599
|
return "";
|
|
289176
289600
|
}
|
|
289177
289601
|
const lines = [];
|
|
289178
289602
|
try {
|
|
289179
|
-
const branch =
|
|
289603
|
+
const branch = execSync34("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
289180
289604
|
if (branch)
|
|
289181
289605
|
lines.push(`Branch: ${branch}`);
|
|
289182
289606
|
} catch {
|
|
289183
289607
|
}
|
|
289184
289608
|
try {
|
|
289185
|
-
const status =
|
|
289609
|
+
const status = execSync34("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
289186
289610
|
if (status) {
|
|
289187
289611
|
const changed = status.split("\n").length;
|
|
289188
289612
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -289192,7 +289616,7 @@ function getGitInfo(repoRoot) {
|
|
|
289192
289616
|
} catch {
|
|
289193
289617
|
}
|
|
289194
289618
|
try {
|
|
289195
|
-
const log22 =
|
|
289619
|
+
const log22 = execSync34("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
289196
289620
|
if (log22)
|
|
289197
289621
|
lines.push(`Recent commits:
|
|
289198
289622
|
${log22}`);
|
|
@@ -291988,7 +292412,7 @@ var init_promptLoader3 = __esm({
|
|
|
291988
292412
|
// packages/cli/dist/tui/dream-engine.js
|
|
291989
292413
|
import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync25, readFileSync as readFileSync41, existsSync as existsSync53, cpSync, rmSync as rmSync3, readdirSync as readdirSync17 } from "node:fs";
|
|
291990
292414
|
import { join as join70, basename as basename15 } from "node:path";
|
|
291991
|
-
import { execSync as
|
|
292415
|
+
import { execSync as execSync35 } from "node:child_process";
|
|
291992
292416
|
function loadAutoresearchMemory(repoRoot) {
|
|
291993
292417
|
const memoryPath = join70(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
291994
292418
|
if (!existsSync53(memoryPath))
|
|
@@ -292352,7 +292776,7 @@ var init_dream_engine = __esm({
|
|
|
292352
292776
|
}
|
|
292353
292777
|
}
|
|
292354
292778
|
try {
|
|
292355
|
-
const output =
|
|
292779
|
+
const output = execSync35(cmd, {
|
|
292356
292780
|
cwd: this.repoRoot,
|
|
292357
292781
|
timeout: 3e4,
|
|
292358
292782
|
encoding: "utf-8",
|
|
@@ -293129,17 +293553,17 @@ ${summaryResult}
|
|
|
293129
293553
|
try {
|
|
293130
293554
|
mkdirSync25(checkpointDir, { recursive: true });
|
|
293131
293555
|
try {
|
|
293132
|
-
const gitStatus =
|
|
293556
|
+
const gitStatus = execSync35("git status --porcelain", {
|
|
293133
293557
|
cwd: this.repoRoot,
|
|
293134
293558
|
encoding: "utf-8",
|
|
293135
293559
|
timeout: 1e4
|
|
293136
293560
|
});
|
|
293137
|
-
const gitDiff =
|
|
293561
|
+
const gitDiff = execSync35("git diff", {
|
|
293138
293562
|
cwd: this.repoRoot,
|
|
293139
293563
|
encoding: "utf-8",
|
|
293140
293564
|
timeout: 1e4
|
|
293141
293565
|
});
|
|
293142
|
-
const gitHash =
|
|
293566
|
+
const gitHash = execSync35("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
293143
293567
|
cwd: this.repoRoot,
|
|
293144
293568
|
encoding: "utf-8",
|
|
293145
293569
|
timeout: 5e3
|
|
@@ -296964,7 +297388,7 @@ __export(text_selection_exports, {
|
|
|
296964
297388
|
stripAnsi: () => stripAnsi3,
|
|
296965
297389
|
visibleLength: () => visibleLength
|
|
296966
297390
|
});
|
|
296967
|
-
import { execSync as
|
|
297391
|
+
import { execSync as execSync36 } from "node:child_process";
|
|
296968
297392
|
function stripAnsi3(s2) {
|
|
296969
297393
|
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
296970
297394
|
}
|
|
@@ -296975,16 +297399,16 @@ function copyText(text) {
|
|
|
296975
297399
|
try {
|
|
296976
297400
|
const platform6 = process.platform;
|
|
296977
297401
|
if (platform6 === "darwin") {
|
|
296978
|
-
|
|
297402
|
+
execSync36("pbcopy", { input: text, timeout: 3e3 });
|
|
296979
297403
|
return true;
|
|
296980
297404
|
}
|
|
296981
297405
|
if (platform6 === "win32") {
|
|
296982
|
-
|
|
297406
|
+
execSync36("clip", { input: text, timeout: 3e3 });
|
|
296983
297407
|
return true;
|
|
296984
297408
|
}
|
|
296985
297409
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
296986
297410
|
try {
|
|
296987
|
-
|
|
297411
|
+
execSync36(tool, { input: text, timeout: 3e3 });
|
|
296988
297412
|
return true;
|
|
296989
297413
|
} catch {
|
|
296990
297414
|
continue;
|
|
@@ -296993,10 +297417,10 @@ function copyText(text) {
|
|
|
296993
297417
|
if (!_clipboardAutoInstallAttempted) {
|
|
296994
297418
|
_clipboardAutoInstallAttempted = true;
|
|
296995
297419
|
try {
|
|
296996
|
-
|
|
297420
|
+
execSync36("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
296997
297421
|
try {
|
|
296998
|
-
|
|
296999
|
-
|
|
297422
|
+
execSync36("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
297423
|
+
execSync36("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
297000
297424
|
return true;
|
|
297001
297425
|
} catch {
|
|
297002
297426
|
}
|
|
@@ -302088,7 +302512,7 @@ var init_profiles = __esm({
|
|
|
302088
302512
|
});
|
|
302089
302513
|
|
|
302090
302514
|
// packages/cli/dist/docker.js
|
|
302091
|
-
import { execSync as
|
|
302515
|
+
import { execSync as execSync37, spawn as spawn22 } from "node:child_process";
|
|
302092
302516
|
import { existsSync as existsSync61, mkdirSync as mkdirSync31, writeFileSync as writeFileSync29 } from "node:fs";
|
|
302093
302517
|
import { join as join78, resolve as resolve33, dirname as dirname22 } from "node:path";
|
|
302094
302518
|
import { homedir as homedir22 } from "node:os";
|
|
@@ -302109,7 +302533,7 @@ function getDockerDir() {
|
|
|
302109
302533
|
}
|
|
302110
302534
|
function isDockerAvailable() {
|
|
302111
302535
|
try {
|
|
302112
|
-
|
|
302536
|
+
execSync37("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
302113
302537
|
return true;
|
|
302114
302538
|
} catch {
|
|
302115
302539
|
return false;
|
|
@@ -302117,7 +302541,7 @@ function isDockerAvailable() {
|
|
|
302117
302541
|
}
|
|
302118
302542
|
function isDockerInstalled() {
|
|
302119
302543
|
try {
|
|
302120
|
-
|
|
302544
|
+
execSync37("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
302121
302545
|
return true;
|
|
302122
302546
|
} catch {
|
|
302123
302547
|
return false;
|
|
@@ -302142,31 +302566,31 @@ async function ensureDocker() {
|
|
|
302142
302566
|
}
|
|
302143
302567
|
try {
|
|
302144
302568
|
console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
|
|
302145
|
-
|
|
302569
|
+
execSync37("curl -fsSL https://get.docker.com | sh", {
|
|
302146
302570
|
stdio: "inherit",
|
|
302147
302571
|
timeout: 3e5
|
|
302148
302572
|
});
|
|
302149
302573
|
const user = process.env["USER"] || process.env["LOGNAME"];
|
|
302150
302574
|
if (user) {
|
|
302151
302575
|
try {
|
|
302152
|
-
|
|
302576
|
+
execSync37(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
|
|
302153
302577
|
} catch {
|
|
302154
302578
|
}
|
|
302155
302579
|
}
|
|
302156
302580
|
try {
|
|
302157
|
-
|
|
302581
|
+
execSync37("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
|
|
302158
302582
|
} catch {
|
|
302159
302583
|
}
|
|
302160
302584
|
try {
|
|
302161
|
-
|
|
302162
|
-
const runtimes =
|
|
302585
|
+
execSync37("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
|
|
302586
|
+
const runtimes = execSync37("docker info --format '{{json .Runtimes}}'", {
|
|
302163
302587
|
stdio: "pipe",
|
|
302164
302588
|
timeout: 5e3
|
|
302165
302589
|
}).toString();
|
|
302166
302590
|
if (!runtimes.includes("nvidia")) {
|
|
302167
302591
|
console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
|
|
302168
302592
|
try {
|
|
302169
|
-
|
|
302593
|
+
execSync37(`
|
|
302170
302594
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
302171
302595
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
302172
302596
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -302196,7 +302620,7 @@ async function ensureDocker() {
|
|
|
302196
302620
|
}
|
|
302197
302621
|
async function ensureNvidiaToolkit() {
|
|
302198
302622
|
try {
|
|
302199
|
-
|
|
302623
|
+
execSync37("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
|
|
302200
302624
|
} catch {
|
|
302201
302625
|
return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
|
|
302202
302626
|
}
|
|
@@ -302207,7 +302631,7 @@ async function ensureNvidiaToolkit() {
|
|
|
302207
302631
|
return { ok: false, message: "Auto-install only supported on Linux. Install manually: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html" };
|
|
302208
302632
|
}
|
|
302209
302633
|
try {
|
|
302210
|
-
|
|
302634
|
+
execSync37(`
|
|
302211
302635
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
302212
302636
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
302213
302637
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -302221,7 +302645,7 @@ async function ensureNvidiaToolkit() {
|
|
|
302221
302645
|
}
|
|
302222
302646
|
function isOaImageBuilt() {
|
|
302223
302647
|
try {
|
|
302224
|
-
const out =
|
|
302648
|
+
const out = execSync37(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
|
|
302225
302649
|
stdio: "pipe",
|
|
302226
302650
|
timeout: 5e3
|
|
302227
302651
|
}).toString().trim();
|
|
@@ -302245,7 +302669,7 @@ async function ensureOaImage(force = false) {
|
|
|
302245
302669
|
}
|
|
302246
302670
|
try {
|
|
302247
302671
|
console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
|
|
302248
|
-
|
|
302672
|
+
execSync37(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
|
|
302249
302673
|
stdio: "inherit",
|
|
302250
302674
|
timeout: 6e5
|
|
302251
302675
|
// 10 min
|
|
@@ -302319,11 +302743,11 @@ exec "$@"
|
|
|
302319
302743
|
}
|
|
302320
302744
|
function hasNvidiaGpu() {
|
|
302321
302745
|
try {
|
|
302322
|
-
|
|
302746
|
+
execSync37("nvidia-smi --query-gpu=name --format=csv,noheader", {
|
|
302323
302747
|
stdio: "pipe",
|
|
302324
302748
|
timeout: 5e3
|
|
302325
302749
|
});
|
|
302326
|
-
const runtimes =
|
|
302750
|
+
const runtimes = execSync37("docker info --format '{{json .Runtimes}}'", {
|
|
302327
302751
|
stdio: "pipe",
|
|
302328
302752
|
timeout: 5e3
|
|
302329
302753
|
}).toString();
|
|
@@ -302396,7 +302820,7 @@ import * as https3 from "node:https";
|
|
|
302396
302820
|
import { createRequire as createRequire4 } from "node:module";
|
|
302397
302821
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
302398
302822
|
import { dirname as dirname23, join as join79, resolve as resolve34 } from "node:path";
|
|
302399
|
-
import { spawn as spawn23, execSync as
|
|
302823
|
+
import { spawn as spawn23, execSync as execSync38 } from "node:child_process";
|
|
302400
302824
|
import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync30, readFileSync as readFileSync49, readdirSync as readdirSync23, existsSync as existsSync62 } from "node:fs";
|
|
302401
302825
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
302402
302826
|
function getVersion3() {
|
|
@@ -303424,7 +303848,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
303424
303848
|
const containerName = `oa-${id}`;
|
|
303425
303849
|
if (job.sandbox === "container") {
|
|
303426
303850
|
try {
|
|
303427
|
-
|
|
303851
|
+
execSync38(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
|
|
303428
303852
|
} catch {
|
|
303429
303853
|
}
|
|
303430
303854
|
}
|
|
@@ -304364,7 +304788,7 @@ import { createRequire as createRequire5 } from "node:module";
|
|
|
304364
304788
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
304365
304789
|
import { readFileSync as readFileSync50, writeFileSync as writeFileSync31, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync33 } from "node:fs";
|
|
304366
304790
|
import { existsSync as existsSync63 } from "node:fs";
|
|
304367
|
-
import { execSync as
|
|
304791
|
+
import { execSync as execSync39 } from "node:child_process";
|
|
304368
304792
|
import { homedir as homedir23 } from "node:os";
|
|
304369
304793
|
function formatTimeAgo(date) {
|
|
304370
304794
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -304559,6 +304983,8 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
304559
304983
|
];
|
|
304560
304984
|
return [
|
|
304561
304985
|
...executionTools.map(adaptTool6),
|
|
304986
|
+
// MCP tools (dynamic — from connected MCP servers, WO-MCP-01)
|
|
304987
|
+
..._mcpTools.map(adaptTool6),
|
|
304562
304988
|
createSubAgentTool(config, repoRoot, contextWindowSize),
|
|
304563
304989
|
createTaskCompleteTool(modelTier)
|
|
304564
304990
|
];
|
|
@@ -305113,6 +305539,21 @@ Content: ${content.slice(0, 500)}` }
|
|
|
305113
305539
|
return { status, findings };
|
|
305114
305540
|
});
|
|
305115
305541
|
}
|
|
305542
|
+
const skillExecTool = tools.find((t2) => t2.name === "skill_execute");
|
|
305543
|
+
if (skillExecTool && "setForkCallback" in skillExecTool) {
|
|
305544
|
+
skillExecTool.setForkCallback(async (skillName, content) => {
|
|
305545
|
+
if (!_agentToolRef)
|
|
305546
|
+
return "Skill fork unavailable \u2014 agent tool not ready";
|
|
305547
|
+
const agentResult = await _agentToolRef.execute({
|
|
305548
|
+
prompt: `Execute this skill:
|
|
305549
|
+
|
|
305550
|
+
${content}`,
|
|
305551
|
+
subagent_type: "general",
|
|
305552
|
+
description: `skill: ${skillName}`
|
|
305553
|
+
});
|
|
305554
|
+
return agentResult?.output ?? "Skill fork failed";
|
|
305555
|
+
});
|
|
305556
|
+
}
|
|
305116
305557
|
const replToolForFinalVar = tools.find((t2) => t2.name === "repl_exec");
|
|
305117
305558
|
if (replToolForFinalVar && "readVariable" in replToolForFinalVar) {
|
|
305118
305559
|
runner.options.finalVarResolver = async (varName) => {
|
|
@@ -305853,6 +306294,29 @@ async function startInteractive(config, repoPath) {
|
|
|
305853
306294
|
}
|
|
305854
306295
|
initOaDirectory(repoRoot);
|
|
305855
306296
|
const savedSettings = resolveSettings(repoRoot);
|
|
306297
|
+
_mcpManager = new McpManager(repoRoot);
|
|
306298
|
+
try {
|
|
306299
|
+
const mcpConnections = await _mcpManager.connectAll();
|
|
306300
|
+
const connected = mcpConnections.filter((c4) => c4.status === "connected");
|
|
306301
|
+
if (connected.length > 0) {
|
|
306302
|
+
_mcpTools = await _mcpManager.buildTools();
|
|
306303
|
+
}
|
|
306304
|
+
} catch {
|
|
306305
|
+
}
|
|
306306
|
+
_pluginManager = new PluginManager(repoRoot);
|
|
306307
|
+
try {
|
|
306308
|
+
const plugins = _pluginManager.discover();
|
|
306309
|
+
const loaded = plugins.filter((p2) => p2.loaded);
|
|
306310
|
+
if (loaded.length > 0 && _mcpManager) {
|
|
306311
|
+
const pluginServers = _pluginManager.getMcpServers();
|
|
306312
|
+
for (const [name10, serverConfig] of Object.entries(pluginServers)) {
|
|
306313
|
+
await _mcpManager.connectOne(name10, serverConfig).catch(() => {
|
|
306314
|
+
});
|
|
306315
|
+
}
|
|
306316
|
+
_mcpTools = await _mcpManager.buildTools().catch(() => []);
|
|
306317
|
+
}
|
|
306318
|
+
} catch {
|
|
306319
|
+
}
|
|
305856
306320
|
let restoredSessionContext = null;
|
|
305857
306321
|
if (process.stdout.isTTY) {
|
|
305858
306322
|
process.stdout.write("\x1B[2J\x1B[3J\x1B]50;ClearScrollback\x07\x1B[H");
|
|
@@ -307283,6 +307747,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
307283
307747
|
} catch {
|
|
307284
307748
|
}
|
|
307285
307749
|
}
|
|
307750
|
+
_mcpManager?.disconnectAll().catch(() => {
|
|
307751
|
+
});
|
|
307286
307752
|
},
|
|
307287
307753
|
async voiceToggle() {
|
|
307288
307754
|
const msg = await voiceEngine.toggle();
|
|
@@ -308289,7 +308755,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
308289
308755
|
try {
|
|
308290
308756
|
if (process.platform === "win32") {
|
|
308291
308757
|
try {
|
|
308292
|
-
|
|
308758
|
+
execSync39(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
308293
308759
|
} catch {
|
|
308294
308760
|
}
|
|
308295
308761
|
} else {
|
|
@@ -308316,7 +308782,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
308316
308782
|
if (pid > 0) {
|
|
308317
308783
|
if (process.platform === "win32") {
|
|
308318
308784
|
try {
|
|
308319
|
-
|
|
308785
|
+
execSync39(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
308320
308786
|
} catch {
|
|
308321
308787
|
}
|
|
308322
308788
|
} else {
|
|
@@ -308333,7 +308799,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
308333
308799
|
} catch {
|
|
308334
308800
|
}
|
|
308335
308801
|
try {
|
|
308336
|
-
|
|
308802
|
+
execSync39(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
308337
308803
|
} catch {
|
|
308338
308804
|
}
|
|
308339
308805
|
const oaPath = join80(repoRoot, OA_DIR);
|
|
@@ -308347,14 +308813,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
308347
308813
|
} catch (err) {
|
|
308348
308814
|
if (attempt < 2) {
|
|
308349
308815
|
try {
|
|
308350
|
-
|
|
308816
|
+
execSync39(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
308351
308817
|
} catch {
|
|
308352
308818
|
}
|
|
308353
308819
|
} else {
|
|
308354
308820
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
308355
308821
|
if (process.platform === "win32") {
|
|
308356
308822
|
try {
|
|
308357
|
-
|
|
308823
|
+
execSync39(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
308358
308824
|
deleted = true;
|
|
308359
308825
|
} catch {
|
|
308360
308826
|
}
|
|
@@ -309580,7 +310046,7 @@ Rules:
|
|
|
309580
310046
|
process.exit(1);
|
|
309581
310047
|
}
|
|
309582
310048
|
}
|
|
309583
|
-
var taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _autoUpdatedThisSession, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
|
|
310049
|
+
var taskManager, _apiCallbacks, _shellToolRef, _replToolRef, _fullSubAgentToolRef, _agentToolRef, _sendMessageToolRef, _agentLifecycleMgr, _activeRunnerRef, _wireSubAgentCallbacks, _wireAgentToolCallbacks, _autoUpdatedThisSession, _mcpManager, _pluginManager, _mcpTools, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
|
|
309584
310050
|
var init_interactive = __esm({
|
|
309585
310051
|
"packages/cli/dist/tui/interactive.js"() {
|
|
309586
310052
|
"use strict";
|
|
@@ -309632,6 +310098,9 @@ var init_interactive = __esm({
|
|
|
309632
310098
|
_wireSubAgentCallbacks = null;
|
|
309633
310099
|
_wireAgentToolCallbacks = null;
|
|
309634
310100
|
_autoUpdatedThisSession = false;
|
|
310101
|
+
_mcpManager = null;
|
|
310102
|
+
_pluginManager = null;
|
|
310103
|
+
_mcpTools = [];
|
|
309635
310104
|
SELF_IMPROVE_INTERVAL = 5;
|
|
309636
310105
|
_tasksSinceImprove = 0;
|
|
309637
310106
|
}
|