@tangle-network/sandbox-ui 0.3.6 → 0.3.7
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/{chat-container-C8eHLw8z.d.ts → chat-container-B34uj-J1.d.ts} +6 -1
- package/dist/chat.d.ts +2 -1
- package/dist/chat.js +5 -1
- package/dist/{chunk-TXI4MZAZ.js → chunk-CSIXZEKN.js} +152 -1
- package/dist/{chunk-4F2GJRGU.js → chunk-PXRPYAMM.js} +101 -4
- package/dist/{chunk-QGI5E7JD.js → chunk-ZSNOGOUX.js} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -3
- package/dist/primitives.d.ts +45 -1
- package/dist/primitives.js +5 -1
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.js +2 -2
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
3
3
|
import { S as SessionMessage, a as SessionPart } from './parts-CyGkM6Fp.js';
|
|
4
4
|
import { A as AgentBranding } from './branding-DCi5VEik.js';
|
|
5
5
|
import { C as CustomToolRenderer } from './tool-display-Ct9nFAzJ.js';
|
|
6
|
+
import { OpenUIAction } from './openui.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* ChatInput — message input bar with file attach, send/cancel, model selector.
|
|
@@ -57,11 +58,15 @@ interface ChatContainerProps {
|
|
|
57
58
|
onRemoveFile?: (id: string) => void;
|
|
58
59
|
onAttach?: (files: FileList) => void;
|
|
59
60
|
disabled?: boolean;
|
|
61
|
+
/** Callback when an OpenUI action button is pressed within inline OpenUI blocks. */
|
|
62
|
+
onOpenUIAction?: (action: OpenUIAction) => void;
|
|
63
|
+
/** Enable rendering OpenUI schemas inline in the chat timeline. Defaults to true. */
|
|
64
|
+
enableOpenUI?: boolean;
|
|
60
65
|
}
|
|
61
66
|
/**
|
|
62
67
|
* Full chat container: message list + auto-scroll + input area.
|
|
63
68
|
* Orchestrates useRunGroups, useRunCollapseState, and useAutoScroll.
|
|
64
69
|
*/
|
|
65
|
-
declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, onSend, onCancel, branding, placeholder, className, hideInput, renderToolDetail, presentation, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, disabled, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
|
|
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>;
|
|
66
71
|
|
|
67
72
|
export { ChatContainer as C, type PendingFile as P, ChatInput as a, type ChatInputProps as b, type ChatContainerProps as c };
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as ChatContainer, c as ChatContainerProps, a as ChatInput, b as ChatInputProps, P as PendingFile } from './chat-container-
|
|
1
|
+
export { C as ChatContainer, c as ChatContainerProps, a as ChatInput, b as ChatInputProps, P as PendingFile } from './chat-container-B34uj-J1.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';
|
|
@@ -7,6 +7,7 @@ import { a as SessionPart, S as SessionMessage } 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';
|
|
10
|
+
import './openui.js';
|
|
10
11
|
|
|
11
12
|
type MessageRole = "user" | "assistant" | "system";
|
|
12
13
|
interface ChatMessageProps {
|
package/dist/chat.js
CHANGED
|
@@ -6,13 +6,17 @@ import {
|
|
|
6
6
|
MessageList,
|
|
7
7
|
ThinkingIndicator,
|
|
8
8
|
UserMessage
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PXRPYAMM.js";
|
|
10
10
|
import "./chunk-CNWVHQFY.js";
|
|
11
11
|
import "./chunk-WUR652Y3.js";
|
|
12
12
|
import "./chunk-HRMUF35V.js";
|
|
13
13
|
import "./chunk-CJ2RYVZH.js";
|
|
14
14
|
import "./chunk-BX6AQMUS.js";
|
|
15
|
+
import "./chunk-YDBXQQLC.js";
|
|
16
|
+
import "./chunk-TQN3VR4F.js";
|
|
15
17
|
import "./chunk-LTFK464G.js";
|
|
18
|
+
import "./chunk-MXCSSOGH.js";
|
|
19
|
+
import "./chunk-HWLX5NME.js";
|
|
16
20
|
import "./chunk-RQHJBTEU.js";
|
|
17
21
|
export {
|
|
18
22
|
AgentTimeline,
|
|
@@ -530,6 +530,155 @@ var TerminalInput = React6.forwardRef(
|
|
|
530
530
|
);
|
|
531
531
|
TerminalInput.displayName = "TerminalInput";
|
|
532
532
|
|
|
533
|
+
// src/primitives/drop-zone.tsx
|
|
534
|
+
import { useCallback as useCallback2, useRef as useRef2, useState as useState3 } from "react";
|
|
535
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
536
|
+
function DropZone({
|
|
537
|
+
onDrop,
|
|
538
|
+
accept,
|
|
539
|
+
disabled,
|
|
540
|
+
overlay,
|
|
541
|
+
title = "Drop files to upload",
|
|
542
|
+
description = "Your files will be securely stored in the workspace.",
|
|
543
|
+
icon = "cloud_upload",
|
|
544
|
+
children,
|
|
545
|
+
className
|
|
546
|
+
}) {
|
|
547
|
+
const [dragOver, setDragOver] = useState3(false);
|
|
548
|
+
const counter = useRef2(0);
|
|
549
|
+
const isAccepted = useCallback2(
|
|
550
|
+
(file) => {
|
|
551
|
+
if (!accept) return true;
|
|
552
|
+
const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
|
|
553
|
+
const fileName = file.name.toLowerCase();
|
|
554
|
+
return extensions.some((ext) => fileName.endsWith(ext));
|
|
555
|
+
},
|
|
556
|
+
[accept]
|
|
557
|
+
);
|
|
558
|
+
const handleDragEnter = useCallback2(
|
|
559
|
+
(e) => {
|
|
560
|
+
e.preventDefault();
|
|
561
|
+
if (disabled) return;
|
|
562
|
+
counter.current++;
|
|
563
|
+
if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
|
|
564
|
+
},
|
|
565
|
+
[disabled]
|
|
566
|
+
);
|
|
567
|
+
const handleDragLeave = useCallback2((e) => {
|
|
568
|
+
e.preventDefault();
|
|
569
|
+
counter.current--;
|
|
570
|
+
if (counter.current === 0) setDragOver(false);
|
|
571
|
+
}, []);
|
|
572
|
+
const handleDragOver = useCallback2(
|
|
573
|
+
(e) => {
|
|
574
|
+
e.preventDefault();
|
|
575
|
+
if (!disabled) e.dataTransfer.dropEffect = "copy";
|
|
576
|
+
},
|
|
577
|
+
[disabled]
|
|
578
|
+
);
|
|
579
|
+
const handleDrop = useCallback2(
|
|
580
|
+
(e) => {
|
|
581
|
+
e.preventDefault();
|
|
582
|
+
counter.current = 0;
|
|
583
|
+
setDragOver(false);
|
|
584
|
+
if (disabled) return;
|
|
585
|
+
const allFiles = Array.from(e.dataTransfer?.files || []);
|
|
586
|
+
const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
|
|
587
|
+
if (accepted.length > 0) onDrop(accepted);
|
|
588
|
+
},
|
|
589
|
+
[disabled, accept, isAccepted, onDrop]
|
|
590
|
+
);
|
|
591
|
+
return /* @__PURE__ */ jsxs5(
|
|
592
|
+
"div",
|
|
593
|
+
{
|
|
594
|
+
onDragEnter: handleDragEnter,
|
|
595
|
+
onDragLeave: handleDragLeave,
|
|
596
|
+
onDragOver: handleDragOver,
|
|
597
|
+
onDrop: handleDrop,
|
|
598
|
+
className: cn("relative", className),
|
|
599
|
+
children: [
|
|
600
|
+
dragOver && (overlay || /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-black/20 backdrop-blur-sm", children: /* @__PURE__ */ jsxs5("div", { className: "rounded-3xl border-2 border-dashed border-[hsl(var(--ring))] bg-[hsl(var(--card))] p-16 text-center shadow-2xl max-w-lg mx-auto", children: [
|
|
601
|
+
/* @__PURE__ */ jsx7("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl bg-[hsl(var(--primary))]/10", children: typeof icon === "string" ? /* @__PURE__ */ jsx7("span", { className: "material-symbols-outlined text-5xl text-[hsl(var(--primary))]", children: icon }) : icon }),
|
|
602
|
+
/* @__PURE__ */ jsx7("h2", { className: "text-2xl font-extrabold text-[hsl(var(--foreground))]", children: title }),
|
|
603
|
+
/* @__PURE__ */ jsx7("p", { className: "mt-2 text-[hsl(var(--muted-foreground))]", children: description })
|
|
604
|
+
] }) })),
|
|
605
|
+
children
|
|
606
|
+
]
|
|
607
|
+
}
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// src/primitives/upload-progress.tsx
|
|
612
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
613
|
+
function formatSize(bytes) {
|
|
614
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
615
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}KB`;
|
|
616
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
617
|
+
}
|
|
618
|
+
function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
619
|
+
if (files.length === 0) return null;
|
|
620
|
+
return /* @__PURE__ */ jsx8("div", { className: cn("space-y-2", className), children: files.map((file) => /* @__PURE__ */ jsxs6(
|
|
621
|
+
"div",
|
|
622
|
+
{
|
|
623
|
+
className: cn(
|
|
624
|
+
"flex items-center gap-3 rounded-lg border px-3 py-2 text-sm",
|
|
625
|
+
file.status === "error" ? "border-[hsl(var(--destructive))]/20 bg-[hsl(var(--destructive))]/5" : file.status === "complete" ? "border-[hsl(var(--success))]/20 bg-[hsl(var(--success))]/5" : "border-[hsl(var(--border))] bg-[hsl(var(--card))]"
|
|
626
|
+
),
|
|
627
|
+
children: [
|
|
628
|
+
/* @__PURE__ */ jsx8(
|
|
629
|
+
"span",
|
|
630
|
+
{
|
|
631
|
+
className: cn(
|
|
632
|
+
"material-symbols-outlined text-base shrink-0",
|
|
633
|
+
file.status === "complete" && "text-[hsl(var(--success))]",
|
|
634
|
+
file.status === "error" && "text-[hsl(var(--destructive))]",
|
|
635
|
+
file.status === "uploading" && "text-[hsl(var(--primary))] animate-pulse",
|
|
636
|
+
file.status === "pending" && "text-[hsl(var(--muted-foreground))]"
|
|
637
|
+
),
|
|
638
|
+
style: file.status === "complete" ? { fontVariationSettings: "'FILL' 1" } : void 0,
|
|
639
|
+
children: file.status === "complete" ? "check_circle" : file.status === "error" ? "error" : file.status === "uploading" ? "progress_activity" : "description"
|
|
640
|
+
}
|
|
641
|
+
),
|
|
642
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex-1 min-w-0", children: [
|
|
643
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
644
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate font-medium text-[hsl(var(--foreground))]", children: file.name }),
|
|
645
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatSize(file.size) })
|
|
646
|
+
] }),
|
|
647
|
+
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1 h-1 w-full rounded-full bg-[hsl(var(--muted))] overflow-hidden", children: /* @__PURE__ */ jsx8(
|
|
648
|
+
"div",
|
|
649
|
+
{
|
|
650
|
+
className: "h-full rounded-full bg-[hsl(var(--primary))] transition-all",
|
|
651
|
+
style: { width: `${file.progress}%` }
|
|
652
|
+
}
|
|
653
|
+
) }),
|
|
654
|
+
file.status === "error" && file.error && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-[hsl(var(--destructive))]", children: file.error })
|
|
655
|
+
] }),
|
|
656
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
657
|
+
file.status === "error" && onRetry && /* @__PURE__ */ jsx8(
|
|
658
|
+
"button",
|
|
659
|
+
{
|
|
660
|
+
type: "button",
|
|
661
|
+
onClick: () => onRetry(file.id),
|
|
662
|
+
className: "rounded p-1 text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] transition-colors",
|
|
663
|
+
children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-sm", children: "refresh" })
|
|
664
|
+
}
|
|
665
|
+
),
|
|
666
|
+
onRemove && /* @__PURE__ */ jsx8(
|
|
667
|
+
"button",
|
|
668
|
+
{
|
|
669
|
+
type: "button",
|
|
670
|
+
onClick: () => onRemove(file.id),
|
|
671
|
+
className: "rounded p-1 text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] transition-colors",
|
|
672
|
+
children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-sm", children: "close" })
|
|
673
|
+
}
|
|
674
|
+
)
|
|
675
|
+
] })
|
|
676
|
+
]
|
|
677
|
+
},
|
|
678
|
+
file.id
|
|
679
|
+
)) });
|
|
680
|
+
}
|
|
681
|
+
|
|
533
682
|
export {
|
|
534
683
|
Select,
|
|
535
684
|
SelectGroup,
|
|
@@ -550,5 +699,7 @@ export {
|
|
|
550
699
|
TerminalDisplay,
|
|
551
700
|
TerminalLine,
|
|
552
701
|
TerminalCursor,
|
|
553
|
-
TerminalInput
|
|
702
|
+
TerminalInput,
|
|
703
|
+
DropZone,
|
|
704
|
+
UploadProgress
|
|
554
705
|
};
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
getToolDisplayMetadata
|
|
16
16
|
} from "./chunk-BX6AQMUS.js";
|
|
17
|
+
import {
|
|
18
|
+
OpenUIArtifactRenderer
|
|
19
|
+
} from "./chunk-YDBXQQLC.js";
|
|
17
20
|
import {
|
|
18
21
|
Markdown
|
|
19
22
|
} from "./chunk-LTFK464G.js";
|
|
@@ -516,6 +519,52 @@ import {
|
|
|
516
519
|
} from "react";
|
|
517
520
|
import { ArrowDown } from "lucide-react";
|
|
518
521
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
522
|
+
var OPENUI_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
523
|
+
"heading",
|
|
524
|
+
"text",
|
|
525
|
+
"badge",
|
|
526
|
+
"stat",
|
|
527
|
+
"key_value",
|
|
528
|
+
"code",
|
|
529
|
+
"markdown",
|
|
530
|
+
"table",
|
|
531
|
+
"actions",
|
|
532
|
+
"separator",
|
|
533
|
+
"stack",
|
|
534
|
+
"grid",
|
|
535
|
+
"card"
|
|
536
|
+
]);
|
|
537
|
+
function isOpenUINode(value) {
|
|
538
|
+
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && OPENUI_NODE_TYPES.has(value.type);
|
|
539
|
+
}
|
|
540
|
+
function extractOpenUISchema(output) {
|
|
541
|
+
if (output == null) return null;
|
|
542
|
+
if (isOpenUINode(output)) return [output];
|
|
543
|
+
if (Array.isArray(output) && output.length > 0 && output.every(isOpenUINode)) {
|
|
544
|
+
return output;
|
|
545
|
+
}
|
|
546
|
+
if (typeof output === "object" && !Array.isArray(output)) {
|
|
547
|
+
const obj = output;
|
|
548
|
+
for (const key of ["openui", "schema", "ui"]) {
|
|
549
|
+
if (obj[key]) {
|
|
550
|
+
const inner = obj[key];
|
|
551
|
+
if (isOpenUINode(inner)) return [inner];
|
|
552
|
+
if (Array.isArray(inner) && inner.length > 0 && inner.every(isOpenUINode)) {
|
|
553
|
+
return inner;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (typeof output === "string") {
|
|
559
|
+
try {
|
|
560
|
+
const parsed = JSON.parse(output);
|
|
561
|
+
return extractOpenUISchema(parsed);
|
|
562
|
+
} catch {
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
519
568
|
function formatUnknown(value) {
|
|
520
569
|
if (value == null) return void 0;
|
|
521
570
|
if (typeof value === "string") return value;
|
|
@@ -563,7 +612,7 @@ function mapToolPartToTimelineType(part) {
|
|
|
563
612
|
return "unknown";
|
|
564
613
|
}
|
|
565
614
|
}
|
|
566
|
-
function buildTimelineItems(messages, partMap, isStreaming) {
|
|
615
|
+
function buildTimelineItems(messages, partMap, isStreaming, onOpenUIAction, enableOpenUI = true) {
|
|
567
616
|
const items = [];
|
|
568
617
|
const lastAssistantMessage = [...messages].reverse().find((message) => message.role === "assistant");
|
|
569
618
|
const toToolCall = (part) => {
|
|
@@ -611,6 +660,18 @@ function buildTimelineItems(messages, partMap, isStreaming) {
|
|
|
611
660
|
calls: toolBuffer.map((part) => toToolCall(part))
|
|
612
661
|
});
|
|
613
662
|
}
|
|
663
|
+
if (enableOpenUI) {
|
|
664
|
+
for (const part of toolBuffer) {
|
|
665
|
+
if (part.state.status !== "completed" || !part.state.output) continue;
|
|
666
|
+
const schema = extractOpenUISchema(part.state.output);
|
|
667
|
+
if (!schema) continue;
|
|
668
|
+
items.push({
|
|
669
|
+
id: `${message.id}-openui-${part.id}`,
|
|
670
|
+
kind: "custom",
|
|
671
|
+
content: /* @__PURE__ */ jsx7("div", { className: "my-2 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--bg-card)] p-4 shadow-[var(--shadow-card)]", children: /* @__PURE__ */ jsx7(OpenUIArtifactRenderer, { schema, onAction: onOpenUIAction }) })
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}
|
|
614
675
|
toolBuffer.length = 0;
|
|
615
676
|
};
|
|
616
677
|
parts.forEach((part, index) => {
|
|
@@ -621,6 +682,40 @@ function buildTimelineItems(messages, partMap, isStreaming) {
|
|
|
621
682
|
}
|
|
622
683
|
flushToolBuffer(index);
|
|
623
684
|
if (part.type === "text" && !part.synthetic && part.text.trim()) {
|
|
685
|
+
if (enableOpenUI) {
|
|
686
|
+
const jsonMatch = part.text.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
|
|
687
|
+
if (jsonMatch) {
|
|
688
|
+
const schema = extractOpenUISchema(jsonMatch[1]);
|
|
689
|
+
if (schema) {
|
|
690
|
+
const beforeJson = part.text.slice(0, part.text.indexOf("```")).trim();
|
|
691
|
+
if (beforeJson) {
|
|
692
|
+
items.push({
|
|
693
|
+
id: `${itemId}-text`,
|
|
694
|
+
kind: "message",
|
|
695
|
+
role: "assistant",
|
|
696
|
+
content: beforeJson,
|
|
697
|
+
timestamp: createdAtFromMessage(message)
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
items.push({
|
|
701
|
+
id: `${itemId}-openui`,
|
|
702
|
+
kind: "custom",
|
|
703
|
+
content: /* @__PURE__ */ jsx7("div", { className: "my-2 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--bg-card)] p-4 shadow-[var(--shadow-card)]", children: /* @__PURE__ */ jsx7(OpenUIArtifactRenderer, { schema, onAction: onOpenUIAction }) })
|
|
704
|
+
});
|
|
705
|
+
const afterJson = part.text.slice(part.text.lastIndexOf("```") + 3).trim();
|
|
706
|
+
if (afterJson) {
|
|
707
|
+
items.push({
|
|
708
|
+
id: `${itemId}-after`,
|
|
709
|
+
kind: "message",
|
|
710
|
+
role: "assistant",
|
|
711
|
+
content: afterJson,
|
|
712
|
+
timestamp: createdAtFromMessage(message)
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
624
719
|
items.push({
|
|
625
720
|
id: itemId,
|
|
626
721
|
kind: "message",
|
|
@@ -665,7 +760,9 @@ var ChatContainer = memo3(
|
|
|
665
760
|
pendingFiles,
|
|
666
761
|
onRemoveFile,
|
|
667
762
|
onAttach,
|
|
668
|
-
disabled = false
|
|
763
|
+
disabled = false,
|
|
764
|
+
onOpenUIAction,
|
|
765
|
+
enableOpenUI = true
|
|
669
766
|
}) => {
|
|
670
767
|
const scrollRef = useRef2(null);
|
|
671
768
|
const groups = useRunGroups({ messages, partMap, isStreaming });
|
|
@@ -677,8 +774,8 @@ var ChatContainer = memo3(
|
|
|
677
774
|
isStreaming
|
|
678
775
|
]);
|
|
679
776
|
const timeline = useMemo(
|
|
680
|
-
() => buildTimelineItems(messages, partMap, isStreaming),
|
|
681
|
-
[messages, partMap, isStreaming]
|
|
777
|
+
() => buildTimelineItems(messages, partMap, isStreaming, onOpenUIAction, enableOpenUI),
|
|
778
|
+
[messages, partMap, isStreaming, onOpenUIAction, enableOpenUI]
|
|
682
779
|
);
|
|
683
780
|
const handleSend = useCallback2(
|
|
684
781
|
(text) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { B as Button, a as ButtonProps, b as buttonVariants } from './button-CMQuQEW_.js';
|
|
2
|
-
export { Avatar, AvatarFallback, AvatarImage, Badge, BadgeProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EmptyStateProps, Input, InputProps, Label, Logo, LogoProps, Progress, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Skeleton, SkeletonCard, SkeletonTable, StatCard, StatCardProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TangleKnot, TerminalDisplay, TerminalCursor as TerminalDisplayCursor, TerminalInput as TerminalDisplayInput, TerminalLine as TerminalDisplayLine, Textarea, TextareaProps, Toast, ToastContainer, ToastProvider, badgeVariants, useToast } from './primitives.js';
|
|
2
|
+
export { Avatar, AvatarFallback, AvatarImage, Badge, BadgeProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EmptyStateProps, Input, InputProps, Label, Logo, LogoProps, Progress, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Skeleton, SkeletonCard, SkeletonTable, StatCard, StatCardProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TangleKnot, TerminalDisplay, TerminalCursor as TerminalDisplayCursor, TerminalInput as TerminalDisplayInput, TerminalLine as TerminalDisplayLine, Textarea, TextareaProps, Toast, ToastContainer, ToastProvider, UploadFile, UploadProgress, UploadProgressProps, badgeVariants, useToast } from './primitives.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default from 'react';
|
|
@@ -7,7 +7,7 @@ export { AgentWorkbench, AuditCheck, AuditResults, AuditResultsProps, BannerType
|
|
|
7
7
|
export { A as ArtifactPane, a as ArtifactPaneProps, F as FileNode, b as FileTabData, c as FileTabs, d as FileTabsProps, e as FileTree, f as FileTreeProps, g as FileTreeVisibilityOptions, h as filterFileTree } from './file-tabs-CmaoDVBI.js';
|
|
8
8
|
export { OpenUIAction, OpenUIActionsNode, OpenUIArtifactRenderer, OpenUIArtifactRendererProps, OpenUIBadgeNode, OpenUICardNode, OpenUICodeNode, OpenUIComponentNode, OpenUIGridNode, OpenUIHeadingNode, OpenUIKeyValueNode, OpenUIMarkdownNode, OpenUIPrimitive, OpenUISeparatorNode, OpenUIStackNode, OpenUIStatNode, OpenUITableNode, OpenUITextNode } from './openui.js';
|
|
9
9
|
export { AgentTimeline, AgentTimelineArtifactItem, AgentTimelineCustomItem, AgentTimelineItem, AgentTimelineMessageItem, AgentTimelineProps, AgentTimelineStatusItem, AgentTimelineTone, AgentTimelineToolGroupItem, AgentTimelineToolItem, ChatMessage, ChatMessageProps, MessageList, MessageRole, ThinkingIndicator, ThinkingIndicatorProps, UserMessage } from './chat.js';
|
|
10
|
-
export { C as ChatContainer, a as ChatInput, b as ChatInputProps, P as PendingFile } from './chat-container-
|
|
10
|
+
export { C as ChatContainer, a as ChatInput, b as ChatInputProps, P as PendingFile } from './chat-container-B34uj-J1.js';
|
|
11
11
|
export { F as FeedSegment, T as ToolCallData, a as ToolCallFeed, b as ToolCallFeedProps, c as ToolCallGroup, d as ToolCallGroupProps, e as ToolCallStatus, f as ToolCallStep, g as ToolCallStepProps, h as ToolCallType, p as parseToolEvent } from './tool-call-feed-D5Ume-Pt.js';
|
|
12
12
|
export { E as ExpandedToolDetail, I as InlineThinkingItem, c as InlineToolItem, R as RunGroup } from './expanded-tool-detail-BDi_h_dZ.js';
|
|
13
13
|
import { b as ToolPart } from './parts-CyGkM6Fp.js';
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
useToolCallStream
|
|
26
26
|
} from "./chunk-5LV6DZZF.js";
|
|
27
27
|
import {
|
|
28
|
+
DropZone,
|
|
28
29
|
Label,
|
|
29
30
|
Select,
|
|
30
31
|
SelectContent,
|
|
@@ -44,8 +45,9 @@ import {
|
|
|
44
45
|
TerminalLine,
|
|
45
46
|
ToastContainer,
|
|
46
47
|
ToastProvider,
|
|
48
|
+
UploadProgress,
|
|
47
49
|
useToast
|
|
48
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-CSIXZEKN.js";
|
|
49
51
|
import {
|
|
50
52
|
Avatar,
|
|
51
53
|
AvatarFallback,
|
|
@@ -81,7 +83,7 @@ import {
|
|
|
81
83
|
StatusBar,
|
|
82
84
|
TerminalPanel,
|
|
83
85
|
WorkspaceLayout
|
|
84
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-ZSNOGOUX.js";
|
|
85
87
|
import {
|
|
86
88
|
EmptyState,
|
|
87
89
|
Input,
|
|
@@ -95,7 +97,7 @@ import {
|
|
|
95
97
|
MessageList,
|
|
96
98
|
ThinkingIndicator,
|
|
97
99
|
UserMessage
|
|
98
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-PXRPYAMM.js";
|
|
99
101
|
import {
|
|
100
102
|
useAutoScroll,
|
|
101
103
|
useRunCollapseState,
|
|
@@ -348,6 +350,7 @@ export {
|
|
|
348
350
|
DialogTrigger,
|
|
349
351
|
DiffPreview,
|
|
350
352
|
DirectoryPane,
|
|
353
|
+
DropZone,
|
|
351
354
|
DropdownMenu,
|
|
352
355
|
DropdownMenuCheckboxItem,
|
|
353
356
|
DropdownMenuContent,
|
|
@@ -440,6 +443,7 @@ export {
|
|
|
440
443
|
ToolCallFeed,
|
|
441
444
|
ToolCallGroup,
|
|
442
445
|
ToolCallStep,
|
|
446
|
+
UploadProgress,
|
|
443
447
|
UsageChart,
|
|
444
448
|
UserMenu,
|
|
445
449
|
UserMessage,
|
package/dist/primitives.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { B as Button, a as ButtonProps, b as buttonVariants } from './button-CMQuQEW_.js';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
3
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
5
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
@@ -230,4 +231,47 @@ interface TerminalInputProps extends Omit<React$1.InputHTMLAttributes<HTMLInputE
|
|
|
230
231
|
}
|
|
231
232
|
declare const TerminalInput: React$1.ForwardRefExoticComponent<TerminalInputProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
232
233
|
|
|
233
|
-
|
|
234
|
+
interface DropZoneProps {
|
|
235
|
+
/** Called with dropped files */
|
|
236
|
+
onDrop: (files: File[]) => void;
|
|
237
|
+
/** Accepted file types (e.g. ".pdf,.csv,.xlsx") */
|
|
238
|
+
accept?: string;
|
|
239
|
+
/** Whether drop zone is active */
|
|
240
|
+
disabled?: boolean;
|
|
241
|
+
/** Custom overlay content (replaces default) */
|
|
242
|
+
overlay?: ReactNode;
|
|
243
|
+
/** Overlay title */
|
|
244
|
+
title?: string;
|
|
245
|
+
/** Overlay description */
|
|
246
|
+
description?: string;
|
|
247
|
+
/** Overlay icon (Material Symbols name or ReactNode) */
|
|
248
|
+
icon?: string | ReactNode;
|
|
249
|
+
/** Children wrapped by the drop zone */
|
|
250
|
+
children: ReactNode;
|
|
251
|
+
className?: string;
|
|
252
|
+
}
|
|
253
|
+
declare function DropZone({ onDrop, accept, disabled, overlay, title, description, icon, children, className, }: DropZoneProps): react_jsx_runtime.JSX.Element;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* UploadProgress — file upload status indicators.
|
|
257
|
+
*
|
|
258
|
+
* Shows a list of files being uploaded with progress bars,
|
|
259
|
+
* completion checkmarks, and error states.
|
|
260
|
+
*/
|
|
261
|
+
interface UploadFile {
|
|
262
|
+
id: string;
|
|
263
|
+
name: string;
|
|
264
|
+
size: number;
|
|
265
|
+
status: "pending" | "uploading" | "complete" | "error";
|
|
266
|
+
progress?: number;
|
|
267
|
+
error?: string;
|
|
268
|
+
}
|
|
269
|
+
interface UploadProgressProps {
|
|
270
|
+
files: UploadFile[];
|
|
271
|
+
onRemove?: (id: string) => void;
|
|
272
|
+
onRetry?: (id: string) => void;
|
|
273
|
+
className?: string;
|
|
274
|
+
}
|
|
275
|
+
declare function UploadProgress({ files, onRemove, onRetry, className }: UploadProgressProps): react_jsx_runtime.JSX.Element | null;
|
|
276
|
+
|
|
277
|
+
export { Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, Input, type InputProps, Label, Logo, type LogoProps, Progress, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Skeleton, SkeletonCard, SkeletonTable, StatCard, type StatCardProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, Textarea, type TextareaProps, type Toast, ToastContainer, ToastProvider, type UploadFile, UploadProgress, type UploadProgressProps, badgeVariants, useToast };
|
package/dist/primitives.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DropZone,
|
|
2
3
|
Label,
|
|
3
4
|
Select,
|
|
4
5
|
SelectContent,
|
|
@@ -18,8 +19,9 @@ import {
|
|
|
18
19
|
TerminalLine,
|
|
19
20
|
ToastContainer,
|
|
20
21
|
ToastProvider,
|
|
22
|
+
UploadProgress,
|
|
21
23
|
useToast
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-CSIXZEKN.js";
|
|
23
25
|
import {
|
|
24
26
|
Avatar,
|
|
25
27
|
AvatarFallback,
|
|
@@ -120,6 +122,7 @@ export {
|
|
|
120
122
|
DialogPortal,
|
|
121
123
|
DialogTitle,
|
|
122
124
|
DialogTrigger,
|
|
125
|
+
DropZone,
|
|
123
126
|
DropdownMenu,
|
|
124
127
|
DropdownMenuCheckboxItem,
|
|
125
128
|
DropdownMenuContent,
|
|
@@ -175,6 +178,7 @@ export {
|
|
|
175
178
|
Textarea,
|
|
176
179
|
ToastContainer,
|
|
177
180
|
ToastProvider,
|
|
181
|
+
UploadProgress,
|
|
178
182
|
badgeVariants,
|
|
179
183
|
buttonVariants,
|
|
180
184
|
useToast
|
package/dist/workspace.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { F as FileNode, g as FileTreeVisibilityOptions, b as FileTabData } from './file-tabs-CmaoDVBI.js';
|
|
4
4
|
export { A as ArtifactPane, a as ArtifactPaneProps } from './file-tabs-CmaoDVBI.js';
|
|
5
|
-
import { c as ChatContainerProps } from './chat-container-
|
|
5
|
+
import { c as ChatContainerProps } from './chat-container-B34uj-J1.js';
|
|
6
6
|
import { OpenUIComponentNode, OpenUIAction } from './openui.js';
|
|
7
7
|
import './parts-CyGkM6Fp.js';
|
|
8
8
|
import './branding-DCi5VEik.js';
|
package/dist/workspace.js
CHANGED
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
StatusBar,
|
|
9
9
|
TerminalPanel,
|
|
10
10
|
WorkspaceLayout
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZSNOGOUX.js";
|
|
12
12
|
import "./chunk-MUOL44AE.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-PXRPYAMM.js";
|
|
14
14
|
import "./chunk-CNWVHQFY.js";
|
|
15
15
|
import "./chunk-WUR652Y3.js";
|
|
16
16
|
import "./chunk-HRMUF35V.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|