open-agents-ai 0.185.23 → 0.185.24
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 +1046 -682
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13741,9 +13741,9 @@ print("${sentinel}")
|
|
|
13741
13741
|
if (!this.proc || this.proc.killed) {
|
|
13742
13742
|
return { success: false, path: "" };
|
|
13743
13743
|
}
|
|
13744
|
-
const { mkdirSync:
|
|
13744
|
+
const { mkdirSync: mkdirSync31, writeFileSync: writeFileSync30 } = await import("node:fs");
|
|
13745
13745
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13746
|
-
|
|
13746
|
+
mkdirSync31(sessionDir, { recursive: true });
|
|
13747
13747
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13748
13748
|
try {
|
|
13749
13749
|
const inspectCode = `
|
|
@@ -13767,7 +13767,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13767
13767
|
trajectoryCount: this.trajectory.length,
|
|
13768
13768
|
subCallCount: this.subCallCount
|
|
13769
13769
|
};
|
|
13770
|
-
|
|
13770
|
+
writeFileSync30(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13771
13771
|
return { success: true, path: sessionPath };
|
|
13772
13772
|
}
|
|
13773
13773
|
} catch {
|
|
@@ -13779,11 +13779,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13779
13779
|
* what was previously computed. */
|
|
13780
13780
|
async loadSessionInfo() {
|
|
13781
13781
|
try {
|
|
13782
|
-
const { readFileSync:
|
|
13782
|
+
const { readFileSync: readFileSync45, existsSync: existsSync57 } = await import("node:fs");
|
|
13783
13783
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13784
|
-
if (!
|
|
13784
|
+
if (!existsSync57(sessionPath))
|
|
13785
13785
|
return null;
|
|
13786
|
-
return JSON.parse(
|
|
13786
|
+
return JSON.parse(readFileSync45(sessionPath, "utf8"));
|
|
13787
13787
|
} catch {
|
|
13788
13788
|
return null;
|
|
13789
13789
|
}
|
|
@@ -13960,10 +13960,10 @@ var init_memory_metabolism = __esm({
|
|
|
13960
13960
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
13961
13961
|
let lessons = [];
|
|
13962
13962
|
try {
|
|
13963
|
-
const { readdirSync: readdirSync23, readFileSync:
|
|
13963
|
+
const { readdirSync: readdirSync23, readFileSync: readFileSync45 } = await import("node:fs");
|
|
13964
13964
|
const files = readdirSync23(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
13965
13965
|
for (const file of files) {
|
|
13966
|
-
const lines =
|
|
13966
|
+
const lines = readFileSync45(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
13967
13967
|
for (const line of lines) {
|
|
13968
13968
|
try {
|
|
13969
13969
|
const entry = JSON.parse(line);
|
|
@@ -14347,14 +14347,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14347
14347
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14348
14348
|
*/
|
|
14349
14349
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14350
|
-
const { readFileSync:
|
|
14350
|
+
const { readFileSync: readFileSync45, existsSync: existsSync57 } = __require("node:fs");
|
|
14351
14351
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14352
14352
|
const storeFile = join23(metaDir, "store.json");
|
|
14353
|
-
if (!
|
|
14353
|
+
if (!existsSync57(storeFile))
|
|
14354
14354
|
return "";
|
|
14355
14355
|
let store = [];
|
|
14356
14356
|
try {
|
|
14357
|
-
store = JSON.parse(
|
|
14357
|
+
store = JSON.parse(readFileSync45(storeFile, "utf8"));
|
|
14358
14358
|
} catch {
|
|
14359
14359
|
return "";
|
|
14360
14360
|
}
|
|
@@ -14376,14 +14376,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14376
14376
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14377
14377
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14378
14378
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14379
|
-
const { readFileSync:
|
|
14379
|
+
const { readFileSync: readFileSync45, writeFileSync: writeFileSync30, existsSync: existsSync57, mkdirSync: mkdirSync31 } = __require("node:fs");
|
|
14380
14380
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14381
14381
|
const storeFile = join23(metaDir, "store.json");
|
|
14382
|
-
if (!
|
|
14382
|
+
if (!existsSync57(storeFile))
|
|
14383
14383
|
return;
|
|
14384
14384
|
let store = [];
|
|
14385
14385
|
try {
|
|
14386
|
-
store = JSON.parse(
|
|
14386
|
+
store = JSON.parse(readFileSync45(storeFile, "utf8"));
|
|
14387
14387
|
} catch {
|
|
14388
14388
|
return;
|
|
14389
14389
|
}
|
|
@@ -14407,8 +14407,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14407
14407
|
updated = true;
|
|
14408
14408
|
}
|
|
14409
14409
|
if (updated) {
|
|
14410
|
-
|
|
14411
|
-
|
|
14410
|
+
mkdirSync31(metaDir, { recursive: true });
|
|
14411
|
+
writeFileSync30(storeFile, JSON.stringify(store, null, 2));
|
|
14412
14412
|
}
|
|
14413
14413
|
}
|
|
14414
14414
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -14830,13 +14830,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14830
14830
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14831
14831
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14832
14832
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14833
|
-
const { readFileSync:
|
|
14833
|
+
const { readFileSync: readFileSync45, existsSync: existsSync57 } = __require("node:fs");
|
|
14834
14834
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14835
|
-
if (!
|
|
14835
|
+
if (!existsSync57(archiveFile))
|
|
14836
14836
|
return "";
|
|
14837
14837
|
let variants = [];
|
|
14838
14838
|
try {
|
|
14839
|
-
variants = JSON.parse(
|
|
14839
|
+
variants = JSON.parse(readFileSync45(archiveFile, "utf8"));
|
|
14840
14840
|
} catch {
|
|
14841
14841
|
return "";
|
|
14842
14842
|
}
|
|
@@ -14854,13 +14854,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14854
14854
|
}
|
|
14855
14855
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14856
14856
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14857
|
-
const { readFileSync:
|
|
14857
|
+
const { readFileSync: readFileSync45, writeFileSync: writeFileSync30, existsSync: existsSync57, mkdirSync: mkdirSync31 } = __require("node:fs");
|
|
14858
14858
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14859
14859
|
const archiveFile = join25(dir, "variants.json");
|
|
14860
14860
|
let variants = [];
|
|
14861
14861
|
try {
|
|
14862
|
-
if (
|
|
14863
|
-
variants = JSON.parse(
|
|
14862
|
+
if (existsSync57(archiveFile))
|
|
14863
|
+
variants = JSON.parse(readFileSync45(archiveFile, "utf8"));
|
|
14864
14864
|
} catch {
|
|
14865
14865
|
}
|
|
14866
14866
|
variants.push({
|
|
@@ -14875,8 +14875,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14875
14875
|
});
|
|
14876
14876
|
if (variants.length > 50)
|
|
14877
14877
|
variants = variants.slice(-50);
|
|
14878
|
-
|
|
14879
|
-
|
|
14878
|
+
mkdirSync31(dir, { recursive: true });
|
|
14879
|
+
writeFileSync30(archiveFile, JSON.stringify(variants, null, 2));
|
|
14880
14880
|
}
|
|
14881
14881
|
async saveArchive(variants) {
|
|
14882
14882
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -15840,9 +15840,9 @@ var init_vision = __esm({
|
|
|
15840
15840
|
if (ollamaResult)
|
|
15841
15841
|
return ollamaResult;
|
|
15842
15842
|
try {
|
|
15843
|
-
const { execSync:
|
|
15843
|
+
const { execSync: execSync35 } = await import("node:child_process");
|
|
15844
15844
|
try {
|
|
15845
|
-
|
|
15845
|
+
execSync35("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
|
|
15846
15846
|
timeout: 12e4,
|
|
15847
15847
|
stdio: "pipe"
|
|
15848
15848
|
});
|
|
@@ -15855,7 +15855,7 @@ var init_vision = __esm({
|
|
|
15855
15855
|
} catch {
|
|
15856
15856
|
}
|
|
15857
15857
|
try {
|
|
15858
|
-
|
|
15858
|
+
execSync35("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
15859
15859
|
const retryOllama = await this.tryOllamaVision(buffer, filename, action, prompt, length, start);
|
|
15860
15860
|
if (retryOllama)
|
|
15861
15861
|
return retryOllama;
|
|
@@ -15963,8 +15963,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
|
|
|
15963
15963
|
const errText = await res.text().catch(() => "");
|
|
15964
15964
|
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
15965
15965
|
try {
|
|
15966
|
-
const { execSync:
|
|
15967
|
-
|
|
15966
|
+
const { execSync: execSync35 } = await import("node:child_process");
|
|
15967
|
+
execSync35("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
15968
15968
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
15969
15969
|
method: "POST",
|
|
15970
15970
|
headers: { "Content-Type": "application/json" },
|
|
@@ -27351,10 +27351,10 @@ ${marker}` : marker);
|
|
|
27351
27351
|
if (!this._workingDirectory)
|
|
27352
27352
|
return;
|
|
27353
27353
|
try {
|
|
27354
|
-
const { mkdirSync:
|
|
27355
|
-
const { join:
|
|
27356
|
-
const sessionDir =
|
|
27357
|
-
|
|
27354
|
+
const { mkdirSync: mkdirSync31, writeFileSync: writeFileSync30 } = __require("node:fs");
|
|
27355
|
+
const { join: join77 } = __require("node:path");
|
|
27356
|
+
const sessionDir = join77(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
27357
|
+
mkdirSync31(sessionDir, { recursive: true });
|
|
27358
27358
|
const checkpoint = {
|
|
27359
27359
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27360
27360
|
sessionId: this._sessionId,
|
|
@@ -27366,7 +27366,7 @@ ${marker}` : marker);
|
|
|
27366
27366
|
memexEntryCount: this._memexArchive.size,
|
|
27367
27367
|
fileRegistrySize: this._fileRegistry.size
|
|
27368
27368
|
};
|
|
27369
|
-
|
|
27369
|
+
writeFileSync30(join77(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
27370
27370
|
} catch {
|
|
27371
27371
|
}
|
|
27372
27372
|
}
|
|
@@ -38906,26 +38906,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
38906
38906
|
async function fetchPeerModels(peerId, authKey) {
|
|
38907
38907
|
try {
|
|
38908
38908
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
38909
|
-
const { existsSync:
|
|
38910
|
-
const { join:
|
|
38909
|
+
const { existsSync: existsSync57, readFileSync: readFileSync45 } = await import("node:fs");
|
|
38910
|
+
const { join: join77 } = await import("node:path");
|
|
38911
38911
|
const cwd4 = process.cwd();
|
|
38912
38912
|
const nexusTool = new NexusTool2(cwd4);
|
|
38913
38913
|
const nexusDir = nexusTool.getNexusDir();
|
|
38914
38914
|
let isLocalPeer = false;
|
|
38915
38915
|
try {
|
|
38916
|
-
const statusPath =
|
|
38917
|
-
if (
|
|
38918
|
-
const status = JSON.parse(
|
|
38916
|
+
const statusPath = join77(nexusDir, "status.json");
|
|
38917
|
+
if (existsSync57(statusPath)) {
|
|
38918
|
+
const status = JSON.parse(readFileSync45(statusPath, "utf8"));
|
|
38919
38919
|
if (status.peerId === peerId)
|
|
38920
38920
|
isLocalPeer = true;
|
|
38921
38921
|
}
|
|
38922
38922
|
} catch {
|
|
38923
38923
|
}
|
|
38924
38924
|
if (isLocalPeer) {
|
|
38925
|
-
const pricingPath =
|
|
38926
|
-
if (
|
|
38925
|
+
const pricingPath = join77(nexusDir, "pricing.json");
|
|
38926
|
+
if (existsSync57(pricingPath)) {
|
|
38927
38927
|
try {
|
|
38928
|
-
const pricing = JSON.parse(
|
|
38928
|
+
const pricing = JSON.parse(readFileSync45(pricingPath, "utf8"));
|
|
38929
38929
|
const localModels = (pricing.models || []).map((m) => ({
|
|
38930
38930
|
name: m.model || "unknown",
|
|
38931
38931
|
size: m.parameterSize || "",
|
|
@@ -38939,10 +38939,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
38939
38939
|
}
|
|
38940
38940
|
}
|
|
38941
38941
|
}
|
|
38942
|
-
const cachePath =
|
|
38943
|
-
if (
|
|
38942
|
+
const cachePath = join77(nexusDir, "peer-models-cache.json");
|
|
38943
|
+
if (existsSync57(cachePath)) {
|
|
38944
38944
|
try {
|
|
38945
|
-
const cache4 = JSON.parse(
|
|
38945
|
+
const cache4 = JSON.parse(readFileSync45(cachePath, "utf8"));
|
|
38946
38946
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
38947
38947
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
38948
38948
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -39057,10 +39057,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
39057
39057
|
} catch {
|
|
39058
39058
|
}
|
|
39059
39059
|
if (isLocalPeer) {
|
|
39060
|
-
const pricingPath =
|
|
39061
|
-
if (
|
|
39060
|
+
const pricingPath = join77(nexusDir, "pricing.json");
|
|
39061
|
+
if (existsSync57(pricingPath)) {
|
|
39062
39062
|
try {
|
|
39063
|
-
const pricing = JSON.parse(
|
|
39063
|
+
const pricing = JSON.parse(readFileSync45(pricingPath, "utf8"));
|
|
39064
39064
|
return (pricing.models || []).map((m) => ({
|
|
39065
39065
|
name: m.model || "unknown",
|
|
39066
39066
|
size: m.parameterSize || "",
|
|
@@ -40724,13 +40724,321 @@ var init_tui_select = __esm({
|
|
|
40724
40724
|
}
|
|
40725
40725
|
});
|
|
40726
40726
|
|
|
40727
|
+
// packages/cli/dist/tui/personaplex.js
|
|
40728
|
+
var personaplex_exports = {};
|
|
40729
|
+
__export(personaplex_exports, {
|
|
40730
|
+
detectPersonaPlexCapability: () => detectPersonaPlexCapability,
|
|
40731
|
+
getPersonaPlexWSUrl: () => getPersonaPlexWSUrl,
|
|
40732
|
+
installPersonaPlex: () => installPersonaPlex,
|
|
40733
|
+
isPersonaPlexInstalled: () => isPersonaPlexInstalled,
|
|
40734
|
+
isPersonaPlexRunning: () => isPersonaPlexRunning,
|
|
40735
|
+
startPersonaPlexDaemon: () => startPersonaPlexDaemon,
|
|
40736
|
+
stopPersonaPlex: () => stopPersonaPlex
|
|
40737
|
+
});
|
|
40738
|
+
import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, mkdirSync as mkdirSync15 } from "node:fs";
|
|
40739
|
+
import { join as join54 } from "node:path";
|
|
40740
|
+
import { homedir as homedir13 } from "node:os";
|
|
40741
|
+
import { execSync as execSync27, spawn as spawn19 } from "node:child_process";
|
|
40742
|
+
function detectPersonaPlexCapability() {
|
|
40743
|
+
try {
|
|
40744
|
+
const nvsmi = execSync27("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
40745
|
+
encoding: "utf8",
|
|
40746
|
+
timeout: 5e3,
|
|
40747
|
+
stdio: "pipe"
|
|
40748
|
+
}).trim();
|
|
40749
|
+
if (!nvsmi) {
|
|
40750
|
+
return { supported: false, reason: "No NVIDIA GPU detected", gpuName: "", vramGB: 0 };
|
|
40751
|
+
}
|
|
40752
|
+
const [gpuName, vramMB] = nvsmi.split("\n")[0].split(", ");
|
|
40753
|
+
const vramGB = parseInt(vramMB ?? "0", 10) / 1024;
|
|
40754
|
+
if (vramGB < 16) {
|
|
40755
|
+
return { supported: false, reason: `GPU has ${vramGB.toFixed(1)}GB VRAM (need \u226516GB)`, gpuName: gpuName ?? "", vramGB };
|
|
40756
|
+
}
|
|
40757
|
+
try {
|
|
40758
|
+
execSync27('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
40759
|
+
timeout: 1e4,
|
|
40760
|
+
stdio: "pipe"
|
|
40761
|
+
});
|
|
40762
|
+
} catch {
|
|
40763
|
+
return { supported: false, reason: "PyTorch CUDA not available", gpuName: gpuName ?? "", vramGB };
|
|
40764
|
+
}
|
|
40765
|
+
return { supported: true, reason: "OK", gpuName: gpuName ?? "", vramGB };
|
|
40766
|
+
} catch {
|
|
40767
|
+
return { supported: false, reason: "nvidia-smi not found", gpuName: "", vramGB: 0 };
|
|
40768
|
+
}
|
|
40769
|
+
}
|
|
40770
|
+
function isPersonaPlexRunning() {
|
|
40771
|
+
if (!existsSync37(PID_FILE))
|
|
40772
|
+
return false;
|
|
40773
|
+
const pid = parseInt(readFileSync28(PID_FILE, "utf8").trim(), 10);
|
|
40774
|
+
if (isNaN(pid) || pid <= 0)
|
|
40775
|
+
return false;
|
|
40776
|
+
try {
|
|
40777
|
+
process.kill(pid, 0);
|
|
40778
|
+
return true;
|
|
40779
|
+
} catch {
|
|
40780
|
+
return false;
|
|
40781
|
+
}
|
|
40782
|
+
}
|
|
40783
|
+
function getPersonaPlexWSUrl() {
|
|
40784
|
+
if (!isPersonaPlexRunning())
|
|
40785
|
+
return null;
|
|
40786
|
+
if (!existsSync37(PORT_FILE))
|
|
40787
|
+
return null;
|
|
40788
|
+
const port = parseInt(readFileSync28(PORT_FILE, "utf8").trim(), 10);
|
|
40789
|
+
return isNaN(port) ? null : `ws://127.0.0.1:${port}`;
|
|
40790
|
+
}
|
|
40791
|
+
function isPersonaPlexInstalled() {
|
|
40792
|
+
return existsSync37(join54(PERSONAPLEX_DIR, "model_ready"));
|
|
40793
|
+
}
|
|
40794
|
+
async function installPersonaPlex(onInfo) {
|
|
40795
|
+
const log = onInfo ?? (() => {
|
|
40796
|
+
});
|
|
40797
|
+
mkdirSync15(PERSONAPLEX_DIR, { recursive: true });
|
|
40798
|
+
const venvDir = join54(PERSONAPLEX_DIR, "venv");
|
|
40799
|
+
if (!existsSync37(venvDir)) {
|
|
40800
|
+
log("Creating Python virtual environment...");
|
|
40801
|
+
try {
|
|
40802
|
+
execSync27(`python3 -m venv "${venvDir}"`, { timeout: 6e4, stdio: "pipe" });
|
|
40803
|
+
} catch (err) {
|
|
40804
|
+
log(`Failed to create venv: ${err instanceof Error ? err.message : String(err)}`);
|
|
40805
|
+
return false;
|
|
40806
|
+
}
|
|
40807
|
+
}
|
|
40808
|
+
const pip = process.platform === "win32" ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
|
|
40809
|
+
const python = process.platform === "win32" ? join54(venvDir, "Scripts", "python.exe") : join54(venvDir, "bin", "python3");
|
|
40810
|
+
log("Installing PersonaPlex dependencies (torch, transformers, websockets)...");
|
|
40811
|
+
try {
|
|
40812
|
+
execSync27(`"${pip}" install --quiet torch torchaudio transformers websockets soundfile huggingface_hub`, { timeout: 3e5, stdio: "pipe" });
|
|
40813
|
+
} catch (err) {
|
|
40814
|
+
log(`Dependency install failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
40815
|
+
return false;
|
|
40816
|
+
}
|
|
40817
|
+
log("Downloading PersonaPlex-7B model (~14GB, this may take a while)...");
|
|
40818
|
+
try {
|
|
40819
|
+
execSync27(`"${python}" -c "from huggingface_hub import snapshot_download; snapshot_download('nvidia/personaplex-7b-v1', local_dir='${join54(PERSONAPLEX_DIR, "model").replace(/\\/g, "\\\\")}')"`, { timeout: 36e5, stdio: "pipe" });
|
|
40820
|
+
} catch (err) {
|
|
40821
|
+
log(`Model download failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
40822
|
+
return false;
|
|
40823
|
+
}
|
|
40824
|
+
writeFileSync16(join54(PERSONAPLEX_DIR, "model_ready"), (/* @__PURE__ */ new Date()).toISOString());
|
|
40825
|
+
log("PersonaPlex installed successfully.");
|
|
40826
|
+
return true;
|
|
40827
|
+
}
|
|
40828
|
+
function writeDaemonScript() {
|
|
40829
|
+
const scriptPath2 = join54(PERSONAPLEX_DIR, "daemon.py");
|
|
40830
|
+
const modelDir2 = join54(PERSONAPLEX_DIR, "model");
|
|
40831
|
+
const script = `#!/usr/bin/env python3
|
|
40832
|
+
"""PersonaPlex daemon \u2014 full-duplex voice WebSocket server."""
|
|
40833
|
+
import asyncio
|
|
40834
|
+
import json
|
|
40835
|
+
import os
|
|
40836
|
+
import signal
|
|
40837
|
+
import sys
|
|
40838
|
+
import numpy as np
|
|
40839
|
+
|
|
40840
|
+
# Write PID file
|
|
40841
|
+
pid_file = os.path.join(os.path.dirname(__file__), "daemon.pid")
|
|
40842
|
+
with open(pid_file, "w") as f:
|
|
40843
|
+
f.write(str(os.getpid()))
|
|
40844
|
+
|
|
40845
|
+
try:
|
|
40846
|
+
import torch
|
|
40847
|
+
import torchaudio
|
|
40848
|
+
from transformers import AutoModel, AutoProcessor
|
|
40849
|
+
import websockets
|
|
40850
|
+
import soundfile as sf
|
|
40851
|
+
except ImportError as e:
|
|
40852
|
+
print(f"Missing dependency: {e}", file=sys.stderr)
|
|
40853
|
+
sys.exit(1)
|
|
40854
|
+
|
|
40855
|
+
MODEL_DIR = ${JSON.stringify(modelDir2)}
|
|
40856
|
+
SAMPLE_RATE = 24000
|
|
40857
|
+
PORT = int(os.environ.get("PERSONAPLEX_PORT", "0")) # 0 = auto-assign
|
|
40858
|
+
|
|
40859
|
+
print("Loading PersonaPlex model...", file=sys.stderr)
|
|
40860
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
40861
|
+
dtype = torch.bfloat16 if device == "cuda" else torch.float32
|
|
40862
|
+
|
|
40863
|
+
try:
|
|
40864
|
+
model = AutoModel.from_pretrained(MODEL_DIR, trust_remote_code=True, torch_dtype=dtype)
|
|
40865
|
+
model = model.to(device)
|
|
40866
|
+
model.eval()
|
|
40867
|
+
processor = AutoProcessor.from_pretrained(MODEL_DIR, trust_remote_code=True)
|
|
40868
|
+
print(f"Model loaded on {device}", file=sys.stderr)
|
|
40869
|
+
except Exception as e:
|
|
40870
|
+
print(f"Model load failed: {e}", file=sys.stderr)
|
|
40871
|
+
sys.exit(1)
|
|
40872
|
+
|
|
40873
|
+
# Persona state
|
|
40874
|
+
persona_text = "You are a helpful voice assistant."
|
|
40875
|
+
voice_prompt = None # Audio conditioning tensor
|
|
40876
|
+
|
|
40877
|
+
async def handle_client(websocket, path):
|
|
40878
|
+
"""Handle a single WebSocket client connection."""
|
|
40879
|
+
global persona_text, voice_prompt
|
|
40880
|
+
print(f"Client connected from {websocket.remote_address}", file=sys.stderr)
|
|
40881
|
+
|
|
40882
|
+
try:
|
|
40883
|
+
async for message in websocket:
|
|
40884
|
+
if isinstance(message, str):
|
|
40885
|
+
# JSON control message
|
|
40886
|
+
try:
|
|
40887
|
+
msg = json.loads(message)
|
|
40888
|
+
if msg.get("type") == "persona":
|
|
40889
|
+
persona_text = msg.get("text", persona_text)
|
|
40890
|
+
print(f"Persona updated: {persona_text[:60]}", file=sys.stderr)
|
|
40891
|
+
elif msg.get("type") == "voice_prompt":
|
|
40892
|
+
# Audio conditioning: base64 PCM \u2192 tensor
|
|
40893
|
+
import base64
|
|
40894
|
+
pcm_bytes = base64.b64decode(msg["audio"])
|
|
40895
|
+
audio = np.frombuffer(pcm_bytes, dtype=np.int16).astype(np.float32) / 32768.0
|
|
40896
|
+
voice_prompt = torch.tensor(audio, dtype=dtype, device=device).unsqueeze(0)
|
|
40897
|
+
print(f"Voice prompt set ({len(audio)} samples)", file=sys.stderr)
|
|
40898
|
+
elif msg.get("type") == "keepalive":
|
|
40899
|
+
await websocket.send(json.dumps({"type": "pong"}))
|
|
40900
|
+
except json.JSONDecodeError:
|
|
40901
|
+
pass
|
|
40902
|
+
else:
|
|
40903
|
+
# Binary audio data: PCM Int16 @ 24kHz
|
|
40904
|
+
pcm = np.frombuffer(message, dtype=np.int16).astype(np.float32) / 32768.0
|
|
40905
|
+
audio_tensor = torch.tensor(pcm, dtype=dtype, device=device).unsqueeze(0)
|
|
40906
|
+
|
|
40907
|
+
# Generate response
|
|
40908
|
+
with torch.no_grad():
|
|
40909
|
+
inputs = processor(
|
|
40910
|
+
audio=audio_tensor,
|
|
40911
|
+
text=persona_text,
|
|
40912
|
+
sampling_rate=SAMPLE_RATE,
|
|
40913
|
+
return_tensors="pt"
|
|
40914
|
+
).to(device)
|
|
40915
|
+
|
|
40916
|
+
if voice_prompt is not None:
|
|
40917
|
+
inputs["voice_prompt"] = voice_prompt
|
|
40918
|
+
|
|
40919
|
+
outputs = model.generate(**inputs, max_new_tokens=512)
|
|
40920
|
+
|
|
40921
|
+
# Extract audio response
|
|
40922
|
+
if hasattr(outputs, "audio"):
|
|
40923
|
+
response_pcm = outputs.audio.cpu().numpy().flatten()
|
|
40924
|
+
else:
|
|
40925
|
+
response_pcm = outputs[0].cpu().numpy().flatten()
|
|
40926
|
+
|
|
40927
|
+
# Convert to Int16 and send
|
|
40928
|
+
response_int16 = (response_pcm * 32767).astype(np.int16)
|
|
40929
|
+
await websocket.send(response_int16.tobytes())
|
|
40930
|
+
|
|
40931
|
+
# Send text if available
|
|
40932
|
+
if hasattr(outputs, "text") and outputs.text:
|
|
40933
|
+
await websocket.send(json.dumps({
|
|
40934
|
+
"type": "transcript",
|
|
40935
|
+
"speaker": "agent",
|
|
40936
|
+
"text": outputs.text
|
|
40937
|
+
}))
|
|
40938
|
+
|
|
40939
|
+
except websockets.exceptions.ConnectionClosed:
|
|
40940
|
+
print("Client disconnected", file=sys.stderr)
|
|
40941
|
+
|
|
40942
|
+
async def main():
|
|
40943
|
+
port = PORT
|
|
40944
|
+
server = await websockets.serve(handle_client, "127.0.0.1", port)
|
|
40945
|
+
actual_port = server.sockets[0].getsockname()[1]
|
|
40946
|
+
|
|
40947
|
+
# Write port file
|
|
40948
|
+
port_file = os.path.join(os.path.dirname(__file__), "daemon.port")
|
|
40949
|
+
with open(port_file, "w") as f:
|
|
40950
|
+
f.write(str(actual_port))
|
|
40951
|
+
|
|
40952
|
+
print(f"PersonaPlex daemon listening on ws://127.0.0.1:{actual_port}", file=sys.stderr)
|
|
40953
|
+
|
|
40954
|
+
# Handle shutdown
|
|
40955
|
+
loop = asyncio.get_event_loop()
|
|
40956
|
+
stop = asyncio.Future()
|
|
40957
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
40958
|
+
loop.add_signal_handler(sig, stop.set_result, None)
|
|
40959
|
+
await stop
|
|
40960
|
+
server.close()
|
|
40961
|
+
await server.wait_closed()
|
|
40962
|
+
|
|
40963
|
+
asyncio.run(main())
|
|
40964
|
+
`;
|
|
40965
|
+
writeFileSync16(scriptPath2, script, "utf8");
|
|
40966
|
+
return scriptPath2;
|
|
40967
|
+
}
|
|
40968
|
+
async function startPersonaPlexDaemon(onInfo) {
|
|
40969
|
+
const log = onInfo ?? (() => {
|
|
40970
|
+
});
|
|
40971
|
+
if (isPersonaPlexRunning()) {
|
|
40972
|
+
const url = getPersonaPlexWSUrl();
|
|
40973
|
+
if (url) {
|
|
40974
|
+
log(`PersonaPlex already running at ${url}`);
|
|
40975
|
+
return url;
|
|
40976
|
+
}
|
|
40977
|
+
}
|
|
40978
|
+
if (!isPersonaPlexInstalled()) {
|
|
40979
|
+
log("PersonaPlex not installed. Run /voice personaplex to set up.");
|
|
40980
|
+
return null;
|
|
40981
|
+
}
|
|
40982
|
+
mkdirSync15(PERSONAPLEX_DIR, { recursive: true });
|
|
40983
|
+
const scriptPath2 = writeDaemonScript();
|
|
40984
|
+
const venvPython2 = process.platform === "win32" ? join54(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join54(PERSONAPLEX_DIR, "venv", "bin", "python3");
|
|
40985
|
+
log("Starting PersonaPlex daemon...");
|
|
40986
|
+
const child = spawn19(venvPython2, [scriptPath2], {
|
|
40987
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
40988
|
+
detached: true,
|
|
40989
|
+
env: { ...process.env, PERSONAPLEX_PORT: "0" }
|
|
40990
|
+
});
|
|
40991
|
+
child.unref();
|
|
40992
|
+
const startTime = Date.now();
|
|
40993
|
+
const timeout = 6e4;
|
|
40994
|
+
while (Date.now() - startTime < timeout) {
|
|
40995
|
+
if (existsSync37(PORT_FILE)) {
|
|
40996
|
+
const port = parseInt(readFileSync28(PORT_FILE, "utf8").trim(), 10);
|
|
40997
|
+
if (!isNaN(port) && port > 0) {
|
|
40998
|
+
const url = `ws://127.0.0.1:${port}`;
|
|
40999
|
+
log(`PersonaPlex ready at ${url}`);
|
|
41000
|
+
return url;
|
|
41001
|
+
}
|
|
41002
|
+
}
|
|
41003
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
41004
|
+
}
|
|
41005
|
+
log("PersonaPlex daemon failed to start within 60s.");
|
|
41006
|
+
return null;
|
|
41007
|
+
}
|
|
41008
|
+
function stopPersonaPlex() {
|
|
41009
|
+
if (!existsSync37(PID_FILE))
|
|
41010
|
+
return;
|
|
41011
|
+
const pid = parseInt(readFileSync28(PID_FILE, "utf8").trim(), 10);
|
|
41012
|
+
if (isNaN(pid) || pid <= 0)
|
|
41013
|
+
return;
|
|
41014
|
+
try {
|
|
41015
|
+
if (process.platform === "win32") {
|
|
41016
|
+
execSync27(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
41017
|
+
} else {
|
|
41018
|
+
process.kill(pid, "SIGTERM");
|
|
41019
|
+
}
|
|
41020
|
+
} catch {
|
|
41021
|
+
}
|
|
41022
|
+
}
|
|
41023
|
+
var PERSONAPLEX_DIR, PID_FILE, PORT_FILE, LOG_FILE;
|
|
41024
|
+
var init_personaplex = __esm({
|
|
41025
|
+
"packages/cli/dist/tui/personaplex.js"() {
|
|
41026
|
+
"use strict";
|
|
41027
|
+
init_render();
|
|
41028
|
+
PERSONAPLEX_DIR = join54(homedir13(), ".open-agents", "voice", "personaplex");
|
|
41029
|
+
PID_FILE = join54(PERSONAPLEX_DIR, "daemon.pid");
|
|
41030
|
+
PORT_FILE = join54(PERSONAPLEX_DIR, "daemon.port");
|
|
41031
|
+
LOG_FILE = join54(PERSONAPLEX_DIR, "daemon.log");
|
|
41032
|
+
}
|
|
41033
|
+
});
|
|
41034
|
+
|
|
40727
41035
|
// packages/cli/dist/tui/setup.js
|
|
40728
41036
|
import * as readline from "node:readline";
|
|
40729
|
-
import { execSync as
|
|
41037
|
+
import { execSync as execSync28, spawn as spawn20, exec as exec2 } from "node:child_process";
|
|
40730
41038
|
import { promisify as promisify6 } from "node:util";
|
|
40731
|
-
import { existsSync as
|
|
40732
|
-
import { join as
|
|
40733
|
-
import { homedir as
|
|
41039
|
+
import { existsSync as existsSync38, writeFileSync as writeFileSync17, readFileSync as readFileSync29, appendFileSync as appendFileSync2, mkdirSync as mkdirSync16 } from "node:fs";
|
|
41040
|
+
import { join as join55 } from "node:path";
|
|
41041
|
+
import { homedir as homedir14, platform as platform2 } from "node:os";
|
|
40734
41042
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
40735
41043
|
if (_toolSupportCache.has(modelName))
|
|
40736
41044
|
return _toolSupportCache.get(modelName);
|
|
@@ -40761,7 +41069,7 @@ function detectSystemSpecs() {
|
|
|
40761
41069
|
let gpuVramGB = 0;
|
|
40762
41070
|
let gpuName = "";
|
|
40763
41071
|
try {
|
|
40764
|
-
const memInfo =
|
|
41072
|
+
const memInfo = execSync28("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
40765
41073
|
encoding: "utf8",
|
|
40766
41074
|
timeout: 5e3
|
|
40767
41075
|
});
|
|
@@ -40781,7 +41089,7 @@ function detectSystemSpecs() {
|
|
|
40781
41089
|
} catch {
|
|
40782
41090
|
}
|
|
40783
41091
|
try {
|
|
40784
|
-
const nvidiaSmi =
|
|
41092
|
+
const nvidiaSmi = execSync28("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
40785
41093
|
const lines = nvidiaSmi.trim().split("\n");
|
|
40786
41094
|
if (lines.length > 0) {
|
|
40787
41095
|
for (const line of lines) {
|
|
@@ -40952,7 +41260,7 @@ function ensureCurl() {
|
|
|
40952
41260
|
for (const s of strategies) {
|
|
40953
41261
|
if (hasCmd(s.check)) {
|
|
40954
41262
|
try {
|
|
40955
|
-
|
|
41263
|
+
execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
40956
41264
|
if (hasCmd("curl")) {
|
|
40957
41265
|
process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
|
|
40958
41266
|
`);
|
|
@@ -40966,7 +41274,7 @@ function ensureCurl() {
|
|
|
40966
41274
|
}
|
|
40967
41275
|
if (plat === "darwin") {
|
|
40968
41276
|
try {
|
|
40969
|
-
|
|
41277
|
+
execSync28("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
40970
41278
|
if (hasCmd("curl"))
|
|
40971
41279
|
return true;
|
|
40972
41280
|
} catch {
|
|
@@ -41001,7 +41309,7 @@ function installOllamaLinux() {
|
|
|
41001
41309
|
|
|
41002
41310
|
`);
|
|
41003
41311
|
try {
|
|
41004
|
-
|
|
41312
|
+
execSync28("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
41005
41313
|
stdio: "inherit",
|
|
41006
41314
|
timeout: 3e5
|
|
41007
41315
|
});
|
|
@@ -41029,10 +41337,10 @@ async function installOllamaMac(_rl) {
|
|
|
41029
41337
|
|
|
41030
41338
|
`);
|
|
41031
41339
|
try {
|
|
41032
|
-
|
|
41340
|
+
execSync28('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
41033
41341
|
if (!hasCmd("brew")) {
|
|
41034
41342
|
try {
|
|
41035
|
-
const brewPrefix =
|
|
41343
|
+
const brewPrefix = existsSync38("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
41036
41344
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
41037
41345
|
} catch {
|
|
41038
41346
|
}
|
|
@@ -41062,7 +41370,7 @@ async function installOllamaMac(_rl) {
|
|
|
41062
41370
|
|
|
41063
41371
|
`);
|
|
41064
41372
|
try {
|
|
41065
|
-
|
|
41373
|
+
execSync28("brew install ollama", {
|
|
41066
41374
|
stdio: "inherit",
|
|
41067
41375
|
timeout: 3e5
|
|
41068
41376
|
});
|
|
@@ -41089,7 +41397,7 @@ function installOllamaWindows() {
|
|
|
41089
41397
|
|
|
41090
41398
|
`);
|
|
41091
41399
|
try {
|
|
41092
|
-
|
|
41400
|
+
execSync28('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
41093
41401
|
stdio: "inherit",
|
|
41094
41402
|
timeout: 3e5
|
|
41095
41403
|
});
|
|
@@ -41140,7 +41448,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
41140
41448
|
process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
|
|
41141
41449
|
`);
|
|
41142
41450
|
try {
|
|
41143
|
-
const child =
|
|
41451
|
+
const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
41144
41452
|
child.unref();
|
|
41145
41453
|
} catch {
|
|
41146
41454
|
process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
|
|
@@ -41170,7 +41478,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
41170
41478
|
}
|
|
41171
41479
|
function pullModelWithAutoUpdate(tag) {
|
|
41172
41480
|
try {
|
|
41173
|
-
|
|
41481
|
+
execSync28(`ollama pull ${tag}`, {
|
|
41174
41482
|
stdio: "inherit",
|
|
41175
41483
|
timeout: 36e5
|
|
41176
41484
|
// 1 hour max
|
|
@@ -41190,7 +41498,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
41190
41498
|
|
|
41191
41499
|
`);
|
|
41192
41500
|
try {
|
|
41193
|
-
|
|
41501
|
+
execSync28("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
41194
41502
|
stdio: "inherit",
|
|
41195
41503
|
timeout: 3e5
|
|
41196
41504
|
// 5 min max for install
|
|
@@ -41201,7 +41509,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
41201
41509
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
41202
41510
|
|
|
41203
41511
|
`);
|
|
41204
|
-
|
|
41512
|
+
execSync28(`ollama pull ${tag}`, {
|
|
41205
41513
|
stdio: "inherit",
|
|
41206
41514
|
timeout: 36e5
|
|
41207
41515
|
});
|
|
@@ -41303,7 +41611,7 @@ function ensurePython3() {
|
|
|
41303
41611
|
if (plat === "darwin") {
|
|
41304
41612
|
if (hasCmd("brew")) {
|
|
41305
41613
|
try {
|
|
41306
|
-
|
|
41614
|
+
execSync28("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
41307
41615
|
if (hasCmd("python3")) {
|
|
41308
41616
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
|
|
41309
41617
|
`);
|
|
@@ -41316,7 +41624,7 @@ function ensurePython3() {
|
|
|
41316
41624
|
for (const s of strategies) {
|
|
41317
41625
|
if (hasCmd(s.check)) {
|
|
41318
41626
|
try {
|
|
41319
|
-
|
|
41627
|
+
execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
41320
41628
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
41321
41629
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
|
|
41322
41630
|
`);
|
|
@@ -41332,11 +41640,11 @@ function ensurePython3() {
|
|
|
41332
41640
|
}
|
|
41333
41641
|
function checkPythonVenv() {
|
|
41334
41642
|
try {
|
|
41335
|
-
|
|
41643
|
+
execSync28("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
41336
41644
|
return true;
|
|
41337
41645
|
} catch {
|
|
41338
41646
|
try {
|
|
41339
|
-
|
|
41647
|
+
execSync28("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
41340
41648
|
return true;
|
|
41341
41649
|
} catch {
|
|
41342
41650
|
return false;
|
|
@@ -41355,7 +41663,7 @@ function ensurePythonVenv() {
|
|
|
41355
41663
|
for (const s of strategies) {
|
|
41356
41664
|
if (hasCmd(s.check)) {
|
|
41357
41665
|
try {
|
|
41358
|
-
|
|
41666
|
+
execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
41359
41667
|
if (checkPythonVenv()) {
|
|
41360
41668
|
process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
|
|
41361
41669
|
`);
|
|
@@ -41513,6 +41821,20 @@ async function doSetup(config, rl) {
|
|
|
41513
41821
|
} else {
|
|
41514
41822
|
process.stdout.write(` ${c2.dim(" GPU:")} No NVIDIA GPU detected (CPU inference)
|
|
41515
41823
|
`);
|
|
41824
|
+
}
|
|
41825
|
+
let personaPlexCapable = false;
|
|
41826
|
+
try {
|
|
41827
|
+
const { detectPersonaPlexCapability: detectPersonaPlexCapability2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
41828
|
+
const ppCaps = detectPersonaPlexCapability2();
|
|
41829
|
+
personaPlexCapable = ppCaps.supported;
|
|
41830
|
+
if (ppCaps.supported) {
|
|
41831
|
+
process.stdout.write(` ${c2.green("\u2714")} PersonaPlex full-duplex voice: ${c2.bold("compatible")} (${ppCaps.gpuName}, ${ppCaps.vramGB.toFixed(0)}GB VRAM)
|
|
41832
|
+
`);
|
|
41833
|
+
process.stdout.write(` ${c2.dim("Enable with: /voice personaplex")}
|
|
41834
|
+
|
|
41835
|
+
`);
|
|
41836
|
+
}
|
|
41837
|
+
} catch {
|
|
41516
41838
|
}
|
|
41517
41839
|
const score = computeInferenceScore(specs);
|
|
41518
41840
|
const bw = 30;
|
|
@@ -41602,7 +41924,7 @@ async function doSetup(config, rl) {
|
|
|
41602
41924
|
${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
|
|
41603
41925
|
`);
|
|
41604
41926
|
try {
|
|
41605
|
-
const child =
|
|
41927
|
+
const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
41606
41928
|
child.unref();
|
|
41607
41929
|
await new Promise((resolve36) => setTimeout(resolve36, 3e3));
|
|
41608
41930
|
try {
|
|
@@ -41630,7 +41952,7 @@ async function doSetup(config, rl) {
|
|
|
41630
41952
|
${c2.cyan("\u25CF")} Starting ollama serve...
|
|
41631
41953
|
`);
|
|
41632
41954
|
try {
|
|
41633
|
-
const child =
|
|
41955
|
+
const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
41634
41956
|
child.unref();
|
|
41635
41957
|
await new Promise((resolve36) => setTimeout(resolve36, 3e3));
|
|
41636
41958
|
try {
|
|
@@ -41763,12 +42085,12 @@ async function doSetup(config, rl) {
|
|
|
41763
42085
|
`PARAMETER num_predict ${numPredict}`,
|
|
41764
42086
|
`PARAMETER stop "<|endoftext|>"`
|
|
41765
42087
|
].join("\n");
|
|
41766
|
-
const modelDir2 =
|
|
41767
|
-
|
|
41768
|
-
const modelfilePath =
|
|
41769
|
-
|
|
42088
|
+
const modelDir2 = join55(homedir14(), ".open-agents", "models");
|
|
42089
|
+
mkdirSync16(modelDir2, { recursive: true });
|
|
42090
|
+
const modelfilePath = join55(modelDir2, `Modelfile.${customName}`);
|
|
42091
|
+
writeFileSync17(modelfilePath, modelfileContent + "\n", "utf8");
|
|
41770
42092
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
41771
|
-
|
|
42093
|
+
execSync28(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
41772
42094
|
stdio: "pipe",
|
|
41773
42095
|
timeout: 12e4
|
|
41774
42096
|
});
|
|
@@ -41811,7 +42133,7 @@ async function isModelAvailable(config) {
|
|
|
41811
42133
|
}
|
|
41812
42134
|
function isFirstRun() {
|
|
41813
42135
|
try {
|
|
41814
|
-
return !
|
|
42136
|
+
return !existsSync38(join55(homedir14(), ".open-agents", "config.json"));
|
|
41815
42137
|
} catch {
|
|
41816
42138
|
return true;
|
|
41817
42139
|
}
|
|
@@ -41819,7 +42141,7 @@ function isFirstRun() {
|
|
|
41819
42141
|
function hasCmd(cmd) {
|
|
41820
42142
|
try {
|
|
41821
42143
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
41822
|
-
|
|
42144
|
+
execSync28(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
41823
42145
|
return true;
|
|
41824
42146
|
} catch {
|
|
41825
42147
|
return false;
|
|
@@ -41848,11 +42170,11 @@ function detectPkgManager() {
|
|
|
41848
42170
|
return null;
|
|
41849
42171
|
}
|
|
41850
42172
|
function getVenvDir() {
|
|
41851
|
-
return
|
|
42173
|
+
return join55(homedir14(), ".open-agents", "venv");
|
|
41852
42174
|
}
|
|
41853
42175
|
function hasVenvModule() {
|
|
41854
42176
|
try {
|
|
41855
|
-
|
|
42177
|
+
execSync28("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
41856
42178
|
return true;
|
|
41857
42179
|
} catch {
|
|
41858
42180
|
return false;
|
|
@@ -41861,9 +42183,9 @@ function hasVenvModule() {
|
|
|
41861
42183
|
function ensureVenv(log) {
|
|
41862
42184
|
const venvDir = getVenvDir();
|
|
41863
42185
|
const isWin2 = process.platform === "win32";
|
|
41864
|
-
const pipPath = isWin2 ?
|
|
42186
|
+
const pipPath = isWin2 ? join55(venvDir, "Scripts", "pip.exe") : join55(venvDir, "bin", "pip");
|
|
41865
42187
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
41866
|
-
if (
|
|
42188
|
+
if (existsSync38(pipPath))
|
|
41867
42189
|
return venvDir;
|
|
41868
42190
|
log("Creating Python venv for vision deps...");
|
|
41869
42191
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
@@ -41875,10 +42197,10 @@ function ensureVenv(log) {
|
|
|
41875
42197
|
return null;
|
|
41876
42198
|
}
|
|
41877
42199
|
try {
|
|
41878
|
-
|
|
42200
|
+
mkdirSync16(join55(homedir14(), ".open-agents"), { recursive: true });
|
|
41879
42201
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
41880
|
-
|
|
41881
|
-
|
|
42202
|
+
execSync28(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
42203
|
+
execSync28(`"${pipPath}" install --upgrade pip`, {
|
|
41882
42204
|
stdio: "pipe",
|
|
41883
42205
|
timeout: 6e4
|
|
41884
42206
|
});
|
|
@@ -41891,7 +42213,7 @@ function ensureVenv(log) {
|
|
|
41891
42213
|
}
|
|
41892
42214
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
41893
42215
|
try {
|
|
41894
|
-
|
|
42216
|
+
execSync28(`sudo -n ${cmd}`, {
|
|
41895
42217
|
stdio: "pipe",
|
|
41896
42218
|
timeout: timeoutMs,
|
|
41897
42219
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -41904,7 +42226,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
41904
42226
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
41905
42227
|
try {
|
|
41906
42228
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
41907
|
-
|
|
42229
|
+
execSync28(`sudo -S bash -c '${escaped}'`, {
|
|
41908
42230
|
input: password + "\n",
|
|
41909
42231
|
stdio: ["pipe", "pipe", "pipe"],
|
|
41910
42232
|
timeout: timeoutMs,
|
|
@@ -42021,7 +42343,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
42021
42343
|
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
42022
42344
|
} else {
|
|
42023
42345
|
try {
|
|
42024
|
-
|
|
42346
|
+
execSync28(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
42025
42347
|
ok = true;
|
|
42026
42348
|
} catch {
|
|
42027
42349
|
ok = false;
|
|
@@ -42058,7 +42380,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
42058
42380
|
const venvCmds = {
|
|
42059
42381
|
apt: () => {
|
|
42060
42382
|
try {
|
|
42061
|
-
const pyVer =
|
|
42383
|
+
const pyVer = execSync28(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
42062
42384
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
42063
42385
|
} catch {
|
|
42064
42386
|
return "apt-get install -y python3-venv";
|
|
@@ -42079,19 +42401,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
42079
42401
|
}
|
|
42080
42402
|
}
|
|
42081
42403
|
const venvDir = getVenvDir();
|
|
42082
|
-
const venvBin =
|
|
42083
|
-
const venvMoondream =
|
|
42404
|
+
const venvBin = join55(venvDir, "bin");
|
|
42405
|
+
const venvMoondream = join55(venvBin, "moondream-station");
|
|
42084
42406
|
const venv = ensureVenv(log);
|
|
42085
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
42086
|
-
const venvPip2 =
|
|
42407
|
+
if (venv && !hasCmd("moondream-station") && !existsSync38(venvMoondream)) {
|
|
42408
|
+
const venvPip2 = join55(venvBin, "pip");
|
|
42087
42409
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
42088
42410
|
try {
|
|
42089
|
-
|
|
42090
|
-
if (
|
|
42411
|
+
execSync28(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
42412
|
+
if (existsSync38(venvMoondream)) {
|
|
42091
42413
|
log("moondream-station installed successfully.");
|
|
42092
42414
|
} else {
|
|
42093
42415
|
try {
|
|
42094
|
-
const check =
|
|
42416
|
+
const check = execSync28(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
42095
42417
|
if (check.includes("moondream")) {
|
|
42096
42418
|
log("moondream-station package installed.");
|
|
42097
42419
|
}
|
|
@@ -42104,11 +42426,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
42104
42426
|
}
|
|
42105
42427
|
}
|
|
42106
42428
|
if (venv) {
|
|
42107
|
-
const venvPython2 =
|
|
42108
|
-
const venvPip2 =
|
|
42429
|
+
const venvPython2 = join55(venvBin, "python");
|
|
42430
|
+
const venvPip2 = join55(venvBin, "pip");
|
|
42109
42431
|
let ocrStackInstalled = false;
|
|
42110
42432
|
try {
|
|
42111
|
-
|
|
42433
|
+
execSync28(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
42112
42434
|
ocrStackInstalled = true;
|
|
42113
42435
|
} catch {
|
|
42114
42436
|
}
|
|
@@ -42116,9 +42438,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
42116
42438
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
42117
42439
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
42118
42440
|
try {
|
|
42119
|
-
|
|
42441
|
+
execSync28(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
42120
42442
|
try {
|
|
42121
|
-
|
|
42443
|
+
execSync28(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
42122
42444
|
log("OCR Python stack installed successfully.");
|
|
42123
42445
|
} catch {
|
|
42124
42446
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -42152,9 +42474,9 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
42152
42474
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
42153
42475
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
42154
42476
|
try {
|
|
42155
|
-
|
|
42156
|
-
if (!process.env.PATH?.includes(`${
|
|
42157
|
-
process.env.PATH = `${
|
|
42477
|
+
execSync28(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir14()}/.local/bin" && mv /tmp/cloudflared "${homedir14()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
42478
|
+
if (!process.env.PATH?.includes(`${homedir14()}/.local/bin`)) {
|
|
42479
|
+
process.env.PATH = `${homedir14()}/.local/bin:${process.env.PATH}`;
|
|
42158
42480
|
}
|
|
42159
42481
|
if (hasCmd("cloudflared")) {
|
|
42160
42482
|
log("cloudflared installed.");
|
|
@@ -42163,7 +42485,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
42163
42485
|
} catch {
|
|
42164
42486
|
}
|
|
42165
42487
|
try {
|
|
42166
|
-
|
|
42488
|
+
execSync28(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
|
|
42167
42489
|
if (hasCmd("cloudflared")) {
|
|
42168
42490
|
log("cloudflared installed.");
|
|
42169
42491
|
return true;
|
|
@@ -42172,7 +42494,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
42172
42494
|
}
|
|
42173
42495
|
} else if (os === "darwin") {
|
|
42174
42496
|
try {
|
|
42175
|
-
|
|
42497
|
+
execSync28("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
42176
42498
|
if (hasCmd("cloudflared")) {
|
|
42177
42499
|
log("cloudflared installed via Homebrew.");
|
|
42178
42500
|
return true;
|
|
@@ -42249,10 +42571,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
42249
42571
|
`PARAMETER num_predict ${numPredict}`,
|
|
42250
42572
|
`PARAMETER stop "<|endoftext|>"`
|
|
42251
42573
|
].join("\n");
|
|
42252
|
-
const modelDir2 =
|
|
42253
|
-
|
|
42254
|
-
const modelfilePath =
|
|
42255
|
-
|
|
42574
|
+
const modelDir2 = join55(homedir14(), ".open-agents", "models");
|
|
42575
|
+
mkdirSync16(modelDir2, { recursive: true });
|
|
42576
|
+
const modelfilePath = join55(modelDir2, `Modelfile.${customName}`);
|
|
42577
|
+
writeFileSync17(modelfilePath, modelfileContent + "\n", "utf8");
|
|
42256
42578
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
42257
42579
|
timeout: 12e4
|
|
42258
42580
|
});
|
|
@@ -42314,7 +42636,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
42314
42636
|
}
|
|
42315
42637
|
async function ensureNeovim() {
|
|
42316
42638
|
try {
|
|
42317
|
-
const nvimPath =
|
|
42639
|
+
const nvimPath = execSync28("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
42318
42640
|
encoding: "utf8",
|
|
42319
42641
|
stdio: "pipe",
|
|
42320
42642
|
timeout: 5e3
|
|
@@ -42326,24 +42648,24 @@ async function ensureNeovim() {
|
|
|
42326
42648
|
const platform6 = process.platform;
|
|
42327
42649
|
const arch2 = process.arch;
|
|
42328
42650
|
if (platform6 === "linux") {
|
|
42329
|
-
const binDir =
|
|
42330
|
-
const nvimDest =
|
|
42651
|
+
const binDir = join55(homedir14(), ".local", "bin");
|
|
42652
|
+
const nvimDest = join55(binDir, "nvim");
|
|
42331
42653
|
try {
|
|
42332
|
-
|
|
42654
|
+
mkdirSync16(binDir, { recursive: true });
|
|
42333
42655
|
} catch {
|
|
42334
42656
|
}
|
|
42335
42657
|
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
42336
42658
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
42337
42659
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
42338
42660
|
try {
|
|
42339
|
-
|
|
42340
|
-
|
|
42661
|
+
execSync28(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
42662
|
+
execSync28(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
42341
42663
|
} catch (err) {
|
|
42342
42664
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
42343
42665
|
return null;
|
|
42344
42666
|
}
|
|
42345
42667
|
try {
|
|
42346
|
-
const ver =
|
|
42668
|
+
const ver = execSync28(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
42347
42669
|
console.log(` Installed: ${ver}`);
|
|
42348
42670
|
} catch {
|
|
42349
42671
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -42358,8 +42680,8 @@ async function ensureNeovim() {
|
|
|
42358
42680
|
if (hasCmd("brew")) {
|
|
42359
42681
|
console.log(" Installing Neovim via Homebrew...");
|
|
42360
42682
|
try {
|
|
42361
|
-
|
|
42362
|
-
const nvimPath =
|
|
42683
|
+
execSync28("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
42684
|
+
const nvimPath = execSync28("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
42363
42685
|
return nvimPath || null;
|
|
42364
42686
|
} catch {
|
|
42365
42687
|
console.log(" brew install neovim failed.");
|
|
@@ -42373,7 +42695,7 @@ async function ensureNeovim() {
|
|
|
42373
42695
|
if (hasCmd("choco")) {
|
|
42374
42696
|
console.log(" Installing Neovim via Chocolatey...");
|
|
42375
42697
|
try {
|
|
42376
|
-
|
|
42698
|
+
execSync28("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
42377
42699
|
return "nvim";
|
|
42378
42700
|
} catch {
|
|
42379
42701
|
console.log(" choco install neovim failed.");
|
|
@@ -42382,7 +42704,7 @@ async function ensureNeovim() {
|
|
|
42382
42704
|
if (hasCmd("winget")) {
|
|
42383
42705
|
console.log(" Installing Neovim via winget...");
|
|
42384
42706
|
try {
|
|
42385
|
-
|
|
42707
|
+
execSync28("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
42386
42708
|
stdio: "inherit",
|
|
42387
42709
|
timeout: 12e4
|
|
42388
42710
|
});
|
|
@@ -42398,9 +42720,9 @@ async function ensureNeovim() {
|
|
|
42398
42720
|
}
|
|
42399
42721
|
function ensurePathInShellRc(binDir) {
|
|
42400
42722
|
const shell = process.env.SHELL ?? "";
|
|
42401
|
-
const rcFile = shell.includes("zsh") ?
|
|
42723
|
+
const rcFile = shell.includes("zsh") ? join55(homedir14(), ".zshrc") : join55(homedir14(), ".bashrc");
|
|
42402
42724
|
try {
|
|
42403
|
-
const rcContent =
|
|
42725
|
+
const rcContent = existsSync38(rcFile) ? readFileSync29(rcFile, "utf8") : "";
|
|
42404
42726
|
if (rcContent.includes(binDir))
|
|
42405
42727
|
return;
|
|
42406
42728
|
const exportLine = `
|
|
@@ -42438,7 +42760,7 @@ var init_setup = __esm({
|
|
|
42438
42760
|
});
|
|
42439
42761
|
|
|
42440
42762
|
// packages/cli/dist/tui/drop-panel.js
|
|
42441
|
-
import { existsSync as
|
|
42763
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
42442
42764
|
import { extname as extname10, resolve as resolve29 } from "node:path";
|
|
42443
42765
|
function ansi4(code, text) {
|
|
42444
42766
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
@@ -42553,7 +42875,7 @@ function showDropPanel(opts) {
|
|
|
42553
42875
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
42554
42876
|
}
|
|
42555
42877
|
filePath = resolve29(filePath);
|
|
42556
|
-
if (!
|
|
42878
|
+
if (!existsSync39(filePath)) {
|
|
42557
42879
|
errorMsg = `File not found: ${filePath}`;
|
|
42558
42880
|
render();
|
|
42559
42881
|
return;
|
|
@@ -42624,10 +42946,10 @@ var init_drop_panel = __esm({
|
|
|
42624
42946
|
});
|
|
42625
42947
|
|
|
42626
42948
|
// packages/cli/dist/tui/neovim-mode.js
|
|
42627
|
-
import { existsSync as
|
|
42949
|
+
import { existsSync as existsSync40, unlinkSync as unlinkSync8 } from "node:fs";
|
|
42628
42950
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
42629
|
-
import { join as
|
|
42630
|
-
import { execSync as
|
|
42951
|
+
import { join as join56 } from "node:path";
|
|
42952
|
+
import { execSync as execSync29 } from "node:child_process";
|
|
42631
42953
|
function isNeovimActive() {
|
|
42632
42954
|
return _state !== null && !_state.cleanedUp;
|
|
42633
42955
|
}
|
|
@@ -42645,7 +42967,7 @@ async function startNeovimMode(opts) {
|
|
|
42645
42967
|
}
|
|
42646
42968
|
let nvimPath;
|
|
42647
42969
|
try {
|
|
42648
|
-
nvimPath =
|
|
42970
|
+
nvimPath = execSync29("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
42649
42971
|
if (!nvimPath)
|
|
42650
42972
|
throw new Error();
|
|
42651
42973
|
} catch {
|
|
@@ -42674,9 +42996,9 @@ async function startNeovimMode(opts) {
|
|
|
42674
42996
|
);
|
|
42675
42997
|
} catch {
|
|
42676
42998
|
}
|
|
42677
|
-
const socketPath =
|
|
42999
|
+
const socketPath = join56(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
42678
43000
|
try {
|
|
42679
|
-
if (
|
|
43001
|
+
if (existsSync40(socketPath))
|
|
42680
43002
|
unlinkSync8(socketPath);
|
|
42681
43003
|
} catch {
|
|
42682
43004
|
}
|
|
@@ -42903,13 +43225,13 @@ function resizeNeovim(cols, contentRows) {
|
|
|
42903
43225
|
}
|
|
42904
43226
|
async function connectRPC(state, neovimPkg, cols) {
|
|
42905
43227
|
let attempts = 0;
|
|
42906
|
-
while (!
|
|
43228
|
+
while (!existsSync40(state.socketPath) && attempts < 30) {
|
|
42907
43229
|
await new Promise((r) => setTimeout(r, 200));
|
|
42908
43230
|
attempts++;
|
|
42909
43231
|
if (state.cleanedUp)
|
|
42910
43232
|
return;
|
|
42911
43233
|
}
|
|
42912
|
-
if (!
|
|
43234
|
+
if (!existsSync40(state.socketPath))
|
|
42913
43235
|
return;
|
|
42914
43236
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
42915
43237
|
state.nvim = nvim;
|
|
@@ -43046,7 +43368,7 @@ function doCleanup(state) {
|
|
|
43046
43368
|
state.pty = null;
|
|
43047
43369
|
}
|
|
43048
43370
|
try {
|
|
43049
|
-
if (
|
|
43371
|
+
if (existsSync40(state.socketPath))
|
|
43050
43372
|
unlinkSync8(state.socketPath);
|
|
43051
43373
|
} catch {
|
|
43052
43374
|
}
|
|
@@ -43481,8 +43803,8 @@ __export(sponsor_wizard_exports, {
|
|
|
43481
43803
|
saveSponsorConfig: () => saveSponsorConfig,
|
|
43482
43804
|
showSponsorDashboard: () => showSponsorDashboard
|
|
43483
43805
|
});
|
|
43484
|
-
import { existsSync as
|
|
43485
|
-
import { join as
|
|
43806
|
+
import { existsSync as existsSync41, readFileSync as readFileSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17 } from "node:fs";
|
|
43807
|
+
import { join as join57 } from "node:path";
|
|
43486
43808
|
function colorPreview(code) {
|
|
43487
43809
|
return `\x1B[38;5;${code}m\u2588\u2588\u2588\u2588\x1B[0m (${code})`;
|
|
43488
43810
|
}
|
|
@@ -43495,26 +43817,26 @@ function gradientPreview(start, end) {
|
|
|
43495
43817
|
return s;
|
|
43496
43818
|
}
|
|
43497
43819
|
function sponsorDir(projectDir) {
|
|
43498
|
-
return
|
|
43820
|
+
return join57(projectDir, ".oa", "sponsor");
|
|
43499
43821
|
}
|
|
43500
43822
|
function configPath(projectDir) {
|
|
43501
|
-
return
|
|
43823
|
+
return join57(sponsorDir(projectDir), "config.json");
|
|
43502
43824
|
}
|
|
43503
43825
|
function loadSponsorConfig(projectDir) {
|
|
43504
43826
|
const p = configPath(projectDir);
|
|
43505
|
-
if (!
|
|
43827
|
+
if (!existsSync41(p))
|
|
43506
43828
|
return null;
|
|
43507
43829
|
try {
|
|
43508
|
-
return JSON.parse(
|
|
43830
|
+
return JSON.parse(readFileSync30(p, "utf8"));
|
|
43509
43831
|
} catch {
|
|
43510
43832
|
return null;
|
|
43511
43833
|
}
|
|
43512
43834
|
}
|
|
43513
43835
|
function saveSponsorConfig(projectDir, config) {
|
|
43514
43836
|
const dir = sponsorDir(projectDir);
|
|
43515
|
-
|
|
43837
|
+
mkdirSync17(dir, { recursive: true });
|
|
43516
43838
|
config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
43517
|
-
|
|
43839
|
+
writeFileSync18(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
|
|
43518
43840
|
}
|
|
43519
43841
|
function defaultConfig() {
|
|
43520
43842
|
return {
|
|
@@ -44217,10 +44539,10 @@ __export(voice_exports, {
|
|
|
44217
44539
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
44218
44540
|
resetNarrationContext: () => resetNarrationContext
|
|
44219
44541
|
});
|
|
44220
|
-
import { existsSync as
|
|
44221
|
-
import { join as
|
|
44222
|
-
import { homedir as
|
|
44223
|
-
import { execSync as
|
|
44542
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync18, writeFileSync as writeFileSync19, readFileSync as readFileSync31, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
|
|
44543
|
+
import { join as join58, dirname as dirname18 } from "node:path";
|
|
44544
|
+
import { homedir as homedir15, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
44545
|
+
import { execSync as execSync30, spawn as nodeSpawn } from "node:child_process";
|
|
44224
44546
|
import { createRequire } from "node:module";
|
|
44225
44547
|
function sanitizeForTTS(text) {
|
|
44226
44548
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -44243,40 +44565,40 @@ function listVoiceModels() {
|
|
|
44243
44565
|
}));
|
|
44244
44566
|
}
|
|
44245
44567
|
function voiceDir() {
|
|
44246
|
-
return
|
|
44568
|
+
return join58(homedir15(), ".open-agents", "voice");
|
|
44247
44569
|
}
|
|
44248
44570
|
function modelsDir() {
|
|
44249
|
-
return
|
|
44571
|
+
return join58(voiceDir(), "models");
|
|
44250
44572
|
}
|
|
44251
44573
|
function modelDir(id) {
|
|
44252
|
-
return
|
|
44574
|
+
return join58(modelsDir(), id);
|
|
44253
44575
|
}
|
|
44254
44576
|
function modelOnnxPath(id) {
|
|
44255
|
-
return
|
|
44577
|
+
return join58(modelDir(id), "model.onnx");
|
|
44256
44578
|
}
|
|
44257
44579
|
function modelConfigPath(id) {
|
|
44258
|
-
return
|
|
44580
|
+
return join58(modelDir(id), "config.json");
|
|
44259
44581
|
}
|
|
44260
44582
|
function luxttsVenvDir() {
|
|
44261
|
-
return
|
|
44583
|
+
return join58(voiceDir(), "luxtts-venv");
|
|
44262
44584
|
}
|
|
44263
44585
|
function luxttsVenvPy() {
|
|
44264
|
-
return platform3() === "win32" ?
|
|
44586
|
+
return platform3() === "win32" ? join58(luxttsVenvDir(), "Scripts", "python.exe") : join58(luxttsVenvDir(), "bin", "python3");
|
|
44265
44587
|
}
|
|
44266
44588
|
function luxttsRepoDir() {
|
|
44267
|
-
return
|
|
44589
|
+
return join58(voiceDir(), "LuxTTS");
|
|
44268
44590
|
}
|
|
44269
44591
|
function luxttsCloneRefsDir() {
|
|
44270
|
-
return
|
|
44592
|
+
return join58(voiceDir(), "clone-refs");
|
|
44271
44593
|
}
|
|
44272
44594
|
function luxttsInferScript() {
|
|
44273
|
-
return
|
|
44595
|
+
return join58(voiceDir(), "luxtts-infer.py");
|
|
44274
44596
|
}
|
|
44275
44597
|
function writeDetectTorchScript(targetPath) {
|
|
44276
|
-
if (
|
|
44598
|
+
if (existsSync42(targetPath))
|
|
44277
44599
|
return;
|
|
44278
44600
|
try {
|
|
44279
|
-
|
|
44601
|
+
mkdirSync18(dirname18(targetPath), { recursive: true });
|
|
44280
44602
|
} catch {
|
|
44281
44603
|
}
|
|
44282
44604
|
const script = `#!/usr/bin/env python3
|
|
@@ -44349,7 +44671,7 @@ def main():
|
|
|
44349
44671
|
if __name__ == "__main__": main()
|
|
44350
44672
|
`;
|
|
44351
44673
|
try {
|
|
44352
|
-
|
|
44674
|
+
writeFileSync19(targetPath, script, { mode: 493 });
|
|
44353
44675
|
} catch {
|
|
44354
44676
|
}
|
|
44355
44677
|
}
|
|
@@ -45159,8 +45481,8 @@ var init_voice = __esm({
|
|
|
45159
45481
|
const refsDir = luxttsCloneRefsDir();
|
|
45160
45482
|
const targets = ["glados", "overwatch"];
|
|
45161
45483
|
for (const modelId of targets) {
|
|
45162
|
-
const refFile =
|
|
45163
|
-
if (
|
|
45484
|
+
const refFile = join58(refsDir, `${modelId}-ref.wav`);
|
|
45485
|
+
if (existsSync42(refFile))
|
|
45164
45486
|
continue;
|
|
45165
45487
|
try {
|
|
45166
45488
|
await this.generateCloneRef(modelId);
|
|
@@ -45239,24 +45561,24 @@ var init_voice = __esm({
|
|
|
45239
45561
|
}
|
|
45240
45562
|
p = p.replace(/\\ /g, " ");
|
|
45241
45563
|
if (p.startsWith("~/") || p === "~") {
|
|
45242
|
-
p =
|
|
45564
|
+
p = join58(homedir15(), p.slice(1));
|
|
45243
45565
|
}
|
|
45244
|
-
if (!
|
|
45566
|
+
if (!existsSync42(p)) {
|
|
45245
45567
|
return `File not found: ${p}
|
|
45246
45568
|
(original input: ${audioPath})`;
|
|
45247
45569
|
}
|
|
45248
45570
|
audioPath = p;
|
|
45249
45571
|
const refsDir = luxttsCloneRefsDir();
|
|
45250
|
-
if (!
|
|
45251
|
-
|
|
45572
|
+
if (!existsSync42(refsDir))
|
|
45573
|
+
mkdirSync18(refsDir, { recursive: true });
|
|
45252
45574
|
const ext = audioPath.split(".").pop() || "wav";
|
|
45253
45575
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
45254
45576
|
const ts = Date.now().toString(36);
|
|
45255
45577
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
45256
|
-
const destPath =
|
|
45578
|
+
const destPath = join58(refsDir, destFilename);
|
|
45257
45579
|
try {
|
|
45258
|
-
const data =
|
|
45259
|
-
|
|
45580
|
+
const data = readFileSync31(audioPath);
|
|
45581
|
+
writeFileSync19(destPath, data);
|
|
45260
45582
|
} catch (err) {
|
|
45261
45583
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
45262
45584
|
}
|
|
@@ -45296,9 +45618,9 @@ var init_voice = __esm({
|
|
|
45296
45618
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
45297
45619
|
}
|
|
45298
45620
|
const refsDir = luxttsCloneRefsDir();
|
|
45299
|
-
if (!
|
|
45300
|
-
|
|
45301
|
-
const destPath =
|
|
45621
|
+
if (!existsSync42(refsDir))
|
|
45622
|
+
mkdirSync18(refsDir, { recursive: true });
|
|
45623
|
+
const destPath = join58(refsDir, `${sourceModelId}-ref.wav`);
|
|
45302
45624
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
45303
45625
|
this.writeWav(audioData, sampleRate, destPath);
|
|
45304
45626
|
this.luxttsCloneRef = destPath;
|
|
@@ -45314,23 +45636,23 @@ var init_voice = __esm({
|
|
|
45314
45636
|
// -------------------------------------------------------------------------
|
|
45315
45637
|
/** Metadata file for friendly names of clone refs */
|
|
45316
45638
|
static cloneMetaFile() {
|
|
45317
|
-
return
|
|
45639
|
+
return join58(luxttsCloneRefsDir(), "meta.json");
|
|
45318
45640
|
}
|
|
45319
45641
|
loadCloneMeta() {
|
|
45320
45642
|
const p = _VoiceEngine.cloneMetaFile();
|
|
45321
|
-
if (!
|
|
45643
|
+
if (!existsSync42(p))
|
|
45322
45644
|
return {};
|
|
45323
45645
|
try {
|
|
45324
|
-
return JSON.parse(
|
|
45646
|
+
return JSON.parse(readFileSync31(p, "utf8"));
|
|
45325
45647
|
} catch {
|
|
45326
45648
|
return {};
|
|
45327
45649
|
}
|
|
45328
45650
|
}
|
|
45329
45651
|
saveCloneMeta(meta) {
|
|
45330
45652
|
const dir = luxttsCloneRefsDir();
|
|
45331
|
-
if (!
|
|
45332
|
-
|
|
45333
|
-
|
|
45653
|
+
if (!existsSync42(dir))
|
|
45654
|
+
mkdirSync18(dir, { recursive: true });
|
|
45655
|
+
writeFileSync19(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
45334
45656
|
}
|
|
45335
45657
|
/** Audio file extensions recognized as clone references */
|
|
45336
45658
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -45340,7 +45662,7 @@ var init_voice = __esm({
|
|
|
45340
45662
|
*/
|
|
45341
45663
|
listCloneRefs() {
|
|
45342
45664
|
const dir = luxttsCloneRefsDir();
|
|
45343
|
-
if (!
|
|
45665
|
+
if (!existsSync42(dir))
|
|
45344
45666
|
return [];
|
|
45345
45667
|
const meta = this.loadCloneMeta();
|
|
45346
45668
|
const files = readdirSync11(dir).filter((f) => {
|
|
@@ -45348,7 +45670,7 @@ var init_voice = __esm({
|
|
|
45348
45670
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
45349
45671
|
});
|
|
45350
45672
|
return files.map((f) => {
|
|
45351
|
-
const p =
|
|
45673
|
+
const p = join58(dir, f);
|
|
45352
45674
|
let size = 0;
|
|
45353
45675
|
try {
|
|
45354
45676
|
size = statSync13(p).size;
|
|
@@ -45365,8 +45687,8 @@ var init_voice = __esm({
|
|
|
45365
45687
|
}
|
|
45366
45688
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
45367
45689
|
deleteCloneRef(filename) {
|
|
45368
|
-
const p =
|
|
45369
|
-
if (!
|
|
45690
|
+
const p = join58(luxttsCloneRefsDir(), filename);
|
|
45691
|
+
if (!existsSync42(p))
|
|
45370
45692
|
return false;
|
|
45371
45693
|
try {
|
|
45372
45694
|
unlinkSync9(p);
|
|
@@ -45390,8 +45712,8 @@ var init_voice = __esm({
|
|
|
45390
45712
|
}
|
|
45391
45713
|
/** Set the active clone reference by filename. */
|
|
45392
45714
|
setActiveCloneRef(filename) {
|
|
45393
|
-
const p =
|
|
45394
|
-
if (!
|
|
45715
|
+
const p = join58(luxttsCloneRefsDir(), filename);
|
|
45716
|
+
if (!existsSync42(p))
|
|
45395
45717
|
return `File not found: ${filename}`;
|
|
45396
45718
|
this.luxttsCloneRef = p;
|
|
45397
45719
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -45716,7 +46038,7 @@ var init_voice = __esm({
|
|
|
45716
46038
|
}
|
|
45717
46039
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
45718
46040
|
}
|
|
45719
|
-
const wavPath =
|
|
46041
|
+
const wavPath = join58(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
45720
46042
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
45721
46043
|
await this.playWav(wavPath);
|
|
45722
46044
|
try {
|
|
@@ -45833,7 +46155,7 @@ var init_voice = __esm({
|
|
|
45833
46155
|
buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
|
|
45834
46156
|
pos += 2;
|
|
45835
46157
|
}
|
|
45836
|
-
|
|
46158
|
+
writeFileSync19(path, buffer);
|
|
45837
46159
|
}
|
|
45838
46160
|
// -------------------------------------------------------------------------
|
|
45839
46161
|
// Phonemization
|
|
@@ -45911,7 +46233,7 @@ var init_voice = __esm({
|
|
|
45911
46233
|
return buffer;
|
|
45912
46234
|
}
|
|
45913
46235
|
writeWav(samples, sampleRate, path) {
|
|
45914
|
-
|
|
46236
|
+
writeFileSync19(path, this.buildWavBuffer(samples, sampleRate));
|
|
45915
46237
|
}
|
|
45916
46238
|
// -------------------------------------------------------------------------
|
|
45917
46239
|
// Audio playback (system default speakers)
|
|
@@ -45961,7 +46283,7 @@ var init_voice = __esm({
|
|
|
45961
46283
|
}
|
|
45962
46284
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
45963
46285
|
try {
|
|
45964
|
-
|
|
46286
|
+
execSync30(`which ${player}`, { stdio: "pipe" });
|
|
45965
46287
|
return [player, path];
|
|
45966
46288
|
} catch {
|
|
45967
46289
|
}
|
|
@@ -45990,7 +46312,7 @@ var init_voice = __esm({
|
|
|
45990
46312
|
return this.python3Path;
|
|
45991
46313
|
for (const bin of ["python3", "python"]) {
|
|
45992
46314
|
try {
|
|
45993
|
-
const path =
|
|
46315
|
+
const path = execSync30(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
45994
46316
|
if (path) {
|
|
45995
46317
|
this.python3Path = path;
|
|
45996
46318
|
return path;
|
|
@@ -46056,7 +46378,7 @@ var init_voice = __esm({
|
|
|
46056
46378
|
return false;
|
|
46057
46379
|
}
|
|
46058
46380
|
try {
|
|
46059
|
-
|
|
46381
|
+
execSync30(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
46060
46382
|
this.mlxInstalled = true;
|
|
46061
46383
|
return true;
|
|
46062
46384
|
} catch {
|
|
@@ -46109,7 +46431,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46109
46431
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
46110
46432
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
46111
46433
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
46112
|
-
const wavPath =
|
|
46434
|
+
const wavPath = join58(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
46113
46435
|
const pyScript = [
|
|
46114
46436
|
"import sys, json",
|
|
46115
46437
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -46117,20 +46439,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46117
46439
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
46118
46440
|
].join("; ");
|
|
46119
46441
|
try {
|
|
46120
|
-
|
|
46442
|
+
execSync30(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
46121
46443
|
} catch (err) {
|
|
46122
46444
|
try {
|
|
46123
46445
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
46124
|
-
|
|
46446
|
+
execSync30(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
46125
46447
|
} catch (err2) {
|
|
46126
46448
|
return;
|
|
46127
46449
|
}
|
|
46128
46450
|
}
|
|
46129
|
-
if (!
|
|
46451
|
+
if (!existsSync42(wavPath))
|
|
46130
46452
|
return;
|
|
46131
46453
|
if (volume !== 1) {
|
|
46132
46454
|
try {
|
|
46133
|
-
const wavData =
|
|
46455
|
+
const wavData = readFileSync31(wavPath);
|
|
46134
46456
|
if (wavData.length > 44) {
|
|
46135
46457
|
const header = wavData.subarray(0, 44);
|
|
46136
46458
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -46138,14 +46460,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46138
46460
|
samples[i] = Math.round(samples[i] * volume);
|
|
46139
46461
|
}
|
|
46140
46462
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
46141
|
-
|
|
46463
|
+
writeFileSync19(wavPath, scaled);
|
|
46142
46464
|
}
|
|
46143
46465
|
} catch {
|
|
46144
46466
|
}
|
|
46145
46467
|
}
|
|
46146
46468
|
if (this.onPCMOutput) {
|
|
46147
46469
|
try {
|
|
46148
|
-
const wavData =
|
|
46470
|
+
const wavData = readFileSync31(wavPath);
|
|
46149
46471
|
if (wavData.length > 44) {
|
|
46150
46472
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
46151
46473
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -46177,7 +46499,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46177
46499
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
46178
46500
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
46179
46501
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
46180
|
-
const wavPath =
|
|
46502
|
+
const wavPath = join58(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
46181
46503
|
const pyScript = [
|
|
46182
46504
|
"import sys, json",
|
|
46183
46505
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -46185,19 +46507,19 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46185
46507
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
46186
46508
|
].join("; ");
|
|
46187
46509
|
try {
|
|
46188
|
-
|
|
46510
|
+
execSync30(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
46189
46511
|
} catch {
|
|
46190
46512
|
try {
|
|
46191
46513
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
46192
|
-
|
|
46514
|
+
execSync30(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
46193
46515
|
} catch {
|
|
46194
46516
|
return null;
|
|
46195
46517
|
}
|
|
46196
46518
|
}
|
|
46197
|
-
if (!
|
|
46519
|
+
if (!existsSync42(wavPath))
|
|
46198
46520
|
return null;
|
|
46199
46521
|
try {
|
|
46200
|
-
const data =
|
|
46522
|
+
const data = readFileSync31(wavPath);
|
|
46201
46523
|
unlinkSync9(wavPath);
|
|
46202
46524
|
return data;
|
|
46203
46525
|
} catch {
|
|
@@ -46220,7 +46542,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46220
46542
|
}
|
|
46221
46543
|
const venvDir = luxttsVenvDir();
|
|
46222
46544
|
const venvPy = luxttsVenvPy();
|
|
46223
|
-
if (
|
|
46545
|
+
if (existsSync42(venvPy)) {
|
|
46224
46546
|
try {
|
|
46225
46547
|
await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
|
|
46226
46548
|
let hasCudaSys = false;
|
|
@@ -46234,7 +46556,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46234
46556
|
if (torchCheck === "cpu") {
|
|
46235
46557
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
46236
46558
|
try {
|
|
46237
|
-
const detectScript =
|
|
46559
|
+
const detectScript = join58(voiceDir(), "detect-torch.py");
|
|
46238
46560
|
writeDetectTorchScript(detectScript);
|
|
46239
46561
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
46240
46562
|
try {
|
|
@@ -46259,7 +46581,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46259
46581
|
}
|
|
46260
46582
|
}
|
|
46261
46583
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
46262
|
-
if (!
|
|
46584
|
+
if (!existsSync42(venvDir)) {
|
|
46263
46585
|
renderInfo(" Creating Python virtual environment...");
|
|
46264
46586
|
try {
|
|
46265
46587
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -46268,7 +46590,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46268
46590
|
}
|
|
46269
46591
|
}
|
|
46270
46592
|
{
|
|
46271
|
-
const detectScript =
|
|
46593
|
+
const detectScript = join58(voiceDir(), "detect-torch.py");
|
|
46272
46594
|
writeDetectTorchScript(detectScript);
|
|
46273
46595
|
let pipArgsStr = "torch torchaudio";
|
|
46274
46596
|
let torchDesc = "unknown platform";
|
|
@@ -46305,10 +46627,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46305
46627
|
}
|
|
46306
46628
|
}
|
|
46307
46629
|
const repoDir = luxttsRepoDir();
|
|
46308
|
-
if (!
|
|
46630
|
+
if (!existsSync42(join58(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
46309
46631
|
renderInfo(" Cloning LuxTTS repository...");
|
|
46310
46632
|
try {
|
|
46311
|
-
if (
|
|
46633
|
+
if (existsSync42(repoDir)) {
|
|
46312
46634
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
46313
46635
|
await this.asyncShell(rmCmd, 3e4);
|
|
46314
46636
|
}
|
|
@@ -46387,7 +46709,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46387
46709
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
46388
46710
|
}
|
|
46389
46711
|
}
|
|
46390
|
-
const isJetson = isArm && (
|
|
46712
|
+
const isJetson = isArm && (existsSync42("/etc/nv_tegra_release") || existsSync42("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
46391
46713
|
const installSteps = isArm ? [
|
|
46392
46714
|
// ARM: install individually so we get clear error messages per package.
|
|
46393
46715
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -46457,14 +46779,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
46457
46779
|
}
|
|
46458
46780
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
46459
46781
|
autoDetectCloneRef() {
|
|
46460
|
-
if (this.luxttsCloneRef &&
|
|
46782
|
+
if (this.luxttsCloneRef && existsSync42(this.luxttsCloneRef))
|
|
46461
46783
|
return;
|
|
46462
46784
|
const refsDir = luxttsCloneRefsDir();
|
|
46463
|
-
if (!
|
|
46785
|
+
if (!existsSync42(refsDir))
|
|
46464
46786
|
return;
|
|
46465
46787
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
46466
|
-
const p =
|
|
46467
|
-
if (
|
|
46788
|
+
const p = join58(refsDir, name);
|
|
46789
|
+
if (existsSync42(p)) {
|
|
46468
46790
|
this.luxttsCloneRef = p;
|
|
46469
46791
|
return;
|
|
46470
46792
|
}
|
|
@@ -46564,15 +46886,15 @@ if __name__ == '__main__':
|
|
|
46564
46886
|
main()
|
|
46565
46887
|
`;
|
|
46566
46888
|
const scriptPath2 = luxttsInferScript();
|
|
46567
|
-
|
|
46568
|
-
|
|
46889
|
+
mkdirSync18(voiceDir(), { recursive: true });
|
|
46890
|
+
writeFileSync19(scriptPath2, script);
|
|
46569
46891
|
}
|
|
46570
46892
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
46571
46893
|
async ensureLuxttsDaemon() {
|
|
46572
46894
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
46573
46895
|
return true;
|
|
46574
46896
|
const venvPy = luxttsVenvPy();
|
|
46575
|
-
if (!
|
|
46897
|
+
if (!existsSync42(venvPy))
|
|
46576
46898
|
return false;
|
|
46577
46899
|
return new Promise((resolve36) => {
|
|
46578
46900
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
@@ -46656,7 +46978,7 @@ if __name__ == '__main__':
|
|
|
46656
46978
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
46657
46979
|
*/
|
|
46658
46980
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
46659
|
-
if (!this.luxttsCloneRef || !
|
|
46981
|
+
if (!this.luxttsCloneRef || !existsSync42(this.luxttsCloneRef))
|
|
46660
46982
|
return null;
|
|
46661
46983
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
46662
46984
|
if (!cleaned)
|
|
@@ -46664,7 +46986,7 @@ if __name__ == '__main__':
|
|
|
46664
46986
|
const ready = await this.ensureLuxttsDaemon();
|
|
46665
46987
|
if (!ready)
|
|
46666
46988
|
return null;
|
|
46667
|
-
const wavPath =
|
|
46989
|
+
const wavPath = join58(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
46668
46990
|
try {
|
|
46669
46991
|
await this.luxttsRequest({
|
|
46670
46992
|
action: "synthesize",
|
|
@@ -46676,17 +46998,17 @@ if __name__ == '__main__':
|
|
|
46676
46998
|
} catch {
|
|
46677
46999
|
return null;
|
|
46678
47000
|
}
|
|
46679
|
-
return
|
|
47001
|
+
return existsSync42(wavPath) ? wavPath : null;
|
|
46680
47002
|
}
|
|
46681
47003
|
/**
|
|
46682
47004
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
46683
47005
|
* Cleans up the WAV file after playback.
|
|
46684
47006
|
*/
|
|
46685
47007
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
46686
|
-
if (!
|
|
47008
|
+
if (!existsSync42(wavPath))
|
|
46687
47009
|
return;
|
|
46688
47010
|
try {
|
|
46689
|
-
const wavData =
|
|
47011
|
+
const wavData = readFileSync31(wavPath);
|
|
46690
47012
|
if (wavData.length > 44) {
|
|
46691
47013
|
const sampleRate = wavData.readUInt32LE(24);
|
|
46692
47014
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -46701,13 +47023,13 @@ if __name__ == '__main__':
|
|
|
46701
47023
|
}
|
|
46702
47024
|
const header = wavData.subarray(0, 44);
|
|
46703
47025
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
46704
|
-
|
|
47026
|
+
writeFileSync19(wavPath, scaled);
|
|
46705
47027
|
}
|
|
46706
47028
|
} catch {
|
|
46707
47029
|
}
|
|
46708
47030
|
if (pitchFactor !== 1) {
|
|
46709
47031
|
try {
|
|
46710
|
-
const wavData =
|
|
47032
|
+
const wavData = readFileSync31(wavPath);
|
|
46711
47033
|
if (wavData.length > 44) {
|
|
46712
47034
|
const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
46713
47035
|
const float32 = new Float32Array(int16.length);
|
|
@@ -46722,7 +47044,7 @@ if __name__ == '__main__':
|
|
|
46722
47044
|
}
|
|
46723
47045
|
if (this.onPCMOutput) {
|
|
46724
47046
|
try {
|
|
46725
|
-
const wavData =
|
|
47047
|
+
const wavData = readFileSync31(wavPath);
|
|
46726
47048
|
if (wavData.length > 44) {
|
|
46727
47049
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
46728
47050
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -46733,7 +47055,7 @@ if __name__ == '__main__':
|
|
|
46733
47055
|
}
|
|
46734
47056
|
if (stereoDelayMs > 0) {
|
|
46735
47057
|
try {
|
|
46736
|
-
const wavData =
|
|
47058
|
+
const wavData = readFileSync31(wavPath);
|
|
46737
47059
|
if (wavData.length > 44) {
|
|
46738
47060
|
const sampleRate = wavData.readUInt32LE(24);
|
|
46739
47061
|
const numChannels = wavData.readUInt16LE(22);
|
|
@@ -46769,7 +47091,7 @@ if __name__ == '__main__':
|
|
|
46769
47091
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
46770
47092
|
*/
|
|
46771
47093
|
async synthesizeLuxttsToBuffer(text) {
|
|
46772
|
-
if (!this.luxttsCloneRef || !
|
|
47094
|
+
if (!this.luxttsCloneRef || !existsSync42(this.luxttsCloneRef))
|
|
46773
47095
|
return null;
|
|
46774
47096
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
46775
47097
|
if (!cleaned)
|
|
@@ -46777,7 +47099,7 @@ if __name__ == '__main__':
|
|
|
46777
47099
|
const ready = await this.ensureLuxttsDaemon();
|
|
46778
47100
|
if (!ready)
|
|
46779
47101
|
return null;
|
|
46780
|
-
const wavPath =
|
|
47102
|
+
const wavPath = join58(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
46781
47103
|
try {
|
|
46782
47104
|
await this.luxttsRequest({
|
|
46783
47105
|
action: "synthesize",
|
|
@@ -46789,10 +47111,10 @@ if __name__ == '__main__':
|
|
|
46789
47111
|
} catch {
|
|
46790
47112
|
return null;
|
|
46791
47113
|
}
|
|
46792
|
-
if (!
|
|
47114
|
+
if (!existsSync42(wavPath))
|
|
46793
47115
|
return null;
|
|
46794
47116
|
try {
|
|
46795
|
-
const data =
|
|
47117
|
+
const data = readFileSync31(wavPath);
|
|
46796
47118
|
unlinkSync9(wavPath);
|
|
46797
47119
|
return data;
|
|
46798
47120
|
} catch {
|
|
@@ -46806,40 +47128,40 @@ if __name__ == '__main__':
|
|
|
46806
47128
|
if (this.ort)
|
|
46807
47129
|
return;
|
|
46808
47130
|
const arch2 = process.arch;
|
|
46809
|
-
|
|
46810
|
-
const pkgPath =
|
|
47131
|
+
mkdirSync18(voiceDir(), { recursive: true });
|
|
47132
|
+
const pkgPath = join58(voiceDir(), "package.json");
|
|
46811
47133
|
const expectedDeps = {
|
|
46812
47134
|
"onnxruntime-node": "^1.21.0",
|
|
46813
47135
|
"phonemizer": "^1.2.1"
|
|
46814
47136
|
};
|
|
46815
|
-
if (
|
|
47137
|
+
if (existsSync42(pkgPath)) {
|
|
46816
47138
|
try {
|
|
46817
|
-
const existing = JSON.parse(
|
|
47139
|
+
const existing = JSON.parse(readFileSync31(pkgPath, "utf8"));
|
|
46818
47140
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
46819
47141
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
46820
|
-
|
|
47142
|
+
writeFileSync19(pkgPath, JSON.stringify(existing, null, 2));
|
|
46821
47143
|
}
|
|
46822
47144
|
} catch {
|
|
46823
47145
|
}
|
|
46824
47146
|
}
|
|
46825
|
-
if (!
|
|
46826
|
-
|
|
47147
|
+
if (!existsSync42(pkgPath)) {
|
|
47148
|
+
writeFileSync19(pkgPath, JSON.stringify({
|
|
46827
47149
|
name: "open-agents-voice",
|
|
46828
47150
|
private: true,
|
|
46829
47151
|
dependencies: expectedDeps
|
|
46830
47152
|
}, null, 2));
|
|
46831
47153
|
}
|
|
46832
|
-
const voiceRequire = createRequire(
|
|
47154
|
+
const voiceRequire = createRequire(join58(voiceDir(), "index.js"));
|
|
46833
47155
|
const probeOnnx = async () => {
|
|
46834
47156
|
try {
|
|
46835
|
-
const output = await this.asyncShell(`NODE_PATH="${
|
|
47157
|
+
const output = await this.asyncShell(`NODE_PATH="${join58(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
|
|
46836
47158
|
return output.trim() === "OK";
|
|
46837
47159
|
} catch {
|
|
46838
47160
|
return false;
|
|
46839
47161
|
}
|
|
46840
47162
|
};
|
|
46841
|
-
const onnxNodeModules =
|
|
46842
|
-
const onnxInstalled =
|
|
47163
|
+
const onnxNodeModules = join58(voiceDir(), "node_modules", "onnxruntime-node");
|
|
47164
|
+
const onnxInstalled = existsSync42(onnxNodeModules);
|
|
46843
47165
|
if (onnxInstalled && !await probeOnnx()) {
|
|
46844
47166
|
throw new Error(`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.`);
|
|
46845
47167
|
}
|
|
@@ -46889,18 +47211,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
46889
47211
|
const dir = modelDir(id);
|
|
46890
47212
|
const onnxPath = modelOnnxPath(id);
|
|
46891
47213
|
const configPath2 = modelConfigPath(id);
|
|
46892
|
-
if (
|
|
47214
|
+
if (existsSync42(onnxPath) && existsSync42(configPath2))
|
|
46893
47215
|
return;
|
|
46894
|
-
|
|
46895
|
-
if (!
|
|
47216
|
+
mkdirSync18(dir, { recursive: true });
|
|
47217
|
+
if (!existsSync42(configPath2)) {
|
|
46896
47218
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
46897
47219
|
const configResp = await fetch(model.configUrl);
|
|
46898
47220
|
if (!configResp.ok)
|
|
46899
47221
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
46900
47222
|
const configText = await configResp.text();
|
|
46901
|
-
|
|
47223
|
+
writeFileSync19(configPath2, configText);
|
|
46902
47224
|
}
|
|
46903
|
-
if (!
|
|
47225
|
+
if (!existsSync42(onnxPath)) {
|
|
46904
47226
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
46905
47227
|
const onnxResp = await fetch(model.onnxUrl);
|
|
46906
47228
|
if (!onnxResp.ok)
|
|
@@ -46925,7 +47247,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
46925
47247
|
}
|
|
46926
47248
|
}
|
|
46927
47249
|
const fullBuffer = Buffer.concat(chunks);
|
|
46928
|
-
|
|
47250
|
+
writeFileSync19(onnxPath, fullBuffer);
|
|
46929
47251
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
46930
47252
|
}
|
|
46931
47253
|
}
|
|
@@ -46937,10 +47259,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
46937
47259
|
throw new Error("ONNX runtime not loaded");
|
|
46938
47260
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
46939
47261
|
const configPath2 = modelConfigPath(this.modelId);
|
|
46940
|
-
if (!
|
|
47262
|
+
if (!existsSync42(onnxPath) || !existsSync42(configPath2)) {
|
|
46941
47263
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
46942
47264
|
}
|
|
46943
|
-
this.config = JSON.parse(
|
|
47265
|
+
this.config = JSON.parse(readFileSync31(configPath2, "utf8"));
|
|
46944
47266
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
46945
47267
|
executionProviders: ["cpu"],
|
|
46946
47268
|
graphOptimizationLevel: "all"
|
|
@@ -46967,8 +47289,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
46967
47289
|
// packages/cli/dist/tui/commands.js
|
|
46968
47290
|
import * as nodeOs from "node:os";
|
|
46969
47291
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
46970
|
-
import { existsSync as
|
|
46971
|
-
import { join as
|
|
47292
|
+
import { existsSync as existsSync43, readFileSync as readFileSync32, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
|
|
47293
|
+
import { join as join59 } from "node:path";
|
|
46972
47294
|
function safeLog(text) {
|
|
46973
47295
|
if (isNeovimActive()) {
|
|
46974
47296
|
writeToNeovimOutput(text + "\n");
|
|
@@ -47387,9 +47709,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47387
47709
|
renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
|
|
47388
47710
|
}
|
|
47389
47711
|
} else if (sub === "name") {
|
|
47390
|
-
const { homedir:
|
|
47712
|
+
const { homedir: homedir21 } = __require("node:os");
|
|
47391
47713
|
const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
|
|
47392
|
-
const namePath = __require("node:path").join(
|
|
47714
|
+
const namePath = __require("node:path").join(homedir21(), ".open-agents", "agent-name");
|
|
47393
47715
|
if (rest2) {
|
|
47394
47716
|
const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
|
|
47395
47717
|
if (!customName) {
|
|
@@ -47662,22 +47984,22 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47662
47984
|
let content = "";
|
|
47663
47985
|
let metadata = {};
|
|
47664
47986
|
if (shareType === "tool") {
|
|
47665
|
-
const toolDir =
|
|
47666
|
-
const toolFile =
|
|
47667
|
-
if (!
|
|
47987
|
+
const toolDir = join59(ctx.repoRoot, ".oa", "tools");
|
|
47988
|
+
const toolFile = join59(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
47989
|
+
if (!existsSync43(toolFile)) {
|
|
47668
47990
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
47669
47991
|
return "handled";
|
|
47670
47992
|
}
|
|
47671
|
-
content =
|
|
47993
|
+
content = readFileSync32(toolFile, "utf8");
|
|
47672
47994
|
metadata = { type: "tool", name: shareName };
|
|
47673
47995
|
} else if (shareType === "skill") {
|
|
47674
|
-
const skillDir =
|
|
47675
|
-
const skillFile =
|
|
47676
|
-
if (!
|
|
47996
|
+
const skillDir = join59(ctx.repoRoot, ".oa", "skills", shareName);
|
|
47997
|
+
const skillFile = join59(skillDir, "SKILL.md");
|
|
47998
|
+
if (!existsSync43(skillFile)) {
|
|
47677
47999
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
47678
48000
|
return "handled";
|
|
47679
48001
|
}
|
|
47680
|
-
content =
|
|
48002
|
+
content = readFileSync32(skillFile, "utf8");
|
|
47681
48003
|
metadata = { type: "skill", name: shareName };
|
|
47682
48004
|
} else {
|
|
47683
48005
|
renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
|
|
@@ -47714,9 +48036,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47714
48036
|
try {
|
|
47715
48037
|
const nexus = new NexusTool(ctx.repoRoot);
|
|
47716
48038
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
47717
|
-
const regFile =
|
|
47718
|
-
if (
|
|
47719
|
-
const reg = JSON.parse(
|
|
48039
|
+
const regFile = join59(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
48040
|
+
if (existsSync43(regFile)) {
|
|
48041
|
+
const reg = JSON.parse(readFileSync32(regFile, "utf8"));
|
|
47720
48042
|
const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
|
|
47721
48043
|
if (pinned) {
|
|
47722
48044
|
renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
|
|
@@ -47768,33 +48090,33 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47768
48090
|
lines.push(`
|
|
47769
48091
|
${c2.bold("IPFS / Helia Status")}
|
|
47770
48092
|
`);
|
|
47771
|
-
const ipfsDir =
|
|
47772
|
-
const ipfsLocalDir =
|
|
48093
|
+
const ipfsDir = join59(ctx.repoRoot, ".oa", "ipfs");
|
|
48094
|
+
const ipfsLocalDir = join59(ipfsDir, "local");
|
|
47773
48095
|
let ipfsFiles = 0;
|
|
47774
48096
|
let ipfsBytes = 0;
|
|
47775
48097
|
let heliaBlocks = 0;
|
|
47776
48098
|
let heliaBytes = 0;
|
|
47777
48099
|
try {
|
|
47778
|
-
if (
|
|
48100
|
+
if (existsSync43(ipfsLocalDir)) {
|
|
47779
48101
|
const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
|
|
47780
48102
|
ipfsFiles = files.length;
|
|
47781
48103
|
for (const f of files) {
|
|
47782
48104
|
try {
|
|
47783
|
-
ipfsBytes += statSync14(
|
|
48105
|
+
ipfsBytes += statSync14(join59(ipfsLocalDir, f)).size;
|
|
47784
48106
|
} catch {
|
|
47785
48107
|
}
|
|
47786
48108
|
}
|
|
47787
48109
|
}
|
|
47788
|
-
const heliaBlockDir =
|
|
47789
|
-
if (
|
|
48110
|
+
const heliaBlockDir = join59(ipfsDir, "blocks");
|
|
48111
|
+
if (existsSync43(heliaBlockDir)) {
|
|
47790
48112
|
const walkDir = (dir) => {
|
|
47791
48113
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
47792
48114
|
if (entry.isDirectory())
|
|
47793
|
-
walkDir(
|
|
48115
|
+
walkDir(join59(dir, entry.name));
|
|
47794
48116
|
else {
|
|
47795
48117
|
heliaBlocks++;
|
|
47796
48118
|
try {
|
|
47797
|
-
heliaBytes += statSync14(
|
|
48119
|
+
heliaBytes += statSync14(join59(dir, entry.name)).size;
|
|
47798
48120
|
} catch {
|
|
47799
48121
|
}
|
|
47800
48122
|
}
|
|
@@ -47810,9 +48132,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47810
48132
|
lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
|
|
47811
48133
|
lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
|
|
47812
48134
|
try {
|
|
47813
|
-
const statusFile =
|
|
47814
|
-
if (
|
|
47815
|
-
const status = JSON.parse(
|
|
48135
|
+
const statusFile = join59(ctx.repoRoot, ".oa", "nexus", "status.json");
|
|
48136
|
+
if (existsSync43(statusFile)) {
|
|
48137
|
+
const status = JSON.parse(readFileSync32(statusFile, "utf8"));
|
|
47816
48138
|
if (status.peerId) {
|
|
47817
48139
|
lines.push(`
|
|
47818
48140
|
${c2.bold("Peer Info")}`);
|
|
@@ -47831,11 +48153,11 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47831
48153
|
${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
47832
48154
|
lines.push(`
|
|
47833
48155
|
${c2.bold("Identity Kernel")}`);
|
|
47834
|
-
const idDir =
|
|
48156
|
+
const idDir = join59(ctx.repoRoot, ".oa", "identity");
|
|
47835
48157
|
try {
|
|
47836
|
-
const stateFile =
|
|
47837
|
-
if (
|
|
47838
|
-
const state = JSON.parse(
|
|
48158
|
+
const stateFile = join59(idDir, "self-state.json");
|
|
48159
|
+
if (existsSync43(stateFile)) {
|
|
48160
|
+
const state = JSON.parse(readFileSync32(stateFile, "utf8"));
|
|
47839
48161
|
lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
|
|
47840
48162
|
if (state.narrative_summary) {
|
|
47841
48163
|
lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
|
|
@@ -47844,9 +48166,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47844
48166
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
47845
48167
|
lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
|
|
47846
48168
|
}
|
|
47847
|
-
const cidFile =
|
|
47848
|
-
if (
|
|
47849
|
-
const cids = JSON.parse(
|
|
48169
|
+
const cidFile = join59(idDir, "cids.json");
|
|
48170
|
+
if (existsSync43(cidFile)) {
|
|
48171
|
+
const cids = JSON.parse(readFileSync32(cidFile, "utf8"));
|
|
47850
48172
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
47851
48173
|
if (lastCid)
|
|
47852
48174
|
lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -47859,9 +48181,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47859
48181
|
lines.push(`
|
|
47860
48182
|
${c2.bold("Memory Sentiment")}`);
|
|
47861
48183
|
try {
|
|
47862
|
-
const metaFile =
|
|
47863
|
-
if (
|
|
47864
|
-
const store = JSON.parse(
|
|
48184
|
+
const metaFile = join59(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
48185
|
+
if (existsSync43(metaFile)) {
|
|
48186
|
+
const store = JSON.parse(readFileSync32(metaFile, "utf8"));
|
|
47865
48187
|
const active = store.filter((m) => m.type !== "quarantine");
|
|
47866
48188
|
const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
|
|
47867
48189
|
const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
|
|
@@ -47879,8 +48201,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47879
48201
|
} catch {
|
|
47880
48202
|
}
|
|
47881
48203
|
try {
|
|
47882
|
-
const dbPath =
|
|
47883
|
-
if (
|
|
48204
|
+
const dbPath = join59(ctx.repoRoot, ".oa", "memory", "structured.db");
|
|
48205
|
+
if (existsSync43(dbPath)) {
|
|
47884
48206
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
47885
48207
|
const db = initDb2(dbPath);
|
|
47886
48208
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -47901,8 +48223,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47901
48223
|
lines.push(`
|
|
47902
48224
|
${c2.bold("Storage Overview")}
|
|
47903
48225
|
`);
|
|
47904
|
-
const oaDir =
|
|
47905
|
-
if (!
|
|
48226
|
+
const oaDir = join59(ctx.repoRoot, ".oa");
|
|
48227
|
+
if (!existsSync43(oaDir)) {
|
|
47906
48228
|
lines.push(` ${c2.dim("No .oa/ directory found.")}`);
|
|
47907
48229
|
safeLog(lines.join("\n") + "\n");
|
|
47908
48230
|
return "handled";
|
|
@@ -47912,7 +48234,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47912
48234
|
const walkStorage = (dir, category) => {
|
|
47913
48235
|
try {
|
|
47914
48236
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
47915
|
-
const full =
|
|
48237
|
+
const full = join59(dir, entry.name);
|
|
47916
48238
|
if (entry.isDirectory()) {
|
|
47917
48239
|
const subCat = category || entry.name;
|
|
47918
48240
|
walkStorage(full, subCat);
|
|
@@ -47948,10 +48270,10 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47948
48270
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
47949
48271
|
const name = entry.name.toLowerCase();
|
|
47950
48272
|
if (sensitivePatterns.some((p) => name.includes(p))) {
|
|
47951
|
-
sensitiveFound.push(
|
|
48273
|
+
sensitiveFound.push(join59(dir, entry.name).replace(oaDir + "/", ""));
|
|
47952
48274
|
}
|
|
47953
48275
|
if (entry.isDirectory())
|
|
47954
|
-
checkSensitive(
|
|
48276
|
+
checkSensitive(join59(dir, entry.name));
|
|
47955
48277
|
}
|
|
47956
48278
|
} catch {
|
|
47957
48279
|
}
|
|
@@ -47979,8 +48301,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47979
48301
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
47980
48302
|
return "handled";
|
|
47981
48303
|
}
|
|
47982
|
-
const resolvedPath =
|
|
47983
|
-
if (!
|
|
48304
|
+
const resolvedPath = join59(ctx.repoRoot, filePath);
|
|
48305
|
+
if (!existsSync43(resolvedPath)) {
|
|
47984
48306
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
47985
48307
|
return "handled";
|
|
47986
48308
|
}
|
|
@@ -47996,9 +48318,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
47996
48318
|
}
|
|
47997
48319
|
try {
|
|
47998
48320
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
47999
|
-
const dbDir =
|
|
48000
|
-
|
|
48001
|
-
const db = initDb2(
|
|
48321
|
+
const dbDir = join59(ctx.repoRoot, ".oa", "memory");
|
|
48322
|
+
mkdirSync19(dbDir, { recursive: true });
|
|
48323
|
+
const db = initDb2(join59(dbDir, "structured.db"));
|
|
48002
48324
|
const memStore = new ProceduralMemoryStore2(db);
|
|
48003
48325
|
if (isAudio) {
|
|
48004
48326
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -48039,7 +48361,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48039
48361
|
return "handled";
|
|
48040
48362
|
}
|
|
48041
48363
|
} else {
|
|
48042
|
-
content =
|
|
48364
|
+
content = readFileSync32(resolvedPath, "utf8");
|
|
48043
48365
|
}
|
|
48044
48366
|
if (!content.trim()) {
|
|
48045
48367
|
renderWarning("No content extracted.");
|
|
@@ -48078,9 +48400,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48078
48400
|
}
|
|
48079
48401
|
case "fortemi": {
|
|
48080
48402
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
48081
|
-
const fortemiDir =
|
|
48082
|
-
const altFortemiDir =
|
|
48083
|
-
const fDir =
|
|
48403
|
+
const fortemiDir = join59(ctx.repoRoot, "..", "fortemi-react");
|
|
48404
|
+
const altFortemiDir = join59(nodeOs.homedir(), "fortemi-react");
|
|
48405
|
+
const fDir = existsSync43(fortemiDir) ? fortemiDir : existsSync43(altFortemiDir) ? altFortemiDir : null;
|
|
48084
48406
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
48085
48407
|
if (!fDir) {
|
|
48086
48408
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -48095,14 +48417,14 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48095
48417
|
// 24h
|
|
48096
48418
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
48097
48419
|
};
|
|
48098
|
-
const jwtFile =
|
|
48099
|
-
|
|
48100
|
-
|
|
48420
|
+
const jwtFile = join59(ctx.repoRoot, ".oa", "fortemi-jwt.json");
|
|
48421
|
+
mkdirSync19(join59(ctx.repoRoot, ".oa"), { recursive: true });
|
|
48422
|
+
writeFileSync20(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
48101
48423
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
48102
48424
|
try {
|
|
48103
|
-
const { spawn:
|
|
48104
|
-
const child =
|
|
48105
|
-
cwd:
|
|
48425
|
+
const { spawn: spawn23 } = __require("node:child_process");
|
|
48426
|
+
const child = spawn23("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
48427
|
+
cwd: join59(fDir, "apps", "standalone"),
|
|
48106
48428
|
stdio: "ignore",
|
|
48107
48429
|
detached: true,
|
|
48108
48430
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -48111,8 +48433,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48111
48433
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
48112
48434
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
48113
48435
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
48114
|
-
const bridgeFile =
|
|
48115
|
-
|
|
48436
|
+
const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
48437
|
+
writeFileSync20(bridgeFile, JSON.stringify({
|
|
48116
48438
|
url: "http://localhost:3000",
|
|
48117
48439
|
pid: child.pid,
|
|
48118
48440
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -48124,12 +48446,12 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48124
48446
|
return "handled";
|
|
48125
48447
|
}
|
|
48126
48448
|
if (fortemiSubCmd === "status") {
|
|
48127
|
-
const bridgeFile =
|
|
48128
|
-
if (!
|
|
48449
|
+
const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
48450
|
+
if (!existsSync43(bridgeFile)) {
|
|
48129
48451
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
48130
48452
|
return "handled";
|
|
48131
48453
|
}
|
|
48132
|
-
const bridge = JSON.parse(
|
|
48454
|
+
const bridge = JSON.parse(readFileSync32(bridgeFile, "utf8"));
|
|
48133
48455
|
let alive = false;
|
|
48134
48456
|
try {
|
|
48135
48457
|
process.kill(bridge.pid, 0);
|
|
@@ -48149,15 +48471,15 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48149
48471
|
lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
|
|
48150
48472
|
lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
|
|
48151
48473
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
48152
|
-
lines.push(` JWT: ${
|
|
48474
|
+
lines.push(` JWT: ${existsSync43(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
|
|
48153
48475
|
lines.push("");
|
|
48154
48476
|
safeLog(lines.join("\n"));
|
|
48155
48477
|
return "handled";
|
|
48156
48478
|
}
|
|
48157
48479
|
if (fortemiSubCmd === "stop") {
|
|
48158
|
-
const bridgeFile =
|
|
48159
|
-
if (
|
|
48160
|
-
const bridge = JSON.parse(
|
|
48480
|
+
const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
48481
|
+
if (existsSync43(bridgeFile)) {
|
|
48482
|
+
const bridge = JSON.parse(readFileSync32(bridgeFile, "utf8"));
|
|
48161
48483
|
try {
|
|
48162
48484
|
process.kill(bridge.pid, "SIGTERM");
|
|
48163
48485
|
} catch {
|
|
@@ -48214,6 +48536,37 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48214
48536
|
ctx.saveSettings(settings);
|
|
48215
48537
|
};
|
|
48216
48538
|
if (arg) {
|
|
48539
|
+
if (arg === "personaplex" || arg === "pp") {
|
|
48540
|
+
const { detectPersonaPlexCapability: detectPersonaPlexCapability2, isPersonaPlexInstalled: isPersonaPlexInstalled2, installPersonaPlex: installPersonaPlex2, startPersonaPlexDaemon: startPersonaPlexDaemon2, stopPersonaPlex: stopPersonaPlex2, isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
48541
|
+
const caps = detectPersonaPlexCapability2();
|
|
48542
|
+
if (!caps.supported) {
|
|
48543
|
+
renderWarning(`PersonaPlex not available: ${caps.reason}`);
|
|
48544
|
+
renderInfo("Requirements: NVIDIA GPU with \u226516GB VRAM (RTX 3090/4090/A100+), CUDA 12.1+, PyTorch");
|
|
48545
|
+
return "handled";
|
|
48546
|
+
}
|
|
48547
|
+
renderInfo(`GPU: ${caps.gpuName} (${caps.vramGB.toFixed(0)}GB VRAM) \u2014 PersonaPlex compatible \u2713`);
|
|
48548
|
+
if (!isPersonaPlexInstalled2()) {
|
|
48549
|
+
renderInfo("Installing PersonaPlex-7B (~14GB download)...");
|
|
48550
|
+
const ok = await installPersonaPlex2((msg2) => renderInfo(msg2));
|
|
48551
|
+
if (!ok) {
|
|
48552
|
+
renderError("PersonaPlex installation failed.");
|
|
48553
|
+
return "handled";
|
|
48554
|
+
}
|
|
48555
|
+
}
|
|
48556
|
+
if (isPersonaPlexRunning2()) {
|
|
48557
|
+
renderInfo("PersonaPlex daemon is running.");
|
|
48558
|
+
renderInfo("Use /call to start a full-duplex voice session.");
|
|
48559
|
+
} else {
|
|
48560
|
+
const url = await startPersonaPlexDaemon2((msg2) => renderInfo(msg2));
|
|
48561
|
+
if (url) {
|
|
48562
|
+
renderInfo(`PersonaPlex ready at ${url}`);
|
|
48563
|
+
renderInfo("Use /call to start a full-duplex voice session with PersonaPlex.");
|
|
48564
|
+
} else {
|
|
48565
|
+
renderError("PersonaPlex daemon failed to start.");
|
|
48566
|
+
}
|
|
48567
|
+
}
|
|
48568
|
+
return "handled";
|
|
48569
|
+
}
|
|
48217
48570
|
if (arg === "enable" || arg === "on") {
|
|
48218
48571
|
const msg2 = await ctx.voiceToggle();
|
|
48219
48572
|
const isOn = msg2.toLowerCase().includes("enabled") || msg2.toLowerCase().includes("on");
|
|
@@ -48505,6 +48858,17 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48505
48858
|
renderWarning("Call mode not available in this context.");
|
|
48506
48859
|
return "handled";
|
|
48507
48860
|
}
|
|
48861
|
+
try {
|
|
48862
|
+
const { isPersonaPlexRunning: isPersonaPlexRunning2, getPersonaPlexWSUrl: getPersonaPlexWSUrl2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
48863
|
+
if (isPersonaPlexRunning2()) {
|
|
48864
|
+
const ppUrl = getPersonaPlexWSUrl2();
|
|
48865
|
+
if (ppUrl) {
|
|
48866
|
+
renderInfo(`PersonaPlex active \u2014 full-duplex mode (${ppUrl})`);
|
|
48867
|
+
renderInfo("257ms response latency, concurrent listen+speak");
|
|
48868
|
+
}
|
|
48869
|
+
}
|
|
48870
|
+
} catch {
|
|
48871
|
+
}
|
|
48508
48872
|
if (arg === "stop" || arg === "off") {
|
|
48509
48873
|
if (ctx.isCallActive?.()) {
|
|
48510
48874
|
await ctx.callStop?.();
|
|
@@ -48738,10 +49102,10 @@ async function handleSlashCommand(input, ctx) {
|
|
|
48738
49102
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
48739
49103
|
if (!sponsorName || sponsorName.length < 2) {
|
|
48740
49104
|
try {
|
|
48741
|
-
const { homedir:
|
|
48742
|
-
const namePath = __require("path").join(
|
|
48743
|
-
if (
|
|
48744
|
-
sponsorName =
|
|
49105
|
+
const { homedir: homedir21 } = __require("os");
|
|
49106
|
+
const namePath = __require("path").join(homedir21(), ".open-agents", "agent-name");
|
|
49107
|
+
if (existsSync43(namePath))
|
|
49108
|
+
sponsorName = readFileSync32(namePath, "utf8").trim();
|
|
48745
49109
|
} catch {
|
|
48746
49110
|
}
|
|
48747
49111
|
if (!sponsorName)
|
|
@@ -49812,13 +50176,13 @@ async function showCohereDashboard(ctx) {
|
|
|
49812
50176
|
} else if (idResult.key === "view") {
|
|
49813
50177
|
await ik.execute({ operation: "hydrate" });
|
|
49814
50178
|
} else if (idResult.key === "history") {
|
|
49815
|
-
const snapDir =
|
|
49816
|
-
if (
|
|
50179
|
+
const snapDir = join59(ctx.repoRoot, ".oa", "identity", "snapshots");
|
|
50180
|
+
if (existsSync43(snapDir)) {
|
|
49817
50181
|
const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
49818
50182
|
const snapItems = snaps.slice(0, 20).map((f) => ({
|
|
49819
50183
|
key: f,
|
|
49820
50184
|
label: f.replace(".json", ""),
|
|
49821
|
-
detail: `${formatFileSize(statSync14(
|
|
50185
|
+
detail: `${formatFileSize(statSync14(join59(snapDir, f)).size)}`
|
|
49822
50186
|
}));
|
|
49823
50187
|
if (snapItems.length > 0) {
|
|
49824
50188
|
await tuiSelect({
|
|
@@ -50139,12 +50503,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
50139
50503
|
continue;
|
|
50140
50504
|
}
|
|
50141
50505
|
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
50142
|
-
const { copyFileSync: copyFileSync2, mkdirSync:
|
|
50143
|
-
const { homedir:
|
|
50506
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync31, existsSync: exists } = await import("node:fs");
|
|
50507
|
+
const { homedir: homedir21 } = await import("node:os");
|
|
50144
50508
|
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
50145
|
-
const destDir = pathJoin(
|
|
50509
|
+
const destDir = pathJoin(homedir21(), ".open-agents", "voice", "models", modelName);
|
|
50146
50510
|
if (!exists(destDir))
|
|
50147
|
-
|
|
50511
|
+
mkdirSync31(destDir, { recursive: true });
|
|
50148
50512
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
50149
50513
|
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
50150
50514
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -50771,11 +51135,11 @@ async function handleSponsoredEndpoint(ctx, local) {
|
|
|
50771
51135
|
}
|
|
50772
51136
|
} catch {
|
|
50773
51137
|
}
|
|
50774
|
-
const sponsorDir2 =
|
|
50775
|
-
const knownFile =
|
|
51138
|
+
const sponsorDir2 = join59(ctx.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
51139
|
+
const knownFile = join59(sponsorDir2, "known-sponsors.json");
|
|
50776
51140
|
try {
|
|
50777
|
-
if (
|
|
50778
|
-
const saved = JSON.parse(
|
|
51141
|
+
if (existsSync43(knownFile)) {
|
|
51142
|
+
const saved = JSON.parse(readFileSync32(knownFile, "utf8"));
|
|
50779
51143
|
for (const s of saved) {
|
|
50780
51144
|
if (!sponsors.some((sp) => sp.url === s.url)) {
|
|
50781
51145
|
sponsors.push({ ...s, source: "saved" });
|
|
@@ -50910,11 +51274,11 @@ async function handleSponsoredEndpoint(ctx, local) {
|
|
|
50910
51274
|
}
|
|
50911
51275
|
const saveKey = selected.url || selected.peerId || selected.name;
|
|
50912
51276
|
try {
|
|
50913
|
-
|
|
50914
|
-
const existing =
|
|
51277
|
+
mkdirSync19(sponsorDir2, { recursive: true });
|
|
51278
|
+
const existing = existsSync43(knownFile) ? JSON.parse(readFileSync32(knownFile, "utf8")) : [];
|
|
50915
51279
|
const updated = existing.filter((s) => (s.url || s.peerId || s.name) !== saveKey);
|
|
50916
51280
|
updated.push(selected);
|
|
50917
|
-
|
|
51281
|
+
writeFileSync20(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
50918
51282
|
} catch {
|
|
50919
51283
|
}
|
|
50920
51284
|
renderInfo(`Connected to sponsored endpoint: ${selected.name}`);
|
|
@@ -50983,11 +51347,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
50983
51347
|
const models = await fetchModels(peerUrl, authKey);
|
|
50984
51348
|
if (models.length > 0) {
|
|
50985
51349
|
try {
|
|
50986
|
-
const { writeFileSync:
|
|
50987
|
-
const { join:
|
|
50988
|
-
const cachePath =
|
|
50989
|
-
|
|
50990
|
-
|
|
51350
|
+
const { writeFileSync: writeFileSync30, mkdirSync: mkdirSync31 } = await import("node:fs");
|
|
51351
|
+
const { join: join77, dirname: dirname23 } = await import("node:path");
|
|
51352
|
+
const cachePath = join77(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
51353
|
+
mkdirSync31(dirname23(cachePath), { recursive: true });
|
|
51354
|
+
writeFileSync30(cachePath, JSON.stringify({
|
|
50991
51355
|
peerId,
|
|
50992
51356
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50993
51357
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -51036,7 +51400,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
51036
51400
|
}
|
|
51037
51401
|
}
|
|
51038
51402
|
async function handleParallel(arg, ctx) {
|
|
51039
|
-
const { execSync:
|
|
51403
|
+
const { execSync: execSync35 } = await import("node:child_process");
|
|
51040
51404
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
51041
51405
|
const isRemote = ctx.config.backendType === "nexus";
|
|
51042
51406
|
if (isRemote) {
|
|
@@ -51060,7 +51424,7 @@ async function handleParallel(arg, ctx) {
|
|
|
51060
51424
|
}
|
|
51061
51425
|
let systemdVal = "";
|
|
51062
51426
|
try {
|
|
51063
|
-
const out =
|
|
51427
|
+
const out = execSync35("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
51064
51428
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
51065
51429
|
if (match)
|
|
51066
51430
|
systemdVal = match[1];
|
|
@@ -51089,7 +51453,7 @@ async function handleParallel(arg, ctx) {
|
|
|
51089
51453
|
}
|
|
51090
51454
|
const isSystemd = (() => {
|
|
51091
51455
|
try {
|
|
51092
|
-
const out =
|
|
51456
|
+
const out = execSync35("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
51093
51457
|
return out === "active" || out === "inactive";
|
|
51094
51458
|
} catch {
|
|
51095
51459
|
return false;
|
|
@@ -51103,10 +51467,10 @@ async function handleParallel(arg, ctx) {
|
|
|
51103
51467
|
const overrideContent = `[Service]
|
|
51104
51468
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
51105
51469
|
`;
|
|
51106
|
-
|
|
51107
|
-
|
|
51108
|
-
|
|
51109
|
-
|
|
51470
|
+
execSync35(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
51471
|
+
execSync35(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
51472
|
+
execSync35("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
51473
|
+
execSync35("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
51110
51474
|
let ready = false;
|
|
51111
51475
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
51112
51476
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -51133,13 +51497,13 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
51133
51497
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
51134
51498
|
try {
|
|
51135
51499
|
try {
|
|
51136
|
-
|
|
51500
|
+
execSync35("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
51137
51501
|
} catch {
|
|
51138
51502
|
}
|
|
51139
51503
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
51140
51504
|
process.env.OLLAMA_NUM_PARALLEL = String(n);
|
|
51141
|
-
const { spawn:
|
|
51142
|
-
const child =
|
|
51505
|
+
const { spawn: spawn23 } = await import("node:child_process");
|
|
51506
|
+
const child = spawn23("ollama", ["serve"], {
|
|
51143
51507
|
stdio: "ignore",
|
|
51144
51508
|
detached: true,
|
|
51145
51509
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
|
|
@@ -51186,17 +51550,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
51186
51550
|
try {
|
|
51187
51551
|
const { createRequire: createRequire6 } = await import("node:module");
|
|
51188
51552
|
const { fileURLToPath: fileURLToPath15 } = await import("node:url");
|
|
51189
|
-
const { dirname: dirname23, join:
|
|
51190
|
-
const { existsSync:
|
|
51553
|
+
const { dirname: dirname23, join: join77 } = await import("node:path");
|
|
51554
|
+
const { existsSync: existsSync57 } = await import("node:fs");
|
|
51191
51555
|
const req = createRequire6(import.meta.url);
|
|
51192
51556
|
const thisDir = dirname23(fileURLToPath15(import.meta.url));
|
|
51193
51557
|
const candidates = [
|
|
51194
|
-
|
|
51195
|
-
|
|
51196
|
-
|
|
51558
|
+
join77(thisDir, "..", "package.json"),
|
|
51559
|
+
join77(thisDir, "..", "..", "package.json"),
|
|
51560
|
+
join77(thisDir, "..", "..", "..", "package.json")
|
|
51197
51561
|
];
|
|
51198
51562
|
for (const pkgPath of candidates) {
|
|
51199
|
-
if (
|
|
51563
|
+
if (existsSync57(pkgPath)) {
|
|
51200
51564
|
const pkg = req(pkgPath);
|
|
51201
51565
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
51202
51566
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -51952,18 +52316,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
51952
52316
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
51953
52317
|
let copied = false;
|
|
51954
52318
|
try {
|
|
51955
|
-
const { execSync:
|
|
52319
|
+
const { execSync: execSync35 } = __require("node:child_process");
|
|
51956
52320
|
const platform6 = process.platform;
|
|
51957
52321
|
if (platform6 === "darwin") {
|
|
51958
|
-
|
|
52322
|
+
execSync35("pbcopy", { input: cmd, timeout: 3e3 });
|
|
51959
52323
|
copied = true;
|
|
51960
52324
|
} else if (platform6 === "win32") {
|
|
51961
|
-
|
|
52325
|
+
execSync35("clip", { input: cmd, timeout: 3e3 });
|
|
51962
52326
|
copied = true;
|
|
51963
52327
|
} else {
|
|
51964
52328
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
51965
52329
|
try {
|
|
51966
|
-
|
|
52330
|
+
execSync35(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
51967
52331
|
copied = true;
|
|
51968
52332
|
break;
|
|
51969
52333
|
} catch {
|
|
@@ -52050,10 +52414,10 @@ var init_commands = __esm({
|
|
|
52050
52414
|
});
|
|
52051
52415
|
|
|
52052
52416
|
// packages/cli/dist/tui/project-context.js
|
|
52053
|
-
import { existsSync as
|
|
52054
|
-
import { join as
|
|
52055
|
-
import { execSync as
|
|
52056
|
-
import { homedir as
|
|
52417
|
+
import { existsSync as existsSync44, readFileSync as readFileSync33, readdirSync as readdirSync13 } from "node:fs";
|
|
52418
|
+
import { join as join60, basename as basename12 } from "node:path";
|
|
52419
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
52420
|
+
import { homedir as homedir17, platform as platform4, release } from "node:os";
|
|
52057
52421
|
function getModelTier(modelName) {
|
|
52058
52422
|
const m = modelName.toLowerCase();
|
|
52059
52423
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -52086,10 +52450,10 @@ function loadProjectMap(repoRoot) {
|
|
|
52086
52450
|
if (!hasOaDirectory(repoRoot)) {
|
|
52087
52451
|
initOaDirectory(repoRoot);
|
|
52088
52452
|
}
|
|
52089
|
-
const mapPath2 =
|
|
52090
|
-
if (
|
|
52453
|
+
const mapPath2 = join60(repoRoot, OA_DIR, "context", "project-map.md");
|
|
52454
|
+
if (existsSync44(mapPath2)) {
|
|
52091
52455
|
try {
|
|
52092
|
-
const content =
|
|
52456
|
+
const content = readFileSync33(mapPath2, "utf-8");
|
|
52093
52457
|
return content;
|
|
52094
52458
|
} catch {
|
|
52095
52459
|
}
|
|
@@ -52098,19 +52462,19 @@ function loadProjectMap(repoRoot) {
|
|
|
52098
52462
|
}
|
|
52099
52463
|
function getGitInfo(repoRoot) {
|
|
52100
52464
|
try {
|
|
52101
|
-
|
|
52465
|
+
execSync31("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
52102
52466
|
} catch {
|
|
52103
52467
|
return "";
|
|
52104
52468
|
}
|
|
52105
52469
|
const lines = [];
|
|
52106
52470
|
try {
|
|
52107
|
-
const branch =
|
|
52471
|
+
const branch = execSync31("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
52108
52472
|
if (branch)
|
|
52109
52473
|
lines.push(`Branch: ${branch}`);
|
|
52110
52474
|
} catch {
|
|
52111
52475
|
}
|
|
52112
52476
|
try {
|
|
52113
|
-
const status =
|
|
52477
|
+
const status = execSync31("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
52114
52478
|
if (status) {
|
|
52115
52479
|
const changed = status.split("\n").length;
|
|
52116
52480
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -52120,7 +52484,7 @@ function getGitInfo(repoRoot) {
|
|
|
52120
52484
|
} catch {
|
|
52121
52485
|
}
|
|
52122
52486
|
try {
|
|
52123
|
-
const log =
|
|
52487
|
+
const log = execSync31("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
52124
52488
|
if (log)
|
|
52125
52489
|
lines.push(`Recent commits:
|
|
52126
52490
|
${log}`);
|
|
@@ -52130,31 +52494,31 @@ ${log}`);
|
|
|
52130
52494
|
}
|
|
52131
52495
|
function loadMemoryContext(repoRoot) {
|
|
52132
52496
|
const sections = [];
|
|
52133
|
-
const oaMemDir =
|
|
52497
|
+
const oaMemDir = join60(repoRoot, OA_DIR, "memory");
|
|
52134
52498
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
52135
52499
|
if (oaEntries)
|
|
52136
52500
|
sections.push(oaEntries);
|
|
52137
|
-
const legacyMemDir =
|
|
52138
|
-
if (legacyMemDir !== oaMemDir &&
|
|
52501
|
+
const legacyMemDir = join60(repoRoot, ".open-agents", "memory");
|
|
52502
|
+
if (legacyMemDir !== oaMemDir && existsSync44(legacyMemDir)) {
|
|
52139
52503
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
52140
52504
|
if (legacyEntries)
|
|
52141
52505
|
sections.push(legacyEntries);
|
|
52142
52506
|
}
|
|
52143
|
-
const globalMemDir =
|
|
52507
|
+
const globalMemDir = join60(homedir17(), ".open-agents", "memory");
|
|
52144
52508
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
52145
52509
|
if (globalEntries)
|
|
52146
52510
|
sections.push(globalEntries);
|
|
52147
52511
|
return sections.join("\n\n");
|
|
52148
52512
|
}
|
|
52149
52513
|
function loadMemoryDir(memDir, scope) {
|
|
52150
|
-
if (!
|
|
52514
|
+
if (!existsSync44(memDir))
|
|
52151
52515
|
return "";
|
|
52152
52516
|
const lines = [];
|
|
52153
52517
|
try {
|
|
52154
52518
|
const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
|
|
52155
52519
|
for (const file of files.slice(0, 10)) {
|
|
52156
52520
|
try {
|
|
52157
|
-
const raw =
|
|
52521
|
+
const raw = readFileSync33(join60(memDir, file), "utf-8");
|
|
52158
52522
|
const entries = JSON.parse(raw);
|
|
52159
52523
|
const topic = basename12(file, ".json");
|
|
52160
52524
|
const keys = Object.keys(entries);
|
|
@@ -53294,8 +53658,8 @@ __export(banner_exports, {
|
|
|
53294
53658
|
saveBannerDesign: () => saveBannerDesign,
|
|
53295
53659
|
setGridText: () => setGridText
|
|
53296
53660
|
});
|
|
53297
|
-
import { existsSync as
|
|
53298
|
-
import { join as
|
|
53661
|
+
import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20 } from "node:fs";
|
|
53662
|
+
import { join as join61 } from "node:path";
|
|
53299
53663
|
function generateMnemonic(seed) {
|
|
53300
53664
|
let h = 2166136261;
|
|
53301
53665
|
for (let i = 0; i < seed.length; i++) {
|
|
@@ -53490,23 +53854,23 @@ function createSponsorBanner(sponsorName, tagline, primaryColor = 214, bgColor =
|
|
|
53490
53854
|
};
|
|
53491
53855
|
}
|
|
53492
53856
|
function saveBannerDesign(workDir, design) {
|
|
53493
|
-
const dir =
|
|
53494
|
-
|
|
53495
|
-
|
|
53857
|
+
const dir = join61(workDir, ".oa", "banners");
|
|
53858
|
+
mkdirSync20(dir, { recursive: true });
|
|
53859
|
+
writeFileSync21(join61(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
|
|
53496
53860
|
}
|
|
53497
53861
|
function loadBannerDesign(workDir, id) {
|
|
53498
|
-
const file =
|
|
53499
|
-
if (!
|
|
53862
|
+
const file = join61(workDir, ".oa", "banners", `${id}.json`);
|
|
53863
|
+
if (!existsSync45(file))
|
|
53500
53864
|
return null;
|
|
53501
53865
|
try {
|
|
53502
|
-
return JSON.parse(
|
|
53866
|
+
return JSON.parse(readFileSync34(file, "utf8"));
|
|
53503
53867
|
} catch {
|
|
53504
53868
|
return null;
|
|
53505
53869
|
}
|
|
53506
53870
|
}
|
|
53507
53871
|
function listBannerDesigns(workDir) {
|
|
53508
|
-
const dir =
|
|
53509
|
-
if (!
|
|
53872
|
+
const dir = join61(workDir, ".oa", "banners");
|
|
53873
|
+
if (!existsSync45(dir))
|
|
53510
53874
|
return [];
|
|
53511
53875
|
try {
|
|
53512
53876
|
const { readdirSync: readdirSync23 } = __require("node:fs");
|
|
@@ -53864,22 +54228,22 @@ var init_banner = __esm({
|
|
|
53864
54228
|
});
|
|
53865
54229
|
|
|
53866
54230
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
53867
|
-
import { existsSync as
|
|
53868
|
-
import { join as
|
|
54231
|
+
import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync21, readdirSync as readdirSync14 } from "node:fs";
|
|
54232
|
+
import { join as join62, basename as basename13 } from "node:path";
|
|
53869
54233
|
function loadToolProfile(repoRoot) {
|
|
53870
|
-
const filePath =
|
|
54234
|
+
const filePath = join62(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
53871
54235
|
try {
|
|
53872
|
-
if (!
|
|
54236
|
+
if (!existsSync46(filePath))
|
|
53873
54237
|
return null;
|
|
53874
|
-
return JSON.parse(
|
|
54238
|
+
return JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
53875
54239
|
} catch {
|
|
53876
54240
|
return null;
|
|
53877
54241
|
}
|
|
53878
54242
|
}
|
|
53879
54243
|
function saveToolProfile(repoRoot, profile) {
|
|
53880
|
-
const contextDir =
|
|
53881
|
-
|
|
53882
|
-
|
|
54244
|
+
const contextDir = join62(repoRoot, OA_DIR, "context");
|
|
54245
|
+
mkdirSync21(contextDir, { recursive: true });
|
|
54246
|
+
writeFileSync22(join62(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
53883
54247
|
}
|
|
53884
54248
|
function categorizeToolCall(toolName) {
|
|
53885
54249
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -53937,25 +54301,25 @@ function weightedColor(profile) {
|
|
|
53937
54301
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
53938
54302
|
}
|
|
53939
54303
|
function loadCachedDescriptors(repoRoot) {
|
|
53940
|
-
const filePath =
|
|
54304
|
+
const filePath = join62(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
53941
54305
|
try {
|
|
53942
|
-
if (!
|
|
54306
|
+
if (!existsSync46(filePath))
|
|
53943
54307
|
return null;
|
|
53944
|
-
const cached = JSON.parse(
|
|
54308
|
+
const cached = JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
53945
54309
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
53946
54310
|
} catch {
|
|
53947
54311
|
return null;
|
|
53948
54312
|
}
|
|
53949
54313
|
}
|
|
53950
54314
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
53951
|
-
const contextDir =
|
|
53952
|
-
|
|
54315
|
+
const contextDir = join62(repoRoot, OA_DIR, "context");
|
|
54316
|
+
mkdirSync21(contextDir, { recursive: true });
|
|
53953
54317
|
const cached = {
|
|
53954
54318
|
phrases,
|
|
53955
54319
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
53956
54320
|
sourceHash
|
|
53957
54321
|
};
|
|
53958
|
-
|
|
54322
|
+
writeFileSync22(join62(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
53959
54323
|
}
|
|
53960
54324
|
function generateDescriptors(repoRoot) {
|
|
53961
54325
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -54003,11 +54367,11 @@ function generateDescriptors(repoRoot) {
|
|
|
54003
54367
|
return phrases;
|
|
54004
54368
|
}
|
|
54005
54369
|
function extractFromPackageJson(repoRoot, tags) {
|
|
54006
|
-
const pkgPath =
|
|
54370
|
+
const pkgPath = join62(repoRoot, "package.json");
|
|
54007
54371
|
try {
|
|
54008
|
-
if (!
|
|
54372
|
+
if (!existsSync46(pkgPath))
|
|
54009
54373
|
return;
|
|
54010
|
-
const pkg = JSON.parse(
|
|
54374
|
+
const pkg = JSON.parse(readFileSync35(pkgPath, "utf-8"));
|
|
54011
54375
|
if (pkg.name && typeof pkg.name === "string") {
|
|
54012
54376
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
54013
54377
|
for (const p of parts)
|
|
@@ -54051,7 +54415,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
54051
54415
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
54052
54416
|
];
|
|
54053
54417
|
for (const check of manifestChecks) {
|
|
54054
|
-
if (
|
|
54418
|
+
if (existsSync46(join62(repoRoot, check.file))) {
|
|
54055
54419
|
tags.push(check.tag);
|
|
54056
54420
|
}
|
|
54057
54421
|
}
|
|
@@ -54073,16 +54437,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
54073
54437
|
}
|
|
54074
54438
|
}
|
|
54075
54439
|
function extractFromMemory(repoRoot, tags) {
|
|
54076
|
-
const memoryDir =
|
|
54440
|
+
const memoryDir = join62(repoRoot, OA_DIR, "memory");
|
|
54077
54441
|
try {
|
|
54078
|
-
if (!
|
|
54442
|
+
if (!existsSync46(memoryDir))
|
|
54079
54443
|
return;
|
|
54080
54444
|
const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
|
|
54081
54445
|
for (const file of files) {
|
|
54082
54446
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
54083
54447
|
tags.push(topic);
|
|
54084
54448
|
try {
|
|
54085
|
-
const data = JSON.parse(
|
|
54449
|
+
const data = JSON.parse(readFileSync35(join62(memoryDir, file), "utf-8"));
|
|
54086
54450
|
if (data && typeof data === "object") {
|
|
54087
54451
|
const keys = Object.keys(data).slice(0, 3);
|
|
54088
54452
|
for (const key of keys) {
|
|
@@ -54753,13 +55117,13 @@ var init_stream_renderer = __esm({
|
|
|
54753
55117
|
});
|
|
54754
55118
|
|
|
54755
55119
|
// packages/cli/dist/tui/edit-history.js
|
|
54756
|
-
import { appendFileSync as appendFileSync3, mkdirSync as
|
|
54757
|
-
import { join as
|
|
55120
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync22 } from "node:fs";
|
|
55121
|
+
import { join as join63 } from "node:path";
|
|
54758
55122
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
54759
|
-
const historyDir =
|
|
54760
|
-
const logPath2 =
|
|
55123
|
+
const historyDir = join63(repoRoot, ".oa", "history");
|
|
55124
|
+
const logPath2 = join63(historyDir, "edits.jsonl");
|
|
54761
55125
|
try {
|
|
54762
|
-
|
|
55126
|
+
mkdirSync22(historyDir, { recursive: true });
|
|
54763
55127
|
} catch {
|
|
54764
55128
|
}
|
|
54765
55129
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -54868,17 +55232,17 @@ var init_edit_history = __esm({
|
|
|
54868
55232
|
});
|
|
54869
55233
|
|
|
54870
55234
|
// packages/cli/dist/tui/promptLoader.js
|
|
54871
|
-
import { readFileSync as
|
|
54872
|
-
import { join as
|
|
55235
|
+
import { readFileSync as readFileSync36, existsSync as existsSync47 } from "node:fs";
|
|
55236
|
+
import { join as join64, dirname as dirname19 } from "node:path";
|
|
54873
55237
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
54874
55238
|
function loadPrompt3(promptPath, vars) {
|
|
54875
55239
|
let content = cache3.get(promptPath);
|
|
54876
55240
|
if (content === void 0) {
|
|
54877
|
-
const fullPath =
|
|
54878
|
-
if (!
|
|
55241
|
+
const fullPath = join64(PROMPTS_DIR3, promptPath);
|
|
55242
|
+
if (!existsSync47(fullPath)) {
|
|
54879
55243
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
54880
55244
|
}
|
|
54881
|
-
content =
|
|
55245
|
+
content = readFileSync36(fullPath, "utf-8");
|
|
54882
55246
|
cache3.set(promptPath, content);
|
|
54883
55247
|
}
|
|
54884
55248
|
if (!vars)
|
|
@@ -54891,23 +55255,23 @@ var init_promptLoader3 = __esm({
|
|
|
54891
55255
|
"use strict";
|
|
54892
55256
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
54893
55257
|
__dirname6 = dirname19(__filename3);
|
|
54894
|
-
devPath2 =
|
|
54895
|
-
publishedPath2 =
|
|
54896
|
-
PROMPTS_DIR3 =
|
|
55258
|
+
devPath2 = join64(__dirname6, "..", "..", "prompts");
|
|
55259
|
+
publishedPath2 = join64(__dirname6, "..", "prompts");
|
|
55260
|
+
PROMPTS_DIR3 = existsSync47(devPath2) ? devPath2 : publishedPath2;
|
|
54897
55261
|
cache3 = /* @__PURE__ */ new Map();
|
|
54898
55262
|
}
|
|
54899
55263
|
});
|
|
54900
55264
|
|
|
54901
55265
|
// packages/cli/dist/tui/dream-engine.js
|
|
54902
|
-
import { mkdirSync as
|
|
54903
|
-
import { join as
|
|
54904
|
-
import { execSync as
|
|
55266
|
+
import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync23, readFileSync as readFileSync37, existsSync as existsSync48, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
|
|
55267
|
+
import { join as join65, basename as basename14 } from "node:path";
|
|
55268
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
54905
55269
|
function loadAutoresearchMemory(repoRoot) {
|
|
54906
|
-
const memoryPath =
|
|
54907
|
-
if (!
|
|
55270
|
+
const memoryPath = join65(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
55271
|
+
if (!existsSync48(memoryPath))
|
|
54908
55272
|
return "";
|
|
54909
55273
|
try {
|
|
54910
|
-
const raw =
|
|
55274
|
+
const raw = readFileSync37(memoryPath, "utf-8");
|
|
54911
55275
|
const data = JSON.parse(raw);
|
|
54912
55276
|
const sections = [];
|
|
54913
55277
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -55097,14 +55461,14 @@ var init_dream_engine = __esm({
|
|
|
55097
55461
|
const content = String(args["content"] ?? "");
|
|
55098
55462
|
if (!rawPath)
|
|
55099
55463
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
55100
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
55464
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join65(this.autoresearchDir, basename14(rawPath)) : join65(this.autoresearchDir, rawPath);
|
|
55101
55465
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
55102
55466
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
55103
55467
|
}
|
|
55104
55468
|
try {
|
|
55105
|
-
const dir =
|
|
55106
|
-
|
|
55107
|
-
|
|
55469
|
+
const dir = join65(targetPath, "..");
|
|
55470
|
+
mkdirSync23(dir, { recursive: true });
|
|
55471
|
+
writeFileSync23(targetPath, content, "utf-8");
|
|
55108
55472
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
55109
55473
|
} catch (err) {
|
|
55110
55474
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -55132,20 +55496,20 @@ var init_dream_engine = __esm({
|
|
|
55132
55496
|
const rawPath = String(args["path"] ?? "");
|
|
55133
55497
|
const oldStr = String(args["old_string"] ?? "");
|
|
55134
55498
|
const newStr = String(args["new_string"] ?? "");
|
|
55135
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
55499
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join65(this.autoresearchDir, basename14(rawPath)) : join65(this.autoresearchDir, rawPath);
|
|
55136
55500
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
55137
55501
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
55138
55502
|
}
|
|
55139
55503
|
try {
|
|
55140
|
-
if (!
|
|
55504
|
+
if (!existsSync48(targetPath)) {
|
|
55141
55505
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
55142
55506
|
}
|
|
55143
|
-
let content =
|
|
55507
|
+
let content = readFileSync37(targetPath, "utf-8");
|
|
55144
55508
|
if (!content.includes(oldStr)) {
|
|
55145
55509
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
55146
55510
|
}
|
|
55147
55511
|
content = content.replace(oldStr, newStr);
|
|
55148
|
-
|
|
55512
|
+
writeFileSync23(targetPath, content, "utf-8");
|
|
55149
55513
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
55150
55514
|
} catch (err) {
|
|
55151
55515
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -55186,14 +55550,14 @@ var init_dream_engine = __esm({
|
|
|
55186
55550
|
const content = String(args["content"] ?? "");
|
|
55187
55551
|
if (!rawPath)
|
|
55188
55552
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
55189
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
55553
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join65(this.dreamsDir, basename14(rawPath)) : join65(this.dreamsDir, rawPath);
|
|
55190
55554
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
55191
55555
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
55192
55556
|
}
|
|
55193
55557
|
try {
|
|
55194
|
-
const dir =
|
|
55195
|
-
|
|
55196
|
-
|
|
55558
|
+
const dir = join65(targetPath, "..");
|
|
55559
|
+
mkdirSync23(dir, { recursive: true });
|
|
55560
|
+
writeFileSync23(targetPath, content, "utf-8");
|
|
55197
55561
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
55198
55562
|
} catch (err) {
|
|
55199
55563
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -55221,20 +55585,20 @@ var init_dream_engine = __esm({
|
|
|
55221
55585
|
const rawPath = String(args["path"] ?? "");
|
|
55222
55586
|
const oldStr = String(args["old_string"] ?? "");
|
|
55223
55587
|
const newStr = String(args["new_string"] ?? "");
|
|
55224
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
55588
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join65(this.dreamsDir, basename14(rawPath)) : join65(this.dreamsDir, rawPath);
|
|
55225
55589
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
55226
55590
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
55227
55591
|
}
|
|
55228
55592
|
try {
|
|
55229
|
-
if (!
|
|
55593
|
+
if (!existsSync48(targetPath)) {
|
|
55230
55594
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
55231
55595
|
}
|
|
55232
|
-
let content =
|
|
55596
|
+
let content = readFileSync37(targetPath, "utf-8");
|
|
55233
55597
|
if (!content.includes(oldStr)) {
|
|
55234
55598
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
55235
55599
|
}
|
|
55236
55600
|
content = content.replace(oldStr, newStr);
|
|
55237
|
-
|
|
55601
|
+
writeFileSync23(targetPath, content, "utf-8");
|
|
55238
55602
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
55239
55603
|
} catch (err) {
|
|
55240
55604
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -55265,7 +55629,7 @@ var init_dream_engine = __esm({
|
|
|
55265
55629
|
}
|
|
55266
55630
|
}
|
|
55267
55631
|
try {
|
|
55268
|
-
const output =
|
|
55632
|
+
const output = execSync32(cmd, {
|
|
55269
55633
|
cwd: this.repoRoot,
|
|
55270
55634
|
timeout: 3e4,
|
|
55271
55635
|
encoding: "utf-8",
|
|
@@ -55288,7 +55652,7 @@ var init_dream_engine = __esm({
|
|
|
55288
55652
|
constructor(config, repoRoot) {
|
|
55289
55653
|
this.config = config;
|
|
55290
55654
|
this.repoRoot = repoRoot;
|
|
55291
|
-
this.dreamsDir =
|
|
55655
|
+
this.dreamsDir = join65(repoRoot, ".oa", "dreams");
|
|
55292
55656
|
this.state = {
|
|
55293
55657
|
mode: "default",
|
|
55294
55658
|
active: false,
|
|
@@ -55319,7 +55683,7 @@ var init_dream_engine = __esm({
|
|
|
55319
55683
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
55320
55684
|
results: []
|
|
55321
55685
|
};
|
|
55322
|
-
|
|
55686
|
+
mkdirSync23(this.dreamsDir, { recursive: true });
|
|
55323
55687
|
this.saveDreamState();
|
|
55324
55688
|
try {
|
|
55325
55689
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -55372,8 +55736,8 @@ ${result.summary}`;
|
|
|
55372
55736
|
if (mode !== "default" || cycle === totalCycles) {
|
|
55373
55737
|
renderDreamContraction(cycle);
|
|
55374
55738
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
55375
|
-
const summaryPath =
|
|
55376
|
-
|
|
55739
|
+
const summaryPath = join65(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
55740
|
+
writeFileSync23(summaryPath, cycleSummary, "utf-8");
|
|
55377
55741
|
}
|
|
55378
55742
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
55379
55743
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -55585,7 +55949,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
55585
55949
|
}
|
|
55586
55950
|
/** Build role-specific tool sets for swarm agents */
|
|
55587
55951
|
buildSwarmTools(role, _workspace) {
|
|
55588
|
-
const autoresearchDir =
|
|
55952
|
+
const autoresearchDir = join65(this.repoRoot, ".oa", "autoresearch");
|
|
55589
55953
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
55590
55954
|
switch (role) {
|
|
55591
55955
|
case "researcher": {
|
|
@@ -55949,7 +56313,7 @@ INSTRUCTIONS:
|
|
|
55949
56313
|
2. Summarize the key learnings and next steps
|
|
55950
56314
|
|
|
55951
56315
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
55952
|
-
const reportPath =
|
|
56316
|
+
const reportPath = join65(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
55953
56317
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
55954
56318
|
|
|
55955
56319
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -55971,8 +56335,8 @@ ${summaryResult}
|
|
|
55971
56335
|
*Generated by open-agents autoresearch swarm*
|
|
55972
56336
|
`;
|
|
55973
56337
|
try {
|
|
55974
|
-
|
|
55975
|
-
|
|
56338
|
+
mkdirSync23(this.dreamsDir, { recursive: true });
|
|
56339
|
+
writeFileSync23(reportPath, report, "utf-8");
|
|
55976
56340
|
} catch {
|
|
55977
56341
|
}
|
|
55978
56342
|
renderSwarmComplete(workspace);
|
|
@@ -56038,29 +56402,29 @@ ${summaryResult}
|
|
|
56038
56402
|
}
|
|
56039
56403
|
/** Save workspace backup for lucid mode */
|
|
56040
56404
|
saveVersionCheckpoint(cycle) {
|
|
56041
|
-
const checkpointDir =
|
|
56405
|
+
const checkpointDir = join65(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
56042
56406
|
try {
|
|
56043
|
-
|
|
56407
|
+
mkdirSync23(checkpointDir, { recursive: true });
|
|
56044
56408
|
try {
|
|
56045
|
-
const gitStatus =
|
|
56409
|
+
const gitStatus = execSync32("git status --porcelain", {
|
|
56046
56410
|
cwd: this.repoRoot,
|
|
56047
56411
|
encoding: "utf-8",
|
|
56048
56412
|
timeout: 1e4
|
|
56049
56413
|
});
|
|
56050
|
-
const gitDiff =
|
|
56414
|
+
const gitDiff = execSync32("git diff", {
|
|
56051
56415
|
cwd: this.repoRoot,
|
|
56052
56416
|
encoding: "utf-8",
|
|
56053
56417
|
timeout: 1e4
|
|
56054
56418
|
});
|
|
56055
|
-
const gitHash =
|
|
56419
|
+
const gitHash = execSync32("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
56056
56420
|
cwd: this.repoRoot,
|
|
56057
56421
|
encoding: "utf-8",
|
|
56058
56422
|
timeout: 5e3
|
|
56059
56423
|
}).trim();
|
|
56060
|
-
|
|
56061
|
-
|
|
56062
|
-
|
|
56063
|
-
|
|
56424
|
+
writeFileSync23(join65(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
56425
|
+
writeFileSync23(join65(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
56426
|
+
writeFileSync23(join65(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
56427
|
+
writeFileSync23(join65(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
56064
56428
|
cycle,
|
|
56065
56429
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
56066
56430
|
gitHash,
|
|
@@ -56068,7 +56432,7 @@ ${summaryResult}
|
|
|
56068
56432
|
}, null, 2), "utf-8");
|
|
56069
56433
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
56070
56434
|
} catch {
|
|
56071
|
-
|
|
56435
|
+
writeFileSync23(join65(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
56072
56436
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
56073
56437
|
}
|
|
56074
56438
|
} catch (err) {
|
|
@@ -56126,14 +56490,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
56126
56490
|
---
|
|
56127
56491
|
*Auto-generated by open-agents dream engine*
|
|
56128
56492
|
`;
|
|
56129
|
-
|
|
56493
|
+
writeFileSync23(join65(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
56130
56494
|
} catch {
|
|
56131
56495
|
}
|
|
56132
56496
|
}
|
|
56133
56497
|
/** Save dream state for resume/inspection */
|
|
56134
56498
|
saveDreamState() {
|
|
56135
56499
|
try {
|
|
56136
|
-
|
|
56500
|
+
writeFileSync23(join65(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
56137
56501
|
} catch {
|
|
56138
56502
|
}
|
|
56139
56503
|
}
|
|
@@ -56507,8 +56871,8 @@ var init_bless_engine = __esm({
|
|
|
56507
56871
|
});
|
|
56508
56872
|
|
|
56509
56873
|
// packages/cli/dist/tui/dmn-engine.js
|
|
56510
|
-
import { existsSync as
|
|
56511
|
-
import { join as
|
|
56874
|
+
import { existsSync as existsSync49, readFileSync as readFileSync38, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
|
|
56875
|
+
import { join as join66, basename as basename15 } from "node:path";
|
|
56512
56876
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
56513
56877
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
56514
56878
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -56628,9 +56992,9 @@ var init_dmn_engine = __esm({
|
|
|
56628
56992
|
constructor(config, repoRoot) {
|
|
56629
56993
|
this.config = config;
|
|
56630
56994
|
this.repoRoot = repoRoot;
|
|
56631
|
-
this.stateDir =
|
|
56632
|
-
this.historyDir =
|
|
56633
|
-
|
|
56995
|
+
this.stateDir = join66(repoRoot, ".oa", "dmn");
|
|
56996
|
+
this.historyDir = join66(repoRoot, ".oa", "dmn", "cycles");
|
|
56997
|
+
mkdirSync24(this.historyDir, { recursive: true });
|
|
56634
56998
|
this.loadState();
|
|
56635
56999
|
}
|
|
56636
57000
|
get stats() {
|
|
@@ -57219,11 +57583,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
57219
57583
|
async gatherMemoryTopics() {
|
|
57220
57584
|
const topics = [];
|
|
57221
57585
|
const dirs = [
|
|
57222
|
-
|
|
57223
|
-
|
|
57586
|
+
join66(this.repoRoot, ".oa", "memory"),
|
|
57587
|
+
join66(this.repoRoot, ".open-agents", "memory")
|
|
57224
57588
|
];
|
|
57225
57589
|
for (const dir of dirs) {
|
|
57226
|
-
if (!
|
|
57590
|
+
if (!existsSync49(dir))
|
|
57227
57591
|
continue;
|
|
57228
57592
|
try {
|
|
57229
57593
|
const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -57239,29 +57603,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
57239
57603
|
}
|
|
57240
57604
|
// ── State persistence ─────────────────────────────────────────────────
|
|
57241
57605
|
loadState() {
|
|
57242
|
-
const path =
|
|
57243
|
-
if (
|
|
57606
|
+
const path = join66(this.stateDir, "state.json");
|
|
57607
|
+
if (existsSync49(path)) {
|
|
57244
57608
|
try {
|
|
57245
|
-
this.state = JSON.parse(
|
|
57609
|
+
this.state = JSON.parse(readFileSync38(path, "utf-8"));
|
|
57246
57610
|
} catch {
|
|
57247
57611
|
}
|
|
57248
57612
|
}
|
|
57249
57613
|
}
|
|
57250
57614
|
saveState() {
|
|
57251
57615
|
try {
|
|
57252
|
-
|
|
57616
|
+
writeFileSync24(join66(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
57253
57617
|
} catch {
|
|
57254
57618
|
}
|
|
57255
57619
|
}
|
|
57256
57620
|
saveCycleResult(result) {
|
|
57257
57621
|
try {
|
|
57258
57622
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
57259
|
-
|
|
57623
|
+
writeFileSync24(join66(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
57260
57624
|
const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
57261
57625
|
if (files.length > 50) {
|
|
57262
57626
|
for (const old of files.slice(0, files.length - 50)) {
|
|
57263
57627
|
try {
|
|
57264
|
-
unlinkSync10(
|
|
57628
|
+
unlinkSync10(join66(this.historyDir, old));
|
|
57265
57629
|
} catch {
|
|
57266
57630
|
}
|
|
57267
57631
|
}
|
|
@@ -57274,8 +57638,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
57274
57638
|
});
|
|
57275
57639
|
|
|
57276
57640
|
// packages/cli/dist/tui/snr-engine.js
|
|
57277
|
-
import { existsSync as
|
|
57278
|
-
import { join as
|
|
57641
|
+
import { existsSync as existsSync50, readdirSync as readdirSync17, readFileSync as readFileSync39 } from "node:fs";
|
|
57642
|
+
import { join as join67, basename as basename16 } from "node:path";
|
|
57279
57643
|
function computeDPrime(signalScores, noiseScores) {
|
|
57280
57644
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
57281
57645
|
return 0;
|
|
@@ -57515,11 +57879,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
57515
57879
|
loadMemoryEntries(topics) {
|
|
57516
57880
|
const entries = [];
|
|
57517
57881
|
const dirs = [
|
|
57518
|
-
|
|
57519
|
-
|
|
57882
|
+
join67(this.repoRoot, ".oa", "memory"),
|
|
57883
|
+
join67(this.repoRoot, ".open-agents", "memory")
|
|
57520
57884
|
];
|
|
57521
57885
|
for (const dir of dirs) {
|
|
57522
|
-
if (!
|
|
57886
|
+
if (!existsSync50(dir))
|
|
57523
57887
|
continue;
|
|
57524
57888
|
try {
|
|
57525
57889
|
const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -57528,7 +57892,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
57528
57892
|
if (topics.length > 0 && !topics.includes(topic))
|
|
57529
57893
|
continue;
|
|
57530
57894
|
try {
|
|
57531
|
-
const data = JSON.parse(
|
|
57895
|
+
const data = JSON.parse(readFileSync39(join67(dir, f), "utf-8"));
|
|
57532
57896
|
for (const [key, val] of Object.entries(data)) {
|
|
57533
57897
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
57534
57898
|
entries.push({ topic, key, value });
|
|
@@ -58095,8 +58459,8 @@ var init_tool_policy = __esm({
|
|
|
58095
58459
|
});
|
|
58096
58460
|
|
|
58097
58461
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
58098
|
-
import { mkdirSync as
|
|
58099
|
-
import { join as
|
|
58462
|
+
import { mkdirSync as mkdirSync25, existsSync as existsSync51, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
|
|
58463
|
+
import { join as join68, resolve as resolve30 } from "node:path";
|
|
58100
58464
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
58101
58465
|
function convertMarkdownToTelegramHTML(md) {
|
|
58102
58466
|
let html = md;
|
|
@@ -58424,7 +58788,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
58424
58788
|
this.polling = true;
|
|
58425
58789
|
this.abortController = new AbortController();
|
|
58426
58790
|
try {
|
|
58427
|
-
|
|
58791
|
+
mkdirSync25(this.mediaCacheDir, { recursive: true });
|
|
58428
58792
|
} catch {
|
|
58429
58793
|
}
|
|
58430
58794
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -58861,7 +59225,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
58861
59225
|
return null;
|
|
58862
59226
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
58863
59227
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
58864
|
-
const localPath =
|
|
59228
|
+
const localPath = join68(this.mediaCacheDir, fileName);
|
|
58865
59229
|
await writeFileAsync(localPath, buffer);
|
|
58866
59230
|
return localPath;
|
|
58867
59231
|
} catch {
|
|
@@ -59877,7 +60241,7 @@ __export(text_selection_exports, {
|
|
|
59877
60241
|
stripAnsi: () => stripAnsi3,
|
|
59878
60242
|
visibleLength: () => visibleLength
|
|
59879
60243
|
});
|
|
59880
|
-
import { execSync as
|
|
60244
|
+
import { execSync as execSync33 } from "node:child_process";
|
|
59881
60245
|
function stripAnsi3(s) {
|
|
59882
60246
|
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
59883
60247
|
}
|
|
@@ -59888,16 +60252,16 @@ function copyText(text) {
|
|
|
59888
60252
|
try {
|
|
59889
60253
|
const platform6 = process.platform;
|
|
59890
60254
|
if (platform6 === "darwin") {
|
|
59891
|
-
|
|
60255
|
+
execSync33("pbcopy", { input: text, timeout: 3e3 });
|
|
59892
60256
|
return true;
|
|
59893
60257
|
}
|
|
59894
60258
|
if (platform6 === "win32") {
|
|
59895
|
-
|
|
60259
|
+
execSync33("clip", { input: text, timeout: 3e3 });
|
|
59896
60260
|
return true;
|
|
59897
60261
|
}
|
|
59898
60262
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
59899
60263
|
try {
|
|
59900
|
-
|
|
60264
|
+
execSync33(tool, { input: text, timeout: 3e3 });
|
|
59901
60265
|
return true;
|
|
59902
60266
|
} catch {
|
|
59903
60267
|
continue;
|
|
@@ -59906,10 +60270,10 @@ function copyText(text) {
|
|
|
59906
60270
|
if (!_clipboardAutoInstallAttempted) {
|
|
59907
60271
|
_clipboardAutoInstallAttempted = true;
|
|
59908
60272
|
try {
|
|
59909
|
-
|
|
60273
|
+
execSync33("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
59910
60274
|
try {
|
|
59911
|
-
|
|
59912
|
-
|
|
60275
|
+
execSync33("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
60276
|
+
execSync33("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
59913
60277
|
return true;
|
|
59914
60278
|
} catch {
|
|
59915
60279
|
}
|
|
@@ -60217,7 +60581,7 @@ var init_text_selection = __esm({
|
|
|
60217
60581
|
});
|
|
60218
60582
|
|
|
60219
60583
|
// packages/cli/dist/tui/status-bar.js
|
|
60220
|
-
import { readFileSync as
|
|
60584
|
+
import { readFileSync as readFileSync40 } from "node:fs";
|
|
60221
60585
|
function setTerminalTitle(task, version) {
|
|
60222
60586
|
if (!process.stdout.isTTY)
|
|
60223
60587
|
return;
|
|
@@ -60914,7 +61278,7 @@ var init_status_bar = __esm({
|
|
|
60914
61278
|
if (nexusDir) {
|
|
60915
61279
|
try {
|
|
60916
61280
|
const metricsPath = nexusDir + "/remote-metrics.json";
|
|
60917
|
-
const raw =
|
|
61281
|
+
const raw = readFileSync40(metricsPath, "utf8");
|
|
60918
61282
|
const cached = JSON.parse(raw);
|
|
60919
61283
|
if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
|
|
60920
61284
|
const m = cached.data;
|
|
@@ -63207,24 +63571,24 @@ var init_direct_input = __esm({
|
|
|
63207
63571
|
});
|
|
63208
63572
|
|
|
63209
63573
|
// packages/cli/dist/api/profiles.js
|
|
63210
|
-
import { existsSync as
|
|
63211
|
-
import { join as
|
|
63212
|
-
import { homedir as
|
|
63574
|
+
import { existsSync as existsSync52, readFileSync as readFileSync41, writeFileSync as writeFileSync25, mkdirSync as mkdirSync26, readdirSync as readdirSync19, unlinkSync as unlinkSync12 } from "node:fs";
|
|
63575
|
+
import { join as join69 } from "node:path";
|
|
63576
|
+
import { homedir as homedir18 } from "node:os";
|
|
63213
63577
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes15, scryptSync as scryptSync3, createHash as createHash5 } from "node:crypto";
|
|
63214
63578
|
function globalProfileDir() {
|
|
63215
|
-
return
|
|
63579
|
+
return join69(homedir18(), ".open-agents", "profiles");
|
|
63216
63580
|
}
|
|
63217
63581
|
function projectProfileDir(projectDir) {
|
|
63218
|
-
return
|
|
63582
|
+
return join69(projectDir || process.cwd(), ".oa", "profiles");
|
|
63219
63583
|
}
|
|
63220
63584
|
function listProfiles(projectDir) {
|
|
63221
63585
|
const result = [];
|
|
63222
63586
|
const seen = /* @__PURE__ */ new Set();
|
|
63223
63587
|
const projDir = projectProfileDir(projectDir);
|
|
63224
|
-
if (
|
|
63588
|
+
if (existsSync52(projDir)) {
|
|
63225
63589
|
for (const f of readdirSync19(projDir).filter((f2) => f2.endsWith(".json"))) {
|
|
63226
63590
|
try {
|
|
63227
|
-
const raw = JSON.parse(
|
|
63591
|
+
const raw = JSON.parse(readFileSync41(join69(projDir, f), "utf8"));
|
|
63228
63592
|
const name = f.replace(".json", "");
|
|
63229
63593
|
seen.add(name);
|
|
63230
63594
|
result.push({
|
|
@@ -63238,13 +63602,13 @@ function listProfiles(projectDir) {
|
|
|
63238
63602
|
}
|
|
63239
63603
|
}
|
|
63240
63604
|
const globDir = globalProfileDir();
|
|
63241
|
-
if (
|
|
63605
|
+
if (existsSync52(globDir)) {
|
|
63242
63606
|
for (const f of readdirSync19(globDir).filter((f2) => f2.endsWith(".json"))) {
|
|
63243
63607
|
const name = f.replace(".json", "");
|
|
63244
63608
|
if (seen.has(name))
|
|
63245
63609
|
continue;
|
|
63246
63610
|
try {
|
|
63247
|
-
const raw = JSON.parse(
|
|
63611
|
+
const raw = JSON.parse(readFileSync41(join69(globDir, f), "utf8"));
|
|
63248
63612
|
result.push({
|
|
63249
63613
|
name,
|
|
63250
63614
|
description: raw.description || "",
|
|
@@ -63259,12 +63623,12 @@ function listProfiles(projectDir) {
|
|
|
63259
63623
|
}
|
|
63260
63624
|
function loadProfile(name, password, projectDir) {
|
|
63261
63625
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
63262
|
-
const projPath =
|
|
63263
|
-
const globPath =
|
|
63264
|
-
const filePath =
|
|
63626
|
+
const projPath = join69(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
63627
|
+
const globPath = join69(globalProfileDir(), `${sanitized}.json`);
|
|
63628
|
+
const filePath = existsSync52(projPath) ? projPath : existsSync52(globPath) ? globPath : null;
|
|
63265
63629
|
if (!filePath)
|
|
63266
63630
|
return null;
|
|
63267
|
-
const raw = JSON.parse(
|
|
63631
|
+
const raw = JSON.parse(readFileSync41(filePath, "utf8"));
|
|
63268
63632
|
if (raw.encrypted === true) {
|
|
63269
63633
|
if (!password)
|
|
63270
63634
|
return null;
|
|
@@ -63274,23 +63638,23 @@ function loadProfile(name, password, projectDir) {
|
|
|
63274
63638
|
}
|
|
63275
63639
|
function saveProfile(profile, password, scope = "global", projectDir) {
|
|
63276
63640
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
63277
|
-
|
|
63641
|
+
mkdirSync26(dir, { recursive: true });
|
|
63278
63642
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
63279
|
-
const filePath =
|
|
63643
|
+
const filePath = join69(dir, `${sanitized}.json`);
|
|
63280
63644
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
63281
63645
|
if (password) {
|
|
63282
63646
|
const encrypted = encryptProfile(profile, password);
|
|
63283
|
-
|
|
63647
|
+
writeFileSync25(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
63284
63648
|
} else {
|
|
63285
63649
|
profile.encrypted = false;
|
|
63286
|
-
|
|
63650
|
+
writeFileSync25(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
|
|
63287
63651
|
}
|
|
63288
63652
|
}
|
|
63289
63653
|
function deleteProfile(name, scope = "global", projectDir) {
|
|
63290
63654
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
63291
63655
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
63292
|
-
const filePath =
|
|
63293
|
-
if (
|
|
63656
|
+
const filePath = join69(dir, `${sanitized}.json`);
|
|
63657
|
+
if (existsSync52(filePath)) {
|
|
63294
63658
|
unlinkSync12(filePath);
|
|
63295
63659
|
return true;
|
|
63296
63660
|
}
|
|
@@ -63383,22 +63747,22 @@ import * as http from "node:http";
|
|
|
63383
63747
|
import * as https from "node:https";
|
|
63384
63748
|
import { createRequire as createRequire3 } from "node:module";
|
|
63385
63749
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
63386
|
-
import { dirname as dirname20, join as
|
|
63387
|
-
import { spawn as
|
|
63388
|
-
import { mkdirSync as
|
|
63750
|
+
import { dirname as dirname20, join as join70, resolve as resolve31 } from "node:path";
|
|
63751
|
+
import { spawn as spawn21 } from "node:child_process";
|
|
63752
|
+
import { mkdirSync as mkdirSync27, writeFileSync as writeFileSync26, readFileSync as readFileSync42, readdirSync as readdirSync20, existsSync as existsSync53 } from "node:fs";
|
|
63389
63753
|
import { randomBytes as randomBytes16 } from "node:crypto";
|
|
63390
63754
|
function getVersion3() {
|
|
63391
63755
|
try {
|
|
63392
63756
|
const require2 = createRequire3(import.meta.url);
|
|
63393
63757
|
const thisDir = dirname20(fileURLToPath12(import.meta.url));
|
|
63394
63758
|
const candidates = [
|
|
63395
|
-
|
|
63396
|
-
|
|
63397
|
-
|
|
63759
|
+
join70(thisDir, "..", "package.json"),
|
|
63760
|
+
join70(thisDir, "..", "..", "package.json"),
|
|
63761
|
+
join70(thisDir, "..", "..", "..", "package.json")
|
|
63398
63762
|
];
|
|
63399
63763
|
for (const pkgPath of candidates) {
|
|
63400
63764
|
try {
|
|
63401
|
-
if (!
|
|
63765
|
+
if (!existsSync53(pkgPath))
|
|
63402
63766
|
continue;
|
|
63403
63767
|
const pkg = require2(pkgPath);
|
|
63404
63768
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
@@ -63693,29 +64057,29 @@ function ollamaStream(ollamaUrl, path, method, body, onData, onEnd, onError) {
|
|
|
63693
64057
|
}
|
|
63694
64058
|
function jobsDir() {
|
|
63695
64059
|
const root = resolve31(process.cwd());
|
|
63696
|
-
const dir =
|
|
63697
|
-
|
|
64060
|
+
const dir = join70(root, ".oa", "jobs");
|
|
64061
|
+
mkdirSync27(dir, { recursive: true });
|
|
63698
64062
|
return dir;
|
|
63699
64063
|
}
|
|
63700
64064
|
function loadJob(id) {
|
|
63701
|
-
const file =
|
|
63702
|
-
if (!
|
|
64065
|
+
const file = join70(jobsDir(), `${id}.json`);
|
|
64066
|
+
if (!existsSync53(file))
|
|
63703
64067
|
return null;
|
|
63704
64068
|
try {
|
|
63705
|
-
return JSON.parse(
|
|
64069
|
+
return JSON.parse(readFileSync42(file, "utf-8"));
|
|
63706
64070
|
} catch {
|
|
63707
64071
|
return null;
|
|
63708
64072
|
}
|
|
63709
64073
|
}
|
|
63710
64074
|
function listJobs() {
|
|
63711
64075
|
const dir = jobsDir();
|
|
63712
|
-
if (!
|
|
64076
|
+
if (!existsSync53(dir))
|
|
63713
64077
|
return [];
|
|
63714
64078
|
const files = readdirSync20(dir).filter((f) => f.endsWith(".json")).sort();
|
|
63715
64079
|
const jobs = [];
|
|
63716
64080
|
for (const file of files) {
|
|
63717
64081
|
try {
|
|
63718
|
-
jobs.push(JSON.parse(
|
|
64082
|
+
jobs.push(JSON.parse(readFileSync42(join70(dir, file), "utf-8")));
|
|
63719
64083
|
} catch {
|
|
63720
64084
|
}
|
|
63721
64085
|
}
|
|
@@ -64108,8 +64472,8 @@ async function handleV1Run(req, res) {
|
|
|
64108
64472
|
if (workingDir) {
|
|
64109
64473
|
cwd4 = resolve31(workingDir);
|
|
64110
64474
|
} else if (isolate) {
|
|
64111
|
-
const wsDir =
|
|
64112
|
-
|
|
64475
|
+
const wsDir = join70(dir, "..", "workspaces", id);
|
|
64476
|
+
mkdirSync27(wsDir, { recursive: true });
|
|
64113
64477
|
cwd4 = wsDir;
|
|
64114
64478
|
} else {
|
|
64115
64479
|
cwd4 = resolve31(process.cwd());
|
|
@@ -64173,7 +64537,7 @@ async function handleV1Run(req, res) {
|
|
|
64173
64537
|
}
|
|
64174
64538
|
}
|
|
64175
64539
|
}
|
|
64176
|
-
const child =
|
|
64540
|
+
const child = spawn21("node", [oaBin, ...args], {
|
|
64177
64541
|
cwd: cwd4,
|
|
64178
64542
|
env: runEnv,
|
|
64179
64543
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -64181,7 +64545,7 @@ async function handleV1Run(req, res) {
|
|
|
64181
64545
|
});
|
|
64182
64546
|
child.unref();
|
|
64183
64547
|
job.pid = child.pid ?? 0;
|
|
64184
|
-
|
|
64548
|
+
writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64185
64549
|
runningProcesses.set(id, child);
|
|
64186
64550
|
if (streamMode) {
|
|
64187
64551
|
res.writeHead(200, {
|
|
@@ -64211,7 +64575,7 @@ async function handleV1Run(req, res) {
|
|
|
64211
64575
|
job.status = code === 0 ? "completed" : "failed";
|
|
64212
64576
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
64213
64577
|
try {
|
|
64214
|
-
|
|
64578
|
+
writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64215
64579
|
} catch {
|
|
64216
64580
|
}
|
|
64217
64581
|
runningProcesses.delete(id);
|
|
@@ -64242,7 +64606,7 @@ async function handleV1Run(req, res) {
|
|
|
64242
64606
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
64243
64607
|
}
|
|
64244
64608
|
try {
|
|
64245
|
-
|
|
64609
|
+
writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64246
64610
|
} catch {
|
|
64247
64611
|
}
|
|
64248
64612
|
runningProcesses.delete(id);
|
|
@@ -64283,7 +64647,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
64283
64647
|
job.error = "Aborted via API";
|
|
64284
64648
|
const dir = jobsDir();
|
|
64285
64649
|
try {
|
|
64286
|
-
|
|
64650
|
+
writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64287
64651
|
} catch {
|
|
64288
64652
|
}
|
|
64289
64653
|
runningProcesses.delete(id);
|
|
@@ -64395,7 +64759,7 @@ async function handlePostCommand(res, cmd) {
|
|
|
64395
64759
|
return;
|
|
64396
64760
|
}
|
|
64397
64761
|
try {
|
|
64398
|
-
const child =
|
|
64762
|
+
const child = spawn21("node", [oaBin, "run", `/${cmd}`, "--json"], {
|
|
64399
64763
|
env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
|
|
64400
64764
|
stdio: ["ignore", "pipe", "pipe"],
|
|
64401
64765
|
timeout: 3e4
|
|
@@ -64808,13 +65172,13 @@ var init_serve = __esm({
|
|
|
64808
65172
|
|
|
64809
65173
|
// packages/cli/dist/tui/interactive.js
|
|
64810
65174
|
import { cwd } from "node:process";
|
|
64811
|
-
import { resolve as resolve32, join as
|
|
65175
|
+
import { resolve as resolve32, join as join71, dirname as dirname21, extname as extname11 } from "node:path";
|
|
64812
65176
|
import { createRequire as createRequire4 } from "node:module";
|
|
64813
65177
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
64814
|
-
import { readFileSync as
|
|
64815
|
-
import { existsSync as
|
|
64816
|
-
import { execSync as
|
|
64817
|
-
import { homedir as
|
|
65178
|
+
import { readFileSync as readFileSync43, writeFileSync as writeFileSync27, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync21, mkdirSync as mkdirSync28 } from "node:fs";
|
|
65179
|
+
import { existsSync as existsSync54 } from "node:fs";
|
|
65180
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
65181
|
+
import { homedir as homedir19 } from "node:os";
|
|
64818
65182
|
function formatTimeAgo(date) {
|
|
64819
65183
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
64820
65184
|
if (seconds < 60)
|
|
@@ -64833,12 +65197,12 @@ function getVersion4() {
|
|
|
64833
65197
|
const require2 = createRequire4(import.meta.url);
|
|
64834
65198
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
64835
65199
|
const candidates = [
|
|
64836
|
-
|
|
64837
|
-
|
|
64838
|
-
|
|
65200
|
+
join71(thisDir, "..", "package.json"),
|
|
65201
|
+
join71(thisDir, "..", "..", "package.json"),
|
|
65202
|
+
join71(thisDir, "..", "..", "..", "package.json")
|
|
64839
65203
|
];
|
|
64840
65204
|
for (const pkgPath of candidates) {
|
|
64841
|
-
if (
|
|
65205
|
+
if (existsSync54(pkgPath)) {
|
|
64842
65206
|
const pkg = require2(pkgPath);
|
|
64843
65207
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
64844
65208
|
return pkg.version ?? "0.0.0";
|
|
@@ -65074,15 +65438,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
65074
65438
|
function gatherMemorySnippets(root) {
|
|
65075
65439
|
const snippets = [];
|
|
65076
65440
|
const dirs = [
|
|
65077
|
-
|
|
65078
|
-
|
|
65441
|
+
join71(root, ".oa", "memory"),
|
|
65442
|
+
join71(root, ".open-agents", "memory")
|
|
65079
65443
|
];
|
|
65080
65444
|
for (const dir of dirs) {
|
|
65081
|
-
if (!
|
|
65445
|
+
if (!existsSync54(dir))
|
|
65082
65446
|
continue;
|
|
65083
65447
|
try {
|
|
65084
65448
|
for (const f of readdirSync21(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
65085
|
-
const data = JSON.parse(
|
|
65449
|
+
const data = JSON.parse(readFileSync43(join71(dir, f), "utf-8"));
|
|
65086
65450
|
for (const val of Object.values(data)) {
|
|
65087
65451
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
65088
65452
|
if (v.length > 10)
|
|
@@ -65239,9 +65603,9 @@ ${metabolismMemories}
|
|
|
65239
65603
|
} catch {
|
|
65240
65604
|
}
|
|
65241
65605
|
try {
|
|
65242
|
-
const archeFile =
|
|
65243
|
-
if (
|
|
65244
|
-
const variants = JSON.parse(
|
|
65606
|
+
const archeFile = join71(repoRoot, ".oa", "arche", "variants.json");
|
|
65607
|
+
if (existsSync54(archeFile)) {
|
|
65608
|
+
const variants = JSON.parse(readFileSync43(archeFile, "utf8"));
|
|
65245
65609
|
if (variants.length > 0) {
|
|
65246
65610
|
let filtered = variants;
|
|
65247
65611
|
if (taskType) {
|
|
@@ -65410,9 +65774,9 @@ RULES:
|
|
|
65410
65774
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
65411
65775
|
let identityInjection = "";
|
|
65412
65776
|
try {
|
|
65413
|
-
const ikStateFile =
|
|
65414
|
-
if (
|
|
65415
|
-
const selfState = JSON.parse(
|
|
65777
|
+
const ikStateFile = join71(repoRoot, ".oa", "identity", "self-state.json");
|
|
65778
|
+
if (existsSync54(ikStateFile)) {
|
|
65779
|
+
const selfState = JSON.parse(readFileSync43(ikStateFile, "utf8"));
|
|
65416
65780
|
const lines = [
|
|
65417
65781
|
`[Identity State v${selfState.version}]`,
|
|
65418
65782
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -66055,13 +66419,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
66055
66419
|
});
|
|
66056
66420
|
}
|
|
66057
66421
|
try {
|
|
66058
|
-
const ikDir =
|
|
66059
|
-
const ikFile =
|
|
66422
|
+
const ikDir = join71(repoRoot, ".oa", "identity");
|
|
66423
|
+
const ikFile = join71(ikDir, "self-state.json");
|
|
66060
66424
|
let ikState;
|
|
66061
|
-
if (
|
|
66062
|
-
ikState = JSON.parse(
|
|
66425
|
+
if (existsSync54(ikFile)) {
|
|
66426
|
+
ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
|
|
66063
66427
|
} else {
|
|
66064
|
-
|
|
66428
|
+
mkdirSync28(ikDir, { recursive: true });
|
|
66065
66429
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
66066
66430
|
ikState = {
|
|
66067
66431
|
self_id: `oa-${machineId}`,
|
|
@@ -66087,7 +66451,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
66087
66451
|
}
|
|
66088
66452
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
66089
66453
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
66090
|
-
|
|
66454
|
+
writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
|
|
66091
66455
|
} catch (ikErr) {
|
|
66092
66456
|
try {
|
|
66093
66457
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -66102,14 +66466,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
66102
66466
|
} else {
|
|
66103
66467
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
66104
66468
|
try {
|
|
66105
|
-
const ikFile =
|
|
66106
|
-
if (
|
|
66107
|
-
const ikState = JSON.parse(
|
|
66469
|
+
const ikFile = join71(repoRoot, ".oa", "identity", "self-state.json");
|
|
66470
|
+
if (existsSync54(ikFile)) {
|
|
66471
|
+
const ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
|
|
66108
66472
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
66109
66473
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
66110
66474
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
66111
66475
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
66112
|
-
|
|
66476
|
+
writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
|
|
66113
66477
|
}
|
|
66114
66478
|
} catch {
|
|
66115
66479
|
}
|
|
@@ -66206,10 +66570,10 @@ async function startInteractive(config, repoPath) {
|
|
|
66206
66570
|
process.stdin.pause();
|
|
66207
66571
|
}
|
|
66208
66572
|
try {
|
|
66209
|
-
const oaDir =
|
|
66210
|
-
const nexusPidFile =
|
|
66211
|
-
if (
|
|
66212
|
-
const pid = parseInt(
|
|
66573
|
+
const oaDir = join71(repoRoot, ".oa");
|
|
66574
|
+
const nexusPidFile = join71(oaDir, "nexus", "daemon.pid");
|
|
66575
|
+
if (existsSync54(nexusPidFile)) {
|
|
66576
|
+
const pid = parseInt(readFileSync43(nexusPidFile, "utf8").trim(), 10);
|
|
66213
66577
|
if (pid > 0) {
|
|
66214
66578
|
try {
|
|
66215
66579
|
process.kill(pid, 0);
|
|
@@ -66518,7 +66882,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
66518
66882
|
let p2pGateway = null;
|
|
66519
66883
|
let peerMesh = null;
|
|
66520
66884
|
let inferenceRouter = null;
|
|
66521
|
-
const secretVault = new SecretVault(
|
|
66885
|
+
const secretVault = new SecretVault(join71(repoRoot, ".oa", "vault.enc"));
|
|
66522
66886
|
let adminSessionKey = null;
|
|
66523
66887
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
66524
66888
|
const streamRenderer = new StreamRenderer();
|
|
@@ -66741,13 +67105,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
66741
67105
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
66742
67106
|
return [hits, line];
|
|
66743
67107
|
}
|
|
66744
|
-
const HISTORY_DIR =
|
|
66745
|
-
const HISTORY_FILE =
|
|
67108
|
+
const HISTORY_DIR = join71(homedir19(), ".open-agents");
|
|
67109
|
+
const HISTORY_FILE = join71(HISTORY_DIR, "repl-history");
|
|
66746
67110
|
const MAX_HISTORY_LINES = 500;
|
|
66747
67111
|
let savedHistory = [];
|
|
66748
67112
|
try {
|
|
66749
|
-
if (
|
|
66750
|
-
const raw =
|
|
67113
|
+
if (existsSync54(HISTORY_FILE)) {
|
|
67114
|
+
const raw = readFileSync43(HISTORY_FILE, "utf8").trim();
|
|
66751
67115
|
if (raw)
|
|
66752
67116
|
savedHistory = raw.split("\n").reverse();
|
|
66753
67117
|
}
|
|
@@ -66850,12 +67214,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
66850
67214
|
if (!line.trim())
|
|
66851
67215
|
return;
|
|
66852
67216
|
try {
|
|
66853
|
-
|
|
67217
|
+
mkdirSync28(HISTORY_DIR, { recursive: true });
|
|
66854
67218
|
appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
|
|
66855
67219
|
if (Math.random() < 0.02) {
|
|
66856
|
-
const all =
|
|
67220
|
+
const all = readFileSync43(HISTORY_FILE, "utf8").trim().split("\n");
|
|
66857
67221
|
if (all.length > MAX_HISTORY_LINES) {
|
|
66858
|
-
|
|
67222
|
+
writeFileSync27(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
66859
67223
|
}
|
|
66860
67224
|
}
|
|
66861
67225
|
} catch {
|
|
@@ -67039,7 +67403,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
67039
67403
|
} catch {
|
|
67040
67404
|
}
|
|
67041
67405
|
try {
|
|
67042
|
-
const oaDir =
|
|
67406
|
+
const oaDir = join71(repoRoot, ".oa");
|
|
67043
67407
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
67044
67408
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
67045
67409
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -67071,7 +67435,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
67071
67435
|
} catch {
|
|
67072
67436
|
}
|
|
67073
67437
|
try {
|
|
67074
|
-
const oaDir =
|
|
67438
|
+
const oaDir = join71(repoRoot, ".oa");
|
|
67075
67439
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
67076
67440
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
67077
67441
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -67112,11 +67476,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
67112
67476
|
}
|
|
67113
67477
|
try {
|
|
67114
67478
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
67115
|
-
const globalNamePath =
|
|
67479
|
+
const globalNamePath = join71(_hd(), ".open-agents", "agent-name");
|
|
67116
67480
|
let agName = "";
|
|
67117
67481
|
try {
|
|
67118
|
-
if (
|
|
67119
|
-
agName =
|
|
67482
|
+
if (existsSync54(globalNamePath))
|
|
67483
|
+
agName = readFileSync43(globalNamePath, "utf8").trim();
|
|
67120
67484
|
} catch {
|
|
67121
67485
|
}
|
|
67122
67486
|
if (!agName) {
|
|
@@ -68081,7 +68445,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68081
68445
|
kind,
|
|
68082
68446
|
targetUrl,
|
|
68083
68447
|
authKey,
|
|
68084
|
-
stateDir:
|
|
68448
|
+
stateDir: join71(repoRoot, ".oa"),
|
|
68085
68449
|
passthrough: passthrough ?? false,
|
|
68086
68450
|
loadbalance: loadbalance ?? false,
|
|
68087
68451
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -68129,7 +68493,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68129
68493
|
await tunnelGateway.stop();
|
|
68130
68494
|
tunnelGateway = null;
|
|
68131
68495
|
}
|
|
68132
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
68496
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join71(repoRoot, ".oa") });
|
|
68133
68497
|
newTunnel.on("stats", (stats) => {
|
|
68134
68498
|
statusBar.setExposeStatus({
|
|
68135
68499
|
status: stats.status,
|
|
@@ -68401,15 +68765,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68401
68765
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
68402
68766
|
}
|
|
68403
68767
|
try {
|
|
68404
|
-
const nexusDir =
|
|
68405
|
-
const pidFile =
|
|
68406
|
-
if (
|
|
68407
|
-
const pid = parseInt(
|
|
68768
|
+
const nexusDir = join71(repoRoot, OA_DIR, "nexus");
|
|
68769
|
+
const pidFile = join71(nexusDir, "daemon.pid");
|
|
68770
|
+
if (existsSync54(pidFile)) {
|
|
68771
|
+
const pid = parseInt(readFileSync43(pidFile, "utf8").trim(), 10);
|
|
68408
68772
|
if (pid > 0) {
|
|
68409
68773
|
try {
|
|
68410
68774
|
if (process.platform === "win32") {
|
|
68411
68775
|
try {
|
|
68412
|
-
|
|
68776
|
+
execSync34(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
68413
68777
|
} catch {
|
|
68414
68778
|
}
|
|
68415
68779
|
} else {
|
|
@@ -68426,17 +68790,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68426
68790
|
} catch {
|
|
68427
68791
|
}
|
|
68428
68792
|
try {
|
|
68429
|
-
const voiceDir2 =
|
|
68793
|
+
const voiceDir2 = join71(homedir19(), ".open-agents", "voice");
|
|
68430
68794
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
68431
68795
|
for (const pf of voicePidFiles) {
|
|
68432
|
-
const pidPath =
|
|
68433
|
-
if (
|
|
68796
|
+
const pidPath = join71(voiceDir2, pf);
|
|
68797
|
+
if (existsSync54(pidPath)) {
|
|
68434
68798
|
try {
|
|
68435
|
-
const pid = parseInt(
|
|
68799
|
+
const pid = parseInt(readFileSync43(pidPath, "utf8").trim(), 10);
|
|
68436
68800
|
if (pid > 0) {
|
|
68437
68801
|
if (process.platform === "win32") {
|
|
68438
68802
|
try {
|
|
68439
|
-
|
|
68803
|
+
execSync34(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
68440
68804
|
} catch {
|
|
68441
68805
|
}
|
|
68442
68806
|
} else {
|
|
@@ -68453,11 +68817,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68453
68817
|
} catch {
|
|
68454
68818
|
}
|
|
68455
68819
|
try {
|
|
68456
|
-
|
|
68820
|
+
execSync34(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
68457
68821
|
} catch {
|
|
68458
68822
|
}
|
|
68459
|
-
const oaPath =
|
|
68460
|
-
if (
|
|
68823
|
+
const oaPath = join71(repoRoot, OA_DIR);
|
|
68824
|
+
if (existsSync54(oaPath)) {
|
|
68461
68825
|
let deleted = false;
|
|
68462
68826
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
68463
68827
|
try {
|
|
@@ -68467,14 +68831,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
68467
68831
|
} catch (err) {
|
|
68468
68832
|
if (attempt < 2) {
|
|
68469
68833
|
try {
|
|
68470
|
-
|
|
68834
|
+
execSync34(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
68471
68835
|
} catch {
|
|
68472
68836
|
}
|
|
68473
68837
|
} else {
|
|
68474
68838
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
68475
68839
|
if (process.platform === "win32") {
|
|
68476
68840
|
try {
|
|
68477
|
-
|
|
68841
|
+
execSync34(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
68478
68842
|
deleted = true;
|
|
68479
68843
|
} catch {
|
|
68480
68844
|
}
|
|
@@ -68867,8 +69231,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
68867
69231
|
}
|
|
68868
69232
|
}
|
|
68869
69233
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
68870
|
-
const isImage = isImagePath(cleanPath) &&
|
|
68871
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
69234
|
+
const isImage = isImagePath(cleanPath) && existsSync54(resolve32(repoRoot, cleanPath));
|
|
69235
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync54(resolve32(repoRoot, cleanPath));
|
|
68872
69236
|
if (activeTask) {
|
|
68873
69237
|
if (activeTask.runner.isPaused) {
|
|
68874
69238
|
activeTask.runner.resume();
|
|
@@ -68877,7 +69241,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
68877
69241
|
if (isImage) {
|
|
68878
69242
|
try {
|
|
68879
69243
|
const imgPath = resolve32(repoRoot, cleanPath);
|
|
68880
|
-
const imgBuffer =
|
|
69244
|
+
const imgBuffer = readFileSync43(imgPath);
|
|
68881
69245
|
const base64 = imgBuffer.toString("base64");
|
|
68882
69246
|
const ext = extname11(cleanPath).toLowerCase();
|
|
68883
69247
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -69405,13 +69769,13 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
69405
69769
|
const handle = startTask(task, config, repoRoot);
|
|
69406
69770
|
await handle.promise;
|
|
69407
69771
|
try {
|
|
69408
|
-
const ikDir =
|
|
69409
|
-
const ikFile =
|
|
69772
|
+
const ikDir = join71(repoRoot, ".oa", "identity");
|
|
69773
|
+
const ikFile = join71(ikDir, "self-state.json");
|
|
69410
69774
|
let ikState;
|
|
69411
|
-
if (
|
|
69412
|
-
ikState = JSON.parse(
|
|
69775
|
+
if (existsSync54(ikFile)) {
|
|
69776
|
+
ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
|
|
69413
69777
|
} else {
|
|
69414
|
-
|
|
69778
|
+
mkdirSync28(ikDir, { recursive: true });
|
|
69415
69779
|
ikState = {
|
|
69416
69780
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
69417
69781
|
version: 1,
|
|
@@ -69433,7 +69797,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
69433
69797
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
69434
69798
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
69435
69799
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
69436
|
-
|
|
69800
|
+
writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
|
|
69437
69801
|
} catch (ikErr) {
|
|
69438
69802
|
}
|
|
69439
69803
|
try {
|
|
@@ -69442,12 +69806,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
69442
69806
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
69443
69807
|
} catch {
|
|
69444
69808
|
try {
|
|
69445
|
-
const archeDir =
|
|
69446
|
-
const archeFile =
|
|
69809
|
+
const archeDir = join71(repoRoot, ".oa", "arche");
|
|
69810
|
+
const archeFile = join71(archeDir, "variants.json");
|
|
69447
69811
|
let variants = [];
|
|
69448
69812
|
try {
|
|
69449
|
-
if (
|
|
69450
|
-
variants = JSON.parse(
|
|
69813
|
+
if (existsSync54(archeFile))
|
|
69814
|
+
variants = JSON.parse(readFileSync43(archeFile, "utf8"));
|
|
69451
69815
|
} catch {
|
|
69452
69816
|
}
|
|
69453
69817
|
variants.push({
|
|
@@ -69462,15 +69826,15 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
69462
69826
|
});
|
|
69463
69827
|
if (variants.length > 50)
|
|
69464
69828
|
variants = variants.slice(-50);
|
|
69465
|
-
|
|
69466
|
-
|
|
69829
|
+
mkdirSync28(archeDir, { recursive: true });
|
|
69830
|
+
writeFileSync27(archeFile, JSON.stringify(variants, null, 2));
|
|
69467
69831
|
} catch {
|
|
69468
69832
|
}
|
|
69469
69833
|
}
|
|
69470
69834
|
try {
|
|
69471
|
-
const metaFile =
|
|
69472
|
-
if (
|
|
69473
|
-
const store = JSON.parse(
|
|
69835
|
+
const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
69836
|
+
if (existsSync54(metaFile)) {
|
|
69837
|
+
const store = JSON.parse(readFileSync43(metaFile, "utf8"));
|
|
69474
69838
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
69475
69839
|
let updated = false;
|
|
69476
69840
|
for (const item of surfaced) {
|
|
@@ -69481,7 +69845,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
69481
69845
|
updated = true;
|
|
69482
69846
|
}
|
|
69483
69847
|
if (updated) {
|
|
69484
|
-
|
|
69848
|
+
writeFileSync27(metaFile, JSON.stringify(store, null, 2));
|
|
69485
69849
|
}
|
|
69486
69850
|
}
|
|
69487
69851
|
} catch {
|
|
@@ -69534,9 +69898,9 @@ Rules:
|
|
|
69534
69898
|
try {
|
|
69535
69899
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
69536
69900
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
69537
|
-
const dbDir =
|
|
69538
|
-
|
|
69539
|
-
const db = initDb2(
|
|
69901
|
+
const dbDir = join71(repoRoot, ".oa", "memory");
|
|
69902
|
+
mkdirSync28(dbDir, { recursive: true });
|
|
69903
|
+
const db = initDb2(join71(dbDir, "structured.db"));
|
|
69540
69904
|
const memStore = new ProceduralMemoryStore2(db);
|
|
69541
69905
|
memStore.createWithEmbedding({
|
|
69542
69906
|
content: content.slice(0, 600),
|
|
@@ -69551,12 +69915,12 @@ Rules:
|
|
|
69551
69915
|
db.close();
|
|
69552
69916
|
} catch {
|
|
69553
69917
|
}
|
|
69554
|
-
const metaDir =
|
|
69555
|
-
const storeFile =
|
|
69918
|
+
const metaDir = join71(repoRoot, ".oa", "memory", "metabolism");
|
|
69919
|
+
const storeFile = join71(metaDir, "store.json");
|
|
69556
69920
|
let store = [];
|
|
69557
69921
|
try {
|
|
69558
|
-
if (
|
|
69559
|
-
store = JSON.parse(
|
|
69922
|
+
if (existsSync54(storeFile))
|
|
69923
|
+
store = JSON.parse(readFileSync43(storeFile, "utf8"));
|
|
69560
69924
|
} catch {
|
|
69561
69925
|
}
|
|
69562
69926
|
store.push({
|
|
@@ -69572,26 +69936,26 @@ Rules:
|
|
|
69572
69936
|
});
|
|
69573
69937
|
if (store.length > 100)
|
|
69574
69938
|
store = store.slice(-100);
|
|
69575
|
-
|
|
69576
|
-
|
|
69939
|
+
mkdirSync28(metaDir, { recursive: true });
|
|
69940
|
+
writeFileSync27(storeFile, JSON.stringify(store, null, 2));
|
|
69577
69941
|
}
|
|
69578
69942
|
}
|
|
69579
69943
|
} catch {
|
|
69580
69944
|
}
|
|
69581
69945
|
try {
|
|
69582
|
-
const cohereSettingsFile =
|
|
69946
|
+
const cohereSettingsFile = join71(repoRoot, ".oa", "settings.json");
|
|
69583
69947
|
let cohereActive = false;
|
|
69584
69948
|
try {
|
|
69585
|
-
if (
|
|
69586
|
-
const settings = JSON.parse(
|
|
69949
|
+
if (existsSync54(cohereSettingsFile)) {
|
|
69950
|
+
const settings = JSON.parse(readFileSync43(cohereSettingsFile, "utf8"));
|
|
69587
69951
|
cohereActive = settings.cohere === true;
|
|
69588
69952
|
}
|
|
69589
69953
|
} catch {
|
|
69590
69954
|
}
|
|
69591
69955
|
if (cohereActive) {
|
|
69592
|
-
const metaFile =
|
|
69593
|
-
if (
|
|
69594
|
-
const store = JSON.parse(
|
|
69956
|
+
const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
69957
|
+
if (existsSync54(metaFile)) {
|
|
69958
|
+
const store = JSON.parse(readFileSync43(metaFile, "utf8"));
|
|
69595
69959
|
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
69596
69960
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
69597
69961
|
try {
|
|
@@ -69616,18 +69980,18 @@ Rules:
|
|
|
69616
69980
|
}
|
|
69617
69981
|
} catch (err) {
|
|
69618
69982
|
try {
|
|
69619
|
-
const ikFile =
|
|
69620
|
-
if (
|
|
69621
|
-
const ikState = JSON.parse(
|
|
69983
|
+
const ikFile = join71(repoRoot, ".oa", "identity", "self-state.json");
|
|
69984
|
+
if (existsSync54(ikFile)) {
|
|
69985
|
+
const ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
|
|
69622
69986
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
69623
69987
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
69624
69988
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
69625
69989
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
69626
|
-
|
|
69990
|
+
writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
|
|
69627
69991
|
}
|
|
69628
|
-
const metaFile =
|
|
69629
|
-
if (
|
|
69630
|
-
const store = JSON.parse(
|
|
69992
|
+
const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
69993
|
+
if (existsSync54(metaFile)) {
|
|
69994
|
+
const store = JSON.parse(readFileSync43(metaFile, "utf8"));
|
|
69631
69995
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
69632
69996
|
for (const item of surfaced) {
|
|
69633
69997
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -69635,15 +69999,15 @@ Rules:
|
|
|
69635
69999
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
69636
70000
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
69637
70001
|
}
|
|
69638
|
-
|
|
70002
|
+
writeFileSync27(metaFile, JSON.stringify(store, null, 2));
|
|
69639
70003
|
}
|
|
69640
70004
|
try {
|
|
69641
|
-
const archeDir =
|
|
69642
|
-
const archeFile =
|
|
70005
|
+
const archeDir = join71(repoRoot, ".oa", "arche");
|
|
70006
|
+
const archeFile = join71(archeDir, "variants.json");
|
|
69643
70007
|
let variants = [];
|
|
69644
70008
|
try {
|
|
69645
|
-
if (
|
|
69646
|
-
variants = JSON.parse(
|
|
70009
|
+
if (existsSync54(archeFile))
|
|
70010
|
+
variants = JSON.parse(readFileSync43(archeFile, "utf8"));
|
|
69647
70011
|
} catch {
|
|
69648
70012
|
}
|
|
69649
70013
|
variants.push({
|
|
@@ -69658,8 +70022,8 @@ Rules:
|
|
|
69658
70022
|
});
|
|
69659
70023
|
if (variants.length > 50)
|
|
69660
70024
|
variants = variants.slice(-50);
|
|
69661
|
-
|
|
69662
|
-
|
|
70025
|
+
mkdirSync28(archeDir, { recursive: true });
|
|
70026
|
+
writeFileSync27(archeFile, JSON.stringify(variants, null, 2));
|
|
69663
70027
|
} catch {
|
|
69664
70028
|
}
|
|
69665
70029
|
} catch {
|
|
@@ -69725,14 +70089,14 @@ __export(run_exports, {
|
|
|
69725
70089
|
statusCommand: () => statusCommand
|
|
69726
70090
|
});
|
|
69727
70091
|
import { resolve as resolve33 } from "node:path";
|
|
69728
|
-
import { spawn as
|
|
69729
|
-
import { mkdirSync as
|
|
70092
|
+
import { spawn as spawn22 } from "node:child_process";
|
|
70093
|
+
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync28, readFileSync as readFileSync44, readdirSync as readdirSync22, existsSync as existsSync55 } from "node:fs";
|
|
69730
70094
|
import { randomBytes as randomBytes17 } from "node:crypto";
|
|
69731
|
-
import { join as
|
|
70095
|
+
import { join as join72 } from "node:path";
|
|
69732
70096
|
function jobsDir2(repoPath) {
|
|
69733
70097
|
const root = resolve33(repoPath ?? process.cwd());
|
|
69734
|
-
const dir =
|
|
69735
|
-
|
|
70098
|
+
const dir = join72(root, ".oa", "jobs");
|
|
70099
|
+
mkdirSync29(dir, { recursive: true });
|
|
69736
70100
|
return dir;
|
|
69737
70101
|
}
|
|
69738
70102
|
async function runCommand(opts, config) {
|
|
@@ -69809,7 +70173,7 @@ async function runBackground(task, config, opts) {
|
|
|
69809
70173
|
const args = [task, "--json"];
|
|
69810
70174
|
if (config.model)
|
|
69811
70175
|
args.push("--model", config.model);
|
|
69812
|
-
const child =
|
|
70176
|
+
const child = spawn22("node", [oaBin, ...args], {
|
|
69813
70177
|
cwd: repoRoot,
|
|
69814
70178
|
env: { ...process.env, OA_JOB_ID: id },
|
|
69815
70179
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -69817,7 +70181,7 @@ async function runBackground(task, config, opts) {
|
|
|
69817
70181
|
});
|
|
69818
70182
|
child.unref();
|
|
69819
70183
|
job.pid = child.pid ?? 0;
|
|
69820
|
-
|
|
70184
|
+
writeFileSync28(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
69821
70185
|
let output = "";
|
|
69822
70186
|
child.stdout?.on("data", (chunk) => {
|
|
69823
70187
|
output += chunk.toString();
|
|
@@ -69833,7 +70197,7 @@ async function runBackground(task, config, opts) {
|
|
|
69833
70197
|
job.summary = result.summary;
|
|
69834
70198
|
job.durationMs = result.durationMs;
|
|
69835
70199
|
job.error = result.error;
|
|
69836
|
-
|
|
70200
|
+
writeFileSync28(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
69837
70201
|
} catch {
|
|
69838
70202
|
}
|
|
69839
70203
|
});
|
|
@@ -69849,13 +70213,13 @@ async function runBackground(task, config, opts) {
|
|
|
69849
70213
|
}
|
|
69850
70214
|
function statusCommand(jobId, repoPath) {
|
|
69851
70215
|
const dir = jobsDir2(repoPath);
|
|
69852
|
-
const file =
|
|
69853
|
-
if (!
|
|
70216
|
+
const file = join72(dir, `${jobId}.json`);
|
|
70217
|
+
if (!existsSync55(file)) {
|
|
69854
70218
|
console.error(`Job not found: ${jobId}`);
|
|
69855
70219
|
console.log(`Available jobs: oa jobs`);
|
|
69856
70220
|
process.exit(1);
|
|
69857
70221
|
}
|
|
69858
|
-
const job = JSON.parse(
|
|
70222
|
+
const job = JSON.parse(readFileSync44(file, "utf-8"));
|
|
69859
70223
|
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`;
|
|
69860
70224
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
69861
70225
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -69878,7 +70242,7 @@ function jobsCommand(repoPath) {
|
|
|
69878
70242
|
console.log("Jobs:");
|
|
69879
70243
|
for (const file of files) {
|
|
69880
70244
|
try {
|
|
69881
|
-
const job = JSON.parse(
|
|
70245
|
+
const job = JSON.parse(readFileSync44(join72(dir, file), "utf-8"));
|
|
69882
70246
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
69883
70247
|
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`;
|
|
69884
70248
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -69898,7 +70262,7 @@ import { glob } from "glob";
|
|
|
69898
70262
|
import ignore from "ignore";
|
|
69899
70263
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
69900
70264
|
import { createHash as createHash6 } from "node:crypto";
|
|
69901
|
-
import { join as
|
|
70265
|
+
import { join as join73, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
69902
70266
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
69903
70267
|
var init_codebase_indexer = __esm({
|
|
69904
70268
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -69942,7 +70306,7 @@ var init_codebase_indexer = __esm({
|
|
|
69942
70306
|
const ig = ignore.default();
|
|
69943
70307
|
if (this.config.respectGitignore) {
|
|
69944
70308
|
try {
|
|
69945
|
-
const gitignoreContent = await readFile23(
|
|
70309
|
+
const gitignoreContent = await readFile23(join73(this.config.rootDir, ".gitignore"), "utf-8");
|
|
69946
70310
|
ig.add(gitignoreContent);
|
|
69947
70311
|
} catch {
|
|
69948
70312
|
}
|
|
@@ -69957,7 +70321,7 @@ var init_codebase_indexer = __esm({
|
|
|
69957
70321
|
for (const relativePath of files) {
|
|
69958
70322
|
if (ig.ignores(relativePath))
|
|
69959
70323
|
continue;
|
|
69960
|
-
const fullPath =
|
|
70324
|
+
const fullPath = join73(this.config.rootDir, relativePath);
|
|
69961
70325
|
try {
|
|
69962
70326
|
const fileStat = await stat4(fullPath);
|
|
69963
70327
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -70003,7 +70367,7 @@ var init_codebase_indexer = __esm({
|
|
|
70003
70367
|
if (!child) {
|
|
70004
70368
|
child = {
|
|
70005
70369
|
name: part,
|
|
70006
|
-
path:
|
|
70370
|
+
path: join73(current.path, part),
|
|
70007
70371
|
type: "directory",
|
|
70008
70372
|
children: []
|
|
70009
70373
|
};
|
|
@@ -70086,13 +70450,13 @@ __export(index_repo_exports, {
|
|
|
70086
70450
|
indexRepoCommand: () => indexRepoCommand
|
|
70087
70451
|
});
|
|
70088
70452
|
import { resolve as resolve34 } from "node:path";
|
|
70089
|
-
import { existsSync as
|
|
70453
|
+
import { existsSync as existsSync56, statSync as statSync16 } from "node:fs";
|
|
70090
70454
|
import { cwd as cwd2 } from "node:process";
|
|
70091
70455
|
async function indexRepoCommand(opts, _config) {
|
|
70092
70456
|
const repoRoot = resolve34(opts.repoPath ?? cwd2());
|
|
70093
70457
|
printHeader("Index Repository");
|
|
70094
70458
|
printInfo(`Indexing: ${repoRoot}`);
|
|
70095
|
-
if (!
|
|
70459
|
+
if (!existsSync56(repoRoot)) {
|
|
70096
70460
|
printError(`Path does not exist: ${repoRoot}`);
|
|
70097
70461
|
process.exit(1);
|
|
70098
70462
|
}
|
|
@@ -70344,8 +70708,8 @@ var config_exports2 = {};
|
|
|
70344
70708
|
__export(config_exports2, {
|
|
70345
70709
|
configCommand: () => configCommand
|
|
70346
70710
|
});
|
|
70347
|
-
import { join as
|
|
70348
|
-
import { homedir as
|
|
70711
|
+
import { join as join74, resolve as resolve35 } from "node:path";
|
|
70712
|
+
import { homedir as homedir20 } from "node:os";
|
|
70349
70713
|
import { cwd as cwd3 } from "node:process";
|
|
70350
70714
|
function redactIfSensitive(key, value) {
|
|
70351
70715
|
if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
|
|
@@ -70427,7 +70791,7 @@ function handleShow(opts, config) {
|
|
|
70427
70791
|
}
|
|
70428
70792
|
}
|
|
70429
70793
|
printSection("Config File");
|
|
70430
|
-
printInfo(`~/.open-agents/config.json (${
|
|
70794
|
+
printInfo(`~/.open-agents/config.json (${join74(homedir20(), ".open-agents", "config.json")})`);
|
|
70431
70795
|
printSection("Priority Chain");
|
|
70432
70796
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
70433
70797
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -70466,7 +70830,7 @@ function handleSet(opts, _config) {
|
|
|
70466
70830
|
const coerced = coerceForSettings(key, value);
|
|
70467
70831
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
70468
70832
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
70469
|
-
printInfo(`Saved to ${
|
|
70833
|
+
printInfo(`Saved to ${join74(repoRoot, ".oa", "settings.json")}`);
|
|
70470
70834
|
printInfo("This override applies only when running in this workspace.");
|
|
70471
70835
|
} catch (err) {
|
|
70472
70836
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -70609,8 +70973,8 @@ __export(eval_exports, {
|
|
|
70609
70973
|
evalCommand: () => evalCommand
|
|
70610
70974
|
});
|
|
70611
70975
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
70612
|
-
import { mkdirSync as
|
|
70613
|
-
import { join as
|
|
70976
|
+
import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29 } from "node:fs";
|
|
70977
|
+
import { join as join75 } from "node:path";
|
|
70614
70978
|
async function evalCommand(opts, config) {
|
|
70615
70979
|
const suiteName = opts.suite ?? "basic";
|
|
70616
70980
|
const suite = SUITES[suiteName];
|
|
@@ -70735,9 +71099,9 @@ async function evalCommand(opts, config) {
|
|
|
70735
71099
|
process.exit(failed > 0 ? 1 : 0);
|
|
70736
71100
|
}
|
|
70737
71101
|
function createTempEvalRepo() {
|
|
70738
|
-
const dir =
|
|
70739
|
-
|
|
70740
|
-
|
|
71102
|
+
const dir = join75(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
71103
|
+
mkdirSync30(dir, { recursive: true });
|
|
71104
|
+
writeFileSync29(join75(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
70741
71105
|
return dir;
|
|
70742
71106
|
}
|
|
70743
71107
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -70797,7 +71161,7 @@ init_updater();
|
|
|
70797
71161
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
70798
71162
|
import { createRequire as createRequire5 } from "node:module";
|
|
70799
71163
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
70800
|
-
import { dirname as dirname22, join as
|
|
71164
|
+
import { dirname as dirname22, join as join76 } from "node:path";
|
|
70801
71165
|
|
|
70802
71166
|
// packages/cli/dist/cli.js
|
|
70803
71167
|
import { createInterface } from "node:readline";
|
|
@@ -70904,7 +71268,7 @@ init_output();
|
|
|
70904
71268
|
function getVersion5() {
|
|
70905
71269
|
try {
|
|
70906
71270
|
const require2 = createRequire5(import.meta.url);
|
|
70907
|
-
const pkgPath =
|
|
71271
|
+
const pkgPath = join76(dirname22(fileURLToPath14(import.meta.url)), "..", "package.json");
|
|
70908
71272
|
const pkg = require2(pkgPath);
|
|
70909
71273
|
return pkg.version;
|
|
70910
71274
|
} catch {
|
|
@@ -71179,12 +71543,12 @@ function crashLog(label, err) {
|
|
|
71179
71543
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
71180
71544
|
`;
|
|
71181
71545
|
try {
|
|
71182
|
-
const { appendFileSync: appendFileSync5, mkdirSync:
|
|
71183
|
-
const { join:
|
|
71184
|
-
const { homedir:
|
|
71185
|
-
const logDir =
|
|
71186
|
-
|
|
71187
|
-
appendFileSync5(
|
|
71546
|
+
const { appendFileSync: appendFileSync5, mkdirSync: mkdirSync31 } = __require("node:fs");
|
|
71547
|
+
const { join: join77 } = __require("node:path");
|
|
71548
|
+
const { homedir: homedir21 } = __require("node:os");
|
|
71549
|
+
const logDir = join77(homedir21(), ".open-agents");
|
|
71550
|
+
mkdirSync31(logDir, { recursive: true });
|
|
71551
|
+
appendFileSync5(join77(logDir, "crash.log"), logLine);
|
|
71188
71552
|
} catch {
|
|
71189
71553
|
}
|
|
71190
71554
|
try {
|