@opengeni/react 7.5.0 → 7.6.0-canary.36935312914001

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 (35) hide show
  1. package/dist/{browser-viewer-Z7S7QEJL.js → browser-viewer-5X47I6T2.js} +3 -3
  2. package/dist/{chunk-FNWQBQOK.js → chunk-55JRUWOA.js} +20 -15
  3. package/dist/chunk-55JRUWOA.js.map +1 -0
  4. package/dist/{chunk-AFLPWUQ7.js → chunk-BI57CQUV.js} +2 -2
  5. package/dist/{chunk-5KYZIQFY.js → chunk-DV2DBNPQ.js} +2 -2
  6. package/dist/{chunk-BDKR6BAR.js → chunk-FGBCYQOT.js} +2 -2
  7. package/dist/{chunk-ZXSEDZP7.js → chunk-KGENSZKS.js} +2 -2
  8. package/dist/{chunk-3IJJEYW4.js → chunk-UJRYEWZI.js} +5 -1
  9. package/dist/{chunk-3IJJEYW4.js.map → chunk-UJRYEWZI.js.map} +1 -1
  10. package/dist/{chunk-LWNLETQT.js → chunk-XA6R7DJQ.js} +2 -2
  11. package/dist/{chunk-2VFNCX4E.js → chunk-YRYF2GLG.js} +3 -3
  12. package/dist/{chunk-M7LBYP63.js → chunk-Z3DISEQN.js} +3 -3
  13. package/dist/composer.js +3 -3
  14. package/dist/connect.js +2 -2
  15. package/dist/index.js +9 -9
  16. package/dist/interaction.js +2 -2
  17. package/dist/{latest-question-IS445HOW.js → latest-question-3BJGKQQ6.js} +3 -3
  18. package/dist/machines.js +2 -2
  19. package/dist/session-ui.js +7 -7
  20. package/dist/session.js +4 -4
  21. package/dist/timeline/genie-loading.d.ts +3 -1
  22. package/package.json +3 -3
  23. package/src/lib/format.ts +12 -0
  24. package/src/timeline/activity-rail.tsx +5 -3
  25. package/src/timeline/genie-loading.tsx +16 -6
  26. package/dist/chunk-FNWQBQOK.js.map +0 -1
  27. /package/dist/{browser-viewer-Z7S7QEJL.js.map → browser-viewer-5X47I6T2.js.map} +0 -0
  28. /package/dist/{chunk-AFLPWUQ7.js.map → chunk-BI57CQUV.js.map} +0 -0
  29. /package/dist/{chunk-5KYZIQFY.js.map → chunk-DV2DBNPQ.js.map} +0 -0
  30. /package/dist/{chunk-BDKR6BAR.js.map → chunk-FGBCYQOT.js.map} +0 -0
  31. /package/dist/{chunk-ZXSEDZP7.js.map → chunk-KGENSZKS.js.map} +0 -0
  32. /package/dist/{chunk-LWNLETQT.js.map → chunk-XA6R7DJQ.js.map} +0 -0
  33. /package/dist/{chunk-2VFNCX4E.js.map → chunk-YRYF2GLG.js.map} +0 -0
  34. /package/dist/{chunk-M7LBYP63.js.map → chunk-Z3DISEQN.js.map} +0 -0
  35. /package/dist/{latest-question-IS445HOW.js.map → latest-question-3BJGKQQ6.js.map} +0 -0
@@ -23,7 +23,7 @@ import {
23
23
  } from "./chunk-BRM6FVZA.js";
24
24
  import {
25
25
  stringifyPayload
26
- } from "./chunk-3IJJEYW4.js";
26
+ } from "./chunk-UJRYEWZI.js";
27
27
  import {
28
28
  cn
29
29
  } from "./chunk-22KP6LR5.js";
@@ -1605,4 +1605,4 @@ export {
1605
1605
  retainedImageId,
1606
1606
  Markdown
1607
1607
  };
1608
- //# sourceMappingURL=chunk-AFLPWUQ7.js.map
1608
+ //# sourceMappingURL=chunk-BI57CQUV.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  composerSubmissionCanRetry,
3
3
  composerSubmissionErrorMessage
4
- } from "./chunk-3IJJEYW4.js";
4
+ } from "./chunk-UJRYEWZI.js";
5
5
  import {
6
6
  useSessionEventTrigger
7
7
  } from "./chunk-KZ73RL76.js";
@@ -2133,4 +2133,4 @@ export {
2133
2133
  shouldSubmitOnKey,
2134
2134
  shouldSteerOnKey
2135
2135
  };
2136
- //# sourceMappingURL=chunk-5KYZIQFY.js.map
2136
+ //# sourceMappingURL=chunk-DV2DBNPQ.js.map
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-RHREZ7BO.js";
14
14
  import {
15
15
  formatBytes
16
- } from "./chunk-3IJJEYW4.js";
16
+ } from "./chunk-UJRYEWZI.js";
17
17
  import {
18
18
  STREAM_CLOSE_REASON_NORMAL,
19
19
  STREAM_KIND_BROWSER,
@@ -4471,4 +4471,4 @@ export {
4471
4471
  useBrowserFrameStream,
4472
4472
  BrowserViewer
4473
4473
  };
4474
- //# sourceMappingURL=chunk-BDKR6BAR.js.map
4474
+ //# sourceMappingURL=chunk-FGBCYQOT.js.map
@@ -7,7 +7,7 @@ import {
7
7
  isCreditExhaustion,
8
8
  presentFailure,
9
9
  tryParseJson
10
- } from "./chunk-3IJJEYW4.js";
10
+ } from "./chunk-UJRYEWZI.js";
11
11
 
12
12
  // src/timeline/projection.ts
13
13
  import {
@@ -2572,4 +2572,4 @@ export {
2572
2572
  isTurnExecutionEvidence,
2573
2573
  extractSessionRef
2574
2574
  };
2575
- //# sourceMappingURL=chunk-ZXSEDZP7.js.map
2575
+ //# sourceMappingURL=chunk-KGENSZKS.js.map
@@ -137,6 +137,10 @@ function humanizeFailureReason(reason) {
137
137
  return reason;
138
138
  }
139
139
  function presentFailure(payload) {
140
+ const databaseFailure = payload.code === "db_deadlock" || payload.code === "db_serialization_failure" || payload.code === "db_failure" || typeof payload.sqlState === "string" && /^[0-9A-Z]{5}$/.test(payload.sqlState) && payload.database !== null && typeof payload.database === "object" && !Array.isArray(payload.database);
141
+ if (databaseFailure) {
142
+ return { reason: "OpenGeni encountered a database error.", safetyRefusal: false };
143
+ }
140
144
  const text = (key) => {
141
145
  const value = payload[key];
142
146
  return typeof value === "string" && value.trim() ? value : null;
@@ -173,4 +177,4 @@ export {
173
177
  humanizeFailureReason,
174
178
  presentFailure
175
179
  };
176
- //# sourceMappingURL=chunk-3IJJEYW4.js.map
180
+ //# sourceMappingURL=chunk-UJRYEWZI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/format.ts"],"sourcesContent":["import { OpenGeniApiError } from \"@opengeni/sdk\";\n\nconst clockTimeFormatter = new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n});\n\n/** Local finished-at stamp for message footers: \"Aug 2, 3:42 PM\" / locale-equivalent. */\nexport function formatClockTime(iso: string): string {\n const then = new Date(iso);\n if (Number.isNaN(then.getTime())) {\n return \"\";\n }\n return clockTimeFormatter.format(then);\n}\n\n/** Compact relative time: \"now\", \"42s\", \"7m\", \"3h\", \"2d\", then a date. */\nexport function formatRelativeTime(iso: string, now: Date = new Date()): string {\n const then = new Date(iso).getTime();\n if (Number.isNaN(then)) {\n return \"\";\n }\n const seconds = Math.max(0, Math.floor((now.getTime() - then) / 1000));\n if (seconds < 10) {\n return \"now\";\n }\n if (seconds < 60) {\n return `${seconds}s`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes}m`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours}h`;\n }\n const days = Math.floor(hours / 24);\n if (days < 14) {\n return `${days}d`;\n }\n return new Date(iso).toLocaleDateString();\n}\n\n/** Human-readable byte size: \"512 B\", \"8.0 KB\", \"1.4 MB\", \"3 GB\". */\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\"] as const;\n let value = bytes / 1024;\n for (const unit of units) {\n if (value < 1024 || unit === \"GB\") {\n return `${value.toFixed(value < 10 ? 1 : 0)} ${unit}`;\n }\n value /= 1024;\n }\n return `${bytes} B`;\n}\n\n/** Single-line preview of arbitrary text, for tiles and collapsed rows. */\nexport function truncate(text: string, maxLength: number): string {\n const collapsed = text.replace(/\\s+/g, \" \").trim();\n if (collapsed.length <= maxLength) {\n return collapsed;\n }\n return `${collapsed.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\n/** Render an unknown payload as readable text (pretty JSON when possible). */\nexport function stringifyPayload(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n const parsed = tryParseJson(value);\n if (parsed !== undefined && typeof parsed === \"object\") {\n return stringifyPayload(parsed);\n }\n return value;\n }\n try {\n return JSON.stringify(value, null, 2) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** JSON.parse that returns `undefined` instead of throwing. */\nexport function tryParseJson(text: string): unknown {\n const trimmed = text.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\") && !trimmed.startsWith('\"')) {\n return undefined;\n }\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The canonical credit-death sentence. Credit exhaustion is the one failure a\n * user can fix themselves — the copy must say what happened (empty balance),\n * what to do (add credits), and what is safe (nothing was lost). Crucially it\n * must NOT say \"send a message to revive\": a revive turn burns credits the\n * workspace no longer has.\n */\nexport const CREDIT_EXHAUSTION_MESSAGE =\n \"Out of Opengeni credits — this workspace's balance is empty. Add credits to continue; the conversation is preserved.\";\n\n/** A usage ceiling refused the send; the default allowance wording, plus what is safe. */\nexport const COMPOSER_MEMBER_ALLOWANCE_MESSAGE =\n \"Usage limit reached. A workspace admin can raise this limit. Your draft is preserved.\";\nexport const COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE =\n \"Workspace usage limit reached. An organization admin can raise the workspace budget. Your draft is preserved.\";\n\n/**\n * Actionable composer copy for an edge rejection before a turn is accepted.\n * Unlike an in-flight credit exhaustion, this path has not consumed the\n * actor-private draft or any finalized attachment.\n */\nexport const COMPOSER_PAYMENT_REQUIRED_MESSAGE =\n \"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.\";\n\nexport function composerSubmissionErrorMessage(error: Error): string {\n if (error instanceof OpenGeniApiError && error.code === \"allowance_exhausted\") {\n // OpenGeniAllowanceExhaustedError carries the scope; read it structurally\n // so this startup-path helper adds no SDK or wording imports.\n return (error as { scope?: unknown }).scope === \"workspace\"\n ? COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE\n : COMPOSER_MEMBER_ALLOWANCE_MESSAGE;\n }\n return isComposerCreditRefusal(error) ? COMPOSER_PAYMENT_REQUIRED_MESSAGE : error.message;\n}\n\n/** These definitive refusals need a payment or allowance change, not an unchanged retry. */\nexport function composerSubmissionCanRetry(error: Error): boolean {\n return !(\n isComposerCreditRefusal(error) ||\n (error instanceof OpenGeniApiError && error.code === \"allowance_exhausted\")\n );\n}\n\nfunction isComposerCreditRefusal(error: Error): boolean {\n return (\n (error instanceof OpenGeniApiError &&\n error.status === 402 &&\n (error.code === \"payment_required\" || error.code === \"insufficient_credits\")) ||\n isCreditExhaustion(error.message)\n );\n}\n\n/**\n * Does this failure/completion payload (or raw error string) mean the\n * workspace ran out of OpenGeni credits? Matches the engine's\n * \"insufficient OpenGeni credits\" text (case-insensitive, substring — it\n * arrives both bare and wrapped in \"Activity task failed: …\") and the\n * budget-exhausted segment limit the engine stamps on a turn it ended early.\n */\nexport function isCreditExhaustion(\n input: { error?: string | null; detail?: string | null; segmentLimit?: string | null } | string,\n): boolean {\n if (typeof input === \"string\") {\n return input.toLowerCase().includes(\"insufficient opengeni credits\");\n }\n if (input.segmentLimit === \"budget_exhausted\") {\n return true;\n }\n for (const text of [input.error, input.detail]) {\n if (typeof text === \"string\" && text.toLowerCase().includes(\"insufficient opengeni credits\")) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Humanize engine/provider failure text before it reaches the timeline or a\n * failure banner. Raw provider errors leak the wrong audience's instructions —\n * \"Incorrect API key … find your API key at platform.openai.com\" tells a\n * managed-deployment USER to fix credentials only an OPERATOR controls (and is\n * flatly wrong for Azure or subscription-backed engines). Auth, quota, and\n * credit-exhaustion failures collapse to one neutral, honest sentence; every\n * other reason passes through untouched. Raw payloads stay available in the\n * debug surfaces.\n */\nexport function humanizeFailureReason(reason: string | null): string | null {\n if (!reason) {\n return reason;\n }\n if (isCreditExhaustion(reason)) {\n return CREDIT_EXHAUSTION_MESSAGE;\n }\n const normalized = reason.toLowerCase();\n const authFailure =\n normalized.includes(\"incorrect api key\") ||\n normalized.includes(\"invalid api key\") ||\n normalized.includes(\"invalid_api_key\") ||\n normalized.includes(\"platform.openai.com/account/api-keys\") ||\n (normalized.includes(\"401\") &&\n (normalized.includes(\"api key\") || normalized.includes(\"unauthorized\")));\n if (authFailure) {\n return \"The model provider rejected this deployment's engine credentials. Sending messages won't help until the deployment's engine configuration is fixed.\";\n }\n const quotaFailure =\n normalized.includes(\"insufficient_quota\") || normalized.includes(\"exceeded your current quota\");\n if (quotaFailure) {\n return \"The model provider refused the request: this deployment's provider quota is exhausted.\";\n }\n return reason;\n}\n\n/** Project failure diagnostics without changing the stored event, including legacy retry wrappers. */\nexport function presentFailure(payload: Record<string, unknown>): {\n reason: string | null;\n safetyRefusal: boolean;\n} {\n const text = (key: string): string | null => {\n const value = payload[key];\n return typeof value === \"string\" && value.trim() ? value : null;\n };\n const message = text(\"error\") ?? text(\"message\");\n const detail = text(\"lastRetryableError\") ?? text(\"detail\");\n const safetyRefusal =\n payload.code === \"provider_safety_refusal\" ||\n [message, detail].some(\n (value) =>\n value !== null && /\\bthis request was blocked by our safety systems\\b/i.test(value),\n );\n if (safetyRefusal) {\n return {\n reason: `The model provider blocked this request.${detail || message ? ` ${detail ?? message}` : \"\"}`,\n safetyRefusal: true,\n };\n }\n return {\n reason:\n detail && detail !== message\n ? [humanizeFailureReason(message), humanizeFailureReason(detail)].filter(Boolean).join(\" \")\n : humanizeFailureReason(message),\n safetyRefusal: false,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/format.ts"],"sourcesContent":["import { OpenGeniApiError } from \"@opengeni/sdk\";\n\nconst clockTimeFormatter = new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n});\n\n/** Local finished-at stamp for message footers: \"Aug 2, 3:42 PM\" / locale-equivalent. */\nexport function formatClockTime(iso: string): string {\n const then = new Date(iso);\n if (Number.isNaN(then.getTime())) {\n return \"\";\n }\n return clockTimeFormatter.format(then);\n}\n\n/** Compact relative time: \"now\", \"42s\", \"7m\", \"3h\", \"2d\", then a date. */\nexport function formatRelativeTime(iso: string, now: Date = new Date()): string {\n const then = new Date(iso).getTime();\n if (Number.isNaN(then)) {\n return \"\";\n }\n const seconds = Math.max(0, Math.floor((now.getTime() - then) / 1000));\n if (seconds < 10) {\n return \"now\";\n }\n if (seconds < 60) {\n return `${seconds}s`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes}m`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours}h`;\n }\n const days = Math.floor(hours / 24);\n if (days < 14) {\n return `${days}d`;\n }\n return new Date(iso).toLocaleDateString();\n}\n\n/** Human-readable byte size: \"512 B\", \"8.0 KB\", \"1.4 MB\", \"3 GB\". */\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\"] as const;\n let value = bytes / 1024;\n for (const unit of units) {\n if (value < 1024 || unit === \"GB\") {\n return `${value.toFixed(value < 10 ? 1 : 0)} ${unit}`;\n }\n value /= 1024;\n }\n return `${bytes} B`;\n}\n\n/** Single-line preview of arbitrary text, for tiles and collapsed rows. */\nexport function truncate(text: string, maxLength: number): string {\n const collapsed = text.replace(/\\s+/g, \" \").trim();\n if (collapsed.length <= maxLength) {\n return collapsed;\n }\n return `${collapsed.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\n/** Render an unknown payload as readable text (pretty JSON when possible). */\nexport function stringifyPayload(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n const parsed = tryParseJson(value);\n if (parsed !== undefined && typeof parsed === \"object\") {\n return stringifyPayload(parsed);\n }\n return value;\n }\n try {\n return JSON.stringify(value, null, 2) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** JSON.parse that returns `undefined` instead of throwing. */\nexport function tryParseJson(text: string): unknown {\n const trimmed = text.trim();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\") && !trimmed.startsWith('\"')) {\n return undefined;\n }\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The canonical credit-death sentence. Credit exhaustion is the one failure a\n * user can fix themselves — the copy must say what happened (empty balance),\n * what to do (add credits), and what is safe (nothing was lost). Crucially it\n * must NOT say \"send a message to revive\": a revive turn burns credits the\n * workspace no longer has.\n */\nexport const CREDIT_EXHAUSTION_MESSAGE =\n \"Out of Opengeni credits — this workspace's balance is empty. Add credits to continue; the conversation is preserved.\";\n\n/** A usage ceiling refused the send; the default allowance wording, plus what is safe. */\nexport const COMPOSER_MEMBER_ALLOWANCE_MESSAGE =\n \"Usage limit reached. A workspace admin can raise this limit. Your draft is preserved.\";\nexport const COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE =\n \"Workspace usage limit reached. An organization admin can raise the workspace budget. Your draft is preserved.\";\n\n/**\n * Actionable composer copy for an edge rejection before a turn is accepted.\n * Unlike an in-flight credit exhaustion, this path has not consumed the\n * actor-private draft or any finalized attachment.\n */\nexport const COMPOSER_PAYMENT_REQUIRED_MESSAGE =\n \"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.\";\n\nexport function composerSubmissionErrorMessage(error: Error): string {\n if (error instanceof OpenGeniApiError && error.code === \"allowance_exhausted\") {\n // OpenGeniAllowanceExhaustedError carries the scope; read it structurally\n // so this startup-path helper adds no SDK or wording imports.\n return (error as { scope?: unknown }).scope === \"workspace\"\n ? COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE\n : COMPOSER_MEMBER_ALLOWANCE_MESSAGE;\n }\n return isComposerCreditRefusal(error) ? COMPOSER_PAYMENT_REQUIRED_MESSAGE : error.message;\n}\n\n/** These definitive refusals need a payment or allowance change, not an unchanged retry. */\nexport function composerSubmissionCanRetry(error: Error): boolean {\n return !(\n isComposerCreditRefusal(error) ||\n (error instanceof OpenGeniApiError && error.code === \"allowance_exhausted\")\n );\n}\n\nfunction isComposerCreditRefusal(error: Error): boolean {\n return (\n (error instanceof OpenGeniApiError &&\n error.status === 402 &&\n (error.code === \"payment_required\" || error.code === \"insufficient_credits\")) ||\n isCreditExhaustion(error.message)\n );\n}\n\n/**\n * Does this failure/completion payload (or raw error string) mean the\n * workspace ran out of OpenGeni credits? Matches the engine's\n * \"insufficient OpenGeni credits\" text (case-insensitive, substring — it\n * arrives both bare and wrapped in \"Activity task failed: …\") and the\n * budget-exhausted segment limit the engine stamps on a turn it ended early.\n */\nexport function isCreditExhaustion(\n input: { error?: string | null; detail?: string | null; segmentLimit?: string | null } | string,\n): boolean {\n if (typeof input === \"string\") {\n return input.toLowerCase().includes(\"insufficient opengeni credits\");\n }\n if (input.segmentLimit === \"budget_exhausted\") {\n return true;\n }\n for (const text of [input.error, input.detail]) {\n if (typeof text === \"string\" && text.toLowerCase().includes(\"insufficient opengeni credits\")) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Humanize engine/provider failure text before it reaches the timeline or a\n * failure banner. Raw provider errors leak the wrong audience's instructions —\n * \"Incorrect API key … find your API key at platform.openai.com\" tells a\n * managed-deployment USER to fix credentials only an OPERATOR controls (and is\n * flatly wrong for Azure or subscription-backed engines). Auth, quota, and\n * credit-exhaustion failures collapse to one neutral, honest sentence; every\n * other reason passes through untouched. Raw payloads stay available in the\n * debug surfaces.\n */\nexport function humanizeFailureReason(reason: string | null): string | null {\n if (!reason) {\n return reason;\n }\n if (isCreditExhaustion(reason)) {\n return CREDIT_EXHAUSTION_MESSAGE;\n }\n const normalized = reason.toLowerCase();\n const authFailure =\n normalized.includes(\"incorrect api key\") ||\n normalized.includes(\"invalid api key\") ||\n normalized.includes(\"invalid_api_key\") ||\n normalized.includes(\"platform.openai.com/account/api-keys\") ||\n (normalized.includes(\"401\") &&\n (normalized.includes(\"api key\") || normalized.includes(\"unauthorized\")));\n if (authFailure) {\n return \"The model provider rejected this deployment's engine credentials. Sending messages won't help until the deployment's engine configuration is fixed.\";\n }\n const quotaFailure =\n normalized.includes(\"insufficient_quota\") || normalized.includes(\"exceeded your current quota\");\n if (quotaFailure) {\n return \"The model provider refused the request: this deployment's provider quota is exhausted.\";\n }\n return reason;\n}\n\n/** Project failure diagnostics without changing the stored event, including legacy retry wrappers. */\nexport function presentFailure(payload: Record<string, unknown>): {\n reason: string | null;\n safetyRefusal: boolean;\n} {\n const databaseFailure =\n payload.code === \"db_deadlock\" ||\n payload.code === \"db_serialization_failure\" ||\n payload.code === \"db_failure\" ||\n (typeof payload.sqlState === \"string\" &&\n /^[0-9A-Z]{5}$/.test(payload.sqlState) &&\n payload.database !== null &&\n typeof payload.database === \"object\" &&\n !Array.isArray(payload.database));\n if (databaseFailure) {\n return { reason: \"OpenGeni encountered a database error.\", safetyRefusal: false };\n }\n const text = (key: string): string | null => {\n const value = payload[key];\n return typeof value === \"string\" && value.trim() ? value : null;\n };\n const message = text(\"error\") ?? text(\"message\");\n const detail = text(\"lastRetryableError\") ?? text(\"detail\");\n const safetyRefusal =\n payload.code === \"provider_safety_refusal\" ||\n [message, detail].some(\n (value) =>\n value !== null && /\\bthis request was blocked by our safety systems\\b/i.test(value),\n );\n if (safetyRefusal) {\n return {\n reason: `The model provider blocked this request.${detail || message ? ` ${detail ?? message}` : \"\"}`,\n safetyRefusal: true,\n };\n }\n return {\n reason:\n detail && detail !== message\n ? [humanizeFailureReason(message), humanizeFailureReason(detail)].filter(Boolean).join(\" \")\n : humanizeFailureReason(message),\n safetyRefusal: false,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  formatBytes,
3
3
  formatRelativeTime
4
- } from "./chunk-3IJJEYW4.js";
4
+ } from "./chunk-UJRYEWZI.js";
5
5
  import {
6
6
  useMutationRunner,
7
7
  usePageLiveActivity
@@ -2448,4 +2448,4 @@ export {
2448
2448
  EnrollmentDeviceFlow,
2449
2449
  EnrollmentConsent
2450
2450
  };
2451
- //# sourceMappingURL=chunk-LWNLETQT.js.map
2451
+ //# sourceMappingURL=chunk-XA6R7DJQ.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  shouldSteerOnKey,
3
3
  shouldSubmitOnKey
4
- } from "./chunk-5KYZIQFY.js";
4
+ } from "./chunk-DV2DBNPQ.js";
5
5
  import {
6
6
  Tooltip,
7
7
  TooltipContent,
@@ -19,7 +19,7 @@ import {
19
19
  composerSubmissionErrorMessage,
20
20
  formatBytes,
21
21
  formatRelativeTime
22
- } from "./chunk-3IJJEYW4.js";
22
+ } from "./chunk-UJRYEWZI.js";
23
23
  import {
24
24
  cn
25
25
  } from "./chunk-22KP6LR5.js";
@@ -4691,4 +4691,4 @@ export {
4691
4691
  useVoiceInput,
4692
4692
  ComposerTranscriptionControl
4693
4693
  };
4694
- //# sourceMappingURL=chunk-2VFNCX4E.js.map
4694
+ //# sourceMappingURL=chunk-YRYF2GLG.js.map
@@ -2,7 +2,7 @@ import {
2
2
  buildTimeline,
3
3
  groupTimeline,
4
4
  sessionStatusFromEvents
5
- } from "./chunk-ZXSEDZP7.js";
5
+ } from "./chunk-KGENSZKS.js";
6
6
  import {
7
7
  useDebouncedCallback,
8
8
  useMutationRunner,
@@ -830,7 +830,7 @@ function useSessionEvents(sessionId, options = {}) {
830
830
  let generation = navigationGenerationRef.current;
831
831
  const current = () => ownsNavigation() && generation === navigationGenerationRef.current;
832
832
  try {
833
- const { resolveLatestQuestion } = await import("./latest-question-IS445HOW.js");
833
+ const { resolveLatestQuestion } = await import("./latest-question-3BJGKQQ6.js");
834
834
  if (!current()) return null;
835
835
  const destination = await resolveLatestQuestion({
836
836
  client,
@@ -2309,4 +2309,4 @@ export {
2309
2309
  projectPendingApprovals,
2310
2310
  conversationTimeline
2311
2311
  };
2312
- //# sourceMappingURL=chunk-M7LBYP63.js.map
2312
+ //# sourceMappingURL=chunk-Z3DISEQN.js.map
package/dist/composer.js CHANGED
@@ -40,8 +40,8 @@ import {
40
40
  useChatComposer,
41
41
  useChatComposerController,
42
42
  useVoiceInput
43
- } from "./chunk-2VFNCX4E.js";
44
- import "./chunk-5KYZIQFY.js";
43
+ } from "./chunk-YRYF2GLG.js";
44
+ import "./chunk-DV2DBNPQ.js";
45
45
  import "./chunk-BRM6FVZA.js";
46
46
  import {
47
47
  BillingClassMark,
@@ -54,7 +54,7 @@ import {
54
54
  import "./chunk-K3HQAKQX.js";
55
55
  import "./chunk-CHPKSLPN.js";
56
56
  import "./chunk-VZTQ73XT.js";
57
- import "./chunk-3IJJEYW4.js";
57
+ import "./chunk-UJRYEWZI.js";
58
58
  import "./chunk-KZ73RL76.js";
59
59
  import "./chunk-NEXLLTP4.js";
60
60
  import "./chunk-22KP6LR5.js";
package/dist/connect.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-45GE35O7.js";
7
7
  import {
8
8
  Markdown
9
- } from "./chunk-AFLPWUQ7.js";
9
+ } from "./chunk-BI57CQUV.js";
10
10
  import "./chunk-GIMRELBW.js";
11
11
  import "./chunk-447JLCBU.js";
12
12
  import "./chunk-XCHWDJ22.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-JVYQRRC4.js";
16
16
  import "./chunk-BRM6FVZA.js";
17
17
  import "./chunk-VZTQ73XT.js";
18
- import "./chunk-3IJJEYW4.js";
18
+ import "./chunk-UJRYEWZI.js";
19
19
  import "./chunk-22KP6LR5.js";
20
20
 
21
21
  // src/capability-catalog-row.tsx
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  healthPulses,
49
49
  pointsFor,
50
50
  useMachines
51
- } from "./chunk-LWNLETQT.js";
51
+ } from "./chunk-XA6R7DJQ.js";
52
52
  import {
53
53
  ActivityRail,
54
54
  ApprovalSurface,
@@ -107,7 +107,7 @@ import {
107
107
  useWorkspaceSessions,
108
108
  userMessageLikelyNeedsDisclosure,
109
109
  v4aToGitFileDiff
110
- } from "./chunk-FNWQBQOK.js";
110
+ } from "./chunk-55JRUWOA.js";
111
111
  import {
112
112
  useThemeType
113
113
  } from "./chunk-UK4TINKT.js";
@@ -140,14 +140,14 @@ import {
140
140
  useSessionControl,
141
141
  useSessionEvents,
142
142
  useTurnQueue
143
- } from "./chunk-M7LBYP63.js";
143
+ } from "./chunk-Z3DISEQN.js";
144
144
  import {
145
145
  buildTimeline,
146
146
  creditExhaustedFromEvents,
147
147
  extractSessionRef,
148
148
  groupTimeline,
149
149
  sessionStatusFromEvents
150
- } from "./chunk-ZXSEDZP7.js";
150
+ } from "./chunk-KGENSZKS.js";
151
151
  import {
152
152
  toolDisplayName
153
153
  } from "./chunk-ERGYJIBB.js";
@@ -177,7 +177,7 @@ import {
177
177
  retainedImageId,
178
178
  sandboxFileLocationFromHref,
179
179
  sandboxFilePathFromHref
180
- } from "./chunk-AFLPWUQ7.js";
180
+ } from "./chunk-BI57CQUV.js";
181
181
  import "./chunk-GIMRELBW.js";
182
182
  import "./chunk-447JLCBU.js";
183
183
  import {
@@ -235,14 +235,14 @@ import {
235
235
  useSlashCommands,
236
236
  useTranscription,
237
237
  useVoiceInput
238
- } from "./chunk-2VFNCX4E.js";
238
+ } from "./chunk-YRYF2GLG.js";
239
239
  import {
240
240
  FILE_ONLY_MESSAGE_TEXT,
241
241
  composeSendInput,
242
242
  shouldSteerOnKey,
243
243
  shouldSubmitOnKey,
244
244
  useComposer
245
- } from "./chunk-5KYZIQFY.js";
245
+ } from "./chunk-DV2DBNPQ.js";
246
246
  import {
247
247
  LightboxProvider,
248
248
  Tooltip,
@@ -296,7 +296,7 @@ import {
296
296
  stringifyPayload,
297
297
  truncate,
298
298
  tryParseJson
299
- } from "./chunk-3IJJEYW4.js";
299
+ } from "./chunk-UJRYEWZI.js";
300
300
  import {
301
301
  SandboxTerminal,
302
302
  terminalCanAcquirePty,
@@ -3756,7 +3756,7 @@ function FilesTabBody(props) {
3756
3756
  return /* @__PURE__ */ jsx6(Suspense, { fallback: /* @__PURE__ */ jsx6(WorkbenchSurfaceLoading, { name: "Files" }), children: /* @__PURE__ */ jsx6(LazySandboxFiles, { ...props }) });
3757
3757
  }
3758
3758
  var LazyBrowserViewer = lazy(async () => {
3759
- const { BrowserViewer } = await import("./browser-viewer-Z7S7QEJL.js");
3759
+ const { BrowserViewer } = await import("./browser-viewer-5X47I6T2.js");
3760
3760
  return { default: BrowserViewer };
3761
3761
  });
3762
3762
  var LazyComputerViewer = lazy(async () => {
@@ -7,7 +7,7 @@ import {
7
7
  useBrowserSession,
8
8
  useBrowserSessions,
9
9
  useSiteAuthConnections
10
- } from "./chunk-BDKR6BAR.js";
10
+ } from "./chunk-FGBCYQOT.js";
11
11
  import {
12
12
  ComputerViewer,
13
13
  useComputerFrameStream,
@@ -21,7 +21,7 @@ import {
21
21
  import "./chunk-JVYQRRC4.js";
22
22
  import "./chunk-DYWBUX5Q.js";
23
23
  import "./chunk-RHREZ7BO.js";
24
- import "./chunk-3IJJEYW4.js";
24
+ import "./chunk-UJRYEWZI.js";
25
25
  import "./chunk-5J4FOW6Q.js";
26
26
  import "./chunk-KZ73RL76.js";
27
27
  import {
@@ -2,9 +2,9 @@ import {
2
2
  isTimelineUserQuestion,
3
3
  isTurnExecutionEvidence,
4
4
  timelineQuestionPlacement
5
- } from "./chunk-ZXSEDZP7.js";
5
+ } from "./chunk-KGENSZKS.js";
6
6
  import "./chunk-ERGYJIBB.js";
7
- import "./chunk-3IJJEYW4.js";
7
+ import "./chunk-UJRYEWZI.js";
8
8
 
9
9
  // src/hooks/latest-question.ts
10
10
  import { SESSION_EVENT_TYPES } from "@opengeni/sdk";
@@ -114,4 +114,4 @@ export {
114
114
  TIMELINE_TURN_ANCHOR_EVENT_TYPES,
115
115
  resolveLatestQuestion
116
116
  };
117
- //# sourceMappingURL=latest-question-IS445HOW.js.map
117
+ //# sourceMappingURL=latest-question-3BJGKQQ6.js.map
package/dist/machines.js CHANGED
@@ -28,9 +28,9 @@ import {
28
28
  healthPulses,
29
29
  pointsFor,
30
30
  useMachines
31
- } from "./chunk-LWNLETQT.js";
31
+ } from "./chunk-XA6R7DJQ.js";
32
32
  import "./chunk-WZ55DVGK.js";
33
- import "./chunk-3IJJEYW4.js";
33
+ import "./chunk-UJRYEWZI.js";
34
34
  import "./chunk-KZ73RL76.js";
35
35
  import "./chunk-NEXLLTP4.js";
36
36
  import "./chunk-22KP6LR5.js";
@@ -24,7 +24,7 @@ import {
24
24
  setStartupDetails,
25
25
  useStartupDetails,
26
26
  userMessageLikelyNeedsDisclosure
27
- } from "./chunk-FNWQBQOK.js";
27
+ } from "./chunk-55JRUWOA.js";
28
28
  import "./chunk-UK4TINKT.js";
29
29
  import "./chunk-YCGBREUV.js";
30
30
  import "./chunk-5QHL6BLH.js";
@@ -36,13 +36,13 @@ import {
36
36
  } from "./chunk-5CVXZA3Y.js";
37
37
  import {
38
38
  createOlderHistoryLoadReceipt
39
- } from "./chunk-M7LBYP63.js";
40
- import "./chunk-ZXSEDZP7.js";
39
+ } from "./chunk-Z3DISEQN.js";
40
+ import "./chunk-KGENSZKS.js";
41
41
  import "./chunk-ERGYJIBB.js";
42
42
  import {
43
43
  OpenGeniProvider
44
44
  } from "./chunk-WZ55DVGK.js";
45
- import "./chunk-AFLPWUQ7.js";
45
+ import "./chunk-BI57CQUV.js";
46
46
  import "./chunk-GIMRELBW.js";
47
47
  import "./chunk-447JLCBU.js";
48
48
  import {
@@ -54,14 +54,14 @@ import {
54
54
  } from "./chunk-XCHWDJ22.js";
55
55
  import "./chunk-A2PI6UMY.js";
56
56
  import "./chunk-JVYQRRC4.js";
57
- import "./chunk-2VFNCX4E.js";
58
- import "./chunk-5KYZIQFY.js";
57
+ import "./chunk-YRYF2GLG.js";
58
+ import "./chunk-DV2DBNPQ.js";
59
59
  import "./chunk-BRM6FVZA.js";
60
60
  import "./chunk-UINDK6C3.js";
61
61
  import "./chunk-K3HQAKQX.js";
62
62
  import "./chunk-CHPKSLPN.js";
63
63
  import "./chunk-VZTQ73XT.js";
64
- import "./chunk-3IJJEYW4.js";
64
+ import "./chunk-UJRYEWZI.js";
65
65
  import "./chunk-B3V6TG77.js";
66
66
  import "./chunk-KZ73RL76.js";
67
67
  import "./chunk-NEXLLTP4.js";
package/dist/session.js CHANGED
@@ -23,14 +23,14 @@ import {
23
23
  useSessionControl,
24
24
  useSessionEvents,
25
25
  useTurnQueue
26
- } from "./chunk-M7LBYP63.js";
26
+ } from "./chunk-Z3DISEQN.js";
27
27
  import {
28
28
  buildTimeline,
29
29
  creditExhaustedFromEvents,
30
30
  extractSessionRef,
31
31
  groupTimeline,
32
32
  sessionStatusFromEvents
33
- } from "./chunk-ZXSEDZP7.js";
33
+ } from "./chunk-KGENSZKS.js";
34
34
  import {
35
35
  toolDisplayName
36
36
  } from "./chunk-ERGYJIBB.js";
@@ -40,8 +40,8 @@ import {
40
40
  shouldSteerOnKey,
41
41
  shouldSubmitOnKey,
42
42
  useComposer
43
- } from "./chunk-5KYZIQFY.js";
44
- import "./chunk-3IJJEYW4.js";
43
+ } from "./chunk-DV2DBNPQ.js";
44
+ import "./chunk-UJRYEWZI.js";
45
45
  import "./chunk-KZ73RL76.js";
46
46
  import "./chunk-NEXLLTP4.js";
47
47
  export {
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode } from "react";
2
2
  export type GenieLoadingRenderProps = {
3
3
  startedAt: string;
4
+ phase: "preparing" | "waiting";
4
5
  detailsOpen: boolean;
5
6
  onShowDetails: () => void;
6
7
  };
@@ -25,8 +26,9 @@ export type GenieLoadingOptions = {
25
26
  };
26
27
  export declare const GenieLoadingOptionsContext: import("react").Context<GenieLoadingOptions | undefined>;
27
28
  /** Decorative copy never substitutes for a failure or claims measurable progress. */
28
- export declare function GenieLoading({ startedAt, onShowDetails, detailsOpen, }: {
29
+ export declare function GenieLoading({ startedAt, phase, onShowDetails, detailsOpen, }: {
29
30
  startedAt: string;
31
+ phase?: GenieLoadingRenderProps["phase"];
30
32
  onShowDetails: () => void;
31
33
  detailsOpen?: boolean;
32
34
  }): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/react",
3
- "version": "7.5.0",
3
+ "version": "7.6.0-canary.36935312914001",
4
4
  "description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -153,8 +153,8 @@
153
153
  "@dnd-kit/utilities": "3.2.2",
154
154
  "@fontsource-variable/noto-sans-arabic": "5.2.10",
155
155
  "@fontsource-variable/noto-sans-jp": "5.2.10",
156
- "@opengeni/connect": "^0.3.1",
157
- "@opengeni/sdk": "^7.5.0",
156
+ "@opengeni/connect": "^0.3.1-canary.36935312914001",
157
+ "@opengeni/sdk": "^7.6.0-canary.36935312914001",
158
158
  "clsx": "^2.1.1",
159
159
  "dequal": "2.0.3",
160
160
  "lucide-react": "^1.8.0",
package/src/lib/format.ts CHANGED
@@ -218,6 +218,18 @@ export function presentFailure(payload: Record<string, unknown>): {
218
218
  reason: string | null;
219
219
  safetyRefusal: boolean;
220
220
  } {
221
+ const databaseFailure =
222
+ payload.code === "db_deadlock" ||
223
+ payload.code === "db_serialization_failure" ||
224
+ payload.code === "db_failure" ||
225
+ (typeof payload.sqlState === "string" &&
226
+ /^[0-9A-Z]{5}$/.test(payload.sqlState) &&
227
+ payload.database !== null &&
228
+ typeof payload.database === "object" &&
229
+ !Array.isArray(payload.database));
230
+ if (databaseFailure) {
231
+ return { reason: "OpenGeni encountered a database error.", safetyRefusal: false };
232
+ }
221
233
  const text = (key: string): string | null => {
222
234
  const value = payload[key];
223
235
  return typeof value === "string" && value.trim() ? value : null;
@@ -105,7 +105,8 @@ export function ActivityRail({
105
105
  const providerResponded = phases.some(
106
106
  (item) => item.phase === "provider_first_byte" && item.status === "complete",
107
107
  );
108
- const preparing =
108
+ const responsePending = phases.some((item) => item.phase === "provider_first_byte");
109
+ const loading =
109
110
  !hasWork &&
110
111
  !interrupted &&
111
112
  (startupActive ?? (!providerResponded && phases.some((item) => item.status === "running")));
@@ -164,7 +165,7 @@ export function ActivityRail({
164
165
  )}
165
166
  >
166
167
  <AnimatePresence initial={false}>
167
- {preparing && !debug ? (
168
+ {loading && !debug ? (
168
169
  <motion.div
169
170
  key="startup"
170
171
  initial={{ opacity: 0 }}
@@ -182,13 +183,14 @@ export function ActivityRail({
182
183
  >
183
184
  <GenieLoading
184
185
  startedAt={startedAt}
186
+ phase={responsePending ? "waiting" : "preparing"}
185
187
  detailsOpen={detailsOpen}
186
188
  onShowDetails={() => setDetailsOpen((open) => !open)}
187
189
  />
188
190
  </motion.div>
189
191
  ) : null}
190
192
  </AnimatePresence>
191
- {detailsOpen && !debug && !preparing ? (
193
+ {detailsOpen && !debug && !loading ? (
192
194
  <button
193
195
  type="button"
194
196
  className="og-genie-details self-start"
@@ -4,6 +4,7 @@ import { createContext, useContext, useEffect, useState, type ReactNode } from "
4
4
 
5
5
  export type GenieLoadingRenderProps = {
6
6
  startedAt: string;
7
+ phase: "preparing" | "waiting";
7
8
  detailsOpen: boolean;
8
9
  onShowDetails: () => void;
9
10
  };
@@ -55,19 +56,23 @@ const PHRASES = [
55
56
  "Putting a wish into motion…",
56
57
  "A little hocus. A little pocus…",
57
58
  ];
59
+ const WAITING_PHRASES = ["Waiting for a response…"];
58
60
 
59
61
  /** Decorative copy never substitutes for a failure or claims measurable progress. */
60
62
  export function GenieLoading({
61
63
  startedAt,
64
+ phase = "preparing",
62
65
  onShowDetails,
63
66
  detailsOpen = false,
64
67
  }: {
65
68
  startedAt: string;
69
+ phase?: GenieLoadingRenderProps["phase"];
66
70
  onShowDetails: () => void;
67
71
  detailsOpen?: boolean;
68
72
  }) {
69
73
  const options = useContext(GenieLoadingOptionsContext);
70
- const phrases = options?.phrases?.length ? options.phrases : PHRASES;
74
+ const waiting = phase === "waiting";
75
+ const phrases = options?.phrases?.length ? options.phrases : waiting ? WAITING_PHRASES : PHRASES;
71
76
  const theme = useThemeType(undefined);
72
77
  const [phrase, setPhrase] = useState(0);
73
78
  const [showDetails, setShowDetails] = useState(false);
@@ -82,7 +87,7 @@ export function GenieLoading({
82
87
  const timer = window.setInterval(update, 5_000);
83
88
  return () => window.clearInterval(timer);
84
89
  }, [startedAt, phrases]);
85
- if (options?.render) return options.render({ startedAt, detailsOpen, onShowDetails });
90
+ if (options?.render) return options.render({ startedAt, phase, detailsOpen, onShowDetails });
86
91
  return (
87
92
  <div className="og-genie-loading">
88
93
  <div
@@ -99,12 +104,17 @@ export function GenieLoading({
99
104
  <div className="og-genie-copy">
100
105
  <span className="sr-only" role="status">
101
106
  {slow
102
- ? (options?.messages?.slowStatus ?? "Preparing your task. Taking longer than usual.")
103
- : (options?.messages?.status ?? "Preparing your task.")}
107
+ ? (options?.messages?.slowStatus ??
108
+ (waiting
109
+ ? "Waiting for a response. Taking longer than usual."
110
+ : "Preparing your task. Taking longer than usual."))
111
+ : (options?.messages?.status ??
112
+ (waiting ? "Waiting for a response." : "Preparing your task."))}
104
113
  </span>
105
114
  <span key={slow ? "slow" : phrase} className="og-genie-phrase" aria-hidden="true">
106
115
  {slow
107
- ? (options?.messages?.slowText ?? "A little longer than usual…")
116
+ ? (options?.messages?.slowText ??
117
+ (waiting ? "Still waiting for a response…" : "A little longer than usual…"))
108
118
  : phrases[phrase % phrases.length]}
109
119
  </span>
110
120
  {showDetails || detailsOpen ? (
@@ -116,7 +126,7 @@ export function GenieLoading({
116
126
  >
117
127
  {detailsOpen
118
128
  ? (options?.messages?.hideDetails ?? "Hide details")
119
- : (options?.messages?.showDetails ?? "Behind the magic")}
129
+ : (options?.messages?.showDetails ?? (waiting ? "Show details" : "Behind the magic"))}
120
130
  <span aria-hidden="true"> ↗</span>
121
131
  </button>
122
132
  ) : null}