@integrity-labs/agt-cli 0.28.550 → 0.28.552
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 +7 -4
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-VSFKVITC.js → chunk-3R4LUCPB.js} +2 -2
- package/dist/lib/manager-worker.js +12 -2
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +101 -1
- package/package.json +1 -1
- /package/dist/{chunk-VSFKVITC.js.map → chunk-3R4LUCPB.js.map} +0 -0
|
@@ -37442,6 +37442,47 @@ var SLACK_EGRESS_TOOLS = /* @__PURE__ */ new Set([
|
|
|
37442
37442
|
"slack.update"
|
|
37443
37443
|
]);
|
|
37444
37444
|
|
|
37445
|
+
// ../core/dist/channels/governance/slack-ingress-only-threads.js
|
|
37446
|
+
function buildIngressThreadKey(channel, threadTs) {
|
|
37447
|
+
if (!channel || !threadTs)
|
|
37448
|
+
return null;
|
|
37449
|
+
return `${channel}:${threadTs}`;
|
|
37450
|
+
}
|
|
37451
|
+
function createIngressOnlyThreadRegistry(maxEntries = 500) {
|
|
37452
|
+
const marked = /* @__PURE__ */ new Set();
|
|
37453
|
+
return {
|
|
37454
|
+
mark(channel, threadTs) {
|
|
37455
|
+
const key2 = buildIngressThreadKey(channel, threadTs);
|
|
37456
|
+
if (!key2)
|
|
37457
|
+
return;
|
|
37458
|
+
marked.delete(key2);
|
|
37459
|
+
marked.add(key2);
|
|
37460
|
+
while (marked.size > maxEntries) {
|
|
37461
|
+
const oldest = marked.values().next();
|
|
37462
|
+
if (oldest.done)
|
|
37463
|
+
break;
|
|
37464
|
+
marked.delete(oldest.value);
|
|
37465
|
+
}
|
|
37466
|
+
},
|
|
37467
|
+
clear(channel, threadTs) {
|
|
37468
|
+
const key2 = buildIngressThreadKey(channel, threadTs);
|
|
37469
|
+
if (!key2)
|
|
37470
|
+
return;
|
|
37471
|
+
marked.delete(key2);
|
|
37472
|
+
},
|
|
37473
|
+
isIngressOnly(channel, threadTs) {
|
|
37474
|
+
const key2 = buildIngressThreadKey(channel, threadTs);
|
|
37475
|
+
if (!key2)
|
|
37476
|
+
return false;
|
|
37477
|
+
return marked.has(key2);
|
|
37478
|
+
},
|
|
37479
|
+
size() {
|
|
37480
|
+
return marked.size;
|
|
37481
|
+
}
|
|
37482
|
+
};
|
|
37483
|
+
}
|
|
37484
|
+
var INGRESS_ONLY_REFUSAL = "This thread was opened by a third-party bot (an alert or issue card), which can wake you but is not someone you can talk to - replying would start a bot-to-bot exchange in a shared channel. Act on the content instead: work the issue, or raise it with a person in a thread they are in. If a human posts here, this thread becomes repliable.";
|
|
37485
|
+
|
|
37445
37486
|
// src/strip-repost-preamble.ts
|
|
37446
37487
|
var PRIOR_ATTEMPT_CUE = /\b(a moment ago|just now|a second ago|earlier|moments ago|previously|last (?:time|attempt)|drafted|dialled|dialed|typed|composed|wrote|sent) (?:this|that|it)?\b|\b(?:drafted|dialled|dialed|typed|composed)\b/i;
|
|
37447
37488
|
var FAILURE_CUE = /\b(?:did(?:n['’]t| not)|could(?:n['’]t| not)|would(?:n['’]t| not)|wasn['’]t|fail(?:ed)?|never)\b[^.!?\n]*?\b(?:parse[d]?|send|sent|go through|went through|land|deliver(?:ed)?|post(?:ed)?|come through|came through)\b/i;
|
|
@@ -39956,6 +39997,16 @@ function classifyPeerMessage(msg, cfg, self) {
|
|
|
39956
39997
|
}
|
|
39957
39998
|
const peer = cfg.peers.find((p2) => p2.bot_user_id === msg.user);
|
|
39958
39999
|
if (!peer) {
|
|
40000
|
+
const thirdParty = cfg.third_party_bots?.find((b) => b.bot_user_id === msg.user);
|
|
40001
|
+
if (thirdParty) {
|
|
40002
|
+
if (cfg.peer_disabled_mode === "cross_team_only") {
|
|
40003
|
+
return { kind: "drop", reason: "peer_disabled_cross_team" };
|
|
40004
|
+
}
|
|
40005
|
+
if (thirdParty.channel_ids.includes(msg.channel)) {
|
|
40006
|
+
return { kind: "bot-ingress", bot: thirdParty };
|
|
40007
|
+
}
|
|
40008
|
+
return { kind: "drop", reason: "third_party_channel_not_allowlisted" };
|
|
40009
|
+
}
|
|
39959
40010
|
return { kind: "drop", reason: "unknown_peer" };
|
|
39960
40011
|
}
|
|
39961
40012
|
if (peer.gate_path === null) {
|
|
@@ -40063,6 +40114,33 @@ function parsePeerGroupIdsEnv(raw) {
|
|
|
40063
40114
|
return [];
|
|
40064
40115
|
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
40065
40116
|
}
|
|
40117
|
+
function parseThirdPartyBotsEnv(raw) {
|
|
40118
|
+
if (!raw || !raw.trim())
|
|
40119
|
+
return [];
|
|
40120
|
+
let parsed;
|
|
40121
|
+
try {
|
|
40122
|
+
parsed = JSON.parse(raw);
|
|
40123
|
+
} catch {
|
|
40124
|
+
return [];
|
|
40125
|
+
}
|
|
40126
|
+
if (!Array.isArray(parsed))
|
|
40127
|
+
return [];
|
|
40128
|
+
const out = [];
|
|
40129
|
+
for (const item of parsed) {
|
|
40130
|
+
if (!item || typeof item !== "object")
|
|
40131
|
+
continue;
|
|
40132
|
+
const rec = item;
|
|
40133
|
+
const botUserId2 = typeof rec["bot_user_id"] === "string" ? rec["bot_user_id"].trim() : "";
|
|
40134
|
+
if (!botUserId2)
|
|
40135
|
+
continue;
|
|
40136
|
+
if (!Array.isArray(rec["channel_ids"]))
|
|
40137
|
+
continue;
|
|
40138
|
+
const channels = rec["channel_ids"].filter((c) => typeof c === "string" && c.trim() !== "").map((c) => c.trim());
|
|
40139
|
+
const label = typeof rec["label"] === "string" && rec["label"].trim() ? rec["label"].trim() : void 0;
|
|
40140
|
+
out.push({ bot_user_id: botUserId2, channel_ids: channels, ...label ? { label } : {} });
|
|
40141
|
+
}
|
|
40142
|
+
return out;
|
|
40143
|
+
}
|
|
40066
40144
|
function parsePeerAgentModeEnv(raw) {
|
|
40067
40145
|
if (raw === "listen" || raw === "respond")
|
|
40068
40146
|
return raw;
|
|
@@ -41074,8 +41152,14 @@ var SLACK_PEER_CLASSIFIER_CONFIG = {
|
|
|
41074
41152
|
peer_agent_mode: parsePeerAgentModeEnv(process.env.SLACK_PEER_AGENT_MODE),
|
|
41075
41153
|
peer_group_ids: parsePeerGroupIdsEnv(process.env.SLACK_PEER_GROUP_IDS),
|
|
41076
41154
|
peers: parsePeersEnv(process.env.SLACK_PEERS, process.env.SLACK_PEERS_GATE),
|
|
41077
|
-
peer_disabled_mode: SLACK_PEER_DISABLED_MODE
|
|
41155
|
+
peer_disabled_mode: SLACK_PEER_DISABLED_MODE,
|
|
41156
|
+
// ENG-8669: third-party bots (Linear, Amazon Q, CloudWatch, PagerDuty) that
|
|
41157
|
+
// may WAKE this agent, per channel. Absent env = empty = the pre-ENG-8669
|
|
41158
|
+
// behaviour exactly, so this ships inert for every agent that has not opted
|
|
41159
|
+
// in. Ingress-only by construction - see isReplyEligible in the classifier.
|
|
41160
|
+
third_party_bots: parseThirdPartyBotsEnv(process.env.SLACK_THIRD_PARTY_BOTS)
|
|
41078
41161
|
};
|
|
41162
|
+
var ingressOnlyThreads = createIngressOnlyThreadRegistry();
|
|
41079
41163
|
var SLACK_TEAM_PEER_USER_IDS = parseTeamPeerUserIdsEnv(
|
|
41080
41164
|
process.env.SLACK_TEAM_PEER_USER_IDS
|
|
41081
41165
|
);
|
|
@@ -43815,6 +43899,16 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
43815
43899
|
if (isImpersonating() && !channelsEnabledOverride() && SLACK_EGRESS_TOOLS.has(name)) {
|
|
43816
43900
|
return buildImpersonationRefusal(name);
|
|
43817
43901
|
}
|
|
43902
|
+
if (SLACK_EGRESS_TOOLS.has(name)) {
|
|
43903
|
+
const egressArgs = args ?? {};
|
|
43904
|
+
const targetThread = egressArgs.thread_ts ?? egressArgs.message_ts;
|
|
43905
|
+
if (ingressOnlyThreads.isIngressOnly(egressArgs.channel, targetThread)) {
|
|
43906
|
+
return {
|
|
43907
|
+
content: [{ type: "text", text: INGRESS_ONLY_REFUSAL }],
|
|
43908
|
+
isError: true
|
|
43909
|
+
};
|
|
43910
|
+
}
|
|
43911
|
+
}
|
|
43818
43912
|
if (name === "slack.reply") {
|
|
43819
43913
|
const { channel, text, thread_ts, message_ts, interim, inbound_id, proactive, to_channel_root } = args;
|
|
43820
43914
|
const bindingMode = slackReplyBindingMode();
|
|
@@ -45491,6 +45585,12 @@ async function connectSocketMode() {
|
|
|
45491
45585
|
});
|
|
45492
45586
|
const passedIdentity = access.kind !== "drop" || access.reason.startsWith("peer:");
|
|
45493
45587
|
if (passedIdentity) recordActivity("inbound");
|
|
45588
|
+
const ingressThreadTs = evt.thread_ts ?? evt.ts;
|
|
45589
|
+
if (peerClassification?.kind === "bot-ingress" && access.kind !== "drop") {
|
|
45590
|
+
ingressOnlyThreads.mark(evt.channel, ingressThreadTs);
|
|
45591
|
+
} else if (!isBot) {
|
|
45592
|
+
ingressOnlyThreads.clear(evt.channel, ingressThreadTs);
|
|
45593
|
+
}
|
|
45494
45594
|
if (access.kind === "drop") {
|
|
45495
45595
|
const channelHash = createHash3("sha256").update(evt.channel ?? "").digest("hex").slice(0, 8);
|
|
45496
45596
|
const subtypeSuffix = access.reason === "content:subtype" ? ` subtype=${evt.subtype ?? "none"}` : "";
|
package/package.json
CHANGED
|
File without changes
|