@shgroup/dsh-serenity-hooks 1.34.0 → 1.34.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 +1 -0
- package/dsh.plugin.json +1 -1
- package/lib/acp-core.d.ts +2 -22
- package/lib/acp-http.d.ts +8 -0
- package/lib/api.d.ts +12 -4
- package/lib/autopilot-chain.d.ts +76 -0
- package/lib/autopilot-core-DCRkiWEe.js +229 -0
- package/lib/autopilot-core.d.ts +132 -0
- package/lib/autopilot-ops.d.ts +48 -0
- package/lib/autopilot-trajectory-D9Znxo75.js +782 -0
- package/lib/autopilot-trajectory.d.ts +64 -97
- package/lib/ccc-roots-Bd_SjEs7.js +152 -0
- package/lib/ccc-roots.d.ts +105 -0
- package/lib/ccc.d.ts +3 -6
- package/lib/client.js +2 -2
- package/lib/clock-runtime.d.ts +197 -0
- package/lib/config-ops.d.ts +9 -14
- package/lib/constants.d.ts +0 -2
- package/lib/container-status.d.ts +183 -0
- package/lib/diag-ops.d.ts +25 -10
- package/lib/face-host.d.ts +110 -0
- package/lib/fs-ops.d.ts +3 -2
- package/lib/gateway-auth.d.ts +2 -5
- package/lib/gateway.d.ts +0 -34
- package/lib/git-ops.d.ts +3 -2
- package/lib/handyman-ops.d.ts +3 -2
- package/lib/handyman-preset-inherit.d.ts +2 -1
- package/lib/host/access.d.ts +8 -7
- package/lib/host/contract.d.ts +29 -6
- package/lib/host/type-contract.d.ts +1 -2
- package/lib/im-bridge.d.ts +6 -5
- package/lib/index.js +8336 -5607
- package/lib/invariant.d.ts +0 -15
- package/lib/invariant.js +1 -1
- package/lib/kit-ops.d.ts +11 -31
- package/lib/localstore-ops.d.ts +3 -17
- package/lib/msm-ops.d.ts +34 -52
- package/lib/opencode-provider.d.ts +4 -5
- package/lib/output-guard-seam.d.ts +0 -3
- package/lib/output-guard.d.ts +12 -3
- package/lib/ports.d.ts +59 -0
- package/lib/rebuild.d.ts +1 -1
- package/lib/seams/bootstrap.d.ts +4 -3
- package/lib/seams/compact.d.ts +2 -1
- package/lib/seams/context.d.ts +2 -4
- package/lib/seams/env.d.ts +2 -1
- package/lib/seams/guards.d.ts +4 -43
- package/lib/seams/keeper.d.ts +1 -1
- package/lib/seams/system-prompt.d.ts +1 -5
- package/lib/session-cleanup.d.ts +3 -2
- package/lib/{settings-section-BuPGQv_H.js → settings-section-DTYZjwUs.js} +65 -9
- package/lib/settings-section.d.ts +3 -31
- package/lib/skiff-core.d.ts +4 -9
- package/lib/skiff-debug.d.ts +15 -21
- package/lib/skiff-registry-FTjoWQTQ.js +25 -0
- package/lib/skiff-registry.d.ts +2 -1
- package/lib/{skiff-role-DAfPb6YQ.js → skiff-role-CEHL5cek.js} +1 -1
- package/lib/skiff-role.d.ts +2 -2
- package/lib/skills/opencode-scan.d.ts +3 -2
- package/lib/skills-discovery.d.ts +15 -2
- package/lib/status.d.ts +2 -1
- package/lib/tools/cce.d.ts +1 -2
- package/lib/tools/container-admin.d.ts +7 -3
- package/lib/tools/eap.d.ts +2 -3
- package/lib/tools/handyman.d.ts +0 -29
- package/lib/tools/msm.d.ts +0 -4
- package/lib/tools/neat.d.ts +1 -2
- package/lib/tools/praxis.d.ts +0 -1
- package/lib/tools/skiff-admin.d.ts +2 -2
- package/lib/tools/trajectory.d.ts +7 -15
- package/lib/totp.d.ts +0 -4
- package/lib/trajectory-assistant.d.ts +2 -1
- package/lib/trajectory-bound-Cax1p9ut.js +190 -0
- package/lib/trajectory-bound.d.ts +3 -4
- package/lib/{trajectory-bound-C8DUxi6_.js → trajectory-ops-mrXK0H0I.js} +2 -159
- package/lib/trajectory-ops.d.ts +4 -9
- package/lib/trajectory-skills.d.ts +71 -0
- package/lib/{wake-registry-D0Vj0WXb.js → wake-registry-CYxIb484.js} +7 -20
- package/lib/wake-registry.d.ts +3 -11
- package/lib/wake-scheduler.d.ts +13 -49
- package/lib/web-fetch-provider.d.ts +0 -21
- package/lib/{weixin-api-PjEhmjlZ.js → weixin-api-CtFYm53S.js} +3 -9
- package/lib/weixin-api.d.ts +6 -37
- package/lib/weixin-bridge.d.ts +5 -24
- package/lib/weixin-hook.d.ts +6 -12
- package/lib/weixin-output-guard.d.ts +2 -1
- package/lib/{weixin-route-D1ND823E.js → weixin-route-B2ajFypI.js} +4 -5
- package/lib/weixin-route.d.ts +0 -2
- package/lib/weixin-send-api.d.ts +15 -6
- package/package.json +2 -4
- package/experiments/autopilot-trajectory/SKILL.md +0 -115
- package/experiments/autopilot-trajectory/scripts/autopilot-trajectory.ts +0 -546
- package/lib/autopilot-script.d.ts +0 -40
- package/lib/skiff-debug-D83-Njy7.js +0 -2867
- package/lib/{ccc-eu_IPF94.js → ccc-NlLr_sxy.js} +1 -1
- package/lib/{session-cleanup-CMT4mHWt.js → session-cleanup-B6IHZgww.js} +1 -1
package/lib/wake-scheduler.d.ts
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
* 补跑窗口 2h(超窗置 missed 留痕)|同 tick 串行|唤起后维持 live(人类可介入)。
|
|
23
23
|
*/
|
|
24
24
|
import type { Context } from 'cordis';
|
|
25
|
-
import type
|
|
25
|
+
import { type ClockRuntime } from './clock-runtime.js';
|
|
26
26
|
import { type WakeEntry } from './wake-registry.js';
|
|
27
27
|
/** 投递结果(写回条目的 lastResult;人读) */
|
|
28
|
-
|
|
28
|
+
interface WakeDeliveryResult {
|
|
29
29
|
ok: boolean;
|
|
30
30
|
detail: string;
|
|
31
31
|
}
|
|
@@ -33,29 +33,15 @@ export interface WakeDeliveryResult {
|
|
|
33
33
|
* 调度器**进程态**(诊断用,模块级 = 进程级,正是诊断对象)。
|
|
34
34
|
*
|
|
35
35
|
* 为什么需要它(R↓,2026-09-14 F 段缺陷):调度器此前**没有任何可观测面**——
|
|
36
|
-
* "条目为何一直是 pending"
|
|
36
|
+
* "条目为何一直是 pending" 只能靠反推。有了这几个字段,`acc-diag` 一次调用即可回答
|
|
37
37
|
* "时钟是否武装 / 上次 tick 何时 / 为何跳过"。
|
|
38
|
+
*
|
|
39
|
+
* C6b(P2):字段由 {@link ClockRuntime} 提供(**工厂那份**,字段名与语义一个字未改);
|
|
40
|
+
* 此处只把 `lastTickLog` 收为**必需**(本钟独有,autopilot 没有它——现状稿 §2.4)。
|
|
38
41
|
*/
|
|
39
|
-
|
|
40
|
-
/** 定时器是否在跑(startTimer 成功 → true;disposer 拆卸 → false) */
|
|
41
|
-
armed: boolean;
|
|
42
|
-
/** 武装时刻(ms;null = 从未) */
|
|
43
|
-
armedAt: number | null;
|
|
44
|
-
/** 上次真正执行 tick 的时刻(ms;null = 从未——被跳过的 tick 不刷新它) */
|
|
45
|
-
lastTickAt: number | null;
|
|
46
|
-
/** 真正执行过多少次 tick */
|
|
47
|
-
ticks: number;
|
|
48
|
-
/** 上次 tick 的逐行摘要(投递 / missed 留痕) */
|
|
42
|
+
export type WakeSchedulerRuntime = ClockRuntime & {
|
|
49
43
|
lastTickLog: string[];
|
|
50
|
-
/** 上次被跳过 / 异常的原因(null = 上次正常执行) */
|
|
51
|
-
lastSkipReason: string | null;
|
|
52
|
-
}
|
|
53
|
-
/** 调度器进程态快照(只读;`enabled` = 全局闸**当前**值,便于区分"未武装"与"闸关") */
|
|
54
|
-
export declare function wakeSchedulerState(): WakeSchedulerRuntime & {
|
|
55
|
-
enabled: boolean;
|
|
56
44
|
};
|
|
57
|
-
/** 测试用:复位进程态(避免用例间串味) */
|
|
58
|
-
export declare function __resetWakeSchedulerStateForTest(): void;
|
|
59
45
|
/** 目标定位:目录名 + SESSION.md 绝对路径 */
|
|
60
46
|
interface WakeTarget {
|
|
61
47
|
dirName: string;
|
|
@@ -68,32 +54,12 @@ interface WakeTarget {
|
|
|
68
54
|
* @returns 命中返回目录信息,未命中 null
|
|
69
55
|
*/
|
|
70
56
|
export declare function resolveWakeTarget(root: string, target: string): WakeTarget | null;
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* **一次性唤醒 `wake-later` 被连带关掉**,注册表条目静默滞留(当日 6.6h 零 tick)。
|
|
78
|
-
* 缺省由 false 改 true 的理由:唤醒注册表已是一等机制(D58),条目**全部由人类/agent 显式登记**
|
|
79
|
-
* 未来时刻(无环境自主性),不需要"默认关"的实验保护;代价 = 一个 unref 的 5min 空检查。
|
|
80
|
-
*
|
|
81
|
-
* 设置服务不可用 → 关(保守;异常由日志与 `dashboard health` 响亮暴露,不静默)。
|
|
82
|
-
*/
|
|
83
|
-
export declare function wakeSchedulerEnabled(): boolean;
|
|
84
|
-
/**
|
|
85
|
-
* 取目标 agent:live 优先 → 冷会话走 sessionController.resolveAgent → 标题回退。
|
|
86
|
-
* @param ctx 插件上下文
|
|
87
|
-
* @param root CCC 根
|
|
88
|
-
* @param dirName 目标 trajectory 目录名
|
|
89
|
-
* @returns 命中返回 agent 与取得方式(how 进 lastResult,便于诊断);未命中返回原因
|
|
90
|
-
*/
|
|
91
|
-
export declare function acquireWakeAgent(ctx: Context, root: string, dirName: string): Promise<{
|
|
92
|
-
agent: Agent;
|
|
93
|
-
how: string;
|
|
94
|
-
} | {
|
|
95
|
-
error: string;
|
|
96
|
-
}>;
|
|
57
|
+
/** 调度器进程态快照(只读;`enabled` = 全局闸**当前**值,便于区分"未武装"与"闸关") */
|
|
58
|
+
export declare function wakeSchedulerState(): WakeSchedulerRuntime & {
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** 测试用:复位进程态(避免用例间串味) */
|
|
62
|
+
export declare function __resetWakeSchedulerStateForTest(): void;
|
|
97
63
|
/** 唤醒消息(唤起即投递正文:身份锚定 + 唤醒信息 + 任务) */
|
|
98
64
|
export declare function buildWakeText(entry: WakeEntry, target: WakeTarget): string;
|
|
99
65
|
/**
|
|
@@ -104,8 +70,6 @@ export declare function buildWakeText(entry: WakeEntry, target: WakeTarget): str
|
|
|
104
70
|
* @returns 投递结果(写回 lastResult)
|
|
105
71
|
*/
|
|
106
72
|
export declare function deliverWake(ctx: Context, root: string, entry: WakeEntry): Promise<WakeDeliveryResult>;
|
|
107
|
-
/** 一次调度 tick:遍历 live CCC → 到期项串行投递 / 超窗项置 missed;返回人读摘要 */
|
|
108
|
-
export declare function runWakeTick(ctx: Context): Promise<string[]>;
|
|
109
73
|
/**
|
|
110
74
|
* 装配调度器(index.ts apply 调用):5min tick + 生命周期 disposer +
|
|
111
75
|
* 会话出现/settings 变化时热启动(与 autopilot 同款触发面,互不干扰)。
|
|
@@ -24,27 +24,6 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { Context } from 'cordis';
|
|
26
26
|
import type { HttpFetchResolver } from '@deepseek-ai/dsh-web-fetch-http';
|
|
27
|
-
/**
|
|
28
|
-
* 与宿主 `WebError` 同形的最小错误(带机器可路由的 `code`)。
|
|
29
|
-
*
|
|
30
|
-
* 为什么不 import 宿主的 WebError:宿主 peer 包在测试环境不可解析(现有测试全部
|
|
31
|
-
* `vi.mock('@deepseek-ai/dsh-tools')` 同因),而 `dsh-tool-web` 只渲染 `error.message`、
|
|
32
|
-
* 不判 `instanceof`——因此本地错误对象足以满足契约,且让本模块零运行时宿主依赖。
|
|
33
|
-
*/
|
|
34
|
-
export declare function fetchError(message: string, code: string): Error;
|
|
35
|
-
/**
|
|
36
|
-
* 传输与配额上限。
|
|
37
|
-
*
|
|
38
|
-
* 值镜像 `@deepseek-ai/dsh-web-fetch-http` 的 Config 默认值(该包 README 的字段表;
|
|
39
|
-
* 它不导出解析后的默认值,`Config` 是 schemastery schema 而非结果)。`userAgent`
|
|
40
|
-
* 运行时取该包导出的 `DEFAULT_USER_AGENT`(单一真相源,不复制字符串)。
|
|
41
|
-
*/
|
|
42
|
-
export declare const FETCH_LIMIT_DEFAULTS: {
|
|
43
|
-
readonly maxResponseBytes: 5000000;
|
|
44
|
-
readonly maxBodyChars: 100000;
|
|
45
|
-
readonly timeoutMs: 30000;
|
|
46
|
-
readonly maxRedirects: 5;
|
|
47
|
-
};
|
|
48
27
|
/** 公网单播 IPv4(拒绝全部保留/私网段——与宿主判定口径一致,只额外放行 fake-ip) */
|
|
49
28
|
export declare function isPublicV4(address: string): boolean;
|
|
50
29
|
/** fake-ip 段判定(198.18.0.0/15) */
|
|
@@ -18,14 +18,8 @@ import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:
|
|
|
18
18
|
* - sendmessage 必须回带 context_token 关联对话
|
|
19
19
|
*/
|
|
20
20
|
var weixin_api_exports = /* @__PURE__ */ __exportAll({
|
|
21
|
-
ILINK_CDN_BASE_URL: () => ILINK_CDN_BASE_URL,
|
|
22
|
-
ILINK_DEFAULT_BASE_URL: () => ILINK_DEFAULT_BASE_URL,
|
|
23
|
-
MessageItemType: () => MessageItemType,
|
|
24
|
-
MessageState: () => MessageState,
|
|
25
|
-
MessageType: () => MessageType,
|
|
26
21
|
TypingStatus: () => TypingStatus,
|
|
27
22
|
aes128EcbDecrypt: () => aes128EcbDecrypt,
|
|
28
|
-
assertIlinkOk: () => assertIlinkOk,
|
|
29
23
|
buildClientVersion: () => buildClientVersion,
|
|
30
24
|
buildMediaDownloadUrl: () => buildMediaDownloadUrl,
|
|
31
25
|
downloadMedia: () => downloadMedia,
|
|
@@ -146,7 +140,7 @@ function assertIlinkOk(endpoint, rawText) {
|
|
|
146
140
|
async function fetchQRCode(params) {
|
|
147
141
|
const botType = params.botType ?? "3";
|
|
148
142
|
const rawText = await apiGet({
|
|
149
|
-
baseUrl: params.baseUrl ??
|
|
143
|
+
baseUrl: params.baseUrl ?? ILINK_DEFAULT_BASE_URL,
|
|
150
144
|
endpoint: `ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(botType)}`,
|
|
151
145
|
timeoutMs: params.timeoutMs ?? 5e3
|
|
152
146
|
});
|
|
@@ -155,7 +149,7 @@ async function fetchQRCode(params) {
|
|
|
155
149
|
async function pollQRStatus(params) {
|
|
156
150
|
try {
|
|
157
151
|
const rawText = await apiGet({
|
|
158
|
-
baseUrl: params.baseUrl ??
|
|
152
|
+
baseUrl: params.baseUrl ?? ILINK_DEFAULT_BASE_URL,
|
|
159
153
|
endpoint: `ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(params.qrcode)}`,
|
|
160
154
|
timeoutMs: params.timeoutMs ?? 35e3
|
|
161
155
|
});
|
|
@@ -272,7 +266,7 @@ async function sendFileMessage(params) {
|
|
|
272
266
|
}
|
|
273
267
|
assertIlinkOk("ilink/bot/getuploadurl", uplRaw);
|
|
274
268
|
if (!upl.upload_full_url && !upl.upload_param) throw new Error(`getuploadurl 响应缺 upload_full_url/upload_param: ${uplRaw.slice(0, 300)}`);
|
|
275
|
-
const uploadUrl = upl.upload_full_url ??
|
|
269
|
+
const uploadUrl = upl.upload_full_url ?? `${ILINK_CDN_BASE_URL}/upload?encrypted_query_param=${encodeURIComponent(upl.upload_param ?? "")}&filekey=${encodeURIComponent(upl.filekey ?? fileKey)}`;
|
|
276
270
|
const cipher = createCipheriv("aes-128-ecb", aesKey, null);
|
|
277
271
|
const encBody = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
278
272
|
const uploadRes = await currentFetch(uploadUrl, {
|
package/lib/weixin-api.d.ts
CHANGED
|
@@ -14,26 +14,12 @@
|
|
|
14
14
|
* - getupdates 长轮询 35s hold;游标 get_updates_buf 从响应原样带回续传
|
|
15
15
|
* - sendmessage 必须回带 context_token 关联对话
|
|
16
16
|
*/
|
|
17
|
-
/** iLink API Base URL(腾讯官方) */
|
|
18
|
-
export declare const ILINK_DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com";
|
|
19
|
-
/** CDN Base(媒体上传/下载;P3 媒体期用) */
|
|
20
|
-
export declare const ILINK_CDN_BASE_URL = "https://novac2c.cdn.weixin.qq.com/c2c";
|
|
21
17
|
/** 版本号 → ClientVersion 整数:(major<<16)|(minor<<8)|patch */
|
|
22
18
|
export declare function buildClientVersion(version: string): number;
|
|
23
19
|
/** fetch 注入点(测试替换;生产 = 全局 fetch) */
|
|
24
|
-
|
|
20
|
+
type FetchLike = typeof fetch;
|
|
25
21
|
/** 测试注入:替换全局 fetch 实现(生产零调用) */
|
|
26
22
|
export declare function __setWeixinFetchForTest(fn: FetchLike | null): void;
|
|
27
|
-
/**
|
|
28
|
-
* iLink 业务层返回码校验(v1.30.9 修复):`apiPost` 只判 HTTP 状态,而 iLink 在 **HTTP 200**
|
|
29
|
-
* 的响应体里用 `ret` / `errcode` 表达失败(如 `{ret:1,errmsg:"denied"}`)——此前被当作成功,
|
|
30
|
-
* 于是"发送成功"的判定是假的:回复路径会给一条**从未送达**的消息触发 outgoing hook 记录
|
|
31
|
-
* (与 weixin-bridge 注释"发送失败不记录"矛盾)。发送类调用一律经此校验。
|
|
32
|
-
* 非 JSON 的 200 响应保持既有宽容语义(视为成功)。
|
|
33
|
-
* @param endpoint 端点名(错误信息定位用)
|
|
34
|
-
* @param rawText 响应体原文
|
|
35
|
-
*/
|
|
36
|
-
export declare function assertIlinkOk(endpoint: string, rawText: string): void;
|
|
37
23
|
/** 取登录二维码(无需凭据;实证裸调可用) */
|
|
38
24
|
export declare function fetchQRCode(params: {
|
|
39
25
|
baseUrl?: string;
|
|
@@ -44,7 +30,7 @@ export declare function fetchQRCode(params: {
|
|
|
44
30
|
qrcode_img_content: string;
|
|
45
31
|
}>;
|
|
46
32
|
/** 扫码状态(轮询;1s 间隔建议,5min 有效) */
|
|
47
|
-
|
|
33
|
+
interface QrStatusResult {
|
|
48
34
|
status: string;
|
|
49
35
|
bot_token?: string;
|
|
50
36
|
ilink_bot_id?: string;
|
|
@@ -58,7 +44,7 @@ export declare function pollQRStatus(params: {
|
|
|
58
44
|
timeoutMs?: number;
|
|
59
45
|
}): Promise<QrStatusResult>;
|
|
60
46
|
/** CDN 媒体元数据(下载侧;协议见 docs/weixin-bot-api.md §6) */
|
|
61
|
-
|
|
47
|
+
interface CDNMedia {
|
|
62
48
|
encrypt_query_param?: string;
|
|
63
49
|
aes_key?: string;
|
|
64
50
|
encrypt_type?: number;
|
|
@@ -116,7 +102,7 @@ export interface WeixinMessage {
|
|
|
116
102
|
item_list?: WeixinMessageItem[];
|
|
117
103
|
context_token?: string;
|
|
118
104
|
}
|
|
119
|
-
|
|
105
|
+
interface GetUpdatesResp {
|
|
120
106
|
ret?: number;
|
|
121
107
|
errcode?: number;
|
|
122
108
|
errmsg?: string;
|
|
@@ -131,24 +117,6 @@ export declare function getUpdates(params: {
|
|
|
131
117
|
getUpdatesBuf?: string;
|
|
132
118
|
timeoutMs?: number;
|
|
133
119
|
}): Promise<GetUpdatesResp>;
|
|
134
|
-
export declare const MessageType: {
|
|
135
|
-
readonly NONE: 0;
|
|
136
|
-
readonly USER: 1;
|
|
137
|
-
readonly BOT: 2;
|
|
138
|
-
};
|
|
139
|
-
export declare const MessageState: {
|
|
140
|
-
readonly NEW: 0;
|
|
141
|
-
readonly GENERATING: 1;
|
|
142
|
-
readonly FINISH: 2;
|
|
143
|
-
};
|
|
144
|
-
export declare const MessageItemType: {
|
|
145
|
-
readonly NONE: 0;
|
|
146
|
-
readonly TEXT: 1;
|
|
147
|
-
readonly IMAGE: 2;
|
|
148
|
-
readonly VOICE: 3;
|
|
149
|
-
readonly FILE: 4;
|
|
150
|
-
readonly VIDEO: 5;
|
|
151
|
-
};
|
|
152
120
|
/** 发文本消息(主动发起时可不带 context_token;md→plain 内置——微信不支持 Markdown)。
|
|
153
121
|
* v1.30.9:HTTP 200 但 `ret/errcode != 0` → 抛错(此前静默当成功,导致"记录已送达"的假象)。 */
|
|
154
122
|
export declare function sendTextMessage(params: {
|
|
@@ -188,7 +156,7 @@ export declare const TypingStatus: {
|
|
|
188
156
|
readonly TYPING: 1;
|
|
189
157
|
readonly CANCEL: 0;
|
|
190
158
|
};
|
|
191
|
-
|
|
159
|
+
interface GetConfigResp {
|
|
192
160
|
ret?: number;
|
|
193
161
|
errmsg?: string;
|
|
194
162
|
typing_ticket?: string;
|
|
@@ -236,3 +204,4 @@ export declare function downloadMedia(params: {
|
|
|
236
204
|
} | null>;
|
|
237
205
|
/** Markdown → 纯文本(代码块/图片/链接/表格/标题/粗斜体/删除线 7 类) */
|
|
238
206
|
export declare function markdownToPlainText(text: string): string;
|
|
207
|
+
export {};
|
package/lib/weixin-bridge.d.ts
CHANGED
|
@@ -17,26 +17,6 @@ import { type WeixinAccountCredential } from './weixin-route.js';
|
|
|
17
17
|
import { type WeixinMessage } from './weixin-api.js';
|
|
18
18
|
/** 测试辅助:清空 typing_ticket 缓存(生产零调用) */
|
|
19
19
|
export declare function resetWeixinTypingCache(): void;
|
|
20
|
-
/**
|
|
21
|
-
* 手动输出模式的**机制标记**(v1.30.10 引入;v1.30.16 按 S142 用户"这个词不能让 ACC 定义,
|
|
22
|
-
* 要让 CCC 定义"重构)。
|
|
23
|
-
*
|
|
24
|
-
* 边界(R↓):ACC 只提供**机制与数据**——"桥不转发最终文本"这个事实 + 三个已填好的参数值
|
|
25
|
-
* (CCC 根 / 账号 / 用户 id)。**纪律措辞归 CCC**:怎么写、必须怎么做、后果是什么,全部写在
|
|
26
|
-
* CCC 的角色提示词文件里(如 `.opencode/skiff/zhaocai.md` 的「输出通道」节),CCC 可随时改,
|
|
27
|
-
* 且 v1.30.15 起角色提示词热重载——改完立即生效,无需 ACC 发版。
|
|
28
|
-
*
|
|
29
|
-
* 为什么不用 ACC 写措辞(历史教训):v1.30.10~v1.30.15 由 ACC 内嵌一段纪律文案,用户实测
|
|
30
|
-
* "约束不够,LLM 不听"——且措辞迭代要动插件代码 + 发版 + 重启;把措辞放 CCC 才能快速迭代,
|
|
31
|
-
* 也符合"ACC 管机制、CCC 管内容"的归属二分。
|
|
32
|
-
*
|
|
33
|
-
* 标记格式(稳定,供 CCC 提示词引用;v1.31.0 起为 ACC 工具形态):
|
|
34
|
-
* ```
|
|
35
|
-
* [serenity:weixin-manual-output]
|
|
36
|
-
* im-bridge({channel:"weixin", action:"send", account:"<account>", user:"<user>", text:"<回复>"})
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
export declare function weixinManualOutputMarker(root: string, accountId: string, userId: string): string;
|
|
40
20
|
/**
|
|
41
21
|
* 手动输出模式的**兜底判定**(纯函数,v1.30.17——把决策矩阵从装配里抽出来,可独立测试)。
|
|
42
22
|
*
|
|
@@ -83,8 +63,8 @@ export declare function stopCccBridge(root: string): void;
|
|
|
83
63
|
*/
|
|
84
64
|
export declare function stopAllBridges(): void;
|
|
85
65
|
/** 主动发送失败原因(稳定 code——入口层翻译成 HTTP 状态 + 可行动提示) */
|
|
86
|
-
|
|
87
|
-
|
|
66
|
+
type ProactiveSendErrorCode = 'BRIDGE_DISABLED' | 'NO_ACCOUNT' | 'ACCOUNT_NOT_FOUND' | 'ACCOUNT_NOT_BOUND' | 'SEND_FAILED';
|
|
67
|
+
interface ProactiveSendInput {
|
|
88
68
|
/** CCC 根(绝对路径;由入口层解析名称/路径后传入) */
|
|
89
69
|
root: string;
|
|
90
70
|
/** 目标用户(iLink from_user_id,形如 xxx@im.wechat;别名解析归调用方) */
|
|
@@ -94,7 +74,7 @@ export interface ProactiveSendInput {
|
|
|
94
74
|
/** 发送账号(缺省 = 该 CCC 第一个启用且已绑定的账号) */
|
|
95
75
|
accountId?: string;
|
|
96
76
|
}
|
|
97
|
-
|
|
77
|
+
type ProactiveSendResult = {
|
|
98
78
|
ok: true;
|
|
99
79
|
accountId: string;
|
|
100
80
|
userId: string;
|
|
@@ -122,7 +102,7 @@ export type ProactiveSendResult = {
|
|
|
122
102
|
* @returns 成功含 accountId/userId/sessionId/role;失败含稳定 code 与可行动提示(不抛错)
|
|
123
103
|
*/
|
|
124
104
|
/** 账号解析结果(文本 / 文件发送共用) */
|
|
125
|
-
|
|
105
|
+
type WeixinAccountResolution = {
|
|
126
106
|
ok: true;
|
|
127
107
|
accountId: string;
|
|
128
108
|
cred: WeixinAccountCredential;
|
|
@@ -154,3 +134,4 @@ export declare function weixinBridgeStatus(): Array<{
|
|
|
154
134
|
* 事件驱动(对齐 autotrajectory v1.26.15):live 会话出现 → 同步该 CCC 桥。
|
|
155
135
|
*/
|
|
156
136
|
export declare function registerWeixinBridge(ctx: Context): void;
|
|
137
|
+
export {};
|
package/lib/weixin-hook.d.ts
CHANGED
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
*
|
|
14
14
|
* 定位:Mech 纯逻辑(事件构造纯函数 + 执行器确定性),可独立单测。
|
|
15
15
|
*/
|
|
16
|
-
/** hook 执行超时(旁路记录足够;超时 kill 防挂死脚本) */
|
|
17
|
-
export declare const WEIXIN_HOOK_TIMEOUT_MS = 15000;
|
|
18
16
|
/** 媒体引用(hook 事件载荷:kind + 相对 CCC 根路径——CCC 可自行决定是否持久保存媒体) */
|
|
19
17
|
export interface WeixinHookMediaRef {
|
|
20
18
|
kind: 'image' | 'file';
|
|
@@ -54,7 +52,7 @@ export interface WeixinHookIncomingEvent extends WeixinHookEventBase {
|
|
|
54
52
|
* - `proactive` = 桥被调用主动发给指定用户(CCC MSM 经本机入口发起)
|
|
55
53
|
* - `reply-fallback`(v1.30.17)= 手动输出模式下 agent 本轮一次都没发送成功 → 桥兜底转发其最终文本
|
|
56
54
|
*/
|
|
57
|
-
|
|
55
|
+
type WeixinOutgoingSource = 'reply' | 'proactive' | 'reply-fallback';
|
|
58
56
|
/** outgoing 事件(bot → 用户):回复文本(已剥离 think) */
|
|
59
57
|
export interface WeixinHookOutgoingEvent extends WeixinHookEventBase {
|
|
60
58
|
event: 'outgoing';
|
|
@@ -69,11 +67,9 @@ export interface WeixinHookOutgoingEvent extends WeixinHookEventBase {
|
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
69
|
/** 全部 hook 事件(判别联合) */
|
|
72
|
-
|
|
73
|
-
/** 事件载荷(JSON 序列化:不含任何会话凭据——H5) */
|
|
74
|
-
export type WeixinHookEventJson = WeixinHookEvent;
|
|
70
|
+
type WeixinHookEvent = WeixinHookIncomingEvent | WeixinHookOutgoingEvent;
|
|
75
71
|
/** incoming 事件构造输入(bridge 提供实参) */
|
|
76
|
-
|
|
72
|
+
interface IncomingHookInput {
|
|
77
73
|
cccRoot: string;
|
|
78
74
|
accountId: string;
|
|
79
75
|
userId: string;
|
|
@@ -83,7 +79,7 @@ export interface IncomingHookInput {
|
|
|
83
79
|
media: WeixinHookMediaRef[];
|
|
84
80
|
}
|
|
85
81
|
/** outgoing 事件构造输入(bridge 提供实参) */
|
|
86
|
-
|
|
82
|
+
interface OutgoingHookInput {
|
|
87
83
|
cccRoot: string;
|
|
88
84
|
accountId: string;
|
|
89
85
|
userId: string;
|
|
@@ -104,7 +100,7 @@ export declare function buildIncomingHookEvent(input: IncomingHookInput): Weixin
|
|
|
104
100
|
/** 构造 outgoing 事件对象(纯函数,可测) */
|
|
105
101
|
export declare function buildOutgoingHookEvent(input: OutgoingHookInput): WeixinHookOutgoingEvent;
|
|
106
102
|
/** hook 执行结果(测试/日志用;调用方只关心无异常) */
|
|
107
|
-
|
|
103
|
+
interface WeixinHookRunResult {
|
|
108
104
|
ok: boolean;
|
|
109
105
|
detail?: string;
|
|
110
106
|
}
|
|
@@ -115,10 +111,8 @@ export interface WeixinHookRunResult {
|
|
|
115
111
|
* 脚本缺失 → {ok:false}(配置了但未实现——日志提示;不视为异常)。
|
|
116
112
|
*/
|
|
117
113
|
export declare function runWeixinHook(root: string, hookRel: string, event: WeixinHookEvent, timeoutMs?: number): Promise<WeixinHookRunResult>;
|
|
118
|
-
/** 测试辅助:把 WeixinHookEvent 转单行 JSON(脚本侧读取约定) */
|
|
119
|
-
export declare function hookEventToStdinLine(event: WeixinHookEvent): string;
|
|
120
114
|
/** hook runner 签名(可注入——bridge 集成测试捕获事件防真实 spawn flake) */
|
|
121
|
-
|
|
115
|
+
type WeixinHookRunner = (root: string, hookRel: string, event: WeixinHookEvent) => Promise<WeixinHookRunResult>;
|
|
122
116
|
/** 测试辅助:替换 runner(null → 还原真实 spawn 执行);生产零调用 */
|
|
123
117
|
export declare function setWeixinHookRunnerForTest(runner: WeixinHookRunner | null): void;
|
|
124
118
|
/** bridge 调用入口(转发 activeRunner——默认真实 spawn;测试可注入捕获) */
|
|
@@ -23,7 +23,7 @@ import type { Context } from 'cordis';
|
|
|
23
23
|
/** 打回上限(超过则放弃并告警——避免与模型无限拉扯) */
|
|
24
24
|
export declare const WEIXIN_OUTPUT_REBUKE_MAX = 2;
|
|
25
25
|
/** 手动模式会话上下文(桥登记) */
|
|
26
|
-
|
|
26
|
+
interface ManualOutputSession {
|
|
27
27
|
root: string;
|
|
28
28
|
accountId: string;
|
|
29
29
|
userId: string;
|
|
@@ -61,3 +61,4 @@ export declare function __resetWeixinOutputGuardForTest(): void;
|
|
|
61
61
|
* 只对**已登记的手动模式会话**生效——其他会话(主舱/其他 skiff/ACP 临时会话)零干预。
|
|
62
62
|
*/
|
|
63
63
|
export declare function registerWeixinOutputGuard(ctx: Context): void;
|
|
64
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-NlLr_sxy.js";
|
|
4
3
|
import { join, resolve } from "node:path";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
//#region src/localstore-ops.ts
|
|
7
7
|
/**
|
|
@@ -102,7 +102,7 @@ function writeAll(root, data) {
|
|
|
102
102
|
/** 读取命名空间全部条目:credential → 扁平;config → 分节(剔除 credentials 保留节) */
|
|
103
103
|
function readStore(root, scope) {
|
|
104
104
|
const all = readAll(root);
|
|
105
|
-
if (scope === "credential") return all[
|
|
105
|
+
if (scope === "credential") return all[CREDENTIALS_SECTION] ?? {};
|
|
106
106
|
const { [CREDENTIALS_SECTION]: _cred, ...rest } = all;
|
|
107
107
|
return rest;
|
|
108
108
|
}
|
|
@@ -162,7 +162,7 @@ function getEntry(root, scope, name) {
|
|
|
162
162
|
const all = readAll(root);
|
|
163
163
|
if (scope === "credential") {
|
|
164
164
|
assertCredentialKey(name);
|
|
165
|
-
return all[
|
|
165
|
+
return all[CREDENTIALS_SECTION]?.[name] ?? null;
|
|
166
166
|
}
|
|
167
167
|
const { section, key } = assertConfigPath(name);
|
|
168
168
|
return all[section]?.[key] ?? null;
|
|
@@ -296,7 +296,6 @@ function runLocalStore(root, args) {
|
|
|
296
296
|
* 不绑定具体 role(用户自选路由目标)。
|
|
297
297
|
*/
|
|
298
298
|
var weixin_route_exports = /* @__PURE__ */ __exportAll({
|
|
299
|
-
WEIXIN_SESSION_PREFIX: () => WEIXIN_SESSION_PREFIX,
|
|
300
299
|
clearWeixinCredential: () => clearWeixinCredential,
|
|
301
300
|
extractWeixinMedia: () => extractWeixinMedia,
|
|
302
301
|
extractWeixinText: () => extractWeixinText,
|
package/lib/weixin-route.d.ts
CHANGED
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { type WeixinSettings, type WeixinRouteConfig, type WeixinAccountConfig } from './ccc.js';
|
|
15
15
|
import type { WeixinMediaRef, WeixinMessageItem } from './weixin-api.js';
|
|
16
|
-
/** 微信桥 skiff 会话 id 前缀(seams 旁路判定;对外面纯净——守卫识别外部面) */
|
|
17
|
-
export declare const WEIXIN_SESSION_PREFIX = "skiff-weixin-";
|
|
18
16
|
/** 判定 sessionId 是否为微信桥会话(外部面——输出守卫/轨迹隐藏生效) */
|
|
19
17
|
export declare function isWeixinSessionId(sessionId: string | undefined): boolean;
|
|
20
18
|
/** 微信用户 → 固定会话 id(同用户长期同一会话,记忆延续;多用户天然隔离)。
|
package/lib/weixin-send-api.d.ts
CHANGED
|
@@ -22,23 +22,21 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { type ServerResponse } from 'node:http';
|
|
24
24
|
import type { Context } from 'cordis';
|
|
25
|
+
import { type FaceSpec } from './face-host.js';
|
|
25
26
|
import { weixinSendEndpoint } from './weixin-send-endpoint.js';
|
|
26
27
|
export { weixinSendEndpoint };
|
|
27
28
|
/** 文本长度上限(微信侧单条消息实践上限;超限拒绝而非静默截断) */
|
|
28
29
|
export declare const WEIXIN_SEND_MAX_TEXT = 4000;
|
|
29
|
-
/** 当前入口地址(MSM 环境变量注入用;未启动 → null)——状态在叶模块(msm-ops 零依赖读取) */
|
|
30
|
-
/** 测试辅助:读取当前监听端口(生产零调用) */
|
|
31
|
-
export declare function weixinSendPort(): number | null;
|
|
32
30
|
/** 来源必须是 loopback(127.0.0.1 / ::1 / IPv4-mapped) */
|
|
33
31
|
export declare function isLoopbackAddress(address: string | undefined): boolean;
|
|
34
|
-
|
|
32
|
+
interface ParsedSendRequest {
|
|
35
33
|
ok: true;
|
|
36
34
|
ccc: string;
|
|
37
35
|
user: string;
|
|
38
36
|
text: string;
|
|
39
37
|
accountId?: string;
|
|
40
38
|
}
|
|
41
|
-
|
|
39
|
+
type ParseResult = ParsedSendRequest | {
|
|
42
40
|
ok: false;
|
|
43
41
|
error: string;
|
|
44
42
|
remediation?: string;
|
|
@@ -78,12 +76,23 @@ export declare function handleWeixinSendRequest(ctx: Context, req: {
|
|
|
78
76
|
};
|
|
79
77
|
[Symbol.asyncIterator]?: unknown;
|
|
80
78
|
}, res: ServerResponse): Promise<void>;
|
|
81
|
-
/**
|
|
79
|
+
/** 本面的规格(C4 块 A/④:**只提供** name/port/host/enabled/handler——样板与生命周期归 face-host) */
|
|
80
|
+
export declare function weixinSendSpec(ctx: Context, cfg: {
|
|
81
|
+
enabled: boolean;
|
|
82
|
+
port: number;
|
|
83
|
+
}): FaceSpec;
|
|
84
|
+
/** 启动监听器(仅 127.0.0.1);已启动 → 幂等返回既有端口 */
|
|
82
85
|
export declare function startWeixinSendApi(ctx: Context, port: number): Promise<number>;
|
|
83
86
|
/** 停止监听器(幂等) */
|
|
84
87
|
export declare function stopWeixinSendApi(): void;
|
|
85
88
|
/**
|
|
86
89
|
* 装配(index.ts apply 调用):按 plugin 全局配置 weixinApi 启停,配置变化热同步。
|
|
87
90
|
* 默认启用(仅 loopback,零公网暴露);`enabled:false` 或 `port:0` 关闭。
|
|
91
|
+
*
|
|
92
|
+
* C4 块 A:启停判据归面规格(`weixinSendSpec.enabled`)+ 宿主统一读取(`faceEnabled`)——
|
|
93
|
+
* 本函数不再手写 `if (want && !active) start / if (!want && active) stop` 样板,
|
|
94
|
+
* 且**停服仍是同步的**(原语义:配置一关,`weixinSendEndpoint()` 当拍变 null)。
|
|
95
|
+
* 🔒 自带的 `ctx.effect` disposer 已删除:拆卸路径归一到 `seams/lifecycle.ts` 的
|
|
96
|
+
* 聚合入口(`stopAllFaces`)——两套拆卸并存正是 C4 要收的重复形态。
|
|
88
97
|
*/
|
|
89
98
|
export declare function registerWeixinSendApi(ctx: Context): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.34.
|
|
3
|
+
"version": "1.34.2",
|
|
4
4
|
"description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:11 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/im-bridge/acc-diag)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.5-rc.2。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,9 +30,7 @@
|
|
|
30
30
|
"lib/**/*.d.ts",
|
|
31
31
|
"cordis.patch.yml",
|
|
32
32
|
"dsh.plugin.json",
|
|
33
|
-
"README.md"
|
|
34
|
-
"experiments/autopilot-trajectory/SKILL.md",
|
|
35
|
-
"experiments/autopilot-trajectory/scripts/autopilot-trajectory.ts"
|
|
33
|
+
"README.md"
|
|
36
34
|
],
|
|
37
35
|
"scripts": {
|
|
38
36
|
"typecheck": "tsc --noEmit",
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: autopilot-trajectory-experiment
|
|
3
|
-
description: Autopilot Trajectory(自动巡航轨迹,正式版;前身自主轨迹实验)参与 skill。本 skill 让 CCC 完整理解机制背景(人类 waiting 是 trajectory 速度瓶颈)、目的(验证"无人等待的 trajectory"能否加速认知推进)、方式(时钟唤起 + 先验偏见 + 轨迹焦点 + 前台运行 + 多 CCC 独立),并提供一站式管理入口(v1.33 起归 `container_admin autopilot`:status 全报告 / init 初始化 / generate-bias 验证偏见内容;条件链诊断走开发面脚本)。任何希望参与的 CCC 复制本目录到 .opencode/skills/ 即可开始。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Skill: autopilot-trajectory-experiment
|
|
7
|
-
|
|
8
|
-
> 本 skill 是 Autopilot Trajectory(自动巡航轨迹)的 **CCC 参与入口**——加载本 skill 即完整理解机制的**背景、目的、方式**。
|
|
9
|
-
> 实验管理(v1.33 起):`container_admin autopilot status | init | generate-bias`(原 `trajectory all/init/random`——D58 起工具更名 `trajectory`,v1.33 起 autopilot 面归机务舱,硬切无别名)
|
|
10
|
-
> 理论依据:serenity-acc-specs `docs/self-sustaining-trajectory-hypothesis.md`(v0.1 猜想)
|
|
11
|
-
|
|
12
|
-
## 触发条件/何时加载
|
|
13
|
-
|
|
14
|
-
- CCC 被选为自主轨迹实验对象时(用户指定)
|
|
15
|
-
- 需要理解"无人等待的 trajectory"实验的背景/目的/参与方式时
|
|
16
|
-
- 需要预检/查看实验配置时
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 1. 背景:为什么有这个实验
|
|
21
|
-
|
|
22
|
-
认知容器理论(specs §0)确立:**Trajectory 是主体**(Agent 可替换、Session 载体可重建、LLM 是认知介质);认知容器 = 发生/存储/再发生的地方。
|
|
23
|
-
|
|
24
|
-
由此观察到**结构性瓶颈**:
|
|
25
|
-
|
|
26
|
-
> **人类 waiting 拖慢 trajectory**:当轨迹以"等待人类"为推进条件时,其事件序列时间被人类响应间隔(钟表时间)锚定。等待人类 = 轨迹空转——人类响应越慢,轨迹运转越慢。
|
|
27
|
-
|
|
28
|
-
**猜想**:设计"无人等待"的 trajectory——不依赖人类输入而自动唤起,唤起时携带先验偏见(自主动机)。若成立,轨迹运转速度提升,更快产生让人类满意的效果。
|
|
29
|
-
|
|
30
|
-
## 2. 实验目的(验证什么)
|
|
31
|
-
|
|
32
|
-
| 命题 | 内容 |
|
|
33
|
-
|------|------|
|
|
34
|
-
| P4 | 无人等待的 trajectory 可以时钟驱动自动唤起并携带先验偏见(自生+随机) |
|
|
35
|
-
| P5 | 轨迹运转速度提升 → 更快产生让人类满意的效果 |
|
|
36
|
-
| 反证 | 熵增失控 / 自我确认循环 / 随机噪音化 / 资源无界 / 反馈脱节——任一显著 → 猜想不成立 |
|
|
37
|
-
|
|
38
|
-
## 3. 参与方式(CCC 侧四步——第一步可一键 init)
|
|
39
|
-
|
|
40
|
-
### ① 初始化(一键):`container_admin autopilot init`
|
|
41
|
-
|
|
42
|
-
自动完成:写配置(`.opencode/serenity.json` `trajectory.autopilot` 段)+ 生成偏见提供者脚本模板(CCC 根 `autopilot-bias.ts`)。
|
|
43
|
-
|
|
44
|
-
```jsonc
|
|
45
|
-
// 写入的配置(init 后可在 .opencode/serenity.json 查看/调整)
|
|
46
|
-
{
|
|
47
|
-
"trajectory": {
|
|
48
|
-
"autopilot": { // 原 autopilotTrajectory 段,字段不变
|
|
49
|
-
"enabled": true, // 总开关(缺省 false,默认关零资源占用)
|
|
50
|
-
"intervalHours": 12, // 无人类活动 N 小时后唤起(缺省 12)
|
|
51
|
-
"biasProvider": "autopilot-bias.ts", // 偏见内容提供者脚本(CCC 根下)
|
|
52
|
-
"topPrompt": "本轨迹的核心焦点:<CCC 填写>", // 轨迹焦点:CCC 定义,每次唤起最先注入
|
|
53
|
-
"session": "S###", // 必填:目标会话(不配置绝不唤起)
|
|
54
|
-
"avoidWakeHours": { "start": 8, "end": 18 } // 可选:避开北京高峰(缺省 8~18 省钱)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### ② 定义轨迹焦点(topPrompt——CCC 自己填写)
|
|
61
|
-
|
|
62
|
-
**CCC 定义 `trajectory.autopilot` 时同时定义本轨迹的顶层提示词**(`topPrompt`):核心目标/纪律/质量要求(示例:"持续深化某领域认知,产出可重建的结论与决策记录")。它会在**每次唤起时最先注入**(`[轨迹焦点]` 段,位于身份锚定之前,影响力最大),作为**稳定焦点锚定 trajectory**——**实验观察:无焦点锚定时,多轮自主唤起中轨迹腐化严重(焦点丢失)**。与偏见内容的分工:**焦点=稳定锚(每轮不变),偏见=随机探索方向(每轮不同),互补**。init 生成占位,CCC 按自己轨迹目标改写(勿留空——留空 = 唤起无焦点锚定,轨迹易漂移)。
|
|
63
|
-
|
|
64
|
-
### ③ 实现偏见内容提供者(`autopilot-bias.ts`)
|
|
65
|
-
|
|
66
|
-
CCC 根目录下一个脚本,**stdout 输出本轮唤起注入的偏见内容**(反事实问题/探索方向/任何让轨迹偏离既有路径的输入)。**偏见内容归 CCC**——用本 CCC 自己的反馈信息来源保证"足够随机"。`container_admin autopilot generate-bias` 可验证输出。
|
|
67
|
-
|
|
68
|
-
### ④ 标记目标会话(可选自生动机段)
|
|
69
|
-
|
|
70
|
-
- 目标会话目录名加 `--auto` 后缀:`AGENT_SESSIONS/<date>--<desc>--auto/`——**只有带标志的轨迹走自主形态**,同 CCC 其他会话不受影响
|
|
71
|
-
- 可选:该 SESSION.md 写「下一轮动机」段(上一轮预写 → 下一轮唤起的自生偏见)
|
|
72
|
-
|
|
73
|
-
## 4. 机制运行(dsp 侧,CCC 无需干预)
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
定时器(每 10min)→ 唤起条件全满足 →
|
|
77
|
-
① 读 topPrompt(CCC 定义的轨迹焦点)→ 唤起消息首段注入
|
|
78
|
-
② 运行 <biasProvider> 脚本 → stdout = 偏见内容(CCC 自定)
|
|
79
|
-
③ 读 SESSION.md「下一轮动机」段 → 自生动机
|
|
80
|
-
④ 定位活跃会话 agent → 注入唤起消息(前台运行——用户全程可见、随时可介入)
|
|
81
|
-
→ 模型自动继续:探索/反事实检验 → 产出落 SESSION.md「自主探索日志」+ 预写「下一轮动机」
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**唤起条件**(全部满足):① enabled ② 会话目录 `--auto` ③ SESSION.md mtime 距今 > intervalHours ④ 北京时间非高峰(缺省避开 8~18)⑤ 无运行中的唤起轮。**偏见提供者脚本缺失 → 唤起中止并报错要求实现**(不静默)。
|
|
85
|
-
|
|
86
|
-
**人类角色**:不触发、不中断;回复/评价天然并入(同一前台会话);轨迹不等人类。
|
|
87
|
-
|
|
88
|
-
## 5. 实验管理(`container_admin autopilot`)——一站式
|
|
89
|
-
|
|
90
|
-
| 用法 | 功能 |
|
|
91
|
-
|------|------|
|
|
92
|
-
| `container_admin autopilot status`(**推荐,无参即全报告**) | **一站式全报告**:背景摘要 + 就绪度检查 + 当前状态 + 下一步指引 + 步骤——CCC agent 看一次即完整理解并知道怎么开始 |
|
|
93
|
-
| `container_admin autopilot init` | **一键初始化**:写配置(`trajectory.autopilot`)+ 生成偏见提供者脚本模板(CCC 根 autopilot-bias.ts) |
|
|
94
|
-
| `container_admin autopilot generate-bias` | 运行偏见提供者脚本,输出当前偏见内容(验证) |
|
|
95
|
-
| (开发面)`bun <包内脚本> check` | 仅就绪度检查(配置/轨迹焦点 topPrompt/偏见提供者/--auto 标志/动机段) |
|
|
96
|
-
| (开发面)`bun <包内脚本> status` | 仅当前状态(配置快照/目标会话/距上次活动/唤起窗口/可唤起性) |
|
|
97
|
-
| (开发面)`bun <包内脚本> diag` | 唤起条件链诊断(逐条件 + 阻断点 + 修复建议)——CCC 侧另有专属工具 `acc-diag`(含进程内 live 运行态) |
|
|
98
|
-
| (开发面)`bun <包内脚本> doc` / `guide` | 机制定义全文(本 SKILL.md)/ 仅步骤指引 |
|
|
99
|
-
|
|
100
|
-
## 6. 观察与验证
|
|
101
|
-
|
|
102
|
-
- **观察**:无人类活动满 intervalHours 且非高峰 → 前台会话自动出现 `[Autopilot Trajectory 唤起]` 消息(可见可介入)
|
|
103
|
-
- **验证阶段**:A 机制可行性(3~5 轮)→ B 速度对比(72h 有/无等待)→ C 质量与熵(人类评审 + H_op)→ D 长期(数周,检验自我确认/熵增)
|
|
104
|
-
- **成功判据**:自主轮产出有意义的比例 ≥ 阈值,且 H_op 维持可运转
|
|
105
|
-
|
|
106
|
-
## 7. 边界
|
|
107
|
-
|
|
108
|
-
- 本实验**非标准条款**——不修改 Serenity-ACC 标准正文;验证成立后才评估进入标准演化议程
|
|
109
|
-
- 默认关闭;未配置 = 零资源占用;不触碰 CCC 其他会话/机制
|
|
110
|
-
|
|
111
|
-
## 相关
|
|
112
|
-
|
|
113
|
-
- 猜想全文:serenity-acc-specs `docs/self-sustaining-trajectory-hypothesis.md`
|
|
114
|
-
- 机制定义:dsh-serenity-plugin `docs/autopilot-trajectory.md`
|
|
115
|
-
- 标准理论:serenity-acc-specs README §0
|