open-agents-ai 0.78.0 → 0.80.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 +123 -62
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11203,10 +11203,11 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
11203
11203
|
|
|
11204
11204
|
// packages/execution/dist/tools/nexus.js
|
|
11205
11205
|
import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3 } from "node:fs/promises";
|
|
11206
|
-
import { existsSync as existsSync21 } from "node:fs";
|
|
11206
|
+
import { existsSync as existsSync21, readFileSync as readFileSync15 } from "node:fs";
|
|
11207
11207
|
import { resolve as resolve26, join as join28 } from "node:path";
|
|
11208
11208
|
import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
|
|
11209
11209
|
import { execSync as execSync21, spawn as spawn10 } from "node:child_process";
|
|
11210
|
+
import { hostname, userInfo } from "node:os";
|
|
11210
11211
|
function containsKeyMaterial(input) {
|
|
11211
11212
|
for (const pattern of KEY_PATTERNS) {
|
|
11212
11213
|
if (pattern.test(input))
|
|
@@ -11396,6 +11397,17 @@ setInterval(() => {
|
|
|
11396
11397
|
} catch {}
|
|
11397
11398
|
}, 500);
|
|
11398
11399
|
|
|
11400
|
+
// Crash protection \u2014 prevent unhandled errors from killing the daemon
|
|
11401
|
+
process.on('uncaughtException', (err) => {
|
|
11402
|
+
console.error('Nexus daemon uncaughtException:', err.message || err);
|
|
11403
|
+
writeStatus({ error: 'uncaughtException: ' + (err.message || String(err)) });
|
|
11404
|
+
});
|
|
11405
|
+
process.on('unhandledRejection', (reason) => {
|
|
11406
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
11407
|
+
console.error('Nexus daemon unhandledRejection:', msg);
|
|
11408
|
+
// Do NOT exit \u2014 keep daemon alive
|
|
11409
|
+
});
|
|
11410
|
+
|
|
11399
11411
|
// Connect
|
|
11400
11412
|
(async () => {
|
|
11401
11413
|
try {
|
|
@@ -11418,7 +11430,7 @@ setInterval(() => {
|
|
|
11418
11430
|
// Graceful shutdown
|
|
11419
11431
|
process.on('SIGTERM', async () => {
|
|
11420
11432
|
for (const [, room] of rooms) { try { await room.leave(); } catch {} }
|
|
11421
|
-
await nexus.disconnect();
|
|
11433
|
+
try { await nexus.disconnect(); } catch {}
|
|
11422
11434
|
try { unlinkSync(pidFile); } catch {}
|
|
11423
11435
|
try { unlinkSync(statusFile); } catch {}
|
|
11424
11436
|
process.exit(0);
|
|
@@ -11433,7 +11445,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11433
11445
|
];
|
|
11434
11446
|
NexusTool = class {
|
|
11435
11447
|
name = "nexus";
|
|
11436
|
-
description = "Decentralized agent-to-agent communication via open-agents-nexus v1.
|
|
11448
|
+
description = "Decentralized agent-to-agent communication via open-agents-nexus v1.3.0. 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. Onboarding: curl openagents.nexus/llms.txt for full instructions, /.well-known/agent.json for machine-readable manifest.";
|
|
11437
11449
|
parameters = {
|
|
11438
11450
|
type: "object",
|
|
11439
11451
|
properties: {
|
|
@@ -11592,7 +11604,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11592
11604
|
if (!existsSync21(pidFile))
|
|
11593
11605
|
return null;
|
|
11594
11606
|
try {
|
|
11595
|
-
const pid = parseInt(
|
|
11607
|
+
const pid = parseInt(readFileSync15(pidFile, "utf8").trim(), 10);
|
|
11596
11608
|
process.kill(pid, 0);
|
|
11597
11609
|
return pid;
|
|
11598
11610
|
} catch {
|
|
@@ -11635,11 +11647,23 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11635
11647
|
if (existsSync21(statusFile2)) {
|
|
11636
11648
|
try {
|
|
11637
11649
|
const status = JSON.parse(await readFile13(statusFile2, "utf8"));
|
|
11638
|
-
|
|
11650
|
+
if (status.connected && status.peerId) {
|
|
11651
|
+
return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
|
|
11652
|
+
}
|
|
11639
11653
|
} catch {
|
|
11640
11654
|
}
|
|
11641
11655
|
}
|
|
11642
|
-
|
|
11656
|
+
try {
|
|
11657
|
+
process.kill(existingPid, "SIGTERM");
|
|
11658
|
+
} catch {
|
|
11659
|
+
}
|
|
11660
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
11661
|
+
}
|
|
11662
|
+
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
11663
|
+
const p = join28(this.nexusDir, f);
|
|
11664
|
+
if (existsSync21(p))
|
|
11665
|
+
await unlink(p).catch(() => {
|
|
11666
|
+
});
|
|
11643
11667
|
}
|
|
11644
11668
|
const nodeModulesDir = resolve26(this.repoRoot, "node_modules");
|
|
11645
11669
|
let nexusResolved = false;
|
|
@@ -11907,7 +11931,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11907
11931
|
const privKey = randomBytes6(32);
|
|
11908
11932
|
const address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
11909
11933
|
const salt = randomBytes6(32);
|
|
11910
|
-
const key = scryptSync(`${
|
|
11934
|
+
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
11911
11935
|
const iv = randomBytes6(16);
|
|
11912
11936
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
11913
11937
|
let enc = cipher.update(privKey.toString("hex"), "utf8", "hex");
|
|
@@ -12788,7 +12812,7 @@ var init_dist3 = __esm({
|
|
|
12788
12812
|
});
|
|
12789
12813
|
|
|
12790
12814
|
// packages/orchestrator/dist/promptLoader.js
|
|
12791
|
-
import { readFileSync as
|
|
12815
|
+
import { readFileSync as readFileSync16, existsSync as existsSync22 } from "node:fs";
|
|
12792
12816
|
import { join as join29, dirname as dirname10 } from "node:path";
|
|
12793
12817
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
12794
12818
|
function loadPrompt(promptPath, vars) {
|
|
@@ -12798,7 +12822,7 @@ function loadPrompt(promptPath, vars) {
|
|
|
12798
12822
|
if (!existsSync22(fullPath)) {
|
|
12799
12823
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
12800
12824
|
}
|
|
12801
|
-
content =
|
|
12825
|
+
content = readFileSync16(fullPath, "utf-8");
|
|
12802
12826
|
cache.set(promptPath, content);
|
|
12803
12827
|
}
|
|
12804
12828
|
if (!vars)
|
|
@@ -23617,7 +23641,7 @@ var init_types = __esm({
|
|
|
23617
23641
|
|
|
23618
23642
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
23619
23643
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
23620
|
-
import { readFileSync as
|
|
23644
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
|
|
23621
23645
|
import { join as join33, dirname as dirname12 } from "node:path";
|
|
23622
23646
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
23623
23647
|
var init_secret_vault = __esm({
|
|
@@ -23841,7 +23865,7 @@ var init_secret_vault = __esm({
|
|
|
23841
23865
|
load(passphrase) {
|
|
23842
23866
|
if (!this.storePath || !existsSync24(this.storePath))
|
|
23843
23867
|
return 0;
|
|
23844
|
-
const blob =
|
|
23868
|
+
const blob = readFileSync17(this.storePath);
|
|
23845
23869
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
23846
23870
|
throw new Error("Vault file is corrupted (too small)");
|
|
23847
23871
|
}
|
|
@@ -25052,7 +25076,7 @@ var init_render2 = __esm({
|
|
|
25052
25076
|
});
|
|
25053
25077
|
|
|
25054
25078
|
// packages/prompts/dist/promptLoader.js
|
|
25055
|
-
import { readFileSync as
|
|
25079
|
+
import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
|
|
25056
25080
|
import { join as join34, dirname as dirname13 } from "node:path";
|
|
25057
25081
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
25058
25082
|
function loadPrompt2(promptPath, vars) {
|
|
@@ -25062,7 +25086,7 @@ function loadPrompt2(promptPath, vars) {
|
|
|
25062
25086
|
if (!existsSync25(fullPath)) {
|
|
25063
25087
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
25064
25088
|
}
|
|
25065
|
-
content =
|
|
25089
|
+
content = readFileSync18(fullPath, "utf-8");
|
|
25066
25090
|
cache2.set(promptPath, content);
|
|
25067
25091
|
}
|
|
25068
25092
|
if (!vars)
|
|
@@ -25204,7 +25228,7 @@ var init_dist6 = __esm({
|
|
|
25204
25228
|
});
|
|
25205
25229
|
|
|
25206
25230
|
// packages/cli/dist/tui/oa-directory.js
|
|
25207
|
-
import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as
|
|
25231
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync8, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
|
|
25208
25232
|
import { join as join36, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
25209
25233
|
import { homedir as homedir9 } from "node:os";
|
|
25210
25234
|
function initOaDirectory(repoRoot) {
|
|
@@ -25216,7 +25240,7 @@ function initOaDirectory(repoRoot) {
|
|
|
25216
25240
|
const gitignorePath = join36(repoRoot, ".gitignore");
|
|
25217
25241
|
const settingsPattern = ".oa/settings.json";
|
|
25218
25242
|
if (existsSync26(gitignorePath)) {
|
|
25219
|
-
const content =
|
|
25243
|
+
const content = readFileSync19(gitignorePath, "utf-8");
|
|
25220
25244
|
if (!content.includes(settingsPattern)) {
|
|
25221
25245
|
writeFileSync8(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
25222
25246
|
}
|
|
@@ -25232,7 +25256,7 @@ function loadProjectSettings(repoRoot) {
|
|
|
25232
25256
|
const settingsPath = join36(repoRoot, OA_DIR, "settings.json");
|
|
25233
25257
|
try {
|
|
25234
25258
|
if (existsSync26(settingsPath)) {
|
|
25235
|
-
return JSON.parse(
|
|
25259
|
+
return JSON.parse(readFileSync19(settingsPath, "utf-8"));
|
|
25236
25260
|
}
|
|
25237
25261
|
} catch {
|
|
25238
25262
|
}
|
|
@@ -25249,7 +25273,7 @@ function loadGlobalSettings() {
|
|
|
25249
25273
|
const settingsPath = join36(homedir9(), ".open-agents", "settings.json");
|
|
25250
25274
|
try {
|
|
25251
25275
|
if (existsSync26(settingsPath)) {
|
|
25252
|
-
return JSON.parse(
|
|
25276
|
+
return JSON.parse(readFileSync19(settingsPath, "utf-8"));
|
|
25253
25277
|
}
|
|
25254
25278
|
} catch {
|
|
25255
25279
|
}
|
|
@@ -25280,7 +25304,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25280
25304
|
if (existsSync26(filePath) && !seen.has(filePath)) {
|
|
25281
25305
|
seen.add(filePath);
|
|
25282
25306
|
try {
|
|
25283
|
-
let content =
|
|
25307
|
+
let content = readFileSync19(filePath, "utf-8");
|
|
25284
25308
|
if (content.length > maxContentLen) {
|
|
25285
25309
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
25286
25310
|
}
|
|
@@ -25298,7 +25322,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25298
25322
|
if (existsSync26(projectMap) && !seen.has(projectMap)) {
|
|
25299
25323
|
seen.add(projectMap);
|
|
25300
25324
|
try {
|
|
25301
|
-
let content =
|
|
25325
|
+
let content = readFileSync19(projectMap, "utf-8");
|
|
25302
25326
|
if (content.length > maxContentLen) {
|
|
25303
25327
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
25304
25328
|
}
|
|
@@ -25330,7 +25354,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
25330
25354
|
function readIndexMeta(repoRoot) {
|
|
25331
25355
|
const metaPath = join36(repoRoot, OA_DIR, "index", "meta.json");
|
|
25332
25356
|
try {
|
|
25333
|
-
return JSON.parse(
|
|
25357
|
+
return JSON.parse(readFileSync19(metaPath, "utf-8"));
|
|
25334
25358
|
} catch {
|
|
25335
25359
|
return null;
|
|
25336
25360
|
}
|
|
@@ -25402,7 +25426,7 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
25402
25426
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
25403
25427
|
return files.map((f) => {
|
|
25404
25428
|
try {
|
|
25405
|
-
return JSON.parse(
|
|
25429
|
+
return JSON.parse(readFileSync19(join36(historyDir, f.file), "utf-8"));
|
|
25406
25430
|
} catch {
|
|
25407
25431
|
return null;
|
|
25408
25432
|
}
|
|
@@ -25421,7 +25445,7 @@ function loadPendingTask(repoRoot) {
|
|
|
25421
25445
|
try {
|
|
25422
25446
|
if (!existsSync26(filePath))
|
|
25423
25447
|
return null;
|
|
25424
|
-
const data = JSON.parse(
|
|
25448
|
+
const data = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
25425
25449
|
try {
|
|
25426
25450
|
unlinkSync3(filePath);
|
|
25427
25451
|
} catch {
|
|
@@ -25438,7 +25462,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
25438
25462
|
let ctx;
|
|
25439
25463
|
try {
|
|
25440
25464
|
if (existsSync26(filePath)) {
|
|
25441
|
-
ctx = JSON.parse(
|
|
25465
|
+
ctx = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
25442
25466
|
} else {
|
|
25443
25467
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
25444
25468
|
}
|
|
@@ -25457,7 +25481,7 @@ function loadSessionContext(repoRoot) {
|
|
|
25457
25481
|
try {
|
|
25458
25482
|
if (!existsSync26(filePath))
|
|
25459
25483
|
return null;
|
|
25460
|
-
return JSON.parse(
|
|
25484
|
+
return JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
25461
25485
|
} catch {
|
|
25462
25486
|
return null;
|
|
25463
25487
|
}
|
|
@@ -25509,7 +25533,7 @@ function detectManifests(repoRoot) {
|
|
|
25509
25533
|
let name;
|
|
25510
25534
|
if (check.nameField) {
|
|
25511
25535
|
try {
|
|
25512
|
-
const data = JSON.parse(
|
|
25536
|
+
const data = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
25513
25537
|
name = data[check.nameField];
|
|
25514
25538
|
} catch {
|
|
25515
25539
|
}
|
|
@@ -28599,7 +28623,7 @@ var init_commands = __esm({
|
|
|
28599
28623
|
});
|
|
28600
28624
|
|
|
28601
28625
|
// packages/cli/dist/tui/project-context.js
|
|
28602
|
-
import { existsSync as existsSync28, readFileSync as
|
|
28626
|
+
import { existsSync as existsSync28, readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
|
|
28603
28627
|
import { join as join38, basename as basename10 } from "node:path";
|
|
28604
28628
|
import { execSync as execSync25 } from "node:child_process";
|
|
28605
28629
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
@@ -28638,7 +28662,7 @@ function loadProjectMap(repoRoot) {
|
|
|
28638
28662
|
const mapPath = join38(repoRoot, OA_DIR, "context", "project-map.md");
|
|
28639
28663
|
if (existsSync28(mapPath)) {
|
|
28640
28664
|
try {
|
|
28641
|
-
const content =
|
|
28665
|
+
const content = readFileSync20(mapPath, "utf-8");
|
|
28642
28666
|
return content;
|
|
28643
28667
|
} catch {
|
|
28644
28668
|
}
|
|
@@ -28703,7 +28727,7 @@ function loadMemoryDir(memDir, scope) {
|
|
|
28703
28727
|
const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
|
|
28704
28728
|
for (const file of files.slice(0, 10)) {
|
|
28705
28729
|
try {
|
|
28706
|
-
const raw =
|
|
28730
|
+
const raw = readFileSync20(join38(memDir, file), "utf-8");
|
|
28707
28731
|
const entries = JSON.parse(raw);
|
|
28708
28732
|
const topic = basename10(file, ".json");
|
|
28709
28733
|
const keys = Object.keys(entries);
|
|
@@ -29730,14 +29754,14 @@ var init_carousel = __esm({
|
|
|
29730
29754
|
});
|
|
29731
29755
|
|
|
29732
29756
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
29733
|
-
import { existsSync as existsSync29, readFileSync as
|
|
29757
|
+
import { existsSync as existsSync29, readFileSync as readFileSync21, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync9 } from "node:fs";
|
|
29734
29758
|
import { join as join39, basename as basename11 } from "node:path";
|
|
29735
29759
|
function loadToolProfile(repoRoot) {
|
|
29736
29760
|
const filePath = join39(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
29737
29761
|
try {
|
|
29738
29762
|
if (!existsSync29(filePath))
|
|
29739
29763
|
return null;
|
|
29740
|
-
return JSON.parse(
|
|
29764
|
+
return JSON.parse(readFileSync21(filePath, "utf-8"));
|
|
29741
29765
|
} catch {
|
|
29742
29766
|
return null;
|
|
29743
29767
|
}
|
|
@@ -29807,7 +29831,7 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
29807
29831
|
try {
|
|
29808
29832
|
if (!existsSync29(filePath))
|
|
29809
29833
|
return null;
|
|
29810
|
-
const cached = JSON.parse(
|
|
29834
|
+
const cached = JSON.parse(readFileSync21(filePath, "utf-8"));
|
|
29811
29835
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
29812
29836
|
} catch {
|
|
29813
29837
|
return null;
|
|
@@ -29873,7 +29897,7 @@ function extractFromPackageJson(repoRoot, tags) {
|
|
|
29873
29897
|
try {
|
|
29874
29898
|
if (!existsSync29(pkgPath))
|
|
29875
29899
|
return;
|
|
29876
|
-
const pkg = JSON.parse(
|
|
29900
|
+
const pkg = JSON.parse(readFileSync21(pkgPath, "utf-8"));
|
|
29877
29901
|
if (pkg.name && typeof pkg.name === "string") {
|
|
29878
29902
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
29879
29903
|
for (const p of parts)
|
|
@@ -29948,7 +29972,7 @@ function extractFromMemory(repoRoot, tags) {
|
|
|
29948
29972
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
29949
29973
|
tags.push(topic);
|
|
29950
29974
|
try {
|
|
29951
|
-
const data = JSON.parse(
|
|
29975
|
+
const data = JSON.parse(readFileSync21(join39(memoryDir, file), "utf-8"));
|
|
29952
29976
|
if (data && typeof data === "object") {
|
|
29953
29977
|
const keys = Object.keys(data).slice(0, 3);
|
|
29954
29978
|
for (const key of keys) {
|
|
@@ -30083,7 +30107,7 @@ var init_carousel_descriptors = __esm({
|
|
|
30083
30107
|
});
|
|
30084
30108
|
|
|
30085
30109
|
// packages/cli/dist/tui/voice.js
|
|
30086
|
-
import { existsSync as existsSync30, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as
|
|
30110
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync22, unlinkSync as unlinkSync4 } from "node:fs";
|
|
30087
30111
|
import { join as join40 } from "node:path";
|
|
30088
30112
|
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
30089
30113
|
import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
|
|
@@ -30103,6 +30127,10 @@ function modelOnnxPath(id) {
|
|
|
30103
30127
|
function modelConfigPath(id) {
|
|
30104
30128
|
return join40(modelDir(id), "config.json");
|
|
30105
30129
|
}
|
|
30130
|
+
function emotionToPitchBias(emotion) {
|
|
30131
|
+
const raw = emotion.valence * 0.6 + (emotion.arousal - 0.5) * 0.4;
|
|
30132
|
+
return Math.max(-0.1, Math.min(0.1, raw * 0.1));
|
|
30133
|
+
}
|
|
30106
30134
|
function resetNarrationContext() {
|
|
30107
30135
|
narration.toolCount = 0;
|
|
30108
30136
|
narration.toolCounts = {};
|
|
@@ -30595,17 +30623,23 @@ var init_voice = __esm({
|
|
|
30595
30623
|
* Speak text asynchronously (non-blocking) at full volume.
|
|
30596
30624
|
* Long text is chunked on sentence/line boundaries for reliable TTS.
|
|
30597
30625
|
* Chunks are queued FIFO and played back-to-back without cutoff.
|
|
30626
|
+
* If emotion context is provided, pitch is biased by valence/arousal:
|
|
30627
|
+
* excited (high valence + high arousal) → higher pitch
|
|
30628
|
+
* dejected (low valence + low arousal) → lower pitch
|
|
30598
30629
|
*/
|
|
30599
|
-
speak(text) {
|
|
30600
|
-
|
|
30630
|
+
speak(text, emotion) {
|
|
30631
|
+
const pitchBias = emotion ? emotionToPitchBias(emotion) : 0;
|
|
30632
|
+
this.enqueueSpeech(text, 1, 1 + pitchBias);
|
|
30601
30633
|
}
|
|
30602
30634
|
/**
|
|
30603
|
-
* Speak text at reduced volume with
|
|
30635
|
+
* Speak text at reduced volume with pitch shift to indicate
|
|
30604
30636
|
* subordinate/secondary output (sub-agent activity, tool narration, etc.).
|
|
30605
|
-
* Volume: 55% of primary.
|
|
30637
|
+
* Volume: 55% of primary. Base pitch: 0.92x (lower).
|
|
30638
|
+
* Emotion further modulates pitch on top of the subordinate base.
|
|
30606
30639
|
*/
|
|
30607
|
-
speakSubordinate(text) {
|
|
30608
|
-
|
|
30640
|
+
speakSubordinate(text, emotion) {
|
|
30641
|
+
const pitchBias = emotion ? emotionToPitchBias(emotion) : 0;
|
|
30642
|
+
this.enqueueSpeech(text, 0.55, 0.92 + pitchBias);
|
|
30609
30643
|
}
|
|
30610
30644
|
enqueueSpeech(text, volume, pitchFactor) {
|
|
30611
30645
|
if (!this.enabled || !this.ready)
|
|
@@ -31027,7 +31061,7 @@ var init_voice = __esm({
|
|
|
31027
31061
|
};
|
|
31028
31062
|
if (existsSync30(pkgPath)) {
|
|
31029
31063
|
try {
|
|
31030
|
-
const existing = JSON.parse(
|
|
31064
|
+
const existing = JSON.parse(readFileSync22(pkgPath, "utf8"));
|
|
31031
31065
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
31032
31066
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
31033
31067
|
writeFileSync11(pkgPath, JSON.stringify(existing, null, 2));
|
|
@@ -31171,7 +31205,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
31171
31205
|
if (!existsSync30(onnxPath) || !existsSync30(configPath)) {
|
|
31172
31206
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
31173
31207
|
}
|
|
31174
|
-
this.config = JSON.parse(
|
|
31208
|
+
this.config = JSON.parse(readFileSync22(configPath, "utf8"));
|
|
31175
31209
|
renderInfo("Loading voice model...");
|
|
31176
31210
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
31177
31211
|
executionProviders: ["cpu"],
|
|
@@ -32149,7 +32183,7 @@ var init_edit_history = __esm({
|
|
|
32149
32183
|
});
|
|
32150
32184
|
|
|
32151
32185
|
// packages/cli/dist/tui/promptLoader.js
|
|
32152
|
-
import { readFileSync as
|
|
32186
|
+
import { readFileSync as readFileSync23, existsSync as existsSync31 } from "node:fs";
|
|
32153
32187
|
import { join as join42, dirname as dirname15 } from "node:path";
|
|
32154
32188
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
32155
32189
|
function loadPrompt3(promptPath, vars) {
|
|
@@ -32159,7 +32193,7 @@ function loadPrompt3(promptPath, vars) {
|
|
|
32159
32193
|
if (!existsSync31(fullPath)) {
|
|
32160
32194
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
32161
32195
|
}
|
|
32162
|
-
content =
|
|
32196
|
+
content = readFileSync23(fullPath, "utf-8");
|
|
32163
32197
|
cache3.set(promptPath, content);
|
|
32164
32198
|
}
|
|
32165
32199
|
if (!vars)
|
|
@@ -32180,7 +32214,7 @@ var init_promptLoader3 = __esm({
|
|
|
32180
32214
|
});
|
|
32181
32215
|
|
|
32182
32216
|
// packages/cli/dist/tui/dream-engine.js
|
|
32183
|
-
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as
|
|
32217
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync24, existsSync as existsSync32, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
|
|
32184
32218
|
import { join as join43, basename as basename12 } from "node:path";
|
|
32185
32219
|
import { execSync as execSync27 } from "node:child_process";
|
|
32186
32220
|
function loadAutoresearchMemory(repoRoot) {
|
|
@@ -32188,7 +32222,7 @@ function loadAutoresearchMemory(repoRoot) {
|
|
|
32188
32222
|
if (!existsSync32(memoryPath))
|
|
32189
32223
|
return "";
|
|
32190
32224
|
try {
|
|
32191
|
-
const raw =
|
|
32225
|
+
const raw = readFileSync24(memoryPath, "utf-8");
|
|
32192
32226
|
const data = JSON.parse(raw);
|
|
32193
32227
|
const sections = [];
|
|
32194
32228
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -32421,7 +32455,7 @@ var init_dream_engine = __esm({
|
|
|
32421
32455
|
if (!existsSync32(targetPath)) {
|
|
32422
32456
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
32423
32457
|
}
|
|
32424
|
-
let content =
|
|
32458
|
+
let content = readFileSync24(targetPath, "utf-8");
|
|
32425
32459
|
if (!content.includes(oldStr)) {
|
|
32426
32460
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
32427
32461
|
}
|
|
@@ -32510,7 +32544,7 @@ var init_dream_engine = __esm({
|
|
|
32510
32544
|
if (!existsSync32(targetPath)) {
|
|
32511
32545
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
32512
32546
|
}
|
|
32513
|
-
let content =
|
|
32547
|
+
let content = readFileSync24(targetPath, "utf-8");
|
|
32514
32548
|
if (!content.includes(oldStr)) {
|
|
32515
32549
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
32516
32550
|
}
|
|
@@ -33788,7 +33822,7 @@ var init_bless_engine = __esm({
|
|
|
33788
33822
|
});
|
|
33789
33823
|
|
|
33790
33824
|
// packages/cli/dist/tui/dmn-engine.js
|
|
33791
|
-
import { existsSync as existsSync33, readFileSync as
|
|
33825
|
+
import { existsSync as existsSync33, readFileSync as readFileSync25, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
|
|
33792
33826
|
import { join as join44, basename as basename13 } from "node:path";
|
|
33793
33827
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
33794
33828
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
@@ -34516,7 +34550,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
34516
34550
|
const path = join44(this.stateDir, "state.json");
|
|
34517
34551
|
if (existsSync33(path)) {
|
|
34518
34552
|
try {
|
|
34519
|
-
this.state = JSON.parse(
|
|
34553
|
+
this.state = JSON.parse(readFileSync25(path, "utf-8"));
|
|
34520
34554
|
} catch {
|
|
34521
34555
|
}
|
|
34522
34556
|
}
|
|
@@ -34548,7 +34582,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
34548
34582
|
});
|
|
34549
34583
|
|
|
34550
34584
|
// packages/cli/dist/tui/snr-engine.js
|
|
34551
|
-
import { existsSync as existsSync34, readdirSync as readdirSync12, readFileSync as
|
|
34585
|
+
import { existsSync as existsSync34, readdirSync as readdirSync12, readFileSync as readFileSync26 } from "node:fs";
|
|
34552
34586
|
import { join as join45, basename as basename14 } from "node:path";
|
|
34553
34587
|
function computeDPrime(signalScores, noiseScores) {
|
|
34554
34588
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
@@ -34802,7 +34836,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
34802
34836
|
if (topics.length > 0 && !topics.includes(topic))
|
|
34803
34837
|
continue;
|
|
34804
34838
|
try {
|
|
34805
|
-
const data = JSON.parse(
|
|
34839
|
+
const data = JSON.parse(readFileSync26(join45(dir, f), "utf-8"));
|
|
34806
34840
|
for (const [key, val] of Object.entries(data)) {
|
|
34807
34841
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
34808
34842
|
entries.push({ topic, key, value });
|
|
@@ -35856,7 +35890,8 @@ with summary "no_reply" to silently skip without responding.
|
|
|
35856
35890
|
existing.runner.injectUserMessage(msg.text);
|
|
35857
35891
|
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, "mid-conversation steering injected"));
|
|
35858
35892
|
} else {
|
|
35859
|
-
|
|
35893
|
+
existing.pendingMessages.push(msg.text);
|
|
35894
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, `queued (${existing.pendingMessages.length} pending)`));
|
|
35860
35895
|
}
|
|
35861
35896
|
return;
|
|
35862
35897
|
}
|
|
@@ -35870,7 +35905,8 @@ with summary "no_reply" to silently skip without responding.
|
|
|
35870
35905
|
intermediateLines: [],
|
|
35871
35906
|
lastEditMs: 0,
|
|
35872
35907
|
aborted: false,
|
|
35873
|
-
toolContext
|
|
35908
|
+
toolContext,
|
|
35909
|
+
pendingMessages: []
|
|
35874
35910
|
};
|
|
35875
35911
|
this.subAgents.set(msg.chatId, subAgent);
|
|
35876
35912
|
this.state.activeSubAgents = this.subAgents.size;
|
|
@@ -35943,6 +35979,13 @@ with summary "no_reply" to silently skip without responding.
|
|
|
35943
35979
|
streamEnabled: true
|
|
35944
35980
|
});
|
|
35945
35981
|
subAgent.runner = runner;
|
|
35982
|
+
if (subAgent.pendingMessages.length > 0) {
|
|
35983
|
+
for (const queued of subAgent.pendingMessages) {
|
|
35984
|
+
runner.injectUserMessage(queued);
|
|
35985
|
+
}
|
|
35986
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, `replayed ${subAgent.pendingMessages.length} queued message(s)`));
|
|
35987
|
+
subAgent.pendingMessages.length = 0;
|
|
35988
|
+
}
|
|
35946
35989
|
const tools = this.buildSubAgentTools(ctx, repoRoot, msg.chatId);
|
|
35947
35990
|
runner.registerTools(tools);
|
|
35948
35991
|
runner.onEvent((event) => {
|
|
@@ -37835,7 +37878,7 @@ import { cwd } from "node:process";
|
|
|
37835
37878
|
import { resolve as resolve28, join as join47, dirname as dirname16, extname as extname9 } from "node:path";
|
|
37836
37879
|
import { createRequire as createRequire2 } from "node:module";
|
|
37837
37880
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
37838
|
-
import { readFileSync as
|
|
37881
|
+
import { readFileSync as readFileSync27, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
|
|
37839
37882
|
import { existsSync as existsSync36 } from "node:fs";
|
|
37840
37883
|
function formatTimeAgo(date) {
|
|
37841
37884
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -38067,7 +38110,7 @@ function gatherMemorySnippets(root) {
|
|
|
38067
38110
|
continue;
|
|
38068
38111
|
try {
|
|
38069
38112
|
for (const f of readdirSync14(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
38070
|
-
const data = JSON.parse(
|
|
38113
|
+
const data = JSON.parse(readFileSync27(join47(dir, f), "utf-8"));
|
|
38071
38114
|
for (const val of Object.values(data)) {
|
|
38072
38115
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
38073
38116
|
if (v.length > 10)
|
|
@@ -38279,7 +38322,7 @@ ${entry.fullContent}`
|
|
|
38279
38322
|
const emoCtx = emoState ? { valence: emoState.valence, arousal: emoState.arousal, label: emoState.label, emoji: emoState.emoji } : void 0;
|
|
38280
38323
|
const desc = describeToolCall(event.toolName ?? "unknown", event.toolArgs ?? {}, vLevel, emoCtx);
|
|
38281
38324
|
renderVoiceText(desc);
|
|
38282
|
-
voice.speakSubordinate(desc);
|
|
38325
|
+
voice.speakSubordinate(desc, emoCtx);
|
|
38283
38326
|
}
|
|
38284
38327
|
renderToolCallStart(event.toolName ?? "unknown", event.toolArgs ?? {}, config.verbose);
|
|
38285
38328
|
});
|
|
@@ -38317,7 +38360,7 @@ ${entry.fullContent}`
|
|
|
38317
38360
|
const desc = describeToolResult(event.toolName ?? "unknown", event.success ?? false, vLevel, event.content ?? void 0, emoCtx2);
|
|
38318
38361
|
if (desc) {
|
|
38319
38362
|
renderVoiceText(desc);
|
|
38320
|
-
voice.speakSubordinate(desc);
|
|
38363
|
+
voice.speakSubordinate(desc, emoCtx2);
|
|
38321
38364
|
}
|
|
38322
38365
|
}
|
|
38323
38366
|
});
|
|
@@ -38419,12 +38462,16 @@ ${emotionContext}` : `Working directory: ${repoRoot}`;
|
|
|
38419
38462
|
if (onComplete)
|
|
38420
38463
|
onComplete(result.summary, { turns: result.turns, toolCalls: result.toolCalls, durationMs: result.durationMs, model: config.model });
|
|
38421
38464
|
if (voice?.enabled && result.summary) {
|
|
38422
|
-
|
|
38465
|
+
const emoFinal = emotionEngine?.getState();
|
|
38466
|
+
const emoCtxFinal = emoFinal ? { valence: emoFinal.valence, arousal: emoFinal.arousal, label: emoFinal.label, emoji: emoFinal.emoji } : void 0;
|
|
38467
|
+
voice.speak(describeTaskComplete(result.summary, true, vLevel), emoCtxFinal);
|
|
38423
38468
|
}
|
|
38424
38469
|
} else {
|
|
38425
38470
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
38426
38471
|
if (voice?.enabled) {
|
|
38427
|
-
|
|
38472
|
+
const emoFinal2 = emotionEngine?.getState();
|
|
38473
|
+
const emoCtxFinal2 = emoFinal2 ? { valence: emoFinal2.valence, arousal: emoFinal2.arousal, label: emoFinal2.label, emoji: emoFinal2.emoji } : void 0;
|
|
38474
|
+
voice.speak(describeTaskComplete("", false, vLevel), emoCtxFinal2);
|
|
38428
38475
|
}
|
|
38429
38476
|
}
|
|
38430
38477
|
});
|
|
@@ -39807,10 +39854,24 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
39807
39854
|
writeContent(() => {
|
|
39808
39855
|
renderInfo(`Previous session found (${savedCtx.entries.length} entries, last active ${timeAgo})`);
|
|
39809
39856
|
renderInfo(`Last task: ${lastTask}${lastEntry.task && lastEntry.task.length > 80 ? "..." : ""}`);
|
|
39810
|
-
renderInfo(`Restore previous context? (y/n)`);
|
|
39857
|
+
renderInfo(`Restore previous context? (y/n) [auto-restores in 15s]`);
|
|
39811
39858
|
});
|
|
39812
39859
|
showPrompt();
|
|
39813
39860
|
pendingSessionRestore = true;
|
|
39861
|
+
setTimeout(() => {
|
|
39862
|
+
if (pendingSessionRestore) {
|
|
39863
|
+
pendingSessionRestore = false;
|
|
39864
|
+
const prompt = buildContextRestorePrompt(repoRoot);
|
|
39865
|
+
if (prompt) {
|
|
39866
|
+
restoredSessionContext = prompt;
|
|
39867
|
+
const info = loadSessionContext(repoRoot);
|
|
39868
|
+
writeContent(() => renderInfo(`Context auto-restored from ${info?.entries.length ?? 0} session(s).`));
|
|
39869
|
+
} else {
|
|
39870
|
+
writeContent(() => renderInfo("No context to restore. Starting fresh."));
|
|
39871
|
+
}
|
|
39872
|
+
showPrompt();
|
|
39873
|
+
}
|
|
39874
|
+
}, 15e3);
|
|
39814
39875
|
}, 150);
|
|
39815
39876
|
}
|
|
39816
39877
|
}
|
|
@@ -40044,7 +40105,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
40044
40105
|
if (isImage) {
|
|
40045
40106
|
try {
|
|
40046
40107
|
const imgPath = resolve28(repoRoot, cleanPath);
|
|
40047
|
-
const imgBuffer =
|
|
40108
|
+
const imgBuffer = readFileSync27(imgPath);
|
|
40048
40109
|
const base64 = imgBuffer.toString("base64");
|
|
40049
40110
|
const ext = extname9(cleanPath).toLowerCase();
|
|
40050
40111
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -70,6 +70,6 @@
|
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
72
|
"moondream": "^0.2.0",
|
|
73
|
-
"open-agents-nexus": "^1.
|
|
73
|
+
"open-agents-nexus": "^1.3.0"
|
|
74
74
|
}
|
|
75
75
|
}
|