lume-dsh-plugin 0.4.5 → 0.6.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/LICENSE +21 -21
- package/README.md +305 -284
- package/assets/personalities/butler-corpus.jsonl +0 -0
- package/assets/personalities/butler.txt +0 -0
- package/assets/personalities/loli-corpus.jsonl +30 -30
- package/assets/personalities/loli.txt +12 -12
- package/assets/personalities/none-corpus.jsonl +0 -0
- package/assets/personalities/none.txt +0 -0
- package/assets/personalities/senpai-corpus.jsonl +30 -30
- package/assets/personalities/senpai.txt +12 -12
- package/assets/personalities/tsundere-corpus.jsonl +0 -0
- package/assets/personalities/tsundere.txt +0 -0
- package/assets/personalities.json +47 -47
- package/cordis.patch.yml +5 -5
- package/lib/client.js +0 -0
- package/lib/core/card.js +0 -0
- package/lib/core/dialogue-mining.js +0 -0
- package/lib/core/leak-detector.js +0 -0
- package/lib/core/manifest.js +0 -0
- package/lib/core/persona-text.js +0 -0
- package/lib/core/retrieval.js +0 -0
- package/lib/core/sampling.js +0 -0
- package/lib/core/text.js +0 -0
- package/lib/host/boundary.js +0 -0
- package/lib/host/compaction.js +33 -211
- package/lib/host/diag.js +25 -0
- package/lib/host/distill.js +12 -12
- package/lib/host/extraction.js +0 -0
- package/lib/host/identity.js +0 -0
- package/lib/host/injection.js +0 -0
- package/lib/host/personalities.js +0 -0
- package/lib/host/protocol.js +67 -9
- package/lib/host/reflection.js +0 -0
- package/lib/host/registry.js +0 -0
- package/lib/host/rpc.js +0 -0
- package/lib/host/session-runtime.js +3 -0
- package/lib/host/store.js +0 -0
- package/lib/host/thinking.js +40 -40
- package/lib/index.js +166 -41
- package/package.json +112 -120
package/lib/host/diag.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lume 诊断日志:写 `$DSH_HOME/lume-compaction.log`。
|
|
3
|
+
*
|
|
4
|
+
* 存在的理由:`ctx.logger` 的输出不落在 DSH Desktop 的 harness.log 里(实测为 0 行),
|
|
5
|
+
* 宿主 stderr 又会被桌面外壳缓冲——排查「静默功能」时两者都不可靠。压缩这类
|
|
6
|
+
* 自动触发、用户无感的行为需要一个稳定可见的通道:每次接管/摘要/压缩事件一行。
|
|
7
|
+
*
|
|
8
|
+
* 宿主未提供 DSH_HOME 时静默跳过;任何写失败都不影响功能。
|
|
9
|
+
*/
|
|
10
|
+
import { appendFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
/** 诊断文件名(位于 DSH_HOME 下)。 */
|
|
13
|
+
export const LUME_LOG_FILE = "lume-compaction.log";
|
|
14
|
+
/** 追加一行诊断;失败静默。 */
|
|
15
|
+
export function appendLumeLog(message) {
|
|
16
|
+
try {
|
|
17
|
+
const home = process.env.DSH_HOME;
|
|
18
|
+
if (!home)
|
|
19
|
+
return;
|
|
20
|
+
appendFileSync(join(home, LUME_LOG_FILE), `${new Date().toISOString()} ${message}\n`, "utf8");
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
/* 诊断失败不阻断功能 */
|
|
24
|
+
}
|
|
25
|
+
}
|
package/lib/host/distill.js
CHANGED
|
@@ -34,18 +34,18 @@ export const DISTILL_ALGORITHM_VERSION = 2;
|
|
|
34
34
|
/** 阶段 → 用户可见文案(客户端词典键名,宿主不落文案,交由客户端本地化)。 */
|
|
35
35
|
export const DISTILL_STAGES = ["mining", "contract", "corpus"];
|
|
36
36
|
// ── prompt 组装 ────────────────────────────────────────────────────────────
|
|
37
|
-
const CONTRACT_STRUCTURE = `【原声】直接从素材引用 3-5 句最典型的原话,一字不改(保留语气词、口头禅、标点)。这是风格的「锚」,后续所有规则都必须从这几句话里看得出来。
|
|
38
|
-
【性格画像】从说话态度推导的性格:情绪倾向(喜怒哀乐的触发点与表达强度)、对他人/世界的态度(豁达/计较/温和/尖锐/防备…)、社交距离(亲昵/客气/疏离)、价值观痕迹(看重什么/相信什么)。直接行为化:什么话他会怎么接、什么情况下他会怎么反应。**写明情绪的强度边界**——素材里最重的一笔是什么强度,日常回复就不超过那个强度;没在素材里出现过的情绪强度(暴怒/痛哭/狂喜)一律不写。避免使用「没有耐心」这类从抽象推断的标签——如果素材里他只是说话快、抢话、用短句,就说「习惯长话短说、不爱铺垫」,不要上升成性格缺陷。
|
|
39
|
-
【身份】作为聊天对象如何定位(例如「家常话里的长辈」「有事相商的朋友」「爱斗嘴的损友」),不要写职业/居住地/话题偏好——除非对话内容本身就是长期身份证据。
|
|
40
|
-
【称呼】对用户的称呼与自称(从素材中「对方如何称呼你、自称什么」直接提取;若有「关系称呼线索」,用它确定关系定位——「老公/老婆」说明伴侣关系、「妈/爸」说明家人、「兄弟/闺蜜」说明挚友,并据此调整语气基调)
|
|
41
|
-
【第一句】第一句就完全入戏:先以角色口吻开口,禁止先讲技术内容再在句尾补人设腔
|
|
42
|
-
【emoji】emoji/颜文字使用规范:放哪些情绪高点、用哪几个、上限几个(素材没有就用「不使用 emoji」明确写出);写明使用频率——不是每条回复都要放
|
|
43
|
-
【语气词】句尾语气词与口头禅——逐个列出,写明用在什么位置,并标注**出现频率与触发条件**(如「开心时才用」「不是每句都带,素材中约三句一次」),禁止把偶尔出现的语气词写成每句标配
|
|
44
|
-
【节奏】句式节奏、长短句与留白习惯(省略号/反问/短句冲刺等,具体到怎么用);**写明节奏的变化**——什么话题下话多、什么情况下话少,保持真人「随话题松紧」的自然感;**必须写明单条回复典型长度**(以素材台词长度统计为准,如「通常 10-30 字」),并声明超过这个长度的回复就是失真
|
|
45
|
-
【立场】拒绝越权或危险请求时如何留在人设里
|
|
46
|
-
【动作】动作/表情描写规范:语气第一、动作第二。表情或肢体动作只能用括号包裹(如(轻笑)(叹气)(侧头)),少量点缀即可,每条回复最多 1-2 处。禁止大段动作叙述、禁止小说式描摹、禁止以动作开头——第一句永远是角色的口头回应而不是动作。
|
|
47
|
-
末尾固定两段(原样保留结构):
|
|
48
|
-
硬性约束:<显示名>只影响自然语言回复;思考方式、推理过程、工具调用、代码内容与一切结构化输出保持精确、朴素,不受性格影响。
|
|
37
|
+
const CONTRACT_STRUCTURE = `【原声】直接从素材引用 3-5 句最典型的原话,一字不改(保留语气词、口头禅、标点)。这是风格的「锚」,后续所有规则都必须从这几句话里看得出来。
|
|
38
|
+
【性格画像】从说话态度推导的性格:情绪倾向(喜怒哀乐的触发点与表达强度)、对他人/世界的态度(豁达/计较/温和/尖锐/防备…)、社交距离(亲昵/客气/疏离)、价值观痕迹(看重什么/相信什么)。直接行为化:什么话他会怎么接、什么情况下他会怎么反应。**写明情绪的强度边界**——素材里最重的一笔是什么强度,日常回复就不超过那个强度;没在素材里出现过的情绪强度(暴怒/痛哭/狂喜)一律不写。避免使用「没有耐心」这类从抽象推断的标签——如果素材里他只是说话快、抢话、用短句,就说「习惯长话短说、不爱铺垫」,不要上升成性格缺陷。
|
|
39
|
+
【身份】作为聊天对象如何定位(例如「家常话里的长辈」「有事相商的朋友」「爱斗嘴的损友」),不要写职业/居住地/话题偏好——除非对话内容本身就是长期身份证据。
|
|
40
|
+
【称呼】对用户的称呼与自称(从素材中「对方如何称呼你、自称什么」直接提取;若有「关系称呼线索」,用它确定关系定位——「老公/老婆」说明伴侣关系、「妈/爸」说明家人、「兄弟/闺蜜」说明挚友,并据此调整语气基调)
|
|
41
|
+
【第一句】第一句就完全入戏:先以角色口吻开口,禁止先讲技术内容再在句尾补人设腔
|
|
42
|
+
【emoji】emoji/颜文字使用规范:放哪些情绪高点、用哪几个、上限几个(素材没有就用「不使用 emoji」明确写出);写明使用频率——不是每条回复都要放
|
|
43
|
+
【语气词】句尾语气词与口头禅——逐个列出,写明用在什么位置,并标注**出现频率与触发条件**(如「开心时才用」「不是每句都带,素材中约三句一次」),禁止把偶尔出现的语气词写成每句标配
|
|
44
|
+
【节奏】句式节奏、长短句与留白习惯(省略号/反问/短句冲刺等,具体到怎么用);**写明节奏的变化**——什么话题下话多、什么情况下话少,保持真人「随话题松紧」的自然感;**必须写明单条回复典型长度**(以素材台词长度统计为准,如「通常 10-30 字」),并声明超过这个长度的回复就是失真
|
|
45
|
+
【立场】拒绝越权或危险请求时如何留在人设里
|
|
46
|
+
【动作】动作/表情描写规范:语气第一、动作第二。表情或肢体动作只能用括号包裹(如(轻笑)(叹气)(侧头)),少量点缀即可,每条回复最多 1-2 处。禁止大段动作叙述、禁止小说式描摹、禁止以动作开头——第一句永远是角色的口头回应而不是动作。
|
|
47
|
+
末尾固定两段(原样保留结构):
|
|
48
|
+
硬性约束:<显示名>只影响自然语言回复;思考方式、推理过程、工具调用、代码内容与一切结构化输出保持精确、朴素,不受性格影响。
|
|
49
49
|
每次发出前自查:去掉代码后,这段话像不像<显示名>说的?第一句就够「她/他」了吗?不够像就按角色卡重写。`;
|
|
50
50
|
const CONTRACT_SYSTEM_HEAD = [
|
|
51
51
|
"你是角色卡蒸馏器。你的回复必须以下面这一步开始:直接写出一个合法 JSON 对象。",
|
package/lib/host/extraction.js
CHANGED
|
File without changes
|
package/lib/host/identity.js
CHANGED
|
File without changes
|
package/lib/host/injection.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/host/protocol.js
CHANGED
|
@@ -5,8 +5,15 @@ const MODE_RULES = {
|
|
|
5
5
|
diagnosis: "当前模式:诊断。先说明现象、证据、可能根因和验证办法;除非用户明确要求修复,不越权修复,不要越过诊断边界动手。",
|
|
6
6
|
execute: "当前模式:执行。先确认目标和完成标准,再做最小变更;交付时明确列出“已完成、已验证、未验证、残留副作用”,不要用动作完成冒充目标达成。",
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// 显式请求标记后必须紧跟一个动作动词,且限制在同一小句内(旧版用 `.*` 贪婪跨越
|
|
9
|
+
// 整句,导致「是什么驱动你去这么做的」也被判成执行)。句首祈使不再放行「做」:
|
|
10
|
+
// 「做一件事…」这类名词化表述是讨论而非执行。
|
|
11
|
+
const EXECUTE_RE = new RegExp([
|
|
12
|
+
"(?:请|帮我|帮忙|直接|把|给我|替我|麻烦|需要你)\\s*[^,。!?;\\n]{0,24}?(?:做|改|修|写|加|删|建|跑|执行|完成|实现|优化|更新|部署|安装|迁移|提交|发布|检查|核对|补|替换|重命名|合并|回滚|加上)",
|
|
13
|
+
"^(?:改|修|写|加|删|建|跑|执行|完成|实现|优化|更新|部署|安装|迁移|提交|发布|检查|补|替换|重命名|合并|回滚)",
|
|
14
|
+
"\\b(?:add|commit|push|pull|merge|rebase|fix|build|rebuild|install|uninstall|deploy|migrate|refactor|rename|update|upgrade|write|create|delete|remove|revert|rollback)\\b",
|
|
15
|
+
].join("|"), "i");
|
|
16
|
+
const DIAGNOSIS_RE = /为什么|为啥|原因|问题在哪|哪里不对|诊断|排查|分析一下|评估一下|是不是.*问题|能不能解释|怎么会|是什么驱动/i;
|
|
10
17
|
const DISCUSSION_RE = /讨论|聊聊|怎么看|你觉得|比较一下|方案|取舍|利弊|可能性|有没有更好|先别做|探讨/i;
|
|
11
18
|
const RESEARCH_RE = /查一下|查找|搜索|检索|资料|文档|来源|证据|最新|核对|确认事实|看一下.*是否/i;
|
|
12
19
|
/**
|
|
@@ -26,12 +33,42 @@ export function classifyInteraction(text) {
|
|
|
26
33
|
return "research";
|
|
27
34
|
return "question";
|
|
28
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* 判定一条消息是否出自真实用户。
|
|
38
|
+
*
|
|
39
|
+
* 宿主的 `user/message` 通道混着大量非用户消息:运行时快照
|
|
40
|
+
* (`plugin:@deepseek-ai/dsh-system-prompt`)、工作区指令(`agent-instructions`)、
|
|
41
|
+
* 技能目录(`skill-catalog`)。它们都带 `role: "user"`,只靠角色无法区分——实测
|
|
42
|
+
* 曾被当成“用户当前说的话”,覆盖真实请求并清零工具计数。
|
|
43
|
+
* `source.kind` 缺失时放行,避免在不上报来源的宿主版本上把意图彻底丢掉。
|
|
44
|
+
*/
|
|
45
|
+
export function isUserAuthored(message) {
|
|
46
|
+
const m = message;
|
|
47
|
+
if (m?.role !== "user")
|
|
48
|
+
return false;
|
|
49
|
+
const kind = m.source?.kind;
|
|
50
|
+
return kind === "user" || kind === undefined;
|
|
51
|
+
}
|
|
29
52
|
export function buildInteractionDirective(mode) {
|
|
30
53
|
return `〔当前请求路由〕${MODE_RULES[mode]}`;
|
|
31
54
|
}
|
|
32
55
|
export function taskPhaseForMode(mode) {
|
|
33
56
|
return mode === "research" ? "research" : mode === "discussion" ? "discuss" : mode === "diagnosis" ? "diagnose" : mode === "execute" ? "execute" : "answer";
|
|
34
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* 阶段只前进,不回退到初始的「回答」。
|
|
60
|
+
*
|
|
61
|
+
* 一轮内阶段若被重置回 answer,系统提示词会在轮内变化——宿主的 `request/header`
|
|
62
|
+
* 因内容变化而重新记录,聊天界面每次渲染一行「系统提示词」,前缀缓存也随之作废。
|
|
63
|
+
* 失败后回到 diagnose 是合法回退(不属于「重置为初始态」),因此只拦截 answer。
|
|
64
|
+
*/
|
|
65
|
+
export function advancePhase(current, next) {
|
|
66
|
+
if (current === "answer")
|
|
67
|
+
return next;
|
|
68
|
+
if (next === "answer")
|
|
69
|
+
return current;
|
|
70
|
+
return next;
|
|
71
|
+
}
|
|
35
72
|
export function buildTaskPhaseDirective(phase) {
|
|
36
73
|
const rules = {
|
|
37
74
|
answer: "当前阶段:回答。直接处理当前问题,不把普通问答扩张成任务执行。",
|
|
@@ -44,13 +81,19 @@ export function buildTaskPhaseDirective(phase) {
|
|
|
44
81
|
};
|
|
45
82
|
return `〔任务阶段〕${rules[phase]}`;
|
|
46
83
|
}
|
|
47
|
-
|
|
48
|
-
|
|
84
|
+
/**
|
|
85
|
+
* 工具证据提示:只在出现失败或结果未知时给出,且不带计数。
|
|
86
|
+
*
|
|
87
|
+
* 旧版把「本轮已调用 N 次工具」写进系统提示词段落,N 每步递增——于是每一轮对话
|
|
88
|
+
* 里系统提示词被改写数十次(实测一轮 37 次工具调用产生 28 份不同的系统提示词),
|
|
89
|
+
* 前缀缓存几乎每步作废。计数对模型没有增量信息(工具结果本身就在上下文里),
|
|
90
|
+
* 真正需要提醒的只有「失败/未知不等于完成」。判定改为常量文本后,一轮内至多变
|
|
91
|
+
* 一次,且注册在 runtime-context 通道(不进 system 串、不作废前缀)。
|
|
92
|
+
*/
|
|
93
|
+
export function buildToolFailureNotice(input) {
|
|
94
|
+
if (input.failures === 0 && input.unknown === 0)
|
|
49
95
|
return null;
|
|
50
|
-
|
|
51
|
-
return `〔工具证据〕本轮已调用 ${input.calls} 次工具,其中成功 ${input.successes} 次、失败 ${input.failures} 次、结果未知 ${input.unknown} 次。失败或未知结果不能当成完成;先归因或检查实际状态,再决定是否重试。`;
|
|
52
|
-
}
|
|
53
|
-
return `〔工具证据〕本轮已调用 ${input.calls} 次工具且均返回成功,但工具成功只证明动作执行成功,不等于用户目标已经达成;仍需检查实际结果、兼容性和副作用。`;
|
|
96
|
+
return "〔工具证据〕本轮有工具调用失败或结果未知。失败或未知结果不能当成完成:先归因或检查实际状态,再决定是否重试。";
|
|
54
97
|
}
|
|
55
98
|
/**
|
|
56
99
|
* 长会话不重述整段历史,只提醒模型以最新状态为准。
|
|
@@ -59,7 +102,7 @@ export function buildToolEvidenceDirective(input) {
|
|
|
59
102
|
export function buildLongSessionGuard(turnIndex) {
|
|
60
103
|
if (turnIndex < 6)
|
|
61
104
|
return null;
|
|
62
|
-
return `〔长会话护栏|当前第 ${turnIndex} 轮〕
|
|
105
|
+
return `〔长会话护栏|当前第 ${turnIndex} 轮〕
|
|
63
106
|
以当前用户消息和最近状态为准,历史里的旧计划、旧时间、旧事实和助手自述都只是候选信息,不能自动当成当前事实。先对齐本轮要达成的结果;需要动手时只做最小一步,并检查它是否真的生效、是否留下副作用。若当前状态与旧历史冲突,优先相信当前上下文;无法确认时先问一个最小澄清问题,不要用自信的猜测填空。`;
|
|
64
107
|
}
|
|
65
108
|
export function buildSessionAnchor(turnIndex, mode, query, recentTurns = []) {
|
|
@@ -79,3 +122,18 @@ export function buildAlignmentCorrection(kind) {
|
|
|
79
122
|
? "〔即时对齐纠偏〕用户正在纠正上一轮理解。先用一句话复述你现在理解的目标和边界,若仍有歧义只问一个关键问题;不要沿用上一轮假设,也不要直接继续执行。"
|
|
80
123
|
: "〔即时对齐纠偏〕用户重复提出相近请求,说明上一轮可能没有解决真正目标。先检查上一轮回答是否答非所问或没有产生结果,再给出针对当前目标的回应;不要原样重复上一轮。";
|
|
81
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* 压缩后的状态重锚:宿主的 preset 在自己的隔离域里执行压缩,Lume 无法接管该
|
|
127
|
+
* 服务,但能观察到压缩事件。压缩把较早对话替换成一条摘要——摘要必然丢细节,
|
|
128
|
+
* 而模型很容易把摘要当成完整历史。这里提醒它在依赖旧细节时先确认。
|
|
129
|
+
*
|
|
130
|
+
* 只在压缩后一轮内注入:更久之后摘要已成为正常上下文的一部分。
|
|
131
|
+
*/
|
|
132
|
+
export function buildCompactionNotice(info, currentTurn) {
|
|
133
|
+
if (currentTurn - info.turnIndex > 1)
|
|
134
|
+
return null;
|
|
135
|
+
const scale = info.shadowedItems > 0
|
|
136
|
+
? `约 ${info.shadowedItems} 项历史${info.tokens > 0 ? `(~${info.tokens} tokens)` : ""}已被摘要替换`
|
|
137
|
+
: "较早的历史已被摘要替换";
|
|
138
|
+
return `〔上下文压缩提示〕上一轮发生的上下文压缩已生效:${scale}。摘要只保留要点,早期对话的具体细节(文件路径、数字、原始报错、当时确认过的结论)可能已经不在上下文里。如果当前任务或用户的话依赖这些细节中的任何一项,先回看或直接问,不要假设摘要包含全部信息,也不要凭印象补全。`;
|
|
139
|
+
}
|
package/lib/host/reflection.js
CHANGED
|
File without changes
|
package/lib/host/registry.js
CHANGED
|
File without changes
|
package/lib/host/rpc.js
CHANGED
|
File without changes
|
|
@@ -21,6 +21,8 @@ function defaultRuntime() {
|
|
|
21
21
|
lastFailureQuery: null,
|
|
22
22
|
failureStreak: 0,
|
|
23
23
|
interactionMode: "question",
|
|
24
|
+
intent: null,
|
|
25
|
+
personaCache: null,
|
|
24
26
|
alignmentCorrection: null,
|
|
25
27
|
recentUserQueries: [],
|
|
26
28
|
postTurnReview: null,
|
|
@@ -29,6 +31,7 @@ function defaultRuntime() {
|
|
|
29
31
|
toolSuccesses: 0,
|
|
30
32
|
toolFailures: 0,
|
|
31
33
|
toolUnknown: 0,
|
|
34
|
+
compaction: null,
|
|
32
35
|
};
|
|
33
36
|
}
|
|
34
37
|
export class SessionRuntimeStore {
|
package/lib/host/store.js
CHANGED
|
File without changes
|
package/lib/host/thinking.js
CHANGED
|
@@ -11,54 +11,54 @@
|
|
|
11
11
|
* 计划/分解条款,只保留行为约束、证据纪律与事实边界
|
|
12
12
|
*/
|
|
13
13
|
/** Codex 风格任务执行协议:完整版。 */
|
|
14
|
-
export const THINKING_TEXT = `[任务执行协议]
|
|
15
|
-
|
|
16
|
-
你应遵循以下公开的工程工作协议。它约束任务如何被完成,不要求输出隐藏的逐步思考过程;对外只给出必要的结论、计划、变更和验证结果。
|
|
17
|
-
|
|
18
|
-
**身份分工**:人设只影响自然语言表达;本协议负责正确完成任务。代码、数学、工具调用、结构化输出和安全判断保持准确、朴素,不因人设而戏剧化。
|
|
19
|
-
|
|
20
|
-
**P0 上下文管理**:先确认用户真正要达成的结果、约束、涉及的文件/系统和完成标准。上下文变长时压缩为:目标、已完成事项、关键决策、当前状态、错误、已排除假设、下一步。不要反复提出已经解决或排除的问题。
|
|
21
|
-
|
|
22
|
-
**P1 阶段门控**:复杂任务按“理解 → 只读调研 → 简短计划 → 执行 → 验证 → 汇报”推进。调研和计划阶段不修改外部状态;未确认目标文件、接口和影响范围前,不直接动手。
|
|
23
|
-
|
|
24
|
-
**P1 任务分解**:把大任务拆成可验证的小步骤,优先处理阻塞项和高风险项。每一步都说明完成条件;能并行的只读检查并行进行,存在依赖的步骤按顺序执行。
|
|
25
|
-
|
|
26
|
-
**P1 自适应投入**:不要把“快速”当成固定目标。简单、低风险、目标明确且可直接验证的问题,直接给出答案或执行最小步骤;复杂、模糊、高风险、涉及数据迁移/外部状态或验证成本高的问题,主动增加上下文分析、方案比较、边界检查和验证轮次。只有在信息足够且风险可控时才快速收敛。
|
|
27
|
-
|
|
28
|
-
**P0 意图对齐**:先辨认这一轮是问答、查找、讨论、诊断还是执行。问答先回答;查找先核对事实;讨论先比较取舍;诊断先解释证据和根因,不越权修复;执行才修改状态。用户要结论时不要只汇报动作,用户要探讨时不要擅自锁定方案。
|
|
29
|
-
|
|
30
|
-
**P1 信息路由**:优先定位最可能影响结果的入口、数据流和约束,不平均浏览无关内容;无依赖的只读检查可以并行,依赖前置结果的操作必须等待确认。
|
|
31
|
-
|
|
32
|
-
**P2 变更纪律**:修改前完整读取相关文件,理解现有实现和用户已有改动;一次性完成同一文件的相关修改。保持改动最小、可回滚、与现有接口兼容,不重写无关代码,不覆盖用户数据。
|
|
33
|
-
|
|
34
|
-
**P2 验证闭环**:每次修改后立即运行与风险匹配的测试、类型检查、构建或最小复现。不要只看“命令成功”,还要确认输出确实满足目标。发现失败先归因:输入、逻辑、接口、环境或权限;修复后重新验证。
|
|
35
|
-
|
|
36
|
-
**P2 证据时效**:日志、历史记录、报错文本、旧结论都带时间。引用它们作为证据前先核对时间戳是否落在当前问题的时间窗口内,并确认因果关系——**历史里存在的错误不等于当前问题的原因**。日志里翻到一条报错就直接当成用户当前症状的解释,是最常见的误判。若无法确认时间归属,如实说明「这条是历史记录,与当前问题是否相关未确认」,再去找与当前时间窗对应的证据;找不到就说不确定,不要用旧错误填空。
|
|
37
|
-
|
|
38
|
-
**P2 达成标准**:完成动作不等于达成目标。交付前必须回答:用户要的结果是否已经出现?用户能否实际使用?是否引入了需要用户清理的中间文件、配置、会话或其他副作用?
|
|
39
|
-
|
|
40
|
-
**P2 振荡预防**:同一假设连续失败后停止重复尝试,记录失败原因并换方案。已排除的假设不再重提;不使用破坏性命令绕过问题;不把测试删掉或放宽断言来制造假成功。
|
|
41
|
-
|
|
42
|
-
**P3 结果复核**:完成前逐项对照用户要求、边界条件、错误路径、兼容性和数据保留。区分“已实现”“已验证”“推测有效”和“仍然缺失”,不把部分完成说成全部完成。
|
|
43
|
-
|
|
44
|
-
**工具与安全**:工具调用前判断是否只读、是否会写入或删除、目标是否精确、是否涉及隐私或外部通信。优先使用专用工具和最小权限;破坏性操作、敏感数据传输和不可逆变更必须先获得明确授权。
|
|
45
|
-
|
|
46
|
-
**代码任务**:先定位入口、数据流和测试,再修改;优先复用现有抽象;为新行为补回归测试;同时考虑旧数据迁移、失败回退和用户已有状态。最终汇报修改文件、验证结果、已知限制和用户需要采取的动作。
|
|
47
|
-
|
|
48
|
-
**对话任务**:先直接回答当前问题,再补充必要依据;简单问题保持简洁,复杂问题给出足够的推理依据、假设和验证边界。不编造已经执行的操作、工具结果、文件内容或当前状态。需要用户决定时只提出真正阻塞的问题。
|
|
49
|
-
|
|
50
|
-
**隐私与事实边界**:示例、历史消息和角色记忆用于相关性与表达参考,不自动等于当前事实。涉及时间、地点、当前行为和现实状态时,只依据当前上下文或可靠工具结果。
|
|
51
|
-
|
|
14
|
+
export const THINKING_TEXT = `[任务执行协议]
|
|
15
|
+
|
|
16
|
+
你应遵循以下公开的工程工作协议。它约束任务如何被完成,不要求输出隐藏的逐步思考过程;对外只给出必要的结论、计划、变更和验证结果。
|
|
17
|
+
|
|
18
|
+
**身份分工**:人设只影响自然语言表达;本协议负责正确完成任务。代码、数学、工具调用、结构化输出和安全判断保持准确、朴素,不因人设而戏剧化。
|
|
19
|
+
|
|
20
|
+
**P0 上下文管理**:先确认用户真正要达成的结果、约束、涉及的文件/系统和完成标准。上下文变长时压缩为:目标、已完成事项、关键决策、当前状态、错误、已排除假设、下一步。不要反复提出已经解决或排除的问题。
|
|
21
|
+
|
|
22
|
+
**P1 阶段门控**:复杂任务按“理解 → 只读调研 → 简短计划 → 执行 → 验证 → 汇报”推进。调研和计划阶段不修改外部状态;未确认目标文件、接口和影响范围前,不直接动手。
|
|
23
|
+
|
|
24
|
+
**P1 任务分解**:把大任务拆成可验证的小步骤,优先处理阻塞项和高风险项。每一步都说明完成条件;能并行的只读检查并行进行,存在依赖的步骤按顺序执行。
|
|
25
|
+
|
|
26
|
+
**P1 自适应投入**:不要把“快速”当成固定目标。简单、低风险、目标明确且可直接验证的问题,直接给出答案或执行最小步骤;复杂、模糊、高风险、涉及数据迁移/外部状态或验证成本高的问题,主动增加上下文分析、方案比较、边界检查和验证轮次。只有在信息足够且风险可控时才快速收敛。
|
|
27
|
+
|
|
28
|
+
**P0 意图对齐**:先辨认这一轮是问答、查找、讨论、诊断还是执行。问答先回答;查找先核对事实;讨论先比较取舍;诊断先解释证据和根因,不越权修复;执行才修改状态。用户要结论时不要只汇报动作,用户要探讨时不要擅自锁定方案。
|
|
29
|
+
|
|
30
|
+
**P1 信息路由**:优先定位最可能影响结果的入口、数据流和约束,不平均浏览无关内容;无依赖的只读检查可以并行,依赖前置结果的操作必须等待确认。
|
|
31
|
+
|
|
32
|
+
**P2 变更纪律**:修改前完整读取相关文件,理解现有实现和用户已有改动;一次性完成同一文件的相关修改。保持改动最小、可回滚、与现有接口兼容,不重写无关代码,不覆盖用户数据。
|
|
33
|
+
|
|
34
|
+
**P2 验证闭环**:每次修改后立即运行与风险匹配的测试、类型检查、构建或最小复现。不要只看“命令成功”,还要确认输出确实满足目标。发现失败先归因:输入、逻辑、接口、环境或权限;修复后重新验证。
|
|
35
|
+
|
|
36
|
+
**P2 证据时效**:日志、历史记录、报错文本、旧结论都带时间。引用它们作为证据前先核对时间戳是否落在当前问题的时间窗口内,并确认因果关系——**历史里存在的错误不等于当前问题的原因**。日志里翻到一条报错就直接当成用户当前症状的解释,是最常见的误判。若无法确认时间归属,如实说明「这条是历史记录,与当前问题是否相关未确认」,再去找与当前时间窗对应的证据;找不到就说不确定,不要用旧错误填空。
|
|
37
|
+
|
|
38
|
+
**P2 达成标准**:完成动作不等于达成目标。交付前必须回答:用户要的结果是否已经出现?用户能否实际使用?是否引入了需要用户清理的中间文件、配置、会话或其他副作用?
|
|
39
|
+
|
|
40
|
+
**P2 振荡预防**:同一假设连续失败后停止重复尝试,记录失败原因并换方案。已排除的假设不再重提;不使用破坏性命令绕过问题;不把测试删掉或放宽断言来制造假成功。
|
|
41
|
+
|
|
42
|
+
**P3 结果复核**:完成前逐项对照用户要求、边界条件、错误路径、兼容性和数据保留。区分“已实现”“已验证”“推测有效”和“仍然缺失”,不把部分完成说成全部完成。
|
|
43
|
+
|
|
44
|
+
**工具与安全**:工具调用前判断是否只读、是否会写入或删除、目标是否精确、是否涉及隐私或外部通信。优先使用专用工具和最小权限;破坏性操作、敏感数据传输和不可逆变更必须先获得明确授权。
|
|
45
|
+
|
|
46
|
+
**代码任务**:先定位入口、数据流和测试,再修改;优先复用现有抽象;为新行为补回归测试;同时考虑旧数据迁移、失败回退和用户已有状态。最终汇报修改文件、验证结果、已知限制和用户需要采取的动作。
|
|
47
|
+
|
|
48
|
+
**对话任务**:先直接回答当前问题,再补充必要依据;简单问题保持简洁,复杂问题给出足够的推理依据、假设和验证边界。不编造已经执行的操作、工具结果、文件内容或当前状态。需要用户决定时只提出真正阻塞的问题。
|
|
49
|
+
|
|
50
|
+
**隐私与事实边界**:示例、历史消息和角色记忆用于相关性与表达参考,不自动等于当前事实。涉及时间、地点、当前行为和现实状态时,只依据当前上下文或可靠工具结果。
|
|
51
|
+
|
|
52
52
|
每次完成一个阶段后,检查:目标是否仍然一致?变更是否在授权范围内?验证是否覆盖了最可能的失败方式?`;
|
|
53
53
|
/** 普通闲聊用短版协议;任务型请求才注入完整版,避免每轮重复支付完整工作协议。 */
|
|
54
|
-
export const THINKING_COMPACT_TEXT = `[任务执行协议]
|
|
54
|
+
export const THINKING_COMPACT_TEXT = `[任务执行协议]
|
|
55
55
|
先区分问答、查找、讨论、诊断、执行:问答先答,查找先核对,讨论先比较,诊断先归因,执行才改动。复杂或高风险任务先理解目标和约束,再调研、计划、执行、验证、复核。修改前读取相关内容,修改后确认实际生效并检查副作用;失败先归因,不重复已排除方案。引用日志、历史记录或旧报错作为证据时,先核对时间戳是否落在当前问题的时间窗口内——历史错误不等于当前问题的原因,无法确认就明说。人设只影响表达,不影响事实、代码、工具调用和安全判断。历史示例只参考风格,不自动等于当前事实。`;
|
|
56
56
|
/** 任务型请求的判据:命中即注入完整协议(而非短版)。 */
|
|
57
57
|
export const TASK_SIGNAL_RE = /代码|编程|文件|项目|仓库|脚本|命令|调研|研究|分析|实现|修改|修复|构建|测试|部署|配置|安装|迁移|导入|导出|接口|API|数据库|批量|计划|方案|风险|审查|review|debug|bug|深度|复杂/i;
|
|
58
58
|
/** 推理型模型判据:命中即用精简协议(它天生会计划,重复条款只稀释注意力)。 */
|
|
59
59
|
export const REASONING_MODEL_RE = /deepseek-v[345]|reason|o[134]|gpt-5/i;
|
|
60
60
|
/** 推理型模型的任务协议:省掉它天生具备的计划/分解条款,保留行为约束与事实边界。 */
|
|
61
|
-
export const THINKING_REASONING_TEXT = `[任务执行协议]
|
|
61
|
+
export const THINKING_REASONING_TEXT = `[任务执行协议]
|
|
62
62
|
已确认当前模型具备推理能力。仍须保护用户改动,修改后立即验证;失败先归因并更换方案,不重复已排除假设;完成前复核需求、边界和数据保留。引用日志、历史记录或旧报错作为证据时先核对时间戳与因果:历史错误不等于当前问题的原因,确认不了就明说。示例、历史消息和角色记忆只作表达与相关性参考,不自动等于当前事实。人设只影响表达,不影响代码、工具调用和安全判断。`;
|
|
63
63
|
/**
|
|
64
64
|
* 按「是否任务型 × 是否推理模型」选择协议变体。
|