@integrity-labs/agt-cli 0.15.6 → 0.15.8
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 +19 -8
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-IGKAMH32.js → chunk-32D5TUSD.js} +8 -1
- package/dist/chunk-32D5TUSD.js.map +1 -0
- package/dist/lib/manager-worker.js +85 -21
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/index.js +9 -0
- package/mcp/slack-channel.js +11 -7
- package/mcp/telegram-channel.js +36 -5
- package/package.json +1 -1
- package/dist/chunk-IGKAMH32.js.map +0 -1
package/mcp/index.js
CHANGED
|
@@ -21040,6 +21040,12 @@ var AGT_API_KEY = process.env.AGT_API_KEY;
|
|
|
21040
21040
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID;
|
|
21041
21041
|
var AGT_AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME;
|
|
21042
21042
|
var AGT_APP_URL = (process.env.AGT_APP_URL ?? "").replace(/\/+$/, "");
|
|
21043
|
+
function readRunId() {
|
|
21044
|
+
const raw = process.env.AGT_RUN_ID ?? "";
|
|
21045
|
+
if (!raw || raw === "${AGT_RUN_ID}") return null;
|
|
21046
|
+
return raw;
|
|
21047
|
+
}
|
|
21048
|
+
var AGT_RUN_ID = readRunId();
|
|
21043
21049
|
var AGT_TOKEN = process.env.AGT_TOKEN ?? "";
|
|
21044
21050
|
if (!AGT_HOST || !AGT_AGENT_ID || !AGT_TOKEN && !AGT_API_KEY) {
|
|
21045
21051
|
console.error(
|
|
@@ -21166,6 +21172,7 @@ server.tool(
|
|
|
21166
21172
|
async (params) => {
|
|
21167
21173
|
const data = await apiPost("/host/kanban", {
|
|
21168
21174
|
agent_id: AGT_AGENT_ID,
|
|
21175
|
+
run_id: AGT_RUN_ID,
|
|
21169
21176
|
add: [
|
|
21170
21177
|
{
|
|
21171
21178
|
title: params.title,
|
|
@@ -21791,6 +21798,8 @@ server.tool(
|
|
|
21791
21798
|
async (params) => {
|
|
21792
21799
|
const data = await apiPost("/host/knowledge", {
|
|
21793
21800
|
agent_id: AGT_AGENT_ID,
|
|
21801
|
+
// ENG-4538 will land a run_id column on team_knowledge; until then
|
|
21802
|
+
// the /host/knowledge endpoint has nowhere to stamp AGT_RUN_ID.
|
|
21794
21803
|
add: [
|
|
21795
21804
|
{
|
|
21796
21805
|
title: params.title,
|
package/mcp/slack-channel.js
CHANGED
|
@@ -14156,17 +14156,21 @@ var ALLOWED_USERS = new Set(
|
|
|
14156
14156
|
);
|
|
14157
14157
|
var THREAD_AUTO_FOLLOW = process.env.SLACK_THREAD_AUTO_FOLLOW ?? "off";
|
|
14158
14158
|
var CHANNEL_RESPONSE_MODE = parseResponseMode(process.env.SLACK_CHANNEL_RESPONSE_MODE);
|
|
14159
|
-
var RESPONSE_TIMEOUT_MS =
|
|
14159
|
+
var RESPONSE_TIMEOUT_MS = 3e5;
|
|
14160
14160
|
var pendingMessages = /* @__PURE__ */ new Map();
|
|
14161
14161
|
function trackPendingMessage(channel, threadTs, messageTs) {
|
|
14162
14162
|
const key = `${channel}:${threadTs}:${messageTs}`;
|
|
14163
14163
|
const timer = setTimeout(async () => {
|
|
14164
14164
|
pendingMessages.delete(key);
|
|
14165
14165
|
try {
|
|
14166
|
-
await fetch("https://slack.com/api/
|
|
14166
|
+
await fetch("https://slack.com/api/chat.postMessage", {
|
|
14167
14167
|
method: "POST",
|
|
14168
14168
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${BOT_TOKEN}` },
|
|
14169
|
-
body: JSON.stringify({
|
|
14169
|
+
body: JSON.stringify({
|
|
14170
|
+
channel,
|
|
14171
|
+
thread_ts: threadTs,
|
|
14172
|
+
text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant."
|
|
14173
|
+
})
|
|
14170
14174
|
});
|
|
14171
14175
|
} catch {
|
|
14172
14176
|
}
|
|
@@ -14271,8 +14275,8 @@ var mcp = new Server(
|
|
|
14271
14275
|
"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 \u2014 don't conflate with earlier participants.",
|
|
14272
14276
|
"Mentioned in a channel \u2192 respond in that thread. DM \u2192 respond directly.",
|
|
14273
14277
|
'auto_followed="true" messages are from threads you previously joined: reply only if you have something useful to add. Skip if the conversation moved on, the message is directed at someone else, or your input would not add value.',
|
|
14274
|
-
|
|
14275
|
-
`When a message in a thread is not addressed to you (different @-mention, conversation between others, auto_followed catch-up): SILENTLY SKIP \u2014 no reaction, no reply, do nothing.
|
|
14278
|
+
"Reaction taxonomy (use slack.react sparingly \u2014 most messages need a reply, not a reaction): \u{1F440} = ack/working on it (already auto-added on inbound, do not duplicate); \u2705 = action completed successfully. NEVER react to signal failure \u2014 users misread emoji reactions and don't know why something failed. If an action failed, send a slack.reply with one sentence explaining what went wrong (no stack traces, no secrets) so the user understands.",
|
|
14279
|
+
`When a message in a thread is not addressed to you (different @-mention, conversation between others, auto_followed catch-up): SILENTLY SKIP \u2014 no reaction, no reply, do nothing. Do NOT post a "this wasn't for me" message and do NOT add a failure reaction; either is misleading.`,
|
|
14276
14280
|
"To deliver a file, save it under your project dir and call slack.upload_file with path, channel, thread_ts."
|
|
14277
14281
|
].join(" ")
|
|
14278
14282
|
}
|
|
@@ -14300,13 +14304,13 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
14300
14304
|
},
|
|
14301
14305
|
{
|
|
14302
14306
|
name: "slack.react",
|
|
14303
|
-
description:
|
|
14307
|
+
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 \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.",
|
|
14304
14308
|
inputSchema: {
|
|
14305
14309
|
type: "object",
|
|
14306
14310
|
properties: {
|
|
14307
14311
|
channel: { type: "string", description: "Slack channel ID" },
|
|
14308
14312
|
timestamp: { type: "string", description: "Message timestamp to react to" },
|
|
14309
|
-
emoji: { type: "string", description: 'Emoji name without colons (e.g. "white_check_mark"
|
|
14313
|
+
emoji: { type: "string", description: 'Emoji name without colons (e.g. "white_check_mark"). Do NOT use "x" or any other failure emoji \u2014 send a slack.reply explaining the failure instead.' }
|
|
14310
14314
|
},
|
|
14311
14315
|
required: ["channel", "timestamp", "emoji"]
|
|
14312
14316
|
}
|
package/mcp/telegram-channel.js
CHANGED
|
@@ -14150,8 +14150,7 @@ function telegramApiCall(method, body, timeoutMs) {
|
|
|
14150
14150
|
});
|
|
14151
14151
|
}
|
|
14152
14152
|
var ACK_EMOJI = "\u{1F440}";
|
|
14153
|
-
var
|
|
14154
|
-
var RESPONSE_TIMEOUT_MS = 12e4;
|
|
14153
|
+
var RESPONSE_TIMEOUT_MS = 3e5;
|
|
14155
14154
|
async function setMessageReaction(chatId, messageId, emoji2) {
|
|
14156
14155
|
try {
|
|
14157
14156
|
const resp = await telegramApiCall(
|
|
@@ -14183,7 +14182,29 @@ function trackPendingMessage(chatId, messageId, chatType) {
|
|
|
14183
14182
|
if (existing) clearTimeout(existing.timer);
|
|
14184
14183
|
const timer = setTimeout(() => {
|
|
14185
14184
|
pendingMessages.delete(key);
|
|
14186
|
-
void setMessageReaction(chatId, messageId,
|
|
14185
|
+
void setMessageReaction(chatId, messageId, null);
|
|
14186
|
+
void telegramApiCall(
|
|
14187
|
+
"sendMessage",
|
|
14188
|
+
{
|
|
14189
|
+
chat_id: chatId,
|
|
14190
|
+
text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant.",
|
|
14191
|
+
reply_to_message_id: Number(messageId),
|
|
14192
|
+
allow_sending_without_reply: true
|
|
14193
|
+
},
|
|
14194
|
+
1e4
|
|
14195
|
+
).then((resp) => {
|
|
14196
|
+
if (!resp.ok) {
|
|
14197
|
+
process.stderr.write(
|
|
14198
|
+
`telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage failed for chat ${redactId(chatId)} message ${redactId(messageId)}: ${resp.description ?? "unknown"}
|
|
14199
|
+
`
|
|
14200
|
+
);
|
|
14201
|
+
}
|
|
14202
|
+
}).catch((err) => {
|
|
14203
|
+
process.stderr.write(
|
|
14204
|
+
`telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage error for chat ${redactId(chatId)} message ${redactId(messageId)}: ${err.message}
|
|
14205
|
+
`
|
|
14206
|
+
);
|
|
14207
|
+
});
|
|
14187
14208
|
process.stderr.write(
|
|
14188
14209
|
`telegram-channel(${AGENT_CODE_NAME}): response timeout for message ${redactId(messageId)} in chat ${redactId(chatId)}
|
|
14189
14210
|
`
|
|
@@ -14203,11 +14224,21 @@ function clearPendingMessage(chatId, messageId) {
|
|
|
14203
14224
|
return;
|
|
14204
14225
|
}
|
|
14205
14226
|
const prefix = `${chatId}:`;
|
|
14227
|
+
let clearedPrivate = false;
|
|
14206
14228
|
for (const [key, entry] of pendingMessages) {
|
|
14207
14229
|
if (!key.startsWith(prefix)) continue;
|
|
14208
14230
|
if (entry.chatType !== "private") continue;
|
|
14209
14231
|
clearTimeout(entry.timer);
|
|
14210
14232
|
pendingMessages.delete(key);
|
|
14233
|
+
clearedPrivate = true;
|
|
14234
|
+
}
|
|
14235
|
+
if (clearedPrivate) return;
|
|
14236
|
+
for (const [key, entry] of pendingMessages) {
|
|
14237
|
+
if (!key.startsWith(prefix)) continue;
|
|
14238
|
+
if (entry.chatType === "private") continue;
|
|
14239
|
+
clearTimeout(entry.timer);
|
|
14240
|
+
pendingMessages.delete(key);
|
|
14241
|
+
return;
|
|
14211
14242
|
}
|
|
14212
14243
|
}
|
|
14213
14244
|
var mcp = new Server(
|
|
@@ -14227,7 +14258,7 @@ var mcp = new Server(
|
|
|
14227
14258
|
'For work >30s follow CLAUDE.md kanban flow: kanban.add, reply with "On it \u2014 tracking here: <kanban URL>", move to in_progress, do the work, reply with the result. Simple lookups skip kanban but still reply.',
|
|
14228
14259
|
"Address users by user_name; user is the numeric Telegram ID. Reply-to a specific message with reply_to_message_id, otherwise omit.",
|
|
14229
14260
|
"Resolve ambiguous times against your own Timezone from CLAUDE.md \u2014 do not ask the user.",
|
|
14230
|
-
|
|
14261
|
+
"Reaction taxonomy (use telegram.react sparingly \u2014 prefer a text reply via telegram.reply): \u{1F440} = ack/working on it (already auto-added on inbound, do not duplicate); \u{1F44D} or \u{1F389} = action completed successfully. NEVER react to signal failure \u2014 users misread emoji reactions and don't know why something failed. If an action failed, send a telegram.reply with one sentence explaining what went wrong (no stack traces, no secrets) so the user understands. Free-tier emoji set: \u{1F44D} \u{1F44E} \u2764 \u{1F525} \u{1F389} \u{1F914} \u{1F92F} \u{1F64F} \u{1F44C} \u{1F440} \u{1F4AF} \u270D \u{1FAE1} \u{1F192} \u{1F973} \u{1F494} (premium-only fail silently)."
|
|
14231
14262
|
].join(" ")
|
|
14232
14263
|
}
|
|
14233
14264
|
);
|
|
@@ -14287,7 +14318,7 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
14287
14318
|
},
|
|
14288
14319
|
{
|
|
14289
14320
|
name: "telegram.react",
|
|
14290
|
-
description:
|
|
14321
|
+
description: "Add an emoji reaction to a Telegram message. Use sparingly \u2014 prefer a text reply via telegram.reply. Reaction taxonomy: \u{1F44D} or \u{1F389} = action completed successfully. NEVER react to signal failure \u2014 users can't tell why it failed from a reaction. On failure, call telegram.reply with one sentence explaining what went wrong instead. \u{1F440} is already auto-applied on inbound; do not duplicate. Only free-tier emoji reactions are available to bots (Premium-only emoji fail silently). Pass an empty string or omit emoji to clear the bot's reaction on that message.",
|
|
14291
14322
|
inputSchema: {
|
|
14292
14323
|
type: "object",
|
|
14293
14324
|
properties: {
|