@agent-native/toolkit 0.198.4 → 0.198.5

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.
@@ -659,6 +659,7 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
659
659
  }, [fileUploadStatus.refetch]);
660
660
  const isRestoring = history?.isRestoring === true || props.threadRestore.status === "loading";
661
661
  const isSubmissionInFlight = history?.isSubmissionInFlight === true;
662
+ const [composerSubmissionPending, setComposerSubmissionPending] = useState(false);
662
663
  const [authError, setAuthError] = useState(null);
663
664
  const [authSessionAvailable, setAuthSessionAvailable] = useState(false);
664
665
  const [composerText, setComposerText] = useState(() => readAssistantChatComposerDraft(props.tabId ?? threadId) ?? "");
@@ -768,6 +769,10 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
768
769
  .reverse()
769
770
  .find((message) => message.role === "assistant"), [thread.messages]);
770
771
  const isRunning = hasActiveAgentRuns(thread);
772
+ const lastMessage = thread.messages.at(-1);
773
+ const isThinkingVisibleInTranscript = (isRunning || isSubmissionInFlight) &&
774
+ lastMessage?.role === "user" &&
775
+ lastMessage.metadata?.hideUserMessage !== true;
771
776
  const isThreadRunning = useCallback(() => hasActiveAgentRuns(controller.getThread(threadId)), [controller, threadId]);
772
777
  useEffect(() => {
773
778
  if (previousPrefillRevisionRef.current === prefillRevision)
@@ -1764,13 +1769,15 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1764
1769
  }
1765
1770
  }, [props.isActiveComposer, props.tabId, send, threadId]);
1766
1771
  const submitSuggestion = useCallback((suggestion) => {
1772
+ if (composerSubmissionPending)
1773
+ return;
1767
1774
  const handler = suggestionSubmitRef.current;
1768
1775
  if (!handler || handler.threadId !== threadId)
1769
1776
  return;
1770
1777
  void handler.submit(suggestion).catch((error) => {
1771
1778
  dispatchSetupRequiredEvent(error, props.tabId, threadId);
1772
1779
  });
1773
- }, [props.tabId, threadId]);
1780
+ }, [composerSubmissionPending, props.tabId, threadId]);
1774
1781
  const retryDeferredSubmission = useCallback(async () => {
1775
1782
  if (!deferredProviderSubmissionFailureId)
1776
1783
  return;
@@ -1903,6 +1910,9 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1903
1910
  setupBouncePulse,
1904
1911
  bounceSetupCard,
1905
1912
  isSubmissionInFlight,
1913
+ composerSubmissionPending,
1914
+ onComposerSubmissionPendingChange: setComposerSubmissionPending,
1915
+ isThinkingVisibleInTranscript,
1906
1916
  contextItems,
1907
1917
  voiceTranscriptMessages,
1908
1918
  selectionLength,
@@ -1974,7 +1984,8 @@ function AgentKitEmptyState({ threadId }) {
1974
1984
  const prompt = agentSuggestionPrompt(suggestion);
1975
1985
  return (_jsx("button", { type: "button", disabled: !surface.canChat ||
1976
1986
  surface.props.composerDisabled ||
1977
- surface.props.composerSubmissionDisabled, onClick: () => surface.submitSuggestion(suggestion), className: "w-full rounded-xl border border-border/70 bg-card/60 px-3 py-2.5 text-left text-[13px] text-muted-foreground shadow-sm transition-colors hover:border-border hover:bg-card hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: typeof suggestion === "string"
1987
+ surface.props.composerSubmissionDisabled ||
1988
+ surface.composerSubmissionPending, onClick: () => surface.submitSuggestion(suggestion), className: "w-full rounded-xl border border-border/70 bg-card/60 px-3 py-2.5 text-left text-[13px] text-muted-foreground shadow-sm transition-colors hover:border-border hover:bg-card hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: typeof suggestion === "string"
1978
1989
  ? suggestion
1979
1990
  : suggestion.label || prompt || String(index) }, typeof suggestion === "string"
1980
1991
  ? suggestion
@@ -2021,10 +2032,6 @@ function AgentKitTranscript({ children, threadId }) {
2021
2032
  },
2022
2033
  });
2023
2034
  const threadMessageIds = new Set(thread.messages.map((message) => message.id));
2024
- const lastMessage = thread.messages.at(-1);
2025
- const showThinking = (surface.isRunning || surface.isSubmissionInFlight) &&
2026
- lastMessage?.role === "user" &&
2027
- lastMessage.metadata?.hideUserMessage !== true;
2028
2035
  const pendingVoiceMessages = surface.voiceTranscriptMessages.filter((message) => !threadMessageIds.has(message.id));
2029
2036
  const showHomeSuggestions = surface.props.centerComposerWhenEmpty &&
2030
2037
  !surface.hasRenderedMessages &&
@@ -2037,7 +2044,8 @@ function AgentKitTranscript({ children, threadId }) {
2037
2044
  surface.suggestions.length > 0 ? (_jsx(AgentKitSuggestedPrompts, { suggestions: surface.suggestions, disabled: !surface.canChat ||
2038
2045
  surface.props.composerDisabled ||
2039
2046
  surface.props.composerSubmissionDisabled ||
2040
- surface.isSubmissionInFlight, onSelect: surface.submitSuggestion, className: "agentkit-host-suggestions" })) : null;
2047
+ surface.isSubmissionInFlight ||
2048
+ surface.composerSubmissionPending, onSelect: surface.submitSuggestion, className: "agentkit-host-suggestions" })) : null;
2041
2049
  if (surface.authError) {
2042
2050
  const authTitle = surface.authSessionAvailable
2043
2051
  ? t("agentChat.auth.refreshTitle")
@@ -2068,7 +2076,7 @@ function AgentKitTranscript({ children, threadId }) {
2068
2076
  }
2069
2077
  return (_jsxs(_Fragment, { children: [thread.messages.length > 0 || surface.hasRenderedMessages ? (_jsx(AgentKitHistoryBeginningRevert, {})) : null, surface.threadRestore.status === "error" ? (_jsxs("div", { className: "mx-4 mt-3 flex items-center justify-between gap-3 rounded-md border border-border px-3 py-2 text-xs text-muted-foreground", role: "alert", children: [_jsx("span", { children: surface.threadRestore.notFound
2070
2078
  ? t("agentChat.message.threadNotFound")
2071
- : t("agentChat.message.restoreRequestFailed") }), _jsx("button", { type: "button", onClick: surface.retryThreadRestore, className: "shrink-0 rounded px-2 py-1 hover:bg-accent hover:text-foreground", children: t("agentChat.common.retry") })] })) : null, renderThreadSlot(surface.props.threadContentSlot, threadId, surface.props.tabId), children, handoffMessages.map((message) => (_jsx(AgentMessageView, { value: message, threadId: threadId }, message.id))), pendingVoiceMessages.map((message) => (_jsx(AgentMessageView, { value: message, threadId: threadId }, message.id))), showThinking ? (_jsx("div", { role: "status", "aria-live": "polite", className: "px-3 py-2 text-sm text-muted-foreground", children: t("agentChat.status.thinking") })) : null, guided.questions?.length ? (_jsx("div", { className: "px-3 pb-3", children: _jsx(GuidedQuestionFlow, { questions: guided.questions, onSubmit: guided.handleSubmit, onSkip: guided.handleSkip, isSubmitting: guided.isSubmitting, isSubmissionBlocked: !surface.canChat, providerStatus: surface.providerStatus, onRetryProviderStatus: surface.retryProviderStatus, ...(guided.title ? { title: guided.title } : {}), ...(guided.description ? { description: guided.description } : {}), ...(guided.skipLabel ? { skipLabel: guided.skipLabel } : {}), ...(guided.submitLabel ? { submitLabel: guided.submitLabel } : {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })) : null, suggestionBar, renderThreadSlot(surface.props.threadFooterSlot, threadId, surface.props.tabId)] }));
2079
+ : t("agentChat.message.restoreRequestFailed") }), _jsx("button", { type: "button", onClick: surface.retryThreadRestore, className: "shrink-0 rounded px-2 py-1 hover:bg-accent hover:text-foreground", children: t("agentChat.common.retry") })] })) : null, renderThreadSlot(surface.props.threadContentSlot, threadId, surface.props.tabId), children, handoffMessages.map((message) => (_jsx(AgentMessageView, { value: message, threadId: threadId }, message.id))), pendingVoiceMessages.map((message) => (_jsx(AgentMessageView, { value: message, threadId: threadId }, message.id))), surface.isThinkingVisibleInTranscript ? (_jsx("div", { role: "status", "aria-live": "polite", className: "px-3 py-2 text-sm text-muted-foreground", children: t("agentChat.status.thinking") })) : null, guided.questions?.length ? (_jsx("div", { className: "px-3 pb-3", children: _jsx(GuidedQuestionFlow, { questions: guided.questions, onSubmit: guided.handleSubmit, onSkip: guided.handleSkip, isSubmitting: guided.isSubmitting, isSubmissionBlocked: !surface.canChat, providerStatus: surface.providerStatus, onRetryProviderStatus: surface.retryProviderStatus, ...(guided.title ? { title: guided.title } : {}), ...(guided.description ? { description: guided.description } : {}), ...(guided.skipLabel ? { skipLabel: guided.skipLabel } : {}), ...(guided.submitLabel ? { submitLabel: guided.submitLabel } : {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })) : null, suggestionBar, renderThreadSlot(surface.props.threadFooterSlot, threadId, surface.props.tabId)] }));
2072
2080
  }
2073
2081
  function renderThreadSlot(slot, threadId, tabId) {
2074
2082
  return typeof slot === "function"
@@ -2125,7 +2133,7 @@ class AgentKitComposerContextError extends Error {
2125
2133
  this.name = "AgentKitComposerContextError";
2126
2134
  }
2127
2135
  }
2128
- function AgentKitComposerSurface({ threadId, props, composerContext, canChat, setupMissing, providerStatus, retryProviderStatus, fileStorageConfigured, fileStorageMissing, retryFileStorageStatus, deferredSubmissionFailed, retryDeferredSubmission, dismissDeferredSubmission, isRunning, isRestoring, isSubmissionInFlight, hasRenderedMessages, threadRestore, suggestions, showSuggestions, setupBouncePulse, bounceSetupCard, contextItems, selectionLength, prefillRevision, text, onTextChange, onRemoveContextItem, onClearSelection, onBeforeSubmit, onSubmit, submitSuggestion, suggestionSubmitRef, onImplementPlan, }) {
2136
+ function AgentKitComposerSurface({ threadId, props, composerContext, canChat, setupMissing, providerStatus, retryProviderStatus, fileStorageConfigured, fileStorageMissing, retryFileStorageStatus, deferredSubmissionFailed, retryDeferredSubmission, dismissDeferredSubmission, isRunning, isRestoring, isSubmissionInFlight, composerSubmissionPending, onComposerSubmissionPendingChange, isThinkingVisibleInTranscript, hasRenderedMessages, threadRestore, suggestions, showSuggestions, setupBouncePulse, bounceSetupCard, contextItems, selectionLength, prefillRevision, text, onTextChange, onRemoveContextItem, onClearSelection, onBeforeSubmit, onSubmit, submitSuggestion, suggestionSubmitRef, onImplementPlan, }) {
2129
2137
  const t = useT();
2130
2138
  const [composerError, setComposerError] = useState(null);
2131
2139
  const mounted = useRef(true);
@@ -2298,7 +2306,8 @@ function AgentKitComposerSurface({ threadId, props, composerContext, canChat, se
2298
2306
  }) }), props.composerSlot, showHomeIntro ? (_jsx("div", { className: "agentkit-home-intro", children: props.homeIntroSlot })) : null, showHomeSuggestions ? (_jsx(AgentKitSuggestedPrompts, { suggestions: suggestions, disabled: !canChat ||
2299
2307
  props.composerDisabled ||
2300
2308
  props.composerSubmissionDisabled ||
2301
- isSubmissionInFlight, onSelect: submitSuggestion, className: "agentkit-home-suggestions" })) : null, showPlanCallout ? (_jsx(PlanModeCallout, { canImplementPlan: latestAssistantWasPlan, onImplementPlan: onImplementPlan, onSwitchToAct: () => props.onExecModeChange?.("build") })) : null, setupMissing && props.showMissingApiKeySetup !== false ? (_jsx(BuilderSetupCard, { fullWidth: true, attached: true, bouncePulse: setupBouncePulse, layout: props.missingApiKeySetupLayout ?? "default", onConnected: () => window.dispatchEvent(new Event("agent-engine:configured-changed")) })) : null, !canChat && !setupMissing && providerStatus !== "configured" ? (_jsx(GuidedQuestionProviderGate, { providerStatus: providerStatus, onRetry: retryProviderStatus })) : null, integration ? (_jsx(McpConnectionSuggestion, { text: text, variant: "composer", requestedByUser: true, integrationId: integration.id })) : null, selectionLength !== null && selectionLength > 0 ? (_jsx(AgentKitSelectionPill, { length: selectionLength, onClear: onClearSelection })) : null, _jsxs("div", { className: "relative", children: [_jsx(AgentKitComposer, { threadId: threadId, disabled: (!canChat && !providerSubmissionPending) ||
2309
+ isSubmissionInFlight ||
2310
+ composerSubmissionPending, onSelect: submitSuggestion, className: "agentkit-home-suggestions" })) : null, showPlanCallout ? (_jsx(PlanModeCallout, { canImplementPlan: latestAssistantWasPlan, onImplementPlan: onImplementPlan, onSwitchToAct: () => props.onExecModeChange?.("build") })) : null, setupMissing && props.showMissingApiKeySetup !== false ? (_jsx(BuilderSetupCard, { fullWidth: true, attached: true, bouncePulse: setupBouncePulse, layout: props.missingApiKeySetupLayout ?? "default", onConnected: () => window.dispatchEvent(new Event("agent-engine:configured-changed")) })) : null, !canChat && !setupMissing && providerStatus !== "configured" ? (_jsx(GuidedQuestionProviderGate, { providerStatus: providerStatus, onRetry: retryProviderStatus })) : null, integration ? (_jsx(McpConnectionSuggestion, { text: text, variant: "composer", requestedByUser: true, integrationId: integration.id })) : null, selectionLength !== null && selectionLength > 0 ? (_jsx(AgentKitSelectionPill, { length: selectionLength, onClear: onClearSelection })) : null, _jsxs("div", { className: "relative", children: [_jsx(AgentKitComposer, { threadId: threadId, disabled: (!canChat && !providerSubmissionPending) ||
2302
2311
  props.composerDisabled ||
2303
2312
  isRestoring, submissionDisabled: (!canChat && !providerSubmissionPending) ||
2304
2313
  props.composerSubmissionDisabled === true ||
@@ -2309,7 +2318,7 @@ function AgentKitComposerSurface({ threadId, props, composerContext, canChat, se
2309
2318
  window.dispatchEvent(new CustomEvent("agent-chat:missing-api-key", {
2310
2319
  detail: { tabId: props.tabId, threadId },
2311
2320
  }));
2312
- }, initialText: text, initialTextKey: `${props.tabId ?? threadId}:${prefillRevision}`, requireAgentEngine: false, onTextChange: onTextChange, onBeforeSubmit: onBeforeSubmit, contextItems: visibleContextItems, contextMenuItems: composerContext?.menuItems, onRemoveContextItem: (key) => {
2321
+ }, initialText: text, initialTextKey: `${props.tabId ?? threadId}:${prefillRevision}`, requireAgentEngine: false, onTextChange: onTextChange, onBeforeSubmit: onBeforeSubmit, announcePendingSubmission: !isThinkingVisibleInTranscript, onSubmissionPendingChange: onComposerSubmissionPendingChange, contextItems: visibleContextItems, contextMenuItems: composerContext?.menuItems, onRemoveContextItem: (key) => {
2313
2322
  if (providerContextKeys.has(key))
2314
2323
  composerContext?.onRemoveContextItem(key);
2315
2324
  else
@@ -2335,7 +2344,8 @@ function AgentKitComposerSurface({ threadId, props, composerContext, canChat, se
2335
2344
  }, "aria-label": t("agentChat.composer.stopResponse"), title: t("agentChat.composer.stopResponse"), "data-agent-composer-slot": "stop-button", className: "flex h-7 w-7 items-center justify-center rounded-full bg-primary text-primary-foreground", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) })) : undefined }), deferredSubmissionFailed ? (_jsxs("div", { role: "alert", className: "mx-3 mb-1.5 flex shrink-0 items-center gap-2 rounded-md border border-border bg-muted/70 px-3 py-2 text-xs text-foreground shadow-sm", children: [_jsx(IconAlertTriangle, { className: "size-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1 leading-snug", children: t("agentChat.recovery.deferredSubmissionFailed") }), _jsx("button", { type: "button", disabled: !canChat || isSubmissionInFlight, onClick: () => void retryDeferredSubmission().catch(() => undefined), className: "shrink-0 rounded px-2 py-1 font-medium hover:bg-accent disabled:opacity-60", children: t("agentChat.common.retry") }), _jsx("button", { type: "button", "aria-label": t("agentChat.common.dismissError"), onClick: () => void dismissDeferredSubmission().catch(() => undefined), className: "-mr-1 flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconX, { className: "size-3.5" }) })] })) : null, composerError ? (_jsxs("div", { role: "alert", className: "mx-3 mb-1.5 flex shrink-0 items-start gap-2 rounded-md border border-border bg-muted/70 px-3 py-2 text-xs text-foreground shadow-sm", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1 leading-snug", children: composerError }), _jsx("button", { type: "button", "aria-label": t("agentChat.common.dismissError"), onClick: () => setComposerError(null), className: "-mr-1 -mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconX, { className: "h-3.5 w-3.5" }) })] })) : null, _jsx(ExternalAgentNudge, { variant: "prompt" })] }), showAfterComposerSuggestions ? (_jsx(AgentKitSuggestedPrompts, { suggestions: suggestions, disabled: !canChat ||
2336
2345
  props.composerDisabled ||
2337
2346
  props.composerSubmissionDisabled ||
2338
- isSubmissionInFlight, onSelect: submitSuggestion, className: "agentkit-home-suggestions" })) : null, showAfterComposerSlot ? (_jsx("div", { className: "agentkit-after-composer-slot", children: props.afterComposerSlot })) : null, composerContext?.dialogs] }));
2347
+ isSubmissionInFlight ||
2348
+ composerSubmissionPending, onSelect: submitSuggestion, className: "agentkit-home-suggestions" })) : null, showAfterComposerSlot ? (_jsx("div", { className: "agentkit-after-composer-slot", children: props.afterComposerSlot })) : null, composerContext?.dialogs] }));
2339
2349
  }
2340
2350
  function AgentKitSuggestedPrompts({ suggestions, disabled, onSelect, className, }) {
2341
2351
  const t = useT();