open-agents-ai 0.53.0 → 0.55.0
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 +77 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17692,6 +17692,7 @@ var init_render = __esm({
|
|
|
17692
17692
|
// packages/cli/dist/tui/voice-session.js
|
|
17693
17693
|
import { createServer } from "node:http";
|
|
17694
17694
|
import { spawn as spawn10, execSync as execSync19 } from "node:child_process";
|
|
17695
|
+
import { createHash } from "node:crypto";
|
|
17695
17696
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
17696
17697
|
function parseWebSocketFrame(buf) {
|
|
17697
17698
|
if (buf.length < 2)
|
|
@@ -17846,20 +17847,31 @@ let scriptProcessor = null;
|
|
|
17846
17847
|
let micActive = false;
|
|
17847
17848
|
let playbackQueue = [];
|
|
17848
17849
|
let isPlaying = false;
|
|
17850
|
+
let reconnectDelay = 1000;
|
|
17851
|
+
let reconnectTimer = null;
|
|
17849
17852
|
|
|
17850
17853
|
// Connect WebSocket
|
|
17851
17854
|
function connect() {
|
|
17855
|
+
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
|
17852
17856
|
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
17853
17857
|
ws = new WebSocket(proto + '//' + location.host + '/ws');
|
|
17854
17858
|
ws.binaryType = 'arraybuffer';
|
|
17855
17859
|
|
|
17856
17860
|
ws.onopen = () => {
|
|
17857
17861
|
statusEl.innerHTML = '<span class="connected">Connected</span>';
|
|
17862
|
+
reconnectDelay = 1000; // Reset backoff on successful connection
|
|
17863
|
+
};
|
|
17864
|
+
|
|
17865
|
+
ws.onerror = () => {
|
|
17866
|
+
// Error fires before close \u2014 just update status, close handler does reconnect
|
|
17867
|
+
statusEl.innerHTML = '<span class="disconnected">Connection error</span>';
|
|
17858
17868
|
};
|
|
17859
17869
|
|
|
17860
17870
|
ws.onclose = () => {
|
|
17861
17871
|
statusEl.innerHTML = '<span class="disconnected">Disconnected \u2014 reconnecting...</span>';
|
|
17862
|
-
|
|
17872
|
+
// Exponential backoff: 1s, 2s, 4s, max 10s
|
|
17873
|
+
reconnectTimer = setTimeout(connect, reconnectDelay);
|
|
17874
|
+
reconnectDelay = Math.min(reconnectDelay * 2, 10000);
|
|
17863
17875
|
};
|
|
17864
17876
|
|
|
17865
17877
|
ws.onmessage = (evt) => {
|
|
@@ -18184,9 +18196,10 @@ var init_voice_session = __esm({
|
|
|
18184
18196
|
socket.destroy();
|
|
18185
18197
|
return;
|
|
18186
18198
|
}
|
|
18187
|
-
const crypto2 = __require("node:crypto");
|
|
18188
18199
|
const magic = "258EAFA5-E914-47DA-95CA-5AB9DC085B62";
|
|
18189
|
-
const accept =
|
|
18200
|
+
const accept = createHash("sha1").update(key + magic).digest("base64");
|
|
18201
|
+
socket.setNoDelay(true);
|
|
18202
|
+
socket.setKeepAlive(true, 3e4);
|
|
18190
18203
|
socket.write(`HTTP/1.1 101 Switching Protocols\r
|
|
18191
18204
|
Upgrade: websocket\r
|
|
18192
18205
|
Connection: Upgrade\r
|
|
@@ -18197,6 +18210,21 @@ Sec-WebSocket-Accept: ${accept}\r
|
|
|
18197
18210
|
this.wsClients.set(clientId, socket);
|
|
18198
18211
|
this.state.connectedUsers.set(clientId, { username: "web-user", connectedAt: Date.now() });
|
|
18199
18212
|
this.emit("userConnected", clientId, "web-user");
|
|
18213
|
+
try {
|
|
18214
|
+
socket.write(createWebSocketFrame(9, Buffer.from("keepalive")));
|
|
18215
|
+
} catch {
|
|
18216
|
+
}
|
|
18217
|
+
const pingInterval = setInterval(() => {
|
|
18218
|
+
if (socket.destroyed) {
|
|
18219
|
+
clearInterval(pingInterval);
|
|
18220
|
+
return;
|
|
18221
|
+
}
|
|
18222
|
+
try {
|
|
18223
|
+
socket.write(createWebSocketFrame(9, Buffer.from("keepalive")));
|
|
18224
|
+
} catch {
|
|
18225
|
+
clearInterval(pingInterval);
|
|
18226
|
+
}
|
|
18227
|
+
}, 25e3);
|
|
18200
18228
|
let frameBuffer = Buffer.alloc(0);
|
|
18201
18229
|
socket.on("data", (data) => {
|
|
18202
18230
|
frameBuffer = Buffer.concat([frameBuffer, data]);
|
|
@@ -18218,10 +18246,15 @@ Sec-WebSocket-Accept: ${accept}\r
|
|
|
18218
18246
|
const consumed = headerLen + (masked ? 4 : 0) + payloadLen;
|
|
18219
18247
|
frameBuffer = frameBuffer.subarray(consumed);
|
|
18220
18248
|
if (frame.opcode === 8) {
|
|
18249
|
+
try {
|
|
18250
|
+
socket.write(createWebSocketFrame(8, Buffer.alloc(0)));
|
|
18251
|
+
} catch {
|
|
18252
|
+
}
|
|
18221
18253
|
socket.end();
|
|
18222
18254
|
return;
|
|
18223
18255
|
} else if (frame.opcode === 9) {
|
|
18224
18256
|
socket.write(createWebSocketFrame(10, frame.payload));
|
|
18257
|
+
} else if (frame.opcode === 10) {
|
|
18225
18258
|
} else if (frame.opcode === 1) {
|
|
18226
18259
|
try {
|
|
18227
18260
|
const msg = JSON.parse(frame.payload.toString());
|
|
@@ -18229,7 +18262,6 @@ Sec-WebSocket-Accept: ${accept}\r
|
|
|
18229
18262
|
const entry = this.state.connectedUsers.get(clientId);
|
|
18230
18263
|
if (entry)
|
|
18231
18264
|
entry.username = msg.username;
|
|
18232
|
-
this.emit("userConnected", clientId, msg.username);
|
|
18233
18265
|
}
|
|
18234
18266
|
} catch {
|
|
18235
18267
|
}
|
|
@@ -18241,12 +18273,13 @@ Sec-WebSocket-Accept: ${accept}\r
|
|
|
18241
18273
|
}
|
|
18242
18274
|
});
|
|
18243
18275
|
socket.on("close", () => {
|
|
18276
|
+
clearInterval(pingInterval);
|
|
18244
18277
|
this.wsClients.delete(clientId);
|
|
18245
|
-
const user = this.state.connectedUsers.get(clientId);
|
|
18246
18278
|
this.state.connectedUsers.delete(clientId);
|
|
18247
18279
|
this.emit("userDisconnected", clientId);
|
|
18248
18280
|
});
|
|
18249
18281
|
socket.on("error", () => {
|
|
18282
|
+
clearInterval(pingInterval);
|
|
18250
18283
|
this.wsClients.delete(clientId);
|
|
18251
18284
|
this.state.connectedUsers.delete(clientId);
|
|
18252
18285
|
});
|
|
@@ -27257,6 +27290,10 @@ function convertMarkdownToTelegramHTML(md) {
|
|
|
27257
27290
|
return html;
|
|
27258
27291
|
}
|
|
27259
27292
|
function formatIntermediateState(event) {
|
|
27293
|
+
if (event.type === "tool_call" && event.toolName === "task_complete")
|
|
27294
|
+
return null;
|
|
27295
|
+
if (event.type === "tool_result" && event.toolName === "task_complete")
|
|
27296
|
+
return null;
|
|
27260
27297
|
if (event.type === "tool_call") {
|
|
27261
27298
|
const argsPreview = event.toolArgs ? JSON.stringify(event.toolArgs).slice(0, 60) : "";
|
|
27262
27299
|
return `\u{1F527} <code>${event.toolName || "tool"}</code>(${argsPreview.length > 57 ? argsPreview.slice(0, 57) + "..." : argsPreview})`;
|
|
@@ -27456,6 +27493,8 @@ with summary "no_reply" to silently skip without responding.
|
|
|
27456
27493
|
commandHandler = null;
|
|
27457
27494
|
/** Callback to get active call session URL (wired from interactive.ts) */
|
|
27458
27495
|
callUrlGetter = null;
|
|
27496
|
+
/** Callback to start a call session and return the URL (wired from interactive.ts) */
|
|
27497
|
+
callStarter = null;
|
|
27459
27498
|
/** Callback to write content into the scrollable TUI waterfall area (wired from interactive.ts) */
|
|
27460
27499
|
writeContent = null;
|
|
27461
27500
|
/** Media cache — fileUniqueId → cache entry */
|
|
@@ -27495,6 +27534,10 @@ with summary "no_reply" to silently skip without responding.
|
|
|
27495
27534
|
setCallUrlGetter(getter) {
|
|
27496
27535
|
this.callUrlGetter = getter;
|
|
27497
27536
|
}
|
|
27537
|
+
/** Register callback to start a call session (returns URL or null) */
|
|
27538
|
+
setCallStarter(starter) {
|
|
27539
|
+
this.callStarter = starter;
|
|
27540
|
+
}
|
|
27498
27541
|
/** Register callback to write content into the scrollable TUI area (status bar guard) */
|
|
27499
27542
|
setWriteContent(fn) {
|
|
27500
27543
|
this.writeContent = fn;
|
|
@@ -27665,6 +27708,20 @@ with summary "no_reply" to silently skip without responding.
|
|
|
27665
27708
|
await this.sendMessage(msg.chatId, "No active call session. Ask the admin to start one with /call.");
|
|
27666
27709
|
return;
|
|
27667
27710
|
}
|
|
27711
|
+
if (this.callStarter) {
|
|
27712
|
+
try {
|
|
27713
|
+
const newUrl = await this.callStarter();
|
|
27714
|
+
if (newUrl) {
|
|
27715
|
+
await this.sendCallButton(msg.chatId, newUrl);
|
|
27716
|
+
} else {
|
|
27717
|
+
await this.sendMessage(msg.chatId, "Failed to start call session.");
|
|
27718
|
+
}
|
|
27719
|
+
} catch (err) {
|
|
27720
|
+
await this.sendMessage(msg.chatId, `Call error: ${err instanceof Error ? err.message : String(err)}`).catch(() => {
|
|
27721
|
+
});
|
|
27722
|
+
}
|
|
27723
|
+
return;
|
|
27724
|
+
}
|
|
27668
27725
|
}
|
|
27669
27726
|
if (isAdminDM && msg.text.startsWith("/") && this.commandHandler) {
|
|
27670
27727
|
const cmdName = msg.text.split(/\s+/)[0].slice(1).toLowerCase();
|
|
@@ -30796,20 +30853,21 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
30796
30853
|
telegramBridge.voiceEnabled = true;
|
|
30797
30854
|
}
|
|
30798
30855
|
telegramBridge.setCallUrlGetter(() => voiceSession?.tunnelUrl ?? null);
|
|
30856
|
+
telegramBridge.setCallStarter(async () => commandCtx.callStart());
|
|
30799
30857
|
telegramBridge.setCommandHandler(async (input) => {
|
|
30800
30858
|
const captured = [];
|
|
30801
30859
|
const origWrite = process.stdout.write;
|
|
30802
|
-
process.stdout.write = function(chunk, ...
|
|
30860
|
+
process.stdout.write = function(chunk, ..._args) {
|
|
30803
30861
|
if (typeof chunk === "string") {
|
|
30804
|
-
|
|
30805
|
-
if (clean)
|
|
30806
|
-
captured.push(clean);
|
|
30862
|
+
captured.push(chunk);
|
|
30807
30863
|
}
|
|
30808
|
-
return
|
|
30864
|
+
return true;
|
|
30809
30865
|
};
|
|
30810
30866
|
try {
|
|
30811
30867
|
const result = await handleSlashCommand(input, commandCtx);
|
|
30812
30868
|
process.stdout.write = origWrite;
|
|
30869
|
+
if (statusBar.isActive)
|
|
30870
|
+
statusBar.handleResize();
|
|
30813
30871
|
if (result === "exit") {
|
|
30814
30872
|
return "Exit command received (ignored via Telegram).";
|
|
30815
30873
|
}
|
|
@@ -30820,7 +30878,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
30820
30878
|
rl.emit("line", input);
|
|
30821
30879
|
return `Skill invoked: ${result.name}`;
|
|
30822
30880
|
}
|
|
30823
|
-
|
|
30881
|
+
const raw = captured.join("");
|
|
30882
|
+
const clean = raw.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B[()][A-Z0-9]/g, "").replace(/\x1B\[?\??[0-9;]*[a-zA-Z]/g, "").replace(/\x1B/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐]/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
30883
|
+
if (!clean)
|
|
30884
|
+
return `Done: ${input}`;
|
|
30885
|
+
return clean.length > 3900 ? clean.slice(0, 3900) + "\n..." : clean;
|
|
30824
30886
|
} catch (err) {
|
|
30825
30887
|
process.stdout.write = origWrite;
|
|
30826
30888
|
throw err;
|
|
@@ -31468,13 +31530,13 @@ NEW TASK: ${fullInput}`;
|
|
|
31468
31530
|
writeContent(() => renderError(errMsg));
|
|
31469
31531
|
if (failureStore) {
|
|
31470
31532
|
try {
|
|
31471
|
-
const { createHash:
|
|
31533
|
+
const { createHash: createHash3 } = await import("node:crypto");
|
|
31472
31534
|
failureStore.insert({
|
|
31473
31535
|
taskId: "",
|
|
31474
31536
|
sessionId: `${Date.now()}`,
|
|
31475
31537
|
repoRoot,
|
|
31476
31538
|
failureType: "runtime-error",
|
|
31477
|
-
fingerprint:
|
|
31539
|
+
fingerprint: createHash3("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
|
|
31478
31540
|
filePath: null,
|
|
31479
31541
|
errorMessage: errMsg.slice(0, 500),
|
|
31480
31542
|
context: null,
|
|
@@ -31735,7 +31797,7 @@ var init_run = __esm({
|
|
|
31735
31797
|
import { glob } from "glob";
|
|
31736
31798
|
import ignore from "ignore";
|
|
31737
31799
|
import { readFile as readFile14, stat as stat4 } from "node:fs/promises";
|
|
31738
|
-
import { createHash } from "node:crypto";
|
|
31800
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
31739
31801
|
import { join as join41, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
|
|
31740
31802
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
31741
31803
|
var init_codebase_indexer = __esm({
|
|
@@ -31801,7 +31863,7 @@ var init_codebase_indexer = __esm({
|
|
|
31801
31863
|
if (fileStat.size > this.config.maxFileSize)
|
|
31802
31864
|
continue;
|
|
31803
31865
|
const content = await readFile14(fullPath);
|
|
31804
|
-
const hash =
|
|
31866
|
+
const hash = createHash2("sha256").update(content).digest("hex");
|
|
31805
31867
|
const ext = extname10(relativePath);
|
|
31806
31868
|
indexed.push({
|
|
31807
31869
|
path: fullPath,
|
package/package.json
CHANGED