@coool/opencode-adaptive 1.2.3 → 1.3.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/dist/gui-experimental.cjs +3 -1
- package/dist/gui.d.ts +2 -1
- package/dist/gui.js +7 -5
- package/dist/gui.js.map +1 -1
- package/dist/tui.js +5 -3
- package/dist/tui.js.map +1 -1
- package/dist/ui/{tui → flow}/controller.d.ts +5 -8
- package/dist/ui/{tui → flow}/controller.js +4 -9
- package/dist/ui/flow/controller.js.map +1 -0
- package/dist/ui/flow/menu.js.map +1 -0
- package/dist/ui/flow/options.d.ts +12 -0
- package/dist/ui/flow/options.js.map +1 -0
- package/dist/ui/{tui → flow}/receipts.d.ts +1 -1
- package/dist/ui/{tui → flow}/receipts.js +4 -7
- package/dist/ui/flow/receipts.js.map +1 -0
- package/dist/ui/{tui → flow}/status.d.ts +0 -2
- package/dist/ui/{tui → flow}/status.js +0 -6
- package/dist/ui/flow/status.js.map +1 -0
- package/dist/ui/{tui → flow}/tiers.d.ts +2 -9
- package/dist/ui/{tui → flow}/tiers.js +5 -25
- package/dist/ui/flow/tiers.js.map +1 -0
- package/dist/ui/gui/api.d.ts +6 -2
- package/dist/ui/gui/api.js +4 -4
- package/dist/ui/gui/api.js.map +1 -1
- package/dist/ui/gui/flow.d.ts +23 -0
- package/dist/ui/gui/flow.js +123 -0
- package/dist/ui/gui/flow.js.map +1 -0
- package/dist/ui/gui/view.js +2 -2
- package/dist/ui/gui/view.js.map +1 -1
- package/dist/ui/tui/search.d.ts +9 -0
- package/dist/ui/tui/search.js +10 -0
- package/dist/ui/tui/search.js.map +1 -0
- package/package.json +2 -1
- package/dist/ui/tui/controller.js.map +0 -1
- package/dist/ui/tui/menu.js.map +0 -1
- package/dist/ui/tui/options.d.ts +0 -19
- package/dist/ui/tui/options.js.map +0 -1
- package/dist/ui/tui/receipts.js.map +0 -1
- package/dist/ui/tui/status.js.map +0 -1
- package/dist/ui/tui/tiers.js.map +0 -1
- /package/dist/ui/{tui → flow}/menu.d.ts +0 -0
- /package/dist/ui/{tui → flow}/menu.js +0 -0
- /package/dist/ui/{tui → flow}/options.js +0 -0
package/dist/ui/tui/menu.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../../src/ui/tui/menu.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Main-menu and mode-menu view models for `/adaptive` (ADP-033): pure data\n * that the controller feeds into `ui.dialog.select`. Descriptions are dynamic\n * where state makes them more informative (health counters, tier contents).\n */\nimport { OPERATING_MODES } from \"../../core/scheduler/types.js\"\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { StatusSnapshot } from \"../../rpc/status.js\"\nimport type { SettingsV1 } from \"../../state/settings/index.js\"\nimport type { SelectOption } from \"./options.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\nexport const MAIN_MENU_ITEMS = [\"status\", \"models\", \"mode\", \"tier\", \"pin\", \"receipts\"] as const\nexport type MainMenuChoice = (typeof MAIN_MENU_ITEMS)[number]\n\n/** \"3 resources · 1 windowed\" — the status line under the menu entry. */\nexport function statusSummary(status: StatusSnapshot | undefined): string {\n if (status === undefined) return \"how every configured model is doing\"\n const total = TIERS.reduce((sum, tier) => sum + status.tiers[tier].length, 0)\n if (total === 0) return \"no models configured yet\"\n const windowed = TIERS.reduce(\n (sum, tier) => sum + status.tiers[tier].filter((entry) => entry.windowed).length,\n 0,\n )\n const windowedNote = windowed === 0 ? \"\" : ` · ${String(windowed)} windowed`\n return `${String(total)} resource${total === 1 ? \"\" : \"s\"}${windowedNote}`\n}\n\n/** \"quick: 1 · standard: 0 · advanced: 2\" — what is configured where. */\nexport function modelsSummary(settings: SettingsV1): string {\n const parts = TIERS.map((tier: TierName) => `${tier}: ${String(settings.tiers[tier].length)}`)\n return parts.join(\" · \")\n}\n\nfunction tierRequestDescription(tierRequest: TierName | null | undefined): string {\n if (tierRequest === undefined) return \"pin a tier for the current session\"\n if (tierRequest === null) return \"not pinned — the routing ladder decides\"\n return `pinned to ${tierRequest} — steers this session`\n}\n\nfunction modeMarker(\n mode: OperatingMode,\n input: { override: OperatingMode | null; effective: OperatingMode },\n): \"override\" | \"current\" | undefined {\n if (mode === input.override) return \"override\"\n if (mode === input.effective) return \"current\"\n return undefined\n}\n\nexport function mainMenuOptions(\n settings: SettingsV1,\n status: StatusSnapshot | undefined,\n tierRequest?: TierName | null,\n effectiveMode: OperatingMode = settings.mode,\n): SelectOption<MainMenuChoice>[] {\n const optionFor = (item: MainMenuChoice): SelectOption<MainMenuChoice> => {\n switch (item) {\n case \"status\":\n return {\n title: \"Status\",\n value: item,\n description: statusSummary(status),\n }\n case \"models\":\n return {\n title: \"Models\",\n value: item,\n description: modelsSummary(settings),\n }\n case \"mode\":\n return {\n title: \"Mode\",\n value: item,\n description: `currently ${effectiveMode}`,\n }\n case \"tier\":\n return {\n title: \"Tier\",\n value: item,\n description: tierRequestDescription(tierRequest),\n }\n case \"pin\":\n return {\n title: \"Pin\",\n value: item,\n description:\n settings.pin === null\n ? \"force one resource\"\n : `pinned to ${resourceLabel(settings.pin)}`,\n }\n case \"receipts\":\n return { title: \"Receipts\", value: item, description: \"why each turn ran the model it ran\" }\n }\n }\n return MAIN_MENU_ITEMS.map(optionFor)\n}\n\nexport function modeOptions(current: OperatingMode): SelectOption<OperatingMode>[] {\n return OPERATING_MODES.map((mode) => ({\n title: mode === current ? `${mode} (current)` : mode,\n value: mode,\n description: modeDescription(mode),\n }))\n}\n\n/** What one mode does — shared by the global and the per-session menus. */\nfunction modeDescription(mode: OperatingMode): string {\n switch (mode) {\n case \"off\":\n return \"Adaptive does nothing\"\n case \"observe\":\n return \"Record decisions without applying them\"\n case \"active\":\n return \"Apply routing and recovery decisions\"\n }\n}\n\n/** One per-session mode-menu pick: follow the global mode, or set an override. */\nexport type SessionModeChoice = { kind: \"global\" } | { kind: \"mode\"; mode: OperatingMode }\n\n/** Which mode the user steers inside a session: the global default or the session override. */\nexport type ModeTarget = \"global\" | \"session\"\n\n/**\n * The first select of the in-session mode flow (ADP-054): ask which mode to\n * steer before showing any mode list — the global default or this session's\n * override. Each row names the current value so the user can tell at a\n * glance which side needs changing.\n */\nexport function modeTargetOptions(\n global: OperatingMode,\n effective: OperatingMode,\n): SelectOption<ModeTarget>[] {\n return [\n {\n title: \"Global mode…\",\n description: `applies to every session without an override (now ${global})`,\n value: \"global\",\n },\n {\n title: \"This session…\",\n description: `override for this session only (now ${effective})`,\n value: \"session\",\n },\n ]\n}\n\n/**\n * The per-session mode menu (ADP-054): first \"Follow global\" (clearing the\n * override), then every mode. An existing override is marked \"(override)\" —\n * distinct from the effective mode's \"(current)\" — so the user can tell a\n * set override apart from a session merely inheriting the global mode.\n */\nexport function sessionModeOptions(input: {\n global: OperatingMode\n override: OperatingMode | null\n effective: OperatingMode\n}): SelectOption<SessionModeChoice>[] {\n const options: SelectOption<SessionModeChoice>[] = [\n {\n title: `Follow global (${input.global})`,\n description: \"clear this session's override\",\n value: { kind: \"global\" },\n },\n ]\n for (const mode of OPERATING_MODES) {\n const marker = modeMarker(mode, input)\n options.push({\n title: marker === undefined ? mode : `${mode} (${marker})`,\n value: { kind: \"mode\", mode },\n description: modeDescription(mode),\n })\n }\n return options\n}\n\n/** What one tier is for — shared by the tier editor and the per-session menu. */\nfunction tierDescription(tier: TierName): string {\n switch (tier) {\n case \"quick\":\n return \"routine edits, mechanical steps\"\n case \"standard\":\n return \"the default\"\n case \"advanced\":\n return \"multi-step design, broad refactors\"\n }\n}\n\n/** One per-session tier-menu pick: follow the routing ladder, or pin a tier. */\nexport type SessionTierChoice = { kind: \"ladder\" } | { kind: \"tier\"; tier: TierName }\n\n/**\n * The per-session tier menu (ADP-055): first \"Follow routing ladder\" (clearing\n * the request), then every tier. A pinned request is marked \"(pinned)\" so the\n * user can tell the sticky request apart from the ordinary ladder.\n */\nexport function sessionTierOptions(input: {\n pinned: TierName | null\n}): SelectOption<SessionTierChoice>[] {\n const options: SelectOption<SessionTierChoice>[] = [\n {\n title: \"Follow routing ladder\",\n description: \"clear this session's tier request\",\n value: { kind: \"ladder\" },\n },\n ]\n for (const tier of TIERS) {\n options.push({\n title: tier === input.pinned ? `${tier} (pinned)` : tier,\n value: { kind: \"tier\", tier },\n description: tierDescription(tier),\n })\n }\n return options\n}\n"]}
|
package/dist/ui/tui/options.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared option shapes for the dialog-driven TUI. These mirror the subset of
|
|
3
|
-
* the host `ui.dialog.select` contract the Adaptive flows use; `tui.ts` adapts
|
|
4
|
-
* them to the real plugin types (structural superset).
|
|
5
|
-
*/
|
|
6
|
-
export interface SelectOption<Value> {
|
|
7
|
-
readonly title: string;
|
|
8
|
-
readonly value: Value;
|
|
9
|
-
readonly description?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface SelectSpec<Value> {
|
|
12
|
-
readonly title: string;
|
|
13
|
-
readonly placeholder?: string;
|
|
14
|
-
readonly options: readonly SelectOption<Value>[];
|
|
15
|
-
readonly current?: Value;
|
|
16
|
-
readonly search?: (query: string, options: readonly SelectOption<Value>[]) => readonly SelectOption<Value>[];
|
|
17
|
-
}
|
|
18
|
-
/** Friendly one-line rendering of an API failure for toasts. */
|
|
19
|
-
export declare function errorText(error: unknown): string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/ui/tui/options.ts"],"names":[],"mappings":"AAsBA,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAA;IAChD,0EAA0E;IAC1E,6EAA6E;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,OAAO,GAAI,KAA+B,CAAC,OAAO,CAAA;QACxD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,OAAO,CAAA;QACrE,yEAAyE;QACzE,oEAAoE;QACpE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,KAAc,EAAE,EAAE,CACjD,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAClD,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC","sourcesContent":["/**\n * Shared option shapes for the dialog-driven TUI. These mirror the subset of\n * the host `ui.dialog.select` contract the Adaptive flows use; `tui.ts` adapts\n * them to the real plugin types (structural superset).\n */\nexport interface SelectOption<Value> {\n readonly title: string\n readonly value: Value\n readonly description?: string\n}\n\nexport interface SelectSpec<Value> {\n readonly title: string\n readonly placeholder?: string\n readonly options: readonly SelectOption<Value>[]\n readonly current?: Value\n readonly search?: (\n query: string,\n options: readonly SelectOption<Value>[],\n ) => readonly SelectOption<Value>[]\n}\n\n/** Friendly one-line rendering of an API failure for toasts. */\nexport function errorText(error: unknown): string {\n if (error instanceof Error) return error.message\n // RPC failures surface as plain objects ({type, message}); String() would\n // render \"[object Object]\" and throw away the only diagnostic the user gets.\n if (typeof error === \"object\" && error !== null) {\n const message = (error as { message?: unknown }).message\n if (typeof message === \"string\" && message.length > 0) return message\n // JSON.stringify throws on BigInt values, which host payloads can carry;\n // stringify them as strings instead of losing the whole diagnostic.\n return JSON.stringify(error, (_, value: unknown) =>\n typeof value === \"bigint\" ? String(value) : value,\n )\n }\n return String(error)\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../../../src/ui/tui/receipts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Receipt view models (ADP-030/033): one-line summaries and bounded detail\n * text for the `/adaptive` receipts browser. No secrets — receipt content is\n * already bounded at write time; this layer only formats.\n */\nimport type { Decision } from \"../../core/scheduler/types.js\"\nimport { resourceLabel } from \"./tiers.js\"\nimport type { Receipt, ReceiptOutcome } from \"../../state/receipts/types.js\"\n\nexport function summarizeDecision(decision: Decision): string {\n switch (decision.kind) {\n case \"apply\": {\n const tier = decision.tier === undefined ? \"\" : ` [${decision.tier}]`\n return `apply ${resourceLabel(decision.model)}${tier} (${decision.reason})`\n }\n case \"defer\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `defer: ${decision.reason}${detail}`\n }\n case \"park\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `park: ${decision.reason}${detail}`\n }\n case \"escalate\": {\n return `escalate ${decision.step} → ${resourceLabel(decision.target)} [${decision.tier}]`\n }\n case \"observe-only\": {\n return `observe: ${summarizeDecision(decision.would)}`\n }\n }\n}\n\nexport function outcomeLine(outcome: ReceiptOutcome | undefined): string {\n if (outcome === undefined) return \"pending\"\n if (outcome.status === \"succeeded\") return \"succeeded\"\n if (outcome.status === \"failed\") return `failed (${outcome.category})`\n return `interrupted (${outcome.reason})`\n}\n\nexport function receiptLine(receipt: Receipt): string {\n return `#${String(receipt.id)} ${summarizeDecision(receipt.decision)} — ${outcomeLine(receipt.outcome)}`\n}\n\nexport function receiptDetail(receipt: Receipt, now: number = Date.now()): string {\n return [\n `id: ${String(receipt.id)}`,\n `when: ${relativeTime(receipt.at, now)} (${new Date(receipt.at).toISOString()})`,\n `session: ${receipt.sessionID}`,\n `unit: ${receipt.unitID ?? \"-\"}`,\n `tier: ${receipt.tier ?? \"-\"}`,\n `decision: ${summarizeDecision(receipt.decision)}`,\n `outcome: ${outcomeLine(receipt.outcome)}`,\n \"\",\n `What happened: ${whatHappened(receipt)}`,\n ].join(\"\\n\")\n}\n\n/** \"just now\" / \"2m ago\" / \"3h ago\" / \"5d ago\" for a receipt timestamp. */\nexport function relativeTime(at: number, now: number): string {\n const seconds = Math.max(0, Math.floor((now - at) / 1000))\n if (seconds < 60) return \"just now\"\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${String(minutes)}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${String(hours)}h ago`\n return `${String(Math.floor(hours / 24))}d ago`\n}\n\n/**\n * Plain-language explanation for a receipt, keyed on the finite reason\n * vocabulary. Unknown reasons fall through to the raw summary.\n */\nexport function whatHappened(receipt: Receipt): string {\n const decision = receipt.decision\n switch (decision.kind) {\n case \"apply\":\n return (\n applyExplanation[decision.reason] ??\n `Adaptive routed this turn to ${resourceLabel(decision.model)}.`\n )\n case \"defer\":\n return deferExplanation[decision.reason] ?? \"Adaptive left the model choice to OpenCode.\"\n case \"park\":\n return (\n parkExplanation[decision.reason] ??\n \"Adaptive could not route this turn and left it to OpenCode.\"\n )\n case \"escalate\":\n return `This turn needed stronger capability, so Adaptive moved it to ${resourceLabel(decision.target)}.`\n case \"observe-only\":\n return \"Adaptive is observing: this is what it would have done, without applying it.\"\n }\n}\n\nconst applyExplanation: Record<string, string> = {\n pin: \"Adaptive routed to the resource you pinned.\",\n preferred:\n \"Adaptive chose this resource: it is the preferred resource for the tier and was available.\",\n fallback:\n \"The preferred resource was unavailable, so Adaptive moved the turn to the next resource in the tier.\",\n probe:\n \"Adaptive sent this turn as a recovery probe after an outage, to check whether the resource works again.\",\n draining: \"Adaptive routed to this resource while its provider was draining capacity.\",\n}\n\nconst deferExplanation: Record<string, string> = {\n \"routing-defer\": \"No routing rule applied to this turn, so Adaptive left the choice to OpenCode.\",\n \"tier-not-configured\":\n \"The tier that would handle this turn has no models configured, so Adaptive left the choice to OpenCode.\",\n \"adaptive-off\": \"Adaptive is switched off, so every turn runs on OpenCode's own choice.\",\n \"pin-unverifiable\":\n \"The pinned resource could not be verified as available, so Adaptive left the choice to OpenCode.\",\n \"pin-incompatible\":\n \"The pinned resource does not fit this turn's requirements, so Adaptive left the choice to OpenCode.\",\n \"escalation-not-justified\":\n \"No structured capability evidence justified escalation, so Adaptive kept the current capability.\",\n \"escalation-budget-exhausted\":\n \"This unit has used its escalation budget; no further escalation is allowed.\",\n \"escalation-ceiling\":\n \"Adaptive is already at the highest capability tier; no stronger tier is configured.\",\n \"escalation-no-candidate\":\n \"No stronger resource was eligible to escalate to (unavailable, blocked, or not configured).\",\n}\n\nconst parkExplanation: Record<string, string> = {\n \"all-blocked\":\n \"Every resource in the tier is currently unavailable, so the turn ran without Adaptive routing.\",\n \"no-candidates\":\n \"There are no models configured for this tier, so the turn ran without Adaptive routing.\",\n \"no-compatible-resource\":\n \"No configured resource fits this turn's requirements, so the turn ran without Adaptive routing.\",\n \"pin-blocked\": \"The pinned resource is unavailable and no fallback is allowed while pinned.\",\n}\n\n/** Receipts shown per dialog page (bounded view). */\nexport const RECEIPTS_PAGE_SIZE = 20\n\nexport function receiptPage(receipts: readonly Receipt[]): Receipt[] {\n return receipts.slice(0, RECEIPTS_PAGE_SIZE)\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/ui/tui/status.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Status-view helpers (ADP-033): flatten the status snapshot into one page\n * showing every configured model with its state, grouped by tier in priority\n * order. Pure and deterministic; local wall-clock rendering is derived from\n * the snapshot's own timestamps.\n */\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../../rpc/status.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\n/** Configured resources in tier order (quick → standard → advanced). */\nexport function healthEntries(\n snapshot: StatusSnapshot,\n): { tier: TierName; status: TierResourceStatus }[] {\n const entries: { tier: TierName; status: TierResourceStatus }[] = []\n for (const tier of TIERS) {\n for (const status of snapshot.tiers[tier]) entries.push({ tier, status })\n }\n return entries\n}\n\n/** Local date and time: quota windows may reset days or weeks from now. */\nexport function clockTime(until: number): string {\n const at = new Date(until)\n const hours = String(at.getHours()).padStart(2, \"0\")\n const minutes = String(at.getMinutes()).padStart(2, \"0\")\n const month = String(at.getMonth() + 1).padStart(2, \"0\")\n const day = String(at.getDate()).padStart(2, \"0\")\n return `${String(at.getFullYear())}-${month}-${day} ${hours}:${minutes}`\n}\n\nfunction pinnedTo(ref: TierResourceStatus[\"ref\"], pin: StatusSnapshot[\"pin\"]): boolean {\n if (pin === null) return false\n return pin.providerID === ref.providerID && pin.id === ref.id && pin.variant === ref.variant\n}\n\n/** One plain status line for a resource: health, window, breaker, pin. */\nexport function statusLine(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n return `${resourceLabel(status.ref)} — ${status.health}${stateSuffix(status, pin)}`\n}\n\n/** Everything after the health state: capacity usage, window, breaker, pin. */\nfunction stateSuffix(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n let suffix = \"\"\n if (status.windowed) {\n suffix +=\n status.windowUntil === null\n ? \", windowed (deadline unknown)\"\n : `, windowed until ${clockTime(status.windowUntil)}`\n }\n if (status.usedPercent !== null) {\n suffix += `, used ${String(status.usedPercent)}%`\n if (status.resetAt !== null) suffix += `, resets ${clockTime(status.resetAt)}`\n }\n if (status.breaker === \"open\") suffix += \", breaker open\"\n else if (status.breaker === \"half_open\") suffix += \", probing\"\n if (pinnedTo(status.ref, pin)) suffix += \" (pinned)\"\n return suffix\n}\n\n/** The STATE column of the status table: window, breaker, pin markers. */\nexport function stateCell(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n return stateSuffix(status, pin).replace(/^[, ]+/, \"\") || \"-\"\n}\n\n/**\n * The whole inventory as a column-aligned table (header row first): models\n * grouped in tier order (quick → standard → advanced), one row per model,\n * columns padded to the widest cell so the grid reads at a glance. There is\n * no per-resource selection step: the table IS the view.\n */\nexport function statusTable(snapshot: StatusSnapshot): string[] {\n const header = [\"MODEL\", \"TIER\", \"HEALTH\", \"STATE\"]\n const rows = healthEntries(snapshot).map(({ tier, status }) => [\n resourceLabel(status.ref),\n tier,\n status.health,\n stateCell(status, snapshot.pin),\n ])\n if (rows.length === 0) return []\n // Header and rows are built together, always four cells wide — the column\n // index cannot be out of range.\n const widths = header.map((cell, column) =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n Math.max(cell.length, ...rows.map((row) => row[column]!.length)),\n )\n const render = (cells: string[]): string =>\n cells\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map((cell, column) => cell.padEnd(widths[column]!))\n .join(\" \")\n .trimEnd()\n return [render(header), ...rows.map(render)]\n}\n\n/** Empty-state copy for the status view when nothing is configured. */\nexport const STATUS_EMPTY_MESSAGE = \"No models configured yet — open Models to add some.\"\n"]}
|
package/dist/ui/tui/tiers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../../src/ui/tui/tiers.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAOvD,qEAAqE;AACrE,MAAM,UAAU,aAAa,CAAC,GAAa;IACzC,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE,CAAA;IAC1C,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAA;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAsC;IAC9D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IACnC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1D,IAAI,MAAM,CAAC,OAAO,KAAK,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;SACpD,IAAI,MAAM,CAAC,OAAO,KAAK,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChE,IAAI,MAAM,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC3C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;AAC3D,CAAC;AAGD,MAAM,UAAU,iBAAiB,CAC/B,QAAoB,EACpB,IAAc,EACd,MAAkC;IAElC,MAAM,OAAO,GAAqC;QAChD,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE;KACvF,CAAA;IACD,MAAM,UAAU,GAAG,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;IACtC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC1C,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE;YAC/D,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE;YAClC,WAAW,EAAE,gBAAgB;SAC9B,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,uEAAuE;IACvE,2CAA2C;IAC3C,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpC,uEAAuE;QACvE,qCAAqC;QACrC,MAAM,WAAW,GACf,SAAS,CAAC,MAAM,KAAK,CAAC;YACpB,CAAC,CAAC,wCAAwC;YAC1C,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;IACrF,CAAC,CAAC,CAAA;AACJ,CAAC;AAeD,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,KAAa;IAC5D,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACpC,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IACzB,OAAO,CACL,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CACpC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAA+B,EAC/B,KAAa;IAEb,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SAC3C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,KAAK,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE;QAC3C,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;KAC9D,CAAC,CAAC,CAAA;AACP,CAAC;AAMD,MAAM,UAAU,cAAc,CAAC,QAA2B;IACxD,MAAM,OAAO,GAAkC;QAC7C,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;KAC5D,CAAA;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAAC,SAA8B,EAAE,KAAa;IAC7E,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;IAC7C,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAA;AAC3D,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,YAAY,CAC1B,SAA8B,EAC9B,KAAa,EACb,KAAa;IAEb,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,CAAA;IAC3B,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;IAC1B,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAA;IACnB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IACnB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,SAA8B,EAAE,KAAa;IAC1E,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;IAC7C,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAA;AAChD,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,CAAC","sourcesContent":["/**\n * Tier-editor view models (ADP-033): resource labels with clear health tags,\n * model search over the real OpenCode model list, variant picking, and pure\n * reorder/remove helpers. All functions are total and deterministic.\n */\nimport type { ModelRef } from \"../../core/work-unit/types.js\"\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../../rpc/status.js\"\nimport type { SettingsV1 } from \"../../state/settings/index.js\"\nimport type { PatchResult } from \"../../state/settings/types.js\"\nimport type { SelectOption } from \"./options.js\"\n\n/** `provider/model` with an `@variant` suffix when pinned to one. */\nexport function resourceLabel(ref: ModelRef): string {\n const base = `${ref.providerID}/${ref.id}`\n return ref.variant === undefined ? base : `${base}@${ref.variant}`\n}\n\n/**\n * Unavailable-resource display: empty string when healthy, otherwise a\n * bracketed, comma-separated tag list (health, breaker, window).\n */\nexport function healthTag(status: TierResourceStatus | undefined): string {\n if (status === undefined) return \"\"\n const parts: string[] = []\n if (status.health !== \"healthy\") parts.push(status.health)\n if (status.breaker === \"open\") parts.push(\"breaker-open\")\n else if (status.breaker === \"half_open\") parts.push(\"half-open\")\n if (status.windowed) parts.push(\"windowed\")\n return parts.length === 0 ? \"\" : ` [${parts.join(\", \")}]`\n}\n\nexport type TierEditorChoice = { kind: \"add\" } | { kind: \"resource\"; index: number }\nexport function tierEditorOptions(\n settings: SettingsV1,\n tier: TierName,\n status: StatusSnapshot | undefined,\n): SelectOption<TierEditorChoice>[] {\n const options: SelectOption<TierEditorChoice>[] = [\n { title: \"Add model…\", value: { kind: \"add\" }, description: \"Search OpenCode models\" },\n ]\n const tierStatus = status?.tiers[tier]\n settings.tiers[tier].forEach((ref, index) => {\n options.push({\n title: `${resourceLabel(ref)}${healthTag(tierStatus?.[index])}`,\n value: { kind: \"resource\", index },\n description: \"Move or remove\",\n })\n })\n // No \"Back\" row: Escape steps back out of the dialog (undefined pick →\n // the editor loop re-shows the tier list).\n return options\n}\n\nexport function tierMenuOptions(status: StatusSnapshot): SelectOption<TierName>[] {\n return TIERS.map((tier) => {\n const resources = status.tiers[tier]\n // The lists are short: showing them inline answers \"what is configured\n // where\" without opening the editor.\n const description =\n resources.length === 0\n ? \"(empty — add models to enable routing)\"\n : resources.map((entry) => resourceLabel(entry.ref)).join(\" · \")\n return { title: `${tier} (${String(resources.length)})`, value: tier, description }\n })\n}\n\n/** Structural summary of one real OpenCode model (built by the entry). */\nexport interface ModelSummary {\n readonly providerID: string\n readonly modelID: string\n readonly name: string\n readonly variants: readonly string[]\n}\n\nexport interface ModelPick {\n providerID: string\n modelID: string\n}\n\nexport function modelMatches(info: ModelSummary, query: string): boolean {\n const q = query.trim().toLowerCase()\n if (q === \"\") return true\n return (\n info.providerID.toLowerCase().includes(q) ||\n info.modelID.toLowerCase().includes(q) ||\n info.name.toLowerCase().includes(q)\n )\n}\n\nexport function modelPickerOptions(\n models: readonly ModelSummary[],\n query: string,\n): SelectOption<ModelPick>[] {\n return models\n .filter((info) => modelMatches(info, query))\n .map((info) => ({\n title: `${info.providerID}/${info.modelID}`,\n description: info.name,\n value: { providerID: info.providerID, modelID: info.modelID },\n }))\n}\n\nexport interface VariantChoice {\n variant: string | undefined\n}\n\nexport function variantOptions(variants: readonly string[]): SelectOption<VariantChoice>[] {\n const options: SelectOption<VariantChoice>[] = [\n { title: \"(model default)\", value: { variant: undefined } },\n ]\n for (const variant of variants) {\n options.push({ title: `@${variant}`, value: { variant } })\n }\n return options\n}\n\n/** Move the resource at `index` to the front (make it primary); out-of-bounds is a no-op. */\nexport function moveResourceToTop(resources: readonly ModelRef[], index: number): ModelRef[] {\n const item = resources[index]\n if (item === undefined) return [...resources]\n return [item, ...resources.filter((_, i) => i !== index)]\n}\n\n/** Swap the resource at `index` with its `delta` neighbour; bounds are no-ops. */\nexport function moveResource(\n resources: readonly ModelRef[],\n index: number,\n delta: -1 | 1,\n): ModelRef[] {\n const next = [...resources]\n const target = index + delta\n const item = next[index]\n const other = next[target]\n if (item === undefined || other === undefined) return next\n next[index] = other\n next[target] = item\n return next\n}\n\n/** Drop the resource at `index`; out-of-bounds keeps the list unchanged. */\nexport function removeResource(resources: readonly ModelRef[], index: number): ModelRef[] {\n const item = resources[index]\n if (item === undefined) return [...resources]\n return resources.filter((_, i) => i !== index)\n}\n\n/** First validation error line for an alert; undefined when the patch applied. */\nexport function validationMessage(result: PatchResult): string | undefined {\n return result.ok ? undefined : result.errors.join(\"; \")\n}\n"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|