@qfei-design/make-ai-assistant 0.1.0

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/react.mjs ADDED
@@ -0,0 +1,661 @@
1
+ import { jsxs as r, jsx as a, Fragment as N } from "react/jsx-runtime";
2
+ import { resolveArtifactTemplate as pe, createArtifactTemplateRegistry as re, createArtifactCapabilities as he } from "./index.mjs";
3
+ import { extendArtifactTemplateRegistry as Oe } from "./index.mjs";
4
+ import { useState as L, useRef as S, useMemo as fe, useEffect as Y } from "react";
5
+ import { c as ae, a as te, M as b, b as _e, p as ke, r as B } from "./conversation-B5kECJz8.js";
6
+ import { d as je, e as Ue, f as Ye, g as ze, v as Ge } from "./conversation-B5kECJz8.js";
7
+ function ve({
8
+ artifact: e,
9
+ context: t,
10
+ fallback: n,
11
+ onAction: c,
12
+ onActionError: i,
13
+ registry: s
14
+ }) {
15
+ const m = pe(s, e, t);
16
+ if (!m)
17
+ return n ? n(e) : /* @__PURE__ */ r("section", { className: "make-ai-artifact make-ai-artifact--unsupported", role: "status", children: [
18
+ /* @__PURE__ */ a("strong", { children: "暂不支持展示此结果" }),
19
+ /* @__PURE__ */ r("span", { children: [
20
+ "结果类型:",
21
+ e.kind
22
+ ] })
23
+ ] });
24
+ const u = {
25
+ context: t,
26
+ onAction: c,
27
+ onActionError: i
28
+ };
29
+ return m.template.render(e, t, u);
30
+ }
31
+ const w = (e, t, n) => {
32
+ if (e == null || e === "") return "—";
33
+ if (typeof e == "boolean") return e ? "是" : "否";
34
+ if (typeof e != "number") return `${e}${t?.unit ?? ""}`;
35
+ const c = t?.precision, i = {
36
+ maximumFractionDigits: c ?? 2,
37
+ minimumFractionDigits: c
38
+ };
39
+ t?.style === "currency" && t.currency ? (i.style = "currency", i.currency = t.currency) : t?.style === "percent" && (i.style = "percent");
40
+ try {
41
+ const s = t?.style === "percent" ? e / 100 : e;
42
+ return `${new Intl.NumberFormat(n, i).format(s)}${t?.unit ?? ""}`;
43
+ } catch {
44
+ return `${e}${t?.unit ?? ""}`;
45
+ }
46
+ }, se = (e) => {
47
+ let t = Number.POSITIVE_INFINITY, n = Number.NEGATIVE_INFINITY;
48
+ for (const c of e)
49
+ t = Math.min(t, c), n = Math.max(n, c);
50
+ return Number.isFinite(t) && Number.isFinite(n) ? { min: t, max: n } : { min: 0, max: 0 };
51
+ }, ie = (e, t, n) => {
52
+ if (!n.onAction) return;
53
+ const c = (s) => {
54
+ console.error("[make-ai-assistant] host action error handler failed", {
55
+ actionId: e.id,
56
+ artifactId: t.artifact.id,
57
+ errorType: s instanceof Error ? s.name : typeof s,
58
+ intent: e.intent
59
+ });
60
+ }, i = (s) => {
61
+ if (n.onActionError) {
62
+ try {
63
+ Promise.resolve(
64
+ n.onActionError(s, e, t)
65
+ ).catch(c);
66
+ } catch (m) {
67
+ c(m);
68
+ }
69
+ return;
70
+ }
71
+ console.error("[make-ai-assistant] host action failed", {
72
+ actionId: e.id,
73
+ artifactId: t.artifact.id,
74
+ errorType: s instanceof Error ? s.name : typeof s,
75
+ intent: e.intent
76
+ });
77
+ };
78
+ try {
79
+ Promise.resolve(n.onAction(e, t)).catch(i);
80
+ } catch (s) {
81
+ i(s);
82
+ }
83
+ }, C = (e, t) => e.actions?.length && t.onAction ? /* @__PURE__ */ a("div", { className: "make-ai-artifact__actions", children: e.actions.map((n) => /* @__PURE__ */ r(
84
+ "button",
85
+ {
86
+ className: `make-ai-artifact__action make-ai-artifact__action--${n.appearance ?? "link"}`,
87
+ type: "button",
88
+ onClick: () => ie(n, { artifact: e, context: t.context }, t),
89
+ children: [
90
+ n.label,
91
+ /* @__PURE__ */ a("span", { "aria-hidden": "true", children: "→" })
92
+ ]
93
+ },
94
+ n.id
95
+ )) }) : null, F = (e, t, n = "") => /* @__PURE__ */ r(
96
+ "section",
97
+ {
98
+ "aria-label": e.title ?? `${e.kind} result`,
99
+ className: `make-ai-artifact ${n}`.trim(),
100
+ "data-artifact-density": e.presentation?.density,
101
+ "data-artifact-kind": e.kind,
102
+ children: [
103
+ e.title ? /* @__PURE__ */ a("h4", { className: "make-ai-artifact__title", children: e.title }) : null,
104
+ e.summary ? /* @__PURE__ */ a("p", { className: "make-ai-artifact__summary", children: e.summary }) : null,
105
+ t
106
+ ]
107
+ }
108
+ ), ye = ({
109
+ artifact: e,
110
+ renderContext: t
111
+ }) => {
112
+ const n = e.data.delta, c = n ? w(
113
+ n.value,
114
+ n.format === "percent" ? { style: "percent" } : void 0,
115
+ t.context.locale
116
+ ) : void 0;
117
+ return F(
118
+ e,
119
+ /* @__PURE__ */ r(N, { children: [
120
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__metric-value", children: w(
121
+ e.data.value,
122
+ e.data.format,
123
+ t.context.locale
124
+ ) }),
125
+ n ? /* @__PURE__ */ r(
126
+ "div",
127
+ {
128
+ className: `make-ai-artifact__delta make-ai-artifact__delta--${n.direction ?? "flat"}`,
129
+ children: [
130
+ /* @__PURE__ */ a("span", { "aria-hidden": "true", children: n.direction === "up" ? "↗" : n.direction === "down" ? "↘" : "→" }),
131
+ /* @__PURE__ */ a("span", { children: c }),
132
+ n.label ? /* @__PURE__ */ a("span", { children: n.label }) : null
133
+ ]
134
+ }
135
+ ) : null,
136
+ e.data.context ? /* @__PURE__ */ a("p", { className: "make-ai-artifact__context", children: e.data.context }) : null,
137
+ C(e, t)
138
+ ] }),
139
+ "make-ai-artifact--metric"
140
+ );
141
+ }, ge = ({
142
+ artifact: e,
143
+ renderContext: t
144
+ }) => F(
145
+ e,
146
+ /* @__PURE__ */ r(N, { children: [
147
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__comparison", children: e.data.items.map((n) => /* @__PURE__ */ r("div", { className: "make-ai-artifact__comparison-item", children: [
148
+ /* @__PURE__ */ a("span", { children: n.label }),
149
+ /* @__PURE__ */ a("strong", { children: w(n.value, n.format, t.context.locale) }),
150
+ n.hint ? /* @__PURE__ */ a("small", { children: n.hint }) : null
151
+ ] }, n.id)) }),
152
+ C(e, t)
153
+ ] }),
154
+ "make-ai-artifact--comparison"
155
+ ), be = ({
156
+ artifact: e,
157
+ renderContext: t
158
+ }) => {
159
+ const n = e.data.series.flatMap((m) => m.points.map((u) => u.y)), { max: c, min: i } = se(n), s = c - i || 1;
160
+ return F(
161
+ e,
162
+ /* @__PURE__ */ r(N, { children: [
163
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__trend", children: e.data.series.map((m) => /* @__PURE__ */ r("div", { className: "make-ai-artifact__trend-series", children: [
164
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__trend-label", children: m.label }),
165
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__trend-bars", children: m.points.map((u, A) => {
166
+ const h = 18 + (u.y - i) / s * 70;
167
+ return /* @__PURE__ */ r("div", { className: "make-ai-artifact__trend-point", children: [
168
+ /* @__PURE__ */ a(
169
+ "span",
170
+ {
171
+ "aria-label": `${u.x}: ${w(
172
+ u.y,
173
+ m.format,
174
+ t.context.locale
175
+ )}`,
176
+ className: "make-ai-artifact__trend-bar",
177
+ role: "img",
178
+ style: { height: `${h}%` },
179
+ title: `${u.x}: ${w(
180
+ u.y,
181
+ m.format,
182
+ t.context.locale
183
+ )}`
184
+ }
185
+ ),
186
+ /* @__PURE__ */ a("small", { children: u.x })
187
+ ] }, `${u.x}-${A}`);
188
+ }) })
189
+ ] }, m.id)) }),
190
+ C(e, t)
191
+ ] }),
192
+ "make-ai-artifact--trend"
193
+ );
194
+ }, Ae = ({
195
+ artifact: e,
196
+ renderContext: t
197
+ }) => {
198
+ const { max: n } = se(
199
+ e.data.items.map((i) => Math.abs(i.value))
200
+ ), c = Math.max(n, 1);
201
+ return F(
202
+ e,
203
+ /* @__PURE__ */ r(N, { children: [
204
+ /* @__PURE__ */ a("ol", { className: "make-ai-artifact__ranking", children: e.data.items.map((i, s) => /* @__PURE__ */ r("li", { children: [
205
+ /* @__PURE__ */ a("span", { className: "make-ai-artifact__rank", children: s + 1 }),
206
+ /* @__PURE__ */ r("span", { className: "make-ai-artifact__ranking-label", children: [
207
+ /* @__PURE__ */ a("span", { children: i.label }),
208
+ i.description ? /* @__PURE__ */ a("small", { children: i.description }) : null
209
+ ] }),
210
+ /* @__PURE__ */ a("span", { className: "make-ai-artifact__ranking-track", "aria-hidden": "true", children: /* @__PURE__ */ a("span", { style: { width: `${Math.abs(i.value) / c * 100}%` } }) }),
211
+ /* @__PURE__ */ a("strong", { children: w(i.value, i.format, t.context.locale) })
212
+ ] }, i.id)) }),
213
+ C(e, t)
214
+ ] }),
215
+ "make-ai-artifact--ranking"
216
+ );
217
+ }, Ie = (e, t) => t.action ?? {
218
+ id: `open-${t.id}`,
219
+ label: t.title ?? t.id,
220
+ intent: "open-record",
221
+ target: { entityKey: e.data.entity.key, recordId: t.id }
222
+ }, Ne = ({
223
+ artifact: e,
224
+ renderContext: t
225
+ }) => F(
226
+ e,
227
+ /* @__PURE__ */ r(N, { children: [
228
+ /* @__PURE__ */ a("div", { className: "make-ai-artifact__record-list", children: e.data.records.length === 0 ? /* @__PURE__ */ a("p", { className: "make-ai-artifact__empty", children: "没有符合条件的记录" }) : e.data.records.map((n) => {
229
+ const c = Ie(e, n), i = /* @__PURE__ */ r(N, { children: [
230
+ /* @__PURE__ */ a("strong", { children: n.title ?? n.id }),
231
+ /* @__PURE__ */ a("span", { className: "make-ai-artifact__record-values", children: e.data.columns.map((s) => /* @__PURE__ */ r("span", { children: [
232
+ /* @__PURE__ */ a("small", { children: s.label }),
233
+ w(
234
+ n.values[s.key],
235
+ s.format,
236
+ t.context.locale
237
+ )
238
+ ] }, s.key)) }),
239
+ t.onAction ? /* @__PURE__ */ a("span", { "aria-hidden": "true", children: "›" }) : null
240
+ ] });
241
+ return t.onAction ? /* @__PURE__ */ a(
242
+ "button",
243
+ {
244
+ className: "make-ai-artifact__record",
245
+ type: "button",
246
+ onClick: () => ie(c, {
247
+ artifact: e,
248
+ context: t.context
249
+ }, t),
250
+ children: i
251
+ },
252
+ n.id
253
+ ) : /* @__PURE__ */ a("div", { className: "make-ai-artifact__record", children: i }, n.id);
254
+ }) }),
255
+ e.data.total !== void 0 ? /* @__PURE__ */ r("p", { className: "make-ai-artifact__record-total", children: [
256
+ "共 ",
257
+ e.data.total,
258
+ " 条"
259
+ ] }) : null,
260
+ C(e, t)
261
+ ] }),
262
+ "make-ai-artifact--record-list"
263
+ ), we = ({
264
+ artifact: e,
265
+ renderContext: t
266
+ }) => F(
267
+ e,
268
+ /* @__PURE__ */ r(N, { children: [
269
+ /* @__PURE__ */ r("div", { className: `make-ai-artifact__notice make-ai-artifact__notice--${e.data.tone}`, children: [
270
+ /* @__PURE__ */ a("span", { "aria-hidden": "true", children: e.data.tone === "success" ? "✓" : e.data.tone === "warning" ? "!" : e.data.tone === "danger" ? "×" : "i" }),
271
+ /* @__PURE__ */ a("p", { children: e.data.body })
272
+ ] }),
273
+ C(e, t)
274
+ ] }),
275
+ "make-ai-artifact--notice"
276
+ ), x = (e, t, n) => ({ id: e, kinds: [t], priority: 0, render: n }), Te = [
277
+ x("platform.metric.default", "metric", (e, t, n) => /* @__PURE__ */ a(ye, { artifact: e, renderContext: n })),
278
+ x("platform.comparison.default", "comparison", (e, t, n) => /* @__PURE__ */ a(ge, { artifact: e, renderContext: n })),
279
+ x("platform.trend.default", "trend", (e, t, n) => /* @__PURE__ */ a(be, { artifact: e, renderContext: n })),
280
+ x("platform.ranking.default", "ranking", (e, t, n) => /* @__PURE__ */ a(Ae, { artifact: e, renderContext: n })),
281
+ x("platform.record-list.default", "record-list", (e, t, n) => /* @__PURE__ */ a(Ne, { artifact: e, renderContext: n })),
282
+ x("platform.notice.default", "notice", (e, t, n) => /* @__PURE__ */ a(we, { artifact: e, renderContext: n }))
283
+ ], Me = re(Te).templates, Ee = (e = Me) => re(e), $e = (e) => `${e}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
284
+ class p extends Error {
285
+ }
286
+ const ne = (e) => {
287
+ try {
288
+ const t = e?.return?.();
289
+ if (!t) return;
290
+ Promise.resolve(t).catch((n) => {
291
+ console.error("[make-ai-assistant] transport iterator close failed", {
292
+ errorType: n instanceof Error ? n.name : typeof n
293
+ });
294
+ });
295
+ } catch (t) {
296
+ console.error("[make-ai-assistant] transport iterator close failed", {
297
+ errorType: t instanceof Error ? t.name : typeof t
298
+ });
299
+ }
300
+ }, oe = () => /* @__PURE__ */ r("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: [
301
+ /* @__PURE__ */ a("path", { d: "M12 2.8c.5 4.4 2.8 6.8 7.2 7.2-4.4.5-6.8 2.8-7.2 7.2-.5-4.4-2.8-6.8-7.2-7.2 4.4-.5 6.8-2.8 7.2-7.2Z" }),
302
+ /* @__PURE__ */ a("path", { d: "M18.3 16.1c.2 1.8 1.2 2.8 3 3-1.8.2-2.8 1.2-3 3-.2-1.8-1.2-2.8-3-3 1.8-.2 2.8-1.2 3-3Z" })
303
+ ] }), Re = () => /* @__PURE__ */ a("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: /* @__PURE__ */ a("path", { d: "m6 6 12 12M18 6 6 18" }) }), xe = () => /* @__PURE__ */ a("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: /* @__PURE__ */ a("path", { d: "M12 5v14M5 12h14" }) }), Se = () => /* @__PURE__ */ r("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: [
304
+ /* @__PURE__ */ a("path", { d: "m4 4 17 8-17 8 3-8-3-8Z" }),
305
+ /* @__PURE__ */ a("path", { d: "M7 12h14" })
306
+ ] }), z = () => /* @__PURE__ */ a("span", { className: "make-ai-assistant__avatar", "aria-hidden": "true", children: /* @__PURE__ */ a(oe, {}) }), Ce = (e, t, n, c, i) => e.messages.map((s) => /* @__PURE__ */ r(
307
+ "article",
308
+ {
309
+ className: `make-ai-assistant__message make-ai-assistant__message--${s.role}`,
310
+ children: [
311
+ s.role === "assistant" ? /* @__PURE__ */ a(z, {}) : null,
312
+ /* @__PURE__ */ r("div", { className: "make-ai-assistant__message-stack", children: [
313
+ s.content ? /* @__PURE__ */ a("div", { className: "make-ai-assistant__bubble", children: s.content }) : s.status === "streaming" ? /* @__PURE__ */ r("div", { className: "make-ai-assistant__typing", "aria-label": "AI 正在思考", children: [
314
+ /* @__PURE__ */ a("span", {}),
315
+ /* @__PURE__ */ a("span", {}),
316
+ /* @__PURE__ */ a("span", {})
317
+ ] }) : null,
318
+ s.artifacts.map((m) => /* @__PURE__ */ a(
319
+ ve,
320
+ {
321
+ artifact: m,
322
+ context: t,
323
+ onAction: c,
324
+ onActionError: i,
325
+ registry: n
326
+ },
327
+ m.id
328
+ ))
329
+ ] })
330
+ ]
331
+ },
332
+ s.id
333
+ ));
334
+ function Fe({
335
+ context: e,
336
+ onAction: t,
337
+ onActionError: n,
338
+ onClose: c,
339
+ onNewConversation: i,
340
+ registry: s,
341
+ subtitle: m,
342
+ suggestions: u = [],
343
+ title: A = "Make AI 助手",
344
+ transport: h
345
+ }) {
346
+ const [v, T] = L(""), [d, y] = L(ae), [D, P] = L(void 0), M = S(void 0), E = S(void 0), $ = S(0), O = S(null), Z = S(!0), G = fe(
347
+ () => s ?? Ee(),
348
+ [s]
349
+ ), j = (o) => {
350
+ $.current += 1;
351
+ const _ = M.current, g = E.current?.iterator;
352
+ return M.current = void 0, E.current = void 0, !_ && !g ? !1 : (console.info("[make-ai-assistant] local run cancellation requested", { reason: o }), _?.abort(), ne(g), !0);
353
+ };
354
+ Y(() => () => {
355
+ j("unmount");
356
+ }, []), Y(() => {
357
+ const o = O.current;
358
+ if (!o || !Z.current) return;
359
+ const _ = requestAnimationFrame(() => {
360
+ if (!Z.current) return;
361
+ const g = d.status === "streaming" || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth";
362
+ typeof o.scrollTo == "function" ? o.scrollTo({ top: o.scrollHeight, behavior: g }) : o.scrollTop = o.scrollHeight;
363
+ });
364
+ return () => cancelAnimationFrame(_);
365
+ }, [d.messages, d.status]);
366
+ const ce = () => {
367
+ const o = O.current;
368
+ o && (Z.current = o.scrollHeight - o.scrollTop - o.clientHeight <= 48);
369
+ }, U = async (o) => {
370
+ const _ = o.trim();
371
+ if (!_ || d.status === "streaming" || M.current) return;
372
+ if (te(
373
+ _,
374
+ b.messageCharacters
375
+ ) > b.messageCharacters) {
376
+ P(
377
+ `输入内容过长,请控制在 ${b.messageCharacters} 个字符以内`
378
+ );
379
+ return;
380
+ }
381
+ const g = { id: $e("user"), content: _ }, K = new AbortController(), R = $.current + 1;
382
+ $.current = R, M.current = K, P(void 0), T(""), y((k) => _e(k, g));
383
+ try {
384
+ let k = !1, f, J = 0, Q = 0, V = 0;
385
+ const W = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(
386
+ [...d.messages.map((H) => H.id), g.id]
387
+ ), q = /* @__PURE__ */ new Set(), ee = h.run(
388
+ {
389
+ threadId: d.threadId,
390
+ message: g,
391
+ context: e,
392
+ capabilities: he(G)
393
+ },
394
+ { signal: K.signal }
395
+ )[Symbol.asyncIterator]();
396
+ for (E.current = { iterator: ee, requestVersion: R }; ; ) {
397
+ const H = await ee.next();
398
+ if ($.current !== R || H.done) break;
399
+ let l;
400
+ try {
401
+ l = ke(H.value);
402
+ } catch (I) {
403
+ throw new p(
404
+ I instanceof Error ? I.message : "Invalid assistant event"
405
+ );
406
+ }
407
+ if (l.type === "message.start") {
408
+ if (f !== void 0 && f !== l.runId)
409
+ throw new p("AI 助手响应 run id 不一致");
410
+ if (f ??= l.runId, Q += 1, Q > b.assistantMessagesPerRun)
411
+ throw new p("AI 助手单次响应消息数量超过限制");
412
+ if (X.has(l.messageId))
413
+ throw new p("AI 助手响应包含重复的 message id");
414
+ X.add(l.messageId), q.add(l.messageId);
415
+ }
416
+ if (l.type === "message.delta") {
417
+ if (!q.has(l.messageId))
418
+ throw new p("AI 助手响应事件顺序无效");
419
+ const I = te(
420
+ l.delta,
421
+ b.messageCharacters - V
422
+ );
423
+ if (V + I > b.messageCharacters)
424
+ throw new p("AI 助手响应文本超过大小限制");
425
+ if (V += I, V > b.messageCharacters)
426
+ throw new p("AI 助手响应文本超过大小限制");
427
+ }
428
+ if (l.type === "artifact") {
429
+ if (!q.has(l.messageId))
430
+ throw new p("AI 助手响应事件顺序无效");
431
+ if (J += 1, J > b.artifactsPerRun)
432
+ throw new p("AI 助手单次响应 Artifact 数量超过限制");
433
+ if (W.has(l.artifact.id))
434
+ throw new p("AI 助手响应包含重复的 Artifact id");
435
+ W.add(l.artifact.id);
436
+ }
437
+ if (l.type === "message.complete" && !q.delete(l.messageId))
438
+ throw new p("AI 助手响应事件顺序无效");
439
+ if (l.type === "run.complete" && f !== void 0 && f !== l.runId)
440
+ throw new p("AI 助手响应 run id 不一致");
441
+ if (l.type === "run.cancelled" && l.runId !== void 0 && f !== void 0 && f !== l.runId)
442
+ throw new p("AI 助手响应 run id 不一致");
443
+ if (y((I) => B(I, l)), l.type === "error" || l.type === "run.cancelled" || l.type === "run.complete") {
444
+ k = !0;
445
+ break;
446
+ }
447
+ }
448
+ if (!k)
449
+ throw new p("AI 助手流式响应在终止事件前结束");
450
+ } catch (k) {
451
+ if ($.current !== R) return;
452
+ if (K.signal.aborted) {
453
+ y(
454
+ (f) => B(f, { type: "run.cancelled" })
455
+ );
456
+ return;
457
+ }
458
+ console.error("[make-ai-assistant] assistant run failed", {
459
+ appId: e.app.id,
460
+ errorType: k instanceof Error ? k.name : typeof k
461
+ }), y(
462
+ (f) => B(f, {
463
+ type: "error",
464
+ code: "TRANSPORT_ERROR",
465
+ message: k instanceof p ? k.message : "连接失败,请重试",
466
+ retryable: !0
467
+ })
468
+ );
469
+ } finally {
470
+ $.current === R && M.current === K && (M.current = void 0), E.current?.requestVersion === R && (ne(E.current.iterator), E.current = void 0);
471
+ }
472
+ }, le = (o) => {
473
+ o.preventDefault(), U(v);
474
+ }, de = (o) => {
475
+ o.key === "Enter" && !o.shiftKey && !o.nativeEvent.isComposing && (o.preventDefault(), U(v));
476
+ }, me = () => {
477
+ j("stop") && y(
478
+ (o) => B(o, { type: "run.cancelled" })
479
+ );
480
+ }, ue = () => {
481
+ j("new-conversation"), T(""), P(void 0), y(ae()), i?.();
482
+ };
483
+ return /* @__PURE__ */ r("section", { className: "make-ai-assistant make-ai-assistant__panel", children: [
484
+ /* @__PURE__ */ r("header", { className: "make-ai-assistant__header", children: [
485
+ /* @__PURE__ */ a(z, {}),
486
+ /* @__PURE__ */ r("div", { children: [
487
+ /* @__PURE__ */ a("h2", { children: A }),
488
+ /* @__PURE__ */ r("p", { children: [
489
+ /* @__PURE__ */ a("span", { className: "make-ai-assistant__online-dot" }),
490
+ m ?? e.app.name ?? "当前应用"
491
+ ] })
492
+ ] }),
493
+ /* @__PURE__ */ r("div", { className: "make-ai-assistant__header-actions", children: [
494
+ /* @__PURE__ */ a(
495
+ "button",
496
+ {
497
+ "aria-label": "新建对话",
498
+ className: "make-ai-assistant__icon-button",
499
+ type: "button",
500
+ onClick: ue,
501
+ children: /* @__PURE__ */ a(xe, {})
502
+ }
503
+ ),
504
+ c ? /* @__PURE__ */ a(
505
+ "button",
506
+ {
507
+ "aria-label": "关闭 Make AI 助手",
508
+ className: "make-ai-assistant__icon-button",
509
+ type: "button",
510
+ onClick: c,
511
+ children: /* @__PURE__ */ a(Re, {})
512
+ }
513
+ ) : null
514
+ ] })
515
+ ] }),
516
+ /* @__PURE__ */ r("div", { className: "make-ai-assistant__privacy-note", role: "note", children: [
517
+ /* @__PURE__ */ a("span", { "aria-hidden": "true", children: "◇" }),
518
+ "当前页面上下文会随请求发送,数据权限以宿主服务端校验结果为准"
519
+ ] }),
520
+ /* @__PURE__ */ r(
521
+ "div",
522
+ {
523
+ className: "make-ai-assistant__body",
524
+ "aria-live": "polite",
525
+ ref: O,
526
+ onScroll: ce,
527
+ children: [
528
+ d.messages.length === 0 ? /* @__PURE__ */ r("div", { className: "make-ai-assistant__empty", children: [
529
+ /* @__PURE__ */ a(z, {}),
530
+ /* @__PURE__ */ a("h3", { children: "有什么可以帮你?" }),
531
+ /* @__PURE__ */ a("p", { children: "我会结合当前 App 和页面上下文理解问题,并用适合的方式展示结果。" })
532
+ ] }) : Ce(d, e, G, t, n),
533
+ d.error ? /* @__PURE__ */ r("div", { className: "make-ai-assistant__error", role: "alert", children: [
534
+ /* @__PURE__ */ a("strong", { children: "暂时无法完成" }),
535
+ /* @__PURE__ */ a("span", { children: d.error.message })
536
+ ] }) : null
537
+ ]
538
+ }
539
+ ),
540
+ /* @__PURE__ */ r("footer", { className: "make-ai-assistant__composer-region", children: [
541
+ u.length > 0 && d.messages.length === 0 ? /* @__PURE__ */ a("div", { className: "make-ai-assistant__suggestions", "aria-label": "推荐问题", children: u.map((o, _) => /* @__PURE__ */ a(
542
+ "button",
543
+ {
544
+ type: "button",
545
+ onClick: () => {
546
+ U(o);
547
+ },
548
+ children: o
549
+ },
550
+ `${_}-${o}`
551
+ )) }) : null,
552
+ /* @__PURE__ */ r("form", { className: "make-ai-assistant__composer", onSubmit: le, children: [
553
+ /* @__PURE__ */ a(
554
+ "textarea",
555
+ {
556
+ "aria-label": "向 Make AI 助手提问",
557
+ "aria-describedby": D ? "make-ai-composer-error" : void 0,
558
+ "aria-invalid": D ? !0 : void 0,
559
+ autoFocus: !0,
560
+ disabled: d.status === "streaming",
561
+ placeholder: `询问当前 ${e.app.name ?? "App"} 中的数据…`,
562
+ rows: 2,
563
+ value: v,
564
+ onChange: (o) => {
565
+ T(o.currentTarget.value), P(void 0);
566
+ },
567
+ onKeyDown: de
568
+ }
569
+ ),
570
+ d.status === "streaming" ? /* @__PURE__ */ a(
571
+ "button",
572
+ {
573
+ "aria-label": "停止生成",
574
+ className: "make-ai-assistant__send make-ai-assistant__send--stop",
575
+ type: "button",
576
+ onClick: me,
577
+ children: /* @__PURE__ */ a("span", { "aria-hidden": "true" })
578
+ }
579
+ ) : /* @__PURE__ */ a(
580
+ "button",
581
+ {
582
+ "aria-label": "发送",
583
+ className: "make-ai-assistant__send",
584
+ disabled: !v.trim(),
585
+ type: "submit",
586
+ children: /* @__PURE__ */ a(Se, {})
587
+ }
588
+ )
589
+ ] }),
590
+ D ? /* @__PURE__ */ a("p", { id: "make-ai-composer-error", role: "alert", children: D }) : null,
591
+ /* @__PURE__ */ a("p", { children: "AI 生成的结果可能存在偏差,重要数据请核对明细。" })
592
+ ] })
593
+ ] });
594
+ }
595
+ function He({
596
+ defaultOpen: e = !1,
597
+ hideLauncher: t = !1,
598
+ launcher: n,
599
+ onOpenChange: c,
600
+ open: i,
601
+ ...s
602
+ }) {
603
+ const [m, u] = L(e), A = S(null), h = i ?? m, v = (d) => {
604
+ i === void 0 && u(d), c?.(d), d || requestAnimationFrame(() => A.current?.focus());
605
+ }, T = () => v(!h);
606
+ return Y(() => {
607
+ if (!h) return;
608
+ const d = (y) => {
609
+ y.key === "Escape" && (v(!1), requestAnimationFrame(() => A.current?.focus()));
610
+ };
611
+ return document.addEventListener("keydown", d), () => document.removeEventListener("keydown", d);
612
+ }, [c, h]), /* @__PURE__ */ r("div", { className: "make-ai-assistant", "data-open": h || void 0, children: [
613
+ !t && (!h || n) ? n ? n({ open: h, toggle: T }) : /* @__PURE__ */ r(
614
+ "button",
615
+ {
616
+ "aria-label": h ? "关闭 Make AI 助手" : "打开 Make AI 助手",
617
+ "aria-expanded": h,
618
+ className: "make-ai-assistant__launcher",
619
+ ref: A,
620
+ type: "button",
621
+ onClick: T,
622
+ children: [
623
+ /* @__PURE__ */ a("span", { className: "make-ai-assistant__launcher-orbit", "aria-hidden": "true" }),
624
+ /* @__PURE__ */ a(oe, {})
625
+ ]
626
+ }
627
+ ) : null,
628
+ h ? /* @__PURE__ */ a(
629
+ "aside",
630
+ {
631
+ "aria-label": "Make AI 助手",
632
+ "aria-modal": "false",
633
+ className: "make-ai-assistant__drawer",
634
+ role: "dialog",
635
+ children: /* @__PURE__ */ a(Fe, { ...s, onClose: () => v(!1) })
636
+ }
637
+ ) : null
638
+ ] });
639
+ }
640
+ export {
641
+ ve as ArtifactRenderer,
642
+ Fe as AssistantPanel,
643
+ je as MAKE_AI_ARTIFACT_KINDS,
644
+ Ue as MAKE_AI_ARTIFACT_LIMITS,
645
+ Ye as MAKE_AI_ARTIFACT_SCHEMA_VERSION,
646
+ b as MAKE_AI_CONVERSATION_LIMITS,
647
+ He as MakeAiAssistant,
648
+ _e as appendUserMessage,
649
+ he as createArtifactCapabilities,
650
+ re as createArtifactTemplateRegistry,
651
+ ae as createAssistantConversationState,
652
+ Ee as createPlatformArtifactRegistry,
653
+ Oe as extendArtifactTemplateRegistry,
654
+ w as formatArtifactValue,
655
+ ze as parseArtifact,
656
+ ke as parseAssistantEvent,
657
+ Me as platformArtifactTemplates,
658
+ B as reduceAssistantEvent,
659
+ pe as resolveArtifactTemplate,
660
+ Ge as validateArtifact
661
+ };
package/dist/sse.cjs ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("./conversation-DpYszfVd.cjs"),S=1e6,u=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),p=(e,t,r)=>{const a=Object.keys(e).find(s=>s.toLowerCase()===t.toLowerCase());a&&delete e[a],e[t]=r},A=e=>{const t={};return Array.isArray(e)?e.forEach(([r,a])=>p(t,r,a)):e&&typeof e.forEach=="function"?e.forEach((r,a)=>p(t,a,r)):e&&Object.entries(e).forEach(([r,a])=>p(t,r,a)),p(t,"Accept","text/event-stream"),p(t,"Content-Type","application/json"),t},I=(e,t)=>{if(!u(t))throw new Error("Invalid assistant SSE event: data");if(Object.prototype.hasOwnProperty.call(t,"type"))throw new Error("Invalid assistant SSE event: unsupported field");try{return b.parseAssistantEvent({...t,type:e})}catch(r){throw r instanceof Error&&r.message.startsWith("Invalid assistant event")?new Error(r.message.replace("Invalid assistant event","Invalid assistant SSE event")):r}},w=e=>{if(!e.trim())return;const t=e.split(`
2
+ `),r=t.find(n=>n.startsWith("event:"))?.slice(6).trim(),a=t.filter(n=>n.startsWith("data:")).map(n=>n.slice(5).trimStart()).join(`
3
+ `);if(t.some(n=>n.startsWith("event:")||n.startsWith("data:"))){if(!r||!a)throw new Error("Invalid assistant SSE event: missing event or data");try{return I(r,JSON.parse(a))}catch(n){throw n instanceof Error&&n.message.startsWith("Invalid assistant SSE event")?n:new Error("Invalid assistant SSE event: JSON")}}};async function*T(e,t,r=S){if(!e.body)throw new Error("当前运行环境无法读取 AI 助手流式响应");const a=e.body.getReader(),s=new TextDecoder;let n="",d=!1,h=!1,l;const c=()=>(l??=a.cancel().catch(o=>{console.error("[make-ai-assistant] SSE reader cancellation failed",{errorType:o instanceof Error?o.name:typeof o})}),l),f=()=>{c()};t?.addEventListener("abort",f,{once:!0});const m=o=>{const i=o.type==="error"||o.type==="run.cancelled"||o.type==="run.complete";return h||=i,i};try{for(;;){if(t?.aborted)throw new DOMException("Aborted","AbortError");const o=await a.read();if(t?.aborted)throw new DOMException("Aborted","AbortError");let i=s.decode(o.value,{stream:!o.done});d&&(i=`\r${i}`,d=!1),!o.done&&i.endsWith("\r")&&(i=i.slice(0,-1),d=!0),o.done&&d&&(i+="\r",d=!1),n+=i.replace(/\r\n|\r/g,`
4
+ `);let E=n.indexOf(`
5
+
6
+ `);for(;E>=0;){if(E>r)throw new Error("AI 助手 SSE 事件超过大小限制");const y=w(n.slice(0,E));if(n=n.slice(E+2),y){const v=m(y);if(yield y,v)return}E=n.indexOf(`
7
+
8
+ `)}if(n.length>r)throw new Error("AI 助手 SSE 事件超过大小限制");if(o.done)break}if(n.trim()){const o=w(n);if(o){const i=m(o);if(yield o,i)return}}if(!h)throw new Error("AI 助手流式响应在终止事件前结束")}finally{t?.removeEventListener("abort",f),await c(),a.releaseLock()}}const g=e=>{const t=e.maxEventCharacters??S;if(!Number.isInteger(t)||t<=0)throw new Error("maxEventCharacters must be a positive integer");return{async*run(r,a){console.info("[make-ai-assistant] SSE run start",{appId:r.context.app.id});try{if(a?.signal?.aborted)throw new DOMException("Aborted","AbortError");let s;const n=e.fetch??globalThis.fetch,d=typeof e.endpoint=="function"?e.endpoint(r):e.endpoint,h=typeof e.headers=="function"?await e.headers():e.headers,l=await n(d,{method:"POST",body:JSON.stringify(r),credentials:e.credentials??"include",headers:A(h),signal:a?.signal});if(!l.ok){if(console.error("[make-ai-assistant] SSE run rejected",{appId:r.context.app.id,status:l.status}),l.body){const c=l.body.getReader();try{await c.cancel()}catch(f){console.error("[make-ai-assistant] SSE reader cancellation failed",{errorType:f instanceof Error?f.name:typeof f})}finally{c.releaseLock()}}throw new Error(`AI 助手请求失败 [${l.status}]`)}for await(const c of T(l,a?.signal,t))(c.type==="error"||c.type==="run.cancelled"||c.type==="run.complete")&&(s=c.type,console.info("[make-ai-assistant] SSE run terminal event",{appId:r.context.app.id,terminalType:s})),yield c}catch(s){throw a?.signal?.aborted?console.info("[make-ai-assistant] SSE run cancelled",{appId:r.context.app.id}):console.error("[make-ai-assistant] SSE run failed",{appId:r.context.app.id,errorType:s instanceof Error?s.name:typeof s}),s}}}};exports.DEFAULT_MAX_SSE_EVENT_CHARACTERS=S;exports.createSseAssistantTransport=g;
package/dist/sse.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./core/sse-transport.js";