@chaoset/adaptive-perf 0.3.2 → 0.4.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/README.md +32 -0
- package/client/client.cjs +35 -2
- package/lib/index.mjs +96 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,17 @@
|
|
|
20
20
|
- **运行时上下文抑制**:对目标 preset 的会话调用 `suppressRuntimeContext()`
|
|
21
21
|
(与极简模式的 `includeRuntimeContext: false` 同一机制),每次模型请求省掉
|
|
22
22
|
"Current runtime context" 快照文本,**零功能损失**。
|
|
23
|
+
- **极简提示词层(minimalPrompt)**:参考实现的完整锚定条件——首轮轨迹由
|
|
24
|
+
**Minimal 的完整 system prompt** 决定,只收窄工具 schema 不够(标准/PTC 的
|
|
25
|
+
系统提示仍带 `harness:identity` / `harness:source` / `app:web-surface` 三个
|
|
26
|
+
全局引导段与标准 persona,思维链仍是 standard-like 的 "Let me…" 叙述)。本层
|
|
27
|
+
对目标会话:
|
|
28
|
+
- 按名阴影屏蔽三个全局引导段(空段在装配时被丢弃,等同极简 `complete`
|
|
29
|
+
persona 的效果;plan-mode 与 PTC 的 SDK 段不受影响);
|
|
30
|
+
- 按名阴影替换 `deployment:persona` 为极简语域 persona(默认与极简模式
|
|
31
|
+
逐字相同:`You are a helpful software engineer assistant.`)。
|
|
32
|
+
两处均为 agent 作用域的 prompt 段阴影,仅影响目标会话;**对已恢复/已晋升的
|
|
33
|
+
旧会话同样生效**(不依赖 bootstrap 阶段)。
|
|
23
34
|
- **工具目录自适应精简**:会话启动时按"工具族"默认隐藏高开销低频工具
|
|
24
35
|
(子代理 / 工作流 / ralph / goal 等编排类),只保留核心编码工具
|
|
25
36
|
(bash / 文件读写编辑 / 检索 / jobs / todo / 提问 / 网页搜索 / 技能 / 计划)。
|
|
@@ -36,6 +47,7 @@
|
|
|
36
47
|
|---|---|---|---|
|
|
37
48
|
| 首轮轨迹(决定后续行为风格) | Minimal 工具对锚定(5/5) | 任何 standard 系 schema 落入 standard-like(11/11) | 请求 #1 收窄到真实 Minimal 工具对,首个持久信号后恢复 |
|
|
38
49
|
| 首轮注入提醒 | 无 skill 目录/AGENTS.md 注入 | 自动注入(在场时锚定 0/9) | 请求 #1 剥离 `skill-catalog` + `agent-instructions` |
|
|
50
|
+
| 系统提示语域(persona + 全局引导段) | 一句话 persona,无任何引导段 | identity/source/web-surface 引导段 + 标准 persona("Let me…" 叙述来源) | minimalPrompt 层按名阴影屏蔽 3 个全局段 + 替换极简 persona(对旧会话同样生效) |
|
|
39
51
|
| 运行时上下文快照 | 关闭(`includeRuntimeContext: false`) | 每次请求注入文件策略/审批策略等快照 | 同一机制:`suppressRuntimeContext()` |
|
|
40
52
|
| 模型可见工具目录 | 2 个(bash、str_replace_editor) | ~22 个工具 schema 全部进请求 | bootstrap 后默认隐藏 4 个编排类工具族(~11 个工具),按需放行 |
|
|
41
53
|
| PTC SDK 参考段 | 无 | 全部工具的类型+描述渲染进提示 | 随目录缩小(同一 `visible` 视图驱动) |
|
|
@@ -89,6 +101,26 @@ dsh plugin --profile web remove @chaoset/adaptive-perf
|
|
|
89
101
|
| `escalateOnUnknownTool` | `true` | 工具调用失败(UNKNOWN_TOOL)→ 放行该族 |
|
|
90
102
|
| `coreTools` | 核心编码工具 | 展示用:不进入任何限制族 |
|
|
91
103
|
| `families` | 见下 | 工具族:`{ 族名: { enabled, tools, keywords } }` |
|
|
104
|
+
| `bootstrap` | 见下 | 首轮锚定(工具对 / 晋升信号 / 剥离上下文 / 压缩恢复集 / 预算封顶) |
|
|
105
|
+
| `minimalPrompt` | 见下 | 极简提示词层(语域锚定) |
|
|
106
|
+
|
|
107
|
+
`minimalPrompt`(极简提示词层,0.4.0 新增):
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"persona": "You are a helpful software engineer assistant.",
|
|
113
|
+
"suppressSections": true
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- `persona`:按名阴影替换 `deployment:persona`;默认与极简模式逐字相同,留空
|
|
118
|
+
(`""`)则不替换。
|
|
119
|
+
- `suppressSections`:屏蔽 `harness:identity` / `harness:source` / `app:web-surface`
|
|
120
|
+
三个全局引导段(等同极简 `complete` persona 的效果;plan-mode 与 PTC 的
|
|
121
|
+
SDK 段不受影响)。
|
|
122
|
+
- 生效范围:目标 preset 的全部会话,**包括已恢复/已晋升的旧会话**(不依赖
|
|
123
|
+
bootstrap 阶段);配置保存后热生效。
|
|
92
124
|
|
|
93
125
|
默认工具族(可整族禁用、改名、增删触发词):
|
|
94
126
|
|
package/client/client.cjs
CHANGED
|
@@ -55,7 +55,13 @@ window.__ModuleLoader__.load({
|
|
|
55
55
|
bootstrapCompactionTools: "压缩后工作集",
|
|
56
56
|
fieldBootstrapCompactionTools: "compaction/end 之后、再次晋升前额外可用的工具(核心工作集)。逗号分隔。",
|
|
57
57
|
bootstrapMaxTokens: "首轮输出预算封顶(token)",
|
|
58
|
-
fieldBootstrapMaxTokens: "请求 #1 的 maxTokens 封顶,晋升后自动剥离;0 = 不封顶(opt-in)"
|
|
58
|
+
fieldBootstrapMaxTokens: "请求 #1 的 maxTokens 封顶,晋升后自动剥离;0 = 不封顶(opt-in)",
|
|
59
|
+
minimalPromptEnabled: "极简提示词层(语域锚定)",
|
|
60
|
+
fieldMinimalPromptEnabled: "把系统提示拉回极简语域:屏蔽全局引导段 + 替换 persona。参考实现的完整锚定条件——仅收窄工具不足以翻转思维链风格(let me → let's/i'll/i need)",
|
|
61
|
+
minimalPromptPersona: "persona 文本",
|
|
62
|
+
fieldMinimalPromptPersona: "按名替换 deployment:persona;默认与极简模式逐字相同。留空 = 不替换(保留原 persona)",
|
|
63
|
+
minimalPromptSuppressSections: "屏蔽全局引导段",
|
|
64
|
+
fieldMinimalPromptSuppressSections: "屏蔽 harness:identity / harness:source / app:web-surface 三个全局段(等同极简 complete persona 的效果;plan-mode 与 PTC 的 SDK 段不受影响)"
|
|
59
65
|
};
|
|
60
66
|
const en = {
|
|
61
67
|
title: "Adaptive performance (adaptive-perf)",
|
|
@@ -94,7 +100,13 @@ window.__ModuleLoader__.load({
|
|
|
94
100
|
bootstrapCompactionTools: "Post-compaction work set",
|
|
95
101
|
fieldBootstrapCompactionTools: "Extra tools available after compaction/end until a new promotion signal (core work set). Comma-separated.",
|
|
96
102
|
bootstrapMaxTokens: "First-request output cap (tokens)",
|
|
97
|
-
fieldBootstrapMaxTokens: "maxTokens cap for request #1, stripped after promotion; 0 = no cap (opt-in)"
|
|
103
|
+
fieldBootstrapMaxTokens: "maxTokens cap for request #1, stripped after promotion; 0 = no cap (opt-in)",
|
|
104
|
+
minimalPromptEnabled: "Minimal prompt layer (register anchor)",
|
|
105
|
+
fieldMinimalPromptEnabled: "Pull the system prompt back to the minimal register: suppress the global orientation sections and replace the persona. The reference's full anchoring condition — tool narrowing alone does not flip the thinking style (let me → let's/i'll/i need)",
|
|
106
|
+
minimalPromptPersona: "Persona text",
|
|
107
|
+
fieldMinimalPromptPersona: "Shadows deployment:persona by name; defaults to the exact minimal-mode text. Empty = keep the original persona",
|
|
108
|
+
minimalPromptSuppressSections: "Suppress global orientation sections",
|
|
109
|
+
fieldMinimalPromptSuppressSections: "Shadow harness:identity / harness:source / app:web-surface to empty (same effect as minimal's complete persona; plan-mode and the PTC SDK sections are unaffected)"
|
|
98
110
|
};
|
|
99
111
|
|
|
100
112
|
// ── 表单字段 ─────────────────────────────────────────────────────────
|
|
@@ -317,6 +329,27 @@ window.__ModuleLoader__.load({
|
|
|
317
329
|
setDraft({ ...draft, bootstrap: { ...(draft.bootstrap || {}), maxTokens: Number.isSafeInteger(n) && n > 0 ? n : 0 } });
|
|
318
330
|
}
|
|
319
331
|
}),
|
|
332
|
+
react.createElement(BoolField, {
|
|
333
|
+
label: t("minimalPromptEnabled"),
|
|
334
|
+
hint: t("fieldMinimalPromptEnabled"),
|
|
335
|
+
value: draft === null ? false : (draft.minimalPrompt && draft.minimalPrompt.enabled === true),
|
|
336
|
+
disabled: draft === null,
|
|
337
|
+
onChange: (v) => setDraft({ ...draft, minimalPrompt: { ...(draft.minimalPrompt || {}), enabled: v } })
|
|
338
|
+
}),
|
|
339
|
+
react.createElement(BoolField, {
|
|
340
|
+
label: t("minimalPromptSuppressSections"),
|
|
341
|
+
hint: t("fieldMinimalPromptSuppressSections"),
|
|
342
|
+
value: draft === null ? false : (draft.minimalPrompt && draft.minimalPrompt.suppressSections === true),
|
|
343
|
+
disabled: draft === null || (draft.minimalPrompt && draft.minimalPrompt.enabled === false),
|
|
344
|
+
onChange: (v) => setDraft({ ...draft, minimalPrompt: { ...(draft.minimalPrompt || {}), suppressSections: v } })
|
|
345
|
+
}),
|
|
346
|
+
react.createElement(TextField, {
|
|
347
|
+
label: t("minimalPromptPersona"),
|
|
348
|
+
hint: t("fieldMinimalPromptPersona"),
|
|
349
|
+
value: draft === null ? "" : ((draft.minimalPrompt && draft.minimalPrompt.persona) || ""),
|
|
350
|
+
disabled: draft === null || (draft.minimalPrompt && draft.minimalPrompt.enabled === false),
|
|
351
|
+
onChange: (v) => setDraft({ ...draft, minimalPrompt: { ...(draft.minimalPrompt || {}), persona: v } })
|
|
352
|
+
}),
|
|
320
353
|
react.createElement(Field, {
|
|
321
354
|
label: t("families"),
|
|
322
355
|
hint: familiesInvalid ? t("invalidFamilies") + (familiesError !== null ? " — " + familiesError : "") : t("fieldFamilies")
|
package/lib/index.mjs
CHANGED
|
@@ -143,6 +143,27 @@ export const DEFAULT_CONFIG = {
|
|
|
143
143
|
/** 请求 #1 的输出预算封顶(token);0 = 不封顶(opt-in)。 */
|
|
144
144
|
maxTokens: 0,
|
|
145
145
|
},
|
|
146
|
+
/**
|
|
147
|
+
* 极简提示词层(语域锚定,参照 dsh-anchored-standard 的完整条件)。
|
|
148
|
+
*
|
|
149
|
+
* 参考实现指出:首轮"轨迹"(思维链风格)锚定需要 **Minimal 的完整 system
|
|
150
|
+
* prompt**——只收窄工具 schema 不够。本层对目标 preset 的会话:
|
|
151
|
+
* - suppressSections:按名阴影屏蔽全局引导段(harness:identity、
|
|
152
|
+
* harness:source、app:web-surface),空段在装配时被丢弃,等同极简
|
|
153
|
+
* complete persona 的效果(plan-mode 段、PTC 的 SDK 段不受影响);
|
|
154
|
+
* - persona:按名阴影替换 deployment:persona 为极简语域的短 persona
|
|
155
|
+
* (默认与极简模式逐字相同;留空则不替换)。
|
|
156
|
+
* 两处都是 agent 作用域的 prompt 段阴影,仅影响目标会话,随会话销毁自动
|
|
157
|
+
* 释放;对已恢复/已晋升的旧会话同样生效(不依赖 bootstrap 阶段)。
|
|
158
|
+
*/
|
|
159
|
+
minimalPrompt: {
|
|
160
|
+
/** 是否启用极简提示词层。 */
|
|
161
|
+
enabled: true,
|
|
162
|
+
/** 替换后的 persona 文本;与极简模式相同可完全对齐语域。留空不替换。 */
|
|
163
|
+
persona: 'You are a helpful software engineer assistant.',
|
|
164
|
+
/** 屏蔽全局引导段(identity / source / web-surface)。 */
|
|
165
|
+
suppressSections: true,
|
|
166
|
+
},
|
|
146
167
|
};
|
|
147
168
|
|
|
148
169
|
/** 轻量配置校验/归一化:非法字段回退默认值,避免 config.json 或 remote.set
|
|
@@ -203,6 +224,15 @@ export function normalizeConfig(source, defaults = DEFAULT_CONFIG) {
|
|
|
203
224
|
compactionTools: stringListOrEmpty(rawBootstrap.compactionTools, db.compactionTools),
|
|
204
225
|
maxTokens,
|
|
205
226
|
};
|
|
227
|
+
const rawMP = raw.minimalPrompt !== null && typeof raw.minimalPrompt === 'object' && !Array.isArray(raw.minimalPrompt)
|
|
228
|
+
? raw.minimalPrompt
|
|
229
|
+
: defaults.minimalPrompt;
|
|
230
|
+
const dm = defaults.minimalPrompt;
|
|
231
|
+
const minimalPrompt = {
|
|
232
|
+
enabled: boolValue(rawMP.enabled, dm.enabled),
|
|
233
|
+
persona: typeof rawMP.persona === 'string' ? rawMP.persona.trim() : dm.persona,
|
|
234
|
+
suppressSections: boolValue(rawMP.suppressSections, dm.suppressSections),
|
|
235
|
+
};
|
|
206
236
|
return {
|
|
207
237
|
enabled: boolValue(merged.enabled, defaults.enabled),
|
|
208
238
|
presets: stringList(merged.presets, defaults.presets),
|
|
@@ -213,6 +243,7 @@ export function normalizeConfig(source, defaults = DEFAULT_CONFIG) {
|
|
|
213
243
|
coreTools: stringList(merged.coreTools, defaults.coreTools),
|
|
214
244
|
families,
|
|
215
245
|
bootstrap,
|
|
246
|
+
minimalPrompt,
|
|
216
247
|
};
|
|
217
248
|
}
|
|
218
249
|
|
|
@@ -270,10 +301,37 @@ export function validateConfig(partial) {
|
|
|
270
301
|
}
|
|
271
302
|
}
|
|
272
303
|
}
|
|
304
|
+
if (partial.minimalPrompt !== void 0) {
|
|
305
|
+
const m = partial.minimalPrompt;
|
|
306
|
+
if (m === null || typeof m !== 'object' || Array.isArray(m)) {
|
|
307
|
+
throw new TypeError('adaptive-perf config field "minimalPrompt" must be an object');
|
|
308
|
+
}
|
|
309
|
+
if (m.enabled !== void 0 && typeof m.enabled !== 'boolean') {
|
|
310
|
+
throw new TypeError('adaptive-perf config field "minimalPrompt.enabled" must be a boolean');
|
|
311
|
+
}
|
|
312
|
+
if (m.suppressSections !== void 0 && typeof m.suppressSections !== 'boolean') {
|
|
313
|
+
throw new TypeError('adaptive-perf config field "minimalPrompt.suppressSections" must be a boolean');
|
|
314
|
+
}
|
|
315
|
+
if (m.persona !== void 0 && typeof m.persona !== 'string') {
|
|
316
|
+
throw new TypeError('adaptive-perf config field "minimalPrompt.persona" must be a string');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
273
319
|
}
|
|
274
320
|
|
|
275
321
|
// ── 纯函数(导出便于回归测试)────────────────────────────────────────────
|
|
276
322
|
|
|
323
|
+
/** 被极简提示词层屏蔽的全局引导段(name, order,与 dsh-app-boot /
|
|
324
|
+
* dsh-web-app / dsh-system-prompt 的注册一致)。 */
|
|
325
|
+
export const SECTION_SHADOWS = [
|
|
326
|
+
['harness:identity', -100],
|
|
327
|
+
['harness:source', -99],
|
|
328
|
+
['app:web-surface', -98],
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
/** persona 段的注册名与顺序(dsh-system-prompt 的 PERSONA_SECTION/PERSONA_ORDER)。 */
|
|
332
|
+
export const PERSONA_SECTION_NAME = 'deployment:persona';
|
|
333
|
+
export const PERSONA_SECTION_ORDER = 0;
|
|
334
|
+
|
|
277
335
|
/** 提取一条用户消息的顶层文本(text 块拼接)。 */
|
|
278
336
|
export function extractUserText(message) {
|
|
279
337
|
if (message === null || typeof message !== 'object' || !Array.isArray(message.content)) return '';
|
|
@@ -459,9 +517,32 @@ export function apply(ctx, config) {
|
|
|
459
517
|
}
|
|
460
518
|
}
|
|
461
519
|
|
|
520
|
+
/** 应用/更新极简提示词层(persona 阴影 + 全局引导段屏蔽)。 */
|
|
521
|
+
function applyMinimalPrompt(a) {
|
|
522
|
+
for (const disposer of a.promptDisposers) {
|
|
523
|
+
try { disposer(); } catch {}
|
|
524
|
+
}
|
|
525
|
+
a.promptDisposers = [];
|
|
526
|
+
if (!cfg.enabled || !cfg.minimalPrompt.enabled) return;
|
|
527
|
+
const sp = a.agent.ctx.systemPrompt;
|
|
528
|
+
try {
|
|
529
|
+
if (cfg.minimalPrompt.suppressSections) {
|
|
530
|
+
for (const [name, order] of SECTION_SHADOWS) {
|
|
531
|
+
a.promptDisposers.push(sp.section({ name, order, text: '' }));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const persona = cfg.minimalPrompt.persona.trim();
|
|
535
|
+
if (persona.length > 0) {
|
|
536
|
+
a.promptDisposers.push(sp.section({ name: PERSONA_SECTION_NAME, order: PERSONA_SECTION_ORDER, text: persona }));
|
|
537
|
+
}
|
|
538
|
+
info(`agent ${a.agent.id}: minimal prompt layer active`);
|
|
539
|
+
} catch (error) {
|
|
540
|
+
warn(`minimalPrompt failed for agent ${a.agent.id}: ${error && error.message || error}`);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
462
544
|
/** 应用/更新工具族限制(lean 模式)。总开关关闭、族被禁用、已升级、
|
|
463
|
-
* 已从配置删除的族一律放行。 */
|
|
464
|
-
function applyFamilies(a) {
|
|
545
|
+
* 已从配置删除的族一律放行。 */ function applyFamilies(a) {
|
|
465
546
|
if (!cfg.enabled || !cfg.leanByDefault) {
|
|
466
547
|
for (const [id, disposer] of a.familyDisposers) {
|
|
467
548
|
try { disposer(); } catch {}
|
|
@@ -521,6 +602,7 @@ export function apply(ctx, config) {
|
|
|
521
602
|
const a = {
|
|
522
603
|
agent,
|
|
523
604
|
suppressDisposer: null,
|
|
605
|
+
promptDisposers: [],
|
|
524
606
|
familyDisposers: new Map(),
|
|
525
607
|
bootstrapDisposer: null,
|
|
526
608
|
bootstrapKey: null,
|
|
@@ -540,6 +622,7 @@ export function apply(ctx, config) {
|
|
|
540
622
|
}
|
|
541
623
|
agents.set(agent.id, a);
|
|
542
624
|
applySuppression(a);
|
|
625
|
+
applyMinimalPrompt(a);
|
|
543
626
|
applyFamilies(a);
|
|
544
627
|
syncBootstrap(a);
|
|
545
628
|
info(`agent ${agent.id}: adaptive-perf active (preset ${String(agentPresets.composedPreset(agent.ctx))})`);
|
|
@@ -554,6 +637,10 @@ export function apply(ctx, config) {
|
|
|
554
637
|
if (a.suppressDisposer !== null) {
|
|
555
638
|
try { a.suppressDisposer(); } catch {}
|
|
556
639
|
}
|
|
640
|
+
for (const disposer of a.promptDisposers) {
|
|
641
|
+
try { disposer(); } catch {}
|
|
642
|
+
}
|
|
643
|
+
a.promptDisposers = [];
|
|
557
644
|
if (a.bootstrapDisposer !== null) {
|
|
558
645
|
try { a.bootstrapDisposer(); } catch {}
|
|
559
646
|
}
|
|
@@ -753,7 +840,9 @@ export function apply(ctx, config) {
|
|
|
753
840
|
cfg = normalizeConfig({ ...patchConfig, ...merged });
|
|
754
841
|
info('config hot-updated; recomputing restrictions for live agents');
|
|
755
842
|
// 补挂此前创建的会话(例如插件从 disabled 切换为 enabled,或新增了
|
|
756
|
-
// 目标 preset):新符合条件的 agent
|
|
843
|
+
// 目标 preset):新符合条件的 agent 立即接管(handleAgent 已应用全部
|
|
844
|
+
// 层,下面的重算只针对此前已接管的 agent,避免同一 onUpdate 内重复)。
|
|
845
|
+
const existing = new Set(agents.keys());
|
|
757
846
|
if (agentsService !== void 0 && typeof agentsService.list === 'function') {
|
|
758
847
|
try {
|
|
759
848
|
for (const agent of agentsService.list()) handleAgent(agent);
|
|
@@ -761,8 +850,11 @@ export function apply(ctx, config) {
|
|
|
761
850
|
warn(`config-update agent sweep failed: ${error && error.message || error}`);
|
|
762
851
|
}
|
|
763
852
|
}
|
|
764
|
-
for (const
|
|
853
|
+
for (const agentId of existing) {
|
|
854
|
+
const a = agents.get(agentId);
|
|
855
|
+
if (a === void 0) continue;
|
|
765
856
|
applySuppression(a);
|
|
857
|
+
applyMinimalPrompt(a);
|
|
766
858
|
applyFamilies(a);
|
|
767
859
|
syncBootstrap(a);
|
|
768
860
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaoset/adaptive-perf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "DSH host plugin: bring standard / PTC presets to minimal-mode-level performance via runtime-context suppression and adaptive tool-catalog trimming with demand-driven escalation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|