@opengeni/react 7.1.0 → 7.1.2-canary.36079201993001
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/dist/artifacts-document.js +2 -2
- package/dist/artifacts-presentation.js +2 -2
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.js +4 -4
- package/dist/{browser-viewer-MN7MOYQT.js → browser-viewer-K2H3SLIW.js} +2 -2
- package/dist/{chunk-4ACTWOOW.js → chunk-6N3AZUOV.js} +31 -14
- package/dist/chunk-6N3AZUOV.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-6P7T4RPE.js} +7 -3
- package/dist/chunk-6P7T4RPE.js.map +1 -0
- package/dist/{chunk-SHRCATV6.js → chunk-7J4DUR3E.js} +12 -5
- package/dist/chunk-7J4DUR3E.js.map +1 -0
- package/dist/{chunk-ZC2DK5SC.js → chunk-AWIX4UAC.js} +88 -7
- package/dist/chunk-AWIX4UAC.js.map +1 -0
- package/dist/{chunk-UQS7BGNQ.js → chunk-ETA37UZ7.js} +82 -11
- package/dist/chunk-ETA37UZ7.js.map +1 -0
- package/dist/{chunk-VR4Z73EU.js → chunk-G2SCXNXW.js} +9 -2
- package/dist/chunk-G2SCXNXW.js.map +1 -0
- package/dist/{chunk-5UONOQ3Y.js → chunk-K3MQZO7R.js} +150 -67
- package/dist/chunk-K3MQZO7R.js.map +1 -0
- package/dist/{chunk-OWHPKAOV.js → chunk-L6MYP3QU.js} +4 -2
- package/dist/{chunk-OWHPKAOV.js.map → chunk-L6MYP3QU.js.map} +1 -1
- package/dist/{chunk-VI7HELBI.js → chunk-SJ5HE4ZA.js} +21 -2
- package/dist/chunk-SJ5HE4ZA.js.map +1 -0
- package/dist/{chunk-XMXRI5JK.js → chunk-ZZ4744OZ.js} +128 -71
- package/dist/chunk-ZZ4744OZ.js.map +1 -0
- package/dist/components/artifacts/artifact-surface.d.ts +3 -1
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +1 -1
- package/dist/components/artifacts/editable-spreadsheet.d.ts +2 -1
- package/dist/components/artifacts/presentation-editor.d.ts +4 -2
- package/dist/components/browser-viewer.d.ts +4 -1
- package/dist/components/markdown.d.ts +2 -0
- package/dist/components/session-capability-frame.d.ts +5 -1
- package/dist/composer.js +1 -1
- package/dist/connect.js +2 -2
- package/dist/hooks/use-browser-session.d.ts +3 -0
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +1 -1
- package/dist/session-ui.js +4 -4
- package/dist/session.js +1 -1
- package/dist/timeline/types.d.ts +2 -0
- package/package.json +3 -3
- package/src/components/artifacts/artifact-surface.tsx +39 -19
- package/src/components/artifacts/document-editor.tsx +77 -9
- package/src/components/artifacts/editable-document.tsx +3 -0
- package/src/components/artifacts/editable-presentation.tsx +3 -0
- package/src/components/artifacts/editable-spreadsheet.tsx +3 -0
- package/src/components/artifacts/presentation-editor.tsx +6 -0
- package/src/components/browser-viewer.tsx +11 -5
- package/src/components/composer-transcription-control.tsx +4 -2
- package/src/components/composer.tsx +20 -9
- package/src/components/markdown.tsx +9 -2
- package/src/components/sandbox-workspace.tsx +1 -0
- package/src/components/session-capability-frame.tsx +11 -3
- package/src/components/session-mcp-capability-card.tsx +174 -70
- package/src/hooks/use-browser-frame-stream.ts +3 -1
- package/src/hooks/use-browser-session.ts +107 -3
- package/src/hooks/use-voice-input.ts +12 -1
- package/src/timeline/compaction-copy.ts +2 -0
- package/src/timeline/parsers.ts +2 -2
- package/src/timeline/projection.ts +31 -5
- package/src/timeline/tool-renderers.tsx +105 -16
- package/src/timeline/turn-summary.tsx +10 -2
- package/src/timeline/types.ts +2 -0
- package/styles/compiled.css +6 -0
- package/styles/session-capability.css +2 -0
- package/dist/chunk-4ACTWOOW.js.map +0 -1
- package/dist/chunk-5UONOQ3Y.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-SHRCATV6.js.map +0 -1
- package/dist/chunk-UQS7BGNQ.js.map +0 -1
- package/dist/chunk-VI7HELBI.js.map +0 -1
- package/dist/chunk-VR4Z73EU.js.map +0 -1
- package/dist/chunk-XMXRI5JK.js.map +0 -1
- package/dist/chunk-ZC2DK5SC.js.map +0 -1
- /package/dist/{browser-viewer-MN7MOYQT.js.map → browser-viewer-K2H3SLIW.js.map} +0 -0
package/dist/interaction.js
CHANGED
package/dist/session-ui.js
CHANGED
|
@@ -19,22 +19,22 @@ import {
|
|
|
19
19
|
setStartupDetails,
|
|
20
20
|
useStartupDetails,
|
|
21
21
|
userMessageLikelyNeedsDisclosure
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-AWIX4UAC.js";
|
|
23
23
|
import "./chunk-GEN54DU5.js";
|
|
24
24
|
import "./chunk-GBPCZH3Y.js";
|
|
25
25
|
import "./chunk-ZYRGEKWS.js";
|
|
26
26
|
import "./chunk-WYWRYUNQ.js";
|
|
27
27
|
import {
|
|
28
28
|
createOlderHistoryLoadReceipt
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-SJ5HE4ZA.js";
|
|
30
30
|
import "./chunk-PAJU5KKL.js";
|
|
31
|
-
import "./chunk-
|
|
31
|
+
import "./chunk-6N3AZUOV.js";
|
|
32
32
|
import "./chunk-3LL47F4U.js";
|
|
33
33
|
import "./chunk-AKOMC3VO.js";
|
|
34
34
|
import "./chunk-IOLPHOF4.js";
|
|
35
35
|
import "./chunk-KZ73RL76.js";
|
|
36
36
|
import "./chunk-NEXLLTP4.js";
|
|
37
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-7J4DUR3E.js";
|
|
38
38
|
import "./chunk-2VHARTBL.js";
|
|
39
39
|
import "./chunk-BRM6FVZA.js";
|
|
40
40
|
import "./chunk-VZTQ73XT.js";
|
package/dist/session.js
CHANGED
package/dist/timeline/types.d.ts
CHANGED
|
@@ -375,6 +375,8 @@ export type AuthNeededItem = {
|
|
|
375
375
|
authorizationUrl: string | null;
|
|
376
376
|
/** Agent-selected catalog recommendation. The host still owns authorization. */
|
|
377
377
|
capability?: NonNullable<ToolAuthNeededPayload["capability"]> | null | undefined;
|
|
378
|
+
/** Human-reviewed custom integration proposal. Never treated as catalog authority. */
|
|
379
|
+
setupRequest?: ToolAuthNeededPayload["setupRequest"] | null | undefined;
|
|
378
380
|
occurredAt: string;
|
|
379
381
|
};
|
|
380
382
|
export type TurnOutcome = "complete" | "failed" | "cancelled";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.2-canary.36079201993001",
|
|
4
4
|
"description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -133,8 +133,8 @@
|
|
|
133
133
|
"@dnd-kit/utilities": "3.2.2",
|
|
134
134
|
"@fontsource-variable/noto-sans-arabic": "5.2.10",
|
|
135
135
|
"@fontsource-variable/noto-sans-jp": "5.2.10",
|
|
136
|
-
"@opengeni/connect": "^0.3.0",
|
|
137
|
-
"@opengeni/sdk": "^7.1.
|
|
136
|
+
"@opengeni/connect": "^0.3.0-canary.36079201993001",
|
|
137
|
+
"@opengeni/sdk": "^7.1.1-canary.36079201993001",
|
|
138
138
|
"clsx": "^2.1.1",
|
|
139
139
|
"dequal": "2.0.3",
|
|
140
140
|
"lucide-react": "^1.8.0",
|
|
@@ -13,6 +13,8 @@ export type ArtifactModality = "spreadsheet" | "document" | "presentation";
|
|
|
13
13
|
export type ArtifactSurfaceProps = {
|
|
14
14
|
modality: ArtifactModality;
|
|
15
15
|
title: string;
|
|
16
|
+
/** An embedding host may already provide the artifact title and navigation. */
|
|
17
|
+
showHeader?: boolean | undefined;
|
|
16
18
|
subtitle?: ReactNode | undefined;
|
|
17
19
|
actions?: ReactNode | undefined;
|
|
18
20
|
children: ReactNode;
|
|
@@ -46,6 +48,7 @@ function ModalityIcon({ modality }: { modality: ArtifactModality }) {
|
|
|
46
48
|
export function ArtifactSurface({
|
|
47
49
|
modality,
|
|
48
50
|
title,
|
|
51
|
+
showHeader = true,
|
|
49
52
|
subtitle,
|
|
50
53
|
actions,
|
|
51
54
|
children,
|
|
@@ -63,25 +66,42 @@ export function ArtifactSurface({
|
|
|
63
66
|
className,
|
|
64
67
|
)}
|
|
65
68
|
>
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
69
|
+
{showHeader ? (
|
|
70
|
+
<header className="flex min-h-11 shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-2 px-3">
|
|
71
|
+
<span
|
|
72
|
+
aria-hidden
|
|
73
|
+
className="grid size-7 shrink-0 place-items-center rounded-og-sm bg-og-surface-3 text-og-fg-muted"
|
|
74
|
+
>
|
|
75
|
+
<ModalityIcon modality={modality} />
|
|
76
|
+
</span>
|
|
77
|
+
<div className="min-w-0 flex-1">
|
|
78
|
+
<h2 className="truncate text-og-base font-medium text-og-fg">{title}</h2>
|
|
79
|
+
{subtitle ? (
|
|
80
|
+
<div className="truncate text-og-xs text-og-fg-muted">{subtitle}</div>
|
|
81
|
+
) : null}
|
|
82
|
+
</div>
|
|
83
|
+
{busy ? (
|
|
84
|
+
<LoaderCircleIcon
|
|
85
|
+
aria-label="Updating artifact"
|
|
86
|
+
className="size-4 shrink-0 animate-spin text-og-fg-muted"
|
|
87
|
+
/>
|
|
88
|
+
) : null}
|
|
89
|
+
{actions ? <div className="flex shrink-0 items-center gap-1">{actions}</div> : null}
|
|
90
|
+
</header>
|
|
91
|
+
) : (
|
|
92
|
+
<>
|
|
93
|
+
{typeof subtitle === "string" || typeof subtitle === "number" ? (
|
|
94
|
+
<span role="status" className="sr-only">
|
|
95
|
+
{subtitle}
|
|
96
|
+
</span>
|
|
97
|
+
) : null}
|
|
98
|
+
{actions ? (
|
|
99
|
+
<div className="flex shrink-0 items-center justify-end gap-1 border-b border-og-border px-3 py-1">
|
|
100
|
+
{actions}
|
|
101
|
+
</div>
|
|
102
|
+
) : null}
|
|
103
|
+
</>
|
|
104
|
+
)}
|
|
85
105
|
|
|
86
106
|
<div className="min-h-0 min-w-0 flex-1">{children}</div>
|
|
87
107
|
|
|
@@ -204,6 +204,7 @@ export type DocumentProjectionArtifactSurfaceProps = Omit<
|
|
|
204
204
|
"ariaLabel" | "className"
|
|
205
205
|
> & {
|
|
206
206
|
title: string;
|
|
207
|
+
showHeader?: boolean | undefined;
|
|
207
208
|
subtitle?: ReactNode | undefined;
|
|
208
209
|
busy?: boolean | undefined;
|
|
209
210
|
className?: string | undefined;
|
|
@@ -212,6 +213,7 @@ export type DocumentProjectionArtifactSurfaceProps = Omit<
|
|
|
212
213
|
|
|
213
214
|
export type DocumentArtifactSurfaceProps = Omit<DocumentEditorProps, "ariaLabel" | "className"> & {
|
|
214
215
|
title: string;
|
|
216
|
+
showHeader?: boolean | undefined;
|
|
215
217
|
subtitle?: ReactNode | undefined;
|
|
216
218
|
busy?: boolean | undefined;
|
|
217
219
|
className?: string | undefined;
|
|
@@ -907,10 +909,27 @@ function DocumentEditorCore({
|
|
|
907
909
|
</div>
|
|
908
910
|
</div>
|
|
909
911
|
) : (
|
|
910
|
-
<div
|
|
912
|
+
<div
|
|
913
|
+
className="relative min-w-full"
|
|
914
|
+
style={{
|
|
915
|
+
height: axis.total,
|
|
916
|
+
minWidth:
|
|
917
|
+
layout === "paginated"
|
|
918
|
+
? pages.reduce(
|
|
919
|
+
(width, page) =>
|
|
920
|
+
Math.max(
|
|
921
|
+
width,
|
|
922
|
+
page.page.widthPt * POINT_TO_CSS_PIXEL * page.renderScale + 32,
|
|
923
|
+
),
|
|
924
|
+
0,
|
|
925
|
+
)
|
|
926
|
+
: undefined,
|
|
927
|
+
}}
|
|
928
|
+
>
|
|
911
929
|
{mountedIndexes.map((pageIndex) => {
|
|
912
930
|
const page = pages[pageIndex]!;
|
|
913
931
|
const top = axis.offsets[pageIndex]!;
|
|
932
|
+
const pageWidth = page.page.widthPt * POINT_TO_CSS_PIXEL * page.renderScale;
|
|
914
933
|
return (
|
|
915
934
|
<article
|
|
916
935
|
key={page.key}
|
|
@@ -923,19 +942,23 @@ function DocumentEditorCore({
|
|
|
923
942
|
className={cn(
|
|
924
943
|
"absolute overflow-hidden",
|
|
925
944
|
layout === "paginated"
|
|
926
|
-
? "
|
|
945
|
+
? "border shadow-og-sm"
|
|
927
946
|
: "left-0 right-0 border-b border-og-border bg-og-surface-1 text-og-fg",
|
|
928
947
|
)}
|
|
929
948
|
style={{
|
|
930
949
|
top,
|
|
950
|
+
// Center against the visible viewport, not the shared width
|
|
951
|
+
// reserved for the widest section in this document.
|
|
952
|
+
left:
|
|
953
|
+
layout === "paginated"
|
|
954
|
+
? Math.max(16, (measuredViewport.width - pageWidth) / 2)
|
|
955
|
+
: undefined,
|
|
931
956
|
color: layout === "paginated" ? "#171717" : undefined,
|
|
932
957
|
backgroundColor: layout === "paginated" ? "#fff" : undefined,
|
|
933
958
|
borderColor: layout === "paginated" ? "#0000001a" : undefined,
|
|
934
|
-
width:
|
|
935
|
-
layout === "paginated"
|
|
936
|
-
? page.page.widthPt * POINT_TO_CSS_PIXEL * page.renderScale
|
|
937
|
-
: undefined,
|
|
959
|
+
width: layout === "paginated" ? pageWidth : undefined,
|
|
938
960
|
height: page.height,
|
|
961
|
+
containerType: layout === "continuous" ? "inline-size" : undefined,
|
|
939
962
|
}}
|
|
940
963
|
>
|
|
941
964
|
<MeasuredPageBody
|
|
@@ -998,6 +1021,7 @@ function DocumentEditorCore({
|
|
|
998
1021
|
export function DocumentArtifactSurface({
|
|
999
1022
|
document,
|
|
1000
1023
|
title,
|
|
1024
|
+
showHeader,
|
|
1001
1025
|
subtitle,
|
|
1002
1026
|
busy,
|
|
1003
1027
|
className,
|
|
@@ -1008,6 +1032,7 @@ export function DocumentArtifactSurface({
|
|
|
1008
1032
|
<ArtifactSurface
|
|
1009
1033
|
modality="document"
|
|
1010
1034
|
title={title}
|
|
1035
|
+
showHeader={showHeader}
|
|
1011
1036
|
subtitle={subtitle}
|
|
1012
1037
|
busy={busy}
|
|
1013
1038
|
className={className}
|
|
@@ -1026,6 +1051,7 @@ export function DocumentArtifactSurface({
|
|
|
1026
1051
|
export function DocumentProjectionArtifactSurface({
|
|
1027
1052
|
projection,
|
|
1028
1053
|
title,
|
|
1054
|
+
showHeader,
|
|
1029
1055
|
subtitle,
|
|
1030
1056
|
busy,
|
|
1031
1057
|
className,
|
|
@@ -1036,6 +1062,7 @@ export function DocumentProjectionArtifactSurface({
|
|
|
1036
1062
|
<ArtifactSurface
|
|
1037
1063
|
modality="document"
|
|
1038
1064
|
title={title}
|
|
1065
|
+
showHeader={showHeader}
|
|
1039
1066
|
subtitle={subtitle}
|
|
1040
1067
|
busy={busy}
|
|
1041
1068
|
className={className}
|
|
@@ -1382,11 +1409,12 @@ function DocumentTableView({
|
|
|
1382
1409
|
viewBlockId: string;
|
|
1383
1410
|
}) {
|
|
1384
1411
|
const columnWidths = table.style.columnWidthsPt;
|
|
1412
|
+
const headerColor = tableHeaderTextColor(table.style.headerFill);
|
|
1385
1413
|
return (
|
|
1386
1414
|
<div
|
|
1387
1415
|
data-og-document-block={viewBlockId}
|
|
1388
1416
|
data-og-block-kind="table"
|
|
1389
|
-
className="overflow-x-auto py-2"
|
|
1417
|
+
className="w-full max-w-full overflow-x-auto py-2"
|
|
1390
1418
|
>
|
|
1391
1419
|
<table
|
|
1392
1420
|
className="w-full border-collapse text-left"
|
|
@@ -1422,6 +1450,8 @@ function DocumentTableView({
|
|
|
1422
1450
|
style={{
|
|
1423
1451
|
borderColor: table.style.borderColor ?? "#d1d5db",
|
|
1424
1452
|
background: header ? (table.style.headerFill ?? "#f3f4f6") : undefined,
|
|
1453
|
+
// An explicitly colored run still owns its authored text style.
|
|
1454
|
+
color: header ? headerColor : undefined,
|
|
1425
1455
|
padding: `${table.style.cellPaddingPt ?? 6}pt`,
|
|
1426
1456
|
}}
|
|
1427
1457
|
>
|
|
@@ -1443,6 +1473,42 @@ function DocumentTableView({
|
|
|
1443
1473
|
);
|
|
1444
1474
|
}
|
|
1445
1475
|
|
|
1476
|
+
/** Choose a theme-independent header color only when both light and dark backdrops allow one. */
|
|
1477
|
+
function tableHeaderTextColor(fill: string | undefined): string | undefined {
|
|
1478
|
+
if (!fill) return "#171717";
|
|
1479
|
+
const hex = /^#([\da-f]{3}|[\da-f]{6}|[\da-f]{8})$/i.exec(fill)?.[1];
|
|
1480
|
+
if (!hex) return undefined;
|
|
1481
|
+
const channels =
|
|
1482
|
+
hex.length === 3
|
|
1483
|
+
? [...hex].map((digit) => Number.parseInt(digit + digit, 16))
|
|
1484
|
+
: [0, 2, 4].map((index) => Number.parseInt(hex.slice(index, index + 2), 16));
|
|
1485
|
+
const alpha = hex.length === 8 ? Number.parseInt(hex.slice(6), 16) / 255 : 1;
|
|
1486
|
+
const luminanceOn = (backdrop: number) => {
|
|
1487
|
+
const linear = channels.map((channel) => {
|
|
1488
|
+
const normalized = (channel * alpha + backdrop * (1 - alpha)) / 255;
|
|
1489
|
+
return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
1490
|
+
});
|
|
1491
|
+
return linear[0]! * 0.2126 + linear[1]! * 0.7152 + linear[2]! * 0.0722;
|
|
1492
|
+
};
|
|
1493
|
+
// A paginated page is white; a continuous page follows its theme. For alpha
|
|
1494
|
+
// fills, choose a fixed foreground only if it contrasts on both extremes.
|
|
1495
|
+
const backdrops = alpha < 1 ? [luminanceOn(0), luminanceOn(255)] : [luminanceOn(255)];
|
|
1496
|
+
const darkTextLuminance = ((23 / 255 + 0.055) / 1.055) ** 2.4;
|
|
1497
|
+
const whiteContrast = Math.min(...backdrops.map((value) => 1.05 / (value + 0.05)));
|
|
1498
|
+
const darkContrast = Math.min(
|
|
1499
|
+
...backdrops.map(
|
|
1500
|
+
(value) =>
|
|
1501
|
+
(Math.max(value, darkTextLuminance) + 0.05) / (Math.min(value, darkTextLuminance) + 0.05),
|
|
1502
|
+
),
|
|
1503
|
+
);
|
|
1504
|
+
if (Math.max(whiteContrast, darkContrast) < 4.5) {
|
|
1505
|
+
// Opaque midtones need pure black where the softer #171717 cannot meet
|
|
1506
|
+
// normal-text contrast. Translucent fills inherit the theme's text color.
|
|
1507
|
+
return alpha < 1 ? undefined : "#000";
|
|
1508
|
+
}
|
|
1509
|
+
return whiteContrast > darkContrast ? "#fff" : "#171717";
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1446
1512
|
function ToolbarButton({
|
|
1447
1513
|
label,
|
|
1448
1514
|
shortcut,
|
|
@@ -1633,7 +1699,9 @@ function responsiveDocumentPageScale(
|
|
|
1633
1699
|
): number {
|
|
1634
1700
|
if (viewportWidth <= 0) return 1;
|
|
1635
1701
|
const naturalWidth = page.widthPt * POINT_TO_CSS_PIXEL;
|
|
1636
|
-
|
|
1702
|
+
// Below this scale the page text becomes too small to read in a narrow dock.
|
|
1703
|
+
// The viewport can pan horizontally without changing the chosen layout.
|
|
1704
|
+
return Math.min(1, Math.max(0.75, (viewportWidth - 32) / naturalWidth));
|
|
1637
1705
|
}
|
|
1638
1706
|
|
|
1639
1707
|
function pageContentStyle(
|
|
@@ -1642,7 +1710,7 @@ function pageContentStyle(
|
|
|
1642
1710
|
): CSSProperties {
|
|
1643
1711
|
if (layout === "continuous") {
|
|
1644
1712
|
return {
|
|
1645
|
-
padding: "24px clamp(
|
|
1713
|
+
padding: "24px clamp(12px, 4cqw, 72px)",
|
|
1646
1714
|
};
|
|
1647
1715
|
}
|
|
1648
1716
|
return {
|
|
@@ -70,6 +70,7 @@ type DocumentCommandState = {
|
|
|
70
70
|
export function EditableDocumentArtifactSurface({
|
|
71
71
|
session,
|
|
72
72
|
title,
|
|
73
|
+
showHeader,
|
|
73
74
|
subtitle,
|
|
74
75
|
readOnly = false,
|
|
75
76
|
onCommit,
|
|
@@ -260,6 +261,7 @@ export function EditableDocumentArtifactSurface({
|
|
|
260
261
|
<DocumentProjectionArtifactSurface
|
|
261
262
|
{...surfaceProps}
|
|
262
263
|
title={title}
|
|
264
|
+
showHeader={showHeader}
|
|
263
265
|
subtitle={
|
|
264
266
|
subtitle ??
|
|
265
267
|
`${projection.blocks.length} block${projection.blocks.length === 1 ? "" : "s"}${writable ? "" : " · Read only"}`
|
|
@@ -274,6 +276,7 @@ export function EditableDocumentArtifactSurface({
|
|
|
274
276
|
<ArtifactSurface
|
|
275
277
|
modality="document"
|
|
276
278
|
title={title}
|
|
279
|
+
showHeader={showHeader}
|
|
277
280
|
subtitle={subtitle ?? status}
|
|
278
281
|
busy={!accessRevoked && !state.error}
|
|
279
282
|
className={surfaceProps.className}
|
|
@@ -89,6 +89,7 @@ type PresentationProjectionState = {
|
|
|
89
89
|
export function EditablePresentationArtifactSurface({
|
|
90
90
|
session,
|
|
91
91
|
title = "Presentation",
|
|
92
|
+
showHeader,
|
|
92
93
|
subtitle,
|
|
93
94
|
readOnly = false,
|
|
94
95
|
onCommit,
|
|
@@ -266,6 +267,7 @@ export function EditablePresentationArtifactSurface({
|
|
|
266
267
|
<PresentationProjectionArtifactSurface
|
|
267
268
|
{...surfaceProps}
|
|
268
269
|
title={title}
|
|
270
|
+
showHeader={showHeader}
|
|
269
271
|
subtitle={
|
|
270
272
|
subtitle ??
|
|
271
273
|
`${projection.slides.length} slide${projection.slides.length === 1 ? "" : "s"}${writable ? "" : " · Read only"}`
|
|
@@ -280,6 +282,7 @@ export function EditablePresentationArtifactSurface({
|
|
|
280
282
|
<ArtifactSurface
|
|
281
283
|
modality="presentation"
|
|
282
284
|
title={title}
|
|
285
|
+
showHeader={showHeader}
|
|
283
286
|
subtitle={subtitle ?? status}
|
|
284
287
|
actions={surfaceProps.actions}
|
|
285
288
|
busy={!accessRevoked && !state.error}
|
|
@@ -62,6 +62,7 @@ export type EditableSpreadsheetArtifactSurfaceProps = Omit<
|
|
|
62
62
|
"metadataRevision" | "sheet"
|
|
63
63
|
> & {
|
|
64
64
|
title?: string | undefined;
|
|
65
|
+
showHeader?: boolean | undefined;
|
|
65
66
|
subtitle?: ReactNode | undefined;
|
|
66
67
|
actions?: ReactNode | undefined;
|
|
67
68
|
initialSheetId?: string | undefined;
|
|
@@ -311,6 +312,7 @@ export function EditableSpreadsheetGrid({
|
|
|
311
312
|
export function EditableSpreadsheetArtifactSurface({
|
|
312
313
|
session,
|
|
313
314
|
title = "Workbook",
|
|
315
|
+
showHeader,
|
|
314
316
|
subtitle,
|
|
315
317
|
actions,
|
|
316
318
|
initialSheetId,
|
|
@@ -392,6 +394,7 @@ export function EditableSpreadsheetArtifactSurface({
|
|
|
392
394
|
<ArtifactSurface
|
|
393
395
|
modality="spreadsheet"
|
|
394
396
|
title={title}
|
|
397
|
+
showHeader={showHeader}
|
|
395
398
|
subtitle={
|
|
396
399
|
subtitle ??
|
|
397
400
|
(accessRevoked
|
|
@@ -334,6 +334,7 @@ export type PresentationProjectionEditorProps = Omit<
|
|
|
334
334
|
|
|
335
335
|
export type PresentationProjectionArtifactSurfaceProps = PresentationProjectionEditorProps & {
|
|
336
336
|
title?: string | undefined;
|
|
337
|
+
showHeader?: boolean | undefined;
|
|
337
338
|
subtitle?: ReactNode | undefined;
|
|
338
339
|
actions?: ReactNode | undefined;
|
|
339
340
|
busy?: boolean | undefined;
|
|
@@ -360,6 +361,7 @@ export type PresentationEditorProps = {
|
|
|
360
361
|
|
|
361
362
|
export type PresentationArtifactSurfaceProps = PresentationEditorProps & {
|
|
362
363
|
title?: string | undefined;
|
|
364
|
+
showHeader?: boolean | undefined;
|
|
363
365
|
subtitle?: ReactNode | undefined;
|
|
364
366
|
actions?: ReactNode | undefined;
|
|
365
367
|
busy?: boolean | undefined;
|
|
@@ -1819,6 +1821,7 @@ function PresentationEditorCore({
|
|
|
1819
1821
|
export function PresentationArtifactSurface({
|
|
1820
1822
|
presentation,
|
|
1821
1823
|
title = "Presentation",
|
|
1824
|
+
showHeader,
|
|
1822
1825
|
subtitle,
|
|
1823
1826
|
actions,
|
|
1824
1827
|
busy,
|
|
@@ -1830,6 +1833,7 @@ export function PresentationArtifactSurface({
|
|
|
1830
1833
|
<ArtifactSurface
|
|
1831
1834
|
modality="presentation"
|
|
1832
1835
|
title={title}
|
|
1836
|
+
showHeader={showHeader}
|
|
1833
1837
|
subtitle={subtitle ?? `${count} slide${count === 1 ? "" : "s"}`}
|
|
1834
1838
|
actions={actions}
|
|
1835
1839
|
busy={busy}
|
|
@@ -1844,6 +1848,7 @@ export function PresentationArtifactSurface({
|
|
|
1844
1848
|
export function PresentationProjectionArtifactSurface({
|
|
1845
1849
|
projection,
|
|
1846
1850
|
title = "Presentation",
|
|
1851
|
+
showHeader,
|
|
1847
1852
|
subtitle,
|
|
1848
1853
|
actions,
|
|
1849
1854
|
busy,
|
|
@@ -1855,6 +1860,7 @@ export function PresentationProjectionArtifactSurface({
|
|
|
1855
1860
|
<ArtifactSurface
|
|
1856
1861
|
modality="presentation"
|
|
1857
1862
|
title={title}
|
|
1863
|
+
showHeader={showHeader}
|
|
1858
1864
|
subtitle={subtitle ?? `${count} slide${count === 1 ? "" : "s"}`}
|
|
1859
1865
|
actions={actions}
|
|
1860
1866
|
busy={busy}
|
|
@@ -82,6 +82,9 @@ export type BrowserViewerProps = EmbeddedBrowserInteractionClientOverride & {
|
|
|
82
82
|
/** The selected OpenGeni agent/session. Peer BrowserSessions stay discoverable. */
|
|
83
83
|
sessionId: string;
|
|
84
84
|
enabled?: boolean | undefined;
|
|
85
|
+
/** Whether the Browser tab is selected. Keeps the mounted media stream warm
|
|
86
|
+
* while pausing semantic reads behind other dock tabs. */
|
|
87
|
+
active?: boolean | undefined;
|
|
85
88
|
className?: string | undefined;
|
|
86
89
|
onNotify?: ((notification: BrowserViewerNotification) => void) | undefined;
|
|
87
90
|
/** Tests/demos only. Production uses the browser's native WebSocket. */
|
|
@@ -139,6 +142,7 @@ type BrowserDiagnosticsView = {
|
|
|
139
142
|
export function BrowserViewer({
|
|
140
143
|
sessionId,
|
|
141
144
|
enabled = true,
|
|
145
|
+
active = true,
|
|
142
146
|
className,
|
|
143
147
|
onNotify,
|
|
144
148
|
webSocketFactory,
|
|
@@ -287,6 +291,7 @@ export function BrowserViewer({
|
|
|
287
291
|
);
|
|
288
292
|
const controllerReady = selectedRegistrySession?.lifecycle === "active";
|
|
289
293
|
const resumeSession = registry.resume;
|
|
294
|
+
const [hasLiveFrame, setHasLiveFrame] = useState(false);
|
|
290
295
|
|
|
291
296
|
const wakeBrowser = useCallback(
|
|
292
297
|
async (session: BrowserSession, retry = false): Promise<void> => {
|
|
@@ -337,17 +342,14 @@ export function BrowserViewer({
|
|
|
337
342
|
setResumeAttempt((visible) =>
|
|
338
343
|
visible?.sessionId === selectedRegistrySession.id ? null : visible,
|
|
339
344
|
);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (selectedRegistrySession.lifecycle === "suspended") {
|
|
343
|
-
void wakeBrowser(selectedRegistrySession);
|
|
344
345
|
}
|
|
345
|
-
}, [selectedRegistrySession
|
|
346
|
+
}, [selectedRegistrySession]);
|
|
346
347
|
|
|
347
348
|
const browser = useBrowserSession({
|
|
348
349
|
...override,
|
|
349
350
|
browserSessionId: selection?.sessionId ?? null,
|
|
350
351
|
enabled: enabled && selection !== null && controllerReady,
|
|
352
|
+
semanticObservationEnabled: active && !hasLiveFrame,
|
|
351
353
|
});
|
|
352
354
|
useEffect(() => {
|
|
353
355
|
if (!isSourcePlacementChangedError(browser.error, "browser_session")) return;
|
|
@@ -413,6 +415,10 @@ export function BrowserViewer({
|
|
|
413
415
|
)
|
|
414
416
|
? frames.frame
|
|
415
417
|
: null;
|
|
418
|
+
const frameIsLive = frames.state === "live" && displayedFrame !== null;
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
setHasLiveFrame(frameIsLive);
|
|
421
|
+
}, [frameIsLive]);
|
|
416
422
|
const supportsLiveFrames = browser.session?.capabilities.liveFrames === true;
|
|
417
423
|
const displayConnectionState = supportsLiveFrames
|
|
418
424
|
? frames.state === "live" && !displayedFrame
|
|
@@ -248,6 +248,7 @@ export function ComposerTranscriptionControl({
|
|
|
248
248
|
>
|
|
249
249
|
<button
|
|
250
250
|
type="button"
|
|
251
|
+
disabled={composer.disabled && !retrying}
|
|
251
252
|
onClick={() =>
|
|
252
253
|
savedTranscript
|
|
253
254
|
? void transcription.insertSavedTranscript()
|
|
@@ -265,7 +266,7 @@ export function ComposerTranscriptionControl({
|
|
|
265
266
|
className={cn(
|
|
266
267
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
267
268
|
"bg-og-fg text-og-bg transition-colors duration-150 motion-reduce:transition-none",
|
|
268
|
-
"hover:bg-og-fg-muted pointer-coarse:size-11",
|
|
269
|
+
"hover:bg-og-fg-muted disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-11",
|
|
269
270
|
)}
|
|
270
271
|
>
|
|
271
272
|
{savedTranscript ? (
|
|
@@ -280,12 +281,13 @@ export function ComposerTranscriptionControl({
|
|
|
280
281
|
<Tip tip={messages.discardRecovered}>
|
|
281
282
|
<button
|
|
282
283
|
type="button"
|
|
284
|
+
disabled={composer.disabled}
|
|
283
285
|
onClick={() => void transcription.discard()}
|
|
284
286
|
aria-label={messages.discardRecovered}
|
|
285
287
|
className={cn(
|
|
286
288
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
287
289
|
"text-og-fg-muted transition-colors duration-150 motion-reduce:transition-none",
|
|
288
|
-
"hover:bg-og-surface-3 hover:text-og-status-failed pointer-coarse:size-11",
|
|
290
|
+
"hover:bg-og-surface-3 hover:text-og-status-failed disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-11",
|
|
289
291
|
)}
|
|
290
292
|
>
|
|
291
293
|
<Trash2Icon className="size-3.5" />
|
|
@@ -457,9 +457,9 @@ export function useChatComposerController({
|
|
|
457
457
|
(event: DragEvent<HTMLDivElement>) => {
|
|
458
458
|
if (!attachments || !dragCarriesFiles(event)) return;
|
|
459
459
|
event.preventDefault();
|
|
460
|
-
setDragging(true);
|
|
460
|
+
if (!disabled) setDragging(true);
|
|
461
461
|
},
|
|
462
|
-
[attachments],
|
|
462
|
+
[attachments, disabled],
|
|
463
463
|
);
|
|
464
464
|
const handleDragLeave = useCallback(
|
|
465
465
|
(event: DragEvent<HTMLDivElement>) => {
|
|
@@ -474,11 +474,16 @@ export function useChatComposerController({
|
|
|
474
474
|
if (!attachments || !dragCarriesFiles(event)) return;
|
|
475
475
|
event.preventDefault();
|
|
476
476
|
setDragging(false);
|
|
477
|
-
if (event.dataTransfer.files.length > 0)
|
|
477
|
+
if (!disabled && event.dataTransfer.files.length > 0)
|
|
478
|
+
attachments.addFiles(event.dataTransfer.files);
|
|
478
479
|
},
|
|
479
|
-
[attachments],
|
|
480
|
+
[attachments, disabled],
|
|
480
481
|
);
|
|
481
482
|
|
|
483
|
+
useEffect(() => {
|
|
484
|
+
if (disabled) setDragging(false);
|
|
485
|
+
}, [disabled]);
|
|
486
|
+
|
|
482
487
|
const [notice, setNotice] = useState<Notice | null>(null);
|
|
483
488
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
484
489
|
const [confirmState, setConfirmState] = useState<ConfirmState>(null);
|
|
@@ -624,17 +629,18 @@ export function useChatComposerController({
|
|
|
624
629
|
);
|
|
625
630
|
const handlePaste = useCallback(
|
|
626
631
|
(event: ClipboardEvent<HTMLTextAreaElement>) => {
|
|
632
|
+
if (disabled) return;
|
|
627
633
|
onPaste?.(event);
|
|
628
634
|
attachments?.addFromPaste(event);
|
|
629
635
|
},
|
|
630
|
-
[attachments, onPaste],
|
|
636
|
+
[attachments, disabled, onPaste],
|
|
631
637
|
);
|
|
632
638
|
const handleFileChange = useCallback(
|
|
633
639
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
634
|
-
if (event.target.files) attachments?.addFiles(event.target.files);
|
|
640
|
+
if (!disabled && event.target.files) attachments?.addFiles(event.target.files);
|
|
635
641
|
event.target.value = "";
|
|
636
642
|
},
|
|
637
|
-
[attachments],
|
|
643
|
+
[attachments, disabled],
|
|
638
644
|
);
|
|
639
645
|
|
|
640
646
|
const helpCommands = useMemo(
|
|
@@ -975,6 +981,7 @@ export function Attachments() {
|
|
|
975
981
|
<AttachmentChips
|
|
976
982
|
attachments={controller.attachments.attachments}
|
|
977
983
|
messages={controller.messages}
|
|
984
|
+
disabled={controller.disabled}
|
|
978
985
|
onRemove={controller.attachments.remove}
|
|
979
986
|
onRetry={controller.attachments.retry}
|
|
980
987
|
onRetainPreview={controller.attachments.retainPreview}
|
|
@@ -1679,6 +1686,7 @@ function ConfirmBar({
|
|
|
1679
1686
|
function AttachmentChips({
|
|
1680
1687
|
attachments,
|
|
1681
1688
|
messages,
|
|
1689
|
+
disabled,
|
|
1682
1690
|
onRemove,
|
|
1683
1691
|
onRetry,
|
|
1684
1692
|
onRetainPreview,
|
|
@@ -1686,6 +1694,7 @@ function AttachmentChips({
|
|
|
1686
1694
|
}: {
|
|
1687
1695
|
attachments: UseFileAttachmentsResult["attachments"];
|
|
1688
1696
|
messages: ChatComposerMessages;
|
|
1697
|
+
disabled: boolean;
|
|
1689
1698
|
onRemove: (id: string) => void;
|
|
1690
1699
|
onRetry?: ((id: string) => void) | undefined;
|
|
1691
1700
|
onRetainPreview: UseFileAttachmentsResult["retainPreview"];
|
|
@@ -1837,7 +1846,8 @@ function AttachmentChips({
|
|
|
1837
1846
|
<button
|
|
1838
1847
|
type="button"
|
|
1839
1848
|
onClick={() => onRetry(attachment.id)}
|
|
1840
|
-
|
|
1849
|
+
disabled={disabled}
|
|
1850
|
+
className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
|
|
1841
1851
|
aria-label={messages.retryAttachment(attachment.name)}
|
|
1842
1852
|
>
|
|
1843
1853
|
<RotateCwIcon className="size-3.5" />
|
|
@@ -1847,7 +1857,8 @@ function AttachmentChips({
|
|
|
1847
1857
|
<button
|
|
1848
1858
|
type="button"
|
|
1849
1859
|
onClick={() => onRemove(attachment.id)}
|
|
1850
|
-
|
|
1860
|
+
disabled={disabled}
|
|
1861
|
+
className="shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-10"
|
|
1851
1862
|
aria-label={messages.removeAttachment(attachment.name)}
|
|
1852
1863
|
>
|
|
1853
1864
|
<XIcon className="size-3.5" />
|