@integrity-labs/agt-cli 0.28.724 → 0.28.726
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-KOAHMMPZ.js → chunk-Z3N7J2MG.js} +3 -3
- package/dist/{chunk-ATJU3SDV.js → chunk-ZCTFF4PA.js} +193 -7
- package/dist/chunk-ZCTFF4PA.js.map +1 -0
- package/dist/{claude-pair-runtime-XWPOUQMP.js → claude-pair-runtime-42GBPDC7.js} +2 -2
- package/dist/lib/manager-worker.js +186 -47
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-CEC5KESY.js → persistent-session-LP7JOGZ5.js} +2 -2
- package/dist/{responsiveness-probe-J3VB4U4W.js → responsiveness-probe-TTHNHBBS.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-ATJU3SDV.js.map +0 -1
- /package/dist/{chunk-KOAHMMPZ.js.map → chunk-Z3N7J2MG.js.map} +0 -0
- /package/dist/{claude-pair-runtime-XWPOUQMP.js.map → claude-pair-runtime-42GBPDC7.js.map} +0 -0
- /package/dist/{persistent-session-CEC5KESY.js.map → persistent-session-LP7JOGZ5.js.map} +0 -0
- /package/dist/{responsiveness-probe-J3VB4U4W.js.map → responsiveness-probe-TTHNHBBS.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-LP7JOGZ5.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-42GBPDC7.js.map
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
safeWriteJsonAtomic,
|
|
58
58
|
setConfigHash,
|
|
59
59
|
tripClass
|
|
60
|
-
} from "../chunk-
|
|
60
|
+
} from "../chunk-Z3N7J2MG.js";
|
|
61
61
|
import {
|
|
62
62
|
getProjectDir as getProjectDir2,
|
|
63
63
|
getReadyTasks,
|
|
@@ -90,8 +90,11 @@ import {
|
|
|
90
90
|
isolationMode,
|
|
91
91
|
log,
|
|
92
92
|
mergeOpencodeConfigArtifact,
|
|
93
|
+
modelPolicyAuthComponent,
|
|
94
|
+
modelPolicyEgressDomains,
|
|
93
95
|
paneLogPath,
|
|
94
96
|
parseEnvIntegrations,
|
|
97
|
+
parseModelPolicy,
|
|
95
98
|
prepareForRespawn,
|
|
96
99
|
readChannelServerEnv,
|
|
97
100
|
readDirectChatSessionState,
|
|
@@ -115,7 +118,7 @@ import {
|
|
|
115
118
|
takeZombieDetection,
|
|
116
119
|
toOpencodeModel,
|
|
117
120
|
writeEgressAllowlist
|
|
118
|
-
} from "../chunk-
|
|
121
|
+
} from "../chunk-ZCTFF4PA.js";
|
|
119
122
|
import {
|
|
120
123
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
121
124
|
AnchorSessionClient,
|
|
@@ -2880,21 +2883,29 @@ var COMPONENT_ORDER = [
|
|
|
2880
2883
|
"auth_mode",
|
|
2881
2884
|
"anthropic_api_key_fingerprint",
|
|
2882
2885
|
"claude_account_fingerprint",
|
|
2883
|
-
"openrouter_fingerprint"
|
|
2886
|
+
"openrouter_fingerprint",
|
|
2887
|
+
// ENG-9483 slice 2: `<policyId>@<revision>` from modelPolicyAuthComponent.
|
|
2888
|
+
// Non-secret: a uuid the operator chose plus an integer they can see in the UI.
|
|
2889
|
+
"model_policy"
|
|
2884
2890
|
];
|
|
2891
|
+
var POLICY_TUPLE_SEPARATOR = "|policy=";
|
|
2885
2892
|
function parseAuthTuple(tuple) {
|
|
2886
|
-
const
|
|
2893
|
+
const full = typeof tuple === "string" ? tuple : "";
|
|
2894
|
+
const sepAt = full.lastIndexOf(POLICY_TUPLE_SEPARATOR);
|
|
2895
|
+
const raw = sepAt === -1 ? full : full.slice(0, sepAt);
|
|
2896
|
+
const policy = sepAt === -1 ? null : full.slice(sepAt + POLICY_TUPLE_SEPARATOR.length) || ABSENT2;
|
|
2897
|
+
const withPolicy = (r) => policy === null ? r : { ...r, model_policy: policy };
|
|
2887
2898
|
if (raw.startsWith("openrouter:")) {
|
|
2888
|
-
return {
|
|
2899
|
+
return withPolicy({
|
|
2889
2900
|
auth_mode: "openrouter",
|
|
2890
2901
|
openrouter_fingerprint: raw.slice("openrouter:".length) || ABSENT2
|
|
2891
|
-
};
|
|
2902
|
+
});
|
|
2892
2903
|
}
|
|
2893
2904
|
const parts = raw.split(":");
|
|
2894
2905
|
if (parts.length < 2) {
|
|
2895
|
-
return { auth_mode: raw || ABSENT2 };
|
|
2906
|
+
return withPolicy({ auth_mode: raw || ABSENT2 });
|
|
2896
2907
|
}
|
|
2897
|
-
return {
|
|
2908
|
+
return withPolicy({
|
|
2898
2909
|
auth_mode: parts[0] || ABSENT2,
|
|
2899
2910
|
anthropic_api_key_fingerprint: parts[1] || ABSENT2,
|
|
2900
2911
|
// Omitted from the string when there is no signed-in account fingerprint
|
|
@@ -2902,7 +2913,19 @@ function parseAuthTuple(tuple) {
|
|
|
2902
2913
|
// Recorded as the ABSENT sentinel so "account appeared" / "account
|
|
2903
2914
|
// disappeared" is itself visible as a change.
|
|
2904
2915
|
claude_account_fingerprint: parts[2] || ABSENT2
|
|
2905
|
-
};
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2918
|
+
function buildAuthTuple(input) {
|
|
2919
|
+
const {
|
|
2920
|
+
openRouterCredential,
|
|
2921
|
+
claudeAuthMode,
|
|
2922
|
+
anthropicApiKeyFingerprint,
|
|
2923
|
+
claudeAccountFingerprint,
|
|
2924
|
+
modelPolicyComponent
|
|
2925
|
+
} = input;
|
|
2926
|
+
const suffix = modelPolicyComponent ? `${POLICY_TUPLE_SEPARATOR}${modelPolicyComponent}` : "";
|
|
2927
|
+
if (openRouterCredential) return `openrouter:${openRouterCredential}${suffix}`;
|
|
2928
|
+
return `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? ABSENT2}${claudeAccountFingerprint ? `:${claudeAccountFingerprint}` : ""}${suffix}`;
|
|
2906
2929
|
}
|
|
2907
2930
|
function diffAuthTuples(recorded, current) {
|
|
2908
2931
|
const before = parseAuthTuple(recorded);
|
|
@@ -5138,6 +5161,16 @@ function slugToTitle(slug) {
|
|
|
5138
5161
|
function escapeYamlDouble(value) {
|
|
5139
5162
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
5140
5163
|
}
|
|
5164
|
+
function resolveIntegrationSkillLane(payload) {
|
|
5165
|
+
if (payload.integration_skills_manifest !== void 0 && payload.integration_skills === void 0) {
|
|
5166
|
+
return null;
|
|
5167
|
+
}
|
|
5168
|
+
return payload.integration_skills ?? payload.plugin_skills ?? [];
|
|
5169
|
+
}
|
|
5170
|
+
function planIntegrationSkillSweep(discovered, currentIds, desiredResolved) {
|
|
5171
|
+
if (!desiredResolved) return [];
|
|
5172
|
+
return [...discovered].filter((entry) => !currentIds.has(entry));
|
|
5173
|
+
}
|
|
5141
5174
|
function groupSkillsByIntegration(skills) {
|
|
5142
5175
|
const map = /* @__PURE__ */ new Map();
|
|
5143
5176
|
for (const s of skills) {
|
|
@@ -5365,19 +5398,14 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
|
|
|
5365
5398
|
} catch {
|
|
5366
5399
|
}
|
|
5367
5400
|
}
|
|
5368
|
-
async function
|
|
5369
|
-
const { globals, shared, cacheDir, fetchContents, log: log2 } = args;
|
|
5401
|
+
async function collectBodies(hashes, cacheDir, fetchContents, lane, log2) {
|
|
5370
5402
|
const bodies = /* @__PURE__ */ new Map();
|
|
5371
5403
|
const missing = [];
|
|
5372
|
-
for (const
|
|
5373
|
-
if (
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
if (bodies.has(entry.hash) || missing.includes(entry.hash)) continue;
|
|
5378
|
-
const cached = readCachedSkill(cacheDir, entry.hash);
|
|
5379
|
-
if (cached !== null) bodies.set(entry.hash, cached);
|
|
5380
|
-
else missing.push(entry.hash);
|
|
5404
|
+
for (const hash of hashes) {
|
|
5405
|
+
if (bodies.has(hash) || missing.includes(hash)) continue;
|
|
5406
|
+
const cached = readCachedSkill(cacheDir, hash);
|
|
5407
|
+
if (cached !== null) bodies.set(hash, cached);
|
|
5408
|
+
else missing.push(hash);
|
|
5381
5409
|
}
|
|
5382
5410
|
for (let i = 0; i < missing.length; i += SKILL_FETCH_CHUNK) {
|
|
5383
5411
|
const chunk2 = missing.slice(i, i + SKILL_FETCH_CHUNK);
|
|
@@ -5385,19 +5413,32 @@ async function resolveSkillsFromManifest(args) {
|
|
|
5385
5413
|
for (const { hash, content } of await fetchContents(chunk2)) {
|
|
5386
5414
|
const written = writeCachedSkill(cacheDir, hash, content);
|
|
5387
5415
|
if (written === "mismatch") {
|
|
5388
|
-
log2?.(`[
|
|
5416
|
+
log2?.(`[${lane}] hash mismatch for ${hash} \u2014 skipping skill sync this poll`);
|
|
5389
5417
|
continue;
|
|
5390
5418
|
}
|
|
5391
5419
|
if (written === "write-failed") {
|
|
5392
|
-
log2?.(`[
|
|
5420
|
+
log2?.(`[${lane}] cache write failed for ${hash} \u2014 serving it uncached this poll`);
|
|
5393
5421
|
}
|
|
5394
5422
|
bodies.set(hash, content);
|
|
5395
5423
|
}
|
|
5396
5424
|
} catch (err) {
|
|
5397
|
-
log2?.(`[
|
|
5425
|
+
log2?.(`[${lane}] fetch failed for ${chunk2.length} entries: ${err.message}`);
|
|
5398
5426
|
}
|
|
5399
5427
|
}
|
|
5400
5428
|
sweepSkillCache(cacheDir);
|
|
5429
|
+
return bodies;
|
|
5430
|
+
}
|
|
5431
|
+
async function resolveSkillsFromManifest(args) {
|
|
5432
|
+
const { globals, shared, cacheDir, fetchContents, log: log2 } = args;
|
|
5433
|
+
const hashes = [];
|
|
5434
|
+
for (const entry of [...globals, ...shared]) {
|
|
5435
|
+
if (!entry.hash) {
|
|
5436
|
+
log2?.(`[skills] manifest entry '${entry.code_name}' has no hash \u2014 skipping skill sync`);
|
|
5437
|
+
return null;
|
|
5438
|
+
}
|
|
5439
|
+
hashes.push(entry.hash);
|
|
5440
|
+
}
|
|
5441
|
+
const bodies = await collectBodies(hashes, cacheDir, fetchContents, "skills", log2);
|
|
5401
5442
|
const resolve2 = (entries) => {
|
|
5402
5443
|
const out = [];
|
|
5403
5444
|
for (const e of entries) {
|
|
@@ -5420,6 +5461,47 @@ async function resolveSkillsFromManifest(args) {
|
|
|
5420
5461
|
}
|
|
5421
5462
|
return { globals: resolvedGlobals, shared: resolvedShared };
|
|
5422
5463
|
}
|
|
5464
|
+
async function resolveIntegrationSkillsFromManifest(args) {
|
|
5465
|
+
const { manifest, cacheDir, fetchContents, log: log2 } = args;
|
|
5466
|
+
const hashes = [];
|
|
5467
|
+
for (const entry of manifest) {
|
|
5468
|
+
if (entry.hash) {
|
|
5469
|
+
hashes.push(entry.hash);
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
if (typeof entry.content !== "string") {
|
|
5473
|
+
log2?.(
|
|
5474
|
+
`[integration-skills] manifest entry '${entry.plugin_slug}/${entry.skill_id}' has neither hash nor content \u2014 skipping integration skill sync`
|
|
5475
|
+
);
|
|
5476
|
+
return null;
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
const bodies = await collectBodies(
|
|
5480
|
+
hashes,
|
|
5481
|
+
cacheDir,
|
|
5482
|
+
fetchContents,
|
|
5483
|
+
"integration-skills",
|
|
5484
|
+
log2
|
|
5485
|
+
);
|
|
5486
|
+
const out = [];
|
|
5487
|
+
for (const e of manifest) {
|
|
5488
|
+
const content = e.hash ? bodies.get(e.hash) : e.content;
|
|
5489
|
+
if (content === void 0) {
|
|
5490
|
+
log2?.(
|
|
5491
|
+
"[integration-skills] one or more bodies unresolved \u2014 leaving on-disk integration skills untouched this poll"
|
|
5492
|
+
);
|
|
5493
|
+
return null;
|
|
5494
|
+
}
|
|
5495
|
+
out.push({
|
|
5496
|
+
plugin_slug: e.plugin_slug,
|
|
5497
|
+
...e.integration_slug !== void 0 ? { integration_slug: e.integration_slug } : {},
|
|
5498
|
+
skill_id: e.skill_id,
|
|
5499
|
+
skill_name: e.skill_name,
|
|
5500
|
+
content
|
|
5501
|
+
});
|
|
5502
|
+
}
|
|
5503
|
+
return out;
|
|
5504
|
+
}
|
|
5423
5505
|
|
|
5424
5506
|
// src/lib/channel-hash-cache.ts
|
|
5425
5507
|
import { existsSync as existsSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
|
|
@@ -12184,7 +12266,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
12184
12266
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
12185
12267
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
12186
12268
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
12187
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
12269
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-TTHNHBBS.js");
|
|
12188
12270
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
12189
12271
|
if (newest === null) return null;
|
|
12190
12272
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -12832,7 +12914,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12832
12914
|
var lastVersionCheckAt = 0;
|
|
12833
12915
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12834
12916
|
var lastResponsivenessProbeAt = 0;
|
|
12835
|
-
var agtCliVersion = true ? "0.28.
|
|
12917
|
+
var agtCliVersion = true ? "0.28.726" : "dev";
|
|
12836
12918
|
function resolveBrewPath(execFileSync3) {
|
|
12837
12919
|
try {
|
|
12838
12920
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -14359,7 +14441,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
14359
14441
|
if (codeNames.length === 0) return;
|
|
14360
14442
|
void (async () => {
|
|
14361
14443
|
try {
|
|
14362
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14444
|
+
const { collectDiagnostics } = await import("../persistent-session-LP7JOGZ5.js");
|
|
14363
14445
|
await api.post("/host/heartbeat", {
|
|
14364
14446
|
host_id: hostId,
|
|
14365
14447
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -14477,7 +14559,7 @@ async function pollCycleInner() {
|
|
|
14477
14559
|
}
|
|
14478
14560
|
try {
|
|
14479
14561
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
14480
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14562
|
+
const { collectDiagnostics } = await import("../persistent-session-LP7JOGZ5.js");
|
|
14481
14563
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
14482
14564
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
14483
14565
|
let tailscaleHostname;
|
|
@@ -14646,7 +14728,7 @@ async function pollCycleInner() {
|
|
|
14646
14728
|
collectPanelessActivityProbes,
|
|
14647
14729
|
getResponsivenessIntervalMs,
|
|
14648
14730
|
occupancyQualificationClassifications
|
|
14649
|
-
} = await import("../responsiveness-probe-
|
|
14731
|
+
} = await import("../responsiveness-probe-TTHNHBBS.js");
|
|
14650
14732
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
14651
14733
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
14652
14734
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14756,7 +14838,7 @@ async function pollCycleInner() {
|
|
|
14756
14838
|
collectResponsivenessProbes,
|
|
14757
14839
|
livePendingInboundOldestAgeSeconds,
|
|
14758
14840
|
parkPendingInbound
|
|
14759
|
-
} = await import("../responsiveness-probe-
|
|
14841
|
+
} = await import("../responsiveness-probe-TTHNHBBS.js");
|
|
14760
14842
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14761
14843
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14762
14844
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -15677,7 +15759,13 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15677
15759
|
// ENG-9585: the same for the two root-skill lanes. A separate flag
|
|
15678
15760
|
// because the two shipped in different CLI versions — an API that
|
|
15679
15761
|
// understands one and not the other must still be able to answer.
|
|
15680
|
-
skills_manifest: true
|
|
15762
|
+
skills_manifest: true,
|
|
15763
|
+
// ENG-9585: and the integration lane, a third flag for the same reason
|
|
15764
|
+
// one level sharper. A manager that sent `skills_manifest` but could not
|
|
15765
|
+
// decode THIS manifest would read the lane as empty and sweep every
|
|
15766
|
+
// integration skill folder off disk, so the flag has to name the exact
|
|
15767
|
+
// capability rather than the family.
|
|
15768
|
+
integration_skills_manifest: true
|
|
15681
15769
|
});
|
|
15682
15770
|
if (refreshData.knowledge_manifest) {
|
|
15683
15771
|
const resolved = await resolveKnowledgeFromManifest({
|
|
@@ -15714,6 +15802,23 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15714
15802
|
refreshData.shared_skills = resolvedSkills.shared;
|
|
15715
15803
|
}
|
|
15716
15804
|
}
|
|
15805
|
+
if (refreshData.integration_skills_manifest) {
|
|
15806
|
+
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
15807
|
+
manifest: refreshData.integration_skills_manifest,
|
|
15808
|
+
cacheDir: join40(config.configDir, "_skills"),
|
|
15809
|
+
fetchContents: async (hashes) => {
|
|
15810
|
+
const res = await api.post(
|
|
15811
|
+
"/host/skills/contents",
|
|
15812
|
+
{ agent_id: agent.agent_id, hashes }
|
|
15813
|
+
);
|
|
15814
|
+
return res.contents ?? [];
|
|
15815
|
+
},
|
|
15816
|
+
log
|
|
15817
|
+
});
|
|
15818
|
+
if (resolvedIntegrationSkills) {
|
|
15819
|
+
refreshData.integration_skills = resolvedIntegrationSkills;
|
|
15820
|
+
}
|
|
15821
|
+
}
|
|
15717
15822
|
} catch (err) {
|
|
15718
15823
|
log(`Refresh failed for '${agent.code_name}': ${err.message}`);
|
|
15719
15824
|
const existing = state8.agents.find((a) => a.agentId === agent.agent_id);
|
|
@@ -16988,9 +17093,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16988
17093
|
agent_id: agent.agent_id,
|
|
16989
17094
|
knowledge_manifest: true,
|
|
16990
17095
|
// Only `scheduled_tasks` is read here, so ask for the manifest shape on
|
|
16991
|
-
//
|
|
17096
|
+
// every lane — nothing in this branch consumes a skill body, and the
|
|
16992
17097
|
// skill lanes are the largest part of the payload being discarded.
|
|
16993
|
-
skills_manifest: true
|
|
17098
|
+
skills_manifest: true,
|
|
17099
|
+
integration_skills_manifest: true
|
|
16994
17100
|
});
|
|
16995
17101
|
tasks = freshData.scheduled_tasks ?? tasks;
|
|
16996
17102
|
}
|
|
@@ -17023,9 +17129,17 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17023
17129
|
if (!slug) continue;
|
|
17024
17130
|
contextBySlug.set(slug, { values: ctx.values ?? {}, overrides: (ctx.overrides ?? "").trim() });
|
|
17025
17131
|
}
|
|
17026
|
-
const
|
|
17027
|
-
|
|
17028
|
-
|
|
17132
|
+
const integrationSkillsInput = resolveIntegrationSkillLane({
|
|
17133
|
+
integration_skills: refreshAny.integration_skills,
|
|
17134
|
+
plugin_skills: refreshAny.plugin_skills,
|
|
17135
|
+
integration_skills_manifest: refreshAny.integration_skills_manifest
|
|
17136
|
+
});
|
|
17137
|
+
if (integrationSkillsInput === null) {
|
|
17138
|
+
log(
|
|
17139
|
+
`Integration skill manifest unresolved for '${agent.code_name}' \u2014 leaving integration skill folders untouched this poll`
|
|
17140
|
+
);
|
|
17141
|
+
}
|
|
17142
|
+
const integrationGroups = groupSkillsByIntegration(integrationSkillsInput ?? []);
|
|
17029
17143
|
for (const [integrationSlug, scopes] of integrationGroups) {
|
|
17030
17144
|
try {
|
|
17031
17145
|
const integrationSkillId = `integration-${integrationSlug}`.replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -17104,10 +17218,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17104
17218
|
});
|
|
17105
17219
|
log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
|
|
17106
17220
|
};
|
|
17107
|
-
for (const entry of
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17221
|
+
for (const entry of planIntegrationSkillSweep(
|
|
17222
|
+
discoveredEntries,
|
|
17223
|
+
currentIntegrationSkillIds,
|
|
17224
|
+
integrationSkillsInput !== null
|
|
17225
|
+
)) {
|
|
17226
|
+
removeSkillFolder(entry, "orphaned skill folder");
|
|
17111
17227
|
}
|
|
17112
17228
|
} catch (err) {
|
|
17113
17229
|
log(`Integration skill cleanup failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -17907,9 +18023,10 @@ var persistentSessionStuckTracker = new PersistentSessionStuckTracker();
|
|
|
17907
18023
|
var claudeAuthTupleBySession = /* @__PURE__ */ new Map();
|
|
17908
18024
|
var opencodeCredentialFingerprintBySession = /* @__PURE__ */ new Map();
|
|
17909
18025
|
var egressAllowlistBySession = /* @__PURE__ */ new Map();
|
|
17910
|
-
function deriveEgressAllowlist(toolsRaw) {
|
|
18026
|
+
function deriveEgressAllowlist(toolsRaw, policy) {
|
|
17911
18027
|
return buildEgressAllowlist(
|
|
17912
|
-
toolsRaw ? extractFrontmatter(toolsRaw).frontmatter : null
|
|
18028
|
+
toolsRaw ? extractFrontmatter(toolsRaw).frontmatter : null,
|
|
18029
|
+
modelPolicyEgressDomains(policy)
|
|
17913
18030
|
);
|
|
17914
18031
|
}
|
|
17915
18032
|
var egressAllowlistEqual = (a, b) => a.length === b.length && a.every((d, i) => d === b[i]);
|
|
@@ -18052,6 +18169,9 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
18052
18169
|
smallFastModel: openRouterRaw.small_fast_model ?? null,
|
|
18053
18170
|
fingerprint: openRouterRaw.fingerprint ?? null
|
|
18054
18171
|
} : null;
|
|
18172
|
+
const modelPolicy = parseModelPolicy(
|
|
18173
|
+
refreshData.model_policy
|
|
18174
|
+
);
|
|
18055
18175
|
let claudeAuthMode;
|
|
18056
18176
|
let anthropicApiKey;
|
|
18057
18177
|
let anthropicApiKeyFingerprint;
|
|
@@ -18153,7 +18273,13 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
18153
18273
|
let dayRolloverForced = false;
|
|
18154
18274
|
const claudeAccountFingerprint = !openRouterForAgent && claudeAuthMode === "subscription" ? await getClaudeAccountFingerprint() : null;
|
|
18155
18275
|
noteClaudeAccountChange(codeName, claudeAccountFingerprint, log);
|
|
18156
|
-
const currentAuthTuple =
|
|
18276
|
+
const currentAuthTuple = buildAuthTuple({
|
|
18277
|
+
openRouterCredential: openRouterForAgent ? openRouterForAgent.fingerprint ?? openRouterForAgent.model : null,
|
|
18278
|
+
claudeAuthMode,
|
|
18279
|
+
anthropicApiKeyFingerprint,
|
|
18280
|
+
claudeAccountFingerprint,
|
|
18281
|
+
modelPolicyComponent: modelPolicyAuthComponent(modelPolicy)
|
|
18282
|
+
});
|
|
18157
18283
|
const recordedAuthTuple = claudeAuthTupleBySession.get(codeName);
|
|
18158
18284
|
if (recordedAuthTuple && recordedAuthTuple !== currentAuthTuple && isSessionHealthy(codeName)) {
|
|
18159
18285
|
const authTupleDiff = diffAuthTuples(recordedAuthTuple, currentAuthTuple);
|
|
@@ -18320,7 +18446,8 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash19("sha256")
|
|
|
18320
18446
|
trackSessionRun(codeName, sessionRunResult.run_id);
|
|
18321
18447
|
const spawnPrimaryModel = resolveModelChain(refreshData).primary ?? refreshData.agent?.["primary_model"] ?? null;
|
|
18322
18448
|
const egressAllowlist = deriveEgressAllowlist(
|
|
18323
|
-
refreshData.tools?.raw_content
|
|
18449
|
+
refreshData.tools?.raw_content,
|
|
18450
|
+
modelPolicy
|
|
18324
18451
|
);
|
|
18325
18452
|
egressAllowlistBySession.set(codeName, egressAllowlist);
|
|
18326
18453
|
let perAgentApiKey = null;
|
|
@@ -18373,6 +18500,17 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash19("sha256")
|
|
|
18373
18500
|
model: openRouterForAgent.model,
|
|
18374
18501
|
smallFastModel: openRouterForAgent.smallFastModel
|
|
18375
18502
|
} : null,
|
|
18503
|
+
// ENG-9483 slice 2 (ADR-0074). The SHAPE reaches the launcher; the
|
|
18504
|
+
// credential does not. `modelPolicyGatewayToken` is deliberately absent
|
|
18505
|
+
// (⇒ null) rather than wired to some plausible existing secret: slice 1's
|
|
18506
|
+
// resolver never selects `model_policy_bindings.credential`, and ENG-9481's
|
|
18507
|
+
// stored-key-vs-pass-through answer decides whether the credential is a
|
|
18508
|
+
// `gateway_token` (needing ANTHROPIC_CUSTOM_HEADERS, an at-rest secret this
|
|
18509
|
+
// tree does not have) or a plain `api_key` (which does not). Until then a
|
|
18510
|
+
// gateway binding resolves to `blocked` and the agent keeps its existing
|
|
18511
|
+
// auth — see resolveBindingCredential, the one function that changes when
|
|
18512
|
+
// that question is answered.
|
|
18513
|
+
modelPolicy,
|
|
18376
18514
|
runId: sessionRunResult.run_id,
|
|
18377
18515
|
agentTimezone,
|
|
18378
18516
|
// ENG-6476: materialize the host-side reply-routing flags into the agent
|
|
@@ -18427,7 +18565,8 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash19("sha256")
|
|
|
18427
18565
|
resetRestartCount(codeName);
|
|
18428
18566
|
if (egressMode(codeName) === "allowlist") {
|
|
18429
18567
|
const allowlist = deriveEgressAllowlist(
|
|
18430
|
-
refreshData.tools?.raw_content
|
|
18568
|
+
refreshData.tools?.raw_content,
|
|
18569
|
+
modelPolicy
|
|
18431
18570
|
);
|
|
18432
18571
|
const prev = egressAllowlistBySession.get(codeName);
|
|
18433
18572
|
if (!prev || !egressAllowlistEqual(prev, allowlist)) {
|
|
@@ -18770,7 +18909,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
18770
18909
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
18771
18910
|
void (async () => {
|
|
18772
18911
|
try {
|
|
18773
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18912
|
+
const { collectDiagnostics } = await import("../persistent-session-LP7JOGZ5.js");
|
|
18774
18913
|
await api.post("/host/heartbeat", {
|
|
18775
18914
|
host_id: hostId,
|
|
18776
18915
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -18821,7 +18960,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
18821
18960
|
}
|
|
18822
18961
|
try {
|
|
18823
18962
|
const hostId = await getHostId();
|
|
18824
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18963
|
+
const { collectDiagnostics } = await import("../persistent-session-LP7JOGZ5.js");
|
|
18825
18964
|
await api.post("/host/heartbeat", {
|
|
18826
18965
|
host_id: hostId,
|
|
18827
18966
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -19453,7 +19592,7 @@ async function processClaudePairSessions(agents) {
|
|
|
19453
19592
|
killPairSession,
|
|
19454
19593
|
pairTmuxSession,
|
|
19455
19594
|
finalizeClaudePairOnboarding
|
|
19456
|
-
} = await import("../claude-pair-runtime-
|
|
19595
|
+
} = await import("../claude-pair-runtime-42GBPDC7.js");
|
|
19457
19596
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
19458
19597
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
19459
19598
|
const killed = await killPairSession(pairTmuxSession(pairId));
|