@annals/agent-mesh 0.17.2 → 0.17.3
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 +115 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1251,6 +1251,32 @@ var BridgeManager = class {
|
|
|
1251
1251
|
}, 5 * 6e4);
|
|
1252
1252
|
timer.unref?.();
|
|
1253
1253
|
this.pendingTransfers.set(offer.transfer_id, { sender, timer });
|
|
1254
|
+
this.pushZipToWorker(offer.transfer_id, zipBuffer);
|
|
1255
|
+
}
|
|
1256
|
+
/** Push ZIP buffer to Worker DO via chunked transfer_upload messages */
|
|
1257
|
+
pushZipToWorker(transferId, zipBuffer) {
|
|
1258
|
+
const CHUNK_SIZE2 = 64 * 1024;
|
|
1259
|
+
const totalChunks = Math.ceil(zipBuffer.length / CHUNK_SIZE2);
|
|
1260
|
+
log.debug(`Pushing ZIP to Worker: transfer=${transferId.slice(0, 8)}... size=${zipBuffer.length} chunks=${totalChunks}`);
|
|
1261
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
1262
|
+
const start = i * CHUNK_SIZE2;
|
|
1263
|
+
const end = Math.min(start + CHUNK_SIZE2, zipBuffer.length);
|
|
1264
|
+
const chunk = zipBuffer.subarray(start, end);
|
|
1265
|
+
const msg = {
|
|
1266
|
+
type: "transfer_upload",
|
|
1267
|
+
transfer_id: transferId,
|
|
1268
|
+
chunk_index: i,
|
|
1269
|
+
total_chunks: totalChunks,
|
|
1270
|
+
data: chunk.toString("base64")
|
|
1271
|
+
};
|
|
1272
|
+
this.wsClient.send(msg);
|
|
1273
|
+
}
|
|
1274
|
+
const complete = {
|
|
1275
|
+
type: "transfer_upload_complete",
|
|
1276
|
+
transfer_id: transferId
|
|
1277
|
+
};
|
|
1278
|
+
this.wsClient.send(complete);
|
|
1279
|
+
log.info(`ZIP pushed to Worker: transfer=${transferId.slice(0, 8)}... (${totalChunks} chunks)`);
|
|
1254
1280
|
}
|
|
1255
1281
|
handleRtcSignalRelay(msg) {
|
|
1256
1282
|
const entry = this.pendingTransfers.get(msg.transfer_id);
|
|
@@ -4502,7 +4528,10 @@ function registerDiscoverCommand(program2) {
|
|
|
4502
4528
|
}
|
|
4503
4529
|
|
|
4504
4530
|
// src/commands/call.ts
|
|
4505
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
4531
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5 } from "fs";
|
|
4532
|
+
import { createHash as createHash2 } from "crypto";
|
|
4533
|
+
import { execSync as execSync4 } from "child_process";
|
|
4534
|
+
import { join as join11 } from "path";
|
|
4506
4535
|
var DEFAULT_BASE_URL4 = "https://agents.hot";
|
|
4507
4536
|
async function submitRating(baseUrl, token, agentId, callId, rating) {
|
|
4508
4537
|
const res = await fetch(`${baseUrl}/api/agents/${agentId}/rate`, {
|
|
@@ -4534,6 +4563,75 @@ function handleError2(err) {
|
|
|
4534
4563
|
}
|
|
4535
4564
|
process.exit(1);
|
|
4536
4565
|
}
|
|
4566
|
+
async function downloadTransferFiles(agentId, offer, token, outputDir, json) {
|
|
4567
|
+
const url = `${DEFAULT_BASE_URL4}/api/agents/${agentId}/transfer/${offer.transfer_id}`;
|
|
4568
|
+
if (!json) {
|
|
4569
|
+
log.info(`Downloading ${offer.file_count} file(s) (${(offer.zip_size / 1024).toFixed(1)} KB)...`);
|
|
4570
|
+
}
|
|
4571
|
+
await sleep6(1e3);
|
|
4572
|
+
let lastError = null;
|
|
4573
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
4574
|
+
try {
|
|
4575
|
+
const res = await fetch(url, {
|
|
4576
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
4577
|
+
});
|
|
4578
|
+
if (res.status === 202) {
|
|
4579
|
+
await sleep6(2e3);
|
|
4580
|
+
continue;
|
|
4581
|
+
}
|
|
4582
|
+
if (res.status === 404) {
|
|
4583
|
+
if (attempt < 4) {
|
|
4584
|
+
await sleep6(2e3);
|
|
4585
|
+
continue;
|
|
4586
|
+
}
|
|
4587
|
+
log.warn("Transfer expired or not found");
|
|
4588
|
+
return;
|
|
4589
|
+
}
|
|
4590
|
+
if (!res.ok) {
|
|
4591
|
+
log.warn(`Download failed: HTTP ${res.status}`);
|
|
4592
|
+
return;
|
|
4593
|
+
}
|
|
4594
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
4595
|
+
const zipBuffer = Buffer.from(arrayBuffer);
|
|
4596
|
+
const hash = createHash2("sha256").update(zipBuffer).digest("hex");
|
|
4597
|
+
if (hash !== offer.zip_sha256) {
|
|
4598
|
+
log.warn(`SHA-256 mismatch: expected ${offer.zip_sha256.slice(0, 12)}... got ${hash.slice(0, 12)}...`);
|
|
4599
|
+
return;
|
|
4600
|
+
}
|
|
4601
|
+
mkdirSync5(outputDir, { recursive: true });
|
|
4602
|
+
const zipPath = join11(outputDir, `.transfer-${offer.transfer_id.slice(0, 8)}.zip`);
|
|
4603
|
+
writeFileSync3(zipPath, zipBuffer);
|
|
4604
|
+
try {
|
|
4605
|
+
execSync4(`unzip -o -q "${zipPath}" -d "${outputDir}"`);
|
|
4606
|
+
try {
|
|
4607
|
+
execSync4(`rm "${zipPath}"`);
|
|
4608
|
+
} catch {
|
|
4609
|
+
}
|
|
4610
|
+
} catch {
|
|
4611
|
+
log.warn(`Failed to extract ZIP. Saved to: ${zipPath}`);
|
|
4612
|
+
return;
|
|
4613
|
+
}
|
|
4614
|
+
if (json) {
|
|
4615
|
+
console.log(JSON.stringify({
|
|
4616
|
+
type: "files_downloaded",
|
|
4617
|
+
file_count: offer.file_count,
|
|
4618
|
+
output_dir: outputDir,
|
|
4619
|
+
zip_size: zipBuffer.length,
|
|
4620
|
+
sha256_verified: true
|
|
4621
|
+
}));
|
|
4622
|
+
} else {
|
|
4623
|
+
log.success(`${offer.file_count} file(s) extracted to ${outputDir}`);
|
|
4624
|
+
}
|
|
4625
|
+
return;
|
|
4626
|
+
} catch (err) {
|
|
4627
|
+
lastError = err;
|
|
4628
|
+
if (attempt < 4) {
|
|
4629
|
+
await sleep6(2e3);
|
|
4630
|
+
}
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
log.warn(`Download failed after retries: ${lastError?.message || "unknown error"}`);
|
|
4634
|
+
}
|
|
4537
4635
|
async function asyncCall(opts) {
|
|
4538
4636
|
const selfAgentId = process.env.AGENT_BRIDGE_AGENT_ID;
|
|
4539
4637
|
const res = await fetch(`${DEFAULT_BASE_URL4}/api/agents/${opts.id}/call`, {
|
|
@@ -4598,6 +4696,7 @@ async function asyncCall(opts) {
|
|
|
4598
4696
|
`);
|
|
4599
4697
|
}
|
|
4600
4698
|
const result = task.result || "";
|
|
4699
|
+
const offer = task.file_transfer_offer;
|
|
4601
4700
|
if (opts.json) {
|
|
4602
4701
|
console.log(JSON.stringify({
|
|
4603
4702
|
call_id,
|
|
@@ -4606,7 +4705,7 @@ async function asyncCall(opts) {
|
|
|
4606
4705
|
status: "completed",
|
|
4607
4706
|
result,
|
|
4608
4707
|
...task.attachments?.length ? { attachments: task.attachments } : {},
|
|
4609
|
-
...
|
|
4708
|
+
...offer ? { file_transfer_offer: offer } : {},
|
|
4610
4709
|
rate_hint: `POST /api/agents/${opts.id}/rate body: { call_id: "${call_id}", rating: 1-5 }`
|
|
4611
4710
|
}));
|
|
4612
4711
|
} else {
|
|
@@ -4616,10 +4715,6 @@ async function asyncCall(opts) {
|
|
|
4616
4715
|
log.info(` ${GRAY}File:${RESET} ${att.name} ${GRAY}${att.url}${RESET}`);
|
|
4617
4716
|
}
|
|
4618
4717
|
}
|
|
4619
|
-
const offer = task.file_transfer_offer;
|
|
4620
|
-
if (offer) {
|
|
4621
|
-
log.info(` ${GRAY}Files:${RESET} ${offer.file_count} file(s) available via WebRTC`);
|
|
4622
|
-
}
|
|
4623
4718
|
if (session_key) {
|
|
4624
4719
|
log.info(` ${GRAY}Session:${RESET} ${session_key}`);
|
|
4625
4720
|
}
|
|
@@ -4628,6 +4723,10 @@ async function asyncCall(opts) {
|
|
|
4628
4723
|
writeFileSync3(opts.outputFile, result);
|
|
4629
4724
|
if (!opts.json) log.info(`Saved to ${opts.outputFile}`);
|
|
4630
4725
|
}
|
|
4726
|
+
if (offer && opts.withFiles) {
|
|
4727
|
+
const outputDir = opts.outputFile ? join11(opts.outputFile, "..", "files") : join11(process.cwd(), "agent-output");
|
|
4728
|
+
await downloadTransferFiles(opts.id, offer, opts.token, outputDir, opts.json);
|
|
4729
|
+
}
|
|
4631
4730
|
if (!opts.json) {
|
|
4632
4731
|
log.info(`${GRAY}Rate this call: agent-mesh rate ${call_id} <1-5> --agent ${opts.id}${RESET}`);
|
|
4633
4732
|
}
|
|
@@ -4715,6 +4814,7 @@ async function streamCall(opts) {
|
|
|
4715
4814
|
let inThinkingBlock = false;
|
|
4716
4815
|
let callId = res.headers.get("X-Call-Id") || "";
|
|
4717
4816
|
let sessionKey = res.headers.get("X-Session-Key") || "";
|
|
4817
|
+
let fileOffer = null;
|
|
4718
4818
|
while (true) {
|
|
4719
4819
|
const { done, value } = await reader.read();
|
|
4720
4820
|
if (done) break;
|
|
@@ -4756,7 +4856,7 @@ async function streamCall(opts) {
|
|
|
4756
4856
|
}
|
|
4757
4857
|
}
|
|
4758
4858
|
if (event.file_transfer_offer) {
|
|
4759
|
-
|
|
4859
|
+
fileOffer = event.file_transfer_offer;
|
|
4760
4860
|
}
|
|
4761
4861
|
} else if (event.type === "error") {
|
|
4762
4862
|
process.stderr.write(`
|
|
@@ -4785,6 +4885,9 @@ Error: ${event.message}
|
|
|
4785
4885
|
}
|
|
4786
4886
|
}
|
|
4787
4887
|
}
|
|
4888
|
+
if (event.type === "done" && event.file_transfer_offer) {
|
|
4889
|
+
fileOffer = event.file_transfer_offer;
|
|
4890
|
+
}
|
|
4788
4891
|
} catch {
|
|
4789
4892
|
}
|
|
4790
4893
|
}
|
|
@@ -4793,6 +4896,11 @@ Error: ${event.message}
|
|
|
4793
4896
|
writeFileSync3(opts.outputFile, outputBuffer);
|
|
4794
4897
|
if (!opts.json) log.info(`Saved to ${opts.outputFile}`);
|
|
4795
4898
|
}
|
|
4899
|
+
if (fileOffer && opts.withFiles) {
|
|
4900
|
+
console.log("");
|
|
4901
|
+
const outputDir = opts.outputFile ? join11(opts.outputFile, "..", "files") : join11(process.cwd(), "agent-output");
|
|
4902
|
+
await downloadTransferFiles(opts.id, fileOffer, opts.token, outputDir, opts.json);
|
|
4903
|
+
}
|
|
4796
4904
|
if (!opts.json) {
|
|
4797
4905
|
console.log("\n");
|
|
4798
4906
|
log.success("Call completed");
|