@zero-library/chat-copilot 3.1.9 → 3.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CloudUploadOutlined, PaperClipOutlined, createFromIconfontCN, LoadingOutlined, EnterOutlined, DownloadOutlined, CloseOutlined, PlayCircleOutlined, CopyOutlined, DotChartOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, SearchOutlined, UpOutlined, DownOutlined, PlusOutlined, CommentOutlined, RedoOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined, FileImageOutlined, FilePdfOutlined, FileWordOutlined, FileExcelOutlined, FilePptOutlined, FileZipOutlined, FileTextOutlined, FileUnknownOutlined } from '@ant-design/icons';
2
2
  import { Attachments, Sender, FileCard, Bubble, Think, XProvider, Mermaid, CodeHighlighter, Welcome, Prompts, Conversations } from '@ant-design/x-v2';
3
- import { useRefState, useDebounce, createTokenManager, useSyncInput, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, isDef, isNull, transform, emit, getWebSocketUrl, safeParseJson } from '@zero-library/common';
3
+ import { useRefState, useDebounce, createTokenManager, useSyncInput, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, emit, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, isDef, isNull, transform, getWebSocketUrl, safeParseJson } from '@zero-library/common';
4
4
  import { App, Badge, Button, Flex, Typography, Tooltip, Layout, Tag, Spin, Splitter, Image as Image$1, Popover, Skeleton, Alert, theme, Collapse, Divider as Divider$1, Select as Select$1, Avatar, Space, Form, Drawer, Empty, Modal, Checkbox, Input, InputNumber, Switch as Switch$1, message, List, Upload, Card, Table, Progress as Progress$1 } from 'antd';
5
5
  import * as React10 from 'react';
6
6
  import React10__default, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, memo, useState, useContext, useCallback, useLayoutEffect } from 'react';
@@ -1327,7 +1327,7 @@ function createChatStore() {
1327
1327
  };
1328
1328
  const setConversationSpec = (spec) => {
1329
1329
  if (isObject(spec)) {
1330
- Object.assign(conversation.active.spec, spec);
1330
+ Object.assign(conversation.active.spec || {}, spec);
1331
1331
  }
1332
1332
  };
1333
1333
  const setConversationUserInput = (userInput) => {
@@ -1549,11 +1549,22 @@ function createChatStore() {
1549
1549
  conversation.messages[msg.conversationId].loading = false;
1550
1550
  const messages = conversation.messages[msg.conversationId]?.message;
1551
1551
  if (messages) {
1552
+ const idx = findExecutionMsgIndex(msg, messages);
1553
+ const contentItem = msg.content[0];
1552
1554
  messages.forEach((item) => {
1553
1555
  if (item.executionId === msg.executionId) {
1554
1556
  item.generating = false;
1555
1557
  }
1556
1558
  });
1559
+ if (contentItem?.type === "runFailed") {
1560
+ if (idx !== -1) {
1561
+ const prevContent = messages[idx]?.content || [];
1562
+ messages[idx].content = [...prevContent, contentItem];
1563
+ } else {
1564
+ const finalMsg = { ...msg, generating: false };
1565
+ messages.push(finalMsg);
1566
+ }
1567
+ }
1557
1568
  }
1558
1569
  config.hooks?.onAfterAcceptMessage?.(msg);
1559
1570
  }
@@ -2591,6 +2602,7 @@ var AgentNavigate_default = memo(({ data }) => {
2591
2602
  }, [data]);
2592
2603
  const handleClick = () => {
2593
2604
  if (!content?.emit) return;
2605
+ emit(content.emit, { ...content.data, name: "luya-web-drawer" }, "nearest");
2594
2606
  };
2595
2607
  return /* @__PURE__ */ jsx(Button, { onClick: handleClick, style: { padding: 0 }, type: "link", children: content?.name || "\u70B9\u51FB\u6B64\u5904" });
2596
2608
  });
@@ -2801,9 +2813,7 @@ var MdEdit_default = ({ data, loading }) => {
2801
2813
  };
2802
2814
  var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2803
2815
  const chatStore = useChatStore();
2804
- const getLinkFileName = (href) => {
2805
- const url = new URL(href, window.location.origin);
2806
- const path = url.searchParams.get("path") || url.pathname;
2816
+ const getLinkFileName = (path) => {
2807
2817
  const lastSegment = path.split("/").pop();
2808
2818
  if (!lastSegment) {
2809
2819
  return "link";
@@ -2814,24 +2824,12 @@ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2814
2824
  return lastSegment;
2815
2825
  }
2816
2826
  };
2817
- const getPreviewFileUrl = (href) => {
2818
- return buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, href);
2819
- };
2820
- const handlePreviewLink = (href) => {
2821
- const fileName = getLinkFileName(href);
2822
- const suffix = getFileSuffixName(fileName);
2823
- chatStore.setPreview({
2824
- fileUrl: getPreviewFileUrl(href),
2825
- fileName,
2826
- suffix
2827
- });
2828
- };
2829
- const handlePathToUrl = (href) => {
2830
- const fileName = getLinkFileName(href);
2827
+ const handlePreviewByPath = (path) => {
2828
+ const fileName = getLinkFileName(path);
2831
2829
  const suffix = getFileSuffixName(fileName);
2832
2830
  chatStore.setPreview({
2833
2831
  fileUrl: chatStore.config.services.request.getPreviewUrl({
2834
- path: href,
2832
+ path,
2835
2833
  workspaceId: message3.conversationId
2836
2834
  }),
2837
2835
  fileName,
@@ -2845,12 +2843,18 @@ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2845
2843
  return;
2846
2844
  }
2847
2845
  e.preventDefault();
2848
- if (String(rest.href).startsWith("/luya")) {
2849
- handlePreviewLink(href);
2846
+ if (String(rest.href).startsWith("/luya") || String(rest.href).startsWith("/agents")) {
2847
+ const url = new URL(href, window.location.origin);
2848
+ const path = url.searchParams.get("path");
2849
+ if (!path) {
2850
+ window.open(href, "_blank");
2851
+ return;
2852
+ }
2853
+ handlePreviewByPath(path);
2850
2854
  return;
2851
2855
  }
2852
2856
  if (String(rest.href).startsWith("/workspace")) {
2853
- handlePathToUrl(href);
2857
+ handlePreviewByPath(href);
2854
2858
  return;
2855
2859
  }
2856
2860
  window.open(href, "_blank");
@@ -3359,11 +3363,8 @@ var A2uiComponents = {
3359
3363
 
3360
3364
  // src/components/CustomComponents/A2uiRuntime/controller/extract.ts
3361
3365
  var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
3362
- function hasA2uiTag(text) {
3363
- return typeof text === "string" && text.includes("<A2UI");
3364
- }
3365
3366
  function parseA2uiTagsFromText(text) {
3366
- if (!hasA2uiTag(text)) return [];
3367
+ if (typeof text !== "string" || !text.includes("<A2UI")) return [];
3367
3368
  const tags = [];
3368
3369
  const regex = new RegExp(A2UI_TAG_REGEX);
3369
3370
  let match;
@@ -3381,61 +3382,17 @@ function parseA2uiTagsFromText(text) {
3381
3382
  return tags;
3382
3383
  }
3383
3384
  function stripA2uiTags(text) {
3384
- if (!hasA2uiTag(text)) return text;
3385
- let result = text.replace(A2UI_TAG_REGEX, "");
3386
- result = result.replace(/<A2UI\b[\s\S]*$/, "");
3387
- return result.trim();
3388
- }
3389
- function splitA2uiTextSegments(text) {
3390
- if (typeof text !== "string" || !text.includes("<A2UI")) {
3391
- return text ? [{ type: "text", content: text }] : [];
3392
- }
3393
- const segments = [];
3394
- const regex = new RegExp(A2UI_TAG_REGEX);
3395
- let lastIndex = 0;
3396
- let match;
3397
- while ((match = regex.exec(text)) !== null) {
3398
- if (match.index > lastIndex) {
3399
- const before = text.slice(lastIndex, match.index);
3400
- if (before) segments.push({ type: "text", content: before });
3401
- }
3402
- const json = match[2].trim();
3403
- if (json) {
3404
- try {
3405
- const parsed = JSON.parse(json);
3406
- const commands = Array.isArray(parsed) ? parsed : [parsed];
3407
- const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
3408
- if (surfaceIds.length) {
3409
- segments.push({ type: "a2ui", surfaceIds });
3410
- }
3411
- } catch {
3412
- }
3413
- }
3414
- lastIndex = regex.lastIndex;
3415
- }
3416
- if (lastIndex < text.length) {
3417
- let remaining = text.slice(lastIndex);
3418
- remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
3419
- if (remaining) segments.push({ type: "text", content: remaining });
3420
- }
3421
- return segments.length ? segments : [];
3385
+ if (typeof text !== "string" || !text.includes("<A2UI")) return text;
3386
+ return text.replace(A2UI_TAG_REGEX, "").trim();
3422
3387
  }
3423
- function extractInlineSurfaceIdsFromMessage(message3) {
3424
- const surfaceIds = /* @__PURE__ */ new Set();
3425
- const items = Array.isArray(message3?.content) ? message3.content : [];
3426
- for (const item of items) {
3427
- if (item?.type !== "text") continue;
3428
- const text = item.messageContent || item.text || "";
3429
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
3430
- const tags = parseA2uiTagsFromText(text);
3431
- for (const tag of tags) {
3432
- for (const cmd of tag.commands) {
3433
- const sid = String(cmd?.createSurface?.surfaceId || "").trim();
3434
- if (sid) surfaceIds.add(sid);
3435
- }
3436
- }
3388
+ function extractItemTextForA2ui(item) {
3389
+ if (!item || item.type !== "toolCall") return "";
3390
+ const result = item.result;
3391
+ if (typeof result === "string") return result;
3392
+ if (result && typeof result === "object" && typeof result.stdout === "string") {
3393
+ return result.stdout;
3437
3394
  }
3438
- return surfaceIds;
3395
+ return "";
3439
3396
  }
3440
3397
  function extractDismissedSurfaceIdsFromMessages(messages) {
3441
3398
  const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
@@ -3449,15 +3406,13 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3449
3406
  const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
3450
3407
  if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3451
3408
  }
3452
- if (item?.type === "text") {
3453
- const text = item.messageContent || item.text || "";
3454
- if (typeof text === "string" && text.includes("<A2UI")) {
3455
- const tags = parseA2uiTagsFromText(text);
3456
- for (const tag of tags) {
3457
- for (const cmd of tag.commands) {
3458
- const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3459
- if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3460
- }
3409
+ const text = extractItemTextForA2ui(item);
3410
+ if (typeof text === "string" && text.includes("<A2UI")) {
3411
+ const tags = parseA2uiTagsFromText(text);
3412
+ for (const tag of tags) {
3413
+ for (const cmd of tag.commands) {
3414
+ const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3415
+ if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3461
3416
  }
3462
3417
  }
3463
3418
  }
@@ -3984,28 +3939,6 @@ function sanitizeA2uiCommands(commands) {
3984
3939
  return rest;
3985
3940
  });
3986
3941
  }
3987
- function diffConversationMessages(messages, prevCursors) {
3988
- if (messages.length < prevCursors.length) {
3989
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
3990
- }
3991
- const nextCursors = [];
3992
- const pendingItems = [];
3993
- for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3994
- const message3 = messages[messageIndex];
3995
- const messageId = String(message3?.messageId ?? messageIndex);
3996
- const items = Array.isArray(message3?.content) ? message3.content : [];
3997
- const prevCursor = prevCursors[messageIndex];
3998
- const startIndex = prevCursor ? prevCursor.contentLength : 0;
3999
- if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
4000
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4001
- }
4002
- for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
4003
- pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
4004
- }
4005
- nextCursors.push({ messageId, contentLength: items.length });
4006
- }
4007
- return { shouldReplayAll: false, nextCursors, pendingItems };
4008
- }
4009
3942
  function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
4010
3943
  const wizard = state.wizardSchemaBySurface[surfaceId];
4011
3944
  const createCommandIndex = state.latestCreateCommandIndexBySurface[surfaceId];
@@ -4025,6 +3958,10 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
4025
3958
  function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
4026
3959
  nextState.serverCommands.push(cmd);
4027
3960
  nextState.lastA2uiHost = { id: messageId, index: messageIndex };
3961
+ const wizardSchema = normalizeWizardSchema(cmd);
3962
+ if (wizardSchema) {
3963
+ nextState.wizardSchemaBySurface[wizardSchema.surfaceId] = wizardSchema;
3964
+ }
4028
3965
  const surfaceId = extractSurfaceId2(cmd);
4029
3966
  if (!surfaceId) return;
4030
3967
  if (cmd?.createSurface) {
@@ -4035,6 +3972,11 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
4035
3972
  if (cmd?.createSurface) {
4036
3973
  nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
4037
3974
  nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
3975
+ const schemaSource = cmd.createSurface.schema ?? cmd.createSurface.wizard ?? cmd.createSurface.plan;
3976
+ const schema = normalizeWizardSchema(schemaSource) ?? normalizeWizardSchema(cmd.createSurface);
3977
+ if (schema) {
3978
+ nextState.wizardSchemaBySurface[surfaceId] = schema;
3979
+ }
4038
3980
  initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
4039
3981
  }
4040
3982
  if (cmd?.updateDataModel) {
@@ -4051,6 +3993,28 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
4051
3993
  delete nextState.modelPathBySurface[surfaceId];
4052
3994
  }
4053
3995
  }
3996
+ function diffConversationMessages(messages, prevCursors) {
3997
+ if (messages.length < prevCursors.length) {
3998
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
3999
+ }
4000
+ const nextCursors = [];
4001
+ const pendingItems = [];
4002
+ for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
4003
+ const message3 = messages[messageIndex];
4004
+ const messageId = String(message3?.messageId ?? messageIndex);
4005
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4006
+ const prevCursor = prevCursors[messageIndex];
4007
+ const startIndex = prevCursor ? prevCursor.contentLength : 0;
4008
+ if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
4009
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4010
+ }
4011
+ for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
4012
+ pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
4013
+ }
4014
+ nextCursors.push({ messageId, contentLength: items.length });
4015
+ }
4016
+ return { shouldReplayAll: false, nextCursors, pendingItems };
4017
+ }
4054
4018
  function scanA2uiTagsFromMessages(messages, processedTagIds) {
4055
4019
  const newTags = [];
4056
4020
  const newTagIds = [];
@@ -4059,8 +4023,7 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
4059
4023
  const messageId = String(message3?.messageId ?? messageIndex);
4060
4024
  const items = Array.isArray(message3?.content) ? message3.content : [];
4061
4025
  for (const item of items) {
4062
- if (item?.type !== "text") continue;
4063
- const text = item.messageContent || item.text || "";
4026
+ const text = extractItemTextForA2ui(item);
4064
4027
  if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4065
4028
  const tags = parseA2uiTagsFromText(text);
4066
4029
  for (const tag of tags) {
@@ -4075,14 +4038,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
4075
4038
  }
4076
4039
  function reduceA2uiRuntimeMessages(state, messages) {
4077
4040
  const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
4078
- const itemsToProcess = shouldReplayAll ? messages.flatMap((message3, messageIndex) => {
4079
- const messageId = String(message3?.messageId ?? messageIndex);
4080
- const items = Array.isArray(message3?.content) ? message3.content : [];
4081
- return items.map((item) => ({ messageIndex, messageId, item }));
4082
- }) : pendingItems;
4083
4041
  const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
4084
4042
  const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
4085
- if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
4043
+ if (!shouldReplayAll && pendingItems.length === 0 && newTags.length === 0) {
4086
4044
  return { state, effects: [] };
4087
4045
  }
4088
4046
  const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
@@ -4101,7 +4059,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
4101
4059
  const effects = shouldReplayAll ? [{ type: "reset-model-store" }] : [];
4102
4060
  const deletedSurfaceIds = /* @__PURE__ */ new Set();
4103
4061
  const nextWizardSteps = {};
4104
- itemsToProcess.forEach(({ item, messageIndex, messageId }) => {
4062
+ pendingItems.forEach(({ item, messageIndex, messageId }) => {
4105
4063
  if (item?.type === "a2uiSchema") {
4106
4064
  const schema = normalizeWizardSchema(item.schema);
4107
4065
  if (schema) {
@@ -4270,11 +4228,9 @@ var A2uiRuntimeContext = React10__default.createContext({
4270
4228
  function useA2uiRuntimeView() {
4271
4229
  return React10__default.useContext(A2uiRuntimeContext);
4272
4230
  }
4273
- function A2uiMessageCards({ messageIndex, message: message3 }) {
4231
+ function A2uiMessageCards({ messageIndex }) {
4274
4232
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4275
- const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4276
- const inlineSurfaceIds = message3 ? extractInlineSurfaceIdsFromMessage(message3) : /* @__PURE__ */ new Set();
4277
- const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
4233
+ const surfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4278
4234
  if (!surfaceIds.length) return null;
4279
4235
  return /* @__PURE__ */ jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
4280
4236
  }
@@ -4480,16 +4436,14 @@ function buildLatestCommandIndexBySurface(messages) {
4480
4436
  if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4481
4437
  continue;
4482
4438
  }
4483
- if (item?.type === "text") {
4484
- const text = item.messageContent || item.text || "";
4485
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4486
- const tags = parseA2uiTagsFromText(text);
4487
- for (const tag of tags) {
4488
- for (const cmd of tag.commands) {
4489
- commandIndex += 1;
4490
- const surfaceId = extractSurfaceId3(cmd);
4491
- if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4492
- }
4439
+ const text = extractItemTextForA2ui(item);
4440
+ if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4441
+ const tags = parseA2uiTagsFromText(text);
4442
+ for (const tag of tags) {
4443
+ for (const cmd of tag.commands) {
4444
+ commandIndex += 1;
4445
+ const surfaceId = extractSurfaceId3(cmd);
4446
+ if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4493
4447
  }
4494
4448
  }
4495
4449
  }
@@ -4658,39 +4612,20 @@ var TextNode2 = React10__default.memo(
4658
4612
  item,
4659
4613
  role,
4660
4614
  customComponents,
4661
- message: message3,
4662
- messageIndex = -1
4615
+ message: message3
4663
4616
  }) => {
4664
- const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4665
- const rawContent = toA2uiDisplayText(role, item?.messageContent);
4666
- const segments = splitA2uiTextSegments(rawContent);
4617
+ const content = toA2uiDisplayText(role, item?.messageContent);
4667
4618
  const markdownComponents = {
4668
4619
  [RESOURCE_MARKDOWN_TAG]: MessageResourceTag,
4669
4620
  ...customComponents
4670
4621
  };
4671
- const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
4672
- const firstSeg = segments[0];
4673
- const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
4674
- if (isPureText) {
4675
- const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
4676
- if (typeof content === "string" && content.startsWith("Question:")) {
4677
- return /* @__PURE__ */ jsx(QuestionSummary, { content });
4678
- }
4679
- const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4680
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4681
- !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4682
- !!markdownContent && /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4683
- ] });
4622
+ if (typeof content === "string" && content.startsWith("Question:")) {
4623
+ return /* @__PURE__ */ jsx(QuestionSummary, { content });
4684
4624
  }
4625
+ const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4685
4626
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4686
4627
  !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4687
- segments.map((seg, i) => {
4688
- if (seg.type === "text") {
4689
- const markdownContent = transformResourceText(seg.content);
4690
- return seg.content.trim() ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent }, `text-${i}`) : null;
4691
- }
4692
- return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
4693
- })
4628
+ !!markdownContent && /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4694
4629
  ] });
4695
4630
  }
4696
4631
  );
@@ -4788,6 +4723,15 @@ var getToolRenderConfig = (toolName) => {
4788
4723
  alwaysShowContent: false
4789
4724
  };
4790
4725
  };
4726
+ function stripA2uiTagsFromResult(result) {
4727
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result;
4728
+ const cleaned = {};
4729
+ for (const [key, value] of Object.entries(result)) {
4730
+ cleaned[key] = typeof value === "string" && value.includes("<A2UI") ? stripA2uiTags(value) : value;
4731
+ }
4732
+ const hasVisible = Object.values(cleaned).some((v) => v !== "" && v !== null && v !== void 0);
4733
+ return hasVisible ? cleaned : null;
4734
+ }
4791
4735
  var formatContent = (content) => {
4792
4736
  try {
4793
4737
  if (!content) return { text: "", isJson: false, parsed: null };
@@ -4798,9 +4742,11 @@ var formatContent = (content) => {
4798
4742
  if (typeof parsed === "object" && parsed !== null) {
4799
4743
  return { text: JSON.stringify(parsed, null, 2), isJson: true, parsed };
4800
4744
  }
4801
- return { text: content, isJson: false, parsed: null };
4745
+ const stripped = content.includes("<A2UI") ? stripA2uiTags(content) : content;
4746
+ return { text: stripped, isJson: false, parsed: null };
4802
4747
  } catch {
4803
- return { text: typeof content === "string" ? content : "", isJson: false, parsed: null };
4748
+ const text = typeof content === "string" ? content.includes("<A2UI") ? stripA2uiTags(content) : content : "";
4749
+ return { text, isJson: false, parsed: null };
4804
4750
  }
4805
4751
  };
4806
4752
  var ToolCallItem = ({ item }) => {
@@ -4814,7 +4760,12 @@ var ToolCallItem = ({ item }) => {
4814
4760
  return "running";
4815
4761
  }, [item.status, item.errorMessage, item.result]);
4816
4762
  const argsContent = useMemo(() => formatContent(item.arguments || item.content), [item.arguments, item.content]);
4817
- const resultContent = useMemo(() => item.result ? formatContent(item.result) : null, [item.result]);
4763
+ const resultContent = useMemo(() => {
4764
+ if (!item.result) return null;
4765
+ const cleanedResult = stripA2uiTagsFromResult(item.result);
4766
+ if (!cleanedResult) return null;
4767
+ return formatContent(cleanedResult);
4768
+ }, [item.result]);
4818
4769
  const hasContent = useMemo(() => {
4819
4770
  if (renderConfig.disableExpandOnError && status === "error") return false;
4820
4771
  let alwaysShow = false;
@@ -4905,7 +4856,7 @@ var ToolCallItem = ({ item }) => {
4905
4856
  );
4906
4857
  };
4907
4858
  var tool_call_item_default = ToolCallItem;
4908
- var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "files", "plan"];
4859
+ var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "runFailed", "files", "plan"];
4909
4860
  var MessageRender_default = React10__default.memo(({ role, message: message3, messageIndex = -1, loading, containerRef, customComponents }) => {
4910
4861
  const content = useMemo(() => {
4911
4862
  return (message3.content || []).filter((item) => {
@@ -4920,9 +4871,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4920
4871
  }
4921
4872
  if (item.type === "text") {
4922
4873
  const rawText = item.messageContent || item.text || "";
4923
- const visibleText = stripA2uiTags(rawText);
4924
- const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
4925
- return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
4874
+ return !!rawText.trim() || !!item.reasoningContent;
4926
4875
  }
4927
4876
  return true;
4928
4877
  });
@@ -4941,9 +4890,16 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4941
4890
  return isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4942
4891
  }, [message3.params, message3.quoteMsg]);
4943
4892
  if (content.length === 0) return null;
4893
+ const lastToolCallIndex = (() => {
4894
+ let lastIdx = -1;
4895
+ content.forEach((item, i) => {
4896
+ if (item.type === "toolCall" || item.type === "toolResult") lastIdx = i;
4897
+ });
4898
+ return lastIdx;
4899
+ })();
4944
4900
  return /* @__PURE__ */ jsxs(Flex, { ref: containerRef, vertical: true, gap: 8, children: [
4945
- content.map((item, index) => {
4946
- return /* @__PURE__ */ jsx(
4901
+ content.map((item, index) => /* @__PURE__ */ jsxs(React10__default.Fragment, { children: [
4902
+ /* @__PURE__ */ jsx(
4947
4903
  Bubble,
4948
4904
  {
4949
4905
  role: role.user,
@@ -4952,17 +4908,26 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4952
4908
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
4953
4909
  item.type === "runStarted" && /* @__PURE__ */ jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4954
4910
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4955
- item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message3.role, customComponents, message: message3, messageIndex }, `message-${index}`),
4956
- item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4911
+ item.type === "text" && /* @__PURE__ */ jsx(
4912
+ TextNode2,
4913
+ {
4914
+ item,
4915
+ role: message3.role,
4916
+ customComponents,
4917
+ message: message3,
4918
+ messageIndex
4919
+ },
4920
+ `message-${index}`
4921
+ ),
4922
+ (item.type === "stepError" || item.type === "runFailed") && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4957
4923
  item.type === "files" && /* @__PURE__ */ jsx(FilesNode, { item }, `files-${index}`),
4958
4924
  item.type === "plan" && /* @__PURE__ */ jsx(A2uiPlanNode, { item }, `plan-${index}`)
4959
4925
  ] })
4960
- },
4961
- `message-${index}`
4962
- );
4963
- }),
4964
- quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role }),
4965
- messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4926
+ }
4927
+ ),
4928
+ index === lastToolCallIndex && messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4929
+ ] }, `message-${index}`)),
4930
+ quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role })
4966
4931
  ] });
4967
4932
  });
4968
4933
  var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {