@opengeni/react 1.4.0 → 1.4.4
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 +8 -0
- package/dist/accounts.js +2 -0
- package/dist/accounts.js.map +1 -1
- package/dist/artifacts-document.js +5 -4
- package/dist/artifacts-presentation.js +5 -4
- package/dist/artifacts-spreadsheet.js +4 -3
- package/dist/artifacts.js +14 -13
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-5EEAS3IU.js +17 -0
- package/dist/chat-interactive-block-ZFHOKTMS.js +12 -0
- package/dist/{chunk-WEHMPOXK.js → chunk-2DDJ6YH6.js} +3 -1
- package/dist/{chunk-WEHMPOXK.js.map → chunk-2DDJ6YH6.js.map} +1 -1
- package/dist/{chunk-C5X5AJXK.js → chunk-2HVLQ26H.js} +5 -4
- package/dist/{chunk-C5X5AJXK.js.map → chunk-2HVLQ26H.js.map} +1 -1
- package/dist/{chunk-HDJWDK7W.js → chunk-2OQA3CPB.js} +300 -166
- package/dist/{chunk-HDJWDK7W.js.map → chunk-2OQA3CPB.js.map} +1 -1
- package/dist/{chunk-A4UJB2MM.js → chunk-32CGLXW2.js} +4 -3
- package/dist/{chunk-A4UJB2MM.js.map → chunk-32CGLXW2.js.map} +1 -1
- package/dist/{chunk-5CVXZA3Y.js → chunk-45NUOSXQ.js} +3 -2
- package/dist/{chunk-5CVXZA3Y.js.map → chunk-45NUOSXQ.js.map} +1 -1
- package/dist/{chunk-WUISZ3WU.js → chunk-53KJBGPZ.js} +5 -4
- package/dist/{chunk-WUISZ3WU.js.map → chunk-53KJBGPZ.js.map} +1 -1
- package/dist/{chunk-MBMPHOMA.js → chunk-55DXD22O.js} +3 -2
- package/dist/{chunk-MBMPHOMA.js.map → chunk-55DXD22O.js.map} +1 -1
- package/dist/{chunk-JT4JW7BC.js → chunk-5I4VRWBB.js} +3 -1
- package/dist/{chunk-JT4JW7BC.js.map → chunk-5I4VRWBB.js.map} +1 -1
- package/dist/{chunk-UK4TINKT.js → chunk-B27E3V37.js} +3 -1
- package/dist/{chunk-UK4TINKT.js.map → chunk-B27E3V37.js.map} +1 -1
- package/dist/{chunk-J6DBS4T3.js → chunk-BNKV5ZLF.js} +5 -4
- package/dist/{chunk-J6DBS4T3.js.map → chunk-BNKV5ZLF.js.map} +1 -1
- package/dist/{chunk-YM2DE7BQ.js → chunk-C5BF4L26.js} +13 -12
- package/dist/{chunk-YM2DE7BQ.js.map → chunk-C5BF4L26.js.map} +1 -1
- package/dist/{chunk-YBXQDQFX.js → chunk-C7CMD56T.js} +6 -5
- package/dist/{chunk-YBXQDQFX.js.map → chunk-C7CMD56T.js.map} +1 -1
- package/dist/{chunk-UGLEYEMP.js → chunk-CM7LVUKC.js} +3 -1
- package/dist/{chunk-UGLEYEMP.js.map → chunk-CM7LVUKC.js.map} +1 -1
- package/dist/{chunk-JVYQRRC4.js → chunk-CVYCLFMH.js} +3 -1
- package/dist/{chunk-JVYQRRC4.js.map → chunk-CVYCLFMH.js.map} +1 -1
- package/dist/{chunk-LJ2UTJJE.js → chunk-EAOSEIXB.js} +182 -97
- package/dist/chunk-EAOSEIXB.js.map +1 -0
- package/dist/{chunk-Y2PRMYLC.js → chunk-G3U2A6GS.js} +3 -2
- package/dist/{chunk-Y2PRMYLC.js.map → chunk-G3U2A6GS.js.map} +1 -1
- package/dist/{chunk-WZMYFJD3.js → chunk-G6YRCIYJ.js} +16 -7
- package/dist/{chunk-WZMYFJD3.js.map → chunk-G6YRCIYJ.js.map} +1 -1
- package/dist/{chunk-B3V6TG77.js → chunk-GC3PH6N7.js} +3 -1
- package/dist/{chunk-B3V6TG77.js.map → chunk-GC3PH6N7.js.map} +1 -1
- package/dist/{chunk-CJUO7J5Z.js → chunk-HXYOSSQO.js} +3 -2
- package/dist/{chunk-CJUO7J5Z.js.map → chunk-HXYOSSQO.js.map} +1 -1
- package/dist/{chunk-GYVRFZDY.js → chunk-I6OY3MWC.js} +310 -115
- package/dist/chunk-I6OY3MWC.js.map +1 -0
- package/dist/{chunk-BRM6FVZA.js → chunk-IEE7WCLN.js} +4 -3
- package/dist/{chunk-BRM6FVZA.js.map → chunk-IEE7WCLN.js.map} +1 -1
- package/dist/{chunk-DYWBUX5Q.js → chunk-IMSUVYQB.js} +6 -5
- package/dist/{chunk-DYWBUX5Q.js.map → chunk-IMSUVYQB.js.map} +1 -1
- package/dist/{chunk-LN6TCXD3.js → chunk-IUHHPMAX.js} +184 -48
- package/dist/chunk-IUHHPMAX.js.map +1 -0
- package/dist/{chunk-SGKD2OCN.js → chunk-IYQCWGU5.js} +6 -5
- package/dist/{chunk-SGKD2OCN.js.map → chunk-IYQCWGU5.js.map} +1 -1
- package/dist/{chunk-J2QWVSQY.js → chunk-JH7V627O.js} +8 -7
- package/dist/{chunk-J2QWVSQY.js.map → chunk-JH7V627O.js.map} +1 -1
- package/dist/{chunk-EESD3PY3.js → chunk-JHTIMBOL.js} +6 -5
- package/dist/{chunk-EESD3PY3.js.map → chunk-JHTIMBOL.js.map} +1 -1
- package/dist/{chunk-LNIRAOA3.js → chunk-L2J3PU7A.js} +7 -6
- package/dist/{chunk-LNIRAOA3.js.map → chunk-L2J3PU7A.js.map} +1 -1
- package/dist/{chunk-ZYRGEKWS.js → chunk-LJUMYUBO.js} +3 -1
- package/dist/{chunk-ZYRGEKWS.js.map → chunk-LJUMYUBO.js.map} +1 -1
- package/dist/{chunk-4RVYOY4O.js → chunk-LSW2OJVV.js} +4 -3
- package/dist/{chunk-4RVYOY4O.js.map → chunk-LSW2OJVV.js.map} +1 -1
- package/dist/{chunk-UTRTG6LH.js → chunk-LVS3MH5T.js} +3 -1
- package/dist/{chunk-UTRTG6LH.js.map → chunk-LVS3MH5T.js.map} +1 -1
- package/dist/chunk-M357MHH3.js +2 -0
- package/dist/{chunk-WRHIZYZF.js → chunk-MEQM4LI3.js} +6 -5
- package/dist/{chunk-WRHIZYZF.js.map → chunk-MEQM4LI3.js.map} +1 -1
- package/dist/chunk-NX4ADH73.js +14 -0
- package/dist/chunk-NX4ADH73.js.map +1 -0
- package/dist/{chunk-XCHWDJ22.js → chunk-OGTTUYNT.js} +3 -1
- package/dist/{chunk-XCHWDJ22.js.map → chunk-OGTTUYNT.js.map} +1 -1
- package/dist/{chunk-GIMRELBW.js → chunk-OYQQJL3J.js} +3 -1
- package/dist/{chunk-GIMRELBW.js.map → chunk-OYQQJL3J.js.map} +1 -1
- package/dist/{chunk-RSI7XYXL.js → chunk-PBCZL4JP.js} +6 -5
- package/dist/{chunk-RSI7XYXL.js.map → chunk-PBCZL4JP.js.map} +1 -1
- package/dist/{chunk-I7IWRQLN.js → chunk-PHBFJCEU.js} +17 -11
- package/dist/chunk-PHBFJCEU.js.map +1 -0
- package/dist/{chunk-3CTRFMAK.js → chunk-PKCAYHDC.js} +5 -4
- package/dist/{chunk-3CTRFMAK.js.map → chunk-PKCAYHDC.js.map} +1 -1
- package/dist/{chunk-K3HQAKQX.js → chunk-PMV53IMM.js} +3 -1
- package/dist/{chunk-K3HQAKQX.js.map → chunk-PMV53IMM.js.map} +1 -1
- package/dist/{chunk-YQEAA6LT.js → chunk-QHUE7E4N.js} +3 -2
- package/dist/{chunk-YQEAA6LT.js.map → chunk-QHUE7E4N.js.map} +1 -1
- package/dist/{chunk-OA6HFRQP.js → chunk-QMMCJGFI.js} +4 -3
- package/dist/{chunk-OA6HFRQP.js.map → chunk-QMMCJGFI.js.map} +1 -1
- package/dist/{chunk-YV4L3ILF.js → chunk-QV3DJVRZ.js} +3 -1
- package/dist/{chunk-YV4L3ILF.js.map → chunk-QV3DJVRZ.js.map} +1 -1
- package/dist/{chunk-447JLCBU.js → chunk-S2QH6EZ5.js} +3 -1
- package/dist/{chunk-447JLCBU.js.map → chunk-S2QH6EZ5.js.map} +1 -1
- package/dist/{chunk-PNY3JKBJ.js → chunk-SFH43JT2.js} +5 -4
- package/dist/{chunk-PNY3JKBJ.js.map → chunk-SFH43JT2.js.map} +1 -1
- package/dist/{chunk-AWZLIMKX.js → chunk-T46QZH3E.js} +3 -1
- package/dist/{chunk-AWZLIMKX.js.map → chunk-T46QZH3E.js.map} +1 -1
- package/dist/{chunk-5J4FOW6Q.js → chunk-TNEZNMSN.js} +3 -1
- package/dist/{chunk-5J4FOW6Q.js.map → chunk-TNEZNMSN.js.map} +1 -1
- package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
- package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
- package/dist/{chunk-H5X55XH7.js → chunk-UDPH5SLV.js} +4 -3
- package/dist/{chunk-H5X55XH7.js.map → chunk-UDPH5SLV.js.map} +1 -1
- package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
- package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
- package/dist/{chunk-5F4WR7X7.js → chunk-XS67YG5R.js} +3 -1
- package/dist/{chunk-5F4WR7X7.js.map → chunk-XS67YG5R.js.map} +1 -1
- package/dist/{chunk-TKOTKRWY.js → chunk-XTD7TZHW.js} +3 -1
- package/dist/{chunk-TKOTKRWY.js.map → chunk-XTD7TZHW.js.map} +1 -1
- package/dist/{chunk-A2PI6UMY.js → chunk-YSRBFJMQ.js} +3 -1
- package/dist/{chunk-A2PI6UMY.js.map → chunk-YSRBFJMQ.js.map} +1 -1
- package/dist/chunk-YVFRBXST.js +1420 -0
- package/dist/chunk-YVFRBXST.js.map +1 -0
- package/dist/{chunk-SCOTPE2I.js → chunk-YYLBXXTE.js} +3 -1
- package/dist/{chunk-SCOTPE2I.js.map → chunk-YYLBXXTE.js.map} +1 -1
- package/dist/{chunk-RHREZ7BO.js → chunk-ZUWF4NF7.js} +3 -1
- package/dist/{chunk-RHREZ7BO.js.map → chunk-ZUWF4NF7.js.map} +1 -1
- package/dist/clipboard.js +3 -2
- package/dist/components/composer-transcription-control.d.ts +4 -0
- package/dist/components/session-conversation.d.ts +6 -0
- package/dist/composer-voice-events.d.ts +8 -0
- package/dist/composer.js +15 -13
- package/dist/computer-viewer-ELNLZGHI.js +20 -0
- package/dist/connect.js +15 -12
- package/dist/connect.js.map +1 -1
- package/dist/desktop.js +6 -5
- package/dist/desktop.js.map +1 -1
- package/dist/diffs.js +2 -1
- package/dist/diffs.js.map +1 -1
- package/dist/editor.js +4 -3
- package/dist/editor.js.map +1 -1
- package/dist/embedded-voice-NIL4RDX3.js +69 -0
- package/dist/embedded-voice-NIL4RDX3.js.map +1 -0
- package/dist/{fleet-decision-row-YZ3ZKWMM.js → fleet-decision-row-SI63O5V4.js} +3 -1
- package/dist/{fleet-decision-row-YZ3ZKWMM.js.map → fleet-decision-row-SI63O5V4.js.map} +1 -1
- package/dist/hooks/use-client-config-flags.d.ts +6 -0
- package/dist/hooks/use-computer-session.d.ts +2 -0
- package/dist/hooks/use-realtime-voice-models.d.ts +9 -0
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/index.js +47 -45
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +14 -13
- package/dist/interaction.js.map +1 -1
- package/dist/{latest-question-GPYM2JNU.js → latest-question-2POFPYNB.js} +5 -4
- package/dist/{latest-question-GPYM2JNU.js.map → latest-question-2POFPYNB.js.map} +1 -1
- package/dist/machines.js +8 -7
- package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-DQ4DRNVT.js} +3 -1
- package/dist/{markdown-table-layout-QXSLK4BY.js.map → markdown-table-layout-DQ4DRNVT.js.map} +1 -1
- package/dist/model-policy-picker-menu-WRNSRFQC.js +15 -0
- package/dist/model-policy.js +2 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
- package/dist/{platform-activity-row-627BFZ46.js → platform-activity-row-PJJVATTZ.js} +3 -1
- package/dist/{platform-activity-row-627BFZ46.js.map → platform-activity-row-PJJVATTZ.js.map} +1 -1
- package/dist/{queue-surface-implementation-ZHFI5JBP.js → queue-surface-implementation-67FS7FUI.js} +10 -9
- package/dist/{queue-surface-implementation-ZHFI5JBP.js.map → queue-surface-implementation-67FS7FUI.js.map} +1 -1
- package/dist/realtime/embedded-voice.d.ts +20 -0
- package/dist/realtime.js +22 -1353
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-34CJJNOY.js +21 -0
- package/dist/session-ui.js +32 -30
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +10 -9
- package/dist/sites.js +2 -1
- package/dist/terminal.js +6 -5
- package/dist/terminal.js.map +1 -1
- package/dist/{timeline-annotation-markers-GNDHTGBD.js → timeline-annotation-markers-U3G66KUD.js} +5 -4
- package/dist/{timeline-annotation-markers-GNDHTGBD.js.map → timeline-annotation-markers-U3G66KUD.js.map} +1 -1
- package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-BI7QTPTZ.js} +4 -3
- package/dist/{timeline-annotation-selection-DMLMM2TX.js.map → timeline-annotation-selection-BI7QTPTZ.js.map} +1 -1
- package/dist/{timeline-annotations-dialog-ELRDBHTS.js → timeline-annotations-dialog-FOMHSDTE.js} +7 -6
- package/dist/{timeline-annotations-dialog-ELRDBHTS.js.map → timeline-annotations-dialog-FOMHSDTE.js.map} +1 -1
- package/dist/usage.js +6 -5
- package/dist/usage.js.map +1 -1
- package/dist/voice-recording-owner.d.ts +7 -0
- package/package.json +3 -3
- package/src/components/composer-transcription-control.tsx +109 -27
- package/src/components/computer-viewer.tsx +139 -30
- package/src/components/markdown.tsx +7 -2
- package/src/components/message-timeline.tsx +10 -1
- package/src/components/session-conversation.tsx +44 -0
- package/src/components/session-list.tsx +1 -1
- package/src/components/session-proxy-scope.tsx +26 -5
- package/src/composer-voice-events.ts +12 -0
- package/src/connection-discovery.tsx +4 -1
- package/src/hooks/use-browser-session.ts +445 -168
- package/src/hooks/use-client-config-flags.ts +8 -0
- package/src/hooks/use-computer-session.ts +334 -98
- package/src/hooks/use-goal.ts +12 -1
- package/src/hooks/use-realtime-voice-models.ts +67 -0
- package/src/hooks/use-voice-input.ts +109 -18
- package/src/realtime/embedded-voice.tsx +81 -0
- package/src/realtime/realtime-control.tsx +82 -17
- package/src/voice-recording-owner.ts +22 -0
- package/styles/compiled.css +77 -18
- package/styles/index.css +49 -0
- package/styles/responsive.css +61 -4
- package/styles/session-capability.css +1 -1
- package/dist/browser-viewer-SHYKQRNX.js +0 -16
- package/dist/chat-interactive-block-UGBTNB3L.js +0 -11
- package/dist/chunk-GYVRFZDY.js.map +0 -1
- package/dist/chunk-I7IWRQLN.js.map +0 -1
- package/dist/chunk-IWIDV7SB.js +0 -1
- package/dist/chunk-LJ2UTJJE.js.map +0 -1
- package/dist/chunk-LN6TCXD3.js.map +0 -1
- package/dist/computer-viewer-6SRGWRUX.js +0 -19
- package/dist/model-policy-picker-menu-DXHUL73H.js +0 -14
- package/dist/sandbox-files-GORZOUUJ.js +0 -20
- /package/dist/{browser-viewer-SHYKQRNX.js.map → browser-viewer-5EEAS3IU.js.map} +0 -0
- /package/dist/{chat-interactive-block-UGBTNB3L.js.map → chat-interactive-block-ZFHOKTMS.js.map} +0 -0
- /package/dist/{chunk-IWIDV7SB.js.map → chunk-M357MHH3.js.map} +0 -0
- /package/dist/{computer-viewer-6SRGWRUX.js.map → computer-viewer-ELNLZGHI.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-DXHUL73H.js.map → model-policy-picker-menu-WRNSRFQC.js.map} +0 -0
- /package/dist/{sandbox-files-GORZOUUJ.js.map → sandbox-files-34CJJNOY.js.map} +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
// src/usage/allowance-copy.ts
|
|
2
4
|
function formatAllowanceDate(iso, now = /* @__PURE__ */ new Date()) {
|
|
3
5
|
const date = new Date(iso);
|
|
@@ -38,4 +40,4 @@ export {
|
|
|
38
40
|
allowanceLabels,
|
|
39
41
|
allowanceResetSentence
|
|
40
42
|
};
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-GC3PH6N7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/usage/allowance-copy.ts"],"sourcesContent":["// Shared, replaceable words for usage allowances. The timeline refusal row\n// (session graph) and the opt-in `@opengeni/react/usage` surfaces both read\n// these, so a host that renames \"workspace\" or \"admin\" does it once.\n//\n// Product rule: never show raw credit amounts here. Hosts that want money or\n// plan multiples opt in with `formatAmount` on the meter components.\n\n/** Which ceiling ran out: the shared workspace pool, or one member's share of it. */\nexport type AllowanceScope = \"workspace\" | \"member\";\n\nexport type AllowanceLabels = {\n /** \"Usage limit reached\" for a member ceiling. */\n memberLimitReachedTitle: string;\n /** \"Workspace usage limit reached\" for the shared pool. */\n workspaceLimitReachedTitle: string;\n /** Who can fix a member ceiling. */\n memberRemedy: string;\n /** Who can fix the workspace pool. */\n workspaceRemedy: string;\n /** \"Resets Nov 1\". `date` is already formatted by `formatDate`. */\n resets: (date: string) => string;\n /** Shown when a ceiling has no automatic reset. */\n noReset: string;\n /** Formats a reset instant for `resets`. Defaults to a short local date. */\n formatDate: (iso: string) => string;\n};\n\nexport function formatAllowanceDate(iso: string, now: Date = new Date()): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n ...(date.getFullYear() === now.getFullYear() ? {} : { year: \"numeric\" }),\n }).format(date);\n}\n\n/** Full local date and time, for a title/tooltip next to the short date. */\nexport function formatAllowanceInstant(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return new Intl.DateTimeFormat(undefined, { dateStyle: \"medium\", timeStyle: \"short\" }).format(\n date,\n );\n}\n\nexport const DEFAULT_ALLOWANCE_LABELS: AllowanceLabels = {\n memberLimitReachedTitle: \"Usage limit reached\",\n workspaceLimitReachedTitle: \"Workspace usage limit reached\",\n memberRemedy: \"A workspace admin can raise this limit.\",\n workspaceRemedy: \"An organization admin can raise the workspace budget.\",\n resets: (date) => `Resets ${date}.`,\n noReset: \"It doesn't reset automatically.\",\n formatDate: (iso) => formatAllowanceDate(iso),\n};\n\nexport function allowanceLabels(overrides?: Partial<AllowanceLabels>): AllowanceLabels {\n return overrides ? { ...DEFAULT_ALLOWANCE_LABELS, ...overrides } : DEFAULT_ALLOWANCE_LABELS;\n}\n\n/** \"Resets Nov 1.\" or the no-reset sentence. */\nexport function allowanceResetSentence(labels: AllowanceLabels, resetsAt: string | null): string {\n return resetsAt === null ? labels.noReset : labels.resets(labels.formatDate(resetsAt));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/usage/allowance-copy.ts"],"sourcesContent":["// Shared, replaceable words for usage allowances. The timeline refusal row\n// (session graph) and the opt-in `@opengeni/react/usage` surfaces both read\n// these, so a host that renames \"workspace\" or \"admin\" does it once.\n//\n// Product rule: never show raw credit amounts here. Hosts that want money or\n// plan multiples opt in with `formatAmount` on the meter components.\n\n/** Which ceiling ran out: the shared workspace pool, or one member's share of it. */\nexport type AllowanceScope = \"workspace\" | \"member\";\n\nexport type AllowanceLabels = {\n /** \"Usage limit reached\" for a member ceiling. */\n memberLimitReachedTitle: string;\n /** \"Workspace usage limit reached\" for the shared pool. */\n workspaceLimitReachedTitle: string;\n /** Who can fix a member ceiling. */\n memberRemedy: string;\n /** Who can fix the workspace pool. */\n workspaceRemedy: string;\n /** \"Resets Nov 1\". `date` is already formatted by `formatDate`. */\n resets: (date: string) => string;\n /** Shown when a ceiling has no automatic reset. */\n noReset: string;\n /** Formats a reset instant for `resets`. Defaults to a short local date. */\n formatDate: (iso: string) => string;\n};\n\nexport function formatAllowanceDate(iso: string, now: Date = new Date()): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n ...(date.getFullYear() === now.getFullYear() ? {} : { year: \"numeric\" }),\n }).format(date);\n}\n\n/** Full local date and time, for a title/tooltip next to the short date. */\nexport function formatAllowanceInstant(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return new Intl.DateTimeFormat(undefined, { dateStyle: \"medium\", timeStyle: \"short\" }).format(\n date,\n );\n}\n\nexport const DEFAULT_ALLOWANCE_LABELS: AllowanceLabels = {\n memberLimitReachedTitle: \"Usage limit reached\",\n workspaceLimitReachedTitle: \"Workspace usage limit reached\",\n memberRemedy: \"A workspace admin can raise this limit.\",\n workspaceRemedy: \"An organization admin can raise the workspace budget.\",\n resets: (date) => `Resets ${date}.`,\n noReset: \"It doesn't reset automatically.\",\n formatDate: (iso) => formatAllowanceDate(iso),\n};\n\nexport function allowanceLabels(overrides?: Partial<AllowanceLabels>): AllowanceLabels {\n return overrides ? { ...DEFAULT_ALLOWANCE_LABELS, ...overrides } : DEFAULT_ALLOWANCE_LABELS;\n}\n\n/** \"Resets Nov 1.\" or the no-reset sentence. */\nexport function allowanceResetSentence(labels: AllowanceLabels, resetsAt: string | null): string {\n return resetsAt === null ? labels.noReset : labels.resets(labels.formatDate(resetsAt));\n}\n"],"mappings":";;;AA2BO,SAAS,oBAAoB,KAAa,MAAY,oBAAI,KAAK,GAAW;AAC/E,QAAM,OAAO,IAAI,KAAK,GAAG;AACzB,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,OAAO;AAAA,IACP,KAAK;AAAA,IACL,GAAI,KAAK,YAAY,MAAM,IAAI,YAAY,IAAI,CAAC,IAAI,EAAE,MAAM,UAAU;AAAA,EACxE,CAAC,EAAE,OAAO,IAAI;AAChB;AAGO,SAAS,uBAAuB,KAAqB;AAC1D,QAAM,OAAO,IAAI,KAAK,GAAG;AACzB,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,IAAI,KAAK,eAAe,QAAW,EAAE,WAAW,UAAU,WAAW,QAAQ,CAAC,EAAE;AAAA,IACrF;AAAA,EACF;AACF;AAEO,IAAM,2BAA4C;AAAA,EACvD,yBAAyB;AAAA,EACzB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,QAAQ,CAAC,SAAS,UAAU,IAAI;AAAA,EAChC,SAAS;AAAA,EACT,YAAY,CAAC,QAAQ,oBAAoB,GAAG;AAC9C;AAEO,SAAS,gBAAgB,WAAuD;AACrF,SAAO,YAAY,EAAE,GAAG,0BAA0B,GAAG,UAAU,IAAI;AACrE;AAGO,SAAS,uBAAuB,QAAyB,UAAiC;AAC/F,SAAO,aAAa,OAAO,OAAO,UAAU,OAAO,OAAO,OAAO,WAAW,QAAQ,CAAC;AACvF;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import {
|
|
2
3
|
mcpToolLeaf
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-T46QZH3E.js";
|
|
4
5
|
|
|
5
6
|
// src/timeline/presented-image.ts
|
|
6
7
|
import { normalizeMcpOutput, parseSandboxFileArtifactReceipt } from "@opengeni/sdk";
|
|
@@ -113,4 +114,4 @@ export {
|
|
|
113
114
|
timelineGroupContainsPresentedImage,
|
|
114
115
|
useRetainedImageObjectUrl
|
|
115
116
|
};
|
|
116
|
-
//# sourceMappingURL=chunk-
|
|
117
|
+
//# sourceMappingURL=chunk-HXYOSSQO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/timeline/presented-image.ts","../src/timeline/retained-image.ts"],"sourcesContent":["import { normalizeMcpOutput, parseSandboxFileArtifactReceipt } from \"@opengeni/sdk\";\nimport { mcpToolLeaf } from \"./tool-display-name\";\nimport type { ActivityItem, TimelineGroup } from \"./types\";\n\n/*\n * Pure presentation facts shared by the projection and the renderers. Kept\n * free of React so the session-only entry can inspect primary output without pulling\n * in rendering code.\n */\n\n/** Shared browser preview allowlist; other published files remain downloads. */\nexport function isRetainedImageContentType(contentType: string): boolean {\n return [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/avif\",\n \"image/svg+xml\",\n ].includes(contentType);\n}\n\n/** Deliberately published images are primary output, not incidental screenshots. */\nexport function activityPresentsImage(items: readonly ActivityItem[]): boolean {\n return items.some((item) => {\n if (item.kind !== \"tool-call\") return false;\n const name = mcpToolLeaf(item.name);\n if (name === \"generate_image\" || name === \"image_generation_call\") return true;\n if (item.status !== \"complete\" || name !== \"sandbox_file_publish\") return false;\n const output = normalizeMcpOutput(item.output);\n if (output.isError) return false;\n const receipt = parseSandboxFileArtifactReceipt(output.text);\n return receipt !== null && isRetainedImageContentType(receipt.artifact.contentType);\n });\n}\n\nexport function timelineGroupContainsPresentedImage(group: TimelineGroup): boolean {\n switch (group.kind) {\n case \"item\":\n return false;\n case \"activity\":\n return (\n activityPresentsImage(group.items) ||\n (group.work?.details?.some(timelineGroupContainsPresentedImage) ?? false)\n );\n case \"turn\":\n return group.groups.some(timelineGroupContainsPresentedImage);\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { RetainedArtifactReference } from \"@opengeni/sdk\";\nimport type { ToolRendererProps } from \"./registry\";\ntype RetainedImageState =\n | { kind: \"loading\" }\n | { kind: \"ready\"; url: string }\n | { kind: \"unavailable\"; label: string }\n | { kind: \"error\"; message: string };\n\nexport { isRetainedImageContentType } from \"./presented-image\";\n\nexport function useRetainedImageObjectUrl(\n artifact: RetainedArtifactReference,\n load: ToolRendererProps[\"loadRetainedArtifact\"],\n): RetainedImageState & { retry: () => void } {\n const [state, setState] = useState<RetainedImageState>({ kind: \"loading\" });\n const [retrievalAttempt, setRetrievalAttempt] = useState(0);\n // Retry only the immutable retained artifact; never issue a new capture or\n // rewrite the tool receipt/model history to repair a human preview.\n const retry = useCallback(() => setRetrievalAttempt((attempt) => attempt + 1), []);\n // Function outputs are commonly serialized JSON. Parsing them creates a new\n // object on every render, so depend on the immutable wire value rather than\n // object identity; otherwise the loader can refetch after its own setState.\n const artifactValue = retainedArtifactValue(artifact);\n const stableArtifactRef = useRef({ value: artifactValue, artifact });\n if (stableArtifactRef.current.value !== artifactValue) {\n stableArtifactRef.current = { value: artifactValue, artifact };\n }\n const stableArtifact = stableArtifactRef.current.artifact;\n useEffect(() => {\n if (!load) {\n setState({ kind: \"unavailable\", label: \"retrieval is not configured\" });\n return;\n }\n const controller = new AbortController();\n let objectUrl: string | null = null;\n setState({ kind: \"loading\" });\n void load(stableArtifact, controller.signal)\n .then((source) => {\n if (controller.signal.aborted) return;\n if (!source) {\n setState({ kind: \"unavailable\", label: \"bytes are unavailable\" });\n return;\n }\n if (!(source instanceof Uint8Array)) {\n if (!source.url.trim()) {\n setState({ kind: \"unavailable\", label: \"URL is unavailable\" });\n return;\n }\n setState({ kind: \"ready\", url: source.url });\n return;\n }\n objectUrl = URL.createObjectURL(\n new Blob([source as unknown as BlobPart], { type: stableArtifact.contentType }),\n );\n setState({ kind: \"ready\", url: objectUrl });\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n const status =\n error && typeof error === \"object\" && \"status\" in error\n ? Number((error as { status?: unknown }).status)\n : null;\n setState(\n status === 404\n ? { kind: \"unavailable\", label: \"deleted\" }\n : status === 410\n ? { kind: \"unavailable\", label: \"expired or unavailable\" }\n : { kind: \"error\", message: \"retrieval failed\" },\n );\n });\n return () => {\n controller.abort();\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n };\n }, [stableArtifact, load, retrievalAttempt]);\n return { ...state, retry };\n}\n\nfunction retainedArtifactValue(artifact: RetainedArtifactReference): string {\n return [\n artifact.artifactId,\n artifact.kind,\n artifact.contentType,\n artifact.originalBytes,\n artifact.sha256,\n artifact.retainedAt,\n artifact.dimensions?.width ?? \"\",\n artifact.dimensions?.height ?? \"\",\n artifact.retention.policy,\n artifact.retention.expiresAt ?? \"\",\n artifact.retrieval.method,\n artifact.retrieval.path,\n artifact.retrieval.acceptRanges,\n artifact.retrieval.maxRangeBytes,\n ].join(\"\\0\");\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/timeline/presented-image.ts","../src/timeline/retained-image.ts"],"sourcesContent":["import { normalizeMcpOutput, parseSandboxFileArtifactReceipt } from \"@opengeni/sdk\";\nimport { mcpToolLeaf } from \"./tool-display-name\";\nimport type { ActivityItem, TimelineGroup } from \"./types\";\n\n/*\n * Pure presentation facts shared by the projection and the renderers. Kept\n * free of React so the session-only entry can inspect primary output without pulling\n * in rendering code.\n */\n\n/** Shared browser preview allowlist; other published files remain downloads. */\nexport function isRetainedImageContentType(contentType: string): boolean {\n return [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/avif\",\n \"image/svg+xml\",\n ].includes(contentType);\n}\n\n/** Deliberately published images are primary output, not incidental screenshots. */\nexport function activityPresentsImage(items: readonly ActivityItem[]): boolean {\n return items.some((item) => {\n if (item.kind !== \"tool-call\") return false;\n const name = mcpToolLeaf(item.name);\n if (name === \"generate_image\" || name === \"image_generation_call\") return true;\n if (item.status !== \"complete\" || name !== \"sandbox_file_publish\") return false;\n const output = normalizeMcpOutput(item.output);\n if (output.isError) return false;\n const receipt = parseSandboxFileArtifactReceipt(output.text);\n return receipt !== null && isRetainedImageContentType(receipt.artifact.contentType);\n });\n}\n\nexport function timelineGroupContainsPresentedImage(group: TimelineGroup): boolean {\n switch (group.kind) {\n case \"item\":\n return false;\n case \"activity\":\n return (\n activityPresentsImage(group.items) ||\n (group.work?.details?.some(timelineGroupContainsPresentedImage) ?? false)\n );\n case \"turn\":\n return group.groups.some(timelineGroupContainsPresentedImage);\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { RetainedArtifactReference } from \"@opengeni/sdk\";\nimport type { ToolRendererProps } from \"./registry\";\ntype RetainedImageState =\n | { kind: \"loading\" }\n | { kind: \"ready\"; url: string }\n | { kind: \"unavailable\"; label: string }\n | { kind: \"error\"; message: string };\n\nexport { isRetainedImageContentType } from \"./presented-image\";\n\nexport function useRetainedImageObjectUrl(\n artifact: RetainedArtifactReference,\n load: ToolRendererProps[\"loadRetainedArtifact\"],\n): RetainedImageState & { retry: () => void } {\n const [state, setState] = useState<RetainedImageState>({ kind: \"loading\" });\n const [retrievalAttempt, setRetrievalAttempt] = useState(0);\n // Retry only the immutable retained artifact; never issue a new capture or\n // rewrite the tool receipt/model history to repair a human preview.\n const retry = useCallback(() => setRetrievalAttempt((attempt) => attempt + 1), []);\n // Function outputs are commonly serialized JSON. Parsing them creates a new\n // object on every render, so depend on the immutable wire value rather than\n // object identity; otherwise the loader can refetch after its own setState.\n const artifactValue = retainedArtifactValue(artifact);\n const stableArtifactRef = useRef({ value: artifactValue, artifact });\n if (stableArtifactRef.current.value !== artifactValue) {\n stableArtifactRef.current = { value: artifactValue, artifact };\n }\n const stableArtifact = stableArtifactRef.current.artifact;\n useEffect(() => {\n if (!load) {\n setState({ kind: \"unavailable\", label: \"retrieval is not configured\" });\n return;\n }\n const controller = new AbortController();\n let objectUrl: string | null = null;\n setState({ kind: \"loading\" });\n void load(stableArtifact, controller.signal)\n .then((source) => {\n if (controller.signal.aborted) return;\n if (!source) {\n setState({ kind: \"unavailable\", label: \"bytes are unavailable\" });\n return;\n }\n if (!(source instanceof Uint8Array)) {\n if (!source.url.trim()) {\n setState({ kind: \"unavailable\", label: \"URL is unavailable\" });\n return;\n }\n setState({ kind: \"ready\", url: source.url });\n return;\n }\n objectUrl = URL.createObjectURL(\n new Blob([source as unknown as BlobPart], { type: stableArtifact.contentType }),\n );\n setState({ kind: \"ready\", url: objectUrl });\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n const status =\n error && typeof error === \"object\" && \"status\" in error\n ? Number((error as { status?: unknown }).status)\n : null;\n setState(\n status === 404\n ? { kind: \"unavailable\", label: \"deleted\" }\n : status === 410\n ? { kind: \"unavailable\", label: \"expired or unavailable\" }\n : { kind: \"error\", message: \"retrieval failed\" },\n );\n });\n return () => {\n controller.abort();\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n };\n }, [stableArtifact, load, retrievalAttempt]);\n return { ...state, retry };\n}\n\nfunction retainedArtifactValue(artifact: RetainedArtifactReference): string {\n return [\n artifact.artifactId,\n artifact.kind,\n artifact.contentType,\n artifact.originalBytes,\n artifact.sha256,\n artifact.retainedAt,\n artifact.dimensions?.width ?? \"\",\n artifact.dimensions?.height ?? \"\",\n artifact.retention.policy,\n artifact.retention.expiresAt ?? \"\",\n artifact.retrieval.method,\n artifact.retrieval.path,\n artifact.retrieval.acceptRanges,\n artifact.retrieval.maxRangeBytes,\n ].join(\"\\0\");\n}\n"],"mappings":"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","names":[]}
|