blun-king-cli 9.1.105 → 9.1.107
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/LIESMICH.txt +3 -1
- package/README.md +3 -1
- package/bin/profile-tool-exclusion-policy.cjs +37 -0
- package/blun.mjs +123 -20
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
|
@@ -9,7 +9,7 @@ Installation
|
|
|
9
9
|
------------
|
|
10
10
|
Die geprüfte Version exakt global installieren:
|
|
11
11
|
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.106
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -107,6 +107,8 @@ Reguläre `Agent`-Teilaufgaben verwenden eine eigene `ContextMemory` und eine ei
|
|
|
107
107
|
|
|
108
108
|
Version 9.1.105 ergänzt `TaskUpdate` für laufende Hintergrundagenten. King übergibt zusätzliche Anweisungen am nächsten sicheren Modellschritt an denselben aktiven Agenten, ohne ihn zu stoppen oder einen weiteren Agenten zu starten. Unbekannte und bereits beendete Aufgaben, Shell-Aufgaben sowie Agenten, die keine Aktualisierung mehr annehmen, werden unverändert abgewiesen.
|
|
109
109
|
|
|
110
|
+
Version 9.1.106 erlaubt Agentenprofilen, Werkzeuge namentlich auszuschließen. King wendet diese Ausschlüsse erst an, nachdem dauerhaft geladene, dynamisch nachgeladene und MCP-Werkzeuge zusammengestellt wurden. Die Standardprofile `coder`, `explore` und `plan` können über Telegram weder antworten noch reagieren, Nachrichten bearbeiten oder Anhänge herunterladen; der Hauptagent bleibt unverändert. So senden delegierte Agenten keine Nachrichten am Hauptagenten vorbei, und ihre Modellanfragen enthalten weniger Werkzeugschemas. Nicht gefundene, namentlich angegebene Werkzeuge werden sichtbar gemeldet.
|
|
111
|
+
|
|
110
112
|
Verliert ein delegierter Einzelagent oder ein Mitglied eines Agentenschwarms die Provider-Verbindung, erhält es eine leere Provider-Antwort, bricht sein Stream wegen Leerlaufs ab oder meldet der Server HTTP 408/500/502/503/504, setzt BLUN King denselben Agenten anhand seines dauerhaften Verlaufs fort. Bei Einzelagenten sowie bei Schwarm-Unterbrechungen außerhalb von HTTP 429 wartet die erste Fortsetzung zwei Sekunden und die zweite fünf Sekunden; danach bleibt der ursprüngliche Fehler sichtbar. HTTP 429 behält im Schwarm seine getrennte, längere Überlastungsregel. Authentifizierungs-, Zahlungs- oder Kontingent-, Richtlinien-, Kontext-, Werkzeug- und Codefehler sowie manuelle Abbrüche lösen keine automatische Fortsetzung aus. Jeder Fortsetzungsversuch verwendet die bestehende Agenten-ID, damit bereits abgeschlossene Arbeit nicht wiederholt wird.
|
|
111
113
|
|
|
112
114
|
Rein lesende Sitzungsdiagnose
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Voraussetzung ist Node.js 24.15 oder neuer. Die geprüfte Version wird exakt
|
|
|
9
9
|
installiert:
|
|
10
10
|
|
|
11
11
|
```powershell
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.106
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -115,6 +115,8 @@ Version 9.1.104 lässt Shell-Befehle im Vordergrund auch bei sehr großen Ausgab
|
|
|
115
115
|
|
|
116
116
|
Version 9.1.105 ergänzt `TaskUpdate` für laufende Hintergrundagenten. King übergibt zusätzliche Anweisungen am nächsten sicheren Modellschritt an denselben aktiven Agenten, ohne ihn zu stoppen oder einen weiteren Agenten zu starten. Unbekannte und bereits beendete Aufgaben, Shell-Aufgaben sowie Agenten, die keine Aktualisierung mehr annehmen, werden unverändert abgewiesen.
|
|
117
117
|
|
|
118
|
+
Version 9.1.106 erlaubt Agentenprofilen, Werkzeuge namentlich auszuschließen. King wendet diese Ausschlüsse erst an, nachdem dauerhaft geladene, dynamisch nachgeladene und MCP-Werkzeuge zusammengestellt wurden. Die Standardprofile `coder`, `explore` und `plan` können über Telegram weder antworten noch reagieren, Nachrichten bearbeiten oder Anhänge herunterladen; der Hauptagent bleibt unverändert. So senden delegierte Agenten keine Nachrichten am Hauptagenten vorbei, und ihre Modellanfragen enthalten weniger Werkzeugschemas. Nicht gefundene, namentlich angegebene Werkzeuge werden sichtbar gemeldet.
|
|
119
|
+
|
|
118
120
|
Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
|
|
119
121
|
|
|
120
122
|
Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function normalizedExcludedToolNames(excludedNames) {
|
|
4
|
+
if (!Array.isArray(excludedNames)) return [];
|
|
5
|
+
return [...new Set(excludedNames
|
|
6
|
+
.map((name) => String(name || '').trim())
|
|
7
|
+
.filter(Boolean))];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function applyProfileToolExclusions(tools, excludedNames) {
|
|
11
|
+
const excluded = normalizedExcludedToolNames(excludedNames);
|
|
12
|
+
if (excluded.length === 0) return { tools, matched: [], unmatched: [] };
|
|
13
|
+
|
|
14
|
+
const excludedSet = new Set(excluded);
|
|
15
|
+
const matchedSet = new Set();
|
|
16
|
+
const filtered = [];
|
|
17
|
+
for (const tool of Array.isArray(tools) ? tools : []) {
|
|
18
|
+
const name = String(tool?.name || '');
|
|
19
|
+
if (excludedSet.has(name)) {
|
|
20
|
+
matchedSet.add(name);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
filtered.push(tool);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
tools: filtered,
|
|
28
|
+
matched: excluded.filter((name) => matchedSet.has(name)),
|
|
29
|
+
unmatched: excluded.filter((name) => !matchedSet.has(name)),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
applyProfileToolExclusions,
|
|
35
|
+
normalizedExcludedToolNames,
|
|
36
|
+
};
|
|
37
|
+
|
package/blun.mjs
CHANGED
|
@@ -21349,6 +21349,7 @@ var init_types$13 = __esmMin((() => {
|
|
|
21349
21349
|
systemPromptTemplate: string().optional(),
|
|
21350
21350
|
promptVars: record(string(), string()).optional(),
|
|
21351
21351
|
tools: array(string()).optional(),
|
|
21352
|
+
excludedTools: array(string()).optional(),
|
|
21352
21353
|
whenToUse: string().optional(),
|
|
21353
21354
|
subagents: record(string(), RawSubagentProfileSchema).optional()
|
|
21354
21355
|
});
|
|
@@ -28341,6 +28342,7 @@ function resolveMergedProfile(name, profileMap, cache, stack) {
|
|
|
28341
28342
|
...profile.promptVars
|
|
28342
28343
|
},
|
|
28343
28344
|
tools: profile.tools !== void 0 ? [...profile.tools] : [...parent?.tools ?? []],
|
|
28345
|
+
excludedTools: profile.excludedTools !== void 0 ? [...profile.excludedTools] : [...parent?.excludedTools ?? []],
|
|
28344
28346
|
whenToUse: profile.whenToUse ?? parent?.whenToUse,
|
|
28345
28347
|
subagents: cloneSubagents(profile.subagents)
|
|
28346
28348
|
};
|
|
@@ -28353,6 +28355,7 @@ function toResolvedProfile(merged) {
|
|
|
28353
28355
|
description: merged.description,
|
|
28354
28356
|
systemPrompt: createSystemPromptRenderer(merged),
|
|
28355
28357
|
tools: [...merged.tools],
|
|
28358
|
+
excludedTools: [...merged.excludedTools],
|
|
28356
28359
|
whenToUse: merged.whenToUse
|
|
28357
28360
|
};
|
|
28358
28361
|
}
|
|
@@ -28524,9 +28527,12 @@ var PROFILE_SOURCES, DEFAULT_INIT_PROMPT, DEFAULT_AGENT_PROFILES;
|
|
|
28524
28527
|
var init_default$1 = __esmMin((() => {
|
|
28525
28528
|
init_agent$3();
|
|
28526
28529
|
init_coder();
|
|
28530
|
+
coder_default = coder_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
28527
28531
|
init_explore();
|
|
28532
|
+
explore_default = explore_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
28528
28533
|
init_init();
|
|
28529
28534
|
init_plan$1();
|
|
28535
|
+
plan_default = plan_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
28530
28536
|
init_system();
|
|
28531
28537
|
init_load();
|
|
28532
28538
|
PROFILE_SOURCES = {
|
|
@@ -263333,7 +263339,7 @@ var init_builtin = __esmMin((() => {
|
|
|
263333
263339
|
var init_types$3 = __esmMin((() => {}));
|
|
263334
263340
|
//#endregion
|
|
263335
263341
|
//#region ../../packages/agent-core/src/agent/tool/index.ts
|
|
263336
|
-
var import_picomatch, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
263342
|
+
var import_picomatch, profileToolExclusionPolicy, applyProfileToolExclusions, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
263337
263343
|
var init_tool$1 = __esmMin((() => {
|
|
263338
263344
|
init_dist$4();
|
|
263339
263345
|
import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
@@ -263346,6 +263352,8 @@ var init_tool$1 = __esmMin((() => {
|
|
|
263346
263352
|
init_builtin();
|
|
263347
263353
|
init_compact_conversation_tool();
|
|
263348
263354
|
init_types$3();
|
|
263355
|
+
profileToolExclusionPolicy = createRequire(import.meta.url)("./bin/profile-tool-exclusion-policy.cjs");
|
|
263356
|
+
applyProfileToolExclusions = profileToolExclusionPolicy.applyProfileToolExclusions;
|
|
263349
263357
|
SHELL_FOREGROUND_TIMEOUT_S = 120;
|
|
263350
263358
|
ToolManager = class {
|
|
263351
263359
|
agent;
|
|
@@ -263361,6 +263369,8 @@ var init_tool$1 = __esmMin((() => {
|
|
|
263361
263369
|
store = {};
|
|
263362
263370
|
mcpToolStatusUnsubscribe;
|
|
263363
263371
|
allowedTools;
|
|
263372
|
+
excludedTools = [];
|
|
263373
|
+
reportedUnmatchedExclusions = /* @__PURE__ */ new Set();
|
|
263364
263374
|
/** Abort controllers for in-flight `!` shell commands, keyed by commandId so
|
|
263365
263375
|
* the TUI can cancel (Esc / Ctrl+C) a running command. */
|
|
263366
263376
|
shellCommandControllers = /* @__PURE__ */ new Map();
|
|
@@ -263681,6 +263691,14 @@ var init_tool$1 = __esmMin((() => {
|
|
|
263681
263691
|
setAllowedTools(tools) {
|
|
263682
263692
|
this.allowedTools = tools !== void 0 && tools.length > 0 ? [...tools] : void 0;
|
|
263683
263693
|
}
|
|
263694
|
+
setExcludedTools(names) {
|
|
263695
|
+
this.excludedTools = [...new Set((Array.isArray(names) ? names : []).map((name) => String(name || "").trim()).filter(Boolean))];
|
|
263696
|
+
this.reportedUnmatchedExclusions.clear();
|
|
263697
|
+
this.agent.records.logRecord({
|
|
263698
|
+
type: "tools.set_excluded_tools",
|
|
263699
|
+
names: this.excludedTools
|
|
263700
|
+
});
|
|
263701
|
+
}
|
|
263684
263702
|
copyLoopToolsFrom(source) {
|
|
263685
263703
|
this.loopToolsOverride = source.loopTools;
|
|
263686
263704
|
}
|
|
@@ -263821,12 +263839,22 @@ var init_tool$1 = __esmMin((() => {
|
|
|
263821
263839
|
}
|
|
263822
263840
|
}
|
|
263823
263841
|
get loopTools() {
|
|
263824
|
-
|
|
263825
|
-
|
|
263826
|
-
|
|
263827
|
-
|
|
263828
|
-
|
|
263829
|
-
|
|
263842
|
+
let selectedTools;
|
|
263843
|
+
if (this.loopToolsOverride !== void 0) selectedTools = this.loopToolsOverride;
|
|
263844
|
+
else {
|
|
263845
|
+
const mcpNames = [...this.mcpTools.keys()].filter((name) => this.isMcpToolEnabled(name));
|
|
263846
|
+
const hideGoalMutationTools = this.agent.goal.getGoal().goal === null;
|
|
263847
|
+
const allowedTools = this.allowedTools;
|
|
263848
|
+
const names = uniq([...this.enabledTools, ...mcpNames]).toSorted((a, b) => a.localeCompare(b)).filter((name) => !(hideGoalMutationTools && (name === "SetGoalBudget" || name === "UpdateGoal")));
|
|
263849
|
+
selectedTools = (allowedTools !== void 0 && allowedTools.length > 0 ? names.filter((name) => allowedTools.includes(name)) : names).map((name) => this.userTools.get(name) ?? this.mcpTools.get(name)?.tool ?? this.builtinTools.get(name)).filter((tool) => !!tool);
|
|
263850
|
+
}
|
|
263851
|
+
const exclusion = applyProfileToolExclusions(selectedTools, this.excludedTools);
|
|
263852
|
+
for (const name of exclusion.unmatched) if (!this.reportedUnmatchedExclusions.has(name)) {
|
|
263853
|
+
this.reportedUnmatchedExclusions.add(name);
|
|
263854
|
+
this.agent.log.warn("profile tool exclusion did not match a loaded tool", { name });
|
|
263855
|
+
this.agent.telemetry.track("profile_tool_exclusion_unmatched", { tool_name: name });
|
|
263856
|
+
}
|
|
263857
|
+
return exclusion.tools;
|
|
263830
263858
|
}
|
|
263831
263859
|
};
|
|
263832
263860
|
}));
|
|
@@ -264424,6 +264452,7 @@ var init_agent = __esmMin((() => {
|
|
|
264424
264452
|
this.setActiveProfile(profile, brandHome);
|
|
264425
264453
|
this.updateSystemPromptFromProfile(profile, context);
|
|
264426
264454
|
this.tools.setActiveTools(profile.tools);
|
|
264455
|
+
this.tools.setExcludedTools(profile.excludedTools);
|
|
264427
264456
|
}
|
|
264428
264457
|
setActiveProfile(profile, brandHome) {
|
|
264429
264458
|
this.activeProfile = profile;
|
|
@@ -412820,27 +412849,45 @@ const STREAMING_ARGS_PREVIEW_MAX_CHARS = 64 * 1024;
|
|
|
412820
412849
|
registerUiCatalogFragment({
|
|
412821
412850
|
en: {
|
|
412822
412851
|
"eventPayload.providerFiltered": "Provider filtered the response before visible output (finishReason={finishReason}{raw}).",
|
|
412823
|
-
"eventPayload.modelEmptyResponse": "King ended twice without producing content. Please send the message again."
|
|
412852
|
+
"eventPayload.modelEmptyResponse": "King ended twice without producing content. Please send the message again.",
|
|
412853
|
+
"eventPayload.providerBusy": "King is busy right now. Please try again shortly.",
|
|
412854
|
+
"eventPayload.providerUnavailable": "King could not complete this response. Please try again.",
|
|
412855
|
+
"eventPayload.providerAuthRequired": "Your King connection needs to be renewed. Please sign in again."
|
|
412824
412856
|
},
|
|
412825
412857
|
de: {
|
|
412826
412858
|
"eventPayload.providerFiltered": "Der Anbieter hat die Antwort vor der sichtbaren Ausgabe gefiltert (finishReason={finishReason}{raw}).",
|
|
412827
|
-
"eventPayload.modelEmptyResponse": "King hat die Antwort zweimal ohne Inhalt beendet. Bitte sende die Nachricht noch einmal."
|
|
412859
|
+
"eventPayload.modelEmptyResponse": "King hat die Antwort zweimal ohne Inhalt beendet. Bitte sende die Nachricht noch einmal.",
|
|
412860
|
+
"eventPayload.providerBusy": "King ist gerade ausgelastet. Bitte versuche es gleich noch einmal.",
|
|
412861
|
+
"eventPayload.providerUnavailable": "King konnte diese Antwort nicht abschließen. Bitte versuche es noch einmal.",
|
|
412862
|
+
"eventPayload.providerAuthRequired": "Die Verbindung zu King muss erneuert werden. Bitte melde dich erneut an."
|
|
412828
412863
|
},
|
|
412829
412864
|
es: {
|
|
412830
412865
|
"eventPayload.providerFiltered": "El proveedor filtró la respuesta antes de que se mostrara la salida (finishReason={finishReason}{raw}).",
|
|
412831
|
-
"eventPayload.modelEmptyResponse": "King terminó dos veces sin generar contenido. Envía el mensaje de nuevo."
|
|
412866
|
+
"eventPayload.modelEmptyResponse": "King terminó dos veces sin generar contenido. Envía el mensaje de nuevo.",
|
|
412867
|
+
"eventPayload.providerBusy": "King está ocupado en este momento. Vuelve a intentarlo en unos instantes.",
|
|
412868
|
+
"eventPayload.providerUnavailable": "King no ha podido completar esta respuesta. Vuelve a intentarlo.",
|
|
412869
|
+
"eventPayload.providerAuthRequired": "Es necesario renovar la conexión con King. Vuelve a iniciar sesión."
|
|
412832
412870
|
},
|
|
412833
412871
|
fr: {
|
|
412834
412872
|
"eventPayload.providerFiltered": "Le fournisseur a filtré la réponse avant l’affichage de la sortie (finishReason={finishReason}{raw}).",
|
|
412835
|
-
"eventPayload.modelEmptyResponse": "King a terminé deux fois sans produire de contenu. Envoyez à nouveau le message."
|
|
412873
|
+
"eventPayload.modelEmptyResponse": "King a terminé deux fois sans produire de contenu. Envoyez à nouveau le message.",
|
|
412874
|
+
"eventPayload.providerBusy": "King est occupé pour le moment. Réessayez dans quelques instants.",
|
|
412875
|
+
"eventPayload.providerUnavailable": "King n’a pas pu terminer cette réponse. Réessayez.",
|
|
412876
|
+
"eventPayload.providerAuthRequired": "La connexion à King doit être renouvelée. Reconnectez-vous."
|
|
412836
412877
|
},
|
|
412837
412878
|
sv: {
|
|
412838
412879
|
"eventPayload.providerFiltered": "Leverantören filtrerade svaret innan någon utdata visades (finishReason={finishReason}{raw}).",
|
|
412839
|
-
"eventPayload.modelEmptyResponse": "King avslutade två gånger utan att skapa något innehåll. Skicka meddelandet igen."
|
|
412880
|
+
"eventPayload.modelEmptyResponse": "King avslutade två gånger utan att skapa något innehåll. Skicka meddelandet igen.",
|
|
412881
|
+
"eventPayload.providerBusy": "King är upptagen just nu. Försök igen om en liten stund.",
|
|
412882
|
+
"eventPayload.providerUnavailable": "King kunde inte slutföra svaret. Försök igen.",
|
|
412883
|
+
"eventPayload.providerAuthRequired": "Anslutningen till King behöver förnyas. Logga in igen."
|
|
412840
412884
|
},
|
|
412841
412885
|
cs: {
|
|
412842
412886
|
"eventPayload.providerFiltered": "Poskytovatel filtroval odpověď před viditelným výstupem (finishReason={finishReason}{raw}).",
|
|
412843
|
-
"eventPayload.modelEmptyResponse": "King dvakrát ukončil odpověď bez obsahu. Odešlete zprávu znovu."
|
|
412887
|
+
"eventPayload.modelEmptyResponse": "King dvakrát ukončil odpověď bez obsahu. Odešlete zprávu znovu.",
|
|
412888
|
+
"eventPayload.providerBusy": "King je právě zaneprázdněný. Zkuste to za chvíli znovu.",
|
|
412889
|
+
"eventPayload.providerUnavailable": "King nemohl tuto odpověď dokončit. Zkuste to znovu.",
|
|
412890
|
+
"eventPayload.providerAuthRequired": "Připojení ke Kingovi je potřeba obnovit. Přihlaste se znovu."
|
|
412844
412891
|
}
|
|
412845
412892
|
});
|
|
412846
412893
|
//#endregion
|
|
@@ -412915,10 +412962,24 @@ function formatErrorMessage$2(error) {
|
|
|
412915
412962
|
}
|
|
412916
412963
|
function formatErrorPayload(error) {
|
|
412917
412964
|
if (error.code === "model.empty_response") return uiText("eventPayload.modelEmptyResponse");
|
|
412965
|
+
if (error.code === "provider.rate_limit") return uiText("eventPayload.providerBusy");
|
|
412966
|
+
if (error.code === "provider.api_error" || error.code === "provider.connection_error") return uiText("eventPayload.providerUnavailable");
|
|
412967
|
+
if (error.code === "provider.auth_error") return uiText("eventPayload.providerAuthRequired");
|
|
412918
412968
|
const filteredMessage = formatProviderFilteredMessage(error.details);
|
|
412919
|
-
if (filteredMessage !== void 0) return projectBlunIdentity(
|
|
412969
|
+
if (filteredMessage !== void 0) return projectBlunIdentity(filteredMessage);
|
|
412920
412970
|
return projectBlunIdentity(`[${error.code}] ${error.message}`);
|
|
412921
412971
|
}
|
|
412972
|
+
|
|
412973
|
+
const CUSTOMER_FACING_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
412974
|
+
"provider.rate_limit",
|
|
412975
|
+
"provider.api_error",
|
|
412976
|
+
"provider.connection_error",
|
|
412977
|
+
"provider.auth_error",
|
|
412978
|
+
"model.empty_response"
|
|
412979
|
+
]);
|
|
412980
|
+
function shouldShowErrorReportHint(event) {
|
|
412981
|
+
return !CUSTOMER_FACING_ERROR_CODES.has(event.code);
|
|
412982
|
+
}
|
|
412922
412983
|
function formatProviderFilteredMessage(details) {
|
|
412923
412984
|
const finishReason = stringDetail(details, "finishReason");
|
|
412924
412985
|
const rawFinishReason = stringDetail(details, "rawFinishReason");
|
|
@@ -497166,29 +497227,41 @@ var HelpPanelComponent = class extends Container {
|
|
|
497166
497227
|
focused = false;
|
|
497167
497228
|
opts;
|
|
497168
497229
|
scrollTop = 0;
|
|
497230
|
+
selectedCommandIndex = 0;
|
|
497231
|
+
showCommandDetail = false;
|
|
497169
497232
|
constructor(opts) {
|
|
497170
497233
|
super();
|
|
497171
497234
|
this.opts = opts;
|
|
497172
497235
|
}
|
|
497173
497236
|
handleInput(data) {
|
|
497174
497237
|
const printable = decodeKittyPrintable(data) ?? data;
|
|
497175
|
-
if (matchesKey(data, Key.escape) ||
|
|
497238
|
+
if (matchesKey(data, Key.escape) || printable === "q" || printable === "Q") {
|
|
497176
497239
|
this.opts.onClose();
|
|
497177
497240
|
return;
|
|
497178
497241
|
}
|
|
497242
|
+
const sortedCmds = [...this.opts.commands].toSorted(compareSlashCommandsForDisplay);
|
|
497243
|
+
if (sortedCmds.length === 0) return;
|
|
497244
|
+
if (matchesKey(data, Key.right) || matchesKey(data, Key.enter)) {
|
|
497245
|
+
this.showCommandDetail = true;
|
|
497246
|
+
return;
|
|
497247
|
+
}
|
|
497248
|
+
if (matchesKey(data, Key.left)) {
|
|
497249
|
+
this.showCommandDetail = false;
|
|
497250
|
+
return;
|
|
497251
|
+
}
|
|
497179
497252
|
if (matchesKey(data, Key.up)) {
|
|
497180
|
-
this.
|
|
497253
|
+
this.selectedCommandIndex = Math.max(0, this.selectedCommandIndex - 1);
|
|
497181
497254
|
return;
|
|
497182
497255
|
}
|
|
497183
497256
|
if (matchesKey(data, Key.down)) {
|
|
497184
|
-
this.
|
|
497257
|
+
this.selectedCommandIndex = Math.min(sortedCmds.length - 1, this.selectedCommandIndex + 1);
|
|
497185
497258
|
return;
|
|
497186
497259
|
}
|
|
497187
497260
|
if (matchesKey(data, Key.pageUp)) {
|
|
497188
|
-
this.
|
|
497261
|
+
this.selectedCommandIndex = Math.max(0, this.selectedCommandIndex - 10);
|
|
497189
497262
|
return;
|
|
497190
497263
|
}
|
|
497191
|
-
if (matchesKey(data, Key.pageDown)) this.
|
|
497264
|
+
if (matchesKey(data, Key.pageDown)) this.selectedCommandIndex = Math.min(sortedCmds.length - 1, this.selectedCommandIndex + 10);
|
|
497192
497265
|
}
|
|
497193
497266
|
render(width) {
|
|
497194
497267
|
const accent = (text) => currentTheme.fg("primary", text);
|
|
@@ -497199,6 +497272,8 @@ var HelpPanelComponent = class extends Container {
|
|
|
497199
497272
|
const shortcuts = this.opts.shortcuts ?? DEFAULT_KEYBOARD_SHORTCUTS;
|
|
497200
497273
|
const kbdWidth = Math.max(8, ...shortcuts.map((s) => s.keys.length));
|
|
497201
497274
|
const sortedCmds = [...this.opts.commands].toSorted(compareSlashCommandsForDisplay);
|
|
497275
|
+
this.selectedCommandIndex = Math.max(0, Math.min(this.selectedCommandIndex, Math.max(0, sortedCmds.length - 1)));
|
|
497276
|
+
if (this.showCommandDetail && sortedCmds.length > 0) return this.renderCommandDetail(width, sortedCmds);
|
|
497202
497277
|
const cmdLabels = sortedCmds.map((c) => {
|
|
497203
497278
|
const aliases = c.aliases.length > 0 ? ` (${c.aliases.map((a) => "/" + a).join(", ")})` : "";
|
|
497204
497279
|
return `/${c.name}${aliases}`;
|
|
@@ -497215,7 +497290,10 @@ var HelpPanelComponent = class extends Container {
|
|
|
497215
497290
|
"",
|
|
497216
497291
|
` ${currentTheme.bold(uiText("help.slashCommands"))}`,
|
|
497217
497292
|
...sortedCmds.map((cmd, i) => {
|
|
497218
|
-
|
|
497293
|
+
const marker = i === this.selectedCommandIndex ? accent("â–¶") : " ";
|
|
497294
|
+
const label = (cmdLabels[i] ?? `/${cmd.name}`).padEnd(cmdWidth);
|
|
497295
|
+
const commandText = i === this.selectedCommandIndex ? currentTheme.boldFg("primary", label) : slashColor(label);
|
|
497296
|
+
return ` ${marker} ${commandText} ${dim(cmd.description)}`;
|
|
497219
497297
|
}),
|
|
497220
497298
|
"",
|
|
497221
497299
|
accent("─".repeat(width))
|
|
@@ -497223,6 +497301,9 @@ var HelpPanelComponent = class extends Container {
|
|
|
497223
497301
|
const content = lines.slice(1, lines.length - 1);
|
|
497224
497302
|
const maxVisible = Math.max(5, this.opts.maxVisible ?? 24);
|
|
497225
497303
|
if (content.length > maxVisible) {
|
|
497304
|
+
const selectedLine = 7 + shortcuts.length + this.selectedCommandIndex;
|
|
497305
|
+
if (selectedLine < this.scrollTop) this.scrollTop = selectedLine;
|
|
497306
|
+
if (selectedLine >= this.scrollTop + maxVisible) this.scrollTop = selectedLine - maxVisible + 1;
|
|
497226
497307
|
this.scrollTop = Math.max(0, Math.min(this.scrollTop, content.length - maxVisible));
|
|
497227
497308
|
const slice = content.slice(this.scrollTop, this.scrollTop + maxVisible);
|
|
497228
497309
|
const scrollInfo = muted(` ${uiText("help.scrollInfo", {
|
|
@@ -497240,6 +497321,27 @@ var HelpPanelComponent = class extends Container {
|
|
|
497240
497321
|
this.scrollTop = 0;
|
|
497241
497322
|
return lines.map((line) => truncateToWidth(line, width));
|
|
497242
497323
|
}
|
|
497324
|
+
renderCommandDetail(width, sortedCmds) {
|
|
497325
|
+
const accent = (text) => currentTheme.fg("primary", text);
|
|
497326
|
+
const dim = (text) => currentTheme.fg("textDim", text);
|
|
497327
|
+
const muted = (text) => currentTheme.fg("textMuted", text);
|
|
497328
|
+
const command = sortedCmds[this.selectedCommandIndex];
|
|
497329
|
+
if (command === void 0) return [];
|
|
497330
|
+
const argumentHint = typeof command.argumentHint === "string" && command.argumentHint.length > 0 ? ` ${command.argumentHint}` : "";
|
|
497331
|
+
const aliases = command.aliases.length > 0 ? command.aliases.map((alias) => `/${alias}`).join(", ") : "—";
|
|
497332
|
+
const descriptionLines = wrapTextWithAnsi(dim(command.description), Math.max(10, width - 4)).map((line) => ` ${line}`);
|
|
497333
|
+
return [
|
|
497334
|
+
accent("─".repeat(width)),
|
|
497335
|
+
currentTheme.boldFg("primary", ` /${command.name}${argumentHint}`),
|
|
497336
|
+
"",
|
|
497337
|
+
...descriptionLines,
|
|
497338
|
+
"",
|
|
497339
|
+
` ${muted("=")} ${dim(aliases)}`,
|
|
497340
|
+
"",
|
|
497341
|
+
muted(` ${this.selectedCommandIndex + 1}/${sortedCmds.length} · ↑↓ · ↠· Esc / q`),
|
|
497342
|
+
accent("─".repeat(width))
|
|
497343
|
+
].map((line) => truncateToWidth(line, width));
|
|
497344
|
+
}
|
|
497243
497345
|
};
|
|
497244
497346
|
function localizedShortcut(keys, descriptionKey) {
|
|
497245
497347
|
return {
|
|
@@ -506727,6 +506829,7 @@ var SessionEventHandler = class {
|
|
|
506727
506829
|
this.showErrorReportHint(event);
|
|
506728
506830
|
}
|
|
506729
506831
|
showErrorReportHint(event) {
|
|
506832
|
+
if (!shouldShowErrorReportHint(event)) return;
|
|
506730
506833
|
const { appState } = this.host.state;
|
|
506731
506834
|
if (appState.sessionId.length === 0) return;
|
|
506732
506835
|
this.host.showStatus(errorReportHintLine({
|