open-agents-ai 0.187.160 → 0.187.161
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 +1159 -795
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -245714,9 +245714,9 @@ print("${sentinel}")
|
|
|
245714
245714
|
if (!this.proc || this.proc.killed) {
|
|
245715
245715
|
return { success: false, path: "" };
|
|
245716
245716
|
}
|
|
245717
|
-
const { mkdirSync:
|
|
245717
|
+
const { mkdirSync: mkdirSync46, writeFileSync: writeFileSync41 } = await import("node:fs");
|
|
245718
245718
|
const sessionDir = join24(this.cwd, ".oa", "rlm");
|
|
245719
|
-
|
|
245719
|
+
mkdirSync46(sessionDir, { recursive: true });
|
|
245720
245720
|
const sessionPath = join24(sessionDir, "session.json");
|
|
245721
245721
|
try {
|
|
245722
245722
|
const inspectCode = `
|
|
@@ -245752,9 +245752,9 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
245752
245752
|
* what was previously computed. */
|
|
245753
245753
|
async loadSessionInfo() {
|
|
245754
245754
|
try {
|
|
245755
|
-
const { readFileSync: readFileSync60, existsSync:
|
|
245755
|
+
const { readFileSync: readFileSync60, existsSync: existsSync78 } = await import("node:fs");
|
|
245756
245756
|
const sessionPath = join24(this.cwd, ".oa", "rlm", "session.json");
|
|
245757
|
-
if (!
|
|
245757
|
+
if (!existsSync78(sessionPath))
|
|
245758
245758
|
return null;
|
|
245759
245759
|
return JSON.parse(readFileSync60(sessionPath, "utf8"));
|
|
245760
245760
|
} catch {
|
|
@@ -246320,10 +246320,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246320
246320
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
246321
246321
|
*/
|
|
246322
246322
|
getTopMemoriesSync(k = 5, taskType) {
|
|
246323
|
-
const { readFileSync: readFileSync60, existsSync:
|
|
246323
|
+
const { readFileSync: readFileSync60, existsSync: existsSync78 } = __require("node:fs");
|
|
246324
246324
|
const metaDir = join25(this.cwd, ".oa", "memory", "metabolism");
|
|
246325
246325
|
const storeFile = join25(metaDir, "store.json");
|
|
246326
|
-
if (!
|
|
246326
|
+
if (!existsSync78(storeFile))
|
|
246327
246327
|
return "";
|
|
246328
246328
|
let store2 = [];
|
|
246329
246329
|
try {
|
|
@@ -246349,10 +246349,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246349
246349
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
246350
246350
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
246351
246351
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
246352
|
-
const { readFileSync: readFileSync60, writeFileSync: writeFileSync41, existsSync:
|
|
246352
|
+
const { readFileSync: readFileSync60, writeFileSync: writeFileSync41, existsSync: existsSync78, mkdirSync: mkdirSync46 } = __require("node:fs");
|
|
246353
246353
|
const metaDir = join25(this.cwd, ".oa", "memory", "metabolism");
|
|
246354
246354
|
const storeFile = join25(metaDir, "store.json");
|
|
246355
|
-
if (!
|
|
246355
|
+
if (!existsSync78(storeFile))
|
|
246356
246356
|
return;
|
|
246357
246357
|
let store2 = [];
|
|
246358
246358
|
try {
|
|
@@ -246380,7 +246380,7 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246380
246380
|
updated = true;
|
|
246381
246381
|
}
|
|
246382
246382
|
if (updated) {
|
|
246383
|
-
|
|
246383
|
+
mkdirSync46(metaDir, { recursive: true });
|
|
246384
246384
|
writeFileSync41(storeFile, JSON.stringify(store2, null, 2));
|
|
246385
246385
|
}
|
|
246386
246386
|
}
|
|
@@ -246803,9 +246803,9 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246803
246803
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
246804
246804
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
246805
246805
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
246806
|
-
const { readFileSync: readFileSync60, existsSync:
|
|
246806
|
+
const { readFileSync: readFileSync60, existsSync: existsSync78 } = __require("node:fs");
|
|
246807
246807
|
const archiveFile = join27(this.cwd, ".oa", "arche", "variants.json");
|
|
246808
|
-
if (!
|
|
246808
|
+
if (!existsSync78(archiveFile))
|
|
246809
246809
|
return "";
|
|
246810
246810
|
let variants = [];
|
|
246811
246811
|
try {
|
|
@@ -246827,12 +246827,12 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246827
246827
|
}
|
|
246828
246828
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
246829
246829
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
246830
|
-
const { readFileSync: readFileSync60, writeFileSync: writeFileSync41, existsSync:
|
|
246830
|
+
const { readFileSync: readFileSync60, writeFileSync: writeFileSync41, existsSync: existsSync78, mkdirSync: mkdirSync46 } = __require("node:fs");
|
|
246831
246831
|
const dir = join27(this.cwd, ".oa", "arche");
|
|
246832
246832
|
const archiveFile = join27(dir, "variants.json");
|
|
246833
246833
|
let variants = [];
|
|
246834
246834
|
try {
|
|
246835
|
-
if (
|
|
246835
|
+
if (existsSync78(archiveFile))
|
|
246836
246836
|
variants = JSON.parse(readFileSync60(archiveFile, "utf8"));
|
|
246837
246837
|
} catch {
|
|
246838
246838
|
}
|
|
@@ -246848,7 +246848,7 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246848
246848
|
});
|
|
246849
246849
|
if (variants.length > 50)
|
|
246850
246850
|
variants = variants.slice(-50);
|
|
246851
|
-
|
|
246851
|
+
mkdirSync46(dir, { recursive: true });
|
|
246852
246852
|
writeFileSync41(archiveFile, JSON.stringify(variants, null, 2));
|
|
246853
246853
|
}
|
|
246854
246854
|
async saveArchive(variants) {
|
|
@@ -264834,17 +264834,286 @@ var init_episodeStore = __esm({
|
|
|
264834
264834
|
});
|
|
264835
264835
|
|
|
264836
264836
|
// packages/memory/dist/temporalGraph.js
|
|
264837
|
+
import { join as join61 } from "node:path";
|
|
264838
|
+
import { mkdirSync as mkdirSync21, existsSync as existsSync46 } from "node:fs";
|
|
264839
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
264840
|
+
var TemporalGraph;
|
|
264837
264841
|
var init_temporalGraph = __esm({
|
|
264838
264842
|
"packages/memory/dist/temporalGraph.js"() {
|
|
264839
264843
|
"use strict";
|
|
264840
264844
|
init_db();
|
|
264845
|
+
TemporalGraph = class {
|
|
264846
|
+
db;
|
|
264847
|
+
constructor(dbPath) {
|
|
264848
|
+
const dir = dbPath === ":memory:" ? null : join61(dbPath, "..");
|
|
264849
|
+
if (dir && !existsSync46(dir))
|
|
264850
|
+
mkdirSync21(dir, { recursive: true });
|
|
264851
|
+
this.db = initDb(dbPath);
|
|
264852
|
+
this.db.exec(`
|
|
264853
|
+
CREATE TABLE IF NOT EXISTS kg_nodes (
|
|
264854
|
+
id TEXT PRIMARY KEY,
|
|
264855
|
+
text TEXT NOT NULL,
|
|
264856
|
+
node_type TEXT DEFAULT 'entity',
|
|
264857
|
+
embedding BLOB,
|
|
264858
|
+
first_seen INTEGER NOT NULL,
|
|
264859
|
+
last_seen INTEGER NOT NULL,
|
|
264860
|
+
mention_count INTEGER DEFAULT 1
|
|
264861
|
+
)
|
|
264862
|
+
`);
|
|
264863
|
+
this.db.exec(`
|
|
264864
|
+
CREATE TABLE IF NOT EXISTS kg_edges (
|
|
264865
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
264866
|
+
src_id TEXT NOT NULL REFERENCES kg_nodes(id),
|
|
264867
|
+
dst_id TEXT NOT NULL REFERENCES kg_nodes(id),
|
|
264868
|
+
relation TEXT NOT NULL,
|
|
264869
|
+
fact TEXT,
|
|
264870
|
+
edge_type TEXT DEFAULT 'triple',
|
|
264871
|
+
valid_from INTEGER NOT NULL,
|
|
264872
|
+
valid_until INTEGER,
|
|
264873
|
+
confidence REAL DEFAULT 1.0,
|
|
264874
|
+
source_episode_id TEXT,
|
|
264875
|
+
modality TEXT DEFAULT 'text'
|
|
264876
|
+
)
|
|
264877
|
+
`);
|
|
264878
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_kgn_text ON kg_nodes(text)`);
|
|
264879
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_kge_src ON kg_edges(src_id)`);
|
|
264880
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_kge_dst ON kg_edges(dst_id)`);
|
|
264881
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_kge_valid ON kg_edges(valid_from, valid_until)`);
|
|
264882
|
+
this.db.pragma("journal_mode = WAL");
|
|
264883
|
+
this.db.pragma("synchronous = NORMAL");
|
|
264884
|
+
}
|
|
264885
|
+
// ─── Node operations ─────────────────────────────────────────────────────
|
|
264886
|
+
/** Get or create a node. If it exists, increment mention_count and update last_seen. */
|
|
264887
|
+
upsertNode(insert) {
|
|
264888
|
+
const now = Date.now();
|
|
264889
|
+
const existing = this.db.prepare("SELECT id, mention_count FROM kg_nodes WHERE text = ? AND node_type = ?").get(insert.text, insert.nodeType);
|
|
264890
|
+
if (existing) {
|
|
264891
|
+
this.db.prepare("UPDATE kg_nodes SET mention_count = mention_count + 1, last_seen = ? WHERE id = ?").run(now, existing.id);
|
|
264892
|
+
return existing.id;
|
|
264893
|
+
}
|
|
264894
|
+
const id = randomUUID5();
|
|
264895
|
+
const embBuf = insert.embedding ? Buffer.from(insert.embedding.buffer) : null;
|
|
264896
|
+
this.db.prepare(`
|
|
264897
|
+
INSERT INTO kg_nodes (id, text, node_type, embedding, first_seen, last_seen, mention_count)
|
|
264898
|
+
VALUES (?, ?, ?, ?, ?, ?, 1)
|
|
264899
|
+
`).run(id, insert.text, insert.nodeType, embBuf, now, now);
|
|
264900
|
+
return id;
|
|
264901
|
+
}
|
|
264902
|
+
/** Find a node by text (case-insensitive). */
|
|
264903
|
+
findNode(text, nodeType) {
|
|
264904
|
+
const sql = nodeType ? "SELECT * FROM kg_nodes WHERE text = ? AND node_type = ? LIMIT 1" : "SELECT * FROM kg_nodes WHERE text = ? LIMIT 1";
|
|
264905
|
+
const row = nodeType ? this.db.prepare(sql).get(text, nodeType) : this.db.prepare(sql).get(text);
|
|
264906
|
+
return row ? this.rowToNode(row) : null;
|
|
264907
|
+
}
|
|
264908
|
+
/** Get a node by ID. */
|
|
264909
|
+
getNode(id) {
|
|
264910
|
+
const row = this.db.prepare("SELECT * FROM kg_nodes WHERE id = ?").get(id);
|
|
264911
|
+
return row ? this.rowToNode(row) : null;
|
|
264912
|
+
}
|
|
264913
|
+
/** List all nodes of a given type. */
|
|
264914
|
+
nodesByType(nodeType, limit = 100) {
|
|
264915
|
+
return this.db.prepare("SELECT * FROM kg_nodes WHERE node_type = ? ORDER BY mention_count DESC LIMIT ?").all(nodeType, limit).map((r2) => this.rowToNode(r2));
|
|
264916
|
+
}
|
|
264917
|
+
// ─── Edge operations ─────────────────────────────────────────────────────
|
|
264918
|
+
/** Add an edge. If a conflicting edge exists (same src, dst, relation), supersede it. */
|
|
264919
|
+
addEdge(insert) {
|
|
264920
|
+
const now = Date.now();
|
|
264921
|
+
this.db.prepare(`
|
|
264922
|
+
UPDATE kg_edges SET valid_until = ?
|
|
264923
|
+
WHERE src_id = ? AND dst_id = ? AND relation = ? AND valid_until IS NULL
|
|
264924
|
+
`).run(now, insert.srcId, insert.dstId, insert.relation);
|
|
264925
|
+
const result = this.db.prepare(`
|
|
264926
|
+
INSERT INTO kg_edges (src_id, dst_id, relation, fact, edge_type, valid_from, valid_until, confidence, source_episode_id, modality)
|
|
264927
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?, ?)
|
|
264928
|
+
`).run(
|
|
264929
|
+
insert.srcId,
|
|
264930
|
+
insert.dstId,
|
|
264931
|
+
insert.relation,
|
|
264932
|
+
insert.fact ?? null,
|
|
264933
|
+
insert.edgeType ?? "triple",
|
|
264934
|
+
now,
|
|
264935
|
+
// valid_from = now
|
|
264936
|
+
insert.confidence ?? 1,
|
|
264937
|
+
insert.sourceEpisodeId ?? null,
|
|
264938
|
+
insert.modality ?? "text"
|
|
264939
|
+
);
|
|
264940
|
+
return result.lastInsertRowid;
|
|
264941
|
+
}
|
|
264942
|
+
// ─── Temporal queries ────────────────────────────────────────────────────
|
|
264943
|
+
/** Get currently valid edges for a node. */
|
|
264944
|
+
currentEdges(nodeId) {
|
|
264945
|
+
return this.db.prepare(`
|
|
264946
|
+
SELECT * FROM kg_edges
|
|
264947
|
+
WHERE (src_id = ? OR dst_id = ?) AND valid_until IS NULL
|
|
264948
|
+
ORDER BY valid_from DESC
|
|
264949
|
+
`).all(nodeId, nodeId).map((r2) => this.rowToEdge(r2));
|
|
264950
|
+
}
|
|
264951
|
+
/** Get edges valid at a specific time. */
|
|
264952
|
+
edgesAtTime(nodeId, timestamp) {
|
|
264953
|
+
return this.db.prepare(`
|
|
264954
|
+
SELECT * FROM kg_edges
|
|
264955
|
+
WHERE (src_id = ? OR dst_id = ?)
|
|
264956
|
+
AND valid_from <= ?
|
|
264957
|
+
AND (valid_until IS NULL OR valid_until > ?)
|
|
264958
|
+
ORDER BY valid_from DESC
|
|
264959
|
+
`).all(nodeId, nodeId, timestamp, timestamp).map((r2) => this.rowToEdge(r2));
|
|
264960
|
+
}
|
|
264961
|
+
/** Get full history of a node (all edges, including superseded). */
|
|
264962
|
+
nodeHistory(nodeId) {
|
|
264963
|
+
return this.db.prepare(`
|
|
264964
|
+
SELECT * FROM kg_edges
|
|
264965
|
+
WHERE src_id = ? OR dst_id = ?
|
|
264966
|
+
ORDER BY valid_from ASC
|
|
264967
|
+
`).all(nodeId, nodeId).map((r2) => this.rowToEdge(r2));
|
|
264968
|
+
}
|
|
264969
|
+
/** Get edges that changed between two timestamps. */
|
|
264970
|
+
changedBetween(start2, end) {
|
|
264971
|
+
return this.db.prepare(`
|
|
264972
|
+
SELECT * FROM kg_edges
|
|
264973
|
+
WHERE valid_from BETWEEN ? AND ?
|
|
264974
|
+
ORDER BY valid_from ASC
|
|
264975
|
+
`).all(start2, end).map((r2) => this.rowToEdge(r2));
|
|
264976
|
+
}
|
|
264977
|
+
/** Find neighbors of a node (1-hop traversal). */
|
|
264978
|
+
neighbors(nodeId, relation) {
|
|
264979
|
+
let sql = `
|
|
264980
|
+
SELECT e.*, n.id as n_id, n.text as n_text, n.node_type as n_type,
|
|
264981
|
+
n.first_seen as n_first, n.last_seen as n_last, n.mention_count as n_mentions
|
|
264982
|
+
FROM kg_edges e
|
|
264983
|
+
JOIN kg_nodes n ON (e.dst_id = n.id AND e.src_id = ?) OR (e.src_id = n.id AND e.dst_id = ?)
|
|
264984
|
+
WHERE e.valid_until IS NULL
|
|
264985
|
+
`;
|
|
264986
|
+
const params = [nodeId, nodeId];
|
|
264987
|
+
if (relation) {
|
|
264988
|
+
sql += " AND e.relation = ?";
|
|
264989
|
+
params.push(relation);
|
|
264990
|
+
}
|
|
264991
|
+
sql += " ORDER BY e.valid_from DESC";
|
|
264992
|
+
return this.db.prepare(sql).all(...params).map((r2) => ({
|
|
264993
|
+
node: { id: r2.n_id, text: r2.n_text, nodeType: r2.n_type, embedding: null, firstSeen: r2.n_first, lastSeen: r2.n_last, mentionCount: r2.n_mentions },
|
|
264994
|
+
edge: this.rowToEdge(r2)
|
|
264995
|
+
}));
|
|
264996
|
+
}
|
|
264997
|
+
// ─── Statistics ──────────────────────────────────────────────────────────
|
|
264998
|
+
nodeCount() {
|
|
264999
|
+
return this.db.prepare("SELECT COUNT(*) as n FROM kg_nodes").get().n;
|
|
265000
|
+
}
|
|
265001
|
+
edgeCount() {
|
|
265002
|
+
return this.db.prepare("SELECT COUNT(*) as n FROM kg_edges").get().n;
|
|
265003
|
+
}
|
|
265004
|
+
activeEdgeCount() {
|
|
265005
|
+
return this.db.prepare("SELECT COUNT(*) as n FROM kg_edges WHERE valid_until IS NULL").get().n;
|
|
265006
|
+
}
|
|
265007
|
+
close() {
|
|
265008
|
+
try {
|
|
265009
|
+
this.db.close();
|
|
265010
|
+
} catch {
|
|
265011
|
+
}
|
|
265012
|
+
}
|
|
265013
|
+
// ─── Internal ────────────────────────────────────────────────────────────
|
|
265014
|
+
rowToNode(row) {
|
|
265015
|
+
return {
|
|
265016
|
+
id: row.id,
|
|
265017
|
+
text: row.text,
|
|
265018
|
+
nodeType: row.node_type,
|
|
265019
|
+
embedding: row.embedding ? new Float32Array(new Uint8Array(row.embedding).buffer) : null,
|
|
265020
|
+
firstSeen: row.first_seen,
|
|
265021
|
+
lastSeen: row.last_seen,
|
|
265022
|
+
mentionCount: row.mention_count
|
|
265023
|
+
};
|
|
265024
|
+
}
|
|
265025
|
+
rowToEdge(row) {
|
|
265026
|
+
return {
|
|
265027
|
+
id: row.id,
|
|
265028
|
+
srcId: row.src_id,
|
|
265029
|
+
dstId: row.dst_id,
|
|
265030
|
+
relation: row.relation,
|
|
265031
|
+
fact: row.fact,
|
|
265032
|
+
edgeType: row.edge_type,
|
|
265033
|
+
validFrom: row.valid_from,
|
|
265034
|
+
validUntil: row.valid_until,
|
|
265035
|
+
confidence: row.confidence,
|
|
265036
|
+
sourceEpisodeId: row.source_episode_id,
|
|
265037
|
+
modality: row.modality
|
|
265038
|
+
};
|
|
265039
|
+
}
|
|
265040
|
+
};
|
|
264841
265041
|
}
|
|
264842
265042
|
});
|
|
264843
265043
|
|
|
264844
265044
|
// packages/memory/dist/embeddings.js
|
|
265045
|
+
async function generateEmbedding(text, config) {
|
|
265046
|
+
const cfg = { ...DEFAULT_CONFIG4, ...config };
|
|
265047
|
+
try {
|
|
265048
|
+
const url = `${cfg.baseUrl}/api/embed`;
|
|
265049
|
+
const resp = await fetch(url, {
|
|
265050
|
+
method: "POST",
|
|
265051
|
+
headers: { "Content-Type": "application/json" },
|
|
265052
|
+
body: JSON.stringify({
|
|
265053
|
+
model: cfg.model,
|
|
265054
|
+
input: text
|
|
265055
|
+
}),
|
|
265056
|
+
signal: AbortSignal.timeout(cfg.timeoutMs)
|
|
265057
|
+
});
|
|
265058
|
+
if (!resp.ok) {
|
|
265059
|
+
if (resp.status === 404) {
|
|
265060
|
+
const pulled = await pullEmbeddingModel(cfg.baseUrl, cfg.model, cfg.timeoutMs);
|
|
265061
|
+
if (!pulled)
|
|
265062
|
+
return null;
|
|
265063
|
+
return generateEmbedding(text, config);
|
|
265064
|
+
}
|
|
265065
|
+
return null;
|
|
265066
|
+
}
|
|
265067
|
+
const data = await resp.json();
|
|
265068
|
+
const rawVector = data.embeddings?.[0] ?? data.embedding;
|
|
265069
|
+
if (!rawVector || rawVector.length === 0)
|
|
265070
|
+
return null;
|
|
265071
|
+
return {
|
|
265072
|
+
vector: new Float32Array(rawVector),
|
|
265073
|
+
model: cfg.model,
|
|
265074
|
+
dimensions: rawVector.length
|
|
265075
|
+
};
|
|
265076
|
+
} catch {
|
|
265077
|
+
return null;
|
|
265078
|
+
}
|
|
265079
|
+
}
|
|
265080
|
+
async function checkEmbeddingAvailable(config) {
|
|
265081
|
+
const cfg = { ...DEFAULT_CONFIG4, ...config };
|
|
265082
|
+
try {
|
|
265083
|
+
const resp = await fetch(`${cfg.baseUrl}/api/tags`, {
|
|
265084
|
+
signal: AbortSignal.timeout(5e3)
|
|
265085
|
+
});
|
|
265086
|
+
if (!resp.ok)
|
|
265087
|
+
return false;
|
|
265088
|
+
const data = await resp.json();
|
|
265089
|
+
return data.models?.some((m2) => m2.name.startsWith(cfg.model)) ?? false;
|
|
265090
|
+
} catch {
|
|
265091
|
+
return false;
|
|
265092
|
+
}
|
|
265093
|
+
}
|
|
265094
|
+
async function pullEmbeddingModel(baseUrl, model, timeoutMs) {
|
|
265095
|
+
try {
|
|
265096
|
+
const resp = await fetch(`${baseUrl}/api/pull`, {
|
|
265097
|
+
method: "POST",
|
|
265098
|
+
headers: { "Content-Type": "application/json" },
|
|
265099
|
+
body: JSON.stringify({ name: model, stream: false }),
|
|
265100
|
+
signal: AbortSignal.timeout(timeoutMs * 10)
|
|
265101
|
+
// pulling can take minutes
|
|
265102
|
+
});
|
|
265103
|
+
return resp.ok;
|
|
265104
|
+
} catch {
|
|
265105
|
+
return false;
|
|
265106
|
+
}
|
|
265107
|
+
}
|
|
265108
|
+
var DEFAULT_CONFIG4;
|
|
264845
265109
|
var init_embeddings = __esm({
|
|
264846
265110
|
"packages/memory/dist/embeddings.js"() {
|
|
264847
265111
|
"use strict";
|
|
265112
|
+
DEFAULT_CONFIG4 = {
|
|
265113
|
+
baseUrl: "http://localhost:11434",
|
|
265114
|
+
model: "nomic-embed-text",
|
|
265115
|
+
timeoutMs: 3e4
|
|
265116
|
+
};
|
|
264848
265117
|
}
|
|
264849
265118
|
});
|
|
264850
265119
|
|
|
@@ -265607,11 +265876,40 @@ var init_agenticRunner = __esm({
|
|
|
265607
265876
|
_errorPatterns = /* @__PURE__ */ new Map();
|
|
265608
265877
|
_errorGuidanceInjected = /* @__PURE__ */ new Set();
|
|
265609
265878
|
// prevent duplicate injection per turn
|
|
265610
|
-
// ── WO-AM-01:
|
|
265611
|
-
//
|
|
265612
|
-
//
|
|
265879
|
+
// ── WO-AM-01/04/10: Associative memory stores ──
|
|
265880
|
+
// Episode store: every tool call → persistent episode with importance + decay
|
|
265881
|
+
// Temporal KG: entities + relations with temporal validity (valid_from/valid_until)
|
|
265882
|
+
// Embedding pipeline: background embedding computation for episodes
|
|
265613
265883
|
_episodeStore = null;
|
|
265614
|
-
|
|
265884
|
+
_temporalGraph = null;
|
|
265885
|
+
_memoryInitialized = false;
|
|
265886
|
+
_embeddingAvailable = null;
|
|
265887
|
+
// null = not checked yet
|
|
265888
|
+
_pendingEmbeddings = [];
|
|
265889
|
+
_embeddingTimer = null;
|
|
265890
|
+
/** WO-AM-10: Process pending episode embeddings in background batches */
|
|
265891
|
+
async processPendingEmbeddings() {
|
|
265892
|
+
if (this._pendingEmbeddings.length === 0 || !this._episodeStore)
|
|
265893
|
+
return;
|
|
265894
|
+
const batch2 = this._pendingEmbeddings.splice(0, 20);
|
|
265895
|
+
const baseUrl = this.backend.baseUrl ?? "http://localhost:11434";
|
|
265896
|
+
for (const { id, content } of batch2) {
|
|
265897
|
+
try {
|
|
265898
|
+
const embResult = await generateEmbedding(content, { baseUrl });
|
|
265899
|
+
if (embResult?.vector) {
|
|
265900
|
+
this._episodeStore.setEmbedding(id, embResult.vector);
|
|
265901
|
+
}
|
|
265902
|
+
} catch {
|
|
265903
|
+
}
|
|
265904
|
+
}
|
|
265905
|
+
}
|
|
265906
|
+
/** Stop the embedding pipeline timer */
|
|
265907
|
+
stopEmbeddingPipeline() {
|
|
265908
|
+
if (this._embeddingTimer) {
|
|
265909
|
+
clearInterval(this._embeddingTimer);
|
|
265910
|
+
this._embeddingTimer = null;
|
|
265911
|
+
}
|
|
265912
|
+
}
|
|
265615
265913
|
_loopBlockedTools;
|
|
265616
265914
|
// Loop intervention: tools removed from schema
|
|
265617
265915
|
// -- Session Checkpointing (Priority 5) --
|
|
@@ -266137,12 +266435,19 @@ Respond with your assessment, then take action.`;
|
|
|
266137
266435
|
const toolCallLog = [];
|
|
266138
266436
|
this.aborted = false;
|
|
266139
266437
|
this._paused = false;
|
|
266140
|
-
if (!this.
|
|
266438
|
+
if (!this._memoryInitialized) {
|
|
266141
266439
|
try {
|
|
266142
266440
|
const path5 = await import("node:path");
|
|
266143
|
-
const
|
|
266144
|
-
this._episodeStore = new EpisodeStore(
|
|
266145
|
-
this.
|
|
266441
|
+
const oaDir = path5.join(process.cwd(), ".oa");
|
|
266442
|
+
this._episodeStore = new EpisodeStore(path5.join(oaDir, "episodes.db"));
|
|
266443
|
+
this._temporalGraph = new TemporalGraph(path5.join(oaDir, "knowledge.db"));
|
|
266444
|
+
this._embeddingAvailable = await checkEmbeddingAvailable({
|
|
266445
|
+
baseUrl: this.backend.baseUrl ?? "http://localhost:11434"
|
|
266446
|
+
}).catch(() => false);
|
|
266447
|
+
if (this._embeddingAvailable && !this._embeddingTimer) {
|
|
266448
|
+
this._embeddingTimer = setInterval(() => this.processPendingEmbeddings(), 1e4);
|
|
266449
|
+
}
|
|
266450
|
+
this._memoryInitialized = true;
|
|
266146
266451
|
} catch {
|
|
266147
266452
|
}
|
|
266148
266453
|
}
|
|
@@ -266911,18 +267216,62 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
266911
267216
|
}
|
|
266912
267217
|
if (this._episodeStore) {
|
|
266913
267218
|
try {
|
|
266914
|
-
|
|
267219
|
+
const episodeContent = result.success ? `${tc.name}: ${(result.output ?? "").slice(0, 500)}` : `${tc.name} ERROR: ${(result.error ?? result.output ?? "").slice(0, 500)}`;
|
|
267220
|
+
const episodeId = this._episodeStore.insert({
|
|
266915
267221
|
sessionId: this._sessionId,
|
|
266916
267222
|
turnNumber: turn,
|
|
266917
|
-
modality:
|
|
267223
|
+
modality: "tool_result",
|
|
266918
267224
|
toolName: tc.name,
|
|
266919
|
-
content:
|
|
267225
|
+
content: episodeContent,
|
|
266920
267226
|
metadata: {
|
|
266921
267227
|
args_fingerprint: argsKey.slice(0, 200),
|
|
266922
267228
|
success: result.success,
|
|
266923
267229
|
duration_ms: performance.now() - toolStart
|
|
266924
267230
|
}
|
|
266925
267231
|
});
|
|
267232
|
+
if (this._embeddingAvailable && episodeContent.length > 20) {
|
|
267233
|
+
this._pendingEmbeddings.push({ id: episodeId, content: episodeContent.slice(0, 500) });
|
|
267234
|
+
}
|
|
267235
|
+
if (this._temporalGraph) {
|
|
267236
|
+
try {
|
|
267237
|
+
const toolNodeId = this._temporalGraph.upsertNode({
|
|
267238
|
+
text: tc.name,
|
|
267239
|
+
nodeType: "tool"
|
|
267240
|
+
});
|
|
267241
|
+
const filePath2 = tc.arguments?.path || tc.arguments?.file_path || tc.arguments?.file;
|
|
267242
|
+
if (filePath2) {
|
|
267243
|
+
const fileNodeId = this._temporalGraph.upsertNode({
|
|
267244
|
+
text: filePath2,
|
|
267245
|
+
nodeType: "file"
|
|
267246
|
+
});
|
|
267247
|
+
const relation = ["file_write", "file_edit", "file_patch", "batch_edit"].includes(tc.name) ? "modified_by" : "related_to";
|
|
267248
|
+
this._temporalGraph.addEdge({
|
|
267249
|
+
srcId: fileNodeId,
|
|
267250
|
+
dstId: toolNodeId,
|
|
267251
|
+
relation,
|
|
267252
|
+
fact: `${filePath2} ${relation} ${tc.name}`,
|
|
267253
|
+
edgeType: "triple",
|
|
267254
|
+
sourceEpisodeId: episodeId
|
|
267255
|
+
});
|
|
267256
|
+
}
|
|
267257
|
+
if (!result.success && result.error) {
|
|
267258
|
+
const errorText = result.error.slice(0, 100);
|
|
267259
|
+
const errorNodeId = this._temporalGraph.upsertNode({
|
|
267260
|
+
text: errorText,
|
|
267261
|
+
nodeType: "error"
|
|
267262
|
+
});
|
|
267263
|
+
this._temporalGraph.addEdge({
|
|
267264
|
+
srcId: toolNodeId,
|
|
267265
|
+
dstId: errorNodeId,
|
|
267266
|
+
relation: "caused_by",
|
|
267267
|
+
fact: `${tc.name} caused: ${errorText}`,
|
|
267268
|
+
edgeType: "causal",
|
|
267269
|
+
sourceEpisodeId: episodeId
|
|
267270
|
+
});
|
|
267271
|
+
}
|
|
267272
|
+
} catch {
|
|
267273
|
+
}
|
|
267274
|
+
}
|
|
266926
267275
|
} catch {
|
|
266927
267276
|
}
|
|
266928
267277
|
}
|
|
@@ -267785,6 +268134,21 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
267785
268134
|
if (pruned > 0) {
|
|
267786
268135
|
this.emit({ type: "status", content: `Pruned ${pruned} expired session episodes`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
267787
268136
|
}
|
|
268137
|
+
if (this._pendingEmbeddings.length > 0) {
|
|
268138
|
+
await this.processPendingEmbeddings();
|
|
268139
|
+
}
|
|
268140
|
+
this.stopEmbeddingPipeline();
|
|
268141
|
+
if (this._temporalGraph) {
|
|
268142
|
+
const nodes = this._temporalGraph.nodeCount();
|
|
268143
|
+
const edges = this._temporalGraph.activeEdgeCount();
|
|
268144
|
+
if (nodes > 0) {
|
|
268145
|
+
this.emit({ type: "status", content: `Knowledge graph: ${nodes} nodes, ${edges} active edges`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
268146
|
+
}
|
|
268147
|
+
}
|
|
268148
|
+
const epCount = this._episodeStore.count(this._sessionId);
|
|
268149
|
+
if (epCount > 0) {
|
|
268150
|
+
this.emit({ type: "status", content: `Episodes captured: ${epCount} this session`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
268151
|
+
}
|
|
267788
268152
|
} catch {
|
|
267789
268153
|
}
|
|
267790
268154
|
}
|
|
@@ -267940,11 +268304,11 @@ ${errOutput}`;
|
|
|
267940
268304
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
267941
268305
|
});
|
|
267942
268306
|
try {
|
|
267943
|
-
const { mkdirSync:
|
|
267944
|
-
const { join:
|
|
267945
|
-
const resultsDir =
|
|
267946
|
-
|
|
267947
|
-
writeFileSync41(
|
|
268307
|
+
const { mkdirSync: mkdirSync46, writeFileSync: writeFileSync41 } = __require("node:fs");
|
|
268308
|
+
const { join: join97 } = __require("node:path");
|
|
268309
|
+
const resultsDir = join97(process.cwd(), ".oa", "tool-results");
|
|
268310
|
+
mkdirSync46(resultsDir, { recursive: true });
|
|
268311
|
+
writeFileSync41(join97(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
|
|
267948
268312
|
# Turn: ${turn}
|
|
267949
268313
|
# Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
267950
268314
|
# Size: ${result.output.length} chars, ${lineCount} lines
|
|
@@ -268083,10 +268447,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
268083
268447
|
if (!this._workingDirectory)
|
|
268084
268448
|
return;
|
|
268085
268449
|
try {
|
|
268086
|
-
const { mkdirSync:
|
|
268087
|
-
const { join:
|
|
268088
|
-
const sessionDir =
|
|
268089
|
-
|
|
268450
|
+
const { mkdirSync: mkdirSync46, writeFileSync: writeFileSync41 } = __require("node:fs");
|
|
268451
|
+
const { join: join97 } = __require("node:path");
|
|
268452
|
+
const sessionDir = join97(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
268453
|
+
mkdirSync46(sessionDir, { recursive: true });
|
|
268090
268454
|
const checkpoint = {
|
|
268091
268455
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
268092
268456
|
sessionId: this._sessionId,
|
|
@@ -268098,7 +268462,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
268098
268462
|
memexEntryCount: this._memexArchive.size,
|
|
268099
268463
|
fileRegistrySize: this._fileRegistry.size
|
|
268100
268464
|
};
|
|
268101
|
-
writeFileSync41(
|
|
268465
|
+
writeFileSync41(join97(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
268102
268466
|
} catch {
|
|
268103
268467
|
}
|
|
268104
268468
|
}
|
|
@@ -269520,10 +269884,10 @@ ${result}`
|
|
|
269520
269884
|
try {
|
|
269521
269885
|
const { execSync: execSync54 } = await import("node:child_process");
|
|
269522
269886
|
const { writeFileSync: writeFileSync41, readFileSync: readFileSync60, unlinkSync: unlinkSync18 } = await import("node:fs");
|
|
269523
|
-
const { join:
|
|
269887
|
+
const { join: join97 } = await import("node:path");
|
|
269524
269888
|
const { tmpdir: tmpdir18 } = await import("node:os");
|
|
269525
|
-
const tmpIn =
|
|
269526
|
-
const tmpOut =
|
|
269889
|
+
const tmpIn = join97(tmpdir18(), `oa_img_in_${Date.now()}.png`);
|
|
269890
|
+
const tmpOut = join97(tmpdir18(), `oa_img_out_${Date.now()}.jpg`);
|
|
269527
269891
|
writeFileSync41(tmpIn, buffer2);
|
|
269528
269892
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
269529
269893
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
@@ -270172,9 +270536,9 @@ var init_constraint_learner = __esm({
|
|
|
270172
270536
|
});
|
|
270173
270537
|
|
|
270174
270538
|
// packages/orchestrator/dist/nexusBackend.js
|
|
270175
|
-
import { existsSync as
|
|
270539
|
+
import { existsSync as existsSync47, statSync as statSync14, openSync, readSync, closeSync, unlinkSync as unlinkSync9, writeFileSync as writeFileSync19 } from "node:fs";
|
|
270176
270540
|
import { watch as fsWatch } from "node:fs";
|
|
270177
|
-
import { join as
|
|
270541
|
+
import { join as join62 } from "node:path";
|
|
270178
270542
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
270179
270543
|
import { randomBytes as randomBytes14 } from "node:crypto";
|
|
270180
270544
|
var NexusAgenticBackend;
|
|
@@ -270324,7 +270688,7 @@ var init_nexusBackend = __esm({
|
|
|
270324
270688
|
* Falls back to unary + word-split if streaming setup fails.
|
|
270325
270689
|
*/
|
|
270326
270690
|
async *chatCompletionStream(request) {
|
|
270327
|
-
const streamFile =
|
|
270691
|
+
const streamFile = join62(tmpdir14(), `nexus-stream-${randomBytes14(6).toString("hex")}.jsonl`);
|
|
270328
270692
|
writeFileSync19(streamFile, "", "utf8");
|
|
270329
270693
|
const daemonArgs = {
|
|
270330
270694
|
model: this.model,
|
|
@@ -271971,8 +272335,8 @@ __export(listen_exports, {
|
|
|
271971
272335
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
271972
272336
|
});
|
|
271973
272337
|
import { spawn as spawn17, execSync as execSync42 } from "node:child_process";
|
|
271974
|
-
import { existsSync as
|
|
271975
|
-
import { join as
|
|
272338
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readdirSync as readdirSync9 } from "node:fs";
|
|
272339
|
+
import { join as join63, dirname as dirname16 } from "node:path";
|
|
271976
272340
|
import { homedir as homedir18 } from "node:os";
|
|
271977
272341
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
271978
272342
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
@@ -272058,15 +272422,15 @@ function findMicCaptureCommand() {
|
|
|
272058
272422
|
function findLiveWhisperScript() {
|
|
272059
272423
|
const thisDir = dirname16(fileURLToPath9(import.meta.url));
|
|
272060
272424
|
const candidates = [
|
|
272061
|
-
|
|
272062
|
-
|
|
272063
|
-
|
|
272425
|
+
join63(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
272426
|
+
join63(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
272427
|
+
join63(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
272064
272428
|
// npm install layout — scripts bundled alongside dist
|
|
272065
|
-
|
|
272066
|
-
|
|
272429
|
+
join63(thisDir, "../scripts/live-whisper.py"),
|
|
272430
|
+
join63(thisDir, "../../scripts/live-whisper.py")
|
|
272067
272431
|
];
|
|
272068
272432
|
for (const p2 of candidates) {
|
|
272069
|
-
if (
|
|
272433
|
+
if (existsSync48(p2)) return p2;
|
|
272070
272434
|
}
|
|
272071
272435
|
try {
|
|
272072
272436
|
const globalRoot = execSync42("npm root -g", {
|
|
@@ -272075,20 +272439,20 @@ function findLiveWhisperScript() {
|
|
|
272075
272439
|
stdio: ["pipe", "pipe", "pipe"]
|
|
272076
272440
|
}).trim();
|
|
272077
272441
|
const candidates2 = [
|
|
272078
|
-
|
|
272079
|
-
|
|
272442
|
+
join63(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
272443
|
+
join63(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
272080
272444
|
];
|
|
272081
272445
|
for (const p2 of candidates2) {
|
|
272082
|
-
if (
|
|
272446
|
+
if (existsSync48(p2)) return p2;
|
|
272083
272447
|
}
|
|
272084
272448
|
} catch {
|
|
272085
272449
|
}
|
|
272086
|
-
const nvmBase =
|
|
272087
|
-
if (
|
|
272450
|
+
const nvmBase = join63(homedir18(), ".nvm", "versions", "node");
|
|
272451
|
+
if (existsSync48(nvmBase)) {
|
|
272088
272452
|
try {
|
|
272089
272453
|
for (const ver of readdirSync9(nvmBase)) {
|
|
272090
|
-
const p2 =
|
|
272091
|
-
if (
|
|
272454
|
+
const p2 = join63(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
272455
|
+
if (existsSync48(p2)) return p2;
|
|
272092
272456
|
}
|
|
272093
272457
|
} catch {
|
|
272094
272458
|
}
|
|
@@ -272104,7 +272468,7 @@ function ensureTranscribeCliBackground() {
|
|
|
272104
272468
|
timeout: 5e3,
|
|
272105
272469
|
stdio: ["pipe", "pipe", "pipe"]
|
|
272106
272470
|
}).trim();
|
|
272107
|
-
if (
|
|
272471
|
+
if (existsSync48(join63(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
272108
272472
|
return true;
|
|
272109
272473
|
}
|
|
272110
272474
|
} catch {
|
|
@@ -272323,24 +272687,24 @@ var init_listen = __esm({
|
|
|
272323
272687
|
timeout: 5e3,
|
|
272324
272688
|
stdio: ["pipe", "pipe", "pipe"]
|
|
272325
272689
|
}).trim();
|
|
272326
|
-
const tcPath =
|
|
272327
|
-
if (
|
|
272690
|
+
const tcPath = join63(globalRoot, "transcribe-cli");
|
|
272691
|
+
if (existsSync48(join63(tcPath, "dist", "index.js"))) {
|
|
272328
272692
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
272329
272693
|
const req2 = createRequire7(import.meta.url);
|
|
272330
|
-
return req2(
|
|
272694
|
+
return req2(join63(tcPath, "dist", "index.js"));
|
|
272331
272695
|
}
|
|
272332
272696
|
} catch {
|
|
272333
272697
|
}
|
|
272334
|
-
const nvmBase =
|
|
272335
|
-
if (
|
|
272698
|
+
const nvmBase = join63(homedir18(), ".nvm", "versions", "node");
|
|
272699
|
+
if (existsSync48(nvmBase)) {
|
|
272336
272700
|
try {
|
|
272337
272701
|
const { readdirSync: readdirSync26 } = await import("node:fs");
|
|
272338
272702
|
for (const ver of readdirSync26(nvmBase)) {
|
|
272339
|
-
const tcPath =
|
|
272340
|
-
if (
|
|
272703
|
+
const tcPath = join63(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
272704
|
+
if (existsSync48(join63(tcPath, "dist", "index.js"))) {
|
|
272341
272705
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
272342
272706
|
const req2 = createRequire7(import.meta.url);
|
|
272343
|
-
return req2(
|
|
272707
|
+
return req2(join63(tcPath, "dist", "index.js"));
|
|
272344
272708
|
}
|
|
272345
272709
|
}
|
|
272346
272710
|
} catch {
|
|
@@ -272614,9 +272978,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
272614
272978
|
});
|
|
272615
272979
|
if (outputDir) {
|
|
272616
272980
|
const { basename: basename19 } = await import("node:path");
|
|
272617
|
-
const transcriptDir =
|
|
272618
|
-
|
|
272619
|
-
const outFile =
|
|
272981
|
+
const transcriptDir = join63(outputDir, ".oa", "transcripts");
|
|
272982
|
+
mkdirSync22(transcriptDir, { recursive: true });
|
|
272983
|
+
const outFile = join63(transcriptDir, `${basename19(filePath)}.txt`);
|
|
272620
272984
|
writeFileSync20(outFile, result.text, "utf-8");
|
|
272621
272985
|
}
|
|
272622
272986
|
return {
|
|
@@ -278643,8 +279007,8 @@ import { EventEmitter as EventEmitter5 } from "node:events";
|
|
|
278643
279007
|
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
278644
279008
|
import { URL as URL2 } from "node:url";
|
|
278645
279009
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
278646
|
-
import { existsSync as
|
|
278647
|
-
import { join as
|
|
279010
|
+
import { existsSync as existsSync49, readFileSync as readFileSync35, writeFileSync as writeFileSync21, unlinkSync as unlinkSync10, mkdirSync as mkdirSync23, readdirSync as readdirSync10, statSync as statSync15 } from "node:fs";
|
|
279011
|
+
import { join as join64 } from "node:path";
|
|
278648
279012
|
function cleanForwardHeaders(raw, targetHost) {
|
|
278649
279013
|
const out = {};
|
|
278650
279014
|
for (const [key, value2] of Object.entries(raw)) {
|
|
@@ -278665,8 +279029,8 @@ function fmtTokens(n2) {
|
|
|
278665
279029
|
}
|
|
278666
279030
|
function readExposeState(stateDir) {
|
|
278667
279031
|
try {
|
|
278668
|
-
const path5 =
|
|
278669
|
-
if (!
|
|
279032
|
+
const path5 = join64(stateDir, STATE_FILE_NAME);
|
|
279033
|
+
if (!existsSync49(path5)) return null;
|
|
278670
279034
|
const raw = readFileSync35(path5, "utf8");
|
|
278671
279035
|
const data = JSON.parse(raw);
|
|
278672
279036
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort) return null;
|
|
@@ -278677,14 +279041,14 @@ function readExposeState(stateDir) {
|
|
|
278677
279041
|
}
|
|
278678
279042
|
function writeExposeState(stateDir, state) {
|
|
278679
279043
|
try {
|
|
278680
|
-
|
|
278681
|
-
writeFileSync21(
|
|
279044
|
+
mkdirSync23(stateDir, { recursive: true });
|
|
279045
|
+
writeFileSync21(join64(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
278682
279046
|
} catch {
|
|
278683
279047
|
}
|
|
278684
279048
|
}
|
|
278685
279049
|
function removeExposeState(stateDir) {
|
|
278686
279050
|
try {
|
|
278687
|
-
unlinkSync10(
|
|
279051
|
+
unlinkSync10(join64(stateDir, STATE_FILE_NAME));
|
|
278688
279052
|
} catch {
|
|
278689
279053
|
}
|
|
278690
279054
|
}
|
|
@@ -278781,8 +279145,8 @@ async function collectSystemMetricsAsync() {
|
|
|
278781
279145
|
}
|
|
278782
279146
|
function readP2PExposeState(stateDir) {
|
|
278783
279147
|
try {
|
|
278784
|
-
const path5 =
|
|
278785
|
-
if (!
|
|
279148
|
+
const path5 = join64(stateDir, P2P_STATE_FILE_NAME);
|
|
279149
|
+
if (!existsSync49(path5)) return null;
|
|
278786
279150
|
const raw = readFileSync35(path5, "utf8");
|
|
278787
279151
|
const data = JSON.parse(raw);
|
|
278788
279152
|
if (!data.peerId || !data.authKey) return null;
|
|
@@ -278793,14 +279157,14 @@ function readP2PExposeState(stateDir) {
|
|
|
278793
279157
|
}
|
|
278794
279158
|
function writeP2PExposeState(stateDir, state) {
|
|
278795
279159
|
try {
|
|
278796
|
-
|
|
278797
|
-
writeFileSync21(
|
|
279160
|
+
mkdirSync23(stateDir, { recursive: true });
|
|
279161
|
+
writeFileSync21(join64(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
278798
279162
|
} catch {
|
|
278799
279163
|
}
|
|
278800
279164
|
}
|
|
278801
279165
|
function removeP2PExposeState(stateDir) {
|
|
278802
279166
|
try {
|
|
278803
|
-
unlinkSync10(
|
|
279167
|
+
unlinkSync10(join64(stateDir, P2P_STATE_FILE_NAME));
|
|
278804
279168
|
} catch {
|
|
278805
279169
|
}
|
|
278806
279170
|
}
|
|
@@ -279790,7 +280154,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
279790
280154
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
279791
280155
|
}
|
|
279792
280156
|
const nexusDir = this._nexusTool.getNexusDir();
|
|
279793
|
-
const statusPath =
|
|
280157
|
+
const statusPath = join64(nexusDir, "status.json");
|
|
279794
280158
|
for (let i2 = 0; i2 < 80; i2++) {
|
|
279795
280159
|
try {
|
|
279796
280160
|
const raw = readFileSync35(statusPath, "utf8");
|
|
@@ -279824,8 +280188,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
279824
280188
|
});
|
|
279825
280189
|
}
|
|
279826
280190
|
try {
|
|
279827
|
-
const invocDir =
|
|
279828
|
-
if (
|
|
280191
|
+
const invocDir = join64(nexusDir, "invocations");
|
|
280192
|
+
if (existsSync49(invocDir)) {
|
|
279829
280193
|
this._prevInvocCount = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json")).length;
|
|
279830
280194
|
this._stats.totalRequests = this._prevInvocCount;
|
|
279831
280195
|
}
|
|
@@ -279852,9 +280216,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
279852
280216
|
const state = readP2PExposeState(stateDir);
|
|
279853
280217
|
if (!state) return null;
|
|
279854
280218
|
const nexusDir = nexusTool.getNexusDir();
|
|
279855
|
-
const statusPath =
|
|
280219
|
+
const statusPath = join64(nexusDir, "status.json");
|
|
279856
280220
|
try {
|
|
279857
|
-
if (!
|
|
280221
|
+
if (!existsSync49(statusPath)) {
|
|
279858
280222
|
removeP2PExposeState(stateDir);
|
|
279859
280223
|
return null;
|
|
279860
280224
|
}
|
|
@@ -279911,8 +280275,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
279911
280275
|
let lastMeteringLineCount = 0;
|
|
279912
280276
|
this._activityPollTimer = setInterval(() => {
|
|
279913
280277
|
try {
|
|
279914
|
-
const invocDir =
|
|
279915
|
-
if (!
|
|
280278
|
+
const invocDir = join64(nexusDir, "invocations");
|
|
280279
|
+
if (!existsSync49(invocDir)) return;
|
|
279916
280280
|
const files = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json"));
|
|
279917
280281
|
const invocCount = files.length;
|
|
279918
280282
|
const newRequests = invocCount - this._prevInvocCount;
|
|
@@ -279926,15 +280290,15 @@ ${this.formatConnectionInfo()}`);
|
|
|
279926
280290
|
let recentActive = 0;
|
|
279927
280291
|
for (const f2 of files.slice(-10)) {
|
|
279928
280292
|
try {
|
|
279929
|
-
const st = statSync15(
|
|
280293
|
+
const st = statSync15(join64(invocDir, f2));
|
|
279930
280294
|
if (now - st.mtimeMs < 1e4) recentActive++;
|
|
279931
280295
|
} catch {
|
|
279932
280296
|
}
|
|
279933
280297
|
}
|
|
279934
|
-
const meteringFile =
|
|
280298
|
+
const meteringFile = join64(nexusDir, "metering.jsonl");
|
|
279935
280299
|
let meteringLines = lastMeteringLineCount;
|
|
279936
280300
|
try {
|
|
279937
|
-
if (
|
|
280301
|
+
if (existsSync49(meteringFile)) {
|
|
279938
280302
|
const content = readFileSync35(meteringFile, "utf8");
|
|
279939
280303
|
meteringLines = content.split("\n").filter((l2) => l2.trim()).length;
|
|
279940
280304
|
}
|
|
@@ -279960,8 +280324,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
279960
280324
|
this._activityPollTimer.unref();
|
|
279961
280325
|
this._pollTimer = setInterval(() => {
|
|
279962
280326
|
try {
|
|
279963
|
-
const statusPath =
|
|
279964
|
-
if (
|
|
280327
|
+
const statusPath = join64(nexusDir, "status.json");
|
|
280328
|
+
if (existsSync49(statusPath)) {
|
|
279965
280329
|
const status = JSON.parse(readFileSync35(statusPath, "utf8"));
|
|
279966
280330
|
if (status.peerId && !this._peerId) {
|
|
279967
280331
|
this._peerId = status.peerId;
|
|
@@ -279971,8 +280335,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
279971
280335
|
} catch {
|
|
279972
280336
|
}
|
|
279973
280337
|
try {
|
|
279974
|
-
const invocDir =
|
|
279975
|
-
if (
|
|
280338
|
+
const invocDir = join64(nexusDir, "invocations");
|
|
280339
|
+
if (existsSync49(invocDir)) {
|
|
279976
280340
|
const files = readdirSync10(invocDir);
|
|
279977
280341
|
const invocCount = files.filter((f2) => f2.endsWith(".json")).length;
|
|
279978
280342
|
if (invocCount > this._stats.totalRequests) {
|
|
@@ -279983,8 +280347,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
279983
280347
|
} catch {
|
|
279984
280348
|
}
|
|
279985
280349
|
try {
|
|
279986
|
-
const meteringFile =
|
|
279987
|
-
if (
|
|
280350
|
+
const meteringFile = join64(nexusDir, "metering.jsonl");
|
|
280351
|
+
if (existsSync49(meteringFile)) {
|
|
279988
280352
|
const content = readFileSync35(meteringFile, "utf8");
|
|
279989
280353
|
if (content.length > lastMeteringSize) {
|
|
279990
280354
|
const newContent = content.slice(lastMeteringSize);
|
|
@@ -280196,7 +280560,7 @@ var init_types = __esm({
|
|
|
280196
280560
|
|
|
280197
280561
|
// packages/cli/src/tui/p2p/secret-vault.ts
|
|
280198
280562
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes16, scryptSync as scryptSync2, createHash as createHash4 } from "node:crypto";
|
|
280199
|
-
import { readFileSync as readFileSync36, writeFileSync as writeFileSync22, existsSync as
|
|
280563
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync22, existsSync as existsSync50, mkdirSync as mkdirSync24 } from "node:fs";
|
|
280200
280564
|
import { dirname as dirname17 } from "node:path";
|
|
280201
280565
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
280202
280566
|
var init_secret_vault = __esm({
|
|
@@ -280404,7 +280768,7 @@ var init_secret_vault = __esm({
|
|
|
280404
280768
|
const tag = cipher.getAuthTag();
|
|
280405
280769
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
280406
280770
|
const dir = dirname17(this.storePath);
|
|
280407
|
-
if (!
|
|
280771
|
+
if (!existsSync50(dir)) mkdirSync24(dir, { recursive: true });
|
|
280408
280772
|
writeFileSync22(this.storePath, blob, { mode: 384 });
|
|
280409
280773
|
}
|
|
280410
280774
|
/**
|
|
@@ -280412,7 +280776,7 @@ var init_secret_vault = __esm({
|
|
|
280412
280776
|
* Returns the number of secrets loaded.
|
|
280413
280777
|
*/
|
|
280414
280778
|
load(passphrase) {
|
|
280415
|
-
if (!this.storePath || !
|
|
280779
|
+
if (!this.storePath || !existsSync50(this.storePath)) return 0;
|
|
280416
280780
|
const blob = readFileSync36(this.storePath);
|
|
280417
280781
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
280418
280782
|
throw new Error("Vault file is corrupted (too small)");
|
|
@@ -281566,23 +281930,23 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
281566
281930
|
async function fetchPeerModels(peerId, authKey) {
|
|
281567
281931
|
try {
|
|
281568
281932
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
|
|
281569
|
-
const { existsSync:
|
|
281570
|
-
const { join:
|
|
281933
|
+
const { existsSync: existsSync78, readFileSync: readFileSync60 } = await import("node:fs");
|
|
281934
|
+
const { join: join97 } = await import("node:path");
|
|
281571
281935
|
const cwd4 = process.cwd();
|
|
281572
281936
|
const nexusTool = new NexusTool2(cwd4);
|
|
281573
281937
|
const nexusDir = nexusTool.getNexusDir();
|
|
281574
281938
|
let isLocalPeer = false;
|
|
281575
281939
|
try {
|
|
281576
|
-
const statusPath =
|
|
281577
|
-
if (
|
|
281940
|
+
const statusPath = join97(nexusDir, "status.json");
|
|
281941
|
+
if (existsSync78(statusPath)) {
|
|
281578
281942
|
const status = JSON.parse(readFileSync60(statusPath, "utf8"));
|
|
281579
281943
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
281580
281944
|
}
|
|
281581
281945
|
} catch {
|
|
281582
281946
|
}
|
|
281583
281947
|
if (isLocalPeer) {
|
|
281584
|
-
const pricingPath =
|
|
281585
|
-
if (
|
|
281948
|
+
const pricingPath = join97(nexusDir, "pricing.json");
|
|
281949
|
+
if (existsSync78(pricingPath)) {
|
|
281586
281950
|
try {
|
|
281587
281951
|
const pricing = JSON.parse(readFileSync60(pricingPath, "utf8"));
|
|
281588
281952
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
@@ -281597,8 +281961,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
281597
281961
|
}
|
|
281598
281962
|
}
|
|
281599
281963
|
}
|
|
281600
|
-
const cachePath =
|
|
281601
|
-
if (
|
|
281964
|
+
const cachePath = join97(nexusDir, "peer-models-cache.json");
|
|
281965
|
+
if (existsSync78(cachePath)) {
|
|
281602
281966
|
try {
|
|
281603
281967
|
const cache7 = JSON.parse(readFileSync60(cachePath, "utf8"));
|
|
281604
281968
|
if (cache7.peerId === peerId && cache7.models?.length > 0) {
|
|
@@ -281712,8 +282076,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
281712
282076
|
} catch {
|
|
281713
282077
|
}
|
|
281714
282078
|
if (isLocalPeer) {
|
|
281715
|
-
const pricingPath =
|
|
281716
|
-
if (
|
|
282079
|
+
const pricingPath = join97(nexusDir, "pricing.json");
|
|
282080
|
+
if (existsSync78(pricingPath)) {
|
|
281717
282081
|
try {
|
|
281718
282082
|
const pricing = JSON.parse(readFileSync60(pricingPath, "utf8"));
|
|
281719
282083
|
return (pricing.models || []).map((m2) => ({
|
|
@@ -281971,14 +282335,14 @@ var init_render2 = __esm({
|
|
|
281971
282335
|
});
|
|
281972
282336
|
|
|
281973
282337
|
// packages/prompts/dist/promptLoader.js
|
|
281974
|
-
import { readFileSync as readFileSync37, existsSync as
|
|
281975
|
-
import { join as
|
|
282338
|
+
import { readFileSync as readFileSync37, existsSync as existsSync51 } from "node:fs";
|
|
282339
|
+
import { join as join66, dirname as dirname18 } from "node:path";
|
|
281976
282340
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
281977
282341
|
function loadPrompt2(promptPath, vars) {
|
|
281978
282342
|
let content = cache5.get(promptPath);
|
|
281979
282343
|
if (content === void 0) {
|
|
281980
|
-
const fullPath =
|
|
281981
|
-
if (!
|
|
282344
|
+
const fullPath = join66(PROMPTS_DIR2, promptPath);
|
|
282345
|
+
if (!existsSync51(fullPath)) {
|
|
281982
282346
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
281983
282347
|
}
|
|
281984
282348
|
content = readFileSync37(fullPath, "utf-8");
|
|
@@ -281994,9 +282358,9 @@ var init_promptLoader2 = __esm({
|
|
|
281994
282358
|
"use strict";
|
|
281995
282359
|
__filename4 = fileURLToPath10(import.meta.url);
|
|
281996
282360
|
__dirname6 = dirname18(__filename4);
|
|
281997
|
-
devPath =
|
|
281998
|
-
publishedPath =
|
|
281999
|
-
PROMPTS_DIR2 =
|
|
282361
|
+
devPath = join66(__dirname6, "..", "templates");
|
|
282362
|
+
publishedPath = join66(__dirname6, "..", "prompts", "templates");
|
|
282363
|
+
PROMPTS_DIR2 = existsSync51(devPath) ? devPath : publishedPath;
|
|
282000
282364
|
cache5 = /* @__PURE__ */ new Map();
|
|
282001
282365
|
}
|
|
282002
282366
|
});
|
|
@@ -282107,7 +282471,7 @@ var init_task_templates = __esm({
|
|
|
282107
282471
|
});
|
|
282108
282472
|
|
|
282109
282473
|
// packages/prompts/dist/index.js
|
|
282110
|
-
import { join as
|
|
282474
|
+
import { join as join67, dirname as dirname19 } from "node:path";
|
|
282111
282475
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
282112
282476
|
var _dir, _packageRoot;
|
|
282113
282477
|
var init_dist9 = __esm({
|
|
@@ -282118,7 +282482,7 @@ var init_dist9 = __esm({
|
|
|
282118
282482
|
init_task_templates();
|
|
282119
282483
|
init_render2();
|
|
282120
282484
|
_dir = dirname19(fileURLToPath11(import.meta.url));
|
|
282121
|
-
_packageRoot =
|
|
282485
|
+
_packageRoot = join67(_dir, "..");
|
|
282122
282486
|
}
|
|
282123
282487
|
});
|
|
282124
282488
|
|
|
@@ -282155,18 +282519,18 @@ __export(oa_directory_exports, {
|
|
|
282155
282519
|
writeIndexData: () => writeIndexData,
|
|
282156
282520
|
writeIndexMeta: () => writeIndexMeta
|
|
282157
282521
|
});
|
|
282158
|
-
import { existsSync as
|
|
282159
|
-
import { join as
|
|
282522
|
+
import { existsSync as existsSync52, mkdirSync as mkdirSync25, readFileSync as readFileSync38, writeFileSync as writeFileSync23, readdirSync as readdirSync11, statSync as statSync16, unlinkSync as unlinkSync11 } from "node:fs";
|
|
282523
|
+
import { join as join68, relative as relative4, basename as basename12 } from "node:path";
|
|
282160
282524
|
import { homedir as homedir19 } from "node:os";
|
|
282161
282525
|
function initOaDirectory(repoRoot) {
|
|
282162
|
-
const oaPath =
|
|
282526
|
+
const oaPath = join68(repoRoot, OA_DIR);
|
|
282163
282527
|
for (const sub of SUBDIRS) {
|
|
282164
|
-
|
|
282528
|
+
mkdirSync25(join68(oaPath, sub), { recursive: true });
|
|
282165
282529
|
}
|
|
282166
282530
|
try {
|
|
282167
|
-
const gitignorePath =
|
|
282531
|
+
const gitignorePath = join68(repoRoot, ".gitignore");
|
|
282168
282532
|
const settingsPattern = ".oa/settings.json";
|
|
282169
|
-
if (
|
|
282533
|
+
if (existsSync52(gitignorePath)) {
|
|
282170
282534
|
const content = readFileSync38(gitignorePath, "utf-8");
|
|
282171
282535
|
if (!content.includes(settingsPattern)) {
|
|
282172
282536
|
writeFileSync23(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
@@ -282177,12 +282541,12 @@ function initOaDirectory(repoRoot) {
|
|
|
282177
282541
|
return oaPath;
|
|
282178
282542
|
}
|
|
282179
282543
|
function hasOaDirectory(repoRoot) {
|
|
282180
|
-
return
|
|
282544
|
+
return existsSync52(join68(repoRoot, OA_DIR, "index"));
|
|
282181
282545
|
}
|
|
282182
282546
|
function loadProjectSettings(repoRoot) {
|
|
282183
|
-
const settingsPath =
|
|
282547
|
+
const settingsPath = join68(repoRoot, OA_DIR, "settings.json");
|
|
282184
282548
|
try {
|
|
282185
|
-
if (
|
|
282549
|
+
if (existsSync52(settingsPath)) {
|
|
282186
282550
|
return JSON.parse(readFileSync38(settingsPath, "utf-8"));
|
|
282187
282551
|
}
|
|
282188
282552
|
} catch {
|
|
@@ -282190,16 +282554,16 @@ function loadProjectSettings(repoRoot) {
|
|
|
282190
282554
|
return {};
|
|
282191
282555
|
}
|
|
282192
282556
|
function saveProjectSettings(repoRoot, settings) {
|
|
282193
|
-
const oaPath =
|
|
282194
|
-
|
|
282557
|
+
const oaPath = join68(repoRoot, OA_DIR);
|
|
282558
|
+
mkdirSync25(oaPath, { recursive: true });
|
|
282195
282559
|
const existing = loadProjectSettings(repoRoot);
|
|
282196
282560
|
const merged = { ...existing, ...settings };
|
|
282197
|
-
writeFileSync23(
|
|
282561
|
+
writeFileSync23(join68(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
282198
282562
|
}
|
|
282199
282563
|
function loadGlobalSettings() {
|
|
282200
|
-
const settingsPath =
|
|
282564
|
+
const settingsPath = join68(homedir19(), ".open-agents", "settings.json");
|
|
282201
282565
|
try {
|
|
282202
|
-
if (
|
|
282566
|
+
if (existsSync52(settingsPath)) {
|
|
282203
282567
|
return JSON.parse(readFileSync38(settingsPath, "utf-8"));
|
|
282204
282568
|
}
|
|
282205
282569
|
} catch {
|
|
@@ -282207,11 +282571,11 @@ function loadGlobalSettings() {
|
|
|
282207
282571
|
return {};
|
|
282208
282572
|
}
|
|
282209
282573
|
function saveGlobalSettings(settings) {
|
|
282210
|
-
const dir =
|
|
282211
|
-
|
|
282574
|
+
const dir = join68(homedir19(), ".open-agents");
|
|
282575
|
+
mkdirSync25(dir, { recursive: true });
|
|
282212
282576
|
const existing = loadGlobalSettings();
|
|
282213
282577
|
const merged = { ...existing, ...settings };
|
|
282214
|
-
writeFileSync23(
|
|
282578
|
+
writeFileSync23(join68(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
282215
282579
|
}
|
|
282216
282580
|
function resolveSettings(repoRoot) {
|
|
282217
282581
|
const global2 = loadGlobalSettings();
|
|
@@ -282226,9 +282590,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
282226
282590
|
while (dir && !visited.has(dir)) {
|
|
282227
282591
|
visited.add(dir);
|
|
282228
282592
|
for (const name10 of CONTEXT_FILES) {
|
|
282229
|
-
const filePath =
|
|
282593
|
+
const filePath = join68(dir, name10);
|
|
282230
282594
|
const normalizedName = name10.toLowerCase();
|
|
282231
|
-
if (
|
|
282595
|
+
if (existsSync52(filePath) && !seen.has(filePath)) {
|
|
282232
282596
|
seen.add(filePath);
|
|
282233
282597
|
try {
|
|
282234
282598
|
let content = readFileSync38(filePath, "utf-8");
|
|
@@ -282245,8 +282609,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
282245
282609
|
}
|
|
282246
282610
|
}
|
|
282247
282611
|
}
|
|
282248
|
-
const projectMap =
|
|
282249
|
-
if (
|
|
282612
|
+
const projectMap = join68(dir, OA_DIR, "context", "project-map.md");
|
|
282613
|
+
if (existsSync52(projectMap) && !seen.has(projectMap)) {
|
|
282250
282614
|
seen.add(projectMap);
|
|
282251
282615
|
try {
|
|
282252
282616
|
let content = readFileSync38(projectMap, "utf-8");
|
|
@@ -282261,7 +282625,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
282261
282625
|
} catch {
|
|
282262
282626
|
}
|
|
282263
282627
|
}
|
|
282264
|
-
const parent =
|
|
282628
|
+
const parent = join68(dir, "..");
|
|
282265
282629
|
if (parent === dir) break;
|
|
282266
282630
|
dir = parent;
|
|
282267
282631
|
}
|
|
@@ -282278,7 +282642,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
282278
282642
|
return found;
|
|
282279
282643
|
}
|
|
282280
282644
|
function readIndexMeta(repoRoot) {
|
|
282281
|
-
const metaPath =
|
|
282645
|
+
const metaPath = join68(repoRoot, OA_DIR, "index", "meta.json");
|
|
282282
282646
|
try {
|
|
282283
282647
|
return JSON.parse(readFileSync38(metaPath, "utf-8"));
|
|
282284
282648
|
} catch {
|
|
@@ -282286,12 +282650,12 @@ function readIndexMeta(repoRoot) {
|
|
|
282286
282650
|
}
|
|
282287
282651
|
}
|
|
282288
282652
|
function writeIndexMeta(repoRoot, meta) {
|
|
282289
|
-
const metaPath =
|
|
282290
|
-
|
|
282653
|
+
const metaPath = join68(repoRoot, OA_DIR, "index", "meta.json");
|
|
282654
|
+
mkdirSync25(join68(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
282291
282655
|
writeFileSync23(metaPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
282292
282656
|
}
|
|
282293
282657
|
function readIndexData(repoRoot, filename) {
|
|
282294
|
-
const filePath =
|
|
282658
|
+
const filePath = join68(repoRoot, OA_DIR, "index", filename);
|
|
282295
282659
|
try {
|
|
282296
282660
|
return JSON.parse(readFileSync38(filePath, "utf-8"));
|
|
282297
282661
|
} catch {
|
|
@@ -282299,8 +282663,8 @@ function readIndexData(repoRoot, filename) {
|
|
|
282299
282663
|
}
|
|
282300
282664
|
}
|
|
282301
282665
|
function writeIndexData(repoRoot, filename, data) {
|
|
282302
|
-
const filePath =
|
|
282303
|
-
|
|
282666
|
+
const filePath = join68(repoRoot, OA_DIR, "index", filename);
|
|
282667
|
+
mkdirSync25(join68(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
282304
282668
|
writeFileSync23(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
282305
282669
|
}
|
|
282306
282670
|
function generateProjectMap(repoRoot) {
|
|
@@ -282348,31 +282712,31 @@ ${tree2}\`\`\`
|
|
|
282348
282712
|
sections.push("");
|
|
282349
282713
|
}
|
|
282350
282714
|
const content = sections.join("\n");
|
|
282351
|
-
const contextDir =
|
|
282352
|
-
|
|
282353
|
-
writeFileSync23(
|
|
282715
|
+
const contextDir = join68(repoRoot, OA_DIR, "context");
|
|
282716
|
+
mkdirSync25(contextDir, { recursive: true });
|
|
282717
|
+
writeFileSync23(join68(contextDir, "project-map.md"), content, "utf-8");
|
|
282354
282718
|
return content;
|
|
282355
282719
|
}
|
|
282356
282720
|
function saveSession(repoRoot, session) {
|
|
282357
|
-
const historyDir =
|
|
282358
|
-
|
|
282721
|
+
const historyDir = join68(repoRoot, OA_DIR, "history");
|
|
282722
|
+
mkdirSync25(historyDir, { recursive: true });
|
|
282359
282723
|
writeFileSync23(
|
|
282360
|
-
|
|
282724
|
+
join68(historyDir, `${session.id}.json`),
|
|
282361
282725
|
JSON.stringify(session, null, 2),
|
|
282362
282726
|
"utf-8"
|
|
282363
282727
|
);
|
|
282364
282728
|
}
|
|
282365
282729
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
282366
|
-
const historyDir =
|
|
282367
|
-
if (!
|
|
282730
|
+
const historyDir = join68(repoRoot, OA_DIR, "history");
|
|
282731
|
+
if (!existsSync52(historyDir)) return [];
|
|
282368
282732
|
try {
|
|
282369
282733
|
const files = readdirSync11(historyDir).filter((f2) => f2.endsWith(".json") && f2 !== "pending-task.json").map((f2) => {
|
|
282370
|
-
const stat6 = statSync16(
|
|
282734
|
+
const stat6 = statSync16(join68(historyDir, f2));
|
|
282371
282735
|
return { file: f2, mtime: stat6.mtimeMs };
|
|
282372
282736
|
}).sort((a2, b) => b.mtime - a2.mtime).slice(0, limit);
|
|
282373
282737
|
return files.map((f2) => {
|
|
282374
282738
|
try {
|
|
282375
|
-
return JSON.parse(readFileSync38(
|
|
282739
|
+
return JSON.parse(readFileSync38(join68(historyDir, f2.file), "utf-8"));
|
|
282376
282740
|
} catch {
|
|
282377
282741
|
return null;
|
|
282378
282742
|
}
|
|
@@ -282384,18 +282748,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
282384
282748
|
}
|
|
282385
282749
|
}
|
|
282386
282750
|
function savePendingTask(repoRoot, task) {
|
|
282387
|
-
const historyDir =
|
|
282388
|
-
|
|
282751
|
+
const historyDir = join68(repoRoot, OA_DIR, "history");
|
|
282752
|
+
mkdirSync25(historyDir, { recursive: true });
|
|
282389
282753
|
writeFileSync23(
|
|
282390
|
-
|
|
282754
|
+
join68(historyDir, PENDING_TASK_FILE),
|
|
282391
282755
|
JSON.stringify(task, null, 2) + "\n",
|
|
282392
282756
|
"utf-8"
|
|
282393
282757
|
);
|
|
282394
282758
|
}
|
|
282395
282759
|
function loadPendingTask(repoRoot) {
|
|
282396
|
-
const filePath =
|
|
282760
|
+
const filePath = join68(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
282397
282761
|
try {
|
|
282398
|
-
if (!
|
|
282762
|
+
if (!existsSync52(filePath)) return null;
|
|
282399
282763
|
const data = JSON.parse(readFileSync38(filePath, "utf-8"));
|
|
282400
282764
|
try {
|
|
282401
282765
|
unlinkSync11(filePath);
|
|
@@ -282407,12 +282771,12 @@ function loadPendingTask(repoRoot) {
|
|
|
282407
282771
|
}
|
|
282408
282772
|
}
|
|
282409
282773
|
function saveSessionContext(repoRoot, entry) {
|
|
282410
|
-
const contextDir =
|
|
282411
|
-
|
|
282412
|
-
const filePath =
|
|
282774
|
+
const contextDir = join68(repoRoot, OA_DIR, "context");
|
|
282775
|
+
mkdirSync25(contextDir, { recursive: true });
|
|
282776
|
+
const filePath = join68(contextDir, CONTEXT_SAVE_FILE);
|
|
282413
282777
|
let ctx3;
|
|
282414
282778
|
try {
|
|
282415
|
-
if (
|
|
282779
|
+
if (existsSync52(filePath)) {
|
|
282416
282780
|
ctx3 = JSON.parse(readFileSync38(filePath, "utf-8"));
|
|
282417
282781
|
} else {
|
|
282418
282782
|
ctx3 = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
@@ -282439,14 +282803,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
282439
282803
|
if (e2.summary) diaryLines.push(`Summary: ${e2.summary.slice(0, 200)}`);
|
|
282440
282804
|
diaryLines.push("");
|
|
282441
282805
|
}
|
|
282442
|
-
writeFileSync23(
|
|
282806
|
+
writeFileSync23(join68(contextDir, "session-diary.md"), diaryLines.join("\n"), "utf-8");
|
|
282443
282807
|
} catch {
|
|
282444
282808
|
}
|
|
282445
282809
|
}
|
|
282446
282810
|
function loadSessionContext(repoRoot) {
|
|
282447
|
-
const filePath =
|
|
282811
|
+
const filePath = join68(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
282448
282812
|
try {
|
|
282449
|
-
if (!
|
|
282813
|
+
if (!existsSync52(filePath)) return null;
|
|
282450
282814
|
return JSON.parse(readFileSync38(filePath, "utf-8"));
|
|
282451
282815
|
} catch {
|
|
282452
282816
|
return null;
|
|
@@ -282474,19 +282838,19 @@ function getLastTaskSummary(repoRoot) {
|
|
|
282474
282838
|
return clean3.length > 40 ? clean3.slice(0, 37) + "..." : clean3;
|
|
282475
282839
|
}
|
|
282476
282840
|
function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
282477
|
-
const sessDir =
|
|
282478
|
-
|
|
282841
|
+
const sessDir = join68(repoRoot, OA_DIR, SESSIONS_DIR);
|
|
282842
|
+
mkdirSync25(sessDir, { recursive: true });
|
|
282479
282843
|
const stripped = contentLines.map(
|
|
282480
282844
|
(line) => typeof line === "string" ? line.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "") : ""
|
|
282481
282845
|
);
|
|
282482
282846
|
const autoName = meta.name || generateSessionName(stripped);
|
|
282483
282847
|
const autoDesc = meta.description || generateSessionDescription(stripped);
|
|
282484
|
-
const contentPath =
|
|
282848
|
+
const contentPath = join68(sessDir, `${sessionId}.jsonl`);
|
|
282485
282849
|
writeFileSync23(contentPath, stripped.join("\n"), "utf-8");
|
|
282486
|
-
const indexPath =
|
|
282850
|
+
const indexPath = join68(sessDir, SESSIONS_INDEX);
|
|
282487
282851
|
let index = [];
|
|
282488
282852
|
try {
|
|
282489
|
-
if (
|
|
282853
|
+
if (existsSync52(indexPath)) {
|
|
282490
282854
|
index = JSON.parse(readFileSync38(indexPath, "utf-8"));
|
|
282491
282855
|
}
|
|
282492
282856
|
} catch {
|
|
@@ -282509,16 +282873,16 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
282509
282873
|
if (index.length > 50) {
|
|
282510
282874
|
const removed = index.shift();
|
|
282511
282875
|
try {
|
|
282512
|
-
unlinkSync11(
|
|
282876
|
+
unlinkSync11(join68(sessDir, `${removed.id}.jsonl`));
|
|
282513
282877
|
} catch {
|
|
282514
282878
|
}
|
|
282515
282879
|
}
|
|
282516
282880
|
writeFileSync23(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
282517
282881
|
}
|
|
282518
282882
|
function listSessions(repoRoot) {
|
|
282519
|
-
const indexPath =
|
|
282883
|
+
const indexPath = join68(repoRoot, OA_DIR, SESSIONS_DIR, SESSIONS_INDEX);
|
|
282520
282884
|
try {
|
|
282521
|
-
if (!
|
|
282885
|
+
if (!existsSync52(indexPath)) return [];
|
|
282522
282886
|
const index = JSON.parse(readFileSync38(indexPath, "utf-8"));
|
|
282523
282887
|
return index.sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
282524
282888
|
} catch {
|
|
@@ -282526,21 +282890,21 @@ function listSessions(repoRoot) {
|
|
|
282526
282890
|
}
|
|
282527
282891
|
}
|
|
282528
282892
|
function loadSessionHistory(repoRoot, sessionId) {
|
|
282529
|
-
const contentPath =
|
|
282893
|
+
const contentPath = join68(repoRoot, OA_DIR, SESSIONS_DIR, `${sessionId}.jsonl`);
|
|
282530
282894
|
try {
|
|
282531
|
-
if (!
|
|
282895
|
+
if (!existsSync52(contentPath)) return null;
|
|
282532
282896
|
return readFileSync38(contentPath, "utf-8").split("\n");
|
|
282533
282897
|
} catch {
|
|
282534
282898
|
return null;
|
|
282535
282899
|
}
|
|
282536
282900
|
}
|
|
282537
282901
|
function deleteSession(repoRoot, sessionId) {
|
|
282538
|
-
const sessDir =
|
|
282539
|
-
const indexPath =
|
|
282902
|
+
const sessDir = join68(repoRoot, OA_DIR, SESSIONS_DIR);
|
|
282903
|
+
const indexPath = join68(sessDir, SESSIONS_INDEX);
|
|
282540
282904
|
try {
|
|
282541
|
-
const contentPath =
|
|
282542
|
-
if (
|
|
282543
|
-
if (
|
|
282905
|
+
const contentPath = join68(sessDir, `${sessionId}.jsonl`);
|
|
282906
|
+
if (existsSync52(contentPath)) unlinkSync11(contentPath);
|
|
282907
|
+
if (existsSync52(indexPath)) {
|
|
282544
282908
|
let index = JSON.parse(readFileSync38(indexPath, "utf-8"));
|
|
282545
282909
|
index = index.filter((s2) => s2.id !== sessionId);
|
|
282546
282910
|
writeFileSync23(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
@@ -282594,8 +282958,8 @@ function detectManifests(repoRoot) {
|
|
|
282594
282958
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
282595
282959
|
];
|
|
282596
282960
|
for (const check of checks) {
|
|
282597
|
-
const filePath =
|
|
282598
|
-
if (
|
|
282961
|
+
const filePath = join68(repoRoot, check.file);
|
|
282962
|
+
if (existsSync52(filePath)) {
|
|
282599
282963
|
let name10;
|
|
282600
282964
|
if (check.nameField) {
|
|
282601
282965
|
try {
|
|
@@ -282628,7 +282992,7 @@ function findKeyFiles(repoRoot) {
|
|
|
282628
282992
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
282629
282993
|
];
|
|
282630
282994
|
for (const check of checks) {
|
|
282631
|
-
if (
|
|
282995
|
+
if (existsSync52(join68(repoRoot, check.pattern))) {
|
|
282632
282996
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
282633
282997
|
}
|
|
282634
282998
|
}
|
|
@@ -282651,12 +283015,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
282651
283015
|
if (entry.isDirectory()) {
|
|
282652
283016
|
let fileCount = 0;
|
|
282653
283017
|
try {
|
|
282654
|
-
fileCount = readdirSync11(
|
|
283018
|
+
fileCount = readdirSync11(join68(root, entry.name)).filter((f2) => !f2.startsWith(".")).length;
|
|
282655
283019
|
} catch {
|
|
282656
283020
|
}
|
|
282657
283021
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
282658
283022
|
`;
|
|
282659
|
-
result += buildDirTree(
|
|
283023
|
+
result += buildDirTree(join68(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
282660
283024
|
} else if (depth < maxDepth) {
|
|
282661
283025
|
result += `${prefix}${connector}${entry.name}
|
|
282662
283026
|
`;
|
|
@@ -282668,7 +283032,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
282668
283032
|
}
|
|
282669
283033
|
function loadUsageFile(filePath) {
|
|
282670
283034
|
try {
|
|
282671
|
-
if (
|
|
283035
|
+
if (existsSync52(filePath)) {
|
|
282672
283036
|
return JSON.parse(readFileSync38(filePath, "utf-8"));
|
|
282673
283037
|
}
|
|
282674
283038
|
} catch {
|
|
@@ -282676,8 +283040,8 @@ function loadUsageFile(filePath) {
|
|
|
282676
283040
|
return { records: [] };
|
|
282677
283041
|
}
|
|
282678
283042
|
function saveUsageFile(filePath, data) {
|
|
282679
|
-
const dir =
|
|
282680
|
-
|
|
283043
|
+
const dir = join68(filePath, "..");
|
|
283044
|
+
mkdirSync25(dir, { recursive: true });
|
|
282681
283045
|
writeFileSync23(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
282682
283046
|
}
|
|
282683
283047
|
function recordUsage(kind, value2, opts) {
|
|
@@ -282705,15 +283069,15 @@ function recordUsage(kind, value2, opts) {
|
|
|
282705
283069
|
}
|
|
282706
283070
|
saveUsageFile(filePath, data);
|
|
282707
283071
|
};
|
|
282708
|
-
update2(
|
|
283072
|
+
update2(join68(homedir19(), ".open-agents", USAGE_HISTORY_FILE));
|
|
282709
283073
|
if (opts?.repoRoot) {
|
|
282710
|
-
update2(
|
|
283074
|
+
update2(join68(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
282711
283075
|
}
|
|
282712
283076
|
}
|
|
282713
283077
|
function loadUsageHistory(kind, repoRoot) {
|
|
282714
|
-
const globalPath =
|
|
283078
|
+
const globalPath = join68(homedir19(), ".open-agents", USAGE_HISTORY_FILE);
|
|
282715
283079
|
const globalData = loadUsageFile(globalPath);
|
|
282716
|
-
const localData = repoRoot ? loadUsageFile(
|
|
283080
|
+
const localData = repoRoot ? loadUsageFile(join68(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
282717
283081
|
const map2 = /* @__PURE__ */ new Map();
|
|
282718
283082
|
for (const r2 of globalData.records) {
|
|
282719
283083
|
if (r2.kind !== kind) continue;
|
|
@@ -282742,9 +283106,9 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
282742
283106
|
saveUsageFile(filePath, data);
|
|
282743
283107
|
}
|
|
282744
283108
|
};
|
|
282745
|
-
remove(
|
|
283109
|
+
remove(join68(homedir19(), ".open-agents", USAGE_HISTORY_FILE));
|
|
282746
283110
|
if (repoRoot) {
|
|
282747
|
-
remove(
|
|
283111
|
+
remove(join68(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
282748
283112
|
}
|
|
282749
283113
|
}
|
|
282750
283114
|
var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SESSIONS_DIR, SESSIONS_INDEX, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -287296,8 +287660,8 @@ __export(personaplex_exports, {
|
|
|
287296
287660
|
startPersonaPlexDaemon: () => startPersonaPlexDaemon,
|
|
287297
287661
|
stopPersonaPlex: () => stopPersonaPlex
|
|
287298
287662
|
});
|
|
287299
|
-
import { existsSync as
|
|
287300
|
-
import { join as
|
|
287663
|
+
import { existsSync as existsSync53, writeFileSync as writeFileSync24, readFileSync as readFileSync40, mkdirSync as mkdirSync26, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync17 } from "node:fs";
|
|
287664
|
+
import { join as join69, dirname as dirname20 } from "node:path";
|
|
287301
287665
|
import { homedir as homedir20 } from "node:os";
|
|
287302
287666
|
import { execSync as execSync45, spawn as spawn20 } from "node:child_process";
|
|
287303
287667
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
@@ -287407,7 +287771,7 @@ function fileLink2(filePath, label) {
|
|
|
287407
287771
|
return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
|
|
287408
287772
|
}
|
|
287409
287773
|
function isPersonaPlexRunning() {
|
|
287410
|
-
if (!
|
|
287774
|
+
if (!existsSync53(PID_FILE)) return false;
|
|
287411
287775
|
const pid = parseInt(readFileSync40(PID_FILE, "utf8").trim(), 10);
|
|
287412
287776
|
if (isNaN(pid) || pid <= 0) return false;
|
|
287413
287777
|
try {
|
|
@@ -287419,17 +287783,17 @@ function isPersonaPlexRunning() {
|
|
|
287419
287783
|
}
|
|
287420
287784
|
function getPersonaPlexWSUrl() {
|
|
287421
287785
|
if (!isPersonaPlexRunning()) return null;
|
|
287422
|
-
if (!
|
|
287786
|
+
if (!existsSync53(PORT_FILE)) return null;
|
|
287423
287787
|
const port = parseInt(readFileSync40(PORT_FILE, "utf8").trim(), 10);
|
|
287424
287788
|
return isNaN(port) ? null : `wss://127.0.0.1:${port}`;
|
|
287425
287789
|
}
|
|
287426
287790
|
function isPersonaPlexInstalled() {
|
|
287427
|
-
return
|
|
287791
|
+
return existsSync53(join69(PERSONAPLEX_DIR, "model_ready"));
|
|
287428
287792
|
}
|
|
287429
287793
|
function getWeightTier() {
|
|
287430
287794
|
const detected = detectPersonaPlexCapability();
|
|
287431
|
-
const tierFile =
|
|
287432
|
-
if (
|
|
287795
|
+
const tierFile = join69(PERSONAPLEX_DIR, "weight_tier");
|
|
287796
|
+
if (existsSync53(tierFile)) {
|
|
287433
287797
|
const saved = readFileSync40(tierFile, "utf8").trim();
|
|
287434
287798
|
if (saved in WEIGHT_REPOS) {
|
|
287435
287799
|
const vram = detected.vramGB;
|
|
@@ -287448,7 +287812,7 @@ function getWeightRepoInfo(tier) {
|
|
|
287448
287812
|
async function installPersonaPlex(onInfo, weightTier) {
|
|
287449
287813
|
const log22 = onInfo ?? (() => {
|
|
287450
287814
|
});
|
|
287451
|
-
|
|
287815
|
+
mkdirSync26(PERSONAPLEX_DIR, { recursive: true });
|
|
287452
287816
|
let arch2 = "";
|
|
287453
287817
|
try {
|
|
287454
287818
|
arch2 = execSync45("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
@@ -287456,8 +287820,8 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287456
287820
|
}
|
|
287457
287821
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
287458
287822
|
if (isAarch64) log22(`Detected ARM64 platform (${arch2}) \u2014 Jetson/ARM install path`);
|
|
287459
|
-
const venvDir =
|
|
287460
|
-
if (!
|
|
287823
|
+
const venvDir = join69(PERSONAPLEX_DIR, "venv");
|
|
287824
|
+
if (!existsSync53(venvDir)) {
|
|
287461
287825
|
log22("Creating Python virtual environment...");
|
|
287462
287826
|
try {
|
|
287463
287827
|
const ssp = isAarch64 ? " --system-site-packages" : "";
|
|
@@ -287467,8 +287831,8 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287467
287831
|
return false;
|
|
287468
287832
|
}
|
|
287469
287833
|
}
|
|
287470
|
-
const pip = process.platform === "win32" ?
|
|
287471
|
-
const python = process.platform === "win32" ?
|
|
287834
|
+
const pip = process.platform === "win32" ? join69(venvDir, "Scripts", "pip.exe") : join69(venvDir, "bin", "pip");
|
|
287835
|
+
const python = process.platform === "win32" ? join69(venvDir, "Scripts", "python.exe") : join69(venvDir, "bin", "python3");
|
|
287472
287836
|
log22("Checking system dependencies (libopus)...");
|
|
287473
287837
|
try {
|
|
287474
287838
|
if (process.platform === "linux") {
|
|
@@ -287498,9 +287862,9 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287498
287862
|
}
|
|
287499
287863
|
}
|
|
287500
287864
|
log22("Installing PersonaPlex (moshi package)...");
|
|
287501
|
-
const repoDir =
|
|
287865
|
+
const repoDir = join69(PERSONAPLEX_DIR, "personaplex-repo");
|
|
287502
287866
|
try {
|
|
287503
|
-
if (!
|
|
287867
|
+
if (!existsSync53(repoDir)) {
|
|
287504
287868
|
await execAsync(
|
|
287505
287869
|
`git clone https://github.com/NVIDIA/personaplex.git "${repoDir}"`,
|
|
287506
287870
|
{ timeout: 12e4 }
|
|
@@ -287524,7 +287888,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287524
287888
|
if (isAarch64) {
|
|
287525
287889
|
log22("ARM64: Installing moshi (--no-deps to preserve JetPack torch)...");
|
|
287526
287890
|
await execAsync(
|
|
287527
|
-
`"${pip}" install --quiet --no-deps "${
|
|
287891
|
+
`"${pip}" install --quiet --no-deps "${join69(repoDir, "moshi")}/."`,
|
|
287528
287892
|
{ timeout: 3e5 }
|
|
287529
287893
|
);
|
|
287530
287894
|
log22("ARM64: Installing remaining moshi dependencies...");
|
|
@@ -287534,7 +287898,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287534
287898
|
);
|
|
287535
287899
|
} else {
|
|
287536
287900
|
await execAsync(
|
|
287537
|
-
`"${pip}" install --quiet "${
|
|
287901
|
+
`"${pip}" install --quiet "${join69(repoDir, "moshi")}/."`,
|
|
287538
287902
|
{ timeout: 6e5 }
|
|
287539
287903
|
// 10 min — torch download is ~2.5GB
|
|
287540
287904
|
);
|
|
@@ -287552,15 +287916,15 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287552
287916
|
}
|
|
287553
287917
|
return false;
|
|
287554
287918
|
}
|
|
287555
|
-
const serverPy =
|
|
287919
|
+
const serverPy = join69(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
287556
287920
|
try {
|
|
287557
287921
|
const sitePackages = execSync45(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
287558
287922
|
encoding: "utf8",
|
|
287559
287923
|
timeout: 5e3,
|
|
287560
287924
|
stdio: "pipe"
|
|
287561
287925
|
}).trim();
|
|
287562
|
-
const serverFile =
|
|
287563
|
-
if (
|
|
287926
|
+
const serverFile = join69(sitePackages, "server.py");
|
|
287927
|
+
if (existsSync53(serverFile)) {
|
|
287564
287928
|
let src2 = readFileSync40(serverFile, "utf8");
|
|
287565
287929
|
if (src2.includes('int(request["seed"])')) {
|
|
287566
287930
|
src2 = src2.replace('int(request["seed"])', 'int(request.query["seed"])');
|
|
@@ -287576,8 +287940,8 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
287576
287940
|
timeout: 5e3,
|
|
287577
287941
|
stdio: "pipe"
|
|
287578
287942
|
}).trim();
|
|
287579
|
-
const loadersFile =
|
|
287580
|
-
if (
|
|
287943
|
+
const loadersFile = join69(sitePackages, "models", "loaders.py");
|
|
287944
|
+
if (existsSync53(loadersFile)) {
|
|
287581
287945
|
let src2 = readFileSync40(loadersFile, "utf8");
|
|
287582
287946
|
if (!src2.includes("_dequantize_2bit_state_dict")) {
|
|
287583
287947
|
const dequantPatch = `
|
|
@@ -287680,16 +288044,16 @@ $2if filename.endswith(".safetensors"):`
|
|
|
287680
288044
|
timeout: 5e3,
|
|
287681
288045
|
stdio: "pipe"
|
|
287682
288046
|
}).trim();
|
|
287683
|
-
const hybridDest =
|
|
287684
|
-
const serverDest =
|
|
287685
|
-
if (!
|
|
288047
|
+
const hybridDest = join69(sitePackages2, "hybrid_agent.py");
|
|
288048
|
+
const serverDest = join69(sitePackages2, "server.py");
|
|
288049
|
+
if (!existsSync53(hybridDest) || !readFileSync40(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
287686
288050
|
log22("Deploying hybrid_agent.py (OA API integration)...");
|
|
287687
288051
|
try {
|
|
287688
288052
|
await execAsync(
|
|
287689
288053
|
`curl -sL "https://raw.githubusercontent.com/robit-man/personaplex/main/personaplex-setup/moshi/moshi/hybrid_agent.py" -o "${hybridDest}"`,
|
|
287690
288054
|
{ timeout: 3e4 }
|
|
287691
288055
|
);
|
|
287692
|
-
if (
|
|
288056
|
+
if (existsSync53(hybridDest) && readFileSync40(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
287693
288057
|
log22("hybrid_agent.py deployed (OA API + Ollama fallback).");
|
|
287694
288058
|
}
|
|
287695
288059
|
} catch {
|
|
@@ -287766,7 +288130,7 @@ $2if filename.endswith(".safetensors"):`
|
|
|
287766
288130
|
await execAsync(`"${python}" -c "from huggingface_hub import hf_hub_download; hf_hub_download('${nf4.repo}', '${nf4.file}', token=False)"`, {
|
|
287767
288131
|
timeout: 6e5
|
|
287768
288132
|
});
|
|
287769
|
-
writeFileSync24(
|
|
288133
|
+
writeFileSync24(join69(PERSONAPLEX_DIR, "weight_tier"), "nf4");
|
|
287770
288134
|
log22(`Downloaded INT4 weights instead (${nf4.sizeGB}GB, public).`);
|
|
287771
288135
|
} catch {
|
|
287772
288136
|
log22("Weight download failed.");
|
|
@@ -287778,8 +288142,8 @@ $2if filename.endswith(".safetensors"):`
|
|
|
287778
288142
|
log22("Weights will download on first server launch.");
|
|
287779
288143
|
}
|
|
287780
288144
|
}
|
|
287781
|
-
writeFileSync24(
|
|
287782
|
-
writeFileSync24(
|
|
288145
|
+
writeFileSync24(join69(PERSONAPLEX_DIR, "weight_tier"), tier);
|
|
288146
|
+
writeFileSync24(join69(PERSONAPLEX_DIR, "model_ready"), (/* @__PURE__ */ new Date()).toISOString());
|
|
287783
288147
|
log22(`PersonaPlex installed (${tier} tier). Use /call to start voice session.`);
|
|
287784
288148
|
return true;
|
|
287785
288149
|
}
|
|
@@ -287798,15 +288162,15 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
287798
288162
|
log22("PersonaPlex not installed. Run /voice personaplex to set up.");
|
|
287799
288163
|
return null;
|
|
287800
288164
|
}
|
|
287801
|
-
|
|
287802
|
-
const venvPython2 = process.platform === "win32" ?
|
|
287803
|
-
const sslDir =
|
|
287804
|
-
|
|
288165
|
+
mkdirSync26(PERSONAPLEX_DIR, { recursive: true });
|
|
288166
|
+
const venvPython2 = process.platform === "win32" ? join69(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join69(PERSONAPLEX_DIR, "venv", "bin", "python3");
|
|
288167
|
+
const sslDir = join69(PERSONAPLEX_DIR, "ssl");
|
|
288168
|
+
mkdirSync26(sslDir, { recursive: true });
|
|
287805
288169
|
const tier = getWeightTier();
|
|
287806
288170
|
const repoInfo = WEIGHT_REPOS[tier];
|
|
287807
288171
|
const extraArgs = [];
|
|
287808
288172
|
if (tier !== "original") {
|
|
287809
|
-
const cachedBf16 =
|
|
288173
|
+
const cachedBf16 = join69(PERSONAPLEX_DIR, "model-bf16-cache.safetensors");
|
|
287810
288174
|
if (tier === "nf4-distilled") {
|
|
287811
288175
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
287812
288176
|
try {
|
|
@@ -287814,8 +288178,8 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
287814
288178
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
287815
288179
|
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
287816
288180
|
).trim();
|
|
287817
|
-
if (
|
|
287818
|
-
if (!
|
|
288181
|
+
if (existsSync53(weightPath)) {
|
|
288182
|
+
if (!existsSync53(cachedBf16)) {
|
|
287819
288183
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
287820
288184
|
execSync45(
|
|
287821
288185
|
`"${venvPython2}" -c "
|
|
@@ -287828,7 +288192,7 @@ print('Converted')
|
|
|
287828
288192
|
{ timeout: 18e4, stdio: "pipe" }
|
|
287829
288193
|
);
|
|
287830
288194
|
}
|
|
287831
|
-
if (
|
|
288195
|
+
if (existsSync53(cachedBf16)) {
|
|
287832
288196
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
287833
288197
|
log22(`Using distilled weights: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
287834
288198
|
} else {
|
|
@@ -287840,12 +288204,12 @@ print('Converted')
|
|
|
287840
288204
|
}
|
|
287841
288205
|
} else {
|
|
287842
288206
|
log22(`Weight tier: ${tier} (${repoInfo.sizeGB}GB) \u2014 dequantizing to bf16 cache...`);
|
|
287843
|
-
const dequantScript =
|
|
287844
|
-
if (!
|
|
288207
|
+
const dequantScript = join69(PERSONAPLEX_DIR, "dequant-loader.py");
|
|
288208
|
+
if (!existsSync53(dequantScript)) {
|
|
287845
288209
|
const shipped = getShippedVoicesDir();
|
|
287846
288210
|
if (shipped) {
|
|
287847
|
-
const src2 =
|
|
287848
|
-
if (
|
|
288211
|
+
const src2 = join69(shipped, "dequant-loader.py");
|
|
288212
|
+
if (existsSync53(src2)) copyFileSync2(src2, dequantScript);
|
|
287849
288213
|
}
|
|
287850
288214
|
}
|
|
287851
288215
|
try {
|
|
@@ -287853,13 +288217,13 @@ print('Converted')
|
|
|
287853
288217
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
287854
288218
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
287855
288219
|
).trim();
|
|
287856
|
-
if (
|
|
288220
|
+
if (existsSync53(dequantScript) && existsSync53(weightPath)) {
|
|
287857
288221
|
try {
|
|
287858
288222
|
execSync45(
|
|
287859
288223
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
287860
288224
|
{ timeout: 3e5, stdio: "pipe" }
|
|
287861
288225
|
);
|
|
287862
|
-
if (
|
|
288226
|
+
if (existsSync53(cachedBf16)) {
|
|
287863
288227
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
287864
288228
|
log22(`Using dequantized cache: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
287865
288229
|
}
|
|
@@ -287872,7 +288236,7 @@ print('Converted')
|
|
|
287872
288236
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
287873
288237
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
287874
288238
|
).trim();
|
|
287875
|
-
if (
|
|
288239
|
+
if (existsSync53(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
|
|
287876
288240
|
} catch {
|
|
287877
288241
|
}
|
|
287878
288242
|
try {
|
|
@@ -287880,7 +288244,7 @@ print('Converted')
|
|
|
287880
288244
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
287881
288245
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
287882
288246
|
).trim();
|
|
287883
|
-
if (
|
|
288247
|
+
if (existsSync53(tokPath)) extraArgs.push("--tokenizer", tokPath);
|
|
287884
288248
|
} catch {
|
|
287885
288249
|
}
|
|
287886
288250
|
} catch {
|
|
@@ -287893,7 +288257,7 @@ print('Converted')
|
|
|
287893
288257
|
let ollamaModel = process.env["HYBRID_LLM_MODEL"] || "";
|
|
287894
288258
|
if (!ollamaModel) {
|
|
287895
288259
|
try {
|
|
287896
|
-
const oaConfig = JSON.parse(readFileSync40(
|
|
288260
|
+
const oaConfig = JSON.parse(readFileSync40(join69(homedir20(), ".open-agents", "config.json"), "utf8"));
|
|
287897
288261
|
if (oaConfig.model) ollamaModel = oaConfig.model;
|
|
287898
288262
|
} catch {
|
|
287899
288263
|
}
|
|
@@ -287992,7 +288356,7 @@ print('Converted')
|
|
|
287992
288356
|
return null;
|
|
287993
288357
|
}
|
|
287994
288358
|
function stopPersonaPlex() {
|
|
287995
|
-
if (!
|
|
288359
|
+
if (!existsSync53(PID_FILE)) return;
|
|
287996
288360
|
const pid = parseInt(readFileSync40(PID_FILE, "utf8").trim(), 10);
|
|
287997
288361
|
if (isNaN(pid) || pid <= 0) return;
|
|
287998
288362
|
try {
|
|
@@ -288029,12 +288393,12 @@ function listPersonaPlexVoices() {
|
|
|
288029
288393
|
for (const name10 of builtins) {
|
|
288030
288394
|
voices.push({ name: name10, type: "builtin", path: `${name10}.pt` });
|
|
288031
288395
|
}
|
|
288032
|
-
if (
|
|
288396
|
+
if (existsSync53(CUSTOM_VOICES_DIR)) {
|
|
288033
288397
|
try {
|
|
288034
288398
|
for (const f2 of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
288035
288399
|
if (f2.endsWith(".pt")) {
|
|
288036
288400
|
const name10 = f2.replace(/\.pt$/, "");
|
|
288037
|
-
voices.push({ name: name10, type: "custom", path:
|
|
288401
|
+
voices.push({ name: name10, type: "custom", path: join69(CUSTOM_VOICES_DIR, f2) });
|
|
288038
288402
|
}
|
|
288039
288403
|
}
|
|
288040
288404
|
} catch {
|
|
@@ -288049,19 +288413,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
288049
288413
|
log22("PersonaPlex not installed. Run /voice personaplex first.");
|
|
288050
288414
|
return null;
|
|
288051
288415
|
}
|
|
288052
|
-
if (!
|
|
288416
|
+
if (!existsSync53(inputWav)) {
|
|
288053
288417
|
log22(`Input WAV not found: ${inputWav}`);
|
|
288054
288418
|
return null;
|
|
288055
288419
|
}
|
|
288056
|
-
|
|
288057
|
-
const outputPt =
|
|
288058
|
-
if (
|
|
288420
|
+
mkdirSync26(CUSTOM_VOICES_DIR, { recursive: true });
|
|
288421
|
+
const outputPt = join69(CUSTOM_VOICES_DIR, `${voiceName}.pt`);
|
|
288422
|
+
if (existsSync53(outputPt)) {
|
|
288059
288423
|
log22(`Voice "${voiceName}" already exists. Delete ${outputPt} to re-clone.`);
|
|
288060
288424
|
return outputPt;
|
|
288061
288425
|
}
|
|
288062
|
-
const venvPython2 = process.platform === "win32" ?
|
|
288063
|
-
const cloneScript =
|
|
288064
|
-
if (!
|
|
288426
|
+
const venvPython2 = process.platform === "win32" ? join69(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join69(PERSONAPLEX_DIR, "venv", "bin", "python3");
|
|
288427
|
+
const cloneScript = join69(PERSONAPLEX_DIR, "clone-voice.py");
|
|
288428
|
+
if (!existsSync53(cloneScript)) {
|
|
288065
288429
|
log22("clone-voice.py not found. Reinstall PersonaPlex.");
|
|
288066
288430
|
return null;
|
|
288067
288431
|
}
|
|
@@ -288093,7 +288457,7 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
288093
288457
|
output += d2.toString();
|
|
288094
288458
|
});
|
|
288095
288459
|
child.on("close", (code8) => {
|
|
288096
|
-
if (code8 === 0 &&
|
|
288460
|
+
if (code8 === 0 && existsSync53(outputPt)) {
|
|
288097
288461
|
log22(`Voice "${voiceName}" cloned successfully.`);
|
|
288098
288462
|
resolve39(outputPt);
|
|
288099
288463
|
} else {
|
|
@@ -288105,19 +288469,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
288105
288469
|
}
|
|
288106
288470
|
function getShippedVoicesDir() {
|
|
288107
288471
|
const candidates = [
|
|
288108
|
-
|
|
288472
|
+
join69(PERSONAPLEX_DIR, "shipped_voices"),
|
|
288109
288473
|
// cached copy
|
|
288110
|
-
|
|
288474
|
+
join69(process.cwd(), "voices", "personaplex")
|
|
288111
288475
|
// repo root
|
|
288112
288476
|
];
|
|
288113
288477
|
try {
|
|
288114
288478
|
const modDir = dirname20(fileURLToPath12(import.meta.url));
|
|
288115
|
-
candidates.push(
|
|
288116
|
-
candidates.push(
|
|
288479
|
+
candidates.push(join69(modDir, "..", "..", "..", "voices", "personaplex"));
|
|
288480
|
+
candidates.push(join69(modDir, "..", "..", "..", "..", "voices", "personaplex"));
|
|
288117
288481
|
} catch {
|
|
288118
288482
|
}
|
|
288119
288483
|
for (const dir of candidates) {
|
|
288120
|
-
if (
|
|
288484
|
+
if (existsSync53(dir)) {
|
|
288121
288485
|
try {
|
|
288122
288486
|
const files = readdirSync12(dir);
|
|
288123
288487
|
if (files.some((f2) => f2.endsWith(".pt"))) return dir;
|
|
@@ -288133,19 +288497,19 @@ function provisionShippedVoices(onInfo) {
|
|
|
288133
288497
|
const shippedDir = getShippedVoicesDir();
|
|
288134
288498
|
if (!shippedDir) return 0;
|
|
288135
288499
|
const hfVoicesDir = getHFVoicesDir();
|
|
288136
|
-
|
|
288500
|
+
mkdirSync26(CUSTOM_VOICES_DIR, { recursive: true });
|
|
288137
288501
|
let deployed = 0;
|
|
288138
288502
|
try {
|
|
288139
288503
|
for (const f2 of readdirSync12(shippedDir)) {
|
|
288140
288504
|
if (!f2.endsWith(".pt")) continue;
|
|
288141
|
-
const customDst =
|
|
288142
|
-
if (!
|
|
288143
|
-
copyFileSync2(
|
|
288505
|
+
const customDst = join69(CUSTOM_VOICES_DIR, f2);
|
|
288506
|
+
if (!existsSync53(customDst)) {
|
|
288507
|
+
copyFileSync2(join69(shippedDir, f2), customDst);
|
|
288144
288508
|
}
|
|
288145
288509
|
if (hfVoicesDir) {
|
|
288146
|
-
const hfDst =
|
|
288147
|
-
if (!
|
|
288148
|
-
copyFileSync2(
|
|
288510
|
+
const hfDst = join69(hfVoicesDir, f2);
|
|
288511
|
+
if (!existsSync53(hfDst)) {
|
|
288512
|
+
copyFileSync2(join69(shippedDir, f2), hfDst);
|
|
288149
288513
|
log22(`Deployed voice: ${f2.replace(".pt", "")}`);
|
|
288150
288514
|
deployed++;
|
|
288151
288515
|
}
|
|
@@ -288153,9 +288517,9 @@ function provisionShippedVoices(onInfo) {
|
|
|
288153
288517
|
}
|
|
288154
288518
|
} catch {
|
|
288155
288519
|
}
|
|
288156
|
-
const shippedScript =
|
|
288157
|
-
const targetScript =
|
|
288158
|
-
if (
|
|
288520
|
+
const shippedScript = join69(shippedDir, "clone-voice.py");
|
|
288521
|
+
const targetScript = join69(PERSONAPLEX_DIR, "clone-voice.py");
|
|
288522
|
+
if (existsSync53(shippedScript) && !existsSync53(targetScript)) {
|
|
288159
288523
|
try {
|
|
288160
288524
|
copyFileSync2(shippedScript, targetScript);
|
|
288161
288525
|
} catch {
|
|
@@ -288164,14 +288528,14 @@ function provisionShippedVoices(onInfo) {
|
|
|
288164
288528
|
return deployed;
|
|
288165
288529
|
}
|
|
288166
288530
|
function getHFVoicesDir() {
|
|
288167
|
-
const hfBase =
|
|
288168
|
-
if (!
|
|
288531
|
+
const hfBase = join69(homedir20(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
288532
|
+
if (!existsSync53(hfBase)) return null;
|
|
288169
288533
|
try {
|
|
288170
|
-
const snapshots =
|
|
288171
|
-
if (!
|
|
288534
|
+
const snapshots = join69(hfBase, "snapshots");
|
|
288535
|
+
if (!existsSync53(snapshots)) return null;
|
|
288172
288536
|
for (const snap of readdirSync12(snapshots)) {
|
|
288173
|
-
const voicesDir =
|
|
288174
|
-
if (
|
|
288537
|
+
const voicesDir = join69(snapshots, snap, "voices");
|
|
288538
|
+
if (existsSync53(voicesDir)) return voicesDir;
|
|
288175
288539
|
}
|
|
288176
288540
|
} catch {
|
|
288177
288541
|
}
|
|
@@ -288180,19 +288544,19 @@ function getHFVoicesDir() {
|
|
|
288180
288544
|
function patchFrontendVoiceList(onInfo) {
|
|
288181
288545
|
const log22 = onInfo ?? (() => {
|
|
288182
288546
|
});
|
|
288183
|
-
const hfBase =
|
|
288184
|
-
if (!
|
|
288547
|
+
const hfBase = join69(homedir20(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
288548
|
+
if (!existsSync53(hfBase)) return;
|
|
288185
288549
|
try {
|
|
288186
|
-
const snapshots =
|
|
288550
|
+
const snapshots = join69(hfBase, "snapshots");
|
|
288187
288551
|
for (const snap of readdirSync12(snapshots)) {
|
|
288188
|
-
const distDir =
|
|
288189
|
-
if (!
|
|
288552
|
+
const distDir = join69(snapshots, snap, "dist", "assets");
|
|
288553
|
+
if (!existsSync53(distDir)) continue;
|
|
288190
288554
|
for (const f2 of readdirSync12(distDir)) {
|
|
288191
288555
|
if (!f2.startsWith("index-") || !f2.endsWith(".js")) continue;
|
|
288192
|
-
const jsPath =
|
|
288556
|
+
const jsPath = join69(distDir, f2);
|
|
288193
288557
|
let js = readFileSync40(jsPath, "utf8");
|
|
288194
288558
|
const customVoices = [];
|
|
288195
|
-
if (
|
|
288559
|
+
if (existsSync53(CUSTOM_VOICES_DIR)) {
|
|
288196
288560
|
for (const vf of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
288197
288561
|
if (vf.endsWith(".pt")) {
|
|
288198
288562
|
const name10 = vf.replace(".pt", "");
|
|
@@ -288258,11 +288622,11 @@ var init_personaplex = __esm({
|
|
|
288258
288622
|
nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
|
|
288259
288623
|
"nf4-distilled": { repo: "cudabenchmarktest/personaplex-7b-nf4-distilled", file: "student_best.pt", sizeGB: 16.7, needsToken: false }
|
|
288260
288624
|
};
|
|
288261
|
-
PERSONAPLEX_DIR =
|
|
288262
|
-
PID_FILE =
|
|
288263
|
-
PORT_FILE =
|
|
288264
|
-
LOG_FILE =
|
|
288265
|
-
CUSTOM_VOICES_DIR =
|
|
288625
|
+
PERSONAPLEX_DIR = join69(homedir20(), ".open-agents", "voice", "personaplex");
|
|
288626
|
+
PID_FILE = join69(PERSONAPLEX_DIR, "daemon.pid");
|
|
288627
|
+
PORT_FILE = join69(PERSONAPLEX_DIR, "daemon.port");
|
|
288628
|
+
LOG_FILE = join69(PERSONAPLEX_DIR, "daemon.log");
|
|
288629
|
+
CUSTOM_VOICES_DIR = join69(PERSONAPLEX_DIR, "custom_voices");
|
|
288266
288630
|
}
|
|
288267
288631
|
});
|
|
288268
288632
|
|
|
@@ -288303,8 +288667,8 @@ __export(setup_exports, {
|
|
|
288303
288667
|
import * as readline from "node:readline";
|
|
288304
288668
|
import { execSync as execSync46, spawn as spawn21, exec as exec4 } from "node:child_process";
|
|
288305
288669
|
import { promisify as promisify7 } from "node:util";
|
|
288306
|
-
import { existsSync as
|
|
288307
|
-
import { join as
|
|
288670
|
+
import { existsSync as existsSync54, writeFileSync as writeFileSync25, readFileSync as readFileSync41, appendFileSync as appendFileSync2, mkdirSync as mkdirSync27 } from "node:fs";
|
|
288671
|
+
import { join as join70 } from "node:path";
|
|
288308
288672
|
import { homedir as homedir21, platform as platform3 } from "node:os";
|
|
288309
288673
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
288310
288674
|
if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
|
|
@@ -288615,7 +288979,7 @@ async function installOllamaMac(_rl) {
|
|
|
288615
288979
|
);
|
|
288616
288980
|
if (!hasCmd("brew")) {
|
|
288617
288981
|
try {
|
|
288618
|
-
const brewPrefix =
|
|
288982
|
+
const brewPrefix = existsSync54("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
288619
288983
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
288620
288984
|
} catch {
|
|
288621
288985
|
}
|
|
@@ -289404,9 +289768,9 @@ async function doSetup(config, rl) {
|
|
|
289404
289768
|
`PARAMETER num_predict ${numPredict}`,
|
|
289405
289769
|
`PARAMETER stop "<|endoftext|>"`
|
|
289406
289770
|
].join("\n");
|
|
289407
|
-
const modelDir2 =
|
|
289408
|
-
|
|
289409
|
-
const modelfilePath =
|
|
289771
|
+
const modelDir2 = join70(homedir21(), ".open-agents", "models");
|
|
289772
|
+
mkdirSync27(modelDir2, { recursive: true });
|
|
289773
|
+
const modelfilePath = join70(modelDir2, `Modelfile.${customName}`);
|
|
289410
289774
|
writeFileSync25(modelfilePath, modelfileContent + "\n", "utf8");
|
|
289411
289775
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
289412
289776
|
execSync46(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
@@ -289452,7 +289816,7 @@ async function isModelAvailable(config) {
|
|
|
289452
289816
|
}
|
|
289453
289817
|
function isFirstRun() {
|
|
289454
289818
|
try {
|
|
289455
|
-
return !
|
|
289819
|
+
return !existsSync54(join70(homedir21(), ".open-agents", "config.json"));
|
|
289456
289820
|
} catch {
|
|
289457
289821
|
return true;
|
|
289458
289822
|
}
|
|
@@ -289500,7 +289864,7 @@ function detectPkgManager() {
|
|
|
289500
289864
|
return null;
|
|
289501
289865
|
}
|
|
289502
289866
|
function getVenvDir() {
|
|
289503
|
-
return
|
|
289867
|
+
return join70(homedir21(), ".open-agents", "venv");
|
|
289504
289868
|
}
|
|
289505
289869
|
function hasVenvModule() {
|
|
289506
289870
|
try {
|
|
@@ -289513,9 +289877,9 @@ function hasVenvModule() {
|
|
|
289513
289877
|
function ensureVenv(log22) {
|
|
289514
289878
|
const venvDir = getVenvDir();
|
|
289515
289879
|
const isWin2 = process.platform === "win32";
|
|
289516
|
-
const pipPath = isWin2 ?
|
|
289880
|
+
const pipPath = isWin2 ? join70(venvDir, "Scripts", "pip.exe") : join70(venvDir, "bin", "pip");
|
|
289517
289881
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
289518
|
-
if (
|
|
289882
|
+
if (existsSync54(pipPath)) return venvDir;
|
|
289519
289883
|
log22("Creating Python venv for vision deps...");
|
|
289520
289884
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
289521
289885
|
log22(`${pythonCmd} not found \u2014 cannot create venv.`);
|
|
@@ -289526,7 +289890,7 @@ function ensureVenv(log22) {
|
|
|
289526
289890
|
return null;
|
|
289527
289891
|
}
|
|
289528
289892
|
try {
|
|
289529
|
-
|
|
289893
|
+
mkdirSync27(join70(homedir21(), ".open-agents"), { recursive: true });
|
|
289530
289894
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
289531
289895
|
execSync46(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
289532
289896
|
execSync46(`"${pipPath}" install --upgrade pip`, {
|
|
@@ -289626,11 +289990,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
289626
289990
|
];
|
|
289627
289991
|
{
|
|
289628
289992
|
const pm2 = detectPkgManager();
|
|
289629
|
-
const _visionMarkerDir =
|
|
289630
|
-
const _visionMarkerFile =
|
|
289993
|
+
const _visionMarkerDir = join70(homedir21(), ".open-agents");
|
|
289994
|
+
const _visionMarkerFile = join70(_visionMarkerDir, "vision-deps-installed.json");
|
|
289631
289995
|
let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
|
|
289632
289996
|
try {
|
|
289633
|
-
if (
|
|
289997
|
+
if (existsSync54(_visionMarkerFile)) {
|
|
289634
289998
|
const _vm = JSON.parse(readFileSync41(_visionMarkerFile, "utf8"));
|
|
289635
289999
|
_visionPreviouslyInstalled = new Set(_vm.installed || []);
|
|
289636
290000
|
}
|
|
@@ -289744,7 +290108,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
289744
290108
|
}
|
|
289745
290109
|
}
|
|
289746
290110
|
try {
|
|
289747
|
-
|
|
290111
|
+
mkdirSync27(_visionMarkerDir, { recursive: true });
|
|
289748
290112
|
writeFileSync25(_visionMarkerFile, JSON.stringify({
|
|
289749
290113
|
installed: [..._visionPreviouslyInstalled],
|
|
289750
290114
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -289797,15 +290161,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
289797
290161
|
}
|
|
289798
290162
|
const venvDir = getVenvDir();
|
|
289799
290163
|
const isWin2 = process.platform === "win32";
|
|
289800
|
-
const venvBin =
|
|
289801
|
-
const venvMoondream =
|
|
290164
|
+
const venvBin = join70(venvDir, isWin2 ? "Scripts" : "bin");
|
|
290165
|
+
const venvMoondream = join70(venvBin, isWin2 ? "moondream-station.exe" : "moondream-station");
|
|
289802
290166
|
const venv = ensureVenv(log22);
|
|
289803
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
289804
|
-
const venvPip2 =
|
|
290167
|
+
if (venv && !hasCmd("moondream-station") && !existsSync54(venvMoondream)) {
|
|
290168
|
+
const venvPip2 = join70(venvBin, "pip");
|
|
289805
290169
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
289806
290170
|
try {
|
|
289807
290171
|
execSync46(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
289808
|
-
if (
|
|
290172
|
+
if (existsSync54(venvMoondream)) {
|
|
289809
290173
|
log22("moondream-station installed successfully.");
|
|
289810
290174
|
} else {
|
|
289811
290175
|
try {
|
|
@@ -289822,8 +290186,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
289822
290186
|
}
|
|
289823
290187
|
}
|
|
289824
290188
|
if (venv) {
|
|
289825
|
-
const venvPython2 =
|
|
289826
|
-
const venvPip2 =
|
|
290189
|
+
const venvPython2 = join70(venvBin, isWin2 ? "python.exe" : "python");
|
|
290190
|
+
const venvPip2 = join70(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
289827
290191
|
let ocrStackInstalled = false;
|
|
289828
290192
|
try {
|
|
289829
290193
|
execSync46(
|
|
@@ -289980,9 +290344,9 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
289980
290344
|
`PARAMETER num_predict ${numPredict}`,
|
|
289981
290345
|
`PARAMETER stop "<|endoftext|>"`
|
|
289982
290346
|
].join("\n");
|
|
289983
|
-
const modelDir2 =
|
|
289984
|
-
|
|
289985
|
-
const modelfilePath =
|
|
290347
|
+
const modelDir2 = join70(homedir21(), ".open-agents", "models");
|
|
290348
|
+
mkdirSync27(modelDir2, { recursive: true });
|
|
290349
|
+
const modelfilePath = join70(modelDir2, `Modelfile.${customName}`);
|
|
289986
290350
|
writeFileSync25(modelfilePath, modelfileContent + "\n", "utf8");
|
|
289987
290351
|
execSync46(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
289988
290352
|
stdio: "pipe",
|
|
@@ -290005,9 +290369,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
290005
290369
|
`PARAMETER num_predict ${numPredict}`,
|
|
290006
290370
|
`PARAMETER stop "<|endoftext|>"`
|
|
290007
290371
|
].join("\n");
|
|
290008
|
-
const modelDir2 =
|
|
290009
|
-
|
|
290010
|
-
const modelfilePath =
|
|
290372
|
+
const modelDir2 = join70(homedir21(), ".open-agents", "models");
|
|
290373
|
+
mkdirSync27(modelDir2, { recursive: true });
|
|
290374
|
+
const modelfilePath = join70(modelDir2, `Modelfile.${customName}`);
|
|
290011
290375
|
writeFileSync25(modelfilePath, modelfileContent + "\n", "utf8");
|
|
290012
290376
|
await execAsync2(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
290013
290377
|
timeout: 12e4
|
|
@@ -290081,10 +290445,10 @@ async function ensureNeovim() {
|
|
|
290081
290445
|
const platform6 = process.platform;
|
|
290082
290446
|
const arch2 = process.arch;
|
|
290083
290447
|
if (platform6 === "linux") {
|
|
290084
|
-
const binDir =
|
|
290085
|
-
const nvimDest =
|
|
290448
|
+
const binDir = join70(homedir21(), ".local", "bin");
|
|
290449
|
+
const nvimDest = join70(binDir, "nvim");
|
|
290086
290450
|
try {
|
|
290087
|
-
|
|
290451
|
+
mkdirSync27(binDir, { recursive: true });
|
|
290088
290452
|
} catch {
|
|
290089
290453
|
}
|
|
290090
290454
|
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
@@ -290153,9 +290517,9 @@ async function ensureNeovim() {
|
|
|
290153
290517
|
}
|
|
290154
290518
|
function ensurePathInShellRc(binDir) {
|
|
290155
290519
|
const shell = process.env.SHELL ?? "";
|
|
290156
|
-
const rcFile = shell.includes("zsh") ?
|
|
290520
|
+
const rcFile = shell.includes("zsh") ? join70(homedir21(), ".zshrc") : join70(homedir21(), ".bashrc");
|
|
290157
290521
|
try {
|
|
290158
|
-
const rcContent =
|
|
290522
|
+
const rcContent = existsSync54(rcFile) ? readFileSync41(rcFile, "utf8") : "";
|
|
290159
290523
|
if (rcContent.includes(binDir)) return;
|
|
290160
290524
|
const exportLine = `
|
|
290161
290525
|
export PATH="${binDir}:$PATH" # Added by open-agents for nvim
|
|
@@ -290192,7 +290556,7 @@ var init_setup = __esm({
|
|
|
290192
290556
|
});
|
|
290193
290557
|
|
|
290194
290558
|
// packages/cli/src/tui/drop-panel.ts
|
|
290195
|
-
import { existsSync as
|
|
290559
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
290196
290560
|
import { extname as extname10, resolve as resolve31 } from "node:path";
|
|
290197
290561
|
function ansi4(code8, text) {
|
|
290198
290562
|
return isTTY4 ? `\x1B[${code8}m${text}\x1B[0m` : text;
|
|
@@ -290313,7 +290677,7 @@ function showDropPanel(opts) {
|
|
|
290313
290677
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
290314
290678
|
}
|
|
290315
290679
|
filePath = resolve31(filePath);
|
|
290316
|
-
if (!
|
|
290680
|
+
if (!existsSync55(filePath)) {
|
|
290317
290681
|
errorMsg = `File not found: ${filePath}`;
|
|
290318
290682
|
render();
|
|
290319
290683
|
return;
|
|
@@ -290385,9 +290749,9 @@ var init_drop_panel = __esm({
|
|
|
290385
290749
|
});
|
|
290386
290750
|
|
|
290387
290751
|
// packages/cli/src/tui/neovim-mode.ts
|
|
290388
|
-
import { existsSync as
|
|
290752
|
+
import { existsSync as existsSync56, unlinkSync as unlinkSync12 } from "node:fs";
|
|
290389
290753
|
import { tmpdir as tmpdir15 } from "node:os";
|
|
290390
|
-
import { join as
|
|
290754
|
+
import { join as join71 } from "node:path";
|
|
290391
290755
|
import { execSync as execSync47 } from "node:child_process";
|
|
290392
290756
|
function isNeovimActive() {
|
|
290393
290757
|
return _state !== null && !_state.cleanedUp;
|
|
@@ -290433,9 +290797,9 @@ async function startNeovimMode(opts) {
|
|
|
290433
290797
|
);
|
|
290434
290798
|
} catch {
|
|
290435
290799
|
}
|
|
290436
|
-
const socketPath =
|
|
290800
|
+
const socketPath = join71(tmpdir15(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
290437
290801
|
try {
|
|
290438
|
-
if (
|
|
290802
|
+
if (existsSync56(socketPath)) unlinkSync12(socketPath);
|
|
290439
290803
|
} catch {
|
|
290440
290804
|
}
|
|
290441
290805
|
const ptyCols = opts.cols;
|
|
@@ -290682,12 +291046,12 @@ function resizeNeovim(cols, contentRows) {
|
|
|
290682
291046
|
}
|
|
290683
291047
|
async function connectRPC(state, neovimPkg, cols) {
|
|
290684
291048
|
let attempts = 0;
|
|
290685
|
-
while (!
|
|
291049
|
+
while (!existsSync56(state.socketPath) && attempts < 30) {
|
|
290686
291050
|
await new Promise((r2) => setTimeout(r2, 200));
|
|
290687
291051
|
attempts++;
|
|
290688
291052
|
if (state.cleanedUp) return;
|
|
290689
291053
|
}
|
|
290690
|
-
if (!
|
|
291054
|
+
if (!existsSync56(state.socketPath)) return;
|
|
290691
291055
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
290692
291056
|
state.nvim = nvim;
|
|
290693
291057
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
@@ -290824,7 +291188,7 @@ function doCleanup(state) {
|
|
|
290824
291188
|
state.pty = null;
|
|
290825
291189
|
}
|
|
290826
291190
|
try {
|
|
290827
|
-
if (
|
|
291191
|
+
if (existsSync56(state.socketPath)) unlinkSync12(state.socketPath);
|
|
290828
291192
|
} catch {
|
|
290829
291193
|
}
|
|
290830
291194
|
if (state.stdinHandler) {
|
|
@@ -290894,8 +291258,8 @@ __export(daemon_exports, {
|
|
|
290894
291258
|
stopDaemon: () => stopDaemon
|
|
290895
291259
|
});
|
|
290896
291260
|
import { spawn as spawn22 } from "node:child_process";
|
|
290897
|
-
import { existsSync as
|
|
290898
|
-
import { join as
|
|
291261
|
+
import { existsSync as existsSync57, readFileSync as readFileSync42, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, unlinkSync as unlinkSync13 } from "node:fs";
|
|
291262
|
+
import { join as join72 } from "node:path";
|
|
290899
291263
|
import { homedir as homedir22 } from "node:os";
|
|
290900
291264
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
290901
291265
|
import { dirname as dirname21 } from "node:path";
|
|
@@ -290920,7 +291284,7 @@ async function isDaemonRunning(port) {
|
|
|
290920
291284
|
}
|
|
290921
291285
|
}
|
|
290922
291286
|
function getDaemonPid() {
|
|
290923
|
-
if (!
|
|
291287
|
+
if (!existsSync57(PID_FILE2)) return null;
|
|
290924
291288
|
try {
|
|
290925
291289
|
const pid = parseInt(readFileSync42(PID_FILE2, "utf8").trim(), 10);
|
|
290926
291290
|
if (!pid || pid <= 0) return null;
|
|
@@ -290935,7 +291299,7 @@ function getDaemonPid() {
|
|
|
290935
291299
|
}
|
|
290936
291300
|
}
|
|
290937
291301
|
async function startDaemon() {
|
|
290938
|
-
|
|
291302
|
+
mkdirSync28(OA_DIR2, { recursive: true });
|
|
290939
291303
|
const nodeExe = process.execPath;
|
|
290940
291304
|
let oaScript = process.argv[1];
|
|
290941
291305
|
if (!oaScript) {
|
|
@@ -290948,8 +291312,8 @@ async function startDaemon() {
|
|
|
290948
291312
|
}
|
|
290949
291313
|
if (!oaScript) {
|
|
290950
291314
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
290951
|
-
const indexJs =
|
|
290952
|
-
if (
|
|
291315
|
+
const indexJs = join72(thisDir, "index.js");
|
|
291316
|
+
if (existsSync57(indexJs)) oaScript = indexJs;
|
|
290953
291317
|
}
|
|
290954
291318
|
if (!oaScript) return null;
|
|
290955
291319
|
try {
|
|
@@ -291047,8 +291411,8 @@ var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
|
|
|
291047
291411
|
var init_daemon = __esm({
|
|
291048
291412
|
"packages/cli/src/daemon.ts"() {
|
|
291049
291413
|
"use strict";
|
|
291050
|
-
OA_DIR2 =
|
|
291051
|
-
PID_FILE2 =
|
|
291414
|
+
OA_DIR2 = join72(homedir22(), ".open-agents");
|
|
291415
|
+
PID_FILE2 = join72(OA_DIR2, "daemon.pid");
|
|
291052
291416
|
DEFAULT_PORT2 = 11435;
|
|
291053
291417
|
}
|
|
291054
291418
|
});
|
|
@@ -291433,8 +291797,8 @@ __export(sponsor_wizard_exports, {
|
|
|
291433
291797
|
saveSponsorConfig: () => saveSponsorConfig,
|
|
291434
291798
|
showSponsorDashboard: () => showSponsorDashboard
|
|
291435
291799
|
});
|
|
291436
|
-
import { existsSync as
|
|
291437
|
-
import { join as
|
|
291800
|
+
import { existsSync as existsSync58, readFileSync as readFileSync43, writeFileSync as writeFileSync27, mkdirSync as mkdirSync29 } from "node:fs";
|
|
291801
|
+
import { join as join73 } from "node:path";
|
|
291438
291802
|
function colorPreview(code8) {
|
|
291439
291803
|
return `\x1B[38;5;${code8}m\u2588\u2588\u2588\u2588\x1B[0m (${code8})`;
|
|
291440
291804
|
}
|
|
@@ -291447,14 +291811,14 @@ function gradientPreview(start2, end) {
|
|
|
291447
291811
|
return s2;
|
|
291448
291812
|
}
|
|
291449
291813
|
function sponsorDir(projectDir) {
|
|
291450
|
-
return
|
|
291814
|
+
return join73(projectDir, ".oa", "sponsor");
|
|
291451
291815
|
}
|
|
291452
291816
|
function configPath(projectDir) {
|
|
291453
|
-
return
|
|
291817
|
+
return join73(sponsorDir(projectDir), "config.json");
|
|
291454
291818
|
}
|
|
291455
291819
|
function loadSponsorConfig(projectDir) {
|
|
291456
291820
|
const p2 = configPath(projectDir);
|
|
291457
|
-
if (!
|
|
291821
|
+
if (!existsSync58(p2)) return null;
|
|
291458
291822
|
try {
|
|
291459
291823
|
return JSON.parse(readFileSync43(p2, "utf8"));
|
|
291460
291824
|
} catch {
|
|
@@ -291463,7 +291827,7 @@ function loadSponsorConfig(projectDir) {
|
|
|
291463
291827
|
}
|
|
291464
291828
|
function saveSponsorConfig(projectDir, config) {
|
|
291465
291829
|
const dir = sponsorDir(projectDir);
|
|
291466
|
-
|
|
291830
|
+
mkdirSync29(dir, { recursive: true });
|
|
291467
291831
|
config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
291468
291832
|
writeFileSync27(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
|
|
291469
291833
|
}
|
|
@@ -292345,8 +292709,8 @@ __export(voice_exports, {
|
|
|
292345
292709
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
292346
292710
|
resetNarrationContext: () => resetNarrationContext
|
|
292347
292711
|
});
|
|
292348
|
-
import { existsSync as
|
|
292349
|
-
import { join as
|
|
292712
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, readFileSync as readFileSync44, unlinkSync as unlinkSync14, readdirSync as readdirSync13, statSync as statSync18 } from "node:fs";
|
|
292713
|
+
import { join as join74, dirname as dirname22 } from "node:path";
|
|
292350
292714
|
import { homedir as homedir23, tmpdir as tmpdir16, platform as platform4 } from "node:os";
|
|
292351
292715
|
import { execSync as execSync48, spawn as nodeSpawn } from "node:child_process";
|
|
292352
292716
|
import { createRequire as createRequire3 } from "node:module";
|
|
@@ -292371,39 +292735,39 @@ function listVoiceModels() {
|
|
|
292371
292735
|
}));
|
|
292372
292736
|
}
|
|
292373
292737
|
function voiceDir() {
|
|
292374
|
-
return
|
|
292738
|
+
return join74(homedir23(), ".open-agents", "voice");
|
|
292375
292739
|
}
|
|
292376
292740
|
function modelsDir() {
|
|
292377
|
-
return
|
|
292741
|
+
return join74(voiceDir(), "models");
|
|
292378
292742
|
}
|
|
292379
292743
|
function modelDir(id) {
|
|
292380
|
-
return
|
|
292744
|
+
return join74(modelsDir(), id);
|
|
292381
292745
|
}
|
|
292382
292746
|
function modelOnnxPath(id) {
|
|
292383
|
-
return
|
|
292747
|
+
return join74(modelDir(id), "model.onnx");
|
|
292384
292748
|
}
|
|
292385
292749
|
function modelConfigPath(id) {
|
|
292386
|
-
return
|
|
292750
|
+
return join74(modelDir(id), "config.json");
|
|
292387
292751
|
}
|
|
292388
292752
|
function luxttsVenvDir() {
|
|
292389
|
-
return
|
|
292753
|
+
return join74(voiceDir(), "luxtts-venv");
|
|
292390
292754
|
}
|
|
292391
292755
|
function luxttsVenvPy() {
|
|
292392
|
-
return platform4() === "win32" ?
|
|
292756
|
+
return platform4() === "win32" ? join74(luxttsVenvDir(), "Scripts", "python.exe") : join74(luxttsVenvDir(), "bin", "python3");
|
|
292393
292757
|
}
|
|
292394
292758
|
function luxttsRepoDir() {
|
|
292395
|
-
return
|
|
292759
|
+
return join74(voiceDir(), "LuxTTS");
|
|
292396
292760
|
}
|
|
292397
292761
|
function luxttsCloneRefsDir() {
|
|
292398
|
-
return
|
|
292762
|
+
return join74(voiceDir(), "clone-refs");
|
|
292399
292763
|
}
|
|
292400
292764
|
function luxttsInferScript() {
|
|
292401
|
-
return
|
|
292765
|
+
return join74(voiceDir(), "luxtts-infer.py");
|
|
292402
292766
|
}
|
|
292403
292767
|
function writeDetectTorchScript(targetPath) {
|
|
292404
|
-
if (
|
|
292768
|
+
if (existsSync59(targetPath)) return;
|
|
292405
292769
|
try {
|
|
292406
|
-
|
|
292770
|
+
mkdirSync30(dirname22(targetPath), { recursive: true });
|
|
292407
292771
|
} catch {
|
|
292408
292772
|
}
|
|
292409
292773
|
const script = `#!/usr/bin/env python3
|
|
@@ -293226,8 +293590,8 @@ var init_voice = __esm({
|
|
|
293226
293590
|
const refsDir = luxttsCloneRefsDir();
|
|
293227
293591
|
const targets = ["glados", "overwatch"];
|
|
293228
293592
|
for (const modelId of targets) {
|
|
293229
|
-
const refFile =
|
|
293230
|
-
if (
|
|
293593
|
+
const refFile = join74(refsDir, `${modelId}-ref.wav`);
|
|
293594
|
+
if (existsSync59(refFile)) continue;
|
|
293231
293595
|
try {
|
|
293232
293596
|
await this.generateCloneRef(modelId);
|
|
293233
293597
|
const meta = this.loadCloneMeta();
|
|
@@ -293303,20 +293667,20 @@ var init_voice = __esm({
|
|
|
293303
293667
|
}
|
|
293304
293668
|
p2 = p2.replace(/\\ /g, " ");
|
|
293305
293669
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
293306
|
-
p2 =
|
|
293670
|
+
p2 = join74(homedir23(), p2.slice(1));
|
|
293307
293671
|
}
|
|
293308
|
-
if (!
|
|
293672
|
+
if (!existsSync59(p2)) {
|
|
293309
293673
|
return `File not found: ${p2}
|
|
293310
293674
|
(original input: ${audioPath})`;
|
|
293311
293675
|
}
|
|
293312
293676
|
audioPath = p2;
|
|
293313
293677
|
const refsDir = luxttsCloneRefsDir();
|
|
293314
|
-
if (!
|
|
293678
|
+
if (!existsSync59(refsDir)) mkdirSync30(refsDir, { recursive: true });
|
|
293315
293679
|
const ext = audioPath.split(".").pop() || "wav";
|
|
293316
293680
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
293317
293681
|
const ts = Date.now().toString(36);
|
|
293318
293682
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
293319
|
-
const destPath =
|
|
293683
|
+
const destPath = join74(refsDir, destFilename);
|
|
293320
293684
|
try {
|
|
293321
293685
|
const data = readFileSync44(audioPath);
|
|
293322
293686
|
writeFileSync28(destPath, data);
|
|
@@ -293359,8 +293723,8 @@ var init_voice = __esm({
|
|
|
293359
293723
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
293360
293724
|
}
|
|
293361
293725
|
const refsDir = luxttsCloneRefsDir();
|
|
293362
|
-
if (!
|
|
293363
|
-
const destPath =
|
|
293726
|
+
if (!existsSync59(refsDir)) mkdirSync30(refsDir, { recursive: true });
|
|
293727
|
+
const destPath = join74(refsDir, `${sourceModelId}-ref.wav`);
|
|
293364
293728
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
293365
293729
|
this.writeWav(audioData, sampleRate, destPath);
|
|
293366
293730
|
this.luxttsCloneRef = destPath;
|
|
@@ -293376,11 +293740,11 @@ var init_voice = __esm({
|
|
|
293376
293740
|
// -------------------------------------------------------------------------
|
|
293377
293741
|
/** Metadata file for friendly names of clone refs */
|
|
293378
293742
|
static cloneMetaFile() {
|
|
293379
|
-
return
|
|
293743
|
+
return join74(luxttsCloneRefsDir(), "meta.json");
|
|
293380
293744
|
}
|
|
293381
293745
|
loadCloneMeta() {
|
|
293382
293746
|
const p2 = _VoiceEngine.cloneMetaFile();
|
|
293383
|
-
if (!
|
|
293747
|
+
if (!existsSync59(p2)) return {};
|
|
293384
293748
|
try {
|
|
293385
293749
|
return JSON.parse(readFileSync44(p2, "utf8"));
|
|
293386
293750
|
} catch {
|
|
@@ -293389,7 +293753,7 @@ var init_voice = __esm({
|
|
|
293389
293753
|
}
|
|
293390
293754
|
saveCloneMeta(meta) {
|
|
293391
293755
|
const dir = luxttsCloneRefsDir();
|
|
293392
|
-
if (!
|
|
293756
|
+
if (!existsSync59(dir)) mkdirSync30(dir, { recursive: true });
|
|
293393
293757
|
writeFileSync28(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
293394
293758
|
}
|
|
293395
293759
|
/** Audio file extensions recognized as clone references */
|
|
@@ -293400,14 +293764,14 @@ var init_voice = __esm({
|
|
|
293400
293764
|
*/
|
|
293401
293765
|
listCloneRefs() {
|
|
293402
293766
|
const dir = luxttsCloneRefsDir();
|
|
293403
|
-
if (!
|
|
293767
|
+
if (!existsSync59(dir)) return [];
|
|
293404
293768
|
const meta = this.loadCloneMeta();
|
|
293405
293769
|
const files = readdirSync13(dir).filter((f2) => {
|
|
293406
293770
|
const ext = f2.split(".").pop()?.toLowerCase() ?? "";
|
|
293407
293771
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
293408
293772
|
});
|
|
293409
293773
|
return files.map((f2) => {
|
|
293410
|
-
const p2 =
|
|
293774
|
+
const p2 = join74(dir, f2);
|
|
293411
293775
|
let size = 0;
|
|
293412
293776
|
try {
|
|
293413
293777
|
size = statSync18(p2).size;
|
|
@@ -293424,8 +293788,8 @@ var init_voice = __esm({
|
|
|
293424
293788
|
}
|
|
293425
293789
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
293426
293790
|
deleteCloneRef(filename) {
|
|
293427
|
-
const p2 =
|
|
293428
|
-
if (!
|
|
293791
|
+
const p2 = join74(luxttsCloneRefsDir(), filename);
|
|
293792
|
+
if (!existsSync59(p2)) return false;
|
|
293429
293793
|
try {
|
|
293430
293794
|
unlinkSync14(p2);
|
|
293431
293795
|
const meta = this.loadCloneMeta();
|
|
@@ -293448,8 +293812,8 @@ var init_voice = __esm({
|
|
|
293448
293812
|
}
|
|
293449
293813
|
/** Set the active clone reference by filename. */
|
|
293450
293814
|
setActiveCloneRef(filename) {
|
|
293451
|
-
const p2 =
|
|
293452
|
-
if (!
|
|
293815
|
+
const p2 = join74(luxttsCloneRefsDir(), filename);
|
|
293816
|
+
if (!existsSync59(p2)) return `File not found: ${filename}`;
|
|
293453
293817
|
this.luxttsCloneRef = p2;
|
|
293454
293818
|
return `Active clone voice set to: ${filename}`;
|
|
293455
293819
|
}
|
|
@@ -293786,7 +294150,7 @@ var init_voice = __esm({
|
|
|
293786
294150
|
}
|
|
293787
294151
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
293788
294152
|
}
|
|
293789
|
-
const wavPath =
|
|
294153
|
+
const wavPath = join74(tmpdir16(), `oa-voice-${Date.now()}.wav`);
|
|
293790
294154
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
293791
294155
|
await this.playWav(wavPath);
|
|
293792
294156
|
try {
|
|
@@ -294181,7 +294545,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294181
294545
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
294182
294546
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
294183
294547
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
294184
|
-
const wavPath =
|
|
294548
|
+
const wavPath = join74(tmpdir16(), `oa-mlx-${Date.now()}.wav`);
|
|
294185
294549
|
const pyScript = [
|
|
294186
294550
|
"import sys, json",
|
|
294187
294551
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -294204,7 +294568,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294204
294568
|
return;
|
|
294205
294569
|
}
|
|
294206
294570
|
}
|
|
294207
|
-
if (!
|
|
294571
|
+
if (!existsSync59(wavPath)) return;
|
|
294208
294572
|
if (volume !== 1) {
|
|
294209
294573
|
try {
|
|
294210
294574
|
const wavData = readFileSync44(wavPath);
|
|
@@ -294255,7 +294619,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294255
294619
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
294256
294620
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
294257
294621
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
294258
|
-
const wavPath =
|
|
294622
|
+
const wavPath = join74(tmpdir16(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
294259
294623
|
const pyScript = [
|
|
294260
294624
|
"import sys, json",
|
|
294261
294625
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -294278,7 +294642,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294278
294642
|
return null;
|
|
294279
294643
|
}
|
|
294280
294644
|
}
|
|
294281
|
-
if (!
|
|
294645
|
+
if (!existsSync59(wavPath)) return null;
|
|
294282
294646
|
try {
|
|
294283
294647
|
const data = readFileSync44(wavPath);
|
|
294284
294648
|
unlinkSync14(wavPath);
|
|
@@ -294305,7 +294669,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294305
294669
|
}
|
|
294306
294670
|
const venvDir = luxttsVenvDir();
|
|
294307
294671
|
const venvPy = luxttsVenvPy();
|
|
294308
|
-
if (
|
|
294672
|
+
if (existsSync59(venvPy)) {
|
|
294309
294673
|
try {
|
|
294310
294674
|
const quotedPy = `"${venvPy}"`;
|
|
294311
294675
|
const repoPath = luxttsRepoDir().replace(/\\/g, "/");
|
|
@@ -294327,7 +294691,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294327
294691
|
if (torchCheck === "cpu") {
|
|
294328
294692
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
294329
294693
|
try {
|
|
294330
|
-
const detectScript =
|
|
294694
|
+
const detectScript = join74(voiceDir(), "detect-torch.py");
|
|
294331
294695
|
writeDetectTorchScript(detectScript);
|
|
294332
294696
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
294333
294697
|
try {
|
|
@@ -294354,7 +294718,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294354
294718
|
}
|
|
294355
294719
|
}
|
|
294356
294720
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
294357
|
-
if (!
|
|
294721
|
+
if (!existsSync59(venvDir)) {
|
|
294358
294722
|
renderInfo(" Creating Python virtual environment...");
|
|
294359
294723
|
try {
|
|
294360
294724
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -294365,7 +294729,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294365
294729
|
}
|
|
294366
294730
|
}
|
|
294367
294731
|
{
|
|
294368
|
-
const detectScript =
|
|
294732
|
+
const detectScript = join74(voiceDir(), "detect-torch.py");
|
|
294369
294733
|
writeDetectTorchScript(detectScript);
|
|
294370
294734
|
let pipArgsStr = "torch torchaudio";
|
|
294371
294735
|
let torchDesc = "unknown platform";
|
|
@@ -294410,10 +294774,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294410
294774
|
}
|
|
294411
294775
|
}
|
|
294412
294776
|
const repoDir = luxttsRepoDir();
|
|
294413
|
-
if (!
|
|
294777
|
+
if (!existsSync59(join74(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
294414
294778
|
renderInfo(" Cloning LuxTTS repository...");
|
|
294415
294779
|
try {
|
|
294416
|
-
if (
|
|
294780
|
+
if (existsSync59(repoDir)) {
|
|
294417
294781
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
294418
294782
|
await this.asyncShell(rmCmd, 3e4);
|
|
294419
294783
|
}
|
|
@@ -294502,7 +294866,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294502
294866
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
294503
294867
|
}
|
|
294504
294868
|
}
|
|
294505
|
-
const isJetson = isArm && (
|
|
294869
|
+
const isJetson = isArm && (existsSync59("/etc/nv_tegra_release") || existsSync59("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
294506
294870
|
const installSteps = isArm ? [
|
|
294507
294871
|
// ARM: install individually so we get clear error messages per package.
|
|
294508
294872
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -294515,7 +294879,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294515
294879
|
...isJetson ? (() => {
|
|
294516
294880
|
let jpVer = "v60";
|
|
294517
294881
|
try {
|
|
294518
|
-
const tegra =
|
|
294882
|
+
const tegra = existsSync59("/etc/nv_tegra_release") ? execSync48("cat /etc/nv_tegra_release 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim() : "";
|
|
294519
294883
|
const dpkg = execSync48("dpkg -l nvidia-jetpack 2>/dev/null | grep nvidia-jetpack | awk '{print $3}'", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
294520
294884
|
const ver = dpkg || process.env.JETSON_L4T_VERSION || "";
|
|
294521
294885
|
if (ver.startsWith("5.") || tegra.includes("R35") || tegra.includes("R34")) jpVer = "v51";
|
|
@@ -294595,12 +294959,12 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
294595
294959
|
}
|
|
294596
294960
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
294597
294961
|
autoDetectCloneRef() {
|
|
294598
|
-
if (this.luxttsCloneRef &&
|
|
294962
|
+
if (this.luxttsCloneRef && existsSync59(this.luxttsCloneRef)) return;
|
|
294599
294963
|
const refsDir = luxttsCloneRefsDir();
|
|
294600
|
-
if (!
|
|
294964
|
+
if (!existsSync59(refsDir)) return;
|
|
294601
294965
|
for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
294602
|
-
const p2 =
|
|
294603
|
-
if (
|
|
294966
|
+
const p2 = join74(refsDir, name10);
|
|
294967
|
+
if (existsSync59(p2)) {
|
|
294604
294968
|
this.luxttsCloneRef = p2;
|
|
294605
294969
|
return;
|
|
294606
294970
|
}
|
|
@@ -294700,14 +295064,14 @@ if __name__ == '__main__':
|
|
|
294700
295064
|
main()
|
|
294701
295065
|
`;
|
|
294702
295066
|
const scriptPath2 = luxttsInferScript();
|
|
294703
|
-
|
|
295067
|
+
mkdirSync30(voiceDir(), { recursive: true });
|
|
294704
295068
|
writeFileSync28(scriptPath2, script);
|
|
294705
295069
|
}
|
|
294706
295070
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
294707
295071
|
async ensureLuxttsDaemon() {
|
|
294708
295072
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed) return true;
|
|
294709
295073
|
const venvPy = luxttsVenvPy();
|
|
294710
|
-
if (!
|
|
295074
|
+
if (!existsSync59(venvPy)) return false;
|
|
294711
295075
|
return new Promise((resolve39) => {
|
|
294712
295076
|
const env2 = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
294713
295077
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
@@ -294796,12 +295160,12 @@ if __name__ == '__main__':
|
|
|
294796
295160
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
294797
295161
|
*/
|
|
294798
295162
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
294799
|
-
if (!this.luxttsCloneRef || !
|
|
295163
|
+
if (!this.luxttsCloneRef || !existsSync59(this.luxttsCloneRef)) return null;
|
|
294800
295164
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
294801
295165
|
if (!cleaned) return null;
|
|
294802
295166
|
const ready = await this.ensureLuxttsDaemon();
|
|
294803
295167
|
if (!ready) return null;
|
|
294804
|
-
const wavPath =
|
|
295168
|
+
const wavPath = join74(tmpdir16(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
294805
295169
|
try {
|
|
294806
295170
|
await this.luxttsRequest({
|
|
294807
295171
|
action: "synthesize",
|
|
@@ -294813,14 +295177,14 @@ if __name__ == '__main__':
|
|
|
294813
295177
|
} catch {
|
|
294814
295178
|
return null;
|
|
294815
295179
|
}
|
|
294816
|
-
return
|
|
295180
|
+
return existsSync59(wavPath) ? wavPath : null;
|
|
294817
295181
|
}
|
|
294818
295182
|
/**
|
|
294819
295183
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
294820
295184
|
* Cleans up the WAV file after playback.
|
|
294821
295185
|
*/
|
|
294822
295186
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
294823
|
-
if (!
|
|
295187
|
+
if (!existsSync59(wavPath)) return;
|
|
294824
295188
|
try {
|
|
294825
295189
|
const wavData = readFileSync44(wavPath);
|
|
294826
295190
|
if (wavData.length > 44) {
|
|
@@ -294916,12 +295280,12 @@ if __name__ == '__main__':
|
|
|
294916
295280
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
294917
295281
|
*/
|
|
294918
295282
|
async synthesizeLuxttsToBuffer(text) {
|
|
294919
|
-
if (!this.luxttsCloneRef || !
|
|
295283
|
+
if (!this.luxttsCloneRef || !existsSync59(this.luxttsCloneRef)) return null;
|
|
294920
295284
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
294921
295285
|
if (!cleaned) return null;
|
|
294922
295286
|
const ready = await this.ensureLuxttsDaemon();
|
|
294923
295287
|
if (!ready) return null;
|
|
294924
|
-
const wavPath =
|
|
295288
|
+
const wavPath = join74(tmpdir16(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
294925
295289
|
try {
|
|
294926
295290
|
await this.luxttsRequest({
|
|
294927
295291
|
action: "synthesize",
|
|
@@ -294933,7 +295297,7 @@ if __name__ == '__main__':
|
|
|
294933
295297
|
} catch {
|
|
294934
295298
|
return null;
|
|
294935
295299
|
}
|
|
294936
|
-
if (!
|
|
295300
|
+
if (!existsSync59(wavPath)) return null;
|
|
294937
295301
|
try {
|
|
294938
295302
|
const data = readFileSync44(wavPath);
|
|
294939
295303
|
unlinkSync14(wavPath);
|
|
@@ -294948,13 +295312,13 @@ if __name__ == '__main__':
|
|
|
294948
295312
|
async ensureRuntime() {
|
|
294949
295313
|
if (this.ort) return;
|
|
294950
295314
|
const arch2 = process.arch;
|
|
294951
|
-
|
|
294952
|
-
const pkgPath =
|
|
295315
|
+
mkdirSync30(voiceDir(), { recursive: true });
|
|
295316
|
+
const pkgPath = join74(voiceDir(), "package.json");
|
|
294953
295317
|
const expectedDeps = {
|
|
294954
295318
|
"onnxruntime-node": "^1.21.0",
|
|
294955
295319
|
"phonemizer": "^1.2.1"
|
|
294956
295320
|
};
|
|
294957
|
-
if (
|
|
295321
|
+
if (existsSync59(pkgPath)) {
|
|
294958
295322
|
try {
|
|
294959
295323
|
const existing = JSON.parse(readFileSync44(pkgPath, "utf8"));
|
|
294960
295324
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
@@ -294964,18 +295328,18 @@ if __name__ == '__main__':
|
|
|
294964
295328
|
} catch {
|
|
294965
295329
|
}
|
|
294966
295330
|
}
|
|
294967
|
-
if (!
|
|
295331
|
+
if (!existsSync59(pkgPath)) {
|
|
294968
295332
|
writeFileSync28(pkgPath, JSON.stringify({
|
|
294969
295333
|
name: "open-agents-voice",
|
|
294970
295334
|
private: true,
|
|
294971
295335
|
dependencies: expectedDeps
|
|
294972
295336
|
}, null, 2));
|
|
294973
295337
|
}
|
|
294974
|
-
const voiceRequire = createRequire3(
|
|
295338
|
+
const voiceRequire = createRequire3(join74(voiceDir(), "index.js"));
|
|
294975
295339
|
const probeOnnx = async () => {
|
|
294976
295340
|
try {
|
|
294977
295341
|
const output = await this.asyncShell(
|
|
294978
|
-
`NODE_PATH="${
|
|
295342
|
+
`NODE_PATH="${join74(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`,
|
|
294979
295343
|
15e3
|
|
294980
295344
|
);
|
|
294981
295345
|
return output.trim() === "OK";
|
|
@@ -294983,8 +295347,8 @@ if __name__ == '__main__':
|
|
|
294983
295347
|
return false;
|
|
294984
295348
|
}
|
|
294985
295349
|
};
|
|
294986
|
-
const onnxNodeModules =
|
|
294987
|
-
const onnxInstalled =
|
|
295350
|
+
const onnxNodeModules = join74(voiceDir(), "node_modules", "onnxruntime-node");
|
|
295351
|
+
const onnxInstalled = existsSync59(onnxNodeModules);
|
|
294988
295352
|
if (onnxInstalled && !await probeOnnx()) {
|
|
294989
295353
|
throw new Error(
|
|
294990
295354
|
`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). 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.`
|
|
@@ -295043,16 +295407,16 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
295043
295407
|
const dir = modelDir(id);
|
|
295044
295408
|
const onnxPath = modelOnnxPath(id);
|
|
295045
295409
|
const configPath2 = modelConfigPath(id);
|
|
295046
|
-
if (
|
|
295047
|
-
|
|
295048
|
-
if (!
|
|
295410
|
+
if (existsSync59(onnxPath) && existsSync59(configPath2)) return;
|
|
295411
|
+
mkdirSync30(dir, { recursive: true });
|
|
295412
|
+
if (!existsSync59(configPath2)) {
|
|
295049
295413
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
295050
295414
|
const configResp = await fetch(model.configUrl);
|
|
295051
295415
|
if (!configResp.ok) throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
295052
295416
|
const configText = await configResp.text();
|
|
295053
295417
|
writeFileSync28(configPath2, configText);
|
|
295054
295418
|
}
|
|
295055
|
-
if (!
|
|
295419
|
+
if (!existsSync59(onnxPath)) {
|
|
295056
295420
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
295057
295421
|
const onnxResp = await fetch(model.onnxUrl);
|
|
295058
295422
|
if (!onnxResp.ok) throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
|
|
@@ -295085,7 +295449,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
295085
295449
|
if (!this.ort) throw new Error("ONNX runtime not loaded");
|
|
295086
295450
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
295087
295451
|
const configPath2 = modelConfigPath(this.modelId);
|
|
295088
|
-
if (!
|
|
295452
|
+
if (!existsSync59(onnxPath) || !existsSync59(configPath2)) {
|
|
295089
295453
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
295090
295454
|
}
|
|
295091
295455
|
this.config = JSON.parse(readFileSync44(configPath2, "utf8"));
|
|
@@ -295115,8 +295479,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
295115
295479
|
// packages/cli/src/tui/commands.ts
|
|
295116
295480
|
import * as nodeOs from "node:os";
|
|
295117
295481
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
295118
|
-
import { existsSync as
|
|
295119
|
-
import { join as
|
|
295482
|
+
import { existsSync as existsSync60, readFileSync as readFileSync45, writeFileSync as writeFileSync29, mkdirSync as mkdirSync31, readdirSync as readdirSync14, statSync as statSync19, rmSync as rmSync2, appendFileSync as appendFileSync3 } from "node:fs";
|
|
295483
|
+
import { join as join75 } from "node:path";
|
|
295120
295484
|
async function _immediateReregister(newUrl) {
|
|
295121
295485
|
if (!_lastRegisteredSponsorPayload) return;
|
|
295122
295486
|
_lastRegisteredSponsorPayload.tunnelUrl = newUrl;
|
|
@@ -295629,8 +295993,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
295629
295993
|
if (out.includes("Connected") || out.includes("Already connected")) {
|
|
295630
295994
|
renderInfo(out.split("\n").slice(0, 4).join("\n"));
|
|
295631
295995
|
try {
|
|
295632
|
-
const pidFile =
|
|
295633
|
-
if (
|
|
295996
|
+
const pidFile = join75(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
|
|
295997
|
+
if (existsSync60(pidFile)) {
|
|
295634
295998
|
const pid = parseInt(readFileSync45(pidFile, "utf8").trim(), 10);
|
|
295635
295999
|
if (pid > 0 && !registry2.daemons.has("Nexus")) {
|
|
295636
296000
|
registry2.register({ name: "Nexus", pid, startedAt: Date.now(), status: "running" });
|
|
@@ -295935,18 +296299,18 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
295935
296299
|
let content = "";
|
|
295936
296300
|
let metadata = {};
|
|
295937
296301
|
if (shareType === "tool") {
|
|
295938
|
-
const toolDir =
|
|
295939
|
-
const toolFile =
|
|
295940
|
-
if (!
|
|
296302
|
+
const toolDir = join75(ctx3.repoRoot, ".oa", "tools");
|
|
296303
|
+
const toolFile = join75(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
296304
|
+
if (!existsSync60(toolFile)) {
|
|
295941
296305
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
295942
296306
|
return "handled";
|
|
295943
296307
|
}
|
|
295944
296308
|
content = readFileSync45(toolFile, "utf8");
|
|
295945
296309
|
metadata = { type: "tool", name: shareName };
|
|
295946
296310
|
} else if (shareType === "skill") {
|
|
295947
|
-
const skillDir =
|
|
295948
|
-
const skillFile =
|
|
295949
|
-
if (!
|
|
296311
|
+
const skillDir = join75(ctx3.repoRoot, ".oa", "skills", shareName);
|
|
296312
|
+
const skillFile = join75(skillDir, "SKILL.md");
|
|
296313
|
+
if (!existsSync60(skillFile)) {
|
|
295950
296314
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
295951
296315
|
return "handled";
|
|
295952
296316
|
}
|
|
@@ -295987,8 +296351,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
295987
296351
|
try {
|
|
295988
296352
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
295989
296353
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
295990
|
-
const regFile =
|
|
295991
|
-
if (
|
|
296354
|
+
const regFile = join75(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
296355
|
+
if (existsSync60(regFile)) {
|
|
295992
296356
|
const reg = JSON.parse(readFileSync45(regFile, "utf8"));
|
|
295993
296357
|
const pinned = Object.values(reg).some((e2) => e2.cid === importCid && e2.pinned);
|
|
295994
296358
|
if (pinned) {
|
|
@@ -296040,32 +296404,32 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296040
296404
|
lines.push(`
|
|
296041
296405
|
${c3.bold("IPFS / Helia Status")}
|
|
296042
296406
|
`);
|
|
296043
|
-
const ipfsDir =
|
|
296044
|
-
const ipfsLocalDir =
|
|
296407
|
+
const ipfsDir = join75(ctx3.repoRoot, ".oa", "ipfs");
|
|
296408
|
+
const ipfsLocalDir = join75(ipfsDir, "local");
|
|
296045
296409
|
let ipfsFiles = 0;
|
|
296046
296410
|
let ipfsBytes = 0;
|
|
296047
296411
|
let heliaBlocks = 0;
|
|
296048
296412
|
let heliaBytes = 0;
|
|
296049
296413
|
try {
|
|
296050
|
-
if (
|
|
296414
|
+
if (existsSync60(ipfsLocalDir)) {
|
|
296051
296415
|
const files = readdirSync14(ipfsLocalDir).filter((f2) => f2.endsWith(".json"));
|
|
296052
296416
|
ipfsFiles = files.length;
|
|
296053
296417
|
for (const f2 of files) {
|
|
296054
296418
|
try {
|
|
296055
|
-
ipfsBytes += statSync19(
|
|
296419
|
+
ipfsBytes += statSync19(join75(ipfsLocalDir, f2)).size;
|
|
296056
296420
|
} catch {
|
|
296057
296421
|
}
|
|
296058
296422
|
}
|
|
296059
296423
|
}
|
|
296060
|
-
const heliaBlockDir =
|
|
296061
|
-
if (
|
|
296424
|
+
const heliaBlockDir = join75(ipfsDir, "blocks");
|
|
296425
|
+
if (existsSync60(heliaBlockDir)) {
|
|
296062
296426
|
const walkDir = (dir) => {
|
|
296063
296427
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
296064
|
-
if (entry.isDirectory()) walkDir(
|
|
296428
|
+
if (entry.isDirectory()) walkDir(join75(dir, entry.name));
|
|
296065
296429
|
else {
|
|
296066
296430
|
heliaBlocks++;
|
|
296067
296431
|
try {
|
|
296068
|
-
heliaBytes += statSync19(
|
|
296432
|
+
heliaBytes += statSync19(join75(dir, entry.name)).size;
|
|
296069
296433
|
} catch {
|
|
296070
296434
|
}
|
|
296071
296435
|
}
|
|
@@ -296081,8 +296445,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296081
296445
|
lines.push(` Blocks: ${c3.bold(String(heliaBlocks))} Size: ${c3.bold(formatFileSize(heliaBytes))}`);
|
|
296082
296446
|
lines.push(` Backend: ${heliaBlocks > 0 ? c3.green("helia-ipfs") : c3.yellow("sha256-local (Helia not initialized)")}`);
|
|
296083
296447
|
try {
|
|
296084
|
-
const statusFile =
|
|
296085
|
-
if (
|
|
296448
|
+
const statusFile = join75(ctx3.repoRoot, ".oa", "nexus", "status.json");
|
|
296449
|
+
if (existsSync60(statusFile)) {
|
|
296086
296450
|
const status = JSON.parse(readFileSync45(statusFile, "utf8"));
|
|
296087
296451
|
if (status.peerId) {
|
|
296088
296452
|
lines.push(`
|
|
@@ -296102,10 +296466,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296102
296466
|
${c3.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
296103
296467
|
lines.push(`
|
|
296104
296468
|
${c3.bold("Identity Kernel")}`);
|
|
296105
|
-
const idDir =
|
|
296469
|
+
const idDir = join75(ctx3.repoRoot, ".oa", "identity");
|
|
296106
296470
|
try {
|
|
296107
|
-
const stateFile =
|
|
296108
|
-
if (
|
|
296471
|
+
const stateFile = join75(idDir, "self-state.json");
|
|
296472
|
+
if (existsSync60(stateFile)) {
|
|
296109
296473
|
const state = JSON.parse(readFileSync45(stateFile, "utf8"));
|
|
296110
296474
|
lines.push(` Version: ${c3.bold("v" + (state.version ?? "?"))} Sessions: ${c3.bold(String(state.session_count ?? 0))}`);
|
|
296111
296475
|
if (state.narrative_summary) {
|
|
@@ -296115,8 +296479,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296115
296479
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
296116
296480
|
lines.push(` Traits: ${c3.dim(traits.slice(0, 60))}`);
|
|
296117
296481
|
}
|
|
296118
|
-
const cidFile =
|
|
296119
|
-
if (
|
|
296482
|
+
const cidFile = join75(idDir, "cids.json");
|
|
296483
|
+
if (existsSync60(cidFile)) {
|
|
296120
296484
|
const cids = JSON.parse(readFileSync45(cidFile, "utf8"));
|
|
296121
296485
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
296122
296486
|
if (lastCid) lines.push(` Last CID: ${c3.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -296129,8 +296493,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296129
296493
|
lines.push(`
|
|
296130
296494
|
${c3.bold("Memory Sentiment")}`);
|
|
296131
296495
|
try {
|
|
296132
|
-
const metaFile =
|
|
296133
|
-
if (
|
|
296496
|
+
const metaFile = join75(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
296497
|
+
if (existsSync60(metaFile)) {
|
|
296134
296498
|
const store2 = JSON.parse(readFileSync45(metaFile, "utf8"));
|
|
296135
296499
|
const active = store2.filter((m2) => m2.type !== "quarantine");
|
|
296136
296500
|
const recoveries = active.filter((m2) => m2.content?.startsWith("[recovery]")).length;
|
|
@@ -296149,8 +296513,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296149
296513
|
} catch {
|
|
296150
296514
|
}
|
|
296151
296515
|
try {
|
|
296152
|
-
const dbPath =
|
|
296153
|
-
if (
|
|
296516
|
+
const dbPath = join75(ctx3.repoRoot, ".oa", "memory", "structured.db");
|
|
296517
|
+
if (existsSync60(dbPath)) {
|
|
296154
296518
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
296155
296519
|
const db = initDb2(dbPath);
|
|
296156
296520
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -296171,8 +296535,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296171
296535
|
lines.push(`
|
|
296172
296536
|
${c3.bold("Storage Overview")}
|
|
296173
296537
|
`);
|
|
296174
|
-
const oaDir =
|
|
296175
|
-
if (!
|
|
296538
|
+
const oaDir = join75(ctx3.repoRoot, ".oa");
|
|
296539
|
+
if (!existsSync60(oaDir)) {
|
|
296176
296540
|
lines.push(` ${c3.dim("No .oa/ directory found.")}`);
|
|
296177
296541
|
safeLog(lines.join("\n") + "\n");
|
|
296178
296542
|
return "handled";
|
|
@@ -296182,7 +296546,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296182
296546
|
const walkStorage = (dir, category) => {
|
|
296183
296547
|
try {
|
|
296184
296548
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
296185
|
-
const full =
|
|
296549
|
+
const full = join75(dir, entry.name);
|
|
296186
296550
|
if (entry.isDirectory()) {
|
|
296187
296551
|
const subCat = category || entry.name;
|
|
296188
296552
|
walkStorage(full, subCat);
|
|
@@ -296217,9 +296581,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296217
296581
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
296218
296582
|
const name10 = entry.name.toLowerCase();
|
|
296219
296583
|
if (sensitivePatterns.some((p2) => name10.includes(p2))) {
|
|
296220
|
-
sensitiveFound.push(
|
|
296584
|
+
sensitiveFound.push(join75(dir, entry.name).replace(oaDir + "/", ""));
|
|
296221
296585
|
}
|
|
296222
|
-
if (entry.isDirectory()) checkSensitive(
|
|
296586
|
+
if (entry.isDirectory()) checkSensitive(join75(dir, entry.name));
|
|
296223
296587
|
}
|
|
296224
296588
|
} catch {
|
|
296225
296589
|
}
|
|
@@ -296247,8 +296611,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296247
296611
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
296248
296612
|
return "handled";
|
|
296249
296613
|
}
|
|
296250
|
-
const resolvedPath =
|
|
296251
|
-
if (!
|
|
296614
|
+
const resolvedPath = join75(ctx3.repoRoot, filePath);
|
|
296615
|
+
if (!existsSync60(resolvedPath)) {
|
|
296252
296616
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
296253
296617
|
return "handled";
|
|
296254
296618
|
}
|
|
@@ -296264,9 +296628,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296264
296628
|
}
|
|
296265
296629
|
try {
|
|
296266
296630
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
296267
|
-
const dbDir =
|
|
296268
|
-
|
|
296269
|
-
const db = initDb2(
|
|
296631
|
+
const dbDir = join75(ctx3.repoRoot, ".oa", "memory");
|
|
296632
|
+
mkdirSync31(dbDir, { recursive: true });
|
|
296633
|
+
const db = initDb2(join75(dbDir, "structured.db"));
|
|
296270
296634
|
const memStore = new ProceduralMemoryStore2(db);
|
|
296271
296635
|
if (isAudio) {
|
|
296272
296636
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -296348,9 +296712,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296348
296712
|
}
|
|
296349
296713
|
case "fortemi": {
|
|
296350
296714
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
296351
|
-
const fortemiDir =
|
|
296352
|
-
const altFortemiDir =
|
|
296353
|
-
const fDir =
|
|
296715
|
+
const fortemiDir = join75(ctx3.repoRoot, "..", "fortemi-react");
|
|
296716
|
+
const altFortemiDir = join75(nodeOs.homedir(), "fortemi-react");
|
|
296717
|
+
const fDir = existsSync60(fortemiDir) ? fortemiDir : existsSync60(altFortemiDir) ? altFortemiDir : null;
|
|
296354
296718
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
296355
296719
|
if (!fDir) {
|
|
296356
296720
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -296365,14 +296729,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296365
296729
|
// 24h
|
|
296366
296730
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
296367
296731
|
};
|
|
296368
|
-
const jwtFile =
|
|
296369
|
-
|
|
296732
|
+
const jwtFile = join75(ctx3.repoRoot, ".oa", "fortemi-jwt.json");
|
|
296733
|
+
mkdirSync31(join75(ctx3.repoRoot, ".oa"), { recursive: true });
|
|
296370
296734
|
writeFileSync29(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
296371
296735
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
296372
296736
|
try {
|
|
296373
296737
|
const { spawn: spawn26 } = __require("node:child_process");
|
|
296374
296738
|
const child = spawn26("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
296375
|
-
cwd:
|
|
296739
|
+
cwd: join75(fDir, "apps", "standalone"),
|
|
296376
296740
|
stdio: "ignore",
|
|
296377
296741
|
detached: true,
|
|
296378
296742
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -296381,7 +296745,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296381
296745
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
296382
296746
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
296383
296747
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
296384
|
-
const bridgeFile =
|
|
296748
|
+
const bridgeFile = join75(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
296385
296749
|
writeFileSync29(bridgeFile, JSON.stringify({
|
|
296386
296750
|
url: "http://localhost:3000",
|
|
296387
296751
|
pid: child.pid,
|
|
@@ -296394,8 +296758,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296394
296758
|
return "handled";
|
|
296395
296759
|
}
|
|
296396
296760
|
if (fortemiSubCmd === "status") {
|
|
296397
|
-
const bridgeFile =
|
|
296398
|
-
if (!
|
|
296761
|
+
const bridgeFile = join75(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
296762
|
+
if (!existsSync60(bridgeFile)) {
|
|
296399
296763
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
296400
296764
|
return "handled";
|
|
296401
296765
|
}
|
|
@@ -296419,14 +296783,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
296419
296783
|
lines.push(` Process: ${alive ? c3.green("running") : c3.yellow("not running")} (PID ${bridge.pid})`);
|
|
296420
296784
|
lines.push(` HTTP: ${httpOk ? c3.green("connected") : c3.yellow("unreachable")}`);
|
|
296421
296785
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
296422
|
-
lines.push(` JWT: ${
|
|
296786
|
+
lines.push(` JWT: ${existsSync60(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
|
|
296423
296787
|
lines.push("");
|
|
296424
296788
|
safeLog(lines.join("\n"));
|
|
296425
296789
|
return "handled";
|
|
296426
296790
|
}
|
|
296427
296791
|
if (fortemiSubCmd === "stop") {
|
|
296428
|
-
const bridgeFile =
|
|
296429
|
-
if (
|
|
296792
|
+
const bridgeFile = join75(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
296793
|
+
if (existsSync60(bridgeFile)) {
|
|
296430
296794
|
const bridge = JSON.parse(readFileSync45(bridgeFile, "utf8"));
|
|
296431
296795
|
try {
|
|
296432
296796
|
process.kill(bridge.pid, "SIGTERM");
|
|
@@ -297233,9 +297597,9 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
297233
297597
|
}
|
|
297234
297598
|
}
|
|
297235
297599
|
}
|
|
297236
|
-
const _spLogDir =
|
|
297237
|
-
|
|
297238
|
-
const _spLogFile =
|
|
297600
|
+
const _spLogDir = join75(projectDir, ".oa", "sponsor");
|
|
297601
|
+
mkdirSync31(_spLogDir, { recursive: true });
|
|
297602
|
+
const _spLogFile = join75(_spLogDir, "sponsor-startup.log");
|
|
297239
297603
|
const _spLog = (msg) => {
|
|
297240
297604
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}
|
|
297241
297605
|
`;
|
|
@@ -297345,17 +297709,17 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
297345
297709
|
}
|
|
297346
297710
|
if (!sponsorUrl && !sponsorPeerId) {
|
|
297347
297711
|
_spLog("FAILED \u2014 no tunnelUrl and no peerId");
|
|
297348
|
-
_spLog(`nexusDir checked: ${
|
|
297349
|
-
_spLog(`status.json exists: ${
|
|
297350
|
-
_spLog(`daemon.pid exists: ${
|
|
297712
|
+
_spLog(`nexusDir checked: ${join75(projectDir, ".oa", "nexus")}`);
|
|
297713
|
+
_spLog(`status.json exists: ${existsSync60(join75(projectDir, ".oa", "nexus", "status.json"))}`);
|
|
297714
|
+
_spLog(`daemon.pid exists: ${existsSync60(join75(projectDir, ".oa", "nexus", "daemon.pid"))}`);
|
|
297351
297715
|
try {
|
|
297352
|
-
const _statusRaw = readFileSync45(
|
|
297716
|
+
const _statusRaw = readFileSync45(join75(projectDir, ".oa", "nexus", "status.json"), "utf8");
|
|
297353
297717
|
_spLog(`status.json content: ${_statusRaw.slice(0, 300)}`);
|
|
297354
297718
|
} catch (e2) {
|
|
297355
297719
|
_spLog(`status.json read error: ${e2}`);
|
|
297356
297720
|
}
|
|
297357
297721
|
try {
|
|
297358
|
-
const _errRaw = readFileSync45(
|
|
297722
|
+
const _errRaw = readFileSync45(join75(projectDir, ".oa", "nexus", "daemon.err"), "utf8");
|
|
297359
297723
|
_spLog(`daemon.err (last 500): ${_errRaw.slice(-500)}`);
|
|
297360
297724
|
} catch (e2) {
|
|
297361
297725
|
_spLog(`daemon.err read error: ${e2}`);
|
|
@@ -297374,7 +297738,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
297374
297738
|
try {
|
|
297375
297739
|
const { homedir: homedir30 } = __require("os");
|
|
297376
297740
|
const namePath = __require("path").join(homedir30(), ".open-agents", "agent-name");
|
|
297377
|
-
if (
|
|
297741
|
+
if (existsSync60(namePath)) sponsorName = readFileSync45(namePath, "utf8").trim();
|
|
297378
297742
|
} catch {
|
|
297379
297743
|
}
|
|
297380
297744
|
if (!sponsorName) sponsorName = "OA Sponsor";
|
|
@@ -297449,8 +297813,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
297449
297813
|
if (result) {
|
|
297450
297814
|
renderInfo("Sponsor wizard completed.");
|
|
297451
297815
|
try {
|
|
297452
|
-
const nexusPidFile =
|
|
297453
|
-
if (
|
|
297816
|
+
const nexusPidFile = join75(projectDir, ".oa", "nexus", "daemon.pid");
|
|
297817
|
+
if (existsSync60(nexusPidFile)) {
|
|
297454
297818
|
const nPid = parseInt(readFileSync45(nexusPidFile, "utf8").trim(), 10);
|
|
297455
297819
|
if (nPid > 0) {
|
|
297456
297820
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -298515,13 +298879,13 @@ async function showCohereDashboard(ctx3) {
|
|
|
298515
298879
|
} else if (idResult.key === "view") {
|
|
298516
298880
|
await ik.execute({ operation: "hydrate" });
|
|
298517
298881
|
} else if (idResult.key === "history") {
|
|
298518
|
-
const snapDir =
|
|
298519
|
-
if (
|
|
298882
|
+
const snapDir = join75(ctx3.repoRoot, ".oa", "identity", "snapshots");
|
|
298883
|
+
if (existsSync60(snapDir)) {
|
|
298520
298884
|
const snaps = readdirSync14(snapDir).filter((f2) => f2.endsWith(".json")).sort().reverse();
|
|
298521
298885
|
const snapItems = snaps.slice(0, 20).map((f2) => ({
|
|
298522
298886
|
key: f2,
|
|
298523
298887
|
label: f2.replace(".json", ""),
|
|
298524
|
-
detail: `${formatFileSize(statSync19(
|
|
298888
|
+
detail: `${formatFileSize(statSync19(join75(snapDir, f2)).size)}`
|
|
298525
298889
|
}));
|
|
298526
298890
|
if (snapItems.length > 0) {
|
|
298527
298891
|
await tuiSelect({
|
|
@@ -298832,11 +299196,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
298832
299196
|
continue;
|
|
298833
299197
|
}
|
|
298834
299198
|
const { basename: basename19, join: pathJoin } = await import("node:path");
|
|
298835
|
-
const { copyFileSync: copyFileSync3, mkdirSync:
|
|
299199
|
+
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync46, existsSync: exists2 } = await import("node:fs");
|
|
298836
299200
|
const { homedir: homedir30 } = await import("node:os");
|
|
298837
299201
|
const modelName = basename19(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
298838
299202
|
const destDir = pathJoin(homedir30(), ".open-agents", "voice", "models", modelName);
|
|
298839
|
-
if (!exists2(destDir))
|
|
299203
|
+
if (!exists2(destDir)) mkdirSync46(destDir, { recursive: true });
|
|
298840
299204
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
298841
299205
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
298842
299206
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -299524,10 +299888,10 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
299524
299888
|
}
|
|
299525
299889
|
} catch {
|
|
299526
299890
|
}
|
|
299527
|
-
const sponsorDir2 =
|
|
299528
|
-
const knownFile =
|
|
299891
|
+
const sponsorDir2 = join75(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
299892
|
+
const knownFile = join75(sponsorDir2, "known-sponsors.json");
|
|
299529
299893
|
try {
|
|
299530
|
-
if (
|
|
299894
|
+
if (existsSync60(knownFile)) {
|
|
299531
299895
|
const saved = JSON.parse(readFileSync45(knownFile, "utf8"));
|
|
299532
299896
|
for (const s2 of saved) {
|
|
299533
299897
|
if (!sponsors.some((sp) => sp.url === s2.url)) {
|
|
@@ -299582,8 +299946,8 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
299582
299946
|
sponsors.push(...verified);
|
|
299583
299947
|
if (verified.length > 0) {
|
|
299584
299948
|
try {
|
|
299585
|
-
const { mkdirSync:
|
|
299586
|
-
|
|
299949
|
+
const { mkdirSync: mkdirSync46, writeFileSync: writeFileSync41 } = __require("node:fs");
|
|
299950
|
+
mkdirSync46(sponsorDir2, { recursive: true });
|
|
299587
299951
|
const cached = verified.map((s2) => ({ ...s2, lastVerified: Date.now() }));
|
|
299588
299952
|
writeFileSync41(knownFile, JSON.stringify(cached, null, 2));
|
|
299589
299953
|
} catch {
|
|
@@ -299678,8 +300042,8 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
299678
300042
|
}
|
|
299679
300043
|
const saveKey = selected.url || selected.peerId || selected.name;
|
|
299680
300044
|
try {
|
|
299681
|
-
|
|
299682
|
-
const existing =
|
|
300045
|
+
mkdirSync31(sponsorDir2, { recursive: true });
|
|
300046
|
+
const existing = existsSync60(knownFile) ? JSON.parse(readFileSync45(knownFile, "utf8")) : [];
|
|
299683
300047
|
const updated = existing.filter((s2) => (s2.url || s2.peerId || s2.name) !== saveKey);
|
|
299684
300048
|
updated.push(selected);
|
|
299685
300049
|
writeFileSync29(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
@@ -299750,10 +300114,10 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
299750
300114
|
const models = await fetchModels(peerUrl, authKey);
|
|
299751
300115
|
if (models.length > 0) {
|
|
299752
300116
|
try {
|
|
299753
|
-
const { writeFileSync: writeFileSync41, mkdirSync:
|
|
299754
|
-
const { join:
|
|
299755
|
-
const cachePath =
|
|
299756
|
-
|
|
300117
|
+
const { writeFileSync: writeFileSync41, mkdirSync: mkdirSync46 } = await import("node:fs");
|
|
300118
|
+
const { join: join97, dirname: dirname28 } = await import("node:path");
|
|
300119
|
+
const cachePath = join97(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
300120
|
+
mkdirSync46(dirname28(cachePath), { recursive: true });
|
|
299757
300121
|
writeFileSync41(cachePath, JSON.stringify({
|
|
299758
300122
|
peerId,
|
|
299759
300123
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -299950,17 +300314,17 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
299950
300314
|
try {
|
|
299951
300315
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
299952
300316
|
const { fileURLToPath: fileURLToPath19 } = await import("node:url");
|
|
299953
|
-
const { dirname: dirname28, join:
|
|
299954
|
-
const { existsSync:
|
|
300317
|
+
const { dirname: dirname28, join: join97 } = await import("node:path");
|
|
300318
|
+
const { existsSync: existsSync78 } = await import("node:fs");
|
|
299955
300319
|
const req2 = createRequire7(import.meta.url);
|
|
299956
300320
|
const thisDir = dirname28(fileURLToPath19(import.meta.url));
|
|
299957
300321
|
const candidates = [
|
|
299958
|
-
|
|
299959
|
-
|
|
299960
|
-
|
|
300322
|
+
join97(thisDir, "..", "package.json"),
|
|
300323
|
+
join97(thisDir, "..", "..", "package.json"),
|
|
300324
|
+
join97(thisDir, "..", "..", "..", "package.json")
|
|
299961
300325
|
];
|
|
299962
300326
|
for (const pkgPath of candidates) {
|
|
299963
|
-
if (
|
|
300327
|
+
if (existsSync78(pkgPath)) {
|
|
299964
300328
|
const pkg = req2(pkgPath);
|
|
299965
300329
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
299966
300330
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -301054,8 +301418,8 @@ var init_commands = __esm({
|
|
|
301054
301418
|
});
|
|
301055
301419
|
|
|
301056
301420
|
// packages/cli/src/tui/project-context.ts
|
|
301057
|
-
import { existsSync as
|
|
301058
|
-
import { join as
|
|
301421
|
+
import { existsSync as existsSync61, readFileSync as readFileSync46, readdirSync as readdirSync15 } from "node:fs";
|
|
301422
|
+
import { join as join76, basename as basename13 } from "node:path";
|
|
301059
301423
|
import { execSync as execSync49 } from "node:child_process";
|
|
301060
301424
|
import { homedir as homedir25, platform as platform5, release } from "node:os";
|
|
301061
301425
|
function getModelTier(modelName) {
|
|
@@ -301086,8 +301450,8 @@ function loadProjectMap(repoRoot) {
|
|
|
301086
301450
|
if (!hasOaDirectory(repoRoot)) {
|
|
301087
301451
|
initOaDirectory(repoRoot);
|
|
301088
301452
|
}
|
|
301089
|
-
const mapPath2 =
|
|
301090
|
-
if (
|
|
301453
|
+
const mapPath2 = join76(repoRoot, OA_DIR, "context", "project-map.md");
|
|
301454
|
+
if (existsSync61(mapPath2)) {
|
|
301091
301455
|
try {
|
|
301092
301456
|
const content = readFileSync46(mapPath2, "utf-8");
|
|
301093
301457
|
return content;
|
|
@@ -301128,27 +301492,27 @@ ${log22}`);
|
|
|
301128
301492
|
}
|
|
301129
301493
|
function loadMemoryContext(repoRoot) {
|
|
301130
301494
|
const sections = [];
|
|
301131
|
-
const oaMemDir =
|
|
301495
|
+
const oaMemDir = join76(repoRoot, OA_DIR, "memory");
|
|
301132
301496
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
301133
301497
|
if (oaEntries) sections.push(oaEntries);
|
|
301134
|
-
const legacyMemDir =
|
|
301135
|
-
if (legacyMemDir !== oaMemDir &&
|
|
301498
|
+
const legacyMemDir = join76(repoRoot, ".open-agents", "memory");
|
|
301499
|
+
if (legacyMemDir !== oaMemDir && existsSync61(legacyMemDir)) {
|
|
301136
301500
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
301137
301501
|
if (legacyEntries) sections.push(legacyEntries);
|
|
301138
301502
|
}
|
|
301139
|
-
const globalMemDir =
|
|
301503
|
+
const globalMemDir = join76(homedir25(), ".open-agents", "memory");
|
|
301140
301504
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
301141
301505
|
if (globalEntries) sections.push(globalEntries);
|
|
301142
301506
|
return sections.join("\n\n");
|
|
301143
301507
|
}
|
|
301144
301508
|
function loadMemoryDir(memDir, scope) {
|
|
301145
|
-
if (!
|
|
301509
|
+
if (!existsSync61(memDir)) return "";
|
|
301146
301510
|
const lines = [];
|
|
301147
301511
|
try {
|
|
301148
301512
|
const files = readdirSync15(memDir).filter((f2) => f2.endsWith(".json"));
|
|
301149
301513
|
for (const file of files.slice(0, 10)) {
|
|
301150
301514
|
try {
|
|
301151
|
-
const raw = readFileSync46(
|
|
301515
|
+
const raw = readFileSync46(join76(memDir, file), "utf-8");
|
|
301152
301516
|
const entries = JSON.parse(raw);
|
|
301153
301517
|
const topic = basename13(file, ".json");
|
|
301154
301518
|
const keys = Object.keys(entries);
|
|
@@ -301650,8 +302014,8 @@ __export(banner_exports, {
|
|
|
301650
302014
|
saveBannerDesign: () => saveBannerDesign,
|
|
301651
302015
|
setGridText: () => setGridText
|
|
301652
302016
|
});
|
|
301653
|
-
import { existsSync as
|
|
301654
|
-
import { join as
|
|
302017
|
+
import { existsSync as existsSync62, readFileSync as readFileSync47, writeFileSync as writeFileSync30, mkdirSync as mkdirSync32 } from "node:fs";
|
|
302018
|
+
import { join as join77 } from "node:path";
|
|
301655
302019
|
function generateMnemonic(seed) {
|
|
301656
302020
|
let h = 2166136261;
|
|
301657
302021
|
for (let i2 = 0; i2 < seed.length; i2++) {
|
|
@@ -301781,13 +302145,13 @@ function createSponsorBanner(sponsorName, tagline, primaryColor = 214, bgColor =
|
|
|
301781
302145
|
};
|
|
301782
302146
|
}
|
|
301783
302147
|
function saveBannerDesign(workDir, design) {
|
|
301784
|
-
const dir =
|
|
301785
|
-
|
|
301786
|
-
writeFileSync30(
|
|
302148
|
+
const dir = join77(workDir, ".oa", "banners");
|
|
302149
|
+
mkdirSync32(dir, { recursive: true });
|
|
302150
|
+
writeFileSync30(join77(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
|
|
301787
302151
|
}
|
|
301788
302152
|
function loadBannerDesign(workDir, id) {
|
|
301789
|
-
const file =
|
|
301790
|
-
if (!
|
|
302153
|
+
const file = join77(workDir, ".oa", "banners", `${id}.json`);
|
|
302154
|
+
if (!existsSync62(file)) return null;
|
|
301791
302155
|
try {
|
|
301792
302156
|
return JSON.parse(readFileSync47(file, "utf8"));
|
|
301793
302157
|
} catch {
|
|
@@ -301795,8 +302159,8 @@ function loadBannerDesign(workDir, id) {
|
|
|
301795
302159
|
}
|
|
301796
302160
|
}
|
|
301797
302161
|
function listBannerDesigns(workDir) {
|
|
301798
|
-
const dir =
|
|
301799
|
-
if (!
|
|
302162
|
+
const dir = join77(workDir, ".oa", "banners");
|
|
302163
|
+
if (!existsSync62(dir)) return [];
|
|
301800
302164
|
try {
|
|
301801
302165
|
const { readdirSync: readdirSync26 } = __require("node:fs");
|
|
301802
302166
|
return readdirSync26(dir).filter((f2) => f2.endsWith(".json")).map((f2) => f2.replace(".json", ""));
|
|
@@ -302103,21 +302467,21 @@ var init_banner = __esm({
|
|
|
302103
302467
|
});
|
|
302104
302468
|
|
|
302105
302469
|
// packages/cli/src/tui/carousel-descriptors.ts
|
|
302106
|
-
import { existsSync as
|
|
302107
|
-
import { join as
|
|
302470
|
+
import { existsSync as existsSync63, readFileSync as readFileSync48, writeFileSync as writeFileSync31, mkdirSync as mkdirSync33, readdirSync as readdirSync16 } from "node:fs";
|
|
302471
|
+
import { join as join78, basename as basename14 } from "node:path";
|
|
302108
302472
|
function loadToolProfile(repoRoot) {
|
|
302109
|
-
const filePath =
|
|
302473
|
+
const filePath = join78(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
302110
302474
|
try {
|
|
302111
|
-
if (!
|
|
302475
|
+
if (!existsSync63(filePath)) return null;
|
|
302112
302476
|
return JSON.parse(readFileSync48(filePath, "utf-8"));
|
|
302113
302477
|
} catch {
|
|
302114
302478
|
return null;
|
|
302115
302479
|
}
|
|
302116
302480
|
}
|
|
302117
302481
|
function saveToolProfile(repoRoot, profile) {
|
|
302118
|
-
const contextDir =
|
|
302119
|
-
|
|
302120
|
-
writeFileSync31(
|
|
302482
|
+
const contextDir = join78(repoRoot, OA_DIR, "context");
|
|
302483
|
+
mkdirSync33(contextDir, { recursive: true });
|
|
302484
|
+
writeFileSync31(join78(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
302121
302485
|
}
|
|
302122
302486
|
function categorizeToolCall(toolName) {
|
|
302123
302487
|
for (const cat2 of TOOL_CATEGORIES) {
|
|
@@ -302172,9 +302536,9 @@ function weightedColor(profile) {
|
|
|
302172
302536
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
302173
302537
|
}
|
|
302174
302538
|
function loadCachedDescriptors(repoRoot) {
|
|
302175
|
-
const filePath =
|
|
302539
|
+
const filePath = join78(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
302176
302540
|
try {
|
|
302177
|
-
if (!
|
|
302541
|
+
if (!existsSync63(filePath)) return null;
|
|
302178
302542
|
const cached = JSON.parse(readFileSync48(filePath, "utf-8"));
|
|
302179
302543
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
302180
302544
|
} catch {
|
|
@@ -302182,14 +302546,14 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
302182
302546
|
}
|
|
302183
302547
|
}
|
|
302184
302548
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
302185
|
-
const contextDir =
|
|
302186
|
-
|
|
302549
|
+
const contextDir = join78(repoRoot, OA_DIR, "context");
|
|
302550
|
+
mkdirSync33(contextDir, { recursive: true });
|
|
302187
302551
|
const cached = {
|
|
302188
302552
|
phrases,
|
|
302189
302553
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
302190
302554
|
sourceHash
|
|
302191
302555
|
};
|
|
302192
|
-
writeFileSync31(
|
|
302556
|
+
writeFileSync31(join78(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
302193
302557
|
}
|
|
302194
302558
|
function generateDescriptors(repoRoot) {
|
|
302195
302559
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -302236,9 +302600,9 @@ function generateDescriptors(repoRoot) {
|
|
|
302236
302600
|
return phrases;
|
|
302237
302601
|
}
|
|
302238
302602
|
function extractFromPackageJson(repoRoot, tags) {
|
|
302239
|
-
const pkgPath =
|
|
302603
|
+
const pkgPath = join78(repoRoot, "package.json");
|
|
302240
302604
|
try {
|
|
302241
|
-
if (!
|
|
302605
|
+
if (!existsSync63(pkgPath)) return;
|
|
302242
302606
|
const pkg = JSON.parse(readFileSync48(pkgPath, "utf-8"));
|
|
302243
302607
|
if (pkg.name && typeof pkg.name === "string") {
|
|
302244
302608
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
@@ -302280,7 +302644,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
302280
302644
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
302281
302645
|
];
|
|
302282
302646
|
for (const check of manifestChecks) {
|
|
302283
|
-
if (
|
|
302647
|
+
if (existsSync63(join78(repoRoot, check.file))) {
|
|
302284
302648
|
tags.push(check.tag);
|
|
302285
302649
|
}
|
|
302286
302650
|
}
|
|
@@ -302302,15 +302666,15 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
302302
302666
|
}
|
|
302303
302667
|
}
|
|
302304
302668
|
function extractFromMemory(repoRoot, tags) {
|
|
302305
|
-
const memoryDir =
|
|
302669
|
+
const memoryDir = join78(repoRoot, OA_DIR, "memory");
|
|
302306
302670
|
try {
|
|
302307
|
-
if (!
|
|
302671
|
+
if (!existsSync63(memoryDir)) return;
|
|
302308
302672
|
const files = readdirSync16(memoryDir).filter((f2) => f2.endsWith(".json"));
|
|
302309
302673
|
for (const file of files) {
|
|
302310
302674
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
302311
302675
|
tags.push(topic);
|
|
302312
302676
|
try {
|
|
302313
|
-
const data = JSON.parse(readFileSync48(
|
|
302677
|
+
const data = JSON.parse(readFileSync48(join78(memoryDir, file), "utf-8"));
|
|
302314
302678
|
if (data && typeof data === "object") {
|
|
302315
302679
|
const keys = Object.keys(data).slice(0, 3);
|
|
302316
302680
|
for (const key of keys) {
|
|
@@ -303004,13 +303368,13 @@ var init_stream_renderer = __esm({
|
|
|
303004
303368
|
});
|
|
303005
303369
|
|
|
303006
303370
|
// packages/cli/src/tui/edit-history.ts
|
|
303007
|
-
import { appendFileSync as appendFileSync4, mkdirSync as
|
|
303008
|
-
import { join as
|
|
303371
|
+
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync34 } from "node:fs";
|
|
303372
|
+
import { join as join79 } from "node:path";
|
|
303009
303373
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
303010
|
-
const historyDir =
|
|
303011
|
-
const logPath2 =
|
|
303374
|
+
const historyDir = join79(repoRoot, ".oa", "history");
|
|
303375
|
+
const logPath2 = join79(historyDir, "edits.jsonl");
|
|
303012
303376
|
try {
|
|
303013
|
-
|
|
303377
|
+
mkdirSync34(historyDir, { recursive: true });
|
|
303014
303378
|
} catch {
|
|
303015
303379
|
}
|
|
303016
303380
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -303118,14 +303482,14 @@ var init_edit_history = __esm({
|
|
|
303118
303482
|
});
|
|
303119
303483
|
|
|
303120
303484
|
// packages/cli/src/tui/promptLoader.ts
|
|
303121
|
-
import { readFileSync as readFileSync49, existsSync as
|
|
303122
|
-
import { join as
|
|
303485
|
+
import { readFileSync as readFileSync49, existsSync as existsSync64 } from "node:fs";
|
|
303486
|
+
import { join as join80, dirname as dirname23 } from "node:path";
|
|
303123
303487
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
303124
303488
|
function loadPrompt3(promptPath, vars) {
|
|
303125
303489
|
let content = cache6.get(promptPath);
|
|
303126
303490
|
if (content === void 0) {
|
|
303127
|
-
const fullPath =
|
|
303128
|
-
if (!
|
|
303491
|
+
const fullPath = join80(PROMPTS_DIR3, promptPath);
|
|
303492
|
+
if (!existsSync64(fullPath)) {
|
|
303129
303493
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
303130
303494
|
}
|
|
303131
303495
|
content = readFileSync49(fullPath, "utf-8");
|
|
@@ -303140,16 +303504,16 @@ var init_promptLoader3 = __esm({
|
|
|
303140
303504
|
"use strict";
|
|
303141
303505
|
__filename5 = fileURLToPath14(import.meta.url);
|
|
303142
303506
|
__dirname7 = dirname23(__filename5);
|
|
303143
|
-
devPath2 =
|
|
303144
|
-
publishedPath2 =
|
|
303145
|
-
PROMPTS_DIR3 =
|
|
303507
|
+
devPath2 = join80(__dirname7, "..", "..", "prompts");
|
|
303508
|
+
publishedPath2 = join80(__dirname7, "..", "prompts");
|
|
303509
|
+
PROMPTS_DIR3 = existsSync64(devPath2) ? devPath2 : publishedPath2;
|
|
303146
303510
|
cache6 = /* @__PURE__ */ new Map();
|
|
303147
303511
|
}
|
|
303148
303512
|
});
|
|
303149
303513
|
|
|
303150
303514
|
// packages/cli/src/tui/dream-engine.ts
|
|
303151
|
-
import { mkdirSync as
|
|
303152
|
-
import { join as
|
|
303515
|
+
import { mkdirSync as mkdirSync35, writeFileSync as writeFileSync32, readFileSync as readFileSync50, existsSync as existsSync65, readdirSync as readdirSync17 } from "node:fs";
|
|
303516
|
+
import { join as join81, basename as basename15 } from "node:path";
|
|
303153
303517
|
import { execSync as execSync50 } from "node:child_process";
|
|
303154
303518
|
function setDreamWriteContent(fn) {
|
|
303155
303519
|
_dreamWriteContent = fn;
|
|
@@ -303162,8 +303526,8 @@ function dreamWrite(fn) {
|
|
|
303162
303526
|
}
|
|
303163
303527
|
}
|
|
303164
303528
|
function loadAutoresearchMemory(repoRoot) {
|
|
303165
|
-
const memoryPath =
|
|
303166
|
-
if (!
|
|
303529
|
+
const memoryPath = join81(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
303530
|
+
if (!existsSync65(memoryPath)) return "";
|
|
303167
303531
|
try {
|
|
303168
303532
|
const raw = readFileSync50(memoryPath, "utf-8");
|
|
303169
303533
|
const data = JSON.parse(raw);
|
|
@@ -303361,13 +303725,13 @@ var init_dream_engine = __esm({
|
|
|
303361
303725
|
const rawPath = String(args["path"] ?? "");
|
|
303362
303726
|
const content = String(args["content"] ?? "");
|
|
303363
303727
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
303364
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
303728
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join81(this.autoresearchDir, basename15(rawPath)) : join81(this.autoresearchDir, rawPath);
|
|
303365
303729
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
303366
303730
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
303367
303731
|
}
|
|
303368
303732
|
try {
|
|
303369
|
-
const dir =
|
|
303370
|
-
|
|
303733
|
+
const dir = join81(targetPath, "..");
|
|
303734
|
+
mkdirSync35(dir, { recursive: true });
|
|
303371
303735
|
writeFileSync32(targetPath, content, "utf-8");
|
|
303372
303736
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
|
|
303373
303737
|
} catch (err) {
|
|
@@ -303395,12 +303759,12 @@ var init_dream_engine = __esm({
|
|
|
303395
303759
|
const rawPath = String(args["path"] ?? "");
|
|
303396
303760
|
const oldStr = String(args["old_string"] ?? "");
|
|
303397
303761
|
const newStr = String(args["new_string"] ?? "");
|
|
303398
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
303762
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join81(this.autoresearchDir, basename15(rawPath)) : join81(this.autoresearchDir, rawPath);
|
|
303399
303763
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
303400
303764
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
303401
303765
|
}
|
|
303402
303766
|
try {
|
|
303403
|
-
if (!
|
|
303767
|
+
if (!existsSync65(targetPath)) {
|
|
303404
303768
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
303405
303769
|
}
|
|
303406
303770
|
let content = readFileSync50(targetPath, "utf-8");
|
|
@@ -303447,13 +303811,13 @@ var init_dream_engine = __esm({
|
|
|
303447
303811
|
const rawPath = String(args["path"] ?? "");
|
|
303448
303812
|
const content = String(args["content"] ?? "");
|
|
303449
303813
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
303450
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
303814
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join81(this.dreamsDir, basename15(rawPath)) : join81(this.dreamsDir, rawPath);
|
|
303451
303815
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
303452
303816
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
303453
303817
|
}
|
|
303454
303818
|
try {
|
|
303455
|
-
const dir =
|
|
303456
|
-
|
|
303819
|
+
const dir = join81(targetPath, "..");
|
|
303820
|
+
mkdirSync35(dir, { recursive: true });
|
|
303457
303821
|
writeFileSync32(targetPath, content, "utf-8");
|
|
303458
303822
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
|
|
303459
303823
|
} catch (err) {
|
|
@@ -303481,12 +303845,12 @@ var init_dream_engine = __esm({
|
|
|
303481
303845
|
const rawPath = String(args["path"] ?? "");
|
|
303482
303846
|
const oldStr = String(args["old_string"] ?? "");
|
|
303483
303847
|
const newStr = String(args["new_string"] ?? "");
|
|
303484
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
303848
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join81(this.dreamsDir, basename15(rawPath)) : join81(this.dreamsDir, rawPath);
|
|
303485
303849
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
303486
303850
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
303487
303851
|
}
|
|
303488
303852
|
try {
|
|
303489
|
-
if (!
|
|
303853
|
+
if (!existsSync65(targetPath)) {
|
|
303490
303854
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
303491
303855
|
}
|
|
303492
303856
|
let content = readFileSync50(targetPath, "utf-8");
|
|
@@ -303542,7 +303906,7 @@ var init_dream_engine = __esm({
|
|
|
303542
303906
|
constructor(config, repoRoot) {
|
|
303543
303907
|
this.config = config;
|
|
303544
303908
|
this.repoRoot = repoRoot;
|
|
303545
|
-
this.dreamsDir =
|
|
303909
|
+
this.dreamsDir = join81(repoRoot, ".oa", "dreams");
|
|
303546
303910
|
this.state = {
|
|
303547
303911
|
mode: "default",
|
|
303548
303912
|
active: false,
|
|
@@ -303579,7 +303943,7 @@ var init_dream_engine = __esm({
|
|
|
303579
303943
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
303580
303944
|
results: []
|
|
303581
303945
|
};
|
|
303582
|
-
|
|
303946
|
+
mkdirSync35(this.dreamsDir, { recursive: true });
|
|
303583
303947
|
this.saveDreamState();
|
|
303584
303948
|
try {
|
|
303585
303949
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -303651,7 +304015,7 @@ ${result.summary}`;
|
|
|
303651
304015
|
if (mode !== "default" || cycle === totalCycles) {
|
|
303652
304016
|
renderDreamContraction(cycle);
|
|
303653
304017
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
303654
|
-
const summaryPath =
|
|
304018
|
+
const summaryPath = join81(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
303655
304019
|
writeFileSync32(summaryPath, cycleSummary, "utf-8");
|
|
303656
304020
|
}
|
|
303657
304021
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
@@ -303891,7 +304255,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
|
|
|
303891
304255
|
}
|
|
303892
304256
|
/** Build role-specific tool sets for swarm agents */
|
|
303893
304257
|
buildSwarmTools(role, _workspace) {
|
|
303894
|
-
const autoresearchDir =
|
|
304258
|
+
const autoresearchDir = join81(this.repoRoot, ".oa", "autoresearch");
|
|
303895
304259
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
303896
304260
|
switch (role) {
|
|
303897
304261
|
case "researcher": {
|
|
@@ -304290,7 +304654,7 @@ Call task_complete with a human-readable summary of the autoresearch session.`,
|
|
|
304290
304654
|
workspace,
|
|
304291
304655
|
onEvent
|
|
304292
304656
|
);
|
|
304293
|
-
const reportPath =
|
|
304657
|
+
const reportPath = join81(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
304294
304658
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
304295
304659
|
|
|
304296
304660
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -304312,7 +304676,7 @@ ${summaryResult}
|
|
|
304312
304676
|
*Generated by open-agents autoresearch swarm*
|
|
304313
304677
|
`;
|
|
304314
304678
|
try {
|
|
304315
|
-
|
|
304679
|
+
mkdirSync35(this.dreamsDir, { recursive: true });
|
|
304316
304680
|
writeFileSync32(reportPath, report, "utf-8");
|
|
304317
304681
|
} catch {
|
|
304318
304682
|
}
|
|
@@ -304379,9 +304743,9 @@ ${summaryResult}
|
|
|
304379
304743
|
}
|
|
304380
304744
|
/** Save workspace backup for lucid mode */
|
|
304381
304745
|
saveVersionCheckpoint(cycle) {
|
|
304382
|
-
const checkpointDir =
|
|
304746
|
+
const checkpointDir = join81(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
304383
304747
|
try {
|
|
304384
|
-
|
|
304748
|
+
mkdirSync35(checkpointDir, { recursive: true });
|
|
304385
304749
|
try {
|
|
304386
304750
|
const gitStatus = execSync50("git status --porcelain", {
|
|
304387
304751
|
cwd: this.repoRoot,
|
|
@@ -304398,11 +304762,11 @@ ${summaryResult}
|
|
|
304398
304762
|
encoding: "utf-8",
|
|
304399
304763
|
timeout: 5e3
|
|
304400
304764
|
}).trim();
|
|
304401
|
-
writeFileSync32(
|
|
304402
|
-
writeFileSync32(
|
|
304403
|
-
writeFileSync32(
|
|
304765
|
+
writeFileSync32(join81(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
304766
|
+
writeFileSync32(join81(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
304767
|
+
writeFileSync32(join81(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
304404
304768
|
writeFileSync32(
|
|
304405
|
-
|
|
304769
|
+
join81(checkpointDir, "checkpoint.json"),
|
|
304406
304770
|
JSON.stringify({
|
|
304407
304771
|
cycle,
|
|
304408
304772
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -304414,7 +304778,7 @@ ${summaryResult}
|
|
|
304414
304778
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
304415
304779
|
} catch {
|
|
304416
304780
|
writeFileSync32(
|
|
304417
|
-
|
|
304781
|
+
join81(checkpointDir, "checkpoint.json"),
|
|
304418
304782
|
JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2),
|
|
304419
304783
|
"utf-8"
|
|
304420
304784
|
);
|
|
@@ -304475,7 +304839,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
|
|
|
304475
304839
|
---
|
|
304476
304840
|
*Auto-generated by open-agents dream engine*
|
|
304477
304841
|
`;
|
|
304478
|
-
writeFileSync32(
|
|
304842
|
+
writeFileSync32(join81(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
304479
304843
|
} catch {
|
|
304480
304844
|
}
|
|
304481
304845
|
}
|
|
@@ -304496,8 +304860,8 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
|
|
|
304496
304860
|
results: []
|
|
304497
304861
|
};
|
|
304498
304862
|
renderInfo("Memory consolidation starting \u2014 Phase 1: Orient \u2192 Phase 2: Gather \u2192 Phase 3: Consolidate \u2192 Phase 4: Prune");
|
|
304499
|
-
const memoryDir =
|
|
304500
|
-
|
|
304863
|
+
const memoryDir = join81(this.repoRoot, ".oa", "memory");
|
|
304864
|
+
mkdirSync35(memoryDir, { recursive: true });
|
|
304501
304865
|
let prompt;
|
|
304502
304866
|
try {
|
|
304503
304867
|
prompt = loadPrompt3("tui/dream-consolidate.md", {
|
|
@@ -304562,7 +304926,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
|
|
|
304562
304926
|
});
|
|
304563
304927
|
try {
|
|
304564
304928
|
writeFileSync32(
|
|
304565
|
-
|
|
304929
|
+
join81(memoryDir, ".last-consolidation"),
|
|
304566
304930
|
JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), summary: result.summary?.slice(0, 500) }) + "\n"
|
|
304567
304931
|
);
|
|
304568
304932
|
} catch {
|
|
@@ -304580,7 +304944,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
|
|
|
304580
304944
|
saveDreamState() {
|
|
304581
304945
|
try {
|
|
304582
304946
|
writeFileSync32(
|
|
304583
|
-
|
|
304947
|
+
join81(this.dreamsDir, "dream-state.json"),
|
|
304584
304948
|
JSON.stringify(this.state, null, 2) + "\n",
|
|
304585
304949
|
"utf-8"
|
|
304586
304950
|
);
|
|
@@ -304950,8 +305314,8 @@ var init_bless_engine = __esm({
|
|
|
304950
305314
|
});
|
|
304951
305315
|
|
|
304952
305316
|
// packages/cli/src/tui/dmn-engine.ts
|
|
304953
|
-
import { existsSync as
|
|
304954
|
-
import { join as
|
|
305317
|
+
import { existsSync as existsSync66, readFileSync as readFileSync51, writeFileSync as writeFileSync33, mkdirSync as mkdirSync36, readdirSync as readdirSync18, unlinkSync as unlinkSync15 } from "node:fs";
|
|
305318
|
+
import { join as join82, basename as basename16 } from "node:path";
|
|
304955
305319
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
304956
305320
|
const competenceReport = competence.length > 0 ? competence.map((c7) => {
|
|
304957
305321
|
const rate = c7.attempts > 0 ? Math.round(c7.successes / c7.attempts * 100) : 0;
|
|
@@ -305055,9 +305419,9 @@ var init_dmn_engine = __esm({
|
|
|
305055
305419
|
constructor(config, repoRoot) {
|
|
305056
305420
|
this.config = config;
|
|
305057
305421
|
this.repoRoot = repoRoot;
|
|
305058
|
-
this.stateDir =
|
|
305059
|
-
this.historyDir =
|
|
305060
|
-
|
|
305422
|
+
this.stateDir = join82(repoRoot, ".oa", "dmn");
|
|
305423
|
+
this.historyDir = join82(repoRoot, ".oa", "dmn", "cycles");
|
|
305424
|
+
mkdirSync36(this.historyDir, { recursive: true });
|
|
305061
305425
|
this.loadState();
|
|
305062
305426
|
}
|
|
305063
305427
|
state = {
|
|
@@ -305689,11 +306053,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305689
306053
|
async gatherMemoryTopics() {
|
|
305690
306054
|
const topics = [];
|
|
305691
306055
|
const dirs = [
|
|
305692
|
-
|
|
305693
|
-
|
|
306056
|
+
join82(this.repoRoot, ".oa", "memory"),
|
|
306057
|
+
join82(this.repoRoot, ".open-agents", "memory")
|
|
305694
306058
|
];
|
|
305695
306059
|
for (const dir of dirs) {
|
|
305696
|
-
if (!
|
|
306060
|
+
if (!existsSync66(dir)) continue;
|
|
305697
306061
|
try {
|
|
305698
306062
|
const files = readdirSync18(dir).filter((f2) => f2.endsWith(".json"));
|
|
305699
306063
|
for (const f2 of files) {
|
|
@@ -305707,8 +306071,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305707
306071
|
}
|
|
305708
306072
|
// ── State persistence ─────────────────────────────────────────────────
|
|
305709
306073
|
loadState() {
|
|
305710
|
-
const path5 =
|
|
305711
|
-
if (
|
|
306074
|
+
const path5 = join82(this.stateDir, "state.json");
|
|
306075
|
+
if (existsSync66(path5)) {
|
|
305712
306076
|
try {
|
|
305713
306077
|
this.state = JSON.parse(readFileSync51(path5, "utf-8"));
|
|
305714
306078
|
} catch {
|
|
@@ -305718,7 +306082,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305718
306082
|
saveState() {
|
|
305719
306083
|
try {
|
|
305720
306084
|
writeFileSync33(
|
|
305721
|
-
|
|
306085
|
+
join82(this.stateDir, "state.json"),
|
|
305722
306086
|
JSON.stringify(this.state, null, 2) + "\n",
|
|
305723
306087
|
"utf-8"
|
|
305724
306088
|
);
|
|
@@ -305729,7 +306093,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305729
306093
|
try {
|
|
305730
306094
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
305731
306095
|
writeFileSync33(
|
|
305732
|
-
|
|
306096
|
+
join82(this.historyDir, filename),
|
|
305733
306097
|
JSON.stringify(result, null, 2) + "\n",
|
|
305734
306098
|
"utf-8"
|
|
305735
306099
|
);
|
|
@@ -305737,7 +306101,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305737
306101
|
if (files.length > 50) {
|
|
305738
306102
|
for (const old of files.slice(0, files.length - 50)) {
|
|
305739
306103
|
try {
|
|
305740
|
-
unlinkSync15(
|
|
306104
|
+
unlinkSync15(join82(this.historyDir, old));
|
|
305741
306105
|
} catch {
|
|
305742
306106
|
}
|
|
305743
306107
|
}
|
|
@@ -305750,8 +306114,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
305750
306114
|
});
|
|
305751
306115
|
|
|
305752
306116
|
// packages/cli/src/tui/snr-engine.ts
|
|
305753
|
-
import { existsSync as
|
|
305754
|
-
import { join as
|
|
306117
|
+
import { existsSync as existsSync67, readdirSync as readdirSync19, readFileSync as readFileSync52 } from "node:fs";
|
|
306118
|
+
import { join as join83, basename as basename17 } from "node:path";
|
|
305755
306119
|
function computeDPrime(signalScores, noiseScores) {
|
|
305756
306120
|
if (signalScores.length === 0 || noiseScores.length === 0) return 0;
|
|
305757
306121
|
const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
|
|
@@ -306035,18 +306399,18 @@ Call task_complete with the JSON array when done.`,
|
|
|
306035
306399
|
loadMemoryEntries(topics) {
|
|
306036
306400
|
const entries = [];
|
|
306037
306401
|
const dirs = [
|
|
306038
|
-
|
|
306039
|
-
|
|
306402
|
+
join83(this.repoRoot, ".oa", "memory"),
|
|
306403
|
+
join83(this.repoRoot, ".open-agents", "memory")
|
|
306040
306404
|
];
|
|
306041
306405
|
for (const dir of dirs) {
|
|
306042
|
-
if (!
|
|
306406
|
+
if (!existsSync67(dir)) continue;
|
|
306043
306407
|
try {
|
|
306044
306408
|
const files = readdirSync19(dir).filter((f2) => f2.endsWith(".json"));
|
|
306045
306409
|
for (const f2 of files) {
|
|
306046
306410
|
const topic = basename17(f2, ".json");
|
|
306047
306411
|
if (topics.length > 0 && !topics.includes(topic)) continue;
|
|
306048
306412
|
try {
|
|
306049
|
-
const data = JSON.parse(readFileSync52(
|
|
306413
|
+
const data = JSON.parse(readFileSync52(join83(dir, f2), "utf-8"));
|
|
306050
306414
|
for (const [key, val] of Object.entries(data)) {
|
|
306051
306415
|
const value2 = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
306052
306416
|
entries.push({ topic, key, value: value2 });
|
|
@@ -306590,8 +306954,8 @@ var init_tool_policy = __esm({
|
|
|
306590
306954
|
});
|
|
306591
306955
|
|
|
306592
306956
|
// packages/cli/src/tui/telegram-bridge.ts
|
|
306593
|
-
import { mkdirSync as
|
|
306594
|
-
import { join as
|
|
306957
|
+
import { mkdirSync as mkdirSync37, unlinkSync as unlinkSync16 } from "node:fs";
|
|
306958
|
+
import { join as join84, resolve as resolve32 } from "node:path";
|
|
306595
306959
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
306596
306960
|
function convertMarkdownToTelegramHTML(md) {
|
|
306597
306961
|
let html = md;
|
|
@@ -306914,7 +307278,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
306914
307278
|
this.polling = true;
|
|
306915
307279
|
this.abortController = new AbortController();
|
|
306916
307280
|
try {
|
|
306917
|
-
|
|
307281
|
+
mkdirSync37(this.mediaCacheDir, { recursive: true });
|
|
306918
307282
|
} catch {
|
|
306919
307283
|
}
|
|
306920
307284
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -307347,7 +307711,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
307347
307711
|
if (!res.ok) return null;
|
|
307348
307712
|
const buffer2 = Buffer.from(await res.arrayBuffer());
|
|
307349
307713
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension2}`;
|
|
307350
|
-
const localPath =
|
|
307714
|
+
const localPath = join84(this.mediaCacheDir, fileName);
|
|
307351
307715
|
await writeFileAsync(localPath, buffer2);
|
|
307352
307716
|
return localPath;
|
|
307353
307717
|
} catch {
|
|
@@ -308262,13 +308626,13 @@ var init_direct_input = __esm({
|
|
|
308262
308626
|
});
|
|
308263
308627
|
|
|
308264
308628
|
// packages/cli/src/api/audit-log.ts
|
|
308265
|
-
import { mkdirSync as
|
|
308266
|
-
import { join as
|
|
308629
|
+
import { mkdirSync as mkdirSync38, appendFileSync as appendFileSync5, readFileSync as readFileSync53, existsSync as existsSync69 } from "node:fs";
|
|
308630
|
+
import { join as join85 } from "node:path";
|
|
308267
308631
|
function initAuditLog(oaDir) {
|
|
308268
|
-
auditDir =
|
|
308269
|
-
auditFile =
|
|
308632
|
+
auditDir = join85(oaDir, "audit");
|
|
308633
|
+
auditFile = join85(auditDir, "audit.jsonl");
|
|
308270
308634
|
try {
|
|
308271
|
-
|
|
308635
|
+
mkdirSync38(auditDir, { recursive: true });
|
|
308272
308636
|
initialized = true;
|
|
308273
308637
|
} catch {
|
|
308274
308638
|
}
|
|
@@ -308282,7 +308646,7 @@ function recordAudit(record) {
|
|
|
308282
308646
|
}
|
|
308283
308647
|
}
|
|
308284
308648
|
function queryAudit(opts) {
|
|
308285
|
-
if (!initialized || !
|
|
308649
|
+
if (!initialized || !existsSync69(auditFile)) return [];
|
|
308286
308650
|
try {
|
|
308287
308651
|
const raw = readFileSync53(auditFile, "utf-8");
|
|
308288
308652
|
const lines = raw.split("\n").filter(Boolean);
|
|
@@ -309603,32 +309967,32 @@ var init_auth_oidc = __esm({
|
|
|
309603
309967
|
});
|
|
309604
309968
|
|
|
309605
309969
|
// packages/cli/src/api/chat-session.ts
|
|
309606
|
-
import { randomUUID as
|
|
309607
|
-
import { existsSync as
|
|
309608
|
-
import { join as
|
|
309970
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
309971
|
+
import { existsSync as existsSync70, readFileSync as readFileSync54, readdirSync as readdirSync21 } from "node:fs";
|
|
309972
|
+
import { join as join86 } from "node:path";
|
|
309609
309973
|
function buildSystemPrompt(cwd4) {
|
|
309610
309974
|
const parts = [];
|
|
309611
309975
|
parts.push(
|
|
309612
309976
|
"You are Open Agent (OA), an AI coding assistant running locally via Ollama. You have access to the user's workspace and can discuss code, files, and projects. Be helpful, concise, and technically precise. When asked about files or code, describe what you know from the conversation context."
|
|
309613
309977
|
);
|
|
309614
309978
|
parts.push(`\\nEnvironment: ${process.platform}, Node ${process.version}, CWD: ${cwd4}`);
|
|
309615
|
-
const diaryPath =
|
|
309616
|
-
if (
|
|
309979
|
+
const diaryPath = join86(cwd4, ".oa", "context", "session-diary.md");
|
|
309980
|
+
if (existsSync70(diaryPath)) {
|
|
309617
309981
|
try {
|
|
309618
309982
|
const diary = readFileSync54(diaryPath, "utf-8").slice(0, 1e3);
|
|
309619
309983
|
parts.push(`\\nPrevious session history:\\n${diary}`);
|
|
309620
309984
|
} catch {
|
|
309621
309985
|
}
|
|
309622
309986
|
}
|
|
309623
|
-
const memDir =
|
|
309624
|
-
if (
|
|
309987
|
+
const memDir = join86(cwd4, ".oa", "memory");
|
|
309988
|
+
if (existsSync70(memDir)) {
|
|
309625
309989
|
try {
|
|
309626
309990
|
const files = readdirSync21(memDir).filter((f2) => f2.endsWith(".json")).slice(0, 5);
|
|
309627
309991
|
if (files.length > 0) {
|
|
309628
309992
|
parts.push("\\nPersistent memory topics: " + files.map((f2) => f2.replace(".json", "")).join(", "));
|
|
309629
309993
|
for (const f2 of files.slice(0, 3)) {
|
|
309630
309994
|
try {
|
|
309631
|
-
const data = JSON.parse(readFileSync54(
|
|
309995
|
+
const data = JSON.parse(readFileSync54(join86(memDir, f2), "utf-8"));
|
|
309632
309996
|
const entries = Object.entries(data).slice(0, 3);
|
|
309633
309997
|
if (entries.length > 0) {
|
|
309634
309998
|
parts.push(`\\nMemory [${f2.replace(".json", "")}]: ` + entries.map(([k, v]) => `${k}: ${String(v.value ?? v).slice(0, 100)}`).join("; "));
|
|
@@ -309641,8 +310005,8 @@ function buildSystemPrompt(cwd4) {
|
|
|
309641
310005
|
}
|
|
309642
310006
|
}
|
|
309643
310007
|
for (const name10 of ["AGENTS.md", "OA.md", ".open-agents.md"]) {
|
|
309644
|
-
const p2 =
|
|
309645
|
-
if (
|
|
310008
|
+
const p2 = join86(cwd4, name10);
|
|
310009
|
+
if (existsSync70(p2)) {
|
|
309646
310010
|
try {
|
|
309647
310011
|
const content = readFileSync54(p2, "utf-8").slice(0, 500);
|
|
309648
310012
|
parts.push(`\\nProject instructions (${name10}):\\n${content}`);
|
|
@@ -309658,7 +310022,7 @@ function getSession(sessionId, model, cwd4) {
|
|
|
309658
310022
|
s2.lastActivity = Date.now();
|
|
309659
310023
|
return s2;
|
|
309660
310024
|
}
|
|
309661
|
-
const id = sessionId ||
|
|
310025
|
+
const id = sessionId || randomUUID6();
|
|
309662
310026
|
const systemPrompt = buildSystemPrompt(cwd4);
|
|
309663
310027
|
const session = {
|
|
309664
310028
|
id,
|
|
@@ -309720,14 +310084,14 @@ var init_chat_session = __esm({
|
|
|
309720
310084
|
});
|
|
309721
310085
|
|
|
309722
310086
|
// packages/cli/src/api/usage-tracker.ts
|
|
309723
|
-
import { mkdirSync as
|
|
309724
|
-
import { join as
|
|
310087
|
+
import { mkdirSync as mkdirSync39, readFileSync as readFileSync55, writeFileSync as writeFileSync34, existsSync as existsSync71 } from "node:fs";
|
|
310088
|
+
import { join as join87 } from "node:path";
|
|
309725
310089
|
function initUsageTracker(oaDir) {
|
|
309726
|
-
const dir =
|
|
309727
|
-
|
|
309728
|
-
usageFile =
|
|
310090
|
+
const dir = join87(oaDir, "usage");
|
|
310091
|
+
mkdirSync39(dir, { recursive: true });
|
|
310092
|
+
usageFile = join87(dir, "token-usage.json");
|
|
309729
310093
|
try {
|
|
309730
|
-
if (
|
|
310094
|
+
if (existsSync71(usageFile)) {
|
|
309731
310095
|
store = JSON.parse(readFileSync55(usageFile, "utf-8"));
|
|
309732
310096
|
}
|
|
309733
310097
|
} catch {
|
|
@@ -309792,24 +310156,24 @@ var init_usage_tracker = __esm({
|
|
|
309792
310156
|
});
|
|
309793
310157
|
|
|
309794
310158
|
// packages/cli/src/api/profiles.ts
|
|
309795
|
-
import { existsSync as
|
|
309796
|
-
import { join as
|
|
310159
|
+
import { existsSync as existsSync72, readFileSync as readFileSync56, writeFileSync as writeFileSync35, mkdirSync as mkdirSync40, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
|
|
310160
|
+
import { join as join88 } from "node:path";
|
|
309797
310161
|
import { homedir as homedir26 } from "node:os";
|
|
309798
310162
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
|
|
309799
310163
|
function globalProfileDir() {
|
|
309800
|
-
return
|
|
310164
|
+
return join88(homedir26(), ".open-agents", "profiles");
|
|
309801
310165
|
}
|
|
309802
310166
|
function projectProfileDir(projectDir) {
|
|
309803
|
-
return
|
|
310167
|
+
return join88(projectDir || process.cwd(), ".oa", "profiles");
|
|
309804
310168
|
}
|
|
309805
310169
|
function listProfiles(projectDir) {
|
|
309806
310170
|
const result = [];
|
|
309807
310171
|
const seen = /* @__PURE__ */ new Set();
|
|
309808
310172
|
const projDir = projectProfileDir(projectDir);
|
|
309809
|
-
if (
|
|
310173
|
+
if (existsSync72(projDir)) {
|
|
309810
310174
|
for (const f2 of readdirSync22(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
309811
310175
|
try {
|
|
309812
|
-
const raw = JSON.parse(readFileSync56(
|
|
310176
|
+
const raw = JSON.parse(readFileSync56(join88(projDir, f2), "utf8"));
|
|
309813
310177
|
const name10 = f2.replace(".json", "");
|
|
309814
310178
|
seen.add(name10);
|
|
309815
310179
|
result.push({
|
|
@@ -309823,12 +310187,12 @@ function listProfiles(projectDir) {
|
|
|
309823
310187
|
}
|
|
309824
310188
|
}
|
|
309825
310189
|
const globDir = globalProfileDir();
|
|
309826
|
-
if (
|
|
310190
|
+
if (existsSync72(globDir)) {
|
|
309827
310191
|
for (const f2 of readdirSync22(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
309828
310192
|
const name10 = f2.replace(".json", "");
|
|
309829
310193
|
if (seen.has(name10)) continue;
|
|
309830
310194
|
try {
|
|
309831
|
-
const raw = JSON.parse(readFileSync56(
|
|
310195
|
+
const raw = JSON.parse(readFileSync56(join88(globDir, f2), "utf8"));
|
|
309832
310196
|
result.push({
|
|
309833
310197
|
name: name10,
|
|
309834
310198
|
description: raw.description || "",
|
|
@@ -309843,9 +310207,9 @@ function listProfiles(projectDir) {
|
|
|
309843
310207
|
}
|
|
309844
310208
|
function loadProfile(name10, password, projectDir) {
|
|
309845
310209
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
309846
|
-
const projPath =
|
|
309847
|
-
const globPath =
|
|
309848
|
-
const filePath =
|
|
310210
|
+
const projPath = join88(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
310211
|
+
const globPath = join88(globalProfileDir(), `${sanitized}.json`);
|
|
310212
|
+
const filePath = existsSync72(projPath) ? projPath : existsSync72(globPath) ? globPath : null;
|
|
309849
310213
|
if (!filePath) return null;
|
|
309850
310214
|
const raw = JSON.parse(readFileSync56(filePath, "utf8"));
|
|
309851
310215
|
if (raw.encrypted === true) {
|
|
@@ -309856,9 +310220,9 @@ function loadProfile(name10, password, projectDir) {
|
|
|
309856
310220
|
}
|
|
309857
310221
|
function saveProfile(profile, password, scope = "global", projectDir) {
|
|
309858
310222
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
309859
|
-
|
|
310223
|
+
mkdirSync40(dir, { recursive: true });
|
|
309860
310224
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
309861
|
-
const filePath =
|
|
310225
|
+
const filePath = join88(dir, `${sanitized}.json`);
|
|
309862
310226
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
309863
310227
|
if (password) {
|
|
309864
310228
|
const encrypted = encryptProfile(profile, password);
|
|
@@ -309871,8 +310235,8 @@ function saveProfile(profile, password, scope = "global", projectDir) {
|
|
|
309871
310235
|
function deleteProfile(name10, scope = "global", projectDir) {
|
|
309872
310236
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
309873
310237
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
309874
|
-
const filePath =
|
|
309875
|
-
if (
|
|
310238
|
+
const filePath = join88(dir, `${sanitized}.json`);
|
|
310239
|
+
if (existsSync72(filePath)) {
|
|
309876
310240
|
unlinkSync17(filePath);
|
|
309877
310241
|
return true;
|
|
309878
310242
|
}
|
|
@@ -309987,23 +310351,23 @@ var init_profiles = __esm({
|
|
|
309987
310351
|
|
|
309988
310352
|
// packages/cli/src/docker.ts
|
|
309989
310353
|
import { execSync as execSync51, spawn as spawn23 } from "node:child_process";
|
|
309990
|
-
import { existsSync as
|
|
309991
|
-
import { join as
|
|
310354
|
+
import { existsSync as existsSync73, mkdirSync as mkdirSync41, writeFileSync as writeFileSync36 } from "node:fs";
|
|
310355
|
+
import { join as join89, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
309992
310356
|
import { homedir as homedir27 } from "node:os";
|
|
309993
310357
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
309994
310358
|
function getDockerDir() {
|
|
309995
310359
|
try {
|
|
309996
310360
|
if (typeof __dirname !== "undefined") {
|
|
309997
|
-
return
|
|
310361
|
+
return join89(__dirname, "..", "..", "..", "docker");
|
|
309998
310362
|
}
|
|
309999
310363
|
} catch {
|
|
310000
310364
|
}
|
|
310001
310365
|
try {
|
|
310002
310366
|
const thisDir = dirname24(fileURLToPath15(import.meta.url));
|
|
310003
|
-
return
|
|
310367
|
+
return join89(thisDir, "..", "..", "..", "docker");
|
|
310004
310368
|
} catch {
|
|
310005
310369
|
}
|
|
310006
|
-
return
|
|
310370
|
+
return join89(process.cwd(), "docker");
|
|
310007
310371
|
}
|
|
310008
310372
|
function isDockerAvailable() {
|
|
310009
310373
|
try {
|
|
@@ -310134,11 +310498,11 @@ async function ensureOaImage(force = false) {
|
|
|
310134
310498
|
}
|
|
310135
310499
|
let buildContext;
|
|
310136
310500
|
const dockerDir = getDockerDir();
|
|
310137
|
-
if (
|
|
310501
|
+
if (existsSync73(join89(dockerDir, "Dockerfile"))) {
|
|
310138
310502
|
buildContext = dockerDir;
|
|
310139
310503
|
} else {
|
|
310140
|
-
buildContext =
|
|
310141
|
-
|
|
310504
|
+
buildContext = join89(homedir27(), ".oa", "docker-build");
|
|
310505
|
+
mkdirSync41(buildContext, { recursive: true });
|
|
310142
310506
|
writeDockerfiles(buildContext);
|
|
310143
310507
|
}
|
|
310144
310508
|
try {
|
|
@@ -310212,8 +310576,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
|
|
|
310212
310576
|
if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
|
|
310213
310577
|
exec "$@"
|
|
310214
310578
|
`;
|
|
310215
|
-
writeFileSync36(
|
|
310216
|
-
writeFileSync36(
|
|
310579
|
+
writeFileSync36(join89(dir, "Dockerfile"), dockerfile);
|
|
310580
|
+
writeFileSync36(join89(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
310217
310581
|
}
|
|
310218
310582
|
function hasNvidiaGpu() {
|
|
310219
310583
|
try {
|
|
@@ -310290,22 +310654,22 @@ import * as http5 from "node:http";
|
|
|
310290
310654
|
import * as https3 from "node:https";
|
|
310291
310655
|
import { createRequire as createRequire4 } from "node:module";
|
|
310292
310656
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
310293
|
-
import { dirname as dirname25, join as
|
|
310657
|
+
import { dirname as dirname25, join as join90, resolve as resolve34 } from "node:path";
|
|
310294
310658
|
import { spawn as spawn24, execSync as execSync52 } from "node:child_process";
|
|
310295
|
-
import { mkdirSync as
|
|
310296
|
-
import { randomBytes as randomBytes19, randomUUID as
|
|
310659
|
+
import { mkdirSync as mkdirSync42, writeFileSync as writeFileSync37, readFileSync as readFileSync57, readdirSync as readdirSync23, existsSync as existsSync74 } from "node:fs";
|
|
310660
|
+
import { randomBytes as randomBytes19, randomUUID as randomUUID7 } from "node:crypto";
|
|
310297
310661
|
function getVersion3() {
|
|
310298
310662
|
try {
|
|
310299
310663
|
const require3 = createRequire4(import.meta.url);
|
|
310300
310664
|
const thisDir = dirname25(fileURLToPath16(import.meta.url));
|
|
310301
310665
|
const candidates = [
|
|
310302
|
-
|
|
310303
|
-
|
|
310304
|
-
|
|
310666
|
+
join90(thisDir, "..", "package.json"),
|
|
310667
|
+
join90(thisDir, "..", "..", "package.json"),
|
|
310668
|
+
join90(thisDir, "..", "..", "..", "package.json")
|
|
310305
310669
|
];
|
|
310306
310670
|
for (const pkgPath of candidates) {
|
|
310307
310671
|
try {
|
|
310308
|
-
if (!
|
|
310672
|
+
if (!existsSync74(pkgPath)) continue;
|
|
310309
310673
|
const pkg = require3(pkgPath);
|
|
310310
310674
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
310311
310675
|
return pkg.version ?? "0.0.0";
|
|
@@ -310594,13 +310958,13 @@ function ollamaStream(ollamaUrl, path5, method, body, onData, onEnd, onError) {
|
|
|
310594
310958
|
}
|
|
310595
310959
|
function jobsDir() {
|
|
310596
310960
|
const root = resolve34(process.cwd());
|
|
310597
|
-
const dir =
|
|
310598
|
-
|
|
310961
|
+
const dir = join90(root, ".oa", "jobs");
|
|
310962
|
+
mkdirSync42(dir, { recursive: true });
|
|
310599
310963
|
return dir;
|
|
310600
310964
|
}
|
|
310601
310965
|
function loadJob(id) {
|
|
310602
|
-
const file =
|
|
310603
|
-
if (!
|
|
310966
|
+
const file = join90(jobsDir(), `${id}.json`);
|
|
310967
|
+
if (!existsSync74(file)) return null;
|
|
310604
310968
|
try {
|
|
310605
310969
|
return JSON.parse(readFileSync57(file, "utf-8"));
|
|
310606
310970
|
} catch {
|
|
@@ -310609,12 +310973,12 @@ function loadJob(id) {
|
|
|
310609
310973
|
}
|
|
310610
310974
|
function listJobs() {
|
|
310611
310975
|
const dir = jobsDir();
|
|
310612
|
-
if (!
|
|
310976
|
+
if (!existsSync74(dir)) return [];
|
|
310613
310977
|
const files = readdirSync23(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
310614
310978
|
const jobs = [];
|
|
310615
310979
|
for (const file of files) {
|
|
310616
310980
|
try {
|
|
310617
|
-
jobs.push(JSON.parse(readFileSync57(
|
|
310981
|
+
jobs.push(JSON.parse(readFileSync57(join90(dir, file), "utf-8")));
|
|
310618
310982
|
} catch {
|
|
310619
310983
|
}
|
|
310620
310984
|
}
|
|
@@ -311088,8 +311452,8 @@ async function handleV1Run(req2, res) {
|
|
|
311088
311452
|
if (workingDir) {
|
|
311089
311453
|
cwd4 = resolve34(workingDir);
|
|
311090
311454
|
} else if (isolate) {
|
|
311091
|
-
const wsDir =
|
|
311092
|
-
|
|
311455
|
+
const wsDir = join90(dir, "..", "workspaces", id);
|
|
311456
|
+
mkdirSync42(wsDir, { recursive: true });
|
|
311093
311457
|
cwd4 = wsDir;
|
|
311094
311458
|
} else {
|
|
311095
311459
|
cwd4 = resolve34(process.cwd());
|
|
@@ -311173,7 +311537,7 @@ async function handleV1Run(req2, res) {
|
|
|
311173
311537
|
job.sandbox = sandbox;
|
|
311174
311538
|
}
|
|
311175
311539
|
job.pid = child.pid ?? 0;
|
|
311176
|
-
writeFileSync37(
|
|
311540
|
+
writeFileSync37(join90(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311177
311541
|
runningProcesses.set(id, child);
|
|
311178
311542
|
if (streamMode) {
|
|
311179
311543
|
res.writeHead(200, {
|
|
@@ -311200,7 +311564,7 @@ async function handleV1Run(req2, res) {
|
|
|
311200
311564
|
job.status = code8 === 0 ? "completed" : "failed";
|
|
311201
311565
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
311202
311566
|
try {
|
|
311203
|
-
writeFileSync37(
|
|
311567
|
+
writeFileSync37(join90(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311204
311568
|
} catch {
|
|
311205
311569
|
}
|
|
311206
311570
|
runningProcesses.delete(id);
|
|
@@ -311240,7 +311604,7 @@ async function handleV1Run(req2, res) {
|
|
|
311240
311604
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
311241
311605
|
}
|
|
311242
311606
|
try {
|
|
311243
|
-
writeFileSync37(
|
|
311607
|
+
writeFileSync37(join90(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311244
311608
|
} catch {
|
|
311245
311609
|
}
|
|
311246
311610
|
runningProcesses.delete(id);
|
|
@@ -311308,7 +311672,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
311308
311672
|
job.error = "Aborted via API";
|
|
311309
311673
|
const dir = jobsDir();
|
|
311310
311674
|
try {
|
|
311311
|
-
writeFileSync37(
|
|
311675
|
+
writeFileSync37(join90(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311312
311676
|
} catch {
|
|
311313
311677
|
}
|
|
311314
311678
|
runningProcesses.delete(id);
|
|
@@ -311442,7 +311806,7 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
311442
311806
|
const urlObj = new URL(req2.url ?? "/", `http://${req2.headers.host ?? "localhost"}`);
|
|
311443
311807
|
const pathname = urlObj.pathname;
|
|
311444
311808
|
const startMs = performance.now();
|
|
311445
|
-
const requestId = req2.headers["x-request-id"] ||
|
|
311809
|
+
const requestId = req2.headers["x-request-id"] || randomUUID7();
|
|
311446
311810
|
res.setHeader("X-Request-ID", requestId);
|
|
311447
311811
|
if (method === "OPTIONS") {
|
|
311448
311812
|
if (!corsHeaders(req2, res)) return;
|
|
@@ -311973,18 +312337,18 @@ function startApiServer(options2 = {}) {
|
|
|
311973
312337
|
const config = loadConfig();
|
|
311974
312338
|
const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
|
|
311975
312339
|
const cwd4 = process.cwd();
|
|
311976
|
-
initAuditLog(
|
|
311977
|
-
initUsageTracker(
|
|
312340
|
+
initAuditLog(join90(cwd4, ".oa"));
|
|
312341
|
+
initUsageTracker(join90(cwd4, ".oa"));
|
|
311978
312342
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
311979
312343
|
if (retentionDays > 0) {
|
|
311980
312344
|
try {
|
|
311981
|
-
const jobsDir3 =
|
|
311982
|
-
if (
|
|
312345
|
+
const jobsDir3 = join90(cwd4, ".oa", "jobs");
|
|
312346
|
+
if (existsSync74(jobsDir3)) {
|
|
311983
312347
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
311984
312348
|
for (const f2 of readdirSync23(jobsDir3)) {
|
|
311985
312349
|
if (!f2.endsWith(".json")) continue;
|
|
311986
312350
|
try {
|
|
311987
|
-
const jobPath =
|
|
312351
|
+
const jobPath = join90(jobsDir3, f2);
|
|
311988
312352
|
const job = JSON.parse(readFileSync57(jobPath, "utf-8"));
|
|
311989
312353
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
311990
312354
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
@@ -312204,11 +312568,11 @@ var init_serve = __esm({
|
|
|
312204
312568
|
|
|
312205
312569
|
// packages/cli/src/tui/interactive.ts
|
|
312206
312570
|
import { cwd } from "node:process";
|
|
312207
|
-
import { resolve as resolve35, join as
|
|
312571
|
+
import { resolve as resolve35, join as join91, dirname as dirname26, extname as extname11 } from "node:path";
|
|
312208
312572
|
import { createRequire as createRequire5 } from "node:module";
|
|
312209
312573
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
312210
|
-
import { readFileSync as readFileSync58, writeFileSync as writeFileSync38, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as
|
|
312211
|
-
import { existsSync as
|
|
312574
|
+
import { readFileSync as readFileSync58, writeFileSync as writeFileSync38, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync43 } from "node:fs";
|
|
312575
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
312212
312576
|
import { execSync as execSync53 } from "node:child_process";
|
|
312213
312577
|
import { homedir as homedir28 } from "node:os";
|
|
312214
312578
|
function formatTimeAgo(date) {
|
|
@@ -312226,12 +312590,12 @@ function getVersion4() {
|
|
|
312226
312590
|
const require3 = createRequire5(import.meta.url);
|
|
312227
312591
|
const thisDir = dirname26(fileURLToPath17(import.meta.url));
|
|
312228
312592
|
const candidates = [
|
|
312229
|
-
|
|
312230
|
-
|
|
312231
|
-
|
|
312593
|
+
join91(thisDir, "..", "package.json"),
|
|
312594
|
+
join91(thisDir, "..", "..", "package.json"),
|
|
312595
|
+
join91(thisDir, "..", "..", "..", "package.json")
|
|
312232
312596
|
];
|
|
312233
312597
|
for (const pkgPath of candidates) {
|
|
312234
|
-
if (
|
|
312598
|
+
if (existsSync75(pkgPath)) {
|
|
312235
312599
|
const pkg = require3(pkgPath);
|
|
312236
312600
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
312237
312601
|
return pkg.version ?? "0.0.0";
|
|
@@ -312735,14 +313099,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
|
|
|
312735
313099
|
function gatherMemorySnippets(root) {
|
|
312736
313100
|
const snippets = [];
|
|
312737
313101
|
const dirs = [
|
|
312738
|
-
|
|
312739
|
-
|
|
313102
|
+
join91(root, ".oa", "memory"),
|
|
313103
|
+
join91(root, ".open-agents", "memory")
|
|
312740
313104
|
];
|
|
312741
313105
|
for (const dir of dirs) {
|
|
312742
|
-
if (!
|
|
313106
|
+
if (!existsSync75(dir)) continue;
|
|
312743
313107
|
try {
|
|
312744
313108
|
for (const f2 of readdirSync24(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
312745
|
-
const data = JSON.parse(readFileSync58(
|
|
313109
|
+
const data = JSON.parse(readFileSync58(join91(dir, f2), "utf-8"));
|
|
312746
313110
|
for (const val of Object.values(data)) {
|
|
312747
313111
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
312748
313112
|
if (v.length > 10) snippets.push(v);
|
|
@@ -312896,8 +313260,8 @@ ${metabolismMemories}
|
|
|
312896
313260
|
} catch {
|
|
312897
313261
|
}
|
|
312898
313262
|
try {
|
|
312899
|
-
const archeFile =
|
|
312900
|
-
if (
|
|
313263
|
+
const archeFile = join91(repoRoot, ".oa", "arche", "variants.json");
|
|
313264
|
+
if (existsSync75(archeFile)) {
|
|
312901
313265
|
const variants = JSON.parse(readFileSync58(archeFile, "utf8"));
|
|
312902
313266
|
if (variants.length > 0) {
|
|
312903
313267
|
let filtered = variants;
|
|
@@ -313067,8 +313431,8 @@ RULES:
|
|
|
313067
313431
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
313068
313432
|
let identityInjection = "";
|
|
313069
313433
|
try {
|
|
313070
|
-
const ikStateFile =
|
|
313071
|
-
if (
|
|
313434
|
+
const ikStateFile = join91(repoRoot, ".oa", "identity", "self-state.json");
|
|
313435
|
+
if (existsSync75(ikStateFile)) {
|
|
313072
313436
|
const selfState = JSON.parse(readFileSync58(ikStateFile, "utf8"));
|
|
313073
313437
|
const lines = [
|
|
313074
313438
|
`[Identity State v${selfState.version}]`,
|
|
@@ -313797,13 +314161,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
313797
314161
|
});
|
|
313798
314162
|
}
|
|
313799
314163
|
try {
|
|
313800
|
-
const ikDir =
|
|
313801
|
-
const ikFile =
|
|
314164
|
+
const ikDir = join91(repoRoot, ".oa", "identity");
|
|
314165
|
+
const ikFile = join91(ikDir, "self-state.json");
|
|
313802
314166
|
let ikState;
|
|
313803
|
-
if (
|
|
314167
|
+
if (existsSync75(ikFile)) {
|
|
313804
314168
|
ikState = JSON.parse(readFileSync58(ikFile, "utf8"));
|
|
313805
314169
|
} else {
|
|
313806
|
-
|
|
314170
|
+
mkdirSync43(ikDir, { recursive: true });
|
|
313807
314171
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
313808
314172
|
ikState = {
|
|
313809
314173
|
self_id: `oa-${machineId}`,
|
|
@@ -313878,8 +314242,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
313878
314242
|
} else {
|
|
313879
314243
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
313880
314244
|
try {
|
|
313881
|
-
const ikFile =
|
|
313882
|
-
if (
|
|
314245
|
+
const ikFile = join91(repoRoot, ".oa", "identity", "self-state.json");
|
|
314246
|
+
if (existsSync75(ikFile)) {
|
|
313883
314247
|
const ikState = JSON.parse(readFileSync58(ikFile, "utf8"));
|
|
313884
314248
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
313885
314249
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -314006,9 +314370,9 @@ async function startInteractive(config, repoPath) {
|
|
|
314006
314370
|
process.stdin.pause();
|
|
314007
314371
|
}
|
|
314008
314372
|
try {
|
|
314009
|
-
const oaDir =
|
|
314010
|
-
const nexusPidFile =
|
|
314011
|
-
if (
|
|
314373
|
+
const oaDir = join91(repoRoot, ".oa");
|
|
314374
|
+
const nexusPidFile = join91(oaDir, "nexus", "daemon.pid");
|
|
314375
|
+
if (existsSync75(nexusPidFile)) {
|
|
314012
314376
|
const pid = parseInt(readFileSync58(nexusPidFile, "utf8").trim(), 10);
|
|
314013
314377
|
if (pid > 0) {
|
|
314014
314378
|
try {
|
|
@@ -314554,7 +314918,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
|
|
|
314554
314918
|
let p2pGateway = null;
|
|
314555
314919
|
let peerMesh = null;
|
|
314556
314920
|
let inferenceRouter = null;
|
|
314557
|
-
const secretVault = new SecretVault(
|
|
314921
|
+
const secretVault = new SecretVault(join91(repoRoot, ".oa", "vault.enc"));
|
|
314558
314922
|
let adminSessionKey = null;
|
|
314559
314923
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
314560
314924
|
const streamRenderer = new StreamRenderer();
|
|
@@ -314773,12 +315137,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
314773
315137
|
const hits = allCompletions.filter((c7) => c7.toLowerCase().startsWith(lower));
|
|
314774
315138
|
return [hits, line];
|
|
314775
315139
|
}
|
|
314776
|
-
const HISTORY_DIR =
|
|
314777
|
-
const HISTORY_FILE =
|
|
315140
|
+
const HISTORY_DIR = join91(homedir28(), ".open-agents");
|
|
315141
|
+
const HISTORY_FILE = join91(HISTORY_DIR, "repl-history");
|
|
314778
315142
|
const MAX_HISTORY_LINES = 500;
|
|
314779
315143
|
let savedHistory = [];
|
|
314780
315144
|
try {
|
|
314781
|
-
if (
|
|
315145
|
+
if (existsSync75(HISTORY_FILE)) {
|
|
314782
315146
|
const raw = readFileSync58(HISTORY_FILE, "utf8").trim();
|
|
314783
315147
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
314784
315148
|
}
|
|
@@ -314904,7 +315268,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
314904
315268
|
function persistHistoryLine(line) {
|
|
314905
315269
|
if (!line.trim()) return;
|
|
314906
315270
|
try {
|
|
314907
|
-
|
|
315271
|
+
mkdirSync43(HISTORY_DIR, { recursive: true });
|
|
314908
315272
|
appendFileSync6(HISTORY_FILE, line + "\n", "utf8");
|
|
314909
315273
|
if (Math.random() < 0.02) {
|
|
314910
315274
|
const all2 = readFileSync58(HISTORY_FILE, "utf8").trim().split("\n");
|
|
@@ -315083,10 +315447,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315083
315447
|
const { unlinkSync: _rmStale } = await import("node:fs");
|
|
315084
315448
|
const { homedir: _hdir } = await import("node:os");
|
|
315085
315449
|
for (const dp of [
|
|
315086
|
-
|
|
315087
|
-
|
|
315450
|
+
join91(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
315451
|
+
join91(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
315088
315452
|
]) {
|
|
315089
|
-
if (
|
|
315453
|
+
if (existsSync75(dp)) try {
|
|
315090
315454
|
_rmStale(dp);
|
|
315091
315455
|
} catch {
|
|
315092
315456
|
}
|
|
@@ -315097,8 +315461,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315097
315461
|
const autoNexus = new NexusTool(repoRoot);
|
|
315098
315462
|
const _registerNexusDaemon = () => {
|
|
315099
315463
|
try {
|
|
315100
|
-
const nexusPidFile =
|
|
315101
|
-
if (
|
|
315464
|
+
const nexusPidFile = join91(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
315465
|
+
if (existsSync75(nexusPidFile)) {
|
|
315102
315466
|
const nPid = parseInt(readFileSync58(nexusPidFile, "utf8").trim(), 10);
|
|
315103
315467
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
315104
315468
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -315146,7 +315510,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315146
315510
|
} catch {
|
|
315147
315511
|
}
|
|
315148
315512
|
try {
|
|
315149
|
-
const oaDir =
|
|
315513
|
+
const oaDir = join91(repoRoot, ".oa");
|
|
315150
315514
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
315151
315515
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
315152
315516
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -315178,7 +315542,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315178
315542
|
} catch {
|
|
315179
315543
|
}
|
|
315180
315544
|
try {
|
|
315181
|
-
const oaDir =
|
|
315545
|
+
const oaDir = join91(repoRoot, ".oa");
|
|
315182
315546
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
315183
315547
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
315184
315548
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -315219,10 +315583,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315219
315583
|
}
|
|
315220
315584
|
try {
|
|
315221
315585
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
315222
|
-
const globalNamePath =
|
|
315586
|
+
const globalNamePath = join91(_hd(), ".open-agents", "agent-name");
|
|
315223
315587
|
let agName = "";
|
|
315224
315588
|
try {
|
|
315225
|
-
if (
|
|
315589
|
+
if (existsSync75(globalNamePath)) agName = readFileSync58(globalNamePath, "utf8").trim();
|
|
315226
315590
|
} catch {
|
|
315227
315591
|
}
|
|
315228
315592
|
if (!agName) {
|
|
@@ -315251,10 +315615,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
315251
315615
|
}
|
|
315252
315616
|
if (!ollamaAlive) {
|
|
315253
315617
|
try {
|
|
315254
|
-
const savedSponsorsPath =
|
|
315618
|
+
const savedSponsorsPath = join91(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
315255
315619
|
let savedSponsors = [];
|
|
315256
315620
|
try {
|
|
315257
|
-
if (
|
|
315621
|
+
if (existsSync75(savedSponsorsPath)) {
|
|
315258
315622
|
savedSponsors = JSON.parse(readFileSync58(savedSponsorsPath, "utf8"));
|
|
315259
315623
|
const oneHourAgo = Date.now() - 36e5;
|
|
315260
315624
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
@@ -316213,7 +316577,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316213
316577
|
kind,
|
|
316214
316578
|
targetUrl,
|
|
316215
316579
|
authKey,
|
|
316216
|
-
stateDir:
|
|
316580
|
+
stateDir: join91(repoRoot, ".oa"),
|
|
316217
316581
|
passthrough: passthrough ?? false,
|
|
316218
316582
|
loadbalance: loadbalance ?? false,
|
|
316219
316583
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -316259,7 +316623,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316259
316623
|
await tunnelGateway.stop();
|
|
316260
316624
|
tunnelGateway = null;
|
|
316261
316625
|
}
|
|
316262
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
316626
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join91(repoRoot, ".oa") });
|
|
316263
316627
|
newTunnel.on("stats", (stats) => {
|
|
316264
316628
|
statusBar.setExposeStatus({
|
|
316265
316629
|
status: stats.status,
|
|
@@ -316346,8 +316710,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316346
316710
|
});
|
|
316347
316711
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
316348
316712
|
try {
|
|
316349
|
-
const nexusPidFile =
|
|
316350
|
-
if (
|
|
316713
|
+
const nexusPidFile = join91(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
316714
|
+
if (existsSync75(nexusPidFile)) {
|
|
316351
316715
|
const pid = parseInt(readFileSync58(nexusPidFile, "utf8").trim(), 10);
|
|
316352
316716
|
if (pid > 0) {
|
|
316353
316717
|
registry2.register({
|
|
@@ -316534,9 +316898,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316534
316898
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
316535
316899
|
}
|
|
316536
316900
|
try {
|
|
316537
|
-
const nexusDir =
|
|
316538
|
-
const pidFile =
|
|
316539
|
-
if (
|
|
316901
|
+
const nexusDir = join91(repoRoot, OA_DIR, "nexus");
|
|
316902
|
+
const pidFile = join91(nexusDir, "daemon.pid");
|
|
316903
|
+
if (existsSync75(pidFile)) {
|
|
316540
316904
|
const pid = parseInt(readFileSync58(pidFile, "utf8").trim(), 10);
|
|
316541
316905
|
if (pid > 0) {
|
|
316542
316906
|
try {
|
|
@@ -316559,11 +316923,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316559
316923
|
} catch {
|
|
316560
316924
|
}
|
|
316561
316925
|
try {
|
|
316562
|
-
const voiceDir2 =
|
|
316926
|
+
const voiceDir2 = join91(homedir28(), ".open-agents", "voice");
|
|
316563
316927
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
316564
316928
|
for (const pf of voicePidFiles) {
|
|
316565
|
-
const pidPath =
|
|
316566
|
-
if (
|
|
316929
|
+
const pidPath = join91(voiceDir2, pf);
|
|
316930
|
+
if (existsSync75(pidPath)) {
|
|
316567
316931
|
try {
|
|
316568
316932
|
const pid = parseInt(readFileSync58(pidPath, "utf8").trim(), 10);
|
|
316569
316933
|
if (pid > 0) {
|
|
@@ -316589,8 +316953,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316589
316953
|
execSync53(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
316590
316954
|
} catch {
|
|
316591
316955
|
}
|
|
316592
|
-
const oaPath =
|
|
316593
|
-
if (
|
|
316956
|
+
const oaPath = join91(repoRoot, OA_DIR);
|
|
316957
|
+
if (existsSync75(oaPath)) {
|
|
316594
316958
|
let deleted = false;
|
|
316595
316959
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
316596
316960
|
try {
|
|
@@ -316672,18 +317036,18 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
316672
317036
|
try {
|
|
316673
317037
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
316674
317038
|
if (isPersonaPlexRunning2()) {
|
|
316675
|
-
const ppPidFile =
|
|
316676
|
-
const ppPortFile =
|
|
316677
|
-
if (
|
|
317039
|
+
const ppPidFile = join91(homedir28(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
317040
|
+
const ppPortFile = join91(homedir28(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
317041
|
+
if (existsSync75(ppPidFile)) {
|
|
316678
317042
|
const ppPid = parseInt(readFileSync58(ppPidFile, "utf8").trim(), 10);
|
|
316679
|
-
const ppPort =
|
|
317043
|
+
const ppPort = existsSync75(ppPortFile) ? parseInt(readFileSync58(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
316680
317044
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
316681
317045
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
316682
317046
|
}
|
|
316683
317047
|
}
|
|
316684
317048
|
}
|
|
316685
|
-
const nexusPidFile =
|
|
316686
|
-
if (
|
|
317049
|
+
const nexusPidFile = join91(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
317050
|
+
if (existsSync75(nexusPidFile)) {
|
|
316687
317051
|
const nPid = parseInt(readFileSync58(nexusPidFile, "utf8").trim(), 10);
|
|
316688
317052
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
316689
317053
|
try {
|
|
@@ -317025,8 +317389,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
317025
317389
|
}
|
|
317026
317390
|
}
|
|
317027
317391
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
317028
|
-
const isImage = isImagePath(cleanPath) &&
|
|
317029
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
317392
|
+
const isImage = isImagePath(cleanPath) && existsSync75(resolve35(repoRoot, cleanPath));
|
|
317393
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync75(resolve35(repoRoot, cleanPath));
|
|
317030
317394
|
if (activeTask) {
|
|
317031
317395
|
if (activeTask.runner.isPaused) {
|
|
317032
317396
|
activeTask.runner.resume();
|
|
@@ -317254,7 +317618,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
317254
317618
|
|
|
317255
317619
|
NEW TASK: ${fullInput}`;
|
|
317256
317620
|
restoredSessionContext = null;
|
|
317257
|
-
} else if (
|
|
317621
|
+
} else if (existsSync75(join91(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
317258
317622
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
317259
317623
|
|
|
317260
317624
|
${fullInput}`;
|
|
@@ -317588,13 +317952,13 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
317588
317952
|
const handle2 = startTask(task, config, repoRoot);
|
|
317589
317953
|
await handle2.promise;
|
|
317590
317954
|
try {
|
|
317591
|
-
const ikDir =
|
|
317592
|
-
const ikFile =
|
|
317955
|
+
const ikDir = join91(repoRoot, ".oa", "identity");
|
|
317956
|
+
const ikFile = join91(ikDir, "self-state.json");
|
|
317593
317957
|
let ikState;
|
|
317594
|
-
if (
|
|
317958
|
+
if (existsSync75(ikFile)) {
|
|
317595
317959
|
ikState = JSON.parse(readFileSync58(ikFile, "utf8"));
|
|
317596
317960
|
} else {
|
|
317597
|
-
|
|
317961
|
+
mkdirSync43(ikDir, { recursive: true });
|
|
317598
317962
|
ikState = {
|
|
317599
317963
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
317600
317964
|
version: 1,
|
|
@@ -317629,11 +317993,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
317629
317993
|
);
|
|
317630
317994
|
} catch {
|
|
317631
317995
|
try {
|
|
317632
|
-
const archeDir =
|
|
317633
|
-
const archeFile =
|
|
317996
|
+
const archeDir = join91(repoRoot, ".oa", "arche");
|
|
317997
|
+
const archeFile = join91(archeDir, "variants.json");
|
|
317634
317998
|
let variants = [];
|
|
317635
317999
|
try {
|
|
317636
|
-
if (
|
|
318000
|
+
if (existsSync75(archeFile)) variants = JSON.parse(readFileSync58(archeFile, "utf8"));
|
|
317637
318001
|
} catch {
|
|
317638
318002
|
}
|
|
317639
318003
|
variants.push({
|
|
@@ -317647,14 +318011,14 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
317647
318011
|
tags: ["general"]
|
|
317648
318012
|
});
|
|
317649
318013
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
317650
|
-
|
|
318014
|
+
mkdirSync43(archeDir, { recursive: true });
|
|
317651
318015
|
writeFileSync38(archeFile, JSON.stringify(variants, null, 2));
|
|
317652
318016
|
} catch {
|
|
317653
318017
|
}
|
|
317654
318018
|
}
|
|
317655
318019
|
try {
|
|
317656
|
-
const metaFile =
|
|
317657
|
-
if (
|
|
318020
|
+
const metaFile = join91(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
318021
|
+
if (existsSync75(metaFile)) {
|
|
317658
318022
|
const store2 = JSON.parse(readFileSync58(metaFile, "utf8"));
|
|
317659
318023
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
317660
318024
|
let updated = false;
|
|
@@ -317719,9 +318083,9 @@ Rules:
|
|
|
317719
318083
|
try {
|
|
317720
318084
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
317721
318085
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
317722
|
-
const dbDir =
|
|
317723
|
-
|
|
317724
|
-
const db = initDb2(
|
|
318086
|
+
const dbDir = join91(repoRoot, ".oa", "memory");
|
|
318087
|
+
mkdirSync43(dbDir, { recursive: true });
|
|
318088
|
+
const db = initDb2(join91(dbDir, "structured.db"));
|
|
317725
318089
|
const memStore = new ProceduralMemoryStore2(db);
|
|
317726
318090
|
memStore.createWithEmbedding({
|
|
317727
318091
|
content: content.slice(0, 600),
|
|
@@ -317736,11 +318100,11 @@ Rules:
|
|
|
317736
318100
|
db.close();
|
|
317737
318101
|
} catch {
|
|
317738
318102
|
}
|
|
317739
|
-
const metaDir =
|
|
317740
|
-
const storeFile =
|
|
318103
|
+
const metaDir = join91(repoRoot, ".oa", "memory", "metabolism");
|
|
318104
|
+
const storeFile = join91(metaDir, "store.json");
|
|
317741
318105
|
let store2 = [];
|
|
317742
318106
|
try {
|
|
317743
|
-
if (
|
|
318107
|
+
if (existsSync75(storeFile)) store2 = JSON.parse(readFileSync58(storeFile, "utf8"));
|
|
317744
318108
|
} catch {
|
|
317745
318109
|
}
|
|
317746
318110
|
store2.push({
|
|
@@ -317755,25 +318119,25 @@ Rules:
|
|
|
317755
318119
|
accessCount: 0
|
|
317756
318120
|
});
|
|
317757
318121
|
if (store2.length > 100) store2 = store2.slice(-100);
|
|
317758
|
-
|
|
318122
|
+
mkdirSync43(metaDir, { recursive: true });
|
|
317759
318123
|
writeFileSync38(storeFile, JSON.stringify(store2, null, 2));
|
|
317760
318124
|
}
|
|
317761
318125
|
}
|
|
317762
318126
|
} catch {
|
|
317763
318127
|
}
|
|
317764
318128
|
try {
|
|
317765
|
-
const cohereSettingsFile =
|
|
318129
|
+
const cohereSettingsFile = join91(repoRoot, ".oa", "settings.json");
|
|
317766
318130
|
let cohereActive = false;
|
|
317767
318131
|
try {
|
|
317768
|
-
if (
|
|
318132
|
+
if (existsSync75(cohereSettingsFile)) {
|
|
317769
318133
|
const settings = JSON.parse(readFileSync58(cohereSettingsFile, "utf8"));
|
|
317770
318134
|
cohereActive = settings.cohere === true;
|
|
317771
318135
|
}
|
|
317772
318136
|
} catch {
|
|
317773
318137
|
}
|
|
317774
318138
|
if (cohereActive) {
|
|
317775
|
-
const metaFile =
|
|
317776
|
-
if (
|
|
318139
|
+
const metaFile = join91(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
318140
|
+
if (existsSync75(metaFile)) {
|
|
317777
318141
|
const store2 = JSON.parse(readFileSync58(metaFile, "utf8"));
|
|
317778
318142
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
317779
318143
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
@@ -317799,8 +318163,8 @@ Rules:
|
|
|
317799
318163
|
}
|
|
317800
318164
|
} catch (err) {
|
|
317801
318165
|
try {
|
|
317802
|
-
const ikFile =
|
|
317803
|
-
if (
|
|
318166
|
+
const ikFile = join91(repoRoot, ".oa", "identity", "self-state.json");
|
|
318167
|
+
if (existsSync75(ikFile)) {
|
|
317804
318168
|
const ikState = JSON.parse(readFileSync58(ikFile, "utf8"));
|
|
317805
318169
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
317806
318170
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
@@ -317808,8 +318172,8 @@ Rules:
|
|
|
317808
318172
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
317809
318173
|
writeFileSync38(ikFile, JSON.stringify(ikState, null, 2));
|
|
317810
318174
|
}
|
|
317811
|
-
const metaFile =
|
|
317812
|
-
if (
|
|
318175
|
+
const metaFile = join91(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
318176
|
+
if (existsSync75(metaFile)) {
|
|
317813
318177
|
const store2 = JSON.parse(readFileSync58(metaFile, "utf8"));
|
|
317814
318178
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
317815
318179
|
for (const item of surfaced) {
|
|
@@ -317821,11 +318185,11 @@ Rules:
|
|
|
317821
318185
|
writeFileSync38(metaFile, JSON.stringify(store2, null, 2));
|
|
317822
318186
|
}
|
|
317823
318187
|
try {
|
|
317824
|
-
const archeDir =
|
|
317825
|
-
const archeFile =
|
|
318188
|
+
const archeDir = join91(repoRoot, ".oa", "arche");
|
|
318189
|
+
const archeFile = join91(archeDir, "variants.json");
|
|
317826
318190
|
let variants = [];
|
|
317827
318191
|
try {
|
|
317828
|
-
if (
|
|
318192
|
+
if (existsSync75(archeFile)) variants = JSON.parse(readFileSync58(archeFile, "utf8"));
|
|
317829
318193
|
} catch {
|
|
317830
318194
|
}
|
|
317831
318195
|
variants.push({
|
|
@@ -317839,7 +318203,7 @@ Rules:
|
|
|
317839
318203
|
tags: ["general"]
|
|
317840
318204
|
});
|
|
317841
318205
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
317842
|
-
|
|
318206
|
+
mkdirSync43(archeDir, { recursive: true });
|
|
317843
318207
|
writeFileSync38(archeFile, JSON.stringify(variants, null, 2));
|
|
317844
318208
|
} catch {
|
|
317845
318209
|
}
|
|
@@ -317922,13 +318286,13 @@ __export(run_exports, {
|
|
|
317922
318286
|
});
|
|
317923
318287
|
import { resolve as resolve36 } from "node:path";
|
|
317924
318288
|
import { spawn as spawn25 } from "node:child_process";
|
|
317925
|
-
import { mkdirSync as
|
|
318289
|
+
import { mkdirSync as mkdirSync44, writeFileSync as writeFileSync39, readFileSync as readFileSync59, readdirSync as readdirSync25, existsSync as existsSync76 } from "node:fs";
|
|
317926
318290
|
import { randomBytes as randomBytes20 } from "node:crypto";
|
|
317927
|
-
import { join as
|
|
318291
|
+
import { join as join92 } from "node:path";
|
|
317928
318292
|
function jobsDir2(repoPath) {
|
|
317929
318293
|
const root = resolve36(repoPath ?? process.cwd());
|
|
317930
|
-
const dir =
|
|
317931
|
-
|
|
318294
|
+
const dir = join92(root, ".oa", "jobs");
|
|
318295
|
+
mkdirSync44(dir, { recursive: true });
|
|
317932
318296
|
return dir;
|
|
317933
318297
|
}
|
|
317934
318298
|
async function runCommand(opts, config) {
|
|
@@ -318043,7 +318407,7 @@ async function runBackground(task, config, opts) {
|
|
|
318043
318407
|
}
|
|
318044
318408
|
});
|
|
318045
318409
|
job.pid = child.pid ?? 0;
|
|
318046
|
-
writeFileSync39(
|
|
318410
|
+
writeFileSync39(join92(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
318047
318411
|
let output = "";
|
|
318048
318412
|
child.stdout?.on("data", (chunk) => {
|
|
318049
318413
|
output += chunk.toString();
|
|
@@ -318059,7 +318423,7 @@ async function runBackground(task, config, opts) {
|
|
|
318059
318423
|
job.summary = result.summary;
|
|
318060
318424
|
job.durationMs = result.durationMs;
|
|
318061
318425
|
job.error = result.error;
|
|
318062
|
-
writeFileSync39(
|
|
318426
|
+
writeFileSync39(join92(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
318063
318427
|
} catch {
|
|
318064
318428
|
}
|
|
318065
318429
|
});
|
|
@@ -318075,8 +318439,8 @@ async function runBackground(task, config, opts) {
|
|
|
318075
318439
|
}
|
|
318076
318440
|
function statusCommand(jobId, repoPath) {
|
|
318077
318441
|
const dir = jobsDir2(repoPath);
|
|
318078
|
-
const file =
|
|
318079
|
-
if (!
|
|
318442
|
+
const file = join92(dir, `${jobId}.json`);
|
|
318443
|
+
if (!existsSync76(file)) {
|
|
318080
318444
|
console.error(`Job not found: ${jobId}`);
|
|
318081
318445
|
console.log(`Available jobs: oa jobs`);
|
|
318082
318446
|
process.exit(1);
|
|
@@ -318101,7 +318465,7 @@ function jobsCommand(repoPath) {
|
|
|
318101
318465
|
console.log("Jobs:");
|
|
318102
318466
|
for (const file of files) {
|
|
318103
318467
|
try {
|
|
318104
|
-
const job = JSON.parse(readFileSync59(
|
|
318468
|
+
const job = JSON.parse(readFileSync59(join92(dir, file), "utf-8"));
|
|
318105
318469
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
318106
318470
|
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
318107
318471
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -318121,7 +318485,7 @@ import { glob as glob2 } from "glob";
|
|
|
318121
318485
|
import ignore from "ignore";
|
|
318122
318486
|
import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
|
|
318123
318487
|
import { createHash as createHash7 } from "node:crypto";
|
|
318124
|
-
import { join as
|
|
318488
|
+
import { join as join93, relative as relative5, extname as extname12, basename as basename18 } from "node:path";
|
|
318125
318489
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
318126
318490
|
var init_codebase_indexer = __esm({
|
|
318127
318491
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -318165,7 +318529,7 @@ var init_codebase_indexer = __esm({
|
|
|
318165
318529
|
const ig = ignore.default();
|
|
318166
318530
|
if (this.config.respectGitignore) {
|
|
318167
318531
|
try {
|
|
318168
|
-
const gitignoreContent = await readFile23(
|
|
318532
|
+
const gitignoreContent = await readFile23(join93(this.config.rootDir, ".gitignore"), "utf-8");
|
|
318169
318533
|
ig.add(gitignoreContent);
|
|
318170
318534
|
} catch {
|
|
318171
318535
|
}
|
|
@@ -318180,7 +318544,7 @@ var init_codebase_indexer = __esm({
|
|
|
318180
318544
|
for (const relativePath of files) {
|
|
318181
318545
|
if (ig.ignores(relativePath))
|
|
318182
318546
|
continue;
|
|
318183
|
-
const fullPath =
|
|
318547
|
+
const fullPath = join93(this.config.rootDir, relativePath);
|
|
318184
318548
|
try {
|
|
318185
318549
|
const fileStat = await stat5(fullPath);
|
|
318186
318550
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -318226,7 +318590,7 @@ var init_codebase_indexer = __esm({
|
|
|
318226
318590
|
if (!child) {
|
|
318227
318591
|
child = {
|
|
318228
318592
|
name: part,
|
|
318229
|
-
path:
|
|
318593
|
+
path: join93(current.path, part),
|
|
318230
318594
|
type: "directory",
|
|
318231
318595
|
children: []
|
|
318232
318596
|
};
|
|
@@ -318334,13 +318698,13 @@ __export(index_repo_exports, {
|
|
|
318334
318698
|
indexRepoCommand: () => indexRepoCommand
|
|
318335
318699
|
});
|
|
318336
318700
|
import { resolve as resolve37 } from "node:path";
|
|
318337
|
-
import { existsSync as
|
|
318701
|
+
import { existsSync as existsSync77, statSync as statSync21 } from "node:fs";
|
|
318338
318702
|
import { cwd as cwd2 } from "node:process";
|
|
318339
318703
|
async function indexRepoCommand(opts, _config3) {
|
|
318340
318704
|
const repoRoot = resolve37(opts.repoPath ?? cwd2());
|
|
318341
318705
|
printHeader("Index Repository");
|
|
318342
318706
|
printInfo(`Indexing: ${repoRoot}`);
|
|
318343
|
-
if (!
|
|
318707
|
+
if (!existsSync77(repoRoot)) {
|
|
318344
318708
|
printError(`Path does not exist: ${repoRoot}`);
|
|
318345
318709
|
process.exit(1);
|
|
318346
318710
|
}
|
|
@@ -318592,7 +318956,7 @@ var config_exports2 = {};
|
|
|
318592
318956
|
__export(config_exports2, {
|
|
318593
318957
|
configCommand: () => configCommand
|
|
318594
318958
|
});
|
|
318595
|
-
import { join as
|
|
318959
|
+
import { join as join94, resolve as resolve38 } from "node:path";
|
|
318596
318960
|
import { homedir as homedir29 } from "node:os";
|
|
318597
318961
|
import { cwd as cwd3 } from "node:process";
|
|
318598
318962
|
function redactIfSensitive(key, value2) {
|
|
@@ -318674,7 +319038,7 @@ function handleShow(opts, config) {
|
|
|
318674
319038
|
}
|
|
318675
319039
|
}
|
|
318676
319040
|
printSection("Config File");
|
|
318677
|
-
printInfo(`~/.open-agents/config.json (${
|
|
319041
|
+
printInfo(`~/.open-agents/config.json (${join94(homedir29(), ".open-agents", "config.json")})`);
|
|
318678
319042
|
printSection("Priority Chain");
|
|
318679
319043
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
318680
319044
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -318713,7 +319077,7 @@ function handleSet(opts, _config3) {
|
|
|
318713
319077
|
const coerced = coerceForSettings(key, value2);
|
|
318714
319078
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
318715
319079
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
|
|
318716
|
-
printInfo(`Saved to ${
|
|
319080
|
+
printInfo(`Saved to ${join94(repoRoot, ".oa", "settings.json")}`);
|
|
318717
319081
|
printInfo("This override applies only when running in this workspace.");
|
|
318718
319082
|
} catch (err) {
|
|
318719
319083
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -318882,8 +319246,8 @@ __export(eval_exports, {
|
|
|
318882
319246
|
evalCommand: () => evalCommand
|
|
318883
319247
|
});
|
|
318884
319248
|
import { tmpdir as tmpdir17 } from "node:os";
|
|
318885
|
-
import { mkdirSync as
|
|
318886
|
-
import { join as
|
|
319249
|
+
import { mkdirSync as mkdirSync45, writeFileSync as writeFileSync40 } from "node:fs";
|
|
319250
|
+
import { join as join95 } from "node:path";
|
|
318887
319251
|
async function evalCommand(opts, config) {
|
|
318888
319252
|
const suiteName = opts.suite ?? "basic";
|
|
318889
319253
|
const suite = SUITES[suiteName];
|
|
@@ -319012,10 +319376,10 @@ async function evalCommand(opts, config) {
|
|
|
319012
319376
|
process.exit(failed > 0 ? 1 : 0);
|
|
319013
319377
|
}
|
|
319014
319378
|
function createTempEvalRepo() {
|
|
319015
|
-
const dir =
|
|
319016
|
-
|
|
319379
|
+
const dir = join95(tmpdir17(), `open-agents-eval-${Date.now()}`);
|
|
319380
|
+
mkdirSync45(dir, { recursive: true });
|
|
319017
319381
|
writeFileSync40(
|
|
319018
|
-
|
|
319382
|
+
join95(dir, "package.json"),
|
|
319019
319383
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
319020
319384
|
"utf8"
|
|
319021
319385
|
);
|
|
@@ -319078,7 +319442,7 @@ init_updater();
|
|
|
319078
319442
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
319079
319443
|
import { createRequire as createRequire6 } from "node:module";
|
|
319080
319444
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
319081
|
-
import { dirname as dirname27, join as
|
|
319445
|
+
import { dirname as dirname27, join as join96 } from "node:path";
|
|
319082
319446
|
|
|
319083
319447
|
// packages/cli/src/cli.ts
|
|
319084
319448
|
import { createInterface } from "node:readline";
|
|
@@ -319185,7 +319549,7 @@ init_output();
|
|
|
319185
319549
|
function getVersion5() {
|
|
319186
319550
|
try {
|
|
319187
319551
|
const require3 = createRequire6(import.meta.url);
|
|
319188
|
-
const pkgPath =
|
|
319552
|
+
const pkgPath = join96(dirname27(fileURLToPath18(import.meta.url)), "..", "package.json");
|
|
319189
319553
|
const pkg = require3(pkgPath);
|
|
319190
319554
|
return pkg.version;
|
|
319191
319555
|
} catch {
|
|
@@ -319477,12 +319841,12 @@ function crashLog(label, err) {
|
|
|
319477
319841
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
319478
319842
|
`;
|
|
319479
319843
|
try {
|
|
319480
|
-
const { appendFileSync: appendFileSync7, mkdirSync:
|
|
319481
|
-
const { join:
|
|
319844
|
+
const { appendFileSync: appendFileSync7, mkdirSync: mkdirSync46 } = __require("node:fs");
|
|
319845
|
+
const { join: join97 } = __require("node:path");
|
|
319482
319846
|
const { homedir: homedir30 } = __require("node:os");
|
|
319483
|
-
const logDir =
|
|
319484
|
-
|
|
319485
|
-
appendFileSync7(
|
|
319847
|
+
const logDir = join97(homedir30(), ".open-agents");
|
|
319848
|
+
mkdirSync46(logDir, { recursive: true });
|
|
319849
|
+
appendFileSync7(join97(logDir, "crash.log"), logLine);
|
|
319486
319850
|
} catch {
|
|
319487
319851
|
}
|
|
319488
319852
|
try {
|