@opengeni/react 7.4.0-canary.36855269964001 → 7.4.0
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.
- package/README.md +3 -48
- package/dist/artifacts-document.js +2 -3
- package/dist/artifacts-presentation.js +2 -3
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +0 -1
- package/dist/artifacts.js +1402 -505
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-R6KK5VKR.js → browser-viewer-2E6R2Y4W.js} +4 -4
- package/dist/{chunk-WUISZ3WU.js → chunk-3E2AITTZ.js} +28 -32
- package/dist/{chunk-WUISZ3WU.js.map → chunk-3E2AITTZ.js.map} +1 -1
- package/dist/{chunk-PWUILT2U.js → chunk-5AZSK6MV.js} +2 -2
- package/dist/{chunk-Y2PRMYLC.js → chunk-DUEBTL3N.js} +3 -4
- package/dist/{chunk-Y2PRMYLC.js.map → chunk-DUEBTL3N.js.map} +1 -1
- package/dist/{chunk-7UAMYXJY.js → chunk-KNDIXZN6.js} +18 -25
- package/dist/{chunk-7UAMYXJY.js.map → chunk-KNDIXZN6.js.map} +1 -1
- package/dist/{chunk-P4G6K2E2.js → chunk-L4OSXQ6H.js} +884 -1119
- package/dist/chunk-L4OSXQ6H.js.map +1 -0
- package/dist/{chunk-LLIH7Q4B.js → chunk-S5JQ4R22.js} +19 -47
- package/dist/chunk-S5JQ4R22.js.map +1 -0
- package/dist/{chunk-A4UJB2MM.js → chunk-SEEVCT36.js} +2 -2
- package/dist/{chunk-UXJCQ5GH.js → chunk-UDD6DLLT.js} +1 -6
- package/dist/chunk-UDD6DLLT.js.map +1 -0
- package/dist/chunk-UGMKPUEM.js +299 -0
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/{chunk-ZCZHKJKZ.js → chunk-USXVQACU.js} +3 -3
- package/dist/{chunk-VABBF52G.js → chunk-V2ABIVYJ.js} +6 -70
- package/dist/chunk-V2ABIVYJ.js.map +1 -0
- package/dist/{chunk-TVO6GXR6.js → chunk-X4HIN6TV.js} +162 -71
- package/dist/chunk-X4HIN6TV.js.map +1 -0
- package/dist/{chunk-IIDEIBMC.js → chunk-XEJEOAOV.js} +38 -49
- package/dist/chunk-XEJEOAOV.js.map +1 -0
- package/dist/{chunk-ZKLCPBWN.js → chunk-Y3QTZN2F.js} +5 -5
- package/dist/{chunk-73BUNGLF.js → chunk-YZ3YYMOM.js} +1 -1
- package/dist/components/artifacts/editable-artifact-ui.d.ts +1 -2
- package/dist/components/artifacts/index.d.ts +0 -7
- package/dist/components/browser-select-control.d.ts +1 -3
- package/dist/components/message-timeline.d.ts +1 -18
- package/dist/components/open-geni-links.d.ts +0 -16
- package/dist/components/session-conversation.d.ts +1 -20
- package/dist/composer.js +3 -3
- package/dist/{computer-viewer-DJHPSP2J.js → computer-viewer-WMJE6OA3.js} +3 -3
- package/dist/connect.js +6 -7
- package/dist/connect.js.map +1 -1
- package/dist/hooks/latest-question.d.ts +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.js +28 -39
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +4 -4
- package/dist/{latest-question-KGCDK3XX.js → latest-question-QB4EUCW5.js} +3 -3
- package/dist/lib/format.d.ts +0 -3
- package/dist/machines.js +2 -2
- package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-PFUEZ2U4.js} +5 -37
- package/dist/markdown-table-layout-PFUEZ2U4.js.map +1 -0
- package/dist/{sandbox-files-4PMXDSDV.js → sandbox-files-PXPIZAFG.js} +2 -2
- package/dist/session-ui.d.ts +2 -5
- package/dist/session-ui.js +13 -23
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +3 -3
- package/dist/sites.js +289 -4
- package/dist/sites.js.map +1 -1
- package/dist/timeline/types.d.ts +1 -7
- package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-ODLVF4OI.js} +1 -6
- package/dist/timeline-annotation-selection-ODLVF4OI.js.map +1 -0
- package/package.json +3 -7
- package/src/artifacts.ts +0 -37
- package/src/components/artifacts/editable-artifact-ui.tsx +1 -3
- package/src/components/artifacts/editable-artifact-workbench.tsx +2 -5
- package/src/components/artifacts/editable-document.tsx +36 -34
- package/src/components/artifacts/editable-presentation.tsx +16 -21
- package/src/components/artifacts/index.ts +0 -41
- package/src/components/browser-select-control.tsx +1 -4
- package/src/components/browser-viewer.tsx +22 -81
- package/src/components/computer-viewer.tsx +23 -51
- package/src/components/markdown-table-layout.ts +5 -49
- package/src/components/markdown.tsx +2 -5
- package/src/components/message-timeline.tsx +434 -515
- package/src/components/open-geni-links.tsx +0 -24
- package/src/components/session-conversation.tsx +20 -131
- package/src/components/timeline-annotation-selection.tsx +0 -7
- package/src/hooks/use-available-models.ts +1 -1
- package/src/index.ts +0 -9
- package/src/lib/format.ts +0 -13
- package/src/session-ui.ts +0 -9
- package/src/timeline/projection.ts +4 -78
- package/src/timeline/types.ts +0 -7
- package/styles/compiled.css +0 -325
- package/dist/chat-interactive-block-VAGABN7J.js +0 -11
- package/dist/chunk-5CVXZA3Y.js +0 -292
- package/dist/chunk-5CVXZA3Y.js.map +0 -1
- package/dist/chunk-B3V6TG77.js +0 -41
- package/dist/chunk-B3V6TG77.js.map +0 -1
- package/dist/chunk-IIDEIBMC.js.map +0 -1
- package/dist/chunk-LLIH7Q4B.js.map +0 -1
- package/dist/chunk-P4G6K2E2.js.map +0 -1
- package/dist/chunk-RAIQYITC.js +0 -1772
- package/dist/chunk-RAIQYITC.js.map +0 -1
- package/dist/chunk-SCOTPE2I.js +0 -589
- package/dist/chunk-SCOTPE2I.js.map +0 -1
- package/dist/chunk-TVO6GXR6.js.map +0 -1
- package/dist/chunk-UXJCQ5GH.js.map +0 -1
- package/dist/chunk-VABBF52G.js.map +0 -1
- package/dist/chunk-WEHMPOXK.js +0 -39
- package/dist/chunk-WEHMPOXK.js.map +0 -1
- package/dist/chunk-XCHWDJ22.js +0 -107
- package/dist/chunk-XCHWDJ22.js.map +0 -1
- package/dist/components/artifacts/artifact-chrome.d.ts +0 -120
- package/dist/components/artifacts/artifact-sandbox.d.ts +0 -27
- package/dist/components/artifacts/chat-interactive-block.d.ts +0 -29
- package/dist/components/artifacts/deferred-chat-media.d.ts +0 -15
- package/dist/components/artifacts/editable-artifact-view.d.ts +0 -46
- package/dist/components/artifacts/latest-task-runner.d.ts +0 -15
- package/dist/components/artifacts/session-artifact-viewer.d.ts +0 -39
- package/dist/components/artifacts/site-view.d.ts +0 -23
- package/dist/components/timeline-pill-geometry.d.ts +0 -6
- package/dist/components/timeline-pill-placement.d.ts +0 -18
- package/dist/components/usage-limit-notice.d.ts +0 -49
- package/dist/components/usage-member-list.d.ts +0 -91
- package/dist/components/usage-meter.d.ts +0 -73
- package/dist/hooks/use-usage.d.ts +0 -40
- package/dist/markdown-table-layout-QXSLK4BY.js.map +0 -1
- package/dist/sandbox-files-4PMXDSDV.js.map +0 -1
- package/dist/timeline/allowance-exhausted-row.d.ts +0 -24
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +0 -1
- package/dist/timeline-pill-geometry-2G6EK47V.js +0 -73
- package/dist/timeline-pill-geometry-2G6EK47V.js.map +0 -1
- package/dist/usage/allowance-copy.d.ts +0 -25
- package/dist/usage/summary.d.ts +0 -35
- package/dist/usage.d.ts +0 -13
- package/dist/usage.js +0 -1073
- package/dist/usage.js.map +0 -1
- package/src/components/artifacts/artifact-chrome.tsx +0 -413
- package/src/components/artifacts/artifact-sandbox.tsx +0 -185
- package/src/components/artifacts/chat-interactive-block.tsx +0 -260
- package/src/components/artifacts/deferred-chat-media.tsx +0 -67
- package/src/components/artifacts/editable-artifact-view.tsx +0 -187
- package/src/components/artifacts/latest-task-runner.ts +0 -49
- package/src/components/artifacts/session-artifact-viewer.tsx +0 -376
- package/src/components/artifacts/site-view.tsx +0 -116
- package/src/components/timeline-pill-geometry.ts +0 -112
- package/src/components/timeline-pill-placement.ts +0 -81
- package/src/components/usage-limit-notice.tsx +0 -179
- package/src/components/usage-member-list.tsx +0 -792
- package/src/components/usage-meter.tsx +0 -382
- package/src/hooks/use-usage.ts +0 -100
- package/src/timeline/allowance-exhausted-row.tsx +0 -86
- package/src/usage/allowance-copy.ts +0 -64
- package/src/usage/summary.ts +0 -93
- package/src/usage.ts +0 -50
- /package/dist/{browser-viewer-R6KK5VKR.js.map → browser-viewer-2E6R2Y4W.js.map} +0 -0
- /package/dist/{chunk-PWUILT2U.js.map → chunk-5AZSK6MV.js.map} +0 -0
- /package/dist/{chunk-A4UJB2MM.js.map → chunk-SEEVCT36.js.map} +0 -0
- /package/dist/{chunk-ZCZHKJKZ.js.map → chunk-USXVQACU.js.map} +0 -0
- /package/dist/{chunk-ZKLCPBWN.js.map → chunk-Y3QTZN2F.js.map} +0 -0
- /package/dist/{chunk-73BUNGLF.js.map → chunk-YZ3YYMOM.js.map} +0 -0
- /package/dist/{chat-interactive-block-VAGABN7J.js.map → computer-viewer-WMJE6OA3.js.map} +0 -0
- /package/dist/{latest-question-KGCDK3XX.js.map → latest-question-QB4EUCW5.js.map} +0 -0
- /package/dist/{computer-viewer-DJHPSP2J.js.map → sandbox-files-PXPIZAFG.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
editableArtifactAccessRevoked,
|
|
5
5
|
editableArtifactStatusLabel,
|
|
6
6
|
useEditableArtifactView
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DUEBTL3N.js";
|
|
8
8
|
import {
|
|
9
9
|
cn
|
|
10
10
|
} from "./chunk-22KP6LR5.js";
|
|
@@ -2835,4 +2835,4 @@ export {
|
|
|
2835
2835
|
EditableSpreadsheetGrid,
|
|
2836
2836
|
EditableSpreadsheetArtifactSurface
|
|
2837
2837
|
};
|
|
2838
|
-
//# sourceMappingURL=chunk-
|
|
2838
|
+
//# sourceMappingURL=chunk-SEEVCT36.js.map
|
|
@@ -89,13 +89,8 @@ function tryParseJson(text) {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
var CREDIT_EXHAUSTION_MESSAGE = "Out of Opengeni credits \u2014 this workspace's balance is empty. Add credits to continue; the conversation is preserved.";
|
|
92
|
-
var COMPOSER_MEMBER_ALLOWANCE_MESSAGE = "Usage limit reached. A workspace admin can raise this limit. Your draft is preserved.";
|
|
93
|
-
var COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE = "Workspace usage limit reached. An organization admin can raise the workspace budget. Your draft is preserved.";
|
|
94
92
|
var COMPOSER_PAYMENT_REQUIRED_MESSAGE = "This turn requires Opengeni managed credits, but the account balance is empty. Add credits or choose a connected Codex subscription model, then retry. Your draft and attachments are preserved.";
|
|
95
93
|
function composerSubmissionErrorMessage(error) {
|
|
96
|
-
if (error instanceof OpenGeniApiError && error.code === "allowance_exhausted") {
|
|
97
|
-
return error.scope === "workspace" ? COMPOSER_WORKSPACE_ALLOWANCE_MESSAGE : COMPOSER_MEMBER_ALLOWANCE_MESSAGE;
|
|
98
|
-
}
|
|
99
94
|
return error instanceof OpenGeniApiError && error.status === 402 && error.code === "payment_required" ? COMPOSER_PAYMENT_REQUIRED_MESSAGE : error.message;
|
|
100
95
|
}
|
|
101
96
|
function isCreditExhaustion(input) {
|
|
@@ -166,4 +161,4 @@ export {
|
|
|
166
161
|
humanizeFailureReason,
|
|
167
162
|
presentFailure
|
|
168
163
|
};
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
164
|
+
//# sourceMappingURL=chunk-UDD6DLLT.js.map
|
|
@@ -0,0 +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/**\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 \"This turn requires Opengeni managed credits, but the account balance is empty. Add credits or choose a connected Codex subscription model, then retry. Your draft and attachments are preserved.\";\n\nexport function composerSubmissionErrorMessage(error: Error): string {\n return error instanceof OpenGeniApiError &&\n error.status === 402 &&\n error.code === \"payment_required\"\n ? COMPOSER_PAYMENT_REQUIRED_MESSAGE\n : error.message;\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":";AAAA,SAAS,wBAAwB;AAEjC,IAAM,qBAAqB,IAAI,KAAK,eAAe,QAAW;AAAA,EAC5D,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;AAGM,SAAS,gBAAgB,KAAqB;AACnD,QAAM,OAAO,IAAI,KAAK,GAAG;AACzB,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO;AAAA,EACT;AACA,SAAO,mBAAmB,OAAO,IAAI;AACvC;AAGO,SAAS,mBAAmB,KAAa,MAAY,oBAAI,KAAK,GAAW;AAC9E,QAAM,OAAO,IAAI,KAAK,GAAG,EAAE,QAAQ;AACnC,MAAI,OAAO,MAAM,IAAI,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,QAAQ,IAAI,QAAQ,GAAI,CAAC;AACrE,MAAI,UAAU,IAAI;AAChB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,IAAI;AAChB,WAAO,GAAG,OAAO;AAAA,EACnB;AACA,QAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,MAAI,UAAU,IAAI;AAChB,WAAO,GAAG,OAAO;AAAA,EACnB;AACA,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,MAAI,QAAQ,IAAI;AACd,WAAO,GAAG,KAAK;AAAA,EACjB;AACA,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,MAAI,OAAO,IAAI;AACb,WAAO,GAAG,IAAI;AAAA,EAChB;AACA,SAAO,IAAI,KAAK,GAAG,EAAE,mBAAmB;AAC1C;AAGO,SAAS,YAAY,OAAuB;AACjD,MAAI,QAAQ,MAAM;AAChB,WAAO,GAAG,KAAK;AAAA,EACjB;AACA,QAAM,QAAQ,CAAC,MAAM,MAAM,IAAI;AAC/B,MAAI,QAAQ,QAAQ;AACpB,aAAW,QAAQ,OAAO;AACxB,QAAI,QAAQ,QAAQ,SAAS,MAAM;AACjC,aAAO,GAAG,MAAM,QAAQ,QAAQ,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI;AAAA,IACrD;AACA,aAAS;AAAA,EACX;AACA,SAAO,GAAG,KAAK;AACjB;AAGO,SAAS,SAAS,MAAc,WAA2B;AAChE,QAAM,YAAY,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACjD,MAAI,UAAU,UAAU,WAAW;AACjC,WAAO;AAAA,EACT;AACA,SAAO,GAAG,UAAU,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC;AACpE;AAGO,SAAS,iBAAiB,OAAwB;AACvD,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,aAAa,KAAK;AACjC,QAAI,WAAW,UAAa,OAAO,WAAW,UAAU;AACtD,aAAO,iBAAiB,MAAM;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,KAAK,UAAU,OAAO,MAAM,CAAC,KAAK,OAAO,KAAK;AAAA,EACvD,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAGO,SAAS,aAAa,MAAuB;AAClD,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,GAAG,GAAG;AACpF,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,IAAM,4BACX;AAOK,IAAM,oCACX;AAEK,SAAS,+BAA+B,OAAsB;AACnE,SAAO,iBAAiB,oBACtB,MAAM,WAAW,OACjB,MAAM,SAAS,qBACb,oCACA,MAAM;AACZ;AASO,SAAS,mBACd,OACS;AACT,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,YAAY,EAAE,SAAS,+BAA+B;AAAA,EACrE;AACA,MAAI,MAAM,iBAAiB,oBAAoB;AAC7C,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,CAAC,MAAM,OAAO,MAAM,MAAM,GAAG;AAC9C,QAAI,OAAO,SAAS,YAAY,KAAK,YAAY,EAAE,SAAS,+BAA+B,GAAG;AAC5F,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAYO,SAAS,sBAAsB,QAAsC;AAC1E,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,mBAAmB,MAAM,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,YAAY;AACtC,QAAM,cACJ,WAAW,SAAS,mBAAmB,KACvC,WAAW,SAAS,iBAAiB,KACrC,WAAW,SAAS,iBAAiB,KACrC,WAAW,SAAS,sCAAsC,KACzD,WAAW,SAAS,KAAK,MACvB,WAAW,SAAS,SAAS,KAAK,WAAW,SAAS,cAAc;AACzE,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AACA,QAAM,eACJ,WAAW,SAAS,oBAAoB,KAAK,WAAW,SAAS,6BAA6B;AAChG,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,eAAe,SAG7B;AACA,QAAM,OAAO,CAAC,QAA+B;AAC3C,UAAM,QAAQ,QAAQ,GAAG;AACzB,WAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,QAAQ;AAAA,EAC7D;AACA,QAAM,UAAU,KAAK,OAAO,KAAK,KAAK,SAAS;AAC/C,QAAM,SAAS,KAAK,oBAAoB,KAAK,KAAK,QAAQ;AAC1D,QAAM,gBACJ,QAAQ,SAAS,6BACjB,CAAC,SAAS,MAAM,EAAE;AAAA,IAChB,CAAC,UACC,UAAU,QAAQ,sDAAsD,KAAK,KAAK;AAAA,EACtF;AACF,MAAI,eAAe;AACjB,WAAO;AAAA,MACL,QAAQ,2CAA2C,UAAU,UAAU,IAAI,UAAU,OAAO,KAAK,EAAE;AAAA,MACnG,eAAe;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AAAA,IACL,QACE,UAAU,WAAW,UACjB,CAAC,sBAAsB,OAAO,GAAG,sBAAsB,MAAM,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,IACxF,sBAAsB,OAAO;AAAA,IACnC,eAAe;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// src/components/artifacts/published-html-artifact-frame.tsx
|
|
2
|
+
import {
|
|
3
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,
|
|
4
|
+
OPENGENI_SITE_BRIDGE_READY,
|
|
5
|
+
OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
6
|
+
OPENGENI_SITE_BRIDGE_VERSION,
|
|
7
|
+
isOpenGeniSiteBridgeCancelMessage,
|
|
8
|
+
isOpenGeniSiteBridgeConnectMessage,
|
|
9
|
+
isOpenGeniSiteBridgeRequestMessage,
|
|
10
|
+
sanitizeOpenGeniSiteToolCallRequest,
|
|
11
|
+
isSiteHttpRequest,
|
|
12
|
+
serveSiteHttp
|
|
13
|
+
} from "@opengeni/sdk/site";
|
|
14
|
+
import { useEffect, useRef, useState } from "react";
|
|
15
|
+
import { resolveSiteClientScript } from "@opengeni/sdk/site-document";
|
|
16
|
+
import { jsx } from "react/jsx-runtime";
|
|
17
|
+
var PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [
|
|
18
|
+
"allow-downloads",
|
|
19
|
+
"allow-forms",
|
|
20
|
+
"allow-modals",
|
|
21
|
+
"allow-orientation-lock",
|
|
22
|
+
"allow-pointer-lock",
|
|
23
|
+
"allow-popups",
|
|
24
|
+
"allow-popups-to-escape-sandbox",
|
|
25
|
+
"allow-presentation",
|
|
26
|
+
"allow-scripts"
|
|
27
|
+
].join(" ");
|
|
28
|
+
var SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(
|
|
29
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL
|
|
30
|
+
)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener("message",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(
|
|
31
|
+
OPENGENI_SITE_BRIDGE_READY
|
|
32
|
+
)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;
|
|
33
|
+
function publishedHtmlArtifactDocument(html, toolBridgeEnabled) {
|
|
34
|
+
if (!toolBridgeEnabled) return html;
|
|
35
|
+
html = resolveSiteClientScript(html);
|
|
36
|
+
const doctypeEnd = leadingDoctypeEnd(html);
|
|
37
|
+
if (doctypeEnd >= 0) {
|
|
38
|
+
return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;
|
|
39
|
+
}
|
|
40
|
+
return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;
|
|
41
|
+
}
|
|
42
|
+
function leadingDoctypeEnd(html) {
|
|
43
|
+
const lower = html.toLowerCase();
|
|
44
|
+
let cursor = html.charCodeAt(0) === 65279 ? 1 : 0;
|
|
45
|
+
while (cursor < html.length) {
|
|
46
|
+
while (/\s/.test(html[cursor] ?? "")) cursor += 1;
|
|
47
|
+
if (!html.startsWith("<!--", cursor)) break;
|
|
48
|
+
const commentEnd = html.indexOf("-->", cursor + 4);
|
|
49
|
+
if (commentEnd < 0) return -1;
|
|
50
|
+
cursor = commentEnd + 3;
|
|
51
|
+
}
|
|
52
|
+
if (!lower.startsWith("<!doctype", cursor)) return -1;
|
|
53
|
+
return html.indexOf(">", cursor + 9);
|
|
54
|
+
}
|
|
55
|
+
function PublishedHtmlArtifactFrame(props) {
|
|
56
|
+
const frameRef = useRef(null);
|
|
57
|
+
const [height, setHeight] = useState();
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!props.autoHeight) return;
|
|
60
|
+
const receive = (event) => {
|
|
61
|
+
if (event.source !== frameRef.current?.contentWindow || event.data?.type !== "opengeni.preview.height")
|
|
62
|
+
return;
|
|
63
|
+
const value = event.data.height;
|
|
64
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
65
|
+
setHeight(Math.min(1200, Math.max(80, value)));
|
|
66
|
+
};
|
|
67
|
+
window.addEventListener("message", receive);
|
|
68
|
+
return () => window.removeEventListener("message", receive);
|
|
69
|
+
}, [props.autoHeight]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
frameRef.current?.contentWindow?.postMessage(
|
|
72
|
+
{ type: "opengeni.preview.theme", theme: props.theme },
|
|
73
|
+
"*"
|
|
74
|
+
);
|
|
75
|
+
}, [props.theme]);
|
|
76
|
+
const bridgeRef = useRef(props.toolBridge);
|
|
77
|
+
const onFrameLoadRef = useRef(() => void 0);
|
|
78
|
+
const frameLoadPendingRef = useRef(false);
|
|
79
|
+
const toolBridgeEnabled = props.toolBridge !== void 0;
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
bridgeRef.current = props.toolBridge;
|
|
82
|
+
}, [props.toolBridge]);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!toolBridgeEnabled || typeof window === "undefined") return;
|
|
85
|
+
const requests = new SiteBridgeRequestRegistry();
|
|
86
|
+
const attachToolPort = (data, ports) => {
|
|
87
|
+
const port = openGeniSiteBridgePortFromBootstrap(data, ports);
|
|
88
|
+
if (!port) return;
|
|
89
|
+
requests.addPort(port);
|
|
90
|
+
port.addEventListener("message", (portEvent) => {
|
|
91
|
+
const message = portEvent.data;
|
|
92
|
+
if (isOpenGeniSiteBridgeCancelMessage(message)) {
|
|
93
|
+
requests.cancel(port, message.requestId);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (isSiteHttpRequest(message) && portEvent.ports.length === 1) {
|
|
97
|
+
const controller2 = requests.start(port, message.requestId);
|
|
98
|
+
if (!controller2) {
|
|
99
|
+
portEvent.ports[0].close();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
void serveSiteHttp(
|
|
103
|
+
message,
|
|
104
|
+
portEvent.ports[0],
|
|
105
|
+
async (request, signal) => {
|
|
106
|
+
const fetch = bridgeRef.current?.fetch;
|
|
107
|
+
if (!fetch) throw new Error("This Site host does not support the session SDK");
|
|
108
|
+
return fetch(request, signal);
|
|
109
|
+
},
|
|
110
|
+
controller2.signal
|
|
111
|
+
).finally(() => requests.complete(port, message.requestId, controller2));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!isOpenGeniSiteBridgeRequestMessage(message)) return;
|
|
115
|
+
const controller = requests.start(port, message.requestId);
|
|
116
|
+
if (!controller) {
|
|
117
|
+
port.postMessage({
|
|
118
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
119
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
120
|
+
requestId: message.requestId,
|
|
121
|
+
ok: false,
|
|
122
|
+
error: {
|
|
123
|
+
code: "duplicate_request_id",
|
|
124
|
+
message: "A Site tool request with this id is already running",
|
|
125
|
+
retryable: false
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
void handleSiteBridgeRequest(bridgeRef.current, message, controller.signal).then((value) => {
|
|
131
|
+
if (!controller.signal.aborted) {
|
|
132
|
+
port.postMessage({
|
|
133
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
134
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
135
|
+
requestId: message.requestId,
|
|
136
|
+
ok: true,
|
|
137
|
+
value
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}).catch((error) => {
|
|
141
|
+
if (!controller.signal.aborted) {
|
|
142
|
+
port.postMessage({
|
|
143
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
144
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
145
|
+
requestId: message.requestId,
|
|
146
|
+
ok: false,
|
|
147
|
+
error: siteBridgeError(error)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}).finally(() => requests.complete(port, message.requestId, controller));
|
|
151
|
+
});
|
|
152
|
+
port.addEventListener("messageerror", () => requests.closePort(port));
|
|
153
|
+
port.start();
|
|
154
|
+
port.postMessage({
|
|
155
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
156
|
+
version: OPENGENI_SITE_BRIDGE_VERSION
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
const documentLease = new SiteBridgeDocumentLease(attachToolPort, () => requests.closeAll());
|
|
160
|
+
const onFrameLoad = () => {
|
|
161
|
+
frameLoadPendingRef.current = false;
|
|
162
|
+
const frameWindow = frameRef.current?.contentWindow ?? null;
|
|
163
|
+
if (!frameWindow) return;
|
|
164
|
+
documentLease.load(frameWindow);
|
|
165
|
+
};
|
|
166
|
+
onFrameLoadRef.current = onFrameLoad;
|
|
167
|
+
if (frameLoadPendingRef.current) {
|
|
168
|
+
frameLoadPendingRef.current = false;
|
|
169
|
+
onFrameLoad();
|
|
170
|
+
}
|
|
171
|
+
return () => {
|
|
172
|
+
onFrameLoadRef.current = () => void 0;
|
|
173
|
+
documentLease.close();
|
|
174
|
+
};
|
|
175
|
+
}, [props.html, toolBridgeEnabled]);
|
|
176
|
+
return /* @__PURE__ */ jsx(
|
|
177
|
+
"iframe",
|
|
178
|
+
{
|
|
179
|
+
ref: frameRef,
|
|
180
|
+
title: props.title,
|
|
181
|
+
sandbox: PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX,
|
|
182
|
+
referrerPolicy: "no-referrer",
|
|
183
|
+
srcDoc: publishedHtmlArtifactDocument(props.html, toolBridgeEnabled),
|
|
184
|
+
onLoad: () => {
|
|
185
|
+
frameRef.current?.contentWindow?.postMessage(
|
|
186
|
+
{ type: "opengeni.preview.theme", theme: props.theme },
|
|
187
|
+
"*"
|
|
188
|
+
);
|
|
189
|
+
frameLoadPendingRef.current = true;
|
|
190
|
+
onFrameLoadRef.current();
|
|
191
|
+
},
|
|
192
|
+
className: props.className,
|
|
193
|
+
style: { ...props.style, ...props.autoHeight && height ? { height } : {} }
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
var SiteBridgeRequestRegistry = class {
|
|
198
|
+
controllersByPort = /* @__PURE__ */ new Map();
|
|
199
|
+
addPort(port) {
|
|
200
|
+
if (!this.controllersByPort.has(port)) this.controllersByPort.set(port, /* @__PURE__ */ new Map());
|
|
201
|
+
}
|
|
202
|
+
start(port, requestId) {
|
|
203
|
+
const controllers = this.controllersByPort.get(port);
|
|
204
|
+
if (!controllers || controllers.has(requestId)) return null;
|
|
205
|
+
const controller = new AbortController();
|
|
206
|
+
controllers.set(requestId, controller);
|
|
207
|
+
return controller;
|
|
208
|
+
}
|
|
209
|
+
cancel(port, requestId) {
|
|
210
|
+
const controllers = this.controllersByPort.get(port);
|
|
211
|
+
const controller = controllers?.get(requestId);
|
|
212
|
+
if (!controller) return;
|
|
213
|
+
controller.abort(new Error("Site tool request cancelled"));
|
|
214
|
+
controllers.delete(requestId);
|
|
215
|
+
}
|
|
216
|
+
complete(port, requestId, controller) {
|
|
217
|
+
const controllers = this.controllersByPort.get(port);
|
|
218
|
+
if (controllers?.get(requestId) === controller) controllers.delete(requestId);
|
|
219
|
+
}
|
|
220
|
+
closePort(port) {
|
|
221
|
+
const controllers = this.controllersByPort.get(port);
|
|
222
|
+
if (!controllers) return;
|
|
223
|
+
for (const controller of controllers.values()) {
|
|
224
|
+
controller.abort(new Error("Site tool bridge port closed"));
|
|
225
|
+
}
|
|
226
|
+
controllers.clear();
|
|
227
|
+
this.controllersByPort.delete(port);
|
|
228
|
+
port.close();
|
|
229
|
+
}
|
|
230
|
+
closeAll() {
|
|
231
|
+
for (const port of [...this.controllersByPort.keys()]) this.closePort(port);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var SiteBridgeDocumentLease = class {
|
|
235
|
+
constructor(attachToolPort, closeActivePorts, createMessageChannel = () => new MessageChannel()) {
|
|
236
|
+
this.attachToolPort = attachToolPort;
|
|
237
|
+
this.closeActivePorts = closeActivePorts;
|
|
238
|
+
this.createMessageChannel = createMessageChannel;
|
|
239
|
+
}
|
|
240
|
+
loaded = false;
|
|
241
|
+
bootstrapPort = null;
|
|
242
|
+
load(frameWindow) {
|
|
243
|
+
if (this.loaded) {
|
|
244
|
+
this.close();
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
this.loaded = true;
|
|
248
|
+
const channel = this.createMessageChannel();
|
|
249
|
+
this.bootstrapPort = channel.port1;
|
|
250
|
+
channel.port1.addEventListener("message", (event) => {
|
|
251
|
+
this.attachToolPort(event.data, event.ports);
|
|
252
|
+
});
|
|
253
|
+
channel.port1.start();
|
|
254
|
+
frameWindow.postMessage(
|
|
255
|
+
{
|
|
256
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
257
|
+
version: OPENGENI_SITE_BRIDGE_VERSION
|
|
258
|
+
},
|
|
259
|
+
"*",
|
|
260
|
+
[channel.port2]
|
|
261
|
+
);
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
close() {
|
|
265
|
+
this.bootstrapPort?.close();
|
|
266
|
+
this.bootstrapPort = null;
|
|
267
|
+
this.closeActivePorts();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
function openGeniSiteBridgePortFromBootstrap(data, ports) {
|
|
271
|
+
if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;
|
|
272
|
+
return ports.length === 1 ? ports[0] : null;
|
|
273
|
+
}
|
|
274
|
+
async function handleSiteBridgeRequest(bridge, message, signal) {
|
|
275
|
+
if (!bridge) throw new Error("Site tool bridge is unavailable");
|
|
276
|
+
if (message.method === "catalog") return await bridge.catalog({ signal });
|
|
277
|
+
if (message.method === "declarations") {
|
|
278
|
+
if (!bridge.declarations) throw new Error("Site tool declarations are unavailable");
|
|
279
|
+
return await bridge.declarations({ signal });
|
|
280
|
+
}
|
|
281
|
+
return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload), { signal });
|
|
282
|
+
}
|
|
283
|
+
function siteBridgeError(error) {
|
|
284
|
+
const candidate = error;
|
|
285
|
+
return {
|
|
286
|
+
code: typeof candidate?.code === "string" ? candidate.code : "site_tool_call_failed",
|
|
287
|
+
message: typeof candidate?.message === "string" ? candidate.message : "Site tool request failed",
|
|
288
|
+
retryable: candidate?.retryable === true,
|
|
289
|
+
outcomeUnknown: candidate?.outcomeUnknown === true
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export {
|
|
294
|
+
PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX,
|
|
295
|
+
publishedHtmlArtifactDocument,
|
|
296
|
+
PublishedHtmlArtifactFrame,
|
|
297
|
+
openGeniSiteBridgePortFromBootstrap
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=chunk-UGMKPUEM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/artifacts/published-html-artifact-frame.tsx"],"sourcesContent":["import {\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n OPENGENI_SITE_BRIDGE_READY,\n OPENGENI_SITE_BRIDGE_RESPONSE,\n OPENGENI_SITE_BRIDGE_VERSION,\n isOpenGeniSiteBridgeCancelMessage,\n isOpenGeniSiteBridgeConnectMessage,\n isOpenGeniSiteBridgeRequestMessage,\n sanitizeOpenGeniSiteToolCallRequest,\n isSiteHttpRequest,\n serveSiteHttp,\n type SiteHttpRequest,\n type OpenGeniSiteBridgeResponseMessage,\n type OpenGeniSiteToolCatalog,\n} from \"@opengeni/sdk/site\";\nimport type {\n ToolGatewayCallRequest,\n ToolGatewayCallResponse,\n ToolGatewayDeclarationsResponse,\n} from \"@opengeni/sdk\";\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport { resolveSiteClientScript } from \"@opengeni/sdk/site-document\";\n\nexport const PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [\n \"allow-downloads\",\n \"allow-forms\",\n \"allow-modals\",\n \"allow-orientation-lock\",\n \"allow-pointer-lock\",\n \"allow-popups\",\n \"allow-popups-to-escape-sandbox\",\n \"allow-presentation\",\n \"allow-scripts\",\n].join(\" \");\n\nexport type PublishedHtmlArtifactFrameProps = {\n html: string;\n autoHeight?: boolean;\n theme?: \"light\" | \"dark\";\n title: string;\n className?: string;\n style?: CSSProperties;\n toolBridge?: PublishedHtmlArtifactToolBridge;\n};\n\nexport type PublishedHtmlArtifactToolBridge = {\n fetch?: (request: SiteHttpRequest, signal: AbortSignal) => Promise<Response>;\n catalog: (options: { signal: AbortSignal }) => Promise<OpenGeniSiteToolCatalog>;\n call: (\n request: ToolGatewayCallRequest,\n options: { signal: AbortSignal },\n ) => Promise<ToolGatewayCallResponse>;\n declarations?: (options: { signal: AbortSignal }) => Promise<ToolGatewayDeclarationsResponse>;\n};\n\nconst SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener(\"message\",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(\n OPENGENI_SITE_BRIDGE_READY,\n)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;\n\nexport function publishedHtmlArtifactDocument(html: string, toolBridgeEnabled: boolean): string {\n if (!toolBridgeEnabled) return html;\n html = resolveSiteClientScript(html);\n const doctypeEnd = leadingDoctypeEnd(html);\n if (doctypeEnd >= 0) {\n return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;\n }\n return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;\n}\n\nfunction leadingDoctypeEnd(html: string): number {\n const lower = html.toLowerCase();\n let cursor = html.charCodeAt(0) === 0xfeff ? 1 : 0;\n while (cursor < html.length) {\n while (/\\s/.test(html[cursor] ?? \"\")) cursor += 1;\n if (!html.startsWith(\"<!--\", cursor)) break;\n const commentEnd = html.indexOf(\"-->\", cursor + 4);\n if (commentEnd < 0) return -1;\n cursor = commentEnd + 3;\n }\n if (!lower.startsWith(\"<!doctype\", cursor)) return -1;\n return html.indexOf(\">\", cursor + 9);\n}\n\n/**\n * Render exact published HTML in an opaque-origin iframe. Artifact scripts,\n * external resources, forms, popups, downloads, and the host-filtered tool\n * bridge work without granting parent-origin authority, shared cookies/storage,\n * or top-level navigation.\n */\nexport function PublishedHtmlArtifactFrame(props: PublishedHtmlArtifactFrameProps) {\n const frameRef = useRef<HTMLIFrameElement | null>(null);\n const [height, setHeight] = useState<number>();\n useEffect(() => {\n if (!props.autoHeight) return;\n const receive = (event: MessageEvent) => {\n if (\n event.source !== frameRef.current?.contentWindow ||\n event.data?.type !== \"opengeni.preview.height\"\n )\n return;\n const value = event.data.height;\n if (typeof value === \"number\" && Number.isFinite(value))\n setHeight(Math.min(1200, Math.max(80, value)));\n };\n window.addEventListener(\"message\", receive);\n return () => window.removeEventListener(\"message\", receive);\n }, [props.autoHeight]);\n useEffect(() => {\n frameRef.current?.contentWindow?.postMessage(\n { type: \"opengeni.preview.theme\", theme: props.theme },\n \"*\",\n );\n }, [props.theme]);\n const bridgeRef = useRef(props.toolBridge);\n const onFrameLoadRef = useRef<() => void>(() => undefined);\n const frameLoadPendingRef = useRef(false);\n const toolBridgeEnabled = props.toolBridge !== undefined;\n useEffect(() => {\n bridgeRef.current = props.toolBridge;\n }, [props.toolBridge]);\n useEffect(() => {\n if (!toolBridgeEnabled || typeof window === \"undefined\") return;\n const requests = new SiteBridgeRequestRegistry();\n const attachToolPort = (data: unknown, ports: readonly MessagePort[]) => {\n const port = openGeniSiteBridgePortFromBootstrap(data, ports);\n if (!port) return;\n requests.addPort(port);\n port.addEventListener(\"message\", (portEvent: MessageEvent<unknown>) => {\n const message = portEvent.data;\n if (isOpenGeniSiteBridgeCancelMessage(message)) {\n requests.cancel(port, message.requestId);\n return;\n }\n if (isSiteHttpRequest(message) && portEvent.ports.length === 1) {\n const controller = requests.start(port, message.requestId);\n if (!controller) {\n portEvent.ports[0]!.close();\n return;\n }\n void serveSiteHttp(\n message,\n portEvent.ports[0]!,\n async (request, signal) => {\n const fetch = bridgeRef.current?.fetch;\n if (!fetch) throw new Error(\"This Site host does not support the session SDK\");\n return fetch(request, signal);\n },\n controller.signal,\n ).finally(() => requests.complete(port, message.requestId, controller));\n return;\n }\n if (!isOpenGeniSiteBridgeRequestMessage(message)) return;\n const controller = requests.start(port, message.requestId);\n if (!controller) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: {\n code: \"duplicate_request_id\",\n message: \"A Site tool request with this id is already running\",\n retryable: false,\n },\n } satisfies OpenGeniSiteBridgeResponseMessage);\n return;\n }\n void handleSiteBridgeRequest(bridgeRef.current, message, controller.signal)\n .then((value) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: true,\n value,\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .catch((error) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: siteBridgeError(error),\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .finally(() => requests.complete(port, message.requestId, controller));\n });\n port.addEventListener(\"messageerror\", () => requests.closePort(port));\n port.start();\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n });\n };\n const documentLease = new SiteBridgeDocumentLease(attachToolPort, () => requests.closeAll());\n const onFrameLoad = () => {\n frameLoadPendingRef.current = false;\n const frameWindow = frameRef.current?.contentWindow ?? null;\n if (!frameWindow) return;\n documentLease.load(frameWindow);\n };\n onFrameLoadRef.current = onFrameLoad;\n if (frameLoadPendingRef.current) {\n frameLoadPendingRef.current = false;\n onFrameLoad();\n }\n return () => {\n onFrameLoadRef.current = () => undefined;\n documentLease.close();\n };\n }, [props.html, toolBridgeEnabled]);\n return (\n <iframe\n ref={frameRef}\n title={props.title}\n sandbox={PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX}\n referrerPolicy=\"no-referrer\"\n srcDoc={publishedHtmlArtifactDocument(props.html, toolBridgeEnabled)}\n onLoad={() => {\n frameRef.current?.contentWindow?.postMessage(\n { type: \"opengeni.preview.theme\", theme: props.theme },\n \"*\",\n );\n frameLoadPendingRef.current = true;\n onFrameLoadRef.current();\n }}\n className={props.className}\n style={{ ...props.style, ...(props.autoHeight && height ? { height } : {}) }}\n />\n );\n}\n\nexport class SiteBridgeRequestRegistry {\n private readonly controllersByPort = new Map<MessagePort, Map<string, AbortController>>();\n\n addPort(port: MessagePort): void {\n // Several SDK clients may share one document bootstrap. Document teardown,\n // not another client connecting, revokes all of that document's ports.\n if (!this.controllersByPort.has(port)) this.controllersByPort.set(port, new Map());\n }\n\n start(port: MessagePort, requestId: string): AbortController | null {\n const controllers = this.controllersByPort.get(port);\n if (!controllers || controllers.has(requestId)) return null;\n const controller = new AbortController();\n controllers.set(requestId, controller);\n return controller;\n }\n\n cancel(port: MessagePort, requestId: string): void {\n const controllers = this.controllersByPort.get(port);\n const controller = controllers?.get(requestId);\n if (!controller) return;\n controller.abort(new Error(\"Site tool request cancelled\"));\n controllers!.delete(requestId);\n }\n\n complete(port: MessagePort, requestId: string, controller: AbortController): void {\n const controllers = this.controllersByPort.get(port);\n if (controllers?.get(requestId) === controller) controllers.delete(requestId);\n }\n\n closePort(port: MessagePort): void {\n const controllers = this.controllersByPort.get(port);\n if (!controllers) return;\n for (const controller of controllers.values()) {\n controller.abort(new Error(\"Site tool bridge port closed\"));\n }\n controllers.clear();\n this.controllersByPort.delete(port);\n port.close();\n }\n\n closeAll(): void {\n for (const port of [...this.controllersByPort.keys()]) this.closePort(port);\n }\n}\n\nexport class SiteBridgeDocumentLease {\n private loaded = false;\n private bootstrapPort: MessagePort | null = null;\n\n constructor(\n private readonly attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void,\n private readonly closeActivePorts: () => void,\n private readonly createMessageChannel: () => MessageChannel = () => new MessageChannel(),\n ) {}\n\n load(frameWindow: Pick<Window, \"postMessage\">): boolean {\n if (this.loaded) {\n this.close();\n return false;\n }\n this.loaded = true;\n const channel = this.createMessageChannel();\n this.bootstrapPort = channel.port1;\n channel.port1.addEventListener(\"message\", (event: MessageEvent<unknown>) => {\n this.attachToolPort(event.data, event.ports);\n });\n channel.port1.start();\n frameWindow.postMessage(\n {\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n },\n \"*\",\n [channel.port2],\n );\n return true;\n }\n\n close(): void {\n this.bootstrapPort?.close();\n this.bootstrapPort = null;\n this.closeActivePorts();\n }\n}\n\nexport function openGeniSiteBridgePortFromBootstrap(\n data: unknown,\n ports: readonly MessagePort[],\n): MessagePort | null {\n if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;\n return ports.length === 1 ? ports[0]! : null;\n}\n\nasync function handleSiteBridgeRequest(\n bridge: PublishedHtmlArtifactToolBridge | undefined,\n message: Parameters<typeof isOpenGeniSiteBridgeRequestMessage>[0] & {\n method: \"catalog\" | \"call\" | \"declarations\";\n requestId: string;\n payload?: ToolGatewayCallRequest;\n },\n signal: AbortSignal,\n): Promise<OpenGeniSiteToolCatalog | ToolGatewayCallResponse | ToolGatewayDeclarationsResponse> {\n if (!bridge) throw new Error(\"Site tool bridge is unavailable\");\n if (message.method === \"catalog\") return await bridge.catalog({ signal });\n if (message.method === \"declarations\") {\n if (!bridge.declarations) throw new Error(\"Site tool declarations are unavailable\");\n return await bridge.declarations({ signal });\n }\n return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload!), { signal });\n}\n\nexport function siteBridgeError(error: unknown): {\n code: string;\n message: string;\n retryable: boolean;\n outcomeUnknown: boolean;\n} {\n const candidate = error as {\n code?: unknown;\n message?: unknown;\n retryable?: unknown;\n outcomeUnknown?: unknown;\n };\n return {\n code: typeof candidate?.code === \"string\" ? candidate.code : \"site_tool_call_failed\",\n message:\n typeof candidate?.message === \"string\" ? candidate.message : \"Site tool request failed\",\n retryable: candidate?.retryable === true,\n outcomeUnknown: candidate?.outcomeUnknown === true,\n };\n}\n"],"mappings":"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","names":["controller"]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
buildTimeline,
|
|
3
3
|
groupTimeline,
|
|
4
4
|
sessionStatusFromEvents
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-V2ABIVYJ.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-
|
|
833
|
+
const { resolveLatestQuestion } = await import("./latest-question-QB4EUCW5.js");
|
|
834
834
|
if (!current()) return null;
|
|
835
835
|
const destination = await resolveLatestQuestion({
|
|
836
836
|
client,
|
|
@@ -2308,4 +2308,4 @@ export {
|
|
|
2308
2308
|
projectPendingApprovals,
|
|
2309
2309
|
conversationTimeline
|
|
2310
2310
|
};
|
|
2311
|
-
//# sourceMappingURL=chunk-
|
|
2311
|
+
//# sourceMappingURL=chunk-USXVQACU.js.map
|
|
@@ -7,14 +7,12 @@ import {
|
|
|
7
7
|
isCreditExhaustion,
|
|
8
8
|
presentFailure,
|
|
9
9
|
tryParseJson
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UDD6DLLT.js";
|
|
11
11
|
|
|
12
12
|
// src/timeline/projection.ts
|
|
13
13
|
import {
|
|
14
14
|
parseMediaGenerationResult,
|
|
15
|
-
parseToolDisplayMetadata
|
|
16
|
-
EMPTY_FINAL_REPLY_NOTICE,
|
|
17
|
-
turnCompletedWithEmptyFinalReply
|
|
15
|
+
parseToolDisplayMetadata
|
|
18
16
|
} from "@opengeni/sdk";
|
|
19
17
|
|
|
20
18
|
// src/timeline/fleet-decision-projection.ts
|
|
@@ -257,10 +255,6 @@ function asRecord(value) {
|
|
|
257
255
|
}
|
|
258
256
|
|
|
259
257
|
// src/timeline/projection.ts
|
|
260
|
-
import {
|
|
261
|
-
allowanceExhaustedMessage,
|
|
262
|
-
parseAllowanceExhaustedRefusal
|
|
263
|
-
} from "@opengeni/sdk/allowance-refusal";
|
|
264
258
|
function isTimelineUserQuestion(event) {
|
|
265
259
|
return event.type === "user.message" && workerCompletionPayload(asRecord2(event.payload).childCompletion) === null;
|
|
266
260
|
}
|
|
@@ -307,34 +301,6 @@ function timelineAnnotationToolOutputText(output) {
|
|
|
307
301
|
}
|
|
308
302
|
function buildTimeline(events, options = {}) {
|
|
309
303
|
const items = [];
|
|
310
|
-
const allowanceNotices = /* @__PURE__ */ new Set();
|
|
311
|
-
const allowanceNotice = (event, turnId) => {
|
|
312
|
-
const refusal = parseAllowanceExhaustedRefusal(event.payload);
|
|
313
|
-
if (!refusal) return null;
|
|
314
|
-
const text = allowanceExhaustedMessage(refusal);
|
|
315
|
-
const key = JSON.stringify([
|
|
316
|
-
turnId,
|
|
317
|
-
event.turnAttemptId,
|
|
318
|
-
startupRecoveryRevisionByTurn.get(turnId ?? "") ?? 0,
|
|
319
|
-
refusal.scope,
|
|
320
|
-
refusal.subjectId,
|
|
321
|
-
refusal.resetsAt
|
|
322
|
-
]);
|
|
323
|
-
if (!allowanceNotices.has(key)) {
|
|
324
|
-
allowanceNotices.add(key);
|
|
325
|
-
items.push({
|
|
326
|
-
kind: "notice",
|
|
327
|
-
id: `${event.id}-allowance`,
|
|
328
|
-
tone: "failed",
|
|
329
|
-
text,
|
|
330
|
-
// The canonical sentence replaces upstream prose, so a host renderer
|
|
331
|
-
// reading `message` never shows a wrapper's private wording.
|
|
332
|
-
allowance: { ...refusal, message: text },
|
|
333
|
-
occurredAt: event.occurredAt
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
return text;
|
|
337
|
-
};
|
|
338
304
|
const prescan = prescanTurnAnchors(events);
|
|
339
305
|
const ordered = orderTimelineEvents(events, prescan);
|
|
340
306
|
let completeHistoryPrefix = options.partialStart !== true;
|
|
@@ -1083,10 +1049,6 @@ ${message}` : message;
|
|
|
1083
1049
|
});
|
|
1084
1050
|
break;
|
|
1085
1051
|
}
|
|
1086
|
-
case "usage.exhausted": {
|
|
1087
|
-
allowanceNotice(event, turnId);
|
|
1088
|
-
break;
|
|
1089
|
-
}
|
|
1090
1052
|
case "turn.completed": {
|
|
1091
1053
|
if (payload.maintenance === "context_compaction") {
|
|
1092
1054
|
finalizeOpen(turnId, "complete", event.occurredAt);
|
|
@@ -1094,15 +1056,6 @@ ${message}` : message;
|
|
|
1094
1056
|
takePendingWaitOutcome(turnId);
|
|
1095
1057
|
break;
|
|
1096
1058
|
}
|
|
1097
|
-
const allowance = parseAllowanceExhaustedRefusal(payload);
|
|
1098
|
-
if (allowance) {
|
|
1099
|
-
finalizeOpen(turnId, "complete", event.occurredAt);
|
|
1100
|
-
takeAgentResponse(turnId);
|
|
1101
|
-
takePendingWaitOutcome(turnId);
|
|
1102
|
-
items.push(turnEndItem(event, "failed", ALLOWANCE_TURN_END_TEXT));
|
|
1103
|
-
allowanceNotice(event, turnId);
|
|
1104
|
-
break;
|
|
1105
|
-
}
|
|
1106
1059
|
if (isCreditExhaustionPayload(payload)) {
|
|
1107
1060
|
finalizeOpen(turnId, "complete", event.occurredAt);
|
|
1108
1061
|
takeAgentResponse(turnId);
|
|
@@ -1153,16 +1106,6 @@ ${message}` : message;
|
|
|
1153
1106
|
finalizeOpen(turnId, "complete", event.occurredAt);
|
|
1154
1107
|
const completedTurn = turnEndItem(event, "complete", null);
|
|
1155
1108
|
items.push(completedTurn);
|
|
1156
|
-
if (turnCompletedWithEmptyFinalReply(payload)) {
|
|
1157
|
-
items.push({
|
|
1158
|
-
kind: "notice",
|
|
1159
|
-
id: `${event.id}-empty-final-reply`,
|
|
1160
|
-
tone: "input",
|
|
1161
|
-
text: EMPTY_FINAL_REPLY_NOTICE,
|
|
1162
|
-
recordedOutcome: true,
|
|
1163
|
-
occurredAt: event.occurredAt
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
1109
|
const hasCompletedFinalResponse = latestAgentResponse?.completed === true && latestAgentResponse.item.phase !== "commentary" && Boolean(visibleTrackedResponse);
|
|
1167
1110
|
if (!hasAuthoritativeFinalOutput && pendingWaitOutcome) {
|
|
1168
1111
|
completedTurn.preserveWaitResponse = true;
|
|
@@ -1186,13 +1129,10 @@ ${message}` : message;
|
|
|
1186
1129
|
takeAgentResponse(turnId);
|
|
1187
1130
|
takePendingWaitOutcome(turnId);
|
|
1188
1131
|
const hadActivity = hasTurnActivity(items, turnId);
|
|
1189
|
-
const
|
|
1190
|
-
const failureText = allowance ? ALLOWANCE_TURN_END_TEXT : isCreditExhaustionPayload(payload) ? CREDIT_EXHAUSTION_MESSAGE : failureMessage(payload);
|
|
1132
|
+
const failureText = isCreditExhaustionPayload(payload) ? CREDIT_EXHAUSTION_MESSAGE : failureMessage(payload);
|
|
1191
1133
|
finalizeOpen(turnId, "cancelled", event.occurredAt);
|
|
1192
1134
|
items.push(turnEndItem(event, "failed", failureText));
|
|
1193
|
-
if (
|
|
1194
|
-
allowanceNotice(event, turnId);
|
|
1195
|
-
} else if (!hadActivity) {
|
|
1135
|
+
if (!hadActivity) {
|
|
1196
1136
|
items.push({
|
|
1197
1137
|
kind: "notice",
|
|
1198
1138
|
id: event.id,
|
|
@@ -1459,9 +1399,7 @@ function mergeToolCallRaw(existingValue, nextValue) {
|
|
|
1459
1399
|
function stripOpaqueCitationTokens(text) {
|
|
1460
1400
|
return text.replace(/\s*cite(?:[^]+)+/gu, "");
|
|
1461
1401
|
}
|
|
1462
|
-
var ALLOWANCE_TURN_END_TEXT = "Usage limit reached";
|
|
1463
1402
|
function isCreditExhaustionPayload(payload) {
|
|
1464
|
-
if (payload.code === "allowance_exhausted") return false;
|
|
1465
1403
|
return isCreditExhaustion({
|
|
1466
1404
|
error: typeof payload.error === "string" ? payload.error : null,
|
|
1467
1405
|
detail: typeof payload.detail === "string" ? payload.detail : null,
|
|
@@ -1920,9 +1858,7 @@ function isAgentActivityEvent(type) {
|
|
|
1920
1858
|
return type.startsWith("agent.") || type.startsWith("sandbox.");
|
|
1921
1859
|
}
|
|
1922
1860
|
function isTurnExecutionEvidence(type) {
|
|
1923
|
-
return isAgentActivityEvent(type) || type === "turn.completed" || type === "turn.failed" ||
|
|
1924
|
-
// its prompt still belongs above the "usage limit reached" row.
|
|
1925
|
-
type === "usage.exhausted" || type === "turn.superseded" || type === "turn.recovery.requested" || type === "turn.capacity_waiting" || type === "session.requiresAction" || type === "tool.auth_needed" || type === "credential.auth_needed" || type.startsWith("turn.startup.phase.") || type.startsWith("rig.setup.") || type === "codex.capacity.waiting" || type === "codex.capacity.resumed" || type === "codex.fleet.decision";
|
|
1861
|
+
return isAgentActivityEvent(type) || type === "turn.completed" || type === "turn.failed" || type === "turn.superseded" || type === "turn.recovery.requested" || type === "turn.capacity_waiting" || type === "session.requiresAction" || type === "tool.auth_needed" || type === "credential.auth_needed" || type.startsWith("turn.startup.phase.") || type.startsWith("rig.setup.") || type === "codex.capacity.waiting" || type === "codex.capacity.resumed" || type === "codex.fleet.decision";
|
|
1926
1862
|
}
|
|
1927
1863
|
function turnEndItem(event, outcome, failureText) {
|
|
1928
1864
|
return {
|
|
@@ -2572,4 +2508,4 @@ export {
|
|
|
2572
2508
|
isTurnExecutionEvidence,
|
|
2573
2509
|
extractSessionRef
|
|
2574
2510
|
};
|
|
2575
|
-
//# sourceMappingURL=chunk-
|
|
2511
|
+
//# sourceMappingURL=chunk-V2ABIVYJ.js.map
|