@integrity-labs/agt-cli 0.28.763 → 0.28.765
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 +5 -5
- package/dist/{chunk-L4KDOGHB.js → chunk-23KTLVYX.js} +15 -1
- package/dist/{chunk-L4KDOGHB.js.map → chunk-23KTLVYX.js.map} +1 -1
- package/dist/{chunk-HVOHM3PB.js → chunk-EWH4J63B.js} +86 -28
- package/dist/chunk-EWH4J63B.js.map +1 -0
- package/dist/{chunk-EU6RSU5V.js → chunk-LVBINNTQ.js} +157 -40
- package/dist/chunk-LVBINNTQ.js.map +1 -0
- package/dist/{claude-pair-runtime-5CKIB2IM.js → claude-pair-runtime-U6WDTNK3.js} +2 -2
- package/dist/lib/manager-worker.js +57 -62
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +14 -0
- package/dist/mcp/index.js +14 -0
- package/dist/mcp/origami.js +14 -0
- package/dist/mcp/slack-channel.js +14 -0
- package/dist/mcp/telegram-channel.js +14 -0
- package/dist/{persistent-session-VS44QKVB.js → persistent-session-3OBDKYWF.js} +3 -3
- package/dist/{responsiveness-probe-CNSUJALX.js → responsiveness-probe-ULIAXSCT.js} +3 -3
- package/dist/{session-auth-dead-3AK3MDNT.js → session-auth-dead-67XFJWMA.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-EU6RSU5V.js.map +0 -1
- package/dist/chunk-HVOHM3PB.js.map +0 -1
- /package/dist/{claude-pair-runtime-5CKIB2IM.js.map → claude-pair-runtime-U6WDTNK3.js.map} +0 -0
- /package/dist/{persistent-session-VS44QKVB.js.map → persistent-session-3OBDKYWF.js.map} +0 -0
- /package/dist/{responsiveness-probe-CNSUJALX.js.map → responsiveness-probe-ULIAXSCT.js.map} +0 -0
- /package/dist/{session-auth-dead-3AK3MDNT.js.map → session-auth-dead-67XFJWMA.js.map} +0 -0
|
@@ -7,13 +7,14 @@ import {
|
|
|
7
7
|
buildRemoteMcpEntry,
|
|
8
8
|
expandTemplateVars,
|
|
9
9
|
getProjectDir,
|
|
10
|
+
hardBoundedExecFile,
|
|
10
11
|
isolationMode,
|
|
11
12
|
log,
|
|
12
13
|
mergeEnvIntegrationsContent,
|
|
13
14
|
parseEnvFileEntries,
|
|
14
15
|
parseEnvIntegrations,
|
|
15
16
|
shellQuote
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-LVBINNTQ.js";
|
|
17
18
|
import {
|
|
18
19
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
19
20
|
INTEGRATIONS_SECTION_END,
|
|
@@ -63,7 +64,7 @@ import {
|
|
|
63
64
|
sessionTranscriptDir,
|
|
64
65
|
worseConnectivityOutcome,
|
|
65
66
|
wrapScheduledTaskPrompt
|
|
66
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-23KTLVYX.js";
|
|
67
68
|
import {
|
|
68
69
|
parsePsRows
|
|
69
70
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -2551,9 +2552,24 @@ function provisionStopHook(codeName) {
|
|
|
2551
2552
|
"# obligation (consume is the explicit handled-without-reply ack, the same",
|
|
2552
2553
|
"# session-scoped drain the MCP applies), so either counts as answered. session_id",
|
|
2553
2554
|
"# is unambiguous (one session per marker), so there is no cross-thread class here.",
|
|
2555
|
+
"#",
|
|
2556
|
+
"# ENG-9420: this predicate was the one of four that ENG-8142 missed. It came",
|
|
2557
|
+
"# from ENG-7808 and had been error-blind ever since, so a direct_chat.reply",
|
|
2558
|
+
'# whose tool_result came back is_error:true still satisfied "the agent',
|
|
2559
|
+
'# replied" - the recovery outbox never written, the owed-reply re-prompt',
|
|
2560
|
+
"# suppressed. Direct chat is where scheduled-task results and approval",
|
|
2561
|
+
"# round-trips land, so that is a user asking a question and getting nothing.",
|
|
2562
|
+
"#",
|
|
2563
|
+
"# A FAILED consume is treated the same as a failed reply, deliberately.",
|
|
2564
|
+
'# consume means "handled without replying" and drains the marker; if the',
|
|
2565
|
+
"# drain failed, the marker was not drained and the conversation is not",
|
|
2566
|
+
"# settled. Counting it would suppress the re-prompt for a message that is",
|
|
2567
|
+
"# still genuinely pending. The failure direction of this choice is an extra",
|
|
2568
|
+
"# re-prompt, which the user sees and can ignore; the other direction is a",
|
|
2569
|
+
"# silently dropped message, which nobody sees at all.",
|
|
2554
2570
|
"replied_this_conv_directchat() {",
|
|
2555
2571
|
' local session_id="$1" hit',
|
|
2556
|
-
` hit=$(printf '%s' "$LAST_ASSISTANT" | jq -r --arg sid "$session_id" '(.message.content // .content // []) | (if type=="array" then . else [] end) | (if any(.[]; (type=="object") and (.type=="tool_use") and ((.name|tostring)|test("(^|__)direct_chat[._](reply|consume)$")) and (((.input.session_id // "")|tostring)==$sid)) then "yes" else "no" end)' 2>/dev/null || echo no)`,
|
|
2572
|
+
` hit=$(printf '%s' "$LAST_ASSISTANT" | jq -r --arg sid "$session_id" --arg errids "$ERRORED_TOOL_IDS" '(($errids // "") | split("\\n") | map(select(length > 0))) as $bad | (.message.content // .content // []) | (if type=="array" then . else [] end) | (if any(.[]; (type=="object") and (.type=="tool_use") and ((.name|tostring)|test("(^|__)direct_chat[._](reply|consume)$")) and ((.id // "") as $tid | ($bad | index($tid)) == null) and (((.input.session_id // "")|tostring)==$sid)) then "yes" else "no" end)' 2>/dev/null || echo no)`,
|
|
2557
2573
|
' [ "$hit" = "yes" ]',
|
|
2558
2574
|
"}",
|
|
2559
2575
|
"recover_telegram_for() {",
|
|
@@ -6436,7 +6452,7 @@ function exchangeFailureKind(err) {
|
|
|
6436
6452
|
}
|
|
6437
6453
|
|
|
6438
6454
|
// src/lib/api-client.ts
|
|
6439
|
-
var agtCliVersion = true ? "0.28.
|
|
6455
|
+
var agtCliVersion = true ? "0.28.765" : "dev";
|
|
6440
6456
|
var lastConfigHash = null;
|
|
6441
6457
|
function setConfigHash(hash) {
|
|
6442
6458
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -7043,6 +7059,12 @@ var HostFlagStore = class {
|
|
|
7043
7059
|
|
|
7044
7060
|
// src/lib/stale-mcp-reaper.ts
|
|
7045
7061
|
import { execFileSync } from "child_process";
|
|
7062
|
+
function livenessFromProbe(r, onNoAnswer) {
|
|
7063
|
+
if (r.kind === "ok") return true;
|
|
7064
|
+
if (r.kind === "failed" && r.status !== null) return false;
|
|
7065
|
+
onNoAnswer?.(r.kind === "timed-out" ? "did not answer within its bound" : `could not run: ${r.message}`);
|
|
7066
|
+
return true;
|
|
7067
|
+
}
|
|
7046
7068
|
var rotationTimestamps = /* @__PURE__ */ new Map();
|
|
7047
7069
|
var DEFAULT_ROTATION_GRACE_MS = 15e3;
|
|
7048
7070
|
function rotationKey(codeName, serverKey) {
|
|
@@ -7256,19 +7278,30 @@ function findMcpChildrenForAgent(args) {
|
|
|
7256
7278
|
function reapStaleMcpChildren(args) {
|
|
7257
7279
|
const { log: log2, codeName, serverKeys, mcpJson, graceMs = 5e3, isolated = false } = args;
|
|
7258
7280
|
if (serverKeys.length === 0) return [];
|
|
7259
|
-
const runPs = args.runPs ?? (isolated ? (
|
|
7260
|
-
|
|
7261
|
-
timeout
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7281
|
+
const runPs = args.runPs ?? (isolated ? (
|
|
7282
|
+
// ENG-9781: hard-bounded. See bounded-exec.ts — `execFileSync`'s own
|
|
7283
|
+
// `timeout` is not a bound, and this runs per isolated agent per cycle
|
|
7284
|
+
// on the manager-worker's critical path. Throws on a non-answer so the
|
|
7285
|
+
// caller's existing catch skips the agent rather than acting on an
|
|
7286
|
+
// empty process list.
|
|
7287
|
+
() => {
|
|
7288
|
+
const r = hardBoundedExecFile(
|
|
7266
7289
|
"docker",
|
|
7267
|
-
["exec", `agt-${codeName}`, "
|
|
7268
|
-
{
|
|
7290
|
+
["exec", `agt-${codeName}`, "ps", "-eo", "pid,ppid,args"],
|
|
7291
|
+
{ timeoutMs: 8e3, log: log2 }
|
|
7292
|
+
);
|
|
7293
|
+
if (r.kind === "ok") return r.stdout;
|
|
7294
|
+
throw new Error(
|
|
7295
|
+
r.kind === "timed-out" ? `docker exec ps did not answer within its bound (bounded=${r.bounded})` : `docker exec ps failed (status=${r.status}): ${r.message}`
|
|
7269
7296
|
);
|
|
7270
|
-
} catch {
|
|
7271
7297
|
}
|
|
7298
|
+
) : () => execFileSync("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 }));
|
|
7299
|
+
const killProcess = args.killProcess ?? (isolated ? (pid, signal) => {
|
|
7300
|
+
hardBoundedExecFile(
|
|
7301
|
+
"docker",
|
|
7302
|
+
["exec", `agt-${codeName}`, "kill", signal === "SIGKILL" ? "-KILL" : "-TERM", String(pid)],
|
|
7303
|
+
{ timeoutMs: 8e3, log: log2 }
|
|
7304
|
+
);
|
|
7272
7305
|
} : (pid, signal) => {
|
|
7273
7306
|
try {
|
|
7274
7307
|
process.kill(pid, signal);
|
|
@@ -7276,15 +7309,17 @@ function reapStaleMcpChildren(args) {
|
|
|
7276
7309
|
}
|
|
7277
7310
|
});
|
|
7278
7311
|
const isAlive = args.isAlive ?? (isolated ? (pid) => {
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7312
|
+
const r = hardBoundedExecFile(
|
|
7313
|
+
"docker",
|
|
7314
|
+
["exec", `agt-${codeName}`, "kill", "-0", String(pid)],
|
|
7315
|
+
{ timeoutMs: 8e3, log: log2 }
|
|
7316
|
+
);
|
|
7317
|
+
return livenessFromProbe(
|
|
7318
|
+
r,
|
|
7319
|
+
(why) => log2(
|
|
7320
|
+
`[stale-mcp-reaper] liveness probe for pid ${pid} in 'agt-${codeName}' ${why} \u2014 treating as ALIVE (no reap) rather than guessing`
|
|
7321
|
+
)
|
|
7322
|
+
);
|
|
7288
7323
|
} : (pid) => {
|
|
7289
7324
|
try {
|
|
7290
7325
|
process.kill(pid, 0);
|
|
@@ -7453,10 +7488,33 @@ function reapMissingMcpSessions(args) {
|
|
|
7453
7488
|
currentGenerationExternallyStarted = false
|
|
7454
7489
|
} = args;
|
|
7455
7490
|
const now = args.now ?? Date.now;
|
|
7456
|
-
const runPs = args.runPs ?? (isolated ? (
|
|
7457
|
-
|
|
7458
|
-
timeout:
|
|
7459
|
-
|
|
7491
|
+
const runPs = args.runPs ?? (isolated ? (
|
|
7492
|
+
// ENG-9781: HARD-bounded, and the distinction is the whole ticket. The
|
|
7493
|
+
// previous `execFileSync(..., { timeout: 8_000 })` bounded nothing —
|
|
7494
|
+
// Node fires SIGTERM at the deadline and then keeps waiting, so a
|
|
7495
|
+
// docker CLI talking to a wedged daemon blocked the manager-worker's
|
|
7496
|
+
// event loop and stopped scheduling for EVERY agent on the host
|
|
7497
|
+
// (33m46s, twice, on 2026-09-01). This call runs once per isolated
|
|
7498
|
+
// agent per poll cycle, so it is the single worst place on the manager
|
|
7499
|
+
// for an unbounded subprocess.
|
|
7500
|
+
//
|
|
7501
|
+
// Throwing on a non-answer is deliberate rather than lazy: the caller
|
|
7502
|
+
// already catches, logs and SKIPS the agent for the cycle, which is
|
|
7503
|
+
// exactly right. A timeout must not become an empty process list —
|
|
7504
|
+
// that reads as "every declared MCP server is missing" and restarts the
|
|
7505
|
+
// session, turning a docker hiccup into a fleet-wide restart storm.
|
|
7506
|
+
() => {
|
|
7507
|
+
const r = hardBoundedExecFile(
|
|
7508
|
+
"docker",
|
|
7509
|
+
["exec", `agt-${codeName}`, "ps", "-eo", "pid,ppid,args"],
|
|
7510
|
+
{ timeoutMs: 8e3, log: log2 }
|
|
7511
|
+
);
|
|
7512
|
+
if (r.kind === "ok") return r.stdout;
|
|
7513
|
+
throw new Error(
|
|
7514
|
+
r.kind === "timed-out" ? `docker exec ps did not answer within its bound (bounded=${r.bounded})` : `docker exec ps failed (status=${r.status}): ${r.message}`
|
|
7515
|
+
);
|
|
7516
|
+
}
|
|
7517
|
+
) : () => execFileSync2("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 }));
|
|
7460
7518
|
if (!mcpJson?.mcpServers) {
|
|
7461
7519
|
return { missing: [], restarted: false, reason: "no-mcp-json" };
|
|
7462
7520
|
}
|
|
@@ -10593,4 +10651,4 @@ export {
|
|
|
10593
10651
|
managerInstallSystemUnitCommand,
|
|
10594
10652
|
managerUninstallSystemUnitCommand
|
|
10595
10653
|
};
|
|
10596
|
-
//# sourceMappingURL=chunk-
|
|
10654
|
+
//# sourceMappingURL=chunk-EWH4J63B.js.map
|