@dimi-agent/cli 0.5.5 → 0.6.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.
Files changed (2) hide show
  1. package/dist/main.mjs +270 -94
  2. package/package.json +4 -4
package/dist/main.mjs CHANGED
@@ -121085,6 +121085,56 @@ var init_toolPolicyService = __esmMin((() => {
121085
121085
  registerScopedService(2, IAgentToolPolicyService, AgentToolPolicyService, 0, "toolPolicy");
121086
121086
  }));
121087
121087
  //#endregion
121088
+ //#region ../../packages/agent-core-v2/src/agent/loop/contextSize.ts
121089
+ /**
121090
+ * Scale a token count by `percent` of the model's default window, keeping
121091
+ * at least `CONTEXT_SIZE_FLOOR_TOKENS` — but never more than the original
121092
+ * window, so models already below the floor (and `percent` at or above
121093
+ * 100, or unset) pass through unchanged.
121094
+ */
121095
+ function scaleContextTokens(tokens, percent) {
121096
+ if (!Number.isFinite(tokens) || tokens <= 0) return tokens;
121097
+ if (percent === void 0 || percent <= 0 || percent >= 100) return tokens;
121098
+ const scaled = Math.floor(tokens * percent / 100);
121099
+ return Math.max(scaled, Math.min(tokens, CONTEXT_SIZE_FLOOR_TOKENS));
121100
+ }
121101
+ /**
121102
+ * Apply the configured context-size percentage to a model capability.
121103
+ * Returns the original object unchanged when nothing changes, so
121104
+ * `UNKNOWN_CAPABILITY` identity and other callers relying on object
121105
+ * equality keep working.
121106
+ */
121107
+ function scaleModelCapabilityContext(capability, percent) {
121108
+ if (percent === void 0 || percent <= 0 || percent >= 100) return capability;
121109
+ const maxContextTokens = scaleContextTokens(capability.max_context_tokens, percent);
121110
+ const maxInputTokens = capability.max_input_tokens === void 0 ? void 0 : scaleContextTokens(capability.max_input_tokens, percent);
121111
+ if (maxContextTokens === capability.max_context_tokens && maxInputTokens === capability.max_input_tokens) return capability;
121112
+ return {
121113
+ ...capability,
121114
+ max_context_tokens: maxContextTokens,
121115
+ max_input_tokens: maxInputTokens
121116
+ };
121117
+ }
121118
+ /**
121119
+ * Offered percentage levels for a model window: `100`, `95`, … descending
121120
+ * in `CONTEXT_SIZE_STEP_PERCENT` steps while the scaled size stays at or
121121
+ * above `CONTEXT_SIZE_FLOOR_TOKENS`. Empty when the window is below the
121122
+ * floor — the model's context size is not adjustable.
121123
+ */
121124
+ function contextSizePercentOptions(contextWindow) {
121125
+ if (!Number.isFinite(contextWindow) || contextWindow <= 0) return [];
121126
+ const options = [];
121127
+ for (let percent = 100; percent >= 5; percent -= 5) {
121128
+ if (Math.floor(contextWindow * percent / 100) < 2e5) break;
121129
+ options.push(percent);
121130
+ }
121131
+ return options;
121132
+ }
121133
+ var CONTEXT_SIZE_FLOOR_TOKENS;
121134
+ var init_contextSize$1 = __esmMin((() => {
121135
+ CONTEXT_SIZE_FLOOR_TOKENS = 2e5;
121136
+ }));
121137
+ //#endregion
121088
121138
  //#region ../../packages/agent-core-v2/src/agent/loop/configSection.ts
121089
121139
  function parseNonNegativeInt(raw) {
121090
121140
  const value = raw.trim();
@@ -121098,6 +121148,7 @@ var init_configSection$5 = __esmMin((() => {
121098
121148
  init_config$5();
121099
121149
  init_configSectionContributions();
121100
121150
  init_toml();
121151
+ init_contextSize$1();
121101
121152
  LOOP_CONTROL_SECTION = "loopControl";
121102
121153
  LOOP_MAX_STEPS_PER_TURN_ENV = "DIMI_LOOP_MAX_STEPS_PER_TURN";
121103
121154
  LOOP_MAX_RETRIES_PER_STEP_ENV = "DIMI_LOOP_MAX_RETRIES_PER_STEP";
@@ -121106,7 +121157,13 @@ var init_configSection$5 = __esmMin((() => {
121106
121157
  maxRetriesPerStep: number$2().int().min(0).optional(),
121107
121158
  maxRalphIterations: number$2().int().min(-1).optional(),
121108
121159
  reservedContextSize: number$2().int().min(0).optional(),
121109
- compactionTriggerRatio: number$2().min(.5).max(.99).optional()
121160
+ compactionTriggerRatio: number$2().min(.5).max(.99).optional(),
121161
+ /**
121162
+ * Effective context window as a percentage of the model's default, in
121163
+ * 5% steps, never below `CONTEXT_SIZE_FLOOR_TOKENS`. See
121164
+ * `agent/loop/contextSize.ts` for the scaling semantics.
121165
+ */
121166
+ contextSizePercent: number$2().int().min(5).max(100).multipleOf(5).optional()
121110
121167
  });
121111
121168
  loopControlEnvBindings = envBindings(LoopControlSchema, {
121112
121169
  maxStepsPerTurn: {
@@ -211855,6 +211912,8 @@ var init_profileService = __esmMin((() => {
211855
211912
  init_errors$11();
211856
211913
  init_bootstrap();
211857
211914
  init_config$5();
211915
+ init_configSection$5();
211916
+ init_contextSize$1();
211858
211917
  init_hostEnvironment();
211859
211918
  init_hostFileSystem();
211860
211919
  init_sessionContext();
@@ -211942,6 +212001,7 @@ var init_profileService = __esmMin((() => {
211942
212001
  this.publishToolPatternWarnings();
211943
212002
  this.refreshSystemPrompt();
211944
212003
  }
212004
+ if (domain === "loopControl") this.emitStatusUpdated();
211945
212005
  }));
211946
212006
  this._register(this.skillCatalog.onDidChange((sourceId) => {
211947
212007
  if (sourceId === "plugin") this.refreshSystemPrompt();
@@ -212139,7 +212199,7 @@ var init_profileService = __esmMin((() => {
212139
212199
  return {
212140
212200
  cwd: this.cwd,
212141
212201
  modelAlias: this.modelAlias,
212142
- modelCapabilities: model === void 0 ? UNKNOWN_CAPABILITY : modelCapabilities(model),
212202
+ modelCapabilities: this.capabilitiesFor(model),
212143
212203
  profileName: this.profileName,
212144
212204
  thinkingLevel: this.thinkingLevel,
212145
212205
  systemPrompt: this.systemPrompt,
@@ -212154,10 +212214,10 @@ var init_profileService = __esmMin((() => {
212154
212214
  resolveModelContext() {
212155
212215
  const modelAlias = this.model;
212156
212216
  const model = this.modelCatalog.get(modelAlias);
212157
- const loopControl = this.config.get("loopControl");
212217
+ const loopControl = this.config.get(LOOP_CONTROL_SECTION);
212158
212218
  return {
212159
212219
  modelAlias,
212160
- modelCapabilities: modelCapabilities(model),
212220
+ modelCapabilities: this.capabilitiesFor(model),
212161
212221
  maxOutputSize: model.maxTokens,
212162
212222
  alwaysThinking: modelAlwaysThinking(model) || void 0,
212163
212223
  thinkingLevel: this.resolveThinkingState(model).effective,
@@ -212182,8 +212242,15 @@ var init_profileService = __esmMin((() => {
212182
212242
  };
212183
212243
  }
212184
212244
  getModelCapabilities() {
212185
- const model = this.tryResolveRawModel();
212186
- return model === void 0 ? UNKNOWN_CAPABILITY : modelCapabilities(model);
212245
+ return this.capabilitiesFor(this.tryResolveRawModel());
212246
+ }
212247
+ /**
212248
+ * Model capabilities with the user's `[loop_control] context_size_percent`
212249
+ * applied to the token limits. The percentage is read on every call, so
212250
+ * config changes take effect on the next request without a restart.
212251
+ */
212252
+ capabilitiesFor(model) {
212253
+ return scaleModelCapabilityContext(model === void 0 ? UNKNOWN_CAPABILITY : modelCapabilities(model), this.config.get(LOOP_CONTROL_SECTION)?.contextSizePercent);
212187
212254
  }
212188
212255
  getMaxOutputSize() {
212189
212256
  return this.tryResolveRawModel()?.maxTokens;
@@ -217678,6 +217745,7 @@ var init_src$6 = __esmMin((() => {
217678
217745
  init_retry();
217679
217746
  init_configSection$5();
217680
217747
  init_configSection$5();
217748
+ init_contextSize$1();
217681
217749
  init_loop();
217682
217750
  init_loopService();
217683
217751
  init_loopContinuation();
@@ -309726,6 +309794,134 @@ var init_busy_input_mode_selector = __esmMin((() => {
309726
309794
  };
309727
309795
  }));
309728
309796
  //#endregion
309797
+ //#region src/utils/usage/usage-format.ts
309798
+ function usageNumber$1(value) {
309799
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
309800
+ }
309801
+ /**
309802
+ * Total prompt tokens for a single generation: non-cache input + cache
309803
+ * read + cache write/creation. Matches the denominator pi uses for CH%.
309804
+ */
309805
+ function promptTokenTotal(usage) {
309806
+ if (usage === null || usage === void 0) return 0;
309807
+ return usageNumber$1(usage.inputOther) + usageNumber$1(usage.inputCacheRead) + usageNumber$1(usage.inputCacheCreation);
309808
+ }
309809
+ /**
309810
+ * Latest-step prompt-cache hit rate as a percentage in [0, 100].
309811
+ * Returns `undefined` when there is no prompt traffic, or when the
309812
+ * provider reported neither cache reads nor cache writes (no cache
309813
+ * signal — same gate as pi's footer `CH` badge).
309814
+ */
309815
+ function cacheHitRatePercent(usage) {
309816
+ if (usage === null || usage === void 0) return void 0;
309817
+ const cacheRead = usageNumber$1(usage.inputCacheRead);
309818
+ const cacheWrite = usageNumber$1(usage.inputCacheCreation);
309819
+ if (cacheRead === 0 && cacheWrite === 0) return void 0;
309820
+ const prompt = promptTokenTotal(usage);
309821
+ if (prompt <= 0) return void 0;
309822
+ return Math.min(100, Math.max(0, cacheRead / prompt * 100));
309823
+ }
309824
+ /** Compact footer/report label, e.g. `CH85.0%`. */
309825
+ function formatCacheHitRate(rate) {
309826
+ if (!Number.isFinite(rate)) return "CH?%";
309827
+ return `CH${rate.toFixed(1)}%`;
309828
+ }
309829
+ /**
309830
+ * Format a token count in 1024-based units: context sizes are powers of
309831
+ * two, so 262144 reads as "256k", not "262.1k". k values at or above
309832
+ * 100 are rounded to whole numbers ("977k").
309833
+ */
309834
+ function formatTokenCount(n) {
309835
+ if (!Number.isFinite(n) || n < 0) return "0";
309836
+ if (n >= 1024 * 1024) return `${trimDecimal(n / (1024 * 1024))}M`;
309837
+ if (n >= 1024) {
309838
+ const k = n / 1024;
309839
+ return `${k >= 100 ? Math.round(k) : trimDecimal(k)}k`;
309840
+ }
309841
+ return String(n);
309842
+ }
309843
+ /** One decimal place, dropping a redundant ".0" ("1.0" → "1", "1.5" stays). */
309844
+ function trimDecimal(v) {
309845
+ const s = v.toFixed(1);
309846
+ return s.endsWith(".0") ? s.slice(0, -2) : s;
309847
+ }
309848
+ /**
309849
+ * Format a token count in 1000-based units ("1M", "950k", "200k"). Unlike
309850
+ * `formatTokenCount` (1024-based, the footer/usage convention), this keeps
309851
+ * exact product numbers readable: the context-size picker's floor is a
309852
+ * literal 200k, and 5% steps of a 1M window land on round values.
309853
+ */
309854
+ function formatDecimalTokenCount(n) {
309855
+ if (!Number.isFinite(n) || n < 0) return "0";
309856
+ if (n >= 1e6) return `${trimDecimal(n / 1e6)}M`;
309857
+ if (n >= 1e3) return `${trimDecimal(n / 1e3)}k`;
309858
+ return String(n);
309859
+ }
309860
+ /**
309861
+ * Usage as a whole-number percentage of `max`, ceiled so any non-zero
309862
+ * usage shows at least 1%, clamped to [0, 100]. A non-positive or
309863
+ * non-finite `max` reports 0.
309864
+ */
309865
+ function usagePercent(used, max) {
309866
+ if (!Number.isFinite(max) || max <= 0) return 0;
309867
+ return Math.min(100, Math.max(0, Math.ceil(used / max * 100)));
309868
+ }
309869
+ /** `usagePercent` for callers that only know the ratio (NaN-safe). */
309870
+ function usagePercentFromRatio(ratio) {
309871
+ return Math.min(100, Math.max(0, Math.ceil(safeUsageRatio(ratio) * 100)));
309872
+ }
309873
+ /**
309874
+ * Build a `[███░░░░░░░]` style bar. Returns a plain-ASCII string with
309875
+ * `filled`/`empty` glyphs — colouring is the caller's responsibility.
309876
+ */
309877
+ function renderProgressBar(ratio, width = 20, filled = "█", empty = "░") {
309878
+ const clamped = safeUsageRatio(ratio);
309879
+ const filledCount = Math.round(clamped * width);
309880
+ return filled.repeat(filledCount) + empty.repeat(Math.max(0, width - filledCount));
309881
+ }
309882
+ function safeUsageRatio(ratio) {
309883
+ return Number.isFinite(ratio) ? Math.max(0, Math.min(ratio, 1)) : 0;
309884
+ }
309885
+ /**
309886
+ * Map a usage ratio to a semantic colour token — the `/usage` renderer
309887
+ * translates these into palette hex values.
309888
+ */
309889
+ function ratioSeverity(ratio) {
309890
+ if (ratio >= .85) return "danger";
309891
+ if (ratio >= .5) return "warn";
309892
+ return "ok";
309893
+ }
309894
+ var init_usage_format = __esmMin((() => {}));
309895
+ //#endregion
309896
+ //#region src/tui/components/dialogs/context-size-selector.ts
309897
+ function buildOptions(contextWindow, percentOptions) {
309898
+ return percentOptions.map((percent) => ({
309899
+ value: String(percent),
309900
+ label: percent === 100 ? "100% (default)" : `${percent}%`,
309901
+ description: `${formatDecimalTokenCount(Math.floor(contextWindow * percent / 100))} tokens`
309902
+ }));
309903
+ }
309904
+ var ContextSizeSelectorComponent;
309905
+ var init_context_size_selector = __esmMin((() => {
309906
+ init_src$6();
309907
+ init_usage_format();
309908
+ init_choice_picker();
309909
+ ContextSizeSelectorComponent = class extends ChoicePickerComponent {
309910
+ constructor(opts) {
309911
+ super({
309912
+ title: "Context size",
309913
+ hint: `Model window ${formatDecimalTokenCount(opts.contextWindow)} · floor ${formatDecimalTokenCount(CONTEXT_SIZE_FLOOR_TOKENS)}`,
309914
+ options: buildOptions(opts.contextWindow, opts.percentOptions),
309915
+ currentValue: String(opts.currentPercent),
309916
+ onSelect: (value) => {
309917
+ opts.onSelect(Number(value));
309918
+ },
309919
+ onCancel: opts.onCancel
309920
+ });
309921
+ }
309922
+ };
309923
+ }));
309924
+ //#endregion
309729
309925
  //#region src/tui/components/dialogs/editor-selector.ts
309730
309926
  var EDITOR_OPTIONS, EditorSelectorComponent;
309731
309927
  var init_editor_selector = __esmMin((() => {
@@ -310186,7 +310382,7 @@ var init_permission_selector = __esmMin((() => {
310186
310382
  //#endregion
310187
310383
  //#region src/tui/components/dialogs/settings-selector.ts
310188
310384
  function isSettingsSelection(value) {
310189
- return value === "model" || value === "theme" || value === "editor" || value === "permission" || value === "busy-input" || value === "experiments" || value === "upgrade" || value === "usage";
310385
+ return value === "model" || value === "theme" || value === "editor" || value === "permission" || value === "busy-input" || value === "context-size" || value === "experiments" || value === "upgrade" || value === "usage";
310190
310386
  }
310191
310387
  var SETTINGS_OPTIONS, SettingsSelectorComponent;
310192
310388
  var init_settings_selector = __esmMin((() => {
@@ -310217,6 +310413,11 @@ var init_settings_selector = __esmMin((() => {
310217
310413
  label: "Busy input",
310218
310414
  description: "Choose whether Enter queues or steers while the agent is working."
310219
310415
  },
310416
+ {
310417
+ value: "context-size",
310418
+ label: "Context size",
310419
+ description: "Cap the conversation window as a percentage of the model default (min 200k)."
310420
+ },
310220
310421
  {
310221
310422
  value: "experiments",
310222
310423
  label: "Experiments",
@@ -310462,93 +310663,6 @@ var init_mcp_status_panel = __esmMin((() => {
310462
310663
  ];
310463
310664
  }));
310464
310665
  //#endregion
310465
- //#region src/utils/usage/usage-format.ts
310466
- function usageNumber$1(value) {
310467
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
310468
- }
310469
- /**
310470
- * Total prompt tokens for a single generation: non-cache input + cache
310471
- * read + cache write/creation. Matches the denominator pi uses for CH%.
310472
- */
310473
- function promptTokenTotal(usage) {
310474
- if (usage === null || usage === void 0) return 0;
310475
- return usageNumber$1(usage.inputOther) + usageNumber$1(usage.inputCacheRead) + usageNumber$1(usage.inputCacheCreation);
310476
- }
310477
- /**
310478
- * Latest-step prompt-cache hit rate as a percentage in [0, 100].
310479
- * Returns `undefined` when there is no prompt traffic, or when the
310480
- * provider reported neither cache reads nor cache writes (no cache
310481
- * signal — same gate as pi's footer `CH` badge).
310482
- */
310483
- function cacheHitRatePercent(usage) {
310484
- if (usage === null || usage === void 0) return void 0;
310485
- const cacheRead = usageNumber$1(usage.inputCacheRead);
310486
- const cacheWrite = usageNumber$1(usage.inputCacheCreation);
310487
- if (cacheRead === 0 && cacheWrite === 0) return void 0;
310488
- const prompt = promptTokenTotal(usage);
310489
- if (prompt <= 0) return void 0;
310490
- return Math.min(100, Math.max(0, cacheRead / prompt * 100));
310491
- }
310492
- /** Compact footer/report label, e.g. `CH85.0%`. */
310493
- function formatCacheHitRate(rate) {
310494
- if (!Number.isFinite(rate)) return "CH?%";
310495
- return `CH${rate.toFixed(1)}%`;
310496
- }
310497
- /**
310498
- * Format a token count in 1024-based units: context sizes are powers of
310499
- * two, so 262144 reads as "256k", not "262.1k". k values at or above
310500
- * 100 are rounded to whole numbers ("977k").
310501
- */
310502
- function formatTokenCount(n) {
310503
- if (!Number.isFinite(n) || n < 0) return "0";
310504
- if (n >= 1024 * 1024) return `${trimDecimal(n / (1024 * 1024))}M`;
310505
- if (n >= 1024) {
310506
- const k = n / 1024;
310507
- return `${k >= 100 ? Math.round(k) : trimDecimal(k)}k`;
310508
- }
310509
- return String(n);
310510
- }
310511
- /** One decimal place, dropping a redundant ".0" ("1.0" → "1", "1.5" stays). */
310512
- function trimDecimal(v) {
310513
- const s = v.toFixed(1);
310514
- return s.endsWith(".0") ? s.slice(0, -2) : s;
310515
- }
310516
- /**
310517
- * Usage as a whole-number percentage of `max`, ceiled so any non-zero
310518
- * usage shows at least 1%, clamped to [0, 100]. A non-positive or
310519
- * non-finite `max` reports 0.
310520
- */
310521
- function usagePercent(used, max) {
310522
- if (!Number.isFinite(max) || max <= 0) return 0;
310523
- return Math.min(100, Math.max(0, Math.ceil(used / max * 100)));
310524
- }
310525
- /** `usagePercent` for callers that only know the ratio (NaN-safe). */
310526
- function usagePercentFromRatio(ratio) {
310527
- return Math.min(100, Math.max(0, Math.ceil(safeUsageRatio(ratio) * 100)));
310528
- }
310529
- /**
310530
- * Build a `[███░░░░░░░]` style bar. Returns a plain-ASCII string with
310531
- * `filled`/`empty` glyphs — colouring is the caller's responsibility.
310532
- */
310533
- function renderProgressBar(ratio, width = 20, filled = "█", empty = "░") {
310534
- const clamped = safeUsageRatio(ratio);
310535
- const filledCount = Math.round(clamped * width);
310536
- return filled.repeat(filledCount) + empty.repeat(Math.max(0, width - filledCount));
310537
- }
310538
- function safeUsageRatio(ratio) {
310539
- return Number.isFinite(ratio) ? Math.max(0, Math.min(ratio, 1)) : 0;
310540
- }
310541
- /**
310542
- * Map a usage ratio to a semantic colour token — the `/usage` renderer
310543
- * translates these into palette hex values.
310544
- */
310545
- function ratioSeverity(ratio) {
310546
- if (ratio >= .85) return "danger";
310547
- if (ratio >= .5) return "warn";
310548
- return "ok";
310549
- }
310550
- var init_usage_format = __esmMin((() => {}));
310551
- //#endregion
310552
310666
  //#region src/tui/components/messages/usage-panel.ts
310553
310667
  function usageRowLabel(row) {
310554
310668
  const window = row.window;
@@ -312313,6 +312427,62 @@ function showBusyInputModePicker(host) {
312313
312427
  }
312314
312428
  }));
312315
312429
  }
312430
+ /** `[loop_control]` from a `getConfig()` result (untyped domain access). */
312431
+ function loopControlFromConfig(config) {
312432
+ return config["loopControl"];
312433
+ }
312434
+ /** The active model's default context window in tokens, or 0 when unknown. */
312435
+ function activeModelContextWindow(host) {
312436
+ const alias = host.state.appState.model;
312437
+ return (alias === void 0 ? void 0 : host.state.appState.availableModels[alias])?.maxContextSize ?? 0;
312438
+ }
312439
+ /**
312440
+ * Open the context-size picker: 5% steps from the model's default window
312441
+ * (100%) down while the scaled window stays at or above 200k. Models whose
312442
+ * window is already below 200k are not adjustable — a notice explains why
312443
+ * instead of opening a one-option picker.
312444
+ */
312445
+ function showContextSizePicker(host) {
312446
+ const contextWindow = activeModelContextWindow(host);
312447
+ if (contextWindow <= 0) {
312448
+ host.showNotice("Context size unavailable", "No model is active. Choose a model first.");
312449
+ return;
312450
+ }
312451
+ const percentOptions = contextSizePercentOptions(contextWindow);
312452
+ if (percentOptions.length <= 1) {
312453
+ host.showNotice("Context size cannot be adjusted", `This model's window (${formatDecimalTokenCount(contextWindow)}) is already at or below the ${formatDecimalTokenCount(CONTEXT_SIZE_FLOOR_TOKENS)} floor.`);
312454
+ return;
312455
+ }
312456
+ host.harness.getConfig().then((config) => {
312457
+ const currentPercent = loopControlFromConfig(config)?.contextSizePercent ?? 100;
312458
+ host.mountEditorReplacement(new ContextSizeSelectorComponent({
312459
+ contextWindow,
312460
+ percentOptions,
312461
+ currentPercent,
312462
+ onSelect: (percent) => {
312463
+ host.restoreEditor();
312464
+ applyContextSizeChoice(host, percent);
312465
+ },
312466
+ onCancel: () => {
312467
+ host.restoreEditor();
312468
+ }
312469
+ }));
312470
+ }, (error) => {
312471
+ host.showError(`Failed to load context size: ${formatErrorMessage$2(error)}`);
312472
+ });
312473
+ }
312474
+ async function applyContextSizeChoice(host, percent) {
312475
+ const contextWindow = activeModelContextWindow(host);
312476
+ try {
312477
+ await host.harness.setConfig({ loopControl: { contextSizePercent: percent } });
312478
+ } catch (error) {
312479
+ host.showError(`Failed to save context size: ${formatErrorMessage$2(error)}`);
312480
+ return;
312481
+ }
312482
+ const maxContextTokens = contextWindow > 0 ? scaleContextTokens(contextWindow, percent) : 0;
312483
+ if (maxContextTokens > 0) host.setAppState({ maxContextTokens });
312484
+ host.showNotice(`Context size: ${percent}%`, `Effective window ${formatDecimalTokenCount(maxContextTokens)} (default ${formatDecimalTokenCount(contextWindow)}).`);
312485
+ }
312316
312486
  async function showExperimentsPanel(host) {
312317
312487
  let features;
312318
312488
  try {
@@ -312457,6 +312627,9 @@ function handleSettingsSelection(host, value) {
312457
312627
  case "busy-input":
312458
312628
  showBusyInputModePicker(host);
312459
312629
  return;
312630
+ case "context-size":
312631
+ showContextSizePicker(host);
312632
+ return;
312460
312633
  case "experiments":
312461
312634
  showExperimentsPanel(host);
312462
312635
  return;
@@ -312472,6 +312645,7 @@ var MODEL_PICKER_REFRESH_TIMEOUT_MS, MODEL_SWITCH_CACHE_WARNING, EFFORT_SWITCH_C
312472
312645
  var init_config = __esmMin((() => {
312473
312646
  init_src$4();
312474
312647
  init_busy_input_mode_selector();
312648
+ init_context_size_selector();
312475
312649
  init_editor_selector();
312476
312650
  init_effort_selector();
312477
312651
  init_experiments_selector();
@@ -312486,6 +312660,8 @@ var init_config = __esmMin((() => {
312486
312660
  init_dimi_tui$1();
312487
312661
  init_event_payload();
312488
312662
  init_thinking_config();
312663
+ init_src$6();
312664
+ init_usage_format();
312489
312665
  init_info();
312490
312666
  init_experimental_flags();
312491
312667
  MODEL_PICKER_REFRESH_TIMEOUT_MS = 2e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimi-agent/cli",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
4
4
  "description": "The Starting Point for Next-Gen Agents",
5
5
  "keywords": [
6
6
  "agent",
@@ -60,14 +60,14 @@
60
60
  "tsx": "^4.21.0",
61
61
  "yazl": "^3.3.1",
62
62
  "zod": "^4.3.6",
63
+ "@dimi-agent/agent-core-v2": "^0.1.0",
63
64
  "@dimi-agent/dimi-oauth": "^0.1.0",
64
65
  "@dimi-agent/dimi-sdk": "^0.2.0",
65
66
  "@dimi-agent/dimi-telemetry": "^0.1.0",
66
- "@dimi-agent/agent-core-v2": "^0.1.0",
67
67
  "@dimi-agent/dimi-web": "^0.1.0",
68
- "@dimi-agent/pi-tui": "^0.1.0",
68
+ "@dimi-agent/kap-server": "^0.1.0",
69
69
  "@dimi-agent/remote": "^0.1.0",
70
- "@dimi-agent/kap-server": "^0.1.0"
70
+ "@dimi-agent/pi-tui": "^0.1.0"
71
71
  },
72
72
  "optionalDependencies": {
73
73
  "@mariozechner/clipboard": "^0.3.9",