@integrity-labs/agt-cli 0.28.733 → 0.28.735
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-7KT2QNXF.js → chunk-5CF4DRXA.js} +4 -1
- package/dist/{chunk-7KT2QNXF.js.map → chunk-5CF4DRXA.js.map} +1 -1
- package/dist/{chunk-LT7UGH4O.js → chunk-AZZ7MLBE.js} +3 -3
- package/dist/{claude-pair-runtime-K5OUT4QN.js → claude-pair-runtime-AWLXOAV6.js} +2 -2
- package/dist/lib/manager-worker.js +190 -90
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +3 -0
- package/dist/mcp/teams-channel.js +3 -0
- package/dist/mcp/telegram-channel.js +23 -13
- package/dist/{persistent-session-H7CP2TUX.js → persistent-session-4KGDH66U.js} +2 -2
- package/dist/{responsiveness-probe-MPPDJSOL.js → responsiveness-probe-HNUYLIFJ.js} +2 -2
- package/package.json +1 -1
- /package/dist/{chunk-LT7UGH4O.js.map → chunk-AZZ7MLBE.js.map} +0 -0
- /package/dist/{claude-pair-runtime-K5OUT4QN.js.map → claude-pair-runtime-AWLXOAV6.js.map} +0 -0
- /package/dist/{persistent-session-H7CP2TUX.js.map → persistent-session-4KGDH66U.js.map} +0 -0
- /package/dist/{responsiveness-probe-MPPDJSOL.js.map → responsiveness-probe-HNUYLIFJ.js.map} +0 -0
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
parseEnvFileEntries,
|
|
14
14
|
parseEnvIntegrations,
|
|
15
15
|
shellQuote
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-5CF4DRXA.js";
|
|
17
17
|
import {
|
|
18
18
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
19
19
|
INTEGRATIONS_SECTION_END,
|
|
@@ -6427,7 +6427,7 @@ function exchangeFailureKind(err) {
|
|
|
6427
6427
|
}
|
|
6428
6428
|
|
|
6429
6429
|
// src/lib/api-client.ts
|
|
6430
|
-
var agtCliVersion = true ? "0.28.
|
|
6430
|
+
var agtCliVersion = true ? "0.28.735" : "dev";
|
|
6431
6431
|
var lastConfigHash = null;
|
|
6432
6432
|
function setConfigHash(hash) {
|
|
6433
6433
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -10473,4 +10473,4 @@ export {
|
|
|
10473
10473
|
managerInstallSystemUnitCommand,
|
|
10474
10474
|
managerUninstallSystemUnitCommand
|
|
10475
10475
|
};
|
|
10476
|
-
//# sourceMappingURL=chunk-
|
|
10476
|
+
//# sourceMappingURL=chunk-AZZ7MLBE.js.map
|
|
@@ -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-4KGDH66U.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-AWLXOAV6.js.map
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
safeWriteJsonAtomic,
|
|
58
58
|
setConfigHash,
|
|
59
59
|
tripClass
|
|
60
|
-
} from "../chunk-
|
|
60
|
+
} from "../chunk-AZZ7MLBE.js";
|
|
61
61
|
import {
|
|
62
62
|
getProjectDir as getProjectDir2,
|
|
63
63
|
getReadyTasks,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
takeZombieDetection,
|
|
119
119
|
toOpencodeModel,
|
|
120
120
|
writeEgressAllowlist
|
|
121
|
-
} from "../chunk-
|
|
121
|
+
} from "../chunk-5CF4DRXA.js";
|
|
122
122
|
import {
|
|
123
123
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
124
124
|
AnchorSessionClient,
|
|
@@ -5584,6 +5584,48 @@ var REFRESH_MANIFEST_FLAGS = {
|
|
|
5584
5584
|
integration_skills_manifest: true
|
|
5585
5585
|
};
|
|
5586
5586
|
|
|
5587
|
+
// src/lib/fetch-cadence.ts
|
|
5588
|
+
function createFetchGate(ttlMs) {
|
|
5589
|
+
const lastFetchedAt = /* @__PURE__ */ new Map();
|
|
5590
|
+
const forceCount = /* @__PURE__ */ new Map();
|
|
5591
|
+
const consumedForceCount = /* @__PURE__ */ new Map();
|
|
5592
|
+
let generation = 0;
|
|
5593
|
+
const fetchedAtGeneration = /* @__PURE__ */ new Map();
|
|
5594
|
+
const pendingForces = (key) => (forceCount.get(key) ?? 0) > (consumedForceCount.get(key) ?? 0);
|
|
5595
|
+
return {
|
|
5596
|
+
shouldFetch(key, now = Date.now()) {
|
|
5597
|
+
if (pendingForces(key)) return true;
|
|
5598
|
+
if ((fetchedAtGeneration.get(key) ?? -1) < generation) return true;
|
|
5599
|
+
const last = lastFetchedAt.get(key);
|
|
5600
|
+
if (last === void 0) return true;
|
|
5601
|
+
return now - last >= ttlMs;
|
|
5602
|
+
},
|
|
5603
|
+
beginFetch(key) {
|
|
5604
|
+
return { forceCount: forceCount.get(key) ?? 0, generation };
|
|
5605
|
+
},
|
|
5606
|
+
markFetched(key, token, now = Date.now()) {
|
|
5607
|
+
lastFetchedAt.set(key, now);
|
|
5608
|
+
fetchedAtGeneration.set(key, token.generation);
|
|
5609
|
+
consumedForceCount.set(key, token.forceCount);
|
|
5610
|
+
},
|
|
5611
|
+
forceNext(key) {
|
|
5612
|
+
forceCount.set(key, (forceCount.get(key) ?? 0) + 1);
|
|
5613
|
+
},
|
|
5614
|
+
forceAll() {
|
|
5615
|
+
generation += 1;
|
|
5616
|
+
},
|
|
5617
|
+
forget(key) {
|
|
5618
|
+
lastFetchedAt.delete(key);
|
|
5619
|
+
fetchedAtGeneration.delete(key);
|
|
5620
|
+
forceCount.delete(key);
|
|
5621
|
+
consumedForceCount.delete(key);
|
|
5622
|
+
},
|
|
5623
|
+
size() {
|
|
5624
|
+
return lastFetchedAt.size;
|
|
5625
|
+
}
|
|
5626
|
+
};
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5587
5629
|
// src/lib/channel-hash-cache.ts
|
|
5588
5630
|
import { existsSync as existsSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
|
|
5589
5631
|
import { join as join25 } from "path";
|
|
@@ -9218,6 +9260,9 @@ function decideInboundAccess(input) {
|
|
|
9218
9260
|
if (input.orgBoundary && !input.orgBoundary.forward) {
|
|
9219
9261
|
return { kind: "drop", reason: "org_boundary" };
|
|
9220
9262
|
}
|
|
9263
|
+
if (input.chatType && !input.chatType.forward) {
|
|
9264
|
+
return { kind: "drop", reason: "chat_type" };
|
|
9265
|
+
}
|
|
9221
9266
|
if (input.senderPolicy && !input.senderPolicy.forward) {
|
|
9222
9267
|
const reason = input.senderPolicy.reason;
|
|
9223
9268
|
const declineWorthy = input.sameOrg && reason !== "internal_only";
|
|
@@ -9993,6 +10038,11 @@ function parsePeerAgentModeEnv2(raw) {
|
|
|
9993
10038
|
return "off";
|
|
9994
10039
|
}
|
|
9995
10040
|
|
|
10041
|
+
// ../../packages/core/dist/channels/governance/telegram-chat-type.js
|
|
10042
|
+
function isTelegramPrivateChat(chatType) {
|
|
10043
|
+
return chatType === "private";
|
|
10044
|
+
}
|
|
10045
|
+
|
|
9996
10046
|
// ../../packages/core/dist/channels/governance/telegram-sender-gate.js
|
|
9997
10047
|
function evaluateTelegramInboundGate(evt, deps) {
|
|
9998
10048
|
const isBot = Boolean(evt.from?.is_bot);
|
|
@@ -10029,6 +10079,10 @@ function evaluateTelegramInboundGate(evt, deps) {
|
|
|
10029
10079
|
// TELEGRAM_ALLOWED_CHATS is Telegram's org-boundary axis. An unlisted chat is
|
|
10030
10080
|
// external ⇒ silent drop.
|
|
10031
10081
|
orgBoundary: deps.allowedChats.size > 0 && !deps.allowedChats.has(chatId) ? { forward: false } : { forward: true },
|
|
10082
|
+
// CS-1628: the chat-kind axis. Only ever restricts - when the policy is off
|
|
10083
|
+
// this is `{ forward: true }`, which the composer treats identically to the
|
|
10084
|
+
// field being absent.
|
|
10085
|
+
chatType: deps.privateChatsOnly && !isTelegramPrivateChat(evt.chat.type) ? { forward: false } : { forward: true },
|
|
10032
10086
|
// No sender-policy mode system and no command dispatch on the injection gate.
|
|
10033
10087
|
sameOrg: false
|
|
10034
10088
|
});
|
|
@@ -12347,7 +12401,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
12347
12401
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
12348
12402
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
12349
12403
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
12350
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
12404
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-HNUYLIFJ.js");
|
|
12351
12405
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
12352
12406
|
if (newest === null) return null;
|
|
12353
12407
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -12960,6 +13014,9 @@ function resolveAgentFramework(codeName) {
|
|
|
12960
13014
|
function clearAgentCaches(agentId, codeName) {
|
|
12961
13015
|
const channelCacheMutated = clearAgentState(agentId, codeName);
|
|
12962
13016
|
agentChannelTokens.delete(codeName);
|
|
13017
|
+
lastRefreshPayload.delete(agentId);
|
|
13018
|
+
refreshFetchGate.forget(agentId);
|
|
13019
|
+
memoriesFetchGate.forget(agentId);
|
|
12963
13020
|
forgetRealtimeRebindState(agentId);
|
|
12964
13021
|
forgetChannelSyncState(agentId);
|
|
12965
13022
|
sharedBusyBuckets.reset(codeName);
|
|
@@ -12995,7 +13052,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12995
13052
|
var lastVersionCheckAt = 0;
|
|
12996
13053
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12997
13054
|
var lastResponsivenessProbeAt = 0;
|
|
12998
|
-
var agtCliVersion = true ? "0.28.
|
|
13055
|
+
var agtCliVersion = true ? "0.28.735" : "dev";
|
|
12999
13056
|
function resolveBrewPath(execFileSync3) {
|
|
13000
13057
|
try {
|
|
13001
13058
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -14505,6 +14562,16 @@ ${SKILLS_INDEX_END}`;
|
|
|
14505
14562
|
);
|
|
14506
14563
|
}
|
|
14507
14564
|
}
|
|
14565
|
+
var DESIRED_STATE_FETCH_TTL_MS = 6e4;
|
|
14566
|
+
var refreshFetchGate = createFetchGate(DESIRED_STATE_FETCH_TTL_MS);
|
|
14567
|
+
var lastRefreshPayload = /* @__PURE__ */ new Map();
|
|
14568
|
+
var memoriesFetchGate = createFetchGate(DESIRED_STATE_FETCH_TTL_MS);
|
|
14569
|
+
var pollCycleFetches = 0;
|
|
14570
|
+
var pollCycleFetchSkips = 0;
|
|
14571
|
+
function forceRefreshFetch() {
|
|
14572
|
+
refreshFetchGate.forceAll();
|
|
14573
|
+
memoriesFetchGate.forceAll();
|
|
14574
|
+
}
|
|
14508
14575
|
var consecutivePollFailures = 0;
|
|
14509
14576
|
function reorderRestartedFirst(agents, restartedIds) {
|
|
14510
14577
|
if (restartedIds.size === 0) return agents;
|
|
@@ -14522,7 +14589,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
14522
14589
|
if (codeNames.length === 0) return;
|
|
14523
14590
|
void (async () => {
|
|
14524
14591
|
try {
|
|
14525
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14592
|
+
const { collectDiagnostics } = await import("../persistent-session-4KGDH66U.js");
|
|
14526
14593
|
await api.post("/host/heartbeat", {
|
|
14527
14594
|
host_id: hostId,
|
|
14528
14595
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -14663,7 +14730,7 @@ async function pollCycleInner() {
|
|
|
14663
14730
|
}
|
|
14664
14731
|
try {
|
|
14665
14732
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
14666
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14733
|
+
const { collectDiagnostics } = await import("../persistent-session-4KGDH66U.js");
|
|
14667
14734
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
14668
14735
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
14669
14736
|
let tailscaleHostname;
|
|
@@ -14832,7 +14899,7 @@ async function pollCycleInner() {
|
|
|
14832
14899
|
collectPanelessActivityProbes,
|
|
14833
14900
|
getResponsivenessIntervalMs,
|
|
14834
14901
|
occupancyQualificationClassifications
|
|
14835
|
-
} = await import("../responsiveness-probe-
|
|
14902
|
+
} = await import("../responsiveness-probe-HNUYLIFJ.js");
|
|
14836
14903
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
14837
14904
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
14838
14905
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14942,7 +15009,7 @@ async function pollCycleInner() {
|
|
|
14942
15009
|
collectResponsivenessProbes,
|
|
14943
15010
|
livePendingInboundOldestAgeSeconds,
|
|
14944
15011
|
parkPendingInbound
|
|
14945
|
-
} = await import("../responsiveness-probe-
|
|
15012
|
+
} = await import("../responsiveness-probe-HNUYLIFJ.js");
|
|
14946
15013
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14947
15014
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14948
15015
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -15258,6 +15325,9 @@ async function pollCycleInner() {
|
|
|
15258
15325
|
const processOrder = fastRespawn ? reorderRestartedFirst(agents, new Set(restartAcks.keys())) : agents;
|
|
15259
15326
|
const managedToolkits = createManagedToolkitReader(agents.map((a) => a.agent_id));
|
|
15260
15327
|
managedPruneLedger = createManagedPruneLedger();
|
|
15328
|
+
const cycleStartedAt = Date.now();
|
|
15329
|
+
pollCycleFetches = 0;
|
|
15330
|
+
pollCycleFetchSkips = 0;
|
|
15261
15331
|
for (const agent of processOrder) {
|
|
15262
15332
|
if (restartInFlight.has(agent.agent_id)) {
|
|
15263
15333
|
const existing = state8.agents.find((a) => a.agentId === agent.agent_id);
|
|
@@ -15296,6 +15366,9 @@ async function pollCycleInner() {
|
|
|
15296
15366
|
promptBindProbeAttempts.set(agent.code_name, PROMPT_BIND_PROBE_ATTEMPTS);
|
|
15297
15367
|
}
|
|
15298
15368
|
}
|
|
15369
|
+
log(
|
|
15370
|
+
`[poll-cycle] agents=${processOrder.length} refresh_fetched=${pollCycleFetches} refresh_skipped=${pollCycleFetchSkips} duration_ms=${Date.now() - cycleStartedAt}`
|
|
15371
|
+
);
|
|
15299
15372
|
void maybeReportActivityCache({ api, log });
|
|
15300
15373
|
const crossAgentPrune = managedPruneLedger.summarize();
|
|
15301
15374
|
if (crossAgentPrune) log(crossAgentPrune);
|
|
@@ -15814,6 +15887,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15814
15887
|
if (previousStatus && previousStatus !== agent.status) {
|
|
15815
15888
|
log(`Agent '${agent.code_name}' status changed: ${previousStatus} \u2192 ${agent.status}`);
|
|
15816
15889
|
agentState.knownVersions.delete(agent.agent_id);
|
|
15890
|
+
refreshFetchGate.forceNext(agent.agent_id);
|
|
15817
15891
|
if (previousStatus === "paused" && agent.status === "active" && restartBreaker.isTripped(agent.code_name)) {
|
|
15818
15892
|
restartBreaker.clear(agent.code_name);
|
|
15819
15893
|
reportedTrips.delete(agent.code_name);
|
|
@@ -15853,85 +15927,95 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15853
15927
|
}
|
|
15854
15928
|
agentState.knownStatuses.set(agent.agent_id, agent.status);
|
|
15855
15929
|
let refreshData;
|
|
15856
|
-
|
|
15857
|
-
|
|
15858
|
-
|
|
15859
|
-
|
|
15860
|
-
|
|
15861
|
-
|
|
15862
|
-
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
15867
|
-
|
|
15868
|
-
manifest
|
|
15869
|
-
|
|
15870
|
-
|
|
15871
|
-
fetchContents: async (hashes) => {
|
|
15872
|
-
const res = await api.post(
|
|
15873
|
-
"/host/knowledge/contents",
|
|
15874
|
-
{ agent_id: agent.agent_id, hashes }
|
|
15875
|
-
);
|
|
15876
|
-
return res.contents ?? [];
|
|
15877
|
-
},
|
|
15878
|
-
log
|
|
15879
|
-
});
|
|
15880
|
-
refreshData.knowledge = resolved;
|
|
15881
|
-
}
|
|
15882
|
-
if (refreshData.global_skills_manifest || refreshData.shared_skills_manifest) {
|
|
15883
|
-
const resolvedSkills = await resolveSkillsFromManifest({
|
|
15884
|
-
globals: refreshData.global_skills_manifest ?? [],
|
|
15885
|
-
shared: refreshData.shared_skills_manifest ?? [],
|
|
15886
|
-
cacheDir: join40(config.configDir, "_skills"),
|
|
15887
|
-
fetchContents: async (hashes) => {
|
|
15888
|
-
const res = await api.post(
|
|
15889
|
-
"/host/skills/contents",
|
|
15890
|
-
{ agent_id: agent.agent_id, hashes }
|
|
15891
|
-
);
|
|
15892
|
-
return res.contents ?? [];
|
|
15893
|
-
},
|
|
15894
|
-
log
|
|
15895
|
-
});
|
|
15896
|
-
if (resolvedSkills) {
|
|
15897
|
-
refreshData.global_skills = resolvedSkills.globals;
|
|
15898
|
-
refreshData.shared_skills = resolvedSkills.shared;
|
|
15899
|
-
}
|
|
15900
|
-
}
|
|
15901
|
-
if (refreshData.integration_skills_manifest) {
|
|
15902
|
-
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
15903
|
-
manifest: refreshData.integration_skills_manifest,
|
|
15904
|
-
cacheDir: join40(config.configDir, "_skills"),
|
|
15905
|
-
fetchContents: async (hashes) => {
|
|
15906
|
-
const res = await api.post(
|
|
15907
|
-
"/host/skills/contents",
|
|
15908
|
-
{ agent_id: agent.agent_id, hashes }
|
|
15909
|
-
);
|
|
15910
|
-
return res.contents ?? [];
|
|
15911
|
-
},
|
|
15912
|
-
log
|
|
15930
|
+
const cachedRefresh = lastRefreshPayload.get(agent.agent_id);
|
|
15931
|
+
const refreshToken = refreshFetchGate.beginFetch(agent.agent_id);
|
|
15932
|
+
if (cachedRefresh !== void 0 && !refreshFetchGate.shouldFetch(agent.agent_id)) {
|
|
15933
|
+
refreshData = cachedRefresh;
|
|
15934
|
+
pollCycleFetchSkips += 1;
|
|
15935
|
+
} else {
|
|
15936
|
+
try {
|
|
15937
|
+
refreshData = await api.post("/host/refresh", {
|
|
15938
|
+
agent_id: agent.agent_id,
|
|
15939
|
+
// ENG-9585: ask for hashes instead of bodies on all three lanes. The
|
|
15940
|
+
// rationale for each flag, and for their staying three flags rather than
|
|
15941
|
+
// one, now lives with the constant — so that a new `/host/refresh` caller
|
|
15942
|
+
// inherits it instead of having to rediscover it. The manifest is
|
|
15943
|
+
// normalised back into `refreshData.knowledge` immediately below.
|
|
15944
|
+
...REFRESH_MANIFEST_FLAGS
|
|
15913
15945
|
});
|
|
15914
|
-
if (
|
|
15915
|
-
|
|
15946
|
+
if (refreshData.knowledge_manifest) {
|
|
15947
|
+
const resolved = await resolveKnowledgeFromManifest({
|
|
15948
|
+
manifest: refreshData.knowledge_manifest,
|
|
15949
|
+
cacheDir: join40(config.configDir, "_knowledge"),
|
|
15950
|
+
delivery: refreshData.agent?.knowledge_delivery ?? "both",
|
|
15951
|
+
fetchContents: async (hashes) => {
|
|
15952
|
+
const res = await api.post(
|
|
15953
|
+
"/host/knowledge/contents",
|
|
15954
|
+
{ agent_id: agent.agent_id, hashes }
|
|
15955
|
+
);
|
|
15956
|
+
return res.contents ?? [];
|
|
15957
|
+
},
|
|
15958
|
+
log
|
|
15959
|
+
});
|
|
15960
|
+
refreshData.knowledge = resolved;
|
|
15961
|
+
}
|
|
15962
|
+
if (refreshData.global_skills_manifest || refreshData.shared_skills_manifest) {
|
|
15963
|
+
const resolvedSkills = await resolveSkillsFromManifest({
|
|
15964
|
+
globals: refreshData.global_skills_manifest ?? [],
|
|
15965
|
+
shared: refreshData.shared_skills_manifest ?? [],
|
|
15966
|
+
cacheDir: join40(config.configDir, "_skills"),
|
|
15967
|
+
fetchContents: async (hashes) => {
|
|
15968
|
+
const res = await api.post(
|
|
15969
|
+
"/host/skills/contents",
|
|
15970
|
+
{ agent_id: agent.agent_id, hashes }
|
|
15971
|
+
);
|
|
15972
|
+
return res.contents ?? [];
|
|
15973
|
+
},
|
|
15974
|
+
log
|
|
15975
|
+
});
|
|
15976
|
+
if (resolvedSkills) {
|
|
15977
|
+
refreshData.global_skills = resolvedSkills.globals;
|
|
15978
|
+
refreshData.shared_skills = resolvedSkills.shared;
|
|
15979
|
+
}
|
|
15916
15980
|
}
|
|
15981
|
+
if (refreshData.integration_skills_manifest) {
|
|
15982
|
+
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
15983
|
+
manifest: refreshData.integration_skills_manifest,
|
|
15984
|
+
cacheDir: join40(config.configDir, "_skills"),
|
|
15985
|
+
fetchContents: async (hashes) => {
|
|
15986
|
+
const res = await api.post(
|
|
15987
|
+
"/host/skills/contents",
|
|
15988
|
+
{ agent_id: agent.agent_id, hashes }
|
|
15989
|
+
);
|
|
15990
|
+
return res.contents ?? [];
|
|
15991
|
+
},
|
|
15992
|
+
log
|
|
15993
|
+
});
|
|
15994
|
+
if (resolvedIntegrationSkills) {
|
|
15995
|
+
refreshData.integration_skills = resolvedIntegrationSkills;
|
|
15996
|
+
}
|
|
15997
|
+
}
|
|
15998
|
+
} catch (err) {
|
|
15999
|
+
log(`Refresh failed for '${agent.code_name}': ${err.message}`);
|
|
16000
|
+
const existing = state8.agents.find((a) => a.agentId === agent.agent_id);
|
|
16001
|
+
agentStates.push(existing ?? {
|
|
16002
|
+
agentId: agent.agent_id,
|
|
16003
|
+
codeName: agent.code_name,
|
|
16004
|
+
status: agent.status,
|
|
16005
|
+
charterVersion: "",
|
|
16006
|
+
toolsVersion: "",
|
|
16007
|
+
secretsHash: null,
|
|
16008
|
+
lastRefreshAt: null,
|
|
16009
|
+
lastProvisionAt: null,
|
|
16010
|
+
lastDriftCheckAt: null,
|
|
16011
|
+
lastSecretsProvisionAt: null,
|
|
16012
|
+
acpSessions: []
|
|
16013
|
+
});
|
|
16014
|
+
return;
|
|
15917
16015
|
}
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
agentStates.push(existing ?? {
|
|
15922
|
-
agentId: agent.agent_id,
|
|
15923
|
-
codeName: agent.code_name,
|
|
15924
|
-
status: agent.status,
|
|
15925
|
-
charterVersion: "",
|
|
15926
|
-
toolsVersion: "",
|
|
15927
|
-
secretsHash: null,
|
|
15928
|
-
lastRefreshAt: null,
|
|
15929
|
-
lastProvisionAt: null,
|
|
15930
|
-
lastDriftCheckAt: null,
|
|
15931
|
-
lastSecretsProvisionAt: null,
|
|
15932
|
-
acpSessions: []
|
|
15933
|
-
});
|
|
15934
|
-
return;
|
|
16016
|
+
lastRefreshPayload.set(agent.agent_id, refreshData);
|
|
16017
|
+
refreshFetchGate.markFetched(agent.agent_id, refreshToken);
|
|
16018
|
+
pollCycleFetches += 1;
|
|
15935
16019
|
}
|
|
15936
16020
|
if (!getAlertSlackWebhook() && refreshData.team?.settings) {
|
|
15937
16021
|
const webhook = refreshData.team.settings["alert_slack_webhook"];
|
|
@@ -16801,8 +16885,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16801
16885
|
for (const integration of integrations) {
|
|
16802
16886
|
if (integration.auth_type !== "oauth2") continue;
|
|
16803
16887
|
const expiresAt = integration.credentials?.token_expires_at;
|
|
16804
|
-
const
|
|
16805
|
-
if (!expiresAt || !
|
|
16888
|
+
const refreshToken2 = integration.credentials?.refresh_token;
|
|
16889
|
+
if (!expiresAt || !refreshToken2) continue;
|
|
16806
16890
|
const msRemaining = new Date(expiresAt).getTime() - Date.now();
|
|
16807
16891
|
if (msRemaining > 10 * 60 * 1e3) continue;
|
|
16808
16892
|
try {
|
|
@@ -17448,7 +17532,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17448
17532
|
}
|
|
17449
17533
|
const fetchTickBoard = createTickBoardFetcher(async () => {
|
|
17450
17534
|
const boardData = await api.post("/host/my-kanban", {
|
|
17451
|
-
agent_id: agent.agent_id
|
|
17535
|
+
agent_id: agent.agent_id,
|
|
17536
|
+
// ENG-9585: this is the ONLY caller that polls (every ~10s, per agent),
|
|
17537
|
+
// and it reads exactly `BoardItem`. `description` and `notes` are 57.8%
|
|
17538
|
+
// of the payload and are read here by nothing — but the `kanban_list` MCP
|
|
17539
|
+
// tool and `agt kanban` DO read them, so the route cannot simply drop
|
|
17540
|
+
// them. Asking for the lean shape is this caller saying what it needs;
|
|
17541
|
+
// every other caller keeps the full payload by default.
|
|
17542
|
+
detail: "board"
|
|
17452
17543
|
});
|
|
17453
17544
|
return (boardData.items ?? []).map(sanitizeBoardItem);
|
|
17454
17545
|
});
|
|
@@ -18933,6 +19024,7 @@ function ensureRealtimeDriftStarted(agentStates) {
|
|
|
18933
19024
|
const agent = agentStates.find((a) => a.agentId === doc.agent_id);
|
|
18934
19025
|
if (agent) {
|
|
18935
19026
|
agentState.knownVersions.delete(doc.agent_id);
|
|
19027
|
+
refreshFetchGate.forceNext(doc.agent_id);
|
|
18936
19028
|
log(`[realtime] Drift invalidated for '${agent.codeName}' \u2014 will re-provision next cycle`);
|
|
18937
19029
|
}
|
|
18938
19030
|
},
|
|
@@ -19009,7 +19101,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
19009
19101
|
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}`));
|
|
19010
19102
|
void (async () => {
|
|
19011
19103
|
try {
|
|
19012
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
19104
|
+
const { collectDiagnostics } = await import("../persistent-session-4KGDH66U.js");
|
|
19013
19105
|
await api.post("/host/heartbeat", {
|
|
19014
19106
|
host_id: hostId,
|
|
19015
19107
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -19055,7 +19147,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
19055
19147
|
}
|
|
19056
19148
|
try {
|
|
19057
19149
|
const hostId = await getHostId();
|
|
19058
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
19150
|
+
const { collectDiagnostics } = await import("../persistent-session-4KGDH66U.js");
|
|
19059
19151
|
await api.post("/host/heartbeat", {
|
|
19060
19152
|
host_id: hostId,
|
|
19061
19153
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -19096,6 +19188,8 @@ function ensureRealtimeAssignStarted(agentStates) {
|
|
|
19096
19188
|
);
|
|
19097
19189
|
},
|
|
19098
19190
|
onAssign: (payload) => {
|
|
19191
|
+
refreshFetchGate.forceNext(payload.agent_id);
|
|
19192
|
+
memoriesFetchGate.forceNext(payload.agent_id);
|
|
19099
19193
|
log(`[realtime] Agent ${payload.agent_id} assigned \u2014 will pick up next cycle`);
|
|
19100
19194
|
markAgentForFreshMemorySync(payload.agent_id);
|
|
19101
19195
|
},
|
|
@@ -19311,6 +19405,7 @@ function triggerEarlyPoll(reason) {
|
|
|
19311
19405
|
pollTimer = null;
|
|
19312
19406
|
}
|
|
19313
19407
|
log(`[realtime] Triggering early poll: ${reason}`);
|
|
19408
|
+
forceRefreshFetch();
|
|
19314
19409
|
pollTimer = setTimeout(() => {
|
|
19315
19410
|
void pollCycleAndReschedule(pollCycle, {
|
|
19316
19411
|
onError: (err) => log(`[poll-loop] early-poll cycle rejected: ${err?.message ?? String(err)}`),
|
|
@@ -19687,7 +19782,7 @@ async function processClaudePairSessions(agents) {
|
|
|
19687
19782
|
killPairSession,
|
|
19688
19783
|
pairTmuxSession,
|
|
19689
19784
|
finalizeClaudePairOnboarding
|
|
19690
|
-
} = await import("../claude-pair-runtime-
|
|
19785
|
+
} = await import("../claude-pair-runtime-AWLXOAV6.js");
|
|
19691
19786
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
19692
19787
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
19693
19788
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -20191,10 +20286,15 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
20191
20286
|
const localListHash = createHash19("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
20192
20287
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
20193
20288
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
20289
|
+
const memoriesToken = memoriesFetchGate.beginFetch(agent.agent_id);
|
|
20290
|
+
if (!force && !memoriesFetchGate.shouldFetch(agent.agent_id)) {
|
|
20291
|
+
return { status: "deferred", tombstones: null, truncated: false };
|
|
20292
|
+
}
|
|
20194
20293
|
try {
|
|
20195
20294
|
const dbMemories = await api.post("/host/memories", {
|
|
20196
20295
|
agent_id: agent.agent_id
|
|
20197
20296
|
});
|
|
20297
|
+
memoriesFetchGate.markFetched(agent.agent_id, memoriesToken);
|
|
20198
20298
|
const tombstones = Array.isArray(dbMemories.tombstones) ? dbMemories.tombstones : null;
|
|
20199
20299
|
const responseHash = createHash19("sha256").update(JSON.stringify({ m: dbMemories.memories ?? [], t: tombstones })).digest("hex").slice(0, 16);
|
|
20200
20300
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|