blun-king-cli 9.1.482 → 9.1.484

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
  };
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) {
@@ -298441,17 +298449,16 @@ var init_types = __esmMin((() => {
298441
298449
  //#endregion
298442
298450
  //#region ../../packages/agent-core/src/plugin/manifest.ts
298443
298451
  async function parseManifest(pluginRoot) {
298444
- const rootJsonPath = path.join(pluginRoot, BLUN_PLUGIN_ROOT_PATH);
298445
- const dirJsonPath = path.join(pluginRoot, BLUN_PLUGIN_DIR_PATH);
298446
- const rootJsonExists = await isFile$1(rootJsonPath);
298447
- const dirJsonExists = await isFile$1(dirJsonPath);
298448
- if (!rootJsonExists && !dirJsonExists) return { diagnostics: [{
298452
+ const candidates = pluginManifestCandidates(pluginRoot);
298453
+ const existing = [];
298454
+ for (const candidate of candidates) if (await isFile$1(candidate.path)) existing.push(candidate);
298455
+ if (existing.length === 0) return { diagnostics: [{
298449
298456
  severity: "error",
298450
- message: `No manifest at ${BLUN_PLUGIN_ROOT_PATH} or ${BLUN_PLUGIN_DIR_PATH}`
298457
+ message: `No manifest at ${BLUN_PLUGIN_ROOT_PATH}, ${BLUN_PLUGIN_DIR_PATH}, or ${CODEX_PLUGIN_DIR_PATH}`
298451
298458
  }] };
298452
- const manifestPath = rootJsonExists ? rootJsonPath : dirJsonPath;
298453
- const manifestKind = rootJsonExists ? "blun-plugin-root" : "blun-plugin-dir";
298454
- const shadowedManifestPath = rootJsonExists && dirJsonExists ? dirJsonPath : void 0;
298459
+ const manifestPath = existing[0].path;
298460
+ const manifestKind = existing[0].kind;
298461
+ const shadowedManifestPath = existing[1]?.path;
298455
298462
  let raw;
298456
298463
  try {
298457
298464
  raw = JSON.parse(await readFile(manifestPath, "utf8"));
@@ -298531,6 +298538,18 @@ async function parseManifest(pluginRoot) {
298531
298538
  diagnostics
298532
298539
  };
298533
298540
  }
298541
+ function pluginManifestCandidates(pluginRoot) {
298542
+ return [{
298543
+ kind: "blun-plugin-root",
298544
+ path: path.join(pluginRoot, BLUN_PLUGIN_ROOT_PATH)
298545
+ }, {
298546
+ kind: "blun-plugin-dir",
298547
+ path: path.join(pluginRoot, BLUN_PLUGIN_DIR_PATH)
298548
+ }, {
298549
+ kind: "codex-plugin-dir",
298550
+ path: path.join(pluginRoot, CODEX_PLUGIN_DIR_PATH)
298551
+ }];
298552
+ }
298534
298553
  function recordUnsupportedRuntimeFields(raw, diagnostics) {
298535
298554
  for (const field of UNSUPPORTED_RUNTIME_FIELDS) {
298536
298555
  if (raw[field] === void 0) continue;
@@ -298588,7 +298607,7 @@ async function resolveSkillsField(pluginRoot, raw, diagnostics) {
298588
298607
  return resolved;
298589
298608
  }
298590
298609
  async function resolvePluginPathField(input) {
298591
- if (!input.value.startsWith("./")) {
298610
+ if (!input.value.startsWith("./") && !path.isAbsolute(input.value)) {
298592
298611
  input.diagnostics.push({
298593
298612
  severity: "warn",
298594
298613
  message: `"${input.field}" path must start with "./" (got "${input.value}")`
@@ -298856,8 +298875,9 @@ function commandNameFromFile(file, root) {
298856
298875
  async function normalizePluginMcpServer(input) {
298857
298876
  const { config } = input;
298858
298877
  if (config.transport === "http" || config.transport === "sse") return config;
298859
- let command = config.command;
298860
- if (command.startsWith("./")) {
298878
+ const configuredCommand = config.command;
298879
+ let command = expandPluginRootToken(configuredCommand, input.pluginRoot);
298880
+ if (command.startsWith("./") || command !== configuredCommand) {
298861
298881
  const resolvedCommand = await resolvePluginPathField({
298862
298882
  pluginRoot: input.pluginRoot,
298863
298883
  field: `mcpServers.${input.name}.command`,
@@ -298873,7 +298893,8 @@ async function normalizePluginMcpServer(input) {
298873
298893
  });
298874
298894
  return;
298875
298895
  }
298876
- let cwd = config.cwd;
298896
+ const args = config.args?.map((arg) => expandPluginRootToken(arg, input.pluginRoot));
298897
+ let cwd = config.cwd === void 0 ? void 0 : expandPluginRootToken(config.cwd, input.pluginRoot);
298877
298898
  if (cwd !== void 0) {
298878
298899
  const resolvedCwd = await resolvePluginPathField({
298879
298900
  pluginRoot: input.pluginRoot,
@@ -298887,9 +298908,13 @@ async function normalizePluginMcpServer(input) {
298887
298908
  return {
298888
298909
  ...config,
298889
298910
  command,
298911
+ args,
298890
298912
  cwd
298891
298913
  };
298892
298914
  }
298915
+ function expandPluginRootToken(value, pluginRoot) {
298916
+ return value.replaceAll("${PLUGIN_ROOT}", pluginRoot).replaceAll("${BLUN_PLUGIN_ROOT}", pluginRoot);
298917
+ }
298893
298918
  function readAuthor(raw) {
298894
298919
  if (typeof raw === "string") return { name: raw };
298895
298920
  if (!isObject$4(raw)) return void 0;
@@ -298957,12 +298982,13 @@ async function isDir(p) {
298957
298982
  return false;
298958
298983
  }
298959
298984
  }
298960
- var BLUN_PLUGIN_ROOT_PATH, BLUN_PLUGIN_DIR_PATH, UNSUPPORTED_RUNTIME_FIELDS;
298985
+ var BLUN_PLUGIN_ROOT_PATH, BLUN_PLUGIN_DIR_PATH, CODEX_PLUGIN_DIR_PATH, UNSUPPORTED_RUNTIME_FIELDS;
298961
298986
  var init_manifest$1 = __esmMin((() => {
298962
298987
  init_schema();
298963
298988
  init_types();
298964
298989
  BLUN_PLUGIN_ROOT_PATH = "blun.plugin.json";
298965
298990
  BLUN_PLUGIN_DIR_PATH = ".blun-plugin/plugin.json";
298991
+ CODEX_PLUGIN_DIR_PATH = ".codex-plugin/plugin.json";
298966
298992
  UNSUPPORTED_RUNTIME_FIELDS = [
298967
298993
  "tools",
298968
298994
  "apps",
@@ -299111,9 +299137,8 @@ async function detectPluginRoot(dir) {
299111
299137
  return dir;
299112
299138
  }
299113
299139
  async function hasManifest(dir) {
299114
- const rootManifest = path.join(dir, "blun.plugin.json");
299115
- const dirManifest = path.join(dir, ".blun-plugin", "plugin.json");
299116
- return await isFile(rootManifest) || await isFile(dirManifest);
299140
+ for (const candidate of pluginManifestCandidates(dir)) if (await isFile(candidate.path)) return true;
299141
+ return false;
299117
299142
  }
299118
299143
  async function isFile(p) {
299119
299144
  try {
@@ -403087,6 +403112,7 @@ registerUiCatalogFragment({
403087
403112
  "command.reload.description": "Reload the session and apply runtime and interface settings",
403088
403113
  "command.reload-tui.description": "Reload interface settings only",
403089
403114
  "command.compact.description": "Compact the conversation context",
403115
+ "command.compactionModel.description": "Choose the model used for context compaction",
403090
403116
  "command.goal.description": "Start or manage an autonomous goal",
403091
403117
  "command.idea.description": "Start or manage an autonomous idea",
403092
403118
  "command.loop.description": "Start or manage a recurring prompt",
@@ -403145,6 +403171,7 @@ registerUiCatalogFragment({
403145
403171
  "command.reload.description": "Sitzung neu laden und Runtime- sowie Oberflächeneinstellungen anwenden",
403146
403172
  "command.reload-tui.description": "Nur Oberflächeneinstellungen neu laden",
403147
403173
  "command.compact.description": "Konversationskontext komprimieren",
403174
+ "command.compactionModel.description": "Modell für die Verdichtung wählen",
403148
403175
  "command.goal.description": "Autonomes Ziel starten oder verwalten",
403149
403176
  "command.idea.description": "Autonome Idee starten oder verwalten",
403150
403177
  "command.loop.description": "Wiederkehrenden Prompt starten oder verwalten",
@@ -403203,6 +403230,7 @@ registerUiCatalogFragment({
403203
403230
  "command.reload.description": "Recargar la sesión y aplicar los ajustes del entorno de ejecución y de la interfaz",
403204
403231
  "command.reload-tui.description": "Recargar solo los ajustes de la interfaz",
403205
403232
  "command.compact.description": "Compactar el contexto de la conversación",
403233
+ "command.compactionModel.description": "Elegir el modelo para compactar el contexto",
403206
403234
  "command.goal.description": "Iniciar o gestionar un objetivo autónomo",
403207
403235
  "command.idea.description": "Iniciar o gestionar una idea autónoma",
403208
403236
  "command.loop.description": "Iniciar o gestionar una instrucción recurrente",
@@ -403261,6 +403289,7 @@ registerUiCatalogFragment({
403261
403289
  "command.reload.description": "Recharger la session et appliquer les paramètres d’exécution et d’interface",
403262
403290
  "command.reload-tui.description": "Recharger uniquement les paramètres de l’interface",
403263
403291
  "command.compact.description": "Compacter le contexte de la conversation",
403292
+ "command.compactionModel.description": "Choisir le modèle utilisé pour compacter le contexte",
403264
403293
  "command.goal.description": "Démarrer ou gérer un objectif autonome",
403265
403294
  "command.idea.description": "Démarrer ou gérer une idée autonome",
403266
403295
  "command.loop.description": "Démarrer ou gérer une demande récurrente",
@@ -403319,6 +403348,7 @@ registerUiCatalogFragment({
403319
403348
  "command.reload.description": "Läs in sessionen på nytt och tillämpa körningsmiljö- och gränssnittsinställningar",
403320
403349
  "command.reload-tui.description": "Läs bara in gränssnittsinställningarna på nytt",
403321
403350
  "command.compact.description": "Komprimera konversationskontexten",
403351
+ "command.compactionModel.description": "Välj modell för kontextkomprimering",
403322
403352
  "command.goal.description": "Starta eller hantera ett autonomt mål",
403323
403353
  "command.idea.description": "Starta eller hantera en självständig idé",
403324
403354
  "command.loop.description": "Starta eller hantera en återkommande prompt",
@@ -403377,6 +403407,7 @@ registerUiCatalogFragment({
403377
403407
  "command.reload.description": "Znovu načíst relaci a použít nastavení běhového prostředí a rozhraní",
403378
403408
  "command.reload-tui.description": "Znovu načíst pouze nastavení rozhraní",
403379
403409
  "command.compact.description": "Komprimovat kontext konverzace",
403410
+ "command.compactionModel.description": "Vyberte model pro komprimaci kontextu",
403380
403411
  "command.goal.description": "Spustit nebo spravovat autonomní cíl",
403381
403412
  "command.idea.description": "Spustit nebo spravovat autonomní nápad",
403382
403413
  "command.loop.description": "Spustit nebo spravovat opakované zadání",
@@ -403778,6 +403809,14 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
403778
403809
  priority: 80,
403779
403810
  argumentHint: "<instruction>"
403780
403811
  },
403812
+ {
403813
+ name: "summarization-model",
403814
+ aliases: ["summary-model", "compaction-model"],
403815
+ descriptionKey: "command.compactionModel.description",
403816
+ priority: 80,
403817
+ argumentHint: "[<model> | inherit]",
403818
+ availability: "idle-only"
403819
+ },
403781
403820
  {
403782
403821
  name: "goal",
403783
403822
  aliases: [],
@@ -417205,6 +417244,115 @@ var PersonalitySelectorComponent = class extends ChoicePickerComponent {
417205
417244
  }
417206
417245
  };
417207
417246
  //#endregion
417247
+ //#region src/tui/components/dialogs/compaction-model-selector.copy.ts
417248
+ registerUiCatalogFragment({
417249
+ en: {
417250
+ "compactionModel.title": "Compaction model",
417251
+ "compactionModel.followLabel": "Follow the active model",
417252
+ "compactionModel.followDescription": "Use the current responder model for each compaction",
417253
+ "compactionModel.modelDescription": "Use {model} for compaction",
417254
+ "compactionModel.saved": "Compaction model set to {model}; session reloaded",
417255
+ "compactionModel.savedActive": "Compaction now follows the active model; session reloaded",
417256
+ "compactionModel.unchanged": "Compaction model is already {model}",
417257
+ "compactionModel.unknown": "Model \"{model}\" is not configured",
417258
+ "compactionModel.failed": "Could not save the compaction model: {error}",
417259
+ "compactionModel.reloadFailed": "The compaction model was saved, but this session could not reload: {error}. Run /reload to apply it.",
417260
+ "compactionModel.noModels": "No configured models are available."
417261
+ },
417262
+ de: {
417263
+ "compactionModel.title": "Verdichtungsmodell",
417264
+ "compactionModel.followLabel": "Dem aktiven Modell folgen",
417265
+ "compactionModel.followDescription": "Bei jeder Verdichtung das aktuell antwortende Modell verwenden",
417266
+ "compactionModel.modelDescription": "{model} für die Verdichtung verwenden",
417267
+ "compactionModel.saved": "Verdichtungsmodell auf {model} gesetzt; Sitzung neu geladen",
417268
+ "compactionModel.savedActive": "Die Verdichtung folgt jetzt dem aktiven Modell; Sitzung neu geladen",
417269
+ "compactionModel.unchanged": "Als Verdichtungsmodell ist bereits {model} eingestellt",
417270
+ "compactionModel.unknown": "Das Modell „{model}“ ist nicht konfiguriert",
417271
+ "compactionModel.failed": "Das Verdichtungsmodell konnte nicht gespeichert werden: {error}",
417272
+ "compactionModel.reloadFailed": "Das Verdichtungsmodell wurde gespeichert, aber die Sitzung konnte nicht neu geladen werden: {error}. Mit /reload wird die Änderung übernommen.",
417273
+ "compactionModel.noModels": "Es sind keine konfigurierten Modelle verfügbar."
417274
+ },
417275
+ es: {
417276
+ "compactionModel.title": "Modelo de compactación",
417277
+ "compactionModel.followLabel": "Seguir el modelo activo",
417278
+ "compactionModel.followDescription": "Usar el modelo que esté respondiendo en cada compactación",
417279
+ "compactionModel.modelDescription": "Usar {model} para la compactación",
417280
+ "compactionModel.saved": "Modelo de compactación cambiado a {model}; sesión recargada",
417281
+ "compactionModel.savedActive": "Ahora la compactación sigue el modelo activo; sesión recargada",
417282
+ "compactionModel.unchanged": "El modelo de compactación ya es {model}",
417283
+ "compactionModel.unknown": "El modelo «{model}» no está configurado",
417284
+ "compactionModel.failed": "No se pudo guardar el modelo de compactación: {error}",
417285
+ "compactionModel.reloadFailed": "El modelo de compactación se guardó, pero no se pudo recargar esta sesión: {error}. Ejecuta /reload para aplicar el cambio.",
417286
+ "compactionModel.noModels": "No hay modelos configurados disponibles."
417287
+ },
417288
+ fr: {
417289
+ "compactionModel.title": "Modèle de compactage",
417290
+ "compactionModel.followLabel": "Suivre le modèle actif",
417291
+ "compactionModel.followDescription": "Utiliser le modèle qui répond actuellement pour chaque compactage",
417292
+ "compactionModel.modelDescription": "Utiliser {model} pour le compactage",
417293
+ "compactionModel.saved": "Modèle de compactage défini sur {model} ; session rechargée",
417294
+ "compactionModel.savedActive": "Le compactage suit désormais le modèle actif ; session rechargée",
417295
+ "compactionModel.unchanged": "Le modèle de compactage est déjà {model}",
417296
+ "compactionModel.unknown": "Le modèle « {model} » n’est pas configuré",
417297
+ "compactionModel.failed": "Impossible d’enregistrer le modèle de compactage : {error}",
417298
+ "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.",
417299
+ "compactionModel.noModels": "Aucun modèle configuré n’est disponible."
417300
+ },
417301
+ sv: {
417302
+ "compactionModel.title": "Komprimeringsmodell",
417303
+ "compactionModel.followLabel": "Följ den aktiva modellen",
417304
+ "compactionModel.followDescription": "Använd modellen som svarar för varje komprimering",
417305
+ "compactionModel.modelDescription": "Använd {model} för komprimering",
417306
+ "compactionModel.saved": "Komprimeringsmodellen har ställts in på {model}; sessionen har lästs in på nytt",
417307
+ "compactionModel.savedActive": "Komprimeringen följer nu den aktiva modellen; sessionen har lästs in på nytt",
417308
+ "compactionModel.unchanged": "Komprimeringsmodellen är redan {model}",
417309
+ "compactionModel.unknown": "Modellen ”{model}” är inte konfigurerad",
417310
+ "compactionModel.failed": "Det gick inte att spara komprimeringsmodellen: {error}",
417311
+ "compactionModel.reloadFailed": "Komprimeringsmodellen sparades, men sessionen kunde inte läsas in på nytt: {error}. Kör /reload för att använda ändringen.",
417312
+ "compactionModel.noModels": "Det finns inga konfigurerade modeller."
417313
+ },
417314
+ cs: {
417315
+ "compactionModel.title": "Model pro komprimaci",
417316
+ "compactionModel.followLabel": "Používat aktivní model",
417317
+ "compactionModel.followDescription": "Pro každou komprimaci použít model, který právě odpovídá",
417318
+ "compactionModel.modelDescription": "Použít model {model} pro komprimaci",
417319
+ "compactionModel.saved": "Model pro komprimaci byl nastaven na {model}; relace byla znovu načtena",
417320
+ "compactionModel.savedActive": "Komprimace nyní používá aktivní model; relace byla znovu načtena",
417321
+ "compactionModel.unchanged": "Model pro komprimaci je již nastaven na {model}",
417322
+ "compactionModel.unknown": "Model „{model}“ není nakonfigurován",
417323
+ "compactionModel.failed": "Model pro komprimaci se nepodařilo uložit: {error}",
417324
+ "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.",
417325
+ "compactionModel.noModels": "Nejsou k dispozici žádné nakonfigurované modely."
417326
+ }
417327
+ });
417328
+ const COMPACTION_MODEL_INHERIT = Symbol("compaction-model-inherit");
417329
+ function compactionModelOptions(models) {
417330
+ return [
417331
+ {
417332
+ value: COMPACTION_MODEL_INHERIT,
417333
+ label: uiText("compactionModel.followLabel"),
417334
+ description: uiText("compactionModel.followDescription")
417335
+ },
417336
+ ...Object.entries(models).sort(([left], [right]) => left.localeCompare(right)).map(([alias, model]) => ({
417337
+ value: alias,
417338
+ label: model.displayName ?? alias,
417339
+ description: uiText("compactionModel.modelDescription", { model: alias })
417340
+ }))
417341
+ ];
417342
+ }
417343
+ var CompactionModelSelectorComponent = class extends ChoicePickerComponent {
417344
+ constructor(opts) {
417345
+ super({
417346
+ title: uiText("compactionModel.title"),
417347
+ options: compactionModelOptions(opts.models),
417348
+ currentValue: opts.currentValue ?? COMPACTION_MODEL_INHERIT,
417349
+ searchable: true,
417350
+ onSelect: opts.onSelect,
417351
+ onCancel: opts.onCancel
417352
+ });
417353
+ }
417354
+ };
417355
+ //#endregion
417208
417356
  //#region src/tui/components/dialogs/settings-selector.ts
417209
417357
  function settingsOptions() {
417210
417358
  return [
@@ -417213,6 +417361,11 @@ function settingsOptions() {
417213
417361
  label: uiText("effort.title"),
417214
417362
  description: uiText("command.effort.description")
417215
417363
  },
417364
+ {
417365
+ value: "compaction-model",
417366
+ label: uiText("compactionModel.title"),
417367
+ description: uiText("command.compactionModel.description")
417368
+ },
417216
417369
  {
417217
417370
  value: "inline-suggest",
417218
417371
  label: uiText("settings.inlineSuggest.label"),
@@ -417261,7 +417414,7 @@ function settingsOptions() {
417261
417414
  ];
417262
417415
  }
417263
417416
  function isSettingsSelection(value) {
417264
- return value === "effort" || value === "action-style" || value === "personality" || value === "theme" || value === "appearance" || value === "editor" || value === "permission" || value === "experiments" || value === "usage" || value === "inline-suggest";
417417
+ 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";
417265
417418
  }
417266
417419
  var SettingsSelectorComponent = class extends ChoicePickerComponent {
417267
417420
  constructor(opts) {
@@ -420689,6 +420842,85 @@ async function handleCompactCommand(host, args) {
420689
420842
  const customInstruction = args.trim() || void 0;
420690
420843
  await session.compact({ instruction: customInstruction });
420691
420844
  }
420845
+ async function handleCompactionModelCommand(host, args) {
420846
+ if (host.session === void 0) {
420847
+ host.showError(noActiveSessionMessage());
420848
+ return;
420849
+ }
420850
+ const selection = normalizeCompactionModelSelection(args);
420851
+ if (selection === void 0) {
420852
+ await showCompactionModelPicker(host);
420853
+ return;
420854
+ }
420855
+ await applyCompactionModelChoice(host, selection);
420856
+ }
420857
+ async function applyCompactionModelChoice(host, selection) {
420858
+ const session = host.session;
420859
+ if (session === void 0) {
420860
+ host.showError(noActiveSessionMessage());
420861
+ return;
420862
+ }
420863
+ let config;
420864
+ try {
420865
+ config = await host.harness.getConfig({ reload: true });
420866
+ } catch (error) {
420867
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420868
+ return;
420869
+ }
420870
+ if (typeof selection === "string" && config.models?.[selection] === void 0) {
420871
+ host.showError(uiText("compactionModel.unknown", { model: selection }));
420872
+ return;
420873
+ }
420874
+ const nextConfig = selection === null ? clearCompactionModelConfig(config) : {
420875
+ ...config,
420876
+ loopControl: {
420877
+ ...config.loopControl,
420878
+ compactionModel: selection
420879
+ }
420880
+ };
420881
+ const nextSelection = nextConfig.loopControl?.compactionModel ?? null;
420882
+ const currentSelection = config.loopControl?.compactionModel ?? null;
420883
+ const activeModel = host.state.appState.model;
420884
+ if (currentSelection === nextSelection) {
420885
+ host.showStatus(uiText("compactionModel.unchanged", { model: nextSelection ?? activeModel }));
420886
+ return;
420887
+ }
420888
+ try {
420889
+ await host.harness.setConfig({ loopControl: { compactionModel: selection } });
420890
+ } catch (error) {
420891
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420892
+ return;
420893
+ }
420894
+ try {
420895
+ await session.reloadSession({ mcpServers: sessionMcpServers() });
420896
+ await host.reloadCurrentSessionView(session, selection === null ? uiText("compactionModel.savedActive") : uiText("compactionModel.saved", { model: selection }));
420897
+ } catch (error) {
420898
+ host.showError(uiText("compactionModel.reloadFailed", { error: formatErrorMessage$2(error) }));
420899
+ }
420900
+ }
420901
+ async function showCompactionModelPicker(host) {
420902
+ if (host.session === void 0) {
420903
+ host.showError(noActiveSessionMessage());
420904
+ return;
420905
+ }
420906
+ let config;
420907
+ try {
420908
+ config = await host.harness.getConfig({ reload: true });
420909
+ } catch (error) {
420910
+ host.showError(uiText("compactionModel.failed", { error: formatErrorMessage$2(error) }));
420911
+ return;
420912
+ }
420913
+ host.mountEditorReplacement(new CompactionModelSelectorComponent({
420914
+ models: config.models ?? {},
420915
+ currentValue: config.loopControl?.compactionModel ?? COMPACTION_MODEL_INHERIT,
420916
+ onSelect: (value) => {
420917
+ host.restoreEditorAfter(() => applyCompactionModelChoice(host, value === COMPACTION_MODEL_INHERIT ? null : value));
420918
+ },
420919
+ onCancel: () => {
420920
+ host.restoreEditor();
420921
+ }
420922
+ }));
420923
+ }
420692
420924
  async function handleEditorCommand(host, args) {
420693
420925
  const command = args.trim();
420694
420926
  if (command.length === 0) {
@@ -421351,6 +421583,9 @@ function handleSettingsSelection(host, value) {
421351
421583
  case "effort":
421352
421584
  handleEffortCommand(host, "");
421353
421585
  return;
421586
+ case "compaction-model":
421587
+ showCompactionModelPicker(host);
421588
+ return;
421354
421589
  case "action-style":
421355
421590
  showOutputStylePicker(host);
421356
421591
  return;
@@ -496287,6 +496522,9 @@ async function handleBuiltInSlashCommand(host, name, args) {
496287
496522
  case "compact":
496288
496523
  await handleCompactCommand(host, args);
496289
496524
  return;
496525
+ case "summarization-model":
496526
+ await handleCompactionModelCommand(host, args);
496527
+ return;
496290
496528
  case "goal":
496291
496529
  await handleGoalCommand(host, args);
496292
496530
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.482",
3
+ "version": "9.1.484",
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": {