jefrichat-mcp 0.48.11 → 0.48.12
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/http.js +75 -36
- package/dist/index.js +75 -36
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -62102,9 +62102,17 @@ function retryKey(extra, parts) {
|
|
|
62102
62102
|
if (rid === void 0 || rid === null) return void 0;
|
|
62103
62103
|
const h = extra?.requestInfo?.headers;
|
|
62104
62104
|
const ua = String((typeof h?.get === "function" ? h.get("user-agent") : h?.["user-agent"]) ?? "");
|
|
62105
|
-
|
|
62105
|
+
if (!ua) return void 0;
|
|
62106
|
+
const bucket = Math.floor(Date.now() / 75e3);
|
|
62106
62107
|
return "mcp-" + createHash2("sha256").update(JSON.stringify([bucket, ua, rid, ...parts])).digest("hex").slice(0, 40);
|
|
62107
62108
|
}
|
|
62109
|
+
function declKey(extra, parts) {
|
|
62110
|
+
const rid = extra?.requestId;
|
|
62111
|
+
if (rid === void 0 || rid === null) return void 0;
|
|
62112
|
+
const h = extra?.requestInfo?.headers;
|
|
62113
|
+
const ua = String((typeof h?.get === "function" ? h.get("user-agent") : h?.["user-agent"]) ?? "");
|
|
62114
|
+
return "d-" + createHash2("sha256").update(JSON.stringify([ua, rid, ...parts])).digest("hex").slice(0, 40);
|
|
62115
|
+
}
|
|
62108
62116
|
async function fetchHistory(c, convId) {
|
|
62109
62117
|
if (isStateless(c)) return c.history(convId);
|
|
62110
62118
|
const p = waitFor(c, "history", (e) => e.conversationId === convId, 4e3);
|
|
@@ -62564,10 +62572,17 @@ Use jefri_agent_apps with agent=<name> to see its live app + active state.`);
|
|
|
62564
62572
|
}
|
|
62565
62573
|
},
|
|
62566
62574
|
async ({ to, text: text5 }, extra) => withClient(async (c) => {
|
|
62567
|
-
|
|
62568
|
-
|
|
62569
|
-
|
|
62570
|
-
|
|
62575
|
+
if (isStateless(c)) {
|
|
62576
|
+
try {
|
|
62577
|
+
const res = await c.message(to, text5, retryKey(extra, ["message", to, text5]));
|
|
62578
|
+
if (res?.deduplicated)
|
|
62579
|
+
return ok3(`Already delivered to @${to} \u2014 this request matched a recent identical send and was suppressed as a retry. If you meant it as a NEW message, send it again (it will not be suppressed twice).`);
|
|
62580
|
+
return ok3(`Sent to @${to}: "${text5}"`);
|
|
62581
|
+
} catch (e) {
|
|
62582
|
+
return fail(`Message rejected: ${e?.message ?? e}`);
|
|
62583
|
+
}
|
|
62584
|
+
}
|
|
62585
|
+
const r = await confirmWrite(c, () => c.message(to, text5));
|
|
62571
62586
|
if (r.error) return fail(`Message rejected: ${r.error}`);
|
|
62572
62587
|
return ok3(`Sent to @${to}: "${text5}"`);
|
|
62573
62588
|
})
|
|
@@ -62780,13 +62795,15 @@ ${psCmd}
|
|
|
62780
62795
|
return fail(`${name} is ${MB(rawBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
62781
62796
|
if (isStateless(c)) {
|
|
62782
62797
|
try {
|
|
62783
|
-
await c.sendFile(
|
|
62798
|
+
const res = await c.sendFile(
|
|
62784
62799
|
{ to, caption },
|
|
62785
62800
|
name,
|
|
62786
62801
|
mime,
|
|
62787
62802
|
rawBytes,
|
|
62788
62803
|
retryKey(extra, ["file", to, name, createHash2("sha256").update(rawBytes).digest("hex")])
|
|
62789
62804
|
);
|
|
62805
|
+
if (res?.deduplicated)
|
|
62806
|
+
return ok3(`Already delivered \u2014 ${name} matched a recent identical upload and was suppressed as a retry (round 28 #2: suppression is SAID, never a false "Sent"). If you meant a new copy, send it again.`);
|
|
62790
62807
|
} catch (e2) {
|
|
62791
62808
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
62792
62809
|
}
|
|
@@ -62828,13 +62845,15 @@ ${psCmd}
|
|
|
62828
62845
|
return fail(`That content is ${MB(contentBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
62829
62846
|
if (isStateless(c)) {
|
|
62830
62847
|
try {
|
|
62831
|
-
await c.sendFile(
|
|
62848
|
+
const res = await c.sendFile(
|
|
62832
62849
|
{ to, caption },
|
|
62833
62850
|
fileName,
|
|
62834
62851
|
mime,
|
|
62835
62852
|
contentBytes,
|
|
62836
62853
|
retryKey(extra, ["file", to, fileName, createHash2("sha256").update(contentBytes).digest("hex")])
|
|
62837
62854
|
);
|
|
62855
|
+
if (res?.deduplicated)
|
|
62856
|
+
return ok3(`Already delivered \u2014 ${fileName} matched a recent identical upload and was suppressed as a retry. If you meant a new copy, send it again.`);
|
|
62838
62857
|
} catch (e2) {
|
|
62839
62858
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
62840
62859
|
}
|
|
@@ -63244,25 +63263,7 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
63244
63263
|
ctx.inbox.length = 0;
|
|
63245
63264
|
}
|
|
63246
63265
|
if (!msgs.length) return ok3("\u{1F4ED} No new messages.");
|
|
63247
|
-
msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : 1);
|
|
63248
|
-
if (ctx.stateless) {
|
|
63249
|
-
const last = msgs[msgs.length - 1];
|
|
63250
|
-
const ack = async () => {
|
|
63251
|
-
try {
|
|
63252
|
-
await fetch(`${ctx.serverUrl.replace(/\/$/, "")}/api/inbox/seen`, {
|
|
63253
|
-
method: "POST",
|
|
63254
|
-
headers: { authorization: `Bearer ${c.token}`, "content-type": "application/json" },
|
|
63255
|
-
body: JSON.stringify({ until: last.createdAt, untilId: last.id })
|
|
63256
|
-
});
|
|
63257
|
-
} catch {
|
|
63258
|
-
}
|
|
63259
|
-
};
|
|
63260
|
-
if (ctx.deferUntilDelivered) ctx.deferUntilDelivered(ack);
|
|
63261
|
-
else await ack();
|
|
63262
|
-
} else {
|
|
63263
|
-
inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
|
|
63264
|
-
saveWatermark();
|
|
63265
|
-
}
|
|
63266
|
+
msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : a.createdAt > b.createdAt ? 1 : a.id < b.id ? -1 : 1);
|
|
63266
63267
|
const groupNames = /* @__PURE__ */ new Map();
|
|
63267
63268
|
if (msgs.some((m) => m.groupId)) {
|
|
63268
63269
|
try {
|
|
@@ -63290,8 +63291,27 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
63290
63291
|
const body = m.kind === "file" ? `\u{1F4CE} sent a file: ${m.fileName} \u2014 to save it call jefri_download_file(from: "${m.senderUsername}"${m.fileName ? `, fileName: "${m.fileName}"` : ""})` : m.content;
|
|
63291
63292
|
return `${at}@${m.senderUsername}${where(m)}: ${body}`;
|
|
63292
63293
|
}));
|
|
63293
|
-
|
|
63294
|
-
` + lines.join("\n")
|
|
63294
|
+
const rendered = `\u{1F4E8} ${lines.length} message(s):
|
|
63295
|
+
` + lines.join("\n");
|
|
63296
|
+
if (ctx.stateless) {
|
|
63297
|
+
const renderedIds = msgs.map((m) => m.id);
|
|
63298
|
+
const ack = async () => {
|
|
63299
|
+
try {
|
|
63300
|
+
await fetch(`${ctx.serverUrl.replace(/\/$/, "")}/api/inbox/seen`, {
|
|
63301
|
+
method: "POST",
|
|
63302
|
+
headers: { authorization: `Bearer ${c.token}`, "content-type": "application/json" },
|
|
63303
|
+
body: JSON.stringify({ messageIds: renderedIds })
|
|
63304
|
+
});
|
|
63305
|
+
} catch {
|
|
63306
|
+
}
|
|
63307
|
+
};
|
|
63308
|
+
if (ctx.deferUntilDelivered) ctx.deferUntilDelivered(ack);
|
|
63309
|
+
else await ack();
|
|
63310
|
+
} else {
|
|
63311
|
+
inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
|
|
63312
|
+
saveWatermark();
|
|
63313
|
+
}
|
|
63314
|
+
return ok3(rendered);
|
|
63295
63315
|
})
|
|
63296
63316
|
);
|
|
63297
63317
|
server2.registerTool(
|
|
@@ -63321,10 +63341,17 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
63321
63341
|
}
|
|
63322
63342
|
},
|
|
63323
63343
|
async ({ groupId, text: text5 }, extra) => withClient(async (c) => {
|
|
63324
|
-
|
|
63325
|
-
|
|
63326
|
-
|
|
63327
|
-
|
|
63344
|
+
if (isStateless(c)) {
|
|
63345
|
+
try {
|
|
63346
|
+
const res = await c.groupMessage(groupId, text5, retryKey(extra, ["group_message", groupId, text5]));
|
|
63347
|
+
if (res?.deduplicated)
|
|
63348
|
+
return ok3(`Already posted \u2014 this request matched a recent identical post and was suppressed as a retry. If you meant it as a NEW message, send it again.`);
|
|
63349
|
+
return ok3(`Posted to the group.`);
|
|
63350
|
+
} catch (e) {
|
|
63351
|
+
return fail(`Couldn't post to the group: ${e?.message ?? e}`);
|
|
63352
|
+
}
|
|
63353
|
+
}
|
|
63354
|
+
const r = await confirmWrite(c, () => c.groupMessage(groupId, text5));
|
|
63328
63355
|
if (r.error) return fail(`Couldn't post to the group: ${r.error}`);
|
|
63329
63356
|
return ok3(`Posted to the group.`);
|
|
63330
63357
|
})
|
|
@@ -63389,13 +63416,15 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
63389
63416
|
return fail(`${name} is ${MB(rawBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
63390
63417
|
if (isStateless(c)) {
|
|
63391
63418
|
try {
|
|
63392
|
-
await c.sendFile(
|
|
63419
|
+
const res = await c.sendFile(
|
|
63393
63420
|
{ groupId, caption },
|
|
63394
63421
|
name,
|
|
63395
63422
|
mime,
|
|
63396
63423
|
rawBytes,
|
|
63397
63424
|
retryKey(extra, ["file", groupId, name, createHash2("sha256").update(rawBytes).digest("hex")])
|
|
63398
63425
|
);
|
|
63426
|
+
if (res?.deduplicated)
|
|
63427
|
+
return ok3(`Already delivered \u2014 ${name} matched a recent identical upload and was suppressed as a retry. If you meant a new copy, send it again.`);
|
|
63399
63428
|
} catch (e2) {
|
|
63400
63429
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
63401
63430
|
}
|
|
@@ -63487,10 +63516,20 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
63487
63516
|
}
|
|
63488
63517
|
},
|
|
63489
63518
|
async ({ status }, extra) => withClient(async (c) => {
|
|
63490
|
-
|
|
63491
|
-
|
|
63519
|
+
if (isStateless(c)) {
|
|
63520
|
+
const declId = declKey(extra, ["presence", status]);
|
|
63521
|
+
try {
|
|
63522
|
+
const res = await c.presence(status, declId);
|
|
63523
|
+
ctx.onPresenceDeclared?.(res.status);
|
|
63524
|
+
if (res.replayed && res.status !== status)
|
|
63525
|
+
return ok3(`That request was an old retry \u2014 your status is "${res.status}" (a newer declaration stands).`);
|
|
63526
|
+
return ok3(`Status set to ${res.status}.`);
|
|
63527
|
+
} catch (e) {
|
|
63528
|
+
return fail(`Couldn't set status: ${e?.message ?? e}`);
|
|
63529
|
+
}
|
|
63530
|
+
}
|
|
63531
|
+
const r = await confirmWrite(c, () => c.presence(status));
|
|
63492
63532
|
if (r.error) return fail(`Couldn't set status: ${r.error}`);
|
|
63493
|
-
ctx.onPresenceDeclared?.(status);
|
|
63494
63533
|
return ok3(`Status set to ${status}.`);
|
|
63495
63534
|
})
|
|
63496
63535
|
);
|
package/dist/index.js
CHANGED
|
@@ -40562,9 +40562,17 @@ function retryKey(extra, parts) {
|
|
|
40562
40562
|
if (rid === void 0 || rid === null) return void 0;
|
|
40563
40563
|
const h = extra?.requestInfo?.headers;
|
|
40564
40564
|
const ua = String((typeof h?.get === "function" ? h.get("user-agent") : h?.["user-agent"]) ?? "");
|
|
40565
|
-
|
|
40565
|
+
if (!ua) return void 0;
|
|
40566
|
+
const bucket = Math.floor(Date.now() / 75e3);
|
|
40566
40567
|
return "mcp-" + createHash("sha256").update(JSON.stringify([bucket, ua, rid, ...parts])).digest("hex").slice(0, 40);
|
|
40567
40568
|
}
|
|
40569
|
+
function declKey(extra, parts) {
|
|
40570
|
+
const rid = extra?.requestId;
|
|
40571
|
+
if (rid === void 0 || rid === null) return void 0;
|
|
40572
|
+
const h = extra?.requestInfo?.headers;
|
|
40573
|
+
const ua = String((typeof h?.get === "function" ? h.get("user-agent") : h?.["user-agent"]) ?? "");
|
|
40574
|
+
return "d-" + createHash("sha256").update(JSON.stringify([ua, rid, ...parts])).digest("hex").slice(0, 40);
|
|
40575
|
+
}
|
|
40568
40576
|
async function fetchHistory2(c2, convId) {
|
|
40569
40577
|
if (isStateless(c2)) return c2.history(convId);
|
|
40570
40578
|
const p = waitFor(c2, "history", (e) => e.conversationId === convId, 4e3);
|
|
@@ -41027,10 +41035,17 @@ Use jefri_agent_apps with agent=<name> to see its live app + active state.`);
|
|
|
41027
41035
|
}
|
|
41028
41036
|
},
|
|
41029
41037
|
async ({ to, text: text5 }, extra) => withClient(async (c2) => {
|
|
41030
|
-
|
|
41031
|
-
|
|
41032
|
-
|
|
41033
|
-
|
|
41038
|
+
if (isStateless(c2)) {
|
|
41039
|
+
try {
|
|
41040
|
+
const res = await c2.message(to, text5, retryKey(extra, ["message", to, text5]));
|
|
41041
|
+
if (res?.deduplicated)
|
|
41042
|
+
return ok3(`Already delivered to @${to} \u2014 this request matched a recent identical send and was suppressed as a retry. If you meant it as a NEW message, send it again (it will not be suppressed twice).`);
|
|
41043
|
+
return ok3(`Sent to @${to}: "${text5}"`);
|
|
41044
|
+
} catch (e) {
|
|
41045
|
+
return fail(`Message rejected: ${e?.message ?? e}`);
|
|
41046
|
+
}
|
|
41047
|
+
}
|
|
41048
|
+
const r = await confirmWrite(c2, () => c2.message(to, text5));
|
|
41034
41049
|
if (r.error) return fail(`Message rejected: ${r.error}`);
|
|
41035
41050
|
return ok3(`Sent to @${to}: "${text5}"`);
|
|
41036
41051
|
})
|
|
@@ -41243,13 +41258,15 @@ ${psCmd}
|
|
|
41243
41258
|
return fail(`${name} is ${MB(rawBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
41244
41259
|
if (isStateless(c2)) {
|
|
41245
41260
|
try {
|
|
41246
|
-
await c2.sendFile(
|
|
41261
|
+
const res = await c2.sendFile(
|
|
41247
41262
|
{ to, caption },
|
|
41248
41263
|
name,
|
|
41249
41264
|
mime,
|
|
41250
41265
|
rawBytes,
|
|
41251
41266
|
retryKey(extra, ["file", to, name, createHash("sha256").update(rawBytes).digest("hex")])
|
|
41252
41267
|
);
|
|
41268
|
+
if (res?.deduplicated)
|
|
41269
|
+
return ok3(`Already delivered \u2014 ${name} matched a recent identical upload and was suppressed as a retry (round 28 #2: suppression is SAID, never a false "Sent"). If you meant a new copy, send it again.`);
|
|
41253
41270
|
} catch (e2) {
|
|
41254
41271
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
41255
41272
|
}
|
|
@@ -41291,13 +41308,15 @@ ${psCmd}
|
|
|
41291
41308
|
return fail(`That content is ${MB(contentBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
41292
41309
|
if (isStateless(c2)) {
|
|
41293
41310
|
try {
|
|
41294
|
-
await c2.sendFile(
|
|
41311
|
+
const res = await c2.sendFile(
|
|
41295
41312
|
{ to, caption },
|
|
41296
41313
|
fileName,
|
|
41297
41314
|
mime,
|
|
41298
41315
|
contentBytes,
|
|
41299
41316
|
retryKey(extra, ["file", to, fileName, createHash("sha256").update(contentBytes).digest("hex")])
|
|
41300
41317
|
);
|
|
41318
|
+
if (res?.deduplicated)
|
|
41319
|
+
return ok3(`Already delivered \u2014 ${fileName} matched a recent identical upload and was suppressed as a retry. If you meant a new copy, send it again.`);
|
|
41301
41320
|
} catch (e2) {
|
|
41302
41321
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
41303
41322
|
}
|
|
@@ -41707,25 +41726,7 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41707
41726
|
ctx.inbox.length = 0;
|
|
41708
41727
|
}
|
|
41709
41728
|
if (!msgs.length) return ok3("\u{1F4ED} No new messages.");
|
|
41710
|
-
msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : 1);
|
|
41711
|
-
if (ctx.stateless) {
|
|
41712
|
-
const last = msgs[msgs.length - 1];
|
|
41713
|
-
const ack = async () => {
|
|
41714
|
-
try {
|
|
41715
|
-
await fetch(`${ctx.serverUrl.replace(/\/$/, "")}/api/inbox/seen`, {
|
|
41716
|
-
method: "POST",
|
|
41717
|
-
headers: { authorization: `Bearer ${c2.token}`, "content-type": "application/json" },
|
|
41718
|
-
body: JSON.stringify({ until: last.createdAt, untilId: last.id })
|
|
41719
|
-
});
|
|
41720
|
-
} catch {
|
|
41721
|
-
}
|
|
41722
|
-
};
|
|
41723
|
-
if (ctx.deferUntilDelivered) ctx.deferUntilDelivered(ack);
|
|
41724
|
-
else await ack();
|
|
41725
|
-
} else {
|
|
41726
|
-
inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
|
|
41727
|
-
saveWatermark();
|
|
41728
|
-
}
|
|
41729
|
+
msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : a.createdAt > b.createdAt ? 1 : a.id < b.id ? -1 : 1);
|
|
41729
41730
|
const groupNames = /* @__PURE__ */ new Map();
|
|
41730
41731
|
if (msgs.some((m) => m.groupId)) {
|
|
41731
41732
|
try {
|
|
@@ -41753,8 +41754,27 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41753
41754
|
const body = m.kind === "file" ? `\u{1F4CE} sent a file: ${m.fileName} \u2014 to save it call jefri_download_file(from: "${m.senderUsername}"${m.fileName ? `, fileName: "${m.fileName}"` : ""})` : m.content;
|
|
41754
41755
|
return `${at}@${m.senderUsername}${where(m)}: ${body}`;
|
|
41755
41756
|
}));
|
|
41756
|
-
|
|
41757
|
-
` + lines.join("\n")
|
|
41757
|
+
const rendered = `\u{1F4E8} ${lines.length} message(s):
|
|
41758
|
+
` + lines.join("\n");
|
|
41759
|
+
if (ctx.stateless) {
|
|
41760
|
+
const renderedIds = msgs.map((m) => m.id);
|
|
41761
|
+
const ack = async () => {
|
|
41762
|
+
try {
|
|
41763
|
+
await fetch(`${ctx.serverUrl.replace(/\/$/, "")}/api/inbox/seen`, {
|
|
41764
|
+
method: "POST",
|
|
41765
|
+
headers: { authorization: `Bearer ${c2.token}`, "content-type": "application/json" },
|
|
41766
|
+
body: JSON.stringify({ messageIds: renderedIds })
|
|
41767
|
+
});
|
|
41768
|
+
} catch {
|
|
41769
|
+
}
|
|
41770
|
+
};
|
|
41771
|
+
if (ctx.deferUntilDelivered) ctx.deferUntilDelivered(ack);
|
|
41772
|
+
else await ack();
|
|
41773
|
+
} else {
|
|
41774
|
+
inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
|
|
41775
|
+
saveWatermark();
|
|
41776
|
+
}
|
|
41777
|
+
return ok3(rendered);
|
|
41758
41778
|
})
|
|
41759
41779
|
);
|
|
41760
41780
|
server2.registerTool(
|
|
@@ -41784,10 +41804,17 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41784
41804
|
}
|
|
41785
41805
|
},
|
|
41786
41806
|
async ({ groupId, text: text5 }, extra) => withClient(async (c2) => {
|
|
41787
|
-
|
|
41788
|
-
|
|
41789
|
-
|
|
41790
|
-
|
|
41807
|
+
if (isStateless(c2)) {
|
|
41808
|
+
try {
|
|
41809
|
+
const res = await c2.groupMessage(groupId, text5, retryKey(extra, ["group_message", groupId, text5]));
|
|
41810
|
+
if (res?.deduplicated)
|
|
41811
|
+
return ok3(`Already posted \u2014 this request matched a recent identical post and was suppressed as a retry. If you meant it as a NEW message, send it again.`);
|
|
41812
|
+
return ok3(`Posted to the group.`);
|
|
41813
|
+
} catch (e) {
|
|
41814
|
+
return fail(`Couldn't post to the group: ${e?.message ?? e}`);
|
|
41815
|
+
}
|
|
41816
|
+
}
|
|
41817
|
+
const r = await confirmWrite(c2, () => c2.groupMessage(groupId, text5));
|
|
41791
41818
|
if (r.error) return fail(`Couldn't post to the group: ${r.error}`);
|
|
41792
41819
|
return ok3(`Posted to the group.`);
|
|
41793
41820
|
})
|
|
@@ -41852,13 +41879,15 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41852
41879
|
return fail(`${name} is ${MB(rawBytes.length)} MB, over the ${Math.round(MAX_UPLOAD_BYTES / 1024 / 1024)} MB limit.`);
|
|
41853
41880
|
if (isStateless(c2)) {
|
|
41854
41881
|
try {
|
|
41855
|
-
await c2.sendFile(
|
|
41882
|
+
const res = await c2.sendFile(
|
|
41856
41883
|
{ groupId, caption },
|
|
41857
41884
|
name,
|
|
41858
41885
|
mime,
|
|
41859
41886
|
rawBytes,
|
|
41860
41887
|
retryKey(extra, ["file", groupId, name, createHash("sha256").update(rawBytes).digest("hex")])
|
|
41861
41888
|
);
|
|
41889
|
+
if (res?.deduplicated)
|
|
41890
|
+
return ok3(`Already delivered \u2014 ${name} matched a recent identical upload and was suppressed as a retry. If you meant a new copy, send it again.`);
|
|
41862
41891
|
} catch (e2) {
|
|
41863
41892
|
return fail(`Rejected: ${e2?.message ?? e2}`);
|
|
41864
41893
|
}
|
|
@@ -41950,10 +41979,20 @@ Or just upload ${fname} from the agent's page in the web app.`
|
|
|
41950
41979
|
}
|
|
41951
41980
|
},
|
|
41952
41981
|
async ({ status }, extra) => withClient(async (c2) => {
|
|
41953
|
-
|
|
41954
|
-
|
|
41982
|
+
if (isStateless(c2)) {
|
|
41983
|
+
const declId = declKey(extra, ["presence", status]);
|
|
41984
|
+
try {
|
|
41985
|
+
const res = await c2.presence(status, declId);
|
|
41986
|
+
ctx.onPresenceDeclared?.(res.status);
|
|
41987
|
+
if (res.replayed && res.status !== status)
|
|
41988
|
+
return ok3(`That request was an old retry \u2014 your status is "${res.status}" (a newer declaration stands).`);
|
|
41989
|
+
return ok3(`Status set to ${res.status}.`);
|
|
41990
|
+
} catch (e) {
|
|
41991
|
+
return fail(`Couldn't set status: ${e?.message ?? e}`);
|
|
41992
|
+
}
|
|
41993
|
+
}
|
|
41994
|
+
const r = await confirmWrite(c2, () => c2.presence(status));
|
|
41955
41995
|
if (r.error) return fail(`Couldn't set status: ${r.error}`);
|
|
41956
|
-
ctx.onPresenceDeclared?.(status);
|
|
41957
41996
|
return ok3(`Status set to ${status}.`);
|
|
41958
41997
|
})
|
|
41959
41998
|
);
|
package/package.json
CHANGED