cartethyia 2.7.1 → 2.7.2

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 (91) hide show
  1. package/dist/dashboard/assets/{BannedPage-D-J75hBM.js → BannedPage-XaUmiBrC.js} +1 -1
  2. package/dist/dashboard/assets/BannedPage-XaUmiBrC.js.gz +0 -0
  3. package/dist/dashboard/assets/{CliToolDetailPage-CVe6RaBH.js → CliToolDetailPage-CqD7QiLM.js} +1 -1
  4. package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolsPage-Dd8ZSamp.js → CliToolsPage-0XUo4UMn.js} +1 -1
  6. package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js.gz +0 -0
  7. package/dist/dashboard/assets/{CombosPage-QoJ6foxo.js → CombosPage-CXGS_Ct-.js} +1 -1
  8. package/dist/dashboard/assets/CombosPage-CXGS_Ct-.js.gz +0 -0
  9. package/dist/dashboard/assets/{ConsoleLogPage-DpNRay4C.js → ConsoleLogPage-DGnGNYnM.js} +1 -1
  10. package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js.gz +0 -0
  11. package/dist/dashboard/assets/{CustomizationPage-CKUFTcW4.js → CustomizationPage-DAG5J9EY.js} +1 -1
  12. package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js.gz +0 -0
  13. package/dist/dashboard/assets/{HealthEventsModal-CzSLiDzr.js → HealthEventsModal-BKtAPYVF.js} +1 -1
  14. package/dist/dashboard/assets/HealthEventsModal-BKtAPYVF.js.gz +0 -0
  15. package/dist/dashboard/assets/{LoginPage-DubdQcvX.js → LoginPage-BdmRLnq2.js} +1 -1
  16. package/dist/dashboard/assets/LoginPage-BdmRLnq2.js.gz +0 -0
  17. package/dist/dashboard/assets/{OverviewPage-DuWzAQFL.js → OverviewPage-CqMxibJB.js} +1 -1
  18. package/dist/dashboard/assets/OverviewPage-CqMxibJB.js.gz +0 -0
  19. package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js +4 -0
  20. package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js.gz +0 -0
  21. package/dist/dashboard/assets/{ProvidersPage-Bwotu8UJ.js → ProvidersPage-B9uWu4Nz.js} +1 -1
  22. package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js.gz +0 -0
  23. package/dist/dashboard/assets/{ProxyPage-D7hpWbg9.js → ProxyPage-BoWOhpDO.js} +1 -1
  24. package/dist/dashboard/assets/{ProxyPage-D7hpWbg9.js.gz → ProxyPage-BoWOhpDO.js.gz} +0 -0
  25. package/dist/dashboard/assets/{QuotaPage-ATpaxrbl.js → QuotaPage-7P2n--Fv.js} +1 -1
  26. package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js.gz +0 -0
  27. package/dist/dashboard/assets/{SettingsPage-CETophpx.js → SettingsPage-CxZ1fTkN.js} +1 -1
  28. package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js.gz +0 -0
  29. package/dist/dashboard/assets/{SetupPage-BdgECjqq.js → SetupPage-Co12Zzaw.js} +1 -1
  30. package/dist/dashboard/assets/SetupPage-Co12Zzaw.js.gz +0 -0
  31. package/dist/dashboard/assets/{SortableList-CAK-EN9z.js → SortableList-Dqf4zpS-.js} +1 -1
  32. package/dist/dashboard/assets/SortableList-Dqf4zpS-.js.gz +0 -0
  33. package/dist/dashboard/assets/{StudioPage-B7W2_RhT.js → StudioPage-Byj2lAEm.js} +1 -1
  34. package/dist/dashboard/assets/StudioPage-Byj2lAEm.js.gz +0 -0
  35. package/dist/dashboard/assets/{UsagePage-6T4EFDjW.js → UsagePage-CTkLAuRc.js} +1 -1
  36. package/dist/dashboard/assets/UsagePage-CTkLAuRc.js.gz +0 -0
  37. package/dist/dashboard/assets/{entry-BLBLxX0h.js → entry-ClCMCWWQ.js} +3 -3
  38. package/dist/dashboard/assets/entry-ClCMCWWQ.js.gz +0 -0
  39. package/dist/dashboard/assets/{formatters-mpBPqAQ8.js → formatters-CWWZ-uCZ.js} +1 -1
  40. package/dist/dashboard/assets/formatters-CWWZ-uCZ.js.gz +0 -0
  41. package/dist/dashboard/assets/{index-D6QzEC_n.js → index-DFVFrnWW.js} +2 -2
  42. package/dist/dashboard/assets/index-DFVFrnWW.js.gz +0 -0
  43. package/dist/dashboard/assets/{select-Cj5Nw43g.js → select-DBNVLdUu.js} +1 -1
  44. package/dist/dashboard/assets/select-DBNVLdUu.js.gz +0 -0
  45. package/dist/dashboard/index.html +1 -1
  46. package/dist/dashboard/index.html.gz +0 -0
  47. package/dist/dashboard/precompressed-assets.json +22 -22
  48. package/package.json +1 -1
  49. package/src/console/cli-tools/contracts.ts +10 -4
  50. package/src/network/outbound-fetch.ts +281 -226
  51. package/src/network/pool/agent.ts +7 -0
  52. package/src/providers/default-registry.ts +1 -0
  53. package/src/providers/integrations/ollamacloud-models.ts +50 -0
  54. package/src/providers/integrations/qoder/qoder-oauth.ts +12 -1
  55. package/src/providers/integrations/qoder/qoder-realm.ts +20 -0
  56. package/src/providers/integrations/qoder/qoder-text-tools.ts +277 -0
  57. package/src/providers/integrations/qoder/qoder.ts +1373 -1641
  58. package/src/providers/operations/account-error-classification.ts +1684 -1660
  59. package/src/providers/operations/account-health-service.ts +621 -621
  60. package/src/providers/operations/provider-catalog-service.ts +11 -1
  61. package/src/providers/provider-contracts.ts +7 -2
  62. package/src/security/cli-client-fingerprint.ts +9 -2
  63. package/src/transport/dispatch/empty-stream.ts +224 -224
  64. package/src/transport/failure-policy.ts +33 -0
  65. package/src/transport/routing/route-catalog.ts +34 -12
  66. package/src/transport/routing/router.ts +28 -0
  67. package/src/transport/surface/responses/encode.ts +2 -3
  68. package/src/transport/surface/responses/parse.ts +49 -7
  69. package/src/types/undici.d.ts +33 -0
  70. package/dist/dashboard/assets/BannedPage-D-J75hBM.js.gz +0 -0
  71. package/dist/dashboard/assets/CliToolDetailPage-CVe6RaBH.js.gz +0 -0
  72. package/dist/dashboard/assets/CliToolsPage-Dd8ZSamp.js.gz +0 -0
  73. package/dist/dashboard/assets/CombosPage-QoJ6foxo.js.gz +0 -0
  74. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js.gz +0 -0
  75. package/dist/dashboard/assets/CustomizationPage-CKUFTcW4.js.gz +0 -0
  76. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js.gz +0 -0
  77. package/dist/dashboard/assets/LoginPage-DubdQcvX.js.gz +0 -0
  78. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js.gz +0 -0
  79. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js +0 -4
  80. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js.gz +0 -0
  81. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js.gz +0 -0
  82. package/dist/dashboard/assets/QuotaPage-ATpaxrbl.js.gz +0 -0
  83. package/dist/dashboard/assets/SettingsPage-CETophpx.js.gz +0 -0
  84. package/dist/dashboard/assets/SetupPage-BdgECjqq.js.gz +0 -0
  85. package/dist/dashboard/assets/SortableList-CAK-EN9z.js.gz +0 -0
  86. package/dist/dashboard/assets/StudioPage-B7W2_RhT.js.gz +0 -0
  87. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js.gz +0 -0
  88. package/dist/dashboard/assets/entry-BLBLxX0h.js.gz +0 -0
  89. package/dist/dashboard/assets/formatters-mpBPqAQ8.js.gz +0 -0
  90. package/dist/dashboard/assets/index-D6QzEC_n.js.gz +0 -0
  91. package/dist/dashboard/assets/select-Cj5Nw43g.js.gz +0 -0
@@ -579,6 +579,34 @@ export class RoutingEngine {
579
579
  },
580
580
  );
581
581
  }
582
+ // The pinned account owns the live session, so it is the only correct
583
+ // target for this tool result — but health still applies. Forcing a
584
+ // session whose account is hard-cooling (quota exhausted) reproduces the
585
+ // refusal that cooled it, which is how "still hit a cooled-down account"
586
+ // leaked through continuation affinity. Evaluate the pin before
587
+ // returning: time-bounded cooling answers 429 with the real reset; an
588
+ // account that is disabled/locked answers a clear 400.
589
+ const pinnedDecisions = pinned.map((candidate) => this.eligibility.evaluate(candidate));
590
+ const blocked = pinnedDecisions.find((decision) => !decision.eligible);
591
+ if (blocked !== undefined) {
592
+ const reason = blocked.reason;
593
+ if (
594
+ reason === "cooldown_hard" ||
595
+ reason === "model_cooldown" ||
596
+ (reason === "quota_exhausted" && typeof blocked.cooldown_until === "number")
597
+ ) {
598
+ throw accountsRateLimitedError(requestedModel, resolved.model, earliestResetMs(pinnedDecisions));
599
+ }
600
+ throw new GatewayError(
601
+ "invalid_request",
602
+ 400,
603
+ "This tool result belongs to an account that is no longer routable. Reconnect the account, or resend the complete conversation.",
604
+ {
605
+ providerId: continuationAffinity.providerId,
606
+ accountId: continuationAffinity.providerAccountId,
607
+ },
608
+ );
609
+ }
582
610
  return {
583
611
  revision: snapshot.revision,
584
612
  candidates: pinned,
@@ -339,8 +339,7 @@ export class ResponsesEventEncoder extends SurfaceStreamEncoder<CanonicalEvent,
339
339
  summary: [],
340
340
  content: [],
341
341
  };
342
- if (content.encrypted_content !== undefined) item.encrypted_content = content.encrypted_content;
343
- this.open = {
342
+ if (typeof content.encrypted_content === "string") item.encrypted_content = content.encrypted_content; this.open = {
344
343
  kind: "reasoning",
345
344
  item,
346
345
  itemId,
@@ -501,7 +500,7 @@ export class ResponsesEventEncoder extends SurfaceStreamEncoder<CanonicalEvent,
501
500
  );
502
501
  summaryChunks.push(delta);
503
502
  }
504
- if (content.encrypted_content !== undefined)
503
+ if (typeof content.encrypted_content === "string")
505
504
  events.push(
506
505
  this.emit("response.reasoning.encrypted_content", {
507
506
  item_id: this.open?.itemId,
@@ -9,7 +9,6 @@ import {
9
9
  parseToolDefinition,
10
10
  } from "../dialects";
11
11
  import { readBoolean, readNumber, readString } from "../../../protocol/codecs";
12
- import { ResponsesReasoningError } from "./errors";
13
12
  import type { ResponsesComputerAction, ResponsesInputItem, ResponsesItemMetadata } from "./contracts";
14
13
  const OPENAI_RESPONSE_INCLUDES = {
15
14
  "file_search_call.results": true,
@@ -397,6 +396,21 @@ function parseInputItem(item: ResponsesInputItem): {
397
396
  metadata: itemMetadata(item),
398
397
  };
399
398
  }
399
+ if (type === "additional_tools") {
400
+ // Codex's automatic approval review (Guardian) declares the tools its
401
+ // review isolate may run as an `additional_tools` input item. It is
402
+ // metadata about the client's runtime, not a conversation turn — the
403
+ // tools it names never reach an upstream model and have no canonical
404
+ // representation. It is skipped (never forwarded, never hoisted into
405
+ // instructions) rather than decoded. The critical part is that it must
406
+ // not throw: rejecting it fails the whole auto-review request, which
407
+ // Codex surfaces as "Automatic approval review failed" — making every
408
+ // permission escalation look like an infrastructure error.
409
+ return {
410
+ message: { role: "developer", content: [] },
411
+ metadata: itemMetadata(item),
412
+ };
413
+ }
400
414
  if (type === "computer_call") {
401
415
  const id = readString(item, "id");
402
416
  const callId = readString(item, "call_id") ?? id;
@@ -443,12 +457,7 @@ function parseInputItem(item: ResponsesInputItem): {
443
457
  const encryptedPresent = hasOwn(item, "encrypted_content");
444
458
  const encrypted = item["encrypted_content"];
445
459
  const summary = reasoningItemText(item);
446
- if (encryptedPresent) {
447
- if (typeof encrypted !== "string")
448
- throw new ResponsesReasoningError(
449
- "reasoning.encrypted_content",
450
- "Encrypted reasoning must remain a string artifact",
451
- );
460
+ if (encryptedPresent && typeof encrypted === "string") {
452
461
  const reasoningPart: ContentPart = {
453
462
  kind: "reasoning",
454
463
  payload: encrypted,
@@ -508,6 +517,9 @@ export function parseResponsesRequest(input: unknown): CanonicalRequest {
508
517
  const hoistedInstructionParts: ContentPart[] = [];
509
518
  const messages: CanonicalMessage[] = [];
510
519
  for (const entry of parsedItems) {
520
+ // Codex's auto-review `additional_tools` item is client-side tool
521
+ // metadata, not a conversation turn — never forwarded, never hoisted.
522
+ if (entry.metadata.type === "additional_tools") continue;
511
523
  if (entry.message.role === "system") hoistedSystemParts.push(...entry.message.content);
512
524
  else if (entry.message.role === "developer") hoistedInstructionParts.push(...entry.message.content);
513
525
  else messages.push(entry.message);
@@ -540,6 +552,24 @@ export function parseResponsesRequest(input: unknown): CanonicalRequest {
540
552
  message !== undefined &&
541
553
  message.role === "assistant" &&
542
554
  message.content.some((part) => part.kind === "toolCall");
555
+ // An assistant turn that carries tool calls — and no standalone prose to
556
+ // keep separate. Responses clients (opencode, Codex) send parallel
557
+ // `function_call` items as consecutive entries with no output between them;
558
+ // decoding each into its own canonical assistant turn produced a transcript
559
+ // the Qoder/OpenAI wire rejects — an assistant `tool_calls` turn must be
560
+ // directly followed by the `tool` turns answering it, and a second assistant
561
+ // turn interposed before one result ("An assistant message with 'tool_calls'
562
+ // must be followed by tool messages responding to each 'tool_call_id'").
563
+ // Consecutive such turns are one assistant turn, so they are folded
564
+ // together. Reasoning may be part of either side (a leading reasoning item
565
+ // merged onto the first call turn, then a bare call turn follows) — that is
566
+ // still one logical turn.
567
+ const isToolCallOnlyTurn = (message: CanonicalMessage | undefined): message is CanonicalMessage =>
568
+ message !== undefined &&
569
+ message.role === "assistant" &&
570
+ message.content.length > 0 &&
571
+ message.content.some((part) => part.kind === "toolCall") &&
572
+ message.content.every((part) => part.kind === "toolCall" || part.kind === "reasoning");
543
573
  for (const message of messages) {
544
574
  if (isReasoningOnly(message)) {
545
575
  const previous = messagesWithReasoning[messagesWithReasoning.length - 1];
@@ -570,6 +600,18 @@ export function parseResponsesRequest(input: unknown): CanonicalRequest {
570
600
  messagesWithReasoning.push({ role: "assistant", content: pendingReasoning });
571
601
  pendingReasoning = undefined;
572
602
  }
603
+ // Parallel `function_call` items arrive as consecutive tool-call turns
604
+ // (bare, or carrying a leading reasoning that was already merged into
605
+ // them); fold them into one assistant turn so the tool results that
606
+ // follow answer a single `tool_calls` turn (see isToolCallOnlyTurn).
607
+ const previous = messagesWithReasoning[messagesWithReasoning.length - 1];
608
+ if (isToolCallOnlyTurn(previous) && isToolCallOnlyTurn(message)) {
609
+ messagesWithReasoning[messagesWithReasoning.length - 1] = {
610
+ ...previous,
611
+ content: [...previous.content, ...message.content],
612
+ };
613
+ continue;
614
+ }
573
615
  messagesWithReasoning.push(message);
574
616
  }
575
617
  if (pendingReasoning !== undefined)
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Minimal ambient types for the `undici` dispatcher used by SOCKS5 pool
3
+ * egress. `undici` ships no type declarations and the project does not carry
4
+ * `@types/undici`; only the two surfaces used here are described.
5
+ */
6
+ declare module "undici" {
7
+ /** Options accepted by undici's fetch (superset of RequestInit). */
8
+ export interface UndiciRequestInit extends RequestInit {
9
+ readonly dispatcher?: Dispatcher;
10
+ }
11
+
12
+ /** A dispatcher that can be supplied to undici fetch. */
13
+ export interface Dispatcher {
14
+ dispatch?: unknown;
15
+ }
16
+
17
+ export class Agent implements Dispatcher {
18
+ constructor(
19
+ options?: {
20
+ readonly connect?: (
21
+ opts: Record<string, unknown>,
22
+ ) => Promise<unknown>;
23
+ },
24
+ );
25
+ dispatch?: unknown;
26
+ }
27
+
28
+ export function fetch(
29
+ input: RequestInfo | URL,
30
+ init?: UndiciRequestInit,
31
+ ): Promise<Response>;
32
+ }
33
+
@@ -1,4 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{t as a}from"./arrow-left-CpBxkoxI.js";import{n as o,t as s}from"./brain-Cwed_72z.js";import{n as c,r as l,t as u}from"./concurrency-BDF0ok7y.js";import{C as d,E as f,O as p,T as m,a as h,c as g,l as _,m as v,s as y,v as b,w as x,x as S}from"./numbers-BO9dKaFr.js";import{t as C}from"./circle-alert-CntYHV5v.js";import{t as w}from"./circle-check-BU3v_mFW.js";import{l as T,m as E}from"./formatters-mpBPqAQ8.js";import{t as D}from"./eye-off-Bk5g2luF.js";import{t as ee}from"./eye-C_hawfH4.js";import{t as O}from"./gauge-BbIMy7MB.js";import{t as k}from"./image-BPaouViG.js";import{n as A,r as j,t as M}from"./state-CWoo7ty5.js";import{t as N}from"./key-round-UkavsGxp.js";import{t as te}from"./layers-2-glBbjl.js";import{r as P}from"./use-modal-focus-By7oJoGd.js";import{n as ne,t as F}from"./dialog-DFvWhwTa.js";import{t as I}from"./pencil-768ysRAr.js";import{t as re}from"./plus-DIdX_g-x.js";import{t as ie}from"./power-off-Yjw9GMJh.js";import{t as ae}from"./refresh-cw-BqJFk4sU.js";import{t as oe}from"./rotate-ccw-CufcqITi.js";import{t as se}from"./search-JOKus9rb.js";import{t as ce}from"./trash-Cppn5c3R.js";import{t as le}from"./wrench-B6E1oEuY.js";import{S as ue,_ as de,w as fe}from"./assert-67xXH5rf.js";import{i as pe,l as me,o as he,t as L}from"./query-keys-CfL_Zdoh.js";import{A as R,B as ge,C as _e,D as ve,O as ye,S as be,T as xe,_ as Se,a as Ce,b as we,c as z,d as Te,et as Ee,f as De,g as Oe,h as ke,k as Ae,l as je,lt as Me,m as Ne,nt as Pe,o as Fe,p as Ie,r as Le,t as Re,tt as ze,u as B,ut as Be,w as Ve,x as He}from"./entry-BLBLxX0h.js";import{n as V,r as H,t as U}from"./card-Cca1XC6G.js";import{n as Ue}from"./download-dRFo5_Wu.js";import{f as We,i as Ge,l as W,n as Ke,r as qe,s as Je,u as G}from"./tokens-COzario9.js";import{t as K}from"./badge-DC2L43Mj.js";import{n as q}from"./input-C_ILAvBb.js";import{t as J}from"./select-Cj5Nw43g.js";import{t as Ye}from"./ProviderIcon-FB6yS4v1.js";import{t as Xe}from"./switch-CCjT6IkF.js";import{t as Y}from"./stack-EMrOMt4I.js";import{n as X,t as Ze}from"./inline-BFUcvllj.js";import{i as Qe}from"./quota-DZGyp0N5.js";import{t as $e}from"./list-row-ebJ_-Nsb.js";import{c as et,l as tt,m as nt}from"./routing-BnIpi1IJ.js";import{t as Z}from"./banner-BBVcb0J3.js";import{o as rt,s as it,t as at}from"./HealthEventsModal-CzSLiDzr.js";import{r as ot}from"./privacy-mode-GM8bej85.js";import{n as st,t as ct}from"./AccountCooldown-Bjo92Qat.js";import{t as lt}from"./use-timeout-BwcBBRrT.js";var ut=e(`cable`,[[`path`,{d:`M17 19a1 1 0 0 1-1-1v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2a1 1 0 0 1-1 1z`,key:`trhst0`}],[`path`,{d:`M17 21v-2`,key:`ds4u3f`}],[`path`,{d:`M19 14V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V10`,key:`1mo9zo`}],[`path`,{d:`M21 21v-2`,key:`eo0ou`}],[`path`,{d:`M3 5V3`,key:`1k5hjh`}],[`path`,{d:`M4 10a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2z`,key:`1dd30t`}],[`path`,{d:`M7 5V3`,key:`1t1388`}]]),dt=e(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),ft=e(`lock-open`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 9.9-1`,key:`1mm8w8`}]]),pt=e(`package-x`,[[`path`,{d:`M12 22V12`,key:`d0xqtd`}],[`path`,{d:`m16.5 14.5 5 5`,key:`ozpm51`}],[`path`,{d:`m16.5 19.5 5-5`,key:`syf6b9`}],[`path`,{d:`M21 10.5V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l.13-.074`,key:`isw6gs`}],[`path`,{d:`M3.29 7 12 12l8.71-5`,key:`19ckod`}],[`path`,{d:`m7.5 4.27 8.997 5.148`,key:`9yrvtv`}]]),mt=e(`repeat`,[[`path`,{d:`m17 2 4 4-4 4`,key:`nntrym`}],[`path`,{d:`M3 11v-1a4 4 0 0 1 4-4h14`,key:`84bu3i`}],[`path`,{d:`m7 22-4-4 4-4`,key:`1wqhfi`}],[`path`,{d:`M21 13v1a4 4 0 0 1-4 4H3`,key:`1rx37r`}]]),ht=e(`save`,[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]]),gt=e(`video`,[[`path`,{d:`m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5`,key:`ftymec`}],[`rect`,{x:`2`,y:`6`,width:`14`,height:`12`,rx:`2`,key:`158x01`}]]),_t=e(`waypoints`,[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]),vt=[`auto`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];function yt(e,t){return t===null?e:`${e}(${t})`}var Q=t(n(),1),$=r();function bt({to:e,label:t}){let n=Ee();return(0,$.jsxs)(`button`,{type:`button`,onClick:()=>{window.history.length>1?n(-1):n(e)},className:`inline-flex items-center gap-3 text-accent text-caption bg-transparent border-0 p-0 cursor-pointer`,children:[(0,$.jsx)(a,{size:14,"aria-hidden":`true`}),t]})}function xt({title:e,description:t,icon:n,badges:r,actions:i,back:a}){return(0,$.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[a?(0,$.jsx)(bt,{...a}):null,(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-6 flex-wrap`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-5 min-w-0`,children:[n?(0,$.jsx)(`div`,{className:`card-header-icon`,children:n}):null,(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,$.jsx)(`h1`,{className:`text-lead font-bold`,children:e}),r]}),t?(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:t}):null]})]}),i?(0,$.jsx)(`div`,{className:v(`flex items-center gap-4 flex-wrap min-w-0 max-w-full`),children:i}):null]})]})}function St(e){return e.isBuiltIn&&e.requiresAccount&&e.oauthFlows===void 0&&!e.hasAdapterUserAgent}function Ct(e,t=600){let n=(0,Q.useRef)(void 0);return(0,Q.useEffect)(()=>()=>clearTimeout(n.current),[]),r=>{clearTimeout(n.current),n.current=setTimeout(()=>e(r),t)}}var wt={fallback:`Failover`,roundRobin:`Round robin`},Tt=new Set([`inferhub`,`cline`]);function Et(e,t){let n=tt(e),r=nt(),[i,a]=(0,Q.useState)(`fallback`),[o,s]=(0,Q.useState)(1),[c,l]=(0,Q.useState)(null),[u,d]=(0,Q.useState)(null),[f,p]=(0,Q.useState)(null),[m,h]=(0,Q.useState)(`percent`),[g,_]=(0,Q.useState)(!1),[v,y]=(0,Q.useState)(``);(0,Q.useEffect)(()=>{n.data&&(a(n.data.strategy),s(n.data.rotateCount),l(n.data.maxInflight),d(n.data.maxInflightPerProxy??null),p(n.data.usageFloor),h(n.data.usageFloorUnit),_(n.data.skipProxy),y(n.data.userAgent))},[n.data]);let b=i=>{r.mutate({providerId:e,request:{enabled:!0,strategy:i.strategy,rotateCount:i.rotateCount,maxInflight:i.maxInflight,maxInflightPerProxy:i.maxInflightPerProxy,usageFloor:i.usageFloor,usageFloorUnit:i.usageFloorUnit,skipProxy:i.skipProxy,...t?{userAgent:i.userAgent}:{}}},{onError:()=>{n.data&&(a(n.data.strategy),s(n.data.rotateCount),l(n.data.maxInflight),d(n.data.maxInflightPerProxy??null),p(n.data.usageFloor),h(n.data.usageFloorUnit),_(n.data.skipProxy),y(n.data.userAgent))}})},x=Ct(e=>b({strategy:i,rotateCount:o,maxInflight:e,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),S=Ct(e=>b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:e,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),C=Ct(e=>b({strategy:i,rotateCount:e,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),w=Ct(e=>b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:e}));return{strategy:i,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,setUsageFloor:(e,t)=>{p(e),h(t),b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:e,usageFloorUnit:t,skipProxy:g,userAgent:v})},skipProxy:g,userAgent:v,isLoading:n.isPending,isError:n.isError,isSaving:r.isPending,saveFailed:r.isError,refetch:()=>n.refetch(),setMaxInflight:e=>{l(e),x(e)},setMaxInflightPerProxy:e=>{d(e),S(e)},setUserAgent:e=>{y(e),w(e)},setSkipProxy:e=>{_(e),b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:e,userAgent:v})},roundRobinEnabled:i===`round_robin`,setRoundRobinEnabled:e=>{let t=e?`round_robin`:`fallback`;a(t),b({strategy:t,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})},rotateCount:o,setRotateCount:e=>{s(e),C(e)}}}var Dt=50,Ot=100;function kt(e,t,n){return[{value:``,label:`None`},{value:`Cartethyia/${e}`,label:`Cartethyia ${e}`},{value:`codex_cli_rs/${t}`,label:`Codex`},{value:`claude-cli/${n} (external, cli)`,label:`Claude Code`}]}function At({children:e,action:t}){return(0,$.jsx)($e,{actions:t,children:e})}function jt({providerId:e,clientVersion:t,routeIdentityVersions:n,userAgentEditable:r}){let i=Et(e,r),[a,o]=(0,Q.useState)(!1),s=Tt.has(e),l=kt(Re,n.codex,n.claude),u=l.some(e=>e.value===i.userAgent)?l:[...l,{value:i.userAgent,label:`Custom`}];if(i.isLoading)return(0,$.jsx)(j,{label:`Loading routing...`});if(i.isError)return(0,$.jsx)(A,{message:`Failed to load routing`,onRetry:i.refetch});let d=i.roundRobinEnabled?`${wt.roundRobin} · ${i.rotateCount} account${i.rotateCount===1?``:`s`} per rotation`:wt.fallback,f=i.isSaving?`Saving...`:i.saveFailed?`Save failed — reverted to last saved value`:`Active: ${d}`,p=i.maxInflight===null,m=p?51:Math.min(51,Math.max(1,i.maxInflight)),h=p?`∞`:String(i.maxInflight),_=i.maxInflightPerProxy===null,v=_?51:Math.min(51,Math.max(1,i.maxInflightPerProxy)),b=_?`∞`:String(i.maxInflightPerProxy),x=i.skipProxy,S=e=>{i.setRotateCount(Math.min(1e3,Math.max(1,i.rotateCount+e)))},C=e=>{if(e===i.userAgent)return;i.setUserAgent(e);let t=u.find(t=>t.value===e)?.label??e;y.success(`Client identity updated`,t)},w=t?`${t.client} ${t.version}`:`Provider default`;return(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Routing Strategy`,subtitle:f,icon:(0,$.jsx)(te,{size:16})}),(0,$.jsx)(V,{children:(0,$.jsxs)(`div`,{className:`grid gap-5 w-full min-w-0`,children:[(0,$.jsx)(At,{action:(0,$.jsxs)($.Fragment,{children:[i.roundRobinEnabled?(0,$.jsxs)(`div`,{role:`group`,"aria-label":`Accounts per rotation`,className:`inline-flex items-center gap-1 rounded-control border border-inner-border bg-surface-1 p-1`,children:[(0,$.jsx)(`span`,{className:`px-2 text-badge text-text-secondary`,children:`Accounts/rotation`}),(0,$.jsx)(g,{variant:`ghost`,size:`icon`,className:`size-9 rounded-tiny`,"aria-label":`Decrease accounts per rotation`,disabled:i.rotateCount<=1,icon:(0,$.jsx)(ne,{size:14}),onClick:()=>S(-1)}),(0,$.jsx)(`output`,{className:`min-w-8 text-center text-body font-semibold tabular-nums`,"aria-live":`polite`,children:i.rotateCount}),(0,$.jsx)(g,{variant:`ghost`,size:`icon`,className:`size-9 rounded-tiny`,"aria-label":`Increase accounts per rotation`,disabled:i.rotateCount>=1e3,icon:(0,$.jsx)(re,{size:14}),onClick:()=>S(1)})]}):null,(0,$.jsx)(Xe,{checked:i.roundRobinEnabled,onChange:i.setRoundRobinEnabled,id:`routing-round-robin`})]}),children:(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`label`,{htmlFor:`routing-round-robin`,children:(0,$.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,$.jsx)(mt,{size:15,"aria-hidden":`true`,className:`shrink-0 ${i.roundRobinEnabled?`text-accent`:`text-text-tertiary`}`}),`Round robin`]})}),(0,$.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Off uses priority order with failover. On rotates requests across this provider's accounts.`})]})}),(0,$.jsx)(At,{action:(0,$.jsx)(Xe,{checked:i.skipProxy,onChange:i.setSkipProxy,id:`routing-skip-proxy`}),children:(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`label`,{htmlFor:`routing-skip-proxy`,children:(0,$.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,$.jsx)(ut,{size:15,"aria-hidden":`true`,className:`shrink-0 ${i.skipProxy?`text-accent`:`text-text-tertiary`}`}),`Always direct`]})}),(0,$.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Bypass automatic proxy-pool routing for this provider and always dial direct`})]})}),(0,$.jsxs)(`div`,{className:`routing-controls-grid grid gap-5 min-w-0 w-full`,children:[(0,$.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0`,children:[(0,$.jsxs)(X,{gap:`6px`,className:`text-body font-semibold mb-3`,children:[(0,$.jsx)(c,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Client identity`]}),r?(0,$.jsx)(J,{id:`routing-user-agent-preset`,"aria-label":`Client identity`,value:i.userAgent,options:u,onValueChange:C}):(0,$.jsx)(J,{id:`routing-user-agent-fixed`,"aria-label":`Client identity`,disabled:!0,value:w,options:[{value:w,label:w}]}),(0,$.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:r?`None sends the request as-is — whatever the runtime or egress sets, with no identity stamped by the gateway. A chosen value overrides it.`:`Set by the provider. It cannot be changed.`})]}),(0,$.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0`,children:[(0,$.jsx)(`label`,{htmlFor:`routing-max-inflight`,className:`form-label`,children:(0,$.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,$.jsx)(O,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Max inflight / account`]})}),(0,$.jsxs)(`div`,{className:`text-badge text-text-tertiary mb-3`,children:[`Per-account ceiling, not a provider-wide one: each account enforces its own limit, so a full account spills to the next. One step past `,Dt,` is unlimited.`]}),(0,$.jsxs)(X,{gap:`10px`,className:`mt-3`,children:[(0,$.jsx)(`input`,{id:`routing-max-inflight`,type:`range`,className:`routing-slider flex-1 min-w-0`,"data-unlimited":p?`true`:void 0,min:1,max:51,step:1,value:m,"aria-valuetext":p?`Unlimited`:String(i.maxInflight),onChange:e=>{let t=Number(e.target.value);Number.isFinite(t)&&i.setMaxInflight(t>Dt?null:Math.round(t))},style:{"--slider-pct":`${m/51*100}%`}}),(0,$.jsx)(`input`,{type:`text`,inputMode:`numeric`,"aria-label":`Max inflight per account`,value:h,onChange:e=>{let t=e.target.value.trim();if(t===``||t===`∞`){i.setMaxInflight(null);return}let n=Number(t);Number.isFinite(n)&&n>=1&&i.setMaxInflight(Math.min(Ot,Math.round(n)))},className:`form-input w-26 shrink-0 px-2 py-3 text-center text-body ${p?`text-status-success`:``}`})]})]})]}),(0,$.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0${x?` opacity-60`:``}`,children:[(0,$.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,$.jsxs)(`label`,{htmlFor:`routing-max-inflight-per-proxy`,className:`min-w-0`,children:[(0,$.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,$.jsx)(_t,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Max inflight / proxy`]}),(0,$.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Each proxy pool carries at most this many concurrent requests for this provider. Other providers on the same pool are unaffected.`})]}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,className:`shrink-0`,"aria-label":`How per-proxy limits work`,onClick:()=>o(!0),children:`How it works`})]}),(0,$.jsxs)(X,{gap:`10px`,className:`mt-3`,children:[(0,$.jsx)(`input`,{id:`routing-max-inflight-per-proxy`,type:`range`,className:`routing-slider flex-1 min-w-0`,"data-unlimited":_?`true`:void 0,min:1,max:51,step:1,disabled:x,value:v,"aria-valuetext":_?`Unlimited`:String(i.maxInflightPerProxy),onChange:e=>{let t=Number(e.target.value);Number.isFinite(t)&&i.setMaxInflightPerProxy(t>Dt?null:Math.round(t))},style:{"--slider-pct":`${v/51*100}%`}}),(0,$.jsx)(`input`,{type:`text`,inputMode:`numeric`,"aria-label":`Max inflight per proxy`,disabled:x,value:b,onChange:e=>{let t=e.target.value.trim();if(t===``||t===`∞`){i.setMaxInflightPerProxy(null);return}let n=Number(t);Number.isFinite(n)&&n>=1&&i.setMaxInflightPerProxy(Math.min(Ot,Math.round(n)))},className:`form-input w-26 shrink-0 px-2 py-3 text-center text-body ${_?`text-status-success`:``}`})]}),(0,$.jsx)(`div`,{className:`mt-2 text-badge text-text-tertiary`,children:x?`Always direct is on, so this provider never dials a pool. The limit is kept for when a pool is used again.`:`One step past ${Dt} is unlimited.`})]}),(0,$.jsx)(F,{open:a,onClose:()=>o(!1),title:`How concurrency limits stack`,size:`md`,children:(0,$.jsxs)(`div`,{className:`grid gap-4 text-body`,children:[(0,$.jsx)(`p`,{className:`text-text-secondary`,children:`Three limits apply at once. Each one bounds a different thing; none replaces another.`}),(0,$.jsxs)(`dl`,{className:`grid gap-3`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{className:`font-semibold`,children:`Max inflight / account`}),(0,$.jsx)(`dd`,{className:`text-badge text-text-tertiary`,children:`One account of this provider, across every proxy. Set here, above.`})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{className:`font-semibold`,children:`Max inflight / proxy`}),(0,$.jsxs)(`dd`,{className:`text-badge text-text-tertiary`,children:[`One proxy pool's concurrent requests `,(0,$.jsx)(`em`,{children:`for this provider`}),`. The same number applies to every pool; each pool counts separately. This is the field above.`]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{className:`font-semibold`,children:`Pool capacity`}),(0,$.jsx)(`dd`,{className:`text-badge text-text-tertiary`,children:`Everything through one pool, all providers combined. Set on the proxy itself, on the Proxies page.`})]})]}),(0,$.jsxs)(`p`,{className:`text-badge text-text-tertiary`,children:[`A request must clear all three. When a pool is full for this provider, the request moves to another pool that still has room; it only fails with`,` `,(0,$.jsx)(`code`,{children:`429`}),` when every pool is full.`]}),(0,$.jsx)(`p`,{className:`text-badge text-text-tertiary`,children:`Unlimited means no counter is kept for this provider, so the limit costs nothing until you set one.`})]})}),s&&(0,$.jsxs)(X,{gap:`6px`,align:`flex-start`,className:`mt-1 text-badge text-text-tertiary`,children:[(0,$.jsx)(dt,{size:12,className:`shrink-0 mt-0.5`}),(0,$.jsx)(`span`,{children:`This provider doesn't reliably work through a plain HTTP/S proxy — use a SOCKS5 or proxy pool instead if you need to route it.`})]})]})})]})}function Mt(e){if(typeof e!=`object`||!e)throw{status:500,code:`invalid_response`,message:`Invalid InferHub summary`};let t=e;return{models:Array.isArray(t.models)?t.models:[],providers:Array.isArray(t.providers)?t.providers:[],pricingConfig:t.pricingConfig??null,meta:t.meta??{fetchedAt:0,ageSeconds:0,stale:!0},error:t.error??null}}function Nt(e=!0){return ue({queryKey:L.inferhub.summary,queryFn:e=>he(`/inferhub/summary`,{signal:de(e)}).then(Mt),enabled:e,...pe,staleTime:6e4})}function Pt(e){return e===null?`—`:`$${e.toFixed(4)}`}function Ft(e){return e===null?`—`:`${e}%`}function It(e){return e<60?`${e}s ago`:e<3600?`${Math.floor(e/60)}m ago`:`${Math.floor(e/3600)}h ago`}var Lt={provider:`Provider (A–Z)`,availability:`Highest availability`,sustainable:`Sustainable price`,price:`Lowest price`,discount:`Biggest discount`};function Rt(e,t){return(n,r)=>{let i=e(n),a=e(r);return i===null&&a===null?0:i===null?1:a===null?-1:t===`asc`?i-a:a-i}}function zt(e){switch(e){case`provider`:return(e,t)=>e.family.localeCompare(t.family,void 0,{sensitivity:`base`})||e.prefix.localeCompare(t.prefix);case`availability`:return(e,t)=>t.providersLive-e.providersLive||Rt(e=>e.health.successRatePct,`desc`)(e,t);case`sustainable`:return Rt(e=>e.capacityPriceIn,`asc`);case`price`:return Rt(e=>e.minAskIn,`asc`);case`discount`:return Rt(e=>e.tiersIn[0]?.discountPct??null,`desc`)}}function Bt(e){return e===`operational`?`ok`:e===`degraded`?`warn`:e===`major_outage`?`err`:`default`}function Vt(e,t){return e.providers.find(e=>e.prefix===t)}function Ht(e){return e.providersLive>0&&e.routable&&e.minAskIn!==null}function Ut(){let e=Nt(),t=e.data,[n,r]=(0,Q.useState)(!1),[i,a]=(0,Q.useState)(!1),[o,s]=(0,Q.useState)(!0),[c,l]=(0,Q.useState)(`provider`),u=t?.models??[],d=u.filter(Ht),f=(0,Q.useMemo)(()=>{let e=[...i?u:d].sort(zt(c)),t=new Map;for(let n of e){let e=t.get(n.prefix);e===void 0?t.set(n.prefix,[n]):e.push(n)}return[...t.entries()].map(([e,t])=>({prefix:e,family:t[0]?.family??e,models:t}))},[u,d,i,c]),p=(0,$.jsxs)(g,{variant:`secondary`,size:`sm`,onClick:()=>void e.refetch(),disabled:e.isFetching,title:`Re-read InferHub market data now`,children:[(0,$.jsx)(ae,{size:14}),e.isFetching?`Refreshing…`:`Refresh`]});if(t===void 0&&!e.isError)return(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`InferHub market`,subtitle:e.isPending?`Reading market data…`:void 0,icon:(0,$.jsx)(ae,{size:16})}),(0,$.jsx)(V,{children:e.isError?(0,$.jsx)(Z,{tone:`danger`,surface:`raised`,live:`none`,children:`InferHub market data could not be read.`}):null})]});if(t===void 0)return(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`InferHub market`,icon:(0,$.jsx)(ae,{size:16}),action:p}),(0,$.jsx)(V,{children:(0,$.jsx)(Z,{tone:`danger`,surface:`raised`,live:`none`,children:`InferHub market data could not be read.`})})]});let m=f,h=m.reduce((e,t)=>e+t.models.length,0),_=u.length-h;return(0,$.jsxs)(U,{children:[(0,$.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,$.jsxs)(`button`,{type:`button`,"aria-expanded":n,"aria-label":n?`Collapse InferHub market`:`Expand InferHub market`,onClick:()=>r(e=>!e),className:`flex min-w-0 flex-1 items-start gap-3 border-0 bg-transparent p-0 text-left text-inherit`,children:[(0,$.jsx)(Be,{size:15,"aria-hidden":`true`,className:v(`mt-1 shrink-0 transition-transform`,!n&&`-rotate-90`)}),(0,$.jsxs)(Y,{gap:`1px`,children:[(0,$.jsx)(`h2`,{className:`text-body font-bold`,children:`InferHub market`}),t.meta.fetchedAt>0?(0,$.jsxs)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Updated `,It(t.meta.ageSeconds)]}):null]})]}),(0,$.jsx)(`div`,{className:`flex items-center gap-2`,children:n?p:null})]}),n?(0,$.jsxs)(V,{children:[(0,$.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,$.jsx)(Gt,{onSaved:()=>void e.refetch()}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,$.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary`,children:[`Sort`,(0,$.jsx)(J,{value:c,onValueChange:e=>l(e),options:Object.keys(Lt).map(e=>({value:e,label:Lt[e]})),"aria-label":`Sort InferHub models`})]}),(0,$.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary cursor-pointer`,children:[(0,$.jsx)(`input`,{type:`checkbox`,checked:o,onChange:e=>s(e.target.checked),className:`cursor-pointer`}),`Show availability`]})]})]}),t.error===`no_config_key`?(0,$.jsxs)(Z,{tone:`warning`,surface:`raised`,live:`none`,children:[`No InferHub `,(0,$.jsx)(`code`,{children:`config_read`}),` key is configured, so the marketplace catalog cannot be read. Add one above.`]}):null,t.error===`upstream_unavailable`?(0,$.jsxs)(Z,{tone:`warning`,surface:`raised`,live:`none`,children:[`InferHub did not answer. Showing the last snapshot that was read`,t.meta.fetchedAt>0?` (${It(t.meta.ageSeconds)})`:``,`.`]}):null,t.meta.stale&&t.error===null?(0,$.jsxs)(Z,{tone:`warning`,surface:`raised`,live:`none`,children:[`This snapshot is `,It(t.meta.ageSeconds),` — press Refresh for current prices.`]}):null,(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,$.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[h,` of `,u.length,` models`]}),(0,$.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary cursor-pointer`,children:[(0,$.jsx)(`input`,{type:`checkbox`,checked:i,onChange:e=>a(e.target.checked),className:`cursor-pointer`}),`Show all`,_>0?(0,$.jsxs)(`span`,{className:`text-micro text-text-tertiary`,children:[`(includes `,_,` hidden)`]}):null]})]}),m.length===0?(0,$.jsx)(`p`,{className:`mt-3 text-caption text-text-secondary`,children:`No models to show.`}):(0,$.jsx)(`div`,{className:`mt-3 flex flex-col gap-3`,children:m.map(e=>(0,$.jsx)(Wt,{group:e,showUpstreams:o,summary:t},e.prefix))})]}):null]})}function Wt({group:e,showUpstreams:t,summary:n}){let[r,i]=(0,Q.useState)(!0),a=Vt(n,e.prefix),o=a?.familyState??null,s=e.models.find(e=>e.systemPromptNote!==null)?.systemPromptNote??null;return(0,$.jsxs)(`div`,{className:`rounded-card border border-inner-border bg-surface-2`,children:[(0,$.jsxs)(`button`,{type:`button`,"aria-expanded":r,"aria-label":`${r?`Collapse`:`Expand`} ${e.family} models`,onClick:()=>i(e=>!e),className:`flex w-full items-center gap-2 border-0 bg-transparent px-3 py-2 text-left text-inherit`,children:[(0,$.jsx)(Be,{size:14,"aria-hidden":`true`,className:v(`shrink-0 transition-transform`,!r&&`-rotate-90`)}),(0,$.jsx)(`span`,{className:`text-caption font-bold`,children:e.family}),(0,$.jsxs)(`span`,{className:`font-mono text-micro text-text-tertiary`,children:[e.prefix,`/`]}),o===null?null:(0,$.jsx)(K,{tone:Bt(o),dot:!0,children:o.replace(/_/g,` `)}),t&&a!==void 0?(0,$.jsxs)(`span`,{className:`text-micro text-text-tertiary tabular-nums`,children:[`24h `,Ft(a.availability24hPct),` · 7d`,` `,Ft(a.availability7dPct)]}):null,(0,$.jsxs)(`span`,{className:`ml-auto text-micro text-text-tertiary`,children:[e.models.length,` model`,e.models.length===1?``:`s`]})]}),r?(0,$.jsxs)(`div`,{className:`px-3 pb-3`,children:[s===null?null:(0,$.jsx)(`p`,{className:`mb-2 text-micro text-text-secondary`,children:s}),(0,$.jsx)(`div`,{className:`overflow-x-auto`,children:(0,$.jsxs)(`table`,{className:`w-full text-caption`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{className:`text-left text-text-secondary`,children:[(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:`Model`}),(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:`Input`}),(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:`Output`}),(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:`Discount`}),(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:`Live`}),(0,$.jsx)(`th`,{className:`py-1 pr-3`,children:t?`24h`:`Success`})]})}),(0,$.jsx)(`tbody`,{children:e.models.map(e=>(0,$.jsxs)(`tr`,{className:`border-t border-inner-border`,children:[(0,$.jsx)(`td`,{className:`py-1 pr-3 font-mono`,children:e.id}),(0,$.jsxs)(`td`,{className:`py-1 pr-3 tabular-nums`,children:[Pt(e.minAskIn),e.capacityPriceIn!==null&&e.capacityPriceIn!==e.minAskIn?(0,$.jsxs)(`div`,{className:`text-micro text-text-secondary`,children:[Pt(e.capacityPriceIn),` sustainable`]}):null]}),(0,$.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:Pt(e.minAskOut)}),(0,$.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:e.tiersIn[0]?.discountPct===void 0||e.tiersIn[0]?.discountPct===null?`—`:`−${e.tiersIn[0].discountPct}%`}),(0,$.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:e.providersLive===0?(0,$.jsx)(K,{children:`none`}):e.providersLive}),(0,$.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:Ft(t?a?.availability24hPct??null:e.health.successRatePct)})]},e.id))})]})})]}):null]})}function Gt({onSaved:e}){let[t,n]=(0,Q.useState)(``),[r,i]=(0,Q.useState)(null),[a,o]=(0,Q.useState)(!1),[s,c]=(0,Q.useState)(null),l=async()=>{if(t.trim().length!==0){o(!0),c(null);try{await he(`/inferhub/key`,{method:`PUT`,body:JSON.stringify({key:t.trim()})}),n(``),i({configured:!0,last4:null}),e()}catch{c(`Could not save the key.`)}finally{o(!1)}}},u=async()=>{o(!0),c(null);try{await he(`/inferhub/key`,{method:`DELETE`}),i({configured:!1,last4:null}),e()}catch{c(`Could not remove the key.`)}finally{o(!1)}};return(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2`,children:[(0,$.jsx)(`div`,{className:`min-w-64 flex-1`,children:(0,$.jsx)(q,{type:`password`,value:t,onChange:e=>n(e.target.value),placeholder:`sk-airo-… (config_read key)`,"aria-label":`InferHub config_read key`,autoComplete:`off`})}),(0,$.jsx)(g,{size:`sm`,onClick:()=>void l(),disabled:a||t.trim().length===0,children:a?`Saving…`:`Save key`}),r?.configured?(0,$.jsx)(g,{size:`sm`,variant:`secondary`,onClick:()=>void u(),disabled:a,children:`Remove`}):null]}),(0,$.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[`Stored encrypted beside the market settings, never in this provider's accounts. Must be a`,` `,(0,$.jsx)(`code`,{children:`config_read`}),` key — never an inference key.`]}),s===null?null:(0,$.jsx)(Z,{tone:`danger`,surface:`raised`,live:`alert`,children:s})]})}function Kt({providerId:e}){let t=Et(e,!1),n=rt(),r=et(e),i=(0,Q.useMemo)(()=>Jt(n.data?.accounts??[],e),[n.data,e]),a=(0,Q.useRef)(null),o=(0,Q.useMemo)(()=>[...r.data?.values()??[]].reduce((e,t)=>e+t,0),[r.data]);(0,Q.useEffect)(()=>{if(a.current===null){a.current=o;return}a.current!==o&&(a.current=o,n.refetch())},[o,n]);let[s,c]=(0,Q.useState)(`40`),[l,u]=(0,Q.useState)(`percent`),d=t.usageFloor!==null;(0,Q.useEffect)(()=>{t.usageFloor!==null&&c(String(t.usageFloor)),u(t.usageFloorUnit)},[t.usageFloor,t.usageFloorUnit]);let f=Number(s),p=Number.isInteger(f)&&f>=0&&f<=1e6,m=i===null||i.remaining<=0?`text-status-danger`:i.percent<=10?`text-status-warning`:`text-status-success`,h=(e,n)=>{(e===null||p)&&t.setUsageFloor(e,n)};return(0,$.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,$.jsxs)(`section`,{className:`usage-floor-panel flex flex-col gap-4 px-5 py-4 border border-inner-border rounded-narrow bg-surface-2`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-3 text-body font-semibold text-text-primary`,children:[(0,$.jsx)(O,{size:14}),(0,$.jsx)(`span`,{children:`Usage floor`}),(0,$.jsx)(`span`,{className:`badge border border-warning-line bg-surface-2 text-micro tracking-label text-status-warning`,children:`BETA`})]}),(0,$.jsx)(`p`,{className:`mt-0.5 text-badge leading-normal text-text-tertiary`,children:`Per account. Skip an account once its remaining allowance reaches this, and send the request to the next one.`})]}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[i!==null&&(0,$.jsxs)(`div`,{className:`flex min-h-24 min-w-0 flex-[1_1_20rem] flex-col justify-center gap-2 py-2`,children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 text-micro font-semibold tracking-label uppercase text-text-tertiary`,children:[(0,$.jsx)(`span`,{children:`Pooled credits`}),(0,$.jsx)(`span`,{className:`text-text-primary`,children:i.accounts}),(0,$.jsx)(`span`,{children:i.accounts===1?`active account`:`active accounts`}),i.inactiveAccounts>0?(0,$.jsxs)(`span`,{className:`badge border border-warning-line text-status-warning normal-case tracking-normal`,title:`Disabled or cooled accounts hold credits this provider cannot route to. Enable or recover them to add their balance.`,children:[i.inactiveAccounts,` inactive`]}):null]}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2 gap-y-1 text-caption font-semibold tabular-nums text-text-primary`,title:`Combined allowance across active accounts; the usage floor is evaluated per account`,children:[(0,$.jsx)(`strong`,{className:`font-bold ${m}`,children:Yt(i.remaining)}),(0,$.jsx)(`span`,{className:`font-medium text-text-secondary`,children:`credits available`}),(0,$.jsxs)(`span`,{className:`font-medium opacity-75`,children:[`of `,Yt(i.total)]}),(0,$.jsxs)(`span`,{className:`font-bold ${m}`,children:[i.percent,`%`]})]}),(0,$.jsx)(`p`,{className:`text-micro leading-normal text-text-tertiary`,children:t.usageFloor===null?`Floor off · exhausted quota windows are still skipped`:`Floor ${Yt(t.usageFloor)} ${t.usageFloorUnit===`credit`?`credits`:`%`} per account`})]}),i===null&&(0,$.jsxs)(`p`,{className:`flex min-h-24 min-w-0 flex-[1_1_20rem] flex-col justify-center gap-2 py-2 text-badge leading-normal text-text-tertiary`,children:[(0,$.jsx)(`span`,{children:`No combined credit balance is available. Separate quota windows are not added together, and exhausted windows are still skipped.`}),(0,$.jsx)(`span`,{className:`text-micro`,children:t.usageFloor===null?`Floor off · exhausted quota windows are still skipped`:`Floor ${Yt(t.usageFloor)} ${t.usageFloorUnit===`credit`?`credits`:`%`} per account`})]}),(0,$.jsxs)(`div`,{className:`ml-auto flex max-w-full shrink-0 flex-col items-end justify-center gap-2`,children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-x-3 gap-y-2`,children:[(0,$.jsx)(`span`,{className:`text-micro font-semibold tracking-label uppercase text-text-tertiary`,children:`Floor threshold`}),(0,$.jsxs)(`label`,{className:`flex h-12 max-w-full items-center overflow-hidden rounded-tiny border border-inner-border bg-surface-1 focus-within:border-text-tertiary`,children:[(0,$.jsx)(`input`,{type:`number`,min:0,max:1e6,value:d?s:``,placeholder:`40`,disabled:!d,"aria-label":`Usage floor amount`,className:`h-full w-24 border-0 bg-transparent px-3 text-right font-mono text-body font-semibold tabular-nums text-text-primary disabled:text-text-tertiary`,onChange:e=>c(e.target.value),onBlur:()=>{d&&h(f,l)}}),(0,$.jsxs)(`select`,{value:l,disabled:!d,"aria-label":`Usage floor unit`,className:`h-full border-0 border-l border-inner-border bg-hover px-3 text-body font-semibold text-text-secondary disabled:cursor-default disabled:opacity-60`,onChange:e=>{let t=e.target.value===`credit`?`credit`:`percent`;u(t),d&&h(f,t)},children:[(0,$.jsx)(`option`,{value:`percent`,children:`%`}),(0,$.jsx)(`option`,{value:`credit`,children:`credits`})]})]}),(0,$.jsx)(Xe,{checked:d,label:`Enabled`,"aria-label":`Usage floor`,className:`usage-floor-switch`,onChange:e=>h(e?p?f:40:null,l)})]}),t.saveFailed?(0,$.jsx)(`p`,{role:`alert`,className:`text-right text-micro leading-normal text-status-danger`,children:`Usage floor save failed. The last saved setting has been restored.`}):null]})]})]}),(0,$.jsx)(qt,{providerId:e})]})}function qt({providerId:e}){let{enabled:t,setEnabled:n}=ot(e);return(0,$.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-6 px-6 py-5 border border-inner-border rounded-control bg-surface-2`,children:[(0,$.jsxs)(`div`,{className:`min-w-0 flex-auto basis-110`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-3 text-body font-semibold text-text-primary`,children:[(0,$.jsx)(D,{size:14}),(0,$.jsx)(`span`,{children:`Mysterious accounts`})]}),(0,$.jsx)(`p`,{className:`mt-0.5 text-badge leading-normal text-text-tertiary`,children:`Hide this provider's emails and usernames. Stored in this browser only.`})]}),(0,$.jsx)(`div`,{className:`flex items-center gap-4 shrink-0`,children:(0,$.jsx)(Xe,{checked:t,"aria-label":`Mysterious accounts`,onChange:n})})]})}function Jt(e,t){let n=0,r=0,i=0,a=0,o=!1;for(let s of e)if(s.provider===t){if(!s.active){a+=1;continue}if(i+=1,s.quota!==null)for(let e of s.quota.windows){if(e.accounting!==`pooled`)continue;let t=typeof e.limit==`number`&&Number.isFinite(e.limit)?e.limit:null;if(t===null)continue;let i=typeof e.remaining==`number`&&Number.isFinite(e.remaining)?e.remaining:typeof e.used==`number`&&Number.isFinite(e.used)?t-e.used:null;i!==null&&(n+=Math.min(t,Math.max(0,i)),r+=t,o=!0)}}return i>0&&o?{accounts:i,inactiveAccounts:a,remaining:n,total:r,percent:r>0?Math.round(n/r*100):0}:null}function Yt(e){return e.toLocaleString(void 0,{maximumFractionDigits:1})}function Xt({provider:e}){let t=e.credentialUrl,n=e.credentialHint,r=e.operatorNotice;if(!t&&!n&&!r)return null;let i=e.oauthFlows?.browser===!0||e.oauthFlows?.device===!0,a=n??(i?`This provider authorizes through its own login flow; there is no key to paste.`:e.requiresAccount?`Create a credential on the provider site, then add it as an account below.`:`This provider needs no credential.`);return(0,$.jsx)(U,{density:`compact`,children:(0,$.jsx)(V,{children:(0,$.jsxs)(X,{gap:`12px`,className:`items-center flex-wrap`,children:[(0,$.jsxs)(`span`,{className:`min-w-110 flex-1 text-caption text-text-secondary`,children:[a,r?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`br`,{}),r]}):null]}),t?(0,$.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,title:t,className:_({size:`sm`,className:`shrink-0 no-underline`}),children:[(0,$.jsx)(`span`,{className:`btn-icon-wrapper`,"aria-hidden":`true`,children:(0,$.jsx)(Me,{size:13})}),i?`Sign in`:`Get API Key`]}):null]})})})}function Zt({provider:e}){let t=Ae(),[n,r]=(0,Q.useState)(!1),[i,a]=(0,Q.useState)(e.baseUrl??``);(0,Q.useEffect)(()=>{a(e.baseUrl??``)},[e.providerId,e.baseUrl]);let o=(e.baseUrl??``).replace(/\/+$/,``),s=i.trim().replace(/\/+$/,``),c=s!==o,l=s.length>0&&c&&!t.isPending;return(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Custom Provider Endpoint`,subtitle:`Upstream base URL`,icon:(0,$.jsx)(d,{size:16})}),(0,$.jsx)(V,{children:(0,$.jsxs)(Y,{gap:`12px`,children:[n?(0,$.jsx)(q,{label:`Base URL`,id:`custom-provider-base-url`,type:`url`,value:i,onChange:e=>a(e.target.value),placeholder:`https://api.example.com/v1`,autoFocus:!0}):(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`text-micro font-semibold uppercase tracking-label text-text-tertiary`,children:`Base URL`}),(0,$.jsx)(`code`,{className:`mt-1 block min-w-0 break-all font-mono text-caption text-text-primary`,children:e.baseUrl??`Not configured`})]}),(0,$.jsxs)(X,{gap:`8px`,className:`w-full flex-wrap`,justify:`end`,children:[n?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{size:`sm`,variant:`primary`,icon:(0,$.jsx)(ht,{size:13}),disabled:!l,loading:t.isPending,onClick:()=>{l&&t.mutate({providerId:e.providerId,request:{baseUrl:s}},{onSuccess:()=>r(!1)})},children:`Save endpoint`}),(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(P,{size:13}),disabled:t.isPending,onClick:()=>{a(e.baseUrl??``),r(!1)},children:`Cancel`})]}):(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(I,{size:13}),onClick:()=>r(!0),children:`Edit endpoint`}),e.requiresAccount?(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(N,{size:13}),onClick:()=>{let e=document.getElementById(`provider-accounts`);e?.scrollIntoView({behavior:`smooth`,block:`start`}),e?.focus({preventScroll:!0})},children:`Manage API keys`}):null]})]})})]})}var Qt={quota_fetch_failed:`Quota unreachable`,quota_exhausted:`Quota exhausted`,policy_blocked:`Policy blocked`,rate_limit_transient:`Rate limited`,missing_credential:`No credential`,validation_required:`Verification required`},$t=new Set([`quota_fetch_failed`]);function en(e){return e===void 0||e.length===0?!1:!$t.has(e)}function tn(e){return e===`oauth`?`Re-login required`:`Replace API key`}function nn(e,t){return e===`auth_invalidated`?tn(t):Qt[e]??e}var rn=/https?:\/\/[^\s"'\\]+/;function an(e){if(e)return rn.exec(e)?.[0]}function on({cooldowns:e,reason:t}){if(!e)return null;let n=Qe(e.until),r=`Soonest: ${e.modelId} — ${n}`;return(0,$.jsxs)(K,{tone:`warn`,dot:!0,title:t?`${t} — ${r}`:r,children:[e.count,` model`,e.count===1?``:`s`,` cooling · `,n]})}function sn(e){if(e.credentialKind===`oauth`)return`OAuth`;if(e.credentialMode===`jwt`)return`JWT`}function cn(e){if(!en(e.lastErrorCategory)||e.lastErrorCategory===`quota_exhausted`&&ct(e))return null;let t=nn(e.lastErrorCategory,e.credentialKind),n=e.lastError??e.lastErrorCategory;if(e.lastErrorCategory===`validation_required`){let r=an(e.lastError);if(r!==void 0)return(0,$.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer noopener`,title:n,children:(0,$.jsxs)(K,{tone:`warn`,children:[t,(0,$.jsx)(Me,{size:12,className:`shrink-0`,"aria-hidden":`true`})]})})}return(0,$.jsx)(K,{tone:`warn`,title:n,children:t})}function ln(e){return e.credentialKind===`oauth`?`blue`:`ok`}function un({account:e}){let t=e.cooldownUntil?new Date(e.cooldownUntil).getTime():NaN,n=Number.isFinite(t)&&t>Date.now(),r=ct(e);if(e.status===`disabled`){let t=sn(e),n=e.lastErrorCategory===`auth_invalidated`;return(0,$.jsxs)(X,{gap:`4px`,children:[(0,$.jsxs)(K,{tone:`disabled`,dot:!0,title:e.lastError,children:[`Disabled`,t?` - ${t}`:``]}),n?(0,$.jsx)(K,{tone:`warn`,title:e.lastError,children:tn(e.credentialKind)}):cn(e),(0,$.jsx)(on,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]})}return e.status===`active`?(0,$.jsxs)(X,{gap:`4px`,children:[(0,$.jsxs)(K,{tone:ln(e),dot:!0,children:[`Active`,sn(e)?` - ${sn(e)}`:``]}),cn(e),(0,$.jsx)(on,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]}):e.status===`cooldown`||n?(0,$.jsxs)(X,{gap:`4px`,children:[(0,$.jsxs)(K,{tone:`warn`,dot:!0,children:[`Cooldown`,sn(e)?` - ${sn(e)}`:``,` `,e.cooldownUntil?`(${Qe(e.cooldownUntil)})`:``]}),cn(e),(0,$.jsx)(on,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]}):(0,$.jsx)(K,{tone:`disabled`,children:`Disabled`})}function dn(e){if(e===void 0)return;let t=new Date(e).getTime();if(Number.isFinite(t))return t<=Date.now()?`Expired ${new Date(e).toLocaleDateString()}`:Qe(e,!1)}function fn({windows:e}){if(e===void 0||e.length===0)return null;let t=0,n=0,r=!1,i=null;for(let a of e){if(a.accounting!==`pooled`){typeof a.remainingPercent==`number`&&Number.isFinite(a.remainingPercent)&&(i=i===null?a.remainingPercent:Math.min(i,a.remainingPercent));continue}let e=typeof a.limit==`number`&&Number.isFinite(a.limit)?a.limit:null,o=typeof a.remaining==`number`&&Number.isFinite(a.remaining)?a.remaining:e!==null&&typeof a.used==`number`&&Number.isFinite(a.used)?e-a.used:null;o!==null&&e!==null&&(t+=Math.max(0,o),n+=e,r=!0)}let a=null;return r?a=`${pn(t)} of ${pn(n)}`:i!==null&&(a=`${Math.round(i)}% left`),a===null?null:(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,"data-tone":r&&t<=0||(i??100)<=10?`warn`:void 0,title:r?`${pn(t)} credits available of ${pn(n)}`:`Lowest remaining percent across this account's quota windows`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Quota`}),a]})}function pn(e){return e.toLocaleString(void 0,{maximumFractionDigits:1})}function mn({providerId:e,account:t,onClose:n}){let r=R(),[i,a]=(0,Q.useState)(``),o=t.label||t.id.slice(0,8),s=r.isPending,c=i.trim().length>0&&!s,l=async()=>{try{a(await navigator.clipboard.readText())}catch{y.error(`Clipboard access denied`)}};return(0,$.jsx)(F,{open:!0,onClose:n,title:`Replace API key — ${o}`,width:560,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:s,children:`Cancel`}),(0,$.jsx)(g,{size:`sm`,variant:`primary`,disabled:!c,onClick:()=>{let a=i.trim();a&&r.mutate({providerId:e,accountId:t.id,request:{secret:a}},{onSuccess:()=>{y.success(`API key replaced`,o),n()},onError:e=>{let t=e instanceof Error?e.message:`Unable to update account`;y.error(`Failed to replace key`,t)}})},children:s?`Saving…`:`Replace key`})]}),children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,$.jsx)(`p`,{className:`m-0 text-caption text-text-secondary`,children:`Paste the new key for this account. The old key stops working immediately; the account keeps its label, history, and routing.`}),(0,$.jsxs)(Y,{gap:`6px`,className:`min-w-0`,children:[(0,$.jsx)(`label`,{className:`text-caption font-semibold text-text-secondary`,children:`New API key`}),(0,$.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),placeholder:`Paste the replacement key…`,rows:4,spellCheck:!1,autoFocus:!0,className:`font-mono tabular-nums w-full min-w-0 min-h-65 rounded-control border border-inner-border bg-input-bg px-6 py-5 text-caption text-text-primary resize-y box-border`}),(0,$.jsx)(X,{gap:`8px`,className:`justify-end`,children:(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void l(),children:`Paste`})})]})]})})}function hn({providerId:e,account:t,inflight:n,quota:r,selected:a,onToggleSelect:o,onDelete:s}){let c=R(),l=we(),u=it(t.id),d=t.status===`disabled`,f=t.cooldownUntil?new Date(t.cooldownUntil).getTime():NaN,p=Number.isFinite(f)&&f>Date.now(),m=t.status===`cooldown`||p,[h,_]=(0,Q.useState)(!1),[v,b]=(0,Q.useState)(!1),[,C]=(0,Q.useState)(0),[w,T]=(0,Q.useState)(!1),[E,D]=(0,Q.useState)(``),ee=ot(e),O=(t.label?.match(/[^\s@]+@[^\s@]+/)?.[0]??t.label)||t.id.slice(0,8),k=ee.enabled?`Mysterious accounts`:O,A=dn(t.tokenExpiresAt),j=st(t),M=Math.max(p&&t.cooldownUntil?f:0,j??0);(0,Q.useEffect)(()=>{if(M<=Date.now())return;let e=setInterval(()=>C(e=>e+1),1e3);return()=>clearInterval(e)},[M]);let te=()=>{let n=E.trim();T(!1),n&&n!==(t.label??``)&&c.mutate({providerId:e,accountId:t.id,request:{label:n}},{onSuccess:()=>y.success(`Account renamed`,n),onError:e=>y.error(`Rename failed`,e.message??`Unable to rename account`)})};return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`account-row account-row-grid grid items-center gap-5 px-5 py-4 border rounded-control bg-surface-2 ${a?`border-accent`:`border-inner-border`} hover:bg-hover`,role:`listitem`,"data-selected":a?`true`:void 0,style:{opacity:d?.62:1},children:[(0,$.jsx)(`div`,{className:`flex items-center`,children:(0,$.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(t.id,e.target.checked),"aria-label":`Select ${k}`,className:`cursor-pointer`})}),(0,$.jsxs)(`div`,{className:`min-w-0 flex flex-col gap-1.5`,children:[(0,$.jsx)(`div`,{className:`flex items-center gap-3 min-w-0`,children:w?(0,$.jsx)(q,{value:E,onChange:e=>D(e.target.value),onKeyDown:e=>{e.key===`Enter`&&te(),e.key===`Escape`&&T(!1)},onBlur:te,autoFocus:!0,"aria-label":`Account label`,className:`text-body max-w-120`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{className:`text-body font-semibold text-text-primary min-w-0 overflow-hidden text-ellipsis whitespace-nowrap`,title:t.label||t.id,children:k}),(0,$.jsx)(`button`,{type:`button`,className:`shrink-0 grid place-items-center w-10 h-10 p-0 border-0 bg-transparent text-text-tertiary cursor-pointer rounded-tiny hover:bg-inner-border hover:text-text-primary`,title:`Rename account`,"aria-label":`Rename ${k}`,onClick:()=>{D(t.label??``),T(!0)},children:(0,$.jsx)(I,{size:11})})]})}),(0,$.jsxs)(`div`,{className:`flex items-center flex-nowrap gap-2 min-w-0 overflow-hidden`,children:[(0,$.jsx)(un,{account:t}),A?(0,$.jsx)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:A,children:A}):null]}),(0,$.jsxs)(`div`,{className:`flex items-center flex-wrap gap-2 min-w-0`,children:[(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Today: ${t.usageToday.totalTokens.toLocaleString()} tokens, ${t.usageToday.requests.toLocaleString()} requests`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Today`}),t.usageToday.totalTokens.toLocaleString(),` tok · `,t.usageToday.requests.toLocaleString(),` req`]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Lifetime totals are backfilled from telemetry still retained when tracking starts; new totals survive telemetry cleanup.`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`All time`}),t.usageAllTime.totalTokens.toLocaleString(),` tok · `,t.usageAllTime.requests.toLocaleString(),` req`]}),(0,$.jsx)(fn,{windows:r}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Concurrency comes from this provider’s Routing Strategy; accounts carry no manual ceilings.`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`In flight`}),n?.toLocaleString()??`—`]})]})]}),(0,$.jsxs)(`div`,{className:`account-row-actions flex items-center justify-end gap-3 flex-wrap`,children:[(0,$.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,$.jsx)(i,{size:12}),label:`Health`,"aria-label":`Health for ${k}`,onClick:()=>_(!0),title:`View Health & Error History`}),(0,$.jsx)(g,{size:`icon`,variant:`secondary`,icon:u.isPending?(0,$.jsx)(S,{size:12,className:`animate-spin`}):(0,$.jsx)(x,{size:12}),label:u.isPending?`Testing…`:`Test`,"aria-label":`Test ${k}`,disabled:u.isPending,onClick:()=>{u.mutate(void 0,{onSuccess:e=>{e?.ok?y.success(`Account test passed`,k):y.error(`Account test failed`,e?.message??`Provider reported an error`)},onError:e=>y.error(`Account test failed`,e.message??`Unable to test account`)})},title:`Refresh quota and health for this account`}),(0,$.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,$.jsx)(N,{size:12}),label:`Edit key`,"aria-label":`Replace API key for ${k}`,onClick:()=>b(!0),title:`Replace API key`}),(0,$.jsx)(g,{size:`icon`,variant:`secondary`,icon:d?(0,$.jsx)(ft,{size:12}):(0,$.jsx)(ie,{size:12}),label:d?`Enable`:`Disable`,"aria-label":d?`Enable ${k}`:`Disable ${k}`,disabled:c.isPending,onClick:()=>{let n=d;c.mutate({providerId:e,accountId:t.id,request:{status:n?`active`:`disabled`}},{onSuccess:()=>y.success(n?`Account enabled`:`Account disabled`,k),onError:e=>y.error(`Update failed`,e.message??`Unable to update account`)})},title:d?`Enable account`:`Disable account`}),m?(0,$.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,$.jsx)(oe,{size:12,className:l.isPending?`animate-spin`:``}),label:l.isPending?`Recovering…`:`Recover`,"aria-label":`Recover ${k}`,disabled:l.isPending,onClick:()=>l.mutate({providerId:e,accountId:t.id}),title:`Clear cooldown / restore active status`}):null,(0,$.jsx)(g,{size:`icon`,variant:`danger`,icon:(0,$.jsx)(ce,{size:12}),label:`Delete`,"aria-label":`Delete ${k}`,onClick:()=>s(t),title:`Delete account`})]})]}),h&&(0,$.jsx)(at,{summary:{providerId:e,accountId:t.id,title:t.label||t.id.slice(0,8),status:t.status,errorCategory:t.lastErrorCategory??void 0,errorMessage:t.lastError??void 0,emptyMessage:`Status transitions, rate limits, and auto-recoveries will appear here.`,staticToken:t.staticToken===!0,credentialKind:t.credentialKind,credentialMode:t.credentialMode,jwtIssuer:t.jwtIssuer},onClose:()=>_(!1)}),v&&(0,$.jsx)(mn,{providerId:e,account:t,onClose:()=>b(!1)})]})}var gn=[`access`,`accessToken`,`access_token`,`sessionToken`,`session_token`,`token`,`apiKey`,`api_key`,`key`,`credential`,`pat`,`secret`],_n=[`refresh`,`refreshToken`,`refresh_token`],vn=[`credentialKind`,`providerId`,`accessToken`],yn=[`accounts`,`items`,`connections`],bn=[`email`,`name`,`accountId`,`account_id`,`id`,`login`,`username`];function xn(e){if(typeof e==`object`&&e&&!Array.isArray(e))return Object.fromEntries(Object.entries(e))}function Sn(e){let t=e.data;if(typeof t==`string`)try{return xn(JSON.parse(t))}catch{return}return xn(t)}function Cn(e){for(let t of gn){let n=e[t];if(typeof n==`string`&&n.trim().length>0)return{value:n.trim(),extracted:!0,source:t}}let t=Sn(e);if(t)for(let e of gn){let n=t[e];if(typeof n==`string`&&n.trim().length>0)return{value:n.trim(),extracted:!0,source:`data.${e}`}}}function wn(e){for(let t of bn){let n=e[t];if(typeof n==`string`&&n.trim().length>0)return n.trim()}let t=Sn(e);if(t)for(let e of bn){let n=t[e];if(typeof n==`string`&&n.trim().length>0)return n.trim()}}function Tn(e){let t=(e,t)=>t.some(t=>typeof e[t]==`string`||typeof e[t]==`number`),n=e=>t(e,_n);if(n(e))return!0;let r=Sn(e);return r?n(r):!1}function En(e){let t=e.trim().split(`.`);if(t.length===3)try{let e=t[1].replaceAll(`-`,`+`).replaceAll(`_`,`/`),n=e.padEnd(e.length+(4-e.length%4)%4,`=`);return xn(JSON.parse(atob(n)))}catch{return}}function Dn(e){let t=En(e)?.exp;if(typeof t!=`number`||!Number.isFinite(t))return;let n=new Date(t*1e3);return Number.isFinite(n.getTime())?n.toISOString():void 0}function On(e){let t={},n=0;for(let r of e.split(/\r?\n/)){let e=/^\s*([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(r),i=e?.[1],a=e?.[2];i!==void 0&&a!==void 0&&(t[i]=a.trim(),n+=1)}return n>0?t:void 0}function kn(e){if(e.startsWith(`{`)||e.startsWith(`[`))try{return JSON.parse(e)}catch{return}}var An=[{id:`codebuddy`,counterpart:`WorkBuddy`},{id:`workbuddy`,counterpart:`CodeBuddy`}];function jn(e,t){let n=`${e} ${t}`.toLowerCase().replace(/[^a-z]/g,``);for(let e of An)if(n.includes(e.id))return{provider:e.id,counterpart:e.counterpart}}function Mn(e){let t=e.trim(),n=xn(kn(t))??On(t);return n&&Tn(n)?`oauth`:En((n?Cn(n)?.value:void 0)??t)===void 0?`api_key`:`jwt`}function Nn(e){return e.length!==0&&!!(e.some(e=>Array.isArray(e.cookies)&&(typeof e.domain==`string`||typeof e.originalUrl==`string`))||e.every(e=>typeof e.name==`string`&&typeof e.value==`string`&&(e.domain!==void 0||e.path!==void 0||e.expirationDate!==void 0)))}function Pn(e,t){let n,r=!1,i=(e,t)=>{let i=e.toLowerCase();(i===`userid`||i===`uid`||i===`accountid`||i===`cuserid`)&&(n||=t.replace(/^"|"$/g,``).trim()),(i.includes(`token`)||i.includes(`ph`)||i.includes(`auth`)||i.includes(`session`))&&(r=!0)};for(let e of t)if(Array.isArray(e.cookies)){for(let t of e.cookies)if(t&&typeof t==`object`){let e=t;typeof e.name==`string`&&typeof e.value==`string`&&i(e.name,e.value)}}else typeof e.name==`string`&&typeof e.value==`string`&&i(e.name,e.value);return{value:e,kind:r?`oauth`:`api_key`,...n?{identity:n}:{}}}function Fn(e){let t=e.credentialKind;if(typeof t==`string`&&typeof e.accessToken==`string`&&vn.every(t=>t in e)){let n=typeof e.label==`string`&&e.label.trim().length>0?e.label.trim():void 0,r=e.accessToken,i=t===`oauth`&&Tn(e);return{value:i?JSON.stringify(e):r,kind:i?`oauth`:`api_key`,...n?{identity:n}:{}}}let n=Cn(e),r=Tn(e)?`oauth`:Mn(n?.value??JSON.stringify(e)),i=r===`oauth`?JSON.stringify(e):n?.value??JSON.stringify(e),a=wn(e);return a?{value:i,kind:r,identity:a}:{value:i,kind:r}}function In(e){for(let t of yn){let n=e[t];if(!Array.isArray(n))continue;let r=n.map(e=>xn(e)).filter(e=>e!==void 0);if(r.length>0)return r}}function Ln(e){let t=e.trim();if(!t)return[];let n=kn(t);if(Array.isArray(n)){let e=n.map(e=>xn(e)).filter(e=>e!==void 0);if(e.length>0)return Nn(e)?[Pn(t,e)]:e.map(Fn)}else{let e=xn(n);if(e){let t=In(e);return t?t.map(Fn):[Fn(e)]}}let r=t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0);if(r.length===0)return[];if(r.length===1){let e=On(r[0]);return e?[Fn(e)]:Rn(r[0])}let i=On(t);return i&&(Cn(i)||Object.keys(i).length===r.length)?[Fn(i)]:r.flatMap(Rn)}function Rn(e){let t=xn(kn(e));if(t){let e=In(t);return e?e.map(Fn):[Fn(t)]}return[{value:e,kind:Mn(e)}]}function zn(e,t,n){let r=new Set(n),i=1;return e.map(e=>{let n=e.identity;if(!n){for(;r.has(`${t}-${i}`);)i+=1;n=`${t}-${i}`,i+=1}let a=n,o=2;for(;r.has(a);)a=`${n} (${o++})`;return r.add(a),a})}function Bn(e,t=50){if(t<1)throw RangeError(`chunk size must be at least 1`);let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}var Vn=2097152,Hn=Vn/1048576;function Un({providerId:e,accounts:t,onClose:n}){let r=Ce(),i=Fe(),[a,o]=(0,Q.useState)(``),[s,c]=(0,Q.useState)(``),[l,u]=(0,Q.useState)(!1),[d,f]=(0,Q.useState)(`auto`),[p,m]=(0,Q.useState)(void 0),h=Ln(s),v=h.length>1,b=h.length===1?h[0]:void 0,x=d===`auto`?b?.kind:d,S=b&&x===`jwt`?Dn(b.value):void 0,C=h.length>0?jn(e,s):void 0,w=C!==void 0&&p!==s,T=t.map(e=>e.label),E=v?zn(h,e,T):[],D=e=>{let t=d===`auto`?e.kind===`jwt`?`jwt`:`auto`:d;return{credentialKind:t===`auto`&&e.kind===`oauth`?`oauth`:`api_key`,credentialMode:t,secret:e.value}},ee=r.isPending||l,O=async()=>{try{let e=await navigator.clipboard.readText();c(e);let t=Ln(e);if(t.length>1)y.success(`Pasted from clipboard`,`Detected ${t.length} credentials`);else{let e=t[0]?.kind??`api_key`,n=e===`oauth`?`OAuth export`:e===`jwt`?`Static JWT`:`API key`;y.success(`Pasted from clipboard`,`Detected: ${n}`)}}catch{y.error(`Clipboard access denied`)}},k=e=>{if(e.size>Vn){y.error(`File too large`,`Credential files must be ${Hn} MB or smaller.`);return}let t=new FileReader;t.onload=()=>{let n=typeof t.result==`string`?t.result:``;c(n);let r=Ln(n);if(r.length===0){y.error(`Nothing to import`,`That file held no credential the gateway recognises.`);return}y.success(`Imported ${e.name}`,r.length>1?`Detected ${r.length} credentials`:r[0]?.kind===`oauth`?`Detected: OAuth export`:`Detected: API key`)},t.onerror=()=>y.error(`Could not read that file`),t.readAsText(e)},A=async()=>{if(h.length!==0&&!w){if(h.length===1){let t=h[0];r.mutate({providerId:e,request:{label:(a.trim()||t.identity)??void 0,...D(t)}},{onSuccess:()=>{y.success(`Account connected`,`New ${t.kind===`oauth`?`OAuth`:t.kind===`jwt`?`Static JWT`:`API key`} account registered successfully`),n()},onError:e=>y.error(`Failed to add account`,e.message??`Invalid credentials`)});return}u(!0);try{let t=Bn(h.map((e,t)=>({label:E[t],...D(e)}))),r=0,a=[],o=!1;for(let[n,s]of t.entries())try{let t=await i.mutateAsync({providerId:e,accounts:s});r+=t.created;let o=n*50;for(let e of t.results)e.ok||a.push(`${E[o+e.index]??o+e.index}: ${e.error??`rejected`}`)}catch(e){o=!0,a.push(`chunk ${n+1}/${t.length}: ${me(e,`request failed`)}`);break}let s=a.length;r>0&&y.success(`${r} account${r===1?``:`s`} added`,o?`stopped partway; ${s} failed`:s>0?`${s} skipped`:void 0),s>0&&y.error(`${s} account${s===1?``:`s`} skipped`,a.slice(0,5).join(`
2
- `)+(s>5?`\n…and ${s-5} more`:``)),r>0&&n()}finally{u(!1)}}};return(0,$.jsx)(F,{open:!0,onClose:n,title:`Add Account (API key / JSON)`,width:560,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:ee,children:`Cancel`}),(0,$.jsx)(g,{size:`sm`,variant:`primary`,disabled:ee||h.length===0,onClick:()=>void A(),children:ee?`Connecting...`:w?`Confirm below`:v?`Add ${h.length} Accounts`:`Add Account`})]}),children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[!v&&(0,$.jsx)(q,{label:`Account label (optional)`,value:a,onChange:e=>o(e.target.value),placeholder:b?.identity??`${e} account`}),(0,$.jsx)(J,{label:`Credential type`,id:`credential-mode`,value:d,onValueChange:e=>f(e===`jwt`||e===`api_key`?e:`auto`),options:[{value:`auto`,label:`Auto — detect JWT, OAuth, or API key`},{value:`jwt`,label:`JWT — static, no refresh`},{value:`api_key`,label:`API key — do not decode as JWT`}]}),(0,$.jsxs)(Y,{gap:`6px`,className:`min-w-0`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,$.jsx)(`label`,{className:`text-caption font-semibold text-text-secondary`,children:`API key, OAuth token, or exported JSON — one or many`}),v?(0,$.jsxs)(K,{tone:`accent`,children:[`Detected: `,h.length,` accounts`]}):b?(0,$.jsxs)(K,{tone:x===`oauth`||x===`jwt`?`accent`:`default`,children:[`Detected:`,` `,x===`oauth`?`OAuth`:x===`jwt`?`Static JWT`:`API key`,b.identity?` · ${b.identity}`:``]}):null,b&&x===`jwt`?(0,$.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[`Static JWT · no refresh token`,S?` · expires ${new Date(S).toLocaleString()}`:` · no expiry claim`]}):null]}),(0,$.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),placeholder:`Paste one credential, or many — one per line, a JSON array, or newline-delimited OAuth exports. Kind and account naming are detected automatically…`,rows:6,spellCheck:!1,className:`font-mono tabular-nums w-full min-w-0 min-h-65 rounded-control border border-inner-border bg-input-bg px-6 py-5 text-caption text-text-primary resize-y box-border`}),(0,$.jsxs)(X,{gap:`8px`,className:`justify-end`,children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void O(),children:`Paste`}),(0,$.jsxs)(`label`,{className:_({size:`sm`,className:`cursor-pointer`}),children:[(0,$.jsx)(`input`,{type:`file`,accept:`.json,.txt,.jsonl,.ndjson,application/json,text/plain`,"aria-label":`Import credentials from a file`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&k(t)}}),`Import file`]})]})]}),v&&(0,$.jsx)(`div`,{className:`flex flex-col gap-2 max-h-75 overflow-y-auto rounded-control border border-inner-border bg-surface-2 px-4 py-5`,children:h.map((e,t)=>(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 text-badge`,children:[(0,$.jsx)(`span`,{className:`truncate min-w-0`,children:E[t]}),(0,$.jsx)(K,{tone:e.kind===`oauth`?`accent`:`default`,children:e.kind===`oauth`?`OAuth`:`API key`})]},t))}),C&&(0,$.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-control border border-warning-line bg-surface-2 px-4 py-5`,role:`alert`,children:[(0,$.jsx)(`div`,{className:`flex items-start gap-3`,children:(0,$.jsx)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:`Cross-channel credential`})}),(0,$.jsxs)(`p`,{className:`text-caption text-text-primary`,children:[`This looks like a `,C.provider,` credential.`,` `,C.provider,` and `,C.counterpart,` tokens are interchangeable — one works in the other — but using a token on a channel it was not issued for can raise the risk of the account being banned, because it appears active somewhere it never authenticated. The same applies in reverse.`]}),w?(0,$.jsxs)(X,{gap:`8px`,className:`justify-end`,children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>{c(``),n()},children:`Cancel`}),(0,$.jsx)(g,{size:`sm`,variant:`primary`,onClick:()=>m(s),children:`Add anyway`})]}):(0,$.jsx)(`p`,{className:`text-micro text-text-tertiary`,children:`Acknowledged — you can add this account now.`})]})]})})}function Wn(e){return e===`active`?0:e===`cooldown`?2:3}var Gn=[{value:`added-asc`,label:`Added · oldest`},{value:`added-desc`,label:`Added · newest`},{value:`label-asc`,label:`Name · A–Z`},{value:`label-desc`,label:`Name · Z–A`},{value:`status-asc`,label:`Status · active first`},{value:`status-desc`,label:`Status · disabled first`},{value:`lastCheck-desc`,label:`Last check · newest`},{value:`lastCheck-asc`,label:`Last check · oldest`}];function Kn(e,t,n){let r=(e,t)=>(e.label||e.id).localeCompare(t.label||t.id)||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id);if(n===`added`)return e.sortIndex-t.sortIndex||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id);if(n===`label`)return r(e,t);if(n===`status`){let n=Wn(e.status)-Wn(t.status);return n===0?r(e,t):n}let i=new Date(e.lastSuccessAt??e.createdAt).getTime();return new Date(t.lastSuccessAt??t.createdAt).getTime()-i||r(e,t)}function qn({providerId:e,accounts:t,onDelete:n,showGrokProbe:r=!1,grokProbePending:i=!1,onGrokProbe:a}){let o=fe(),s=R(),c=we(),l=je(),d=et(e).data??new Map,f=rt(),p=(0,Q.useMemo)(()=>{let t=new Map;for(let n of f.data?.accounts??[])n.provider===e&&n.quota&&t.set(n.id,n.quota.windows);return t},[f.data,e]),[h,_]=(0,Q.useState)(``),[v,b]=(0,Q.useState)(new Set),[S,C]=(0,Q.useState)(`added-asc`),[w,T]=(0,Q.useState)(!1),[E,D]=(0,Q.useState)(null),[ee,O]=(0,Q.useState)(!1),k=h.trim().toLowerCase(),A=(0,Q.useMemo)(()=>k?t.filter(e=>{let t=`${e.label??``} ${e.id} ${e.credentialKind} ${e.status}`.toLowerCase();return k.split(/\s+/).every(e=>t.includes(e))}):t,[t,k]),j=(0,Q.useMemo)(()=>{let e=S.slice(0,S.lastIndexOf(`-`)),t=S.endsWith(`-desc`)?-1:1,n=[...A];return n.sort((n,r)=>t*Kn(n,r,e)),n},[A,S]),N=(0,Q.useMemo)(()=>t.filter(e=>v.has(e.id)),[t,v]),te=A.length>0&&A.every(e=>v.has(e.id)),ne=N.some(e=>e.status===`disabled`),F=N.some(e=>e.status!==`disabled`),I=N.length===0,re=(e,t)=>{b(n=>{let r=new Set(n);return t?r.add(e):r.delete(e),r})},ae=()=>{b(e=>{let t=new Set(e);if(te)for(let e of A)t.delete(e.id);else for(let e of A)t.add(e.id);return t})},le=async(e,t)=>{if(N.length===0)return;T(!0);let n=await Promise.allSettled(N.map(e=>t(e))),r=n.filter(e=>e.status===`rejected`).length,i=n.length-r;T(!1),r===0?y.success(`${e} complete`,`${i} account${i===1?``:`s`}`):y.error(`${e} partially failed`,`${i} succeeded, ${r} failed`)},ue=()=>le(`Recover`,t=>c.mutateAsync({providerId:e,accountId:t.id})),de=async()=>{t.length!==0&&(T(!0),D({done:0,total:t.length}),await u(t,3,async(e,n)=>{let r=await he(`/accounts/${encodeURIComponent(e.id)}/quota/refresh`,{method:`POST`});return D({done:n+1,total:t.length}),r}),await Promise.all([o.invalidateQueries({queryKey:L.quota.all}),o.invalidateQueries({queryKey:L.providers.all})]),T(!1),D(null),y.success(`Test complete`,`${t.length} account${t.length===1?``:`s`} tested`))},pe=t=>le(t?`Enable`:`Disable`,n=>s.mutateAsync({providerId:e,accountId:n.id,request:{status:t?`active`:`disabled`}})),me=async()=>{if(N.length!==0){T(!0);try{let t=await l.mutateAsync({providerId:e,accountIds:N.map(e=>e.id)}),n=new Date().toISOString().replace(/[:.]/g,`-`);Ue(`${e}-accounts-${n}.json`,JSON.stringify(t,null,2),`application/json`),y.success(`Accounts exported`,`${t.accounts.length} account${t.accounts.length===1?``:`s`} — contains plaintext credentials`)}catch(e){y.error(`Export failed`,e.message??`Unable to export accounts`)}finally{T(!1)}}};return(0,$.jsxs)(Y,{gap:`8px`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2 p-3 border border-inner-border rounded-control bg-surface-2`,children:[(0,$.jsxs)(`label`,{className:`relative w-full`,children:[(0,$.jsx)(se,{size:13,"aria-hidden":`true`,className:`pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary`}),(0,$.jsx)(q,{id:`accounts-search`,value:h,onChange:e=>_(e.target.value),placeholder:`Search accounts...`,"aria-label":`Search accounts`,className:`pl-9`})]}),(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,$.jsx)(g,{size:`sm`,variant:`primary`,icon:(0,$.jsx)(x,{size:12}),disabled:w||t.length===0,onClick:de,"aria-label":E===null?`Test all accounts`:`Testing accounts, ${E.done} of ${E.total} tested`,title:`Test every account, regardless of selection or filters`,children:E===null?`Test all`:`Tested ${E.done}/${E.total}`}),(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(oe,{size:12}),disabled:w||I,title:I?`Select at least one account to recover it`:`Clear cooldowns and retry-wait states on the selected accounts`,onClick:()=>void ue(),children:`Recover`}),(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(ft,{size:12}),disabled:w||!ne,title:I?`Select at least one disabled account to enable it`:ne?`Enable the selected accounts`:`No selected account is currently disabled`,onClick:()=>void pe(!0),children:`Enable`}),(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(ie,{size:12}),disabled:w||!F,title:I?`Select at least one enabled account to disable it`:F?`Disable the selected accounts`:`No selected account is currently enabled`,onClick:()=>void pe(!1),children:`Disable`}),(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(m,{size:12}),disabled:w||I,title:I?`Select at least one account to export`:`Download the selected accounts as JSON`,onClick:()=>void me(),children:`Export`}),(0,$.jsx)(g,{size:`sm`,variant:`danger`,icon:(0,$.jsx)(ce,{size:12}),disabled:w||I,title:I?`Select at least one account to delete`:`Delete ${N.length} selected account${N.length===1?``:`s`}`,onClick:()=>O(!0),children:`Delete`}),r?(0,$.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,$.jsx)(x,{size:12,className:i?`animate-spin`:``}),disabled:i||t.length===0,onClick:a,title:`Probe every Grok account with the live 407 streaming request`,children:i?`Testing…`:`Test 407`}):null,(0,$.jsx)(`label`,{className:`inline-flex h-15 shrink-0 items-center gap-2 text-caption font-semibold text-text-secondary [&_.radix-select-trigger]:font-semibold [&_.radix-select-trigger]:bg-hover [&_.radix-select-trigger]:text-text-primary`,children:(0,$.jsx)(J,{size:`sm`,value:S,onValueChange:e=>C(e),options:Gn,"aria-label":`Sort accounts by`})}),(0,$.jsxs)(`label`,{className:`inline-flex h-15 shrink-0 items-center gap-2 text-caption font-semibold text-text-secondary`,children:[(0,$.jsx)(`input`,{type:`checkbox`,checked:te,onChange:ae,"aria-label":`Select accounts`}),(0,$.jsx)(`span`,{children:`Select`})]}),I?null:(0,$.jsxs)(`button`,{type:`button`,onClick:()=>b(new Set),className:`inline-flex h-15 shrink-0 items-center gap-1 rounded-control border border-inner-border px-3 text-badge font-semibold text-text-secondary hover:bg-hover`,title:`Clear selection`,children:[N.length,` selected`,(0,$.jsx)(P,{size:11,"aria-hidden":`true`})]})]})]}),(0,$.jsx)(`div`,{className:`account-list flex flex-col gap-3 max-h-230 overflow-y-auto pr-1 [container-type:inline-size] [container-name:account-list]`,role:`list`,"aria-label":`Provider accounts`,children:j.length===0?(0,$.jsx)(M,{compact:!0,icon:(0,$.jsx)(se,{size:20}),title:`No matching accounts`,message:k?`Nothing matches “${k}”. Clear the filter to see all ${t.length} account${t.length===1?``:`s`}.`:`This provider has no accounts yet.`}):j.map(t=>(0,$.jsx)(hn,{providerId:e,account:t,inflight:d.get(t.id)??t.inflight,quota:p.get(t.id),selected:v.has(t.id),onToggleSelect:re,onDelete:n},t.id))}),(0,$.jsx)(`div`,{className:`flex items-center justify-between text-badge text-text-tertiary`,children:(0,$.jsxs)(`span`,{children:[`Showing `,A.length,` account`,A.length===1?``:`s`,k?` (filtered from ${t.length})`:``]})}),(0,$.jsx)(ge,{open:ee,onClose:()=>{w||O(!1)},onConfirm:async()=>{await le(`Delete`,async e=>{let t=e.tenantId===null?`/global/accounts/${encodeURIComponent(e.id)}`:`/accounts/${encodeURIComponent(e.id)}`;await he(t,{method:`DELETE`}),o.removeQueries({queryKey:L.quota.account(e.id),exact:!0})}),b(new Set),O(!1),await Promise.all([o.invalidateQueries({queryKey:L.providers.accounts(e)}),o.invalidateQueries({queryKey:L.providers.all}),o.invalidateQueries({queryKey:L.quota.all})])},title:`Delete ${N.length} account${N.length===1?``:`s`}?`,message:`This permanently removes the selected accounts and their credentials. This cannot be undone.`,confirmLabel:`Delete`,danger:!0})]})}function Jn(e){let t=e.trim(),n=e=>{try{return new URL(e).searchParams}catch{return}},r=n(t)??new URLSearchParams(t.startsWith(`?`)?t.slice(1):t),i=r.get(`code`);if(i)return{code:i};let a=r.get(`error_description`)??r.get(`error`);return a?{error:`The provider refused the login: ${a}`}:r.has(`authCodeInfo`)||r.has(`refreshToken`)||r.has(`refresh_token`)?{code:r.toString()}:n(t)!==void 0||t.startsWith(`?`)?{error:`That redirect URL carries no authorization code — copy the full URL from the address bar.`}:{code:t}}function Yn({providerId:e,authorizeUrl:t,state:n,popup:r,onClose:i}){let[a,o]=(0,Q.useState)(!1),[s,c]=(0,Q.useState)(``),l=Le(),u=lt(),d=fe(),m=Ne(e),h=(0,Q.useRef)(null),_=(0,Q.useRef)(!1);(0,Q.useEffect)(()=>{let t=setInterval(()=>{d.invalidateQueries({queryKey:L.providers.accounts(e)})},1500);return()=>clearInterval(t)},[d,e]),(0,Q.useEffect)(()=>{let e=m.data?.map(e=>e.id)??null;if(e!==null){if(h.current===null){h.current=new Set(e);return}_.current||e.find(e=>!h.current.has(e))!==void 0&&(_.current=!0,r.close(),y.success(`Account connected`,`OAuth login completed successfully`),i(!0))}},[m.data,r,i]);let v=()=>{r.close(),i(!1)},[b,x]=(0,Q.useState)(!1),C=()=>{x(!0),d.invalidateQueries({queryKey:L.providers.accounts(e)}).finally(()=>x(!1))},w=async()=>{try{let e=await navigator.clipboard.readText();if(!e.trim()){y.error(`Clipboard is empty`);return}c(e),y.success(`Pasted redirect URL`)}catch{y.error(`Clipboard unavailable on this origin`)}};return(0,$.jsx)(F,{open:!0,onClose:v,title:`Connect via OAuth`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:v,disabled:l.isPending,children:`Cancel`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:C,disabled:l.isPending||b,title:`You already approved in the popup — check now instead of waiting`,children:b?`Checking…`:`Complete`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,disabled:l.isPending||s.trim().length===0,onClick:()=>{let t=Jn(s);if(`error`in t){y.error(`OAuth callback failed`,t.error);return}l.mutate({providerId:e,code:t.code,state:n},{onSuccess:()=>{r.close(),y.success(`Account connected`,`OAuth login completed successfully`),i(!0)},onError:e=>y.error(`OAuth callback failed`,e.message??`Invalid or expired authorization code`)})},children:l.isPending?`Connecting…`:`Connect`})]}),children:(0,$.jsxs)(Y,{gap:`14px`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,$.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,$.jsx)(`span`,{className:`text-body font-semibold`,children:`Waiting for popup authorization…`})]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 1: Open this URL in your browser`}),(0,$.jsxs)(X,{gap:`8px`,children:[(0,$.jsx)(`a`,{className:`min-w-0 flex-1 font-mono text-badge text-accent overflow-hidden text-ellipsis whitespace-nowrap px-2.5 py-2 rounded-control bg-input-bg border border-inner-border`,href:t,target:`_blank`,rel:`noreferrer`,title:t,children:t}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:a?(0,$.jsx)(p,{size:12}):(0,$.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(t),o(!0),u(()=>o(!1),1500)},className:`shrink-0`,children:a?`Copied`:`Copy`})]}),(0,$.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:`A popup should open automatically. If it was blocked, open the URL above manually.`})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2.5 text-micro font-bold uppercase tracking-label text-text-tertiary`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,className:`flex-1 h-px bg-inner-border`}),(0,$.jsx)(`span`,{children:`Or complete manually`}),(0,$.jsx)(`span`,{"aria-hidden":`true`,className:`flex-1 h-px bg-inner-border`})]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 2: Paste the redirect URL here`}),(0,$.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:`If the redirect lands on an unreachable address, copy that page's full URL from your browser and paste it below — this works from any machine, not just localhost.`}),(0,$.jsxs)(X,{gap:`8px`,align:`flex-start`,children:[(0,$.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),placeholder:`http://127.0.0.1:59653/callback?code=…&state=… (or just the code)`,rows:2,spellCheck:!1,className:`w-full min-h-16 resize-y rounded-control border border-inner-border bg-input-bg px-2.5 py-2 font-mono text-badge text-text-primary box-border focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-1 flex-1`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void w(),className:`shrink-0`,children:`Paste`})]})]})]})})}function Xn(e){try{return new URL(e).host}catch{return e}}function Zn({providerId:e,parameters:t,onClose:n}){let r=Ve(),i=Te(),[a,o]=(0,Q.useState)(null),[s,c]=(0,Q.useState)(!1),[l,u]=(0,Q.useState)(!1),d=lt();(0,Q.useEffect)(()=>{let i=!1;return r.mutate({providerId:e,...t===void 0||Object.keys(t).length===0?{}:{parameters:t}},{onSuccess:e=>{i||o(e)},onError:e=>{i||(y.error(`Failed to start device login`,e.message??`Unable to start device authorization`),n())}}),()=>{i=!0}},[]);let m=(0,Q.useRef)(null),[h,_]=(0,Q.useState)(!1);return(0,Q.useEffect)(()=>{if(!a)return;let e=window.open(a.verificationUri,`cartethyia-device`,`popup,width=720,height=820`);return e?m.current=e:_(!0),()=>{let e=m.current;m.current=null,e&&!e.closed&&e.close()}},[a]),(0,Q.useEffect)(()=>{if(!a)return;let t=Date.now(),r=Math.max(1,a.expiresInSeconds)*1e3,o=!1,s=Math.max(1,a.intervalSeconds)*1e3,c=!1,l=0,u=()=>window.clearTimeout(l),d=e=>{u(),l=window.setTimeout(f,e)},f=()=>{if(!c){if(Date.now()-t>r){u(),y.error(`Device login expired`,`Please try again.`),n();return}o||(o=!0,i.mutate({providerId:e,deviceAuthId:a.deviceAuthId},{onSuccess:e=>{if(o=!1,!c){if(e.status===`complete`){u();let e=m.current;e&&!e.closed&&e.close(),y.success(`OAuth account connected`,`Device authorization complete`),n()}else e.status===`failed`?(u(),y.error(`Device login failed`,e.reason),n()):e.status===`slow_down`?(s=(e.retryAfterSeconds===void 0?s+5e3:Math.max(1,e.retryAfterSeconds)*1e3)+1e3,d(s)):(e.status===`pending`&&e.retryAfterSeconds!==void 0&&(s=Math.max(1,e.retryAfterSeconds)*1e3+1e3),d(s))}},onError:()=>{o=!1,c||d(s)}}))}};return d(s+1e3),()=>{c=!0,u()}},[a]),(0,$.jsx)(F,{open:!0,onClose:n,title:`Login with OAuth (device code)`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,children:`Cancel`}),null]}),children:(0,$.jsx)(Y,{gap:`14px`,children:a?(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,$.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,$.jsx)(`span`,{className:`text-body font-semibold`,children:`Waiting for authorization…`})]}),a.userCode?(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 1: Enter this code`}),(0,$.jsxs)(`div`,{className:`rounded-card border border-inner-border bg-surface-2 p-3.5 flex flex-col gap-1.5 items-center text-center`,children:[(0,$.jsx)(`div`,{className:`text-micro font-bold uppercase tracking-label text-text-tertiary`,children:`Device code`}),(0,$.jsx)(`div`,{className:`font-mono text-display font-bold tracking-code text-text-primary`,children:a.userCode}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:l?(0,$.jsx)(p,{size:12}):(0,$.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(a.userCode),u(!0),d(()=>u(!1),1500)},children:l?`Copied`:`Copy code`})]})]}):null,(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:a.userCode?`Step 2: Open the verification page`:`Open the verification page to authorize`}),(0,$.jsxs)(X,{gap:`8px`,children:[(0,$.jsx)(`a`,{className:`min-w-0 flex-1 font-mono text-badge text-accent overflow-hidden text-ellipsis whitespace-nowrap px-2.5 py-2 rounded-control bg-input-bg border border-inner-border`,href:a.verificationUri,target:`_blank`,rel:`noreferrer`,title:a.verificationUri,children:Xn(a.verificationUri)}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,$.jsx)(Me,{size:12}),onClick:()=>window.open(a.verificationUri,`_blank`,`noopener`),className:`shrink-0`,children:`Open`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:s?(0,$.jsx)(p,{size:12}):(0,$.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(a.verificationUri),c(!0),d(()=>c(!1),1500)},className:`shrink-0`,children:s?`Copied`:`Copy`})]}),(0,$.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:h?`The popup was blocked — open the page with Open above, finish signing in there, then press Check now.`:`The page opened in a popup. Finish signing in there — this dialog closes automatically once the account connects, or press Check now.`})]})]}):(0,$.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,$.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,$.jsx)(`span`,{className:`text-body font-semibold`,children:`Starting device authorization…`})]})})})}function Qn({providerId:e}){let[t,n]=(0,Q.useState)(!1),r=Se(e,t);return(0,$.jsxs)(U,{children:[(0,$.jsxs)(`button`,{type:`button`,onClick:()=>n(e=>!e),"aria-expanded":t,className:`card-header-bar w-full cursor-pointer list-none text-left`,children:[(0,$.jsxs)(`div`,{className:`card-header-left`,children:[(0,$.jsx)(`div`,{className:`card-header-icon`,children:(0,$.jsx)(i,{size:16,"aria-hidden":`true`})}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`font-bold text-text-primary`,children:`Activity Matrix`}),(0,$.jsxs)(`div`,{className:`text-caption text-text-secondary`,children:[`Daily token usage, last `,r.data?.days??30,` days · expand to load`]})]})]}),(0,$.jsx)(`div`,{className:`card-header-right`,children:(0,$.jsx)(Be,{size:14,"aria-hidden":`true`,className:v(`transition-transform`,t&&`rotate-180`)})})]}),t?(0,$.jsx)(ur,{matrix:r}):null]})}function $n(e){let t=new Map,n=new Map,r={requests:0,tokens:0,cachedTokens:0,costUsd:0};for(let i of e.rows){let e=t.get(i.day)??{tokens:0,models:new Map},a=i.inputTokens+i.outputTokens;e.tokens+=a;let o=i.model??`unknown`,s=e.models.get(o)??{tokens:0,requests:0};s.tokens+=a,s.requests+=i.requests,e.models.set(o,s),t.set(i.day,e);let c=n.get(o)??{tokens:0,requests:0};c.tokens+=a,c.requests+=i.requests,n.set(o,c),r.requests+=i.requests,r.tokens+=a,r.cachedTokens+=i.cachedInputTokens,r.costUsd+=i.costUsd}let i=Math.min(Math.max(e.days,1),366),a=new Date,o=Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()),s=[],c=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],l=0;for(let e of t.values())l=Math.max(l,e.tokens);let u=new Date(o-(i-1)*864e5),d=(u.getUTCDay()+6)%7,f=u.getTime()-d*864e5,p=[];for(;;){if(f>o){if(p.length>0||s.length===0){for(;p.length<7;)p.push(null);s.push({cells:p})}break}let e=new Date(f),n=e.toISOString().slice(0,10),r=t.get(n),i=r?[...r.models.entries()].map(([e,t])=>({name:e,tokens:t.tokens,requests:t.requests,color:er(e)})).sort((e,t)=>t.tokens-e.tokens):[],a=r?{day:n,label:`${c[(e.getUTCDay()+6)%7]} ${n.slice(5)}`,total:r.tokens,color:i[0]?.color??`var(--surface-2)`,models:i}:null;p.push(a),p.length===7&&(s.push({cells:p}),p=[]),f+=864e5}let m=[...n.entries()].map(([e,t])=>({name:e,tokens:t.tokens,requests:t.requests,color:er(e)})).sort((e,t)=>t.tokens-e.tokens);return{weeks:s,maxDay:l,totals:r,models:m}}function er(e){let t=5381;for(let n=0;n<e.length;n++)t=t*33^e.charCodeAt(n);let n=Math.abs(t)%360;return`hsl(${(n<60||n>110?n:n+130)%360} 65% 60%)`}function tr(e,t){if(e<=0||t<=0)return 0;let n=e/t,r=1;for(let e=1;e<nr.length;e++)n>e/(nr.length-1)&&(r=e);return Math.min(r,nr.length-1)}var nr=[0,.18,.38,.62,.9];function rr(e){return nr[Math.min(Math.max(Math.trunc(e),0),nr.length-1)]??0}function ir(e){let t=rr(e)*100;return t===0?`var(--surface-2)`:`color-mix(in srgb, var(--text-primary) ${t}%, transparent)`}function ar(e,t){if(t===0)return{backgroundColor:`var(--surface-2)`,borderColor:`var(--inner-border)`};let n=rr(t)*100;return{backgroundColor:`color-mix(in srgb, ${e.color} ${n}%, transparent)`,borderColor:`color-mix(in srgb, ${e.color} 45%, transparent)`}}function or(e){return[`${e.label} — ${G(e.total)} tokens`,...e.models.map(t=>`• ${t.name}: ${G(t.tokens)} (${Math.round(t.tokens/e.total*100)}%) · ${t.requests} req`)].join(`
3
- `)}var sr=`26px repeat(7, minmax(0, 1fr))`,cr=420,lr=360;function ur({matrix:e}){let t=(0,Q.useMemo)(()=>e.data?$n(e.data):void 0,[e.data]),n;return n=e.isPending?(0,$.jsx)(`p`,{className:`p-4 text-caption text-text-secondary`,children:`Loading activity…`}):e.isError?(0,$.jsx)(`p`,{className:`p-4 text-caption text-status-danger`,children:`Failed to load activity matrix.`}):!t||t.totals.requests===0?(0,$.jsx)(`p`,{className:`p-4 text-caption text-text-secondary`,children:`No usage recorded for this provider in the window.`}):(0,$.jsx)(fr,{view:t}),(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`div`,{className:`border-t border-inner-border`,children:(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 p-4 max-small:p-3 min-[641px]:grid-cols-4`,children:[(0,$.jsx)(dr,{label:`Total tokens`,value:G(t?.totals.tokens)}),(0,$.jsx)(dr,{label:`Requests`,value:(t?.totals.requests??0).toLocaleString(`en-US`)}),(0,$.jsx)(dr,{label:`Cached`,value:G(t?.totals.cachedTokens)}),(0,$.jsx)(dr,{label:`Est. cost`,value:T(t?.totals.costUsd)})]})}),(0,$.jsxs)(`div`,{className:`min-w-0 overflow-x-auto border-t border-inner-border p-4 max-small:p-3`,children:[n,t&&t.totals.requests>0?(0,$.jsxs)(`div`,{className:`mt-3 flex items-center justify-end gap-1.5 text-micro text-text-tertiary`,children:[(0,$.jsx)(`span`,{children:`Less`}),[0,1,2,3,4].map(e=>(0,$.jsx)(`span`,{className:`size-3 rounded-micro border border-inner-border`,style:{backgroundColor:ir(e)}},e)),(0,$.jsx)(`span`,{children:`More`})]}):null,t&&t.totals.requests>0&&t.models.length>0?(0,$.jsxs)(`details`,{className:`group mt-4 border-t border-inner-border pt-3`,children:[(0,$.jsxs)(`summary`,{className:`flex cursor-pointer list-none items-center justify-between gap-3 text-caption text-text-secondary [&::-webkit-details-marker]:hidden`,children:[(0,$.jsxs)(`span`,{className:`font-semibold`,children:[`Usage by model (`,t.models.length,`) · sorted by tokens`]}),(0,$.jsx)(Be,{size:14,"aria-hidden":`true`,className:`shrink-0 transition-transform group-open:rotate-180`})]}),(0,$.jsx)(`div`,{className:`mt-3 flex flex-col gap-2.5`,children:t.models.map(e=>{let n=t.totals.tokens>0?e.tokens/t.totals.tokens:0;return(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,$.jsx)(`span`,{className:`min-w-0 shrink truncate text-caption font-semibold`,style:{color:e.color},title:e.name,children:e.name}),(0,$.jsx)(`span`,{className:`h-2.5 min-w-0 flex-1 rounded-micro`,style:{backgroundColor:`var(--surface-2)`,backgroundImage:`linear-gradient(to right, ${e.color} ${Math.max(n*100,2)}%, transparent ${Math.max(n*100,2)}%)`}}),(0,$.jsxs)(`span`,{className:`shrink-0 font-mono text-caption text-text-secondary`,children:[G(e.tokens),` `,(0,$.jsxs)(`span`,{className:`text-text-tertiary`,children:[Math.round(n*100),`%`]}),` ·`,` `,e.requests.toLocaleString(`en-US`),` req`]})]},e.name)})})]}):null]})]})}function dr({label:e,value:t}){return(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`text-micro font-semibold uppercase tracking-label text-text-tertiary`,children:e}),(0,$.jsx)(`div`,{className:`mt-0.5 font-mono text-lg font-bold text-text-primary`,children:t})]})}function fr({view:e}){return(0,$.jsx)(`div`,{style:{minWidth:lr},children:(0,$.jsxs)(`div`,{className:`grid gap-1`,style:{gridTemplateColumns:sr,maxWidth:cr},children:[(0,$.jsx)(`div`,{}),[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`].map(e=>(0,$.jsx)(`div`,{className:`text-center text-micro text-text-tertiary`,children:e},e)),e.weeks.map((t,n)=>(0,$.jsxs)(`div`,{className:`contents`,children:[(0,$.jsxs)(`div`,{className:`flex items-center text-micro text-text-tertiary`,children:[`W`,n+1]}),t.cells.map((t,r)=>t===null?(0,$.jsx)(`div`,{},`${n}-${r}`):(0,$.jsx)(`div`,{className:`aspect-square cursor-pointer rounded-micro border border-inner-border transition-[outline-offset] hover:outline hover:outline-2 hover:outline-accent`,style:ar(t,tr(t.total,e.maxDay)),title:or(t)},t.day))]},n))]})})}function pr(e){let t={};for(let n of e)t[n.key]=n.defaultValue??``;return t}function mr(e,t){return e.filter(e=>e.required===!0&&(t[e.key]??``).trim().length===0).map(e=>e.key)}function hr({fields:e,values:t,onChange:n,idPrefix:r}){return e.length===0?null:(0,$.jsx)(Y,{gap:`10px`,children:e.map(e=>{let i=`${r}-${e.key}`,a=t[e.key]??``;return e.options&&e.options.length>0?(0,$.jsx)(J,{id:i,label:e.label,value:a,onValueChange:t=>n(e.key,t),options:e.options.map(e=>({value:e.value,label:e.label}))},e.key):(0,$.jsx)(q,{id:i,label:e.label,value:a,placeholder:e.placeholder??``,type:e.secret===!0?`password`:`text`,autoComplete:`off`,onChange:t=>n(e.key,t.target.value)},e.key)})})}function gr({providerId:e,providerName:t,fields:n,onClose:r}){let i=B(),[a,o]=(0,Q.useState)(``),[s,c]=(0,Q.useState)(``),[l,u]=(0,Q.useState)(()=>pr(n)),d=(0,Q.useMemo)(()=>mr(n,l),[n,l]);return(0,$.jsx)(F,{open:!0,onClose:r,title:`Import a ${t} credential`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:r,disabled:i.isPending,children:`Cancel`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,onClick:()=>{if(a.trim().length===0){y.error(`Credential required`,`Paste the token, key or exported JSON to import.`);return}if(d.length>0){y.error(`Missing required fields`,`Fill in: ${d.join(`, `)}`);return}i.mutate({providerId:e,credential:a.trim(),...Object.keys(l).length>0?{fields:l}:{},...s.trim().length>0?{accountLabel:s.trim()}:{}},{onSuccess:()=>{y.success(`Account imported`,`The credential was validated and saved`),r()},onError:e=>y.error(`Import failed`,e.message??`The provider rejected this credential`)})},disabled:i.isPending,icon:i.isPending?(0,$.jsx)(S,{size:13,className:`animate-spin`}):void 0,children:i.isPending?`Validating…`:`Import`})]}),children:(0,$.jsxs)(Y,{gap:`12px`,children:[(0,$.jsxs)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:[`The credential is checked against `,t,` before it is saved, so one that no longer works is reported here instead of being stored.`]}),(0,$.jsx)(hr,{fields:n,values:l,idPrefix:`import`,onChange:(e,t)=>u(n=>({...n,[e]:t}))}),(0,$.jsx)(q,{id:`import-account-label`,label:`Account label`,hint:`optional`,value:s,placeholder:e,onChange:e=>c(e.target.value)}),(0,$.jsx)(q,{id:`import-credential`,label:`Credential`,value:a,placeholder:`Paste the token, key, or exported JSON`,type:`password`,autoComplete:`off`,onChange:e=>o(e.target.value)})]})})}function _r(e,t,n){let r=n?.trim()??``,i=r.indexOf(` — `),a=i>0?r.slice(0,i):``,o=i>0?r.slice(i+3):r;return{title:`${e}/${t} probe failed${a.length>0?` via ${a}`:``}`,detail:o.length>0?o:`Unknown error`}}function vr(e,t,n){let{title:r,detail:i}=_r(e,t,n);return[r,i]}function yr(e){return e===`builtin`?`Built-in model`:e===`auto_free`?`Free tier, discovered from the provider`:e===`discovered`?`Fetched from provider`:`Added manually`}function br(e){return e===`auto_free`?`Free tier`:e===`discovered`?`Fetched`:`Manual`}var xr=[{key:`builtin`,label:`Built-in models`,hint:`Compiled catalog — can be disabled, not deleted`,matches:e=>e===null||e===`builtin`},{key:`auto_free`,label:`Free models (auto)`,hint:`Discovered from the provider's free tier`,matches:e=>e===`auto_free`},{key:`manual`,label:`Manually added`,hint:`Added by hand from the Add Model dialog`,matches:e=>e===`manual`},{key:`fetched`,label:`Fetched from provider`,hint:`Listed by the provider's /v1/models`,matches:e=>e!==null&&e!==`builtin`&&e!==`auto_free`&&e!==`manual`}],Sr={key:`disabled`,label:`Disabled models`,hint:`Turned off — not routable until re-enabled`};function Cr(){return vt.map(e=>({value:e,label:e===`auto`?`Thinking: auto`:e.charAt(0).toUpperCase()+e.slice(1)}))}function wr({value:e,onChange:t,disabled:n,id:r=`probe-thinking-effort`}){return(0,$.jsx)(`div`,{title:`Reasoning effort every test in this section sends. Auto leaves the model's own reasoning default in place.`,className:`min-w-74 shrink-0`,children:(0,$.jsx)(J,{id:r,"aria-label":`Thinking effort`,value:e,disabled:n,onValueChange:e=>t(e),options:Cr()})})}function Tr({providerId:e,provider:t,onClose:n}){let r=Ie(),i=He(),[a,o]=(0,Q.useState)(``),s=t?.supportedWireFamilies,c=t?.wireFamilyDefault!==void 0&&(s===void 0||s.includes(t.wireFamilyDefault))?t.wireFamilyDefault:s?.[0],l=(0,Q.useMemo)(()=>{let e=[`chat`,`responses`,`messages`],t=(s??[]).filter(t=>e.includes(t));return[...t,...e.filter(e=>!t.includes(e))]},[s]),[u,d]=(0,Q.useState)(c??`chat`),[f,p]=(0,Q.useState)(`auto`),[m,h]=(0,Q.useState)(`idle`),[_,v]=(0,Q.useState)(``),[b,C]=(0,Q.useState)(kr),w=a.trim(),T=w.toLowerCase().startsWith(`${e.toLowerCase()}/`)&&w.length>e.length+1?w.slice(e.length+1):w,E=T!==w,D=()=>{T&&(h(`testing`),v(``),r.mutate({providerId:e,request:{modelId:T,wireFamily:u,reasoningEffort:f,serviceKind:`llm`}},{onSuccess:e=>{e.ok?h(`passed`):(h(`failed`),v(e.error??`Model probe failed`))},onError:e=>{h(`failed`),v(e.message??`Model probe failed`)}}))};return(0,$.jsx)(F,{open:!0,onClose:n,title:`Add Custom Model`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:i.isPending,children:`Cancel`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,disabled:i.isPending||T.length===0,onClick:()=>{if(!T)return;let t=We(b.contextLimit),r=We(b.outputLimit);if(t===null||r===null){y.error(`Invalid limits`,`Use a token count such as 512k, 200000, or 1.5m.`);return}i.mutate({providerId:e,modelIds:[T],wireFamily:u,metadata:{contextLimit:t??null,outputLimit:r??null,passthrough:b.passthrough,image:b.passthrough?!0:b.image,reasoning:b.passthrough?!0:b.reasoning,toolCall:b.passthrough?!0:b.toolCall}},{onSuccess:()=>{y.success(`Custom model added`,`Sent to ${e}/${T}`),n()},onError:e=>y.error(`Failed to add model`,e.message??`Unable to register model`)})},children:i.isPending?`Adding...`:`Add Model`})]}),children:(0,$.jsxs)(Y,{gap:`10px`,children:[(0,$.jsxs)(X,{gap:`8px`,align:`flex-end`,children:[(0,$.jsx)(q,{label:`Model ID`,autoFocus:!0,placeholder:`e.g. gpt-4o, free-model-id`,value:a,onChange:e=>{o(e.target.value),h(`idle`),v(``)},onKeyDown:e=>{e.key===`Enter`&&T.length>0&&D()},className:`flex-1`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:m===`testing`?(0,$.jsx)(S,{size:13,className:`animate-spin`}):(0,$.jsx)(x,{size:13}),disabled:r.isPending||T.length===0,onClick:D,className:`shrink-0`,children:m===`testing`?`Testing...`:`Test`})]}),E&&(0,$.jsxs)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Using `,(0,$.jsx)(`span`,{className:`font-mono tabular-nums`,children:T}),` (provider prefix removed).`]}),(0,$.jsx)(J,{label:`Wire family`,id:`add-model-wire-family`,value:u,onValueChange:e=>{d(e),h(`idle`),v(``)},options:l.map(e=>({value:e,label:Fr(e)}))}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Thinking`}),(0,$.jsx)(wr,{id:`add-model-thinking-effort`,value:f,onChange:e=>{p(e),h(`idle`),v(``)},disabled:r.isPending}),(0,$.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:`Sent with the test. Auto leaves the model's own reasoning default in place.`})]}),(0,$.jsx)(Ar,{draft:b,onChange:C,idPrefix:`add-model`,disabled:i.isPending}),s!==void 0&&!s.includes(u)&&(0,$.jsxs)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:[`This provider does not declare the`,` `,(0,$.jsx)(`span`,{className:`font-mono tabular-nums`,children:Fr(u)}),` wire. The request is sent as chosen; the upstream decides whether it answers.`]}),m===`passed`&&(0,$.jsx)(Z,{tone:`success`,live:`status`,children:`Model test passed — ready to add.`}),m===`failed`&&(0,$.jsx)(Z,{tone:`danger`,live:`alert`,children:_||`Model test failed.`})]})})}function Er(){return{contextLimit:``,outputLimit:``,passthrough:!1,image:!0,reasoning:!0,toolCall:!0}}var Dr=String(qe),Or=String(Ge);function kr(){return{...Er(),contextLimit:Dr,outputLimit:Or}}function Ar({draft:e,onChange:t,idPrefix:n,disabled:r=!1}){let i=e.passthrough;return(0,$.jsxs)(Y,{gap:`10px`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Limits`}),(0,$.jsxs)(X,{gap:`8px`,children:[(0,$.jsx)(q,{label:`Context`,id:`${n}-context`,placeholder:Dr,value:e.contextLimit,disabled:r,onChange:n=>t({...e,contextLimit:n.target.value}),className:`flex-1`}),(0,$.jsx)(q,{label:`Output`,id:`${n}-output`,placeholder:Or,value:e.outputLimit,disabled:r,onChange:n=>t({...e,outputLimit:n.target.value}),className:`flex-1`})]}),(0,$.jsxs)(`label`,{className:`inline-flex items-center gap-2 mt-2 text-badge text-text-secondary cursor-pointer`,children:[(0,$.jsx)(`input`,{type:`checkbox`,id:`${n}-fallback-limits`,checked:e.contextLimit===Dr&&e.outputLimit===Or,disabled:r,onChange:n=>t(n.target.checked?{...e,contextLimit:Dr,outputLimit:Or}:{...e,contextLimit:``,outputLimit:``})}),`Use fallback — `,W(qe),` ctx ·`,` `,W(Ge),` out`]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Capabilities`}),(0,$.jsx)(Y,{gap:`6px`,children:[[`image`,`Can image`,e.image],[`reasoning`,`Reasoning`,e.reasoning],[`toolCall`,`Tools`,e.toolCall]].map(([a,o,s])=>(0,$.jsxs)(`label`,{className:`inline-flex items-center gap-2 text-badge text-text-secondary`,style:i?{opacity:.5}:void 0,children:[(0,$.jsx)(`input`,{type:`checkbox`,id:`${n}-${a}`,checked:i?!0:s,disabled:r||i,onChange:n=>t({...e,[a]:n.target.checked})}),o]},a))}),(0,$.jsxs)(`label`,{className:`inline-flex items-center gap-2 mt-2 text-badge text-text-secondary cursor-pointer`,children:[(0,$.jsx)(`input`,{type:`checkbox`,id:`${n}-passthrough`,checked:e.passthrough,disabled:r,onChange:n=>t({...e,passthrough:n.target.checked})}),`Passthrough — accept every capability`]}),i?(0,$.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:`Passthrough grants all of the above, so they are locked on. Uncheck it to restore your own choices.`}):null]})]})}function jr({providerId:e,model:t,onClose:n}){let r=ye(),[i,a]=(0,Q.useState)(()=>({contextLimit:t.contextLimit?String(t.contextLimit):``,outputLimit:t.outputLimit?String(t.outputLimit):``,passthrough:!1,image:t.vision===!0,reasoning:t.reasoning===!0,toolCall:t.toolCall===!0}));return(0,$.jsx)(F,{open:!0,onClose:n,title:`Edit Model`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:r.isPending,children:`Cancel`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,disabled:r.isPending,onClick:()=>{let a=We(i.contextLimit),o=We(i.outputLimit);if(a===null||o===null){y.error(`Invalid limits`,`Use a token count such as 512k, 200000, or 1.5m.`);return}r.mutate({providerId:e,modelId:t.modelId,route:t.route??``,metadata:{contextLimit:a??null,outputLimit:o??null,passthrough:i.passthrough,image:i.passthrough?!0:i.image,reasoning:i.passthrough?!0:i.reasoning,toolCall:i.passthrough?!0:i.toolCall}},{onSuccess:()=>n(),onError:e=>y.error(`Failed to update model`,e.message??`Unable to update model`)})},children:r.isPending?`Saving...`:`Save`})]}),children:(0,$.jsxs)(Y,{gap:`10px`,children:[(0,$.jsxs)(`div`,{className:`text-badge text-text-tertiary`,children:[`Editing `,(0,$.jsx)(`span`,{className:`font-mono tabular-nums`,children:t.modelId})]}),(0,$.jsx)(Ar,{draft:i,onChange:a,idPrefix:`edit-model`,disabled:r.isPending})]})})}function Mr({providerId:e,model:t,serviceKind:n,searchCapable:r,thinkingEffort:i,onDeleteRequest:a,onEditRequest:c,deletePending:l}){let u=Ie(),m=be(),[_,v]=(0,Q.useState)(!1),[T,D]=(0,Q.useState)(null),O=lt(),k=n===`llm`?yt(t.modelId,i===`auto`?null:i):t.modelId,A=`${e}/${k}`,j=n===`websearch`?`Searching…`:`Thinking…`,M=()=>{u.mutate({providerId:e,request:{modelId:t.modelId,route:t.route,...n===`llm`?{reasoningEffort:i}:{},serviceKind:n}},{onSuccess:t=>{if(D({ok:t.ok,latencyMs:t.latencyMs}),!t.ok){let{title:n,detail:r}=_r(e,k,t.error);y.error(n,r);return}let n=t.sample?.trim()??``,r=t.reportedModel?.trim()??``;y.successRich(`${k} · END ${h(t.latencyMs)}`,(0,$.jsxs)(`span`,{className:`grid gap-2 min-w-0`,children:[r?(0,$.jsxs)(X,{gap:`6px`,align:`center`,className:`min-w-0`,children:[(0,$.jsx)(E,{size:12,"aria-hidden":`true`,className:`shrink-0 text-text-tertiary`}),(0,$.jsx)(`span`,{className:`truncate font-mono text-badge text-text-secondary`,title:r,children:r})]}):null,(0,$.jsx)(`span`,{children:n||`No sample text in the response.`})]}),[r,n].filter(Boolean).join(`
4
- `)||`No sample text in the response.`)},onError:t=>{D({ok:!1,latencyMs:0}),y.error(...vr(e,k,t.message))}})},N=()=>{let n=!t.enabled;m.mutate({providerId:e,request:{modelId:t.modelId,route:t.route,enabled:n}},{onSuccess:()=>y.success(n?`Model enabled`:`Model disabled`,t.modelId),onError:e=>y.error(`Failed to update model`,e.message??`Unable to update model`)})};return(0,$.jsx)($.Fragment,{children:(0,$.jsxs)(`div`,{className:`model-card box-border flex w-full min-w-0 flex-1-auto flex-col gap-5 rounded-panel border border-inner-border p-6 ${t.enabled?`bg-surface-2`:`bg-surface-1 opacity-72`}`,children:[(0,$.jsxs)(`div`,{className:`flex items-start gap-4 min-w-0`,children:[(0,$.jsx)(`span`,{className:`inline-flex items-center justify-center w-13 h-13 rounded-inset bg-teal-soft text-teal shrink-0`,children:(0,$.jsx)(o,{size:14})}),(0,$.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-1`,children:[(0,$.jsx)(`div`,{title:A,className:`font-mono tabular-nums min-w-0 truncate text-caption font-semibold leading-[1.35]`,children:k}),(0,$.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0 text-micro text-text-tertiary`,children:[(0,$.jsx)(`span`,{title:`${t.wireFamily} · ${t.route??e}`,className:`shrink-0 rounded-tiny px-3.5 py-0.5 text-micro font-bold`,style:{...Pr(t.wireFamily)},children:Fr(t.wireFamily)}),t.source!==null&&t.source!==`builtin`?(0,$.jsx)(`span`,{title:yr(t.source),className:`shrink-0 rounded-pill border border-teal-soft px-3 py-0.5 text-micro font-bold tracking-[0.04em] text-teal`,children:br(t.source)}):null,t.proOnly===!0?(0,$.jsx)(`span`,{title:`Refused on a free plan. Nothing in the provider's model directory predicts it, so this comes from a real dispatch: the upstream answers that the model is not allowed for a free user type.`,className:`shrink-0 rounded-tiny border border-orange bg-orange-soft px-3.5 py-0.5 text-micro font-bold uppercase tracking-[0.04em] text-orange`,children:`Pro`}):null,t.freeTier===!0&&t.source!==`auto_free`?(0,$.jsx)(`span`,{title:`Free on this provider's plan. Taken from the provider's own model directory, not a hardcoded list, so it tracks plan changes.`,className:`shrink-0 rounded-pill border border-teal-soft px-3 py-0.5 text-micro font-bold text-teal`,children:`Free tier`}):null,t.enabled?null:(0,$.jsx)(`span`,{className:`shrink-0 rounded-pill bg-red-soft px-3 py-0.5 text-micro font-bold tracking-[0.04em] text-red`,children:`Off`})]})]}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,icon:_?(0,$.jsx)(p,{size:12}):(0,$.jsx)(f,{size:12}),"aria-label":`Copy ${A}`,title:`Copy ${A}`,onClick:()=>{navigator.clipboard?.writeText(A),v(!0),O(()=>v(!1),1500)},className:`shrink-0 p-2 opacity-70`})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0 text-badge text-text-secondary`,children:[(0,$.jsxs)(`span`,{className:`inline-flex gap-2.5`,children:[t.reasoning?(0,$.jsx)(`span`,{title:`Reasoning`,"aria-label":`Reasoning`,className:`inline-flex text-purple`,children:(0,$.jsx)(s,{size:12})}):null,t.vision?(0,$.jsx)(`span`,{title:`Vision`,"aria-label":`Vision`,className:`inline-flex text-status-info`,children:(0,$.jsx)(ee,{size:12})}):null,t.toolCall?(0,$.jsx)(`span`,{title:`Tool calling`,"aria-label":`Tool calling`,className:`inline-flex text-orange`,children:(0,$.jsx)(le,{size:12})}):null,r?(0,$.jsx)(`span`,{title:`Web search`,"aria-label":`Web search`,className:`inline-flex text-teal`,children:(0,$.jsx)(d,{size:12})}):null]}),(0,$.jsxs)(`span`,{className:`whitespace-nowrap`,children:[t.limitsEstimated?(0,$.jsx)(`span`,{title:Ke,"aria-label":`Limits are a fallback estimate`,className:`estimate-dot inline-flex items-center justify-center rounded-full border border-inner-border bg-surface-2 text-orange cursor-help mr-1 align-middle`,children:(0,$.jsx)(C,{size:9,"aria-hidden":`true`})}):null,t.contextLimit?`${W(t.contextLimit)} ctx`:(0,$.jsx)(`span`,{title:Je,className:`cursor-help`,children:`n/a ctx`}),t.outputLimit?` · ${W(t.outputLimit)} out`:(0,$.jsx)(`span`,{title:Je,className:`cursor-help`,children:` · n/a out`})]}),c?(0,$.jsx)(`button`,{type:`button`,className:`shrink-0 grid place-items-center w-6 h-6 p-0 border-0 bg-transparent text-text-tertiary cursor-pointer rounded-tiny hover:bg-inner-border hover:text-text-primary`,title:`Edit limits and capabilities`,"aria-label":`Edit ${t.modelId} limits and capabilities`,onClick:()=>c(t),children:(0,$.jsx)(I,{size:11})}):null]}),(0,$.jsxs)(`div`,{className:`flex gap-3 items-center flex-wrap`,children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,disabled:u.isPending,onClick:M,"aria-label":`Test ${k}`,title:u.isPending?`Probing ${k}…`:T?.ok?`Last probe OK in ${h(T.latencyMs)} — click to re-test`:T?`Last probe failed — click to retry`:`Test ${k}`,className:`flex-1 justify-center`,icon:u.isPending?(0,$.jsx)(S,{size:12,className:`animate-spin`}):T?T.ok?(0,$.jsx)(`span`,{className:`inline-flex text-green`,children:(0,$.jsx)(w,{size:12})}):(0,$.jsx)(`span`,{className:`inline-flex text-red`,children:(0,$.jsx)(b,{size:12})}):(0,$.jsx)(x,{size:12}),children:u.isPending?j:T?.ok?h(T.latencyMs):T?`Fail`:`Test`}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,disabled:m.isPending,onClick:N,icon:t.enabled?(0,$.jsx)(ie,{size:12}):(0,$.jsx)(ft,{size:12}),"aria-label":t.enabled?`Disable ${t.modelId}`:`Enable ${t.modelId}`,title:t.enabled?`Disable model`:`Enable model`,className:`flex-1 justify-center ${t.enabled?`text-red`:`text-green`}`,children:t.enabled?`Disable`:`Enable`}),t.source===`builtin`?null:(0,$.jsx)(g,{variant:`ghost`,size:`sm`,disabled:l,onClick:()=>a(t),icon:(0,$.jsx)(ce,{size:12}),"aria-label":`Delete ${t.modelId}`,title:`Delete model`,className:`model-card-delete shrink-0 px-4 py-3 text-text-tertiary`})]})]})})}var Nr=(0,Q.memo)(Mr);function Pr(e){return e===`responses`?{color:`var(--purple)`,background:`var(--purple-soft)`}:e===`messages`?{color:`var(--orange)`,background:`color-mix(in srgb, var(--orange) 14%, transparent)`}:{color:`var(--teal)`,background:`var(--teal-soft)`}}function Fr(e){let t=e.toLowerCase();return t===`responses`?`Responses`:t===`messages`?`Messages`:`Chat`}function Ir({providerId:e,models:t,thinkingEffort:n,serviceKind:r=`llm`,searchCapable:i=!1}){let a=z(),[o,s]=(0,Q.useState)(null),[c,l]=(0,Q.useState)(null),u=e=>e.enabled!==!1,d=xr.map(e=>({...e,rows:t.filter(t=>u(t)&&e.matches(t.source))})).filter(e=>e.rows.length>0),f=t.filter(e=>!u(e)),p=t=>(0,$.jsx)(Nr,{providerId:e,model:t,serviceKind:r,searchCapable:i,thinkingEffort:n,deletePending:a.isPending,onDeleteRequest:s,onEditRequest:t.source===`builtin`?void 0:l},`${t.modelId}::${t.route}`);return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(Y,{gap:`16px`,children:[d.map(e=>(0,$.jsxs)(`section`,{className:`flex flex-col gap-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-baseline gap-4 min-w-0`,children:[(0,$.jsx)(`span`,{className:`text-caption font-bold text-text-secondary`,children:e.label}),(0,$.jsx)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:e.rows.length}),(0,$.jsxs)(`span`,{title:e.hint,className:`text-micro text-text-tertiary overflow-hidden truncate`,children:[`· `,e.hint]})]}),(0,$.jsx)(`div`,{className:`provider-grid grid gap-4 items-stretch`,children:e.rows.map(p)})]},e.key)),f.length===0?null:(0,$.jsxs)(`section`,{className:`flex flex-col gap-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-baseline gap-4 min-w-0`,children:[(0,$.jsx)(`span`,{className:`text-caption font-bold text-text-secondary`,children:Sr.label}),(0,$.jsx)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:f.length}),(0,$.jsxs)(`span`,{title:Sr.hint,className:`text-micro text-text-tertiary overflow-hidden truncate`,children:[`· `,Sr.hint]})]}),(0,$.jsx)(`div`,{className:`provider-grid grid gap-4 items-stretch`,children:f.map(p)})]})]}),(0,$.jsx)(ge,{open:o!==null,onClose:()=>{a.isPending||s(null)},onConfirm:async()=>{o!==null&&(await a.mutateAsync({providerId:e,request:{modelId:o.modelId,route:o.route}}),y.success(`Model deleted`,`${e}/${o.modelId}`),s(null))},title:`Delete model?`,message:`Delete ${e}/${o?.modelId??``} from the provider catalog?`,confirmLabel:`Delete`,danger:!0}),c===null?null:(0,$.jsx)(jr,{providerId:e,model:c,onClose:()=>l(null)})]})}function Lr(e){return e===`llm`?`LLM`:e===`websearch`?`Search`:e===`imageGeneration`?`Image`:e===`videoGeneration`?`Video`:e}function Rr(e){let t=e.serviceKinds;return Array.isArray(t)&&t.length>0?t:[`llm`]}function zr(){let{providerId:e}=ze(),[t]=Pe(),n=e??``,r=t.get(`service`),[i,a]=(0,Q.useState)(r===`websearch`||r===`imageGeneration`||r===`videoGeneration`?r:`llm`),o=ke(n),s=Oe(n),c=Ne(n),u=xe(),f=xe({silent:!0}),[p,h]=(0,Q.useState)(!1),_=De(),v=ve(),b=_e(),x=fe(),[S,C]=(0,Q.useState)(!1),[w,T]=(0,Q.useState)(!1),E=Ie(),[D,ee]=(0,Q.useState)(``),[O,te]=(0,Q.useState)(``),[P,ne]=(0,Q.useState)(null),I=e=>`cartethyia:provider:${e}:thinking-effort`,oe=e=>{if(typeof window>`u`||!window.localStorage)return`auto`;let t=window.localStorage.getItem(I(e));if(t===null)return`auto`;let n=t.trim().toLowerCase();return vt.includes(n)?n:`auto`},[se,le]=(0,Q.useState)(()=>oe(n));(0,Q.useEffect)(()=>{if(!n)return;let e=oe(n);e!==se&&le(e)},[n]),(0,Q.useEffect)(()=>{typeof window>`u`||!window.localStorage||!n||window.localStorage.setItem(I(n),se)},[n,se]);let[ue,de]=(0,Q.useState)(!1),[pe,me]=(0,Q.useState)(!1),[R,ye]=(0,Q.useState)(null),[be,Se]=(0,Q.useState)({}),[Ce,we]=(0,Q.useState)({}),[z,Te]=(0,Q.useState)(null),[Ee,Ae]=(0,Q.useState)(!1),[je,Fe]=(0,Q.useState)(null),Le=(0,Q.useRef)(null),Re=(0,Q.useRef)(null);(0,Q.useEffect)(()=>()=>{let e=Le.current;Le.current=null,e&&!e.closed&&e.close()},[]);let B=o.data,Be=n===`opencode`||n===`cline`,Ve=B===void 0?[`llm`]:Rr(B),He=[];for(let e of Ve)(e===`llm`||e===`websearch`||e===`imageGeneration`||e===`videoGeneration`)&&He.push(e);(0,Q.useEffect)(()=>{if(B===void 0)return;let e=r===`websearch`||r===`imageGeneration`||r===`videoGeneration`||r===`llm`?r:void 0,t=He[0];if(e!==void 0&&He.includes(e)){i!==e&&a(e);return}!He.includes(i)&&t!==void 0&&a(t)},[B,r,i,He.join(`|`)]),(0,Q.useEffect)(()=>{Be&&B!==void 0&&B.supportsModelDiscovery!==!1&&Re.current!==n&&(Re.current=n,f.mutate(n))},[Be,f,n,B?.supportsModelDiscovery]);let Ue=c.data??[],We=s.data??[],Ge=(()=>{let e=new Map;for(let t of We){let n=`${t.serviceKind??`llm`}:${t.modelId}`,r=e.get(n);if(!r)e.set(n,t);else{let i=r.contextLimit??0;(t.contextLimit??0)>i&&e.set(n,t)}}return[...e.values()].sort((e,t)=>e.modelId.localeCompare(t.modelId))})(),W=Ge.filter(e=>e.serviceKind===`llm`||e.serviceKind===void 0),Ke=Ge.filter(e=>e.serviceKind===`websearch`),qe=Ge.filter(e=>e.serviceKind===`imageGeneration`),Je=Ge.filter(e=>e.serviceKind===`videoGeneration`),G=He.includes(i)?i:He[0],K=O||Ke[0]?.modelId||``,q=()=>{let e=D.trim();K&&e&&(ne(null),E.mutate({providerId:n,request:{modelId:K,serviceKind:`websearch`,prompt:e}},{onSuccess:e=>ne({ok:e.ok,latencyMs:e.latencyMs,...e.searchResults?{results:e.searchResults,count:e.searchResults.length}:{},...e.error?{error:e.error}:{}}),onError:e=>ne({ok:!1,error:e instanceof Error?e.message:`Search test failed`})}))};if(o.isPending)return(0,$.jsx)(j,{label:`Loading provider...`});if(o.isError)return(0,$.jsx)(A,{title:`Unable to load providers`,message:`The provider details could not be read, so this page cannot resolve its endpoint settings.`,onRetry:()=>void o.refetch(),retrying:o.isFetching,action:(0,$.jsx)(bt,{to:`/providers`,label:`Back to providers`})});if(!B)return(0,$.jsx)(M,{icon:(0,$.jsx)(pt,{size:20}),title:`Provider not found`,message:`No provider named “${n}”. It may have been removed, or the link is stale.`,action:(0,$.jsx)(bt,{to:`/providers`,label:`Back to providers`})});let J=Ue.filter(e=>e.status===`active`).length,Xe=e=>{let t=e===`browser`?B?.oauthFlows?.browserLoginFields??[]:B?.oauthFlows?.deviceLoginFields??[];if(t.length===0){e===`browser`?$e():de(!0);return}Se(pr(t)),ye(e)},Qe=()=>{if(R===null)return;let e=mr(R===`browser`?B?.oauthFlows?.browserLoginFields??[]:B?.oauthFlows?.deviceLoginFields??[],be);if(e.length>0){y.error(`Missing required fields`,`Fill in: ${e.join(`, `)}`);return}let t=R;ye(null),t===`browser`?$e(be):(we(be),de(!0))},$e=e=>{let t=window.open(`about:blank`,`cartethyia-oauth`,`popup,width=720,height=820`);t&&(t.opener=null,Le.current=t),b.mutate({providerId:n,...e===void 0?{}:{parameters:e}},{onSuccess:({authorizeUrl:e,state:n})=>{let r=null;if(t&&!t.closed?(t.location.href=e,r=t):(r=window.open(e,`cartethyia-oauth`,`popup,width=720,height=820`),r&&(r.opener=null,Le.current=r)),!r){y.error(`Popup blocked`,`Allow popups to complete OAuth login.`);return}Fe({authorizeUrl:e,state:n,popup:r})},onError:e=>{t&&!t.closed&&t.close(),Le.current===t&&(Le.current=null),y.error(`Failed to start OAuth`,e.message??`Unable to start authorization`)}})};return(0,$.jsxs)(Y,{gap:`16px`,children:[(0,$.jsx)(xt,{title:`${B.label||B.displayName}${G?` (${Lr(G)})`:``}`,description:`${B.providerId}/${B.baseUrl?` · ${B.baseUrl}`:``}`,icon:(0,$.jsx)(Ye,{icon:B.providerId,name:B.label||B.displayName,size:28}),back:{to:`/providers`,label:`Back to Providers`},actions:(0,$.jsx)(X,{gap:`8px`,className:`flex-wrap w-full max-w-full min-w-0`,children:B.isBuiltIn?(0,$.jsx)(g,{variant:B.enabled?`danger`:`secondary`,icon:B.enabled?(0,$.jsx)(ie,{size:13}):(0,$.jsx)(ft,{size:13}),loading:v.isPending,onClick:()=>v.mutate({providerId:n,enabled:!B.enabled},{onSuccess:e=>y.success(e.enabled?`Provider enabled`:`Provider disabled`,B.label||B.displayName),onError:e=>y.error(`Provider update failed`,e.message??`Unable to change provider availability`)}),title:B.enabled?`Disable provider globally`:`Enable provider globally`,children:B.enabled?`Disable`:`Enable`}):null})}),(0,$.jsx)(Xt,{provider:B}),B.isBuiltIn?null:(0,$.jsx)(Zt,{provider:B}),G===`llm`?(0,$.jsx)(jt,{providerId:n,clientVersion:B.clientVersion,routeIdentityVersions:B.routeIdentityVersions,userAgentEditable:St(B)}):null,(0,$.jsx)(Qn,{providerId:n}),(0,$.jsx)(`div`,{id:`provider-accounts`,tabIndex:-1,children:B.requiresAccount===!1?(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Accounts`,icon:(0,$.jsx)(ut,{size:16})}),(0,$.jsx)(V,{children:(0,$.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`This provider is a public, unauthenticated route — no account or credential is needed. Routing already works without any setup here.`})})]}):(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Accounts`,subtitle:`${Ue.length} total · ${J} active · ${Ue.length-J} disabled`,icon:(0,$.jsx)(ut,{size:16}),action:(0,$.jsxs)(Ze,{children:[B.oauthFlows?.browser&&(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(Me,{size:13}),disabled:b.isPending,onClick:()=>Xe(`browser`),title:`Browser OAuth login — opens the provider authorize page in a popup`,children:b.isPending?`Starting...`:`Login with browser`}),B.oauthFlows?.device&&(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(N,{size:13}),onClick:()=>Xe(`device`),title:`Device-code login — enter the shown code on the provider site`,children:`Login with device code`}),B.oauthFlows?.import&&(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(m,{size:13}),onClick:()=>me(!0),title:B.oauthFlows.browser||B.oauthFlows.device||B.oauthFlows.refreshable?`Import a credential you already hold — a refresh token, an exported auth blob, or an API key`:`Add and validate an API key`,children:B.oauthFlows.browser||B.oauthFlows.device||B.oauthFlows.refreshable?`Import credential`:`Add API key`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,$.jsx)(re,{size:13}),onClick:()=>C(!0),children:`Add Account`})]})}),(0,$.jsxs)(V,{className:`flex flex-col gap-5`,children:[(0,$.jsx)(Kt,{providerId:n}),c.isPending?(0,$.jsx)(j,{label:`Loading accounts...`}):c.isError?(0,$.jsx)(A,{message:`Failed to load accounts`,onRetry:()=>c.refetch()}):Ue.length===0?(0,$.jsx)(M,{title:`No accounts connected`,message:`Add an API key or OAuth credential to route requests to this provider.`}):(0,$.jsx)(qn,{providerId:n,accounts:Ue,onDelete:e=>Te(e),showGrokProbe:G===`llm`&&n===`grok`,grokProbePending:_.isPending,onGrokProbe:()=>{_.mutate({providerId:n,request:{modelId:`grok-4.6`,prompt:`reply my message with exact number 407`,stream:!0,serviceKind:`llm`}},{onSuccess:e=>{let t=e.results.filter(e=>e.ok).length,n=e.results.filter(e=>e.statusCode===202).length,r=e.results.length-t-n;y.success(`Grok account probe complete`,`${t} passed · ${n} returned 202 and were parked in cooldown · ${r} other failures`)},onError:e=>y.error(`Grok account probe failed`,e.message??`Unable to probe Grok accounts`)})}})]})]})}),G===`llm`?(0,$.jsxs)($.Fragment,{children:[n===`inferhub`?(0,$.jsx)(Ut,{}):null,(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Models`,subtitle:`${W.length} model${W.length===1?``:`s`} registered`,icon:(0,$.jsx)(l,{size:16}),action:(0,$.jsxs)(X,{gap:`6px`,className:`flex-wrap items-center`,children:[(0,$.jsx)(wr,{id:`models-section-thinking-effort`,value:se,onChange:le}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(ae,{size:13,className:u.isPending||f.isPending?`animate-spin`:``}),disabled:u.isPending||f.isPending,onClick:()=>u.mutate(n),children:u.isPending||f.isPending?`Fetching...`:`Fetch models`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(ce,{size:13,className:p?`animate-spin`:``}),disabled:u.isPending||f.isPending||p||W.filter(e=>e.source!==`builtin`&&e.source!==null).length===0,onClick:async()=>{let e=W.filter(e=>e.source!==`builtin`&&e.source!==null);if(e.length!==0&&confirm(`Delete ${e.length} fetched/manual model(s) for ${n}?`)){h(!0);try{let t=await he(`/providers/${encodeURIComponent(n)}/models/bulk`,{method:`DELETE`,body:JSON.stringify({items:e.map(e=>({modelId:e.modelId,route:e.route}))})});await Promise.all([x.invalidateQueries({queryKey:L.providers.models(n)}),x.invalidateQueries({queryKey:L.providers.all})]);let r=t.failures.length;y.success(`Fetched models deleted`,r>0?`${t.deleted}/${t.total} removed, ${r} failed`:`${t.deleted}/${t.total} removed`)}catch(e){y.error(`Failed to delete fetched models`,e.message??`Unable to delete models`)}finally{h(!1)}}},children:p?`Deleting…`:`Delete fetched`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,$.jsx)(re,{size:13}),onClick:()=>T(!0),children:`Add Model`})]})}),(0,$.jsx)(V,{className:`flex flex-col gap-8`,children:s.isPending?(0,$.jsx)(j,{label:`Loading models...`}):s.isError?(0,$.jsx)(A,{message:`Failed to load models`,onRetry:()=>s.refetch()}):W.length===0?(0,$.jsx)(M,{title:`No LLM models found`,message:`No LLM models published by this provider yet. Sync or add a custom model above.`}):(0,$.jsx)(Ir,{providerId:n,models:W,serviceKind:`llm`,thinkingEffort:se,searchCapable:B?.supportsWebSearch===!0})})]})]}):G===`websearch`?(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:`Web Search`,subtitle:`Run a real search request through the selected provider.`,icon:(0,$.jsx)(d,{size:16})}),(0,$.jsx)(V,{className:`flex flex-col gap-6`,children:s.isPending?(0,$.jsx)(j,{label:`Loading search models...`}):s.isError?(0,$.jsx)(A,{message:`Failed to load search models`,onRetry:()=>s.refetch()}):Ke.length===0?(0,$.jsx)(M,{title:`No Search models found`,message:`This provider advertises Search, but no websearch model is registered yet.`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`label`,{className:`flex flex-col gap-2.5 text-badge text-text-secondary`,children:[`Search model`,(0,$.jsx)(`select`,{value:K,onChange:e=>{te(e.target.value),ne(null)},className:`w-full min-h-17 rounded-inset border border-inner-border bg-surface-1 text-text-primary px-4.5 py-0`,children:Ke.map(e=>(0,$.jsx)(`option`,{value:e.modelId,children:e.modelId},`${e.modelId}:${e.route}`))})]}),(0,$.jsxs)(`label`,{className:`flex flex-col gap-2.5 text-badge text-text-secondary`,children:[`Query`,(0,$.jsx)(`input`,{value:D,onChange:e=>ee(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),q())},placeholder:`What is the latest news about AI?`,className:`w-full min-h-17 rounded-inset border border-inner-border bg-surface-1 text-text-primary px-4.5 py-0`})]}),(0,$.jsxs)(X,{gap:`8px`,className:`items-center flex-wrap`,children:[(0,$.jsx)(g,{variant:`primary`,size:`sm`,disabled:E.isPending||D.trim().length===0,loading:E.isPending,onClick:q,children:`Test search`}),P?(0,$.jsx)(`span`,{className:`text-badge`,style:{color:P.ok?`var(--green)`:`var(--red)`},children:P.ok?`Search ok · ${P.latencyMs}ms · ${P.count??0} result(s)`:P.error??`Search failed.`}):null]}),P&&P.results&&P.results.length>0?(0,$.jsx)(`div`,{className:`flex max-h-110 flex-col gap-4 overflow-y-auto rounded-inset border border-inner-border bg-surface-1 p-4`,children:P.results.map((e,t)=>(0,$.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,$.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noreferrer`,className:`text-caption text-text-primary font-semibold`,children:e.title||e.url}),(0,$.jsx)(`span`,{className:`text-badge text-text-tertiary break-all`,children:e.url}),e.snippet?(0,$.jsx)(`span`,{className:`text-badge text-text-secondary`,children:e.snippet}):null]},`${e.url}:${t}`))}):null]})})]}):G===`imageGeneration`||G===`videoGeneration`?(0,$.jsxs)(U,{children:[(0,$.jsx)(H,{title:Lr(G),subtitle:G===`imageGeneration`?`Models that return an image rather than text.`:`Models that return a video. Wired and routable; not yet verified against a live account.`,icon:G===`imageGeneration`?(0,$.jsx)(k,{size:16}):(0,$.jsx)(gt,{size:16})}),(0,$.jsx)(V,{className:`flex flex-col gap-6`,children:s.isPending?(0,$.jsx)(j,{label:`Loading ${Lr(G).toLowerCase()} models...`}):s.isError?(0,$.jsx)(A,{message:`Failed to load ${Lr(G).toLowerCase()} models`,onRetry:()=>s.refetch()}):(G===`imageGeneration`?qe:Je).length===0?(0,$.jsx)(M,{title:`No ${Lr(G)} models found`,message:`This provider advertises ${Lr(G)}, but no ${G} model is registered yet.`}):(0,$.jsx)(Ir,{providerId:n,models:G===`imageGeneration`?qe:Je,serviceKind:`llm`,searchCapable:!1,thinkingEffort:`auto`})})]}):(0,$.jsx)(U,{children:(0,$.jsx)(V,{children:(0,$.jsx)(M,{title:`Service not available`,message:`This provider advertises ${Ve.map(Lr).join(`, `)}, but the dashboard has no controls for the selected service yet.`})})}),S&&(0,$.jsx)(Un,{providerId:n,accounts:Ue,onClose:()=>C(!1)}),G===`llm`&&w?(0,$.jsx)(Tr,{providerId:n,provider:B,onClose:()=>T(!1)}):null,(0,$.jsx)(ge,{open:z!==null,onClose:()=>{Ee||Te(null)},onConfirm:async()=>{if(z){Ae(!0);try{let e=z.tenantId===null?`/global/accounts/${encodeURIComponent(z.id)}`:`/accounts/${encodeURIComponent(z.id)}`;await he(e,{method:`DELETE`}),x.removeQueries({queryKey:L.quota.account(z.id),exact:!0}),await Promise.all([x.invalidateQueries({queryKey:L.providers.accounts(n)}),x.invalidateQueries({queryKey:L.providers.healthEvents(n,z.id)}),x.invalidateQueries({queryKey:L.providers.all}),x.invalidateQueries({queryKey:L.quota.all})]),y.success(`Account deleted`,z.label||z.id.slice(0,8)),Te(null)}catch(e){throw y.error(`Failed to delete account`,e.message??`Unable to delete account`),e}finally{Ae(!1)}}},title:`Delete account?`,message:`Delete "${z?.label||z?.id.slice(0,8)}"? This cannot be undone.`,confirmLabel:`Delete`,danger:!0}),ue&&(0,$.jsx)(Zn,{providerId:n,parameters:Ce,onClose:()=>{de(!1),we({})}}),R!==null&&(0,$.jsx)(F,{open:!0,onClose:()=>ye(null),title:R===`browser`?`Sign in with`:`Device sign-in details`,size:`sm`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>ye(null),children:`Cancel`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,onClick:Qe,children:`Continue`})]}),children:(0,$.jsxs)(Y,{gap:`12px`,children:[(0,$.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:R===`browser`?`Choose how ${B.label||B.displayName} should identify you, then continue to its sign-in page.`:`These decide which organization the device code is issued for.`}),(0,$.jsx)(hr,{fields:R===`browser`?B?.oauthFlows?.browserLoginFields??[]:B?.oauthFlows?.deviceLoginFields??[],values:be,idPrefix:`flow-${R}`,onChange:(e,t)=>Se(n=>({...n,[e]:t}))})]})}),pe&&B?.oauthFlows?.import===!0&&(0,$.jsx)(gr,{providerId:n,providerName:B.label||B.displayName,fields:B.oauthFlows.importFields,onClose:()=>me(!1)}),je&&(0,$.jsx)(Yn,{providerId:n,authorizeUrl:je.authorizeUrl,state:je.state,popup:je.popup,onClose:e=>{Le.current=null,Fe(null),e&&x.invalidateQueries({queryKey:L.providers.accounts(n)})}})]})}export{zr as default};