@pactor-app/chat 1.15.6 → 1.17.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/README.md +8 -4
- package/dist/index.cjs +1303 -578
- package/dist/index.d.cts +205 -43
- package/dist/index.d.ts +205 -43
- package/dist/index.js +1236 -526
- package/package.json +6 -6
- package/styles.css +322 -29
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
ARTIFACT_IMAGE_EXTENSIONS: () => ARTIFACT_IMAGE_EXTENSIONS,
|
|
23
24
|
ActivityTrace: () => ActivityTrace,
|
|
24
25
|
AppShell: () => AppShell,
|
|
25
26
|
ArtifactPanel: () => ArtifactPanel,
|
|
@@ -29,6 +30,7 @@ __export(index_exports, {
|
|
|
29
30
|
CHAT_LAYOUT_TYPE: () => CHAT_LAYOUT_TYPE,
|
|
30
31
|
CHAT_SHELL_COMPONENT_TYPE: () => CHAT_SHELL_COMPONENT_TYPE,
|
|
31
32
|
Chat: () => Chat,
|
|
33
|
+
ChatArtifactCard: () => ChatArtifactCard,
|
|
32
34
|
ChatDenied: () => ChatDenied,
|
|
33
35
|
ChatLayout: () => ChatLayout,
|
|
34
36
|
ChatServicesProvider: () => ChatServicesProvider,
|
|
@@ -43,7 +45,11 @@ __export(index_exports, {
|
|
|
43
45
|
MessageBubble: () => MessageBubble,
|
|
44
46
|
PartRenderer: () => PartRenderer,
|
|
45
47
|
applyChatEvent: () => applyChatEvent,
|
|
48
|
+
artifactCardMeta: () => artifactCardMeta,
|
|
49
|
+
buildArtifactBlob: () => buildArtifactBlob,
|
|
50
|
+
buildArtifactTree: () => buildArtifactTree,
|
|
46
51
|
buildChatScope: () => buildChatScope,
|
|
52
|
+
collectArtifacts: () => collectArtifacts,
|
|
47
53
|
collectMessageText: () => collectMessageText,
|
|
48
54
|
createChatComponentRegistry: () => createChatComponentRegistry,
|
|
49
55
|
createChatId: () => createChatId,
|
|
@@ -52,14 +58,24 @@ __export(index_exports, {
|
|
|
52
58
|
createManualDriver: () => createManualDriver,
|
|
53
59
|
createSafeRegistry: () => createSafeRegistry,
|
|
54
60
|
detectStreamingMode: () => detectStreamingMode,
|
|
61
|
+
downloadArtifact: () => downloadArtifact,
|
|
62
|
+
formatArtifactSize: () => formatArtifactSize,
|
|
63
|
+
formatMessageTime: () => formatMessageTime,
|
|
55
64
|
guardChatDsl: () => guardChatDsl,
|
|
65
|
+
isImageArtifact: () => isImageArtifact,
|
|
66
|
+
mergeArtifacts: () => mergeArtifacts,
|
|
56
67
|
pairToolTraces: () => pairToolTraces,
|
|
57
68
|
registerCapabilityAction: () => registerCapabilityAction,
|
|
58
69
|
registerChatComponent: () => registerChatComponent,
|
|
59
70
|
registerChatLayout: () => registerChatLayout,
|
|
60
71
|
registerChatShellComponent: () => registerChatShellComponent,
|
|
72
|
+
resolveArtifactFileType: () => resolveArtifactFileType,
|
|
73
|
+
resolveArtifactFilename: () => resolveArtifactFilename,
|
|
74
|
+
resolveArtifactIcon: () => resolveArtifactIcon,
|
|
75
|
+
resolveArtifactIconName: () => resolveArtifactIconName,
|
|
61
76
|
runChatTurn: () => runChatTurn,
|
|
62
77
|
runRegenerateTurn: () => runRegenerateTurn,
|
|
78
|
+
saveBlob: () => saveBlob,
|
|
63
79
|
useChatAutoScroll: () => useChatAutoScroll,
|
|
64
80
|
useChatServices: () => useChatServices,
|
|
65
81
|
useSidebarDrawer: () => useSidebarDrawer,
|
|
@@ -187,35 +203,204 @@ var ConversationStore = class {
|
|
|
187
203
|
};
|
|
188
204
|
|
|
189
205
|
// src/artifact.ts
|
|
206
|
+
var ARTIFACT_IMAGE_EXTENSIONS = [
|
|
207
|
+
"png",
|
|
208
|
+
"jpg",
|
|
209
|
+
"jpeg",
|
|
210
|
+
"gif",
|
|
211
|
+
"svg",
|
|
212
|
+
"webp",
|
|
213
|
+
"avif",
|
|
214
|
+
"bmp",
|
|
215
|
+
"ico"
|
|
216
|
+
];
|
|
217
|
+
function resolveArtifactFileType(artifact) {
|
|
218
|
+
const declared = artifact.fileType?.trim().toLowerCase().replace(/^\./, "");
|
|
219
|
+
if (declared) {
|
|
220
|
+
return declared;
|
|
221
|
+
}
|
|
222
|
+
const match = /\.([A-Za-z0-9]+)$/.exec(artifact.title.trim());
|
|
223
|
+
return match ? match[1].toLowerCase() : null;
|
|
224
|
+
}
|
|
225
|
+
function isImageArtifact(artifact) {
|
|
226
|
+
const ext = resolveArtifactFileType(artifact);
|
|
227
|
+
return ext !== null && ARTIFACT_IMAGE_EXTENSIONS.includes(ext);
|
|
228
|
+
}
|
|
229
|
+
var ARTIFACT_ICON_BY_EXTENSION = {
|
|
230
|
+
// 表格数据(绿)
|
|
231
|
+
csv: { name: "table", tone: "green" },
|
|
232
|
+
tsv: { name: "table", tone: "green" },
|
|
233
|
+
xls: { name: "table", tone: "green" },
|
|
234
|
+
xlsx: { name: "table", tone: "green" },
|
|
235
|
+
// 数据 / 数据库(琥珀)
|
|
236
|
+
json: { name: "database", tone: "amber" },
|
|
237
|
+
sql: { name: "database", tone: "amber" },
|
|
238
|
+
// 脚本(蓝,终端图标)
|
|
239
|
+
sh: { name: "terminal", tone: "blue" },
|
|
240
|
+
bash: { name: "terminal", tone: "blue" },
|
|
241
|
+
zsh: { name: "terminal", tone: "blue" },
|
|
242
|
+
// 代码 / 配置(蓝)
|
|
243
|
+
js: { name: "code", tone: "blue" },
|
|
244
|
+
mjs: { name: "code", tone: "blue" },
|
|
245
|
+
cjs: { name: "code", tone: "blue" },
|
|
246
|
+
jsx: { name: "code", tone: "blue" },
|
|
247
|
+
ts: { name: "code", tone: "blue" },
|
|
248
|
+
mts: { name: "code", tone: "blue" },
|
|
249
|
+
cts: { name: "code", tone: "blue" },
|
|
250
|
+
tsx: { name: "code", tone: "blue" },
|
|
251
|
+
py: { name: "code", tone: "blue" },
|
|
252
|
+
rb: { name: "code", tone: "blue" },
|
|
253
|
+
go: { name: "code", tone: "blue" },
|
|
254
|
+
rs: { name: "code", tone: "blue" },
|
|
255
|
+
java: { name: "code", tone: "blue" },
|
|
256
|
+
kt: { name: "code", tone: "blue" },
|
|
257
|
+
c: { name: "code", tone: "blue" },
|
|
258
|
+
h: { name: "code", tone: "blue" },
|
|
259
|
+
cc: { name: "code", tone: "blue" },
|
|
260
|
+
cpp: { name: "code", tone: "blue" },
|
|
261
|
+
cs: { name: "code", tone: "blue" },
|
|
262
|
+
swift: { name: "code", tone: "blue" },
|
|
263
|
+
php: { name: "code", tone: "blue" },
|
|
264
|
+
css: { name: "code", tone: "blue" },
|
|
265
|
+
scss: { name: "code", tone: "blue" },
|
|
266
|
+
less: { name: "code", tone: "blue" },
|
|
267
|
+
html: { name: "code", tone: "blue" },
|
|
268
|
+
vue: { name: "code", tone: "blue" },
|
|
269
|
+
svelte: { name: "code", tone: "blue" },
|
|
270
|
+
yaml: { name: "code", tone: "blue" },
|
|
271
|
+
yml: { name: "code", tone: "blue" },
|
|
272
|
+
toml: { name: "code", tone: "blue" },
|
|
273
|
+
xml: { name: "code", tone: "blue" },
|
|
274
|
+
// 文档 / 文本(石板灰)
|
|
275
|
+
md: { name: "file-text", tone: "slate" },
|
|
276
|
+
markdown: { name: "file-text", tone: "slate" },
|
|
277
|
+
mdx: { name: "file-text", tone: "slate" },
|
|
278
|
+
txt: { name: "file-text", tone: "slate" },
|
|
279
|
+
text: { name: "file-text", tone: "slate" },
|
|
280
|
+
log: { name: "file-text", tone: "slate" },
|
|
281
|
+
rst: { name: "file-text", tone: "slate" },
|
|
282
|
+
pdf: { name: "file-text", tone: "slate" },
|
|
283
|
+
doc: { name: "file-text", tone: "slate" },
|
|
284
|
+
docx: { name: "file-text", tone: "slate" }
|
|
285
|
+
};
|
|
286
|
+
function resolveArtifactIcon(artifact) {
|
|
287
|
+
const ext = resolveArtifactFileType(artifact);
|
|
288
|
+
if (ext !== null) {
|
|
289
|
+
if (ARTIFACT_IMAGE_EXTENSIONS.includes(ext)) {
|
|
290
|
+
return { name: "image", tone: "violet" };
|
|
291
|
+
}
|
|
292
|
+
const spec = ARTIFACT_ICON_BY_EXTENSION[ext];
|
|
293
|
+
if (spec !== void 0) {
|
|
294
|
+
return spec;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (artifact.kind === "code") {
|
|
298
|
+
return { name: "code", tone: "blue" };
|
|
299
|
+
}
|
|
300
|
+
if (artifact.kind === "dsl") {
|
|
301
|
+
return { name: "layout-grid", tone: "slate" };
|
|
302
|
+
}
|
|
303
|
+
return ext === null ? { name: "file-text", tone: "slate" } : { name: "file", tone: "slate" };
|
|
304
|
+
}
|
|
305
|
+
function resolveArtifactIconName(artifact) {
|
|
306
|
+
return resolveArtifactIcon(artifact).name;
|
|
307
|
+
}
|
|
308
|
+
function formatArtifactSize(size) {
|
|
309
|
+
if (typeof size !== "number" || !Number.isFinite(size) || size < 0) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
if (size < 1024) {
|
|
313
|
+
return `${size} B`;
|
|
314
|
+
}
|
|
315
|
+
if (size < 1024 * 1024) {
|
|
316
|
+
return `${(size / 1024).toFixed(1)} KB`;
|
|
317
|
+
}
|
|
318
|
+
return `${(size / 1024 / 1024).toFixed(1)} MB`;
|
|
319
|
+
}
|
|
320
|
+
function collectArtifacts(messages) {
|
|
321
|
+
const order = [];
|
|
322
|
+
const byId = /* @__PURE__ */ new Map();
|
|
323
|
+
for (const message of messages) {
|
|
324
|
+
for (const part of message.parts) {
|
|
325
|
+
if (part.type !== "artifact" || !part.artifact) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (part.status !== void 0 && part.status !== "ready") {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (!byId.has(part.artifact.id)) {
|
|
332
|
+
order.push(part.artifact.id);
|
|
333
|
+
}
|
|
334
|
+
byId.set(part.artifact.id, part.artifact);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return order.map((id) => byId.get(id));
|
|
338
|
+
}
|
|
339
|
+
function mergeArtifacts(stream, opened) {
|
|
340
|
+
const openedById = new Map(opened.map((item) => [item.id, item]));
|
|
341
|
+
const merged = stream.map((item) => openedById.get(item.id) ?? item);
|
|
342
|
+
for (const item of opened) {
|
|
343
|
+
if (!stream.some((s) => s.id === item.id)) {
|
|
344
|
+
merged.push(item);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return merged;
|
|
348
|
+
}
|
|
190
349
|
var ArtifactStore = class {
|
|
191
350
|
constructor() {
|
|
192
|
-
this.
|
|
351
|
+
this.artifacts = [];
|
|
352
|
+
this.activeId = null;
|
|
193
353
|
this.listeners = /* @__PURE__ */ new Set();
|
|
194
354
|
}
|
|
195
|
-
/**
|
|
355
|
+
/** 当前激活产出物(未打开时为 null;引用在不变时保持稳定) */
|
|
196
356
|
get() {
|
|
197
|
-
|
|
357
|
+
if (this.activeId === null) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
return this.artifacts.find((item) => item.id === this.activeId) ?? null;
|
|
198
361
|
}
|
|
199
|
-
/**
|
|
362
|
+
/** 全部产出物(插入序;数组不可变,引用稳定) */
|
|
363
|
+
list() {
|
|
364
|
+
return this.artifacts;
|
|
365
|
+
}
|
|
366
|
+
/** 打开(或按 id 替换)产出物并激活 */
|
|
200
367
|
open(artifact) {
|
|
201
|
-
this.
|
|
368
|
+
const index = this.artifacts.findIndex((item) => item.id === artifact.id);
|
|
369
|
+
this.artifacts = index === -1 ? [...this.artifacts, artifact] : this.artifacts.map((item, i) => i === index ? artifact : item);
|
|
370
|
+
this.activeId = artifact.id;
|
|
371
|
+
this.notify();
|
|
372
|
+
}
|
|
373
|
+
/** 切换激活项(未知 id 告警并忽略,不抛错) */
|
|
374
|
+
activate(id) {
|
|
375
|
+
if (this.activeId === id) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (!this.artifacts.some((item) => item.id === id)) {
|
|
379
|
+
console.warn("[@pactor-app/chat] unknown artifact id, activate ignored");
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
this.activeId = id;
|
|
202
383
|
this.notify();
|
|
203
384
|
}
|
|
204
|
-
/**
|
|
385
|
+
/** 部分更新当前激活产出物(id 不可改);未 open 时告警并忽略 */
|
|
205
386
|
update(patch) {
|
|
206
|
-
|
|
387
|
+
const current = this.get();
|
|
388
|
+
if (!current) {
|
|
207
389
|
console.warn("[@pactor-app/chat] artifact not open, update ignored");
|
|
208
390
|
return;
|
|
209
391
|
}
|
|
210
|
-
|
|
392
|
+
const next = { ...current, ...patch, id: current.id };
|
|
393
|
+
this.artifacts = this.artifacts.map(
|
|
394
|
+
(item) => item.id === current.id ? next : item
|
|
395
|
+
);
|
|
211
396
|
this.notify();
|
|
212
397
|
}
|
|
213
|
-
/**
|
|
398
|
+
/** 关闭面板:清空激活项,列表保留(未打开时幂等,不重复通知) */
|
|
214
399
|
close() {
|
|
215
|
-
if (this.
|
|
400
|
+
if (this.activeId === null) {
|
|
216
401
|
return;
|
|
217
402
|
}
|
|
218
|
-
this.
|
|
403
|
+
this.activeId = null;
|
|
219
404
|
this.notify();
|
|
220
405
|
}
|
|
221
406
|
/** 订阅变更;返回退订函数 */
|
|
@@ -232,6 +417,94 @@ var ArtifactStore = class {
|
|
|
232
417
|
}
|
|
233
418
|
};
|
|
234
419
|
|
|
420
|
+
// src/artifact-download.ts
|
|
421
|
+
var KIND_EXTENSIONS = {
|
|
422
|
+
markdown: "md",
|
|
423
|
+
text: "txt",
|
|
424
|
+
code: "txt",
|
|
425
|
+
dsl: "json"
|
|
426
|
+
};
|
|
427
|
+
function resolveArtifactFilename(artifact) {
|
|
428
|
+
const title = artifact.title.trim() || "artifact";
|
|
429
|
+
if (/\.[A-Za-z0-9]+$/.test(title)) {
|
|
430
|
+
return title;
|
|
431
|
+
}
|
|
432
|
+
const ext = resolveArtifactFileType(artifact) ?? KIND_EXTENSIONS[artifact.kind];
|
|
433
|
+
return `${title}.${ext}`;
|
|
434
|
+
}
|
|
435
|
+
function dataUrlToBlob(dataUrl) {
|
|
436
|
+
const comma = dataUrl.indexOf(",");
|
|
437
|
+
const meta = dataUrl.slice(0, comma);
|
|
438
|
+
const payload = dataUrl.slice(comma + 1);
|
|
439
|
+
const mime = /^data:([^;,]+)/.exec(meta)?.[1] ?? "application/octet-stream";
|
|
440
|
+
if (meta.includes(";base64")) {
|
|
441
|
+
const binary = atob(payload);
|
|
442
|
+
const bytes = new Uint8Array(binary.length);
|
|
443
|
+
for (let i = 0; i < binary.length; i++) {
|
|
444
|
+
bytes[i] = binary.charCodeAt(i);
|
|
445
|
+
}
|
|
446
|
+
return new Blob([bytes], { type: mime });
|
|
447
|
+
}
|
|
448
|
+
return new Blob([decodeURIComponent(payload)], { type: mime });
|
|
449
|
+
}
|
|
450
|
+
function isRemoteUrl(raw) {
|
|
451
|
+
return /^https?:\/\//.test(raw.trim());
|
|
452
|
+
}
|
|
453
|
+
function buildArtifactBlob(artifact) {
|
|
454
|
+
if (artifact.kind === "dsl" && typeof artifact.content === "object") {
|
|
455
|
+
return new Blob([JSON.stringify(artifact.content, null, 2)], {
|
|
456
|
+
type: "application/json"
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
const raw = String(artifact.content);
|
|
460
|
+
if (isImageArtifact(artifact)) {
|
|
461
|
+
const trimmed = raw.trim();
|
|
462
|
+
if (trimmed.startsWith("data:")) {
|
|
463
|
+
return dataUrlToBlob(trimmed);
|
|
464
|
+
}
|
|
465
|
+
if (trimmed.startsWith("<svg") || trimmed.startsWith("<?xml")) {
|
|
466
|
+
return new Blob([raw], { type: "image/svg+xml" });
|
|
467
|
+
}
|
|
468
|
+
if (isRemoteUrl(trimmed)) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const ext = resolveArtifactFileType(artifact);
|
|
473
|
+
const mime = ext === "md" || artifact.kind === "markdown" ? "text/markdown" : "text/plain";
|
|
474
|
+
return new Blob([raw], { type: `${mime};charset=utf-8` });
|
|
475
|
+
}
|
|
476
|
+
function saveBlob(blob, filename) {
|
|
477
|
+
const url = URL.createObjectURL(blob);
|
|
478
|
+
const anchor = document.createElement("a");
|
|
479
|
+
anchor.href = url;
|
|
480
|
+
anchor.download = filename;
|
|
481
|
+
document.body.appendChild(anchor);
|
|
482
|
+
anchor.click();
|
|
483
|
+
anchor.remove();
|
|
484
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
485
|
+
}
|
|
486
|
+
async function downloadArtifact(artifact) {
|
|
487
|
+
const filename = resolveArtifactFilename(artifact);
|
|
488
|
+
const raw = String(artifact.content ?? "").trim();
|
|
489
|
+
if (isImageArtifact(artifact) && isRemoteUrl(raw)) {
|
|
490
|
+
try {
|
|
491
|
+
const response = await fetch(raw);
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
throw new Error(`HTTP ${response.status}`);
|
|
494
|
+
}
|
|
495
|
+
saveBlob(await response.blob(), filename);
|
|
496
|
+
return;
|
|
497
|
+
} catch {
|
|
498
|
+
window.open(raw, "_blank", "noopener");
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
const blob = buildArtifactBlob(artifact);
|
|
503
|
+
if (blob) {
|
|
504
|
+
saveBlob(blob, filename);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
235
508
|
// src/events.ts
|
|
236
509
|
function applyChatEvent(store, event) {
|
|
237
510
|
switch (event.type) {
|
|
@@ -868,7 +1141,7 @@ function useChatAutoScroll({
|
|
|
868
1141
|
|
|
869
1142
|
// src/chat-composition.tsx
|
|
870
1143
|
var import_runtime5 = require("@pactor-app/runtime");
|
|
871
|
-
var
|
|
1144
|
+
var import_react19 = require("react");
|
|
872
1145
|
|
|
873
1146
|
// src/hooks/use-chat-model.ts
|
|
874
1147
|
var import_react3 = require("react");
|
|
@@ -922,14 +1195,14 @@ function AppShell({
|
|
|
922
1195
|
}
|
|
923
1196
|
|
|
924
1197
|
// src/view/ArtifactPanel.tsx
|
|
925
|
-
var
|
|
1198
|
+
var import_components5 = require("@pactor-app/ui/components");
|
|
926
1199
|
var import_core3 = require("@pactor-app/core");
|
|
927
1200
|
var import_markdown2 = require("@pactor-app/markdown");
|
|
928
1201
|
var import_runtime4 = require("@pactor-app/runtime");
|
|
929
|
-
var
|
|
1202
|
+
var import_react8 = require("react");
|
|
930
1203
|
|
|
931
1204
|
// src/view/PartRenderer.tsx
|
|
932
|
-
var
|
|
1205
|
+
var import_components3 = require("@pactor-app/ui/components");
|
|
933
1206
|
var import_markdown = require("@pactor-app/markdown");
|
|
934
1207
|
var import_runtime3 = require("@pactor-app/runtime");
|
|
935
1208
|
|
|
@@ -971,59 +1244,7 @@ function useThrottledValue(value, intervalMs, enabled) {
|
|
|
971
1244
|
}
|
|
972
1245
|
|
|
973
1246
|
// src/view/chrome/artifact-card.tsx
|
|
974
|
-
|
|
975
|
-
return {
|
|
976
|
-
requires: ["Card", "Flex", "Text", "Badge", "Button"],
|
|
977
|
-
node: {
|
|
978
|
-
type: "Card",
|
|
979
|
-
props: { className: "pactor-chat-artifact-card" },
|
|
980
|
-
children: [
|
|
981
|
-
{
|
|
982
|
-
type: "Flex",
|
|
983
|
-
props: { justify: "space-between", align: "center", gap: "small" },
|
|
984
|
-
children: [
|
|
985
|
-
{
|
|
986
|
-
type: "Text",
|
|
987
|
-
props: {
|
|
988
|
-
text: artifact.title,
|
|
989
|
-
strong: true,
|
|
990
|
-
className: "pactor-chat-artifact-card__title"
|
|
991
|
-
}
|
|
992
|
-
},
|
|
993
|
-
{
|
|
994
|
-
type: "Badge",
|
|
995
|
-
props: {
|
|
996
|
-
text: artifact.kind,
|
|
997
|
-
variant: "secondary",
|
|
998
|
-
className: "pactor-chat-artifact-card__kind"
|
|
999
|
-
}
|
|
1000
|
-
},
|
|
1001
|
-
{
|
|
1002
|
-
type: "Button",
|
|
1003
|
-
props: {
|
|
1004
|
-
text: "\u5728\u9762\u677F\u4E2D\u6253\u5F00",
|
|
1005
|
-
variant: "default",
|
|
1006
|
-
size: "small",
|
|
1007
|
-
className: "pactor-chat-artifact-card__open"
|
|
1008
|
-
},
|
|
1009
|
-
events: {
|
|
1010
|
-
onClick: [
|
|
1011
|
-
{
|
|
1012
|
-
action: "chat.openArtifact",
|
|
1013
|
-
params: { artifact }
|
|
1014
|
-
}
|
|
1015
|
-
]
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
]
|
|
1019
|
-
}
|
|
1020
|
-
]
|
|
1021
|
-
}
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
// src/view/chrome/ChromeSlot.tsx
|
|
1026
|
-
var import_runtime2 = require("@pactor-app/runtime");
|
|
1247
|
+
var import_components2 = require("@pactor-app/ui/components");
|
|
1027
1248
|
var import_react5 = require("react");
|
|
1028
1249
|
|
|
1029
1250
|
// src/view/chrome/actions.ts
|
|
@@ -1104,9 +1325,125 @@ function ensureChatChromeActions(actions) {
|
|
|
1104
1325
|
function invokeChatPanelClose() {
|
|
1105
1326
|
handlers.panelClose?.();
|
|
1106
1327
|
}
|
|
1328
|
+
function invokeChatOpenArtifact(artifact) {
|
|
1329
|
+
handlers.openArtifact?.(artifact);
|
|
1330
|
+
}
|
|
1331
|
+
function invokeChatOpenArtifactList() {
|
|
1332
|
+
handlers.openArtifactList?.();
|
|
1333
|
+
}
|
|
1334
|
+
function invokeChatPanelToggleList() {
|
|
1335
|
+
handlers.panelToggleList?.();
|
|
1336
|
+
}
|
|
1337
|
+
function invokeChatPanelDownload() {
|
|
1338
|
+
handlers.panelDownload?.();
|
|
1339
|
+
}
|
|
1107
1340
|
|
|
1108
|
-
// src/view/chrome/
|
|
1341
|
+
// src/view/chrome/artifact-card.tsx
|
|
1109
1342
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1343
|
+
function artifactCardMeta(artifact) {
|
|
1344
|
+
const ext = resolveArtifactFileType(artifact);
|
|
1345
|
+
const typeLabel = (ext ?? artifact.kind).toUpperCase();
|
|
1346
|
+
const sizeLabel = formatArtifactSize(artifact.meta?.["size"]);
|
|
1347
|
+
return [sizeLabel, typeLabel].filter(Boolean).join(" \xB7 ");
|
|
1348
|
+
}
|
|
1349
|
+
function ChatArtifactCard({
|
|
1350
|
+
artifact
|
|
1351
|
+
}) {
|
|
1352
|
+
const icon = resolveArtifactIcon(artifact);
|
|
1353
|
+
const meta = artifactCardMeta(artifact);
|
|
1354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1355
|
+
"button",
|
|
1356
|
+
{
|
|
1357
|
+
type: "button",
|
|
1358
|
+
className: `pactor-chat-artifact-card pactor-chat-artifact-card--${icon.tone}`,
|
|
1359
|
+
"data-artifact-kind": artifact.kind,
|
|
1360
|
+
"aria-label": `\u5728\u9762\u677F\u4E2D\u6253\u5F00\uFF1A${artifact.title}`,
|
|
1361
|
+
title: `\u5728\u9762\u677F\u4E2D\u6253\u5F00\uFF1A${artifact.title}`,
|
|
1362
|
+
onClick: () => invokeChatOpenArtifact(artifact),
|
|
1363
|
+
children: [
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "pactor-chat-artifact-card__icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.Icon, { name: icon.name, size: 20 }) }),
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "pactor-chat-artifact-card__text", children: [
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "pactor-chat-artifact-card__title", children: artifact.title }),
|
|
1367
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "pactor-chat-artifact-card__meta", children: meta }) : null
|
|
1368
|
+
] }),
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "pactor-chat-artifact-card__arrow", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.Icon, { name: "arrow-up-right", size: 14 }) })
|
|
1370
|
+
]
|
|
1371
|
+
}
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
var ARTIFACT_CARD_INTERNAL_COMPONENTS = {
|
|
1375
|
+
ChatArtifactCard,
|
|
1376
|
+
ChatArtifactCardGroup
|
|
1377
|
+
};
|
|
1378
|
+
var ARTIFACT_CARD_GROUP_LIMIT = 4;
|
|
1379
|
+
function ChatArtifactCardGroup({
|
|
1380
|
+
artifacts
|
|
1381
|
+
}) {
|
|
1382
|
+
const [expanded, setExpanded] = (0, import_react5.useState)(false);
|
|
1383
|
+
const overflow = artifacts.length > ARTIFACT_CARD_GROUP_LIMIT;
|
|
1384
|
+
const visible = overflow && !expanded ? artifacts.slice(0, ARTIFACT_CARD_GROUP_LIMIT) : artifacts;
|
|
1385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "pactor-chat-artifact-group", children: [
|
|
1386
|
+
visible.map((artifact) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatArtifactCard, { artifact }, artifact.id)),
|
|
1387
|
+
overflow ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "pactor-chat-artifact-group__footer", children: [
|
|
1388
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1389
|
+
"button",
|
|
1390
|
+
{
|
|
1391
|
+
type: "button",
|
|
1392
|
+
className: "pactor-chat-artifact-group__toggle",
|
|
1393
|
+
"aria-expanded": expanded,
|
|
1394
|
+
onClick: () => setExpanded((value) => !value),
|
|
1395
|
+
children: [
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1397
|
+
import_components2.Icon,
|
|
1398
|
+
{
|
|
1399
|
+
name: expanded ? "chevron-up" : "chevron-down",
|
|
1400
|
+
size: 12
|
|
1401
|
+
}
|
|
1402
|
+
),
|
|
1403
|
+
expanded ? "\u6536\u8D77" : "\u5C55\u5F00"
|
|
1404
|
+
]
|
|
1405
|
+
}
|
|
1406
|
+
),
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1408
|
+
"button",
|
|
1409
|
+
{
|
|
1410
|
+
type: "button",
|
|
1411
|
+
className: "pactor-chat-artifact-group__all",
|
|
1412
|
+
onClick: () => invokeChatOpenArtifactList(),
|
|
1413
|
+
children: [
|
|
1414
|
+
"\u67E5\u770B\u6240\u6709\u4EA7\u7269(",
|
|
1415
|
+
artifacts.length,
|
|
1416
|
+
")",
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.Icon, { name: "chevron-right", size: 12 })
|
|
1418
|
+
]
|
|
1419
|
+
}
|
|
1420
|
+
)
|
|
1421
|
+
] }) : null
|
|
1422
|
+
] });
|
|
1423
|
+
}
|
|
1424
|
+
function buildArtifactCardFragment(artifact) {
|
|
1425
|
+
return {
|
|
1426
|
+
requires: ["ChatArtifactCard"],
|
|
1427
|
+
node: {
|
|
1428
|
+
type: "ChatArtifactCard",
|
|
1429
|
+
props: { artifact }
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
function buildArtifactCardGroupFragment(artifacts) {
|
|
1434
|
+
return {
|
|
1435
|
+
requires: ["ChatArtifactCardGroup"],
|
|
1436
|
+
node: {
|
|
1437
|
+
type: "ChatArtifactCardGroup",
|
|
1438
|
+
props: { artifacts }
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// src/view/chrome/ChromeSlot.tsx
|
|
1444
|
+
var import_runtime2 = require("@pactor-app/runtime");
|
|
1445
|
+
var import_react6 = require("react");
|
|
1446
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1110
1447
|
var warnedMissing = /* @__PURE__ */ new Set();
|
|
1111
1448
|
function warnMissingOnce(key, detail) {
|
|
1112
1449
|
if (!warnedMissing.has(key)) {
|
|
@@ -1124,7 +1461,7 @@ function ChromeSlotInner({
|
|
|
1124
1461
|
try {
|
|
1125
1462
|
renderer = (0, import_runtime2.useRenderer)();
|
|
1126
1463
|
} catch {
|
|
1127
|
-
return /* @__PURE__ */ (0,
|
|
1464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: fallback });
|
|
1128
1465
|
}
|
|
1129
1466
|
ensureChatChromeActions(renderer.context.actions);
|
|
1130
1467
|
if (components) {
|
|
@@ -1135,7 +1472,7 @@ function ChromeSlotInner({
|
|
|
1135
1472
|
`conflict:${name}`,
|
|
1136
1473
|
`[@pactor-app/chat] chrome \u5185\u90E8\u7EC4\u4EF6\u540D\u300C${name}\u300D\u88AB\u5BBF\u4E3B\u5360\u7528\uFF0C\u5DF2\u56DE\u9000\u5185\u5EFA\u5B9E\u73B0`
|
|
1137
1474
|
);
|
|
1138
|
-
return /* @__PURE__ */ (0,
|
|
1475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: fallback });
|
|
1139
1476
|
}
|
|
1140
1477
|
if (existing === void 0) {
|
|
1141
1478
|
renderer.context.components.register(
|
|
@@ -1153,12 +1490,12 @@ function ChromeSlotInner({
|
|
|
1153
1490
|
`${fragment.node.type}:${missing.join(",")}`,
|
|
1154
1491
|
`[@pactor-app/chat] chrome DSL \u7247\u6BB5\u6240\u9700\u7EC4\u4EF6\u7C7B\u578B\u7F3A\u5931\uFF08${missing.join(" / ")}\uFF09\uFF0C\u5DF2\u56DE\u9000\u5185\u5EFA\u5B9E\u73B0`
|
|
1155
1492
|
);
|
|
1156
|
-
return /* @__PURE__ */ (0,
|
|
1493
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: fallback });
|
|
1157
1494
|
}
|
|
1158
|
-
const rendered = /* @__PURE__ */ (0,
|
|
1159
|
-
return wrap ? /* @__PURE__ */ (0,
|
|
1495
|
+
const rendered = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pactor-chat-chrome", children: renderer.renderChildren([fragment.node]) });
|
|
1496
|
+
return wrap ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: wrap(rendered) }) : rendered;
|
|
1160
1497
|
}
|
|
1161
|
-
var ChromeSlotGuard = class extends
|
|
1498
|
+
var ChromeSlotGuard = class extends import_react6.Component {
|
|
1162
1499
|
constructor() {
|
|
1163
1500
|
super(...arguments);
|
|
1164
1501
|
this.state = { failed: false };
|
|
@@ -1171,7 +1508,7 @@ var ChromeSlotGuard = class extends import_react5.Component {
|
|
|
1171
1508
|
}
|
|
1172
1509
|
};
|
|
1173
1510
|
function ChromeSlot(props) {
|
|
1174
|
-
return /* @__PURE__ */ (0,
|
|
1511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChromeSlotGuard, { fallback: props.fallback, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChromeSlotInner, { ...props }) });
|
|
1175
1512
|
}
|
|
1176
1513
|
|
|
1177
1514
|
// src/view/chrome/feedback.tsx
|
|
@@ -1195,9 +1532,9 @@ function buildStatusFragment(text) {
|
|
|
1195
1532
|
}
|
|
1196
1533
|
|
|
1197
1534
|
// src/view/PartRenderer.tsx
|
|
1198
|
-
var
|
|
1535
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1199
1536
|
function ChatDenied({ deniedType }) {
|
|
1200
|
-
return /* @__PURE__ */ (0,
|
|
1537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "pactor-chat-denied", "data-pactor-chat-denied": deniedType, children: [
|
|
1201
1538
|
"\u8BE5\u7EC4\u4EF6\u4E0D\u5141\u8BB8\u5728 Chat \u4E2D\u4F7F\u7528",
|
|
1202
1539
|
deniedType ? `\uFF1A${deniedType}` : ""
|
|
1203
1540
|
] });
|
|
@@ -1208,89 +1545,68 @@ function ChatDslNode({
|
|
|
1208
1545
|
}) {
|
|
1209
1546
|
const renderer = (0, import_runtime3.useRenderer)();
|
|
1210
1547
|
const extraScope = scope ? buildChatScope(scope) : void 0;
|
|
1211
|
-
return /* @__PURE__ */ (0,
|
|
1548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: renderer.renderChildren([node], extraScope) });
|
|
1212
1549
|
}
|
|
1213
1550
|
function SmoothText({ content, streaming }) {
|
|
1214
1551
|
const shown = useSmoothStreamText(content, streaming);
|
|
1215
|
-
return /* @__PURE__ */ (0,
|
|
1552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pactor-chat-text", children: shown });
|
|
1216
1553
|
}
|
|
1217
1554
|
function SmoothMarkdown({ content, streaming }) {
|
|
1218
1555
|
const shown = useSmoothStreamText(content, streaming);
|
|
1219
1556
|
const throttled = useThrottledValue(shown, 100, streaming);
|
|
1220
|
-
return /* @__PURE__ */ (0,
|
|
1557
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_markdown.MarkdownRenderer, { content: throttled });
|
|
1221
1558
|
}
|
|
1222
|
-
function PartRenderer({ part, runtime, scope, streaming = false
|
|
1559
|
+
function PartRenderer({ part, runtime, scope, streaming = false }) {
|
|
1223
1560
|
switch (part.type) {
|
|
1224
1561
|
case "text":
|
|
1225
|
-
return /* @__PURE__ */ (0,
|
|
1562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SmoothText, { content: part.content, streaming });
|
|
1226
1563
|
case "markdown":
|
|
1227
|
-
return /* @__PURE__ */ (0,
|
|
1564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SmoothMarkdown, { content: part.content, streaming });
|
|
1228
1565
|
case "thinking":
|
|
1229
1566
|
case "tool-call":
|
|
1230
1567
|
case "tool-result":
|
|
1231
1568
|
return null;
|
|
1232
1569
|
case "dsl": {
|
|
1233
1570
|
if (!part.schema || !runtime) {
|
|
1234
|
-
return /* @__PURE__ */ (0,
|
|
1571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1235
1572
|
ChromeSlot,
|
|
1236
1573
|
{
|
|
1237
1574
|
fragment: buildStatusFragment(
|
|
1238
1575
|
part.schema ? "DSL \u6E32\u67D3\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "\u5185\u5BB9\u751F\u6210\u4E2D\u2026"
|
|
1239
1576
|
),
|
|
1240
|
-
fallback: /* @__PURE__ */ (0,
|
|
1577
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pactor-chat-dsl-pending", children: part.schema ? "DSL \u6E32\u67D3\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "\u5185\u5BB9\u751F\u6210\u4E2D\u2026" })
|
|
1241
1578
|
}
|
|
1242
1579
|
);
|
|
1243
1580
|
}
|
|
1244
1581
|
const guarded = guardChatDsl(part.schema, runtime.context.components);
|
|
1245
|
-
return /* @__PURE__ */ (0,
|
|
1582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pactor-chat-dsl", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_runtime3.DslRenderer, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatDslNode, { node: guarded, scope }) }) });
|
|
1246
1583
|
}
|
|
1247
1584
|
case "error":
|
|
1248
|
-
return /* @__PURE__ */ (0,
|
|
1585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1249
1586
|
ChromeSlot,
|
|
1250
1587
|
{
|
|
1251
1588
|
fragment: buildErrorFragment(part.message),
|
|
1252
|
-
fallback: /* @__PURE__ */ (0,
|
|
1253
|
-
/* @__PURE__ */ (0,
|
|
1254
|
-
/* @__PURE__ */ (0,
|
|
1589
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "pactor-chat-error", role: "alert", children: [
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_components3.Icon, { name: "error", size: 14 }),
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: part.message })
|
|
1255
1592
|
] })
|
|
1256
1593
|
}
|
|
1257
1594
|
);
|
|
1258
1595
|
case "status":
|
|
1259
|
-
return /* @__PURE__ */ (0,
|
|
1596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1260
1597
|
ChromeSlot,
|
|
1261
1598
|
{
|
|
1262
1599
|
fragment: buildStatusFragment(part.text),
|
|
1263
|
-
fallback: /* @__PURE__ */ (0,
|
|
1600
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pactor-chat-status", children: part.text })
|
|
1264
1601
|
}
|
|
1265
1602
|
);
|
|
1266
1603
|
case "artifact":
|
|
1267
|
-
return /* @__PURE__ */ (0,
|
|
1604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1268
1605
|
ChromeSlot,
|
|
1269
1606
|
{
|
|
1270
1607
|
fragment: buildArtifactCardFragment(part.artifact),
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
{
|
|
1274
|
-
className: "pactor-chat-artifact-card",
|
|
1275
|
-
"data-artifact-kind": part.artifact.kind,
|
|
1276
|
-
children: [
|
|
1277
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pactor-chat-artifact-card__title", children: part.artifact.title }),
|
|
1278
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pactor-chat-artifact-card__kind", children: part.artifact.kind }),
|
|
1279
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1280
|
-
"button",
|
|
1281
|
-
{
|
|
1282
|
-
type: "button",
|
|
1283
|
-
className: "pactor-chat-artifact-card__open",
|
|
1284
|
-
onClick: () => onOpenArtifact?.(part.artifact),
|
|
1285
|
-
children: [
|
|
1286
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.Icon, { name: "panel-right-open", size: 13, strokeWidth: 1.7 }),
|
|
1287
|
-
"\u5728\u9762\u677F\u4E2D\u6253\u5F00"
|
|
1288
|
-
]
|
|
1289
|
-
}
|
|
1290
|
-
)
|
|
1291
|
-
]
|
|
1292
|
-
}
|
|
1293
|
-
)
|
|
1608
|
+
components: ARTIFACT_CARD_INTERNAL_COMPONENTS,
|
|
1609
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatArtifactCard, { artifact: part.artifact })
|
|
1294
1610
|
}
|
|
1295
1611
|
);
|
|
1296
1612
|
default:
|
|
@@ -1299,10 +1615,17 @@ function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact
|
|
|
1299
1615
|
}
|
|
1300
1616
|
|
|
1301
1617
|
// src/view/chrome/panel-header.tsx
|
|
1302
|
-
var
|
|
1303
|
-
var
|
|
1618
|
+
var import_components4 = require("@pactor-app/ui/components");
|
|
1619
|
+
var import_react7 = require("react");
|
|
1620
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1621
|
+
var ChatPanelContext = (0, import_react7.createContext)(
|
|
1622
|
+
null
|
|
1623
|
+
);
|
|
1624
|
+
function artifactIconName(artifact) {
|
|
1625
|
+
return artifact ? resolveArtifactIconName(artifact) : "file";
|
|
1626
|
+
}
|
|
1304
1627
|
function ChatPanelCloseButton() {
|
|
1305
|
-
return /* @__PURE__ */ (0,
|
|
1628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1306
1629
|
"button",
|
|
1307
1630
|
{
|
|
1308
1631
|
type: "button",
|
|
@@ -1310,14 +1633,99 @@ function ChatPanelCloseButton() {
|
|
|
1310
1633
|
title: "\u5173\u95ED\u9762\u677F",
|
|
1311
1634
|
"aria-label": "\u5173\u95ED\u9762\u677F",
|
|
1312
1635
|
onClick: () => invokeChatPanelClose(),
|
|
1313
|
-
children: /* @__PURE__ */ (0,
|
|
1636
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components4.Icon, { name: "x", size: 16 })
|
|
1637
|
+
}
|
|
1638
|
+
);
|
|
1639
|
+
}
|
|
1640
|
+
function ChatPanelListButton() {
|
|
1641
|
+
const ctx = (0, import_react7.useContext)(ChatPanelContext);
|
|
1642
|
+
if (ctx?.view === "list") {
|
|
1643
|
+
return null;
|
|
1644
|
+
}
|
|
1645
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1646
|
+
"button",
|
|
1647
|
+
{
|
|
1648
|
+
type: "button",
|
|
1649
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__list-toggle",
|
|
1650
|
+
title: "\u4EA7\u7269\u76EE\u5F55",
|
|
1651
|
+
"aria-label": "\u4EA7\u7269\u76EE\u5F55",
|
|
1652
|
+
onClick: () => invokeChatPanelToggleList(),
|
|
1653
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components4.Icon, { name: "arrow-left", size: 16 })
|
|
1654
|
+
}
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
function ChatPanelDownloadButton() {
|
|
1658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1659
|
+
"button",
|
|
1660
|
+
{
|
|
1661
|
+
type: "button",
|
|
1662
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__download",
|
|
1663
|
+
title: "\u4E0B\u8F7D\u4EA7\u7269",
|
|
1664
|
+
"aria-label": "\u4E0B\u8F7D\u4EA7\u7269",
|
|
1665
|
+
onClick: () => invokeChatPanelDownload(),
|
|
1666
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components4.Icon, { name: "download", size: 16 })
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
function ChatPanelArtifactMenu() {
|
|
1671
|
+
const ctx = (0, import_react7.useContext)(ChatPanelContext);
|
|
1672
|
+
if (!ctx || ctx.artifacts.length === 0) {
|
|
1673
|
+
return null;
|
|
1674
|
+
}
|
|
1675
|
+
const active = ctx.artifacts.find((item) => item.id === ctx.activeId);
|
|
1676
|
+
const inList = ctx.view === "list";
|
|
1677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1678
|
+
import_components4.DropdownMenu,
|
|
1679
|
+
{
|
|
1680
|
+
items: ctx.artifacts.map((item) => ({
|
|
1681
|
+
label: item.title,
|
|
1682
|
+
value: item.id,
|
|
1683
|
+
icon: artifactIconName(item)
|
|
1684
|
+
})),
|
|
1685
|
+
onSelect: (value) => {
|
|
1686
|
+
const target = ctx.artifacts.find((item) => item.id === value);
|
|
1687
|
+
if (target) {
|
|
1688
|
+
ctx.onSelectArtifact?.(target);
|
|
1689
|
+
}
|
|
1690
|
+
},
|
|
1691
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1692
|
+
"span",
|
|
1693
|
+
{
|
|
1694
|
+
className: "pactor-chat-inspector__menu-trigger",
|
|
1695
|
+
"data-view": ctx.view,
|
|
1696
|
+
children: [
|
|
1697
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1698
|
+
import_components4.Icon,
|
|
1699
|
+
{
|
|
1700
|
+
name: inList ? "folder" : artifactIconName(active),
|
|
1701
|
+
size: 13
|
|
1702
|
+
}
|
|
1703
|
+
),
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pactor-chat-inspector__title", children: inList ? "\u4EA7\u7269\u76EE\u5F55" : active?.title ?? "\u4EA7\u51FA\u7269" }),
|
|
1705
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components4.Icon, { name: "chevron-down", size: 12 })
|
|
1706
|
+
]
|
|
1707
|
+
}
|
|
1708
|
+
)
|
|
1314
1709
|
}
|
|
1315
1710
|
);
|
|
1316
1711
|
}
|
|
1317
|
-
var PANEL_HEADER_INTERNAL_COMPONENTS = {
|
|
1712
|
+
var PANEL_HEADER_INTERNAL_COMPONENTS = {
|
|
1713
|
+
ChatPanelCloseButton,
|
|
1714
|
+
ChatPanelDownloadButton,
|
|
1715
|
+
ChatPanelListButton,
|
|
1716
|
+
ChatPanelArtifactMenu
|
|
1717
|
+
};
|
|
1318
1718
|
function buildPanelHeaderFragment(props) {
|
|
1319
1719
|
return {
|
|
1320
|
-
requires: [
|
|
1720
|
+
requires: [
|
|
1721
|
+
"Flex",
|
|
1722
|
+
"Text",
|
|
1723
|
+
"Badge",
|
|
1724
|
+
"ChatPanelCloseButton",
|
|
1725
|
+
"ChatPanelDownloadButton",
|
|
1726
|
+
"ChatPanelListButton",
|
|
1727
|
+
"ChatPanelArtifactMenu"
|
|
1728
|
+
],
|
|
1321
1729
|
node: {
|
|
1322
1730
|
type: "Flex",
|
|
1323
1731
|
props: {
|
|
@@ -1331,7 +1739,8 @@ function buildPanelHeaderFragment(props) {
|
|
|
1331
1739
|
type: "Flex",
|
|
1332
1740
|
props: { align: "center", gap: "small" },
|
|
1333
1741
|
children: [
|
|
1334
|
-
{
|
|
1742
|
+
...props.showListButton ? [{ type: "ChatPanelListButton" }] : [],
|
|
1743
|
+
props.showMenu ? { type: "ChatPanelArtifactMenu" } : {
|
|
1335
1744
|
type: "Text",
|
|
1336
1745
|
props: {
|
|
1337
1746
|
text: props.title,
|
|
@@ -1339,26 +1748,35 @@ function buildPanelHeaderFragment(props) {
|
|
|
1339
1748
|
className: "pactor-chat-inspector__title"
|
|
1340
1749
|
}
|
|
1341
1750
|
},
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1751
|
+
...props.view === "list" ? [] : [
|
|
1752
|
+
{
|
|
1753
|
+
type: "Badge",
|
|
1754
|
+
props: {
|
|
1755
|
+
text: props.kind,
|
|
1756
|
+
variant: "secondary",
|
|
1757
|
+
className: "pactor-chat-inspector__kind"
|
|
1758
|
+
}
|
|
1348
1759
|
}
|
|
1349
|
-
|
|
1760
|
+
]
|
|
1350
1761
|
]
|
|
1351
1762
|
},
|
|
1352
|
-
{
|
|
1763
|
+
{
|
|
1764
|
+
type: "Flex",
|
|
1765
|
+
props: { align: "center", gap: "small" },
|
|
1766
|
+
children: [
|
|
1767
|
+
...props.showDownload ? [{ type: "ChatPanelDownloadButton" }] : [],
|
|
1768
|
+
{ type: "ChatPanelCloseButton" }
|
|
1769
|
+
]
|
|
1770
|
+
}
|
|
1353
1771
|
]
|
|
1354
1772
|
}
|
|
1355
1773
|
};
|
|
1356
1774
|
}
|
|
1357
1775
|
|
|
1358
1776
|
// src/view/ArtifactPanel.tsx
|
|
1359
|
-
var
|
|
1777
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1360
1778
|
function useArtifactRuntime(safeRegistry, user) {
|
|
1361
|
-
return (0,
|
|
1779
|
+
return (0, import_react8.useMemo)(() => {
|
|
1362
1780
|
if (!safeRegistry) {
|
|
1363
1781
|
return void 0;
|
|
1364
1782
|
}
|
|
@@ -1370,7 +1788,7 @@ function useArtifactRuntime(safeRegistry, user) {
|
|
|
1370
1788
|
return createChatRuntime({ safeRegistry: components, user });
|
|
1371
1789
|
}, [safeRegistry, user]);
|
|
1372
1790
|
}
|
|
1373
|
-
var ArtifactDslGuard = class extends
|
|
1791
|
+
var ArtifactDslGuard = class extends import_react8.Component {
|
|
1374
1792
|
constructor() {
|
|
1375
1793
|
super(...arguments);
|
|
1376
1794
|
this.state = { failed: false };
|
|
@@ -1382,12 +1800,12 @@ var ArtifactDslGuard = class extends import_react6.Component {
|
|
|
1382
1800
|
console.warn("[@pactor-app/chat] DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A", error);
|
|
1383
1801
|
}
|
|
1384
1802
|
render() {
|
|
1385
|
-
return this.state.failed ? /* @__PURE__ */ (0,
|
|
1803
|
+
return this.state.failed ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-denied", children: "DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A" }) : this.props.children;
|
|
1386
1804
|
}
|
|
1387
1805
|
};
|
|
1388
1806
|
function ArtifactDslNode({ node }) {
|
|
1389
1807
|
const { renderChildren } = (0, import_runtime4.useRenderer)();
|
|
1390
|
-
return /* @__PURE__ */ (0,
|
|
1808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: renderChildren([node]) });
|
|
1391
1809
|
}
|
|
1392
1810
|
function ArtifactDslContent({
|
|
1393
1811
|
content,
|
|
@@ -1395,47 +1813,195 @@ function ArtifactDslContent({
|
|
|
1395
1813
|
}) {
|
|
1396
1814
|
const node = typeof content === "object" && content !== null && !Array.isArray(content) && typeof content.type === "string" ? content : void 0;
|
|
1397
1815
|
if (!node || !runtime) {
|
|
1398
|
-
return /* @__PURE__ */ (0,
|
|
1816
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-denied", children: node ? "DSL \u9884\u89C8\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "DSL \u4EA7\u51FA\u7269\u5185\u5BB9\u65E0\u6548" });
|
|
1399
1817
|
}
|
|
1400
1818
|
const guarded = guardChatDsl(node, runtime.context.components);
|
|
1401
|
-
return /* @__PURE__ */ (0,
|
|
1819
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_runtime4.DslRenderer, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArtifactDslGuard, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArtifactDslNode, { node: guarded }) }) });
|
|
1820
|
+
}
|
|
1821
|
+
function ArtifactKindIcon({ artifact }) {
|
|
1822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components5.Icon, { name: resolveArtifactIconName(artifact), size: 13 });
|
|
1823
|
+
}
|
|
1824
|
+
function buildArtifactTree(artifacts) {
|
|
1825
|
+
const root = { name: "", path: "", children: [] };
|
|
1826
|
+
for (const artifact of artifacts) {
|
|
1827
|
+
const segments = artifact.id.split("/").filter(Boolean);
|
|
1828
|
+
let node = root;
|
|
1829
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1830
|
+
const path = segments.slice(0, i + 1).join("/");
|
|
1831
|
+
let child = node.children.find(
|
|
1832
|
+
(item) => item.path === path && item.artifact === void 0
|
|
1833
|
+
);
|
|
1834
|
+
if (!child) {
|
|
1835
|
+
child = { name: segments[i], path, children: [] };
|
|
1836
|
+
node.children.push(child);
|
|
1837
|
+
}
|
|
1838
|
+
node = child;
|
|
1839
|
+
}
|
|
1840
|
+
node.children.push({
|
|
1841
|
+
name: artifact.title,
|
|
1842
|
+
path: artifact.id,
|
|
1843
|
+
artifact,
|
|
1844
|
+
children: []
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
const sortLevel = (nodes) => {
|
|
1848
|
+
nodes.sort((a, b) => {
|
|
1849
|
+
const dirDelta = Number(b.artifact === void 0) - Number(a.artifact === void 0);
|
|
1850
|
+
return dirDelta !== 0 ? dirDelta : a.name.localeCompare(b.name);
|
|
1851
|
+
});
|
|
1852
|
+
for (const item of nodes) {
|
|
1853
|
+
sortLevel(item.children);
|
|
1854
|
+
}
|
|
1855
|
+
};
|
|
1856
|
+
sortLevel(root.children);
|
|
1857
|
+
return root.children;
|
|
1858
|
+
}
|
|
1859
|
+
function ArtifactListView({
|
|
1860
|
+
nodes,
|
|
1861
|
+
activeId,
|
|
1862
|
+
onSelect
|
|
1863
|
+
}) {
|
|
1864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "pactor-chat-inspector__list", children: nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1865
|
+
ArtifactTreeRow,
|
|
1866
|
+
{
|
|
1867
|
+
node,
|
|
1868
|
+
activeId,
|
|
1869
|
+
onSelect
|
|
1870
|
+
},
|
|
1871
|
+
node.path
|
|
1872
|
+
)) });
|
|
1873
|
+
}
|
|
1874
|
+
function ArtifactTreeRow({
|
|
1875
|
+
node,
|
|
1876
|
+
activeId,
|
|
1877
|
+
onSelect
|
|
1878
|
+
}) {
|
|
1879
|
+
const [open, setOpen] = (0, import_react8.useState)(true);
|
|
1880
|
+
if (node.artifact) {
|
|
1881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1882
|
+
"button",
|
|
1883
|
+
{
|
|
1884
|
+
type: "button",
|
|
1885
|
+
className: "pactor-chat-inspector__list-item",
|
|
1886
|
+
"data-active": node.artifact.id === activeId,
|
|
1887
|
+
onClick: () => onSelect?.(node.artifact),
|
|
1888
|
+
children: [
|
|
1889
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArtifactKindIcon, { artifact: node.artifact }),
|
|
1890
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-inspector__list-item-title", children: node.artifact.title }),
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-inspector__kind", children: node.artifact.kind })
|
|
1892
|
+
]
|
|
1893
|
+
}
|
|
1894
|
+
) });
|
|
1895
|
+
}
|
|
1896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1898
|
+
"button",
|
|
1899
|
+
{
|
|
1900
|
+
type: "button",
|
|
1901
|
+
className: "pactor-chat-inspector__list-folder",
|
|
1902
|
+
"aria-expanded": open,
|
|
1903
|
+
"data-open": open,
|
|
1904
|
+
onClick: () => setOpen((value) => !value),
|
|
1905
|
+
children: [
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components5.Icon, { name: "chevron-right", size: 12 }) }),
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components5.Icon, { name: "folder", size: 13 }),
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: node.name })
|
|
1909
|
+
]
|
|
1910
|
+
}
|
|
1911
|
+
),
|
|
1912
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-inspector__list-children", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1913
|
+
ArtifactListView,
|
|
1914
|
+
{
|
|
1915
|
+
nodes: node.children,
|
|
1916
|
+
activeId,
|
|
1917
|
+
onSelect
|
|
1918
|
+
}
|
|
1919
|
+
) })
|
|
1920
|
+
] });
|
|
1921
|
+
}
|
|
1922
|
+
function ArtifactImageContent({ artifact }) {
|
|
1923
|
+
const raw = String(artifact.content).trim();
|
|
1924
|
+
const src = raw.startsWith("<svg") || raw.startsWith("<?xml") ? `data:image/svg+xml;utf8,${encodeURIComponent(raw)}` : raw;
|
|
1925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-inspector__image", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src, alt: artifact.title }) });
|
|
1402
1926
|
}
|
|
1403
1927
|
function ArtifactContent({
|
|
1404
1928
|
artifact,
|
|
1405
|
-
runtime
|
|
1929
|
+
runtime,
|
|
1930
|
+
viewers
|
|
1406
1931
|
}) {
|
|
1932
|
+
const ext = resolveArtifactFileType(artifact);
|
|
1933
|
+
const custom = (ext ? viewers?.[ext] : void 0) ?? viewers?.[artifact.kind];
|
|
1934
|
+
if (custom) {
|
|
1935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: custom(artifact) });
|
|
1936
|
+
}
|
|
1937
|
+
if (isImageArtifact(artifact)) {
|
|
1938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArtifactImageContent, { artifact });
|
|
1939
|
+
}
|
|
1407
1940
|
switch (artifact.kind) {
|
|
1408
1941
|
case "markdown":
|
|
1409
|
-
return /* @__PURE__ */ (0,
|
|
1942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_markdown2.MarkdownRenderer, { content: String(artifact.content) });
|
|
1410
1943
|
case "code":
|
|
1411
|
-
return /* @__PURE__ */ (0,
|
|
1412
|
-
artifact.language ? /* @__PURE__ */ (0,
|
|
1413
|
-
/* @__PURE__ */ (0,
|
|
1944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "pactor-chat-inspector__code", children: [
|
|
1945
|
+
artifact.language ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-inspector__code-lang", children: artifact.language }) : null,
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: String(artifact.content) }) })
|
|
1414
1947
|
] });
|
|
1415
1948
|
case "text":
|
|
1416
|
-
return /* @__PURE__ */ (0,
|
|
1949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { className: "pactor-chat-inspector__text", children: String(artifact.content) });
|
|
1417
1950
|
case "dsl":
|
|
1418
|
-
return /* @__PURE__ */ (0,
|
|
1951
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArtifactDslContent, { content: artifact.content, runtime });
|
|
1419
1952
|
default:
|
|
1420
1953
|
return null;
|
|
1421
1954
|
}
|
|
1422
1955
|
}
|
|
1423
1956
|
function ArtifactPanel({
|
|
1424
1957
|
artifact,
|
|
1958
|
+
artifacts,
|
|
1959
|
+
activeArtifactId,
|
|
1960
|
+
onSelectArtifact,
|
|
1961
|
+
viewRequest,
|
|
1962
|
+
onViewRequestConsumed,
|
|
1425
1963
|
inspector,
|
|
1426
1964
|
onClose,
|
|
1427
1965
|
safeRegistry,
|
|
1428
1966
|
user,
|
|
1967
|
+
artifactViewers,
|
|
1429
1968
|
className
|
|
1430
1969
|
}) {
|
|
1431
1970
|
const runtime = useArtifactRuntime(safeRegistry, user);
|
|
1432
|
-
const
|
|
1971
|
+
const [view, setView] = (0, import_react8.useState)("content");
|
|
1972
|
+
const activeId = activeArtifactId ?? artifact?.id;
|
|
1973
|
+
(0, import_react8.useEffect)(() => {
|
|
1974
|
+
setView("content");
|
|
1975
|
+
}, [activeId]);
|
|
1976
|
+
(0, import_react8.useEffect)(() => {
|
|
1977
|
+
if (viewRequest != null) {
|
|
1978
|
+
setView("list");
|
|
1979
|
+
onViewRequestConsumed?.();
|
|
1980
|
+
}
|
|
1981
|
+
}, [viewRequest]);
|
|
1982
|
+
const showListButton = artifacts !== void 0 && artifacts.length > 0;
|
|
1983
|
+
const showMenu = artifacts !== void 0 && artifacts.length > 0;
|
|
1984
|
+
const toggleListRef = (0, import_react8.useRef)(() => {
|
|
1985
|
+
});
|
|
1986
|
+
toggleListRef.current = () => setView((value) => value === "list" ? "content" : "list");
|
|
1987
|
+
const closeRef = (0, import_react8.useRef)(onClose);
|
|
1433
1988
|
closeRef.current = onClose;
|
|
1434
|
-
(0,
|
|
1435
|
-
|
|
1989
|
+
const artifactRef = (0, import_react8.useRef)(artifact);
|
|
1990
|
+
artifactRef.current = artifact;
|
|
1991
|
+
(0, import_react8.useEffect)(() => {
|
|
1992
|
+
setChatChromeHandlers({
|
|
1993
|
+
panelClose: () => closeRef.current?.(),
|
|
1994
|
+
panelToggleList: () => toggleListRef.current(),
|
|
1995
|
+
panelDownload: () => {
|
|
1996
|
+
const current = artifactRef.current;
|
|
1997
|
+
if (current) {
|
|
1998
|
+
void downloadArtifact(current);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
1436
2002
|
}, []);
|
|
1437
|
-
const panelRef = (0,
|
|
1438
|
-
const [width, setWidth] = (0,
|
|
2003
|
+
const panelRef = (0, import_react8.useRef)(null);
|
|
2004
|
+
const [width, setWidth] = (0, import_react8.useState)(null);
|
|
1439
2005
|
const handleResizeStart = (event) => {
|
|
1440
2006
|
event.preventDefault();
|
|
1441
2007
|
const panel = panelRef.current;
|
|
@@ -1444,14 +2010,14 @@ function ArtifactPanel({
|
|
|
1444
2010
|
}
|
|
1445
2011
|
const hostRect = panel.parentElement?.getBoundingClientRect();
|
|
1446
2012
|
const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
|
|
1447
|
-
const maxWidth = hostWidth *
|
|
2013
|
+
const maxWidth = hostWidth * 2 / 3;
|
|
1448
2014
|
const startWidth = panel.getBoundingClientRect().width;
|
|
1449
2015
|
const startX = event.clientX;
|
|
1450
2016
|
const prevUserSelect = document.body.style.userSelect;
|
|
1451
2017
|
document.body.style.userSelect = "none";
|
|
1452
2018
|
const onMove = (moveEvent) => {
|
|
1453
2019
|
const next = startWidth + (startX - moveEvent.clientX);
|
|
1454
|
-
setWidth(Math.round(Math.min(Math.max(next,
|
|
2020
|
+
setWidth(Math.round(Math.min(Math.max(next, 480), maxWidth)));
|
|
1455
2021
|
};
|
|
1456
2022
|
const onUp = () => {
|
|
1457
2023
|
document.body.style.userSelect = prevUserSelect;
|
|
@@ -1461,66 +2027,88 @@ function ArtifactPanel({
|
|
|
1461
2027
|
document.addEventListener("pointermove", onMove);
|
|
1462
2028
|
document.addEventListener("pointerup", onUp);
|
|
1463
2029
|
};
|
|
1464
|
-
return /* @__PURE__ */ (0,
|
|
1465
|
-
|
|
2030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2031
|
+
ChatPanelContext.Provider,
|
|
1466
2032
|
{
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
2033
|
+
value: {
|
|
2034
|
+
artifacts: artifacts ?? [],
|
|
2035
|
+
activeId,
|
|
2036
|
+
view,
|
|
2037
|
+
onSelectArtifact
|
|
2038
|
+
},
|
|
2039
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2040
|
+
"aside",
|
|
2041
|
+
{
|
|
2042
|
+
ref: panelRef,
|
|
2043
|
+
className: `pactor-chat-inspector${className ? ` ${className}` : ""}`,
|
|
2044
|
+
"data-kind": artifact?.kind,
|
|
2045
|
+
style: width !== null ? { width: `${width}px` } : void 0,
|
|
2046
|
+
children: [
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2048
|
+
"div",
|
|
2049
|
+
{
|
|
2050
|
+
className: "pactor-chat-inspector__resize",
|
|
2051
|
+
role: "separator",
|
|
2052
|
+
"aria-orientation": "vertical",
|
|
2053
|
+
"aria-label": "\u62D6\u52A8\u8C03\u6574\u9762\u677F\u5BBD\u5EA6",
|
|
2054
|
+
onPointerDown: handleResizeStart
|
|
2055
|
+
}
|
|
2056
|
+
),
|
|
2057
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-inspector__header", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2058
|
+
ChromeSlot,
|
|
2059
|
+
{
|
|
2060
|
+
fragment: buildPanelHeaderFragment({
|
|
2061
|
+
title: view === "list" ? "\u4EA7\u7269\u76EE\u5F55" : artifact?.title ?? "\u4EA7\u51FA\u7269",
|
|
2062
|
+
kind: artifact?.kind ?? "text",
|
|
2063
|
+
showListButton,
|
|
2064
|
+
showDownload: artifact != null,
|
|
2065
|
+
showMenu,
|
|
2066
|
+
view
|
|
2067
|
+
}),
|
|
2068
|
+
components: PANEL_HEADER_INTERNAL_COMPONENTS,
|
|
2069
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2070
|
+
showListButton ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatPanelListButton, {}) : null,
|
|
2071
|
+
showMenu ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatPanelArtifactMenu, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-inspector__title", children: view === "list" ? "\u4EA7\u7269\u76EE\u5F55" : artifact?.title ?? "\u4EA7\u51FA\u7269" }),
|
|
2072
|
+
view !== "list" && artifact ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pactor-chat-inspector__kind", children: artifact.kind }) : null,
|
|
2073
|
+
artifact ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatPanelDownloadButton, {}) : null,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatPanelCloseButton, {})
|
|
2075
|
+
] })
|
|
2076
|
+
}
|
|
2077
|
+
) }),
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pactor-chat-inspector__body", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2079
|
+
ArtifactListView,
|
|
2080
|
+
{
|
|
2081
|
+
nodes: buildArtifactTree(artifacts),
|
|
2082
|
+
activeId,
|
|
2083
|
+
onSelect: onSelectArtifact
|
|
2084
|
+
}
|
|
2085
|
+
) : inspector !== void 0 && inspector !== null ? inspector : artifact ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2086
|
+
ArtifactContent,
|
|
2087
|
+
{
|
|
2088
|
+
artifact,
|
|
2089
|
+
runtime,
|
|
2090
|
+
viewers: artifactViewers
|
|
2091
|
+
}
|
|
2092
|
+
) : null })
|
|
2093
|
+
]
|
|
2094
|
+
}
|
|
2095
|
+
)
|
|
1508
2096
|
}
|
|
1509
2097
|
);
|
|
1510
2098
|
}
|
|
1511
2099
|
|
|
1512
2100
|
// src/view/ChatView.tsx
|
|
1513
|
-
var
|
|
2101
|
+
var import_components11 = require("@pactor-app/ui/components");
|
|
1514
2102
|
var import_core4 = require("@pactor-app/core");
|
|
1515
|
-
var
|
|
2103
|
+
var import_react17 = require("react");
|
|
1516
2104
|
|
|
1517
2105
|
// src/view/Composer.tsx
|
|
1518
|
-
var
|
|
1519
|
-
var
|
|
2106
|
+
var import_components8 = require("@pactor-app/ui/components");
|
|
2107
|
+
var import_react13 = require("react");
|
|
1520
2108
|
|
|
1521
2109
|
// src/view/AnchoredPopover.tsx
|
|
1522
|
-
var
|
|
1523
|
-
var
|
|
2110
|
+
var import_react9 = require("react");
|
|
2111
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1524
2112
|
function AnchoredPopover({
|
|
1525
2113
|
anchorRect,
|
|
1526
2114
|
onClose,
|
|
@@ -1529,9 +2117,9 @@ function AnchoredPopover({
|
|
|
1529
2117
|
role = "dialog",
|
|
1530
2118
|
sideOffset = 8
|
|
1531
2119
|
}) {
|
|
1532
|
-
const ref = (0,
|
|
1533
|
-
const [position, setPosition] = (0,
|
|
1534
|
-
(0,
|
|
2120
|
+
const ref = (0, import_react9.useRef)(null);
|
|
2121
|
+
const [position, setPosition] = (0, import_react9.useState)(null);
|
|
2122
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
1535
2123
|
const element = ref.current;
|
|
1536
2124
|
if (!element) return;
|
|
1537
2125
|
const height = element.offsetHeight;
|
|
@@ -1549,7 +2137,7 @@ function AnchoredPopover({
|
|
|
1549
2137
|
}
|
|
1550
2138
|
);
|
|
1551
2139
|
}, [anchorRect, sideOffset]);
|
|
1552
|
-
(0,
|
|
2140
|
+
(0, import_react9.useEffect)(() => {
|
|
1553
2141
|
const onKeyDown = (event) => {
|
|
1554
2142
|
if (event.key !== "Escape") return;
|
|
1555
2143
|
const element = ref.current;
|
|
@@ -1577,7 +2165,7 @@ function AnchoredPopover({
|
|
|
1577
2165
|
position?.below ? "pactor-chat-popover--below" : "",
|
|
1578
2166
|
className ?? ""
|
|
1579
2167
|
].filter(Boolean).join(" ");
|
|
1580
|
-
return /* @__PURE__ */ (0,
|
|
2168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1581
2169
|
"div",
|
|
1582
2170
|
{
|
|
1583
2171
|
ref,
|
|
@@ -1596,8 +2184,8 @@ function AnchoredPopover({
|
|
|
1596
2184
|
}
|
|
1597
2185
|
|
|
1598
2186
|
// src/view/ModelChip.tsx
|
|
1599
|
-
var
|
|
1600
|
-
var
|
|
2187
|
+
var import_components6 = require("@pactor-app/ui/components");
|
|
2188
|
+
var import_react10 = require("react");
|
|
1601
2189
|
|
|
1602
2190
|
// src/view/chrome/model-select.tsx
|
|
1603
2191
|
function buildModelSelectFragment(props) {
|
|
@@ -1623,17 +2211,17 @@ function buildModelSelectFragment(props) {
|
|
|
1623
2211
|
}
|
|
1624
2212
|
|
|
1625
2213
|
// src/view/ModelChip.tsx
|
|
1626
|
-
var
|
|
2214
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1627
2215
|
function ModelChip({
|
|
1628
2216
|
models,
|
|
1629
2217
|
model,
|
|
1630
2218
|
onModelChange
|
|
1631
2219
|
}) {
|
|
1632
|
-
const chipRef = (0,
|
|
1633
|
-
const [anchor, setAnchor] = (0,
|
|
2220
|
+
const chipRef = (0, import_react10.useRef)(null);
|
|
2221
|
+
const [anchor, setAnchor] = (0, import_react10.useState)(null);
|
|
1634
2222
|
const currentOption = models.find((option) => option.value === model) ?? models[0];
|
|
1635
|
-
return /* @__PURE__ */ (0,
|
|
1636
|
-
/* @__PURE__ */ (0,
|
|
2223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1637
2225
|
"button",
|
|
1638
2226
|
{
|
|
1639
2227
|
ref: chipRef,
|
|
@@ -1643,18 +2231,18 @@ function ModelChip({
|
|
|
1643
2231
|
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
1644
2232
|
onClick: () => setAnchor(chipRef.current.getBoundingClientRect()),
|
|
1645
2233
|
children: [
|
|
1646
|
-
/* @__PURE__ */ (0,
|
|
1647
|
-
/* @__PURE__ */ (0,
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-model-chip__label", children: currentOption.label }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "chevrons-up-down", size: 12 })
|
|
1648
2236
|
]
|
|
1649
2237
|
}
|
|
1650
2238
|
),
|
|
1651
|
-
anchor && /* @__PURE__ */ (0,
|
|
2239
|
+
anchor && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1652
2240
|
AnchoredPopover,
|
|
1653
2241
|
{
|
|
1654
2242
|
anchorRect: anchor,
|
|
1655
2243
|
onClose: () => setAnchor(null),
|
|
1656
2244
|
role: "listbox",
|
|
1657
|
-
children: models.map((option) => /* @__PURE__ */ (0,
|
|
2245
|
+
children: models.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1658
2246
|
"button",
|
|
1659
2247
|
{
|
|
1660
2248
|
type: "button",
|
|
@@ -1666,8 +2254,8 @@ function ModelChip({
|
|
|
1666
2254
|
setAnchor(null);
|
|
1667
2255
|
},
|
|
1668
2256
|
children: [
|
|
1669
|
-
/* @__PURE__ */ (0,
|
|
1670
|
-
option.value === currentOption.value && /* @__PURE__ */ (0,
|
|
2257
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-popover__item-label", children: option.label }),
|
|
2258
|
+
option.value === currentOption.value && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "check", size: 13, className: "pactor-chat-popover__item-check" })
|
|
1671
2259
|
]
|
|
1672
2260
|
},
|
|
1673
2261
|
option.value
|
|
@@ -1681,31 +2269,31 @@ function ModelSelect({
|
|
|
1681
2269
|
model,
|
|
1682
2270
|
onModelChange
|
|
1683
2271
|
}) {
|
|
1684
|
-
const changeRef = (0,
|
|
2272
|
+
const changeRef = (0, import_react10.useRef)(onModelChange);
|
|
1685
2273
|
changeRef.current = onModelChange;
|
|
1686
|
-
(0,
|
|
2274
|
+
(0, import_react10.useEffect)(() => {
|
|
1687
2275
|
setChatChromeHandlers({
|
|
1688
2276
|
modelChange: (value) => changeRef.current?.(value)
|
|
1689
2277
|
});
|
|
1690
2278
|
}, []);
|
|
1691
|
-
return /* @__PURE__ */ (0,
|
|
2279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1692
2280
|
ChromeSlot,
|
|
1693
2281
|
{
|
|
1694
2282
|
fragment: buildModelSelectFragment({ models, model }),
|
|
1695
|
-
fallback: /* @__PURE__ */ (0,
|
|
2283
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ModelChip, { models, model, onModelChange })
|
|
1696
2284
|
}
|
|
1697
2285
|
);
|
|
1698
2286
|
}
|
|
1699
2287
|
|
|
1700
2288
|
// src/view/chrome/composer.tsx
|
|
1701
|
-
var
|
|
1702
|
-
var
|
|
1703
|
-
var
|
|
1704
|
-
var ComposerBridgeContext = (0,
|
|
2289
|
+
var import_components7 = require("@pactor-app/ui/components");
|
|
2290
|
+
var import_react11 = require("react");
|
|
2291
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2292
|
+
var ComposerBridgeContext = (0, import_react11.createContext)(
|
|
1705
2293
|
null
|
|
1706
2294
|
);
|
|
1707
2295
|
function useComposerBridge() {
|
|
1708
|
-
const bridge = (0,
|
|
2296
|
+
const bridge = (0, import_react11.useContext)(ComposerBridgeContext);
|
|
1709
2297
|
if (!bridge) {
|
|
1710
2298
|
throw new Error(
|
|
1711
2299
|
"[@pactor-app/chat] ChatComposer* \u5185\u90E8\u7EC4\u4EF6\u4EC5\u53EF\u5728 Composer chrome \u7247\u6BB5\u5185\u6E32\u67D3"
|
|
@@ -1730,21 +2318,21 @@ function ComposerAttachments({
|
|
|
1730
2318
|
if (attachments.length === 0) {
|
|
1731
2319
|
return null;
|
|
1732
2320
|
}
|
|
1733
|
-
return /* @__PURE__ */ (0,
|
|
2321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-composer__attachments", children: attachments.map((attachment) => {
|
|
1734
2322
|
const isImage = attachment.mimeType.startsWith("image/");
|
|
1735
|
-
return /* @__PURE__ */ (0,
|
|
2323
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1736
2324
|
"div",
|
|
1737
2325
|
{
|
|
1738
2326
|
className: "pactor-chat-composer__attachment",
|
|
1739
2327
|
"data-attachment-id": attachment.id,
|
|
1740
2328
|
onClick: () => onClick?.(attachment),
|
|
1741
2329
|
children: [
|
|
1742
|
-
isImage && attachment.url ? /* @__PURE__ */ (0,
|
|
1743
|
-
/* @__PURE__ */ (0,
|
|
1744
|
-
/* @__PURE__ */ (0,
|
|
1745
|
-
attachment.size !== void 0 && /* @__PURE__ */ (0,
|
|
2330
|
+
isImage && attachment.url ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "pactor-chat-composer__attachment-thumb", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: attachment.url, alt: attachment.name }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "pactor-chat-composer__attachment-info", children: [
|
|
2331
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "file-text", size: 14 }),
|
|
2332
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
2333
|
+
attachment.size !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1746
2334
|
] }),
|
|
1747
|
-
/* @__PURE__ */ (0,
|
|
2335
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1748
2336
|
"button",
|
|
1749
2337
|
{
|
|
1750
2338
|
type: "button",
|
|
@@ -1755,7 +2343,7 @@ function ComposerAttachments({
|
|
|
1755
2343
|
event.stopPropagation();
|
|
1756
2344
|
onRemove(attachment.id);
|
|
1757
2345
|
},
|
|
1758
|
-
children: /* @__PURE__ */ (0,
|
|
2346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "x", size: 12 })
|
|
1759
2347
|
}
|
|
1760
2348
|
)
|
|
1761
2349
|
]
|
|
@@ -1771,14 +2359,14 @@ function ComposerContextChips({
|
|
|
1771
2359
|
if (chips.length === 0) {
|
|
1772
2360
|
return null;
|
|
1773
2361
|
}
|
|
1774
|
-
return /* @__PURE__ */ (0,
|
|
2362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-composer__contexts", children: chips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1775
2363
|
"span",
|
|
1776
2364
|
{
|
|
1777
2365
|
className: "pactor-chat-context-chip",
|
|
1778
2366
|
"data-context-id": chip.id,
|
|
1779
2367
|
children: [
|
|
1780
|
-
/* @__PURE__ */ (0,
|
|
1781
|
-
/* @__PURE__ */ (0,
|
|
2368
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "pactor-chat-context-chip__label", children: chip.label }),
|
|
2369
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1782
2370
|
"button",
|
|
1783
2371
|
{
|
|
1784
2372
|
type: "button",
|
|
@@ -1786,7 +2374,7 @@ function ComposerContextChips({
|
|
|
1786
2374
|
title: `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1787
2375
|
"aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1788
2376
|
onClick: () => onRemove(chip),
|
|
1789
|
-
children: /* @__PURE__ */ (0,
|
|
2377
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "x", size: 12 })
|
|
1790
2378
|
}
|
|
1791
2379
|
)
|
|
1792
2380
|
]
|
|
@@ -1796,8 +2384,8 @@ function ComposerContextChips({
|
|
|
1796
2384
|
}
|
|
1797
2385
|
function ChatComposerHeader() {
|
|
1798
2386
|
const bridge = useComposerBridge();
|
|
1799
|
-
return /* @__PURE__ */ (0,
|
|
1800
|
-
bridge.attachments !== void 0 && /* @__PURE__ */ (0,
|
|
2387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2388
|
+
bridge.attachments !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1801
2389
|
ComposerAttachments,
|
|
1802
2390
|
{
|
|
1803
2391
|
attachments: bridge.attachments,
|
|
@@ -1805,7 +2393,7 @@ function ChatComposerHeader() {
|
|
|
1805
2393
|
onClick: bridge.attachmentClick
|
|
1806
2394
|
}
|
|
1807
2395
|
),
|
|
1808
|
-
bridge.contextChips !== void 0 && /* @__PURE__ */ (0,
|
|
2396
|
+
bridge.contextChips !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1809
2397
|
ComposerContextChips,
|
|
1810
2398
|
{
|
|
1811
2399
|
chips: bridge.contextChips,
|
|
@@ -1816,9 +2404,9 @@ function ChatComposerHeader() {
|
|
|
1816
2404
|
}
|
|
1817
2405
|
function ChatComposerToolbarStart() {
|
|
1818
2406
|
const bridge = useComposerBridge();
|
|
1819
|
-
return /* @__PURE__ */ (0,
|
|
2407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1820
2408
|
bridge.toolbarStart,
|
|
1821
|
-
bridge.showPlus && /* @__PURE__ */ (0,
|
|
2409
|
+
bridge.showPlus && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1822
2410
|
"button",
|
|
1823
2411
|
{
|
|
1824
2412
|
type: "button",
|
|
@@ -1826,10 +2414,10 @@ function ChatComposerToolbarStart() {
|
|
|
1826
2414
|
title: "\u66F4\u591A\u529F\u80FD",
|
|
1827
2415
|
"aria-label": "\u66F4\u591A\u529F\u80FD",
|
|
1828
2416
|
onClick: (event) => bridge.plusClick(event.currentTarget.getBoundingClientRect()),
|
|
1829
|
-
children: /* @__PURE__ */ (0,
|
|
2417
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "plus", size: 14 })
|
|
1830
2418
|
}
|
|
1831
2419
|
),
|
|
1832
|
-
bridge.showAttach && /* @__PURE__ */ (0,
|
|
2420
|
+
bridge.showAttach && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1833
2421
|
"button",
|
|
1834
2422
|
{
|
|
1835
2423
|
type: "button",
|
|
@@ -1837,15 +2425,15 @@ function ChatComposerToolbarStart() {
|
|
|
1837
2425
|
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1838
2426
|
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1839
2427
|
onClick: bridge.openFilePicker,
|
|
1840
|
-
children: /* @__PURE__ */ (0,
|
|
2428
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "paperclip", size: 14 })
|
|
1841
2429
|
}
|
|
1842
2430
|
)
|
|
1843
2431
|
] });
|
|
1844
2432
|
}
|
|
1845
2433
|
function ChatComposerToolbarEnd() {
|
|
1846
2434
|
const bridge = useComposerBridge();
|
|
1847
|
-
return /* @__PURE__ */ (0,
|
|
1848
|
-
bridge.modelChipEnabled && /* @__PURE__ */ (0,
|
|
2435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2436
|
+
bridge.modelChipEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1849
2437
|
ModelSelect,
|
|
1850
2438
|
{
|
|
1851
2439
|
models: bridge.models,
|
|
@@ -1854,7 +2442,7 @@ function ChatComposerToolbarEnd() {
|
|
|
1854
2442
|
}
|
|
1855
2443
|
),
|
|
1856
2444
|
bridge.toolbarEnd,
|
|
1857
|
-
/* @__PURE__ */ (0,
|
|
2445
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1858
2446
|
"button",
|
|
1859
2447
|
{
|
|
1860
2448
|
type: "button",
|
|
@@ -1863,14 +2451,14 @@ function ChatComposerToolbarEnd() {
|
|
|
1863
2451
|
"aria-label": bridge.streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1864
2452
|
disabled: bridge.streaming ? false : bridge.disabled || !bridge.text.trim(),
|
|
1865
2453
|
onClick: bridge.streaming ? bridge.stop : bridge.send,
|
|
1866
|
-
children: bridge.streaming ? /* @__PURE__ */ (0,
|
|
2454
|
+
children: bridge.streaming ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components7.Icon, { name: "arrow-up", size: 16 })
|
|
1867
2455
|
}
|
|
1868
2456
|
)
|
|
1869
2457
|
] });
|
|
1870
2458
|
}
|
|
1871
2459
|
function ChatComposerFooter() {
|
|
1872
2460
|
const bridge = useComposerBridge();
|
|
1873
|
-
return /* @__PURE__ */ (0,
|
|
2461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: bridge.composerFooter });
|
|
1874
2462
|
}
|
|
1875
2463
|
var COMPOSER_INTERNAL_COMPONENTS = {
|
|
1876
2464
|
ChatComposerHeader,
|
|
@@ -1911,8 +2499,8 @@ function buildComposerFragment(props) {
|
|
|
1911
2499
|
}
|
|
1912
2500
|
|
|
1913
2501
|
// src/view/context-sources.tsx
|
|
1914
|
-
var
|
|
1915
|
-
var
|
|
2502
|
+
var import_react12 = require("react");
|
|
2503
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1916
2504
|
function sourceCacheKey(source) {
|
|
1917
2505
|
return `${source.service ?? ""}:${JSON.stringify(source.params ?? {})}`;
|
|
1918
2506
|
}
|
|
@@ -1947,8 +2535,8 @@ function ContextSourceList({
|
|
|
1947
2535
|
cache,
|
|
1948
2536
|
onSelect
|
|
1949
2537
|
}) {
|
|
1950
|
-
const [resolutions, setResolutions] = (0,
|
|
1951
|
-
(0,
|
|
2538
|
+
const [resolutions, setResolutions] = (0, import_react12.useState)([]);
|
|
2539
|
+
(0, import_react12.useEffect)(() => {
|
|
1952
2540
|
let cancelled = false;
|
|
1953
2541
|
const initial = sources.map(
|
|
1954
2542
|
(source) => source.items ? { status: "ready", items: source.items } : { status: "loading" }
|
|
@@ -1993,12 +2581,12 @@ function ContextSourceList({
|
|
|
1993
2581
|
totalMatched += items.length;
|
|
1994
2582
|
return { source, resolution, items };
|
|
1995
2583
|
});
|
|
1996
|
-
return /* @__PURE__ */ (0,
|
|
1997
|
-
groups.map(({ source, resolution, items }) => /* @__PURE__ */ (0,
|
|
1998
|
-
sources.length > 1 && /* @__PURE__ */ (0,
|
|
1999
|
-
resolution.status === "loading" && /* @__PURE__ */ (0,
|
|
2000
|
-
resolution.status === "error" && /* @__PURE__ */ (0,
|
|
2001
|
-
items.map((item) => /* @__PURE__ */ (0,
|
|
2584
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "pactor-chat-source-list", children: [
|
|
2585
|
+
groups.map(({ source, resolution, items }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "pactor-chat-source-list__group", children: [
|
|
2586
|
+
sources.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pactor-chat-source-list__group-label", children: source.label }),
|
|
2587
|
+
resolution.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pactor-chat-source-list__hint", children: "\u52A0\u8F7D\u4E2D\u2026" }),
|
|
2588
|
+
resolution.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pactor-chat-source-list__error", role: "alert", children: resolution.message }),
|
|
2589
|
+
items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2002
2590
|
"button",
|
|
2003
2591
|
{
|
|
2004
2592
|
type: "button",
|
|
@@ -2009,12 +2597,12 @@ function ContextSourceList({
|
|
|
2009
2597
|
item.id
|
|
2010
2598
|
))
|
|
2011
2599
|
] }, `${source.trigger}:${source.label}`)),
|
|
2012
|
-
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */ (0,
|
|
2600
|
+
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pactor-chat-source-list__hint", children: "\u65E0\u5339\u914D\u9879" })
|
|
2013
2601
|
] });
|
|
2014
2602
|
}
|
|
2015
2603
|
|
|
2016
2604
|
// src/view/Composer.tsx
|
|
2017
|
-
var
|
|
2605
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2018
2606
|
var MAX_INPUT_HEIGHT = 200;
|
|
2019
2607
|
function detectMention(text, caret) {
|
|
2020
2608
|
const beforeCaret = text.slice(0, caret);
|
|
@@ -2048,26 +2636,26 @@ function Composer({
|
|
|
2048
2636
|
composerFooter,
|
|
2049
2637
|
hideToolbar = false
|
|
2050
2638
|
}) {
|
|
2051
|
-
const [text, setText] = (0,
|
|
2052
|
-
const [dragOver, setDragOver] = (0,
|
|
2053
|
-
const inputRef = (0,
|
|
2054
|
-
const fileInputRef = (0,
|
|
2055
|
-
const plusButtonRef = (0,
|
|
2056
|
-
const composingRef = (0,
|
|
2639
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
2640
|
+
const [dragOver, setDragOver] = (0, import_react13.useState)(false);
|
|
2641
|
+
const inputRef = (0, import_react13.useRef)(null);
|
|
2642
|
+
const fileInputRef = (0, import_react13.useRef)(null);
|
|
2643
|
+
const plusButtonRef = (0, import_react13.useRef)(null);
|
|
2644
|
+
const composingRef = (0, import_react13.useRef)(false);
|
|
2057
2645
|
const modelChipEnabled = models !== void 0 && models.length > 0;
|
|
2058
|
-
const mentionSources = (0,
|
|
2646
|
+
const mentionSources = (0, import_react13.useMemo)(
|
|
2059
2647
|
() => contextSources?.filter((source) => source.trigger === "@") ?? [],
|
|
2060
2648
|
[contextSources]
|
|
2061
2649
|
);
|
|
2062
|
-
const plusSources = (0,
|
|
2650
|
+
const plusSources = (0, import_react13.useMemo)(
|
|
2063
2651
|
() => contextSources?.filter((source) => source.trigger === "+") ?? [],
|
|
2064
2652
|
[contextSources]
|
|
2065
2653
|
);
|
|
2066
2654
|
const builtinMentionEnabled = onMentionTrigger === void 0 && mentionSources.length > 0;
|
|
2067
2655
|
const builtinPlusEnabled = onPlusMenu === void 0 && plusSources.length > 0;
|
|
2068
|
-
const [mentionState, setMentionState] = (0,
|
|
2069
|
-
const [plusAnchor, setPlusAnchor] = (0,
|
|
2070
|
-
const sourceCacheRef = (0,
|
|
2656
|
+
const [mentionState, setMentionState] = (0, import_react13.useState)(null);
|
|
2657
|
+
const [plusAnchor, setPlusAnchor] = (0, import_react13.useState)(null);
|
|
2658
|
+
const sourceCacheRef = (0, import_react13.useRef)(null);
|
|
2071
2659
|
if (sourceCacheRef.current === null) {
|
|
2072
2660
|
sourceCacheRef.current = /* @__PURE__ */ new Map();
|
|
2073
2661
|
}
|
|
@@ -2086,7 +2674,7 @@ function Composer({
|
|
|
2086
2674
|
setMentionState(null);
|
|
2087
2675
|
setPlusAnchor(null);
|
|
2088
2676
|
};
|
|
2089
|
-
(0,
|
|
2677
|
+
(0, import_react13.useLayoutEffect)(() => {
|
|
2090
2678
|
const input = inputRef.current;
|
|
2091
2679
|
if (input) {
|
|
2092
2680
|
input.style.height = "auto";
|
|
@@ -2101,9 +2689,9 @@ function Composer({
|
|
|
2101
2689
|
onSend?.(value);
|
|
2102
2690
|
setText("");
|
|
2103
2691
|
};
|
|
2104
|
-
const sendRef = (0,
|
|
2692
|
+
const sendRef = (0, import_react13.useRef)(send);
|
|
2105
2693
|
sendRef.current = send;
|
|
2106
|
-
(0,
|
|
2694
|
+
(0, import_react13.useLayoutEffect)(() => {
|
|
2107
2695
|
setChatChromeHandlers({ composerSubmit: () => sendRef.current() });
|
|
2108
2696
|
}, []);
|
|
2109
2697
|
const syncText = (value, caret, rect) => {
|
|
@@ -2161,7 +2749,7 @@ function Composer({
|
|
|
2161
2749
|
}
|
|
2162
2750
|
};
|
|
2163
2751
|
const showToolbar = !hideToolbar && (toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled);
|
|
2164
|
-
const fileInputNode = onAttachFiles ? /* @__PURE__ */ (0,
|
|
2752
|
+
const fileInputNode = onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2165
2753
|
"input",
|
|
2166
2754
|
{
|
|
2167
2755
|
ref: fileInputRef,
|
|
@@ -2177,14 +2765,14 @@ function Composer({
|
|
|
2177
2765
|
}
|
|
2178
2766
|
}
|
|
2179
2767
|
) : null;
|
|
2180
|
-
const popoverNodes = /* @__PURE__ */ (0,
|
|
2181
|
-
builtinMentionEnabled && mentionState && /* @__PURE__ */ (0,
|
|
2768
|
+
const popoverNodes = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2769
|
+
builtinMentionEnabled && mentionState && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2182
2770
|
AnchoredPopover,
|
|
2183
2771
|
{
|
|
2184
2772
|
anchorRect: mentionState.anchorRect,
|
|
2185
2773
|
onClose: () => setMentionState(null),
|
|
2186
2774
|
role: "listbox",
|
|
2187
|
-
children: /* @__PURE__ */ (0,
|
|
2775
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2188
2776
|
ContextSourceList,
|
|
2189
2777
|
{
|
|
2190
2778
|
sources: mentionSources,
|
|
@@ -2196,13 +2784,13 @@ function Composer({
|
|
|
2196
2784
|
)
|
|
2197
2785
|
}
|
|
2198
2786
|
),
|
|
2199
|
-
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ (0,
|
|
2787
|
+
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2200
2788
|
AnchoredPopover,
|
|
2201
2789
|
{
|
|
2202
2790
|
anchorRect: plusAnchor,
|
|
2203
2791
|
onClose: () => setPlusAnchor(null),
|
|
2204
2792
|
role: "listbox",
|
|
2205
|
-
children: /* @__PURE__ */ (0,
|
|
2793
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2206
2794
|
ContextSourceList,
|
|
2207
2795
|
{
|
|
2208
2796
|
sources: plusSources,
|
|
@@ -2215,13 +2803,13 @@ function Composer({
|
|
|
2215
2803
|
}
|
|
2216
2804
|
)
|
|
2217
2805
|
] });
|
|
2218
|
-
const fallback = /* @__PURE__ */ (0,
|
|
2806
|
+
const fallback = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2219
2807
|
"div",
|
|
2220
2808
|
{
|
|
2221
2809
|
className: `pactor-chat-composer${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
2222
2810
|
...dragHandlers,
|
|
2223
2811
|
children: [
|
|
2224
|
-
attachments !== void 0 && /* @__PURE__ */ (0,
|
|
2812
|
+
attachments !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2225
2813
|
ComposerAttachments,
|
|
2226
2814
|
{
|
|
2227
2815
|
attachments,
|
|
@@ -2229,7 +2817,7 @@ function Composer({
|
|
|
2229
2817
|
onClick: onAttachmentClick
|
|
2230
2818
|
}
|
|
2231
2819
|
),
|
|
2232
|
-
contextChips !== void 0 && /* @__PURE__ */ (0,
|
|
2820
|
+
contextChips !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2233
2821
|
ComposerContextChips,
|
|
2234
2822
|
{
|
|
2235
2823
|
chips: contextChips,
|
|
@@ -2240,8 +2828,8 @@ function Composer({
|
|
|
2240
2828
|
)
|
|
2241
2829
|
}
|
|
2242
2830
|
),
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2244
|
-
/* @__PURE__ */ (0,
|
|
2831
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pactor-chat-composer__row", children: [
|
|
2832
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2245
2833
|
"textarea",
|
|
2246
2834
|
{
|
|
2247
2835
|
ref: inputRef,
|
|
@@ -2273,7 +2861,7 @@ function Composer({
|
|
|
2273
2861
|
}
|
|
2274
2862
|
}
|
|
2275
2863
|
),
|
|
2276
|
-
hideToolbar ? null : /* @__PURE__ */ (0,
|
|
2864
|
+
hideToolbar ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2277
2865
|
"button",
|
|
2278
2866
|
{
|
|
2279
2867
|
type: "button",
|
|
@@ -2282,14 +2870,14 @@ function Composer({
|
|
|
2282
2870
|
"aria-label": streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
2283
2871
|
disabled: streaming ? false : disabled || !text.trim(),
|
|
2284
2872
|
onClick: streaming ? onStop : send,
|
|
2285
|
-
children: streaming ? /* @__PURE__ */ (0,
|
|
2873
|
+
children: streaming ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components8.Icon, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components8.Icon, { name: "arrow-up", size: 16 })
|
|
2286
2874
|
}
|
|
2287
2875
|
)
|
|
2288
2876
|
] }),
|
|
2289
|
-
showToolbar && /* @__PURE__ */ (0,
|
|
2877
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pactor-chat-composer__toolbar", children: [
|
|
2290
2878
|
toolbarStart,
|
|
2291
|
-
/* @__PURE__ */ (0,
|
|
2292
|
-
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ (0,
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "pactor-chat-composer__toolbar-spacer" }),
|
|
2880
|
+
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2293
2881
|
"button",
|
|
2294
2882
|
{
|
|
2295
2883
|
ref: plusButtonRef,
|
|
@@ -2305,10 +2893,10 @@ function Composer({
|
|
|
2305
2893
|
setPlusAnchor(rect);
|
|
2306
2894
|
}
|
|
2307
2895
|
},
|
|
2308
|
-
children: /* @__PURE__ */ (0,
|
|
2896
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components8.Icon, { name: "plus", size: 14 })
|
|
2309
2897
|
}
|
|
2310
2898
|
),
|
|
2311
|
-
onAttachFiles && /* @__PURE__ */ (0,
|
|
2899
|
+
onAttachFiles && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2312
2900
|
"button",
|
|
2313
2901
|
{
|
|
2314
2902
|
type: "button",
|
|
@@ -2316,10 +2904,10 @@ function Composer({
|
|
|
2316
2904
|
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
2317
2905
|
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
2318
2906
|
onClick: () => fileInputRef.current?.click(),
|
|
2319
|
-
children: /* @__PURE__ */ (0,
|
|
2907
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components8.Icon, { name: "paperclip", size: 14 })
|
|
2320
2908
|
}
|
|
2321
2909
|
),
|
|
2322
|
-
modelChipEnabled && /* @__PURE__ */ (0,
|
|
2910
|
+
modelChipEnabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2323
2911
|
ModelSelect,
|
|
2324
2912
|
{
|
|
2325
2913
|
models,
|
|
@@ -2329,7 +2917,7 @@ function Composer({
|
|
|
2329
2917
|
),
|
|
2330
2918
|
toolbarEnd
|
|
2331
2919
|
] }),
|
|
2332
|
-
composerFooter !== void 0 && composerFooter !== null ? /* @__PURE__ */ (0,
|
|
2920
|
+
composerFooter !== void 0 && composerFooter !== null ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pactor-chat-composer__footer", children: composerFooter }) : null,
|
|
2333
2921
|
fileInputNode,
|
|
2334
2922
|
popoverNodes
|
|
2335
2923
|
]
|
|
@@ -2368,7 +2956,7 @@ function Composer({
|
|
|
2368
2956
|
),
|
|
2369
2957
|
modelChange: onModelChange
|
|
2370
2958
|
};
|
|
2371
|
-
return /* @__PURE__ */ (0,
|
|
2959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2372
2960
|
ChromeSlot,
|
|
2373
2961
|
{
|
|
2374
2962
|
fragment: buildComposerFragment({
|
|
@@ -2379,7 +2967,7 @@ function Composer({
|
|
|
2379
2967
|
}),
|
|
2380
2968
|
components: COMPOSER_INTERNAL_COMPONENTS,
|
|
2381
2969
|
fallback,
|
|
2382
|
-
wrap: (children) => /* @__PURE__ */ (0,
|
|
2970
|
+
wrap: (children) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComposerBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2383
2971
|
"div",
|
|
2384
2972
|
{
|
|
2385
2973
|
className: `pactor-chat-composer pactor-chat-composer--dsl${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
@@ -2467,7 +3055,7 @@ function buildEmptyStateFragment(props) {
|
|
|
2467
3055
|
}
|
|
2468
3056
|
|
|
2469
3057
|
// src/view/EmptyState.tsx
|
|
2470
|
-
var
|
|
3058
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2471
3059
|
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2472
3060
|
function suggestionLabel2(suggestion) {
|
|
2473
3061
|
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
@@ -2481,10 +3069,10 @@ function EmptyStateFallback({
|
|
|
2481
3069
|
onSuggestionClick,
|
|
2482
3070
|
greeting
|
|
2483
3071
|
}) {
|
|
2484
|
-
return /* @__PURE__ */ (0,
|
|
2485
|
-
/* @__PURE__ */ (0,
|
|
2486
|
-
subtitle && /* @__PURE__ */ (0,
|
|
2487
|
-
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0,
|
|
3072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-empty__greeting", children: greeting }),
|
|
3074
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-empty__subtitle", children: subtitle }),
|
|
3075
|
+
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-empty__suggestions", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2488
3076
|
"button",
|
|
2489
3077
|
{
|
|
2490
3078
|
type: "button",
|
|
@@ -2502,11 +3090,11 @@ function EmptyState({
|
|
|
2502
3090
|
suggestions,
|
|
2503
3091
|
onSuggestionClick
|
|
2504
3092
|
}) {
|
|
2505
|
-
return /* @__PURE__ */ (0,
|
|
3093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-empty", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2506
3094
|
ChromeSlot,
|
|
2507
3095
|
{
|
|
2508
3096
|
fragment: buildEmptyStateFragment({ greeting, subtitle, suggestions }),
|
|
2509
|
-
fallback: /* @__PURE__ */ (0,
|
|
3097
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2510
3098
|
EmptyStateFallback,
|
|
2511
3099
|
{
|
|
2512
3100
|
greeting,
|
|
@@ -2520,16 +3108,20 @@ function EmptyState({
|
|
|
2520
3108
|
}
|
|
2521
3109
|
|
|
2522
3110
|
// src/view/MessageBubble.tsx
|
|
2523
|
-
var
|
|
3111
|
+
var import_react16 = require("react");
|
|
2524
3112
|
|
|
2525
3113
|
// src/view/ActivityTrace.tsx
|
|
2526
|
-
var
|
|
3114
|
+
var import_components9 = require("@pactor-app/ui/components");
|
|
2527
3115
|
var import_markdown3 = require("@pactor-app/markdown");
|
|
2528
|
-
var
|
|
2529
|
-
var
|
|
3116
|
+
var import_react14 = require("react");
|
|
3117
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2530
3118
|
function usePinnedCollapse(autoOpen) {
|
|
2531
|
-
const [state, setState] = (0,
|
|
2532
|
-
const
|
|
3119
|
+
const [state, setState] = (0, import_react14.useState)("auto");
|
|
3120
|
+
const autoCollapsedRef = (0, import_react14.useRef)(false);
|
|
3121
|
+
if (state === "auto" && !autoOpen) {
|
|
3122
|
+
autoCollapsedRef.current = true;
|
|
3123
|
+
}
|
|
3124
|
+
const open = state === "auto" ? autoOpen && !autoCollapsedRef.current : state === "pinned-open";
|
|
2533
3125
|
const toggle = () => {
|
|
2534
3126
|
setState(open ? "pinned-closed" : "pinned-open");
|
|
2535
3127
|
};
|
|
@@ -2554,8 +3146,8 @@ function statusText(message, mode, toolCount) {
|
|
|
2554
3146
|
}
|
|
2555
3147
|
function useElapsedSeconds(startedAt, active) {
|
|
2556
3148
|
const compute = () => Math.max(0, Math.floor((Date.now() - startedAt) / 1e3));
|
|
2557
|
-
const [elapsed, setElapsed] = (0,
|
|
2558
|
-
(0,
|
|
3149
|
+
const [elapsed, setElapsed] = (0, import_react14.useState)(compute);
|
|
3150
|
+
(0, import_react14.useEffect)(() => {
|
|
2559
3151
|
if (!active) {
|
|
2560
3152
|
setElapsed(compute());
|
|
2561
3153
|
return;
|
|
@@ -2569,15 +3161,15 @@ function useElapsedSeconds(startedAt, active) {
|
|
|
2569
3161
|
}
|
|
2570
3162
|
function TraceStatusIcon({ status }) {
|
|
2571
3163
|
if (status === "running") {
|
|
2572
|
-
return /* @__PURE__ */ (0,
|
|
3164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" });
|
|
2573
3165
|
}
|
|
2574
3166
|
if (status === "success") {
|
|
2575
|
-
return /* @__PURE__ */ (0,
|
|
3167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "check-circle", size: 13 });
|
|
2576
3168
|
}
|
|
2577
3169
|
if (status === "failed") {
|
|
2578
|
-
return /* @__PURE__ */ (0,
|
|
3170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "x-circle", size: 13 });
|
|
2579
3171
|
}
|
|
2580
|
-
return /* @__PURE__ */ (0,
|
|
3172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "clock", size: 13 });
|
|
2581
3173
|
}
|
|
2582
3174
|
function summarizeArgs(args) {
|
|
2583
3175
|
if (args === void 0) {
|
|
@@ -2606,16 +3198,16 @@ function formatDetail(value) {
|
|
|
2606
3198
|
}
|
|
2607
3199
|
}
|
|
2608
3200
|
function TraceRow({ entry }) {
|
|
2609
|
-
const [open, setOpen] = (0,
|
|
3201
|
+
const [open, setOpen] = (0, import_react14.useState)(false);
|
|
2610
3202
|
const summary = summarizeArgs(entry.args);
|
|
2611
|
-
return /* @__PURE__ */ (0,
|
|
3203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2612
3204
|
"div",
|
|
2613
3205
|
{
|
|
2614
3206
|
className: "pactor-chat-trace__entry",
|
|
2615
3207
|
"data-status": entry.status,
|
|
2616
3208
|
"data-open": open,
|
|
2617
3209
|
children: [
|
|
2618
|
-
/* @__PURE__ */ (0,
|
|
3210
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2619
3211
|
"button",
|
|
2620
3212
|
{
|
|
2621
3213
|
type: "button",
|
|
@@ -2623,16 +3215,16 @@ function TraceRow({ entry }) {
|
|
|
2623
3215
|
"aria-expanded": open,
|
|
2624
3216
|
onClick: () => setOpen((value) => !value),
|
|
2625
3217
|
children: [
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2627
|
-
/* @__PURE__ */ (0,
|
|
2628
|
-
/* @__PURE__ */ (0,
|
|
2629
|
-
summary && /* @__PURE__ */ (0,
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "chevron-right", size: 12 }) }),
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__entry-icon", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TraceStatusIcon, { status: entry.status }) }),
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__entry-title", children: entry.title ?? entry.name }),
|
|
3221
|
+
summary && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__entry-args", children: summary })
|
|
2630
3222
|
]
|
|
2631
3223
|
}
|
|
2632
3224
|
),
|
|
2633
|
-
open && /* @__PURE__ */ (0,
|
|
2634
|
-
entry.args !== void 0 && /* @__PURE__ */ (0,
|
|
2635
|
-
/* @__PURE__ */ (0,
|
|
3225
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "pactor-chat-trace__entry-body", children: [
|
|
3226
|
+
entry.args !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "pactor-chat-trace__entry-detail", children: formatDetail(entry.args) }),
|
|
3227
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "pactor-chat-trace__entry-detail", children: entry.status === "failed" ? entry.error ?? "\u6267\u884C\u5931\u8D25" : formatDetail(entry.result) })
|
|
2636
3228
|
] })
|
|
2637
3229
|
]
|
|
2638
3230
|
}
|
|
@@ -2645,14 +3237,14 @@ function ThinkingCard({
|
|
|
2645
3237
|
const partStreaming = part.status === "streaming";
|
|
2646
3238
|
const shown = useThrottledValue(part.content, 120, partStreaming);
|
|
2647
3239
|
const { open, toggle } = usePinnedCollapse(partStreaming && !answerPhase);
|
|
2648
|
-
return /* @__PURE__ */ (0,
|
|
3240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2649
3241
|
"div",
|
|
2650
3242
|
{
|
|
2651
3243
|
className: "pactor-chat-thinking",
|
|
2652
3244
|
"data-open": open,
|
|
2653
3245
|
"data-streaming": partStreaming,
|
|
2654
3246
|
children: [
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
3247
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2656
3248
|
"button",
|
|
2657
3249
|
{
|
|
2658
3250
|
type: "button",
|
|
@@ -2660,13 +3252,13 @@ function ThinkingCard({
|
|
|
2660
3252
|
"aria-expanded": open,
|
|
2661
3253
|
onClick: toggle,
|
|
2662
3254
|
children: [
|
|
2663
|
-
/* @__PURE__ */ (0,
|
|
2664
|
-
/* @__PURE__ */ (0,
|
|
2665
|
-
/* @__PURE__ */ (0,
|
|
3255
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "chevron-right", size: 12 }) }),
|
|
3256
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-thinking__icon", children: partStreaming ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "brain", size: 13 }) }),
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "\u601D\u8003\u8FC7\u7A0B" })
|
|
2666
3258
|
]
|
|
2667
3259
|
}
|
|
2668
3260
|
),
|
|
2669
|
-
open && /* @__PURE__ */ (0,
|
|
3261
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pactor-chat-thinking__body", children: partStreaming ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pactor-chat-thinking__text", children: shown }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_markdown3.MarkdownRenderer, { content: part.content }) })
|
|
2670
3262
|
]
|
|
2671
3263
|
}
|
|
2672
3264
|
);
|
|
@@ -2681,7 +3273,7 @@ function ActivityTrace({ message }) {
|
|
|
2681
3273
|
const answerPhase = mode === "responding" || !streaming;
|
|
2682
3274
|
const { open, toggle } = usePinnedCollapse(!answerPhase);
|
|
2683
3275
|
const collapsible = entries.length > 0 || thinkingParts.length > 0;
|
|
2684
|
-
const mountTimeRef = (0,
|
|
3276
|
+
const mountTimeRef = (0, import_react14.useRef)(0);
|
|
2685
3277
|
if (mountTimeRef.current === 0) {
|
|
2686
3278
|
mountTimeRef.current = Date.now();
|
|
2687
3279
|
}
|
|
@@ -2689,23 +3281,23 @@ function ActivityTrace({ message }) {
|
|
|
2689
3281
|
message.createdAt ?? mountTimeRef.current,
|
|
2690
3282
|
streaming
|
|
2691
3283
|
);
|
|
2692
|
-
const header = /* @__PURE__ */ (0,
|
|
2693
|
-
/* @__PURE__ */ (0,
|
|
2694
|
-
/* @__PURE__ */ (0,
|
|
3284
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__status-icon", children: streaming ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "check-circle", size: 13 }) }),
|
|
3286
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2695
3287
|
"span",
|
|
2696
3288
|
{
|
|
2697
3289
|
className: `pactor-chat-trace__status-text${streaming ? " pactor-chat-trace__status-text--breathing" : ""}`,
|
|
2698
3290
|
children: statusText(message, mode, entries.length)
|
|
2699
3291
|
}
|
|
2700
3292
|
),
|
|
2701
|
-
/* @__PURE__ */ (0,
|
|
3293
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "pactor-chat-trace__elapsed", children: [
|
|
2702
3294
|
elapsed,
|
|
2703
3295
|
"s"
|
|
2704
3296
|
] }),
|
|
2705
|
-
collapsible && /* @__PURE__ */ (0,
|
|
3297
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "chevron-right", size: 12 }) })
|
|
2706
3298
|
] });
|
|
2707
|
-
return /* @__PURE__ */ (0,
|
|
2708
|
-
collapsible ? /* @__PURE__ */ (0,
|
|
3299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "pactor-chat-trace", "data-open": open, children: [
|
|
3300
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2709
3301
|
"button",
|
|
2710
3302
|
{
|
|
2711
3303
|
type: "button",
|
|
@@ -2714,10 +3306,10 @@ function ActivityTrace({ message }) {
|
|
|
2714
3306
|
onClick: toggle,
|
|
2715
3307
|
children: header
|
|
2716
3308
|
}
|
|
2717
|
-
) : /* @__PURE__ */ (0,
|
|
2718
|
-
open && /* @__PURE__ */ (0,
|
|
2719
|
-
entries.length > 0 && /* @__PURE__ */ (0,
|
|
2720
|
-
thinkingParts.map((part, index) => /* @__PURE__ */ (0,
|
|
3309
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pactor-chat-trace__header", children: header }),
|
|
3310
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3311
|
+
entries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pactor-chat-trace__entries", children: entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TraceRow, { entry }, entry.callIndex)) }),
|
|
3312
|
+
thinkingParts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2721
3313
|
ThinkingCard,
|
|
2722
3314
|
{
|
|
2723
3315
|
part,
|
|
@@ -2730,8 +3322,8 @@ function ActivityTrace({ message }) {
|
|
|
2730
3322
|
}
|
|
2731
3323
|
|
|
2732
3324
|
// src/view/MessageActions.tsx
|
|
2733
|
-
var
|
|
2734
|
-
var
|
|
3325
|
+
var import_components10 = require("@pactor-app/ui/components");
|
|
3326
|
+
var import_react15 = require("react");
|
|
2735
3327
|
|
|
2736
3328
|
// src/view/chrome/message-actions.tsx
|
|
2737
3329
|
function buildMessageActionsFragment(args) {
|
|
@@ -2784,7 +3376,7 @@ function buildMessageActionsFragment(args) {
|
|
|
2784
3376
|
}
|
|
2785
3377
|
|
|
2786
3378
|
// src/view/MessageActions.tsx
|
|
2787
|
-
var
|
|
3379
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2788
3380
|
var BUILTIN_ACTION_DEFAULTS = {
|
|
2789
3381
|
copy: {
|
|
2790
3382
|
label: "\u590D\u5236",
|
|
@@ -2857,13 +3449,13 @@ function MessageActions({
|
|
|
2857
3449
|
callService,
|
|
2858
3450
|
onMessageAction
|
|
2859
3451
|
}) {
|
|
2860
|
-
const [copied, setCopied] = (0,
|
|
2861
|
-
const dispatchRef = (0,
|
|
3452
|
+
const [copied, setCopied] = (0, import_react15.useState)(false);
|
|
3453
|
+
const dispatchRef = (0, import_react15.useRef)(
|
|
2862
3454
|
() => {
|
|
2863
3455
|
}
|
|
2864
3456
|
);
|
|
2865
|
-
const visibleActionsRef = (0,
|
|
2866
|
-
(0,
|
|
3457
|
+
const visibleActionsRef = (0, import_react15.useRef)([]);
|
|
3458
|
+
(0, import_react15.useEffect)(() => {
|
|
2867
3459
|
setMessageActionDispatcher(message.id, (actionId) => {
|
|
2868
3460
|
const action = visibleActionsRef.current.find((a) => a.id === actionId);
|
|
2869
3461
|
if (action) {
|
|
@@ -2937,7 +3529,7 @@ function MessageActions({
|
|
|
2937
3529
|
const copiedFeedback = action.builtin === "copy" && copied;
|
|
2938
3530
|
const label = copiedFeedback ? "\u5DF2\u590D\u5236" : action.label;
|
|
2939
3531
|
const iconName = copiedFeedback ? "check" : action.icon;
|
|
2940
|
-
return /* @__PURE__ */ (0,
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2941
3533
|
"button",
|
|
2942
3534
|
{
|
|
2943
3535
|
type: "button",
|
|
@@ -2946,16 +3538,16 @@ function MessageActions({
|
|
|
2946
3538
|
"aria-label": label,
|
|
2947
3539
|
"data-message-action": action.id,
|
|
2948
3540
|
onClick: () => dispatch(action),
|
|
2949
|
-
children: iconName !== void 0 ? /* @__PURE__ */ (0,
|
|
3541
|
+
children: iconName !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_components10.Icon, { name: iconName, size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_components10.Icon, { name: "help-circle", size: 14 })
|
|
2950
3542
|
},
|
|
2951
3543
|
action.id
|
|
2952
3544
|
);
|
|
2953
3545
|
});
|
|
2954
|
-
return /* @__PURE__ */ (0,
|
|
3546
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2955
3547
|
"div",
|
|
2956
3548
|
{
|
|
2957
3549
|
className: `pactor-chat-message__actions${forceVisible ? " pactor-chat-message__actions--visible" : ""}`,
|
|
2958
|
-
children: /* @__PURE__ */ (0,
|
|
3550
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2959
3551
|
ChromeSlot,
|
|
2960
3552
|
{
|
|
2961
3553
|
fragment: buildMessageActionsFragment({
|
|
@@ -2971,13 +3563,38 @@ function MessageActions({
|
|
|
2971
3563
|
}
|
|
2972
3564
|
|
|
2973
3565
|
// src/view/MessageBubble.tsx
|
|
2974
|
-
var
|
|
3566
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3567
|
+
function groupArtifactParts(parts) {
|
|
3568
|
+
const segments = [];
|
|
3569
|
+
for (const part of parts) {
|
|
3570
|
+
if (part.type === "artifact" && part.artifact) {
|
|
3571
|
+
const last = segments[segments.length - 1];
|
|
3572
|
+
if (Array.isArray(last)) {
|
|
3573
|
+
last.push(part.artifact);
|
|
3574
|
+
} else {
|
|
3575
|
+
segments.push([part.artifact]);
|
|
3576
|
+
}
|
|
3577
|
+
} else {
|
|
3578
|
+
segments.push(part);
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
return segments;
|
|
3582
|
+
}
|
|
3583
|
+
function formatMessageTime(ts, now = Date.now()) {
|
|
3584
|
+
const date = new Date(ts);
|
|
3585
|
+
const hh = String(date.getHours()).padStart(2, "0");
|
|
3586
|
+
const mm = String(date.getMinutes()).padStart(2, "0");
|
|
3587
|
+
if (new Date(now).toDateString() === date.toDateString()) {
|
|
3588
|
+
return `${hh}:${mm}`;
|
|
3589
|
+
}
|
|
3590
|
+
return `${date.getMonth() + 1}\u6708${date.getDate()}\u65E5 ${hh}:${mm}`;
|
|
3591
|
+
}
|
|
2975
3592
|
function MessageEditForm({
|
|
2976
3593
|
initialText,
|
|
2977
3594
|
onConfirm,
|
|
2978
3595
|
onCancel
|
|
2979
3596
|
}) {
|
|
2980
|
-
const [text, setText] = (0,
|
|
3597
|
+
const [text, setText] = (0, import_react16.useState)(initialText);
|
|
2981
3598
|
const confirm = () => {
|
|
2982
3599
|
const value = text.trim();
|
|
2983
3600
|
if (!value) {
|
|
@@ -2985,8 +3602,8 @@ function MessageEditForm({
|
|
|
2985
3602
|
}
|
|
2986
3603
|
onConfirm(value);
|
|
2987
3604
|
};
|
|
2988
|
-
return /* @__PURE__ */ (0,
|
|
2989
|
-
/* @__PURE__ */ (0,
|
|
3605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__edit", children: [
|
|
3606
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2990
3607
|
"textarea",
|
|
2991
3608
|
{
|
|
2992
3609
|
className: "pactor-chat-message__edit-input",
|
|
@@ -3004,8 +3621,8 @@ function MessageEditForm({
|
|
|
3004
3621
|
}
|
|
3005
3622
|
}
|
|
3006
3623
|
),
|
|
3007
|
-
/* @__PURE__ */ (0,
|
|
3008
|
-
/* @__PURE__ */ (0,
|
|
3624
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__edit-actions", children: [
|
|
3625
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3009
3626
|
"button",
|
|
3010
3627
|
{
|
|
3011
3628
|
type: "button",
|
|
@@ -3015,7 +3632,7 @@ function MessageEditForm({
|
|
|
3015
3632
|
children: "\u53D1\u9001"
|
|
3016
3633
|
}
|
|
3017
3634
|
),
|
|
3018
|
-
/* @__PURE__ */ (0,
|
|
3635
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3019
3636
|
"button",
|
|
3020
3637
|
{
|
|
3021
3638
|
type: "button",
|
|
@@ -3038,10 +3655,9 @@ function MessageBubble({
|
|
|
3038
3655
|
onEditResend,
|
|
3039
3656
|
messageActions,
|
|
3040
3657
|
callService,
|
|
3041
|
-
onMessageAction
|
|
3042
|
-
onOpenArtifact
|
|
3658
|
+
onMessageAction
|
|
3043
3659
|
}) {
|
|
3044
|
-
const [editing, setEditing] = (0,
|
|
3660
|
+
const [editing, setEditing] = (0, import_react16.useState)(false);
|
|
3045
3661
|
const bubbleScope = {
|
|
3046
3662
|
conversation: scope?.conversation ?? {},
|
|
3047
3663
|
message: { id: message.id },
|
|
@@ -3049,21 +3665,22 @@ function MessageBubble({
|
|
|
3049
3665
|
};
|
|
3050
3666
|
const streaming = message.status === "streaming";
|
|
3051
3667
|
const live = message.status === "pending" || message.status === "streaming";
|
|
3052
|
-
const wasLiveRef = (0,
|
|
3668
|
+
const wasLiveRef = (0, import_react16.useRef)(live);
|
|
3053
3669
|
if (live) {
|
|
3054
3670
|
wasLiveRef.current = true;
|
|
3055
3671
|
}
|
|
3056
3672
|
const showTrace = message.role === "assistant" && (wasLiveRef.current || message.parts.some(
|
|
3057
3673
|
(part) => part.type === "thinking" || part.type === "tool-call" || part.type === "tool-result"
|
|
3058
3674
|
));
|
|
3059
|
-
|
|
3675
|
+
const showTime = message.role === "assistant" && !live && message.createdAt !== void 0;
|
|
3676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3060
3677
|
"div",
|
|
3061
3678
|
{
|
|
3062
3679
|
className: `pactor-chat-message pactor-chat-message--${message.role}`,
|
|
3063
3680
|
"data-message-id": message.id,
|
|
3064
3681
|
"data-message-status": message.status,
|
|
3065
3682
|
children: [
|
|
3066
|
-
editing ? /* @__PURE__ */ (0,
|
|
3683
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3067
3684
|
MessageEditForm,
|
|
3068
3685
|
{
|
|
3069
3686
|
initialText: collectMessageText(message),
|
|
@@ -3073,21 +3690,53 @@ function MessageBubble({
|
|
|
3073
3690
|
},
|
|
3074
3691
|
onCancel: () => setEditing(false)
|
|
3075
3692
|
}
|
|
3076
|
-
) : /* @__PURE__ */ (0,
|
|
3077
|
-
showTrace && /* @__PURE__ */ (0,
|
|
3078
|
-
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ (0,
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3693
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__body", children: [
|
|
3694
|
+
showTrace && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ActivityTrace, { message }),
|
|
3695
|
+
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "pactor-chat-message__pending", children: "\u2026" }) : groupArtifactParts(message.parts).map(
|
|
3696
|
+
(segment, index) => Array.isArray(segment) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3697
|
+
ChromeSlot,
|
|
3698
|
+
{
|
|
3699
|
+
fragment: buildArtifactCardGroupFragment(segment),
|
|
3700
|
+
components: ARTIFACT_CARD_INTERNAL_COMPONENTS,
|
|
3701
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChatArtifactCardGroup, { artifacts: segment })
|
|
3702
|
+
},
|
|
3703
|
+
`artifacts:${segment[0].id}`
|
|
3704
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3705
|
+
PartRenderer,
|
|
3706
|
+
{
|
|
3707
|
+
part: segment,
|
|
3708
|
+
runtime,
|
|
3709
|
+
scope: bubbleScope,
|
|
3710
|
+
streaming
|
|
3711
|
+
},
|
|
3712
|
+
segment.id ?? index
|
|
3713
|
+
)
|
|
3714
|
+
)
|
|
3089
3715
|
] }),
|
|
3090
|
-
!editing && /* @__PURE__ */ (0,
|
|
3716
|
+
!editing && (showTime ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__footer", children: [
|
|
3717
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3718
|
+
MessageActions,
|
|
3719
|
+
{
|
|
3720
|
+
message,
|
|
3721
|
+
actions: messageActions,
|
|
3722
|
+
showRegenerate,
|
|
3723
|
+
onRegenerate,
|
|
3724
|
+
onRetry,
|
|
3725
|
+
onEdit: onEditResend ? () => setEditing(true) : void 0,
|
|
3726
|
+
forceVisible: message.status === "error",
|
|
3727
|
+
callService,
|
|
3728
|
+
onMessageAction
|
|
3729
|
+
}
|
|
3730
|
+
),
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3732
|
+
"span",
|
|
3733
|
+
{
|
|
3734
|
+
className: "pactor-chat-message__time",
|
|
3735
|
+
title: new Date(message.createdAt).toLocaleString(),
|
|
3736
|
+
children: formatMessageTime(message.createdAt)
|
|
3737
|
+
}
|
|
3738
|
+
)
|
|
3739
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3091
3740
|
MessageActions,
|
|
3092
3741
|
{
|
|
3093
3742
|
message,
|
|
@@ -3100,14 +3749,14 @@ function MessageBubble({
|
|
|
3100
3749
|
callService,
|
|
3101
3750
|
onMessageAction
|
|
3102
3751
|
}
|
|
3103
|
-
)
|
|
3752
|
+
))
|
|
3104
3753
|
]
|
|
3105
3754
|
}
|
|
3106
3755
|
);
|
|
3107
3756
|
}
|
|
3108
3757
|
|
|
3109
3758
|
// src/view/ChatView.tsx
|
|
3110
|
-
var
|
|
3759
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3111
3760
|
function lastContentLength(messages) {
|
|
3112
3761
|
const last = messages[messages.length - 1];
|
|
3113
3762
|
if (!last) {
|
|
@@ -3135,6 +3784,7 @@ function ChatView({
|
|
|
3135
3784
|
className,
|
|
3136
3785
|
onArtifact,
|
|
3137
3786
|
onOpenArtifact,
|
|
3787
|
+
onOpenArtifactList,
|
|
3138
3788
|
attachments,
|
|
3139
3789
|
onAttachmentsChange,
|
|
3140
3790
|
onAttachFiles,
|
|
@@ -3156,14 +3806,14 @@ function ChatView({
|
|
|
3156
3806
|
onMessageAction,
|
|
3157
3807
|
composerBottom
|
|
3158
3808
|
}) {
|
|
3159
|
-
const messages = (0,
|
|
3809
|
+
const messages = (0, import_react17.useSyncExternalStore)(
|
|
3160
3810
|
(listener) => store.subscribe(listener),
|
|
3161
3811
|
() => store.getMessages()
|
|
3162
3812
|
);
|
|
3163
3813
|
const isStreaming = messages.some(
|
|
3164
3814
|
(message) => message.status === "pending" || message.status === "streaming"
|
|
3165
3815
|
);
|
|
3166
|
-
const runtime = (0,
|
|
3816
|
+
const runtime = (0, import_react17.useMemo)(() => {
|
|
3167
3817
|
if (!safeRegistry) {
|
|
3168
3818
|
return void 0;
|
|
3169
3819
|
}
|
|
@@ -3180,12 +3830,12 @@ function ChatView({
|
|
|
3180
3830
|
user
|
|
3181
3831
|
});
|
|
3182
3832
|
}, [safeRegistry, capabilities, permission, confirm, user]);
|
|
3183
|
-
const scope = (0,
|
|
3833
|
+
const scope = (0, import_react17.useMemo)(
|
|
3184
3834
|
() => ({ conversation: { id: conversationId }, params }),
|
|
3185
3835
|
[conversationId, params]
|
|
3186
3836
|
);
|
|
3187
|
-
const notifiedArtifactsRef = (0,
|
|
3188
|
-
(0,
|
|
3837
|
+
const notifiedArtifactsRef = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
|
|
3838
|
+
(0, import_react17.useEffect)(() => {
|
|
3189
3839
|
if (!onArtifact) {
|
|
3190
3840
|
return;
|
|
3191
3841
|
}
|
|
@@ -3204,7 +3854,7 @@ function ChatView({
|
|
|
3204
3854
|
});
|
|
3205
3855
|
}
|
|
3206
3856
|
}, [messages, onArtifact]);
|
|
3207
|
-
const abortRef = (0,
|
|
3857
|
+
const abortRef = (0, import_react17.useRef)(null);
|
|
3208
3858
|
const { containerRef, isFollowing, scrollToBottom } = useChatAutoScroll({
|
|
3209
3859
|
messageCount: messages.length,
|
|
3210
3860
|
lastContentLength: lastContentLength(messages),
|
|
@@ -3215,7 +3865,7 @@ function ChatView({
|
|
|
3215
3865
|
model,
|
|
3216
3866
|
onModelChange
|
|
3217
3867
|
});
|
|
3218
|
-
const [contextChips, setContextChips] = (0,
|
|
3868
|
+
const [contextChips, setContextChips] = (0, import_react17.useState)([]);
|
|
3219
3869
|
const handleContextChipsChange = (chips) => {
|
|
3220
3870
|
setContextChips(chips);
|
|
3221
3871
|
onContextsChange?.(chips);
|
|
@@ -3247,14 +3897,17 @@ function ChatView({
|
|
|
3247
3897
|
abortRef.current?.abort();
|
|
3248
3898
|
abortRef.current = null;
|
|
3249
3899
|
};
|
|
3250
|
-
const handleSendRef = (0,
|
|
3900
|
+
const handleSendRef = (0, import_react17.useRef)(handleSend);
|
|
3251
3901
|
handleSendRef.current = handleSend;
|
|
3252
|
-
const onOpenArtifactRef = (0,
|
|
3902
|
+
const onOpenArtifactRef = (0, import_react17.useRef)(onOpenArtifact);
|
|
3253
3903
|
onOpenArtifactRef.current = onOpenArtifact;
|
|
3254
|
-
(0,
|
|
3904
|
+
const onOpenArtifactListRef = (0, import_react17.useRef)(onOpenArtifactList);
|
|
3905
|
+
onOpenArtifactListRef.current = onOpenArtifactList;
|
|
3906
|
+
(0, import_react17.useEffect)(() => {
|
|
3255
3907
|
setChatChromeHandlers({
|
|
3256
3908
|
sendSuggestion: (text) => handleSendRef.current(text),
|
|
3257
|
-
openArtifact: (artifact) => onOpenArtifactRef.current?.(artifact)
|
|
3909
|
+
openArtifact: (artifact) => onOpenArtifactRef.current?.(artifact),
|
|
3910
|
+
openArtifactList: () => onOpenArtifactListRef.current?.()
|
|
3258
3911
|
});
|
|
3259
3912
|
}, []);
|
|
3260
3913
|
const handleRegenerate = () => {
|
|
@@ -3274,7 +3927,7 @@ function ChatView({
|
|
|
3274
3927
|
const lastMessage = messages[messages.length - 1];
|
|
3275
3928
|
const regenerableMessageId = lastMessage?.role === "assistant" && lastMessage.status === "completed" ? lastMessage.id : void 0;
|
|
3276
3929
|
const isEmpty = messages.length === 0;
|
|
3277
|
-
const composerNode = /* @__PURE__ */ (0,
|
|
3930
|
+
const composerNode = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3278
3931
|
Composer,
|
|
3279
3932
|
{
|
|
3280
3933
|
onSend: handleSend,
|
|
@@ -3299,18 +3952,18 @@ function ChatView({
|
|
|
3299
3952
|
callService
|
|
3300
3953
|
}
|
|
3301
3954
|
);
|
|
3302
|
-
const composerDock = /* @__PURE__ */ (0,
|
|
3955
|
+
const composerDock = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pactor-chat-view__composer-dock", children: [
|
|
3303
3956
|
composerNode,
|
|
3304
|
-
composerBottom !== void 0 && composerBottom !== null ? /* @__PURE__ */ (0,
|
|
3957
|
+
composerBottom !== void 0 && composerBottom !== null ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pactor-chat-view__composer-bottom", children: composerBottom }) : null
|
|
3305
3958
|
] });
|
|
3306
|
-
return /* @__PURE__ */ (0,
|
|
3959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3307
3960
|
"div",
|
|
3308
3961
|
{
|
|
3309
3962
|
className: `pactor-chat-view${isEmpty ? " pactor-chat-view--empty" : ""}${className ? ` ${className}` : ""}`,
|
|
3310
3963
|
children: [
|
|
3311
|
-
/* @__PURE__ */ (0,
|
|
3312
|
-
isEmpty ? /* @__PURE__ */ (0,
|
|
3313
|
-
/* @__PURE__ */ (0,
|
|
3964
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pactor-chat-messages", ref: containerRef, children: [
|
|
3965
|
+
isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pactor-chat-view__empty-stack", children: [
|
|
3966
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3314
3967
|
EmptyState,
|
|
3315
3968
|
{
|
|
3316
3969
|
greeting,
|
|
@@ -3320,7 +3973,7 @@ function ChatView({
|
|
|
3320
3973
|
}
|
|
3321
3974
|
),
|
|
3322
3975
|
composerDock
|
|
3323
|
-
] }) : messages.map((message) => /* @__PURE__ */ (0,
|
|
3976
|
+
] }) : messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3324
3977
|
MessageBubble,
|
|
3325
3978
|
{
|
|
3326
3979
|
message,
|
|
@@ -3332,19 +3985,18 @@ function ChatView({
|
|
|
3332
3985
|
onEditResend: (text) => handleEditResend(message.id, text),
|
|
3333
3986
|
messageActions,
|
|
3334
3987
|
callService,
|
|
3335
|
-
onMessageAction
|
|
3336
|
-
onOpenArtifact
|
|
3988
|
+
onMessageAction
|
|
3337
3989
|
},
|
|
3338
3990
|
message.id
|
|
3339
3991
|
)),
|
|
3340
|
-
!isFollowing && /* @__PURE__ */ (0,
|
|
3992
|
+
!isFollowing && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3341
3993
|
"button",
|
|
3342
3994
|
{
|
|
3343
3995
|
type: "button",
|
|
3344
3996
|
className: "pactor-chat-scroll-bottom",
|
|
3345
3997
|
onClick: scrollToBottom,
|
|
3346
3998
|
children: [
|
|
3347
|
-
/* @__PURE__ */ (0,
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "arrow-down", size: 13 }),
|
|
3348
4000
|
"\u56DE\u5230\u5E95\u90E8"
|
|
3349
4001
|
]
|
|
3350
4002
|
}
|
|
@@ -3357,8 +4009,8 @@ function ChatView({
|
|
|
3357
4009
|
}
|
|
3358
4010
|
|
|
3359
4011
|
// src/view/WorkspaceHeader.tsx
|
|
3360
|
-
var
|
|
3361
|
-
var
|
|
4012
|
+
var import_components12 = require("@pactor-app/ui/components");
|
|
4013
|
+
var import_react18 = require("react");
|
|
3362
4014
|
|
|
3363
4015
|
// src/export-markdown.ts
|
|
3364
4016
|
var ROLE_LABELS = {
|
|
@@ -3435,7 +4087,7 @@ function buildHeaderActionsFragment(props) {
|
|
|
3435
4087
|
}
|
|
3436
4088
|
|
|
3437
4089
|
// src/view/WorkspaceHeader.tsx
|
|
3438
|
-
var
|
|
4090
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3439
4091
|
function readCurrentTheme() {
|
|
3440
4092
|
if (typeof document === "undefined") {
|
|
3441
4093
|
return "light";
|
|
@@ -3455,10 +4107,10 @@ function WorkspaceHeader({
|
|
|
3455
4107
|
onTitleChange
|
|
3456
4108
|
}) {
|
|
3457
4109
|
const hasActions = headerActions !== void 0 && headerActions.length > 0;
|
|
3458
|
-
const [overrideTitle, setOverrideTitle] = (0,
|
|
3459
|
-
const [editing, setEditing] = (0,
|
|
3460
|
-
const [draft, setDraft] = (0,
|
|
3461
|
-
const prevTitleRef = (0,
|
|
4110
|
+
const [overrideTitle, setOverrideTitle] = (0, import_react18.useState)(null);
|
|
4111
|
+
const [editing, setEditing] = (0, import_react18.useState)(false);
|
|
4112
|
+
const [draft, setDraft] = (0, import_react18.useState)("");
|
|
4113
|
+
const prevTitleRef = (0, import_react18.useRef)(title);
|
|
3462
4114
|
if (prevTitleRef.current !== title) {
|
|
3463
4115
|
prevTitleRef.current = title;
|
|
3464
4116
|
if (overrideTitle !== null) {
|
|
@@ -3466,7 +4118,7 @@ function WorkspaceHeader({
|
|
|
3466
4118
|
}
|
|
3467
4119
|
}
|
|
3468
4120
|
const displayTitle = overrideTitle ?? title;
|
|
3469
|
-
const [theme, setTheme] = (0,
|
|
4121
|
+
const [theme, setTheme] = (0, import_react18.useState)(readCurrentTheme);
|
|
3470
4122
|
const commitTitle = () => {
|
|
3471
4123
|
setEditing(false);
|
|
3472
4124
|
const next = draft.trim();
|
|
@@ -3493,9 +4145,9 @@ function WorkspaceHeader({
|
|
|
3493
4145
|
store.clear();
|
|
3494
4146
|
onClear?.();
|
|
3495
4147
|
};
|
|
3496
|
-
const handlersRef = (0,
|
|
4148
|
+
const handlersRef = (0, import_react18.useRef)({ handleExport, handleTheme, handleClear });
|
|
3497
4149
|
handlersRef.current = { handleExport, handleTheme, handleClear };
|
|
3498
|
-
(0,
|
|
4150
|
+
(0, import_react18.useEffect)(() => {
|
|
3499
4151
|
setChatChromeHandlers({
|
|
3500
4152
|
headerAction: (name) => {
|
|
3501
4153
|
const handlers2 = handlersRef.current;
|
|
@@ -3510,7 +4162,7 @@ function WorkspaceHeader({
|
|
|
3510
4162
|
});
|
|
3511
4163
|
}, []);
|
|
3512
4164
|
const actionButtons = {
|
|
3513
|
-
export: /* @__PURE__ */ (0,
|
|
4165
|
+
export: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3514
4166
|
"button",
|
|
3515
4167
|
{
|
|
3516
4168
|
type: "button",
|
|
@@ -3518,11 +4170,11 @@ function WorkspaceHeader({
|
|
|
3518
4170
|
title: "\u5BFC\u51FA Markdown",
|
|
3519
4171
|
"aria-label": "\u5BFC\u51FA Markdown",
|
|
3520
4172
|
onClick: handleExport,
|
|
3521
|
-
children: /* @__PURE__ */ (0,
|
|
4173
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "download", size: 15 })
|
|
3522
4174
|
},
|
|
3523
4175
|
"export"
|
|
3524
4176
|
),
|
|
3525
|
-
theme: /* @__PURE__ */ (0,
|
|
4177
|
+
theme: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3526
4178
|
"button",
|
|
3527
4179
|
{
|
|
3528
4180
|
type: "button",
|
|
@@ -3530,11 +4182,11 @@ function WorkspaceHeader({
|
|
|
3530
4182
|
title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
3531
4183
|
"aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
|
|
3532
4184
|
onClick: handleTheme,
|
|
3533
|
-
children: theme === "dark" ? /* @__PURE__ */ (0,
|
|
4185
|
+
children: theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "sun", size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "moon", size: 15 })
|
|
3534
4186
|
},
|
|
3535
4187
|
"theme"
|
|
3536
4188
|
),
|
|
3537
|
-
clear: /* @__PURE__ */ (0,
|
|
4189
|
+
clear: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3538
4190
|
"button",
|
|
3539
4191
|
{
|
|
3540
4192
|
type: "button",
|
|
@@ -3542,12 +4194,12 @@ function WorkspaceHeader({
|
|
|
3542
4194
|
title: "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
3543
4195
|
"aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
3544
4196
|
onClick: handleClear,
|
|
3545
|
-
children: /* @__PURE__ */ (0,
|
|
4197
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "trash", size: 15 })
|
|
3546
4198
|
},
|
|
3547
4199
|
"clear"
|
|
3548
4200
|
)
|
|
3549
4201
|
};
|
|
3550
|
-
const titleNode = editableTitle ? editing ? /* @__PURE__ */ (0,
|
|
4202
|
+
const titleNode = editableTitle ? editing ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3551
4203
|
"input",
|
|
3552
4204
|
{
|
|
3553
4205
|
className: "pactor-chat-workspace__title-input",
|
|
@@ -3564,7 +4216,7 @@ function WorkspaceHeader({
|
|
|
3564
4216
|
}
|
|
3565
4217
|
}
|
|
3566
4218
|
}
|
|
3567
|
-
) : /* @__PURE__ */ (0,
|
|
4219
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3568
4220
|
"button",
|
|
3569
4221
|
{
|
|
3570
4222
|
type: "button",
|
|
@@ -3576,17 +4228,17 @@ function WorkspaceHeader({
|
|
|
3576
4228
|
},
|
|
3577
4229
|
children: displayTitle
|
|
3578
4230
|
}
|
|
3579
|
-
) : /* @__PURE__ */ (0,
|
|
3580
|
-
return /* @__PURE__ */ (0,
|
|
4231
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "pactor-chat-workspace__title", children: title });
|
|
4232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("header", { className: "pactor-chat-workspace__header", children: [
|
|
3581
4233
|
headerStart !== void 0 ? (
|
|
3582
4234
|
// header 位模型 chip(决策 D2):与 title 组成左端组,chip 在前
|
|
3583
|
-
/* @__PURE__ */ (0,
|
|
4235
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "pactor-chat-workspace__header-left", children: [
|
|
3584
4236
|
headerStart,
|
|
3585
4237
|
titleNode
|
|
3586
4238
|
] })
|
|
3587
4239
|
) : titleNode,
|
|
3588
|
-
hasActions ? /* @__PURE__ */ (0,
|
|
3589
|
-
/* @__PURE__ */ (0,
|
|
4240
|
+
hasActions ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "pactor-chat-workspace__header-right", children: [
|
|
4241
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "pactor-chat-workspace__header-actions", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3590
4242
|
ChromeSlot,
|
|
3591
4243
|
{
|
|
3592
4244
|
fragment: buildHeaderActionsFragment({
|
|
@@ -3596,18 +4248,18 @@ function WorkspaceHeader({
|
|
|
3596
4248
|
fallback: headerActions.map((action) => actionButtons[action])
|
|
3597
4249
|
}
|
|
3598
4250
|
) }),
|
|
3599
|
-
headerExtra !== void 0 ? /* @__PURE__ */ (0,
|
|
3600
|
-
] }) : headerExtra !== void 0 ? /* @__PURE__ */ (0,
|
|
4251
|
+
headerExtra !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
4252
|
+
] }) : headerExtra !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
3601
4253
|
] });
|
|
3602
4254
|
}
|
|
3603
4255
|
|
|
3604
4256
|
// src/chat-composition.tsx
|
|
3605
|
-
var
|
|
4257
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3606
4258
|
function DslNodeSlotInner({ node }) {
|
|
3607
4259
|
const { renderChildren } = (0, import_runtime5.useRenderer)();
|
|
3608
4260
|
return renderChildren([node]);
|
|
3609
4261
|
}
|
|
3610
|
-
var DslSlotGuard = class extends
|
|
4262
|
+
var DslSlotGuard = class extends import_react19.Component {
|
|
3611
4263
|
constructor() {
|
|
3612
4264
|
super(...arguments);
|
|
3613
4265
|
this.state = { failed: false };
|
|
@@ -3625,17 +4277,17 @@ var DslSlotGuard = class extends import_react17.Component {
|
|
|
3625
4277
|
}
|
|
3626
4278
|
};
|
|
3627
4279
|
function DslNodeSlot({ node }) {
|
|
3628
|
-
return /* @__PURE__ */ (0,
|
|
4280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DslSlotGuard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DslNodeSlotInner, { node }) });
|
|
3629
4281
|
}
|
|
3630
4282
|
function isDslNodeValue(value) {
|
|
3631
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0,
|
|
4283
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0, import_react19.isValidElement)(value) && typeof value.type === "string";
|
|
3632
4284
|
}
|
|
3633
4285
|
function resolveSlot(slot) {
|
|
3634
4286
|
if (slot === void 0 || slot === null) {
|
|
3635
4287
|
return void 0;
|
|
3636
4288
|
}
|
|
3637
4289
|
if (isDslNodeValue(slot)) {
|
|
3638
|
-
return /* @__PURE__ */ (0,
|
|
4290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DslNodeSlot, { node: slot });
|
|
3639
4291
|
}
|
|
3640
4292
|
return slot;
|
|
3641
4293
|
}
|
|
@@ -3674,28 +4326,51 @@ function ChatComposition({
|
|
|
3674
4326
|
onSend,
|
|
3675
4327
|
artifact,
|
|
3676
4328
|
panelOpen,
|
|
4329
|
+
artifacts: artifactsProp,
|
|
4330
|
+
onSelectArtifact,
|
|
3677
4331
|
onPanelClose,
|
|
3678
4332
|
inspector,
|
|
3679
4333
|
onArtifact,
|
|
3680
|
-
onOpenArtifact
|
|
4334
|
+
onOpenArtifact,
|
|
4335
|
+
onOpenArtifactList
|
|
3681
4336
|
}) {
|
|
3682
|
-
const storeRef = (0,
|
|
4337
|
+
const storeRef = (0, import_react19.useRef)(null);
|
|
3683
4338
|
if (storeRef.current === null) {
|
|
3684
4339
|
storeRef.current = services.store ?? services.storeFactory?.() ?? new ConversationStore();
|
|
3685
4340
|
}
|
|
3686
4341
|
const store = storeRef.current;
|
|
3687
|
-
const artifactStoreRef = (0,
|
|
4342
|
+
const artifactStoreRef = (0, import_react19.useRef)(null);
|
|
3688
4343
|
if (artifactStoreRef.current === null) {
|
|
3689
4344
|
artifactStoreRef.current = services.artifactStore ?? new ArtifactStore();
|
|
3690
4345
|
}
|
|
3691
4346
|
const artifactStore = artifactStoreRef.current;
|
|
3692
4347
|
const panelControlled = panelOpen !== void 0 || artifact !== void 0;
|
|
3693
|
-
const storeArtifact = (0,
|
|
4348
|
+
const storeArtifact = (0, import_react19.useSyncExternalStore)(
|
|
3694
4349
|
(listener) => artifactStore.subscribe(listener),
|
|
3695
4350
|
() => artifactStore.get()
|
|
3696
4351
|
);
|
|
4352
|
+
const storeArtifacts = (0, import_react19.useSyncExternalStore)(
|
|
4353
|
+
(listener) => artifactStore.subscribe(listener),
|
|
4354
|
+
() => artifactStore.list()
|
|
4355
|
+
);
|
|
4356
|
+
const messages = (0, import_react19.useSyncExternalStore)(
|
|
4357
|
+
(listener) => store.subscribe(listener),
|
|
4358
|
+
() => store.getMessages()
|
|
4359
|
+
);
|
|
4360
|
+
const streamArtifacts = (0, import_react19.useMemo)(() => collectArtifacts(messages), [messages]);
|
|
4361
|
+
const mergedArtifacts = (0, import_react19.useMemo)(
|
|
4362
|
+
() => mergeArtifacts(streamArtifacts, storeArtifacts),
|
|
4363
|
+
[streamArtifacts, storeArtifacts]
|
|
4364
|
+
);
|
|
3697
4365
|
const effectiveArtifact = panelControlled ? artifact ?? null : storeArtifact;
|
|
3698
4366
|
const effectivePanelOpen = panelControlled ? panelOpen ?? artifact != null : storeArtifact !== null;
|
|
4367
|
+
const effectiveArtifacts = artifactsProp ?? mergedArtifacts;
|
|
4368
|
+
const handleSelectArtifact = (next) => {
|
|
4369
|
+
onSelectArtifact?.(next);
|
|
4370
|
+
if (!panelControlled) {
|
|
4371
|
+
artifactStore.open(next);
|
|
4372
|
+
}
|
|
4373
|
+
};
|
|
3699
4374
|
const handlePanelClose = () => {
|
|
3700
4375
|
onPanelClose?.();
|
|
3701
4376
|
if (!panelControlled) {
|
|
@@ -3708,7 +4383,18 @@ function ChatComposition({
|
|
|
3708
4383
|
artifactStore.open(next);
|
|
3709
4384
|
}
|
|
3710
4385
|
};
|
|
3711
|
-
const [
|
|
4386
|
+
const [listViewRequest, setListViewRequest] = (0, import_react19.useState)(null);
|
|
4387
|
+
const handleOpenArtifactList = () => {
|
|
4388
|
+
onOpenArtifactList?.();
|
|
4389
|
+
setListViewRequest((value) => (value ?? 0) + 1);
|
|
4390
|
+
if (!panelControlled && artifactStore.get() === null) {
|
|
4391
|
+
const first = mergedArtifacts[0];
|
|
4392
|
+
if (first !== void 0) {
|
|
4393
|
+
artifactStore.open(first);
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
};
|
|
4397
|
+
const [attachments, setAttachments] = (0, import_react19.useState)([]);
|
|
3712
4398
|
const handleAttachFiles = services.onAttachFiles ? (files) => {
|
|
3713
4399
|
void Promise.resolve(services.onAttachFiles(files)).then(
|
|
3714
4400
|
(created) => {
|
|
@@ -3728,7 +4414,7 @@ function ChatComposition({
|
|
|
3728
4414
|
model,
|
|
3729
4415
|
onModelChange
|
|
3730
4416
|
});
|
|
3731
|
-
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ (0,
|
|
4417
|
+
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3732
4418
|
ModelSelect,
|
|
3733
4419
|
{
|
|
3734
4420
|
models,
|
|
@@ -3736,133 +4422,144 @@ function ChatComposition({
|
|
|
3736
4422
|
onModelChange: handleModelChange
|
|
3737
4423
|
}
|
|
3738
4424
|
) : void 0;
|
|
3739
|
-
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ (0,
|
|
4425
|
+
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3740
4426
|
services.toolbarEnd,
|
|
3741
4427
|
toolbarEnd
|
|
3742
4428
|
] }) : void 0;
|
|
3743
|
-
const mergedToolbarStart = services.toolbarStart !== void 0 || toolbarStart !== void 0 ? /* @__PURE__ */ (0,
|
|
4429
|
+
const mergedToolbarStart = services.toolbarStart !== void 0 || toolbarStart !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3744
4430
|
services.toolbarStart,
|
|
3745
4431
|
toolbarStart
|
|
3746
4432
|
] }) : void 0;
|
|
3747
|
-
const mergedComposerFooter = services.composerFooter !== void 0 || composerFooter !== void 0 ? /* @__PURE__ */ (0,
|
|
4433
|
+
const mergedComposerFooter = services.composerFooter !== void 0 || composerFooter !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3748
4434
|
services.composerFooter,
|
|
3749
4435
|
composerFooter
|
|
3750
4436
|
] }) : void 0;
|
|
3751
|
-
const mergedComposerBottom = services.composerBottom !== void 0 || composerBottom !== void 0 ? /* @__PURE__ */ (0,
|
|
4437
|
+
const mergedComposerBottom = services.composerBottom !== void 0 || composerBottom !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3752
4438
|
services.composerBottom,
|
|
3753
4439
|
composerBottom
|
|
3754
4440
|
] }) : void 0;
|
|
3755
4441
|
const hasHeaderContent = header !== void 0 && header !== null ? true : title !== void 0 || headerExtra !== void 0 && headerExtra !== null || headerActions !== void 0 && headerActions.length > 0 || headerModelChip !== void 0;
|
|
3756
4442
|
const renderHeader = showHeader !== false && hasHeaderContent;
|
|
3757
|
-
const
|
|
4443
|
+
const workspaceHeader = renderHeader ? header ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4444
|
+
WorkspaceHeader,
|
|
4445
|
+
{
|
|
4446
|
+
title,
|
|
4447
|
+
headerExtra,
|
|
4448
|
+
headerActions,
|
|
4449
|
+
editableTitle,
|
|
4450
|
+
headerStart: headerModelChip,
|
|
4451
|
+
store,
|
|
4452
|
+
onExport,
|
|
4453
|
+
onThemeChange,
|
|
4454
|
+
onClear,
|
|
4455
|
+
onTitleChange
|
|
4456
|
+
}
|
|
4457
|
+
) : null;
|
|
4458
|
+
const workspace = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3758
4459
|
"div",
|
|
3759
4460
|
{
|
|
3760
4461
|
className: `pactor-chat-workspace${className ? ` ${className}` : ""}`,
|
|
3761
|
-
children:
|
|
3762
|
-
|
|
3763
|
-
|
|
4462
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4463
|
+
ChatView,
|
|
4464
|
+
{
|
|
4465
|
+
store,
|
|
4466
|
+
transport: services.transport,
|
|
4467
|
+
onSend: handleSend,
|
|
4468
|
+
safeRegistry: services.safeRegistry,
|
|
4469
|
+
capabilities: services.capabilities,
|
|
4470
|
+
permission: services.permission,
|
|
4471
|
+
confirm: services.confirm,
|
|
4472
|
+
conversationId,
|
|
4473
|
+
user: services.user,
|
|
4474
|
+
params,
|
|
4475
|
+
greeting,
|
|
4476
|
+
subtitle,
|
|
4477
|
+
suggestions,
|
|
4478
|
+
attachments,
|
|
4479
|
+
onAttachmentsChange: setAttachments,
|
|
4480
|
+
onAttachFiles: handleAttachFiles,
|
|
4481
|
+
onAttachmentClick: services.onAttachmentClick,
|
|
4482
|
+
toolbarStart: mergedToolbarStart,
|
|
4483
|
+
toolbarEnd: mergedToolbarEnd,
|
|
4484
|
+
composerFooter: mergedComposerFooter,
|
|
4485
|
+
composerBottom: mergedComposerBottom,
|
|
4486
|
+
hideToolbar,
|
|
4487
|
+
onMentionTrigger: services.onMentionTrigger,
|
|
4488
|
+
onPlusMenu: services.onPlusMenu,
|
|
4489
|
+
onArtifact,
|
|
4490
|
+
onOpenArtifact: handleOpenArtifact,
|
|
4491
|
+
onOpenArtifactList: handleOpenArtifactList,
|
|
4492
|
+
models,
|
|
4493
|
+
model: currentModel,
|
|
4494
|
+
onModelChange: handleModelChange,
|
|
4495
|
+
modelPlacement,
|
|
4496
|
+
contexts,
|
|
4497
|
+
onContextsChange,
|
|
4498
|
+
callService: services.callService,
|
|
4499
|
+
messageActions,
|
|
4500
|
+
onMessageAction
|
|
4501
|
+
}
|
|
4502
|
+
)
|
|
4503
|
+
}
|
|
4504
|
+
);
|
|
4505
|
+
const main = sidebar ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AppShell, { sidebar, children: workspace }) : workspace;
|
|
4506
|
+
const panelFeatureUsed = artifact !== void 0 || panelOpen !== void 0 || inspector !== void 0 || onPanelClose !== void 0 || onArtifact !== void 0 || onOpenArtifact !== void 0 || onOpenArtifactList !== void 0 || services.artifactStore !== void 0;
|
|
4507
|
+
if (!panelFeatureUsed && !effectivePanelOpen) {
|
|
4508
|
+
return workspaceHeader ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-with-header", children: [
|
|
4509
|
+
workspaceHeader,
|
|
4510
|
+
main
|
|
4511
|
+
] }) : main;
|
|
4512
|
+
}
|
|
4513
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host", children: [
|
|
4514
|
+
workspaceHeader,
|
|
4515
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host__row", children: [
|
|
4516
|
+
main,
|
|
4517
|
+
effectivePanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4518
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4519
|
+
"div",
|
|
3764
4520
|
{
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
editableTitle,
|
|
3769
|
-
headerStart: headerModelChip,
|
|
3770
|
-
store,
|
|
3771
|
-
onExport,
|
|
3772
|
-
onThemeChange,
|
|
3773
|
-
onClear,
|
|
3774
|
-
onTitleChange
|
|
4521
|
+
className: "pactor-chat-inspector__scrim",
|
|
4522
|
+
"aria-hidden": true,
|
|
4523
|
+
onClick: handlePanelClose
|
|
3775
4524
|
}
|
|
3776
|
-
)
|
|
3777
|
-
/* @__PURE__ */ (0,
|
|
3778
|
-
|
|
4525
|
+
),
|
|
4526
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4527
|
+
ArtifactPanel,
|
|
3779
4528
|
{
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
4529
|
+
artifact: effectiveArtifact,
|
|
4530
|
+
artifacts: effectiveArtifacts,
|
|
4531
|
+
activeArtifactId: effectiveArtifact?.id,
|
|
4532
|
+
onSelectArtifact: handleSelectArtifact,
|
|
4533
|
+
inspector,
|
|
4534
|
+
onClose: handlePanelClose,
|
|
3783
4535
|
safeRegistry: services.safeRegistry,
|
|
3784
|
-
capabilities: services.capabilities,
|
|
3785
|
-
permission: services.permission,
|
|
3786
|
-
confirm: services.confirm,
|
|
3787
|
-
conversationId,
|
|
3788
4536
|
user: services.user,
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
suggestions,
|
|
3793
|
-
attachments,
|
|
3794
|
-
onAttachmentsChange: setAttachments,
|
|
3795
|
-
onAttachFiles: handleAttachFiles,
|
|
3796
|
-
onAttachmentClick: services.onAttachmentClick,
|
|
3797
|
-
toolbarStart: mergedToolbarStart,
|
|
3798
|
-
toolbarEnd: mergedToolbarEnd,
|
|
3799
|
-
composerFooter: mergedComposerFooter,
|
|
3800
|
-
composerBottom: mergedComposerBottom,
|
|
3801
|
-
hideToolbar,
|
|
3802
|
-
onMentionTrigger: services.onMentionTrigger,
|
|
3803
|
-
onPlusMenu: services.onPlusMenu,
|
|
3804
|
-
onArtifact,
|
|
3805
|
-
onOpenArtifact: handleOpenArtifact,
|
|
3806
|
-
models,
|
|
3807
|
-
model: currentModel,
|
|
3808
|
-
onModelChange: handleModelChange,
|
|
3809
|
-
modelPlacement,
|
|
3810
|
-
contexts,
|
|
3811
|
-
onContextsChange,
|
|
3812
|
-
callService: services.callService,
|
|
3813
|
-
messageActions,
|
|
3814
|
-
onMessageAction
|
|
4537
|
+
artifactViewers: services.artifactViewers,
|
|
4538
|
+
viewRequest: listViewRequest,
|
|
4539
|
+
onViewRequestConsumed: () => setListViewRequest(null)
|
|
3815
4540
|
}
|
|
3816
4541
|
)
|
|
3817
|
-
]
|
|
3818
|
-
}
|
|
3819
|
-
);
|
|
3820
|
-
const main = sidebar ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AppShell, { sidebar, children: workspace }) : workspace;
|
|
3821
|
-
const panelFeatureUsed = artifact !== void 0 || panelOpen !== void 0 || inspector !== void 0 || onPanelClose !== void 0 || onArtifact !== void 0 || onOpenArtifact !== void 0 || services.artifactStore !== void 0;
|
|
3822
|
-
if (!panelFeatureUsed && !effectivePanelOpen) {
|
|
3823
|
-
return main;
|
|
3824
|
-
}
|
|
3825
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "pactor-chat-inspector-host", children: [
|
|
3826
|
-
main,
|
|
3827
|
-
effectivePanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3828
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3829
|
-
"div",
|
|
3830
|
-
{
|
|
3831
|
-
className: "pactor-chat-inspector__scrim",
|
|
3832
|
-
"aria-hidden": true,
|
|
3833
|
-
onClick: handlePanelClose
|
|
3834
|
-
}
|
|
3835
|
-
),
|
|
3836
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3837
|
-
ArtifactPanel,
|
|
3838
|
-
{
|
|
3839
|
-
artifact: effectiveArtifact,
|
|
3840
|
-
inspector,
|
|
3841
|
-
onClose: handlePanelClose,
|
|
3842
|
-
safeRegistry: services.safeRegistry,
|
|
3843
|
-
user: services.user
|
|
3844
|
-
}
|
|
3845
|
-
)
|
|
3846
|
-
] }) : null
|
|
4542
|
+
] }) : null
|
|
4543
|
+
] })
|
|
3847
4544
|
] });
|
|
3848
4545
|
}
|
|
3849
4546
|
|
|
3850
4547
|
// src/chat-services.tsx
|
|
3851
|
-
var
|
|
3852
|
-
var
|
|
3853
|
-
var ChatServicesContext = (0,
|
|
4548
|
+
var import_react20 = require("react");
|
|
4549
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4550
|
+
var ChatServicesContext = (0, import_react20.createContext)(null);
|
|
3854
4551
|
function ChatServicesProvider({
|
|
3855
4552
|
value,
|
|
3856
4553
|
children
|
|
3857
4554
|
}) {
|
|
3858
|
-
return /* @__PURE__ */ (0,
|
|
4555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatServicesContext.Provider, { value, children });
|
|
3859
4556
|
}
|
|
3860
4557
|
function useChatServices() {
|
|
3861
|
-
return (0,
|
|
4558
|
+
return (0, import_react20.useContext)(ChatServicesContext);
|
|
3862
4559
|
}
|
|
3863
4560
|
|
|
3864
4561
|
// src/chat-workspace.tsx
|
|
3865
|
-
var
|
|
4562
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3866
4563
|
function createChatWorkspace(services) {
|
|
3867
4564
|
function ChatWorkspace({
|
|
3868
4565
|
title,
|
|
@@ -3883,6 +4580,8 @@ function createChatWorkspace(services) {
|
|
|
3883
4580
|
inspector,
|
|
3884
4581
|
onArtifact,
|
|
3885
4582
|
onOpenArtifact,
|
|
4583
|
+
onOpenArtifactList,
|
|
4584
|
+
onSelectArtifact,
|
|
3886
4585
|
headerActions,
|
|
3887
4586
|
editableTitle,
|
|
3888
4587
|
onExport,
|
|
@@ -3899,7 +4598,7 @@ function createChatWorkspace(services) {
|
|
|
3899
4598
|
onMessageAction,
|
|
3900
4599
|
className
|
|
3901
4600
|
}) {
|
|
3902
|
-
return /* @__PURE__ */ (0,
|
|
4601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChatServicesProvider, { value: services, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3903
4602
|
ChatComposition,
|
|
3904
4603
|
{
|
|
3905
4604
|
services,
|
|
@@ -3911,18 +4610,20 @@ function createChatWorkspace(services) {
|
|
|
3911
4610
|
params,
|
|
3912
4611
|
className,
|
|
3913
4612
|
headerExtra: services.headerExtra,
|
|
3914
|
-
sidebar: sidebar ? /* @__PURE__ */ (0,
|
|
3915
|
-
toolbarStart: toolbarStart ? /* @__PURE__ */ (0,
|
|
3916
|
-
toolbarEnd: toolbarEnd ? /* @__PURE__ */ (0,
|
|
3917
|
-
composerFooter: composerFooter ? /* @__PURE__ */ (0,
|
|
3918
|
-
composerBottom: composerBottom ? /* @__PURE__ */ (0,
|
|
4613
|
+
sidebar: sidebar ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: sidebar }) : void 0,
|
|
4614
|
+
toolbarStart: toolbarStart ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: toolbarStart }) : void 0,
|
|
4615
|
+
toolbarEnd: toolbarEnd ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: toolbarEnd }) : void 0,
|
|
4616
|
+
composerFooter: composerFooter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: composerFooter }) : void 0,
|
|
4617
|
+
composerBottom: composerBottom ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: composerBottom }) : void 0,
|
|
3919
4618
|
hideToolbar,
|
|
3920
4619
|
artifact,
|
|
3921
4620
|
panelOpen,
|
|
3922
4621
|
onPanelClose,
|
|
3923
|
-
inspector: inspector ? /* @__PURE__ */ (0,
|
|
4622
|
+
inspector: inspector ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DslNodeSlot, { node: inspector }) : void 0,
|
|
3924
4623
|
onArtifact,
|
|
3925
4624
|
onOpenArtifact,
|
|
4625
|
+
onOpenArtifactList,
|
|
4626
|
+
onSelectArtifact,
|
|
3926
4627
|
headerActions,
|
|
3927
4628
|
editableTitle,
|
|
3928
4629
|
onExport,
|
|
@@ -3944,8 +4645,8 @@ function createChatWorkspace(services) {
|
|
|
3944
4645
|
}
|
|
3945
4646
|
|
|
3946
4647
|
// src/view/Chat.tsx
|
|
3947
|
-
var
|
|
3948
|
-
var
|
|
4648
|
+
var import_components13 = require("@pactor-app/ui/components");
|
|
4649
|
+
var import_react21 = require("react");
|
|
3949
4650
|
|
|
3950
4651
|
// src/view/chrome/menu.tsx
|
|
3951
4652
|
function buildSidebarMenuFragment(props) {
|
|
@@ -3974,7 +4675,7 @@ function buildSidebarMenuFragment(props) {
|
|
|
3974
4675
|
}
|
|
3975
4676
|
|
|
3976
4677
|
// src/view/ChatShell.tsx
|
|
3977
|
-
var
|
|
4678
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3978
4679
|
function ChatShell({
|
|
3979
4680
|
menu,
|
|
3980
4681
|
activeMenuKey,
|
|
@@ -3986,7 +4687,7 @@ function ChatShell({
|
|
|
3986
4687
|
className,
|
|
3987
4688
|
onMenuSelect
|
|
3988
4689
|
}) {
|
|
3989
|
-
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0,
|
|
4690
|
+
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3990
4691
|
ChatSidebarMenu,
|
|
3991
4692
|
{
|
|
3992
4693
|
menu,
|
|
@@ -3994,7 +4695,7 @@ function ChatShell({
|
|
|
3994
4695
|
onMenuSelect
|
|
3995
4696
|
}
|
|
3996
4697
|
) : null);
|
|
3997
|
-
return /* @__PURE__ */ (0,
|
|
4698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3998
4699
|
AppShell,
|
|
3999
4700
|
{
|
|
4000
4701
|
sidebar: sidebarContent,
|
|
@@ -4011,7 +4712,7 @@ function ChatShellDslAdapter({
|
|
|
4011
4712
|
onMenuSelect,
|
|
4012
4713
|
...rest
|
|
4013
4714
|
}) {
|
|
4014
|
-
return /* @__PURE__ */ (0,
|
|
4715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4015
4716
|
ChatShell,
|
|
4016
4717
|
{
|
|
4017
4718
|
...rest,
|
|
@@ -4026,20 +4727,20 @@ function registerChatShellComponent(registry) {
|
|
|
4026
4727
|
}
|
|
4027
4728
|
|
|
4028
4729
|
// src/view/Chat.tsx
|
|
4029
|
-
var
|
|
4730
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4030
4731
|
function ChatSidebarMenu({
|
|
4031
4732
|
menu,
|
|
4032
4733
|
activeMenuKey,
|
|
4033
4734
|
onMenuSelect
|
|
4034
4735
|
}) {
|
|
4035
4736
|
const drawer = useSidebarDrawer();
|
|
4036
|
-
const menuRef = (0,
|
|
4737
|
+
const menuRef = (0, import_react21.useRef)(menu);
|
|
4037
4738
|
menuRef.current = menu;
|
|
4038
|
-
const selectRef = (0,
|
|
4739
|
+
const selectRef = (0, import_react21.useRef)(onMenuSelect);
|
|
4039
4740
|
selectRef.current = onMenuSelect;
|
|
4040
|
-
const drawerRef = (0,
|
|
4741
|
+
const drawerRef = (0, import_react21.useRef)(drawer);
|
|
4041
4742
|
drawerRef.current = drawer;
|
|
4042
|
-
(0,
|
|
4743
|
+
(0, import_react21.useEffect)(() => {
|
|
4043
4744
|
setChatChromeHandlers({
|
|
4044
4745
|
menuSelect: (key) => {
|
|
4045
4746
|
const item = menuRef.current.find((entry) => entry.key === key);
|
|
@@ -4053,12 +4754,12 @@ function ChatSidebarMenu({
|
|
|
4053
4754
|
}, []);
|
|
4054
4755
|
const fallback = (() => {
|
|
4055
4756
|
let lastGroup;
|
|
4056
|
-
return /* @__PURE__ */ (0,
|
|
4757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("nav", { className: "pactor-chat-menu", "aria-label": "\u4F1A\u8BDD\u5BFC\u822A", children: menu.map((item) => {
|
|
4057
4758
|
const groupLabel = item.group !== void 0 && item.group !== lastGroup ? item.group : void 0;
|
|
4058
4759
|
lastGroup = item.group;
|
|
4059
4760
|
const active = item.key === activeMenuKey;
|
|
4060
4761
|
const collapsed = drawer?.collapsed === true;
|
|
4061
|
-
const button = /* @__PURE__ */ (0,
|
|
4762
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4062
4763
|
"button",
|
|
4063
4764
|
{
|
|
4064
4765
|
type: "button",
|
|
@@ -4073,20 +4774,20 @@ function ChatSidebarMenu({
|
|
|
4073
4774
|
drawer?.close();
|
|
4074
4775
|
},
|
|
4075
4776
|
children: [
|
|
4076
|
-
item.icon !== void 0 ? /* @__PURE__ */ (0,
|
|
4077
|
-
/* @__PURE__ */ (0,
|
|
4078
|
-
item.dot === true ? /* @__PURE__ */ (0,
|
|
4079
|
-
item.badge !== void 0 ? /* @__PURE__ */ (0,
|
|
4777
|
+
item.icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components13.Icon, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
|
|
4778
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
4779
|
+
item.dot === true ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
4780
|
+
item.badge !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
|
|
4080
4781
|
]
|
|
4081
4782
|
}
|
|
4082
4783
|
);
|
|
4083
|
-
return /* @__PURE__ */ (0,
|
|
4084
|
-
groupLabel !== void 0 ? /* @__PURE__ */ (0,
|
|
4085
|
-
collapsed ? /* @__PURE__ */ (0,
|
|
4784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react21.Fragment, { children: [
|
|
4785
|
+
groupLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "pactor-chat-menu__group", children: groupLabel }) : null,
|
|
4786
|
+
collapsed ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components13.RailTooltip, { label: item.label, children: button }) : button
|
|
4086
4787
|
] }, item.key);
|
|
4087
4788
|
}) });
|
|
4088
4789
|
})();
|
|
4089
|
-
return /* @__PURE__ */ (0,
|
|
4790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4090
4791
|
ChromeSlot,
|
|
4091
4792
|
{
|
|
4092
4793
|
fragment: buildSidebarMenuFragment({ menu, activeMenuKey }),
|
|
@@ -4132,12 +4833,14 @@ function Chat({
|
|
|
4132
4833
|
inspector,
|
|
4133
4834
|
onArtifact,
|
|
4134
4835
|
onOpenArtifact,
|
|
4836
|
+
onOpenArtifactList,
|
|
4837
|
+
onSelectArtifact,
|
|
4135
4838
|
className,
|
|
4136
4839
|
onSend,
|
|
4137
4840
|
onMenuSelect
|
|
4138
4841
|
}) {
|
|
4139
4842
|
const services = useChatServices();
|
|
4140
|
-
(0,
|
|
4843
|
+
(0, import_react21.useEffect)(() => {
|
|
4141
4844
|
if (!services) {
|
|
4142
4845
|
console.warn(
|
|
4143
4846
|
"[@pactor-app/chat] Chat \u672A\u68C0\u6D4B\u5230 ChatServicesProvider\uFF1A\u8BF7\u5728\u5E94\u7528\u6839\u90E8\u4EE5 <ChatServicesProvider> \u6CE8\u5165 transport \u7B49\u670D\u52A1"
|
|
@@ -4145,10 +4848,10 @@ function Chat({
|
|
|
4145
4848
|
}
|
|
4146
4849
|
}, [services]);
|
|
4147
4850
|
if (!services) {
|
|
4148
|
-
return /* @__PURE__ */ (0,
|
|
4851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "pactor-chat-notice", role: "note", children: "\u672A\u914D\u7F6E\u804A\u5929\u670D\u52A1\uFF1A\u8BF7\u5728 Chat \u5916\u5C42\u4F7F\u7528 ChatServicesProvider \u6CE8\u5165 transport \u7B49\u670D\u52A1\u540E\u91CD\u8BD5\u3002" });
|
|
4149
4852
|
}
|
|
4150
4853
|
const sidebarSlot = resolveSlot(sidebar);
|
|
4151
|
-
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0,
|
|
4854
|
+
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4152
4855
|
ChatSidebarMenu,
|
|
4153
4856
|
{
|
|
4154
4857
|
menu,
|
|
@@ -4156,7 +4859,7 @@ function Chat({
|
|
|
4156
4859
|
onMenuSelect
|
|
4157
4860
|
}
|
|
4158
4861
|
) : void 0);
|
|
4159
|
-
return /* @__PURE__ */ (0,
|
|
4862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4160
4863
|
ChatComposition,
|
|
4161
4864
|
{
|
|
4162
4865
|
services,
|
|
@@ -4196,7 +4899,9 @@ function Chat({
|
|
|
4196
4899
|
onPanelClose,
|
|
4197
4900
|
inspector: resolveSlot(inspector),
|
|
4198
4901
|
onArtifact,
|
|
4199
|
-
onOpenArtifact
|
|
4902
|
+
onOpenArtifact,
|
|
4903
|
+
onOpenArtifactList,
|
|
4904
|
+
onSelectArtifact
|
|
4200
4905
|
}
|
|
4201
4906
|
);
|
|
4202
4907
|
}
|
|
@@ -4207,6 +4912,8 @@ function ChatDslAdapter({
|
|
|
4207
4912
|
onPanelClose,
|
|
4208
4913
|
onArtifact,
|
|
4209
4914
|
onOpenArtifact,
|
|
4915
|
+
onOpenArtifactList,
|
|
4916
|
+
onSelectArtifact,
|
|
4210
4917
|
onModelChange,
|
|
4211
4918
|
onContextsChange,
|
|
4212
4919
|
onMessageAction,
|
|
@@ -4216,7 +4923,7 @@ function ChatDslAdapter({
|
|
|
4216
4923
|
onTitleChange,
|
|
4217
4924
|
...rest
|
|
4218
4925
|
}) {
|
|
4219
|
-
return /* @__PURE__ */ (0,
|
|
4926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4220
4927
|
Chat,
|
|
4221
4928
|
{
|
|
4222
4929
|
...rest,
|
|
@@ -4225,6 +4932,8 @@ function ChatDslAdapter({
|
|
|
4225
4932
|
onPanelClose: onPanelClose ? () => onPanelClose({}) : void 0,
|
|
4226
4933
|
onArtifact: onArtifact ? (artifact) => onArtifact({ artifact }) : void 0,
|
|
4227
4934
|
onOpenArtifact: onOpenArtifact ? (artifact) => onOpenArtifact({ artifact }) : void 0,
|
|
4935
|
+
onOpenArtifactList: onOpenArtifactList ? () => onOpenArtifactList({}) : void 0,
|
|
4936
|
+
onSelectArtifact: onSelectArtifact ? (artifact) => onSelectArtifact({ artifact }) : void 0,
|
|
4228
4937
|
onModelChange: onModelChange ? (model) => onModelChange({ model }) : void 0,
|
|
4229
4938
|
onContextsChange: onContextsChange ? (contexts) => onContextsChange({ contexts }) : void 0,
|
|
4230
4939
|
onMessageAction: onMessageAction ? (action, message) => onMessageAction({ action, message }) : void 0,
|
|
@@ -4242,17 +4951,17 @@ function registerChatComponent(registry) {
|
|
|
4242
4951
|
registerChatShellComponent(registry);
|
|
4243
4952
|
}
|
|
4244
4953
|
function createChatComponentRegistry() {
|
|
4245
|
-
const registry = (0,
|
|
4954
|
+
const registry = (0, import_components13.createComponentRegistry)();
|
|
4246
4955
|
registerChatComponent(registry);
|
|
4247
4956
|
return registry;
|
|
4248
4957
|
}
|
|
4249
4958
|
|
|
4250
4959
|
// src/view/ChatLayout.tsx
|
|
4251
|
-
var
|
|
4960
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4252
4961
|
function ChatLayout({ title, children }) {
|
|
4253
|
-
return /* @__PURE__ */ (0,
|
|
4254
|
-
/* @__PURE__ */ (0,
|
|
4255
|
-
/* @__PURE__ */ (0,
|
|
4962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "pactor-chat-layout", children: [
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("header", { className: "pactor-chat-layout__header", children: title ?? "Chat" }),
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("main", { className: "pactor-chat-layout__main", children })
|
|
4256
4965
|
] });
|
|
4257
4966
|
}
|
|
4258
4967
|
var CHAT_LAYOUT_TYPE = "chat";
|
|
@@ -4263,6 +4972,7 @@ function registerChatLayout(layoutRegistry) {
|
|
|
4263
4972
|
}
|
|
4264
4973
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4265
4974
|
0 && (module.exports = {
|
|
4975
|
+
ARTIFACT_IMAGE_EXTENSIONS,
|
|
4266
4976
|
ActivityTrace,
|
|
4267
4977
|
AppShell,
|
|
4268
4978
|
ArtifactPanel,
|
|
@@ -4272,6 +4982,7 @@ function registerChatLayout(layoutRegistry) {
|
|
|
4272
4982
|
CHAT_LAYOUT_TYPE,
|
|
4273
4983
|
CHAT_SHELL_COMPONENT_TYPE,
|
|
4274
4984
|
Chat,
|
|
4985
|
+
ChatArtifactCard,
|
|
4275
4986
|
ChatDenied,
|
|
4276
4987
|
ChatLayout,
|
|
4277
4988
|
ChatServicesProvider,
|
|
@@ -4286,7 +4997,11 @@ function registerChatLayout(layoutRegistry) {
|
|
|
4286
4997
|
MessageBubble,
|
|
4287
4998
|
PartRenderer,
|
|
4288
4999
|
applyChatEvent,
|
|
5000
|
+
artifactCardMeta,
|
|
5001
|
+
buildArtifactBlob,
|
|
5002
|
+
buildArtifactTree,
|
|
4289
5003
|
buildChatScope,
|
|
5004
|
+
collectArtifacts,
|
|
4290
5005
|
collectMessageText,
|
|
4291
5006
|
createChatComponentRegistry,
|
|
4292
5007
|
createChatId,
|
|
@@ -4295,14 +5010,24 @@ function registerChatLayout(layoutRegistry) {
|
|
|
4295
5010
|
createManualDriver,
|
|
4296
5011
|
createSafeRegistry,
|
|
4297
5012
|
detectStreamingMode,
|
|
5013
|
+
downloadArtifact,
|
|
5014
|
+
formatArtifactSize,
|
|
5015
|
+
formatMessageTime,
|
|
4298
5016
|
guardChatDsl,
|
|
5017
|
+
isImageArtifact,
|
|
5018
|
+
mergeArtifacts,
|
|
4299
5019
|
pairToolTraces,
|
|
4300
5020
|
registerCapabilityAction,
|
|
4301
5021
|
registerChatComponent,
|
|
4302
5022
|
registerChatLayout,
|
|
4303
5023
|
registerChatShellComponent,
|
|
5024
|
+
resolveArtifactFileType,
|
|
5025
|
+
resolveArtifactFilename,
|
|
5026
|
+
resolveArtifactIcon,
|
|
5027
|
+
resolveArtifactIconName,
|
|
4304
5028
|
runChatTurn,
|
|
4305
5029
|
runRegenerateTurn,
|
|
5030
|
+
saveBlob,
|
|
4306
5031
|
useChatAutoScroll,
|
|
4307
5032
|
useChatServices,
|
|
4308
5033
|
useSidebarDrawer,
|