@mcp-b/react-components 0.6.3 → 0.6.4

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.
@@ -5,7 +5,7 @@ import { Context, ContextContent, ContextContentBody, ContextContentHeader, Cont
5
5
  import { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton } from "./Conversation.js";
6
6
  import { Message, MessageAction, MessageActions, MessageAttachment, MessageContent, MessageResponse } from "./Message.js";
7
7
  import { MenuGroup, MenuGroupLabel } from "./Menu.js";
8
- import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
8
+ import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
9
9
  import { Reasoning, ReasoningContent, ReasoningTrigger } from "./Reasoning.js";
10
10
  import * as React from "react";
11
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -107,7 +107,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
107
107
  const [skippedApprovalIds, setSkippedApprovalIds] = React.useState([]);
108
108
  const pendingApprovals = getPendingToolApprovals(messages, { pausedExecutions: Boolean(executionApprovals) }).filter(({ part }) => {
109
109
  if (part.state === "approval-requested" && !onApprovalResponse) return false;
110
- const id = getApprovalRequestId(part);
110
+ const id = getApprovalStateKey(part);
111
111
  return Boolean(id) && !skippedApprovalIds.includes(id);
112
112
  });
113
113
  const approvalsWired = Boolean(onApprovalResponse || executionApprovals);
@@ -117,8 +117,9 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
117
117
  if (permissionMode !== "bypass") return;
118
118
  for (const { part } of pendingApprovals) {
119
119
  const id = getApprovalRequestId(part);
120
- if (!id || autoApprovedIds.current.has(id)) continue;
121
- autoApprovedIds.current.add(id);
120
+ const key = getApprovalStateKey(part);
121
+ if (!id || !key || autoApprovedIds.current.has(key)) continue;
122
+ autoApprovedIds.current.add(key);
122
123
  if (part.state === "approval-requested") onApprovalResponse?.({
123
124
  id,
124
125
  approved: true
@@ -195,7 +196,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
195
196
  onRespond: onApprovalResponse,
196
197
  executionApprovals,
197
198
  onSkip: () => {
198
- const id = getApprovalRequestId(pendingApproval.part);
199
+ const id = getApprovalStateKey(pendingApproval.part);
199
200
  if (id) setSkippedApprovalIds((previous) => [...previous, id]);
200
201
  }
201
202
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -356,6 +356,8 @@ interface ExecutionApprovals {
356
356
  }
357
357
  /** The id a response must carry: the approval id, or the paused run's executionId. */
358
358
  declare function getApprovalRequestId(part: ApprovalToolPart): string | undefined;
359
+ /** Component-local identity: paused executions can ask for multiple approvals. */
360
+ declare function getApprovalStateKey(part: ApprovalToolPart): string | undefined;
359
361
  interface PendingToolApproval<MessageT extends UIMessage = UIMessage> {
360
362
  message: MessageT;
361
363
  messageIndex: number;
@@ -529,4 +531,4 @@ declare const PromptInputCommandItem: typeof ComboboxItem;
529
531
  type PromptInputCommandSeparatorProps = React.ComponentPropsWithoutRef<typeof ComboboxSeparator>;
530
532
  declare const PromptInputCommandSeparator: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
531
533
  //#endregion
532
- export { ApprovalToolPart, AttachmentsContext, ExecutionApprovals, PendingToolApproval, PermissionMode, PromptInput, PromptInputActionAddAttachments, PromptInputActionAddAttachmentsProps, PromptInputActionAddScreenshot, PromptInputActionAddScreenshotProps, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuContentProps, PromptInputActionMenuItem, PromptInputActionMenuItemProps, PromptInputActionMenuProps, PromptInputActionMenuTrigger, PromptInputActionMenuTriggerProps, PromptInputApproval, PromptInputApprovalProps, PromptInputAttachment, PromptInputAttachmentProps, PromptInputAttachments, PromptInputAttachmentsProps, PromptInputBody, PromptInputBodyProps, PromptInputButton, PromptInputButtonProps, PromptInputButtonTooltip, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandEmptyProps, PromptInputCommandGroup, PromptInputCommandGroupProps, PromptInputCommandInput, PromptInputCommandInputProps, PromptInputCommandItem, PromptInputCommandItemProps, PromptInputCommandList, PromptInputCommandListProps, PromptInputCommandProps, PromptInputCommandSeparator, PromptInputCommandSeparatorProps, PromptInputControllerProps, PromptInputFilePart, PromptInputFooter, PromptInputFooterProps, PromptInputHeader, PromptInputHeaderProps, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardContentProps, PromptInputHoverCardProps, PromptInputHoverCardTrigger, PromptInputHoverCardTriggerProps, PromptInputMessage, PromptInputPermissionSelector, PromptInputPermissionSelectorProps, PromptInputProps, PromptInputProvider, PromptInputProviderProps, PromptInputReferencedSource, PromptInputSelect, PromptInputSelectContent, PromptInputSelectContentProps, PromptInputSelectItem, PromptInputSelectItemProps, PromptInputSelectProps, PromptInputSelectTrigger, PromptInputSelectTriggerProps, PromptInputSelectValue, PromptInputSelectValueProps, PromptInputStatus, PromptInputSubmit, PromptInputSubmitProps, PromptInputTab, PromptInputTabBody, PromptInputTabBodyProps, PromptInputTabItem, PromptInputTabItemProps, PromptInputTabLabel, PromptInputTabLabelProps, PromptInputTabProps, PromptInputTabsList, PromptInputTabsListProps, PromptInputTextarea, PromptInputTextareaProps, PromptInputTools, PromptInputToolsProps, PromptInputTooltipConfig, ReferencedSourcesContext, TextInputContext, TooltipSide, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
534
+ export { ApprovalToolPart, AttachmentsContext, ExecutionApprovals, PendingToolApproval, PermissionMode, PromptInput, PromptInputActionAddAttachments, PromptInputActionAddAttachmentsProps, PromptInputActionAddScreenshot, PromptInputActionAddScreenshotProps, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuContentProps, PromptInputActionMenuItem, PromptInputActionMenuItemProps, PromptInputActionMenuProps, PromptInputActionMenuTrigger, PromptInputActionMenuTriggerProps, PromptInputApproval, PromptInputApprovalProps, PromptInputAttachment, PromptInputAttachmentProps, PromptInputAttachments, PromptInputAttachmentsProps, PromptInputBody, PromptInputBodyProps, PromptInputButton, PromptInputButtonProps, PromptInputButtonTooltip, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandEmptyProps, PromptInputCommandGroup, PromptInputCommandGroupProps, PromptInputCommandInput, PromptInputCommandInputProps, PromptInputCommandItem, PromptInputCommandItemProps, PromptInputCommandList, PromptInputCommandListProps, PromptInputCommandProps, PromptInputCommandSeparator, PromptInputCommandSeparatorProps, PromptInputControllerProps, PromptInputFilePart, PromptInputFooter, PromptInputFooterProps, PromptInputHeader, PromptInputHeaderProps, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardContentProps, PromptInputHoverCardProps, PromptInputHoverCardTrigger, PromptInputHoverCardTriggerProps, PromptInputMessage, PromptInputPermissionSelector, PromptInputPermissionSelectorProps, PromptInputProps, PromptInputProvider, PromptInputProviderProps, PromptInputReferencedSource, PromptInputSelect, PromptInputSelectContent, PromptInputSelectContentProps, PromptInputSelectItem, PromptInputSelectItemProps, PromptInputSelectProps, PromptInputSelectTrigger, PromptInputSelectTriggerProps, PromptInputSelectValue, PromptInputSelectValueProps, PromptInputStatus, PromptInputSubmit, PromptInputSubmitProps, PromptInputTab, PromptInputTabBody, PromptInputTabBodyProps, PromptInputTabItem, PromptInputTabItemProps, PromptInputTabLabel, PromptInputTabLabelProps, PromptInputTabProps, PromptInputTabsList, PromptInputTabsListProps, PromptInputTextarea, PromptInputTextareaProps, PromptInputTools, PromptInputToolsProps, PromptInputTooltipConfig, ReferencedSourcesContext, TextInputContext, TooltipSide, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
@@ -667,6 +667,14 @@ function getApprovalRequestId(part) {
667
667
  if (part.state === "approval-requested") return part.approval.id;
668
668
  return getPausedExecution(part)?.executionId;
669
669
  }
670
+ /** Component-local identity: paused executions can ask for multiple approvals. */
671
+ function getApprovalStateKey(part) {
672
+ if (part.state === "approval-requested") return part.approval.id;
673
+ const paused = getPausedExecution(part);
674
+ if (!paused) return void 0;
675
+ const seq = paused.pending[0]?.seq;
676
+ return seq === void 0 ? paused.executionId : `${paused.executionId}:${seq}`;
677
+ }
670
678
  /** Derives pending tool approvals straight from the messages — no app-owned shapes. */
671
679
  function getPendingToolApprovals(messages, { pausedExecutions = false } = {}) {
672
680
  const pending = [];
@@ -701,7 +709,7 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
701
709
  const reasonRef = React.useRef(null);
702
710
  const approval = part.state === "approval-requested" ? part.approval : void 0;
703
711
  const paused = getPausedExecution(part);
704
- const approvalId = approval?.id ?? paused?.executionId;
712
+ const approvalId = getApprovalStateKey(part);
705
713
  React.useEffect(() => {
706
714
  setSelected("approve");
707
715
  setReason("");
@@ -709,19 +717,23 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
709
717
  }, [approvalId]);
710
718
  if (approval ? !onRespond : !(paused && executionApprovals)) return null;
711
719
  const toolName = getToolName(part);
712
- const respond = (approved) => {
720
+ const respond = async (approved) => {
713
721
  if (busy) return;
714
722
  setBusy(true);
715
723
  const trimmed = reason.trim();
716
724
  const denyReason = !approved && trimmed ? trimmed : void 0;
717
- if (approval) onRespond?.({
718
- id: approval.id,
719
- approved,
720
- reason: denyReason
721
- });
722
- else if (paused) approved ? executionApprovals?.approve(paused.executionId) : executionApprovals?.reject(paused.executionId, denyReason);
725
+ try {
726
+ if (approval) await onRespond?.({
727
+ id: approval.id,
728
+ approved,
729
+ reason: denyReason
730
+ });
731
+ else if (paused) await (approved ? executionApprovals?.approve(paused.executionId) : executionApprovals?.reject(paused.executionId, denyReason));
732
+ } finally {
733
+ setBusy(false);
734
+ }
723
735
  };
724
- const submit = () => respond(selected === "approve");
736
+ const submit = () => void respond(selected === "approve");
725
737
  const input = "input" in part ? part.input : void 0;
726
738
  const inputEntries = input && typeof input === "object" && !Array.isArray(input) ? Object.entries(input) : void 0;
727
739
  return /* @__PURE__ */ jsxs("div", {
@@ -790,7 +802,7 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
790
802
  className: "prompt-input__approval-option",
791
803
  "data-selected": selected === "approve" || void 0,
792
804
  disabled: busy,
793
- onClick: () => respond(true),
805
+ onClick: () => void respond(true),
794
806
  onFocus: () => setSelected("approve"),
795
807
  children: [
796
808
  /* @__PURE__ */ jsx("span", {
@@ -1047,4 +1059,4 @@ function createId() {
1047
1059
  return globalThis.crypto?.randomUUID?.() ?? `prompt-input-${Date.now()}-${Math.random()}`;
1048
1060
  }
1049
1061
  //#endregion
1050
- export { PromptInput, PromptInputActionAddAttachments, PromptInputActionAddScreenshot, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandGroup, PromptInputCommandInput, PromptInputCommandItem, PromptInputCommandList, PromptInputCommandSeparator, PromptInputFooter, PromptInputHeader, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardTrigger, PromptInputPermissionSelector, PromptInputProvider, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSubmit, PromptInputTab, PromptInputTabBody, PromptInputTabItem, PromptInputTabLabel, PromptInputTabsList, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
1062
+ export { PromptInput, PromptInputActionAddAttachments, PromptInputActionAddScreenshot, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandGroup, PromptInputCommandInput, PromptInputCommandItem, PromptInputCommandList, PromptInputCommandSeparator, PromptInputFooter, PromptInputHeader, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardTrigger, PromptInputPermissionSelector, PromptInputProvider, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSubmit, PromptInputTab, PromptInputTabBody, PromptInputTabItem, PromptInputTabLabel, PromptInputTabsList, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/react-components",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
5
5
  "homepage": "https://design-system.sigvelo.com",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "anser": "^2.3.5",
50
50
  "shiki": "^3.23.0",
51
51
  "streamdown": "^2.5.0",
52
- "@mcp-b/design-tokens": "0.6.3"
52
+ "@mcp-b/design-tokens": "0.6.4"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@ai-sdk/react": "^3.0.194",