@integrity-labs/agt-cli 0.25.0 → 0.25.2
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-IEVHEZV4.js → chunk-M2RBM3M5.js} +8 -3
- package/dist/chunk-M2RBM3M5.js.map +1 -0
- package/dist/{chunk-5PS4FY7I.js → chunk-U4DAVDAZ.js} +3 -125
- package/dist/chunk-U4DAVDAZ.js.map +1 -0
- package/dist/{chunk-7DRLULIO.js → chunk-VWOXS4YP.js} +357 -8
- package/dist/chunk-VWOXS4YP.js.map +1 -0
- package/dist/{claude-pair-runtime-SENCKRI4.js → claude-pair-runtime-Q5CZLM2R.js} +2 -2
- package/dist/lib/manager-worker.js +318 -9
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-3SNFKR2Q.js → persistent-session-MUJA45LT.js} +3 -3
- package/dist/{responsiveness-probe-UBNJFMAU.js → responsiveness-probe-2TBRHC5T.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-5PS4FY7I.js.map +0 -1
- package/dist/chunk-7DRLULIO.js.map +0 -1
- package/dist/chunk-IEVHEZV4.js.map +0 -1
- /package/dist/{claude-pair-runtime-SENCKRI4.js.map → claude-pair-runtime-Q5CZLM2R.js.map} +0 -0
- /package/dist/{persistent-session-3SNFKR2Q.js.map → persistent-session-MUJA45LT.js.map} +0 -0
- /package/dist/{responsiveness-probe-UBNJFMAU.js.map → responsiveness-probe-2TBRHC5T.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-MUJA45LT.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
const pairEnv = {
|
|
106
106
|
...process.env,
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
startClaudePair,
|
|
374
374
|
submitClaudePairCode
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
376
|
+
//# sourceMappingURL=claude-pair-runtime-Q5CZLM2R.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
provisionOrientHook,
|
|
14
14
|
provisionStopHook,
|
|
15
15
|
requireHost
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-U4DAVDAZ.js";
|
|
17
17
|
import {
|
|
18
18
|
findTaskByTemplate,
|
|
19
19
|
getProjectDir as getProjectDir2,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
stopAllSessionsAndWait,
|
|
51
51
|
stopPersistentSession,
|
|
52
52
|
takeZombieDetection
|
|
53
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-M2RBM3M5.js";
|
|
54
54
|
import {
|
|
55
55
|
KANBAN_CHECK_COMMAND,
|
|
56
56
|
appendDmFooter,
|
|
@@ -68,10 +68,12 @@ import {
|
|
|
68
68
|
parseDeliveryTarget,
|
|
69
69
|
parseTranscriptUsage,
|
|
70
70
|
parseUsageBanner,
|
|
71
|
+
probeHttpProvider,
|
|
71
72
|
resolveChannels,
|
|
73
|
+
resolveConnectivityProbe,
|
|
72
74
|
resolveDmTarget,
|
|
73
75
|
wrapScheduledTaskPrompt
|
|
74
|
-
} from "../chunk-
|
|
76
|
+
} from "../chunk-VWOXS4YP.js";
|
|
75
77
|
|
|
76
78
|
// src/lib/manager-worker.ts
|
|
77
79
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -681,6 +683,233 @@ function formatStatusMessage(events, windowMs) {
|
|
|
681
683
|
return `Circuit breaker tripped: ${events.length} restarts in ${windowLabel} (${breakdown}); most recent=${last.reason} at ${new Date(last.at).toISOString()}`;
|
|
682
684
|
}
|
|
683
685
|
|
|
686
|
+
// src/lib/model-change-respawn.ts
|
|
687
|
+
function shouldRespawnForModelChange(input) {
|
|
688
|
+
const { previousModel, primaryModel, framework, sessionHealthy } = input;
|
|
689
|
+
if (framework !== "claude-code") return false;
|
|
690
|
+
if (!sessionHealthy) return false;
|
|
691
|
+
if (!previousModel) return false;
|
|
692
|
+
if (!primaryModel) return false;
|
|
693
|
+
return previousModel !== primaryModel;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// src/lib/connectivity-probe-executor.ts
|
|
697
|
+
async function executeConnectivityProbe(target, deps = {}) {
|
|
698
|
+
const descriptor = resolveConnectivityProbe({
|
|
699
|
+
definitionId: target.definitionId,
|
|
700
|
+
sourceType: target.sourceType,
|
|
701
|
+
authType: target.authType
|
|
702
|
+
});
|
|
703
|
+
if (!descriptor.readOnly) {
|
|
704
|
+
throw new Error(`Refusing non-read-only probe for ${target.definitionId}`);
|
|
705
|
+
}
|
|
706
|
+
switch (descriptor.kind) {
|
|
707
|
+
case "http_provider":
|
|
708
|
+
return probeHttpProvider(target.definitionId, target.credentials, deps.fetchImpl ?? fetch);
|
|
709
|
+
case "composio_account":
|
|
710
|
+
if (!deps.composioProbe) return null;
|
|
711
|
+
return deps.composioProbe(target.definitionId, target.credentials);
|
|
712
|
+
case "mcp_tools_list":
|
|
713
|
+
if (!deps.mcpProbe) return null;
|
|
714
|
+
return deps.mcpProbe({
|
|
715
|
+
serverKey: target.mcpServerKey ?? target.definitionId,
|
|
716
|
+
definitionId: target.definitionId
|
|
717
|
+
});
|
|
718
|
+
case "cli_command":
|
|
719
|
+
if (!deps.runCli) return null;
|
|
720
|
+
return deps.runCli(target.cliBinary ?? target.definitionId, descriptor.cliArgs ?? ["--version"]);
|
|
721
|
+
case "builtin":
|
|
722
|
+
return { status: "ok", message: `${target.definitionId}: built-in` };
|
|
723
|
+
case "unsupported":
|
|
724
|
+
default:
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// src/lib/connectivity-probe-runner.ts
|
|
730
|
+
var DEFAULT_INTERVAL_MS = 60 * 60 * 1e3;
|
|
731
|
+
var DEFAULT_MAX_PER_RUN = 25;
|
|
732
|
+
function isDue(lastCheck, now, intervalMs) {
|
|
733
|
+
if (!lastCheck) return true;
|
|
734
|
+
const t = Date.parse(lastCheck);
|
|
735
|
+
if (Number.isNaN(t)) return true;
|
|
736
|
+
return now - t >= intervalMs;
|
|
737
|
+
}
|
|
738
|
+
async function runConnectivityProbes(integrations, options = {}) {
|
|
739
|
+
const now = (options.now?.() ?? /* @__PURE__ */ new Date()).getTime();
|
|
740
|
+
const intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
741
|
+
const maxPerRun = options.maxPerRun ?? DEFAULT_MAX_PER_RUN;
|
|
742
|
+
const probeDeps = options.probeDeps ?? {};
|
|
743
|
+
const execute = options.executeProbe ?? executeConnectivityProbe;
|
|
744
|
+
const due = integrations.filter((i) => isDue(i.last_connectivity_check_at, now, intervalMs)).sort((a, b) => {
|
|
745
|
+
const ta = a.last_connectivity_check_at ? Date.parse(a.last_connectivity_check_at) : 0;
|
|
746
|
+
const tb = b.last_connectivity_check_at ? Date.parse(b.last_connectivity_check_at) : 0;
|
|
747
|
+
return ta - tb;
|
|
748
|
+
});
|
|
749
|
+
const batch = due.slice(0, maxPerRun);
|
|
750
|
+
const reports = [];
|
|
751
|
+
let skipped = 0;
|
|
752
|
+
for (const integ of batch) {
|
|
753
|
+
const target = {
|
|
754
|
+
definitionId: integ.definition_id,
|
|
755
|
+
sourceType: integ.source_type ?? null,
|
|
756
|
+
authType: integ.auth_type ?? null,
|
|
757
|
+
credentials: integ.credentials ?? {},
|
|
758
|
+
cliBinary: integ.cli_binary,
|
|
759
|
+
mcpServerKey: integ.mcp_server_key
|
|
760
|
+
};
|
|
761
|
+
let outcome;
|
|
762
|
+
try {
|
|
763
|
+
outcome = await execute(target, probeDeps);
|
|
764
|
+
} catch (err) {
|
|
765
|
+
console.warn(`[connectivity-probe] ${integ.definition_id} threw: ${err.message}`);
|
|
766
|
+
outcome = null;
|
|
767
|
+
}
|
|
768
|
+
if (!outcome) {
|
|
769
|
+
skipped += 1;
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
reports.push({
|
|
773
|
+
integration_id: integ.id,
|
|
774
|
+
scope: integ.scope,
|
|
775
|
+
status: outcome.status,
|
|
776
|
+
...outcome.message ? { message: outcome.message } : {}
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
return { reports, due: due.length, probed: batch.length, skipped };
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// src/lib/mcp-probe-client.ts
|
|
783
|
+
var MCP_ACCEPT = "application/json, text/event-stream";
|
|
784
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
785
|
+
async function parseRpc(res, expectedId) {
|
|
786
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
787
|
+
if (ct.includes("text/event-stream")) {
|
|
788
|
+
const text = await res.text();
|
|
789
|
+
let dataLines = [];
|
|
790
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
791
|
+
if (rawLine.startsWith("data:")) {
|
|
792
|
+
dataLines.push(rawLine.slice(5).trimStart());
|
|
793
|
+
continue;
|
|
794
|
+
}
|
|
795
|
+
if (rawLine === "" && dataLines.length > 0) {
|
|
796
|
+
try {
|
|
797
|
+
const msg2 = JSON.parse(dataLines.join("\n"));
|
|
798
|
+
if (("result" in msg2 || "error" in msg2) && msg2["id"] === expectedId) return msg2;
|
|
799
|
+
} catch {
|
|
800
|
+
}
|
|
801
|
+
dataLines = [];
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
const msg = await res.json().catch(() => null);
|
|
807
|
+
if (msg && ("result" in msg || "error" in msg) && msg["id"] === expectedId) return msg;
|
|
808
|
+
return msg;
|
|
809
|
+
}
|
|
810
|
+
function httpStatusOutcome(status, step) {
|
|
811
|
+
if (status === 401 || status === 403) {
|
|
812
|
+
return { status: "down", message: `MCP ${step} unauthorized (${status}) \u2014 reconnect required` };
|
|
813
|
+
}
|
|
814
|
+
if (status >= 500) {
|
|
815
|
+
return { status: "transient_error", message: `MCP ${step} returned ${status}` };
|
|
816
|
+
}
|
|
817
|
+
return { status: "down", message: `MCP ${step} returned ${status}` };
|
|
818
|
+
}
|
|
819
|
+
async function probeMcpHttp(config2, fetchImpl = fetch) {
|
|
820
|
+
const timeoutMs = config2.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
821
|
+
const baseHeaders = {
|
|
822
|
+
...config2.headers ?? {},
|
|
823
|
+
"Content-Type": "application/json",
|
|
824
|
+
Accept: MCP_ACCEPT
|
|
825
|
+
};
|
|
826
|
+
try {
|
|
827
|
+
const initRes = await fetchImpl(config2.url, {
|
|
828
|
+
method: "POST",
|
|
829
|
+
headers: baseHeaders,
|
|
830
|
+
body: JSON.stringify({
|
|
831
|
+
jsonrpc: "2.0",
|
|
832
|
+
id: 1,
|
|
833
|
+
method: "initialize",
|
|
834
|
+
params: {
|
|
835
|
+
protocolVersion: "2025-03-26",
|
|
836
|
+
capabilities: {},
|
|
837
|
+
clientInfo: { name: "augmented-connectivity-probe", version: "1.0.0" }
|
|
838
|
+
}
|
|
839
|
+
}),
|
|
840
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
841
|
+
});
|
|
842
|
+
if (!initRes.ok) return httpStatusOutcome(initRes.status, "initialize");
|
|
843
|
+
const sessionId = initRes.headers.get("mcp-session-id");
|
|
844
|
+
await parseRpc(initRes, 1);
|
|
845
|
+
const sessionHeaders = { ...baseHeaders, ...sessionId ? { "Mcp-Session-Id": sessionId } : {} };
|
|
846
|
+
const initializedRes = await fetchImpl(config2.url, {
|
|
847
|
+
method: "POST",
|
|
848
|
+
headers: sessionHeaders,
|
|
849
|
+
body: JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }),
|
|
850
|
+
signal: AbortSignal.timeout(5e3)
|
|
851
|
+
});
|
|
852
|
+
if (!initializedRes.ok) return httpStatusOutcome(initializedRes.status, "initialized");
|
|
853
|
+
await initializedRes.text().catch(() => "");
|
|
854
|
+
const listRes = await fetchImpl(config2.url, {
|
|
855
|
+
method: "POST",
|
|
856
|
+
headers: sessionHeaders,
|
|
857
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 2, method: "tools/list" }),
|
|
858
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
859
|
+
});
|
|
860
|
+
if (!listRes.ok) return httpStatusOutcome(listRes.status, "tools/list");
|
|
861
|
+
const rpc = await parseRpc(listRes, 2);
|
|
862
|
+
if (rpc && "error" in rpc) {
|
|
863
|
+
const err = rpc["error"];
|
|
864
|
+
return { status: "down", message: `MCP tools/list error: ${err?.message ?? "unknown"}` };
|
|
865
|
+
}
|
|
866
|
+
const result = rpc?.["result"];
|
|
867
|
+
const toolCount = Array.isArray(result?.tools) ? result.tools.length : void 0;
|
|
868
|
+
return {
|
|
869
|
+
status: "ok",
|
|
870
|
+
message: toolCount !== void 0 ? `${toolCount} tools` : "reachable",
|
|
871
|
+
...toolCount !== void 0 ? { details: { toolCount } } : {}
|
|
872
|
+
};
|
|
873
|
+
} catch (err) {
|
|
874
|
+
const isAbort = err?.name === "TimeoutError" || err?.name === "AbortError";
|
|
875
|
+
return {
|
|
876
|
+
status: "transient_error",
|
|
877
|
+
message: isAbort ? `MCP handshake timed out after ${timeoutMs / 1e3}s` : `MCP handshake failed: ${err.message}`
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// src/lib/cli-probe.ts
|
|
883
|
+
import { execFile } from "child_process";
|
|
884
|
+
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
885
|
+
function runCliProbe(binary, args, opts = {}) {
|
|
886
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
887
|
+
return new Promise((resolve) => {
|
|
888
|
+
execFile(
|
|
889
|
+
binary,
|
|
890
|
+
args,
|
|
891
|
+
{ timeout: timeoutMs, env: opts.env ?? process.env, windowsHide: true },
|
|
892
|
+
(err, stdout) => {
|
|
893
|
+
if (!err) {
|
|
894
|
+
const firstLine = String(stdout).split(/\r?\n/, 1)[0]?.trim();
|
|
895
|
+
resolve({ status: "ok", message: firstLine ? `${binary}: ${firstLine}` : `${binary}: ok` });
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
const e = err;
|
|
899
|
+
if (e.code === "ENOENT") {
|
|
900
|
+
resolve({ status: "down", message: `${binary} not found on PATH (not installed)` });
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (e.killed || e.signal === "SIGTERM") {
|
|
904
|
+
resolve({ status: "transient_error", message: `${binary} probe timed out after ${timeoutMs / 1e3}s` });
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
resolve({ status: "down", message: `${binary} exited non-zero: ${e.message}` });
|
|
908
|
+
}
|
|
909
|
+
);
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
|
|
684
913
|
// src/lib/usage-banner-monitor.ts
|
|
685
914
|
var MIN_CHECK_INTERVAL_MS = 6e4;
|
|
686
915
|
var PANE_TAIL_LINES_FOR_BANNER = 200;
|
|
@@ -1367,9 +1596,9 @@ var GatewayClientPool = class extends EventEmitter {
|
|
|
1367
1596
|
import { readFile, readdir } from "fs/promises";
|
|
1368
1597
|
import { homedir as homedir2, platform } from "os";
|
|
1369
1598
|
import { join as join3 } from "path";
|
|
1370
|
-
import { execFile } from "child_process";
|
|
1599
|
+
import { execFile as execFile2 } from "child_process";
|
|
1371
1600
|
import { promisify } from "util";
|
|
1372
|
-
var execFileAsync = promisify(
|
|
1601
|
+
var execFileAsync = promisify(execFile2);
|
|
1373
1602
|
var EXPIRING_SOON_MS = 48 * 60 * 60 * 1e3;
|
|
1374
1603
|
async function detectClaudeAuth() {
|
|
1375
1604
|
if (process.env["ANTHROPIC_API_KEY"] || process.env["ANTHROPIC_AUTH_TOKEN"]) {
|
|
@@ -2702,6 +2931,55 @@ function projectMcpKeys(_codeName, projectDir) {
|
|
|
2702
2931
|
return null;
|
|
2703
2932
|
}
|
|
2704
2933
|
}
|
|
2934
|
+
function readMcpHttpServerConfig(projectDir, serverKey) {
|
|
2935
|
+
try {
|
|
2936
|
+
const raw = readFileSync5(join6(projectDir, ".mcp.json"), "utf-8");
|
|
2937
|
+
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
2938
|
+
const entry = servers[serverKey];
|
|
2939
|
+
if (entry && typeof entry.url === "string" && (entry.type === "http" || entry.type === void 0)) {
|
|
2940
|
+
return { url: entry.url, ...entry.headers ? { headers: entry.headers } : {} };
|
|
2941
|
+
}
|
|
2942
|
+
return null;
|
|
2943
|
+
} catch {
|
|
2944
|
+
return null;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
async function runAgentConnectivityProbes(agent, integrations, projectDir) {
|
|
2948
|
+
if (integrations.length === 0) return;
|
|
2949
|
+
const probeDeps = {
|
|
2950
|
+
fetchImpl: fetch,
|
|
2951
|
+
runCli: (binary, args) => runCliProbe(binary, args),
|
|
2952
|
+
mcpProbe: async (target) => {
|
|
2953
|
+
const cfg = readMcpHttpServerConfig(projectDir, target.serverKey);
|
|
2954
|
+
if (!cfg) {
|
|
2955
|
+
return { status: "transient_error", message: `MCP server '${target.serverKey}' not resolvable from .mcp.json` };
|
|
2956
|
+
}
|
|
2957
|
+
return probeMcpHttp(cfg);
|
|
2958
|
+
}
|
|
2959
|
+
};
|
|
2960
|
+
const intervalSec = Number(process.env.AGT_CONNECTIVITY_PROBE_INTERVAL_SECONDS) || 3600;
|
|
2961
|
+
const result = await runConnectivityProbes(
|
|
2962
|
+
integrations.map((i) => ({
|
|
2963
|
+
id: i.id,
|
|
2964
|
+
definition_id: i.definition_id,
|
|
2965
|
+
scope: i.scope,
|
|
2966
|
+
auth_type: i.auth_type,
|
|
2967
|
+
source_type: i.source_type ?? null,
|
|
2968
|
+
credentials: i.credentials,
|
|
2969
|
+
last_connectivity_check_at: i.last_connectivity_check_at ?? null
|
|
2970
|
+
})),
|
|
2971
|
+
{ probeDeps, intervalMs: intervalSec * 1e3 }
|
|
2972
|
+
);
|
|
2973
|
+
if (result.reports.length > 0) {
|
|
2974
|
+
await api.post("/host/integration-connectivity", {
|
|
2975
|
+
agent_id: agent.agent_id,
|
|
2976
|
+
results: result.reports
|
|
2977
|
+
});
|
|
2978
|
+
log(
|
|
2979
|
+
`Connectivity probe for '${agent.code_name}': probed=${result.probed} reported=${result.reports.length} due=${result.due}`
|
|
2980
|
+
);
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2705
2983
|
function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason) {
|
|
2706
2984
|
cancelPendingSessionRestart(codeName);
|
|
2707
2985
|
stopPersistentSession(codeName, log);
|
|
@@ -2852,7 +3130,7 @@ var cachedFrameworkVersion = null;
|
|
|
2852
3130
|
var lastVersionCheckAt = 0;
|
|
2853
3131
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2854
3132
|
var lastResponsivenessProbeAt = 0;
|
|
2855
|
-
var agtCliVersion = true ? "0.25.
|
|
3133
|
+
var agtCliVersion = true ? "0.25.2" : "dev";
|
|
2856
3134
|
function resolveBrewPath(execFileSync4) {
|
|
2857
3135
|
try {
|
|
2858
3136
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -3811,7 +4089,7 @@ async function pollCycle() {
|
|
|
3811
4089
|
}
|
|
3812
4090
|
try {
|
|
3813
4091
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
3814
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
4092
|
+
const { collectDiagnostics } = await import("../persistent-session-MUJA45LT.js");
|
|
3815
4093
|
const diagCodeNames = [...persistentSessionAgents];
|
|
3816
4094
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
3817
4095
|
let tailscaleHostname;
|
|
@@ -3869,7 +4147,7 @@ async function pollCycle() {
|
|
|
3869
4147
|
const {
|
|
3870
4148
|
collectResponsivenessProbes,
|
|
3871
4149
|
getResponsivenessIntervalMs
|
|
3872
|
-
} = await import("../responsiveness-probe-
|
|
4150
|
+
} = await import("../responsiveness-probe-2TBRHC5T.js");
|
|
3873
4151
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
3874
4152
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
3875
4153
|
const probeCodeNames = [...persistentSessionAgents];
|
|
@@ -4485,6 +4763,27 @@ async function processAgent(agent, agentStates) {
|
|
|
4485
4763
|
} catch (err) {
|
|
4486
4764
|
log(`Failed to update model for '${agent.code_name}': ${err.message}`);
|
|
4487
4765
|
}
|
|
4766
|
+
if (shouldRespawnForModelChange({
|
|
4767
|
+
previousModel,
|
|
4768
|
+
primaryModel,
|
|
4769
|
+
framework: frameworkId,
|
|
4770
|
+
sessionHealthy: isSessionHealthy(agent.code_name)
|
|
4771
|
+
})) {
|
|
4772
|
+
const restartNotice = `Your model was changed to ${primaryModel}. Claude Code applies the model at launch, so your manager will restart your session shortly to switch.`;
|
|
4773
|
+
const delivered = await injectMessage(
|
|
4774
|
+
agent.code_name,
|
|
4775
|
+
"system",
|
|
4776
|
+
restartNotice,
|
|
4777
|
+
{ task_name: "model-update" },
|
|
4778
|
+
log
|
|
4779
|
+
).catch(() => false);
|
|
4780
|
+
const delay = delivered ? 8e3 : 3e3;
|
|
4781
|
+
if (!delivered) {
|
|
4782
|
+
log(`[hot-reload] Inject notification unconfirmed for '${agent.code_name}' \u2014 proceeding with shorter delay`);
|
|
4783
|
+
}
|
|
4784
|
+
log(`[hot-reload] Model changed for '${agent.code_name}': ${previousModel} \u2192 ${primaryModel} \u2014 restarting session`);
|
|
4785
|
+
scheduleSessionRestart(agent.code_name, delay, "model change", "model-change");
|
|
4786
|
+
}
|
|
4488
4787
|
}
|
|
4489
4788
|
knownModels.set(agent.agent_id, primaryModel);
|
|
4490
4789
|
}
|
|
@@ -4758,6 +5057,14 @@ async function processAgent(agent, agentStates) {
|
|
|
4758
5057
|
log(`OAuth token refresh failed for '${agent.code_name}/${integration.definition_id}': ${err.message}`);
|
|
4759
5058
|
}
|
|
4760
5059
|
}
|
|
5060
|
+
if (process.env.AGT_CONNECTIVITY_PROBE_ENABLED === "true") {
|
|
5061
|
+
try {
|
|
5062
|
+
const probeProjectDir = join6(homedir4(), ".augmented", agent.code_name, "project");
|
|
5063
|
+
await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
|
|
5064
|
+
} catch (err) {
|
|
5065
|
+
log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
|
|
5066
|
+
}
|
|
5067
|
+
}
|
|
4761
5068
|
if (integrations.length > 0) {
|
|
4762
5069
|
const intHash = computeIntegrationsHash(integrations);
|
|
4763
5070
|
const prevIntHash = knownIntegrationHashes.get(agent.agent_id);
|
|
@@ -6340,6 +6647,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
6340
6647
|
source_type: "system",
|
|
6341
6648
|
metadata: { type: "persistent_session_boot" }
|
|
6342
6649
|
});
|
|
6650
|
+
const spawnPrimaryModel = resolveModelChain(refreshData).primary ?? refreshData.agent?.["primary_model"] ?? null;
|
|
6343
6651
|
startPersistentSession({
|
|
6344
6652
|
codeName,
|
|
6345
6653
|
agentId: agent.agent_id,
|
|
@@ -6351,6 +6659,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
6351
6659
|
apiHost: requireHost(),
|
|
6352
6660
|
claudeAuthMode,
|
|
6353
6661
|
anthropicApiKey,
|
|
6662
|
+
primaryModel: spawnPrimaryModel,
|
|
6354
6663
|
runId: sessionRunResult.run_id,
|
|
6355
6664
|
agentTimezone,
|
|
6356
6665
|
log
|
|
@@ -7842,7 +8151,7 @@ async function processClaudePairSessions(agents) {
|
|
|
7842
8151
|
killPairSession,
|
|
7843
8152
|
pairTmuxSession,
|
|
7844
8153
|
finalizeClaudePairOnboarding
|
|
7845
|
-
} = await import("../claude-pair-runtime-
|
|
8154
|
+
} = await import("../claude-pair-runtime-Q5CZLM2R.js");
|
|
7846
8155
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
7847
8156
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
7848
8157
|
const killed = await killPairSession(pairTmuxSession(pairId));
|