dsh-nextsteps 1.3.0 → 1.3.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/client.js +15 -8
- package/index.js +8 -2
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -351,7 +351,7 @@ window.__ModuleLoader__.load({
|
|
|
351
351
|
if (modelCatalogCache === undefined || force === true) {
|
|
352
352
|
try {
|
|
353
353
|
const response = await fetch(MODELS_ROUTE, { cache: 'no-store' });
|
|
354
|
-
const data = await response
|
|
354
|
+
const data = await responseJson(response);
|
|
355
355
|
if (data !== null && typeof data === 'object' && data.ok === true) modelCatalogCache = data;
|
|
356
356
|
} catch (error) {
|
|
357
357
|
console.warn('dsh-nextsteps: model catalog unavailable:', error);
|
|
@@ -363,17 +363,24 @@ window.__ModuleLoader__.load({
|
|
|
363
363
|
const SETTINGS_ROUTE = '/api/dsh-nextsteps.settings';
|
|
364
364
|
const UPDATE_ROUTE = '/api/dsh-nextsteps.update';
|
|
365
365
|
const DICTIONARIES = {
|
|
366
|
-
en: {"header":"Suggested followups","showEarlier":"Show earlier suggestions","hideEarlier":"Hide earlier suggestions","srFollowupSent":"Followup sent","sendFailed":"Could not send: ","intro":"Suggested next-step prompts under every finished agent turn — one click sends the followup.","setLanguage":"Language","setLanguageTip":"Followups are generated in this language. Auto follows the conversation.","optAuto":"Auto (follow the conversation)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文",setModel:"Model","setModelTip":"The model that generates the suggestions. Auto keeps them inside the main turn.","optModelAuto":"Auto (same model as the chat)",
|
|
367
|
-
'pt-BR': {"header":"Sugestões de acompanhamento","showEarlier":"Mostrar sugestões anteriores","hideEarlier":"Ocultar sugestões anteriores","srFollowupSent":"Follow-up enviado","sendFailed":"Não consegui enviar: ","intro":"Sugestões de próximos passos sob cada turno concluído do agente — um clique envia o followup.","setLanguage":"Idioma","setLanguageTip":"Os followups são gerados neste idioma. Automático segue a conversa.","optAuto":"Automático (segue a conversa)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文","setMax":"Followups por turno","setMaxTip":"Quantas sugestões o modelo deve produzir (1-6).","setHeader":"Mostrar cabeçalho","setHeaderTip":"O rótulo pequeno “Sugestões de acompanhamento” acima dos cartões.","updates":"Atualizações","current":"Versão","checking":"Verificando…","upToDate":"em dia","available":"{v} disponível","manualCopy":"Cópia de desenvolvimento ou renomeada — atualize manualmente.","installing":"Instalando {v}…","restartMsg":"Versão {v} instalada. Reinicie o dsh para usá-la.","noReleases":"Nenhum release publicado ainda","checkFailed":"Falha ao verificar atualizações ({e})","updateNow":"Atualizar agora","check":"Verificar atualizações","openRelease":"Abrir página do release","releaseNotes":"Notas do release","repo":"Repositório no GitHub","issues":"Reportar um problema"},
|
|
368
|
-
'zh-CN': {"header":"建议的后续操作","showEarlier":"显示较早的建议","hideEarlier":"隐藏较早的建议","srFollowupSent":"后续操作已发送","sendFailed":"发送失败:","intro":"在每个智能体回合完成后的下方推荐下一步提示——单击即可发送。","setLanguage":"语言","setLanguageTip":"后续操作提示将以此语言生成。“自动”会跟随对话语言。","optAuto":"自动(跟随对话)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文","setMax":"每回合提示数","setMaxTip":"模型应生成的建议提示数量(1-6)。","setHeader":"显示标题","setHeaderTip":"卡片上方的小标题“建议的后续操作”。","updates":"更新","current":"版本","checking":"检查中…","upToDate":"已是最新","available":"{v} 可用","manualCopy":"开发或重命名的副本——请手动更新。","installing":"正在安装 {v}…","restartMsg":"版本 {v} 已安装。请重启 dsh 以使用。","noReleases":"尚未发布任何版本","checkFailed":"检查更新失败({e})","updateNow":"立即更新","check":"检查更新","openRelease":"打开发布页","releaseNotes":"发布说明","repo":"GitHub 仓库","issues":"反馈问题"}
|
|
366
|
+
en: {"header":"Suggested followups","showEarlier":"Show earlier suggestions","hideEarlier":"Hide earlier suggestions","srFollowupSent":"Followup sent","sendFailed":"Could not send: ","intro":"Suggested next-step prompts under every finished agent turn — one click sends the followup.","setLanguage":"Language","setLanguageTip":"Followups are generated in this language. Auto follows the conversation.","optAuto":"Auto (follow the conversation)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文","setModel":"Model","setModelTip":"The model that generates the suggestions. Auto keeps them inside the main turn.","optModelAuto":"Auto (same model as the chat)","setMax":"Followups per turn","setMaxTip":"How many suggested prompts the model should produce (1-6).","setHeader":"Show header","setHeaderTip":"The small “Suggested followups” label above the cards.","updates":"Updates","current":"Version","checking":"Checking…","upToDate":"up to date","available":"{v} is available","manualCopy":"Development or renamed copy — update it manually.","installing":"Installing {v}…","restartMsg":"Version {v} was installed. Restart the dsh to use it.","noReleases":"No releases published yet","checkFailed":"Update check failed ({e})","updateNow":"Update now","check":"Check for updates","openRelease":"Open release page","releaseNotes":"Release notes","repo":"GitHub repository","issues":"Report an issue"},
|
|
367
|
+
'pt-BR': {"header":"Sugestões de acompanhamento","showEarlier":"Mostrar sugestões anteriores","hideEarlier":"Ocultar sugestões anteriores","srFollowupSent":"Follow-up enviado","sendFailed":"Não consegui enviar: ","intro":"Sugestões de próximos passos sob cada turno concluído do agente — um clique envia o followup.","setLanguage":"Idioma","setLanguageTip":"Os followups são gerados neste idioma. Automático segue a conversa.","optAuto":"Automático (segue a conversa)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文","setModel":"Modelo","setModelTip":"O modelo que gera as sugestões. Automático as mantém no turno principal.","optModelAuto":"Automático (mesmo modelo da conversa)","setMax":"Followups por turno","setMaxTip":"Quantas sugestões o modelo deve produzir (1-6).","setHeader":"Mostrar cabeçalho","setHeaderTip":"O rótulo pequeno “Sugestões de acompanhamento” acima dos cartões.","updates":"Atualizações","current":"Versão","checking":"Verificando…","upToDate":"em dia","available":"{v} disponível","manualCopy":"Cópia de desenvolvimento ou renomeada — atualize manualmente.","installing":"Instalando {v}…","restartMsg":"Versão {v} instalada. Reinicie o dsh para usá-la.","noReleases":"Nenhum release publicado ainda","checkFailed":"Falha ao verificar atualizações ({e})","updateNow":"Atualizar agora","check":"Verificar atualizações","openRelease":"Abrir página do release","releaseNotes":"Notas do release","repo":"Repositório no GitHub","issues":"Reportar um problema"},
|
|
368
|
+
'zh-CN': {"header":"建议的后续操作","showEarlier":"显示较早的建议","hideEarlier":"隐藏较早的建议","srFollowupSent":"后续操作已发送","sendFailed":"发送失败:","intro":"在每个智能体回合完成后的下方推荐下一步提示——单击即可发送。","setLanguage":"语言","setLanguageTip":"后续操作提示将以此语言生成。“自动”会跟随对话语言。","optAuto":"自动(跟随对话)","optEn":"English","optPt":"Português (Brasil)","optZh":"简体中文","setModel":"模型","setModelTip":"生成建议的模型。自动会跟随对话所用的模型。","optModelAuto":"自动(与对话相同的模型)","setMax":"每回合提示数","setMaxTip":"模型应生成的建议提示数量(1-6)。","setHeader":"显示标题","setHeaderTip":"卡片上方的小标题“建议的后续操作”。","updates":"更新","current":"版本","checking":"检查中…","upToDate":"已是最新","available":"{v} 可用","manualCopy":"开发或重命名的副本——请手动更新。","installing":"正在安装 {v}…","restartMsg":"版本 {v} 已安装。请重启 dsh 以使用。","noReleases":"尚未发布任何版本","checkFailed":"检查更新失败({e})","updateNow":"立即更新","check":"检查更新","openRelease":"打开发布页","releaseNotes":"发布说明","repo":"GitHub 仓库","issues":"反馈问题"}
|
|
369
369
|
};
|
|
370
370
|
let pluginSettings = { lang: 'auto', maxFollowups: 3, showHeader: true };
|
|
371
371
|
let pluginVersion;
|
|
372
372
|
|
|
373
|
+
async function responseJson(response) {
|
|
374
|
+
try {
|
|
375
|
+
return await response.json();
|
|
376
|
+
} catch {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
373
380
|
async function refreshPluginSettings() {
|
|
374
381
|
try {
|
|
375
382
|
const response = await fetch(SETTINGS_ROUTE, { cache: 'no-store' });
|
|
376
|
-
const data = await response
|
|
383
|
+
const data = await responseJson(response);
|
|
377
384
|
if (data !== null && typeof data === 'object' && data.ok === true && data.settings !== null && typeof data.settings === 'object') {
|
|
378
385
|
pluginSettings = data.settings;
|
|
379
386
|
if (typeof data.version === 'string') pluginVersion = data.version;
|
|
@@ -491,7 +498,7 @@ window.__ModuleLoader__.load({
|
|
|
491
498
|
(async () => {
|
|
492
499
|
try {
|
|
493
500
|
const response = await fetch(GENERATE_ROUTE, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ sessionId, afterSeq }) });
|
|
494
|
-
const data = await response
|
|
501
|
+
const data = await responseJson(response);
|
|
495
502
|
if (!alive || !response.ok || data === null || typeof data !== 'object' || !Array.isArray(data.followups) || data.followups.length === 0) return;
|
|
496
503
|
rememberCapture(sessionId, 'generated-' + turn, turn, validateFollowups(data.followups));
|
|
497
504
|
} catch (error) {
|
|
@@ -535,7 +542,7 @@ window.__ModuleLoader__.load({
|
|
|
535
542
|
setSettings(merged);
|
|
536
543
|
try {
|
|
537
544
|
const response = await fetch(SETTINGS_ROUTE, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(patch) });
|
|
538
|
-
const data = await response
|
|
545
|
+
const data = await responseJson(response);
|
|
539
546
|
if (data !== null && typeof data === 'object' && data.ok === true && data.settings !== null && typeof data.settings === 'object') { pluginSettings = data.settings; setSettings(data.settings); }
|
|
540
547
|
} catch (error) {
|
|
541
548
|
console.warn('dsh-nextsteps: settings save failed:', error);
|
|
@@ -545,7 +552,7 @@ window.__ModuleLoader__.load({
|
|
|
545
552
|
setUpdate((previous) => ({ ...previous, status: 'checking' }));
|
|
546
553
|
try {
|
|
547
554
|
const response = await fetch(UPDATE_ROUTE, { cache: 'no-store' });
|
|
548
|
-
const info = await response
|
|
555
|
+
const info = await responseJson(response);
|
|
549
556
|
if (!response.ok || info === null || typeof info !== 'object' || info.error !== undefined) throw new Error(info?.error ?? 'HTTP ' + response.status);
|
|
550
557
|
setUpdate({ status: info.newer === true ? (info.managed ? 'available' : 'manual') : 'current', info });
|
|
551
558
|
} catch (error) {
|
package/index.js
CHANGED
|
@@ -126,12 +126,15 @@ const PARAMETER_SCHEMA = {
|
|
|
126
126
|
|
|
127
127
|
function toolDescription(settings) {
|
|
128
128
|
const language = LANGUAGE_NAMES[settings.lang] ?? LANGUAGE_NAMES.auto;
|
|
129
|
+
const languageRule = settings.lang === 'auto'
|
|
130
|
+
? 'Write every prompt and label in the same language the conversation has been using.'
|
|
131
|
+
: `LANGUAGE OVERRIDE, applies to this 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.`;
|
|
129
132
|
return [
|
|
130
133
|
'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
134
|
`Suggest exactly ${settings.maxFollowups} followup prompts the user is likely to want next.`,
|
|
132
135
|
'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
136
|
`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
|
-
|
|
137
|
+
languageRule,
|
|
135
138
|
'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
139
|
'This never waits for an answer: its result only confirms the suggestions were recorded.',
|
|
137
140
|
'Example input:',
|
|
@@ -205,11 +208,14 @@ function turnTranscript(events, afterSeq) {
|
|
|
205
208
|
|
|
206
209
|
function generateSystem(settings) {
|
|
207
210
|
const language = LANGUAGE_NAMES[settings.lang] ?? LANGUAGE_NAMES.auto;
|
|
211
|
+
const languageRule = settings.lang === 'auto'
|
|
212
|
+
? 'Write every prompt and label in the same language the conversation has been using.'
|
|
213
|
+
: `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
214
|
return [
|
|
209
215
|
'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
216
|
`Output shape: {"followups":[{"prompt":"...","label":"..."}]} with exactly ${settings.maxFollowups} items.`,
|
|
211
217
|
'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
|
-
|
|
218
|
+
languageRule,
|
|
213
219
|
'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
220
|
].join('\n');
|
|
215
221
|
}
|