blun-king-cli 9.1.481 → 9.1.483

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.
@@ -7,6 +7,25 @@ function resolveCompactionModelAlias(configuredAlias, activeAlias) {
7
7
  return activeAlias;
8
8
  }
9
9
 
10
+ function normalizeCompactionModelSelection(value) {
11
+ if (typeof value !== 'string') return undefined;
12
+ const normalized = value.trim();
13
+ if (normalized.length === 0) return undefined;
14
+ if (['clear', 'default', 'inherit'].includes(normalized.toLowerCase())) return null;
15
+ return normalized;
16
+ }
17
+
18
+ function clearCompactionModelConfig(config) {
19
+ const loopControl = { ...(config?.loopControl ?? {}) };
20
+ delete loopControl.compactionModel;
21
+ return {
22
+ ...config,
23
+ loopControl,
24
+ };
25
+ }
26
+
10
27
  module.exports = {
28
+ clearCompactionModelConfig,
29
+ normalizeCompactionModelSelection,
11
30
  resolveCompactionModelAlias,
12
31
  };
@@ -14,6 +14,7 @@ const TOOL_RESULT_HISTORICAL_REPLACEMENT_BUDGET_CHARS = 600;
14
14
  const TOOL_RESULT_SUCCESS_KEEP_RECENT_MESSAGES = 12;
15
15
  const TOOL_RESULT_HISTORICAL_SUCCESS_MARKER = '[Old tool result content cleared]';
16
16
  const TOOL_RESULT_REPEAT_MARKER = '[Repeated tool result omitted]';
17
+ const READ_CONTINUATION_LINE_OFFSET_RE = /^Continue reading with line_offset=(\d+)\. Do not assume you have reached the end of the file\.$/mu;
17
18
 
18
19
  function shouldOffloadToolResult(textLength) {
19
20
  return Number.isFinite(textLength) && textLength > TOOL_RESULT_MAX_CHARS;
@@ -32,6 +33,12 @@ function createToolResultPreview(text) {
32
33
  return `${text.slice(0, headChars)}\n\n[... ${String(omittedChars)} characters omitted ...]\n\n${text.slice(-tailChars)}`;
33
34
  }
34
35
 
36
+ function readContinuationLineOffset(text) {
37
+ if (typeof text !== 'string') return undefined;
38
+ const value = Number(text.match(READ_CONTINUATION_LINE_OFFSET_RE)?.[1]);
39
+ return Number.isSafeInteger(value) && value >= 1 ? value : undefined;
40
+ }
41
+
35
42
  function isPersistedToolResultReference(content) {
36
43
  if (!Array.isArray(content)) return false;
37
44
 
@@ -89,10 +96,14 @@ function compactPersistedToolResultReference(content) {
89
96
  const outputPath = lines.find((line) => line.startsWith('output_path: '));
90
97
  if (outputPath === undefined) return part;
91
98
  const recoveryLines = [TOOL_RESULT_OFFLOAD_MARKER];
92
- for (const prefix of ['tool_name: ', 'output_size_chars: ']) {
99
+ for (const prefix of ['tool_name: ', 'output_size_chars: ', 'next_line_offset: ']) {
93
100
  const line = lines.find((candidate) => candidate.startsWith(prefix));
94
101
  if (line !== undefined) recoveryLines.push(line);
95
102
  }
103
+ if (recoveryLines.some((line) => line.startsWith('next_line_offset: '))) {
104
+ const nextStep = lines.find((line) => line.startsWith('next_step: '));
105
+ if (nextStep !== undefined) recoveryLines.push(nextStep);
106
+ }
96
107
  recoveryLines.push(outputPath);
97
108
  const text = recoveryLines.join('\n');
98
109
  if (text === part.text) return part;
@@ -298,6 +309,7 @@ module.exports = {
298
309
  dedupeRepeatedSuccessfulToolResults,
299
310
  freshToolResultIds,
300
311
  isPersistedToolResultReference,
312
+ readContinuationLineOffset,
301
313
  selectHistoricalToolResultOffloads,
302
314
  selectToolResultBatchOffloads,
303
315
  shouldKeepFreshToolResult,
package/blun.mjs CHANGED
@@ -49,7 +49,7 @@ const { writeTelegramConsoleStatus } = telegramConsoleStatusPolicy;
49
49
  const { goalAutostartDecision, goalContinuationDecision } = cognitiveGoalAutostartPolicy;
50
50
  const { GoalTimeTriggerController } = cognitiveGoalTimeTriggerController;
51
51
  const { recordRuntimeExit } = runtimeExitLedger;
52
- const { resolveCompactionModelAlias } = compactionModelPolicy;
52
+ const { clearCompactionModelConfig, normalizeCompactionModelSelection, resolveCompactionModelAlias } = compactionModelPolicy;
53
53
  const { createAgentResumeSnapshot, restoreAgentResumeSnapshot } = agentResumeSnapshot;
54
54
  const { loadResumeCheckpoint, writeResumeCheckpoint } = sessionResumeCheckpoint;
55
55
  const { SessionScrollbackArchive, sessionScrollbackArchiveDirectory } = sessionScrollbackArchive;
@@ -10193,7 +10193,9 @@ var init_schema = __esmMin((() => {
10193
10193
  ModelAliasPatchSchema = ModelAliasSchema.partial();
10194
10194
  ThinkingConfigPatchSchema = ThinkingConfigSchema.partial();
10195
10195
  PermissionConfigPatchSchema = PermissionConfigSchema.partial();
10196
- LoopControlPatchSchema = LoopControlSchema.partial();
10196
+ LoopControlPatchSchema = LoopControlSchema.partial().extend({
10197
+ compactionModel: string().min(1).nullable().optional()
10198
+ });
10197
10199
  BackgroundConfigPatchSchema = BackgroundConfigSchema.partial();
10198
10200
  ModelCatalogConfigPatchSchema = ModelCatalogConfigSchema.partial();
10199
10201
  ExperimentalConfigPatchSchema = ExperimentalConfigSchema;
@@ -10231,7 +10233,12 @@ var init_schema = __esmMin((() => {
10231
10233
  //#endregion
10232
10234
  //#region ../../packages/agent-core/src/config/merge.ts
10233
10235
  function mergeConfigPatch(config, patch) {
10234
- return validateConfig(deepMerge(validateConfig(config), parsePatch(patch)));
10236
+ const parsed = parsePatch(patch);
10237
+ const clearCompactionModel = parsed.loopControl?.compactionModel === null;
10238
+ if (clearCompactionModel) delete parsed.loopControl.compactionModel;
10239
+ let merged = deepMerge(validateConfig(config), parsed);
10240
+ if (clearCompactionModel) merged = clearCompactionModelConfig(merged);
10241
+ return validateConfig(merged);
10235
10242
  }
10236
10243
  function parsePatch(patch) {
10237
10244
  try {
@@ -16220,6 +16227,7 @@ function visionReaderToToml(service) {
16220
16227
  function loopControlToToml(loopControl, rawLoopControl) {
16221
16228
  const out = cloneRecord$2(rawLoopControl);
16222
16229
  for (const [key, value] of Object.entries(loopControl)) setDefined(out, camelToSnake$2(key), value);
16230
+ if (loopControl.compactionModel === void 0) delete out["compaction_model"];
16223
16231
  return out;
16224
16232
  }
16225
16233
  function backgroundToToml(background, rawBackground) {
@@ -261032,6 +261040,7 @@ async function persistHistoricalToolResultForModel(options, knownText) {
261032
261040
  };
261033
261041
  }
261034
261042
  function renderHistoricalToolResultReference(toolName, toolCallId, text, outputPath, storageMode) {
261043
+ const nextLineOffset = toolName === "Read" ? readContinuationLineOffset(text) : void 0;
261035
261044
  return [
261036
261045
  TOOL_RESULT_OFFLOAD_MARKER,
261037
261046
  "An older tool result was archived to keep the active context fast.",
@@ -261040,14 +261049,15 @@ function renderHistoricalToolResultReference(toolName, toolCallId, text, outputP
261040
261049
  `tool_call_id: ${toolCallId}`,
261041
261050
  `output_size_chars: ${String(text.length)}`,
261042
261051
  `output_size_bytes: ${String(Buffer.byteLength(text, "utf8"))}`,
261052
+ ...(nextLineOffset === void 0 ? [] : [`next_line_offset: ${String(nextLineOffset)}`]),
261043
261053
  `output_path: ${outputPath}`,
261044
- `next_step: Use Read with output_path using n_lines <= ${String(TOOL_RESULT_RECOVERY_PAGE_LINES)}; advance line_offset between calls.`
261054
+ nextLineOffset === void 0 ? `next_step: Use Read with output_path using n_lines <= ${String(TOOL_RESULT_RECOVERY_PAGE_LINES)}; advance line_offset between calls.` : `next_step: Continue the original Read with line_offset=${String(nextLineOffset)}; do not restart at the beginning.`
261045
261055
  ].join("\n");
261046
261056
  }
261047
261057
  function safeToolResultFileStem(toolName, toolCallId) {
261048
261058
  return `${toolName}-${toolCallId}`.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80) || "tool-result";
261049
261059
  }
261050
- var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_RECOVERY_PAGE_LINES, TOOL_RESULT_OFFLOAD_MARKER, TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES, shouldKeepFreshToolResult, shouldOffloadToolResult, createToolResultPreview, compactPersistedToolResultReference, compactHistoricalSuccessfulToolResults, dedupeRepeatedSuccessfulToolResults, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
261060
+ var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_RECOVERY_PAGE_LINES, TOOL_RESULT_OFFLOAD_MARKER, TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES, shouldKeepFreshToolResult, shouldOffloadToolResult, createToolResultPreview, compactPersistedToolResultReference, compactHistoricalSuccessfulToolResults, dedupeRepeatedSuccessfulToolResults, readContinuationLineOffset, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
261051
261061
  var init_tool_result_budget = __esmMin((() => {
261052
261062
  init_dist$6();
261053
261063
  const toolResultOffloadPolicy = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs");
@@ -261064,6 +261074,7 @@ var init_tool_result_budget = __esmMin((() => {
261064
261074
  compactHistoricalSuccessfulToolResults = toolResultOffloadPolicy.compactHistoricalSuccessfulToolResults;
261065
261075
  dedupeRepeatedSuccessfulToolResults = toolResultOffloadPolicy.dedupeRepeatedSuccessfulToolResults;
261066
261076
  freshToolResultIds = toolResultOffloadPolicy.freshToolResultIds;
261077
+ readContinuationLineOffset = toolResultOffloadPolicy.readContinuationLineOffset;
261067
261078
  selectToolResultBatchOffloads = toolResultOffloadPolicy.selectToolResultBatchOffloads;
261068
261079
  selectHistoricalToolResultOffloads = toolResultOffloadPolicy.selectHistoricalToolResultOffloads;
261069
261080
  }));
@@ -403084,6 +403095,7 @@ registerUiCatalogFragment({
403084
403095
  "command.reload.description": "Reload the session and apply runtime and interface settings",
403085
403096
  "command.reload-tui.description": "Reload interface settings only",
403086
403097
  "command.compact.description": "Compact the conversation context",
403098
+ "command.compactionModel.description": "Choose the model used for context compaction",
403087
403099
  "command.goal.description": "Start or manage an autonomous goal",
403088
403100
  "command.idea.description": "Start or manage an autonomous idea",
403089
403101
  "command.loop.description": "Start or manage a recurring prompt",
@@ -403142,6 +403154,7 @@ registerUiCatalogFragment({
403142
403154
  "command.reload.description": "Sitzung neu laden und Runtime- sowie Oberflächeneinstellungen anwenden",
403143
403155
  "command.reload-tui.description": "Nur Oberflächeneinstellungen neu laden",
403144
403156
  "command.compact.description": "Konversationskontext komprimieren",
403157
+ "command.compactionModel.description": "Modell für die Verdichtung wählen",
403145
403158
  "command.goal.description": "Autonomes Ziel starten oder verwalten",
403146
403159
  "command.idea.description": "Autonome Idee starten oder verwalten",
403147
403160
  "command.loop.description": "Wiederkehrenden Prompt starten oder verwalten",
@@ -403200,6 +403213,7 @@ registerUiCatalogFragment({
403200
403213
  "command.reload.description": "Recargar la sesión y aplicar los ajustes del entorno de ejecución y de la interfaz",
403201
403214
  "command.reload-tui.description": "Recargar solo los ajustes de la interfaz",
403202
403215
  "command.compact.description": "Compactar el contexto de la conversación",
403216
+ "command.compactionModel.description": "Elegir el modelo para compactar el contexto",
403203
403217
  "command.goal.description": "Iniciar o gestionar un objetivo autónomo",
403204
403218
  "command.idea.description": "Iniciar o gestionar una idea autónoma",
403205
403219
  "command.loop.description": "Iniciar o gestionar una instrucción recurrente",
@@ -403258,6 +403272,7 @@ registerUiCatalogFragment({
403258
403272
  "command.reload.description": "Recharger la session et appliquer les paramètres d’exécution et d’interface",
403259
403273
  "command.reload-tui.description": "Recharger uniquement les paramètres de l’interface",
403260
403274
  "command.compact.description": "Compacter le contexte de la conversation",
403275
+ "command.compactionModel.description": "Choisir le modèle utilisé pour compacter le contexte",
403261
403276
  "command.goal.description": "Démarrer ou gérer un objectif autonome",
403262
403277
  "command.idea.description": "Démarrer ou gérer une idée autonome",
403263
403278
  "command.loop.description": "Démarrer ou gérer une demande récurrente",
@@ -403316,6 +403331,7 @@ registerUiCatalogFragment({
403316
403331
  "command.reload.description": "Läs in sessionen på nytt och tillämpa körningsmiljö- och gränssnittsinställningar",
403317
403332
  "command.reload-tui.description": "Läs bara in gränssnittsinställningarna på nytt",
403318
403333
  "command.compact.description": "Komprimera konversationskontexten",
403334
+ "command.compactionModel.description": "Välj modell för kontextkomprimering",
403319
403335
  "command.goal.description": "Starta eller hantera ett autonomt mål",
403320
403336
  "command.idea.description": "Starta eller hantera en självständig idé",
403321
403337
  "command.loop.description": "Starta eller hantera en återkommande prompt",
@@ -403374,6 +403390,7 @@ registerUiCatalogFragment({
403374
403390
  "command.reload.description": "Znovu načíst relaci a použít nastavení běhového prostředí a rozhraní",
403375
403391
  "command.reload-tui.description": "Znovu načíst pouze nastavení rozhraní",
403376
403392
  "command.compact.description": "Komprimovat kontext konverzace",
403393
+ "command.compactionModel.description": "Vyberte model pro komprimaci kontextu",
403377
403394
  "command.goal.description": "Spustit nebo spravovat autonomní cíl",
403378
403395
  "command.idea.description": "Spustit nebo spravovat autonomní nápad",
403379
403396
  "command.loop.description": "Spustit nebo spravovat opakované zadání",
@@ -403775,6 +403792,14 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
403775
403792
  priority: 80,
403776
403793
  argumentHint: "<instruction>"
403777
403794
  },
403795
+ {
403796
+ name: "summarization-model",
403797
+ aliases: ["summary-model", "compaction-model"],
403798
+ descriptionKey: "command.compactionModel.description",
403799
+ priority: 80,
403800
+ argumentHint: "[<model> | inherit]",
403801
+ availability: "idle-only"
403802
+ },
403778
403803
  {
403779
403804
  name: "goal",
403780
403805
  aliases: [],
@@ -417202,6 +417227,115 @@ var PersonalitySelectorComponent = class extends ChoicePickerComponent {
417202
417227
  }
417203
417228
  };
417204
417229
  //#endregion
417230
+ //#region src/tui/components/dialogs/compaction-model-selector.copy.ts
417231
+ registerUiCatalogFragment({
417232
+ en: {
417233
+ "compactionModel.title": "Compaction model",
417234
+ "compactionModel.followLabel": "Follow the active model",
417235
+ "compactionModel.followDescription": "Use the current responder model for each compaction",
417236
+ "compactionModel.modelDescription": "Use {model} for compaction",
417237
+ "compactionModel.saved": "Compaction model set to {model}; session reloaded",
417238
+ "compactionModel.savedActive": "Compaction now follows the active model; session reloaded",
417239
+ "compactionModel.unchanged": "Compaction model is already {model}",
417240
+ "compactionModel.unknown": "Model \"{model}\" is not configured",
417241
+ "compactionModel.failed": "Could not save the compaction model: {error}",
417242
+ "compactionModel.reloadFailed": "The compaction model was saved, but this session could not reload: {error}. Run /reload to apply it.",
417243
+ "compactionModel.noModels": "No configured models are available."
417244
+ },
417245
+ de: {
417246
+ "compactionModel.title": "Verdichtungsmodell",
417247
+ "compactionModel.followLabel": "Dem aktiven Modell folgen",
417248
+ "compactionModel.followDescription": "Bei jeder Verdichtung das aktuell antwortende Modell verwenden",
417249
+ "compactionModel.modelDescription": "{model} für die Verdichtung verwenden",
417250
+ "compactionModel.saved": "Verdichtungsmodell auf {model} gesetzt; Sitzung neu geladen",
417251
+ "compactionModel.savedActive": "Die Verdichtung folgt jetzt dem aktiven Modell; Sitzung neu geladen",
417252
+ "compactionModel.unchanged": "Als Verdichtungsmodell ist bereits {model} eingestellt",
417253
+ "compactionModel.unknown": "Das Modell „{model}“ ist nicht konfiguriert",
417254
+ "compactionModel.failed": "Das Verdichtungsmodell konnte nicht gespeichert werden: {error}",
417255
+ "compactionModel.reloadFailed": "Das Verdichtungsmodell wurde gespeichert, aber die Sitzung konnte nicht neu geladen werden: {error}. Mit /reload wird die Änderung übernommen.",
417256
+ "compactionModel.noModels": "Es sind keine konfigurierten Modelle verfügbar."
417257
+ },
417258
+ es: {
417259
+ "compactionModel.title": "Modelo de compactación",
417260
+ "compactionModel.followLabel": "Seguir el modelo activo",
417261
+ "compactionModel.followDescription": "Usar el modelo que esté respondiendo en cada compactación",
417262
+ "compactionModel.modelDescription": "Usar {model} para la compactación",
417263
+ "compactionModel.saved": "Modelo de compactación cambiado a {model}; sesión recargada",
417264
+ "compactionModel.savedActive": "Ahora la compactación sigue el modelo activo; sesión recargada",
417265
+ "compactionModel.unchanged": "El modelo de compactación ya es {model}",
417266
+ "compactionModel.unknown": "El modelo «{model}» no está configurado",
417267
+ "compactionModel.failed": "No se pudo guardar el modelo de compactación: {error}",
417268
+ "compactionModel.reloadFailed": "El modelo de compactación se guardó, pero no se pudo recargar esta sesión: {error}. Ejecuta /reload para aplicar el cambio.",
417269
+ "compactionModel.noModels": "No hay modelos configurados disponibles."
417270
+ },
417271
+ fr: {
417272
+ "compactionModel.title": "Modèle de compactage",
417273
+ "compactionModel.followLabel": "Suivre le modèle actif",
417274
+ "compactionModel.followDescription": "Utiliser le modèle qui répond actuellement pour chaque compactage",
417275
+ "compactionModel.modelDescription": "Utiliser {model} pour le compactage",
417276
+ "compactionModel.saved": "Modèle de compactage défini sur {model} ; session rechargée",
417277
+ "compactionModel.savedActive": "Le compactage suit désormais le modèle actif ; session rechargée",
417278
+ "compactionModel.unchanged": "Le modèle de compactage est déjà {model}",
417279
+ "compactionModel.unknown": "Le modèle « {model} » n’est pas configuré",
417280
+ "compactionModel.failed": "Impossible d’enregistrer le modèle de compactage : {error}",
417281
+ "compactionModel.reloadFailed": "Le modèle de compactage a été enregistré, mais cette session n’a pas pu être rechargée : {error}. Exécutez /reload pour appliquer la modification.",
417282
+ "compactionModel.noModels": "Aucun modèle configuré n’est disponible."
417283
+ },
417284
+ sv: {
417285
+ "compactionModel.title": "Komprimeringsmodell",
417286
+ "compactionModel.followLabel": "Följ den aktiva modellen",
417287
+ "compactionModel.followDescription": "Använd modellen som svarar för varje komprimering",
417288
+ "compactionModel.modelDescription": "Använd {model} för komprimering",
417289
+ "compactionModel.saved": "Komprimeringsmodellen har ställts in på {model}; sessionen har lästs in på nytt",
417290
+ "compactionModel.savedActive": "Komprimeringen följer nu den aktiva modellen; sessionen har lästs in på nytt",
417291
+ "compactionModel.unchanged": "Komprimeringsmodellen är redan {model}",
417292
+ "compactionModel.unknown": "Modellen ”{model}” är inte konfigurerad",
417293
+ "compactionModel.failed": "Det gick inte att spara komprimeringsmodellen: {error}",
417294
+ "compactionModel.reloadFailed": "Komprimeringsmodellen sparades, men sessionen kunde inte läsas in på nytt: {error}. Kör /reload för att använda ändringen.",
417295
+ "compactionModel.noModels": "Det finns inga konfigurerade modeller."
417296
+ },
417297
+ cs: {
417298
+ "compactionModel.title": "Model pro komprimaci",
417299
+ "compactionModel.followLabel": "Používat aktivní model",
417300
+ "compactionModel.followDescription": "Pro každou komprimaci použít model, který právě odpovídá",
417301
+ "compactionModel.modelDescription": "Použít model {model} pro komprimaci",
417302
+ "compactionModel.saved": "Model pro komprimaci byl nastaven na {model}; relace byla znovu načtena",
417303
+ "compactionModel.savedActive": "Komprimace nyní používá aktivní model; relace byla znovu načtena",
417304
+ "compactionModel.unchanged": "Model pro komprimaci je již nastaven na {model}",
417305
+ "compactionModel.unknown": "Model „{model}“ není nakonfigurován",
417306
+ "compactionModel.failed": "Model pro komprimaci se nepodařilo uložit: {error}",
417307
+ "compactionModel.reloadFailed": "Model pro komprimaci byl uložen, ale tuto relaci se nepodařilo znovu načíst: {error}. Změnu použijete příkazem /reload.",
417308
+ "compactionModel.noModels": "Nejsou k dispozici žádné nakonfigurované modely."
417309
+ }
417310
+ });
417311
+ const COMPACTION_MODEL_INHERIT = Symbol("compaction-model-inherit");
417312
+ function compactionModelOptions(models) {
417313
+ return [
417314
+ {
417315
+ value: COMPACTION_MODEL_INHERIT,
417316
+ label: uiText("compactionModel.followLabel"),
417317
+ description: uiText("compactionModel.followDescription")
417318
+ },
417319
+ ...Object.entries(models).sort(([left], [right]) => left.localeCompare(right)).map(([alias, model]) => ({
417320
+ value: alias,
417321
+ label: model.displayName ?? alias,
417322
+ description: uiText("compactionModel.modelDescription", { model: alias })
417323
+ }))
417324
+ ];
417325
+ }
417326
+ var CompactionModelSelectorComponent = class extends ChoicePickerComponent {
417327
+ constructor(opts) {
417328
+ super({
417329
+ title: uiText("compactionModel.title"),
417330
+ options: compactionModelOptions(opts.models),
417331
+ currentValue: opts.currentValue ?? COMPACTION_MODEL_INHERIT,
417332
+ searchable: true,
417333
+ onSelect: opts.onSelect,
417334
+ onCancel: opts.onCancel
417335
+ });
417336
+ }
417337
+ };
417338
+ //#endregion
417205
417339
  //#region src/tui/components/dialogs/settings-selector.ts
417206
417340
  function settingsOptions() {
417207
417341
  return [
@@ -417210,6 +417344,11 @@ function settingsOptions() {
417210
417344
  label: uiText("effort.title"),
417211
417345
  description: uiText("command.effort.description")
417212
417346
  },
417347
+ {
417348
+ value: "compaction-model",
417349
+ label: uiText("compactionModel.title"),
417350
+ description: uiText("command.compactionModel.description")
417351
+ },
417213
417352
  {
417214
417353
  value: "inline-suggest",
417215
417354
  label: uiText("settings.inlineSuggest.label"),
@@ -417258,7 +417397,7 @@ function settingsOptions() {
417258
417397
  ];
417259
417398
  }
417260
417399
  function isSettingsSelection(value) {
417261
- return value === "effort" || value === "action-style" || value === "personality" || value === "theme" || value === "appearance" || value === "editor" || value === "permission" || value === "experiments" || value === "usage" || value === "inline-suggest";
417400
+ return value === "effort" || value === "compaction-model" || value === "action-style" || value === "personality" || value === "theme" || value === "appearance" || value === "editor" || value === "permission" || value === "experiments" || value === "usage" || value === "inline-suggest";
417262
417401
  }
417263
417402
  var SettingsSelectorComponent = class extends ChoicePickerComponent {
417264
417403
  constructor(opts) {
@@ -420686,6 +420825,85 @@ async function handleCompactCommand(host, args) {
420686
420825
  const customInstruction = args.trim() || void 0;
420687
420826
  await session.compact({ instruction: customInstruction });
420688
420827
  }
420828
+ async function handleCompactionModelCommand(host, args) {
420829
+ if (host.session === void 0) {
420830
+ host.showError(noActiveSessionMessage());
420831
+ return;
420832
+ }
420833
+ const selection = normalizeCompactionModelSelection(args);
420834
+ if (selection === void 0) {
420835
+ await showCompactionModelPicker(host);
420836
+ return;
420837
+ }
420838
+ await applyCompactionModelChoice(host, selection);
420839
+ }
420840
+ async function applyCompactionModelChoice(host, selection) {
420841
+ const session = host.session;
420842
+ if (session === void 0) {
420843
+ host.showError(noActiveSessionMessage());
420844
+ return;
420845
+ }
420846
+ let config;
420847
+ try {
420848
+ config = await host.harness.getConfig({ reload: true });
420849
+ } catch (error) {
420850
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420851
+ return;
420852
+ }
420853
+ if (typeof selection === "string" && config.models?.[selection] === void 0) {
420854
+ host.showError(uiText("compactionModel.unknown", { model: selection }));
420855
+ return;
420856
+ }
420857
+ const nextConfig = selection === null ? clearCompactionModelConfig(config) : {
420858
+ ...config,
420859
+ loopControl: {
420860
+ ...config.loopControl,
420861
+ compactionModel: selection
420862
+ }
420863
+ };
420864
+ const nextSelection = nextConfig.loopControl?.compactionModel ?? null;
420865
+ const currentSelection = config.loopControl?.compactionModel ?? null;
420866
+ const activeModel = host.state.appState.model;
420867
+ if (currentSelection === nextSelection) {
420868
+ host.showStatus(uiText("compactionModel.unchanged", { model: nextSelection ?? activeModel }));
420869
+ return;
420870
+ }
420871
+ try {
420872
+ await host.harness.setConfig({ loopControl: { compactionModel: selection } });
420873
+ } catch (error) {
420874
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420875
+ return;
420876
+ }
420877
+ try {
420878
+ await session.reloadSession({ mcpServers: sessionMcpServers() });
420879
+ await host.reloadCurrentSessionView(session, selection === null ? uiText("compactionModel.savedActive") : uiText("compactionModel.saved", { model: selection }));
420880
+ } catch (error) {
420881
+ host.showError(uiText("compactionModel.reloadFailed", { error: formatErrorMessage$2(error) }));
420882
+ }
420883
+ }
420884
+ async function showCompactionModelPicker(host) {
420885
+ if (host.session === void 0) {
420886
+ host.showError(noActiveSessionMessage());
420887
+ return;
420888
+ }
420889
+ let config;
420890
+ try {
420891
+ config = await host.harness.getConfig({ reload: true });
420892
+ } catch (error) {
420893
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420894
+ return;
420895
+ }
420896
+ host.mountEditorReplacement(new CompactionModelSelectorComponent({
420897
+ models: config.models ?? {},
420898
+ currentValue: config.loopControl?.compactionModel ?? COMPACTION_MODEL_INHERIT,
420899
+ onSelect: (value) => {
420900
+ host.restoreEditorAfter(() => applyCompactionModelChoice(host, value === COMPACTION_MODEL_INHERIT ? null : value));
420901
+ },
420902
+ onCancel: () => {
420903
+ host.restoreEditor();
420904
+ }
420905
+ }));
420906
+ }
420689
420907
  async function handleEditorCommand(host, args) {
420690
420908
  const command = args.trim();
420691
420909
  if (command.length === 0) {
@@ -421348,6 +421566,9 @@ function handleSettingsSelection(host, value) {
421348
421566
  case "effort":
421349
421567
  handleEffortCommand(host, "");
421350
421568
  return;
421569
+ case "compaction-model":
421570
+ showCompactionModelPicker(host);
421571
+ return;
421351
421572
  case "action-style":
421352
421573
  showOutputStylePicker(host);
421353
421574
  return;
@@ -496284,6 +496505,9 @@ async function handleBuiltInSlashCommand(host, name, args) {
496284
496505
  case "compact":
496285
496506
  await handleCompactCommand(host, args);
496286
496507
  return;
496508
+ case "summarization-model":
496509
+ await handleCompactionModelCommand(host, args);
496510
+ return;
496287
496511
  case "goal":
496288
496512
  await handleGoalCommand(host, args);
496289
496513
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.481",
3
+ "version": "9.1.483",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {