pi-subagents-lite 1.4.1 → 1.4.3

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.
@@ -10,10 +10,11 @@
10
10
  */
11
11
 
12
12
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
13
- import { SettingsList, SelectList, type SettingItem } from "@earendil-works/pi-tui";
13
+ import { SettingsList, type SettingItem } from "@earendil-works/pi-tui";
14
14
  import { getAgentConfig, getAllTypes } from "../../agents/agent-types.js";
15
+ import type { Theme } from "../types.js";
15
16
  import { CONFIG_AGENT_NON_MODEL_KEYS } from "../../config/types.js";
16
- import { buildSettingsListTheme, buildSelectListTheme, createDelegatingComponent } from "./helpers.js";
17
+ import { buildSettingsListTheme, createSearchableSelect } from "./helpers.js";
17
18
  import { createModelSelectSubmenu } from "./submenus/model-select.js";
18
19
  import { createConfirmSubmenu } from "./submenus/confirm.js";
19
20
  import { SettingsListWrapper } from "./wrappers/settings-list.js";
@@ -24,7 +25,7 @@ export async function showModelSettingsMenu(
24
25
  modelOptions: string[],
25
26
  ): Promise<void> {
26
27
  // Build menu items from current store state.
27
- const buildItems = (store: ReturnType<typeof getStore>, theme: any): SettingItem[] => {
28
+ const buildItems = (store: ReturnType<typeof getStore>, theme: Theme): SettingItem[] => {
28
29
  const items: SettingItem[] = [];
29
30
 
30
31
  // Shared onSelect for model override submenus: applies session/permanent/clear
@@ -71,6 +72,7 @@ export async function showModelSettingsMenu(
71
72
  id: "defaultModel",
72
73
  label: "Global default model",
73
74
  currentValue: globalDisplayValue,
75
+ description: "Model used when no per-type override or frontmatter model applies.",
74
76
  submenu: createModelSelectSubmenu({
75
77
  modelOptions,
76
78
  showClear: false,
@@ -105,6 +107,7 @@ export async function showModelSettingsMenu(
105
107
  id: `type:${typeName}`,
106
108
  label: typeName,
107
109
  currentValue: `${frontmatterHint}${displayModel}`,
110
+ description: `Per-type model override for the ${typeName} agent type.`,
108
111
  submenu: createModelSelectSubmenu({
109
112
  modelOptions,
110
113
  showClear: hasPerm,
@@ -121,26 +124,26 @@ export async function showModelSettingsMenu(
121
124
  id: "overrideType",
122
125
  label: "Override another type...",
123
126
  currentValue: "",
124
- submenu: (_currentValue, subDone) => {
125
- const typeNames = nonOverridden.map(e => ({ value: e.typeName, label: e.typeName }));
126
- const typeList = new SelectList(typeNames, 10, buildSelectListTheme(theme));
127
- const delegator = createDelegatingComponent(typeList);
128
-
129
- typeList.onSelect = (item) => {
130
- const entry = nonOverridden.find(e => e.typeName === item.value)!;
131
- // Delegate to createModelSelectSubmenu for the 2-step model flow
132
- const modelSubmenu = createModelSelectSubmenu({
133
- modelOptions,
134
- showClear: false,
135
- theme,
136
- onSelect: modelOverrideOnSelect(entry.typeName, entry.typeName),
137
- });
138
- delegator.setActive(modelSubmenu(entry.effectiveModel, subDone));
139
- };
140
- typeList.onCancel = () => subDone();
141
-
142
- return delegator;
143
- },
127
+ description: "Add a model override for an agent type that currently inherits.",
128
+ submenu: (_currentValue, subDone) =>
129
+ createSearchableSelect(
130
+ nonOverridden.map(e => ({ value: e.typeName, label: e.typeName })),
131
+ {
132
+ onSelect: (typeName) => {
133
+ const entry = nonOverridden.find(e => e.typeName === typeName)!;
134
+ // Delegate to createModelSelectSubmenu for the 2-step model flow
135
+ const modelSubmenu = createModelSelectSubmenu({
136
+ modelOptions,
137
+ showClear: false,
138
+ theme,
139
+ onSelect: modelOverrideOnSelect(entry.typeName, entry.typeName),
140
+ });
141
+ return modelSubmenu(entry.effectiveModel, subDone);
142
+ },
143
+ onCancel: () => subDone(),
144
+ },
145
+ theme,
146
+ ),
144
147
  });
145
148
  }
146
149
 
@@ -153,6 +156,7 @@ export async function showModelSettingsMenu(
153
156
  id: "clearSession",
154
157
  label: "Clear session overrides",
155
158
  currentValue: "",
159
+ description: "Discard model overrides set only for this session.",
156
160
  submenu: createConfirmSubmenu({
157
161
  message: "Clear all session overrides?",
158
162
  theme,
@@ -169,6 +173,7 @@ export async function showModelSettingsMenu(
169
173
  id: "clearAll",
170
174
  label: "Clear all overrides",
171
175
  currentValue: "",
176
+ description: "Discard all model overrides (config and session).",
172
177
  submenu: createConfirmSubmenu({
173
178
  message: "Clear all model overrides?",
174
179
  theme,
@@ -22,6 +22,7 @@ import { getDisplayName, truncateDesc } from "../format.js";
22
22
  import { buildSnapshotMarkdown } from "../../prompt/context.js";
23
23
  import { buildSelectListTheme, createDelegatingComponent } from "./helpers.js";
24
24
  import { getManager, getStore } from "../../shell.js";
25
+ import type { Theme } from "../types.js";
25
26
 
26
27
  /**
27
28
  * Show a ResultViewer for an agent's result, error, or snapshot.
@@ -73,7 +74,7 @@ async function showResultViewer(
73
74
  export function buildAgentActionsList(
74
75
  ctx: ExtensionCommandContext,
75
76
  record: AgentRecord,
76
- theme: any,
77
+ theme: Theme,
77
78
  done: () => void,
78
79
  setActive: (c: import("@earendil-works/pi-tui").Component) => void,
79
80
  onClose: () => void,
@@ -27,6 +27,7 @@ export async function showSpawnOptionsMenu(ctx: ExtensionCommandContext): Promis
27
27
  label: "Force background",
28
28
  currentValue: store.agent.forceBackground ? "ON" : "OFF",
29
29
  values: ["ON", "OFF"],
30
+ description: "Spawn every agent in the background by default (no foreground wait).",
30
31
  },
31
32
  {
32
33
  id: "graceTurns",
@@ -36,6 +37,7 @@ export async function showSpawnOptionsMenu(ctx: ExtensionCommandContext): Promis
36
37
  store.mutate.agent.setGraceTurns(parsed);
37
38
  ctx.ui.notify(`Grace turns set to ${parsed}`, "info");
38
39
  }),
40
+ description: "Extra turns after the soft turn limit before a hard abort.",
39
41
  },
40
42
  {
41
43
  id: "defaultMaxTurns",
@@ -48,18 +50,21 @@ export async function showSpawnOptionsMenu(ctx: ExtensionCommandContext): Promis
48
50
  store.mutate.agent.setDefaultMaxTurns(undefined);
49
51
  ctx.ui.notify("Default max turns cleared", "info");
50
52
  }),
53
+ description: "Soft turn limit; agent is steered here, then hard-aborts after grace turns. Blank = unlimited.",
51
54
  },
52
55
  {
53
56
  id: "defaultThinking",
54
57
  label: "Default thinking level",
55
58
  currentValue: store.agent.defaultThinking ?? "inherit",
56
59
  values: ["off", "minimal", "low", "medium", "high", "xhigh", "inherit"],
60
+ description: "Thinking level applied when agent frontmatter omits one.",
57
61
  },
58
62
  {
59
63
  id: "disableDefaultAgents",
60
64
  label: "Disable default agents",
61
65
  currentValue: store.agent.disableDefaultAgents ? "ON" : "OFF",
62
66
  values: ["ON", "OFF"],
67
+ description: "Skip auto-loading built-in agent types next session; only .pi/agents types load.",
63
68
  },
64
69
  ];
65
70
 
@@ -11,9 +11,10 @@
11
11
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
12
12
  import { SettingsList, SelectList, type SettingItem } from "@earendil-works/pi-tui";
13
13
  import type { ThinkingLevel } from "../../types.js";
14
+ import type { Theme } from "../types.js";
14
15
  import { getAgentConfig, getAvailableTypes, resolveType, discoverNewAgents } from "../../agents/agent-types.js";
15
- import { findModelInRegistry } from "../../utils.js";
16
- import { buildSettingsListTheme, buildSelectListTheme } from "./helpers.js";
16
+ import { findModelInRegistry, VALID_THINKING_LEVELS } from "../../utils.js";
17
+ import { buildSettingsListTheme, buildSelectListTheme, createSearchableSelect } from "./helpers.js";
17
18
  import { DEFAULT_GRACE_TURNS } from "../../config/config-io.js";
18
19
  import { createModelSelectSubmenu } from "./submenus/model-select.js";
19
20
  import { createNumericSubmenu, createInputSubmenu } from "./submenus/numeric-input.js";
@@ -120,7 +121,6 @@ async function isInGitRepo(cwd: string): Promise<boolean> {
120
121
  // Spawn agent wizard
121
122
  // ============================================================================
122
123
 
123
- const THINKING_LEVELS: ThinkingLevel[] = ["off", "minimal", "low", "medium", "high", "xhigh"];
124
124
 
125
125
  /**
126
126
  * Show the spawn agent flow as a multi-step wizard:
@@ -146,6 +146,7 @@ export async function showSpawnAgentMenu(
146
146
  id: t,
147
147
  label: t,
148
148
  currentValue: t,
149
+ description: getAgentConfig(t)?.description ?? "Agent type",
149
150
  submenu: (_v: string, _subDone: (value?: string) => void) => {
150
151
  done(t);
151
152
  return undefined as any;
@@ -214,6 +215,7 @@ export async function showSpawnAgentMenu(
214
215
  id: "spawn",
215
216
  label: "Spawn",
216
217
  currentValue: "",
218
+ description: "Spawn the agent with current settings",
217
219
  submenu: (_v, done) => {
218
220
  const gtItem = items.find(i => i.id === "graceTurns");
219
221
  const bgItem = items.find(i => i.id === "background");
@@ -304,6 +306,7 @@ export async function showSpawnAgentMenu(
304
306
  id: "model",
305
307
  label: "Model",
306
308
  currentValue: displayModel,
309
+ description: "Override the default model for this agent",
307
310
  submenu: createModelSelectSubmenu({
308
311
  modelOptions,
309
312
  showClear: false,
@@ -317,6 +320,7 @@ export async function showSpawnAgentMenu(
317
320
  id: "background",
318
321
  label: "Background",
319
322
  currentValue: currentBackground ? "ON" : "OFF",
323
+ description: "Run the agent in the background",
320
324
  values: ["ON", "OFF"],
321
325
  },
322
326
  ...(inGitRepo
@@ -324,28 +328,33 @@ export async function showSpawnAgentMenu(
324
328
  id: "worktree",
325
329
  label: "Worktree",
326
330
  currentValue: currentWorktreeLabel,
331
+ description: "Run in a linked git worktree instead of parent cwd",
327
332
  submenu: (_v: string, done: (v?: string) => void) => {
328
333
  const pickerItems = [
329
334
  { value: "Inherits parent cwd", label: "Inherits parent cwd" },
330
335
  ...worktrees.map(wt => {
331
336
  const branchLabel = wt.isDetached ? "detached" : (wt.branch ?? "detached");
332
337
  const truncPath = truncatePath(wt.path);
333
- return { value: wt.path, label: `${branchLabel} · ${truncPath}` };
338
+ return { value: wt.path, label: truncPath, provider: branchLabel };
334
339
  }),
335
340
  ];
336
- const list = new SelectList(pickerItems, 10, buildSelectListTheme(theme));
337
- list.onSelect = (item) => {
338
- if (item.value === "Inherits parent cwd") {
339
- currentWorktreePath = undefined;
340
- done("Inherits parent cwd");
341
- } else {
342
- const wt = worktrees.find(w => w.path === item.value);
343
- currentWorktreePath = wt?.path;
344
- done(wt?.branch ?? "detached");
345
- }
346
- };
347
- list.onCancel = () => done();
348
- return list;
341
+ return createSearchableSelect(
342
+ pickerItems,
343
+ {
344
+ onSelect: (value) => {
345
+ if (value === "Inherits parent cwd") {
346
+ currentWorktreePath = undefined;
347
+ done("Inherits parent cwd");
348
+ } else {
349
+ const wt = worktrees.find(w => w.path === value);
350
+ currentWorktreePath = wt?.path;
351
+ done(wt?.branch ?? "detached");
352
+ }
353
+ },
354
+ onCancel: () => done(),
355
+ },
356
+ theme,
357
+ );
349
358
  },
350
359
  } as SettingItem]
351
360
  : []),
@@ -353,24 +362,28 @@ export async function showSpawnAgentMenu(
353
362
  id: "thinkingLevel",
354
363
  label: "Thinking level",
355
364
  currentValue: currentThinking ?? "inherit",
356
- values: [...THINKING_LEVELS, "inherit"],
365
+ description: "Set the reasoning effort level",
366
+ values: [...VALID_THINKING_LEVELS, "inherit"],
357
367
  },
358
368
  {
359
369
  id: "maxTokens",
360
370
  label: "Max tokens",
361
371
  currentValue: fmtNum(currentMaxTokens),
372
+ description: "Maximum tokens the agent can consume",
362
373
  submenu: createNumericSubmenu(ctx, (parsed) => { currentMaxTokens = parsed; }, () => { currentMaxTokens = undefined; }),
363
374
  },
364
375
  {
365
376
  id: "maxTurns",
366
377
  label: "Max turns",
367
378
  currentValue: fmtNum(currentMaxTurns),
379
+ description: "Maximum conversation turns before hard stop",
368
380
  submenu: createNumericSubmenu(ctx, (parsed) => { currentMaxTurns = parsed; }, () => { currentMaxTurns = undefined; }),
369
381
  },
370
382
  {
371
383
  id: "graceTurns",
372
384
  label: "Grace turns",
373
385
  currentValue: String(currentGraceTurns),
386
+ description: "Extra turns after soft limit before abort",
374
387
  submenu: createNumericSubmenu(ctx, { min: 0, default: DEFAULT_GRACE_TURNS }, (parsed) => { currentGraceTurns = parsed; }),
375
388
  },
376
389
  { id: "__sep__", label: " ", currentValue: "" },
@@ -378,12 +391,14 @@ export async function showSpawnAgentMenu(
378
391
  id: "description",
379
392
  label: "Description",
380
393
  currentValue: currentDescription,
394
+ description: "Short label shown in the agents list",
381
395
  submenu: createInputSubmenu(ctx),
382
396
  },
383
397
  {
384
398
  id: "prompt",
385
399
  label: "Prompt",
386
400
  currentValue: prompt,
401
+ description: "The user message sent to the agent",
387
402
  submenu: createInputSubmenu(ctx, { required: true }),
388
403
  }
389
404
  ];
@@ -391,7 +406,7 @@ export async function showSpawnAgentMenu(
391
406
  return items;
392
407
  };
393
408
 
394
- let theme: any;
409
+ let theme: Theme;
395
410
  let doneRef: () => void;
396
411
 
397
412
  await ctx.ui.custom((_tui, t, _kb, done) => {
@@ -17,7 +17,7 @@ import { buildSettingsListTheme } from "./helpers.js";
17
17
  import { SettingsListWrapper } from "./wrappers/settings-list.js";
18
18
  import type { SystemPromptMode } from "../../agents/types.js";
19
19
  import { getStore } from "../../shell.js";
20
- import { CUSTOM_PROMPT_PATH } from "../../agents/agent-runner.js";
20
+ import { CUSTOM_PROMPT_PATH } from "../../config/config-io.js";
21
21
 
22
22
  export async function showSystemPromptMenu(ctx: ExtensionCommandContext): Promise<void> {
23
23
  const store = getStore();
@@ -29,6 +29,7 @@ export async function showSystemPromptMenu(ctx: ExtensionCommandContext): Promis
29
29
  label: "System prompt mode",
30
30
  currentValue: store.agent.systemPromptMode,
31
31
  values: ["replace", "inherit", "custom"],
32
+ description: "How the subagent system prompt is built: replace, inherit, or custom.",
32
33
  },
33
34
  ];
34
35
 
@@ -39,6 +40,7 @@ export async function showSystemPromptMenu(ctx: ExtensionCommandContext): Promis
39
40
  label: "Create prompt file",
40
41
  currentValue: CUSTOM_PROMPT_PATH,
41
42
  values: ["Create"],
43
+ description: `Create ${CUSTOM_PROMPT_PATH} with a starter template for custom mode.`,
42
44
  });
43
45
  }
44
46
 
@@ -48,24 +50,26 @@ export async function showSystemPromptMenu(ctx: ExtensionCommandContext): Promis
48
50
  label: "Include AGENTS.md",
49
51
  currentValue: store.agent.includeContextFiles ? "ON" : "OFF",
50
52
  values: ["ON", "OFF"],
53
+ description: "Load project and ~/.pi/agent AGENTS.md as shared <project_context>.",
51
54
  },
52
55
  {
53
56
  id: "loadSkillsImplicitly",
54
57
  label: "Load skills implicitly",
55
58
  currentValue: store.agent.loadSkillsImplicitly ? "ON" : "OFF",
56
59
  values: ["ON", "OFF"],
60
+ description: "Give new agents all skills when frontmatter omits the field.",
57
61
  },
58
62
  {
59
63
  id: "loadExtensionsImplicitly",
60
64
  label: "Load extensions implicitly",
61
65
  currentValue: store.agent.loadExtensionsImplicitly ? "ON" : "OFF",
62
66
  values: ["ON", "OFF"],
67
+ description: "Give new agents all extensions when frontmatter omits the field.",
63
68
  },
64
69
  );
65
70
 
66
71
  return items;
67
72
  };
68
-
69
73
  let items = buildItems();
70
74
  let rebuild: ((newItems: SettingItem[]) => void) | null = null;
71
75
 
@@ -54,15 +54,29 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
54
54
  store.mutate.widget.setShortcut(newValue === "ON");
55
55
  ctx.ui.notify(`Ctrl+o shortcut ${newValue}`, "info");
56
56
  break;
57
+ case "thinkingBuffer":
58
+ store.mutate.agent.setOutputThinkingBufferSize(newValue === "OFF" ? 0 : Number(newValue));
59
+ ctx.ui.notify(`Thinking buffer ${newValue}`, "info");
60
+ break;
57
61
  }
58
62
  };
59
63
 
60
64
  await ctx.ui.custom((_tui, theme, _kb, done) => {
65
+ const statDescriptions: Record<string, string> = {
66
+ showTools: "Show tool count (🛠 ) in the widget.",
67
+ showTurns: "Show turn count (⟳ ) in the widget.",
68
+ showInput: "Show input tokens (↑) in the widget.",
69
+ showOutput: "Show output tokens (↓) in the widget.",
70
+ showContext: "Show context-fill percent (%) in the widget.",
71
+ showCost: "Show dollar cost ($) in the widget.",
72
+ showTime: "Show elapsed time in the widget.",
73
+ };
61
74
  const statItems: SettingItem[] = [...statConfig.entries()].map(([id, cfg]) => ({
62
75
  id,
63
76
  label: cfg.label,
64
77
  currentValue: cfg.get() ? "ON" : "OFF",
65
78
  values: ["ON", "OFF"],
79
+ description: statDescriptions[id],
66
80
  }));
67
81
 
68
82
  const items: SettingItem[] = [
@@ -71,6 +85,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
71
85
  label: "Force compact mode",
72
86
  currentValue: store.agent.widgetCompact ? "ON" : "OFF",
73
87
  values: ["ON", "OFF"],
88
+ description: "Force compact widget mode regardless of ctrl+o state.",
74
89
  },
75
90
  {
76
91
  id: "maxLines",
@@ -80,6 +95,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
80
95
  store.mutate.widget.setMaxLines(parsed);
81
96
  ctx.ui.notify(`Max lines (full) set to ${parsed}`, "info");
82
97
  }),
98
+ description: "Max body lines in full widget mode (excluding heading).",
83
99
  },
84
100
  {
85
101
  id: "descLengthFull",
@@ -89,6 +105,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
89
105
  store.mutate.widget.setDescLengthFull(parsed);
90
106
  ctx.ui.notify(`Description length (full) set to ${parsed}`, "info");
91
107
  }),
108
+ description: "Max description length shown in full widget mode.",
92
109
  },
93
110
  {
94
111
  id: "maxLinesCompact",
@@ -98,6 +115,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
98
115
  store.mutate.widget.setMaxLinesCompact(parsed);
99
116
  ctx.ui.notify(`Max lines (compact) set to ${parsed}`, "info");
100
117
  }),
118
+ description: "Max body lines in compact widget mode.",
101
119
  },
102
120
  {
103
121
  id: "descLengthCompact",
@@ -107,12 +125,21 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
107
125
  store.mutate.widget.setDescLengthCompact(parsed);
108
126
  ctx.ui.notify(`Description length (compact) set to ${parsed}`, "info");
109
127
  }),
128
+ description: "Max description length shown in compact widget mode.",
110
129
  },
111
130
  {
112
131
  id: "shortcut",
113
132
  label: "Ctrl+o shortcut",
114
133
  currentValue: store.agent.widgetShortcut ? "ON" : "OFF",
115
134
  values: ["ON", "OFF"],
135
+ description: "When ON, ctrl+o toggles compact mode; when OFF, compact is set manually.",
136
+ },
137
+ {
138
+ id: "thinkingBuffer",
139
+ label: "Log file thinking buffer",
140
+ currentValue: store.agent.outputThinkingBufferSize === 0 ? "OFF" : String(store.agent.outputThinkingBufferSize),
141
+ values: ["OFF", "80", "200", "500", "1000"],
142
+ description: "Controls log file thinking buffering in chars. OFF = only at turn end, 80 = flush after 80 chars.",
116
143
  },
117
144
  { id: "__sep__", label: " ", currentValue: "" },
118
145
  {
@@ -121,6 +148,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
121
148
  currentValue: "→",
122
149
  submenu: (_currentValue, done2) =>
123
150
  new SettingsList(statItems, 7, buildSettingsListTheme(theme), onChange, () => done2()),
151
+ description: "Toggle which usage stats appear in the widget.",
124
152
  },
125
153
  ];
126
154
 
@@ -6,13 +6,14 @@
6
6
  */
7
7
 
8
8
  import { SelectList, type Component } from "@earendil-works/pi-tui";
9
+ import type { Theme } from "../../types.js";
9
10
  import { buildSelectListTheme } from "../helpers.js";
10
11
 
11
12
  export interface ConfirmSubmenuOptions {
12
13
  /** Message shown to the user */
13
14
  message: string;
14
15
  /** Theme from pi-coding-agent (fg, bold, italic) */
15
- theme: any;
16
+ theme: Theme;
16
17
  /** Called when user confirms (selects Yes) */
17
18
  onConfirm: () => void;
18
19
  }
@@ -2,19 +2,20 @@
2
2
  * model-select-submenu.ts — 2-step model override submenu.
3
3
  *
4
4
  * Step 1: SelectList with override mode (session/permanent/clear)
5
- * Step 2 (if session/permanent): ModelSelectorDialog for model selection
5
+ * Step 2 (if session/permanent): SearchableSelectDialog for model selection
6
6
  *
7
7
  * The submenu factory must be created inside ctx.ui.custom to capture the theme.
8
8
  */
9
9
 
10
10
  import { SelectList, type Component } from "@earendil-works/pi-tui";
11
- import { ModelSelectorDialog, type ModelOption } from "../../../models/model-selector.js";
11
+ import type { Theme } from "../../types.js";
12
+ import { SearchableSelectDialog, type SelectOption } from "../../../ui/searchable-select.js";
12
13
  import { buildModelOptions, buildSelectListTheme, createDelegatingComponent } from "../helpers.js";
13
14
 
14
15
  export interface ModelSelectSubmenuOptions {
15
16
  modelOptions: string[];
16
17
  showClear: boolean;
17
- theme: any; // Theme from pi-coding-agent (fg, bold, italic)
18
+ theme: Theme;
18
19
  onSelect: (mode: "session" | "permanent" | "clear", model: string | null) => void;
19
20
  }
20
21
 
@@ -52,7 +53,7 @@ export function createModelSelectSubmenu(
52
53
  modeList.onCancel = () => done();
53
54
 
54
55
  const modelOpts = buildModelOptions(options.modelOptions);
55
- const modelSelector = new ModelSelectorDialog(
56
+ const modelSelector = new SearchableSelectDialog(
56
57
  modelOpts,
57
58
  _currentValue === "(inherits parent)" ? null : _currentValue,
58
59
  {