@integrity-labs/agt-cli 0.27.79 → 0.27.81
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/bin/agt.js +3 -3
- package/dist/{chunk-QYUQLNI3.js → chunk-CGUXKOUF.js} +1 -1
- package/dist/lib/manager-worker.js +74 -2
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +51 -6
- package/dist/mcp/telegram-channel.js +11 -6
- package/package.json +1 -1
- /package/dist/{chunk-QYUQLNI3.js.map → chunk-CGUXKOUF.js.map} +0 -0
|
@@ -14345,6 +14345,15 @@ function decideAckReaction(i) {
|
|
|
14345
14345
|
function decideRecoveryHeal(i) {
|
|
14346
14346
|
return i.wasUndeliverable && i.hasTarget ? "heal" : "none";
|
|
14347
14347
|
}
|
|
14348
|
+
var SLACK_UNDELIVERABLE_REACTION = "hourglass_flowing_sand";
|
|
14349
|
+
var SLACK_UNDELIVERABLE_REACTION_LEGACY = "x";
|
|
14350
|
+
var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
14351
|
+
function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
|
|
14352
|
+
return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
|
|
14353
|
+
}
|
|
14354
|
+
function undeliverableNoticeText() {
|
|
14355
|
+
return "\u23F3 I can't get to this right now \u2014 I'll follow up as soon as I'm back, but if it's urgent please resend in a few minutes.";
|
|
14356
|
+
}
|
|
14348
14357
|
function oldestPendingMarkerAgeMs(dir, now = Date.now()) {
|
|
14349
14358
|
if (!dir) return null;
|
|
14350
14359
|
let names;
|
|
@@ -15859,12 +15868,16 @@ function healSlackUndeliverable(channel, messageTs) {
|
|
|
15859
15868
|
"Content-Type": "application/json",
|
|
15860
15869
|
Authorization: `Bearer ${BOT_TOKEN}`
|
|
15861
15870
|
};
|
|
15862
|
-
fetch("https://slack.com/api/reactions.remove", {
|
|
15871
|
+
const remove = (name) => fetch("https://slack.com/api/reactions.remove", {
|
|
15863
15872
|
method: "POST",
|
|
15864
15873
|
headers,
|
|
15865
|
-
body: JSON.stringify({ channel, timestamp: messageTs, name
|
|
15874
|
+
body: JSON.stringify({ channel, timestamp: messageTs, name })
|
|
15866
15875
|
}).catch(() => {
|
|
15867
|
-
})
|
|
15876
|
+
});
|
|
15877
|
+
void Promise.allSettled([
|
|
15878
|
+
remove(SLACK_UNDELIVERABLE_REACTION),
|
|
15879
|
+
remove(SLACK_UNDELIVERABLE_REACTION_LEGACY)
|
|
15880
|
+
]).finally(() => {
|
|
15868
15881
|
fetch("https://slack.com/api/reactions.add", {
|
|
15869
15882
|
method: "POST",
|
|
15870
15883
|
headers,
|
|
@@ -15873,6 +15886,32 @@ function healSlackUndeliverable(channel, messageTs) {
|
|
|
15873
15886
|
});
|
|
15874
15887
|
});
|
|
15875
15888
|
}
|
|
15889
|
+
var lastSlackUndeliverableNoticeAt = /* @__PURE__ */ new Map();
|
|
15890
|
+
function postUndeliverableNotice(channel, threadTs, isThreadReply) {
|
|
15891
|
+
if (!BOT_TOKEN || !channel) return;
|
|
15892
|
+
const now = Date.now();
|
|
15893
|
+
const conversationKey = isThreadReply && threadTs ? `${channel}:${threadTs}` : channel;
|
|
15894
|
+
if (!shouldPostUndeliverableNotice(lastSlackUndeliverableNoticeAt.get(conversationKey), now)) {
|
|
15895
|
+
return;
|
|
15896
|
+
}
|
|
15897
|
+
lastSlackUndeliverableNoticeAt.set(conversationKey, now);
|
|
15898
|
+
fetch("https://slack.com/api/chat.postMessage", {
|
|
15899
|
+
method: "POST",
|
|
15900
|
+
headers: {
|
|
15901
|
+
"Content-Type": "application/json",
|
|
15902
|
+
Authorization: `Bearer ${BOT_TOKEN}`
|
|
15903
|
+
},
|
|
15904
|
+
body: JSON.stringify({
|
|
15905
|
+
channel,
|
|
15906
|
+
text: undeliverableNoticeText(),
|
|
15907
|
+
...threadTs ? { thread_ts: threadTs } : {}
|
|
15908
|
+
})
|
|
15909
|
+
}).catch(() => {
|
|
15910
|
+
});
|
|
15911
|
+
}
|
|
15912
|
+
function __resetSlackUndeliverableNoticeThrottle() {
|
|
15913
|
+
lastSlackUndeliverableNoticeAt.clear();
|
|
15914
|
+
}
|
|
15876
15915
|
function clearSlackMarkerFileWithHeal(fullPath) {
|
|
15877
15916
|
let marker = null;
|
|
15878
15917
|
try {
|
|
@@ -16725,7 +16764,7 @@ var mcp = new Server(
|
|
|
16725
16764
|
"Inbound attachments: <channel> `files` is a JSON-serialised array \u2014 JSON.parse it. If an entry has `path`, the image is already downloaded \u2014 Read it directly, do NOT call slack.download_attachment. Use that tool only for entries with `file_id` but NO `path` (PDF, docx, csv): pass file_id + channel verbatim, then Read the returned path. Single-image messages also get a top-level `image_path`. Don't surface internal file-handling errors that don't affect the answer.",
|
|
16726
16765
|
"Address users by user_name, never by raw user ID. In multi-participant threads the CURRENT speaker is the one on the latest <channel> tag.",
|
|
16727
16766
|
'Mentioned in a channel \u2192 respond in that thread. DM \u2192 respond directly. auto_followed="true" \u2192 only reply if useful, OR if your own bot user is @-mentioned (counts even in auto_followed).',
|
|
16728
|
-
"Reaction taxonomy (use slack.react sparingly \u2014 prefer a reply): \u{1F440} = ack (already auto-added on inbound, do not duplicate); \u2705 = success. NEVER react to signal failure of YOUR work \u2014 users can't tell why something failed from an emoji. On failure, slack.reply with one sentence explaining what went wrong (no stack traces, no secrets). (The \
|
|
16767
|
+
"Reaction taxonomy (use slack.react sparingly \u2014 prefer a reply): \u{1F440} = ack (already auto-added on inbound, do not duplicate); \u2705 = success. NEVER react to signal failure of YOUR work \u2014 users can't tell why something failed from an emoji. On failure, slack.reply with one sentence explaining what went wrong (no stack traces, no secrets). (The \u23F3 you may see on an inbound is applied by the system, not you \u2014 it marks a message that arrived while the agent couldn't reply; never add \u23F3 or \u274C yourself.)",
|
|
16729
16768
|
`When a thread message is NOT addressed to you (different @-mention, side conversation, auto_followed catch-up): SILENTLY SKIP \u2014 no reaction, no reply, no "this wasn't for me" message.`,
|
|
16730
16769
|
"To deliver a file: save under your project dir, call slack.upload_file with path + channel + thread_ts."
|
|
16731
16770
|
].join(" ")
|
|
@@ -16765,7 +16804,7 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
16765
16804
|
},
|
|
16766
16805
|
{
|
|
16767
16806
|
name: "slack.react",
|
|
16768
|
-
description: "Add an emoji reaction to a Slack message. Use sparingly \u2014 prefer a text reply. Reaction taxonomy: \u2705 = action completed successfully. NEVER react to signal failure of your work \u2014 users can't tell why it failed from a reaction. On failure, call slack.reply with one sentence explaining what went wrong instead. \u{1F440} (eyes) is already auto-applied on inbound; do not duplicate. \
|
|
16807
|
+
description: "Add an emoji reaction to a Slack message. Use sparingly \u2014 prefer a text reply. Reaction taxonomy: \u2705 = action completed successfully. NEVER react to signal failure of your work \u2014 users can't tell why it failed from a reaction. On failure, call slack.reply with one sentence explaining what went wrong instead. \u{1F440} (eyes) is already auto-applied on inbound; do not duplicate. \u23F3 (:hourglass_flowing_sand:) is reserved for the system to mark an inbound that arrived while the agent couldn't reply \u2014 never add \u23F3 or \u274C yourself.",
|
|
16769
16808
|
inputSchema: {
|
|
16770
16809
|
type: "object",
|
|
16771
16810
|
properties: {
|
|
@@ -18281,7 +18320,7 @@ async function connectSocketMode() {
|
|
|
18281
18320
|
paneLogFreshAgeMs
|
|
18282
18321
|
});
|
|
18283
18322
|
if (ackDecision !== "none") {
|
|
18284
|
-
const reactionName = ackDecision === "undeliverable" ?
|
|
18323
|
+
const reactionName = ackDecision === "undeliverable" ? SLACK_UNDELIVERABLE_REACTION : "eyes";
|
|
18285
18324
|
fetch("https://slack.com/api/reactions.add", {
|
|
18286
18325
|
method: "POST",
|
|
18287
18326
|
headers: {
|
|
@@ -18291,6 +18330,9 @@ async function connectSocketMode() {
|
|
|
18291
18330
|
body: JSON.stringify({ channel, timestamp: ts, name: reactionName })
|
|
18292
18331
|
}).catch(() => {
|
|
18293
18332
|
});
|
|
18333
|
+
if (ackDecision === "undeliverable" && channel && shouldEngage) {
|
|
18334
|
+
postUndeliverableNotice(channel, threadTs, isThreadReply);
|
|
18335
|
+
}
|
|
18294
18336
|
}
|
|
18295
18337
|
if (channel && ts && shouldEngage) {
|
|
18296
18338
|
trackPendingMessage(channel, threadTs, ts, ackDecision === "undeliverable");
|
|
@@ -18460,3 +18502,6 @@ if (THREAD_STORE_PATH) {
|
|
|
18460
18502
|
);
|
|
18461
18503
|
}
|
|
18462
18504
|
connectSocketModeSafely();
|
|
18505
|
+
export {
|
|
18506
|
+
__resetSlackUndeliverableNoticeThrottle
|
|
18507
|
+
};
|
|
@@ -15526,6 +15526,13 @@ function decideAckReaction(i) {
|
|
|
15526
15526
|
function decideRecoveryHeal(i) {
|
|
15527
15527
|
return i.wasUndeliverable && i.hasTarget ? "heal" : "none";
|
|
15528
15528
|
}
|
|
15529
|
+
var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
15530
|
+
function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
|
|
15531
|
+
return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
|
|
15532
|
+
}
|
|
15533
|
+
function undeliverableNoticeText() {
|
|
15534
|
+
return "\u23F3 I can't get to this right now \u2014 I'll follow up as soon as I'm back, but if it's urgent please resend in a few minutes.";
|
|
15535
|
+
}
|
|
15529
15536
|
function oldestPendingMarkerAgeMs(dir, now = Date.now()) {
|
|
15530
15537
|
if (!dir) return null;
|
|
15531
15538
|
let names;
|
|
@@ -15806,20 +15813,19 @@ async function setMessageReaction(chatId, messageId, emoji2) {
|
|
|
15806
15813
|
);
|
|
15807
15814
|
}
|
|
15808
15815
|
}
|
|
15809
|
-
var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
|
|
15810
15816
|
var lastUndeliverableNoticeAt = /* @__PURE__ */ new Map();
|
|
15811
15817
|
async function notifyUndeliverable(chatId, messageId) {
|
|
15812
15818
|
const key2 = String(chatId);
|
|
15813
15819
|
const now = Date.now();
|
|
15814
|
-
|
|
15815
|
-
if (last != null && now - last < UNDELIVERABLE_NOTICE_THROTTLE_MS) return;
|
|
15820
|
+
if (!shouldPostUndeliverableNotice(lastUndeliverableNoticeAt.get(key2), now)) return;
|
|
15816
15821
|
lastUndeliverableNoticeAt.set(key2, now);
|
|
15817
15822
|
try {
|
|
15818
15823
|
const resp = await telegramApiCall(
|
|
15819
15824
|
"sendMessage",
|
|
15820
15825
|
{
|
|
15821
15826
|
chat_id: chatId,
|
|
15822
|
-
|
|
15827
|
+
// ENG-6025: shared copy with the Slack undeliverable notice.
|
|
15828
|
+
text: undeliverableNoticeText(),
|
|
15823
15829
|
reply_to_message_id: Number(messageId),
|
|
15824
15830
|
allow_sending_without_reply: true
|
|
15825
15831
|
},
|
|
@@ -15845,8 +15851,7 @@ var lastBackOnlineNoticeAt = /* @__PURE__ */ new Map();
|
|
|
15845
15851
|
function notifyBackOnline(chatId) {
|
|
15846
15852
|
const key2 = String(chatId);
|
|
15847
15853
|
const now = Date.now();
|
|
15848
|
-
|
|
15849
|
-
if (last != null && now - last < UNDELIVERABLE_NOTICE_THROTTLE_MS) return;
|
|
15854
|
+
if (!shouldPostUndeliverableNotice(lastBackOnlineNoticeAt.get(key2), now)) return;
|
|
15850
15855
|
lastBackOnlineNoticeAt.set(key2, now);
|
|
15851
15856
|
void (async () => {
|
|
15852
15857
|
try {
|
package/package.json
CHANGED
|
File without changes
|