@shgroup/dsh-serenity-hooks 1.57.0 → 1.57.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 +23 -9
- package/assets/eap-paper-LICENSE.txt +21 -0
- package/assets/eap-paper.md +492 -0
- package/dsh.plugin.json +1 -1
- package/lib/{ccc-roots-BC8mn8iM.js → ccc-roots-GIJ3A_tw.js} +79 -2
- package/lib/ccc-roots.d.ts +2 -1
- package/lib/client.js +43 -379
- package/lib/config-ops.d.ts +3 -34
- package/lib/face-host.d.ts +7 -5
- package/lib/index.d.ts +0 -31
- package/lib/index.js +197 -1079
- package/lib/{message-source-BcCRsEOh.js → message-source-B4P3Uw6D.js} +1 -1
- package/lib/output-guard-seam.d.ts +9 -2
- package/lib/ports.d.ts +6 -6
- package/lib/seams/lifecycle.d.ts +3 -3
- package/lib/{settings-section-xHABl8nk.js → settings-section-DQIVsTqE.js} +45 -30
- package/lib/settings-section.d.ts +3 -16
- package/lib/skiff-core.d.ts +6 -5
- package/lib/skiff-debug.d.ts +5 -4
- package/lib/skiff-role.d.ts +1 -1
- package/lib/tools/eap.d.ts +33 -3
- package/lib/tools/praxis.d.ts +4 -2
- package/lib/tools/skiff-admin.d.ts +1 -1
- package/lib/unattended-ops.d.ts +3 -1
- package/lib/weixin-bridge.d.ts +9 -2
- package/lib/weixin-output-guard.d.ts +1 -1
- package/package.json +3 -1
- package/lib/access-CNccNtgf.js +0 -79
- package/lib/acp-core.d.ts +0 -80
- package/lib/acp-http.d.ts +0 -37
- package/lib/skiff-registry-BjIX_KD1.js +0 -43
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as cccRootForCwd } from "./ccc-roots-
|
|
1
|
+
import { r as cccRootForCwd } from "./ccc-roots-GIJ3A_tw.js";
|
|
2
2
|
import { basename, dirname, join } from "node:path";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/time.ts
|
|
@@ -5,10 +5,17 @@
|
|
|
5
5
|
* 命中 → `agent.steer(buildRebuke(hits))` 打回重生成(turn 不关闭,模型同轮重答)。
|
|
6
6
|
* 连续命中达 REBUKE_MAX_ROUNDS → 放弃打回(防死循环),输出保留 + 审计日志。
|
|
7
7
|
*
|
|
8
|
-
* 作用范围(v1.26.3 用户拍板):**仅外部面**——skiff
|
|
9
|
-
* (session id `skiff-`/`
|
|
8
|
+
* 作用范围(v1.26.3 用户拍板):**仅外部面**——skiff 等对外输出会话
|
|
9
|
+
* (session id `skiff-`/`rebuild-` 前缀;v1.22.4 rebuild 新建会话同面)。
|
|
10
10
|
* **本地维护会话(普通 dsh 会话)不检测**——维护会话必然提及机制词
|
|
11
11
|
* (dsh-serenity-hooks/container_trajectory rebuild/mech-registry),打回会瘫痪自身工作。
|
|
12
|
+
*
|
|
13
|
+
* 🔴 **2026-10-15 补注(面 E 退役)**:`acp-` 前缀分支**已成孤儿,但本批不动**。
|
|
14
|
+
* 判据(两条,实测):① **该前缀从来没有生产者** —— 历史 `acp-core.ts` 建会话走的是
|
|
15
|
+
* `createSkiffAgent`,其 id = `` `skiff-${role}-${uuid}` ``(`skiff-core.ts:269`)⇒ `acp-` **从不出现**;
|
|
16
|
+
* ② 面 E 退役后连"本可能产生它的模块"也不在了。⇒ 该分支是**恒 false 的死判据**。
|
|
17
|
+
* ⚠️ **仍不擅自删**:这是**运行时字符串比较**,删它属**行为变更**(不是纯清理),
|
|
18
|
+
* 依本轨既有先例(`cheap-worker-` 四处置孤儿,同族、同判据)⇒ **登记待裁**(见 S142 §当前状态「观察」)。
|
|
12
19
|
*/
|
|
13
20
|
import type { Context } from 'cordis';
|
|
14
21
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
package/lib/ports.d.ts
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* 本模块是**零依赖叶模块**(纯常量,无 import)——output-guard(守卫词表)、config-ops
|
|
21
21
|
* (默认值)、settings-section(面板默认)、index(Config 默认)都可安全引用而不引入依赖环。
|
|
22
22
|
*/
|
|
23
|
-
/**
|
|
24
|
-
export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug'
|
|
23
|
+
/** 面标识(四个对外面;A 由宿主监听,B/C/D 由本插件监听) */
|
|
24
|
+
export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug';
|
|
25
25
|
/** 一个面的端口语义 */
|
|
26
26
|
export interface PortSpec {
|
|
27
27
|
/** 端口号 */
|
|
@@ -36,7 +36,7 @@ export interface PortSpec {
|
|
|
36
36
|
/**
|
|
37
37
|
* 集中端口表。
|
|
38
38
|
* A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
|
|
39
|
-
* / D=Skiff
|
|
39
|
+
* / D=Skiff 调试(默认关)。
|
|
40
40
|
*/
|
|
41
41
|
export declare const FACE_PORTS: Readonly<Record<FaceId, PortSpec>>;
|
|
42
42
|
/** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
|
|
@@ -47,13 +47,13 @@ export declare const GATEWAY_PORT: number;
|
|
|
47
47
|
export declare const WEIXIN_SEND_PORT: number;
|
|
48
48
|
/** Skiff 调试页端口默认值(面 D) */
|
|
49
49
|
export declare const SKIFF_DEBUG_PORT: number;
|
|
50
|
-
/** ACP / 对外问答端口默认值(面 E) */
|
|
51
|
-
export declare const ACP_HTTP_PORT: number;
|
|
52
50
|
/**
|
|
53
51
|
* **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
|
|
54
52
|
*
|
|
55
53
|
* 由 {@link FACE_PORTS} 机械派生 ⇒ 与面清单**永不漂移**。
|
|
56
54
|
* ⚠️ 修复记录(C4 块 B,2026-09-15):旧常量硬写 `['3080','3081','3099','3100']`
|
|
57
|
-
* ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"
|
|
55
|
+
* ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,四面齐全。
|
|
56
|
+
* ⚠️ 面变更记录(2026-10-15):**面 E(3100 ACP/问答)已整体退役**(owner 裁「砍掉外部问答」)
|
|
57
|
+
* ⇒ 本词表随之少一项,**无需另改**(这正是"派生而非手抄"的收益)。
|
|
58
58
|
*/
|
|
59
59
|
export declare const MECHANISM_PORTS: readonly string[];
|
package/lib/seams/lifecycle.d.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* `core/session/src/index.ts:62`),长跑进程里这些 Map 只增不减——且 `waitIdle`
|
|
11
11
|
* 在 agent 先被销毁时永不结算。
|
|
12
12
|
*
|
|
13
|
-
* ② **插件卸载/HMR/profile 重载 → 停掉自起的监听器与轮询器**。skiff
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* ② **插件卸载/HMR/profile 重载 → 停掉自起的监听器与轮询器**。skiff 调试页、微信桥轮询
|
|
14
|
+
* 都是 dsp 自己起的资源(⚠️ 2026-10-15:原同批还有 ACP HTTP 端点,该面已退役);
|
|
15
|
+
* 此前没有 `ctx.effect` 拆卸,卸载后端口仍被占用(EADDRINUSE)、轮询器重复启动。
|
|
16
16
|
*
|
|
17
17
|
* 设计约束:清理与拆卸**一律吞掉异常**——生命周期回调里抛错会影响宿主的销毁流程
|
|
18
18
|
* (宿主对 `session/disposed` 监听器异常是"contained"语义,但没必要制造噪音)。
|
|
@@ -1,10 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { f as hostSettings } from "./ccc-roots-GIJ3A_tw.js";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
//#region src/constants.ts
|
|
6
|
+
/** 常量(纯模块,零 DSH 依赖) */
|
|
7
|
+
/**
|
|
8
|
+
* ACC 版本:自动从 package.json 读取(单一真相源,消除与 CHANGELOG 的漂移)。
|
|
9
|
+
* 发布时只需改 package.json 的 version。
|
|
10
|
+
*/
|
|
11
|
+
const ACC_VERSION = (() => {
|
|
12
|
+
try {
|
|
13
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf-8")).version ?? "0.0.0";
|
|
15
|
+
} catch {
|
|
16
|
+
return "0.0.0";
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/skiff-registry.ts
|
|
21
|
+
const skiffSessions = /* @__PURE__ */ new Map();
|
|
22
|
+
/** 查 sessionId 的 Skiff 角色名(无 → null)——向后兼容(guards/seams 依赖) */
|
|
23
|
+
function skiffRoleFor(sessionId) {
|
|
24
|
+
return skiffSessions.get(sessionId)?.role ?? null;
|
|
25
|
+
}
|
|
26
|
+
/** 查 sessionId 的完整绑定(role + ccc;无 → null)——v1.25.10 会话追问校验 */
|
|
27
|
+
function skiffSessionInfo(sessionId) {
|
|
28
|
+
return skiffSessions.get(sessionId) ?? null;
|
|
29
|
+
}
|
|
30
|
+
function registerSkiffSession(sessionId, role, ccc) {
|
|
31
|
+
skiffSessions.set(sessionId, {
|
|
32
|
+
role,
|
|
33
|
+
ccc
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function unregisterSkiffSession(sessionId) {
|
|
37
|
+
skiffSessions.delete(sessionId);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
3
40
|
//#region src/ports.ts
|
|
4
41
|
/**
|
|
5
42
|
* 集中端口表。
|
|
6
43
|
* A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
|
|
7
|
-
* / D=Skiff
|
|
44
|
+
* / D=Skiff 调试(默认关)。
|
|
8
45
|
*/
|
|
9
46
|
const FACE_PORTS = {
|
|
10
47
|
main: {
|
|
@@ -30,12 +67,6 @@ const FACE_PORTS = {
|
|
|
30
67
|
host: "127.0.0.1",
|
|
31
68
|
defaultEnabled: false,
|
|
32
69
|
meaning: "Skiff 调试问答面(人工调试子角色;无认证,仅靠 loopback)"
|
|
33
|
-
},
|
|
34
|
-
acpHttp: {
|
|
35
|
-
port: 3100,
|
|
36
|
-
host: "127.0.0.1",
|
|
37
|
-
defaultEnabled: false,
|
|
38
|
-
meaning: "ACP JSON-RPC + 对外问答面(外部程序 + key 认证的问答页共用一 listener)"
|
|
39
70
|
}
|
|
40
71
|
};
|
|
41
72
|
/** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
|
|
@@ -46,28 +77,18 @@ const GATEWAY_PORT = FACE_PORTS.gateway.port;
|
|
|
46
77
|
const WEIXIN_SEND_PORT = FACE_PORTS.weixinSend.port;
|
|
47
78
|
/** Skiff 调试页端口默认值(面 D) */
|
|
48
79
|
const SKIFF_DEBUG_PORT = FACE_PORTS.skiffDebug.port;
|
|
49
|
-
/** ACP / 对外问答端口默认值(面 E) */
|
|
50
|
-
const ACP_HTTP_PORT = FACE_PORTS.acpHttp.port;
|
|
51
80
|
/**
|
|
52
81
|
* **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
|
|
53
82
|
*
|
|
54
83
|
* 由 {@link FACE_PORTS} 机械派生 ⇒ 与面清单**永不漂移**。
|
|
55
84
|
* ⚠️ 修复记录(C4 块 B,2026-09-15):旧常量硬写 `['3080','3081','3099','3100']`
|
|
56
|
-
* ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"
|
|
85
|
+
* ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,四面齐全。
|
|
86
|
+
* ⚠️ 面变更记录(2026-10-15):**面 E(3100 ACP/问答)已整体退役**(owner 裁「砍掉外部问答」)
|
|
87
|
+
* ⇒ 本词表随之少一项,**无需另改**(这正是"派生而非手抄"的收益)。
|
|
57
88
|
*/
|
|
58
89
|
const MECHANISM_PORTS = Object.keys(FACE_PORTS).map((id) => String(FACE_PORTS[id].port));
|
|
59
90
|
//#endregion
|
|
60
91
|
//#region src/settings-section.ts
|
|
61
|
-
var settings_section_exports = /* @__PURE__ */ __exportAll({
|
|
62
|
-
SERENITY_SETTINGS_NS: () => SERENITY_SETTINGS_NS,
|
|
63
|
-
defaultHumanChannelSettings: () => defaultHumanChannelSettings,
|
|
64
|
-
defaultSimpleSettings: () => defaultSimpleSettings,
|
|
65
|
-
humanChannelSettingsFromConfig: () => humanChannelSettingsFromConfig,
|
|
66
|
-
readSimpleSettings: () => readSimpleSettings,
|
|
67
|
-
registerSettingsSection: () => registerSettingsSection,
|
|
68
|
-
simpleSettingsFromConfig: () => simpleSettingsFromConfig,
|
|
69
|
-
unwrapVolatile: () => unwrapVolatile
|
|
70
|
-
});
|
|
71
92
|
/**
|
|
72
93
|
* 设置面板命名空间 = **profile 条目 id**(v0.1.7 起;与旧 `settings.yaml` 段名逐字相同)。
|
|
73
94
|
*/
|
|
@@ -79,9 +100,6 @@ function defaultSimpleSettings() {
|
|
|
79
100
|
rebuildThresholdK: 400,
|
|
80
101
|
skiffEnabled: false,
|
|
81
102
|
skiffDebugPort: SKIFF_DEBUG_PORT,
|
|
82
|
-
acpEnabled: false,
|
|
83
|
-
acpHttpPort: ACP_HTTP_PORT,
|
|
84
|
-
publicAskEnabled: false,
|
|
85
103
|
croEnabled: true,
|
|
86
104
|
unattendedEnabled: false,
|
|
87
105
|
diagramEnabled: false,
|
|
@@ -98,7 +116,7 @@ function defaultSimpleSettings() {
|
|
|
98
116
|
* `meta.volatile` **无条件**包 `createVolatile(value)`,且该分支排在"缺省值回退"那一段
|
|
99
117
|
* **之前** ⇒ **"用户没设过"的字段也是恒真对象**(`.get()` 返回 `undefined`),**不是 `undefined`**。
|
|
100
118
|
*
|
|
101
|
-
* ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff
|
|
119
|
+
* ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff 会被
|
|
102
120
|
* **无意打开**(比"面板不显示"更坏:静默改变对外暴露面)。
|
|
103
121
|
*
|
|
104
122
|
* ## 为什么用结构判定
|
|
@@ -178,9 +196,6 @@ function simpleSettingsFromConfig(config) {
|
|
|
178
196
|
rebuildThresholdK: unwrapVolatile(config.rebuildThresholdK) ?? config.rebuild?.thresholdK ?? d.rebuildThresholdK,
|
|
179
197
|
skiffEnabled: unwrapVolatile(config.skiffEnabled) ?? config.skiff?.enabled ?? d.skiffEnabled,
|
|
180
198
|
skiffDebugPort: unwrapVolatile(config.skiffDebugPort) ?? config.skiff?.debugPort ?? d.skiffDebugPort,
|
|
181
|
-
acpEnabled: unwrapVolatile(config.acpEnabled) ?? config.acp?.enabled ?? d.acpEnabled,
|
|
182
|
-
acpHttpPort: unwrapVolatile(config.acpHttpPort) ?? config.acp?.httpPort ?? d.acpHttpPort,
|
|
183
|
-
publicAskEnabled: unwrapVolatile(config.publicAskEnabled) ?? d.publicAskEnabled,
|
|
184
199
|
croEnabled: unwrapVolatile(config.croEnabled) ?? d.croEnabled,
|
|
185
200
|
unattendedEnabled: unwrapVolatile(config.unattendedEnabled) ?? d.unattendedEnabled,
|
|
186
201
|
diagramEnabled: unwrapVolatile(config.diagramEnabled) ?? config.diagram?.enabled ?? d.diagramEnabled,
|
|
@@ -222,4 +237,4 @@ function registerSettingsSection(ctx, config) {
|
|
|
222
237
|
} catch {}
|
|
223
238
|
}
|
|
224
239
|
//#endregion
|
|
225
|
-
export {
|
|
240
|
+
export { GATEWAY_PORT as a, SKIFF_DEBUG_PORT as c, skiffRoleFor as d, skiffSessionInfo as f, FACE_PORTS as i, WEIXIN_SEND_PORT as l, ACC_VERSION as m, readSimpleSettings as n, MAIN_WEB_PORT as o, unregisterSkiffSession as p, registerSettingsSection as r, MECHANISM_PORTS as s, SERENITY_SETTINGS_NS as t, registerSkiffSession as u };
|
|
@@ -64,11 +64,7 @@ interface SimpleConfigFragment {
|
|
|
64
64
|
enabled?: boolean;
|
|
65
65
|
debugPort?: number;
|
|
66
66
|
};
|
|
67
|
-
/**
|
|
68
|
-
acp?: {
|
|
69
|
-
enabled?: boolean;
|
|
70
|
-
httpPort?: number;
|
|
71
|
-
};
|
|
67
|
+
/** F4 Skiff(实验性):调试服务启停(人工) */
|
|
72
68
|
/** diagram(实验性 demo;2026-09-29 owner 具名令 D104):标签源码 → 进程内出图(不借浏览器) */
|
|
73
69
|
diagram?: {
|
|
74
70
|
enabled?: boolean;
|
|
@@ -79,9 +75,6 @@ interface SimpleConfigFragment {
|
|
|
79
75
|
rebuildThresholdK?: PanelNumber;
|
|
80
76
|
skiffEnabled?: PanelBoolean;
|
|
81
77
|
skiffDebugPort?: PanelNumber;
|
|
82
|
-
acpEnabled?: PanelBoolean;
|
|
83
|
-
acpHttpPort?: PanelNumber;
|
|
84
|
-
publicAskEnabled?: PanelBoolean;
|
|
85
78
|
croEnabled?: PanelBoolean;
|
|
86
79
|
unattendedEnabled?: PanelBoolean;
|
|
87
80
|
diagramEnabled?: PanelBoolean;
|
|
@@ -102,12 +95,6 @@ interface SerenitySimpleSettings {
|
|
|
102
95
|
skiffEnabled: boolean;
|
|
103
96
|
/** F4 Skiff 调试端口(默认 3099,仅 127.0.0.1) */
|
|
104
97
|
skiffDebugPort: number;
|
|
105
|
-
/** F4c ACP HTTP JSON-RPC 端点总开关(实验性;默认关) */
|
|
106
|
-
acpEnabled: boolean;
|
|
107
|
-
/** F4c ACP HTTP 端口(默认 3100,仅 127.0.0.1) */
|
|
108
|
-
acpHttpPort: number;
|
|
109
|
-
/** F4d 建议问答页总开关(实验性;默认关——按认知容器暴露问答页,key 认证) */
|
|
110
|
-
publicAskEnabled: boolean;
|
|
111
98
|
/** **CRO(轨迹自编程唤起)总开关**(2026-09-21 所有者令新增;**缺省开**)。
|
|
112
99
|
*
|
|
113
100
|
* CRO = 轨迹目录下放一个 `continuous-re-occurrence.ts`,由 ACC 的 5min tick spawn,
|
|
@@ -132,7 +119,7 @@ interface SerenitySimpleSettings {
|
|
|
132
119
|
* `parseDsl → renderDsl(SVG + 四项体检)→ resvg-wasm 光栅化(内置字体)→ PNG`,
|
|
133
120
|
* 产物落 CCC `_tmp/diagram/` 且**图片块进对话**(**不借浏览器、不截图**)。
|
|
134
121
|
* **缺省关**:owner 口中的"demo 功能" ⇒ 关时**不注册**(工具不进模型工具清单:
|
|
135
|
-
* 零 token、不会被误调),同 `skiff
|
|
122
|
+
* 零 token、不会被误调),同 `skiff` 的"未开启零资源占用"口径。
|
|
136
123
|
* 依赖面:随包分发 3.8 MB 内置字体(`assets/diagram/`,wasm 对系统字体不可见)。 */
|
|
137
124
|
diagramEnabled: boolean;
|
|
138
125
|
/** **human-channel(人机信道)机器级配置**(2026-09-26 owner 定案;P0-1 立 schema + 投影)。
|
|
@@ -157,7 +144,7 @@ interface VolatileRef<T> {
|
|
|
157
144
|
* `meta.volatile` **无条件**包 `createVolatile(value)`,且该分支排在"缺省值回退"那一段
|
|
158
145
|
* **之前** ⇒ **"用户没设过"的字段也是恒真对象**(`.get()` 返回 `undefined`),**不是 `undefined`**。
|
|
159
146
|
*
|
|
160
|
-
* ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff
|
|
147
|
+
* ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff 会被
|
|
161
148
|
* **无意打开**(比"面板不显示"更坏:静默改变对外暴露面)。
|
|
162
149
|
*
|
|
163
150
|
* ## 为什么用结构判定
|
package/lib/skiff-core.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export declare function ensureWorkspacePromptSection(agent: Agent, scope: string
|
|
|
67
67
|
*
|
|
68
68
|
* 判定链:
|
|
69
69
|
* ⓪ **临时身份不建工作台**(v1.30.9,S142 用户报"SESSION 爆炸"根治):`persistent=false`
|
|
70
|
-
*
|
|
70
|
+
* (调试页等**无固定会话 id**的临时 agent)→ null。理由(R↓):这些 agent 每次
|
|
71
71
|
* 调用都是新 id、无身份延续,为其建 SESSION = 每次问答留一个永久空目录(无界熵增);
|
|
72
72
|
* 用户模型「skiff 本质是临时会话机制」——工作台属于**持久身份**,不属于单次调用。
|
|
73
73
|
* ① 角色未启用 session 能力(trajectory.session !== true)→ null(现状零变化)
|
|
@@ -96,10 +96,10 @@ interface SkiffAgentRef {
|
|
|
96
96
|
* 指定 sessionId 且磁盘已有持久化 log → `ctx.agents.resume`(DSH 持久化语义:
|
|
97
97
|
* sessionId 即身份,已持久化会话必须 resume——历史 + turn 续号延续,同用户长期记忆保留);
|
|
98
98
|
* 无 log(首次)/持久化未配置 → `ctx.agents.create`(新建)。不指定 sessionId →
|
|
99
|
-
* 随机 id 恒 create
|
|
99
|
+
* 随机 id 恒 create(调试页默认路径)。
|
|
100
100
|
*
|
|
101
101
|
* @param sessionId 指定会话 id(可选;微信桥等外部面用固定 id 实现用户↔会话长期映射——
|
|
102
|
-
* 不传则随机生成 skiff-<role>-<uuid
|
|
102
|
+
* 不传则随机生成 skiff-<role>-<uuid>,调试页默认路径)
|
|
103
103
|
*/
|
|
104
104
|
export declare function createSkiffAgent(ctx: Context, root: string, roleName: string, role: SkiffRoleConfig, defaultModel?: string, sessionId?: string): Promise<SkiffAgentRef>;
|
|
105
105
|
export interface SkiffTrajectoryEntry {
|
|
@@ -117,8 +117,9 @@ interface SkiffAskResult {
|
|
|
117
117
|
* 提问一轮:followup → 等 idle → 读答案 + 轨迹。
|
|
118
118
|
* @param eventsStart 轨迹起点:显式传 0 = 全量轨迹(会话追问时页面重绘完整时间线,
|
|
119
119
|
* v1.25.10 用户拍板);不传(undefined)= 本轮增量(followup 前 events 之后)
|
|
120
|
-
* @param options.includeTrajectory 是否计算轨迹(v1.26.10
|
|
121
|
-
* 公开问答页 / ACP JSON-RPC
|
|
120
|
+
* @param options.includeTrajectory 是否计算轨迹(v1.26.10 起供**对外面**传 false 跳过计算——
|
|
121
|
+
* 原消费方 = 3100 公开问答页 / ACP JSON-RPC,**该面已于 2026-10-15 退役** ⇒ 现无生产调用方传 false;
|
|
122
|
+
* 3099 调试页默认 true 保留)
|
|
122
123
|
*/
|
|
123
124
|
export declare function askSkiff(ctx: Context, agent: Agent, question: string, eventsStart?: number, options?: {
|
|
124
125
|
includeTrajectory?: boolean;
|
package/lib/skiff-debug.d.ts
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* 下拉列出全部候选(live 会话 cwd 上溯 .serenity 去重 + 默认绑定 root 兜底),
|
|
12
12
|
* 切换后角色下拉联动(各 CCC 的 skiff.roles 实时读取),提问按所选 CCC 创建 agent。
|
|
13
13
|
*
|
|
14
|
-
* 与
|
|
15
|
-
*
|
|
14
|
+
* 与 skiff 会话核心(createSkiffAgent + askSkiff)直接共用同一实现;
|
|
15
|
+
* (原「与 ACP stdio 协议(F4c 后续)共用同一会话核心」一句已随面 E 退役删除,2026-10-15)
|
|
16
|
+
* 轨迹 = session.events 结构化返回(与 dsh WebUI 同源数据),
|
|
16
17
|
* 页面 JS 渲染成对话时间线;同时保留原生 WebUI 会话链接供完整交互。
|
|
17
18
|
*
|
|
18
19
|
* 实验性质:未开启时零资源占用(无监听、无 agent 创建)。
|
|
@@ -42,8 +43,8 @@ export declare function skiffDebugPage(cccs: CccEntry[], defaultRoot: string, we
|
|
|
42
43
|
* 在 JSON **文本层**把它们替换为 `\uXXXX` 转义序列:JSON.parse 后语义完全一致(还原原字符),
|
|
43
44
|
* 且 JSC 正则看到的是常规 ASCII 转义(与 JSON.stringify 对控制字符的输出同形态,安全)。
|
|
44
45
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
46
|
+
* 3099 调试页客户端 `await res.json()` 与页面内嵌 JSON 均需此兼容层
|
|
47
|
+
* ——iOS Safari 用户实测"复杂回答"触发。(原同批还列了 3100 问答页,该面已退役,2026-10-15)
|
|
47
48
|
*
|
|
48
49
|
* @param jsonText JSON.stringify 的输出文本;原地等价替换,返回 JSC 安全文本
|
|
49
50
|
*/
|
package/lib/skiff-role.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export declare function systemPromptSource(role: SkiffRoleConfig | undefined): '
|
|
|
47
47
|
* 角色类型(v1.30.15,S142 用户拍板):
|
|
48
48
|
* - 显式 `role.kind` 优先(`temporary` / `persistent`)
|
|
49
49
|
* - 缺省 = 隐式推断:调用方给出**稳定 sessionId** → persistent;否则 temporary
|
|
50
|
-
* (存量配置零迁移;微信桥传固定会话 id → persistent
|
|
50
|
+
* (存量配置零迁移;微信桥传固定会话 id → persistent,调试页随机 id → temporary)
|
|
51
51
|
*/
|
|
52
52
|
type SkiffKind = 'temporary' | 'persistent';
|
|
53
53
|
export declare function resolveSkiffKind(role: SkiffRoleConfig | undefined, hasStableId: boolean): SkiffKind;
|
package/lib/tools/eap.d.ts
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* eap.ts — EAP
|
|
2
|
+
* eap.ts — EAP 内容源(**完整论文全文**,v1.30 三工具合并为 praxis 后只保留内容源)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 🔴 本文件的形态由一条 owner 令决定(2026-10-15,S142 续 125):
|
|
5
|
+
* 原实现内嵌一份约 1.5 KB 的「简易说明」(三变量表 + 自检清单),而 `praxis eap`
|
|
6
|
+
* 的职责是**注入 EAP 论文全文**。owner 原话:「praxis · eap 放的不是 eap 完整论文全文
|
|
7
|
+
* 而是简易说明,这是不行的,要求改成全文」。
|
|
8
|
+
*
|
|
9
|
+
* ⇒ 正文**不再内嵌**(58 KB 塞进 TS 模板字符串还要转义论文里 4 处 ```mermaid 围栏——
|
|
10
|
+
* 本容器为此踩过四次),改为**随包的静态资产 + 运行时读取**:
|
|
11
|
+
* 资产 = `assets/eap-paper.md`(**逐字**来自上游论文,未经改写)
|
|
12
|
+
* 读取 = `loadEapPaper()`(进程内缓存一次;同 `voyage-page.ts` 的既有先例)
|
|
13
|
+
*
|
|
14
|
+
* 🔴 **单一真相源**:正文只在 `assets/eap-paper.md` 一个地方。本文件负责**定位与读取**,
|
|
15
|
+
* `praxis.ts` 只负责**路由**。二者都不得内嵌任何论文片段——否则又是"第二份会漂的正文"。
|
|
16
|
+
*
|
|
17
|
+
* 上游:https://github.com/tellmewhattodo/theory-eap(MIT,许可证随包见
|
|
18
|
+
* `assets/eap-paper-LICENSE.txt`;同 `assets/diagram/*.ttf` 的既有做法)。
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* 资产相对包根的路径。
|
|
22
|
+
* 🔒 它**必须**同时出现在两处,否则发布包会缺文件、`praxis eap` 在**运行态**才报错:
|
|
23
|
+
* ① `package.json` 的 `files` 白名单;
|
|
24
|
+
* ② `scripts/dsh-develop.ts` 的 `verifyTarball` / `deploy` 的 `required` 数组。
|
|
25
|
+
* 同 v1.26.15 事故形态(`files` 白名单漏运行时必需文件)。
|
|
26
|
+
*/
|
|
27
|
+
export declare const EAP_PAPER_ASSET = "assets/eap-paper.md";
|
|
28
|
+
/** 论文资产的绝对路径(导出以便测试与 pack-check 共用同一判据来源) */
|
|
29
|
+
export declare function eapPaperPath(): string;
|
|
30
|
+
/**
|
|
31
|
+
* 读取论文全文。**读不到即抛错** —— 绝不静默返回空串或退回一份"简易说明":
|
|
32
|
+
* 那种降级会把"资产缺失"伪装成"调用成功",而本工具的全部价值就是那份正文。
|
|
5
33
|
*/
|
|
6
|
-
export declare
|
|
34
|
+
export declare function loadEapPaper(assetPath?: string): string;
|
|
35
|
+
/** 清缓存(测试用) */
|
|
36
|
+
export declare function resetEapCache(): void;
|
package/lib/tools/praxis.d.ts
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* Metaphor 映射:Engineering Drawings(图纸 = 可实践理论的编码,第 3 条隐喻)。
|
|
8
8
|
*
|
|
9
9
|
* section 参数渐进披露:不传 = 返回精简目录;传 = 返回对应框架全文/章节。
|
|
10
|
-
*
|
|
10
|
+
* 每个框架一个内容源(单一真相源):neat.ts / cce.ts / ontology.ts;
|
|
11
|
+
* 🔴 **eap 的内容源是随包资产 `assets/eap-paper.md`**(论文全文,58 KB)——
|
|
12
|
+
* 读它在 `tools/eap.ts`(本文件只路由,不内嵌任何正文;见该文件的成因注释)。
|
|
11
13
|
*/
|
|
12
14
|
/** 框架清单(无参调用时返回的精简目录) */
|
|
13
|
-
export declare const PRAXIS_INDEX = "praxis \u2014 \u53EF\u5B9E\u8DF5\u7406\u8BBA\u6CE8\u5165\uFF08\u8BA4\u77E5\u6846\u67B6\uFF0C\u6309\u9700\u52A0\u8F7D\uFF09\n\u9009\u62E9\u6846\u67B6\uFF1Apraxis eap\uFF08\u8BA4\u77E5\u8D28\u91CF\u2014\
|
|
15
|
+
export declare const PRAXIS_INDEX = "praxis \u2014 \u53EF\u5B9E\u8DF5\u7406\u8BBA\u6CE8\u5165\uFF08\u8BA4\u77E5\u6846\u67B6\uFF0C\u6309\u9700\u52A0\u8F7D\uFF09\n\u9009\u62E9\u6846\u67B6\uFF1Apraxis eap\uFF08\u8BA4\u77E5\u8D28\u91CF\u2014\u2014EAP \u8BBA\u6587\u5168\u6587\uFF09\n praxis neat\uFF08Neat \u534F\u4F5C\u534F\u8BAE\u2014\u2014\u5C0F\u6B65\u5BF9\u9F50/\u663E\u5F0F\u51B3\u7B56/\u6587\u6863\u9A71\u52A8\uFF09\n praxis cce\uFF08\u8BA4\u77E5\u8FDE\u7EED\u6027\u5DE5\u7A0B\u2014\u2014\u5BB9\u5668 5 \u884C\u4E3A\u7EA6\u675F + H_op \u64CD\u4F5C\u71B5\uFF09\n praxis ontology\uFF08\u672C\u4F53\u8BBA\u5DE5\u7A0B\u65B9\u6CD5\u7FA4\u2014\u2014\u89E6\u53D1/\u7F16\u7801/\u56DB\u7EC4\u5224\u636E M\u00B7L\u00B7D\u00B7V/OEPE \u5FAA\u73AF/\u516C\u7406/\u53CD\u6A21\u5F0F\uFF09\n\u65E0\u53C2\u8FD4\u56DE\u672C\u76EE\u5F55\uFF1B\u8BE6\u60C5\u4EE5\u5BF9\u5E94\u6846\u67B6\u539F\u6587\u4E3A\u51C6\uFF08\u5355\u4E00\u771F\u76F8\u6E90\uFF09\u3002\n";
|
|
14
16
|
export declare const praxisTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { JsonValue } from '../json.js';
|
|
11
11
|
/** Skiff 定义教程(核心):概念 / schema / 认知 MSM 写法 / 双白名单 / 轨迹纪律 / 示例角色 */
|
|
12
|
-
export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Definition Guide (F4, experimental) \u2550\u2550\u2550\n\nSkiff = \u5B81\u9759\u53F7\u653E\u51FA\u7684\u72EC\u7ACB\u5C0F\u8247\u2014\u2014\u5B8C\u6574 trajectory\uFF08\u5728\u5B81\u9759\u53F7\u5185\u5168\u77E5\u5168\u80FD\uFF09\u7684**\u4EFB\u610F\u5B50\u96C6\u89D2\u8272**\u3002\n\u7531\u672C CCC\uFF08.opencode/serenity.json skiff.roles\uFF09\u5B9A\u4E49\uFF1A\u80FD\u529B\u9762\uFF08\u53CC\u767D\u540D\u5355\uFF09+ \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6 + \u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002\ndsp \u53EA\u63D0\u4F9B\u673A\u5236\uFF08\u53CC\u767D\u540D\u5355\u5F3A\u5236 + \u57FA\u7840\u63D0\u793A\u8BCD + \u8C03\u8BD5\u95EE\u7B54\u9875\uFF09\uFF1B\u89D2\u8272\u5185\u5BB9\u5B8C\u5168\u7531 CCC \u53D1\u6325\u3002\n\n\u2500\u2500 \u89D2\u8272\u914D\u7F6E schema \u2500\u2500\n { \"skiff\": { \"roles\": {\n \"<role-name>\": {\n \"model\": \"provider/model\", // \u89D2\u8272\u6A21\u578B\uFF08CCC \u76F4\u63A5\u6307\u5B9A\uFF0C\u65E0\u767D\u540D\u5355\u6821\u9A8C\uFF1B\u7F3A\u7701\u56DE\u9000 cheap-worker.defaultModel\uFF09\n \"msms\": [\"msm-a\", \"msm-b\"], // MSM \u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1Amsm \u5DE5\u5177\u53EA\u80FD\u6267\u884C\u8FD9\u4E9B\uFF1Bregister/deregister \u5FC5\u62D2\n \"tools\": [\"read\",\"grep\",\"glob\",...], // \u975E MSM \u5DE5\u5177\u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1A\u767D\u540D\u5355\u5916\u5DE5\u5177\u4E00\u5F8B\u4E0D\u53EF\u7528\uFF08guard \u5F3A\u5236\uFF09\n \"trajectory\": { \"session\": false, \"keeper\": false, \"rebuild\": false }, // \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08\u7F3A\u7701\u5168\u5173 = \u5B8C\u5168\u72EC\u7ACB\uFF09\n // \u89D2\u8272\u4EBA\u683C/\u8BA4\u77E5\u8FB9\u754C/\u98CE\u683C\uFF08CCC \u5B8C\u6574\u5B9A\u4E49\uFF1Bdsp \u53EA\u7ED9\u57FA\u7840\u63D0\u793A\u8BCD\uFF09\n \"systemPromptFile\": \".opencode/skiff/<role>.md\" // \u2605 \u63A8\u8350\uFF1A\u5F15\u7528 md \u6587\u4EF6\uFF08\u76F8\u5BF9 CCC \u6839\uFF1B\u8D85\u957F\u63D0\u793A\u8BCD\u5728 JSON \u5185\u5D4C\u4E0D\u53EF\u8BFB\uFF09\n // \"systemPrompt\": \"...\" // \u517C\u5BB9\uFF1A\u5185\u5D4C\u5B57\u7B26\u4E32\u4ECD\u53EF\u7528\uFF1B\u4E24\u8005\u90FD\u8BBE\u65F6 systemPromptFile \u4F18\u5148\n }\n } } }\n\n\u2500\u2500 \u53CC\u767D\u540D\u5355\u8BED\u4E49\uFF08\u5168\u6309\u767D\u540D\u5355\u66B4\u9732\uFF0C\u767D\u540D\u5355\u5916\u5168\u9690\u85CF\uFF09\u2500\u2500\n - tools \u7A7A + msms \u975E\u7A7A = \u7EAF MSM \u89D2\u8272\uFF08\u8BA4\u77E5\u95EE\u7B54\u5178\u578B\u5F62\u6001\uFF09\n - msms \u975E\u7A7A \u2192 msm \u5DE5\u5177\u81EA\u52A8\u53EF\u7528\uFF08MSM \u901A\u9053\uFF09\n - \u767D\u540D\u5355\u5916\u5DE5\u5177\u5373\u4F7F DSH \u672A\u6765\u65B0\u589E\u4E5F\u81EA\u52A8\u88AB\u6321\uFF08guard \u6309\u89D2\u8272\u5224\u5B9A\uFF0C\u4E0D\u679A\u4E3E\u5DE5\u5177\u540D\u2014\u2014\u5B8C\u5907\u6027\uFF09\n\n\u2500\u2500 \u8BA4\u77E5 MSM \u5199\u6CD5\uFF08\u8BFB\u77E5\u8BC6 / \u64CD\u4F5C\u80FD\u529B\uFF09\u2500\u2500\n - \u8BFB\u77E5\u8BC6\uFF1A\u811A\u672C\u8BFB CCC \u5185\u6587\u4EF6\uFF08SERENITY_ROOT env \u6CE8\u5165\uFF09\u2192 \u8F93\u51FA\u7B54\u6848/\u6458\u8981\uFF08\u5982 cognitive-qa\uFF09\n - \u64CD\u4F5C\u80FD\u529B\uFF1A\u811A\u672C\u8C03\u7528\u65E2\u6709\u5BB6\u5EAD\u5DE5\u5177/\u670D\u52A1\uFF08SSH/API/\u6587\u4EF6\u64CD\u4F5C\uFF09\u2014\u2014\u89D2\u8272\u80FD\u529B\u4E0A\u9650 = \u767D\u540D\u5355 MSM \u7684\u5B9E\u9645\u884C\u4E3A\n - \u4F8B\uFF1Acognitive-qa\uFF08\u8BFB docs/references \u56DE\u7B54\uFF09\u3001review-scan\uFF08\u8BFB\u4EE3\u7801\u51FA\u5BA1\u67E5\u610F\u89C1\uFF09\u3001review-fix\uFF08\u5199\u4FEE\u590D\uFF09\n - \u6CE8\u610F\uFF1AMSM \u5728\u811A\u672C\u5C42\u6267\u884C\uFF08bun\uFF09\uFF0C\u6587\u4EF6\u8BBF\u95EE\u4E0D\u53D7 agent \u5DE5\u5177\u9762\u7EA6\u675F\u2014\u2014\"\u53EA\u8BFB\"\u8BED\u4E49\u9760 CCC \u81EA\u5199 MSM \u81EA\u89C9\n\n\u2500\u2500 \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08trajectory\uFF09\u2500\u2500\n - session/keeper/rebuild \u9ED8\u8BA4 false\uFF1ASkiff \u5B8C\u5168\u72EC\u7ACB\uFF08\u4E0D\u5EFA SESSION.md\u3001\u65E0 keeper \u63D0\u9192\u3001\u65E0 rebuild \u538B\u529B\u68C0\u6D4B\uFF09\n - \u5F00\u542F\u67D0\u9879 = \u8BE5\u89D2\u8272\u53C2\u4E0E\u5BF9\u5E94\u8F68\u8FF9\u673A\u5236\uFF08\u5982 keeper=true \u8BA1\u5206\u63D0\u9192\u6309\u89D2\u8272\u751F\u6548\uFF09\n\n\u2500\u2500 \u793A\u4F8B\u89D2\u8272 \u2500\u2500\n qa-readonly: { \"msms\": [\"cognitive-qa\"], \"tools\": [], \"trajectory\": {} }\n \u2192 \u8BA4\u77E5\u95EE\u7B54\uFF08\u4EC5 MSM \u901A\u9053\uFF0C\u65E0\u76F4\u63A5\u5DE5\u5177\uFF0C\u5B8C\u5168\u72EC\u7ACB\uFF09\n code-review: { \"msms\": [\"review-scan\",\"review-fix\"], \"tools\": [\"read\",\"grep\",\"glob\",\"write\",\"edit\"], \"trajectory\": { \"keeper\": true } }\n \u2192 \u6709\u64CD\u4F5C\u80FD\u529B\uFF08\u53EF\u5199\u4FEE\u590D\uFF09\uFF0C\u53C2\u4E0E keeper \u8F68\u8FF9\u673A\u5236\n\n\u2500\u2500 \u8FD0\u884C \u2500\u2500\n \u8C03\u8BD5\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CSerenity\u300D\u9875 Skiff \u533A\u5757\u5F00\u542F \u2192 http://127.0.0.1:<debugPort> \u95EE\u7B54\u9875\u5B9E\u6D4B\n
|
|
12
|
+
export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Definition Guide (F4, experimental) \u2550\u2550\u2550\n\nSkiff = \u5B81\u9759\u53F7\u653E\u51FA\u7684\u72EC\u7ACB\u5C0F\u8247\u2014\u2014\u5B8C\u6574 trajectory\uFF08\u5728\u5B81\u9759\u53F7\u5185\u5168\u77E5\u5168\u80FD\uFF09\u7684**\u4EFB\u610F\u5B50\u96C6\u89D2\u8272**\u3002\n\u7531\u672C CCC\uFF08.opencode/serenity.json skiff.roles\uFF09\u5B9A\u4E49\uFF1A\u80FD\u529B\u9762\uFF08\u53CC\u767D\u540D\u5355\uFF09+ \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6 + \u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002\ndsp \u53EA\u63D0\u4F9B\u673A\u5236\uFF08\u53CC\u767D\u540D\u5355\u5F3A\u5236 + \u57FA\u7840\u63D0\u793A\u8BCD + \u8C03\u8BD5\u95EE\u7B54\u9875\uFF09\uFF1B\u89D2\u8272\u5185\u5BB9\u5B8C\u5168\u7531 CCC \u53D1\u6325\u3002\n\n\u2500\u2500 \u89D2\u8272\u914D\u7F6E schema \u2500\u2500\n { \"skiff\": { \"roles\": {\n \"<role-name>\": {\n \"model\": \"provider/model\", // \u89D2\u8272\u6A21\u578B\uFF08CCC \u76F4\u63A5\u6307\u5B9A\uFF0C\u65E0\u767D\u540D\u5355\u6821\u9A8C\uFF1B\u7F3A\u7701\u56DE\u9000 cheap-worker.defaultModel\uFF09\n \"msms\": [\"msm-a\", \"msm-b\"], // MSM \u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1Amsm \u5DE5\u5177\u53EA\u80FD\u6267\u884C\u8FD9\u4E9B\uFF1Bregister/deregister \u5FC5\u62D2\n \"tools\": [\"read\",\"grep\",\"glob\",...], // \u975E MSM \u5DE5\u5177\u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1A\u767D\u540D\u5355\u5916\u5DE5\u5177\u4E00\u5F8B\u4E0D\u53EF\u7528\uFF08guard \u5F3A\u5236\uFF09\n \"trajectory\": { \"session\": false, \"keeper\": false, \"rebuild\": false }, // \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08\u7F3A\u7701\u5168\u5173 = \u5B8C\u5168\u72EC\u7ACB\uFF09\n // \u89D2\u8272\u4EBA\u683C/\u8BA4\u77E5\u8FB9\u754C/\u98CE\u683C\uFF08CCC \u5B8C\u6574\u5B9A\u4E49\uFF1Bdsp \u53EA\u7ED9\u57FA\u7840\u63D0\u793A\u8BCD\uFF09\n \"systemPromptFile\": \".opencode/skiff/<role>.md\" // \u2605 \u63A8\u8350\uFF1A\u5F15\u7528 md \u6587\u4EF6\uFF08\u76F8\u5BF9 CCC \u6839\uFF1B\u8D85\u957F\u63D0\u793A\u8BCD\u5728 JSON \u5185\u5D4C\u4E0D\u53EF\u8BFB\uFF09\n // \"systemPrompt\": \"...\" // \u517C\u5BB9\uFF1A\u5185\u5D4C\u5B57\u7B26\u4E32\u4ECD\u53EF\u7528\uFF1B\u4E24\u8005\u90FD\u8BBE\u65F6 systemPromptFile \u4F18\u5148\n }\n } } }\n\n\u2500\u2500 \u53CC\u767D\u540D\u5355\u8BED\u4E49\uFF08\u5168\u6309\u767D\u540D\u5355\u66B4\u9732\uFF0C\u767D\u540D\u5355\u5916\u5168\u9690\u85CF\uFF09\u2500\u2500\n - tools \u7A7A + msms \u975E\u7A7A = \u7EAF MSM \u89D2\u8272\uFF08\u8BA4\u77E5\u95EE\u7B54\u5178\u578B\u5F62\u6001\uFF09\n - msms \u975E\u7A7A \u2192 msm \u5DE5\u5177\u81EA\u52A8\u53EF\u7528\uFF08MSM \u901A\u9053\uFF09\n - \u767D\u540D\u5355\u5916\u5DE5\u5177\u5373\u4F7F DSH \u672A\u6765\u65B0\u589E\u4E5F\u81EA\u52A8\u88AB\u6321\uFF08guard \u6309\u89D2\u8272\u5224\u5B9A\uFF0C\u4E0D\u679A\u4E3E\u5DE5\u5177\u540D\u2014\u2014\u5B8C\u5907\u6027\uFF09\n\n\u2500\u2500 \u8BA4\u77E5 MSM \u5199\u6CD5\uFF08\u8BFB\u77E5\u8BC6 / \u64CD\u4F5C\u80FD\u529B\uFF09\u2500\u2500\n - \u8BFB\u77E5\u8BC6\uFF1A\u811A\u672C\u8BFB CCC \u5185\u6587\u4EF6\uFF08SERENITY_ROOT env \u6CE8\u5165\uFF09\u2192 \u8F93\u51FA\u7B54\u6848/\u6458\u8981\uFF08\u5982 cognitive-qa\uFF09\n - \u64CD\u4F5C\u80FD\u529B\uFF1A\u811A\u672C\u8C03\u7528\u65E2\u6709\u5BB6\u5EAD\u5DE5\u5177/\u670D\u52A1\uFF08SSH/API/\u6587\u4EF6\u64CD\u4F5C\uFF09\u2014\u2014\u89D2\u8272\u80FD\u529B\u4E0A\u9650 = \u767D\u540D\u5355 MSM \u7684\u5B9E\u9645\u884C\u4E3A\n - \u4F8B\uFF1Acognitive-qa\uFF08\u8BFB docs/references \u56DE\u7B54\uFF09\u3001review-scan\uFF08\u8BFB\u4EE3\u7801\u51FA\u5BA1\u67E5\u610F\u89C1\uFF09\u3001review-fix\uFF08\u5199\u4FEE\u590D\uFF09\n - \u6CE8\u610F\uFF1AMSM \u5728\u811A\u672C\u5C42\u6267\u884C\uFF08bun\uFF09\uFF0C\u6587\u4EF6\u8BBF\u95EE\u4E0D\u53D7 agent \u5DE5\u5177\u9762\u7EA6\u675F\u2014\u2014\"\u53EA\u8BFB\"\u8BED\u4E49\u9760 CCC \u81EA\u5199 MSM \u81EA\u89C9\n\n\u2500\u2500 \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08trajectory\uFF09\u2500\u2500\n - session/keeper/rebuild \u9ED8\u8BA4 false\uFF1ASkiff \u5B8C\u5168\u72EC\u7ACB\uFF08\u4E0D\u5EFA SESSION.md\u3001\u65E0 keeper \u63D0\u9192\u3001\u65E0 rebuild \u538B\u529B\u68C0\u6D4B\uFF09\n - \u5F00\u542F\u67D0\u9879 = \u8BE5\u89D2\u8272\u53C2\u4E0E\u5BF9\u5E94\u8F68\u8FF9\u673A\u5236\uFF08\u5982 keeper=true \u8BA1\u5206\u63D0\u9192\u6309\u89D2\u8272\u751F\u6548\uFF09\n\n\u2500\u2500 \u793A\u4F8B\u89D2\u8272 \u2500\u2500\n qa-readonly: { \"msms\": [\"cognitive-qa\"], \"tools\": [], \"trajectory\": {} }\n \u2192 \u8BA4\u77E5\u95EE\u7B54\uFF08\u4EC5 MSM \u901A\u9053\uFF0C\u65E0\u76F4\u63A5\u5DE5\u5177\uFF0C\u5B8C\u5168\u72EC\u7ACB\uFF09\n code-review: { \"msms\": [\"review-scan\",\"review-fix\"], \"tools\": [\"read\",\"grep\",\"glob\",\"write\",\"edit\"], \"trajectory\": { \"keeper\": true } }\n \u2192 \u6709\u64CD\u4F5C\u80FD\u529B\uFF08\u53EF\u5199\u4FEE\u590D\uFF09\uFF0C\u53C2\u4E0E keeper \u8F68\u8FF9\u673A\u5236\n\n\u2500\u2500 \u8FD0\u884C \u2500\u2500\n \u8C03\u8BD5\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CSerenity\u300D\u9875 Skiff \u533A\u5757\u5F00\u542F \u2192 http://127.0.0.1:<debugPort> \u95EE\u7B54\u9875\u5B9E\u6D4B\n \uD83D\uDD34 \u5916\u90E8\u7A0B\u5E8F\u5316\u63A5\u5165\uFF082026-10-15 \u8D77\u6539\u8D70\u5B98\u65B9\uFF09\uFF1A\u672C\u63D2\u4EF6\u81EA\u9020\u7684 ACP \u9762\uFF08HTTP JSON-RPC 3100 \uFF0F\n \u5EFA\u8BAE\u95EE\u7B54\u9875\uFF09**\u5DF2\u6574\u4F53\u9000\u5F79**\uFF08owner \u88C1\u300C\u780D\u6389\u5916\u90E8\u95EE\u7B54\u300D\uFF09\u3002\u73B0\u5728\u8981\u7A0B\u5E8F\u5316/\u8FDC\u7A0B\u63A5\u5165\uFF0C\u8D70\u5BBF\u4E3B\n \u81EA\u5E26\u7684\u5B98\u65B9 ACP server\uFF1Adsh --profile acp\uFF08\u7EAF stdio\u3001\u96F6\u8BA4\u8BC1\uFF09\uFF0B \u4EFB\u4E00 ACP \u5BA2\u6237\u7AEF\n \uFF08\u624B\u673A\u7AEF\u5982 Agmente / ACP UI\uFF09\u7ECF\u96A7\u9053\u63A5\u5165\u3002\u8BE6\u89C1 S142 \u7684\u63A5\u5165\u6307\u5357\u6587\u6863\u3002\n \u542F\u505C = \u4EBA\u5DE5\uFF08\u8BBE\u7F6E\u9762\u677F\u5F00\u5173\uFF0C\u4E0D\u968F\u63D2\u4EF6\u52A0\u8F7D\u81EA\u52A8\u542F\u52A8\uFF09\uFF1B\u672A\u5F00\u542F\u96F6\u8D44\u6E90\u5360\u7528\n \u751F\u6548\u673A\u5236\uFF1A\u89D2\u8272\u914D\u7F6E**\u5B9E\u65F6\u8BFB\u53D6**\uFF08\u6539 .opencode/serenity.json \u2192 \u5237\u65B0\u8C03\u8BD5\u9875\u5373\u751F\u6548\uFF09\uFF1B\n \u6539\u914D\u7F6E\u540E\u7528 container_admin role apply \u505A\u663E\u5F0F\u6821\u9A8C + \u5E94\u7528\u786E\u8BA4\uFF08\u7ED1\u5B9A CCC + \u89D2\u8272\u6E05\u5355\uFF09\n \u4F1A\u8BDD\u8FFD\u95EE\uFF08v1.25.10\uFF09\uFF1A\u8C03\u8BD5\u9875\u6301\u6709\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8FFD\u95EE\u81EA\u52A8\u7EED\u63A5\uFF08\u540C\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u5EF6\u7EED\uFF09\uFF1B\n \u300C\u65B0\u5BF9\u8BDD\u300D\u6309\u94AE\u5F00\u65B0\u4F1A\u8BDD\uFF1B\u8FDB\u7A0B\u91CD\u542F\u540E\u65E7\u4F1A\u8BDD\u4E0D\u53EF\u7EED\uFF08WebUI \u4ECD\u53EF\u89C1\u5386\u53F2\uFF09\n \u6CE8\u610F\uFF1Askill \u52A0\u8F7D\u5BF9 skiff **\u6052\u53EF\u7528**\uFF08\u4E0D\u8BBE\u767D\u540D\u5355\u2014\u2014\u8BFB\u77E5\u8BC6\u9762\uFF0C\u65E0\u5199\u80FD\u529B\uFF09";
|
|
13
13
|
/** 校验当前 CCC 的 skiff 配置:roles schema 合法 / msms 均已注册 / model ∈ cheap-worker.models / systemPrompt 非空 */
|
|
14
14
|
export declare function validateSkiffConfig(root: string): JsonValue;
|
|
15
15
|
/** 列出当前 CCC 已定义角色(名 / 模型 / msms / tools / 轨迹纪律摘要) */
|
package/lib/unattended-ops.d.ts
CHANGED
|
@@ -98,7 +98,9 @@ export declare function claimsUserNotification(text: string): boolean;
|
|
|
98
98
|
/**
|
|
99
99
|
* **不许开**的会话(设计 §3 的"建议写死",本版**确实写死**):
|
|
100
100
|
* `skiff-`(F4 问答 / **微信桥会话也是这个前缀** —— 桥那侧的"用户"是**家人**,
|
|
101
|
-
* 代理替家人说话 = **冒充**)| `acp
|
|
101
|
+
* 代理替家人说话 = **冒充**)| `acp-`(对外程序化面 —— ⚠️ **2026-10-15 起已成死判据**:
|
|
102
|
+
* 该前缀从无生产者且面 E 已退役;理由与"为何保留"见 `output-guard-seam.ts` 文件头)|
|
|
103
|
+
* `cheap-worker-`(自主 worker,已有自己的完成码循环)。
|
|
102
104
|
*
|
|
103
105
|
* ⚠️ **`rebuild-` 不在排除面**(与 `output-guard-seam.ts` 的取向**刻意不同**):重建会话是
|
|
104
106
|
* **同一轨迹的载体**(内部维护面),不是对外面;把它排除会让"重建后就没人推了"。
|
package/lib/weixin-bridge.d.ts
CHANGED
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* **CCC 级**:dsh 一个进程含多个 CCC,每个 CCC 独立对接微信桥(S142 用户拍板)——
|
|
5
5
|
* 扫描 live CCC → 每 CCC 读 weixin 配置(enabled + accounts + routes)→
|
|
6
|
-
* 启动该 CCC 该账号的 iLink 轮询循环。消息 → weixin-route 路由 →
|
|
7
|
-
* (session/new + session/prompt
|
|
6
|
+
* 启动该 CCC 该账号的 iLink 轮询循环。消息 → weixin-route 路由 → skiff 核心直调
|
|
7
|
+
* (session/new + session/prompt,同进程不经网络)。
|
|
8
|
+
*
|
|
9
|
+
* 🔴 **一处陈旧注释的更正(2026-10-15,随面 E 退役一并核实)**:本行原写「→ **AcpServer 直调**
|
|
10
|
+
* (…——acp-core 传输无关设计)」。**该描述从来不是事实** —— 实测 grep 全仓:本文件**从不**
|
|
11
|
+
* `import acp-core`(它 import 的是 `skiff-core` / `skiff-role` / `weixin-*`),
|
|
12
|
+
* 而 `acp-core` 的消费者**自始至终只有两个**(`acp-http.ts` + 其测试)。
|
|
13
|
+
* ⇒ 当年那句是**设计意图的误记**,不是依赖关系;面 E 退役后它更是彻底失效。
|
|
14
|
+
* 🔵 判据复述:**注释里的"设计意图"不能当依赖判据**,必须 grep import。
|
|
8
15
|
*
|
|
9
16
|
* 实验性质:未配置/未启用 → 完全不启动(零资源占用)。配置变化(面板写入)
|
|
10
17
|
* → 热重建受影响 CCC 的桥(对齐 gateway 热重建模式)。
|
|
@@ -58,7 +58,7 @@ export declare function buildManualOutputRebuke(session: ManualOutputSession): s
|
|
|
58
58
|
export declare function __resetWeixinOutputGuardForTest(): void;
|
|
59
59
|
/**
|
|
60
60
|
* 装配闸门(index.ts apply 调用)。
|
|
61
|
-
* 只对**已登记的手动模式会话**生效——其他会话(主舱/其他 skiff
|
|
61
|
+
* 只对**已登记的手动模式会话**生效——其他会话(主舱/其他 skiff 会话)零干预。
|
|
62
62
|
*/
|
|
63
63
|
export declare function registerWeixinOutputGuard(ctx: Context): void;
|
|
64
64
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.57.
|
|
3
|
+
"version": "1.57.2",
|
|
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": {
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"assets/serenity-voyage.html",
|
|
32
32
|
"assets/serenity-voyage-preview.png",
|
|
33
33
|
"assets/README.md",
|
|
34
|
+
"assets/eap-paper.md",
|
|
35
|
+
"assets/eap-paper-LICENSE.txt",
|
|
34
36
|
"assets/diagram/DroidSansFallbackFull.ttf",
|
|
35
37
|
"assets/diagram/LICENSE-Apache-2.0.txt",
|
|
36
38
|
"assets/diagram/NotoSans-Regular.ttf",
|
package/lib/access-CNccNtgf.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
//#region src/host/access.ts
|
|
2
|
-
/**
|
|
3
|
-
* host/access.ts — 宿主访问收口(S142 review F-06)
|
|
4
|
-
*
|
|
5
|
-
* 为什么存在:dsp 此前在 30+ 个文件里各自用 `(ctx as unknown as {…})` 断言读取宿主
|
|
6
|
-
* 服务——契约表达分散、失败模式各异(多数静默 undefined)。本模块是**唯一**读取宿主
|
|
7
|
-
* 的入口:所有 `ctx.get` / `ctx.<service>` 的形状断言集中在此,调用点只拿类型化结果。
|
|
8
|
-
*
|
|
9
|
-
* 约定:
|
|
10
|
-
* - 只读、无副作用;服务缺失一律返回 `undefined`(调用方决定降级策略),**不抛错**
|
|
11
|
-
* (宿主对插件 apply 抛错 = 整个 dsh 启动失败,访问层不能成为单点)。
|
|
12
|
-
* - 形状以 `AI_LAB/dsh-harness-public` @ 0.1.2-rc.1 为准;成员缺失由
|
|
13
|
-
* `host/contract.ts` 的探针在装载时与 `dashboard health` 中报告。
|
|
14
|
-
* - 迁移是渐进的:新代码必须走本模块;旧调用点逐轮收敛(F-06 轮次记录见 CHANGELOG)。
|
|
15
|
-
*/
|
|
16
|
-
/** 通用读取:`ctx.get(name)`(含异常吞掉——服务 getter 抛错视为不可用) */
|
|
17
|
-
function hostService(ctx, name) {
|
|
18
|
-
const c = ctx;
|
|
19
|
-
if (typeof c?.get !== "function") return void 0;
|
|
20
|
-
try {
|
|
21
|
-
return c.get(name);
|
|
22
|
-
} catch {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 直接属性读取(injected 服务:`ctx.<name>`),属性缺失**或读取抛错**时回落 `ctx.get`。
|
|
28
|
-
*
|
|
29
|
-
* v1.31.4 修复(R↓,实证 v1.31.3 真机首测):cordis 的 Context 是 Proxy,
|
|
30
|
-
* `ReflectService.handler.get`(`vendor/cordis/src/reflect.ts`)对**未经 `inject` 声明**
|
|
31
|
-
* 的服务名会沿 fiber 链查找,找不到时**抛错**而非返回 undefined:
|
|
32
|
-
*
|
|
33
|
-
* cannot get property "<name>" without inject
|
|
34
|
-
*
|
|
35
|
-
* 于是"先直接属性读、失败回落 ctx.get"的写法在**真实 cordis** 下永远走不到回落分支——
|
|
36
|
-
* 异常直接逃逸(`hostService` 的 try/catch 被绕过)。v1.31.3 的 `hostSubagents`
|
|
37
|
-
* 正是这样炸的:`subagents` 是 lazy 服务(不在插件 `inject` 列表内)。
|
|
38
|
-
* 现有 fake ctx 单测(普通对象无 getter)复现不了 → 真 cordis 用例见
|
|
39
|
-
* `tests/host/cordis-access.test.ts`。
|
|
40
|
-
*
|
|
41
|
-
* 为什么吞掉异常而不是让它冒泡:本模块的契约是"服务缺失一律返回 undefined,**不抛错**"
|
|
42
|
-
* (宿主对插件 apply 抛错 = 整个 dsh 启动失败)。读取失败 = 服务不可用,等价于缺失。
|
|
43
|
-
*/
|
|
44
|
-
function hostInjected(ctx, name) {
|
|
45
|
-
const c = ctx;
|
|
46
|
-
try {
|
|
47
|
-
const direct = c?.[name];
|
|
48
|
-
if (direct !== void 0) return direct;
|
|
49
|
-
} catch {}
|
|
50
|
-
return hostService(ctx, name);
|
|
51
|
-
}
|
|
52
|
-
/** `ctx.sessions`(injected) */
|
|
53
|
-
function hostSessions(ctx) {
|
|
54
|
-
return hostInjected(ctx, "sessions");
|
|
55
|
-
}
|
|
56
|
-
/** `ctx.agents`(injected) */
|
|
57
|
-
function hostAgents(ctx) {
|
|
58
|
-
return hostInjected(ctx, "agents");
|
|
59
|
-
}
|
|
60
|
-
/** `ctx.webServer`(injected) */
|
|
61
|
-
function hostWebServer(ctx) {
|
|
62
|
-
return hostInjected(ctx, "webServer");
|
|
63
|
-
}
|
|
64
|
-
/** `ctx.settings`(injected;提供 settings 面板装配通道) */
|
|
65
|
-
function hostSettings(ctx) {
|
|
66
|
-
return hostInjected(ctx, "settings");
|
|
67
|
-
}
|
|
68
|
-
/** `ctx.web`(injected;v1.30.12 web_fetch provider 注册通道) */
|
|
69
|
-
function hostWeb(ctx) {
|
|
70
|
-
return hostInjected(ctx, "web");
|
|
71
|
-
}
|
|
72
|
-
function hostSubagents(ctx) {
|
|
73
|
-
return hostInjected(ctx, "subagents");
|
|
74
|
-
}
|
|
75
|
-
function hostLlm(ctx) {
|
|
76
|
-
return hostInjected(ctx, "llm");
|
|
77
|
-
}
|
|
78
|
-
//#endregion
|
|
79
|
-
export { hostSessions as a, hostWeb as c, hostService as i, hostWebServer as l, hostInjected as n, hostSettings as o, hostLlm as r, hostSubagents as s, hostAgents as t };
|