@bubblebrain-ai/bubble 0.0.34 → 0.0.36

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 (168) hide show
  1. package/README.md +27 -7
  2. package/dist/agent/abort-errors.d.ts +2 -2
  3. package/dist/agent/budget-ledger.d.ts +4 -45
  4. package/dist/agent/budget-ledger.js +5 -75
  5. package/dist/agent/categories.d.ts +66 -2
  6. package/dist/agent/categories.js +120 -19
  7. package/dist/agent/child-runner.d.ts +1 -3
  8. package/dist/agent/child-runner.js +6 -37
  9. package/dist/agent/discovery-barrier.js +1 -1
  10. package/dist/agent/profiles.d.ts +1 -2
  11. package/dist/agent/profiles.js +25 -14
  12. package/dist/agent/routing-catalog.d.ts +113 -0
  13. package/dist/agent/routing-catalog.js +240 -0
  14. package/dist/agent/subagent-control.d.ts +5 -12
  15. package/dist/agent/subagent-control.js +0 -2
  16. package/dist/agent/subagent-store.d.ts +1 -1
  17. package/dist/agent/subagent-store.js +1 -3
  18. package/dist/agent/workflow/control.d.ts +21 -0
  19. package/dist/agent/workflow/control.js +50 -8
  20. package/dist/agent/workflow/runtime.d.ts +15 -2
  21. package/dist/agent/workflow/runtime.js +112 -30
  22. package/dist/agent.d.ts +82 -48
  23. package/dist/agent.js +360 -232
  24. package/dist/approval/controller.js +28 -0
  25. package/dist/approval/tool-helper.js +2 -0
  26. package/dist/approval/types.d.ts +21 -1
  27. package/dist/cli.d.ts +1 -1
  28. package/dist/cli.js +2 -1
  29. package/dist/config.d.ts +5 -3
  30. package/dist/config.js +10 -5
  31. package/dist/context/compact-llm.d.ts +2 -2
  32. package/dist/external-runtime/grok-acp.d.ts +56 -0
  33. package/dist/external-runtime/grok-acp.js +386 -0
  34. package/dist/external-runtime/grok-binary.d.ts +25 -0
  35. package/dist/external-runtime/grok-binary.js +108 -0
  36. package/dist/external-runtime/grok-errors.d.ts +7 -0
  37. package/dist/external-runtime/grok-errors.js +15 -0
  38. package/dist/external-runtime/grok-input-policy.d.ts +58 -0
  39. package/dist/external-runtime/grok-input-policy.js +52 -0
  40. package/dist/external-runtime/grok-ndjson.d.ts +14 -0
  41. package/dist/external-runtime/grok-ndjson.js +193 -0
  42. package/dist/external-runtime/grok-network.d.ts +15 -0
  43. package/dist/external-runtime/grok-network.js +81 -0
  44. package/dist/external-runtime/grok-preflight.d.ts +28 -0
  45. package/dist/external-runtime/grok-preflight.js +194 -0
  46. package/dist/external-runtime/grok-process.d.ts +26 -0
  47. package/dist/external-runtime/grok-process.js +184 -0
  48. package/dist/external-runtime/grok-profile.d.ts +32 -0
  49. package/dist/external-runtime/grok-profile.js +419 -0
  50. package/dist/external-runtime/grok-provider.d.ts +31 -0
  51. package/dist/external-runtime/grok-provider.js +41 -0
  52. package/dist/external-runtime/grok-runtime.d.ts +91 -0
  53. package/dist/external-runtime/grok-runtime.js +882 -0
  54. package/dist/external-runtime/index.d.ts +13 -0
  55. package/dist/external-runtime/index.js +13 -0
  56. package/dist/external-runtime/session-policy.d.ts +11 -0
  57. package/dist/external-runtime/session-policy.js +30 -0
  58. package/dist/external-runtime/types.d.ts +65 -0
  59. package/dist/external-runtime/types.js +1 -0
  60. package/dist/feishu/agent-host/approval-card.js +21 -0
  61. package/dist/feishu/agent-host/run-driver.js +19 -3
  62. package/dist/feishu/serve.js +1 -0
  63. package/dist/goal/tools.d.ts +6 -3
  64. package/dist/goal/tools.js +7 -19
  65. package/dist/main.js +114 -28
  66. package/dist/memory/db.d.ts +2 -0
  67. package/dist/memory/db.js +10 -0
  68. package/dist/memory/index.d.ts +1 -0
  69. package/dist/memory/index.js +1 -0
  70. package/dist/memory/phase1.js +14 -2
  71. package/dist/memory/phase2.js +21 -2
  72. package/dist/memory/prompts.js +1 -1
  73. package/dist/memory/session-policy.d.ts +25 -0
  74. package/dist/memory/session-policy.js +55 -0
  75. package/dist/memory/storage.d.ts +1 -0
  76. package/dist/memory/storage.js +13 -0
  77. package/dist/model-catalog.d.ts +18 -0
  78. package/dist/model-catalog.js +92 -52
  79. package/dist/model-config.d.ts +3 -1
  80. package/dist/model-config.js +11 -0
  81. package/dist/oauth/grok.d.ts +25 -0
  82. package/dist/oauth/grok.js +218 -0
  83. package/dist/oauth/index.d.ts +1 -0
  84. package/dist/oauth/index.js +1 -0
  85. package/dist/oauth/storage.d.ts +9 -0
  86. package/dist/oauth/storage.js +25 -0
  87. package/dist/orchestrator/default-hooks.js +23 -7
  88. package/dist/prompt/compose.d.ts +3 -0
  89. package/dist/prompt/compose.js +3 -0
  90. package/dist/prompt/delegation.d.ts +1 -1
  91. package/dist/prompt/delegation.js +41 -8
  92. package/dist/prompt/environment.js +0 -4
  93. package/dist/prompt/reminders.d.ts +0 -1
  94. package/dist/prompt/reminders.js +1 -11
  95. package/dist/prompt/routing.d.ts +14 -0
  96. package/dist/prompt/routing.js +71 -0
  97. package/dist/prompt/runtime.js +1 -1
  98. package/dist/prompt/task-reminders.d.ts +20 -0
  99. package/dist/prompt/task-reminders.js +73 -1
  100. package/dist/provider-ai-sdk.js +2 -2
  101. package/dist/provider-grok.d.ts +26 -0
  102. package/dist/provider-grok.js +59 -0
  103. package/dist/provider-openai-codex.d.ts +17 -1
  104. package/dist/provider-openai-codex.js +101 -29
  105. package/dist/provider-registry.d.ts +72 -0
  106. package/dist/provider-registry.js +336 -59
  107. package/dist/provider-transform.d.ts +1 -1
  108. package/dist/provider-transform.js +35 -17
  109. package/dist/provider.d.ts +3 -0
  110. package/dist/provider.js +14 -0
  111. package/dist/session-types.d.ts +19 -1
  112. package/dist/session.d.ts +1 -0
  113. package/dist/session.js +4 -0
  114. package/dist/slash-commands/commands.js +224 -14
  115. package/dist/slash-commands/types.d.ts +14 -1
  116. package/dist/system-prompt.d.ts +2 -0
  117. package/dist/tools/agent-lifecycle.d.ts +1 -9
  118. package/dist/tools/agent-lifecycle.js +42 -272
  119. package/dist/tools/bash.js +1 -1
  120. package/dist/tools/child-tools.js +2 -0
  121. package/dist/tools/index.d.ts +2 -2
  122. package/dist/tools/index.js +7 -5
  123. package/dist/tools/lsp.js +1 -0
  124. package/dist/tools/memory.d.ts +7 -2
  125. package/dist/tools/memory.js +28 -43
  126. package/dist/tools/server.js +4 -0
  127. package/dist/tools/tool-search.d.ts +1 -1
  128. package/dist/tools/tool-search.js +23 -3
  129. package/dist/tui/model-switch.d.ts +7 -0
  130. package/dist/tui/model-switch.js +15 -5
  131. package/dist/tui-ink/app.d.ts +3 -1
  132. package/dist/tui-ink/app.js +672 -243
  133. package/dist/tui-ink/approval/approval-dialog.js +37 -1
  134. package/dist/tui-ink/approval/diff-view.js +4 -4
  135. package/dist/tui-ink/approval/select.js +2 -2
  136. package/dist/tui-ink/composer-buffer.d.ts +55 -0
  137. package/dist/tui-ink/composer-buffer.js +317 -0
  138. package/dist/tui-ink/feedback-dialog.js +2 -2
  139. package/dist/tui-ink/feishu-setup-picker.js +3 -3
  140. package/dist/tui-ink/footer.d.ts +1 -0
  141. package/dist/tui-ink/footer.js +7 -2
  142. package/dist/tui-ink/input-box.d.ts +36 -7
  143. package/dist/tui-ink/input-box.js +229 -157
  144. package/dist/tui-ink/markdown.js +11 -9
  145. package/dist/tui-ink/message-list.d.ts +5 -1
  146. package/dist/tui-ink/message-list.js +15 -2
  147. package/dist/tui-ink/model-picker.d.ts +61 -4
  148. package/dist/tui-ink/model-picker.js +464 -128
  149. package/dist/tui-ink/paste-operation-tracker.d.ts +13 -0
  150. package/dist/tui-ink/paste-operation-tracker.js +25 -0
  151. package/dist/tui-ink/plan-confirm.js +1 -1
  152. package/dist/tui-ink/run.d.ts +3 -0
  153. package/dist/tui-ink/run.js +1 -1
  154. package/dist/tui-ink/subagent-view.d.ts +34 -1
  155. package/dist/tui-ink/subagent-view.js +82 -1
  156. package/dist/tui-ink/theme.d.ts +19 -2
  157. package/dist/tui-ink/theme.js +25 -8
  158. package/dist/tui-ink/welcome.d.ts +3 -2
  159. package/dist/tui-ink/welcome.js +10 -6
  160. package/dist/types.d.ts +8 -31
  161. package/dist/types.js +1 -1
  162. package/dist/variant/thinking-level.d.ts +2 -2
  163. package/dist/variant/thinking-level.js +2 -1
  164. package/dist/variant/variant-resolver.d.ts +22 -0
  165. package/dist/variant/variant-resolver.js +43 -0
  166. package/package.json +6 -2
  167. package/dist/tools/task.d.ts +0 -2
  168. package/dist/tools/task.js +0 -58
@@ -320,16 +320,17 @@ function appendInlineSegment(segments, text, style) {
320
320
  segments.push(next);
321
321
  }
322
322
  }
323
- function renderSegmentNodes(segments, keyPrefix) {
324
- return segments.map((segment, index) => (_jsx(Text, { bold: segment.bold, italic: segment.italic, color: segment.code ? "#a78bfa" : undefined, children: segment.text }, `${keyPrefix}-${index}`)));
323
+ function renderSegmentNodes(segments, keyPrefix, codeColor) {
324
+ return segments.map((segment, index) => (_jsx(Text, { bold: segment.bold, italic: segment.italic, color: segment.code ? codeColor : undefined, children: segment.text }, `${keyPrefix}-${index}`)));
325
325
  }
326
- function renderInlineSegments(text, keyPrefix, style = {}) {
327
- return renderSegmentNodes(parseMarkdownInlineSegments(text, style), keyPrefix);
326
+ function renderInlineSegments(text, keyPrefix, codeColor, style = {}) {
327
+ return renderSegmentNodes(parseMarkdownInlineSegments(text, style), keyPrefix, codeColor);
328
328
  }
329
329
  function inlinePlainText(text) {
330
330
  return parseMarkdownInlineSegments(text).map((segment) => segment.text).join("");
331
331
  }
332
332
  function InlineText({ text, maxWidth }) {
333
+ const theme = useTheme();
333
334
  const { columns } = useTerminalSize();
334
335
  // Pre-wrap CJK-aware so Ink's space-only wrap-ansi can't chop "、"-joined runs
335
336
  // mid-token. A caller-supplied maxWidth is exact (it already nets out the
@@ -338,10 +339,10 @@ function InlineText({ text, maxWidth }) {
338
339
  // wrapping a few cells early is invisible, a mid-token chop is not.
339
340
  const effectiveWidth = maxWidth ?? (columns ? Math.max(20, columns - 10) : undefined);
340
341
  if (effectiveWidth === undefined) {
341
- return _jsx(Text, { children: renderInlineSegments(text, "inline") });
342
+ return _jsx(Text, { children: renderInlineSegments(text, "inline", theme.inlineCode) });
342
343
  }
343
344
  const wrapped = wrapInlineSegments(parseMarkdownInlineSegments(text), effectiveWidth);
344
- return (_jsx(_Fragment, { children: wrapped.map((segments, li) => (_jsx(Text, { children: segments.length ? renderSegmentNodes(segments, `inline-${li}`) : " " }, li))) }));
345
+ return (_jsx(_Fragment, { children: wrapped.map((segments, li) => (_jsx(Text, { children: segments.length ? renderSegmentNodes(segments, `inline-${li}`, theme.inlineCode) : " " }, li))) }));
345
346
  }
346
347
  function CodeBlock({ lang, lines }) {
347
348
  const theme = useTheme();
@@ -378,6 +379,7 @@ function CodeBlock({ lang, lines }) {
378
379
  return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [lang && _jsx(Text, { color: theme.muted, children: lang }), _jsx(Box, { flexDirection: "column", children: highlighted.map((line, i) => (_jsx(Text, { children: line || " " }, i))) })] }));
379
380
  }
380
381
  function TableBlock({ headers, rows, maxWidth, }) {
382
+ const theme = useTheme();
381
383
  const { columns: termWidth } = useTerminalSize();
382
384
  const colCount = headers.length;
383
385
  // Reserve a buffer so the table fits even when wrapped inside an indented
@@ -425,7 +427,7 @@ function TableBlock({ headers, rows, maxWidth, }) {
425
427
  return lines;
426
428
  });
427
429
  const height = Math.max(1, ...wrapped.map((lines) => lines.length));
428
- return (_jsx(Box, { flexDirection: "column", children: Array.from({ length: height }, (_, line) => (_jsxs(Text, { children: [`${g.v} `, wrapped.map((cellLines, i) => (_jsxs(React.Fragment, { children: [renderCellLine(cellLines[line] ?? [], widths[i] ?? 4, `${keyPrefix}-cell-${i}-${line}`), i < colCount - 1 ? ` ${g.v} ` : ` ${g.v}`] }, i)))] }, `${keyPrefix}-line-${line}`))) }, keyPrefix));
430
+ return (_jsx(Box, { flexDirection: "column", children: Array.from({ length: height }, (_, line) => (_jsxs(Text, { children: [`${g.v} `, wrapped.map((cellLines, i) => (_jsxs(React.Fragment, { children: [renderCellLine(cellLines[line] ?? [], widths[i] ?? 4, `${keyPrefix}-cell-${i}-${line}`, theme.inlineCode), i < colCount - 1 ? ` ${g.v} ` : ` ${g.v}`] }, i)))] }, `${keyPrefix}-line-${line}`))) }, keyPrefix));
429
431
  };
430
432
  return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { children: top }), renderRow(headers, "header", true), _jsx(Text, { children: mid }), rows.map((row, ri) => renderRow(row, `row-${ri}`)), _jsx(Text, { children: bot })] }));
431
433
  }
@@ -491,10 +493,10 @@ export function allocateColumnWidths(natural, available) {
491
493
  }
492
494
  return widths;
493
495
  }
494
- function renderCellLine(segments, width, keyPrefix) {
496
+ function renderCellLine(segments, width, keyPrefix, codeColor) {
495
497
  const padding = " ".repeat(Math.max(0, width - inlineSegmentsWidth(segments)));
496
498
  return [
497
- ...segments.map((segment, index) => (_jsx(Text, { bold: segment.bold, italic: segment.italic, color: segment.code ? "#a78bfa" : undefined, children: segment.text }, `${keyPrefix}-${index}`))),
499
+ ...renderSegmentNodes(segments, keyPrefix, codeColor),
498
500
  _jsx(Text, { children: padding }, `${keyPrefix}-pad`),
499
501
  ];
500
502
  }
@@ -31,7 +31,11 @@ interface MessageListProps {
31
31
  * a freshly-cleared screen instead of appending duplicates.
32
32
  */
33
33
  staticGeneration?: number;
34
- /** Horizontal padding applied inside each committed/streaming row. */
34
+ /**
35
+ * Horizontal padding applied inside each committed/streaming row. Wrap
36
+ * budgets net this out via TRANSCRIPT_ROW_PADDING (= both sides of the
37
+ * default of 1) — keep the two in sync if this ever changes.
38
+ */
35
39
  paddingX?: number;
36
40
  /**
37
41
  * Maximum height (rows) for the live/dynamic region. The in-progress turn is
@@ -12,6 +12,16 @@ import { latestSubagentNote, sortSubagents, subagentDescriptor, subagentLabel, s
12
12
  import { sanitizeInternalReminderBlocks } from "../agent/internal-reminder-sanitizer.js";
13
13
  import { splitImageDisplayContent } from "../tui/image-display.js";
14
14
  const EXECUTE_COMMAND_BLOCK_MAX_LINES = 4;
15
+ /**
16
+ * Every transcript row — each committed <Static> item and the DynamicClamp
17
+ * live region — wraps its content in paddingX={1}: one column of inset on
18
+ * EACH side. Any wrap budget derived from terminalColumns inside a row must
19
+ * net out these two columns. Forgetting them hands the pre-wrapper a budget
20
+ * two columns wider than the real room, and a dense CJK line that packs flush
21
+ * against that budget renders past the terminal edge — the terminal then
22
+ * hard-wraps the last glyph onto a stray row at column 0.
23
+ */
24
+ const TRANSCRIPT_ROW_PADDING = 2;
15
25
  export function MessageList({ messages, streamingContent, streamingReasoning, streamingTools, streamingParts, terminalColumns, showThinking = false, verboseTrace, pendingApproval, nowTick, welcomeBanner, staticGeneration = 0, paddingX = 1, maxStreamRows, }) {
16
26
  const theme = useTheme();
17
27
  const hasStreaming = !!(streamingContent ||
@@ -195,7 +205,9 @@ function TimelineText({ content, compactTop, terminalColumns, streaming = false,
195
205
  // cell right and would overflow. Reserve that extra cell up front so the
196
206
  // pre-wrap never packs a line the terminal then hard-wraps.
197
207
  const gutter = ambiguousIsWide() ? 6 : 5;
198
- const available = terminalColumns ? Math.max(20, terminalColumns - gutter) : undefined;
208
+ const available = terminalColumns
209
+ ? Math.max(20, terminalColumns - gutter - TRANSCRIPT_ROW_PADDING)
210
+ : undefined;
199
211
  const trimmed = visible.trim();
200
212
  return (_jsxs(Box, { marginLeft: 2, marginTop: compactTop ? 0 : 1, children: [_jsx(Text, { color: theme.agent, children: "\u25CF " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: streaming ? (_jsx(StreamingMarkdown, { content: trimmed, maxWidth: available })) : (_jsx(MarkdownContent, { content: trimmed, maxWidth: available })) })] }));
201
213
  }
@@ -347,7 +359,8 @@ function UserMessageBlock({ content, terminalColumns, inputStatus, separateFromP
347
359
  }
348
360
  function PendingInputMessagesBlock({ messages, terminalColumns, title, hint, bulletColor, }) {
349
361
  const theme = useTheme();
350
- const contentWidth = Math.max(20, terminalColumns - 5);
362
+ // Inset per row: marginLeft (2) + "↳ " (2) + the transcript row padding.
363
+ const contentWidth = Math.max(20, terminalColumns - 4 - TRANSCRIPT_ROW_PADDING);
351
364
  return (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: bulletColor, children: "\u2022 " }), _jsxs(Text, { bold: true, color: theme.inputText, children: [title, " "] }), _jsxs(Text, { color: theme.dim, children: ["(", hint, ")"] })] }), messages.flatMap((message, messageIndex) => {
352
365
  const { bodyLines, referenceLines } = splitImageDisplayContent(message.content || " ");
353
366
  const wrappedBody = bodyLines.flatMap((line) => wrapByVisualWidth(line || " ", contentWidth));
@@ -1,4 +1,4 @@
1
- import { ProviderRegistry } from "../provider-registry.js";
1
+ import { ProviderRegistry, type ModelDiscoverySource, type ModelInfo, type ProviderProfile } from "../provider-registry.js";
2
2
  import type { ThinkingLevel } from "../types.js";
3
3
  export { padVisual, truncateVisual } from "../text-display.js";
4
4
  export interface ModelPickerOption {
@@ -7,6 +7,25 @@ export interface ModelPickerOption {
7
7
  group: string;
8
8
  providerBadge: string;
9
9
  reasoningLevels: ThinkingLevel[];
10
+ defaultReasoningLevel?: ThinkingLevel;
11
+ contextWindow?: number;
12
+ toolOutputTokenLimit?: number;
13
+ available: boolean;
14
+ pending: boolean;
15
+ }
16
+ export type ModelPickerPhase = {
17
+ kind: "model";
18
+ } | {
19
+ kind: "effort";
20
+ model: ModelPickerOption;
21
+ selectedIndex: number;
22
+ };
23
+ export interface ModelProviderDiscoveryState {
24
+ status: "pending" | "complete";
25
+ models: ModelInfo[];
26
+ source?: ModelDiscoverySource;
27
+ authoritative: boolean;
28
+ error?: string;
10
29
  }
11
30
  export type PickerKeyAction = "up" | "down" | "enter" | "escape" | "backspace" | "delete";
12
31
  export declare function resolvePickerKeyAction(input: string, key: {
@@ -26,13 +45,36 @@ export declare function formatSkillPickerRow(skill: {
26
45
  width: number;
27
46
  }): string;
28
47
  export declare const MODEL_PICKER_MAX_BODY_ROWS = 10;
29
- export declare const MODEL_PICKER_CHROME_ROWS = 13;
48
+ export declare const MODEL_PICKER_CHROME_ROWS = 14;
49
+ export declare const MODEL_PICKER_RECENT_FAMILY_LIMIT = 3;
50
+ export type ModelPickerDisplayItem = {
51
+ kind: "header";
52
+ key: string;
53
+ label: string;
54
+ } | {
55
+ kind: "model";
56
+ key: string;
57
+ option: ModelPickerOption;
58
+ };
30
59
  export declare function modelPickerBodyRows(termHeight: number): number;
31
60
  export declare function clampPickerIndex(index: number, length: number): number;
32
61
  export declare function pickerWindowStart(selectedIndex: number, length: number, visibleRows: number): number;
33
62
  export declare function padPickerRows(rows: string[], bodyRows: number, width: number): string[];
63
+ export declare function modelPickerRecentKey(recent: readonly string[]): string;
64
+ /**
65
+ * Returns a provider-scoped family key for model ordering.
66
+ *
67
+ * Keep this deliberately conservative: suffixes such as `mini`, `codex`,
68
+ * `spark`, or `highspeed` often describe distinct products rather than
69
+ * interchangeable siblings. The Codex Sol/Terra/Luna trio is the one family
70
+ * whose relationship is explicitly declared by the provider catalog.
71
+ */
72
+ export declare function modelPickerFamilyKey(provider: Pick<ProviderProfile, "id" | "authType">, modelId: string): string;
73
+ export declare function buildModelPickerDisplayItems(options: readonly ModelPickerOption[]): ModelPickerDisplayItem[];
74
+ export declare function resolveModelPickerDisplayIndex(items: readonly ModelPickerDisplayItem[], selectedId: string | undefined): number;
75
+ export declare function filterAndRankModelPickerOptions(options: readonly ModelPickerOption[], query: string): ModelPickerOption[];
34
76
  export declare function formatReasoningLevelsLabel(levels: readonly ThinkingLevel[], asToggle?: boolean): string;
35
- export declare function formatModelPickerRow(option: Pick<ModelPickerOption, "id" | "label" | "providerBadge" | "reasoningLevels">, options: {
77
+ export declare function formatModelPickerRow(option: Pick<ModelPickerOption, "id" | "label" | "providerBadge" | "reasoningLevels"> & Partial<Pick<ModelPickerOption, "available" | "pending">>, options: {
36
78
  selected: boolean;
37
79
  current: boolean;
38
80
  width: number;
@@ -43,8 +85,12 @@ export declare function formatEffortPickerRow(level: ThinkingLevel, options: {
43
85
  asToggle?: boolean;
44
86
  }): string;
45
87
  export declare function formatNoModelResultsRow(query: string, width: number): string;
46
- export declare function preferredEffortIndex(option: Pick<ModelPickerOption, "reasoningLevels">, currentThinkingLevel: ThinkingLevel): number;
88
+ export declare function preferredEffortIndex(option: Pick<ModelPickerOption, "reasoningLevels" | "defaultReasoningLevel">, currentThinkingLevel: ThinkingLevel): number;
47
89
  export declare function shouldOpenEffortPicker(option: Pick<ModelPickerOption, "reasoningLevels">): boolean;
90
+ export declare function isModelOptionSelectable(option: Pick<ModelPickerOption, "available" | "pending" | "reasoningLevels">): boolean;
91
+ export declare function resolveSelectedModelId(options: readonly ModelPickerOption[], selectedId: string | undefined): string | undefined;
92
+ export declare function moveModelSelection(options: readonly ModelPickerOption[], selectedId: string | undefined, direction: -1 | 1): string | undefined;
93
+ export declare function reconcileModelPickerPhase(phase: ModelPickerPhase, options: readonly ModelPickerOption[], currentThinkingLevel: ThinkingLevel): ModelPickerPhase;
48
94
  export interface ModelPickerProps {
49
95
  registry: ProviderRegistry;
50
96
  current: string;
@@ -55,6 +101,17 @@ export interface ModelPickerProps {
55
101
  }
56
102
  export declare function ModelPicker({ registry, current, currentThinkingLevel, recent, onSelect, onCancel }: ModelPickerProps): import("react/jsx-runtime").JSX.Element;
57
103
  export declare function buildLocalModelOptions(registry: ProviderRegistry, current: string, recent: string[]): ModelPickerOption[];
104
+ export declare function buildMergedModelOptions(input: {
105
+ providers: ReturnType<ProviderRegistry["getEnabled"]>;
106
+ localModelsByProvider: ReadonlyMap<string, readonly ModelInfo[]>;
107
+ discoveries: ReadonlyMap<string, ModelProviderDiscoveryState>;
108
+ current: string;
109
+ recent: readonly string[];
110
+ }): ModelPickerOption[];
111
+ export declare function formatModelDiscoveryStatus(providers: readonly Pick<ReturnType<ProviderRegistry["getEnabled"]>[number], "id" | "name">[], discoveries: ReadonlyMap<string, ModelProviderDiscoveryState>): {
112
+ text: string;
113
+ hasError: boolean;
114
+ };
58
115
  export interface ProviderPickerProps {
59
116
  providers: Array<{
60
117
  id: string;