@agent-native/toolkit 0.204.0 → 0.204.1-nightly-20261008065100

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.
Files changed (168) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/dist/app/agent-page/AgentJobsTab.d.ts.map +1 -1
  3. package/dist/app/agent-page/AgentJobsTab.js +4 -2
  4. package/dist/app/agent-page/AgentJobsTab.js.map +1 -1
  5. package/dist/app/agent-page/AutomationDetailsDialog.d.ts +2 -1
  6. package/dist/app/agent-page/AutomationDetailsDialog.d.ts.map +1 -1
  7. package/dist/app/agent-page/AutomationDetailsDialog.js +8 -4
  8. package/dist/app/agent-page/AutomationDetailsDialog.js.map +1 -1
  9. package/dist/app/agent-page/ScheduledTriggerNotice.d.ts.map +1 -1
  10. package/dist/app/agent-page/ScheduledTriggerNotice.js +41 -19
  11. package/dist/app/agent-page/ScheduledTriggerNotice.js.map +1 -1
  12. package/dist/app/agent-page/use-jobs.d.ts +1 -1
  13. package/dist/app/agent-page/use-jobs.d.ts.map +1 -1
  14. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  15. package/dist/app/agentkit/react/components.js +124 -45
  16. package/dist/app/agentkit/react/components.js.map +1 -1
  17. package/dist/app/agentkit/react/context.d.ts +22 -1
  18. package/dist/app/agentkit/react/context.d.ts.map +1 -1
  19. package/dist/app/agentkit/react/context.js +14 -1
  20. package/dist/app/agentkit/react/context.js.map +1 -1
  21. package/dist/app/agentkit/react/root.d.ts +3 -2
  22. package/dist/app/agentkit/react/root.d.ts.map +1 -1
  23. package/dist/app/agentkit/react/root.js +2 -2
  24. package/dist/app/agentkit/react/root.js.map +1 -1
  25. package/dist/app/agentkit/react/styles.css +32 -2
  26. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  27. package/dist/app/chat/AgentKitAssistantChat.js +74 -7
  28. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  29. package/dist/app/chat/AgentPanel.js +1 -1
  30. package/dist/app/chat/AgentPanel.js.map +1 -1
  31. package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
  32. package/dist/app/chat/MultiTabAssistantChat.js +10 -9
  33. package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
  34. package/dist/app/chat/RunStuckBanner.d.ts +8 -1
  35. package/dist/app/chat/RunStuckBanner.d.ts.map +1 -1
  36. package/dist/app/chat/RunStuckBanner.js +68 -6
  37. package/dist/app/chat/RunStuckBanner.js.map +1 -1
  38. package/dist/app/chat/chat/run-recovery.d.ts +4 -2
  39. package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
  40. package/dist/app/chat/chat/run-recovery.js +3 -3
  41. package/dist/app/chat/chat/run-recovery.js.map +1 -1
  42. package/dist/app/chat/chat/surface-types.d.ts +1 -0
  43. package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
  44. package/dist/app/chat/composer/use-mention-search.d.ts +1 -0
  45. package/dist/app/chat/composer/use-mention-search.d.ts.map +1 -1
  46. package/dist/app/chat/fallback-chat-title.d.ts +2 -0
  47. package/dist/app/chat/fallback-chat-title.d.ts.map +1 -0
  48. package/dist/app/chat/fallback-chat-title.js +11 -0
  49. package/dist/app/chat/fallback-chat-title.js.map +1 -0
  50. package/dist/app/chat/feedback-report.d.ts +12 -0
  51. package/dist/app/chat/feedback-report.d.ts.map +1 -0
  52. package/dist/app/chat/feedback-report.js +21 -0
  53. package/dist/app/chat/feedback-report.js.map +1 -0
  54. package/dist/app/chat/reconcile-settled-run.d.ts +15 -0
  55. package/dist/app/chat/reconcile-settled-run.d.ts.map +1 -0
  56. package/dist/app/chat/reconcile-settled-run.js +41 -0
  57. package/dist/app/chat/reconcile-settled-run.js.map +1 -0
  58. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  59. package/dist/app/i18n/catalogs/ar-SA.js +9 -0
  60. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  61. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  62. package/dist/app/i18n/catalogs/de-DE.js +9 -0
  63. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  64. package/dist/app/i18n/catalogs/en-US.d.ts +9 -0
  65. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  66. package/dist/app/i18n/catalogs/en-US.js +9 -0
  67. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  68. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  69. package/dist/app/i18n/catalogs/es-ES.js +9 -0
  70. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  71. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  72. package/dist/app/i18n/catalogs/fr-FR.js +9 -0
  73. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  74. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  75. package/dist/app/i18n/catalogs/hi-IN.js +9 -0
  76. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  77. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  78. package/dist/app/i18n/catalogs/ja-JP.js +9 -0
  79. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  80. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  81. package/dist/app/i18n/catalogs/ko-KR.js +9 -0
  82. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  83. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  84. package/dist/app/i18n/catalogs/pt-BR.js +9 -0
  85. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  86. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  87. package/dist/app/i18n/catalogs/zh-CN.js +9 -0
  88. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  89. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  90. package/dist/app/i18n/catalogs/zh-TW.js +9 -0
  91. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  92. package/dist/app/providers/AppProviders.d.ts.map +1 -1
  93. package/dist/app/providers/AppProviders.js +7 -1
  94. package/dist/app/providers/AppProviders.js.map +1 -1
  95. package/dist/app/settings/shell/pages/audit.d.ts.map +1 -1
  96. package/dist/app/settings/shell/pages/audit.js +11 -2
  97. package/dist/app/settings/shell/pages/audit.js.map +1 -1
  98. package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
  99. package/dist/app/shared/AppShellSkeleton.js +4 -0
  100. package/dist/app/shared/AppShellSkeleton.js.map +1 -1
  101. package/dist/composer/ComposerContextMenu.d.ts +14 -1
  102. package/dist/composer/ComposerContextMenu.d.ts.map +1 -1
  103. package/dist/composer/ComposerContextMenu.js +65 -19
  104. package/dist/composer/ComposerContextMenu.js.map +1 -1
  105. package/dist/composer/MentionPopover.d.ts.map +1 -1
  106. package/dist/composer/MentionPopover.js +3 -3
  107. package/dist/composer/MentionPopover.js.map +1 -1
  108. package/dist/composer/PromptComposer.d.ts +1 -1
  109. package/dist/composer/PromptComposer.d.ts.map +1 -1
  110. package/dist/composer/TiptapComposer.d.ts +2 -2
  111. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  112. package/dist/composer/TiptapComposer.js +92 -36
  113. package/dist/composer/TiptapComposer.js.map +1 -1
  114. package/dist/composer/use-mention-search.d.ts +1 -0
  115. package/dist/composer/use-mention-search.d.ts.map +1 -1
  116. package/dist/composer/use-mention-search.js +8 -1
  117. package/dist/composer/use-mention-search.js.map +1 -1
  118. package/package.json +4 -4
  119. package/src/app/agent-page/AgentJobsTab.blocked.spec.tsx +43 -0
  120. package/src/app/agent-page/AgentJobsTab.tsx +14 -5
  121. package/src/app/agent-page/AutomationDetailsDialog.tsx +22 -8
  122. package/src/app/agent-page/ScheduledTriggerNotice.spec.tsx +45 -3
  123. package/src/app/agent-page/ScheduledTriggerNotice.tsx +52 -31
  124. package/src/app/agent-page/use-jobs.ts +1 -1
  125. package/src/app/agentkit/react/components.interaction.spec.tsx +311 -1
  126. package/src/app/agentkit/react/components.spec.tsx +106 -2
  127. package/src/app/agentkit/react/components.tsx +217 -80
  128. package/src/app/agentkit/react/context.tsx +36 -0
  129. package/src/app/agentkit/react/root.tsx +4 -0
  130. package/src/app/agentkit/react/styles.css +32 -2
  131. package/src/app/chat/AgentKitAssistantChat.spec.tsx +140 -18
  132. package/src/app/chat/AgentKitAssistantChat.tsx +123 -7
  133. package/src/app/chat/AgentPanel.header.spec.ts +43 -7
  134. package/src/app/chat/AgentPanel.tsx +1 -1
  135. package/src/app/chat/MultiTabAssistantChat.spec.tsx +34 -0
  136. package/src/app/chat/MultiTabAssistantChat.tsx +10 -9
  137. package/src/app/chat/RunStuckBanner.spec.tsx +258 -17
  138. package/src/app/chat/RunStuckBanner.tsx +107 -5
  139. package/src/app/chat/chat/run-recovery.tsx +10 -2
  140. package/src/app/chat/chat/surface-types.ts +1 -0
  141. package/src/app/chat/fallback-chat-title.ts +10 -0
  142. package/src/app/chat/feedback-report.spec.ts +45 -0
  143. package/src/app/chat/feedback-report.ts +27 -0
  144. package/src/app/chat/reconcile-settled-run.spec.ts +112 -0
  145. package/src/app/chat/reconcile-settled-run.ts +57 -0
  146. package/src/app/i18n/catalogs/ar-SA.ts +12 -0
  147. package/src/app/i18n/catalogs/de-DE.ts +12 -0
  148. package/src/app/i18n/catalogs/en-US.ts +12 -0
  149. package/src/app/i18n/catalogs/es-ES.ts +12 -0
  150. package/src/app/i18n/catalogs/fr-FR.ts +12 -0
  151. package/src/app/i18n/catalogs/hi-IN.ts +12 -0
  152. package/src/app/i18n/catalogs/ja-JP.ts +12 -0
  153. package/src/app/i18n/catalogs/ko-KR.ts +12 -0
  154. package/src/app/i18n/catalogs/pt-BR.ts +12 -0
  155. package/src/app/i18n/catalogs/zh-CN.ts +10 -0
  156. package/src/app/i18n/catalogs/zh-TW.ts +10 -0
  157. package/src/app/providers/AppProviders.spec.tsx +29 -0
  158. package/src/app/providers/AppProviders.tsx +13 -0
  159. package/src/app/settings/shell/pages/audit.spec.tsx +30 -0
  160. package/src/app/settings/shell/pages/audit.tsx +12 -1
  161. package/src/app/shared/AppShellSkeleton.tsx +4 -0
  162. package/src/composer/ComposerContextMenu.tsx +94 -22
  163. package/src/composer/ComposerPlusMenu.parity.spec.tsx +218 -233
  164. package/src/composer/MentionPopover.tsx +12 -3
  165. package/src/composer/PromptComposer.context.spec.tsx +527 -195
  166. package/src/composer/PromptComposer.tsx +1 -1
  167. package/src/composer/TiptapComposer.tsx +105 -37
  168. package/src/composer/use-mention-search.ts +8 -1
@@ -1311,37 +1311,22 @@ function AgentMentionIcon({ icon }) {
1311
1311
  return _jsx(IconStack2, { ...props });
1312
1312
  }
1313
1313
  }
1314
+ // Only the composer's serialized `@[label|icon]` form is a mention. A bare
1315
+ // "@word" is whatever the user typed — an address, a handle, "@3pm" — and
1316
+ // rendering it as a chip claims a reference the message never carried.
1314
1317
  function renderUserMessageText(text) {
1315
1318
  const richMatches = Array.from(text.matchAll(/@\[([^\]|]+)\|([^\]]+)\]/g));
1316
- if (richMatches.length) {
1317
- const parts = [];
1318
- let lastIndex = 0;
1319
- richMatches.forEach((match, index) => {
1320
- const start = match.index ?? 0;
1321
- if (start > lastIndex)
1322
- parts.push(text.slice(lastIndex, start));
1323
- const label = match[1] ?? "";
1324
- parts.push(_jsxs("span", { className: "agentkit-mention", "data-mention-label": label, children: [_jsx(AgentMentionIcon, { icon: match[2] ?? "" }), _jsx("span", { className: "agentkit-mention-label", children: label })] }, `rich-mention:${start}:${index}`));
1325
- lastIndex = start + match[0].length;
1326
- });
1327
- if (lastIndex < text.length)
1328
- parts.push(text.slice(lastIndex));
1329
- return parts;
1330
- }
1331
- const plainMatches = Array.from(text.matchAll(/(^|\s)@(\w+)/g));
1332
- if (!plainMatches.length)
1319
+ if (!richMatches.length)
1333
1320
  return [text];
1334
1321
  const parts = [];
1335
1322
  let lastIndex = 0;
1336
- plainMatches.forEach((match, index) => {
1337
- const matchIndex = match.index ?? 0;
1338
- const start = matchIndex + (match[1]?.length ?? 0);
1339
- const end = matchIndex + match[0].length;
1323
+ richMatches.forEach((match, index) => {
1324
+ const start = match.index ?? 0;
1340
1325
  if (start > lastIndex)
1341
1326
  parts.push(text.slice(lastIndex, start));
1342
- const label = match[2] ?? "";
1343
- parts.push(_jsxs("span", { className: "agentkit-mention agentkit-mention--plain", "data-mention-label": label, children: ["@", label] }, `plain-mention:${start}:${index}`));
1344
- lastIndex = end;
1327
+ const label = match[1] ?? "";
1328
+ parts.push(_jsxs("span", { className: "agentkit-mention", "data-mention-label": label, children: [_jsx(AgentMentionIcon, { icon: match[2] ?? "" }), _jsx("span", { className: "agentkit-mention-label", children: label })] }, `rich-mention:${start}:${index}`));
1329
+ lastIndex = start + match[0].length;
1345
1330
  });
1346
1331
  if (lastIndex < text.length)
1347
1332
  parts.push(text.slice(lastIndex));
@@ -1537,7 +1522,7 @@ async function forkAndResubmitMessage({ controller, threadId, messages, sourceMe
1537
1522
  });
1538
1523
  }
1539
1524
  export function AgentMessageActions({ value: message, threadId, }) {
1540
- const { controller, labels, slots, onThreadForked, onCopyMessage, branchNavigation, loadRunUsage, } = useAgentKit();
1525
+ const { controller, labels, slots, onThreadForked, onCopyMessage, buildFeedbackReport, branchNavigation, loadRunUsage, } = useAgentKit();
1541
1526
  const thread = useAgentThread(threadId);
1542
1527
  const feedbackCapability = useAgentCapability("feedback");
1543
1528
  const forkingCapability = useAgentCapability("threadForking");
@@ -1555,6 +1540,8 @@ export function AgentMessageActions({ value: message, threadId, }) {
1555
1540
  const [feedbackReasonSubmitted, setFeedbackReasonSubmitted] = useState(false);
1556
1541
  const copiedTimer = useRef(null);
1557
1542
  const [requestIdCopied, setRequestIdCopied] = useState(false);
1543
+ const [feedbackDetailsCopied, setFeedbackDetailsCopied] = useState(false);
1544
+ const feedbackDetailsCopiedTimer = useRef(null);
1558
1545
  const [actionsMenuOpen, setActionsMenuOpen] = useState(false);
1559
1546
  const [usageDetails, setUsageDetails] = useState(null);
1560
1547
  const usageCacheRef = useRef(null);
@@ -1614,6 +1601,8 @@ export function AgentMessageActions({ value: message, threadId, }) {
1614
1601
  clearTimeout(copiedTimer.current);
1615
1602
  if (requestIdCopiedTimer.current)
1616
1603
  clearTimeout(requestIdCopiedTimer.current);
1604
+ if (feedbackDetailsCopiedTimer.current)
1605
+ clearTimeout(feedbackDetailsCopiedTimer.current);
1617
1606
  }, [message.id]);
1618
1607
  const copyAction = useAgentKitMutation(async () => {
1619
1608
  const handled = await onCopyMessage?.({ message, text });
@@ -1654,6 +1643,23 @@ export function AgentMessageActions({ value: message, threadId, }) {
1654
1643
  setRequestIdCopied(false);
1655
1644
  }, 1_400);
1656
1645
  }, `${threadId}:${message.id}:request-id:${requestId ?? "unavailable"}`);
1646
+ const copyFeedbackDetailsAction = useAgentKitMutation(async () => {
1647
+ if (!buildFeedbackReport)
1648
+ throw new Error(labels.copyUnavailable);
1649
+ const report = buildFeedbackReport({
1650
+ threadId,
1651
+ ...(runId ? { runId } : {}),
1652
+ messageId: message.id,
1653
+ note: feedbackReason,
1654
+ });
1655
+ if (!(await writeClipboardText(report))) {
1656
+ throw new Error(labels.copyUnavailable);
1657
+ }
1658
+ setFeedbackDetailsCopied(true);
1659
+ if (feedbackDetailsCopiedTimer.current)
1660
+ clearTimeout(feedbackDetailsCopiedTimer.current);
1661
+ feedbackDetailsCopiedTimer.current = setTimeout(() => setFeedbackDetailsCopied(false), 1_400);
1662
+ }, `${threadId}:${message.id}:feedback-details`);
1657
1663
  const forkAction = useAgentKitMutation(async () => {
1658
1664
  const thread = await control.fork(message.id);
1659
1665
  onThreadForked?.(thread);
@@ -1686,6 +1692,12 @@ export function AgentMessageActions({ value: message, threadId, }) {
1686
1692
  setFeedback(previous);
1687
1693
  }
1688
1694
  };
1695
+ const addFeedbackReason = (reason) => setFeedbackReason((current) => {
1696
+ if (current.includes(reason))
1697
+ return current;
1698
+ const trimmed = current.trim();
1699
+ return (trimmed ? `${trimmed}. ${reason}` : reason).slice(0, 2_000);
1700
+ });
1689
1701
  const submitFeedbackReason = async (event) => {
1690
1702
  event.preventDefault();
1691
1703
  const reason = feedbackReason.trim();
@@ -1705,6 +1717,7 @@ export function AgentMessageActions({ value: message, threadId, }) {
1705
1717
  feedbackAction.error ??
1706
1718
  branchNavigationAction.error ??
1707
1719
  requestIdAction.error ??
1720
+ copyFeedbackDetailsAction.error ??
1708
1721
  forkAction.error ??
1709
1722
  regenerateAction.error;
1710
1723
  const usageMenuItems = hasRunUsage
@@ -1833,10 +1846,19 @@ export function AgentMessageActions({ value: message, threadId, }) {
1833
1846
  setFeedbackReasonOpen(open);
1834
1847
  if (open)
1835
1848
  setFeedbackReasonSubmitted(false);
1836
- }, placement: "bottom", align: "start", className: "agentkit-feedback-popover", trigger: _jsx(IconButton, { label: labels.negativeFeedback, icon: _jsx(IconThumbDown, { "aria-hidden": "true" }), size: "compact", "aria-pressed": feedback === "negative", pending: feedbackAction.pending && feedback === "negative", disabled: feedbackAction.pending || !feedbackCapability.enabled, title: feedbackCapability.reason, onPress: () => void updateFeedback("negative") }), children: _jsxs("form", { className: "agentkit-feedback-form", onSubmit: submitFeedbackReason, children: [_jsx(TextArea, { label: labels.feedbackWhatWentWrong, value: feedbackReason, onChange: setFeedbackReason, placeholder: labels.feedbackPlaceholder, rows: 3, maxLength: 2_000, disabled: feedbackAction.pending, className: "agentkit-feedback-textarea" }), _jsxs("div", { className: "agentkit-feedback-footer", children: [_jsx("span", { children: labels.feedbackKeyboardHint.replace("{{shortcut}}", typeof navigator !== "undefined" &&
1849
+ }, placement: "bottom", align: "start", className: "agentkit-feedback-popover", trigger: _jsx(IconButton, { label: labels.negativeFeedback, icon: _jsx(IconThumbDown, { "aria-hidden": "true" }), size: "compact", "aria-pressed": feedback === "negative", pending: feedbackAction.pending && feedback === "negative", disabled: feedbackAction.pending || !feedbackCapability.enabled, title: feedbackCapability.reason, onPress: () => void updateFeedback("negative") }), children: _jsxs("form", { className: "agentkit-feedback-form", onSubmit: submitFeedbackReason, children: [_jsx(TextArea, { label: labels.feedbackWhatWentWrong, value: feedbackReason, onChange: setFeedbackReason, placeholder: labels.feedbackPlaceholder, rows: 3, maxLength: 2_000, disabled: feedbackAction.pending, className: "agentkit-feedback-textarea" }), _jsx("div", { className: "agentkit-feedback-reasons", children: [
1850
+ labels.feedbackReasonMisread,
1851
+ labels.feedbackReasonNotDone,
1852
+ labels.feedbackReasonWrongNumbers,
1853
+ labels.feedbackReasonTooSlow,
1854
+ ].map((reason) => (_jsx(ActionButton, { type: "button", size: "compact", emphasis: "outline", disabled: feedbackAction.pending, onPress: () => addFeedbackReason(reason), children: reason }, reason))) }), _jsxs("div", { className: "agentkit-feedback-footer", children: [_jsx("span", { children: labels.feedbackKeyboardHint.replace("{{shortcut}}", typeof navigator !== "undefined" &&
1837
1855
  /Mac|iPhone|iPad/.test(navigator.userAgent)
1838
1856
  ? "⌘"
1839
- : "Ctrl") }), _jsx(ActionButton, { type: "submit", intent: "primary", size: "compact", pending: feedbackAction.pending, disabled: feedbackAction.pending || !feedbackReason.trim(), children: labels.feedbackSubmit })] })] }) }), feedbackReasonSubmitted ? (_jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: labels.feedbackSubmitted })) : null] })) : null] }), _jsxs("div", { className: "agentkit-message-actions-trailing", children: [isLastAssistantMessage &&
1857
+ : "Ctrl") }), _jsxs("div", { className: "agentkit-feedback-actions", children: [buildFeedbackReport ? (_jsx(ActionButton, { type: "button", size: "compact", emphasis: "ghost", leadingIcon: feedbackDetailsCopied ? (_jsx(IconCircleCheck, { size: 14, "aria-hidden": "true" })) : (_jsx(IconCopy, { size: 14, "aria-hidden": "true" })), pending: copyFeedbackDetailsAction.pending, onPress: () => void copyFeedbackDetailsAction
1858
+ .execute()
1859
+ .catch(() => undefined), children: feedbackDetailsCopied
1860
+ ? labels.copied
1861
+ : labels.feedbackCopyDetails })) : null, _jsx(ActionButton, { type: "submit", intent: "primary", size: "compact", pending: feedbackAction.pending, disabled: feedbackAction.pending || !feedbackReason.trim(), children: labels.feedbackSubmit })] })] })] }) }), feedbackReasonSubmitted ? (_jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: labels.feedbackSubmitted })) : null] })) : null] }), _jsxs("div", { className: "agentkit-message-actions-trailing", children: [isLastAssistantMessage &&
1840
1862
  previousUserMessage &&
1841
1863
  forkingCapability.visible &&
1842
1864
  onThreadForked ? (_jsx(IconButton, { label: labels.regenerateResponse, icon: _jsx(IconRefresh, { "aria-hidden": "true" }), size: "compact", pending: regenerateAction.pending, disabled: regenerateAction.pending ||
@@ -1912,7 +1934,25 @@ function stripAgentContextMetadata(metadata) {
1912
1934
  }
1913
1935
  export function AgentRunFailure({ error, runId, threadId, }) {
1914
1936
  const { labels } = useAgentKit();
1915
- return (_jsxs("div", { className: "agentkit-run-failure", "data-error-code": error.code, "data-run-id": runId, "data-thread-id": threadId, role: "alert", children: [_jsx(IconAlertCircle, { "aria-hidden": "true", className: "agentkit-icon" }), _jsxs("div", { className: "agentkit-run-failure-copy", children: [_jsx("strong", { children: labels.runFailed }), _jsx("span", { children: error.message })] })] }));
1937
+ const control = useAgentKitControl(threadId);
1938
+ const thread = useAgentThread(threadId);
1939
+ const [continuing, setContinuing] = useState(false);
1940
+ const [continueFailed, setContinueFailed] = useState(false);
1941
+ // Continuing resumes the stopped run's own turn, so only that turn's newest
1942
+ // run can be continued; once anything ran after it, the card is history.
1943
+ const startedAt = thread.runs[runId]?.startedAt;
1944
+ const superseded = Object.values(thread.runs).some((run) => run.id !== runId &&
1945
+ Boolean(run.startedAt && startedAt && run.startedAt > startedAt));
1946
+ const canContinue = error.retryable === true && control.canContinueRun && !superseded;
1947
+ const continueRun = () => {
1948
+ setContinuing(true);
1949
+ setContinueFailed(false);
1950
+ control.continueRun(runId).catch(() => {
1951
+ setContinuing(false);
1952
+ setContinueFailed(true);
1953
+ });
1954
+ };
1955
+ return (_jsxs("div", { className: "agentkit-run-failure", "data-error-code": error.code, "data-run-id": runId, "data-thread-id": threadId, role: "alert", children: [_jsx(IconAlertCircle, { "aria-hidden": "true", className: "agentkit-icon" }), _jsxs("div", { className: "agentkit-run-failure-copy", children: [_jsx("strong", { children: labels.runFailed }), _jsx("span", { children: error.message }), canContinue ? (_jsx("div", { className: "agentkit-error-actions", children: _jsx(ActionButton, { emphasis: "outline", size: "compact", pending: continuing, onPress: continueRun, children: labels.continueRun }) })) : null, continueFailed ? (_jsx("span", { className: "agentkit-command-error", children: labels.continueRunUnavailable })) : null] })] }));
1916
1956
  }
1917
1957
  export function AgentConnectionErrorView({ error, threadId, recover, recovering, recoveryError, }) {
1918
1958
  const { labels } = useAgentKit();
@@ -2691,9 +2731,62 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
2691
2731
  return error ? (_jsx(RunFailure, { error: error, runId: runId, threadId: threadId })) : null;
2692
2732
  };
2693
2733
  const renderRunWork = ({ runId, anchor, afterSequence, throughSequence, }) => (_jsxs(AgentKitSurfaceBoundary, { surface: "activity", resetKey: `${runId}:${anchor}:${thread.events.length}`, children: [_jsx(AgentCollaborationFeed, { runId: runId, afterSequence: afterSequence, throughSequence: throughSequence }), _jsx(AgentTaskGroup, { runId: runId, afterSequence: afterSequence, throughSequence: throughSequence }), _jsx(AgentActivityGroup, { runId: runId, afterSequence: afterSequence, throughSequence: throughSequence, excludeAgentActivities: true, isCurrentSegment: throughSequence === undefined })] }, `run-work:${threadId}:${runId}:${anchor}`));
2734
+ const renderRunTail = (runId) => {
2735
+ const items = [];
2736
+ if (pendingRuns.has(runId)) {
2737
+ const boundary = lastAssistantMessagesByRun.get(runId);
2738
+ items.push(renderRunWork({
2739
+ runId,
2740
+ anchor: boundary?.id ?? "start",
2741
+ afterSequence: boundary?.sequence,
2742
+ }));
2743
+ }
2744
+ if (failedRuns.has(runId)) {
2745
+ items.push(_jsx(AgentKitSurfaceBoundary, { surface: "activity", resetKey: `${runId}:${thread.events.length}`, children: renderRunFailure(runId) }, `run-failure:${runId}`));
2746
+ }
2747
+ return items;
2748
+ };
2749
+ // A run's work after its last reply, and its failure, belong to its turn: a
2750
+ // finished run's tail goes before the first message written after it ended.
2751
+ const runEndedAt = new Map();
2752
+ for (const event of thread.events) {
2753
+ const occurredAt = Date.parse(event.occurredAt);
2754
+ if (!Number.isFinite(occurredAt))
2755
+ continue;
2756
+ runEndedAt.set(event.runId, Math.max(runEndedAt.get(event.runId) ?? occurredAt, occurredAt));
2757
+ }
2758
+ const tailRunIds = Array.from(new Set([
2759
+ ...pendingRunIds,
2760
+ ...Array.from(failedRuns.keys()).filter((runId) => !lastAssistantMessagesByRun.has(runId)),
2761
+ ]));
2762
+ const tailsBeforeMessage = new Map();
2763
+ const tailsAtEnd = [];
2764
+ for (const runId of tailRunIds) {
2765
+ const status = thread.runs[runId]?.status;
2766
+ const endedAt = runEndedAt.get(runId);
2767
+ const lastOwnMessage = thread.messages.findLastIndex((message) => messageRunIds.get(message.id) === runId);
2768
+ const before = endedAt !== undefined &&
2769
+ (status === "completed" || status === "failed" || status === "cancelled")
2770
+ ? thread.messages.findIndex((message, index) => index > lastOwnMessage &&
2771
+ messageRunIds.get(message.id) !== runId &&
2772
+ Date.parse(message.createdAt ?? "") > endedAt)
2773
+ : -1;
2774
+ if (before === -1) {
2775
+ tailsAtEnd.push(runId);
2776
+ }
2777
+ else {
2778
+ tailsBeforeMessage.set(before, [
2779
+ ...(tailsBeforeMessage.get(before) ?? []),
2780
+ runId,
2781
+ ]);
2782
+ }
2783
+ }
2694
2784
  const transcriptItems = [];
2695
2785
  const previousAssistantByRun = new Map();
2696
- for (const message of thread.messages) {
2786
+ for (const [messageIndex, message] of thread.messages.entries()) {
2787
+ for (const runId of tailsBeforeMessage.get(messageIndex) ?? []) {
2788
+ transcriptItems.push(...renderRunTail(runId));
2789
+ }
2697
2790
  const runId = messageRunIds.get(message.id);
2698
2791
  const sequence = messageBoundarySequences.get(message.id);
2699
2792
  const isAssistantBoundary = message.role === "assistant" &&
@@ -2745,22 +2838,8 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
2745
2838
  transcriptItems.push(_jsx(AgentKitSurfaceBoundary, { surface: "activity", resetKey: `${runId}:${thread.events.length}`, children: renderRunFailure(runId) }, `run-failure:${runId}`));
2746
2839
  }
2747
2840
  }
2748
- for (const runId of pendingRunIds) {
2749
- const boundary = lastAssistantMessagesByRun.get(runId);
2750
- transcriptItems.push(renderRunWork({
2751
- runId,
2752
- anchor: boundary?.id ?? "start",
2753
- afterSequence: boundary?.sequence,
2754
- }));
2755
- if (failedRuns.has(runId)) {
2756
- transcriptItems.push(_jsx(AgentKitSurfaceBoundary, { surface: "activity", resetKey: `${runId}:${thread.events.length}`, children: renderRunFailure(runId) }, `run-failure:${runId}`));
2757
- }
2758
- }
2759
- for (const [runId] of failedRuns) {
2760
- if (lastAssistantMessagesByRun.has(runId) || pendingRuns.has(runId)) {
2761
- continue;
2762
- }
2763
- transcriptItems.push(_jsx(AgentKitSurfaceBoundary, { surface: "activity", resetKey: `${runId}:${thread.events.length}`, children: renderRunFailure(runId) }, `run-failure:${runId}`));
2841
+ for (const runId of tailsAtEnd) {
2842
+ transcriptItems.push(...renderRunTail(runId));
2764
2843
  }
2765
2844
  return (_jsx(AgentMessageEditContext.Provider, { value: messageEditContext, children: _jsxs("section", { "aria-label": typeof title === "string" ? title : labels.conversation, className: `agentkit-chat ${className ?? ""}`, "data-empty": !hasConversation, "data-empty-composer-placement": hasConversation ? "bottom" : emptyComposerPlacement, onDragEnter: handleFileDragEnter, onDragOver: handleFileDragOver, onDragLeave: handleFileDragLeave, onDrop: handleFileDrop, children: [fileDragActive ? (_jsx("div", { className: "agentkit-file-drop-overlay", role: "status", children: labels.dropFilesToAttach })) : null, hasConversation && (title || toolbar) ? (_jsx(AgentKitSurfaceBoundary, { surface: "header", resetKey: threadId, children: _jsx(AgentKitRegionSlot, { slot: Header, threadId: threadId, children: _jsxs("header", { className: "agentkit-chat-header", children: [_jsx("div", { className: "agentkit-chat-title", children: title }), _jsx(AgentKitRegionSlot, { slot: Toolbar, threadId: threadId, children: _jsx("div", { className: "agentkit-chat-toolbar", children: toolbar }) })] }) }) })) : null, _jsxs("div", { ref: transcriptRef, className: "agentkit-transcript", "aria-live": "off", "data-scrollbar-visible": transcriptScrollbarVisible, onKeyDown: handleTranscriptKeyDown, onPointerDown: handleTranscriptPointerDown, onScroll: handleTranscriptScroll, onTouchMove: revealTranscriptScrollbar, onWheel: revealTranscriptScrollbar, children: [_jsx("div", { ref: transcriptContentRef, className: "agentkit-transcript-content", children: _jsxs(AgentKitRegionSlot, { slot: Transcript, threadId: threadId, children: [!hasConversation && EmptyState ? (_jsx(EmptyState, { threadId: threadId })) : null, transcriptItems, approvalEntries.map(([approvalId, request]) => (_jsx(AgentKitSurfaceBoundary, { surface: "approval", resetKey: `${approvalId}:${thread.events.length}`, children: Approval ? (_jsx(Approval, { value: request, threadId: threadId, runId: thread.approvalRunIds[approvalId] ?? "" })) : (_jsx(AgentApprovalPrompt, { request: request, runId: thread.approvalRunIds[approvalId] ?? "" })) }, `${threadId}:${approvalId}`))), connectionRequestEntries.map(([requestId, request]) => (_jsx(AgentKitSurfaceBoundary, { surface: "connection-request", resetKey: `${requestId}:${request.status}`, children: ConnectionRequest ? (_jsx(ConnectionRequest, { value: request, threadId: threadId, runId: thread.connectionRequestRunIds[requestId] ?? "" })) : (_jsx(AgentConnectionRequestCard, { request: request, runId: thread.connectionRequestRunIds[requestId] ?? "" })) }, `${threadId}:${requestId}`))), connectionError ? (_jsx(AgentKitSurfaceBoundary, { surface: "connection-error", resetKey: `${threadId}:${connectionError.code}`, children: _jsx(ErrorState, { error: connectionError, threadId: threadId, recover: recovery.execute, recovering: recovery.pending, recoveryError: recovery.error }) })) : null] }) }), transcriptAwayFromBottom ? (_jsx("div", { className: "agentkit-scroll-to-bottom-control", children: _jsx(IconButton, { label: labels.scrollToBottom, icon: _jsx(IconArrowDown, { "aria-hidden": "true" }), size: "compact", onPress: returnTranscriptToBottom }) })) : null] }), composer ? (_jsx("footer", { className: "agentkit-chat-footer", children: _jsx(AgentKitSurfaceBoundary, { surface: "composer", resetKey: threadId, children: _jsx(AgentKitRegionSlot, { slot: Footer, threadId: threadId, children: slots.composer ? (_jsx(Composer, { threadId: threadId })) : (_jsx(AgentKitComposer, { ...composerProps, threadId: threadId })) }) }) })) : null] }) }));
2766
2845
  }