micro-models-agent 0.60.1 → 0.61.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ All notable changes to Micro Models Agent (MMA) will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.61.0] - 2026-09-15
8
+
9
+ ### Added
10
+ - **Budget share controls**: `mma context --system <f>` / `--reserve <f>` and REPL `/context system <f>` / `reserve <f>` set `contextBudget.systemPrompt` / `responseReserve` (validated 0.05–0.9, system + reserve < 0.95). `mma context` and `/context` with no argument now print the budget breakdown (system / reserve / history in tokens and %). `mma config set contextBudget.systemPrompt <f>` keeps working.
11
+
12
+ ### Changed
13
+ - **Overflow fix advice**: the "system prompt exceeds budget" warning no longer only snaps to a coarse standard context size — a 32K project was jumping straight to `131072`, which looked arbitrary and was often unusable on a local model. The hint (`prompt.overflow.hint_*`, en+ru) now states the raw requirement (`needs ~N system tokens; current budget: W × f = B`) and both levers: raise `contextWindow` to the exact minimum (with the standard size) **or** keep the window and raise `contextBudget.systemPrompt` to the required share (`mma context --system <f>`).
14
+
15
+ ### Fixed
16
+ - **`mma context` ignored `MMA_CONFIG_DIR`**: it saved to a hardcoded `~/.mma/config.json`; it now writes to the config dir resolved by bootstrap.
17
+
7
18
  ## [0.60.1] - 2026-09-15
8
19
 
9
20
  ### Fixed
package/dist/i18n/en.json CHANGED
@@ -279,6 +279,14 @@
279
279
  "cli.manage_context": "Manage context window",
280
280
  "cli.invalid_context_size": "Invalid context size. Must be a number >= 1024",
281
281
  "cli.context_set": "Context window set to: {size} tokens",
282
+ "cli.context_budget_header": "Context budget (window {window} tokens):",
283
+ "cli.context_system_line": " system prompt: {tokens} tokens ({percent}%)",
284
+ "cli.context_reserve_line": " response reserve: {tokens} tokens ({percent}%)",
285
+ "cli.context_history_line": " history: {tokens} tokens ({percent}%)",
286
+ "cli.context_system_fraction": "System-prompt share of the context window (0.05–0.9)",
287
+ "cli.context_reserve_fraction": "Response-reserve share of the context window (0.05–0.9)",
288
+ "cli.context_fraction_set": "{key} share set to {value}",
289
+ "cli.context_invalid_fraction": "Invalid share. Use a number between 0.05 and 0.9 (system + reserve must stay below 0.95).",
282
290
  "repl.reload": "Reload agent with current config",
283
291
  "repl.reload_usage": "Usage: /reload",
284
292
  "repl.reloading": "Reloading agent...",
@@ -442,7 +450,7 @@
442
450
  "repl.sysprompt_desc": "Show system prompt",
443
451
  "repl.sysprompt_tokens": "System prompt ({count} tokens):",
444
452
  "repl.excluded_blocks": "\nExcluded blocks: {count}",
445
- "repl.context_usage": "Usage: /context <size> (min 1024)",
453
+ "repl.context_usage": "Usage: /context [<size> | system <fraction> | reserve <fraction>] (min 1024; fractions 0.05–0.9)",
446
454
  "repl.msgs": "msgs",
447
455
  "repl.max_iters": "Max iters:",
448
456
  "repl.stuck_thresh": "Stuck thresh:",
@@ -729,6 +737,9 @@
729
737
  "prompt.overflow.summarizing": "System prompt overflow: summarizing \"{label}\" ({original} tok → {budget} tok budget) with the model…",
730
738
  "prompt.overflow.truncating": "System prompt overflow: truncating \"{label}\" ({original} tok) — summarization unavailable.",
731
739
  "prompt.overflow.summarize_failed": "System prompt overflow: summarization failed for \"{label}\": {error} — falling back to truncation.",
740
+ "prompt.overflow.hint_needed": "the prompt needs ~{needed} system tokens (current budget: {window} × {fraction} = {budget})",
741
+ "prompt.overflow.hint_window": "raise contextWindow to at least {required} (standard size {recommended}) — {how}",
742
+ "prompt.overflow.hint_fraction": "or keep the window and raise contextBudget.systemPrompt to ~{fraction} (run: mma context --system {fraction})",
732
743
  "prompt.overflow.exceeded": "Prompt overflow: \"{label}\" ({original} tok) exceeded the system-prompt budget ({budget} tok) — {mode} to {resolved} tok. To fit fully, {hint}.",
733
744
  "prompt.overflow.failed": "Prompt overflow resolution failed: {error} — oversized blocks will be dropped.",
734
745
  "prompt.overflow.startup": "Startup check: {block} ({original} tok) exceeds the system-prompt budget ({budget} tok) — it will be summarized/truncated before the first run. To include it fully, {hint}.",
package/dist/i18n/ru.json CHANGED
@@ -277,6 +277,14 @@
277
277
  "cli.manage_context": "Управление контекстным окном",
278
278
  "cli.invalid_context_size": "Некорректный размер контекста. Должно быть число >= 1024",
279
279
  "cli.context_set": "Контекстное окно установлено: {size} токенов",
280
+ "cli.context_budget_header": "Бюджет контекста (окно {window} токенов):",
281
+ "cli.context_system_line": " системный промпт: {tokens} токенов ({percent}%)",
282
+ "cli.context_reserve_line": " резерв ответа: {tokens} токенов ({percent}%)",
283
+ "cli.context_history_line": " история: {tokens} токенов ({percent}%)",
284
+ "cli.context_system_fraction": "Доля системного промпта в контекстном окне (0.05–0.9)",
285
+ "cli.context_reserve_fraction": "Доля резерва ответа в контекстном окне (0.05–0.9)",
286
+ "cli.context_fraction_set": "Доля {key} установлена: {value}",
287
+ "cli.context_invalid_fraction": "Некорректная доля. Нужно число от 0.05 до 0.9 (системный + резерв должны оставаться ниже 0.95).",
280
288
  "cli.set_model": "Установить модель по умолчанию",
281
289
  "cli.model_set": "Модель установлена: {name}",
282
290
  "cli.certify": "Запустить сертификационный набор для модели",
@@ -436,7 +444,7 @@
436
444
  "repl.sysprompt_desc": "Показать системный промпт",
437
445
  "repl.sysprompt_tokens": "Системный промпт ({count} токенов):",
438
446
  "repl.excluded_blocks": "\nИсключённые блоки: {count}",
439
- "repl.context_usage": "Использование: /context <размер> (мин 1024)",
447
+ "repl.context_usage": "Использование: /context [<размер> | system <доля> | reserve <доля>] (мин 1024; доли 0.05–0.9)",
440
448
  "repl.msgs": "сообщ.",
441
449
  "repl.max_iters": "Макс итераций:",
442
450
  "repl.stuck_thresh": "Порог зависания:",
@@ -729,6 +737,9 @@
729
737
  "prompt.overflow.summarizing": "Переполнение системного промпта: суммаризирую \"{label}\" ({original} токенов → бюджет {budget} токенов) моделью…",
730
738
  "prompt.overflow.truncating": "Переполнение системного промпта: обрезаю \"{label}\" ({original} токенов) — суммаризация недоступна.",
731
739
  "prompt.overflow.summarize_failed": "Переполнение системного промпта: не удалось суммаризировать \"{label}\": {error} — перехожу к обрезке.",
740
+ "prompt.overflow.hint_needed": "промпту нужно ~{needed} токенов системного бюджета (сейчас: {window} × {fraction} = {budget})",
741
+ "prompt.overflow.hint_window": "подними contextWindow минимум до {required} (стандартный размер {recommended}) — {how}",
742
+ "prompt.overflow.hint_fraction": "или оставь окно и подними contextBudget.systemPrompt до ~{fraction} (выполни: mma context --system {fraction})",
732
743
  "prompt.overflow.exceeded": "Промпт переполнен: \"{label}\" ({original} токенов) превысил бюджет системного промпта ({budget} токенов) — {mode} до {resolved} токенов. Чтобы включить полностью, {hint}.",
733
744
  "prompt.overflow.failed": "Не удалось разрешить переполнение промпта: {error} — слишком большие блоки будут отброшены.",
734
745
  "prompt.overflow.startup": "Проверка при старте: {block} ({original} токенов) превышает бюджет системного промпта ({budget} токенов) — будет суммаризован/обрезан перед первым запуском. Чтобы включить полностью, {hint}.",
package/dist/main.js CHANGED
@@ -2728,6 +2728,14 @@ Fix the error and re-edit the file (a clean write clears the failure), or mark t
2728
2728
  "cli.manage_context": "Manage context window",
2729
2729
  "cli.invalid_context_size": "Invalid context size. Must be a number >= 1024",
2730
2730
  "cli.context_set": "Context window set to: {size} tokens",
2731
+ "cli.context_budget_header": "Context budget (window {window} tokens):",
2732
+ "cli.context_system_line": " system prompt: {tokens} tokens ({percent}%)",
2733
+ "cli.context_reserve_line": " response reserve: {tokens} tokens ({percent}%)",
2734
+ "cli.context_history_line": " history: {tokens} tokens ({percent}%)",
2735
+ "cli.context_system_fraction": "System-prompt share of the context window (0.05–0.9)",
2736
+ "cli.context_reserve_fraction": "Response-reserve share of the context window (0.05–0.9)",
2737
+ "cli.context_fraction_set": "{key} share set to {value}",
2738
+ "cli.context_invalid_fraction": "Invalid share. Use a number between 0.05 and 0.9 (system + reserve must stay below 0.95).",
2731
2739
  "repl.reload": "Reload agent with current config",
2732
2740
  "repl.reload_usage": "Usage: /reload",
2733
2741
  "repl.reloading": "Reloading agent...",
@@ -2893,7 +2901,7 @@ Available commands:`,
2893
2901
  "repl.sysprompt_tokens": "System prompt ({count} tokens):",
2894
2902
  "repl.excluded_blocks": `
2895
2903
  Excluded blocks: {count}`,
2896
- "repl.context_usage": "Usage: /context <size> (min 1024)",
2904
+ "repl.context_usage": "Usage: /context [<size> | system <fraction> | reserve <fraction>] (min 1024; fractions 0.05–0.9)",
2897
2905
  "repl.msgs": "msgs",
2898
2906
  "repl.max_iters": "Max iters:",
2899
2907
  "repl.stuck_thresh": "Stuck thresh:",
@@ -3206,6 +3214,9 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
3206
3214
  "prompt.overflow.summarizing": 'System prompt overflow: summarizing "{label}" ({original} tok → {budget} tok budget) with the model…',
3207
3215
  "prompt.overflow.truncating": 'System prompt overflow: truncating "{label}" ({original} tok) — summarization unavailable.',
3208
3216
  "prompt.overflow.summarize_failed": 'System prompt overflow: summarization failed for "{label}": {error} — falling back to truncation.',
3217
+ "prompt.overflow.hint_needed": "the prompt needs ~{needed} system tokens (current budget: {window} × {fraction} = {budget})",
3218
+ "prompt.overflow.hint_window": "raise contextWindow to at least {required} (standard size {recommended}) — {how}",
3219
+ "prompt.overflow.hint_fraction": "or keep the window and raise contextBudget.systemPrompt to ~{fraction} (run: mma context --system {fraction})",
3209
3220
  "prompt.overflow.exceeded": 'Prompt overflow: "{label}" ({original} tok) exceeded the system-prompt budget ({budget} tok) — {mode} to {resolved} tok. To fit fully, {hint}.',
3210
3221
  "prompt.overflow.failed": "Prompt overflow resolution failed: {error} — oversized blocks will be dropped.",
3211
3222
  "prompt.overflow.startup": "Startup check: {block} ({original} tok) exceeds the system-prompt budget ({budget} tok) — it will be summarized/truncated before the first run. To include it fully, {hint}.",
@@ -3531,6 +3542,14 @@ var init_ru = __esm(() => {
3531
3542
  "cli.manage_context": "Управление контекстным окном",
3532
3543
  "cli.invalid_context_size": "Некорректный размер контекста. Должно быть число >= 1024",
3533
3544
  "cli.context_set": "Контекстное окно установлено: {size} токенов",
3545
+ "cli.context_budget_header": "Бюджет контекста (окно {window} токенов):",
3546
+ "cli.context_system_line": " системный промпт: {tokens} токенов ({percent}%)",
3547
+ "cli.context_reserve_line": " резерв ответа: {tokens} токенов ({percent}%)",
3548
+ "cli.context_history_line": " история: {tokens} токенов ({percent}%)",
3549
+ "cli.context_system_fraction": "Доля системного промпта в контекстном окне (0.05–0.9)",
3550
+ "cli.context_reserve_fraction": "Доля резерва ответа в контекстном окне (0.05–0.9)",
3551
+ "cli.context_fraction_set": "Доля {key} установлена: {value}",
3552
+ "cli.context_invalid_fraction": "Некорректная доля. Нужно число от 0.05 до 0.9 (системный + резерв должны оставаться ниже 0.95).",
3534
3553
  "cli.set_model": "Установить модель по умолчанию",
3535
3554
  "cli.model_set": "Модель установлена: {name}",
3536
3555
  "cli.certify": "Запустить сертификационный набор для модели",
@@ -3692,7 +3711,7 @@ var init_ru = __esm(() => {
3692
3711
  "repl.sysprompt_tokens": "Системный промпт ({count} токенов):",
3693
3712
  "repl.excluded_blocks": `
3694
3713
  Исключённые блоки: {count}`,
3695
- "repl.context_usage": "Использование: /context <размер> (мин 1024)",
3714
+ "repl.context_usage": "Использование: /context [<размер> | system <доля> | reserve <доля>] (мин 1024; доли 0.05–0.9)",
3696
3715
  "repl.msgs": "сообщ.",
3697
3716
  "repl.max_iters": "Макс итераций:",
3698
3717
  "repl.stuck_thresh": "Порог зависания:",
@@ -4012,6 +4031,9 @@ var init_ru = __esm(() => {
4012
4031
  "prompt.overflow.summarizing": 'Переполнение системного промпта: суммаризирую "{label}" ({original} токенов → бюджет {budget} токенов) моделью…',
4013
4032
  "prompt.overflow.truncating": 'Переполнение системного промпта: обрезаю "{label}" ({original} токенов) — суммаризация недоступна.',
4014
4033
  "prompt.overflow.summarize_failed": 'Переполнение системного промпта: не удалось суммаризировать "{label}": {error} — перехожу к обрезке.',
4034
+ "prompt.overflow.hint_needed": "промпту нужно ~{needed} токенов системного бюджета (сейчас: {window} × {fraction} = {budget})",
4035
+ "prompt.overflow.hint_window": "подними contextWindow минимум до {required} (стандартный размер {recommended}) — {how}",
4036
+ "prompt.overflow.hint_fraction": "или оставь окно и подними contextBudget.systemPrompt до ~{fraction} (выполни: mma context --system {fraction})",
4015
4037
  "prompt.overflow.exceeded": 'Промпт переполнен: "{label}" ({original} токенов) превысил бюджет системного промпта ({budget} токенов) — {mode} до {resolved} токенов. Чтобы включить полностью, {hint}.',
4016
4038
  "prompt.overflow.failed": "Не удалось разрешить переполнение промпта: {error} — слишком большие блоки будут отброшены.",
4017
4039
  "prompt.overflow.startup": "Проверка при старте: {block} ({original} токенов) превышает бюджет системного промпта ({budget} токенов) — будет суммаризован/обрезан перед первым запуском. Чтобы включить полностью, {hint}.",
@@ -14784,6 +14806,33 @@ function recommendContextSize(neededSystemTokens) {
14784
14806
  const sizes = [8192, 16384, 32768, 65536, 131072, 262144];
14785
14807
  return sizes.find((s) => Math.floor(s * 0.1) >= neededSystemTokens) ?? sizes[sizes.length - 1];
14786
14808
  }
14809
+ function requiredContextWindow(neededTokens, systemFraction) {
14810
+ const fraction = systemFraction > 0 ? systemFraction : 0.1;
14811
+ return Math.ceil(neededTokens / fraction);
14812
+ }
14813
+ function requiredSystemFraction(neededTokens, contextWindow) {
14814
+ if (contextWindow <= 0)
14815
+ return 1;
14816
+ return Math.min(1, Math.ceil(neededTokens / contextWindow * 100) / 100);
14817
+ }
14818
+ function overflowHint(config, configDir, neededTokens) {
14819
+ const fraction = config.contextBudget?.systemPrompt ?? 0.1;
14820
+ const budget = Math.floor(config.contextWindow * fraction);
14821
+ const recommended = recommendContextSize(neededTokens);
14822
+ const requiredWindow = requiredContextWindow(neededTokens, fraction);
14823
+ const requiredFraction = requiredSystemFraction(neededTokens, config.contextWindow);
14824
+ const how = configDir ? contextWindowHint(config, configDir, recommended) : `increase contextWindow (e.g. to ${recommended})`;
14825
+ return [
14826
+ t("prompt.overflow.hint_needed", {
14827
+ needed: neededTokens,
14828
+ window: config.contextWindow,
14829
+ fraction,
14830
+ budget
14831
+ }),
14832
+ t("prompt.overflow.hint_window", { required: requiredWindow, recommended, how }),
14833
+ t("prompt.overflow.hint_fraction", { fraction: requiredFraction })
14834
+ ].join(" ");
14835
+ }
14787
14836
  var HINT_BLOCK_TOKENS = 60, CHARS_PER_TOKEN = 4, KIND_ORDER, KIND_LABEL, KIND_SOURCE_FILE;
14788
14837
  var init_prompt_overflow = __esm(() => {
14789
14838
  init_prompt_builder();
@@ -14964,8 +15013,8 @@ class Agent {
14964
15013
  this.promptOverrides.set(r.kind, r);
14965
15014
  }
14966
15015
  this.overflowHintBlock = res.hintBlock;
14967
- const recommended = recommendContextSize(dry.blocks.filter((b) => b.included).reduce((s, b) => s + b.tokens, 0) + overflow.reduce((s, b) => s + b.estimatedTokens, 0) + HINT_BLOCK_TOKENS);
14968
- const hint = this.deps.configDir ? contextWindowHint(cfg, this.deps.configDir, recommended) : `increase contextWindow (e.g. to ${recommended})`;
15016
+ const needed = dry.blocks.filter((b) => b.included).reduce((s, b) => s + b.tokens, 0) + overflow.reduce((s, b) => s + b.estimatedTokens, 0) + HINT_BLOCK_TOKENS;
15017
+ const hint = overflowHint(cfg, this.deps.configDir, needed);
14969
15018
  for (const w of res.warnings) {
14970
15019
  this.deps.logger.warn(t("prompt.overflow.exceeded", {
14971
15020
  label: w.label,
@@ -26836,8 +26885,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26836
26885
  const dry = dryRunOverflow([...promptBlocks, ...dynamicBlocks], systemBudget);
26837
26886
  if (dry.overflow.length > 0) {
26838
26887
  const overflowTokens = dry.overflow.reduce((s, b) => s + b.estimatedTokens, 0);
26839
- const recommended = recommendContextSize(dry.includedTokens + overflowTokens);
26840
- const hint = contextWindowHint(config, dir, recommended);
26888
+ const hint = overflowHint(config, dir, dry.includedTokens + overflowTokens);
26841
26889
  for (const b of dry.overflow) {
26842
26890
  logger4.warn(t("prompt.overflow.startup", {
26843
26891
  block: b.kind === "instructions" ? "AGENTS.md" : "project map",
@@ -27742,6 +27790,49 @@ var init_map_command = __esm(() => {
27742
27790
  init_i18n();
27743
27791
  });
27744
27792
 
27793
+ // src/config/budget.ts
27794
+ function budgetBreakdown(config) {
27795
+ const window = config.contextWindow;
27796
+ const budget = config.contextBudget;
27797
+ const system = Math.floor(window * budget.systemPrompt);
27798
+ const reserve = Math.floor(window * budget.responseReserve);
27799
+ const history = window - system - reserve;
27800
+ return {
27801
+ window,
27802
+ system,
27803
+ reserve,
27804
+ history,
27805
+ systemFraction: budget.systemPrompt,
27806
+ reserveFraction: budget.responseReserve,
27807
+ historyFraction: window > 0 ? history / window : 0
27808
+ };
27809
+ }
27810
+ function setBudgetShare(config, key, value) {
27811
+ if (!Number.isFinite(value) || value < MIN_SHARE || value > MAX_SHARE)
27812
+ return "range";
27813
+ const budget = config.contextBudget;
27814
+ const nextSystem = key === "system" ? value : budget.systemPrompt;
27815
+ const nextReserve = key === "reserve" ? value : budget.responseReserve;
27816
+ if (nextSystem + nextReserve > MAX_COMBINED)
27817
+ return "combined";
27818
+ budget[key === "system" ? "systemPrompt" : "responseReserve"] = value;
27819
+ return null;
27820
+ }
27821
+ function budgetBreakdownLines(config) {
27822
+ const bd = budgetBreakdown(config);
27823
+ const pct = (f) => Math.round(f * 100);
27824
+ return [
27825
+ t("cli.context_budget_header", { window: bd.window }),
27826
+ t("cli.context_system_line", { tokens: bd.system, percent: pct(bd.systemFraction) }),
27827
+ t("cli.context_reserve_line", { tokens: bd.reserve, percent: pct(bd.reserveFraction) }),
27828
+ t("cli.context_history_line", { tokens: bd.history, percent: pct(bd.historyFraction) })
27829
+ ];
27830
+ }
27831
+ var MIN_SHARE = 0.05, MAX_SHARE = 0.9, MAX_COMBINED = 0.95;
27832
+ var init_budget = __esm(() => {
27833
+ init_i18n();
27834
+ });
27835
+
27745
27836
  // node_modules/yaml/dist/nodes/identity.js
27746
27837
  var require_identity = __commonJS((exports) => {
27747
27838
  var ALIAS = Symbol.for("yaml.alias");
@@ -36293,11 +36384,28 @@ function registerProviderCommands(ctx) {
36293
36384
  ctx.registerCommand({
36294
36385
  name: "context",
36295
36386
  description: t("cli.manage_context"),
36296
- usage: "/context <size>",
36387
+ usage: t("repl.context_usage"),
36297
36388
  action: async (args) => {
36389
+ const save = async () => {
36390
+ const configPath = join54(ctx.configDir, "config.json");
36391
+ saveConfig(ctx.config, configPath, dirname24(configPath));
36392
+ await ctx.agent.reconfigure(ctx.config);
36393
+ };
36298
36394
  if (args.length === 0) {
36299
- console.log(`/context ${t("repl.context")} ${ctx.config.contextWindow}`);
36300
- console.log(t("repl.context_usage"));
36395
+ for (const line of budgetBreakdownLines(ctx.config))
36396
+ console.log(line);
36397
+ console.log(pc2.dim(t("repl.context_usage")));
36398
+ return;
36399
+ }
36400
+ if (args[0] === "system" || args[0] === "reserve") {
36401
+ const key = args[0];
36402
+ const value = Number(args[1]);
36403
+ if (setBudgetShare(ctx.config, key, value) !== null) {
36404
+ console.log(pc2.yellow(t("cli.context_invalid_fraction")));
36405
+ return;
36406
+ }
36407
+ await save();
36408
+ console.log(pc2.green(t("cli.context_fraction_set", { key, value })));
36301
36409
  return;
36302
36410
  }
36303
36411
  const size = parseInt(args[0], 10);
@@ -36306,9 +36414,7 @@ function registerProviderCommands(ctx) {
36306
36414
  return;
36307
36415
  }
36308
36416
  ctx.config.contextWindow = size;
36309
- const configPath = join54(ctx.configDir, "config.json");
36310
- saveConfig(ctx.config, configPath, dirname24(configPath));
36311
- await ctx.agent.reconfigure(ctx.config);
36417
+ await save();
36312
36418
  console.log(pc2.green(t("cli.context_set", { size })));
36313
36419
  }
36314
36420
  });
@@ -36695,6 +36801,7 @@ var init_repl_commands = __esm(() => {
36695
36801
  init_i18n();
36696
36802
  init_setup();
36697
36803
  init_config2();
36804
+ init_budget();
36698
36805
  init_token_counter();
36699
36806
  init_map_command();
36700
36807
  init_utils();
@@ -37426,6 +37533,7 @@ function targetsFromProviders(entries) {
37426
37533
  // src/cli/commands.ts
37427
37534
  init_version();
37428
37535
  init_map_command();
37536
+ init_budget();
37429
37537
 
37430
37538
  // src/modules/updater/changelog-reader.ts
37431
37539
  import { readFileSync as readFileSync35, existsSync as existsSync53 } from "fs";
@@ -37686,9 +37794,25 @@ function buildModelCommands(program2) {
37686
37794
  });
37687
37795
  }
37688
37796
  function buildContextCommand(program2) {
37689
- program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
37690
- const configPath = join53(homedir17(), ".mma", "config.json");
37691
- const { config } = await bootstrap();
37797
+ program2.command("context").description(t("cli.manage_context")).argument("[size]", "Context window size in tokens (omit to show the budget breakdown)").option("--system <fraction>", t("cli.context_system_fraction")).option("--reserve <fraction>", t("cli.context_reserve_fraction")).action(async (size, opts) => {
37798
+ const { config, configDir } = await bootstrap();
37799
+ const configPath = join53(configDir, "config.json");
37800
+ if (opts.system !== undefined || opts.reserve !== undefined) {
37801
+ const key = opts.system !== undefined ? "system" : "reserve";
37802
+ const value = Number(opts.system ?? opts.reserve);
37803
+ if (setBudgetShare(config, key, value) !== null) {
37804
+ console.log(t("cli.context_invalid_fraction"));
37805
+ return;
37806
+ }
37807
+ saveConfig(config, configPath, dirname23(configPath));
37808
+ console.log(t("cli.context_fraction_set", { key, value }));
37809
+ return;
37810
+ }
37811
+ if (size === undefined) {
37812
+ for (const line of budgetBreakdownLines(config))
37813
+ console.log(line);
37814
+ return;
37815
+ }
37692
37816
  const contextWindow = parseInt(size, 10);
37693
37817
  if (isNaN(contextWindow) || contextWindow < 1024) {
37694
37818
  console.log(t("cli.invalid_context_size"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.60.1",
3
+ "version": "0.61.0",
4
4
  "description": "Micro Models Agent (MMA) — LLM agent harness for small models (Qwen3.5-9B, 32K-64K context)",
5
5
  "type": "module",
6
6
  "bin": {