@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.cjs.js CHANGED
@@ -1356,7 +1356,7 @@ function createChatStore() {
1356
1356
  };
1357
1357
  const setConversationSpec = (spec) => {
1358
1358
  if (common.isObject(spec)) {
1359
- Object.assign(conversation.active.spec, spec);
1359
+ Object.assign(conversation.active.spec || {}, spec);
1360
1360
  }
1361
1361
  };
1362
1362
  const setConversationUserInput = (userInput) => {
@@ -1578,11 +1578,22 @@ function createChatStore() {
1578
1578
  conversation.messages[msg.conversationId].loading = false;
1579
1579
  const messages = conversation.messages[msg.conversationId]?.message;
1580
1580
  if (messages) {
1581
+ const idx = findExecutionMsgIndex(msg, messages);
1582
+ const contentItem = msg.content[0];
1581
1583
  messages.forEach((item) => {
1582
1584
  if (item.executionId === msg.executionId) {
1583
1585
  item.generating = false;
1584
1586
  }
1585
1587
  });
1588
+ if (contentItem?.type === "runFailed") {
1589
+ if (idx !== -1) {
1590
+ const prevContent = messages[idx]?.content || [];
1591
+ messages[idx].content = [...prevContent, contentItem];
1592
+ } else {
1593
+ const finalMsg = { ...msg, generating: false };
1594
+ messages.push(finalMsg);
1595
+ }
1596
+ }
1586
1597
  }
1587
1598
  config.hooks?.onAfterAcceptMessage?.(msg);
1588
1599
  }
@@ -2620,6 +2631,7 @@ var AgentNavigate_default = React10.memo(({ data }) => {
2620
2631
  }, [data]);
2621
2632
  const handleClick = () => {
2622
2633
  if (!content?.emit) return;
2634
+ common.emit(content.emit, { ...content.data, name: "luya-web-drawer" }, "nearest");
2623
2635
  };
2624
2636
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: handleClick, style: { padding: 0 }, type: "link", children: content?.name || "\u70B9\u51FB\u6B64\u5904" });
2625
2637
  });
@@ -2830,9 +2842,7 @@ var MdEdit_default = ({ data, loading }) => {
2830
2842
  };
2831
2843
  var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2832
2844
  const chatStore = useChatStore();
2833
- const getLinkFileName = (href) => {
2834
- const url = new URL(href, window.location.origin);
2835
- const path = url.searchParams.get("path") || url.pathname;
2845
+ const getLinkFileName = (path) => {
2836
2846
  const lastSegment = path.split("/").pop();
2837
2847
  if (!lastSegment) {
2838
2848
  return "link";
@@ -2843,24 +2853,12 @@ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2843
2853
  return lastSegment;
2844
2854
  }
2845
2855
  };
2846
- const getPreviewFileUrl = (href) => {
2847
- return common.buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, href);
2848
- };
2849
- const handlePreviewLink = (href) => {
2850
- const fileName = getLinkFileName(href);
2851
- const suffix = common.getFileSuffixName(fileName);
2852
- chatStore.setPreview({
2853
- fileUrl: getPreviewFileUrl(href),
2854
- fileName,
2855
- suffix
2856
- });
2857
- };
2858
- const handlePathToUrl = (href) => {
2859
- const fileName = getLinkFileName(href);
2856
+ const handlePreviewByPath = (path) => {
2857
+ const fileName = getLinkFileName(path);
2860
2858
  const suffix = common.getFileSuffixName(fileName);
2861
2859
  chatStore.setPreview({
2862
2860
  fileUrl: chatStore.config.services.request.getPreviewUrl({
2863
- path: href,
2861
+ path,
2864
2862
  workspaceId: message3.conversationId
2865
2863
  }),
2866
2864
  fileName,
@@ -2874,12 +2872,18 @@ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2874
2872
  return;
2875
2873
  }
2876
2874
  e.preventDefault();
2877
- if (String(rest.href).startsWith("/luya")) {
2878
- handlePreviewLink(href);
2875
+ if (String(rest.href).startsWith("/luya") || String(rest.href).startsWith("/agents")) {
2876
+ const url = new URL(href, window.location.origin);
2877
+ const path = url.searchParams.get("path");
2878
+ if (!path) {
2879
+ window.open(href, "_blank");
2880
+ return;
2881
+ }
2882
+ handlePreviewByPath(path);
2879
2883
  return;
2880
2884
  }
2881
2885
  if (String(rest.href).startsWith("/workspace")) {
2882
- handlePathToUrl(href);
2886
+ handlePreviewByPath(href);
2883
2887
  return;
2884
2888
  }
2885
2889
  window.open(href, "_blank");
@@ -3388,11 +3392,8 @@ var A2uiComponents = {
3388
3392
 
3389
3393
  // src/components/CustomComponents/A2uiRuntime/controller/extract.ts
3390
3394
  var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
3391
- function hasA2uiTag(text) {
3392
- return typeof text === "string" && text.includes("<A2UI");
3393
- }
3394
3395
  function parseA2uiTagsFromText(text) {
3395
- if (!hasA2uiTag(text)) return [];
3396
+ if (typeof text !== "string" || !text.includes("<A2UI")) return [];
3396
3397
  const tags = [];
3397
3398
  const regex = new RegExp(A2UI_TAG_REGEX);
3398
3399
  let match;
@@ -3410,61 +3411,17 @@ function parseA2uiTagsFromText(text) {
3410
3411
  return tags;
3411
3412
  }
3412
3413
  function stripA2uiTags(text) {
3413
- if (!hasA2uiTag(text)) return text;
3414
- let result = text.replace(A2UI_TAG_REGEX, "");
3415
- result = result.replace(/<A2UI\b[\s\S]*$/, "");
3416
- return result.trim();
3417
- }
3418
- function splitA2uiTextSegments(text) {
3419
- if (typeof text !== "string" || !text.includes("<A2UI")) {
3420
- return text ? [{ type: "text", content: text }] : [];
3421
- }
3422
- const segments = [];
3423
- const regex = new RegExp(A2UI_TAG_REGEX);
3424
- let lastIndex = 0;
3425
- let match;
3426
- while ((match = regex.exec(text)) !== null) {
3427
- if (match.index > lastIndex) {
3428
- const before = text.slice(lastIndex, match.index);
3429
- if (before) segments.push({ type: "text", content: before });
3430
- }
3431
- const json = match[2].trim();
3432
- if (json) {
3433
- try {
3434
- const parsed = JSON.parse(json);
3435
- const commands = Array.isArray(parsed) ? parsed : [parsed];
3436
- const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
3437
- if (surfaceIds.length) {
3438
- segments.push({ type: "a2ui", surfaceIds });
3439
- }
3440
- } catch {
3441
- }
3442
- }
3443
- lastIndex = regex.lastIndex;
3444
- }
3445
- if (lastIndex < text.length) {
3446
- let remaining = text.slice(lastIndex);
3447
- remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
3448
- if (remaining) segments.push({ type: "text", content: remaining });
3449
- }
3450
- return segments.length ? segments : [];
3414
+ if (typeof text !== "string" || !text.includes("<A2UI")) return text;
3415
+ return text.replace(A2UI_TAG_REGEX, "").trim();
3451
3416
  }
3452
- function extractInlineSurfaceIdsFromMessage(message3) {
3453
- const surfaceIds = /* @__PURE__ */ new Set();
3454
- const items = Array.isArray(message3?.content) ? message3.content : [];
3455
- for (const item of items) {
3456
- if (item?.type !== "text") continue;
3457
- const text = item.messageContent || item.text || "";
3458
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
3459
- const tags = parseA2uiTagsFromText(text);
3460
- for (const tag of tags) {
3461
- for (const cmd of tag.commands) {
3462
- const sid = String(cmd?.createSurface?.surfaceId || "").trim();
3463
- if (sid) surfaceIds.add(sid);
3464
- }
3465
- }
3417
+ function extractItemTextForA2ui(item) {
3418
+ if (!item || item.type !== "toolCall") return "";
3419
+ const result = item.result;
3420
+ if (typeof result === "string") return result;
3421
+ if (result && typeof result === "object" && typeof result.stdout === "string") {
3422
+ return result.stdout;
3466
3423
  }
3467
- return surfaceIds;
3424
+ return "";
3468
3425
  }
3469
3426
  function extractDismissedSurfaceIdsFromMessages(messages) {
3470
3427
  const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
@@ -3478,15 +3435,13 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3478
3435
  const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
3479
3436
  if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3480
3437
  }
3481
- if (item?.type === "text") {
3482
- const text = item.messageContent || item.text || "";
3483
- if (typeof text === "string" && text.includes("<A2UI")) {
3484
- const tags = parseA2uiTagsFromText(text);
3485
- for (const tag of tags) {
3486
- for (const cmd of tag.commands) {
3487
- const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3488
- if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3489
- }
3438
+ const text = extractItemTextForA2ui(item);
3439
+ if (typeof text === "string" && text.includes("<A2UI")) {
3440
+ const tags = parseA2uiTagsFromText(text);
3441
+ for (const tag of tags) {
3442
+ for (const cmd of tag.commands) {
3443
+ const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3444
+ if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3490
3445
  }
3491
3446
  }
3492
3447
  }
@@ -4013,28 +3968,6 @@ function sanitizeA2uiCommands(commands) {
4013
3968
  return rest;
4014
3969
  });
4015
3970
  }
4016
- function diffConversationMessages(messages, prevCursors) {
4017
- if (messages.length < prevCursors.length) {
4018
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4019
- }
4020
- const nextCursors = [];
4021
- const pendingItems = [];
4022
- for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
4023
- const message3 = messages[messageIndex];
4024
- const messageId = String(message3?.messageId ?? messageIndex);
4025
- const items = Array.isArray(message3?.content) ? message3.content : [];
4026
- const prevCursor = prevCursors[messageIndex];
4027
- const startIndex = prevCursor ? prevCursor.contentLength : 0;
4028
- if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
4029
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4030
- }
4031
- for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
4032
- pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
4033
- }
4034
- nextCursors.push({ messageId, contentLength: items.length });
4035
- }
4036
- return { shouldReplayAll: false, nextCursors, pendingItems };
4037
- }
4038
3971
  function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
4039
3972
  const wizard = state.wizardSchemaBySurface[surfaceId];
4040
3973
  const createCommandIndex = state.latestCreateCommandIndexBySurface[surfaceId];
@@ -4054,6 +3987,10 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
4054
3987
  function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
4055
3988
  nextState.serverCommands.push(cmd);
4056
3989
  nextState.lastA2uiHost = { id: messageId, index: messageIndex };
3990
+ const wizardSchema = normalizeWizardSchema(cmd);
3991
+ if (wizardSchema) {
3992
+ nextState.wizardSchemaBySurface[wizardSchema.surfaceId] = wizardSchema;
3993
+ }
4057
3994
  const surfaceId = extractSurfaceId2(cmd);
4058
3995
  if (!surfaceId) return;
4059
3996
  if (cmd?.createSurface) {
@@ -4064,6 +4001,11 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
4064
4001
  if (cmd?.createSurface) {
4065
4002
  nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
4066
4003
  nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
4004
+ const schemaSource = cmd.createSurface.schema ?? cmd.createSurface.wizard ?? cmd.createSurface.plan;
4005
+ const schema = normalizeWizardSchema(schemaSource) ?? normalizeWizardSchema(cmd.createSurface);
4006
+ if (schema) {
4007
+ nextState.wizardSchemaBySurface[surfaceId] = schema;
4008
+ }
4067
4009
  initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
4068
4010
  }
4069
4011
  if (cmd?.updateDataModel) {
@@ -4080,6 +4022,28 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
4080
4022
  delete nextState.modelPathBySurface[surfaceId];
4081
4023
  }
4082
4024
  }
4025
+ function diffConversationMessages(messages, prevCursors) {
4026
+ if (messages.length < prevCursors.length) {
4027
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4028
+ }
4029
+ const nextCursors = [];
4030
+ const pendingItems = [];
4031
+ for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
4032
+ const message3 = messages[messageIndex];
4033
+ const messageId = String(message3?.messageId ?? messageIndex);
4034
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4035
+ const prevCursor = prevCursors[messageIndex];
4036
+ const startIndex = prevCursor ? prevCursor.contentLength : 0;
4037
+ if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
4038
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4039
+ }
4040
+ for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
4041
+ pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
4042
+ }
4043
+ nextCursors.push({ messageId, contentLength: items.length });
4044
+ }
4045
+ return { shouldReplayAll: false, nextCursors, pendingItems };
4046
+ }
4083
4047
  function scanA2uiTagsFromMessages(messages, processedTagIds) {
4084
4048
  const newTags = [];
4085
4049
  const newTagIds = [];
@@ -4088,8 +4052,7 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
4088
4052
  const messageId = String(message3?.messageId ?? messageIndex);
4089
4053
  const items = Array.isArray(message3?.content) ? message3.content : [];
4090
4054
  for (const item of items) {
4091
- if (item?.type !== "text") continue;
4092
- const text = item.messageContent || item.text || "";
4055
+ const text = extractItemTextForA2ui(item);
4093
4056
  if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4094
4057
  const tags = parseA2uiTagsFromText(text);
4095
4058
  for (const tag of tags) {
@@ -4104,14 +4067,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
4104
4067
  }
4105
4068
  function reduceA2uiRuntimeMessages(state, messages) {
4106
4069
  const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
4107
- const itemsToProcess = shouldReplayAll ? messages.flatMap((message3, messageIndex) => {
4108
- const messageId = String(message3?.messageId ?? messageIndex);
4109
- const items = Array.isArray(message3?.content) ? message3.content : [];
4110
- return items.map((item) => ({ messageIndex, messageId, item }));
4111
- }) : pendingItems;
4112
4070
  const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
4113
4071
  const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
4114
- if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
4072
+ if (!shouldReplayAll && pendingItems.length === 0 && newTags.length === 0) {
4115
4073
  return { state, effects: [] };
4116
4074
  }
4117
4075
  const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
@@ -4130,7 +4088,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
4130
4088
  const effects = shouldReplayAll ? [{ type: "reset-model-store" }] : [];
4131
4089
  const deletedSurfaceIds = /* @__PURE__ */ new Set();
4132
4090
  const nextWizardSteps = {};
4133
- itemsToProcess.forEach(({ item, messageIndex, messageId }) => {
4091
+ pendingItems.forEach(({ item, messageIndex, messageId }) => {
4134
4092
  if (item?.type === "a2uiSchema") {
4135
4093
  const schema = normalizeWizardSchema(item.schema);
4136
4094
  if (schema) {
@@ -4299,11 +4257,9 @@ var A2uiRuntimeContext = React10__namespace.default.createContext({
4299
4257
  function useA2uiRuntimeView() {
4300
4258
  return React10__namespace.default.useContext(A2uiRuntimeContext);
4301
4259
  }
4302
- function A2uiMessageCards({ messageIndex, message: message3 }) {
4260
+ function A2uiMessageCards({ messageIndex }) {
4303
4261
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4304
- const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4305
- const inlineSurfaceIds = message3 ? extractInlineSurfaceIdsFromMessage(message3) : /* @__PURE__ */ new Set();
4306
- const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
4262
+ const surfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4307
4263
  if (!surfaceIds.length) return null;
4308
4264
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
4309
4265
  }
@@ -4509,16 +4465,14 @@ function buildLatestCommandIndexBySurface(messages) {
4509
4465
  if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4510
4466
  continue;
4511
4467
  }
4512
- if (item?.type === "text") {
4513
- const text = item.messageContent || item.text || "";
4514
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4515
- const tags = parseA2uiTagsFromText(text);
4516
- for (const tag of tags) {
4517
- for (const cmd of tag.commands) {
4518
- commandIndex += 1;
4519
- const surfaceId = extractSurfaceId3(cmd);
4520
- if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4521
- }
4468
+ const text = extractItemTextForA2ui(item);
4469
+ if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4470
+ const tags = parseA2uiTagsFromText(text);
4471
+ for (const tag of tags) {
4472
+ for (const cmd of tag.commands) {
4473
+ commandIndex += 1;
4474
+ const surfaceId = extractSurfaceId3(cmd);
4475
+ if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4522
4476
  }
4523
4477
  }
4524
4478
  }
@@ -4687,39 +4641,20 @@ var TextNode2 = React10__namespace.default.memo(
4687
4641
  item,
4688
4642
  role,
4689
4643
  customComponents,
4690
- message: message3,
4691
- messageIndex = -1
4644
+ message: message3
4692
4645
  }) => {
4693
- const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4694
- const rawContent = toA2uiDisplayText(role, item?.messageContent);
4695
- const segments = splitA2uiTextSegments(rawContent);
4646
+ const content = toA2uiDisplayText(role, item?.messageContent);
4696
4647
  const markdownComponents = {
4697
4648
  [RESOURCE_MARKDOWN_TAG]: MessageResourceTag,
4698
4649
  ...customComponents
4699
4650
  };
4700
- const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
4701
- const firstSeg = segments[0];
4702
- const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
4703
- if (isPureText) {
4704
- const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
4705
- if (typeof content === "string" && content.startsWith("Question:")) {
4706
- return /* @__PURE__ */ jsxRuntime.jsx(QuestionSummary, { content });
4707
- }
4708
- const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4709
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4710
- !!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4711
- !!markdownContent && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4712
- ] });
4651
+ if (typeof content === "string" && content.startsWith("Question:")) {
4652
+ return /* @__PURE__ */ jsxRuntime.jsx(QuestionSummary, { content });
4713
4653
  }
4654
+ const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4714
4655
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4715
4656
  !!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4716
- segments.map((seg, i) => {
4717
- if (seg.type === "text") {
4718
- const markdownContent = transformResourceText(seg.content);
4719
- return seg.content.trim() ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent }, `text-${i}`) : null;
4720
- }
4721
- return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
4722
- })
4657
+ !!markdownContent && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4723
4658
  ] });
4724
4659
  }
4725
4660
  );
@@ -4817,6 +4752,15 @@ var getToolRenderConfig = (toolName) => {
4817
4752
  alwaysShowContent: false
4818
4753
  };
4819
4754
  };
4755
+ function stripA2uiTagsFromResult(result) {
4756
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result;
4757
+ const cleaned = {};
4758
+ for (const [key, value] of Object.entries(result)) {
4759
+ cleaned[key] = typeof value === "string" && value.includes("<A2UI") ? stripA2uiTags(value) : value;
4760
+ }
4761
+ const hasVisible = Object.values(cleaned).some((v) => v !== "" && v !== null && v !== void 0);
4762
+ return hasVisible ? cleaned : null;
4763
+ }
4820
4764
  var formatContent = (content) => {
4821
4765
  try {
4822
4766
  if (!content) return { text: "", isJson: false, parsed: null };
@@ -4827,9 +4771,11 @@ var formatContent = (content) => {
4827
4771
  if (typeof parsed === "object" && parsed !== null) {
4828
4772
  return { text: JSON.stringify(parsed, null, 2), isJson: true, parsed };
4829
4773
  }
4830
- return { text: content, isJson: false, parsed: null };
4774
+ const stripped = content.includes("<A2UI") ? stripA2uiTags(content) : content;
4775
+ return { text: stripped, isJson: false, parsed: null };
4831
4776
  } catch {
4832
- return { text: typeof content === "string" ? content : "", isJson: false, parsed: null };
4777
+ const text = typeof content === "string" ? content.includes("<A2UI") ? stripA2uiTags(content) : content : "";
4778
+ return { text, isJson: false, parsed: null };
4833
4779
  }
4834
4780
  };
4835
4781
  var ToolCallItem = ({ item }) => {
@@ -4843,7 +4789,12 @@ var ToolCallItem = ({ item }) => {
4843
4789
  return "running";
4844
4790
  }, [item.status, item.errorMessage, item.result]);
4845
4791
  const argsContent = React10.useMemo(() => formatContent(item.arguments || item.content), [item.arguments, item.content]);
4846
- const resultContent = React10.useMemo(() => item.result ? formatContent(item.result) : null, [item.result]);
4792
+ const resultContent = React10.useMemo(() => {
4793
+ if (!item.result) return null;
4794
+ const cleanedResult = stripA2uiTagsFromResult(item.result);
4795
+ if (!cleanedResult) return null;
4796
+ return formatContent(cleanedResult);
4797
+ }, [item.result]);
4847
4798
  const hasContent = React10.useMemo(() => {
4848
4799
  if (renderConfig.disableExpandOnError && status === "error") return false;
4849
4800
  let alwaysShow = false;
@@ -4934,7 +4885,7 @@ var ToolCallItem = ({ item }) => {
4934
4885
  );
4935
4886
  };
4936
4887
  var tool_call_item_default = ToolCallItem;
4937
- var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "files", "plan"];
4888
+ var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "runFailed", "files", "plan"];
4938
4889
  var MessageRender_default = React10__namespace.default.memo(({ role, message: message3, messageIndex = -1, loading, containerRef, customComponents }) => {
4939
4890
  const content = React10.useMemo(() => {
4940
4891
  return (message3.content || []).filter((item) => {
@@ -4949,9 +4900,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4949
4900
  }
4950
4901
  if (item.type === "text") {
4951
4902
  const rawText = item.messageContent || item.text || "";
4952
- const visibleText = stripA2uiTags(rawText);
4953
- const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
4954
- return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
4903
+ return !!rawText.trim() || !!item.reasoningContent;
4955
4904
  }
4956
4905
  return true;
4957
4906
  });
@@ -4970,9 +4919,16 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4970
4919
  return common.isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4971
4920
  }, [message3.params, message3.quoteMsg]);
4972
4921
  if (content.length === 0) return null;
4922
+ const lastToolCallIndex = (() => {
4923
+ let lastIdx = -1;
4924
+ content.forEach((item, i) => {
4925
+ if (item.type === "toolCall" || item.type === "toolResult") lastIdx = i;
4926
+ });
4927
+ return lastIdx;
4928
+ })();
4973
4929
  return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { ref: containerRef, vertical: true, gap: 8, children: [
4974
- content.map((item, index) => {
4975
- return /* @__PURE__ */ jsxRuntime.jsx(
4930
+ content.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React10__namespace.default.Fragment, { children: [
4931
+ /* @__PURE__ */ jsxRuntime.jsx(
4976
4932
  xV2.Bubble,
4977
4933
  {
4978
4934
  role: role.user,
@@ -4981,17 +4937,26 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4981
4937
  content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4982
4938
  item.type === "runStarted" && /* @__PURE__ */ jsxRuntime.jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4983
4939
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsxRuntime.jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4984
- item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message3.role, customComponents, message: message3, messageIndex }, `message-${index}`),
4985
- item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4940
+ item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(
4941
+ TextNode2,
4942
+ {
4943
+ item,
4944
+ role: message3.role,
4945
+ customComponents,
4946
+ message: message3,
4947
+ messageIndex
4948
+ },
4949
+ `message-${index}`
4950
+ ),
4951
+ (item.type === "stepError" || item.type === "runFailed") && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4986
4952
  item.type === "files" && /* @__PURE__ */ jsxRuntime.jsx(FilesNode, { item }, `files-${index}`),
4987
4953
  item.type === "plan" && /* @__PURE__ */ jsxRuntime.jsx(A2uiPlanNode, { item }, `plan-${index}`)
4988
4954
  ] })
4989
- },
4990
- `message-${index}`
4991
- );
4992
- }),
4993
- quoteMsg && /* @__PURE__ */ jsxRuntime.jsx(QuoteMsgNode, { quoteMsg, role }),
4994
- messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4955
+ }
4956
+ ),
4957
+ index === lastToolCallIndex && messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4958
+ ] }, `message-${index}`)),
4959
+ quoteMsg && /* @__PURE__ */ jsxRuntime.jsx(QuoteMsgNode, { quoteMsg, role })
4995
4960
  ] });
4996
4961
  });
4997
4962
  var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {