@opengeni/react 7.0.0 → 7.1.0-canary.35855175602001
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 +34 -0
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts.js +17 -17
- package/dist/{browser-viewer-LGH4IP47.js → browser-viewer-MN7MOYQT.js} +5 -5
- package/dist/{chunk-YS24CFDI.js → chunk-2O2HXRGP.js} +7 -7
- package/dist/{chunk-IP4BUBKH.js → chunk-3LL47F4U.js} +28 -17
- package/dist/chunk-3LL47F4U.js.map +1 -0
- package/dist/{chunk-UXE5SSNN.js → chunk-4ACTWOOW.js} +8 -8
- package/dist/{chunk-IYUPN32E.js → chunk-DBPVUGQT.js} +6 -1
- package/dist/{chunk-IYUPN32E.js.map → chunk-DBPVUGQT.js.map} +1 -1
- package/dist/{chunk-5GAL23FF.js → chunk-IOLPHOF4.js} +2 -5
- package/dist/chunk-IOLPHOF4.js.map +1 -0
- package/dist/{chunk-JPHDWKZE.js → chunk-PFDNB3U7.js} +15 -10
- package/dist/chunk-PFDNB3U7.js.map +1 -0
- package/dist/{chunk-D7GAPJ3V.js → chunk-SHRCATV6.js} +67 -34
- package/dist/chunk-SHRCATV6.js.map +1 -0
- package/dist/{chunk-H5YGYNXS.js → chunk-TV5PP2PE.js} +11 -11
- package/dist/chunk-TV5PP2PE.js.map +1 -0
- package/dist/{chunk-PNAVEK2U.js → chunk-UQS7BGNQ.js} +12 -12
- package/dist/{chunk-JKLGJQO5.js → chunk-VI7HELBI.js} +40 -20
- package/dist/chunk-VI7HELBI.js.map +1 -0
- package/dist/{chunk-HJ5VJ4JB.js → chunk-WKFFRFJF.js} +73 -15
- package/dist/chunk-WKFFRFJF.js.map +1 -0
- package/dist/{chunk-D5NOQPLR.js → chunk-ZC2DK5SC.js} +75 -65
- package/dist/chunk-ZC2DK5SC.js.map +1 -0
- package/dist/components/markdown.d.ts +2 -0
- package/dist/components/model-policy-picker.d.ts +17 -1
- package/dist/components/session-conversation.d.ts +3 -0
- package/dist/composer.d.ts +1 -1
- package/dist/composer.js +7 -7
- package/dist/{computer-viewer-CTFCJVS7.js → computer-viewer-FX4WOZMX.js} +4 -4
- package/dist/connect.js +5 -5
- package/dist/hooks/use-session-events.d.ts +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +112 -115
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +5 -5
- package/dist/machines.js +2 -2
- package/dist/{model-policy-picker-menu-RVOQ4ZZG.js → model-policy-picker-menu-AGXXJZ2B.js} +4 -4
- package/dist/model-policy.js +1 -1
- package/dist/realtime.js +5 -5
- package/dist/session-ui.js +12 -12
- package/dist/session.js +3 -3
- package/dist/timeline/tool-display-name.d.ts +2 -1
- package/dist/timeline/types.d.ts +2 -1
- package/package.json +3 -3
- package/src/approvals.ts +8 -1
- package/src/components/approval-surface.tsx +12 -2
- package/src/components/machine-card.tsx +5 -5
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machines/machine-detail.tsx +5 -2
- package/src/components/markdown.tsx +101 -55
- package/src/components/model-policy-picker-menu.tsx +131 -33
- package/src/components/model-policy-picker.tsx +61 -12
- package/src/components/session-commands-panel.tsx +8 -3
- package/src/components/session-conversation.tsx +5 -1
- package/src/composer.ts +1 -0
- package/src/hooks/use-last-started-turn-policy.ts +3 -7
- package/src/hooks/use-session-events.ts +32 -7
- package/src/index.ts +1 -0
- package/src/model-policy.ts +1 -4
- package/src/timeline/projection.ts +4 -0
- package/src/timeline/rolling-activity.tsx +4 -2
- package/src/timeline/tool-display-name.ts +8 -6
- package/src/timeline/tool-renderers.tsx +5 -3
- package/src/timeline/types.ts +2 -0
- package/styles/compiled.css +15 -0
- package/dist/chunk-5GAL23FF.js.map +0 -1
- package/dist/chunk-D5NOQPLR.js.map +0 -1
- package/dist/chunk-D7GAPJ3V.js.map +0 -1
- package/dist/chunk-H5YGYNXS.js.map +0 -1
- package/dist/chunk-HJ5VJ4JB.js.map +0 -1
- package/dist/chunk-IP4BUBKH.js.map +0 -1
- package/dist/chunk-JKLGJQO5.js.map +0 -1
- package/dist/chunk-JPHDWKZE.js.map +0 -1
- /package/dist/{browser-viewer-LGH4IP47.js.map → browser-viewer-MN7MOYQT.js.map} +0 -0
- /package/dist/{chunk-YS24CFDI.js.map → chunk-2O2HXRGP.js.map} +0 -0
- /package/dist/{chunk-UXE5SSNN.js.map → chunk-4ACTWOOW.js.map} +0 -0
- /package/dist/{chunk-PNAVEK2U.js.map → chunk-UQS7BGNQ.js.map} +0 -0
- /package/dist/{computer-viewer-CTFCJVS7.js.map → computer-viewer-FX4WOZMX.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-RVOQ4ZZG.js.map → model-policy-picker-menu-AGXXJZ2B.js.map} +0 -0
package/dist/interaction.js
CHANGED
|
@@ -7,29 +7,29 @@ import {
|
|
|
7
7
|
useBrowserSession,
|
|
8
8
|
useBrowserSessions,
|
|
9
9
|
useSiteAuthConnections
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UQS7BGNQ.js";
|
|
11
11
|
import {
|
|
12
12
|
ComputerViewer,
|
|
13
13
|
useComputerFrameStream,
|
|
14
14
|
useComputerSession,
|
|
15
15
|
useComputerSessions
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2O2HXRGP.js";
|
|
17
17
|
import {
|
|
18
18
|
useInteractionInterventions,
|
|
19
19
|
useInteractionInvalidation
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-TV5PP2PE.js";
|
|
21
21
|
import "./chunk-4MDLEHXL.js";
|
|
22
22
|
import "./chunk-5YK2ZDIG.js";
|
|
23
|
-
import "./chunk-JVYQRRC4.js";
|
|
24
23
|
import "./chunk-KZ73RL76.js";
|
|
25
|
-
import "./chunk-PLYRL5ER.js";
|
|
26
24
|
import {
|
|
27
25
|
useEmbeddedBrowserInteraction,
|
|
28
26
|
useEmbeddedComputerInteraction,
|
|
29
27
|
useEmbeddedInteraction,
|
|
30
28
|
useEmbeddedInterventions
|
|
31
29
|
} from "./chunk-NEXLLTP4.js";
|
|
30
|
+
import "./chunk-PLYRL5ER.js";
|
|
32
31
|
import "./chunk-22KP6LR5.js";
|
|
32
|
+
import "./chunk-JVYQRRC4.js";
|
|
33
33
|
|
|
34
34
|
// src/hooks/use-network-routes.ts
|
|
35
35
|
import { useCallback, useEffect, useRef, useState } from "react";
|
package/dist/machines.js
CHANGED
|
@@ -28,11 +28,11 @@ import {
|
|
|
28
28
|
healthPulses,
|
|
29
29
|
pointsFor,
|
|
30
30
|
useMachines
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-PFDNB3U7.js";
|
|
32
32
|
import "./chunk-PAJU5KKL.js";
|
|
33
33
|
import "./chunk-KZ73RL76.js";
|
|
34
|
-
import "./chunk-PLYRL5ER.js";
|
|
35
34
|
import "./chunk-NEXLLTP4.js";
|
|
35
|
+
import "./chunk-PLYRL5ER.js";
|
|
36
36
|
import "./chunk-22KP6LR5.js";
|
|
37
37
|
export {
|
|
38
38
|
CONNECTION_STATUS_META,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ModelPolicyPickerMenu,
|
|
3
3
|
ModelPolicyPickerPopover
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-WKFFRFJF.js";
|
|
5
|
+
import "./chunk-3LL47F4U.js";
|
|
6
|
+
import "./chunk-IOLPHOF4.js";
|
|
6
7
|
import "./chunk-VZTQ73XT.js";
|
|
7
|
-
import "./chunk-5GAL23FF.js";
|
|
8
8
|
import "./chunk-22KP6LR5.js";
|
|
9
9
|
export {
|
|
10
10
|
ModelPolicyPickerMenu,
|
|
11
11
|
ModelPolicyPickerPopover
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=model-policy-picker-menu-
|
|
13
|
+
//# sourceMappingURL=model-policy-picker-menu-AGXXJZ2B.js.map
|
package/dist/model-policy.js
CHANGED
package/dist/realtime.js
CHANGED
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
PickerAnimatedPage,
|
|
4
4
|
PickerBackHeader,
|
|
5
5
|
PickerNavRow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3LL47F4U.js";
|
|
7
|
+
import "./chunk-IOLPHOF4.js";
|
|
8
|
+
import {
|
|
9
|
+
useEmbeddedRealtimeSession
|
|
10
|
+
} from "./chunk-NEXLLTP4.js";
|
|
7
11
|
import {
|
|
8
12
|
usePortalTokenSource,
|
|
9
13
|
usePortalTokenStyle
|
|
10
14
|
} from "./chunk-VZTQ73XT.js";
|
|
11
|
-
import {
|
|
12
|
-
useEmbeddedRealtimeSession
|
|
13
|
-
} from "./chunk-NEXLLTP4.js";
|
|
14
|
-
import "./chunk-5GAL23FF.js";
|
|
15
15
|
import {
|
|
16
16
|
cn
|
|
17
17
|
} from "./chunk-22KP6LR5.js";
|
package/dist/session-ui.js
CHANGED
|
@@ -19,28 +19,28 @@ import {
|
|
|
19
19
|
setStartupDetails,
|
|
20
20
|
useStartupDetails,
|
|
21
21
|
userMessageLikelyNeedsDisclosure
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZC2DK5SC.js";
|
|
23
23
|
import "./chunk-GEN54DU5.js";
|
|
24
24
|
import "./chunk-GBPCZH3Y.js";
|
|
25
25
|
import "./chunk-ZYRGEKWS.js";
|
|
26
|
-
import "./chunk-PAJU5KKL.js";
|
|
27
|
-
import "./chunk-D7GAPJ3V.js";
|
|
28
|
-
import "./chunk-2VHARTBL.js";
|
|
29
|
-
import "./chunk-JVYQRRC4.js";
|
|
30
|
-
import "./chunk-UXE5SSNN.js";
|
|
31
|
-
import "./chunk-BRM6FVZA.js";
|
|
32
26
|
import "./chunk-WYWRYUNQ.js";
|
|
33
|
-
import "./chunk-IP4BUBKH.js";
|
|
34
|
-
import "./chunk-VZTQ73XT.js";
|
|
35
27
|
import {
|
|
36
28
|
createOlderHistoryLoadReceipt
|
|
37
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-VI7HELBI.js";
|
|
30
|
+
import "./chunk-PAJU5KKL.js";
|
|
31
|
+
import "./chunk-4ACTWOOW.js";
|
|
32
|
+
import "./chunk-3LL47F4U.js";
|
|
38
33
|
import "./chunk-AKOMC3VO.js";
|
|
34
|
+
import "./chunk-IOLPHOF4.js";
|
|
39
35
|
import "./chunk-KZ73RL76.js";
|
|
40
|
-
import "./chunk-PLYRL5ER.js";
|
|
41
36
|
import "./chunk-NEXLLTP4.js";
|
|
42
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-SHRCATV6.js";
|
|
38
|
+
import "./chunk-2VHARTBL.js";
|
|
39
|
+
import "./chunk-BRM6FVZA.js";
|
|
40
|
+
import "./chunk-VZTQ73XT.js";
|
|
41
|
+
import "./chunk-PLYRL5ER.js";
|
|
43
42
|
import "./chunk-22KP6LR5.js";
|
|
43
|
+
import "./chunk-JVYQRRC4.js";
|
|
44
44
|
export {
|
|
45
45
|
ApprovalSurface,
|
|
46
46
|
BUILT_IN_TURN_SUMMARY_FACET_IDS,
|
package/dist/session.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useSessionControl,
|
|
11
11
|
useSessionLineage,
|
|
12
12
|
useSessionMcpApprovalPolicy
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DBPVUGQT.js";
|
|
14
14
|
import {
|
|
15
15
|
buildTimeline,
|
|
16
16
|
conversationTimeline,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
useSession,
|
|
30
30
|
useSessionEvents,
|
|
31
31
|
useTurnQueue
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-VI7HELBI.js";
|
|
33
33
|
import {
|
|
34
34
|
FILE_ONLY_MESSAGE_TEXT,
|
|
35
35
|
composeSendInput,
|
|
@@ -38,8 +38,8 @@ import {
|
|
|
38
38
|
useComposer
|
|
39
39
|
} from "./chunk-AKOMC3VO.js";
|
|
40
40
|
import "./chunk-KZ73RL76.js";
|
|
41
|
-
import "./chunk-PLYRL5ER.js";
|
|
42
41
|
import "./chunk-NEXLLTP4.js";
|
|
42
|
+
import "./chunk-PLYRL5ER.js";
|
|
43
43
|
export {
|
|
44
44
|
FILE_ONLY_MESSAGE_TEXT,
|
|
45
45
|
approvalsFromRequiresAction,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* and bare `session_create` resolve the same UI — without inventing previews
|
|
7
7
|
* from argument JSON.
|
|
8
8
|
*/
|
|
9
|
+
import type { ToolDisplayMetadata } from "@opengeni/sdk";
|
|
9
10
|
/** Leaf tool name after the first `__` server boundary (or the whole name). */
|
|
10
11
|
export declare function mcpToolLeaf(name: string): string;
|
|
11
12
|
/**
|
|
@@ -18,4 +19,4 @@ export declare function toolMatchesLeaf(wireName: string, leaf: string): boolean
|
|
|
18
19
|
* Readable label for a tool call ("session_create" / "opengeni__session_create"
|
|
19
20
|
* → "Session create"). Title-cases the first character of the leaf phrase.
|
|
20
21
|
*/
|
|
21
|
-
export declare function toolDisplayName(name: string): string;
|
|
22
|
+
export declare function toolDisplayName(name: string, display?: ToolDisplayMetadata): string;
|
package/dist/timeline/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HumanInputQuestion, HumanInputResponse, MediaGenerationResult, ResourceRef, SessionStatus, TimelineAnnotation, TimelineAnnotationSource, ToolAuthNeededPayload, ToolRef } from "@opengeni/sdk";
|
|
1
|
+
import type { HumanInputQuestion, HumanInputResponse, MediaGenerationResult, ResourceRef, SessionStatus, TimelineAnnotation, TimelineAnnotationSource, ToolAuthNeededPayload, ToolRef, ToolDisplayMetadata } from "@opengeni/sdk";
|
|
2
2
|
export type TimelineAnnotationSourceDescriptor = Omit<TimelineAnnotationSource, "startOffset" | "endOffset" | "contextBefore" | "contextAfter"> & {
|
|
3
3
|
text: string;
|
|
4
4
|
};
|
|
@@ -97,6 +97,7 @@ export type ToolCallItem = {
|
|
|
97
97
|
turnId: string | null;
|
|
98
98
|
callId: string | null;
|
|
99
99
|
name: string;
|
|
100
|
+
display?: ToolDisplayMetadata;
|
|
100
101
|
arguments: unknown;
|
|
101
102
|
output: unknown;
|
|
102
103
|
truncation?: ToolCallTruncation | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.1.0-canary.35855175602001",
|
|
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.0.
|
|
136
|
+
"@opengeni/connect": "^0.3.0-canary.35855175602001",
|
|
137
|
+
"@opengeni/sdk": "^7.1.0-canary.35855175602001",
|
|
138
138
|
"clsx": "^2.1.1",
|
|
139
139
|
"dequal": "2.0.3",
|
|
140
140
|
"lucide-react": "^1.8.0",
|
package/src/approvals.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
parseToolDisplayMetadata,
|
|
3
|
+
type ToolDisplayMetadata,
|
|
4
|
+
type SessionEvent,
|
|
5
|
+
} from "@opengeni/sdk";
|
|
2
6
|
|
|
3
7
|
/* ----------------------------------------------------------------------------
|
|
4
8
|
Pending-approvals projection
|
|
@@ -26,6 +30,7 @@ export type PendingApproval = {
|
|
|
26
30
|
id: string;
|
|
27
31
|
/** Tool/function name awaiting the decision. */
|
|
28
32
|
name: string;
|
|
33
|
+
display?: ToolDisplayMetadata;
|
|
29
34
|
arguments?: unknown;
|
|
30
35
|
/** The raw approval entry from the `session.requiresAction` payload. */
|
|
31
36
|
raw?: unknown;
|
|
@@ -49,11 +54,13 @@ export function approvalsFromRequiresAction(payload: unknown): PendingApproval[]
|
|
|
49
54
|
raw.rawItem && typeof raw.rawItem === "object"
|
|
50
55
|
? (raw.rawItem as Record<string, unknown>)
|
|
51
56
|
: {};
|
|
57
|
+
const display = parseToolDisplayMetadata(raw.display);
|
|
52
58
|
return {
|
|
53
59
|
// Mirror the runtime's canonical interruption identity before retaining
|
|
54
60
|
// the legacy top-level callId fallback for already-normalized payloads.
|
|
55
61
|
id: String(rawItem.callId ?? rawItem.id ?? raw.id ?? raw.callId ?? raw.name ?? index),
|
|
56
62
|
name: String(raw.name ?? raw.toolName ?? rawItem.name ?? "approval"),
|
|
63
|
+
...(display ? { display } : {}),
|
|
57
64
|
arguments: raw.arguments ?? rawItem.arguments,
|
|
58
65
|
raw: approval,
|
|
59
66
|
};
|
|
@@ -2,6 +2,7 @@ import { CheckIcon, ShieldCheckIcon, XIcon } from "lucide-react";
|
|
|
2
2
|
import { useEffect, useId, useRef, useState, type ReactNode } from "react";
|
|
3
3
|
import type { PendingApproval } from "../approvals";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
+
import { toolDisplayName } from "../timeline/tool-display-name";
|
|
5
6
|
|
|
6
7
|
export type ApprovalSurfaceMessages = {
|
|
7
8
|
title: string;
|
|
@@ -20,7 +21,10 @@ export const defaultApprovalSurfaceMessages: ApprovalSurfaceMessages = {
|
|
|
20
21
|
reject: "Reject",
|
|
21
22
|
approving: "Approving…",
|
|
22
23
|
rejecting: "Rejecting…",
|
|
23
|
-
formatToolName: (name) =>
|
|
24
|
+
formatToolName: (name) =>
|
|
25
|
+
name.includes("__") || /^[a-f0-9]{64}$/.test(name)
|
|
26
|
+
? toolDisplayName(name)
|
|
27
|
+
: name.replaceAll("_", " ").replaceAll(".", " › "),
|
|
24
28
|
};
|
|
25
29
|
|
|
26
30
|
export type ApprovalSurfaceProps = {
|
|
@@ -154,8 +158,14 @@ export function ApprovalSurface({
|
|
|
154
158
|
) : (
|
|
155
159
|
<>
|
|
156
160
|
<p className="text-og-sm font-medium text-og-fg">
|
|
157
|
-
{
|
|
161
|
+
{approval.display?.title ??
|
|
162
|
+
messages.formatToolName(approval.display?.toolName ?? approval.name)}
|
|
158
163
|
</p>
|
|
164
|
+
{approval.display?.accountLabel ? (
|
|
165
|
+
<p className="mt-1 break-words text-og-xs text-og-fg-muted">
|
|
166
|
+
{approval.display.accountLabel}
|
|
167
|
+
</p>
|
|
168
|
+
) : null}
|
|
159
169
|
{argumentsPreview !== null ? (
|
|
160
170
|
<pre className="mt-2 max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-og-sm bg-og-surface-2 p-2 font-mono text-og-xs text-og-fg-muted">
|
|
161
171
|
{argumentsPreview}
|
|
@@ -36,10 +36,12 @@ export type MachineCardProps = {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
function KindIcon({ machine }: { machine: MachineView }) {
|
|
39
|
-
if (machine.
|
|
39
|
+
if (machine.kind === "local" || machine.kind === "selfhosted")
|
|
40
|
+
return <LaptopIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
41
|
+
if (machine.kind === "docker" || machine.isSessionGroup)
|
|
40
42
|
return <ServerIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
41
43
|
if (machine.kind === "modal") return <CpuIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
42
|
-
return <
|
|
44
|
+
return <ServerIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/**
|
|
@@ -158,9 +160,7 @@ export function MachineCard({
|
|
|
158
160
|
{machine.scope === "user" ? "personal" : machine.scope}
|
|
159
161
|
</span>
|
|
160
162
|
<span aria-hidden>·</span>
|
|
161
|
-
<span className="capitalize">
|
|
162
|
-
{machine.isSessionGroup ? "session sandbox" : machine.kind}
|
|
163
|
-
</span>
|
|
163
|
+
<span className="capitalize">{machine.kind}</span>
|
|
164
164
|
<span aria-hidden>·</span>
|
|
165
165
|
<span className="font-og-mono">
|
|
166
166
|
{machine.os}/{machine.arch}
|
|
@@ -23,7 +23,7 @@ export type MachineDockBarProps = {
|
|
|
23
23
|
* chrome (the dock-parity contract: selfhosted == Modal for the surfaces).
|
|
24
24
|
*/
|
|
25
25
|
export function MachineDockBar({ name, kind, state, className }: MachineDockBarProps) {
|
|
26
|
-
const Icon = kind === "selfhosted" ? LaptopIcon : CpuIcon;
|
|
26
|
+
const Icon = kind === "selfhosted" || kind === "local" ? LaptopIcon : CpuIcon;
|
|
27
27
|
const stateBadge = MACHINE_STATE_BADGE_META[state];
|
|
28
28
|
return (
|
|
29
29
|
<div
|
|
@@ -44,9 +44,12 @@ export type MachineDetailProps = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function KindIcon({ kind, session }: { kind: string; session: boolean }) {
|
|
47
|
-
if (
|
|
47
|
+
if (kind === "local" || kind === "selfhosted")
|
|
48
|
+
return <LaptopIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
49
|
+
if (kind === "docker" || session)
|
|
50
|
+
return <ServerIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
48
51
|
if (kind === "modal") return <CpuIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
49
|
-
return <
|
|
52
|
+
return <ServerIcon className="size-4 text-og-fg-subtle" aria-hidden />;
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
export function MachineDetail({
|
|
@@ -56,6 +56,8 @@ const InteractiveContext = createContext<{
|
|
|
56
56
|
}>({ source: "" });
|
|
57
57
|
|
|
58
58
|
export type MarkdownProps = {
|
|
59
|
+
/** Resolve a retained-file reference to the host's authenticated artifact page. */
|
|
60
|
+
artifactHref?: ((artifactId: string) => string) | undefined;
|
|
59
61
|
/** Reveals a bounded source excerpt; closing Find retains it until explicit restore. */
|
|
60
62
|
searchTarget?: TimelineSearchTarget | null | undefined;
|
|
61
63
|
renderImage?: ((image: { src: string; alt: string }) => ReactNode) | undefined;
|
|
@@ -217,47 +219,85 @@ const baseComponents: Components = {
|
|
|
217
219
|
const MARKDOWN_LINK_CLASS =
|
|
218
220
|
"break-words font-medium text-og-accent-strong underline-offset-2 hover:underline";
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
222
|
+
// Keep renderer component types stable: rebuilding them remounts paragraphs,
|
|
223
|
+
// destroys native selections, and resets embedded media on host updates.
|
|
224
|
+
const MarkdownLinkContext = createContext<Pick<MarkdownProps, "onSandboxFile" | "artifactHref">>(
|
|
225
|
+
{},
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const markdownComponents: Components = {
|
|
229
|
+
...baseComponents,
|
|
230
|
+
p: ({ children, node, ...props }) => {
|
|
231
|
+
const containsArtifact = node?.children.some(
|
|
232
|
+
(child) =>
|
|
233
|
+
child.type === "element" &&
|
|
234
|
+
child.tagName === "img" &&
|
|
235
|
+
typeof child.properties.src === "string" &&
|
|
236
|
+
retainedImageId(child.properties.src),
|
|
237
|
+
);
|
|
238
|
+
const Tag = containsArtifact ? "div" : "p";
|
|
239
|
+
return (
|
|
240
|
+
<Tag className="my-2.5 leading-7 first:mt-0 last:mb-0" {...props}>
|
|
241
|
+
{children}
|
|
242
|
+
</Tag>
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
a: ({ children, href, ...props }) => {
|
|
246
|
+
const { onSandboxFile, artifactHref } = useContext(MarkdownLinkContext);
|
|
247
|
+
const artifactId = href ? retainedImageId(href) : null;
|
|
248
|
+
if (artifactId) {
|
|
249
|
+
const destination = artifactHref?.(artifactId);
|
|
250
|
+
return destination ? (
|
|
248
251
|
<a
|
|
249
252
|
className={MARKDOWN_LINK_CLASS}
|
|
253
|
+
href={defaultUrlTransform(destination)}
|
|
250
254
|
target="_blank"
|
|
251
255
|
rel="noreferrer noopener"
|
|
252
|
-
href={href}
|
|
253
|
-
{...props}
|
|
254
256
|
>
|
|
255
257
|
{children}
|
|
256
258
|
</a>
|
|
259
|
+
) : (
|
|
260
|
+
<span title="This artifact requires a workspace-aware host">
|
|
261
|
+
{children} (artifact unavailable)
|
|
262
|
+
</span>
|
|
257
263
|
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
|
|
264
|
+
}
|
|
265
|
+
const location = sandboxFileLocationFromHref(href);
|
|
266
|
+
if (location !== null) {
|
|
267
|
+
return (
|
|
268
|
+
<SandboxMarkdownLink location={location} onSandboxFile={onSandboxFile}>
|
|
269
|
+
{children}
|
|
270
|
+
</SandboxMarkdownLink>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
if (isSandboxHref(href) || !href) {
|
|
274
|
+
return (
|
|
275
|
+
<span
|
|
276
|
+
className="break-words text-og-fg-subtle"
|
|
277
|
+
aria-disabled="true"
|
|
278
|
+
title={
|
|
279
|
+
isSandboxHref(href)
|
|
280
|
+
? "This sandbox file reference is invalid"
|
|
281
|
+
: "This link is unavailable"
|
|
282
|
+
}
|
|
283
|
+
>
|
|
284
|
+
{children} (link unavailable)
|
|
285
|
+
</span>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
return (
|
|
289
|
+
<a
|
|
290
|
+
className={MARKDOWN_LINK_CLASS}
|
|
291
|
+
target="_blank"
|
|
292
|
+
rel="noreferrer noopener"
|
|
293
|
+
href={href}
|
|
294
|
+
{...props}
|
|
295
|
+
>
|
|
296
|
+
{children}
|
|
297
|
+
</a>
|
|
298
|
+
);
|
|
299
|
+
},
|
|
300
|
+
};
|
|
261
301
|
|
|
262
302
|
function SandboxMarkdownLink({
|
|
263
303
|
location,
|
|
@@ -371,7 +411,7 @@ function MarkdownImage({ src, alt }: ComponentPropsWithoutRef<"img">) {
|
|
|
371
411
|
}
|
|
372
412
|
|
|
373
413
|
const markdownUrlTransform: UrlTransform = (url, key, node) =>
|
|
374
|
-
(key === "href" && node.tagName === "a" && isSandboxHref(url)) ||
|
|
414
|
+
(key === "href" && node.tagName === "a" && (isSandboxHref(url) || retainedImageId(url))) ||
|
|
375
415
|
(key === "src" && node.tagName === "img" && retainedImageId(url))
|
|
376
416
|
? url
|
|
377
417
|
: defaultUrlTransform(url);
|
|
@@ -546,6 +586,7 @@ function MarkdownTable({ children, className, ...props }: ComponentPropsWithoutR
|
|
|
546
586
|
|
|
547
587
|
function MarkdownImpl({
|
|
548
588
|
children,
|
|
589
|
+
artifactHref,
|
|
549
590
|
className,
|
|
550
591
|
streaming = false,
|
|
551
592
|
onSandboxFile,
|
|
@@ -640,7 +681,10 @@ function MarkdownImpl({
|
|
|
640
681
|
// fences don't snap to final GFM one commit before the crystallize morph.
|
|
641
682
|
// Reveal identity still tracks the true source (`children`).
|
|
642
683
|
const parseText = streaming || revealActive ? softenStreamingMarkdown(children) : children;
|
|
643
|
-
const
|
|
684
|
+
const linkContext = useMemo(
|
|
685
|
+
() => ({ onSandboxFile, artifactHref }),
|
|
686
|
+
[onSandboxFile, artifactHref],
|
|
687
|
+
);
|
|
644
688
|
|
|
645
689
|
const interactiveContext = useMemo(
|
|
646
690
|
() => ({
|
|
@@ -655,27 +699,29 @@ function MarkdownImpl({
|
|
|
655
699
|
// `min-w-0` lets the prose shrink inside flex parents (message bubbles) so
|
|
656
700
|
// long links and code blocks wrap/scroll instead of forcing overflow.
|
|
657
701
|
return (
|
|
658
|
-
<
|
|
659
|
-
<
|
|
660
|
-
<
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
<ReactMarkdown
|
|
669
|
-
remarkPlugins={[remarkGfm]}
|
|
670
|
-
rehypePlugins={rehypePlugins}
|
|
671
|
-
components={components}
|
|
672
|
-
urlTransform={markdownUrlTransform}
|
|
702
|
+
<MarkdownLinkContext.Provider value={linkContext}>
|
|
703
|
+
<InteractiveContext.Provider value={interactiveContext}>
|
|
704
|
+
<TooltipProvider delayDuration={400}>
|
|
705
|
+
<div
|
|
706
|
+
ref={bodyRef}
|
|
707
|
+
className={cn(
|
|
708
|
+
"og-markdown-body min-w-0 break-words",
|
|
709
|
+
settling && "og-markdown-settle",
|
|
710
|
+
className,
|
|
711
|
+
)}
|
|
673
712
|
>
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
713
|
+
<ReactMarkdown
|
|
714
|
+
remarkPlugins={[remarkGfm]}
|
|
715
|
+
rehypePlugins={rehypePlugins}
|
|
716
|
+
components={markdownComponents}
|
|
717
|
+
urlTransform={markdownUrlTransform}
|
|
718
|
+
>
|
|
719
|
+
{parseText}
|
|
720
|
+
</ReactMarkdown>
|
|
721
|
+
</div>
|
|
722
|
+
</TooltipProvider>
|
|
723
|
+
</InteractiveContext.Provider>
|
|
724
|
+
</MarkdownLinkContext.Provider>
|
|
679
725
|
);
|
|
680
726
|
}
|
|
681
727
|
|