dsh-plugin-prompt-tool 0.5.0 → 0.6.1
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 +18 -12
- package/engine/anchor-match.mjs +117 -0
- package/engine/compositions/library/context-gate.yml +2 -2
- package/engine/compositions/library/delegation.yml +2 -2
- package/engine/compositions/library/str-replace-editor.yml +1 -1
- package/engine/compositions/library/tool-bootstrap.yml +2 -2
- package/engine/compositions/library/tool-filter.yml +3 -3
- package/engine/compositions/source/local/context-gate.yml +2 -2
- package/engine/compositions/source/local/tool-bootstrap.yml +3 -3
- package/engine/executor.mjs +9 -2
- package/engine/interpolate.mjs +116 -0
- package/engine/layers.mjs +26 -22
- package/engine/schema.mjs +18 -0
- package/engine/session-vars.mjs +52 -0
- package/engine/shared.mjs +0 -19
- package/engine/strategies.mjs +28 -38
- package/lib/client.js +471 -162
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +35 -9
- package/lib/index.mjs +376 -92
- package/lib/preset-core.d.mts +2 -2
- package/lib/preset-core.mjs +3 -6
- package/lib/{prompt-configs-BcP6miu9.d.mts → prompt-configs-B4vH09wx.d.mts} +1 -3
- package/lib/{prompt-configs-k7wuZs0C.mjs → prompt-configs-ThS4iXPg.mjs} +85 -33
- package/package.json +105 -104
- package/preset/anchored/preset.yml +40 -42
- package/preset/creative/preset.yml +33 -30
- package/preset/creative/skills/cordis-plugin-development/SKILL.md +420 -0
- package/preset/creative/skills/editing-cordis-compositions/SKILL.md +165 -0
- package/preset/liangshen/preset.yml +24 -18
- package/preset/minimal/preset.yml +27 -24
- package/preset/ptc/preset.yml +23 -17
- package/preset/standard/preset.yml +23 -17
- package/templates/20-system-section.yml +5 -0
- package/templates/70-subagent-maintenance.yml +38 -0
- package/engine/compositions/library/router-first-turn.yml +0 -9
- package/engine/compositions/source/local/router-first-turn.yml +0 -5
- package/engine/router-first-turn.mjs +0 -85
package/engine/strategies.mjs
CHANGED
|
@@ -6,15 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extractText } from './shared.mjs'
|
|
9
|
+
import { MATCH_LOGIC, createAnchorMatcher } from './anchor-match.mjs'
|
|
9
10
|
import { createInstructionHintResolver, createPlaceholderResolver } from './fillers.mjs'
|
|
10
11
|
|
|
11
12
|
const name = 'prompt-config-engine'
|
|
12
13
|
|
|
13
|
-
/** 锚定词正则转义。 */
|
|
14
|
-
function escapeRegExp(text) {
|
|
15
|
-
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
/**
|
|
19
15
|
* first-turn-anchor:首条真实用户消息后的一次性任务锚点。
|
|
20
16
|
* 正则与锚句文本全部来自 config.params(由 preset.yml 单一配置源下发)。
|
|
@@ -74,16 +70,6 @@ function createGuideAutoResolver(config) {
|
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
/** 判断 reasoning 开头是否命中自定义锚定词:ASCII 词按词边界匹配,其他按前缀匹配。 */
|
|
78
|
-
function matchesAnchorWord(raw, firstTurnWord) {
|
|
79
|
-
const text = String(raw ?? '').trim()
|
|
80
|
-
if (text.length === 0 || firstTurnWord.length === 0) return false
|
|
81
|
-
if (/^[\x20-\x7E]+$/.test(firstTurnWord)) {
|
|
82
|
-
return new RegExp(`^${escapeRegExp(firstTurnWord.toLowerCase())}\\b`, 'i').test(text)
|
|
83
|
-
}
|
|
84
|
-
return text.startsWith(firstTurnWord)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
73
|
/**
|
|
88
74
|
* custom-fallback:自定义锚定词命中后注入一次,未命中最多两轮兜底。
|
|
89
75
|
* 参数全部来自 config.params(由 preset.yml 单一配置源下发)。
|
|
@@ -95,6 +81,8 @@ function createCustomFallbackResolver(config) {
|
|
|
95
81
|
const firstTurnWord = typeof config.params?.firstTurnWord === 'string' && config.params.firstTurnWord.length > 0
|
|
96
82
|
? config.params.firstTurnWord
|
|
97
83
|
: 'we'
|
|
84
|
+
// 锚定匹配经 anchor-match 引擎(prefix 模式:首轮 reasoning 开头命中锚定词)。
|
|
85
|
+
const anchor = createAnchorMatcher({ keys: [firstTurnWord], mode: 'prefix' })
|
|
98
86
|
|
|
99
87
|
const anchorScanned = new Map()
|
|
100
88
|
|
|
@@ -106,7 +94,7 @@ function createCustomFallbackResolver(config) {
|
|
|
106
94
|
if (first === undefined) return false
|
|
107
95
|
const content = first.data?.message?.content ?? []
|
|
108
96
|
const reasoning = content.find((block) => block.type === 'reasoning')
|
|
109
|
-
const confirmed = reasoning !== undefined &&
|
|
97
|
+
const confirmed = reasoning !== undefined && anchor.scan(String(reasoning.text ?? '')).active
|
|
110
98
|
anchorScanned.set(session.id, confirmed)
|
|
111
99
|
return confirmed
|
|
112
100
|
}
|
|
@@ -135,41 +123,43 @@ function createCustomFallbackResolver(config) {
|
|
|
135
123
|
|
|
136
124
|
/**
|
|
137
125
|
* world-book:世界书条目(角色卡 lorebook)。constant=true 恒注入(不扫 keys);
|
|
138
|
-
* selective 条目扫描当前消息批文本,keys/secondaryKeys
|
|
139
|
-
*
|
|
126
|
+
* selective 条目扫描当前消息批文本,keys/secondaryKeys 按 selectiveLogic 组合
|
|
127
|
+
* (any=任一命中 / all=副键全中 / not=副键全不中)。匹配经 anchor-match 引擎。
|
|
140
128
|
*/
|
|
141
129
|
function createWorldBookResolver(config) {
|
|
142
130
|
const constant = config.params?.constant === true
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
?
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
131
|
+
// selectiveLogic:ST world_info_logic 0=AND_ANY 1=NOT_ALL 2=NOT_ANY 3=AND_ALL。
|
|
132
|
+
const rawLogic = config.params?.selectiveLogic
|
|
133
|
+
const logic = rawLogic === 3
|
|
134
|
+
? MATCH_LOGIC.ALL
|
|
135
|
+
: (rawLogic === 1
|
|
136
|
+
? MATCH_LOGIC.NOT
|
|
137
|
+
: (rawLogic === 2 ? MATCH_LOGIC.NOT_ANY : MATCH_LOGIC.ANY))
|
|
138
|
+
const matcher = createAnchorMatcher({
|
|
139
|
+
keys: Array.isArray(config.params?.keys) ? config.params.keys : [],
|
|
140
|
+
secondaryKeys: Array.isArray(config.params?.secondaryKeys) ? config.params.secondaryKeys : [],
|
|
141
|
+
caseSensitive: config.params?.caseSensitive === true,
|
|
142
|
+
wholeWords: config.params?.wholeWords === true,
|
|
143
|
+
useRegex: config.params?.useRegex === true,
|
|
144
|
+
logic,
|
|
145
|
+
})
|
|
146
|
+
// ST 语义:constant 或无任何键的条目恒注入(always active)。
|
|
147
|
+
const hasAnyKey = (Array.isArray(config.params?.keys) ? config.params.keys : [])
|
|
148
|
+
.some((key) => String(key).trim().length > 0)
|
|
149
|
+
|| (Array.isArray(config.params?.secondaryKeys) ? config.params.secondaryKeys : [])
|
|
150
|
+
.some((key) => String(key).trim().length > 0)
|
|
160
151
|
const promptText = config.texts.length > 0
|
|
161
152
|
? config.texts.join('\n\n')
|
|
162
153
|
: (typeof config.params?.text === 'string' && config.params.text.length > 0 ? config.params.text : undefined)
|
|
163
154
|
return ({ messages }) => {
|
|
164
155
|
if (promptText === undefined) return null
|
|
165
|
-
if (constant ||
|
|
156
|
+
if (constant || !hasAnyKey) return { text: promptText }
|
|
166
157
|
const haystack = (Array.isArray(messages) ? messages : [])
|
|
167
158
|
.map((message) => extractText(message))
|
|
168
159
|
.filter((text) => text.length > 0)
|
|
169
160
|
.join('\n')
|
|
170
161
|
if (haystack.length === 0) return null
|
|
171
|
-
|
|
172
|
-
return needle.test(haystack) ? { text: promptText } : null
|
|
162
|
+
return matcher.scan(haystack).active ? { text: promptText } : null
|
|
173
163
|
}
|
|
174
164
|
}
|
|
175
165
|
|