@integrity-labs/agt-cli 0.28.6 → 0.28.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 +4 -4
- package/dist/{chunk-NS4G4HHD.js → chunk-CHUL4CPY.js} +11 -1
- package/dist/{chunk-NS4G4HHD.js.map → chunk-CHUL4CPY.js.map} +1 -1
- package/dist/{chunk-BEHCN5RZ.js → chunk-CJSEB2LS.js} +2 -2
- package/dist/{chunk-LIB6VTH3.js → chunk-QG553V7F.js} +2 -2
- package/dist/{claude-pair-runtime-OACH27NE.js → claude-pair-runtime-KOXXDT6B.js} +2 -2
- package/dist/lib/manager-worker.js +153 -138
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +230 -5
- package/dist/{persistent-session-DSG4HI4R.js → persistent-session-S6H3P6WD.js} +3 -3
- package/dist/{responsiveness-probe-53KDTOUT.js → responsiveness-probe-6BLLBJB4.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-BEHCN5RZ.js.map → chunk-CJSEB2LS.js.map} +0 -0
- /package/dist/{chunk-LIB6VTH3.js.map → chunk-QG553V7F.js.map} +0 -0
- /package/dist/{claude-pair-runtime-OACH27NE.js.map → claude-pair-runtime-KOXXDT6B.js.map} +0 -0
- /package/dist/{persistent-session-DSG4HI4R.js.map → persistent-session-S6H3P6WD.js.map} +0 -0
- /package/dist/{responsiveness-probe-53KDTOUT.js.map → responsiveness-probe-6BLLBJB4.js.map} +0 -0
|
@@ -13971,9 +13971,49 @@ function buildImpersonationRefusal(toolName) {
|
|
|
13971
13971
|
// src/channel-egress-tools.ts
|
|
13972
13972
|
var DIRECT_CHAT_EGRESS_TOOLS = /* @__PURE__ */ new Set([
|
|
13973
13973
|
"direct_chat.reply",
|
|
13974
|
+
"direct_chat.consume",
|
|
13974
13975
|
"channel_request_input"
|
|
13975
13976
|
]);
|
|
13976
13977
|
|
|
13978
|
+
// src/direct-chat-claim-tracker.ts
|
|
13979
|
+
var DirectChatClaimTracker = class {
|
|
13980
|
+
bySession = /* @__PURE__ */ new Map();
|
|
13981
|
+
/** Record that `messageId` was claimed for `sessionId` (idempotent). */
|
|
13982
|
+
track(sessionId, messageId) {
|
|
13983
|
+
let set = this.bySession.get(sessionId);
|
|
13984
|
+
if (!set) {
|
|
13985
|
+
set = /* @__PURE__ */ new Set();
|
|
13986
|
+
this.bySession.set(sessionId, set);
|
|
13987
|
+
}
|
|
13988
|
+
set.add(messageId);
|
|
13989
|
+
}
|
|
13990
|
+
/**
|
|
13991
|
+
* The claimed-but-unconsumed message ids for a session, WITHOUT clearing them.
|
|
13992
|
+
* Peek-then-clear-on-success (rather than drain-up-front) so a failed
|
|
13993
|
+
* reply/consume POST doesn't lose the ids — they stay tracked for the retry.
|
|
13994
|
+
*/
|
|
13995
|
+
peek(sessionId) {
|
|
13996
|
+
return [...this.bySession.get(sessionId) ?? []];
|
|
13997
|
+
}
|
|
13998
|
+
/**
|
|
13999
|
+
* Clear exactly the given ids for a session (call after a successful
|
|
14000
|
+
* reply/consume). Only the ids actually sent are cleared, so any message
|
|
14001
|
+
* claimed between peek and clear stays tracked for the next turn.
|
|
14002
|
+
*/
|
|
14003
|
+
clear(sessionId, ids) {
|
|
14004
|
+
const set = this.bySession.get(sessionId);
|
|
14005
|
+
if (!set) return;
|
|
14006
|
+
for (const id of ids) set.delete(id);
|
|
14007
|
+
if (set.size === 0) this.bySession.delete(sessionId);
|
|
14008
|
+
}
|
|
14009
|
+
/** Total tracked message ids across all sessions (for bounding / diagnostics). */
|
|
14010
|
+
get size() {
|
|
14011
|
+
let n = 0;
|
|
14012
|
+
for (const set of this.bySession.values()) n += set.size;
|
|
14013
|
+
return n;
|
|
14014
|
+
}
|
|
14015
|
+
};
|
|
14016
|
+
|
|
13977
14017
|
// src/mcp-spawn-lock.ts
|
|
13978
14018
|
import {
|
|
13979
14019
|
existsSync,
|
|
@@ -14044,12 +14084,52 @@ function readLockHolder(path) {
|
|
|
14044
14084
|
}
|
|
14045
14085
|
|
|
14046
14086
|
// src/direct-chat-channel.ts
|
|
14087
|
+
import { homedir as homedir2 } from "os";
|
|
14088
|
+
import { join as join3 } from "path";
|
|
14089
|
+
import { watch, mkdirSync as mkdirSync2 } from "fs";
|
|
14090
|
+
|
|
14091
|
+
// src/flags-cache-read.ts
|
|
14092
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
14047
14093
|
import { homedir } from "os";
|
|
14048
14094
|
import { join as join2 } from "path";
|
|
14095
|
+
function defaultFlagsCachePath() {
|
|
14096
|
+
return join2(homedir(), ".augmented", "flags-cache.json");
|
|
14097
|
+
}
|
|
14098
|
+
function envBoolean(raw) {
|
|
14099
|
+
if (raw === void 0) return void 0;
|
|
14100
|
+
const v = raw.trim().toLowerCase();
|
|
14101
|
+
if (v === "") return void 0;
|
|
14102
|
+
if (v === "1" || v === "true" || v === "yes" || v === "on") return true;
|
|
14103
|
+
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
14104
|
+
return void 0;
|
|
14105
|
+
}
|
|
14106
|
+
function cachedBoolean(key, path) {
|
|
14107
|
+
try {
|
|
14108
|
+
if (!existsSync2(path)) return void 0;
|
|
14109
|
+
const parsed = JSON.parse(readFileSync2(path, "utf8"));
|
|
14110
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
14111
|
+
const flags = parsed.flags;
|
|
14112
|
+
if (!flags || typeof flags !== "object") return void 0;
|
|
14113
|
+
const value = flags[key];
|
|
14114
|
+
return typeof value === "boolean" ? value : void 0;
|
|
14115
|
+
} catch {
|
|
14116
|
+
return void 0;
|
|
14117
|
+
}
|
|
14118
|
+
}
|
|
14119
|
+
function resolveHostBooleanFlag(opts) {
|
|
14120
|
+
const env = opts.env ?? process.env;
|
|
14121
|
+
const envValue = envBoolean(env[opts.envVar]);
|
|
14122
|
+
if (envValue !== void 0) return envValue;
|
|
14123
|
+
const cached2 = cachedBoolean(opts.key, opts.cachePath ?? defaultFlagsCachePath());
|
|
14124
|
+
if (cached2 !== void 0) return cached2;
|
|
14125
|
+
return opts.defaultValue;
|
|
14126
|
+
}
|
|
14127
|
+
|
|
14128
|
+
// src/direct-chat-channel.ts
|
|
14049
14129
|
var AGT_HOST = process.env.AGT_HOST;
|
|
14050
14130
|
var AGT_API_KEY = process.env.AGT_API_KEY;
|
|
14051
14131
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID;
|
|
14052
|
-
var DIRECT_CHAT_AGENT_DIR = AGT_AGENT_ID ?
|
|
14132
|
+
var DIRECT_CHAT_AGENT_DIR = AGT_AGENT_ID ? join3(homedir2(), ".augmented", AGT_AGENT_ID) : null;
|
|
14053
14133
|
var inboundContextClient = createInboundContextClient({
|
|
14054
14134
|
agtHost: AGT_HOST ?? null,
|
|
14055
14135
|
agtApiKey: AGT_API_KEY ?? null,
|
|
@@ -14125,10 +14205,12 @@ var mcp = new Server(
|
|
|
14125
14205
|
'Messages from the webapp Direct Chat arrive as <channel source="direct-chat" session_id="..." user="...">.',
|
|
14126
14206
|
"Reply using the direct_chat.reply tool, passing the session_id from the tag.",
|
|
14127
14207
|
"Always reply to every direct chat message \u2014 the user is waiting in the webapp.",
|
|
14208
|
+
"In the rare case you deliberately handle a message without replying (e.g. an internal command), call direct_chat.consume with the session_id so it is not treated as undelivered and redelivered.",
|
|
14128
14209
|
"Keep replies concise and helpful. You have full access to all your MCP tools."
|
|
14129
14210
|
].join(" ")
|
|
14130
14211
|
}
|
|
14131
14212
|
);
|
|
14213
|
+
var claimTracker = new DirectChatClaimTracker();
|
|
14132
14214
|
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
14133
14215
|
tools: [
|
|
14134
14216
|
{
|
|
@@ -14185,6 +14267,20 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
14185
14267
|
},
|
|
14186
14268
|
required: ["session_id", "content"]
|
|
14187
14269
|
}
|
|
14270
|
+
},
|
|
14271
|
+
{
|
|
14272
|
+
name: "direct_chat.consume",
|
|
14273
|
+
description: "Acknowledge direct-chat message(s) you handled WITHOUT sending a reply (e.g. a command that only updated state, or a message you deliberately ignored). Pass the session_id from the <channel> tag. If you send a direct_chat.reply you do NOT also need to consume \u2014 the reply already acknowledges the message. Without one of the two, a silently-handled message is treated as undelivered and may be redelivered.",
|
|
14274
|
+
inputSchema: {
|
|
14275
|
+
type: "object",
|
|
14276
|
+
properties: {
|
|
14277
|
+
session_id: {
|
|
14278
|
+
type: "string",
|
|
14279
|
+
description: "Session ID (from the session_id attribute in the <channel> tag)"
|
|
14280
|
+
}
|
|
14281
|
+
},
|
|
14282
|
+
required: ["session_id"]
|
|
14283
|
+
}
|
|
14188
14284
|
}
|
|
14189
14285
|
]
|
|
14190
14286
|
}));
|
|
@@ -14206,11 +14302,13 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
14206
14302
|
}
|
|
14207
14303
|
if (name === "direct_chat.reply") {
|
|
14208
14304
|
const { session_id, content } = args;
|
|
14305
|
+
const message_ids = claimTracker.peek(session_id);
|
|
14209
14306
|
try {
|
|
14210
14307
|
const res = await apiPost("/host/direct-chat/reply", {
|
|
14211
14308
|
agent_id: AGT_AGENT_ID,
|
|
14212
14309
|
session_id,
|
|
14213
|
-
content
|
|
14310
|
+
content,
|
|
14311
|
+
message_ids
|
|
14214
14312
|
});
|
|
14215
14313
|
const data = await res.json();
|
|
14216
14314
|
if (!res.ok || data.error) {
|
|
@@ -14219,6 +14317,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
14219
14317
|
isError: true
|
|
14220
14318
|
};
|
|
14221
14319
|
}
|
|
14320
|
+
claimTracker.clear(session_id, message_ids);
|
|
14222
14321
|
return { content: [{ type: "text", text: "sent" }] };
|
|
14223
14322
|
} catch (err) {
|
|
14224
14323
|
return {
|
|
@@ -14227,9 +14326,80 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
14227
14326
|
};
|
|
14228
14327
|
}
|
|
14229
14328
|
}
|
|
14329
|
+
if (name === "direct_chat.consume") {
|
|
14330
|
+
const { session_id } = args;
|
|
14331
|
+
const message_ids = claimTracker.peek(session_id);
|
|
14332
|
+
if (message_ids.length === 0) {
|
|
14333
|
+
return { content: [{ type: "text", text: "nothing to consume" }] };
|
|
14334
|
+
}
|
|
14335
|
+
try {
|
|
14336
|
+
const res = await apiPost("/host/direct-chat/consume", {
|
|
14337
|
+
agent_id: AGT_AGENT_ID,
|
|
14338
|
+
session_id,
|
|
14339
|
+
message_ids
|
|
14340
|
+
});
|
|
14341
|
+
const data = await res.json();
|
|
14342
|
+
if (!res.ok || data.error) {
|
|
14343
|
+
return {
|
|
14344
|
+
content: [{ type: "text", text: `Consume failed: ${data.error ?? res.statusText}` }],
|
|
14345
|
+
isError: true
|
|
14346
|
+
};
|
|
14347
|
+
}
|
|
14348
|
+
claimTracker.clear(session_id, message_ids);
|
|
14349
|
+
return { content: [{ type: "text", text: "consumed" }] };
|
|
14350
|
+
} catch (err) {
|
|
14351
|
+
return {
|
|
14352
|
+
content: [{ type: "text", text: `Failed: ${err.message}` }],
|
|
14353
|
+
isError: true
|
|
14354
|
+
};
|
|
14355
|
+
}
|
|
14356
|
+
}
|
|
14230
14357
|
throw new Error(`Unknown tool: ${name}`);
|
|
14231
14358
|
});
|
|
14232
14359
|
await mcp.connect(new StdioServerTransport());
|
|
14360
|
+
var processedIds = /* @__PURE__ */ new Set();
|
|
14361
|
+
async function pollForMessages() {
|
|
14362
|
+
try {
|
|
14363
|
+
const res = await apiPost("/host/direct-chat/poll", {
|
|
14364
|
+
agent_id: AGT_AGENT_ID
|
|
14365
|
+
});
|
|
14366
|
+
if (!res.ok) return;
|
|
14367
|
+
const data = await res.json();
|
|
14368
|
+
for (const msg of data.messages ?? []) {
|
|
14369
|
+
if (processedIds.has(msg.id)) continue;
|
|
14370
|
+
processedIds.add(msg.id);
|
|
14371
|
+
if (processedIds.size > 500) {
|
|
14372
|
+
const ids = [...processedIds];
|
|
14373
|
+
for (let i = 0; i < 250; i++) processedIds.delete(ids[i]);
|
|
14374
|
+
}
|
|
14375
|
+
claimTracker.track(msg.session_id, msg.id);
|
|
14376
|
+
await mcp.notification({
|
|
14377
|
+
method: "notifications/claude/channel",
|
|
14378
|
+
params: {
|
|
14379
|
+
content: msg.content,
|
|
14380
|
+
meta: {
|
|
14381
|
+
session_id: msg.session_id,
|
|
14382
|
+
user: "webapp",
|
|
14383
|
+
source: "direct-chat"
|
|
14384
|
+
}
|
|
14385
|
+
}
|
|
14386
|
+
});
|
|
14387
|
+
inboundContextClient?.recordInbound({
|
|
14388
|
+
sourceIntegration: "direct-chat",
|
|
14389
|
+
sourceExternalId: msg.session_id
|
|
14390
|
+
});
|
|
14391
|
+
process.stderr.write(
|
|
14392
|
+
`direct-chat-channel: Injected message ${msg.id} (session=${msg.session_id})
|
|
14393
|
+
`
|
|
14394
|
+
);
|
|
14395
|
+
}
|
|
14396
|
+
} catch (err) {
|
|
14397
|
+
process.stderr.write(
|
|
14398
|
+
`direct-chat-channel: Poll error: ${err.message}
|
|
14399
|
+
`
|
|
14400
|
+
);
|
|
14401
|
+
}
|
|
14402
|
+
}
|
|
14233
14403
|
var acquiredLockPath = null;
|
|
14234
14404
|
{
|
|
14235
14405
|
const lockResult = acquireMcpSpawnLock({
|
|
@@ -14246,16 +14416,71 @@ var acquiredLockPath = null;
|
|
|
14246
14416
|
acquiredLockPath = lockResult.path;
|
|
14247
14417
|
}
|
|
14248
14418
|
}
|
|
14249
|
-
|
|
14250
|
-
|
|
14419
|
+
var DOORBELL_ENABLED = resolveHostBooleanFlag({
|
|
14420
|
+
key: "direct-chat-doorbell",
|
|
14421
|
+
envVar: "AGT_DIRECT_CHAT_DOORBELL_ENABLED",
|
|
14422
|
+
defaultValue: false
|
|
14423
|
+
});
|
|
14424
|
+
var DOORBELL_FILE = "direct-chat-doorbell";
|
|
14425
|
+
var SAFETY_NET_POLL_MS = 3e4;
|
|
14426
|
+
var pollInFlight = false;
|
|
14427
|
+
async function pollOnce() {
|
|
14428
|
+
if (pollInFlight) return;
|
|
14429
|
+
pollInFlight = true;
|
|
14430
|
+
try {
|
|
14431
|
+
await pollForMessages();
|
|
14432
|
+
} finally {
|
|
14433
|
+
pollInFlight = false;
|
|
14434
|
+
}
|
|
14435
|
+
}
|
|
14436
|
+
var doorbellWatcher = null;
|
|
14437
|
+
var safetyNetTimer = null;
|
|
14438
|
+
if (DOORBELL_ENABLED && DIRECT_CHAT_AGENT_DIR) {
|
|
14439
|
+
try {
|
|
14440
|
+
mkdirSync2(DIRECT_CHAT_AGENT_DIR, { recursive: true });
|
|
14441
|
+
} catch {
|
|
14442
|
+
}
|
|
14443
|
+
let debounce = null;
|
|
14444
|
+
try {
|
|
14445
|
+
doorbellWatcher = watch(DIRECT_CHAT_AGENT_DIR, (_event, filename) => {
|
|
14446
|
+
if (filename !== DOORBELL_FILE) return;
|
|
14447
|
+
if (debounce) clearTimeout(debounce);
|
|
14448
|
+
debounce = setTimeout(() => {
|
|
14449
|
+
void pollOnce();
|
|
14450
|
+
}, 50);
|
|
14451
|
+
});
|
|
14452
|
+
} catch (err) {
|
|
14453
|
+
process.stderr.write(
|
|
14454
|
+
`direct-chat-channel: doorbell watch failed (${err.message}) \u2014 relying on safety-net poll
|
|
14251
14455
|
`
|
|
14252
|
-
);
|
|
14456
|
+
);
|
|
14457
|
+
}
|
|
14458
|
+
safetyNetTimer = setInterval(() => {
|
|
14459
|
+
void pollOnce();
|
|
14460
|
+
}, SAFETY_NET_POLL_MS);
|
|
14461
|
+
safetyNetTimer.unref?.();
|
|
14462
|
+
void pollOnce();
|
|
14463
|
+
process.stderr.write(
|
|
14464
|
+
`direct-chat-channel: Started (agent=${AGT_AGENT_ID}, delivery=doorbell+pull \u2014 watching ${DOORBELL_FILE}, safety-net ${SAFETY_NET_POLL_MS}ms)
|
|
14465
|
+
`
|
|
14466
|
+
);
|
|
14467
|
+
} else {
|
|
14468
|
+
process.stderr.write(
|
|
14469
|
+
`direct-chat-channel: Started (agent=${AGT_AGENT_ID}, polling=disabled \u2014 using Realtime)
|
|
14470
|
+
`
|
|
14471
|
+
);
|
|
14472
|
+
}
|
|
14253
14473
|
var isShuttingDown = false;
|
|
14254
14474
|
function shutdown(reason) {
|
|
14255
14475
|
if (isShuttingDown) return;
|
|
14256
14476
|
isShuttingDown = true;
|
|
14257
14477
|
process.stderr.write(`direct-chat-channel: ${reason} \u2014 exiting
|
|
14258
14478
|
`);
|
|
14479
|
+
try {
|
|
14480
|
+
doorbellWatcher?.close();
|
|
14481
|
+
} catch {
|
|
14482
|
+
}
|
|
14483
|
+
if (safetyNetTimer) clearInterval(safetyNetTimer);
|
|
14259
14484
|
try {
|
|
14260
14485
|
releaseMcpSpawnLock(acquiredLockPath);
|
|
14261
14486
|
} catch {
|
|
@@ -23,8 +23,8 @@ import {
|
|
|
23
23
|
stopPersistentSession,
|
|
24
24
|
takeZombieDetection,
|
|
25
25
|
writePersistentClaudeWrapper
|
|
26
|
-
} from "./chunk-
|
|
27
|
-
import "./chunk-
|
|
26
|
+
} from "./chunk-QG553V7F.js";
|
|
27
|
+
import "./chunk-CHUL4CPY.js";
|
|
28
28
|
import "./chunk-XWVM4KPK.js";
|
|
29
29
|
export {
|
|
30
30
|
SEND_KEYS_ENTER_DELAY_MS,
|
|
@@ -52,4 +52,4 @@ export {
|
|
|
52
52
|
takeZombieDetection,
|
|
53
53
|
writePersistentClaudeWrapper
|
|
54
54
|
};
|
|
55
|
-
//# sourceMappingURL=persistent-session-
|
|
55
|
+
//# sourceMappingURL=persistent-session-S6H3P6WD.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-QG553V7F.js";
|
|
4
|
+
import "./chunk-CHUL4CPY.js";
|
|
5
5
|
import "./chunk-XWVM4KPK.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/responsiveness-probe.ts
|
|
@@ -248,4 +248,4 @@ export {
|
|
|
248
248
|
parkPendingInbound,
|
|
249
249
|
readAndResetChannelDeflections
|
|
250
250
|
};
|
|
251
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
251
|
+
//# sourceMappingURL=responsiveness-probe-6BLLBJB4.js.map
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|