open-agents-ai 0.103.17 → 0.103.19
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 +1661 -251
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1257,9 +1257,58 @@ var init_dist = __esm({
|
|
|
1257
1257
|
});
|
|
1258
1258
|
|
|
1259
1259
|
// packages/execution/dist/tool-executor.js
|
|
1260
|
+
var DEFAULT_CONFIG2, ToolExecutor;
|
|
1260
1261
|
var init_tool_executor = __esm({
|
|
1261
1262
|
"packages/execution/dist/tool-executor.js"() {
|
|
1262
1263
|
"use strict";
|
|
1264
|
+
DEFAULT_CONFIG2 = {
|
|
1265
|
+
workingDir: ".",
|
|
1266
|
+
timeout: 3e4,
|
|
1267
|
+
maxOutputSize: 1e5
|
|
1268
|
+
};
|
|
1269
|
+
ToolExecutor = class {
|
|
1270
|
+
tools = /* @__PURE__ */ new Map();
|
|
1271
|
+
config;
|
|
1272
|
+
constructor(config) {
|
|
1273
|
+
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
1274
|
+
}
|
|
1275
|
+
register(tool) {
|
|
1276
|
+
this.tools.set(tool.name, tool);
|
|
1277
|
+
}
|
|
1278
|
+
getToolDefinitions() {
|
|
1279
|
+
return Array.from(this.tools.values()).map((tool) => ({
|
|
1280
|
+
type: "function",
|
|
1281
|
+
function: {
|
|
1282
|
+
name: tool.name,
|
|
1283
|
+
description: tool.description,
|
|
1284
|
+
parameters: tool.parameters
|
|
1285
|
+
}
|
|
1286
|
+
}));
|
|
1287
|
+
}
|
|
1288
|
+
async execute(toolName, args) {
|
|
1289
|
+
const tool = this.tools.get(toolName);
|
|
1290
|
+
if (!tool) {
|
|
1291
|
+
return {
|
|
1292
|
+
success: false,
|
|
1293
|
+
output: "",
|
|
1294
|
+
error: `Unknown tool: ${toolName}`,
|
|
1295
|
+
durationMs: 0
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
const start = performance.now();
|
|
1299
|
+
try {
|
|
1300
|
+
const result = await tool.execute(args);
|
|
1301
|
+
return result;
|
|
1302
|
+
} catch (error) {
|
|
1303
|
+
return {
|
|
1304
|
+
success: false,
|
|
1305
|
+
output: "",
|
|
1306
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1307
|
+
durationMs: performance.now() - start
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1263
1312
|
}
|
|
1264
1313
|
});
|
|
1265
1314
|
|
|
@@ -4845,6 +4894,9 @@ function hasCommand(cmd) {
|
|
|
4845
4894
|
return false;
|
|
4846
4895
|
}
|
|
4847
4896
|
}
|
|
4897
|
+
function setSudoPassword(pw) {
|
|
4898
|
+
_sudoPassword = pw;
|
|
4899
|
+
}
|
|
4848
4900
|
function runInstall(installCmd) {
|
|
4849
4901
|
const plat = process.platform;
|
|
4850
4902
|
let cmd = installCmd;
|
|
@@ -4944,6 +4996,54 @@ function ensureCommand(command) {
|
|
|
4944
4996
|
_cache.set(command, result);
|
|
4945
4997
|
return result;
|
|
4946
4998
|
}
|
|
4999
|
+
function ensureDepsForGroup(group) {
|
|
5000
|
+
const deps = DESKTOP_DEPS.filter((d) => d.group === group);
|
|
5001
|
+
const results = deps.map((d) => ({ command: d.command, result: ensureCommand(d.command) }));
|
|
5002
|
+
const allAvailable = results.every((r) => r.result.available);
|
|
5003
|
+
const installed = results.filter((r) => r.result.installed);
|
|
5004
|
+
const failed = results.filter((r) => !r.result.available);
|
|
5005
|
+
const parts = [];
|
|
5006
|
+
if (installed.length > 0) {
|
|
5007
|
+
parts.push(`Installed: ${installed.map((r) => r.command).join(", ")}`);
|
|
5008
|
+
}
|
|
5009
|
+
if (failed.length > 0) {
|
|
5010
|
+
parts.push(`Missing: ${failed.map((r) => `${r.command} (${r.result.error})`).join(", ")}`);
|
|
5011
|
+
}
|
|
5012
|
+
return { allAvailable, results, summary: parts.join(". ") || "All dependencies available." };
|
|
5013
|
+
}
|
|
5014
|
+
function ensureAllDesktopDeps() {
|
|
5015
|
+
const results = DESKTOP_DEPS.map((d) => ({
|
|
5016
|
+
dep: d,
|
|
5017
|
+
result: ensureCommand(d.command)
|
|
5018
|
+
}));
|
|
5019
|
+
const installed = results.filter((r) => r.result.installed).map((r) => r.dep.command);
|
|
5020
|
+
const missing = results.filter((r) => !r.result.available).map((r) => r.dep.command);
|
|
5021
|
+
const allAvailable = missing.length === 0;
|
|
5022
|
+
const parts = [];
|
|
5023
|
+
if (installed.length > 0) {
|
|
5024
|
+
parts.push(`Auto-installed: ${installed.join(", ")}`);
|
|
5025
|
+
}
|
|
5026
|
+
if (missing.length > 0) {
|
|
5027
|
+
parts.push(`Could not install: ${missing.join(", ")}`);
|
|
5028
|
+
}
|
|
5029
|
+
return {
|
|
5030
|
+
allAvailable,
|
|
5031
|
+
summary: parts.join(". ") || "All desktop dependencies available.",
|
|
5032
|
+
installed,
|
|
5033
|
+
missing
|
|
5034
|
+
};
|
|
5035
|
+
}
|
|
5036
|
+
function checkDesktopDeps() {
|
|
5037
|
+
return DESKTOP_DEPS.map((d) => ({
|
|
5038
|
+
dep: d,
|
|
5039
|
+
available: hasCommand(d.command)
|
|
5040
|
+
}));
|
|
5041
|
+
}
|
|
5042
|
+
function resetDepCache() {
|
|
5043
|
+
_cache.clear();
|
|
5044
|
+
_detectedPkgManager = void 0;
|
|
5045
|
+
_sudoPassword = null;
|
|
5046
|
+
}
|
|
4947
5047
|
var DESKTOP_DEPS, _detectedPkgManager, _cache, _sudoPassword;
|
|
4948
5048
|
var init_system_deps = __esm({
|
|
4949
5049
|
"packages/execution/dist/system-deps.js"() {
|
|
@@ -7759,6 +7859,10 @@ Details: ${err.message}` : "");
|
|
|
7759
7859
|
throw new Error(moondreamError);
|
|
7760
7860
|
}
|
|
7761
7861
|
}
|
|
7862
|
+
function resetMoondreamClient() {
|
|
7863
|
+
moondreamClient = null;
|
|
7864
|
+
moondreamError = null;
|
|
7865
|
+
}
|
|
7762
7866
|
function loadImageBuffer(workingDir, rawPath) {
|
|
7763
7867
|
const fullPath = resolve16(workingDir, rawPath);
|
|
7764
7868
|
if (!existsSync14(fullPath)) {
|
|
@@ -12167,9 +12271,16 @@ async function handleCmd(cmd) {
|
|
|
12167
12271
|
riData = { prompt: riPrompt };
|
|
12168
12272
|
}
|
|
12169
12273
|
|
|
12274
|
+
var riAuthKey = args.auth_key || '';
|
|
12275
|
+
|
|
12170
12276
|
// Derive capability name from model
|
|
12171
12277
|
var riCapName = 'inference:' + riModel.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
12172
|
-
dlog('remote_infer: model=' + riModel + ' cap=' + riCapName + ' prompt_len=' + riPrompt.length);
|
|
12278
|
+
dlog('remote_infer: model=' + riModel + ' cap=' + riCapName + ' prompt_len=' + riPrompt.length + (riAuthKey ? ' auth=yes' : ''));
|
|
12279
|
+
|
|
12280
|
+
// Include auth key in data if provided
|
|
12281
|
+
if (riAuthKey) {
|
|
12282
|
+
riData.auth_key = riAuthKey;
|
|
12283
|
+
}
|
|
12173
12284
|
|
|
12174
12285
|
// If target_peer specified, invoke directly. Otherwise auto-discover.
|
|
12175
12286
|
if (riTargetPeer) {
|
|
@@ -12414,6 +12525,12 @@ async function handleCmd(cmd) {
|
|
|
12414
12525
|
|
|
12415
12526
|
// \u2500\u2500 Metered Inference Exposure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
12416
12527
|
case 'expose': {
|
|
12528
|
+
// Auth key for gating inference access (passed from ExposeP2PGateway)
|
|
12529
|
+
var exposeAuthKey = args.auth_key || '';
|
|
12530
|
+
if (exposeAuthKey) {
|
|
12531
|
+
dlog('expose: auth key configured (' + exposeAuthKey.length + ' chars)');
|
|
12532
|
+
}
|
|
12533
|
+
|
|
12417
12534
|
// Query Ollama for available models
|
|
12418
12535
|
const ollamaUrl = args.ollama_url || process.env.OLLAMA_URL || 'http://localhost:11434';
|
|
12419
12536
|
let models = [];
|
|
@@ -12513,6 +12630,25 @@ async function handleCmd(cmd) {
|
|
|
12513
12630
|
const logFile = join(invocationsDir, Date.now() + '-' + capName + '.json');
|
|
12514
12631
|
try { writeFileSync(logFile, JSON.stringify(logEntry, null, 2)); } catch {}
|
|
12515
12632
|
|
|
12633
|
+
// Auth key validation \u2014 if expose was started with auth_key, require it
|
|
12634
|
+
if (exposeAuthKey) {
|
|
12635
|
+
var reqAuthKey = '';
|
|
12636
|
+
if (request.data && typeof request.data === 'object' && request.data.auth_key) {
|
|
12637
|
+
reqAuthKey = request.data.auth_key;
|
|
12638
|
+
} else if (request.metadata && request.metadata.auth_key) {
|
|
12639
|
+
reqAuthKey = request.metadata.auth_key;
|
|
12640
|
+
}
|
|
12641
|
+
if (reqAuthKey !== exposeAuthKey) {
|
|
12642
|
+
dlog('expose: auth REJECTED for ' + capName + ' from ' + (request.from || 'unknown'));
|
|
12643
|
+
await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: false });
|
|
12644
|
+
await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized \u2014 invalid or missing auth key' });
|
|
12645
|
+
await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
12646
|
+
stream.close();
|
|
12647
|
+
return;
|
|
12648
|
+
}
|
|
12649
|
+
dlog('expose: auth OK for ' + capName);
|
|
12650
|
+
}
|
|
12651
|
+
|
|
12516
12652
|
// Collect input via stream data events
|
|
12517
12653
|
let prompt = '';
|
|
12518
12654
|
var dataChunks = [];
|
|
@@ -12655,6 +12791,64 @@ async function handleCmd(cmd) {
|
|
|
12655
12791
|
}
|
|
12656
12792
|
}
|
|
12657
12793
|
|
|
12794
|
+
// Register system_metrics capability \u2014 returns CPU/GPU/memory utilization
|
|
12795
|
+
if (typeof nexus.registerCapability === 'function') {
|
|
12796
|
+
nexus.registerCapability('system_metrics', async (request, stream) => {
|
|
12797
|
+
// Auth check for system_metrics too
|
|
12798
|
+
if (exposeAuthKey) {
|
|
12799
|
+
var smAuthKey = '';
|
|
12800
|
+
if (request.data && typeof request.data === 'object' && request.data.auth_key) {
|
|
12801
|
+
smAuthKey = request.data.auth_key;
|
|
12802
|
+
} else if (request.metadata && request.metadata.auth_key) {
|
|
12803
|
+
smAuthKey = request.metadata.auth_key;
|
|
12804
|
+
}
|
|
12805
|
+
if (smAuthKey !== exposeAuthKey) {
|
|
12806
|
+
await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: false });
|
|
12807
|
+
await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
12808
|
+
stream.close();
|
|
12809
|
+
return;
|
|
12810
|
+
}
|
|
12811
|
+
}
|
|
12812
|
+
await stream.write({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: true });
|
|
12813
|
+
try {
|
|
12814
|
+
var os = require('os');
|
|
12815
|
+
var loads = os.loadavg();
|
|
12816
|
+
var cores = os.cpus().length;
|
|
12817
|
+
var totalMem = os.totalmem();
|
|
12818
|
+
var freeMem = os.freemem();
|
|
12819
|
+
var usedMem = totalMem - freeMem;
|
|
12820
|
+
var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
|
|
12821
|
+
try {
|
|
12822
|
+
var cp = require('child_process');
|
|
12823
|
+
var smiOut = cp.execSync('nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null', { encoding: 'utf8', timeout: 3000 });
|
|
12824
|
+
var smiLine = smiOut.trim().split('\\n')[0];
|
|
12825
|
+
if (smiLine) {
|
|
12826
|
+
var sp = smiLine.split(',').map(function(s) { return s.trim(); });
|
|
12827
|
+
gpuInfo.available = true;
|
|
12828
|
+
gpuInfo.utilization = parseInt(sp[0] || '0', 10) || 0;
|
|
12829
|
+
gpuInfo.vramUsedMB = parseInt(sp[1] || '0', 10) || 0;
|
|
12830
|
+
gpuInfo.vramTotalMB = parseInt(sp[2] || '0', 10) || 0;
|
|
12831
|
+
gpuInfo.name = sp[3] || '';
|
|
12832
|
+
gpuInfo.vramUtilization = gpuInfo.vramTotalMB > 0 ? Math.round((gpuInfo.vramUsedMB / gpuInfo.vramTotalMB) * 100) : 0;
|
|
12833
|
+
}
|
|
12834
|
+
} catch (ge) { /* no GPU */ }
|
|
12835
|
+
var metricsPayload = {
|
|
12836
|
+
cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores },
|
|
12837
|
+
memory: { utilization: Math.round((usedMem / totalMem) * 100), totalGB: Math.round((totalMem / (1024*1024*1024)) * 10) / 10 },
|
|
12838
|
+
gpu: gpuInfo,
|
|
12839
|
+
timestamp: new Date().toISOString(),
|
|
12840
|
+
};
|
|
12841
|
+
await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'result', data: JSON.stringify(metricsPayload) });
|
|
12842
|
+
await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: JSON.stringify(metricsPayload).length } });
|
|
12843
|
+
} catch (me) {
|
|
12844
|
+
await stream.write({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'metrics error: ' + me.message });
|
|
12845
|
+
await stream.write({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
12846
|
+
}
|
|
12847
|
+
stream.close();
|
|
12848
|
+
});
|
|
12849
|
+
dlog('system_metrics capability registered');
|
|
12850
|
+
}
|
|
12851
|
+
|
|
12658
12852
|
// Write pricing menu to file
|
|
12659
12853
|
const pricingFile = join(nexusDir, 'pricing.json');
|
|
12660
12854
|
writeFileSync(pricingFile, JSON.stringify({ updated: new Date().toISOString(), models: pricingMenu }, null, 2));
|
|
@@ -14065,21 +14259,185 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14065
14259
|
});
|
|
14066
14260
|
|
|
14067
14261
|
// packages/execution/dist/shellRunner.js
|
|
14262
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
14263
|
+
async function runShell(options) {
|
|
14264
|
+
const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
14265
|
+
const mergedEnv = env ? { ...process.env, ...env } : process.env;
|
|
14266
|
+
return new Promise((resolve31) => {
|
|
14267
|
+
const start = Date.now();
|
|
14268
|
+
let timedOut = false;
|
|
14269
|
+
const child = spawn12(command, args, {
|
|
14270
|
+
cwd: cwd4,
|
|
14271
|
+
env: mergedEnv
|
|
14272
|
+
// Do NOT use shell:true — we pass command + args separately
|
|
14273
|
+
});
|
|
14274
|
+
let stdout = "";
|
|
14275
|
+
let stderr = "";
|
|
14276
|
+
child.stdout.on("data", (chunk) => {
|
|
14277
|
+
stdout += chunk.toString();
|
|
14278
|
+
});
|
|
14279
|
+
child.stderr.on("data", (chunk) => {
|
|
14280
|
+
stderr += chunk.toString();
|
|
14281
|
+
});
|
|
14282
|
+
const timer = setTimeout(() => {
|
|
14283
|
+
timedOut = true;
|
|
14284
|
+
child.kill("SIGKILL");
|
|
14285
|
+
}, timeoutMs);
|
|
14286
|
+
child.on("close", (code) => {
|
|
14287
|
+
clearTimeout(timer);
|
|
14288
|
+
const durationMs = Date.now() - start;
|
|
14289
|
+
const exitCode = timedOut ? -1 : code ?? -1;
|
|
14290
|
+
resolve31({
|
|
14291
|
+
stdout,
|
|
14292
|
+
stderr,
|
|
14293
|
+
exitCode,
|
|
14294
|
+
success: !timedOut && exitCode === 0,
|
|
14295
|
+
timedOut,
|
|
14296
|
+
durationMs
|
|
14297
|
+
});
|
|
14298
|
+
});
|
|
14299
|
+
child.on("error", (err) => {
|
|
14300
|
+
clearTimeout(timer);
|
|
14301
|
+
const durationMs = Date.now() - start;
|
|
14302
|
+
resolve31({
|
|
14303
|
+
stdout,
|
|
14304
|
+
stderr: stderr + err.message,
|
|
14305
|
+
exitCode: -1,
|
|
14306
|
+
success: false,
|
|
14307
|
+
timedOut: false,
|
|
14308
|
+
durationMs
|
|
14309
|
+
});
|
|
14310
|
+
});
|
|
14311
|
+
});
|
|
14312
|
+
}
|
|
14313
|
+
var DEFAULT_TIMEOUT_MS;
|
|
14068
14314
|
var init_shellRunner = __esm({
|
|
14069
14315
|
"packages/execution/dist/shellRunner.js"() {
|
|
14070
14316
|
"use strict";
|
|
14317
|
+
DEFAULT_TIMEOUT_MS = 6e4;
|
|
14071
14318
|
}
|
|
14072
14319
|
});
|
|
14073
14320
|
|
|
14074
14321
|
// packages/execution/dist/gitWorktree.js
|
|
14322
|
+
async function createWorktree(options) {
|
|
14323
|
+
const { repoPath, worktreePath, branch, timeoutMs = DEFAULT_GIT_TIMEOUT_MS } = options;
|
|
14324
|
+
const result = await runShell({
|
|
14325
|
+
command: "git",
|
|
14326
|
+
args: ["worktree", "add", "-b", branch, worktreePath],
|
|
14327
|
+
cwd: repoPath,
|
|
14328
|
+
timeoutMs
|
|
14329
|
+
});
|
|
14330
|
+
if (!result.success) {
|
|
14331
|
+
throw new Error(`git worktree add failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
14332
|
+
}
|
|
14333
|
+
return { worktreePath, branch };
|
|
14334
|
+
}
|
|
14335
|
+
async function removeWorktree(options) {
|
|
14336
|
+
const { repoPath, worktreePath, timeoutMs = DEFAULT_GIT_TIMEOUT_MS } = options;
|
|
14337
|
+
const result = await runShell({
|
|
14338
|
+
command: "git",
|
|
14339
|
+
args: ["worktree", "remove", "--force", worktreePath],
|
|
14340
|
+
cwd: repoPath,
|
|
14341
|
+
timeoutMs
|
|
14342
|
+
});
|
|
14343
|
+
if (!result.success) {
|
|
14344
|
+
const isAlreadyGone = result.stderr.includes("not a working tree") || result.stderr.includes("is not a working tree") || result.stderr.includes("No such file");
|
|
14345
|
+
if (!isAlreadyGone) {
|
|
14346
|
+
throw new Error(`git worktree remove failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
14347
|
+
}
|
|
14348
|
+
}
|
|
14349
|
+
await runShell({
|
|
14350
|
+
command: "git",
|
|
14351
|
+
args: ["worktree", "prune"],
|
|
14352
|
+
cwd: repoPath,
|
|
14353
|
+
timeoutMs
|
|
14354
|
+
});
|
|
14355
|
+
}
|
|
14356
|
+
var DEFAULT_GIT_TIMEOUT_MS;
|
|
14075
14357
|
var init_gitWorktree = __esm({
|
|
14076
14358
|
"packages/execution/dist/gitWorktree.js"() {
|
|
14077
14359
|
"use strict";
|
|
14078
14360
|
init_shellRunner();
|
|
14361
|
+
DEFAULT_GIT_TIMEOUT_MS = 3e4;
|
|
14079
14362
|
}
|
|
14080
14363
|
});
|
|
14081
14364
|
|
|
14082
14365
|
// packages/execution/dist/patchApplier.js
|
|
14366
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
|
|
14367
|
+
import { dirname as dirname11 } from "node:path";
|
|
14368
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
14369
|
+
async function applyPatch(patch) {
|
|
14370
|
+
switch (patch.type) {
|
|
14371
|
+
case "block-replace":
|
|
14372
|
+
return applyBlockReplace(patch);
|
|
14373
|
+
case "rewrite":
|
|
14374
|
+
return applyRewrite(patch);
|
|
14375
|
+
case "new-file":
|
|
14376
|
+
return applyNewFile(patch);
|
|
14377
|
+
case "unified-diff":
|
|
14378
|
+
return applyUnifiedDiff(patch);
|
|
14379
|
+
}
|
|
14380
|
+
}
|
|
14381
|
+
function applyBlockReplace(patch) {
|
|
14382
|
+
const original = readFileSync17(patch.filePath, "utf-8");
|
|
14383
|
+
if (!original.includes(patch.oldContent)) {
|
|
14384
|
+
throw new Error(`Block not found in "${patch.filePath}": the oldContent string was not found in the file.`);
|
|
14385
|
+
}
|
|
14386
|
+
const updated = original.replace(patch.oldContent, patch.newContent);
|
|
14387
|
+
writeFileSync7(patch.filePath, updated, "utf-8");
|
|
14388
|
+
}
|
|
14389
|
+
function applyRewrite(patch) {
|
|
14390
|
+
writeFileSync7(patch.filePath, patch.newContent, "utf-8");
|
|
14391
|
+
}
|
|
14392
|
+
function applyNewFile(patch) {
|
|
14393
|
+
if (existsSync24(patch.filePath)) {
|
|
14394
|
+
throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
|
|
14395
|
+
}
|
|
14396
|
+
mkdirSync7(dirname11(patch.filePath), { recursive: true });
|
|
14397
|
+
writeFileSync7(patch.filePath, patch.newContent, "utf-8");
|
|
14398
|
+
}
|
|
14399
|
+
async function applyUnifiedDiff(patch) {
|
|
14400
|
+
const { filePath, diff } = patch;
|
|
14401
|
+
const result = await runWithStdin({
|
|
14402
|
+
command: "patch",
|
|
14403
|
+
args: [
|
|
14404
|
+
"--no-backup-if-mismatch",
|
|
14405
|
+
"-p1",
|
|
14406
|
+
filePath
|
|
14407
|
+
],
|
|
14408
|
+
cwd: dirname11(filePath),
|
|
14409
|
+
stdin: diff
|
|
14410
|
+
});
|
|
14411
|
+
if (!result.success) {
|
|
14412
|
+
throw new Error(`patch command failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
14413
|
+
}
|
|
14414
|
+
}
|
|
14415
|
+
function runWithStdin(options) {
|
|
14416
|
+
const { command, args, cwd: cwd4, stdin } = options;
|
|
14417
|
+
return new Promise((resolve31) => {
|
|
14418
|
+
const child = spawn13(command, args, {
|
|
14419
|
+
cwd: cwd4,
|
|
14420
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
14421
|
+
});
|
|
14422
|
+
let stdout = "";
|
|
14423
|
+
let stderr = "";
|
|
14424
|
+
child.stdout.on("data", (chunk) => {
|
|
14425
|
+
stdout += chunk.toString();
|
|
14426
|
+
});
|
|
14427
|
+
child.stderr.on("data", (chunk) => {
|
|
14428
|
+
stderr += chunk.toString();
|
|
14429
|
+
});
|
|
14430
|
+
child.stdin.write(stdin);
|
|
14431
|
+
child.stdin.end();
|
|
14432
|
+
child.on("close", (code) => {
|
|
14433
|
+
const exitCode = code ?? -1;
|
|
14434
|
+
resolve31({ success: exitCode === 0, exitCode, stdout, stderr });
|
|
14435
|
+
});
|
|
14436
|
+
child.on("error", (err) => {
|
|
14437
|
+
resolve31({ success: false, exitCode: -1, stdout, stderr: err.message });
|
|
14438
|
+
});
|
|
14439
|
+
});
|
|
14440
|
+
}
|
|
14083
14441
|
var init_patchApplier = __esm({
|
|
14084
14442
|
"packages/execution/dist/patchApplier.js"() {
|
|
14085
14443
|
"use strict";
|
|
@@ -14087,6 +14445,55 @@ var init_patchApplier = __esm({
|
|
|
14087
14445
|
});
|
|
14088
14446
|
|
|
14089
14447
|
// packages/execution/dist/formatterRunner.js
|
|
14448
|
+
function buildFormatterCommand(formatter, extraArgs) {
|
|
14449
|
+
switch (formatter) {
|
|
14450
|
+
case "prettier":
|
|
14451
|
+
return {
|
|
14452
|
+
command: "npx",
|
|
14453
|
+
args: ["prettier", "--write", ".", ...extraArgs]
|
|
14454
|
+
};
|
|
14455
|
+
case "black":
|
|
14456
|
+
return {
|
|
14457
|
+
command: "black",
|
|
14458
|
+
args: [".", ...extraArgs]
|
|
14459
|
+
};
|
|
14460
|
+
case "rustfmt":
|
|
14461
|
+
return {
|
|
14462
|
+
command: "rustfmt",
|
|
14463
|
+
args: [...extraArgs]
|
|
14464
|
+
};
|
|
14465
|
+
case "gofmt":
|
|
14466
|
+
return {
|
|
14467
|
+
command: "gofmt",
|
|
14468
|
+
args: ["-w", ".", ...extraArgs]
|
|
14469
|
+
};
|
|
14470
|
+
}
|
|
14471
|
+
}
|
|
14472
|
+
async function runFormatter(options) {
|
|
14473
|
+
const { profile, extraArgs = [] } = options;
|
|
14474
|
+
if (profile.formatter === null) {
|
|
14475
|
+
return {
|
|
14476
|
+
success: true,
|
|
14477
|
+
tool: "none",
|
|
14478
|
+
stdout: "",
|
|
14479
|
+
stderr: "",
|
|
14480
|
+
skipped: true
|
|
14481
|
+
};
|
|
14482
|
+
}
|
|
14483
|
+
const { command, args } = buildFormatterCommand(profile.formatter, extraArgs);
|
|
14484
|
+
const shellResult = await runShell({
|
|
14485
|
+
command,
|
|
14486
|
+
args,
|
|
14487
|
+
cwd: profile.projectRoot
|
|
14488
|
+
});
|
|
14489
|
+
return {
|
|
14490
|
+
success: shellResult.success,
|
|
14491
|
+
tool: profile.formatter,
|
|
14492
|
+
stdout: shellResult.stdout,
|
|
14493
|
+
stderr: shellResult.stderr,
|
|
14494
|
+
skipped: false
|
|
14495
|
+
};
|
|
14496
|
+
}
|
|
14090
14497
|
var init_formatterRunner = __esm({
|
|
14091
14498
|
"packages/execution/dist/formatterRunner.js"() {
|
|
14092
14499
|
"use strict";
|
|
@@ -14095,6 +14502,60 @@ var init_formatterRunner = __esm({
|
|
|
14095
14502
|
});
|
|
14096
14503
|
|
|
14097
14504
|
// packages/execution/dist/linterRunner.js
|
|
14505
|
+
function buildLinterCommand(linter, extraArgs) {
|
|
14506
|
+
switch (linter) {
|
|
14507
|
+
case "eslint":
|
|
14508
|
+
return {
|
|
14509
|
+
command: "npx",
|
|
14510
|
+
args: ["eslint", ".", ...extraArgs]
|
|
14511
|
+
};
|
|
14512
|
+
case "ruff":
|
|
14513
|
+
return {
|
|
14514
|
+
command: "ruff",
|
|
14515
|
+
args: ["check", ".", ...extraArgs]
|
|
14516
|
+
};
|
|
14517
|
+
case "flake8":
|
|
14518
|
+
return {
|
|
14519
|
+
command: "flake8",
|
|
14520
|
+
args: [".", ...extraArgs]
|
|
14521
|
+
};
|
|
14522
|
+
case "clippy":
|
|
14523
|
+
return {
|
|
14524
|
+
command: "cargo",
|
|
14525
|
+
args: ["clippy", ...extraArgs]
|
|
14526
|
+
};
|
|
14527
|
+
case "golangci-lint":
|
|
14528
|
+
return {
|
|
14529
|
+
command: "golangci-lint",
|
|
14530
|
+
args: ["run", ...extraArgs]
|
|
14531
|
+
};
|
|
14532
|
+
}
|
|
14533
|
+
}
|
|
14534
|
+
async function runLinter(options) {
|
|
14535
|
+
const { profile, extraArgs = [] } = options;
|
|
14536
|
+
if (profile.linter === null) {
|
|
14537
|
+
return {
|
|
14538
|
+
success: true,
|
|
14539
|
+
tool: "none",
|
|
14540
|
+
stdout: "",
|
|
14541
|
+
stderr: "",
|
|
14542
|
+
skipped: true
|
|
14543
|
+
};
|
|
14544
|
+
}
|
|
14545
|
+
const { command, args } = buildLinterCommand(profile.linter, extraArgs);
|
|
14546
|
+
const shellResult = await runShell({
|
|
14547
|
+
command,
|
|
14548
|
+
args,
|
|
14549
|
+
cwd: profile.projectRoot
|
|
14550
|
+
});
|
|
14551
|
+
return {
|
|
14552
|
+
success: shellResult.success,
|
|
14553
|
+
tool: profile.linter,
|
|
14554
|
+
stdout: shellResult.stdout,
|
|
14555
|
+
stderr: shellResult.stderr,
|
|
14556
|
+
skipped: false
|
|
14557
|
+
};
|
|
14558
|
+
}
|
|
14098
14559
|
var init_linterRunner = __esm({
|
|
14099
14560
|
"packages/execution/dist/linterRunner.js"() {
|
|
14100
14561
|
"use strict";
|
|
@@ -14103,6 +14564,50 @@ var init_linterRunner = __esm({
|
|
|
14103
14564
|
});
|
|
14104
14565
|
|
|
14105
14566
|
// packages/execution/dist/typecheckRunner.js
|
|
14567
|
+
function buildTypecheckerCommand(typechecker, extraArgs) {
|
|
14568
|
+
switch (typechecker) {
|
|
14569
|
+
case "tsc":
|
|
14570
|
+
return {
|
|
14571
|
+
command: "npx",
|
|
14572
|
+
args: ["tsc", "--noEmit", ...extraArgs]
|
|
14573
|
+
};
|
|
14574
|
+
case "mypy":
|
|
14575
|
+
return {
|
|
14576
|
+
command: "mypy",
|
|
14577
|
+
args: [".", ...extraArgs]
|
|
14578
|
+
};
|
|
14579
|
+
case "pyright":
|
|
14580
|
+
return {
|
|
14581
|
+
command: "pyright",
|
|
14582
|
+
args: [...extraArgs]
|
|
14583
|
+
};
|
|
14584
|
+
}
|
|
14585
|
+
}
|
|
14586
|
+
async function runTypecheck(options) {
|
|
14587
|
+
const { profile, extraArgs = [] } = options;
|
|
14588
|
+
if (profile.typechecker === null) {
|
|
14589
|
+
return {
|
|
14590
|
+
success: true,
|
|
14591
|
+
tool: "none",
|
|
14592
|
+
stdout: "",
|
|
14593
|
+
stderr: "",
|
|
14594
|
+
skipped: true
|
|
14595
|
+
};
|
|
14596
|
+
}
|
|
14597
|
+
const { command, args } = buildTypecheckerCommand(profile.typechecker, extraArgs);
|
|
14598
|
+
const shellResult = await runShell({
|
|
14599
|
+
command,
|
|
14600
|
+
args,
|
|
14601
|
+
cwd: profile.projectRoot
|
|
14602
|
+
});
|
|
14603
|
+
return {
|
|
14604
|
+
success: shellResult.success,
|
|
14605
|
+
tool: profile.typechecker,
|
|
14606
|
+
stdout: shellResult.stdout,
|
|
14607
|
+
stderr: shellResult.stderr,
|
|
14608
|
+
skipped: false
|
|
14609
|
+
};
|
|
14610
|
+
}
|
|
14106
14611
|
var init_typecheckRunner = __esm({
|
|
14107
14612
|
"packages/execution/dist/typecheckRunner.js"() {
|
|
14108
14613
|
"use strict";
|
|
@@ -14111,6 +14616,60 @@ var init_typecheckRunner = __esm({
|
|
|
14111
14616
|
});
|
|
14112
14617
|
|
|
14113
14618
|
// packages/execution/dist/testRunner.js
|
|
14619
|
+
function buildTestRunnerCommand(testRunner, extraArgs) {
|
|
14620
|
+
switch (testRunner) {
|
|
14621
|
+
case "jest":
|
|
14622
|
+
return {
|
|
14623
|
+
command: "npx",
|
|
14624
|
+
args: ["jest", ...extraArgs]
|
|
14625
|
+
};
|
|
14626
|
+
case "vitest":
|
|
14627
|
+
return {
|
|
14628
|
+
command: "npx",
|
|
14629
|
+
args: ["vitest", "run", ...extraArgs]
|
|
14630
|
+
};
|
|
14631
|
+
case "pytest":
|
|
14632
|
+
return {
|
|
14633
|
+
command: "pytest",
|
|
14634
|
+
args: [...extraArgs]
|
|
14635
|
+
};
|
|
14636
|
+
case "mocha":
|
|
14637
|
+
return {
|
|
14638
|
+
command: "npx",
|
|
14639
|
+
args: ["mocha", ...extraArgs]
|
|
14640
|
+
};
|
|
14641
|
+
case "go-test":
|
|
14642
|
+
return {
|
|
14643
|
+
command: "go",
|
|
14644
|
+
args: ["test", "./...", ...extraArgs]
|
|
14645
|
+
};
|
|
14646
|
+
}
|
|
14647
|
+
}
|
|
14648
|
+
async function runTests(options) {
|
|
14649
|
+
const { profile, extraArgs = [] } = options;
|
|
14650
|
+
if (profile.testRunner === null) {
|
|
14651
|
+
return {
|
|
14652
|
+
success: true,
|
|
14653
|
+
tool: "none",
|
|
14654
|
+
stdout: "",
|
|
14655
|
+
stderr: "",
|
|
14656
|
+
skipped: true
|
|
14657
|
+
};
|
|
14658
|
+
}
|
|
14659
|
+
const { command, args } = buildTestRunnerCommand(profile.testRunner, extraArgs);
|
|
14660
|
+
const shellResult = await runShell({
|
|
14661
|
+
command,
|
|
14662
|
+
args,
|
|
14663
|
+
cwd: profile.projectRoot
|
|
14664
|
+
});
|
|
14665
|
+
return {
|
|
14666
|
+
success: shellResult.success,
|
|
14667
|
+
tool: profile.testRunner,
|
|
14668
|
+
stdout: shellResult.stdout,
|
|
14669
|
+
stderr: shellResult.stderr,
|
|
14670
|
+
skipped: false
|
|
14671
|
+
};
|
|
14672
|
+
}
|
|
14114
14673
|
var init_testRunner = __esm({
|
|
14115
14674
|
"packages/execution/dist/testRunner.js"() {
|
|
14116
14675
|
"use strict";
|
|
@@ -14119,6 +14678,71 @@ var init_testRunner = __esm({
|
|
|
14119
14678
|
});
|
|
14120
14679
|
|
|
14121
14680
|
// packages/execution/dist/buildRunner.js
|
|
14681
|
+
function buildBuilderCommand(profile, extraArgs) {
|
|
14682
|
+
switch (profile.builder) {
|
|
14683
|
+
case "tsc":
|
|
14684
|
+
return {
|
|
14685
|
+
command: "npx",
|
|
14686
|
+
args: ["tsc", "--build", ...extraArgs]
|
|
14687
|
+
};
|
|
14688
|
+
case "vite":
|
|
14689
|
+
return {
|
|
14690
|
+
command: "npx",
|
|
14691
|
+
args: ["vite", "build", ...extraArgs]
|
|
14692
|
+
};
|
|
14693
|
+
case "webpack":
|
|
14694
|
+
return {
|
|
14695
|
+
command: "npx",
|
|
14696
|
+
args: ["webpack", ...extraArgs]
|
|
14697
|
+
};
|
|
14698
|
+
case "cargo":
|
|
14699
|
+
return {
|
|
14700
|
+
command: "cargo",
|
|
14701
|
+
args: ["build", "--release", ...extraArgs]
|
|
14702
|
+
};
|
|
14703
|
+
case "go-build":
|
|
14704
|
+
return {
|
|
14705
|
+
command: "go",
|
|
14706
|
+
args: ["build", "./...", ...extraArgs]
|
|
14707
|
+
};
|
|
14708
|
+
case "custom": {
|
|
14709
|
+
if (!profile.buildCommand) {
|
|
14710
|
+
throw new Error('buildCommand is required when builder is "custom"');
|
|
14711
|
+
}
|
|
14712
|
+
return {
|
|
14713
|
+
command: "sh",
|
|
14714
|
+
args: ["-c", profile.buildCommand]
|
|
14715
|
+
};
|
|
14716
|
+
}
|
|
14717
|
+
default:
|
|
14718
|
+
throw new Error(`Unsupported builder: ${String(profile.builder)}`);
|
|
14719
|
+
}
|
|
14720
|
+
}
|
|
14721
|
+
async function runBuild(options) {
|
|
14722
|
+
const { profile, extraArgs = [] } = options;
|
|
14723
|
+
if (profile.builder === null) {
|
|
14724
|
+
return {
|
|
14725
|
+
success: true,
|
|
14726
|
+
tool: "none",
|
|
14727
|
+
stdout: "",
|
|
14728
|
+
stderr: "",
|
|
14729
|
+
skipped: true
|
|
14730
|
+
};
|
|
14731
|
+
}
|
|
14732
|
+
const { command, args } = buildBuilderCommand(profile, extraArgs);
|
|
14733
|
+
const shellResult = await runShell({
|
|
14734
|
+
command,
|
|
14735
|
+
args,
|
|
14736
|
+
cwd: profile.projectRoot
|
|
14737
|
+
});
|
|
14738
|
+
return {
|
|
14739
|
+
success: shellResult.success,
|
|
14740
|
+
tool: profile.builder,
|
|
14741
|
+
stdout: shellResult.stdout,
|
|
14742
|
+
stderr: shellResult.stderr,
|
|
14743
|
+
skipped: false
|
|
14744
|
+
};
|
|
14745
|
+
}
|
|
14122
14746
|
var init_buildRunner = __esm({
|
|
14123
14747
|
"packages/execution/dist/buildRunner.js"() {
|
|
14124
14748
|
"use strict";
|
|
@@ -14127,6 +14751,100 @@ var init_buildRunner = __esm({
|
|
|
14127
14751
|
});
|
|
14128
14752
|
|
|
14129
14753
|
// packages/execution/dist/validationPipeline.js
|
|
14754
|
+
async function runValidationPipeline(config) {
|
|
14755
|
+
const { projectRoot, profile, stopOnFirstFailure = true } = config;
|
|
14756
|
+
const formatterProfile = {
|
|
14757
|
+
formatter: profile.formatter,
|
|
14758
|
+
projectRoot
|
|
14759
|
+
};
|
|
14760
|
+
const linterProfile = {
|
|
14761
|
+
linter: profile.linter,
|
|
14762
|
+
projectRoot
|
|
14763
|
+
};
|
|
14764
|
+
const typecheckProfile = {
|
|
14765
|
+
typechecker: profile.typechecker,
|
|
14766
|
+
projectRoot
|
|
14767
|
+
};
|
|
14768
|
+
const testProfile = {
|
|
14769
|
+
testRunner: profile.testRunner,
|
|
14770
|
+
projectRoot
|
|
14771
|
+
};
|
|
14772
|
+
const buildProfile = {
|
|
14773
|
+
builder: profile.builder,
|
|
14774
|
+
projectRoot,
|
|
14775
|
+
buildCommand: profile.buildCommand
|
|
14776
|
+
};
|
|
14777
|
+
const steps = [];
|
|
14778
|
+
const start = Date.now();
|
|
14779
|
+
const formatRaw = await runFormatter({ profile: formatterProfile });
|
|
14780
|
+
const formatStep = {
|
|
14781
|
+
name: "format",
|
|
14782
|
+
success: formatRaw.success,
|
|
14783
|
+
tool: formatRaw.tool,
|
|
14784
|
+
stdout: formatRaw.stdout,
|
|
14785
|
+
stderr: formatRaw.stderr,
|
|
14786
|
+
skipped: formatRaw.skipped
|
|
14787
|
+
};
|
|
14788
|
+
steps.push(formatStep);
|
|
14789
|
+
if (!formatStep.success && stopOnFirstFailure) {
|
|
14790
|
+
return { overall: "fail", steps, totalDurationMs: Date.now() - start };
|
|
14791
|
+
}
|
|
14792
|
+
const lintRaw = await runLinter({ profile: linterProfile });
|
|
14793
|
+
const lintStep = {
|
|
14794
|
+
name: "lint",
|
|
14795
|
+
success: lintRaw.success,
|
|
14796
|
+
tool: lintRaw.tool,
|
|
14797
|
+
stdout: lintRaw.stdout,
|
|
14798
|
+
stderr: lintRaw.stderr,
|
|
14799
|
+
skipped: lintRaw.skipped
|
|
14800
|
+
};
|
|
14801
|
+
steps.push(lintStep);
|
|
14802
|
+
if (!lintStep.success && stopOnFirstFailure) {
|
|
14803
|
+
return { overall: "fail", steps, totalDurationMs: Date.now() - start };
|
|
14804
|
+
}
|
|
14805
|
+
const typecheckRaw = await runTypecheck({ profile: typecheckProfile });
|
|
14806
|
+
const typecheckStep = {
|
|
14807
|
+
name: "typecheck",
|
|
14808
|
+
success: typecheckRaw.success,
|
|
14809
|
+
tool: typecheckRaw.tool,
|
|
14810
|
+
stdout: typecheckRaw.stdout,
|
|
14811
|
+
stderr: typecheckRaw.stderr,
|
|
14812
|
+
skipped: typecheckRaw.skipped
|
|
14813
|
+
};
|
|
14814
|
+
steps.push(typecheckStep);
|
|
14815
|
+
if (!typecheckStep.success && stopOnFirstFailure) {
|
|
14816
|
+
return { overall: "fail", steps, totalDurationMs: Date.now() - start };
|
|
14817
|
+
}
|
|
14818
|
+
const testRaw = await runTests({ profile: testProfile });
|
|
14819
|
+
const testStep = {
|
|
14820
|
+
name: "test",
|
|
14821
|
+
success: testRaw.success,
|
|
14822
|
+
tool: testRaw.tool,
|
|
14823
|
+
stdout: testRaw.stdout,
|
|
14824
|
+
stderr: testRaw.stderr,
|
|
14825
|
+
skipped: testRaw.skipped
|
|
14826
|
+
};
|
|
14827
|
+
steps.push(testStep);
|
|
14828
|
+
if (!testStep.success && stopOnFirstFailure) {
|
|
14829
|
+
return { overall: "fail", steps, totalDurationMs: Date.now() - start };
|
|
14830
|
+
}
|
|
14831
|
+
const buildRaw = await runBuild({ profile: buildProfile });
|
|
14832
|
+
const buildStep = {
|
|
14833
|
+
name: "build",
|
|
14834
|
+
success: buildRaw.success,
|
|
14835
|
+
tool: buildRaw.tool,
|
|
14836
|
+
stdout: buildRaw.stdout,
|
|
14837
|
+
stderr: buildRaw.stderr,
|
|
14838
|
+
skipped: buildRaw.skipped
|
|
14839
|
+
};
|
|
14840
|
+
steps.push(buildStep);
|
|
14841
|
+
const anyFailed = steps.some((s) => !s.success);
|
|
14842
|
+
return {
|
|
14843
|
+
overall: anyFailed ? "fail" : "pass",
|
|
14844
|
+
steps,
|
|
14845
|
+
totalDurationMs: Date.now() - start
|
|
14846
|
+
};
|
|
14847
|
+
}
|
|
14130
14848
|
var init_validationPipeline = __esm({
|
|
14131
14849
|
"packages/execution/dist/validationPipeline.js"() {
|
|
14132
14850
|
"use strict";
|
|
@@ -14139,6 +14857,97 @@ var init_validationPipeline = __esm({
|
|
|
14139
14857
|
});
|
|
14140
14858
|
|
|
14141
14859
|
// packages/execution/dist/index.js
|
|
14860
|
+
var dist_exports = {};
|
|
14861
|
+
__export(dist_exports, {
|
|
14862
|
+
AgendaTool: () => AgendaTool,
|
|
14863
|
+
AiwgHealthTool: () => AiwgHealthTool,
|
|
14864
|
+
AiwgSetupTool: () => AiwgSetupTool,
|
|
14865
|
+
AiwgWorkflowTool: () => AiwgWorkflowTool,
|
|
14866
|
+
AutoresearchTool: () => AutoresearchTool,
|
|
14867
|
+
BackgroundRunTool: () => BackgroundRunTool,
|
|
14868
|
+
BackgroundTaskManager: () => BackgroundTaskManager,
|
|
14869
|
+
BatchEditTool: () => BatchEditTool,
|
|
14870
|
+
BrowserActionTool: () => BrowserActionTool,
|
|
14871
|
+
CodeSandboxTool: () => CodeSandboxTool,
|
|
14872
|
+
CodebaseMapTool: () => CodebaseMapTool,
|
|
14873
|
+
CreateToolTool: () => CreateToolTool,
|
|
14874
|
+
CronAgentTool: () => CronAgentTool,
|
|
14875
|
+
CustomTool: () => CustomTool,
|
|
14876
|
+
DESKTOP_DEPS: () => DESKTOP_DEPS,
|
|
14877
|
+
DesktopClickTool: () => DesktopClickTool,
|
|
14878
|
+
DesktopDescribeTool: () => DesktopDescribeTool,
|
|
14879
|
+
DiagnosticTool: () => DiagnosticTool,
|
|
14880
|
+
ExploreToolsTool: () => ExploreToolsTool,
|
|
14881
|
+
FactoryTool: () => FactoryTool,
|
|
14882
|
+
FileEditTool: () => FileEditTool,
|
|
14883
|
+
FilePatchTool: () => FilePatchTool,
|
|
14884
|
+
FileReadTool: () => FileReadTool,
|
|
14885
|
+
FileWriteTool: () => FileWriteTool,
|
|
14886
|
+
GitInfoTool: () => GitInfoTool,
|
|
14887
|
+
GlobFindTool: () => GlobFindTool,
|
|
14888
|
+
GrepSearchTool: () => GrepSearchTool,
|
|
14889
|
+
ImageReadTool: () => ImageReadTool,
|
|
14890
|
+
ListDirectoryTool: () => ListDirectoryTool,
|
|
14891
|
+
ManageToolsTool: () => ManageToolsTool,
|
|
14892
|
+
MemoryReadTool: () => MemoryReadTool,
|
|
14893
|
+
MemorySearchTool: () => MemorySearchTool,
|
|
14894
|
+
MemoryWriteTool: () => MemoryWriteTool,
|
|
14895
|
+
NexusTool: () => NexusTool,
|
|
14896
|
+
OCRTool: () => OCRTool,
|
|
14897
|
+
OcrImageAdvancedTool: () => OcrImageAdvancedTool,
|
|
14898
|
+
OcrPdfTool: () => OcrPdfTool,
|
|
14899
|
+
OpenCodeTool: () => OpenCodeTool,
|
|
14900
|
+
PdfToTextTool: () => PdfToTextTool,
|
|
14901
|
+
ReminderTool: () => ReminderTool,
|
|
14902
|
+
SchedulerTool: () => SchedulerTool,
|
|
14903
|
+
ScreenshotTool: () => ScreenshotTool,
|
|
14904
|
+
ShellTool: () => ShellTool,
|
|
14905
|
+
SkillBuildTool: () => SkillBuildTool,
|
|
14906
|
+
SkillExecuteTool: () => SkillExecuteTool,
|
|
14907
|
+
SkillListTool: () => SkillListTool,
|
|
14908
|
+
StructuredFileTool: () => StructuredFileTool,
|
|
14909
|
+
StructuredReadTool: () => StructuredReadTool,
|
|
14910
|
+
TaskOutputTool: () => TaskOutputTool,
|
|
14911
|
+
TaskStatusTool: () => TaskStatusTool,
|
|
14912
|
+
TaskStopTool: () => TaskStopTool,
|
|
14913
|
+
ToolExecutor: () => ToolExecutor,
|
|
14914
|
+
TranscribeFileTool: () => TranscribeFileTool,
|
|
14915
|
+
TranscribeUrlTool: () => TranscribeUrlTool,
|
|
14916
|
+
VisionTool: () => VisionTool,
|
|
14917
|
+
WebCrawlTool: () => WebCrawlTool,
|
|
14918
|
+
WebFetchTool: () => WebFetchTool,
|
|
14919
|
+
WebSearchTool: () => WebSearchTool,
|
|
14920
|
+
applyPatch: () => applyPatch,
|
|
14921
|
+
buildCustomTools: () => buildCustomTools,
|
|
14922
|
+
buildSkillsSummary: () => buildSkillsSummary,
|
|
14923
|
+
checkDesktopDeps: () => checkDesktopDeps,
|
|
14924
|
+
createWorktree: () => createWorktree,
|
|
14925
|
+
detectSearchProvider: () => detectSearchProvider,
|
|
14926
|
+
discoverSkills: () => discoverSkills,
|
|
14927
|
+
ensureAllDesktopDeps: () => ensureAllDesktopDeps,
|
|
14928
|
+
ensureCommand: () => ensureCommand,
|
|
14929
|
+
ensureDepsForGroup: () => ensureDepsForGroup,
|
|
14930
|
+
getActiveAttentionItems: () => getActiveAttentionItems,
|
|
14931
|
+
getDueReminders: () => getDueReminders,
|
|
14932
|
+
isImagePath: () => isImagePath,
|
|
14933
|
+
listCustomToolFiles: () => listCustomToolFiles,
|
|
14934
|
+
loadCustomTools: () => loadCustomTools,
|
|
14935
|
+
loadReminderStore: () => loadReminderStore,
|
|
14936
|
+
loadSkillContent: () => loadSkillContent,
|
|
14937
|
+
markRemindersSeen: () => markRemindersSeen,
|
|
14938
|
+
removeWorktree: () => removeWorktree,
|
|
14939
|
+
resetDepCache: () => resetDepCache,
|
|
14940
|
+
resetMoondreamClient: () => resetMoondreamClient,
|
|
14941
|
+
runBuild: () => runBuild,
|
|
14942
|
+
runFormatter: () => runFormatter,
|
|
14943
|
+
runLinter: () => runLinter,
|
|
14944
|
+
runShell: () => runShell,
|
|
14945
|
+
runTests: () => runTests,
|
|
14946
|
+
runTypecheck: () => runTypecheck,
|
|
14947
|
+
runValidationPipeline: () => runValidationPipeline,
|
|
14948
|
+
saveCustomToolDefinition: () => saveCustomToolDefinition,
|
|
14949
|
+
setSudoPassword: () => setSudoPassword
|
|
14950
|
+
});
|
|
14142
14951
|
var init_dist2 = __esm({
|
|
14143
14952
|
"packages/execution/dist/index.js"() {
|
|
14144
14953
|
"use strict";
|
|
@@ -14873,17 +15682,17 @@ var init_dist3 = __esm({
|
|
|
14873
15682
|
});
|
|
14874
15683
|
|
|
14875
15684
|
// packages/orchestrator/dist/promptLoader.js
|
|
14876
|
-
import { readFileSync as
|
|
14877
|
-
import { join as join31, dirname as
|
|
15685
|
+
import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
|
|
15686
|
+
import { join as join31, dirname as dirname12 } from "node:path";
|
|
14878
15687
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
14879
15688
|
function loadPrompt(promptPath, vars) {
|
|
14880
15689
|
let content = cache.get(promptPath);
|
|
14881
15690
|
if (content === void 0) {
|
|
14882
15691
|
const fullPath = join31(PROMPTS_DIR, promptPath);
|
|
14883
|
-
if (!
|
|
15692
|
+
if (!existsSync25(fullPath)) {
|
|
14884
15693
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
14885
15694
|
}
|
|
14886
|
-
content =
|
|
15695
|
+
content = readFileSync18(fullPath, "utf-8");
|
|
14887
15696
|
cache.set(promptPath, content);
|
|
14888
15697
|
}
|
|
14889
15698
|
if (!vars)
|
|
@@ -14895,7 +15704,7 @@ var init_promptLoader = __esm({
|
|
|
14895
15704
|
"packages/orchestrator/dist/promptLoader.js"() {
|
|
14896
15705
|
"use strict";
|
|
14897
15706
|
__filename = fileURLToPath7(import.meta.url);
|
|
14898
|
-
__dirname4 =
|
|
15707
|
+
__dirname4 = dirname12(__filename);
|
|
14899
15708
|
PROMPTS_DIR = join31(__dirname4, "..", "prompts");
|
|
14900
15709
|
cache = /* @__PURE__ */ new Map();
|
|
14901
15710
|
}
|
|
@@ -15232,12 +16041,12 @@ var init_grep_search2 = __esm({
|
|
|
15232
16041
|
});
|
|
15233
16042
|
|
|
15234
16043
|
// packages/retrieval/dist/code-retriever.js
|
|
15235
|
-
var
|
|
16044
|
+
var DEFAULT_CONFIG3, CodeRetriever;
|
|
15236
16045
|
var init_code_retriever = __esm({
|
|
15237
16046
|
"packages/retrieval/dist/code-retriever.js"() {
|
|
15238
16047
|
"use strict";
|
|
15239
16048
|
init_grep_search2();
|
|
15240
|
-
|
|
16049
|
+
DEFAULT_CONFIG3 = {
|
|
15241
16050
|
rootDir: ".",
|
|
15242
16051
|
maxResults: 20,
|
|
15243
16052
|
maxFileSize: 5e5,
|
|
@@ -15248,7 +16057,7 @@ var init_code_retriever = __esm({
|
|
|
15248
16057
|
config;
|
|
15249
16058
|
grepSearch;
|
|
15250
16059
|
constructor(config) {
|
|
15251
|
-
this.config = { ...
|
|
16060
|
+
this.config = { ...DEFAULT_CONFIG3, ...config };
|
|
15252
16061
|
this.grepSearch = new GrepSearch(this.config.rootDir);
|
|
15253
16062
|
}
|
|
15254
16063
|
async searchByPattern(pattern) {
|
|
@@ -15959,8 +16768,8 @@ var init_contextAssembler = __esm({
|
|
|
15959
16768
|
});
|
|
15960
16769
|
|
|
15961
16770
|
// packages/retrieval/dist/index.js
|
|
15962
|
-
var
|
|
15963
|
-
__export(
|
|
16771
|
+
var dist_exports2 = {};
|
|
16772
|
+
__export(dist_exports2, {
|
|
15964
16773
|
CodeRetriever: () => CodeRetriever,
|
|
15965
16774
|
GrepSearch: () => GrepSearch,
|
|
15966
16775
|
IndexBackedSemanticSearchEngine: () => IndexBackedSemanticSearchEngine,
|
|
@@ -15997,7 +16806,7 @@ var init_dist4 = __esm({
|
|
|
15997
16806
|
|
|
15998
16807
|
// packages/orchestrator/dist/scoutRunner.js
|
|
15999
16808
|
async function loadCodeRetriever(rootDir) {
|
|
16000
|
-
const mod = await Promise.resolve().then(() => (init_dist4(),
|
|
16809
|
+
const mod = await Promise.resolve().then(() => (init_dist4(), dist_exports2));
|
|
16001
16810
|
return new mod.CodeRetriever({ rootDir });
|
|
16002
16811
|
}
|
|
16003
16812
|
function parseJsonFromContent4(content) {
|
|
@@ -18258,10 +19067,10 @@ ${marker}` : marker);
|
|
|
18258
19067
|
if (!this._workingDirectory)
|
|
18259
19068
|
return;
|
|
18260
19069
|
try {
|
|
18261
|
-
const { mkdirSync:
|
|
19070
|
+
const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync19 } = __require("node:fs");
|
|
18262
19071
|
const { join: join55 } = __require("node:path");
|
|
18263
19072
|
const sessionDir = join55(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
18264
|
-
|
|
19073
|
+
mkdirSync21(sessionDir, { recursive: true });
|
|
18265
19074
|
const checkpoint = {
|
|
18266
19075
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18267
19076
|
sessionId: this._sessionId,
|
|
@@ -18273,7 +19082,7 @@ ${marker}` : marker);
|
|
|
18273
19082
|
memexEntryCount: this._memexArchive.size,
|
|
18274
19083
|
fileRegistrySize: this._fileRegistry.size
|
|
18275
19084
|
};
|
|
18276
|
-
|
|
19085
|
+
writeFileSync19(join55(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
18277
19086
|
} catch {
|
|
18278
19087
|
}
|
|
18279
19088
|
}
|
|
@@ -19515,10 +20324,12 @@ var init_nexusBackend = __esm({
|
|
|
19515
20324
|
sendFn;
|
|
19516
20325
|
model;
|
|
19517
20326
|
targetPeer;
|
|
19518
|
-
|
|
20327
|
+
authKey;
|
|
20328
|
+
constructor(sendFn, model, targetPeer, authKey) {
|
|
19519
20329
|
this.sendFn = sendFn;
|
|
19520
20330
|
this.model = model;
|
|
19521
20331
|
this.targetPeer = targetPeer || "";
|
|
20332
|
+
this.authKey = authKey || "";
|
|
19522
20333
|
}
|
|
19523
20334
|
async chatCompletion(request) {
|
|
19524
20335
|
const daemonArgs = {
|
|
@@ -19531,6 +20342,9 @@ var init_nexusBackend = __esm({
|
|
|
19531
20342
|
if (this.targetPeer) {
|
|
19532
20343
|
daemonArgs.target_peer = this.targetPeer;
|
|
19533
20344
|
}
|
|
20345
|
+
if (this.authKey) {
|
|
20346
|
+
daemonArgs.auth_key = this.authKey;
|
|
20347
|
+
}
|
|
19534
20348
|
const rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
|
|
19535
20349
|
let parsed;
|
|
19536
20350
|
try {
|
|
@@ -19664,6 +20478,273 @@ var init_nexusBackend = __esm({
|
|
|
19664
20478
|
}
|
|
19665
20479
|
});
|
|
19666
20480
|
|
|
20481
|
+
// packages/orchestrator/dist/cascadeBackend.js
|
|
20482
|
+
var CascadeBackend;
|
|
20483
|
+
var init_cascadeBackend = __esm({
|
|
20484
|
+
"packages/orchestrator/dist/cascadeBackend.js"() {
|
|
20485
|
+
"use strict";
|
|
20486
|
+
init_agenticRunner();
|
|
20487
|
+
init_nexusBackend();
|
|
20488
|
+
CascadeBackend = class {
|
|
20489
|
+
model;
|
|
20490
|
+
endpoints;
|
|
20491
|
+
backends = /* @__PURE__ */ new Map();
|
|
20492
|
+
activeIndex = 0;
|
|
20493
|
+
consecutiveFailures = 0;
|
|
20494
|
+
maxFailures;
|
|
20495
|
+
probeTimer = null;
|
|
20496
|
+
onSwitch;
|
|
20497
|
+
onProbeResult;
|
|
20498
|
+
stopped = false;
|
|
20499
|
+
constructor(model, endpoints, options) {
|
|
20500
|
+
if (endpoints.length === 0)
|
|
20501
|
+
throw new Error("CascadeBackend requires at least one endpoint");
|
|
20502
|
+
this.model = model;
|
|
20503
|
+
this.endpoints = [...endpoints];
|
|
20504
|
+
this.maxFailures = options?.maxFailuresBeforeSwitch ?? 2;
|
|
20505
|
+
this.onSwitch = options?.onSwitch;
|
|
20506
|
+
this.onProbeResult = options?.onProbeResult;
|
|
20507
|
+
for (const ep of this.endpoints) {
|
|
20508
|
+
this.backends.set(ep.url, this.createBackend(ep));
|
|
20509
|
+
}
|
|
20510
|
+
if (this.endpoints.length > 1) {
|
|
20511
|
+
const probeInterval = options?.probeIntervalMs ?? 3e4;
|
|
20512
|
+
this.probeTimer = setInterval(() => this.probePrimary(), probeInterval);
|
|
20513
|
+
}
|
|
20514
|
+
}
|
|
20515
|
+
/** Get the currently active endpoint */
|
|
20516
|
+
get activeEndpoint() {
|
|
20517
|
+
return this.endpoints[this.activeIndex];
|
|
20518
|
+
}
|
|
20519
|
+
/** Get all endpoints with their status */
|
|
20520
|
+
get endpointStatus() {
|
|
20521
|
+
return this.endpoints.map((ep, i) => ({
|
|
20522
|
+
...ep,
|
|
20523
|
+
active: i === this.activeIndex,
|
|
20524
|
+
failures: i === this.activeIndex ? this.consecutiveFailures : 0
|
|
20525
|
+
}));
|
|
20526
|
+
}
|
|
20527
|
+
/** Number of available fallback endpoints */
|
|
20528
|
+
get fallbackCount() {
|
|
20529
|
+
return this.endpoints.filter((ep, i) => i !== this.activeIndex && ep.modelAvailable !== false).length;
|
|
20530
|
+
}
|
|
20531
|
+
async chatCompletion(request) {
|
|
20532
|
+
const backend = this.getActiveBackend();
|
|
20533
|
+
try {
|
|
20534
|
+
const result = await backend.chatCompletion(request);
|
|
20535
|
+
this.consecutiveFailures = 0;
|
|
20536
|
+
return result;
|
|
20537
|
+
} catch (err) {
|
|
20538
|
+
this.consecutiveFailures++;
|
|
20539
|
+
if (this.isTransientError(err) && this.consecutiveFailures >= this.maxFailures) {
|
|
20540
|
+
const nextIdx = this.findNextAvailableEndpoint();
|
|
20541
|
+
if (nextIdx !== null && nextIdx !== this.activeIndex) {
|
|
20542
|
+
const from = this.endpoints[this.activeIndex];
|
|
20543
|
+
const to = this.endpoints[nextIdx];
|
|
20544
|
+
const reason = `${this.consecutiveFailures} consecutive failures: ${err instanceof Error ? err.message : String(err)}`;
|
|
20545
|
+
this.activeIndex = nextIdx;
|
|
20546
|
+
this.consecutiveFailures = 0;
|
|
20547
|
+
this.onSwitch?.(from, to, reason);
|
|
20548
|
+
const newBackend = this.getActiveBackend();
|
|
20549
|
+
try {
|
|
20550
|
+
const result = await newBackend.chatCompletion(request);
|
|
20551
|
+
return result;
|
|
20552
|
+
} catch (cascadeErr) {
|
|
20553
|
+
this.consecutiveFailures++;
|
|
20554
|
+
throw cascadeErr;
|
|
20555
|
+
}
|
|
20556
|
+
}
|
|
20557
|
+
}
|
|
20558
|
+
throw err;
|
|
20559
|
+
}
|
|
20560
|
+
}
|
|
20561
|
+
/**
|
|
20562
|
+
* Streaming support — delegates to active backend's stream method if available.
|
|
20563
|
+
*/
|
|
20564
|
+
async *chatCompletionStream(request) {
|
|
20565
|
+
const backend = this.getActiveBackend();
|
|
20566
|
+
const streamable = backend;
|
|
20567
|
+
if (typeof streamable.chatCompletionStream !== "function") {
|
|
20568
|
+
const result = await this.chatCompletion(request);
|
|
20569
|
+
const choice = result.choices[0];
|
|
20570
|
+
if (choice?.message.content) {
|
|
20571
|
+
yield { type: "content", content: choice.message.content };
|
|
20572
|
+
}
|
|
20573
|
+
if (choice?.message.toolCalls) {
|
|
20574
|
+
for (let i = 0; i < choice.message.toolCalls.length; i++) {
|
|
20575
|
+
const tc = choice.message.toolCalls[i];
|
|
20576
|
+
yield {
|
|
20577
|
+
type: "tool_call_delta",
|
|
20578
|
+
toolCallIndex: i,
|
|
20579
|
+
toolCallId: tc.id,
|
|
20580
|
+
toolCallName: tc.name,
|
|
20581
|
+
toolCallArgs: JSON.stringify(tc.arguments)
|
|
20582
|
+
};
|
|
20583
|
+
}
|
|
20584
|
+
}
|
|
20585
|
+
if (result.usage) {
|
|
20586
|
+
yield {
|
|
20587
|
+
type: "usage",
|
|
20588
|
+
usage: {
|
|
20589
|
+
promptTokens: result.usage.promptTokens ?? 0,
|
|
20590
|
+
completionTokens: result.usage.completionTokens ?? 0,
|
|
20591
|
+
totalTokens: result.usage.totalTokens
|
|
20592
|
+
}
|
|
20593
|
+
};
|
|
20594
|
+
}
|
|
20595
|
+
yield { type: "finish", finishReason: "stop" };
|
|
20596
|
+
return;
|
|
20597
|
+
}
|
|
20598
|
+
try {
|
|
20599
|
+
for await (const chunk of streamable.chatCompletionStream(request)) {
|
|
20600
|
+
yield chunk;
|
|
20601
|
+
}
|
|
20602
|
+
this.consecutiveFailures = 0;
|
|
20603
|
+
} catch (err) {
|
|
20604
|
+
this.consecutiveFailures++;
|
|
20605
|
+
if (this.isTransientError(err) && this.consecutiveFailures >= this.maxFailures) {
|
|
20606
|
+
const nextIdx = this.findNextAvailableEndpoint();
|
|
20607
|
+
if (nextIdx !== null && nextIdx !== this.activeIndex) {
|
|
20608
|
+
const from = this.endpoints[this.activeIndex];
|
|
20609
|
+
const to = this.endpoints[nextIdx];
|
|
20610
|
+
this.activeIndex = nextIdx;
|
|
20611
|
+
this.consecutiveFailures = 0;
|
|
20612
|
+
this.onSwitch?.(from, to, err instanceof Error ? err.message : String(err));
|
|
20613
|
+
const result = await this.chatCompletion(request);
|
|
20614
|
+
const choice = result.choices[0];
|
|
20615
|
+
if (choice?.message.content) {
|
|
20616
|
+
yield { type: "content", content: choice.message.content };
|
|
20617
|
+
}
|
|
20618
|
+
if (choice?.message.toolCalls) {
|
|
20619
|
+
for (let i = 0; i < choice.message.toolCalls.length; i++) {
|
|
20620
|
+
const tc = choice.message.toolCalls[i];
|
|
20621
|
+
yield {
|
|
20622
|
+
type: "tool_call_delta",
|
|
20623
|
+
toolCallIndex: i,
|
|
20624
|
+
toolCallId: tc.id,
|
|
20625
|
+
toolCallName: tc.name,
|
|
20626
|
+
toolCallArgs: JSON.stringify(tc.arguments)
|
|
20627
|
+
};
|
|
20628
|
+
}
|
|
20629
|
+
}
|
|
20630
|
+
yield { type: "finish", finishReason: "stop" };
|
|
20631
|
+
return;
|
|
20632
|
+
}
|
|
20633
|
+
}
|
|
20634
|
+
throw err;
|
|
20635
|
+
}
|
|
20636
|
+
}
|
|
20637
|
+
/** Add a fallback endpoint at the end of the cascade */
|
|
20638
|
+
addEndpoint(endpoint) {
|
|
20639
|
+
this.endpoints.push(endpoint);
|
|
20640
|
+
this.backends.set(endpoint.url, this.createBackend(endpoint));
|
|
20641
|
+
if (this.endpoints.length === 2 && !this.probeTimer) {
|
|
20642
|
+
this.probeTimer = setInterval(() => this.probePrimary(), 3e4);
|
|
20643
|
+
}
|
|
20644
|
+
}
|
|
20645
|
+
/** Remove an endpoint from the cascade */
|
|
20646
|
+
removeEndpoint(url) {
|
|
20647
|
+
const idx = this.endpoints.findIndex((ep) => ep.url === url);
|
|
20648
|
+
if (idx === -1)
|
|
20649
|
+
return;
|
|
20650
|
+
if (idx === this.activeIndex)
|
|
20651
|
+
return;
|
|
20652
|
+
this.endpoints.splice(idx, 1);
|
|
20653
|
+
this.backends.delete(url);
|
|
20654
|
+
if (this.activeIndex > idx) {
|
|
20655
|
+
this.activeIndex--;
|
|
20656
|
+
}
|
|
20657
|
+
}
|
|
20658
|
+
/** Stop the cascade (clears probe timer) */
|
|
20659
|
+
stop() {
|
|
20660
|
+
this.stopped = true;
|
|
20661
|
+
if (this.probeTimer) {
|
|
20662
|
+
clearInterval(this.probeTimer);
|
|
20663
|
+
this.probeTimer = null;
|
|
20664
|
+
}
|
|
20665
|
+
}
|
|
20666
|
+
/** Update the model (e.g. when user runs /model) */
|
|
20667
|
+
setModel(model) {
|
|
20668
|
+
this.model = model;
|
|
20669
|
+
for (const ep of this.endpoints) {
|
|
20670
|
+
this.backends.set(ep.url, this.createBackend(ep));
|
|
20671
|
+
}
|
|
20672
|
+
}
|
|
20673
|
+
// ── Private helpers ────────────────────────────────────────────────────
|
|
20674
|
+
getActiveBackend() {
|
|
20675
|
+
const ep = this.endpoints[this.activeIndex];
|
|
20676
|
+
return this.backends.get(ep.url);
|
|
20677
|
+
}
|
|
20678
|
+
createBackend(ep) {
|
|
20679
|
+
if (ep.backendType === "nexus" && ep.sendCommandFn) {
|
|
20680
|
+
const targetPeer = ep.url.startsWith("peer://") ? ep.url.slice(7) : void 0;
|
|
20681
|
+
return new NexusAgenticBackend(ep.sendCommandFn, this.model, targetPeer, ep.apiKey);
|
|
20682
|
+
}
|
|
20683
|
+
return new OllamaAgenticBackend(ep.url, this.model, ep.apiKey);
|
|
20684
|
+
}
|
|
20685
|
+
findNextAvailableEndpoint() {
|
|
20686
|
+
for (let offset = 1; offset < this.endpoints.length; offset++) {
|
|
20687
|
+
const idx = (this.activeIndex + offset) % this.endpoints.length;
|
|
20688
|
+
const ep = this.endpoints[idx];
|
|
20689
|
+
if (ep.modelAvailable !== false) {
|
|
20690
|
+
return idx;
|
|
20691
|
+
}
|
|
20692
|
+
}
|
|
20693
|
+
return null;
|
|
20694
|
+
}
|
|
20695
|
+
isTransientError(err) {
|
|
20696
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
20697
|
+
if (/Backend HTTP (502|503|504)/i.test(msg))
|
|
20698
|
+
return true;
|
|
20699
|
+
if (/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EPIPE|socket hang up/i.test(msg))
|
|
20700
|
+
return true;
|
|
20701
|
+
if (/received HTML error page/i.test(msg))
|
|
20702
|
+
return true;
|
|
20703
|
+
if (/model is loading|server busy|overloaded/i.test(msg))
|
|
20704
|
+
return true;
|
|
20705
|
+
if (/remote inference failed|timed out/i.test(msg))
|
|
20706
|
+
return true;
|
|
20707
|
+
return false;
|
|
20708
|
+
}
|
|
20709
|
+
/**
|
|
20710
|
+
* Probe the primary endpoint to check if it's recovered.
|
|
20711
|
+
* If the current active endpoint is NOT the primary, tests the primary
|
|
20712
|
+
* with a lightweight request and switches back if successful.
|
|
20713
|
+
*/
|
|
20714
|
+
async probePrimary() {
|
|
20715
|
+
if (this.stopped)
|
|
20716
|
+
return;
|
|
20717
|
+
if (this.activeIndex === 0)
|
|
20718
|
+
return;
|
|
20719
|
+
if (this.endpoints.length === 0)
|
|
20720
|
+
return;
|
|
20721
|
+
const primary = this.endpoints[0];
|
|
20722
|
+
const primaryBackend = this.backends.get(primary.url);
|
|
20723
|
+
if (!primaryBackend)
|
|
20724
|
+
return;
|
|
20725
|
+
try {
|
|
20726
|
+
const result = await primaryBackend.chatCompletion({
|
|
20727
|
+
messages: [{ role: "user", content: "ping" }],
|
|
20728
|
+
tools: [],
|
|
20729
|
+
temperature: 0,
|
|
20730
|
+
maxTokens: 1,
|
|
20731
|
+
timeoutMs: 1e4
|
|
20732
|
+
});
|
|
20733
|
+
if (result.choices.length > 0) {
|
|
20734
|
+
this.onProbeResult?.(primary, true);
|
|
20735
|
+
const from = this.endpoints[this.activeIndex];
|
|
20736
|
+
this.activeIndex = 0;
|
|
20737
|
+
this.consecutiveFailures = 0;
|
|
20738
|
+
this.onSwitch?.(from, primary, "Primary endpoint recovered");
|
|
20739
|
+
}
|
|
20740
|
+
} catch {
|
|
20741
|
+
this.onProbeResult?.(primary, false);
|
|
20742
|
+
}
|
|
20743
|
+
}
|
|
20744
|
+
};
|
|
20745
|
+
}
|
|
20746
|
+
});
|
|
20747
|
+
|
|
19667
20748
|
// packages/orchestrator/dist/flowstatePrompt.js
|
|
19668
20749
|
var FLOWSTATE_PROMPT;
|
|
19669
20750
|
var init_flowstatePrompt = __esm({
|
|
@@ -20198,6 +21279,7 @@ var init_dist5 = __esm({
|
|
|
20198
21279
|
init_retryController();
|
|
20199
21280
|
init_agenticRunner();
|
|
20200
21281
|
init_nexusBackend();
|
|
21282
|
+
init_cascadeBackend();
|
|
20201
21283
|
init_flowstatePrompt();
|
|
20202
21284
|
init_costTracker();
|
|
20203
21285
|
init_workEvaluator();
|
|
@@ -20218,9 +21300,9 @@ __export(listen_exports, {
|
|
|
20218
21300
|
isVideoPath: () => isVideoPath,
|
|
20219
21301
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
20220
21302
|
});
|
|
20221
|
-
import { spawn as
|
|
20222
|
-
import { existsSync as
|
|
20223
|
-
import { join as join34, dirname as
|
|
21303
|
+
import { spawn as spawn14, execSync as execSync23 } from "node:child_process";
|
|
21304
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, readdirSync as readdirSync6 } from "node:fs";
|
|
21305
|
+
import { join as join34, dirname as dirname13 } from "node:path";
|
|
20224
21306
|
import { homedir as homedir8 } from "node:os";
|
|
20225
21307
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
20226
21308
|
import { EventEmitter } from "node:events";
|
|
@@ -20304,7 +21386,7 @@ function findMicCaptureCommand() {
|
|
|
20304
21386
|
return null;
|
|
20305
21387
|
}
|
|
20306
21388
|
function findLiveWhisperScript() {
|
|
20307
|
-
const thisDir =
|
|
21389
|
+
const thisDir = dirname13(fileURLToPath8(import.meta.url));
|
|
20308
21390
|
const candidates = [
|
|
20309
21391
|
join34(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
20310
21392
|
join34(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
@@ -20314,7 +21396,7 @@ function findLiveWhisperScript() {
|
|
|
20314
21396
|
join34(thisDir, "../../scripts/live-whisper.py")
|
|
20315
21397
|
];
|
|
20316
21398
|
for (const p of candidates) {
|
|
20317
|
-
if (
|
|
21399
|
+
if (existsSync26(p))
|
|
20318
21400
|
return p;
|
|
20319
21401
|
}
|
|
20320
21402
|
try {
|
|
@@ -20328,17 +21410,17 @@ function findLiveWhisperScript() {
|
|
|
20328
21410
|
join34(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
20329
21411
|
];
|
|
20330
21412
|
for (const p of candidates2) {
|
|
20331
|
-
if (
|
|
21413
|
+
if (existsSync26(p))
|
|
20332
21414
|
return p;
|
|
20333
21415
|
}
|
|
20334
21416
|
} catch {
|
|
20335
21417
|
}
|
|
20336
21418
|
const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
|
|
20337
|
-
if (
|
|
21419
|
+
if (existsSync26(nvmBase)) {
|
|
20338
21420
|
try {
|
|
20339
21421
|
for (const ver of readdirSync6(nvmBase)) {
|
|
20340
21422
|
const p = join34(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
20341
|
-
if (
|
|
21423
|
+
if (existsSync26(p))
|
|
20342
21424
|
return p;
|
|
20343
21425
|
}
|
|
20344
21426
|
} catch {
|
|
@@ -20356,7 +21438,7 @@ function ensureTranscribeCliBackground() {
|
|
|
20356
21438
|
timeout: 5e3,
|
|
20357
21439
|
stdio: ["pipe", "pipe", "pipe"]
|
|
20358
21440
|
}).trim();
|
|
20359
|
-
if (
|
|
21441
|
+
if (existsSync26(join34(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
20360
21442
|
return true;
|
|
20361
21443
|
}
|
|
20362
21444
|
} catch {
|
|
@@ -20428,7 +21510,7 @@ var init_listen = __esm({
|
|
|
20428
21510
|
const timeout = setTimeout(() => {
|
|
20429
21511
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
20430
21512
|
}, 3e5);
|
|
20431
|
-
this.process =
|
|
21513
|
+
this.process = spawn14("python3", [
|
|
20432
21514
|
this.scriptPath,
|
|
20433
21515
|
"--model",
|
|
20434
21516
|
this.model,
|
|
@@ -20580,7 +21662,7 @@ var init_listen = __esm({
|
|
|
20580
21662
|
stdio: ["pipe", "pipe", "pipe"]
|
|
20581
21663
|
}).trim();
|
|
20582
21664
|
const tcPath = join34(globalRoot, "transcribe-cli");
|
|
20583
|
-
if (
|
|
21665
|
+
if (existsSync26(join34(tcPath, "dist", "index.js"))) {
|
|
20584
21666
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
20585
21667
|
const req = createRequire4(import.meta.url);
|
|
20586
21668
|
return req(join34(tcPath, "dist", "index.js"));
|
|
@@ -20588,12 +21670,12 @@ var init_listen = __esm({
|
|
|
20588
21670
|
} catch {
|
|
20589
21671
|
}
|
|
20590
21672
|
const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
|
|
20591
|
-
if (
|
|
21673
|
+
if (existsSync26(nvmBase)) {
|
|
20592
21674
|
try {
|
|
20593
21675
|
const { readdirSync: readdirSync16 } = await import("node:fs");
|
|
20594
21676
|
for (const ver of readdirSync16(nvmBase)) {
|
|
20595
21677
|
const tcPath = join34(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
20596
|
-
if (
|
|
21678
|
+
if (existsSync26(join34(tcPath, "dist", "index.js"))) {
|
|
20597
21679
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
20598
21680
|
const req = createRequire4(import.meta.url);
|
|
20599
21681
|
return req(join34(tcPath, "dist", "index.js"));
|
|
@@ -20710,7 +21792,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
20710
21792
|
return `Failed to start live transcription: ${msg}${tcHint}`;
|
|
20711
21793
|
}
|
|
20712
21794
|
}
|
|
20713
|
-
this.micProcess =
|
|
21795
|
+
this.micProcess = spawn14(micCmd.cmd, micCmd.args, {
|
|
20714
21796
|
stdio: ["pipe", "pipe", "pipe"],
|
|
20715
21797
|
env: { ...process.env }
|
|
20716
21798
|
});
|
|
@@ -20879,9 +21961,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
20879
21961
|
if (outputDir) {
|
|
20880
21962
|
const { basename: basename16 } = await import("node:path");
|
|
20881
21963
|
const transcriptDir = join34(outputDir, ".oa", "transcripts");
|
|
20882
|
-
|
|
21964
|
+
mkdirSync8(transcriptDir, { recursive: true });
|
|
20883
21965
|
const outFile = join34(transcriptDir, `${basename16(filePath)}.txt`);
|
|
20884
|
-
|
|
21966
|
+
writeFileSync8(outFile, result.text, "utf-8");
|
|
20885
21967
|
}
|
|
20886
21968
|
return {
|
|
20887
21969
|
text: result.text,
|
|
@@ -25470,7 +26552,7 @@ var init_render = __esm({
|
|
|
25470
26552
|
|
|
25471
26553
|
// packages/cli/dist/tui/voice-session.js
|
|
25472
26554
|
import { createServer } from "node:http";
|
|
25473
|
-
import { spawn as
|
|
26555
|
+
import { spawn as spawn15, execSync as execSync24 } from "node:child_process";
|
|
25474
26556
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
25475
26557
|
function generateFrontendHTML() {
|
|
25476
26558
|
return `<!DOCTYPE html>
|
|
@@ -26124,7 +27206,7 @@ var init_voice_session = __esm({
|
|
|
26124
27206
|
const timeout = setTimeout(() => {
|
|
26125
27207
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
26126
27208
|
}, 3e4);
|
|
26127
|
-
this.cloudflaredProcess =
|
|
27209
|
+
this.cloudflaredProcess = spawn15("cloudflared", [
|
|
26128
27210
|
"tunnel",
|
|
26129
27211
|
"--url",
|
|
26130
27212
|
`http://127.0.0.1:${port}`
|
|
@@ -26198,12 +27280,12 @@ var init_voice_session = __esm({
|
|
|
26198
27280
|
|
|
26199
27281
|
// packages/cli/dist/tui/expose.js
|
|
26200
27282
|
import { createServer as createServer2, request as httpRequest } from "node:http";
|
|
26201
|
-
import { spawn as
|
|
27283
|
+
import { spawn as spawn16, exec } from "node:child_process";
|
|
26202
27284
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
26203
27285
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
26204
27286
|
import { URL as URL2 } from "node:url";
|
|
26205
27287
|
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
26206
|
-
import { existsSync as
|
|
27288
|
+
import { existsSync as existsSync27, readFileSync as readFileSync19, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, readdirSync as readdirSync7 } from "node:fs";
|
|
26207
27289
|
import { join as join35 } from "node:path";
|
|
26208
27290
|
function cleanForwardHeaders(raw, targetHost) {
|
|
26209
27291
|
const out = {};
|
|
@@ -26233,9 +27315,9 @@ function fmtTokens(n) {
|
|
|
26233
27315
|
function readExposeState(stateDir) {
|
|
26234
27316
|
try {
|
|
26235
27317
|
const path = join35(stateDir, STATE_FILE_NAME);
|
|
26236
|
-
if (!
|
|
27318
|
+
if (!existsSync27(path))
|
|
26237
27319
|
return null;
|
|
26238
|
-
const raw =
|
|
27320
|
+
const raw = readFileSync19(path, "utf8");
|
|
26239
27321
|
const data = JSON.parse(raw);
|
|
26240
27322
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort)
|
|
26241
27323
|
return null;
|
|
@@ -26246,8 +27328,8 @@ function readExposeState(stateDir) {
|
|
|
26246
27328
|
}
|
|
26247
27329
|
function writeExposeState(stateDir, state) {
|
|
26248
27330
|
try {
|
|
26249
|
-
|
|
26250
|
-
|
|
27331
|
+
mkdirSync9(stateDir, { recursive: true });
|
|
27332
|
+
writeFileSync9(join35(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
26251
27333
|
} catch {
|
|
26252
27334
|
}
|
|
26253
27335
|
}
|
|
@@ -26349,6 +27431,7 @@ var init_expose = __esm({
|
|
|
26349
27431
|
_targetUrl;
|
|
26350
27432
|
_kind;
|
|
26351
27433
|
_stateDir;
|
|
27434
|
+
_fullAccess;
|
|
26352
27435
|
_stats = {
|
|
26353
27436
|
status: "standby",
|
|
26354
27437
|
totalRequests: 0,
|
|
@@ -26381,6 +27464,7 @@ var init_expose = __esm({
|
|
|
26381
27464
|
this._kind = options.kind;
|
|
26382
27465
|
this._targetUrl = options.targetUrl ?? DEFAULT_TARGETS[options.kind];
|
|
26383
27466
|
this._stateDir = options.stateDir ?? null;
|
|
27467
|
+
this._fullAccess = options.fullAccess ?? false;
|
|
26384
27468
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
26385
27469
|
this._authKey = randomBytes7(24).toString("base64url");
|
|
26386
27470
|
} else {
|
|
@@ -26566,6 +27650,18 @@ var init_expose = __esm({
|
|
|
26566
27650
|
this.emitStats();
|
|
26567
27651
|
url.searchParams.delete("key");
|
|
26568
27652
|
const forwardPath = url.pathname + url.search;
|
|
27653
|
+
if (!this._fullAccess) {
|
|
27654
|
+
const p = url.pathname.toLowerCase();
|
|
27655
|
+
if (p === "/api/pull" || p === "/api/delete" || p === "/api/create" || p === "/api/copy" || p === "/api/push" || p === "/api/blobs") {
|
|
27656
|
+
this._stats.activeConnections--;
|
|
27657
|
+
user.activeRequests--;
|
|
27658
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
27659
|
+
res.end(JSON.stringify({
|
|
27660
|
+
error: "Forbidden \u2014 model management is disabled. Provider must run /expose with --full to allow this."
|
|
27661
|
+
}));
|
|
27662
|
+
return;
|
|
27663
|
+
}
|
|
27664
|
+
}
|
|
26569
27665
|
const bodyChunks = [];
|
|
26570
27666
|
req.on("data", (chunk) => bodyChunks.push(chunk));
|
|
26571
27667
|
req.on("end", () => {
|
|
@@ -26755,7 +27851,7 @@ var init_expose = __esm({
|
|
|
26755
27851
|
const timeout = setTimeout(() => {
|
|
26756
27852
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
26757
27853
|
}, 3e4);
|
|
26758
|
-
this.cloudflaredProcess =
|
|
27854
|
+
this.cloudflaredProcess = spawn16("cloudflared", [
|
|
26759
27855
|
"tunnel",
|
|
26760
27856
|
"--url",
|
|
26761
27857
|
`http://127.0.0.1:${port}`,
|
|
@@ -26956,6 +28052,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
26956
28052
|
// NexusTool instance
|
|
26957
28053
|
_kind;
|
|
26958
28054
|
_targetUrl;
|
|
28055
|
+
_authKey;
|
|
26959
28056
|
_peerId = null;
|
|
26960
28057
|
_capabilities = [];
|
|
26961
28058
|
_exposedModels = 0;
|
|
@@ -26976,6 +28073,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
26976
28073
|
get peerId() {
|
|
26977
28074
|
return this._peerId;
|
|
26978
28075
|
}
|
|
28076
|
+
get authKey() {
|
|
28077
|
+
return this._authKey;
|
|
28078
|
+
}
|
|
26979
28079
|
get stats() {
|
|
26980
28080
|
return this._stats;
|
|
26981
28081
|
}
|
|
@@ -26999,6 +28099,11 @@ ${this.formatConnectionInfo()}`);
|
|
|
26999
28099
|
this._margin = options.margin ?? 0.5;
|
|
27000
28100
|
this._onInfo = options.onInfo;
|
|
27001
28101
|
this._onError = options.onError;
|
|
28102
|
+
if (options.authKey === void 0 || options.authKey === "") {
|
|
28103
|
+
this._authKey = randomBytes7(24).toString("base64url");
|
|
28104
|
+
} else {
|
|
28105
|
+
this._authKey = options.authKey;
|
|
28106
|
+
}
|
|
27002
28107
|
}
|
|
27003
28108
|
async start() {
|
|
27004
28109
|
this._onInfo?.("Connecting to nexus P2P network...");
|
|
@@ -27015,14 +28120,16 @@ ${this.formatConnectionInfo()}`);
|
|
|
27015
28120
|
let exposeResult = await this._nexusTool.execute({
|
|
27016
28121
|
action: "expose",
|
|
27017
28122
|
ollama_url: this._targetUrl,
|
|
27018
|
-
margin: String(this._margin)
|
|
28123
|
+
margin: String(this._margin),
|
|
28124
|
+
auth_key: this._authKey
|
|
27019
28125
|
});
|
|
27020
28126
|
if (!exposeResult.success && exposeResult.error?.includes("not running")) {
|
|
27021
28127
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
27022
28128
|
exposeResult = await this._nexusTool.execute({
|
|
27023
28129
|
action: "expose",
|
|
27024
28130
|
ollama_url: this._targetUrl,
|
|
27025
|
-
margin: String(this._margin)
|
|
28131
|
+
margin: String(this._margin),
|
|
28132
|
+
auth_key: this._authKey
|
|
27026
28133
|
});
|
|
27027
28134
|
}
|
|
27028
28135
|
if (!exposeResult.success) {
|
|
@@ -27032,7 +28139,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
27032
28139
|
const statusPath = join35(nexusDir, "status.json");
|
|
27033
28140
|
for (let i = 0; i < 60; i++) {
|
|
27034
28141
|
try {
|
|
27035
|
-
const raw =
|
|
28142
|
+
const raw = readFileSync19(statusPath, "utf8");
|
|
27036
28143
|
if (raw.length > 10) {
|
|
27037
28144
|
const status = JSON.parse(raw);
|
|
27038
28145
|
if (status.connected && status.peerId) {
|
|
@@ -27065,8 +28172,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
27065
28172
|
this._pollTimer = setInterval(() => {
|
|
27066
28173
|
try {
|
|
27067
28174
|
const statusPath = join35(nexusDir, "status.json");
|
|
27068
|
-
if (
|
|
27069
|
-
const status = JSON.parse(
|
|
28175
|
+
if (existsSync27(statusPath)) {
|
|
28176
|
+
const status = JSON.parse(readFileSync19(statusPath, "utf8"));
|
|
27070
28177
|
if (status.peerId && !this._peerId) {
|
|
27071
28178
|
this._peerId = status.peerId;
|
|
27072
28179
|
}
|
|
@@ -27076,7 +28183,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
27076
28183
|
}
|
|
27077
28184
|
try {
|
|
27078
28185
|
const invocDir = join35(nexusDir, "invocations");
|
|
27079
|
-
if (
|
|
28186
|
+
if (existsSync27(invocDir)) {
|
|
27080
28187
|
const files = readdirSync7(invocDir);
|
|
27081
28188
|
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
27082
28189
|
if (invocCount > this._stats.totalRequests) {
|
|
@@ -27088,8 +28195,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
27088
28195
|
}
|
|
27089
28196
|
try {
|
|
27090
28197
|
const meteringFile = join35(nexusDir, "metering.jsonl");
|
|
27091
|
-
if (
|
|
27092
|
-
const content =
|
|
28198
|
+
if (existsSync27(meteringFile)) {
|
|
28199
|
+
const content = readFileSync19(meteringFile, "utf8");
|
|
27093
28200
|
if (content.length > lastMeteringSize) {
|
|
27094
28201
|
const newContent = content.slice(lastMeteringSize);
|
|
27095
28202
|
lastMeteringSize = content.length;
|
|
@@ -27165,15 +28272,24 @@ ${this.formatConnectionInfo()}`);
|
|
|
27165
28272
|
}
|
|
27166
28273
|
/** Format connection info for display */
|
|
27167
28274
|
formatConnectionInfo() {
|
|
28275
|
+
const endpointCmd = `/endpoint ${this._peerId ?? "<peer-id>"} --auth ${this._authKey}`;
|
|
27168
28276
|
const lines = [];
|
|
27169
28277
|
lines.push(` ${c2.green("\u25CF")} Expose gateway active ${c2.dim("(libp2p)")}`);
|
|
27170
28278
|
lines.push(` ${c2.cyan("Backend".padEnd(12))} ${this._kind} (${this._targetUrl})`);
|
|
27171
28279
|
lines.push(` ${c2.cyan("Transport".padEnd(12))} ${c2.bold("libp2p")} (DHT + mDNS + NATS relay)`);
|
|
27172
28280
|
lines.push(` ${c2.cyan("Peer ID".padEnd(12))} ${c2.bold(this._peerId ?? "connecting...")}`);
|
|
28281
|
+
lines.push(` ${c2.cyan("Auth Key".padEnd(12))} ${c2.bold(this._authKey)}`);
|
|
27173
28282
|
lines.push(` ${c2.cyan("Models".padEnd(12))} ${this._exposedModels || this._capabilities.filter((cap) => cap.startsWith("inference:")).length} exposed`);
|
|
27174
28283
|
lines.push("");
|
|
27175
|
-
lines.push(` ${c2.dim("Remote
|
|
27176
|
-
lines.push(` ${c2.
|
|
28284
|
+
lines.push(` ${c2.dim("Remote consumers connect with:")}`);
|
|
28285
|
+
lines.push(` ${c2.bold(endpointCmd)}`);
|
|
28286
|
+
lines.push("");
|
|
28287
|
+
lines.push(` ${c2.yellow("!")} ${c2.dim("Keep this key secure \u2014 it grants full access to your models.")}`);
|
|
28288
|
+
if ((process.stdout.isTTY ?? false) && this._peerId) {
|
|
28289
|
+
const b64 = Buffer.from(endpointCmd).toString("base64");
|
|
28290
|
+
lines.push(`\x1B]52;c;${b64}\x07`);
|
|
28291
|
+
lines.push(` ${c2.dim("(copied to clipboard)")}`);
|
|
28292
|
+
}
|
|
27177
28293
|
const infCaps = this._capabilities.filter((cap) => cap.startsWith("inference:"));
|
|
27178
28294
|
if (infCaps.length > 0) {
|
|
27179
28295
|
lines.push("");
|
|
@@ -27255,8 +28371,8 @@ var init_types = __esm({
|
|
|
27255
28371
|
|
|
27256
28372
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
27257
28373
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
27258
|
-
import { readFileSync as
|
|
27259
|
-
import { join as join36, dirname as
|
|
28374
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync10, existsSync as existsSync28, mkdirSync as mkdirSync10 } from "node:fs";
|
|
28375
|
+
import { join as join36, dirname as dirname14 } from "node:path";
|
|
27260
28376
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
27261
28377
|
var init_secret_vault = __esm({
|
|
27262
28378
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -27467,19 +28583,19 @@ var init_secret_vault = __esm({
|
|
|
27467
28583
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
27468
28584
|
const tag = cipher.getAuthTag();
|
|
27469
28585
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
27470
|
-
const dir =
|
|
27471
|
-
if (!
|
|
27472
|
-
|
|
27473
|
-
|
|
28586
|
+
const dir = dirname14(this.storePath);
|
|
28587
|
+
if (!existsSync28(dir))
|
|
28588
|
+
mkdirSync10(dir, { recursive: true });
|
|
28589
|
+
writeFileSync10(this.storePath, blob, { mode: 384 });
|
|
27474
28590
|
}
|
|
27475
28591
|
/**
|
|
27476
28592
|
* Load vault from disk, decrypting with the given passphrase.
|
|
27477
28593
|
* Returns the number of secrets loaded.
|
|
27478
28594
|
*/
|
|
27479
28595
|
load(passphrase) {
|
|
27480
|
-
if (!this.storePath || !
|
|
28596
|
+
if (!this.storePath || !existsSync28(this.storePath))
|
|
27481
28597
|
return 0;
|
|
27482
|
-
const blob =
|
|
28598
|
+
const blob = readFileSync20(this.storePath);
|
|
27483
28599
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
27484
28600
|
throw new Error("Vault file is corrupted (too small)");
|
|
27485
28601
|
}
|
|
@@ -28516,7 +29632,54 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
28516
29632
|
parameterSize: m.owned_by ?? void 0
|
|
28517
29633
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
28518
29634
|
}
|
|
29635
|
+
async function fetchPeerModels(peerId) {
|
|
29636
|
+
try {
|
|
29637
|
+
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
29638
|
+
const cwd4 = process.cwd();
|
|
29639
|
+
const nexusTool = new NexusTool2(cwd4);
|
|
29640
|
+
const result = await nexusTool.execute({
|
|
29641
|
+
action: "find_agent",
|
|
29642
|
+
peer_id: peerId
|
|
29643
|
+
});
|
|
29644
|
+
if (result.success && result.output) {
|
|
29645
|
+
const models = [];
|
|
29646
|
+
const capMatches = result.output.matchAll(/inference:([^\s,\]]+)/g);
|
|
29647
|
+
for (const m of capMatches) {
|
|
29648
|
+
const capName = m[1];
|
|
29649
|
+
const modelName = capName.replace(/_(\d+[bBmMkK])$/, ":$1").replace(/_latest$/, ":latest");
|
|
29650
|
+
models.push({
|
|
29651
|
+
name: modelName,
|
|
29652
|
+
size: "",
|
|
29653
|
+
modified: "",
|
|
29654
|
+
sizeBytes: 0,
|
|
29655
|
+
parameterSize: "remote"
|
|
29656
|
+
});
|
|
29657
|
+
}
|
|
29658
|
+
if (models.length > 0)
|
|
29659
|
+
return models;
|
|
29660
|
+
}
|
|
29661
|
+
const { existsSync: existsSync42, readFileSync: readFileSync31 } = await import("node:fs");
|
|
29662
|
+
const { join: join55 } = await import("node:path");
|
|
29663
|
+
const pricingPath = join55(nexusTool.getNexusDir(), "pricing.json");
|
|
29664
|
+
if (existsSync42(pricingPath)) {
|
|
29665
|
+
const pricing = JSON.parse(readFileSync31(pricingPath, "utf8"));
|
|
29666
|
+
return (pricing.models || []).map((m) => ({
|
|
29667
|
+
name: m.model || "unknown",
|
|
29668
|
+
size: m.parameterSize || "",
|
|
29669
|
+
modified: "",
|
|
29670
|
+
sizeBytes: 0,
|
|
29671
|
+
parameterSize: m.parameterSize || "remote"
|
|
29672
|
+
}));
|
|
29673
|
+
}
|
|
29674
|
+
return [];
|
|
29675
|
+
} catch {
|
|
29676
|
+
return [];
|
|
29677
|
+
}
|
|
29678
|
+
}
|
|
28519
29679
|
async function fetchModels(baseUrl, apiKey) {
|
|
29680
|
+
if (baseUrl.startsWith("peer://")) {
|
|
29681
|
+
return fetchPeerModels(baseUrl.slice(7));
|
|
29682
|
+
}
|
|
28520
29683
|
const provider = detectProvider(baseUrl);
|
|
28521
29684
|
if (provider.id === "ollama") {
|
|
28522
29685
|
try {
|
|
@@ -28593,6 +29756,8 @@ async function queryOpenAIContextSize(baseUrl, modelName, apiKey) {
|
|
|
28593
29756
|
}
|
|
28594
29757
|
}
|
|
28595
29758
|
async function queryContextSize(baseUrl, modelName, apiKey) {
|
|
29759
|
+
if (baseUrl.startsWith("peer://"))
|
|
29760
|
+
return 32768;
|
|
28596
29761
|
const ollamaSize = await queryModelContextSize(baseUrl, modelName);
|
|
28597
29762
|
if (ollamaSize)
|
|
28598
29763
|
return ollamaSize;
|
|
@@ -28600,6 +29765,16 @@ async function queryContextSize(baseUrl, modelName, apiKey) {
|
|
|
28600
29765
|
}
|
|
28601
29766
|
async function queryModelCapabilities(baseUrl, modelName) {
|
|
28602
29767
|
const caps = { vision: false, toolUse: false, thinking: false };
|
|
29768
|
+
if (baseUrl.startsWith("peer://")) {
|
|
29769
|
+
const nameLower = modelName.toLowerCase();
|
|
29770
|
+
if (/qwen3|qwen2\.5|llama3\.[13]|mistral|mixtral|command-r|gemma3|devstral|deepseek/.test(nameLower)) {
|
|
29771
|
+
caps.toolUse = true;
|
|
29772
|
+
}
|
|
29773
|
+
if (/qwen3|deepseek-r1/.test(nameLower)) {
|
|
29774
|
+
caps.thinking = true;
|
|
29775
|
+
}
|
|
29776
|
+
return caps;
|
|
29777
|
+
}
|
|
28603
29778
|
try {
|
|
28604
29779
|
const normalized = normalizeBaseUrl(baseUrl);
|
|
28605
29780
|
const res = await fetch(`${normalized}/api/show`, {
|
|
@@ -28699,17 +29874,17 @@ var init_render2 = __esm({
|
|
|
28699
29874
|
});
|
|
28700
29875
|
|
|
28701
29876
|
// packages/prompts/dist/promptLoader.js
|
|
28702
|
-
import { readFileSync as
|
|
28703
|
-
import { join as join37, dirname as
|
|
29877
|
+
import { readFileSync as readFileSync21, existsSync as existsSync29 } from "node:fs";
|
|
29878
|
+
import { join as join37, dirname as dirname15 } from "node:path";
|
|
28704
29879
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
28705
29880
|
function loadPrompt2(promptPath, vars) {
|
|
28706
29881
|
let content = cache2.get(promptPath);
|
|
28707
29882
|
if (content === void 0) {
|
|
28708
29883
|
const fullPath = join37(PROMPTS_DIR2, promptPath);
|
|
28709
|
-
if (!
|
|
29884
|
+
if (!existsSync29(fullPath)) {
|
|
28710
29885
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
28711
29886
|
}
|
|
28712
|
-
content =
|
|
29887
|
+
content = readFileSync21(fullPath, "utf-8");
|
|
28713
29888
|
cache2.set(promptPath, content);
|
|
28714
29889
|
}
|
|
28715
29890
|
if (!vars)
|
|
@@ -28721,10 +29896,10 @@ var init_promptLoader2 = __esm({
|
|
|
28721
29896
|
"packages/prompts/dist/promptLoader.js"() {
|
|
28722
29897
|
"use strict";
|
|
28723
29898
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
28724
|
-
__dirname5 =
|
|
29899
|
+
__dirname5 = dirname15(__filename2);
|
|
28725
29900
|
devPath = join37(__dirname5, "..", "templates");
|
|
28726
29901
|
publishedPath = join37(__dirname5, "..", "prompts", "templates");
|
|
28727
|
-
PROMPTS_DIR2 =
|
|
29902
|
+
PROMPTS_DIR2 = existsSync29(devPath) ? devPath : publishedPath;
|
|
28728
29903
|
cache2 = /* @__PURE__ */ new Map();
|
|
28729
29904
|
}
|
|
28730
29905
|
});
|
|
@@ -28835,7 +30010,7 @@ var init_task_templates = __esm({
|
|
|
28835
30010
|
});
|
|
28836
30011
|
|
|
28837
30012
|
// packages/prompts/dist/index.js
|
|
28838
|
-
import { join as join38, dirname as
|
|
30013
|
+
import { join as join38, dirname as dirname16 } from "node:path";
|
|
28839
30014
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
28840
30015
|
var _dir, _packageRoot;
|
|
28841
30016
|
var init_dist6 = __esm({
|
|
@@ -28845,27 +30020,27 @@ var init_dist6 = __esm({
|
|
|
28845
30020
|
init_render2();
|
|
28846
30021
|
init_task_templates();
|
|
28847
30022
|
init_render2();
|
|
28848
|
-
_dir =
|
|
30023
|
+
_dir = dirname16(fileURLToPath10(import.meta.url));
|
|
28849
30024
|
_packageRoot = join38(_dir, "..");
|
|
28850
30025
|
}
|
|
28851
30026
|
});
|
|
28852
30027
|
|
|
28853
30028
|
// packages/cli/dist/tui/oa-directory.js
|
|
28854
|
-
import { existsSync as
|
|
30029
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync11, readdirSync as readdirSync8, statSync as statSync9, unlinkSync as unlinkSync4 } from "node:fs";
|
|
28855
30030
|
import { join as join39, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
28856
30031
|
import { homedir as homedir9 } from "node:os";
|
|
28857
30032
|
function initOaDirectory(repoRoot) {
|
|
28858
30033
|
const oaPath = join39(repoRoot, OA_DIR);
|
|
28859
30034
|
for (const sub of SUBDIRS) {
|
|
28860
|
-
|
|
30035
|
+
mkdirSync11(join39(oaPath, sub), { recursive: true });
|
|
28861
30036
|
}
|
|
28862
30037
|
try {
|
|
28863
30038
|
const gitignorePath = join39(repoRoot, ".gitignore");
|
|
28864
30039
|
const settingsPattern = ".oa/settings.json";
|
|
28865
|
-
if (
|
|
28866
|
-
const content =
|
|
30040
|
+
if (existsSync30(gitignorePath)) {
|
|
30041
|
+
const content = readFileSync22(gitignorePath, "utf-8");
|
|
28867
30042
|
if (!content.includes(settingsPattern)) {
|
|
28868
|
-
|
|
30043
|
+
writeFileSync11(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
28869
30044
|
}
|
|
28870
30045
|
}
|
|
28871
30046
|
} catch {
|
|
@@ -28873,13 +30048,13 @@ function initOaDirectory(repoRoot) {
|
|
|
28873
30048
|
return oaPath;
|
|
28874
30049
|
}
|
|
28875
30050
|
function hasOaDirectory(repoRoot) {
|
|
28876
|
-
return
|
|
30051
|
+
return existsSync30(join39(repoRoot, OA_DIR, "index"));
|
|
28877
30052
|
}
|
|
28878
30053
|
function loadProjectSettings(repoRoot) {
|
|
28879
30054
|
const settingsPath = join39(repoRoot, OA_DIR, "settings.json");
|
|
28880
30055
|
try {
|
|
28881
|
-
if (
|
|
28882
|
-
return JSON.parse(
|
|
30056
|
+
if (existsSync30(settingsPath)) {
|
|
30057
|
+
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
28883
30058
|
}
|
|
28884
30059
|
} catch {
|
|
28885
30060
|
}
|
|
@@ -28887,16 +30062,16 @@ function loadProjectSettings(repoRoot) {
|
|
|
28887
30062
|
}
|
|
28888
30063
|
function saveProjectSettings(repoRoot, settings) {
|
|
28889
30064
|
const oaPath = join39(repoRoot, OA_DIR);
|
|
28890
|
-
|
|
30065
|
+
mkdirSync11(oaPath, { recursive: true });
|
|
28891
30066
|
const existing = loadProjectSettings(repoRoot);
|
|
28892
30067
|
const merged = { ...existing, ...settings };
|
|
28893
|
-
|
|
30068
|
+
writeFileSync11(join39(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
28894
30069
|
}
|
|
28895
30070
|
function loadGlobalSettings() {
|
|
28896
30071
|
const settingsPath = join39(homedir9(), ".open-agents", "settings.json");
|
|
28897
30072
|
try {
|
|
28898
|
-
if (
|
|
28899
|
-
return JSON.parse(
|
|
30073
|
+
if (existsSync30(settingsPath)) {
|
|
30074
|
+
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
28900
30075
|
}
|
|
28901
30076
|
} catch {
|
|
28902
30077
|
}
|
|
@@ -28904,10 +30079,10 @@ function loadGlobalSettings() {
|
|
|
28904
30079
|
}
|
|
28905
30080
|
function saveGlobalSettings(settings) {
|
|
28906
30081
|
const dir = join39(homedir9(), ".open-agents");
|
|
28907
|
-
|
|
30082
|
+
mkdirSync11(dir, { recursive: true });
|
|
28908
30083
|
const existing = loadGlobalSettings();
|
|
28909
30084
|
const merged = { ...existing, ...settings };
|
|
28910
|
-
|
|
30085
|
+
writeFileSync11(join39(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
28911
30086
|
}
|
|
28912
30087
|
function resolveSettings(repoRoot) {
|
|
28913
30088
|
const global = loadGlobalSettings();
|
|
@@ -28924,10 +30099,10 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
28924
30099
|
for (const name of CONTEXT_FILES) {
|
|
28925
30100
|
const filePath = join39(dir, name);
|
|
28926
30101
|
const normalizedName = name.toLowerCase();
|
|
28927
|
-
if (
|
|
30102
|
+
if (existsSync30(filePath) && !seen.has(filePath)) {
|
|
28928
30103
|
seen.add(filePath);
|
|
28929
30104
|
try {
|
|
28930
|
-
let content =
|
|
30105
|
+
let content = readFileSync22(filePath, "utf-8");
|
|
28931
30106
|
if (content.length > maxContentLen) {
|
|
28932
30107
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
28933
30108
|
}
|
|
@@ -28942,10 +30117,10 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
28942
30117
|
}
|
|
28943
30118
|
}
|
|
28944
30119
|
const projectMap = join39(dir, OA_DIR, "context", "project-map.md");
|
|
28945
|
-
if (
|
|
30120
|
+
if (existsSync30(projectMap) && !seen.has(projectMap)) {
|
|
28946
30121
|
seen.add(projectMap);
|
|
28947
30122
|
try {
|
|
28948
|
-
let content =
|
|
30123
|
+
let content = readFileSync22(projectMap, "utf-8");
|
|
28949
30124
|
if (content.length > maxContentLen) {
|
|
28950
30125
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
28951
30126
|
}
|
|
@@ -28977,7 +30152,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
28977
30152
|
function readIndexMeta(repoRoot) {
|
|
28978
30153
|
const metaPath = join39(repoRoot, OA_DIR, "index", "meta.json");
|
|
28979
30154
|
try {
|
|
28980
|
-
return JSON.parse(
|
|
30155
|
+
return JSON.parse(readFileSync22(metaPath, "utf-8"));
|
|
28981
30156
|
} catch {
|
|
28982
30157
|
return null;
|
|
28983
30158
|
}
|
|
@@ -29029,18 +30204,18 @@ ${tree}\`\`\`
|
|
|
29029
30204
|
}
|
|
29030
30205
|
const content = sections.join("\n");
|
|
29031
30206
|
const contextDir = join39(repoRoot, OA_DIR, "context");
|
|
29032
|
-
|
|
29033
|
-
|
|
30207
|
+
mkdirSync11(contextDir, { recursive: true });
|
|
30208
|
+
writeFileSync11(join39(contextDir, "project-map.md"), content, "utf-8");
|
|
29034
30209
|
return content;
|
|
29035
30210
|
}
|
|
29036
30211
|
function saveSession(repoRoot, session) {
|
|
29037
30212
|
const historyDir = join39(repoRoot, OA_DIR, "history");
|
|
29038
|
-
|
|
29039
|
-
|
|
30213
|
+
mkdirSync11(historyDir, { recursive: true });
|
|
30214
|
+
writeFileSync11(join39(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
29040
30215
|
}
|
|
29041
30216
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
29042
30217
|
const historyDir = join39(repoRoot, OA_DIR, "history");
|
|
29043
|
-
if (!
|
|
30218
|
+
if (!existsSync30(historyDir))
|
|
29044
30219
|
return [];
|
|
29045
30220
|
try {
|
|
29046
30221
|
const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
@@ -29049,7 +30224,7 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
29049
30224
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
29050
30225
|
return files.map((f) => {
|
|
29051
30226
|
try {
|
|
29052
|
-
return JSON.parse(
|
|
30227
|
+
return JSON.parse(readFileSync22(join39(historyDir, f.file), "utf-8"));
|
|
29053
30228
|
} catch {
|
|
29054
30229
|
return null;
|
|
29055
30230
|
}
|
|
@@ -29060,15 +30235,15 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
29060
30235
|
}
|
|
29061
30236
|
function savePendingTask(repoRoot, task) {
|
|
29062
30237
|
const historyDir = join39(repoRoot, OA_DIR, "history");
|
|
29063
|
-
|
|
29064
|
-
|
|
30238
|
+
mkdirSync11(historyDir, { recursive: true });
|
|
30239
|
+
writeFileSync11(join39(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
29065
30240
|
}
|
|
29066
30241
|
function loadPendingTask(repoRoot) {
|
|
29067
30242
|
const filePath = join39(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
29068
30243
|
try {
|
|
29069
|
-
if (!
|
|
30244
|
+
if (!existsSync30(filePath))
|
|
29070
30245
|
return null;
|
|
29071
|
-
const data = JSON.parse(
|
|
30246
|
+
const data = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
29072
30247
|
try {
|
|
29073
30248
|
unlinkSync4(filePath);
|
|
29074
30249
|
} catch {
|
|
@@ -29080,12 +30255,12 @@ function loadPendingTask(repoRoot) {
|
|
|
29080
30255
|
}
|
|
29081
30256
|
function saveSessionContext(repoRoot, entry) {
|
|
29082
30257
|
const contextDir = join39(repoRoot, OA_DIR, "context");
|
|
29083
|
-
|
|
30258
|
+
mkdirSync11(contextDir, { recursive: true });
|
|
29084
30259
|
const filePath = join39(contextDir, CONTEXT_SAVE_FILE);
|
|
29085
30260
|
let ctx;
|
|
29086
30261
|
try {
|
|
29087
|
-
if (
|
|
29088
|
-
ctx = JSON.parse(
|
|
30262
|
+
if (existsSync30(filePath)) {
|
|
30263
|
+
ctx = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
29089
30264
|
} else {
|
|
29090
30265
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
29091
30266
|
}
|
|
@@ -29097,14 +30272,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
29097
30272
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
29098
30273
|
}
|
|
29099
30274
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
29100
|
-
|
|
30275
|
+
writeFileSync11(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
29101
30276
|
}
|
|
29102
30277
|
function loadSessionContext(repoRoot) {
|
|
29103
30278
|
const filePath = join39(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
29104
30279
|
try {
|
|
29105
|
-
if (!
|
|
30280
|
+
if (!existsSync30(filePath))
|
|
29106
30281
|
return null;
|
|
29107
|
-
return JSON.parse(
|
|
30282
|
+
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
29108
30283
|
} catch {
|
|
29109
30284
|
return null;
|
|
29110
30285
|
}
|
|
@@ -29152,11 +30327,11 @@ function detectManifests(repoRoot) {
|
|
|
29152
30327
|
];
|
|
29153
30328
|
for (const check of checks) {
|
|
29154
30329
|
const filePath = join39(repoRoot, check.file);
|
|
29155
|
-
if (
|
|
30330
|
+
if (existsSync30(filePath)) {
|
|
29156
30331
|
let name;
|
|
29157
30332
|
if (check.nameField) {
|
|
29158
30333
|
try {
|
|
29159
|
-
const data = JSON.parse(
|
|
30334
|
+
const data = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
29160
30335
|
name = data[check.nameField];
|
|
29161
30336
|
} catch {
|
|
29162
30337
|
}
|
|
@@ -29185,7 +30360,7 @@ function findKeyFiles(repoRoot) {
|
|
|
29185
30360
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
29186
30361
|
];
|
|
29187
30362
|
for (const check of checks) {
|
|
29188
|
-
if (
|
|
30363
|
+
if (existsSync30(join39(repoRoot, check.pattern))) {
|
|
29189
30364
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
29190
30365
|
}
|
|
29191
30366
|
}
|
|
@@ -29228,8 +30403,8 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
29228
30403
|
}
|
|
29229
30404
|
function loadUsageFile(filePath) {
|
|
29230
30405
|
try {
|
|
29231
|
-
if (
|
|
29232
|
-
return JSON.parse(
|
|
30406
|
+
if (existsSync30(filePath)) {
|
|
30407
|
+
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
29233
30408
|
}
|
|
29234
30409
|
} catch {
|
|
29235
30410
|
}
|
|
@@ -29237,8 +30412,8 @@ function loadUsageFile(filePath) {
|
|
|
29237
30412
|
}
|
|
29238
30413
|
function saveUsageFile(filePath, data) {
|
|
29239
30414
|
const dir = join39(filePath, "..");
|
|
29240
|
-
|
|
29241
|
-
|
|
30415
|
+
mkdirSync11(dir, { recursive: true });
|
|
30416
|
+
writeFileSync11(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
29242
30417
|
}
|
|
29243
30418
|
function recordUsage(kind, value, opts) {
|
|
29244
30419
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -29341,9 +30516,9 @@ var init_oa_directory = __esm({
|
|
|
29341
30516
|
|
|
29342
30517
|
// packages/cli/dist/tui/setup.js
|
|
29343
30518
|
import * as readline from "node:readline";
|
|
29344
|
-
import { execSync as execSync25, spawn as
|
|
30519
|
+
import { execSync as execSync25, spawn as spawn17, exec as exec2 } from "node:child_process";
|
|
29345
30520
|
import { promisify as promisify5 } from "node:util";
|
|
29346
|
-
import { existsSync as
|
|
30521
|
+
import { existsSync as existsSync31, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12 } from "node:fs";
|
|
29347
30522
|
import { join as join40 } from "node:path";
|
|
29348
30523
|
import { homedir as homedir10, platform } from "node:os";
|
|
29349
30524
|
function detectSystemSpecs() {
|
|
@@ -29621,7 +30796,7 @@ async function installOllamaMac(_rl) {
|
|
|
29621
30796
|
execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
29622
30797
|
if (!hasCmd("brew")) {
|
|
29623
30798
|
try {
|
|
29624
|
-
const brewPrefix =
|
|
30799
|
+
const brewPrefix = existsSync31("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
29625
30800
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
29626
30801
|
} catch {
|
|
29627
30802
|
}
|
|
@@ -29729,7 +30904,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
29729
30904
|
process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
|
|
29730
30905
|
`);
|
|
29731
30906
|
try {
|
|
29732
|
-
const child =
|
|
30907
|
+
const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
29733
30908
|
child.unref();
|
|
29734
30909
|
} catch {
|
|
29735
30910
|
process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
|
|
@@ -30197,7 +31372,7 @@ async function doSetup(config, rl) {
|
|
|
30197
31372
|
${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
|
|
30198
31373
|
`);
|
|
30199
31374
|
try {
|
|
30200
|
-
const child =
|
|
31375
|
+
const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
30201
31376
|
child.unref();
|
|
30202
31377
|
await new Promise((resolve31) => setTimeout(resolve31, 3e3));
|
|
30203
31378
|
try {
|
|
@@ -30225,7 +31400,7 @@ async function doSetup(config, rl) {
|
|
|
30225
31400
|
${c2.cyan("\u25CF")} Starting ollama serve...
|
|
30226
31401
|
`);
|
|
30227
31402
|
try {
|
|
30228
|
-
const child =
|
|
31403
|
+
const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
30229
31404
|
child.unref();
|
|
30230
31405
|
await new Promise((resolve31) => setTimeout(resolve31, 3e3));
|
|
30231
31406
|
try {
|
|
@@ -30376,9 +31551,9 @@ async function doSetup(config, rl) {
|
|
|
30376
31551
|
`PARAMETER stop "<|endoftext|>"`
|
|
30377
31552
|
].join("\n");
|
|
30378
31553
|
const modelDir2 = join40(homedir10(), ".open-agents", "models");
|
|
30379
|
-
|
|
31554
|
+
mkdirSync12(modelDir2, { recursive: true });
|
|
30380
31555
|
const modelfilePath = join40(modelDir2, `Modelfile.${customName}`);
|
|
30381
|
-
|
|
31556
|
+
writeFileSync12(modelfilePath, modelfileContent + "\n", "utf8");
|
|
30382
31557
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
30383
31558
|
execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
30384
31559
|
stdio: "pipe",
|
|
@@ -30423,7 +31598,7 @@ async function isModelAvailable(config) {
|
|
|
30423
31598
|
}
|
|
30424
31599
|
function isFirstRun() {
|
|
30425
31600
|
try {
|
|
30426
|
-
return !
|
|
31601
|
+
return !existsSync31(join40(homedir10(), ".open-agents", "config.json"));
|
|
30427
31602
|
} catch {
|
|
30428
31603
|
return true;
|
|
30429
31604
|
}
|
|
@@ -30473,7 +31648,7 @@ function hasVenvModule() {
|
|
|
30473
31648
|
function ensureVenv(log) {
|
|
30474
31649
|
const venvDir = getVenvDir();
|
|
30475
31650
|
const venvPip = join40(venvDir, "bin", "pip");
|
|
30476
|
-
if (
|
|
31651
|
+
if (existsSync31(venvPip))
|
|
30477
31652
|
return venvDir;
|
|
30478
31653
|
log("Creating Python venv for vision deps...");
|
|
30479
31654
|
if (!hasCmd("python3")) {
|
|
@@ -30485,7 +31660,7 @@ function ensureVenv(log) {
|
|
|
30485
31660
|
return null;
|
|
30486
31661
|
}
|
|
30487
31662
|
try {
|
|
30488
|
-
|
|
31663
|
+
mkdirSync12(join40(homedir10(), ".open-agents"), { recursive: true });
|
|
30489
31664
|
execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
30490
31665
|
execSync25(`"${join40(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
30491
31666
|
stdio: "pipe",
|
|
@@ -30681,12 +31856,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
30681
31856
|
const venvBin = join40(venvDir, "bin");
|
|
30682
31857
|
const venvMoondream = join40(venvBin, "moondream-station");
|
|
30683
31858
|
const venv = ensureVenv(log);
|
|
30684
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
31859
|
+
if (venv && !hasCmd("moondream-station") && !existsSync31(venvMoondream)) {
|
|
30685
31860
|
const venvPip = join40(venvBin, "pip");
|
|
30686
31861
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
30687
31862
|
try {
|
|
30688
31863
|
execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
30689
|
-
if (
|
|
31864
|
+
if (existsSync31(venvMoondream)) {
|
|
30690
31865
|
log("moondream-station installed successfully.");
|
|
30691
31866
|
} else {
|
|
30692
31867
|
try {
|
|
@@ -30818,9 +31993,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB) {
|
|
|
30818
31993
|
`PARAMETER stop "<|endoftext|>"`
|
|
30819
31994
|
].join("\n");
|
|
30820
31995
|
const modelDir2 = join40(homedir10(), ".open-agents", "models");
|
|
30821
|
-
|
|
31996
|
+
mkdirSync12(modelDir2, { recursive: true });
|
|
30822
31997
|
const modelfilePath = join40(modelDir2, `Modelfile.${customName}`);
|
|
30823
|
-
|
|
31998
|
+
writeFileSync12(modelfilePath, modelfileContent + "\n", "utf8");
|
|
30824
31999
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
30825
32000
|
timeout: 12e4
|
|
30826
32001
|
});
|
|
@@ -31838,6 +33013,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
31838
33013
|
renderInfo(" /expose status Show usage stats");
|
|
31839
33014
|
renderInfo(" --key <key> Use specific auth key (tunnel mode)");
|
|
31840
33015
|
renderInfo(" --key Auto-generate auth key (tunnel mode)");
|
|
33016
|
+
renderInfo(" --full Allow full Ollama API access (pull/delete/etc)");
|
|
31841
33017
|
}
|
|
31842
33018
|
return "handled";
|
|
31843
33019
|
}
|
|
@@ -31857,8 +33033,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
31857
33033
|
} else if (exposeParts.includes("--libp2p")) {
|
|
31858
33034
|
exposeTransport = "libp2p";
|
|
31859
33035
|
}
|
|
33036
|
+
const exposeFullAccess = exposeParts.includes("--full");
|
|
31860
33037
|
try {
|
|
31861
|
-
const tunnelUrl = await ctx.exposeStart(kindOrUrl, exposeAuthKey, exposeTransport);
|
|
33038
|
+
const tunnelUrl = await ctx.exposeStart(kindOrUrl, exposeAuthKey, exposeTransport, exposeFullAccess);
|
|
31862
33039
|
if (tunnelUrl) {
|
|
31863
33040
|
const info = ctx.getExposeInfo?.();
|
|
31864
33041
|
if (info) {
|
|
@@ -32618,6 +33795,10 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
32618
33795
|
if (authIdx !== -1 && parts[authIdx + 1]) {
|
|
32619
33796
|
apiKey = parts[authIdx + 1];
|
|
32620
33797
|
}
|
|
33798
|
+
if (url.startsWith("12D3KooW") && url.length > 40 && !url.includes("://")) {
|
|
33799
|
+
await handlePeerEndpoint(url, apiKey, ctx, local);
|
|
33800
|
+
return;
|
|
33801
|
+
}
|
|
32621
33802
|
try {
|
|
32622
33803
|
new URL(url);
|
|
32623
33804
|
} catch {
|
|
@@ -32741,6 +33922,110 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
32741
33922
|
renderWarning(`Could not verify model availability on ${provider.label}. If inference fails, use /model to switch.`);
|
|
32742
33923
|
}
|
|
32743
33924
|
}
|
|
33925
|
+
async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
33926
|
+
process.stdout.write(`
|
|
33927
|
+
${c2.dim("Detected:")} ${c2.bold("libp2p peer")}
|
|
33928
|
+
`);
|
|
33929
|
+
process.stdout.write(` ${c2.cyan("Peer ID".padEnd(12))} ${peerId}
|
|
33930
|
+
`);
|
|
33931
|
+
if (authKey) {
|
|
33932
|
+
process.stdout.write(` ${c2.cyan("Auth Key".padEnd(12))} ${authKey.slice(0, 8)}...
|
|
33933
|
+
`);
|
|
33934
|
+
}
|
|
33935
|
+
process.stdout.write(` ${c2.dim("Connecting to nexus network...")} `);
|
|
33936
|
+
try {
|
|
33937
|
+
if (!ctx.nexusConnect) {
|
|
33938
|
+
throw new Error("Nexus not available \u2014 run /nexus connect first");
|
|
33939
|
+
}
|
|
33940
|
+
const connectMsg = await ctx.nexusConnect();
|
|
33941
|
+
process.stdout.write(`${c2.green("\u2714")} Connected
|
|
33942
|
+
`);
|
|
33943
|
+
} catch (err) {
|
|
33944
|
+
process.stdout.write(`${c2.yellow("\u26A0")} ${err instanceof Error ? err.message : String(err)}
|
|
33945
|
+
`);
|
|
33946
|
+
renderInfo("Setting peer endpoint anyway \u2014 nexus may connect later.");
|
|
33947
|
+
}
|
|
33948
|
+
const peerUrl = `peer://${peerId}`;
|
|
33949
|
+
ctx.setEndpoint(peerUrl, "nexus", authKey);
|
|
33950
|
+
const endpointSettings = { backendUrl: peerUrl, backendType: "nexus", ...authKey ? { apiKey: authKey } : {} };
|
|
33951
|
+
if (local) {
|
|
33952
|
+
ctx.saveLocalSettings(endpointSettings);
|
|
33953
|
+
} else {
|
|
33954
|
+
setConfigValue("backendUrl", peerUrl);
|
|
33955
|
+
setConfigValue("backendType", "nexus");
|
|
33956
|
+
if (authKey)
|
|
33957
|
+
setConfigValue("apiKey", authKey);
|
|
33958
|
+
ctx.saveSettings(endpointSettings);
|
|
33959
|
+
}
|
|
33960
|
+
recordUsage("endpoint", peerUrl, {
|
|
33961
|
+
repoRoot: local ? ctx.repoRoot : void 0,
|
|
33962
|
+
local,
|
|
33963
|
+
meta: {
|
|
33964
|
+
provider: "libp2p-peer",
|
|
33965
|
+
backendType: "nexus",
|
|
33966
|
+
peerId,
|
|
33967
|
+
...authKey ? { authHint: authKey.slice(0, 4) + "..." } : {}
|
|
33968
|
+
}
|
|
33969
|
+
});
|
|
33970
|
+
process.stdout.write(`
|
|
33971
|
+
${c2.green("\u2714")} Endpoint set to libp2p peer${local ? " (project-local)" : ""}:
|
|
33972
|
+
`);
|
|
33973
|
+
process.stdout.write(` ${c2.cyan("Transport".padEnd(12))} libp2p (DHT + mDNS + NATS relay)
|
|
33974
|
+
`);
|
|
33975
|
+
process.stdout.write(` ${c2.cyan("Peer ID".padEnd(12))} ${peerId}
|
|
33976
|
+
`);
|
|
33977
|
+
if (authKey) {
|
|
33978
|
+
process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} ${authKey.slice(0, 8)}...
|
|
33979
|
+
`);
|
|
33980
|
+
}
|
|
33981
|
+
process.stdout.write(`
|
|
33982
|
+
${c2.dim("Inference requests will be routed via nexus P2P network.")}
|
|
33983
|
+
|
|
33984
|
+
`);
|
|
33985
|
+
try {
|
|
33986
|
+
const models = await fetchModels(peerUrl, authKey);
|
|
33987
|
+
if (models.length > 0) {
|
|
33988
|
+
process.stdout.write(` ${c2.green("\u2714")} Discovered ${models.length} model(s) on peer:
|
|
33989
|
+
`);
|
|
33990
|
+
for (const m of models.slice(0, 10)) {
|
|
33991
|
+
process.stdout.write(` ${c2.dim("\u2022")} ${m.name}${m.parameterSize ? c2.dim(` (${m.parameterSize})`) : ""}
|
|
33992
|
+
`);
|
|
33993
|
+
}
|
|
33994
|
+
if (models.length > 10) {
|
|
33995
|
+
process.stdout.write(` ${c2.dim(`... and ${models.length - 10} more`)}
|
|
33996
|
+
`);
|
|
33997
|
+
}
|
|
33998
|
+
process.stdout.write("\n");
|
|
33999
|
+
const currentModel = ctx.config.model;
|
|
34000
|
+
const found = findModel(models, currentModel);
|
|
34001
|
+
if (!found && models.length > 0) {
|
|
34002
|
+
const autoModel = models[0].name;
|
|
34003
|
+
ctx.setModel(autoModel);
|
|
34004
|
+
if (local) {
|
|
34005
|
+
ctx.saveLocalSettings({ model: autoModel });
|
|
34006
|
+
} else {
|
|
34007
|
+
ctx.saveSettings({ model: autoModel });
|
|
34008
|
+
}
|
|
34009
|
+
renderWarning(`Model "${currentModel}" not found on peer.`);
|
|
34010
|
+
renderModelSwitch(currentModel, autoModel);
|
|
34011
|
+
} else if (found) {
|
|
34012
|
+
process.stdout.write(` ${c2.green("\u2714")} Model "${currentModel}" available on peer.
|
|
34013
|
+
|
|
34014
|
+
`);
|
|
34015
|
+
}
|
|
34016
|
+
} else {
|
|
34017
|
+
renderWarning("No models discovered on peer. The peer may not have exposed yet, or discovery needs time.");
|
|
34018
|
+
renderInfo("Use /models to try again, or just send a prompt \u2014 inference will attempt to reach the peer directly.");
|
|
34019
|
+
}
|
|
34020
|
+
} catch {
|
|
34021
|
+
renderWarning("Could not discover models on peer. Use /models to try again later.");
|
|
34022
|
+
}
|
|
34023
|
+
ctx.refreshModelCache?.();
|
|
34024
|
+
if (ctx.hasActiveTask?.()) {
|
|
34025
|
+
ctx.abortActiveTask?.();
|
|
34026
|
+
renderWarning("Active task aborted \u2014 endpoint changed. Send a new prompt to continue.");
|
|
34027
|
+
}
|
|
34028
|
+
}
|
|
32744
34029
|
async function handleUpdate(subcommand, ctx) {
|
|
32745
34030
|
const repoRoot = ctx.repoRoot;
|
|
32746
34031
|
if (subcommand === "auto") {
|
|
@@ -32761,17 +34046,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
32761
34046
|
try {
|
|
32762
34047
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
32763
34048
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
32764
|
-
const { dirname:
|
|
32765
|
-
const { existsSync:
|
|
34049
|
+
const { dirname: dirname20, join: join55 } = await import("node:path");
|
|
34050
|
+
const { existsSync: existsSync42 } = await import("node:fs");
|
|
32766
34051
|
const req = createRequire4(import.meta.url);
|
|
32767
|
-
const thisDir =
|
|
34052
|
+
const thisDir = dirname20(fileURLToPath14(import.meta.url));
|
|
32768
34053
|
const candidates = [
|
|
32769
34054
|
join55(thisDir, "..", "package.json"),
|
|
32770
34055
|
join55(thisDir, "..", "..", "package.json"),
|
|
32771
34056
|
join55(thisDir, "..", "..", "..", "package.json")
|
|
32772
34057
|
];
|
|
32773
34058
|
for (const pkgPath of candidates) {
|
|
32774
|
-
if (
|
|
34059
|
+
if (existsSync42(pkgPath)) {
|
|
32775
34060
|
const pkg = req(pkgPath);
|
|
32776
34061
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
32777
34062
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -33056,7 +34341,7 @@ var init_commands = __esm({
|
|
|
33056
34341
|
});
|
|
33057
34342
|
|
|
33058
34343
|
// packages/cli/dist/tui/project-context.js
|
|
33059
|
-
import { existsSync as
|
|
34344
|
+
import { existsSync as existsSync32, readFileSync as readFileSync23, readdirSync as readdirSync9 } from "node:fs";
|
|
33060
34345
|
import { join as join41, basename as basename10 } from "node:path";
|
|
33061
34346
|
import { execSync as execSync26 } from "node:child_process";
|
|
33062
34347
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
@@ -33093,9 +34378,9 @@ function loadProjectMap(repoRoot) {
|
|
|
33093
34378
|
initOaDirectory(repoRoot);
|
|
33094
34379
|
}
|
|
33095
34380
|
const mapPath = join41(repoRoot, OA_DIR, "context", "project-map.md");
|
|
33096
|
-
if (
|
|
34381
|
+
if (existsSync32(mapPath)) {
|
|
33097
34382
|
try {
|
|
33098
|
-
const content =
|
|
34383
|
+
const content = readFileSync23(mapPath, "utf-8");
|
|
33099
34384
|
return content;
|
|
33100
34385
|
} catch {
|
|
33101
34386
|
}
|
|
@@ -33141,7 +34426,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
33141
34426
|
if (oaEntries)
|
|
33142
34427
|
sections.push(oaEntries);
|
|
33143
34428
|
const legacyMemDir = join41(repoRoot, ".open-agents", "memory");
|
|
33144
|
-
if (legacyMemDir !== oaMemDir &&
|
|
34429
|
+
if (legacyMemDir !== oaMemDir && existsSync32(legacyMemDir)) {
|
|
33145
34430
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
33146
34431
|
if (legacyEntries)
|
|
33147
34432
|
sections.push(legacyEntries);
|
|
@@ -33153,14 +34438,14 @@ function loadMemoryContext(repoRoot) {
|
|
|
33153
34438
|
return sections.join("\n\n");
|
|
33154
34439
|
}
|
|
33155
34440
|
function loadMemoryDir(memDir, scope) {
|
|
33156
|
-
if (!
|
|
34441
|
+
if (!existsSync32(memDir))
|
|
33157
34442
|
return "";
|
|
33158
34443
|
const lines = [];
|
|
33159
34444
|
try {
|
|
33160
34445
|
const files = readdirSync9(memDir).filter((f) => f.endsWith(".json"));
|
|
33161
34446
|
for (const file of files.slice(0, 10)) {
|
|
33162
34447
|
try {
|
|
33163
|
-
const raw =
|
|
34448
|
+
const raw = readFileSync23(join41(memDir, file), "utf-8");
|
|
33164
34449
|
const entries = JSON.parse(raw);
|
|
33165
34450
|
const topic = basename10(file, ".json");
|
|
33166
34451
|
const keys = Object.keys(entries);
|
|
@@ -34183,22 +35468,22 @@ var init_carousel = __esm({
|
|
|
34183
35468
|
});
|
|
34184
35469
|
|
|
34185
35470
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
34186
|
-
import { existsSync as
|
|
35471
|
+
import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync13, mkdirSync as mkdirSync13, readdirSync as readdirSync10 } from "node:fs";
|
|
34187
35472
|
import { join as join42, basename as basename11 } from "node:path";
|
|
34188
35473
|
function loadToolProfile(repoRoot) {
|
|
34189
35474
|
const filePath = join42(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
34190
35475
|
try {
|
|
34191
|
-
if (!
|
|
35476
|
+
if (!existsSync33(filePath))
|
|
34192
35477
|
return null;
|
|
34193
|
-
return JSON.parse(
|
|
35478
|
+
return JSON.parse(readFileSync24(filePath, "utf-8"));
|
|
34194
35479
|
} catch {
|
|
34195
35480
|
return null;
|
|
34196
35481
|
}
|
|
34197
35482
|
}
|
|
34198
35483
|
function saveToolProfile(repoRoot, profile) {
|
|
34199
35484
|
const contextDir = join42(repoRoot, OA_DIR, "context");
|
|
34200
|
-
|
|
34201
|
-
|
|
35485
|
+
mkdirSync13(contextDir, { recursive: true });
|
|
35486
|
+
writeFileSync13(join42(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
34202
35487
|
}
|
|
34203
35488
|
function categorizeToolCall(toolName) {
|
|
34204
35489
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -34258,9 +35543,9 @@ function weightedColor(profile) {
|
|
|
34258
35543
|
function loadCachedDescriptors(repoRoot) {
|
|
34259
35544
|
const filePath = join42(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
34260
35545
|
try {
|
|
34261
|
-
if (!
|
|
35546
|
+
if (!existsSync33(filePath))
|
|
34262
35547
|
return null;
|
|
34263
|
-
const cached = JSON.parse(
|
|
35548
|
+
const cached = JSON.parse(readFileSync24(filePath, "utf-8"));
|
|
34264
35549
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
34265
35550
|
} catch {
|
|
34266
35551
|
return null;
|
|
@@ -34268,13 +35553,13 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
34268
35553
|
}
|
|
34269
35554
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
34270
35555
|
const contextDir = join42(repoRoot, OA_DIR, "context");
|
|
34271
|
-
|
|
35556
|
+
mkdirSync13(contextDir, { recursive: true });
|
|
34272
35557
|
const cached = {
|
|
34273
35558
|
phrases,
|
|
34274
35559
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34275
35560
|
sourceHash
|
|
34276
35561
|
};
|
|
34277
|
-
|
|
35562
|
+
writeFileSync13(join42(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
34278
35563
|
}
|
|
34279
35564
|
function generateDescriptors(repoRoot) {
|
|
34280
35565
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -34324,9 +35609,9 @@ function generateDescriptors(repoRoot) {
|
|
|
34324
35609
|
function extractFromPackageJson(repoRoot, tags) {
|
|
34325
35610
|
const pkgPath = join42(repoRoot, "package.json");
|
|
34326
35611
|
try {
|
|
34327
|
-
if (!
|
|
35612
|
+
if (!existsSync33(pkgPath))
|
|
34328
35613
|
return;
|
|
34329
|
-
const pkg = JSON.parse(
|
|
35614
|
+
const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
|
|
34330
35615
|
if (pkg.name && typeof pkg.name === "string") {
|
|
34331
35616
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
34332
35617
|
for (const p of parts)
|
|
@@ -34370,7 +35655,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
34370
35655
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
34371
35656
|
];
|
|
34372
35657
|
for (const check of manifestChecks) {
|
|
34373
|
-
if (
|
|
35658
|
+
if (existsSync33(join42(repoRoot, check.file))) {
|
|
34374
35659
|
tags.push(check.tag);
|
|
34375
35660
|
}
|
|
34376
35661
|
}
|
|
@@ -34394,14 +35679,14 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
34394
35679
|
function extractFromMemory(repoRoot, tags) {
|
|
34395
35680
|
const memoryDir = join42(repoRoot, OA_DIR, "memory");
|
|
34396
35681
|
try {
|
|
34397
|
-
if (!
|
|
35682
|
+
if (!existsSync33(memoryDir))
|
|
34398
35683
|
return;
|
|
34399
35684
|
const files = readdirSync10(memoryDir).filter((f) => f.endsWith(".json"));
|
|
34400
35685
|
for (const file of files) {
|
|
34401
35686
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
34402
35687
|
tags.push(topic);
|
|
34403
35688
|
try {
|
|
34404
|
-
const data = JSON.parse(
|
|
35689
|
+
const data = JSON.parse(readFileSync24(join42(memoryDir, file), "utf-8"));
|
|
34405
35690
|
if (data && typeof data === "object") {
|
|
34406
35691
|
const keys = Object.keys(data).slice(0, 3);
|
|
34407
35692
|
for (const key of keys) {
|
|
@@ -34536,7 +35821,7 @@ var init_carousel_descriptors = __esm({
|
|
|
34536
35821
|
});
|
|
34537
35822
|
|
|
34538
35823
|
// packages/cli/dist/tui/voice.js
|
|
34539
|
-
import { existsSync as
|
|
35824
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync14, writeFileSync as writeFileSync14, readFileSync as readFileSync25, unlinkSync as unlinkSync5 } from "node:fs";
|
|
34540
35825
|
import { join as join43 } from "node:path";
|
|
34541
35826
|
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
34542
35827
|
import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
|
|
@@ -35546,7 +36831,7 @@ var init_voice = __esm({
|
|
|
35546
36831
|
return buffer;
|
|
35547
36832
|
}
|
|
35548
36833
|
writeWav(samples, sampleRate, path) {
|
|
35549
|
-
|
|
36834
|
+
writeFileSync14(path, this.buildWavBuffer(samples, sampleRate));
|
|
35550
36835
|
}
|
|
35551
36836
|
// -------------------------------------------------------------------------
|
|
35552
36837
|
// Audio playback (system default speakers)
|
|
@@ -35722,11 +37007,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
35722
37007
|
return;
|
|
35723
37008
|
}
|
|
35724
37009
|
}
|
|
35725
|
-
if (!
|
|
37010
|
+
if (!existsSync34(wavPath))
|
|
35726
37011
|
return;
|
|
35727
37012
|
if (volume !== 1) {
|
|
35728
37013
|
try {
|
|
35729
|
-
const wavData =
|
|
37014
|
+
const wavData = readFileSync25(wavPath);
|
|
35730
37015
|
if (wavData.length > 44) {
|
|
35731
37016
|
const header = wavData.subarray(0, 44);
|
|
35732
37017
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -35734,14 +37019,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
35734
37019
|
samples[i] = Math.round(samples[i] * volume);
|
|
35735
37020
|
}
|
|
35736
37021
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
35737
|
-
|
|
37022
|
+
writeFileSync14(wavPath, scaled);
|
|
35738
37023
|
}
|
|
35739
37024
|
} catch {
|
|
35740
37025
|
}
|
|
35741
37026
|
}
|
|
35742
37027
|
if (this.onPCMOutput) {
|
|
35743
37028
|
try {
|
|
35744
|
-
const wavData =
|
|
37029
|
+
const wavData = readFileSync25(wavPath);
|
|
35745
37030
|
if (wavData.length > 44) {
|
|
35746
37031
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
35747
37032
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -35790,10 +37075,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
35790
37075
|
return null;
|
|
35791
37076
|
}
|
|
35792
37077
|
}
|
|
35793
|
-
if (!
|
|
37078
|
+
if (!existsSync34(wavPath))
|
|
35794
37079
|
return null;
|
|
35795
37080
|
try {
|
|
35796
|
-
const data =
|
|
37081
|
+
const data = readFileSync25(wavPath);
|
|
35797
37082
|
unlinkSync5(wavPath);
|
|
35798
37083
|
return data;
|
|
35799
37084
|
} catch {
|
|
@@ -35807,24 +37092,24 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
35807
37092
|
if (this.ort)
|
|
35808
37093
|
return;
|
|
35809
37094
|
const arch = process.arch;
|
|
35810
|
-
|
|
37095
|
+
mkdirSync14(voiceDir(), { recursive: true });
|
|
35811
37096
|
const pkgPath = join43(voiceDir(), "package.json");
|
|
35812
37097
|
const expectedDeps = {
|
|
35813
37098
|
"onnxruntime-node": "^1.21.0",
|
|
35814
37099
|
"phonemizer": "^1.2.1"
|
|
35815
37100
|
};
|
|
35816
|
-
if (
|
|
37101
|
+
if (existsSync34(pkgPath)) {
|
|
35817
37102
|
try {
|
|
35818
|
-
const existing = JSON.parse(
|
|
37103
|
+
const existing = JSON.parse(readFileSync25(pkgPath, "utf8"));
|
|
35819
37104
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
35820
37105
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
35821
|
-
|
|
37106
|
+
writeFileSync14(pkgPath, JSON.stringify(existing, null, 2));
|
|
35822
37107
|
}
|
|
35823
37108
|
} catch {
|
|
35824
37109
|
}
|
|
35825
37110
|
}
|
|
35826
|
-
if (!
|
|
35827
|
-
|
|
37111
|
+
if (!existsSync34(pkgPath)) {
|
|
37112
|
+
writeFileSync14(pkgPath, JSON.stringify({
|
|
35828
37113
|
name: "open-agents-voice",
|
|
35829
37114
|
private: true,
|
|
35830
37115
|
dependencies: expectedDeps
|
|
@@ -35841,7 +37126,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
35841
37126
|
}
|
|
35842
37127
|
};
|
|
35843
37128
|
const onnxNodeModules = join43(voiceDir(), "node_modules", "onnxruntime-node");
|
|
35844
|
-
const onnxInstalled =
|
|
37129
|
+
const onnxInstalled = existsSync34(onnxNodeModules);
|
|
35845
37130
|
if (onnxInstalled && !probeOnnx()) {
|
|
35846
37131
|
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
|
|
35847
37132
|
}
|
|
@@ -35899,18 +37184,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
35899
37184
|
const dir = modelDir(id);
|
|
35900
37185
|
const onnxPath = modelOnnxPath(id);
|
|
35901
37186
|
const configPath = modelConfigPath(id);
|
|
35902
|
-
if (
|
|
37187
|
+
if (existsSync34(onnxPath) && existsSync34(configPath))
|
|
35903
37188
|
return;
|
|
35904
|
-
|
|
35905
|
-
if (!
|
|
37189
|
+
mkdirSync14(dir, { recursive: true });
|
|
37190
|
+
if (!existsSync34(configPath)) {
|
|
35906
37191
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
35907
37192
|
const configResp = await fetch(model.configUrl);
|
|
35908
37193
|
if (!configResp.ok)
|
|
35909
37194
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
35910
37195
|
const configText = await configResp.text();
|
|
35911
|
-
|
|
37196
|
+
writeFileSync14(configPath, configText);
|
|
35912
37197
|
}
|
|
35913
|
-
if (!
|
|
37198
|
+
if (!existsSync34(onnxPath)) {
|
|
35914
37199
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
35915
37200
|
const onnxResp = await fetch(model.onnxUrl);
|
|
35916
37201
|
if (!onnxResp.ok)
|
|
@@ -35935,7 +37220,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
35935
37220
|
}
|
|
35936
37221
|
}
|
|
35937
37222
|
const fullBuffer = Buffer.concat(chunks);
|
|
35938
|
-
|
|
37223
|
+
writeFileSync14(onnxPath, fullBuffer);
|
|
35939
37224
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
35940
37225
|
}
|
|
35941
37226
|
}
|
|
@@ -35947,10 +37232,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
35947
37232
|
throw new Error("ONNX runtime not loaded");
|
|
35948
37233
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
35949
37234
|
const configPath = modelConfigPath(this.modelId);
|
|
35950
|
-
if (!
|
|
37235
|
+
if (!existsSync34(onnxPath) || !existsSync34(configPath)) {
|
|
35951
37236
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
35952
37237
|
}
|
|
35953
|
-
this.config = JSON.parse(
|
|
37238
|
+
this.config = JSON.parse(readFileSync25(configPath, "utf8"));
|
|
35954
37239
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
35955
37240
|
executionProviders: ["cpu"],
|
|
35956
37241
|
graphOptimizationLevel: "all"
|
|
@@ -36811,13 +38096,13 @@ var init_stream_renderer = __esm({
|
|
|
36811
38096
|
});
|
|
36812
38097
|
|
|
36813
38098
|
// packages/cli/dist/tui/edit-history.js
|
|
36814
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
38099
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
|
|
36815
38100
|
import { join as join44 } from "node:path";
|
|
36816
38101
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
36817
38102
|
const historyDir = join44(repoRoot, ".oa", "history");
|
|
36818
38103
|
const logPath = join44(historyDir, "edits.jsonl");
|
|
36819
38104
|
try {
|
|
36820
|
-
|
|
38105
|
+
mkdirSync15(historyDir, { recursive: true });
|
|
36821
38106
|
} catch {
|
|
36822
38107
|
}
|
|
36823
38108
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -36926,17 +38211,17 @@ var init_edit_history = __esm({
|
|
|
36926
38211
|
});
|
|
36927
38212
|
|
|
36928
38213
|
// packages/cli/dist/tui/promptLoader.js
|
|
36929
|
-
import { readFileSync as
|
|
36930
|
-
import { join as join45, dirname as
|
|
38214
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35 } from "node:fs";
|
|
38215
|
+
import { join as join45, dirname as dirname17 } from "node:path";
|
|
36931
38216
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
36932
38217
|
function loadPrompt3(promptPath, vars) {
|
|
36933
38218
|
let content = cache3.get(promptPath);
|
|
36934
38219
|
if (content === void 0) {
|
|
36935
38220
|
const fullPath = join45(PROMPTS_DIR3, promptPath);
|
|
36936
|
-
if (!
|
|
38221
|
+
if (!existsSync35(fullPath)) {
|
|
36937
38222
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
36938
38223
|
}
|
|
36939
|
-
content =
|
|
38224
|
+
content = readFileSync26(fullPath, "utf-8");
|
|
36940
38225
|
cache3.set(promptPath, content);
|
|
36941
38226
|
}
|
|
36942
38227
|
if (!vars)
|
|
@@ -36948,24 +38233,24 @@ var init_promptLoader3 = __esm({
|
|
|
36948
38233
|
"packages/cli/dist/tui/promptLoader.js"() {
|
|
36949
38234
|
"use strict";
|
|
36950
38235
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
36951
|
-
__dirname6 =
|
|
38236
|
+
__dirname6 = dirname17(__filename3);
|
|
36952
38237
|
devPath2 = join45(__dirname6, "..", "..", "prompts");
|
|
36953
38238
|
publishedPath2 = join45(__dirname6, "..", "prompts");
|
|
36954
|
-
PROMPTS_DIR3 =
|
|
38239
|
+
PROMPTS_DIR3 = existsSync35(devPath2) ? devPath2 : publishedPath2;
|
|
36955
38240
|
cache3 = /* @__PURE__ */ new Map();
|
|
36956
38241
|
}
|
|
36957
38242
|
});
|
|
36958
38243
|
|
|
36959
38244
|
// packages/cli/dist/tui/dream-engine.js
|
|
36960
|
-
import { mkdirSync as
|
|
38245
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync15, readFileSync as readFileSync27, existsSync as existsSync36, cpSync, rmSync, readdirSync as readdirSync11 } from "node:fs";
|
|
36961
38246
|
import { join as join46, basename as basename12 } from "node:path";
|
|
36962
38247
|
import { execSync as execSync28 } from "node:child_process";
|
|
36963
38248
|
function loadAutoresearchMemory(repoRoot) {
|
|
36964
38249
|
const memoryPath = join46(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
36965
|
-
if (!
|
|
38250
|
+
if (!existsSync36(memoryPath))
|
|
36966
38251
|
return "";
|
|
36967
38252
|
try {
|
|
36968
|
-
const raw =
|
|
38253
|
+
const raw = readFileSync27(memoryPath, "utf-8");
|
|
36969
38254
|
const data = JSON.parse(raw);
|
|
36970
38255
|
const sections = [];
|
|
36971
38256
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -37161,8 +38446,8 @@ var init_dream_engine = __esm({
|
|
|
37161
38446
|
}
|
|
37162
38447
|
try {
|
|
37163
38448
|
const dir = join46(targetPath, "..");
|
|
37164
|
-
|
|
37165
|
-
|
|
38449
|
+
mkdirSync16(dir, { recursive: true });
|
|
38450
|
+
writeFileSync15(targetPath, content, "utf-8");
|
|
37166
38451
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
37167
38452
|
} catch (err) {
|
|
37168
38453
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -37195,15 +38480,15 @@ var init_dream_engine = __esm({
|
|
|
37195
38480
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
37196
38481
|
}
|
|
37197
38482
|
try {
|
|
37198
|
-
if (!
|
|
38483
|
+
if (!existsSync36(targetPath)) {
|
|
37199
38484
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
37200
38485
|
}
|
|
37201
|
-
let content =
|
|
38486
|
+
let content = readFileSync27(targetPath, "utf-8");
|
|
37202
38487
|
if (!content.includes(oldStr)) {
|
|
37203
38488
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
37204
38489
|
}
|
|
37205
38490
|
content = content.replace(oldStr, newStr);
|
|
37206
|
-
|
|
38491
|
+
writeFileSync15(targetPath, content, "utf-8");
|
|
37207
38492
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
37208
38493
|
} catch (err) {
|
|
37209
38494
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -37250,8 +38535,8 @@ var init_dream_engine = __esm({
|
|
|
37250
38535
|
}
|
|
37251
38536
|
try {
|
|
37252
38537
|
const dir = join46(targetPath, "..");
|
|
37253
|
-
|
|
37254
|
-
|
|
38538
|
+
mkdirSync16(dir, { recursive: true });
|
|
38539
|
+
writeFileSync15(targetPath, content, "utf-8");
|
|
37255
38540
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
37256
38541
|
} catch (err) {
|
|
37257
38542
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -37284,15 +38569,15 @@ var init_dream_engine = __esm({
|
|
|
37284
38569
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
37285
38570
|
}
|
|
37286
38571
|
try {
|
|
37287
|
-
if (!
|
|
38572
|
+
if (!existsSync36(targetPath)) {
|
|
37288
38573
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
37289
38574
|
}
|
|
37290
|
-
let content =
|
|
38575
|
+
let content = readFileSync27(targetPath, "utf-8");
|
|
37291
38576
|
if (!content.includes(oldStr)) {
|
|
37292
38577
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
37293
38578
|
}
|
|
37294
38579
|
content = content.replace(oldStr, newStr);
|
|
37295
|
-
|
|
38580
|
+
writeFileSync15(targetPath, content, "utf-8");
|
|
37296
38581
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
37297
38582
|
} catch (err) {
|
|
37298
38583
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -37377,7 +38662,7 @@ var init_dream_engine = __esm({
|
|
|
37377
38662
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
37378
38663
|
results: []
|
|
37379
38664
|
};
|
|
37380
|
-
|
|
38665
|
+
mkdirSync16(this.dreamsDir, { recursive: true });
|
|
37381
38666
|
this.saveDreamState();
|
|
37382
38667
|
try {
|
|
37383
38668
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -37431,7 +38716,7 @@ ${result.summary}`;
|
|
|
37431
38716
|
renderDreamContraction(cycle);
|
|
37432
38717
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
37433
38718
|
const summaryPath = join46(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
37434
|
-
|
|
38719
|
+
writeFileSync15(summaryPath, cycleSummary, "utf-8");
|
|
37435
38720
|
}
|
|
37436
38721
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
37437
38722
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -38029,8 +39314,8 @@ ${summaryResult}
|
|
|
38029
39314
|
*Generated by open-agents autoresearch swarm*
|
|
38030
39315
|
`;
|
|
38031
39316
|
try {
|
|
38032
|
-
|
|
38033
|
-
|
|
39317
|
+
mkdirSync16(this.dreamsDir, { recursive: true });
|
|
39318
|
+
writeFileSync15(reportPath, report, "utf-8");
|
|
38034
39319
|
} catch {
|
|
38035
39320
|
}
|
|
38036
39321
|
renderSwarmComplete(workspace);
|
|
@@ -38098,7 +39383,7 @@ ${summaryResult}
|
|
|
38098
39383
|
saveVersionCheckpoint(cycle) {
|
|
38099
39384
|
const checkpointDir = join46(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
38100
39385
|
try {
|
|
38101
|
-
|
|
39386
|
+
mkdirSync16(checkpointDir, { recursive: true });
|
|
38102
39387
|
try {
|
|
38103
39388
|
const gitStatus = execSync28("git status --porcelain", {
|
|
38104
39389
|
cwd: this.repoRoot,
|
|
@@ -38115,10 +39400,10 @@ ${summaryResult}
|
|
|
38115
39400
|
encoding: "utf-8",
|
|
38116
39401
|
timeout: 5e3
|
|
38117
39402
|
}).trim();
|
|
38118
|
-
|
|
38119
|
-
|
|
38120
|
-
|
|
38121
|
-
|
|
39403
|
+
writeFileSync15(join46(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
39404
|
+
writeFileSync15(join46(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
39405
|
+
writeFileSync15(join46(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
39406
|
+
writeFileSync15(join46(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
38122
39407
|
cycle,
|
|
38123
39408
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38124
39409
|
gitHash,
|
|
@@ -38126,7 +39411,7 @@ ${summaryResult}
|
|
|
38126
39411
|
}, null, 2), "utf-8");
|
|
38127
39412
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
38128
39413
|
} catch {
|
|
38129
|
-
|
|
39414
|
+
writeFileSync15(join46(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
38130
39415
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
38131
39416
|
}
|
|
38132
39417
|
} catch (err) {
|
|
@@ -38184,14 +39469,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
38184
39469
|
---
|
|
38185
39470
|
*Auto-generated by open-agents dream engine*
|
|
38186
39471
|
`;
|
|
38187
|
-
|
|
39472
|
+
writeFileSync15(join46(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
38188
39473
|
} catch {
|
|
38189
39474
|
}
|
|
38190
39475
|
}
|
|
38191
39476
|
/** Save dream state for resume/inspection */
|
|
38192
39477
|
saveDreamState() {
|
|
38193
39478
|
try {
|
|
38194
|
-
|
|
39479
|
+
writeFileSync15(join46(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
38195
39480
|
} catch {
|
|
38196
39481
|
}
|
|
38197
39482
|
}
|
|
@@ -38565,7 +39850,7 @@ var init_bless_engine = __esm({
|
|
|
38565
39850
|
});
|
|
38566
39851
|
|
|
38567
39852
|
// packages/cli/dist/tui/dmn-engine.js
|
|
38568
|
-
import { existsSync as
|
|
39853
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28, writeFileSync as writeFileSync16, mkdirSync as mkdirSync17, readdirSync as readdirSync12, unlinkSync as unlinkSync6 } from "node:fs";
|
|
38569
39854
|
import { join as join47, basename as basename13 } from "node:path";
|
|
38570
39855
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
38571
39856
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
@@ -38681,7 +39966,7 @@ var init_dmn_engine = __esm({
|
|
|
38681
39966
|
this.repoRoot = repoRoot;
|
|
38682
39967
|
this.stateDir = join47(repoRoot, ".oa", "dmn");
|
|
38683
39968
|
this.historyDir = join47(repoRoot, ".oa", "dmn", "cycles");
|
|
38684
|
-
|
|
39969
|
+
mkdirSync17(this.historyDir, { recursive: true });
|
|
38685
39970
|
this.loadState();
|
|
38686
39971
|
}
|
|
38687
39972
|
get stats() {
|
|
@@ -39274,7 +40559,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
39274
40559
|
join47(this.repoRoot, ".open-agents", "memory")
|
|
39275
40560
|
];
|
|
39276
40561
|
for (const dir of dirs) {
|
|
39277
|
-
if (!
|
|
40562
|
+
if (!existsSync37(dir))
|
|
39278
40563
|
continue;
|
|
39279
40564
|
try {
|
|
39280
40565
|
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -39291,23 +40576,23 @@ OUTPUT: Call task_complete with JSON:
|
|
|
39291
40576
|
// ── State persistence ─────────────────────────────────────────────────
|
|
39292
40577
|
loadState() {
|
|
39293
40578
|
const path = join47(this.stateDir, "state.json");
|
|
39294
|
-
if (
|
|
40579
|
+
if (existsSync37(path)) {
|
|
39295
40580
|
try {
|
|
39296
|
-
this.state = JSON.parse(
|
|
40581
|
+
this.state = JSON.parse(readFileSync28(path, "utf-8"));
|
|
39297
40582
|
} catch {
|
|
39298
40583
|
}
|
|
39299
40584
|
}
|
|
39300
40585
|
}
|
|
39301
40586
|
saveState() {
|
|
39302
40587
|
try {
|
|
39303
|
-
|
|
40588
|
+
writeFileSync16(join47(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
39304
40589
|
} catch {
|
|
39305
40590
|
}
|
|
39306
40591
|
}
|
|
39307
40592
|
saveCycleResult(result) {
|
|
39308
40593
|
try {
|
|
39309
40594
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
39310
|
-
|
|
40595
|
+
writeFileSync16(join47(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
39311
40596
|
const files = readdirSync12(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
39312
40597
|
if (files.length > 50) {
|
|
39313
40598
|
for (const old of files.slice(0, files.length - 50)) {
|
|
@@ -39325,7 +40610,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
39325
40610
|
});
|
|
39326
40611
|
|
|
39327
40612
|
// packages/cli/dist/tui/snr-engine.js
|
|
39328
|
-
import { existsSync as
|
|
40613
|
+
import { existsSync as existsSync38, readdirSync as readdirSync13, readFileSync as readFileSync29 } from "node:fs";
|
|
39329
40614
|
import { join as join48, basename as basename14 } from "node:path";
|
|
39330
40615
|
function computeDPrime(signalScores, noiseScores) {
|
|
39331
40616
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
@@ -39570,7 +40855,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
39570
40855
|
join48(this.repoRoot, ".open-agents", "memory")
|
|
39571
40856
|
];
|
|
39572
40857
|
for (const dir of dirs) {
|
|
39573
|
-
if (!
|
|
40858
|
+
if (!existsSync38(dir))
|
|
39574
40859
|
continue;
|
|
39575
40860
|
try {
|
|
39576
40861
|
const files = readdirSync13(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -39579,7 +40864,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
39579
40864
|
if (topics.length > 0 && !topics.includes(topic))
|
|
39580
40865
|
continue;
|
|
39581
40866
|
try {
|
|
39582
|
-
const data = JSON.parse(
|
|
40867
|
+
const data = JSON.parse(readFileSync29(join48(dir, f), "utf-8"));
|
|
39583
40868
|
for (const [key, val] of Object.entries(data)) {
|
|
39584
40869
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
39585
40870
|
entries.push({ topic, key, value });
|
|
@@ -40146,7 +41431,7 @@ var init_tool_policy = __esm({
|
|
|
40146
41431
|
});
|
|
40147
41432
|
|
|
40148
41433
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
40149
|
-
import { mkdirSync as
|
|
41434
|
+
import { mkdirSync as mkdirSync18, existsSync as existsSync39, unlinkSync as unlinkSync7, readdirSync as readdirSync14, statSync as statSync10 } from "node:fs";
|
|
40150
41435
|
import { join as join49, resolve as resolve27 } from "node:path";
|
|
40151
41436
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
40152
41437
|
function convertMarkdownToTelegramHTML(md) {
|
|
@@ -40475,7 +41760,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
40475
41760
|
this.polling = true;
|
|
40476
41761
|
this.abortController = new AbortController();
|
|
40477
41762
|
try {
|
|
40478
|
-
|
|
41763
|
+
mkdirSync18(this.mediaCacheDir, { recursive: true });
|
|
40479
41764
|
} catch {
|
|
40480
41765
|
}
|
|
40481
41766
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -42012,6 +43297,56 @@ var init_status_bar = __esm({
|
|
|
42012
43297
|
poll();
|
|
42013
43298
|
this._remoteMetricsTimer = setInterval(poll, 1e4);
|
|
42014
43299
|
}
|
|
43300
|
+
/**
|
|
43301
|
+
* Start polling a peer endpoint for metrics via nexus daemon.
|
|
43302
|
+
* Queries the remote peer's system_metrics capability for CPU/GPU data,
|
|
43303
|
+
* with fallback to local metering data.
|
|
43304
|
+
*/
|
|
43305
|
+
startPeerMetricsPolling(sendCommand, peerId, authKey) {
|
|
43306
|
+
this.stopRemoteMetricsPolling();
|
|
43307
|
+
const poll = async () => {
|
|
43308
|
+
try {
|
|
43309
|
+
const queryData = { type: "query" };
|
|
43310
|
+
if (authKey)
|
|
43311
|
+
queryData.auth_key = authKey;
|
|
43312
|
+
const raw = await sendCommand("invoke_capability", {
|
|
43313
|
+
target_peer: peerId,
|
|
43314
|
+
capability: "system_metrics",
|
|
43315
|
+
data: JSON.stringify(queryData)
|
|
43316
|
+
}, 8e3);
|
|
43317
|
+
const result = JSON.parse(raw);
|
|
43318
|
+
if (result.ok !== false && result.result) {
|
|
43319
|
+
const data = typeof result.result === "string" ? JSON.parse(result.result) : result.result;
|
|
43320
|
+
this.setRemoteMetrics({
|
|
43321
|
+
cpuUtil: data.cpu?.utilization ?? 0,
|
|
43322
|
+
gpuUtil: data.gpu?.available ? data.gpu.utilization ?? 0 : -1,
|
|
43323
|
+
gpuName: data.gpu?.name ?? "",
|
|
43324
|
+
vramUtil: data.gpu?.available ? data.gpu.vramUtilization ?? 0 : -1,
|
|
43325
|
+
memUtil: data.memory?.utilization ?? 0
|
|
43326
|
+
});
|
|
43327
|
+
return;
|
|
43328
|
+
}
|
|
43329
|
+
} catch {
|
|
43330
|
+
}
|
|
43331
|
+
try {
|
|
43332
|
+
const raw = await sendCommand("metering_status", { peer_id: peerId }, 5e3);
|
|
43333
|
+
const result = JSON.parse(raw);
|
|
43334
|
+
if (result.ok !== false && result.output) {
|
|
43335
|
+
this.setRemoteMetrics({
|
|
43336
|
+
cpuUtil: -1,
|
|
43337
|
+
// -1 = unavailable (won't render bar)
|
|
43338
|
+
gpuUtil: -1,
|
|
43339
|
+
gpuName: "peer",
|
|
43340
|
+
vramUtil: -1,
|
|
43341
|
+
memUtil: -1
|
|
43342
|
+
});
|
|
43343
|
+
}
|
|
43344
|
+
} catch {
|
|
43345
|
+
}
|
|
43346
|
+
};
|
|
43347
|
+
poll();
|
|
43348
|
+
this._remoteMetricsTimer = setInterval(poll, 1e4);
|
|
43349
|
+
}
|
|
42015
43350
|
/** Stop polling remote metrics */
|
|
42016
43351
|
stopRemoteMetricsPolling() {
|
|
42017
43352
|
if (this._remoteMetricsTimer) {
|
|
@@ -42745,11 +44080,11 @@ var init_status_bar = __esm({
|
|
|
42745
44080
|
import * as readline2 from "node:readline";
|
|
42746
44081
|
import { Writable } from "node:stream";
|
|
42747
44082
|
import { cwd } from "node:process";
|
|
42748
|
-
import { resolve as resolve28, join as join50, dirname as
|
|
44083
|
+
import { resolve as resolve28, join as join50, dirname as dirname18, extname as extname9 } from "node:path";
|
|
42749
44084
|
import { createRequire as createRequire2 } from "node:module";
|
|
42750
44085
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
42751
|
-
import { readFileSync as
|
|
42752
|
-
import { existsSync as
|
|
44086
|
+
import { readFileSync as readFileSync30, writeFileSync as writeFileSync17, appendFileSync as appendFileSync3, rmSync as rmSync2, readdirSync as readdirSync15, mkdirSync as mkdirSync19 } from "node:fs";
|
|
44087
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
42753
44088
|
import { homedir as homedir13 } from "node:os";
|
|
42754
44089
|
function formatTimeAgo(date) {
|
|
42755
44090
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -42767,14 +44102,14 @@ function formatTimeAgo(date) {
|
|
|
42767
44102
|
function getVersion3() {
|
|
42768
44103
|
try {
|
|
42769
44104
|
const require2 = createRequire2(import.meta.url);
|
|
42770
|
-
const thisDir =
|
|
44105
|
+
const thisDir = dirname18(fileURLToPath12(import.meta.url));
|
|
42771
44106
|
const candidates = [
|
|
42772
44107
|
join50(thisDir, "..", "package.json"),
|
|
42773
44108
|
join50(thisDir, "..", "..", "package.json"),
|
|
42774
44109
|
join50(thisDir, "..", "..", "..", "package.json")
|
|
42775
44110
|
];
|
|
42776
44111
|
for (const pkgPath of candidates) {
|
|
42777
|
-
if (
|
|
44112
|
+
if (existsSync40(pkgPath)) {
|
|
42778
44113
|
const pkg = require2(pkgPath);
|
|
42779
44114
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
42780
44115
|
return pkg.version ?? "0.0.0";
|
|
@@ -42917,7 +44252,8 @@ function createSubAgentTool(config, repoRoot, ctxWindowSize) {
|
|
|
42917
44252
|
let backend;
|
|
42918
44253
|
if (config.backendType === "nexus") {
|
|
42919
44254
|
const nexusTool = new NexusTool(repoRoot);
|
|
42920
|
-
|
|
44255
|
+
const subTargetPeer = config.backendUrl.startsWith("peer://") ? config.backendUrl.slice(7) : void 0;
|
|
44256
|
+
backend = new NexusAgenticBackend(nexusTool.sendCommand.bind(nexusTool), config.model, subTargetPeer, config.apiKey);
|
|
42921
44257
|
} else {
|
|
42922
44258
|
backend = new OllamaAgenticBackend(config.backendUrl, config.model, config.apiKey);
|
|
42923
44259
|
}
|
|
@@ -42984,11 +44320,11 @@ function gatherMemorySnippets(root) {
|
|
|
42984
44320
|
join50(root, ".open-agents", "memory")
|
|
42985
44321
|
];
|
|
42986
44322
|
for (const dir of dirs) {
|
|
42987
|
-
if (!
|
|
44323
|
+
if (!existsSync40(dir))
|
|
42988
44324
|
continue;
|
|
42989
44325
|
try {
|
|
42990
44326
|
for (const f of readdirSync15(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
42991
|
-
const data = JSON.parse(
|
|
44327
|
+
const data = JSON.parse(readFileSync30(join50(dir, f), "utf-8"));
|
|
42992
44328
|
for (const val of Object.values(data)) {
|
|
42993
44329
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
42994
44330
|
if (v.length > 10)
|
|
@@ -43094,10 +44430,58 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
43094
44430
|
if (config.backendType === "nexus") {
|
|
43095
44431
|
const nexusTool = new NexusTool(repoRoot);
|
|
43096
44432
|
const sendFn = nexusTool.sendCommand.bind(nexusTool);
|
|
43097
|
-
|
|
44433
|
+
const targetPeer = config.backendUrl.startsWith("peer://") ? config.backendUrl.slice(7) : void 0;
|
|
44434
|
+
backend = new NexusAgenticBackend(sendFn, config.model, targetPeer, config.apiKey);
|
|
43098
44435
|
} else {
|
|
43099
44436
|
backend = new OllamaAgenticBackend(config.backendUrl, config.model, config.apiKey);
|
|
43100
44437
|
}
|
|
44438
|
+
try {
|
|
44439
|
+
const endpointHistory = loadUsageHistory("endpoint", repoRoot);
|
|
44440
|
+
const fallbackEndpoints = [];
|
|
44441
|
+
for (const entry of endpointHistory) {
|
|
44442
|
+
if (entry.value === config.backendUrl)
|
|
44443
|
+
continue;
|
|
44444
|
+
const bt = entry.meta?.backendType ?? "ollama";
|
|
44445
|
+
const ep = {
|
|
44446
|
+
url: entry.value,
|
|
44447
|
+
backendType: bt,
|
|
44448
|
+
apiKey: entry.meta?.authHint ? void 0 : void 0,
|
|
44449
|
+
// auth keys not stored in history
|
|
44450
|
+
label: entry.meta?.provider ?? entry.value
|
|
44451
|
+
};
|
|
44452
|
+
if (bt === "nexus" && ep.url.startsWith("peer://")) {
|
|
44453
|
+
const nt = new NexusTool(repoRoot);
|
|
44454
|
+
ep.sendCommandFn = nt.sendCommand.bind(nt);
|
|
44455
|
+
}
|
|
44456
|
+
fallbackEndpoints.push(ep);
|
|
44457
|
+
}
|
|
44458
|
+
if (fallbackEndpoints.length > 0) {
|
|
44459
|
+
const primaryEndpoint = {
|
|
44460
|
+
url: config.backendUrl,
|
|
44461
|
+
backendType: config.backendType,
|
|
44462
|
+
apiKey: config.apiKey,
|
|
44463
|
+
label: "primary"
|
|
44464
|
+
};
|
|
44465
|
+
if (config.backendType === "nexus" && config.backendUrl.startsWith("peer://")) {
|
|
44466
|
+
const nt = new NexusTool(repoRoot);
|
|
44467
|
+
primaryEndpoint.sendCommandFn = nt.sendCommand.bind(nt);
|
|
44468
|
+
}
|
|
44469
|
+
backend = new CascadeBackend(config.model, [primaryEndpoint, ...fallbackEndpoints], {
|
|
44470
|
+
onSwitch: (_from, to, reason) => {
|
|
44471
|
+
process.stderr.write(`
|
|
44472
|
+
[cascade] Failover \u2192 ${to.label ?? to.url}: ${reason}
|
|
44473
|
+
`);
|
|
44474
|
+
},
|
|
44475
|
+
onProbeResult: (ep, success) => {
|
|
44476
|
+
if (success) {
|
|
44477
|
+
process.stderr.write(`[cascade] Primary recovered: ${ep.label ?? ep.url}
|
|
44478
|
+
`);
|
|
44479
|
+
}
|
|
44480
|
+
}
|
|
44481
|
+
});
|
|
44482
|
+
}
|
|
44483
|
+
} catch {
|
|
44484
|
+
}
|
|
43101
44485
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
43102
44486
|
const runner = new AgenticRunner(backend, {
|
|
43103
44487
|
maxTurns: 60,
|
|
@@ -43521,6 +44905,9 @@ ${emotionContext}` : `Working directory: ${repoRoot}`;
|
|
|
43521
44905
|
} catch {
|
|
43522
44906
|
}
|
|
43523
44907
|
}
|
|
44908
|
+
if (backend && typeof backend.stop === "function") {
|
|
44909
|
+
backend.stop();
|
|
44910
|
+
}
|
|
43524
44911
|
});
|
|
43525
44912
|
return { runner, promise, filesTouched, get toolCallCount() {
|
|
43526
44913
|
return toolSequence.length;
|
|
@@ -43930,8 +45317,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
43930
45317
|
const MAX_HISTORY_LINES = 500;
|
|
43931
45318
|
let savedHistory = [];
|
|
43932
45319
|
try {
|
|
43933
|
-
if (
|
|
43934
|
-
const raw =
|
|
45320
|
+
if (existsSync40(HISTORY_FILE)) {
|
|
45321
|
+
const raw = readFileSync30(HISTORY_FILE, "utf8").trim();
|
|
43935
45322
|
if (raw)
|
|
43936
45323
|
savedHistory = raw.split("\n").reverse();
|
|
43937
45324
|
}
|
|
@@ -43950,12 +45337,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
43950
45337
|
if (!line.trim())
|
|
43951
45338
|
return;
|
|
43952
45339
|
try {
|
|
43953
|
-
|
|
45340
|
+
mkdirSync19(HISTORY_DIR, { recursive: true });
|
|
43954
45341
|
appendFileSync3(HISTORY_FILE, line + "\n", "utf8");
|
|
43955
45342
|
if (Math.random() < 0.02) {
|
|
43956
|
-
const all =
|
|
45343
|
+
const all = readFileSync30(HISTORY_FILE, "utf8").trim().split("\n");
|
|
43957
45344
|
if (all.length > MAX_HISTORY_LINES) {
|
|
43958
|
-
|
|
45345
|
+
writeFileSync17(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
43959
45346
|
}
|
|
43960
45347
|
}
|
|
43961
45348
|
} catch {
|
|
@@ -44085,8 +45472,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
44085
45472
|
} catch {
|
|
44086
45473
|
}
|
|
44087
45474
|
try {
|
|
44088
|
-
const
|
|
44089
|
-
|
|
45475
|
+
const isPeer = currentConfig.backendUrl.startsWith("peer://");
|
|
45476
|
+
const isRemote = !currentConfig.backendUrl.includes("127.0.0.1") && !currentConfig.backendUrl.includes("localhost") && !isPeer;
|
|
45477
|
+
if (isPeer) {
|
|
45478
|
+
const peerId = currentConfig.backendUrl.slice(7);
|
|
45479
|
+
const nexusTool = new NexusTool(repoRoot);
|
|
45480
|
+
statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, currentConfig.apiKey);
|
|
45481
|
+
} else if (isRemote) {
|
|
44090
45482
|
statusBar.startRemoteMetricsPolling(currentConfig.backendUrl, currentConfig.apiKey);
|
|
44091
45483
|
}
|
|
44092
45484
|
} catch {
|
|
@@ -44158,8 +45550,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
44158
45550
|
};
|
|
44159
45551
|
const newProvider = detectProvider(url);
|
|
44160
45552
|
costTracker.setProvider(newProvider.id);
|
|
44161
|
-
const
|
|
44162
|
-
|
|
45553
|
+
const isPeer = url.startsWith("peer://");
|
|
45554
|
+
const isRemote = !url.includes("127.0.0.1") && !url.includes("localhost") && !isPeer;
|
|
45555
|
+
if (isPeer) {
|
|
45556
|
+
const peerId = url.slice(7);
|
|
45557
|
+
const nexusTool = new NexusTool(repoRoot);
|
|
45558
|
+
statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, apiKey);
|
|
45559
|
+
} else if (isRemote) {
|
|
44163
45560
|
statusBar.startRemoteMetricsPolling(url, apiKey);
|
|
44164
45561
|
} else {
|
|
44165
45562
|
statusBar.stopRemoteMetricsPolling();
|
|
@@ -44714,7 +46111,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44714
46111
|
getCallUrl() {
|
|
44715
46112
|
return voiceSession?.tunnelUrl ?? null;
|
|
44716
46113
|
},
|
|
44717
|
-
async exposeStart(kindOrUrl, authKey, transport) {
|
|
46114
|
+
async exposeStart(kindOrUrl, authKey, transport, fullAccess) {
|
|
44718
46115
|
const knownKinds = ["ollama", "vllm", "llvm"];
|
|
44719
46116
|
let kind;
|
|
44720
46117
|
let targetUrl;
|
|
@@ -44730,6 +46127,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44730
46127
|
const p2pGateway = new ExposeP2PGateway({
|
|
44731
46128
|
kind,
|
|
44732
46129
|
targetUrl,
|
|
46130
|
+
authKey,
|
|
44733
46131
|
stateDir: join50(repoRoot, ".oa")
|
|
44734
46132
|
}, nexusTool);
|
|
44735
46133
|
p2pGateway.on("stats", (stats) => {
|
|
@@ -44758,7 +46156,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44758
46156
|
}
|
|
44759
46157
|
}
|
|
44760
46158
|
}
|
|
44761
|
-
const tunnelGateway = new ExposeGateway({ kind, targetUrl, authKey, stateDir: join50(repoRoot, ".oa") });
|
|
46159
|
+
const tunnelGateway = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join50(repoRoot, ".oa") });
|
|
44762
46160
|
tunnelGateway.on("stats", (stats) => {
|
|
44763
46161
|
statusBar.setExposeStatus({
|
|
44764
46162
|
status: stats.status,
|
|
@@ -44795,7 +46193,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44795
46193
|
if (exposeGateway instanceof ExposeP2PGateway) {
|
|
44796
46194
|
return {
|
|
44797
46195
|
tunnelUrl: exposeGateway.peerId,
|
|
44798
|
-
authKey:
|
|
46196
|
+
authKey: exposeGateway.authKey,
|
|
44799
46197
|
stats: exposeGateway.formatStats()
|
|
44800
46198
|
};
|
|
44801
46199
|
}
|
|
@@ -44805,6 +46203,18 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44805
46203
|
stats: exposeGateway.formatStats()
|
|
44806
46204
|
};
|
|
44807
46205
|
},
|
|
46206
|
+
// ── Nexus daemon connect ──────────────────────────────────────────────
|
|
46207
|
+
async nexusConnect() {
|
|
46208
|
+
const nexusTool = new NexusTool(repoRoot);
|
|
46209
|
+
const result = await nexusTool.execute({
|
|
46210
|
+
action: "connect",
|
|
46211
|
+
agent_name: "open-agents-node",
|
|
46212
|
+
agent_type: "general"
|
|
46213
|
+
});
|
|
46214
|
+
if (!result.success)
|
|
46215
|
+
throw new Error(result.error || "Connect failed");
|
|
46216
|
+
return result.output;
|
|
46217
|
+
},
|
|
44808
46218
|
// ── P2P mesh controls ────────────────────────────────────────────────
|
|
44809
46219
|
async p2pStart(bootstrapPeers) {
|
|
44810
46220
|
if (peerMesh)
|
|
@@ -44954,7 +46364,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
44954
46364
|
},
|
|
44955
46365
|
destroyProject() {
|
|
44956
46366
|
const oaPath = join50(repoRoot, OA_DIR);
|
|
44957
|
-
if (
|
|
46367
|
+
if (existsSync40(oaPath)) {
|
|
44958
46368
|
try {
|
|
44959
46369
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
44960
46370
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -45285,13 +46695,13 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
45285
46695
|
}
|
|
45286
46696
|
}
|
|
45287
46697
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
45288
|
-
const isImage = isImagePath(cleanPath) &&
|
|
45289
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
46698
|
+
const isImage = isImagePath(cleanPath) && existsSync40(resolve28(repoRoot, cleanPath));
|
|
46699
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync40(resolve28(repoRoot, cleanPath));
|
|
45290
46700
|
if (activeTask) {
|
|
45291
46701
|
if (isImage) {
|
|
45292
46702
|
try {
|
|
45293
46703
|
const imgPath = resolve28(repoRoot, cleanPath);
|
|
45294
|
-
const imgBuffer =
|
|
46704
|
+
const imgBuffer = readFileSync30(imgPath);
|
|
45295
46705
|
const base64 = imgBuffer.toString("base64");
|
|
45296
46706
|
const ext = extname9(cleanPath).toLowerCase();
|
|
45297
46707
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -45989,13 +47399,13 @@ __export(index_repo_exports, {
|
|
|
45989
47399
|
indexRepoCommand: () => indexRepoCommand
|
|
45990
47400
|
});
|
|
45991
47401
|
import { resolve as resolve29 } from "node:path";
|
|
45992
|
-
import { existsSync as
|
|
47402
|
+
import { existsSync as existsSync41, statSync as statSync11 } from "node:fs";
|
|
45993
47403
|
import { cwd as cwd2 } from "node:process";
|
|
45994
47404
|
async function indexRepoCommand(opts, _config) {
|
|
45995
47405
|
const repoRoot = resolve29(opts.repoPath ?? cwd2());
|
|
45996
47406
|
printHeader("Index Repository");
|
|
45997
47407
|
printInfo(`Indexing: ${repoRoot}`);
|
|
45998
|
-
if (!
|
|
47408
|
+
if (!existsSync41(repoRoot)) {
|
|
45999
47409
|
printError(`Path does not exist: ${repoRoot}`);
|
|
46000
47410
|
process.exit(1);
|
|
46001
47411
|
}
|
|
@@ -46469,7 +47879,7 @@ var serve_exports = {};
|
|
|
46469
47879
|
__export(serve_exports, {
|
|
46470
47880
|
serveCommand: () => serveCommand
|
|
46471
47881
|
});
|
|
46472
|
-
import { spawn as
|
|
47882
|
+
import { spawn as spawn18 } from "node:child_process";
|
|
46473
47883
|
async function serveCommand(opts, config) {
|
|
46474
47884
|
const backendType = config.backendType;
|
|
46475
47885
|
if (backendType === "ollama") {
|
|
@@ -46562,7 +47972,7 @@ async function serveVllm(opts, config) {
|
|
|
46562
47972
|
}
|
|
46563
47973
|
async function runVllmServer(args, verbose) {
|
|
46564
47974
|
return new Promise((resolve31, reject) => {
|
|
46565
|
-
const child =
|
|
47975
|
+
const child = spawn18("python", args, {
|
|
46566
47976
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
46567
47977
|
env: { ...process.env }
|
|
46568
47978
|
});
|
|
@@ -46627,7 +48037,7 @@ __export(eval_exports, {
|
|
|
46627
48037
|
evalCommand: () => evalCommand
|
|
46628
48038
|
});
|
|
46629
48039
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
46630
|
-
import { mkdirSync as
|
|
48040
|
+
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync18 } from "node:fs";
|
|
46631
48041
|
import { join as join53 } from "node:path";
|
|
46632
48042
|
async function evalCommand(opts, config) {
|
|
46633
48043
|
const suiteName = opts.suite ?? "basic";
|
|
@@ -46754,8 +48164,8 @@ async function evalCommand(opts, config) {
|
|
|
46754
48164
|
}
|
|
46755
48165
|
function createTempEvalRepo() {
|
|
46756
48166
|
const dir = join53(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
46757
|
-
|
|
46758
|
-
|
|
48167
|
+
mkdirSync20(dir, { recursive: true });
|
|
48168
|
+
writeFileSync18(join53(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
46759
48169
|
return dir;
|
|
46760
48170
|
}
|
|
46761
48171
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -46815,7 +48225,7 @@ init_updater();
|
|
|
46815
48225
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
46816
48226
|
import { createRequire as createRequire3 } from "node:module";
|
|
46817
48227
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
46818
|
-
import { dirname as
|
|
48228
|
+
import { dirname as dirname19, join as join54 } from "node:path";
|
|
46819
48229
|
|
|
46820
48230
|
// packages/cli/dist/cli.js
|
|
46821
48231
|
import { createInterface } from "node:readline";
|
|
@@ -46922,7 +48332,7 @@ init_output();
|
|
|
46922
48332
|
function getVersion4() {
|
|
46923
48333
|
try {
|
|
46924
48334
|
const require2 = createRequire3(import.meta.url);
|
|
46925
|
-
const pkgPath = join54(
|
|
48335
|
+
const pkgPath = join54(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
46926
48336
|
const pkg = require2(pkgPath);
|
|
46927
48337
|
return pkg.version;
|
|
46928
48338
|
} catch {
|