open-agents-ai 0.185.76 → 0.185.78
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 +683 -402
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13782,9 +13782,9 @@ print("${sentinel}")
|
|
|
13782
13782
|
if (!this.proc || this.proc.killed) {
|
|
13783
13783
|
return { success: false, path: "" };
|
|
13784
13784
|
}
|
|
13785
|
-
const { mkdirSync:
|
|
13785
|
+
const { mkdirSync: mkdirSync33, writeFileSync: writeFileSync31 } = await import("node:fs");
|
|
13786
13786
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13787
|
-
|
|
13787
|
+
mkdirSync33(sessionDir, { recursive: true });
|
|
13788
13788
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13789
13789
|
try {
|
|
13790
13790
|
const inspectCode = `
|
|
@@ -13808,7 +13808,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13808
13808
|
trajectoryCount: this.trajectory.length,
|
|
13809
13809
|
subCallCount: this.subCallCount
|
|
13810
13810
|
};
|
|
13811
|
-
|
|
13811
|
+
writeFileSync31(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13812
13812
|
return { success: true, path: sessionPath };
|
|
13813
13813
|
}
|
|
13814
13814
|
} catch {
|
|
@@ -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: readFileSync47, existsSync: existsSync59 } = await import("node:fs");
|
|
13824
13824
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13825
|
-
if (!
|
|
13825
|
+
if (!existsSync59(sessionPath))
|
|
13826
13826
|
return null;
|
|
13827
|
-
return JSON.parse(
|
|
13827
|
+
return JSON.parse(readFileSync47(sessionPath, "utf8"));
|
|
13828
13828
|
} catch {
|
|
13829
13829
|
return null;
|
|
13830
13830
|
}
|
|
@@ -13971,9 +13971,9 @@ var init_memory_metabolism = __esm({
|
|
|
13971
13971
|
};
|
|
13972
13972
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
13973
13973
|
await mkdir6(metaDir, { recursive: true });
|
|
13974
|
-
const
|
|
13975
|
-
|
|
13976
|
-
await this.saveStore(metaDir,
|
|
13974
|
+
const store2 = await this.loadStore(metaDir);
|
|
13975
|
+
store2.push(item);
|
|
13976
|
+
await this.saveStore(metaDir, store2);
|
|
13977
13977
|
if (admitted && scope !== "private" && this.deltaPublisher) {
|
|
13978
13978
|
try {
|
|
13979
13979
|
this.deltaPublisher({
|
|
@@ -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: readdirSync24, readFileSync:
|
|
14004
|
+
const { readdirSync: readdirSync24, readFileSync: readFileSync47 } = await import("node:fs");
|
|
14005
14005
|
const files = readdirSync24(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
14006
14006
|
for (const file of files) {
|
|
14007
|
-
const lines =
|
|
14007
|
+
const lines = readFileSync47(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);
|
|
@@ -14032,9 +14032,9 @@ var init_memory_metabolism = __esm({
|
|
|
14032
14032
|
if (lessons.length > 0) {
|
|
14033
14033
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14034
14034
|
await mkdir6(metaDir, { recursive: true });
|
|
14035
|
-
const
|
|
14035
|
+
const store2 = await this.loadStore(metaDir);
|
|
14036
14036
|
for (const lesson of lessons.slice(0, 10)) {
|
|
14037
|
-
|
|
14037
|
+
store2.push({
|
|
14038
14038
|
id: `lesson-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
|
|
14039
14039
|
type: lesson.type === "recovery" ? "procedural" : "procedural",
|
|
14040
14040
|
content: `${lesson.description}
|
|
@@ -14047,7 +14047,7 @@ Context: ${lesson.context}`,
|
|
|
14047
14047
|
accessCount: 0
|
|
14048
14048
|
});
|
|
14049
14049
|
}
|
|
14050
|
-
await this.saveStore(metaDir,
|
|
14050
|
+
await this.saveStore(metaDir, store2);
|
|
14051
14051
|
}
|
|
14052
14052
|
return {
|
|
14053
14053
|
success: true,
|
|
@@ -14060,8 +14060,8 @@ Context: ${lesson.context}`,
|
|
|
14060
14060
|
async listMemories(args, start) {
|
|
14061
14061
|
const filterType = args.memory_type;
|
|
14062
14062
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14063
|
-
const
|
|
14064
|
-
const filtered = filterType ?
|
|
14063
|
+
const store2 = await this.loadStore(metaDir);
|
|
14064
|
+
const filtered = filterType ? store2.filter((m) => m.type === filterType) : store2;
|
|
14065
14065
|
if (filtered.length === 0) {
|
|
14066
14066
|
return { success: true, output: "No memories stored yet.", durationMs: performance.now() - start };
|
|
14067
14067
|
}
|
|
@@ -14082,15 +14082,15 @@ ${lines.join("\n")}`,
|
|
|
14082
14082
|
return { success: false, output: "id and memory_type required", durationMs: performance.now() - start };
|
|
14083
14083
|
}
|
|
14084
14084
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14085
|
-
const
|
|
14086
|
-
const item =
|
|
14085
|
+
const store2 = await this.loadStore(metaDir);
|
|
14086
|
+
const item = store2.find((m) => m.id === id);
|
|
14087
14087
|
if (!item) {
|
|
14088
14088
|
return { success: false, output: `Memory ${id} not found`, durationMs: performance.now() - start };
|
|
14089
14089
|
}
|
|
14090
14090
|
const oldType = item.type;
|
|
14091
14091
|
item.type = newType;
|
|
14092
14092
|
item.decision = { action: "promote", reason: `Promoted from ${oldType} to ${newType}` };
|
|
14093
|
-
await this.saveStore(metaDir,
|
|
14093
|
+
await this.saveStore(metaDir, store2);
|
|
14094
14094
|
return {
|
|
14095
14095
|
success: true,
|
|
14096
14096
|
output: `Promoted ${id}: ${oldType} \u2192 ${newType}`,
|
|
@@ -14104,13 +14104,13 @@ ${lines.join("\n")}`,
|
|
|
14104
14104
|
return { success: false, output: "id required", durationMs: performance.now() - start };
|
|
14105
14105
|
}
|
|
14106
14106
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14107
|
-
const
|
|
14108
|
-
const idx =
|
|
14107
|
+
const store2 = await this.loadStore(metaDir);
|
|
14108
|
+
const idx = store2.findIndex((m) => m.id === id);
|
|
14109
14109
|
if (idx === -1) {
|
|
14110
14110
|
return { success: false, output: `Memory ${id} not found`, durationMs: performance.now() - start };
|
|
14111
14111
|
}
|
|
14112
|
-
const removed =
|
|
14113
|
-
await this.saveStore(metaDir,
|
|
14112
|
+
const removed = store2.splice(idx, 1)[0];
|
|
14113
|
+
await this.saveStore(metaDir, store2);
|
|
14114
14114
|
return {
|
|
14115
14115
|
success: true,
|
|
14116
14116
|
output: `Forgotten: [${removed.id}] ${removed.content.slice(0, 60)}`,
|
|
@@ -14125,15 +14125,15 @@ ${lines.join("\n")}`,
|
|
|
14125
14125
|
*/
|
|
14126
14126
|
async repairMemories(start) {
|
|
14127
14127
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14128
|
-
const
|
|
14129
|
-
if (
|
|
14128
|
+
const store2 = await this.loadStore(metaDir);
|
|
14129
|
+
if (store2.length === 0) {
|
|
14130
14130
|
return { success: true, output: "No memories to repair.", durationMs: performance.now() - start };
|
|
14131
14131
|
}
|
|
14132
14132
|
let repaired = 0;
|
|
14133
14133
|
let quarantined = 0;
|
|
14134
14134
|
let expired = 0;
|
|
14135
14135
|
const issues = [];
|
|
14136
|
-
for (const item of
|
|
14136
|
+
for (const item of store2) {
|
|
14137
14137
|
if (item.type === "working") {
|
|
14138
14138
|
const ageMs = Date.now() - new Date(item.createdAt).getTime();
|
|
14139
14139
|
if (ageMs > 24 * 60 * 60 * 1e3) {
|
|
@@ -14142,7 +14142,7 @@ ${lines.join("\n")}`,
|
|
|
14142
14142
|
issues.push(`[${item.id}] Working memory expired \u2014 marked for cleanup`);
|
|
14143
14143
|
}
|
|
14144
14144
|
}
|
|
14145
|
-
const duplicates =
|
|
14145
|
+
const duplicates = store2.filter((m) => m.id !== item.id && m.content === item.content);
|
|
14146
14146
|
if (duplicates.length > 0) {
|
|
14147
14147
|
for (const dup of duplicates) {
|
|
14148
14148
|
const dupScore = (dup.scores.novelty + dup.scores.utility + dup.scores.confidence + dup.scores.identityRelevance) / 4;
|
|
@@ -14156,7 +14156,7 @@ ${lines.join("\n")}`,
|
|
|
14156
14156
|
}
|
|
14157
14157
|
}
|
|
14158
14158
|
if (item.type === "procedural" || item.type === "semantic") {
|
|
14159
|
-
const conflicts =
|
|
14159
|
+
const conflicts = store2.filter((m) => m.id !== item.id && m.type === item.type && m.decision.action !== "quarantine" && this.detectContradiction(item.content, m.content));
|
|
14160
14160
|
if (conflicts.length > 0) {
|
|
14161
14161
|
for (const conflict of conflicts) {
|
|
14162
14162
|
if (new Date(conflict.createdAt) < new Date(item.createdAt)) {
|
|
@@ -14176,12 +14176,12 @@ ${lines.join("\n")}`,
|
|
|
14176
14176
|
issues.push(`[${item.id}] Low confidence (${item.scores.confidence.toFixed(2)}) \u2014 quarantined`);
|
|
14177
14177
|
}
|
|
14178
14178
|
}
|
|
14179
|
-
const cleanedStore =
|
|
14179
|
+
const cleanedStore = store2.filter((m) => !(m.type === "working" && m.decision.action === "forget"));
|
|
14180
14180
|
await this.saveStore(metaDir, cleanedStore);
|
|
14181
14181
|
return {
|
|
14182
14182
|
success: true,
|
|
14183
14183
|
output: `Memory repair complete:
|
|
14184
|
-
Scanned: ${
|
|
14184
|
+
Scanned: ${store2.length} memories
|
|
14185
14185
|
Repaired contradictions: ${repaired}
|
|
14186
14186
|
Quarantined (duplicates/low-confidence): ${quarantined}
|
|
14187
14187
|
Expired working memories removed: ${expired}
|
|
@@ -14293,14 +14293,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14293
14293
|
// Memories below decay threshold get quarantined.
|
|
14294
14294
|
async decayMemories(start) {
|
|
14295
14295
|
const dir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14296
|
-
const
|
|
14297
|
-
if (
|
|
14296
|
+
const store2 = await this.loadStore(dir);
|
|
14297
|
+
if (store2.length === 0)
|
|
14298
14298
|
return { success: true, output: "No memories to decay", durationMs: performance.now() - start };
|
|
14299
14299
|
const now = Date.now();
|
|
14300
14300
|
const DECAY_RATE = 1e-3;
|
|
14301
14301
|
const QUARANTINE_THRESHOLD = 0.15;
|
|
14302
14302
|
let decayed = 0, quarantined = 0;
|
|
14303
|
-
for (const item of
|
|
14303
|
+
for (const item of store2) {
|
|
14304
14304
|
if (item.type === "quarantine")
|
|
14305
14305
|
continue;
|
|
14306
14306
|
const ageHours = (now - new Date(item.lastAccessedAt).getTime()) / (1e3 * 60 * 60);
|
|
@@ -14317,7 +14317,7 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14317
14317
|
quarantined++;
|
|
14318
14318
|
}
|
|
14319
14319
|
}
|
|
14320
|
-
await this.saveStore(dir,
|
|
14320
|
+
await this.saveStore(dir, store2);
|
|
14321
14321
|
return {
|
|
14322
14322
|
success: true,
|
|
14323
14323
|
output: `Decay sweep: ${decayed} memories updated, ${quarantined} quarantined (threshold: ${QUARANTINE_THRESHOLD})`,
|
|
@@ -14332,11 +14332,11 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14332
14332
|
// Any → procedural: if content matches action/strategy patterns
|
|
14333
14333
|
async autoLifecycle(start) {
|
|
14334
14334
|
const dir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14335
|
-
const
|
|
14336
|
-
if (
|
|
14335
|
+
const store2 = await this.loadStore(dir);
|
|
14336
|
+
if (store2.length === 0)
|
|
14337
14337
|
return { success: true, output: "No memories to process", durationMs: performance.now() - start };
|
|
14338
14338
|
let promoted = 0;
|
|
14339
|
-
for (const item of
|
|
14339
|
+
for (const item of store2) {
|
|
14340
14340
|
if (item.type === "quarantine")
|
|
14341
14341
|
continue;
|
|
14342
14342
|
if (item.type === "working" && item.accessCount >= 3) {
|
|
@@ -14358,18 +14358,18 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14358
14358
|
}
|
|
14359
14359
|
}
|
|
14360
14360
|
const decayResult = await this.decayMemories(start);
|
|
14361
|
-
await this.saveStore(dir,
|
|
14361
|
+
await this.saveStore(dir, store2);
|
|
14362
14362
|
try {
|
|
14363
14363
|
const { IdentityKernelTool: IdentityKernelTool2 } = await Promise.resolve().then(() => (init_identity_kernel(), identity_kernel_exports));
|
|
14364
14364
|
const ik = new IdentityKernelTool2(this.cwd);
|
|
14365
14365
|
const typeCounts = {};
|
|
14366
|
-
for (const item of
|
|
14366
|
+
for (const item of store2) {
|
|
14367
14367
|
typeCounts[item.type] = (typeCounts[item.type] || 0) + 1;
|
|
14368
14368
|
}
|
|
14369
14369
|
await ik.execute({
|
|
14370
14370
|
op: "observe",
|
|
14371
|
-
event: `Memory lifecycle: ${
|
|
14372
|
-
context: JSON.stringify({ total:
|
|
14371
|
+
event: `Memory lifecycle: ${store2.length} total, ${promoted} promoted. Types: ${JSON.stringify(typeCounts)}`,
|
|
14372
|
+
context: JSON.stringify({ total: store2.length, promoted, typeCounts })
|
|
14373
14373
|
});
|
|
14374
14374
|
} catch {
|
|
14375
14375
|
}
|
|
@@ -14388,18 +14388,18 @@ ${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: readFileSync47, existsSync: existsSync59 } = __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 (!existsSync59(storeFile))
|
|
14395
14395
|
return "";
|
|
14396
|
-
let
|
|
14396
|
+
let store2 = [];
|
|
14397
14397
|
try {
|
|
14398
|
-
|
|
14398
|
+
store2 = JSON.parse(readFileSync47(storeFile, "utf8"));
|
|
14399
14399
|
} catch {
|
|
14400
14400
|
return "";
|
|
14401
14401
|
}
|
|
14402
|
-
let items =
|
|
14402
|
+
let items = store2.filter((m) => m.type !== "quarantine" && m.scores.confidence > 0.15);
|
|
14403
14403
|
if (taskType) {
|
|
14404
14404
|
const typeMatch = items.filter((m) => m.content.toLowerCase().includes(taskType.toLowerCase()) || m.sourceTrace.toLowerCase().includes(taskType.toLowerCase()));
|
|
14405
14405
|
if (typeMatch.length >= 2)
|
|
@@ -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: readFileSync47, writeFileSync: writeFileSync31, existsSync: existsSync59, 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 (!existsSync59(storeFile))
|
|
14424
14424
|
return;
|
|
14425
|
-
let
|
|
14425
|
+
let store2 = [];
|
|
14426
14426
|
try {
|
|
14427
|
-
|
|
14427
|
+
store2 = JSON.parse(readFileSync47(storeFile, "utf8"));
|
|
14428
14428
|
} catch {
|
|
14429
14429
|
return;
|
|
14430
14430
|
}
|
|
@@ -14433,7 +14433,7 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14433
14433
|
return;
|
|
14434
14434
|
const surfacedIds = new Set(idMatches.map((m) => m.slice(1, -1)));
|
|
14435
14435
|
let updated = false;
|
|
14436
|
-
for (const item of
|
|
14436
|
+
for (const item of store2) {
|
|
14437
14437
|
if (!surfacedIds.has(item.id))
|
|
14438
14438
|
continue;
|
|
14439
14439
|
item.accessCount++;
|
|
@@ -14448,8 +14448,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14448
14448
|
updated = true;
|
|
14449
14449
|
}
|
|
14450
14450
|
if (updated) {
|
|
14451
|
-
|
|
14452
|
-
|
|
14451
|
+
mkdirSync33(metaDir, { recursive: true });
|
|
14452
|
+
writeFileSync31(storeFile, JSON.stringify(store2, null, 2));
|
|
14453
14453
|
}
|
|
14454
14454
|
}
|
|
14455
14455
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -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: readFileSync47, existsSync: existsSync59 } = __require("node:fs");
|
|
14875
14875
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14876
|
-
if (!
|
|
14876
|
+
if (!existsSync59(archiveFile))
|
|
14877
14877
|
return "";
|
|
14878
14878
|
let variants = [];
|
|
14879
14879
|
try {
|
|
14880
|
-
variants = JSON.parse(
|
|
14880
|
+
variants = JSON.parse(readFileSync47(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: readFileSync47, writeFileSync: writeFileSync31, existsSync: existsSync59, 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 (existsSync59(archiveFile))
|
|
14904
|
+
variants = JSON.parse(readFileSync47(archiveFile, "utf8"));
|
|
14905
14905
|
} catch {
|
|
14906
14906
|
}
|
|
14907
14907
|
variants.push({
|
|
@@ -14916,8 +14916,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14916
14916
|
});
|
|
14917
14917
|
if (variants.length > 50)
|
|
14918
14918
|
variants = variants.slice(-50);
|
|
14919
|
-
|
|
14920
|
-
|
|
14919
|
+
mkdirSync33(dir, { recursive: true });
|
|
14920
|
+
writeFileSync31(archiveFile, JSON.stringify(variants, null, 2));
|
|
14921
14921
|
}
|
|
14922
14922
|
async saveArchive(variants) {
|
|
14923
14923
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -18168,12 +18168,12 @@ async function loadStore(workingDir) {
|
|
|
18168
18168
|
return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
18169
18169
|
}
|
|
18170
18170
|
}
|
|
18171
|
-
async function saveStore(workingDir,
|
|
18171
|
+
async function saveStore(workingDir, store2) {
|
|
18172
18172
|
const dir = resolve23(workingDir, ".oa", "scheduled");
|
|
18173
18173
|
await mkdir11(dir, { recursive: true });
|
|
18174
18174
|
await mkdir11(join34(dir, "logs"), { recursive: true });
|
|
18175
|
-
|
|
18176
|
-
await writeFile15(join34(dir, "tasks.json"), JSON.stringify(
|
|
18175
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18176
|
+
await writeFile15(join34(dir, "tasks.json"), JSON.stringify(store2, null, 2), "utf-8");
|
|
18177
18177
|
}
|
|
18178
18178
|
function globalStoreDir() {
|
|
18179
18179
|
return join34(homedir9(), ".open-agents", "scheduled");
|
|
@@ -18186,12 +18186,12 @@ async function loadGlobalStore() {
|
|
|
18186
18186
|
return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
18187
18187
|
}
|
|
18188
18188
|
}
|
|
18189
|
-
async function saveGlobalStore(
|
|
18189
|
+
async function saveGlobalStore(store2) {
|
|
18190
18190
|
const dir = globalStoreDir();
|
|
18191
18191
|
await mkdir11(dir, { recursive: true });
|
|
18192
18192
|
await mkdir11(join34(dir, "logs"), { recursive: true });
|
|
18193
|
-
|
|
18194
|
-
await writeFile15(join34(dir, "tasks.json"), JSON.stringify(
|
|
18193
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18194
|
+
await writeFile15(join34(dir, "tasks.json"), JSON.stringify(store2, null, 2), "utf-8");
|
|
18195
18195
|
}
|
|
18196
18196
|
async function loadAllStores(workingDir) {
|
|
18197
18197
|
const [local, global] = await Promise.all([
|
|
@@ -18332,13 +18332,13 @@ var init_scheduler = __esm({
|
|
|
18332
18332
|
projectDir: resolve23(this.workingDir)
|
|
18333
18333
|
};
|
|
18334
18334
|
if (scope === "global") {
|
|
18335
|
-
const
|
|
18336
|
-
|
|
18337
|
-
await saveGlobalStore(
|
|
18335
|
+
const store2 = await loadGlobalStore();
|
|
18336
|
+
store2.tasks.push(newTask);
|
|
18337
|
+
await saveGlobalStore(store2);
|
|
18338
18338
|
} else {
|
|
18339
|
-
const
|
|
18340
|
-
|
|
18341
|
-
await saveStore(this.workingDir,
|
|
18339
|
+
const store2 = await loadStore(this.workingDir);
|
|
18340
|
+
store2.tasks.push(newTask);
|
|
18341
|
+
await saveStore(this.workingDir, store2);
|
|
18342
18342
|
}
|
|
18343
18343
|
installCronJob(newTask, this.workingDir);
|
|
18344
18344
|
return {
|
|
@@ -18418,12 +18418,12 @@ var init_scheduler = __esm({
|
|
|
18418
18418
|
const id = String(args["id"] ?? "");
|
|
18419
18419
|
if (!id)
|
|
18420
18420
|
return { success: false, output: "", error: "id is required for cancel action", durationMs: performance.now() - start };
|
|
18421
|
-
const
|
|
18422
|
-
const idx =
|
|
18421
|
+
const store2 = await loadStore(this.workingDir);
|
|
18422
|
+
const idx = store2.tasks.findIndex((t) => t.id === id);
|
|
18423
18423
|
if (idx === -1)
|
|
18424
18424
|
return { success: false, output: "", error: `No task found with ID '${id}'`, durationMs: performance.now() - start };
|
|
18425
|
-
const removed =
|
|
18426
|
-
await saveStore(this.workingDir,
|
|
18425
|
+
const removed = store2.tasks.splice(idx, 1)[0];
|
|
18426
|
+
await saveStore(this.workingDir, store2);
|
|
18427
18427
|
removeCronJob(id);
|
|
18428
18428
|
return {
|
|
18429
18429
|
success: true,
|
|
@@ -18435,12 +18435,12 @@ var init_scheduler = __esm({
|
|
|
18435
18435
|
const id = String(args["id"] ?? "");
|
|
18436
18436
|
if (!id)
|
|
18437
18437
|
return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
|
|
18438
|
-
const
|
|
18439
|
-
const task =
|
|
18438
|
+
const store2 = await loadStore(this.workingDir);
|
|
18439
|
+
const task = store2.tasks.find((t) => t.id === id);
|
|
18440
18440
|
if (!task)
|
|
18441
18441
|
return { success: false, output: "", error: `No task found with ID '${id}'`, durationMs: performance.now() - start };
|
|
18442
18442
|
task.enabled = enable;
|
|
18443
|
-
await saveStore(this.workingDir,
|
|
18443
|
+
await saveStore(this.workingDir, store2);
|
|
18444
18444
|
if (enable) {
|
|
18445
18445
|
installCronJob(task, this.workingDir);
|
|
18446
18446
|
} else {
|
|
@@ -18535,15 +18535,15 @@ async function loadReminderStore(workingDir) {
|
|
|
18535
18535
|
return { reminders: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
18536
18536
|
}
|
|
18537
18537
|
}
|
|
18538
|
-
async function saveReminderStore(workingDir,
|
|
18538
|
+
async function saveReminderStore(workingDir, store2) {
|
|
18539
18539
|
const storePath = await getStorePath(workingDir);
|
|
18540
|
-
|
|
18541
|
-
await writeFile16(storePath, JSON.stringify(
|
|
18540
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18541
|
+
await writeFile16(storePath, JSON.stringify(store2, null, 2), "utf-8");
|
|
18542
18542
|
}
|
|
18543
18543
|
async function getDueReminders(workingDir) {
|
|
18544
|
-
const
|
|
18544
|
+
const store2 = await loadReminderStore(workingDir);
|
|
18545
18545
|
const now = /* @__PURE__ */ new Date();
|
|
18546
|
-
return
|
|
18546
|
+
return store2.reminders.filter((r) => {
|
|
18547
18547
|
if (r.status !== "pending")
|
|
18548
18548
|
return false;
|
|
18549
18549
|
if (!r.dueAt)
|
|
@@ -18552,15 +18552,15 @@ async function getDueReminders(workingDir) {
|
|
|
18552
18552
|
});
|
|
18553
18553
|
}
|
|
18554
18554
|
async function markRemindersSeen(workingDir, ids) {
|
|
18555
|
-
const
|
|
18555
|
+
const store2 = await loadReminderStore(workingDir);
|
|
18556
18556
|
const idSet = new Set(ids);
|
|
18557
|
-
for (const r of
|
|
18557
|
+
for (const r of store2.reminders) {
|
|
18558
18558
|
if (idSet.has(r.id) && r.status === "pending") {
|
|
18559
18559
|
r.status = "seen";
|
|
18560
18560
|
r.seenAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18561
18561
|
}
|
|
18562
18562
|
}
|
|
18563
|
-
await saveReminderStore(workingDir,
|
|
18563
|
+
await saveReminderStore(workingDir, store2);
|
|
18564
18564
|
}
|
|
18565
18565
|
var STORE_FILE, ReminderTool;
|
|
18566
18566
|
var init_reminder = __esm({
|
|
@@ -18683,9 +18683,9 @@ var init_reminder = __esm({
|
|
|
18683
18683
|
context,
|
|
18684
18684
|
source: "agent"
|
|
18685
18685
|
};
|
|
18686
|
-
const
|
|
18687
|
-
|
|
18688
|
-
await saveReminderStore(this.workingDir,
|
|
18686
|
+
const store2 = await loadReminderStore(this.workingDir);
|
|
18687
|
+
store2.reminders.push(entry);
|
|
18688
|
+
await saveReminderStore(this.workingDir, store2);
|
|
18689
18689
|
return {
|
|
18690
18690
|
success: true,
|
|
18691
18691
|
output: [
|
|
@@ -18703,9 +18703,9 @@ var init_reminder = __esm({
|
|
|
18703
18703
|
};
|
|
18704
18704
|
}
|
|
18705
18705
|
async listReminders(args, start) {
|
|
18706
|
-
const
|
|
18706
|
+
const store2 = await loadReminderStore(this.workingDir);
|
|
18707
18707
|
const filter = String(args["filter"] ?? "pending");
|
|
18708
|
-
let filtered =
|
|
18708
|
+
let filtered = store2.reminders;
|
|
18709
18709
|
if (filter === "pending")
|
|
18710
18710
|
filtered = filtered.filter((r) => r.status === "pending" || r.status === "seen");
|
|
18711
18711
|
else if (filter !== "all")
|
|
@@ -18744,12 +18744,12 @@ var init_reminder = __esm({
|
|
|
18744
18744
|
const id = String(args["id"] ?? "");
|
|
18745
18745
|
if (!id)
|
|
18746
18746
|
return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
|
|
18747
|
-
const
|
|
18748
|
-
const reminder =
|
|
18747
|
+
const store2 = await loadReminderStore(this.workingDir);
|
|
18748
|
+
const reminder = store2.reminders.find((r) => r.id === id);
|
|
18749
18749
|
if (!reminder)
|
|
18750
18750
|
return { success: false, output: "", error: `No reminder found with ID '${id}'`, durationMs: performance.now() - start };
|
|
18751
18751
|
reminder.status = status;
|
|
18752
|
-
await saveReminderStore(this.workingDir,
|
|
18752
|
+
await saveReminderStore(this.workingDir, store2);
|
|
18753
18753
|
return {
|
|
18754
18754
|
success: true,
|
|
18755
18755
|
output: `Reminder '${id}' marked as ${status}: ${reminder.message.slice(0, 80)}`,
|
|
@@ -18764,15 +18764,15 @@ var init_reminder = __esm({
|
|
|
18764
18764
|
const parsed = parseDueTime(due);
|
|
18765
18765
|
if (!parsed)
|
|
18766
18766
|
return { success: false, output: "", error: `Cannot parse due time '${due}'`, durationMs: performance.now() - start };
|
|
18767
|
-
const
|
|
18768
|
-
const reminder =
|
|
18767
|
+
const store2 = await loadReminderStore(this.workingDir);
|
|
18768
|
+
const reminder = store2.reminders.find((r) => r.id === id);
|
|
18769
18769
|
if (!reminder)
|
|
18770
18770
|
return { success: false, output: "", error: `No reminder found with ID '${id}'`, durationMs: performance.now() - start };
|
|
18771
18771
|
reminder.status = "pending";
|
|
18772
18772
|
reminder.dueAt = parsed.isoDate;
|
|
18773
18773
|
reminder.dueDescription = parsed.description;
|
|
18774
18774
|
reminder.seenAt = void 0;
|
|
18775
|
-
await saveReminderStore(this.workingDir,
|
|
18775
|
+
await saveReminderStore(this.workingDir, store2);
|
|
18776
18776
|
return {
|
|
18777
18777
|
success: true,
|
|
18778
18778
|
output: `Reminder '${id}' snoozed until ${parsed.description}: ${reminder.message.slice(0, 80)}`,
|
|
@@ -18796,25 +18796,25 @@ async function loadAttentionStore(workingDir) {
|
|
|
18796
18796
|
return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
18797
18797
|
}
|
|
18798
18798
|
}
|
|
18799
|
-
async function saveAttentionStore(workingDir,
|
|
18799
|
+
async function saveAttentionStore(workingDir, store2) {
|
|
18800
18800
|
const dir = resolve25(workingDir, ".oa", "scheduled");
|
|
18801
18801
|
await mkdir13(dir, { recursive: true });
|
|
18802
|
-
|
|
18803
|
-
await writeFile17(join36(dir, "attention.json"), JSON.stringify(
|
|
18802
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18803
|
+
await writeFile17(join36(dir, "attention.json"), JSON.stringify(store2, null, 2), "utf-8");
|
|
18804
18804
|
}
|
|
18805
18805
|
async function getActiveAttentionItems(workingDir) {
|
|
18806
|
-
const
|
|
18806
|
+
const store2 = await loadAttentionStore(workingDir);
|
|
18807
18807
|
const now = /* @__PURE__ */ new Date();
|
|
18808
18808
|
let changed = false;
|
|
18809
|
-
for (const item of
|
|
18809
|
+
for (const item of store2.items) {
|
|
18810
18810
|
if (item.status === "active" && item.expiresAt && new Date(item.expiresAt) <= now) {
|
|
18811
18811
|
item.status = "expired";
|
|
18812
18812
|
changed = true;
|
|
18813
18813
|
}
|
|
18814
18814
|
}
|
|
18815
18815
|
if (changed)
|
|
18816
|
-
await saveAttentionStore(workingDir,
|
|
18817
|
-
return
|
|
18816
|
+
await saveAttentionStore(workingDir, store2);
|
|
18817
|
+
return store2.items.filter((i) => i.status === "active");
|
|
18818
18818
|
}
|
|
18819
18819
|
var AgendaTool;
|
|
18820
18820
|
var init_agenda = __esm({
|
|
@@ -19002,9 +19002,9 @@ ${sections.join("\n")}`,
|
|
|
19002
19002
|
status: "active",
|
|
19003
19003
|
notes: notes2
|
|
19004
19004
|
};
|
|
19005
|
-
const
|
|
19006
|
-
|
|
19007
|
-
await saveAttentionStore(this.workingDir,
|
|
19005
|
+
const store2 = await loadAttentionStore(this.workingDir);
|
|
19006
|
+
store2.items.push(item);
|
|
19007
|
+
await saveAttentionStore(this.workingDir, store2);
|
|
19008
19008
|
return {
|
|
19009
19009
|
success: true,
|
|
19010
19010
|
output: [
|
|
@@ -19025,13 +19025,13 @@ ${sections.join("\n")}`,
|
|
|
19025
19025
|
const id = String(args["id"] ?? "");
|
|
19026
19026
|
if (!id)
|
|
19027
19027
|
return { success: false, output: "", error: "id is required for resolve", durationMs: performance.now() - start };
|
|
19028
|
-
const
|
|
19029
|
-
const item =
|
|
19028
|
+
const store2 = await loadAttentionStore(this.workingDir);
|
|
19029
|
+
const item = store2.items.find((i) => i.id === id);
|
|
19030
19030
|
if (!item)
|
|
19031
19031
|
return { success: false, output: "", error: `No attention item found with ID '${id}'`, durationMs: performance.now() - start };
|
|
19032
19032
|
item.status = "resolved";
|
|
19033
19033
|
item.resolvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19034
|
-
await saveAttentionStore(this.workingDir,
|
|
19034
|
+
await saveAttentionStore(this.workingDir, store2);
|
|
19035
19035
|
return {
|
|
19036
19036
|
success: true,
|
|
19037
19037
|
output: `Attention item '${id}' resolved: ${item.title}`,
|
|
@@ -19097,8 +19097,8 @@ ${sections.join("\n")}`,
|
|
|
19097
19097
|
try {
|
|
19098
19098
|
const storePath = resolve25(this.workingDir, ".oa", "scheduled", "tasks.json");
|
|
19099
19099
|
const raw = await readFile17(storePath, "utf-8");
|
|
19100
|
-
const
|
|
19101
|
-
return
|
|
19100
|
+
const store2 = JSON.parse(raw);
|
|
19101
|
+
return store2.tasks ?? [];
|
|
19102
19102
|
} catch {
|
|
19103
19103
|
return [];
|
|
19104
19104
|
}
|
|
@@ -19816,12 +19816,12 @@ async function loadStore2(workingDir) {
|
|
|
19816
19816
|
return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
19817
19817
|
}
|
|
19818
19818
|
}
|
|
19819
|
-
async function saveStore2(workingDir,
|
|
19819
|
+
async function saveStore2(workingDir, store2) {
|
|
19820
19820
|
const dir = resolve27(workingDir, ".oa", "cron-agents");
|
|
19821
19821
|
await mkdir14(dir, { recursive: true });
|
|
19822
19822
|
await mkdir14(join39(dir, "logs"), { recursive: true });
|
|
19823
|
-
|
|
19824
|
-
await writeFile18(join39(dir, "store.json"), JSON.stringify(
|
|
19823
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19824
|
+
await writeFile18(join39(dir, "store.json"), JSON.stringify(store2, null, 2), "utf-8");
|
|
19825
19825
|
}
|
|
19826
19826
|
function globalCronDir() {
|
|
19827
19827
|
return join39(homedir10(), ".open-agents", "cron-agents");
|
|
@@ -19834,12 +19834,12 @@ async function loadGlobalCronStore() {
|
|
|
19834
19834
|
return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
19835
19835
|
}
|
|
19836
19836
|
}
|
|
19837
|
-
async function saveGlobalCronStore(
|
|
19837
|
+
async function saveGlobalCronStore(store2) {
|
|
19838
19838
|
const dir = globalCronDir();
|
|
19839
19839
|
await mkdir14(dir, { recursive: true });
|
|
19840
19840
|
await mkdir14(join39(dir, "logs"), { recursive: true });
|
|
19841
|
-
|
|
19842
|
-
await writeFile18(join39(dir, "store.json"), JSON.stringify(
|
|
19841
|
+
store2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19842
|
+
await writeFile18(join39(dir, "store.json"), JSON.stringify(store2, null, 2), "utf-8");
|
|
19843
19843
|
}
|
|
19844
19844
|
async function loadAllCronStores(workingDir) {
|
|
19845
19845
|
const [local, global] = await Promise.all([
|
|
@@ -20008,13 +20008,13 @@ var init_cron_agent = __esm({
|
|
|
20008
20008
|
projectDir: resolve27(this.workingDir)
|
|
20009
20009
|
};
|
|
20010
20010
|
if (scope === "global") {
|
|
20011
|
-
const
|
|
20012
|
-
|
|
20013
|
-
await saveGlobalCronStore(
|
|
20011
|
+
const store2 = await loadGlobalCronStore();
|
|
20012
|
+
store2.jobs.push(job);
|
|
20013
|
+
await saveGlobalCronStore(store2);
|
|
20014
20014
|
} else {
|
|
20015
|
-
const
|
|
20016
|
-
|
|
20017
|
-
await saveStore2(this.workingDir,
|
|
20015
|
+
const store2 = await loadStore2(this.workingDir);
|
|
20016
|
+
store2.jobs.push(job);
|
|
20017
|
+
await saveStore2(this.workingDir, store2);
|
|
20018
20018
|
}
|
|
20019
20019
|
installCronAgentJob(job, this.workingDir);
|
|
20020
20020
|
return {
|
|
@@ -20089,8 +20089,8 @@ var init_cron_agent = __esm({
|
|
|
20089
20089
|
const id = String(args["id"] ?? "");
|
|
20090
20090
|
if (!id)
|
|
20091
20091
|
return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
|
|
20092
|
-
const
|
|
20093
|
-
const job =
|
|
20092
|
+
const store2 = await loadStore2(this.workingDir);
|
|
20093
|
+
const job = store2.jobs.find((j) => j.id === id);
|
|
20094
20094
|
if (!job)
|
|
20095
20095
|
return { success: false, output: "", error: `No job found with ID '${id}'`, durationMs: performance.now() - start };
|
|
20096
20096
|
const lines = [
|
|
@@ -20124,12 +20124,12 @@ var init_cron_agent = __esm({
|
|
|
20124
20124
|
const id = String(args["id"] ?? "");
|
|
20125
20125
|
if (!id)
|
|
20126
20126
|
return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
|
|
20127
|
-
const
|
|
20128
|
-
const idx =
|
|
20127
|
+
const store2 = await loadStore2(this.workingDir);
|
|
20128
|
+
const idx = store2.jobs.findIndex((j) => j.id === id);
|
|
20129
20129
|
if (idx === -1)
|
|
20130
20130
|
return { success: false, output: "", error: `No job found with ID '${id}'`, durationMs: performance.now() - start };
|
|
20131
|
-
const removed =
|
|
20132
|
-
await saveStore2(this.workingDir,
|
|
20131
|
+
const removed = store2.jobs.splice(idx, 1)[0];
|
|
20132
|
+
await saveStore2(this.workingDir, store2);
|
|
20133
20133
|
removeCronAgentJob(id);
|
|
20134
20134
|
return {
|
|
20135
20135
|
success: true,
|
|
@@ -20155,8 +20155,8 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
20155
20155
|
const id = String(args["id"] ?? "");
|
|
20156
20156
|
if (!id)
|
|
20157
20157
|
return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
|
|
20158
|
-
const
|
|
20159
|
-
const job =
|
|
20158
|
+
const store2 = await loadStore2(this.workingDir);
|
|
20159
|
+
const job = store2.jobs.find((j) => j.id === id);
|
|
20160
20160
|
if (!job)
|
|
20161
20161
|
return { success: false, output: "", error: `No job found with ID '${id}'`, durationMs: performance.now() - start };
|
|
20162
20162
|
const lines = [
|
|
@@ -20181,7 +20181,7 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
20181
20181
|
lines.push(` cron_agent(action='cancel', id='${id}')`);
|
|
20182
20182
|
job.status = "completed";
|
|
20183
20183
|
removeCronAgentJob(id);
|
|
20184
|
-
await saveStore2(this.workingDir,
|
|
20184
|
+
await saveStore2(this.workingDir, store2);
|
|
20185
20185
|
lines.push(" Status automatically set to COMPLETED.");
|
|
20186
20186
|
} catch (err) {
|
|
20187
20187
|
const errMsg = err instanceof Error ? err.stderr?.toString() || err.message : String(err);
|
|
@@ -27422,10 +27422,10 @@ ${marker}` : marker);
|
|
|
27422
27422
|
if (!this._workingDirectory)
|
|
27423
27423
|
return;
|
|
27424
27424
|
try {
|
|
27425
|
-
const { mkdirSync:
|
|
27426
|
-
const { join:
|
|
27427
|
-
const sessionDir =
|
|
27428
|
-
|
|
27425
|
+
const { mkdirSync: mkdirSync33, writeFileSync: writeFileSync31 } = __require("node:fs");
|
|
27426
|
+
const { join: join79 } = __require("node:path");
|
|
27427
|
+
const sessionDir = join79(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
27428
|
+
mkdirSync33(sessionDir, { recursive: true });
|
|
27429
27429
|
const checkpoint = {
|
|
27430
27430
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27431
27431
|
sessionId: this._sessionId,
|
|
@@ -27437,7 +27437,7 @@ ${marker}` : marker);
|
|
|
27437
27437
|
memexEntryCount: this._memexArchive.size,
|
|
27438
27438
|
fileRegistrySize: this._fileRegistry.size
|
|
27439
27439
|
};
|
|
27440
|
-
|
|
27440
|
+
writeFileSync31(join79(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:
|
|
28579
|
-
const { join:
|
|
28578
|
+
const { writeFileSync: writeFileSync31, readFileSync: readFileSync47, unlinkSync: unlinkSync13 } = await import("node:fs");
|
|
28579
|
+
const { join: join79 } = await import("node:path");
|
|
28580
28580
|
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
28581
|
-
const tmpIn =
|
|
28582
|
-
const tmpOut =
|
|
28583
|
-
|
|
28581
|
+
const tmpIn = join79(tmpdir11(), `oa_img_in_${Date.now()}.png`);
|
|
28582
|
+
const tmpOut = join79(tmpdir11(), `oa_img_out_${Date.now()}.jpg`);
|
|
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 = readFileSync47(tmpOut);
|
|
28589
28589
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
28590
28590
|
try {
|
|
28591
28591
|
unlinkSync13(tmpIn);
|
|
@@ -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: existsSync59, readFileSync: readFileSync47 } = await import("node:fs");
|
|
39561
|
+
const { join: join79 } = 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 = join79(nexusDir, "status.json");
|
|
39568
|
+
if (existsSync59(statusPath)) {
|
|
39569
|
+
const status = JSON.parse(readFileSync47(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 = join79(nexusDir, "pricing.json");
|
|
39577
|
+
if (existsSync59(pricingPath)) {
|
|
39578
39578
|
try {
|
|
39579
|
-
const pricing = JSON.parse(
|
|
39579
|
+
const pricing = JSON.parse(readFileSync47(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 = join79(nexusDir, "peer-models-cache.json");
|
|
39594
|
+
if (existsSync59(cachePath)) {
|
|
39595
39595
|
try {
|
|
39596
|
-
const cache4 = JSON.parse(
|
|
39596
|
+
const cache4 = JSON.parse(readFileSync47(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 = join79(nexusDir, "pricing.json");
|
|
39712
|
+
if (existsSync59(pricingPath)) {
|
|
39713
39713
|
try {
|
|
39714
|
-
const pricing = JSON.parse(
|
|
39714
|
+
const pricing = JSON.parse(readFileSync47(pricingPath, "utf8"));
|
|
39715
39715
|
return (pricing.models || []).map((m) => ({
|
|
39716
39716
|
name: m.model || "unknown",
|
|
39717
39717
|
size: m.parameterSize || "",
|
|
@@ -49671,8 +49671,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
49671
49671
|
try {
|
|
49672
49672
|
const metaFile = join59(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
49673
49673
|
if (existsSync43(metaFile)) {
|
|
49674
|
-
const
|
|
49675
|
-
const active =
|
|
49674
|
+
const store2 = JSON.parse(readFileSync32(metaFile, "utf8"));
|
|
49675
|
+
const active = store2.filter((m) => m.type !== "quarantine");
|
|
49676
49676
|
const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
|
|
49677
49677
|
const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
|
|
49678
49678
|
const optimizations = active.filter((m) => m.content?.startsWith("[optimization]")).length;
|
|
@@ -52121,12 +52121,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
52121
52121
|
continue;
|
|
52122
52122
|
}
|
|
52123
52123
|
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
52124
|
-
const { copyFileSync: copyFileSync3, mkdirSync:
|
|
52124
|
+
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync33, existsSync: exists } = await import("node:fs");
|
|
52125
52125
|
const { homedir: homedir21 } = await import("node:os");
|
|
52126
52126
|
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
52127
52127
|
const destDir = pathJoin(homedir21(), ".open-agents", "voice", "models", modelName);
|
|
52128
52128
|
if (!exists(destDir))
|
|
52129
|
-
|
|
52129
|
+
mkdirSync33(destDir, { recursive: true });
|
|
52130
52130
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
52131
52131
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
52132
52132
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -52965,11 +52965,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
52965
52965
|
const models = await fetchModels(peerUrl, authKey);
|
|
52966
52966
|
if (models.length > 0) {
|
|
52967
52967
|
try {
|
|
52968
|
-
const { writeFileSync:
|
|
52969
|
-
const { join:
|
|
52970
|
-
const cachePath =
|
|
52971
|
-
|
|
52972
|
-
|
|
52968
|
+
const { writeFileSync: writeFileSync31, mkdirSync: mkdirSync33 } = await import("node:fs");
|
|
52969
|
+
const { join: join79, dirname: dirname24 } = await import("node:path");
|
|
52970
|
+
const cachePath = join79(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
52971
|
+
mkdirSync33(dirname24(cachePath), { recursive: true });
|
|
52972
|
+
writeFileSync31(cachePath, JSON.stringify({
|
|
52973
52973
|
peerId,
|
|
52974
52974
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52975
52975
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -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: join79 } = await import("node:path");
|
|
53172
|
+
const { existsSync: existsSync59 } = 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
|
+
join79(thisDir, "..", "package.json"),
|
|
53177
|
+
join79(thisDir, "..", "..", "package.json"),
|
|
53178
|
+
join79(thisDir, "..", "..", "..", "package.json")
|
|
53179
53179
|
];
|
|
53180
53180
|
for (const pkgPath of candidates) {
|
|
53181
|
-
if (
|
|
53181
|
+
if (existsSync59(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";
|
|
@@ -54176,11 +54176,11 @@ function getEnvironment(repoRoot) {
|
|
|
54176
54176
|
];
|
|
54177
54177
|
return lines.join("\n");
|
|
54178
54178
|
}
|
|
54179
|
-
function loadTaskMemories(repoRoot,
|
|
54179
|
+
function loadTaskMemories(repoRoot, store2) {
|
|
54180
54180
|
try {
|
|
54181
|
-
let tasks =
|
|
54181
|
+
let tasks = store2.listByRepo(repoRoot);
|
|
54182
54182
|
if (tasks.length === 0) {
|
|
54183
|
-
tasks =
|
|
54183
|
+
tasks = store2.recent(10);
|
|
54184
54184
|
}
|
|
54185
54185
|
if (tasks.length === 0)
|
|
54186
54186
|
return "";
|
|
@@ -54198,9 +54198,9 @@ function loadTaskMemories(repoRoot, store) {
|
|
|
54198
54198
|
return "";
|
|
54199
54199
|
}
|
|
54200
54200
|
}
|
|
54201
|
-
function loadFailurePatterns(
|
|
54201
|
+
function loadFailurePatterns(store2) {
|
|
54202
54202
|
try {
|
|
54203
|
-
const unresolved =
|
|
54203
|
+
const unresolved = store2.listUnresolved();
|
|
54204
54204
|
if (unresolved.length === 0)
|
|
54205
54205
|
return "";
|
|
54206
54206
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -54222,10 +54222,10 @@ function loadFailurePatterns(store) {
|
|
|
54222
54222
|
return "";
|
|
54223
54223
|
}
|
|
54224
54224
|
}
|
|
54225
|
-
function loadPatternSuggestions(repoRoot,
|
|
54225
|
+
function loadPatternSuggestions(repoRoot, store2) {
|
|
54226
54226
|
try {
|
|
54227
|
-
const projectPatterns =
|
|
54228
|
-
const globalPatterns =
|
|
54227
|
+
const projectPatterns = store2.detectPatterns({ repoRoot, minOccurrences: 3, minLen: 3 });
|
|
54228
|
+
const globalPatterns = store2.detectPatterns({ minOccurrences: 3, minLen: 3 });
|
|
54229
54229
|
const all = [...projectPatterns];
|
|
54230
54230
|
for (const gp of globalPatterns) {
|
|
54231
54231
|
const fp = gp.pattern.map((e) => e.tool).join("->");
|
|
@@ -65537,7 +65537,10 @@ body {
|
|
|
65537
65537
|
<div id="tabs" style="display:flex;gap:0;background:#1e1e22;border-bottom:1px solid #2a2a30;padding:0 16px;flex-shrink:0">
|
|
65538
65538
|
<button class="tab active" onclick="switchTab('chat')" id="tab-chat" style="background:none;border:none;border-bottom:2px solid #b2920a;color:#b2920a;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">chat</button>
|
|
65539
65539
|
<button class="tab" onclick="switchTab('agent')" id="tab-agent" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">agent</button>
|
|
65540
|
-
<button class="tab" onclick="switchTab('jobs')" id="tab-jobs" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">
|
|
65540
|
+
<button class="tab" onclick="switchTab('jobs')" id="tab-jobs" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">dashboard</button>
|
|
65541
|
+
<button class="tab" onclick="switchTab('config')" id="tab-config" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">config</button>
|
|
65542
|
+
<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
|
+
<span id="token-counter" style="margin-left:auto;font-size:0.6rem;color:#555">0 tokens</span>
|
|
65541
65544
|
</div>
|
|
65542
65545
|
<div id="conversation"></div>
|
|
65543
65546
|
<div id="agent-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
@@ -65551,10 +65554,41 @@ body {
|
|
|
65551
65554
|
</div>
|
|
65552
65555
|
<div id="jobs-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65553
65556
|
<div id="dashboard-health" style="display:flex;gap:12px;margin-bottom:16px;flex-wrap:wrap"></div>
|
|
65557
|
+
<div id="dashboard-daemons" style="margin-bottom:16px"></div>
|
|
65554
65558
|
<div id="dashboard-usage" style="margin-bottom:16px"></div>
|
|
65555
65559
|
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:8px">Job History</h3>
|
|
65556
65560
|
<div id="jobs-list" style="font-size:0.78rem"></div>
|
|
65557
65561
|
</div>
|
|
65562
|
+
<div id="config-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65563
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:12px">Server Configuration</h3>
|
|
65564
|
+
<div id="config-content" style="font-size:0.78rem"></div>
|
|
65565
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Model</h3>
|
|
65566
|
+
<div style="display:flex;gap:8px;align-items:center">
|
|
65567
|
+
<select id="config-model-select" style="background:#2a2a30;border:1px solid #3a3a42;color:#b0b0b0;padding:4px 8px;border-radius:3px;font-family:inherit;font-size:0.7rem;flex:1"></select>
|
|
65568
|
+
<button onclick="switchModel()" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">switch</button>
|
|
65569
|
+
</div>
|
|
65570
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Inference Provider</h3>
|
|
65571
|
+
<div id="config-endpoint" style="font-size:0.78rem;color:#888;margin-bottom:8px"></div>
|
|
65572
|
+
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:4px">
|
|
65573
|
+
<input id="config-ep-url" placeholder="https://api.example.com/v1" style="flex:1;min-width:200px;background:#2a2a30;border:1px solid #3a3a42;border-radius:3px;padding:4px 8px;color:#b0b0b0;font-family:inherit;font-size:0.7rem;outline:none">
|
|
65574
|
+
<input id="config-ep-key" placeholder="Bearer key (optional)" type="password" style="flex:1;min-width:150px;background:#2a2a30;border:1px solid #3a3a42;border-radius:3px;padding:4px 8px;color:#b0b0b0;font-family:inherit;font-size:0.7rem;outline:none">
|
|
65575
|
+
<select id="config-ep-type" style="background:#2a2a30;border:1px solid #3a3a42;color:#b0b0b0;padding:4px 8px;border-radius:3px;font-family:inherit;font-size:0.7rem">
|
|
65576
|
+
<option value="ollama">ollama</option><option value="vllm">vllm</option><option value="openai">openai</option>
|
|
65577
|
+
</select>
|
|
65578
|
+
<button onclick="switchEndpoint()" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">set</button>
|
|
65579
|
+
</div>
|
|
65580
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Profiles</h3>
|
|
65581
|
+
<div id="config-profiles" style="font-size:0.78rem"></div>
|
|
65582
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Export Conversation</h3>
|
|
65583
|
+
<div style="display:flex;gap:8px">
|
|
65584
|
+
<button onclick="exportChat('md')" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">markdown</button>
|
|
65585
|
+
<button onclick="exportChat('json')" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">JSON</button>
|
|
65586
|
+
</div>
|
|
65587
|
+
</div>
|
|
65588
|
+
<div id="activity-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65589
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:12px">Recent Activity (Audit Log)</h3>
|
|
65590
|
+
<div id="activity-feed" style="font-size:0.72rem"></div>
|
|
65591
|
+
</div>
|
|
65558
65592
|
|
|
65559
65593
|
<div id="footer">
|
|
65560
65594
|
<span id="system-prompt-toggle" onclick="toggleSystemPrompt()">sys</span>
|
|
@@ -65733,6 +65767,7 @@ async function sendMessage() {
|
|
|
65733
65767
|
}
|
|
65734
65768
|
|
|
65735
65769
|
messages.push({ role: 'assistant', content: fullContent });
|
|
65770
|
+
updateTokenCounter(fullContent.split(/\\s+/).length * 1.3 | 0); // rough token estimate
|
|
65736
65771
|
// Re-render with copy button
|
|
65737
65772
|
msgDiv.innerHTML = renderMarkdown(fullContent);
|
|
65738
65773
|
const actions = document.createElement('div');
|
|
@@ -65780,16 +65815,150 @@ function closeKeyModal() {
|
|
|
65780
65815
|
}
|
|
65781
65816
|
|
|
65782
65817
|
// Tab switching
|
|
65818
|
+
const allPanels = ['conversation','agent-panel','jobs-panel','config-panel','activity-panel'];
|
|
65783
65819
|
function switchTab(tab) {
|
|
65784
|
-
|
|
65785
|
-
document.getElementById(
|
|
65786
|
-
document.getElementById(
|
|
65820
|
+
const panelMap = {chat:'conversation',agent:'agent-panel',jobs:'jobs-panel',config:'config-panel',activity:'activity-panel'};
|
|
65821
|
+
allPanels.forEach(id => { const el = document.getElementById(id); if(el) el.style.display = 'none'; });
|
|
65822
|
+
const panel = document.getElementById(panelMap[tab]);
|
|
65823
|
+
if (panel) panel.style.display = tab === 'chat' ? 'flex' : 'block';
|
|
65787
65824
|
document.getElementById('footer').style.display = tab === 'chat' ? 'flex' : 'none';
|
|
65788
65825
|
document.querySelectorAll('.tab').forEach(t => { t.style.borderBottomColor = 'transparent'; t.style.color = '#555'; });
|
|
65789
65826
|
const active = document.getElementById('tab-' + tab);
|
|
65790
65827
|
if (active) { active.style.borderBottomColor = '#b2920a'; active.style.color = '#b2920a'; }
|
|
65791
65828
|
if (tab === 'jobs') loadJobs();
|
|
65792
65829
|
if (tab === 'agent') loadProfiles();
|
|
65830
|
+
if (tab === 'config') loadConfig();
|
|
65831
|
+
if (tab === 'activity') loadActivity();
|
|
65832
|
+
}
|
|
65833
|
+
|
|
65834
|
+
// Token counter
|
|
65835
|
+
let totalTokens = 0;
|
|
65836
|
+
function updateTokenCounter(n) { totalTokens += n; document.getElementById('token-counter').textContent = totalTokens.toLocaleString() + ' tokens'; }
|
|
65837
|
+
|
|
65838
|
+
// Config panel
|
|
65839
|
+
async function loadConfig() {
|
|
65840
|
+
try {
|
|
65841
|
+
const [cfg, ep, models] = await Promise.all([
|
|
65842
|
+
fetch('/v1/config', { headers: headers() }).then(r => r.json()),
|
|
65843
|
+
fetch('/v1/config/endpoint', { headers: headers() }).then(r => r.json()),
|
|
65844
|
+
fetch('/v1/models', { headers: headers() }).then(r => r.json()),
|
|
65845
|
+
]);
|
|
65846
|
+
const c = cfg.config || {};
|
|
65847
|
+
document.getElementById('config-content').innerHTML =
|
|
65848
|
+
'<table style="width:100%">' +
|
|
65849
|
+
Object.entries(c).map(([k,v]) =>
|
|
65850
|
+
'<tr style="border-bottom:1px solid #2a2a30"><td style="padding:4px;color:#888">' + k + '</td>' +
|
|
65851
|
+
'<td style="padding:4px;color:#b0b0b0">' + (v === '[redacted]' ? '<span style="color:#555">[redacted]</span>' : String(v)) + '</td></tr>'
|
|
65852
|
+
).join('') + '</table>';
|
|
65853
|
+
document.getElementById('config-endpoint').textContent = ep.url + ' (' + (ep.backendType || 'unknown') + ')';
|
|
65854
|
+
// Populate model switcher
|
|
65855
|
+
const sel = document.getElementById('config-model-select');
|
|
65856
|
+
sel.innerHTML = '';
|
|
65857
|
+
for (const m of (models.data || [])) {
|
|
65858
|
+
const opt = document.createElement('option');
|
|
65859
|
+
opt.value = m.id.replace(/^local\\//, '');
|
|
65860
|
+
opt.textContent = m.id.replace(/^local\\//, '');
|
|
65861
|
+
if (opt.value === c.model) opt.selected = true;
|
|
65862
|
+
sel.appendChild(opt);
|
|
65863
|
+
}
|
|
65864
|
+
} catch {}
|
|
65865
|
+
// Profiles
|
|
65866
|
+
try {
|
|
65867
|
+
const r = await fetch('/v1/profiles', { headers: headers() });
|
|
65868
|
+
const d = await r.json();
|
|
65869
|
+
document.getElementById('config-profiles').innerHTML = (d.profiles || []).map(p =>
|
|
65870
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:6px 10px;margin:4px 0">' +
|
|
65871
|
+
'<span style="color:#b2920a">' + p.name + '</span>' +
|
|
65872
|
+
(p.encrypted ? ' <span style="color:#555;font-size:0.6rem">(encrypted)</span>' : '') +
|
|
65873
|
+
' <span style="color:#555;font-size:0.6rem">' + (p.source || '') + '</span></div>'
|
|
65874
|
+
).join('') || '<span style="color:#555">No profiles</span>';
|
|
65875
|
+
} catch {}
|
|
65876
|
+
}
|
|
65877
|
+
|
|
65878
|
+
async function switchEndpoint() {
|
|
65879
|
+
const url = document.getElementById('config-ep-url').value.trim();
|
|
65880
|
+
const auth = document.getElementById('config-ep-key').value.trim();
|
|
65881
|
+
const backendType = document.getElementById('config-ep-type').value;
|
|
65882
|
+
if (!url) return;
|
|
65883
|
+
try {
|
|
65884
|
+
await fetch('/v1/config/endpoint', {
|
|
65885
|
+
method: 'PUT', headers: headers(),
|
|
65886
|
+
body: JSON.stringify({ url, auth: auth ? 'Bearer ' + auth : '', backendType }),
|
|
65887
|
+
});
|
|
65888
|
+
loadConfig();
|
|
65889
|
+
loadModels(); // refresh model list from new endpoint
|
|
65890
|
+
} catch {}
|
|
65891
|
+
}
|
|
65892
|
+
|
|
65893
|
+
async function switchModel() {
|
|
65894
|
+
const model = document.getElementById('config-model-select').value;
|
|
65895
|
+
if (!model) return;
|
|
65896
|
+
try {
|
|
65897
|
+
await fetch('/v1/config/model', {
|
|
65898
|
+
method: 'PUT', headers: headers(),
|
|
65899
|
+
body: JSON.stringify({ model }),
|
|
65900
|
+
});
|
|
65901
|
+
loadConfig();
|
|
65902
|
+
modelSelect.value = model; // sync chat model picker
|
|
65903
|
+
} catch {}
|
|
65904
|
+
}
|
|
65905
|
+
|
|
65906
|
+
// Export conversation
|
|
65907
|
+
function exportChat(fmt) {
|
|
65908
|
+
let content;
|
|
65909
|
+
if (fmt === 'json') {
|
|
65910
|
+
content = JSON.stringify(messages, null, 2);
|
|
65911
|
+
} else {
|
|
65912
|
+
content = messages.map(m => (m.role === 'user' ? '**You:** ' : '**Agent:** ') + m.content).join('\\n\\n');
|
|
65913
|
+
}
|
|
65914
|
+
const blob = new Blob([content], { type: fmt === 'json' ? 'application/json' : 'text/markdown' });
|
|
65915
|
+
const a = document.createElement('a');
|
|
65916
|
+
a.href = URL.createObjectURL(blob);
|
|
65917
|
+
a.download = 'conversation.' + (fmt === 'json' ? 'json' : 'md');
|
|
65918
|
+
a.click();
|
|
65919
|
+
}
|
|
65920
|
+
|
|
65921
|
+
// Activity feed (audit log)
|
|
65922
|
+
async function loadActivity() {
|
|
65923
|
+
try {
|
|
65924
|
+
const r = await fetch('/v1/audit?limit=50', { headers: headers() });
|
|
65925
|
+
const d = await r.json();
|
|
65926
|
+
const feed = document.getElementById('activity-feed');
|
|
65927
|
+
if (!d.records?.length) { feed.innerHTML = '<span style="color:#555">No activity yet</span>'; return; }
|
|
65928
|
+
feed.innerHTML = d.records.map(r => {
|
|
65929
|
+
const time = r.ts?.split('T')[1]?.slice(0,8) || '';
|
|
65930
|
+
const color = r.status >= 400 ? '#ff4444' : r.status >= 300 ? '#b2920a' : '#4ec94e';
|
|
65931
|
+
return '<div style="padding:3px 0;border-bottom:1px solid #1e1e22">' +
|
|
65932
|
+
'<span style="color:#555">' + time + '</span> ' +
|
|
65933
|
+
'<span style="color:' + color + '">' + r.status + '</span> ' +
|
|
65934
|
+
'<span style="color:#888">' + r.method + '</span> ' +
|
|
65935
|
+
'<span style="color:#b0b0b0">' + r.path + '</span> ' +
|
|
65936
|
+
'<span style="color:#555">' + r.latencyMs + 'ms</span> ' +
|
|
65937
|
+
'<span style="color:#555;font-size:0.6rem">' + (r.user || '') + '</span></div>';
|
|
65938
|
+
}).join('');
|
|
65939
|
+
} catch {}
|
|
65940
|
+
}
|
|
65941
|
+
|
|
65942
|
+
// Daemon monitor (on dashboard tab)
|
|
65943
|
+
async function loadDaemons() {
|
|
65944
|
+
// The daemon registry is server-side (TUI). We can't query it via REST yet.
|
|
65945
|
+
// Show running jobs as a proxy for active processes.
|
|
65946
|
+
try {
|
|
65947
|
+
const r = await fetch('/v1/runs?status=running', { headers: headers() });
|
|
65948
|
+
const d = await r.json();
|
|
65949
|
+
const el = document.getElementById('dashboard-daemons');
|
|
65950
|
+
if (!d.runs?.length) {
|
|
65951
|
+
el.innerHTML = '<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;color:#555;font-size:0.7rem">No active processes</div>';
|
|
65952
|
+
return;
|
|
65953
|
+
}
|
|
65954
|
+
el.innerHTML = '<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:8px">Active Processes</h3>' +
|
|
65955
|
+
d.runs.map(j =>
|
|
65956
|
+
'<div style="background:#1e1e22;border-left:2px solid #b2920a;padding:6px 10px;margin:4px 0;font-size:0.72rem">' +
|
|
65957
|
+
'<span style="color:#b2920a">' + (j.id||'').slice(0,12) + '</span> ' +
|
|
65958
|
+
'<span style="color:#4ec94e">running</span> ' +
|
|
65959
|
+
'<span style="color:#888">' + (j.task||'').slice(0,50) + '</span></div>'
|
|
65960
|
+
).join('');
|
|
65961
|
+
} catch {}
|
|
65793
65962
|
}
|
|
65794
65963
|
|
|
65795
65964
|
// Agent task
|
|
@@ -65892,24 +66061,45 @@ async function loadDashboard() {
|
|
|
65892
66061
|
'<div style="color:#555;font-size:0.6rem">VERSION</div>' +
|
|
65893
66062
|
'<div style="color:#b0b0b0;font-size:0.8rem">' + d.version + '</div></div>';
|
|
65894
66063
|
} catch {}
|
|
65895
|
-
// Usage
|
|
66064
|
+
// Usage \u2014 per-provider breakdown with persistent totals
|
|
65896
66065
|
try {
|
|
65897
66066
|
const r = await fetch('/v1/usage', { headers: headers() });
|
|
65898
66067
|
const d = await r.json();
|
|
66068
|
+
const ps = d.persistent?.byProvider || {};
|
|
66069
|
+
let providerCards = '';
|
|
66070
|
+
for (const [label, stats] of Object.entries(ps)) {
|
|
66071
|
+
const s = stats;
|
|
66072
|
+
providerCards +=
|
|
66073
|
+
'<div style="background:#1e1e22;border-left:2px solid #b2920a;padding:8px 12px;margin:4px 0">' +
|
|
66074
|
+
'<div style="color:#b2920a;font-size:0.7rem;font-weight:bold">' + label + '</div>' +
|
|
66075
|
+
'<div style="display:flex;gap:16px;margin-top:4px">' +
|
|
66076
|
+
'<span style="color:#555;font-size:0.65rem">in: <span style="color:#b0b0b0">' + (s.tokensIn || 0).toLocaleString() + '</span></span>' +
|
|
66077
|
+
'<span style="color:#555;font-size:0.65rem">out: <span style="color:#b0b0b0">' + (s.tokensOut || 0).toLocaleString() + '</span></span>' +
|
|
66078
|
+
'<span style="color:#555;font-size:0.65rem">reqs: <span style="color:#b0b0b0">' + (s.requests || 0).toLocaleString() + '</span></span>' +
|
|
66079
|
+
'</div></div>';
|
|
66080
|
+
}
|
|
66081
|
+
const totalIn = d.persistent?.totalIn || d.totalTokensIn || 0;
|
|
66082
|
+
const totalOut = d.persistent?.totalOut || d.totalTokensOut || 0;
|
|
65899
66083
|
document.getElementById('dashboard-usage').innerHTML =
|
|
65900
|
-
'<
|
|
66084
|
+
'<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:8px">Token Usage by Provider (persistent)</h3>' +
|
|
66085
|
+
'<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:8px">' +
|
|
66086
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1">' +
|
|
66087
|
+
'<div style="color:#555;font-size:0.6rem">TOTAL IN</div>' +
|
|
66088
|
+
'<div style="color:#b2920a;font-size:0.9rem;font-weight:bold">' + totalIn.toLocaleString() + '</div></div>' +
|
|
65901
66089
|
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1">' +
|
|
65902
|
-
'<div style="color:#555;font-size:0.6rem">
|
|
65903
|
-
'<div style="color:#b2920a;font-size:0.
|
|
66090
|
+
'<div style="color:#555;font-size:0.6rem">TOTAL OUT</div>' +
|
|
66091
|
+
'<div style="color:#b2920a;font-size:0.9rem;font-weight:bold">' + totalOut.toLocaleString() + '</div></div>' +
|
|
65904
66092
|
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;flex:1">' +
|
|
65905
|
-
'<div style="color:#555;font-size:0.6rem">
|
|
65906
|
-
'<div style="color:#b2920a;font-size:0.
|
|
65907
|
-
'</div>'
|
|
66093
|
+
'<div style="color:#555;font-size:0.6rem">TOTAL REQUESTS</div>' +
|
|
66094
|
+
'<div style="color:#b2920a;font-size:0.9rem;font-weight:bold">' + (d.persistent?.totalRequests || 0).toLocaleString() + '</div></div>' +
|
|
66095
|
+
'</div>' +
|
|
66096
|
+
(providerCards || '<div style="color:#555;font-size:0.7rem">No provider usage recorded yet</div>');
|
|
65908
66097
|
} catch {}
|
|
65909
66098
|
}
|
|
65910
66099
|
|
|
65911
66100
|
async function loadJobs() {
|
|
65912
66101
|
loadDashboard();
|
|
66102
|
+
loadDaemons();
|
|
65913
66103
|
const list = document.getElementById('jobs-list');
|
|
65914
66104
|
try {
|
|
65915
66105
|
const r = await fetch('/v1/runs', { headers: headers() });
|
|
@@ -66069,25 +66259,101 @@ var init_auth_oidc = __esm({
|
|
|
66069
66259
|
}
|
|
66070
66260
|
});
|
|
66071
66261
|
|
|
66072
|
-
// packages/cli/dist/api/
|
|
66073
|
-
import {
|
|
66262
|
+
// packages/cli/dist/api/usage-tracker.js
|
|
66263
|
+
import { mkdirSync as mkdirSync27, readFileSync as readFileSync42, writeFileSync as writeFileSync25, existsSync as existsSync53 } from "node:fs";
|
|
66074
66264
|
import { join as join70 } from "node:path";
|
|
66265
|
+
function initUsageTracker(oaDir) {
|
|
66266
|
+
const dir = join70(oaDir, "usage");
|
|
66267
|
+
mkdirSync27(dir, { recursive: true });
|
|
66268
|
+
usageFile = join70(dir, "token-usage.json");
|
|
66269
|
+
try {
|
|
66270
|
+
if (existsSync53(usageFile)) {
|
|
66271
|
+
store = JSON.parse(readFileSync42(usageFile, "utf-8"));
|
|
66272
|
+
}
|
|
66273
|
+
} catch {
|
|
66274
|
+
store = { providers: {}, lastSaved: "" };
|
|
66275
|
+
}
|
|
66276
|
+
initialized2 = true;
|
|
66277
|
+
setInterval(() => {
|
|
66278
|
+
if (dirty)
|
|
66279
|
+
flush();
|
|
66280
|
+
}, 3e4);
|
|
66281
|
+
}
|
|
66282
|
+
function ensureProvider(label) {
|
|
66283
|
+
if (!store.providers[label]) {
|
|
66284
|
+
store.providers[label] = { tokensIn: 0, tokensOut: 0, requests: 0, byDay: {} };
|
|
66285
|
+
}
|
|
66286
|
+
return store.providers[label];
|
|
66287
|
+
}
|
|
66288
|
+
function today() {
|
|
66289
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
66290
|
+
}
|
|
66291
|
+
function trackTokens(provider, tokensIn, tokensOut) {
|
|
66292
|
+
if (!initialized2)
|
|
66293
|
+
return;
|
|
66294
|
+
const p = ensureProvider(provider);
|
|
66295
|
+
p.tokensIn += tokensIn;
|
|
66296
|
+
p.tokensOut += tokensOut;
|
|
66297
|
+
p.requests++;
|
|
66298
|
+
const day = today();
|
|
66299
|
+
if (!p.byDay[day])
|
|
66300
|
+
p.byDay[day] = { in: 0, out: 0, reqs: 0 };
|
|
66301
|
+
p.byDay[day].in += tokensIn;
|
|
66302
|
+
p.byDay[day].out += tokensOut;
|
|
66303
|
+
p.byDay[day].reqs++;
|
|
66304
|
+
dirty = true;
|
|
66305
|
+
}
|
|
66306
|
+
function flush() {
|
|
66307
|
+
if (!initialized2 || !dirty)
|
|
66308
|
+
return;
|
|
66309
|
+
try {
|
|
66310
|
+
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
66311
|
+
writeFileSync25(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
66312
|
+
dirty = false;
|
|
66313
|
+
} catch {
|
|
66314
|
+
}
|
|
66315
|
+
}
|
|
66316
|
+
function getUsageSummary() {
|
|
66317
|
+
let totalIn = 0, totalOut = 0, totalRequests = 0;
|
|
66318
|
+
const byProvider = {};
|
|
66319
|
+
for (const [label, p] of Object.entries(store.providers)) {
|
|
66320
|
+
totalIn += p.tokensIn;
|
|
66321
|
+
totalOut += p.tokensOut;
|
|
66322
|
+
totalRequests += p.requests;
|
|
66323
|
+
byProvider[label] = { tokensIn: p.tokensIn, tokensOut: p.tokensOut, requests: p.requests };
|
|
66324
|
+
}
|
|
66325
|
+
return { totalIn, totalOut, totalRequests, byProvider };
|
|
66326
|
+
}
|
|
66327
|
+
var store, usageFile, dirty, initialized2;
|
|
66328
|
+
var init_usage_tracker = __esm({
|
|
66329
|
+
"packages/cli/dist/api/usage-tracker.js"() {
|
|
66330
|
+
"use strict";
|
|
66331
|
+
store = { providers: {}, lastSaved: "" };
|
|
66332
|
+
usageFile = "";
|
|
66333
|
+
dirty = false;
|
|
66334
|
+
initialized2 = false;
|
|
66335
|
+
}
|
|
66336
|
+
});
|
|
66337
|
+
|
|
66338
|
+
// packages/cli/dist/api/profiles.js
|
|
66339
|
+
import { existsSync as existsSync54, readFileSync as readFileSync43, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, readdirSync as readdirSync20, unlinkSync as unlinkSync12 } from "node:fs";
|
|
66340
|
+
import { join as join71 } from "node:path";
|
|
66075
66341
|
import { homedir as homedir18 } from "node:os";
|
|
66076
66342
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes15, scryptSync as scryptSync3, createHash as createHash5 } from "node:crypto";
|
|
66077
66343
|
function globalProfileDir() {
|
|
66078
|
-
return
|
|
66344
|
+
return join71(homedir18(), ".open-agents", "profiles");
|
|
66079
66345
|
}
|
|
66080
66346
|
function projectProfileDir(projectDir) {
|
|
66081
|
-
return
|
|
66347
|
+
return join71(projectDir || process.cwd(), ".oa", "profiles");
|
|
66082
66348
|
}
|
|
66083
66349
|
function listProfiles(projectDir) {
|
|
66084
66350
|
const result = [];
|
|
66085
66351
|
const seen = /* @__PURE__ */ new Set();
|
|
66086
66352
|
const projDir = projectProfileDir(projectDir);
|
|
66087
|
-
if (
|
|
66353
|
+
if (existsSync54(projDir)) {
|
|
66088
66354
|
for (const f of readdirSync20(projDir).filter((f2) => f2.endsWith(".json"))) {
|
|
66089
66355
|
try {
|
|
66090
|
-
const raw = JSON.parse(
|
|
66356
|
+
const raw = JSON.parse(readFileSync43(join71(projDir, f), "utf8"));
|
|
66091
66357
|
const name = f.replace(".json", "");
|
|
66092
66358
|
seen.add(name);
|
|
66093
66359
|
result.push({
|
|
@@ -66101,13 +66367,13 @@ function listProfiles(projectDir) {
|
|
|
66101
66367
|
}
|
|
66102
66368
|
}
|
|
66103
66369
|
const globDir = globalProfileDir();
|
|
66104
|
-
if (
|
|
66370
|
+
if (existsSync54(globDir)) {
|
|
66105
66371
|
for (const f of readdirSync20(globDir).filter((f2) => f2.endsWith(".json"))) {
|
|
66106
66372
|
const name = f.replace(".json", "");
|
|
66107
66373
|
if (seen.has(name))
|
|
66108
66374
|
continue;
|
|
66109
66375
|
try {
|
|
66110
|
-
const raw = JSON.parse(
|
|
66376
|
+
const raw = JSON.parse(readFileSync43(join71(globDir, f), "utf8"));
|
|
66111
66377
|
result.push({
|
|
66112
66378
|
name,
|
|
66113
66379
|
description: raw.description || "",
|
|
@@ -66122,12 +66388,12 @@ function listProfiles(projectDir) {
|
|
|
66122
66388
|
}
|
|
66123
66389
|
function loadProfile(name, password, projectDir) {
|
|
66124
66390
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66125
|
-
const projPath =
|
|
66126
|
-
const globPath =
|
|
66127
|
-
const filePath =
|
|
66391
|
+
const projPath = join71(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
66392
|
+
const globPath = join71(globalProfileDir(), `${sanitized}.json`);
|
|
66393
|
+
const filePath = existsSync54(projPath) ? projPath : existsSync54(globPath) ? globPath : null;
|
|
66128
66394
|
if (!filePath)
|
|
66129
66395
|
return null;
|
|
66130
|
-
const raw = JSON.parse(
|
|
66396
|
+
const raw = JSON.parse(readFileSync43(filePath, "utf8"));
|
|
66131
66397
|
if (raw.encrypted === true) {
|
|
66132
66398
|
if (!password)
|
|
66133
66399
|
return null;
|
|
@@ -66137,23 +66403,23 @@ function loadProfile(name, password, projectDir) {
|
|
|
66137
66403
|
}
|
|
66138
66404
|
function saveProfile(profile, password, scope = "global", projectDir) {
|
|
66139
66405
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
66140
|
-
|
|
66406
|
+
mkdirSync28(dir, { recursive: true });
|
|
66141
66407
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66142
|
-
const filePath =
|
|
66408
|
+
const filePath = join71(dir, `${sanitized}.json`);
|
|
66143
66409
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
66144
66410
|
if (password) {
|
|
66145
66411
|
const encrypted = encryptProfile(profile, password);
|
|
66146
|
-
|
|
66412
|
+
writeFileSync26(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
66147
66413
|
} else {
|
|
66148
66414
|
profile.encrypted = false;
|
|
66149
|
-
|
|
66415
|
+
writeFileSync26(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
|
|
66150
66416
|
}
|
|
66151
66417
|
}
|
|
66152
66418
|
function deleteProfile(name, scope = "global", projectDir) {
|
|
66153
66419
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
66154
66420
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
66155
|
-
const filePath =
|
|
66156
|
-
if (
|
|
66421
|
+
const filePath = join71(dir, `${sanitized}.json`);
|
|
66422
|
+
if (existsSync54(filePath)) {
|
|
66157
66423
|
unlinkSync12(filePath);
|
|
66158
66424
|
return true;
|
|
66159
66425
|
}
|
|
@@ -66246,22 +66512,22 @@ import * as http from "node:http";
|
|
|
66246
66512
|
import * as https from "node:https";
|
|
66247
66513
|
import { createRequire as createRequire3 } from "node:module";
|
|
66248
66514
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
66249
|
-
import { dirname as dirname21, join as
|
|
66515
|
+
import { dirname as dirname21, join as join72, resolve as resolve31 } from "node:path";
|
|
66250
66516
|
import { spawn as spawn21 } from "node:child_process";
|
|
66251
|
-
import { mkdirSync as
|
|
66517
|
+
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync27, readFileSync as readFileSync44, readdirSync as readdirSync21, existsSync as existsSync55 } from "node:fs";
|
|
66252
66518
|
import { randomBytes as randomBytes16, randomUUID as randomUUID4 } from "node:crypto";
|
|
66253
66519
|
function getVersion3() {
|
|
66254
66520
|
try {
|
|
66255
66521
|
const require2 = createRequire3(import.meta.url);
|
|
66256
66522
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
66257
66523
|
const candidates = [
|
|
66258
|
-
|
|
66259
|
-
|
|
66260
|
-
|
|
66524
|
+
join72(thisDir, "..", "package.json"),
|
|
66525
|
+
join72(thisDir, "..", "..", "package.json"),
|
|
66526
|
+
join72(thisDir, "..", "..", "..", "package.json")
|
|
66261
66527
|
];
|
|
66262
66528
|
for (const pkgPath of candidates) {
|
|
66263
66529
|
try {
|
|
66264
|
-
if (!
|
|
66530
|
+
if (!existsSync55(pkgPath))
|
|
66265
66531
|
continue;
|
|
66266
66532
|
const pkg = require2(pkgPath);
|
|
66267
66533
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
@@ -66277,14 +66543,14 @@ function getVersion3() {
|
|
|
66277
66543
|
}
|
|
66278
66544
|
function getEndpointUsage(label) {
|
|
66279
66545
|
let u = endpointUsage.get(label);
|
|
66280
|
-
const
|
|
66546
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
66281
66547
|
if (!u) {
|
|
66282
|
-
u = { requestTimestamps: [], tokensToday: 0, tokenDate:
|
|
66548
|
+
u = { requestTimestamps: [], tokensToday: 0, tokenDate: today2 };
|
|
66283
66549
|
endpointUsage.set(label, u);
|
|
66284
66550
|
}
|
|
66285
|
-
if (u.tokenDate !==
|
|
66551
|
+
if (u.tokenDate !== today2) {
|
|
66286
66552
|
u.tokensToday = 0;
|
|
66287
|
-
u.tokenDate =
|
|
66553
|
+
u.tokenDate = today2;
|
|
66288
66554
|
}
|
|
66289
66555
|
return u;
|
|
66290
66556
|
}
|
|
@@ -66562,29 +66828,29 @@ function ollamaStream(ollamaUrl, path, method, body, onData, onEnd, onError) {
|
|
|
66562
66828
|
}
|
|
66563
66829
|
function jobsDir() {
|
|
66564
66830
|
const root = resolve31(process.cwd());
|
|
66565
|
-
const dir =
|
|
66566
|
-
|
|
66831
|
+
const dir = join72(root, ".oa", "jobs");
|
|
66832
|
+
mkdirSync29(dir, { recursive: true });
|
|
66567
66833
|
return dir;
|
|
66568
66834
|
}
|
|
66569
66835
|
function loadJob(id) {
|
|
66570
|
-
const file =
|
|
66571
|
-
if (!
|
|
66836
|
+
const file = join72(jobsDir(), `${id}.json`);
|
|
66837
|
+
if (!existsSync55(file))
|
|
66572
66838
|
return null;
|
|
66573
66839
|
try {
|
|
66574
|
-
return JSON.parse(
|
|
66840
|
+
return JSON.parse(readFileSync44(file, "utf-8"));
|
|
66575
66841
|
} catch {
|
|
66576
66842
|
return null;
|
|
66577
66843
|
}
|
|
66578
66844
|
}
|
|
66579
66845
|
function listJobs() {
|
|
66580
66846
|
const dir = jobsDir();
|
|
66581
|
-
if (!
|
|
66847
|
+
if (!existsSync55(dir))
|
|
66582
66848
|
return [];
|
|
66583
66849
|
const files = readdirSync21(dir).filter((f) => f.endsWith(".json")).sort();
|
|
66584
66850
|
const jobs = [];
|
|
66585
66851
|
for (const file of files) {
|
|
66586
66852
|
try {
|
|
66587
|
-
jobs.push(JSON.parse(
|
|
66853
|
+
jobs.push(JSON.parse(readFileSync44(join72(dir, file), "utf-8")));
|
|
66588
66854
|
} catch {
|
|
66589
66855
|
}
|
|
66590
66856
|
}
|
|
@@ -66595,10 +66861,10 @@ function getKeyUsage(user) {
|
|
|
66595
66861
|
perKeyUsage.set(user, { requestTimestamps: [], tokensToday: 0, tokenDate: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), activeJobs: 0 });
|
|
66596
66862
|
}
|
|
66597
66863
|
const u = perKeyUsage.get(user);
|
|
66598
|
-
const
|
|
66599
|
-
if (u.tokenDate !==
|
|
66864
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
66865
|
+
if (u.tokenDate !== today2) {
|
|
66600
66866
|
u.tokensToday = 0;
|
|
66601
|
-
u.tokenDate =
|
|
66867
|
+
u.tokenDate = today2;
|
|
66602
66868
|
}
|
|
66603
66869
|
return u;
|
|
66604
66870
|
}
|
|
@@ -66777,8 +67043,11 @@ async function handleV1ChatCompletions(req, res, ollamaUrl) {
|
|
|
66777
67043
|
const parsed = JSON.parse(result.body);
|
|
66778
67044
|
if (parsed.usage) {
|
|
66779
67045
|
const totalTok = (parsed.usage.prompt_tokens ?? 0) + (parsed.usage.completion_tokens ?? 0);
|
|
66780
|
-
|
|
66781
|
-
|
|
67046
|
+
const _pIn = parsed.usage.prompt_tokens ?? 0;
|
|
67047
|
+
const _pOut = parsed.usage.completion_tokens ?? 0;
|
|
67048
|
+
metrics.totalTokensIn += _pIn;
|
|
67049
|
+
metrics.totalTokensOut += _pOut;
|
|
67050
|
+
trackTokens(route?.endpoint?.label ?? "local", _pIn, _pOut);
|
|
66782
67051
|
if (route?.endpoint)
|
|
66783
67052
|
recordEndpointUsage(route.endpoint.label, totalTok);
|
|
66784
67053
|
}
|
|
@@ -66816,6 +67085,7 @@ async function handleV1ChatCompletions(req, res, ollamaUrl) {
|
|
|
66816
67085
|
metrics.totalTokensOut += ollamaChunk.eval_count;
|
|
66817
67086
|
if (ollamaChunk.prompt_eval_count)
|
|
66818
67087
|
metrics.totalTokensIn += ollamaChunk.prompt_eval_count;
|
|
67088
|
+
trackTokens("local", ollamaChunk.prompt_eval_count ?? 0, ollamaChunk.eval_count ?? 0);
|
|
66819
67089
|
const doneEvent = {
|
|
66820
67090
|
id: chatId,
|
|
66821
67091
|
object: "chat.completion.chunk",
|
|
@@ -66866,6 +67136,7 @@ async function handleV1ChatCompletions(req, res, ollamaUrl) {
|
|
|
66866
67136
|
metrics.totalTokensOut += ollamaChunk.eval_count;
|
|
66867
67137
|
if (ollamaChunk.prompt_eval_count)
|
|
66868
67138
|
metrics.totalTokensIn += ollamaChunk.prompt_eval_count;
|
|
67139
|
+
trackTokens("local", ollamaChunk.prompt_eval_count ?? 0, ollamaChunk.eval_count ?? 0);
|
|
66869
67140
|
res.write(`data: ${JSON.stringify({
|
|
66870
67141
|
id: chatId,
|
|
66871
67142
|
object: "chat.completion.chunk",
|
|
@@ -66905,6 +67176,7 @@ async function handleV1ChatCompletions(req, res, ollamaUrl) {
|
|
|
66905
67176
|
metrics.totalTokensOut += ollamaResp.eval_count;
|
|
66906
67177
|
if (ollamaResp.prompt_eval_count)
|
|
66907
67178
|
metrics.totalTokensIn += ollamaResp.prompt_eval_count;
|
|
67179
|
+
trackTokens("local", ollamaResp.prompt_eval_count ?? 0, ollamaResp.eval_count ?? 0);
|
|
66908
67180
|
const chatId = `chatcmpl-${randomBytes16(12).toString("hex")}`;
|
|
66909
67181
|
const openaiResponse = {
|
|
66910
67182
|
id: chatId,
|
|
@@ -67026,8 +67298,8 @@ async function handleV1Run(req, res) {
|
|
|
67026
67298
|
if (workingDir) {
|
|
67027
67299
|
cwd4 = resolve31(workingDir);
|
|
67028
67300
|
} else if (isolate) {
|
|
67029
|
-
const wsDir =
|
|
67030
|
-
|
|
67301
|
+
const wsDir = join72(dir, "..", "workspaces", id);
|
|
67302
|
+
mkdirSync29(wsDir, { recursive: true });
|
|
67031
67303
|
cwd4 = wsDir;
|
|
67032
67304
|
} else {
|
|
67033
67305
|
cwd4 = resolve31(process.cwd());
|
|
@@ -67099,7 +67371,7 @@ async function handleV1Run(req, res) {
|
|
|
67099
67371
|
});
|
|
67100
67372
|
child.unref();
|
|
67101
67373
|
job.pid = child.pid ?? 0;
|
|
67102
|
-
|
|
67374
|
+
writeFileSync27(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67103
67375
|
runningProcesses.set(id, child);
|
|
67104
67376
|
if (streamMode) {
|
|
67105
67377
|
res.writeHead(200, {
|
|
@@ -67126,7 +67398,7 @@ async function handleV1Run(req, res) {
|
|
|
67126
67398
|
job.status = code === 0 ? "completed" : "failed";
|
|
67127
67399
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67128
67400
|
try {
|
|
67129
|
-
|
|
67401
|
+
writeFileSync27(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67130
67402
|
} catch {
|
|
67131
67403
|
}
|
|
67132
67404
|
runningProcesses.delete(id);
|
|
@@ -67157,7 +67429,7 @@ async function handleV1Run(req, res) {
|
|
|
67157
67429
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67158
67430
|
}
|
|
67159
67431
|
try {
|
|
67160
|
-
|
|
67432
|
+
writeFileSync27(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67161
67433
|
} catch {
|
|
67162
67434
|
}
|
|
67163
67435
|
runningProcesses.delete(id);
|
|
@@ -67206,7 +67478,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
67206
67478
|
job.error = "Aborted via API";
|
|
67207
67479
|
const dir = jobsDir();
|
|
67208
67480
|
try {
|
|
67209
|
-
|
|
67481
|
+
writeFileSync27(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
67210
67482
|
} catch {
|
|
67211
67483
|
}
|
|
67212
67484
|
runningProcesses.delete(id);
|
|
@@ -67492,7 +67764,14 @@ async function handleRequest(req, res, ollamaUrl, verbose) {
|
|
|
67492
67764
|
limits: ep.limits ?? { maxRequestsPerMinute: "unlimited", maxTokensPerDay: "unlimited" }
|
|
67493
67765
|
};
|
|
67494
67766
|
}
|
|
67495
|
-
|
|
67767
|
+
const persistent = getUsageSummary();
|
|
67768
|
+
jsonResponse(res, 200, {
|
|
67769
|
+
usage: usageData,
|
|
67770
|
+
totalTokensIn: metrics.totalTokensIn,
|
|
67771
|
+
totalTokensOut: metrics.totalTokensOut,
|
|
67772
|
+
persistent
|
|
67773
|
+
// survives restarts
|
|
67774
|
+
});
|
|
67496
67775
|
return;
|
|
67497
67776
|
}
|
|
67498
67777
|
if (pathname === "/v1/commands" && method === "GET") {
|
|
@@ -67641,19 +67920,20 @@ function startApiServer(options = {}) {
|
|
|
67641
67920
|
const config = loadConfig();
|
|
67642
67921
|
const ollamaUrl = options.ollamaUrl ?? config.backendUrl;
|
|
67643
67922
|
const cwd4 = process.cwd();
|
|
67644
|
-
initAuditLog(
|
|
67923
|
+
initAuditLog(join72(cwd4, ".oa"));
|
|
67924
|
+
initUsageTracker(join72(cwd4, ".oa"));
|
|
67645
67925
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
67646
67926
|
if (retentionDays > 0) {
|
|
67647
67927
|
try {
|
|
67648
|
-
const jobsDir3 =
|
|
67649
|
-
if (
|
|
67928
|
+
const jobsDir3 = join72(cwd4, ".oa", "jobs");
|
|
67929
|
+
if (existsSync55(jobsDir3)) {
|
|
67650
67930
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
67651
67931
|
for (const f of readdirSync21(jobsDir3)) {
|
|
67652
67932
|
if (!f.endsWith(".json"))
|
|
67653
67933
|
continue;
|
|
67654
67934
|
try {
|
|
67655
|
-
const jobPath =
|
|
67656
|
-
const job = JSON.parse(
|
|
67935
|
+
const jobPath = join72(jobsDir3, f);
|
|
67936
|
+
const job = JSON.parse(readFileSync44(jobPath, "utf-8"));
|
|
67657
67937
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
67658
67938
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
67659
67939
|
const { unlinkSync: unlinkSync13 } = __require("node:fs");
|
|
@@ -67673,8 +67953,8 @@ function startApiServer(options = {}) {
|
|
|
67673
67953
|
if (useTls) {
|
|
67674
67954
|
try {
|
|
67675
67955
|
tlsOpts = {
|
|
67676
|
-
cert:
|
|
67677
|
-
key:
|
|
67956
|
+
cert: readFileSync44(resolve31(tlsCert)),
|
|
67957
|
+
key: readFileSync44(resolve31(tlsKey))
|
|
67678
67958
|
};
|
|
67679
67959
|
} catch (e) {
|
|
67680
67960
|
log2(`
|
|
@@ -67824,6 +68104,7 @@ var init_serve = __esm({
|
|
|
67824
68104
|
init_logger();
|
|
67825
68105
|
init_openapi();
|
|
67826
68106
|
init_auth_oidc();
|
|
68107
|
+
init_usage_tracker();
|
|
67827
68108
|
init_oa_directory();
|
|
67828
68109
|
init_render();
|
|
67829
68110
|
init_profiles();
|
|
@@ -67846,11 +68127,11 @@ var init_serve = __esm({
|
|
|
67846
68127
|
|
|
67847
68128
|
// packages/cli/dist/tui/interactive.js
|
|
67848
68129
|
import { cwd } from "node:process";
|
|
67849
|
-
import { resolve as resolve32, join as
|
|
68130
|
+
import { resolve as resolve32, join as join73, dirname as dirname22, extname as extname11 } from "node:path";
|
|
67850
68131
|
import { createRequire as createRequire4 } from "node:module";
|
|
67851
68132
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
67852
|
-
import { readFileSync as
|
|
67853
|
-
import { existsSync as
|
|
68133
|
+
import { readFileSync as readFileSync45, writeFileSync as writeFileSync28, appendFileSync as appendFileSync5, rmSync as rmSync3, readdirSync as readdirSync22, mkdirSync as mkdirSync30 } from "node:fs";
|
|
68134
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
67854
68135
|
import { execSync as execSync35 } from "node:child_process";
|
|
67855
68136
|
import { homedir as homedir19 } from "node:os";
|
|
67856
68137
|
function formatTimeAgo(date) {
|
|
@@ -67871,12 +68152,12 @@ function getVersion4() {
|
|
|
67871
68152
|
const require2 = createRequire4(import.meta.url);
|
|
67872
68153
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
67873
68154
|
const candidates = [
|
|
67874
|
-
|
|
67875
|
-
|
|
67876
|
-
|
|
68155
|
+
join73(thisDir, "..", "package.json"),
|
|
68156
|
+
join73(thisDir, "..", "..", "package.json"),
|
|
68157
|
+
join73(thisDir, "..", "..", "..", "package.json")
|
|
67877
68158
|
];
|
|
67878
68159
|
for (const pkgPath of candidates) {
|
|
67879
|
-
if (
|
|
68160
|
+
if (existsSync56(pkgPath)) {
|
|
67880
68161
|
const pkg = require2(pkgPath);
|
|
67881
68162
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
67882
68163
|
return pkg.version ?? "0.0.0";
|
|
@@ -68115,15 +68396,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
68115
68396
|
function gatherMemorySnippets(root) {
|
|
68116
68397
|
const snippets = [];
|
|
68117
68398
|
const dirs = [
|
|
68118
|
-
|
|
68119
|
-
|
|
68399
|
+
join73(root, ".oa", "memory"),
|
|
68400
|
+
join73(root, ".open-agents", "memory")
|
|
68120
68401
|
];
|
|
68121
68402
|
for (const dir of dirs) {
|
|
68122
|
-
if (!
|
|
68403
|
+
if (!existsSync56(dir))
|
|
68123
68404
|
continue;
|
|
68124
68405
|
try {
|
|
68125
68406
|
for (const f of readdirSync22(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
68126
|
-
const data = JSON.parse(
|
|
68407
|
+
const data = JSON.parse(readFileSync45(join73(dir, f), "utf-8"));
|
|
68127
68408
|
for (const val of Object.values(data)) {
|
|
68128
68409
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
68129
68410
|
if (v.length > 10)
|
|
@@ -68280,9 +68561,9 @@ ${metabolismMemories}
|
|
|
68280
68561
|
} catch {
|
|
68281
68562
|
}
|
|
68282
68563
|
try {
|
|
68283
|
-
const archeFile =
|
|
68284
|
-
if (
|
|
68285
|
-
const variants = JSON.parse(
|
|
68564
|
+
const archeFile = join73(repoRoot, ".oa", "arche", "variants.json");
|
|
68565
|
+
if (existsSync56(archeFile)) {
|
|
68566
|
+
const variants = JSON.parse(readFileSync45(archeFile, "utf8"));
|
|
68286
68567
|
if (variants.length > 0) {
|
|
68287
68568
|
let filtered = variants;
|
|
68288
68569
|
if (taskType) {
|
|
@@ -68451,9 +68732,9 @@ RULES:
|
|
|
68451
68732
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
68452
68733
|
let identityInjection = "";
|
|
68453
68734
|
try {
|
|
68454
|
-
const ikStateFile =
|
|
68455
|
-
if (
|
|
68456
|
-
const selfState = JSON.parse(
|
|
68735
|
+
const ikStateFile = join73(repoRoot, ".oa", "identity", "self-state.json");
|
|
68736
|
+
if (existsSync56(ikStateFile)) {
|
|
68737
|
+
const selfState = JSON.parse(readFileSync45(ikStateFile, "utf8"));
|
|
68457
68738
|
const lines = [
|
|
68458
68739
|
`[Identity State v${selfState.version}]`,
|
|
68459
68740
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -69097,13 +69378,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
69097
69378
|
});
|
|
69098
69379
|
}
|
|
69099
69380
|
try {
|
|
69100
|
-
const ikDir =
|
|
69101
|
-
const ikFile =
|
|
69381
|
+
const ikDir = join73(repoRoot, ".oa", "identity");
|
|
69382
|
+
const ikFile = join73(ikDir, "self-state.json");
|
|
69102
69383
|
let ikState;
|
|
69103
|
-
if (
|
|
69104
|
-
ikState = JSON.parse(
|
|
69384
|
+
if (existsSync56(ikFile)) {
|
|
69385
|
+
ikState = JSON.parse(readFileSync45(ikFile, "utf8"));
|
|
69105
69386
|
} else {
|
|
69106
|
-
|
|
69387
|
+
mkdirSync30(ikDir, { recursive: true });
|
|
69107
69388
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
69108
69389
|
ikState = {
|
|
69109
69390
|
self_id: `oa-${machineId}`,
|
|
@@ -69129,7 +69410,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
69129
69410
|
}
|
|
69130
69411
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
69131
69412
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
69132
|
-
|
|
69413
|
+
writeFileSync28(ikFile, JSON.stringify(ikState, null, 2));
|
|
69133
69414
|
} catch (ikErr) {
|
|
69134
69415
|
try {
|
|
69135
69416
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -69144,14 +69425,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
69144
69425
|
} else {
|
|
69145
69426
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
69146
69427
|
try {
|
|
69147
|
-
const ikFile =
|
|
69148
|
-
if (
|
|
69149
|
-
const ikState = JSON.parse(
|
|
69428
|
+
const ikFile = join73(repoRoot, ".oa", "identity", "self-state.json");
|
|
69429
|
+
if (existsSync56(ikFile)) {
|
|
69430
|
+
const ikState = JSON.parse(readFileSync45(ikFile, "utf8"));
|
|
69150
69431
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
69151
69432
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
69152
69433
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
69153
69434
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
69154
|
-
|
|
69435
|
+
writeFileSync28(ikFile, JSON.stringify(ikState, null, 2));
|
|
69155
69436
|
}
|
|
69156
69437
|
} catch {
|
|
69157
69438
|
}
|
|
@@ -69248,10 +69529,10 @@ async function startInteractive(config, repoPath) {
|
|
|
69248
69529
|
process.stdin.pause();
|
|
69249
69530
|
}
|
|
69250
69531
|
try {
|
|
69251
|
-
const oaDir =
|
|
69252
|
-
const nexusPidFile =
|
|
69253
|
-
if (
|
|
69254
|
-
const pid = parseInt(
|
|
69532
|
+
const oaDir = join73(repoRoot, ".oa");
|
|
69533
|
+
const nexusPidFile = join73(oaDir, "nexus", "daemon.pid");
|
|
69534
|
+
if (existsSync56(nexusPidFile)) {
|
|
69535
|
+
const pid = parseInt(readFileSync45(nexusPidFile, "utf8").trim(), 10);
|
|
69255
69536
|
if (pid > 0) {
|
|
69256
69537
|
try {
|
|
69257
69538
|
process.kill(pid, 0);
|
|
@@ -69588,7 +69869,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
69588
69869
|
let p2pGateway = null;
|
|
69589
69870
|
let peerMesh = null;
|
|
69590
69871
|
let inferenceRouter = null;
|
|
69591
|
-
const secretVault = new SecretVault(
|
|
69872
|
+
const secretVault = new SecretVault(join73(repoRoot, ".oa", "vault.enc"));
|
|
69592
69873
|
let adminSessionKey = null;
|
|
69593
69874
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
69594
69875
|
const streamRenderer = new StreamRenderer();
|
|
@@ -69811,13 +70092,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
69811
70092
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
69812
70093
|
return [hits, line];
|
|
69813
70094
|
}
|
|
69814
|
-
const HISTORY_DIR =
|
|
69815
|
-
const HISTORY_FILE =
|
|
70095
|
+
const HISTORY_DIR = join73(homedir19(), ".open-agents");
|
|
70096
|
+
const HISTORY_FILE = join73(HISTORY_DIR, "repl-history");
|
|
69816
70097
|
const MAX_HISTORY_LINES = 500;
|
|
69817
70098
|
let savedHistory = [];
|
|
69818
70099
|
try {
|
|
69819
|
-
if (
|
|
69820
|
-
const raw =
|
|
70100
|
+
if (existsSync56(HISTORY_FILE)) {
|
|
70101
|
+
const raw = readFileSync45(HISTORY_FILE, "utf8").trim();
|
|
69821
70102
|
if (raw)
|
|
69822
70103
|
savedHistory = raw.split("\n").reverse();
|
|
69823
70104
|
}
|
|
@@ -69920,12 +70201,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
69920
70201
|
if (!line.trim())
|
|
69921
70202
|
return;
|
|
69922
70203
|
try {
|
|
69923
|
-
|
|
70204
|
+
mkdirSync30(HISTORY_DIR, { recursive: true });
|
|
69924
70205
|
appendFileSync5(HISTORY_FILE, line + "\n", "utf8");
|
|
69925
70206
|
if (Math.random() < 0.02) {
|
|
69926
|
-
const all =
|
|
70207
|
+
const all = readFileSync45(HISTORY_FILE, "utf8").trim().split("\n");
|
|
69927
70208
|
if (all.length > MAX_HISTORY_LINES) {
|
|
69928
|
-
|
|
70209
|
+
writeFileSync28(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
69929
70210
|
}
|
|
69930
70211
|
}
|
|
69931
70212
|
} catch {
|
|
@@ -70109,7 +70390,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70109
70390
|
} catch {
|
|
70110
70391
|
}
|
|
70111
70392
|
try {
|
|
70112
|
-
const oaDir =
|
|
70393
|
+
const oaDir = join73(repoRoot, ".oa");
|
|
70113
70394
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
70114
70395
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
70115
70396
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -70141,7 +70422,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70141
70422
|
} catch {
|
|
70142
70423
|
}
|
|
70143
70424
|
try {
|
|
70144
|
-
const oaDir =
|
|
70425
|
+
const oaDir = join73(repoRoot, ".oa");
|
|
70145
70426
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
70146
70427
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
70147
70428
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -70182,11 +70463,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
70182
70463
|
}
|
|
70183
70464
|
try {
|
|
70184
70465
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
70185
|
-
const globalNamePath =
|
|
70466
|
+
const globalNamePath = join73(_hd(), ".open-agents", "agent-name");
|
|
70186
70467
|
let agName = "";
|
|
70187
70468
|
try {
|
|
70188
|
-
if (
|
|
70189
|
-
agName =
|
|
70469
|
+
if (existsSync56(globalNamePath))
|
|
70470
|
+
agName = readFileSync45(globalNamePath, "utf8").trim();
|
|
70190
70471
|
} catch {
|
|
70191
70472
|
}
|
|
70192
70473
|
if (!agName) {
|
|
@@ -71162,7 +71443,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71162
71443
|
kind,
|
|
71163
71444
|
targetUrl,
|
|
71164
71445
|
authKey,
|
|
71165
|
-
stateDir:
|
|
71446
|
+
stateDir: join73(repoRoot, ".oa"),
|
|
71166
71447
|
passthrough: passthrough ?? false,
|
|
71167
71448
|
loadbalance: loadbalance ?? false,
|
|
71168
71449
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -71208,7 +71489,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71208
71489
|
await tunnelGateway.stop();
|
|
71209
71490
|
tunnelGateway = null;
|
|
71210
71491
|
}
|
|
71211
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
71492
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join73(repoRoot, ".oa") });
|
|
71212
71493
|
newTunnel.on("stats", (stats) => {
|
|
71213
71494
|
statusBar.setExposeStatus({
|
|
71214
71495
|
status: stats.status,
|
|
@@ -71297,9 +71578,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71297
71578
|
if (!result.success)
|
|
71298
71579
|
throw new Error(result.error || "Connect failed");
|
|
71299
71580
|
try {
|
|
71300
|
-
const nexusPidFile =
|
|
71301
|
-
if (
|
|
71302
|
-
const pid = parseInt(
|
|
71581
|
+
const nexusPidFile = join73(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
71582
|
+
if (existsSync56(nexusPidFile)) {
|
|
71583
|
+
const pid = parseInt(readFileSync45(nexusPidFile, "utf8").trim(), 10);
|
|
71303
71584
|
if (pid > 0) {
|
|
71304
71585
|
registry.register({
|
|
71305
71586
|
name: "Nexus",
|
|
@@ -71495,10 +71776,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71495
71776
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
71496
71777
|
}
|
|
71497
71778
|
try {
|
|
71498
|
-
const nexusDir =
|
|
71499
|
-
const pidFile =
|
|
71500
|
-
if (
|
|
71501
|
-
const pid = parseInt(
|
|
71779
|
+
const nexusDir = join73(repoRoot, OA_DIR, "nexus");
|
|
71780
|
+
const pidFile = join73(nexusDir, "daemon.pid");
|
|
71781
|
+
if (existsSync56(pidFile)) {
|
|
71782
|
+
const pid = parseInt(readFileSync45(pidFile, "utf8").trim(), 10);
|
|
71502
71783
|
if (pid > 0) {
|
|
71503
71784
|
try {
|
|
71504
71785
|
if (process.platform === "win32") {
|
|
@@ -71520,13 +71801,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71520
71801
|
} catch {
|
|
71521
71802
|
}
|
|
71522
71803
|
try {
|
|
71523
|
-
const voiceDir2 =
|
|
71804
|
+
const voiceDir2 = join73(homedir19(), ".open-agents", "voice");
|
|
71524
71805
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
71525
71806
|
for (const pf of voicePidFiles) {
|
|
71526
|
-
const pidPath =
|
|
71527
|
-
if (
|
|
71807
|
+
const pidPath = join73(voiceDir2, pf);
|
|
71808
|
+
if (existsSync56(pidPath)) {
|
|
71528
71809
|
try {
|
|
71529
|
-
const pid = parseInt(
|
|
71810
|
+
const pid = parseInt(readFileSync45(pidPath, "utf8").trim(), 10);
|
|
71530
71811
|
if (pid > 0) {
|
|
71531
71812
|
if (process.platform === "win32") {
|
|
71532
71813
|
try {
|
|
@@ -71550,8 +71831,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71550
71831
|
execSync35(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
71551
71832
|
} catch {
|
|
71552
71833
|
}
|
|
71553
|
-
const oaPath =
|
|
71554
|
-
if (
|
|
71834
|
+
const oaPath = join73(repoRoot, OA_DIR);
|
|
71835
|
+
if (existsSync56(oaPath)) {
|
|
71555
71836
|
let deleted = false;
|
|
71556
71837
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
71557
71838
|
try {
|
|
@@ -71634,19 +71915,19 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
71634
71915
|
try {
|
|
71635
71916
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
71636
71917
|
if (isPersonaPlexRunning2()) {
|
|
71637
|
-
const ppPidFile =
|
|
71638
|
-
const ppPortFile =
|
|
71639
|
-
if (
|
|
71640
|
-
const ppPid = parseInt(
|
|
71641
|
-
const ppPort =
|
|
71918
|
+
const ppPidFile = join73(homedir19(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
71919
|
+
const ppPortFile = join73(homedir19(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
71920
|
+
if (existsSync56(ppPidFile)) {
|
|
71921
|
+
const ppPid = parseInt(readFileSync45(ppPidFile, "utf8").trim(), 10);
|
|
71922
|
+
const ppPort = existsSync56(ppPortFile) ? parseInt(readFileSync45(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
71642
71923
|
if (ppPid > 0 && !registry.daemons.has("PersonaPlex")) {
|
|
71643
71924
|
registry.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
71644
71925
|
}
|
|
71645
71926
|
}
|
|
71646
71927
|
}
|
|
71647
|
-
const nexusPidFile =
|
|
71648
|
-
if (
|
|
71649
|
-
const nPid = parseInt(
|
|
71928
|
+
const nexusPidFile = join73(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
71929
|
+
if (existsSync56(nexusPidFile)) {
|
|
71930
|
+
const nPid = parseInt(readFileSync45(nexusPidFile, "utf8").trim(), 10);
|
|
71650
71931
|
if (nPid > 0 && !registry.daemons.has("Nexus")) {
|
|
71651
71932
|
try {
|
|
71652
71933
|
process.kill(nPid, 0);
|
|
@@ -71988,8 +72269,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
71988
72269
|
}
|
|
71989
72270
|
}
|
|
71990
72271
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
71991
|
-
const isImage = isImagePath(cleanPath) &&
|
|
71992
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
72272
|
+
const isImage = isImagePath(cleanPath) && existsSync56(resolve32(repoRoot, cleanPath));
|
|
72273
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync56(resolve32(repoRoot, cleanPath));
|
|
71993
72274
|
if (activeTask) {
|
|
71994
72275
|
if (activeTask.runner.isPaused) {
|
|
71995
72276
|
activeTask.runner.resume();
|
|
@@ -71998,7 +72279,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
71998
72279
|
if (isImage) {
|
|
71999
72280
|
try {
|
|
72000
72281
|
const imgPath = resolve32(repoRoot, cleanPath);
|
|
72001
|
-
const imgBuffer =
|
|
72282
|
+
const imgBuffer = readFileSync45(imgPath);
|
|
72002
72283
|
const base64 = imgBuffer.toString("base64");
|
|
72003
72284
|
const ext = extname11(cleanPath).toLowerCase();
|
|
72004
72285
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -72213,7 +72494,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
72213
72494
|
|
|
72214
72495
|
NEW TASK: ${fullInput}`;
|
|
72215
72496
|
restoredSessionContext = null;
|
|
72216
|
-
} else if (
|
|
72497
|
+
} else if (existsSync56(join73(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
72217
72498
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
72218
72499
|
|
|
72219
72500
|
${fullInput}`;
|
|
@@ -72530,13 +72811,13 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72530
72811
|
const handle = startTask(task, config, repoRoot);
|
|
72531
72812
|
await handle.promise;
|
|
72532
72813
|
try {
|
|
72533
|
-
const ikDir =
|
|
72534
|
-
const ikFile =
|
|
72814
|
+
const ikDir = join73(repoRoot, ".oa", "identity");
|
|
72815
|
+
const ikFile = join73(ikDir, "self-state.json");
|
|
72535
72816
|
let ikState;
|
|
72536
|
-
if (
|
|
72537
|
-
ikState = JSON.parse(
|
|
72817
|
+
if (existsSync56(ikFile)) {
|
|
72818
|
+
ikState = JSON.parse(readFileSync45(ikFile, "utf8"));
|
|
72538
72819
|
} else {
|
|
72539
|
-
|
|
72820
|
+
mkdirSync30(ikDir, { recursive: true });
|
|
72540
72821
|
ikState = {
|
|
72541
72822
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
72542
72823
|
version: 1,
|
|
@@ -72558,7 +72839,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72558
72839
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
72559
72840
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
72560
72841
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
72561
|
-
|
|
72842
|
+
writeFileSync28(ikFile, JSON.stringify(ikState, null, 2));
|
|
72562
72843
|
} catch (ikErr) {
|
|
72563
72844
|
}
|
|
72564
72845
|
try {
|
|
@@ -72567,12 +72848,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72567
72848
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
72568
72849
|
} catch {
|
|
72569
72850
|
try {
|
|
72570
|
-
const archeDir =
|
|
72571
|
-
const archeFile =
|
|
72851
|
+
const archeDir = join73(repoRoot, ".oa", "arche");
|
|
72852
|
+
const archeFile = join73(archeDir, "variants.json");
|
|
72572
72853
|
let variants = [];
|
|
72573
72854
|
try {
|
|
72574
|
-
if (
|
|
72575
|
-
variants = JSON.parse(
|
|
72855
|
+
if (existsSync56(archeFile))
|
|
72856
|
+
variants = JSON.parse(readFileSync45(archeFile, "utf8"));
|
|
72576
72857
|
} catch {
|
|
72577
72858
|
}
|
|
72578
72859
|
variants.push({
|
|
@@ -72587,16 +72868,16 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72587
72868
|
});
|
|
72588
72869
|
if (variants.length > 50)
|
|
72589
72870
|
variants = variants.slice(-50);
|
|
72590
|
-
|
|
72591
|
-
|
|
72871
|
+
mkdirSync30(archeDir, { recursive: true });
|
|
72872
|
+
writeFileSync28(archeFile, JSON.stringify(variants, null, 2));
|
|
72592
72873
|
} catch {
|
|
72593
72874
|
}
|
|
72594
72875
|
}
|
|
72595
72876
|
try {
|
|
72596
|
-
const metaFile =
|
|
72597
|
-
if (
|
|
72598
|
-
const
|
|
72599
|
-
const surfaced =
|
|
72877
|
+
const metaFile = join73(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
72878
|
+
if (existsSync56(metaFile)) {
|
|
72879
|
+
const store2 = JSON.parse(readFileSync45(metaFile, "utf8"));
|
|
72880
|
+
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);
|
|
72600
72881
|
let updated = false;
|
|
72601
72882
|
for (const item of surfaced) {
|
|
72602
72883
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -72606,7 +72887,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
72606
72887
|
updated = true;
|
|
72607
72888
|
}
|
|
72608
72889
|
if (updated) {
|
|
72609
|
-
|
|
72890
|
+
writeFileSync28(metaFile, JSON.stringify(store2, null, 2));
|
|
72610
72891
|
}
|
|
72611
72892
|
}
|
|
72612
72893
|
} catch {
|
|
@@ -72659,9 +72940,9 @@ Rules:
|
|
|
72659
72940
|
try {
|
|
72660
72941
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
72661
72942
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
72662
|
-
const dbDir =
|
|
72663
|
-
|
|
72664
|
-
const db = initDb2(
|
|
72943
|
+
const dbDir = join73(repoRoot, ".oa", "memory");
|
|
72944
|
+
mkdirSync30(dbDir, { recursive: true });
|
|
72945
|
+
const db = initDb2(join73(dbDir, "structured.db"));
|
|
72665
72946
|
const memStore = new ProceduralMemoryStore2(db);
|
|
72666
72947
|
memStore.createWithEmbedding({
|
|
72667
72948
|
content: content.slice(0, 600),
|
|
@@ -72676,15 +72957,15 @@ Rules:
|
|
|
72676
72957
|
db.close();
|
|
72677
72958
|
} catch {
|
|
72678
72959
|
}
|
|
72679
|
-
const metaDir =
|
|
72680
|
-
const storeFile =
|
|
72681
|
-
let
|
|
72960
|
+
const metaDir = join73(repoRoot, ".oa", "memory", "metabolism");
|
|
72961
|
+
const storeFile = join73(metaDir, "store.json");
|
|
72962
|
+
let store2 = [];
|
|
72682
72963
|
try {
|
|
72683
|
-
if (
|
|
72684
|
-
|
|
72964
|
+
if (existsSync56(storeFile))
|
|
72965
|
+
store2 = JSON.parse(readFileSync45(storeFile, "utf8"));
|
|
72685
72966
|
} catch {
|
|
72686
72967
|
}
|
|
72687
|
-
|
|
72968
|
+
store2.push({
|
|
72688
72969
|
id: `mem-traj-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
|
|
72689
72970
|
type: "procedural",
|
|
72690
72971
|
content: content.slice(0, 600),
|
|
@@ -72695,29 +72976,29 @@ Rules:
|
|
|
72695
72976
|
lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
72696
72977
|
accessCount: 0
|
|
72697
72978
|
});
|
|
72698
|
-
if (
|
|
72699
|
-
|
|
72700
|
-
|
|
72701
|
-
|
|
72979
|
+
if (store2.length > 100)
|
|
72980
|
+
store2 = store2.slice(-100);
|
|
72981
|
+
mkdirSync30(metaDir, { recursive: true });
|
|
72982
|
+
writeFileSync28(storeFile, JSON.stringify(store2, null, 2));
|
|
72702
72983
|
}
|
|
72703
72984
|
}
|
|
72704
72985
|
} catch {
|
|
72705
72986
|
}
|
|
72706
72987
|
try {
|
|
72707
|
-
const cohereSettingsFile =
|
|
72988
|
+
const cohereSettingsFile = join73(repoRoot, ".oa", "settings.json");
|
|
72708
72989
|
let cohereActive = false;
|
|
72709
72990
|
try {
|
|
72710
|
-
if (
|
|
72711
|
-
const settings = JSON.parse(
|
|
72991
|
+
if (existsSync56(cohereSettingsFile)) {
|
|
72992
|
+
const settings = JSON.parse(readFileSync45(cohereSettingsFile, "utf8"));
|
|
72712
72993
|
cohereActive = settings.cohere === true;
|
|
72713
72994
|
}
|
|
72714
72995
|
} catch {
|
|
72715
72996
|
}
|
|
72716
72997
|
if (cohereActive) {
|
|
72717
|
-
const metaFile =
|
|
72718
|
-
if (
|
|
72719
|
-
const
|
|
72720
|
-
const latest =
|
|
72998
|
+
const metaFile = join73(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
72999
|
+
if (existsSync56(metaFile)) {
|
|
73000
|
+
const store2 = JSON.parse(readFileSync45(metaFile, "utf8"));
|
|
73001
|
+
const latest = store2.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
72721
73002
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
72722
73003
|
try {
|
|
72723
73004
|
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
@@ -72741,34 +73022,34 @@ Rules:
|
|
|
72741
73022
|
}
|
|
72742
73023
|
} catch (err) {
|
|
72743
73024
|
try {
|
|
72744
|
-
const ikFile =
|
|
72745
|
-
if (
|
|
72746
|
-
const ikState = JSON.parse(
|
|
73025
|
+
const ikFile = join73(repoRoot, ".oa", "identity", "self-state.json");
|
|
73026
|
+
if (existsSync56(ikFile)) {
|
|
73027
|
+
const ikState = JSON.parse(readFileSync45(ikFile, "utf8"));
|
|
72747
73028
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
72748
73029
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
72749
73030
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
72750
73031
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
72751
|
-
|
|
73032
|
+
writeFileSync28(ikFile, JSON.stringify(ikState, null, 2));
|
|
72752
73033
|
}
|
|
72753
|
-
const metaFile =
|
|
72754
|
-
if (
|
|
72755
|
-
const
|
|
72756
|
-
const surfaced =
|
|
73034
|
+
const metaFile = join73(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
73035
|
+
if (existsSync56(metaFile)) {
|
|
73036
|
+
const store2 = JSON.parse(readFileSync45(metaFile, "utf8"));
|
|
73037
|
+
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);
|
|
72757
73038
|
for (const item of surfaced) {
|
|
72758
73039
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
72759
73040
|
item.lastAccessedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
72760
73041
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
72761
73042
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
72762
73043
|
}
|
|
72763
|
-
|
|
73044
|
+
writeFileSync28(metaFile, JSON.stringify(store2, null, 2));
|
|
72764
73045
|
}
|
|
72765
73046
|
try {
|
|
72766
|
-
const archeDir =
|
|
72767
|
-
const archeFile =
|
|
73047
|
+
const archeDir = join73(repoRoot, ".oa", "arche");
|
|
73048
|
+
const archeFile = join73(archeDir, "variants.json");
|
|
72768
73049
|
let variants = [];
|
|
72769
73050
|
try {
|
|
72770
|
-
if (
|
|
72771
|
-
variants = JSON.parse(
|
|
73051
|
+
if (existsSync56(archeFile))
|
|
73052
|
+
variants = JSON.parse(readFileSync45(archeFile, "utf8"));
|
|
72772
73053
|
} catch {
|
|
72773
73054
|
}
|
|
72774
73055
|
variants.push({
|
|
@@ -72783,8 +73064,8 @@ Rules:
|
|
|
72783
73064
|
});
|
|
72784
73065
|
if (variants.length > 50)
|
|
72785
73066
|
variants = variants.slice(-50);
|
|
72786
|
-
|
|
72787
|
-
|
|
73067
|
+
mkdirSync30(archeDir, { recursive: true });
|
|
73068
|
+
writeFileSync28(archeFile, JSON.stringify(variants, null, 2));
|
|
72788
73069
|
} catch {
|
|
72789
73070
|
}
|
|
72790
73071
|
} catch {
|
|
@@ -72854,13 +73135,13 @@ __export(run_exports, {
|
|
|
72854
73135
|
});
|
|
72855
73136
|
import { resolve as resolve33 } from "node:path";
|
|
72856
73137
|
import { spawn as spawn22 } from "node:child_process";
|
|
72857
|
-
import { mkdirSync as
|
|
73138
|
+
import { mkdirSync as mkdirSync31, writeFileSync as writeFileSync29, readFileSync as readFileSync46, readdirSync as readdirSync23, existsSync as existsSync57 } from "node:fs";
|
|
72858
73139
|
import { randomBytes as randomBytes17 } from "node:crypto";
|
|
72859
|
-
import { join as
|
|
73140
|
+
import { join as join74 } from "node:path";
|
|
72860
73141
|
function jobsDir2(repoPath) {
|
|
72861
73142
|
const root = resolve33(repoPath ?? process.cwd());
|
|
72862
|
-
const dir =
|
|
72863
|
-
|
|
73143
|
+
const dir = join74(root, ".oa", "jobs");
|
|
73144
|
+
mkdirSync31(dir, { recursive: true });
|
|
72864
73145
|
return dir;
|
|
72865
73146
|
}
|
|
72866
73147
|
async function runCommand(opts, config) {
|
|
@@ -72945,7 +73226,7 @@ async function runBackground(task, config, opts) {
|
|
|
72945
73226
|
});
|
|
72946
73227
|
child.unref();
|
|
72947
73228
|
job.pid = child.pid ?? 0;
|
|
72948
|
-
|
|
73229
|
+
writeFileSync29(join74(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
72949
73230
|
let output = "";
|
|
72950
73231
|
child.stdout?.on("data", (chunk) => {
|
|
72951
73232
|
output += chunk.toString();
|
|
@@ -72961,7 +73242,7 @@ async function runBackground(task, config, opts) {
|
|
|
72961
73242
|
job.summary = result.summary;
|
|
72962
73243
|
job.durationMs = result.durationMs;
|
|
72963
73244
|
job.error = result.error;
|
|
72964
|
-
|
|
73245
|
+
writeFileSync29(join74(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
72965
73246
|
} catch {
|
|
72966
73247
|
}
|
|
72967
73248
|
});
|
|
@@ -72977,13 +73258,13 @@ async function runBackground(task, config, opts) {
|
|
|
72977
73258
|
}
|
|
72978
73259
|
function statusCommand(jobId, repoPath) {
|
|
72979
73260
|
const dir = jobsDir2(repoPath);
|
|
72980
|
-
const file =
|
|
72981
|
-
if (!
|
|
73261
|
+
const file = join74(dir, `${jobId}.json`);
|
|
73262
|
+
if (!existsSync57(file)) {
|
|
72982
73263
|
console.error(`Job not found: ${jobId}`);
|
|
72983
73264
|
console.log(`Available jobs: oa jobs`);
|
|
72984
73265
|
process.exit(1);
|
|
72985
73266
|
}
|
|
72986
|
-
const job = JSON.parse(
|
|
73267
|
+
const job = JSON.parse(readFileSync46(file, "utf-8"));
|
|
72987
73268
|
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`;
|
|
72988
73269
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
72989
73270
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -73006,7 +73287,7 @@ function jobsCommand(repoPath) {
|
|
|
73006
73287
|
console.log("Jobs:");
|
|
73007
73288
|
for (const file of files) {
|
|
73008
73289
|
try {
|
|
73009
|
-
const job = JSON.parse(
|
|
73290
|
+
const job = JSON.parse(readFileSync46(join74(dir, file), "utf-8"));
|
|
73010
73291
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
73011
73292
|
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`;
|
|
73012
73293
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -73026,7 +73307,7 @@ import { glob } from "glob";
|
|
|
73026
73307
|
import ignore from "ignore";
|
|
73027
73308
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
73028
73309
|
import { createHash as createHash6 } from "node:crypto";
|
|
73029
|
-
import { join as
|
|
73310
|
+
import { join as join75, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
73030
73311
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
73031
73312
|
var init_codebase_indexer = __esm({
|
|
73032
73313
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -73070,7 +73351,7 @@ var init_codebase_indexer = __esm({
|
|
|
73070
73351
|
const ig = ignore.default();
|
|
73071
73352
|
if (this.config.respectGitignore) {
|
|
73072
73353
|
try {
|
|
73073
|
-
const gitignoreContent = await readFile23(
|
|
73354
|
+
const gitignoreContent = await readFile23(join75(this.config.rootDir, ".gitignore"), "utf-8");
|
|
73074
73355
|
ig.add(gitignoreContent);
|
|
73075
73356
|
} catch {
|
|
73076
73357
|
}
|
|
@@ -73085,7 +73366,7 @@ var init_codebase_indexer = __esm({
|
|
|
73085
73366
|
for (const relativePath of files) {
|
|
73086
73367
|
if (ig.ignores(relativePath))
|
|
73087
73368
|
continue;
|
|
73088
|
-
const fullPath =
|
|
73369
|
+
const fullPath = join75(this.config.rootDir, relativePath);
|
|
73089
73370
|
try {
|
|
73090
73371
|
const fileStat = await stat4(fullPath);
|
|
73091
73372
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -73131,7 +73412,7 @@ var init_codebase_indexer = __esm({
|
|
|
73131
73412
|
if (!child) {
|
|
73132
73413
|
child = {
|
|
73133
73414
|
name: part,
|
|
73134
|
-
path:
|
|
73415
|
+
path: join75(current.path, part),
|
|
73135
73416
|
type: "directory",
|
|
73136
73417
|
children: []
|
|
73137
73418
|
};
|
|
@@ -73214,13 +73495,13 @@ __export(index_repo_exports, {
|
|
|
73214
73495
|
indexRepoCommand: () => indexRepoCommand
|
|
73215
73496
|
});
|
|
73216
73497
|
import { resolve as resolve34 } from "node:path";
|
|
73217
|
-
import { existsSync as
|
|
73498
|
+
import { existsSync as existsSync58, statSync as statSync17 } from "node:fs";
|
|
73218
73499
|
import { cwd as cwd2 } from "node:process";
|
|
73219
73500
|
async function indexRepoCommand(opts, _config) {
|
|
73220
73501
|
const repoRoot = resolve34(opts.repoPath ?? cwd2());
|
|
73221
73502
|
printHeader("Index Repository");
|
|
73222
73503
|
printInfo(`Indexing: ${repoRoot}`);
|
|
73223
|
-
if (!
|
|
73504
|
+
if (!existsSync58(repoRoot)) {
|
|
73224
73505
|
printError(`Path does not exist: ${repoRoot}`);
|
|
73225
73506
|
process.exit(1);
|
|
73226
73507
|
}
|
|
@@ -73472,7 +73753,7 @@ var config_exports2 = {};
|
|
|
73472
73753
|
__export(config_exports2, {
|
|
73473
73754
|
configCommand: () => configCommand
|
|
73474
73755
|
});
|
|
73475
|
-
import { join as
|
|
73756
|
+
import { join as join76, resolve as resolve35 } from "node:path";
|
|
73476
73757
|
import { homedir as homedir20 } from "node:os";
|
|
73477
73758
|
import { cwd as cwd3 } from "node:process";
|
|
73478
73759
|
function redactIfSensitive(key, value) {
|
|
@@ -73555,7 +73836,7 @@ function handleShow(opts, config) {
|
|
|
73555
73836
|
}
|
|
73556
73837
|
}
|
|
73557
73838
|
printSection("Config File");
|
|
73558
|
-
printInfo(`~/.open-agents/config.json (${
|
|
73839
|
+
printInfo(`~/.open-agents/config.json (${join76(homedir20(), ".open-agents", "config.json")})`);
|
|
73559
73840
|
printSection("Priority Chain");
|
|
73560
73841
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
73561
73842
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -73594,7 +73875,7 @@ function handleSet(opts, _config) {
|
|
|
73594
73875
|
const coerced = coerceForSettings(key, value);
|
|
73595
73876
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
73596
73877
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
73597
|
-
printInfo(`Saved to ${
|
|
73878
|
+
printInfo(`Saved to ${join76(repoRoot, ".oa", "settings.json")}`);
|
|
73598
73879
|
printInfo("This override applies only when running in this workspace.");
|
|
73599
73880
|
} catch (err) {
|
|
73600
73881
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -73737,8 +74018,8 @@ __export(eval_exports, {
|
|
|
73737
74018
|
evalCommand: () => evalCommand
|
|
73738
74019
|
});
|
|
73739
74020
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
73740
|
-
import { mkdirSync as
|
|
73741
|
-
import { join as
|
|
74021
|
+
import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync30 } from "node:fs";
|
|
74022
|
+
import { join as join77 } from "node:path";
|
|
73742
74023
|
async function evalCommand(opts, config) {
|
|
73743
74024
|
const suiteName = opts.suite ?? "basic";
|
|
73744
74025
|
const suite = SUITES[suiteName];
|
|
@@ -73863,9 +74144,9 @@ async function evalCommand(opts, config) {
|
|
|
73863
74144
|
process.exit(failed > 0 ? 1 : 0);
|
|
73864
74145
|
}
|
|
73865
74146
|
function createTempEvalRepo() {
|
|
73866
|
-
const dir =
|
|
73867
|
-
|
|
73868
|
-
|
|
74147
|
+
const dir = join77(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
74148
|
+
mkdirSync32(dir, { recursive: true });
|
|
74149
|
+
writeFileSync30(join77(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
73869
74150
|
return dir;
|
|
73870
74151
|
}
|
|
73871
74152
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -73925,7 +74206,7 @@ init_updater();
|
|
|
73925
74206
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
73926
74207
|
import { createRequire as createRequire5 } from "node:module";
|
|
73927
74208
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
73928
|
-
import { dirname as dirname23, join as
|
|
74209
|
+
import { dirname as dirname23, join as join78 } from "node:path";
|
|
73929
74210
|
|
|
73930
74211
|
// packages/cli/dist/cli.js
|
|
73931
74212
|
import { createInterface } from "node:readline";
|
|
@@ -74032,7 +74313,7 @@ init_output();
|
|
|
74032
74313
|
function getVersion5() {
|
|
74033
74314
|
try {
|
|
74034
74315
|
const require2 = createRequire5(import.meta.url);
|
|
74035
|
-
const pkgPath =
|
|
74316
|
+
const pkgPath = join78(dirname23(fileURLToPath15(import.meta.url)), "..", "package.json");
|
|
74036
74317
|
const pkg = require2(pkgPath);
|
|
74037
74318
|
return pkg.version;
|
|
74038
74319
|
} catch {
|
|
@@ -74307,12 +74588,12 @@ function crashLog(label, err) {
|
|
|
74307
74588
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
74308
74589
|
`;
|
|
74309
74590
|
try {
|
|
74310
|
-
const { appendFileSync: appendFileSync6, mkdirSync:
|
|
74311
|
-
const { join:
|
|
74591
|
+
const { appendFileSync: appendFileSync6, mkdirSync: mkdirSync33 } = __require("node:fs");
|
|
74592
|
+
const { join: join79 } = __require("node:path");
|
|
74312
74593
|
const { homedir: homedir21 } = __require("node:os");
|
|
74313
|
-
const logDir =
|
|
74314
|
-
|
|
74315
|
-
appendFileSync6(
|
|
74594
|
+
const logDir = join79(homedir21(), ".open-agents");
|
|
74595
|
+
mkdirSync33(logDir, { recursive: true });
|
|
74596
|
+
appendFileSync6(join79(logDir, "crash.log"), logLine);
|
|
74316
74597
|
} catch {
|
|
74317
74598
|
}
|
|
74318
74599
|
try {
|