@opengeni/react 7.6.1-canary.37073905159001 → 7.6.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.
Files changed (136) hide show
  1. package/README.md +2 -19
  2. package/dist/{browser-viewer-63TXMINB.js → browser-viewer-5X47I6T2.js} +5 -6
  3. package/dist/{chunk-TKB4SB44.js → chunk-45GE35O7.js} +2 -10
  4. package/dist/chunk-45GE35O7.js.map +1 -0
  5. package/dist/{chunk-DOJWJQ3F.js → chunk-5EXGU7UF.js} +3 -3
  6. package/dist/{chunk-YN7I3STW.js → chunk-6NEZPF53.js} +32 -153
  7. package/dist/chunk-6NEZPF53.js.map +1 -0
  8. package/dist/{chunk-I7IWRQLN.js → chunk-BI57CQUV.js} +2 -2
  9. package/dist/{chunk-6ZSWSH4I.js → chunk-CHPKSLPN.js} +1 -3
  10. package/dist/chunk-CHPKSLPN.js.map +1 -0
  11. package/dist/{chunk-Q5QBEZIQ.js → chunk-DV2DBNPQ.js} +29 -48
  12. package/dist/chunk-DV2DBNPQ.js.map +1 -0
  13. package/dist/{chunk-RDKBXMWX.js → chunk-FGBCYQOT.js} +74 -120
  14. package/dist/chunk-FGBCYQOT.js.map +1 -0
  15. package/dist/{chunk-AAG4R3QN.js → chunk-KGENSZKS.js} +3 -4
  16. package/dist/chunk-KGENSZKS.js.map +1 -0
  17. package/dist/{chunk-YQEAA6LT.js → chunk-KZ73RL76.js} +3 -7
  18. package/dist/chunk-KZ73RL76.js.map +1 -0
  19. package/dist/{chunk-LFXYGZWK.js → chunk-LZ3KHA55.js} +60 -169
  20. package/dist/chunk-LZ3KHA55.js.map +1 -0
  21. package/dist/{chunk-2QUSQVF2.js → chunk-UINDK6C3.js} +3 -3
  22. package/dist/{chunk-UTRTG6LH.js → chunk-UJRYEWZI.js} +8 -48
  23. package/dist/chunk-UJRYEWZI.js.map +1 -0
  24. package/dist/{chunk-XOAMRDDK.js → chunk-VGIKFIO2.js} +3 -6
  25. package/dist/chunk-VGIKFIO2.js.map +1 -0
  26. package/dist/{chunk-ELCE5SXV.js → chunk-WZ55DVGK.js} +4 -8
  27. package/dist/chunk-WZ55DVGK.js.map +1 -0
  28. package/dist/{chunk-IQUCRAT7.js → chunk-XA6R7DJQ.js} +3 -3
  29. package/dist/{chunk-TOAH2BKA.js → chunk-YCGBREUV.js} +2 -6
  30. package/dist/{chunk-TOAH2BKA.js.map → chunk-YCGBREUV.js.map} +1 -1
  31. package/dist/{chunk-HNFCAQ5R.js → chunk-YRYF2GLG.js} +31 -39
  32. package/dist/chunk-YRYF2GLG.js.map +1 -0
  33. package/dist/{chunk-GISEVGS6.js → chunk-YSMMDOOE.js} +2 -10
  34. package/dist/chunk-YSMMDOOE.js.map +1 -0
  35. package/dist/{chunk-CWWKTNKK.js → chunk-Z3DISEQN.js} +18 -35
  36. package/dist/chunk-Z3DISEQN.js.map +1 -0
  37. package/dist/client.d.ts +1 -4
  38. package/dist/commands/types.d.ts +0 -2
  39. package/dist/components/approval-surface.d.ts +0 -15
  40. package/dist/composer.js +7 -8
  41. package/dist/{computer-viewer-X2MBRZY4.js → computer-viewer-7GF35SNY.js} +4 -5
  42. package/dist/connect.js +3 -3
  43. package/dist/hooks/use-browser-session.d.ts +0 -4
  44. package/dist/hooks/use-composer.d.ts +0 -2
  45. package/dist/hooks/use-computer-session.d.ts +0 -2
  46. package/dist/hooks/use-file-attachments.d.ts +0 -2
  47. package/dist/hooks/use-session-events.d.ts +1 -1
  48. package/dist/hooks/use-workspace-sessions.d.ts +5 -15
  49. package/dist/index.d.ts +2 -2
  50. package/dist/index.js +21 -28
  51. package/dist/index.js.map +1 -1
  52. package/dist/interaction.d.ts +1 -1
  53. package/dist/interaction.js +5 -6
  54. package/dist/interaction.js.map +1 -1
  55. package/dist/{latest-question-CNEZ5KAN.js → latest-question-3BJGKQQ6.js} +3 -3
  56. package/dist/lib/format.d.ts +3 -27
  57. package/dist/lib/interaction-errors.d.ts +0 -3
  58. package/dist/machines.js +4 -5
  59. package/dist/{model-policy-picker-menu-JSA64TNN.js → model-policy-picker-menu-PUTA5JOB.js} +4 -4
  60. package/dist/model-policy.js +1 -1
  61. package/dist/provider.d.ts +1 -5
  62. package/dist/{queue-surface-implementation-HENWYFWA.js → queue-surface-implementation-2CAQAIHM.js} +2 -3
  63. package/dist/{queue-surface-implementation-HENWYFWA.js.map → queue-surface-implementation-2CAQAIHM.js.map} +1 -1
  64. package/dist/realtime.js +2 -2
  65. package/dist/{sandbox-files-BBC47SLD.js → sandbox-files-AEJTWGT4.js} +3 -4
  66. package/dist/session-ui.d.ts +1 -1
  67. package/dist/session-ui.js +12 -13
  68. package/dist/session-ui.js.map +1 -1
  69. package/dist/session.js +6 -7
  70. package/dist/usage.js +1 -2
  71. package/dist/usage.js.map +1 -1
  72. package/package.json +3 -3
  73. package/src/client.ts +1 -5
  74. package/src/commands/registry.ts +15 -18
  75. package/src/commands/types.ts +0 -2
  76. package/src/components/approval-surface.tsx +42 -166
  77. package/src/components/browser-viewer.tsx +9 -38
  78. package/src/components/composer.tsx +2 -9
  79. package/src/components/computer-viewer.tsx +30 -160
  80. package/src/components/generated-video-player.tsx +2 -4
  81. package/src/components/human-input-form.tsx +5 -18
  82. package/src/components/message-timeline.tsx +2 -4
  83. package/src/components/open-geni-chat.tsx +4 -11
  84. package/src/components/queue-surface-state.tsx +1 -3
  85. package/src/components/session-chrome.tsx +2 -5
  86. package/src/components/session-commands-panel.tsx +1 -3
  87. package/src/components/session-conversation.tsx +2 -4
  88. package/src/components/session-list.tsx +5 -7
  89. package/src/components/session-mcp-capability-card.tsx +1 -11
  90. package/src/hooks/internal.ts +2 -3
  91. package/src/hooks/use-browser-session.ts +79 -115
  92. package/src/hooks/use-composer.ts +31 -70
  93. package/src/hooks/use-computer-session.ts +6 -57
  94. package/src/hooks/use-file-attachments.ts +3 -16
  95. package/src/hooks/use-goal.ts +1 -2
  96. package/src/hooks/use-session-capabilities.ts +2 -3
  97. package/src/hooks/use-session-events.ts +8 -15
  98. package/src/hooks/use-slash-commands.ts +11 -6
  99. package/src/hooks/use-turn-queue.ts +1 -2
  100. package/src/hooks/use-workspace-sessions.ts +7 -40
  101. package/src/index.ts +2 -7
  102. package/src/interaction.ts +0 -1
  103. package/src/lib/format.ts +9 -73
  104. package/src/lib/interaction-errors.ts +0 -15
  105. package/src/model-policy.ts +0 -5
  106. package/src/provider.tsx +4 -12
  107. package/src/session-ui.ts +1 -1
  108. package/src/timeline/projection.ts +1 -12
  109. package/styles/compiled.css +0 -14
  110. package/dist/chunk-6ZSWSH4I.js.map +0 -1
  111. package/dist/chunk-AAG4R3QN.js.map +0 -1
  112. package/dist/chunk-CWWKTNKK.js.map +0 -1
  113. package/dist/chunk-ELCE5SXV.js.map +0 -1
  114. package/dist/chunk-GISEVGS6.js.map +0 -1
  115. package/dist/chunk-HNFCAQ5R.js.map +0 -1
  116. package/dist/chunk-LFXYGZWK.js.map +0 -1
  117. package/dist/chunk-Q5QBEZIQ.js.map +0 -1
  118. package/dist/chunk-RDKBXMWX.js.map +0 -1
  119. package/dist/chunk-TKB4SB44.js.map +0 -1
  120. package/dist/chunk-UGLEYEMP.js +0 -33
  121. package/dist/chunk-UGLEYEMP.js.map +0 -1
  122. package/dist/chunk-UTRTG6LH.js.map +0 -1
  123. package/dist/chunk-XOAMRDDK.js.map +0 -1
  124. package/dist/chunk-YN7I3STW.js.map +0 -1
  125. package/dist/chunk-YQEAA6LT.js.map +0 -1
  126. package/dist/lib/error-message.d.ts +0 -7
  127. package/src/lib/error-message.ts +0 -37
  128. /package/dist/{browser-viewer-63TXMINB.js.map → browser-viewer-5X47I6T2.js.map} +0 -0
  129. /package/dist/{chunk-DOJWJQ3F.js.map → chunk-5EXGU7UF.js.map} +0 -0
  130. /package/dist/{chunk-I7IWRQLN.js.map → chunk-BI57CQUV.js.map} +0 -0
  131. /package/dist/{chunk-2QUSQVF2.js.map → chunk-UINDK6C3.js.map} +0 -0
  132. /package/dist/{chunk-IQUCRAT7.js.map → chunk-XA6R7DJQ.js.map} +0 -0
  133. /package/dist/{computer-viewer-X2MBRZY4.js.map → computer-viewer-7GF35SNY.js.map} +0 -0
  134. /package/dist/{latest-question-CNEZ5KAN.js.map → latest-question-3BJGKQQ6.js.map} +0 -0
  135. /package/dist/{model-policy-picker-menu-JSA64TNN.js.map → model-policy-picker-menu-PUTA5JOB.js.map} +0 -0
  136. /package/dist/{sandbox-files-BBC47SLD.js.map → sandbox-files-AEJTWGT4.js.map} +0 -0
@@ -1,19 +1,15 @@
1
- import type { Session, SessionListEntry } from "@opengeni/sdk";
1
+ import type { Session } from "@opengeni/sdk";
2
2
  import { useCallback, useEffect, useRef } from "react";
3
3
  import { useOpenGeni, type ClientOverride } from "../provider";
4
4
  import { usePolledValue } from "./internal";
5
5
 
6
6
  export type UseWorkspaceSessionsOptions = ClientOverride & {
7
- /** Compact list records; detail reads remain full sessions. */
8
- projection?: "summary" | undefined;
9
7
  limit?: number | undefined;
10
8
  parentSessionId?: string | null | undefined;
11
9
  cursor?: string | undefined;
12
10
  search?: string | undefined;
13
11
  /** Return only the complete personal pinned projection. */
14
12
  pinsOnly?: boolean | undefined;
15
- /** Skip pinned details when the pinned section is loaded separately. */
16
- includePinned?: boolean | undefined;
17
13
  archivedOnly?: boolean | undefined;
18
14
  sortBy?: "updatedAt" | "createdAt" | "name" | undefined;
19
15
  archiveStatus?: "active" | "archived" | "all" | undefined;
@@ -24,14 +20,14 @@ export type UseWorkspaceSessionsOptions = ClientOverride & {
24
20
  beginRead?: (() => number) | undefined;
25
21
  };
26
22
 
27
- export type UseWorkspaceSessionsResult<T extends Session | SessionListEntry = Session> = {
23
+ export type UseWorkspaceSessionsResult = {
28
24
  /**
29
25
  * All visible rows, with pins first. This preserves the pre-pinning hook
30
26
  * contract for consumers that only read `sessions`.
31
27
  */
32
- sessions: T[];
28
+ sessions: Session[];
33
29
  /** The complete personal pinned section, also present in `sessions`. */
34
- pinned: T[];
30
+ pinned: Session[];
35
31
  /** True when the server omitted older pins from its bounded pinned section. */
36
32
  pinnedTruncated: boolean;
37
33
  nextCursor: string | null;
@@ -45,26 +41,15 @@ export type UseWorkspaceSessionsResult<T extends Session | SessionListEntry = Se
45
41
  };
46
42
 
47
43
  /** List the workspace's sessions — the data behind fleet and manager views. */
48
- export function useWorkspaceSessions(
49
- options: UseWorkspaceSessionsOptions & { projection: "summary" },
50
- ): UseWorkspaceSessionsResult<SessionListEntry>;
51
- export function useWorkspaceSessions(
52
- options?: UseWorkspaceSessionsOptions & { projection?: undefined },
53
- ): UseWorkspaceSessionsResult;
54
- export function useWorkspaceSessions(
55
- options: UseWorkspaceSessionsOptions,
56
- ): UseWorkspaceSessionsResult<Session | SessionListEntry>;
57
44
  export function useWorkspaceSessions(
58
45
  options: UseWorkspaceSessionsOptions = {},
59
- ): UseWorkspaceSessionsResult<Session | SessionListEntry> {
46
+ ): UseWorkspaceSessionsResult {
60
47
  const { client, workspaceId } = useOpenGeni(options);
61
- const projection = options.projection;
62
48
  const limit = options.limit;
63
49
  const parentSessionId = options.parentSessionId;
64
50
  const cursor = options.cursor;
65
51
  const search = options.search;
66
52
  const pinsOnly = options.pinsOnly;
67
- const includePinned = options.includePinned;
68
53
  const archivedOnly = options.archivedOnly;
69
54
  const sortBy = options.sortBy;
70
55
  const archiveStatus = options.archiveStatus;
@@ -74,13 +59,11 @@ export function useWorkspaceSessions(
74
59
  const beginRead = options.beginRead;
75
60
  const queryKey = [
76
61
  workspaceId,
77
- projection ?? "full",
78
62
  limit ?? "",
79
63
  parentSessionId === null ? "null" : (parentSessionId ?? ""),
80
64
  cursor ?? "",
81
65
  search ?? "",
82
66
  pinsOnly ? "1" : "",
83
- includePinned === false ? "no-pins" : "",
84
67
  archivedOnly ? "archived" : "active",
85
68
  sortBy ?? "",
86
69
  archiveStatus ?? "",
@@ -93,31 +76,17 @@ export function useWorkspaceSessions(
93
76
  const load = useCallback(
94
77
  async (signal?: AbortSignal) => {
95
78
  const readGeneration = beginRead?.() ?? ++nextReadGeneration.current;
96
- const query = {
79
+ const page = await client.listSessionPage(workspaceId, {
97
80
  ...(limit !== undefined ? { limit } : {}),
98
81
  ...(parentSessionId !== undefined ? { parentSessionId } : {}),
99
82
  ...(cursor !== undefined ? { cursor } : {}),
100
83
  ...(search !== undefined ? { search } : {}),
101
84
  ...(pinsOnly ? { pinsOnly: true } : {}),
102
- ...(includePinned === false ? { includePinned: false } : {}),
103
85
  ...(archivedOnly ? { archivedOnly: true } : {}),
104
86
  ...(sortBy ? { sortBy } : {}),
105
87
  ...(archiveStatus ? { archiveStatus } : {}),
106
88
  signal,
107
- };
108
- const page =
109
- projection === "summary"
110
- ? client.listSessionSummaryPage
111
- ? await client.listSessionSummaryPage(workspaceId, query)
112
- : await client.listSessionPage(workspaceId, query).then(async (full) => {
113
- const { sessionListEntry } = await import("@opengeni/sdk/session-list-entries");
114
- return {
115
- ...full,
116
- pinned: full.pinned.map(sessionListEntry),
117
- sessions: full.sessions.map(sessionListEntry),
118
- };
119
- })
120
- : await client.listSessionPage(workspaceId, query);
89
+ });
121
90
  return {
122
91
  queryKey,
123
92
  page,
@@ -129,13 +98,11 @@ export function useWorkspaceSessions(
129
98
  beginRead,
130
99
  client,
131
100
  workspaceId,
132
- projection,
133
101
  limit,
134
102
  parentSessionId,
135
103
  cursor,
136
104
  search,
137
105
  pinsOnly,
138
- includePinned,
139
106
  archivedOnly,
140
107
  sortBy,
141
108
  archiveStatus,
package/src/index.ts CHANGED
@@ -43,7 +43,7 @@ export type {
43
43
  SessionClientLike,
44
44
  } from "./client";
45
45
  export { OpenGeniProvider } from "./provider";
46
- export type { OpenGeniProviderProps, ErrorMessageFormatter } from "./provider";
46
+ export type { OpenGeniProviderProps } from "./provider";
47
47
  export { useOpenGeni, useOpenGeniClient } from "./session-context";
48
48
  export { useVideoArtifactPlaybackLoader } from "./hooks/use-video-artifact-playback";
49
49
  export type { ClientOverride, OpenGeniContextValue } from "./session-context";
@@ -130,12 +130,7 @@ export type {
130
130
  VoiceRecordingTranscriptionState,
131
131
  VoiceRecordingUploadState,
132
132
  } from "./voice-recording-store";
133
- export {
134
- COMPOSER_MODEL_UNAVAILABLE_MESSAGE,
135
- COMPOSER_PAYMENT_REQUIRED_MESSAGE,
136
- composerSubmissionErrorMessage,
137
- isModelUnavailableSubmissionError,
138
- } from "./lib/format";
133
+ export { COMPOSER_PAYMENT_REQUIRED_MESSAGE, composerSubmissionErrorMessage } from "./lib/format";
139
134
  export {
140
135
  INITIAL_TRANSCRIPTION_CONTROL_STATE,
141
136
  appendFinalTranscript,
@@ -58,7 +58,6 @@ export type {
58
58
  } from "./hooks/use-browser-identities";
59
59
  export { useBrowserSession } from "./hooks/use-browser-session";
60
60
  export type {
61
- BrowserInputFailure,
62
61
  UseBrowserSessionOptions,
63
62
  UseBrowserSessionResult,
64
63
  } from "./hooks/use-browser-session";
package/src/lib/format.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { formatErrorMessage, OpenGeniApiError } from "@opengeni/sdk";
1
+ import { OpenGeniApiError } from "@opengeni/sdk";
2
2
 
3
3
  const clockTimeFormatter = new Intl.DateTimeFormat(undefined, {
4
4
  month: "short",
@@ -109,7 +109,7 @@ export function tryParseJson(text: string): unknown {
109
109
  * workspace no longer has.
110
110
  */
111
111
  export const CREDIT_EXHAUSTION_MESSAGE =
112
- "Out of credits — this workspace's balance is empty. Add credits to continue; the conversation is preserved.";
112
+ "Out of Opengeni credits — this workspace's balance is empty. Add credits to continue; the conversation is preserved.";
113
113
 
114
114
  /** A usage ceiling refused the send; the default allowance wording, plus what is safe. */
115
115
  export const COMPOSER_MEMBER_ALLOWANCE_MESSAGE =
@@ -123,87 +123,23 @@ export const COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE =
123
123
  * actor-private draft or any finalized attachment.
124
124
  */
125
125
  export const COMPOSER_PAYMENT_REQUIRED_MESSAGE =
126
- "Your organization doesn't have enough credits to send this message. Add credits or choose a model with another payment source. Your message and attachments are saved.";
127
-
128
- /** Trusted, composer-owned guidance; unlike remote diagnostic prose, this is UI copy. */
129
- export class ComposerStateError extends Error {}
130
-
131
- /** A restored request has omitted credentials and must be reconciled, not replayed. */
132
- export class ComposerReconciliationRequiredError extends ComposerStateError {
133
- constructor() {
134
- super(
135
- "Opengeni cannot safely retry this uncertain request after remount; reconcile the session before sending again.",
136
- );
137
- }
138
- }
139
-
140
- export class ComposerWorkspaceControlUnavailableError extends Error {
141
- constructor() {
142
- super("@opengeni/react: workspace-scoped resume requires setWorkspaceInferenceState.");
143
- }
144
- }
145
-
146
- /**
147
- * The send named a model that is no longer in the live catalog (retired or
148
- * removed). Retrying the same send cannot succeed; the person must choose
149
- * another model, and the typed message stays recoverable via Edit message.
150
- */
151
- export const COMPOSER_MODEL_UNAVAILABLE_MESSAGE =
152
- "This chat's model is no longer available. Choose another model to continue. Your message is saved.";
153
-
154
- /** `details.code` the API sets on a 422 for a model missing from the live catalog. */
155
- export const MODEL_UNAVAILABLE_DETAIL_CODE = "model_unavailable";
156
-
157
- /**
158
- * Is this send refusal "the model is no longer available"? Reads the typed
159
- * `details.code`, and also the historical message so a refusal persisted
160
- * before a reload (only its text survives) or from an older API is recognized.
161
- */
162
- export function isModelUnavailableSubmissionError(error: Error): boolean {
163
- if (error instanceof OpenGeniApiError && error.details?.code === MODEL_UNAVAILABLE_DETAIL_CODE) {
164
- return true;
165
- }
166
- return (
167
- error.message === COMPOSER_MODEL_UNAVAILABLE_MESSAGE ||
168
- /^OpenGeni API 422: model is not available: /.test(error.message)
169
- );
170
- }
126
+ "Your organization doesn't have enough OpenGeni credits to send this message. Add credits or choose a model with another payment source. Your message and attachments are saved.";
171
127
 
172
128
  export function composerSubmissionErrorMessage(error: Error): string {
173
- if (error instanceof ComposerReconciliationRequiredError) {
174
- return "This client cannot safely retry this uncertain request after remount; reconcile the session before sending again.";
175
- }
176
- if (error instanceof ComposerWorkspaceControlUnavailableError) {
177
- return "This client cannot resume the workspace. Ask your administrator for a control-capable client.";
178
- }
179
- if (error instanceof ComposerStateError) return error.message;
180
- if (error instanceof OpenGeniApiError && error.outcomeUnknown) return formatErrorMessage(error);
181
- if (isModelUnavailableSubmissionError(error)) return COMPOSER_MODEL_UNAVAILABLE_MESSAGE;
182
129
  if (error instanceof OpenGeniApiError && error.code === "allowance_exhausted") {
183
130
  // OpenGeniAllowanceExhaustedError carries the scope; read it structurally
184
131
  // so this startup-path helper adds no SDK or wording imports.
185
- const message =
186
- (error as { scope?: unknown }).scope === "workspace"
187
- ? COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE
188
- : COMPOSER_MEMBER_ALLOWANCE_MESSAGE;
189
- return composerErrorReference(error, message);
132
+ return (error as { scope?: unknown }).scope === "workspace"
133
+ ? COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE
134
+ : COMPOSER_MEMBER_ALLOWANCE_MESSAGE;
190
135
  }
191
- return isComposerCreditRefusal(error)
192
- ? composerErrorReference(error, COMPOSER_PAYMENT_REQUIRED_MESSAGE)
193
- : formatErrorMessage(error);
194
- }
195
-
196
- function composerErrorReference(error: Error, message: string): string {
197
- return error instanceof OpenGeniApiError && error.correlationId
198
- ? `${message} Reference: ${error.correlationId}.`
199
- : message;
136
+ return isComposerCreditRefusal(error) ? COMPOSER_PAYMENT_REQUIRED_MESSAGE : error.message;
200
137
  }
201
138
 
202
- /** These definitive refusals need a payment, allowance or model change, not an unchanged retry. */
139
+ /** These definitive refusals need a payment or allowance change, not an unchanged retry. */
203
140
  export function composerSubmissionCanRetry(error: Error): boolean {
204
141
  return !(
205
142
  isComposerCreditRefusal(error) ||
206
- isModelUnavailableSubmissionError(error) ||
207
143
  (error instanceof OpenGeniApiError && error.code === "allowance_exhausted")
208
144
  );
209
145
  }
@@ -292,7 +228,7 @@ export function presentFailure(payload: Record<string, unknown>): {
292
228
  typeof payload.database === "object" &&
293
229
  !Array.isArray(payload.database));
294
230
  if (databaseFailure) {
295
- return { reason: "The service encountered a database error.", safetyRefusal: false };
231
+ return { reason: "OpenGeni encountered a database error.", safetyRefusal: false };
296
232
  }
297
233
  const text = (key: string): string | null => {
298
234
  const value = payload[key];
@@ -1,19 +1,4 @@
1
1
  import { OpenGeniApiError } from "@opengeni/sdk";
2
- import { interactionControlFailureFromError } from "@opengeni/sdk/interaction";
3
-
4
- /** Media can remain live when the independent control service is unavailable.
5
- * A target refusal or an uncertain mutation does not establish a service outage. */
6
- export function isInteractionControlUnavailable(
7
- error: unknown,
8
- request: "control" | "observation" = "control",
9
- ): error is OpenGeniApiError {
10
- if (!(error instanceof OpenGeniApiError)) return false;
11
- const failure = interactionControlFailureFromError(error);
12
- if (failure) return failure.code === "agent_offline" || failure.code === "draining";
13
- return (
14
- request === "control" && !error.outcomeUnknown && (error.status >= 500 || error.status === 0)
15
- );
16
- }
17
2
 
18
3
  export function isNonRetryableInteractionError(error: unknown): error is OpenGeniApiError {
19
4
  return error instanceof OpenGeniApiError && error.retryable === false;
@@ -47,11 +47,6 @@ export function billingClassForModel(model: ClientModel): PickerBillingClass {
47
47
  if (model.provider === "organization-gateway" || model.provider === "organization-openrouter") {
48
48
  return "organization_byok";
49
49
  }
50
- if (
51
- model.provider?.startsWith("workspace-openai-") ||
52
- model.provider?.startsWith("workspace-azure-openai-")
53
- )
54
- return "byok";
55
50
  if (model.provider === "workspace-gateway" || model.provider === "workspace-openrouter") {
56
51
  return "byok";
57
52
  }
package/src/provider.tsx CHANGED
@@ -9,9 +9,6 @@ import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } fro
9
9
  import type { SessionClientLike } from "./client";
10
10
  import { usePageLiveActivity } from "./hooks/internal";
11
11
  import { OpenGeniContext } from "./session-context";
12
- import { ErrorMessageContext, type ErrorMessageFormatter } from "./lib/error-message";
13
-
14
- export type { ErrorMessageFormatter } from "./lib/error-message";
15
12
 
16
13
  export { useOpenGeni, useOpenGeniClient } from "./session-context";
17
14
  export type { ClientOverride, OpenGeniContextValue } from "./session-context";
@@ -30,8 +27,6 @@ export type OpenGeniProviderProps = {
30
27
  * the SDK's tolerant-reader compatibility applies.
31
28
  */
32
29
  reloadOnApiContractChange?: boolean | undefined;
33
- /** Host-owned error copy. Receives the original diagnostic error and neutral default copy. */
34
- formatError?: ErrorMessageFormatter | undefined;
35
30
  children?: ReactNode;
36
31
  };
37
32
 
@@ -45,7 +40,6 @@ export function OpenGeniProvider({
45
40
  onWorkspaceControlEvent,
46
41
  onWorkspaceInteractionEvent,
47
42
  reloadOnApiContractChange = false,
48
- formatError,
49
43
  children,
50
44
  }: OpenGeniProviderProps) {
51
45
  const [workspaceControlEvent, setWorkspaceControlEvent] = useState<WorkspaceControlEvent | null>(
@@ -337,12 +331,10 @@ export function OpenGeniProvider({
337
331
  ],
338
332
  );
339
333
  return (
340
- <ErrorMessageContext.Provider value={formatError}>
341
- <OpenGeniContext.Provider value={value}>
342
- {children}
343
- {contractMismatch ? <ApiContractMismatchScreen mismatch={contractMismatch} /> : null}
344
- </OpenGeniContext.Provider>
345
- </ErrorMessageContext.Provider>
334
+ <OpenGeniContext.Provider value={value}>
335
+ {children}
336
+ {contractMismatch ? <ApiContractMismatchScreen mismatch={contractMismatch} /> : null}
337
+ </OpenGeniContext.Provider>
346
338
  );
347
339
  }
348
340
 
package/src/session-ui.ts CHANGED
@@ -55,7 +55,7 @@ export { QueueSurface } from "./components/queue-surface";
55
55
  // The provider too, so a host needs only this entry (the root also exports the
56
56
  // workbench, whose editors, terminal and desktop are optional peers).
57
57
  export { OpenGeniProvider } from "./provider";
58
- export type { OpenGeniProviderProps, ErrorMessageFormatter } from "./provider";
58
+ export type { OpenGeniProviderProps } from "./provider";
59
59
  // The tool-renderer registry, so custom tool renderers need no root import.
60
60
  export { createDefaultToolRegistry, createToolRegistry, defaultToolRegistry } from "./timeline";
61
61
  export type {
@@ -2017,19 +2017,8 @@ function groupReadableTurns(items: TimelineItem[]): TimelineGroup[] {
2017
2017
  if (group?.work) group.work.details.push({ kind: "item", item });
2018
2018
  else groups.push({ kind: "item", item });
2019
2019
  } else {
2020
+ groups.push({ kind: "item", item });
2020
2021
  const current = turns.get(currentTurn)?.work;
2021
- // A live approval wait is carried by the turn header ("Waiting for you")
2022
- // and decided in the host's approval surface; a second in-timeline banner
2023
- // only repeats it. Once resolved it returns as the quiet recorded marker.
2024
- const liveApprovalWait =
2025
- item.kind === "notice" &&
2026
- item.tone === "waiting" &&
2027
- !item.recordedOutcome &&
2028
- !item.resolvedAt &&
2029
- item.text.startsWith("Approval needed") &&
2030
- current !== undefined &&
2031
- !current.endedAt;
2032
- if (!liveApprovalWait) groups.push({ kind: "item", item });
2033
2022
  if (current && !current.endedAt) {
2034
2023
  if (
2035
2024
  item.kind === "notice" &&
@@ -2051,9 +2051,6 @@
2051
2051
  :where(.og-root).max-h-20,:where(.og-root) .max-h-20 {
2052
2052
  max-height: calc(var(--spacing) * 20);
2053
2053
  }
2054
- :where(.og-root).max-h-32,:where(.og-root) .max-h-32 {
2055
- max-height: calc(var(--spacing) * 32);
2056
- }
2057
2054
  :where(.og-root).max-h-40,:where(.og-root) .max-h-40 {
2058
2055
  max-height: calc(var(--spacing) * 40);
2059
2056
  }
@@ -2537,9 +2534,6 @@
2537
2534
  :where(.og-root).grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\],:where(.og-root) .grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\] {
2538
2535
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
2539
2536
  }
2540
- :where(.og-root).grid-cols-\[minmax\(5\.5rem\,max-content\)_minmax\(0\,1fr\)\],:where(.og-root) .grid-cols-\[minmax\(5\.5rem\,max-content\)_minmax\(0\,1fr\)\] {
2541
- grid-template-columns: minmax(5.5rem,max-content) minmax(0,1fr);
2542
- }
2543
2537
  :where(.og-root).flex-col,:where(.og-root) .flex-col {
2544
2538
  flex-direction: column;
2545
2539
  }
@@ -2714,14 +2708,6 @@
2714
2708
  }
2715
2709
  }
2716
2710
  }
2717
- :where(.og-root).divide-og-status-waiting\/20,:where(.og-root) .divide-og-status-waiting\/20 {
2718
- :where(& > :not(:last-child)) {
2719
- border-color: var(--og-color-status-waiting);
2720
- @supports (color: color-mix(in lab, red, red)) {
2721
- border-color: color-mix(in oklab, var(--og-color-status-waiting) 20%, transparent);
2722
- }
2723
- }
2724
- }
2725
2711
  :where(.og-root).self-center,:where(.og-root) .self-center {
2726
2712
  align-self: center;
2727
2713
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/model-policy.ts"],"sourcesContent":["import {\n compareModelPickerOrder,\n modelPickerBillingClassFor,\n type ModelPickerBillingClass,\n} from \"@opengeni/sdk/model-picker-order\";\nimport type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\n\nexport type PickerBillingClass = ModelPickerBillingClass;\n\nexport type PickerModelRow<TCatalog extends ClientModel = WorkspaceModelCatalogModel> = {\n id: string;\n label: string;\n /** Catalog-curated compact label for dense UI; fall back to `label` when absent. */\n shortLabel?: string | undefined;\n billingClass: PickerBillingClass;\n billingClassLabel: string;\n selectable: boolean;\n unavailableReason: string | null;\n provider: string;\n providerLabel: string;\n catalog: TCatalog;\n};\n\nexport type LatencyModeId = \"standard\" | \"priority\" | \"fast\";\n\nconst BILLING_CLASS_LABELS: Record<PickerBillingClass, string> = {\n opengeni_credits: \"Opengeni\",\n external: \"External\",\n codex_subscription: \"Codex\",\n supergrok_subscription: \"SuperGrok\",\n claude_subscription: \"Claude subscription\",\n byok: \"Workspace providers\",\n organization_byok: \"Organization providers\",\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.provider === \"organization-gateway\" || model.provider === \"organization-openrouter\") {\n return \"organization_byok\";\n }\n if (\n model.provider?.startsWith(\"workspace-openai-\") ||\n model.provider?.startsWith(\"workspace-azure-openai-\")\n )\n return \"byok\";\n if (model.provider === \"workspace-gateway\" || model.provider === \"workspace-openrouter\") {\n return \"byok\";\n }\n return modelPickerBillingClassFor(model);\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\", \"max\"];\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 labelReasoningEffort(effort: ReasoningEffort): string {\n if (effort === \"xhigh\") {\n return \"Extra high\";\n }\n return effort.slice(0, 1).toUpperCase() + effort.slice(1);\n}\n\n/** Payment prompts must use cost policy, never the presentation group. */\nexport function modelUsesCredits(model: ClientModel | undefined): boolean {\n if (model?.cost !== undefined) return model.cost === \"credits\";\n return model?.billing?.metering === \"opengeni_credits\";\n}\n\nexport function payerSummaryForModel(model: ClientModel): string {\n if (model.cost === \"free\") {\n return \"Free in this deployment\";\n }\n if (model.cost === \"credits\") {\n return \"Opengeni credits\";\n }\n if (model.cost === \"subscription\") {\n return model.source === \"supergrok\"\n ? \"SuperGrok subscription · external billing\"\n : \"Codex subscription · external billing\";\n }\n if (model.cost === \"workspace\") {\n return workspaceProviderPayerSummary(model);\n }\n if (model.cost === \"organization\") {\n return organizationProviderPayerSummary(model);\n }\n\n // Older client-config payloads do not carry `cost`; preserve their existing\n // settlement-derived label until every deployment has rolled forward.\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 model.source === \"supergrok\"\n ? \"SuperGrok subscription · external billing\"\n : \"Codex subscription · external billing\";\n }\n if (billing.upstreamPayer === \"workspace\") {\n return workspaceProviderPayerSummary(model);\n }\n if (billing.upstreamPayer === \"organization\") {\n return organizationProviderPayerSummary(model);\n }\n return billing.upstreamPayer === \"deployment\"\n ? \"Opengeni · no model credits\"\n : \"External provider · no Opengeni credits\";\n}\n\nexport function advancedSourceSummary(model: ClientModel): string | null {\n const source = model.credentialSource;\n if (!source) {\n return model.billing?.metering === \"external\" && model.billing.upstreamPayer === \"deployment\"\n ? \"Deployment-provided connection\"\n : null;\n }\n if (source.kind === \"connected_subscription\") {\n return source.provider === \"xai\"\n ? \"Connected SuperGrok subscription\"\n : \"Connected Codex subscription\";\n }\n if (source.kind === \"workspace_connection\") {\n if (model.provider === \"workspace-openrouter\") {\n return \"Workspace OpenRouter connection\";\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return \"Workspace Vercel AI Gateway\";\n }\n return \"Workspace provider connection\";\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\nfunction workspaceProviderPayerSummary(model: ClientModel): string {\n if (model.provider === \"workspace-anthropic\")\n return \"Billed to the workspace Anthropic API account\";\n if (model.provider === \"workspace-claude-subscription\")\n return \"Uses the workspace Claude subscription · no OpenGeni credits\";\n if (model.provider === \"workspace-openrouter\") {\n return \"Billed to the workspace OpenRouter account\";\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return \"Billed to the workspace Vercel account\";\n }\n return \"Billed to the workspace provider account\";\n}\n\nfunction organizationProviderPayerSummary(model: ClientModel): string {\n if (model.provider === \"organization-anthropic\")\n return \"Billed to the organization Anthropic API account\";\n if (model.provider === \"organization-claude-subscription\")\n return \"Uses the connected Claude subscription · no OpenGeni credits\";\n if (model.provider === \"organization-openrouter\") {\n return \"Billed to the organization OpenRouter account\";\n }\n if (model.provider === \"organization-gateway\") {\n return \"Billed to the organization Vercel account\";\n }\n return \"Billed to the organization provider account\";\n}\n\nexport function projectPickerRows(models: WorkspaceModelCatalogModel[]): PickerModelRow[] {\n return models\n .filter((catalog) => catalog.credentialReadiness.status === \"ready\")\n .map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: catalog.label,\n ...(catalog.shortLabel ? { shortLabel: catalog.shortLabel } : {}),\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\n/** Project the lightweight client-config model list into the same picker contract. */\nexport function projectClientModelRows(models: ClientModel[]): PickerModelRow<ClientModel>[] {\n return models.map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: catalog.label,\n ...(catalog.shortLabel ? { shortLabel: catalog.shortLabel } : {}),\n billingClass,\n billingClassLabel: billingClassLabel(billingClass),\n selectable: true,\n unavailableReason: null,\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\nexport function sortPickerRows<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n): PickerModelRow<TCatalog>[] {\n return [...rows].sort(compareModelPickerOrder);\n}\n\nexport function findPickerRow<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n modelId: string,\n): PickerModelRow<TCatalog> | null {\n return rows.find((row) => row.id === modelId) ?? null;\n}\n\nexport function groupPickerRowsByBillingClass(\n rows: PickerModelRow[],\n options?: { codexOnly?: boolean },\n): Array<{ billingClass: PickerBillingClass; label: string; rows: PickerModelRow[] }>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n options?: { codexOnly?: boolean },\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n options?: { codexOnly?: boolean },\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}> {\n const sorted = sortPickerRows(rows);\n const groups: Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\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 const codexIndex = groups.findIndex((group) => group.billingClass === \"codex_subscription\");\n const codex = groups[codexIndex];\n const selectableOpenGeni = groups\n .find((group) => group.billingClass === \"opengeni_credits\")\n ?.rows.filter((row) => row.selectable);\n // Presentation only: never change the catalog/default model ordering or selection.\n const onlyFreeOpenGeni =\n selectableOpenGeni !== undefined &&\n selectableOpenGeni.length > 0 &&\n selectableOpenGeni.every((row) => row.catalog.cost === \"free\");\n if (\n codex &&\n codex.rows.some((row) => row.selectable) &&\n (options?.codexOnly || onlyFreeOpenGeni)\n ) {\n groups.splice(codexIndex, 1);\n groups.unshift(codex);\n }\n return groups;\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAqBP,IAAM,uBAA2D;AAAA,EAC/D,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,MAAM;AAAA,EACN,mBAAmB;AACrB;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,aAAa,0BAA0B,MAAM,aAAa,2BAA2B;AAC7F,WAAO;AAAA,EACT;AACA,MACE,MAAM,UAAU,WAAW,mBAAmB,KAC9C,MAAM,UAAU,WAAW,yBAAyB;AAEpD,WAAO;AACT,MAAI,MAAM,aAAa,uBAAuB,MAAM,aAAa,wBAAwB;AACvF,WAAO;AAAA,EACT;AACA,SAAO,2BAA2B,KAAK;AACzC;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,SAAS,KAAK;AAC5F,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,QAAiC;AACpE,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,MAAM,GAAG,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAC1D;AAGO,SAAS,iBAAiB,OAAyC;AACxE,MAAI,OAAO,SAAS,OAAW,QAAO,MAAM,SAAS;AACrD,SAAO,OAAO,SAAS,aAAa;AACtC;AAEO,SAAS,qBAAqB,OAA4B;AAC/D,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,WAAW;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO,MAAM,WAAW,cACpB,iDACA;AAAA,EACN;AACA,MAAI,MAAM,SAAS,aAAa;AAC9B,WAAO,8BAA8B,KAAK;AAAA,EAC5C;AACA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO,iCAAiC,KAAK;AAAA,EAC/C;AAIA,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,MAAM,WAAW,cACpB,iDACA;AAAA,EACN;AACA,MAAI,QAAQ,kBAAkB,aAAa;AACzC,WAAO,8BAA8B,KAAK;AAAA,EAC5C;AACA,MAAI,QAAQ,kBAAkB,gBAAgB;AAC5C,WAAO,iCAAiC,KAAK;AAAA,EAC/C;AACA,SAAO,QAAQ,kBAAkB,eAC7B,mCACA;AACN;AAEO,SAAS,sBAAsB,OAAmC;AACvE,QAAM,SAAS,MAAM;AACrB,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,SAAS,aAAa,cAAc,MAAM,QAAQ,kBAAkB,eAC7E,mCACA;AAAA,EACN;AACA,MAAI,OAAO,SAAS,0BAA0B;AAC5C,WAAO,OAAO,aAAa,QACvB,qCACA;AAAA,EACN;AACA,MAAI,OAAO,SAAS,wBAAwB;AAC1C,QAAI,MAAM,aAAa,wBAAwB;AAC7C,aAAO;AAAA,IACT;AACA,QAAI,MAAM,aAAa,uBAAuB,MAAM,WAAW,qBAAqB;AAClF,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,cAAc;AAChC,WAAO,OAAO,cAAc,oBACxB,8BACA;AAAA,EACN;AACA,SAAO;AACT;AAEA,SAAS,8BAA8B,OAA4B;AACjE,MAAI,MAAM,aAAa;AACrB,WAAO;AACT,MAAI,MAAM,aAAa;AACrB,WAAO;AACT,MAAI,MAAM,aAAa,wBAAwB;AAC7C,WAAO;AAAA,EACT;AACA,MAAI,MAAM,aAAa,uBAAuB,MAAM,WAAW,qBAAqB;AAClF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,iCAAiC,OAA4B;AACpE,MAAI,MAAM,aAAa;AACrB,WAAO;AACT,MAAI,MAAM,aAAa;AACrB,WAAO;AACT,MAAI,MAAM,aAAa,2BAA2B;AAChD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,aAAa,wBAAwB;AAC7C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAAwD;AACxF,SAAO,OACJ,OAAO,CAAC,YAAY,QAAQ,oBAAoB,WAAW,OAAO,EAClE,IAAI,CAAC,YAAY;AAChB,UAAM,eAAe,qBAAqB,OAAO;AACjD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,MAC/D;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;AAGO,SAAS,uBAAuB,QAAsD;AAC3F,SAAO,OAAO,IAAI,CAAC,YAAY;AAC7B,UAAM,eAAe,qBAAqB,OAAO;AACjD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,MAC/D;AAAA,MACA,mBAAmB,kBAAkB,YAAY;AAAA,MACjD,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,UAAU,QAAQ;AAAA,MAClB,eAAe,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,eACd,MAC4B;AAC5B,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,uBAAuB;AAC/C;AAEO,SAAS,cACd,MACA,SACiC;AACjC,SAAO,KAAK,KAAK,CAAC,QAAQ,IAAI,OAAO,OAAO,KAAK;AACnD;AAcO,SAAS,8BACd,MACA,SAKC;AACD,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,QAAM,aAAa,OAAO,UAAU,CAAC,UAAU,MAAM,iBAAiB,oBAAoB;AAC1F,QAAM,QAAQ,OAAO,UAAU;AAC/B,QAAM,qBAAqB,OACxB,KAAK,CAAC,UAAU,MAAM,iBAAiB,kBAAkB,GACxD,KAAK,OAAO,CAAC,QAAQ,IAAI,UAAU;AAEvC,QAAM,mBACJ,uBAAuB,UACvB,mBAAmB,SAAS,KAC5B,mBAAmB,MAAM,CAAC,QAAQ,IAAI,QAAQ,SAAS,MAAM;AAC/D,MACE,SACA,MAAM,KAAK,KAAK,CAAC,QAAQ,IAAI,UAAU,MACtC,SAAS,aAAa,mBACvB;AACA,WAAO,OAAO,YAAY,CAAC;AAC3B,WAAO,QAAQ,KAAK;AAAA,EACtB;AACA,SAAO;AACT;","names":[]}