@integrity-labs/agt-cli 0.19.17 → 0.19.19
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-AYSU35A4.js → chunk-WQJL6EGC.js} +162 -13
- package/dist/chunk-WQJL6EGC.js.map +1 -0
- package/dist/lib/manager-worker.js +91 -37
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/telegram-channel.js +563 -9
- package/package.json +1 -1
- package/dist/chunk-AYSU35A4.js.map +0 -1
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveChannels,
|
|
23
23
|
resolveDmTarget,
|
|
24
24
|
wrapScheduledTaskPrompt
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-WQJL6EGC.js";
|
|
26
26
|
import {
|
|
27
27
|
findTaskByTemplate,
|
|
28
28
|
getProjectDir,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
} from "../chunk-3K3RO5NS.js";
|
|
53
53
|
|
|
54
54
|
// src/lib/manager-worker.ts
|
|
55
|
-
import { createHash } from "crypto";
|
|
55
|
+
import { createHash as createHash2 } from "crypto";
|
|
56
56
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, chmodSync, existsSync as existsSync3, rmSync as rmSync2, readdirSync as readdirSync2, statSync, unlinkSync, copyFileSync } from "fs";
|
|
57
57
|
import https from "https";
|
|
58
58
|
import { execFileSync as syncExecFile } from "child_process";
|
|
@@ -68,6 +68,27 @@ function decideMcpDriftAction(currentHash, knownHash) {
|
|
|
68
68
|
return { kind: "drift", previous: knownHash, current: currentHash };
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
// src/lib/integration-hash.ts
|
|
72
|
+
import { createHash } from "crypto";
|
|
73
|
+
function canonicalize(value) {
|
|
74
|
+
if (Array.isArray(value)) return value.map(canonicalize);
|
|
75
|
+
if (value && typeof value === "object") {
|
|
76
|
+
const obj = value;
|
|
77
|
+
const out = {};
|
|
78
|
+
for (const key of Object.keys(obj).sort()) {
|
|
79
|
+
out[key] = canonicalize(obj[key]);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
function computeIntegrationsHash(integrations) {
|
|
86
|
+
const payload = integrations.map(
|
|
87
|
+
(i) => `${i.definition_id}:${JSON.stringify(canonicalize(i.credentials ?? {}))}:${JSON.stringify(canonicalize(i.config ?? {}))}`
|
|
88
|
+
);
|
|
89
|
+
return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
90
|
+
}
|
|
91
|
+
|
|
71
92
|
// src/lib/stale-mcp-reaper.ts
|
|
72
93
|
import { execFileSync } from "child_process";
|
|
73
94
|
function parseEnvIntegrationsEntries(content) {
|
|
@@ -1790,6 +1811,24 @@ var config = null;
|
|
|
1790
1811
|
var running = false;
|
|
1791
1812
|
var pollTimer = null;
|
|
1792
1813
|
var PANE_TAIL_PREVIEW_LINES = 5;
|
|
1814
|
+
function extractCharterTelegramPeers(rawContent) {
|
|
1815
|
+
if (!rawContent || rawContent.length === 0) return [];
|
|
1816
|
+
try {
|
|
1817
|
+
const parsed = extractFrontmatter(rawContent);
|
|
1818
|
+
const frontmatter = parsed.frontmatter;
|
|
1819
|
+
const peers = frontmatter?.multi_agent?.telegram_peers;
|
|
1820
|
+
if (!peers || !Array.isArray(peers)) return [];
|
|
1821
|
+
const out = [];
|
|
1822
|
+
for (const p of peers) {
|
|
1823
|
+
if (p && typeof p === "object" && typeof p.code_name === "string" && typeof p.bot_id === "number" && Number.isInteger(p.bot_id) && p.bot_id > 0) {
|
|
1824
|
+
out.push({ code_name: p.code_name, bot_id: p.bot_id, agent_id: "" });
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
return out;
|
|
1828
|
+
} catch {
|
|
1829
|
+
return [];
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1793
1832
|
function truncateForLog(s) {
|
|
1794
1833
|
const lines = s.split("\n").filter((l) => l.length > 0);
|
|
1795
1834
|
return lines.slice(-PANE_TAIL_PREVIEW_LINES).map((l) => ` | ${l}`).join("\n");
|
|
@@ -1826,7 +1865,7 @@ var knownSecretsHashes = /* @__PURE__ */ new Map();
|
|
|
1826
1865
|
var runningMcpHashes = /* @__PURE__ */ new Map();
|
|
1827
1866
|
function projectMcpHash(codeName, projectDir) {
|
|
1828
1867
|
try {
|
|
1829
|
-
return
|
|
1868
|
+
return createHash2("sha256").update(readFileSync3(join4(projectDir, ".mcp.json"))).digest("hex");
|
|
1830
1869
|
} catch {
|
|
1831
1870
|
return null;
|
|
1832
1871
|
}
|
|
@@ -1929,7 +1968,7 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
1929
1968
|
var cachedFrameworkVersion = null;
|
|
1930
1969
|
var lastVersionCheckAt = 0;
|
|
1931
1970
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1932
|
-
var agtCliVersion = true ? "0.19.
|
|
1971
|
+
var agtCliVersion = true ? "0.19.19" : "dev";
|
|
1933
1972
|
function resolveBrewPath(execFileSync3) {
|
|
1934
1973
|
try {
|
|
1935
1974
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -2454,7 +2493,7 @@ function log(msg) {
|
|
|
2454
2493
|
}
|
|
2455
2494
|
}
|
|
2456
2495
|
function sha256(content) {
|
|
2457
|
-
return
|
|
2496
|
+
return createHash2("sha256").update(content, "utf8").digest("hex");
|
|
2458
2497
|
}
|
|
2459
2498
|
function hashFile(filePath) {
|
|
2460
2499
|
try {
|
|
@@ -2862,7 +2901,7 @@ async function pollCycle() {
|
|
|
2862
2901
|
claudeAuth = await detectClaudeAuth();
|
|
2863
2902
|
} catch (err) {
|
|
2864
2903
|
const errText = err instanceof Error ? err.message : String(err);
|
|
2865
|
-
const errId =
|
|
2904
|
+
const errId = createHash2("sha256").update(errText).digest("hex").slice(0, 12);
|
|
2866
2905
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
2867
2906
|
}
|
|
2868
2907
|
await api.post("/host/heartbeat", {
|
|
@@ -3408,7 +3447,13 @@ async function processAgent(agent, agentStates) {
|
|
|
3408
3447
|
activeChannels.set(channelId, /* @__PURE__ */ new Set());
|
|
3409
3448
|
}
|
|
3410
3449
|
activeChannels.get(channelId).add(agent.code_name);
|
|
3411
|
-
const
|
|
3450
|
+
const teamSettingsForHash = channelId === "telegram" ? {
|
|
3451
|
+
telegram_peer_disabled: Boolean(
|
|
3452
|
+
refreshData.team?.settings?.["telegram_peer_disabled"] ?? false
|
|
3453
|
+
)
|
|
3454
|
+
} : null;
|
|
3455
|
+
const peersForHash = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "") : null;
|
|
3456
|
+
const configHash = createHash2("sha256").update(canonicalJson({ config: entry.config, team: teamSettingsForHash, peers: peersForHash })).digest("hex");
|
|
3412
3457
|
const cacheKey = `${agent.agent_id}:${channelId}`;
|
|
3413
3458
|
let onDiskPresent = true;
|
|
3414
3459
|
try {
|
|
@@ -3428,7 +3473,16 @@ async function processAgent(agent, agentStates) {
|
|
|
3428
3473
|
}
|
|
3429
3474
|
try {
|
|
3430
3475
|
const sessionMode2 = refreshData.agent.session_mode;
|
|
3431
|
-
|
|
3476
|
+
const telegramPeerDisabled = channelId === "telegram" ? Boolean(
|
|
3477
|
+
refreshData.team?.settings?.["telegram_peer_disabled"] ?? false
|
|
3478
|
+
) : void 0;
|
|
3479
|
+
const telegramPeers = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "") : void 0;
|
|
3480
|
+
frameworkAdapter.writeChannelCredentials(
|
|
3481
|
+
agent.code_name,
|
|
3482
|
+
channelId,
|
|
3483
|
+
entry.config,
|
|
3484
|
+
{ sessionMode: sessionMode2, agentId: agent.agent_id, telegramPeerDisabled, telegramPeers }
|
|
3485
|
+
);
|
|
3432
3486
|
knownChannelConfigHashes.set(cacheKey, configHash);
|
|
3433
3487
|
saveChannelHashCache2();
|
|
3434
3488
|
log(`Channel credentials written for '${agent.code_name}/${channelId}' (reason=${reason}, hash=${configHash.slice(0, 8)}${prevHash ? `, prev=${prevHash.slice(0, 8)}` : ""})`);
|
|
@@ -3567,7 +3621,7 @@ async function processAgent(agent, agentStates) {
|
|
|
3567
3621
|
}
|
|
3568
3622
|
}
|
|
3569
3623
|
if (integrations.length > 0) {
|
|
3570
|
-
const intHash =
|
|
3624
|
+
const intHash = computeIntegrationsHash(integrations);
|
|
3571
3625
|
const prevIntHash = knownIntegrationHashes.get(agent.agent_id);
|
|
3572
3626
|
if (intHash !== prevIntHash) {
|
|
3573
3627
|
const projectDir = join4(homedir3(), ".augmented", agent.code_name, "project");
|
|
@@ -3579,7 +3633,7 @@ async function processAgent(agent, agentStates) {
|
|
|
3579
3633
|
preWriteEnv = void 0;
|
|
3580
3634
|
}
|
|
3581
3635
|
if (frameworkAdapter.writeIntegrations) {
|
|
3582
|
-
frameworkAdapter.writeIntegrations(agent.code_name, integrations);
|
|
3636
|
+
frameworkAdapter.writeIntegrations(agent.code_name, integrations, agent.agent_id);
|
|
3583
3637
|
}
|
|
3584
3638
|
log(`Integrations provisioned for '${agent.code_name}' (${integrations.length} integration(s))`);
|
|
3585
3639
|
const fw = agentFrameworkCache.get(agent.code_name) ?? "openclaw";
|
|
@@ -3635,15 +3689,15 @@ async function processAgent(agent, agentStates) {
|
|
|
3635
3689
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
3636
3690
|
}
|
|
3637
3691
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
3638
|
-
const headersHash =
|
|
3692
|
+
const headersHash = createHash2("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
3639
3693
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
3640
3694
|
}).join("\n");
|
|
3641
|
-
const mcpHash =
|
|
3695
|
+
const mcpHash = createHash2("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
3642
3696
|
const prevMcpHash = knownManagedMcpHashes.get(agent.agent_id);
|
|
3643
3697
|
if (mcpHash !== prevMcpHash) {
|
|
3644
3698
|
for (const e of desiredEntries) {
|
|
3645
3699
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
3646
|
-
const urlHash =
|
|
3700
|
+
const urlHash = createHash2("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
3647
3701
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
3648
3702
|
}
|
|
3649
3703
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
@@ -3765,7 +3819,7 @@ async function processAgent(agent, agentStates) {
|
|
|
3765
3819
|
if (frameworkAdapter.installSkillFiles) {
|
|
3766
3820
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
3767
3821
|
const installedIntegrationSkills = [];
|
|
3768
|
-
const { createHash:
|
|
3822
|
+
const { createHash: createHash3 } = await import("crypto");
|
|
3769
3823
|
const refreshAny = refreshData;
|
|
3770
3824
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
3771
3825
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -3794,7 +3848,7 @@ async function processAgent(agent, agentStates) {
|
|
|
3794
3848
|
)
|
|
3795
3849
|
}));
|
|
3796
3850
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
3797
|
-
const contentHash =
|
|
3851
|
+
const contentHash = createHash3("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
3798
3852
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
3799
3853
|
if (knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
3800
3854
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -3863,7 +3917,7 @@ async function processAgent(agent, agentStates) {
|
|
|
3863
3917
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
3864
3918
|
if (!slug) continue;
|
|
3865
3919
|
try {
|
|
3866
|
-
const scriptHash =
|
|
3920
|
+
const scriptHash = createHash3("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
3867
3921
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
3868
3922
|
if (knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
3869
3923
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -3878,9 +3932,9 @@ async function processAgent(agent, agentStates) {
|
|
|
3878
3932
|
} else if (result.timedOut) {
|
|
3879
3933
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
3880
3934
|
} else {
|
|
3881
|
-
const stderrHash =
|
|
3935
|
+
const stderrHash = createHash3("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
3882
3936
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
3883
|
-
const missingCmdHash = missingCmd ?
|
|
3937
|
+
const missingCmdHash = missingCmd ? createHash3("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
3884
3938
|
log(
|
|
3885
3939
|
`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}]`
|
|
3886
3940
|
);
|
|
@@ -3939,10 +3993,10 @@ async function processAgent(agent, agentStates) {
|
|
|
3939
3993
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
3940
3994
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
3941
3995
|
} else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
|
|
3942
|
-
const stableTasksHash =
|
|
3943
|
-
const boardHash = boardItems.length > 0 ?
|
|
3996
|
+
const stableTasksHash = createHash2("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
3997
|
+
const boardHash = boardItems.length > 0 ? createHash2("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
3944
3998
|
const resolvedModels = resolveModelChain(refreshData);
|
|
3945
|
-
const modelsHash =
|
|
3999
|
+
const modelsHash = createHash2("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
3946
4000
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
3947
4001
|
const prevTasksHash = knownTasksHashes.get(agent.agent_id);
|
|
3948
4002
|
if (combinedHash !== prevTasksHash) {
|
|
@@ -4307,10 +4361,10 @@ var MAX_CLAUDE_CONCURRENCY = 2;
|
|
|
4307
4361
|
var claudeSchedulerStates = /* @__PURE__ */ new Map();
|
|
4308
4362
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData) {
|
|
4309
4363
|
const codeName = agent.code_name;
|
|
4310
|
-
const stableTasksHash =
|
|
4311
|
-
const boardHash = boardItems.length > 0 ?
|
|
4364
|
+
const stableTasksHash = createHash2("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
4365
|
+
const boardHash = boardItems.length > 0 ? createHash2("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
4312
4366
|
const resolvedModels = resolveModelChain(refreshData);
|
|
4313
|
-
const modelsHash =
|
|
4367
|
+
const modelsHash = createHash2("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
4314
4368
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
4315
4369
|
const prevHash = knownTasksHashes.get(agent.agent_id);
|
|
4316
4370
|
if (combinedHash !== prevHash) {
|
|
@@ -4388,7 +4442,7 @@ async function startRun(opts) {
|
|
|
4388
4442
|
return { run_id: res.run_id ?? null, kanban_item_id: res.kanban_item_id ?? null };
|
|
4389
4443
|
} catch (err) {
|
|
4390
4444
|
const errText = err instanceof Error ? err.message : String(err);
|
|
4391
|
-
const errId =
|
|
4445
|
+
const errId = createHash2("sha256").update(errText).digest("hex").slice(0, 12);
|
|
4392
4446
|
log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
|
|
4393
4447
|
return { run_id: null, kanban_item_id: null };
|
|
4394
4448
|
}
|
|
@@ -4405,7 +4459,7 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
4405
4459
|
});
|
|
4406
4460
|
} catch (err) {
|
|
4407
4461
|
const errText = err instanceof Error ? err.message : String(err);
|
|
4408
|
-
const errId =
|
|
4462
|
+
const errId = createHash2("sha256").update(errText).digest("hex").slice(0, 12);
|
|
4409
4463
|
log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
|
|
4410
4464
|
}
|
|
4411
4465
|
}
|
|
@@ -4422,7 +4476,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
4422
4476
|
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
4423
4477
|
} catch (err) {
|
|
4424
4478
|
const errText = err instanceof Error ? err.message : String(err);
|
|
4425
|
-
const errId =
|
|
4479
|
+
const errId = createHash2("sha256").update(errText).digest("hex").slice(0, 12);
|
|
4426
4480
|
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
4427
4481
|
return [];
|
|
4428
4482
|
}
|
|
@@ -4556,10 +4610,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
4556
4610
|
const classification = classifyOutput(rawOutput);
|
|
4557
4611
|
if (classification.action === "suppress") {
|
|
4558
4612
|
const trimmed = (rawOutput ?? "").trim();
|
|
4559
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
4613
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash2("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
4560
4614
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
4561
4615
|
if (classification.suppressedNotes) {
|
|
4562
|
-
const notesHash =
|
|
4616
|
+
const notesHash = createHash2("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
4563
4617
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
4564
4618
|
}
|
|
4565
4619
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -4734,7 +4788,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
4734
4788
|
const ctx = getLastFailureContext(codeName);
|
|
4735
4789
|
const recovery = prepareForRespawn(codeName);
|
|
4736
4790
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
4737
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
4791
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
4738
4792
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
4739
4793
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
4740
4794
|
log(
|
|
@@ -4772,7 +4826,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash("sha256").u
|
|
|
4772
4826
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
4773
4827
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
4774
4828
|
}
|
|
4775
|
-
const stableTasksHash =
|
|
4829
|
+
const stableTasksHash = createHash2("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
4776
4830
|
const prevHash = knownTasksHashes.get(agent.agent_id);
|
|
4777
4831
|
if (stableTasksHash !== prevHash) {
|
|
4778
4832
|
const taskInputs = tasks.map((t) => ({
|
|
@@ -5245,7 +5299,7 @@ ${escapeXml(msg.content)}
|
|
|
5245
5299
|
log(`[direct-chat] Reply sent for '${agent.codeName}'`);
|
|
5246
5300
|
} catch (err) {
|
|
5247
5301
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
5248
|
-
const errorId =
|
|
5302
|
+
const errorId = createHash2("sha256").update(errMsg).digest("hex").slice(0, 12);
|
|
5249
5303
|
log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
|
|
5250
5304
|
try {
|
|
5251
5305
|
await api.post("/host/direct-chat/reply", {
|
|
@@ -6395,7 +6449,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
6395
6449
|
if (!file.endsWith(".md")) continue;
|
|
6396
6450
|
try {
|
|
6397
6451
|
const raw = readFileSync3(join4(memoryDir, file), "utf-8");
|
|
6398
|
-
const fileHash =
|
|
6452
|
+
const fileHash = createHash2("sha256").update(raw).digest("hex").slice(0, 16);
|
|
6399
6453
|
currentHashes.set(file, fileHash);
|
|
6400
6454
|
if (prevHashes.get(file) === fileHash) continue;
|
|
6401
6455
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -6433,14 +6487,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
6433
6487
|
}
|
|
6434
6488
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
6435
6489
|
const localFiles = existsSync3(memoryDir) ? readdirSync2(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
6436
|
-
const localListHash =
|
|
6490
|
+
const localListHash = createHash2("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
6437
6491
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
6438
6492
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
6439
6493
|
try {
|
|
6440
6494
|
const dbMemories = await api.post("/host/memories", {
|
|
6441
6495
|
agent_id: agent.agent_id
|
|
6442
6496
|
});
|
|
6443
|
-
const responseHash =
|
|
6497
|
+
const responseHash = createHash2("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
6444
6498
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
6445
6499
|
return true;
|
|
6446
6500
|
}
|
|
@@ -6479,7 +6533,7 @@ ${mem.content}
|
|
|
6479
6533
|
}
|
|
6480
6534
|
if (written > 0 || overwritten > 0) {
|
|
6481
6535
|
const updatedFiles = readdirSync2(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
6482
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
6536
|
+
lastLocalFileHash.set(agent.agent_id, createHash2("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
6483
6537
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
6484
6538
|
}
|
|
6485
6539
|
}
|
|
@@ -6743,7 +6797,7 @@ function deployMcpAssets() {
|
|
|
6743
6797
|
const fileHash = (p) => {
|
|
6744
6798
|
try {
|
|
6745
6799
|
if (!existsSync3(p)) return null;
|
|
6746
|
-
return
|
|
6800
|
+
return createHash2("sha256").update(readFileSync3(p)).digest("hex");
|
|
6747
6801
|
} catch {
|
|
6748
6802
|
return null;
|
|
6749
6803
|
}
|