@tangle-network/sandbox-ui 0.18.0 → 0.20.1
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.d.ts +8 -1
- package/dist/chat.js +1 -1
- package/dist/{chunk-GPT7VKK6.js → chunk-CP2L6B53.js} +21 -4
- package/dist/{chunk-CNVE6KOM.js → chunk-MQ52AYJX.js} +38 -10
- package/dist/{chunk-5I363RL7.js → chunk-R6QNJQRH.js} +636 -571
- package/dist/dashboard.d.ts +49 -1
- package/dist/dashboard.js +7 -1
- package/dist/globals.css +1248 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -3
- package/dist/styles.css +1248 -0
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.js +1 -1
- package/package.json +1 -1
package/dist/chat.d.ts
CHANGED
|
@@ -57,6 +57,13 @@ interface ArtifactAgentDockTransport {
|
|
|
57
57
|
content: string;
|
|
58
58
|
signal: AbortSignal;
|
|
59
59
|
}): AsyncIterable<ArtifactDockStreamEvent>;
|
|
60
|
+
/** Stop the server-side run for a thread. Optional — when present, the dock
|
|
61
|
+
* calls it on cancel/scope-switch BEFORE aborting the local fetch, so the
|
|
62
|
+
* agent run is actually stopped (not orphaned, still billing) rather than
|
|
63
|
+
* the client merely closing its reader. */
|
|
64
|
+
cancel?(args: {
|
|
65
|
+
threadId: string;
|
|
66
|
+
}): Promise<void> | void;
|
|
60
67
|
}
|
|
61
68
|
interface ArtifactAgentDockProps {
|
|
62
69
|
scope: ArtifactScope;
|
|
@@ -95,7 +102,7 @@ declare function ArtifactAgentDock({ scope, open, onOpenChange, transport, defau
|
|
|
95
102
|
* their own transport object.
|
|
96
103
|
*
|
|
97
104
|
* The expected NDJSON event shape:
|
|
98
|
-
* { type: "message.part.
|
|
105
|
+
* { type: "message.part.updated", data: { delta: string, part?: {type} } } // assistant chunk
|
|
99
106
|
* { type: "error", data: { message: string, ... } } // surface error
|
|
100
107
|
*
|
|
101
108
|
* Other event types are ignored — consumers that need tool-call rendering
|
package/dist/chat.js
CHANGED
|
@@ -1652,8 +1652,11 @@ function CheckRow({ check }) {
|
|
|
1652
1652
|
}
|
|
1653
1653
|
|
|
1654
1654
|
// src/workspace/task-board.tsx
|
|
1655
|
-
import {
|
|
1655
|
+
import {
|
|
1656
|
+
useMemo as useMemo5
|
|
1657
|
+
} from "react";
|
|
1656
1658
|
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1659
|
+
var INTERACTIVE_SELECTOR = 'button, a, input, textarea, select, [role="button"], [role="link"]';
|
|
1657
1660
|
function TaskBoard({
|
|
1658
1661
|
items,
|
|
1659
1662
|
columns,
|
|
@@ -1686,10 +1689,24 @@ function TaskBoard({
|
|
|
1686
1689
|
colItems.length === 0 && columnEmptyState,
|
|
1687
1690
|
colItems.map((item, index) => {
|
|
1688
1691
|
const card = /* @__PURE__ */ jsxs11(
|
|
1689
|
-
"
|
|
1692
|
+
"div",
|
|
1690
1693
|
{
|
|
1691
|
-
|
|
1692
|
-
|
|
1694
|
+
role: onClickItem ? "button" : void 0,
|
|
1695
|
+
tabIndex: onClickItem ? 0 : void 0,
|
|
1696
|
+
onClick: (event) => {
|
|
1697
|
+
if (!onClickItem) return;
|
|
1698
|
+
const target = event.target;
|
|
1699
|
+
const interactive = target.closest(INTERACTIVE_SELECTOR);
|
|
1700
|
+
if (interactive && interactive !== event.currentTarget) return;
|
|
1701
|
+
onClickItem(item);
|
|
1702
|
+
},
|
|
1703
|
+
onKeyDown: (event) => {
|
|
1704
|
+
if (!onClickItem || event.currentTarget !== event.target) return;
|
|
1705
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1706
|
+
if (event.repeat) return;
|
|
1707
|
+
event.preventDefault();
|
|
1708
|
+
onClickItem(item);
|
|
1709
|
+
},
|
|
1693
1710
|
className: "group w-full rounded-lg border border-border bg-card p-3 text-left transition-colors hover:border-accent/50",
|
|
1694
1711
|
children: [
|
|
1695
1712
|
/* @__PURE__ */ jsx11("p", { className: "text-sm font-medium text-foreground", children: item.title }),
|
|
@@ -121,6 +121,18 @@ function defaultScopeLabel(scope) {
|
|
|
121
121
|
function normalizeRole(role) {
|
|
122
122
|
return role === "assistant" || role === "system" ? role : "user";
|
|
123
123
|
}
|
|
124
|
+
function createDockMessageId() {
|
|
125
|
+
const c = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
|
|
126
|
+
if (c && typeof c.randomUUID === "function") return c.randomUUID();
|
|
127
|
+
if (c && typeof c.getRandomValues === "function") {
|
|
128
|
+
const b = c.getRandomValues(new Uint8Array(16));
|
|
129
|
+
b[6] = b[6] & 15 | 64;
|
|
130
|
+
b[8] = b[8] & 63 | 128;
|
|
131
|
+
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
132
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
133
|
+
}
|
|
134
|
+
throw new Error("crypto.getRandomValues is required for message ids");
|
|
135
|
+
}
|
|
124
136
|
function ArtifactAgentDock({
|
|
125
137
|
scope,
|
|
126
138
|
open,
|
|
@@ -138,6 +150,7 @@ function ArtifactAgentDock({
|
|
|
138
150
|
const [loading, setLoading] = React.useState(false);
|
|
139
151
|
const abortRef = React.useRef(null);
|
|
140
152
|
const scrollRef = React.useRef(null);
|
|
153
|
+
const scopeTokenRef = React.useRef(0);
|
|
141
154
|
const reportError = React.useCallback(
|
|
142
155
|
(message) => {
|
|
143
156
|
if (onError) onError(message);
|
|
@@ -147,6 +160,9 @@ function ArtifactAgentDock({
|
|
|
147
160
|
);
|
|
148
161
|
React.useEffect(() => {
|
|
149
162
|
if (!open) return;
|
|
163
|
+
scopeTokenRef.current += 1;
|
|
164
|
+
abortRef.current?.abort();
|
|
165
|
+
abortRef.current = null;
|
|
150
166
|
let cancelled = false;
|
|
151
167
|
async function bootstrap() {
|
|
152
168
|
setLoading(true);
|
|
@@ -185,8 +201,9 @@ function ArtifactAgentDock({
|
|
|
185
201
|
const send = React.useCallback(async () => {
|
|
186
202
|
const text = composer.trim();
|
|
187
203
|
if (!text || !threadId || sending) return;
|
|
204
|
+
const token = scopeTokenRef.current;
|
|
188
205
|
const userMsg = {
|
|
189
|
-
id:
|
|
206
|
+
id: createDockMessageId(),
|
|
190
207
|
role: "user",
|
|
191
208
|
content: text,
|
|
192
209
|
createdAt: /* @__PURE__ */ new Date()
|
|
@@ -201,6 +218,7 @@ function ArtifactAgentDock({
|
|
|
201
218
|
let streamFailed = false;
|
|
202
219
|
try {
|
|
203
220
|
for await (const event of transport.sendStream({ threadId, content: text, signal: controller.signal })) {
|
|
221
|
+
if (scopeTokenRef.current !== token) return;
|
|
204
222
|
if (event.type === "delta") {
|
|
205
223
|
assistantContent += event.text;
|
|
206
224
|
setStreamContent(assistantContent);
|
|
@@ -209,11 +227,12 @@ function ArtifactAgentDock({
|
|
|
209
227
|
reportError(event.message);
|
|
210
228
|
}
|
|
211
229
|
}
|
|
230
|
+
if (scopeTokenRef.current !== token) return;
|
|
212
231
|
if (assistantContent && !streamFailed) {
|
|
213
232
|
setMessages((prev) => [
|
|
214
233
|
...prev,
|
|
215
234
|
{
|
|
216
|
-
id:
|
|
235
|
+
id: createDockMessageId(),
|
|
217
236
|
role: "assistant",
|
|
218
237
|
content: assistantContent,
|
|
219
238
|
createdAt: /* @__PURE__ */ new Date()
|
|
@@ -223,17 +242,24 @@ function ArtifactAgentDock({
|
|
|
223
242
|
setStreamContent("");
|
|
224
243
|
} catch (err) {
|
|
225
244
|
if (err?.name === "AbortError") return;
|
|
226
|
-
reportError(err instanceof Error ? err.message : "Send failed");
|
|
245
|
+
if (scopeTokenRef.current === token) reportError(err instanceof Error ? err.message : "Send failed");
|
|
227
246
|
} finally {
|
|
228
|
-
setSending(false);
|
|
229
|
-
abortRef.current = null;
|
|
247
|
+
if (scopeTokenRef.current === token) setSending(false);
|
|
248
|
+
if (abortRef.current === controller) abortRef.current = null;
|
|
230
249
|
}
|
|
231
250
|
}, [composer, threadId, sending, transport, reportError]);
|
|
232
251
|
const cancel = React.useCallback(() => {
|
|
252
|
+
if (threadId && transport.cancel) {
|
|
253
|
+
try {
|
|
254
|
+
void Promise.resolve(transport.cancel({ threadId })).catch(() => {
|
|
255
|
+
});
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
}
|
|
233
259
|
abortRef.current?.abort();
|
|
234
260
|
setSending(false);
|
|
235
261
|
setStreamContent("");
|
|
236
|
-
}, []);
|
|
262
|
+
}, [threadId, transport]);
|
|
237
263
|
if (!open) return null;
|
|
238
264
|
const heading = defaultScopeLabel(scope);
|
|
239
265
|
return /* @__PURE__ */ jsxs2(
|
|
@@ -384,10 +410,12 @@ function createFetchTransport(opts) {
|
|
|
384
410
|
if (!line.trim()) continue;
|
|
385
411
|
try {
|
|
386
412
|
const event = JSON.parse(line);
|
|
387
|
-
if (event.type === "message.part.
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
413
|
+
if (event.type === "message.part.updated" && event.data) {
|
|
414
|
+
const delta = event.data.delta;
|
|
415
|
+
const part = event.data.part;
|
|
416
|
+
const isText = !part || typeof part !== "object" || part.type === void 0 || part.type === "text";
|
|
417
|
+
if (isText && typeof delta === "string" && delta.length > 0) {
|
|
418
|
+
yield { type: "delta", text: delta };
|
|
391
419
|
}
|
|
392
420
|
} else if (event.type === "error" && event.data) {
|
|
393
421
|
const message = typeof event.data.message === "string" ? event.data.message : "Stream error";
|