open-agents-ai 0.99.0 → 0.100.0
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 +878 -548
- package/package.json +2 -1
- package/prompts/agentic/system-large.md +2 -1
- package/prompts/agentic/system-medium.md +1 -1
- package/prompts/skill-builder/seed-analysis.md +30 -0
- package/prompts/skill-builder/skill-expansion.md +76 -0
- package/prompts/skill-builder/skill-validation.md +31 -0
package/dist/index.js
CHANGED
|
@@ -6047,7 +6047,8 @@ function loadSkillsFromDir(dir, source, out) {
|
|
|
6047
6047
|
description: manifestEntry?.description ?? parseDescription(skillMd),
|
|
6048
6048
|
triggers: manifestEntry?.triggers ?? parseTriggers(skillMd),
|
|
6049
6049
|
source,
|
|
6050
|
-
filePath: skillMd
|
|
6050
|
+
filePath: skillMd,
|
|
6051
|
+
compactionStrategy: parseCompactionStrategy(skillMd)
|
|
6051
6052
|
};
|
|
6052
6053
|
out.set(entry, info);
|
|
6053
6054
|
}
|
|
@@ -6134,6 +6135,25 @@ function parseDescription(filePath) {
|
|
|
6134
6135
|
}
|
|
6135
6136
|
return "";
|
|
6136
6137
|
}
|
|
6138
|
+
function parseCompactionStrategy(filePath) {
|
|
6139
|
+
try {
|
|
6140
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
6141
|
+
if (!content.startsWith("---"))
|
|
6142
|
+
return void 0;
|
|
6143
|
+
const endIdx = content.indexOf("---", 3);
|
|
6144
|
+
if (endIdx === -1)
|
|
6145
|
+
return void 0;
|
|
6146
|
+
const frontmatter = content.slice(3, endIdx);
|
|
6147
|
+
const match = frontmatter.match(/^compaction_strategy:\s*(.+)$/m);
|
|
6148
|
+
if (!match)
|
|
6149
|
+
return void 0;
|
|
6150
|
+
const val = match[1].trim().toLowerCase();
|
|
6151
|
+
const valid = ["default", "aggressive", "decisions", "errors", "summary", "structured"];
|
|
6152
|
+
return valid.includes(val) ? val : void 0;
|
|
6153
|
+
} catch {
|
|
6154
|
+
return void 0;
|
|
6155
|
+
}
|
|
6156
|
+
}
|
|
6137
6157
|
function parseTriggers(filePath) {
|
|
6138
6158
|
const triggers = [];
|
|
6139
6159
|
try {
|
|
@@ -6269,10 +6289,12 @@ Did you mean: ${fuzzy.map((s) => s.name).join(", ")}?` : "\nUse skill_list to se
|
|
|
6269
6289
|
durationMs: performance.now() - start
|
|
6270
6290
|
};
|
|
6271
6291
|
}
|
|
6292
|
+
const compactionHint = skill.compactionStrategy ? `
|
|
6293
|
+
Compaction strategy: ${skill.compactionStrategy}` : "";
|
|
6272
6294
|
return {
|
|
6273
6295
|
success: true,
|
|
6274
6296
|
output: `# Skill: ${skill.name}
|
|
6275
|
-
Source: ${skill.source}
|
|
6297
|
+
Source: ${skill.source}${compactionHint}
|
|
6276
6298
|
|
|
6277
6299
|
${content}`,
|
|
6278
6300
|
durationMs: performance.now() - start
|
|
@@ -6282,9 +6304,254 @@ ${content}`,
|
|
|
6282
6304
|
}
|
|
6283
6305
|
});
|
|
6284
6306
|
|
|
6307
|
+
// packages/execution/dist/tools/skill-builder.js
|
|
6308
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "node:fs";
|
|
6309
|
+
import { join as join15, dirname as dirname4 } from "node:path";
|
|
6310
|
+
function loadBuilderPrompt(name, vars) {
|
|
6311
|
+
const candidates = [
|
|
6312
|
+
// Dev layout: execution/dist/tools/ → orchestrator/prompts/
|
|
6313
|
+
join15(dirname4(dirname4(dirname4(__dirname))), "orchestrator", "prompts", "skill-builder", name),
|
|
6314
|
+
// Published layout: publish/dist/ → publish/prompts/
|
|
6315
|
+
join15(dirname4(dirname4(__dirname)), "prompts", "skill-builder", name),
|
|
6316
|
+
// Monorepo root fallback
|
|
6317
|
+
join15(dirname4(dirname4(dirname4(dirname4(__dirname)))), "packages", "orchestrator", "prompts", "skill-builder", name)
|
|
6318
|
+
];
|
|
6319
|
+
let content;
|
|
6320
|
+
for (const p of candidates) {
|
|
6321
|
+
try {
|
|
6322
|
+
content = readFileSync9(p, "utf-8");
|
|
6323
|
+
break;
|
|
6324
|
+
} catch {
|
|
6325
|
+
}
|
|
6326
|
+
}
|
|
6327
|
+
if (!content) {
|
|
6328
|
+
throw new Error(`Skill builder prompt not found: ${name} (searched: ${candidates.join(", ")})`);
|
|
6329
|
+
}
|
|
6330
|
+
if (!vars)
|
|
6331
|
+
return content;
|
|
6332
|
+
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
6333
|
+
}
|
|
6334
|
+
function extractJSON(text) {
|
|
6335
|
+
const codeBlockMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
6336
|
+
if (codeBlockMatch)
|
|
6337
|
+
return codeBlockMatch[1].trim();
|
|
6338
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
6339
|
+
if (jsonMatch)
|
|
6340
|
+
return jsonMatch[0];
|
|
6341
|
+
throw new Error("No JSON found in LLM response");
|
|
6342
|
+
}
|
|
6343
|
+
var SkillBuildTool;
|
|
6344
|
+
var init_skill_builder = __esm({
|
|
6345
|
+
"packages/execution/dist/tools/skill-builder.js"() {
|
|
6346
|
+
"use strict";
|
|
6347
|
+
SkillBuildTool = class {
|
|
6348
|
+
name = "skill_build";
|
|
6349
|
+
description = "Generate a comprehensive SKILL.md from a simple skill request. Takes a natural language description (e.g. 'learn to write pytest fixtures') and expands it into a structured skill definition with triggers, behaviors, verification steps, and compaction hints. The skill is saved to .oa/skills/ for immediate use with skill_execute.";
|
|
6350
|
+
parameters = {
|
|
6351
|
+
type: "object",
|
|
6352
|
+
properties: {
|
|
6353
|
+
skill_request: {
|
|
6354
|
+
type: "string",
|
|
6355
|
+
description: "Natural language description of the skill to build (e.g. 'write Rust unit tests', 'debug Kubernetes pods', 'optimize SQL queries')"
|
|
6356
|
+
},
|
|
6357
|
+
target_dir: {
|
|
6358
|
+
type: "string",
|
|
6359
|
+
description: "Optional: directory to save the skill. Defaults to .oa/skills/ in the project root. Can also be .aiwg/skills/ for AIWG-compatible deployment."
|
|
6360
|
+
},
|
|
6361
|
+
validate: {
|
|
6362
|
+
type: "boolean",
|
|
6363
|
+
description: "Whether to run the validation phase (default: true). Validation scores the generated skill and suggests improvements."
|
|
6364
|
+
}
|
|
6365
|
+
},
|
|
6366
|
+
required: ["skill_request"]
|
|
6367
|
+
};
|
|
6368
|
+
repoRoot;
|
|
6369
|
+
llmCall;
|
|
6370
|
+
constructor(repoRoot, llmCall) {
|
|
6371
|
+
this.repoRoot = repoRoot;
|
|
6372
|
+
this.llmCall = llmCall;
|
|
6373
|
+
}
|
|
6374
|
+
async execute(args) {
|
|
6375
|
+
const start = performance.now();
|
|
6376
|
+
const skillRequest = String(args["skill_request"] ?? "").trim();
|
|
6377
|
+
const targetDir = String(args["target_dir"] ?? join15(this.repoRoot, ".oa", "skills"));
|
|
6378
|
+
const shouldValidate = args["validate"] !== false;
|
|
6379
|
+
if (!skillRequest) {
|
|
6380
|
+
return {
|
|
6381
|
+
success: false,
|
|
6382
|
+
output: "",
|
|
6383
|
+
error: "skill_request is required. Describe the skill you want to build.",
|
|
6384
|
+
durationMs: performance.now() - start
|
|
6385
|
+
};
|
|
6386
|
+
}
|
|
6387
|
+
try {
|
|
6388
|
+
const seed = await this.analyzeSeed(skillRequest);
|
|
6389
|
+
let skillContent = await this.expandSkill(seed);
|
|
6390
|
+
let validationInfo = "";
|
|
6391
|
+
if (shouldValidate) {
|
|
6392
|
+
const validation = await this.validateSkill(skillContent);
|
|
6393
|
+
validationInfo = `
|
|
6394
|
+
Validation: ${validation.pass ? "PASS" : "NEEDS IMPROVEMENT"} (${validation.overall.toFixed(1)}/5.0)`;
|
|
6395
|
+
if (validation.fixes.length > 0) {
|
|
6396
|
+
validationInfo += `
|
|
6397
|
+
Suggestions: ${validation.fixes.join("; ")}`;
|
|
6398
|
+
}
|
|
6399
|
+
if (!validation.pass && validation.fixes.length > 0) {
|
|
6400
|
+
skillContent = await this.refineSkill(skillContent, validation.fixes);
|
|
6401
|
+
validationInfo += "\n Applied refinement pass.";
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
const skillDir = join15(targetDir, seed.name);
|
|
6405
|
+
const skillPath = join15(skillDir, "SKILL.md");
|
|
6406
|
+
if (!existsSync12(skillDir)) {
|
|
6407
|
+
mkdirSync4(skillDir, { recursive: true });
|
|
6408
|
+
}
|
|
6409
|
+
writeFileSync4(skillPath, skillContent, "utf-8");
|
|
6410
|
+
const output = [
|
|
6411
|
+
`Skill "${seed.name}" built successfully.`,
|
|
6412
|
+
` Domain: ${seed.domain}`,
|
|
6413
|
+
` Scope: ${seed.scope}`,
|
|
6414
|
+
` Capabilities: ${seed.capabilities.length}`,
|
|
6415
|
+
` Triggers: ${seed.triggers.length}`,
|
|
6416
|
+
` Compaction: ${seed.compaction_strategy}`,
|
|
6417
|
+
` Saved to: ${skillPath}`,
|
|
6418
|
+
validationInfo,
|
|
6419
|
+
"",
|
|
6420
|
+
'Use `skill_execute` with name "' + seed.name + '" to load the skill.'
|
|
6421
|
+
].join("\n");
|
|
6422
|
+
return {
|
|
6423
|
+
success: true,
|
|
6424
|
+
output,
|
|
6425
|
+
durationMs: performance.now() - start
|
|
6426
|
+
};
|
|
6427
|
+
} catch (err) {
|
|
6428
|
+
return {
|
|
6429
|
+
success: false,
|
|
6430
|
+
output: "",
|
|
6431
|
+
error: `Skill build failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
6432
|
+
durationMs: performance.now() - start
|
|
6433
|
+
};
|
|
6434
|
+
}
|
|
6435
|
+
}
|
|
6436
|
+
// -------------------------------------------------------------------------
|
|
6437
|
+
// Phase 1: Seed Analysis
|
|
6438
|
+
// -------------------------------------------------------------------------
|
|
6439
|
+
async analyzeSeed(request) {
|
|
6440
|
+
const prompt = loadBuilderPrompt("seed-analysis.md", {
|
|
6441
|
+
skill_request: request
|
|
6442
|
+
});
|
|
6443
|
+
const response = await this.llmCall([
|
|
6444
|
+
{ role: "system", content: prompt },
|
|
6445
|
+
{ role: "user", content: `Analyze this skill request: "${request}"` }
|
|
6446
|
+
]);
|
|
6447
|
+
const jsonStr = extractJSON(response);
|
|
6448
|
+
const seed = JSON.parse(jsonStr);
|
|
6449
|
+
if (!seed.name || !seed.description || !seed.capabilities?.length) {
|
|
6450
|
+
throw new Error("Seed analysis produced incomplete result \u2014 missing name, description, or capabilities");
|
|
6451
|
+
}
|
|
6452
|
+
seed.name = seed.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
6453
|
+
return seed;
|
|
6454
|
+
}
|
|
6455
|
+
// -------------------------------------------------------------------------
|
|
6456
|
+
// Phase 2: Skill Expansion
|
|
6457
|
+
// -------------------------------------------------------------------------
|
|
6458
|
+
async expandSkill(seed) {
|
|
6459
|
+
const prompt = loadBuilderPrompt("skill-expansion.md", {
|
|
6460
|
+
seed_json: JSON.stringify(seed, null, 2)
|
|
6461
|
+
});
|
|
6462
|
+
const response = await this.llmCall([
|
|
6463
|
+
{ role: "system", content: prompt },
|
|
6464
|
+
{
|
|
6465
|
+
role: "user",
|
|
6466
|
+
content: `Generate the complete SKILL.md for the "${seed.name}" skill.`
|
|
6467
|
+
}
|
|
6468
|
+
]);
|
|
6469
|
+
let content = response.trim();
|
|
6470
|
+
if (content.startsWith("```markdown")) {
|
|
6471
|
+
content = content.slice("```markdown".length).trim();
|
|
6472
|
+
} else if (content.startsWith("```")) {
|
|
6473
|
+
content = content.slice(3).trim();
|
|
6474
|
+
}
|
|
6475
|
+
if (content.endsWith("```")) {
|
|
6476
|
+
content = content.slice(0, -3).trim();
|
|
6477
|
+
}
|
|
6478
|
+
if (!content.startsWith("---")) {
|
|
6479
|
+
const frontmatter = [
|
|
6480
|
+
"---",
|
|
6481
|
+
`name: ${seed.name}`,
|
|
6482
|
+
`description: ${seed.description}`,
|
|
6483
|
+
`compaction_strategy: ${seed.compaction_strategy}`,
|
|
6484
|
+
"triggers:",
|
|
6485
|
+
...seed.triggers.map((t) => ` - "${t}"`),
|
|
6486
|
+
"---",
|
|
6487
|
+
""
|
|
6488
|
+
].join("\n");
|
|
6489
|
+
content = frontmatter + content;
|
|
6490
|
+
}
|
|
6491
|
+
return content;
|
|
6492
|
+
}
|
|
6493
|
+
// -------------------------------------------------------------------------
|
|
6494
|
+
// Phase 3: Validation
|
|
6495
|
+
// -------------------------------------------------------------------------
|
|
6496
|
+
async validateSkill(content) {
|
|
6497
|
+
const prompt = loadBuilderPrompt("skill-validation.md", {
|
|
6498
|
+
skill_content: content
|
|
6499
|
+
});
|
|
6500
|
+
try {
|
|
6501
|
+
const response = await this.llmCall([
|
|
6502
|
+
{ role: "system", content: prompt },
|
|
6503
|
+
{ role: "user", content: "Validate this SKILL.md." }
|
|
6504
|
+
]);
|
|
6505
|
+
const jsonStr = extractJSON(response);
|
|
6506
|
+
return JSON.parse(jsonStr);
|
|
6507
|
+
} catch {
|
|
6508
|
+
return {
|
|
6509
|
+
scores: { structure: 3, actionability: 3, completeness: 3, verification: 3, conciseness: 3 },
|
|
6510
|
+
overall: 3,
|
|
6511
|
+
pass: true,
|
|
6512
|
+
fixes: []
|
|
6513
|
+
};
|
|
6514
|
+
}
|
|
6515
|
+
}
|
|
6516
|
+
// -------------------------------------------------------------------------
|
|
6517
|
+
// Phase 3b: Refinement (if validation fails)
|
|
6518
|
+
// -------------------------------------------------------------------------
|
|
6519
|
+
async refineSkill(content, fixes) {
|
|
6520
|
+
const fixList = fixes.map((f, i) => `${i + 1}. ${f}`).join("\n");
|
|
6521
|
+
const response = await this.llmCall([
|
|
6522
|
+
{
|
|
6523
|
+
role: "system",
|
|
6524
|
+
content: "You are a skill definition editor. Apply the requested fixes to the SKILL.md content. Output ONLY the corrected SKILL.md content (starting with --- frontmatter). Do not explain changes or add commentary."
|
|
6525
|
+
},
|
|
6526
|
+
{
|
|
6527
|
+
role: "user",
|
|
6528
|
+
content: `Apply these fixes to the SKILL.md:
|
|
6529
|
+
|
|
6530
|
+
${fixList}
|
|
6531
|
+
|
|
6532
|
+
---
|
|
6533
|
+
|
|
6534
|
+
Current SKILL.md:
|
|
6535
|
+
|
|
6536
|
+
${content}`
|
|
6537
|
+
}
|
|
6538
|
+
]);
|
|
6539
|
+
let refined = response.trim();
|
|
6540
|
+
if (refined.startsWith("```markdown"))
|
|
6541
|
+
refined = refined.slice("```markdown".length).trim();
|
|
6542
|
+
else if (refined.startsWith("```"))
|
|
6543
|
+
refined = refined.slice(3).trim();
|
|
6544
|
+
if (refined.endsWith("```"))
|
|
6545
|
+
refined = refined.slice(0, -3).trim();
|
|
6546
|
+
return refined.startsWith("---") ? refined : content;
|
|
6547
|
+
}
|
|
6548
|
+
};
|
|
6549
|
+
}
|
|
6550
|
+
});
|
|
6551
|
+
|
|
6285
6552
|
// packages/execution/dist/tools/transcribe-tool.js
|
|
6286
|
-
import { existsSync as
|
|
6287
|
-
import { join as
|
|
6553
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readFileSync as readFileSync10, unlinkSync } from "node:fs";
|
|
6554
|
+
import { join as join16, basename as basename4, extname as extname3, resolve as resolve13 } from "node:path";
|
|
6288
6555
|
import { homedir as homedir6 } from "node:os";
|
|
6289
6556
|
import { execSync as execSync10, spawn as spawn4 } from "node:child_process";
|
|
6290
6557
|
function isTranscribable(path) {
|
|
@@ -6301,25 +6568,25 @@ async function loadTranscribeCli() {
|
|
|
6301
6568
|
timeout: 5e3,
|
|
6302
6569
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6303
6570
|
}).trim();
|
|
6304
|
-
const tcPath =
|
|
6305
|
-
if (
|
|
6571
|
+
const tcPath = join16(globalRoot, "transcribe-cli");
|
|
6572
|
+
if (existsSync13(join16(tcPath, "dist", "index.js"))) {
|
|
6306
6573
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
6307
6574
|
const req = createRequire4(import.meta.url);
|
|
6308
|
-
_tcModule = req(
|
|
6575
|
+
_tcModule = req(join16(tcPath, "dist", "index.js"));
|
|
6309
6576
|
return _tcModule;
|
|
6310
6577
|
}
|
|
6311
6578
|
} catch {
|
|
6312
6579
|
}
|
|
6313
|
-
const nvmBase =
|
|
6314
|
-
if (
|
|
6580
|
+
const nvmBase = join16(homedir6(), ".nvm", "versions", "node");
|
|
6581
|
+
if (existsSync13(nvmBase)) {
|
|
6315
6582
|
try {
|
|
6316
6583
|
const { readdirSync: readdirSync15 } = await import("node:fs");
|
|
6317
6584
|
for (const ver of readdirSync15(nvmBase)) {
|
|
6318
|
-
const tcPath =
|
|
6319
|
-
if (
|
|
6585
|
+
const tcPath = join16(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
6586
|
+
if (existsSync13(join16(tcPath, "dist", "index.js"))) {
|
|
6320
6587
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
6321
6588
|
const req = createRequire4(import.meta.url);
|
|
6322
|
-
_tcModule = req(
|
|
6589
|
+
_tcModule = req(join16(tcPath, "dist", "index.js"));
|
|
6323
6590
|
return _tcModule;
|
|
6324
6591
|
}
|
|
6325
6592
|
}
|
|
@@ -6391,7 +6658,7 @@ var init_transcribe_tool = __esm({
|
|
|
6391
6658
|
const filePath = resolve13(this.workingDir, String(args["path"] ?? ""));
|
|
6392
6659
|
const model = String(args["model"] ?? "base");
|
|
6393
6660
|
const diarize = Boolean(args["diarize"] ?? false);
|
|
6394
|
-
if (!
|
|
6661
|
+
if (!existsSync13(filePath)) {
|
|
6395
6662
|
return {
|
|
6396
6663
|
success: false,
|
|
6397
6664
|
output: "",
|
|
@@ -6418,10 +6685,10 @@ var init_transcribe_tool = __esm({
|
|
|
6418
6685
|
diarize,
|
|
6419
6686
|
wordTimestamps: false
|
|
6420
6687
|
});
|
|
6421
|
-
const transcriptDir =
|
|
6422
|
-
|
|
6423
|
-
const outFile =
|
|
6424
|
-
|
|
6688
|
+
const transcriptDir = join16(this.workingDir, ".oa", "transcripts");
|
|
6689
|
+
mkdirSync5(transcriptDir, { recursive: true });
|
|
6690
|
+
const outFile = join16(transcriptDir, `${basename4(filePath)}.txt`);
|
|
6691
|
+
writeFileSync5(outFile, result.text, "utf-8");
|
|
6425
6692
|
const lines = [
|
|
6426
6693
|
`Transcription of: ${basename4(filePath)}`,
|
|
6427
6694
|
`Model: ${model} | Language: ${result.language} | Duration: ${result.duration ? `${result.duration.toFixed(1)}s` : "unknown"}`,
|
|
@@ -6518,14 +6785,14 @@ var init_transcribe_tool = __esm({
|
|
|
6518
6785
|
durationMs: performance.now() - start
|
|
6519
6786
|
};
|
|
6520
6787
|
}
|
|
6521
|
-
const tmpDir =
|
|
6522
|
-
|
|
6788
|
+
const tmpDir = join16(this.workingDir, ".oa", "tmp");
|
|
6789
|
+
mkdirSync5(tmpDir, { recursive: true });
|
|
6523
6790
|
const urlPath = new URL(url).pathname;
|
|
6524
6791
|
let ext = extname3(urlPath).toLowerCase();
|
|
6525
6792
|
if (!ext || !AUDIO_EXTS.has(ext) && !VIDEO_EXTS.has(ext)) {
|
|
6526
6793
|
ext = ".mp3";
|
|
6527
6794
|
}
|
|
6528
|
-
const tmpFile =
|
|
6795
|
+
const tmpFile = join16(tmpDir, `download-${Date.now()}${ext}`);
|
|
6529
6796
|
try {
|
|
6530
6797
|
try {
|
|
6531
6798
|
execSync10(`curl -sL -o "${tmpFile}" "${url}"`, {
|
|
@@ -6538,7 +6805,7 @@ var init_transcribe_tool = __esm({
|
|
|
6538
6805
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6539
6806
|
});
|
|
6540
6807
|
}
|
|
6541
|
-
if (!
|
|
6808
|
+
if (!existsSync13(tmpFile)) {
|
|
6542
6809
|
return {
|
|
6543
6810
|
success: false,
|
|
6544
6811
|
output: "",
|
|
@@ -6578,7 +6845,7 @@ ${result.output}`,
|
|
|
6578
6845
|
|
|
6579
6846
|
// packages/execution/dist/tools/structured-file.js
|
|
6580
6847
|
import { writeFile as writeFile6, mkdir as mkdir3 } from "node:fs/promises";
|
|
6581
|
-
import { resolve as resolve14, dirname as
|
|
6848
|
+
import { resolve as resolve14, dirname as dirname5, extname as extname4 } from "node:path";
|
|
6582
6849
|
function jsonToCSV(data, separator = ",") {
|
|
6583
6850
|
if (!Array.isArray(data) || data.length === 0)
|
|
6584
6851
|
return "";
|
|
@@ -6693,7 +6960,7 @@ var init_structured_file = __esm({
|
|
|
6693
6960
|
}
|
|
6694
6961
|
try {
|
|
6695
6962
|
const fullPath = resolve14(this.workingDir, filePath);
|
|
6696
|
-
await mkdir3(
|
|
6963
|
+
await mkdir3(dirname5(fullPath), { recursive: true });
|
|
6697
6964
|
let content;
|
|
6698
6965
|
let byteInfo = "";
|
|
6699
6966
|
switch (format) {
|
|
@@ -6759,7 +7026,7 @@ var init_structured_file = __esm({
|
|
|
6759
7026
|
// packages/execution/dist/tools/code-sandbox.js
|
|
6760
7027
|
import { spawn as spawn5 } from "node:child_process";
|
|
6761
7028
|
import { writeFile as writeFile7, mkdtemp, rm, readdir as readdir2, stat } from "node:fs/promises";
|
|
6762
|
-
import { join as
|
|
7029
|
+
import { join as join17 } from "node:path";
|
|
6763
7030
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
6764
7031
|
function runProcess(cmd, args, options) {
|
|
6765
7032
|
return new Promise((resolve31) => {
|
|
@@ -6825,7 +7092,7 @@ async function listCreatedFiles(dir) {
|
|
|
6825
7092
|
for (const entry of entries) {
|
|
6826
7093
|
if (entry.startsWith("_sandbox_script"))
|
|
6827
7094
|
continue;
|
|
6828
|
-
const fullPath =
|
|
7095
|
+
const fullPath = join17(dir, entry);
|
|
6829
7096
|
const s = await stat(fullPath);
|
|
6830
7097
|
if (s.isFile()) {
|
|
6831
7098
|
files.push(entry);
|
|
@@ -6945,9 +7212,9 @@ ${result.filesCreated.join("\n")}`);
|
|
|
6945
7212
|
// Subprocess mode — temp directory + separate process
|
|
6946
7213
|
// -------------------------------------------------------------------------
|
|
6947
7214
|
async #runSubprocess(code, langConfig, timeoutMs, stdin) {
|
|
6948
|
-
const sandboxDir = await mkdtemp(
|
|
7215
|
+
const sandboxDir = await mkdtemp(join17(tmpdir2(), "oa-sandbox-"));
|
|
6949
7216
|
try {
|
|
6950
|
-
const scriptFile =
|
|
7217
|
+
const scriptFile = join17(sandboxDir, `_sandbox_script${langConfig.ext}`);
|
|
6951
7218
|
await writeFile7(scriptFile, code, "utf-8");
|
|
6952
7219
|
const result = await runProcess(langConfig.cmd, langConfig.args(scriptFile), {
|
|
6953
7220
|
cwd: sandboxDir,
|
|
@@ -6972,10 +7239,10 @@ ${result.filesCreated.join("\n")}`);
|
|
|
6972
7239
|
bash: "bash:5"
|
|
6973
7240
|
};
|
|
6974
7241
|
const image = images[language] ?? "node:22-slim";
|
|
6975
|
-
const sandboxDir = await mkdtemp(
|
|
7242
|
+
const sandboxDir = await mkdtemp(join17(tmpdir2(), "oa-docker-sandbox-"));
|
|
6976
7243
|
try {
|
|
6977
7244
|
const scriptFile = `_sandbox_script${langConfig.ext}`;
|
|
6978
|
-
await writeFile7(
|
|
7245
|
+
await writeFile7(join17(sandboxDir, scriptFile), code, "utf-8");
|
|
6979
7246
|
const dockerArgs = [
|
|
6980
7247
|
"run",
|
|
6981
7248
|
"--rm",
|
|
@@ -7345,9 +7612,9 @@ ${parts.join("\n\n")}`,
|
|
|
7345
7612
|
});
|
|
7346
7613
|
|
|
7347
7614
|
// packages/execution/dist/tools/vision.js
|
|
7348
|
-
import { readFileSync as
|
|
7615
|
+
import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
|
|
7349
7616
|
import { execSync as execSync11, spawn as spawn6 } from "node:child_process";
|
|
7350
|
-
import { resolve as resolve16, extname as extname6, basename as basename5, dirname as
|
|
7617
|
+
import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join18 } from "node:path";
|
|
7351
7618
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7352
7619
|
async function probeStation(endpoint) {
|
|
7353
7620
|
try {
|
|
@@ -7362,24 +7629,24 @@ async function probeStation(endpoint) {
|
|
|
7362
7629
|
}
|
|
7363
7630
|
}
|
|
7364
7631
|
function findStationBinary() {
|
|
7365
|
-
const oaVenvPython =
|
|
7366
|
-
if (
|
|
7632
|
+
const oaVenvPython = join18(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
|
|
7633
|
+
if (existsSync14(oaVenvPython)) {
|
|
7367
7634
|
try {
|
|
7368
7635
|
execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
|
|
7369
7636
|
return oaVenvPython;
|
|
7370
7637
|
} catch {
|
|
7371
7638
|
}
|
|
7372
7639
|
}
|
|
7373
|
-
const oaVenvBin =
|
|
7374
|
-
if (
|
|
7640
|
+
const oaVenvBin = join18(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
|
|
7641
|
+
if (existsSync14(oaVenvBin))
|
|
7375
7642
|
return oaVenvBin;
|
|
7376
|
-
const thisDir =
|
|
7643
|
+
const thisDir = dirname6(fileURLToPath2(import.meta.url));
|
|
7377
7644
|
const localVenvPaths = [
|
|
7378
7645
|
resolve16(thisDir, "../../../../.moondream-venv/bin/python"),
|
|
7379
7646
|
resolve16(thisDir, "../../../.moondream-venv/bin/python")
|
|
7380
7647
|
];
|
|
7381
7648
|
for (const p of localVenvPaths) {
|
|
7382
|
-
if (
|
|
7649
|
+
if (existsSync14(p)) {
|
|
7383
7650
|
try {
|
|
7384
7651
|
execSync11(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
|
|
7385
7652
|
return p;
|
|
@@ -7399,9 +7666,9 @@ async function autoLaunchStation(port = 2020) {
|
|
|
7399
7666
|
const pythonBin = findStationBinary();
|
|
7400
7667
|
if (!pythonBin)
|
|
7401
7668
|
return false;
|
|
7402
|
-
const thisDir =
|
|
7669
|
+
const thisDir = dirname6(fileURLToPath2(import.meta.url));
|
|
7403
7670
|
const launcherScript = resolve16(thisDir, "../../scripts/start-moondream.py");
|
|
7404
|
-
if (!
|
|
7671
|
+
if (!existsSync14(launcherScript))
|
|
7405
7672
|
return false;
|
|
7406
7673
|
return new Promise((resolvePromise) => {
|
|
7407
7674
|
const child = spawn6(pythonBin, [launcherScript, "--port", String(port)], {
|
|
@@ -7476,7 +7743,7 @@ Details: ${err.message}` : "");
|
|
|
7476
7743
|
}
|
|
7477
7744
|
function loadImageBuffer(workingDir, rawPath) {
|
|
7478
7745
|
const fullPath = resolve16(workingDir, rawPath);
|
|
7479
|
-
if (!
|
|
7746
|
+
if (!existsSync14(fullPath)) {
|
|
7480
7747
|
throw new Error(`File not found: ${rawPath}`);
|
|
7481
7748
|
}
|
|
7482
7749
|
const stat5 = statSync5(fullPath);
|
|
@@ -7487,7 +7754,7 @@ function loadImageBuffer(workingDir, rawPath) {
|
|
|
7487
7754
|
if (!IMAGE_EXTENSIONS2.has(ext)) {
|
|
7488
7755
|
throw new Error(`Not a supported image format: ${ext}. Supported: ${[...IMAGE_EXTENSIONS2].join(", ")}`);
|
|
7489
7756
|
}
|
|
7490
|
-
return { buffer:
|
|
7757
|
+
return { buffer: readFileSync11(fullPath), fullPath };
|
|
7491
7758
|
}
|
|
7492
7759
|
var moondreamClient, moondreamError, stationProcess, IMAGE_EXTENSIONS2, VisionTool;
|
|
7493
7760
|
var init_vision = __esm({
|
|
@@ -7715,10 +7982,10 @@ ${response}`, durationMs: performance.now() - start };
|
|
|
7715
7982
|
});
|
|
7716
7983
|
|
|
7717
7984
|
// packages/execution/dist/tools/desktop-click.js
|
|
7718
|
-
import { readFileSync as
|
|
7985
|
+
import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
|
|
7719
7986
|
import { execSync as execSync12 } from "node:child_process";
|
|
7720
7987
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
7721
|
-
import { join as
|
|
7988
|
+
import { join as join19, dirname as dirname7 } from "node:path";
|
|
7722
7989
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
7723
7990
|
function hasCommand2(cmd) {
|
|
7724
7991
|
try {
|
|
@@ -7780,7 +8047,7 @@ function captureScreenshot(outputPath) {
|
|
|
7780
8047
|
} else {
|
|
7781
8048
|
try {
|
|
7782
8049
|
execSync12(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
|
|
7783
|
-
if (
|
|
8050
|
+
if (existsSync15(outputPath))
|
|
7784
8051
|
return;
|
|
7785
8052
|
} catch {
|
|
7786
8053
|
}
|
|
@@ -7791,7 +8058,7 @@ function captureScreenshot(outputPath) {
|
|
|
7791
8058
|
throw new Error("No screenshot tool found. Auto-install failed. Try manually: sudo apt install scrot");
|
|
7792
8059
|
}
|
|
7793
8060
|
execSync12(cmd, { stdio: "pipe", timeout: 1e4 });
|
|
7794
|
-
if (!
|
|
8061
|
+
if (!existsSync15(outputPath)) {
|
|
7795
8062
|
throw new Error("Screenshot file was not created");
|
|
7796
8063
|
}
|
|
7797
8064
|
}
|
|
@@ -7842,7 +8109,7 @@ for i in range(${clicks}):
|
|
|
7842
8109
|
} catch {
|
|
7843
8110
|
}
|
|
7844
8111
|
try {
|
|
7845
|
-
const venvPy =
|
|
8112
|
+
const venvPy = join19(__dirname2, "../../../../.moondream-venv/bin/python");
|
|
7846
8113
|
execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
|
|
7847
8114
|
return;
|
|
7848
8115
|
} catch {
|
|
@@ -7865,12 +8132,12 @@ for i in range(${clicks}):
|
|
|
7865
8132
|
throw new Error(`Desktop click not supported on platform: ${plat}`);
|
|
7866
8133
|
}
|
|
7867
8134
|
}
|
|
7868
|
-
var
|
|
8135
|
+
var __dirname2, DesktopClickTool, DesktopDescribeTool;
|
|
7869
8136
|
var init_desktop_click = __esm({
|
|
7870
8137
|
"packages/execution/dist/tools/desktop-click.js"() {
|
|
7871
8138
|
"use strict";
|
|
7872
8139
|
init_system_deps();
|
|
7873
|
-
|
|
8140
|
+
__dirname2 = dirname7(fileURLToPath3(import.meta.url));
|
|
7874
8141
|
DesktopClickTool = class {
|
|
7875
8142
|
workingDir;
|
|
7876
8143
|
name = "desktop_click";
|
|
@@ -7934,7 +8201,7 @@ var init_desktop_click = __esm({
|
|
|
7934
8201
|
if (delayMs > 0) {
|
|
7935
8202
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
7936
8203
|
}
|
|
7937
|
-
const screenshotPath =
|
|
8204
|
+
const screenshotPath = join19(tmpdir3(), `oa-desktop-click-${Date.now()}.png`);
|
|
7938
8205
|
captureScreenshot(screenshotPath);
|
|
7939
8206
|
const dims = getImageDimensions2(screenshotPath);
|
|
7940
8207
|
if (!dims) {
|
|
@@ -7959,7 +8226,7 @@ var init_desktop_click = __esm({
|
|
|
7959
8226
|
} else {
|
|
7960
8227
|
client = new vl({ endpoint: "http://localhost:2020/v1" });
|
|
7961
8228
|
}
|
|
7962
|
-
const imageBuffer =
|
|
8229
|
+
const imageBuffer = readFileSync12(screenshotPath);
|
|
7963
8230
|
const pointResult = await client.point({ image: imageBuffer, object: target });
|
|
7964
8231
|
points = pointResult.points ?? [];
|
|
7965
8232
|
visionWorked = true;
|
|
@@ -7970,7 +8237,7 @@ var init_desktop_click = __esm({
|
|
|
7970
8237
|
const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
7971
8238
|
const envModel = process.env["OLLAMA_VISION_MODEL"];
|
|
7972
8239
|
const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
7973
|
-
const imageBase64 =
|
|
8240
|
+
const imageBase64 = readFileSync12(screenshotPath).toString("base64");
|
|
7974
8241
|
const res = await fetch(`${ollamaHost}/api/generate`, {
|
|
7975
8242
|
method: "POST",
|
|
7976
8243
|
headers: { "Content-Type": "application/json" },
|
|
@@ -8109,10 +8376,10 @@ Screenshot: ${screenshotPath}`,
|
|
|
8109
8376
|
if (delayMs > 0) {
|
|
8110
8377
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
8111
8378
|
}
|
|
8112
|
-
const screenshotPath =
|
|
8379
|
+
const screenshotPath = join19(tmpdir3(), `oa-desktop-describe-${Date.now()}.png`);
|
|
8113
8380
|
captureScreenshot(screenshotPath);
|
|
8114
8381
|
const dims = getImageDimensions2(screenshotPath);
|
|
8115
|
-
const imageBuffer =
|
|
8382
|
+
const imageBuffer = readFileSync12(screenshotPath);
|
|
8116
8383
|
const parts = [];
|
|
8117
8384
|
let visionWorked = false;
|
|
8118
8385
|
try {
|
|
@@ -8224,7 +8491,7 @@ Screen: ${dims.width}x${dims.height}`);
|
|
|
8224
8491
|
});
|
|
8225
8492
|
|
|
8226
8493
|
// packages/execution/dist/tools/ocr-pdf.js
|
|
8227
|
-
import { existsSync as
|
|
8494
|
+
import { existsSync as existsSync16, statSync as statSync6 } from "node:fs";
|
|
8228
8495
|
import { resolve as resolve17, basename as basename6 } from "node:path";
|
|
8229
8496
|
import { execSync as execSync13 } from "node:child_process";
|
|
8230
8497
|
var OcrPdfTool;
|
|
@@ -8276,7 +8543,7 @@ var init_ocr_pdf = __esm({
|
|
|
8276
8543
|
return { success: false, output: "", error: "input path is required", durationMs: 0 };
|
|
8277
8544
|
}
|
|
8278
8545
|
const inputPath = resolve17(this.workingDir, rawInput);
|
|
8279
|
-
if (!
|
|
8546
|
+
if (!existsSync16(inputPath)) {
|
|
8280
8547
|
return { success: false, output: "", error: `File not found: ${rawInput}`, durationMs: performance.now() - start };
|
|
8281
8548
|
}
|
|
8282
8549
|
const stat5 = statSync6(inputPath);
|
|
@@ -8347,8 +8614,8 @@ Language: ${language}
|
|
|
8347
8614
|
});
|
|
8348
8615
|
|
|
8349
8616
|
// packages/execution/dist/tools/pdf-to-text.js
|
|
8350
|
-
import { existsSync as
|
|
8351
|
-
import { resolve as resolve18, basename as basename7, join as
|
|
8617
|
+
import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
8618
|
+
import { resolve as resolve18, basename as basename7, join as join20 } from "node:path";
|
|
8352
8619
|
import { execSync as execSync14 } from "node:child_process";
|
|
8353
8620
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
8354
8621
|
var PdfToTextTool;
|
|
@@ -8400,7 +8667,7 @@ var init_pdf_to_text = __esm({
|
|
|
8400
8667
|
return { success: false, output: "", error: "path is required", durationMs: 0 };
|
|
8401
8668
|
}
|
|
8402
8669
|
const fullPath = resolve18(this.workingDir, rawPath);
|
|
8403
|
-
if (!
|
|
8670
|
+
if (!existsSync17(fullPath)) {
|
|
8404
8671
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: performance.now() - start };
|
|
8405
8672
|
}
|
|
8406
8673
|
const fileStat = statSync7(fullPath);
|
|
@@ -8502,7 +8769,7 @@ ${text}`,
|
|
|
8502
8769
|
if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
|
|
8503
8770
|
return null;
|
|
8504
8771
|
}
|
|
8505
|
-
const tmpPdf =
|
|
8772
|
+
const tmpPdf = join20(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
|
|
8506
8773
|
try {
|
|
8507
8774
|
const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
|
|
8508
8775
|
execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
|
|
@@ -8532,27 +8799,27 @@ ${text}`,
|
|
|
8532
8799
|
});
|
|
8533
8800
|
|
|
8534
8801
|
// packages/execution/dist/tools/ocr-image-advanced.js
|
|
8535
|
-
import { existsSync as
|
|
8536
|
-
import { resolve as resolve19, basename as basename8, dirname as
|
|
8802
|
+
import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
|
|
8803
|
+
import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join21 } from "node:path";
|
|
8537
8804
|
import { execSync as execSync15 } from "node:child_process";
|
|
8538
8805
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
8539
8806
|
import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
|
|
8540
8807
|
function findOcrScript() {
|
|
8541
|
-
const thisDir =
|
|
8808
|
+
const thisDir = dirname8(fileURLToPath4(import.meta.url));
|
|
8542
8809
|
const devPath3 = resolve19(thisDir, "../../scripts/ocr-advanced.py");
|
|
8543
|
-
if (
|
|
8810
|
+
if (existsSync18(devPath3))
|
|
8544
8811
|
return devPath3;
|
|
8545
8812
|
const bundledPath = resolve19(thisDir, "../scripts/ocr-advanced.py");
|
|
8546
|
-
if (
|
|
8813
|
+
if (existsSync18(bundledPath))
|
|
8547
8814
|
return bundledPath;
|
|
8548
8815
|
const sameDirPath = resolve19(thisDir, "ocr-advanced.py");
|
|
8549
|
-
if (
|
|
8816
|
+
if (existsSync18(sameDirPath))
|
|
8550
8817
|
return sameDirPath;
|
|
8551
8818
|
return null;
|
|
8552
8819
|
}
|
|
8553
8820
|
function findPython() {
|
|
8554
|
-
const venvPython =
|
|
8555
|
-
if (
|
|
8821
|
+
const venvPython = join21(homedir7(), ".open-agents", "venv", "bin", "python");
|
|
8822
|
+
if (existsSync18(venvPython)) {
|
|
8556
8823
|
try {
|
|
8557
8824
|
execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
|
|
8558
8825
|
stdio: "pipe",
|
|
@@ -8636,7 +8903,7 @@ var init_ocr_image_advanced = __esm({
|
|
|
8636
8903
|
return { success: false, output: "", error: "image path is required", durationMs: 0 };
|
|
8637
8904
|
}
|
|
8638
8905
|
const fullPath = resolve19(this.workingDir, rawPath);
|
|
8639
|
-
if (!
|
|
8906
|
+
if (!existsSync18(fullPath)) {
|
|
8640
8907
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: performance.now() - start };
|
|
8641
8908
|
}
|
|
8642
8909
|
if (!batch) {
|
|
@@ -8697,7 +8964,7 @@ var init_ocr_image_advanced = __esm({
|
|
|
8697
8964
|
cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
|
|
8698
8965
|
let debugDir;
|
|
8699
8966
|
if (debug) {
|
|
8700
|
-
debugDir =
|
|
8967
|
+
debugDir = join21(tmpdir5(), `oa-ocr-debug-${Date.now()}`);
|
|
8701
8968
|
cmdParts.push("--debug-dir", debugDir);
|
|
8702
8969
|
}
|
|
8703
8970
|
try {
|
|
@@ -8796,7 +9063,7 @@ var init_ocr_image_advanced = __esm({
|
|
|
8796
9063
|
if (region) {
|
|
8797
9064
|
try {
|
|
8798
9065
|
const [x, y, w, h] = region.split(",").map(Number);
|
|
8799
|
-
const croppedPath =
|
|
9066
|
+
const croppedPath = join21(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
|
|
8800
9067
|
execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
|
|
8801
9068
|
inputPath = croppedPath;
|
|
8802
9069
|
} catch {
|
|
@@ -8836,8 +9103,8 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
|
|
|
8836
9103
|
|
|
8837
9104
|
// packages/execution/dist/tools/browser-action.js
|
|
8838
9105
|
import { execSync as execSync16, spawn as spawn7 } from "node:child_process";
|
|
8839
|
-
import { existsSync as
|
|
8840
|
-
import { join as
|
|
9106
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
|
|
9107
|
+
import { join as join22, dirname as dirname9 } from "node:path";
|
|
8841
9108
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
8842
9109
|
async function probeService() {
|
|
8843
9110
|
try {
|
|
@@ -8867,7 +9134,7 @@ async function launchService() {
|
|
|
8867
9134
|
const python = findPython2();
|
|
8868
9135
|
if (!python)
|
|
8869
9136
|
return "Python 3 not found. Install Python 3.9+ to use browser automation.";
|
|
8870
|
-
if (!
|
|
9137
|
+
if (!existsSync19(SCRAPE_SCRIPT)) {
|
|
8871
9138
|
return `Scrape service script not found at ${SCRAPE_SCRIPT}`;
|
|
8872
9139
|
}
|
|
8873
9140
|
serviceProcess = spawn7(python, [SCRAPE_SCRIPT], {
|
|
@@ -8924,12 +9191,12 @@ async function apiCall(endpoint, method = "POST", body) {
|
|
|
8924
9191
|
const res = await fetch(url, options);
|
|
8925
9192
|
return await res.json();
|
|
8926
9193
|
}
|
|
8927
|
-
var
|
|
9194
|
+
var __dirname3, SCRAPE_SCRIPT, DEFAULT_PORT, BASE_URL, serviceProcess, activeSessionId, BrowserActionTool;
|
|
8928
9195
|
var init_browser_action = __esm({
|
|
8929
9196
|
"packages/execution/dist/tools/browser-action.js"() {
|
|
8930
9197
|
"use strict";
|
|
8931
|
-
|
|
8932
|
-
SCRAPE_SCRIPT =
|
|
9198
|
+
__dirname3 = dirname9(fileURLToPath5(import.meta.url));
|
|
9199
|
+
SCRAPE_SCRIPT = join22(__dirname3, "..", "..", "scripts", "web_scrape.py");
|
|
8933
9200
|
DEFAULT_PORT = 8130;
|
|
8934
9201
|
BASE_URL = `http://localhost:${DEFAULT_PORT}`;
|
|
8935
9202
|
serviceProcess = null;
|
|
@@ -9089,19 +9356,19 @@ var init_browser_action = __esm({
|
|
|
9089
9356
|
|
|
9090
9357
|
// packages/execution/dist/tools/autoresearch.js
|
|
9091
9358
|
import { execSync as execSync17, spawn as spawn8 } from "node:child_process";
|
|
9092
|
-
import { existsSync as
|
|
9093
|
-
import { join as
|
|
9359
|
+
import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
|
|
9360
|
+
import { join as join23, resolve as resolve20, dirname as dirname10 } from "node:path";
|
|
9094
9361
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
9095
9362
|
function findAutoresearchScript(scriptName) {
|
|
9096
|
-
const thisDir =
|
|
9363
|
+
const thisDir = dirname10(fileURLToPath6(import.meta.url));
|
|
9097
9364
|
const devPath3 = resolve20(thisDir, "../../scripts", scriptName);
|
|
9098
|
-
if (
|
|
9365
|
+
if (existsSync20(devPath3))
|
|
9099
9366
|
return devPath3;
|
|
9100
9367
|
const bundledPath = resolve20(thisDir, "../scripts", scriptName);
|
|
9101
|
-
if (
|
|
9368
|
+
if (existsSync20(bundledPath))
|
|
9102
9369
|
return bundledPath;
|
|
9103
9370
|
const sameDirPath = resolve20(thisDir, scriptName);
|
|
9104
|
-
if (
|
|
9371
|
+
if (existsSync20(sameDirPath))
|
|
9105
9372
|
return sameDirPath;
|
|
9106
9373
|
return null;
|
|
9107
9374
|
}
|
|
@@ -9192,7 +9459,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
|
|
|
9192
9459
|
async execute(args) {
|
|
9193
9460
|
const start = Date.now();
|
|
9194
9461
|
const action = String(args["action"] ?? "status");
|
|
9195
|
-
const workspacePath = String(args["workspace"] ??
|
|
9462
|
+
const workspacePath = String(args["workspace"] ?? join23(this.repoRoot, ".oa", "autoresearch"));
|
|
9196
9463
|
try {
|
|
9197
9464
|
switch (action) {
|
|
9198
9465
|
case "setup":
|
|
@@ -9229,17 +9496,17 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
|
|
|
9229
9496
|
} catch {
|
|
9230
9497
|
output.push("GPU: detection failed (nvidia-smi not available)");
|
|
9231
9498
|
}
|
|
9232
|
-
|
|
9499
|
+
mkdirSync6(workspace, { recursive: true });
|
|
9233
9500
|
const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
|
|
9234
9501
|
const trainScript = findAutoresearchScript("autoresearch-train.py");
|
|
9235
9502
|
if (prepareScript) {
|
|
9236
|
-
copyFileSync(prepareScript,
|
|
9503
|
+
copyFileSync(prepareScript, join23(workspace, "prepare.py"));
|
|
9237
9504
|
output.push("Copied prepare.py template");
|
|
9238
9505
|
} else {
|
|
9239
9506
|
return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
|
|
9240
9507
|
}
|
|
9241
9508
|
if (trainScript) {
|
|
9242
|
-
copyFileSync(trainScript,
|
|
9509
|
+
copyFileSync(trainScript, join23(workspace, "train.py"));
|
|
9243
9510
|
output.push("Copied train.py template");
|
|
9244
9511
|
} else {
|
|
9245
9512
|
return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
|
|
@@ -9271,7 +9538,7 @@ name = "pytorch-cu128"
|
|
|
9271
9538
|
url = "https://download.pytorch.org/whl/cu128"
|
|
9272
9539
|
explicit = true
|
|
9273
9540
|
`;
|
|
9274
|
-
|
|
9541
|
+
writeFileSync6(join23(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
|
|
9275
9542
|
output.push("Created pyproject.toml");
|
|
9276
9543
|
try {
|
|
9277
9544
|
execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
@@ -9313,9 +9580,9 @@ explicit = true
|
|
|
9313
9580
|
const e = err;
|
|
9314
9581
|
output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
|
|
9315
9582
|
}
|
|
9316
|
-
const tsvPath =
|
|
9317
|
-
if (!
|
|
9318
|
-
|
|
9583
|
+
const tsvPath = join23(workspace, "results.tsv");
|
|
9584
|
+
if (!existsSync20(tsvPath)) {
|
|
9585
|
+
writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
|
|
9319
9586
|
output.push("Created results.tsv");
|
|
9320
9587
|
}
|
|
9321
9588
|
return {
|
|
@@ -9335,10 +9602,10 @@ Next steps:
|
|
|
9335
9602
|
}
|
|
9336
9603
|
// ── Run experiment ─────────────────────────────────────────────────────
|
|
9337
9604
|
async run(workspace, args, start) {
|
|
9338
|
-
if (!
|
|
9605
|
+
if (!existsSync20(join23(workspace, "train.py"))) {
|
|
9339
9606
|
return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9340
9607
|
}
|
|
9341
|
-
if (!
|
|
9608
|
+
if (!existsSync20(join23(workspace, ".venv")) && existsSync20(join23(workspace, "pyproject.toml"))) {
|
|
9342
9609
|
try {
|
|
9343
9610
|
execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
|
|
9344
9611
|
} catch {
|
|
@@ -9346,7 +9613,7 @@ Next steps:
|
|
|
9346
9613
|
}
|
|
9347
9614
|
const timeoutMin = Number(args["timeout_minutes"] ?? 10);
|
|
9348
9615
|
const timeoutMs = timeoutMin * 60 * 1e3;
|
|
9349
|
-
const logPath =
|
|
9616
|
+
const logPath = join23(workspace, "run.log");
|
|
9350
9617
|
return new Promise((resolveResult) => {
|
|
9351
9618
|
const proc = spawn8("uv", ["run", "train.py"], {
|
|
9352
9619
|
cwd: workspace,
|
|
@@ -9377,7 +9644,7 @@ Next steps:
|
|
|
9377
9644
|
clearTimeout(timer);
|
|
9378
9645
|
const fullLog = stdout + "\n" + stderr;
|
|
9379
9646
|
try {
|
|
9380
|
-
|
|
9647
|
+
writeFileSync6(logPath, fullLog, "utf-8");
|
|
9381
9648
|
} catch {
|
|
9382
9649
|
}
|
|
9383
9650
|
if (timedOut) {
|
|
@@ -9417,7 +9684,7 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9417
9684
|
return;
|
|
9418
9685
|
}
|
|
9419
9686
|
try {
|
|
9420
|
-
|
|
9687
|
+
writeFileSync6(join23(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
|
|
9421
9688
|
} catch {
|
|
9422
9689
|
}
|
|
9423
9690
|
const memGB = (result.peak_vram_mb / 1024).toFixed(1);
|
|
@@ -9453,11 +9720,11 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9453
9720
|
}
|
|
9454
9721
|
// ── Results ────────────────────────────────────────────────────────────
|
|
9455
9722
|
getResults(workspace, start) {
|
|
9456
|
-
const tsvPath =
|
|
9457
|
-
if (!
|
|
9723
|
+
const tsvPath = join23(workspace, "results.tsv");
|
|
9724
|
+
if (!existsSync20(tsvPath)) {
|
|
9458
9725
|
return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9459
9726
|
}
|
|
9460
|
-
const content =
|
|
9727
|
+
const content = readFileSync15(tsvPath, "utf-8");
|
|
9461
9728
|
const lines = content.trim().split("\n");
|
|
9462
9729
|
if (lines.length <= 1) {
|
|
9463
9730
|
return { success: true, output: 'No experiments recorded yet. Run autoresearch(action="run") to start.', durationMs: Date.now() - start };
|
|
@@ -9480,7 +9747,7 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9480
9747
|
// ── Status ─────────────────────────────────────────────────────────────
|
|
9481
9748
|
getStatus(workspace, start) {
|
|
9482
9749
|
const output = [];
|
|
9483
|
-
if (!
|
|
9750
|
+
if (!existsSync20(join23(workspace, "train.py"))) {
|
|
9484
9751
|
return {
|
|
9485
9752
|
success: true,
|
|
9486
9753
|
output: `Autoresearch workspace not initialized at ${workspace}.
|
|
@@ -9503,33 +9770,33 @@ Run autoresearch(action="setup") to begin.`,
|
|
|
9503
9770
|
} catch {
|
|
9504
9771
|
output.push("GPU: not detected");
|
|
9505
9772
|
}
|
|
9506
|
-
const lastResultPath =
|
|
9507
|
-
if (
|
|
9773
|
+
const lastResultPath = join23(workspace, ".last-result.json");
|
|
9774
|
+
if (existsSync20(lastResultPath)) {
|
|
9508
9775
|
try {
|
|
9509
|
-
const last = JSON.parse(
|
|
9776
|
+
const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
|
|
9510
9777
|
output.push(`Last experiment: val_bpb=${last.val_bpb.toFixed(6)}, ${(last.peak_vram_mb / 1024).toFixed(1)}GB VRAM, ${last.num_params_M.toFixed(1)}M params`);
|
|
9511
9778
|
} catch {
|
|
9512
9779
|
}
|
|
9513
9780
|
}
|
|
9514
|
-
const tsvPath =
|
|
9515
|
-
if (
|
|
9516
|
-
const lines =
|
|
9781
|
+
const tsvPath = join23(workspace, "results.tsv");
|
|
9782
|
+
if (existsSync20(tsvPath)) {
|
|
9783
|
+
const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
|
|
9517
9784
|
output.push(`Experiments recorded: ${lines.length - 1}`);
|
|
9518
9785
|
}
|
|
9519
|
-
const cacheDir =
|
|
9520
|
-
output.push(`Data cache: ${
|
|
9786
|
+
const cacheDir = join23(process.env["HOME"] ?? "~", ".cache", "autoresearch");
|
|
9787
|
+
output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
|
|
9521
9788
|
return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
|
|
9522
9789
|
}
|
|
9523
9790
|
// ── Keep / Discard ─────────────────────────────────────────────────────
|
|
9524
9791
|
keepExperiment(workspace, args, start) {
|
|
9525
9792
|
const desc = String(args["description"] ?? "experiment");
|
|
9526
|
-
const tsvPath =
|
|
9527
|
-
const lastResultPath =
|
|
9793
|
+
const tsvPath = join23(workspace, "results.tsv");
|
|
9794
|
+
const lastResultPath = join23(workspace, ".last-result.json");
|
|
9528
9795
|
let valBpb = args["val_bpb"];
|
|
9529
9796
|
let memGb = args["memory_gb"];
|
|
9530
|
-
if ((valBpb === void 0 || memGb === void 0) &&
|
|
9797
|
+
if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
|
|
9531
9798
|
try {
|
|
9532
|
-
const last = JSON.parse(
|
|
9799
|
+
const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
|
|
9533
9800
|
if (valBpb === void 0)
|
|
9534
9801
|
valBpb = last.val_bpb;
|
|
9535
9802
|
if (memGb === void 0)
|
|
@@ -9562,13 +9829,13 @@ Branch advanced. Ready for next experiment.`,
|
|
|
9562
9829
|
}
|
|
9563
9830
|
discardExperiment(workspace, args, start) {
|
|
9564
9831
|
const desc = String(args["description"] ?? "experiment");
|
|
9565
|
-
const tsvPath =
|
|
9566
|
-
const lastResultPath =
|
|
9832
|
+
const tsvPath = join23(workspace, "results.tsv");
|
|
9833
|
+
const lastResultPath = join23(workspace, ".last-result.json");
|
|
9567
9834
|
let valBpb = args["val_bpb"];
|
|
9568
9835
|
let memGb = args["memory_gb"];
|
|
9569
|
-
if ((valBpb === void 0 || memGb === void 0) &&
|
|
9836
|
+
if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
|
|
9570
9837
|
try {
|
|
9571
|
-
const last = JSON.parse(
|
|
9838
|
+
const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
|
|
9572
9839
|
if (valBpb === void 0)
|
|
9573
9840
|
valBpb = last.val_bpb;
|
|
9574
9841
|
if (memGb === void 0)
|
|
@@ -9610,7 +9877,7 @@ train.py reverted to last kept state. Ready for next experiment.`,
|
|
|
9610
9877
|
// packages/execution/dist/tools/scheduler.js
|
|
9611
9878
|
import { execSync as execSync18, exec as execCb } from "node:child_process";
|
|
9612
9879
|
import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
|
|
9613
|
-
import { resolve as resolve21, join as
|
|
9880
|
+
import { resolve as resolve21, join as join24 } from "node:path";
|
|
9614
9881
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
9615
9882
|
function isValidCron(expr) {
|
|
9616
9883
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -9694,7 +9961,7 @@ function installCronJob(task, workingDir) {
|
|
|
9694
9961
|
const lines = getCurrentCrontab();
|
|
9695
9962
|
const oaBin = findOaBinary();
|
|
9696
9963
|
const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
|
|
9697
|
-
const logFile =
|
|
9964
|
+
const logFile = join24(logDir, `${task.id}.log`);
|
|
9698
9965
|
const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
|
|
9699
9966
|
const taskEscaped = task.task.replace(/'/g, "'\\''");
|
|
9700
9967
|
const taskId = task.id;
|
|
@@ -9736,9 +10003,9 @@ async function loadStore(workingDir) {
|
|
|
9736
10003
|
async function saveStore(workingDir, store) {
|
|
9737
10004
|
const dir = resolve21(workingDir, ".oa", "scheduled");
|
|
9738
10005
|
await mkdir4(dir, { recursive: true });
|
|
9739
|
-
await mkdir4(
|
|
10006
|
+
await mkdir4(join24(dir, "logs"), { recursive: true });
|
|
9740
10007
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9741
|
-
await writeFile8(
|
|
10008
|
+
await writeFile8(join24(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
9742
10009
|
}
|
|
9743
10010
|
var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
|
|
9744
10011
|
var init_scheduler = __esm({
|
|
@@ -9972,7 +10239,7 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
9972
10239
|
|
|
9973
10240
|
// packages/execution/dist/tools/reminder.js
|
|
9974
10241
|
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
|
|
9975
|
-
import { resolve as resolve22, join as
|
|
10242
|
+
import { resolve as resolve22, join as join25 } from "node:path";
|
|
9976
10243
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
9977
10244
|
function parseDueTime(due) {
|
|
9978
10245
|
const lower = due.toLowerCase().trim();
|
|
@@ -10024,7 +10291,7 @@ function parseDueTime(due) {
|
|
|
10024
10291
|
async function getStorePath(workingDir) {
|
|
10025
10292
|
const dir = resolve22(workingDir, ".oa", "scheduled");
|
|
10026
10293
|
await mkdir5(dir, { recursive: true });
|
|
10027
|
-
return
|
|
10294
|
+
return join25(dir, STORE_FILE);
|
|
10028
10295
|
}
|
|
10029
10296
|
async function loadReminderStore(workingDir) {
|
|
10030
10297
|
const storePath = await getStorePath(workingDir);
|
|
@@ -10285,7 +10552,7 @@ var init_reminder = __esm({
|
|
|
10285
10552
|
|
|
10286
10553
|
// packages/execution/dist/tools/agenda.js
|
|
10287
10554
|
import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
|
|
10288
|
-
import { resolve as resolve23, join as
|
|
10555
|
+
import { resolve as resolve23, join as join26 } from "node:path";
|
|
10289
10556
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
10290
10557
|
async function loadAttentionStore(workingDir) {
|
|
10291
10558
|
const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
|
|
@@ -10300,7 +10567,7 @@ async function saveAttentionStore(workingDir, store) {
|
|
|
10300
10567
|
const dir = resolve23(workingDir, ".oa", "scheduled");
|
|
10301
10568
|
await mkdir6(dir, { recursive: true });
|
|
10302
10569
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10303
|
-
await writeFile10(
|
|
10570
|
+
await writeFile10(join26(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
10304
10571
|
}
|
|
10305
10572
|
async function getActiveAttentionItems(workingDir) {
|
|
10306
10573
|
const store = await loadAttentionStore(workingDir);
|
|
@@ -10609,8 +10876,8 @@ ${sections.join("\n")}`,
|
|
|
10609
10876
|
|
|
10610
10877
|
// packages/execution/dist/tools/opencode.js
|
|
10611
10878
|
import { execSync as execSync19, spawn as spawn9 } from "node:child_process";
|
|
10612
|
-
import { existsSync as
|
|
10613
|
-
import { join as
|
|
10879
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
10880
|
+
import { join as join27, resolve as resolve24 } from "node:path";
|
|
10614
10881
|
function findOpencode() {
|
|
10615
10882
|
for (const cmd of ["opencode"]) {
|
|
10616
10883
|
try {
|
|
@@ -10622,12 +10889,12 @@ function findOpencode() {
|
|
|
10622
10889
|
}
|
|
10623
10890
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
10624
10891
|
const candidates = [
|
|
10625
|
-
|
|
10626
|
-
|
|
10892
|
+
join27(homeDir, ".opencode", "bin", "opencode"),
|
|
10893
|
+
join27(homeDir, "bin", "opencode"),
|
|
10627
10894
|
"/usr/local/bin/opencode"
|
|
10628
10895
|
];
|
|
10629
10896
|
for (const p of candidates) {
|
|
10630
|
-
if (
|
|
10897
|
+
if (existsSync21(p))
|
|
10631
10898
|
return p;
|
|
10632
10899
|
}
|
|
10633
10900
|
return null;
|
|
@@ -10883,8 +11150,8 @@ var init_opencode = __esm({
|
|
|
10883
11150
|
|
|
10884
11151
|
// packages/execution/dist/tools/factory.js
|
|
10885
11152
|
import { execSync as execSync20, spawn as spawn10 } from "node:child_process";
|
|
10886
|
-
import { existsSync as
|
|
10887
|
-
import { join as
|
|
11153
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
11154
|
+
import { join as join28 } from "node:path";
|
|
10888
11155
|
function findDroid() {
|
|
10889
11156
|
for (const cmd of ["droid"]) {
|
|
10890
11157
|
try {
|
|
@@ -10896,12 +11163,12 @@ function findDroid() {
|
|
|
10896
11163
|
}
|
|
10897
11164
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
10898
11165
|
const candidates = [
|
|
10899
|
-
|
|
10900
|
-
|
|
11166
|
+
join28(homeDir, ".factory", "bin", "droid"),
|
|
11167
|
+
join28(homeDir, "bin", "droid"),
|
|
10901
11168
|
"/usr/local/bin/droid"
|
|
10902
11169
|
];
|
|
10903
11170
|
for (const p of candidates) {
|
|
10904
|
-
if (
|
|
11171
|
+
if (existsSync22(p))
|
|
10905
11172
|
return p;
|
|
10906
11173
|
}
|
|
10907
11174
|
return null;
|
|
@@ -11193,7 +11460,7 @@ var init_factory = __esm({
|
|
|
11193
11460
|
// packages/execution/dist/tools/cron-agent.js
|
|
11194
11461
|
import { execSync as execSync21 } from "node:child_process";
|
|
11195
11462
|
import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
|
|
11196
|
-
import { resolve as resolve25, join as
|
|
11463
|
+
import { resolve as resolve25, join as join29 } from "node:path";
|
|
11197
11464
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
11198
11465
|
function isValidCron2(expr) {
|
|
11199
11466
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -11279,7 +11546,7 @@ function installCronAgentJob(job, workingDir) {
|
|
|
11279
11546
|
const lines = getCurrentCrontab2();
|
|
11280
11547
|
const oaBin = findOaBinary2();
|
|
11281
11548
|
const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
|
|
11282
|
-
const logFile =
|
|
11549
|
+
const logFile = join29(logDir, `${job.id}.log`);
|
|
11283
11550
|
const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
|
|
11284
11551
|
const taskEscaped = job.task.replace(/'/g, "'\\''");
|
|
11285
11552
|
const jobId = job.id;
|
|
@@ -11318,9 +11585,9 @@ async function loadStore2(workingDir) {
|
|
|
11318
11585
|
async function saveStore2(workingDir, store) {
|
|
11319
11586
|
const dir = resolve25(workingDir, ".oa", "cron-agents");
|
|
11320
11587
|
await mkdir7(dir, { recursive: true });
|
|
11321
|
-
await mkdir7(
|
|
11588
|
+
await mkdir7(join29(dir, "logs"), { recursive: true });
|
|
11322
11589
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11323
|
-
await writeFile11(
|
|
11590
|
+
await writeFile11(join29(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
11324
11591
|
}
|
|
11325
11592
|
var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
|
|
11326
11593
|
var init_cron_agent = __esm({
|
|
@@ -11657,8 +11924,8 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
11657
11924
|
|
|
11658
11925
|
// packages/execution/dist/tools/nexus.js
|
|
11659
11926
|
import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
|
|
11660
|
-
import { existsSync as
|
|
11661
|
-
import { resolve as resolve26, join as
|
|
11927
|
+
import { existsSync as existsSync23, readFileSync as readFileSync16 } from "node:fs";
|
|
11928
|
+
import { resolve as resolve26, join as join30 } from "node:path";
|
|
11662
11929
|
import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
|
|
11663
11930
|
import { execSync as execSync22, spawn as spawn11 } from "node:child_process";
|
|
11664
11931
|
import { hostname, userInfo } from "node:os";
|
|
@@ -12694,7 +12961,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12694
12961
|
this.nexusDir = resolve26(repoRoot, ".oa", "nexus");
|
|
12695
12962
|
}
|
|
12696
12963
|
async ensureDir() {
|
|
12697
|
-
if (!
|
|
12964
|
+
if (!existsSync23(this.nexusDir)) {
|
|
12698
12965
|
await mkdir8(this.nexusDir, { recursive: true });
|
|
12699
12966
|
}
|
|
12700
12967
|
}
|
|
@@ -12809,11 +13076,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12809
13076
|
// Daemon management
|
|
12810
13077
|
// =========================================================================
|
|
12811
13078
|
getDaemonPid() {
|
|
12812
|
-
const pidFile =
|
|
12813
|
-
if (!
|
|
13079
|
+
const pidFile = join30(this.nexusDir, "daemon.pid");
|
|
13080
|
+
if (!existsSync23(pidFile))
|
|
12814
13081
|
return null;
|
|
12815
13082
|
try {
|
|
12816
|
-
const pid = parseInt(
|
|
13083
|
+
const pid = parseInt(readFileSync16(pidFile, "utf8").trim(), 10);
|
|
12817
13084
|
process.kill(pid, 0);
|
|
12818
13085
|
return pid;
|
|
12819
13086
|
} catch {
|
|
@@ -12825,16 +13092,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12825
13092
|
if (!pid)
|
|
12826
13093
|
throw new Error("Nexus daemon not running. Use action 'connect' first.");
|
|
12827
13094
|
const cmdId = randomBytes6(8).toString("hex");
|
|
12828
|
-
const cmdFile =
|
|
12829
|
-
const respFile =
|
|
12830
|
-
if (
|
|
13095
|
+
const cmdFile = join30(this.nexusDir, "cmd.json");
|
|
13096
|
+
const respFile = join30(this.nexusDir, "resp.json");
|
|
13097
|
+
if (existsSync23(respFile))
|
|
12831
13098
|
await unlink(respFile).catch(() => {
|
|
12832
13099
|
});
|
|
12833
13100
|
await writeFile12(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
|
|
12834
13101
|
const polls = Math.ceil(timeoutMs / 500);
|
|
12835
13102
|
for (let i = 0; i < polls; i++) {
|
|
12836
13103
|
await new Promise((r) => setTimeout(r, 500));
|
|
12837
|
-
if (!
|
|
13104
|
+
if (!existsSync23(respFile))
|
|
12838
13105
|
continue;
|
|
12839
13106
|
try {
|
|
12840
13107
|
const resp = JSON.parse(await readFile13(respFile, "utf8"));
|
|
@@ -12861,8 +13128,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12861
13128
|
await this.ensureDir();
|
|
12862
13129
|
const existingPid = this.getDaemonPid();
|
|
12863
13130
|
if (existingPid) {
|
|
12864
|
-
const statusFile2 =
|
|
12865
|
-
if (
|
|
13131
|
+
const statusFile2 = join30(this.nexusDir, "status.json");
|
|
13132
|
+
if (existsSync23(statusFile2)) {
|
|
12866
13133
|
try {
|
|
12867
13134
|
const status = JSON.parse(await readFile13(statusFile2, "utf8"));
|
|
12868
13135
|
if (status.connected && status.peerId) {
|
|
@@ -12878,8 +13145,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12878
13145
|
await new Promise((r) => setTimeout(r, 500));
|
|
12879
13146
|
}
|
|
12880
13147
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
12881
|
-
const p =
|
|
12882
|
-
if (
|
|
13148
|
+
const p = join30(this.nexusDir, f);
|
|
13149
|
+
if (existsSync23(p))
|
|
12883
13150
|
await unlink(p).catch(() => {
|
|
12884
13151
|
});
|
|
12885
13152
|
}
|
|
@@ -12887,21 +13154,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12887
13154
|
let nexusResolved = false;
|
|
12888
13155
|
let installedVersion = "";
|
|
12889
13156
|
try {
|
|
12890
|
-
const nexusPkg =
|
|
12891
|
-
if (
|
|
13157
|
+
const nexusPkg = join30(nodeModulesDir, "open-agents-nexus", "package.json");
|
|
13158
|
+
if (existsSync23(nexusPkg)) {
|
|
12892
13159
|
nexusResolved = true;
|
|
12893
13160
|
try {
|
|
12894
|
-
const pkg = JSON.parse(
|
|
13161
|
+
const pkg = JSON.parse(readFileSync16(nexusPkg, "utf8"));
|
|
12895
13162
|
installedVersion = pkg.version || "";
|
|
12896
13163
|
} catch {
|
|
12897
13164
|
}
|
|
12898
13165
|
} else {
|
|
12899
13166
|
const globalDir = execSync22("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
12900
|
-
const globalPkg =
|
|
12901
|
-
if (
|
|
13167
|
+
const globalPkg = join30(globalDir, "open-agents-nexus", "package.json");
|
|
13168
|
+
if (existsSync23(globalPkg)) {
|
|
12902
13169
|
nexusResolved = true;
|
|
12903
13170
|
try {
|
|
12904
|
-
const pkg = JSON.parse(
|
|
13171
|
+
const pkg = JSON.parse(readFileSync16(globalPkg, "utf8"));
|
|
12905
13172
|
installedVersion = pkg.version || "";
|
|
12906
13173
|
} catch {
|
|
12907
13174
|
}
|
|
@@ -12944,7 +13211,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12944
13211
|
}
|
|
12945
13212
|
}
|
|
12946
13213
|
}
|
|
12947
|
-
const daemonPath =
|
|
13214
|
+
const daemonPath = join30(this.nexusDir, "nexus-daemon.mjs");
|
|
12948
13215
|
await writeFile12(daemonPath, DAEMON_SCRIPT);
|
|
12949
13216
|
const agentName = args.agent_name || "open-agents-node";
|
|
12950
13217
|
const agentType = args.agent_type || "general";
|
|
@@ -12969,10 +13236,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
12969
13236
|
child.stderr?.on("data", (d) => {
|
|
12970
13237
|
earlyError += d.toString();
|
|
12971
13238
|
});
|
|
12972
|
-
const statusFile =
|
|
13239
|
+
const statusFile = join30(this.nexusDir, "status.json");
|
|
12973
13240
|
for (let i = 0; i < 40; i++) {
|
|
12974
13241
|
await new Promise((r) => setTimeout(r, 500));
|
|
12975
|
-
if (
|
|
13242
|
+
if (existsSync23(statusFile)) {
|
|
12976
13243
|
try {
|
|
12977
13244
|
const status = JSON.parse(await readFile13(statusFile, "utf8"));
|
|
12978
13245
|
if (status.error) {
|
|
@@ -13013,8 +13280,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13013
13280
|
} catch {
|
|
13014
13281
|
}
|
|
13015
13282
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
13016
|
-
const p =
|
|
13017
|
-
if (
|
|
13283
|
+
const p = join30(this.nexusDir, f);
|
|
13284
|
+
if (existsSync23(p))
|
|
13018
13285
|
await unlink(p).catch(() => {
|
|
13019
13286
|
});
|
|
13020
13287
|
}
|
|
@@ -13024,8 +13291,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13024
13291
|
const pid = this.getDaemonPid();
|
|
13025
13292
|
if (!pid)
|
|
13026
13293
|
return "Nexus daemon not running. Use action 'connect' to start.";
|
|
13027
|
-
const statusFile =
|
|
13028
|
-
if (!
|
|
13294
|
+
const statusFile = join30(this.nexusDir, "status.json");
|
|
13295
|
+
if (!existsSync23(statusFile))
|
|
13029
13296
|
return `Daemon running (pid: ${pid}) but no status yet.`;
|
|
13030
13297
|
try {
|
|
13031
13298
|
const status = JSON.parse(await readFile13(statusFile, "utf8"));
|
|
@@ -13039,8 +13306,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13039
13306
|
` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
|
|
13040
13307
|
` Blocked peers: ${(status.blockedPeers || []).length || 0}`
|
|
13041
13308
|
];
|
|
13042
|
-
const walletPath =
|
|
13043
|
-
if (
|
|
13309
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
13310
|
+
if (existsSync23(walletPath)) {
|
|
13044
13311
|
try {
|
|
13045
13312
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
13046
13313
|
lines.push(` Wallet: ${w.address}`);
|
|
@@ -13050,14 +13317,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13050
13317
|
} else {
|
|
13051
13318
|
lines.push(` Wallet: not configured`);
|
|
13052
13319
|
}
|
|
13053
|
-
const inboxDir =
|
|
13054
|
-
if (
|
|
13320
|
+
const inboxDir = join30(this.nexusDir, "inbox");
|
|
13321
|
+
if (existsSync23(inboxDir)) {
|
|
13055
13322
|
try {
|
|
13056
13323
|
const roomDirs = await readdir3(inboxDir);
|
|
13057
13324
|
let totalMsgs = 0;
|
|
13058
13325
|
for (const rd of roomDirs) {
|
|
13059
13326
|
try {
|
|
13060
|
-
totalMsgs += (await readdir3(
|
|
13327
|
+
totalMsgs += (await readdir3(join30(inboxDir, rd))).length;
|
|
13061
13328
|
} catch {
|
|
13062
13329
|
}
|
|
13063
13330
|
}
|
|
@@ -13104,10 +13371,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13104
13371
|
}
|
|
13105
13372
|
async doReadMessages(args) {
|
|
13106
13373
|
const roomId = args.room_id;
|
|
13107
|
-
const inboxDir =
|
|
13374
|
+
const inboxDir = join30(this.nexusDir, "inbox");
|
|
13108
13375
|
if (roomId) {
|
|
13109
|
-
const roomInbox =
|
|
13110
|
-
if (!
|
|
13376
|
+
const roomInbox = join30(inboxDir, roomId);
|
|
13377
|
+
if (!existsSync23(roomInbox))
|
|
13111
13378
|
return `No messages in room: ${roomId}`;
|
|
13112
13379
|
const files = (await readdir3(roomInbox)).sort().slice(-20);
|
|
13113
13380
|
if (files.length === 0)
|
|
@@ -13115,7 +13382,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13115
13382
|
const messages = [`Messages in ${roomId} (last ${files.length}):`];
|
|
13116
13383
|
for (const f of files) {
|
|
13117
13384
|
try {
|
|
13118
|
-
const msg = JSON.parse(await readFile13(
|
|
13385
|
+
const msg = JSON.parse(await readFile13(join30(roomInbox, f), "utf8"));
|
|
13119
13386
|
const sender = (msg.sender || "unknown").slice(0, 12);
|
|
13120
13387
|
messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
|
|
13121
13388
|
} catch {
|
|
@@ -13123,7 +13390,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13123
13390
|
}
|
|
13124
13391
|
return messages.join("\n");
|
|
13125
13392
|
}
|
|
13126
|
-
if (!
|
|
13393
|
+
if (!existsSync23(inboxDir))
|
|
13127
13394
|
return "No messages received yet.";
|
|
13128
13395
|
const roomDirs = await readdir3(inboxDir);
|
|
13129
13396
|
if (roomDirs.length === 0)
|
|
@@ -13131,7 +13398,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13131
13398
|
const lines = ["Inbox:"];
|
|
13132
13399
|
for (const rd of roomDirs) {
|
|
13133
13400
|
try {
|
|
13134
|
-
const count = (await readdir3(
|
|
13401
|
+
const count = (await readdir3(join30(inboxDir, rd))).length;
|
|
13135
13402
|
lines.push(` ${rd}: ${count} message(s)`);
|
|
13136
13403
|
} catch {
|
|
13137
13404
|
}
|
|
@@ -13143,8 +13410,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13143
13410
|
// ---------------------------------------------------------------------------
|
|
13144
13411
|
async doWalletStatus() {
|
|
13145
13412
|
await this.ensureDir();
|
|
13146
|
-
const walletPath =
|
|
13147
|
-
if (!
|
|
13413
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
13414
|
+
if (!existsSync23(walletPath)) {
|
|
13148
13415
|
return "No wallet configured. Use wallet_create to set one up.";
|
|
13149
13416
|
}
|
|
13150
13417
|
try {
|
|
@@ -13182,8 +13449,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13182
13449
|
}
|
|
13183
13450
|
async doWalletCreate(args) {
|
|
13184
13451
|
await this.ensureDir();
|
|
13185
|
-
const walletPath =
|
|
13186
|
-
if (
|
|
13452
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
13453
|
+
if (existsSync23(walletPath))
|
|
13187
13454
|
return "Wallet already exists. Delete wallet.enc to create a new one.";
|
|
13188
13455
|
const userAddress = args.wallet_address;
|
|
13189
13456
|
if (userAddress) {
|
|
@@ -13228,7 +13495,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13228
13495
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
13229
13496
|
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
13230
13497
|
enc += cipher.final("hex");
|
|
13231
|
-
const x402KeyPath =
|
|
13498
|
+
const x402KeyPath = join30(this.nexusDir, "x402-wallet.key");
|
|
13232
13499
|
const x402Fh = await fsOpen(x402KeyPath, "w", 384);
|
|
13233
13500
|
await x402Fh.writeFile("0x" + privKeyHex);
|
|
13234
13501
|
await x402Fh.close();
|
|
@@ -13299,8 +13566,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13299
13566
|
// ---------------------------------------------------------------------------
|
|
13300
13567
|
async doLedgerStatus() {
|
|
13301
13568
|
await this.ensureDir();
|
|
13302
|
-
const ledgerPath =
|
|
13303
|
-
if (!
|
|
13569
|
+
const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
|
|
13570
|
+
if (!existsSync23(ledgerPath)) {
|
|
13304
13571
|
return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
|
|
13305
13572
|
}
|
|
13306
13573
|
try {
|
|
@@ -13341,8 +13608,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13341
13608
|
}
|
|
13342
13609
|
}
|
|
13343
13610
|
async getLedgerSummary() {
|
|
13344
|
-
const ledgerPath =
|
|
13345
|
-
if (!
|
|
13611
|
+
const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
|
|
13612
|
+
if (!existsSync23(ledgerPath))
|
|
13346
13613
|
return null;
|
|
13347
13614
|
try {
|
|
13348
13615
|
const raw = await readFile13(ledgerPath, "utf8");
|
|
@@ -13366,16 +13633,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13366
13633
|
}
|
|
13367
13634
|
async appendLedger(entry) {
|
|
13368
13635
|
await this.ensureDir();
|
|
13369
|
-
const ledgerPath =
|
|
13636
|
+
const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
|
|
13370
13637
|
const line = JSON.stringify(entry) + "\n";
|
|
13371
|
-
await writeFile12(ledgerPath,
|
|
13638
|
+
await writeFile12(ledgerPath, existsSync23(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
|
|
13372
13639
|
}
|
|
13373
13640
|
// ---------------------------------------------------------------------------
|
|
13374
13641
|
// Step 4: Budget Policy — Spending limits and auto-approve thresholds
|
|
13375
13642
|
// ---------------------------------------------------------------------------
|
|
13376
13643
|
async loadBudget() {
|
|
13377
|
-
const budgetPath =
|
|
13378
|
-
if (!
|
|
13644
|
+
const budgetPath = join30(this.nexusDir, "budget.json");
|
|
13645
|
+
if (!existsSync23(budgetPath))
|
|
13379
13646
|
return null;
|
|
13380
13647
|
try {
|
|
13381
13648
|
return JSON.parse(await readFile13(budgetPath, "utf8"));
|
|
@@ -13384,8 +13651,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13384
13651
|
}
|
|
13385
13652
|
}
|
|
13386
13653
|
async ensureDefaultBudget() {
|
|
13387
|
-
const budgetPath =
|
|
13388
|
-
if (
|
|
13654
|
+
const budgetPath = join30(this.nexusDir, "budget.json");
|
|
13655
|
+
if (existsSync23(budgetPath))
|
|
13389
13656
|
return;
|
|
13390
13657
|
const defaultBudget = {
|
|
13391
13658
|
version: 1,
|
|
@@ -13454,13 +13721,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13454
13721
|
if (changes.length === 0) {
|
|
13455
13722
|
return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
|
|
13456
13723
|
}
|
|
13457
|
-
const budgetPath =
|
|
13724
|
+
const budgetPath = join30(this.nexusDir, "budget.json");
|
|
13458
13725
|
await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
|
|
13459
13726
|
return `Budget updated: ${changes.join(", ")}`;
|
|
13460
13727
|
}
|
|
13461
13728
|
async getTodaySpending() {
|
|
13462
|
-
const ledgerPath =
|
|
13463
|
-
if (!
|
|
13729
|
+
const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
|
|
13730
|
+
if (!existsSync23(ledgerPath))
|
|
13464
13731
|
return 0;
|
|
13465
13732
|
try {
|
|
13466
13733
|
const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -13503,8 +13770,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13503
13770
|
if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
|
|
13504
13771
|
return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
|
|
13505
13772
|
}
|
|
13506
|
-
const walletPath =
|
|
13507
|
-
if (
|
|
13773
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
13774
|
+
if (existsSync23(walletPath)) {
|
|
13508
13775
|
try {
|
|
13509
13776
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
13510
13777
|
if (w.version === 2 && w.address) {
|
|
@@ -13534,8 +13801,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13534
13801
|
const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
|
|
13535
13802
|
if (!budgetResult.allowed)
|
|
13536
13803
|
return `BLOCKED by budget policy: ${budgetResult.reason}`;
|
|
13537
|
-
const walletPath =
|
|
13538
|
-
if (!
|
|
13804
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
13805
|
+
if (!existsSync23(walletPath))
|
|
13539
13806
|
throw new Error("No wallet. Use wallet_create first.");
|
|
13540
13807
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
13541
13808
|
if (!w.encryptedKey)
|
|
@@ -13595,7 +13862,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13595
13862
|
capability: "transfer:direct",
|
|
13596
13863
|
note: "signed, awaiting submission"
|
|
13597
13864
|
});
|
|
13598
|
-
const proofFile =
|
|
13865
|
+
const proofFile = join30(this.nexusDir, "pending-transfer.json");
|
|
13599
13866
|
const proof = {
|
|
13600
13867
|
from: account.address,
|
|
13601
13868
|
to: targetAddress,
|
|
@@ -13637,8 +13904,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13637
13904
|
throw new Error("prompt is required");
|
|
13638
13905
|
const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
|
|
13639
13906
|
let estimatedCostSmallest = 0;
|
|
13640
|
-
const pricingPath =
|
|
13641
|
-
if (
|
|
13907
|
+
const pricingPath = join30(this.nexusDir, "pricing.json");
|
|
13908
|
+
if (existsSync23(pricingPath)) {
|
|
13642
13909
|
try {
|
|
13643
13910
|
const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
|
|
13644
13911
|
const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
|
|
@@ -13757,7 +14024,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13757
14024
|
const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
|
|
13758
14025
|
const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
|
|
13759
14026
|
await this.ensureDir();
|
|
13760
|
-
await writeFile12(
|
|
14027
|
+
await writeFile12(join30(this.nexusDir, "inference-proof.json"), JSON.stringify({
|
|
13761
14028
|
modelName,
|
|
13762
14029
|
gpuName,
|
|
13763
14030
|
vramMb,
|
|
@@ -13885,6 +14152,7 @@ var init_dist2 = __esm({
|
|
|
13885
14152
|
init_custom_tool();
|
|
13886
14153
|
init_tool_creator();
|
|
13887
14154
|
init_skill_tools();
|
|
14155
|
+
init_skill_builder();
|
|
13888
14156
|
init_transcribe_tool();
|
|
13889
14157
|
init_structured_file();
|
|
13890
14158
|
init_code_sandbox();
|
|
@@ -14587,30 +14855,30 @@ var init_dist3 = __esm({
|
|
|
14587
14855
|
});
|
|
14588
14856
|
|
|
14589
14857
|
// packages/orchestrator/dist/promptLoader.js
|
|
14590
|
-
import { readFileSync as
|
|
14591
|
-
import { join as
|
|
14858
|
+
import { readFileSync as readFileSync17, existsSync as existsSync24 } from "node:fs";
|
|
14859
|
+
import { join as join31, dirname as dirname11 } from "node:path";
|
|
14592
14860
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
14593
14861
|
function loadPrompt(promptPath, vars) {
|
|
14594
14862
|
let content = cache.get(promptPath);
|
|
14595
14863
|
if (content === void 0) {
|
|
14596
|
-
const fullPath =
|
|
14597
|
-
if (!
|
|
14864
|
+
const fullPath = join31(PROMPTS_DIR, promptPath);
|
|
14865
|
+
if (!existsSync24(fullPath)) {
|
|
14598
14866
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
14599
14867
|
}
|
|
14600
|
-
content =
|
|
14868
|
+
content = readFileSync17(fullPath, "utf-8");
|
|
14601
14869
|
cache.set(promptPath, content);
|
|
14602
14870
|
}
|
|
14603
14871
|
if (!vars)
|
|
14604
14872
|
return content;
|
|
14605
14873
|
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
14606
14874
|
}
|
|
14607
|
-
var __filename,
|
|
14875
|
+
var __filename, __dirname4, PROMPTS_DIR, cache;
|
|
14608
14876
|
var init_promptLoader = __esm({
|
|
14609
14877
|
"packages/orchestrator/dist/promptLoader.js"() {
|
|
14610
14878
|
"use strict";
|
|
14611
14879
|
__filename = fileURLToPath7(import.meta.url);
|
|
14612
|
-
|
|
14613
|
-
PROMPTS_DIR =
|
|
14880
|
+
__dirname4 = dirname11(__filename);
|
|
14881
|
+
PROMPTS_DIR = join31(__dirname4, "..", "prompts");
|
|
14614
14882
|
cache = /* @__PURE__ */ new Map();
|
|
14615
14883
|
}
|
|
14616
14884
|
});
|
|
@@ -14990,7 +15258,7 @@ var init_code_retriever = __esm({
|
|
|
14990
15258
|
import { execFile as execFile5 } from "node:child_process";
|
|
14991
15259
|
import { promisify as promisify4 } from "node:util";
|
|
14992
15260
|
import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
14993
|
-
import { join as
|
|
15261
|
+
import { join as join32, extname as extname7 } from "node:path";
|
|
14994
15262
|
async function searchByPath(pathPattern, options) {
|
|
14995
15263
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
14996
15264
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -15132,7 +15400,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
15132
15400
|
continue;
|
|
15133
15401
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
15134
15402
|
continue;
|
|
15135
|
-
const absPath =
|
|
15403
|
+
const absPath = join32(dir, entry.name);
|
|
15136
15404
|
if (entry.isDirectory()) {
|
|
15137
15405
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
15138
15406
|
} else if (entry.isFile()) {
|
|
@@ -15439,7 +15707,7 @@ var init_graphExpand = __esm({
|
|
|
15439
15707
|
|
|
15440
15708
|
// packages/retrieval/dist/snippetPacker.js
|
|
15441
15709
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
15442
|
-
import { join as
|
|
15710
|
+
import { join as join33 } from "node:path";
|
|
15443
15711
|
async function packSnippets(requests, opts = {}) {
|
|
15444
15712
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
15445
15713
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -15465,7 +15733,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
15465
15733
|
return { packed, dropped, totalTokens };
|
|
15466
15734
|
}
|
|
15467
15735
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
15468
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
15736
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join33(repoRoot, req.filePath);
|
|
15469
15737
|
let content;
|
|
15470
15738
|
try {
|
|
15471
15739
|
content = await readFile15(absPath, "utf-8");
|
|
@@ -16646,6 +16914,7 @@ var init_agenticRunner = __esm({
|
|
|
16646
16914
|
_sudoPassword = null;
|
|
16647
16915
|
_sudoResolve = null;
|
|
16648
16916
|
_pendingCompaction = null;
|
|
16917
|
+
_skillCompactionStrategy = null;
|
|
16649
16918
|
// -- Task State Tracking (Priority 3) --
|
|
16650
16919
|
_taskState = {
|
|
16651
16920
|
goal: "",
|
|
@@ -16892,6 +17161,14 @@ ${this.options.dynamicContext}`,
|
|
|
16892
17161
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16893
17162
|
});
|
|
16894
17163
|
}
|
|
17164
|
+
/**
|
|
17165
|
+
* Set the active skill's preferred compaction strategy.
|
|
17166
|
+
* When set, auto-compaction uses this strategy instead of "default".
|
|
17167
|
+
* Called by the CLI when a skill is loaded via skill_execute.
|
|
17168
|
+
*/
|
|
17169
|
+
setSkillCompactionStrategy(strategy) {
|
|
17170
|
+
this._skillCompactionStrategy = strategy;
|
|
17171
|
+
}
|
|
16895
17172
|
/**
|
|
16896
17173
|
* If paused, block until resume() or abort() is called.
|
|
16897
17174
|
* Returns true if the loop should continue, false if aborted while paused.
|
|
@@ -17343,7 +17620,7 @@ You have used ${totalTurns} turns and ${toolCallCount} tool calls so far. The ta
|
|
|
17343
17620
|
|
|
17344
17621
|
You have ${this.options.maxTurns} more turns. Continue making progress. Call task_complete when the task is fully done.`
|
|
17345
17622
|
});
|
|
17346
|
-
const compacted = await this.compactMessages(messages);
|
|
17623
|
+
const compacted = await this.compactMessages(messages, this._skillCompactionStrategy ?? "default");
|
|
17347
17624
|
if (compacted !== messages) {
|
|
17348
17625
|
messages.length = 0;
|
|
17349
17626
|
messages.push(...compacted);
|
|
@@ -17407,7 +17684,7 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
17407
17684
|
this._pendingCompaction = null;
|
|
17408
17685
|
compactedMsgs = await this.compactMessages(messages, strategy, true);
|
|
17409
17686
|
} else {
|
|
17410
|
-
compactedMsgs = await this.compactMessages(messages);
|
|
17687
|
+
compactedMsgs = await this.compactMessages(messages, this._skillCompactionStrategy ?? "default");
|
|
17411
17688
|
}
|
|
17412
17689
|
const chatRequest = { messages: compactedMsgs, tools: toolDefs, temperature: this.options.temperature, maxTokens: this.options.maxTokens, timeoutMs: this.options.requestTimeoutMs };
|
|
17413
17690
|
let response;
|
|
@@ -17685,10 +17962,10 @@ ${marker}` : marker);
|
|
|
17685
17962
|
if (!this._workingDirectory)
|
|
17686
17963
|
return;
|
|
17687
17964
|
try {
|
|
17688
|
-
const { mkdirSync:
|
|
17689
|
-
const { join:
|
|
17690
|
-
const sessionDir =
|
|
17691
|
-
|
|
17965
|
+
const { mkdirSync: mkdirSync19, writeFileSync: writeFileSync17 } = __require("node:fs");
|
|
17966
|
+
const { join: join54 } = __require("node:path");
|
|
17967
|
+
const sessionDir = join54(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
17968
|
+
mkdirSync19(sessionDir, { recursive: true });
|
|
17692
17969
|
const checkpoint = {
|
|
17693
17970
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17694
17971
|
sessionId: this._sessionId,
|
|
@@ -17700,7 +17977,7 @@ ${marker}` : marker);
|
|
|
17700
17977
|
memexEntryCount: this._memexArchive.size,
|
|
17701
17978
|
fileRegistrySize: this._fileRegistry.size
|
|
17702
17979
|
};
|
|
17703
|
-
|
|
17980
|
+
writeFileSync17(join54(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
17704
17981
|
} catch {
|
|
17705
17982
|
}
|
|
17706
17983
|
}
|
|
@@ -17992,6 +18269,7 @@ ${newerSummary}` : newerSummary;
|
|
|
17992
18269
|
const commandResults = [];
|
|
17993
18270
|
const searchFindings = [];
|
|
17994
18271
|
const errors = [];
|
|
18272
|
+
let skillResults;
|
|
17995
18273
|
let toolCallCount = 0;
|
|
17996
18274
|
for (const msg of messages) {
|
|
17997
18275
|
if (msg.role === "assistant" && typeof msg.content === "string" && msg.content.trim()) {
|
|
@@ -18085,6 +18363,19 @@ ${newerSummary}` : newerSummary;
|
|
|
18085
18363
|
searchFindings.push(`find "${pattern}": ${files.length} files \u2014 ${files.slice(0, 5).join(", ")}`);
|
|
18086
18364
|
break;
|
|
18087
18365
|
}
|
|
18366
|
+
case "skill_build":
|
|
18367
|
+
case "skill_execute":
|
|
18368
|
+
case "skill_list":
|
|
18369
|
+
case "memory_write":
|
|
18370
|
+
case "memory_read": {
|
|
18371
|
+
const summary = content.length > 300 ? content.slice(0, 300) + "..." : content;
|
|
18372
|
+
if (!skillResults)
|
|
18373
|
+
skillResults = [];
|
|
18374
|
+
skillResults.push(`${tc.name}: ${summary}`);
|
|
18375
|
+
if (content.startsWith("Error:"))
|
|
18376
|
+
errors.push(`${tc.name}: ${content.slice(0, 200)}`);
|
|
18377
|
+
break;
|
|
18378
|
+
}
|
|
18088
18379
|
default: {
|
|
18089
18380
|
if (content.startsWith("Error:"))
|
|
18090
18381
|
errors.push(`${tc.name}: ${content.slice(0, 200)}`);
|
|
@@ -18133,6 +18424,13 @@ ${newerSummary}` : newerSummary;
|
|
|
18133
18424
|
}
|
|
18134
18425
|
parts.push("");
|
|
18135
18426
|
}
|
|
18427
|
+
if (skillResults && skillResults.length > 0) {
|
|
18428
|
+
parts.push("### Skill/Memory Context");
|
|
18429
|
+
for (const sr of skillResults.slice(0, 5)) {
|
|
18430
|
+
parts.push(`- ${sr}`);
|
|
18431
|
+
}
|
|
18432
|
+
parts.push("");
|
|
18433
|
+
}
|
|
18136
18434
|
if (errors.length > 0) {
|
|
18137
18435
|
parts.push("### Errors Encountered");
|
|
18138
18436
|
for (const error of errors.slice(0, 5)) {
|
|
@@ -18310,11 +18608,24 @@ ${newerSummary}` : newerSummary;
|
|
|
18310
18608
|
context: action,
|
|
18311
18609
|
error: content.slice(0, 300)
|
|
18312
18610
|
});
|
|
18611
|
+
} else if (tc.name === "skill_build" || tc.name === "skill_execute" || tc.name === "memory_read") {
|
|
18612
|
+
successes.push(`${action}: ${content.slice(0, 200)}`);
|
|
18313
18613
|
} else {
|
|
18314
18614
|
successes.push(`${action} \u2192 ok`);
|
|
18315
18615
|
}
|
|
18316
18616
|
}
|
|
18317
18617
|
}
|
|
18618
|
+
const decisions = [];
|
|
18619
|
+
for (const msg of messages) {
|
|
18620
|
+
if (msg.role === "assistant" && typeof msg.content === "string" && msg.content.trim().length > 30) {
|
|
18621
|
+
const decisionPatterns = /(?:I (?:will|need to|should|decided|chose|'ll)|Let me|The (?:fix|solution|approach|issue))[^.!?\n]{10,120}[.!?]/gi;
|
|
18622
|
+
const matches = msg.content.match(decisionPatterns);
|
|
18623
|
+
if (matches) {
|
|
18624
|
+
for (const m of matches.slice(0, 2))
|
|
18625
|
+
decisions.push(m.trim());
|
|
18626
|
+
}
|
|
18627
|
+
}
|
|
18628
|
+
}
|
|
18318
18629
|
const parts = [];
|
|
18319
18630
|
parts.push(`## Error-Focused Compact
|
|
18320
18631
|
`);
|
|
@@ -18328,6 +18639,12 @@ ${newerSummary}` : newerSummary;
|
|
|
18328
18639
|
}
|
|
18329
18640
|
parts.push("");
|
|
18330
18641
|
}
|
|
18642
|
+
if (decisions.length > 0) {
|
|
18643
|
+
parts.push("### Key Decisions");
|
|
18644
|
+
for (const d of decisions.slice(0, 5))
|
|
18645
|
+
parts.push(`- ${d}`);
|
|
18646
|
+
parts.push("");
|
|
18647
|
+
}
|
|
18331
18648
|
if (successes.length > 0) {
|
|
18332
18649
|
parts.push(`### Successful Operations (${successes.length} total)`);
|
|
18333
18650
|
for (const s of successes.slice(0, 10))
|
|
@@ -19478,8 +19795,8 @@ __export(listen_exports, {
|
|
|
19478
19795
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
19479
19796
|
});
|
|
19480
19797
|
import { spawn as spawn12, execSync as execSync23 } from "node:child_process";
|
|
19481
|
-
import { existsSync as
|
|
19482
|
-
import { join as
|
|
19798
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, readdirSync as readdirSync6 } from "node:fs";
|
|
19799
|
+
import { join as join34, dirname as dirname12 } from "node:path";
|
|
19483
19800
|
import { homedir as homedir8 } from "node:os";
|
|
19484
19801
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
19485
19802
|
import { EventEmitter } from "node:events";
|
|
@@ -19563,17 +19880,17 @@ function findMicCaptureCommand() {
|
|
|
19563
19880
|
return null;
|
|
19564
19881
|
}
|
|
19565
19882
|
function findLiveWhisperScript() {
|
|
19566
|
-
const thisDir =
|
|
19883
|
+
const thisDir = dirname12(fileURLToPath8(import.meta.url));
|
|
19567
19884
|
const candidates = [
|
|
19568
|
-
|
|
19569
|
-
|
|
19570
|
-
|
|
19885
|
+
join34(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
19886
|
+
join34(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
19887
|
+
join34(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
19571
19888
|
// npm install layout — scripts bundled alongside dist
|
|
19572
|
-
|
|
19573
|
-
|
|
19889
|
+
join34(thisDir, "../scripts/live-whisper.py"),
|
|
19890
|
+
join34(thisDir, "../../scripts/live-whisper.py")
|
|
19574
19891
|
];
|
|
19575
19892
|
for (const p of candidates) {
|
|
19576
|
-
if (
|
|
19893
|
+
if (existsSync25(p))
|
|
19577
19894
|
return p;
|
|
19578
19895
|
}
|
|
19579
19896
|
try {
|
|
@@ -19583,21 +19900,21 @@ function findLiveWhisperScript() {
|
|
|
19583
19900
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19584
19901
|
}).trim();
|
|
19585
19902
|
const candidates2 = [
|
|
19586
|
-
|
|
19587
|
-
|
|
19903
|
+
join34(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
19904
|
+
join34(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
19588
19905
|
];
|
|
19589
19906
|
for (const p of candidates2) {
|
|
19590
|
-
if (
|
|
19907
|
+
if (existsSync25(p))
|
|
19591
19908
|
return p;
|
|
19592
19909
|
}
|
|
19593
19910
|
} catch {
|
|
19594
19911
|
}
|
|
19595
|
-
const nvmBase =
|
|
19596
|
-
if (
|
|
19912
|
+
const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
|
|
19913
|
+
if (existsSync25(nvmBase)) {
|
|
19597
19914
|
try {
|
|
19598
19915
|
for (const ver of readdirSync6(nvmBase)) {
|
|
19599
|
-
const p =
|
|
19600
|
-
if (
|
|
19916
|
+
const p = join34(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
19917
|
+
if (existsSync25(p))
|
|
19601
19918
|
return p;
|
|
19602
19919
|
}
|
|
19603
19920
|
} catch {
|
|
@@ -19615,7 +19932,7 @@ function ensureTranscribeCliBackground() {
|
|
|
19615
19932
|
timeout: 5e3,
|
|
19616
19933
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19617
19934
|
}).trim();
|
|
19618
|
-
if (
|
|
19935
|
+
if (existsSync25(join34(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
19619
19936
|
return true;
|
|
19620
19937
|
}
|
|
19621
19938
|
} catch {
|
|
@@ -19838,24 +20155,24 @@ var init_listen = __esm({
|
|
|
19838
20155
|
timeout: 5e3,
|
|
19839
20156
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19840
20157
|
}).trim();
|
|
19841
|
-
const tcPath =
|
|
19842
|
-
if (
|
|
20158
|
+
const tcPath = join34(globalRoot, "transcribe-cli");
|
|
20159
|
+
if (existsSync25(join34(tcPath, "dist", "index.js"))) {
|
|
19843
20160
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
19844
20161
|
const req = createRequire4(import.meta.url);
|
|
19845
|
-
return req(
|
|
20162
|
+
return req(join34(tcPath, "dist", "index.js"));
|
|
19846
20163
|
}
|
|
19847
20164
|
} catch {
|
|
19848
20165
|
}
|
|
19849
|
-
const nvmBase =
|
|
19850
|
-
if (
|
|
20166
|
+
const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
|
|
20167
|
+
if (existsSync25(nvmBase)) {
|
|
19851
20168
|
try {
|
|
19852
20169
|
const { readdirSync: readdirSync15 } = await import("node:fs");
|
|
19853
20170
|
for (const ver of readdirSync15(nvmBase)) {
|
|
19854
|
-
const tcPath =
|
|
19855
|
-
if (
|
|
20171
|
+
const tcPath = join34(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
20172
|
+
if (existsSync25(join34(tcPath, "dist", "index.js"))) {
|
|
19856
20173
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
19857
20174
|
const req = createRequire4(import.meta.url);
|
|
19858
|
-
return req(
|
|
20175
|
+
return req(join34(tcPath, "dist", "index.js"));
|
|
19859
20176
|
}
|
|
19860
20177
|
}
|
|
19861
20178
|
} catch {
|
|
@@ -20137,10 +20454,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
20137
20454
|
});
|
|
20138
20455
|
if (outputDir) {
|
|
20139
20456
|
const { basename: basename16 } = await import("node:path");
|
|
20140
|
-
const transcriptDir =
|
|
20141
|
-
|
|
20142
|
-
const outFile =
|
|
20143
|
-
|
|
20457
|
+
const transcriptDir = join34(outputDir, ".oa", "transcripts");
|
|
20458
|
+
mkdirSync7(transcriptDir, { recursive: true });
|
|
20459
|
+
const outFile = join34(transcriptDir, `${basename16(filePath)}.txt`);
|
|
20460
|
+
writeFileSync7(outFile, result.text, "utf-8");
|
|
20144
20461
|
}
|
|
20145
20462
|
return {
|
|
20146
20463
|
text: result.text,
|
|
@@ -25740,8 +26057,8 @@ var init_types = __esm({
|
|
|
25740
26057
|
|
|
25741
26058
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
25742
26059
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
25743
|
-
import { readFileSync as
|
|
25744
|
-
import { join as
|
|
26060
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync8, existsSync as existsSync26, mkdirSync as mkdirSync8 } from "node:fs";
|
|
26061
|
+
import { join as join35, dirname as dirname13 } from "node:path";
|
|
25745
26062
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
25746
26063
|
var init_secret_vault = __esm({
|
|
25747
26064
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -25952,19 +26269,19 @@ var init_secret_vault = __esm({
|
|
|
25952
26269
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
25953
26270
|
const tag = cipher.getAuthTag();
|
|
25954
26271
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
25955
|
-
const dir =
|
|
25956
|
-
if (!
|
|
25957
|
-
|
|
25958
|
-
|
|
26272
|
+
const dir = dirname13(this.storePath);
|
|
26273
|
+
if (!existsSync26(dir))
|
|
26274
|
+
mkdirSync8(dir, { recursive: true });
|
|
26275
|
+
writeFileSync8(this.storePath, blob, { mode: 384 });
|
|
25959
26276
|
}
|
|
25960
26277
|
/**
|
|
25961
26278
|
* Load vault from disk, decrypting with the given passphrase.
|
|
25962
26279
|
* Returns the number of secrets loaded.
|
|
25963
26280
|
*/
|
|
25964
26281
|
load(passphrase) {
|
|
25965
|
-
if (!this.storePath || !
|
|
26282
|
+
if (!this.storePath || !existsSync26(this.storePath))
|
|
25966
26283
|
return 0;
|
|
25967
|
-
const blob =
|
|
26284
|
+
const blob = readFileSync18(this.storePath);
|
|
25968
26285
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
25969
26286
|
throw new Error("Vault file is corrupted (too small)");
|
|
25970
26287
|
}
|
|
@@ -27184,32 +27501,32 @@ var init_render2 = __esm({
|
|
|
27184
27501
|
});
|
|
27185
27502
|
|
|
27186
27503
|
// packages/prompts/dist/promptLoader.js
|
|
27187
|
-
import { readFileSync as
|
|
27188
|
-
import { join as
|
|
27504
|
+
import { readFileSync as readFileSync19, existsSync as existsSync27 } from "node:fs";
|
|
27505
|
+
import { join as join36, dirname as dirname14 } from "node:path";
|
|
27189
27506
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
27190
27507
|
function loadPrompt2(promptPath, vars) {
|
|
27191
27508
|
let content = cache2.get(promptPath);
|
|
27192
27509
|
if (content === void 0) {
|
|
27193
|
-
const fullPath =
|
|
27194
|
-
if (!
|
|
27510
|
+
const fullPath = join36(PROMPTS_DIR2, promptPath);
|
|
27511
|
+
if (!existsSync27(fullPath)) {
|
|
27195
27512
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
27196
27513
|
}
|
|
27197
|
-
content =
|
|
27514
|
+
content = readFileSync19(fullPath, "utf-8");
|
|
27198
27515
|
cache2.set(promptPath, content);
|
|
27199
27516
|
}
|
|
27200
27517
|
if (!vars)
|
|
27201
27518
|
return content;
|
|
27202
27519
|
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
27203
27520
|
}
|
|
27204
|
-
var __filename2,
|
|
27521
|
+
var __filename2, __dirname5, devPath, publishedPath, PROMPTS_DIR2, cache2;
|
|
27205
27522
|
var init_promptLoader2 = __esm({
|
|
27206
27523
|
"packages/prompts/dist/promptLoader.js"() {
|
|
27207
27524
|
"use strict";
|
|
27208
27525
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
27209
|
-
|
|
27210
|
-
devPath =
|
|
27211
|
-
publishedPath =
|
|
27212
|
-
PROMPTS_DIR2 =
|
|
27526
|
+
__dirname5 = dirname14(__filename2);
|
|
27527
|
+
devPath = join36(__dirname5, "..", "templates");
|
|
27528
|
+
publishedPath = join36(__dirname5, "..", "prompts", "templates");
|
|
27529
|
+
PROMPTS_DIR2 = existsSync27(devPath) ? devPath : publishedPath;
|
|
27213
27530
|
cache2 = /* @__PURE__ */ new Map();
|
|
27214
27531
|
}
|
|
27215
27532
|
});
|
|
@@ -27320,7 +27637,7 @@ var init_task_templates = __esm({
|
|
|
27320
27637
|
});
|
|
27321
27638
|
|
|
27322
27639
|
// packages/prompts/dist/index.js
|
|
27323
|
-
import { join as
|
|
27640
|
+
import { join as join37, dirname as dirname15 } from "node:path";
|
|
27324
27641
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
27325
27642
|
var _dir, _packageRoot;
|
|
27326
27643
|
var init_dist6 = __esm({
|
|
@@ -27330,27 +27647,27 @@ var init_dist6 = __esm({
|
|
|
27330
27647
|
init_render2();
|
|
27331
27648
|
init_task_templates();
|
|
27332
27649
|
init_render2();
|
|
27333
|
-
_dir =
|
|
27334
|
-
_packageRoot =
|
|
27650
|
+
_dir = dirname15(fileURLToPath10(import.meta.url));
|
|
27651
|
+
_packageRoot = join37(_dir, "..");
|
|
27335
27652
|
}
|
|
27336
27653
|
});
|
|
27337
27654
|
|
|
27338
27655
|
// packages/cli/dist/tui/oa-directory.js
|
|
27339
|
-
import { existsSync as
|
|
27340
|
-
import { join as
|
|
27656
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync9, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
|
|
27657
|
+
import { join as join38, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
27341
27658
|
import { homedir as homedir9 } from "node:os";
|
|
27342
27659
|
function initOaDirectory(repoRoot) {
|
|
27343
|
-
const oaPath =
|
|
27660
|
+
const oaPath = join38(repoRoot, OA_DIR);
|
|
27344
27661
|
for (const sub of SUBDIRS) {
|
|
27345
|
-
|
|
27662
|
+
mkdirSync9(join38(oaPath, sub), { recursive: true });
|
|
27346
27663
|
}
|
|
27347
27664
|
try {
|
|
27348
|
-
const gitignorePath =
|
|
27665
|
+
const gitignorePath = join38(repoRoot, ".gitignore");
|
|
27349
27666
|
const settingsPattern = ".oa/settings.json";
|
|
27350
|
-
if (
|
|
27351
|
-
const content =
|
|
27667
|
+
if (existsSync28(gitignorePath)) {
|
|
27668
|
+
const content = readFileSync20(gitignorePath, "utf-8");
|
|
27352
27669
|
if (!content.includes(settingsPattern)) {
|
|
27353
|
-
|
|
27670
|
+
writeFileSync9(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
27354
27671
|
}
|
|
27355
27672
|
}
|
|
27356
27673
|
} catch {
|
|
@@ -27358,41 +27675,41 @@ function initOaDirectory(repoRoot) {
|
|
|
27358
27675
|
return oaPath;
|
|
27359
27676
|
}
|
|
27360
27677
|
function hasOaDirectory(repoRoot) {
|
|
27361
|
-
return
|
|
27678
|
+
return existsSync28(join38(repoRoot, OA_DIR, "index"));
|
|
27362
27679
|
}
|
|
27363
27680
|
function loadProjectSettings(repoRoot) {
|
|
27364
|
-
const settingsPath =
|
|
27681
|
+
const settingsPath = join38(repoRoot, OA_DIR, "settings.json");
|
|
27365
27682
|
try {
|
|
27366
|
-
if (
|
|
27367
|
-
return JSON.parse(
|
|
27683
|
+
if (existsSync28(settingsPath)) {
|
|
27684
|
+
return JSON.parse(readFileSync20(settingsPath, "utf-8"));
|
|
27368
27685
|
}
|
|
27369
27686
|
} catch {
|
|
27370
27687
|
}
|
|
27371
27688
|
return {};
|
|
27372
27689
|
}
|
|
27373
27690
|
function saveProjectSettings(repoRoot, settings) {
|
|
27374
|
-
const oaPath =
|
|
27375
|
-
|
|
27691
|
+
const oaPath = join38(repoRoot, OA_DIR);
|
|
27692
|
+
mkdirSync9(oaPath, { recursive: true });
|
|
27376
27693
|
const existing = loadProjectSettings(repoRoot);
|
|
27377
27694
|
const merged = { ...existing, ...settings };
|
|
27378
|
-
|
|
27695
|
+
writeFileSync9(join38(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
27379
27696
|
}
|
|
27380
27697
|
function loadGlobalSettings() {
|
|
27381
|
-
const settingsPath =
|
|
27698
|
+
const settingsPath = join38(homedir9(), ".open-agents", "settings.json");
|
|
27382
27699
|
try {
|
|
27383
|
-
if (
|
|
27384
|
-
return JSON.parse(
|
|
27700
|
+
if (existsSync28(settingsPath)) {
|
|
27701
|
+
return JSON.parse(readFileSync20(settingsPath, "utf-8"));
|
|
27385
27702
|
}
|
|
27386
27703
|
} catch {
|
|
27387
27704
|
}
|
|
27388
27705
|
return {};
|
|
27389
27706
|
}
|
|
27390
27707
|
function saveGlobalSettings(settings) {
|
|
27391
|
-
const dir =
|
|
27392
|
-
|
|
27708
|
+
const dir = join38(homedir9(), ".open-agents");
|
|
27709
|
+
mkdirSync9(dir, { recursive: true });
|
|
27393
27710
|
const existing = loadGlobalSettings();
|
|
27394
27711
|
const merged = { ...existing, ...settings };
|
|
27395
|
-
|
|
27712
|
+
writeFileSync9(join38(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
27396
27713
|
}
|
|
27397
27714
|
function resolveSettings(repoRoot) {
|
|
27398
27715
|
const global = loadGlobalSettings();
|
|
@@ -27407,12 +27724,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
27407
27724
|
while (dir && !visited.has(dir)) {
|
|
27408
27725
|
visited.add(dir);
|
|
27409
27726
|
for (const name of CONTEXT_FILES) {
|
|
27410
|
-
const filePath =
|
|
27727
|
+
const filePath = join38(dir, name);
|
|
27411
27728
|
const normalizedName = name.toLowerCase();
|
|
27412
|
-
if (
|
|
27729
|
+
if (existsSync28(filePath) && !seen.has(filePath)) {
|
|
27413
27730
|
seen.add(filePath);
|
|
27414
27731
|
try {
|
|
27415
|
-
let content =
|
|
27732
|
+
let content = readFileSync20(filePath, "utf-8");
|
|
27416
27733
|
if (content.length > maxContentLen) {
|
|
27417
27734
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
27418
27735
|
}
|
|
@@ -27426,11 +27743,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
27426
27743
|
}
|
|
27427
27744
|
}
|
|
27428
27745
|
}
|
|
27429
|
-
const projectMap =
|
|
27430
|
-
if (
|
|
27746
|
+
const projectMap = join38(dir, OA_DIR, "context", "project-map.md");
|
|
27747
|
+
if (existsSync28(projectMap) && !seen.has(projectMap)) {
|
|
27431
27748
|
seen.add(projectMap);
|
|
27432
27749
|
try {
|
|
27433
|
-
let content =
|
|
27750
|
+
let content = readFileSync20(projectMap, "utf-8");
|
|
27434
27751
|
if (content.length > maxContentLen) {
|
|
27435
27752
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
27436
27753
|
}
|
|
@@ -27442,7 +27759,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
27442
27759
|
} catch {
|
|
27443
27760
|
}
|
|
27444
27761
|
}
|
|
27445
|
-
const parent =
|
|
27762
|
+
const parent = join38(dir, "..");
|
|
27446
27763
|
if (parent === dir)
|
|
27447
27764
|
break;
|
|
27448
27765
|
dir = parent;
|
|
@@ -27460,9 +27777,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
27460
27777
|
return found;
|
|
27461
27778
|
}
|
|
27462
27779
|
function readIndexMeta(repoRoot) {
|
|
27463
|
-
const metaPath =
|
|
27780
|
+
const metaPath = join38(repoRoot, OA_DIR, "index", "meta.json");
|
|
27464
27781
|
try {
|
|
27465
|
-
return JSON.parse(
|
|
27782
|
+
return JSON.parse(readFileSync20(metaPath, "utf-8"));
|
|
27466
27783
|
} catch {
|
|
27467
27784
|
return null;
|
|
27468
27785
|
}
|
|
@@ -27513,28 +27830,28 @@ ${tree}\`\`\`
|
|
|
27513
27830
|
sections.push("");
|
|
27514
27831
|
}
|
|
27515
27832
|
const content = sections.join("\n");
|
|
27516
|
-
const contextDir =
|
|
27517
|
-
|
|
27518
|
-
|
|
27833
|
+
const contextDir = join38(repoRoot, OA_DIR, "context");
|
|
27834
|
+
mkdirSync9(contextDir, { recursive: true });
|
|
27835
|
+
writeFileSync9(join38(contextDir, "project-map.md"), content, "utf-8");
|
|
27519
27836
|
return content;
|
|
27520
27837
|
}
|
|
27521
27838
|
function saveSession(repoRoot, session) {
|
|
27522
|
-
const historyDir =
|
|
27523
|
-
|
|
27524
|
-
|
|
27839
|
+
const historyDir = join38(repoRoot, OA_DIR, "history");
|
|
27840
|
+
mkdirSync9(historyDir, { recursive: true });
|
|
27841
|
+
writeFileSync9(join38(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
27525
27842
|
}
|
|
27526
27843
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
27527
|
-
const historyDir =
|
|
27528
|
-
if (!
|
|
27844
|
+
const historyDir = join38(repoRoot, OA_DIR, "history");
|
|
27845
|
+
if (!existsSync28(historyDir))
|
|
27529
27846
|
return [];
|
|
27530
27847
|
try {
|
|
27531
27848
|
const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
27532
|
-
const stat5 = statSync9(
|
|
27849
|
+
const stat5 = statSync9(join38(historyDir, f));
|
|
27533
27850
|
return { file: f, mtime: stat5.mtimeMs };
|
|
27534
27851
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
27535
27852
|
return files.map((f) => {
|
|
27536
27853
|
try {
|
|
27537
|
-
return JSON.parse(
|
|
27854
|
+
return JSON.parse(readFileSync20(join38(historyDir, f.file), "utf-8"));
|
|
27538
27855
|
} catch {
|
|
27539
27856
|
return null;
|
|
27540
27857
|
}
|
|
@@ -27544,16 +27861,16 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
27544
27861
|
}
|
|
27545
27862
|
}
|
|
27546
27863
|
function savePendingTask(repoRoot, task) {
|
|
27547
|
-
const historyDir =
|
|
27548
|
-
|
|
27549
|
-
|
|
27864
|
+
const historyDir = join38(repoRoot, OA_DIR, "history");
|
|
27865
|
+
mkdirSync9(historyDir, { recursive: true });
|
|
27866
|
+
writeFileSync9(join38(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
27550
27867
|
}
|
|
27551
27868
|
function loadPendingTask(repoRoot) {
|
|
27552
|
-
const filePath =
|
|
27869
|
+
const filePath = join38(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
27553
27870
|
try {
|
|
27554
|
-
if (!
|
|
27871
|
+
if (!existsSync28(filePath))
|
|
27555
27872
|
return null;
|
|
27556
|
-
const data = JSON.parse(
|
|
27873
|
+
const data = JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
27557
27874
|
try {
|
|
27558
27875
|
unlinkSync3(filePath);
|
|
27559
27876
|
} catch {
|
|
@@ -27564,13 +27881,13 @@ function loadPendingTask(repoRoot) {
|
|
|
27564
27881
|
}
|
|
27565
27882
|
}
|
|
27566
27883
|
function saveSessionContext(repoRoot, entry) {
|
|
27567
|
-
const contextDir =
|
|
27568
|
-
|
|
27569
|
-
const filePath =
|
|
27884
|
+
const contextDir = join38(repoRoot, OA_DIR, "context");
|
|
27885
|
+
mkdirSync9(contextDir, { recursive: true });
|
|
27886
|
+
const filePath = join38(contextDir, CONTEXT_SAVE_FILE);
|
|
27570
27887
|
let ctx;
|
|
27571
27888
|
try {
|
|
27572
|
-
if (
|
|
27573
|
-
ctx = JSON.parse(
|
|
27889
|
+
if (existsSync28(filePath)) {
|
|
27890
|
+
ctx = JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
27574
27891
|
} else {
|
|
27575
27892
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
27576
27893
|
}
|
|
@@ -27582,14 +27899,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
27582
27899
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
27583
27900
|
}
|
|
27584
27901
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
27585
|
-
|
|
27902
|
+
writeFileSync9(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
27586
27903
|
}
|
|
27587
27904
|
function loadSessionContext(repoRoot) {
|
|
27588
|
-
const filePath =
|
|
27905
|
+
const filePath = join38(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
27589
27906
|
try {
|
|
27590
|
-
if (!
|
|
27907
|
+
if (!existsSync28(filePath))
|
|
27591
27908
|
return null;
|
|
27592
|
-
return JSON.parse(
|
|
27909
|
+
return JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
27593
27910
|
} catch {
|
|
27594
27911
|
return null;
|
|
27595
27912
|
}
|
|
@@ -27636,12 +27953,12 @@ function detectManifests(repoRoot) {
|
|
|
27636
27953
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
27637
27954
|
];
|
|
27638
27955
|
for (const check of checks) {
|
|
27639
|
-
const filePath =
|
|
27640
|
-
if (
|
|
27956
|
+
const filePath = join38(repoRoot, check.file);
|
|
27957
|
+
if (existsSync28(filePath)) {
|
|
27641
27958
|
let name;
|
|
27642
27959
|
if (check.nameField) {
|
|
27643
27960
|
try {
|
|
27644
|
-
const data = JSON.parse(
|
|
27961
|
+
const data = JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
27645
27962
|
name = data[check.nameField];
|
|
27646
27963
|
} catch {
|
|
27647
27964
|
}
|
|
@@ -27670,7 +27987,7 @@ function findKeyFiles(repoRoot) {
|
|
|
27670
27987
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
27671
27988
|
];
|
|
27672
27989
|
for (const check of checks) {
|
|
27673
|
-
if (
|
|
27990
|
+
if (existsSync28(join38(repoRoot, check.pattern))) {
|
|
27674
27991
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
27675
27992
|
}
|
|
27676
27993
|
}
|
|
@@ -27696,12 +28013,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
27696
28013
|
if (entry.isDirectory()) {
|
|
27697
28014
|
let fileCount = 0;
|
|
27698
28015
|
try {
|
|
27699
|
-
fileCount = readdirSync7(
|
|
28016
|
+
fileCount = readdirSync7(join38(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
27700
28017
|
} catch {
|
|
27701
28018
|
}
|
|
27702
28019
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
27703
28020
|
`;
|
|
27704
|
-
result += buildDirTree(
|
|
28021
|
+
result += buildDirTree(join38(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
27705
28022
|
} else if (depth < maxDepth) {
|
|
27706
28023
|
result += `${prefix}${connector}${entry.name}
|
|
27707
28024
|
`;
|
|
@@ -27755,8 +28072,8 @@ var init_oa_directory = __esm({
|
|
|
27755
28072
|
// packages/cli/dist/tui/setup.js
|
|
27756
28073
|
import * as readline from "node:readline";
|
|
27757
28074
|
import { execSync as execSync25, spawn as spawn15 } from "node:child_process";
|
|
27758
|
-
import { existsSync as
|
|
27759
|
-
import { join as
|
|
28075
|
+
import { existsSync as existsSync29, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10 } from "node:fs";
|
|
28076
|
+
import { join as join39 } from "node:path";
|
|
27760
28077
|
import { homedir as homedir10, platform } from "node:os";
|
|
27761
28078
|
function detectSystemSpecs() {
|
|
27762
28079
|
let totalRamGB = 0;
|
|
@@ -27989,7 +28306,7 @@ async function installOllamaMac(_rl) {
|
|
|
27989
28306
|
execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
27990
28307
|
if (!hasCmd("brew")) {
|
|
27991
28308
|
try {
|
|
27992
|
-
const brewPrefix =
|
|
28309
|
+
const brewPrefix = existsSync29("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
27993
28310
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
27994
28311
|
} catch {
|
|
27995
28312
|
}
|
|
@@ -28743,10 +29060,10 @@ async function doSetup(config, rl) {
|
|
|
28743
29060
|
`PARAMETER num_predict ${numPredict}`,
|
|
28744
29061
|
`PARAMETER stop "<|endoftext|>"`
|
|
28745
29062
|
].join("\n");
|
|
28746
|
-
const modelDir2 =
|
|
28747
|
-
|
|
28748
|
-
const modelfilePath =
|
|
28749
|
-
|
|
29063
|
+
const modelDir2 = join39(homedir10(), ".open-agents", "models");
|
|
29064
|
+
mkdirSync10(modelDir2, { recursive: true });
|
|
29065
|
+
const modelfilePath = join39(modelDir2, `Modelfile.${customName}`);
|
|
29066
|
+
writeFileSync10(modelfilePath, modelfileContent + "\n", "utf8");
|
|
28750
29067
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
28751
29068
|
execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
28752
29069
|
stdio: "pipe",
|
|
@@ -28791,7 +29108,7 @@ async function isModelAvailable(config) {
|
|
|
28791
29108
|
}
|
|
28792
29109
|
function isFirstRun() {
|
|
28793
29110
|
try {
|
|
28794
|
-
return !
|
|
29111
|
+
return !existsSync29(join39(homedir10(), ".open-agents", "config.json"));
|
|
28795
29112
|
} catch {
|
|
28796
29113
|
return true;
|
|
28797
29114
|
}
|
|
@@ -28828,7 +29145,7 @@ function detectPkgManager() {
|
|
|
28828
29145
|
return null;
|
|
28829
29146
|
}
|
|
28830
29147
|
function getVenvDir() {
|
|
28831
|
-
return
|
|
29148
|
+
return join39(homedir10(), ".open-agents", "venv");
|
|
28832
29149
|
}
|
|
28833
29150
|
function hasVenvModule() {
|
|
28834
29151
|
try {
|
|
@@ -28840,8 +29157,8 @@ function hasVenvModule() {
|
|
|
28840
29157
|
}
|
|
28841
29158
|
function ensureVenv(log) {
|
|
28842
29159
|
const venvDir = getVenvDir();
|
|
28843
|
-
const venvPip =
|
|
28844
|
-
if (
|
|
29160
|
+
const venvPip = join39(venvDir, "bin", "pip");
|
|
29161
|
+
if (existsSync29(venvPip))
|
|
28845
29162
|
return venvDir;
|
|
28846
29163
|
log("Creating Python venv for vision deps...");
|
|
28847
29164
|
if (!hasCmd("python3")) {
|
|
@@ -28853,9 +29170,9 @@ function ensureVenv(log) {
|
|
|
28853
29170
|
return null;
|
|
28854
29171
|
}
|
|
28855
29172
|
try {
|
|
28856
|
-
|
|
29173
|
+
mkdirSync10(join39(homedir10(), ".open-agents"), { recursive: true });
|
|
28857
29174
|
execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
28858
|
-
execSync25(`"${
|
|
29175
|
+
execSync25(`"${join39(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
28859
29176
|
stdio: "pipe",
|
|
28860
29177
|
timeout: 6e4
|
|
28861
29178
|
});
|
|
@@ -29064,15 +29381,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
29064
29381
|
}
|
|
29065
29382
|
}
|
|
29066
29383
|
const venvDir = getVenvDir();
|
|
29067
|
-
const venvBin =
|
|
29068
|
-
const venvMoondream =
|
|
29384
|
+
const venvBin = join39(venvDir, "bin");
|
|
29385
|
+
const venvMoondream = join39(venvBin, "moondream-station");
|
|
29069
29386
|
const venv = ensureVenv(log);
|
|
29070
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
29071
|
-
const venvPip =
|
|
29387
|
+
if (venv && !hasCmd("moondream-station") && !existsSync29(venvMoondream)) {
|
|
29388
|
+
const venvPip = join39(venvBin, "pip");
|
|
29072
29389
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
29073
29390
|
try {
|
|
29074
29391
|
execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
29075
|
-
if (
|
|
29392
|
+
if (existsSync29(venvMoondream)) {
|
|
29076
29393
|
log("moondream-station installed successfully.");
|
|
29077
29394
|
} else {
|
|
29078
29395
|
try {
|
|
@@ -29089,8 +29406,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
29089
29406
|
}
|
|
29090
29407
|
}
|
|
29091
29408
|
if (venv) {
|
|
29092
|
-
const venvPython =
|
|
29093
|
-
const venvPip2 =
|
|
29409
|
+
const venvPython = join39(venvBin, "python");
|
|
29410
|
+
const venvPip2 = join39(venvBin, "pip");
|
|
29094
29411
|
let ocrStackInstalled = false;
|
|
29095
29412
|
try {
|
|
29096
29413
|
execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
@@ -29203,10 +29520,10 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
|
|
|
29203
29520
|
`PARAMETER num_predict ${numPredict}`,
|
|
29204
29521
|
`PARAMETER stop "<|endoftext|>"`
|
|
29205
29522
|
].join("\n");
|
|
29206
|
-
const modelDir2 =
|
|
29207
|
-
|
|
29208
|
-
const modelfilePath =
|
|
29209
|
-
|
|
29523
|
+
const modelDir2 = join39(homedir10(), ".open-agents", "models");
|
|
29524
|
+
mkdirSync10(modelDir2, { recursive: true });
|
|
29525
|
+
const modelfilePath = join39(modelDir2, `Modelfile.${customName}`);
|
|
29526
|
+
writeFileSync10(modelfilePath, modelfileContent + "\n", "utf8");
|
|
29210
29527
|
execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
29211
29528
|
stdio: "pipe",
|
|
29212
29529
|
timeout: 12e4
|
|
@@ -30534,17 +30851,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
30534
30851
|
try {
|
|
30535
30852
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
30536
30853
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
30537
|
-
const { dirname:
|
|
30538
|
-
const { existsSync:
|
|
30854
|
+
const { dirname: dirname19, join: join54 } = await import("node:path");
|
|
30855
|
+
const { existsSync: existsSync40 } = await import("node:fs");
|
|
30539
30856
|
const req = createRequire4(import.meta.url);
|
|
30540
|
-
const thisDir =
|
|
30857
|
+
const thisDir = dirname19(fileURLToPath14(import.meta.url));
|
|
30541
30858
|
const candidates = [
|
|
30542
|
-
|
|
30543
|
-
|
|
30544
|
-
|
|
30859
|
+
join54(thisDir, "..", "package.json"),
|
|
30860
|
+
join54(thisDir, "..", "..", "package.json"),
|
|
30861
|
+
join54(thisDir, "..", "..", "..", "package.json")
|
|
30545
30862
|
];
|
|
30546
30863
|
for (const pkgPath of candidates) {
|
|
30547
|
-
if (
|
|
30864
|
+
if (existsSync40(pkgPath)) {
|
|
30548
30865
|
const pkg = req(pkgPath);
|
|
30549
30866
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
30550
30867
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -30819,8 +31136,8 @@ var init_commands = __esm({
|
|
|
30819
31136
|
});
|
|
30820
31137
|
|
|
30821
31138
|
// packages/cli/dist/tui/project-context.js
|
|
30822
|
-
import { existsSync as
|
|
30823
|
-
import { join as
|
|
31139
|
+
import { existsSync as existsSync30, readFileSync as readFileSync21, readdirSync as readdirSync8 } from "node:fs";
|
|
31140
|
+
import { join as join40, basename as basename10 } from "node:path";
|
|
30824
31141
|
import { execSync as execSync26 } from "node:child_process";
|
|
30825
31142
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
30826
31143
|
function getModelTier(modelName) {
|
|
@@ -30855,10 +31172,10 @@ function loadProjectMap(repoRoot) {
|
|
|
30855
31172
|
if (!hasOaDirectory(repoRoot)) {
|
|
30856
31173
|
initOaDirectory(repoRoot);
|
|
30857
31174
|
}
|
|
30858
|
-
const mapPath =
|
|
30859
|
-
if (
|
|
31175
|
+
const mapPath = join40(repoRoot, OA_DIR, "context", "project-map.md");
|
|
31176
|
+
if (existsSync30(mapPath)) {
|
|
30860
31177
|
try {
|
|
30861
|
-
const content =
|
|
31178
|
+
const content = readFileSync21(mapPath, "utf-8");
|
|
30862
31179
|
return content;
|
|
30863
31180
|
} catch {
|
|
30864
31181
|
}
|
|
@@ -30899,31 +31216,31 @@ ${log}`);
|
|
|
30899
31216
|
}
|
|
30900
31217
|
function loadMemoryContext(repoRoot) {
|
|
30901
31218
|
const sections = [];
|
|
30902
|
-
const oaMemDir =
|
|
31219
|
+
const oaMemDir = join40(repoRoot, OA_DIR, "memory");
|
|
30903
31220
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
30904
31221
|
if (oaEntries)
|
|
30905
31222
|
sections.push(oaEntries);
|
|
30906
|
-
const legacyMemDir =
|
|
30907
|
-
if (legacyMemDir !== oaMemDir &&
|
|
31223
|
+
const legacyMemDir = join40(repoRoot, ".open-agents", "memory");
|
|
31224
|
+
if (legacyMemDir !== oaMemDir && existsSync30(legacyMemDir)) {
|
|
30908
31225
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
30909
31226
|
if (legacyEntries)
|
|
30910
31227
|
sections.push(legacyEntries);
|
|
30911
31228
|
}
|
|
30912
|
-
const globalMemDir =
|
|
31229
|
+
const globalMemDir = join40(homedir11(), ".open-agents", "memory");
|
|
30913
31230
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
30914
31231
|
if (globalEntries)
|
|
30915
31232
|
sections.push(globalEntries);
|
|
30916
31233
|
return sections.join("\n\n");
|
|
30917
31234
|
}
|
|
30918
31235
|
function loadMemoryDir(memDir, scope) {
|
|
30919
|
-
if (!
|
|
31236
|
+
if (!existsSync30(memDir))
|
|
30920
31237
|
return "";
|
|
30921
31238
|
const lines = [];
|
|
30922
31239
|
try {
|
|
30923
31240
|
const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
|
|
30924
31241
|
for (const file of files.slice(0, 10)) {
|
|
30925
31242
|
try {
|
|
30926
|
-
const raw =
|
|
31243
|
+
const raw = readFileSync21(join40(memDir, file), "utf-8");
|
|
30927
31244
|
const entries = JSON.parse(raw);
|
|
30928
31245
|
const topic = basename10(file, ".json");
|
|
30929
31246
|
const keys = Object.keys(entries);
|
|
@@ -31950,22 +32267,22 @@ var init_carousel = __esm({
|
|
|
31950
32267
|
});
|
|
31951
32268
|
|
|
31952
32269
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
31953
|
-
import { existsSync as
|
|
31954
|
-
import { join as
|
|
32270
|
+
import { existsSync as existsSync31, readFileSync as readFileSync22, writeFileSync as writeFileSync11, mkdirSync as mkdirSync11, readdirSync as readdirSync9 } from "node:fs";
|
|
32271
|
+
import { join as join41, basename as basename11 } from "node:path";
|
|
31955
32272
|
function loadToolProfile(repoRoot) {
|
|
31956
|
-
const filePath =
|
|
32273
|
+
const filePath = join41(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
31957
32274
|
try {
|
|
31958
|
-
if (!
|
|
32275
|
+
if (!existsSync31(filePath))
|
|
31959
32276
|
return null;
|
|
31960
|
-
return JSON.parse(
|
|
32277
|
+
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
31961
32278
|
} catch {
|
|
31962
32279
|
return null;
|
|
31963
32280
|
}
|
|
31964
32281
|
}
|
|
31965
32282
|
function saveToolProfile(repoRoot, profile) {
|
|
31966
|
-
const contextDir =
|
|
31967
|
-
|
|
31968
|
-
|
|
32283
|
+
const contextDir = join41(repoRoot, OA_DIR, "context");
|
|
32284
|
+
mkdirSync11(contextDir, { recursive: true });
|
|
32285
|
+
writeFileSync11(join41(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
31969
32286
|
}
|
|
31970
32287
|
function categorizeToolCall(toolName) {
|
|
31971
32288
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -32023,25 +32340,25 @@ function weightedColor(profile) {
|
|
|
32023
32340
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
32024
32341
|
}
|
|
32025
32342
|
function loadCachedDescriptors(repoRoot) {
|
|
32026
|
-
const filePath =
|
|
32343
|
+
const filePath = join41(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
32027
32344
|
try {
|
|
32028
|
-
if (!
|
|
32345
|
+
if (!existsSync31(filePath))
|
|
32029
32346
|
return null;
|
|
32030
|
-
const cached = JSON.parse(
|
|
32347
|
+
const cached = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
32031
32348
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
32032
32349
|
} catch {
|
|
32033
32350
|
return null;
|
|
32034
32351
|
}
|
|
32035
32352
|
}
|
|
32036
32353
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
32037
|
-
const contextDir =
|
|
32038
|
-
|
|
32354
|
+
const contextDir = join41(repoRoot, OA_DIR, "context");
|
|
32355
|
+
mkdirSync11(contextDir, { recursive: true });
|
|
32039
32356
|
const cached = {
|
|
32040
32357
|
phrases,
|
|
32041
32358
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32042
32359
|
sourceHash
|
|
32043
32360
|
};
|
|
32044
|
-
|
|
32361
|
+
writeFileSync11(join41(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
32045
32362
|
}
|
|
32046
32363
|
function generateDescriptors(repoRoot) {
|
|
32047
32364
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -32089,11 +32406,11 @@ function generateDescriptors(repoRoot) {
|
|
|
32089
32406
|
return phrases;
|
|
32090
32407
|
}
|
|
32091
32408
|
function extractFromPackageJson(repoRoot, tags) {
|
|
32092
|
-
const pkgPath =
|
|
32409
|
+
const pkgPath = join41(repoRoot, "package.json");
|
|
32093
32410
|
try {
|
|
32094
|
-
if (!
|
|
32411
|
+
if (!existsSync31(pkgPath))
|
|
32095
32412
|
return;
|
|
32096
|
-
const pkg = JSON.parse(
|
|
32413
|
+
const pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
|
|
32097
32414
|
if (pkg.name && typeof pkg.name === "string") {
|
|
32098
32415
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
32099
32416
|
for (const p of parts)
|
|
@@ -32137,7 +32454,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
32137
32454
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
32138
32455
|
];
|
|
32139
32456
|
for (const check of manifestChecks) {
|
|
32140
|
-
if (
|
|
32457
|
+
if (existsSync31(join41(repoRoot, check.file))) {
|
|
32141
32458
|
tags.push(check.tag);
|
|
32142
32459
|
}
|
|
32143
32460
|
}
|
|
@@ -32159,16 +32476,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
32159
32476
|
}
|
|
32160
32477
|
}
|
|
32161
32478
|
function extractFromMemory(repoRoot, tags) {
|
|
32162
|
-
const memoryDir =
|
|
32479
|
+
const memoryDir = join41(repoRoot, OA_DIR, "memory");
|
|
32163
32480
|
try {
|
|
32164
|
-
if (!
|
|
32481
|
+
if (!existsSync31(memoryDir))
|
|
32165
32482
|
return;
|
|
32166
32483
|
const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
|
|
32167
32484
|
for (const file of files) {
|
|
32168
32485
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
32169
32486
|
tags.push(topic);
|
|
32170
32487
|
try {
|
|
32171
|
-
const data = JSON.parse(
|
|
32488
|
+
const data = JSON.parse(readFileSync22(join41(memoryDir, file), "utf-8"));
|
|
32172
32489
|
if (data && typeof data === "object") {
|
|
32173
32490
|
const keys = Object.keys(data).slice(0, 3);
|
|
32174
32491
|
for (const key of keys) {
|
|
@@ -32303,25 +32620,25 @@ var init_carousel_descriptors = __esm({
|
|
|
32303
32620
|
});
|
|
32304
32621
|
|
|
32305
32622
|
// packages/cli/dist/tui/voice.js
|
|
32306
|
-
import { existsSync as
|
|
32307
|
-
import { join as
|
|
32623
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12, readFileSync as readFileSync23, unlinkSync as unlinkSync4 } from "node:fs";
|
|
32624
|
+
import { join as join42 } from "node:path";
|
|
32308
32625
|
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
32309
32626
|
import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
|
|
32310
32627
|
import { createRequire } from "node:module";
|
|
32311
32628
|
function voiceDir() {
|
|
32312
|
-
return
|
|
32629
|
+
return join42(homedir12(), ".open-agents", "voice");
|
|
32313
32630
|
}
|
|
32314
32631
|
function modelsDir() {
|
|
32315
|
-
return
|
|
32632
|
+
return join42(voiceDir(), "models");
|
|
32316
32633
|
}
|
|
32317
32634
|
function modelDir(id) {
|
|
32318
|
-
return
|
|
32635
|
+
return join42(modelsDir(), id);
|
|
32319
32636
|
}
|
|
32320
32637
|
function modelOnnxPath(id) {
|
|
32321
|
-
return
|
|
32638
|
+
return join42(modelDir(id), "model.onnx");
|
|
32322
32639
|
}
|
|
32323
32640
|
function modelConfigPath(id) {
|
|
32324
|
-
return
|
|
32641
|
+
return join42(modelDir(id), "config.json");
|
|
32325
32642
|
}
|
|
32326
32643
|
function emotionToPitchBias(emotion) {
|
|
32327
32644
|
const raw = emotion.valence * 0.6 + (emotion.arousal - 0.5) * 0.4;
|
|
@@ -33141,7 +33458,7 @@ var init_voice = __esm({
|
|
|
33141
33458
|
}
|
|
33142
33459
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
33143
33460
|
}
|
|
33144
|
-
const wavPath =
|
|
33461
|
+
const wavPath = join42(tmpdir6(), `oa-voice-${Date.now()}.wav`);
|
|
33145
33462
|
this.writeWav(audioData, sampleRate, wavPath);
|
|
33146
33463
|
await this.playWav(wavPath);
|
|
33147
33464
|
try {
|
|
@@ -33273,7 +33590,7 @@ var init_voice = __esm({
|
|
|
33273
33590
|
return buffer;
|
|
33274
33591
|
}
|
|
33275
33592
|
writeWav(samples, sampleRate, path) {
|
|
33276
|
-
|
|
33593
|
+
writeFileSync12(path, this.buildWavBuffer(samples, sampleRate));
|
|
33277
33594
|
}
|
|
33278
33595
|
// -------------------------------------------------------------------------
|
|
33279
33596
|
// Audio playback (system default speakers)
|
|
@@ -33432,7 +33749,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33432
33749
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
33433
33750
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
33434
33751
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
33435
|
-
const wavPath =
|
|
33752
|
+
const wavPath = join42(tmpdir6(), `oa-mlx-${Date.now()}.wav`);
|
|
33436
33753
|
const pyScript = [
|
|
33437
33754
|
"import sys, json",
|
|
33438
33755
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -33449,11 +33766,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33449
33766
|
return;
|
|
33450
33767
|
}
|
|
33451
33768
|
}
|
|
33452
|
-
if (!
|
|
33769
|
+
if (!existsSync32(wavPath))
|
|
33453
33770
|
return;
|
|
33454
33771
|
if (volume !== 1) {
|
|
33455
33772
|
try {
|
|
33456
|
-
const wavData =
|
|
33773
|
+
const wavData = readFileSync23(wavPath);
|
|
33457
33774
|
if (wavData.length > 44) {
|
|
33458
33775
|
const header = wavData.subarray(0, 44);
|
|
33459
33776
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -33461,14 +33778,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33461
33778
|
samples[i] = Math.round(samples[i] * volume);
|
|
33462
33779
|
}
|
|
33463
33780
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
33464
|
-
|
|
33781
|
+
writeFileSync12(wavPath, scaled);
|
|
33465
33782
|
}
|
|
33466
33783
|
} catch {
|
|
33467
33784
|
}
|
|
33468
33785
|
}
|
|
33469
33786
|
if (this.onPCMOutput) {
|
|
33470
33787
|
try {
|
|
33471
|
-
const wavData =
|
|
33788
|
+
const wavData = readFileSync23(wavPath);
|
|
33472
33789
|
if (wavData.length > 44) {
|
|
33473
33790
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
33474
33791
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -33500,7 +33817,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33500
33817
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
33501
33818
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
33502
33819
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
33503
|
-
const wavPath =
|
|
33820
|
+
const wavPath = join42(tmpdir6(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
33504
33821
|
const pyScript = [
|
|
33505
33822
|
"import sys, json",
|
|
33506
33823
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -33517,10 +33834,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33517
33834
|
return null;
|
|
33518
33835
|
}
|
|
33519
33836
|
}
|
|
33520
|
-
if (!
|
|
33837
|
+
if (!existsSync32(wavPath))
|
|
33521
33838
|
return null;
|
|
33522
33839
|
try {
|
|
33523
|
-
const data =
|
|
33840
|
+
const data = readFileSync23(wavPath);
|
|
33524
33841
|
unlinkSync4(wavPath);
|
|
33525
33842
|
return data;
|
|
33526
33843
|
} catch {
|
|
@@ -33534,41 +33851,41 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
33534
33851
|
if (this.ort)
|
|
33535
33852
|
return;
|
|
33536
33853
|
const arch = process.arch;
|
|
33537
|
-
|
|
33538
|
-
const pkgPath =
|
|
33854
|
+
mkdirSync12(voiceDir(), { recursive: true });
|
|
33855
|
+
const pkgPath = join42(voiceDir(), "package.json");
|
|
33539
33856
|
const expectedDeps = {
|
|
33540
33857
|
"onnxruntime-node": "^1.21.0",
|
|
33541
33858
|
"phonemizer": "^1.2.1"
|
|
33542
33859
|
};
|
|
33543
|
-
if (
|
|
33860
|
+
if (existsSync32(pkgPath)) {
|
|
33544
33861
|
try {
|
|
33545
|
-
const existing = JSON.parse(
|
|
33862
|
+
const existing = JSON.parse(readFileSync23(pkgPath, "utf8"));
|
|
33546
33863
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
33547
33864
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
33548
|
-
|
|
33865
|
+
writeFileSync12(pkgPath, JSON.stringify(existing, null, 2));
|
|
33549
33866
|
}
|
|
33550
33867
|
} catch {
|
|
33551
33868
|
}
|
|
33552
33869
|
}
|
|
33553
|
-
if (!
|
|
33554
|
-
|
|
33870
|
+
if (!existsSync32(pkgPath)) {
|
|
33871
|
+
writeFileSync12(pkgPath, JSON.stringify({
|
|
33555
33872
|
name: "open-agents-voice",
|
|
33556
33873
|
private: true,
|
|
33557
33874
|
dependencies: expectedDeps
|
|
33558
33875
|
}, null, 2));
|
|
33559
33876
|
}
|
|
33560
|
-
const voiceRequire = createRequire(
|
|
33877
|
+
const voiceRequire = createRequire(join42(voiceDir(), "index.js"));
|
|
33561
33878
|
const probeOnnx = () => {
|
|
33562
33879
|
try {
|
|
33563
|
-
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH:
|
|
33880
|
+
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join42(voiceDir(), "node_modules") } });
|
|
33564
33881
|
const output = result.toString().trim();
|
|
33565
33882
|
return output === "OK";
|
|
33566
33883
|
} catch {
|
|
33567
33884
|
return false;
|
|
33568
33885
|
}
|
|
33569
33886
|
};
|
|
33570
|
-
const onnxNodeModules =
|
|
33571
|
-
const onnxInstalled =
|
|
33887
|
+
const onnxNodeModules = join42(voiceDir(), "node_modules", "onnxruntime-node");
|
|
33888
|
+
const onnxInstalled = existsSync32(onnxNodeModules);
|
|
33572
33889
|
if (onnxInstalled && !probeOnnx()) {
|
|
33573
33890
|
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.`);
|
|
33574
33891
|
}
|
|
@@ -33626,18 +33943,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
33626
33943
|
const dir = modelDir(id);
|
|
33627
33944
|
const onnxPath = modelOnnxPath(id);
|
|
33628
33945
|
const configPath = modelConfigPath(id);
|
|
33629
|
-
if (
|
|
33946
|
+
if (existsSync32(onnxPath) && existsSync32(configPath))
|
|
33630
33947
|
return;
|
|
33631
|
-
|
|
33632
|
-
if (!
|
|
33948
|
+
mkdirSync12(dir, { recursive: true });
|
|
33949
|
+
if (!existsSync32(configPath)) {
|
|
33633
33950
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
33634
33951
|
const configResp = await fetch(model.configUrl);
|
|
33635
33952
|
if (!configResp.ok)
|
|
33636
33953
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
33637
33954
|
const configText = await configResp.text();
|
|
33638
|
-
|
|
33955
|
+
writeFileSync12(configPath, configText);
|
|
33639
33956
|
}
|
|
33640
|
-
if (!
|
|
33957
|
+
if (!existsSync32(onnxPath)) {
|
|
33641
33958
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
33642
33959
|
const onnxResp = await fetch(model.onnxUrl);
|
|
33643
33960
|
if (!onnxResp.ok)
|
|
@@ -33662,7 +33979,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
33662
33979
|
}
|
|
33663
33980
|
}
|
|
33664
33981
|
const fullBuffer = Buffer.concat(chunks);
|
|
33665
|
-
|
|
33982
|
+
writeFileSync12(onnxPath, fullBuffer);
|
|
33666
33983
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
33667
33984
|
}
|
|
33668
33985
|
}
|
|
@@ -33674,10 +33991,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
33674
33991
|
throw new Error("ONNX runtime not loaded");
|
|
33675
33992
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
33676
33993
|
const configPath = modelConfigPath(this.modelId);
|
|
33677
|
-
if (!
|
|
33994
|
+
if (!existsSync32(onnxPath) || !existsSync32(configPath)) {
|
|
33678
33995
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
33679
33996
|
}
|
|
33680
|
-
this.config = JSON.parse(
|
|
33997
|
+
this.config = JSON.parse(readFileSync23(configPath, "utf8"));
|
|
33681
33998
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
33682
33999
|
executionProviders: ["cpu"],
|
|
33683
34000
|
graphOptimizationLevel: "all"
|
|
@@ -34538,13 +34855,13 @@ var init_stream_renderer = __esm({
|
|
|
34538
34855
|
});
|
|
34539
34856
|
|
|
34540
34857
|
// packages/cli/dist/tui/edit-history.js
|
|
34541
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
34542
|
-
import { join as
|
|
34858
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync13 } from "node:fs";
|
|
34859
|
+
import { join as join43 } from "node:path";
|
|
34543
34860
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
34544
|
-
const historyDir =
|
|
34545
|
-
const logPath =
|
|
34861
|
+
const historyDir = join43(repoRoot, ".oa", "history");
|
|
34862
|
+
const logPath = join43(historyDir, "edits.jsonl");
|
|
34546
34863
|
try {
|
|
34547
|
-
|
|
34864
|
+
mkdirSync13(historyDir, { recursive: true });
|
|
34548
34865
|
} catch {
|
|
34549
34866
|
}
|
|
34550
34867
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -34653,46 +34970,46 @@ var init_edit_history = __esm({
|
|
|
34653
34970
|
});
|
|
34654
34971
|
|
|
34655
34972
|
// packages/cli/dist/tui/promptLoader.js
|
|
34656
|
-
import { readFileSync as
|
|
34657
|
-
import { join as
|
|
34973
|
+
import { readFileSync as readFileSync24, existsSync as existsSync33 } from "node:fs";
|
|
34974
|
+
import { join as join44, dirname as dirname16 } from "node:path";
|
|
34658
34975
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
34659
34976
|
function loadPrompt3(promptPath, vars) {
|
|
34660
34977
|
let content = cache3.get(promptPath);
|
|
34661
34978
|
if (content === void 0) {
|
|
34662
|
-
const fullPath =
|
|
34663
|
-
if (!
|
|
34979
|
+
const fullPath = join44(PROMPTS_DIR3, promptPath);
|
|
34980
|
+
if (!existsSync33(fullPath)) {
|
|
34664
34981
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
34665
34982
|
}
|
|
34666
|
-
content =
|
|
34983
|
+
content = readFileSync24(fullPath, "utf-8");
|
|
34667
34984
|
cache3.set(promptPath, content);
|
|
34668
34985
|
}
|
|
34669
34986
|
if (!vars)
|
|
34670
34987
|
return content;
|
|
34671
34988
|
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
34672
34989
|
}
|
|
34673
|
-
var __filename3,
|
|
34990
|
+
var __filename3, __dirname6, devPath2, publishedPath2, PROMPTS_DIR3, cache3;
|
|
34674
34991
|
var init_promptLoader3 = __esm({
|
|
34675
34992
|
"packages/cli/dist/tui/promptLoader.js"() {
|
|
34676
34993
|
"use strict";
|
|
34677
34994
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
34678
|
-
|
|
34679
|
-
devPath2 =
|
|
34680
|
-
publishedPath2 =
|
|
34681
|
-
PROMPTS_DIR3 =
|
|
34995
|
+
__dirname6 = dirname16(__filename3);
|
|
34996
|
+
devPath2 = join44(__dirname6, "..", "..", "prompts");
|
|
34997
|
+
publishedPath2 = join44(__dirname6, "..", "prompts");
|
|
34998
|
+
PROMPTS_DIR3 = existsSync33(devPath2) ? devPath2 : publishedPath2;
|
|
34682
34999
|
cache3 = /* @__PURE__ */ new Map();
|
|
34683
35000
|
}
|
|
34684
35001
|
});
|
|
34685
35002
|
|
|
34686
35003
|
// packages/cli/dist/tui/dream-engine.js
|
|
34687
|
-
import { mkdirSync as
|
|
34688
|
-
import { join as
|
|
35004
|
+
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync13, readFileSync as readFileSync25, existsSync as existsSync34, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
|
|
35005
|
+
import { join as join45, basename as basename12 } from "node:path";
|
|
34689
35006
|
import { execSync as execSync28 } from "node:child_process";
|
|
34690
35007
|
function loadAutoresearchMemory(repoRoot) {
|
|
34691
|
-
const memoryPath =
|
|
34692
|
-
if (!
|
|
35008
|
+
const memoryPath = join45(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
35009
|
+
if (!existsSync34(memoryPath))
|
|
34693
35010
|
return "";
|
|
34694
35011
|
try {
|
|
34695
|
-
const raw =
|
|
35012
|
+
const raw = readFileSync25(memoryPath, "utf-8");
|
|
34696
35013
|
const data = JSON.parse(raw);
|
|
34697
35014
|
const sections = [];
|
|
34698
35015
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -34882,14 +35199,14 @@ var init_dream_engine = __esm({
|
|
|
34882
35199
|
const content = String(args["content"] ?? "");
|
|
34883
35200
|
if (!rawPath)
|
|
34884
35201
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
34885
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
35202
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join45(this.autoresearchDir, basename12(rawPath)) : join45(this.autoresearchDir, rawPath);
|
|
34886
35203
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
34887
35204
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
34888
35205
|
}
|
|
34889
35206
|
try {
|
|
34890
|
-
const dir =
|
|
34891
|
-
|
|
34892
|
-
|
|
35207
|
+
const dir = join45(targetPath, "..");
|
|
35208
|
+
mkdirSync14(dir, { recursive: true });
|
|
35209
|
+
writeFileSync13(targetPath, content, "utf-8");
|
|
34893
35210
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
34894
35211
|
} catch (err) {
|
|
34895
35212
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -34917,20 +35234,20 @@ var init_dream_engine = __esm({
|
|
|
34917
35234
|
const rawPath = String(args["path"] ?? "");
|
|
34918
35235
|
const oldStr = String(args["old_string"] ?? "");
|
|
34919
35236
|
const newStr = String(args["new_string"] ?? "");
|
|
34920
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
35237
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join45(this.autoresearchDir, basename12(rawPath)) : join45(this.autoresearchDir, rawPath);
|
|
34921
35238
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
34922
35239
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
34923
35240
|
}
|
|
34924
35241
|
try {
|
|
34925
|
-
if (!
|
|
35242
|
+
if (!existsSync34(targetPath)) {
|
|
34926
35243
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
34927
35244
|
}
|
|
34928
|
-
let content =
|
|
35245
|
+
let content = readFileSync25(targetPath, "utf-8");
|
|
34929
35246
|
if (!content.includes(oldStr)) {
|
|
34930
35247
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
34931
35248
|
}
|
|
34932
35249
|
content = content.replace(oldStr, newStr);
|
|
34933
|
-
|
|
35250
|
+
writeFileSync13(targetPath, content, "utf-8");
|
|
34934
35251
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
34935
35252
|
} catch (err) {
|
|
34936
35253
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -34971,14 +35288,14 @@ var init_dream_engine = __esm({
|
|
|
34971
35288
|
const content = String(args["content"] ?? "");
|
|
34972
35289
|
if (!rawPath)
|
|
34973
35290
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
34974
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
35291
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join45(this.dreamsDir, basename12(rawPath)) : join45(this.dreamsDir, rawPath);
|
|
34975
35292
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
34976
35293
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
34977
35294
|
}
|
|
34978
35295
|
try {
|
|
34979
|
-
const dir =
|
|
34980
|
-
|
|
34981
|
-
|
|
35296
|
+
const dir = join45(targetPath, "..");
|
|
35297
|
+
mkdirSync14(dir, { recursive: true });
|
|
35298
|
+
writeFileSync13(targetPath, content, "utf-8");
|
|
34982
35299
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
34983
35300
|
} catch (err) {
|
|
34984
35301
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -35006,20 +35323,20 @@ var init_dream_engine = __esm({
|
|
|
35006
35323
|
const rawPath = String(args["path"] ?? "");
|
|
35007
35324
|
const oldStr = String(args["old_string"] ?? "");
|
|
35008
35325
|
const newStr = String(args["new_string"] ?? "");
|
|
35009
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
35326
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join45(this.dreamsDir, basename12(rawPath)) : join45(this.dreamsDir, rawPath);
|
|
35010
35327
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
35011
35328
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
35012
35329
|
}
|
|
35013
35330
|
try {
|
|
35014
|
-
if (!
|
|
35331
|
+
if (!existsSync34(targetPath)) {
|
|
35015
35332
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
35016
35333
|
}
|
|
35017
|
-
let content =
|
|
35334
|
+
let content = readFileSync25(targetPath, "utf-8");
|
|
35018
35335
|
if (!content.includes(oldStr)) {
|
|
35019
35336
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
35020
35337
|
}
|
|
35021
35338
|
content = content.replace(oldStr, newStr);
|
|
35022
|
-
|
|
35339
|
+
writeFileSync13(targetPath, content, "utf-8");
|
|
35023
35340
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
35024
35341
|
} catch (err) {
|
|
35025
35342
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -35073,7 +35390,7 @@ var init_dream_engine = __esm({
|
|
|
35073
35390
|
constructor(config, repoRoot) {
|
|
35074
35391
|
this.config = config;
|
|
35075
35392
|
this.repoRoot = repoRoot;
|
|
35076
|
-
this.dreamsDir =
|
|
35393
|
+
this.dreamsDir = join45(repoRoot, ".oa", "dreams");
|
|
35077
35394
|
this.state = {
|
|
35078
35395
|
mode: "default",
|
|
35079
35396
|
active: false,
|
|
@@ -35104,7 +35421,7 @@ var init_dream_engine = __esm({
|
|
|
35104
35421
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35105
35422
|
results: []
|
|
35106
35423
|
};
|
|
35107
|
-
|
|
35424
|
+
mkdirSync14(this.dreamsDir, { recursive: true });
|
|
35108
35425
|
this.saveDreamState();
|
|
35109
35426
|
try {
|
|
35110
35427
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -35157,8 +35474,8 @@ ${result.summary}`;
|
|
|
35157
35474
|
if (mode !== "default" || cycle === totalCycles) {
|
|
35158
35475
|
renderDreamContraction(cycle);
|
|
35159
35476
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
35160
|
-
const summaryPath =
|
|
35161
|
-
|
|
35477
|
+
const summaryPath = join45(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
35478
|
+
writeFileSync13(summaryPath, cycleSummary, "utf-8");
|
|
35162
35479
|
}
|
|
35163
35480
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
35164
35481
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -35370,7 +35687,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
35370
35687
|
}
|
|
35371
35688
|
/** Build role-specific tool sets for swarm agents */
|
|
35372
35689
|
buildSwarmTools(role, _workspace) {
|
|
35373
|
-
const autoresearchDir =
|
|
35690
|
+
const autoresearchDir = join45(this.repoRoot, ".oa", "autoresearch");
|
|
35374
35691
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
35375
35692
|
switch (role) {
|
|
35376
35693
|
case "researcher": {
|
|
@@ -35734,7 +36051,7 @@ INSTRUCTIONS:
|
|
|
35734
36051
|
2. Summarize the key learnings and next steps
|
|
35735
36052
|
|
|
35736
36053
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
35737
|
-
const reportPath =
|
|
36054
|
+
const reportPath = join45(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
35738
36055
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
35739
36056
|
|
|
35740
36057
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -35756,8 +36073,8 @@ ${summaryResult}
|
|
|
35756
36073
|
*Generated by open-agents autoresearch swarm*
|
|
35757
36074
|
`;
|
|
35758
36075
|
try {
|
|
35759
|
-
|
|
35760
|
-
|
|
36076
|
+
mkdirSync14(this.dreamsDir, { recursive: true });
|
|
36077
|
+
writeFileSync13(reportPath, report, "utf-8");
|
|
35761
36078
|
} catch {
|
|
35762
36079
|
}
|
|
35763
36080
|
renderSwarmComplete(workspace);
|
|
@@ -35823,9 +36140,9 @@ ${summaryResult}
|
|
|
35823
36140
|
}
|
|
35824
36141
|
/** Save workspace backup for lucid mode */
|
|
35825
36142
|
saveVersionCheckpoint(cycle) {
|
|
35826
|
-
const checkpointDir =
|
|
36143
|
+
const checkpointDir = join45(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
35827
36144
|
try {
|
|
35828
|
-
|
|
36145
|
+
mkdirSync14(checkpointDir, { recursive: true });
|
|
35829
36146
|
try {
|
|
35830
36147
|
const gitStatus = execSync28("git status --porcelain", {
|
|
35831
36148
|
cwd: this.repoRoot,
|
|
@@ -35842,10 +36159,10 @@ ${summaryResult}
|
|
|
35842
36159
|
encoding: "utf-8",
|
|
35843
36160
|
timeout: 5e3
|
|
35844
36161
|
}).trim();
|
|
35845
|
-
|
|
35846
|
-
|
|
35847
|
-
|
|
35848
|
-
|
|
36162
|
+
writeFileSync13(join45(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
36163
|
+
writeFileSync13(join45(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
36164
|
+
writeFileSync13(join45(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
36165
|
+
writeFileSync13(join45(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
35849
36166
|
cycle,
|
|
35850
36167
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35851
36168
|
gitHash,
|
|
@@ -35853,7 +36170,7 @@ ${summaryResult}
|
|
|
35853
36170
|
}, null, 2), "utf-8");
|
|
35854
36171
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
35855
36172
|
} catch {
|
|
35856
|
-
|
|
36173
|
+
writeFileSync13(join45(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
35857
36174
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
35858
36175
|
}
|
|
35859
36176
|
} catch (err) {
|
|
@@ -35911,14 +36228,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
35911
36228
|
---
|
|
35912
36229
|
*Auto-generated by open-agents dream engine*
|
|
35913
36230
|
`;
|
|
35914
|
-
|
|
36231
|
+
writeFileSync13(join45(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
35915
36232
|
} catch {
|
|
35916
36233
|
}
|
|
35917
36234
|
}
|
|
35918
36235
|
/** Save dream state for resume/inspection */
|
|
35919
36236
|
saveDreamState() {
|
|
35920
36237
|
try {
|
|
35921
|
-
|
|
36238
|
+
writeFileSync13(join45(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
35922
36239
|
} catch {
|
|
35923
36240
|
}
|
|
35924
36241
|
}
|
|
@@ -36292,8 +36609,8 @@ var init_bless_engine = __esm({
|
|
|
36292
36609
|
});
|
|
36293
36610
|
|
|
36294
36611
|
// packages/cli/dist/tui/dmn-engine.js
|
|
36295
|
-
import { existsSync as
|
|
36296
|
-
import { join as
|
|
36612
|
+
import { existsSync as existsSync35, readFileSync as readFileSync26, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
|
|
36613
|
+
import { join as join46, basename as basename13 } from "node:path";
|
|
36297
36614
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
36298
36615
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
36299
36616
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -36406,9 +36723,9 @@ var init_dmn_engine = __esm({
|
|
|
36406
36723
|
constructor(config, repoRoot) {
|
|
36407
36724
|
this.config = config;
|
|
36408
36725
|
this.repoRoot = repoRoot;
|
|
36409
|
-
this.stateDir =
|
|
36410
|
-
this.historyDir =
|
|
36411
|
-
|
|
36726
|
+
this.stateDir = join46(repoRoot, ".oa", "dmn");
|
|
36727
|
+
this.historyDir = join46(repoRoot, ".oa", "dmn", "cycles");
|
|
36728
|
+
mkdirSync15(this.historyDir, { recursive: true });
|
|
36412
36729
|
this.loadState();
|
|
36413
36730
|
}
|
|
36414
36731
|
get stats() {
|
|
@@ -36997,11 +37314,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
36997
37314
|
async gatherMemoryTopics() {
|
|
36998
37315
|
const topics = [];
|
|
36999
37316
|
const dirs = [
|
|
37000
|
-
|
|
37001
|
-
|
|
37317
|
+
join46(this.repoRoot, ".oa", "memory"),
|
|
37318
|
+
join46(this.repoRoot, ".open-agents", "memory")
|
|
37002
37319
|
];
|
|
37003
37320
|
for (const dir of dirs) {
|
|
37004
|
-
if (!
|
|
37321
|
+
if (!existsSync35(dir))
|
|
37005
37322
|
continue;
|
|
37006
37323
|
try {
|
|
37007
37324
|
const files = readdirSync11(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -37017,29 +37334,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
37017
37334
|
}
|
|
37018
37335
|
// ── State persistence ─────────────────────────────────────────────────
|
|
37019
37336
|
loadState() {
|
|
37020
|
-
const path =
|
|
37021
|
-
if (
|
|
37337
|
+
const path = join46(this.stateDir, "state.json");
|
|
37338
|
+
if (existsSync35(path)) {
|
|
37022
37339
|
try {
|
|
37023
|
-
this.state = JSON.parse(
|
|
37340
|
+
this.state = JSON.parse(readFileSync26(path, "utf-8"));
|
|
37024
37341
|
} catch {
|
|
37025
37342
|
}
|
|
37026
37343
|
}
|
|
37027
37344
|
}
|
|
37028
37345
|
saveState() {
|
|
37029
37346
|
try {
|
|
37030
|
-
|
|
37347
|
+
writeFileSync14(join46(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
37031
37348
|
} catch {
|
|
37032
37349
|
}
|
|
37033
37350
|
}
|
|
37034
37351
|
saveCycleResult(result) {
|
|
37035
37352
|
try {
|
|
37036
37353
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
37037
|
-
|
|
37354
|
+
writeFileSync14(join46(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
37038
37355
|
const files = readdirSync11(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
37039
37356
|
if (files.length > 50) {
|
|
37040
37357
|
for (const old of files.slice(0, files.length - 50)) {
|
|
37041
37358
|
try {
|
|
37042
|
-
unlinkSync5(
|
|
37359
|
+
unlinkSync5(join46(this.historyDir, old));
|
|
37043
37360
|
} catch {
|
|
37044
37361
|
}
|
|
37045
37362
|
}
|
|
@@ -37052,8 +37369,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
37052
37369
|
});
|
|
37053
37370
|
|
|
37054
37371
|
// packages/cli/dist/tui/snr-engine.js
|
|
37055
|
-
import { existsSync as
|
|
37056
|
-
import { join as
|
|
37372
|
+
import { existsSync as existsSync36, readdirSync as readdirSync12, readFileSync as readFileSync27 } from "node:fs";
|
|
37373
|
+
import { join as join47, basename as basename14 } from "node:path";
|
|
37057
37374
|
function computeDPrime(signalScores, noiseScores) {
|
|
37058
37375
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
37059
37376
|
return 0;
|
|
@@ -37293,11 +37610,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
37293
37610
|
loadMemoryEntries(topics) {
|
|
37294
37611
|
const entries = [];
|
|
37295
37612
|
const dirs = [
|
|
37296
|
-
|
|
37297
|
-
|
|
37613
|
+
join47(this.repoRoot, ".oa", "memory"),
|
|
37614
|
+
join47(this.repoRoot, ".open-agents", "memory")
|
|
37298
37615
|
];
|
|
37299
37616
|
for (const dir of dirs) {
|
|
37300
|
-
if (!
|
|
37617
|
+
if (!existsSync36(dir))
|
|
37301
37618
|
continue;
|
|
37302
37619
|
try {
|
|
37303
37620
|
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -37306,7 +37623,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
37306
37623
|
if (topics.length > 0 && !topics.includes(topic))
|
|
37307
37624
|
continue;
|
|
37308
37625
|
try {
|
|
37309
|
-
const data = JSON.parse(
|
|
37626
|
+
const data = JSON.parse(readFileSync27(join47(dir, f), "utf-8"));
|
|
37310
37627
|
for (const [key, val] of Object.entries(data)) {
|
|
37311
37628
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
37312
37629
|
entries.push({ topic, key, value });
|
|
@@ -37857,8 +38174,8 @@ var init_tool_policy = __esm({
|
|
|
37857
38174
|
});
|
|
37858
38175
|
|
|
37859
38176
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
37860
|
-
import { mkdirSync as
|
|
37861
|
-
import { join as
|
|
38177
|
+
import { mkdirSync as mkdirSync16, existsSync as existsSync37, unlinkSync as unlinkSync6, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
|
|
38178
|
+
import { join as join48, resolve as resolve27 } from "node:path";
|
|
37862
38179
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
37863
38180
|
function convertMarkdownToTelegramHTML(md) {
|
|
37864
38181
|
let html = md;
|
|
@@ -38186,7 +38503,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
38186
38503
|
this.polling = true;
|
|
38187
38504
|
this.abortController = new AbortController();
|
|
38188
38505
|
try {
|
|
38189
|
-
|
|
38506
|
+
mkdirSync16(this.mediaCacheDir, { recursive: true });
|
|
38190
38507
|
} catch {
|
|
38191
38508
|
}
|
|
38192
38509
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -38623,7 +38940,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
38623
38940
|
return null;
|
|
38624
38941
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
38625
38942
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
38626
|
-
const localPath =
|
|
38943
|
+
const localPath = join48(this.mediaCacheDir, fileName);
|
|
38627
38944
|
await writeFileAsync(localPath, buffer);
|
|
38628
38945
|
return localPath;
|
|
38629
38946
|
} catch {
|
|
@@ -40360,11 +40677,11 @@ var init_status_bar = __esm({
|
|
|
40360
40677
|
import * as readline2 from "node:readline";
|
|
40361
40678
|
import { Writable } from "node:stream";
|
|
40362
40679
|
import { cwd } from "node:process";
|
|
40363
|
-
import { resolve as resolve28, join as
|
|
40680
|
+
import { resolve as resolve28, join as join49, dirname as dirname17, extname as extname9 } from "node:path";
|
|
40364
40681
|
import { createRequire as createRequire2 } from "node:module";
|
|
40365
40682
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
40366
|
-
import { readFileSync as
|
|
40367
|
-
import { existsSync as
|
|
40683
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync15, appendFileSync as appendFileSync3, rmSync as rmSync2, readdirSync as readdirSync14, mkdirSync as mkdirSync17 } from "node:fs";
|
|
40684
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
40368
40685
|
import { homedir as homedir13 } from "node:os";
|
|
40369
40686
|
function formatTimeAgo(date) {
|
|
40370
40687
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -40382,14 +40699,14 @@ function formatTimeAgo(date) {
|
|
|
40382
40699
|
function getVersion3() {
|
|
40383
40700
|
try {
|
|
40384
40701
|
const require2 = createRequire2(import.meta.url);
|
|
40385
|
-
const thisDir =
|
|
40702
|
+
const thisDir = dirname17(fileURLToPath12(import.meta.url));
|
|
40386
40703
|
const candidates = [
|
|
40387
|
-
|
|
40388
|
-
|
|
40389
|
-
|
|
40704
|
+
join49(thisDir, "..", "package.json"),
|
|
40705
|
+
join49(thisDir, "..", "..", "package.json"),
|
|
40706
|
+
join49(thisDir, "..", "..", "..", "package.json")
|
|
40390
40707
|
];
|
|
40391
40708
|
for (const pkgPath of candidates) {
|
|
40392
|
-
if (
|
|
40709
|
+
if (existsSync38(pkgPath)) {
|
|
40393
40710
|
const pkg = require2(pkgPath);
|
|
40394
40711
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
40395
40712
|
return pkg.version ?? "0.0.0";
|
|
@@ -40595,15 +40912,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
40595
40912
|
function gatherMemorySnippets(root) {
|
|
40596
40913
|
const snippets = [];
|
|
40597
40914
|
const dirs = [
|
|
40598
|
-
|
|
40599
|
-
|
|
40915
|
+
join49(root, ".oa", "memory"),
|
|
40916
|
+
join49(root, ".open-agents", "memory")
|
|
40600
40917
|
];
|
|
40601
40918
|
for (const dir of dirs) {
|
|
40602
|
-
if (!
|
|
40919
|
+
if (!existsSync38(dir))
|
|
40603
40920
|
continue;
|
|
40604
40921
|
try {
|
|
40605
40922
|
for (const f of readdirSync14(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
40606
|
-
const data = JSON.parse(
|
|
40923
|
+
const data = JSON.parse(readFileSync28(join49(dir, f), "utf-8"));
|
|
40607
40924
|
for (const val of Object.values(data)) {
|
|
40608
40925
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
40609
40926
|
if (v.length > 10)
|
|
@@ -40778,6 +41095,19 @@ ${entry.fullContent}`
|
|
|
40778
41095
|
};
|
|
40779
41096
|
}
|
|
40780
41097
|
});
|
|
41098
|
+
{
|
|
41099
|
+
const llmCall = async (messages) => {
|
|
41100
|
+
const resp = await backend.chatCompletion({
|
|
41101
|
+
messages: messages.map((m) => ({ role: m.role, content: m.content })),
|
|
41102
|
+
tools: [],
|
|
41103
|
+
temperature: 0,
|
|
41104
|
+
maxTokens: 8192,
|
|
41105
|
+
timeoutMs: 12e4
|
|
41106
|
+
});
|
|
41107
|
+
return resp.choices[0]?.message?.content ?? "";
|
|
41108
|
+
};
|
|
41109
|
+
runner.registerTool(new SkillBuildTool(repoRoot, llmCall));
|
|
41110
|
+
}
|
|
40781
41111
|
if (slashCommandHandler) {
|
|
40782
41112
|
runner.registerTool({
|
|
40783
41113
|
name: "slash_command",
|
|
@@ -41338,7 +41668,7 @@ async function startInteractive(config, repoPath) {
|
|
|
41338
41668
|
let exposeGateway = null;
|
|
41339
41669
|
let peerMesh = null;
|
|
41340
41670
|
let inferenceRouter = null;
|
|
41341
|
-
const secretVault = new SecretVault(
|
|
41671
|
+
const secretVault = new SecretVault(join49(repoRoot, ".oa", "vault.enc"));
|
|
41342
41672
|
let adminSessionKey = null;
|
|
41343
41673
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
41344
41674
|
const streamRenderer = new StreamRenderer();
|
|
@@ -41543,13 +41873,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
41543
41873
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
41544
41874
|
return [hits, line];
|
|
41545
41875
|
}
|
|
41546
|
-
const HISTORY_DIR =
|
|
41547
|
-
const HISTORY_FILE =
|
|
41876
|
+
const HISTORY_DIR = join49(homedir13(), ".open-agents");
|
|
41877
|
+
const HISTORY_FILE = join49(HISTORY_DIR, "repl-history");
|
|
41548
41878
|
const MAX_HISTORY_LINES = 500;
|
|
41549
41879
|
let savedHistory = [];
|
|
41550
41880
|
try {
|
|
41551
|
-
if (
|
|
41552
|
-
const raw =
|
|
41881
|
+
if (existsSync38(HISTORY_FILE)) {
|
|
41882
|
+
const raw = readFileSync28(HISTORY_FILE, "utf8").trim();
|
|
41553
41883
|
if (raw)
|
|
41554
41884
|
savedHistory = raw.split("\n").reverse();
|
|
41555
41885
|
}
|
|
@@ -41568,12 +41898,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
41568
41898
|
if (!line.trim())
|
|
41569
41899
|
return;
|
|
41570
41900
|
try {
|
|
41571
|
-
|
|
41901
|
+
mkdirSync17(HISTORY_DIR, { recursive: true });
|
|
41572
41902
|
appendFileSync3(HISTORY_FILE, line + "\n", "utf8");
|
|
41573
41903
|
if (Math.random() < 0.02) {
|
|
41574
|
-
const all =
|
|
41904
|
+
const all = readFileSync28(HISTORY_FILE, "utf8").trim().split("\n");
|
|
41575
41905
|
if (all.length > MAX_HISTORY_LINES) {
|
|
41576
|
-
|
|
41906
|
+
writeFileSync15(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
41577
41907
|
}
|
|
41578
41908
|
}
|
|
41579
41909
|
} catch {
|
|
@@ -42433,8 +42763,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
42433
42763
|
return true;
|
|
42434
42764
|
},
|
|
42435
42765
|
destroyProject() {
|
|
42436
|
-
const oaPath =
|
|
42437
|
-
if (
|
|
42766
|
+
const oaPath = join49(repoRoot, OA_DIR);
|
|
42767
|
+
if (existsSync38(oaPath)) {
|
|
42438
42768
|
try {
|
|
42439
42769
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
42440
42770
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -42765,13 +43095,13 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
42765
43095
|
}
|
|
42766
43096
|
}
|
|
42767
43097
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
42768
|
-
const isImage = isImagePath(cleanPath) &&
|
|
42769
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
43098
|
+
const isImage = isImagePath(cleanPath) && existsSync38(resolve28(repoRoot, cleanPath));
|
|
43099
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync38(resolve28(repoRoot, cleanPath));
|
|
42770
43100
|
if (activeTask) {
|
|
42771
43101
|
if (isImage) {
|
|
42772
43102
|
try {
|
|
42773
43103
|
const imgPath = resolve28(repoRoot, cleanPath);
|
|
42774
|
-
const imgBuffer =
|
|
43104
|
+
const imgBuffer = readFileSync28(imgPath);
|
|
42775
43105
|
const base64 = imgBuffer.toString("base64");
|
|
42776
43106
|
const ext = extname9(cleanPath).toLowerCase();
|
|
42777
43107
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -43285,7 +43615,7 @@ import { glob } from "glob";
|
|
|
43285
43615
|
import ignore from "ignore";
|
|
43286
43616
|
import { readFile as readFile16, stat as stat4 } from "node:fs/promises";
|
|
43287
43617
|
import { createHash as createHash4 } from "node:crypto";
|
|
43288
|
-
import { join as
|
|
43618
|
+
import { join as join50, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
|
|
43289
43619
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
43290
43620
|
var init_codebase_indexer = __esm({
|
|
43291
43621
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -43329,7 +43659,7 @@ var init_codebase_indexer = __esm({
|
|
|
43329
43659
|
const ig = ignore.default();
|
|
43330
43660
|
if (this.config.respectGitignore) {
|
|
43331
43661
|
try {
|
|
43332
|
-
const gitignoreContent = await readFile16(
|
|
43662
|
+
const gitignoreContent = await readFile16(join50(this.config.rootDir, ".gitignore"), "utf-8");
|
|
43333
43663
|
ig.add(gitignoreContent);
|
|
43334
43664
|
} catch {
|
|
43335
43665
|
}
|
|
@@ -43344,7 +43674,7 @@ var init_codebase_indexer = __esm({
|
|
|
43344
43674
|
for (const relativePath of files) {
|
|
43345
43675
|
if (ig.ignores(relativePath))
|
|
43346
43676
|
continue;
|
|
43347
|
-
const fullPath =
|
|
43677
|
+
const fullPath = join50(this.config.rootDir, relativePath);
|
|
43348
43678
|
try {
|
|
43349
43679
|
const fileStat = await stat4(fullPath);
|
|
43350
43680
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -43390,7 +43720,7 @@ var init_codebase_indexer = __esm({
|
|
|
43390
43720
|
if (!child) {
|
|
43391
43721
|
child = {
|
|
43392
43722
|
name: part,
|
|
43393
|
-
path:
|
|
43723
|
+
path: join50(current.path, part),
|
|
43394
43724
|
type: "directory",
|
|
43395
43725
|
children: []
|
|
43396
43726
|
};
|
|
@@ -43473,13 +43803,13 @@ __export(index_repo_exports, {
|
|
|
43473
43803
|
indexRepoCommand: () => indexRepoCommand
|
|
43474
43804
|
});
|
|
43475
43805
|
import { resolve as resolve29 } from "node:path";
|
|
43476
|
-
import { existsSync as
|
|
43806
|
+
import { existsSync as existsSync39, statSync as statSync11 } from "node:fs";
|
|
43477
43807
|
import { cwd as cwd2 } from "node:process";
|
|
43478
43808
|
async function indexRepoCommand(opts, _config) {
|
|
43479
43809
|
const repoRoot = resolve29(opts.repoPath ?? cwd2());
|
|
43480
43810
|
printHeader("Index Repository");
|
|
43481
43811
|
printInfo(`Indexing: ${repoRoot}`);
|
|
43482
|
-
if (!
|
|
43812
|
+
if (!existsSync39(repoRoot)) {
|
|
43483
43813
|
printError(`Path does not exist: ${repoRoot}`);
|
|
43484
43814
|
process.exit(1);
|
|
43485
43815
|
}
|
|
@@ -43731,7 +44061,7 @@ var config_exports = {};
|
|
|
43731
44061
|
__export(config_exports, {
|
|
43732
44062
|
configCommand: () => configCommand
|
|
43733
44063
|
});
|
|
43734
|
-
import { join as
|
|
44064
|
+
import { join as join51, resolve as resolve30 } from "node:path";
|
|
43735
44065
|
import { homedir as homedir14 } from "node:os";
|
|
43736
44066
|
import { cwd as cwd3 } from "node:process";
|
|
43737
44067
|
function redactIfSensitive(key, value) {
|
|
@@ -43790,7 +44120,7 @@ function handleShow(opts, config) {
|
|
|
43790
44120
|
}
|
|
43791
44121
|
}
|
|
43792
44122
|
printSection("Config File");
|
|
43793
|
-
printInfo(`~/.open-agents/config.json (${
|
|
44123
|
+
printInfo(`~/.open-agents/config.json (${join51(homedir14(), ".open-agents", "config.json")})`);
|
|
43794
44124
|
printSection("Priority Chain");
|
|
43795
44125
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
43796
44126
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -43829,7 +44159,7 @@ function handleSet(opts, _config) {
|
|
|
43829
44159
|
const coerced = coerceForSettings(key, value);
|
|
43830
44160
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
43831
44161
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
43832
|
-
printInfo(`Saved to ${
|
|
44162
|
+
printInfo(`Saved to ${join51(repoRoot, ".oa", "settings.json")}`);
|
|
43833
44163
|
printInfo("This override applies only when running in this workspace.");
|
|
43834
44164
|
} catch (err) {
|
|
43835
44165
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -44048,8 +44378,8 @@ __export(eval_exports, {
|
|
|
44048
44378
|
evalCommand: () => evalCommand
|
|
44049
44379
|
});
|
|
44050
44380
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
44051
|
-
import { mkdirSync as
|
|
44052
|
-
import { join as
|
|
44381
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "node:fs";
|
|
44382
|
+
import { join as join52 } from "node:path";
|
|
44053
44383
|
async function evalCommand(opts, config) {
|
|
44054
44384
|
const suiteName = opts.suite ?? "basic";
|
|
44055
44385
|
const suite = SUITES[suiteName];
|
|
@@ -44174,9 +44504,9 @@ async function evalCommand(opts, config) {
|
|
|
44174
44504
|
process.exit(failed > 0 ? 1 : 0);
|
|
44175
44505
|
}
|
|
44176
44506
|
function createTempEvalRepo() {
|
|
44177
|
-
const dir =
|
|
44178
|
-
|
|
44179
|
-
|
|
44507
|
+
const dir = join52(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
44508
|
+
mkdirSync18(dir, { recursive: true });
|
|
44509
|
+
writeFileSync16(join52(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
44180
44510
|
return dir;
|
|
44181
44511
|
}
|
|
44182
44512
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -44236,7 +44566,7 @@ init_updater();
|
|
|
44236
44566
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
44237
44567
|
import { createRequire as createRequire3 } from "node:module";
|
|
44238
44568
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
44239
|
-
import { dirname as
|
|
44569
|
+
import { dirname as dirname18, join as join53 } from "node:path";
|
|
44240
44570
|
|
|
44241
44571
|
// packages/cli/dist/cli.js
|
|
44242
44572
|
import { createInterface } from "node:readline";
|
|
@@ -44343,7 +44673,7 @@ init_output();
|
|
|
44343
44673
|
function getVersion4() {
|
|
44344
44674
|
try {
|
|
44345
44675
|
const require2 = createRequire3(import.meta.url);
|
|
44346
|
-
const pkgPath =
|
|
44676
|
+
const pkgPath = join53(dirname18(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
44347
44677
|
const pkg = require2(pkgPath);
|
|
44348
44678
|
return pkg.version;
|
|
44349
44679
|
} catch {
|