dishui 0.0.89 → 0.0.97
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/.release-verified.json +6 -0
- package/dist/ai.js +22 -0
- package/dist/components/Card/Metric2.js +11 -11
- package/dist/components/Card/Metric2.js.map +1 -1
- package/dist/components/Card/index.d.ts +20 -0
- package/dist/components/Card/index.js +184 -179
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/GroupButton/index.js +4 -4
- package/dist/components/GroupButton/index.js.map +1 -1
- package/dist/components/GroupedTable/index.js +10 -10
- package/dist/components/GroupedTable/index.js.map +1 -1
- package/dist/components/NavigationList/index.js +9 -9
- package/dist/components/NavigationList/index.js.map +1 -1
- package/dist/components/Section/index.js +11 -11
- package/dist/components/Section/index.js.map +1 -1
- package/dist/components/Skeleton/index.js +1 -1
- package/dist/components/Skeleton/index.js.map +1 -1
- package/dist/components/Table/index.d.ts +23 -2
- package/dist/components/Table/index.js +153 -101
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/ai/AgentChat/index.d.ts +54 -0
- package/dist/components/ai/AgentChat/index.js +176 -0
- package/dist/components/ai/AgentChat/index.js.map +1 -0
- package/dist/components/ai/AgentScreen/index.d.ts +50 -0
- package/dist/components/ai/AgentScreen/index.js +233 -0
- package/dist/components/ai/AgentScreen/index.js.map +1 -0
- package/dist/components/ai/ApprovalCard/index.d.ts +26 -0
- package/dist/components/ai/ApprovalCard/index.js +89 -0
- package/dist/components/ai/ApprovalCard/index.js.map +1 -0
- package/dist/components/ai/CodeView/index.d.ts +30 -0
- package/dist/components/ai/CodeView/index.js +149 -0
- package/dist/components/ai/CodeView/index.js.map +1 -0
- package/dist/components/ai/CommandSearch/index.d.ts +39 -0
- package/dist/components/ai/CommandSearch/index.js +217 -0
- package/dist/components/ai/CommandSearch/index.js.map +1 -0
- package/dist/components/ai/ContextCards/index.d.ts +42 -0
- package/dist/components/ai/ContextCards/index.js +106 -0
- package/dist/components/ai/ContextCards/index.js.map +1 -0
- package/dist/components/ai/DiffTable/index.d.ts +70 -0
- package/dist/components/ai/DiffTable/index.js +235 -0
- package/dist/components/ai/DiffTable/index.js.map +1 -0
- package/dist/components/ai/FilterTable/index.d.ts +35 -0
- package/dist/components/ai/FilterTable/index.js +86 -0
- package/dist/components/ai/FilterTable/index.js.map +1 -0
- package/dist/components/ai/FineTuneCard/index.d.ts +24 -0
- package/dist/components/ai/FineTuneCard/index.js +75 -0
- package/dist/components/ai/FineTuneCard/index.js.map +1 -0
- package/dist/components/ai/InsightCards/index.d.ts +23 -0
- package/dist/components/ai/InsightCards/index.js +64 -0
- package/dist/components/ai/InsightCards/index.js.map +1 -0
- package/dist/components/ai/LoadingState/index.d.ts +22 -0
- package/dist/components/ai/LoadingState/index.js +80 -0
- package/dist/components/ai/LoadingState/index.js.map +1 -0
- package/dist/components/ai/PromptBar/index.d.ts +26 -0
- package/dist/components/ai/PromptBar/index.js +117 -0
- package/dist/components/ai/PromptBar/index.js.map +1 -0
- package/dist/components/ai/RecommendationCard/index.d.ts +44 -0
- package/dist/components/ai/RecommendationCard/index.js +142 -0
- package/dist/components/ai/RecommendationCard/index.js.map +1 -0
- package/dist/components/ai/RecordsTable/index.d.ts +65 -0
- package/dist/components/ai/RecordsTable/index.js +334 -0
- package/dist/components/ai/RecordsTable/index.js.map +1 -0
- package/dist/components/ai/SelectionActions/index.d.ts +19 -0
- package/dist/components/ai/SelectionActions/index.js +40 -0
- package/dist/components/ai/SelectionActions/index.js.map +1 -0
- package/dist/components/ai/StateFlow/index.d.ts +24 -0
- package/dist/components/ai/StateFlow/index.js +50 -0
- package/dist/components/ai/StateFlow/index.js.map +1 -0
- package/dist/components/ai/StreamingText/index.d.ts +44 -0
- package/dist/components/ai/StreamingText/index.js +211 -0
- package/dist/components/ai/StreamingText/index.js.map +1 -0
- package/dist/components/ai/TaskRows/index.d.ts +53 -0
- package/dist/components/ai/TaskRows/index.js +186 -0
- package/dist/components/ai/TaskRows/index.js.map +1 -0
- package/dist/components/ai/Thinking/index.d.ts +47 -0
- package/dist/components/ai/Thinking/index.js +197 -0
- package/dist/components/ai/Thinking/index.js.map +1 -0
- package/dist/components/ai/ToolChips/index.d.ts +21 -0
- package/dist/components/ai/ToolChips/index.js +63 -0
- package/dist/components/ai/ToolChips/index.js.map +1 -0
- package/dist/components/ai/index.d.ts +50 -0
- package/dist/components/ai/shared.d.ts +13 -0
- package/dist/components/ai/shared.js +25 -0
- package/dist/components/ai/shared.js.map +1 -0
- package/dist/components/pro/DataTable/DataTable.js +70 -51
- package/dist/components/pro/DataTable/DataTable.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableBody.d.ts +3 -1
- package/dist/components/pro/DataTable/components/TableBody.js +41 -39
- package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableToolbar.d.ts +2 -1
- package/dist/components/pro/DataTable/components/TableToolbar.js +25 -19
- package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
- package/dist/components/pro/DataTable/index.d.ts +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
- package/dist/components/pro/DataTable/types.d.ts +19 -0
- package/dist/data-table.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +128 -107
- package/dist/layouts/Sidebar.d.ts +16 -0
- package/dist/layouts/Sidebar.js +85 -52
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/lite.d.ts +2 -0
- package/dist/lite.js +22 -21
- package/package.json +10 -3
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { cn as e } from "../../../utils/cn.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import t, { useEffect as n, useState as r } from "react";
|
|
4
|
+
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/ai/StreamingText/index.tsx
|
|
6
|
+
var s = 30, c = {
|
|
7
|
+
width: 16,
|
|
8
|
+
height: 16,
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
fill: "none",
|
|
11
|
+
stroke: "currentColor",
|
|
12
|
+
strokeWidth: 2,
|
|
13
|
+
strokeLinecap: "round",
|
|
14
|
+
strokeLinejoin: "round",
|
|
15
|
+
"aria-hidden": !0
|
|
16
|
+
}, l = () => /* @__PURE__ */ o("svg", {
|
|
17
|
+
...c,
|
|
18
|
+
children: [/* @__PURE__ */ a("rect", {
|
|
19
|
+
width: "14",
|
|
20
|
+
height: "14",
|
|
21
|
+
x: "8",
|
|
22
|
+
y: "8",
|
|
23
|
+
rx: "2"
|
|
24
|
+
}), /* @__PURE__ */ a("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })]
|
|
25
|
+
}), u = () => /* @__PURE__ */ o("svg", {
|
|
26
|
+
...c,
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ a("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
29
|
+
/* @__PURE__ */ a("path", { d: "M21 3v5h-5" }),
|
|
30
|
+
/* @__PURE__ */ a("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
31
|
+
/* @__PURE__ */ a("path", { d: "M8 16H3v5" })
|
|
32
|
+
]
|
|
33
|
+
}), d = () => /* @__PURE__ */ o("svg", {
|
|
34
|
+
...c,
|
|
35
|
+
children: [/* @__PURE__ */ a("path", { d: "M7 10v12" }), /* @__PURE__ */ a("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" })]
|
|
36
|
+
}), f = () => /* @__PURE__ */ o("svg", {
|
|
37
|
+
...c,
|
|
38
|
+
children: [/* @__PURE__ */ a("path", { d: "M17 14V2" }), /* @__PURE__ */ a("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" })]
|
|
39
|
+
}), p = () => /* @__PURE__ */ o("svg", {
|
|
40
|
+
...c,
|
|
41
|
+
children: [/* @__PURE__ */ a("path", { d: "M7 17 17 7" }), /* @__PURE__ */ a("path", { d: "M7 7h10v10" })]
|
|
42
|
+
}), m = /\[(\d+)\]/g, h = (e) => (e.domain ?? e.title).trim().charAt(0).toUpperCase();
|
|
43
|
+
function g(e, t, n, r) {
|
|
44
|
+
if (!n) return [e];
|
|
45
|
+
let i = [], o = 0, s;
|
|
46
|
+
for (m.lastIndex = 0; (s = m.exec(e)) !== null;) {
|
|
47
|
+
s.index > o && i.push(e.slice(o, s.index));
|
|
48
|
+
let n = Number(s[1]), c = t?.[n - 1], l = c ? c.title : `Source ${n}`;
|
|
49
|
+
i.push(c?.url ? /* @__PURE__ */ a("a", {
|
|
50
|
+
className: "dishui-ai-streaming__cite",
|
|
51
|
+
href: c.url,
|
|
52
|
+
target: "_blank",
|
|
53
|
+
rel: "noreferrer",
|
|
54
|
+
title: l,
|
|
55
|
+
"aria-label": l,
|
|
56
|
+
children: n
|
|
57
|
+
}, `${r}-${s.index}`) : /* @__PURE__ */ a("span", {
|
|
58
|
+
className: "dishui-ai-streaming__cite",
|
|
59
|
+
title: l,
|
|
60
|
+
"aria-label": l,
|
|
61
|
+
role: "note",
|
|
62
|
+
children: n
|
|
63
|
+
}, `${r}-${s.index}`)), o = s.index + s[0].length;
|
|
64
|
+
}
|
|
65
|
+
return o < e.length && i.push(e.slice(o)), i;
|
|
66
|
+
}
|
|
67
|
+
function _({ text: c, streaming: m = !1, typewriter: _ = !1, typewriterSpeed: v = 3, sources: y, citations: b = !1, maxVisibleSources: x = 3, actions: S, onCopy: C, onRegenerate: w, onFeedback: T, followUps: E, onFollowUp: D, followUpsLabel: O = "Follow-ups", className: k, ...A }) {
|
|
68
|
+
let [j, M] = r(0), [N, P] = r(!1), F = _ && j < c.length;
|
|
69
|
+
n(() => {
|
|
70
|
+
if (!F) return;
|
|
71
|
+
let e = window.setTimeout(() => {
|
|
72
|
+
M((e) => Math.min(c.length, e + Math.max(1, v)));
|
|
73
|
+
}, s);
|
|
74
|
+
return () => window.clearTimeout(e);
|
|
75
|
+
}, [
|
|
76
|
+
F,
|
|
77
|
+
c.length,
|
|
78
|
+
v
|
|
79
|
+
]);
|
|
80
|
+
let I = _ ? c.slice(0, j) : c, L = m || F, R = I.split(/\n{2,}/).filter((e, t, n) => e.length > 0 || L && t === n.length - 1), z = [];
|
|
81
|
+
C && z.push({
|
|
82
|
+
id: "copy",
|
|
83
|
+
label: "Copy",
|
|
84
|
+
icon: /* @__PURE__ */ a(l, {}),
|
|
85
|
+
onClick: () => C(c)
|
|
86
|
+
}), w && z.push({
|
|
87
|
+
id: "regenerate",
|
|
88
|
+
label: "Regenerate",
|
|
89
|
+
icon: /* @__PURE__ */ a(u, {}),
|
|
90
|
+
onClick: w
|
|
91
|
+
}), T && (z.push({
|
|
92
|
+
id: "up",
|
|
93
|
+
label: "Good response",
|
|
94
|
+
icon: /* @__PURE__ */ a(d, {}),
|
|
95
|
+
onClick: () => T("up")
|
|
96
|
+
}), z.push({
|
|
97
|
+
id: "down",
|
|
98
|
+
label: "Bad response",
|
|
99
|
+
icon: /* @__PURE__ */ a(f, {}),
|
|
100
|
+
onClick: () => T("down")
|
|
101
|
+
}));
|
|
102
|
+
let B = [...z, ...S ?? []], V = y ?? [], H = N ? V : V.slice(0, x), U = V.length - H.length;
|
|
103
|
+
return /* @__PURE__ */ o("div", {
|
|
104
|
+
...A,
|
|
105
|
+
className: e("dishui-ai-streaming", L && "dishui-ai-streaming--live", k),
|
|
106
|
+
children: [
|
|
107
|
+
/* @__PURE__ */ a("div", {
|
|
108
|
+
className: "dishui-ai-streaming__body",
|
|
109
|
+
"aria-live": L ? "polite" : void 0,
|
|
110
|
+
"aria-busy": L || void 0,
|
|
111
|
+
children: R.map((e, n) => {
|
|
112
|
+
let r = e.split("\n"), i = n === R.length - 1;
|
|
113
|
+
return /* @__PURE__ */ o("p", {
|
|
114
|
+
className: "dishui-ai-streaming__paragraph",
|
|
115
|
+
children: [r.map((e, r) => /* @__PURE__ */ o(t.Fragment, { children: [r > 0 && /* @__PURE__ */ a("br", {}), g(e, y, b, `${n}-${r}`)] }, e)), i && L && /* @__PURE__ */ a("span", {
|
|
116
|
+
className: "dishui-ai-streaming__caret",
|
|
117
|
+
"aria-hidden": "true"
|
|
118
|
+
})]
|
|
119
|
+
}, e);
|
|
120
|
+
})
|
|
121
|
+
}),
|
|
122
|
+
V.length > 0 && /* @__PURE__ */ o("div", {
|
|
123
|
+
className: "dishui-ai-streaming__sources",
|
|
124
|
+
children: [/* @__PURE__ */ o("span", {
|
|
125
|
+
className: "dishui-ai-streaming__sources-count",
|
|
126
|
+
children: [
|
|
127
|
+
V.length,
|
|
128
|
+
" ",
|
|
129
|
+
V.length === 1 ? "source" : "sources"
|
|
130
|
+
]
|
|
131
|
+
}), /* @__PURE__ */ o("ul", {
|
|
132
|
+
className: "dishui-ai-streaming__source-list",
|
|
133
|
+
children: [H.map((e, t) => {
|
|
134
|
+
let n = /* @__PURE__ */ o(i, { children: [
|
|
135
|
+
/* @__PURE__ */ a("span", {
|
|
136
|
+
className: "dishui-ai-streaming__source-icon",
|
|
137
|
+
"aria-hidden": "true",
|
|
138
|
+
children: e.favicon ?? h(e)
|
|
139
|
+
}),
|
|
140
|
+
/* @__PURE__ */ a("span", {
|
|
141
|
+
className: "dishui-ai-streaming__source-title",
|
|
142
|
+
children: e.title
|
|
143
|
+
}),
|
|
144
|
+
e.domain && /* @__PURE__ */ a("span", {
|
|
145
|
+
className: "dishui-ai-streaming__source-domain",
|
|
146
|
+
children: e.domain
|
|
147
|
+
})
|
|
148
|
+
] });
|
|
149
|
+
return /* @__PURE__ */ a("li", { children: e.url ? /* @__PURE__ */ a("a", {
|
|
150
|
+
className: "dishui-ai-streaming__source",
|
|
151
|
+
href: e.url,
|
|
152
|
+
target: "_blank",
|
|
153
|
+
rel: "noreferrer",
|
|
154
|
+
title: `[${t + 1}] ${e.title}`,
|
|
155
|
+
children: n
|
|
156
|
+
}) : /* @__PURE__ */ a("span", {
|
|
157
|
+
className: "dishui-ai-streaming__source",
|
|
158
|
+
title: `[${t + 1}] ${e.title}`,
|
|
159
|
+
children: n
|
|
160
|
+
}) }, e.id);
|
|
161
|
+
}), (U > 0 || N) && V.length > x && /* @__PURE__ */ a("li", { children: /* @__PURE__ */ a("button", {
|
|
162
|
+
type: "button",
|
|
163
|
+
className: "dishui-ai-streaming__source dishui-ai-streaming__source--more",
|
|
164
|
+
"aria-expanded": N,
|
|
165
|
+
onClick: () => P((e) => !e),
|
|
166
|
+
children: N ? "Show less" : `+${U}`
|
|
167
|
+
}) })]
|
|
168
|
+
})]
|
|
169
|
+
}),
|
|
170
|
+
!L && B.length > 0 && /* @__PURE__ */ a("div", {
|
|
171
|
+
className: "dishui-ai-streaming__actions",
|
|
172
|
+
role: "toolbar",
|
|
173
|
+
"aria-label": "Answer actions",
|
|
174
|
+
children: B.map((t) => /* @__PURE__ */ a("button", {
|
|
175
|
+
type: "button",
|
|
176
|
+
className: e("dishui-ai-streaming__action", !t.icon && "dishui-ai-streaming__action--text"),
|
|
177
|
+
"aria-label": t.label,
|
|
178
|
+
title: t.label,
|
|
179
|
+
onClick: t.onClick,
|
|
180
|
+
children: t.icon ?? t.label
|
|
181
|
+
}, t.id))
|
|
182
|
+
}),
|
|
183
|
+
!L && E && E.length > 0 && /* @__PURE__ */ o("div", {
|
|
184
|
+
className: "dishui-ai-streaming__follow-ups",
|
|
185
|
+
children: [/* @__PURE__ */ a("div", {
|
|
186
|
+
className: "dishui-ai-streaming__follow-ups-label",
|
|
187
|
+
children: O
|
|
188
|
+
}), /* @__PURE__ */ a("ul", {
|
|
189
|
+
className: "dishui-ai-streaming__follow-up-list",
|
|
190
|
+
children: E.map((e) => /* @__PURE__ */ a("li", { children: /* @__PURE__ */ o("button", {
|
|
191
|
+
type: "button",
|
|
192
|
+
className: "dishui-ai-streaming__follow-up",
|
|
193
|
+
onClick: () => D?.(e),
|
|
194
|
+
children: [/* @__PURE__ */ a("span", {
|
|
195
|
+
className: "dishui-ai-streaming__follow-up-text",
|
|
196
|
+
children: e
|
|
197
|
+
}), /* @__PURE__ */ a("span", {
|
|
198
|
+
className: "dishui-ai-streaming__follow-up-icon",
|
|
199
|
+
"aria-hidden": "true",
|
|
200
|
+
children: /* @__PURE__ */ a(p, {})
|
|
201
|
+
})]
|
|
202
|
+
}) }, e))
|
|
203
|
+
})]
|
|
204
|
+
})
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//#endregion
|
|
209
|
+
export { _ as default };
|
|
210
|
+
|
|
211
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ai/StreamingText/index.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { cn } from '../../../utils/cn';\nimport './StreamingText.css';\n\nexport type StreamingSource = {\n id: string;\n title: string;\n domain?: string;\n url?: string;\n favicon?: React.ReactNode;\n};\n\nexport type StreamingAction = {\n id: string;\n label: string;\n icon?: React.ReactNode;\n onClick?: () => void;\n};\n\nexport type StreamingFeedback = 'up' | 'down';\n\nexport type StreamingTextProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {\n /** Full or partial answer text. `\\n\\n` starts a new paragraph. */\n text: string;\n /** Shows the caret and hides actions / follow-ups until the answer is complete. */\n streaming?: boolean;\n /** Reveal `text` progressively on the client. Remount (key) to replay. */\n typewriter?: boolean;\n /** Characters revealed per tick in typewriter mode. */\n typewriterSpeed?: number;\n sources?: StreamingSource[];\n /** Render `[n]` markers in `text` as inline chips pointing at `sources[n - 1]`. */\n citations?: boolean;\n /** Source chips shown before the “+k” overflow toggle. */\n maxVisibleSources?: number;\n /** Extra actions appended after the built-in copy / regenerate / feedback buttons. */\n actions?: StreamingAction[];\n onCopy?: (text: string) => void;\n onRegenerate?: () => void;\n onFeedback?: (kind: StreamingFeedback) => void;\n followUps?: string[];\n onFollowUp?: (question: string) => void;\n followUpsLabel?: React.ReactNode;\n};\n\nconst TYPEWRITER_TICK_MS = 30;\n\nconst svgProps = { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true } as const;\nconst CopyIcon = () => (\n <svg {...svgProps}><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" /><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" /></svg>\n);\nconst RefreshIcon = () => (\n <svg {...svgProps}><path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" /><path d=\"M21 3v5h-5\" /><path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" /><path d=\"M8 16H3v5\" /></svg>\n);\nconst ThumbsUpIcon = () => (\n <svg {...svgProps}><path d=\"M7 10v12\" /><path d=\"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z\" /></svg>\n);\nconst ThumbsDownIcon = () => (\n <svg {...svgProps}><path d=\"M17 14V2\" /><path d=\"M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z\" /></svg>\n);\nconst ArrowIcon = () => (\n <svg {...svgProps}><path d=\"M7 17 17 7\" /><path d=\"M7 7h10v10\" /></svg>\n);\n\nconst CITATION_RE = /\\[(\\d+)\\]/g;\n\nconst initialOf = (source: StreamingSource) => (source.domain ?? source.title).trim().charAt(0).toUpperCase();\n\nfunction renderLine(line: string, sources: StreamingSource[] | undefined, citations: boolean, keyBase: string): React.ReactNode[] {\n if (!citations) return [line];\n const nodes: React.ReactNode[] = [];\n let last = 0;\n let match: RegExpExecArray | null;\n CITATION_RE.lastIndex = 0;\n while ((match = CITATION_RE.exec(line)) !== null) {\n if (match.index > last) nodes.push(line.slice(last, match.index));\n const n = Number(match[1]);\n const source = sources?.[n - 1];\n const label = source ? source.title : `Source ${n}`;\n nodes.push(\n source?.url ? (\n <a key={`${keyBase}-${match.index}`} className=\"dishui-ai-streaming__cite\" href={source.url} target=\"_blank\" rel=\"noreferrer\" title={label} aria-label={label}>{n}</a>\n ) : (\n <span key={`${keyBase}-${match.index}`} className=\"dishui-ai-streaming__cite\" title={label} aria-label={label} role=\"note\">{n}</span>\n ),\n );\n last = match.index + match[0].length;\n }\n if (last < line.length) nodes.push(line.slice(last));\n return nodes;\n}\n\n/**\n * Streamed answer: paragraphs with optional inline citations, a source bar,\n * an action row and follow-up questions. Fully controlled — it renders the\n * `text` it is given; `typewriter` only adds a client-side reveal.\n */\nexport default function StreamingText({\n text,\n streaming = false,\n typewriter = false,\n typewriterSpeed = 3,\n sources,\n citations = false,\n maxVisibleSources = 3,\n actions,\n onCopy,\n onRegenerate,\n onFeedback,\n followUps,\n onFollowUp,\n followUpsLabel = 'Follow-ups',\n className,\n ...rest\n}: StreamingTextProps) {\n const [revealed, setRevealed] = useState(0);\n const [showAllSources, setShowAllSources] = useState(false);\n\n const revealing = typewriter && revealed < text.length;\n useEffect(() => {\n if (!revealing) return;\n const id = window.setTimeout(() => {\n setRevealed(count => Math.min(text.length, count + Math.max(1, typewriterSpeed)));\n }, TYPEWRITER_TICK_MS);\n return () => window.clearTimeout(id);\n }, [revealing, text.length, typewriterSpeed]);\n\n const visibleText = typewriter ? text.slice(0, revealed) : text;\n const live = streaming || revealing;\n // Keep a trailing empty paragraph only while live so the caret has a home.\n const paragraphs = visibleText.split(/\\n{2,}/).filter((p, i, all) => p.length > 0 || (live && i === all.length - 1));\n\n const builtIns: StreamingAction[] = [];\n if (onCopy) builtIns.push({ id: 'copy', label: 'Copy', icon: <CopyIcon />, onClick: () => onCopy(text) });\n if (onRegenerate) builtIns.push({ id: 'regenerate', label: 'Regenerate', icon: <RefreshIcon />, onClick: onRegenerate });\n if (onFeedback) {\n builtIns.push({ id: 'up', label: 'Good response', icon: <ThumbsUpIcon />, onClick: () => onFeedback('up') });\n builtIns.push({ id: 'down', label: 'Bad response', icon: <ThumbsDownIcon />, onClick: () => onFeedback('down') });\n }\n const allActions = [...builtIns, ...(actions ?? [])];\n\n const sourceList = sources ?? [];\n const visibleSources = showAllSources ? sourceList : sourceList.slice(0, maxVisibleSources);\n const overflow = sourceList.length - visibleSources.length;\n\n return (\n <div {...rest} className={cn('dishui-ai-streaming', live && 'dishui-ai-streaming--live', className)}>\n <div className=\"dishui-ai-streaming__body\" aria-live={live ? 'polite' : undefined} aria-busy={live || undefined}>\n {paragraphs.map((paragraph, pi) => {\n const lines = paragraph.split('\\n');\n const isLast = pi === paragraphs.length - 1;\n return (\n <p key={paragraph} className=\"dishui-ai-streaming__paragraph\">\n {lines.map((line, li) => (\n <React.Fragment key={line}>\n {li > 0 && <br />}\n {renderLine(line, sources, citations, `${pi}-${li}`)}\n </React.Fragment>\n ))}\n {isLast && live && <span className=\"dishui-ai-streaming__caret\" aria-hidden=\"true\" />}\n </p>\n );\n })}\n </div>\n\n {sourceList.length > 0 && (\n <div className=\"dishui-ai-streaming__sources\">\n <span className=\"dishui-ai-streaming__sources-count\">\n {sourceList.length} {sourceList.length === 1 ? 'source' : 'sources'}\n </span>\n <ul className=\"dishui-ai-streaming__source-list\">\n {visibleSources.map((source, i) => {\n const inner = (\n <>\n <span className=\"dishui-ai-streaming__source-icon\" aria-hidden=\"true\">{source.favicon ?? initialOf(source)}</span>\n <span className=\"dishui-ai-streaming__source-title\">{source.title}</span>\n {source.domain && <span className=\"dishui-ai-streaming__source-domain\">{source.domain}</span>}\n </>\n );\n return (\n <li key={source.id}>\n {source.url ? (\n <a className=\"dishui-ai-streaming__source\" href={source.url} target=\"_blank\" rel=\"noreferrer\" title={`[${i + 1}] ${source.title}`}>{inner}</a>\n ) : (\n <span className=\"dishui-ai-streaming__source\" title={`[${i + 1}] ${source.title}`}>{inner}</span>\n )}\n </li>\n );\n })}\n {(overflow > 0 || showAllSources) && sourceList.length > maxVisibleSources && (\n <li>\n <button\n type=\"button\"\n className=\"dishui-ai-streaming__source dishui-ai-streaming__source--more\"\n aria-expanded={showAllSources}\n onClick={() => setShowAllSources(v => !v)}\n >\n {showAllSources ? 'Show less' : `+${overflow}`}\n </button>\n </li>\n )}\n </ul>\n </div>\n )}\n\n {!live && allActions.length > 0 && (\n <div className=\"dishui-ai-streaming__actions\" role=\"toolbar\" aria-label=\"Answer actions\">\n {allActions.map(action => (\n <button\n key={action.id}\n type=\"button\"\n className={cn('dishui-ai-streaming__action', !action.icon && 'dishui-ai-streaming__action--text')}\n aria-label={action.label}\n title={action.label}\n onClick={action.onClick}\n >\n {action.icon ?? action.label}\n </button>\n ))}\n </div>\n )}\n\n {!live && followUps && followUps.length > 0 && (\n <div className=\"dishui-ai-streaming__follow-ups\">\n <div className=\"dishui-ai-streaming__follow-ups-label\">{followUpsLabel}</div>\n <ul className=\"dishui-ai-streaming__follow-up-list\">\n {followUps.map(question => (\n <li key={question}>\n <button type=\"button\" className=\"dishui-ai-streaming__follow-up\" onClick={() => onFollowUp?.(question)}>\n <span className=\"dishui-ai-streaming__follow-up-text\">{question}</span>\n <span className=\"dishui-ai-streaming__follow-up-icon\" aria-hidden=\"true\"><ArrowIcon /></span>\n </button>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AgentStatus } from '../shared';
|
|
3
|
+
export type AgentSubtask = {
|
|
4
|
+
id: string;
|
|
5
|
+
title: React.ReactNode;
|
|
6
|
+
/** Right-aligned value, e.g. `12/12`, `68%`, `draft`. */
|
|
7
|
+
value?: React.ReactNode;
|
|
8
|
+
status?: AgentStatus;
|
|
9
|
+
};
|
|
10
|
+
export type AgentTask = {
|
|
11
|
+
id: string;
|
|
12
|
+
title: React.ReactNode;
|
|
13
|
+
/** Short qualifier shown after the title, e.g. `12 suppliers`. */
|
|
14
|
+
meta?: React.ReactNode;
|
|
15
|
+
status: AgentStatus;
|
|
16
|
+
/** Determinate progress 0–100. Running tasks without it show an indeterminate bar. */
|
|
17
|
+
progress?: number;
|
|
18
|
+
subtasks?: AgentSubtask[];
|
|
19
|
+
/** Shown under a failed task, next to the retry action. */
|
|
20
|
+
error?: React.ReactNode;
|
|
21
|
+
};
|
|
22
|
+
export type TaskRowsView = 'capsules' | 'list';
|
|
23
|
+
export type TaskRowsLabels = {
|
|
24
|
+
capsules?: string;
|
|
25
|
+
list?: string;
|
|
26
|
+
retry?: string;
|
|
27
|
+
view?: string;
|
|
28
|
+
status?: Partial<Record<AgentStatus, string>>;
|
|
29
|
+
};
|
|
30
|
+
export type TaskRowsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {
|
|
31
|
+
tasks: AgentTask[];
|
|
32
|
+
/** Controlled view mode. */
|
|
33
|
+
view?: TaskRowsView;
|
|
34
|
+
defaultView?: TaskRowsView;
|
|
35
|
+
onViewChange?: (view: TaskRowsView) => void;
|
|
36
|
+
/** Render the Capsules / List toggle above the tasks. */
|
|
37
|
+
showViewToggle?: boolean;
|
|
38
|
+
/** Controlled list of task ids whose subtasks are visible. */
|
|
39
|
+
expanded?: string[];
|
|
40
|
+
/** Defaults to every running or failed task. */
|
|
41
|
+
defaultExpanded?: string[];
|
|
42
|
+
onExpandedChange?: (expanded: string[]) => void;
|
|
43
|
+
/** Enables the retry action on failed tasks. */
|
|
44
|
+
onRetry?: (task: AgentTask) => void;
|
|
45
|
+
emptyText?: React.ReactNode;
|
|
46
|
+
labels?: TaskRowsLabels;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Live agent task status. Each task is a row (or capsule) with a text +
|
|
50
|
+
* colour status pill, optional progress and expandable subtasks with
|
|
51
|
+
* right-aligned tabular values.
|
|
52
|
+
*/
|
|
53
|
+
export default function TaskRows({ tasks, view: viewProp, defaultView, onViewChange, showViewToggle, expanded: expandedProp, defaultExpanded, onExpandedChange, onRetry, emptyText, labels, className, ...rest }: TaskRowsProps): React.JSX.Element;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { cn as e } from "../../../utils/cn.js";
|
|
2
|
+
import { AGENT_STATUS_LABEL as t, clamp as n } from "../shared.js";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import { useCallback as r, useId as i, useState as a } from "react";
|
|
5
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ai/TaskRows/index.tsx
|
|
7
|
+
var c = {
|
|
8
|
+
capsules: "Capsules",
|
|
9
|
+
list: "List",
|
|
10
|
+
retry: "Retry",
|
|
11
|
+
view: "View"
|
|
12
|
+
}, l = {
|
|
13
|
+
pending: "neutral",
|
|
14
|
+
running: "info",
|
|
15
|
+
completed: "success",
|
|
16
|
+
failed: "danger",
|
|
17
|
+
skipped: "neutral"
|
|
18
|
+
}, u = () => /* @__PURE__ */ o("svg", {
|
|
19
|
+
width: "16",
|
|
20
|
+
height: "16",
|
|
21
|
+
viewBox: "0 0 24 24",
|
|
22
|
+
fill: "none",
|
|
23
|
+
stroke: "currentColor",
|
|
24
|
+
strokeWidth: "2",
|
|
25
|
+
strokeLinecap: "round",
|
|
26
|
+
strokeLinejoin: "round",
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
children: /* @__PURE__ */ o("path", { d: "m9 18 6-6-6-6" })
|
|
29
|
+
}), d = () => /* @__PURE__ */ s("svg", {
|
|
30
|
+
width: "16",
|
|
31
|
+
height: "16",
|
|
32
|
+
viewBox: "0 0 24 24",
|
|
33
|
+
fill: "none",
|
|
34
|
+
stroke: "currentColor",
|
|
35
|
+
strokeWidth: "2",
|
|
36
|
+
strokeLinecap: "round",
|
|
37
|
+
strokeLinejoin: "round",
|
|
38
|
+
"aria-hidden": "true",
|
|
39
|
+
children: [/* @__PURE__ */ o("path", { d: "M3 12a9 9 0 1 0 3-6.7" }), /* @__PURE__ */ o("path", { d: "M3 4v5h5" })]
|
|
40
|
+
}), f = ({ status: t, label: n }) => /* @__PURE__ */ s("span", {
|
|
41
|
+
className: e("dishui-ai-task-rows__status", `dishui-ai-task-rows__status--${l[t]}`),
|
|
42
|
+
children: [t === "running" && /* @__PURE__ */ o("span", {
|
|
43
|
+
className: "dishui-ai-task-rows__pulse",
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
}), n]
|
|
46
|
+
}), p = (e) => e.filter((e) => e.status === "running" || e.status === "failed").map((e) => e.id);
|
|
47
|
+
function m({ tasks: l, view: m, defaultView: h = "capsules", onViewChange: g, showViewToggle: _ = !1, expanded: v, defaultExpanded: y, onExpandedChange: b, onRetry: x, emptyText: S = "No tasks yet", labels: C, className: w, ...T }) {
|
|
48
|
+
let E = i(), D = {
|
|
49
|
+
...c,
|
|
50
|
+
...C
|
|
51
|
+
}, [O, k] = a(h), A = m ?? O, j = r((e) => {
|
|
52
|
+
k(e), g?.(e);
|
|
53
|
+
}, [g]), [M, N] = a(() => y ?? p(l)), P = v ?? M, F = r((e) => {
|
|
54
|
+
let t = P.includes(e) ? P.filter((t) => t !== e) : [...P, e];
|
|
55
|
+
N(t), b?.(t);
|
|
56
|
+
}, [P, b]), I = (e) => C?.status?.[e] ?? t[e];
|
|
57
|
+
return /* @__PURE__ */ s("div", {
|
|
58
|
+
...T,
|
|
59
|
+
className: e("dishui-ai-task-rows", `dishui-ai-task-rows--${A}`, w),
|
|
60
|
+
children: [_ && /* @__PURE__ */ o("div", {
|
|
61
|
+
className: "dishui-ai-task-rows__toolbar",
|
|
62
|
+
children: /* @__PURE__ */ o("div", {
|
|
63
|
+
className: "dishui-ai-task-rows__segmented",
|
|
64
|
+
role: "group",
|
|
65
|
+
"aria-label": D.view,
|
|
66
|
+
children: ["capsules", "list"].map((t) => /* @__PURE__ */ o("button", {
|
|
67
|
+
type: "button",
|
|
68
|
+
className: e("dishui-ai-task-rows__segment", t === A && "dishui-ai-task-rows__segment--active"),
|
|
69
|
+
"aria-pressed": t === A,
|
|
70
|
+
onClick: () => j(t),
|
|
71
|
+
children: D[t]
|
|
72
|
+
}, t))
|
|
73
|
+
})
|
|
74
|
+
}), l.length === 0 ? /* @__PURE__ */ o("div", {
|
|
75
|
+
className: "dishui-ai-task-rows__empty",
|
|
76
|
+
children: S
|
|
77
|
+
}) : /* @__PURE__ */ o("ul", {
|
|
78
|
+
className: "dishui-ai-task-rows__list",
|
|
79
|
+
children: l.map((t) => {
|
|
80
|
+
let r = !!t.subtasks?.length, i = r && P.includes(t.id), a = `${E}-${t.id}`, c = t.progress === void 0 ? void 0 : n(t.progress, 0, 100), l = A === "capsules" && (c !== void 0 || t.status === "running");
|
|
81
|
+
return /* @__PURE__ */ s("li", {
|
|
82
|
+
className: e("dishui-ai-task-rows__task", `dishui-ai-task-rows__task--${t.status}`, i && "dishui-ai-task-rows__task--open"),
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ s("div", {
|
|
85
|
+
className: "dishui-ai-task-rows__row",
|
|
86
|
+
children: [
|
|
87
|
+
r ? /* @__PURE__ */ s("button", {
|
|
88
|
+
type: "button",
|
|
89
|
+
className: "dishui-ai-task-rows__toggle",
|
|
90
|
+
"aria-expanded": i,
|
|
91
|
+
"aria-controls": a,
|
|
92
|
+
onClick: () => F(t.id),
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ o("span", {
|
|
95
|
+
className: "dishui-ai-task-rows__chevron",
|
|
96
|
+
children: /* @__PURE__ */ o(u, {})
|
|
97
|
+
}),
|
|
98
|
+
/* @__PURE__ */ o("span", {
|
|
99
|
+
className: "dishui-ai-task-rows__title",
|
|
100
|
+
children: t.title
|
|
101
|
+
}),
|
|
102
|
+
t.meta !== void 0 && /* @__PURE__ */ o("span", {
|
|
103
|
+
className: "dishui-ai-task-rows__meta",
|
|
104
|
+
children: t.meta
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
}) : /* @__PURE__ */ s("div", {
|
|
108
|
+
className: "dishui-ai-task-rows__toggle dishui-ai-task-rows__toggle--static",
|
|
109
|
+
children: [
|
|
110
|
+
/* @__PURE__ */ o("span", { className: "dishui-ai-task-rows__chevron dishui-ai-task-rows__chevron--blank" }),
|
|
111
|
+
/* @__PURE__ */ o("span", {
|
|
112
|
+
className: "dishui-ai-task-rows__title",
|
|
113
|
+
children: t.title
|
|
114
|
+
}),
|
|
115
|
+
t.meta !== void 0 && /* @__PURE__ */ o("span", {
|
|
116
|
+
className: "dishui-ai-task-rows__meta",
|
|
117
|
+
children: t.meta
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
}),
|
|
121
|
+
c !== void 0 && t.status === "running" && /* @__PURE__ */ s("span", {
|
|
122
|
+
className: "dishui-ai-task-rows__percent",
|
|
123
|
+
children: [Math.round(c), "%"]
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ o(f, {
|
|
126
|
+
status: t.status,
|
|
127
|
+
label: I(t.status)
|
|
128
|
+
})
|
|
129
|
+
]
|
|
130
|
+
}),
|
|
131
|
+
l && /* @__PURE__ */ o("div", {
|
|
132
|
+
className: e("dishui-ai-task-rows__bar", c === void 0 && "dishui-ai-task-rows__bar--indeterminate"),
|
|
133
|
+
role: "progressbar",
|
|
134
|
+
"aria-valuemin": 0,
|
|
135
|
+
"aria-valuemax": 100,
|
|
136
|
+
"aria-valuenow": c,
|
|
137
|
+
children: /* @__PURE__ */ o("span", {
|
|
138
|
+
className: "dishui-ai-task-rows__fill",
|
|
139
|
+
style: c === void 0 ? void 0 : { width: `${c}%` }
|
|
140
|
+
})
|
|
141
|
+
}),
|
|
142
|
+
t.status === "failed" && (t.error !== void 0 || x) && /* @__PURE__ */ s("div", {
|
|
143
|
+
className: "dishui-ai-task-rows__error",
|
|
144
|
+
role: "alert",
|
|
145
|
+
children: [/* @__PURE__ */ o("span", {
|
|
146
|
+
className: "dishui-ai-task-rows__error-text",
|
|
147
|
+
children: t.error
|
|
148
|
+
}), x && /* @__PURE__ */ s("button", {
|
|
149
|
+
type: "button",
|
|
150
|
+
className: "dishui-ai-task-rows__retry",
|
|
151
|
+
onClick: () => x(t),
|
|
152
|
+
children: [/* @__PURE__ */ o(d, {}), D.retry]
|
|
153
|
+
})]
|
|
154
|
+
}),
|
|
155
|
+
r && /* @__PURE__ */ o("ul", {
|
|
156
|
+
id: a,
|
|
157
|
+
className: "dishui-ai-task-rows__subtasks",
|
|
158
|
+
hidden: !i,
|
|
159
|
+
children: t.subtasks.map((n) => /* @__PURE__ */ s("li", {
|
|
160
|
+
className: e("dishui-ai-task-rows__subtask", n.status && `dishui-ai-task-rows__subtask--${n.status}`),
|
|
161
|
+
children: [
|
|
162
|
+
/* @__PURE__ */ o("span", {
|
|
163
|
+
className: "dishui-ai-task-rows__subtitle",
|
|
164
|
+
children: n.title
|
|
165
|
+
}),
|
|
166
|
+
n.value !== void 0 && /* @__PURE__ */ o("span", {
|
|
167
|
+
className: "dishui-ai-task-rows__value",
|
|
168
|
+
children: n.value
|
|
169
|
+
}),
|
|
170
|
+
n.status && n.status !== t.status && /* @__PURE__ */ o("span", {
|
|
171
|
+
className: "dishui-ai-task-rows__substatus",
|
|
172
|
+
children: I(n.status)
|
|
173
|
+
})
|
|
174
|
+
]
|
|
175
|
+
}, n.id))
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
}, t.id);
|
|
179
|
+
})
|
|
180
|
+
})]
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { m as default };
|
|
185
|
+
|
|
186
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ai/TaskRows/index.tsx"],"sourcesContent":["import React, { useCallback, useId, useState } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { AGENT_STATUS_LABEL, clamp } from '../shared';\nimport type { AgentStatus } from '../shared';\nimport './TaskRows.css';\n\nexport type AgentSubtask = {\n id: string;\n title: React.ReactNode;\n /** Right-aligned value, e.g. `12/12`, `68%`, `draft`. */\n value?: React.ReactNode;\n status?: AgentStatus;\n};\n\nexport type AgentTask = {\n id: string;\n title: React.ReactNode;\n /** Short qualifier shown after the title, e.g. `12 suppliers`. */\n meta?: React.ReactNode;\n status: AgentStatus;\n /** Determinate progress 0–100. Running tasks without it show an indeterminate bar. */\n progress?: number;\n subtasks?: AgentSubtask[];\n /** Shown under a failed task, next to the retry action. */\n error?: React.ReactNode;\n};\n\nexport type TaskRowsView = 'capsules' | 'list';\n\nexport type TaskRowsLabels = {\n capsules?: string;\n list?: string;\n retry?: string;\n view?: string;\n status?: Partial<Record<AgentStatus, string>>;\n};\n\nexport type TaskRowsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {\n tasks: AgentTask[];\n /** Controlled view mode. */\n view?: TaskRowsView;\n defaultView?: TaskRowsView;\n onViewChange?: (view: TaskRowsView) => void;\n /** Render the Capsules / List toggle above the tasks. */\n showViewToggle?: boolean;\n /** Controlled list of task ids whose subtasks are visible. */\n expanded?: string[];\n /** Defaults to every running or failed task. */\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n /** Enables the retry action on failed tasks. */\n onRetry?: (task: AgentTask) => void;\n emptyText?: React.ReactNode;\n labels?: TaskRowsLabels;\n};\n\nconst DEFAULT_LABELS = { capsules: 'Capsules', list: 'List', retry: 'Retry', view: 'View' };\n\nconst STATUS_TONE: Record<AgentStatus, string> = {\n pending: 'neutral',\n running: 'info',\n completed: 'success',\n failed: 'danger',\n skipped: 'neutral',\n};\n\nconst ChevronIcon: React.FC = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nconst RetryIcon: React.FC = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M3 12a9 9 0 1 0 3-6.7\" />\n <path d=\"M3 4v5h5\" />\n </svg>\n);\n\nconst StatusPill: React.FC<{ status: AgentStatus; label: string }> = ({ status, label }) => (\n <span className={cn('dishui-ai-task-rows__status', `dishui-ai-task-rows__status--${STATUS_TONE[status]}`)}>\n {status === 'running' && <span className=\"dishui-ai-task-rows__pulse\" aria-hidden=\"true\" />}\n {label}\n </span>\n);\n\nconst defaultExpandedFor = (tasks: AgentTask[]) =>\n tasks.filter(t => t.status === 'running' || t.status === 'failed').map(t => t.id);\n\n/**\n * Live agent task status. Each task is a row (or capsule) with a text +\n * colour status pill, optional progress and expandable subtasks with\n * right-aligned tabular values.\n */\nexport default function TaskRows({\n tasks,\n view: viewProp,\n defaultView = 'capsules',\n onViewChange,\n showViewToggle = false,\n expanded: expandedProp,\n defaultExpanded,\n onExpandedChange,\n onRetry,\n emptyText = 'No tasks yet',\n labels,\n className,\n ...rest\n}: TaskRowsProps) {\n const baseId = useId();\n const text = { ...DEFAULT_LABELS, ...labels };\n\n const [internalView, setInternalView] = useState<TaskRowsView>(defaultView);\n const view = viewProp ?? internalView;\n const changeView = useCallback((next: TaskRowsView) => {\n setInternalView(next);\n onViewChange?.(next);\n }, [onViewChange]);\n\n const [internalExpanded, setInternalExpanded] = useState<string[]>(\n () => defaultExpanded ?? defaultExpandedFor(tasks),\n );\n const expanded = expandedProp ?? internalExpanded;\n const toggle = useCallback((id: string) => {\n const next = expanded.includes(id) ? expanded.filter(x => x !== id) : [...expanded, id];\n setInternalExpanded(next);\n onExpandedChange?.(next);\n }, [expanded, onExpandedChange]);\n\n const statusLabel = (status: AgentStatus) => labels?.status?.[status] ?? AGENT_STATUS_LABEL[status];\n\n return (\n <div {...rest} className={cn('dishui-ai-task-rows', `dishui-ai-task-rows--${view}`, className)}>\n {showViewToggle && (\n <div className=\"dishui-ai-task-rows__toolbar\">\n <div className=\"dishui-ai-task-rows__segmented\" role=\"group\" aria-label={text.view}>\n {(['capsules', 'list'] as TaskRowsView[]).map(v => (\n <button\n key={v}\n type=\"button\"\n className={cn('dishui-ai-task-rows__segment', v === view && 'dishui-ai-task-rows__segment--active')}\n aria-pressed={v === view}\n onClick={() => changeView(v)}\n >\n {text[v]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {tasks.length === 0 ? (\n <div className=\"dishui-ai-task-rows__empty\">{emptyText}</div>\n ) : (\n <ul className=\"dishui-ai-task-rows__list\">\n {tasks.map(task => {\n const hasSubtasks = !!task.subtasks?.length;\n const isOpen = hasSubtasks && expanded.includes(task.id);\n const panelId = `${baseId}-${task.id}`;\n const progress = task.progress === undefined ? undefined : clamp(task.progress, 0, 100);\n const showBar = view === 'capsules' && (progress !== undefined || task.status === 'running');\n return (\n <li\n key={task.id}\n className={cn(\n 'dishui-ai-task-rows__task',\n `dishui-ai-task-rows__task--${task.status}`,\n isOpen && 'dishui-ai-task-rows__task--open',\n )}\n >\n <div className=\"dishui-ai-task-rows__row\">\n {hasSubtasks ? (\n <button\n type=\"button\"\n className=\"dishui-ai-task-rows__toggle\"\n aria-expanded={isOpen}\n aria-controls={panelId}\n onClick={() => toggle(task.id)}\n >\n <span className=\"dishui-ai-task-rows__chevron\"><ChevronIcon /></span>\n <span className=\"dishui-ai-task-rows__title\">{task.title}</span>\n {task.meta !== undefined && <span className=\"dishui-ai-task-rows__meta\">{task.meta}</span>}\n </button>\n ) : (\n <div className=\"dishui-ai-task-rows__toggle dishui-ai-task-rows__toggle--static\">\n <span className=\"dishui-ai-task-rows__chevron dishui-ai-task-rows__chevron--blank\" />\n <span className=\"dishui-ai-task-rows__title\">{task.title}</span>\n {task.meta !== undefined && <span className=\"dishui-ai-task-rows__meta\">{task.meta}</span>}\n </div>\n )}\n {progress !== undefined && task.status === 'running' && (\n <span className=\"dishui-ai-task-rows__percent\">{Math.round(progress)}%</span>\n )}\n <StatusPill status={task.status} label={statusLabel(task.status)} />\n </div>\n\n {showBar && (\n <div\n className={cn('dishui-ai-task-rows__bar', progress === undefined && 'dishui-ai-task-rows__bar--indeterminate')}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={progress}\n >\n <span className=\"dishui-ai-task-rows__fill\" style={progress === undefined ? undefined : { width: `${progress}%` }} />\n </div>\n )}\n\n {task.status === 'failed' && (task.error !== undefined || onRetry) && (\n <div className=\"dishui-ai-task-rows__error\" role=\"alert\">\n <span className=\"dishui-ai-task-rows__error-text\">{task.error}</span>\n {onRetry && (\n <button type=\"button\" className=\"dishui-ai-task-rows__retry\" onClick={() => onRetry(task)}>\n <RetryIcon />\n {text.retry}\n </button>\n )}\n </div>\n )}\n\n {hasSubtasks && (\n <ul id={panelId} className=\"dishui-ai-task-rows__subtasks\" hidden={!isOpen}>\n {task.subtasks!.map(sub => (\n <li\n key={sub.id}\n className={cn('dishui-ai-task-rows__subtask', sub.status && `dishui-ai-task-rows__subtask--${sub.status}`)}\n >\n <span className=\"dishui-ai-task-rows__subtitle\">{sub.title}</span>\n {sub.value !== undefined && <span className=\"dishui-ai-task-rows__value\">{sub.value}</span>}\n {sub.status && sub.status !== task.status && (\n <span className=\"dishui-ai-task-rows__substatus\">{statusLabel(sub.status)}</span>\n )}\n </li>\n ))}\n </ul>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AgentStatus } from '../shared';
|
|
3
|
+
export type ThinkingStepKind = 'step' | 'reasoning' | 'search' | 'coding';
|
|
4
|
+
export type ThinkingMode = 'steps' | 'reasoning' | 'search' | 'coding' | 'auto';
|
|
5
|
+
export type ThinkingStatus = 'thinking' | 'done';
|
|
6
|
+
export type ThinkingSearchResult = {
|
|
7
|
+
title: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
domain?: string;
|
|
10
|
+
};
|
|
11
|
+
export type ThinkingCode = {
|
|
12
|
+
language?: string;
|
|
13
|
+
content: string;
|
|
14
|
+
file?: string;
|
|
15
|
+
};
|
|
16
|
+
export type ThinkingStep = {
|
|
17
|
+
id: string;
|
|
18
|
+
kind: ThinkingStepKind;
|
|
19
|
+
title: React.ReactNode;
|
|
20
|
+
detail?: React.ReactNode;
|
|
21
|
+
/** Defaults to `completed`. */
|
|
22
|
+
status?: AgentStatus;
|
|
23
|
+
durationMs?: number;
|
|
24
|
+
/** Result chips rendered by `search` steps. */
|
|
25
|
+
results?: ThinkingSearchResult[];
|
|
26
|
+
/** Code block rendered by `coding` steps. */
|
|
27
|
+
code?: ThinkingCode;
|
|
28
|
+
};
|
|
29
|
+
export type ThinkingProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'title'> & {
|
|
30
|
+
steps: ThinkingStep[];
|
|
31
|
+
/** Derived from the steps when omitted: any running step → `thinking`. */
|
|
32
|
+
status?: ThinkingStatus;
|
|
33
|
+
/** Total time; rendered as “Thought for 4s” once done. Falls back to the sum of step durations. */
|
|
34
|
+
durationMs?: number;
|
|
35
|
+
/** Overrides the default “Thinking” / “Thought for …” header text. */
|
|
36
|
+
title?: React.ReactNode;
|
|
37
|
+
expanded?: boolean;
|
|
38
|
+
defaultExpanded?: boolean;
|
|
39
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
40
|
+
/** Rendering emphasis. `auto` renders each step by its own `kind`. */
|
|
41
|
+
mode?: ThinkingMode;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Expandable reasoning trace. Collapsed by default; the header summarises the
|
|
45
|
+
* currently running step while collapsed and reads “Thought for …” once done.
|
|
46
|
+
*/
|
|
47
|
+
export default function Thinking({ steps, status: statusProp, durationMs, title, expanded: expandedProp, defaultExpanded, onExpandedChange, mode, className, ...rest }: ThinkingProps): React.JSX.Element;
|