open-agents-ai 0.185.78 → 0.185.80
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 +583 -244
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11957,8 +11957,8 @@ async function loadTranscribeCli() {
|
|
|
11957
11957
|
const nvmBase = join19(homedir7(), ".nvm", "versions", "node");
|
|
11958
11958
|
if (existsSync16(nvmBase)) {
|
|
11959
11959
|
try {
|
|
11960
|
-
const { readdirSync:
|
|
11961
|
-
for (const ver of
|
|
11960
|
+
const { readdirSync: readdirSync25 } = await import("node:fs");
|
|
11961
|
+
for (const ver of readdirSync25(nvmBase)) {
|
|
11962
11962
|
const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
11963
11963
|
if (existsSync16(join19(tcPath, "dist", "index.js"))) {
|
|
11964
11964
|
const { createRequire: createRequire6 } = await import("node:module");
|
|
@@ -13820,11 +13820,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13820
13820
|
* what was previously computed. */
|
|
13821
13821
|
async loadSessionInfo() {
|
|
13822
13822
|
try {
|
|
13823
|
-
const { readFileSync:
|
|
13823
|
+
const { readFileSync: readFileSync48, existsSync: existsSync60 } = await import("node:fs");
|
|
13824
13824
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13825
|
-
if (!
|
|
13825
|
+
if (!existsSync60(sessionPath))
|
|
13826
13826
|
return null;
|
|
13827
|
-
return JSON.parse(
|
|
13827
|
+
return JSON.parse(readFileSync48(sessionPath, "utf8"));
|
|
13828
13828
|
} catch {
|
|
13829
13829
|
return null;
|
|
13830
13830
|
}
|
|
@@ -14001,10 +14001,10 @@ var init_memory_metabolism = __esm({
|
|
|
14001
14001
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
14002
14002
|
let lessons = [];
|
|
14003
14003
|
try {
|
|
14004
|
-
const { readdirSync:
|
|
14005
|
-
const files =
|
|
14004
|
+
const { readdirSync: readdirSync25, readFileSync: readFileSync48 } = await import("node:fs");
|
|
14005
|
+
const files = readdirSync25(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
14006
14006
|
for (const file of files) {
|
|
14007
|
-
const lines =
|
|
14007
|
+
const lines = readFileSync48(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
14008
14008
|
for (const line of lines) {
|
|
14009
14009
|
try {
|
|
14010
14010
|
const entry = JSON.parse(line);
|
|
@@ -14388,14 +14388,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14388
14388
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14389
14389
|
*/
|
|
14390
14390
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14391
|
-
const { readFileSync:
|
|
14391
|
+
const { readFileSync: readFileSync48, existsSync: existsSync60 } = __require("node:fs");
|
|
14392
14392
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14393
14393
|
const storeFile = join23(metaDir, "store.json");
|
|
14394
|
-
if (!
|
|
14394
|
+
if (!existsSync60(storeFile))
|
|
14395
14395
|
return "";
|
|
14396
14396
|
let store2 = [];
|
|
14397
14397
|
try {
|
|
14398
|
-
store2 = JSON.parse(
|
|
14398
|
+
store2 = JSON.parse(readFileSync48(storeFile, "utf8"));
|
|
14399
14399
|
} catch {
|
|
14400
14400
|
return "";
|
|
14401
14401
|
}
|
|
@@ -14417,14 +14417,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14417
14417
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14418
14418
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14419
14419
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14420
|
-
const { readFileSync:
|
|
14420
|
+
const { readFileSync: readFileSync48, writeFileSync: writeFileSync31, existsSync: existsSync60, mkdirSync: mkdirSync33 } = __require("node:fs");
|
|
14421
14421
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14422
14422
|
const storeFile = join23(metaDir, "store.json");
|
|
14423
|
-
if (!
|
|
14423
|
+
if (!existsSync60(storeFile))
|
|
14424
14424
|
return;
|
|
14425
14425
|
let store2 = [];
|
|
14426
14426
|
try {
|
|
14427
|
-
store2 = JSON.parse(
|
|
14427
|
+
store2 = JSON.parse(readFileSync48(storeFile, "utf8"));
|
|
14428
14428
|
} catch {
|
|
14429
14429
|
return;
|
|
14430
14430
|
}
|
|
@@ -14871,13 +14871,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14871
14871
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14872
14872
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14873
14873
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14874
|
-
const { readFileSync:
|
|
14874
|
+
const { readFileSync: readFileSync48, existsSync: existsSync60 } = __require("node:fs");
|
|
14875
14875
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14876
|
-
if (!
|
|
14876
|
+
if (!existsSync60(archiveFile))
|
|
14877
14877
|
return "";
|
|
14878
14878
|
let variants = [];
|
|
14879
14879
|
try {
|
|
14880
|
-
variants = JSON.parse(
|
|
14880
|
+
variants = JSON.parse(readFileSync48(archiveFile, "utf8"));
|
|
14881
14881
|
} catch {
|
|
14882
14882
|
return "";
|
|
14883
14883
|
}
|
|
@@ -14895,13 +14895,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14895
14895
|
}
|
|
14896
14896
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14897
14897
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14898
|
-
const { readFileSync:
|
|
14898
|
+
const { readFileSync: readFileSync48, writeFileSync: writeFileSync31, existsSync: existsSync60, mkdirSync: mkdirSync33 } = __require("node:fs");
|
|
14899
14899
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14900
14900
|
const archiveFile = join25(dir, "variants.json");
|
|
14901
14901
|
let variants = [];
|
|
14902
14902
|
try {
|
|
14903
|
-
if (
|
|
14904
|
-
variants = JSON.parse(
|
|
14903
|
+
if (existsSync60(archiveFile))
|
|
14904
|
+
variants = JSON.parse(readFileSync48(archiveFile, "utf8"));
|
|
14905
14905
|
} catch {
|
|
14906
14906
|
}
|
|
14907
14907
|
variants.push({
|
|
@@ -27423,8 +27423,8 @@ ${marker}` : marker);
|
|
|
27423
27423
|
return;
|
|
27424
27424
|
try {
|
|
27425
27425
|
const { mkdirSync: mkdirSync33, writeFileSync: writeFileSync31 } = __require("node:fs");
|
|
27426
|
-
const { join:
|
|
27427
|
-
const sessionDir =
|
|
27426
|
+
const { join: join80 } = __require("node:path");
|
|
27427
|
+
const sessionDir = join80(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
27428
27428
|
mkdirSync33(sessionDir, { recursive: true });
|
|
27429
27429
|
const checkpoint = {
|
|
27430
27430
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27437,7 +27437,7 @@ ${marker}` : marker);
|
|
|
27437
27437
|
memexEntryCount: this._memexArchive.size,
|
|
27438
27438
|
fileRegistrySize: this._fileRegistry.size
|
|
27439
27439
|
};
|
|
27440
|
-
writeFileSync31(
|
|
27440
|
+
writeFileSync31(join80(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
27441
27441
|
} catch {
|
|
27442
27442
|
}
|
|
27443
27443
|
}
|
|
@@ -28575,17 +28575,17 @@ ${transcript}`
|
|
|
28575
28575
|
let resizedBase64 = null;
|
|
28576
28576
|
try {
|
|
28577
28577
|
const { execSync: execSync36 } = await import("node:child_process");
|
|
28578
|
-
const { writeFileSync: writeFileSync31, readFileSync:
|
|
28579
|
-
const { join:
|
|
28578
|
+
const { writeFileSync: writeFileSync31, readFileSync: readFileSync48, unlinkSync: unlinkSync13 } = await import("node:fs");
|
|
28579
|
+
const { join: join80 } = await import("node:path");
|
|
28580
28580
|
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
28581
|
-
const tmpIn =
|
|
28582
|
-
const tmpOut =
|
|
28581
|
+
const tmpIn = join80(tmpdir11(), `oa_img_in_${Date.now()}.png`);
|
|
28582
|
+
const tmpOut = join80(tmpdir11(), `oa_img_out_${Date.now()}.jpg`);
|
|
28583
28583
|
writeFileSync31(tmpIn, buffer);
|
|
28584
28584
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
28585
28585
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
28586
28586
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
28587
28587
|
execSync36(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
28588
|
-
const resizedBuf =
|
|
28588
|
+
const resizedBuf = readFileSync48(tmpOut);
|
|
28589
28589
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
28590
28590
|
try {
|
|
28591
28591
|
unlinkSync13(tmpIn);
|
|
@@ -30716,8 +30716,8 @@ var init_listen = __esm({
|
|
|
30716
30716
|
const nvmBase = join48(homedir11(), ".nvm", "versions", "node");
|
|
30717
30717
|
if (existsSync32(nvmBase)) {
|
|
30718
30718
|
try {
|
|
30719
|
-
const { readdirSync:
|
|
30720
|
-
for (const ver of
|
|
30719
|
+
const { readdirSync: readdirSync25 } = await import("node:fs");
|
|
30720
|
+
for (const ver of readdirSync25(nvmBase)) {
|
|
30721
30721
|
const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
30722
30722
|
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
30723
30723
|
const { createRequire: createRequire6 } = await import("node:module");
|
|
@@ -39557,26 +39557,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
39557
39557
|
async function fetchPeerModels(peerId, authKey) {
|
|
39558
39558
|
try {
|
|
39559
39559
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
39560
|
-
const { existsSync:
|
|
39561
|
-
const { join:
|
|
39560
|
+
const { existsSync: existsSync60, readFileSync: readFileSync48 } = await import("node:fs");
|
|
39561
|
+
const { join: join80 } = await import("node:path");
|
|
39562
39562
|
const cwd4 = process.cwd();
|
|
39563
39563
|
const nexusTool = new NexusTool2(cwd4);
|
|
39564
39564
|
const nexusDir = nexusTool.getNexusDir();
|
|
39565
39565
|
let isLocalPeer = false;
|
|
39566
39566
|
try {
|
|
39567
|
-
const statusPath =
|
|
39568
|
-
if (
|
|
39569
|
-
const status = JSON.parse(
|
|
39567
|
+
const statusPath = join80(nexusDir, "status.json");
|
|
39568
|
+
if (existsSync60(statusPath)) {
|
|
39569
|
+
const status = JSON.parse(readFileSync48(statusPath, "utf8"));
|
|
39570
39570
|
if (status.peerId === peerId)
|
|
39571
39571
|
isLocalPeer = true;
|
|
39572
39572
|
}
|
|
39573
39573
|
} catch {
|
|
39574
39574
|
}
|
|
39575
39575
|
if (isLocalPeer) {
|
|
39576
|
-
const pricingPath =
|
|
39577
|
-
if (
|
|
39576
|
+
const pricingPath = join80(nexusDir, "pricing.json");
|
|
39577
|
+
if (existsSync60(pricingPath)) {
|
|
39578
39578
|
try {
|
|
39579
|
-
const pricing = JSON.parse(
|
|
39579
|
+
const pricing = JSON.parse(readFileSync48(pricingPath, "utf8"));
|
|
39580
39580
|
const localModels = (pricing.models || []).map((m) => ({
|
|
39581
39581
|
name: m.model || "unknown",
|
|
39582
39582
|
size: m.parameterSize || "",
|
|
@@ -39590,10 +39590,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
39590
39590
|
}
|
|
39591
39591
|
}
|
|
39592
39592
|
}
|
|
39593
|
-
const cachePath =
|
|
39594
|
-
if (
|
|
39593
|
+
const cachePath = join80(nexusDir, "peer-models-cache.json");
|
|
39594
|
+
if (existsSync60(cachePath)) {
|
|
39595
39595
|
try {
|
|
39596
|
-
const cache4 = JSON.parse(
|
|
39596
|
+
const cache4 = JSON.parse(readFileSync48(cachePath, "utf8"));
|
|
39597
39597
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
39598
39598
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
39599
39599
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -39708,10 +39708,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
39708
39708
|
} catch {
|
|
39709
39709
|
}
|
|
39710
39710
|
if (isLocalPeer) {
|
|
39711
|
-
const pricingPath =
|
|
39712
|
-
if (
|
|
39711
|
+
const pricingPath = join80(nexusDir, "pricing.json");
|
|
39712
|
+
if (existsSync60(pricingPath)) {
|
|
39713
39713
|
try {
|
|
39714
|
-
const pricing = JSON.parse(
|
|
39714
|
+
const pricing = JSON.parse(readFileSync48(pricingPath, "utf8"));
|
|
39715
39715
|
return (pricing.models || []).map((m) => ({
|
|
39716
39716
|
name: m.model || "unknown",
|
|
39717
39717
|
size: m.parameterSize || "",
|
|
@@ -52966,8 +52966,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
52966
52966
|
if (models.length > 0) {
|
|
52967
52967
|
try {
|
|
52968
52968
|
const { writeFileSync: writeFileSync31, mkdirSync: mkdirSync33 } = await import("node:fs");
|
|
52969
|
-
const { join:
|
|
52970
|
-
const cachePath =
|
|
52969
|
+
const { join: join80, dirname: dirname24 } = await import("node:path");
|
|
52970
|
+
const cachePath = join80(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
52971
52971
|
mkdirSync33(dirname24(cachePath), { recursive: true });
|
|
52972
52972
|
writeFileSync31(cachePath, JSON.stringify({
|
|
52973
52973
|
peerId,
|
|
@@ -53168,17 +53168,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
53168
53168
|
try {
|
|
53169
53169
|
const { createRequire: createRequire6 } = await import("node:module");
|
|
53170
53170
|
const { fileURLToPath: fileURLToPath16 } = await import("node:url");
|
|
53171
|
-
const { dirname: dirname24, join:
|
|
53172
|
-
const { existsSync:
|
|
53171
|
+
const { dirname: dirname24, join: join80 } = await import("node:path");
|
|
53172
|
+
const { existsSync: existsSync60 } = await import("node:fs");
|
|
53173
53173
|
const req = createRequire6(import.meta.url);
|
|
53174
53174
|
const thisDir = dirname24(fileURLToPath16(import.meta.url));
|
|
53175
53175
|
const candidates = [
|
|
53176
|
-
|
|
53177
|
-
|
|
53178
|
-
|
|
53176
|
+
join80(thisDir, "..", "package.json"),
|
|
53177
|
+
join80(thisDir, "..", "..", "package.json"),
|
|
53178
|
+
join80(thisDir, "..", "..", "..", "package.json")
|
|
53179
53179
|
];
|
|
53180
53180
|
for (const pkgPath of candidates) {
|
|
53181
|
-
if (
|
|
53181
|
+
if (existsSync60(pkgPath)) {
|
|
53182
53182
|
const pkg = req(pkgPath);
|
|
53183
53183
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
53184
53184
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -54151,11 +54151,11 @@ function loadMemoryDir(memDir, scope) {
|
|
|
54151
54151
|
return lines.join("\n");
|
|
54152
54152
|
}
|
|
54153
54153
|
function loadSessionHistory(repoRoot) {
|
|
54154
|
-
const
|
|
54155
|
-
if (
|
|
54154
|
+
const sessions2 = loadRecentSessions(repoRoot, 5);
|
|
54155
|
+
if (sessions2.length === 0)
|
|
54156
54156
|
return "";
|
|
54157
54157
|
const lines = ["Recent tasks in this project:"];
|
|
54158
|
-
for (const s of
|
|
54158
|
+
for (const s of sessions2) {
|
|
54159
54159
|
if (!s.startedAt || !s.task)
|
|
54160
54160
|
continue;
|
|
54161
54161
|
const status = s.completed ? "completed" : "incomplete";
|
|
@@ -55490,8 +55490,8 @@ function listBannerDesigns(workDir) {
|
|
|
55490
55490
|
if (!existsSync45(dir))
|
|
55491
55491
|
return [];
|
|
55492
55492
|
try {
|
|
55493
|
-
const { readdirSync:
|
|
55494
|
-
return
|
|
55493
|
+
const { readdirSync: readdirSync25 } = __require("node:fs");
|
|
55494
|
+
return readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) => f.replace(".json", ""));
|
|
55495
55495
|
} catch {
|
|
55496
55496
|
return [];
|
|
55497
55497
|
}
|
|
@@ -56039,8 +56039,8 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
56039
56039
|
}
|
|
56040
56040
|
function extractFromSessions(repoRoot, tags) {
|
|
56041
56041
|
try {
|
|
56042
|
-
const
|
|
56043
|
-
for (const session of
|
|
56042
|
+
const sessions2 = loadRecentSessions(repoRoot, 10);
|
|
56043
|
+
for (const session of sessions2) {
|
|
56044
56044
|
if (session.task) {
|
|
56045
56045
|
const words = session.task.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w) => w.length > 3 && !STOP_WORDS.has(w));
|
|
56046
56046
|
tags.push(...words.slice(0, 4));
|
|
@@ -65508,6 +65508,13 @@ body {
|
|
|
65508
65508
|
outline: none;
|
|
65509
65509
|
margin-bottom: 12px;
|
|
65510
65510
|
}
|
|
65511
|
+
/* WO-E21: Responsive design */
|
|
65512
|
+
@media (max-width: 768px) {
|
|
65513
|
+
#workspace-sidebar { position:fixed !important; top:0; left:0; bottom:0; z-index:50; width:80vw !important; box-shadow:4px 0 20px rgba(0,0,0,0.5); }
|
|
65514
|
+
#header select { display:none; }
|
|
65515
|
+
#header .key-btn:first-of-type { display:none; }
|
|
65516
|
+
.tab { padding:6px 10px !important; font-size:0.6rem !important; }
|
|
65517
|
+
}
|
|
65511
65518
|
#key-modal .modal button {
|
|
65512
65519
|
background: #2a2a30;
|
|
65513
65520
|
border: 1px solid #b2920a;
|
|
@@ -65527,6 +65534,8 @@ body {
|
|
|
65527
65534
|
<span class="accent">OA</span>
|
|
65528
65535
|
<span class="status" id="status">connecting...</span>
|
|
65529
65536
|
<select id="model-select"><option>loading...</option></select>
|
|
65537
|
+
<button class="key-btn" onclick="toggleWorkspace()" title="Toggle workspace sidebar">files</button>
|
|
65538
|
+
<button class="key-btn" id="sandbox-toggle" onclick="toggleSandbox()" title="Toggle Docker sandbox" style="opacity:0.5">sandbox: off</button>
|
|
65530
65539
|
<button class="key-btn" id="key-btn" title="Set API key">key</button>
|
|
65531
65540
|
</div>
|
|
65532
65541
|
|
|
@@ -65542,7 +65551,17 @@ body {
|
|
|
65542
65551
|
<button class="tab" onclick="switchTab('activity')" id="tab-activity" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">activity</button>
|
|
65543
65552
|
<span id="token-counter" style="margin-left:auto;font-size:0.6rem;color:#555">0 tokens</span>
|
|
65544
65553
|
</div>
|
|
65545
|
-
<div
|
|
65554
|
+
<div style="display:flex;flex:1;overflow:hidden">
|
|
65555
|
+
<div id="workspace-sidebar" style="display:none;width:250px;background:#1e1e22;border-right:1px solid #2a2a30;overflow-y:auto;padding:8px;flex-shrink:0;font-size:0.7rem">
|
|
65556
|
+
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
|
65557
|
+
<span style="color:#b2920a;font-size:0.7rem;font-weight:bold">Workspace</span>
|
|
65558
|
+
<button onclick="toggleWorkspace()" style="background:none;border:none;color:#555;cursor:pointer;font-size:0.8rem">x</button>
|
|
65559
|
+
</div>
|
|
65560
|
+
<div id="workspace-cwd" style="color:#555;font-size:0.6rem;margin-bottom:8px;word-break:break-all"></div>
|
|
65561
|
+
<div id="workspace-tree" style="color:#b0b0b0"></div>
|
|
65562
|
+
</div>
|
|
65563
|
+
<div id="conversation" style="flex:1;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:4px"></div>
|
|
65564
|
+
</div>
|
|
65546
65565
|
<div id="agent-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65547
65566
|
<textarea id="agent-task" placeholder="Describe the task for the agent..." style="width:100%;min-height:80px;background:#2a2a30;border:1px solid #3a3a42;border-radius:3px;padding:8px 12px;color:#b0b0b0;font-family:inherit;font-size:0.82rem;resize:vertical;outline:none;margin-bottom:8px"></textarea>
|
|
65548
65567
|
<div style="display:flex;gap:8px;margin-bottom:12px;align-items:center">
|
|
@@ -65617,6 +65636,7 @@ const statusEl = document.getElementById('status');
|
|
|
65617
65636
|
let apiKey = localStorage.getItem('oa-api-key') || '';
|
|
65618
65637
|
let streaming = false;
|
|
65619
65638
|
let messages = [];
|
|
65639
|
+
let chatSessionId = null; // stateful session for /v1/chat
|
|
65620
65640
|
|
|
65621
65641
|
// Auto-resize textarea
|
|
65622
65642
|
input.addEventListener('input', () => {
|
|
@@ -65722,22 +65742,25 @@ async function sendMessage() {
|
|
|
65722
65742
|
let fullContent = '';
|
|
65723
65743
|
|
|
65724
65744
|
try {
|
|
65745
|
+
// Use stateful /v1/chat endpoint (maintains OA identity + context)
|
|
65725
65746
|
const body = {
|
|
65747
|
+
session_id: chatSessionId,
|
|
65726
65748
|
model: modelSelect.value,
|
|
65727
|
-
|
|
65728
|
-
...(sysPrompt ? [{ role: 'system', content: sysPrompt }] : []),
|
|
65729
|
-
...messages,
|
|
65730
|
-
],
|
|
65749
|
+
message: text,
|
|
65731
65750
|
stream: true,
|
|
65732
65751
|
max_tokens: 4096,
|
|
65733
65752
|
};
|
|
65734
65753
|
|
|
65735
|
-
const response = await fetch('/v1/chat
|
|
65754
|
+
const response = await fetch('/v1/chat', {
|
|
65736
65755
|
method: 'POST',
|
|
65737
65756
|
headers: headers(),
|
|
65738
65757
|
body: JSON.stringify(body),
|
|
65739
65758
|
});
|
|
65740
65759
|
|
|
65760
|
+
// Capture session ID from response header
|
|
65761
|
+
const sid = response.headers.get('x-session-id');
|
|
65762
|
+
if (sid) chatSessionId = sid;
|
|
65763
|
+
|
|
65741
65764
|
const reader = response.body.getReader();
|
|
65742
65765
|
const decoder = new TextDecoder();
|
|
65743
65766
|
let buffer = '';
|
|
@@ -66061,6 +66084,25 @@ async function loadDashboard() {
|
|
|
66061
66084
|
'<div style="color:#555;font-size:0.6rem">VERSION</div>' +
|
|
66062
66085
|
'<div style="color:#b0b0b0;font-size:0.8rem">' + d.version + '</div></div>';
|
|
66063
66086
|
} catch {}
|
|
66087
|
+
// System info + model recommendations
|
|
66088
|
+
try {
|
|
66089
|
+
const sr = await fetch('/v1/system', { headers: headers() });
|
|
66090
|
+
const sys = await sr.json();
|
|
66091
|
+
const gpuHtml = (sys.gpu || []).map(g => g.name + ' (' + g.vram_gb + 'GB)').join(', ') || 'No GPU detected';
|
|
66092
|
+
const healthEl = document.getElementById('dashboard-health');
|
|
66093
|
+
healthEl.innerHTML +=
|
|
66094
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1;min-width:120px">' +
|
|
66095
|
+
'<div style="color:#555;font-size:0.6rem">GPU</div>' +
|
|
66096
|
+
'<div style="color:#b0b0b0;font-size:0.7rem">' + gpuHtml + '</div></div>' +
|
|
66097
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1;min-width:120px">' +
|
|
66098
|
+
'<div style="color:#555;font-size:0.6rem">RAM</div>' +
|
|
66099
|
+
'<div style="color:#b0b0b0;font-size:0.8rem">' + sys.ram_gb + 'GB</div></div>' +
|
|
66100
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1;min-width:120px">' +
|
|
66101
|
+
'<div style="color:#555;font-size:0.6rem">MAX MODEL</div>' +
|
|
66102
|
+
'<div style="color:#b2920a;font-size:0.8rem">' + sys.recommended_max_params + '</div></div>';
|
|
66103
|
+
// Store for model badges
|
|
66104
|
+
window._sysMaxParams = sys.recommended_max_params;
|
|
66105
|
+
} catch {}
|
|
66064
66106
|
// Usage \u2014 per-provider breakdown with persistent totals
|
|
66065
66107
|
try {
|
|
66066
66108
|
const r = await fetch('/v1/usage', { headers: headers() });
|
|
@@ -66120,6 +66162,33 @@ async function loadJobs() {
|
|
|
66120
66162
|
} catch { list.innerHTML = '<div style="color:#ff4444">Failed to load jobs</div>'; }
|
|
66121
66163
|
}
|
|
66122
66164
|
|
|
66165
|
+
// Workspace sidebar
|
|
66166
|
+
function toggleWorkspace() {
|
|
66167
|
+
const sb = document.getElementById('workspace-sidebar');
|
|
66168
|
+
sb.style.display = sb.style.display === 'none' ? 'block' : 'none';
|
|
66169
|
+
if (sb.style.display === 'block') loadWorkspaceTree();
|
|
66170
|
+
}
|
|
66171
|
+
async function loadWorkspaceTree() {
|
|
66172
|
+
try {
|
|
66173
|
+
const r = await fetch('/v1/system', { headers: headers() });
|
|
66174
|
+
const d = await r.json();
|
|
66175
|
+
document.getElementById('workspace-cwd').textContent = d.cwd || process.cwd?.() || '.';
|
|
66176
|
+
} catch {}
|
|
66177
|
+
// Placeholder tree \u2014 full implementation requires a directory listing endpoint
|
|
66178
|
+
document.getElementById('workspace-tree').innerHTML =
|
|
66179
|
+
'<div style="color:#555;font-size:0.65rem">File tree requires /v1/files endpoint (future WO)</div>';
|
|
66180
|
+
}
|
|
66181
|
+
|
|
66182
|
+
// Docker sandbox toggle
|
|
66183
|
+
let sandboxMode = 'none';
|
|
66184
|
+
function toggleSandbox() {
|
|
66185
|
+
sandboxMode = sandboxMode === 'none' ? 'container' : 'none';
|
|
66186
|
+
const btn = document.getElementById('sandbox-toggle');
|
|
66187
|
+
btn.textContent = 'sandbox: ' + (sandboxMode === 'none' ? 'off' : 'docker');
|
|
66188
|
+
btn.style.opacity = sandboxMode === 'none' ? '0.5' : '1';
|
|
66189
|
+
btn.style.borderColor = sandboxMode === 'none' ? '#3a3a42' : '#b2920a';
|
|
66190
|
+
}
|
|
66191
|
+
|
|
66123
66192
|
// Init
|
|
66124
66193
|
checkHealth();
|
|
66125
66194
|
loadModels();
|
|
@@ -66259,16 +66328,137 @@ var init_auth_oidc = __esm({
|
|
|
66259
66328
|
}
|
|
66260
66329
|
});
|
|
66261
66330
|
|
|
66262
|
-
// packages/cli/dist/api/
|
|
66263
|
-
import {
|
|
66331
|
+
// packages/cli/dist/api/chat-session.js
|
|
66332
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
66333
|
+
import { existsSync as existsSync53, readFileSync as readFileSync42, readdirSync as readdirSync20 } from "node:fs";
|
|
66264
66334
|
import { join as join70 } from "node:path";
|
|
66335
|
+
function buildSystemPrompt(cwd4) {
|
|
66336
|
+
const parts = [];
|
|
66337
|
+
parts.push("You are Open Agent (OA), an AI coding assistant running locally via Ollama. You have access to the user's workspace and can discuss code, files, and projects. Be helpful, concise, and technically precise. When asked about files or code, describe what you know from the conversation context.");
|
|
66338
|
+
parts.push(`\\nEnvironment: ${process.platform}, Node ${process.version}, CWD: ${cwd4}`);
|
|
66339
|
+
const diaryPath = join70(cwd4, ".oa", "context", "session-diary.md");
|
|
66340
|
+
if (existsSync53(diaryPath)) {
|
|
66341
|
+
try {
|
|
66342
|
+
const diary = readFileSync42(diaryPath, "utf-8").slice(0, 1e3);
|
|
66343
|
+
parts.push(`\\nPrevious session history:\\n${diary}`);
|
|
66344
|
+
} catch {
|
|
66345
|
+
}
|
|
66346
|
+
}
|
|
66347
|
+
const memDir = join70(cwd4, ".oa", "memory");
|
|
66348
|
+
if (existsSync53(memDir)) {
|
|
66349
|
+
try {
|
|
66350
|
+
const files = readdirSync20(memDir).filter((f) => f.endsWith(".json")).slice(0, 5);
|
|
66351
|
+
if (files.length > 0) {
|
|
66352
|
+
parts.push("\\nPersistent memory topics: " + files.map((f) => f.replace(".json", "")).join(", "));
|
|
66353
|
+
for (const f of files.slice(0, 3)) {
|
|
66354
|
+
try {
|
|
66355
|
+
const data = JSON.parse(readFileSync42(join70(memDir, f), "utf-8"));
|
|
66356
|
+
const entries = Object.entries(data).slice(0, 3);
|
|
66357
|
+
if (entries.length > 0) {
|
|
66358
|
+
parts.push(`\\nMemory [${f.replace(".json", "")}]: ` + entries.map(([k, v]) => `${k}: ${String(v.value ?? v).slice(0, 100)}`).join("; "));
|
|
66359
|
+
}
|
|
66360
|
+
} catch {
|
|
66361
|
+
}
|
|
66362
|
+
}
|
|
66363
|
+
}
|
|
66364
|
+
} catch {
|
|
66365
|
+
}
|
|
66366
|
+
}
|
|
66367
|
+
for (const name of ["AGENTS.md", "OA.md", ".open-agents.md"]) {
|
|
66368
|
+
const p = join70(cwd4, name);
|
|
66369
|
+
if (existsSync53(p)) {
|
|
66370
|
+
try {
|
|
66371
|
+
const content = readFileSync42(p, "utf-8").slice(0, 500);
|
|
66372
|
+
parts.push(`\\nProject instructions (${name}):\\n${content}`);
|
|
66373
|
+
} catch {
|
|
66374
|
+
}
|
|
66375
|
+
}
|
|
66376
|
+
}
|
|
66377
|
+
return parts.join("");
|
|
66378
|
+
}
|
|
66379
|
+
function getSession(sessionId, model, cwd4) {
|
|
66380
|
+
if (sessionId && sessions.has(sessionId)) {
|
|
66381
|
+
const s = sessions.get(sessionId);
|
|
66382
|
+
s.lastActivity = Date.now();
|
|
66383
|
+
return s;
|
|
66384
|
+
}
|
|
66385
|
+
const id = sessionId || randomUUID4();
|
|
66386
|
+
const systemPrompt = buildSystemPrompt(cwd4);
|
|
66387
|
+
const session = {
|
|
66388
|
+
id,
|
|
66389
|
+
messages: [{ role: "system", content: systemPrompt }],
|
|
66390
|
+
model,
|
|
66391
|
+
createdAt: Date.now(),
|
|
66392
|
+
lastActivity: Date.now(),
|
|
66393
|
+
tokensIn: 0,
|
|
66394
|
+
tokensOut: 0
|
|
66395
|
+
};
|
|
66396
|
+
sessions.set(id, session);
|
|
66397
|
+
return session;
|
|
66398
|
+
}
|
|
66399
|
+
function addUserMessage(session, content) {
|
|
66400
|
+
session.messages.push({ role: "user", content });
|
|
66401
|
+
session.lastActivity = Date.now();
|
|
66402
|
+
return [...session.messages];
|
|
66403
|
+
}
|
|
66404
|
+
function addAssistantMessage(session, content) {
|
|
66405
|
+
session.messages.push({ role: "assistant", content });
|
|
66406
|
+
session.lastActivity = Date.now();
|
|
66407
|
+
}
|
|
66408
|
+
function trackSessionTokens(session, tokensIn, tokensOut) {
|
|
66409
|
+
session.tokensIn += tokensIn;
|
|
66410
|
+
session.tokensOut += tokensOut;
|
|
66411
|
+
}
|
|
66412
|
+
function listSessions() {
|
|
66413
|
+
return Array.from(sessions.values()).map((s) => ({
|
|
66414
|
+
id: s.id,
|
|
66415
|
+
model: s.model,
|
|
66416
|
+
messages: s.messages.length - 1,
|
|
66417
|
+
// exclude system prompt
|
|
66418
|
+
tokensIn: s.tokensIn,
|
|
66419
|
+
tokensOut: s.tokensOut,
|
|
66420
|
+
lastActivity: new Date(s.lastActivity).toISOString()
|
|
66421
|
+
}));
|
|
66422
|
+
}
|
|
66423
|
+
function compactSession(session, maxMessages = 40) {
|
|
66424
|
+
if (session.messages.length <= maxMessages)
|
|
66425
|
+
return;
|
|
66426
|
+
const system = session.messages[0];
|
|
66427
|
+
const recent = session.messages.slice(-20);
|
|
66428
|
+
const middle = session.messages.slice(1, -20);
|
|
66429
|
+
const summary = `[Earlier conversation: ${middle.length} messages discussed ` + middle.filter((m) => m.role === "user").map((m) => m.content.slice(0, 50)).slice(0, 5).join(", ") + "...]";
|
|
66430
|
+
session.messages = [
|
|
66431
|
+
system,
|
|
66432
|
+
{ role: "system", content: summary },
|
|
66433
|
+
...recent
|
|
66434
|
+
];
|
|
66435
|
+
}
|
|
66436
|
+
var sessions, SESSION_TTL_MS;
|
|
66437
|
+
var init_chat_session = __esm({
|
|
66438
|
+
"packages/cli/dist/api/chat-session.js"() {
|
|
66439
|
+
"use strict";
|
|
66440
|
+
sessions = /* @__PURE__ */ new Map();
|
|
66441
|
+
SESSION_TTL_MS = 30 * 60 * 1e3;
|
|
66442
|
+
setInterval(() => {
|
|
66443
|
+
const now = Date.now();
|
|
66444
|
+
for (const [id, s] of sessions) {
|
|
66445
|
+
if (now - s.lastActivity > SESSION_TTL_MS)
|
|
66446
|
+
sessions.delete(id);
|
|
66447
|
+
}
|
|
66448
|
+
}, 5 * 60 * 1e3);
|
|
66449
|
+
}
|
|
66450
|
+
});
|
|
66451
|
+
|
|
66452
|
+
// packages/cli/dist/api/usage-tracker.js
|
|
66453
|
+
import { mkdirSync as mkdirSync27, readFileSync as readFileSync43, writeFileSync as writeFileSync25, existsSync as existsSync54 } from "node:fs";
|
|
66454
|
+
import { join as join71 } from "node:path";
|
|
66265
66455
|
function initUsageTracker(oaDir) {
|
|
66266
|
-
const dir =
|
|
66456
|
+
const dir = join71(oaDir, "usage");
|
|
66267
66457
|
mkdirSync27(dir, { recursive: true });
|
|
66268
|
-
usageFile =
|
|
66458
|
+
usageFile = join71(dir, "token-usage.json");
|
|
66269
66459
|
try {
|
|
66270
|
-
if (
|
|
66271
|
-
store = JSON.parse(
|
|
66460
|
+
if (existsSync54(usageFile)) {
|
|
66461
|
+
store = JSON.parse(readFileSync43(usageFile, "utf-8"));
|
|
66272
66462
|
}
|
|
66273
66463
|
} catch {
|
|
66274
66464
|
store = { providers: {}, lastSaved: "" };
|
|
@@ -66336,24 +66526,24 @@ var init_usage_tracker = __esm({
|
|
|
66336
66526
|
});
|
|
66337
66527
|
|
|
66338
66528
|
// packages/cli/dist/api/profiles.js
|
|
66339
|
-
import { existsSync as
|
|
66340
|
-
import { join as
|
|
66529
|
+
import { existsSync as existsSync55, readFileSync as readFileSync44, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, readdirSync as readdirSync21, unlinkSync as unlinkSync12 } from "node:fs";
|
|
66530
|
+
import { join as join72 } from "node:path";
|
|
66341
66531
|
import { homedir as homedir18 } from "node:os";
|
|
66342
66532
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes15, scryptSync as scryptSync3, createHash as createHash5 } from "node:crypto";
|
|
66343
66533
|
function globalProfileDir() {
|
|
66344
|
-
return
|
|
66534
|
+
return join72(homedir18(), ".open-agents", "profiles");
|
|
66345
66535
|
}
|
|
66346
66536
|
function projectProfileDir(projectDir) {
|
|
66347
|
-
return
|
|
66537
|
+
return join72(projectDir || process.cwd(), ".oa", "profiles");
|
|
66348
66538
|
}
|
|
66349
66539
|
function listProfiles(projectDir) {
|
|
66350
66540
|
const result = [];
|
|
66351
66541
|
const seen = /* @__PURE__ */ new Set();
|
|
66352
66542
|
const projDir = projectProfileDir(projectDir);
|
|
66353
|
-
if (
|
|
66354
|
-
for (const f of
|
|
66543
|
+
if (existsSync55(projDir)) {
|
|
66544
|
+
for (const f of readdirSync21(projDir).filter((f2) => f2.endsWith(".json"))) {
|
|
66355
66545
|
try {
|
|
66356
|
-
const raw = JSON.parse(
|
|
66546
|
+
const raw = JSON.parse(readFileSync44(join72(projDir, f), "utf8"));
|
|
66357
66547
|
const name = f.replace(".json", "");
|
|
66358
66548
|
seen.add(name);
|
|
66359
66549
|
result.push({
|
|
@@ -66367,13 +66557,13 @@ function listProfiles(projectDir) {
|
|
|
66367
66557
|
}
|
|
66368
66558
|
}
|
|
66369
66559
|
const globDir = globalProfileDir();
|
|
66370
|
-
if (
|
|
66371
|
-
for (const f of
|
|
66560
|
+
if (existsSync55(globDir)) {
|
|
66561
|
+
for (const f of readdirSync21(globDir).filter((f2) => f2.endsWith(".json"))) {
|
|
66372
66562
|
const name = f.replace(".json", "");
|
|
66373
66563
|
if (seen.has(name))
|
|
66374
66564
|
continue;
|
|
66375
66565
|
try {
|
|
66376
|
-
const raw = JSON.parse(
|
|
66566
|
+
const raw = JSON.parse(readFileSync44(join72(globDir, f), "utf8"));
|
|
66377
66567
|
result.push({
|
|
66378
66568
|
name,
|
|
66379
66569
|
description: raw.description || "",
|
|
@@ -66388,12 +66578,12 @@ function listProfiles(projectDir) {
|
|
|
66388
66578
|
}
|
|
66389
66579
|
function loadProfile(name, password, projectDir) {
|
|
66390
66580
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66391
|
-
const projPath =
|
|
66392
|
-
const globPath =
|
|
66393
|
-
const filePath =
|
|
66581
|
+
const projPath = join72(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
66582
|
+
const globPath = join72(globalProfileDir(), `${sanitized}.json`);
|
|
66583
|
+
const filePath = existsSync55(projPath) ? projPath : existsSync55(globPath) ? globPath : null;
|
|
66394
66584
|
if (!filePath)
|
|
66395
66585
|
return null;
|
|
66396
|
-
const raw = JSON.parse(
|
|
66586
|
+
const raw = JSON.parse(readFileSync44(filePath, "utf8"));
|
|
66397
66587
|
if (raw.encrypted === true) {
|
|
66398
66588
|
if (!password)
|
|
66399
66589
|
return null;
|
|
@@ -66405,7 +66595,7 @@ function saveProfile(profile, password, scope = "global", projectDir) {
|
|
|
66405
66595
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
66406
66596
|
mkdirSync28(dir, { recursive: true });
|
|
66407
66597
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66408
|
-
const filePath =
|
|
66598
|
+
const filePath = join72(dir, `${sanitized}.json`);
|
|
66409
66599
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
66410
66600
|
if (password) {
|
|
66411
66601
|
const encrypted = encryptProfile(profile, password);
|
|
@@ -66418,8 +66608,8 @@ function saveProfile(profile, password, scope = "global", projectDir) {
|
|
|
66418
66608
|
function deleteProfile(name, scope = "global", projectDir) {
|
|
66419
66609
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66420
66610
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
66421
|
-
const filePath =
|
|
66422
|
-
if (
|
|
66611
|
+
const filePath = join72(dir, `${sanitized}.json`);
|
|
66612
|
+
if (existsSync55(filePath)) {
|
|
66423
66613
|
unlinkSync12(filePath);
|
|
66424
66614
|
return true;
|
|
66425
66615
|
}
|
|
@@ -66512,22 +66702,22 @@ import * as http from "node:http";
|
|
|
66512
66702
|
import * as https from "node:https";
|
|
66513
66703
|
import { createRequire as createRequire3 } from "node:module";
|
|
66514
66704
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
66515
|
-
import { dirname as dirname21, join as
|
|
66705
|
+
import { dirname as dirname21, join as join73, resolve as resolve31 } from "node:path";
|
|
66516
66706
|
import { spawn as spawn21 } from "node:child_process";
|
|
66517
|
-
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync27, readFileSync as
|
|
66518
|
-
import { randomBytes as randomBytes16, randomUUID as
|
|
66707
|
+
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync27, readFileSync as readFileSync45, readdirSync as readdirSync22, existsSync as existsSync56 } from "node:fs";
|
|
66708
|
+
import { randomBytes as randomBytes16, randomUUID as randomUUID5 } from "node:crypto";
|
|
66519
66709
|
function getVersion3() {
|
|
66520
66710
|
try {
|
|
66521
66711
|
const require2 = createRequire3(import.meta.url);
|
|
66522
66712
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
66523
66713
|
const candidates = [
|
|
66524
|
-
|
|
66525
|
-
|
|
66526
|
-
|
|
66714
|
+
join73(thisDir, "..", "package.json"),
|
|
66715
|
+
join73(thisDir, "..", "..", "package.json"),
|
|
66716
|
+
join73(thisDir, "..", "..", "..", "package.json")
|
|
66527
66717
|
];
|
|
66528
66718
|
for (const pkgPath of candidates) {
|
|
66529
66719
|
try {
|
|
66530
|
-
if (!
|
|
66720
|
+
if (!existsSync56(pkgPath))
|
|
66531
66721
|
continue;
|
|
66532
66722
|
const pkg = require2(pkgPath);
|
|
66533
66723
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
@@ -66828,29 +67018,29 @@ function ollamaStream(ollamaUrl, path, method, body, onData, onEnd, onError) {
|
|
|
66828
67018
|
}
|
|
66829
67019
|
function jobsDir() {
|
|
66830
67020
|
const root = resolve31(process.cwd());
|
|
66831
|
-
const dir =
|
|
67021
|
+
const dir = join73(root, ".oa", "jobs");
|
|
66832
67022
|
mkdirSync29(dir, { recursive: true });
|
|
66833
67023
|
return dir;
|
|
66834
67024
|
}
|
|
66835
67025
|
function loadJob(id) {
|
|
66836
|
-
const file =
|
|
66837
|
-
if (!
|
|
67026
|
+
const file = join73(jobsDir(), `${id}.json`);
|
|
67027
|
+
if (!existsSync56(file))
|
|
66838
67028
|
return null;
|
|
66839
67029
|
try {
|
|
66840
|
-
return JSON.parse(
|
|
67030
|
+
return JSON.parse(readFileSync45(file, "utf-8"));
|
|
66841
67031
|
} catch {
|
|
66842
67032
|
return null;
|
|
66843
67033
|
}
|
|
66844
67034
|
}
|
|
66845
67035
|
function listJobs() {
|
|
66846
67036
|
const dir = jobsDir();
|
|
66847
|
-
if (!
|
|
67037
|
+
if (!existsSync56(dir))
|
|
66848
67038
|
return [];
|
|
66849
|
-
const files =
|
|
67039
|
+
const files = readdirSync22(dir).filter((f) => f.endsWith(".json")).sort();
|
|
66850
67040
|
const jobs = [];
|
|
66851
67041
|
for (const file of files) {
|
|
66852
67042
|
try {
|
|
66853
|
-
jobs.push(JSON.parse(
|
|
67043
|
+
jobs.push(JSON.parse(readFileSync45(join73(dir, file), "utf-8")));
|
|
66854
67044
|
} catch {
|
|
66855
67045
|
}
|
|
66856
67046
|
}
|
|
@@ -67298,7 +67488,7 @@ async function handleV1Run(req, res) {
|
|
|
67298
67488
|
if (workingDir) {
|
|
67299
67489
|
cwd4 = resolve31(workingDir);
|
|
67300
67490
|
} else if (isolate) {
|
|
67301
|
-
const wsDir =
|
|
67491
|
+
const wsDir = join73(dir, "..", "workspaces", id);
|
|
67302
67492
|
mkdirSync29(wsDir, { recursive: true });
|
|
67303
67493
|
cwd4 = wsDir;
|
|
67304
67494
|
} else {
|
|
@@ -67371,7 +67561,7 @@ async function handleV1Run(req, res) {
|
|
|
67371
67561
|
});
|
|
67372
67562
|
child.unref();
|
|
67373
67563
|
job.pid = child.pid ?? 0;
|
|
67374
|
-
writeFileSync27(
|
|
67564
|
+
writeFileSync27(join73(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67375
67565
|
runningProcesses.set(id, child);
|
|
67376
67566
|
if (streamMode) {
|
|
67377
67567
|
res.writeHead(200, {
|
|
@@ -67398,7 +67588,7 @@ async function handleV1Run(req, res) {
|
|
|
67398
67588
|
job.status = code === 0 ? "completed" : "failed";
|
|
67399
67589
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67400
67590
|
try {
|
|
67401
|
-
writeFileSync27(
|
|
67591
|
+
writeFileSync27(join73(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67402
67592
|
} catch {
|
|
67403
67593
|
}
|
|
67404
67594
|
runningProcesses.delete(id);
|
|
@@ -67429,7 +67619,7 @@ async function handleV1Run(req, res) {
|
|
|
67429
67619
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67430
67620
|
}
|
|
67431
67621
|
try {
|
|
67432
|
-
writeFileSync27(
|
|
67622
|
+
writeFileSync27(join73(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67433
67623
|
} catch {
|
|
67434
67624
|
}
|
|
67435
67625
|
runningProcesses.delete(id);
|
|
@@ -67478,7 +67668,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
67478
67668
|
job.error = "Aborted via API";
|
|
67479
67669
|
const dir = jobsDir();
|
|
67480
67670
|
try {
|
|
67481
|
-
writeFileSync27(
|
|
67671
|
+
writeFileSync27(join73(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67482
67672
|
} catch {
|
|
67483
67673
|
}
|
|
67484
67674
|
runningProcesses.delete(id);
|
|
@@ -67623,7 +67813,7 @@ async function handleRequest(req, res, ollamaUrl, verbose) {
|
|
|
67623
67813
|
const urlObj = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
67624
67814
|
const pathname = urlObj.pathname;
|
|
67625
67815
|
const startMs = performance.now();
|
|
67626
|
-
const requestId = req.headers["x-request-id"] ||
|
|
67816
|
+
const requestId = req.headers["x-request-id"] || randomUUID5();
|
|
67627
67817
|
res.setHeader("X-Request-ID", requestId);
|
|
67628
67818
|
if (method === "OPTIONS") {
|
|
67629
67819
|
if (!corsHeaders(req, res))
|
|
@@ -67698,6 +67888,154 @@ async function handleRequest(req, res, ollamaUrl, verbose) {
|
|
|
67698
67888
|
return;
|
|
67699
67889
|
}
|
|
67700
67890
|
}
|
|
67891
|
+
if (pathname === "/v1/system" && method === "GET") {
|
|
67892
|
+
const os = __require("node:os");
|
|
67893
|
+
const { execSync: es } = __require("node:child_process");
|
|
67894
|
+
let gpus = [];
|
|
67895
|
+
try {
|
|
67896
|
+
const nv = es("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", { encoding: "utf8", timeout: 5e3, stdio: "pipe" });
|
|
67897
|
+
for (const line of nv.trim().split("\n")) {
|
|
67898
|
+
const [name, mem] = line.split(",").map((s) => s.trim());
|
|
67899
|
+
if (name && mem)
|
|
67900
|
+
gpus.push({ name, vram_gb: Math.round(parseInt(mem, 10) / 1024) });
|
|
67901
|
+
}
|
|
67902
|
+
} catch {
|
|
67903
|
+
}
|
|
67904
|
+
const totalVram = gpus.reduce((s, g) => s + g.vram_gb, 0);
|
|
67905
|
+
jsonResponse(res, 200, {
|
|
67906
|
+
gpu: gpus,
|
|
67907
|
+
total_vram_gb: totalVram,
|
|
67908
|
+
ram_gb: Math.round(os.totalmem() / 1024 ** 3),
|
|
67909
|
+
cpu: os.cpus()[0]?.model ?? "unknown",
|
|
67910
|
+
cores: os.cpus().length,
|
|
67911
|
+
platform: process.platform,
|
|
67912
|
+
node: process.version,
|
|
67913
|
+
// Model compatibility recommendations
|
|
67914
|
+
recommended_max_params: totalVram >= 80 ? "120B+" : totalVram >= 48 ? "70B" : totalVram >= 24 ? "27B" : totalVram >= 8 ? "9B" : "4B"
|
|
67915
|
+
});
|
|
67916
|
+
return;
|
|
67917
|
+
}
|
|
67918
|
+
if (pathname === "/v1/chat" && method === "POST") {
|
|
67919
|
+
if (!checkAuth(req, res, "run")) {
|
|
67920
|
+
status = 401;
|
|
67921
|
+
return;
|
|
67922
|
+
}
|
|
67923
|
+
const chatBody = await parseJsonBody(req);
|
|
67924
|
+
if (!chatBody?.message || typeof chatBody.message !== "string") {
|
|
67925
|
+
jsonResponse(res, 400, { error: "Missing required field: message" });
|
|
67926
|
+
return;
|
|
67927
|
+
}
|
|
67928
|
+
const sessionId = chatBody.session_id;
|
|
67929
|
+
const model = chatBody.model || loadConfig().model;
|
|
67930
|
+
const session = getSession(sessionId, model, resolve31(process.cwd()));
|
|
67931
|
+
const messages = addUserMessage(session, chatBody.message);
|
|
67932
|
+
compactSession(session);
|
|
67933
|
+
const streamMode = chatBody.stream !== false;
|
|
67934
|
+
const chatRequest = {
|
|
67935
|
+
model: session.model,
|
|
67936
|
+
messages,
|
|
67937
|
+
stream: streamMode,
|
|
67938
|
+
max_tokens: chatBody.max_tokens || 4096
|
|
67939
|
+
};
|
|
67940
|
+
const route = resolveModelEndpoint(session.model);
|
|
67941
|
+
const targetUrl = route?.endpoint?.url || loadConfig().backendUrl;
|
|
67942
|
+
if (streamMode) {
|
|
67943
|
+
res.writeHead(200, {
|
|
67944
|
+
"Content-Type": "text/event-stream",
|
|
67945
|
+
"Cache-Control": "no-cache",
|
|
67946
|
+
"Connection": "keep-alive",
|
|
67947
|
+
"X-Session-ID": session.id
|
|
67948
|
+
});
|
|
67949
|
+
let fullContent = "";
|
|
67950
|
+
try {
|
|
67951
|
+
const url = new URL("/api/chat", targetUrl);
|
|
67952
|
+
const isHttps = url.protocol === "https:";
|
|
67953
|
+
const transport = isHttps ? https : http;
|
|
67954
|
+
const reqBody = JSON.stringify({
|
|
67955
|
+
model: session.model.replace(/^local\//, ""),
|
|
67956
|
+
messages: messages.map((m) => ({ role: m.role, content: m.content })),
|
|
67957
|
+
stream: true
|
|
67958
|
+
});
|
|
67959
|
+
await new Promise((resolve36, reject) => {
|
|
67960
|
+
const proxyReq = transport.request({
|
|
67961
|
+
hostname: url.hostname,
|
|
67962
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
67963
|
+
path: url.pathname,
|
|
67964
|
+
method: "POST",
|
|
67965
|
+
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(reqBody) }
|
|
67966
|
+
}, (proxyRes) => {
|
|
67967
|
+
let buffer = "";
|
|
67968
|
+
proxyRes.on("data", (chunk) => {
|
|
67969
|
+
buffer += chunk.toString();
|
|
67970
|
+
const lines = buffer.split("\n");
|
|
67971
|
+
buffer = lines.pop() || "";
|
|
67972
|
+
for (const line of lines) {
|
|
67973
|
+
if (!line.trim())
|
|
67974
|
+
continue;
|
|
67975
|
+
try {
|
|
67976
|
+
const parsed = JSON.parse(line);
|
|
67977
|
+
if (parsed.message?.content) {
|
|
67978
|
+
fullContent += parsed.message.content;
|
|
67979
|
+
const sseChunk = {
|
|
67980
|
+
id: `chatcmpl-${session.id.slice(0, 8)}`,
|
|
67981
|
+
object: "chat.completion.chunk",
|
|
67982
|
+
choices: [{ index: 0, delta: { content: parsed.message.content }, finish_reason: null }]
|
|
67983
|
+
};
|
|
67984
|
+
res.write("data: " + JSON.stringify(sseChunk) + "\n\n");
|
|
67985
|
+
}
|
|
67986
|
+
if (parsed.done) {
|
|
67987
|
+
trackSessionTokens(session, parsed.prompt_eval_count ?? 0, parsed.eval_count ?? 0);
|
|
67988
|
+
trackTokens("local", parsed.prompt_eval_count ?? 0, parsed.eval_count ?? 0);
|
|
67989
|
+
metrics.totalTokensIn += parsed.prompt_eval_count ?? 0;
|
|
67990
|
+
metrics.totalTokensOut += parsed.eval_count ?? 0;
|
|
67991
|
+
res.write("data: [DONE]\n\n");
|
|
67992
|
+
}
|
|
67993
|
+
} catch {
|
|
67994
|
+
}
|
|
67995
|
+
}
|
|
67996
|
+
});
|
|
67997
|
+
proxyRes.on("end", resolve36);
|
|
67998
|
+
proxyRes.on("error", reject);
|
|
67999
|
+
});
|
|
68000
|
+
proxyReq.setTimeout(12e4, () => proxyReq.destroy(new Error("Chat stream timeout")));
|
|
68001
|
+
proxyReq.on("error", reject);
|
|
68002
|
+
proxyReq.write(reqBody);
|
|
68003
|
+
proxyReq.end();
|
|
68004
|
+
});
|
|
68005
|
+
} catch (e) {
|
|
68006
|
+
res.write("data: " + JSON.stringify({ error: e.message }) + "\n\n");
|
|
68007
|
+
}
|
|
68008
|
+
addAssistantMessage(session, fullContent);
|
|
68009
|
+
res.end();
|
|
68010
|
+
} else {
|
|
68011
|
+
try {
|
|
68012
|
+
const result = await ollamaRequest(targetUrl, "/api/chat", "POST", JSON.stringify({
|
|
68013
|
+
model: session.model.replace(/^local\//, ""),
|
|
68014
|
+
messages: messages.map((m) => ({ role: m.role, content: m.content })),
|
|
68015
|
+
stream: false
|
|
68016
|
+
}));
|
|
68017
|
+
const parsed = JSON.parse(result.body);
|
|
68018
|
+
const content = parsed.message?.content ?? "";
|
|
68019
|
+
addAssistantMessage(session, content);
|
|
68020
|
+
trackSessionTokens(session, parsed.prompt_eval_count ?? 0, parsed.eval_count ?? 0);
|
|
68021
|
+
trackTokens("local", parsed.prompt_eval_count ?? 0, parsed.eval_count ?? 0);
|
|
68022
|
+
jsonResponse(res, 200, {
|
|
68023
|
+
session_id: session.id,
|
|
68024
|
+
message: { role: "assistant", content },
|
|
68025
|
+
usage: { prompt_tokens: parsed.prompt_eval_count ?? 0, completion_tokens: parsed.eval_count ?? 0 }
|
|
68026
|
+
});
|
|
68027
|
+
} catch (e) {
|
|
68028
|
+
jsonResponse(res, 500, { error: "Chat failed", message: e.message });
|
|
68029
|
+
}
|
|
68030
|
+
}
|
|
68031
|
+
return;
|
|
68032
|
+
}
|
|
68033
|
+
if (pathname === "/v1/chat/sessions" && method === "GET") {
|
|
68034
|
+
if (!checkAuth(req, res, "read"))
|
|
68035
|
+
return;
|
|
68036
|
+
jsonResponse(res, 200, { sessions: listSessions() });
|
|
68037
|
+
return;
|
|
68038
|
+
}
|
|
67701
68039
|
if (pathname === "/v1/models" && method === "GET") {
|
|
67702
68040
|
await handleV1Models(res, ollamaUrl);
|
|
67703
68041
|
return;
|
|
@@ -67920,20 +68258,20 @@ function startApiServer(options = {}) {
|
|
|
67920
68258
|
const config = loadConfig();
|
|
67921
68259
|
const ollamaUrl = options.ollamaUrl ?? config.backendUrl;
|
|
67922
68260
|
const cwd4 = process.cwd();
|
|
67923
|
-
initAuditLog(
|
|
67924
|
-
initUsageTracker(
|
|
68261
|
+
initAuditLog(join73(cwd4, ".oa"));
|
|
68262
|
+
initUsageTracker(join73(cwd4, ".oa"));
|
|
67925
68263
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
67926
68264
|
if (retentionDays > 0) {
|
|
67927
68265
|
try {
|
|
67928
|
-
const jobsDir3 =
|
|
67929
|
-
if (
|
|
68266
|
+
const jobsDir3 = join73(cwd4, ".oa", "jobs");
|
|
68267
|
+
if (existsSync56(jobsDir3)) {
|
|
67930
68268
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
67931
|
-
for (const f of
|
|
68269
|
+
for (const f of readdirSync22(jobsDir3)) {
|
|
67932
68270
|
if (!f.endsWith(".json"))
|
|
67933
68271
|
continue;
|
|
67934
68272
|
try {
|
|
67935
|
-
const jobPath =
|
|
67936
|
-
const job = JSON.parse(
|
|
68273
|
+
const jobPath = join73(jobsDir3, f);
|
|
68274
|
+
const job = JSON.parse(readFileSync45(jobPath, "utf-8"));
|
|
67937
68275
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
67938
68276
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
67939
68277
|
const { unlinkSync: unlinkSync13 } = __require("node:fs");
|
|
@@ -67953,8 +68291,8 @@ function startApiServer(options = {}) {
|
|
|
67953
68291
|
if (useTls) {
|
|
67954
68292
|
try {
|
|
67955
68293
|
tlsOpts = {
|
|
67956
|
-
cert:
|
|
67957
|
-
key:
|
|
68294
|
+
cert: readFileSync45(resolve31(tlsCert)),
|
|
68295
|
+
key: readFileSync45(resolve31(tlsKey))
|
|
67958
68296
|
};
|
|
67959
68297
|
} catch (e) {
|
|
67960
68298
|
log2(`
|
|
@@ -68104,6 +68442,7 @@ var init_serve = __esm({
|
|
|
68104
68442
|
init_logger();
|
|
68105
68443
|
init_openapi();
|
|
68106
68444
|
init_auth_oidc();
|
|
68445
|
+
init_chat_session();
|
|
68107
68446
|
init_usage_tracker();
|
|
68108
68447
|
init_oa_directory();
|
|
68109
68448
|
init_render();
|
|
@@ -68127,11 +68466,11 @@ var init_serve = __esm({
|
|
|
68127
68466
|
|
|
68128
68467
|
// packages/cli/dist/tui/interactive.js
|
|
68129
68468
|
import { cwd } from "node:process";
|
|
68130
|
-
import { resolve as resolve32, join as
|
|
68469
|
+
import { resolve as resolve32, join as join74, dirname as dirname22, extname as extname11 } from "node:path";
|
|
68131
68470
|
import { createRequire as createRequire4 } from "node:module";
|
|
68132
68471
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
68133
|
-
import { readFileSync as
|
|
68134
|
-
import { existsSync as
|
|
68472
|
+
import { readFileSync as readFileSync46, writeFileSync as writeFileSync28, appendFileSync as appendFileSync5, rmSync as rmSync3, readdirSync as readdirSync23, mkdirSync as mkdirSync30 } from "node:fs";
|
|
68473
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
68135
68474
|
import { execSync as execSync35 } from "node:child_process";
|
|
68136
68475
|
import { homedir as homedir19 } from "node:os";
|
|
68137
68476
|
function formatTimeAgo(date) {
|
|
@@ -68152,12 +68491,12 @@ function getVersion4() {
|
|
|
68152
68491
|
const require2 = createRequire4(import.meta.url);
|
|
68153
68492
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
68154
68493
|
const candidates = [
|
|
68155
|
-
|
|
68156
|
-
|
|
68157
|
-
|
|
68494
|
+
join74(thisDir, "..", "package.json"),
|
|
68495
|
+
join74(thisDir, "..", "..", "package.json"),
|
|
68496
|
+
join74(thisDir, "..", "..", "..", "package.json")
|
|
68158
68497
|
];
|
|
68159
68498
|
for (const pkgPath of candidates) {
|
|
68160
|
-
if (
|
|
68499
|
+
if (existsSync57(pkgPath)) {
|
|
68161
68500
|
const pkg = require2(pkgPath);
|
|
68162
68501
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
68163
68502
|
return pkg.version ?? "0.0.0";
|
|
@@ -68396,15 +68735,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
68396
68735
|
function gatherMemorySnippets(root) {
|
|
68397
68736
|
const snippets = [];
|
|
68398
68737
|
const dirs = [
|
|
68399
|
-
|
|
68400
|
-
|
|
68738
|
+
join74(root, ".oa", "memory"),
|
|
68739
|
+
join74(root, ".open-agents", "memory")
|
|
68401
68740
|
];
|
|
68402
68741
|
for (const dir of dirs) {
|
|
68403
|
-
if (!
|
|
68742
|
+
if (!existsSync57(dir))
|
|
68404
68743
|
continue;
|
|
68405
68744
|
try {
|
|
68406
|
-
for (const f of
|
|
68407
|
-
const data = JSON.parse(
|
|
68745
|
+
for (const f of readdirSync23(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
68746
|
+
const data = JSON.parse(readFileSync46(join74(dir, f), "utf-8"));
|
|
68408
68747
|
for (const val of Object.values(data)) {
|
|
68409
68748
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
68410
68749
|
if (v.length > 10)
|
|
@@ -68561,9 +68900,9 @@ ${metabolismMemories}
|
|
|
68561
68900
|
} catch {
|
|
68562
68901
|
}
|
|
68563
68902
|
try {
|
|
68564
|
-
const archeFile =
|
|
68565
|
-
if (
|
|
68566
|
-
const variants = JSON.parse(
|
|
68903
|
+
const archeFile = join74(repoRoot, ".oa", "arche", "variants.json");
|
|
68904
|
+
if (existsSync57(archeFile)) {
|
|
68905
|
+
const variants = JSON.parse(readFileSync46(archeFile, "utf8"));
|
|
68567
68906
|
if (variants.length > 0) {
|
|
68568
68907
|
let filtered = variants;
|
|
68569
68908
|
if (taskType) {
|
|
@@ -68732,9 +69071,9 @@ RULES:
|
|
|
68732
69071
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
68733
69072
|
let identityInjection = "";
|
|
68734
69073
|
try {
|
|
68735
|
-
const ikStateFile =
|
|
68736
|
-
if (
|
|
68737
|
-
const selfState = JSON.parse(
|
|
69074
|
+
const ikStateFile = join74(repoRoot, ".oa", "identity", "self-state.json");
|
|
69075
|
+
if (existsSync57(ikStateFile)) {
|
|
69076
|
+
const selfState = JSON.parse(readFileSync46(ikStateFile, "utf8"));
|
|
68738
69077
|
const lines = [
|
|
68739
69078
|
`[Identity State v${selfState.version}]`,
|
|
68740
69079
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -69378,11 +69717,11 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
69378
69717
|
});
|
|
69379
69718
|
}
|
|
69380
69719
|
try {
|
|
69381
|
-
const ikDir =
|
|
69382
|
-
const ikFile =
|
|
69720
|
+
const ikDir = join74(repoRoot, ".oa", "identity");
|
|
69721
|
+
const ikFile = join74(ikDir, "self-state.json");
|
|
69383
69722
|
let ikState;
|
|
69384
|
-
if (
|
|
69385
|
-
ikState = JSON.parse(
|
|
69723
|
+
if (existsSync57(ikFile)) {
|
|
69724
|
+
ikState = JSON.parse(readFileSync46(ikFile, "utf8"));
|
|
69386
69725
|
} else {
|
|
69387
69726
|
mkdirSync30(ikDir, { recursive: true });
|
|
69388
69727
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
@@ -69425,9 +69764,9 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
69425
69764
|
} else {
|
|
69426
69765
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
69427
69766
|
try {
|
|
69428
|
-
const ikFile =
|
|
69429
|
-
if (
|
|
69430
|
-
const ikState = JSON.parse(
|
|
69767
|
+
const ikFile = join74(repoRoot, ".oa", "identity", "self-state.json");
|
|
69768
|
+
if (existsSync57(ikFile)) {
|
|
69769
|
+
const ikState = JSON.parse(readFileSync46(ikFile, "utf8"));
|
|
69431
69770
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
69432
69771
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
69433
69772
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
@@ -69529,10 +69868,10 @@ async function startInteractive(config, repoPath) {
|
|
|
69529
69868
|
process.stdin.pause();
|
|
69530
69869
|
}
|
|
69531
69870
|
try {
|
|
69532
|
-
const oaDir =
|
|
69533
|
-
const nexusPidFile =
|
|
69534
|
-
if (
|
|
69535
|
-
const pid = parseInt(
|
|
69871
|
+
const oaDir = join74(repoRoot, ".oa");
|
|
69872
|
+
const nexusPidFile = join74(oaDir, "nexus", "daemon.pid");
|
|
69873
|
+
if (existsSync57(nexusPidFile)) {
|
|
69874
|
+
const pid = parseInt(readFileSync46(nexusPidFile, "utf8").trim(), 10);
|
|
69536
69875
|
if (pid > 0) {
|
|
69537
69876
|
try {
|
|
69538
69877
|
process.kill(pid, 0);
|
|
@@ -69869,7 +70208,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
69869
70208
|
let p2pGateway = null;
|
|
69870
70209
|
let peerMesh = null;
|
|
69871
70210
|
let inferenceRouter = null;
|
|
69872
|
-
const secretVault = new SecretVault(
|
|
70211
|
+
const secretVault = new SecretVault(join74(repoRoot, ".oa", "vault.enc"));
|
|
69873
70212
|
let adminSessionKey = null;
|
|
69874
70213
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
69875
70214
|
const streamRenderer = new StreamRenderer();
|
|
@@ -70092,13 +70431,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70092
70431
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
70093
70432
|
return [hits, line];
|
|
70094
70433
|
}
|
|
70095
|
-
const HISTORY_DIR =
|
|
70096
|
-
const HISTORY_FILE =
|
|
70434
|
+
const HISTORY_DIR = join74(homedir19(), ".open-agents");
|
|
70435
|
+
const HISTORY_FILE = join74(HISTORY_DIR, "repl-history");
|
|
70097
70436
|
const MAX_HISTORY_LINES = 500;
|
|
70098
70437
|
let savedHistory = [];
|
|
70099
70438
|
try {
|
|
70100
|
-
if (
|
|
70101
|
-
const raw =
|
|
70439
|
+
if (existsSync57(HISTORY_FILE)) {
|
|
70440
|
+
const raw = readFileSync46(HISTORY_FILE, "utf8").trim();
|
|
70102
70441
|
if (raw)
|
|
70103
70442
|
savedHistory = raw.split("\n").reverse();
|
|
70104
70443
|
}
|
|
@@ -70204,7 +70543,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70204
70543
|
mkdirSync30(HISTORY_DIR, { recursive: true });
|
|
70205
70544
|
appendFileSync5(HISTORY_FILE, line + "\n", "utf8");
|
|
70206
70545
|
if (Math.random() < 0.02) {
|
|
70207
|
-
const all =
|
|
70546
|
+
const all = readFileSync46(HISTORY_FILE, "utf8").trim().split("\n");
|
|
70208
70547
|
if (all.length > MAX_HISTORY_LINES) {
|
|
70209
70548
|
writeFileSync28(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
70210
70549
|
}
|
|
@@ -70390,7 +70729,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70390
70729
|
} catch {
|
|
70391
70730
|
}
|
|
70392
70731
|
try {
|
|
70393
|
-
const oaDir =
|
|
70732
|
+
const oaDir = join74(repoRoot, ".oa");
|
|
70394
70733
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
70395
70734
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
70396
70735
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -70422,7 +70761,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70422
70761
|
} catch {
|
|
70423
70762
|
}
|
|
70424
70763
|
try {
|
|
70425
|
-
const oaDir =
|
|
70764
|
+
const oaDir = join74(repoRoot, ".oa");
|
|
70426
70765
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
70427
70766
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
70428
70767
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -70463,11 +70802,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70463
70802
|
}
|
|
70464
70803
|
try {
|
|
70465
70804
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
70466
|
-
const globalNamePath =
|
|
70805
|
+
const globalNamePath = join74(_hd(), ".open-agents", "agent-name");
|
|
70467
70806
|
let agName = "";
|
|
70468
70807
|
try {
|
|
70469
|
-
if (
|
|
70470
|
-
agName =
|
|
70808
|
+
if (existsSync57(globalNamePath))
|
|
70809
|
+
agName = readFileSync46(globalNamePath, "utf8").trim();
|
|
70471
70810
|
} catch {
|
|
70472
70811
|
}
|
|
70473
70812
|
if (!agName) {
|
|
@@ -71443,7 +71782,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71443
71782
|
kind,
|
|
71444
71783
|
targetUrl,
|
|
71445
71784
|
authKey,
|
|
71446
|
-
stateDir:
|
|
71785
|
+
stateDir: join74(repoRoot, ".oa"),
|
|
71447
71786
|
passthrough: passthrough ?? false,
|
|
71448
71787
|
loadbalance: loadbalance ?? false,
|
|
71449
71788
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -71489,7 +71828,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71489
71828
|
await tunnelGateway.stop();
|
|
71490
71829
|
tunnelGateway = null;
|
|
71491
71830
|
}
|
|
71492
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
71831
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join74(repoRoot, ".oa") });
|
|
71493
71832
|
newTunnel.on("stats", (stats) => {
|
|
71494
71833
|
statusBar.setExposeStatus({
|
|
71495
71834
|
status: stats.status,
|
|
@@ -71578,9 +71917,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71578
71917
|
if (!result.success)
|
|
71579
71918
|
throw new Error(result.error || "Connect failed");
|
|
71580
71919
|
try {
|
|
71581
|
-
const nexusPidFile =
|
|
71582
|
-
if (
|
|
71583
|
-
const pid = parseInt(
|
|
71920
|
+
const nexusPidFile = join74(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
71921
|
+
if (existsSync57(nexusPidFile)) {
|
|
71922
|
+
const pid = parseInt(readFileSync46(nexusPidFile, "utf8").trim(), 10);
|
|
71584
71923
|
if (pid > 0) {
|
|
71585
71924
|
registry.register({
|
|
71586
71925
|
name: "Nexus",
|
|
@@ -71776,10 +72115,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71776
72115
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
71777
72116
|
}
|
|
71778
72117
|
try {
|
|
71779
|
-
const nexusDir =
|
|
71780
|
-
const pidFile =
|
|
71781
|
-
if (
|
|
71782
|
-
const pid = parseInt(
|
|
72118
|
+
const nexusDir = join74(repoRoot, OA_DIR, "nexus");
|
|
72119
|
+
const pidFile = join74(nexusDir, "daemon.pid");
|
|
72120
|
+
if (existsSync57(pidFile)) {
|
|
72121
|
+
const pid = parseInt(readFileSync46(pidFile, "utf8").trim(), 10);
|
|
71783
72122
|
if (pid > 0) {
|
|
71784
72123
|
try {
|
|
71785
72124
|
if (process.platform === "win32") {
|
|
@@ -71801,13 +72140,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71801
72140
|
} catch {
|
|
71802
72141
|
}
|
|
71803
72142
|
try {
|
|
71804
|
-
const voiceDir2 =
|
|
72143
|
+
const voiceDir2 = join74(homedir19(), ".open-agents", "voice");
|
|
71805
72144
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
71806
72145
|
for (const pf of voicePidFiles) {
|
|
71807
|
-
const pidPath =
|
|
71808
|
-
if (
|
|
72146
|
+
const pidPath = join74(voiceDir2, pf);
|
|
72147
|
+
if (existsSync57(pidPath)) {
|
|
71809
72148
|
try {
|
|
71810
|
-
const pid = parseInt(
|
|
72149
|
+
const pid = parseInt(readFileSync46(pidPath, "utf8").trim(), 10);
|
|
71811
72150
|
if (pid > 0) {
|
|
71812
72151
|
if (process.platform === "win32") {
|
|
71813
72152
|
try {
|
|
@@ -71831,8 +72170,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71831
72170
|
execSync35(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
71832
72171
|
} catch {
|
|
71833
72172
|
}
|
|
71834
|
-
const oaPath =
|
|
71835
|
-
if (
|
|
72173
|
+
const oaPath = join74(repoRoot, OA_DIR);
|
|
72174
|
+
if (existsSync57(oaPath)) {
|
|
71836
72175
|
let deleted = false;
|
|
71837
72176
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
71838
72177
|
try {
|
|
@@ -71915,19 +72254,19 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71915
72254
|
try {
|
|
71916
72255
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
71917
72256
|
if (isPersonaPlexRunning2()) {
|
|
71918
|
-
const ppPidFile =
|
|
71919
|
-
const ppPortFile =
|
|
71920
|
-
if (
|
|
71921
|
-
const ppPid = parseInt(
|
|
71922
|
-
const ppPort =
|
|
72257
|
+
const ppPidFile = join74(homedir19(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
72258
|
+
const ppPortFile = join74(homedir19(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
72259
|
+
if (existsSync57(ppPidFile)) {
|
|
72260
|
+
const ppPid = parseInt(readFileSync46(ppPidFile, "utf8").trim(), 10);
|
|
72261
|
+
const ppPort = existsSync57(ppPortFile) ? parseInt(readFileSync46(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
71923
72262
|
if (ppPid > 0 && !registry.daemons.has("PersonaPlex")) {
|
|
71924
72263
|
registry.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
71925
72264
|
}
|
|
71926
72265
|
}
|
|
71927
72266
|
}
|
|
71928
|
-
const nexusPidFile =
|
|
71929
|
-
if (
|
|
71930
|
-
const nPid = parseInt(
|
|
72267
|
+
const nexusPidFile = join74(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
72268
|
+
if (existsSync57(nexusPidFile)) {
|
|
72269
|
+
const nPid = parseInt(readFileSync46(nexusPidFile, "utf8").trim(), 10);
|
|
71931
72270
|
if (nPid > 0 && !registry.daemons.has("Nexus")) {
|
|
71932
72271
|
try {
|
|
71933
72272
|
process.kill(nPid, 0);
|
|
@@ -72269,8 +72608,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
72269
72608
|
}
|
|
72270
72609
|
}
|
|
72271
72610
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
72272
|
-
const isImage = isImagePath(cleanPath) &&
|
|
72273
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
72611
|
+
const isImage = isImagePath(cleanPath) && existsSync57(resolve32(repoRoot, cleanPath));
|
|
72612
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync57(resolve32(repoRoot, cleanPath));
|
|
72274
72613
|
if (activeTask) {
|
|
72275
72614
|
if (activeTask.runner.isPaused) {
|
|
72276
72615
|
activeTask.runner.resume();
|
|
@@ -72279,7 +72618,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
72279
72618
|
if (isImage) {
|
|
72280
72619
|
try {
|
|
72281
72620
|
const imgPath = resolve32(repoRoot, cleanPath);
|
|
72282
|
-
const imgBuffer =
|
|
72621
|
+
const imgBuffer = readFileSync46(imgPath);
|
|
72283
72622
|
const base64 = imgBuffer.toString("base64");
|
|
72284
72623
|
const ext = extname11(cleanPath).toLowerCase();
|
|
72285
72624
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -72494,7 +72833,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
72494
72833
|
|
|
72495
72834
|
NEW TASK: ${fullInput}`;
|
|
72496
72835
|
restoredSessionContext = null;
|
|
72497
|
-
} else if (
|
|
72836
|
+
} else if (existsSync57(join74(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
72498
72837
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
72499
72838
|
|
|
72500
72839
|
${fullInput}`;
|
|
@@ -72811,11 +73150,11 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72811
73150
|
const handle = startTask(task, config, repoRoot);
|
|
72812
73151
|
await handle.promise;
|
|
72813
73152
|
try {
|
|
72814
|
-
const ikDir =
|
|
72815
|
-
const ikFile =
|
|
73153
|
+
const ikDir = join74(repoRoot, ".oa", "identity");
|
|
73154
|
+
const ikFile = join74(ikDir, "self-state.json");
|
|
72816
73155
|
let ikState;
|
|
72817
|
-
if (
|
|
72818
|
-
ikState = JSON.parse(
|
|
73156
|
+
if (existsSync57(ikFile)) {
|
|
73157
|
+
ikState = JSON.parse(readFileSync46(ikFile, "utf8"));
|
|
72819
73158
|
} else {
|
|
72820
73159
|
mkdirSync30(ikDir, { recursive: true });
|
|
72821
73160
|
ikState = {
|
|
@@ -72848,12 +73187,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72848
73187
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
72849
73188
|
} catch {
|
|
72850
73189
|
try {
|
|
72851
|
-
const archeDir =
|
|
72852
|
-
const archeFile =
|
|
73190
|
+
const archeDir = join74(repoRoot, ".oa", "arche");
|
|
73191
|
+
const archeFile = join74(archeDir, "variants.json");
|
|
72853
73192
|
let variants = [];
|
|
72854
73193
|
try {
|
|
72855
|
-
if (
|
|
72856
|
-
variants = JSON.parse(
|
|
73194
|
+
if (existsSync57(archeFile))
|
|
73195
|
+
variants = JSON.parse(readFileSync46(archeFile, "utf8"));
|
|
72857
73196
|
} catch {
|
|
72858
73197
|
}
|
|
72859
73198
|
variants.push({
|
|
@@ -72874,9 +73213,9 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72874
73213
|
}
|
|
72875
73214
|
}
|
|
72876
73215
|
try {
|
|
72877
|
-
const metaFile =
|
|
72878
|
-
if (
|
|
72879
|
-
const store2 = JSON.parse(
|
|
73216
|
+
const metaFile = join74(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
73217
|
+
if (existsSync57(metaFile)) {
|
|
73218
|
+
const store2 = JSON.parse(readFileSync46(metaFile, "utf8"));
|
|
72880
73219
|
const surfaced = store2.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);
|
|
72881
73220
|
let updated = false;
|
|
72882
73221
|
for (const item of surfaced) {
|
|
@@ -72940,9 +73279,9 @@ Rules:
|
|
|
72940
73279
|
try {
|
|
72941
73280
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
72942
73281
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
72943
|
-
const dbDir =
|
|
73282
|
+
const dbDir = join74(repoRoot, ".oa", "memory");
|
|
72944
73283
|
mkdirSync30(dbDir, { recursive: true });
|
|
72945
|
-
const db = initDb2(
|
|
73284
|
+
const db = initDb2(join74(dbDir, "structured.db"));
|
|
72946
73285
|
const memStore = new ProceduralMemoryStore2(db);
|
|
72947
73286
|
memStore.createWithEmbedding({
|
|
72948
73287
|
content: content.slice(0, 600),
|
|
@@ -72957,12 +73296,12 @@ Rules:
|
|
|
72957
73296
|
db.close();
|
|
72958
73297
|
} catch {
|
|
72959
73298
|
}
|
|
72960
|
-
const metaDir =
|
|
72961
|
-
const storeFile =
|
|
73299
|
+
const metaDir = join74(repoRoot, ".oa", "memory", "metabolism");
|
|
73300
|
+
const storeFile = join74(metaDir, "store.json");
|
|
72962
73301
|
let store2 = [];
|
|
72963
73302
|
try {
|
|
72964
|
-
if (
|
|
72965
|
-
store2 = JSON.parse(
|
|
73303
|
+
if (existsSync57(storeFile))
|
|
73304
|
+
store2 = JSON.parse(readFileSync46(storeFile, "utf8"));
|
|
72966
73305
|
} catch {
|
|
72967
73306
|
}
|
|
72968
73307
|
store2.push({
|
|
@@ -72985,19 +73324,19 @@ Rules:
|
|
|
72985
73324
|
} catch {
|
|
72986
73325
|
}
|
|
72987
73326
|
try {
|
|
72988
|
-
const cohereSettingsFile =
|
|
73327
|
+
const cohereSettingsFile = join74(repoRoot, ".oa", "settings.json");
|
|
72989
73328
|
let cohereActive = false;
|
|
72990
73329
|
try {
|
|
72991
|
-
if (
|
|
72992
|
-
const settings = JSON.parse(
|
|
73330
|
+
if (existsSync57(cohereSettingsFile)) {
|
|
73331
|
+
const settings = JSON.parse(readFileSync46(cohereSettingsFile, "utf8"));
|
|
72993
73332
|
cohereActive = settings.cohere === true;
|
|
72994
73333
|
}
|
|
72995
73334
|
} catch {
|
|
72996
73335
|
}
|
|
72997
73336
|
if (cohereActive) {
|
|
72998
|
-
const metaFile =
|
|
72999
|
-
if (
|
|
73000
|
-
const store2 = JSON.parse(
|
|
73337
|
+
const metaFile = join74(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
73338
|
+
if (existsSync57(metaFile)) {
|
|
73339
|
+
const store2 = JSON.parse(readFileSync46(metaFile, "utf8"));
|
|
73001
73340
|
const latest = store2.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
73002
73341
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
73003
73342
|
try {
|
|
@@ -73022,18 +73361,18 @@ Rules:
|
|
|
73022
73361
|
}
|
|
73023
73362
|
} catch (err) {
|
|
73024
73363
|
try {
|
|
73025
|
-
const ikFile =
|
|
73026
|
-
if (
|
|
73027
|
-
const ikState = JSON.parse(
|
|
73364
|
+
const ikFile = join74(repoRoot, ".oa", "identity", "self-state.json");
|
|
73365
|
+
if (existsSync57(ikFile)) {
|
|
73366
|
+
const ikState = JSON.parse(readFileSync46(ikFile, "utf8"));
|
|
73028
73367
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
73029
73368
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
73030
73369
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
73031
73370
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
73032
73371
|
writeFileSync28(ikFile, JSON.stringify(ikState, null, 2));
|
|
73033
73372
|
}
|
|
73034
|
-
const metaFile =
|
|
73035
|
-
if (
|
|
73036
|
-
const store2 = JSON.parse(
|
|
73373
|
+
const metaFile = join74(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
73374
|
+
if (existsSync57(metaFile)) {
|
|
73375
|
+
const store2 = JSON.parse(readFileSync46(metaFile, "utf8"));
|
|
73037
73376
|
const surfaced = store2.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);
|
|
73038
73377
|
for (const item of surfaced) {
|
|
73039
73378
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -73044,12 +73383,12 @@ Rules:
|
|
|
73044
73383
|
writeFileSync28(metaFile, JSON.stringify(store2, null, 2));
|
|
73045
73384
|
}
|
|
73046
73385
|
try {
|
|
73047
|
-
const archeDir =
|
|
73048
|
-
const archeFile =
|
|
73386
|
+
const archeDir = join74(repoRoot, ".oa", "arche");
|
|
73387
|
+
const archeFile = join74(archeDir, "variants.json");
|
|
73049
73388
|
let variants = [];
|
|
73050
73389
|
try {
|
|
73051
|
-
if (
|
|
73052
|
-
variants = JSON.parse(
|
|
73390
|
+
if (existsSync57(archeFile))
|
|
73391
|
+
variants = JSON.parse(readFileSync46(archeFile, "utf8"));
|
|
73053
73392
|
} catch {
|
|
73054
73393
|
}
|
|
73055
73394
|
variants.push({
|
|
@@ -73135,12 +73474,12 @@ __export(run_exports, {
|
|
|
73135
73474
|
});
|
|
73136
73475
|
import { resolve as resolve33 } from "node:path";
|
|
73137
73476
|
import { spawn as spawn22 } from "node:child_process";
|
|
73138
|
-
import { mkdirSync as mkdirSync31, writeFileSync as writeFileSync29, readFileSync as
|
|
73477
|
+
import { mkdirSync as mkdirSync31, writeFileSync as writeFileSync29, readFileSync as readFileSync47, readdirSync as readdirSync24, existsSync as existsSync58 } from "node:fs";
|
|
73139
73478
|
import { randomBytes as randomBytes17 } from "node:crypto";
|
|
73140
|
-
import { join as
|
|
73479
|
+
import { join as join75 } from "node:path";
|
|
73141
73480
|
function jobsDir2(repoPath) {
|
|
73142
73481
|
const root = resolve33(repoPath ?? process.cwd());
|
|
73143
|
-
const dir =
|
|
73482
|
+
const dir = join75(root, ".oa", "jobs");
|
|
73144
73483
|
mkdirSync31(dir, { recursive: true });
|
|
73145
73484
|
return dir;
|
|
73146
73485
|
}
|
|
@@ -73226,7 +73565,7 @@ async function runBackground(task, config, opts) {
|
|
|
73226
73565
|
});
|
|
73227
73566
|
child.unref();
|
|
73228
73567
|
job.pid = child.pid ?? 0;
|
|
73229
|
-
writeFileSync29(
|
|
73568
|
+
writeFileSync29(join75(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
73230
73569
|
let output = "";
|
|
73231
73570
|
child.stdout?.on("data", (chunk) => {
|
|
73232
73571
|
output += chunk.toString();
|
|
@@ -73242,7 +73581,7 @@ async function runBackground(task, config, opts) {
|
|
|
73242
73581
|
job.summary = result.summary;
|
|
73243
73582
|
job.durationMs = result.durationMs;
|
|
73244
73583
|
job.error = result.error;
|
|
73245
|
-
writeFileSync29(
|
|
73584
|
+
writeFileSync29(join75(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
73246
73585
|
} catch {
|
|
73247
73586
|
}
|
|
73248
73587
|
});
|
|
@@ -73258,13 +73597,13 @@ async function runBackground(task, config, opts) {
|
|
|
73258
73597
|
}
|
|
73259
73598
|
function statusCommand(jobId, repoPath) {
|
|
73260
73599
|
const dir = jobsDir2(repoPath);
|
|
73261
|
-
const file =
|
|
73262
|
-
if (!
|
|
73600
|
+
const file = join75(dir, `${jobId}.json`);
|
|
73601
|
+
if (!existsSync58(file)) {
|
|
73263
73602
|
console.error(`Job not found: ${jobId}`);
|
|
73264
73603
|
console.log(`Available jobs: oa jobs`);
|
|
73265
73604
|
process.exit(1);
|
|
73266
73605
|
}
|
|
73267
|
-
const job = JSON.parse(
|
|
73606
|
+
const job = JSON.parse(readFileSync47(file, "utf-8"));
|
|
73268
73607
|
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`;
|
|
73269
73608
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
73270
73609
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -73279,7 +73618,7 @@ function statusCommand(jobId, repoPath) {
|
|
|
73279
73618
|
}
|
|
73280
73619
|
function jobsCommand(repoPath) {
|
|
73281
73620
|
const dir = jobsDir2(repoPath);
|
|
73282
|
-
const files =
|
|
73621
|
+
const files = readdirSync24(dir).filter((f) => f.endsWith(".json")).sort();
|
|
73283
73622
|
if (files.length === 0) {
|
|
73284
73623
|
console.log("No jobs found.");
|
|
73285
73624
|
return;
|
|
@@ -73287,7 +73626,7 @@ function jobsCommand(repoPath) {
|
|
|
73287
73626
|
console.log("Jobs:");
|
|
73288
73627
|
for (const file of files) {
|
|
73289
73628
|
try {
|
|
73290
|
-
const job = JSON.parse(
|
|
73629
|
+
const job = JSON.parse(readFileSync47(join75(dir, file), "utf-8"));
|
|
73291
73630
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
73292
73631
|
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`;
|
|
73293
73632
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -73307,7 +73646,7 @@ import { glob } from "glob";
|
|
|
73307
73646
|
import ignore from "ignore";
|
|
73308
73647
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
73309
73648
|
import { createHash as createHash6 } from "node:crypto";
|
|
73310
|
-
import { join as
|
|
73649
|
+
import { join as join76, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
73311
73650
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
73312
73651
|
var init_codebase_indexer = __esm({
|
|
73313
73652
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -73351,7 +73690,7 @@ var init_codebase_indexer = __esm({
|
|
|
73351
73690
|
const ig = ignore.default();
|
|
73352
73691
|
if (this.config.respectGitignore) {
|
|
73353
73692
|
try {
|
|
73354
|
-
const gitignoreContent = await readFile23(
|
|
73693
|
+
const gitignoreContent = await readFile23(join76(this.config.rootDir, ".gitignore"), "utf-8");
|
|
73355
73694
|
ig.add(gitignoreContent);
|
|
73356
73695
|
} catch {
|
|
73357
73696
|
}
|
|
@@ -73366,7 +73705,7 @@ var init_codebase_indexer = __esm({
|
|
|
73366
73705
|
for (const relativePath of files) {
|
|
73367
73706
|
if (ig.ignores(relativePath))
|
|
73368
73707
|
continue;
|
|
73369
|
-
const fullPath =
|
|
73708
|
+
const fullPath = join76(this.config.rootDir, relativePath);
|
|
73370
73709
|
try {
|
|
73371
73710
|
const fileStat = await stat4(fullPath);
|
|
73372
73711
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -73412,7 +73751,7 @@ var init_codebase_indexer = __esm({
|
|
|
73412
73751
|
if (!child) {
|
|
73413
73752
|
child = {
|
|
73414
73753
|
name: part,
|
|
73415
|
-
path:
|
|
73754
|
+
path: join76(current.path, part),
|
|
73416
73755
|
type: "directory",
|
|
73417
73756
|
children: []
|
|
73418
73757
|
};
|
|
@@ -73495,13 +73834,13 @@ __export(index_repo_exports, {
|
|
|
73495
73834
|
indexRepoCommand: () => indexRepoCommand
|
|
73496
73835
|
});
|
|
73497
73836
|
import { resolve as resolve34 } from "node:path";
|
|
73498
|
-
import { existsSync as
|
|
73837
|
+
import { existsSync as existsSync59, statSync as statSync17 } from "node:fs";
|
|
73499
73838
|
import { cwd as cwd2 } from "node:process";
|
|
73500
73839
|
async function indexRepoCommand(opts, _config) {
|
|
73501
73840
|
const repoRoot = resolve34(opts.repoPath ?? cwd2());
|
|
73502
73841
|
printHeader("Index Repository");
|
|
73503
73842
|
printInfo(`Indexing: ${repoRoot}`);
|
|
73504
|
-
if (!
|
|
73843
|
+
if (!existsSync59(repoRoot)) {
|
|
73505
73844
|
printError(`Path does not exist: ${repoRoot}`);
|
|
73506
73845
|
process.exit(1);
|
|
73507
73846
|
}
|
|
@@ -73753,7 +74092,7 @@ var config_exports2 = {};
|
|
|
73753
74092
|
__export(config_exports2, {
|
|
73754
74093
|
configCommand: () => configCommand
|
|
73755
74094
|
});
|
|
73756
|
-
import { join as
|
|
74095
|
+
import { join as join77, resolve as resolve35 } from "node:path";
|
|
73757
74096
|
import { homedir as homedir20 } from "node:os";
|
|
73758
74097
|
import { cwd as cwd3 } from "node:process";
|
|
73759
74098
|
function redactIfSensitive(key, value) {
|
|
@@ -73836,7 +74175,7 @@ function handleShow(opts, config) {
|
|
|
73836
74175
|
}
|
|
73837
74176
|
}
|
|
73838
74177
|
printSection("Config File");
|
|
73839
|
-
printInfo(`~/.open-agents/config.json (${
|
|
74178
|
+
printInfo(`~/.open-agents/config.json (${join77(homedir20(), ".open-agents", "config.json")})`);
|
|
73840
74179
|
printSection("Priority Chain");
|
|
73841
74180
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
73842
74181
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -73875,7 +74214,7 @@ function handleSet(opts, _config) {
|
|
|
73875
74214
|
const coerced = coerceForSettings(key, value);
|
|
73876
74215
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
73877
74216
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
73878
|
-
printInfo(`Saved to ${
|
|
74217
|
+
printInfo(`Saved to ${join77(repoRoot, ".oa", "settings.json")}`);
|
|
73879
74218
|
printInfo("This override applies only when running in this workspace.");
|
|
73880
74219
|
} catch (err) {
|
|
73881
74220
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -74019,7 +74358,7 @@ __export(eval_exports, {
|
|
|
74019
74358
|
});
|
|
74020
74359
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
74021
74360
|
import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync30 } from "node:fs";
|
|
74022
|
-
import { join as
|
|
74361
|
+
import { join as join78 } from "node:path";
|
|
74023
74362
|
async function evalCommand(opts, config) {
|
|
74024
74363
|
const suiteName = opts.suite ?? "basic";
|
|
74025
74364
|
const suite = SUITES[suiteName];
|
|
@@ -74144,9 +74483,9 @@ async function evalCommand(opts, config) {
|
|
|
74144
74483
|
process.exit(failed > 0 ? 1 : 0);
|
|
74145
74484
|
}
|
|
74146
74485
|
function createTempEvalRepo() {
|
|
74147
|
-
const dir =
|
|
74486
|
+
const dir = join78(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
74148
74487
|
mkdirSync32(dir, { recursive: true });
|
|
74149
|
-
writeFileSync30(
|
|
74488
|
+
writeFileSync30(join78(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
74150
74489
|
return dir;
|
|
74151
74490
|
}
|
|
74152
74491
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -74206,7 +74545,7 @@ init_updater();
|
|
|
74206
74545
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
74207
74546
|
import { createRequire as createRequire5 } from "node:module";
|
|
74208
74547
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
74209
|
-
import { dirname as dirname23, join as
|
|
74548
|
+
import { dirname as dirname23, join as join79 } from "node:path";
|
|
74210
74549
|
|
|
74211
74550
|
// packages/cli/dist/cli.js
|
|
74212
74551
|
import { createInterface } from "node:readline";
|
|
@@ -74313,7 +74652,7 @@ init_output();
|
|
|
74313
74652
|
function getVersion5() {
|
|
74314
74653
|
try {
|
|
74315
74654
|
const require2 = createRequire5(import.meta.url);
|
|
74316
|
-
const pkgPath =
|
|
74655
|
+
const pkgPath = join79(dirname23(fileURLToPath15(import.meta.url)), "..", "package.json");
|
|
74317
74656
|
const pkg = require2(pkgPath);
|
|
74318
74657
|
return pkg.version;
|
|
74319
74658
|
} catch {
|
|
@@ -74589,11 +74928,11 @@ function crashLog(label, err) {
|
|
|
74589
74928
|
`;
|
|
74590
74929
|
try {
|
|
74591
74930
|
const { appendFileSync: appendFileSync6, mkdirSync: mkdirSync33 } = __require("node:fs");
|
|
74592
|
-
const { join:
|
|
74931
|
+
const { join: join80 } = __require("node:path");
|
|
74593
74932
|
const { homedir: homedir21 } = __require("node:os");
|
|
74594
|
-
const logDir =
|
|
74933
|
+
const logDir = join80(homedir21(), ".open-agents");
|
|
74595
74934
|
mkdirSync33(logDir, { recursive: true });
|
|
74596
|
-
appendFileSync6(
|
|
74935
|
+
appendFileSync6(join80(logDir, "crash.log"), logLine);
|
|
74597
74936
|
} catch {
|
|
74598
74937
|
}
|
|
74599
74938
|
try {
|