@tangle-network/sandbox-ui 0.3.7 → 0.3.10
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/active-sessions-store-CeOmXgv5.d.ts +85 -0
- package/dist/artifact-pane-Bh45Ssco.d.ts +24 -0
- package/dist/{chat-container-B34uj-J1.d.ts → chat-container-Dn1jWtWo.d.ts} +15 -3
- package/dist/chat.d.ts +16 -4
- package/dist/chat.js +2 -2
- package/dist/{chunk-PXRPYAMM.js → chunk-6H3EFUUC.js} +96 -74
- package/dist/{chunk-WUR652Y3.js → chunk-72UEKFZ2.js} +113 -89
- package/dist/{chunk-5LV6DZZF.js → chunk-FOQTE67I.js} +278 -21
- package/dist/chunk-MGCVTFKB.js +10910 -0
- package/dist/chunk-OEX7NZE3.js +321 -0
- package/dist/chunk-Q56BYXQF.js +61 -0
- package/dist/{chunk-ZSNOGOUX.js → chunk-RQOX5JRR.js} +541 -76
- package/dist/{chunk-PDV7W4NY.js → chunk-SULQQJPB.js} +1 -56
- package/dist/chunk-W4LM3QYZ.js +54 -0
- package/dist/{chunk-JF6E2DS5.js → chunk-ZYGWTIWO.js} +171 -155
- package/dist/document-editor-pane-Bk-9MQmw.d.ts +116 -0
- package/dist/document-editor-pane-GRIQOJHB.js +11 -0
- package/dist/editor.d.ts +7 -84
- package/dist/editor.js +18 -699
- package/dist/{expanded-tool-detail-BDi_h_dZ.d.ts → expanded-tool-detail-DM5M_T9h.d.ts} +10 -2
- package/dist/{file-tabs-CmaoDVBI.d.ts → file-tabs-BLfxfmAH.d.ts} +1 -22
- package/dist/files.d.ts +25 -3
- package/dist/files.js +2 -1
- package/dist/hooks.d.ts +3 -1
- package/dist/hooks.js +6 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.js +21 -8
- package/dist/pages.js +4 -2
- package/dist/primitives.js +4 -2
- package/dist/run.d.ts +1 -1
- package/dist/run.js +1 -1
- package/dist/sdk-hooks.d.ts +32 -1
- package/dist/sdk-hooks.js +6 -1
- package/dist/stores.d.ts +1 -0
- package/dist/stores.js +60 -1
- package/dist/types.d.ts +2 -0
- package/dist/workspace.d.ts +84 -6
- package/dist/workspace.js +10 -4
- package/package.json +17 -6
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as nanostores from 'nanostores';
|
|
2
|
+
|
|
3
|
+
type SessionProjectKey = string | number;
|
|
4
|
+
type ActiveSessionStatus = "idle" | "running" | "attention-needed" | "error";
|
|
5
|
+
type ActiveSessionReconnectState = "idle" | "reconnecting" | "failed";
|
|
6
|
+
type ActiveSessionConnectionState = "disconnected" | "connecting" | "connected" | "reconnecting" | "error";
|
|
7
|
+
type ActiveSessionTransportMode = "websocket" | "sse" | "polling" | "custom";
|
|
8
|
+
interface ActiveSessionRecord {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
projectId: SessionProjectKey | null;
|
|
11
|
+
projectLabel?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
href?: string;
|
|
14
|
+
registeredAt: number;
|
|
15
|
+
lastActivityAt: number;
|
|
16
|
+
lastEventAt: number | null;
|
|
17
|
+
status: ActiveSessionStatus;
|
|
18
|
+
isRunning: boolean;
|
|
19
|
+
isForeground: boolean;
|
|
20
|
+
needsAttention: boolean;
|
|
21
|
+
connectionState: ActiveSessionConnectionState;
|
|
22
|
+
reconnectState: ActiveSessionReconnectState;
|
|
23
|
+
transportMode: ActiveSessionTransportMode | null;
|
|
24
|
+
lastError: string | null;
|
|
25
|
+
metadata?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
interface ActiveSessionsState {
|
|
28
|
+
sessions: Record<string, ActiveSessionRecord>;
|
|
29
|
+
lastUpdatedAt: number;
|
|
30
|
+
}
|
|
31
|
+
interface RegisterActiveSessionOptions {
|
|
32
|
+
sessionId: string;
|
|
33
|
+
projectId?: SessionProjectKey | null;
|
|
34
|
+
projectLabel?: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
href?: string;
|
|
37
|
+
metadata?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
interface ActiveSessionConnectionOptions {
|
|
40
|
+
connectionState: ActiveSessionConnectionState;
|
|
41
|
+
reconnectState?: ActiveSessionReconnectState;
|
|
42
|
+
transportMode?: ActiveSessionTransportMode | null;
|
|
43
|
+
lastError?: string | null;
|
|
44
|
+
lastEventAt?: number | null;
|
|
45
|
+
}
|
|
46
|
+
interface ActiveSessionActivityOptions {
|
|
47
|
+
lastEventAt?: number | null;
|
|
48
|
+
}
|
|
49
|
+
interface ActiveProjectActivity {
|
|
50
|
+
projectId: SessionProjectKey;
|
|
51
|
+
projectLabel?: string;
|
|
52
|
+
activeSessionCount: number;
|
|
53
|
+
runningSessionIds: string[];
|
|
54
|
+
lastActivityAt: number;
|
|
55
|
+
}
|
|
56
|
+
declare const activeSessionsAtom: nanostores.PreinitializedWritableAtom<ActiveSessionsState> & object;
|
|
57
|
+
declare function registerActiveSession(options: RegisterActiveSessionOptions): void;
|
|
58
|
+
declare function unregisterActiveSession(sessionId: string): void;
|
|
59
|
+
declare function setForegroundActiveSession(sessionId: string | null): void;
|
|
60
|
+
declare function updateActiveSessionMeta(sessionId: string, meta: Partial<Pick<ActiveSessionRecord, "title" | "href" | "projectId" | "projectLabel" | "metadata">>): void;
|
|
61
|
+
declare function setActiveSessionConnection(sessionId: string, options: ActiveSessionConnectionOptions): void;
|
|
62
|
+
declare function setActiveSessionRunning(sessionId: string, isRunning: boolean, options?: ActiveSessionActivityOptions): void;
|
|
63
|
+
declare function setActiveSessionAttention(sessionId: string, needsAttention: boolean, options?: ActiveSessionActivityOptions): void;
|
|
64
|
+
declare function setActiveSessionError(sessionId: string, error: string | null): void;
|
|
65
|
+
declare function bumpActiveSessionActivity(sessionId: string, options?: ActiveSessionActivityOptions): void;
|
|
66
|
+
declare function resetActiveSessions(): void;
|
|
67
|
+
declare function getAllActiveSessions(state: ActiveSessionsState): ActiveSessionRecord[];
|
|
68
|
+
declare function getActiveSession(state: ActiveSessionsState, sessionId: string): ActiveSessionRecord | null;
|
|
69
|
+
declare function getSessionsForProject(state: ActiveSessionsState, projectId: SessionProjectKey): ActiveSessionRecord[];
|
|
70
|
+
declare function getSessionsForNavbar(state: ActiveSessionsState, projectId?: SessionProjectKey | null): ActiveSessionRecord[];
|
|
71
|
+
declare function getSessionsByActivity(state: ActiveSessionsState): ActiveSessionRecord[];
|
|
72
|
+
declare function getTotalRunningSessionCount(state: ActiveSessionsState): number;
|
|
73
|
+
declare function hasBackgroundRunningSessions(state: ActiveSessionsState): boolean;
|
|
74
|
+
declare function getAllProjectActivity(state: ActiveSessionsState): ActiveProjectActivity[];
|
|
75
|
+
declare function useActiveSessionsState(): ActiveSessionsState;
|
|
76
|
+
declare function useActiveSessions(): ActiveSessionRecord[];
|
|
77
|
+
declare function useActiveSession(sessionId: string | null): ActiveSessionRecord | null;
|
|
78
|
+
declare function useProjectSessions(projectId: SessionProjectKey | null): ActiveSessionRecord[];
|
|
79
|
+
declare function useNavbarSessions(projectId?: SessionProjectKey | null): ActiveSessionRecord[];
|
|
80
|
+
declare function useSessionsByActivity(): ActiveSessionRecord[];
|
|
81
|
+
declare function useProjectActivity(): ActiveProjectActivity[];
|
|
82
|
+
declare function useTotalRunningSessions(): number;
|
|
83
|
+
declare function useHasBackgroundRunningSessions(): boolean;
|
|
84
|
+
|
|
85
|
+
export { type ActiveProjectActivity as A, updateActiveSessionMeta as B, useActiveSession as C, useActiveSessions as D, useActiveSessionsState as E, useHasBackgroundRunningSessions as F, useNavbarSessions as G, useProjectActivity as H, useProjectSessions as I, useSessionsByActivity as J, useTotalRunningSessions as K, type RegisterActiveSessionOptions as R, type SessionProjectKey as S, type ActiveSessionActivityOptions as a, type ActiveSessionConnectionOptions as b, type ActiveSessionConnectionState as c, type ActiveSessionReconnectState as d, type ActiveSessionRecord as e, type ActiveSessionStatus as f, type ActiveSessionTransportMode as g, type ActiveSessionsState as h, activeSessionsAtom as i, bumpActiveSessionActivity as j, getActiveSession as k, getAllActiveSessions as l, getAllProjectActivity as m, getSessionsByActivity as n, getSessionsForNavbar as o, getSessionsForProject as p, getTotalRunningSessionCount as q, hasBackgroundRunningSessions as r, registerActiveSession as s, resetActiveSessions as t, setActiveSessionAttention as u, setActiveSessionConnection as v, setActiveSessionError as w, setActiveSessionRunning as x, setForegroundActiveSession as y, unregisterActiveSession as z };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ArtifactPaneProps {
|
|
5
|
+
eyebrow?: ReactNode;
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
subtitle?: ReactNode;
|
|
8
|
+
meta?: ReactNode;
|
|
9
|
+
headerActions?: ReactNode;
|
|
10
|
+
tabs?: ReactNode;
|
|
11
|
+
toolbar?: ReactNode;
|
|
12
|
+
footer?: ReactNode;
|
|
13
|
+
emptyState?: ReactNode;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
contentClassName?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* ArtifactPane — shared frame for files, previews, documents, inspectors, and
|
|
20
|
+
* other artifact-like surfaces inside sandbox applications.
|
|
21
|
+
*/
|
|
22
|
+
declare function ArtifactPane({ eyebrow, title, subtitle, meta, headerActions, tabs, toolbar, footer, emptyState, children, className, contentClassName, }: ArtifactPaneProps): react_jsx_runtime.JSX.Element;
|
|
23
|
+
|
|
24
|
+
export { type ArtifactPaneProps as A, ArtifactPane as a };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import { S as SessionMessage, a as SessionPart } from './parts-CyGkM6Fp.js';
|
|
4
|
+
import { S as SessionMessage, a as SessionPart, b as ToolPart } from './parts-CyGkM6Fp.js';
|
|
4
5
|
import { A as AgentBranding } from './branding-DCi5VEik.js';
|
|
5
6
|
import { C as CustomToolRenderer } from './tool-display-Ct9nFAzJ.js';
|
|
7
|
+
import { R as Run } from './run-CtFZ6s-D.js';
|
|
6
8
|
import { OpenUIAction } from './openui.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -62,11 +64,21 @@ interface ChatContainerProps {
|
|
|
62
64
|
onOpenUIAction?: (action: OpenUIAction) => void;
|
|
63
65
|
/** Enable rendering OpenUI schemas inline in the chat timeline. Defaults to true. */
|
|
64
66
|
enableOpenUI?: boolean;
|
|
67
|
+
/** Optional actions rendered beside each grouped assistant run. */
|
|
68
|
+
renderRunActions?: (run: Run) => ReactNode;
|
|
69
|
+
/** Optional actions rendered below each user message bubble. */
|
|
70
|
+
renderUserMessageActions?: (message: SessionMessage, parts: SessionPart[]) => ReactNode;
|
|
71
|
+
/** Optional actions rendered beside individual tool items. */
|
|
72
|
+
renderToolActions?: (part: ToolPart, options: {
|
|
73
|
+
run: Run;
|
|
74
|
+
messageId: string;
|
|
75
|
+
partIndex: number;
|
|
76
|
+
}) => ReactNode;
|
|
65
77
|
}
|
|
66
78
|
/**
|
|
67
79
|
* Full chat container: message list + auto-scroll + input area.
|
|
68
80
|
* Orchestrates useRunGroups, useRunCollapseState, and useAutoScroll.
|
|
69
81
|
*/
|
|
70
|
-
declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, onSend, onCancel, branding, placeholder, className, hideInput, renderToolDetail, presentation, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, disabled, onOpenUIAction, enableOpenUI, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
|
|
82
|
+
declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, onSend, onCancel, branding, placeholder, className, hideInput, renderToolDetail, presentation, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, disabled, onOpenUIAction, enableOpenUI, renderRunActions, renderUserMessageActions, renderToolActions, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
|
|
71
83
|
|
|
72
|
-
export { ChatContainer as C, type PendingFile as P,
|
|
84
|
+
export { ChatContainer as C, type PendingFile as P, type ChatContainerProps as a, ChatInput as b, type ChatInputProps as c };
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { C as ChatContainer,
|
|
1
|
+
export { C as ChatContainer, a as ChatContainerProps, b as ChatInput, c as ChatInputProps, P as PendingFile } from './chat-container-Dn1jWtWo.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { G as GroupedMessage } from './run-CtFZ6s-D.js';
|
|
6
|
-
import { a as SessionPart, S as SessionMessage } from './parts-CyGkM6Fp.js';
|
|
6
|
+
import { a as SessionPart, S as SessionMessage, b as ToolPart } from './parts-CyGkM6Fp.js';
|
|
7
7
|
import { A as AgentBranding } from './branding-DCi5VEik.js';
|
|
8
8
|
import { C as CustomToolRenderer } from './tool-display-Ct9nFAzJ.js';
|
|
9
9
|
import { T as ToolCallData } from './tool-call-feed-D5Ume-Pt.js';
|
|
@@ -30,22 +30,34 @@ interface MessageListProps {
|
|
|
30
30
|
onToggleCollapse: (runId: string) => void;
|
|
31
31
|
branding?: AgentBranding;
|
|
32
32
|
renderToolDetail?: CustomToolRenderer;
|
|
33
|
+
renderRunActions?: (group: Extract<GroupedMessage, {
|
|
34
|
+
type: "run";
|
|
35
|
+
}>["run"]) => ReactNode;
|
|
36
|
+
renderUserMessageActions?: (message: SessionMessage, parts: SessionPart[]) => ReactNode;
|
|
37
|
+
renderToolActions?: (part: ToolPart, options: {
|
|
38
|
+
run: Extract<GroupedMessage, {
|
|
39
|
+
type: "run";
|
|
40
|
+
}>["run"];
|
|
41
|
+
messageId: string;
|
|
42
|
+
partIndex: number;
|
|
43
|
+
}) => ReactNode;
|
|
33
44
|
}
|
|
34
45
|
/**
|
|
35
46
|
* Maps GroupedMessage[] to UserMessage and RunGroup components.
|
|
36
47
|
* This is the main render list for the chat view.
|
|
37
48
|
*/
|
|
38
|
-
declare const MessageList: React.MemoExoticComponent<({ groups, partMap, isCollapsed, onToggleCollapse, branding, renderToolDetail, }: MessageListProps) => react_jsx_runtime.JSX.Element>;
|
|
49
|
+
declare const MessageList: React.MemoExoticComponent<({ groups, partMap, isCollapsed, onToggleCollapse, branding, renderToolDetail, renderRunActions, renderUserMessageActions, renderToolActions, }: MessageListProps) => react_jsx_runtime.JSX.Element>;
|
|
39
50
|
|
|
40
51
|
interface UserMessageProps {
|
|
41
52
|
message: SessionMessage;
|
|
42
53
|
parts: SessionPart[];
|
|
54
|
+
actions?: ReactNode;
|
|
43
55
|
}
|
|
44
56
|
/**
|
|
45
57
|
* Simple user message bubble.
|
|
46
58
|
* Renders text parts from the user's message.
|
|
47
59
|
*/
|
|
48
|
-
declare const UserMessage: React.MemoExoticComponent<({ message, parts }: UserMessageProps) => react_jsx_runtime.JSX.Element | null>;
|
|
60
|
+
declare const UserMessage: React.MemoExoticComponent<({ message, parts, actions }: UserMessageProps) => react_jsx_runtime.JSX.Element | null>;
|
|
49
61
|
|
|
50
62
|
interface ThinkingIndicatorProps {
|
|
51
63
|
className?: string;
|
package/dist/chat.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
MessageList,
|
|
7
7
|
ThinkingIndicator,
|
|
8
8
|
UserMessage
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6H3EFUUC.js";
|
|
10
10
|
import "./chunk-CNWVHQFY.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-72UEKFZ2.js";
|
|
12
12
|
import "./chunk-HRMUF35V.js";
|
|
13
13
|
import "./chunk-CJ2RYVZH.js";
|
|
14
14
|
import "./chunk-BX6AQMUS.js";
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
InlineThinkingItem,
|
|
8
8
|
RunGroup
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-72UEKFZ2.js";
|
|
10
10
|
import {
|
|
11
11
|
ToolCallGroup,
|
|
12
12
|
ToolCallStep
|
|
@@ -27,12 +27,15 @@ import {
|
|
|
27
27
|
// src/chat/user-message.tsx
|
|
28
28
|
import { memo } from "react";
|
|
29
29
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
30
|
-
var UserMessage = memo(({ message, parts }) => {
|
|
30
|
+
var UserMessage = memo(({ message, parts, actions }) => {
|
|
31
31
|
const textContent = parts.filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
32
32
|
if (!textContent.trim()) return null;
|
|
33
|
-
return /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs("div", { className: "max-w-[
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
|
|
33
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs("div", { className: "flex max-w-[82%] flex-col items-end gap-2", children: [
|
|
34
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full rounded-[calc(var(--radius-xl)+2px)] rounded-br-[var(--radius-sm)] border border-[var(--border-accent)] bg-[radial-gradient(circle_at_top_right,rgba(96,165,250,0.18),transparent_45%),linear-gradient(135deg,rgba(98,114,243,0.18),rgba(98,114,243,0.06)_55%,rgba(255,255,255,0.02))] px-4 py-3.5 shadow-[var(--shadow-accent)] backdrop-blur-sm", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-[var(--brand-cool)]", children: "You" }),
|
|
36
|
+
/* @__PURE__ */ jsx("div", { className: "text-[15px] leading-7 text-[var(--text-primary)]", children: /* @__PURE__ */ jsx(Markdown, { className: "tangle-prose", children: textContent }) })
|
|
37
|
+
] }),
|
|
38
|
+
actions ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-end gap-1.5 text-xs text-[var(--text-muted)]", children: actions }) : null
|
|
36
39
|
] }) });
|
|
37
40
|
});
|
|
38
41
|
UserMessage.displayName = "UserMessage";
|
|
@@ -47,15 +50,20 @@ var MessageList = memo2(
|
|
|
47
50
|
isCollapsed,
|
|
48
51
|
onToggleCollapse,
|
|
49
52
|
branding,
|
|
50
|
-
renderToolDetail
|
|
53
|
+
renderToolDetail,
|
|
54
|
+
renderRunActions,
|
|
55
|
+
renderUserMessageActions,
|
|
56
|
+
renderToolActions
|
|
51
57
|
}) => {
|
|
52
58
|
return /* @__PURE__ */ jsx2("div", { className: "space-y-3", children: groups.map((group) => {
|
|
53
59
|
if (group.type === "user") {
|
|
60
|
+
const messageParts = partMap[group.message.id] ?? [];
|
|
54
61
|
return /* @__PURE__ */ jsx2(
|
|
55
62
|
UserMessage,
|
|
56
63
|
{
|
|
57
64
|
message: group.message,
|
|
58
|
-
parts:
|
|
65
|
+
parts: messageParts,
|
|
66
|
+
actions: renderUserMessageActions?.(group.message, messageParts)
|
|
59
67
|
},
|
|
60
68
|
group.message.id
|
|
61
69
|
);
|
|
@@ -68,7 +76,9 @@ var MessageList = memo2(
|
|
|
68
76
|
collapsed: isCollapsed(group.run.id),
|
|
69
77
|
onToggle: () => onToggleCollapse(group.run.id),
|
|
70
78
|
branding,
|
|
71
|
-
renderToolDetail
|
|
79
|
+
renderToolDetail,
|
|
80
|
+
headerActions: renderRunActions?.(group.run),
|
|
81
|
+
renderToolActions
|
|
72
82
|
},
|
|
73
83
|
group.run.id
|
|
74
84
|
);
|
|
@@ -93,8 +103,8 @@ function ChatMessage({
|
|
|
93
103
|
"div",
|
|
94
104
|
{
|
|
95
105
|
className: cn(
|
|
96
|
-
"flex gap-
|
|
97
|
-
isUser ? "border-[var(--border-accent)] bg-[linear-gradient(135deg,rgba(98,114,243,0.
|
|
106
|
+
"flex gap-4 rounded-[calc(var(--radius-xl)+2px)] border px-4 py-4 shadow-[var(--shadow-card)] backdrop-blur-sm",
|
|
107
|
+
isUser ? "border-[var(--border-accent)] bg-[radial-gradient(circle_at_top_right,rgba(96,165,250,0.18),transparent_42%),linear-gradient(135deg,rgba(98,114,243,0.18),rgba(98,114,243,0.06)_55%,rgba(255,255,255,0.02))]" : "border-[var(--border-subtle)] bg-[radial-gradient(circle_at_top_left,rgba(96,165,250,0.12),transparent_34%),linear-gradient(180deg,rgba(255,255,255,0.03),transparent_32%),var(--bg-card)]",
|
|
98
108
|
className
|
|
99
109
|
),
|
|
100
110
|
children: [
|
|
@@ -102,20 +112,20 @@ function ChatMessage({
|
|
|
102
112
|
"div",
|
|
103
113
|
{
|
|
104
114
|
className: cn(
|
|
105
|
-
"mt-0.5 flex h-
|
|
106
|
-
isUser ? "border-[var(--border-accent)] bg-[
|
|
115
|
+
"mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-[calc(var(--radius-md)+2px)] border shadow-[var(--shadow-accent)]",
|
|
116
|
+
isUser ? "border-[var(--border-accent)] bg-[linear-gradient(135deg,rgba(82,164,255,0.24),rgba(82,164,255,0.08))] text-[var(--brand-cool)]" : "border-[var(--border-subtle)] bg-[linear-gradient(135deg,rgba(77,203,255,0.24),rgba(77,203,255,0.08))] text-[var(--brand-glow)]"
|
|
107
117
|
),
|
|
108
118
|
children: isUser ? /* @__PURE__ */ jsx3(User, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(Bot, { className: "h-4 w-4" })
|
|
109
119
|
}
|
|
110
120
|
),
|
|
111
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
121
|
+
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
112
122
|
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
113
|
-
/* @__PURE__ */ jsx3("span", { className: "text-
|
|
114
|
-
timestamp && /* @__PURE__ */ jsx3("span", { className: "text-
|
|
123
|
+
/* @__PURE__ */ jsx3("span", { className: "text-[11px] font-semibold uppercase tracking-[0.14em] text-[var(--text-secondary)]", children: isUser ? "You" : "Agent" }),
|
|
124
|
+
timestamp && /* @__PURE__ */ jsx3("span", { className: "text-[11px] text-[var(--text-muted)]", children: formatTime(timestamp) })
|
|
115
125
|
] }),
|
|
116
|
-
isUser ? /* @__PURE__ */ jsx3("div", { className: "text-
|
|
117
|
-
content && /* @__PURE__ */ jsx3(Markdown, { className: "tangle-prose", children: content }),
|
|
118
|
-
isStreaming && /* @__PURE__ */ jsx3("span", { className: "inline-block w-2
|
|
126
|
+
isUser ? /* @__PURE__ */ jsx3("div", { className: "whitespace-pre-wrap text-[15px] leading-7 text-[var(--text-primary)]", children: content }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
127
|
+
content && /* @__PURE__ */ jsx3(Markdown, { className: "tangle-prose text-[15px] leading-7", children: content }),
|
|
128
|
+
isStreaming && /* @__PURE__ */ jsx3("span", { className: "ml-0.5 inline-block h-4 w-2 animate-pulse rounded-sm bg-[var(--brand-cool)] align-text-bottom" })
|
|
119
129
|
] }),
|
|
120
130
|
toolCalls
|
|
121
131
|
] })
|
|
@@ -405,8 +415,8 @@ function ChatInput({
|
|
|
405
415
|
"span",
|
|
406
416
|
{
|
|
407
417
|
className: cn(
|
|
408
|
-
"inline-flex items-center gap-1.5 rounded-[var(--radius-full)] border px-3 py-1.5 text-xs shadow-[var(--shadow-card)]",
|
|
409
|
-
"border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.
|
|
418
|
+
"inline-flex items-center gap-1.5 rounded-[var(--radius-full)] border px-3 py-1.5 text-xs shadow-[var(--shadow-card)] backdrop-blur-sm",
|
|
419
|
+
"border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02))]",
|
|
410
420
|
f.status === "error" && "border-[var(--code-error)]/30 text-[var(--code-error)]",
|
|
411
421
|
f.status !== "error" && "text-[var(--text-secondary)]"
|
|
412
422
|
),
|
|
@@ -427,65 +437,71 @@ function ChatInput({
|
|
|
427
437
|
},
|
|
428
438
|
f.id
|
|
429
439
|
)) }),
|
|
430
|
-
/* @__PURE__ */ jsx6("div", { className: "rounded-[
|
|
431
|
-
|
|
440
|
+
/* @__PURE__ */ jsx6("div", { className: "rounded-[28px] border border-[var(--border-subtle)] bg-[radial-gradient(circle_at_top,rgba(96,165,250,0.16),transparent_42%),linear-gradient(135deg,rgba(98,114,243,0.12),rgba(255,255,255,0.03)_42%,transparent)] p-[1px] shadow-[var(--shadow-accent)]", children: /* @__PURE__ */ jsxs5("div", { className: "rounded-[26px] border border-white/5 bg-[linear-gradient(180deg,rgba(255,255,255,0.03),transparent_35%),var(--bg-card)] px-3 py-3.5 transition-colors focus-within:border-[var(--border-accent)]", children: [
|
|
441
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-2 flex items-center justify-between gap-3 px-1", children: [
|
|
442
|
+
/* @__PURE__ */ jsx6("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-[var(--text-muted)]", children: "Agent Command Deck" }),
|
|
443
|
+
/* @__PURE__ */ jsx6("div", { className: "text-[11px] text-[var(--text-muted)]", children: isStreaming ? "Streaming response" : "Ready for next instruction" })
|
|
444
|
+
] }),
|
|
445
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-end gap-2", children: [
|
|
446
|
+
onAttach && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
447
|
+
/* @__PURE__ */ jsx6(
|
|
448
|
+
"button",
|
|
449
|
+
{
|
|
450
|
+
type: "button",
|
|
451
|
+
onClick: handleAttachClick,
|
|
452
|
+
disabled: isStreaming,
|
|
453
|
+
"aria-label": "Attach files",
|
|
454
|
+
className: "mb-0.5 shrink-0 rounded-[var(--radius-md)] border border-transparent p-2 text-[var(--text-muted)] transition-colors hover:border-[var(--border-subtle)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)] disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/60",
|
|
455
|
+
children: /* @__PURE__ */ jsx6(Paperclip, { className: "h-4 w-4" })
|
|
456
|
+
}
|
|
457
|
+
),
|
|
458
|
+
/* @__PURE__ */ jsx6(
|
|
459
|
+
"input",
|
|
460
|
+
{
|
|
461
|
+
ref: fileInputRef,
|
|
462
|
+
type: "file",
|
|
463
|
+
multiple: true,
|
|
464
|
+
className: "hidden",
|
|
465
|
+
onChange: handleFileChange,
|
|
466
|
+
accept: ".pdf,.csv,.xlsx,.xls,.jpg,.jpeg,.png,.gif,.txt,.json,.yaml,.yml"
|
|
467
|
+
}
|
|
468
|
+
)
|
|
469
|
+
] }),
|
|
432
470
|
/* @__PURE__ */ jsx6(
|
|
471
|
+
"textarea",
|
|
472
|
+
{
|
|
473
|
+
ref: textareaRef,
|
|
474
|
+
value,
|
|
475
|
+
onChange: handleChange,
|
|
476
|
+
onKeyDown: handleKeyDown,
|
|
477
|
+
placeholder,
|
|
478
|
+
disabled: isStreaming || disabled,
|
|
479
|
+
rows: 1,
|
|
480
|
+
"aria-label": "Message input",
|
|
481
|
+
className: "min-h-[36px] max-h-[160px] flex-1 resize-none bg-transparent text-[15px] leading-7 text-[var(--text-primary)] placeholder:text-[var(--text-muted)] disabled:opacity-50 focus-visible:outline-none"
|
|
482
|
+
}
|
|
483
|
+
),
|
|
484
|
+
isStreaming ? /* @__PURE__ */ jsx6(
|
|
433
485
|
"button",
|
|
434
486
|
{
|
|
435
487
|
type: "button",
|
|
436
|
-
onClick:
|
|
437
|
-
|
|
438
|
-
"
|
|
439
|
-
|
|
440
|
-
children: /* @__PURE__ */ jsx6(Paperclip, { className: "h-4 w-4" })
|
|
488
|
+
onClick: onCancel,
|
|
489
|
+
"aria-label": "Stop response",
|
|
490
|
+
className: "mb-0.5 shrink-0 rounded-[var(--radius-lg)] border border-[var(--code-error)]/20 bg-[var(--code-error)]/14 p-2.5 text-[var(--code-error)] transition-colors hover:bg-[var(--code-error)]/24 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--code-error)]/50",
|
|
491
|
+
children: /* @__PURE__ */ jsx6(Square, { className: "h-4 w-4" })
|
|
441
492
|
}
|
|
442
|
-
)
|
|
443
|
-
|
|
444
|
-
"input",
|
|
493
|
+
) : /* @__PURE__ */ jsx6(
|
|
494
|
+
"button",
|
|
445
495
|
{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
496
|
+
type: "button",
|
|
497
|
+
onClick: handleSend,
|
|
498
|
+
disabled: !value.trim() || disabled,
|
|
499
|
+
"aria-label": "Send message",
|
|
500
|
+
className: "mb-0.5 shrink-0 rounded-[var(--radius-lg)] border border-[var(--border-accent)] bg-[linear-gradient(135deg,rgba(82,164,255,0.24),rgba(82,164,255,0.08))] p-2.5 text-[var(--brand-cool)] transition-colors hover:translate-y-[-1px] hover:bg-[linear-gradient(135deg,rgba(82,164,255,0.28),rgba(82,164,255,0.12))] disabled:opacity-30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/60",
|
|
501
|
+
children: /* @__PURE__ */ jsx6(Send, { className: "h-4 w-4" })
|
|
452
502
|
}
|
|
453
503
|
)
|
|
454
|
-
] })
|
|
455
|
-
/* @__PURE__ */ jsx6(
|
|
456
|
-
"textarea",
|
|
457
|
-
{
|
|
458
|
-
ref: textareaRef,
|
|
459
|
-
value,
|
|
460
|
-
onChange: handleChange,
|
|
461
|
-
onKeyDown: handleKeyDown,
|
|
462
|
-
placeholder,
|
|
463
|
-
disabled: isStreaming || disabled,
|
|
464
|
-
rows: 1,
|
|
465
|
-
"aria-label": "Message input",
|
|
466
|
-
className: "min-h-[28px] max-h-[160px] flex-1 resize-none bg-transparent text-sm leading-relaxed text-[var(--text-primary)] placeholder:text-[var(--text-muted)] disabled:opacity-50 focus-visible:outline-none"
|
|
467
|
-
}
|
|
468
|
-
),
|
|
469
|
-
isStreaming ? /* @__PURE__ */ jsx6(
|
|
470
|
-
"button",
|
|
471
|
-
{
|
|
472
|
-
type: "button",
|
|
473
|
-
onClick: onCancel,
|
|
474
|
-
"aria-label": "Stop response",
|
|
475
|
-
className: "mb-0.5 shrink-0 rounded-[var(--radius-md)] bg-[var(--code-error)]/15 p-2 text-[var(--code-error)] transition-colors hover:bg-[var(--code-error)]/25 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--code-error)]/50",
|
|
476
|
-
children: /* @__PURE__ */ jsx6(Square, { className: "h-4 w-4" })
|
|
477
|
-
}
|
|
478
|
-
) : /* @__PURE__ */ jsx6(
|
|
479
|
-
"button",
|
|
480
|
-
{
|
|
481
|
-
type: "button",
|
|
482
|
-
onClick: handleSend,
|
|
483
|
-
disabled: !value.trim() || disabled,
|
|
484
|
-
"aria-label": "Send message",
|
|
485
|
-
className: "mb-0.5 shrink-0 rounded-[var(--radius-md)] bg-[var(--brand-cool)]/15 p-2 text-[var(--brand-cool)] transition-colors hover:bg-[var(--brand-cool)]/25 disabled:opacity-30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/60",
|
|
486
|
-
children: /* @__PURE__ */ jsx6(Send, { className: "h-4 w-4" })
|
|
487
|
-
}
|
|
488
|
-
)
|
|
504
|
+
] })
|
|
489
505
|
] }) }),
|
|
490
506
|
/* @__PURE__ */ jsxs5("div", { className: "mt-2 flex items-center justify-between px-1", children: [
|
|
491
507
|
/* @__PURE__ */ jsx6("div", { className: "flex items-center gap-2", children: modelLabel && /* @__PURE__ */ jsxs5(
|
|
@@ -494,7 +510,7 @@ function ChatInput({
|
|
|
494
510
|
type: "button",
|
|
495
511
|
onClick: onModelClick,
|
|
496
512
|
"aria-label": `Select model, current model ${modelLabel}`,
|
|
497
|
-
className: "inline-flex items-center gap-1 rounded-[var(--radius-full)] border border-[var(--border-subtle)] bg-[
|
|
513
|
+
className: "inline-flex items-center gap-1.5 rounded-[var(--radius-full)] border border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.04),transparent)] px-2.5 py-1 text-xs text-[var(--text-muted)] transition-colors hover:border-[var(--border-accent)] hover:text-[var(--text-secondary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/60",
|
|
498
514
|
children: [
|
|
499
515
|
/* @__PURE__ */ jsx6("span", { className: "w-1.5 h-1.5 rounded-full bg-[var(--code-success)]" }),
|
|
500
516
|
modelLabel
|
|
@@ -762,7 +778,10 @@ var ChatContainer = memo3(
|
|
|
762
778
|
onAttach,
|
|
763
779
|
disabled = false,
|
|
764
780
|
onOpenUIAction,
|
|
765
|
-
enableOpenUI = true
|
|
781
|
+
enableOpenUI = true,
|
|
782
|
+
renderRunActions,
|
|
783
|
+
renderUserMessageActions,
|
|
784
|
+
renderToolActions
|
|
766
785
|
}) => {
|
|
767
786
|
const scrollRef = useRef2(null);
|
|
768
787
|
const groups = useRunGroups({ messages, partMap, isStreaming });
|
|
@@ -800,7 +819,10 @@ var ChatContainer = memo3(
|
|
|
800
819
|
isCollapsed,
|
|
801
820
|
onToggleCollapse: toggleCollapse,
|
|
802
821
|
branding,
|
|
803
|
-
renderToolDetail
|
|
822
|
+
renderToolDetail,
|
|
823
|
+
renderRunActions,
|
|
824
|
+
renderUserMessageActions,
|
|
825
|
+
renderToolActions
|
|
804
826
|
}
|
|
805
827
|
) })
|
|
806
828
|
}
|