@opengeni/react 0.36.0 → 0.36.1

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.
@@ -7,7 +7,7 @@ var BILLING_CLASS_ORDER = [
7
7
  var BILLING_CLASS_LABELS = {
8
8
  opengeni_credits: "OpenGeni",
9
9
  codex_subscription: "Codex",
10
- byok: "Bring your own key"
10
+ byok: "Your Gateway"
11
11
  };
12
12
  var AVAILABILITY_REASON_LABELS = {
13
13
  missing_credential: "Credentials required",
@@ -19,6 +19,12 @@ var AVAILABILITY_REASON_LABELS = {
19
19
  unsupported: "Unsupported"
20
20
  };
21
21
  function billingClassForModel(model) {
22
+ if (model.source === "codex") {
23
+ return "codex_subscription";
24
+ }
25
+ if (model.source === "workspace_gateway") {
26
+ return "byok";
27
+ }
22
28
  if (model.credentialSource?.kind === "connected_subscription") {
23
29
  return "codex_subscription";
24
30
  }
@@ -90,7 +96,7 @@ function payerSummaryForModel(model) {
90
96
  return "Codex subscription \xB7 external billing";
91
97
  }
92
98
  if (billing.upstreamPayer === "workspace") {
93
- return "Workspace credentials \xB7 external billing";
99
+ return "Billed to your AI Gateway";
94
100
  }
95
101
  return "Deployment route \xB7 external billing";
96
102
  }
@@ -103,7 +109,7 @@ function advancedSourceSummary(model) {
103
109
  return "Connected Codex subscription";
104
110
  }
105
111
  if (source.kind === "workspace_connection") {
106
- return "Workspace API key connection";
112
+ return "Workspace AI Gateway";
107
113
  }
108
114
  if (source.kind === "deployment") {
109
115
  return source.mechanism === "azure_ad_bearer" ? "Deployment Azure identity" : "Deployment API key";
@@ -111,7 +117,10 @@ function advancedSourceSummary(model) {
111
117
  return null;
112
118
  }
113
119
  function projectPickerRows(models) {
114
- return models.map((catalog) => {
120
+ return models.filter((catalog) => {
121
+ const billingClass = billingClassForModel(catalog);
122
+ return billingClass === "opengeni_credits" || catalog.credentialReadiness.status === "ready";
123
+ }).map((catalog) => {
115
124
  const billingClass = billingClassForModel(catalog);
116
125
  return {
117
126
  id: catalog.id,
@@ -175,4 +184,4 @@ export {
175
184
  findPickerRow,
176
185
  groupPickerRowsByBillingClass
177
186
  };
178
- //# sourceMappingURL=chunk-U255M5EZ.js.map
187
+ //# sourceMappingURL=chunk-22RM4GMO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/model-policy.ts"],"sourcesContent":["import type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\n\nexport type PickerBillingClass = \"opengeni_credits\" | \"codex_subscription\" | \"byok\";\n\nexport type PickerModelRow = {\n id: string;\n label: string;\n billingClass: PickerBillingClass;\n billingClassLabel: string;\n selectable: boolean;\n unavailableReason: string | null;\n provider: string;\n providerLabel: string;\n catalog: WorkspaceModelCatalogModel;\n};\n\nexport type LatencyModeId = \"standard\" | \"priority\" | \"fast\";\n\nconst BILLING_CLASS_ORDER: PickerBillingClass[] = [\n \"opengeni_credits\",\n \"codex_subscription\",\n \"byok\",\n];\n\nconst BILLING_CLASS_LABELS: Record<PickerBillingClass, string> = {\n opengeni_credits: \"OpenGeni\",\n codex_subscription: \"Codex\",\n byok: \"Your Gateway\",\n};\n\nconst AVAILABILITY_REASON_LABELS: Record<string, string> = {\n missing_credential: \"Credentials required\",\n needs_reauth: \"Reconnect required\",\n credential_not_ready: \"Credential not ready\",\n not_entitled: \"Not entitled\",\n provider_unhealthy: \"Provider unavailable\",\n policy_blocked: \"Blocked by workspace policy\",\n unsupported: \"Unsupported\",\n};\n\nexport function billingClassForModel(model: ClientModel): PickerBillingClass {\n if (model.source === \"codex\") {\n return \"codex_subscription\";\n }\n if (model.source === \"workspace_gateway\") {\n return \"byok\";\n }\n if (model.credentialSource?.kind === \"connected_subscription\") {\n return \"codex_subscription\";\n }\n if (model.credentialSource?.kind === \"workspace_connection\") {\n return \"byok\";\n }\n if (model.billing?.upstreamPayer === \"connected_subscription\") {\n return \"codex_subscription\";\n }\n if (model.billing?.upstreamPayer === \"workspace\") {\n return \"byok\";\n }\n return \"opengeni_credits\";\n}\n\nexport function billingClassLabel(billingClass: PickerBillingClass): string {\n return BILLING_CLASS_LABELS[billingClass];\n}\n\nexport function availabilityReasonLabel(\n reason: WorkspaceModelCatalogModel[\"availability\"][\"reason\"],\n): string | null {\n if (!reason) {\n return null;\n }\n return AVAILABILITY_REASON_LABELS[reason] ?? \"Unavailable\";\n}\n\nexport function effortOptionsForModel(model: ClientModel): ReasoningEffort[] {\n const efforts = model.capabilities?.reasoning.efforts;\n if (!efforts || efforts.length === 0) {\n return [\"low\"];\n }\n const order: ReasoningEffort[] = [\"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"];\n return order.filter((effort) => efforts.includes(effort));\n}\n\nexport function defaultEffortForModel(model: ClientModel): ReasoningEffort {\n const options = effortOptionsForModel(model);\n const configured = model.capabilities?.reasoning.defaultEffort;\n if (configured && options.includes(configured)) {\n return configured;\n }\n return options[0] ?? \"low\";\n}\n\nexport function coerceReasoningEffortForModel(\n model: ClientModel,\n effort: ReasoningEffort,\n): ReasoningEffort {\n const options = effortOptionsForModel(model);\n if (options.includes(effort)) {\n return effort;\n }\n return defaultEffortForModel(model);\n}\n\nexport function runnableLatencyModesForModel(model: ClientModel): LatencyModeId[] {\n const modes = model.capabilities?.latencyModes ?? [];\n return modes.filter((mode) => mode.runnable).map((mode) => mode.id);\n}\n\nexport function labelLatencyMode(mode: LatencyModeId): string {\n if (mode === \"fast\") {\n return \"Fast\";\n }\n if (mode === \"priority\") {\n return \"Priority\";\n }\n return \"Standard\";\n}\n\nexport function payerSummaryForModel(model: ClientModel): string {\n const billing = model.billing;\n if (!billing) {\n return \"Route unknown\";\n }\n if (billing.metering === \"opengeni_credits\") {\n return \"OpenGeni credits · automatic managed route\";\n }\n if (billing.upstreamPayer === \"connected_subscription\") {\n return \"Codex subscription · external billing\";\n }\n if (billing.upstreamPayer === \"workspace\") {\n return \"Billed to your AI Gateway\";\n }\n return \"Deployment route · external billing\";\n}\n\nexport function advancedSourceSummary(model: ClientModel): string | null {\n const source = model.credentialSource;\n if (!source) {\n return null;\n }\n if (source.kind === \"connected_subscription\") {\n return \"Connected Codex subscription\";\n }\n if (source.kind === \"workspace_connection\") {\n return \"Workspace AI Gateway\";\n }\n if (source.kind === \"deployment\") {\n return source.mechanism === \"azure_ad_bearer\"\n ? \"Deployment Azure identity\"\n : \"Deployment API key\";\n }\n return null;\n}\n\nexport function projectPickerRows(models: WorkspaceModelCatalogModel[]): PickerModelRow[] {\n return models\n .filter((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return billingClass === \"opengeni_credits\" || catalog.credentialReadiness.status === \"ready\";\n })\n .map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: catalog.label,\n billingClass,\n billingClassLabel: billingClassLabel(billingClass),\n selectable: catalog.availability.selectable,\n unavailableReason: catalog.availability.selectable\n ? null\n : availabilityReasonLabel(catalog.availability.reason),\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\nexport function sortPickerRows(rows: PickerModelRow[]): PickerModelRow[] {\n return [...rows].sort((left, right) => {\n const classDelta =\n BILLING_CLASS_ORDER.indexOf(left.billingClass) -\n BILLING_CLASS_ORDER.indexOf(right.billingClass);\n if (classDelta !== 0) {\n return classDelta;\n }\n if (left.selectable !== right.selectable) {\n return left.selectable ? -1 : 1;\n }\n return left.label.localeCompare(right.label);\n });\n}\n\nexport function findPickerRow(rows: PickerModelRow[], modelId: string): PickerModelRow | null {\n return rows.find((row) => row.id === modelId) ?? null;\n}\n\nexport function groupPickerRowsByBillingClass(\n rows: PickerModelRow[],\n): Array<{ billingClass: PickerBillingClass; label: string; rows: PickerModelRow[] }> {\n const sorted = sortPickerRows(rows);\n const groups: Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow[];\n }> = [];\n for (const row of sorted) {\n const existing = groups.find((group) => group.billingClass === row.billingClass);\n if (existing) {\n existing.rows.push(row);\n continue;\n }\n groups.push({\n billingClass: row.billingClass,\n label: row.billingClassLabel,\n rows: [row],\n });\n }\n return groups;\n}\n"],"mappings":";AAkBA,IAAM,sBAA4C;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,uBAA2D;AAAA,EAC/D,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,MAAM;AACR;AAEA,IAAM,6BAAqD;AAAA,EACzD,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,aAAa;AACf;AAEO,SAAS,qBAAqB,OAAwC;AAC3E,MAAI,MAAM,WAAW,SAAS;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,WAAW,qBAAqB;AACxC,WAAO;AAAA,EACT;AACA,MAAI,MAAM,kBAAkB,SAAS,0BAA0B;AAC7D,WAAO;AAAA,EACT;AACA,MAAI,MAAM,kBAAkB,SAAS,wBAAwB;AAC3D,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,kBAAkB,0BAA0B;AAC7D,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,kBAAkB,aAAa;AAChD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,cAA0C;AAC1E,SAAO,qBAAqB,YAAY;AAC1C;AAEO,SAAS,wBACd,QACe;AACf,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SAAO,2BAA2B,MAAM,KAAK;AAC/C;AAEO,SAAS,sBAAsB,OAAuC;AAC3E,QAAM,UAAU,MAAM,cAAc,UAAU;AAC9C,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,CAAC,KAAK;AAAA,EACf;AACA,QAAM,QAA2B,CAAC,QAAQ,WAAW,OAAO,UAAU,QAAQ,OAAO;AACrF,SAAO,MAAM,OAAO,CAAC,WAAW,QAAQ,SAAS,MAAM,CAAC;AAC1D;AAEO,SAAS,sBAAsB,OAAqC;AACzE,QAAM,UAAU,sBAAsB,KAAK;AAC3C,QAAM,aAAa,MAAM,cAAc,UAAU;AACjD,MAAI,cAAc,QAAQ,SAAS,UAAU,GAAG;AAC9C,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEO,SAAS,8BACd,OACA,QACiB;AACjB,QAAM,UAAU,sBAAsB,KAAK;AAC3C,MAAI,QAAQ,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,sBAAsB,KAAK;AACpC;AAEO,SAAS,6BAA6B,OAAqC;AAChF,QAAM,QAAQ,MAAM,cAAc,gBAAgB,CAAC;AACnD,SAAO,MAAM,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,IAAI,CAAC,SAAS,KAAK,EAAE;AACpE;AAEO,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,YAAY;AACvB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,qBAAqB,OAA4B;AAC/D,QAAM,UAAU,MAAM;AACtB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,aAAa,oBAAoB;AAC3C,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,kBAAkB,0BAA0B;AACtD,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,kBAAkB,aAAa;AACzC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAmC;AACvE,QAAM,SAAS,MAAM;AACrB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,0BAA0B;AAC5C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,wBAAwB;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,cAAc;AAChC,WAAO,OAAO,cAAc,oBACxB,8BACA;AAAA,EACN;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAAwD;AACxF,SAAO,OACJ,OAAO,CAAC,YAAY;AACnB,UAAM,eAAe,qBAAqB,OAAO;AACjD,WAAO,iBAAiB,sBAAsB,QAAQ,oBAAoB,WAAW;AAAA,EACvF,CAAC,EACA,IAAI,CAAC,YAAY;AAChB,UAAM,eAAe,qBAAqB,OAAO;AACjD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf;AAAA,MACA,mBAAmB,kBAAkB,YAAY;AAAA,MACjD,YAAY,QAAQ,aAAa;AAAA,MACjC,mBAAmB,QAAQ,aAAa,aACpC,OACA,wBAAwB,QAAQ,aAAa,MAAM;AAAA,MACvD,UAAU,QAAQ;AAAA,MAClB,eAAe,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEO,SAAS,eAAe,MAA0C;AACvE,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,UAAU;AACrC,UAAM,aACJ,oBAAoB,QAAQ,KAAK,YAAY,IAC7C,oBAAoB,QAAQ,MAAM,YAAY;AAChD,QAAI,eAAe,GAAG;AACpB,aAAO;AAAA,IACT;AACA,QAAI,KAAK,eAAe,MAAM,YAAY;AACxC,aAAO,KAAK,aAAa,KAAK;AAAA,IAChC;AACA,WAAO,KAAK,MAAM,cAAc,MAAM,KAAK;AAAA,EAC7C,CAAC;AACH;AAEO,SAAS,cAAc,MAAwB,SAAwC;AAC5F,SAAO,KAAK,KAAK,CAAC,QAAQ,IAAI,OAAO,OAAO,KAAK;AACnD;AAEO,SAAS,8BACd,MACoF;AACpF,QAAM,SAAS,eAAe,IAAI;AAClC,QAAM,SAID,CAAC;AACN,aAAW,OAAO,QAAQ;AACxB,UAAM,WAAW,OAAO,KAAK,CAAC,UAAU,MAAM,iBAAiB,IAAI,YAAY;AAC/E,QAAI,UAAU;AACZ,eAAS,KAAK,KAAK,GAAG;AACtB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV,cAAc,IAAI;AAAA,MAClB,OAAO,IAAI;AAAA,MACX,MAAM,CAAC,GAAG;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-FT2TXNGZ.js";
5
5
  import {
6
6
  groupPickerRowsByBillingClass
7
- } from "./chunk-U255M5EZ.js";
7
+ } from "./chunk-22RM4GMO.js";
8
8
  import {
9
9
  Tooltip,
10
10
  TooltipContent,
@@ -1249,10 +1249,10 @@ import { useId, useMemo as useMemo3 } from "react";
1249
1249
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1250
1250
  var EMPTY_CLIENT_MODELS = [];
1251
1251
  function isCodexClientModel(model) {
1252
- return model.id.startsWith("codex/") || model.provider === "codex-subscription";
1252
+ return model.id.startsWith("codex/") || model.source === "codex";
1253
1253
  }
1254
1254
  function isCodexPickerRow(row) {
1255
- return row.id.startsWith("codex/") || row.provider === "codex-subscription";
1255
+ return row.id.startsWith("codex/") || row.catalog.source === "codex";
1256
1256
  }
1257
1257
  function applyCodexOnlyRows(rows, codexOnly) {
1258
1258
  if (!codexOnly) return rows;
@@ -1902,9 +1902,20 @@ function Attachments() {
1902
1902
  }
1903
1903
  );
1904
1904
  }
1905
- var Input = forwardRef(function ComposerInput({ rows = 1, placeholder, className, "aria-label": ariaLabel, ...props }, forwardedRef) {
1905
+ var Input = forwardRef(function ComposerInput({ rows = 1, placeholder, className, "aria-label": ariaLabel, autoFocus = false, ...props }, forwardedRef) {
1906
1906
  const controller = useComposerController();
1907
+ const autoFocusedRef = useRef4(false);
1907
1908
  const paletteOpen = controller.paletteEnabled && controller.paletteMounted && controller.palette.open;
1909
+ useEffect3(() => {
1910
+ if (!autoFocus || controller.disabled || autoFocusedRef.current) return;
1911
+ const frame = window.requestAnimationFrame(() => {
1912
+ const textarea = controller.textareaRef.current;
1913
+ if (!textarea || textarea.disabled) return;
1914
+ autoFocusedRef.current = true;
1915
+ textarea.focus();
1916
+ });
1917
+ return () => window.cancelAnimationFrame(frame);
1918
+ }, [autoFocus, controller.disabled, controller.textareaRef]);
1908
1919
  return /* @__PURE__ */ jsx3(
1909
1920
  "textarea",
1910
1921
  {
@@ -1917,6 +1928,7 @@ var Input = forwardRef(function ComposerInput({ rows = 1, placeholder, className
1917
1928
  onPaste: controller.handlePaste,
1918
1929
  placeholder: controller.paused && !controller.disabled ? controller.messages.pausedPlaceholder : placeholder ?? controller.messages.messagePlaceholder,
1919
1930
  disabled: controller.disabled,
1931
+ autoFocus: autoFocus && !controller.disabled,
1920
1932
  "aria-label": ariaLabel ?? controller.messages.inputLabel,
1921
1933
  "aria-keyshortcuts": "Enter Meta+Enter Control+Enter Shift+Enter",
1922
1934
  "aria-autocomplete": controller.paletteEnabled && controller.paletteMounted ? "list" : void 0,
@@ -2799,4 +2811,4 @@ export {
2799
2811
  Status,
2800
2812
  ComposerTranscriptionControl
2801
2813
  };
2802
- //# sourceMappingURL=chunk-PVW56EVR.js.map
2814
+ //# sourceMappingURL=chunk-N4XEBE23.js.map