@shgroup/dsh-serenity-hooks 1.18.3 → 1.18.5
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/dsh.plugin.json +1 -1
- package/lib/index.js +51 -29
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.5",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/loop + 拦截缝机械约束(safe-mode/路径守卫/会话落盘)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。私有(dsh-external 组织)。",
|
|
6
6
|
"engines": {
|
package/lib/index.js
CHANGED
|
@@ -1924,16 +1924,18 @@ function decideGuard(input) {
|
|
|
1924
1924
|
deny: `path escape blocked: "${pathArg}" 越出 CCC 根`,
|
|
1925
1925
|
kind: "deny"
|
|
1926
1926
|
};
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1927
|
+
if (toolName === "write" || toolName === "edit" || toolName === "str_replace_editor" || toolName === "cc_fs" || toolName === "bash" || toolName === "append" || toolName === "touch") {
|
|
1928
|
+
const rel = relative(root, abs).split("\\").join("/");
|
|
1929
|
+
if (rel === ".serenity-safe-on" || rel === ".serenity" || rel.startsWith(".serenity-safe-on/") || rel.startsWith(".serenity/")) return {
|
|
1930
|
+
deny: `CCC 治理文件 "${rel}" 保留给用户,agent 不可写`,
|
|
1931
|
+
kind: "deny"
|
|
1932
|
+
};
|
|
1933
|
+
const hit = matchBlacklist(rel, blacklist);
|
|
1934
|
+
if (hit) return {
|
|
1935
|
+
deny: hit.message ?? `blacklist blocked: "${pathArg}" 命中规则 "${hit.pattern}"`,
|
|
1936
|
+
kind: "deny"
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1937
1939
|
}
|
|
1938
1940
|
return { kind: "allow" };
|
|
1939
1941
|
}
|
|
@@ -3527,9 +3529,14 @@ const DEFAULT_COMPACTION_TOOLS = [
|
|
|
3527
3529
|
/** 默认首轮锚定消息(用户指定:persona 设定 + we/us 人称——首轮模型以 we/us 自称,
|
|
3528
3530
|
* 对齐 anchored 实测的 "we" 轨迹特征) */
|
|
3529
3531
|
const DEFAULT_ANCHOR_MESSAGE = "You are a helpful software engineer assistant.The personal pronoun is us/we.";
|
|
3530
|
-
/**
|
|
3531
|
-
|
|
3532
|
-
|
|
3532
|
+
/**
|
|
3533
|
+
* 构建一个 epoch 感知晋升跟踪器(纯逻辑,可单测)。
|
|
3534
|
+
* requiredSignals:晋升所需信号数(boundary 后累计;默认 1)。
|
|
3535
|
+
* 多轮锚定(v4):两轮递进锚定时 requiredSignals = 锚定轮数——
|
|
3536
|
+
* 每条锚定回复(assistant/message)计一次,最后一条回复后晋升。
|
|
3537
|
+
*/
|
|
3538
|
+
function createEpochPromotion(promoteEvents, requiredSignals = 1) {
|
|
3539
|
+
/** sessionId -> { boundary, signalCount }(boundary 后晋升信号计数) */
|
|
3533
3540
|
const state = /* @__PURE__ */ new Map();
|
|
3534
3541
|
const sessionIdOf = (session) => {
|
|
3535
3542
|
if (session && typeof session === "object") {
|
|
@@ -3539,24 +3546,27 @@ function createEpochPromotion(promoteEvents) {
|
|
|
3539
3546
|
};
|
|
3540
3547
|
const scan = (session) => {
|
|
3541
3548
|
let boundary = -1;
|
|
3542
|
-
let
|
|
3549
|
+
let signalCount = 0;
|
|
3543
3550
|
const events = session?.events;
|
|
3544
3551
|
if (Array.isArray(events)) for (const event of events) {
|
|
3545
3552
|
const e = event;
|
|
3546
3553
|
const seq = typeof e.seq === "number" ? e.seq : 0;
|
|
3547
3554
|
if (e.type === "compaction/end") {
|
|
3548
3555
|
boundary = seq;
|
|
3549
|
-
|
|
3556
|
+
signalCount = 0;
|
|
3550
3557
|
continue;
|
|
3551
3558
|
}
|
|
3552
|
-
if (promoteEvents.has(e.type) && seq > boundary)
|
|
3559
|
+
if (promoteEvents.has(e.type) && seq > boundary) signalCount++;
|
|
3553
3560
|
}
|
|
3554
3561
|
const entry = {
|
|
3555
3562
|
boundary,
|
|
3556
|
-
promoted
|
|
3563
|
+
promoted: signalCount >= requiredSignals
|
|
3557
3564
|
};
|
|
3558
3565
|
const sid = sessionIdOf(session);
|
|
3559
|
-
if (sid) state.set(sid,
|
|
3566
|
+
if (sid) state.set(sid, {
|
|
3567
|
+
boundary,
|
|
3568
|
+
signalCount
|
|
3569
|
+
});
|
|
3560
3570
|
return entry;
|
|
3561
3571
|
};
|
|
3562
3572
|
return {
|
|
@@ -3579,7 +3589,12 @@ function createEpochPromotion(promoteEvents) {
|
|
|
3579
3589
|
boundary: -1,
|
|
3580
3590
|
promoted: true
|
|
3581
3591
|
};
|
|
3582
|
-
|
|
3592
|
+
const s = state.get(sid);
|
|
3593
|
+
if (s) return {
|
|
3594
|
+
boundary: s.boundary,
|
|
3595
|
+
promoted: s.signalCount >= requiredSignals
|
|
3596
|
+
};
|
|
3597
|
+
return scan(session);
|
|
3583
3598
|
},
|
|
3584
3599
|
observe(session, event) {
|
|
3585
3600
|
const sid = sessionIdOf(session);
|
|
@@ -3591,13 +3606,13 @@ function createEpochPromotion(promoteEvents) {
|
|
|
3591
3606
|
if (e.type === "compaction/end") {
|
|
3592
3607
|
state.set(sid, {
|
|
3593
3608
|
boundary: seq,
|
|
3594
|
-
|
|
3609
|
+
signalCount: 0
|
|
3595
3610
|
});
|
|
3596
3611
|
return;
|
|
3597
3612
|
}
|
|
3598
|
-
if (promoteEvents.has(e.type) && seq > entry.boundary
|
|
3599
|
-
|
|
3600
|
-
|
|
3613
|
+
if (promoteEvents.has(e.type) && seq > entry.boundary) state.set(sid, {
|
|
3614
|
+
boundary: entry.boundary,
|
|
3615
|
+
signalCount: entry.signalCount + 1
|
|
3601
3616
|
});
|
|
3602
3617
|
}
|
|
3603
3618
|
};
|
|
@@ -3620,12 +3635,18 @@ function sourceList(value, field, fallback) {
|
|
|
3620
3635
|
function resolveBootstrapSettings(opts) {
|
|
3621
3636
|
const promoteOn = opts.promoteOn ?? "either";
|
|
3622
3637
|
if (promoteOn !== "either" && promoteOn !== "tool-call" && promoteOn !== "assistant-message") throw new TypeError(`bootstrap: promoteOn must be one of "tool-call", "assistant-message", "either"; got ${JSON.stringify(promoteOn)}`);
|
|
3638
|
+
let anchorMessages;
|
|
3639
|
+
if (Array.isArray(opts.anchorMessages)) {
|
|
3640
|
+
if (opts.anchorMessages.length === 0 || opts.anchorMessages.some((m) => typeof m !== "string" || m.length === 0)) throw new TypeError(`bootstrap: anchorMessages must be a non-empty array of non-empty strings`);
|
|
3641
|
+
anchorMessages = opts.anchorMessages;
|
|
3642
|
+
} else anchorMessages = [typeof opts.anchorMessage === "string" && opts.anchorMessage.length > 0 ? opts.anchorMessage : DEFAULT_ANCHOR_MESSAGE];
|
|
3623
3643
|
return {
|
|
3624
3644
|
bootstrapTools: stringList(opts.bootstrapTools, "bootstrapTools", DEFAULT_BOOTSTRAP_TOOLS),
|
|
3625
3645
|
promoteEvents: opts.zeroTools ? PROMOTE_EVENTS["assistant-message"] : PROMOTE_EVENTS[promoteOn],
|
|
3646
|
+
requiredSignals: opts.zeroTools ? anchorMessages.length : 1,
|
|
3626
3647
|
suppressedSources: sourceList(opts.suppressedContextSources, "suppressedContextSources", DEFAULT_SUPPRESSED_SOURCES),
|
|
3627
3648
|
compactionTools: stringList(opts.compactionTools, "compactionTools", DEFAULT_COMPACTION_TOOLS),
|
|
3628
|
-
|
|
3649
|
+
anchorMessages,
|
|
3629
3650
|
zeroTools: opts.zeroTools === true
|
|
3630
3651
|
};
|
|
3631
3652
|
}
|
|
@@ -3656,6 +3677,7 @@ function readBootstrapConfig(agent) {
|
|
|
3656
3677
|
suppressedContextSources: b?.suppressedContextSources,
|
|
3657
3678
|
compactionTools: b?.compactionTools,
|
|
3658
3679
|
anchorMessage: b?.anchorMessage,
|
|
3680
|
+
anchorMessages: b?.anchorMessages,
|
|
3659
3681
|
zeroTools: b?.zeroTools
|
|
3660
3682
|
});
|
|
3661
3683
|
}
|
|
@@ -3665,7 +3687,7 @@ function registerBootstrap(ctx) {
|
|
|
3665
3687
|
const trackerFor = (root, settings) => {
|
|
3666
3688
|
let t = trackers.get(root);
|
|
3667
3689
|
if (!t) {
|
|
3668
|
-
t = createEpochPromotion(settings.promoteEvents);
|
|
3690
|
+
t = createEpochPromotion(settings.promoteEvents, settings.requiredSignals);
|
|
3669
3691
|
trackers.set(root, t);
|
|
3670
3692
|
}
|
|
3671
3693
|
return t;
|
|
@@ -3692,12 +3714,12 @@ function registerBootstrap(ctx) {
|
|
|
3692
3714
|
if (message?.source?.kind === "plugin") return;
|
|
3693
3715
|
const inbox = agent.inbox;
|
|
3694
3716
|
if (!inbox?.prepend) return;
|
|
3695
|
-
inbox.prepend("next-turn", {
|
|
3696
|
-
id: `bootstrap-anchor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
3717
|
+
for (let i = settings.anchorMessages.length - 1; i >= 0; i--) inbox.prepend("next-turn", {
|
|
3718
|
+
id: `bootstrap-anchor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${i}`,
|
|
3697
3719
|
role: "user",
|
|
3698
3720
|
content: [{
|
|
3699
3721
|
type: "text",
|
|
3700
|
-
text: settings.
|
|
3722
|
+
text: settings.anchorMessages[i]
|
|
3701
3723
|
}],
|
|
3702
3724
|
source: {
|
|
3703
3725
|
kind: "plugin",
|
|
@@ -3706,7 +3728,7 @@ function registerBootstrap(ctx) {
|
|
|
3706
3728
|
summary: "bootstrap anchor turn"
|
|
3707
3729
|
}
|
|
3708
3730
|
});
|
|
3709
|
-
warnOnce(`anchor
|
|
3731
|
+
warnOnce(`anchor turns injected: ${settings.anchorMessages.length} 条(${settings.anchorMessages[0].slice(0, 40)}…)`);
|
|
3710
3732
|
} catch {}
|
|
3711
3733
|
});
|
|
3712
3734
|
let warned = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.5",
|
|
4
4
|
"description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|