@integrity-labs/agt-cli 0.28.324 → 0.28.326
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-KHSPRKK2.js → chunk-3PT6JAFU.js} +2 -2
- package/dist/lib/manager-worker.js +20 -8
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +35 -0
- package/dist/mcp/slack-channel.js +67 -9
- package/dist/mcp/teams-channel.js +7 -1
- package/dist/mcp/telegram-channel.js +39 -1
- package/package.json +1 -1
- /package/dist/{chunk-KHSPRKK2.js.map → chunk-3PT6JAFU.js.map} +0 -0
|
@@ -14693,6 +14693,7 @@ function createKanbanCardActiveClient(args) {
|
|
|
14693
14693
|
const agentId = args.agentId;
|
|
14694
14694
|
const apiKey = args.agtApiKey;
|
|
14695
14695
|
const cache = /* @__PURE__ */ new Map();
|
|
14696
|
+
const threadCache = /* @__PURE__ */ new Map();
|
|
14696
14697
|
let cachedToken = null;
|
|
14697
14698
|
let cachedTokenExpiresAt = 0;
|
|
14698
14699
|
async function getToken() {
|
|
@@ -14737,6 +14738,26 @@ function createKanbanCardActiveClient(args) {
|
|
|
14737
14738
|
const data = await resp.json();
|
|
14738
14739
|
return data.active === true;
|
|
14739
14740
|
}
|
|
14741
|
+
async function queryThreadOnce(sourceIntegration, channel) {
|
|
14742
|
+
const token = await getToken();
|
|
14743
|
+
const qs = new URLSearchParams({ agent_id: agentId, source_integration: sourceIntegration, channel });
|
|
14744
|
+
return fetchImpl(`${base}/host/kanban/active-source-thread?${qs.toString()}`, {
|
|
14745
|
+
method: "GET",
|
|
14746
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
14747
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
|
|
14748
|
+
});
|
|
14749
|
+
}
|
|
14750
|
+
async function queryThread(sourceIntegration, channel) {
|
|
14751
|
+
let resp = await queryThreadOnce(sourceIntegration, channel);
|
|
14752
|
+
if (resp.status === 401) {
|
|
14753
|
+
cachedToken = null;
|
|
14754
|
+
cachedTokenExpiresAt = 0;
|
|
14755
|
+
resp = await queryThreadOnce(sourceIntegration, channel);
|
|
14756
|
+
}
|
|
14757
|
+
if (!resp.ok) return void 0;
|
|
14758
|
+
const data = await resp.json();
|
|
14759
|
+
return data.thread_ts ?? void 0;
|
|
14760
|
+
}
|
|
14740
14761
|
return {
|
|
14741
14762
|
async isCardActive(sourceIntegration, sourceExternalId) {
|
|
14742
14763
|
const key = `${sourceIntegration}:${sourceExternalId}`;
|
|
@@ -14751,6 +14772,20 @@ function createKanbanCardActiveClient(args) {
|
|
|
14751
14772
|
log(`kanban-card-active: query threw key=${key}: ${err.message}`);
|
|
14752
14773
|
return false;
|
|
14753
14774
|
}
|
|
14775
|
+
},
|
|
14776
|
+
async getActiveCardSourceThread(sourceIntegration, channel) {
|
|
14777
|
+
const key = `thread:${sourceIntegration}:${channel}`;
|
|
14778
|
+
const t = now();
|
|
14779
|
+
const hit = threadCache.get(key);
|
|
14780
|
+
if (hit && t < hit.expiresAt) return hit.threadTs;
|
|
14781
|
+
try {
|
|
14782
|
+
const threadTs = await queryThread(sourceIntegration, channel);
|
|
14783
|
+
threadCache.set(key, { threadTs, expiresAt: t + (threadTs ? positiveTtlMs : negativeTtlMs) });
|
|
14784
|
+
return threadTs;
|
|
14785
|
+
} catch (err) {
|
|
14786
|
+
log(`kanban-card-active: thread query threw key=${key}: ${err.message}`);
|
|
14787
|
+
return void 0;
|
|
14788
|
+
}
|
|
14754
14789
|
}
|
|
14755
14790
|
};
|
|
14756
14791
|
}
|
|
@@ -14549,6 +14549,11 @@ function decideModeForward(evt, policy) {
|
|
|
14549
14549
|
const label = extractAugmentedSlackLabel(evt);
|
|
14550
14550
|
if (!label)
|
|
14551
14551
|
return { forward: false, reason: "sender_policy" };
|
|
14552
|
+
if (policy.registeredAgentSlackUserIds !== void 0) {
|
|
14553
|
+
if (typeof evt.user !== "string" || !policy.registeredAgentSlackUserIds.has(evt.user)) {
|
|
14554
|
+
return { forward: false, reason: "sender_policy" };
|
|
14555
|
+
}
|
|
14556
|
+
}
|
|
14552
14557
|
if (policy.mode === "team_agents_only" || policy.mode === "manager_only" || policy.mode === "team_only") {
|
|
14553
14558
|
if (!policy.teamId || label.teamId !== policy.teamId) {
|
|
14554
14559
|
return { forward: false, reason: "sender_policy" };
|
|
@@ -16279,6 +16284,7 @@ function createKanbanCardActiveClient(args) {
|
|
|
16279
16284
|
const agentId = args.agentId;
|
|
16280
16285
|
const apiKey = args.agtApiKey;
|
|
16281
16286
|
const cache = /* @__PURE__ */ new Map();
|
|
16287
|
+
const threadCache = /* @__PURE__ */ new Map();
|
|
16282
16288
|
let cachedToken = null;
|
|
16283
16289
|
let cachedTokenExpiresAt = 0;
|
|
16284
16290
|
async function getToken() {
|
|
@@ -16323,6 +16329,26 @@ function createKanbanCardActiveClient(args) {
|
|
|
16323
16329
|
const data = await resp.json();
|
|
16324
16330
|
return data.active === true;
|
|
16325
16331
|
}
|
|
16332
|
+
async function queryThreadOnce(sourceIntegration, channel) {
|
|
16333
|
+
const token = await getToken();
|
|
16334
|
+
const qs = new URLSearchParams({ agent_id: agentId, source_integration: sourceIntegration, channel });
|
|
16335
|
+
return fetchImpl(`${base}/host/kanban/active-source-thread?${qs.toString()}`, {
|
|
16336
|
+
method: "GET",
|
|
16337
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
16338
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
16339
|
+
});
|
|
16340
|
+
}
|
|
16341
|
+
async function queryThread(sourceIntegration, channel) {
|
|
16342
|
+
let resp = await queryThreadOnce(sourceIntegration, channel);
|
|
16343
|
+
if (resp.status === 401) {
|
|
16344
|
+
cachedToken = null;
|
|
16345
|
+
cachedTokenExpiresAt = 0;
|
|
16346
|
+
resp = await queryThreadOnce(sourceIntegration, channel);
|
|
16347
|
+
}
|
|
16348
|
+
if (!resp.ok) return void 0;
|
|
16349
|
+
const data = await resp.json();
|
|
16350
|
+
return data.thread_ts ?? void 0;
|
|
16351
|
+
}
|
|
16326
16352
|
return {
|
|
16327
16353
|
async isCardActive(sourceIntegration, sourceExternalId) {
|
|
16328
16354
|
const key2 = `${sourceIntegration}:${sourceExternalId}`;
|
|
@@ -16337,6 +16363,20 @@ function createKanbanCardActiveClient(args) {
|
|
|
16337
16363
|
log(`kanban-card-active: query threw key=${key2}: ${err.message}`);
|
|
16338
16364
|
return false;
|
|
16339
16365
|
}
|
|
16366
|
+
},
|
|
16367
|
+
async getActiveCardSourceThread(sourceIntegration, channel) {
|
|
16368
|
+
const key2 = `thread:${sourceIntegration}:${channel}`;
|
|
16369
|
+
const t = now();
|
|
16370
|
+
const hit = threadCache.get(key2);
|
|
16371
|
+
if (hit && t < hit.expiresAt) return hit.threadTs;
|
|
16372
|
+
try {
|
|
16373
|
+
const threadTs = await queryThread(sourceIntegration, channel);
|
|
16374
|
+
threadCache.set(key2, { threadTs, expiresAt: t + (threadTs ? positiveTtlMs : negativeTtlMs) });
|
|
16375
|
+
return threadTs;
|
|
16376
|
+
} catch (err) {
|
|
16377
|
+
log(`kanban-card-active: thread query threw key=${key2}: ${err.message}`);
|
|
16378
|
+
return void 0;
|
|
16379
|
+
}
|
|
16340
16380
|
}
|
|
16341
16381
|
};
|
|
16342
16382
|
}
|
|
@@ -16344,7 +16384,9 @@ function createKanbanCardActiveClient(args) {
|
|
|
16344
16384
|
// src/slack-reply-threading.ts
|
|
16345
16385
|
function resolveReplyThreadTs(input) {
|
|
16346
16386
|
if (input.threadTs) return input.threadTs;
|
|
16347
|
-
|
|
16387
|
+
if (input.messageTs) return input.messageTs;
|
|
16388
|
+
if (input.threadTs === null) return void 0;
|
|
16389
|
+
return input.activeCardThreadTs || void 0;
|
|
16348
16390
|
}
|
|
16349
16391
|
|
|
16350
16392
|
// src/restart-confirm.ts
|
|
@@ -17726,7 +17768,8 @@ function parsePeersEnv(raw, gateRaw) {
|
|
|
17726
17768
|
return [];
|
|
17727
17769
|
const gateMap = /* @__PURE__ */ new Map();
|
|
17728
17770
|
let gateConfigInvalid = false;
|
|
17729
|
-
|
|
17771
|
+
const gatePresent = !!(gateRaw && gateRaw.trim().length > 0);
|
|
17772
|
+
if (gatePresent) {
|
|
17730
17773
|
try {
|
|
17731
17774
|
const gateParsed = JSON.parse(gateRaw);
|
|
17732
17775
|
if (!gateParsed || typeof gateParsed !== "object" || Array.isArray(gateParsed)) {
|
|
@@ -17769,6 +17812,8 @@ function parsePeersEnv(raw, gateRaw) {
|
|
|
17769
17812
|
peer.gate_path = null;
|
|
17770
17813
|
} else if (gateMap.has(e.bot_user_id)) {
|
|
17771
17814
|
peer.gate_path = gateMap.get(e.bot_user_id) ?? null;
|
|
17815
|
+
} else if (gatePresent) {
|
|
17816
|
+
peer.gate_path = null;
|
|
17772
17817
|
}
|
|
17773
17818
|
out.push(peer);
|
|
17774
17819
|
}
|
|
@@ -18343,13 +18388,21 @@ var SLACK_SENDER_POLICY = (() => {
|
|
|
18343
18388
|
);
|
|
18344
18389
|
}
|
|
18345
18390
|
const internalOnlyFields = internalOnly ? { internalOnly: true, homeTeamId } : {};
|
|
18346
|
-
|
|
18347
|
-
|
|
18391
|
+
const slackPeersRaw = process.env.SLACK_PEERS;
|
|
18392
|
+
const registryFields = slackPeersRaw && slackPeersRaw.trim().length > 0 ? {
|
|
18393
|
+
registeredAgentSlackUserIds: new Set(
|
|
18394
|
+
parsePeersEnv(slackPeersRaw, process.env.SLACK_PEERS_GATE).map(
|
|
18395
|
+
(p) => p.bot_user_id
|
|
18396
|
+
)
|
|
18397
|
+
)
|
|
18398
|
+
} : {};
|
|
18399
|
+
if (raw === "all") return { mode: "all", ...internalOnlyFields, ...registryFields };
|
|
18400
|
+
if (raw === "agents_only") return { mode: "agents_only", ...internalOnlyFields, ...registryFields };
|
|
18348
18401
|
if (raw === "team_agents_only") {
|
|
18349
18402
|
if (!AGT_TEAM_ID) {
|
|
18350
18403
|
throw new Error("SLACK_SENDER_POLICY=team_agents_only requires AGT_TEAM_ID");
|
|
18351
18404
|
}
|
|
18352
|
-
return { mode: "team_agents_only", teamId: AGT_TEAM_ID, ...internalOnlyFields };
|
|
18405
|
+
return { mode: "team_agents_only", teamId: AGT_TEAM_ID, ...internalOnlyFields, ...registryFields };
|
|
18353
18406
|
}
|
|
18354
18407
|
if (raw === "team_only") {
|
|
18355
18408
|
if (!AGT_TEAM_ID) {
|
|
@@ -18361,7 +18414,8 @@ var SLACK_SENDER_POLICY = (() => {
|
|
|
18361
18414
|
mode: "team_only",
|
|
18362
18415
|
teamId: AGT_TEAM_ID,
|
|
18363
18416
|
teamPrincipalSlackUserIds,
|
|
18364
|
-
...internalOnlyFields
|
|
18417
|
+
...internalOnlyFields,
|
|
18418
|
+
...registryFields
|
|
18365
18419
|
};
|
|
18366
18420
|
}
|
|
18367
18421
|
if (raw === "manager_only") {
|
|
@@ -18374,7 +18428,7 @@ var SLACK_SENDER_POLICY = (() => {
|
|
|
18374
18428
|
"SLACK_SENDER_POLICY=manager_only requires SLACK_SENDER_POLICY_PRINCIPAL_ID. Set agent.reports_to_person with a slack_user_id in contact_preferences and re-run /host/refresh."
|
|
18375
18429
|
);
|
|
18376
18430
|
}
|
|
18377
|
-
return { mode: "manager_only", teamId: AGT_TEAM_ID, principalSlackUserId, ...internalOnlyFields };
|
|
18431
|
+
return { mode: "manager_only", teamId: AGT_TEAM_ID, principalSlackUserId, ...internalOnlyFields, ...registryFields };
|
|
18378
18432
|
}
|
|
18379
18433
|
throw new Error(`Invalid SLACK_SENDER_POLICY=${JSON.stringify(process.env.SLACK_SENDER_POLICY)}`);
|
|
18380
18434
|
})();
|
|
@@ -21145,10 +21199,12 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
21145
21199
|
};
|
|
21146
21200
|
}
|
|
21147
21201
|
const bindingFeedback = bindingMode === "warn" ? binding.agentFeedback : void 0;
|
|
21202
|
+
const activeCardThreadTs = !scheduledDest && !enforceBound && !channelGuard.corrected && !thread_ts && !message_ts && kanbanCardActiveClient && typeof channel === "string" && channel ? await kanbanCardActiveClient.getActiveCardSourceThread("slack", channel) : void 0;
|
|
21148
21203
|
const effectiveThreadTs = scheduledDest ? scheduledDest.thread_ts : enforceBound ? binding.threadTs : channelGuard.corrected ? channelGuard.threadTs : resolveReplyThreadTs({
|
|
21149
21204
|
channel,
|
|
21150
21205
|
threadTs: thread_ts,
|
|
21151
|
-
messageTs: message_ts
|
|
21206
|
+
messageTs: message_ts,
|
|
21207
|
+
activeCardThreadTs
|
|
21152
21208
|
});
|
|
21153
21209
|
if (effectiveChannel) {
|
|
21154
21210
|
recordReplyTargetClassification(
|
|
@@ -21826,10 +21882,12 @@ async function handleSendStructured(args) {
|
|
|
21826
21882
|
if (typeof text !== "string" || !text) {
|
|
21827
21883
|
return errResult("text is required (used as fallback for push notifications and unfurls)");
|
|
21828
21884
|
}
|
|
21885
|
+
const activeCardThreadTs = !thread_ts && !message_ts && kanbanCardActiveClient ? await kanbanCardActiveClient.getActiveCardSourceThread("slack", channel) : void 0;
|
|
21829
21886
|
const effectiveThreadTs = resolveReplyThreadTs({
|
|
21830
21887
|
channel,
|
|
21831
21888
|
threadTs: thread_ts,
|
|
21832
|
-
messageTs: message_ts
|
|
21889
|
+
messageTs: message_ts,
|
|
21890
|
+
activeCardThreadTs
|
|
21833
21891
|
});
|
|
21834
21892
|
recordReplyTargetClassification(
|
|
21835
21893
|
SLACK_AGENT_DIR,
|
|
@@ -14796,7 +14796,13 @@ function decideTeamsActivityForward(input) {
|
|
|
14796
14796
|
}
|
|
14797
14797
|
if (allowedTeamIds.size > 0) {
|
|
14798
14798
|
const teamId = activity.channelData?.team?.id;
|
|
14799
|
-
|
|
14799
|
+
const convType = activity.conversation?.conversationType;
|
|
14800
|
+
const isDirect = convType === "personal" || convType === "groupChat";
|
|
14801
|
+
if (isDirect) {
|
|
14802
|
+
if (teamId && !allowedTeamIds.has(teamId)) {
|
|
14803
|
+
return { forward: false, reason: "team_not_allowed" };
|
|
14804
|
+
}
|
|
14805
|
+
} else if (!teamId || !allowedTeamIds.has(teamId)) {
|
|
14800
14806
|
return { forward: false, reason: "team_not_allowed" };
|
|
14801
14807
|
}
|
|
14802
14808
|
}
|
|
@@ -14922,7 +14922,8 @@ function parsePeersEnv(raw, gateRaw) {
|
|
|
14922
14922
|
return [];
|
|
14923
14923
|
const gateMap = /* @__PURE__ */ new Map();
|
|
14924
14924
|
let gateConfigInvalid = false;
|
|
14925
|
-
|
|
14925
|
+
const gatePresent = !!(gateRaw && gateRaw.trim().length > 0);
|
|
14926
|
+
if (gatePresent) {
|
|
14926
14927
|
try {
|
|
14927
14928
|
const gateParsed = JSON.parse(gateRaw);
|
|
14928
14929
|
if (!gateParsed || typeof gateParsed !== "object" || Array.isArray(gateParsed)) {
|
|
@@ -14963,6 +14964,8 @@ function parsePeersEnv(raw, gateRaw) {
|
|
|
14963
14964
|
const key2 = String(e.bot_id);
|
|
14964
14965
|
if (gateMap.has(key2)) {
|
|
14965
14966
|
peer.gate_path = gateMap.get(key2) ?? null;
|
|
14967
|
+
} else if (gatePresent) {
|
|
14968
|
+
peer.gate_path = null;
|
|
14966
14969
|
}
|
|
14967
14970
|
}
|
|
14968
14971
|
out.push(peer);
|
|
@@ -17106,6 +17109,7 @@ function createKanbanCardActiveClient(args) {
|
|
|
17106
17109
|
const agentId = args.agentId;
|
|
17107
17110
|
const apiKey = args.agtApiKey;
|
|
17108
17111
|
const cache = /* @__PURE__ */ new Map();
|
|
17112
|
+
const threadCache = /* @__PURE__ */ new Map();
|
|
17109
17113
|
let cachedToken = null;
|
|
17110
17114
|
let cachedTokenExpiresAt = 0;
|
|
17111
17115
|
async function getToken() {
|
|
@@ -17150,6 +17154,26 @@ function createKanbanCardActiveClient(args) {
|
|
|
17150
17154
|
const data = await resp.json();
|
|
17151
17155
|
return data.active === true;
|
|
17152
17156
|
}
|
|
17157
|
+
async function queryThreadOnce(sourceIntegration, channel) {
|
|
17158
|
+
const token = await getToken();
|
|
17159
|
+
const qs = new URLSearchParams({ agent_id: agentId, source_integration: sourceIntegration, channel });
|
|
17160
|
+
return fetchImpl(`${base}/host/kanban/active-source-thread?${qs.toString()}`, {
|
|
17161
|
+
method: "GET",
|
|
17162
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
17163
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS6)
|
|
17164
|
+
});
|
|
17165
|
+
}
|
|
17166
|
+
async function queryThread(sourceIntegration, channel) {
|
|
17167
|
+
let resp = await queryThreadOnce(sourceIntegration, channel);
|
|
17168
|
+
if (resp.status === 401) {
|
|
17169
|
+
cachedToken = null;
|
|
17170
|
+
cachedTokenExpiresAt = 0;
|
|
17171
|
+
resp = await queryThreadOnce(sourceIntegration, channel);
|
|
17172
|
+
}
|
|
17173
|
+
if (!resp.ok) return void 0;
|
|
17174
|
+
const data = await resp.json();
|
|
17175
|
+
return data.thread_ts ?? void 0;
|
|
17176
|
+
}
|
|
17153
17177
|
return {
|
|
17154
17178
|
async isCardActive(sourceIntegration, sourceExternalId) {
|
|
17155
17179
|
const key2 = `${sourceIntegration}:${sourceExternalId}`;
|
|
@@ -17164,6 +17188,20 @@ function createKanbanCardActiveClient(args) {
|
|
|
17164
17188
|
log(`kanban-card-active: query threw key=${key2}: ${err.message}`);
|
|
17165
17189
|
return false;
|
|
17166
17190
|
}
|
|
17191
|
+
},
|
|
17192
|
+
async getActiveCardSourceThread(sourceIntegration, channel) {
|
|
17193
|
+
const key2 = `thread:${sourceIntegration}:${channel}`;
|
|
17194
|
+
const t = now();
|
|
17195
|
+
const hit = threadCache.get(key2);
|
|
17196
|
+
if (hit && t < hit.expiresAt) return hit.threadTs;
|
|
17197
|
+
try {
|
|
17198
|
+
const threadTs = await queryThread(sourceIntegration, channel);
|
|
17199
|
+
threadCache.set(key2, { threadTs, expiresAt: t + (threadTs ? positiveTtlMs : negativeTtlMs) });
|
|
17200
|
+
return threadTs;
|
|
17201
|
+
} catch (err) {
|
|
17202
|
+
log(`kanban-card-active: thread query threw key=${key2}: ${err.message}`);
|
|
17203
|
+
return void 0;
|
|
17204
|
+
}
|
|
17167
17205
|
}
|
|
17168
17206
|
};
|
|
17169
17207
|
}
|
package/package.json
CHANGED
|
File without changes
|