@integrity-labs/agt-cli 0.28.274 → 0.28.276
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-73NA6BKT.js → chunk-NY47D6QP.js} +8 -6
- package/dist/chunk-NY47D6QP.js.map +1 -0
- package/dist/lib/manager-worker.js +58 -3
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/xero.js +120573 -0
- package/package.json +3 -2
- package/dist/chunk-73NA6BKT.js.map +0 -1
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
requireHost,
|
|
39
39
|
safeWriteJsonAtomic,
|
|
40
40
|
setConfigHash
|
|
41
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-NY47D6QP.js";
|
|
42
42
|
import {
|
|
43
43
|
getProjectDir as getProjectDir2,
|
|
44
44
|
getReadyTasks,
|
|
@@ -211,6 +211,18 @@ function decidePostRestartVerification(pending, sessionStartedAt, sessionHealthy
|
|
|
211
211
|
function shouldRemediateUnverifiedRestart(outcome, ctx) {
|
|
212
212
|
return ctx.enabled && !ctx.breakerTripped && outcome.kind === "unverified" && outcome.final;
|
|
213
213
|
}
|
|
214
|
+
function computeFirstConnectUnsettled(integrations, now, windowMs) {
|
|
215
|
+
return integrations.some((i) => {
|
|
216
|
+
if (i.last_connectivity_status !== "transient_error") return false;
|
|
217
|
+
if (!i.created_at) return false;
|
|
218
|
+
const addedAt = Date.parse(i.created_at);
|
|
219
|
+
if (!Number.isFinite(addedAt)) return false;
|
|
220
|
+
return now - addedAt <= windowMs;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function shouldDeferBindRemediationForFirstConnect(outcome, ctx) {
|
|
224
|
+
return ctx.enabled && !ctx.breakerTripped && ctx.firstConnectUnsettled && ctx.deferralsSoFar < ctx.maxDeferrals && outcome.kind === "unverified" && outcome.final;
|
|
225
|
+
}
|
|
214
226
|
|
|
215
227
|
// src/lib/integration-hash.ts
|
|
216
228
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -6352,6 +6364,16 @@ function bindRemediationEnabled() {
|
|
|
6352
6364
|
return v === "true" || v === "1";
|
|
6353
6365
|
}
|
|
6354
6366
|
var BIND_REMEDIATION_JITTER_MS = 3e4;
|
|
6367
|
+
var BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS = readEnvNumber(
|
|
6368
|
+
"AGT_BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS",
|
|
6369
|
+
9e5
|
|
6370
|
+
// 15 min
|
|
6371
|
+
);
|
|
6372
|
+
var BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS = readEnvNumber(
|
|
6373
|
+
"AGT_BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS",
|
|
6374
|
+
3
|
|
6375
|
+
);
|
|
6376
|
+
var firstConnectUnsettledByAgent = /* @__PURE__ */ new Map();
|
|
6355
6377
|
function verifyPendingRestarts(now) {
|
|
6356
6378
|
if (pendingRestartVerifications.size === 0) return;
|
|
6357
6379
|
for (const [codeName, pending] of pendingRestartVerifications) {
|
|
@@ -6373,6 +6395,24 @@ function verifyPendingRestarts(now) {
|
|
|
6373
6395
|
break;
|
|
6374
6396
|
case "unverified":
|
|
6375
6397
|
if (outcome.final) {
|
|
6398
|
+
const deferrals = pending.connectivityDeferrals ?? 0;
|
|
6399
|
+
if (shouldDeferBindRemediationForFirstConnect(outcome, {
|
|
6400
|
+
enabled: bindRemediationEnabled(),
|
|
6401
|
+
breakerTripped: restartBreaker.isTripped(codeName),
|
|
6402
|
+
firstConnectUnsettled: firstConnectUnsettledByAgent.get(codeName) ?? false,
|
|
6403
|
+
deferralsSoFar: deferrals,
|
|
6404
|
+
maxDeferrals: BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS
|
|
6405
|
+
})) {
|
|
6406
|
+
pendingRestartVerifications.set(codeName, {
|
|
6407
|
+
firedAt: now,
|
|
6408
|
+
attempts: pending.attempts,
|
|
6409
|
+
connectivityDeferrals: deferrals + 1
|
|
6410
|
+
});
|
|
6411
|
+
log(
|
|
6412
|
+
`[bind-remediation] '${codeName}' deferring forced re-respawn (${deferrals + 1}/${BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS}) \u2014 a freshly-added integration is still transient_error; waiting for first-connect to settle before re-binding its tools (ENG-7575)`
|
|
6413
|
+
);
|
|
6414
|
+
break;
|
|
6415
|
+
}
|
|
6376
6416
|
pendingRestartVerifications.delete(codeName);
|
|
6377
6417
|
log(
|
|
6378
6418
|
`[restart-verify] ERROR '${codeName}' did NOT respawn healthy after ${outcome.attempt} attempts following an MCP change \u2014 the live session may be stuck on its pre-restart tools. Check session health / manager.log; a manual session restart may be required (ENG-6174)`
|
|
@@ -6788,7 +6828,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
6788
6828
|
var lastVersionCheckAt = 0;
|
|
6789
6829
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
6790
6830
|
var lastResponsivenessProbeAt = 0;
|
|
6791
|
-
var agtCliVersion = true ? "0.28.
|
|
6831
|
+
var agtCliVersion = true ? "0.28.276" : "dev";
|
|
6792
6832
|
function resolveBrewPath(execFileSync2) {
|
|
6793
6833
|
try {
|
|
6794
6834
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9321,6 +9361,10 @@ async function processAgent(agent, agentStates) {
|
|
|
9321
9361
|
try {
|
|
9322
9362
|
const integrationsData = await api.post("/host/agent-integrations", { agent_id: agent.agent_id });
|
|
9323
9363
|
const integrations = (integrationsData.integrations ?? []).map(withResolvedRemoteMcp);
|
|
9364
|
+
firstConnectUnsettledByAgent.set(
|
|
9365
|
+
agent.code_name,
|
|
9366
|
+
computeFirstConnectUnsettled(integrations, Date.now(), BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS)
|
|
9367
|
+
);
|
|
9324
9368
|
for (const integration of integrations) {
|
|
9325
9369
|
if (integration.auth_type !== "oauth2") continue;
|
|
9326
9370
|
const expiresAt = integration.credentials?.token_expires_at;
|
|
@@ -12067,7 +12111,18 @@ function deployMcpAssets() {
|
|
|
12067
12111
|
// with the session and a bundle update applies on the next natural
|
|
12068
12112
|
// session restart. It fetches its credential + identity per call, so it
|
|
12069
12113
|
// never needs restarting to pick up a key rotation either.
|
|
12070
|
-
"origami.js"
|
|
12114
|
+
"origami.js",
|
|
12115
|
+
// ENG-7579: the Xero vendor MCP (our @integrity-labs/xero-mcp-server fork),
|
|
12116
|
+
// now bundled with the CLI instead of resolved at runtime via
|
|
12117
|
+
// `npx @integrity-labs/xero-mcp-server@latest`. The npx form required a
|
|
12118
|
+
// manual npm publish on every change and silently stranded the fleet on the
|
|
12119
|
+
// last-published version (CS-1440's attachment tool shipped in 0.0.21 but
|
|
12120
|
+
// npm @latest stayed at 0.0.20). Same treatment as origami - NOT a channel,
|
|
12121
|
+
// so not in RESTARTABLE_CHANNEL_FILES; the reaper (re)starts it with the
|
|
12122
|
+
// session and a bundle update applies on the next natural session restart.
|
|
12123
|
+
// In broker mode it fetches the freshest access_token per call, so it never
|
|
12124
|
+
// needs restarting to pick up a token rotation.
|
|
12125
|
+
"xero.js"
|
|
12071
12126
|
]) {
|
|
12072
12127
|
const src = join17(mcpSourceDir, file);
|
|
12073
12128
|
const dst = join17(targetDir, file);
|