dsh-nextsteps 1.3.1 → 1.3.3
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/index.js +44 -14
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -124,14 +124,13 @@ const PARAMETER_SCHEMA = {
|
|
|
124
124
|
required: ['followups']
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
-
function toolDescription(
|
|
128
|
-
const language = LANGUAGE_NAMES[settings.lang] ?? LANGUAGE_NAMES.auto;
|
|
127
|
+
function toolDescription() {
|
|
129
128
|
return [
|
|
130
129
|
'MANDATORY in every turn: once all real work and other tool calls are done, call this tool BEFORE writing your final answer — the answer must come after this tool returns, so the turn ends cleanly right after it. Never write your final answer before calling it.',
|
|
131
|
-
|
|
130
|
+
'Suggest exactly the number of followup prompts stated in the nextsteps section of the system prompt.',
|
|
132
131
|
'Good suggestions include alternatives to the latest implementation, related features, cleanup opportunities, tests to add, or verification steps you could run yourself; if plan steps remain, one suggestion may be continuing with the next step.',
|
|
133
132
|
`Each prompt must be short (usually one sentence), goal-oriented — name the outcome, not the steps — stand alone without conversation context, and be phrased in the user's first-person voice.`,
|
|
134
|
-
|
|
133
|
+
'Write every prompt and label in the language the nextsteps section of the system prompt states.',
|
|
135
134
|
'Never suggest actions the user would carry out themselves outside this session (e.g. "commit these changes"); judge by the tools you actually have.',
|
|
136
135
|
'This never waits for an answer: its result only confirms the suggestions were recorded.',
|
|
137
136
|
'Example input:',
|
|
@@ -139,12 +138,25 @@ function toolDescription(settings) {
|
|
|
139
138
|
].join('\n');
|
|
140
139
|
}
|
|
141
140
|
|
|
141
|
+
function nextstepsSectionText() {
|
|
142
|
+
const settings = settingsLoad();
|
|
143
|
+
const language = LANGUAGE_NAMES[settings.lang] ?? LANGUAGE_NAMES.auto;
|
|
144
|
+
const languageRule = settings.lang === 'auto'
|
|
145
|
+
? `Write every prompt and label in the same language the conversation has been using.`
|
|
146
|
+
: `LANGUAGE OVERRIDE, applies to the suggest_followups tool only: write every prompt and label in ${language} — even if the conversation or the session history is in another language. Never copy the conversation's language here.`;
|
|
147
|
+
return [
|
|
148
|
+
'nextsteps (the followup suggestion cards):',
|
|
149
|
+
`- Suggest exactly ${settings.maxFollowups} followup prompts when you call suggest_followups.`,
|
|
150
|
+
`- ${languageRule}`
|
|
151
|
+
].join('\n');
|
|
152
|
+
}
|
|
153
|
+
|
|
142
154
|
const PLUGIN_REV = 'sf-2';
|
|
143
155
|
|
|
144
|
-
function toolSpec(
|
|
156
|
+
function toolSpec() {
|
|
145
157
|
return {
|
|
146
158
|
name: TOOL_NAME,
|
|
147
|
-
description: toolDescription(
|
|
159
|
+
description: toolDescription(),
|
|
148
160
|
parameters: PARAMETER_SCHEMA,
|
|
149
161
|
output: {
|
|
150
162
|
schema: { type: 'string' },
|
|
@@ -205,11 +217,14 @@ function turnTranscript(events, afterSeq) {
|
|
|
205
217
|
|
|
206
218
|
function generateSystem(settings) {
|
|
207
219
|
const language = LANGUAGE_NAMES[settings.lang] ?? LANGUAGE_NAMES.auto;
|
|
220
|
+
const languageRule = settings.lang === 'auto'
|
|
221
|
+
? 'Write every prompt and label in the same language the conversation has been using.'
|
|
222
|
+
: `LANGUAGE OVERRIDE, applies to this answer only: write every prompt and label in ${language} — even if the transcript is in another language. Never copy the transcript's language here.`;
|
|
208
223
|
return [
|
|
209
224
|
'You suggest followup prompts the user of a coding-agent chat may want next. You answer with JSON only — no prose, no code fence.',
|
|
210
225
|
`Output shape: {"followups":[{"prompt":"...","label":"..."}]} with exactly ${settings.maxFollowups} items.`,
|
|
211
226
|
'Each prompt is one short sentence in the user\'s first-person voice, goal-oriented, standing alone without the transcript; each label is 2-5 words.',
|
|
212
|
-
|
|
227
|
+
languageRule,
|
|
213
228
|
'Good suggestions: alternatives to the latest change, related features, cleanup, tests, verification steps. If the transcript shows remaining plan steps, one suggestion may continue the next step.'
|
|
214
229
|
].join('\n');
|
|
215
230
|
}
|
|
@@ -302,20 +317,35 @@ async function apply(ctx) {
|
|
|
302
317
|
let settings = settingsLoad();
|
|
303
318
|
const json = (value, status = 200) => new Response(JSON.stringify(value), { status, headers: { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' } });
|
|
304
319
|
const isExternal = (next) => typeof next.model === 'string' && next.model !== '';
|
|
305
|
-
try {
|
|
306
|
-
if (!isExternal(settings)) ctx.tools.register(toolSpec(settings));
|
|
307
|
-
} catch (error) {
|
|
308
|
-
console.error('dsh-nextsteps: tool registration failed:', error);
|
|
309
|
-
}
|
|
310
320
|
const reapplyTool = (next) => {
|
|
311
321
|
settings = next;
|
|
312
322
|
try {
|
|
313
|
-
|
|
314
|
-
|
|
323
|
+
try { ctx.tools.unregister(TOOL_NAME); } catch { /* not registered yet */ }
|
|
324
|
+
if (!isExternal(next)) ctx.tools.register(toolSpec());
|
|
315
325
|
} catch (error) {
|
|
316
326
|
console.error('dsh-nextsteps: tool re-registration failed:', error);
|
|
317
327
|
}
|
|
318
328
|
};
|
|
329
|
+
try {
|
|
330
|
+
if (!isExternal(settings)) ctx.tools.register(toolSpec());
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error('dsh-nextsteps: tool registration failed:', error);
|
|
333
|
+
}
|
|
334
|
+
if (typeof ctx.inject === 'function') {
|
|
335
|
+
ctx.inject(['tools', 'systemPrompt'], (sub) => {
|
|
336
|
+
try {
|
|
337
|
+
try { sub.tools.unregister(TOOL_NAME); } catch { /* not registered yet */ }
|
|
338
|
+
if (!isExternal(settings)) sub.tools.register(toolSpec());
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error('dsh-nextsteps: tool registration via inject failed:', error);
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
sub.systemPrompt.section({ name: 'dsh-nextsteps', order: 640, interpolate: false, text: () => nextstepsSectionText() });
|
|
344
|
+
} catch (error) {
|
|
345
|
+
console.error('dsh-nextsteps: system prompt section rejected:', error);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
319
349
|
ctx.connection?.fetch?.register({
|
|
320
350
|
path: '/api/dsh-nextsteps.settings',
|
|
321
351
|
methods: ['GET', 'POST'],
|