@qadanm/opencode-smart-router 0.0.0-stage → 0.4.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 (65) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/CONTRIBUTING.md +96 -0
  3. package/LICENSE +21 -0
  4. package/README.md +341 -2
  5. package/SECURITY.md +174 -0
  6. package/config.example.json +108 -0
  7. package/dist/allowance.js +487 -0
  8. package/dist/gui-experimental.cjs +1 -0
  9. package/dist/index.js +11111 -0
  10. package/dist/npm/index.js +40 -0
  11. package/dist/tui.js +587 -0
  12. package/docs/ARCHITECTURE.md +104 -0
  13. package/docs/DEBUGGING-GUI.md +70 -0
  14. package/docs/INSTALL.md +120 -0
  15. package/docs/LIMITATIONS.md +213 -0
  16. package/docs/MODELS.md +124 -0
  17. package/docs/OPENDESIGN-INTEGRATION.md +635 -0
  18. package/docs/QA.md +142 -0
  19. package/docs/SHARED-CORE.md +72 -0
  20. package/install +75 -0
  21. package/package.json +92 -4
  22. package/scripts/install.sh +324 -0
  23. package/scripts/uninstall.sh +91 -0
  24. package/src/allowance.ts +135 -0
  25. package/src/core/classify/classifier.ts +305 -0
  26. package/src/core/config-writer.ts +167 -0
  27. package/src/core/config.ts +1030 -0
  28. package/src/core/context/strategy.ts +188 -0
  29. package/src/core/context-health.ts +39 -0
  30. package/src/core/failures.ts +398 -0
  31. package/src/core/history/opencode.ts +173 -0
  32. package/src/core/models/protocol.ts +22 -0
  33. package/src/core/models/registry.ts +203 -0
  34. package/src/core/models/seed.ts +771 -0
  35. package/src/core/offline/mode.ts +321 -0
  36. package/src/core/plan-page.ts +390 -0
  37. package/src/core/plans/catalog.ts +481 -0
  38. package/src/core/policy/calibration.ts +259 -0
  39. package/src/core/policy/eligibility.ts +578 -0
  40. package/src/core/providers/enablement.ts +143 -0
  41. package/src/core/providers/opendesign-credits.ts +206 -0
  42. package/src/core/providers/opendesign-models.ts +628 -0
  43. package/src/core/providers/opendesign.ts +474 -0
  44. package/src/core/quota/calibration.ts +166 -0
  45. package/src/core/quota/commandcode.ts +471 -0
  46. package/src/core/quota/credentials.ts +490 -0
  47. package/src/core/quota/ledger.ts +1273 -0
  48. package/src/core/quota/opencode-go.ts +148 -0
  49. package/src/core/quota/opendesign.ts +1043 -0
  50. package/src/core/quota/reconcile.ts +155 -0
  51. package/src/core/quota/report.ts +261 -0
  52. package/src/core/quota/service.ts +273 -0
  53. package/src/core/reprompt.ts +48 -0
  54. package/src/core/routing/engine.ts +919 -0
  55. package/src/core/types.ts +825 -0
  56. package/src/core/ui.ts +236 -0
  57. package/src/core/util.ts +114 -0
  58. package/src/gui/index.tsx +1670 -0
  59. package/src/gui/viewmodel.ts +456 -0
  60. package/src/index.ts +48 -0
  61. package/src/rpc.ts +204 -0
  62. package/src/server/controller.ts +3281 -0
  63. package/src/server/route-tracker.ts +60 -0
  64. package/src/server/shared-core.ts +671 -0
  65. package/src/tui/index.tsx +168 -0
@@ -0,0 +1,487 @@
1
+ // src/core/plans/catalog.ts
2
+ var OPENDESIGN_DESIGN_PLAN_MODELS = /* @__PURE__ */ new Set([
3
+ "deepseek-v4.1-flash",
4
+ "mimo-v2.6-flash",
5
+ "mimo-v2.6-pro",
6
+ "hy4-preview",
7
+ "deepseek-v4-flash",
8
+ "deepseek-v4-flash-vision-exp",
9
+ "deepseek-v4-pro",
10
+ "glm-5.3-flash",
11
+ "kimi-k2.7-code",
12
+ "claude-haiku-5.5",
13
+ "glm-5.3-flashx",
14
+ "gpt-6-luna"
15
+ ]);
16
+ var OPENDESIGN_DESIGN_PLAN_POOL = "design-plan";
17
+ var OPENDESIGN_PLAN_MODEL_POOL = "plan-models";
18
+ var opendesign = (planID, label, monthlyPriceUsd, designPlanMonthlyUsd, planModelMonthlyUsd, weeklyUsd, fiveHourUsd, concurrency, extraNotes = []) => {
19
+ const pools = [];
20
+ if (designPlanMonthlyUsd > 0) {
21
+ pools.push({
22
+ id: OPENDESIGN_DESIGN_PLAN_POOL,
23
+ label: "Design Plan credits",
24
+ monthlyUsd: designPlanMonthlyUsd,
25
+ ...weeklyUsd !== void 0 ? { weeklyUsd } : {},
26
+ ...fiveHourUsd !== void 0 ? { fiveHourUsd } : {},
27
+ resetKind: "fixed-7-day",
28
+ drawOrder: 1,
29
+ note: fiveHourUsd === void 0 ? "Seven-day ceiling nested inside the monthly maximum. Used before plan model credits." : "Five-hour and seven-day ceilings nested inside the monthly maximum. Used before plan model credits."
30
+ });
31
+ }
32
+ if (planModelMonthlyUsd > 0) {
33
+ pools.push({
34
+ id: OPENDESIGN_PLAN_MODEL_POOL,
35
+ label: "Plan model credits",
36
+ monthlyUsd: planModelMonthlyUsd,
37
+ resetKind: "billing-cycle",
38
+ drawOrder: 2,
39
+ note: "No five-hour or seven-day window. Funds plan models directly, and Design Plan models once their own credits are exhausted. Design Plan multipliers do not carry over to this pool."
40
+ });
41
+ }
42
+ return {
43
+ providerID: "opendesign",
44
+ planID,
45
+ label,
46
+ monthlyPriceUsd,
47
+ pools,
48
+ ...concurrency > 0 ? { concurrency } : {},
49
+ notes: [
50
+ "Credits are not cash and are not a fixed request count.",
51
+ "Design Plan credits and plan model credits are separate pools, but they do spill: on Plus, Pro and Max, Design Plan usage draws from plan model credits once the Design Plan allowance is spent. Go has no plan model credits, so a spent window means waiting for the reset.",
52
+ "The seven-day Design Plan window starts when the subscription starts and repeats every seven days. It is not a rolling window and does not align to Monday or the first of the month.",
53
+ "Plan model credits have no five-hour or seven-day window; they are granted and reset per billing cycle.",
54
+ "Unused subscription credits do not roll over.",
55
+ ...extraNotes
56
+ ]
57
+ };
58
+ };
59
+ var OPENDESIGN_PLANS = [
60
+ opendesign("go", "OpenDesign Go", 10, 120, 0, 30, 10, 10, [
61
+ "Go includes Design Plan credits only and no plan model credits."
62
+ ]),
63
+ // The seven-day Design Plan ceiling for Plus is $40, not "no cap". It was
64
+ // undefined here, which made Plus look like it could spend the whole $160 in
65
+ // one week — understating the real limit by 4x for anyone on that tier.
66
+ opendesign("plus", "OpenDesign Plus", 20, 160, 20, 40, void 0, 20, [
67
+ "Plus has a seven-day Design Plan window and no five-hour window."
68
+ ]),
69
+ opendesign("pro", "OpenDesign Pro", 100, 360, 120, 90, void 0, 30, [
70
+ "Pro has a seven-day Design Plan window and no five-hour window.",
71
+ "The $120 plan model pool currently carries a limited-time promotional bonus and resets per billing cycle."
72
+ ]),
73
+ opendesign("max", "OpenDesign Max", 200, 600, 300, 150, void 0, 30, [
74
+ "Max has a seven-day Design Plan window and no five-hour window."
75
+ ])
76
+ ];
77
+ var GO_MODEL_ALLOWANCES = {
78
+ "deepseek-v4.1-flash": 80,
79
+ "deepseek-v4-pro": 15,
80
+ "glm-5.3-flash": 60,
81
+ "glm-5.3": 15,
82
+ "glm-5.2": 60,
83
+ "minimax-m3.1-flash": 20,
84
+ "mimo-v2.6-flash": 60,
85
+ "mimo-v2.6-pro": 15,
86
+ "claude-haiku-5-5": 15,
87
+ "gpt-6-luna": 15,
88
+ "gpt-6-luna-high": 15,
89
+ "kimi-k3": 15,
90
+ "kimi-k3.1-pro": 15,
91
+ "kimi-k2.7-code": 60,
92
+ "grok-4.7": 15,
93
+ "qwen3.8-max": 15,
94
+ "qwen3.8-flash": 30,
95
+ "step-5-preview": 15,
96
+ "longcat-2.0": 60,
97
+ hy3: 60,
98
+ "hy4-preview": 30,
99
+ "gemini-4-argon": 30
100
+ };
101
+ var GO_PLUS_MODEL_ALLOWANCES = {
102
+ "deepseek-v4.1-flash": 160,
103
+ "deepseek-v4-pro": 60,
104
+ "glm-5.3-flash": 180,
105
+ "glm-5.3": 120,
106
+ "glm-5.2": 180,
107
+ "minimax-m3.1-flash": 80,
108
+ "mimo-v2.6-flash": 120,
109
+ "mimo-v2.6-pro": 60,
110
+ "claude-haiku-5-5": 60,
111
+ "gpt-6-luna": 60,
112
+ "kimi-k3": 60,
113
+ "kimi-k3.1-pro": 60,
114
+ "kimi-k2.7-code": 180,
115
+ "grok-4.7": 60,
116
+ "qwen3.8-max": 60,
117
+ "qwen3.8-flash": 90,
118
+ "step-5-preview": 60,
119
+ "longcat-2.0": 240,
120
+ hy3: 240,
121
+ "hy4-preview": 120,
122
+ "gemini-4-argon": 120
123
+ };
124
+ var openCodeGoPlan = (planID, label, monthlyPriceUsd, allowances) => ({
125
+ providerID: "opencode-go",
126
+ planID,
127
+ label,
128
+ monthlyPriceUsd,
129
+ pools: [
130
+ {
131
+ id: "per-model",
132
+ label: "Per-model monthly allowances",
133
+ // There is no shared pool; the monthly total is the sum of the
134
+ // per-model ceilings for reporting only.
135
+ monthlyUsd: Object.values(allowances).reduce((sum, value) => sum + value, 0),
136
+ resetKind: "billing-cycle",
137
+ drawOrder: 1,
138
+ note: "Each model has its own monthly dollar allowance. The five-hour and weekly ceilings are percentages of that model's allowance, not separate credit."
139
+ }
140
+ ],
141
+ perModelMonthlyUsd: allowances,
142
+ perModelWindowRule: { fiveHourPct: 20, weeklyPct: 50 },
143
+ notes: [
144
+ "Allowances are per model and do not pool across models.",
145
+ "Token prices are identical on Go, Go Plus and Go Teams; only the allowances differ."
146
+ ]
147
+ });
148
+ var COMMANDCODE_PLANS = [
149
+ {
150
+ providerID: "commandcode",
151
+ planID: "goat",
152
+ label: "Command Code GOAT",
153
+ monthlyPriceUsd: 10,
154
+ pools: [
155
+ {
156
+ id: "monthly",
157
+ label: "GOAT monthly credits",
158
+ monthlyUsd: 70,
159
+ weeklyUsd: 35,
160
+ fiveHourUsd: 14,
161
+ resetKind: "billing-cycle",
162
+ drawOrder: 1,
163
+ note: "One shared pool with five-hour and weekly ceilings nested inside the monthly maximum."
164
+ }
165
+ ],
166
+ notes: ["Read from Command Code's read-only account endpoints; the account response is authoritative."]
167
+ }
168
+ ];
169
+ var PLAN_CATALOG = [
170
+ ...OPENDESIGN_PLANS,
171
+ openCodeGoPlan("go", "OpenCode Go", 10, GO_MODEL_ALLOWANCES),
172
+ openCodeGoPlan("go-plus", "OpenCode Go Plus", 40, GO_PLUS_MODEL_ALLOWANCES),
173
+ ...COMMANDCODE_PLANS
174
+ ];
175
+ var PLAN_BY_KEY = new Map(
176
+ PLAN_CATALOG.map((plan) => [`${plan.providerID}/${plan.planID}`, plan])
177
+ );
178
+ var DEFAULT_PLAN_ID = {
179
+ opendesign: "pro",
180
+ "opencode-go": "go",
181
+ commandcode: "goat"
182
+ };
183
+ var defaultPlanIdFor = (providerID) => DEFAULT_PLAN_ID[providerID];
184
+ var PLAN_ALIASES = {
185
+ "opendesign/go-plus": "plus",
186
+ "opendesign/max-plan": "max",
187
+ "opencode-go/goplus": "go-plus",
188
+ "opencode-go/go+": "go-plus"
189
+ };
190
+ var resolvePlanWithReason = (providerID, planID) => {
191
+ const requested = (planID ?? "").trim().toLowerCase();
192
+ if (requested) {
193
+ const aliasTarget = PLAN_ALIASES[`${providerID}/${requested}`];
194
+ if (aliasTarget) {
195
+ const plan = PLAN_BY_KEY.get(`${providerID}/${aliasTarget}`);
196
+ if (plan) return { plan, resolution: "alias", planID: plan.planID };
197
+ }
198
+ const direct = PLAN_BY_KEY.get(`${providerID}/${requested}`);
199
+ if (direct) return { plan: direct, resolution: "exact", planID: direct.planID };
200
+ return { plan: void 0, resolution: "unknown", planID: void 0 };
201
+ }
202
+ const fallback = DEFAULT_PLAN_ID[providerID];
203
+ return {
204
+ plan: fallback ? PLAN_BY_KEY.get(`${providerID}/${fallback}`) : void 0,
205
+ resolution: fallback ? "default" : "unknown",
206
+ planID: fallback
207
+ };
208
+ };
209
+ var resolvePlan = (providerID, planID) => resolvePlanWithReason(providerID, planID).plan;
210
+ var planById = (providerID, planID) => PLAN_BY_KEY.get(`${providerID}/${planID}`);
211
+ var fundingPoolFor = (plan, modelID) => {
212
+ if (plan.providerID === "opendesign") {
213
+ const designPlan = plan.pools.find((pool) => pool.id === OPENDESIGN_DESIGN_PLAN_POOL);
214
+ const planModels = plan.pools.find((pool) => pool.id === OPENDESIGN_PLAN_MODEL_POOL);
215
+ if (OPENDESIGN_DESIGN_PLAN_MODELS.has(modelID)) return designPlan ?? planModels;
216
+ return planModels ?? designPlan;
217
+ }
218
+ return [...plan.pools].sort((a, b) => a.drawOrder - b.drawOrder)[0];
219
+ };
220
+ var isEscalationOnlyPool = (plan, modelID) => {
221
+ if (plan.providerID !== "opendesign") return false;
222
+ return !OPENDESIGN_DESIGN_PLAN_MODELS.has(modelID);
223
+ };
224
+ var poolDrawSequence = (plan, modelID) => {
225
+ const primary = fundingPoolFor(plan, modelID);
226
+ if (!primary) return [];
227
+ const sequence = [{ pool: primary, multiplierApplies: plan.providerID !== "opendesign" || primary.id === OPENDESIGN_DESIGN_PLAN_POOL }];
228
+ if (plan.providerID !== "opendesign") return sequence;
229
+ const designPlan = plan.pools.find((pool) => pool.id === OPENDESIGN_DESIGN_PLAN_POOL);
230
+ const planModels = plan.pools.find((pool) => pool.id === OPENDESIGN_PLAN_MODEL_POOL);
231
+ if (primary.id === OPENDESIGN_DESIGN_PLAN_POOL && planModels) {
232
+ sequence.push({ pool: planModels, multiplierApplies: false });
233
+ } else if (primary.id === OPENDESIGN_PLAN_MODEL_POOL && designPlan && OPENDESIGN_DESIGN_PLAN_MODELS.has(modelID)) {
234
+ sequence.unshift({ pool: designPlan, multiplierApplies: true });
235
+ }
236
+ return sequence;
237
+ };
238
+ var modelMonthlyAllowanceUsd = (plan, modelID) => {
239
+ const table = plan.perModelMonthlyUsd;
240
+ if (!table) return 0;
241
+ return table[modelID] ?? 0;
242
+ };
243
+ var modelWindowCaps = (plan, modelID) => {
244
+ const monthlyUsd = modelMonthlyAllowanceUsd(plan, modelID);
245
+ const rule = plan.perModelWindowRule;
246
+ if (!rule || monthlyUsd <= 0) return { monthlyUsd, weeklyUsd: 0, fiveHourUsd: 0 };
247
+ return {
248
+ monthlyUsd,
249
+ weeklyUsd: monthlyUsd * (rule.weeklyPct / 100),
250
+ fiveHourUsd: monthlyUsd * (rule.fiveHourPct / 100)
251
+ };
252
+ };
253
+ var planSummaryLine = (plan) => {
254
+ const parts = plan.pools.map((pool) => {
255
+ const windows = [
256
+ pool.fiveHourUsd !== void 0 ? `5h $${pool.fiveHourUsd}` : void 0,
257
+ pool.weeklyUsd !== void 0 ? `7d $${pool.weeklyUsd}` : void 0
258
+ ].filter((entry) => Boolean(entry));
259
+ const suffix = windows.length > 0 ? ` (${windows.join(", ")} nested)` : "";
260
+ return `${pool.label} $${pool.monthlyUsd}/mo${suffix}`;
261
+ });
262
+ return `${plan.label} ($${plan.monthlyPriceUsd}/mo): ${parts.join(" + ")}`;
263
+ };
264
+
265
+ // src/core/context/strategy.ts
266
+ var CONTEXT_ELIGIBILITY_MARGIN_TOKENS = 2e4;
267
+ var MINIMUM_REPLY_RESERVE_FRACTION = 0.125;
268
+ var replyMarginFor = (windowTokens) => {
269
+ if (!Number.isFinite(windowTokens) || windowTokens <= 0) return CONTEXT_ELIGIBILITY_MARGIN_TOKENS;
270
+ return Math.min(CONTEXT_ELIGIBILITY_MARGIN_TOKENS, Math.floor(windowTokens * MINIMUM_REPLY_RESERVE_FRACTION));
271
+ };
272
+ var CONTEXT_SAFE_WINDOW_FRACTION = 0.95;
273
+ var no = (reason) => ({ compact: false, reason, hardLimit: false });
274
+ var decideCompaction = (input) => {
275
+ const { mode, settings, contextTokens, effectiveWindow } = input;
276
+ if (!settings.enabled) {
277
+ return { compact: false, reason: "Context management is disabled; native context handling only.", hardLimit: false };
278
+ }
279
+ if (contextTokens <= 0) return no("No measured context size yet.");
280
+ if (effectiveWindow <= 0) return no("The model's accepted context window is unknown; no router-driven compaction.");
281
+ const required = contextTokens + replyMarginFor(effectiveWindow);
282
+ const safeLimit = effectiveWindow * CONTEXT_SAFE_WINDOW_FRACTION;
283
+ const overflow = required > safeLimit;
284
+ if (mode === "native") {
285
+ if (!overflow) return no("Native mode: the transcript fits the verified window.");
286
+ if (settings.allowEmergencyCompaction === false) {
287
+ return {
288
+ compact: false,
289
+ reason: "Native mode: transcript is at the verified limit, but emergency compaction is disabled.",
290
+ triggerTokens: contextTokens,
291
+ targetTokens: Math.floor(safeLimit),
292
+ hardLimit: true
293
+ };
294
+ }
295
+ return {
296
+ compact: true,
297
+ reason: "Native mode emergency compaction: the transcript would exceed the model's verified window.",
298
+ triggerTokens: contextTokens,
299
+ targetTokens: Math.floor(safeLimit),
300
+ hardLimit: true
301
+ };
302
+ }
303
+ if (mode === "conservative") {
304
+ if (!overflow) return no("Conservative mode: the transcript fits the verified window; history preserved.");
305
+ return {
306
+ compact: true,
307
+ reason: "Conservative mode: compacting only because the transcript would exceed the verified window.",
308
+ triggerTokens: contextTokens,
309
+ targetTokens: Math.floor(safeLimit),
310
+ hardLimit: true
311
+ };
312
+ }
313
+ const target = input.cheapestWindow && input.cheapestWindow > 0 ? input.cheapestWindow : effectiveWindow;
314
+ const targetLimit = target * CONTEXT_SAFE_WINDOW_FRACTION;
315
+ const threshold = Math.min(
316
+ targetLimit,
317
+ settings.compactAtTokens > 0 ? settings.compactAtTokens : Number.POSITIVE_INFINITY
318
+ );
319
+ if (required <= threshold) return no("Budget-optimized mode: inside the configured compact threshold.");
320
+ const hardLimit = required > safeLimit;
321
+ return {
322
+ compact: true,
323
+ reason: hardLimit ? "Budget-optimized mode: compacting to stay inside the verified window of the cheapest qualified route." : "Budget-optimized mode: compacting early to keep this session on the cheapest qualified route.",
324
+ triggerTokens: contextTokens,
325
+ targetTokens: Math.floor(threshold),
326
+ hardLimit
327
+ };
328
+ };
329
+ var practicalWindow = (model) => {
330
+ if (model.context <= 0) return 0;
331
+ return model.context;
332
+ };
333
+ var describeMode = (mode) => {
334
+ switch (mode) {
335
+ case "native":
336
+ return "Native: no router-driven compaction unless the transcript would exceed the verified window.";
337
+ case "conservative":
338
+ return "Conservative: history preserved; compaction only to prevent a real overflow.";
339
+ case "budget-optimized":
340
+ return "Budget-optimized: compacts early to keep sessions on the cheapest qualified route.";
341
+ default:
342
+ return "Unknown mode.";
343
+ }
344
+ };
345
+
346
+ // src/core/quota/report.ts
347
+ var FIVE_HOURS_MS = 5 * 60 * 60 * 1e3;
348
+ var WEEK_MS = 7 * 24 * 60 * 60 * 1e3;
349
+ var DAY_MS = 24 * 60 * 60 * 1e3;
350
+ var forecast = (input) => {
351
+ const windowStart = input.now - input.windowMs;
352
+ const earliest = Math.max(windowStart, input.activityStart ?? windowStart);
353
+ const basisMs = Math.min(
354
+ input.windowMs,
355
+ Math.max(60 * 60 * 1e3, input.now - earliest)
356
+ );
357
+ const basisHours = basisMs / (60 * 60 * 1e3);
358
+ const windowHours = input.windowMs / (60 * 60 * 1e3);
359
+ const perHour = input.spendInWindowUsd / Math.max(1e-3, basisHours);
360
+ const projectedUsd = perHour * windowHours;
361
+ const remaining = input.remainingUsd;
362
+ const willExhaust = remaining !== void 0 && projectedUsd > remaining;
363
+ const exhaustsAt = willExhaust && perHour > 0 ? input.now + Math.max(0, remaining ?? 0) / perHour * 60 * 60 * 1e3 : void 0;
364
+ const explanation = willExhaust ? `At the current rate the ${input.label} allowance runs out about ${formatRelative(exhaustsAt ?? input.now, input.now)}.` : `At the current rate the ${input.label} allowance covers the full window.`;
365
+ return {
366
+ projectedUsd,
367
+ basisHours,
368
+ ...exhaustsAt !== void 0 ? { exhaustsAt } : {},
369
+ willExhaust,
370
+ explanation
371
+ };
372
+ };
373
+ var formatRelative = (at, now) => {
374
+ const delta = at - now;
375
+ if (delta <= 0) return "now";
376
+ const hours = delta / (60 * 60 * 1e3);
377
+ if (hours < 1) return `${Math.round(delta / 6e4)} minutes from now`;
378
+ if (hours < 48) return `${hours.toFixed(1)} hours from now`;
379
+ return `${(hours / 24).toFixed(1)} days from now`;
380
+ };
381
+ var buildProviderUsageReport = (input) => {
382
+ const { now, source_ } = input;
383
+ const monthStart = now - 30 * DAY_MS;
384
+ const fiveHour = input.hasFiveHourWindow ? source_.aggregate({ providerID: input.providerID, since: now - FIVE_HOURS_MS, until: now }) : emptyTotals(now - FIVE_HOURS_MS, now);
385
+ const weekly = input.hasWeeklyWindow ? source_.aggregate({ providerID: input.providerID, since: now - WEEK_MS, until: now }) : emptyTotals(now - WEEK_MS, now);
386
+ const monthly = source_.aggregate({ providerID: input.providerID, since: monthStart, until: now });
387
+ const byModel = source_.usageByModel({ since: monthStart, until: now }).filter((entry) => entry.providerID === input.providerID);
388
+ const totalInput = monthly.input + monthly.cacheRead + monthly.cacheWrite;
389
+ const cacheSharePct = totalInput > 0 ? monthly.cacheRead / totalInput * 100 : 0;
390
+ const activityStart = earliestActivity(source_.usageEvents, input.providerID);
391
+ const forecasts = [
392
+ ...input.hasFiveHourWindow ? [{
393
+ window: "5-hour",
394
+ forecast: forecast({
395
+ windowMs: FIVE_HOURS_MS,
396
+ now,
397
+ spendInWindowUsd: fiveHour.usd,
398
+ ...activityStart !== void 0 ? { activityStart } : {},
399
+ label: `${input.label} five-hour`
400
+ })
401
+ }] : [],
402
+ ...input.hasWeeklyWindow ? [{
403
+ window: "7-day",
404
+ forecast: forecast({
405
+ windowMs: WEEK_MS,
406
+ now,
407
+ spendInWindowUsd: weekly.usd,
408
+ ...activityStart !== void 0 ? { activityStart } : {},
409
+ label: `${input.label} seven-day`
410
+ })
411
+ }] : [],
412
+ {
413
+ window: "monthly",
414
+ forecast: forecast({
415
+ windowMs: 30 * DAY_MS,
416
+ now,
417
+ spendInWindowUsd: monthly.usd,
418
+ ...activityStart !== void 0 ? { activityStart } : {},
419
+ ...input.remainingMonthlyUsd !== void 0 ? { remainingUsd: input.remainingMonthlyUsd } : {},
420
+ label: `${input.label} monthly`
421
+ })
422
+ }
423
+ ];
424
+ return {
425
+ providerID: input.providerID,
426
+ label: input.label,
427
+ plan: input.plan,
428
+ source: input.source,
429
+ ...input.quotaState ? { quotaState: input.quotaState } : {},
430
+ fiveHour,
431
+ weekly,
432
+ monthly,
433
+ cacheSharePct,
434
+ byModel,
435
+ forecasts,
436
+ notes: [
437
+ ...input.notes,
438
+ input.hasFiveHourWindow ? "This plan meters a five-hour window." : "This plan has no five-hour window; that row is not a limit being ignored."
439
+ ]
440
+ };
441
+ };
442
+ var emptyTotals = (since, until) => ({
443
+ since,
444
+ until,
445
+ requests: 0,
446
+ input: 0,
447
+ output: 0,
448
+ cacheRead: 0,
449
+ cacheWrite: 0,
450
+ usd: 0,
451
+ failures: 0,
452
+ latencyMsTotal: 0,
453
+ latencySamples: 0
454
+ });
455
+ var earliestActivity = (events, providerID) => {
456
+ let earliest;
457
+ for (const event of events) {
458
+ if (event.providerID !== providerID) continue;
459
+ if (earliest === void 0 || event.at < earliest) earliest = event.at;
460
+ }
461
+ return earliest;
462
+ };
463
+ export {
464
+ CONTEXT_ELIGIBILITY_MARGIN_TOKENS,
465
+ CONTEXT_SAFE_WINDOW_FRACTION,
466
+ DEFAULT_PLAN_ID,
467
+ OPENDESIGN_DESIGN_PLAN_MODELS,
468
+ OPENDESIGN_DESIGN_PLAN_POOL,
469
+ OPENDESIGN_PLAN_MODEL_POOL,
470
+ PLAN_CATALOG,
471
+ buildProviderUsageReport,
472
+ decideCompaction,
473
+ defaultPlanIdFor,
474
+ describeMode,
475
+ forecast,
476
+ formatRelative,
477
+ fundingPoolFor,
478
+ isEscalationOnlyPool,
479
+ modelMonthlyAllowanceUsd,
480
+ modelWindowCaps,
481
+ planById,
482
+ planSummaryLine,
483
+ poolDrawSequence,
484
+ practicalWindow,
485
+ resolvePlan,
486
+ resolvePlanWithReason
487
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("solid-js/web"),G=require("@opencode/plugin/gui"),h=require("solid-js"),ye=require("@opencode/plugin/rpc"),fe={type:"object",additionalProperties:!0},N={type:"object",properties:{},additionalProperties:!1},ee={type:"object",properties:{sessionID:{type:"string"}},required:["sessionID"],additionalProperties:!1},F=t=>({input:t,output:fe}),Q=ye.Rpc.define({id:"smart-router",methods:{status:F({type:"object",properties:{sessionID:{type:"string"}},additionalProperties:!1}),preview:F({type:"object",properties:{sessionID:{type:"string"},text:{type:"string"},files:{type:"array",items:{type:"object",additionalProperties:!0}}},required:["sessionID","text"],additionalProperties:!1}),setMode:F({type:"object",properties:{mode:{type:"string",enum:["efficiency","balanced","premium"]}},required:["mode"],additionalProperties:!1}),setPaused:F({type:"object",properties:{paused:{type:"boolean"}},required:["paused"],additionalProperties:!1}),setSessionAuto:F({type:"object",properties:{sessionID:{type:"string"},auto:{type:"boolean"}},required:["sessionID","auto"],additionalProperties:!1}),setDryRun:F({type:"object",properties:{dryRun:{type:"boolean"}},required:["dryRun"],additionalProperties:!1}),resumeAuto:F(ee),pin:F({type:"object",properties:{sessionID:{type:"string"},providerID:{type:"string"},modelID:{type:"string"},variant:{type:"string"}},required:["sessionID","providerID","modelID"],additionalProperties:!1}),approvePremium:F(ee),denyPremium:F(ee),excludeModel:F({type:"object",properties:{providerID:{type:"string"},modelID:{type:"string"},excluded:{type:"boolean"}},required:["providerID","modelID","excluded"],additionalProperties:!1}),setPremiumBudget:F({type:"object",properties:{usd:{type:"number",minimum:0,maximum:1e5}},required:["usd"],additionalProperties:!1}),setReserve:F({type:"object",properties:{providerID:{type:"string"},monthlyPct:{type:"number",minimum:0,maximum:90},weeklyPct:{type:"number",minimum:0,maximum:90},fiveHourPct:{type:"number",minimum:0,maximum:90}},required:["providerID"],additionalProperties:!1}),floor:F(N),setCalibrateFloor:F({type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"],additionalProperties:!1}),refreshQuota:F(N),onboarding:F(N),completeOnboarding:F(N),recordPlanPage:F({type:"object",properties:{page:{type:"string"},confirm:{type:"boolean"}},required:["page"],additionalProperties:!1}),report:F(N),usage:F(N),getConfig:F(N),resetOverrides:F(N),resetMetrics:F(N),refreshIndicator:F(ee),diagnostics:F(N),setTitleIndicator:F({type:"object",properties:{enabled:{type:"boolean"}},required:["enabled"],additionalProperties:!1})},events:{decision:{schema:{type:"object",properties:{decision:{type:"object",additionalProperties:!0}},required:["decision"],additionalProperties:!1}},status:{schema:{type:"object",properties:{sessionID:{type:"string"},summary:{type:"object",additionalProperties:!0}},required:["summary"],additionalProperties:!1}},quota:{schema:{type:"object",properties:{providers:{type:"array",items:{type:"object",additionalProperties:!0}}},required:["providers"],additionalProperties:!1}}}}),ae=t=>{switch(t){case"provider":return"verified by provider";case"estimate":return"estimated — lower bound";default:return"not reported"}},ge={fiveHour:"5h",weekly:"7d",monthly:"Monthly"},te=(t,n=Date.now())=>{if(t===void 0)return;const o=t-n;if(o<=0)return"resetting";const r=Math.round(o/6e4);if(r<60)return`in ${r}m`;const i=Math.round(r/60);return i<36?`in ${i}h`:`in ${Math.round(i/24)}d`},oe=(t,n,o)=>{const r=n?.source??"unknown",i=n?.usedPct??0,s=r!=="unknown"&&(n?.capUsd!==void 0||i>0);return{id:t,label:ge[t],usedPct:i,remainingPct:n?.remainingPct??Math.max(0,100-i),...n?.usedUsd!==void 0?{usedUsd:n.usedUsd}:{},...n?.capUsd!==void 0?{capUsd:n.capUsd}:{},...n?.resetsAt!==void 0?{resetsAt:n.resetsAt}:{},...te(n?.resetsAt,o)?{resetLabel:te(n?.resetsAt,o)}:{},source:r,sourceLabel:ae(r),exceeded:!!n?.exceeded,reported:s,lowerBound:r==="estimate"}},me=(t,n=Date.now())=>{const o=t.monthly?.source==="provider"?"provider":t.monthly?.source==="estimate"?"estimate":"unknown",r=[oe("fiveHour",t.rolling,n),oe("weekly",t.weekly,n),oe("monthly",t.monthly,n)],i=r.find(u=>u.exceeded),s=(t.pools??[]).map(u=>({id:u.id,label:u.label,source:u.source,sourceLabel:ae(u.source),monthlyUsd:u.monthlyUsd,usedUsd:u.usedUsd,remainingUsd:u.remainingUsd,usedPct:u.usedPct,...u.weeklyUsedPct!==void 0?{weeklyPct:u.weeklyUsedPct}:{},...u.fiveHourUsedPct!==void 0?{fiveHourPct:u.fiveHourUsedPct}:{},...te(u.resetsAt,n)?{resetLabel:te(u.resetsAt,n)}:{},note:u.note}));return{providerID:t.providerID,label:t.label??t.providerID,plan:t.plan??"",source:o,sourceLabel:ae(o),...t.quotaState?{quotaState:t.quotaState}:{},stale:!!t.stale,fetchedAt:t.fetchedAt??n,exhausted:!!i,...i?{exhaustedWindow:i.label}:{},windows:r,pools:s,...t.monthlyRemainingUsd!==void 0?{monthlyRemainingUsd:t.monthlyRemainingUsd}:{},...t.extraCredits?{extraCreditsUsd:t.extraCredits.totalUsd}:{},...t.error?{error:t.error}:{},notes:t.notes??[],...o==="estimate"?{caveat:(t.notes??[])[0]}:{}}},J=t=>Number.isFinite(t)?t===0?"$0":t<.01?`$${t.toFixed(4)}`:t<1?`$${t.toFixed(3)}`:`$${t.toFixed(2)}`:"—",ue=t=>Number.isFinite(t)?`${Math.round(t)}%`:"—",pe=t=>{if(!t.reported)return"—";const n=ue(t.usedPct);return t.lowerBound?`≥${n}`:n},he=t=>{const n=[],o=t.creditMultiplier;o!==void 0&&o!==1&&n.push(`${o}x plan credits`);const r=t.speedFactor;r!==void 0&&r!==1&&n.push(`${r}x measured speed`);const i=t.marginalPriceFactor;return i!==void 0&&i!==1&&n.push(`${i}x expiring allowance`),t.switchPenaltyUsd>0&&n.push(`${J(t.switchPenaltyUsd)} switch cost`),n},be=t=>`${t.providerID}/${t.modelID}`,Se=(t,n)=>{const o=be(t.model);return{key:o,name:t.name,tier:t.tier,verdict:o===n&&t.eligible?"chosen":t.eligible?"eligible":"blocked",reason:t.reason,estimatedUsd:t.estimatedUsd,effectiveCost:t.effectiveCost,successProbability:t.successProbability,adjustments:he(t)}},ce={chosen:0,eligible:1,blocked:2},xe=t=>[...t].sort((n,o)=>{const r=ce[n.verdict]-ce[o.verdict];return r!==0?r:n.verdict==="blocked"?n.key.localeCompare(o.key):n.effectiveCost-o.effectiveCost||n.key.localeCompare(o.key)}),Pe=t=>{if(!t)return;const n=t.chosen?`${t.chosen.providerID}/${t.chosen.id}`:void 0,o=xe(t.candidates.map(r=>Se(r,n)));return{id:t.id,chosen:n,switched:t.switched,switchReason:t.switchReason,taskKind:t.task?.kind??"unknown",taskTier:t.task?.tier??0,contextTokens:t.contextTokens,estimatedUsd:t.estimatedUsd,reasons:t.reasons??[],warnings:t.warnings??[],selfheal:t.selfheal?.rejected?`rejected ${t.selfheal.rejected} · ${t.selfheal.action==="noted"?"noted for the next prompt":t.selfheal.action}`:void 0,eligibleCount:o.filter(r=>r.verdict!=="blocked").length,blockedCount:o.filter(r=>r.verdict==="blocked").length,rows:o}},we=t=>!Number.isFinite(t)||t<=0?"unknown":t>=1e6?`${Number((t/1e6).toFixed(1))}M`:`${Math.round(t/1e3)}k`,Ce=t=>{const n=new Map;for(const r of t.models){const i=r.excluded?"excluded":r.approved?"approved":"not approved",s={key:r.key,providerID:r.providerID,name:r.name,tier:r.tier,intelligence:r.intelligence,design:r.design,contextLabel:we(r.context),costLabel:`${J(r.costInput)} / ${J(r.costOutput)} per 1M`,vision:r.vision,state:i},u=n.get(r.providerID)??[];u.push(s),n.set(r.providerID,u)}const o=new Map(t.quota.map(r=>[r.providerID,r.label??r.providerID]));return[...n.entries()].map(([r,i])=>{const s=t.activeProviders.includes(r),u=i.filter(l=>l.state==="approved").length;return{providerID:r,label:o.get(r)??r,state:s?"active":"not configured",models:[...i].sort((l,v)=>{const C=y=>y.state==="approved"?0:y.state==="excluded"?2:1;return C(l)-C(v)||l.tier-v.tier||l.key.localeCompare(v.key)}),approvedCount:u,totalCount:i.length,...s?{}:{note:"Not routing here: no credential found for this provider on this machine."}}}).sort((r,i)=>r.state!==i.state?r.state==="active"?-1:1:r.label.localeCompare(i.label))};var ke=e.template("<div style=display:flex;flex-direction:column><div style=display:flex;justify-content:space-between;align-items:baseline><span style=text-transform:uppercase;letter-spacing:0.06em;font-weight:600>"),ze=e.template('<div style="display:flex;flex-direction:column;padding:10px 11px">'),De=e.template("<span style=display:flex;flex-direction:column;gap:1px;min-width:0><span></span><span style=font-variant-numeric:tabular-nums>"),$e=e.template("<div role=meter aria-valuemin=0 aria-valuemax=100 style=flex:1;height:3px;border-radius:2px;background:rgba(255,255,255,0.09);overflow:hidden;min-width:36px><div style=height:100%;border-radius:2px>"),Ie=e.template('<span style="font-weight:600;text-transform:uppercase;letter-spacing:0.05em;padding:2px 6px;border-radius:4px;white-space:nowrap">'),je=e.template('<div style="display:flex;flex-direction:column;gap:3px;padding:12px 11px"><span style=font-weight:550></span><span style=line-height:1.5>'),Me=e.template('<button type=button style="display:flex;justify-content:space-between;align-items:center;width:100%;border:none;padding:5px 7px;margin:-5px -7px;color:inherit;font:inherit;cursor:pointer;text-align:left;transition:background 100ms ease"><span style=display:flex;gap:7px;align-items:center;min-width:0><span aria-hidden=true style="display:inline-block;width:9px;font-size:9px;flex-shrink:0;transition:transform 120ms ease">▸</span><span></span></span><span style=display:flex;align-items:baseline;flex-shrink:0>'),Re=e.template('<svg viewBox="0 0 60 60"aria-hidden=true style=flex-shrink:0;display:block><defs><linearGradient id=sr-brand x1=0 y1=0 x2=1 y2=1><stop offset=0%></stop><stop offset=100%></stop></linearGradient></defs><g fill=none stroke=url(#sr-brand) stroke-width=4 stroke-linecap=round><path d="M8 30h12"></path><path d="M20 30c7 0 8-14 15-14h8"></path><path d="M20 30c7 0 8 14 15 14h8"></path><path d="M20 30h23"></path></g><circle cx=5 cy=30 r=4.5 fill=url(#sr-brand)></circle><g fill=url(#sr-brand)><rect x=45 y=10 width=9 height=9 rx=2.5></rect><rect x=45 y=25.5 width=9 height=9 rx=2.5></rect><rect x=45 y=41 width=9 height=9 rx=2.5>'),Ae=e.template("<div style=display:flex;justify-content:space-between;align-items:center><div style=display:flex;align-items:center;min-width:0><div style=display:flex;flex-direction:column;gap:0><span style=font-weight:650;letter-spacing:-0.2px>Smart Router</span><span style=letter-spacing:0.09em;font-weight:600>FOR OPENCODE</span></div></div><div style=display:flex;align-items:center>"),Oe=e.template('<button type=button style="display:flex;align-items:center;justify-content:space-between;width:100%;padding:9px 11px;font:inherit;text-align:left;transition:background 120ms ease"><span style=display:flex;flex-direction:column;gap:1px><span style=font-weight:600>Automatic routing</span><span></span></span><span aria-hidden=true style="width:30px;height:16px;border-radius:8px;position:relative;flex-shrink:0;transition:background 140ms ease"><span style="position:absolute;top:2px;width:12px;height:12px;border-radius:50%;background:#fff;transition:left 140ms ease">'),Ue=e.template('<div style=display:flex;justify-content:space-between;align-items:baseline><span style="font-family:ui-monospace, SFMono-Regular, Menlo, monospace;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">'),Te=e.template("<div style=display:flex;flex-wrap:wrap>"),Fe=e.template("<div style=display:flex;flex-direction:column;gap:3px><span style=text-transform:uppercase;letter-spacing:0.05em>Why"),qe=e.template("<div style=display:flex;align-items:baseline><span style=line-height:1.6>›</span><span style=line-height:1.5>Self-healed: "),Le=e.template("<span style=font-weight:500>Candidates"),Ee=e.template("<div style=display:flex;flex-direction:column;gap:1px>"),He=e.template("<span> eligible · <!> blocked"),Be=e.template("<div style=display:flex;align-items:baseline><span style=line-height:1.6>›</span><span style=line-height:1.5>"),Ne=e.template("<span> considered"),Ge=e.template('<div style="display:flex;flex-direction:column;gap:2px;padding:6px 8px"><div style=display:flex;justify-content:space-between;align-items:baseline><span style="font-family:ui-monospace, SFMono-Regular, Menlo, monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"></span><span style=display:flex;flex-shrink:0><span style=font-variant-numeric:tabular-nums></span><span style=font-variant-numeric:tabular-nums></span></span></div><span style=line-height:1.45>'),We=e.template("<span style=line-height:1.4>"),Ke=e.template('<div style="display:flex;justify-content:space-between;align-items:center;padding:7px 9px"><span style=display:flex;flex-direction:column;gap:2px;min-width:0><span style=font-weight:550></span></span><span style=display:flex;align-items:center;flex-shrink:0><span>/'),Ye=e.template("<span style=font-weight:500>"),Je=e.template("<span style=font-weight:500>Not configured"),Qe=e.template("<span> active"),_=e.template("<span>"),Ve=e.template("<span> provider"),Xe=e.template("<div style=display:flex;justify-content:space-between;align-items:center><span style=font-weight:550></span><span style=display:flex;align-items:center>"),Ze=e.template("<div style=display:flex;flex-direction:column;gap:4px>"),_e=e.template("<div style=display:flex;flex-direction:column;gap:2px>"),re=e.template("<span style=line-height:1.45>"),et=e.template("<div style=display:flex;align-items:center><span style=min-width:42px;font-variant-numeric:tabular-nums></span><span style=min-width:82px;text-align:right;font-variant-numeric:tabular-nums;flex-shrink:0>"),tt=e.template("<span style=flex:1>"),rt=e.template("<div style=display:flex;justify-content:space-between><span></span><span style=font-variant-numeric:tabular-nums> of "),nt=e.template('<button type=button style="padding:5px 11px;font-weight:500">'),ot=e.template("<span style=line-height:1.5>OpenDesign exposes no usage API, so the router can only count what it routed itself. Paste your <strong>Plan &amp; balance</strong> page to replace the estimate with your real position — it carries the percentage, the window it belongs to, and when it resets."),it=e.template('<textarea placeholder="Paste your Plan &amp; balance page — navigation and all is fine."aria-label="Paste your OpenDesign Plan and balance page"rows=3 style="width:100%;resize:vertical;padding:8px 9px;background:transparent;font-family:inherit;line-height:1.5;box-sizing:border-box;outline:none;transition:border-color 120ms ease">'),at=e.template("<span style=line-height:1.5>"),st=e.template("<span>Not on the page: "),lt=e.template("<div style=display:flex>"),dt=e.template("<span>: charged <!>, implied <!>× vs catalog <!>×"),ct=e.template("<span>Handing off to your browser — the page opens in a new tab."),ut=e.template('<span style=line-height:1.45>Could not open the browser automatically. Open this address yourself: <span style="font-family:ui-monospace, SFMono-Regular, Menlo, monospace">https://open-design.ai/cloud/dashboard'),vt=e.template('<div style=display:flex;flex-direction:column><button type=button title=https://open-design.ai/cloud/dashboard style="display:inline-flex;align-items:center;gap:6px;align-self:flex-start;padding:6px 10px;font-weight:550;font-family:inherit;text-underline-offset:2px;transition:background 120ms ease, border-color 120ms ease"><span aria-hidden=true style=font-size:11px>'),yt=e.template("<span><strong style=font-weight:650></strong> <span>request<!> from OpenCode's own database"),ft=e.template("<span style=line-height:1.5>Each one carries its own timestamp and the model that served it, so the seven-day window starts accurate instead of empty."),gt=e.template("<div style=display:flex;flex-direction:column;gap:5px>"),mt=e.template("<span style=font-weight:550>OpenDesign does not expose usage to an API key"),pt=e.template("<span style=line-height:1.55>So the router can only count what <em>it</em> has routed. Anything you spent before installing it — in the desktop app, or with another tool — is invisible, which makes its estimate far too optimistic."),ht=e.template("<span style=line-height:1.55>Paste your <strong>Plan &amp; balance</strong> page once and it knows your real position. This is the only page worth pasting: it carries the percentage, which window it belongs to, and when it resets."),bt=e.template('<textarea placeholder="Paste the whole page here — the navigation and all is fine."aria-label="Paste your OpenDesign Plan and balance page"rows=3 style="width:100%;resize:vertical;padding:8px 9px;background:transparent;font-family:inherit;line-height:1.5;box-sizing:border-box;outline:none">'),St=e.template('<div style=display:flex;align-items:center><button type=button style="padding:5px 11px;font-family:inherit"></button><span>Optional — you can skip and paste later.'),xt=e.template("<span>Recorded. Your allowance now starts from what the account actually shows."),Pt=e.template("<span style=line-height:1.5> provider<!> had no credential and stayed off. They are listed under Providers whenever you want them."),wt=e.template(`<div style="display:flex;flex-direction:column;padding:18px 16px;height:100%;overflow-y:auto;box-sizing:border-box;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;-webkit-font-smoothing:antialiased"><div style="display:flex;flex-direction:column;align-items:center;text-align:center;padding:10px 0 4px"><span style=font-weight:700;letter-spacing:-0.4px;line-height:1.25>Your router is ready</span><span style=line-height:1.5;max-width:260px>It found what is already on this machine and configured itself. Here is exactly what it did.</span></div><button type=button style="margin-top:auto;padding:10px 12px;border:none;color:#fff;font-weight:600;font:inherit;transition:opacity 120ms ease">`),Ct=e.template('<div style="display:flex;justify-content:space-between;align-items:center;padding:8px 9px"><span style=display:flex;flex-direction:column;gap:1px;min-width:0><span style=font-weight:550>'),kt=e.template("<div style=display:flex;align-items:baseline><span>›</span><span style=line-height:1.5>"),zt=e.template("<span>Router unreachable: "),Dt=e.template("<span>The plugin may have failed to load. Check Settings → Extensions → Plugins."),$t=e.template(`<div style="display:flex;flex-direction:column;padding:14px 14px 18px;height:100%;overflow-y:auto;box-sizing:border-box;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;-webkit-font-smoothing:antialiased"><div style=display:flex;flex-direction:column;gap:3px><div style=display:flex;justify-content:space-between;align-items:baseline><span style="font-family:ui-monospace, SFMono-Regular, Menlo, monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"></span><span style=flex-shrink:0>`),It=e.template("<span style=display:inline-flex;align-items:center;gap:5px><span>Smart Router");const p={label:"11px",caption:"13px",body:"14px",title:"16px",display:"20px"},A={xs:"4px",sm:"6px",md:"8px",lg:"12px",xl:"16px"},H={sm:"6px",md:"8px"},a={text:"var(--text-primary, #e8e8ec)",muted:"var(--text-secondary, #9a9aa6)",faint:"var(--text-tertiary, #6f6f7c)",border:"var(--border-subtle, rgba(255,255,255,0.09))",borderStrong:"var(--border-default, rgba(255,255,255,0.16))",surface:"var(--surface-raised, rgba(255,255,255,0.04))",raised:"var(--surface-overlay, rgba(255,255,255,0.07))",good:"var(--text-success, #7ad19a)",warn:"var(--text-warning, #e0b463)",bad:"var(--text-danger, #e08a8a)",brand:"#0f766e",brandTo:"#0891b2"},ve=`linear-gradient(135deg, ${a.brand} 0%, ${a.brandTo} 100%)`;function W(t){return(()=>{var n=ke(),o=n.firstChild,r=o.firstChild;return e.insert(r,()=>t.label),e.insert(o,()=>t.aside,null),e.insert(n,()=>t.children,null),e.effect(i=>{var s={gap:A.sm,...t.first?{}:{"padding-top":A.lg,"border-top":`1px solid ${a.border}`}},u=A.md,l=a.faint,v=p.label;return i.e=e.style(n,s,i.e),u!==i.t&&e.setStyleProperty(o,"gap",i.t=u),l!==i.a&&e.setStyleProperty(r,"color",i.a=l),v!==i.o&&e.setStyleProperty(r,"font-size",i.o=v),i},{e:void 0,t:void 0,a:void 0,o:void 0}),n})()}function V(t){return(()=>{var n=ze();return e.insert(n,()=>t.children),e.effect(o=>{var r=A.sm,i=H.md,s=`1px solid ${t.accent?a.borderStrong:a.border}`,u=a.surface;return r!==o.e&&e.setStyleProperty(n,"gap",o.e=r),i!==o.t&&e.setStyleProperty(n,"border-radius",o.t=i),s!==o.a&&e.setStyleProperty(n,"border",o.a=s),u!==o.o&&e.setStyleProperty(n,"background",o.o=u),o},{e:void 0,t:void 0,a:void 0,o:void 0}),n})()}function ie(t){const n=t.tone==="good"?a.good:t.tone==="warn"?a.warn:t.tone==="bad"?a.bad:a.muted;return(()=>{var o=De(),r=o.firstChild,i=r.nextSibling;return e.insert(r,()=>t.label),e.setStyleProperty(i,"color",n),e.insert(i,()=>t.value),e.effect(s=>{var u=a.faint,l=p.label,v=p.body;return u!==s.e&&e.setStyleProperty(r,"color",s.e=u),l!==s.t&&e.setStyleProperty(r,"font-size",s.t=l),v!==s.a&&e.setStyleProperty(i,"font-size",s.a=v),s},{e:void 0,t:void 0,a:void 0}),o})()}function jt(t){const n=Math.min(100,Math.max(0,t.usedPct)),o=t.exhausted?a.bad:n>=80?a.warn:n>=50?a.brandTo:a.good;return(()=>{var r=$e(),i=r.firstChild;return e.setStyleProperty(i,"width",`${n}%`),e.setStyleProperty(i,"background",o),e.effect(()=>e.setAttribute(r,"aria-valuenow",Math.round(n))),r})()}function Y(t){const n=t.tone==="good"?"rgba(122,209,154,0.12)":t.tone==="warn"?"rgba(224,180,99,0.12)":t.tone==="bad"?"rgba(224,138,138,0.12)":t.tone==="brand"?"rgba(8,145,178,0.16)":"rgba(255,255,255,0.06)",o=t.tone==="good"?a.good:t.tone==="warn"?a.warn:t.tone==="bad"?a.bad:t.tone==="brand"?a.brandTo:a.muted;return(()=>{var r=Ie();return e.setStyleProperty(r,"background",n),e.setStyleProperty(r,"color",o),e.insert(r,()=>t.children),e.effect(i=>e.setStyleProperty(r,"font-size",p.label)),r})()}function ne(t){return(()=>{var n=je(),o=n.firstChild,r=o.nextSibling;return e.insert(o,()=>t.title),e.insert(r,()=>t.body),e.effect(i=>{var s=H.md,u=`1px dashed ${a.border}`,l=a.muted,v=p.body,C=a.faint,y=p.caption;return s!==i.e&&e.setStyleProperty(n,"border-radius",i.e=s),u!==i.t&&e.setStyleProperty(n,"border",i.t=u),l!==i.a&&e.setStyleProperty(o,"color",i.a=l),v!==i.o&&e.setStyleProperty(o,"font-size",i.o=v),C!==i.i&&e.setStyleProperty(r,"color",i.i=C),y!==i.n&&e.setStyleProperty(r,"font-size",i.n=y),i},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),n})()}function se(t){const n=t.size!=="row";return(()=>{var o=Me(),r=o.firstChild,i=r.firstChild,s=i.nextSibling,u=r.nextSibling;return o.addEventListener("mouseleave",()=>t.onHover(void 0)),o.addEventListener("mouseenter",()=>t.onHover(t.id)),e.addEventListener(o,"click",t.onToggle,!0),e.insert(s,()=>t.children),e.insert(u,()=>t.aside),e.effect(l=>{var v=t.open,C=t.open?"Collapse":"Expand",y=A.md,f=t.hovered?a.surface:"transparent",x=H.sm,g=t.hovered?a.text:a.faint,D=t.open?"rotate(90deg)":"none",O=n?{color:a.faint,"font-size":p.label,"text-transform":"uppercase","letter-spacing":"0.06em","font-weight":600}:{color:a.text,"font-size":p.title,"font-weight":550},U=A.md;return v!==l.e&&e.setAttribute(o,"aria-expanded",l.e=v),C!==l.t&&e.setAttribute(o,"title",l.t=C),y!==l.a&&e.setStyleProperty(o,"gap",l.a=y),f!==l.o&&e.setStyleProperty(o,"background",l.o=f),x!==l.i&&e.setStyleProperty(o,"border-radius",l.i=x),g!==l.n&&e.setStyleProperty(i,"color",l.n=g),D!==l.s&&e.setStyleProperty(i,"transform",l.s=D),l.h=e.style(s,O,l.h),U!==l.r&&e.setStyleProperty(u,"gap",l.r=U),l},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0}),o})()}function le(t){const n=t.size??22;return(()=>{var o=Re(),r=o.firstChild,i=r.firstChild,s=i.firstChild,u=s.nextSibling;return e.setAttribute(o,"width",n),e.setAttribute(o,"height",n),e.effect(l=>{var v=a.brand,C=a.brandTo;return v!==l.e&&e.setAttribute(s,"stop-color",l.e=v),C!==l.t&&e.setAttribute(u,"stop-color",l.t=C),l},{e:void 0,t:void 0}),o})()}function Mt(t){const n=t.runtime==="paused"?"warn":t.runtime==="manual"?"neutral":"brand";return(()=>{var o=Ae(),r=o.firstChild,i=r.firstChild,s=i.firstChild,u=s.nextSibling,l=r.nextSibling;return e.insert(r,e.createComponent(le,{}),i),e.insert(l,e.createComponent(Y,{tone:n,get children(){return t.mode}})),e.effect(v=>{var C=A.md,y=A.sm,f=a.text,x=p.title,g=a.faint,D=p.caption,O=A.xs;return C!==v.e&&e.setStyleProperty(o,"gap",v.e=C),y!==v.t&&e.setStyleProperty(r,"gap",v.t=y),f!==v.a&&e.setStyleProperty(s,"color",v.a=f),x!==v.o&&e.setStyleProperty(s,"font-size",v.o=x),g!==v.i&&e.setStyleProperty(u,"color",v.i=g),D!==v.n&&e.setStyleProperty(u,"font-size",v.n=D),O!==v.s&&e.setStyleProperty(l,"gap",v.s=O),v},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),o})()}const Rt=t=>{const n=Date.now()-t;return n<5e3?"just now":n<6e4?`${Math.round(n/1e3)}s ago`:n<36e5?`${Math.round(n/6e4)}m ago`:`${Math.round(n/36e5)}h ago`};function At(t){const n=G.usePlugin(),[o,r]=h.createSignal(!1),[i,s]=h.createSignal(!1),u=async()=>{if(!(!t.sessionID||o())){r(!0);try{await n.client.rpc(Q).setSessionAuto({sessionID:t.sessionID,auto:!t.auto}),t.onChanged()}finally{r(!1)}}};return(()=>{var l=Oe(),v=l.firstChild,C=v.firstChild,y=C.nextSibling,f=v.nextSibling,x=f.firstChild;return l.addEventListener("mouseleave",()=>s(!1)),l.addEventListener("mouseenter",()=>s(!0)),l.$$click=()=>{u()},e.insert(y,()=>t.auto?"The router picks the model for you":"You keep your model; the router only observes"),e.effect(g=>{var D=o()||!t.sessionID,O=t.auto,U=t.auto?"Click to keep your current model":"Click to let the router choose",S=A.md,d=H.md,k=`1px solid ${t.auto?"transparent":a.border}`,P=t.auto?"rgba(8,145,178,0.10)":i()?a.surface:"transparent",w=a.text,R=o()||!t.sessionID?"default":"pointer",z=p.body,T=t.auto?a.brandTo:a.faint,M=p.caption,c=t.auto?ve:"rgba(255,255,255,0.14)",m=t.auto?"16px":"2px";return D!==g.e&&(l.disabled=g.e=D),O!==g.t&&e.setAttribute(l,"aria-pressed",g.t=O),U!==g.a&&e.setAttribute(l,"title",g.a=U),S!==g.o&&e.setStyleProperty(l,"gap",g.o=S),d!==g.i&&e.setStyleProperty(l,"border-radius",g.i=d),k!==g.n&&e.setStyleProperty(l,"border",g.n=k),P!==g.s&&e.setStyleProperty(l,"background",g.s=P),w!==g.h&&e.setStyleProperty(l,"color",g.h=w),R!==g.r&&e.setStyleProperty(l,"cursor",g.r=R),z!==g.d&&e.setStyleProperty(C,"font-size",g.d=z),T!==g.l&&e.setStyleProperty(y,"color",g.l=T),M!==g.u&&e.setStyleProperty(y,"font-size",g.u=M),c!==g.c&&e.setStyleProperty(f,"background",g.c=c),m!==g.w&&e.setStyleProperty(x,"left",g.w=m),g},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0,c:void 0,w:void 0}),l})()}function Ot(t){return e.createComponent(W,{label:"Last decision",get aside(){return e.createComponent(h.Show,{get when(){return t.view},get children(){var n=He(),o=n.firstChild,r=o.nextSibling;return r.nextSibling,e.insert(n,()=>t.view.eligibleCount,o),e.insert(n,()=>t.view.blockedCount,r),e.effect(i=>{var s=a.faint,u=p.caption;return s!==i.e&&e.setStyleProperty(n,"color",i.e=s),u!==i.t&&e.setStyleProperty(n,"font-size",i.t=u),i},{e:void 0,t:void 0}),n}})},get children(){return e.createComponent(h.Show,{get when(){return t.view},get fallback(){return e.createComponent(ne,{title:"No decision yet",body:"Send a prompt and the router will explain which model it chose, and why it beat the others."})},get children(){return[e.createComponent(V,{accent:!0,get children(){return[(()=>{var n=Ue(),o=n.firstChild;return e.insert(o,()=>t.view.chosen??"nothing eligible"),e.insert(n,e.createComponent(Y,{get tone(){return t.view.chosen?"good":"bad"},get children(){return t.view.chosen?"chosen":"blocked"}}),null),e.effect(r=>{var i=A.md,s=p.body,u=a.text;return i!==r.e&&e.setStyleProperty(n,"gap",r.e=i),s!==r.t&&e.setStyleProperty(o,"font-size",r.t=s),u!==r.a&&e.setStyleProperty(o,"color",r.a=u),r},{e:void 0,t:void 0,a:void 0}),n})(),(()=>{var n=Te();return e.insert(n,e.createComponent(ie,{label:"est. cost",get value(){return J(t.view.estimatedUsd)}}),null),e.insert(n,e.createComponent(ie,{label:"task",get value(){return`${t.view.taskKind} · T${t.view.taskTier}`}}),null),e.insert(n,e.createComponent(ie,{label:"context",get value(){return`${Math.round(t.view.contextTokens/1e3)}k`}}),null),e.effect(o=>e.setStyleProperty(n,"gap",A.xl)),n})(),e.createComponent(h.Show,{get when(){return t.view.reasons.length>0},get children(){var n=Fe(),o=n.firstChild;return e.insert(n,e.createComponent(h.For,{get each(){return t.view.reasons},children:r=>(()=>{var i=Be(),s=i.firstChild,u=s.nextSibling;return e.insert(u,r),e.effect(l=>{var v=A.sm,C=a.brandTo,y=p.caption,f=a.muted,x=p.caption;return v!==l.e&&e.setStyleProperty(i,"gap",l.e=v),C!==l.t&&e.setStyleProperty(s,"color",l.t=C),y!==l.a&&e.setStyleProperty(s,"font-size",l.a=y),f!==l.o&&e.setStyleProperty(u,"color",l.o=f),x!==l.i&&e.setStyleProperty(u,"font-size",l.i=x),l},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),i})()}),null),e.effect(r=>{var i=A.xs,s=a.faint,u=p.caption;return i!==r.e&&e.setStyleProperty(n,"padding-top",r.e=i),s!==r.t&&e.setStyleProperty(o,"color",r.t=s),u!==r.a&&e.setStyleProperty(o,"font-size",r.a=u),r},{e:void 0,t:void 0,a:void 0}),n}}),e.createComponent(h.Show,{get when(){return t.view.selfheal},get children(){var n=qe(),o=n.firstChild,r=o.nextSibling;return r.firstChild,e.insert(r,()=>t.view.selfheal,null),e.effect(i=>{var s=A.sm,u=A.xs,l=a.brandTo,v=p.caption,C=a.text,y=p.caption;return s!==i.e&&e.setStyleProperty(n,"gap",i.e=s),u!==i.t&&e.setStyleProperty(n,"padding-top",i.t=u),l!==i.a&&e.setStyleProperty(o,"color",i.a=l),v!==i.o&&e.setStyleProperty(o,"font-size",i.o=v),C!==i.i&&e.setStyleProperty(r,"color",i.i=C),y!==i.n&&e.setStyleProperty(r,"font-size",i.n=y),i},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),n}})]}}),e.createComponent(h.Show,{get when(){return t.view.rows.length>0},get children(){return[e.createComponent(se,{id:"candidates",size:"row",get open(){return t.expanded},get onToggle(){return t.onToggle},get hovered(){return t.hovered==="candidates"},get onHover(){return t.onHover},get aside(){return(()=>{var n=Ne(),o=n.firstChild;return e.insert(n,()=>t.view.rows.length,o),e.effect(r=>{var i=a.faint,s=p.caption;return i!==r.e&&e.setStyleProperty(n,"color",r.e=i),s!==r.t&&e.setStyleProperty(n,"font-size",r.t=s),r},{e:void 0,t:void 0}),n})()},get children(){var n=Le();return e.effect(o=>{var r=p.caption,i=a.muted;return r!==o.e&&e.setStyleProperty(n,"font-size",o.e=r),i!==o.t&&e.setStyleProperty(n,"color",o.t=i),o},{e:void 0,t:void 0}),n}}),e.createComponent(h.Show,{get when(){return t.expanded},get children(){var n=Ee();return e.insert(n,e.createComponent(h.For,{get each(){return t.view.rows},children:o=>(()=>{var r=Ge(),i=r.firstChild,s=i.firstChild,u=s.nextSibling,l=u.firstChild,v=l.nextSibling,C=i.nextSibling;return e.insert(s,()=>o.key),e.insert(l,()=>J(o.effectiveCost)),e.insert(v,()=>ue(o.successProbability*100)),e.insert(C,()=>o.reason,null),e.insert(C,(()=>{var y=e.memo(()=>o.adjustments.length>0);return()=>y()?` · ${o.adjustments.join(" · ")}`:""})(),null),e.effect(y=>{var f=H.sm,x=o.verdict==="chosen"?"rgba(8,145,178,0.08)":"transparent",g=A.md,D=p.caption,O=o.verdict==="blocked"?a.faint:a.text,U=A.md,S=a.muted,d=p.caption,k=a.faint,P=p.caption,w=a.faint,R=p.caption;return f!==y.e&&e.setStyleProperty(r,"border-radius",y.e=f),x!==y.t&&e.setStyleProperty(r,"background",y.t=x),g!==y.a&&e.setStyleProperty(i,"gap",y.a=g),D!==y.o&&e.setStyleProperty(s,"font-size",y.o=D),O!==y.i&&e.setStyleProperty(s,"color",y.i=O),U!==y.n&&e.setStyleProperty(u,"gap",y.n=U),S!==y.s&&e.setStyleProperty(l,"color",y.s=S),d!==y.h&&e.setStyleProperty(l,"font-size",y.h=d),k!==y.r&&e.setStyleProperty(v,"color",y.r=k),P!==y.d&&e.setStyleProperty(v,"font-size",y.d=P),w!==y.l&&e.setStyleProperty(C,"color",y.l=w),R!==y.u&&e.setStyleProperty(C,"font-size",y.u=R),y},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0}),r})()})),n}})]}})]}})}})}function Ut(t){const[n,o]=h.createSignal(!0),[r,i]=h.createSignal(!1),[s,u]=h.createSignal(void 0),l=()=>{const f=t.status;if(!f?.models)return[];const x=(f.quota??[]).filter(g=>!g.error).map(g=>g.providerID??"");return Ce({models:f.models,quota:f.quota??[],activeProviders:x})},v=()=>l().filter(f=>f.state==="active"),C=()=>l().filter(f=>f.state!=="active"),y=f=>(()=>{var x=Ke(),g=x.firstChild,D=g.firstChild,O=g.nextSibling,U=O.firstChild,S=U.firstChild;return e.insert(D,()=>f.group.label),e.insert(g,e.createComponent(h.Show,{get when(){return f.group.note},get children(){var d=We();return e.insert(d,()=>f.group.note),e.effect(k=>{var P=a.faint,w=p.caption;return P!==k.e&&e.setStyleProperty(d,"color",k.e=P),w!==k.t&&e.setStyleProperty(d,"font-size",k.t=w),k},{e:void 0,t:void 0}),d}}),null),e.insert(U,()=>f.group.approvedCount,S),e.insert(U,()=>f.group.totalCount,null),e.insert(O,e.createComponent(Y,{get tone(){return f.group.state==="active"?"brand":"neutral"},get children(){return f.group.state==="active"?"active":"off"}}),null),e.effect(d=>{var k=A.md,P=H.sm,w=`1px solid ${a.border}`,R=f.group.state==="active"?a.surface:"transparent",z=p.body,T=a.text,M=A.md,c=a.faint,m=p.caption;return k!==d.e&&e.setStyleProperty(x,"gap",d.e=k),P!==d.t&&e.setStyleProperty(x,"border-radius",d.t=P),w!==d.a&&e.setStyleProperty(x,"border",d.a=w),R!==d.o&&e.setStyleProperty(x,"background",d.o=R),z!==d.i&&e.setStyleProperty(D,"font-size",d.i=z),T!==d.n&&e.setStyleProperty(D,"color",d.n=T),M!==d.s&&e.setStyleProperty(O,"gap",d.s=M),c!==d.h&&e.setStyleProperty(U,"color",d.h=c),m!==d.r&&e.setStyleProperty(U,"font-size",d.r=m),d},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0}),x})();return e.createComponent(W,{label:"Providers",get aside(){return(()=>{var f=Qe(),x=f.firstChild;return e.insert(f,()=>v().length,x),e.insert(f,(()=>{var g=e.memo(()=>C().length>0);return()=>g()?` · ${C().length} off`:""})(),null),e.effect(g=>{var D=a.faint,O=p.caption;return D!==g.e&&e.setStyleProperty(f,"color",g.e=D),O!==g.t&&e.setStyleProperty(f,"font-size",g.t=O),g},{e:void 0,t:void 0}),f})()},get children(){return[e.createComponent(se,{id:"providers",get open(){return n()},onToggle:()=>o(f=>!f),get hovered(){return s()==="providers"},onHover:u,get aside(){return(()=>{var f=_();return e.insert(f,()=>n()?"hide":"show"),e.effect(x=>{var g=a.faint,D=p.caption;return g!==x.e&&e.setStyleProperty(f,"color",x.e=g),D!==x.t&&e.setStyleProperty(f,"font-size",x.t=D),x},{e:void 0,t:void 0}),f})()},get children(){var f=Ye();return e.insert(f,()=>n()?"Configured":"Show configured"),e.effect(x=>{var g=p.caption,D=a.muted;return g!==x.e&&e.setStyleProperty(f,"font-size",x.e=g),D!==x.t&&e.setStyleProperty(f,"color",x.t=D),x},{e:void 0,t:void 0}),f}}),e.createComponent(h.Show,{get when(){return n()},get children(){return[e.createComponent(h.For,{get each(){return v()},children:f=>e.createComponent(y,{group:f})}),e.createComponent(h.Show,{get when(){return C().length>0},get children(){return[e.createComponent(se,{id:"not-configured",get open(){return r()},onToggle:()=>i(f=>!f),get hovered(){return s()==="not-configured"},onHover:u,get aside(){return(()=>{var f=_();return e.insert(f,()=>C().length),e.effect(x=>{var g=a.faint,D=p.caption;return g!==x.e&&e.setStyleProperty(f,"color",x.e=g),D!==x.t&&e.setStyleProperty(f,"font-size",x.t=D),x},{e:void 0,t:void 0}),f})()},get children(){var f=Je();return e.effect(x=>{var g=p.caption,D=a.muted;return g!==x.e&&e.setStyleProperty(f,"font-size",x.e=g),D!==x.t&&e.setStyleProperty(f,"color",x.t=D),x},{e:void 0,t:void 0}),f}}),e.createComponent(h.Show,{get when(){return r()},get children(){return e.createComponent(h.For,{get each(){return C()},children:f=>e.createComponent(y,{group:f})})}})]}})]}})]}})}function Tt(t){return e.createComponent(W,{label:"Allowances",get aside(){return(()=>{var n=Ve(),o=n.firstChild;return e.insert(n,()=>t.providers.length,o),e.insert(n,()=>t.providers.length===1?"":"s",null),e.effect(r=>{var i=a.faint,s=p.caption;return i!==r.e&&e.setStyleProperty(n,"color",r.e=i),s!==r.t&&e.setStyleProperty(n,"font-size",r.t=s),r},{e:void 0,t:void 0}),n})()},get children(){return e.createComponent(h.Show,{get when(){return t.providers.length>0},get fallback(){return e.createComponent(ne,{title:"No quota data",body:"No provider has reported an allowance yet."})},get children(){return e.createComponent(h.For,{get each(){return t.providers},children:n=>e.createComponent(V,{get children(){return[(()=>{var o=Xe(),r=o.firstChild,i=r.nextSibling;return e.insert(r,()=>n.label),e.insert(i,e.createComponent(h.Show,{get when(){return n.stale},get children(){return e.createComponent(Y,{tone:"warn",children:"stale"})}}),null),e.insert(i,e.createComponent(h.Show,{get when(){return n.exhausted},get children(){return e.createComponent(Y,{tone:"bad",get children(){return[e.memo(()=>n.exhaustedWindow)," spent"]}})}}),null),e.insert(i,e.createComponent(h.Show,{get when(){return e.memo(()=>!n.exhausted)()&&!n.stale},get children(){return e.createComponent(Y,{get tone(){return n.source==="provider"?"good":"neutral"},get children(){return n.source==="provider"?"verified":"estimated"}})}}),null),e.effect(s=>{var u=A.md,l=p.body,v=n.error?a.bad:a.text,C=A.xs;return u!==s.e&&e.setStyleProperty(o,"gap",s.e=u),l!==s.t&&e.setStyleProperty(r,"font-size",s.t=l),v!==s.a&&e.setStyleProperty(r,"color",s.a=v),C!==s.o&&e.setStyleProperty(i,"gap",s.o=C),s},{e:void 0,t:void 0,a:void 0,o:void 0}),o})(),(()=>{var o=Ze();return e.insert(o,e.createComponent(h.For,{get each(){return n.windows},children:r=>(()=>{var i=et(),s=i.firstChild,u=s.nextSibling;return e.insert(s,()=>r.label),e.insert(i,e.createComponent(h.Show,{get when(){return r.reported},get fallback(){return tt()},get children(){return e.createComponent(jt,{get usedPct(){return r.usedPct},get exhausted(){return r.exceeded}})}}),u),e.insert(u,(()=>{var l=e.memo(()=>!!r.reported);return()=>l()?pe(r):"—"})(),null),e.insert(u,(()=>{var l=e.memo(()=>!!r.resetLabel);return()=>l()?` · ${r.resetLabel}`:""})(),null),e.effect(l=>{var v=A.md,C=a.faint,y=p.caption,f=r.exceeded?a.bad:r.reported?a.muted:a.faint,x=p.caption;return v!==l.e&&e.setStyleProperty(i,"gap",l.e=v),C!==l.t&&e.setStyleProperty(s,"color",l.t=C),y!==l.a&&e.setStyleProperty(s,"font-size",l.a=y),f!==l.o&&e.setStyleProperty(u,"color",l.o=f),x!==l.i&&e.setStyleProperty(u,"font-size",l.i=x),l},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),i})()})),o})(),e.createComponent(h.Show,{get when(){return n.pools.length>0},get children(){var o=_e();return e.insert(o,e.createComponent(h.For,{get each(){return n.pools},children:r=>(()=>{var i=rt(),s=i.firstChild,u=s.nextSibling,l=u.firstChild;return e.insert(s,()=>r.label),e.insert(u,()=>J(r.remainingUsd),l),e.insert(u,()=>J(r.monthlyUsd),null),e.effect(v=>{var C=A.md,y=a.faint,f=p.caption,x=a.muted,g=p.caption;return C!==v.e&&e.setStyleProperty(i,"gap",v.e=C),y!==v.t&&e.setStyleProperty(s,"color",v.t=y),f!==v.a&&e.setStyleProperty(s,"font-size",v.a=f),x!==v.o&&e.setStyleProperty(u,"color",v.o=x),g!==v.i&&e.setStyleProperty(u,"font-size",v.i=g),v},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),i})()})),e.effect(r=>e.setStyleProperty(o,"padding-top",A.xs)),o}}),e.createComponent(h.Show,{get when(){return n.caveat},get children(){var o=re();return e.insert(o,()=>n.caveat),e.effect(r=>{var i=a.warn,s=p.caption;return i!==r.e&&e.setStyleProperty(o,"color",r.e=i),s!==r.t&&e.setStyleProperty(o,"font-size",r.t=s),r},{e:void 0,t:void 0}),o}}),e.createComponent(h.Show,{get when(){return n.error},get children(){var o=_();return e.insert(o,()=>n.error),e.effect(r=>{var i=a.bad,s=p.caption;return i!==r.e&&e.setStyleProperty(o,"color",r.e=i),s!==r.t&&e.setStyleProperty(o,"font-size",r.t=s),r},{e:void 0,t:void 0}),o}})]}})})}})}})}function Ft(t){const n=G.usePlugin(),[o,r]=h.createSignal(""),[i,s]=h.createSignal(void 0),[u,l]=h.createSignal(void 0),[v,C]=h.createSignal(!1),[y,f]=h.createSignal(!1),[x,g]=h.createSignal(!1),D=()=>{r(""),s(void 0)},O=async S=>{if(!(!o().trim()||v())){C(!0);try{const d=await n.client.rpc(Q).recordPlanPage({page:o(),confirm:S});l({ok:d?.ok!==!1,text:d?.message??""}),d?.ok&&!S?s(d.preview):d?.ok&&S&&(D(),t.onChanged())}catch(d){l({ok:!1,text:d instanceof Error?d.message:String(d)})}finally{C(!1)}}},U=(S,d,k)=>(()=>{var P=nt();return e.addEventListener(P,"click",k,!0),P.disabled=!d,e.setStyleProperty(P,"cursor",d?"pointer":"default"),e.insert(P,S),e.effect(w=>{var R=H.sm,z=`1px solid ${d?a.borderStrong:a.border}`,T=d?a.raised:"transparent",M=d?a.text:a.faint,c=p.caption,m=d?"inherit":`${p.caption} inherit`;return R!==w.e&&e.setStyleProperty(P,"border-radius",w.e=R),z!==w.t&&e.setStyleProperty(P,"border",w.t=z),T!==w.a&&e.setStyleProperty(P,"background",w.a=T),M!==w.o&&e.setStyleProperty(P,"color",w.o=M),c!==w.i&&e.setStyleProperty(P,"font-size",w.i=c),m!==w.n&&e.setStyleProperty(P,"font",w.n=m),w},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),P})();return e.createComponent(W,{label:"Account reading",get children(){return[(()=>{var S=ot(),d=S.firstChild,k=d.nextSibling;return e.effect(P=>{var w=a.faint,R=p.caption,z=a.text;return w!==P.e&&e.setStyleProperty(S,"color",P.e=w),R!==P.t&&e.setStyleProperty(S,"font-size",P.t=R),z!==P.a&&e.setStyleProperty(k,"color",P.a=z),P},{e:void 0,t:void 0,a:void 0}),S})(),(()=>{var S=it();return S.addEventListener("blur",()=>f(!1)),S.addEventListener("focus",()=>f(!0)),S.$$input=d=>{r(d.currentTarget.value),s(void 0)},e.effect(d=>{var k=H.sm,P=`1px solid ${y()?a.brandTo:a.border}`,w=a.text,R=p.caption;return k!==d.e&&e.setStyleProperty(S,"border-radius",d.e=k),P!==d.t&&e.setStyleProperty(S,"border",d.t=P),w!==d.a&&e.setStyleProperty(S,"color",d.a=w),R!==d.o&&e.setStyleProperty(S,"font-size",d.o=R),d},{e:void 0,t:void 0,a:void 0,o:void 0}),e.effect(()=>S.value=o()),S})(),e.createComponent(h.Show,{get when(){return i()},get children(){return e.createComponent(V,{get children(){return[(()=>{var S=at();return e.insert(S,()=>i().summary),e.effect(d=>{var k=a.text,P=p.caption;return k!==d.e&&e.setStyleProperty(S,"color",d.e=k),P!==d.t&&e.setStyleProperty(S,"font-size",d.t=P),d},{e:void 0,t:void 0}),S})(),e.createComponent(h.Show,{get when(){return i().missing?.length>0},get children(){var S=st();return S.firstChild,e.insert(S,()=>i().missing.join(", "),null),e.effect(d=>{var k=a.warn,P=p.caption;return k!==d.e&&e.setStyleProperty(S,"color",d.e=k),P!==d.t&&e.setStyleProperty(S,"font-size",d.t=P),d},{e:void 0,t:void 0}),S}}),e.createComponent(h.Show,{get when(){return i().reconciliation},get children(){return[(()=>{var S=re();return e.insert(S,()=>i().reconciliation.summary),e.effect(d=>{var k=i().reconciliation.differ>0?a.warn:a.good,P=p.caption;return k!==d.e&&e.setStyleProperty(S,"color",d.e=k),P!==d.t&&e.setStyleProperty(S,"font-size",d.t=P),d},{e:void 0,t:void 0}),S})(),e.createComponent(h.For,{get each(){return i().reconciliation.rows.filter(S=>S.verdict==="differs")},children:S=>(()=>{var d=dt(),k=d.firstChild,P=k.nextSibling,w=P.nextSibling,R=w.nextSibling,z=R.nextSibling,T=z.nextSibling;return T.nextSibling,e.insert(d,()=>S.modelName,k),e.insert(d,()=>S.chargedUsd.toFixed(2),P),e.insert(d,()=>S.impliedMultiplier?.toFixed(2),R),e.insert(d,()=>S.catalogMultiplier?.toFixed(2),T),e.effect(M=>{var c=a.faint,m=p.caption;return c!==M.e&&e.setStyleProperty(d,"color",M.e=c),m!==M.t&&e.setStyleProperty(d,"font-size",M.t=m),M},{e:void 0,t:void 0}),d})()})]}})]}})}}),(()=>{var S=lt();return S.addEventListener("mouseleave",()=>g(!1)),S.addEventListener("mouseenter",()=>g(!0)),e.insert(S,e.createComponent(h.Show,{get when(){return i()},get fallback(){return U(v()?"Reading…":"Read page",!!o().trim()&&!v(),()=>{O(!1)})},get children(){return[e.createComponent(h.Show,{get when(){return i().kind==="allowance"},get children(){return U(v()?"Saving…":"Use this",!v(),()=>{O(!0)})}}),e.memo(()=>U(i().kind==="usage"?"Done":"Cancel",!v(),D))]}})),e.effect(d=>e.setStyleProperty(S,"gap",A.sm)),S})(),e.createComponent(h.Show,{get when(){return u()},get children(){var S=re();return e.insert(S,()=>u().text),e.effect(d=>{var k=u().ok?a.good:a.bad,P=p.caption;return k!==d.e&&e.setStyleProperty(S,"color",d.e=k),P!==d.t&&e.setStyleProperty(S,"font-size",d.t=P),d},{e:void 0,t:void 0}),S}})]}})}function qt(){const t=G.usePlugin(),[n,o]=h.createSignal("idle"),[r,i]=h.createSignal(!1),s="https://open-design.ai/cloud/dashboard",u=()=>{if(n()!=="opening"){o("opening");try{t.system.openExternal(s),setTimeout(()=>o("idle"),900)}catch{o("failed")}}};return(()=>{var l=vt(),v=l.firstChild,C=v.firstChild;return v.addEventListener("mouseleave",()=>i(!1)),v.addEventListener("mouseenter",()=>i(!0)),v.$$click=u,e.insert(C,()=>n()==="opening"?"◌":"↗"),e.insert(v,()=>n()==="opening"?"Opening…":"Open Plan & balance",null),e.insert(l,e.createComponent(h.Show,{get when(){return n()==="opening"},get children(){var y=ct();return e.effect(f=>{var x=a.faint,g=p.caption;return x!==f.e&&e.setStyleProperty(y,"color",f.e=x),g!==f.t&&e.setStyleProperty(y,"font-size",f.t=g),f},{e:void 0,t:void 0}),y}}),null),e.insert(l,e.createComponent(h.Show,{get when(){return n()==="failed"},get children(){var y=ut(),f=y.firstChild,x=f.nextSibling;return e.effect(g=>{var D=a.warn,O=p.caption,U=a.text;return D!==g.e&&e.setStyleProperty(y,"color",g.e=D),O!==g.t&&e.setStyleProperty(y,"font-size",g.t=O),U!==g.a&&e.setStyleProperty(x,"color",g.a=U),g},{e:void 0,t:void 0,a:void 0}),y}}),null),e.effect(y=>{var f=A.xs,x=n()==="opening",g=n()==="opening",D=H.sm,O=`1px solid ${r()?a.brandTo:a.borderStrong}`,U=r()?"rgba(8,145,178,0.12)":"transparent",S=a.brandTo,d=p.caption,k=n()==="opening"?"default":"pointer",P=r()?"underline":"none";return f!==y.e&&e.setStyleProperty(l,"gap",y.e=f),x!==y.t&&(v.disabled=y.t=x),g!==y.a&&e.setAttribute(v,"aria-busy",y.a=g),D!==y.o&&e.setStyleProperty(v,"border-radius",y.o=D),O!==y.i&&e.setStyleProperty(v,"border",y.i=O),U!==y.n&&e.setStyleProperty(v,"background",y.n=U),S!==y.s&&e.setStyleProperty(v,"color",y.s=S),d!==y.h&&e.setStyleProperty(v,"font-size",y.h=d),k!==y.r&&e.setStyleProperty(v,"cursor",y.r=k),P!==y.d&&e.setStyleProperty(v,"text-decoration",y.d=P),y},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0}),l})()}function Lt(t){const n=G.usePlugin(),[o,r]=h.createSignal(!1),[i,s]=h.createSignal(void 0),[u,l]=h.createSignal(""),[v,C]=h.createSignal(!1),[y,f]=h.createSignal(!1),[x,g]=h.createSignal(!1),[D,O]=h.createSignal(void 0),U=()=>(t.state?.providers??[]).some(w=>w.providerID==="opendesign"&&w.found),S=async w=>{if(!(!u().trim()||y())){f(!0);try{const R=await n.client.rpc(Q).recordPlanPage({page:u(),confirm:!0});O({ok:R?.ok!==!1,text:R?.message??""}),R?.ok!==!1&&C(!0)}catch(R){O({ok:!1,text:R instanceof Error?R.message:String(R)})}finally{f(!1)}}},d=async()=>{if(!o()){r(!0);try{await n.client.rpc(Q).completeOnboarding({}),t.onDone()}finally{r(!1)}}},k=()=>(t.state?.providers??[]).filter(w=>w.found),P=()=>(t.state?.providers??[]).filter(w=>!w.found);return(()=>{var w=wt(),R=w.firstChild,z=R.firstChild,T=z.nextSibling,M=R.nextSibling;return e.insert(R,e.createComponent(le,{size:44}),z),e.insert(w,e.createComponent(W,{label:"Found on this machine",first:!0,get children(){return e.createComponent(h.Show,{get when(){return k().length>0},get fallback(){return e.createComponent(ne,{title:"No provider credentials found",body:"Add a key for OpenCode Go, Command Code or OpenDesign in OpenCode, then reopen this panel."})},get children(){return e.createComponent(h.For,{get each(){return k()},children:c=>(()=>{var m=Ct(),$=m.firstChild,b=$.firstChild;return e.insert(b,()=>c.label),e.insert($,e.createComponent(h.Show,{get when(){return c.source},get children(){var I=_();return e.insert(I,()=>c.source),e.effect(j=>{var q=a.faint,L=p.caption;return q!==j.e&&e.setStyleProperty(I,"color",j.e=q),L!==j.t&&e.setStyleProperty(I,"font-size",j.t=L),j},{e:void 0,t:void 0}),I}}),null),e.insert(m,e.createComponent(Y,{get tone(){return c.enabled?"good":"neutral"},get children(){return c.enabled?"enabled":"off"}}),null),e.effect(I=>{var j=A.md,q=H.sm,L=`1px solid ${a.border}`,E=a.surface,B=p.body;return j!==I.e&&e.setStyleProperty(m,"gap",I.e=j),q!==I.t&&e.setStyleProperty(m,"border-radius",I.t=q),L!==I.a&&e.setStyleProperty(m,"border",I.a=L),E!==I.o&&e.setStyleProperty(m,"background",I.o=E),B!==I.i&&e.setStyleProperty(b,"font-size",I.i=B),I},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),m})()})}})}}),M),e.insert(w,e.createComponent(W,{label:"Learned from your history",get aside(){return(()=>{var c=_();return e.insert(c,()=>t.state?.hasHistory?"imported":"none yet"),e.effect(m=>{var $=a.faint,b=p.caption;return $!==m.e&&e.setStyleProperty(c,"color",m.e=$),b!==m.t&&e.setStyleProperty(c,"font-size",m.t=b),m},{e:void 0,t:void 0}),c})()},get children(){return e.createComponent(h.Show,{get when(){return t.state?.hasHistory},get fallback(){return e.createComponent(ne,{title:"Nothing to import yet",body:"Once you have used OpenCode, the router reads that history so day one is not a guess."})},get children(){return e.createComponent(V,{accent:!0,get children(){return[(()=>{var c=yt(),m=c.firstChild,$=m.nextSibling,b=$.nextSibling,I=b.firstChild,j=I.nextSibling;return j.nextSibling,e.insert(m,()=>t.state.historyImported),e.insert(b,()=>t.state.historyImported===1?"":"s",j),e.effect(q=>{var L=p.body,E=a.muted;return L!==q.e&&e.setStyleProperty(c,"font-size",q.e=L),E!==q.t&&e.setStyleProperty(b,"color",q.t=E),q},{e:void 0,t:void 0}),c})(),(()=>{var c=ft();return e.effect(m=>{var $=a.faint,b=p.caption;return $!==m.e&&e.setStyleProperty(c,"color",m.e=$),b!==m.t&&e.setStyleProperty(c,"font-size",m.t=b),m},{e:void 0,t:void 0}),c})()]}})}})}}),M),e.insert(w,e.createComponent(W,{label:"What it will do",get children(){var c=gt();return e.insert(c,e.createComponent(h.For,{each:["Pick the cheapest model that can actually do the job, and say why.","Stop before an allowance runs out, not after a request fails.","Count what you spend here, and never guess silently."],children:m=>(()=>{var $=kt(),b=$.firstChild,I=b.nextSibling;return e.insert(I,m),e.effect(j=>{var q=A.sm,L=a.brandTo,E=p.caption,B=a.muted,K=p.caption;return q!==j.e&&e.setStyleProperty($,"gap",j.e=q),L!==j.t&&e.setStyleProperty(b,"color",j.t=L),E!==j.a&&e.setStyleProperty(b,"font-size",j.a=E),B!==j.o&&e.setStyleProperty(I,"color",j.o=B),K!==j.i&&e.setStyleProperty(I,"font-size",j.i=K),j},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),$})()})),c}}),M),e.insert(w,e.createComponent(h.Show,{get when(){return U()},get children(){return e.createComponent(W,{label:"One thing it cannot see",get aside(){return e.createComponent(Y,{tone:"warn",children:"needed for accuracy"})},get children(){return e.createComponent(V,{get children(){return[(()=>{var c=mt();return e.effect(m=>e.setStyleProperty(c,"font-size",p.body)),c})(),(()=>{var c=pt();return e.effect(m=>{var $=a.muted,b=p.caption;return $!==m.e&&e.setStyleProperty(c,"color",m.e=$),b!==m.t&&e.setStyleProperty(c,"font-size",m.t=b),m},{e:void 0,t:void 0}),c})(),(()=>{var c=ht(),m=c.firstChild,$=m.nextSibling;return e.effect(b=>{var I=a.muted,j=p.caption,q=a.text;return I!==b.e&&e.setStyleProperty(c,"color",b.e=I),j!==b.t&&e.setStyleProperty(c,"font-size",b.t=j),q!==b.a&&e.setStyleProperty($,"color",b.a=q),b},{e:void 0,t:void 0,a:void 0}),c})(),e.createComponent(h.Show,{get when(){return!v()},get children(){return[e.createComponent(qt,{}),(()=>{var c=bt();return c.$$input=m=>l(m.currentTarget.value),e.effect(m=>{var $=H.sm,b=`1px solid ${x()?a.brandTo:a.border}`,I=a.text,j=p.caption;return $!==m.e&&e.setStyleProperty(c,"border-radius",m.e=$),b!==m.t&&e.setStyleProperty(c,"border",m.t=b),I!==m.a&&e.setStyleProperty(c,"color",m.a=I),j!==m.o&&e.setStyleProperty(c,"font-size",m.o=j),m},{e:void 0,t:void 0,a:void 0,o:void 0}),e.effect(()=>c.value=u()),c})(),(()=>{var c=St(),m=c.firstChild,$=m.nextSibling;return m.$$click=()=>{S()},e.insert(m,()=>y()?"Reading…":"Check it"),e.effect(b=>{var I=A.sm,j=!u().trim()||y(),q=H.sm,L=`1px solid ${a.borderStrong}`,E=u().trim()?a.raised:"transparent",B=u().trim()?a.text:a.faint,K=p.caption,X=u().trim()?"pointer":"default",Z=a.faint,de=p.caption;return I!==b.e&&e.setStyleProperty(c,"gap",b.e=I),j!==b.t&&(m.disabled=b.t=j),q!==b.a&&e.setStyleProperty(m,"border-radius",b.a=q),L!==b.o&&e.setStyleProperty(m,"border",b.o=L),E!==b.i&&e.setStyleProperty(m,"background",b.i=E),B!==b.n&&e.setStyleProperty(m,"color",b.n=B),K!==b.s&&e.setStyleProperty(m,"font-size",b.s=K),X!==b.h&&e.setStyleProperty(m,"cursor",b.h=X),Z!==b.r&&e.setStyleProperty($,"color",b.r=Z),de!==b.d&&e.setStyleProperty($,"font-size",b.d=de),b},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0}),c})(),e.createComponent(h.Show,{get when(){return D()},children:c=>(()=>{var m=re();return e.insert(m,()=>c().text),e.effect($=>{var b=c().ok?a.good:a.bad,I=p.caption;return b!==$.e&&e.setStyleProperty(m,"color",$.e=b),I!==$.t&&e.setStyleProperty(m,"font-size",$.t=I),$},{e:void 0,t:void 0}),m})()})]}}),e.createComponent(h.Show,{get when(){return v()},get children(){var c=xt();return e.effect(m=>{var $=a.good,b=p.caption;return $!==m.e&&e.setStyleProperty(c,"color",m.e=$),b!==m.t&&e.setStyleProperty(c,"font-size",m.t=b),m},{e:void 0,t:void 0}),c}})]}})}})}}),M),e.insert(w,e.createComponent(h.Show,{get when(){return e.memo(()=>P().length>0)()&&!U()},get children(){return e.createComponent(W,{label:"Not needed yet",get children(){var c=Pt(),m=c.firstChild,$=m.nextSibling;return $.nextSibling,e.insert(c,()=>P().length,m),e.insert(c,()=>P().length===1?"":"s",$),e.effect(b=>{var I=a.faint,j=p.caption;return I!==b.e&&e.setStyleProperty(c,"color",b.e=I),j!==b.t&&e.setStyleProperty(c,"font-size",b.t=j),b},{e:void 0,t:void 0}),c}})}}),M),M.addEventListener("mouseleave",()=>s(void 0)),M.addEventListener("mouseenter",()=>s("done")),M.$$click=()=>{d()},e.setStyleProperty(M,"background",ve),e.insert(M,()=>o()?"Starting…":"Start routing"),e.effect(c=>{var m=A.lg,$=a.text,b=p.body,I=A.sm,j=p.display,q=a.muted,L=p.caption,E=o(),B=H.md,K=p.body,X=o()?"default":"pointer",Z=o()?.7:i()==="done"?.92:1;return m!==c.e&&e.setStyleProperty(w,"gap",c.e=m),$!==c.t&&e.setStyleProperty(w,"color",c.t=$),b!==c.a&&e.setStyleProperty(w,"font-size",c.a=b),I!==c.o&&e.setStyleProperty(R,"gap",c.o=I),j!==c.i&&e.setStyleProperty(z,"font-size",c.i=j),q!==c.n&&e.setStyleProperty(T,"color",c.n=q),L!==c.s&&e.setStyleProperty(T,"font-size",c.s=L),E!==c.h&&(M.disabled=c.h=E),B!==c.r&&e.setStyleProperty(M,"border-radius",c.r=B),K!==c.d&&e.setStyleProperty(M,"font-size",c.d=K),X!==c.l&&e.setStyleProperty(M,"cursor",c.l=X),Z!==c.u&&e.setStyleProperty(M,"opacity",c.u=Z),c},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0,d:void 0,l:void 0,u:void 0}),w})()}function Et(t){const n=G.usePlugin(),[o,r]=h.createSignal(void 0),[i,s]=h.createSignal(void 0),[u,l]=h.createSignal(void 0),[v,C]=h.createSignal(!1),[y,f]=h.createSignal(void 0),[x,g]=h.createSignal(void 0),D=async()=>{const d=t.sessionID;if(d)try{const k=await n.client.rpc(Q).status({sessionID:d});r(k),l(Date.now()),s(void 0)}catch(k){s(k instanceof Error?k.message:String(k))}};h.onMount(()=>{D(),(async()=>{try{const k=await Promise.race([n.client.rpc(Q).onboarding({}),new Promise(P=>setTimeout(()=>P(void 0),1500))]);k?.firstRun&&g(k)}catch{}})();const d=setInterval(()=>{D()},3e3);h.onCleanup(()=>clearInterval(d))});const O=()=>Pe(o()?.lastDecision),U=()=>(o()?.quota??[]).map(d=>me(d)),S=()=>U().some(d=>d.source==="estimate");return e.createComponent(h.Show,{get when(){return!x()},get fallback(){return e.createComponent(Lt,{get state(){return x()},onDone:()=>{g(void 0),D()}})},get children(){var d=$t(),k=d.firstChild,P=k.firstChild,w=P.firstChild,R=w.nextSibling;return e.insert(k,e.createComponent(Mt,{get runtime(){return o()?.runtime??"connecting"},get mode(){return o()?.mode??"—"}}),P),e.insert(w,(()=>{var z=e.memo(()=>!!o()?.current);return()=>z()?`${o().current.providerID}/${o().current.id}`:"no model yet"})()),e.insert(R,(()=>{var z=e.memo(()=>!!u());return()=>z()?Rt(u()):"connecting…"})()),e.insert(d,e.createComponent(h.Show,{get when(){return i()},get children(){return e.createComponent(V,{get children(){return[(()=>{var z=zt();return z.firstChild,e.insert(z,i,null),e.effect(T=>{var M=a.bad,c=p.caption;return M!==T.e&&e.setStyleProperty(z,"color",T.e=M),c!==T.t&&e.setStyleProperty(z,"font-size",T.t=c),T},{e:void 0,t:void 0}),z})(),(()=>{var z=Dt();return e.effect(T=>{var M=a.faint,c=p.caption;return M!==T.e&&e.setStyleProperty(z,"color",T.e=M),c!==T.t&&e.setStyleProperty(z,"font-size",T.t=c),T},{e:void 0,t:void 0}),z})()]}})}}),null),e.insert(d,e.createComponent(At,{get sessionID(){return t.sessionID},get auto(){return(o()?.runtime??"automatic")==="automatic"},onChanged:()=>{D()}}),null),e.insert(d,e.createComponent(Ot,{get view(){return O()},get expanded(){return v()},onToggle:()=>C(z=>!z),get hovered(){return y()},onHover:f}),null),e.insert(d,e.createComponent(Tt,{get providers(){return U()}}),null),e.insert(d,e.createComponent(h.Show,{get when(){return S()},get children(){return e.createComponent(Ft,{onChanged:()=>{D()}})}}),null),e.insert(d,e.createComponent(Ut,{get status(){return o()}}),null),e.effect(z=>{var T=A.lg,M=a.text,c=p.body,m=A.md,$=p.caption,b=o()?.current?a.muted:a.faint,I=a.faint,j=p.caption;return T!==z.e&&e.setStyleProperty(d,"gap",z.e=T),M!==z.t&&e.setStyleProperty(d,"color",z.t=M),c!==z.a&&e.setStyleProperty(d,"font-size",z.a=c),m!==z.o&&e.setStyleProperty(P,"gap",z.o=m),$!==z.i&&e.setStyleProperty(w,"font-size",z.i=$),b!==z.n&&e.setStyleProperty(w,"color",z.n=b),I!==z.s&&e.setStyleProperty(R,"color",z.s=I),j!==z.h&&e.setStyleProperty(R,"font-size",z.h=j),z},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0}),d}})}const Ht={id:"router",get title(){return"Router"},closable:"hover"},Bt=G.Plugin.define({i18n:{en:{"command.open":"Open Smart Router","panel.title":"Router"}}}),Nt=G.Plugin.define({...Bt,setup(t){t.add(G.Command,()=>({id:"panel",title:t.t("command.open"),group:"Smart Router",bind:"mod+shift+r",slash:{name:"router-gui"},run:()=>{const s=t.sessions.current();s&&t.layout.toggle(`${t.id}:router`,s)}})),t.add(G.Panel,{id:"router",region:"side",list:s=>s.open.includes("router")?[Ht]:[],render:s=>e.createComponent(Et,{get sessionID(){return s.session.id}})});const n=`${t.id}:router`,o=new Set,i=setInterval(()=>{try{if(!t.layout.ready())return;const s=t.sessions.current();if(!s||o.has(s.key))return;if(t.layout.state(n,s)!=="closed"){o.add(s.key);return}o.add(s.key),t.layout.open(n,s)}catch{}},800);return t.add(G.Slot,{at:"window.bottom",render:()=>(()=>{var s=It(),u=s.firstChild;return e.insert(s,e.createComponent(le,{size:12}),u),e.effect(l=>{var v=p.caption,C=a.faint;return v!==l.e&&e.setStyleProperty(u,"font-size",l.e=v),C!==l.t&&e.setStyleProperty(u,"color",l.t=C),l},{e:void 0,t:void 0}),s})()}),()=>{clearInterval(i)}}});e.delegateEvents(["click","input"]);exports.default=Nt;