tesseract-agent 0.2.1 → 0.2.2
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-bundle/cli.js +184 -4
- package/package.json +4 -1
package/dist-bundle/cli.js
CHANGED
|
@@ -6031,6 +6031,20 @@ function resolveUniqueName(dir, name) {
|
|
|
6031
6031
|
}
|
|
6032
6032
|
var OUTSIDE = (verb) => ({ ok: false, error: `Refusing to ${verb} outside the shared root.` });
|
|
6033
6033
|
var validName = (n) => !!n && !n.includes("/") && !n.includes("\\") && n !== "." && n !== "..";
|
|
6034
|
+
async function readRemoteBytes(root, path) {
|
|
6035
|
+
if (!isInsideRoot(path, root))
|
|
6036
|
+
return { error: "Path is outside the shared root." };
|
|
6037
|
+
try {
|
|
6038
|
+
const s = statSync(path);
|
|
6039
|
+
if (!s.isFile())
|
|
6040
|
+
return { error: "Not a file" };
|
|
6041
|
+
if (s.size > REMOTE_READ_CAP)
|
|
6042
|
+
return { error: `File is too large to read whole over the network (${(s.size / 1024 / 1024).toFixed(1)} MB) \u2014 open it locally.` };
|
|
6043
|
+
return { bytes: await readFile(path), size: s.size };
|
|
6044
|
+
} catch (err) {
|
|
6045
|
+
return { error: String(err.message) };
|
|
6046
|
+
}
|
|
6047
|
+
}
|
|
6034
6048
|
async function runRemoteFsOp(root, op, args) {
|
|
6035
6049
|
const a = args ?? [];
|
|
6036
6050
|
switch (op) {
|
|
@@ -6295,6 +6309,164 @@ function unwatchAllRemote() {
|
|
|
6295
6309
|
remoteWatches.clear();
|
|
6296
6310
|
}
|
|
6297
6311
|
|
|
6312
|
+
// ../../packages/host-core/dist/fs-datachannel-host.js
|
|
6313
|
+
var ndcPromise = null;
|
|
6314
|
+
function loadNdc() {
|
|
6315
|
+
if (!ndcPromise) {
|
|
6316
|
+
ndcPromise = (async () => {
|
|
6317
|
+
try {
|
|
6318
|
+
const m = await import("node-datachannel");
|
|
6319
|
+
return m.default ?? m;
|
|
6320
|
+
} catch {
|
|
6321
|
+
return null;
|
|
6322
|
+
}
|
|
6323
|
+
})();
|
|
6324
|
+
}
|
|
6325
|
+
return ndcPromise;
|
|
6326
|
+
}
|
|
6327
|
+
function toNdcIceServers(configs) {
|
|
6328
|
+
const out = [];
|
|
6329
|
+
for (const c of configs ?? []) {
|
|
6330
|
+
const urls = Array.isArray(c.urls) ? c.urls : [c.urls];
|
|
6331
|
+
for (const url of urls) {
|
|
6332
|
+
const m = /^(stun|stuns|turn|turns):([^:?]+)(?::(\d+))?(?:\?transport=(udp|tcp))?/i.exec(url);
|
|
6333
|
+
if (!m)
|
|
6334
|
+
continue;
|
|
6335
|
+
const scheme = m[1].toLowerCase();
|
|
6336
|
+
const hostname3 = m[2];
|
|
6337
|
+
const port = m[3] ? parseInt(m[3], 10) : scheme.endsWith("s") ? 5349 : 3478;
|
|
6338
|
+
if (scheme.startsWith("stun")) {
|
|
6339
|
+
out.push({ hostname: hostname3, port });
|
|
6340
|
+
continue;
|
|
6341
|
+
}
|
|
6342
|
+
const transport = (m[4] ?? "udp").toLowerCase();
|
|
6343
|
+
const relayType = scheme === "turns" ? "TurnTls" : transport === "tcp" ? "TurnTcp" : "TurnUdp";
|
|
6344
|
+
out.push({ hostname: hostname3, port, username: c.username, password: c.credential, relayType });
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
6347
|
+
return out;
|
|
6348
|
+
}
|
|
6349
|
+
var peers = /* @__PURE__ */ new Map();
|
|
6350
|
+
var delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6351
|
+
var CHUNK = 16 * 1024;
|
|
6352
|
+
var HIGH_WATER = 4 * 1024 * 1024;
|
|
6353
|
+
async function serveGet(dc, id, path, root) {
|
|
6354
|
+
const res = await readRemoteBytes(root, path);
|
|
6355
|
+
if (!dc.isOpen())
|
|
6356
|
+
return;
|
|
6357
|
+
if (res.error || !res.bytes) {
|
|
6358
|
+
try {
|
|
6359
|
+
dc.sendMessage(JSON.stringify({ t: "err", id, error: res.error ?? "read failed" }));
|
|
6360
|
+
} catch {
|
|
6361
|
+
}
|
|
6362
|
+
return;
|
|
6363
|
+
}
|
|
6364
|
+
const bytes = res.bytes;
|
|
6365
|
+
try {
|
|
6366
|
+
dc.sendMessage(JSON.stringify({ t: "meta", id, size: bytes.length }));
|
|
6367
|
+
} catch {
|
|
6368
|
+
return;
|
|
6369
|
+
}
|
|
6370
|
+
for (let off = 0, seq = 0; off < bytes.length; off += CHUNK, seq++) {
|
|
6371
|
+
let guard = 0;
|
|
6372
|
+
while (dc.isOpen() && dc.bufferedAmount() > HIGH_WATER && guard++ < 2e3)
|
|
6373
|
+
await delay(15);
|
|
6374
|
+
if (!dc.isOpen())
|
|
6375
|
+
return;
|
|
6376
|
+
const end = Math.min(off + CHUNK, bytes.length);
|
|
6377
|
+
const frame = Buffer.allocUnsafe(8 + (end - off));
|
|
6378
|
+
frame.writeUInt32LE(id >>> 0, 0);
|
|
6379
|
+
frame.writeUInt32LE(seq >>> 0, 4);
|
|
6380
|
+
bytes.copy(frame, 8, off, end);
|
|
6381
|
+
try {
|
|
6382
|
+
dc.sendMessageBinary(frame);
|
|
6383
|
+
} catch {
|
|
6384
|
+
return;
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6387
|
+
if (dc.isOpen()) {
|
|
6388
|
+
try {
|
|
6389
|
+
dc.sendMessage(JSON.stringify({ t: "end", id }));
|
|
6390
|
+
} catch {
|
|
6391
|
+
}
|
|
6392
|
+
}
|
|
6393
|
+
}
|
|
6394
|
+
function wireServer(dc, root) {
|
|
6395
|
+
try {
|
|
6396
|
+
dc.setBufferedAmountLowThreshold(HIGH_WATER / 4);
|
|
6397
|
+
} catch {
|
|
6398
|
+
}
|
|
6399
|
+
dc.onMessage((msg) => {
|
|
6400
|
+
if (typeof msg !== "string")
|
|
6401
|
+
return;
|
|
6402
|
+
let req;
|
|
6403
|
+
try {
|
|
6404
|
+
req = JSON.parse(msg);
|
|
6405
|
+
} catch {
|
|
6406
|
+
return;
|
|
6407
|
+
}
|
|
6408
|
+
if (req.t === "get" && typeof req.id === "number" && typeof req.path === "string")
|
|
6409
|
+
void serveGet(dc, req.id, req.path, root);
|
|
6410
|
+
});
|
|
6411
|
+
}
|
|
6412
|
+
async function handleDcSignal(clientId, msg, root, ownHostId2, emit) {
|
|
6413
|
+
if (msg.type === "signal:dc-ice") {
|
|
6414
|
+
const peer2 = peers.get(clientId);
|
|
6415
|
+
if (peer2 && peer2.remoteSet) {
|
|
6416
|
+
try {
|
|
6417
|
+
peer2.pc.addRemoteCandidate(msg.candidate, msg.mid);
|
|
6418
|
+
} catch {
|
|
6419
|
+
}
|
|
6420
|
+
} else if (peer2)
|
|
6421
|
+
peer2.pendingIce.push({ candidate: msg.candidate, mid: msg.mid });
|
|
6422
|
+
return;
|
|
6423
|
+
}
|
|
6424
|
+
if (msg.type !== "signal:dc-offer")
|
|
6425
|
+
return;
|
|
6426
|
+
const ndc = await loadNdc();
|
|
6427
|
+
if (!ndc) {
|
|
6428
|
+
emit({ type: "signal:dc-unavailable", hostId: ownHostId2 });
|
|
6429
|
+
return;
|
|
6430
|
+
}
|
|
6431
|
+
releaseDcClient(clientId);
|
|
6432
|
+
let pc;
|
|
6433
|
+
try {
|
|
6434
|
+
pc = new ndc.PeerConnection("fsdc", { iceServers: toNdcIceServers(msg.iceServers) });
|
|
6435
|
+
} catch {
|
|
6436
|
+
emit({ type: "signal:dc-unavailable", hostId: ownHostId2 });
|
|
6437
|
+
return;
|
|
6438
|
+
}
|
|
6439
|
+
const peer = { pc, pendingIce: [], remoteSet: false };
|
|
6440
|
+
peers.set(clientId, peer);
|
|
6441
|
+
pc.onLocalDescription((sdp, type) => emit({ type: "signal:dc-answer", sdp, sdpType: type, hostId: ownHostId2 }));
|
|
6442
|
+
pc.onLocalCandidate((candidate, mid) => emit({ type: "signal:dc-ice", candidate, mid, hostId: ownHostId2 }));
|
|
6443
|
+
pc.onDataChannel((dc) => wireServer(dc, root));
|
|
6444
|
+
try {
|
|
6445
|
+
pc.setRemoteDescription(msg.sdp, "offer");
|
|
6446
|
+
peer.remoteSet = true;
|
|
6447
|
+
for (const c of peer.pendingIce) {
|
|
6448
|
+
try {
|
|
6449
|
+
pc.addRemoteCandidate(c.candidate, c.mid);
|
|
6450
|
+
} catch {
|
|
6451
|
+
}
|
|
6452
|
+
}
|
|
6453
|
+
peer.pendingIce = [];
|
|
6454
|
+
} catch {
|
|
6455
|
+
releaseDcClient(clientId);
|
|
6456
|
+
emit({ type: "signal:dc-unavailable", hostId: ownHostId2 });
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6459
|
+
function releaseDcClient(clientId) {
|
|
6460
|
+
const peer = peers.get(clientId);
|
|
6461
|
+
if (!peer)
|
|
6462
|
+
return;
|
|
6463
|
+
peers.delete(clientId);
|
|
6464
|
+
try {
|
|
6465
|
+
peer.pc.close();
|
|
6466
|
+
} catch {
|
|
6467
|
+
}
|
|
6468
|
+
}
|
|
6469
|
+
|
|
6298
6470
|
// ../../packages/host-core/dist/host-metrics.js
|
|
6299
6471
|
import os from "node:os";
|
|
6300
6472
|
function primaryIpv4(ifaces = os.networkInterfaces()) {
|
|
@@ -6331,8 +6503,8 @@ function dynamicMetrics() {
|
|
|
6331
6503
|
import { readdir as readdir2, lstat, mkdir as mkdir3, chmod, rm as rm2, readlink, symlink, stat as stat2 } from "node:fs/promises";
|
|
6332
6504
|
import { openSync as openSync2, readSync as readSync2, closeSync as closeSync2, existsSync as existsSync3, createWriteStream } from "node:fs";
|
|
6333
6505
|
import { dirname as dirname4, join as join4, relative as relative2, sep as sep2 } from "node:path";
|
|
6334
|
-
var
|
|
6335
|
-
var MAX_INFLIGHT = 8 *
|
|
6506
|
+
var CHUNK2 = 1024 * 1024;
|
|
6507
|
+
var MAX_INFLIGHT = 8 * CHUNK2;
|
|
6336
6508
|
var IDLE_MS = 6e4;
|
|
6337
6509
|
var HEAVY_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", ".next", ".turbo", "out", "target", ".cache", "coverage"]);
|
|
6338
6510
|
var ALWAYS_SKIP = /* @__PURE__ */ new Set([".DS_Store"]);
|
|
@@ -6465,11 +6637,11 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
|
|
|
6465
6637
|
if (f.size === 0) {
|
|
6466
6638
|
send2({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset: 0, base64: "", eof: true }, { hostId: toHost });
|
|
6467
6639
|
} else {
|
|
6468
|
-
for (let offset = 0; offset < f.size && !state.cancelled; offset +=
|
|
6640
|
+
for (let offset = 0; offset < f.size && !state.cancelled; offset += CHUNK2) {
|
|
6469
6641
|
await waitWindow();
|
|
6470
6642
|
if (state.cancelled)
|
|
6471
6643
|
break;
|
|
6472
|
-
const len = Math.min(
|
|
6644
|
+
const len = Math.min(CHUNK2, f.size - offset);
|
|
6473
6645
|
const buf = Buffer.alloc(len);
|
|
6474
6646
|
const read = readSync2(fd, buf, 0, len, offset);
|
|
6475
6647
|
send2({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset, base64: buf.subarray(0, read).toString("base64"), eof: offset + len >= f.size }, { hostId: toHost });
|
|
@@ -6939,6 +7111,7 @@ async function serveInboundFs(requestId, op, args, driverClientId) {
|
|
|
6939
7111
|
}
|
|
6940
7112
|
function releaseDriver(clientId) {
|
|
6941
7113
|
unwatchRemoteClient(clientId);
|
|
7114
|
+
releaseDcClient(clientId);
|
|
6942
7115
|
for (const [sid, cid] of [...driverBySession]) {
|
|
6943
7116
|
if (cid !== clientId)
|
|
6944
7117
|
continue;
|
|
@@ -7136,6 +7309,13 @@ function connect() {
|
|
|
7136
7309
|
}
|
|
7137
7310
|
return;
|
|
7138
7311
|
}
|
|
7312
|
+
if (channel === "signal") {
|
|
7313
|
+
const p = env.payload;
|
|
7314
|
+
if (inbound && clientId && typeof p?.type === "string" && p.type.startsWith("signal:dc-")) {
|
|
7315
|
+
void handleDcSignal(clientId, p, HOST_ROOT, ownHostId(), (payload) => send("signal", payload, { clientId, browserId: "fsdc" }));
|
|
7316
|
+
}
|
|
7317
|
+
return;
|
|
7318
|
+
}
|
|
7139
7319
|
};
|
|
7140
7320
|
socket.onclose = () => {
|
|
7141
7321
|
cleanup();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tesseract-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@anthropic-ai/claude-agent-sdk": "0.2.112"
|
|
35
35
|
},
|
|
36
|
+
"optionalDependencies": {
|
|
37
|
+
"node-datachannel": "^0.32.0"
|
|
38
|
+
},
|
|
36
39
|
"devDependencies": {
|
|
37
40
|
"@fineguide-tesseract/agent-core": "*",
|
|
38
41
|
"@fineguide-tesseract/host-core": "*",
|