@javierkaiser/opencode-indexing 0.1.0 → 0.2.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/tui.ts CHANGED
@@ -28,6 +28,8 @@ import { describeRow, forgetWorkspaceFlow, type WorkspacesRpc } from "./tui/work
28
28
  import { pagePalette } from "./tui/page-style.ts"
29
29
  import type { FooterHandle, FooterState } from "./tui/footer-view.tsx"
30
30
  import { describeError } from "./src/errors.ts"
31
+ import { getDefaultModelId, isLiveTested, listModelIds } from "./src/registry.ts"
32
+ import type { EmbedderProvider } from "./src/types.ts"
31
33
 
32
34
  /**
33
35
  * Navigable rows on the page.
@@ -40,6 +42,9 @@ const PAGE_ROW_COUNT = PAGE_ROWS.length
40
42
 
41
43
  const ID = "opencode.indexing"
42
44
 
45
+ /** Sentinel for the "type it yourself" entry in the model chooser. */
46
+ const CUSTOM_MODEL = "\u0000custom-model"
47
+
43
48
  type RpcClient = {
44
49
  "settings.get": (input: Record<string, never>) => Promise<{ settings: SettingsView }>
45
50
  "settings.set": (input: { patch: Record<string, unknown> }) => Promise<{ settings: SettingsView }>
@@ -64,8 +69,8 @@ interface SettingsView {
64
69
  /** Master switch for writing the own index. */
65
70
  enabled: boolean
66
71
  searchMaxResults: number
67
- hasMistralKey: boolean
68
- hasOpenAiKey: boolean
72
+ /** Providers that have a usable credential or base URL configured. */
73
+ configuredProviders: string[]
69
74
  settingsFile: string
70
75
  }
71
76
 
@@ -334,13 +339,49 @@ const plugin = {
334
339
  })
335
340
  if (typeof provider !== "string") return
336
341
 
337
- const model = await context.ui.dialog.prompt({
338
- title: `Model for ${provider} (leave empty for default)`,
339
- placeholder: provider === "mistral" ? "codestral-embed-2505" : "",
342
+ // Offer the catalog instead of a blank text field. The model list existed
343
+ // all along and was never shown, so the only way to discover a valid model
344
+ // id was to already know it.
345
+ const catalog = listModelIds(provider as EmbedderProvider)
346
+ const defaultModel = getDefaultModelId(provider as EmbedderProvider)
347
+ const tested = isLiveTested(provider as EmbedderProvider)
348
+ const choice = await context.ui.dialog.select({
349
+ title: `Model for ${provider}`,
350
+ options: [
351
+ {
352
+ title: defaultModel ? `${defaultModel} (default)` : "(provider default)",
353
+ value: "",
354
+ description: tested
355
+ ? "Leave the model unset so the provider default applies"
356
+ : "Not yet exercised against the real API; see the README",
357
+ },
358
+ ...catalog
359
+ .filter((modelId) => modelId !== defaultModel)
360
+ .map((modelId) => ({ title: modelId, value: modelId, description: `${provider} model` })),
361
+ {
362
+ title: "Custom…",
363
+ value: CUSTOM_MODEL,
364
+ description: catalog.length > 0 ? "Type a model id that is not in the list" : "This provider has no catalog; type the model id",
365
+ },
366
+ ],
340
367
  })
341
- const patch: Record<string, unknown> = { provider }
342
- if (model && model.trim()) patch.model = model.trim()
343
- await patchSettings(patch)
368
+ if (typeof choice !== "string") return
369
+
370
+ let model = choice
371
+ if (choice === CUSTOM_MODEL) {
372
+ const typed = await context.ui.dialog.prompt({
373
+ title: `Model id for ${provider}`,
374
+ placeholder: defaultModel || "e.g. bge-m3",
375
+ })
376
+ if (typed === undefined) return
377
+ model = typed.trim()
378
+ }
379
+
380
+ // `model` is always written, empty when the user accepted the default.
381
+ // Omitting it left the previous provider's model in the file, where it
382
+ // outranks the new provider's default: switching to voyage produced
383
+ // `voyage` + `codestral-embed-2505`.
384
+ await patchSettings({ provider, model })
344
385
 
345
386
  // API key for the provider (masked prompt).
346
387
  const keyLabel =
@@ -357,7 +398,7 @@ const plugin = {
357
398
  : null
358
399
 
359
400
  if (keyLabel) {
360
- const current = provider === "mistral" && settings.hasMistralKey
401
+ const current = settings.configuredProviders.includes(provider)
361
402
  const key = await context.ui.dialog.prompt({
362
403
  title: `${keyLabel} (leave empty to keep current)`,
363
404
  placeholder: current ? "•••••• (set)" : "not set",