@kanadego/dsh-heartbeat 1.9.1 → 1.9.2
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/README.md +27 -5
- package/cordis.patch.yml +18 -39
- package/dist/{chunk-BQCXYE7N.js → chunk-3MDBU6WY.js} +2 -2
- package/dist/{chunk-HT57FOEF.js → chunk-AJ5HLAL7.js} +34 -11
- package/dist/chunk-AJ5HLAL7.js.map +1 -0
- package/dist/{chunk-OYVNWB5G.js → chunk-CUOSICYJ.js} +2 -2
- package/dist/{chunk-WRJCINZ7.js → chunk-IG6YMUHW.js} +4 -4
- package/dist/{chunk-KOOQOMQY.js → chunk-JDH2LDFS.js} +2 -2
- package/dist/chunk-K5Y6JP2B.js +399 -0
- package/dist/chunk-K5Y6JP2B.js.map +1 -0
- package/dist/{chunk-QOQ7EPZZ.js → chunk-KB5SMG3F.js} +3 -3
- package/dist/{chunk-2NB4QILF.js → chunk-XFNCTOW7.js} +2 -2
- package/dist/cli/index.js +9 -9
- package/dist/{inbox-JLT5G7TL.js → inbox-P26DDMWC.js} +3 -3
- package/dist/index.d.ts +33 -0
- package/dist/index.js +104 -20
- package/dist/index.js.map +1 -1
- package/dist/{migrate-WDVFHUP7.js → migrate-D4VKAKYT.js} +3 -3
- package/dist/{orchestrator-2ZLU7RGE.js → orchestrator-EUTZ3KG6.js} +10 -8
- package/dist/{pool-B34NTH6D.js → pool-UTXQJJ5C.js} +3 -3
- package/dist/{snapshot-JQDJ346Z.js → snapshot-K5VHETTK.js} +4 -4
- package/package.json +83 -83
- package/dist/chunk-7TW6DD6Q.js +0 -208
- package/dist/chunk-7TW6DD6Q.js.map +0 -1
- package/dist/chunk-HT57FOEF.js.map +0 -1
- /package/dist/{chunk-BQCXYE7N.js.map → chunk-3MDBU6WY.js.map} +0 -0
- /package/dist/{chunk-OYVNWB5G.js.map → chunk-CUOSICYJ.js.map} +0 -0
- /package/dist/{chunk-WRJCINZ7.js.map → chunk-IG6YMUHW.js.map} +0 -0
- /package/dist/{chunk-KOOQOMQY.js.map → chunk-JDH2LDFS.js.map} +0 -0
- /package/dist/{chunk-QOQ7EPZZ.js.map → chunk-KB5SMG3F.js.map} +0 -0
- /package/dist/{chunk-2NB4QILF.js.map → chunk-XFNCTOW7.js.map} +0 -0
- /package/dist/{inbox-JLT5G7TL.js.map → inbox-P26DDMWC.js.map} +0 -0
- /package/dist/{migrate-WDVFHUP7.js.map → migrate-D4VKAKYT.js.map} +0 -0
- /package/dist/{orchestrator-2ZLU7RGE.js.map → orchestrator-EUTZ3KG6.js.map} +0 -0
- /package/dist/{pool-B34NTH6D.js.map → pool-UTXQJJ5C.js.map} +0 -0
- /package/dist/{snapshot-JQDJ346Z.js.map → snapshot-K5VHETTK.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -368,6 +368,29 @@ interface PathGuard {
|
|
|
368
368
|
check(target: string): string | null;
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
+
type RelocateResult = {
|
|
372
|
+
action: 'relocated';
|
|
373
|
+
/** Package-local tree the data came from (now deleted). */
|
|
374
|
+
srcDir: string;
|
|
375
|
+
dstDir: string;
|
|
376
|
+
backupDir: string;
|
|
377
|
+
files: number;
|
|
378
|
+
bytes: number;
|
|
379
|
+
/** Plaintext JSON/JSONL that does not parse (verified byte-identical). */
|
|
380
|
+
warnings: string[];
|
|
381
|
+
/** Paths that could not be deleted after the move (cosmetic leftovers). */
|
|
382
|
+
leftovers: string[];
|
|
383
|
+
} | {
|
|
384
|
+
action: 'skipped';
|
|
385
|
+
reason: 'source-missing' | 'no-payload' | 'destination-exists';
|
|
386
|
+
} | {
|
|
387
|
+
action: 'failed';
|
|
388
|
+
stage: 'backup' | 'copy' | 'verify' | 'commit';
|
|
389
|
+
problems: string[];
|
|
390
|
+
/** Null when the backup itself could not be created. */
|
|
391
|
+
backupDir: string | null;
|
|
392
|
+
};
|
|
393
|
+
|
|
371
394
|
interface WorkspacePaths {
|
|
372
395
|
/** Guard boundary and the only writable tree at runtime. */
|
|
373
396
|
dataDir: string;
|
|
@@ -379,6 +402,11 @@ interface WorkspacePaths {
|
|
|
379
402
|
packageRoot: string;
|
|
380
403
|
configDir: string;
|
|
381
404
|
assetsDir: string;
|
|
405
|
+
/**
|
|
406
|
+
* Set only when a legacy package-local data dir was found: the outcome of
|
|
407
|
+
* the one-time relocation. Absent for explicit dirs and fresh installs.
|
|
408
|
+
*/
|
|
409
|
+
relocation?: RelocateResult;
|
|
382
410
|
}
|
|
383
411
|
|
|
384
412
|
interface OrchestratorDeps {
|
|
@@ -403,6 +431,11 @@ interface OrchestratorDeps {
|
|
|
403
431
|
policy: Policy;
|
|
404
432
|
/** Agent preset the heartbeat agent joins (composition entry `agentPreset`). */
|
|
405
433
|
agentPreset?: string;
|
|
434
|
+
/** Awaited right before the preset mount: the plugin registers its preset at
|
|
435
|
+
* runtime (issue #2 — the composition must not name a host package), and the
|
|
436
|
+
* mount must not race that registration. Resolves at once when registration
|
|
437
|
+
* was skipped or the host has no registry API. */
|
|
438
|
+
presetRegistration?: () => Promise<void>;
|
|
406
439
|
/** Extra tool names the engine-room allow-list should include (config
|
|
407
440
|
* `extraTools`, comma-separated in the composition entry). Only names that
|
|
408
441
|
* actually exist in the global layer are applied. */
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
sessionEventCount,
|
|
28
28
|
sessionEvents,
|
|
29
29
|
startOrchestrator
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-AJ5HLAL7.js";
|
|
31
31
|
import {
|
|
32
32
|
appendEntry,
|
|
33
33
|
ledgerFilePath,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
readLedger,
|
|
37
37
|
readWeeklyReport,
|
|
38
38
|
scanPending
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-IG6YMUHW.js";
|
|
40
40
|
import {
|
|
41
41
|
getRuntime,
|
|
42
42
|
setRuntime
|
|
@@ -49,19 +49,19 @@ import {
|
|
|
49
49
|
loadPool,
|
|
50
50
|
restoreSeed,
|
|
51
51
|
seedsFilePath
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import "./chunk-
|
|
52
|
+
} from "./chunk-JDH2LDFS.js";
|
|
53
|
+
import "./chunk-3MDBU6WY.js";
|
|
54
54
|
import "./chunk-IV2ZWQA3.js";
|
|
55
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-KB5SMG3F.js";
|
|
56
56
|
import {
|
|
57
57
|
appendAuditLine,
|
|
58
58
|
loadProfile,
|
|
59
59
|
profileFilePath
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-CUOSICYJ.js";
|
|
61
61
|
import {
|
|
62
62
|
initWorkspace,
|
|
63
63
|
writeText
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-K5Y6JP2B.js";
|
|
65
65
|
import {
|
|
66
66
|
atomicWriteFileSync,
|
|
67
67
|
atomicWriteJsonSync
|
|
@@ -1483,7 +1483,7 @@ function buildEndpoints(deps, isLive) {
|
|
|
1483
1483
|
async "migrate.export"(p) {
|
|
1484
1484
|
const passphrase = String(p.passphrase ?? "");
|
|
1485
1485
|
if (!passphrase) return err("bad-request", "\u9700\u8981\u8BBE\u7F6E\u53E3\u4EE4");
|
|
1486
|
-
const { collectMigrationEntries, encryptContainer } = await import("./migrate-
|
|
1486
|
+
const { collectMigrationEntries, encryptContainer } = await import("./migrate-D4VKAKYT.js");
|
|
1487
1487
|
const { entries } = collectMigrationEntries(guard, paths);
|
|
1488
1488
|
if (entries.length === 0) return err("bad-request", "\u6CA1\u6709\u53EF\u6253\u5305\u7684\u8BB0\u5FC6\u6587\u4EF6\uFF08data/ \u662F\u7A7A\u7684\uFF09");
|
|
1489
1489
|
const out = path4.join(paths.exportsDir, `heartbeat-memory-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.hbmig`);
|
|
@@ -1495,7 +1495,7 @@ function buildEndpoints(deps, isLive) {
|
|
|
1495
1495
|
const passphrase = String(p.passphrase ?? "");
|
|
1496
1496
|
const file = String(p.file ?? "");
|
|
1497
1497
|
if (!passphrase || !file) return err("bad-request", "\u9700\u8981\u5BB9\u5668\u8DEF\u5F84\u4E0E\u53E3\u4EE4");
|
|
1498
|
-
const { decryptContainer, applyMigrationEntries } = await import("./migrate-
|
|
1498
|
+
const { decryptContainer, applyMigrationEntries } = await import("./migrate-D4VKAKYT.js");
|
|
1499
1499
|
let text;
|
|
1500
1500
|
try {
|
|
1501
1501
|
text = fs4.readFileSync(file, "utf8");
|
|
@@ -1680,6 +1680,47 @@ function registerStatusbarSection(ctx, guard, paths, opts) {
|
|
|
1680
1680
|
});
|
|
1681
1681
|
}
|
|
1682
1682
|
|
|
1683
|
+
// src/core/preset-definition.ts
|
|
1684
|
+
function heartbeatPresetDefinition(id = "heartbeat") {
|
|
1685
|
+
return {
|
|
1686
|
+
id,
|
|
1687
|
+
name: "\u5FC3\u8DF3\u6A21\u5F0F",
|
|
1688
|
+
description: "\u5FC3\u8DF3 agent \u4E13\u7528\uFF1A\u4EC5 web_search + \u4E0A\u4E0B\u6587\u6298\u53E0\uFF1B\u65E0 shell\u3001\u65E0\u6587\u4EF6\u3001\u65E0\u5B50\u4EE3\u7406\u3002",
|
|
1689
|
+
order: 20,
|
|
1690
|
+
plugins: [
|
|
1691
|
+
{
|
|
1692
|
+
id: "compaction",
|
|
1693
|
+
name: "cordis:group",
|
|
1694
|
+
group: true,
|
|
1695
|
+
isolate: { compaction: true, toolResultPruner: true },
|
|
1696
|
+
config: [
|
|
1697
|
+
{ id: "compaction-basic", name: "@deepseek-ai/dsh-compaction-basic" },
|
|
1698
|
+
{ id: "command-compact", name: "@deepseek-ai/dsh-command-compact" },
|
|
1699
|
+
{
|
|
1700
|
+
id: "tool-result-pruner",
|
|
1701
|
+
name: "@deepseek-ai/dsh-compaction-tool-result-pruner",
|
|
1702
|
+
config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 }
|
|
1703
|
+
}
|
|
1704
|
+
]
|
|
1705
|
+
},
|
|
1706
|
+
{ id: "tool-web", name: "@deepseek-ai/dsh-tool-web", config: { fetch: false, searchTimeoutMs: 6e4 } }
|
|
1707
|
+
]
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
async function registerHeartbeatPreset(service, id = "heartbeat", enabled = true) {
|
|
1711
|
+
if (!enabled) return { action: "skipped-disabled", id };
|
|
1712
|
+
const registrar = service;
|
|
1713
|
+
if (registrar === void 0 || registrar === null || typeof registrar.register !== "function") {
|
|
1714
|
+
return { action: "skipped-no-api", id };
|
|
1715
|
+
}
|
|
1716
|
+
try {
|
|
1717
|
+
await registrar.register(heartbeatPresetDefinition(id));
|
|
1718
|
+
return { action: "registered", id };
|
|
1719
|
+
} catch (e) {
|
|
1720
|
+
return { action: "error", id, detail: String(e).slice(0, 200) };
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1683
1724
|
// src/ledger/tool.ts
|
|
1684
1725
|
var MAX_TEXT = 120;
|
|
1685
1726
|
function clean(v) {
|
|
@@ -1809,7 +1850,8 @@ function apply(ctx, config = {}) {
|
|
|
1809
1850
|
guard,
|
|
1810
1851
|
policy,
|
|
1811
1852
|
agentPreset: config.agentPreset || "heartbeat",
|
|
1812
|
-
extraTools: (config.extraTools ?? "").split(",").map((s) => s.trim()).filter(Boolean)
|
|
1853
|
+
extraTools: (config.extraTools ?? "").split(",").map((s) => s.trim()).filter(Boolean),
|
|
1854
|
+
presetRegistration: () => presetRegistration ?? Promise.resolve()
|
|
1813
1855
|
};
|
|
1814
1856
|
setRuntime({
|
|
1815
1857
|
paths,
|
|
@@ -1822,23 +1864,36 @@ function apply(ctx, config = {}) {
|
|
|
1822
1864
|
tokenSaver: () => tokenSaverRef
|
|
1823
1865
|
}
|
|
1824
1866
|
});
|
|
1867
|
+
let presetRegistration;
|
|
1825
1868
|
ctx.inject(["agentPresets"], (presetCtx) => {
|
|
1826
1869
|
const service = presetCtx.agentPresets;
|
|
1870
|
+
const presetId = config.agentPreset || "heartbeat";
|
|
1871
|
+
const installEnabled = config.installPreset !== false;
|
|
1872
|
+
const audit = (entry) => {
|
|
1873
|
+
try {
|
|
1874
|
+
appendAuditLine(guard.assert(paths.logsDir + "/heartbeat.jsonl"), entry);
|
|
1875
|
+
} catch (e) {
|
|
1876
|
+
ctx.logger.warn("heartbeat: preset audit failed (%s)", String(e).slice(0, 120));
|
|
1877
|
+
}
|
|
1878
|
+
};
|
|
1879
|
+
presetRegistration = registerHeartbeatPreset(service, presetId, installEnabled).then((result2) => {
|
|
1880
|
+
audit({ event: "preset_register", ...result2 });
|
|
1881
|
+
if (result2.action === "error") {
|
|
1882
|
+
ctx.logger.warn("heartbeat: preset register failed (%s) \u2014 the engine room runs without it", result2.detail ?? "");
|
|
1883
|
+
} else if (result2.action === "registered") {
|
|
1884
|
+
ctx.logger.info("heartbeat: preset %s registered at runtime", result2.id);
|
|
1885
|
+
} else {
|
|
1886
|
+
ctx.logger.info("heartbeat: preset registration skipped (%s)", result2.action);
|
|
1887
|
+
}
|
|
1888
|
+
});
|
|
1827
1889
|
const root = userPresetRoot(service?.roots);
|
|
1828
1890
|
const result = installBundledPreset({
|
|
1829
1891
|
moduleUrl: import.meta.url,
|
|
1830
|
-
id:
|
|
1892
|
+
id: presetId,
|
|
1831
1893
|
...root === void 0 ? { rosterKnown: service !== void 0 } : { root },
|
|
1832
|
-
enabled:
|
|
1894
|
+
enabled: installEnabled
|
|
1833
1895
|
});
|
|
1834
|
-
|
|
1835
|
-
appendAuditLine(guard.assert(paths.logsDir + "/heartbeat.jsonl"), {
|
|
1836
|
-
event: "preset_install",
|
|
1837
|
-
...result
|
|
1838
|
-
});
|
|
1839
|
-
} catch (e) {
|
|
1840
|
-
ctx.logger.warn("heartbeat: preset_install audit failed (%s)", String(e).slice(0, 120));
|
|
1841
|
-
}
|
|
1896
|
+
audit({ event: "preset_install", ...result });
|
|
1842
1897
|
const line = describeInstall(result);
|
|
1843
1898
|
if (result.action === "error" || result.action === "skipped-no-root") {
|
|
1844
1899
|
ctx.logger.warn("heartbeat: %s", line);
|
|
@@ -1917,6 +1972,35 @@ function apply(ctx, config = {}) {
|
|
|
1917
1972
|
guard.assert(paths.logsDir + "/heartbeat.jsonl"),
|
|
1918
1973
|
{ event: "plugin_init", dataDir: paths.dataDir }
|
|
1919
1974
|
);
|
|
1975
|
+
if (paths.relocation) {
|
|
1976
|
+
const auditFile = guard.assert(paths.logsDir + "/heartbeat.jsonl");
|
|
1977
|
+
if (paths.relocation.action === "relocated") {
|
|
1978
|
+
appendAuditLine(auditFile, {
|
|
1979
|
+
event: "data_dir_relocated",
|
|
1980
|
+
from: paths.relocation.srcDir,
|
|
1981
|
+
to: paths.relocation.dstDir,
|
|
1982
|
+
files: paths.relocation.files,
|
|
1983
|
+
bytes: paths.relocation.bytes,
|
|
1984
|
+
warnings: paths.relocation.warnings,
|
|
1985
|
+
leftovers: paths.relocation.leftovers
|
|
1986
|
+
});
|
|
1987
|
+
ctx.logger.info(
|
|
1988
|
+
"heartbeat: data dir moved out of the package (%s files, %s bytes)",
|
|
1989
|
+
paths.relocation.files,
|
|
1990
|
+
paths.relocation.bytes
|
|
1991
|
+
);
|
|
1992
|
+
} else if (paths.relocation.action === "failed") {
|
|
1993
|
+
appendAuditLine(auditFile, {
|
|
1994
|
+
event: "data_dir_relocate_failed",
|
|
1995
|
+
stage: paths.relocation.stage,
|
|
1996
|
+
problems: paths.relocation.problems
|
|
1997
|
+
});
|
|
1998
|
+
ctx.logger.warn(
|
|
1999
|
+
"heartbeat: data dir relocation failed (%s); continuing in the package dir",
|
|
2000
|
+
paths.relocation.stage
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
1920
2004
|
const uiGet = () => ({
|
|
1921
2005
|
intervalMin: getRuntime().policy.heartbeat.intervalMin,
|
|
1922
2006
|
maxDailySend: getRuntime().policy.gate.maxDailySend,
|