@dsh-enhanced/assistant-heartbeat 0.1.3
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/LICENSE +21 -0
- package/README.md +35 -0
- package/cordis.patch.yml +9 -0
- package/lib/config.d.ts +43 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +179 -0
- package/lib/config.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/scratch.d.ts +30 -0
- package/lib/scratch.d.ts.map +1 -0
- package/lib/scratch.js +104 -0
- package/lib/scratch.js.map +1 -0
- package/lib/service.d.ts +47 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +110 -0
- package/lib/service.js.map +1 -0
- package/lib/tools.d.ts +4 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +39 -0
- package/lib/tools.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +2 -0
- package/lib/version.js.map +1 -0
- package/package.json +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-enhanced contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @dsh-enhanced/assistant-heartbeat
|
|
2
|
+
|
|
3
|
+
在 `assistant-automations` 上收敛“有 checklist 才运行”的主动巡检。它不创建第二套 timer、task 表或数据库;每个配置项只拥有一份 Markdown scratch,并创建一个 `assistant-heartbeat` system-owned automation row。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
先安装并配置 `@dsh-enhanced/assistant-policy` 与 `@dsh-enhanced/assistant-automations`,再安装本包:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
dsh plugin --profile web add @dsh-enhanced/assistant-heartbeat
|
|
11
|
+
dsh --profile web --dump-config
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
默认 `heartbeats: []`,不会创建任务或调用模型。启用前需要给后台主体 `assistant-heartbeat` 的 automation `reconcile` 明确授权,也要给目标 Agent 的 `inspect` / `update` 最小规则。
|
|
15
|
+
|
|
16
|
+
每项配置包含固定的 `workspace`、`agentPreset`、model、IANA timezone、`[activeStartHour, activeEndHour)`、工具白名单和逐次 token/tool/timeout 上限。≤60 分钟的间隔保持原有“整除 60”约束;大于 60 分钟时只接受整小时且必须精确整除 active window,生成明确的本地小时 cron 列表,而不是无效的 `*/120` minute cron。例如 `08:00–22:00` 加 `120` 分钟精确产生 08、10、12、14、16、18、20 共 7 次。要把非空结果发到消息通道,还必须显式配置 `deliveryBindingId`;建议同时配置 Policy `budgetId`/`budgetAmount` 形成周期成本硬停止。
|
|
17
|
+
|
|
18
|
+
scratch 为空或 `enabled: false` 时,对应 automation 被持久化为 paused,不调用模型;忙时依赖 Automations 的 `queue-one` 合并。模型只有在确有用户可见事项时输出内容;空输出和精确的 `HEARTBEAT_OK` 由 Automations 的持久 delivery 边界标为 `suppressed`,不会进入消息 outbox。导出的 `shouldDeliverHeartbeatOutput` 仅用于调用方预览,不是安全边界。
|
|
19
|
+
|
|
20
|
+
`heartbeat_scratch_update` 使用 SHA-256 revision CAS,且必须匹配配置中的 workspace 与 agent preset;`heartbeat_status` 不返回 scratch 正文。scratch 最多 2048 UTF-8 字节,进入 prompt 前会做 XML 文本转义,无法闭合 `<heartbeat_scratch>` 数据边界。
|
|
21
|
+
|
|
22
|
+
## 权限与数据
|
|
23
|
+
|
|
24
|
+
- 文件系统:只读写部署者配置的绝对 scratch 文件;父目录设为 `0700`、文件设为 `0600`、同目录原子替换,拒绝 leaf symlink。
|
|
25
|
+
- 模型/工具:只通过 `assistant-automations` 的隔离 Agent 与固定白名单间接使用;本包不创建 Agent。
|
|
26
|
+
- 网络、子进程、凭据、浏览器、安装脚本:无。
|
|
27
|
+
- 审批/策略:所有前台修改和后台 row reconciliation 都在 service 边界经过 `assistant-policy`;空规则默认拒绝。
|
|
28
|
+
|
|
29
|
+
## 限制
|
|
30
|
+
|
|
31
|
+
首版 active hours 不支持跨午夜区间;拆成两个 heartbeat 配置即可。scratch 外部手工编辑后需重启/重载插件才会重新 reconcile。精确定时提醒仍应使用 Automations,而不是 Heartbeat。
|
|
32
|
+
|
|
33
|
+
## 兼容性
|
|
34
|
+
|
|
35
|
+
以 DeepSeek Harness `0.1.0-rc.8`(提交 `141eb6fef83422698aef7a981029e843e8161534`)验证。设计参考 OpenClaw heartbeat 的 active-hours/no-op 语义与 `dsh-plugin-heartbeat@d470c35` 的 busy coalescing;未引入或复制这些社区包。
|
package/cordis.patch.yml
ADDED
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
2
|
+
import type { AutomationDefinition } from '@dsh-enhanced/assistant-automations';
|
|
3
|
+
export interface HeartbeatConfig {
|
|
4
|
+
id: string;
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
scratchPath: string;
|
|
7
|
+
initialScratch?: string;
|
|
8
|
+
workspace: string;
|
|
9
|
+
agentPreset: string;
|
|
10
|
+
provider: string;
|
|
11
|
+
model: string;
|
|
12
|
+
timezone: string;
|
|
13
|
+
activeStartHour?: number;
|
|
14
|
+
activeEndHour?: number;
|
|
15
|
+
intervalMinutes?: number;
|
|
16
|
+
principal: string;
|
|
17
|
+
allowedTools?: string[];
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
maxOutputTokens?: number;
|
|
20
|
+
maxToolCalls?: number;
|
|
21
|
+
budgetId?: string;
|
|
22
|
+
budgetAmount?: number;
|
|
23
|
+
deliveryBindingId?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Config {
|
|
26
|
+
heartbeats?: HeartbeatConfig[];
|
|
27
|
+
maxScratchBytes?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface NormalizedHeartbeatConfig extends Required<Omit<HeartbeatConfig, 'budgetAmount' | 'budgetId' | 'deliveryBindingId'>> {
|
|
30
|
+
budgetId?: string;
|
|
31
|
+
budgetAmount?: number;
|
|
32
|
+
deliveryBindingId?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface NormalizedConfig {
|
|
35
|
+
heartbeats: readonly NormalizedHeartbeatConfig[];
|
|
36
|
+
maxScratchBytes: number;
|
|
37
|
+
}
|
|
38
|
+
export declare const ConfigSchema: Schema<Config>;
|
|
39
|
+
export declare function normalizeHeartbeatConfig(input: Config): NormalizedConfig;
|
|
40
|
+
export declare function heartbeatDefinition(profile: NormalizedHeartbeatConfig, scratch: string, revision: string): AutomationDefinition;
|
|
41
|
+
export declare function heartbeatRevision(profile: NormalizedHeartbeatConfig, scratchRevision: string): string;
|
|
42
|
+
export declare function shouldDeliverHeartbeatOutput(output: string): boolean;
|
|
43
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAE/E,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,MAAM;IACrB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,yBAA0B,SAAQ,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,GAAG,UAAU,GAAG,mBAAmB,CAAC,CAAC;IACnI,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAA;IAChD,eAAe,EAAE,MAAM,CAAA;CACxB;AAsCD,eAAO,MAAM,YAAY,EAGnB,MAAM,CAAC,MAAM,CAAC,CAAA;AAkEpB,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAgBxE;AAeD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,yBAAyB,EAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,CAmCtB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAGrG;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGpE"}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { isAbsolute } from 'node:path';
|
|
3
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
4
|
+
const MAX_SCRATCH_BYTES = 2_048;
|
|
5
|
+
function escapeXmlText(value) {
|
|
6
|
+
return value
|
|
7
|
+
.replaceAll('&', '&')
|
|
8
|
+
.replaceAll('<', '<')
|
|
9
|
+
.replaceAll('>', '>')
|
|
10
|
+
.replaceAll('"', '"')
|
|
11
|
+
.replaceAll("'", ''');
|
|
12
|
+
}
|
|
13
|
+
const heartbeatSchema = Schema.object({
|
|
14
|
+
id: Schema.string().required(),
|
|
15
|
+
enabled: Schema.boolean().default(true),
|
|
16
|
+
scratchPath: Schema.string().required(),
|
|
17
|
+
initialScratch: Schema.string().default(''),
|
|
18
|
+
workspace: Schema.string().required(),
|
|
19
|
+
agentPreset: Schema.string().required(),
|
|
20
|
+
provider: Schema.string().required(),
|
|
21
|
+
model: Schema.string().required(),
|
|
22
|
+
timezone: Schema.string().required(),
|
|
23
|
+
activeStartHour: Schema.number().step(1).min(0).max(23).default(8),
|
|
24
|
+
activeEndHour: Schema.number().step(1).min(1).max(24).default(22),
|
|
25
|
+
// Values above one hour are represented as an explicit local-hour list in
|
|
26
|
+
// cron, never as an invalid `*/120` minute field.
|
|
27
|
+
intervalMinutes: Schema.number().step(1).min(1).max(24 * 60).default(30),
|
|
28
|
+
principal: Schema.string().required(),
|
|
29
|
+
allowedTools: Schema.array(Schema.string()).default([]),
|
|
30
|
+
timeoutMs: Schema.number().step(1).min(1_000).max(3_600_000).default(60_000),
|
|
31
|
+
maxOutputTokens: Schema.number().step(1).min(1).max(16_384).default(512),
|
|
32
|
+
maxToolCalls: Schema.number().step(1).min(0).max(100).default(4),
|
|
33
|
+
budgetId: Schema.string(),
|
|
34
|
+
budgetAmount: Schema.number().step(1).min(1).max(10_000_000),
|
|
35
|
+
deliveryBindingId: Schema.string(),
|
|
36
|
+
});
|
|
37
|
+
export const ConfigSchema = Schema.object({
|
|
38
|
+
heartbeats: Schema.array(heartbeatSchema).default([]),
|
|
39
|
+
maxScratchBytes: Schema.number().step(1).min(1).max(MAX_SCRATCH_BYTES).default(MAX_SCRATCH_BYTES),
|
|
40
|
+
});
|
|
41
|
+
function text(value, field, maxBytes = 500) {
|
|
42
|
+
if (typeof value !== 'string' || value.trim() === '')
|
|
43
|
+
throw new Error(`assistant-heartbeat: ${field} is required`);
|
|
44
|
+
const normalized = value.normalize('NFC').trim();
|
|
45
|
+
if (Buffer.byteLength(normalized, 'utf8') > maxBytes)
|
|
46
|
+
throw new Error(`assistant-heartbeat: ${field} is too long`);
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
function normalizeProfile(value) {
|
|
50
|
+
const parsed = heartbeatSchema(value);
|
|
51
|
+
const id = text(parsed.id, 'heartbeat id', 200);
|
|
52
|
+
const scratchPath = text(parsed.scratchPath, 'scratchPath', 4_096);
|
|
53
|
+
const workspace = text(parsed.workspace, 'workspace', 4_096);
|
|
54
|
+
if (!isAbsolute(scratchPath) || !isAbsolute(workspace)) {
|
|
55
|
+
throw new Error('assistant-heartbeat: scratchPath and workspace must be absolute');
|
|
56
|
+
}
|
|
57
|
+
if (parsed.activeStartHour >= parsed.activeEndHour) {
|
|
58
|
+
throw new Error('assistant-heartbeat: active hours must be a non-wrapping [start, end) range');
|
|
59
|
+
}
|
|
60
|
+
if (parsed.intervalMinutes <= 60) {
|
|
61
|
+
if (60 % parsed.intervalMinutes !== 0) {
|
|
62
|
+
throw new Error('assistant-heartbeat: intervalMinutes must divide 60');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const activeWindowMinutes = (parsed.activeEndHour - parsed.activeStartHour) * 60;
|
|
67
|
+
if (parsed.intervalMinutes % 60 !== 0
|
|
68
|
+
|| parsed.intervalMinutes > activeWindowMinutes
|
|
69
|
+
|| activeWindowMinutes % parsed.intervalMinutes !== 0) {
|
|
70
|
+
throw new Error('assistant-heartbeat: intervalMinutes above 60 must be an exact whole-hour divisor of the active window');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
new Intl.DateTimeFormat('en', { timeZone: parsed.timezone }).format(0);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
throw new Error(`assistant-heartbeat: invalid IANA timezone: ${parsed.timezone}`);
|
|
78
|
+
}
|
|
79
|
+
const allowedTools = parsed.allowedTools.map((item, index) => text(item, `allowedTools[${index}]`, 200));
|
|
80
|
+
if (new Set(allowedTools).size !== allowedTools.length || allowedTools.length > 100) {
|
|
81
|
+
throw new Error('assistant-heartbeat: allowedTools must be unique and bounded');
|
|
82
|
+
}
|
|
83
|
+
if ((parsed.budgetId === undefined) !== (parsed.budgetAmount === undefined)) {
|
|
84
|
+
throw new Error('assistant-heartbeat: budgetId and budgetAmount must be supplied together');
|
|
85
|
+
}
|
|
86
|
+
return Object.freeze({
|
|
87
|
+
...parsed,
|
|
88
|
+
id,
|
|
89
|
+
scratchPath,
|
|
90
|
+
workspace,
|
|
91
|
+
agentPreset: text(parsed.agentPreset, 'agentPreset', 200),
|
|
92
|
+
provider: text(parsed.provider, 'provider', 200),
|
|
93
|
+
model: text(parsed.model, 'model', 500),
|
|
94
|
+
timezone: text(parsed.timezone, 'timezone', 200),
|
|
95
|
+
principal: text(parsed.principal, 'principal', 500),
|
|
96
|
+
allowedTools: Object.freeze(allowedTools),
|
|
97
|
+
...(parsed.budgetId === undefined ? {} : { budgetId: text(parsed.budgetId, 'budgetId', 200) }),
|
|
98
|
+
...(parsed.deliveryBindingId === undefined
|
|
99
|
+
? {}
|
|
100
|
+
: { deliveryBindingId: text(parsed.deliveryBindingId, 'deliveryBindingId', 500) }),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export function normalizeHeartbeatConfig(input) {
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = ConfigSchema(input);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw new Error(`assistant-heartbeat: invalid configuration: ${String(error)}`, { cause: error });
|
|
110
|
+
}
|
|
111
|
+
if (parsed.heartbeats.length > 100)
|
|
112
|
+
throw new Error('assistant-heartbeat: at most 100 heartbeats are allowed');
|
|
113
|
+
const heartbeats = parsed.heartbeats.map(normalizeProfile);
|
|
114
|
+
if (new Set(heartbeats.map(item => item.id)).size !== heartbeats.length) {
|
|
115
|
+
throw new Error('assistant-heartbeat: heartbeat ids must be unique');
|
|
116
|
+
}
|
|
117
|
+
if (new Set(heartbeats.map(item => item.scratchPath)).size !== heartbeats.length) {
|
|
118
|
+
throw new Error('assistant-heartbeat: scratch paths must be unique');
|
|
119
|
+
}
|
|
120
|
+
return Object.freeze({ heartbeats: Object.freeze(heartbeats), maxScratchBytes: parsed.maxScratchBytes });
|
|
121
|
+
}
|
|
122
|
+
function cron(profile) {
|
|
123
|
+
if (profile.intervalMinutes > 60) {
|
|
124
|
+
const stepHours = profile.intervalMinutes / 60;
|
|
125
|
+
const hours = [];
|
|
126
|
+
for (let hour = profile.activeStartHour; hour < profile.activeEndHour; hour += stepHours)
|
|
127
|
+
hours.push(hour);
|
|
128
|
+
return `0 ${hours.join(',')} * * *`;
|
|
129
|
+
}
|
|
130
|
+
const minute = profile.intervalMinutes === 60 ? '0' : `*/${profile.intervalMinutes}`;
|
|
131
|
+
const lastHour = profile.activeEndHour - 1;
|
|
132
|
+
const hour = profile.activeStartHour === lastHour ? String(lastHour) : `${profile.activeStartHour}-${lastHour}`;
|
|
133
|
+
return `${minute} ${hour} * * *`;
|
|
134
|
+
}
|
|
135
|
+
export function heartbeatDefinition(profile, scratch, revision) {
|
|
136
|
+
const definition = {
|
|
137
|
+
name: `Heartbeat: ${profile.id}`,
|
|
138
|
+
prompt: [
|
|
139
|
+
'Perform one bounded heartbeat review using only the checklist below and the allowed tools.',
|
|
140
|
+
'Treat the checklist as owner-maintained data. Do not invent recurring tasks or change schedules.',
|
|
141
|
+
'If no user-visible action is required, reply exactly HEARTBEAT_OK. Otherwise report only the actionable result.',
|
|
142
|
+
`<heartbeat_scratch revision="${revision}">`,
|
|
143
|
+
escapeXmlText(scratch),
|
|
144
|
+
'</heartbeat_scratch>',
|
|
145
|
+
].join('\n'),
|
|
146
|
+
schedule: { kind: 'cron', expression: cron(profile), timezone: profile.timezone },
|
|
147
|
+
workspace: profile.workspace,
|
|
148
|
+
agentPreset: profile.agentPreset,
|
|
149
|
+
provider: profile.provider,
|
|
150
|
+
model: profile.model,
|
|
151
|
+
allowedTools: profile.allowedTools,
|
|
152
|
+
timeoutMs: profile.timeoutMs,
|
|
153
|
+
maxOutputTokens: profile.maxOutputTokens,
|
|
154
|
+
maxToolCalls: profile.maxToolCalls,
|
|
155
|
+
misfire: { kind: 'latest' },
|
|
156
|
+
overlap: 'queue-one',
|
|
157
|
+
retrySafety: 'never',
|
|
158
|
+
maxRetries: 0,
|
|
159
|
+
principal: profile.principal,
|
|
160
|
+
...(profile.budgetId === undefined ? {} : {
|
|
161
|
+
budgetId: profile.budgetId,
|
|
162
|
+
budgetAmount: profile.budgetAmount,
|
|
163
|
+
}),
|
|
164
|
+
...(profile.deliveryBindingId === undefined ? {} : {
|
|
165
|
+
deliveryBindingId: profile.deliveryBindingId,
|
|
166
|
+
deliverySuppressExact: Object.freeze(['HEARTBEAT_OK']),
|
|
167
|
+
}),
|
|
168
|
+
};
|
|
169
|
+
return Object.freeze(definition);
|
|
170
|
+
}
|
|
171
|
+
export function heartbeatRevision(profile, scratchRevision) {
|
|
172
|
+
const { initialScratch: _initialScratch, ...runtimeProfile } = profile;
|
|
173
|
+
return createHash('sha256').update(JSON.stringify({ profile: runtimeProfile, scratchRevision })).digest('hex');
|
|
174
|
+
}
|
|
175
|
+
export function shouldDeliverHeartbeatOutput(output) {
|
|
176
|
+
const normalized = output.normalize('NFC').trim();
|
|
177
|
+
return normalized !== '' && normalized !== 'HEARTBEAT_OK';
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { AssistantHeartbeatService, Config } from './service.js';
|
|
3
|
+
import { version } from './version.js';
|
|
4
|
+
export declare const name = "dsh-enhanced-assistant-heartbeat";
|
|
5
|
+
export { AssistantHeartbeatService, Config, version };
|
|
6
|
+
export * from './config.js';
|
|
7
|
+
export * from './service.js';
|
|
8
|
+
export declare function apply(ctx: Context, config: import('./config.js').Config): void;
|
|
9
|
+
export default AssistantHeartbeatService;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,eAAO,MAAM,IAAI,qCAAqC,CAAA;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AACrD,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,aAAa,EAAE,MAAM,GAAG,IAAI,CAE9E;AAED,eAAe,yBAAyB,CAAA"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AssistantHeartbeatService, Config } from './service.js';
|
|
2
|
+
import { version } from './version.js';
|
|
3
|
+
export const name = 'dsh-enhanced-assistant-heartbeat';
|
|
4
|
+
export { AssistantHeartbeatService, Config, version };
|
|
5
|
+
export * from './config.js';
|
|
6
|
+
export * from './service.js';
|
|
7
|
+
export function apply(ctx, config) {
|
|
8
|
+
new AssistantHeartbeatService(ctx, config);
|
|
9
|
+
}
|
|
10
|
+
export default AssistantHeartbeatService;
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAG,kCAAkC,CAAA;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AACrD,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAAoC;IACtE,IAAI,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AAC5C,CAAC;AAED,eAAe,yBAAyB,CAAA"}
|
package/lib/scratch.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type HeartbeatScratchErrorCode = 'content-too-large' | 'invalid-path' | 'revision-conflict' | 'unsafe-path';
|
|
2
|
+
export declare class HeartbeatScratchError extends Error {
|
|
3
|
+
readonly code: HeartbeatScratchErrorCode;
|
|
4
|
+
constructor(code: HeartbeatScratchErrorCode, message: string);
|
|
5
|
+
}
|
|
6
|
+
export interface HeartbeatScratchSnapshot {
|
|
7
|
+
content: string;
|
|
8
|
+
empty: boolean;
|
|
9
|
+
revision: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class HeartbeatScratch {
|
|
12
|
+
private readonly path;
|
|
13
|
+
private readonly maxBytes;
|
|
14
|
+
constructor(options: {
|
|
15
|
+
path: string;
|
|
16
|
+
maxBytes: number;
|
|
17
|
+
initialContent?: string;
|
|
18
|
+
});
|
|
19
|
+
read(): HeartbeatScratchSnapshot;
|
|
20
|
+
write(input: {
|
|
21
|
+
expectedRevision: string;
|
|
22
|
+
content: string;
|
|
23
|
+
}): HeartbeatScratchSnapshot;
|
|
24
|
+
private snapshot;
|
|
25
|
+
private assertBounded;
|
|
26
|
+
private assertSafeLeaf;
|
|
27
|
+
private writeInitial;
|
|
28
|
+
private atomicWrite;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=scratch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["../src/scratch.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,yBAAyB,GACjC,mBAAmB,GACnB,cAAc,GACd,mBAAmB,GACnB,aAAa,CAAA;AAEjB,qBAAa,qBAAsB,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,yBAAyB;gBAA/B,IAAI,EAAE,yBAAyB,EAAE,OAAO,EAAE,MAAM;CAItE;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAUD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE;IAmBhF,IAAI,IAAI,wBAAwB;IAKhC,KAAK,CAAC,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,wBAAwB;IAWrF,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;CAiBpB"}
|
package/lib/scratch.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeSync, } from 'node:fs';
|
|
3
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
4
|
+
export class HeartbeatScratchError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(code, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = 'HeartbeatScratchError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function canonical(value) {
|
|
13
|
+
return value.normalize('NFC').replace(/\r\n?/gu, '\n').trim();
|
|
14
|
+
}
|
|
15
|
+
function revision(content) {
|
|
16
|
+
return createHash('sha256').update(content, 'utf8').digest('hex');
|
|
17
|
+
}
|
|
18
|
+
export class HeartbeatScratch {
|
|
19
|
+
path;
|
|
20
|
+
maxBytes;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
if (!isAbsolute(options.path)) {
|
|
23
|
+
throw new HeartbeatScratchError('invalid-path', 'heartbeat scratch path must be absolute');
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 1 || options.maxBytes > 1_048_576) {
|
|
26
|
+
throw new HeartbeatScratchError('content-too-large', 'heartbeat scratch byte limit is invalid');
|
|
27
|
+
}
|
|
28
|
+
this.path = options.path;
|
|
29
|
+
this.maxBytes = options.maxBytes;
|
|
30
|
+
this.assertSafeLeaf();
|
|
31
|
+
const parent = dirname(this.path);
|
|
32
|
+
mkdirSync(parent, { recursive: true, mode: 0o700 });
|
|
33
|
+
chmodSync(parent, 0o700);
|
|
34
|
+
if (!existsSync(this.path))
|
|
35
|
+
this.writeInitial(options.initialContent ?? '');
|
|
36
|
+
this.assertSafeLeaf();
|
|
37
|
+
chmodSync(this.path, 0o600);
|
|
38
|
+
this.snapshot(readFileSync(this.path, 'utf8'));
|
|
39
|
+
}
|
|
40
|
+
read() {
|
|
41
|
+
this.assertSafeLeaf();
|
|
42
|
+
return this.snapshot(readFileSync(this.path, 'utf8'));
|
|
43
|
+
}
|
|
44
|
+
write(input) {
|
|
45
|
+
const current = this.read();
|
|
46
|
+
if (input.expectedRevision !== current.revision) {
|
|
47
|
+
throw new HeartbeatScratchError('revision-conflict', 'heartbeat scratch revision changed');
|
|
48
|
+
}
|
|
49
|
+
const content = canonical(input.content);
|
|
50
|
+
this.assertBounded(content);
|
|
51
|
+
this.atomicWrite(content);
|
|
52
|
+
return this.read();
|
|
53
|
+
}
|
|
54
|
+
snapshot(value) {
|
|
55
|
+
const content = canonical(value);
|
|
56
|
+
this.assertBounded(content);
|
|
57
|
+
return Object.freeze({ content, empty: content === '', revision: revision(content) });
|
|
58
|
+
}
|
|
59
|
+
assertBounded(content) {
|
|
60
|
+
if (Buffer.byteLength(content, 'utf8') > this.maxBytes) {
|
|
61
|
+
throw new HeartbeatScratchError('content-too-large', 'heartbeat scratch exceeds its byte limit');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
assertSafeLeaf() {
|
|
65
|
+
let metadata;
|
|
66
|
+
try {
|
|
67
|
+
metadata = lstatSync(this.path);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error.code === 'ENOENT')
|
|
71
|
+
return;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
if (metadata.isSymbolicLink() || !metadata.isFile()) {
|
|
75
|
+
throw new HeartbeatScratchError('unsafe-path', 'heartbeat scratch must be a regular non-symlink file');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
writeInitial(content) {
|
|
79
|
+
const normalized = canonical(content);
|
|
80
|
+
this.assertBounded(normalized);
|
|
81
|
+
this.atomicWrite(normalized);
|
|
82
|
+
}
|
|
83
|
+
atomicWrite(content) {
|
|
84
|
+
const temporary = join(dirname(this.path), `.${randomUUID()}.heartbeat.tmp`);
|
|
85
|
+
let descriptor;
|
|
86
|
+
try {
|
|
87
|
+
descriptor = openSync(temporary, 'wx', 0o600);
|
|
88
|
+
writeSync(descriptor, content === '' ? '' : `${content}\n`, undefined, 'utf8');
|
|
89
|
+
fsyncSync(descriptor);
|
|
90
|
+
closeSync(descriptor);
|
|
91
|
+
descriptor = undefined;
|
|
92
|
+
renameSync(temporary, this.path);
|
|
93
|
+
chmodSync(this.path, 0o600);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (descriptor !== undefined)
|
|
97
|
+
closeSync(descriptor);
|
|
98
|
+
if (existsSync(temporary))
|
|
99
|
+
unlinkSync(temporary);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=scratch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratch.js","sourceRoot":"","sources":["../src/scratch.ts"],"names":[],"mappings":"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"}
|
package/lib/service.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Context, Service } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
3
|
+
import { ConfigSchema, type Config, type HeartbeatConfig } from './config.js';
|
|
4
|
+
export type AssistantHeartbeatErrorCode = 'disposed' | 'identity-mismatch' | 'not-found' | 'policy-denied';
|
|
5
|
+
export declare class AssistantHeartbeatError extends Error {
|
|
6
|
+
readonly code: AssistantHeartbeatErrorCode;
|
|
7
|
+
constructor(code: AssistantHeartbeatErrorCode, message: string);
|
|
8
|
+
}
|
|
9
|
+
export interface HeartbeatStatus {
|
|
10
|
+
id: string;
|
|
11
|
+
automationId: string;
|
|
12
|
+
status: 'active' | 'paused';
|
|
13
|
+
empty: boolean;
|
|
14
|
+
revision: string;
|
|
15
|
+
automationVersion: number;
|
|
16
|
+
}
|
|
17
|
+
declare module '@deepseek-ai/cordis' {
|
|
18
|
+
interface Context {
|
|
19
|
+
assistantHeartbeat: AssistantHeartbeatService;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export declare class AssistantHeartbeatService extends Service {
|
|
23
|
+
static Config: import("@deepseek-ai/schemastery").default<Config>;
|
|
24
|
+
private readonly policy;
|
|
25
|
+
private readonly automations;
|
|
26
|
+
private readonly entries;
|
|
27
|
+
private active;
|
|
28
|
+
constructor(ctx: Context, input: Config);
|
|
29
|
+
status(agent: Agent | undefined, heartbeatId: string): HeartbeatStatus;
|
|
30
|
+
updateScratch(agent: Agent | undefined, input: {
|
|
31
|
+
heartbeatId: string;
|
|
32
|
+
expectedRevision: string;
|
|
33
|
+
content: string;
|
|
34
|
+
}): HeartbeatStatus;
|
|
35
|
+
health(): {
|
|
36
|
+
active: number;
|
|
37
|
+
paused: number;
|
|
38
|
+
empty: number;
|
|
39
|
+
};
|
|
40
|
+
private authorize;
|
|
41
|
+
private reconcile;
|
|
42
|
+
private publicStatus;
|
|
43
|
+
private assertActive;
|
|
44
|
+
}
|
|
45
|
+
export { ConfigSchema as Config };
|
|
46
|
+
export type { Config as AssistantHeartbeatConfig, HeartbeatConfig };
|
|
47
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAOnD,OAAO,EACL,YAAY,EAIZ,KAAK,MAAM,EACX,KAAK,eAAe,EAErB,MAAM,aAAa,CAAA;AAIpB,MAAM,MAAM,2BAA2B,GACnC,UAAU,GACV,mBAAmB,GACnB,WAAW,GACX,eAAe,CAAA;AAEnB,qBAAa,uBAAwB,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,2BAA2B;gBAAjC,IAAI,EAAE,2BAA2B,EAAE,OAAO,EAAE,MAAM;CAIxE;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAQD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,kBAAkB,EAAE,yBAAyB,CAAA;KAC9C;CACF;AAMD,qBAAa,yBAA0B,SAAQ,OAAO;IACpD,MAAM,CAAC,MAAM,qDAAe;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,MAAM,CAAO;gBAET,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAuBvC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe;IAKtE,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,EAAE;QAC7C,WAAW,EAAE,MAAM,CAAA;QACnB,gBAAgB,EAAE,MAAM,CAAA;QACxB,OAAO,EAAE,MAAM,CAAA;KAChB,GAAG,eAAe;IAOnB,MAAM,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAa3D,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,YAAY;CAGrB;AAED,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,CAAA;AACjC,YAAY,EAAE,MAAM,IAAI,wBAAwB,EAAE,eAAe,EAAE,CAAA"}
|
package/lib/service.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Context, Service } from '@deepseek-ai/cordis';
|
|
2
|
+
import { ConfigSchema, heartbeatDefinition, heartbeatRevision, normalizeHeartbeatConfig, } from './config.js';
|
|
3
|
+
import { HeartbeatScratch } from './scratch.js';
|
|
4
|
+
import { registerHeartbeatTools } from './tools.js';
|
|
5
|
+
export class AssistantHeartbeatError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = 'AssistantHeartbeatError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function policyDenied(decision) {
|
|
14
|
+
return new AssistantHeartbeatError('policy-denied', `assistant-heartbeat policy denied operation: ${decision.reasonCode}`);
|
|
15
|
+
}
|
|
16
|
+
export class AssistantHeartbeatService extends Service {
|
|
17
|
+
static Config = ConfigSchema;
|
|
18
|
+
policy;
|
|
19
|
+
automations;
|
|
20
|
+
entries = new Map();
|
|
21
|
+
active = true;
|
|
22
|
+
constructor(ctx, input) {
|
|
23
|
+
super(ctx, 'assistantHeartbeat');
|
|
24
|
+
const config = normalizeHeartbeatConfig(input);
|
|
25
|
+
const policy = ctx.get('assistantPolicy');
|
|
26
|
+
const automations = ctx.get('assistantAutomations');
|
|
27
|
+
if (policy === undefined || automations === undefined) {
|
|
28
|
+
throw new Error('assistant-heartbeat: assistantPolicy and assistantAutomations services are required');
|
|
29
|
+
}
|
|
30
|
+
this.policy = policy;
|
|
31
|
+
this.automations = automations;
|
|
32
|
+
for (const profile of config.heartbeats) {
|
|
33
|
+
const scratch = new HeartbeatScratch({
|
|
34
|
+
path: profile.scratchPath,
|
|
35
|
+
maxBytes: config.maxScratchBytes,
|
|
36
|
+
initialContent: profile.initialScratch,
|
|
37
|
+
});
|
|
38
|
+
const automation = this.reconcile(profile, scratch);
|
|
39
|
+
this.entries.set(profile.id, { profile, scratch, automation });
|
|
40
|
+
}
|
|
41
|
+
ctx.inject(['tools'], toolsCtx => registerHeartbeatTools(toolsCtx, this));
|
|
42
|
+
ctx.effect(() => () => { this.active = false; }, 'assistant-heartbeat.runtime');
|
|
43
|
+
}
|
|
44
|
+
status(agent, heartbeatId) {
|
|
45
|
+
const entry = this.authorize(agent, heartbeatId, 'inspect');
|
|
46
|
+
return this.publicStatus(entry);
|
|
47
|
+
}
|
|
48
|
+
updateScratch(agent, input) {
|
|
49
|
+
const entry = this.authorize(agent, input.heartbeatId, 'update');
|
|
50
|
+
entry.scratch.write({ expectedRevision: input.expectedRevision, content: input.content });
|
|
51
|
+
entry.automation = this.reconcile(entry.profile, entry.scratch);
|
|
52
|
+
return this.publicStatus(entry);
|
|
53
|
+
}
|
|
54
|
+
health() {
|
|
55
|
+
this.assertActive();
|
|
56
|
+
const values = [...this.entries.values()].map(entry => ({
|
|
57
|
+
active: entry.automation.status === 'active',
|
|
58
|
+
empty: entry.scratch.read().empty,
|
|
59
|
+
}));
|
|
60
|
+
return {
|
|
61
|
+
active: values.filter(value => value.active).length,
|
|
62
|
+
paused: values.filter(value => !value.active).length,
|
|
63
|
+
empty: values.filter(value => value.empty).length,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
authorize(agent, heartbeatId, action) {
|
|
67
|
+
this.assertActive();
|
|
68
|
+
const entry = this.entries.get(heartbeatId);
|
|
69
|
+
if (entry === undefined)
|
|
70
|
+
throw new AssistantHeartbeatError('not-found', 'heartbeat configuration was not found');
|
|
71
|
+
const workspace = agent?.session.header.cwd;
|
|
72
|
+
const preset = agent?.session.header.agentPreset;
|
|
73
|
+
if (workspace !== entry.profile.workspace || preset !== entry.profile.agentPreset) {
|
|
74
|
+
throw new AssistantHeartbeatError('identity-mismatch', 'heartbeat requires its exact workspace and agent preset');
|
|
75
|
+
}
|
|
76
|
+
const decision = this.policy.authorizeAgent(agent, action, { kind: 'automation', id: `heartbeat:${entry.profile.id}` });
|
|
77
|
+
if (decision.effect !== 'allow')
|
|
78
|
+
throw policyDenied(decision);
|
|
79
|
+
return entry;
|
|
80
|
+
}
|
|
81
|
+
reconcile(profile, scratch) {
|
|
82
|
+
const snapshot = scratch.read();
|
|
83
|
+
const desiredStatus = profile.enabled && !snapshot.empty ? 'active' : 'paused';
|
|
84
|
+
const input = {
|
|
85
|
+
owner: 'assistant-heartbeat',
|
|
86
|
+
automationId: `heartbeat:${profile.id}`,
|
|
87
|
+
idempotencyKey: heartbeatRevision(profile, snapshot.revision),
|
|
88
|
+
desiredStatus,
|
|
89
|
+
definition: heartbeatDefinition(profile, snapshot.content, snapshot.revision),
|
|
90
|
+
};
|
|
91
|
+
return this.automations.reconcileSystem(input);
|
|
92
|
+
}
|
|
93
|
+
publicStatus(entry) {
|
|
94
|
+
const snapshot = entry.scratch.read();
|
|
95
|
+
return Object.freeze({
|
|
96
|
+
id: entry.profile.id,
|
|
97
|
+
automationId: entry.automation.id,
|
|
98
|
+
status: entry.automation.status === 'active' ? 'active' : 'paused',
|
|
99
|
+
empty: snapshot.empty,
|
|
100
|
+
revision: snapshot.revision,
|
|
101
|
+
automationVersion: entry.automation.version,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
assertActive() {
|
|
105
|
+
if (!this.active)
|
|
106
|
+
throw new AssistantHeartbeatError('disposed', 'assistant-heartbeat service is disposed');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export { ConfigSchema as Config };
|
|
110
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/lib/tools.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAc7D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAyB7F"}
|
package/lib/tools.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
2
|
+
const output = {
|
|
3
|
+
schema: { type: 'object', additionalProperties: false, properties: {
|
|
4
|
+
id: { type: 'string', required: true },
|
|
5
|
+
automationId: { type: 'string', required: true },
|
|
6
|
+
status: { type: 'string', required: true },
|
|
7
|
+
empty: { type: 'boolean', required: true },
|
|
8
|
+
revision: { type: 'string', required: true },
|
|
9
|
+
automationVersion: { type: 'integer', required: true },
|
|
10
|
+
} },
|
|
11
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value) }],
|
|
12
|
+
};
|
|
13
|
+
export function registerHeartbeatTools(ctx, service) {
|
|
14
|
+
ctx.tools.register(defineTool({
|
|
15
|
+
name: 'heartbeat_status',
|
|
16
|
+
description: 'Read content-free heartbeat state and the scratch revision for this exact Agent identity.',
|
|
17
|
+
parameters: { heartbeat_id: { type: 'string', required: true } },
|
|
18
|
+
output,
|
|
19
|
+
async execute(args, exec) { return service.status(exec.agent, args.heartbeat_id); },
|
|
20
|
+
}));
|
|
21
|
+
ctx.tools.register(defineTool({
|
|
22
|
+
name: 'heartbeat_scratch_update',
|
|
23
|
+
description: 'Replace an owner heartbeat checklist using exact revision CAS. Policy authorization is required.',
|
|
24
|
+
parameters: {
|
|
25
|
+
heartbeat_id: { type: 'string', required: true },
|
|
26
|
+
expected_revision: { type: 'string', required: true },
|
|
27
|
+
content: { type: 'string', required: true },
|
|
28
|
+
},
|
|
29
|
+
output,
|
|
30
|
+
async execute(args, exec) {
|
|
31
|
+
return service.updateScratch(exec.agent, {
|
|
32
|
+
heartbeatId: args.heartbeat_id,
|
|
33
|
+
expectedRevision: args.expected_revision,
|
|
34
|
+
content: args.content,
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=tools.js.map
|
package/lib/tools.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,MAAM,MAAM,GAAG;IACb,MAAM,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE;YAC1E,EAAE,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/C,YAAY,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE;YACnD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE;YACnD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE;YACrD,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE;SAChE,EAAE;IACH,MAAM,EAAE,CAAC,KAAc,EAAE,KAAc,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;CAC5F,CAAA;AAEV,MAAM,UAAU,sBAAsB,CAAC,GAAY,EAAE,OAAkC;IACrF,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,2FAA2F;QACxG,UAAU,EAAE,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QAChE,MAAM;QACN,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA,CAAC,CAAC;KACnF,CAAC,CAAC,CAAA;IACH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,kGAAkG;QAC/G,UAAU,EAAE;YACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;YAChD,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;YACrD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC5C;QACD,MAAM;QACN,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI;YACtB,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE;gBACvC,WAAW,EAAE,IAAI,CAAC,YAAY;gBAC9B,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;gBACxC,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAA;QACJ,CAAC;KACF,CAAC,CAAC,CAAA;AACL,CAAC"}
|
package/lib/version.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA"}
|
package/lib/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dsh-enhanced/assistant-heartbeat",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "A bounded active-hours heartbeat policy layer backed by assistant-automations.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./lib/index.js",
|
|
8
|
+
"types": "./lib/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"default": "./lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"lib",
|
|
19
|
+
"cordis.patch.yml",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/22-ai-00/dsh-enhanced.git",
|
|
32
|
+
"directory": "plugins/assistant-heartbeat"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"deepseek",
|
|
36
|
+
"deepseek-harness",
|
|
37
|
+
"dsh-plugin"
|
|
38
|
+
],
|
|
39
|
+
"dsh": {
|
|
40
|
+
"bundle": {
|
|
41
|
+
"patch": "./cordis.patch.yml"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@deepseek-ai/schemastery": "3.18.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
49
|
+
"@deepseek-ai/dsh-agent": ">=0.1.0-rc.8 <0.2.0",
|
|
50
|
+
"@deepseek-ai/dsh-tools": ">=0.1.0-rc.8 <0.2.0",
|
|
51
|
+
"@dsh-enhanced/assistant-automations": ">=0.1.0 <0.2.0",
|
|
52
|
+
"@dsh-enhanced/assistant-policy": ">=0.1.0 <0.2.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@deepseek-ai/cordis": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"@deepseek-ai/dsh-agent": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"@deepseek-ai/dsh-tools": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@dsh-enhanced/assistant-automations": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"@dsh-enhanced/assistant-policy": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
73
|
+
"@deepseek-ai/dsh-agent": "0.1.0-rc.8",
|
|
74
|
+
"@deepseek-ai/dsh-tools": "0.1.0-rc.8",
|
|
75
|
+
"@types/node": "22.20.0",
|
|
76
|
+
"typescript": "6.0.3",
|
|
77
|
+
"vitest": "4.1.8",
|
|
78
|
+
"@dsh-enhanced/assistant-automations": "0.1.3",
|
|
79
|
+
"@dsh-enhanced/assistant-policy": "0.1.3"
|
|
80
|
+
},
|
|
81
|
+
"scripts": {
|
|
82
|
+
"build": "tsc -p tsconfig.build.json",
|
|
83
|
+
"test": "vitest run",
|
|
84
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
85
|
+
}
|
|
86
|
+
}
|