@integrity-labs/agt-cli 0.28.342 → 0.28.343
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-I3YS5WFV.js → chunk-EP6E6CIY.js} +3 -3
- package/dist/chunk-EP6E6CIY.js.map +1 -0
- package/dist/{chunk-V2FVNWF2.js → chunk-GAYSFNTX.js} +6 -3
- package/dist/{chunk-V2FVNWF2.js.map → chunk-GAYSFNTX.js.map} +1 -1
- package/dist/lib/manager-worker.js +129 -27
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{claude-scheduler-FATCLHDM.js → scheduler-engine-HYOOQV4A.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-I3YS5WFV.js.map +0 -1
- /package/dist/{claude-scheduler-FATCLHDM.js.map → scheduler-engine-HYOOQV4A.js.map} +0 -0
|
@@ -46,14 +46,14 @@ import {
|
|
|
46
46
|
resolveEffectivePinRaw,
|
|
47
47
|
safeWriteJsonAtomic,
|
|
48
48
|
setConfigHash
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-GAYSFNTX.js";
|
|
50
50
|
import {
|
|
51
51
|
getProjectDir as getProjectDir2,
|
|
52
52
|
getReadyTasks,
|
|
53
53
|
loadSchedulerState,
|
|
54
54
|
markTaskFired,
|
|
55
55
|
syncTasksToScheduler
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-EP6E6CIY.js";
|
|
57
57
|
import {
|
|
58
58
|
AnchorSessionClient,
|
|
59
59
|
CONVERSATION_FAILURE_CATEGORIES,
|
|
@@ -141,7 +141,7 @@ import {
|
|
|
141
141
|
} from "../chunk-XWVM4KPK.js";
|
|
142
142
|
|
|
143
143
|
// src/lib/manager-worker.ts
|
|
144
|
-
import { createHash as
|
|
144
|
+
import { createHash as createHash13 } from "crypto";
|
|
145
145
|
import { readFileSync as readFileSync18, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, existsSync as existsSync12, rmSync as rmSync4, readdirSync as readdirSync5, statSync as statSync4, copyFileSync } from "fs";
|
|
146
146
|
import { execFileSync as syncExecFile } from "child_process";
|
|
147
147
|
import { join as join21, dirname as dirname6 } from "path";
|
|
@@ -6712,6 +6712,98 @@ function stopAllOpencodeSlackIngests(log2) {
|
|
|
6712
6712
|
for (const codeName of [...ingests.keys()]) stopOpencodeSlackIngest(codeName, log2);
|
|
6713
6713
|
}
|
|
6714
6714
|
|
|
6715
|
+
// src/lib/manager/opencode-scheduler.ts
|
|
6716
|
+
import { createHash as createHash12 } from "crypto";
|
|
6717
|
+
var MAX_OPENCODE_SCHED_CONCURRENCY = 2;
|
|
6718
|
+
var opencodeSchedulerStates = /* @__PURE__ */ new Map();
|
|
6719
|
+
var inFlightOpencodeTasks = /* @__PURE__ */ new Set();
|
|
6720
|
+
var opencodeTaskConcurrency = /* @__PURE__ */ new Map();
|
|
6721
|
+
var knownOpencodeTaskHashes = /* @__PURE__ */ new Map();
|
|
6722
|
+
function shouldDeliver(task, reply) {
|
|
6723
|
+
if ((task.deliveryPolicy ?? "always") === "never") return false;
|
|
6724
|
+
if (task.deliveryMode === "none") return false;
|
|
6725
|
+
if (task.deliveryTo == null) return false;
|
|
6726
|
+
return typeof reply === "string" && reply.trim().length > 0;
|
|
6727
|
+
}
|
|
6728
|
+
async function syncAndCheckOpencodeScheduler(agent, tasks, refreshData) {
|
|
6729
|
+
const codeName = agent.code_name;
|
|
6730
|
+
const tasksHash = createHash12("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
6731
|
+
if (knownOpencodeTaskHashes.get(agent.agent_id) !== tasksHash) {
|
|
6732
|
+
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
6733
|
+
const state8 = syncTasksToScheduler(codeName, agent.agent_id, taskInputs);
|
|
6734
|
+
opencodeSchedulerStates.set(codeName, state8);
|
|
6735
|
+
knownOpencodeTaskHashes.set(agent.agent_id, tasksHash);
|
|
6736
|
+
log(`[opencode-scheduler] tasks synced for '${codeName}' (${taskInputs.length} task(s))`);
|
|
6737
|
+
}
|
|
6738
|
+
if (!opencodeSchedulerStates.has(codeName)) {
|
|
6739
|
+
opencodeSchedulerStates.set(codeName, loadSchedulerState(codeName));
|
|
6740
|
+
}
|
|
6741
|
+
const state7 = opencodeSchedulerStates.get(codeName);
|
|
6742
|
+
const ready = getReadyTasks(state7, inFlightOpencodeTasks);
|
|
6743
|
+
if (ready.length === 0) return;
|
|
6744
|
+
if (!isOpencodeSessionHealthy(codeName)) {
|
|
6745
|
+
log(`[opencode-scheduler] '${codeName}' has ${ready.length} due task(s) but no healthy serve yet - deferring`);
|
|
6746
|
+
return;
|
|
6747
|
+
}
|
|
6748
|
+
for (const task of ready) {
|
|
6749
|
+
if ((opencodeTaskConcurrency.get(codeName) ?? 0) >= MAX_OPENCODE_SCHED_CONCURRENCY) break;
|
|
6750
|
+
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
6751
|
+
opencodeSchedulerStates.set(codeName, markTaskFired(codeName, task.taskId, "ok"));
|
|
6752
|
+
continue;
|
|
6753
|
+
}
|
|
6754
|
+
inFlightOpencodeTasks.add(task.taskId);
|
|
6755
|
+
opencodeTaskConcurrency.set(codeName, (opencodeTaskConcurrency.get(codeName) ?? 0) + 1);
|
|
6756
|
+
void fireOpencodeScheduledTask(agent, task).finally(() => {
|
|
6757
|
+
inFlightOpencodeTasks.delete(task.taskId);
|
|
6758
|
+
opencodeTaskConcurrency.set(
|
|
6759
|
+
codeName,
|
|
6760
|
+
Math.max(0, (opencodeTaskConcurrency.get(codeName) ?? 1) - 1)
|
|
6761
|
+
);
|
|
6762
|
+
});
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
async function fireOpencodeScheduledTask(agent, task) {
|
|
6766
|
+
const codeName = agent.code_name;
|
|
6767
|
+
const conversationKey = `scheduled:${task.taskId}:${Date.now()}`;
|
|
6768
|
+
try {
|
|
6769
|
+
const result = await injectOpencodeMessage(
|
|
6770
|
+
codeName,
|
|
6771
|
+
{
|
|
6772
|
+
channelId: "scheduler",
|
|
6773
|
+
conversationKey,
|
|
6774
|
+
senderId: "scheduler",
|
|
6775
|
+
text: task.prompt,
|
|
6776
|
+
meta: {
|
|
6777
|
+
source: "scheduled_task",
|
|
6778
|
+
task: task.name,
|
|
6779
|
+
// The manager delivers the output; the agent isn't replying into a
|
|
6780
|
+
// channel thread itself, so it must not try to.
|
|
6781
|
+
requires_reply: "false"
|
|
6782
|
+
}
|
|
6783
|
+
},
|
|
6784
|
+
{ awaitReply: true }
|
|
6785
|
+
);
|
|
6786
|
+
if (result.status === "declined") {
|
|
6787
|
+
log(`[opencode-scheduler] task '${task.name}' for '${codeName}' declined: ${result.reason}`);
|
|
6788
|
+
return;
|
|
6789
|
+
}
|
|
6790
|
+
const reply = result.status === "replied" ? result.reply : null;
|
|
6791
|
+
if (shouldDeliver(task, reply)) {
|
|
6792
|
+
try {
|
|
6793
|
+
await deliverScheduledTaskOutput(codeName, agent.agent_id, task.deliveryTo, reply, task.taskId);
|
|
6794
|
+
} catch (err) {
|
|
6795
|
+
log(`[opencode-scheduler] delivery failed for task '${task.name}' on '${codeName}': ${err.message}`);
|
|
6796
|
+
}
|
|
6797
|
+
} else if ((task.deliveryPolicy ?? "always") !== "never" && task.deliveryTo != null) {
|
|
6798
|
+
log(`[opencode-scheduler] task '${task.name}' for '${codeName}' produced no output to deliver`);
|
|
6799
|
+
}
|
|
6800
|
+
opencodeSchedulerStates.set(codeName, markTaskFired(codeName, task.taskId, "ok"));
|
|
6801
|
+
} catch (err) {
|
|
6802
|
+
log(`[opencode-scheduler] task '${task.name}' for '${codeName}' failed: ${err.message}`);
|
|
6803
|
+
opencodeSchedulerStates.set(codeName, markTaskFired(codeName, task.taskId, "error"));
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6806
|
+
|
|
6715
6807
|
// src/lib/wedge-detection.ts
|
|
6716
6808
|
var DEFAULTS = {
|
|
6717
6809
|
inboundWaitSeconds: 120,
|
|
@@ -8122,7 +8214,7 @@ var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
|
8122
8214
|
function projectMcpHash(_codeName, projectDir) {
|
|
8123
8215
|
try {
|
|
8124
8216
|
const raw = readFileSync18(join21(projectDir, ".mcp.json"), "utf-8");
|
|
8125
|
-
return
|
|
8217
|
+
return createHash13("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
8126
8218
|
} catch {
|
|
8127
8219
|
return null;
|
|
8128
8220
|
}
|
|
@@ -8468,7 +8560,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
8468
8560
|
var lastVersionCheckAt = 0;
|
|
8469
8561
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
8470
8562
|
var lastResponsivenessProbeAt = 0;
|
|
8471
|
-
var agtCliVersion = true ? "0.28.
|
|
8563
|
+
var agtCliVersion = true ? "0.28.343" : "dev";
|
|
8472
8564
|
function resolveBrewPath(execFileSync2) {
|
|
8473
8565
|
try {
|
|
8474
8566
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9562,7 +9654,7 @@ async function pollCycle() {
|
|
|
9562
9654
|
claudeAuth = await detectClaudeAuth();
|
|
9563
9655
|
} catch (err) {
|
|
9564
9656
|
const errText = err instanceof Error ? err.message : String(err);
|
|
9565
|
-
const errId =
|
|
9657
|
+
const errId = createHash13("sha256").update(errText).digest("hex").slice(0, 12);
|
|
9566
9658
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
9567
9659
|
}
|
|
9568
9660
|
const hostHasClaudeCode = state6.agents.some(
|
|
@@ -9720,7 +9812,7 @@ async function pollCycle() {
|
|
|
9720
9812
|
livePendingInboundOldestAgeSeconds,
|
|
9721
9813
|
parkPendingInbound
|
|
9722
9814
|
} = await import("../responsiveness-probe-XLS2FXIX.js");
|
|
9723
|
-
const { getProjectDir: wedgeProjectDir } = await import("../
|
|
9815
|
+
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-HYOOQV4A.js");
|
|
9724
9816
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
9725
9817
|
const liveAgents = agentState.persistentSessionAgents;
|
|
9726
9818
|
for (const tracked of consecutiveWedgeCycles.keys()) {
|
|
@@ -10982,7 +11074,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10982
11074
|
const behaviourSubset = extractMsTeamsBehaviourSubset(
|
|
10983
11075
|
msteamsEntry?.config
|
|
10984
11076
|
);
|
|
10985
|
-
const behaviourHash =
|
|
11077
|
+
const behaviourHash = createHash13("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
|
|
10986
11078
|
const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
|
|
10987
11079
|
const msteamsBehaviourRestrictive = isMsTeamsBehaviourRestrictive(behaviourSubset);
|
|
10988
11080
|
const behaviourDecision = decideSenderPolicyRestart({
|
|
@@ -11038,7 +11130,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11038
11130
|
const slackBehaviourSubset = extractSlackBehaviourSubset(
|
|
11039
11131
|
slackEntry?.config
|
|
11040
11132
|
);
|
|
11041
|
-
const slackBehaviourHash =
|
|
11133
|
+
const slackBehaviourHash = createHash13("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
|
|
11042
11134
|
const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
|
|
11043
11135
|
const slackBehaviourRestrictive = isSlackBehaviourRestrictive(slackBehaviourSubset);
|
|
11044
11136
|
const slackBehaviourDecision = decideSenderPolicyRestart({
|
|
@@ -11388,10 +11480,10 @@ async function processAgent(agent, agentStates) {
|
|
|
11388
11480
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
11389
11481
|
}
|
|
11390
11482
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
11391
|
-
const headersHash =
|
|
11483
|
+
const headersHash = createHash13("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
11392
11484
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
11393
11485
|
}).join("\n");
|
|
11394
|
-
const mcpHash =
|
|
11486
|
+
const mcpHash = createHash13("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
11395
11487
|
const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
|
|
11396
11488
|
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
11397
11489
|
const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
|
|
@@ -11406,7 +11498,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11406
11498
|
if (mcpHash !== prevMcpHash) {
|
|
11407
11499
|
for (const e of desiredEntries) {
|
|
11408
11500
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
11409
|
-
const urlHash =
|
|
11501
|
+
const urlHash = createHash13("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
11410
11502
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
11411
11503
|
}
|
|
11412
11504
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
@@ -11515,7 +11607,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11515
11607
|
if (frameworkAdapter.installSkillFiles) {
|
|
11516
11608
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
11517
11609
|
const installedIntegrationSkills = [];
|
|
11518
|
-
const { createHash:
|
|
11610
|
+
const { createHash: createHash14 } = await import("crypto");
|
|
11519
11611
|
const refreshAny = refreshData;
|
|
11520
11612
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
11521
11613
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -11544,7 +11636,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11544
11636
|
)
|
|
11545
11637
|
}));
|
|
11546
11638
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
11547
|
-
const contentHash =
|
|
11639
|
+
const contentHash = createHash14("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
11548
11640
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
11549
11641
|
if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
11550
11642
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -11611,7 +11703,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11611
11703
|
const plan = planGlobalSkillSync(
|
|
11612
11704
|
[...globalSkillsPayload ?? [], ...sharedSkillsPayload ?? []],
|
|
11613
11705
|
prevIds,
|
|
11614
|
-
(content) =>
|
|
11706
|
+
(content) => createHash14("sha256").update(content).digest("hex").slice(0, 12),
|
|
11615
11707
|
(skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`),
|
|
11616
11708
|
{ desiredResolved }
|
|
11617
11709
|
);
|
|
@@ -11662,7 +11754,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11662
11754
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
11663
11755
|
if (!slug) continue;
|
|
11664
11756
|
try {
|
|
11665
|
-
const scriptHash =
|
|
11757
|
+
const scriptHash = createHash14("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
11666
11758
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
11667
11759
|
if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
11668
11760
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -11677,9 +11769,9 @@ async function processAgent(agent, agentStates) {
|
|
|
11677
11769
|
} else if (result.timedOut) {
|
|
11678
11770
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
11679
11771
|
} else {
|
|
11680
|
-
const stderrHash =
|
|
11772
|
+
const stderrHash = createHash14("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
11681
11773
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
11682
|
-
const missingCmdHash = missingCmd ?
|
|
11774
|
+
const missingCmdHash = missingCmd ? createHash14("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
11683
11775
|
log(
|
|
11684
11776
|
`Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
|
|
11685
11777
|
);
|
|
@@ -11983,6 +12075,9 @@ async function processAgent(agent, agentStates) {
|
|
|
11983
12075
|
log(`[mcp-presence-reaper] presence check failed for '${agent.code_name}': ${err.message}`);
|
|
11984
12076
|
}
|
|
11985
12077
|
}
|
|
12078
|
+
if (agentFw === "opencode" && tasks.length > 0) {
|
|
12079
|
+
await syncAndCheckOpencodeScheduler(agent, tasks, refreshData);
|
|
12080
|
+
}
|
|
11986
12081
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
11987
12082
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
11988
12083
|
}
|
|
@@ -12448,7 +12543,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
12448
12543
|
const ctx = getLastFailureContext(codeName);
|
|
12449
12544
|
const recovery = prepareForRespawn(codeName);
|
|
12450
12545
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
12451
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
12546
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash13("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
12452
12547
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
12453
12548
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
12454
12549
|
log(
|
|
@@ -12462,7 +12557,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash12("sha256")
|
|
|
12462
12557
|
);
|
|
12463
12558
|
getHostId().then((hostId) => {
|
|
12464
12559
|
if (!hostId) return;
|
|
12465
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
12560
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash13("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
12466
12561
|
return api.post("/host/events", {
|
|
12467
12562
|
host_id: hostId,
|
|
12468
12563
|
agent_code_name: codeName,
|
|
@@ -12611,7 +12706,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash12("sha256")
|
|
|
12611
12706
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
12612
12707
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
12613
12708
|
}
|
|
12614
|
-
const stableTasksHash =
|
|
12709
|
+
const stableTasksHash = createHash13("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
12615
12710
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
12616
12711
|
if (stableTasksHash !== prevHash) {
|
|
12617
12712
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
@@ -13550,8 +13645,15 @@ function generateArtifacts(agent, refreshData, adapter) {
|
|
|
13550
13645
|
log(
|
|
13551
13646
|
`[provision/active-tasks] agent=${agent.code_name} count=${activeTasksFromRefresh.length} estimated_tokens=${activeTasksTokens}`
|
|
13552
13647
|
);
|
|
13648
|
+
const provisionAgent = (() => {
|
|
13649
|
+
const rawAgent = refreshData.agent;
|
|
13650
|
+
if (rawAgent?.["framework"] !== "opencode") return rawAgent;
|
|
13651
|
+
const hostOverride = process.env["AGT_OPENCODE_MODEL"]?.trim();
|
|
13652
|
+
const resolved = hostOverride || resolveModelChain(refreshData).primary || rawAgent?.["primary_model"];
|
|
13653
|
+
return resolved ? { ...rawAgent, primary_model: resolved } : rawAgent;
|
|
13654
|
+
})();
|
|
13553
13655
|
const provisionInput = {
|
|
13554
|
-
agent:
|
|
13656
|
+
agent: provisionAgent,
|
|
13555
13657
|
charterFrontmatter,
|
|
13556
13658
|
charterContent,
|
|
13557
13659
|
toolsFrontmatter,
|
|
@@ -13639,7 +13741,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
13639
13741
|
if (!file.endsWith(".md")) continue;
|
|
13640
13742
|
try {
|
|
13641
13743
|
const raw = readFileSync18(join21(memoryDir, file), "utf-8");
|
|
13642
|
-
const fileHash =
|
|
13744
|
+
const fileHash = createHash13("sha256").update(raw).digest("hex").slice(0, 16);
|
|
13643
13745
|
currentHashes.set(file, fileHash);
|
|
13644
13746
|
if (prevHashes.get(file) === fileHash) continue;
|
|
13645
13747
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -13677,14 +13779,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
13677
13779
|
}
|
|
13678
13780
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
13679
13781
|
const localFiles = existsSync12(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
13680
|
-
const localListHash =
|
|
13782
|
+
const localListHash = createHash13("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
13681
13783
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
13682
13784
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
13683
13785
|
try {
|
|
13684
13786
|
const dbMemories = await api.post("/host/memories", {
|
|
13685
13787
|
agent_id: agent.agent_id
|
|
13686
13788
|
});
|
|
13687
|
-
const responseHash =
|
|
13789
|
+
const responseHash = createHash13("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
13688
13790
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
13689
13791
|
return true;
|
|
13690
13792
|
}
|
|
@@ -13723,7 +13825,7 @@ ${mem.content}
|
|
|
13723
13825
|
}
|
|
13724
13826
|
if (written > 0 || overwritten > 0) {
|
|
13725
13827
|
const updatedFiles = readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
13726
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
13828
|
+
lastLocalFileHash.set(agent.agent_id, createHash13("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
13727
13829
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
13728
13830
|
}
|
|
13729
13831
|
}
|
|
@@ -14139,7 +14241,7 @@ function deployMcpAssets() {
|
|
|
14139
14241
|
const fileHash = (p) => {
|
|
14140
14242
|
try {
|
|
14141
14243
|
if (!existsSync12(p)) return null;
|
|
14142
|
-
return
|
|
14244
|
+
return createHash13("sha256").update(readFileSync18(p)).digest("hex");
|
|
14143
14245
|
} catch {
|
|
14144
14246
|
return null;
|
|
14145
14247
|
}
|