open-agents-ai 0.104.31 → 0.105.1
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 +928 -588
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5639,8 +5639,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
|
|
|
5639
5639
|
const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
|
|
5640
5640
|
const filePath = join13(dir, `${name}.json`);
|
|
5641
5641
|
if (existsSync10(filePath)) {
|
|
5642
|
-
const { unlinkSync:
|
|
5643
|
-
|
|
5642
|
+
const { unlinkSync: unlinkSync10 } = __require("node:fs");
|
|
5643
|
+
unlinkSync10(filePath);
|
|
5644
5644
|
return true;
|
|
5645
5645
|
}
|
|
5646
5646
|
return false;
|
|
@@ -12555,15 +12555,16 @@ async function handleCmd(cmd) {
|
|
|
12555
12555
|
riData.auth_key = riAuthKey;
|
|
12556
12556
|
}
|
|
12557
12557
|
|
|
12558
|
+
// Streaming mode: if stream_file is provided, use stream:true and write tokens to file
|
|
12559
|
+
var riStreamFile = args.stream_file || '';
|
|
12560
|
+
var riUseStream = !!riStreamFile;
|
|
12561
|
+
|
|
12558
12562
|
// If target_peer specified, invoke directly. Otherwise auto-discover.
|
|
12559
12563
|
if (riTargetPeer) {
|
|
12560
|
-
|
|
12561
|
-
// For cross-NAT peers, libp2p dial can take 10-60s to fail while NATS
|
|
12562
|
-
// succeeds in <1s. Racing them eliminates the wait.
|
|
12563
|
-
dlog('remote_infer: invoking ' + riCapName + ' on peer ' + riTargetPeer.slice(0, 20) + ' (libp2p' + (_natsConn ? ' + NATS parallel' : '') + ')');
|
|
12564
|
+
dlog('remote_infer: invoking ' + riCapName + ' on peer ' + riTargetPeer.slice(0, 20) + ' stream=' + riUseStream + ' (libp2p' + (_natsConn ? ' + NATS parallel' : '') + ')');
|
|
12564
12565
|
try {
|
|
12565
|
-
var RI_TIMEOUT =
|
|
12566
|
-
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream:
|
|
12566
|
+
var RI_TIMEOUT = 120000;
|
|
12567
|
+
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: riUseStream, maxDurationMs: 90000 });
|
|
12567
12568
|
var riTimeoutP = new Promise(function(_, reject) { setTimeout(function() { reject(new Error('remote_infer timed out after ' + (RI_TIMEOUT / 1000) + 's')); }, RI_TIMEOUT); });
|
|
12568
12569
|
|
|
12569
12570
|
// Build race candidates \u2014 libp2p + timeout always present
|
|
@@ -12667,22 +12668,67 @@ async function handleCmd(cmd) {
|
|
|
12667
12668
|
}
|
|
12668
12669
|
|
|
12669
12670
|
// riResult and riTargetPeer are available from either path above
|
|
12670
|
-
//
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12671
|
+
// \u2500\u2500 Streaming mode: iterate AsyncGenerator, write tokens to file \u2500\u2500
|
|
12672
|
+
if (riUseStream && riResult && typeof riResult[Symbol.asyncIterator] === 'function') {
|
|
12673
|
+
// Signal OA process that streaming has started
|
|
12674
|
+
writeResp(id, { ok: true, output: JSON.stringify({ streaming: true, stream_file: riStreamFile }) });
|
|
12675
|
+
|
|
12676
|
+
var riTokenContent = '';
|
|
12677
|
+
var riToolCalls = [];
|
|
12678
|
+
var riInputTokens = 0;
|
|
12679
|
+
var riOutputTokens = 0;
|
|
12680
|
+
try {
|
|
12681
|
+
for await (var riEvt of riResult) {
|
|
12682
|
+
if (riEvt.event === 'token' && riEvt.data) {
|
|
12683
|
+
var tkn = typeof riEvt.data === 'string' ? riEvt.data : String(riEvt.data);
|
|
12684
|
+
riTokenContent += tkn;
|
|
12685
|
+
appendFileSync(riStreamFile, JSON.stringify({ type: 'token', content: tkn }) + '
|
|
12686
|
+
');
|
|
12687
|
+
} else if (riEvt.event === 'result' && riEvt.data) {
|
|
12688
|
+
// Final metadata event \u2014 parse for usage/tool_calls
|
|
12689
|
+
try {
|
|
12690
|
+
var riMeta = typeof riEvt.data === 'string' ? JSON.parse(riEvt.data) : riEvt.data;
|
|
12691
|
+
if (riMeta.usage) {
|
|
12692
|
+
riInputTokens = riMeta.usage.input_tokens || riMeta.usage.prompt_tokens || 0;
|
|
12693
|
+
riOutputTokens = riMeta.usage.output_tokens || riMeta.usage.completion_tokens || 0;
|
|
12694
|
+
}
|
|
12695
|
+
if (riMeta.choices && riMeta.choices[0] && riMeta.choices[0].message && riMeta.choices[0].message.tool_calls) {
|
|
12696
|
+
riToolCalls = riMeta.choices[0].message.tool_calls;
|
|
12697
|
+
}
|
|
12698
|
+
} catch {}
|
|
12699
|
+
}
|
|
12700
|
+
}
|
|
12701
|
+
} catch (riStreamErr) {
|
|
12702
|
+
dlog('remote_infer: stream error: ' + (riStreamErr.message || riStreamErr));
|
|
12703
|
+
}
|
|
12704
|
+
|
|
12705
|
+
// Write done sentinel with final response
|
|
12706
|
+
var riFinalPayload = {
|
|
12707
|
+
model: riModel,
|
|
12708
|
+
response: riTokenContent,
|
|
12709
|
+
choices: [{
|
|
12710
|
+
message: {
|
|
12711
|
+
content: riTokenContent,
|
|
12712
|
+
tool_calls: riToolCalls.length > 0 ? riToolCalls : undefined,
|
|
12713
|
+
},
|
|
12714
|
+
}],
|
|
12715
|
+
usage: { input_tokens: riInputTokens, output_tokens: riOutputTokens },
|
|
12716
|
+
};
|
|
12717
|
+
appendFileSync(riStreamFile, JSON.stringify({ type: 'done', result: JSON.stringify(riFinalPayload) }) + '
|
|
12718
|
+
');
|
|
12719
|
+
dlog('remote_infer: stream complete, tokens=' + riTokenContent.length + ' in=' + riInputTokens + ' out=' + riOutputTokens);
|
|
12720
|
+
break;
|
|
12721
|
+
}
|
|
12722
|
+
|
|
12723
|
+
// \u2500\u2500 Unary mode: check for errors and write response \u2500\u2500
|
|
12675
12724
|
var riIsError = false;
|
|
12676
12725
|
if (typeof riResult === 'string') {
|
|
12677
|
-
// Try to parse as JSON \u2014 if it has model+response or choices, it's valid
|
|
12678
12726
|
var riParsedCheck = null;
|
|
12679
12727
|
try { riParsedCheck = JSON.parse(riResult); } catch {}
|
|
12680
12728
|
if (riParsedCheck && typeof riParsedCheck === 'object' &&
|
|
12681
12729
|
(riParsedCheck.model || riParsedCheck.choices || riParsedCheck.response !== undefined)) {
|
|
12682
|
-
// Valid inference response \u2014 NOT an error
|
|
12683
12730
|
riIsError = false;
|
|
12684
12731
|
} else {
|
|
12685
|
-
// Non-JSON or unstructured response \u2014 check for error keywords
|
|
12686
12732
|
var riLower = riResult.toLowerCase();
|
|
12687
12733
|
if (riLower.includes('unauthorized') || riLower.includes('forbidden') ||
|
|
12688
12734
|
riLower.includes('not found') || riLower.includes('error') ||
|
|
@@ -13118,12 +13164,15 @@ async function handleCmd(cmd) {
|
|
|
13118
13164
|
|
|
13119
13165
|
var genResp, genData, output, inputTokens, outputTokens, responsePayload;
|
|
13120
13166
|
|
|
13167
|
+
// Detect if requester wants streaming (outputMode from invoke.open)
|
|
13168
|
+
var wantsStream = request.outputMode === 'stream';
|
|
13169
|
+
|
|
13121
13170
|
if (parsedReq && parsedReq.messages && Array.isArray(parsedReq.messages)) {
|
|
13122
13171
|
// Structured request \u2014 use /v1/chat/completions (supports tools + multi-turn)
|
|
13123
13172
|
var chatBody = {
|
|
13124
13173
|
model: model.name,
|
|
13125
13174
|
messages: parsedReq.messages,
|
|
13126
|
-
stream:
|
|
13175
|
+
stream: wantsStream,
|
|
13127
13176
|
};
|
|
13128
13177
|
if (parsedReq.tools && parsedReq.tools.length > 0) {
|
|
13129
13178
|
chatBody.tools = parsedReq.tools;
|
|
@@ -13134,41 +13183,117 @@ async function handleCmd(cmd) {
|
|
|
13134
13183
|
|
|
13135
13184
|
var chatHeaders = { 'Content-Type': 'application/json' };
|
|
13136
13185
|
if (isPassthrough && endpointAuth) chatHeaders['Authorization'] = 'Bearer ' + endpointAuth;
|
|
13137
|
-
dlog('expose: calling /v1/chat/completions with ' + chatBody.messages.length + ' messages, tools=' + (chatBody.tools ? chatBody.tools.length : 0) + (isPassthrough ? ' (passthrough)' : ''));
|
|
13186
|
+
dlog('expose: calling /v1/chat/completions with ' + chatBody.messages.length + ' messages, tools=' + (chatBody.tools ? chatBody.tools.length : 0) + ' stream=' + wantsStream + (isPassthrough ? ' (passthrough)' : ''));
|
|
13138
13187
|
genResp = await fetch(ollamaUrl + '/v1/chat/completions', {
|
|
13139
13188
|
method: 'POST',
|
|
13140
13189
|
headers: chatHeaders,
|
|
13141
13190
|
body: JSON.stringify(chatBody),
|
|
13142
|
-
signal: AbortSignal.timeout(210000),
|
|
13191
|
+
signal: AbortSignal.timeout(210000),
|
|
13143
13192
|
});
|
|
13144
|
-
genData = await genResp.json();
|
|
13145
|
-
dlog('expose: ollama response keys=' + Object.keys(genData).join(',') + ' choices=' + (genData.choices ? genData.choices.length : 0));
|
|
13146
|
-
|
|
13147
|
-
var chatChoices = genData.choices || [];
|
|
13148
|
-
var firstMsg = (chatChoices[0] || {}).message || {};
|
|
13149
|
-
// Strip <think>...</think> tags from content (thinking models)
|
|
13150
|
-
var rawContent = firstMsg.content || '';
|
|
13151
|
-
output = rawContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
|
|
13152
|
-
// Fallback: if content is empty but reasoning exists, use reasoning
|
|
13153
|
-
// (happens when max_tokens is too small for thinking models at temp=0)
|
|
13154
|
-
if (!output && firstMsg.reasoning) {
|
|
13155
|
-
output = firstMsg.reasoning;
|
|
13156
|
-
}
|
|
13157
|
-
// Update the choices to reflect final content
|
|
13158
|
-
if (chatChoices[0] && chatChoices[0].message) {
|
|
13159
|
-
chatChoices[0].message.content = output;
|
|
13160
|
-
}
|
|
13161
|
-
dlog('expose: rawContent_len=' + rawContent.length + ' output_len=' + output.length + ' reasoning=' + (firstMsg.reasoning ? firstMsg.reasoning.length : 0) + ' tool_calls=' + (firstMsg.tool_calls ? firstMsg.tool_calls.length : 0));
|
|
13162
|
-
inputTokens = (genData.usage || {}).prompt_tokens || 0;
|
|
13163
|
-
outputTokens = (genData.usage || {}).completion_tokens || 0;
|
|
13164
13193
|
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13194
|
+
if (wantsStream && genResp.ok && genResp.body) {
|
|
13195
|
+
// \u2500\u2500 SSE streaming path \u2014 read tokens and send as invoke.event \u2500\u2500
|
|
13196
|
+
var sseReader = genResp.body.getReader();
|
|
13197
|
+
var sseDecoder = new TextDecoder();
|
|
13198
|
+
var sseBuf = '';
|
|
13199
|
+
var sseSeq = 0;
|
|
13200
|
+
var sseContent = '';
|
|
13201
|
+
var sseToolCalls = [];
|
|
13202
|
+
inputTokens = 0;
|
|
13203
|
+
outputTokens = 0;
|
|
13204
|
+
|
|
13205
|
+
while (true) {
|
|
13206
|
+
var sseChunk = await sseReader.read();
|
|
13207
|
+
if (sseChunk.done) break;
|
|
13208
|
+
sseBuf += sseDecoder.decode(sseChunk.value, { stream: true });
|
|
13209
|
+
var sseLines = sseBuf.split('
|
|
13210
|
+
');
|
|
13211
|
+
sseBuf = sseLines.pop();
|
|
13212
|
+
|
|
13213
|
+
for (var sli = 0; sli < sseLines.length; sli++) {
|
|
13214
|
+
var sseLine = sseLines[sli];
|
|
13215
|
+
if (!sseLine.startsWith('data: ')) continue;
|
|
13216
|
+
var sseData = sseLine.slice(6).trim();
|
|
13217
|
+
if (sseData === '[DONE]') continue;
|
|
13218
|
+
|
|
13219
|
+
try {
|
|
13220
|
+
var sseObj = JSON.parse(sseData);
|
|
13221
|
+
var sseDelta = (sseObj.choices && sseObj.choices[0] && sseObj.choices[0].delta) || {};
|
|
13222
|
+
var sseToken = sseDelta.content || '';
|
|
13223
|
+
if (sseToken) {
|
|
13224
|
+
sseContent += sseToken;
|
|
13225
|
+
await swrite({
|
|
13226
|
+
type: 'invoke.event', version: 1,
|
|
13227
|
+
requestId: request.requestId, seq: sseSeq++,
|
|
13228
|
+
event: 'token', data: sseToken,
|
|
13229
|
+
});
|
|
13230
|
+
}
|
|
13231
|
+
// Collect tool calls from streaming deltas
|
|
13232
|
+
if (sseDelta.tool_calls) {
|
|
13233
|
+
for (var stci = 0; stci < sseDelta.tool_calls.length; stci++) {
|
|
13234
|
+
var stc = sseDelta.tool_calls[stci];
|
|
13235
|
+
if (stc.index !== undefined) {
|
|
13236
|
+
while (sseToolCalls.length <= stc.index) sseToolCalls.push({ id: '', function: { name: '', arguments: '' } });
|
|
13237
|
+
if (stc.id) sseToolCalls[stc.index].id = stc.id;
|
|
13238
|
+
if (stc.function) {
|
|
13239
|
+
if (stc.function.name) sseToolCalls[stc.index].function.name = stc.function.name;
|
|
13240
|
+
if (stc.function.arguments) sseToolCalls[stc.index].function.arguments += stc.function.arguments;
|
|
13241
|
+
}
|
|
13242
|
+
}
|
|
13243
|
+
}
|
|
13244
|
+
}
|
|
13245
|
+
// Capture usage from final chunk
|
|
13246
|
+
if (sseObj.usage) {
|
|
13247
|
+
inputTokens = sseObj.usage.prompt_tokens || 0;
|
|
13248
|
+
outputTokens = sseObj.usage.completion_tokens || 0;
|
|
13249
|
+
}
|
|
13250
|
+
} catch (sseParseErr) { /* skip bad SSE lines */ }
|
|
13251
|
+
}
|
|
13252
|
+
}
|
|
13253
|
+
|
|
13254
|
+
// Strip thinking tags from accumulated content
|
|
13255
|
+
output = sseContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
|
|
13256
|
+
// Build final response payload for the result event
|
|
13257
|
+
var sseChoices = [{
|
|
13258
|
+
message: {
|
|
13259
|
+
content: output,
|
|
13260
|
+
tool_calls: sseToolCalls.length > 0 ? sseToolCalls : undefined,
|
|
13261
|
+
},
|
|
13262
|
+
}];
|
|
13263
|
+
responsePayload = {
|
|
13264
|
+
model: model.name,
|
|
13265
|
+
response: output,
|
|
13266
|
+
choices: sseChoices,
|
|
13267
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
13268
|
+
pricing: entry.pricing,
|
|
13269
|
+
};
|
|
13270
|
+
} else {
|
|
13271
|
+
// \u2500\u2500 Unary path (stream: false or streaming not available) \u2500\u2500
|
|
13272
|
+
genData = await genResp.json();
|
|
13273
|
+
dlog('expose: ollama response keys=' + Object.keys(genData).join(',') + ' choices=' + (genData.choices ? genData.choices.length : 0));
|
|
13274
|
+
|
|
13275
|
+
var chatChoices = genData.choices || [];
|
|
13276
|
+
var firstMsg = (chatChoices[0] || {}).message || {};
|
|
13277
|
+
var rawContent = firstMsg.content || '';
|
|
13278
|
+
output = rawContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
|
|
13279
|
+
if (!output && firstMsg.reasoning) {
|
|
13280
|
+
output = firstMsg.reasoning;
|
|
13281
|
+
}
|
|
13282
|
+
if (chatChoices[0] && chatChoices[0].message) {
|
|
13283
|
+
chatChoices[0].message.content = output;
|
|
13284
|
+
}
|
|
13285
|
+
dlog('expose: rawContent_len=' + rawContent.length + ' output_len=' + output.length);
|
|
13286
|
+
inputTokens = (genData.usage || {}).prompt_tokens || 0;
|
|
13287
|
+
outputTokens = (genData.usage || {}).completion_tokens || 0;
|
|
13288
|
+
|
|
13289
|
+
responsePayload = {
|
|
13290
|
+
model: model.name,
|
|
13291
|
+
response: output,
|
|
13292
|
+
choices: chatChoices,
|
|
13293
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
13294
|
+
pricing: entry.pricing,
|
|
13295
|
+
};
|
|
13296
|
+
}
|
|
13172
13297
|
} else if (isPassthrough) {
|
|
13173
13298
|
// Passthrough flat prompt \u2014 convert to /v1/chat/completions (upstream has no /api/generate)
|
|
13174
13299
|
var flatPrompt = parsedReq && parsedReq.prompt ? parsedReq.prompt : (prompt || 'Hello');
|
|
@@ -14321,11 +14446,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14321
14446
|
nodePaths.push(globalDir);
|
|
14322
14447
|
} catch {
|
|
14323
14448
|
}
|
|
14324
|
-
const { openSync, closeSync } = await import("node:fs");
|
|
14449
|
+
const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
|
|
14325
14450
|
const daemonLogPath = join30(this.nexusDir, "daemon.log");
|
|
14326
14451
|
const daemonErrPath = join30(this.nexusDir, "daemon.err");
|
|
14327
|
-
const outFd =
|
|
14328
|
-
const errFd =
|
|
14452
|
+
const outFd = openSync2(daemonLogPath, "w");
|
|
14453
|
+
const errFd = openSync2(daemonErrPath, "w");
|
|
14329
14454
|
const child = spawn11("node", [daemonPath, this.nexusDir, agentName, agentType], {
|
|
14330
14455
|
detached: true,
|
|
14331
14456
|
stdio: ["ignore", outFd, errFd],
|
|
@@ -14334,11 +14459,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14334
14459
|
});
|
|
14335
14460
|
child.unref();
|
|
14336
14461
|
try {
|
|
14337
|
-
|
|
14462
|
+
closeSync2(outFd);
|
|
14338
14463
|
} catch {
|
|
14339
14464
|
}
|
|
14340
14465
|
try {
|
|
14341
|
-
|
|
14466
|
+
closeSync2(errFd);
|
|
14342
14467
|
} catch {
|
|
14343
14468
|
}
|
|
14344
14469
|
const statusFile = join30(this.nexusDir, "status.json");
|
|
@@ -20059,9 +20184,9 @@ ${marker}` : marker);
|
|
|
20059
20184
|
if (!this._workingDirectory)
|
|
20060
20185
|
return;
|
|
20061
20186
|
try {
|
|
20062
|
-
const { mkdirSync: mkdirSync21, writeFileSync:
|
|
20063
|
-
const { join:
|
|
20064
|
-
const sessionDir =
|
|
20187
|
+
const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
|
|
20188
|
+
const { join: join57 } = __require("node:path");
|
|
20189
|
+
const sessionDir = join57(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
20065
20190
|
mkdirSync21(sessionDir, { recursive: true });
|
|
20066
20191
|
const checkpoint = {
|
|
20067
20192
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -20074,7 +20199,7 @@ ${marker}` : marker);
|
|
|
20074
20199
|
memexEntryCount: this._memexArchive.size,
|
|
20075
20200
|
fileRegistrySize: this._fileRegistry.size
|
|
20076
20201
|
};
|
|
20077
|
-
|
|
20202
|
+
writeFileSync20(join57(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
20078
20203
|
} catch {
|
|
20079
20204
|
}
|
|
20080
20205
|
}
|
|
@@ -21340,6 +21465,11 @@ ${transcript}`
|
|
|
21340
21465
|
});
|
|
21341
21466
|
|
|
21342
21467
|
// packages/orchestrator/dist/nexusBackend.js
|
|
21468
|
+
import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
21469
|
+
import { watch as fsWatch } from "node:fs";
|
|
21470
|
+
import { join as join34 } from "node:path";
|
|
21471
|
+
import { tmpdir as tmpdir6 } from "node:os";
|
|
21472
|
+
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
21343
21473
|
var NexusAgenticBackend;
|
|
21344
21474
|
var init_nexusBackend = __esm({
|
|
21345
21475
|
"packages/orchestrator/dist/nexusBackend.js"() {
|
|
@@ -21475,47 +21605,199 @@ var init_nexusBackend = __esm({
|
|
|
21475
21605
|
};
|
|
21476
21606
|
}
|
|
21477
21607
|
/**
|
|
21478
|
-
*
|
|
21479
|
-
*
|
|
21480
|
-
*
|
|
21608
|
+
* Real streaming: sends remote_infer with a stream_file, then tails
|
|
21609
|
+
* the file for token-by-token delivery from the remote peer.
|
|
21610
|
+
* Falls back to unary + word-split if streaming setup fails.
|
|
21481
21611
|
*/
|
|
21482
21612
|
async *chatCompletionStream(request) {
|
|
21483
|
-
const
|
|
21484
|
-
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
|
|
21613
|
+
const streamFile = join34(tmpdir6(), `nexus-stream-${randomBytes7(6).toString("hex")}.jsonl`);
|
|
21614
|
+
writeFileSync8(streamFile, "", "utf8");
|
|
21615
|
+
const daemonArgs = {
|
|
21616
|
+
model: this.model,
|
|
21617
|
+
messages: JSON.stringify(request.messages),
|
|
21618
|
+
tools: JSON.stringify(request.tools),
|
|
21619
|
+
temperature: String(request.temperature),
|
|
21620
|
+
max_tokens: String(request.maxTokens),
|
|
21621
|
+
stream_file: streamFile
|
|
21622
|
+
};
|
|
21623
|
+
if (this.targetPeer)
|
|
21624
|
+
daemonArgs.target_peer = this.targetPeer;
|
|
21625
|
+
if (this.authKey)
|
|
21626
|
+
daemonArgs.auth_key = this.authKey;
|
|
21627
|
+
daemonArgs.think = String(this.thinking);
|
|
21628
|
+
let rawResult;
|
|
21629
|
+
try {
|
|
21630
|
+
rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
|
|
21631
|
+
} catch (sendErr) {
|
|
21632
|
+
this.consecutiveFailures++;
|
|
21633
|
+
try {
|
|
21634
|
+
unlinkSync3(streamFile);
|
|
21635
|
+
} catch {
|
|
21494
21636
|
}
|
|
21637
|
+
throw sendErr;
|
|
21495
21638
|
}
|
|
21496
|
-
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
|
|
21500
|
-
|
|
21501
|
-
toolCallIndex: i,
|
|
21502
|
-
toolCallId: tc.id,
|
|
21503
|
-
toolCallName: tc.name,
|
|
21504
|
-
toolCallArgs: JSON.stringify(tc.arguments)
|
|
21505
|
-
};
|
|
21639
|
+
let isStreaming = false;
|
|
21640
|
+
try {
|
|
21641
|
+
const parsed = JSON.parse(rawResult);
|
|
21642
|
+
if (parsed.streaming === true) {
|
|
21643
|
+
isStreaming = true;
|
|
21506
21644
|
}
|
|
21645
|
+
} catch {
|
|
21507
21646
|
}
|
|
21508
|
-
if (
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
|
|
21512
|
-
|
|
21513
|
-
|
|
21514
|
-
|
|
21647
|
+
if (!isStreaming) {
|
|
21648
|
+
try {
|
|
21649
|
+
unlinkSync3(streamFile);
|
|
21650
|
+
} catch {
|
|
21651
|
+
}
|
|
21652
|
+
let parsed;
|
|
21653
|
+
try {
|
|
21654
|
+
parsed = JSON.parse(rawResult);
|
|
21655
|
+
} catch {
|
|
21656
|
+
this.consecutiveFailures++;
|
|
21657
|
+
throw new Error(rawResult.slice(0, 500));
|
|
21658
|
+
}
|
|
21659
|
+
if (parsed.success === false) {
|
|
21660
|
+
this.consecutiveFailures++;
|
|
21661
|
+
throw new Error(`Remote inference failed: ${String(parsed.output || rawResult)}`);
|
|
21662
|
+
}
|
|
21663
|
+
this.consecutiveFailures = 0;
|
|
21664
|
+
const invokeResult = parsed.result;
|
|
21665
|
+
let responseData = null;
|
|
21666
|
+
if (typeof invokeResult === "string") {
|
|
21667
|
+
try {
|
|
21668
|
+
responseData = JSON.parse(invokeResult);
|
|
21669
|
+
} catch {
|
|
21670
|
+
responseData = { response: invokeResult };
|
|
21515
21671
|
}
|
|
21516
|
-
}
|
|
21672
|
+
} else if (invokeResult) {
|
|
21673
|
+
const events = Array.isArray(invokeResult) ? invokeResult : [invokeResult];
|
|
21674
|
+
for (const evt of events) {
|
|
21675
|
+
if (evt.event === "result" && evt.data) {
|
|
21676
|
+
const evtData = evt.data;
|
|
21677
|
+
try {
|
|
21678
|
+
responseData = typeof evtData === "string" ? JSON.parse(evtData) : evtData;
|
|
21679
|
+
} catch {
|
|
21680
|
+
responseData = { response: String(evtData) };
|
|
21681
|
+
}
|
|
21682
|
+
}
|
|
21683
|
+
}
|
|
21684
|
+
}
|
|
21685
|
+
const content = responseData ? responseData.response || "" : "";
|
|
21686
|
+
if (content) {
|
|
21687
|
+
const words = content.split(/(\s+)/);
|
|
21688
|
+
for (const word of words) {
|
|
21689
|
+
if (word)
|
|
21690
|
+
yield { type: "content", content: word };
|
|
21691
|
+
}
|
|
21692
|
+
}
|
|
21693
|
+
yield { type: "finish", finishReason: "stop" };
|
|
21694
|
+
return;
|
|
21695
|
+
}
|
|
21696
|
+
this.consecutiveFailures = 0;
|
|
21697
|
+
let position = 0;
|
|
21698
|
+
let done = false;
|
|
21699
|
+
const deadline = Date.now() + (request.timeoutMs ?? 12e4);
|
|
21700
|
+
try {
|
|
21701
|
+
while (!done && Date.now() < deadline) {
|
|
21702
|
+
await new Promise((resolve32) => {
|
|
21703
|
+
let resolved = false;
|
|
21704
|
+
const finish = () => {
|
|
21705
|
+
if (!resolved) {
|
|
21706
|
+
resolved = true;
|
|
21707
|
+
resolve32();
|
|
21708
|
+
}
|
|
21709
|
+
};
|
|
21710
|
+
let watcher = null;
|
|
21711
|
+
try {
|
|
21712
|
+
watcher = fsWatch(streamFile, { persistent: false }, () => {
|
|
21713
|
+
try {
|
|
21714
|
+
watcher?.close();
|
|
21715
|
+
} catch {
|
|
21716
|
+
}
|
|
21717
|
+
finish();
|
|
21718
|
+
});
|
|
21719
|
+
} catch {
|
|
21720
|
+
}
|
|
21721
|
+
setTimeout(() => {
|
|
21722
|
+
try {
|
|
21723
|
+
watcher?.close();
|
|
21724
|
+
} catch {
|
|
21725
|
+
}
|
|
21726
|
+
finish();
|
|
21727
|
+
}, 50);
|
|
21728
|
+
});
|
|
21729
|
+
const stat5 = statSync9(streamFile, { throwIfNoEntry: false });
|
|
21730
|
+
if (!stat5 || stat5.size <= position)
|
|
21731
|
+
continue;
|
|
21732
|
+
const fd = openSync(streamFile, "r");
|
|
21733
|
+
const buf = Buffer.allocUnsafe(stat5.size - position);
|
|
21734
|
+
readSync(fd, buf, 0, buf.length, position);
|
|
21735
|
+
closeSync(fd);
|
|
21736
|
+
position = stat5.size;
|
|
21737
|
+
for (const line of buf.toString("utf8").split("\n")) {
|
|
21738
|
+
if (!line.trim())
|
|
21739
|
+
continue;
|
|
21740
|
+
let event;
|
|
21741
|
+
try {
|
|
21742
|
+
event = JSON.parse(line);
|
|
21743
|
+
} catch {
|
|
21744
|
+
continue;
|
|
21745
|
+
}
|
|
21746
|
+
if (event.type === "token" && event.content) {
|
|
21747
|
+
yield { type: "content", content: event.content };
|
|
21748
|
+
} else if (event.type === "done") {
|
|
21749
|
+
done = true;
|
|
21750
|
+
if (event.result) {
|
|
21751
|
+
try {
|
|
21752
|
+
const r = JSON.parse(event.result);
|
|
21753
|
+
const choices = r.choices;
|
|
21754
|
+
if (choices?.[0]) {
|
|
21755
|
+
const msg = choices[0].message || {};
|
|
21756
|
+
const toolCalls = msg.tool_calls || [];
|
|
21757
|
+
if (toolCalls.length > 0) {
|
|
21758
|
+
for (let i = 0; i < toolCalls.length; i++) {
|
|
21759
|
+
const tc = toolCalls[i];
|
|
21760
|
+
const fn = tc.function || {};
|
|
21761
|
+
let args;
|
|
21762
|
+
try {
|
|
21763
|
+
args = typeof fn.arguments === "string" ? JSON.parse(fn.arguments) : fn.arguments ?? {};
|
|
21764
|
+
} catch {
|
|
21765
|
+
args = { _raw: fn.arguments };
|
|
21766
|
+
}
|
|
21767
|
+
yield {
|
|
21768
|
+
type: "tool_call_delta",
|
|
21769
|
+
toolCallIndex: i,
|
|
21770
|
+
toolCallId: tc.id || crypto.randomUUID(),
|
|
21771
|
+
toolCallName: fn.name,
|
|
21772
|
+
toolCallArgs: JSON.stringify(args)
|
|
21773
|
+
};
|
|
21774
|
+
}
|
|
21775
|
+
}
|
|
21776
|
+
}
|
|
21777
|
+
if (r.usage) {
|
|
21778
|
+
yield {
|
|
21779
|
+
type: "usage",
|
|
21780
|
+
usage: {
|
|
21781
|
+
promptTokens: r.usage.input_tokens ?? r.usage.prompt_tokens ?? 0,
|
|
21782
|
+
completionTokens: r.usage.output_tokens ?? r.usage.completion_tokens ?? 0,
|
|
21783
|
+
totalTokens: (r.usage.input_tokens ?? 0) + (r.usage.output_tokens ?? 0)
|
|
21784
|
+
}
|
|
21785
|
+
};
|
|
21786
|
+
}
|
|
21787
|
+
} catch {
|
|
21788
|
+
}
|
|
21789
|
+
}
|
|
21790
|
+
yield { type: "finish", finishReason: "stop" };
|
|
21791
|
+
break;
|
|
21792
|
+
}
|
|
21793
|
+
}
|
|
21794
|
+
}
|
|
21795
|
+
} finally {
|
|
21796
|
+
try {
|
|
21797
|
+
unlinkSync3(streamFile);
|
|
21798
|
+
} catch {
|
|
21799
|
+
}
|
|
21517
21800
|
}
|
|
21518
|
-
yield { type: "finish", finishReason: "stop" };
|
|
21519
21801
|
}
|
|
21520
21802
|
extractUsage(data) {
|
|
21521
21803
|
const usage = data.usage;
|
|
@@ -22356,8 +22638,8 @@ __export(listen_exports, {
|
|
|
22356
22638
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
22357
22639
|
});
|
|
22358
22640
|
import { spawn as spawn14, execSync as execSync23 } from "node:child_process";
|
|
22359
|
-
import { existsSync as
|
|
22360
|
-
import { join as
|
|
22641
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
|
|
22642
|
+
import { join as join35, dirname as dirname13 } from "node:path";
|
|
22361
22643
|
import { homedir as homedir8 } from "node:os";
|
|
22362
22644
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
22363
22645
|
import { EventEmitter } from "node:events";
|
|
@@ -22443,15 +22725,15 @@ function findMicCaptureCommand() {
|
|
|
22443
22725
|
function findLiveWhisperScript() {
|
|
22444
22726
|
const thisDir = dirname13(fileURLToPath8(import.meta.url));
|
|
22445
22727
|
const candidates = [
|
|
22446
|
-
|
|
22447
|
-
|
|
22448
|
-
|
|
22728
|
+
join35(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
22729
|
+
join35(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
22730
|
+
join35(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
22449
22731
|
// npm install layout — scripts bundled alongside dist
|
|
22450
|
-
|
|
22451
|
-
|
|
22732
|
+
join35(thisDir, "../scripts/live-whisper.py"),
|
|
22733
|
+
join35(thisDir, "../../scripts/live-whisper.py")
|
|
22452
22734
|
];
|
|
22453
22735
|
for (const p of candidates) {
|
|
22454
|
-
if (
|
|
22736
|
+
if (existsSync27(p))
|
|
22455
22737
|
return p;
|
|
22456
22738
|
}
|
|
22457
22739
|
try {
|
|
@@ -22461,21 +22743,21 @@ function findLiveWhisperScript() {
|
|
|
22461
22743
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22462
22744
|
}).trim();
|
|
22463
22745
|
const candidates2 = [
|
|
22464
|
-
|
|
22465
|
-
|
|
22746
|
+
join35(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
22747
|
+
join35(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
22466
22748
|
];
|
|
22467
22749
|
for (const p of candidates2) {
|
|
22468
|
-
if (
|
|
22750
|
+
if (existsSync27(p))
|
|
22469
22751
|
return p;
|
|
22470
22752
|
}
|
|
22471
22753
|
} catch {
|
|
22472
22754
|
}
|
|
22473
|
-
const nvmBase =
|
|
22474
|
-
if (
|
|
22755
|
+
const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
|
|
22756
|
+
if (existsSync27(nvmBase)) {
|
|
22475
22757
|
try {
|
|
22476
22758
|
for (const ver of readdirSync6(nvmBase)) {
|
|
22477
|
-
const p =
|
|
22478
|
-
if (
|
|
22759
|
+
const p = join35(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
22760
|
+
if (existsSync27(p))
|
|
22479
22761
|
return p;
|
|
22480
22762
|
}
|
|
22481
22763
|
} catch {
|
|
@@ -22493,7 +22775,7 @@ function ensureTranscribeCliBackground() {
|
|
|
22493
22775
|
timeout: 5e3,
|
|
22494
22776
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22495
22777
|
}).trim();
|
|
22496
|
-
if (
|
|
22778
|
+
if (existsSync27(join35(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
22497
22779
|
return true;
|
|
22498
22780
|
}
|
|
22499
22781
|
} catch {
|
|
@@ -22716,24 +22998,24 @@ var init_listen = __esm({
|
|
|
22716
22998
|
timeout: 5e3,
|
|
22717
22999
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22718
23000
|
}).trim();
|
|
22719
|
-
const tcPath =
|
|
22720
|
-
if (
|
|
23001
|
+
const tcPath = join35(globalRoot, "transcribe-cli");
|
|
23002
|
+
if (existsSync27(join35(tcPath, "dist", "index.js"))) {
|
|
22721
23003
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
22722
23004
|
const req = createRequire4(import.meta.url);
|
|
22723
|
-
return req(
|
|
23005
|
+
return req(join35(tcPath, "dist", "index.js"));
|
|
22724
23006
|
}
|
|
22725
23007
|
} catch {
|
|
22726
23008
|
}
|
|
22727
|
-
const nvmBase =
|
|
22728
|
-
if (
|
|
23009
|
+
const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
|
|
23010
|
+
if (existsSync27(nvmBase)) {
|
|
22729
23011
|
try {
|
|
22730
23012
|
const { readdirSync: readdirSync17 } = await import("node:fs");
|
|
22731
23013
|
for (const ver of readdirSync17(nvmBase)) {
|
|
22732
|
-
const tcPath =
|
|
22733
|
-
if (
|
|
23014
|
+
const tcPath = join35(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
23015
|
+
if (existsSync27(join35(tcPath, "dist", "index.js"))) {
|
|
22734
23016
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
22735
23017
|
const req = createRequire4(import.meta.url);
|
|
22736
|
-
return req(
|
|
23018
|
+
return req(join35(tcPath, "dist", "index.js"));
|
|
22737
23019
|
}
|
|
22738
23020
|
}
|
|
22739
23021
|
} catch {
|
|
@@ -23015,10 +23297,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
23015
23297
|
});
|
|
23016
23298
|
if (outputDir) {
|
|
23017
23299
|
const { basename: basename16 } = await import("node:path");
|
|
23018
|
-
const transcriptDir =
|
|
23300
|
+
const transcriptDir = join35(outputDir, ".oa", "transcripts");
|
|
23019
23301
|
mkdirSync8(transcriptDir, { recursive: true });
|
|
23020
|
-
const outFile =
|
|
23021
|
-
|
|
23302
|
+
const outFile = join35(transcriptDir, `${basename16(filePath)}.txt`);
|
|
23303
|
+
writeFileSync9(outFile, result.text, "utf-8");
|
|
23022
23304
|
}
|
|
23023
23305
|
return {
|
|
23024
23306
|
text: result.text,
|
|
@@ -25266,7 +25548,7 @@ var require_websocket = __commonJS({
|
|
|
25266
25548
|
var http = __require("http");
|
|
25267
25549
|
var net = __require("net");
|
|
25268
25550
|
var tls = __require("tls");
|
|
25269
|
-
var { randomBytes:
|
|
25551
|
+
var { randomBytes: randomBytes11, createHash: createHash5 } = __require("crypto");
|
|
25270
25552
|
var { Duplex, Readable } = __require("stream");
|
|
25271
25553
|
var { URL: URL3 } = __require("url");
|
|
25272
25554
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -25796,7 +26078,7 @@ var require_websocket = __commonJS({
|
|
|
25796
26078
|
}
|
|
25797
26079
|
}
|
|
25798
26080
|
const defaultPort = isSecure ? 443 : 80;
|
|
25799
|
-
const key =
|
|
26081
|
+
const key = randomBytes11(16).toString("base64");
|
|
25800
26082
|
const request = isSecure ? https.request : http.request;
|
|
25801
26083
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
25802
26084
|
let perMessageDeflate;
|
|
@@ -28371,11 +28653,11 @@ var init_voice_session = __esm({
|
|
|
28371
28653
|
import { createServer as createServer2, request as httpRequest } from "node:http";
|
|
28372
28654
|
import { spawn as spawn16, exec } from "node:child_process";
|
|
28373
28655
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
28374
|
-
import { randomBytes as
|
|
28656
|
+
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
28375
28657
|
import { URL as URL2 } from "node:url";
|
|
28376
28658
|
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
28377
|
-
import { existsSync as
|
|
28378
|
-
import { join as
|
|
28659
|
+
import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
|
|
28660
|
+
import { join as join36 } from "node:path";
|
|
28379
28661
|
function cleanForwardHeaders(raw, targetHost) {
|
|
28380
28662
|
const out = {};
|
|
28381
28663
|
for (const [key, value] of Object.entries(raw)) {
|
|
@@ -28403,8 +28685,8 @@ function fmtTokens(n) {
|
|
|
28403
28685
|
}
|
|
28404
28686
|
function readExposeState(stateDir) {
|
|
28405
28687
|
try {
|
|
28406
|
-
const path =
|
|
28407
|
-
if (!
|
|
28688
|
+
const path = join36(stateDir, STATE_FILE_NAME);
|
|
28689
|
+
if (!existsSync28(path))
|
|
28408
28690
|
return null;
|
|
28409
28691
|
const raw = readFileSync19(path, "utf8");
|
|
28410
28692
|
const data = JSON.parse(raw);
|
|
@@ -28418,13 +28700,13 @@ function readExposeState(stateDir) {
|
|
|
28418
28700
|
function writeExposeState(stateDir, state) {
|
|
28419
28701
|
try {
|
|
28420
28702
|
mkdirSync9(stateDir, { recursive: true });
|
|
28421
|
-
|
|
28703
|
+
writeFileSync10(join36(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
28422
28704
|
} catch {
|
|
28423
28705
|
}
|
|
28424
28706
|
}
|
|
28425
28707
|
function removeExposeState(stateDir) {
|
|
28426
28708
|
try {
|
|
28427
|
-
|
|
28709
|
+
unlinkSync4(join36(stateDir, STATE_FILE_NAME));
|
|
28428
28710
|
} catch {
|
|
28429
28711
|
}
|
|
28430
28712
|
}
|
|
@@ -28513,8 +28795,8 @@ async function collectSystemMetricsAsync() {
|
|
|
28513
28795
|
}
|
|
28514
28796
|
function readP2PExposeState(stateDir) {
|
|
28515
28797
|
try {
|
|
28516
|
-
const path =
|
|
28517
|
-
if (!
|
|
28798
|
+
const path = join36(stateDir, P2P_STATE_FILE_NAME);
|
|
28799
|
+
if (!existsSync28(path))
|
|
28518
28800
|
return null;
|
|
28519
28801
|
const raw = readFileSync19(path, "utf8");
|
|
28520
28802
|
const data = JSON.parse(raw);
|
|
@@ -28528,13 +28810,13 @@ function readP2PExposeState(stateDir) {
|
|
|
28528
28810
|
function writeP2PExposeState(stateDir, state) {
|
|
28529
28811
|
try {
|
|
28530
28812
|
mkdirSync9(stateDir, { recursive: true });
|
|
28531
|
-
|
|
28813
|
+
writeFileSync10(join36(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
28532
28814
|
} catch {
|
|
28533
28815
|
}
|
|
28534
28816
|
}
|
|
28535
28817
|
function removeP2PExposeState(stateDir) {
|
|
28536
28818
|
try {
|
|
28537
|
-
|
|
28819
|
+
unlinkSync4(join36(stateDir, P2P_STATE_FILE_NAME));
|
|
28538
28820
|
} catch {
|
|
28539
28821
|
}
|
|
28540
28822
|
}
|
|
@@ -28616,7 +28898,7 @@ var init_expose = __esm({
|
|
|
28616
28898
|
this._stateDir = options.stateDir ?? null;
|
|
28617
28899
|
this._fullAccess = options.fullAccess ?? false;
|
|
28618
28900
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
28619
|
-
this._authKey =
|
|
28901
|
+
this._authKey = randomBytes8(24).toString("base64url");
|
|
28620
28902
|
} else {
|
|
28621
28903
|
this._authKey = options.authKey;
|
|
28622
28904
|
}
|
|
@@ -29324,7 +29606,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29324
29606
|
this._onInfo = options.onInfo;
|
|
29325
29607
|
this._onError = options.onError;
|
|
29326
29608
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
29327
|
-
this._authKey =
|
|
29609
|
+
this._authKey = randomBytes8(24).toString("base64url");
|
|
29328
29610
|
} else {
|
|
29329
29611
|
this._authKey = options.authKey;
|
|
29330
29612
|
}
|
|
@@ -29362,7 +29644,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29362
29644
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
29363
29645
|
}
|
|
29364
29646
|
const nexusDir = this._nexusTool.getNexusDir();
|
|
29365
|
-
const statusPath =
|
|
29647
|
+
const statusPath = join36(nexusDir, "status.json");
|
|
29366
29648
|
for (let i = 0; i < 80; i++) {
|
|
29367
29649
|
try {
|
|
29368
29650
|
const raw = readFileSync19(statusPath, "utf8");
|
|
@@ -29396,8 +29678,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
29396
29678
|
});
|
|
29397
29679
|
}
|
|
29398
29680
|
try {
|
|
29399
|
-
const invocDir =
|
|
29400
|
-
if (
|
|
29681
|
+
const invocDir = join36(nexusDir, "invocations");
|
|
29682
|
+
if (existsSync28(invocDir)) {
|
|
29401
29683
|
this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
|
|
29402
29684
|
this._stats.totalRequests = this._prevInvocCount;
|
|
29403
29685
|
}
|
|
@@ -29426,9 +29708,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
29426
29708
|
if (!state)
|
|
29427
29709
|
return null;
|
|
29428
29710
|
const nexusDir = nexusTool.getNexusDir();
|
|
29429
|
-
const statusPath =
|
|
29711
|
+
const statusPath = join36(nexusDir, "status.json");
|
|
29430
29712
|
try {
|
|
29431
|
-
if (!
|
|
29713
|
+
if (!existsSync28(statusPath)) {
|
|
29432
29714
|
removeP2PExposeState(stateDir);
|
|
29433
29715
|
return null;
|
|
29434
29716
|
}
|
|
@@ -29485,8 +29767,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
29485
29767
|
let lastMeteringLineCount = 0;
|
|
29486
29768
|
this._activityPollTimer = setInterval(() => {
|
|
29487
29769
|
try {
|
|
29488
|
-
const invocDir =
|
|
29489
|
-
if (!
|
|
29770
|
+
const invocDir = join36(nexusDir, "invocations");
|
|
29771
|
+
if (!existsSync28(invocDir))
|
|
29490
29772
|
return;
|
|
29491
29773
|
const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
|
|
29492
29774
|
const invocCount = files.length;
|
|
@@ -29501,16 +29783,16 @@ ${this.formatConnectionInfo()}`);
|
|
|
29501
29783
|
let recentActive = 0;
|
|
29502
29784
|
for (const f of files.slice(-10)) {
|
|
29503
29785
|
try {
|
|
29504
|
-
const st =
|
|
29786
|
+
const st = statSync10(join36(invocDir, f));
|
|
29505
29787
|
if (now - st.mtimeMs < 1e4)
|
|
29506
29788
|
recentActive++;
|
|
29507
29789
|
} catch {
|
|
29508
29790
|
}
|
|
29509
29791
|
}
|
|
29510
|
-
const meteringFile =
|
|
29792
|
+
const meteringFile = join36(nexusDir, "metering.jsonl");
|
|
29511
29793
|
let meteringLines = lastMeteringLineCount;
|
|
29512
29794
|
try {
|
|
29513
|
-
if (
|
|
29795
|
+
if (existsSync28(meteringFile)) {
|
|
29514
29796
|
const content = readFileSync19(meteringFile, "utf8");
|
|
29515
29797
|
meteringLines = content.split("\n").filter((l) => l.trim()).length;
|
|
29516
29798
|
}
|
|
@@ -29537,8 +29819,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
29537
29819
|
this._activityPollTimer.unref();
|
|
29538
29820
|
this._pollTimer = setInterval(() => {
|
|
29539
29821
|
try {
|
|
29540
|
-
const statusPath =
|
|
29541
|
-
if (
|
|
29822
|
+
const statusPath = join36(nexusDir, "status.json");
|
|
29823
|
+
if (existsSync28(statusPath)) {
|
|
29542
29824
|
const status = JSON.parse(readFileSync19(statusPath, "utf8"));
|
|
29543
29825
|
if (status.peerId && !this._peerId) {
|
|
29544
29826
|
this._peerId = status.peerId;
|
|
@@ -29548,8 +29830,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
29548
29830
|
} catch {
|
|
29549
29831
|
}
|
|
29550
29832
|
try {
|
|
29551
|
-
const invocDir =
|
|
29552
|
-
if (
|
|
29833
|
+
const invocDir = join36(nexusDir, "invocations");
|
|
29834
|
+
if (existsSync28(invocDir)) {
|
|
29553
29835
|
const files = readdirSync7(invocDir);
|
|
29554
29836
|
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
29555
29837
|
if (invocCount > this._stats.totalRequests) {
|
|
@@ -29560,8 +29842,8 @@ ${this.formatConnectionInfo()}`);
|
|
|
29560
29842
|
} catch {
|
|
29561
29843
|
}
|
|
29562
29844
|
try {
|
|
29563
|
-
const meteringFile =
|
|
29564
|
-
if (
|
|
29845
|
+
const meteringFile = join36(nexusDir, "metering.jsonl");
|
|
29846
|
+
if (existsSync28(meteringFile)) {
|
|
29565
29847
|
const content = readFileSync19(meteringFile, "utf8");
|
|
29566
29848
|
if (content.length > lastMeteringSize) {
|
|
29567
29849
|
const newContent = content.slice(lastMeteringSize);
|
|
@@ -29778,9 +30060,9 @@ var init_types = __esm({
|
|
|
29778
30060
|
});
|
|
29779
30061
|
|
|
29780
30062
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
29781
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as
|
|
29782
|
-
import { readFileSync as readFileSync20, writeFileSync as
|
|
29783
|
-
import { join as
|
|
30063
|
+
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes9, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
30064
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
|
|
30065
|
+
import { join as join37, dirname as dirname14 } from "node:path";
|
|
29784
30066
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
29785
30067
|
var init_secret_vault = __esm({
|
|
29786
30068
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -29984,24 +30266,24 @@ var init_secret_vault = __esm({
|
|
|
29984
30266
|
minTrust: s.minTrust,
|
|
29985
30267
|
createdAt: s.createdAt
|
|
29986
30268
|
})));
|
|
29987
|
-
const salt =
|
|
30269
|
+
const salt = randomBytes9(SALT_LEN);
|
|
29988
30270
|
const key = scryptSync2(passphrase, salt, KEY_LEN);
|
|
29989
|
-
const iv =
|
|
30271
|
+
const iv = randomBytes9(IV_LEN);
|
|
29990
30272
|
const cipher = createCipheriv2(CIPHER_ALGO, key, iv);
|
|
29991
30273
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
29992
30274
|
const tag = cipher.getAuthTag();
|
|
29993
30275
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
29994
30276
|
const dir = dirname14(this.storePath);
|
|
29995
|
-
if (!
|
|
30277
|
+
if (!existsSync29(dir))
|
|
29996
30278
|
mkdirSync10(dir, { recursive: true });
|
|
29997
|
-
|
|
30279
|
+
writeFileSync11(this.storePath, blob, { mode: 384 });
|
|
29998
30280
|
}
|
|
29999
30281
|
/**
|
|
30000
30282
|
* Load vault from disk, decrypting with the given passphrase.
|
|
30001
30283
|
* Returns the number of secrets loaded.
|
|
30002
30284
|
*/
|
|
30003
30285
|
load(passphrase) {
|
|
30004
|
-
if (!this.storePath || !
|
|
30286
|
+
if (!this.storePath || !existsSync29(this.storePath))
|
|
30005
30287
|
return 0;
|
|
30006
30288
|
const blob = readFileSync20(this.storePath);
|
|
30007
30289
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
@@ -30044,7 +30326,7 @@ var init_secret_vault = __esm({
|
|
|
30044
30326
|
// packages/cli/dist/tui/p2p/peer-mesh.js
|
|
30045
30327
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
30046
30328
|
import { createServer as createServer3 } from "node:http";
|
|
30047
|
-
import { randomBytes as
|
|
30329
|
+
import { randomBytes as randomBytes10, createHash as createHash3, generateKeyPairSync } from "node:crypto";
|
|
30048
30330
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
30049
30331
|
var init_peer_mesh = __esm({
|
|
30050
30332
|
"packages/cli/dist/tui/p2p/peer-mesh.js"() {
|
|
@@ -30096,7 +30378,7 @@ var init_peer_mesh = __esm({
|
|
|
30096
30378
|
this.peerId = createHash3("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
30097
30379
|
this.capabilities = options.capabilities;
|
|
30098
30380
|
this.displayName = options.displayName;
|
|
30099
|
-
this._authKey = options.authKey ??
|
|
30381
|
+
this._authKey = options.authKey ?? randomBytes10(24).toString("base64url");
|
|
30100
30382
|
}
|
|
30101
30383
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
30102
30384
|
/** Start the mesh node — creates WS server and connects to bootstrap peers */
|
|
@@ -30260,7 +30542,7 @@ var init_peer_mesh = __esm({
|
|
|
30260
30542
|
if (!ws || ws.readyState !== import_websocket.default.OPEN) {
|
|
30261
30543
|
throw new Error(`Peer ${peerId} not connected`);
|
|
30262
30544
|
}
|
|
30263
|
-
const msgId =
|
|
30545
|
+
const msgId = randomBytes10(8).toString("hex");
|
|
30264
30546
|
return new Promise((resolve32, reject) => {
|
|
30265
30547
|
const timeout = setTimeout(() => {
|
|
30266
30548
|
this.pendingRequests.delete(msgId);
|
|
@@ -30481,7 +30763,7 @@ var init_peer_mesh = __esm({
|
|
|
30481
30763
|
const msg = {
|
|
30482
30764
|
type,
|
|
30483
30765
|
from: this.peerId,
|
|
30484
|
-
msgId: msgId ??
|
|
30766
|
+
msgId: msgId ?? randomBytes10(8).toString("hex"),
|
|
30485
30767
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30486
30768
|
payload
|
|
30487
30769
|
};
|
|
@@ -31116,15 +31398,15 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
31116
31398
|
async function fetchPeerModels(peerId, authKey) {
|
|
31117
31399
|
try {
|
|
31118
31400
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
31119
|
-
const { existsSync:
|
|
31120
|
-
const { join:
|
|
31401
|
+
const { existsSync: existsSync45, readFileSync: readFileSync32 } = await import("node:fs");
|
|
31402
|
+
const { join: join57 } = await import("node:path");
|
|
31121
31403
|
const cwd4 = process.cwd();
|
|
31122
31404
|
const nexusTool = new NexusTool2(cwd4);
|
|
31123
31405
|
const nexusDir = nexusTool.getNexusDir();
|
|
31124
31406
|
let isLocalPeer = false;
|
|
31125
31407
|
try {
|
|
31126
|
-
const statusPath =
|
|
31127
|
-
if (
|
|
31408
|
+
const statusPath = join57(nexusDir, "status.json");
|
|
31409
|
+
if (existsSync45(statusPath)) {
|
|
31128
31410
|
const status = JSON.parse(readFileSync32(statusPath, "utf8"));
|
|
31129
31411
|
if (status.peerId === peerId)
|
|
31130
31412
|
isLocalPeer = true;
|
|
@@ -31132,8 +31414,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31132
31414
|
} catch {
|
|
31133
31415
|
}
|
|
31134
31416
|
if (isLocalPeer) {
|
|
31135
|
-
const pricingPath =
|
|
31136
|
-
if (
|
|
31417
|
+
const pricingPath = join57(nexusDir, "pricing.json");
|
|
31418
|
+
if (existsSync45(pricingPath)) {
|
|
31137
31419
|
try {
|
|
31138
31420
|
const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
|
|
31139
31421
|
const localModels = (pricing.models || []).map((m) => ({
|
|
@@ -31149,8 +31431,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31149
31431
|
}
|
|
31150
31432
|
}
|
|
31151
31433
|
}
|
|
31152
|
-
const cachePath =
|
|
31153
|
-
if (
|
|
31434
|
+
const cachePath = join57(nexusDir, "peer-models-cache.json");
|
|
31435
|
+
if (existsSync45(cachePath)) {
|
|
31154
31436
|
try {
|
|
31155
31437
|
const cache4 = JSON.parse(readFileSync32(cachePath, "utf8"));
|
|
31156
31438
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
@@ -31267,8 +31549,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31267
31549
|
} catch {
|
|
31268
31550
|
}
|
|
31269
31551
|
if (isLocalPeer) {
|
|
31270
|
-
const pricingPath =
|
|
31271
|
-
if (
|
|
31552
|
+
const pricingPath = join57(nexusDir, "pricing.json");
|
|
31553
|
+
if (existsSync45(pricingPath)) {
|
|
31272
31554
|
try {
|
|
31273
31555
|
const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
|
|
31274
31556
|
return (pricing.models || []).map((m) => ({
|
|
@@ -31539,14 +31821,14 @@ var init_render2 = __esm({
|
|
|
31539
31821
|
});
|
|
31540
31822
|
|
|
31541
31823
|
// packages/prompts/dist/promptLoader.js
|
|
31542
|
-
import { readFileSync as readFileSync21, existsSync as
|
|
31543
|
-
import { join as
|
|
31824
|
+
import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
|
|
31825
|
+
import { join as join38, dirname as dirname15 } from "node:path";
|
|
31544
31826
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
31545
31827
|
function loadPrompt2(promptPath, vars) {
|
|
31546
31828
|
let content = cache2.get(promptPath);
|
|
31547
31829
|
if (content === void 0) {
|
|
31548
|
-
const fullPath =
|
|
31549
|
-
if (!
|
|
31830
|
+
const fullPath = join38(PROMPTS_DIR2, promptPath);
|
|
31831
|
+
if (!existsSync30(fullPath)) {
|
|
31550
31832
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
31551
31833
|
}
|
|
31552
31834
|
content = readFileSync21(fullPath, "utf-8");
|
|
@@ -31562,9 +31844,9 @@ var init_promptLoader2 = __esm({
|
|
|
31562
31844
|
"use strict";
|
|
31563
31845
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
31564
31846
|
__dirname5 = dirname15(__filename2);
|
|
31565
|
-
devPath =
|
|
31566
|
-
publishedPath =
|
|
31567
|
-
PROMPTS_DIR2 =
|
|
31847
|
+
devPath = join38(__dirname5, "..", "templates");
|
|
31848
|
+
publishedPath = join38(__dirname5, "..", "prompts", "templates");
|
|
31849
|
+
PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
|
|
31568
31850
|
cache2 = /* @__PURE__ */ new Map();
|
|
31569
31851
|
}
|
|
31570
31852
|
});
|
|
@@ -31675,7 +31957,7 @@ var init_task_templates = __esm({
|
|
|
31675
31957
|
});
|
|
31676
31958
|
|
|
31677
31959
|
// packages/prompts/dist/index.js
|
|
31678
|
-
import { join as
|
|
31960
|
+
import { join as join39, dirname as dirname16 } from "node:path";
|
|
31679
31961
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
31680
31962
|
var _dir, _packageRoot;
|
|
31681
31963
|
var init_dist6 = __esm({
|
|
@@ -31686,26 +31968,26 @@ var init_dist6 = __esm({
|
|
|
31686
31968
|
init_task_templates();
|
|
31687
31969
|
init_render2();
|
|
31688
31970
|
_dir = dirname16(fileURLToPath10(import.meta.url));
|
|
31689
|
-
_packageRoot =
|
|
31971
|
+
_packageRoot = join39(_dir, "..");
|
|
31690
31972
|
}
|
|
31691
31973
|
});
|
|
31692
31974
|
|
|
31693
31975
|
// packages/cli/dist/tui/oa-directory.js
|
|
31694
|
-
import { existsSync as
|
|
31695
|
-
import { join as
|
|
31976
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync5 } from "node:fs";
|
|
31977
|
+
import { join as join40, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
31696
31978
|
import { homedir as homedir9 } from "node:os";
|
|
31697
31979
|
function initOaDirectory(repoRoot) {
|
|
31698
|
-
const oaPath =
|
|
31980
|
+
const oaPath = join40(repoRoot, OA_DIR);
|
|
31699
31981
|
for (const sub of SUBDIRS) {
|
|
31700
|
-
mkdirSync11(
|
|
31982
|
+
mkdirSync11(join40(oaPath, sub), { recursive: true });
|
|
31701
31983
|
}
|
|
31702
31984
|
try {
|
|
31703
|
-
const gitignorePath =
|
|
31985
|
+
const gitignorePath = join40(repoRoot, ".gitignore");
|
|
31704
31986
|
const settingsPattern = ".oa/settings.json";
|
|
31705
|
-
if (
|
|
31987
|
+
if (existsSync31(gitignorePath)) {
|
|
31706
31988
|
const content = readFileSync22(gitignorePath, "utf-8");
|
|
31707
31989
|
if (!content.includes(settingsPattern)) {
|
|
31708
|
-
|
|
31990
|
+
writeFileSync12(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
31709
31991
|
}
|
|
31710
31992
|
}
|
|
31711
31993
|
} catch {
|
|
@@ -31713,12 +31995,12 @@ function initOaDirectory(repoRoot) {
|
|
|
31713
31995
|
return oaPath;
|
|
31714
31996
|
}
|
|
31715
31997
|
function hasOaDirectory(repoRoot) {
|
|
31716
|
-
return
|
|
31998
|
+
return existsSync31(join40(repoRoot, OA_DIR, "index"));
|
|
31717
31999
|
}
|
|
31718
32000
|
function loadProjectSettings(repoRoot) {
|
|
31719
|
-
const settingsPath =
|
|
32001
|
+
const settingsPath = join40(repoRoot, OA_DIR, "settings.json");
|
|
31720
32002
|
try {
|
|
31721
|
-
if (
|
|
32003
|
+
if (existsSync31(settingsPath)) {
|
|
31722
32004
|
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
31723
32005
|
}
|
|
31724
32006
|
} catch {
|
|
@@ -31726,16 +32008,16 @@ function loadProjectSettings(repoRoot) {
|
|
|
31726
32008
|
return {};
|
|
31727
32009
|
}
|
|
31728
32010
|
function saveProjectSettings(repoRoot, settings) {
|
|
31729
|
-
const oaPath =
|
|
32011
|
+
const oaPath = join40(repoRoot, OA_DIR);
|
|
31730
32012
|
mkdirSync11(oaPath, { recursive: true });
|
|
31731
32013
|
const existing = loadProjectSettings(repoRoot);
|
|
31732
32014
|
const merged = { ...existing, ...settings };
|
|
31733
|
-
|
|
32015
|
+
writeFileSync12(join40(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
31734
32016
|
}
|
|
31735
32017
|
function loadGlobalSettings() {
|
|
31736
|
-
const settingsPath =
|
|
32018
|
+
const settingsPath = join40(homedir9(), ".open-agents", "settings.json");
|
|
31737
32019
|
try {
|
|
31738
|
-
if (
|
|
32020
|
+
if (existsSync31(settingsPath)) {
|
|
31739
32021
|
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
31740
32022
|
}
|
|
31741
32023
|
} catch {
|
|
@@ -31743,11 +32025,11 @@ function loadGlobalSettings() {
|
|
|
31743
32025
|
return {};
|
|
31744
32026
|
}
|
|
31745
32027
|
function saveGlobalSettings(settings) {
|
|
31746
|
-
const dir =
|
|
32028
|
+
const dir = join40(homedir9(), ".open-agents");
|
|
31747
32029
|
mkdirSync11(dir, { recursive: true });
|
|
31748
32030
|
const existing = loadGlobalSettings();
|
|
31749
32031
|
const merged = { ...existing, ...settings };
|
|
31750
|
-
|
|
32032
|
+
writeFileSync12(join40(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
31751
32033
|
}
|
|
31752
32034
|
function resolveSettings(repoRoot) {
|
|
31753
32035
|
const global = loadGlobalSettings();
|
|
@@ -31762,9 +32044,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
31762
32044
|
while (dir && !visited.has(dir)) {
|
|
31763
32045
|
visited.add(dir);
|
|
31764
32046
|
for (const name of CONTEXT_FILES) {
|
|
31765
|
-
const filePath =
|
|
32047
|
+
const filePath = join40(dir, name);
|
|
31766
32048
|
const normalizedName = name.toLowerCase();
|
|
31767
|
-
if (
|
|
32049
|
+
if (existsSync31(filePath) && !seen.has(filePath)) {
|
|
31768
32050
|
seen.add(filePath);
|
|
31769
32051
|
try {
|
|
31770
32052
|
let content = readFileSync22(filePath, "utf-8");
|
|
@@ -31781,8 +32063,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
31781
32063
|
}
|
|
31782
32064
|
}
|
|
31783
32065
|
}
|
|
31784
|
-
const projectMap =
|
|
31785
|
-
if (
|
|
32066
|
+
const projectMap = join40(dir, OA_DIR, "context", "project-map.md");
|
|
32067
|
+
if (existsSync31(projectMap) && !seen.has(projectMap)) {
|
|
31786
32068
|
seen.add(projectMap);
|
|
31787
32069
|
try {
|
|
31788
32070
|
let content = readFileSync22(projectMap, "utf-8");
|
|
@@ -31797,7 +32079,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
31797
32079
|
} catch {
|
|
31798
32080
|
}
|
|
31799
32081
|
}
|
|
31800
|
-
const parent =
|
|
32082
|
+
const parent = join40(dir, "..");
|
|
31801
32083
|
if (parent === dir)
|
|
31802
32084
|
break;
|
|
31803
32085
|
dir = parent;
|
|
@@ -31815,7 +32097,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
31815
32097
|
return found;
|
|
31816
32098
|
}
|
|
31817
32099
|
function readIndexMeta(repoRoot) {
|
|
31818
|
-
const metaPath =
|
|
32100
|
+
const metaPath = join40(repoRoot, OA_DIR, "index", "meta.json");
|
|
31819
32101
|
try {
|
|
31820
32102
|
return JSON.parse(readFileSync22(metaPath, "utf-8"));
|
|
31821
32103
|
} catch {
|
|
@@ -31868,28 +32150,28 @@ ${tree}\`\`\`
|
|
|
31868
32150
|
sections.push("");
|
|
31869
32151
|
}
|
|
31870
32152
|
const content = sections.join("\n");
|
|
31871
|
-
const contextDir =
|
|
32153
|
+
const contextDir = join40(repoRoot, OA_DIR, "context");
|
|
31872
32154
|
mkdirSync11(contextDir, { recursive: true });
|
|
31873
|
-
|
|
32155
|
+
writeFileSync12(join40(contextDir, "project-map.md"), content, "utf-8");
|
|
31874
32156
|
return content;
|
|
31875
32157
|
}
|
|
31876
32158
|
function saveSession(repoRoot, session) {
|
|
31877
|
-
const historyDir =
|
|
32159
|
+
const historyDir = join40(repoRoot, OA_DIR, "history");
|
|
31878
32160
|
mkdirSync11(historyDir, { recursive: true });
|
|
31879
|
-
|
|
32161
|
+
writeFileSync12(join40(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
31880
32162
|
}
|
|
31881
32163
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
31882
|
-
const historyDir =
|
|
31883
|
-
if (!
|
|
32164
|
+
const historyDir = join40(repoRoot, OA_DIR, "history");
|
|
32165
|
+
if (!existsSync31(historyDir))
|
|
31884
32166
|
return [];
|
|
31885
32167
|
try {
|
|
31886
32168
|
const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
31887
|
-
const stat5 =
|
|
32169
|
+
const stat5 = statSync11(join40(historyDir, f));
|
|
31888
32170
|
return { file: f, mtime: stat5.mtimeMs };
|
|
31889
32171
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
31890
32172
|
return files.map((f) => {
|
|
31891
32173
|
try {
|
|
31892
|
-
return JSON.parse(readFileSync22(
|
|
32174
|
+
return JSON.parse(readFileSync22(join40(historyDir, f.file), "utf-8"));
|
|
31893
32175
|
} catch {
|
|
31894
32176
|
return null;
|
|
31895
32177
|
}
|
|
@@ -31899,18 +32181,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
31899
32181
|
}
|
|
31900
32182
|
}
|
|
31901
32183
|
function savePendingTask(repoRoot, task) {
|
|
31902
|
-
const historyDir =
|
|
32184
|
+
const historyDir = join40(repoRoot, OA_DIR, "history");
|
|
31903
32185
|
mkdirSync11(historyDir, { recursive: true });
|
|
31904
|
-
|
|
32186
|
+
writeFileSync12(join40(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
31905
32187
|
}
|
|
31906
32188
|
function loadPendingTask(repoRoot) {
|
|
31907
|
-
const filePath =
|
|
32189
|
+
const filePath = join40(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
31908
32190
|
try {
|
|
31909
|
-
if (!
|
|
32191
|
+
if (!existsSync31(filePath))
|
|
31910
32192
|
return null;
|
|
31911
32193
|
const data = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
31912
32194
|
try {
|
|
31913
|
-
|
|
32195
|
+
unlinkSync5(filePath);
|
|
31914
32196
|
} catch {
|
|
31915
32197
|
}
|
|
31916
32198
|
return data;
|
|
@@ -31919,12 +32201,12 @@ function loadPendingTask(repoRoot) {
|
|
|
31919
32201
|
}
|
|
31920
32202
|
}
|
|
31921
32203
|
function saveSessionContext(repoRoot, entry) {
|
|
31922
|
-
const contextDir =
|
|
32204
|
+
const contextDir = join40(repoRoot, OA_DIR, "context");
|
|
31923
32205
|
mkdirSync11(contextDir, { recursive: true });
|
|
31924
|
-
const filePath =
|
|
32206
|
+
const filePath = join40(contextDir, CONTEXT_SAVE_FILE);
|
|
31925
32207
|
let ctx;
|
|
31926
32208
|
try {
|
|
31927
|
-
if (
|
|
32209
|
+
if (existsSync31(filePath)) {
|
|
31928
32210
|
ctx = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
31929
32211
|
} else {
|
|
31930
32212
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
@@ -31937,12 +32219,12 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
31937
32219
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
31938
32220
|
}
|
|
31939
32221
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
31940
|
-
|
|
32222
|
+
writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
31941
32223
|
}
|
|
31942
32224
|
function loadSessionContext(repoRoot) {
|
|
31943
|
-
const filePath =
|
|
32225
|
+
const filePath = join40(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
31944
32226
|
try {
|
|
31945
|
-
if (!
|
|
32227
|
+
if (!existsSync31(filePath))
|
|
31946
32228
|
return null;
|
|
31947
32229
|
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
31948
32230
|
} catch {
|
|
@@ -31991,8 +32273,8 @@ function detectManifests(repoRoot) {
|
|
|
31991
32273
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
31992
32274
|
];
|
|
31993
32275
|
for (const check of checks) {
|
|
31994
|
-
const filePath =
|
|
31995
|
-
if (
|
|
32276
|
+
const filePath = join40(repoRoot, check.file);
|
|
32277
|
+
if (existsSync31(filePath)) {
|
|
31996
32278
|
let name;
|
|
31997
32279
|
if (check.nameField) {
|
|
31998
32280
|
try {
|
|
@@ -32025,7 +32307,7 @@ function findKeyFiles(repoRoot) {
|
|
|
32025
32307
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
32026
32308
|
];
|
|
32027
32309
|
for (const check of checks) {
|
|
32028
|
-
if (
|
|
32310
|
+
if (existsSync31(join40(repoRoot, check.pattern))) {
|
|
32029
32311
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
32030
32312
|
}
|
|
32031
32313
|
}
|
|
@@ -32051,12 +32333,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
32051
32333
|
if (entry.isDirectory()) {
|
|
32052
32334
|
let fileCount = 0;
|
|
32053
32335
|
try {
|
|
32054
|
-
fileCount = readdirSync8(
|
|
32336
|
+
fileCount = readdirSync8(join40(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
32055
32337
|
} catch {
|
|
32056
32338
|
}
|
|
32057
32339
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
32058
32340
|
`;
|
|
32059
|
-
result += buildDirTree(
|
|
32341
|
+
result += buildDirTree(join40(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
32060
32342
|
} else if (depth < maxDepth) {
|
|
32061
32343
|
result += `${prefix}${connector}${entry.name}
|
|
32062
32344
|
`;
|
|
@@ -32068,7 +32350,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
32068
32350
|
}
|
|
32069
32351
|
function loadUsageFile(filePath) {
|
|
32070
32352
|
try {
|
|
32071
|
-
if (
|
|
32353
|
+
if (existsSync31(filePath)) {
|
|
32072
32354
|
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
32073
32355
|
}
|
|
32074
32356
|
} catch {
|
|
@@ -32076,9 +32358,9 @@ function loadUsageFile(filePath) {
|
|
|
32076
32358
|
return { records: [] };
|
|
32077
32359
|
}
|
|
32078
32360
|
function saveUsageFile(filePath, data) {
|
|
32079
|
-
const dir =
|
|
32361
|
+
const dir = join40(filePath, "..");
|
|
32080
32362
|
mkdirSync11(dir, { recursive: true });
|
|
32081
|
-
|
|
32363
|
+
writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
32082
32364
|
}
|
|
32083
32365
|
function recordUsage(kind, value, opts) {
|
|
32084
32366
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -32106,15 +32388,15 @@ function recordUsage(kind, value, opts) {
|
|
|
32106
32388
|
}
|
|
32107
32389
|
saveUsageFile(filePath, data);
|
|
32108
32390
|
};
|
|
32109
|
-
update(
|
|
32391
|
+
update(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
|
|
32110
32392
|
if (opts?.repoRoot) {
|
|
32111
|
-
update(
|
|
32393
|
+
update(join40(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
32112
32394
|
}
|
|
32113
32395
|
}
|
|
32114
32396
|
function loadUsageHistory(kind, repoRoot) {
|
|
32115
|
-
const globalPath =
|
|
32397
|
+
const globalPath = join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
|
|
32116
32398
|
const globalData = loadUsageFile(globalPath);
|
|
32117
|
-
const localData = repoRoot ? loadUsageFile(
|
|
32399
|
+
const localData = repoRoot ? loadUsageFile(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
32118
32400
|
const map = /* @__PURE__ */ new Map();
|
|
32119
32401
|
for (const r of globalData.records) {
|
|
32120
32402
|
if (r.kind !== kind)
|
|
@@ -32145,9 +32427,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
32145
32427
|
saveUsageFile(filePath, data);
|
|
32146
32428
|
}
|
|
32147
32429
|
};
|
|
32148
|
-
remove(
|
|
32430
|
+
remove(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
|
|
32149
32431
|
if (repoRoot) {
|
|
32150
|
-
remove(
|
|
32432
|
+
remove(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
32151
32433
|
}
|
|
32152
32434
|
}
|
|
32153
32435
|
var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -32197,8 +32479,8 @@ var init_oa_directory = __esm({
|
|
|
32197
32479
|
import * as readline from "node:readline";
|
|
32198
32480
|
import { execSync as execSync25, spawn as spawn17, exec as exec2 } from "node:child_process";
|
|
32199
32481
|
import { promisify as promisify5 } from "node:util";
|
|
32200
|
-
import { existsSync as
|
|
32201
|
-
import { join as
|
|
32482
|
+
import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
|
|
32483
|
+
import { join as join41 } from "node:path";
|
|
32202
32484
|
import { homedir as homedir10, platform } from "node:os";
|
|
32203
32485
|
function detectSystemSpecs() {
|
|
32204
32486
|
let totalRamGB = 0;
|
|
@@ -32485,7 +32767,7 @@ async function installOllamaMac(_rl) {
|
|
|
32485
32767
|
execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
32486
32768
|
if (!hasCmd("brew")) {
|
|
32487
32769
|
try {
|
|
32488
|
-
const brewPrefix =
|
|
32770
|
+
const brewPrefix = existsSync32("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
32489
32771
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
32490
32772
|
} catch {
|
|
32491
32773
|
}
|
|
@@ -33239,10 +33521,10 @@ async function doSetup(config, rl) {
|
|
|
33239
33521
|
`PARAMETER num_predict ${numPredict}`,
|
|
33240
33522
|
`PARAMETER stop "<|endoftext|>"`
|
|
33241
33523
|
].join("\n");
|
|
33242
|
-
const modelDir2 =
|
|
33524
|
+
const modelDir2 = join41(homedir10(), ".open-agents", "models");
|
|
33243
33525
|
mkdirSync12(modelDir2, { recursive: true });
|
|
33244
|
-
const modelfilePath =
|
|
33245
|
-
|
|
33526
|
+
const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
|
|
33527
|
+
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
33246
33528
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
33247
33529
|
execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
33248
33530
|
stdio: "pipe",
|
|
@@ -33287,7 +33569,7 @@ async function isModelAvailable(config) {
|
|
|
33287
33569
|
}
|
|
33288
33570
|
function isFirstRun() {
|
|
33289
33571
|
try {
|
|
33290
|
-
return !
|
|
33572
|
+
return !existsSync32(join41(homedir10(), ".open-agents", "config.json"));
|
|
33291
33573
|
} catch {
|
|
33292
33574
|
return true;
|
|
33293
33575
|
}
|
|
@@ -33324,7 +33606,7 @@ function detectPkgManager() {
|
|
|
33324
33606
|
return null;
|
|
33325
33607
|
}
|
|
33326
33608
|
function getVenvDir() {
|
|
33327
|
-
return
|
|
33609
|
+
return join41(homedir10(), ".open-agents", "venv");
|
|
33328
33610
|
}
|
|
33329
33611
|
function hasVenvModule() {
|
|
33330
33612
|
try {
|
|
@@ -33336,8 +33618,8 @@ function hasVenvModule() {
|
|
|
33336
33618
|
}
|
|
33337
33619
|
function ensureVenv(log) {
|
|
33338
33620
|
const venvDir = getVenvDir();
|
|
33339
|
-
const venvPip =
|
|
33340
|
-
if (
|
|
33621
|
+
const venvPip = join41(venvDir, "bin", "pip");
|
|
33622
|
+
if (existsSync32(venvPip))
|
|
33341
33623
|
return venvDir;
|
|
33342
33624
|
log("Creating Python venv for vision deps...");
|
|
33343
33625
|
if (!hasCmd("python3")) {
|
|
@@ -33349,9 +33631,9 @@ function ensureVenv(log) {
|
|
|
33349
33631
|
return null;
|
|
33350
33632
|
}
|
|
33351
33633
|
try {
|
|
33352
|
-
mkdirSync12(
|
|
33634
|
+
mkdirSync12(join41(homedir10(), ".open-agents"), { recursive: true });
|
|
33353
33635
|
execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
33354
|
-
execSync25(`"${
|
|
33636
|
+
execSync25(`"${join41(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
33355
33637
|
stdio: "pipe",
|
|
33356
33638
|
timeout: 6e4
|
|
33357
33639
|
});
|
|
@@ -33542,15 +33824,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
33542
33824
|
}
|
|
33543
33825
|
}
|
|
33544
33826
|
const venvDir = getVenvDir();
|
|
33545
|
-
const venvBin =
|
|
33546
|
-
const venvMoondream =
|
|
33827
|
+
const venvBin = join41(venvDir, "bin");
|
|
33828
|
+
const venvMoondream = join41(venvBin, "moondream-station");
|
|
33547
33829
|
const venv = ensureVenv(log);
|
|
33548
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
33549
|
-
const venvPip =
|
|
33830
|
+
if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
|
|
33831
|
+
const venvPip = join41(venvBin, "pip");
|
|
33550
33832
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
33551
33833
|
try {
|
|
33552
33834
|
execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
33553
|
-
if (
|
|
33835
|
+
if (existsSync32(venvMoondream)) {
|
|
33554
33836
|
log("moondream-station installed successfully.");
|
|
33555
33837
|
} else {
|
|
33556
33838
|
try {
|
|
@@ -33567,8 +33849,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
33567
33849
|
}
|
|
33568
33850
|
}
|
|
33569
33851
|
if (venv) {
|
|
33570
|
-
const venvPython =
|
|
33571
|
-
const venvPip2 =
|
|
33852
|
+
const venvPython = join41(venvBin, "python");
|
|
33853
|
+
const venvPip2 = join41(venvBin, "pip");
|
|
33572
33854
|
let ocrStackInstalled = false;
|
|
33573
33855
|
try {
|
|
33574
33856
|
execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
@@ -33712,10 +33994,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
33712
33994
|
`PARAMETER num_predict ${numPredict}`,
|
|
33713
33995
|
`PARAMETER stop "<|endoftext|>"`
|
|
33714
33996
|
].join("\n");
|
|
33715
|
-
const modelDir2 =
|
|
33997
|
+
const modelDir2 = join41(homedir10(), ".open-agents", "models");
|
|
33716
33998
|
mkdirSync12(modelDir2, { recursive: true });
|
|
33717
|
-
const modelfilePath =
|
|
33718
|
-
|
|
33999
|
+
const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
|
|
34000
|
+
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
33719
34001
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
33720
34002
|
timeout: 12e4
|
|
33721
34003
|
});
|
|
@@ -33789,8 +34071,8 @@ async function ensureNeovim() {
|
|
|
33789
34071
|
const platform5 = process.platform;
|
|
33790
34072
|
const arch = process.arch;
|
|
33791
34073
|
if (platform5 === "linux") {
|
|
33792
|
-
const binDir =
|
|
33793
|
-
const nvimDest =
|
|
34074
|
+
const binDir = join41(homedir10(), ".local", "bin");
|
|
34075
|
+
const nvimDest = join41(binDir, "nvim");
|
|
33794
34076
|
try {
|
|
33795
34077
|
mkdirSync12(binDir, { recursive: true });
|
|
33796
34078
|
} catch {
|
|
@@ -33861,9 +34143,9 @@ async function ensureNeovim() {
|
|
|
33861
34143
|
}
|
|
33862
34144
|
function ensurePathInShellRc(binDir) {
|
|
33863
34145
|
const shell = process.env.SHELL ?? "";
|
|
33864
|
-
const rcFile = shell.includes("zsh") ?
|
|
34146
|
+
const rcFile = shell.includes("zsh") ? join41(homedir10(), ".zshrc") : join41(homedir10(), ".bashrc");
|
|
33865
34147
|
try {
|
|
33866
|
-
const rcContent =
|
|
34148
|
+
const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
|
|
33867
34149
|
if (rcContent.includes(binDir))
|
|
33868
34150
|
return;
|
|
33869
34151
|
const exportLine = `
|
|
@@ -34445,7 +34727,7 @@ var init_tui_select = __esm({
|
|
|
34445
34727
|
});
|
|
34446
34728
|
|
|
34447
34729
|
// packages/cli/dist/tui/drop-panel.js
|
|
34448
|
-
import { existsSync as
|
|
34730
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
34449
34731
|
import { extname as extname9, resolve as resolve27 } from "node:path";
|
|
34450
34732
|
function ansi4(code, text) {
|
|
34451
34733
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
@@ -34560,7 +34842,7 @@ function showDropPanel(opts) {
|
|
|
34560
34842
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
34561
34843
|
}
|
|
34562
34844
|
filePath = resolve27(filePath);
|
|
34563
|
-
if (!
|
|
34845
|
+
if (!existsSync33(filePath)) {
|
|
34564
34846
|
errorMsg = `File not found: ${filePath}`;
|
|
34565
34847
|
render();
|
|
34566
34848
|
return;
|
|
@@ -34631,9 +34913,9 @@ var init_drop_panel = __esm({
|
|
|
34631
34913
|
});
|
|
34632
34914
|
|
|
34633
34915
|
// packages/cli/dist/tui/neovim-mode.js
|
|
34634
|
-
import { existsSync as
|
|
34635
|
-
import { tmpdir as
|
|
34636
|
-
import { join as
|
|
34916
|
+
import { existsSync as existsSync34, unlinkSync as unlinkSync6 } from "node:fs";
|
|
34917
|
+
import { tmpdir as tmpdir7 } from "node:os";
|
|
34918
|
+
import { join as join42 } from "node:path";
|
|
34637
34919
|
import { execSync as execSync26 } from "node:child_process";
|
|
34638
34920
|
function isNeovimActive() {
|
|
34639
34921
|
return _state !== null && !_state.cleanedUp;
|
|
@@ -34681,10 +34963,10 @@ async function startNeovimMode(opts) {
|
|
|
34681
34963
|
);
|
|
34682
34964
|
} catch {
|
|
34683
34965
|
}
|
|
34684
|
-
const socketPath =
|
|
34966
|
+
const socketPath = join42(tmpdir7(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
34685
34967
|
try {
|
|
34686
|
-
if (
|
|
34687
|
-
|
|
34968
|
+
if (existsSync34(socketPath))
|
|
34969
|
+
unlinkSync6(socketPath);
|
|
34688
34970
|
} catch {
|
|
34689
34971
|
}
|
|
34690
34972
|
const ptyCols = opts.cols;
|
|
@@ -34834,13 +35116,13 @@ function resizeNeovim(cols, contentRows) {
|
|
|
34834
35116
|
}
|
|
34835
35117
|
async function connectRPC(state, neovimPkg, cols) {
|
|
34836
35118
|
let attempts = 0;
|
|
34837
|
-
while (!
|
|
35119
|
+
while (!existsSync34(state.socketPath) && attempts < 30) {
|
|
34838
35120
|
await new Promise((r) => setTimeout(r, 200));
|
|
34839
35121
|
attempts++;
|
|
34840
35122
|
if (state.cleanedUp)
|
|
34841
35123
|
return;
|
|
34842
35124
|
}
|
|
34843
|
-
if (!
|
|
35125
|
+
if (!existsSync34(state.socketPath))
|
|
34844
35126
|
return;
|
|
34845
35127
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
34846
35128
|
state.nvim = nvim;
|
|
@@ -34976,8 +35258,8 @@ function doCleanup(state) {
|
|
|
34976
35258
|
state.pty = null;
|
|
34977
35259
|
}
|
|
34978
35260
|
try {
|
|
34979
|
-
if (
|
|
34980
|
-
|
|
35261
|
+
if (existsSync34(state.socketPath))
|
|
35262
|
+
unlinkSync6(state.socketPath);
|
|
34981
35263
|
} catch {
|
|
34982
35264
|
}
|
|
34983
35265
|
if (state.stdinHandler) {
|
|
@@ -35032,9 +35314,9 @@ __export(voice_exports, {
|
|
|
35032
35314
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
35033
35315
|
resetNarrationContext: () => resetNarrationContext
|
|
35034
35316
|
});
|
|
35035
|
-
import { existsSync as
|
|
35036
|
-
import { join as
|
|
35037
|
-
import { homedir as homedir11, tmpdir as
|
|
35317
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync7, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
|
|
35318
|
+
import { join as join43 } from "node:path";
|
|
35319
|
+
import { homedir as homedir11, tmpdir as tmpdir8, platform as platform2 } from "node:os";
|
|
35038
35320
|
import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
|
|
35039
35321
|
import { createRequire } from "node:module";
|
|
35040
35322
|
function registerCustomOnnxModel(id, label) {
|
|
@@ -35055,34 +35337,34 @@ function listVoiceModels() {
|
|
|
35055
35337
|
}));
|
|
35056
35338
|
}
|
|
35057
35339
|
function voiceDir() {
|
|
35058
|
-
return
|
|
35340
|
+
return join43(homedir11(), ".open-agents", "voice");
|
|
35059
35341
|
}
|
|
35060
35342
|
function modelsDir() {
|
|
35061
|
-
return
|
|
35343
|
+
return join43(voiceDir(), "models");
|
|
35062
35344
|
}
|
|
35063
35345
|
function modelDir(id) {
|
|
35064
|
-
return
|
|
35346
|
+
return join43(modelsDir(), id);
|
|
35065
35347
|
}
|
|
35066
35348
|
function modelOnnxPath(id) {
|
|
35067
|
-
return
|
|
35349
|
+
return join43(modelDir(id), "model.onnx");
|
|
35068
35350
|
}
|
|
35069
35351
|
function modelConfigPath(id) {
|
|
35070
|
-
return
|
|
35352
|
+
return join43(modelDir(id), "config.json");
|
|
35071
35353
|
}
|
|
35072
35354
|
function luxttsVenvDir() {
|
|
35073
|
-
return
|
|
35355
|
+
return join43(voiceDir(), "luxtts-venv");
|
|
35074
35356
|
}
|
|
35075
35357
|
function luxttsVenvPy() {
|
|
35076
|
-
return platform2() === "win32" ?
|
|
35358
|
+
return platform2() === "win32" ? join43(luxttsVenvDir(), "Scripts", "python.exe") : join43(luxttsVenvDir(), "bin", "python3");
|
|
35077
35359
|
}
|
|
35078
35360
|
function luxttsRepoDir() {
|
|
35079
|
-
return
|
|
35361
|
+
return join43(voiceDir(), "LuxTTS");
|
|
35080
35362
|
}
|
|
35081
35363
|
function luxttsCloneRefsDir() {
|
|
35082
|
-
return
|
|
35364
|
+
return join43(voiceDir(), "clone-refs");
|
|
35083
35365
|
}
|
|
35084
35366
|
function luxttsInferScript() {
|
|
35085
|
-
return
|
|
35367
|
+
return join43(voiceDir(), "luxtts-infer.py");
|
|
35086
35368
|
}
|
|
35087
35369
|
function emotionToPitchBias(emotion, stark = false, autist = false) {
|
|
35088
35370
|
if (autist)
|
|
@@ -35890,8 +36172,8 @@ var init_voice = __esm({
|
|
|
35890
36172
|
const refsDir = luxttsCloneRefsDir();
|
|
35891
36173
|
const targets = ["glados", "overwatch"];
|
|
35892
36174
|
for (const modelId of targets) {
|
|
35893
|
-
const refFile =
|
|
35894
|
-
if (
|
|
36175
|
+
const refFile = join43(refsDir, `${modelId}-ref.wav`);
|
|
36176
|
+
if (existsSync35(refFile))
|
|
35895
36177
|
continue;
|
|
35896
36178
|
try {
|
|
35897
36179
|
await this.generateCloneRef(modelId);
|
|
@@ -35970,24 +36252,24 @@ var init_voice = __esm({
|
|
|
35970
36252
|
}
|
|
35971
36253
|
p = p.replace(/\\ /g, " ");
|
|
35972
36254
|
if (p.startsWith("~/") || p === "~") {
|
|
35973
|
-
p =
|
|
36255
|
+
p = join43(homedir11(), p.slice(1));
|
|
35974
36256
|
}
|
|
35975
|
-
if (!
|
|
36257
|
+
if (!existsSync35(p)) {
|
|
35976
36258
|
return `File not found: ${p}
|
|
35977
36259
|
(original input: ${audioPath})`;
|
|
35978
36260
|
}
|
|
35979
36261
|
audioPath = p;
|
|
35980
36262
|
const refsDir = luxttsCloneRefsDir();
|
|
35981
|
-
if (!
|
|
36263
|
+
if (!existsSync35(refsDir))
|
|
35982
36264
|
mkdirSync13(refsDir, { recursive: true });
|
|
35983
36265
|
const ext = audioPath.split(".").pop() || "wav";
|
|
35984
36266
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
35985
36267
|
const ts = Date.now().toString(36);
|
|
35986
36268
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
35987
|
-
const destPath =
|
|
36269
|
+
const destPath = join43(refsDir, destFilename);
|
|
35988
36270
|
try {
|
|
35989
36271
|
const data = readFileSync24(audioPath);
|
|
35990
|
-
|
|
36272
|
+
writeFileSync14(destPath, data);
|
|
35991
36273
|
} catch (err) {
|
|
35992
36274
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
35993
36275
|
}
|
|
@@ -36027,9 +36309,9 @@ var init_voice = __esm({
|
|
|
36027
36309
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
36028
36310
|
}
|
|
36029
36311
|
const refsDir = luxttsCloneRefsDir();
|
|
36030
|
-
if (!
|
|
36312
|
+
if (!existsSync35(refsDir))
|
|
36031
36313
|
mkdirSync13(refsDir, { recursive: true });
|
|
36032
|
-
const destPath =
|
|
36314
|
+
const destPath = join43(refsDir, `${sourceModelId}-ref.wav`);
|
|
36033
36315
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
36034
36316
|
this.writeWav(audioData, sampleRate, destPath);
|
|
36035
36317
|
this.luxttsCloneRef = destPath;
|
|
@@ -36045,11 +36327,11 @@ var init_voice = __esm({
|
|
|
36045
36327
|
// -------------------------------------------------------------------------
|
|
36046
36328
|
/** Metadata file for friendly names of clone refs */
|
|
36047
36329
|
static cloneMetaFile() {
|
|
36048
|
-
return
|
|
36330
|
+
return join43(luxttsCloneRefsDir(), "meta.json");
|
|
36049
36331
|
}
|
|
36050
36332
|
loadCloneMeta() {
|
|
36051
36333
|
const p = _VoiceEngine.cloneMetaFile();
|
|
36052
|
-
if (!
|
|
36334
|
+
if (!existsSync35(p))
|
|
36053
36335
|
return {};
|
|
36054
36336
|
try {
|
|
36055
36337
|
return JSON.parse(readFileSync24(p, "utf8"));
|
|
@@ -36059,9 +36341,9 @@ var init_voice = __esm({
|
|
|
36059
36341
|
}
|
|
36060
36342
|
saveCloneMeta(meta) {
|
|
36061
36343
|
const dir = luxttsCloneRefsDir();
|
|
36062
|
-
if (!
|
|
36344
|
+
if (!existsSync35(dir))
|
|
36063
36345
|
mkdirSync13(dir, { recursive: true });
|
|
36064
|
-
|
|
36346
|
+
writeFileSync14(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
36065
36347
|
}
|
|
36066
36348
|
/** Audio file extensions recognized as clone references */
|
|
36067
36349
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -36071,7 +36353,7 @@ var init_voice = __esm({
|
|
|
36071
36353
|
*/
|
|
36072
36354
|
listCloneRefs() {
|
|
36073
36355
|
const dir = luxttsCloneRefsDir();
|
|
36074
|
-
if (!
|
|
36356
|
+
if (!existsSync35(dir))
|
|
36075
36357
|
return [];
|
|
36076
36358
|
const meta = this.loadCloneMeta();
|
|
36077
36359
|
const files = readdirSync9(dir).filter((f) => {
|
|
@@ -36079,10 +36361,10 @@ var init_voice = __esm({
|
|
|
36079
36361
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
36080
36362
|
});
|
|
36081
36363
|
return files.map((f) => {
|
|
36082
|
-
const p =
|
|
36364
|
+
const p = join43(dir, f);
|
|
36083
36365
|
let size = 0;
|
|
36084
36366
|
try {
|
|
36085
|
-
size =
|
|
36367
|
+
size = statSync12(p).size;
|
|
36086
36368
|
} catch {
|
|
36087
36369
|
}
|
|
36088
36370
|
return {
|
|
@@ -36096,11 +36378,11 @@ var init_voice = __esm({
|
|
|
36096
36378
|
}
|
|
36097
36379
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
36098
36380
|
deleteCloneRef(filename) {
|
|
36099
|
-
const p =
|
|
36100
|
-
if (!
|
|
36381
|
+
const p = join43(luxttsCloneRefsDir(), filename);
|
|
36382
|
+
if (!existsSync35(p))
|
|
36101
36383
|
return false;
|
|
36102
36384
|
try {
|
|
36103
|
-
|
|
36385
|
+
unlinkSync7(p);
|
|
36104
36386
|
const meta = this.loadCloneMeta();
|
|
36105
36387
|
delete meta[filename];
|
|
36106
36388
|
this.saveCloneMeta(meta);
|
|
@@ -36121,8 +36403,8 @@ var init_voice = __esm({
|
|
|
36121
36403
|
}
|
|
36122
36404
|
/** Set the active clone reference by filename. */
|
|
36123
36405
|
setActiveCloneRef(filename) {
|
|
36124
|
-
const p =
|
|
36125
|
-
if (!
|
|
36406
|
+
const p = join43(luxttsCloneRefsDir(), filename);
|
|
36407
|
+
if (!existsSync35(p))
|
|
36126
36408
|
return `File not found: ${filename}`;
|
|
36127
36409
|
this.luxttsCloneRef = p;
|
|
36128
36410
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -36407,11 +36689,11 @@ var init_voice = __esm({
|
|
|
36407
36689
|
}
|
|
36408
36690
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
36409
36691
|
}
|
|
36410
|
-
const wavPath =
|
|
36692
|
+
const wavPath = join43(tmpdir8(), `oa-voice-${Date.now()}.wav`);
|
|
36411
36693
|
this.writeWav(audioData, sampleRate, wavPath);
|
|
36412
36694
|
await this.playWav(wavPath);
|
|
36413
36695
|
try {
|
|
36414
|
-
|
|
36696
|
+
unlinkSync7(wavPath);
|
|
36415
36697
|
} catch {
|
|
36416
36698
|
}
|
|
36417
36699
|
}
|
|
@@ -36545,7 +36827,7 @@ var init_voice = __esm({
|
|
|
36545
36827
|
return buffer;
|
|
36546
36828
|
}
|
|
36547
36829
|
writeWav(samples, sampleRate, path) {
|
|
36548
|
-
|
|
36830
|
+
writeFileSync14(path, this.buildWavBuffer(samples, sampleRate));
|
|
36549
36831
|
}
|
|
36550
36832
|
// -------------------------------------------------------------------------
|
|
36551
36833
|
// Audio playback (system default speakers)
|
|
@@ -36656,7 +36938,7 @@ var init_voice = __esm({
|
|
|
36656
36938
|
return new Promise((resolve32, reject) => {
|
|
36657
36939
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
36658
36940
|
stdio: ["ignore", "pipe", "pipe"],
|
|
36659
|
-
cwd:
|
|
36941
|
+
cwd: tmpdir8()
|
|
36660
36942
|
});
|
|
36661
36943
|
let stdout = "";
|
|
36662
36944
|
let stderr = "";
|
|
@@ -36750,7 +37032,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36750
37032
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
36751
37033
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
36752
37034
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
36753
|
-
const wavPath =
|
|
37035
|
+
const wavPath = join43(tmpdir8(), `oa-mlx-${Date.now()}.wav`);
|
|
36754
37036
|
const pyScript = [
|
|
36755
37037
|
"import sys, json",
|
|
36756
37038
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -36758,16 +37040,16 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36758
37040
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
36759
37041
|
].join("; ");
|
|
36760
37042
|
try {
|
|
36761
|
-
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37043
|
+
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
|
|
36762
37044
|
} catch (err) {
|
|
36763
37045
|
try {
|
|
36764
37046
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
36765
|
-
execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37047
|
+
execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
|
|
36766
37048
|
} catch (err2) {
|
|
36767
37049
|
return;
|
|
36768
37050
|
}
|
|
36769
37051
|
}
|
|
36770
|
-
if (!
|
|
37052
|
+
if (!existsSync35(wavPath))
|
|
36771
37053
|
return;
|
|
36772
37054
|
if (volume !== 1) {
|
|
36773
37055
|
try {
|
|
@@ -36779,7 +37061,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36779
37061
|
samples[i] = Math.round(samples[i] * volume);
|
|
36780
37062
|
}
|
|
36781
37063
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
36782
|
-
|
|
37064
|
+
writeFileSync14(wavPath, scaled);
|
|
36783
37065
|
}
|
|
36784
37066
|
} catch {
|
|
36785
37067
|
}
|
|
@@ -36797,7 +37079,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36797
37079
|
}
|
|
36798
37080
|
await this.playWav(wavPath);
|
|
36799
37081
|
try {
|
|
36800
|
-
|
|
37082
|
+
unlinkSync7(wavPath);
|
|
36801
37083
|
} catch {
|
|
36802
37084
|
}
|
|
36803
37085
|
}
|
|
@@ -36818,7 +37100,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36818
37100
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
36819
37101
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
36820
37102
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
36821
|
-
const wavPath =
|
|
37103
|
+
const wavPath = join43(tmpdir8(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
36822
37104
|
const pyScript = [
|
|
36823
37105
|
"import sys, json",
|
|
36824
37106
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -36826,20 +37108,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36826
37108
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
36827
37109
|
].join("; ");
|
|
36828
37110
|
try {
|
|
36829
|
-
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37111
|
+
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
|
|
36830
37112
|
} catch {
|
|
36831
37113
|
try {
|
|
36832
37114
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
36833
|
-
execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37115
|
+
execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
|
|
36834
37116
|
} catch {
|
|
36835
37117
|
return null;
|
|
36836
37118
|
}
|
|
36837
37119
|
}
|
|
36838
|
-
if (!
|
|
37120
|
+
if (!existsSync35(wavPath))
|
|
36839
37121
|
return null;
|
|
36840
37122
|
try {
|
|
36841
37123
|
const data = readFileSync24(wavPath);
|
|
36842
|
-
|
|
37124
|
+
unlinkSync7(wavPath);
|
|
36843
37125
|
return data;
|
|
36844
37126
|
} catch {
|
|
36845
37127
|
return null;
|
|
@@ -36861,7 +37143,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36861
37143
|
}
|
|
36862
37144
|
const venvDir = luxttsVenvDir();
|
|
36863
37145
|
const venvPy = luxttsVenvPy();
|
|
36864
|
-
if (
|
|
37146
|
+
if (existsSync35(venvPy)) {
|
|
36865
37147
|
try {
|
|
36866
37148
|
await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
|
|
36867
37149
|
let hasCudaSys = false;
|
|
@@ -36891,7 +37173,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36891
37173
|
}
|
|
36892
37174
|
}
|
|
36893
37175
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
36894
|
-
if (!
|
|
37176
|
+
if (!existsSync35(venvDir)) {
|
|
36895
37177
|
renderInfo(" Creating Python virtual environment...");
|
|
36896
37178
|
try {
|
|
36897
37179
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -36929,10 +37211,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36929
37211
|
}
|
|
36930
37212
|
}
|
|
36931
37213
|
const repoDir = luxttsRepoDir();
|
|
36932
|
-
if (!
|
|
37214
|
+
if (!existsSync35(join43(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
36933
37215
|
renderInfo(" Cloning LuxTTS repository...");
|
|
36934
37216
|
try {
|
|
36935
|
-
if (
|
|
37217
|
+
if (existsSync35(repoDir)) {
|
|
36936
37218
|
await this.asyncShell(`rm -rf ${JSON.stringify(repoDir)}`, 3e4);
|
|
36937
37219
|
}
|
|
36938
37220
|
await this.asyncShell(`git clone --depth 1 https://github.com/ysharma3501/LuxTTS.git ${JSON.stringify(repoDir)}`, 12e4);
|
|
@@ -36972,14 +37254,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
36972
37254
|
}
|
|
36973
37255
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
36974
37256
|
autoDetectCloneRef() {
|
|
36975
|
-
if (this.luxttsCloneRef &&
|
|
37257
|
+
if (this.luxttsCloneRef && existsSync35(this.luxttsCloneRef))
|
|
36976
37258
|
return;
|
|
36977
37259
|
const refsDir = luxttsCloneRefsDir();
|
|
36978
|
-
if (!
|
|
37260
|
+
if (!existsSync35(refsDir))
|
|
36979
37261
|
return;
|
|
36980
37262
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
36981
|
-
const p =
|
|
36982
|
-
if (
|
|
37263
|
+
const p = join43(refsDir, name);
|
|
37264
|
+
if (existsSync35(p)) {
|
|
36983
37265
|
this.luxttsCloneRef = p;
|
|
36984
37266
|
return;
|
|
36985
37267
|
}
|
|
@@ -37080,20 +37362,20 @@ if __name__ == '__main__':
|
|
|
37080
37362
|
`;
|
|
37081
37363
|
const scriptPath2 = luxttsInferScript();
|
|
37082
37364
|
mkdirSync13(voiceDir(), { recursive: true });
|
|
37083
|
-
|
|
37365
|
+
writeFileSync14(scriptPath2, script);
|
|
37084
37366
|
}
|
|
37085
37367
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
37086
37368
|
async ensureLuxttsDaemon() {
|
|
37087
37369
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
37088
37370
|
return true;
|
|
37089
37371
|
const venvPy = luxttsVenvPy();
|
|
37090
|
-
if (!
|
|
37372
|
+
if (!existsSync35(venvPy))
|
|
37091
37373
|
return false;
|
|
37092
37374
|
return new Promise((resolve32) => {
|
|
37093
37375
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
37094
37376
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
37095
37377
|
stdio: ["pipe", "pipe", "pipe"],
|
|
37096
|
-
cwd:
|
|
37378
|
+
cwd: tmpdir8(),
|
|
37097
37379
|
env
|
|
37098
37380
|
});
|
|
37099
37381
|
this._luxttsDaemon = daemon;
|
|
@@ -37166,7 +37448,7 @@ if __name__ == '__main__':
|
|
|
37166
37448
|
* Volume is applied via WAV sample scaling.
|
|
37167
37449
|
*/
|
|
37168
37450
|
async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1) {
|
|
37169
|
-
if (!this.luxttsCloneRef || !
|
|
37451
|
+
if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef)) {
|
|
37170
37452
|
return;
|
|
37171
37453
|
}
|
|
37172
37454
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
@@ -37175,7 +37457,7 @@ if __name__ == '__main__':
|
|
|
37175
37457
|
const ready = await this.ensureLuxttsDaemon();
|
|
37176
37458
|
if (!ready)
|
|
37177
37459
|
return;
|
|
37178
|
-
const wavPath =
|
|
37460
|
+
const wavPath = join43(tmpdir8(), `oa-luxtts-${Date.now()}.wav`);
|
|
37179
37461
|
try {
|
|
37180
37462
|
await this.luxttsRequest({
|
|
37181
37463
|
action: "synthesize",
|
|
@@ -37187,7 +37469,7 @@ if __name__ == '__main__':
|
|
|
37187
37469
|
} catch {
|
|
37188
37470
|
return;
|
|
37189
37471
|
}
|
|
37190
|
-
if (!
|
|
37472
|
+
if (!existsSync35(wavPath))
|
|
37191
37473
|
return;
|
|
37192
37474
|
if (volume !== 1) {
|
|
37193
37475
|
try {
|
|
@@ -37199,7 +37481,7 @@ if __name__ == '__main__':
|
|
|
37199
37481
|
}
|
|
37200
37482
|
const header = wavData.subarray(0, 44);
|
|
37201
37483
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
37202
|
-
|
|
37484
|
+
writeFileSync14(wavPath, scaled);
|
|
37203
37485
|
}
|
|
37204
37486
|
} catch {
|
|
37205
37487
|
}
|
|
@@ -37232,7 +37514,7 @@ if __name__ == '__main__':
|
|
|
37232
37514
|
}
|
|
37233
37515
|
await this.playWav(wavPath);
|
|
37234
37516
|
try {
|
|
37235
|
-
|
|
37517
|
+
unlinkSync7(wavPath);
|
|
37236
37518
|
} catch {
|
|
37237
37519
|
}
|
|
37238
37520
|
}
|
|
@@ -37241,7 +37523,7 @@ if __name__ == '__main__':
|
|
|
37241
37523
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
37242
37524
|
*/
|
|
37243
37525
|
async synthesizeLuxttsToBuffer(text) {
|
|
37244
|
-
if (!this.luxttsCloneRef || !
|
|
37526
|
+
if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef))
|
|
37245
37527
|
return null;
|
|
37246
37528
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
37247
37529
|
if (!cleaned)
|
|
@@ -37249,7 +37531,7 @@ if __name__ == '__main__':
|
|
|
37249
37531
|
const ready = await this.ensureLuxttsDaemon();
|
|
37250
37532
|
if (!ready)
|
|
37251
37533
|
return null;
|
|
37252
|
-
const wavPath =
|
|
37534
|
+
const wavPath = join43(tmpdir8(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
37253
37535
|
try {
|
|
37254
37536
|
await this.luxttsRequest({
|
|
37255
37537
|
action: "synthesize",
|
|
@@ -37261,11 +37543,11 @@ if __name__ == '__main__':
|
|
|
37261
37543
|
} catch {
|
|
37262
37544
|
return null;
|
|
37263
37545
|
}
|
|
37264
|
-
if (!
|
|
37546
|
+
if (!existsSync35(wavPath))
|
|
37265
37547
|
return null;
|
|
37266
37548
|
try {
|
|
37267
37549
|
const data = readFileSync24(wavPath);
|
|
37268
|
-
|
|
37550
|
+
unlinkSync7(wavPath);
|
|
37269
37551
|
return data;
|
|
37270
37552
|
} catch {
|
|
37271
37553
|
return null;
|
|
@@ -37279,40 +37561,40 @@ if __name__ == '__main__':
|
|
|
37279
37561
|
return;
|
|
37280
37562
|
const arch = process.arch;
|
|
37281
37563
|
mkdirSync13(voiceDir(), { recursive: true });
|
|
37282
|
-
const pkgPath =
|
|
37564
|
+
const pkgPath = join43(voiceDir(), "package.json");
|
|
37283
37565
|
const expectedDeps = {
|
|
37284
37566
|
"onnxruntime-node": "^1.21.0",
|
|
37285
37567
|
"phonemizer": "^1.2.1"
|
|
37286
37568
|
};
|
|
37287
|
-
if (
|
|
37569
|
+
if (existsSync35(pkgPath)) {
|
|
37288
37570
|
try {
|
|
37289
37571
|
const existing = JSON.parse(readFileSync24(pkgPath, "utf8"));
|
|
37290
37572
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
37291
37573
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
37292
|
-
|
|
37574
|
+
writeFileSync14(pkgPath, JSON.stringify(existing, null, 2));
|
|
37293
37575
|
}
|
|
37294
37576
|
} catch {
|
|
37295
37577
|
}
|
|
37296
37578
|
}
|
|
37297
|
-
if (!
|
|
37298
|
-
|
|
37579
|
+
if (!existsSync35(pkgPath)) {
|
|
37580
|
+
writeFileSync14(pkgPath, JSON.stringify({
|
|
37299
37581
|
name: "open-agents-voice",
|
|
37300
37582
|
private: true,
|
|
37301
37583
|
dependencies: expectedDeps
|
|
37302
37584
|
}, null, 2));
|
|
37303
37585
|
}
|
|
37304
|
-
const voiceRequire = createRequire(
|
|
37586
|
+
const voiceRequire = createRequire(join43(voiceDir(), "index.js"));
|
|
37305
37587
|
const probeOnnx = () => {
|
|
37306
37588
|
try {
|
|
37307
|
-
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH:
|
|
37589
|
+
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join43(voiceDir(), "node_modules") } });
|
|
37308
37590
|
const output = result.toString().trim();
|
|
37309
37591
|
return output === "OK";
|
|
37310
37592
|
} catch {
|
|
37311
37593
|
return false;
|
|
37312
37594
|
}
|
|
37313
37595
|
};
|
|
37314
|
-
const onnxNodeModules =
|
|
37315
|
-
const onnxInstalled =
|
|
37596
|
+
const onnxNodeModules = join43(voiceDir(), "node_modules", "onnxruntime-node");
|
|
37597
|
+
const onnxInstalled = existsSync35(onnxNodeModules);
|
|
37316
37598
|
if (onnxInstalled && !probeOnnx()) {
|
|
37317
37599
|
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
|
|
37318
37600
|
}
|
|
@@ -37370,18 +37652,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
37370
37652
|
const dir = modelDir(id);
|
|
37371
37653
|
const onnxPath = modelOnnxPath(id);
|
|
37372
37654
|
const configPath = modelConfigPath(id);
|
|
37373
|
-
if (
|
|
37655
|
+
if (existsSync35(onnxPath) && existsSync35(configPath))
|
|
37374
37656
|
return;
|
|
37375
37657
|
mkdirSync13(dir, { recursive: true });
|
|
37376
|
-
if (!
|
|
37658
|
+
if (!existsSync35(configPath)) {
|
|
37377
37659
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
37378
37660
|
const configResp = await fetch(model.configUrl);
|
|
37379
37661
|
if (!configResp.ok)
|
|
37380
37662
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
37381
37663
|
const configText = await configResp.text();
|
|
37382
|
-
|
|
37664
|
+
writeFileSync14(configPath, configText);
|
|
37383
37665
|
}
|
|
37384
|
-
if (!
|
|
37666
|
+
if (!existsSync35(onnxPath)) {
|
|
37385
37667
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
37386
37668
|
const onnxResp = await fetch(model.onnxUrl);
|
|
37387
37669
|
if (!onnxResp.ok)
|
|
@@ -37406,7 +37688,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
37406
37688
|
}
|
|
37407
37689
|
}
|
|
37408
37690
|
const fullBuffer = Buffer.concat(chunks);
|
|
37409
|
-
|
|
37691
|
+
writeFileSync14(onnxPath, fullBuffer);
|
|
37410
37692
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
37411
37693
|
}
|
|
37412
37694
|
}
|
|
@@ -37418,7 +37700,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
37418
37700
|
throw new Error("ONNX runtime not loaded");
|
|
37419
37701
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
37420
37702
|
const configPath = modelConfigPath(this.modelId);
|
|
37421
|
-
if (!
|
|
37703
|
+
if (!existsSync35(onnxPath) || !existsSync35(configPath)) {
|
|
37422
37704
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
37423
37705
|
}
|
|
37424
37706
|
this.config = JSON.parse(readFileSync24(configPath, "utf8"));
|
|
@@ -39654,11 +39936,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
39654
39936
|
const models = await fetchModels(peerUrl, authKey);
|
|
39655
39937
|
if (models.length > 0) {
|
|
39656
39938
|
try {
|
|
39657
|
-
const { writeFileSync:
|
|
39658
|
-
const { join:
|
|
39659
|
-
const cachePath =
|
|
39939
|
+
const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
|
|
39940
|
+
const { join: join57, dirname: dirname20 } = await import("node:path");
|
|
39941
|
+
const cachePath = join57(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
39660
39942
|
mkdirSync21(dirname20(cachePath), { recursive: true });
|
|
39661
|
-
|
|
39943
|
+
writeFileSync20(cachePath, JSON.stringify({
|
|
39662
39944
|
peerId,
|
|
39663
39945
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39664
39946
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -39857,17 +40139,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39857
40139
|
try {
|
|
39858
40140
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
39859
40141
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
39860
|
-
const { dirname: dirname20, join:
|
|
39861
|
-
const { existsSync:
|
|
40142
|
+
const { dirname: dirname20, join: join57 } = await import("node:path");
|
|
40143
|
+
const { existsSync: existsSync45 } = await import("node:fs");
|
|
39862
40144
|
const req = createRequire4(import.meta.url);
|
|
39863
40145
|
const thisDir = dirname20(fileURLToPath14(import.meta.url));
|
|
39864
40146
|
const candidates = [
|
|
39865
|
-
|
|
39866
|
-
|
|
39867
|
-
|
|
40147
|
+
join57(thisDir, "..", "package.json"),
|
|
40148
|
+
join57(thisDir, "..", "..", "package.json"),
|
|
40149
|
+
join57(thisDir, "..", "..", "..", "package.json")
|
|
39868
40150
|
];
|
|
39869
40151
|
for (const pkgPath of candidates) {
|
|
39870
|
-
if (
|
|
40152
|
+
if (existsSync45(pkgPath)) {
|
|
39871
40153
|
const pkg = req(pkgPath);
|
|
39872
40154
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
39873
40155
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -39905,13 +40187,6 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39905
40187
|
}
|
|
39906
40188
|
};
|
|
39907
40189
|
}
|
|
39908
|
-
process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
|
|
39909
|
-
process.stdout.write(`
|
|
39910
|
-
${c2.bold("Open Agents Update")}
|
|
39911
|
-
${c2.dim("\u2500".repeat(40))}
|
|
39912
|
-
|
|
39913
|
-
`);
|
|
39914
|
-
const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
|
|
39915
40190
|
const info = await checkForUpdate(currentVersion, true);
|
|
39916
40191
|
const { exec: exec4, execSync: es2 } = await import("node:child_process");
|
|
39917
40192
|
let needsSudo = false;
|
|
@@ -39925,6 +40200,65 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39925
40200
|
}
|
|
39926
40201
|
} catch {
|
|
39927
40202
|
}
|
|
40203
|
+
const items = [];
|
|
40204
|
+
const skipKeys = [];
|
|
40205
|
+
items.push({ key: "hdr_status", label: selectColors.dim(`\u2500\u2500\u2500 v${currentVersion} \u2500\u2500\u2500`), kind: "header" });
|
|
40206
|
+
skipKeys.push("hdr_status");
|
|
40207
|
+
if (info) {
|
|
40208
|
+
items.push({ key: "info_avail", label: `Update available: v${currentVersion} \u2192 ${c2.bold(c2.green("v" + info.latestVersion))}`, kind: "info" });
|
|
40209
|
+
} else {
|
|
40210
|
+
items.push({ key: "info_avail", label: c2.dim("Primary package is up to date"), kind: "info" });
|
|
40211
|
+
}
|
|
40212
|
+
skipKeys.push("info_avail");
|
|
40213
|
+
items.push({ key: "hdr_options", label: selectColors.dim("\u2500\u2500\u2500 Update Options \u2500\u2500\u2500"), kind: "header" });
|
|
40214
|
+
skipKeys.push("hdr_options");
|
|
40215
|
+
if (info) {
|
|
40216
|
+
items.push({ key: "quick", label: "Quick Update", detail: "Install latest package only (fast)", kind: "action" });
|
|
40217
|
+
}
|
|
40218
|
+
items.push({ key: "full", label: "Full Update", detail: "Package + dependencies + native modules + Python + cloudflared", kind: "action" });
|
|
40219
|
+
items.push({ key: "deps_only", label: "Dependencies Only", detail: "Update subordinate deps (nexus, viem, moondream, etc.)", kind: "action" });
|
|
40220
|
+
items.push({ key: "rebuild", label: "Rebuild Native Modules", detail: "Rebuild better-sqlite3, node-pty, etc.", kind: "action" });
|
|
40221
|
+
items.push({ key: "python", label: "Python Packages Only", detail: "Upgrade venv packages (moondream, tesseract, etc.)", kind: "action" });
|
|
40222
|
+
items.push({ key: "hdr_policy", label: selectColors.dim("\u2500\u2500\u2500 Policy \u2500\u2500\u2500"), kind: "header" });
|
|
40223
|
+
skipKeys.push("hdr_policy");
|
|
40224
|
+
items.push({ key: "policy_auto", label: "Auto-update mode", detail: "Install updates automatically after tasks", kind: "action" });
|
|
40225
|
+
items.push({ key: "policy_manual", label: "Manual-update mode", detail: "Only update when you run /update", kind: "action" });
|
|
40226
|
+
const menuResult = await tuiSelect({
|
|
40227
|
+
items,
|
|
40228
|
+
title: "Update Manager",
|
|
40229
|
+
rl: ctx.rl,
|
|
40230
|
+
skipKeys,
|
|
40231
|
+
availableRows: ctx.availableContentRows?.()
|
|
40232
|
+
});
|
|
40233
|
+
if (!menuResult.confirmed || !menuResult.key) {
|
|
40234
|
+
renderInfo("Update cancelled.");
|
|
40235
|
+
return;
|
|
40236
|
+
}
|
|
40237
|
+
if (menuResult.key === "policy_auto") {
|
|
40238
|
+
const settings = { updateMode: "auto" };
|
|
40239
|
+
saveProjectSettings(repoRoot, settings);
|
|
40240
|
+
saveGlobalSettings(settings);
|
|
40241
|
+
renderInfo("Update mode: auto \u2014 updates install automatically after task completion.");
|
|
40242
|
+
return;
|
|
40243
|
+
}
|
|
40244
|
+
if (menuResult.key === "policy_manual") {
|
|
40245
|
+
const settings = { updateMode: "manual" };
|
|
40246
|
+
saveProjectSettings(repoRoot, settings);
|
|
40247
|
+
saveGlobalSettings(settings);
|
|
40248
|
+
renderInfo("Update mode: manual \u2014 only installs when you run /update.");
|
|
40249
|
+
return;
|
|
40250
|
+
}
|
|
40251
|
+
const doPackage = menuResult.key === "quick" || menuResult.key === "full";
|
|
40252
|
+
const doDeps = menuResult.key === "deps_only" || menuResult.key === "full";
|
|
40253
|
+
const doRebuild = menuResult.key === "rebuild" || menuResult.key === "full";
|
|
40254
|
+
const doPython = menuResult.key === "python" || menuResult.key === "full";
|
|
40255
|
+
const doCloudflared = menuResult.key === "full";
|
|
40256
|
+
process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
|
|
40257
|
+
process.stdout.write(`
|
|
40258
|
+
${c2.bold("Open Agents Update")}
|
|
40259
|
+
${c2.dim("\u2500".repeat(40))}
|
|
40260
|
+
|
|
40261
|
+
`);
|
|
39928
40262
|
let installError = "";
|
|
39929
40263
|
const runInstall2 = (cmd) => new Promise((resolve32) => {
|
|
39930
40264
|
const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
@@ -39937,7 +40271,6 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39937
40271
|
if (needsSudo) {
|
|
39938
40272
|
process.stdout.write("\x1B[?1049l");
|
|
39939
40273
|
renderInfo("Global npm directory requires elevated permissions.");
|
|
39940
|
-
renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
|
|
39941
40274
|
safeWrite("\n");
|
|
39942
40275
|
try {
|
|
39943
40276
|
es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
|
|
@@ -39954,14 +40287,11 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39954
40287
|
}
|
|
39955
40288
|
const sudoPrefix = needsSudo ? "sudo " : "";
|
|
39956
40289
|
let primaryUpdated = false;
|
|
39957
|
-
|
|
39958
|
-
|
|
39959
|
-
} else {
|
|
39960
|
-
checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
|
|
40290
|
+
let depsUpdated = false;
|
|
40291
|
+
if (doPackage && info) {
|
|
39961
40292
|
const installSpinner = startInlineSpinner("Installing update");
|
|
39962
40293
|
const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
|
|
39963
|
-
let installOk =
|
|
39964
|
-
installOk = await runInstall2(installCmd);
|
|
40294
|
+
let installOk = await runInstall2(installCmd);
|
|
39965
40295
|
if (!installOk && /ENOTEMPTY|errno -39/i.test(installError)) {
|
|
39966
40296
|
installSpinner.stop("Cleaning stale npm temp files...");
|
|
39967
40297
|
try {
|
|
@@ -39982,10 +40312,6 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39982
40312
|
}
|
|
39983
40313
|
if (!installOk) {
|
|
39984
40314
|
installSpinner.stop("Update install failed.");
|
|
39985
|
-
const errPreview = installError.split("\n").filter((l) => l.trim()).slice(-3).join("\n ");
|
|
39986
|
-
if (errPreview)
|
|
39987
|
-
renderWarning(`Error:
|
|
39988
|
-
${errPreview}`);
|
|
39989
40315
|
renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
|
|
39990
40316
|
process.stdout.write("\x1B[?1049l");
|
|
39991
40317
|
return;
|
|
@@ -39993,99 +40319,113 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
39993
40319
|
installSpinner.stop(`Update installed (v${info.latestVersion}).`);
|
|
39994
40320
|
primaryUpdated = true;
|
|
39995
40321
|
}
|
|
39996
|
-
|
|
39997
|
-
|
|
39998
|
-
|
|
39999
|
-
|
|
40000
|
-
|
|
40001
|
-
|
|
40002
|
-
|
|
40003
|
-
|
|
40004
|
-
|
|
40005
|
-
|
|
40006
|
-
|
|
40007
|
-
|
|
40008
|
-
|
|
40009
|
-
|
|
40010
|
-
|
|
40011
|
-
|
|
40012
|
-
|
|
40322
|
+
if (doDeps) {
|
|
40323
|
+
const depsSpinner = startInlineSpinner("Updating subordinate dependencies");
|
|
40324
|
+
try {
|
|
40325
|
+
const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
40326
|
+
const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
|
|
40327
|
+
const { existsSync: fe, readFileSync: rf } = await import("node:fs");
|
|
40328
|
+
const { join: pj } = await import("node:path");
|
|
40329
|
+
const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
|
|
40330
|
+
if (fe(pkgPath)) {
|
|
40331
|
+
const pkg = JSON.parse(rf(pkgPath, "utf8"));
|
|
40332
|
+
const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
|
|
40333
|
+
if (Object.keys(allDeps).length > 0) {
|
|
40334
|
+
const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
|
|
40335
|
+
const updateOk = await runInstall2(updateCmd);
|
|
40336
|
+
if (updateOk)
|
|
40337
|
+
depsUpdated = true;
|
|
40338
|
+
}
|
|
40013
40339
|
}
|
|
40340
|
+
} catch {
|
|
40014
40341
|
}
|
|
40015
|
-
|
|
40342
|
+
depsSpinner.stop(depsUpdated ? "Dependencies updated." : "Dependencies checked.");
|
|
40016
40343
|
}
|
|
40017
|
-
|
|
40018
|
-
|
|
40019
|
-
renderInfo("Everything is up to date \u2014 no changes needed.");
|
|
40344
|
+
if (!primaryUpdated && !depsUpdated && !doRebuild && !doPython && !doCloudflared) {
|
|
40345
|
+
renderInfo("No changes needed.");
|
|
40020
40346
|
safeWrite("\n");
|
|
40021
40347
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
40022
40348
|
process.stdout.write("\x1B[?1049l");
|
|
40023
40349
|
return;
|
|
40024
40350
|
}
|
|
40025
|
-
|
|
40026
|
-
|
|
40027
|
-
const
|
|
40028
|
-
|
|
40029
|
-
|
|
40030
|
-
|
|
40031
|
-
|
|
40351
|
+
if (doRebuild) {
|
|
40352
|
+
const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
|
|
40353
|
+
const rebuildOk = await new Promise((resolve32) => {
|
|
40354
|
+
const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
|
|
40355
|
+
child.stdout?.resume();
|
|
40356
|
+
child.stderr?.resume();
|
|
40357
|
+
});
|
|
40358
|
+
rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
|
|
40359
|
+
}
|
|
40032
40360
|
const { existsSync: fsExists } = await import("node:fs");
|
|
40033
40361
|
const { join: pathJoin } = await import("node:path");
|
|
40034
40362
|
const { homedir: getHome } = await import("node:os");
|
|
40035
|
-
|
|
40036
|
-
|
|
40037
|
-
|
|
40038
|
-
|
|
40039
|
-
|
|
40040
|
-
|
|
40041
|
-
|
|
40042
|
-
|
|
40043
|
-
|
|
40363
|
+
if (doPython) {
|
|
40364
|
+
let hasPython = hasCmd("python3") || hasCmd("python");
|
|
40365
|
+
if (!hasPython) {
|
|
40366
|
+
const pyInstallSpinner = startInlineSpinner("Installing Python3");
|
|
40367
|
+
try {
|
|
40368
|
+
ensurePython3();
|
|
40369
|
+
hasPython = hasCmd("python3") || hasCmd("python");
|
|
40370
|
+
pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
|
|
40371
|
+
} catch {
|
|
40372
|
+
pyInstallSpinner.stop("Python3 install failed.");
|
|
40373
|
+
}
|
|
40374
|
+
}
|
|
40375
|
+
if (hasPython && !checkPythonVenv()) {
|
|
40376
|
+
const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
|
|
40377
|
+
try {
|
|
40378
|
+
ensurePythonVenv();
|
|
40379
|
+
venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
|
|
40380
|
+
} catch {
|
|
40381
|
+
venvInstallSpinner.stop("python3-venv install failed.");
|
|
40382
|
+
}
|
|
40383
|
+
}
|
|
40384
|
+
const venvDir = pathJoin(getHome(), ".open-agents", "venv");
|
|
40385
|
+
const venvPip = pathJoin(venvDir, "bin", "pip");
|
|
40386
|
+
if (fsExists(venvPip)) {
|
|
40387
|
+
const pySpinner = startInlineSpinner("Upgrading Python venv packages");
|
|
40388
|
+
const pyOk = await new Promise((resolve32) => {
|
|
40389
|
+
const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
|
|
40390
|
+
child.stdout?.resume();
|
|
40391
|
+
child.stderr?.resume();
|
|
40392
|
+
});
|
|
40393
|
+
pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
|
|
40394
|
+
} else {
|
|
40395
|
+
const pySpinner = startInlineSpinner("Setting up Python venv & deps");
|
|
40396
|
+
await ensureVisionDeps((msg) => {
|
|
40397
|
+
pySpinner.stop(msg);
|
|
40398
|
+
}).catch(() => {
|
|
40399
|
+
});
|
|
40400
|
+
pySpinner.stop("Python deps bootstrapped.");
|
|
40044
40401
|
}
|
|
40045
40402
|
}
|
|
40046
|
-
|
|
40047
|
-
|
|
40403
|
+
let hasCf = false;
|
|
40404
|
+
if (doCloudflared) {
|
|
40405
|
+
const cfSpinner = startInlineSpinner("Checking cloudflared");
|
|
40048
40406
|
try {
|
|
40049
|
-
|
|
40050
|
-
|
|
40407
|
+
const { execSync: es } = await import("node:child_process");
|
|
40408
|
+
es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
|
|
40409
|
+
hasCf = true;
|
|
40051
40410
|
} catch {
|
|
40052
|
-
venvInstallSpinner.stop("python3-venv install failed.");
|
|
40053
40411
|
}
|
|
40412
|
+
if (!hasCf) {
|
|
40413
|
+
cfSpinner.stop("Installing cloudflared...");
|
|
40414
|
+
ensureCloudflaredBackground((msg) => renderInfo(msg));
|
|
40415
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
40416
|
+
} else {
|
|
40417
|
+
cfSpinner.stop("cloudflared ready.");
|
|
40418
|
+
}
|
|
40419
|
+
ensureTranscribeCliBackground();
|
|
40054
40420
|
}
|
|
40055
|
-
|
|
40056
|
-
|
|
40057
|
-
|
|
40058
|
-
|
|
40059
|
-
const pyOk = await new Promise((resolve32) => {
|
|
40060
|
-
const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
|
|
40061
|
-
child.stdout?.resume();
|
|
40062
|
-
child.stderr?.resume();
|
|
40063
|
-
});
|
|
40064
|
-
pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
|
|
40065
|
-
} else {
|
|
40066
|
-
const pySpinner = startInlineSpinner("Setting up Python venv & deps");
|
|
40067
|
-
await ensureVisionDeps((msg) => {
|
|
40068
|
-
pySpinner.stop(msg);
|
|
40069
|
-
}).catch(() => {
|
|
40070
|
-
});
|
|
40071
|
-
pySpinner.stop("Python deps bootstrapped.");
|
|
40072
|
-
}
|
|
40073
|
-
const cfSpinner = startInlineSpinner("Checking cloudflared");
|
|
40074
|
-
let hasCf = false;
|
|
40075
|
-
try {
|
|
40076
|
-
const { execSync: es } = await import("node:child_process");
|
|
40077
|
-
es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
|
|
40078
|
-
hasCf = true;
|
|
40079
|
-
} catch {
|
|
40080
|
-
}
|
|
40081
|
-
if (!hasCf) {
|
|
40082
|
-
cfSpinner.stop("Installing cloudflared...");
|
|
40083
|
-
ensureCloudflaredBackground((msg) => renderInfo(msg));
|
|
40421
|
+
if (!primaryUpdated) {
|
|
40422
|
+
safeWrite(`
|
|
40423
|
+
${c2.green("\u2714")} Done.
|
|
40424
|
+
`);
|
|
40084
40425
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
40085
|
-
|
|
40086
|
-
|
|
40426
|
+
process.stdout.write("\x1B[?1049l");
|
|
40427
|
+
return;
|
|
40087
40428
|
}
|
|
40088
|
-
ensureTranscribeCliBackground();
|
|
40089
40429
|
const reloadSpinner = startInlineSpinner("Loading");
|
|
40090
40430
|
await new Promise((r) => setTimeout(r, 400));
|
|
40091
40431
|
ctx.contextSave?.();
|
|
@@ -40433,8 +40773,8 @@ var init_commands = __esm({
|
|
|
40433
40773
|
});
|
|
40434
40774
|
|
|
40435
40775
|
// packages/cli/dist/tui/project-context.js
|
|
40436
|
-
import { existsSync as
|
|
40437
|
-
import { join as
|
|
40776
|
+
import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
|
|
40777
|
+
import { join as join44, basename as basename10 } from "node:path";
|
|
40438
40778
|
import { execSync as execSync28 } from "node:child_process";
|
|
40439
40779
|
import { homedir as homedir12, platform as platform3, release } from "node:os";
|
|
40440
40780
|
function getModelTier(modelName) {
|
|
@@ -40469,8 +40809,8 @@ function loadProjectMap(repoRoot) {
|
|
|
40469
40809
|
if (!hasOaDirectory(repoRoot)) {
|
|
40470
40810
|
initOaDirectory(repoRoot);
|
|
40471
40811
|
}
|
|
40472
|
-
const mapPath =
|
|
40473
|
-
if (
|
|
40812
|
+
const mapPath = join44(repoRoot, OA_DIR, "context", "project-map.md");
|
|
40813
|
+
if (existsSync36(mapPath)) {
|
|
40474
40814
|
try {
|
|
40475
40815
|
const content = readFileSync25(mapPath, "utf-8");
|
|
40476
40816
|
return content;
|
|
@@ -40513,31 +40853,31 @@ ${log}`);
|
|
|
40513
40853
|
}
|
|
40514
40854
|
function loadMemoryContext(repoRoot) {
|
|
40515
40855
|
const sections = [];
|
|
40516
|
-
const oaMemDir =
|
|
40856
|
+
const oaMemDir = join44(repoRoot, OA_DIR, "memory");
|
|
40517
40857
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
40518
40858
|
if (oaEntries)
|
|
40519
40859
|
sections.push(oaEntries);
|
|
40520
|
-
const legacyMemDir =
|
|
40521
|
-
if (legacyMemDir !== oaMemDir &&
|
|
40860
|
+
const legacyMemDir = join44(repoRoot, ".open-agents", "memory");
|
|
40861
|
+
if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
|
|
40522
40862
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
40523
40863
|
if (legacyEntries)
|
|
40524
40864
|
sections.push(legacyEntries);
|
|
40525
40865
|
}
|
|
40526
|
-
const globalMemDir =
|
|
40866
|
+
const globalMemDir = join44(homedir12(), ".open-agents", "memory");
|
|
40527
40867
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
40528
40868
|
if (globalEntries)
|
|
40529
40869
|
sections.push(globalEntries);
|
|
40530
40870
|
return sections.join("\n\n");
|
|
40531
40871
|
}
|
|
40532
40872
|
function loadMemoryDir(memDir, scope) {
|
|
40533
|
-
if (!
|
|
40873
|
+
if (!existsSync36(memDir))
|
|
40534
40874
|
return "";
|
|
40535
40875
|
const lines = [];
|
|
40536
40876
|
try {
|
|
40537
40877
|
const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
|
|
40538
40878
|
for (const file of files.slice(0, 10)) {
|
|
40539
40879
|
try {
|
|
40540
|
-
const raw = readFileSync25(
|
|
40880
|
+
const raw = readFileSync25(join44(memDir, file), "utf-8");
|
|
40541
40881
|
const entries = JSON.parse(raw);
|
|
40542
40882
|
const topic = basename10(file, ".json");
|
|
40543
40883
|
const keys = Object.keys(entries);
|
|
@@ -41560,12 +41900,12 @@ var init_carousel = __esm({
|
|
|
41560
41900
|
});
|
|
41561
41901
|
|
|
41562
41902
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
41563
|
-
import { existsSync as
|
|
41564
|
-
import { join as
|
|
41903
|
+
import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
|
|
41904
|
+
import { join as join45, basename as basename11 } from "node:path";
|
|
41565
41905
|
function loadToolProfile(repoRoot) {
|
|
41566
|
-
const filePath =
|
|
41906
|
+
const filePath = join45(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
41567
41907
|
try {
|
|
41568
|
-
if (!
|
|
41908
|
+
if (!existsSync37(filePath))
|
|
41569
41909
|
return null;
|
|
41570
41910
|
return JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
41571
41911
|
} catch {
|
|
@@ -41573,9 +41913,9 @@ function loadToolProfile(repoRoot) {
|
|
|
41573
41913
|
}
|
|
41574
41914
|
}
|
|
41575
41915
|
function saveToolProfile(repoRoot, profile) {
|
|
41576
|
-
const contextDir =
|
|
41916
|
+
const contextDir = join45(repoRoot, OA_DIR, "context");
|
|
41577
41917
|
mkdirSync14(contextDir, { recursive: true });
|
|
41578
|
-
|
|
41918
|
+
writeFileSync15(join45(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
41579
41919
|
}
|
|
41580
41920
|
function categorizeToolCall(toolName) {
|
|
41581
41921
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -41633,9 +41973,9 @@ function weightedColor(profile) {
|
|
|
41633
41973
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
41634
41974
|
}
|
|
41635
41975
|
function loadCachedDescriptors(repoRoot) {
|
|
41636
|
-
const filePath =
|
|
41976
|
+
const filePath = join45(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
41637
41977
|
try {
|
|
41638
|
-
if (!
|
|
41978
|
+
if (!existsSync37(filePath))
|
|
41639
41979
|
return null;
|
|
41640
41980
|
const cached = JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
41641
41981
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
@@ -41644,14 +41984,14 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
41644
41984
|
}
|
|
41645
41985
|
}
|
|
41646
41986
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
41647
|
-
const contextDir =
|
|
41987
|
+
const contextDir = join45(repoRoot, OA_DIR, "context");
|
|
41648
41988
|
mkdirSync14(contextDir, { recursive: true });
|
|
41649
41989
|
const cached = {
|
|
41650
41990
|
phrases,
|
|
41651
41991
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
41652
41992
|
sourceHash
|
|
41653
41993
|
};
|
|
41654
|
-
|
|
41994
|
+
writeFileSync15(join45(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
41655
41995
|
}
|
|
41656
41996
|
function generateDescriptors(repoRoot) {
|
|
41657
41997
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -41699,9 +42039,9 @@ function generateDescriptors(repoRoot) {
|
|
|
41699
42039
|
return phrases;
|
|
41700
42040
|
}
|
|
41701
42041
|
function extractFromPackageJson(repoRoot, tags) {
|
|
41702
|
-
const pkgPath =
|
|
42042
|
+
const pkgPath = join45(repoRoot, "package.json");
|
|
41703
42043
|
try {
|
|
41704
|
-
if (!
|
|
42044
|
+
if (!existsSync37(pkgPath))
|
|
41705
42045
|
return;
|
|
41706
42046
|
const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
|
|
41707
42047
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -41747,7 +42087,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
41747
42087
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
41748
42088
|
];
|
|
41749
42089
|
for (const check of manifestChecks) {
|
|
41750
|
-
if (
|
|
42090
|
+
if (existsSync37(join45(repoRoot, check.file))) {
|
|
41751
42091
|
tags.push(check.tag);
|
|
41752
42092
|
}
|
|
41753
42093
|
}
|
|
@@ -41769,16 +42109,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
41769
42109
|
}
|
|
41770
42110
|
}
|
|
41771
42111
|
function extractFromMemory(repoRoot, tags) {
|
|
41772
|
-
const memoryDir =
|
|
42112
|
+
const memoryDir = join45(repoRoot, OA_DIR, "memory");
|
|
41773
42113
|
try {
|
|
41774
|
-
if (!
|
|
42114
|
+
if (!existsSync37(memoryDir))
|
|
41775
42115
|
return;
|
|
41776
42116
|
const files = readdirSync11(memoryDir).filter((f) => f.endsWith(".json"));
|
|
41777
42117
|
for (const file of files) {
|
|
41778
42118
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
41779
42119
|
tags.push(topic);
|
|
41780
42120
|
try {
|
|
41781
|
-
const data = JSON.parse(readFileSync26(
|
|
42121
|
+
const data = JSON.parse(readFileSync26(join45(memoryDir, file), "utf-8"));
|
|
41782
42122
|
if (data && typeof data === "object") {
|
|
41783
42123
|
const keys = Object.keys(data).slice(0, 3);
|
|
41784
42124
|
for (const key of keys) {
|
|
@@ -42401,10 +42741,10 @@ var init_stream_renderer = __esm({
|
|
|
42401
42741
|
|
|
42402
42742
|
// packages/cli/dist/tui/edit-history.js
|
|
42403
42743
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
|
|
42404
|
-
import { join as
|
|
42744
|
+
import { join as join46 } from "node:path";
|
|
42405
42745
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
42406
|
-
const historyDir =
|
|
42407
|
-
const logPath =
|
|
42746
|
+
const historyDir = join46(repoRoot, ".oa", "history");
|
|
42747
|
+
const logPath = join46(historyDir, "edits.jsonl");
|
|
42408
42748
|
try {
|
|
42409
42749
|
mkdirSync15(historyDir, { recursive: true });
|
|
42410
42750
|
} catch {
|
|
@@ -42515,14 +42855,14 @@ var init_edit_history = __esm({
|
|
|
42515
42855
|
});
|
|
42516
42856
|
|
|
42517
42857
|
// packages/cli/dist/tui/promptLoader.js
|
|
42518
|
-
import { readFileSync as readFileSync27, existsSync as
|
|
42519
|
-
import { join as
|
|
42858
|
+
import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
|
|
42859
|
+
import { join as join47, dirname as dirname17 } from "node:path";
|
|
42520
42860
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
42521
42861
|
function loadPrompt3(promptPath, vars) {
|
|
42522
42862
|
let content = cache3.get(promptPath);
|
|
42523
42863
|
if (content === void 0) {
|
|
42524
|
-
const fullPath =
|
|
42525
|
-
if (!
|
|
42864
|
+
const fullPath = join47(PROMPTS_DIR3, promptPath);
|
|
42865
|
+
if (!existsSync38(fullPath)) {
|
|
42526
42866
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
42527
42867
|
}
|
|
42528
42868
|
content = readFileSync27(fullPath, "utf-8");
|
|
@@ -42538,20 +42878,20 @@ var init_promptLoader3 = __esm({
|
|
|
42538
42878
|
"use strict";
|
|
42539
42879
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
42540
42880
|
__dirname6 = dirname17(__filename3);
|
|
42541
|
-
devPath2 =
|
|
42542
|
-
publishedPath2 =
|
|
42543
|
-
PROMPTS_DIR3 =
|
|
42881
|
+
devPath2 = join47(__dirname6, "..", "..", "prompts");
|
|
42882
|
+
publishedPath2 = join47(__dirname6, "..", "prompts");
|
|
42883
|
+
PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
|
|
42544
42884
|
cache3 = /* @__PURE__ */ new Map();
|
|
42545
42885
|
}
|
|
42546
42886
|
});
|
|
42547
42887
|
|
|
42548
42888
|
// packages/cli/dist/tui/dream-engine.js
|
|
42549
|
-
import { mkdirSync as mkdirSync16, writeFileSync as
|
|
42550
|
-
import { join as
|
|
42889
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
|
|
42890
|
+
import { join as join48, basename as basename12 } from "node:path";
|
|
42551
42891
|
import { execSync as execSync29 } from "node:child_process";
|
|
42552
42892
|
function loadAutoresearchMemory(repoRoot) {
|
|
42553
|
-
const memoryPath =
|
|
42554
|
-
if (!
|
|
42893
|
+
const memoryPath = join48(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
42894
|
+
if (!existsSync39(memoryPath))
|
|
42555
42895
|
return "";
|
|
42556
42896
|
try {
|
|
42557
42897
|
const raw = readFileSync28(memoryPath, "utf-8");
|
|
@@ -42744,14 +43084,14 @@ var init_dream_engine = __esm({
|
|
|
42744
43084
|
const content = String(args["content"] ?? "");
|
|
42745
43085
|
if (!rawPath)
|
|
42746
43086
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
42747
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
43087
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
|
|
42748
43088
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
42749
43089
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
42750
43090
|
}
|
|
42751
43091
|
try {
|
|
42752
|
-
const dir =
|
|
43092
|
+
const dir = join48(targetPath, "..");
|
|
42753
43093
|
mkdirSync16(dir, { recursive: true });
|
|
42754
|
-
|
|
43094
|
+
writeFileSync16(targetPath, content, "utf-8");
|
|
42755
43095
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
42756
43096
|
} catch (err) {
|
|
42757
43097
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -42779,12 +43119,12 @@ var init_dream_engine = __esm({
|
|
|
42779
43119
|
const rawPath = String(args["path"] ?? "");
|
|
42780
43120
|
const oldStr = String(args["old_string"] ?? "");
|
|
42781
43121
|
const newStr = String(args["new_string"] ?? "");
|
|
42782
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
43122
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
|
|
42783
43123
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
42784
43124
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
42785
43125
|
}
|
|
42786
43126
|
try {
|
|
42787
|
-
if (!
|
|
43127
|
+
if (!existsSync39(targetPath)) {
|
|
42788
43128
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
42789
43129
|
}
|
|
42790
43130
|
let content = readFileSync28(targetPath, "utf-8");
|
|
@@ -42792,7 +43132,7 @@ var init_dream_engine = __esm({
|
|
|
42792
43132
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
42793
43133
|
}
|
|
42794
43134
|
content = content.replace(oldStr, newStr);
|
|
42795
|
-
|
|
43135
|
+
writeFileSync16(targetPath, content, "utf-8");
|
|
42796
43136
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
42797
43137
|
} catch (err) {
|
|
42798
43138
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -42833,14 +43173,14 @@ var init_dream_engine = __esm({
|
|
|
42833
43173
|
const content = String(args["content"] ?? "");
|
|
42834
43174
|
if (!rawPath)
|
|
42835
43175
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
42836
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
43176
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
|
|
42837
43177
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
42838
43178
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
42839
43179
|
}
|
|
42840
43180
|
try {
|
|
42841
|
-
const dir =
|
|
43181
|
+
const dir = join48(targetPath, "..");
|
|
42842
43182
|
mkdirSync16(dir, { recursive: true });
|
|
42843
|
-
|
|
43183
|
+
writeFileSync16(targetPath, content, "utf-8");
|
|
42844
43184
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
42845
43185
|
} catch (err) {
|
|
42846
43186
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -42868,12 +43208,12 @@ var init_dream_engine = __esm({
|
|
|
42868
43208
|
const rawPath = String(args["path"] ?? "");
|
|
42869
43209
|
const oldStr = String(args["old_string"] ?? "");
|
|
42870
43210
|
const newStr = String(args["new_string"] ?? "");
|
|
42871
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
43211
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
|
|
42872
43212
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
42873
43213
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
42874
43214
|
}
|
|
42875
43215
|
try {
|
|
42876
|
-
if (!
|
|
43216
|
+
if (!existsSync39(targetPath)) {
|
|
42877
43217
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
42878
43218
|
}
|
|
42879
43219
|
let content = readFileSync28(targetPath, "utf-8");
|
|
@@ -42881,7 +43221,7 @@ var init_dream_engine = __esm({
|
|
|
42881
43221
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
42882
43222
|
}
|
|
42883
43223
|
content = content.replace(oldStr, newStr);
|
|
42884
|
-
|
|
43224
|
+
writeFileSync16(targetPath, content, "utf-8");
|
|
42885
43225
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
42886
43226
|
} catch (err) {
|
|
42887
43227
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -42935,7 +43275,7 @@ var init_dream_engine = __esm({
|
|
|
42935
43275
|
constructor(config, repoRoot) {
|
|
42936
43276
|
this.config = config;
|
|
42937
43277
|
this.repoRoot = repoRoot;
|
|
42938
|
-
this.dreamsDir =
|
|
43278
|
+
this.dreamsDir = join48(repoRoot, ".oa", "dreams");
|
|
42939
43279
|
this.state = {
|
|
42940
43280
|
mode: "default",
|
|
42941
43281
|
active: false,
|
|
@@ -43019,8 +43359,8 @@ ${result.summary}`;
|
|
|
43019
43359
|
if (mode !== "default" || cycle === totalCycles) {
|
|
43020
43360
|
renderDreamContraction(cycle);
|
|
43021
43361
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
43022
|
-
const summaryPath =
|
|
43023
|
-
|
|
43362
|
+
const summaryPath = join48(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
43363
|
+
writeFileSync16(summaryPath, cycleSummary, "utf-8");
|
|
43024
43364
|
}
|
|
43025
43365
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
43026
43366
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -43232,7 +43572,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
43232
43572
|
}
|
|
43233
43573
|
/** Build role-specific tool sets for swarm agents */
|
|
43234
43574
|
buildSwarmTools(role, _workspace) {
|
|
43235
|
-
const autoresearchDir =
|
|
43575
|
+
const autoresearchDir = join48(this.repoRoot, ".oa", "autoresearch");
|
|
43236
43576
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
43237
43577
|
switch (role) {
|
|
43238
43578
|
case "researcher": {
|
|
@@ -43596,7 +43936,7 @@ INSTRUCTIONS:
|
|
|
43596
43936
|
2. Summarize the key learnings and next steps
|
|
43597
43937
|
|
|
43598
43938
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
43599
|
-
const reportPath =
|
|
43939
|
+
const reportPath = join48(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
43600
43940
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
43601
43941
|
|
|
43602
43942
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -43619,7 +43959,7 @@ ${summaryResult}
|
|
|
43619
43959
|
`;
|
|
43620
43960
|
try {
|
|
43621
43961
|
mkdirSync16(this.dreamsDir, { recursive: true });
|
|
43622
|
-
|
|
43962
|
+
writeFileSync16(reportPath, report, "utf-8");
|
|
43623
43963
|
} catch {
|
|
43624
43964
|
}
|
|
43625
43965
|
renderSwarmComplete(workspace);
|
|
@@ -43685,7 +44025,7 @@ ${summaryResult}
|
|
|
43685
44025
|
}
|
|
43686
44026
|
/** Save workspace backup for lucid mode */
|
|
43687
44027
|
saveVersionCheckpoint(cycle) {
|
|
43688
|
-
const checkpointDir =
|
|
44028
|
+
const checkpointDir = join48(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
43689
44029
|
try {
|
|
43690
44030
|
mkdirSync16(checkpointDir, { recursive: true });
|
|
43691
44031
|
try {
|
|
@@ -43704,10 +44044,10 @@ ${summaryResult}
|
|
|
43704
44044
|
encoding: "utf-8",
|
|
43705
44045
|
timeout: 5e3
|
|
43706
44046
|
}).trim();
|
|
43707
|
-
|
|
43708
|
-
|
|
43709
|
-
|
|
43710
|
-
|
|
44047
|
+
writeFileSync16(join48(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
44048
|
+
writeFileSync16(join48(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
44049
|
+
writeFileSync16(join48(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
44050
|
+
writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
43711
44051
|
cycle,
|
|
43712
44052
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43713
44053
|
gitHash,
|
|
@@ -43715,7 +44055,7 @@ ${summaryResult}
|
|
|
43715
44055
|
}, null, 2), "utf-8");
|
|
43716
44056
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
43717
44057
|
} catch {
|
|
43718
|
-
|
|
44058
|
+
writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
43719
44059
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
43720
44060
|
}
|
|
43721
44061
|
} catch (err) {
|
|
@@ -43773,14 +44113,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
43773
44113
|
---
|
|
43774
44114
|
*Auto-generated by open-agents dream engine*
|
|
43775
44115
|
`;
|
|
43776
|
-
|
|
44116
|
+
writeFileSync16(join48(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
43777
44117
|
} catch {
|
|
43778
44118
|
}
|
|
43779
44119
|
}
|
|
43780
44120
|
/** Save dream state for resume/inspection */
|
|
43781
44121
|
saveDreamState() {
|
|
43782
44122
|
try {
|
|
43783
|
-
|
|
44123
|
+
writeFileSync16(join48(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
43784
44124
|
} catch {
|
|
43785
44125
|
}
|
|
43786
44126
|
}
|
|
@@ -44154,8 +44494,8 @@ var init_bless_engine = __esm({
|
|
|
44154
44494
|
});
|
|
44155
44495
|
|
|
44156
44496
|
// packages/cli/dist/tui/dmn-engine.js
|
|
44157
|
-
import { existsSync as
|
|
44158
|
-
import { join as
|
|
44497
|
+
import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync8 } from "node:fs";
|
|
44498
|
+
import { join as join49, basename as basename13 } from "node:path";
|
|
44159
44499
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
44160
44500
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
44161
44501
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -44268,8 +44608,8 @@ var init_dmn_engine = __esm({
|
|
|
44268
44608
|
constructor(config, repoRoot) {
|
|
44269
44609
|
this.config = config;
|
|
44270
44610
|
this.repoRoot = repoRoot;
|
|
44271
|
-
this.stateDir =
|
|
44272
|
-
this.historyDir =
|
|
44611
|
+
this.stateDir = join49(repoRoot, ".oa", "dmn");
|
|
44612
|
+
this.historyDir = join49(repoRoot, ".oa", "dmn", "cycles");
|
|
44273
44613
|
mkdirSync17(this.historyDir, { recursive: true });
|
|
44274
44614
|
this.loadState();
|
|
44275
44615
|
}
|
|
@@ -44859,11 +45199,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
44859
45199
|
async gatherMemoryTopics() {
|
|
44860
45200
|
const topics = [];
|
|
44861
45201
|
const dirs = [
|
|
44862
|
-
|
|
44863
|
-
|
|
45202
|
+
join49(this.repoRoot, ".oa", "memory"),
|
|
45203
|
+
join49(this.repoRoot, ".open-agents", "memory")
|
|
44864
45204
|
];
|
|
44865
45205
|
for (const dir of dirs) {
|
|
44866
|
-
if (!
|
|
45206
|
+
if (!existsSync40(dir))
|
|
44867
45207
|
continue;
|
|
44868
45208
|
try {
|
|
44869
45209
|
const files = readdirSync13(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -44879,8 +45219,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
44879
45219
|
}
|
|
44880
45220
|
// ── State persistence ─────────────────────────────────────────────────
|
|
44881
45221
|
loadState() {
|
|
44882
|
-
const path =
|
|
44883
|
-
if (
|
|
45222
|
+
const path = join49(this.stateDir, "state.json");
|
|
45223
|
+
if (existsSync40(path)) {
|
|
44884
45224
|
try {
|
|
44885
45225
|
this.state = JSON.parse(readFileSync29(path, "utf-8"));
|
|
44886
45226
|
} catch {
|
|
@@ -44889,19 +45229,19 @@ OUTPUT: Call task_complete with JSON:
|
|
|
44889
45229
|
}
|
|
44890
45230
|
saveState() {
|
|
44891
45231
|
try {
|
|
44892
|
-
|
|
45232
|
+
writeFileSync17(join49(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
44893
45233
|
} catch {
|
|
44894
45234
|
}
|
|
44895
45235
|
}
|
|
44896
45236
|
saveCycleResult(result) {
|
|
44897
45237
|
try {
|
|
44898
45238
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
44899
|
-
|
|
45239
|
+
writeFileSync17(join49(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
44900
45240
|
const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
44901
45241
|
if (files.length > 50) {
|
|
44902
45242
|
for (const old of files.slice(0, files.length - 50)) {
|
|
44903
45243
|
try {
|
|
44904
|
-
|
|
45244
|
+
unlinkSync8(join49(this.historyDir, old));
|
|
44905
45245
|
} catch {
|
|
44906
45246
|
}
|
|
44907
45247
|
}
|
|
@@ -44914,8 +45254,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
44914
45254
|
});
|
|
44915
45255
|
|
|
44916
45256
|
// packages/cli/dist/tui/snr-engine.js
|
|
44917
|
-
import { existsSync as
|
|
44918
|
-
import { join as
|
|
45257
|
+
import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
|
|
45258
|
+
import { join as join50, basename as basename14 } from "node:path";
|
|
44919
45259
|
function computeDPrime(signalScores, noiseScores) {
|
|
44920
45260
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
44921
45261
|
return 0;
|
|
@@ -45155,11 +45495,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
45155
45495
|
loadMemoryEntries(topics) {
|
|
45156
45496
|
const entries = [];
|
|
45157
45497
|
const dirs = [
|
|
45158
|
-
|
|
45159
|
-
|
|
45498
|
+
join50(this.repoRoot, ".oa", "memory"),
|
|
45499
|
+
join50(this.repoRoot, ".open-agents", "memory")
|
|
45160
45500
|
];
|
|
45161
45501
|
for (const dir of dirs) {
|
|
45162
|
-
if (!
|
|
45502
|
+
if (!existsSync41(dir))
|
|
45163
45503
|
continue;
|
|
45164
45504
|
try {
|
|
45165
45505
|
const files = readdirSync14(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -45168,7 +45508,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
45168
45508
|
if (topics.length > 0 && !topics.includes(topic))
|
|
45169
45509
|
continue;
|
|
45170
45510
|
try {
|
|
45171
|
-
const data = JSON.parse(readFileSync30(
|
|
45511
|
+
const data = JSON.parse(readFileSync30(join50(dir, f), "utf-8"));
|
|
45172
45512
|
for (const [key, val] of Object.entries(data)) {
|
|
45173
45513
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
45174
45514
|
entries.push({ topic, key, value });
|
|
@@ -45735,8 +46075,8 @@ var init_tool_policy = __esm({
|
|
|
45735
46075
|
});
|
|
45736
46076
|
|
|
45737
46077
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
45738
|
-
import { mkdirSync as mkdirSync18, existsSync as
|
|
45739
|
-
import { join as
|
|
46078
|
+
import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync9, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
|
|
46079
|
+
import { join as join51, resolve as resolve28 } from "node:path";
|
|
45740
46080
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
45741
46081
|
function convertMarkdownToTelegramHTML(md) {
|
|
45742
46082
|
let html = md;
|
|
@@ -46501,7 +46841,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
46501
46841
|
return null;
|
|
46502
46842
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
46503
46843
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
46504
|
-
const localPath =
|
|
46844
|
+
const localPath = join51(this.mediaCacheDir, fileName);
|
|
46505
46845
|
await writeFileAsync(localPath, buffer);
|
|
46506
46846
|
return localPath;
|
|
46507
46847
|
} catch {
|
|
@@ -46589,7 +46929,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
46589
46929
|
for (const [key, entry] of this.mediaCache) {
|
|
46590
46930
|
if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
|
|
46591
46931
|
try {
|
|
46592
|
-
|
|
46932
|
+
unlinkSync9(entry.localPath);
|
|
46593
46933
|
} catch {
|
|
46594
46934
|
}
|
|
46595
46935
|
this.mediaCache.delete(key);
|
|
@@ -46665,11 +47005,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
46665
47005
|
let mimeType = "audio/wav";
|
|
46666
47006
|
try {
|
|
46667
47007
|
const { execSync: execSyncLocal } = await import("node:child_process");
|
|
46668
|
-
const { tmpdir:
|
|
47008
|
+
const { tmpdir: tmpdir10 } = await import("node:os");
|
|
46669
47009
|
const { join: joinPath } = await import("node:path");
|
|
46670
47010
|
const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
|
|
46671
|
-
const tmpWav = joinPath(
|
|
46672
|
-
const tmpOgg = joinPath(
|
|
47011
|
+
const tmpWav = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.wav`);
|
|
47012
|
+
const tmpOgg = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.ogg`);
|
|
46673
47013
|
writeFs(tmpWav, wavBuffer);
|
|
46674
47014
|
execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
|
|
46675
47015
|
timeout: 15e3,
|
|
@@ -48940,11 +49280,11 @@ var init_status_bar = __esm({
|
|
|
48940
49280
|
import * as readline2 from "node:readline";
|
|
48941
49281
|
import { Writable } from "node:stream";
|
|
48942
49282
|
import { cwd } from "node:process";
|
|
48943
|
-
import { resolve as resolve29, join as
|
|
49283
|
+
import { resolve as resolve29, join as join52, dirname as dirname18, extname as extname10 } from "node:path";
|
|
48944
49284
|
import { createRequire as createRequire2 } from "node:module";
|
|
48945
49285
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
48946
|
-
import { readFileSync as readFileSync31, writeFileSync as
|
|
48947
|
-
import { existsSync as
|
|
49286
|
+
import { readFileSync as readFileSync31, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
|
|
49287
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
48948
49288
|
import { homedir as homedir13 } from "node:os";
|
|
48949
49289
|
function formatTimeAgo(date) {
|
|
48950
49290
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -48964,12 +49304,12 @@ function getVersion3() {
|
|
|
48964
49304
|
const require2 = createRequire2(import.meta.url);
|
|
48965
49305
|
const thisDir = dirname18(fileURLToPath12(import.meta.url));
|
|
48966
49306
|
const candidates = [
|
|
48967
|
-
|
|
48968
|
-
|
|
48969
|
-
|
|
49307
|
+
join52(thisDir, "..", "package.json"),
|
|
49308
|
+
join52(thisDir, "..", "..", "package.json"),
|
|
49309
|
+
join52(thisDir, "..", "..", "..", "package.json")
|
|
48970
49310
|
];
|
|
48971
49311
|
for (const pkgPath of candidates) {
|
|
48972
|
-
if (
|
|
49312
|
+
if (existsSync43(pkgPath)) {
|
|
48973
49313
|
const pkg = require2(pkgPath);
|
|
48974
49314
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
48975
49315
|
return pkg.version ?? "0.0.0";
|
|
@@ -49176,15 +49516,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
49176
49516
|
function gatherMemorySnippets(root) {
|
|
49177
49517
|
const snippets = [];
|
|
49178
49518
|
const dirs = [
|
|
49179
|
-
|
|
49180
|
-
|
|
49519
|
+
join52(root, ".oa", "memory"),
|
|
49520
|
+
join52(root, ".open-agents", "memory")
|
|
49181
49521
|
];
|
|
49182
49522
|
for (const dir of dirs) {
|
|
49183
|
-
if (!
|
|
49523
|
+
if (!existsSync43(dir))
|
|
49184
49524
|
continue;
|
|
49185
49525
|
try {
|
|
49186
49526
|
for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
49187
|
-
const data = JSON.parse(readFileSync31(
|
|
49527
|
+
const data = JSON.parse(readFileSync31(join52(dir, f), "utf-8"));
|
|
49188
49528
|
for (const val of Object.values(data)) {
|
|
49189
49529
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
49190
49530
|
if (v.length > 10)
|
|
@@ -50148,7 +50488,7 @@ async function startInteractive(config, repoPath) {
|
|
|
50148
50488
|
let p2pGateway = null;
|
|
50149
50489
|
let peerMesh = null;
|
|
50150
50490
|
let inferenceRouter = null;
|
|
50151
|
-
const secretVault = new SecretVault(
|
|
50491
|
+
const secretVault = new SecretVault(join52(repoRoot, ".oa", "vault.enc"));
|
|
50152
50492
|
let adminSessionKey = null;
|
|
50153
50493
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
50154
50494
|
const streamRenderer = new StreamRenderer();
|
|
@@ -50357,12 +50697,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
50357
50697
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
50358
50698
|
return [hits, line];
|
|
50359
50699
|
}
|
|
50360
|
-
const HISTORY_DIR =
|
|
50361
|
-
const HISTORY_FILE =
|
|
50700
|
+
const HISTORY_DIR = join52(homedir13(), ".open-agents");
|
|
50701
|
+
const HISTORY_FILE = join52(HISTORY_DIR, "repl-history");
|
|
50362
50702
|
const MAX_HISTORY_LINES = 500;
|
|
50363
50703
|
let savedHistory = [];
|
|
50364
50704
|
try {
|
|
50365
|
-
if (
|
|
50705
|
+
if (existsSync43(HISTORY_FILE)) {
|
|
50366
50706
|
const raw = readFileSync31(HISTORY_FILE, "utf8").trim();
|
|
50367
50707
|
if (raw)
|
|
50368
50708
|
savedHistory = raw.split("\n").reverse();
|
|
@@ -50387,7 +50727,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
50387
50727
|
if (Math.random() < 0.02) {
|
|
50388
50728
|
const all = readFileSync31(HISTORY_FILE, "utf8").trim().split("\n");
|
|
50389
50729
|
if (all.length > MAX_HISTORY_LINES) {
|
|
50390
|
-
|
|
50730
|
+
writeFileSync18(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
50391
50731
|
}
|
|
50392
50732
|
}
|
|
50393
50733
|
} catch {
|
|
@@ -50568,7 +50908,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
50568
50908
|
} catch {
|
|
50569
50909
|
}
|
|
50570
50910
|
try {
|
|
50571
|
-
const oaDir =
|
|
50911
|
+
const oaDir = join52(repoRoot, ".oa");
|
|
50572
50912
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
50573
50913
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
50574
50914
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -50591,7 +50931,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
50591
50931
|
} catch {
|
|
50592
50932
|
}
|
|
50593
50933
|
try {
|
|
50594
|
-
const oaDir =
|
|
50934
|
+
const oaDir = join52(repoRoot, ".oa");
|
|
50595
50935
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
50596
50936
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
50597
50937
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -51410,7 +51750,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
51410
51750
|
kind,
|
|
51411
51751
|
targetUrl,
|
|
51412
51752
|
authKey,
|
|
51413
|
-
stateDir:
|
|
51753
|
+
stateDir: join52(repoRoot, ".oa"),
|
|
51414
51754
|
passthrough: passthrough ?? false,
|
|
51415
51755
|
loadbalance: loadbalance ?? false,
|
|
51416
51756
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -51458,7 +51798,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
51458
51798
|
await tunnelGateway.stop();
|
|
51459
51799
|
tunnelGateway = null;
|
|
51460
51800
|
}
|
|
51461
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
51801
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join52(repoRoot, ".oa") });
|
|
51462
51802
|
newTunnel.on("stats", (stats) => {
|
|
51463
51803
|
statusBar.setExposeStatus({
|
|
51464
51804
|
status: stats.status,
|
|
@@ -51720,8 +52060,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
51720
52060
|
}
|
|
51721
52061
|
},
|
|
51722
52062
|
destroyProject() {
|
|
51723
|
-
const oaPath =
|
|
51724
|
-
if (
|
|
52063
|
+
const oaPath = join52(repoRoot, OA_DIR);
|
|
52064
|
+
if (existsSync43(oaPath)) {
|
|
51725
52065
|
try {
|
|
51726
52066
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
51727
52067
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -52066,8 +52406,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
52066
52406
|
}
|
|
52067
52407
|
}
|
|
52068
52408
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
52069
|
-
const isImage = isImagePath(cleanPath) &&
|
|
52070
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
52409
|
+
const isImage = isImagePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
|
|
52410
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
|
|
52071
52411
|
if (activeTask) {
|
|
52072
52412
|
if (activeTask.runner.isPaused) {
|
|
52073
52413
|
activeTask.runner.resume();
|
|
@@ -52655,7 +52995,7 @@ import { glob } from "glob";
|
|
|
52655
52995
|
import ignore from "ignore";
|
|
52656
52996
|
import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
|
|
52657
52997
|
import { createHash as createHash4 } from "node:crypto";
|
|
52658
|
-
import { join as
|
|
52998
|
+
import { join as join53, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
|
|
52659
52999
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
52660
53000
|
var init_codebase_indexer = __esm({
|
|
52661
53001
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -52699,7 +53039,7 @@ var init_codebase_indexer = __esm({
|
|
|
52699
53039
|
const ig = ignore.default();
|
|
52700
53040
|
if (this.config.respectGitignore) {
|
|
52701
53041
|
try {
|
|
52702
|
-
const gitignoreContent = await readFile17(
|
|
53042
|
+
const gitignoreContent = await readFile17(join53(this.config.rootDir, ".gitignore"), "utf-8");
|
|
52703
53043
|
ig.add(gitignoreContent);
|
|
52704
53044
|
} catch {
|
|
52705
53045
|
}
|
|
@@ -52714,7 +53054,7 @@ var init_codebase_indexer = __esm({
|
|
|
52714
53054
|
for (const relativePath of files) {
|
|
52715
53055
|
if (ig.ignores(relativePath))
|
|
52716
53056
|
continue;
|
|
52717
|
-
const fullPath =
|
|
53057
|
+
const fullPath = join53(this.config.rootDir, relativePath);
|
|
52718
53058
|
try {
|
|
52719
53059
|
const fileStat = await stat4(fullPath);
|
|
52720
53060
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -52760,7 +53100,7 @@ var init_codebase_indexer = __esm({
|
|
|
52760
53100
|
if (!child) {
|
|
52761
53101
|
child = {
|
|
52762
53102
|
name: part,
|
|
52763
|
-
path:
|
|
53103
|
+
path: join53(current.path, part),
|
|
52764
53104
|
type: "directory",
|
|
52765
53105
|
children: []
|
|
52766
53106
|
};
|
|
@@ -52843,17 +53183,17 @@ __export(index_repo_exports, {
|
|
|
52843
53183
|
indexRepoCommand: () => indexRepoCommand
|
|
52844
53184
|
});
|
|
52845
53185
|
import { resolve as resolve30 } from "node:path";
|
|
52846
|
-
import { existsSync as
|
|
53186
|
+
import { existsSync as existsSync44, statSync as statSync14 } from "node:fs";
|
|
52847
53187
|
import { cwd as cwd2 } from "node:process";
|
|
52848
53188
|
async function indexRepoCommand(opts, _config) {
|
|
52849
53189
|
const repoRoot = resolve30(opts.repoPath ?? cwd2());
|
|
52850
53190
|
printHeader("Index Repository");
|
|
52851
53191
|
printInfo(`Indexing: ${repoRoot}`);
|
|
52852
|
-
if (!
|
|
53192
|
+
if (!existsSync44(repoRoot)) {
|
|
52853
53193
|
printError(`Path does not exist: ${repoRoot}`);
|
|
52854
53194
|
process.exit(1);
|
|
52855
53195
|
}
|
|
52856
|
-
const stat5 =
|
|
53196
|
+
const stat5 = statSync14(repoRoot);
|
|
52857
53197
|
if (!stat5.isDirectory()) {
|
|
52858
53198
|
printError(`Path is not a directory: ${repoRoot}`);
|
|
52859
53199
|
process.exit(1);
|
|
@@ -53101,7 +53441,7 @@ var config_exports = {};
|
|
|
53101
53441
|
__export(config_exports, {
|
|
53102
53442
|
configCommand: () => configCommand
|
|
53103
53443
|
});
|
|
53104
|
-
import { join as
|
|
53444
|
+
import { join as join54, resolve as resolve31 } from "node:path";
|
|
53105
53445
|
import { homedir as homedir14 } from "node:os";
|
|
53106
53446
|
import { cwd as cwd3 } from "node:process";
|
|
53107
53447
|
function redactIfSensitive(key, value) {
|
|
@@ -53184,7 +53524,7 @@ function handleShow(opts, config) {
|
|
|
53184
53524
|
}
|
|
53185
53525
|
}
|
|
53186
53526
|
printSection("Config File");
|
|
53187
|
-
printInfo(`~/.open-agents/config.json (${
|
|
53527
|
+
printInfo(`~/.open-agents/config.json (${join54(homedir14(), ".open-agents", "config.json")})`);
|
|
53188
53528
|
printSection("Priority Chain");
|
|
53189
53529
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
53190
53530
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -53223,7 +53563,7 @@ function handleSet(opts, _config) {
|
|
|
53223
53563
|
const coerced = coerceForSettings(key, value);
|
|
53224
53564
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
53225
53565
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
53226
|
-
printInfo(`Saved to ${
|
|
53566
|
+
printInfo(`Saved to ${join54(repoRoot, ".oa", "settings.json")}`);
|
|
53227
53567
|
printInfo("This override applies only when running in this workspace.");
|
|
53228
53568
|
} catch (err) {
|
|
53229
53569
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -53480,9 +53820,9 @@ var eval_exports = {};
|
|
|
53480
53820
|
__export(eval_exports, {
|
|
53481
53821
|
evalCommand: () => evalCommand
|
|
53482
53822
|
});
|
|
53483
|
-
import { tmpdir as
|
|
53484
|
-
import { mkdirSync as mkdirSync20, writeFileSync as
|
|
53485
|
-
import { join as
|
|
53823
|
+
import { tmpdir as tmpdir9 } from "node:os";
|
|
53824
|
+
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
|
|
53825
|
+
import { join as join55 } from "node:path";
|
|
53486
53826
|
async function evalCommand(opts, config) {
|
|
53487
53827
|
const suiteName = opts.suite ?? "basic";
|
|
53488
53828
|
const suite = SUITES[suiteName];
|
|
@@ -53607,9 +53947,9 @@ async function evalCommand(opts, config) {
|
|
|
53607
53947
|
process.exit(failed > 0 ? 1 : 0);
|
|
53608
53948
|
}
|
|
53609
53949
|
function createTempEvalRepo() {
|
|
53610
|
-
const dir =
|
|
53950
|
+
const dir = join55(tmpdir9(), `open-agents-eval-${Date.now()}`);
|
|
53611
53951
|
mkdirSync20(dir, { recursive: true });
|
|
53612
|
-
|
|
53952
|
+
writeFileSync19(join55(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
53613
53953
|
return dir;
|
|
53614
53954
|
}
|
|
53615
53955
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -53669,7 +54009,7 @@ init_updater();
|
|
|
53669
54009
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
53670
54010
|
import { createRequire as createRequire3 } from "node:module";
|
|
53671
54011
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
53672
|
-
import { dirname as dirname19, join as
|
|
54012
|
+
import { dirname as dirname19, join as join56 } from "node:path";
|
|
53673
54013
|
|
|
53674
54014
|
// packages/cli/dist/cli.js
|
|
53675
54015
|
import { createInterface } from "node:readline";
|
|
@@ -53776,7 +54116,7 @@ init_output();
|
|
|
53776
54116
|
function getVersion4() {
|
|
53777
54117
|
try {
|
|
53778
54118
|
const require2 = createRequire3(import.meta.url);
|
|
53779
|
-
const pkgPath =
|
|
54119
|
+
const pkgPath = join56(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
53780
54120
|
const pkg = require2(pkgPath);
|
|
53781
54121
|
return pkg.version;
|
|
53782
54122
|
} catch {
|