@opengeni/react 7.6.1 → 7.7.0-canary.37090756480001

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 (142) hide show
  1. package/README.md +19 -2
  2. package/dist/{browser-viewer-5X47I6T2.js → browser-viewer-63TXMINB.js} +6 -5
  3. package/dist/{chunk-UINDK6C3.js → chunk-2QUSQVF2.js} +3 -3
  4. package/dist/{chunk-CHPKSLPN.js → chunk-6ZSWSH4I.js} +3 -1
  5. package/dist/chunk-6ZSWSH4I.js.map +1 -0
  6. package/dist/{chunk-KGENSZKS.js → chunk-AAG4R3QN.js} +4 -3
  7. package/dist/chunk-AAG4R3QN.js.map +1 -0
  8. package/dist/{chunk-Z3DISEQN.js → chunk-CWWKTNKK.js} +35 -18
  9. package/dist/chunk-CWWKTNKK.js.map +1 -0
  10. package/dist/{chunk-5EXGU7UF.js → chunk-DOJWJQ3F.js} +3 -3
  11. package/dist/{chunk-WZ55DVGK.js → chunk-ELCE5SXV.js} +8 -4
  12. package/dist/chunk-ELCE5SXV.js.map +1 -0
  13. package/dist/{chunk-YSMMDOOE.js → chunk-GISEVGS6.js} +10 -2
  14. package/dist/chunk-GISEVGS6.js.map +1 -0
  15. package/dist/{chunk-YRYF2GLG.js → chunk-HNFCAQ5R.js} +39 -31
  16. package/dist/chunk-HNFCAQ5R.js.map +1 -0
  17. package/dist/{chunk-BI57CQUV.js → chunk-I7IWRQLN.js} +2 -2
  18. package/dist/{chunk-XA6R7DJQ.js → chunk-IQUCRAT7.js} +3 -3
  19. package/dist/{chunk-DV2DBNPQ.js → chunk-Q5QBEZIQ.js} +48 -29
  20. package/dist/chunk-Q5QBEZIQ.js.map +1 -0
  21. package/dist/{chunk-FGBCYQOT.js → chunk-RDKBXMWX.js} +120 -74
  22. package/dist/chunk-RDKBXMWX.js.map +1 -0
  23. package/dist/{chunk-45GE35O7.js → chunk-TKB4SB44.js} +10 -2
  24. package/dist/chunk-TKB4SB44.js.map +1 -0
  25. package/dist/{chunk-YCGBREUV.js → chunk-TOAH2BKA.js} +6 -2
  26. package/dist/{chunk-YCGBREUV.js.map → chunk-TOAH2BKA.js.map} +1 -1
  27. package/dist/chunk-UGLEYEMP.js +33 -0
  28. package/dist/chunk-UGLEYEMP.js.map +1 -0
  29. package/dist/{chunk-UJRYEWZI.js → chunk-UTRTG6LH.js} +48 -8
  30. package/dist/chunk-UTRTG6LH.js.map +1 -0
  31. package/dist/{chunk-VGIKFIO2.js → chunk-XOAMRDDK.js} +6 -3
  32. package/dist/chunk-XOAMRDDK.js.map +1 -0
  33. package/dist/{chunk-6NEZPF53.js → chunk-YN7I3STW.js} +153 -32
  34. package/dist/chunk-YN7I3STW.js.map +1 -0
  35. package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
  36. package/dist/chunk-YQEAA6LT.js.map +1 -0
  37. package/dist/{chunk-LZ3KHA55.js → chunk-ZYALTAEQ.js} +329 -339
  38. package/dist/chunk-ZYALTAEQ.js.map +1 -0
  39. package/dist/client.d.ts +4 -1
  40. package/dist/commands/types.d.ts +2 -0
  41. package/dist/components/approval-surface.d.ts +15 -0
  42. package/dist/composer.js +8 -7
  43. package/dist/{computer-viewer-7GF35SNY.js → computer-viewer-X2MBRZY4.js} +5 -4
  44. package/dist/connect.js +3 -3
  45. package/dist/hooks/use-browser-session.d.ts +4 -0
  46. package/dist/hooks/use-composer.d.ts +2 -0
  47. package/dist/hooks/use-computer-session.d.ts +2 -0
  48. package/dist/hooks/use-file-attachments.d.ts +2 -0
  49. package/dist/hooks/use-session-events.d.ts +1 -1
  50. package/dist/hooks/use-workspace-sessions.d.ts +15 -5
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.js +28 -21
  53. package/dist/index.js.map +1 -1
  54. package/dist/interaction.d.ts +1 -1
  55. package/dist/interaction.js +6 -5
  56. package/dist/interaction.js.map +1 -1
  57. package/dist/{latest-question-3BJGKQQ6.js → latest-question-CNEZ5KAN.js} +3 -3
  58. package/dist/lib/error-message.d.ts +7 -0
  59. package/dist/lib/format.d.ts +27 -3
  60. package/dist/lib/interaction-errors.d.ts +3 -0
  61. package/dist/machines.js +5 -4
  62. package/dist/{model-policy-picker-menu-PUTA5JOB.js → model-policy-picker-menu-JSA64TNN.js} +4 -4
  63. package/dist/model-policy.js +1 -1
  64. package/dist/provider.d.ts +5 -1
  65. package/dist/{queue-surface-implementation-2CAQAIHM.js → queue-surface-implementation-HENWYFWA.js} +3 -2
  66. package/dist/{queue-surface-implementation-2CAQAIHM.js.map → queue-surface-implementation-HENWYFWA.js.map} +1 -1
  67. package/dist/realtime.js +2 -2
  68. package/dist/{sandbox-files-AEJTWGT4.js → sandbox-files-BBC47SLD.js} +4 -3
  69. package/dist/session-ui.d.ts +1 -1
  70. package/dist/session-ui.js +13 -12
  71. package/dist/session-ui.js.map +1 -1
  72. package/dist/session.js +7 -6
  73. package/dist/usage.js +2 -1
  74. package/dist/usage.js.map +1 -1
  75. package/package.json +3 -3
  76. package/src/client.ts +5 -1
  77. package/src/commands/registry.ts +18 -15
  78. package/src/commands/types.ts +2 -0
  79. package/src/components/approval-surface.tsx +166 -42
  80. package/src/components/browser-viewer.tsx +38 -9
  81. package/src/components/composer.tsx +9 -2
  82. package/src/components/computer-viewer.tsx +160 -30
  83. package/src/components/generated-video-player.tsx +4 -2
  84. package/src/components/human-input-form.tsx +18 -5
  85. package/src/components/message-timeline.tsx +120 -168
  86. package/src/components/open-geni-chat.tsx +11 -4
  87. package/src/components/queue-surface-state.tsx +3 -1
  88. package/src/components/session-chrome.tsx +5 -2
  89. package/src/components/session-commands-panel.tsx +3 -1
  90. package/src/components/session-conversation.tsx +4 -2
  91. package/src/components/session-list.tsx +7 -5
  92. package/src/components/session-mcp-capability-card.tsx +11 -1
  93. package/src/hooks/internal.ts +3 -2
  94. package/src/hooks/use-browser-session.ts +115 -79
  95. package/src/hooks/use-composer.ts +70 -31
  96. package/src/hooks/use-computer-session.ts +57 -6
  97. package/src/hooks/use-file-attachments.ts +16 -3
  98. package/src/hooks/use-goal.ts +2 -1
  99. package/src/hooks/use-session-capabilities.ts +3 -2
  100. package/src/hooks/use-session-events.ts +15 -8
  101. package/src/hooks/use-slash-commands.ts +6 -11
  102. package/src/hooks/use-turn-queue.ts +2 -1
  103. package/src/hooks/use-workspace-sessions.ts +40 -7
  104. package/src/index.ts +7 -2
  105. package/src/interaction.ts +1 -0
  106. package/src/lib/error-message.ts +37 -0
  107. package/src/lib/format.ts +73 -9
  108. package/src/lib/interaction-errors.ts +15 -0
  109. package/src/model-policy.ts +5 -0
  110. package/src/provider.tsx +12 -4
  111. package/src/session-ui.ts +1 -1
  112. package/src/timeline/projection.ts +12 -1
  113. package/styles/compiled.css +14 -30
  114. package/dist/chunk-45GE35O7.js.map +0 -1
  115. package/dist/chunk-6NEZPF53.js.map +0 -1
  116. package/dist/chunk-CHPKSLPN.js.map +0 -1
  117. package/dist/chunk-DV2DBNPQ.js.map +0 -1
  118. package/dist/chunk-FGBCYQOT.js.map +0 -1
  119. package/dist/chunk-KGENSZKS.js.map +0 -1
  120. package/dist/chunk-KZ73RL76.js.map +0 -1
  121. package/dist/chunk-LZ3KHA55.js.map +0 -1
  122. package/dist/chunk-UJRYEWZI.js.map +0 -1
  123. package/dist/chunk-VGIKFIO2.js.map +0 -1
  124. package/dist/chunk-WZ55DVGK.js.map +0 -1
  125. package/dist/chunk-YRYF2GLG.js.map +0 -1
  126. package/dist/chunk-YSMMDOOE.js.map +0 -1
  127. package/dist/chunk-Z3DISEQN.js.map +0 -1
  128. package/dist/components/timeline-pill-geometry.d.ts +0 -8
  129. package/dist/components/timeline-pill-placement.d.ts +0 -24
  130. package/dist/timeline-pill-geometry-Z23V243M.js +0 -110
  131. package/dist/timeline-pill-geometry-Z23V243M.js.map +0 -1
  132. package/src/components/timeline-pill-geometry.ts +0 -169
  133. package/src/components/timeline-pill-placement.ts +0 -99
  134. /package/dist/{browser-viewer-5X47I6T2.js.map → browser-viewer-63TXMINB.js.map} +0 -0
  135. /package/dist/{chunk-UINDK6C3.js.map → chunk-2QUSQVF2.js.map} +0 -0
  136. /package/dist/{chunk-5EXGU7UF.js.map → chunk-DOJWJQ3F.js.map} +0 -0
  137. /package/dist/{chunk-BI57CQUV.js.map → chunk-I7IWRQLN.js.map} +0 -0
  138. /package/dist/{chunk-XA6R7DJQ.js.map → chunk-IQUCRAT7.js.map} +0 -0
  139. /package/dist/{computer-viewer-7GF35SNY.js.map → computer-viewer-X2MBRZY4.js.map} +0 -0
  140. /package/dist/{latest-question-3BJGKQQ6.js.map → latest-question-CNEZ5KAN.js.map} +0 -0
  141. /package/dist/{model-policy-picker-menu-PUTA5JOB.js.map → model-policy-picker-menu-JSA64TNN.js.map} +0 -0
  142. /package/dist/{sandbox-files-AEJTWGT4.js.map → sandbox-files-BBC47SLD.js.map} +0 -0
@@ -1 +0,0 @@
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 +0,0 @@
1
- {"version":3,"sources":["../src/embedded-session-client.ts","../src/hooks/use-goal.ts","../src/hooks/use-session-mcp-approval-policy.ts","../src/hooks/use-session-lineage.ts"],"sourcesContent":["import type { ComposerDraft } from \"@opengeni/sdk\";\nimport type { EmbeddedSessionClientLike } from \"./client\";\n\nexport type ComposerDraftMapContext = {\n operation: \"read\" | \"save\" | \"submit\";\n workspaceId: string;\n sessionId: string;\n};\n\nexport type CreateEmbeddedSessionClientOptions = {\n /**\n * Explicit host-owned method replacements. Methods inherited from `base`\n * retain `base` as their receiver; overrides retain this object as theirs.\n */\n overrides?: Partial<EmbeddedSessionClientLike> | undefined;\n /** Presentation/policy projection for every draft entering the React layer. */\n mapComposerDraft?:\n | ((draft: ComposerDraft, context: ComposerDraftMapContext) => ComposerDraft)\n | undefined;\n};\n\nconst requiredMethods = [\n \"getSession\",\n \"listEvents\",\n \"streamEvents\",\n \"getComposerDraft\",\n \"saveComposerDraft\",\n \"submitComposerDraft\",\n \"sendMessage\",\n \"steerMessage\",\n \"getQueue\",\n \"moveQueueItem\",\n \"editQueueItem\",\n \"steerQueueItem\",\n \"deleteQueueItem\",\n \"pauseSession\",\n \"resumeSession\",\n \"sendApprovalDecision\",\n] as const satisfies readonly (keyof EmbeddedSessionClientLike)[];\n\n/**\n * Build the exact client required by `@opengeni/react/session` from a full SDK\n * client or host proxy. The constructor binds every delegated method once,\n * supports a host-owned atomic composer-submit override, and fails at creation\n * time instead of waiting for a missing method to be exercised by a hook.\n */\nexport function createEmbeddedSessionClient(\n base: EmbeddedSessionClientLike,\n options: CreateEmbeddedSessionClientOptions = {},\n): EmbeddedSessionClientLike {\n const overrides = options.overrides ?? {};\n const client = {} as EmbeddedSessionClientLike;\n for (const key of requiredMethods) {\n const override = overrides[key];\n const method = override ?? base[key];\n if (typeof method !== \"function\") {\n throw new TypeError(`Embedded session client method is required: ${key}`);\n }\n client[key] = method.bind(override === undefined ? base : overrides) as never;\n }\n\n const inferenceOverride = overrides.setWorkspaceInferenceState;\n const inferenceBase = base.setWorkspaceInferenceState;\n const inferenceMethod = inferenceOverride ?? inferenceBase;\n if (typeof inferenceMethod === \"function\") {\n client.setWorkspaceInferenceState = inferenceMethod.bind(\n inferenceOverride === undefined ? base : overrides,\n );\n }\n\n const mapDraft = options.mapComposerDraft;\n if (!mapDraft) return client;\n\n const getComposerDraft = client.getComposerDraft;\n client.getComposerDraft = async (workspaceId, sessionId) =>\n mapDraft(await getComposerDraft(workspaceId, sessionId), {\n operation: \"read\",\n workspaceId,\n sessionId,\n });\n\n const saveComposerDraft = client.saveComposerDraft;\n client.saveComposerDraft = async (workspaceId, sessionId, request) =>\n mapDraft(await saveComposerDraft(workspaceId, sessionId, request), {\n operation: \"save\",\n workspaceId,\n sessionId,\n });\n\n const submitComposerDraft = client.submitComposerDraft;\n client.submitComposerDraft = async (workspaceId, sessionId, request) => {\n const response = await submitComposerDraft(workspaceId, sessionId, request);\n return {\n ...response,\n draft: mapDraft(response.draft, {\n operation: \"submit\",\n workspaceId,\n sessionId,\n }),\n };\n };\n\n return client;\n}\n","import { OpenGeniApiError, type SessionEvent, type SessionGoal } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useEmbeddedGoal, type EmbeddedGoalClientOverride } from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePageLiveActivity,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Event types that change the session goal (set/updated/completed/paused/...). */\nexport function isGoalEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type.startsWith(\"goal.\");\n}\n\n/**\n * Events that can change the server-authoritative continuation projection.\n * The projection is derived from durable turn, session, control, and system\n * update state, so those events refresh the goal without model polling.\n */\nexport function isGoalRefreshEvent(event: Pick<SessionEvent, \"type\">): boolean {\n const type = event.type;\n return (\n isGoalEvent(event) ||\n type.startsWith(\"turn.\") ||\n type.startsWith(\"session.\") ||\n type.startsWith(\"system.update.\") ||\n type.startsWith(\"workspace.inference.\") ||\n type.startsWith(\"user.\")\n );\n}\n\nexport type UseGoalOptions = EmbeddedGoalClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default — event refreshes drive updates. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseGoalResult = {\n /** The session goal, or null when the session has none. */\n goal: SessionGoal | null;\n /** Convenience flags over `goal.status`. */\n isActive: boolean;\n isPaused: boolean;\n isCompleted: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n /** Pause the goal loop (PATCH status=paused). */\n pause: (rationale?: string) => Promise<SessionGoal | null>;\n /** Resume a paused goal: resets counters and re-arms continuations. */\n resume: () => Promise<SessionGoal | null>;\n /** Clear the session goal; goal-less sessions remain a successful no-op. */\n clearGoal: () => Promise<void>;\n /** Alias for `clearGoal`. */\n deleteGoal: () => Promise<void>;\n /** True while a pause/resume/clear is in flight. */\n updating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/**\n * The session's goal: state, the autonomy counters (`autoContinuations`,\n * `noProgressStreak`), and pause/resume control. A goal-less session yields\n * `goal: null` (the 404 is absorbed). Live-updates on goal, turn, session,\n * control, and system-update events — pass `options.events` from\n * `useSessionEvents` to reuse its stream.\n */\nexport function useGoal(\n sessionId: string | null | undefined,\n options: UseGoalOptions = {},\n): UseGoalResult {\n const { client, workspaceId } = useEmbeddedGoal(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const sharedEvents = options.events;\n const sharedFeed = sharedEvents !== undefined;\n const pageLive = usePageLiveActivity();\n const [goal, setGoal] = useState<SessionGoal | null>(null);\n const [loading, setLoading] = useState(enabled);\n const [error, setError] = useState<Error | null>(null);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner();\n const generation = useRef(0);\n const targetKeyRef = useRef<string | null>(null);\n const loadAbort = useRef<AbortController | null>(null);\n\n const retireLoads = useCallback(() => {\n generation.current += 1;\n loadAbort.current?.abort();\n loadAbort.current = null;\n }, []);\n\n const load = useCallback(async (): Promise<void> => {\n if (!sessionId) {\n return;\n }\n const ticket = ++generation.current;\n loadAbort.current?.abort();\n const controller = new AbortController();\n loadAbort.current = controller;\n try {\n const fetched = await client.getGoal(workspaceId, sessionId, {\n signal: controller.signal,\n });\n if (ticket === generation.current) {\n setGoal(fetched);\n setError(null);\n setLoading(false);\n }\n } catch (cause) {\n if (ticket !== generation.current) {\n return;\n }\n if (cause instanceof OpenGeniApiError && cause.status === 404) {\n // No goal is a normal state, not an error.\n setGoal(null);\n setError(null);\n } else {\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n setLoading(false);\n } finally {\n if (loadAbort.current === controller) loadAbort.current = null;\n }\n }, [client, workspaceId, sessionId]);\n\n useEffect(() => {\n const targetKey = `${workspaceId} ${sessionId ?? \"\"}`;\n if (targetKeyRef.current !== targetKey) {\n targetKeyRef.current = targetKey;\n setGoal(null);\n setError(null);\n }\n if (!enabled || !pageLive) {\n retireLoads();\n setLoading(false);\n return;\n }\n if (sharedFeed) {\n // A shared log supplies invalidations, not the authoritative goal snapshot.\n setLoading(true);\n void load();\n return () => {\n retireLoads();\n };\n }\n setLoading(true);\n const pollIntervalMs = options.pollIntervalMs;\n if (pollIntervalMs === undefined || pollIntervalMs <= 0) {\n void load();\n return () => {\n retireLoads();\n };\n }\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const schedule = () => {\n if (cancelled) return;\n timer = setTimeout(() => {\n timer = null;\n void load().finally(schedule);\n }, pollIntervalMs);\n };\n void load().finally(schedule);\n return () => {\n cancelled = true;\n if (timer !== null) clearTimeout(timer);\n retireLoads();\n };\n }, [\n load,\n enabled,\n pageLive,\n workspaceId,\n sessionId,\n options.pollIntervalMs,\n retireLoads,\n sharedFeed,\n ]);\n\n const scheduleRefresh = useDebouncedCallback(() => void load());\n useSessionEventTrigger(client, workspaceId, sessionId, isGoalRefreshEvent, scheduleRefresh, {\n enabled,\n ...(sharedEvents !== undefined ? { events: sharedEvents } : {}),\n });\n\n const pause = useCallback(\n async (rationale?: string): Promise<SessionGoal | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() =>\n client.updateGoal(workspaceId, sessionId, {\n status: \"paused\",\n ...(rationale !== undefined ? { rationale } : {}),\n }),\n );\n if (result) {\n setGoal(result);\n }\n return result;\n },\n [client, workspaceId, sessionId, run],\n );\n\n const resume = useCallback(async (): Promise<SessionGoal | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() => client.updateGoal(workspaceId, sessionId, { status: \"active\" }));\n if (result) {\n setGoal(result);\n }\n return result;\n }, [client, workspaceId, sessionId, run]);\n\n const clearGoal = useCallback(async (): Promise<void> => {\n if (!sessionId) {\n return;\n }\n // deleteGoal resolves void, so distinguish success (a truthy sentinel) from\n // mutation.run's null-on-failure. Only a SUCCESSFUL delete hides the goal:\n // a failed one leaves the pill up so its mutationError renders. And invalidate\n // any in-flight load first so a slower getGoal started before the delete can't\n // commit and repopulate the just-cleared goal.\n const ok = await run(async () => {\n await client.deleteGoal(workspaceId, sessionId);\n return true as const;\n });\n if (ok) {\n retireLoads();\n setGoal(null);\n setError(null);\n }\n }, [client, workspaceId, sessionId, run, retireLoads]);\n\n return {\n goal,\n isActive: goal?.status === \"active\",\n isPaused: goal?.status === \"paused\",\n isCompleted: goal?.status === \"completed\",\n loading,\n error,\n refresh: load,\n pause,\n resume,\n clearGoal,\n deleteGoal: clearGoal,\n updating: mutating,\n mutationError,\n clearMutationError,\n };\n}\n","import type {\n SessionEvent,\n SessionMcpApprovalPolicy,\n SessionMcpApprovalPolicyTarget,\n UpdateSessionMcpApprovalPolicyResponse,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useEmbeddedSessionMcpApprovalPolicy,\n type EmbeddedSessionMcpApprovalPolicyClientOverride,\n} from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport function isSessionMcpApprovalPolicyEvent(\n event: Pick<SessionEvent, \"type\" | \"payload\">,\n serverId?: string,\n): boolean {\n if (event.type !== \"session.mcp.approval_policy.updated\") {\n return false;\n }\n if (serverId === undefined) {\n return true;\n }\n const payload = event.payload as { serverId?: unknown } | null;\n return payload?.serverId === serverId;\n}\n\nexport type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolicyClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default; policy events drive refreshes. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseSessionMcpApprovalPolicyResult = {\n server: SessionMcpApprovalPolicyTarget | null;\n policy: SessionMcpApprovalPolicy | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n update: (\n policy: SessionMcpApprovalPolicy,\n ) => Promise<UpdateSessionMcpApprovalPolicyResponse | null>;\n updating: boolean;\n clearError: () => void;\n};\n\n/**\n * Read and update one existing session MCP server's approval policy. Updates\n * become effective for the next claimed attempt; current work is unchanged.\n */\nexport function useSessionMcpApprovalPolicy(\n sessionId: string | null | undefined,\n serverId: string | null | undefined,\n options: UseSessionMcpApprovalPolicyOptions = {},\n): UseSessionMcpApprovalPolicyResult {\n const { client, workspaceId } = useEmbeddedSessionMcpApprovalPolicy(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId && serverId);\n const [override, setOverride] = useState<SessionMcpApprovalPolicyTarget | null>(null);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${serverId ?? \"\"}`;\n const authoritativeGeneration = useRef(0);\n const mutationIdentity = useMemo(() => ({ client, targetKey }), [client, targetKey]);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner(mutationIdentity);\n\n useLayoutEffect(() => {\n authoritativeGeneration.current += 1;\n setOverride(null);\n }, [client, targetKey]);\n\n type PolicyRead = {\n targetKey: string;\n generation: number;\n server: SessionMcpApprovalPolicyTarget | null;\n };\n const load = useCallback(async (): Promise<PolicyRead> => {\n const generation = authoritativeGeneration.current;\n if (!sessionId || !serverId) {\n return { targetKey, generation, server: null };\n }\n const session = await client.getSession(workspaceId, sessionId);\n return {\n targetKey,\n generation,\n server:\n session.mcpServers.find((server) => server.id === serverId) ??\n (session.mcpApprovalPolicies && Object.hasOwn(session.mcpApprovalPolicies, serverId)\n ? {\n id: serverId,\n source: \"workspace\",\n requireApproval: session.mcpApprovalPolicies[serverId]!,\n }\n : null),\n };\n }, [client, serverId, sessionId, targetKey, workspaceId]);\n const {\n data,\n loading,\n error: loadError,\n refresh,\n } = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n useEffect(() => {\n if (data?.targetKey === targetKey && data.generation === authoritativeGeneration.current) {\n setOverride(null);\n }\n }, [data, targetKey]);\n\n const scheduleRefresh = useDebouncedCallback(() => void refresh());\n const matchesPolicyEvent = useCallback(\n (event: Pick<SessionEvent, \"type\" | \"payload\">) =>\n isSessionMcpApprovalPolicyEvent(event, serverId ?? undefined),\n [serverId],\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n matchesPolicyEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n async () => await refresh(),\n );\n\n const update = useCallback(\n async (\n policy: SessionMcpApprovalPolicy,\n ): Promise<UpdateSessionMcpApprovalPolicyResponse | null> => {\n if (!sessionId || !serverId) {\n return null;\n }\n const response = await run(() =>\n client.updateSessionMcpApprovalPolicy(workspaceId, sessionId, serverId, {\n requireApproval: policy,\n }),\n );\n if (response) {\n authoritativeGeneration.current += 1;\n setOverride(response.server);\n void refresh();\n }\n return response;\n },\n [client, refresh, run, serverId, sessionId, workspaceId],\n );\n\n const server = override ?? data?.server ?? null;\n return {\n server,\n policy: server?.requireApproval ?? null,\n loading,\n error: mutationError ?? loadError,\n refresh: async () => {\n await refresh();\n },\n update,\n updating: mutating,\n clearError: clearMutationError,\n };\n}\n","import type { SessionEvent, SessionLineageResponse } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n useEmbeddedSessionLineage,\n type EmbeddedSessionLineageClientOverride,\n} from \"../session-context\";\nimport { useDebouncedCallback, usePolledValue, useSessionEventTrigger } from \"./internal\";\n\nexport type UseSessionLineageOptions = EmbeddedSessionLineageClientOverride & {\n events?: SessionEvent[] | undefined;\n /** Refresh interval (ms). Off by default. */\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n};\n\nexport type UseSessionLineageResult = {\n lineage: SessionLineageResponse | null;\n loading: boolean;\n error: Error | null;\n /** Causal generation captured when the accepted lineage read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n};\n\nexport function isLineageRefreshEvent(event: SessionEvent): boolean {\n if (event.type === \"session.status.changed\" || event.type === \"session.created\") {\n return true;\n }\n // A child's creation never appears on the PARENT's stream as session.created —\n // the parent sees its own spawn as an agent.toolCall.* for session_create.\n // Created events are handled separately so they can refresh immediately and\n // once after the child row has had time to commit.\n if (event.type === \"agent.toolCall.output\") {\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n }\n return false;\n}\n\nfunction isSessionCreateToolCallCreated(event: SessionEvent): boolean {\n if (event.type !== \"agent.toolCall.created\") {\n return false;\n }\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n}\n\n/** Read the ancestors + descendant tree for one session. Data-only; no UI state. */\nexport function useSessionLineage(\n sessionId: string | null | undefined,\n options: UseSessionLineageOptions = {},\n): UseSessionLineageResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionLineage(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const load = useCallback(\n async (signal?: AbortSignal) => {\n if (!sessionId) {\n return {\n lineage: { ancestors: [], children: [], truncated: false },\n readGeneration: 0,\n };\n }\n let readGeneration = 0;\n const lineage = await client.getSessionLineage(workspaceId, sessionId, {\n signal,\n onRequestStart: (sharedReadGeneration) => {\n readGeneration = sharedReadGeneration ?? beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n return {\n lineage,\n readGeneration,\n };\n },\n [beginRead, client, workspaceId, sessionId],\n );\n const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });\n const refresh = state.refresh;\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"lineage\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n const refreshSoon = useDebouncedCallback(() => void refresh(), 150);\n const delayedChildRefreshRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Clear a pending delayed refresh on session/workspace SWITCH (not just\n // unmount): otherwise a timer scheduled for the previous session can fire\n // ~2.5s later and commit that session's lineage onto the new one.\n useEffect(() => {\n return () => {\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n delayedChildRefreshRef.current = null;\n }\n };\n }, [sessionId, workspaceId]);\n const refreshAfterChildCreate = useCallback(() => {\n void refresh();\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n }\n delayedChildRefreshRef.current = setTimeout(() => {\n delayedChildRefreshRef.current = null;\n void refresh();\n }, 2500);\n }, [refresh]);\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isLineageRefreshEvent,\n refreshSoon,\n // SHARED-FEED ONLY: without a caller-provided events log the trigger would\n // open its OWN streamEvents tail — a second live SSE connection next to the\n // session route's useSessionEvents. A caller with no feed opts into polling\n // (pollIntervalMs), never a duplicate stream.\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isSessionCreateToolCallCreated,\n refreshAfterChildCreate,\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n return {\n lineage: state.data?.lineage ?? null,\n loading: state.loading,\n error: state.error,\n readGeneration: state.data?.readGeneration ?? 0,\n refresh,\n };\n}\n"],"mappings":"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","names":["useCallback","useEffect","useRef","useState","useState","useRef","useCallback","server","useEffect","useCallback","useEffect","useRef","useRef","useCallback","useEffect"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["import {\n OpenGeniApiContractMismatchError,\n OPENGENI_API_CONTRACT_REVISION,\n type StreamConnectionState,\n type WorkspaceControlEvent,\n type WorkspaceInteractionRevisionEvent,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport type { SessionClientLike } from \"./client\";\nimport { usePageLiveActivity } from \"./hooks/internal\";\nimport { OpenGeniContext } from \"./session-context\";\n\nexport { useOpenGeni, useOpenGeniClient } from \"./session-context\";\nexport type { ClientOverride, OpenGeniContextValue } from \"./session-context\";\nconst CONTRACT_RELOAD_STORAGE_PREFIX = \"opengeni.reloadForApiContract:\";\n\nexport type OpenGeniProviderProps = {\n client: SessionClientLike;\n workspaceId: string;\n onWorkspaceControlEvent?: ((event: WorkspaceControlEvent) => void) | undefined;\n onWorkspaceInteractionEvent?: ((event: WorkspaceInteractionRevisionEvent) => void) | undefined;\n /**\n * Stale-tab protection for the stock OpenGeni web app: when the server's API\n * contract revision differs from this bundle's, cover the page and reload it\n * once. Off by default, because an embedded product's page must never be\n * blocked or reloaded when OpenGeni deploys; there a mismatch is ignored and\n * the SDK's tolerant-reader compatibility applies.\n */\n reloadOnApiContractChange?: boolean | undefined;\n children?: ReactNode;\n};\n\n/**\n * Supplies the OpenGeni client + workspace to all hooks below it. Hooks also\n * accept `{ client, workspaceId }` overrides per call for multi-workspace UIs.\n */\nexport function OpenGeniProvider({\n client,\n workspaceId,\n onWorkspaceControlEvent,\n onWorkspaceInteractionEvent,\n reloadOnApiContractChange = false,\n children,\n}: OpenGeniProviderProps) {\n const [workspaceControlEvent, setWorkspaceControlEvent] = useState<WorkspaceControlEvent | null>(\n null,\n );\n const [workspaceControlConnectionState, setWorkspaceControlConnectionState] = useState<\n StreamConnectionState | \"idle\" | \"error\"\n >(\"idle\");\n const [workspaceInteractionEvent, setWorkspaceInteractionEvent] =\n useState<WorkspaceInteractionRevisionEvent | null>(null);\n const [workspaceInteractionConnectionState, setWorkspaceInteractionConnectionState] = useState<\n StreamConnectionState | \"idle\" | \"error\"\n >(\"idle\");\n const [contractMismatch, setContractMismatch] = useState<OpenGeniApiContractMismatchError | null>(\n null,\n );\n const callbackRef = useRef(onWorkspaceControlEvent);\n const interactionCallbackRef = useRef(onWorkspaceInteractionEvent);\n const reconcilersRef = useRef(new Map<string, Map<string, () => Promise<void>>>());\n const reconcileInFlightRef = useRef(new Map<string, Promise<void>>());\n const workspaceControlSequencesRef = useRef(new Map<string, number>());\n const workspaceInteractionSequencesRef = useRef(new Map<string, number>());\n const pageLive = usePageLiveActivity();\n const supportsWorkspaceLiveStream =\n \"streamWorkspaceLiveEvents\" in client && typeof client.streamWorkspaceLiveEvents === \"function\";\n callbackRef.current = onWorkspaceControlEvent;\n interactionCallbackRef.current = onWorkspaceInteractionEvent;\n\n const strictContract = reloadOnApiContractChange;\n const verifyApiContract = useCallback(async (): Promise<void> => {\n try {\n const config = await client.getClientConfig();\n if (strictContract && config.apiContractRevision !== OPENGENI_API_CONTRACT_REVISION) {\n throw new OpenGeniApiContractMismatchError(\n OPENGENI_API_CONTRACT_REVISION,\n String(config.apiContractRevision || \"(missing)\"),\n );\n }\n } catch (error) {\n if (error instanceof OpenGeniApiContractMismatchError) {\n // Embedded hosts: a revision difference is not a reason to block or reload the page.\n if (!strictContract) return;\n setContractMismatch(error);\n reloadForContractMismatchOnce(error);\n }\n throw error;\n }\n }, [client, strictContract]);\n\n const registerSessionReconciler = useMemo(\n () =>\n (sessionId: string, key: string, reconcile: () => Promise<void>): (() => void) => {\n const sessionReconcilers = reconcilersRef.current.get(sessionId) ?? new Map();\n sessionReconcilers.set(key, reconcile);\n reconcilersRef.current.set(sessionId, sessionReconcilers);\n return () => {\n const current = reconcilersRef.current.get(sessionId);\n current?.delete(key);\n if (current?.size === 0) reconcilersRef.current.delete(sessionId);\n };\n },\n [],\n );\n const reconcileSession = useMemo(\n () =>\n (sessionId: string): Promise<void> => {\n const existing = reconcileInFlightRef.current.get(sessionId);\n if (existing) return existing;\n // This read also crosses the exact API-contract handshake before stale\n // state can be presented as live after a deployment.\n const promise = (async () => {\n await withTimeout(verifyApiContract(), 10_000, \"API contract reconciliation\");\n const callbacks = [...(reconcilersRef.current.get(sessionId)?.values() ?? [])];\n await withTimeout(\n Promise.all(callbacks.map((reconcile) => reconcile())).then(() => undefined),\n 15_000,\n \"session reconciliation\",\n );\n })().finally(() => {\n if (reconcileInFlightRef.current.get(sessionId) === promise) {\n reconcileInFlightRef.current.delete(sessionId);\n }\n });\n reconcileInFlightRef.current.set(sessionId, promise);\n return promise;\n },\n [verifyApiContract],\n );\n\n useEffect(() => {\n if (!supportsWorkspaceLiveStream) return;\n const openLiveStream = client.streamWorkspaceLiveEvents!;\n setWorkspaceControlEvent(null);\n setWorkspaceInteractionEvent(null);\n if (!pageLive) {\n setWorkspaceControlConnectionState(\"idle\");\n setWorkspaceInteractionConnectionState(\"idle\");\n return;\n }\n const controller = new AbortController();\n const setConnectionState = (state: StreamConnectionState) => {\n setWorkspaceControlConnectionState(state);\n setWorkspaceInteractionConnectionState(state);\n };\n setConnectionState(\"connecting\");\n void (async () => {\n try {\n await verifyApiContract();\n const workspace = await client.getWorkspace(workspaceId);\n const controlAfter = Math.max(\n workspaceControlSequencesRef.current.get(workspaceId) ?? 0,\n workspace.inferenceControl.revision,\n );\n const interactionAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;\n workspaceControlSequencesRef.current.set(workspaceId, controlAfter);\n const stream = openLiveStream.call(client, workspaceId, {\n controlAfter,\n interactionAfter,\n signal: controller.signal,\n onStateChange: setConnectionState,\n });\n for await (const event of stream) {\n if (controller.signal.aborted) return;\n if (event.type === \"workspace.control.changed\") {\n workspaceControlSequencesRef.current.set(\n workspaceId,\n Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence),\n );\n setWorkspaceControlEvent((current) =>\n !current || event.sequence > current.sequence ? event : current,\n );\n callbackRef.current?.(event);\n } else {\n workspaceInteractionSequencesRef.current.set(\n workspaceId,\n Math.max(\n workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,\n event.sequence,\n ),\n );\n setWorkspaceInteractionEvent((current) =>\n !current || event.sequence > current.sequence ? event : current,\n );\n interactionCallbackRef.current?.(event);\n }\n }\n } catch (error) {\n if (strictContract && error instanceof OpenGeniApiContractMismatchError) {\n setContractMismatch(error);\n reloadForContractMismatchOnce(error);\n }\n if (!controller.signal.aborted) {\n setWorkspaceControlConnectionState(\"error\");\n setWorkspaceInteractionConnectionState(\"error\");\n }\n }\n })();\n return () => controller.abort();\n }, [\n client,\n pageLive,\n strictContract,\n supportsWorkspaceLiveStream,\n verifyApiContract,\n workspaceId,\n ]);\n\n useEffect(() => {\n if (supportsWorkspaceLiveStream) return;\n if (!pageLive) {\n setWorkspaceControlConnectionState(\"idle\");\n return;\n }\n const controller = new AbortController();\n setWorkspaceControlConnectionState(\"connecting\");\n void (async () => {\n try {\n await verifyApiContract();\n const workspace = await client.getWorkspace(workspaceId);\n const resumeAfter = Math.max(\n workspaceControlSequencesRef.current.get(workspaceId) ?? 0,\n workspace.inferenceControl.revision,\n );\n workspaceControlSequencesRef.current.set(workspaceId, resumeAfter);\n const stream = client.streamWorkspaceControlEvents(workspaceId, {\n after: resumeAfter,\n signal: controller.signal,\n onStateChange: setWorkspaceControlConnectionState,\n });\n for await (const event of stream) {\n if (controller.signal.aborted) return;\n workspaceControlSequencesRef.current.set(\n workspaceId,\n Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence),\n );\n setWorkspaceControlEvent((current) =>\n !current || event.sequence > current.sequence ? event : current,\n );\n callbackRef.current?.(event);\n }\n } catch (error) {\n if (strictContract && error instanceof OpenGeniApiContractMismatchError) {\n setContractMismatch(error);\n reloadForContractMismatchOnce(error);\n }\n if (!controller.signal.aborted) setWorkspaceControlConnectionState(\"error\");\n }\n })();\n return () => controller.abort();\n }, [\n client,\n pageLive,\n strictContract,\n supportsWorkspaceLiveStream,\n verifyApiContract,\n workspaceId,\n ]);\n\n useEffect(() => {\n if (supportsWorkspaceLiveStream) return;\n setWorkspaceInteractionEvent(null);\n if (!pageLive) {\n setWorkspaceInteractionConnectionState(\"idle\");\n return;\n }\n const controller = new AbortController();\n setWorkspaceInteractionConnectionState(\"connecting\");\n void (async () => {\n try {\n await verifyApiContract();\n const resumeAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;\n const stream = client.streamWorkspaceInteractionRevisions(workspaceId, {\n after: resumeAfter,\n signal: controller.signal,\n onStateChange: setWorkspaceInteractionConnectionState,\n });\n for await (const event of stream) {\n if (controller.signal.aborted) return;\n workspaceInteractionSequencesRef.current.set(\n workspaceId,\n Math.max(\n workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,\n event.sequence,\n ),\n );\n setWorkspaceInteractionEvent((current) =>\n !current || event.sequence > current.sequence ? event : current,\n );\n interactionCallbackRef.current?.(event);\n }\n } catch (error) {\n if (strictContract && error instanceof OpenGeniApiContractMismatchError) {\n setContractMismatch(error);\n reloadForContractMismatchOnce(error);\n }\n if (!controller.signal.aborted) setWorkspaceInteractionConnectionState(\"error\");\n }\n })();\n return () => controller.abort();\n }, [\n client,\n pageLive,\n strictContract,\n supportsWorkspaceLiveStream,\n verifyApiContract,\n workspaceId,\n ]);\n\n const value = useMemo(\n () => ({\n client,\n workspaceId,\n workspaceControlEvent,\n workspaceControlConnectionState,\n workspaceInteractionEvent,\n workspaceInteractionConnectionState,\n registerSessionReconciler,\n reconcileSession,\n }),\n [\n client,\n workspaceId,\n workspaceControlEvent,\n workspaceControlConnectionState,\n workspaceInteractionEvent,\n workspaceInteractionConnectionState,\n registerSessionReconciler,\n reconcileSession,\n ],\n );\n return (\n <OpenGeniContext.Provider value={value}>\n {children}\n {contractMismatch ? <ApiContractMismatchScreen mismatch={contractMismatch} /> : null}\n </OpenGeniContext.Provider>\n );\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n return Promise.race([\n promise,\n new Promise<T>((_resolve, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]).finally(() => {\n if (timer !== undefined) clearTimeout(timer);\n });\n}\n\nfunction ApiContractMismatchScreen({ mismatch }: { mismatch: OpenGeniApiContractMismatchError }) {\n return (\n <div\n className=\"og-root fixed inset-0 z-[2147483647] grid place-items-center bg-og-bg/95 p-6 backdrop-blur-sm\"\n role=\"alert\"\n aria-live=\"assertive\"\n data-opengeni-api-contract-mismatch\n >\n <div className=\"w-full max-w-md rounded-xl border border-og-border bg-og-surface p-6 shadow-2xl\">\n <p className=\"text-og-menu font-semibold text-og-fg\">Opengeni updated</p>\n <p className=\"mt-2 text-og-menu leading-6 text-og-muted\">\n This tab cannot safely continue with the new server version. Reload it before sending or\n controlling work.\n </p>\n <p className=\"mt-3 font-mono text-og-control text-og-subtle\">\n Client {mismatch.expected} · API {mismatch.actual}\n </p>\n <button\n type=\"button\"\n className=\"mt-5 inline-flex h-9 items-center rounded-md border border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover px-3 text-og-menu font-medium\"\n onClick={() => window.location.reload()}\n >\n Reload now\n </button>\n </div>\n </div>\n );\n}\n\nfunction reloadForContractMismatchOnce(mismatch: OpenGeniApiContractMismatchError): void {\n if (typeof window === \"undefined\" || typeof sessionStorage === \"undefined\") return;\n const key = `${CONTRACT_RELOAD_STORAGE_PREFIX}${mismatch.actual}`;\n if (sessionStorage.getItem(key) === OPENGENI_API_CONTRACT_REVISION) return;\n sessionStorage.setItem(key, OPENGENI_API_CONTRACT_REVISION);\n window.setTimeout(() => window.location.reload(), 150);\n}\n"],"mappings":"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","names":[]}