open-agents-ai 0.73.0 → 0.75.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 +639 -1119
- package/dist/launcher.cjs +12 -12
- package/dist/preinstall.cjs +12 -12
- package/package.json +5 -3
- package/prompts/agentic/system-large.md +304 -0
- package/prompts/agentic/system-medium.md +43 -0
- package/prompts/agentic/system-small.md +17 -0
- package/prompts/compaction/context-compaction.md +9 -0
- package/prompts/personality/level-1-minimal.md +3 -0
- package/prompts/personality/level-2-concise.md +3 -0
- package/prompts/personality/level-4-explanatory.md +3 -0
- package/prompts/personality/level-5-thorough.md +3 -0
- package/prompts/runners/dispatcher.md +24 -0
- package/prompts/runners/editor.md +44 -0
- package/prompts/runners/evaluator.md +30 -0
- package/prompts/runners/merge-summary.md +9 -0
- package/prompts/runners/normalizer.md +23 -0
- package/prompts/runners/planner.md +33 -0
- package/prompts/runners/scout.md +39 -0
- package/prompts/runners/verifier.md +36 -0
- package/prompts/templates/analysis.md +14 -0
- package/prompts/templates/code-review.md +16 -0
- package/prompts/templates/code.md +13 -0
- package/prompts/templates/document.md +13 -0
- package/prompts/templates/error-diagnosis.md +14 -0
- package/prompts/templates/general.md +9 -0
- package/prompts/templates/plan.md +15 -0
- package/prompts/templates/system.md +16 -0
- package/prompts/tui/dmn-gather.md +128 -0
- package/prompts/tui/dream-lucid-eval.md +17 -0
- package/prompts/tui/dream-lucid-implement.md +14 -0
- package/prompts/tui/dream-stages.md +19 -0
- package/prompts/tui/emotion-behavioral.md +2 -0
- package/prompts/tui/emotion-center.md +12 -0
package/dist/index.js
CHANGED
|
@@ -281,10 +281,10 @@ function loadCache() {
|
|
|
281
281
|
}
|
|
282
282
|
return { lastCheck: 0, latestVersion: null };
|
|
283
283
|
}
|
|
284
|
-
function saveCache(
|
|
284
|
+
function saveCache(cache4) {
|
|
285
285
|
try {
|
|
286
286
|
mkdirSync2(CACHE_DIR, { recursive: true });
|
|
287
|
-
writeFileSync2(CACHE_FILE, JSON.stringify(
|
|
287
|
+
writeFileSync2(CACHE_FILE, JSON.stringify(cache4), "utf8");
|
|
288
288
|
} catch {
|
|
289
289
|
}
|
|
290
290
|
}
|
|
@@ -303,10 +303,10 @@ async function fetchLatestVersion() {
|
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
async function checkForUpdate(currentVersion, forceCheck = false) {
|
|
306
|
-
const
|
|
306
|
+
const cache4 = loadCache();
|
|
307
307
|
const now = Date.now();
|
|
308
|
-
let latest =
|
|
309
|
-
if (forceCheck || now -
|
|
308
|
+
let latest = cache4.latestVersion;
|
|
309
|
+
if (forceCheck || now - cache4.lastCheck > CHECK_INTERVAL_MS) {
|
|
310
310
|
latest = await fetchLatestVersion();
|
|
311
311
|
saveCache({ lastCheck: now, latestVersion: latest });
|
|
312
312
|
}
|
|
@@ -8394,9 +8394,9 @@ import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
|
8394
8394
|
import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
|
|
8395
8395
|
function findOcrScript() {
|
|
8396
8396
|
const thisDir = dirname7(fileURLToPath4(import.meta.url));
|
|
8397
|
-
const
|
|
8398
|
-
if (existsSync17(
|
|
8399
|
-
return
|
|
8397
|
+
const devPath3 = resolve19(thisDir, "../../scripts/ocr-advanced.py");
|
|
8398
|
+
if (existsSync17(devPath3))
|
|
8399
|
+
return devPath3;
|
|
8400
8400
|
const bundledPath = resolve19(thisDir, "../scripts/ocr-advanced.py");
|
|
8401
8401
|
if (existsSync17(bundledPath))
|
|
8402
8402
|
return bundledPath;
|
|
@@ -8949,9 +8949,9 @@ import { join as join22, resolve as resolve20, dirname as dirname9 } from "node:
|
|
|
8949
8949
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
8950
8950
|
function findAutoresearchScript(scriptName) {
|
|
8951
8951
|
const thisDir = dirname9(fileURLToPath6(import.meta.url));
|
|
8952
|
-
const
|
|
8953
|
-
if (existsSync19(
|
|
8954
|
-
return
|
|
8952
|
+
const devPath3 = resolve20(thisDir, "../../scripts", scriptName);
|
|
8953
|
+
if (existsSync19(devPath3))
|
|
8954
|
+
return devPath3;
|
|
8955
8955
|
const bundledPath = resolve20(thisDir, "../scripts", scriptName);
|
|
8956
8956
|
if (existsSync19(bundledPath))
|
|
8957
8957
|
return bundledPath;
|
|
@@ -11202,15 +11202,6 @@ var init_nexus = __esm({
|
|
|
11202
11202
|
* Usage: node nexus-daemon.mjs <nexus-dir> <agent-name> [agent-type]
|
|
11203
11203
|
*/
|
|
11204
11204
|
|
|
11205
|
-
// Polyfill for Node <22 (libp2p's it-queue/mortice depends on this)
|
|
11206
|
-
if (typeof Promise.withResolvers === 'undefined') {
|
|
11207
|
-
Promise.withResolvers = function withResolvers() {
|
|
11208
|
-
let resolve, reject;
|
|
11209
|
-
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
|
11210
|
-
return { promise, resolve, reject };
|
|
11211
|
-
};
|
|
11212
|
-
}
|
|
11213
|
-
|
|
11214
11205
|
import { NexusClient } from 'open-agents-nexus';
|
|
11215
11206
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, readdirSync } from 'node:fs';
|
|
11216
11207
|
import { join } from 'node:path';
|
|
@@ -11237,6 +11228,10 @@ const nexus = new NexusClient({
|
|
|
11237
11228
|
role: 'light',
|
|
11238
11229
|
enableMdns: true,
|
|
11239
11230
|
enablePubsubDiscovery: true,
|
|
11231
|
+
enableNats: true,
|
|
11232
|
+
natsServers: ['wss://demo.nats.io:8443'],
|
|
11233
|
+
enableCircuitRelay: true,
|
|
11234
|
+
usePublicBootstrap: true,
|
|
11240
11235
|
});
|
|
11241
11236
|
|
|
11242
11237
|
const rooms = new Map();
|
|
@@ -11315,6 +11310,43 @@ async function handleCmd(cmd) {
|
|
|
11315
11310
|
writeResp(id, { ok: true, output: joined.length ? 'Rooms: ' + joined.join(', ') : 'No rooms joined.' });
|
|
11316
11311
|
break;
|
|
11317
11312
|
}
|
|
11313
|
+
case 'send_dm': {
|
|
11314
|
+
const peerId = args.target_peer;
|
|
11315
|
+
if (!peerId) { writeResp(id, { ok: false, output: 'target_peer is required' }); return; }
|
|
11316
|
+
await nexus.sendDM(peerId, args.message || '');
|
|
11317
|
+
writeResp(id, { ok: true, output: 'DM sent to ' + peerId.slice(0, 20) + '...' });
|
|
11318
|
+
break;
|
|
11319
|
+
}
|
|
11320
|
+
case 'find_agent': {
|
|
11321
|
+
const peerId = args.peer_id;
|
|
11322
|
+
if (!peerId) { writeResp(id, { ok: false, output: 'peer_id is required' }); return; }
|
|
11323
|
+
const profile = await nexus.findAgent(peerId);
|
|
11324
|
+
writeResp(id, { ok: true, output: profile ? JSON.stringify(profile, null, 2) : 'Agent not found: ' + peerId });
|
|
11325
|
+
break;
|
|
11326
|
+
}
|
|
11327
|
+
case 'invoke_capability': {
|
|
11328
|
+
const peerId = args.target_peer;
|
|
11329
|
+
const capability = args.capability || 'text-generation';
|
|
11330
|
+
const input = args.input || {};
|
|
11331
|
+
if (!peerId) { writeResp(id, { ok: false, output: 'target_peer is required' }); return; }
|
|
11332
|
+
const result = await nexus.invokeCapability(peerId, capability, typeof input === 'string' ? { prompt: input } : input, { stream: false, maxDurationMs: 60000 });
|
|
11333
|
+
writeResp(id, { ok: true, output: JSON.stringify(result, null, 2) });
|
|
11334
|
+
break;
|
|
11335
|
+
}
|
|
11336
|
+
case 'store_content': {
|
|
11337
|
+
const data = args.data;
|
|
11338
|
+
if (!data) { writeResp(id, { ok: false, output: 'data is required' }); return; }
|
|
11339
|
+
const cid = await nexus.store(typeof data === 'string' ? { data } : data);
|
|
11340
|
+
writeResp(id, { ok: true, output: 'Stored. CID: ' + cid });
|
|
11341
|
+
break;
|
|
11342
|
+
}
|
|
11343
|
+
case 'retrieve_content': {
|
|
11344
|
+
const cid = args.cid;
|
|
11345
|
+
if (!cid) { writeResp(id, { ok: false, output: 'cid is required' }); return; }
|
|
11346
|
+
const data = await nexus.retrieve(cid);
|
|
11347
|
+
writeResp(id, { ok: true, output: JSON.stringify(data, null, 2) });
|
|
11348
|
+
break;
|
|
11349
|
+
}
|
|
11318
11350
|
case 'ping': {
|
|
11319
11351
|
writeResp(id, { ok: true, output: 'pong' });
|
|
11320
11352
|
break;
|
|
@@ -11377,7 +11409,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11377
11409
|
];
|
|
11378
11410
|
NexusTool = class {
|
|
11379
11411
|
name = "nexus";
|
|
11380
|
-
description = "Decentralized agent-to-agent communication via open-agents-nexus. Spawns a background Node.js process with real network sockets for libp2p P2P mesh. Simple flow: connect \u2192 join room \u2192 send messages. Auto-installs nexus if needed. Also supports peer discovery, x402 micropayments, and inference proofs.";
|
|
11412
|
+
description = "Decentralized agent-to-agent communication via open-agents-nexus v1.2.1. Spawns a background Node.js process with real network sockets for libp2p + NATS P2P mesh. Simple flow: connect \u2192 join room \u2192 send messages. Auto-installs nexus if needed. Also supports direct peer invoke (streaming inference), IPFS content storage, direct messages, peer discovery, x402 micropayments, and inference proofs.";
|
|
11381
11413
|
parameters = {
|
|
11382
11414
|
type: "object",
|
|
11383
11415
|
properties: {
|
|
@@ -11393,6 +11425,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11393
11425
|
"read_messages",
|
|
11394
11426
|
"discover_peers",
|
|
11395
11427
|
"list_rooms",
|
|
11428
|
+
"send_dm",
|
|
11429
|
+
"find_agent",
|
|
11430
|
+
"invoke_capability",
|
|
11431
|
+
"store_content",
|
|
11432
|
+
"retrieve_content",
|
|
11396
11433
|
"wallet_status",
|
|
11397
11434
|
"wallet_create",
|
|
11398
11435
|
"inference_proof"
|
|
@@ -11418,6 +11455,30 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11418
11455
|
wallet_address: {
|
|
11419
11456
|
type: "string",
|
|
11420
11457
|
description: "Wallet address for wallet_create (user-provided receive address)"
|
|
11458
|
+
},
|
|
11459
|
+
target_peer: {
|
|
11460
|
+
type: "string",
|
|
11461
|
+
description: "Target peer ID for send_dm, find_agent, invoke_capability (e.g. '12D3KooW...')"
|
|
11462
|
+
},
|
|
11463
|
+
peer_id: {
|
|
11464
|
+
type: "string",
|
|
11465
|
+
description: "Peer ID for find_agent"
|
|
11466
|
+
},
|
|
11467
|
+
capability: {
|
|
11468
|
+
type: "string",
|
|
11469
|
+
description: "Capability name for invoke_capability (e.g. 'text-generation')"
|
|
11470
|
+
},
|
|
11471
|
+
input: {
|
|
11472
|
+
type: "string",
|
|
11473
|
+
description: "Input data for invoke_capability (prompt text or JSON string)"
|
|
11474
|
+
},
|
|
11475
|
+
data: {
|
|
11476
|
+
type: "string",
|
|
11477
|
+
description: "Data to store for store_content"
|
|
11478
|
+
},
|
|
11479
|
+
cid: {
|
|
11480
|
+
type: "string",
|
|
11481
|
+
description: "Content ID for retrieve_content"
|
|
11421
11482
|
}
|
|
11422
11483
|
},
|
|
11423
11484
|
required: ["action"],
|
|
@@ -11467,6 +11528,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11467
11528
|
case "list_rooms":
|
|
11468
11529
|
result = await this.sendDaemonCmd("list_rooms", args);
|
|
11469
11530
|
break;
|
|
11531
|
+
case "send_dm":
|
|
11532
|
+
result = await this.doSendDM(args);
|
|
11533
|
+
break;
|
|
11534
|
+
case "find_agent":
|
|
11535
|
+
result = await this.sendDaemonCmd("find_agent", args);
|
|
11536
|
+
break;
|
|
11537
|
+
case "invoke_capability":
|
|
11538
|
+
result = await this.sendDaemonCmd("invoke_capability", args);
|
|
11539
|
+
break;
|
|
11540
|
+
case "store_content":
|
|
11541
|
+
result = await this.sendDaemonCmd("store_content", args);
|
|
11542
|
+
break;
|
|
11543
|
+
case "retrieve_content":
|
|
11544
|
+
result = await this.sendDaemonCmd("retrieve_content", args);
|
|
11545
|
+
break;
|
|
11470
11546
|
case "wallet_status":
|
|
11471
11547
|
result = await this.doWalletStatus();
|
|
11472
11548
|
break;
|
|
@@ -11711,6 +11787,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11711
11787
|
}
|
|
11712
11788
|
return this.sendDaemonCmd("send_message", args);
|
|
11713
11789
|
}
|
|
11790
|
+
async doSendDM(args) {
|
|
11791
|
+
const message = args.message;
|
|
11792
|
+
if (!message)
|
|
11793
|
+
throw new Error("message is required");
|
|
11794
|
+
if (!args.target_peer)
|
|
11795
|
+
throw new Error("target_peer is required");
|
|
11796
|
+
if (containsKeyMaterial(message)) {
|
|
11797
|
+
return [
|
|
11798
|
+
"BLOCKED: Message contains potential key material or secrets.",
|
|
11799
|
+
"Messages containing private keys or sensitive cryptographic material",
|
|
11800
|
+
"cannot be sent over the network. Remove the sensitive content and retry."
|
|
11801
|
+
].join("\n");
|
|
11802
|
+
}
|
|
11803
|
+
return this.sendDaemonCmd("send_dm", args);
|
|
11804
|
+
}
|
|
11714
11805
|
async doReadMessages(args) {
|
|
11715
11806
|
const roomId = args.room_id;
|
|
11716
11807
|
const inboxDir = join28(this.nexusDir, "inbox");
|
|
@@ -12672,6 +12763,35 @@ var init_dist3 = __esm({
|
|
|
12672
12763
|
}
|
|
12673
12764
|
});
|
|
12674
12765
|
|
|
12766
|
+
// packages/orchestrator/dist/promptLoader.js
|
|
12767
|
+
import { readFileSync as readFileSync15, existsSync as existsSync22 } from "node:fs";
|
|
12768
|
+
import { join as join29, dirname as dirname10 } from "node:path";
|
|
12769
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
12770
|
+
function loadPrompt(promptPath, vars) {
|
|
12771
|
+
let content = cache.get(promptPath);
|
|
12772
|
+
if (content === void 0) {
|
|
12773
|
+
const fullPath = join29(PROMPTS_DIR, promptPath);
|
|
12774
|
+
if (!existsSync22(fullPath)) {
|
|
12775
|
+
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
12776
|
+
}
|
|
12777
|
+
content = readFileSync15(fullPath, "utf-8");
|
|
12778
|
+
cache.set(promptPath, content);
|
|
12779
|
+
}
|
|
12780
|
+
if (!vars)
|
|
12781
|
+
return content;
|
|
12782
|
+
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
12783
|
+
}
|
|
12784
|
+
var __filename, __dirname3, PROMPTS_DIR, cache;
|
|
12785
|
+
var init_promptLoader = __esm({
|
|
12786
|
+
"packages/orchestrator/dist/promptLoader.js"() {
|
|
12787
|
+
"use strict";
|
|
12788
|
+
__filename = fileURLToPath7(import.meta.url);
|
|
12789
|
+
__dirname3 = dirname10(__filename);
|
|
12790
|
+
PROMPTS_DIR = join29(__dirname3, "..", "prompts");
|
|
12791
|
+
cache = /* @__PURE__ */ new Map();
|
|
12792
|
+
}
|
|
12793
|
+
});
|
|
12794
|
+
|
|
12675
12795
|
// packages/orchestrator/dist/taskNormalizer.js
|
|
12676
12796
|
function parseJsonFromContent(content) {
|
|
12677
12797
|
const fencedMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -12683,35 +12803,14 @@ function parseJsonFromContent(content) {
|
|
|
12683
12803
|
}
|
|
12684
12804
|
}
|
|
12685
12805
|
function normalizationPrompt(rawRequest, repoRoot) {
|
|
12686
|
-
return
|
|
12687
|
-
|
|
12688
|
-
SCHEMA:
|
|
12689
|
-
{
|
|
12690
|
-
"id": "<unique string - generate a short UUID-like identifier>",
|
|
12691
|
-
"goal": "<single concise goal sentence>",
|
|
12692
|
-
"constraints": ["<constraint string>", ...],
|
|
12693
|
-
"successCriteria": ["<criterion string>", ...],
|
|
12694
|
-
"repoRoot": "<absolute path to repo root>",
|
|
12695
|
-
"urgency": "low" | "medium" | "high" | "critical",
|
|
12696
|
-
"taskClass": "bugfix" | "feature" | "refactor" | "migration" | "dependency-upgrade" | "test" | "docs" | "infra",
|
|
12697
|
-
"rawRequest": "<original user request verbatim>",
|
|
12698
|
-
"createdAt": "<ISO-8601 timestamp>"
|
|
12699
|
-
}
|
|
12700
|
-
|
|
12701
|
-
RULES:
|
|
12702
|
-
- "repoRoot" MUST be: ${repoRoot}
|
|
12703
|
-
- "rawRequest" MUST be the exact request text provided below.
|
|
12704
|
-
- "createdAt" MUST be the current UTC datetime in ISO-8601 format.
|
|
12705
|
-
- Respond ONLY with the JSON object, no additional text.
|
|
12706
|
-
|
|
12707
|
-
USER REQUEST:
|
|
12708
|
-
${rawRequest}`;
|
|
12806
|
+
return loadPrompt("runners/normalizer.md", { rawRequest, repoRoot });
|
|
12709
12807
|
}
|
|
12710
12808
|
var TaskNormalizer;
|
|
12711
12809
|
var init_taskNormalizer = __esm({
|
|
12712
12810
|
"packages/orchestrator/dist/taskNormalizer.js"() {
|
|
12713
12811
|
"use strict";
|
|
12714
12812
|
init_dist3();
|
|
12813
|
+
init_promptLoader();
|
|
12715
12814
|
TaskNormalizer = class {
|
|
12716
12815
|
backend;
|
|
12717
12816
|
constructor(backend) {
|
|
@@ -12814,30 +12913,7 @@ function heuristicDecision(task) {
|
|
|
12814
12913
|
};
|
|
12815
12914
|
}
|
|
12816
12915
|
function dispatchPrompt(task) {
|
|
12817
|
-
return
|
|
12818
|
-
|
|
12819
|
-
TASK:
|
|
12820
|
-
${JSON.stringify(task, null, 2)}
|
|
12821
|
-
|
|
12822
|
-
SCHEMA:
|
|
12823
|
-
{
|
|
12824
|
-
"mode": "single_pass" | "multi_agent" | "hybrid",
|
|
12825
|
-
"taskComplexity": "low" | "medium" | "high",
|
|
12826
|
-
"splitRecommended": boolean,
|
|
12827
|
-
"initialAgents": ["planner" | "scout" | "editor" | "verifier" | "researcher", ...],
|
|
12828
|
-
"budgets": {
|
|
12829
|
-
"promptTokens": <positive integer>,
|
|
12830
|
-
"retries": <non-negative integer>,
|
|
12831
|
-
"wallClockSec": <positive number>
|
|
12832
|
-
}
|
|
12833
|
-
}
|
|
12834
|
-
|
|
12835
|
-
RULES:
|
|
12836
|
-
- Use "single_pass" only for small, well-scoped changes.
|
|
12837
|
-
- Use "multi_agent" when the task touches many independent subsystems.
|
|
12838
|
-
- "splitRecommended" should be true only when "multi_agent" is chosen.
|
|
12839
|
-
- "initialAgents" must always include "scout", "editor", and "verifier".
|
|
12840
|
-
- Respond ONLY with the JSON object, no additional text.`;
|
|
12916
|
+
return loadPrompt("runners/dispatcher.md", { task: JSON.stringify(task, null, 2) });
|
|
12841
12917
|
}
|
|
12842
12918
|
function parseJsonFromContent2(content) {
|
|
12843
12919
|
const fencedMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -12853,6 +12929,7 @@ var init_dispatcher = __esm({
|
|
|
12853
12929
|
"packages/orchestrator/dist/dispatcher.js"() {
|
|
12854
12930
|
"use strict";
|
|
12855
12931
|
init_dist3();
|
|
12932
|
+
init_promptLoader();
|
|
12856
12933
|
Dispatcher = class {
|
|
12857
12934
|
backend;
|
|
12858
12935
|
/**
|
|
@@ -12917,39 +12994,7 @@ ${JSON.stringify(repoProfile, null, 2)}` : "REPOSITORY PROFILE: (not available)"
|
|
|
12917
12994
|
Architecture note: ${retrievalPacket.architectureNote ?? "n/a"}
|
|
12918
12995
|
Prior attempt note: ${retrievalPacket.priorAttemptNote ?? "n/a"}
|
|
12919
12996
|
Files available: ${Object.keys(retrievalPacket.files).join(", ")}` : "RETRIEVAL CONTEXT: (not available)";
|
|
12920
|
-
return
|
|
12921
|
-
|
|
12922
|
-
TASK:
|
|
12923
|
-
${JSON.stringify(task, null, 2)}
|
|
12924
|
-
|
|
12925
|
-
${profileSection}
|
|
12926
|
-
|
|
12927
|
-
${retrievalSection}
|
|
12928
|
-
|
|
12929
|
-
SCHEMA for your response:
|
|
12930
|
-
{
|
|
12931
|
-
"goal": "<restate the goal concisely>",
|
|
12932
|
-
"subtasks": [
|
|
12933
|
-
{
|
|
12934
|
-
"id": "<short unique id, e.g. 'st-1'>",
|
|
12935
|
-
"kind": "inspect" | "patch" | "test" | "migrate" | "verify" | "merge",
|
|
12936
|
-
"targets": ["<file or symbol>", ...],
|
|
12937
|
-
"dependsOn": ["<subtask id>", ...],
|
|
12938
|
-
"reason": "<why this subtask is needed>",
|
|
12939
|
-
"validation": ["<shell command or assertion>", ...]
|
|
12940
|
-
}
|
|
12941
|
-
],
|
|
12942
|
-
"riskAreas": ["<file or module at risk>", ...],
|
|
12943
|
-
"unknowns": ["<ambiguity or missing information>", ...]
|
|
12944
|
-
}
|
|
12945
|
-
|
|
12946
|
-
RULES:
|
|
12947
|
-
- Every subtask must have a unique "id".
|
|
12948
|
-
- "dependsOn" references must be ids of earlier subtasks in the array.
|
|
12949
|
-
- Include at least one "verify" subtask at the end.
|
|
12950
|
-
- The first subtask should usually be an "inspect" of the most relevant file.
|
|
12951
|
-
- Keep the plan pragmatic: do not exceed 12 subtasks.
|
|
12952
|
-
- Respond ONLY with the JSON object, no additional text.`;
|
|
12997
|
+
return loadPrompt("runners/planner.md", { task: JSON.stringify(task, null, 2), profileSection, retrievalSection });
|
|
12953
12998
|
}
|
|
12954
12999
|
function parseJsonFromContent3(content) {
|
|
12955
13000
|
const fencedMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -12965,6 +13010,7 @@ var init_plannerRunner = __esm({
|
|
|
12965
13010
|
"packages/orchestrator/dist/plannerRunner.js"() {
|
|
12966
13011
|
"use strict";
|
|
12967
13012
|
init_dist3();
|
|
13013
|
+
init_promptLoader();
|
|
12968
13014
|
PlannerRunner = class {
|
|
12969
13015
|
backend;
|
|
12970
13016
|
constructor(backend) {
|
|
@@ -13121,7 +13167,7 @@ var init_code_retriever = __esm({
|
|
|
13121
13167
|
import { execFile as execFile5 } from "node:child_process";
|
|
13122
13168
|
import { promisify as promisify4 } from "node:util";
|
|
13123
13169
|
import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
13124
|
-
import { join as
|
|
13170
|
+
import { join as join30, extname as extname7 } from "node:path";
|
|
13125
13171
|
async function searchByPath(pathPattern, options) {
|
|
13126
13172
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
13127
13173
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -13263,7 +13309,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
13263
13309
|
continue;
|
|
13264
13310
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
13265
13311
|
continue;
|
|
13266
|
-
const absPath =
|
|
13312
|
+
const absPath = join30(dir, entry.name);
|
|
13267
13313
|
if (entry.isDirectory()) {
|
|
13268
13314
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
13269
13315
|
} else if (entry.isFile()) {
|
|
@@ -13570,7 +13616,7 @@ var init_graphExpand = __esm({
|
|
|
13570
13616
|
|
|
13571
13617
|
// packages/retrieval/dist/snippetPacker.js
|
|
13572
13618
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
13573
|
-
import { join as
|
|
13619
|
+
import { join as join31 } from "node:path";
|
|
13574
13620
|
async function packSnippets(requests, opts = {}) {
|
|
13575
13621
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
13576
13622
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -13596,7 +13642,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
13596
13642
|
return { packed, dropped, totalTokens };
|
|
13597
13643
|
}
|
|
13598
13644
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
13599
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
13645
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join31(repoRoot, req.filePath);
|
|
13600
13646
|
let content;
|
|
13601
13647
|
try {
|
|
13602
13648
|
content = await readFile15(absPath, "utf-8");
|
|
@@ -13862,51 +13908,19 @@ function scoutPrompt(task, repoProfile, candidateFiles, subtasks) {
|
|
|
13862
13908
|
const fileList = Object.keys(candidateFiles).join("\n - ");
|
|
13863
13909
|
const profileNote = repoProfile ? `The repo uses ${repoProfile.languages.join(", ")} with ${repoProfile.frameworks.join(", ")}.` : "No repo profile available.";
|
|
13864
13910
|
const subtaskTargets = subtasks.flatMap((s) => s.targets).filter((t, i, arr) => arr.indexOf(t) === i);
|
|
13865
|
-
return
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
${
|
|
13869
|
-
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
SUBTASK TARGETS (from planner, if available):
|
|
13873
|
-
${subtaskTargets.length ? subtaskTargets.map((t) => ` - ${t}`).join("\n") : " (none yet)"}
|
|
13874
|
-
|
|
13875
|
-
CANDIDATE FILES FOUND BY SEARCH:
|
|
13876
|
-
- ${fileList || "(none found)"}
|
|
13877
|
-
|
|
13878
|
-
Produce a RetrievalPacket JSON with the following schema:
|
|
13879
|
-
{
|
|
13880
|
-
"request": {
|
|
13881
|
-
"query": "<what you searched for>",
|
|
13882
|
-
"pathsHint": ["<high-priority paths>"],
|
|
13883
|
-
"symbolHint": ["<symbol names>"],
|
|
13884
|
-
"errorHint": [],
|
|
13885
|
-
"maxFiles": 10,
|
|
13886
|
-
"maxSnippets": 20,
|
|
13887
|
-
"includeTests": true,
|
|
13888
|
-
"includeConfigs": false
|
|
13889
|
-
},
|
|
13890
|
-
"files": {
|
|
13891
|
-
"<repo-relative path>": "<short excerpt or empty string>"
|
|
13892
|
-
},
|
|
13893
|
-
"snippets": [],
|
|
13894
|
-
"architectureNote": "<one-line architecture insight>",
|
|
13895
|
-
"priorAttemptNote": null,
|
|
13896
|
-
"assembledAt": "<ISO-8601 now>"
|
|
13897
|
-
}
|
|
13898
|
-
|
|
13899
|
-
RULES:
|
|
13900
|
-
- Include only the top 10 most relevant files in "files".
|
|
13901
|
-
- The keys of "files" must be repo-relative paths present in the candidate list above.
|
|
13902
|
-
- "assembledAt" must be a current ISO-8601 datetime.
|
|
13903
|
-
- Respond ONLY with the JSON object, no additional text.`;
|
|
13911
|
+
return loadPrompt("runners/scout.md", {
|
|
13912
|
+
task: JSON.stringify(task, null, 2),
|
|
13913
|
+
profileNote,
|
|
13914
|
+
subtaskTargets: subtaskTargets.length ? subtaskTargets.map((t) => ` - ${t}`).join("\n") : " (none yet)",
|
|
13915
|
+
fileList: fileList || "(none found)"
|
|
13916
|
+
});
|
|
13904
13917
|
}
|
|
13905
13918
|
var ScoutRunner;
|
|
13906
13919
|
var init_scoutRunner = __esm({
|
|
13907
13920
|
"packages/orchestrator/dist/scoutRunner.js"() {
|
|
13908
13921
|
"use strict";
|
|
13909
13922
|
init_dist3();
|
|
13923
|
+
init_promptLoader();
|
|
13910
13924
|
ScoutRunner = class {
|
|
13911
13925
|
backend;
|
|
13912
13926
|
constructor(backend) {
|
|
@@ -14019,50 +14033,12 @@ Evidence:
|
|
|
14019
14033
|
${previousVerification.evidence.map((e) => ` - ${e}`).join("\n")}
|
|
14020
14034
|
Focus files: ${previousVerification.focusFiles.join(", ")}
|
|
14021
14035
|
Failure fingerprint: ${previousVerification.failureFingerprint ?? "none"}` : "";
|
|
14022
|
-
return
|
|
14023
|
-
|
|
14024
|
-
|
|
14025
|
-
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
${JSON.stringify(subtask, null, 2)}
|
|
14029
|
-
|
|
14030
|
-
RETRIEVED SOURCE FILES:
|
|
14031
|
-
${filesSection || "(no files retrieved)"}
|
|
14032
|
-
|
|
14033
|
-
${retrySection}
|
|
14034
|
-
|
|
14035
|
-
Produce a PatchProposal JSON with the following schema:
|
|
14036
|
-
{
|
|
14037
|
-
"summary": "<one paragraph: what changed and why>",
|
|
14038
|
-
"edits": [
|
|
14039
|
-
{
|
|
14040
|
-
"file": "<repo-relative path>",
|
|
14041
|
-
"operation": "diff" | "rewrite" | "append" | "create",
|
|
14042
|
-
"content": "<unified diff, full file content, or new content>"
|
|
14043
|
-
}
|
|
14044
|
-
],
|
|
14045
|
-
"testsToRun": ["<shell command or test file path>"],
|
|
14046
|
-
"assumptions": ["<assumption made>"],
|
|
14047
|
-
"risks": ["<known risk>"],
|
|
14048
|
-
"needsMoreContext": null
|
|
14049
|
-
}
|
|
14050
|
-
|
|
14051
|
-
If you CANNOT safely produce a patch without more information, set "needsMoreContext":
|
|
14052
|
-
{
|
|
14053
|
-
"reason": "<why you need more info>",
|
|
14054
|
-
"requestedPaths": ["<paths to read>"],
|
|
14055
|
-
"requestedSymbols": ["<symbol names>"]
|
|
14056
|
-
}
|
|
14057
|
-
and set "edits" to an empty array.
|
|
14058
|
-
|
|
14059
|
-
RULES:
|
|
14060
|
-
- Prefer "diff" operation with proper unified diff format when modifying existing files.
|
|
14061
|
-
- Use "rewrite" only for small files or when the diff would be confusing.
|
|
14062
|
-
- Use "create" for new files that do not yet exist.
|
|
14063
|
-
- Include at least one entry in "testsToRun" unless the subtask kind is "inspect".
|
|
14064
|
-
- Be conservative: only change what is required by the subtask.
|
|
14065
|
-
- Respond ONLY with the JSON object, no additional text.`;
|
|
14036
|
+
return loadPrompt("runners/editor.md", {
|
|
14037
|
+
task: JSON.stringify(task, null, 2),
|
|
14038
|
+
subtask: JSON.stringify(subtask, null, 2),
|
|
14039
|
+
filesSection: filesSection || "(no files retrieved)",
|
|
14040
|
+
retrySection
|
|
14041
|
+
});
|
|
14066
14042
|
}
|
|
14067
14043
|
function parseJsonFromContent5(content) {
|
|
14068
14044
|
const fencedMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -14078,6 +14054,7 @@ var init_editorRunner = __esm({
|
|
|
14078
14054
|
"packages/orchestrator/dist/editorRunner.js"() {
|
|
14079
14055
|
"use strict";
|
|
14080
14056
|
init_dist3();
|
|
14057
|
+
init_promptLoader();
|
|
14081
14058
|
EditorRunner = class {
|
|
14082
14059
|
backend;
|
|
14083
14060
|
constructor(backend) {
|
|
@@ -14138,42 +14115,16 @@ function verifierPrompt(task, subtask, patch, toolOutput) {
|
|
|
14138
14115
|
${toolOutput}` : "TOOL EXECUTION OUTPUT: (not executed)";
|
|
14139
14116
|
const editsSection = patch.edits.map((e) => `--- ${e.file} [${e.operation}] ---
|
|
14140
14117
|
${e.content.slice(0, 800)}`).join("\n\n");
|
|
14141
|
-
return
|
|
14142
|
-
|
|
14143
|
-
|
|
14144
|
-
|
|
14145
|
-
|
|
14146
|
-
|
|
14147
|
-
|
|
14148
|
-
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
Assumptions: ${patch.assumptions.join("; ") || "none"}
|
|
14152
|
-
Risks: ${patch.risks.join("; ") || "none"}
|
|
14153
|
-
Tests to run: ${patch.testsToRun.join(", ") || "none"}
|
|
14154
|
-
|
|
14155
|
-
EDITS:
|
|
14156
|
-
${editsSection || "(no edits)"}
|
|
14157
|
-
|
|
14158
|
-
${toolSection}
|
|
14159
|
-
|
|
14160
|
-
Produce a VerificationDecision JSON:
|
|
14161
|
-
{
|
|
14162
|
-
"status": "pass" | "fail" | "partial",
|
|
14163
|
-
"evidence": ["<concrete evidence line from output or code review>", ...],
|
|
14164
|
-
"nextAction": "finish" | "retry" | "rollback" | "inspect_more",
|
|
14165
|
-
"focusFiles": ["<file to focus on in next round>", ...],
|
|
14166
|
-
"failureFingerprint": "<short stable failure identifier, or null if status is pass>"
|
|
14167
|
-
}
|
|
14168
|
-
|
|
14169
|
-
DECISION RULES:
|
|
14170
|
-
- "pass" + "finish": all success criteria addressed, no regressions visible.
|
|
14171
|
-
- "fail" + "retry": fixable issue; leave a precise "failureFingerprint".
|
|
14172
|
-
- "fail" + "rollback": irreversible regression or destructive change detected.
|
|
14173
|
-
- "partial" + "inspect_more": patch is incomplete; more context needed.
|
|
14174
|
-
- "failureFingerprint" must be null (omit the field) when status is "pass".
|
|
14175
|
-
- "evidence" must have at least one entry.
|
|
14176
|
-
- Respond ONLY with the JSON object, no additional text.`;
|
|
14118
|
+
return loadPrompt("runners/verifier.md", {
|
|
14119
|
+
task: JSON.stringify(task, null, 2),
|
|
14120
|
+
subtask: JSON.stringify(subtask, null, 2),
|
|
14121
|
+
patchSummary: patch.summary,
|
|
14122
|
+
patchAssumptions: patch.assumptions.join("; ") || "none",
|
|
14123
|
+
patchRisks: patch.risks.join("; ") || "none",
|
|
14124
|
+
patchTests: patch.testsToRun.join(", ") || "none",
|
|
14125
|
+
editsSection: editsSection || "(no edits)",
|
|
14126
|
+
toolSection
|
|
14127
|
+
});
|
|
14177
14128
|
}
|
|
14178
14129
|
function parseJsonFromContent6(content) {
|
|
14179
14130
|
const fencedMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -14189,6 +14140,7 @@ var init_verifierRunner = __esm({
|
|
|
14189
14140
|
"packages/orchestrator/dist/verifierRunner.js"() {
|
|
14190
14141
|
"use strict";
|
|
14191
14142
|
init_dist3();
|
|
14143
|
+
init_promptLoader();
|
|
14192
14144
|
VerifierRunner = class {
|
|
14193
14145
|
backend;
|
|
14194
14146
|
options;
|
|
@@ -14285,6 +14237,7 @@ var MergeRunner;
|
|
|
14285
14237
|
var init_mergeRunner = __esm({
|
|
14286
14238
|
"packages/orchestrator/dist/mergeRunner.js"() {
|
|
14287
14239
|
"use strict";
|
|
14240
|
+
init_promptLoader();
|
|
14288
14241
|
MergeRunner = class {
|
|
14289
14242
|
backend;
|
|
14290
14243
|
/**
|
|
@@ -14345,15 +14298,13 @@ var init_mergeRunner = __esm({
|
|
|
14345
14298
|
if (!this.backend || mergedEdits.length === 0) {
|
|
14346
14299
|
return basicSummary;
|
|
14347
14300
|
}
|
|
14348
|
-
const prompt =
|
|
14349
|
-
|
|
14350
|
-
|
|
14351
|
-
|
|
14352
|
-
|
|
14353
|
-
|
|
14354
|
-
|
|
14355
|
-
|
|
14356
|
-
Write a concise developer-facing merge summary. No JSON, just plain text.`;
|
|
14301
|
+
const prompt = loadPrompt("runners/merge-summary.md", {
|
|
14302
|
+
taskGoal: task.goal,
|
|
14303
|
+
successfulSubtasks: successfulSubtasks.join(", "),
|
|
14304
|
+
failedSubtasks: failedSubtasks.join(", ") || "none",
|
|
14305
|
+
filesChanged: [...new Set(mergedEdits.map((e) => e.file))].join(", "),
|
|
14306
|
+
conflicts: conflicts.map((c3) => c3.filePath + " (" + c3.conflictingSubtasks.join(" vs ") + ")").join(", ") || "none"
|
|
14307
|
+
});
|
|
14357
14308
|
try {
|
|
14358
14309
|
const response = await this.backend.complete({
|
|
14359
14310
|
messages: [{ role: "user", content: prompt }],
|
|
@@ -14804,26 +14755,18 @@ var init_ralphLoop = __esm({
|
|
|
14804
14755
|
function compilePersonalityPrompt(profile) {
|
|
14805
14756
|
const avg = (profile.frequency + profile.depth + profile.threshold + profile.effort + profile.willingness) / 5;
|
|
14806
14757
|
if (avg <= 1.5) {
|
|
14807
|
-
return
|
|
14808
|
-
## Response Style
|
|
14809
|
-
Be extremely concise. Act silently \u2014 only speak when results are surprising or errors occur. No preamble, no summaries. Raw results and tool calls only.`;
|
|
14758
|
+
return loadPrompt("personality/level-1-minimal.md");
|
|
14810
14759
|
}
|
|
14811
14760
|
if (avg <= 2.5) {
|
|
14812
|
-
return
|
|
14813
|
-
## Response Style
|
|
14814
|
-
Be concise and direct. Brief status updates between tool calls. Skip reasoning explanation unless the approach is non-obvious. No markdown headers for short answers.`;
|
|
14761
|
+
return loadPrompt("personality/level-2-concise.md");
|
|
14815
14762
|
}
|
|
14816
14763
|
if (avg <= 3.5) {
|
|
14817
14764
|
return "";
|
|
14818
14765
|
}
|
|
14819
14766
|
if (avg <= 4.5) {
|
|
14820
|
-
return
|
|
14821
|
-
## Response Style
|
|
14822
|
-
Explain your reasoning as you work. Describe what you're looking for and why. Summarize findings. Use structured formatting for complex output.`;
|
|
14767
|
+
return loadPrompt("personality/level-4-explanatory.md");
|
|
14823
14768
|
}
|
|
14824
|
-
return
|
|
14825
|
-
## Response Style
|
|
14826
|
-
Provide thorough explanations of your reasoning at each step. Describe alternatives you considered. Offer suggestions beyond the immediate task. Use well-structured markdown with headers and examples.`;
|
|
14769
|
+
return loadPrompt("personality/level-5-thorough.md");
|
|
14827
14770
|
}
|
|
14828
14771
|
function getPreset(name) {
|
|
14829
14772
|
return PERSONALITY_PRESETS[name];
|
|
@@ -14832,6 +14775,7 @@ var PERSONALITY_PRESETS, PRESET_NAMES;
|
|
|
14832
14775
|
var init_personality = __esm({
|
|
14833
14776
|
"packages/orchestrator/dist/personality.js"() {
|
|
14834
14777
|
"use strict";
|
|
14778
|
+
init_promptLoader();
|
|
14835
14779
|
PERSONALITY_PRESETS = {
|
|
14836
14780
|
/** Silent operator — acts, doesn't explain */
|
|
14837
14781
|
concise: { frequency: 1, depth: 1, threshold: 1, effort: 2, willingness: 1 },
|
|
@@ -14863,325 +14807,10 @@ var init_agenticRunner = __esm({
|
|
|
14863
14807
|
"use strict";
|
|
14864
14808
|
init_dist();
|
|
14865
14809
|
init_personality();
|
|
14866
|
-
|
|
14867
|
-
|
|
14868
|
-
|
|
14869
|
-
|
|
14870
|
-
You have a comprehensive set of tools. NEVER say "I can't do that" or "I don't have the ability to...". Instead, ALWAYS attempt the task using your tools:
|
|
14871
|
-
- Need to open Firefox? Use shell: \`firefox https://example.com &\`
|
|
14872
|
-
- Need to click a button? Use desktop_click or shell with xdotool
|
|
14873
|
-
- Need to see the screen? Use screenshot or desktop_describe
|
|
14874
|
-
- Need to type text? Use shell with xdotool: \`xdotool type "text"\` (to target a specific window: \`xdotool type --window $WID "text"\`)
|
|
14875
|
-
- Need to install software? Use shell: \`sudo apt install ...\`
|
|
14876
|
-
- Need to interact with a website? Use web_fetch, or open the browser and use desktop tools
|
|
14877
|
-
|
|
14878
|
-
If a tool fails, try a different approach. If you're unsure, explore with your tools first. Do NOT give a text-only response when tools could accomplish the task.
|
|
14879
|
-
|
|
14880
|
-
## Available Tools
|
|
14881
|
-
|
|
14882
|
-
- file_read: Read file contents (always read before editing). Supports path, offset, limit.
|
|
14883
|
-
- file_write: Create or overwrite a file with complete content
|
|
14884
|
-
- file_edit: Make a precise string replacement in a file (preferred over rewriting). Uses old_string/new_string. old_string must be unique unless replace_all=true. Use replace_all for variable renames.
|
|
14885
|
-
- file_patch: Edit specific line ranges in large files. Modes: replace (swap lines), insert_before, insert_after, delete. Use dry_run to preview. Best for large files (500+ lines) where string matching is fragile.
|
|
14886
|
-
- find_files: Find files by name pattern (glob). Searches recursively, excludes node_modules/.git.
|
|
14887
|
-
- grep_search: Search file contents with regex. Returns matching lines with paths and line numbers.
|
|
14888
|
-
- shell: Execute any shell command (tests, builds, git, npm, etc.). Supports stdin parameter for input. Commands run with CI=true for non-interactive mode.
|
|
14889
|
-
- list_directory: List files in a directory with types and sizes
|
|
14890
|
-
- web_search: Search the web for documentation or solutions
|
|
14891
|
-
- web_fetch: Fetch a web page and extract text content (for docs, MDN, w3schools.com, etc.)
|
|
14892
|
-
- memory_read: Read from persistent memory (learned patterns, solutions)
|
|
14893
|
-
- memory_write: Store a fact, pattern, or solution in persistent memory for future tasks
|
|
14894
|
-
- task_complete: Signal task completion with a summary
|
|
14895
|
-
|
|
14896
|
-
## Parallel Execution & Sub-Agents
|
|
14897
|
-
|
|
14898
|
-
- background_run: Run a shell command in the background. Returns a task ID immediately.
|
|
14899
|
-
- task_status: Check status of background tasks (or list all)
|
|
14900
|
-
- task_output: Read stdout/stderr from a background task
|
|
14901
|
-
- task_stop: Kill a running background task
|
|
14902
|
-
- sub_agent: Delegate a sub-task to an independent agent with its own context
|
|
14903
|
-
|
|
14904
|
-
IMPORTANT \u2014 True Parallelism:
|
|
14905
|
-
When you issue MULTIPLE tool calls in a SINGLE response, read-only tools (file_read, grep_search,
|
|
14906
|
-
find_files, list_directory, web_fetch, web_search, memory_read, task_status, task_output) execute
|
|
14907
|
-
IN PARALLEL automatically. Use this to dramatically speed up exploration \u2014 call 3-5 file_reads or
|
|
14908
|
-
greps at once instead of one at a time.
|
|
14909
|
-
|
|
14910
|
-
For sub-agents: use background=true and launch MULTIPLE sub_agent calls in one response to run
|
|
14911
|
-
them concurrently against the backend. Each sub-agent gets its own independent context window and
|
|
14912
|
-
makes its own API requests. Check results with task_status/task_output when done.
|
|
14913
|
-
|
|
14914
|
-
PARALLEL SUB-AGENT PATTERN (preferred for independent tasks):
|
|
14915
|
-
1. Call sub_agent({task: "task A", background: true}) AND sub_agent({task: "task B", background: true}) in ONE response
|
|
14916
|
-
2. Both sub-agents run simultaneously against the backend
|
|
14917
|
-
3. Use task_status() to poll, then task_output() to read results
|
|
14918
|
-
|
|
14919
|
-
## Skills (AIWG)
|
|
14920
|
-
|
|
14921
|
-
- skill_list: Discover available skills \u2014 shows descriptions and trigger patterns. Use filter param to search.
|
|
14922
|
-
- skill_execute: Load a skill's full instructions by name. Returns the SKILL.md content with detailed behavioral guidance.
|
|
14923
|
-
|
|
14924
|
-
When a user request matches a skill trigger pattern (listed in your context or discovered via skill_list), call skill_execute to load the skill instructions, then follow them.
|
|
14925
|
-
|
|
14926
|
-
Use background_run for long-running commands (builds, test suites) so you can continue other work.
|
|
14927
|
-
Use sub_agent to parallelize independent sub-tasks or explore different approaches simultaneously.
|
|
14928
|
-
Check task_status periodically and read task_output when tasks complete.
|
|
14929
|
-
|
|
14930
|
-
## Desktop Automation & Vision
|
|
14931
|
-
|
|
14932
|
-
- desktop_click: Click a UI element by natural language description. Takes a screenshot, finds the element with vision, clicks it. Example: desktop_click({target: "the Save button"})
|
|
14933
|
-
- desktop_describe: Take a screenshot and describe what's on screen (or ask a question about it). Use this to "see" the desktop.
|
|
14934
|
-
- vision: Analyze any image with Moondream VLM \u2014 caption, query, detect objects, find click targets
|
|
14935
|
-
- screenshot: Capture the screen or active window
|
|
14936
|
-
- image_read: Read an image file (returns base64, dimensions, OCR text)
|
|
14937
|
-
- ocr: Extract text from an image using OCR (supports region cropping/zoom)
|
|
14938
|
-
|
|
14939
|
-
### Desktop Interaction Workflow
|
|
14940
|
-
|
|
14941
|
-
When asked to interact with desktop applications (open browsers, click buttons, fill forms, etc.):
|
|
14942
|
-
1. Use shell to launch applications: \`firefox https://example.com &\`
|
|
14943
|
-
2. Use screenshot or desktop_describe to see what's on screen
|
|
14944
|
-
3. Use desktop_click to click UI elements: \`desktop_click({target: "Sign Up button"})\`
|
|
14945
|
-
4. Use shell with xdotool for keyboard input: \`xdotool type "username"\` and \`xdotool key Return\`
|
|
14946
|
-
To target a specific window by ID: \`xdotool type --window $WID "text"\` and \`xdotool key --window $WID Return\`
|
|
14947
|
-
IMPORTANT: xdotool type/key use \`--window WID\` flag, NOT positional args. \`xdotool type -- $WID "text"\` is WRONG (types the WID as text).
|
|
14948
|
-
5. Use shell with xdotool for navigation: \`xdotool key Tab\`, \`xdotool key ctrl+l\`
|
|
14949
|
-
6. Take screenshots between steps to verify progress
|
|
14950
|
-
|
|
14951
|
-
You CAN open Firefox, Chrome, or any application. You CAN click buttons, fill forms, and navigate websites.
|
|
14952
|
-
You CAN use xdotool for keyboard/mouse control. These are real capabilities, not hypothetical.
|
|
14953
|
-
|
|
14954
|
-
### Self-Guided Image Exploration
|
|
14955
|
-
|
|
14956
|
-
When you discover image files (png, jpg, gif, svg, webp, bmp) during codebase exploration:
|
|
14957
|
-
- Proactively read them with image_read to understand visual assets, diagrams, and screenshots
|
|
14958
|
-
- Use ocr to extract text from images containing code, diagrams, or documentation
|
|
14959
|
-
- Use ocr with region cropping to zoom into specific areas of large images
|
|
14960
|
-
- If you find architecture diagrams, UI mockups, or annotated screenshots, read and integrate their content
|
|
14961
|
-
- Report what you find in images \u2014 they often contain critical context not in code files
|
|
14962
|
-
- For directories with many images, prioritize: README images, diagrams, screenshots, then decorative assets
|
|
14963
|
-
|
|
14964
|
-
## Workflow
|
|
14965
|
-
|
|
14966
|
-
1. EXPLORE: Use find_files and grep_search to locate relevant code. Read specific files.
|
|
14967
|
-
2. PLAN: Determine what changes are needed based on the code you've read.
|
|
14968
|
-
3. IMPLEMENT: Make changes using file_edit (preferred) or file_write for new files.
|
|
14969
|
-
4. VALIDATE: Run tests/build/lint using shell. Read the FULL output.
|
|
14970
|
-
5. FIX: If validation fails, read the error carefully. Fix the SPECIFIC issue. Re-validate.
|
|
14971
|
-
6. ITERATE: Repeat steps 4-5 until all tests pass. Do NOT give up.
|
|
14972
|
-
7. LEARN: If you discovered something useful, store it with memory_write.
|
|
14973
|
-
8. COMPLETE: Call task_complete ONLY when validation passes.
|
|
14974
|
-
|
|
14975
|
-
## Critical Rules
|
|
14976
|
-
|
|
14977
|
-
- ALWAYS read a file before modifying it \u2014 never guess at file contents
|
|
14978
|
-
- ALWAYS run validation (tests, build, lint) after making changes
|
|
14979
|
-
- If tests fail, read the FULL error output. Fix the exact failing assertion or error.
|
|
14980
|
-
- Do NOT give up after a failure. Iterate: fix \u2192 test \u2192 fix \u2192 test until it passes.
|
|
14981
|
-
- Use grep_search and find_files for efficient exploration (don't dump entire directories)
|
|
14982
|
-
- Use file_edit for small changes instead of rewriting entire files
|
|
14983
|
-
- Keep tool calls focused \u2014 read only what you need
|
|
14984
|
-
- You MUST call task_complete when the task is done
|
|
14985
|
-
|
|
14986
|
-
## Project Awareness
|
|
14987
|
-
|
|
14988
|
-
Your system prompt is dynamically enriched with project context. Before each task:
|
|
14989
|
-
- AGENTS.md, OA.md, CLAUDE.md, and README.md are auto-discovered and loaded
|
|
14990
|
-
- The .oa/ directory stores per-project artifacts (memory, index, session history)
|
|
14991
|
-
- Git state (branch, dirty files, recent commits) is injected
|
|
14992
|
-
- Persistent memories from previous sessions are loaded
|
|
14993
|
-
- Recent session history shows what was worked on before
|
|
14994
|
-
|
|
14995
|
-
When working in a new project, use codebase_map first to orient yourself.
|
|
14996
|
-
Store important discoveries with memory_write for future sessions.
|
|
14997
|
-
|
|
14998
|
-
## Self-Learning
|
|
14999
|
-
|
|
15000
|
-
When you encounter an unfamiliar API, language feature, or runtime behavior:
|
|
15001
|
-
1. Use web_search to find documentation (prefer w3schools.com, MDN, official docs)
|
|
15002
|
-
2. Use web_fetch to read the relevant page
|
|
15003
|
-
3. Use memory_write to store the learned pattern for future reference
|
|
15004
|
-
4. Check memory_read at the start of tasks for previously learned solutions
|
|
15005
|
-
|
|
15006
|
-
## Error Recovery
|
|
15007
|
-
|
|
15008
|
-
When a test or build fails:
|
|
15009
|
-
1. Read the COMPLETE error output from shell \u2014 don't skip lines
|
|
15010
|
-
2. Identify the EXACT file, line, and assertion that failed
|
|
15011
|
-
3. Read that file section with file_read
|
|
15012
|
-
4. Understand WHY it failed (wrong value, missing import, syntax error, etc.)
|
|
15013
|
-
5. Fix with file_edit (precise replacement)
|
|
15014
|
-
6. Re-run the SAME validation command
|
|
15015
|
-
7. If it fails again with a DIFFERENT error, that's progress \u2014 fix the new error
|
|
15016
|
-
8. If it fails with the SAME error, try a different approach
|
|
15017
|
-
9. After 3 failed attempts at the same error, use web_search for solutions
|
|
15018
|
-
|
|
15019
|
-
## Interactive Commands
|
|
15020
|
-
|
|
15021
|
-
Commands run non-interactively (CI=true). When running scaffolding tools:
|
|
15022
|
-
- ALWAYS add non-interactive flags: --yes, --no-input, --defaults, etc.
|
|
15023
|
-
- For npx create-next-app: use --yes (skips all prompts, uses defaults)
|
|
15024
|
-
- For npm init: use -y
|
|
15025
|
-
- If a command needs specific answers, use the stdin parameter
|
|
15026
|
-
- If a command times out, it likely hit an interactive prompt \u2014 retry with --yes
|
|
15027
|
-
|
|
15028
|
-
## Custom Tools
|
|
15029
|
-
|
|
15030
|
-
- create_tool: Create a reusable custom tool from a repeated multi-step workflow. Saves to .oa/tools/ (project) or ~/.open-agents/tools/ (global).
|
|
15031
|
-
- manage_tools: List, inspect, or delete custom tools.
|
|
15032
|
-
|
|
15033
|
-
Custom tools are agent-created shell command sequences that automate repeated workflows.
|
|
15034
|
-
They appear alongside core tools and can be invoked just like any built-in tool.
|
|
15035
|
-
|
|
15036
|
-
### When to Create a Custom Tool
|
|
15037
|
-
|
|
15038
|
-
If you notice you're performing the SAME multi-step sequence for the 3rd time or more:
|
|
15039
|
-
1. Recognize the repeated pattern (e.g., "bump version \u2192 build \u2192 publish \u2192 commit \u2192 push")
|
|
15040
|
-
2. Identify what varies between runs (these become parameters)
|
|
15041
|
-
3. Call create_tool with the steps and parameters
|
|
15042
|
-
4. Choose scope: 'project' for project-specific workflows, 'global' for cross-project patterns
|
|
15043
|
-
|
|
15044
|
-
### Custom Tool Guidelines
|
|
15045
|
-
|
|
15046
|
-
- Name tools descriptively in snake_case (e.g., run_full_validation, deploy_to_staging)
|
|
15047
|
-
- Use {{param}} syntax in step commands for interpolation
|
|
15048
|
-
- Set continueOnError=true on steps that may fail but shouldn't stop the pipeline
|
|
15049
|
-
- Test the tool mentally before creating \u2014 ensure the steps would work in order
|
|
15050
|
-
- Prefer 'project' scope unless the pattern genuinely applies to all projects
|
|
15051
|
-
|
|
15052
|
-
## Nexus P2P Networking & x402 Micropayments
|
|
15053
|
-
|
|
15054
|
-
- nexus: Decentralized agent-to-agent communication via open-agents-nexus.
|
|
15055
|
-
|
|
15056
|
-
open-agents-nexus is auto-installed on first use \u2014 just call connect and it handles the rest.
|
|
15057
|
-
The core flow is simple \u2014 connect, join a room, send/receive messages:
|
|
15058
|
-
nexus(action='connect', agent_name='MyAgent')
|
|
15059
|
-
nexus(action='join_room', room_id='general')
|
|
15060
|
-
nexus(action='send_message', room_id='general', message='Hello from MyAgent!')
|
|
15061
|
-
Everything else (peer discovery, IPFS storage, x402 payments) is automatic.
|
|
15062
|
-
|
|
15063
|
-
Additional actions: disconnect, status, list_rooms, discover_peers, find_agent,
|
|
15064
|
-
register_service, list_services, wallet_status, wallet_create, inference_proof,
|
|
15065
|
-
store_content, retrieve_content.
|
|
15066
|
-
|
|
15067
|
-
SECURITY: Wallet private keys are AES-256-GCM encrypted and NEVER accessible to you.
|
|
15068
|
-
You can see the public address and balance, but NEVER the private key. All outbound messages
|
|
15069
|
-
are scanned for key material leaks. Payment operations use the key internally.
|
|
15070
|
-
|
|
15071
|
-
When the user asks about expanding capabilities or connecting with other agents, suggest
|
|
15072
|
-
enabling nexus networking. Use inference_proof to benchmark and advertise capabilities.
|
|
15073
|
-
|
|
15074
|
-
## Temporal Agency \u2014 Scheduling, Reminders & Long-Horizon Tasks
|
|
15075
|
-
|
|
15076
|
-
You have 4 temporal tools for persistent, cross-session time management:
|
|
15077
|
-
|
|
15078
|
-
- scheduler: Create OS-level cron jobs that launch the agent on a schedule.
|
|
15079
|
-
scheduler(action='schedule', task='Run full test suite', schedule='daily')
|
|
15080
|
-
scheduler(action='list') \u2014 see all scheduled tasks
|
|
15081
|
-
Presets: 'every 5 minutes', 'every hour', 'daily', 'weekly', 'monthly', or raw cron.
|
|
15082
|
-
|
|
15083
|
-
- cron_agent: Like scheduler but with goal tracking, completion criteria, and execution history.
|
|
15084
|
-
cron_agent(action='create', task='Check for dependency updates', goal='Keep deps current',
|
|
15085
|
-
schedule='weekly', completion_criteria='No outdated packages', verify_command='npm outdated')
|
|
15086
|
-
Use for long-horizon autonomous workflows: periodic reviews, monitoring, updates.
|
|
15087
|
-
|
|
15088
|
-
- reminder: Leave a message for your future self across sessions.
|
|
15089
|
-
reminder(action='create', message='Follow up on PR review', due='in 2 hours', priority='high')
|
|
15090
|
-
Reminders surface automatically at agent startup. Use for deferred attention.
|
|
15091
|
-
|
|
15092
|
-
- agenda: View and manage attention directives \u2014 what to focus on across sessions.
|
|
15093
|
-
agenda(action='view') \u2014 see active focus items
|
|
15094
|
-
agenda(action='set', focus='Finish migration before Friday', priority='critical')
|
|
15095
|
-
|
|
15096
|
-
These tools use OS cron (survives process death) and persist state to .oa/ for cross-session continuity.
|
|
15097
|
-
Use cron_agent for recurring autonomous tasks, scheduler for simple repeating commands,
|
|
15098
|
-
reminder for deferred attention, and agenda for strategic focus tracking.
|
|
15099
|
-
|
|
15100
|
-
## Priority Ingress \u2014 Task Classification & Delegation
|
|
15101
|
-
|
|
15102
|
-
When multiple tasks arrive (Telegram, reminders, updates), classify and route them:
|
|
15103
|
-
- priority_classify: Determine a task's priority (critical/high/moderate/normal/low/salient)
|
|
15104
|
-
priority_classify(message='...', source='external', origin='telegram')
|
|
15105
|
-
Returns: priority, weight, delegable flag, handling policy
|
|
15106
|
-
- priority_delegate: Send normal/low/salient tasks to a sub-agent
|
|
15107
|
-
priority_delegate(task_prompt='...', priority='normal')
|
|
15108
|
-
|
|
15109
|
-
Priority handling policies:
|
|
15110
|
-
CRITICAL (100): Interrupt immediately. Handle now.
|
|
15111
|
-
HIGH (80): Interrupt at turn boundary. Handle next.
|
|
15112
|
-
MODERATE (60): Queue, run after current task.
|
|
15113
|
-
NORMAL (40): Can delegate to sub-agent.
|
|
15114
|
-
LOW (20): Should delegate to sub-agent.
|
|
15115
|
-
SALIENT (5): Note for later, delegate if possible.
|
|
15116
|
-
|
|
15117
|
-
## Context Efficiency
|
|
15118
|
-
|
|
15119
|
-
- Use grep_search to find specific code instead of reading many files
|
|
15120
|
-
- Use file_edit for targeted changes instead of full file rewrites
|
|
15121
|
-
- Use file_edit with replace_all=true for variable/function renames across a file
|
|
15122
|
-
- If file_edit fails with "not unique", include more surrounding context in old_string
|
|
15123
|
-
- For large files (500+ lines): use file_read with offset/limit, then file_patch with line numbers
|
|
15124
|
-
- file_patch with dry_run=true lets you preview changes before applying them
|
|
15125
|
-
- batch_edit to apply multiple edits across files in one call (reduces turns)
|
|
15126
|
-
- Focus on error messages in shell output \u2014 skip verbose build logs
|
|
15127
|
-
- Don't read files you don't need to modify`;
|
|
15128
|
-
SYSTEM_PROMPT_MEDIUM = `You are Open Agent, an AI coding agent with access to the local machine. You can read/write files, execute shell commands, search the web, and interact with any software. You solve tasks by using tools iteratively until complete.
|
|
15129
|
-
|
|
15130
|
-
## NEVER REFUSE \u2014 ALWAYS ATTEMPT
|
|
15131
|
-
|
|
15132
|
-
NEVER say "I can't do that". ALWAYS attempt the task using your tools. If a tool fails, try a different approach.
|
|
15133
|
-
|
|
15134
|
-
## Tools
|
|
15135
|
-
|
|
15136
|
-
- file_read: Read file contents (always read before editing)
|
|
15137
|
-
- file_write: Create or overwrite a file
|
|
15138
|
-
- file_edit: Precise string replacement (preferred over rewriting). old_string must be unique.
|
|
15139
|
-
- file_patch: Edit specific line ranges in large files
|
|
15140
|
-
- find_files: Find files by glob pattern
|
|
15141
|
-
- grep_search: Search file contents with regex
|
|
15142
|
-
- shell: Execute any shell command (tests, builds, git, npm, etc.)
|
|
15143
|
-
- list_directory: List files in a directory
|
|
15144
|
-
- web_search: Search the web
|
|
15145
|
-
- web_fetch: Fetch a web page's text
|
|
15146
|
-
- memory_read / memory_write: Persistent memory across sessions
|
|
15147
|
-
- task_complete: Signal task completion
|
|
15148
|
-
- batch_edit: Multiple edits across files in one call
|
|
15149
|
-
- skill_list / skill_execute: Discover and load specialized skills (use on-demand)
|
|
15150
|
-
|
|
15151
|
-
## Workflow
|
|
15152
|
-
|
|
15153
|
-
1. EXPLORE: Use find_files, grep_search, file_read to understand the codebase
|
|
15154
|
-
2. IMPLEMENT: Make changes with file_edit (preferred) or file_write
|
|
15155
|
-
3. VALIDATE: Run tests/build with shell. Read FULL output.
|
|
15156
|
-
4. FIX: If validation fails, fix the specific issue and re-validate
|
|
15157
|
-
5. ITERATE: Repeat until all tests pass. Do NOT give up.
|
|
15158
|
-
6. COMPLETE: Call task_complete when done
|
|
15159
|
-
|
|
15160
|
-
## Rules
|
|
15161
|
-
|
|
15162
|
-
- ALWAYS read a file before modifying it
|
|
15163
|
-
- ALWAYS run validation after changes
|
|
15164
|
-
- If tests fail, read the FULL error. Fix the exact issue.
|
|
15165
|
-
- Do NOT give up after failure. Iterate until it passes.
|
|
15166
|
-
- Use file_edit for small changes, not full file rewrites
|
|
15167
|
-
- You MUST call task_complete when done
|
|
15168
|
-
- Do NOT output long explanations. Focus on tool calls.`;
|
|
15169
|
-
SYSTEM_PROMPT_SMALL = `You are a coding agent. You MUST call tools in EVERY response. NEVER reply with only text.
|
|
15170
|
-
|
|
15171
|
-
Tools: file_read, file_write, file_edit, shell, task_complete, find_files, grep_search, web_search, web_fetch
|
|
15172
|
-
|
|
15173
|
-
Steps:
|
|
15174
|
-
1. file_read the source files AND test files
|
|
15175
|
-
2. file_edit or file_write to make changes
|
|
15176
|
-
3. shell to run tests (npm test, etc.)
|
|
15177
|
-
4. If tests fail: read error, fix, retest
|
|
15178
|
-
5. task_complete when tests pass
|
|
15179
|
-
|
|
15180
|
-
Rules:
|
|
15181
|
-
- ALWAYS call tools. NEVER just write text.
|
|
15182
|
-
- Read files before editing them.
|
|
15183
|
-
- Run tests after every change.
|
|
15184
|
-
- Call task_complete when done.`;
|
|
14810
|
+
init_promptLoader();
|
|
14811
|
+
SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
|
|
14812
|
+
SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
|
|
14813
|
+
SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
|
|
15185
14814
|
AgenticRunner = class {
|
|
15186
14815
|
backend;
|
|
15187
14816
|
tools = /* @__PURE__ */ new Map();
|
|
@@ -15206,6 +14835,8 @@ Rules:
|
|
|
15206
14835
|
_fileRegistry = /* @__PURE__ */ new Map();
|
|
15207
14836
|
// -- Memex Experience Archive (arXiv:2603.04257 inspired) --
|
|
15208
14837
|
_memexArchive = /* @__PURE__ */ new Map();
|
|
14838
|
+
// -- Consecutive ENOENT tracker (prevents path-guessing spirals) --
|
|
14839
|
+
_consecutiveEnoent = 0;
|
|
15209
14840
|
// -- Session Checkpointing (Priority 5) --
|
|
15210
14841
|
_sessionId = `session-${Date.now()}`;
|
|
15211
14842
|
_workingDirectory = "";
|
|
@@ -15719,6 +15350,19 @@ ${result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : resul
|
|
|
15719
15350
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
15720
15351
|
});
|
|
15721
15352
|
}
|
|
15353
|
+
const enoentTools = /* @__PURE__ */ new Set(["file_read", "list_directory", "find_files"]);
|
|
15354
|
+
if (!result.success && enoentTools.has(tc.name) && /ENOENT|no such file|does not exist/i.test(result.error ?? result.output)) {
|
|
15355
|
+
this._consecutiveEnoent++;
|
|
15356
|
+
if (this._consecutiveEnoent >= 2) {
|
|
15357
|
+
this.pendingUserMessages.push(`[SYSTEM] You have hit ${this._consecutiveEnoent} consecutive ENOENT errors. STOP guessing paths. Instead:
|
|
15358
|
+
1. Use list_directory on the PROJECT ROOT to discover what actually exists
|
|
15359
|
+
2. If the missing path came from memory, use memory_write to remove the stale reference
|
|
15360
|
+
3. Navigate from the root to find the correct location
|
|
15361
|
+
Do NOT continue walking up parent directories.`);
|
|
15362
|
+
}
|
|
15363
|
+
} else {
|
|
15364
|
+
this._consecutiveEnoent = 0;
|
|
15365
|
+
}
|
|
15722
15366
|
return { tc, output };
|
|
15723
15367
|
};
|
|
15724
15368
|
const parallelBatch = [];
|
|
@@ -15940,6 +15584,19 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
15940
15584
|
...(truncated)` : result.output : `Error: ${result.error || "unknown error"}
|
|
15941
15585
|
${result.output}`;
|
|
15942
15586
|
this.emit({ type: "tool_result", toolName: tc.name, content: output.slice(0, 200), success: result.success, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
15587
|
+
const enoentTools2 = /* @__PURE__ */ new Set(["file_read", "list_directory", "find_files"]);
|
|
15588
|
+
if (!result.success && enoentTools2.has(tc.name) && /ENOENT|no such file|does not exist/i.test(result.error ?? result.output)) {
|
|
15589
|
+
this._consecutiveEnoent++;
|
|
15590
|
+
if (this._consecutiveEnoent >= 2) {
|
|
15591
|
+
this.pendingUserMessages.push(`[SYSTEM] You have hit ${this._consecutiveEnoent} consecutive ENOENT errors. STOP guessing paths. Instead:
|
|
15592
|
+
1. Use list_directory on the PROJECT ROOT to discover what actually exists
|
|
15593
|
+
2. If the missing path came from memory, use memory_write to remove the stale reference
|
|
15594
|
+
3. Navigate from the root to find the correct location
|
|
15595
|
+
Do NOT continue walking up parent directories.`);
|
|
15596
|
+
}
|
|
15597
|
+
} else {
|
|
15598
|
+
this._consecutiveEnoent = 0;
|
|
15599
|
+
}
|
|
15943
15600
|
const toolMsg = this.buildToolMessage(output, tc.id);
|
|
15944
15601
|
messages.push(toolMsg);
|
|
15945
15602
|
if (tc.name === "task_complete") {
|
|
@@ -16122,8 +15779,8 @@ ${marker}` : marker);
|
|
|
16122
15779
|
return;
|
|
16123
15780
|
try {
|
|
16124
15781
|
const { mkdirSync: mkdirSync17, writeFileSync: writeFileSync15 } = __require("node:fs");
|
|
16125
|
-
const { join:
|
|
16126
|
-
const sessionDir =
|
|
15782
|
+
const { join: join52 } = __require("node:path");
|
|
15783
|
+
const sessionDir = join52(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
16127
15784
|
mkdirSync17(sessionDir, { recursive: true });
|
|
16128
15785
|
const checkpoint = {
|
|
16129
15786
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -16136,7 +15793,7 @@ ${marker}` : marker);
|
|
|
16136
15793
|
memexEntryCount: this._memexArchive.size,
|
|
16137
15794
|
fileRegistrySize: this._fileRegistry.size
|
|
16138
15795
|
};
|
|
16139
|
-
writeFileSync15(
|
|
15796
|
+
writeFileSync15(join52(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
16140
15797
|
} catch {
|
|
16141
15798
|
}
|
|
16142
15799
|
}
|
|
@@ -16864,7 +16521,7 @@ Last analysis: ${lastAssistantText.slice(0, 300)}${lastAssistantText.length > 30
|
|
|
16864
16521
|
const summaryPrompt = [
|
|
16865
16522
|
{
|
|
16866
16523
|
role: "system",
|
|
16867
|
-
content: "
|
|
16524
|
+
content: loadPrompt("compaction/context-compaction.md")
|
|
16868
16525
|
},
|
|
16869
16526
|
{
|
|
16870
16527
|
role: "user",
|
|
@@ -17374,41 +17031,22 @@ function getRubric(taskType) {
|
|
|
17374
17031
|
}
|
|
17375
17032
|
function buildEvaluationPrompt(task, summary, rubric) {
|
|
17376
17033
|
const dimensionList = rubric.dimensions.map((d, i) => `${i + 1}. **${d.name}** (${Math.round(d.weight * 100)}%): ${d.criteria}`).join("\n");
|
|
17377
|
-
return
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
|
|
17382
|
-
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17386
|
-
|
|
17387
|
-
|
|
17388
|
-
## Instructions
|
|
17389
|
-
For each dimension, provide:
|
|
17390
|
-
1. A score from 0-10 (0 = completely missing, 5 = adequate, 10 = exceptional)
|
|
17391
|
-
2. A brief explanation (1-2 sentences)
|
|
17392
|
-
|
|
17393
|
-
Then provide an overall summary of the work quality.
|
|
17394
|
-
|
|
17395
|
-
Respond in EXACTLY this JSON format:
|
|
17396
|
-
{
|
|
17397
|
-
"dimensions": [
|
|
17398
|
-
{"name": "${rubric.dimensions[0].name}", "score": <0-10>, "feedback": "<explanation>"},
|
|
17399
|
-
{"name": "${rubric.dimensions[1].name}", "score": <0-10>, "feedback": "<explanation>"},
|
|
17400
|
-
{"name": "${rubric.dimensions[2].name}", "score": <0-10>, "feedback": "<explanation>"},
|
|
17401
|
-
{"name": "${rubric.dimensions[3].name}", "score": <0-10>, "feedback": "<explanation>"}
|
|
17402
|
-
],
|
|
17403
|
-
"summary": "<2-3 sentence overall assessment>"
|
|
17404
|
-
}
|
|
17405
|
-
|
|
17406
|
-
Respond with ONLY the JSON object, no other text.`;
|
|
17034
|
+
return loadPrompt("runners/evaluator.md", {
|
|
17035
|
+
task,
|
|
17036
|
+
summary,
|
|
17037
|
+
rubricLabel: rubric.label,
|
|
17038
|
+
dimensionList,
|
|
17039
|
+
dim0: rubric.dimensions[0].name,
|
|
17040
|
+
dim1: rubric.dimensions[1].name,
|
|
17041
|
+
dim2: rubric.dimensions[2].name,
|
|
17042
|
+
dim3: rubric.dimensions[3].name
|
|
17043
|
+
});
|
|
17407
17044
|
}
|
|
17408
17045
|
var RUBRICS, TASK_TYPE_PATTERNS, WorkEvaluator;
|
|
17409
17046
|
var init_workEvaluator = __esm({
|
|
17410
17047
|
"packages/orchestrator/dist/workEvaluator.js"() {
|
|
17411
17048
|
"use strict";
|
|
17049
|
+
init_promptLoader();
|
|
17412
17050
|
RUBRICS = {
|
|
17413
17051
|
code: {
|
|
17414
17052
|
type: "code",
|
|
@@ -17719,10 +17357,10 @@ __export(listen_exports, {
|
|
|
17719
17357
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
17720
17358
|
});
|
|
17721
17359
|
import { spawn as spawn11, execSync as execSync22 } from "node:child_process";
|
|
17722
|
-
import { existsSync as
|
|
17723
|
-
import { join as
|
|
17360
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
|
|
17361
|
+
import { join as join32, dirname as dirname11 } from "node:path";
|
|
17724
17362
|
import { homedir as homedir8 } from "node:os";
|
|
17725
|
-
import { fileURLToPath as
|
|
17363
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
17726
17364
|
import { EventEmitter } from "node:events";
|
|
17727
17365
|
import { createInterface as createInterface2 } from "node:readline";
|
|
17728
17366
|
function isAudioPath(path) {
|
|
@@ -17804,17 +17442,17 @@ function findMicCaptureCommand() {
|
|
|
17804
17442
|
return null;
|
|
17805
17443
|
}
|
|
17806
17444
|
function findLiveWhisperScript() {
|
|
17807
|
-
const thisDir =
|
|
17445
|
+
const thisDir = dirname11(fileURLToPath8(import.meta.url));
|
|
17808
17446
|
const candidates = [
|
|
17809
|
-
|
|
17810
|
-
|
|
17811
|
-
|
|
17447
|
+
join32(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
17448
|
+
join32(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
17449
|
+
join32(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
17812
17450
|
// npm install layout — scripts bundled alongside dist
|
|
17813
|
-
|
|
17814
|
-
|
|
17451
|
+
join32(thisDir, "../scripts/live-whisper.py"),
|
|
17452
|
+
join32(thisDir, "../../scripts/live-whisper.py")
|
|
17815
17453
|
];
|
|
17816
17454
|
for (const p of candidates) {
|
|
17817
|
-
if (
|
|
17455
|
+
if (existsSync23(p))
|
|
17818
17456
|
return p;
|
|
17819
17457
|
}
|
|
17820
17458
|
try {
|
|
@@ -17824,21 +17462,21 @@ function findLiveWhisperScript() {
|
|
|
17824
17462
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17825
17463
|
}).trim();
|
|
17826
17464
|
const candidates2 = [
|
|
17827
|
-
|
|
17828
|
-
|
|
17465
|
+
join32(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
17466
|
+
join32(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
17829
17467
|
];
|
|
17830
17468
|
for (const p of candidates2) {
|
|
17831
|
-
if (
|
|
17469
|
+
if (existsSync23(p))
|
|
17832
17470
|
return p;
|
|
17833
17471
|
}
|
|
17834
17472
|
} catch {
|
|
17835
17473
|
}
|
|
17836
|
-
const nvmBase =
|
|
17837
|
-
if (
|
|
17474
|
+
const nvmBase = join32(homedir8(), ".nvm", "versions", "node");
|
|
17475
|
+
if (existsSync23(nvmBase)) {
|
|
17838
17476
|
try {
|
|
17839
17477
|
for (const ver of readdirSync6(nvmBase)) {
|
|
17840
|
-
const p =
|
|
17841
|
-
if (
|
|
17478
|
+
const p = join32(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
17479
|
+
if (existsSync23(p))
|
|
17842
17480
|
return p;
|
|
17843
17481
|
}
|
|
17844
17482
|
} catch {
|
|
@@ -17856,7 +17494,7 @@ function ensureTranscribeCliBackground() {
|
|
|
17856
17494
|
timeout: 5e3,
|
|
17857
17495
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17858
17496
|
}).trim();
|
|
17859
|
-
if (
|
|
17497
|
+
if (existsSync23(join32(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
17860
17498
|
return true;
|
|
17861
17499
|
}
|
|
17862
17500
|
} catch {
|
|
@@ -18079,24 +17717,24 @@ var init_listen = __esm({
|
|
|
18079
17717
|
timeout: 5e3,
|
|
18080
17718
|
stdio: ["pipe", "pipe", "pipe"]
|
|
18081
17719
|
}).trim();
|
|
18082
|
-
const tcPath =
|
|
18083
|
-
if (
|
|
17720
|
+
const tcPath = join32(globalRoot, "transcribe-cli");
|
|
17721
|
+
if (existsSync23(join32(tcPath, "dist", "index.js"))) {
|
|
18084
17722
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
18085
17723
|
const req = createRequire4(import.meta.url);
|
|
18086
|
-
return req(
|
|
17724
|
+
return req(join32(tcPath, "dist", "index.js"));
|
|
18087
17725
|
}
|
|
18088
17726
|
} catch {
|
|
18089
17727
|
}
|
|
18090
|
-
const nvmBase =
|
|
18091
|
-
if (
|
|
17728
|
+
const nvmBase = join32(homedir8(), ".nvm", "versions", "node");
|
|
17729
|
+
if (existsSync23(nvmBase)) {
|
|
18092
17730
|
try {
|
|
18093
17731
|
const { readdirSync: readdirSync15 } = await import("node:fs");
|
|
18094
17732
|
for (const ver of readdirSync15(nvmBase)) {
|
|
18095
|
-
const tcPath =
|
|
18096
|
-
if (
|
|
17733
|
+
const tcPath = join32(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
17734
|
+
if (existsSync23(join32(tcPath, "dist", "index.js"))) {
|
|
18097
17735
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
18098
17736
|
const req = createRequire4(import.meta.url);
|
|
18099
|
-
return req(
|
|
17737
|
+
return req(join32(tcPath, "dist", "index.js"));
|
|
18100
17738
|
}
|
|
18101
17739
|
}
|
|
18102
17740
|
} catch {
|
|
@@ -18378,9 +18016,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
18378
18016
|
});
|
|
18379
18017
|
if (outputDir) {
|
|
18380
18018
|
const { basename: basename16 } = await import("node:path");
|
|
18381
|
-
const transcriptDir =
|
|
18019
|
+
const transcriptDir = join32(outputDir, ".oa", "transcripts");
|
|
18382
18020
|
mkdirSync6(transcriptDir, { recursive: true });
|
|
18383
|
-
const outFile =
|
|
18021
|
+
const outFile = join32(transcriptDir, `${basename16(filePath)}.txt`);
|
|
18384
18022
|
writeFileSync6(outFile, result.text, "utf-8");
|
|
18385
18023
|
}
|
|
18386
18024
|
return {
|
|
@@ -23955,8 +23593,8 @@ var init_types = __esm({
|
|
|
23955
23593
|
|
|
23956
23594
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
23957
23595
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
23958
|
-
import { readFileSync as
|
|
23959
|
-
import { join as
|
|
23596
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
|
|
23597
|
+
import { join as join33, dirname as dirname12 } from "node:path";
|
|
23960
23598
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
23961
23599
|
var init_secret_vault = __esm({
|
|
23962
23600
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -24167,8 +23805,8 @@ var init_secret_vault = __esm({
|
|
|
24167
23805
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
24168
23806
|
const tag = cipher.getAuthTag();
|
|
24169
23807
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
24170
|
-
const dir =
|
|
24171
|
-
if (!
|
|
23808
|
+
const dir = dirname12(this.storePath);
|
|
23809
|
+
if (!existsSync24(dir))
|
|
24172
23810
|
mkdirSync7(dir, { recursive: true });
|
|
24173
23811
|
writeFileSync7(this.storePath, blob, { mode: 384 });
|
|
24174
23812
|
}
|
|
@@ -24177,9 +23815,9 @@ var init_secret_vault = __esm({
|
|
|
24177
23815
|
* Returns the number of secrets loaded.
|
|
24178
23816
|
*/
|
|
24179
23817
|
load(passphrase) {
|
|
24180
|
-
if (!this.storePath || !
|
|
23818
|
+
if (!this.storePath || !existsSync24(this.storePath))
|
|
24181
23819
|
return 0;
|
|
24182
|
-
const blob =
|
|
23820
|
+
const blob = readFileSync16(this.storePath);
|
|
24183
23821
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
24184
23822
|
throw new Error("Vault file is corrupted (too small)");
|
|
24185
23823
|
}
|
|
@@ -25389,6 +25027,37 @@ var init_render2 = __esm({
|
|
|
25389
25027
|
}
|
|
25390
25028
|
});
|
|
25391
25029
|
|
|
25030
|
+
// packages/prompts/dist/promptLoader.js
|
|
25031
|
+
import { readFileSync as readFileSync17, existsSync as existsSync25 } from "node:fs";
|
|
25032
|
+
import { join as join34, dirname as dirname13 } from "node:path";
|
|
25033
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
25034
|
+
function loadPrompt2(promptPath, vars) {
|
|
25035
|
+
let content = cache2.get(promptPath);
|
|
25036
|
+
if (content === void 0) {
|
|
25037
|
+
const fullPath = join34(PROMPTS_DIR2, promptPath);
|
|
25038
|
+
if (!existsSync25(fullPath)) {
|
|
25039
|
+
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
25040
|
+
}
|
|
25041
|
+
content = readFileSync17(fullPath, "utf-8");
|
|
25042
|
+
cache2.set(promptPath, content);
|
|
25043
|
+
}
|
|
25044
|
+
if (!vars)
|
|
25045
|
+
return content;
|
|
25046
|
+
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
25047
|
+
}
|
|
25048
|
+
var __filename2, __dirname4, devPath, publishedPath, PROMPTS_DIR2, cache2;
|
|
25049
|
+
var init_promptLoader2 = __esm({
|
|
25050
|
+
"packages/prompts/dist/promptLoader.js"() {
|
|
25051
|
+
"use strict";
|
|
25052
|
+
__filename2 = fileURLToPath9(import.meta.url);
|
|
25053
|
+
__dirname4 = dirname13(__filename2);
|
|
25054
|
+
devPath = join34(__dirname4, "..", "templates");
|
|
25055
|
+
publishedPath = join34(__dirname4, "..", "prompts", "templates");
|
|
25056
|
+
PROMPTS_DIR2 = existsSync25(devPath) ? devPath : publishedPath;
|
|
25057
|
+
cache2 = /* @__PURE__ */ new Map();
|
|
25058
|
+
}
|
|
25059
|
+
});
|
|
25060
|
+
|
|
25392
25061
|
// packages/prompts/dist/task-templates.js
|
|
25393
25062
|
function getTaskTemplate(type) {
|
|
25394
25063
|
return TEMPLATES[type];
|
|
@@ -25407,24 +25076,13 @@ var TEMPLATES;
|
|
|
25407
25076
|
var init_task_templates = __esm({
|
|
25408
25077
|
"packages/prompts/dist/task-templates.js"() {
|
|
25409
25078
|
"use strict";
|
|
25079
|
+
init_promptLoader2();
|
|
25410
25080
|
TEMPLATES = {
|
|
25411
25081
|
code: {
|
|
25412
25082
|
type: "code",
|
|
25413
25083
|
label: "Software Development",
|
|
25414
25084
|
description: "Writing, debugging, refactoring, or reviewing code.",
|
|
25415
|
-
systemPromptAddition:
|
|
25416
|
-
## Task Context: Software Development
|
|
25417
|
-
|
|
25418
|
-
You are working on a software development task. Follow these principles:
|
|
25419
|
-
|
|
25420
|
-
- **Read before writing**: Always read the existing code and understand the context before making changes.
|
|
25421
|
-
- **Test-driven approach**: Run existing tests first, make changes, then verify tests still pass.
|
|
25422
|
-
- **Minimal changes**: Make the smallest change that solves the problem. Avoid refactoring unrelated code.
|
|
25423
|
-
- **Convention adherence**: Match the existing code style, naming conventions, and patterns in the project.
|
|
25424
|
-
- **Error handling**: Ensure proper error handling and edge case coverage.
|
|
25425
|
-
- **File organization**: Follow the existing project structure when adding new files.
|
|
25426
|
-
|
|
25427
|
-
When the task is complete, verify by running tests and/or type-checking where available.`,
|
|
25085
|
+
systemPromptAddition: loadPrompt2("code.md"),
|
|
25428
25086
|
recommendedTools: [
|
|
25429
25087
|
"file_read",
|
|
25430
25088
|
"file_write",
|
|
@@ -25441,19 +25099,7 @@ When the task is complete, verify by running tests and/or type-checking where av
|
|
|
25441
25099
|
type: "document",
|
|
25442
25100
|
label: "Document Drafting",
|
|
25443
25101
|
description: "Creating reports, specifications, guides, proposals, or other professional documents.",
|
|
25444
|
-
systemPromptAddition:
|
|
25445
|
-
## Task Context: Document Drafting
|
|
25446
|
-
|
|
25447
|
-
You are working on a professional document. Follow these principles:
|
|
25448
|
-
|
|
25449
|
-
- **Audience awareness**: Tailor language, depth, and terminology to the intended audience.
|
|
25450
|
-
- **Structure first**: Create a clear outline before filling in content. Use headings, sections, and lists.
|
|
25451
|
-
- **Completeness**: Cover all aspects the user requested. Flag any areas where you need clarification.
|
|
25452
|
-
- **Clarity**: Use clear, concise language. Avoid jargon unless appropriate for the audience.
|
|
25453
|
-
- **Formatting**: Use appropriate markdown formatting \u2014 tables for data, code blocks for technical content, lists for enumerations.
|
|
25454
|
-
- **Citations**: When referencing external information, note sources or indicate where citations are needed.
|
|
25455
|
-
|
|
25456
|
-
Use the create_structured_file tool for spreadsheets, CSV, or formatted output. Use file_write for documents.`,
|
|
25102
|
+
systemPromptAddition: loadPrompt2("document.md"),
|
|
25457
25103
|
recommendedTools: [
|
|
25458
25104
|
"file_read",
|
|
25459
25105
|
"file_write",
|
|
@@ -25468,20 +25114,7 @@ Use the create_structured_file tool for spreadsheets, CSV, or formatted output.
|
|
|
25468
25114
|
type: "analysis",
|
|
25469
25115
|
label: "Analysis & Research",
|
|
25470
25116
|
description: "Analyzing data, evaluating options, conducting research, or producing insights.",
|
|
25471
|
-
systemPromptAddition:
|
|
25472
|
-
## Task Context: Analysis & Research
|
|
25473
|
-
|
|
25474
|
-
You are working on an analytical task. Follow these principles:
|
|
25475
|
-
|
|
25476
|
-
- **Evidence-based**: Ground conclusions in data, code, or verifiable sources. Avoid speculation.
|
|
25477
|
-
- **Methodology**: State your analytical approach clearly. When comparing options, define criteria upfront.
|
|
25478
|
-
- **Quantify**: Use numbers, metrics, and measurements wherever possible. Avoid vague qualifiers.
|
|
25479
|
-
- **Visualization**: Present data in tables or structured formats for clarity.
|
|
25480
|
-
- **Limitations**: Acknowledge limitations in your analysis \u2014 data gaps, assumptions, scope boundaries.
|
|
25481
|
-
- **Actionable conclusions**: End with clear recommendations or next steps.
|
|
25482
|
-
|
|
25483
|
-
Use web_search for external research. Use grep_search and codebase_map for codebase analysis.
|
|
25484
|
-
Use create_structured_file to output data as CSV, JSON, or markdown tables.`,
|
|
25117
|
+
systemPromptAddition: loadPrompt2("analysis.md"),
|
|
25485
25118
|
recommendedTools: [
|
|
25486
25119
|
"file_read",
|
|
25487
25120
|
"grep_search",
|
|
@@ -25498,21 +25131,7 @@ Use create_structured_file to output data as CSV, JSON, or markdown tables.`,
|
|
|
25498
25131
|
type: "plan",
|
|
25499
25132
|
label: "Planning & Design",
|
|
25500
25133
|
description: "Creating project plans, system designs, architecture proposals, or roadmaps.",
|
|
25501
|
-
systemPromptAddition:
|
|
25502
|
-
## Task Context: Planning & Design
|
|
25503
|
-
|
|
25504
|
-
You are working on a planning or design task. Follow these principles:
|
|
25505
|
-
|
|
25506
|
-
- **Scope clarity**: Define what is in-scope and out-of-scope explicitly.
|
|
25507
|
-
- **Phased approach**: Break work into phases or milestones with clear dependencies.
|
|
25508
|
-
- **Risk identification**: Identify key risks, assumptions, and dependencies for each phase.
|
|
25509
|
-
- **Resource awareness**: Consider team size, skill requirements, and tool/infrastructure needs.
|
|
25510
|
-
- **Alternatives**: When making design decisions, briefly note alternatives considered and why the chosen approach is preferred.
|
|
25511
|
-
- **Actionable items**: Every section should include concrete next steps or action items.
|
|
25512
|
-
- **Traceability**: Link plan items to requirements or goals where applicable.
|
|
25513
|
-
|
|
25514
|
-
Use codebase_map and grep_search to understand existing architecture.
|
|
25515
|
-
Use create_structured_file for timeline/schedule output.`,
|
|
25134
|
+
systemPromptAddition: loadPrompt2("plan.md"),
|
|
25516
25135
|
recommendedTools: [
|
|
25517
25136
|
"file_read",
|
|
25518
25137
|
"grep_search",
|
|
@@ -25529,15 +25148,7 @@ Use create_structured_file for timeline/schedule output.`,
|
|
|
25529
25148
|
type: "general",
|
|
25530
25149
|
label: "General Task",
|
|
25531
25150
|
description: "Tasks that don't clearly fit another category.",
|
|
25532
|
-
systemPromptAddition:
|
|
25533
|
-
## Task Context: General
|
|
25534
|
-
|
|
25535
|
-
Approach this task thoughtfully:
|
|
25536
|
-
|
|
25537
|
-
- **Clarify intent**: If the task is ambiguous, use available tools to gather context before proceeding.
|
|
25538
|
-
- **Appropriate tools**: Select the right tools for the job \u2014 file tools for file work, search for research, shell for commands.
|
|
25539
|
-
- **Quality output**: Regardless of task type, produce clear, complete, and well-organized output.
|
|
25540
|
-
- **Verify results**: After completing work, verify the results are correct and complete.`,
|
|
25151
|
+
systemPromptAddition: loadPrompt2("general.md"),
|
|
25541
25152
|
recommendedTools: [
|
|
25542
25153
|
"file_read",
|
|
25543
25154
|
"file_write",
|
|
@@ -25553,8 +25164,8 @@ Approach this task thoughtfully:
|
|
|
25553
25164
|
});
|
|
25554
25165
|
|
|
25555
25166
|
// packages/prompts/dist/index.js
|
|
25556
|
-
import { join as
|
|
25557
|
-
import { fileURLToPath as
|
|
25167
|
+
import { join as join35, dirname as dirname14 } from "node:path";
|
|
25168
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
25558
25169
|
var _dir, _packageRoot;
|
|
25559
25170
|
var init_dist6 = __esm({
|
|
25560
25171
|
"packages/prompts/dist/index.js"() {
|
|
@@ -25563,25 +25174,25 @@ var init_dist6 = __esm({
|
|
|
25563
25174
|
init_render2();
|
|
25564
25175
|
init_task_templates();
|
|
25565
25176
|
init_render2();
|
|
25566
|
-
_dir =
|
|
25567
|
-
_packageRoot =
|
|
25177
|
+
_dir = dirname14(fileURLToPath10(import.meta.url));
|
|
25178
|
+
_packageRoot = join35(_dir, "..");
|
|
25568
25179
|
}
|
|
25569
25180
|
});
|
|
25570
25181
|
|
|
25571
25182
|
// packages/cli/dist/tui/oa-directory.js
|
|
25572
|
-
import { existsSync as
|
|
25573
|
-
import { join as
|
|
25183
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as readFileSync18, writeFileSync as writeFileSync8, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
|
|
25184
|
+
import { join as join36, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
25574
25185
|
import { homedir as homedir9 } from "node:os";
|
|
25575
25186
|
function initOaDirectory(repoRoot) {
|
|
25576
|
-
const oaPath =
|
|
25187
|
+
const oaPath = join36(repoRoot, OA_DIR);
|
|
25577
25188
|
for (const sub of SUBDIRS) {
|
|
25578
|
-
mkdirSync8(
|
|
25189
|
+
mkdirSync8(join36(oaPath, sub), { recursive: true });
|
|
25579
25190
|
}
|
|
25580
25191
|
try {
|
|
25581
|
-
const gitignorePath =
|
|
25192
|
+
const gitignorePath = join36(repoRoot, ".gitignore");
|
|
25582
25193
|
const settingsPattern = ".oa/settings.json";
|
|
25583
|
-
if (
|
|
25584
|
-
const content =
|
|
25194
|
+
if (existsSync26(gitignorePath)) {
|
|
25195
|
+
const content = readFileSync18(gitignorePath, "utf-8");
|
|
25585
25196
|
if (!content.includes(settingsPattern)) {
|
|
25586
25197
|
writeFileSync8(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
25587
25198
|
}
|
|
@@ -25591,41 +25202,41 @@ function initOaDirectory(repoRoot) {
|
|
|
25591
25202
|
return oaPath;
|
|
25592
25203
|
}
|
|
25593
25204
|
function hasOaDirectory(repoRoot) {
|
|
25594
|
-
return
|
|
25205
|
+
return existsSync26(join36(repoRoot, OA_DIR, "index"));
|
|
25595
25206
|
}
|
|
25596
25207
|
function loadProjectSettings(repoRoot) {
|
|
25597
|
-
const settingsPath =
|
|
25208
|
+
const settingsPath = join36(repoRoot, OA_DIR, "settings.json");
|
|
25598
25209
|
try {
|
|
25599
|
-
if (
|
|
25600
|
-
return JSON.parse(
|
|
25210
|
+
if (existsSync26(settingsPath)) {
|
|
25211
|
+
return JSON.parse(readFileSync18(settingsPath, "utf-8"));
|
|
25601
25212
|
}
|
|
25602
25213
|
} catch {
|
|
25603
25214
|
}
|
|
25604
25215
|
return {};
|
|
25605
25216
|
}
|
|
25606
25217
|
function saveProjectSettings(repoRoot, settings) {
|
|
25607
|
-
const oaPath =
|
|
25218
|
+
const oaPath = join36(repoRoot, OA_DIR);
|
|
25608
25219
|
mkdirSync8(oaPath, { recursive: true });
|
|
25609
25220
|
const existing = loadProjectSettings(repoRoot);
|
|
25610
25221
|
const merged = { ...existing, ...settings };
|
|
25611
|
-
writeFileSync8(
|
|
25222
|
+
writeFileSync8(join36(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
25612
25223
|
}
|
|
25613
25224
|
function loadGlobalSettings() {
|
|
25614
|
-
const settingsPath =
|
|
25225
|
+
const settingsPath = join36(homedir9(), ".open-agents", "settings.json");
|
|
25615
25226
|
try {
|
|
25616
|
-
if (
|
|
25617
|
-
return JSON.parse(
|
|
25227
|
+
if (existsSync26(settingsPath)) {
|
|
25228
|
+
return JSON.parse(readFileSync18(settingsPath, "utf-8"));
|
|
25618
25229
|
}
|
|
25619
25230
|
} catch {
|
|
25620
25231
|
}
|
|
25621
25232
|
return {};
|
|
25622
25233
|
}
|
|
25623
25234
|
function saveGlobalSettings(settings) {
|
|
25624
|
-
const dir =
|
|
25235
|
+
const dir = join36(homedir9(), ".open-agents");
|
|
25625
25236
|
mkdirSync8(dir, { recursive: true });
|
|
25626
25237
|
const existing = loadGlobalSettings();
|
|
25627
25238
|
const merged = { ...existing, ...settings };
|
|
25628
|
-
writeFileSync8(
|
|
25239
|
+
writeFileSync8(join36(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
25629
25240
|
}
|
|
25630
25241
|
function resolveSettings(repoRoot) {
|
|
25631
25242
|
const global = loadGlobalSettings();
|
|
@@ -25640,12 +25251,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25640
25251
|
while (dir && !visited.has(dir)) {
|
|
25641
25252
|
visited.add(dir);
|
|
25642
25253
|
for (const name of CONTEXT_FILES) {
|
|
25643
|
-
const filePath =
|
|
25254
|
+
const filePath = join36(dir, name);
|
|
25644
25255
|
const normalizedName = name.toLowerCase();
|
|
25645
|
-
if (
|
|
25256
|
+
if (existsSync26(filePath) && !seen.has(filePath)) {
|
|
25646
25257
|
seen.add(filePath);
|
|
25647
25258
|
try {
|
|
25648
|
-
let content =
|
|
25259
|
+
let content = readFileSync18(filePath, "utf-8");
|
|
25649
25260
|
if (content.length > maxContentLen) {
|
|
25650
25261
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
25651
25262
|
}
|
|
@@ -25659,11 +25270,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25659
25270
|
}
|
|
25660
25271
|
}
|
|
25661
25272
|
}
|
|
25662
|
-
const projectMap =
|
|
25663
|
-
if (
|
|
25273
|
+
const projectMap = join36(dir, OA_DIR, "context", "project-map.md");
|
|
25274
|
+
if (existsSync26(projectMap) && !seen.has(projectMap)) {
|
|
25664
25275
|
seen.add(projectMap);
|
|
25665
25276
|
try {
|
|
25666
|
-
let content =
|
|
25277
|
+
let content = readFileSync18(projectMap, "utf-8");
|
|
25667
25278
|
if (content.length > maxContentLen) {
|
|
25668
25279
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
25669
25280
|
}
|
|
@@ -25675,7 +25286,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25675
25286
|
} catch {
|
|
25676
25287
|
}
|
|
25677
25288
|
}
|
|
25678
|
-
const parent =
|
|
25289
|
+
const parent = join36(dir, "..");
|
|
25679
25290
|
if (parent === dir)
|
|
25680
25291
|
break;
|
|
25681
25292
|
dir = parent;
|
|
@@ -25693,9 +25304,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25693
25304
|
return found;
|
|
25694
25305
|
}
|
|
25695
25306
|
function readIndexMeta(repoRoot) {
|
|
25696
|
-
const metaPath =
|
|
25307
|
+
const metaPath = join36(repoRoot, OA_DIR, "index", "meta.json");
|
|
25697
25308
|
try {
|
|
25698
|
-
return JSON.parse(
|
|
25309
|
+
return JSON.parse(readFileSync18(metaPath, "utf-8"));
|
|
25699
25310
|
} catch {
|
|
25700
25311
|
return null;
|
|
25701
25312
|
}
|
|
@@ -25746,28 +25357,28 @@ ${tree}\`\`\`
|
|
|
25746
25357
|
sections.push("");
|
|
25747
25358
|
}
|
|
25748
25359
|
const content = sections.join("\n");
|
|
25749
|
-
const contextDir =
|
|
25360
|
+
const contextDir = join36(repoRoot, OA_DIR, "context");
|
|
25750
25361
|
mkdirSync8(contextDir, { recursive: true });
|
|
25751
|
-
writeFileSync8(
|
|
25362
|
+
writeFileSync8(join36(contextDir, "project-map.md"), content, "utf-8");
|
|
25752
25363
|
return content;
|
|
25753
25364
|
}
|
|
25754
25365
|
function saveSession(repoRoot, session) {
|
|
25755
|
-
const historyDir =
|
|
25366
|
+
const historyDir = join36(repoRoot, OA_DIR, "history");
|
|
25756
25367
|
mkdirSync8(historyDir, { recursive: true });
|
|
25757
|
-
writeFileSync8(
|
|
25368
|
+
writeFileSync8(join36(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
25758
25369
|
}
|
|
25759
25370
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
25760
|
-
const historyDir =
|
|
25761
|
-
if (!
|
|
25371
|
+
const historyDir = join36(repoRoot, OA_DIR, "history");
|
|
25372
|
+
if (!existsSync26(historyDir))
|
|
25762
25373
|
return [];
|
|
25763
25374
|
try {
|
|
25764
25375
|
const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
25765
|
-
const stat5 = statSync9(
|
|
25376
|
+
const stat5 = statSync9(join36(historyDir, f));
|
|
25766
25377
|
return { file: f, mtime: stat5.mtimeMs };
|
|
25767
25378
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
25768
25379
|
return files.map((f) => {
|
|
25769
25380
|
try {
|
|
25770
|
-
return JSON.parse(
|
|
25381
|
+
return JSON.parse(readFileSync18(join36(historyDir, f.file), "utf-8"));
|
|
25771
25382
|
} catch {
|
|
25772
25383
|
return null;
|
|
25773
25384
|
}
|
|
@@ -25777,16 +25388,16 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
25777
25388
|
}
|
|
25778
25389
|
}
|
|
25779
25390
|
function savePendingTask(repoRoot, task) {
|
|
25780
|
-
const historyDir =
|
|
25391
|
+
const historyDir = join36(repoRoot, OA_DIR, "history");
|
|
25781
25392
|
mkdirSync8(historyDir, { recursive: true });
|
|
25782
|
-
writeFileSync8(
|
|
25393
|
+
writeFileSync8(join36(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
25783
25394
|
}
|
|
25784
25395
|
function loadPendingTask(repoRoot) {
|
|
25785
|
-
const filePath =
|
|
25396
|
+
const filePath = join36(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
25786
25397
|
try {
|
|
25787
|
-
if (!
|
|
25398
|
+
if (!existsSync26(filePath))
|
|
25788
25399
|
return null;
|
|
25789
|
-
const data = JSON.parse(
|
|
25400
|
+
const data = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
25790
25401
|
try {
|
|
25791
25402
|
unlinkSync3(filePath);
|
|
25792
25403
|
} catch {
|
|
@@ -25797,13 +25408,13 @@ function loadPendingTask(repoRoot) {
|
|
|
25797
25408
|
}
|
|
25798
25409
|
}
|
|
25799
25410
|
function saveSessionContext(repoRoot, entry) {
|
|
25800
|
-
const contextDir =
|
|
25411
|
+
const contextDir = join36(repoRoot, OA_DIR, "context");
|
|
25801
25412
|
mkdirSync8(contextDir, { recursive: true });
|
|
25802
|
-
const filePath =
|
|
25413
|
+
const filePath = join36(contextDir, CONTEXT_SAVE_FILE);
|
|
25803
25414
|
let ctx;
|
|
25804
25415
|
try {
|
|
25805
|
-
if (
|
|
25806
|
-
ctx = JSON.parse(
|
|
25416
|
+
if (existsSync26(filePath)) {
|
|
25417
|
+
ctx = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
25807
25418
|
} else {
|
|
25808
25419
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
25809
25420
|
}
|
|
@@ -25818,11 +25429,11 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
25818
25429
|
writeFileSync8(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
25819
25430
|
}
|
|
25820
25431
|
function loadSessionContext(repoRoot) {
|
|
25821
|
-
const filePath =
|
|
25432
|
+
const filePath = join36(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
25822
25433
|
try {
|
|
25823
|
-
if (!
|
|
25434
|
+
if (!existsSync26(filePath))
|
|
25824
25435
|
return null;
|
|
25825
|
-
return JSON.parse(
|
|
25436
|
+
return JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
25826
25437
|
} catch {
|
|
25827
25438
|
return null;
|
|
25828
25439
|
}
|
|
@@ -25869,12 +25480,12 @@ function detectManifests(repoRoot) {
|
|
|
25869
25480
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
25870
25481
|
];
|
|
25871
25482
|
for (const check of checks) {
|
|
25872
|
-
const filePath =
|
|
25873
|
-
if (
|
|
25483
|
+
const filePath = join36(repoRoot, check.file);
|
|
25484
|
+
if (existsSync26(filePath)) {
|
|
25874
25485
|
let name;
|
|
25875
25486
|
if (check.nameField) {
|
|
25876
25487
|
try {
|
|
25877
|
-
const data = JSON.parse(
|
|
25488
|
+
const data = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
25878
25489
|
name = data[check.nameField];
|
|
25879
25490
|
} catch {
|
|
25880
25491
|
}
|
|
@@ -25903,7 +25514,7 @@ function findKeyFiles(repoRoot) {
|
|
|
25903
25514
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
25904
25515
|
];
|
|
25905
25516
|
for (const check of checks) {
|
|
25906
|
-
if (
|
|
25517
|
+
if (existsSync26(join36(repoRoot, check.pattern))) {
|
|
25907
25518
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
25908
25519
|
}
|
|
25909
25520
|
}
|
|
@@ -25929,12 +25540,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
25929
25540
|
if (entry.isDirectory()) {
|
|
25930
25541
|
let fileCount = 0;
|
|
25931
25542
|
try {
|
|
25932
|
-
fileCount = readdirSync7(
|
|
25543
|
+
fileCount = readdirSync7(join36(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
25933
25544
|
} catch {
|
|
25934
25545
|
}
|
|
25935
25546
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
25936
25547
|
`;
|
|
25937
|
-
result += buildDirTree(
|
|
25548
|
+
result += buildDirTree(join36(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
25938
25549
|
} else if (depth < maxDepth) {
|
|
25939
25550
|
result += `${prefix}${connector}${entry.name}
|
|
25940
25551
|
`;
|
|
@@ -25988,8 +25599,8 @@ var init_oa_directory = __esm({
|
|
|
25988
25599
|
// packages/cli/dist/tui/setup.js
|
|
25989
25600
|
import * as readline from "node:readline";
|
|
25990
25601
|
import { execSync as execSync24, spawn as spawn14 } from "node:child_process";
|
|
25991
|
-
import { existsSync as
|
|
25992
|
-
import { join as
|
|
25602
|
+
import { existsSync as existsSync27, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "node:fs";
|
|
25603
|
+
import { join as join37 } from "node:path";
|
|
25993
25604
|
import { homedir as homedir10, platform } from "node:os";
|
|
25994
25605
|
function detectSystemSpecs() {
|
|
25995
25606
|
let totalRamGB = 0;
|
|
@@ -26222,7 +25833,7 @@ async function installOllamaMac(_rl) {
|
|
|
26222
25833
|
execSync24('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
26223
25834
|
if (!hasCmd("brew")) {
|
|
26224
25835
|
try {
|
|
26225
|
-
const brewPrefix =
|
|
25836
|
+
const brewPrefix = existsSync27("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
26226
25837
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
26227
25838
|
} catch {
|
|
26228
25839
|
}
|
|
@@ -26976,9 +26587,9 @@ async function doSetup(config, rl) {
|
|
|
26976
26587
|
`PARAMETER num_predict ${numPredict}`,
|
|
26977
26588
|
`PARAMETER stop "<|endoftext|>"`
|
|
26978
26589
|
].join("\n");
|
|
26979
|
-
const modelDir2 =
|
|
26590
|
+
const modelDir2 = join37(homedir10(), ".open-agents", "models");
|
|
26980
26591
|
mkdirSync9(modelDir2, { recursive: true });
|
|
26981
|
-
const modelfilePath =
|
|
26592
|
+
const modelfilePath = join37(modelDir2, `Modelfile.${customName}`);
|
|
26982
26593
|
writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
|
|
26983
26594
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
26984
26595
|
execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
@@ -27024,7 +26635,7 @@ async function isModelAvailable(config) {
|
|
|
27024
26635
|
}
|
|
27025
26636
|
function isFirstRun() {
|
|
27026
26637
|
try {
|
|
27027
|
-
return !
|
|
26638
|
+
return !existsSync27(join37(homedir10(), ".open-agents", "config.json"));
|
|
27028
26639
|
} catch {
|
|
27029
26640
|
return true;
|
|
27030
26641
|
}
|
|
@@ -27061,7 +26672,7 @@ function detectPkgManager() {
|
|
|
27061
26672
|
return null;
|
|
27062
26673
|
}
|
|
27063
26674
|
function getVenvDir() {
|
|
27064
|
-
return
|
|
26675
|
+
return join37(homedir10(), ".open-agents", "venv");
|
|
27065
26676
|
}
|
|
27066
26677
|
function hasVenvModule() {
|
|
27067
26678
|
try {
|
|
@@ -27073,8 +26684,8 @@ function hasVenvModule() {
|
|
|
27073
26684
|
}
|
|
27074
26685
|
function ensureVenv(log) {
|
|
27075
26686
|
const venvDir = getVenvDir();
|
|
27076
|
-
const venvPip =
|
|
27077
|
-
if (
|
|
26687
|
+
const venvPip = join37(venvDir, "bin", "pip");
|
|
26688
|
+
if (existsSync27(venvPip))
|
|
27078
26689
|
return venvDir;
|
|
27079
26690
|
log("Creating Python venv for vision deps...");
|
|
27080
26691
|
if (!hasCmd("python3")) {
|
|
@@ -27086,9 +26697,9 @@ function ensureVenv(log) {
|
|
|
27086
26697
|
return null;
|
|
27087
26698
|
}
|
|
27088
26699
|
try {
|
|
27089
|
-
mkdirSync9(
|
|
26700
|
+
mkdirSync9(join37(homedir10(), ".open-agents"), { recursive: true });
|
|
27090
26701
|
execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
27091
|
-
execSync24(`"${
|
|
26702
|
+
execSync24(`"${join37(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
27092
26703
|
stdio: "pipe",
|
|
27093
26704
|
timeout: 6e4
|
|
27094
26705
|
});
|
|
@@ -27297,15 +26908,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
27297
26908
|
}
|
|
27298
26909
|
}
|
|
27299
26910
|
const venvDir = getVenvDir();
|
|
27300
|
-
const venvBin =
|
|
27301
|
-
const venvMoondream =
|
|
26911
|
+
const venvBin = join37(venvDir, "bin");
|
|
26912
|
+
const venvMoondream = join37(venvBin, "moondream-station");
|
|
27302
26913
|
const venv = ensureVenv(log);
|
|
27303
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
27304
|
-
const venvPip =
|
|
26914
|
+
if (venv && !hasCmd("moondream-station") && !existsSync27(venvMoondream)) {
|
|
26915
|
+
const venvPip = join37(venvBin, "pip");
|
|
27305
26916
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
27306
26917
|
try {
|
|
27307
26918
|
execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
27308
|
-
if (
|
|
26919
|
+
if (existsSync27(venvMoondream)) {
|
|
27309
26920
|
log("moondream-station installed successfully.");
|
|
27310
26921
|
} else {
|
|
27311
26922
|
try {
|
|
@@ -27322,8 +26933,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
27322
26933
|
}
|
|
27323
26934
|
}
|
|
27324
26935
|
if (venv) {
|
|
27325
|
-
const venvPython =
|
|
27326
|
-
const venvPip2 =
|
|
26936
|
+
const venvPython = join37(venvBin, "python");
|
|
26937
|
+
const venvPip2 = join37(venvBin, "pip");
|
|
27327
26938
|
let ocrStackInstalled = false;
|
|
27328
26939
|
try {
|
|
27329
26940
|
execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
@@ -27436,9 +27047,9 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
|
|
|
27436
27047
|
`PARAMETER num_predict ${numPredict}`,
|
|
27437
27048
|
`PARAMETER stop "<|endoftext|>"`
|
|
27438
27049
|
].join("\n");
|
|
27439
|
-
const modelDir2 =
|
|
27050
|
+
const modelDir2 = join37(homedir10(), ".open-agents", "models");
|
|
27440
27051
|
mkdirSync9(modelDir2, { recursive: true });
|
|
27441
|
-
const modelfilePath =
|
|
27052
|
+
const modelfilePath = join37(modelDir2, `Modelfile.${customName}`);
|
|
27442
27053
|
writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
|
|
27443
27054
|
execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
27444
27055
|
stdio: "pipe",
|
|
@@ -28730,18 +28341,18 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
28730
28341
|
let currentVersion = "0.0.0";
|
|
28731
28342
|
try {
|
|
28732
28343
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
28733
|
-
const { fileURLToPath:
|
|
28734
|
-
const { dirname:
|
|
28735
|
-
const { existsSync:
|
|
28344
|
+
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
28345
|
+
const { dirname: dirname18, join: join52 } = await import("node:path");
|
|
28346
|
+
const { existsSync: existsSync38 } = await import("node:fs");
|
|
28736
28347
|
const req = createRequire4(import.meta.url);
|
|
28737
|
-
const thisDir =
|
|
28348
|
+
const thisDir = dirname18(fileURLToPath14(import.meta.url));
|
|
28738
28349
|
const candidates = [
|
|
28739
|
-
|
|
28740
|
-
|
|
28741
|
-
|
|
28350
|
+
join52(thisDir, "..", "package.json"),
|
|
28351
|
+
join52(thisDir, "..", "..", "package.json"),
|
|
28352
|
+
join52(thisDir, "..", "..", "..", "package.json")
|
|
28742
28353
|
];
|
|
28743
28354
|
for (const pkgPath of candidates) {
|
|
28744
|
-
if (
|
|
28355
|
+
if (existsSync38(pkgPath)) {
|
|
28745
28356
|
const pkg = req(pkgPath);
|
|
28746
28357
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
28747
28358
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -28964,8 +28575,8 @@ var init_commands = __esm({
|
|
|
28964
28575
|
});
|
|
28965
28576
|
|
|
28966
28577
|
// packages/cli/dist/tui/project-context.js
|
|
28967
|
-
import { existsSync as
|
|
28968
|
-
import { join as
|
|
28578
|
+
import { existsSync as existsSync28, readFileSync as readFileSync19, readdirSync as readdirSync8 } from "node:fs";
|
|
28579
|
+
import { join as join38, basename as basename10 } from "node:path";
|
|
28969
28580
|
import { execSync as execSync25 } from "node:child_process";
|
|
28970
28581
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
28971
28582
|
function getModelTier(modelName) {
|
|
@@ -29000,10 +28611,10 @@ function loadProjectMap(repoRoot) {
|
|
|
29000
28611
|
if (!hasOaDirectory(repoRoot)) {
|
|
29001
28612
|
initOaDirectory(repoRoot);
|
|
29002
28613
|
}
|
|
29003
|
-
const mapPath =
|
|
29004
|
-
if (
|
|
28614
|
+
const mapPath = join38(repoRoot, OA_DIR, "context", "project-map.md");
|
|
28615
|
+
if (existsSync28(mapPath)) {
|
|
29005
28616
|
try {
|
|
29006
|
-
const content =
|
|
28617
|
+
const content = readFileSync19(mapPath, "utf-8");
|
|
29007
28618
|
return content;
|
|
29008
28619
|
} catch {
|
|
29009
28620
|
}
|
|
@@ -29044,31 +28655,31 @@ ${log}`);
|
|
|
29044
28655
|
}
|
|
29045
28656
|
function loadMemoryContext(repoRoot) {
|
|
29046
28657
|
const sections = [];
|
|
29047
|
-
const oaMemDir =
|
|
28658
|
+
const oaMemDir = join38(repoRoot, OA_DIR, "memory");
|
|
29048
28659
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
29049
28660
|
if (oaEntries)
|
|
29050
28661
|
sections.push(oaEntries);
|
|
29051
|
-
const legacyMemDir =
|
|
29052
|
-
if (legacyMemDir !== oaMemDir &&
|
|
28662
|
+
const legacyMemDir = join38(repoRoot, ".open-agents", "memory");
|
|
28663
|
+
if (legacyMemDir !== oaMemDir && existsSync28(legacyMemDir)) {
|
|
29053
28664
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
29054
28665
|
if (legacyEntries)
|
|
29055
28666
|
sections.push(legacyEntries);
|
|
29056
28667
|
}
|
|
29057
|
-
const globalMemDir =
|
|
28668
|
+
const globalMemDir = join38(homedir11(), ".open-agents", "memory");
|
|
29058
28669
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
29059
28670
|
if (globalEntries)
|
|
29060
28671
|
sections.push(globalEntries);
|
|
29061
28672
|
return sections.join("\n\n");
|
|
29062
28673
|
}
|
|
29063
28674
|
function loadMemoryDir(memDir, scope) {
|
|
29064
|
-
if (!
|
|
28675
|
+
if (!existsSync28(memDir))
|
|
29065
28676
|
return "";
|
|
29066
28677
|
const lines = [];
|
|
29067
28678
|
try {
|
|
29068
28679
|
const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
|
|
29069
28680
|
for (const file of files.slice(0, 10)) {
|
|
29070
28681
|
try {
|
|
29071
|
-
const raw =
|
|
28682
|
+
const raw = readFileSync19(join38(memDir, file), "utf-8");
|
|
29072
28683
|
const entries = JSON.parse(raw);
|
|
29073
28684
|
const topic = basename10(file, ".json");
|
|
29074
28685
|
const keys = Object.keys(entries);
|
|
@@ -30095,22 +29706,22 @@ var init_carousel = __esm({
|
|
|
30095
29706
|
});
|
|
30096
29707
|
|
|
30097
29708
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
30098
|
-
import { existsSync as
|
|
30099
|
-
import { join as
|
|
29709
|
+
import { existsSync as existsSync29, readFileSync as readFileSync20, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync9 } from "node:fs";
|
|
29710
|
+
import { join as join39, basename as basename11 } from "node:path";
|
|
30100
29711
|
function loadToolProfile(repoRoot) {
|
|
30101
|
-
const filePath =
|
|
29712
|
+
const filePath = join39(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
30102
29713
|
try {
|
|
30103
|
-
if (!
|
|
29714
|
+
if (!existsSync29(filePath))
|
|
30104
29715
|
return null;
|
|
30105
|
-
return JSON.parse(
|
|
29716
|
+
return JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
30106
29717
|
} catch {
|
|
30107
29718
|
return null;
|
|
30108
29719
|
}
|
|
30109
29720
|
}
|
|
30110
29721
|
function saveToolProfile(repoRoot, profile) {
|
|
30111
|
-
const contextDir =
|
|
29722
|
+
const contextDir = join39(repoRoot, OA_DIR, "context");
|
|
30112
29723
|
mkdirSync10(contextDir, { recursive: true });
|
|
30113
|
-
writeFileSync10(
|
|
29724
|
+
writeFileSync10(join39(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
30114
29725
|
}
|
|
30115
29726
|
function categorizeToolCall(toolName) {
|
|
30116
29727
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -30168,25 +29779,25 @@ function weightedColor(profile) {
|
|
|
30168
29779
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
30169
29780
|
}
|
|
30170
29781
|
function loadCachedDescriptors(repoRoot) {
|
|
30171
|
-
const filePath =
|
|
29782
|
+
const filePath = join39(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
30172
29783
|
try {
|
|
30173
|
-
if (!
|
|
29784
|
+
if (!existsSync29(filePath))
|
|
30174
29785
|
return null;
|
|
30175
|
-
const cached = JSON.parse(
|
|
29786
|
+
const cached = JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
30176
29787
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
30177
29788
|
} catch {
|
|
30178
29789
|
return null;
|
|
30179
29790
|
}
|
|
30180
29791
|
}
|
|
30181
29792
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
30182
|
-
const contextDir =
|
|
29793
|
+
const contextDir = join39(repoRoot, OA_DIR, "context");
|
|
30183
29794
|
mkdirSync10(contextDir, { recursive: true });
|
|
30184
29795
|
const cached = {
|
|
30185
29796
|
phrases,
|
|
30186
29797
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30187
29798
|
sourceHash
|
|
30188
29799
|
};
|
|
30189
|
-
writeFileSync10(
|
|
29800
|
+
writeFileSync10(join39(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
30190
29801
|
}
|
|
30191
29802
|
function generateDescriptors(repoRoot) {
|
|
30192
29803
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -30234,11 +29845,11 @@ function generateDescriptors(repoRoot) {
|
|
|
30234
29845
|
return phrases;
|
|
30235
29846
|
}
|
|
30236
29847
|
function extractFromPackageJson(repoRoot, tags) {
|
|
30237
|
-
const pkgPath =
|
|
29848
|
+
const pkgPath = join39(repoRoot, "package.json");
|
|
30238
29849
|
try {
|
|
30239
|
-
if (!
|
|
29850
|
+
if (!existsSync29(pkgPath))
|
|
30240
29851
|
return;
|
|
30241
|
-
const pkg = JSON.parse(
|
|
29852
|
+
const pkg = JSON.parse(readFileSync20(pkgPath, "utf-8"));
|
|
30242
29853
|
if (pkg.name && typeof pkg.name === "string") {
|
|
30243
29854
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
30244
29855
|
for (const p of parts)
|
|
@@ -30282,7 +29893,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
30282
29893
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
30283
29894
|
];
|
|
30284
29895
|
for (const check of manifestChecks) {
|
|
30285
|
-
if (
|
|
29896
|
+
if (existsSync29(join39(repoRoot, check.file))) {
|
|
30286
29897
|
tags.push(check.tag);
|
|
30287
29898
|
}
|
|
30288
29899
|
}
|
|
@@ -30304,16 +29915,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
30304
29915
|
}
|
|
30305
29916
|
}
|
|
30306
29917
|
function extractFromMemory(repoRoot, tags) {
|
|
30307
|
-
const memoryDir =
|
|
29918
|
+
const memoryDir = join39(repoRoot, OA_DIR, "memory");
|
|
30308
29919
|
try {
|
|
30309
|
-
if (!
|
|
29920
|
+
if (!existsSync29(memoryDir))
|
|
30310
29921
|
return;
|
|
30311
29922
|
const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
|
|
30312
29923
|
for (const file of files) {
|
|
30313
29924
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
30314
29925
|
tags.push(topic);
|
|
30315
29926
|
try {
|
|
30316
|
-
const data = JSON.parse(
|
|
29927
|
+
const data = JSON.parse(readFileSync20(join39(memoryDir, file), "utf-8"));
|
|
30317
29928
|
if (data && typeof data === "object") {
|
|
30318
29929
|
const keys = Object.keys(data).slice(0, 3);
|
|
30319
29930
|
for (const key of keys) {
|
|
@@ -30448,25 +30059,25 @@ var init_carousel_descriptors = __esm({
|
|
|
30448
30059
|
});
|
|
30449
30060
|
|
|
30450
30061
|
// packages/cli/dist/tui/voice.js
|
|
30451
|
-
import { existsSync as
|
|
30452
|
-
import { join as
|
|
30062
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync21, unlinkSync as unlinkSync4 } from "node:fs";
|
|
30063
|
+
import { join as join40 } from "node:path";
|
|
30453
30064
|
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
30454
30065
|
import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
|
|
30455
30066
|
import { createRequire } from "node:module";
|
|
30456
30067
|
function voiceDir() {
|
|
30457
|
-
return
|
|
30068
|
+
return join40(homedir12(), ".open-agents", "voice");
|
|
30458
30069
|
}
|
|
30459
30070
|
function modelsDir() {
|
|
30460
|
-
return
|
|
30071
|
+
return join40(voiceDir(), "models");
|
|
30461
30072
|
}
|
|
30462
30073
|
function modelDir(id) {
|
|
30463
|
-
return
|
|
30074
|
+
return join40(modelsDir(), id);
|
|
30464
30075
|
}
|
|
30465
30076
|
function modelOnnxPath(id) {
|
|
30466
|
-
return
|
|
30077
|
+
return join40(modelDir(id), "model.onnx");
|
|
30467
30078
|
}
|
|
30468
30079
|
function modelConfigPath(id) {
|
|
30469
|
-
return
|
|
30080
|
+
return join40(modelDir(id), "config.json");
|
|
30470
30081
|
}
|
|
30471
30082
|
function resetNarrationContext() {
|
|
30472
30083
|
narration.toolCount = 0;
|
|
@@ -31144,7 +30755,7 @@ var init_voice = __esm({
|
|
|
31144
30755
|
}
|
|
31145
30756
|
this.onPCMOutput(Buffer.from(int16.buffer), this.config.audio.sample_rate);
|
|
31146
30757
|
}
|
|
31147
|
-
const wavPath =
|
|
30758
|
+
const wavPath = join40(tmpdir6(), `oa-voice-${Date.now()}.wav`);
|
|
31148
30759
|
this.writeWav(audioData, this.config.audio.sample_rate, wavPath);
|
|
31149
30760
|
await this.playWav(wavPath);
|
|
31150
30761
|
try {
|
|
@@ -31302,14 +30913,14 @@ var init_voice = __esm({
|
|
|
31302
30913
|
return;
|
|
31303
30914
|
const arch = process.arch;
|
|
31304
30915
|
mkdirSync11(voiceDir(), { recursive: true });
|
|
31305
|
-
const pkgPath =
|
|
30916
|
+
const pkgPath = join40(voiceDir(), "package.json");
|
|
31306
30917
|
const expectedDeps = {
|
|
31307
30918
|
"onnxruntime-node": "^1.21.0",
|
|
31308
30919
|
"phonemizer": "^1.2.1"
|
|
31309
30920
|
};
|
|
31310
|
-
if (
|
|
30921
|
+
if (existsSync30(pkgPath)) {
|
|
31311
30922
|
try {
|
|
31312
|
-
const existing = JSON.parse(
|
|
30923
|
+
const existing = JSON.parse(readFileSync21(pkgPath, "utf8"));
|
|
31313
30924
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
31314
30925
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
31315
30926
|
writeFileSync11(pkgPath, JSON.stringify(existing, null, 2));
|
|
@@ -31317,14 +30928,38 @@ var init_voice = __esm({
|
|
|
31317
30928
|
} catch {
|
|
31318
30929
|
}
|
|
31319
30930
|
}
|
|
31320
|
-
if (!
|
|
30931
|
+
if (!existsSync30(pkgPath)) {
|
|
31321
30932
|
writeFileSync11(pkgPath, JSON.stringify({
|
|
31322
30933
|
name: "open-agents-voice",
|
|
31323
30934
|
private: true,
|
|
31324
30935
|
dependencies: expectedDeps
|
|
31325
30936
|
}, null, 2));
|
|
31326
30937
|
}
|
|
31327
|
-
const voiceRequire = createRequire(
|
|
30938
|
+
const voiceRequire = createRequire(join40(voiceDir(), "index.js"));
|
|
30939
|
+
const probeOnnx = () => {
|
|
30940
|
+
try {
|
|
30941
|
+
const result = execSync26(`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: join40(voiceDir(), "node_modules") } });
|
|
30942
|
+
const output = result.toString().trim();
|
|
30943
|
+
if (output === "OK")
|
|
30944
|
+
return true;
|
|
30945
|
+
if (output.startsWith("FAIL:")) {
|
|
30946
|
+
renderWarning(`ONNX runtime probe failed: ${output.slice(5)}`);
|
|
30947
|
+
return false;
|
|
30948
|
+
}
|
|
30949
|
+
return false;
|
|
30950
|
+
} catch (err) {
|
|
30951
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
30952
|
+
if (msg.includes("CPUID") || msg.includes("unknown cpu") || msg.includes("signal")) {
|
|
30953
|
+
renderWarning(`ONNX runtime is not compatible with this CPU (${process.platform}-${arch}).`);
|
|
30954
|
+
}
|
|
30955
|
+
return false;
|
|
30956
|
+
}
|
|
30957
|
+
};
|
|
30958
|
+
const onnxNodeModules = join40(voiceDir(), "node_modules", "onnxruntime-node");
|
|
30959
|
+
const onnxInstalled = existsSync30(onnxNodeModules);
|
|
30960
|
+
if (onnxInstalled && !probeOnnx()) {
|
|
30961
|
+
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.`);
|
|
30962
|
+
}
|
|
31328
30963
|
try {
|
|
31329
30964
|
this.ort = voiceRequire("onnxruntime-node");
|
|
31330
30965
|
} catch {
|
|
@@ -31335,12 +30970,19 @@ var init_voice = __esm({
|
|
|
31335
30970
|
stdio: "pipe",
|
|
31336
30971
|
timeout: 12e4
|
|
31337
30972
|
});
|
|
31338
|
-
this.ort = voiceRequire("onnxruntime-node");
|
|
31339
30973
|
} catch (err) {
|
|
31340
30974
|
const archHint = arch !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch}.` : "";
|
|
31341
30975
|
throw new Error(`Failed to install voice dependencies.${archHint} Try manually: cd ${voiceDir()} && npm install
|
|
31342
30976
|
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
31343
30977
|
}
|
|
30978
|
+
if (!probeOnnx()) {
|
|
30979
|
+
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.`);
|
|
30980
|
+
}
|
|
30981
|
+
try {
|
|
30982
|
+
this.ort = voiceRequire("onnxruntime-node");
|
|
30983
|
+
} catch (err) {
|
|
30984
|
+
throw new Error(`Failed to load ONNX runtime after install. Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
30985
|
+
}
|
|
31344
30986
|
}
|
|
31345
30987
|
try {
|
|
31346
30988
|
const phonemizerMod = voiceRequire("phonemizer");
|
|
@@ -31372,10 +31014,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
31372
31014
|
const dir = modelDir(id);
|
|
31373
31015
|
const onnxPath = modelOnnxPath(id);
|
|
31374
31016
|
const configPath = modelConfigPath(id);
|
|
31375
|
-
if (
|
|
31017
|
+
if (existsSync30(onnxPath) && existsSync30(configPath))
|
|
31376
31018
|
return;
|
|
31377
31019
|
mkdirSync11(dir, { recursive: true });
|
|
31378
|
-
if (!
|
|
31020
|
+
if (!existsSync30(configPath)) {
|
|
31379
31021
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
31380
31022
|
const configResp = await fetch(model.configUrl);
|
|
31381
31023
|
if (!configResp.ok)
|
|
@@ -31383,7 +31025,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
31383
31025
|
const configText = await configResp.text();
|
|
31384
31026
|
writeFileSync11(configPath, configText);
|
|
31385
31027
|
}
|
|
31386
|
-
if (!
|
|
31028
|
+
if (!existsSync30(onnxPath)) {
|
|
31387
31029
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
31388
31030
|
const onnxResp = await fetch(model.onnxUrl);
|
|
31389
31031
|
if (!onnxResp.ok)
|
|
@@ -31419,10 +31061,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
31419
31061
|
throw new Error("ONNX runtime not loaded");
|
|
31420
31062
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
31421
31063
|
const configPath = modelConfigPath(this.modelId);
|
|
31422
|
-
if (!
|
|
31064
|
+
if (!existsSync30(onnxPath) || !existsSync30(configPath)) {
|
|
31423
31065
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
31424
31066
|
}
|
|
31425
|
-
this.config = JSON.parse(
|
|
31067
|
+
this.config = JSON.parse(readFileSync21(configPath, "utf8"));
|
|
31426
31068
|
renderInfo("Loading voice model...");
|
|
31427
31069
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
31428
31070
|
executionProviders: ["cpu"],
|
|
@@ -32286,10 +31928,10 @@ var init_stream_renderer = __esm({
|
|
|
32286
31928
|
|
|
32287
31929
|
// packages/cli/dist/tui/edit-history.js
|
|
32288
31930
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
|
|
32289
|
-
import { join as
|
|
31931
|
+
import { join as join41 } from "node:path";
|
|
32290
31932
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
32291
|
-
const historyDir =
|
|
32292
|
-
const logPath =
|
|
31933
|
+
const historyDir = join41(repoRoot, ".oa", "history");
|
|
31934
|
+
const logPath = join41(historyDir, "edits.jsonl");
|
|
32293
31935
|
try {
|
|
32294
31936
|
mkdirSync12(historyDir, { recursive: true });
|
|
32295
31937
|
} catch {
|
|
@@ -32399,16 +32041,47 @@ var init_edit_history = __esm({
|
|
|
32399
32041
|
}
|
|
32400
32042
|
});
|
|
32401
32043
|
|
|
32044
|
+
// packages/cli/dist/tui/promptLoader.js
|
|
32045
|
+
import { readFileSync as readFileSync22, existsSync as existsSync31 } from "node:fs";
|
|
32046
|
+
import { join as join42, dirname as dirname15 } from "node:path";
|
|
32047
|
+
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
32048
|
+
function loadPrompt3(promptPath, vars) {
|
|
32049
|
+
let content = cache3.get(promptPath);
|
|
32050
|
+
if (content === void 0) {
|
|
32051
|
+
const fullPath = join42(PROMPTS_DIR3, promptPath);
|
|
32052
|
+
if (!existsSync31(fullPath)) {
|
|
32053
|
+
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
32054
|
+
}
|
|
32055
|
+
content = readFileSync22(fullPath, "utf-8");
|
|
32056
|
+
cache3.set(promptPath, content);
|
|
32057
|
+
}
|
|
32058
|
+
if (!vars)
|
|
32059
|
+
return content;
|
|
32060
|
+
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
32061
|
+
}
|
|
32062
|
+
var __filename3, __dirname5, devPath2, publishedPath2, PROMPTS_DIR3, cache3;
|
|
32063
|
+
var init_promptLoader3 = __esm({
|
|
32064
|
+
"packages/cli/dist/tui/promptLoader.js"() {
|
|
32065
|
+
"use strict";
|
|
32066
|
+
__filename3 = fileURLToPath11(import.meta.url);
|
|
32067
|
+
__dirname5 = dirname15(__filename3);
|
|
32068
|
+
devPath2 = join42(__dirname5, "..", "..", "prompts");
|
|
32069
|
+
publishedPath2 = join42(__dirname5, "..", "prompts");
|
|
32070
|
+
PROMPTS_DIR3 = existsSync31(devPath2) ? devPath2 : publishedPath2;
|
|
32071
|
+
cache3 = /* @__PURE__ */ new Map();
|
|
32072
|
+
}
|
|
32073
|
+
});
|
|
32074
|
+
|
|
32402
32075
|
// packages/cli/dist/tui/dream-engine.js
|
|
32403
|
-
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as
|
|
32404
|
-
import { join as
|
|
32076
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync23, existsSync as existsSync32, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
|
|
32077
|
+
import { join as join43, basename as basename12 } from "node:path";
|
|
32405
32078
|
import { execSync as execSync27 } from "node:child_process";
|
|
32406
32079
|
function loadAutoresearchMemory(repoRoot) {
|
|
32407
|
-
const memoryPath =
|
|
32408
|
-
if (!
|
|
32080
|
+
const memoryPath = join43(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
32081
|
+
if (!existsSync32(memoryPath))
|
|
32409
32082
|
return "";
|
|
32410
32083
|
try {
|
|
32411
|
-
const raw =
|
|
32084
|
+
const raw = readFileSync23(memoryPath, "utf-8");
|
|
32412
32085
|
const data = JSON.parse(raw);
|
|
32413
32086
|
const sections = [];
|
|
32414
32087
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -32447,62 +32120,31 @@ function buildDreamPrompt(mode, stage, cycleNum, totalCycles, previousFindings,
|
|
|
32447
32120
|
"NREM-3": `DEEP CONSOLIDATION (Stage 3/${SLEEP_STAGES.length}): Synthesize your findings into concrete, actionable proposals. For each proposal, write: (1) problem statement, (2) proposed solution with implementation plan, (3) estimated effort, (4) expected impact. Create clean entrypoint files.`,
|
|
32448
32121
|
"REM": `CREATIVE EXPANSION (Stage 4/${SLEEP_STAGES.length}): Think boldly and creatively. What novel features could transform this project? Cross-domain inspiration? Unconventional approaches? Generate at least 3 wild ideas alongside 3 practical innovations. Write detailed vision documents.`
|
|
32449
32122
|
}[stage.name];
|
|
32450
|
-
return
|
|
32451
|
-
|
|
32452
|
-
|
|
32453
|
-
|
|
32454
|
-
|
|
32455
|
-
|
|
32456
|
-
|
|
32457
|
-
|
|
32123
|
+
return loadPrompt3("tui/dream-stages.md", {
|
|
32124
|
+
modeDesc,
|
|
32125
|
+
cycleNum: String(cycleNum),
|
|
32126
|
+
totalCycles: String(totalCycles),
|
|
32127
|
+
stageName: stage.name,
|
|
32128
|
+
stageLabel: stage.label,
|
|
32129
|
+
stageDescription: stage.description,
|
|
32130
|
+
stageInstruction: stageInstruction || "",
|
|
32131
|
+
stageNameLower: stage.name.toLowerCase(),
|
|
32132
|
+
previousFindings: previousFindings ? `PREVIOUS FINDINGS FROM EARLIER STAGES:
|
|
32458
32133
|
${previousFindings}
|
|
32459
|
-
` : ""
|
|
32460
|
-
|
|
32461
|
-
RULES:
|
|
32462
|
-
- Read any file in the workspace freely for analysis
|
|
32463
|
-
- ALL written output goes to .oa/dreams/ using file_write (path relative to .oa/dreams/)
|
|
32464
|
-
- Use codebase_map, file_read, grep_search, find_files, list_directory to explore
|
|
32465
|
-
- Create well-structured markdown proposals with clear sections
|
|
32466
|
-
- Name files descriptively: cycle-${cycleNum}-${stage.name.toLowerCase()}-{topic}.md
|
|
32467
|
-
- For proposals, include a PROPOSAL-INDEX.md that catalogs all proposals with status and priority
|
|
32468
|
-
- Include implementation entrypoints: specific file paths, function signatures, step-by-step plans
|
|
32469
|
-
|
|
32470
|
-
When done with this stage, call task_complete with a summary of findings.`;
|
|
32134
|
+
` : ""
|
|
32135
|
+
});
|
|
32471
32136
|
}
|
|
32472
32137
|
function buildLucidImplementPrompt(proposal, cycleNum) {
|
|
32473
|
-
return
|
|
32474
|
-
|
|
32475
|
-
|
|
32476
|
-
|
|
32477
|
-
PROPOSAL TO IMPLEMENT:
|
|
32478
|
-
${proposal}
|
|
32479
|
-
|
|
32480
|
-
INSTRUCTIONS:
|
|
32481
|
-
1. Implement the proposal carefully, following the plan
|
|
32482
|
-
2. Run tests after implementation to verify nothing breaks
|
|
32483
|
-
3. If tests fail, fix the issues
|
|
32484
|
-
4. Write a brief evaluation of the implementation to .oa/dreams/cycle-${cycleNum}-implementation-report.md
|
|
32485
|
-
|
|
32486
|
-
After implementation and testing, call task_complete with a summary of what was implemented and test results.`;
|
|
32138
|
+
return loadPrompt3("tui/dream-lucid-implement.md", {
|
|
32139
|
+
cycleNum: String(cycleNum),
|
|
32140
|
+
proposal
|
|
32141
|
+
});
|
|
32487
32142
|
}
|
|
32488
32143
|
function buildLucidEvalPrompt(implementationSummary, cycleNum) {
|
|
32489
|
-
return
|
|
32490
|
-
|
|
32491
|
-
|
|
32492
|
-
|
|
32493
|
-
IMPLEMENTATION SUMMARY:
|
|
32494
|
-
${implementationSummary}
|
|
32495
|
-
|
|
32496
|
-
EVALUATION TASKS:
|
|
32497
|
-
1. Review the changes you made \u2014 are they clean, well-structured, properly tested?
|
|
32498
|
-
2. Self-play: Try to use the features as an end-user would. Test edge cases.
|
|
32499
|
-
3. Rate the implementation: usefulness (1-10), code quality (1-10), test coverage (1-10)
|
|
32500
|
-
4. Identify any issues, regressions, or improvements needed
|
|
32501
|
-
5. Write evaluation report to .oa/dreams/cycle-${cycleNum}-evaluation.md
|
|
32502
|
-
|
|
32503
|
-
SELF-PLAY: Actually exercise the code paths \u2014 run commands, read outputs, verify behavior.
|
|
32504
|
-
|
|
32505
|
-
After evaluation, call task_complete with your ratings and findings.`;
|
|
32144
|
+
return loadPrompt3("tui/dream-lucid-eval.md", {
|
|
32145
|
+
cycleNum: String(cycleNum),
|
|
32146
|
+
implementationSummary
|
|
32147
|
+
});
|
|
32506
32148
|
}
|
|
32507
32149
|
function renderDreamCycleHeader(cycle, total, mode) {
|
|
32508
32150
|
const modeLabel = mode === "lucid" ? "LUCID" : mode === "deep" ? "DEEP" : "DREAM";
|
|
@@ -32600,6 +32242,7 @@ var init_dream_engine = __esm({
|
|
|
32600
32242
|
init_project_context();
|
|
32601
32243
|
init_setup();
|
|
32602
32244
|
init_render();
|
|
32245
|
+
init_promptLoader3();
|
|
32603
32246
|
SWARM_ROLE_CONFIG = {
|
|
32604
32247
|
researcher: { maxTurns: 25, temperature: 0.4 },
|
|
32605
32248
|
monitor: { maxTurns: 5, temperature: 0.1 },
|
|
@@ -32628,12 +32271,12 @@ var init_dream_engine = __esm({
|
|
|
32628
32271
|
const content = String(args["content"] ?? "");
|
|
32629
32272
|
if (!rawPath)
|
|
32630
32273
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
32631
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
32274
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join43(this.autoresearchDir, basename12(rawPath)) : join43(this.autoresearchDir, rawPath);
|
|
32632
32275
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
32633
32276
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
32634
32277
|
}
|
|
32635
32278
|
try {
|
|
32636
|
-
const dir =
|
|
32279
|
+
const dir = join43(targetPath, "..");
|
|
32637
32280
|
mkdirSync13(dir, { recursive: true });
|
|
32638
32281
|
writeFileSync12(targetPath, content, "utf-8");
|
|
32639
32282
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
@@ -32663,15 +32306,15 @@ var init_dream_engine = __esm({
|
|
|
32663
32306
|
const rawPath = String(args["path"] ?? "");
|
|
32664
32307
|
const oldStr = String(args["old_string"] ?? "");
|
|
32665
32308
|
const newStr = String(args["new_string"] ?? "");
|
|
32666
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
32309
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join43(this.autoresearchDir, basename12(rawPath)) : join43(this.autoresearchDir, rawPath);
|
|
32667
32310
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
32668
32311
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
32669
32312
|
}
|
|
32670
32313
|
try {
|
|
32671
|
-
if (!
|
|
32314
|
+
if (!existsSync32(targetPath)) {
|
|
32672
32315
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
32673
32316
|
}
|
|
32674
|
-
let content =
|
|
32317
|
+
let content = readFileSync23(targetPath, "utf-8");
|
|
32675
32318
|
if (!content.includes(oldStr)) {
|
|
32676
32319
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
32677
32320
|
}
|
|
@@ -32717,12 +32360,12 @@ var init_dream_engine = __esm({
|
|
|
32717
32360
|
const content = String(args["content"] ?? "");
|
|
32718
32361
|
if (!rawPath)
|
|
32719
32362
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
32720
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
32363
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join43(this.dreamsDir, basename12(rawPath)) : join43(this.dreamsDir, rawPath);
|
|
32721
32364
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
32722
32365
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
32723
32366
|
}
|
|
32724
32367
|
try {
|
|
32725
|
-
const dir =
|
|
32368
|
+
const dir = join43(targetPath, "..");
|
|
32726
32369
|
mkdirSync13(dir, { recursive: true });
|
|
32727
32370
|
writeFileSync12(targetPath, content, "utf-8");
|
|
32728
32371
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
@@ -32752,15 +32395,15 @@ var init_dream_engine = __esm({
|
|
|
32752
32395
|
const rawPath = String(args["path"] ?? "");
|
|
32753
32396
|
const oldStr = String(args["old_string"] ?? "");
|
|
32754
32397
|
const newStr = String(args["new_string"] ?? "");
|
|
32755
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
32398
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join43(this.dreamsDir, basename12(rawPath)) : join43(this.dreamsDir, rawPath);
|
|
32756
32399
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
32757
32400
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
32758
32401
|
}
|
|
32759
32402
|
try {
|
|
32760
|
-
if (!
|
|
32403
|
+
if (!existsSync32(targetPath)) {
|
|
32761
32404
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
32762
32405
|
}
|
|
32763
|
-
let content =
|
|
32406
|
+
let content = readFileSync23(targetPath, "utf-8");
|
|
32764
32407
|
if (!content.includes(oldStr)) {
|
|
32765
32408
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
32766
32409
|
}
|
|
@@ -32819,7 +32462,7 @@ var init_dream_engine = __esm({
|
|
|
32819
32462
|
constructor(config, repoRoot) {
|
|
32820
32463
|
this.config = config;
|
|
32821
32464
|
this.repoRoot = repoRoot;
|
|
32822
|
-
this.dreamsDir =
|
|
32465
|
+
this.dreamsDir = join43(repoRoot, ".oa", "dreams");
|
|
32823
32466
|
this.state = {
|
|
32824
32467
|
mode: "default",
|
|
32825
32468
|
active: false,
|
|
@@ -32903,7 +32546,7 @@ ${result.summary}`;
|
|
|
32903
32546
|
if (mode !== "default" || cycle === totalCycles) {
|
|
32904
32547
|
renderDreamContraction(cycle);
|
|
32905
32548
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
32906
|
-
const summaryPath =
|
|
32549
|
+
const summaryPath = join43(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
32907
32550
|
writeFileSync12(summaryPath, cycleSummary, "utf-8");
|
|
32908
32551
|
}
|
|
32909
32552
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
@@ -33116,7 +32759,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
33116
32759
|
}
|
|
33117
32760
|
/** Build role-specific tool sets for swarm agents */
|
|
33118
32761
|
buildSwarmTools(role, _workspace) {
|
|
33119
|
-
const autoresearchDir =
|
|
32762
|
+
const autoresearchDir = join43(this.repoRoot, ".oa", "autoresearch");
|
|
33120
32763
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
33121
32764
|
switch (role) {
|
|
33122
32765
|
case "researcher": {
|
|
@@ -33480,7 +33123,7 @@ INSTRUCTIONS:
|
|
|
33480
33123
|
2. Summarize the key learnings and next steps
|
|
33481
33124
|
|
|
33482
33125
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
33483
|
-
const reportPath =
|
|
33126
|
+
const reportPath = join43(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
33484
33127
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
33485
33128
|
|
|
33486
33129
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -33569,7 +33212,7 @@ ${summaryResult}
|
|
|
33569
33212
|
}
|
|
33570
33213
|
/** Save workspace backup for lucid mode */
|
|
33571
33214
|
saveVersionCheckpoint(cycle) {
|
|
33572
|
-
const checkpointDir =
|
|
33215
|
+
const checkpointDir = join43(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
33573
33216
|
try {
|
|
33574
33217
|
mkdirSync13(checkpointDir, { recursive: true });
|
|
33575
33218
|
try {
|
|
@@ -33588,10 +33231,10 @@ ${summaryResult}
|
|
|
33588
33231
|
encoding: "utf-8",
|
|
33589
33232
|
timeout: 5e3
|
|
33590
33233
|
}).trim();
|
|
33591
|
-
writeFileSync12(
|
|
33592
|
-
writeFileSync12(
|
|
33593
|
-
writeFileSync12(
|
|
33594
|
-
writeFileSync12(
|
|
33234
|
+
writeFileSync12(join43(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
33235
|
+
writeFileSync12(join43(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
33236
|
+
writeFileSync12(join43(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
33237
|
+
writeFileSync12(join43(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
33595
33238
|
cycle,
|
|
33596
33239
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33597
33240
|
gitHash,
|
|
@@ -33599,7 +33242,7 @@ ${summaryResult}
|
|
|
33599
33242
|
}, null, 2), "utf-8");
|
|
33600
33243
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
33601
33244
|
} catch {
|
|
33602
|
-
writeFileSync12(
|
|
33245
|
+
writeFileSync12(join43(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
33603
33246
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
33604
33247
|
}
|
|
33605
33248
|
} catch (err) {
|
|
@@ -33657,14 +33300,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
33657
33300
|
---
|
|
33658
33301
|
*Auto-generated by open-agents dream engine*
|
|
33659
33302
|
`;
|
|
33660
|
-
writeFileSync12(
|
|
33303
|
+
writeFileSync12(join43(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
33661
33304
|
} catch {
|
|
33662
33305
|
}
|
|
33663
33306
|
}
|
|
33664
33307
|
/** Save dream state for resume/inspection */
|
|
33665
33308
|
saveDreamState() {
|
|
33666
33309
|
try {
|
|
33667
|
-
writeFileSync12(
|
|
33310
|
+
writeFileSync12(join43(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
33668
33311
|
} catch {
|
|
33669
33312
|
}
|
|
33670
33313
|
}
|
|
@@ -34038,143 +33681,23 @@ var init_bless_engine = __esm({
|
|
|
34038
33681
|
});
|
|
34039
33682
|
|
|
34040
33683
|
// packages/cli/dist/tui/dmn-engine.js
|
|
34041
|
-
import { existsSync as
|
|
34042
|
-
import { join as
|
|
33684
|
+
import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
|
|
33685
|
+
import { join as join44, basename as basename13 } from "node:path";
|
|
34043
33686
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
34044
33687
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
34045
33688
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
34046
33689
|
return ` - ${c3.taskType}: ${c3.attempts} attempts, ${rate}% success`;
|
|
34047
33690
|
}).join("\n") : " (no data yet \u2014 this is a fresh start)";
|
|
34048
33691
|
const reflectionsText = reflectionBuffer.length > 0 ? reflectionBuffer.map((r, i) => ` ${i + 1}. ${r}`).join("\n") : " (none)";
|
|
34049
|
-
return
|
|
34050
|
-
|
|
34051
|
-
|
|
34052
|
-
|
|
34053
|
-
|
|
34054
|
-
|
|
34055
|
-
|
|
34056
|
-
|
|
34057
|
-
|
|
34058
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
34059
|
-
|
|
34060
|
-
PHASE 1: GATHER CONTEXT
|
|
34061
|
-
|
|
34062
|
-
Use memory_search and memory_read to explore ALL stored knowledge. Be thorough.
|
|
34063
|
-
Look for:
|
|
34064
|
-
- Standing directives ("always do X", "seek Y", "monitor Z")
|
|
34065
|
-
- Unfinished goals or partially completed missions
|
|
34066
|
-
- Knowledge gaps that could be filled
|
|
34067
|
-
- Patterns in recent task history that suggest momentum direction
|
|
34068
|
-
- Environmental signals (reminders, attention items)
|
|
34069
|
-
|
|
34070
|
-
IMPORTANT: Start by searching memory broadly. Use memory_search with terms like
|
|
34071
|
-
"goal", "directive", "plan", "todo", "important" to find standing orders. Then
|
|
34072
|
-
read specific topics that seem relevant. The richness of your reasoning depends
|
|
34073
|
-
on how well you explore what you already know.
|
|
34074
|
-
|
|
34075
|
-
Recent task history (last completed tasks):
|
|
34076
|
-
${recentTaskSummaries.length > 0 ? recentTaskSummaries.map((s, i) => ` ${i + 1}. ${s}`).join("\n") : " (no recent tasks)"}
|
|
34077
|
-
|
|
34078
|
-
Recent failures (Reflexion buffer \u2014 learn from these):
|
|
34079
|
-
${reflectionsText}
|
|
34080
|
-
|
|
34081
|
-
Competence tracker (attempts and success rate by category):
|
|
34082
|
-
${competenceReport}
|
|
34083
|
-
|
|
34084
|
-
Due reminders:
|
|
34085
|
-
${dueReminders.length > 0 ? dueReminders.map((r) => ` - ${r}`).join("\n") : " (none)"}
|
|
34086
|
-
|
|
34087
|
-
Active attention items:
|
|
34088
|
-
${attentionItems.length > 0 ? attentionItems.map((a) => ` - ${a}`).join("\n") : " (none)"}
|
|
34089
|
-
|
|
34090
|
-
Known memory topics:
|
|
34091
|
-
${memoryTopics.length > 0 ? memoryTopics.map((t) => ` - ${t}`).join("\n") : " (none \u2014 fresh start)"}
|
|
34092
|
-
|
|
34093
|
-
Available capabilities:
|
|
34094
|
-
${capabilities.map((c3) => ` - ${c3}`).join("\n")}
|
|
34095
|
-
|
|
34096
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
34097
|
-
|
|
34098
|
-
PHASE 2: REFLECT, CONSOLIDATE & REASON (Generative Agents + Reflexion)
|
|
34099
|
-
|
|
34100
|
-
After gathering context, consolidate and reason:
|
|
34101
|
-
|
|
34102
|
-
Memory consolidation:
|
|
34103
|
-
- Are there overlapping or redundant memories that should be merged?
|
|
34104
|
-
- Are there new insights from recent tasks worth writing to memory?
|
|
34105
|
-
- Write any new insights to memory NOW using memory_write.
|
|
34106
|
-
|
|
34107
|
-
Self-evaluation (answer these questions in your reasoning):
|
|
34108
|
-
1. What directives or goals have been set that still need work?
|
|
34109
|
-
2. What was the momentum of recent tasks \u2014 what logically comes next?
|
|
34110
|
-
3. Are there capabilities I haven't exercised that could be valuable?
|
|
34111
|
-
4. What knowledge gaps exist that exploration could fill?
|
|
34112
|
-
5. Are there environmental signals (reminders, attention items) to address?
|
|
34113
|
-
6. What can I learn from recent failures? (Check the Reflexion buffer above)
|
|
34114
|
-
7. Where is my learning progress fastest? (Check competence tracker \u2014 pursue
|
|
34115
|
-
categories where success rate is RISING, avoid categories where it's flat)
|
|
34116
|
-
|
|
34117
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
34118
|
-
|
|
34119
|
-
PHASE 3: GENERATE CANDIDATES (Voyager-style curriculum)
|
|
34120
|
-
|
|
34121
|
-
Propose 2-4 candidate next tasks. Use the "Goldilocks" principle from Voyager:
|
|
34122
|
-
propose tasks at the FRONTIER of current capabilities \u2014 neither too easy
|
|
34123
|
-
(already mastered) nor too hard (no chance of success). Check the competence
|
|
34124
|
-
tracker to calibrate difficulty.
|
|
34125
|
-
|
|
34126
|
-
For each candidate, specify:
|
|
34127
|
-
- The task description (specific, actionable, measurable)
|
|
34128
|
-
- Rationale (why this task, what led you to it)
|
|
34129
|
-
- Provenance (which memories, directives, or signals informed this)
|
|
34130
|
-
- Category: directive | exploration | capability | maintenance | social
|
|
34131
|
-
- Confidence (0-1, calibrated against competence data)
|
|
34132
|
-
|
|
34133
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
34134
|
-
|
|
34135
|
-
PHASE 4: ADVERSARIAL CHALLENGE (Self-Rewarding + Constitutional AI)
|
|
34136
|
-
|
|
34137
|
-
For each candidate, run a rigorous adversarial review:
|
|
34138
|
-
- Is this actually useful or just busywork?
|
|
34139
|
-
- Does it align with stored directives and goals?
|
|
34140
|
-
- Is it achievable with available tools and current competence?
|
|
34141
|
-
- Could it cause harm or waste resources?
|
|
34142
|
-
- Is there a higher-priority alternative?
|
|
34143
|
-
- Would this task help or hinder the agent's long-term growth?
|
|
34144
|
-
- Challenge your own confidence rating \u2014 are you overconfident?
|
|
34145
|
-
|
|
34146
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
34147
|
-
|
|
34148
|
-
PHASE 5: SELECT & FORMAT
|
|
34149
|
-
|
|
34150
|
-
Pick the single highest-value task. If NO task is genuinely worth doing
|
|
34151
|
-
(all candidates are low-value or risky), respond with "NO_TASK" \u2014 it's
|
|
34152
|
-
better to rest than to waste cycles on meaningless work.
|
|
34153
|
-
|
|
34154
|
-
When you have decided, call task_complete with a JSON summary in this format:
|
|
34155
|
-
{
|
|
34156
|
-
"selectedTask": {
|
|
34157
|
-
"task": "the specific task to execute",
|
|
34158
|
-
"rationale": "why this is the best next action",
|
|
34159
|
-
"provenance": ["memory:topic/key", "reminder:xyz", "attention:abc"],
|
|
34160
|
-
"category": "directive",
|
|
34161
|
-
"confidence": 0.85,
|
|
34162
|
-
"challengeResult": "survived adversarial review because..."
|
|
34163
|
-
},
|
|
34164
|
-
"reasoning": "full chain of thought that led to this decision",
|
|
34165
|
-
"alternativesConsidered": ["task A (rejected because...)", "task B (rejected because...)"]
|
|
34166
|
-
}
|
|
34167
|
-
|
|
34168
|
-
Or if nothing is worth doing:
|
|
34169
|
-
{
|
|
34170
|
-
"selectedTask": null,
|
|
34171
|
-
"reasoning": "why no task is worth pursuing right now"
|
|
34172
|
-
}
|
|
34173
|
-
|
|
34174
|
-
REMEMBER: Use memory_read, memory_write, and memory_search EXTENSIVELY.
|
|
34175
|
-
Write consolidation insights and new reflections to memory before selecting a task.
|
|
34176
|
-
The next DMN cycle (and the main agent) will benefit from anything you store now.
|
|
34177
|
-
`;
|
|
33692
|
+
return loadPrompt3("tui/dmn-gather.md", {
|
|
33693
|
+
recentTaskSummaries: recentTaskSummaries.length > 0 ? recentTaskSummaries.map((s, i) => ` ${i + 1}. ${s}`).join("\n") : " (no recent tasks)",
|
|
33694
|
+
reflectionsText,
|
|
33695
|
+
competenceReport,
|
|
33696
|
+
dueReminders: dueReminders.length > 0 ? dueReminders.map((r) => ` - ${r}`).join("\n") : " (none)",
|
|
33697
|
+
attentionItems: attentionItems.length > 0 ? attentionItems.map((a) => ` - ${a}`).join("\n") : " (none)",
|
|
33698
|
+
memoryTopics: memoryTopics.length > 0 ? memoryTopics.map((t) => ` - ${t}`).join("\n") : " (none \u2014 fresh start)",
|
|
33699
|
+
capabilities: capabilities.map((c3) => ` - ${c3}`).join("\n")
|
|
33700
|
+
});
|
|
34178
33701
|
}
|
|
34179
33702
|
function adaptTool3(tool) {
|
|
34180
33703
|
return {
|
|
@@ -34251,6 +33774,7 @@ var init_dmn_engine = __esm({
|
|
|
34251
33774
|
init_dist2();
|
|
34252
33775
|
init_project_context();
|
|
34253
33776
|
init_render();
|
|
33777
|
+
init_promptLoader3();
|
|
34254
33778
|
DMNEngine = class {
|
|
34255
33779
|
config;
|
|
34256
33780
|
repoRoot;
|
|
@@ -34271,8 +33795,8 @@ var init_dmn_engine = __esm({
|
|
|
34271
33795
|
constructor(config, repoRoot) {
|
|
34272
33796
|
this.config = config;
|
|
34273
33797
|
this.repoRoot = repoRoot;
|
|
34274
|
-
this.stateDir =
|
|
34275
|
-
this.historyDir =
|
|
33798
|
+
this.stateDir = join44(repoRoot, ".oa", "dmn");
|
|
33799
|
+
this.historyDir = join44(repoRoot, ".oa", "dmn", "cycles");
|
|
34276
33800
|
mkdirSync14(this.historyDir, { recursive: true });
|
|
34277
33801
|
this.loadState();
|
|
34278
33802
|
}
|
|
@@ -34862,11 +34386,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
34862
34386
|
async gatherMemoryTopics() {
|
|
34863
34387
|
const topics = [];
|
|
34864
34388
|
const dirs = [
|
|
34865
|
-
|
|
34866
|
-
|
|
34389
|
+
join44(this.repoRoot, ".oa", "memory"),
|
|
34390
|
+
join44(this.repoRoot, ".open-agents", "memory")
|
|
34867
34391
|
];
|
|
34868
34392
|
for (const dir of dirs) {
|
|
34869
|
-
if (!
|
|
34393
|
+
if (!existsSync33(dir))
|
|
34870
34394
|
continue;
|
|
34871
34395
|
try {
|
|
34872
34396
|
const files = readdirSync11(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -34882,29 +34406,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
34882
34406
|
}
|
|
34883
34407
|
// ── State persistence ─────────────────────────────────────────────────
|
|
34884
34408
|
loadState() {
|
|
34885
|
-
const path =
|
|
34886
|
-
if (
|
|
34409
|
+
const path = join44(this.stateDir, "state.json");
|
|
34410
|
+
if (existsSync33(path)) {
|
|
34887
34411
|
try {
|
|
34888
|
-
this.state = JSON.parse(
|
|
34412
|
+
this.state = JSON.parse(readFileSync24(path, "utf-8"));
|
|
34889
34413
|
} catch {
|
|
34890
34414
|
}
|
|
34891
34415
|
}
|
|
34892
34416
|
}
|
|
34893
34417
|
saveState() {
|
|
34894
34418
|
try {
|
|
34895
|
-
writeFileSync13(
|
|
34419
|
+
writeFileSync13(join44(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
34896
34420
|
} catch {
|
|
34897
34421
|
}
|
|
34898
34422
|
}
|
|
34899
34423
|
saveCycleResult(result) {
|
|
34900
34424
|
try {
|
|
34901
34425
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
34902
|
-
writeFileSync13(
|
|
34426
|
+
writeFileSync13(join44(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
34903
34427
|
const files = readdirSync11(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
34904
34428
|
if (files.length > 50) {
|
|
34905
34429
|
for (const old of files.slice(0, files.length - 50)) {
|
|
34906
34430
|
try {
|
|
34907
|
-
unlinkSync5(
|
|
34431
|
+
unlinkSync5(join44(this.historyDir, old));
|
|
34908
34432
|
} catch {
|
|
34909
34433
|
}
|
|
34910
34434
|
}
|
|
@@ -34917,8 +34441,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
34917
34441
|
});
|
|
34918
34442
|
|
|
34919
34443
|
// packages/cli/dist/tui/snr-engine.js
|
|
34920
|
-
import { existsSync as
|
|
34921
|
-
import { join as
|
|
34444
|
+
import { existsSync as existsSync34, readdirSync as readdirSync12, readFileSync as readFileSync25 } from "node:fs";
|
|
34445
|
+
import { join as join45, basename as basename14 } from "node:path";
|
|
34922
34446
|
function computeDPrime(signalScores, noiseScores) {
|
|
34923
34447
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
34924
34448
|
return 0;
|
|
@@ -34974,13 +34498,6 @@ function adaptTool4(tool) {
|
|
|
34974
34498
|
}
|
|
34975
34499
|
};
|
|
34976
34500
|
}
|
|
34977
|
-
function renderSNRUpdate(score) {
|
|
34978
|
-
const pct = Math.round(score.ratio * 100);
|
|
34979
|
-
const color = pct >= 70 ? c2.green : pct >= 40 ? c2.yellow : c2.red;
|
|
34980
|
-
const capWarn = score.capacityWarning ? c2.red(" [CAPACITY]") : "";
|
|
34981
|
-
process.stdout.write(` ${color("\u25C8")} SNR: ${color(`${pct}%`)} (d'=${score.dPrime.toFixed(1)}, signal=${score.signalCount}/${score.entriesEvaluated}, sparsity=${Math.round(score.sparsity * 100)}%) [${score.evaluators.join("+")}]${capWarn}
|
|
34982
|
-
`);
|
|
34983
|
-
}
|
|
34984
34501
|
var SNREngine;
|
|
34985
34502
|
var init_snr_engine = __esm({
|
|
34986
34503
|
"packages/cli/dist/tui/snr-engine.js"() {
|
|
@@ -35165,11 +34682,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
35165
34682
|
loadMemoryEntries(topics) {
|
|
35166
34683
|
const entries = [];
|
|
35167
34684
|
const dirs = [
|
|
35168
|
-
|
|
35169
|
-
|
|
34685
|
+
join45(this.repoRoot, ".oa", "memory"),
|
|
34686
|
+
join45(this.repoRoot, ".open-agents", "memory")
|
|
35170
34687
|
];
|
|
35171
34688
|
for (const dir of dirs) {
|
|
35172
|
-
if (!
|
|
34689
|
+
if (!existsSync34(dir))
|
|
35173
34690
|
continue;
|
|
35174
34691
|
try {
|
|
35175
34692
|
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -35178,7 +34695,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
35178
34695
|
if (topics.length > 0 && !topics.includes(topic))
|
|
35179
34696
|
continue;
|
|
35180
34697
|
try {
|
|
35181
|
-
const data = JSON.parse(
|
|
34698
|
+
const data = JSON.parse(readFileSync25(join45(dir, f), "utf-8"));
|
|
35182
34699
|
for (const [key, val] of Object.entries(data)) {
|
|
35183
34700
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
35184
34701
|
entries.push({ topic, key, value });
|
|
@@ -35322,6 +34839,7 @@ var init_emotion_engine = __esm({
|
|
|
35322
34839
|
"packages/cli/dist/tui/emotion-engine.js"() {
|
|
35323
34840
|
"use strict";
|
|
35324
34841
|
init_dist5();
|
|
34842
|
+
init_promptLoader3();
|
|
35325
34843
|
BASELINE_VALENCE = 0.1;
|
|
35326
34844
|
BASELINE_AROUSAL = 0.3;
|
|
35327
34845
|
DECAY_HALF_LIFE_MS = 3e5;
|
|
@@ -35390,8 +34908,13 @@ var init_emotion_engine = __esm({
|
|
|
35390
34908
|
} else {
|
|
35391
34909
|
behavioralHint = "You are in a balanced state. Proceed with measured confidence.";
|
|
35392
34910
|
}
|
|
35393
|
-
return
|
|
35394
|
-
|
|
34911
|
+
return loadPrompt3("tui/emotion-behavioral.md", {
|
|
34912
|
+
emoji: this.state.emoji,
|
|
34913
|
+
label: this.state.label,
|
|
34914
|
+
valence: valence.toFixed(2),
|
|
34915
|
+
arousal: arousal.toFixed(2),
|
|
34916
|
+
behavioralHint
|
|
34917
|
+
});
|
|
35395
34918
|
}
|
|
35396
34919
|
/**
|
|
35397
34920
|
* Appraise an agent event and update emotional state.
|
|
@@ -35512,18 +35035,11 @@ ${behavioralHint}`;
|
|
|
35512
35035
|
}
|
|
35513
35036
|
};
|
|
35514
35037
|
runner.registerTools([taskComplete]);
|
|
35515
|
-
const prompt =
|
|
35516
|
-
|
|
35517
|
-
|
|
35518
|
-
|
|
35519
|
-
|
|
35520
|
-
|
|
35521
|
-
You tend to use face emojis (\u{1F60A} \u{1F624} \u{1F914} \u{1F630} \u{1F929} \u{1F60C} \u{1F97A} \u{1F608}) but you can break off to animals, objects, or esoteric emojis when the mood strikes you. The word should be a single evocative emotion word \u2014 not from a fixed list, choose freely. Be creative and authentic.
|
|
35522
|
-
|
|
35523
|
-
Respond with ONLY: <emoji> <word>
|
|
35524
|
-
Example: \u{1F525} exhilarated
|
|
35525
|
-
Example: \u{1F98A} cunning
|
|
35526
|
-
Example: \u{1F30A} flowing`;
|
|
35038
|
+
const prompt = loadPrompt3("tui/emotion-center.md", {
|
|
35039
|
+
valence: this.state.valence.toFixed(2),
|
|
35040
|
+
arousal: this.state.arousal.toFixed(2),
|
|
35041
|
+
recentStreak: this.consecutiveSuccesses > 0 ? `${this.consecutiveSuccesses} successes` : this.consecutiveFailures > 0 ? `${this.consecutiveFailures} failures` : "mixed"
|
|
35042
|
+
});
|
|
35527
35043
|
const result = await runner.run(prompt, "Emotion center \u2014 respond with one emoji and one word only.");
|
|
35528
35044
|
const output = (result.summary || "").trim();
|
|
35529
35045
|
const match = output.match(new RegExp("^(\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F?)\\s+(\\S+)", "u"));
|
|
@@ -35730,8 +35246,8 @@ var init_tool_policy = __esm({
|
|
|
35730
35246
|
});
|
|
35731
35247
|
|
|
35732
35248
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
35733
|
-
import { mkdirSync as mkdirSync15, existsSync as
|
|
35734
|
-
import { join as
|
|
35249
|
+
import { mkdirSync as mkdirSync15, existsSync as existsSync35, unlinkSync as unlinkSync6, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
|
|
35250
|
+
import { join as join46, resolve as resolve27 } from "node:path";
|
|
35735
35251
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
35736
35252
|
function convertMarkdownToTelegramHTML(md) {
|
|
35737
35253
|
let html = md;
|
|
@@ -36483,7 +35999,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
36483
35999
|
return null;
|
|
36484
36000
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
36485
36001
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
36486
|
-
const localPath =
|
|
36002
|
+
const localPath = join46(this.mediaCacheDir, fileName);
|
|
36487
36003
|
await writeFileAsync(localPath, buffer);
|
|
36488
36004
|
return localPath;
|
|
36489
36005
|
} catch {
|
|
@@ -38205,11 +37721,11 @@ var init_status_bar = __esm({
|
|
|
38205
37721
|
import * as readline2 from "node:readline";
|
|
38206
37722
|
import { Writable } from "node:stream";
|
|
38207
37723
|
import { cwd } from "node:process";
|
|
38208
|
-
import { resolve as resolve28, join as
|
|
37724
|
+
import { resolve as resolve28, join as join47, dirname as dirname16, extname as extname9 } from "node:path";
|
|
38209
37725
|
import { createRequire as createRequire2 } from "node:module";
|
|
38210
|
-
import { fileURLToPath as
|
|
38211
|
-
import { readFileSync as
|
|
38212
|
-
import { existsSync as
|
|
37726
|
+
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
37727
|
+
import { readFileSync as readFileSync26, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
|
|
37728
|
+
import { existsSync as existsSync36 } from "node:fs";
|
|
38213
37729
|
function formatTimeAgo(date) {
|
|
38214
37730
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
38215
37731
|
if (seconds < 60)
|
|
@@ -38226,14 +37742,14 @@ function formatTimeAgo(date) {
|
|
|
38226
37742
|
function getVersion2() {
|
|
38227
37743
|
try {
|
|
38228
37744
|
const require2 = createRequire2(import.meta.url);
|
|
38229
|
-
const thisDir =
|
|
37745
|
+
const thisDir = dirname16(fileURLToPath12(import.meta.url));
|
|
38230
37746
|
const candidates = [
|
|
38231
|
-
|
|
38232
|
-
|
|
38233
|
-
|
|
37747
|
+
join47(thisDir, "..", "package.json"),
|
|
37748
|
+
join47(thisDir, "..", "..", "package.json"),
|
|
37749
|
+
join47(thisDir, "..", "..", "..", "package.json")
|
|
38234
37750
|
];
|
|
38235
37751
|
for (const pkgPath of candidates) {
|
|
38236
|
-
if (
|
|
37752
|
+
if (existsSync36(pkgPath)) {
|
|
38237
37753
|
const pkg = require2(pkgPath);
|
|
38238
37754
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
38239
37755
|
return pkg.version ?? "0.0.0";
|
|
@@ -38432,15 +37948,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
38432
37948
|
function gatherMemorySnippets(root) {
|
|
38433
37949
|
const snippets = [];
|
|
38434
37950
|
const dirs = [
|
|
38435
|
-
|
|
38436
|
-
|
|
37951
|
+
join47(root, ".oa", "memory"),
|
|
37952
|
+
join47(root, ".open-agents", "memory")
|
|
38437
37953
|
];
|
|
38438
37954
|
for (const dir of dirs) {
|
|
38439
|
-
if (!
|
|
37955
|
+
if (!existsSync36(dir))
|
|
38440
37956
|
continue;
|
|
38441
37957
|
try {
|
|
38442
37958
|
for (const f of readdirSync14(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
38443
|
-
const data = JSON.parse(
|
|
37959
|
+
const data = JSON.parse(readFileSync26(join47(dir, f), "utf-8"));
|
|
38444
37960
|
for (const val of Object.values(data)) {
|
|
38445
37961
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
38446
37962
|
if (v.length > 10)
|
|
@@ -39075,12 +38591,17 @@ async function startInteractive(config, repoPath) {
|
|
|
39075
38591
|
let exposeGateway = null;
|
|
39076
38592
|
let peerMesh = null;
|
|
39077
38593
|
let inferenceRouter = null;
|
|
39078
|
-
const secretVault = new SecretVault(
|
|
38594
|
+
const secretVault = new SecretVault(join47(repoRoot, ".oa", "vault.enc"));
|
|
39079
38595
|
let adminSessionKey = null;
|
|
39080
38596
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
39081
38597
|
const streamRenderer = new StreamRenderer();
|
|
39082
38598
|
if (savedSettings.voice) {
|
|
39083
|
-
voiceEngine.toggle().catch(() => {
|
|
38599
|
+
voiceEngine.toggle().catch((err) => {
|
|
38600
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
38601
|
+
if (msg.includes("ONNX runtime crashes") || msg.includes("unavailable")) {
|
|
38602
|
+
renderWarning(`Voice disabled: ${msg}`);
|
|
38603
|
+
renderInfo("All other features work normally. Use /voice to retry later.");
|
|
38604
|
+
}
|
|
39084
38605
|
});
|
|
39085
38606
|
if (savedSettings.voiceModel) {
|
|
39086
38607
|
voiceEngine.setModel(savedSettings.voiceModel).catch(() => {
|
|
@@ -39109,7 +38630,6 @@ async function startInteractive(config, repoPath) {
|
|
|
39109
38630
|
try {
|
|
39110
38631
|
const score = await snrEngine.evaluateWithAgents(taskPrompt, []);
|
|
39111
38632
|
statusBar.setSNR(score.ratio, score.dPrime, score.capacityWarning);
|
|
39112
|
-
renderSNRUpdate(score);
|
|
39113
38633
|
} catch {
|
|
39114
38634
|
} finally {
|
|
39115
38635
|
pendingSNREval = null;
|
|
@@ -40120,8 +39640,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
40120
39640
|
return true;
|
|
40121
39641
|
},
|
|
40122
39642
|
destroyProject() {
|
|
40123
|
-
const oaPath =
|
|
40124
|
-
if (
|
|
39643
|
+
const oaPath = join47(repoRoot, OA_DIR);
|
|
39644
|
+
if (existsSync36(oaPath)) {
|
|
40125
39645
|
try {
|
|
40126
39646
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
40127
39647
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -40407,13 +39927,13 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
40407
39927
|
}
|
|
40408
39928
|
}
|
|
40409
39929
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
40410
|
-
const isImage = isImagePath(cleanPath) &&
|
|
40411
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
39930
|
+
const isImage = isImagePath(cleanPath) && existsSync36(resolve28(repoRoot, cleanPath));
|
|
39931
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync36(resolve28(repoRoot, cleanPath));
|
|
40412
39932
|
if (activeTask) {
|
|
40413
39933
|
if (isImage) {
|
|
40414
39934
|
try {
|
|
40415
39935
|
const imgPath = resolve28(repoRoot, cleanPath);
|
|
40416
|
-
const imgBuffer =
|
|
39936
|
+
const imgBuffer = readFileSync26(imgPath);
|
|
40417
39937
|
const base64 = imgBuffer.toString("base64");
|
|
40418
39938
|
const ext = extname9(cleanPath).toLowerCase();
|
|
40419
39939
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -40908,7 +40428,7 @@ import { glob } from "glob";
|
|
|
40908
40428
|
import ignore from "ignore";
|
|
40909
40429
|
import { readFile as readFile16, stat as stat4 } from "node:fs/promises";
|
|
40910
40430
|
import { createHash as createHash4 } from "node:crypto";
|
|
40911
|
-
import { join as
|
|
40431
|
+
import { join as join48, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
|
|
40912
40432
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
40913
40433
|
var init_codebase_indexer = __esm({
|
|
40914
40434
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -40952,7 +40472,7 @@ var init_codebase_indexer = __esm({
|
|
|
40952
40472
|
const ig = ignore.default();
|
|
40953
40473
|
if (this.config.respectGitignore) {
|
|
40954
40474
|
try {
|
|
40955
|
-
const gitignoreContent = await readFile16(
|
|
40475
|
+
const gitignoreContent = await readFile16(join48(this.config.rootDir, ".gitignore"), "utf-8");
|
|
40956
40476
|
ig.add(gitignoreContent);
|
|
40957
40477
|
} catch {
|
|
40958
40478
|
}
|
|
@@ -40967,7 +40487,7 @@ var init_codebase_indexer = __esm({
|
|
|
40967
40487
|
for (const relativePath of files) {
|
|
40968
40488
|
if (ig.ignores(relativePath))
|
|
40969
40489
|
continue;
|
|
40970
|
-
const fullPath =
|
|
40490
|
+
const fullPath = join48(this.config.rootDir, relativePath);
|
|
40971
40491
|
try {
|
|
40972
40492
|
const fileStat = await stat4(fullPath);
|
|
40973
40493
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -41013,7 +40533,7 @@ var init_codebase_indexer = __esm({
|
|
|
41013
40533
|
if (!child) {
|
|
41014
40534
|
child = {
|
|
41015
40535
|
name: part,
|
|
41016
|
-
path:
|
|
40536
|
+
path: join48(current.path, part),
|
|
41017
40537
|
type: "directory",
|
|
41018
40538
|
children: []
|
|
41019
40539
|
};
|
|
@@ -41096,13 +40616,13 @@ __export(index_repo_exports, {
|
|
|
41096
40616
|
indexRepoCommand: () => indexRepoCommand
|
|
41097
40617
|
});
|
|
41098
40618
|
import { resolve as resolve29 } from "node:path";
|
|
41099
|
-
import { existsSync as
|
|
40619
|
+
import { existsSync as existsSync37, statSync as statSync11 } from "node:fs";
|
|
41100
40620
|
import { cwd as cwd2 } from "node:process";
|
|
41101
40621
|
async function indexRepoCommand(opts, _config) {
|
|
41102
40622
|
const repoRoot = resolve29(opts.repoPath ?? cwd2());
|
|
41103
40623
|
printHeader("Index Repository");
|
|
41104
40624
|
printInfo(`Indexing: ${repoRoot}`);
|
|
41105
|
-
if (!
|
|
40625
|
+
if (!existsSync37(repoRoot)) {
|
|
41106
40626
|
printError(`Path does not exist: ${repoRoot}`);
|
|
41107
40627
|
process.exit(1);
|
|
41108
40628
|
}
|
|
@@ -41354,7 +40874,7 @@ var config_exports = {};
|
|
|
41354
40874
|
__export(config_exports, {
|
|
41355
40875
|
configCommand: () => configCommand
|
|
41356
40876
|
});
|
|
41357
|
-
import { join as
|
|
40877
|
+
import { join as join49, resolve as resolve30 } from "node:path";
|
|
41358
40878
|
import { homedir as homedir13 } from "node:os";
|
|
41359
40879
|
import { cwd as cwd3 } from "node:process";
|
|
41360
40880
|
function redactIfSensitive(key, value) {
|
|
@@ -41413,7 +40933,7 @@ function handleShow(opts, config) {
|
|
|
41413
40933
|
}
|
|
41414
40934
|
}
|
|
41415
40935
|
printSection("Config File");
|
|
41416
|
-
printInfo(`~/.open-agents/config.json (${
|
|
40936
|
+
printInfo(`~/.open-agents/config.json (${join49(homedir13(), ".open-agents", "config.json")})`);
|
|
41417
40937
|
printSection("Priority Chain");
|
|
41418
40938
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
41419
40939
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -41452,7 +40972,7 @@ function handleSet(opts, _config) {
|
|
|
41452
40972
|
const coerced = coerceForSettings(key, value);
|
|
41453
40973
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
41454
40974
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
41455
|
-
printInfo(`Saved to ${
|
|
40975
|
+
printInfo(`Saved to ${join49(repoRoot, ".oa", "settings.json")}`);
|
|
41456
40976
|
printInfo("This override applies only when running in this workspace.");
|
|
41457
40977
|
} catch (err) {
|
|
41458
40978
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -41672,7 +41192,7 @@ __export(eval_exports, {
|
|
|
41672
41192
|
});
|
|
41673
41193
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
41674
41194
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "node:fs";
|
|
41675
|
-
import { join as
|
|
41195
|
+
import { join as join50 } from "node:path";
|
|
41676
41196
|
async function evalCommand(opts, config) {
|
|
41677
41197
|
const suiteName = opts.suite ?? "basic";
|
|
41678
41198
|
const suite = SUITES[suiteName];
|
|
@@ -41793,9 +41313,9 @@ async function evalCommand(opts, config) {
|
|
|
41793
41313
|
process.exit(failed > 0 ? 1 : 0);
|
|
41794
41314
|
}
|
|
41795
41315
|
function createTempEvalRepo() {
|
|
41796
|
-
const dir =
|
|
41316
|
+
const dir = join50(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
41797
41317
|
mkdirSync16(dir, { recursive: true });
|
|
41798
|
-
writeFileSync14(
|
|
41318
|
+
writeFileSync14(join50(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
41799
41319
|
return dir;
|
|
41800
41320
|
}
|
|
41801
41321
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -41854,8 +41374,8 @@ init_output();
|
|
|
41854
41374
|
init_updater();
|
|
41855
41375
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
41856
41376
|
import { createRequire as createRequire3 } from "node:module";
|
|
41857
|
-
import { fileURLToPath as
|
|
41858
|
-
import { dirname as
|
|
41377
|
+
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
41378
|
+
import { dirname as dirname17, join as join51 } from "node:path";
|
|
41859
41379
|
|
|
41860
41380
|
// packages/cli/dist/cli.js
|
|
41861
41381
|
import { createInterface } from "node:readline";
|
|
@@ -41962,7 +41482,7 @@ init_output();
|
|
|
41962
41482
|
function getVersion3() {
|
|
41963
41483
|
try {
|
|
41964
41484
|
const require2 = createRequire3(import.meta.url);
|
|
41965
|
-
const pkgPath =
|
|
41485
|
+
const pkgPath = join51(dirname17(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
41966
41486
|
const pkg = require2(pkgPath);
|
|
41967
41487
|
return pkg.version;
|
|
41968
41488
|
} catch {
|