@shgroup/dsh-serenity-hooks 1.59.5 → 1.61.0
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/host/contract.d.ts +11 -0
- package/lib/index.js +132 -33
- package/lib/seams/bootstrap.d.ts +39 -3
- 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.
|
|
3
|
+
"version": "1.61.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 轨迹日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档,deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
package/lib/host/contract.d.ts
CHANGED
|
@@ -23,6 +23,17 @@ type HostAccess = 'injected' | 'lazy';
|
|
|
23
23
|
interface HostMember {
|
|
24
24
|
name: string;
|
|
25
25
|
kind: 'function' | 'value';
|
|
26
|
+
/**
|
|
27
|
+
* 成员所属的「互斥族」标签(可选)。**同族成员满足任一即可**。
|
|
28
|
+
*
|
|
29
|
+
* 🔴 为什么需要(v1.61,S151 2026-10-17 报告):
|
|
30
|
+
* 宿主会**给同一个能力改名**并保留旧名作回退。`subagents` 就是实例:
|
|
31
|
+
* `0.2.1-rc.*+` 的正门叫 `startActivation`,`start` 仅作旧宿主回退
|
|
32
|
+
* (`tools/cheap-worker.ts` 的 `resolveSubagentStarter()` 是**双路**的)。
|
|
33
|
+
* 若契约把某一个具体名字钉成"必须有",宿主改名后 ⇒ **探针报假故障,而功能是好的**。
|
|
34
|
+
* ⇒ 判据必须是「**这一族里至少有一个能用**」,不是「这个名字必须在」。
|
|
35
|
+
*/
|
|
36
|
+
anyOf?: string;
|
|
26
37
|
}
|
|
27
38
|
interface HostServiceContract {
|
|
28
39
|
/** 稳定标识(报告用) */
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { c as hostInjected, d as hostSessions, f as hostSettings, h as hostWebServer, i as cccRootForExec, l as hostLlm, m as hostWeb, n as agentCwdFor, o as listCccs, p as hostSubagents, r as cccRootForCwd, s as hostAgents, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-GIJ3A_tw.js";
|
|
3
3
|
import { _ as resolveInside, a as findSerenityRoot$1, c as matchBlacklist, d as readCccName$1, f as readCheapWorkerConfig, h as readTrajectorySkills, i as findGitRoot, l as pathInside, m as readSafeModeHiddenTools, n as SAFE_MODE_MARKER, o as isSafeModeOn, p as readExclusiveTools, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-B0ZGL9lx.js";
|
|
4
|
-
import { A as localIdStamp, C as setActiveSessionInfo, D as isoLocal, E as useSession, O as localFileStamp, S as sessionsRoot, T as summarize, _ as namingTitleFor, a as pruneMissingBindings, b as resolveSessionByTitle, c as setBindingStore, d as clearActiveSessionInfo, f as createSession, g as listSessions, h as getActiveSessionInfo, i as listBoundSessionIds, k as localHuman, l as DEFAULT_SESSION_SCOPE, m as findSession, n as PLUGIN_SOURCE, o as readLastBound, p as extractSessionMdPathFromText, r as appendBound, s as resolveSessionTrajectoryLabel,
|
|
4
|
+
import { A as localIdStamp, C as setActiveSessionInfo, D as isoLocal, E as useSession, O as localFileStamp, S as sessionsRoot, T as summarize, _ as namingTitleFor, a as pruneMissingBindings, b as resolveSessionByTitle, c as setBindingStore, d as clearActiveSessionInfo, f as createSession, g as listSessions, h as getActiveSessionInfo, i as listBoundSessionIds, k as localHuman, l as DEFAULT_SESSION_SCOPE, m as findSession, n as PLUGIN_SOURCE, o as readLastBound, p as extractSessionMdPathFromText, r as appendBound, s as resolveSessionTrajectoryLabel, u as TRAJECTORY_ACTIONS, v as parseSessionContextFromEvents, w as showSession, x as sessionEvents$1, y as readActiveSessionMd } from "./message-source-B4P3Uw6D.js";
|
|
5
5
|
import { a as readGitTrack, c as unsetEntry, i as localstorePath, l as writeEntry, n as checkLocalstoreGitCompliance, o as readStore, r as getEntry, s as runLocalStore, t as LOCALSTORE_SCOPES } from "./localstore-ops-DMs_ovHo.js";
|
|
6
6
|
import { a as FACE_PORTS, c as MECHANISM_PORTS, d as registerSkiffSession$1, f as skiffRoleFor$1, h as ACC_VERSION, i as ACP_PORT, l as SKIFF_DEBUG_PORT, m as unregisterSkiffSession$1, n as readSimpleSettings, o as GATEWAY_PORT, p as skiffSessionInfo$1, r as registerSettingsSection, s as MAIN_WEB_PORT, u as WEIXIN_SEND_PORT } from "./settings-section-DGUQZo5j.js";
|
|
7
7
|
import { a as readSkiffRoles, c as roleMsmWhitelist, d as systemPromptSource, f as trajectorySubset, i as isSkiffSessionId, l as roleToolWhitelist, n as buildSkiffBasePrompt, o as resolveRoleSystemPrompt, r as createRolePromptReader, s as resolveSkiffKind } from "./skiff-role-B615L9MV.js";
|
|
@@ -14101,6 +14101,88 @@ const DEFAULT_ANCHOR_MESSAGES = ["You are the operator agent of Serenity — a c
|
|
|
14101
14101
|
function hasUserMessageHistory(session) {
|
|
14102
14102
|
return sessionEvents$1(session).some((event) => event.type === "user/message");
|
|
14103
14103
|
}
|
|
14104
|
+
/** 造出来的 assistant 回复正文。锚定轮要求"只回确认、不做事"。 */
|
|
14105
|
+
const ANCHOR_ACK_TEXT = "acknowledge";
|
|
14106
|
+
/** 占位 system 文本:宿主 `SystemPromptProjection.project()` 会把它**原地 replace** 成真提示词。 */
|
|
14107
|
+
const ANCHOR_SYSTEM_PLACEHOLDER = "<!-- serenity:anchor-placeholder -->";
|
|
14108
|
+
/**
|
|
14109
|
+
* 把两轮 first-anchor 对话**直接写进会话日志**,取代原来的「真跑两轮」。
|
|
14110
|
+
*
|
|
14111
|
+
* ## 为什么可以这样(三条取证,全部打在真 `@deepseek-ai/dsh-session` 上)
|
|
14112
|
+
*
|
|
14113
|
+
* 1. **system 必须是 surface node 0**,而 `agent/pre-step` 跑在宿主提交 system **之前**
|
|
14114
|
+
* ⇒ 若直接写 [anchor…],system 会被追加到**末尾**(实测:`systemAtIndex: 4`,
|
|
14115
|
+
* 且**不报错**、静默走偏)。解法 = **先写一条占位 system**:宿主随后看到 node0
|
|
14116
|
+
* 已有 system 且文本不同 ⇒ 走 `replace(head)` 换成真提示词,锚定历史原样留在其后。
|
|
14117
|
+
* 2. **`contentGeneration` 只在 replace 时涨,append 不涨**;而 `buildRequest()`
|
|
14118
|
+
* 取 generation 快照**晚于** `systemPrompt.project()` ⇒ 那次 replace 不会被
|
|
14119
|
+
* 误判成「系列断裂」(不会误触发 `startsSeries`)。
|
|
14120
|
+
* 3. **造出来的 `assistant/message` 合法**:`stream: []` 通过校验;整段历史之后
|
|
14121
|
+
* 仍可被 compaction 的 `surfaceOp: replace` 整体覆盖(不炸)。
|
|
14122
|
+
*
|
|
14123
|
+
* ## ⚠️ 为什么不发 turn/start、turn/end
|
|
14124
|
+
*
|
|
14125
|
+
* 宿主的 turn 计数是**构造时缓存**的:`phase.lastTurn` 在本钩子触发前已读定(0),
|
|
14126
|
+
* 之后 `turn()` 恒用 `phase.turn + 1`。我们若自己发 `turn/start{1}{2}`,宿主随后
|
|
14127
|
+
* 仍会再发一条 `turn/start{1}` ⇒ **重复编号 ∧ 两个 turn 同时开着**。
|
|
14128
|
+
* ⇒ 只给消息打 **turn 标签**(模型可见顺序不依赖 turn 事件,`deriveMessages` 只看
|
|
14129
|
+
* surface 节点),**不碰宿主的 turn 账本**。
|
|
14130
|
+
*
|
|
14131
|
+
* @param session 会话(需有 append)
|
|
14132
|
+
* @param provider 当前路由 provider(写入 assistant 消息来源)
|
|
14133
|
+
* @param model 当前模型 id
|
|
14134
|
+
* @returns 是否成功写入
|
|
14135
|
+
*/
|
|
14136
|
+
function appendAnchorHistory(session, provider, model, anchorMessages = DEFAULT_ANCHOR_MESSAGES) {
|
|
14137
|
+
const target = session;
|
|
14138
|
+
if (typeof target?.append !== "function") return false;
|
|
14139
|
+
const append = target.append.bind(target);
|
|
14140
|
+
const rid = (prefix) => `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
14141
|
+
append("system/message", {
|
|
14142
|
+
turn: 1,
|
|
14143
|
+
step: 1,
|
|
14144
|
+
message: {
|
|
14145
|
+
id: rid("anchor-system"),
|
|
14146
|
+
role: "system",
|
|
14147
|
+
content: [{
|
|
14148
|
+
type: "text",
|
|
14149
|
+
text: ANCHOR_SYSTEM_PLACEHOLDER
|
|
14150
|
+
}],
|
|
14151
|
+
source: { kind: "system-prompt" }
|
|
14152
|
+
}
|
|
14153
|
+
}, { surfaceOp: "append" });
|
|
14154
|
+
for (let i = 0; i < anchorMessages.length; i++) {
|
|
14155
|
+
const turn = i + 1;
|
|
14156
|
+
append("user/message", {
|
|
14157
|
+
id: rid(`anchor-user-${turn}`),
|
|
14158
|
+
role: "user",
|
|
14159
|
+
content: [{
|
|
14160
|
+
type: "text",
|
|
14161
|
+
text: anchorMessages[i]
|
|
14162
|
+
}],
|
|
14163
|
+
source: { kind: "user" }
|
|
14164
|
+
}, { surfaceOp: "append" });
|
|
14165
|
+
append("assistant/message", {
|
|
14166
|
+
turn,
|
|
14167
|
+
step: 1,
|
|
14168
|
+
message: {
|
|
14169
|
+
id: rid(`anchor-assistant-${turn}`),
|
|
14170
|
+
role: "assistant",
|
|
14171
|
+
content: [{
|
|
14172
|
+
type: "text",
|
|
14173
|
+
text: ANCHOR_ACK_TEXT
|
|
14174
|
+
}],
|
|
14175
|
+
source: {
|
|
14176
|
+
kind: "model",
|
|
14177
|
+
provider,
|
|
14178
|
+
model
|
|
14179
|
+
}
|
|
14180
|
+
},
|
|
14181
|
+
stream: []
|
|
14182
|
+
}, { surfaceOp: "append" });
|
|
14183
|
+
}
|
|
14184
|
+
return true;
|
|
14185
|
+
}
|
|
14104
14186
|
/**
|
|
14105
14187
|
* 构建一个 epoch 感知晋升跟踪器(纯逻辑,可单测)。
|
|
14106
14188
|
* requiredSignals:晋升所需信号数(boundary 后累计;默认 1)。
|
|
@@ -14213,9 +14295,16 @@ const PROMOTE_EVENTS = {
|
|
|
14213
14295
|
"assistant-message": /* @__PURE__ */ new Set(["assistant/message"]),
|
|
14214
14296
|
either: /* @__PURE__ */ new Set(["tool/call", "assistant/message"])
|
|
14215
14297
|
};
|
|
14216
|
-
/** 协议固有 bootstrap
|
|
14217
|
-
*
|
|
14218
|
-
*
|
|
14298
|
+
/** 协议固有 bootstrap 设置:**zeroTools=false**(v1.60 起)。
|
|
14299
|
+
*
|
|
14300
|
+
* 🔴 **为什么从 true 改成 false**(owner 令 2026-10-17,造历史取代真跑):
|
|
14301
|
+
* 锚定历史现在**直接写进日志**,因此 `assistant/message` 晋升信号在首请求前
|
|
14302
|
+
* 就已满足 ⇒ `boundary < 0` 分支实际不可达。但**不能依赖"恰好满足"这个副作用**:
|
|
14303
|
+
* 若哪天锚定历史没写成(例如非 CCC 会话/异常降级),`zeroTools: true` 会退回到
|
|
14304
|
+
* 「首请求 0 工具」,那是**另一种**退化。显式关掉 ⇒ 任何情况下首请求都拿完整目录。
|
|
14305
|
+
*
|
|
14306
|
+
* ⚠️ 这意味着 `bootstrapTools` 窄化也随之失效 —— 它的作用本来就是"首请求窄目录",
|
|
14307
|
+
* 而造历史的目的正是**取消这个断点**。保留字段只为不破坏旧测试的引用面。 */
|
|
14219
14308
|
function resolveBootstrapSettings() {
|
|
14220
14309
|
return {
|
|
14221
14310
|
bootstrapTools: [...DEFAULT_BOOTSTRAP_TOOLS],
|
|
@@ -14224,7 +14313,7 @@ function resolveBootstrapSettings() {
|
|
|
14224
14313
|
suppressedSources: new Set(DEFAULT_SUPPRESSED_SOURCES),
|
|
14225
14314
|
compactionTools: [...DEFAULT_COMPACTION_TOOLS],
|
|
14226
14315
|
anchorMessages: [...DEFAULT_ANCHOR_MESSAGES],
|
|
14227
|
-
zeroTools:
|
|
14316
|
+
zeroTools: false
|
|
14228
14317
|
};
|
|
14229
14318
|
}
|
|
14230
14319
|
/**
|
|
@@ -14276,23 +14365,11 @@ function registerBootstrap(ctx) {
|
|
|
14276
14365
|
if (hasUserMessageHistory(session)) return;
|
|
14277
14366
|
} else if (sid !== void 0 && anchoredSessions.has(sid)) return;
|
|
14278
14367
|
if (message?.source?.kind === "plugin:dsh-serenity-hooks") return;
|
|
14279
|
-
const
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
content: [{
|
|
14285
|
-
type: "text",
|
|
14286
|
-
text: SETTINGS.anchorMessages[i]
|
|
14287
|
-
}],
|
|
14288
|
-
source: {
|
|
14289
|
-
kind: ACC_MESSAGE_KIND,
|
|
14290
|
-
form: "notice",
|
|
14291
|
-
summary: "bootstrap anchor turn"
|
|
14292
|
-
}
|
|
14293
|
-
});
|
|
14294
|
-
if (sid !== void 0) anchoredSessions.add(sid);
|
|
14295
|
-
warnOnce(`anchor turns injected: ${SETTINGS.anchorMessages.length} 条(${SETTINGS.anchorMessages[0].slice(0, 40)}…)`);
|
|
14368
|
+
const route = agent.options;
|
|
14369
|
+
const wrote = appendAnchorHistory(session, typeof route?.provider === "string" ? route.provider : "unknown", typeof route?.model === "string" ? route.model : "unknown");
|
|
14370
|
+
if (wrote && sid !== void 0) anchoredSessions.add(sid);
|
|
14371
|
+
if (wrote) warnOnce(`anchor history fabricated: ${SETTINGS.anchorMessages.length} 轮(不再真跑)`);
|
|
14372
|
+
return;
|
|
14296
14373
|
} catch {}
|
|
14297
14374
|
});
|
|
14298
14375
|
let warned = false;
|
|
@@ -14330,11 +14407,11 @@ function registerBootstrap(ctx) {
|
|
|
14330
14407
|
tools: tools.filter((tool) => typeof tool.name === "string" && keep.has(tool.name))
|
|
14331
14408
|
};
|
|
14332
14409
|
}
|
|
14333
|
-
|
|
14334
|
-
|
|
14410
|
+
if (status.boundary < 0) return assembled;
|
|
14411
|
+
const keep = new Set(SETTINGS.compactionTools);
|
|
14335
14412
|
const missing = [...keep].filter((name) => !available.has(name));
|
|
14336
14413
|
if (missing.length > 0) {
|
|
14337
|
-
warnOnce(`expected
|
|
14414
|
+
warnOnce(`expected compaction tools missing=${JSON.stringify(missing)} — bootstrap disabled, full catalog exposed`);
|
|
14338
14415
|
return assembled;
|
|
14339
14416
|
}
|
|
14340
14417
|
return {
|
|
@@ -16141,8 +16218,13 @@ const HOST_SERVICES = [
|
|
|
16141
16218
|
name: "subagents",
|
|
16142
16219
|
access: "lazy",
|
|
16143
16220
|
members: [{
|
|
16221
|
+
name: "startActivation",
|
|
16222
|
+
kind: "function",
|
|
16223
|
+
anyOf: "spawn-starter"
|
|
16224
|
+
}, {
|
|
16144
16225
|
name: "start",
|
|
16145
|
-
kind: "function"
|
|
16226
|
+
kind: "function",
|
|
16227
|
+
anyOf: "spawn-starter"
|
|
16146
16228
|
}],
|
|
16147
16229
|
impact: "cheap-worker 委派不可用(前台委派的正门,响亮报错)",
|
|
16148
16230
|
required: false
|
|
@@ -16388,13 +16470,30 @@ function probeHostContract(ctx, hostVersion = null) {
|
|
|
16388
16470
|
for (const member of svc.members) {
|
|
16389
16471
|
checked += 1;
|
|
16390
16472
|
const actual = value[member.name];
|
|
16391
|
-
if (!(member.kind === "function" ? typeof actual === "function" : actual !== void 0))
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16473
|
+
if (!(member.kind === "function" ? typeof actual === "function" : actual !== void 0)) {
|
|
16474
|
+
if (member.anyOf !== void 0) {
|
|
16475
|
+
const siblings = svc.members.filter((m) => m.anyOf === member.anyOf);
|
|
16476
|
+
if (siblings.some((m) => {
|
|
16477
|
+
const v = value[m.name];
|
|
16478
|
+
return m.kind === "function" ? typeof v === "function" : v !== void 0;
|
|
16479
|
+
})) continue;
|
|
16480
|
+
issues.push({
|
|
16481
|
+
id: `${svc.id}.${member.anyOf}`,
|
|
16482
|
+
kind: "member",
|
|
16483
|
+
detail: `service "${svc.name}" is missing every ${member.kind} of "${member.anyOf}" (${siblings.map((m) => m.name).join(" | ")})`,
|
|
16484
|
+
impact: svc.impact,
|
|
16485
|
+
required: svc.required
|
|
16486
|
+
});
|
|
16487
|
+
continue;
|
|
16488
|
+
}
|
|
16489
|
+
issues.push({
|
|
16490
|
+
id: `${svc.id}.${member.name}`,
|
|
16491
|
+
kind: "member",
|
|
16492
|
+
detail: `service "${svc.name}" is missing ${member.kind} "${member.name}"`,
|
|
16493
|
+
impact: svc.impact,
|
|
16494
|
+
required: svc.required
|
|
16495
|
+
});
|
|
16496
|
+
}
|
|
16398
16497
|
}
|
|
16399
16498
|
}
|
|
16400
16499
|
const version = checkHostVersion(hostVersion);
|
package/lib/seams/bootstrap.d.ts
CHANGED
|
@@ -59,6 +59,35 @@ export declare const DEFAULT_ANCHOR_MESSAGES: string[];
|
|
|
59
59
|
* 统一经 sessionEvents() 读取(snapshotEvents() 优先,.events 兜底)。
|
|
60
60
|
*/
|
|
61
61
|
export declare function hasUserMessageHistory(session: unknown): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* 把两轮 first-anchor 对话**直接写进会话日志**,取代原来的「真跑两轮」。
|
|
64
|
+
*
|
|
65
|
+
* ## 为什么可以这样(三条取证,全部打在真 `@deepseek-ai/dsh-session` 上)
|
|
66
|
+
*
|
|
67
|
+
* 1. **system 必须是 surface node 0**,而 `agent/pre-step` 跑在宿主提交 system **之前**
|
|
68
|
+
* ⇒ 若直接写 [anchor…],system 会被追加到**末尾**(实测:`systemAtIndex: 4`,
|
|
69
|
+
* 且**不报错**、静默走偏)。解法 = **先写一条占位 system**:宿主随后看到 node0
|
|
70
|
+
* 已有 system 且文本不同 ⇒ 走 `replace(head)` 换成真提示词,锚定历史原样留在其后。
|
|
71
|
+
* 2. **`contentGeneration` 只在 replace 时涨,append 不涨**;而 `buildRequest()`
|
|
72
|
+
* 取 generation 快照**晚于** `systemPrompt.project()` ⇒ 那次 replace 不会被
|
|
73
|
+
* 误判成「系列断裂」(不会误触发 `startsSeries`)。
|
|
74
|
+
* 3. **造出来的 `assistant/message` 合法**:`stream: []` 通过校验;整段历史之后
|
|
75
|
+
* 仍可被 compaction 的 `surfaceOp: replace` 整体覆盖(不炸)。
|
|
76
|
+
*
|
|
77
|
+
* ## ⚠️ 为什么不发 turn/start、turn/end
|
|
78
|
+
*
|
|
79
|
+
* 宿主的 turn 计数是**构造时缓存**的:`phase.lastTurn` 在本钩子触发前已读定(0),
|
|
80
|
+
* 之后 `turn()` 恒用 `phase.turn + 1`。我们若自己发 `turn/start{1}{2}`,宿主随后
|
|
81
|
+
* 仍会再发一条 `turn/start{1}` ⇒ **重复编号 ∧ 两个 turn 同时开着**。
|
|
82
|
+
* ⇒ 只给消息打 **turn 标签**(模型可见顺序不依赖 turn 事件,`deriveMessages` 只看
|
|
83
|
+
* surface 节点),**不碰宿主的 turn 账本**。
|
|
84
|
+
*
|
|
85
|
+
* @param session 会话(需有 append)
|
|
86
|
+
* @param provider 当前路由 provider(写入 assistant 消息来源)
|
|
87
|
+
* @param model 当前模型 id
|
|
88
|
+
* @returns 是否成功写入
|
|
89
|
+
*/
|
|
90
|
+
export declare function appendAnchorHistory(session: unknown, provider: string, model: string, anchorMessages?: string[]): boolean;
|
|
62
91
|
interface PromotionStatus {
|
|
63
92
|
/** 最后一次 compaction/end 的 seq(-1 = 未压缩过) */
|
|
64
93
|
boundary: number;
|
|
@@ -85,9 +114,16 @@ interface PromotionTracker {
|
|
|
85
114
|
* 通常 ≤ 2 < 默认兜底 3,不受影响。
|
|
86
115
|
*/
|
|
87
116
|
export declare function createEpochPromotion(promoteEvents: Set<'tool/call' | 'assistant/message'>, requiredSignals?: number, maxRoundsFallback?: number): PromotionTracker;
|
|
88
|
-
/** 协议固有 bootstrap
|
|
89
|
-
*
|
|
90
|
-
*
|
|
117
|
+
/** 协议固有 bootstrap 设置:**zeroTools=false**(v1.60 起)。
|
|
118
|
+
*
|
|
119
|
+
* 🔴 **为什么从 true 改成 false**(owner 令 2026-10-17,造历史取代真跑):
|
|
120
|
+
* 锚定历史现在**直接写进日志**,因此 `assistant/message` 晋升信号在首请求前
|
|
121
|
+
* 就已满足 ⇒ `boundary < 0` 分支实际不可达。但**不能依赖"恰好满足"这个副作用**:
|
|
122
|
+
* 若哪天锚定历史没写成(例如非 CCC 会话/异常降级),`zeroTools: true` 会退回到
|
|
123
|
+
* 「首请求 0 工具」,那是**另一种**退化。显式关掉 ⇒ 任何情况下首请求都拿完整目录。
|
|
124
|
+
*
|
|
125
|
+
* ⚠️ 这意味着 `bootstrapTools` 窄化也随之失效 —— 它的作用本来就是"首请求窄目录",
|
|
126
|
+
* 而造历史的目的正是**取消这个断点**。保留字段只为不破坏旧测试的引用面。 */
|
|
91
127
|
export declare function resolveBootstrapSettings(): BootstrapSettings;
|
|
92
128
|
export declare function registerBootstrap(ctx: Context): void;
|
|
93
129
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.61.0",
|
|
4
4
|
"description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|