@agent-native/core 0.149.1 → 0.149.2
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +2 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +150 -46
- package/corpus/templates/analytics/app/global.css +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +37 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +2 -0
- package/corpus/templates/analytics/changelog/2026-08-10-dashboard-tables-can-be-copied-and-sorted-by-multiple-column.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/assets/app/global.css +1 -1
- package/corpus/templates/assets/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/brain/app/global.css +1 -1
- package/corpus/templates/brain/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-10-clips-desktop-sign-in-now-starts-with-magic-links-and-google.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.css +1 -0
- package/corpus/templates/clips/desktop/src/app.tsx +274 -137
- package/corpus/templates/clips/desktop/src/styles.css +35 -0
- package/corpus/templates/content/app/global.css +1 -0
- package/corpus/templates/crm/app/global.css +1 -1
- package/corpus/templates/crm/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/forms/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/plan/app/global.css +1 -0
- package/corpus/templates/plan/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/plan/server/ui-plan-html.ts +4 -1
- package/corpus/templates/slides/AGENTS.md +11 -10
- package/corpus/templates/slides/actions/add-deck.ts +2 -0
- package/corpus/templates/slides/actions/add-slide.ts +15 -1
- package/corpus/templates/slides/actions/create-deck.ts +18 -6
- package/corpus/templates/slides/actions/get-deck.ts +29 -1
- package/corpus/templates/slides/actions/patch-deck.ts +122 -9
- package/corpus/templates/slides/actions/save-deck.ts +24 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +134 -618
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +69 -60
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +13 -1
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +56 -174
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +239 -116
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +3 -3
- package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +1 -1
- package/corpus/templates/slides/app/components/layout/Layout.tsx +34 -35
- package/corpus/templates/slides/app/components/layout/layout-route-policy.ts +2 -5
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +45 -40
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +63 -16
- package/corpus/templates/slides/app/hooks/use-generating-slide-preview.ts +25 -3
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +5 -4
- package/corpus/templates/slides/app/lib/recent-references.ts +23 -1
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +41 -3
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -27
- package/corpus/templates/slides/app/pages/Index.tsx +240 -89
- package/corpus/templates/slides/changelog/2026-08-10-ai-editing-avatar-badge.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-generated-decks-keep-a-clear-human-readable-title.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-new-deck-creation-now-shows-progress-opens-the-editor-direct.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-presentation-reveals-now-follow-valid-targets.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-editing-controls-are-consolidated-into-one-focused-me.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-now-verify-and-restyle-every-imported-slide-in-one-pa.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-only-suggests-a-google-connection-for-relevant-reques.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-the-google-slides-import-option-is-now-labeled-slides.md +6 -0
- package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -3
- package/corpus/templates/slides/shared/api.ts +2 -1
- package/corpus/templates/slides/shared/deck-title.ts +135 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +4 -1
- package/dist/agent/engine/ai-sdk-engine.js +1 -1
- package/dist/agent/production-agent.d.ts +21 -1
- package/dist/agent/production-agent.js +129 -10
- package/dist/agent/tool-approval-store.d.ts +18 -0
- package/dist/agent/tool-approval-store.js +122 -0
- package/dist/agent/types.d.ts +1 -1
- package/dist/cli/code-agent-executor.js +11 -2
- package/dist/client/AgentPanel.js +31 -6
- package/dist/client/AssistantChat.d.ts +3 -2
- package/dist/client/AssistantChat.js +7 -20
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +11 -0
- package/dist/client/agent-chat.d.ts +1 -1
- package/dist/client/chat/markdown-renderer.js +14 -2
- package/dist/client/chat/message-components.d.ts +6 -2
- package/dist/client/chat/message-components.js +25 -47
- package/dist/client/chat/tool-call-display.d.ts +3 -5
- package/dist/client/chat/tool-call-display.js +7 -212
- package/dist/client/chat-first/apps-rail.js +3 -3
- package/dist/client/chat-first/browser-pane.js +4 -1
- package/dist/client/chat-first/chat-history.d.ts +3 -1
- package/dist/client/chat-first/chat-history.js +2 -2
- package/dist/client/chat-first/surface-tabs.d.ts +1 -1
- package/dist/client/chat-first/surface-tabs.js +52 -41
- package/dist/client/chat-first/types.d.ts +3 -0
- package/dist/client/chat-first.d.ts +10 -0
- package/dist/client/chat-first.js +37 -2
- package/dist/client/components/ui/message-scroller.js +4 -1
- package/dist/client/i18n.js +3 -1
- package/dist/client/resources/McpConnectionSuggestion.js +9 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/use-chat-models.js +156 -80
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/integrations/webhook-handler.js +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/auth.js +262 -31
- package/dist/server/onboarding-html.js +56 -9
- package/dist/shared/reasoning-effort.d.ts +8 -8
- package/dist/shared/reasoning-effort.js +10 -10
- package/dist/shared/streaming-text-smoothing.js +41 -11
- package/dist/styles/agent-native.css +19 -32
- package/dist/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/docs/content/template-chat.mdx +1 -1
- package/package.json +2 -2
- package/src/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
|
@@ -24,6 +24,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
24
24
|
import { Tooltip as DesignSystemTooltip } from "@agent-native/toolkit/design-system";
|
|
25
25
|
import { IconMessageCircle, IconMessageDots, IconTerminal2, IconSettings, IconLayoutSidebarRightCollapse, IconLayoutGrid, IconCheck, IconPlus, IconX, IconDotsVertical, IconHistory, IconArrowsHorizontal, IconArrowsMaximize, IconExternalLink, } from "@tabler/icons-react";
|
|
26
26
|
import React, { useState, useEffect, useRef, useCallback, useMemo, lazy, Suspense, startTransition, } from "react";
|
|
27
|
+
import { flushSync } from "react-dom";
|
|
27
28
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from "./components/ui/dropdown-menu.js";
|
|
28
29
|
import { normalizeTooltipText } from "./components/ui/tooltip.js";
|
|
29
30
|
import { ErrorReportActions } from "./ErrorReportActions.js";
|
|
@@ -1700,6 +1701,26 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
|
|
|
1700
1701
|
return next;
|
|
1701
1702
|
});
|
|
1702
1703
|
}, []);
|
|
1704
|
+
// `view-transition-name` is only legal to carry while a transition is
|
|
1705
|
+
// actually capturing. Left on permanently it makes the panel its own
|
|
1706
|
+
// stacking context and the containing block for every fixed/absolute
|
|
1707
|
+
// descendant, and enlists it as a captured group in unrelated transitions
|
|
1708
|
+
// (any React Router `viewTransition` navigation), which is how overlays end
|
|
1709
|
+
// up painted at stale offsets. Apply it only around the drawer morph, and
|
|
1710
|
+
// flush it into the DOM first: `startViewTransition` captures the old state
|
|
1711
|
+
// before it invokes the callback, so a name applied in a normal React commit
|
|
1712
|
+
// would land too late to be captured.
|
|
1713
|
+
const [drawerMorphing, setDrawerMorphing] = useState(false);
|
|
1714
|
+
const runDrawerMorph = useCallback((apply) => {
|
|
1715
|
+
flushSync(() => setDrawerMorphing(true));
|
|
1716
|
+
const settle = () => setDrawerMorphing(false);
|
|
1717
|
+
const transition = startAgentChatViewTransition(apply);
|
|
1718
|
+
if (!transition) {
|
|
1719
|
+
settle();
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
transition.finished.then(settle, settle);
|
|
1723
|
+
}, []);
|
|
1703
1724
|
const snapTo75Percent = useCallback(() => {
|
|
1704
1725
|
if (drawerExitTimerRef.current !== null) {
|
|
1705
1726
|
clearTimeout(drawerExitTimerRef.current);
|
|
@@ -1719,8 +1740,8 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
|
|
|
1719
1740
|
}
|
|
1720
1741
|
catch { }
|
|
1721
1742
|
};
|
|
1722
|
-
|
|
1723
|
-
}, [drawerPlaceholderWidth, isWideDrawer, width]);
|
|
1743
|
+
runDrawerMorph(apply);
|
|
1744
|
+
}, [runDrawerMorph, drawerPlaceholderWidth, isWideDrawer, width]);
|
|
1724
1745
|
const exitWideDrawer = useCallback(() => {
|
|
1725
1746
|
if (!isWideDrawer || drawerExitTimerRef.current !== null)
|
|
1726
1747
|
return;
|
|
@@ -1738,8 +1759,8 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
|
|
|
1738
1759
|
setIsWideDrawer(false);
|
|
1739
1760
|
}, SIDEBAR_ANIMATION_MS + 32);
|
|
1740
1761
|
};
|
|
1741
|
-
|
|
1742
|
-
}, [drawerPlaceholderWidth, isWideDrawer]);
|
|
1762
|
+
runDrawerMorph(apply);
|
|
1763
|
+
}, [runDrawerMorph, drawerPlaceholderWidth, isWideDrawer]);
|
|
1743
1764
|
const handleResizeStart = useCallback(() => setIsResizing(true), []);
|
|
1744
1765
|
const handleResizeEnd = useCallback(() => setIsResizing(false), []);
|
|
1745
1766
|
const isLeft = position === "left";
|
|
@@ -1820,7 +1841,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
|
|
|
1820
1841
|
borderLeft: isLeft ? "none" : "1px solid hsl(var(--border))",
|
|
1821
1842
|
borderRight: isLeft ? "1px solid hsl(var(--border))" : "none",
|
|
1822
1843
|
display: "flex",
|
|
1823
|
-
|
|
1844
|
+
...(drawerMorphing
|
|
1845
|
+
? { viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME }
|
|
1846
|
+
: null),
|
|
1824
1847
|
};
|
|
1825
1848
|
}
|
|
1826
1849
|
else {
|
|
@@ -1841,7 +1864,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
|
|
|
1841
1864
|
display: desktopAnimationEnabled || panelOpen ? "flex" : "none",
|
|
1842
1865
|
minWidth: desktopAnimationEnabled ? 0 : undefined,
|
|
1843
1866
|
pointerEvents: desktopAnimationEnabled && !panelOpen ? "none" : undefined,
|
|
1844
|
-
|
|
1867
|
+
...(drawerMorphing
|
|
1868
|
+
? { viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME }
|
|
1869
|
+
: null),
|
|
1845
1870
|
};
|
|
1846
1871
|
}
|
|
1847
1872
|
// Mount the live chat surface only while visible or actively needed. Keeping
|
|
@@ -136,6 +136,7 @@ type QueuedMessage = {
|
|
|
136
136
|
recoveryAction?: AgentRecoveryAction;
|
|
137
137
|
trackInRunsTray?: boolean;
|
|
138
138
|
hideUserMessage?: boolean;
|
|
139
|
+
approvedToolCalls?: string[];
|
|
139
140
|
/**
|
|
140
141
|
* Model/engine/effort snapshotted at enqueue time, for the same reason
|
|
141
142
|
* `requestMode` is: the picker is global and live, so a queue that flushes
|
|
@@ -306,7 +307,7 @@ export interface AssistantChatProps {
|
|
|
306
307
|
defaultModel?: string;
|
|
307
308
|
/** Selected engine override for this conversation */
|
|
308
309
|
selectedEngine?: string;
|
|
309
|
-
/** Selected
|
|
310
|
+
/** Selected effort override for this conversation */
|
|
310
311
|
selectedEffort?: ReasoningEffort;
|
|
311
312
|
/** Available engine/model list for the model picker */
|
|
312
313
|
availableModels?: Array<{
|
|
@@ -319,7 +320,7 @@ export interface AssistantChatProps {
|
|
|
319
320
|
modelListLoading?: boolean;
|
|
320
321
|
/** Callback when user picks a model from the picker */
|
|
321
322
|
onModelChange?: (model: string, engine: string) => void;
|
|
322
|
-
/** Callback when user picks
|
|
323
|
+
/** Callback when user picks an effort from the picker */
|
|
323
324
|
onEffortChange?: (effort: ReasoningEffort) => void;
|
|
324
325
|
/**
|
|
325
326
|
* Optional secondary model menu (e.g. an image-generation model) shown inside
|
|
@@ -3102,7 +3102,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3102
3102
|
...(messageAttachments.length > 0
|
|
3103
3103
|
? { attachments: messageAttachments }
|
|
3104
3104
|
: {}),
|
|
3105
|
-
...createUserMessageRunConfig(next.references, next.requestMode, next.recoveryAction, next.trackInRunsTray,
|
|
3105
|
+
...createUserMessageRunConfig(next.references, next.requestMode, next.recoveryAction, next.trackInRunsTray, next.approvedToolCalls, next.id, next.hideUserMessage, {
|
|
3106
3106
|
model: next.model,
|
|
3107
3107
|
engine: next.engine,
|
|
3108
3108
|
effort: next.effort,
|
|
@@ -3433,7 +3433,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3433
3433
|
stopActiveRunRef.current({ preserveQueuedMessages: true });
|
|
3434
3434
|
}, [applyLocalQueuedMessages]);
|
|
3435
3435
|
const visibleQueuedMessages = useMemo(() => queuedMessages.filter((message) => !message.hideUserMessage), [queuedMessages]);
|
|
3436
|
-
const addToQueue = useCallback(async (text, images, references, attachments, requestMode, intent = "queued", recoveryAction, includeComposerContext = false, trackInRunsTray = false, preserveReconnectAutoRecoveryBudget = false, hideUserMessage = false, submitMessageId) => {
|
|
3436
|
+
const addToQueue = useCallback(async (text, images, references, attachments, requestMode, intent = "queued", recoveryAction, includeComposerContext = false, trackInRunsTray = false, preserveReconnectAutoRecoveryBudget = false, hideUserMessage = false, submitMessageId, approvedToolCalls) => {
|
|
3437
3437
|
if (isAgentChatSubmitCancelled(submitMessageId))
|
|
3438
3438
|
return;
|
|
3439
3439
|
if (engineSetupRequired) {
|
|
@@ -3582,6 +3582,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3582
3582
|
recoveryAction,
|
|
3583
3583
|
trackInRunsTray,
|
|
3584
3584
|
hideUserMessage,
|
|
3585
|
+
approvedToolCalls,
|
|
3585
3586
|
...modelSnapshot,
|
|
3586
3587
|
},
|
|
3587
3588
|
]);
|
|
@@ -3602,6 +3603,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3602
3603
|
recoveryAction,
|
|
3603
3604
|
trackInRunsTray,
|
|
3604
3605
|
hideUserMessage,
|
|
3606
|
+
approvedToolCalls,
|
|
3605
3607
|
...modelSnapshot,
|
|
3606
3608
|
},
|
|
3607
3609
|
]);
|
|
@@ -3615,7 +3617,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3615
3617
|
...(messageAttachments.length > 0
|
|
3616
3618
|
? { attachments: messageAttachments }
|
|
3617
3619
|
: {}),
|
|
3618
|
-
...createUserMessageRunConfig(references, effectiveRequestMode, recoveryAction, trackInRunsTray,
|
|
3620
|
+
...createUserMessageRunConfig(references, effectiveRequestMode, recoveryAction, trackInRunsTray, approvedToolCalls, undefined, hideUserMessage),
|
|
3619
3621
|
});
|
|
3620
3622
|
}
|
|
3621
3623
|
catch (error) {
|
|
@@ -4006,31 +4008,16 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4006
4008
|
getApprovalResolution,
|
|
4007
4009
|
onApprovalResolved: recordApprovalResolution,
|
|
4008
4010
|
onApprove: (approvalKey) => {
|
|
4009
|
-
|
|
4010
|
-
appendThreadMessage({
|
|
4011
|
-
role: "user",
|
|
4012
|
-
content: [
|
|
4013
|
-
{
|
|
4014
|
-
type: "text",
|
|
4015
|
-
text: "Approved. Go ahead and run the requested action.",
|
|
4016
|
-
},
|
|
4017
|
-
],
|
|
4018
|
-
...createUserMessageRunConfig(undefined, execMode === "plan"
|
|
4019
|
-
? "plan"
|
|
4020
|
-
: execMode === "build"
|
|
4021
|
-
? "act"
|
|
4022
|
-
: undefined, undefined, undefined, [approvalKey]),
|
|
4023
|
-
});
|
|
4011
|
+
void addToQueue("Approved. Go ahead and run the requested action.", undefined, undefined, undefined, undefined, "queued", undefined, false, false, false, false, undefined, [approvalKey]);
|
|
4024
4012
|
},
|
|
4025
4013
|
...(approvalActions?.onDeny ? { onDeny: approvalActions.onDeny } : {}),
|
|
4026
4014
|
...(approvalActions?.onAlwaysAllow
|
|
4027
4015
|
? { onAlwaysAllow: approvalActions.onAlwaysAllow }
|
|
4028
4016
|
: {}),
|
|
4029
4017
|
}), [
|
|
4030
|
-
|
|
4018
|
+
addToQueue,
|
|
4031
4019
|
execMode,
|
|
4032
4020
|
getApprovalResolution,
|
|
4033
|
-
markOptimisticRunning,
|
|
4034
4021
|
approvalActions,
|
|
4035
4022
|
recordApprovalResolution,
|
|
4036
4023
|
]);
|
|
@@ -39,4 +39,4 @@ export { AGENT_SIDEBAR_DEFAULT_MAX_WIDTH, AGENT_SIDEBAR_MIN_WIDTH, AGENT_SIDEBAR
|
|
|
39
39
|
export { clearReservedToolRenderersForTests, clearToolRenderersForTests, registerActionChatRenderer, registerFallbackToolRenderer, registerReservedActionChatRenderer, registerReservedFallbackToolRenderer, registerReservedToolRenderer, registerToolRenderer, resolveToolRenderer, type ActionChatRendererRegistration, type ToolRendererComponent, type ToolRendererContext, type ToolRendererMatch, type ToolRendererProps, type ToolRendererRegistration, } from "../chat/tool-render-registry.js";
|
|
40
40
|
export * from "../chat/connectors.js";
|
|
41
41
|
export * from "../chat/runtime.js";
|
|
42
|
-
export { CHAT_FIRST_APP_LAYOUT_STORAGE_KEY, CHAT_FIRST_DEFAULT_APP_IDS, CHAT_FIRST_SURFACE_TABS_STORAGE_KEY, CHAT_FIRST_SURFACE_PANEL_STORAGE_KEY, CHAT_FIRST_SURFACE_WIDTH_DEFAULT, CHAT_FIRST_SURFACE_WIDTH_MIN, clampChatFirstSurfaceWidth, CHAT_FIRST_MODE_STORAGE_KEY, CHAT_FIRST_MODE_CHANGED_EVENT, CHAT_FIRST_OPEN_APP_EVENT, CHAT_FIRST_OPEN_BROWSER_EVENT, CHAT_FIRST_WATCH_SESSION_EVENT, CHAT_FIRST_SURFACE_CATALOG, chatFirstSurfaceTabId, closeChatFirstSessionWatch, emitChatFirstOpenApp, emitChatFirstOpenBrowser, emitChatFirstSessionWatch, getChatFirstSessionWatchStore, getChatFirstSurfaceTabsStore, getChatFirstSurfacePanelStore, orderChatFirstAppIds, readChatFirstAppLayout, resolveChatFirstAppTarget, resolveChatFirstBrowserTarget, resolveChatFirstSessionId, normalizeChatFirstSessionReference, readChatFirstMode, readChatFirstModeState, readChatFirstSurfaceWidth, subscribeChatFirstOpenApp, subscribeChatFirstOpenBrowser, subscribeChatFirstSessionWatch, useChatFirstSessionWatch, useChatFirstSurfaceResize, useChatFirstSurfacePanel, useChatFirstSurfaceTabs, writeChatFirstAppLayout, writeChatFirstMode, writeChatFirstSurfaceWidth, type ChatFirstAppLayoutPreference, type ChatFirstModeReadResult, type ChatFirstAppRegistration, type ChatFirstAppResolution, type ChatFirstAppTarget, type ChatFirstAgentActivity, type ChatFirstAgentActivityStatus, type ChatFirstOpenAppDelivery, type ChatFirstOpenAppDetail, type ChatFirstOpenBrowserDetail, type ChatFirstBrowserResolution, type ChatFirstSessionKind, type ChatFirstSessionReference, type ChatFirstSessionWatchDelivery, type ChatFirstSessionWatchState, type ChatFirstSessionWatchStore, type ChatFirstSurfaceKind, type ChatFirstSurfaceTab, type ChatFirstSurfacePanelState, type ChatFirstSurfacePanelStore, type ChatFirstSurfaceTabsState, type ChatFirstSurfaceTabsStore, } from "../chat-first.js";
|
|
42
|
+
export { CHAT_FIRST_APP_LAYOUT_STORAGE_KEY, CHAT_FIRST_DEFAULT_APP_IDS, CHAT_FIRST_SURFACE_TABS_STORAGE_KEY, CHAT_FIRST_SURFACE_PANEL_STORAGE_KEY, CHAT_FIRST_SURFACE_WIDTH_DEFAULT, CHAT_FIRST_SURFACE_WIDTH_MIN, clampChatFirstSurfaceWidth, CHAT_FIRST_MODE_STORAGE_KEY, CHAT_FIRST_MODE_CHANGED_EVENT, CHAT_FIRST_OPEN_APP_EVENT, CHAT_FIRST_OPEN_BROWSER_EVENT, CHAT_FIRST_WATCH_SESSION_EVENT, CHAT_FIRST_SURFACE_CATALOG, chatFirstSurfaceTabId, closeChatFirstSessionWatch, emitChatFirstOpenApp, emitChatFirstOpenBrowser, emitChatFirstSessionWatch, getChatFirstSessionWatchStore, getChatFirstSurfaceTabsStore, getChatFirstSurfacePanelStore, orderChatFirstAppIds, readChatFirstAppLayout, resolveChatFirstAppTarget, resolveChatFirstBrowserTarget, resolveChatFirstSessionId, normalizeChatFirstSessionReference, readChatFirstMode, readChatFirstModeState, readChatFirstSurfaceWidth, subscribeChatFirstOpenApp, subscribeChatFirstOpenBrowser, subscribeChatFirstSessionWatch, useChatFirstSessionWatch, useChatFirstSurfaceResize, useChatFirstSurfacePanel, useChatFirstSurfaceTabs, writeChatFirstAppLayout, writeChatFirstMode, writeChatFirstSurfaceWidth, type ChatFirstAppLayoutPreference, type ChatFirstModeReadResult, type ChatFirstAppRegistration, type ChatFirstAppResolution, type ChatFirstAppTarget, type ChatFirstAppSurfacePlacement, type ChatFirstAgentActivity, type ChatFirstAgentActivityStatus, type ChatFirstOpenAppDelivery, type ChatFirstOpenAppDetail, type ChatFirstOpenBrowserDetail, type ChatFirstBrowserResolution, type ChatFirstSessionKind, type ChatFirstSessionReference, type ChatFirstSessionWatchDelivery, type ChatFirstSessionWatchState, type ChatFirstSessionWatchStore, type ChatFirstSurfaceKind, type ChatFirstSurfaceTab, type ChatFirstSurfacePanelState, type ChatFirstSurfacePanelStore, type ChatFirstSurfaceTabsState, type ChatFirstSurfaceTabsStore, } from "../chat-first.js";
|
|
@@ -85,6 +85,16 @@ const LARGE_INPUT_TOOL_NAMES = new Set([
|
|
|
85
85
|
]);
|
|
86
86
|
const MAX_HISTORY_LARGE_TOOL_ARGS_CHARS = 200_000;
|
|
87
87
|
const STARTUP_RESPONSE_TIMEOUT_MS = 45_000;
|
|
88
|
+
function dispatchTerminalChatUiCleanup(tabId) {
|
|
89
|
+
if (typeof window === "undefined")
|
|
90
|
+
return;
|
|
91
|
+
// Some terminal outcomes are synthesized by the adapter after recovery
|
|
92
|
+
// (for example, a completed tool whose final response timed out) and never
|
|
93
|
+
// pass through a terminal SSE frame. Clear both halves of the status UI so
|
|
94
|
+
// the wrap-up result cannot leave a preparation label or "Resuming" state.
|
|
95
|
+
window.dispatchEvent(new CustomEvent("agent-chat:activity-clear", { detail: { tabId } }));
|
|
96
|
+
window.dispatchEvent(new CustomEvent("agent-chat:stream-progress", { detail: { tabId } }));
|
|
97
|
+
}
|
|
88
98
|
// ── Background follow mode ──────────────────────────────────────────────────
|
|
89
99
|
// For server-continued runs (dispatchMode starts with "background" or equals
|
|
90
100
|
// "foreground-self-chain") the SERVER normally chains continuation chunks
|
|
@@ -3526,6 +3536,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3526
3536
|
}
|
|
3527
3537
|
finally {
|
|
3528
3538
|
if (typeof window !== "undefined") {
|
|
3539
|
+
dispatchTerminalChatUiCleanup(tabId);
|
|
3529
3540
|
window.dispatchEvent(new CustomEvent("agentNative.chatRunning", {
|
|
3530
3541
|
detail: { isRunning: false, tabId },
|
|
3531
3542
|
}));
|
|
@@ -42,7 +42,7 @@ export interface AgentChatMessage {
|
|
|
42
42
|
model?: string;
|
|
43
43
|
/** Engine preference paired with model for cross-provider switches. */
|
|
44
44
|
engine?: string;
|
|
45
|
-
/**
|
|
45
|
+
/** Effort preference paired with model. */
|
|
46
46
|
effort?: ReasoningEffort;
|
|
47
47
|
/**
|
|
48
48
|
* Execution mode for this submitted turn. When omitted, sendToAgentChat
|
|
@@ -264,6 +264,8 @@ function rememberStreamingText(resetKey, targetText, visibleText) {
|
|
|
264
264
|
if (oldestKey !== undefined)
|
|
265
265
|
smoothStreamingTextCache.delete(oldestKey);
|
|
266
266
|
}
|
|
267
|
+
/** Stable placeholder so the grapheme ref stays `string[]` before it is seeded. */
|
|
268
|
+
const EMPTY_GRAPHEMES = [];
|
|
267
269
|
export function useSmoothStreamingText(targetText, streaming, resetKey) {
|
|
268
270
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
269
271
|
const [visibleText, setVisibleText] = useState(() => {
|
|
@@ -276,9 +278,19 @@ export function useSmoothStreamingText(targetText, streaming, resetKey) {
|
|
|
276
278
|
return sliceGraphemes(targetText, graphemes, initialSmoothStreamingGraphemeCount(graphemes));
|
|
277
279
|
});
|
|
278
280
|
const visibleTextRef = useRef(visibleText);
|
|
279
|
-
const visibleCountRef = useRef(splitStreamingTextGraphemes(visibleText).length);
|
|
280
281
|
const targetTextRef = useRef(targetText);
|
|
281
|
-
|
|
282
|
+
// `useRef(expr)` evaluates `expr` on EVERY render and throws it away after
|
|
283
|
+
// mount. Segmenting here therefore ran a full Intl.Segmenter pass per commit
|
|
284
|
+
// — up to 60Hz per streaming message — and, because `visibleText` is a strict
|
|
285
|
+
// prefix of `targetText`, that pass could never hit the incremental path and
|
|
286
|
+
// evicted the shared segmenter cache for every other live stream too. Seed
|
|
287
|
+
// once; the streaming effect below keeps both refs authoritative after that.
|
|
288
|
+
const visibleCountRef = useRef(-1);
|
|
289
|
+
const targetGraphemesRef = useRef(EMPTY_GRAPHEMES);
|
|
290
|
+
if (visibleCountRef.current < 0) {
|
|
291
|
+
targetGraphemesRef.current = splitStreamingTextGraphemes(targetText);
|
|
292
|
+
visibleCountRef.current = splitStreamingTextGraphemes(visibleText).length;
|
|
293
|
+
}
|
|
282
294
|
const frameRef = useRef(null);
|
|
283
295
|
const lastCommitAtRef = useRef(0);
|
|
284
296
|
const pauseUntilRef = useRef(0);
|
|
@@ -49,15 +49,19 @@ export declare function shouldOfferRestore(args: {
|
|
|
49
49
|
* messages put it at `metadata.runId`.
|
|
50
50
|
*/
|
|
51
51
|
export declare function assistantMessageRunId(message: unknown): string | undefined;
|
|
52
|
+
export declare function resolveAssistantRequestId(message: unknown, activeRun: {
|
|
53
|
+
threadId: string;
|
|
54
|
+
runId: string;
|
|
55
|
+
} | null, threadId: string): string | undefined;
|
|
52
56
|
export declare function MessageBranchPicker(): React.JSX.Element;
|
|
53
|
-
export declare function MessageActionsMenu({ showRevert, onRevert, }?: {
|
|
57
|
+
export declare function MessageActionsMenu({ showRevert, onRevert, threadId, }?: {
|
|
54
58
|
showRevert?: boolean;
|
|
55
59
|
onRevert?: () => void;
|
|
60
|
+
threadId?: string;
|
|
56
61
|
}): React.JSX.Element;
|
|
57
62
|
export declare function UserMessage(): React.JSX.Element | null;
|
|
58
63
|
export declare function messageTextFromContent(content: unknown): string;
|
|
59
64
|
export declare function isMissingFinalResponseWarningText(text: string): boolean;
|
|
60
|
-
export declare function completedAssistantToolNamesAfterLastText(content: readonly ContentPart[]): string[];
|
|
61
65
|
export declare function latestUserMessageText(messages: readonly unknown[]): string;
|
|
62
66
|
export declare function userMessageTextBeforeAssistant(messages: readonly unknown[], assistantMessageId: string): string;
|
|
63
67
|
export declare function assistantMessageHasUnresolvedTool(content: unknown): boolean;
|
|
@@ -14,7 +14,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel,
|
|
|
14
14
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
15
15
|
import { ThumbsFeedback } from "../observability/ThumbsFeedback.js";
|
|
16
16
|
import { McpConnectionSuggestion } from "../resources/McpConnectionSuggestion.js";
|
|
17
|
-
import {
|
|
17
|
+
import { isCallAgentToolCallShadowed, shadowedCallAgentToolCallIds, } from "../tool-display.js";
|
|
18
18
|
import { cn } from "../utils.js";
|
|
19
19
|
import { MarkdownText, renderMarkdownToClipboardHtml, SmoothMarkdownText, } from "./markdown-renderer.js";
|
|
20
20
|
import { getAssistantRunDurationMs } from "./repo-helpers.js";
|
|
@@ -172,6 +172,10 @@ export function assistantMessageRunId(message) {
|
|
|
172
172
|
? metadata.runId
|
|
173
173
|
: undefined;
|
|
174
174
|
}
|
|
175
|
+
export function resolveAssistantRequestId(message, activeRun, threadId) {
|
|
176
|
+
return (assistantMessageRunId(message) ||
|
|
177
|
+
(activeRun?.threadId === threadId ? activeRun.runId : undefined));
|
|
178
|
+
}
|
|
175
179
|
// ─── MessageBranchPicker ──────────────────────────────────────────────────────
|
|
176
180
|
export function MessageBranchPicker() {
|
|
177
181
|
return (_jsxs(BranchPickerPrimitive.Root, { hideWhenSingleBranch: true, className: "flex items-center gap-0.5 text-[11px] text-muted-foreground", children: [_jsx(BranchPickerPrimitive.Previous, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Previous branch", className: "flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 transition-colors duration-150 hover:bg-accent hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40", children: _jsx(IconChevronLeft, { className: "h-3.5 w-3.5" }) }) }), _jsxs("span", { className: "tabular-nums select-none", children: [_jsx(BranchPickerPrimitive.Number, {}), "/", _jsx(BranchPickerPrimitive.Count, {})] }), _jsx(BranchPickerPrimitive.Next, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Next branch", className: "flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 transition-colors duration-150 hover:bg-accent hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40", children: _jsx(IconChevronRight, { className: "h-3.5 w-3.5" }) }) })] }));
|
|
@@ -284,7 +288,7 @@ function UserMessageEditComposer() {
|
|
|
284
288
|
return (_jsxs(ComposerPrimitive.Root, { className: "flex flex-col gap-2 rounded-lg border border-border bg-background px-3 py-2 shadow-sm", children: [_jsx(ComposerPrimitive.Input, { className: "w-full resize-none bg-transparent text-sm leading-relaxed text-foreground placeholder:text-muted-foreground focus:outline-none", rows: 1, submitMode: "enter" }), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(ComposerPrimitive.Cancel, { asChild: true, children: _jsx("button", { type: "button", className: "cursor-pointer rounded-md px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground", children: "Cancel" }) }), _jsx(ComposerPrimitive.Send, { asChild: true, children: _jsx("button", { type: "submit", className: "cursor-pointer rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: "Save" }) })] })] }));
|
|
285
289
|
}
|
|
286
290
|
// ─── MessageActionsMenu ────────────────────────────────────────────────────────
|
|
287
|
-
export function MessageActionsMenu({ showRevert, onRevert, } = {}) {
|
|
291
|
+
export function MessageActionsMenu({ showRevert, onRevert, threadId = "", } = {}) {
|
|
288
292
|
const [open, setOpen] = useState(false);
|
|
289
293
|
const [copied, setCopied] = useState(null);
|
|
290
294
|
const messageRuntime = useMessageRuntime();
|
|
@@ -311,24 +315,23 @@ export function MessageActionsMenu({ showRevert, onRevert, } = {}) {
|
|
|
311
315
|
}, [messageRuntime]);
|
|
312
316
|
const handleCopyRequestId = useCallback(() => {
|
|
313
317
|
const m = messageRuntime.getState();
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
(typeof window !== "undefined" ? getActiveRun()?.runId : null) ||
|
|
320
|
-
m.id ||
|
|
321
|
-
"";
|
|
318
|
+
const runId = resolveAssistantRequestId(m, getActiveRun(), threadId);
|
|
319
|
+
if (!runId) {
|
|
320
|
+
setCopied("id-unavailable");
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
322
323
|
void writeClipboardText(runId).then((ok) => {
|
|
323
|
-
if (!ok)
|
|
324
|
+
if (!ok) {
|
|
325
|
+
setCopied("id-failed");
|
|
324
326
|
return;
|
|
327
|
+
}
|
|
325
328
|
setCopied("id");
|
|
326
329
|
setTimeout(() => {
|
|
327
330
|
setCopied(null);
|
|
328
331
|
setOpen(false);
|
|
329
332
|
}, 1000);
|
|
330
333
|
});
|
|
331
|
-
}, [messageRuntime]);
|
|
334
|
+
}, [messageRuntime, threadId]);
|
|
332
335
|
const handleForkChat = useCallback(() => {
|
|
333
336
|
setOpen(false);
|
|
334
337
|
actionsCtx?.onForkChat?.();
|
|
@@ -343,7 +346,13 @@ export function MessageActionsMenu({ showRevert, onRevert, } = {}) {
|
|
|
343
346
|
}, children: [copied === "message" ? (_jsx(IconCheck, { className: "h-3.5 w-3.5" })) : (_jsx(IconCopy, { className: "h-3.5 w-3.5" })), copied === "message" ? "Copied!" : "Copy Message"] }), _jsxs(DropdownMenuItem, { onSelect: (e) => {
|
|
344
347
|
e.preventDefault();
|
|
345
348
|
handleCopyRequestId();
|
|
346
|
-
}, children: [copied === "id" ? (_jsx(IconCheck, { className: "h-3.5 w-3.5" })) : (_jsx(IconId, { className: "h-3.5 w-3.5" })), copied === "id"
|
|
349
|
+
}, children: [copied === "id" ? (_jsx(IconCheck, { className: "h-3.5 w-3.5" })) : (_jsx(IconId, { className: "h-3.5 w-3.5" })), copied === "id"
|
|
350
|
+
? "Copied!"
|
|
351
|
+
: copied === "id-unavailable"
|
|
352
|
+
? "Request ID unavailable"
|
|
353
|
+
: copied === "id-failed"
|
|
354
|
+
? "Copy failed"
|
|
355
|
+
: "Copy Request ID"] }), showRevert && (_jsxs(DropdownMenuItem, { onSelect: handleRevert, children: [_jsx(IconArrowBackUp, { className: "h-3.5 w-3.5" }), "Revert to here"] })), timestamp && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuLabel, { className: "px-2 py-1 text-[11px] font-normal text-muted-foreground", children: ["Sent ", timestamp.short] })] }))] })] }));
|
|
347
356
|
}
|
|
348
357
|
// ─── UserMessage ──────────────────────────────────────────────────────────────
|
|
349
358
|
export function UserMessage() {
|
|
@@ -481,29 +490,6 @@ function missingFinalResponseWarningText(content) {
|
|
|
481
490
|
}
|
|
482
491
|
return null;
|
|
483
492
|
}
|
|
484
|
-
export function completedAssistantToolNamesAfterLastText(content) {
|
|
485
|
-
let lastTextIndex = -1;
|
|
486
|
-
for (let index = content.length - 1; index >= 0; index -= 1) {
|
|
487
|
-
if (content[index]?.type === "text") {
|
|
488
|
-
lastTextIndex = index;
|
|
489
|
-
break;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
const names = new Set();
|
|
493
|
-
for (let index = lastTextIndex + 1; index < content.length; index += 1) {
|
|
494
|
-
const part = content[index];
|
|
495
|
-
if (part?.type !== "tool-call" ||
|
|
496
|
-
part.activity === true ||
|
|
497
|
-
part.result === undefined ||
|
|
498
|
-
part.isError === true ||
|
|
499
|
-
part.outcome === "unknown" ||
|
|
500
|
-
isCallAgentToolCallShadowed(content, index)) {
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
names.add(humanizeToolName(part.toolName));
|
|
504
|
-
}
|
|
505
|
-
return [...names];
|
|
506
|
-
}
|
|
507
493
|
export function latestUserMessageText(messages) {
|
|
508
494
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
509
495
|
const message = messages[index];
|
|
@@ -781,11 +767,6 @@ export function InlineRunErrorNotice({ info, durationMs, onRetry, }) {
|
|
|
781
767
|
: headline;
|
|
782
768
|
return (_jsxs("div", { className: "my-1 w-full", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), "aria-expanded": open, className: "flex cursor-pointer items-center gap-1.5 py-0.5 text-[13px] text-muted-foreground transition-colors hover:text-foreground", children: [_jsx(IconAlertTriangle, { className: "size-3.5 shrink-0 text-amber-500" }), _jsx("span", { className: "truncate", children: label }), _jsx(IconChevronRight, { className: cn("size-3.5 shrink-0 transition-transform", open && "rotate-90") })] }), open && (_jsxs("div", { className: "mt-1 rounded-md border border-border/60 bg-background/70 p-2 text-[11px] leading-relaxed text-muted-foreground", children: [_jsx("p", { className: "whitespace-pre-wrap break-words", children: info.message }), info.errorCode && (_jsxs("div", { className: "mt-1 font-mono", children: ["code: ", info.errorCode] })), info.runId && _jsxs("div", { className: "font-mono", children: ["run: ", info.runId] }), info.details && (_jsx("pre", { className: "mt-1 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details })), onRetry && (_jsxs("button", { type: "button", onClick: onRetry, className: "mt-2 inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { className: "size-3" }), "Retry"] }))] }))] }));
|
|
783
769
|
}
|
|
784
|
-
function AssistantCompletionProgress({ messageId, toolNames, }) {
|
|
785
|
-
if (toolNames.length === 0)
|
|
786
|
-
return null;
|
|
787
|
-
return (_jsx("div", { className: "my-1 w-full text-[13px] text-muted-foreground", role: "status", "aria-live": "polite", "data-testid": "assistant-completion-progress", children: _jsx(SmoothMarkdownText, { text: `The agent completed these actions: ${toolNames.join(", ")}`, streaming: true, resetKey: `assistant-completion-progress:${messageId}`, statusType: "running" }) }));
|
|
788
|
-
}
|
|
789
770
|
function MissingFinalResponseNotice({ messageId, text, animate, onRevealComplete, }) {
|
|
790
771
|
return (_jsx("div", { className: "my-1 w-full text-muted-foreground", role: "status", "aria-live": "polite", "data-testid": "missing-final-response", children: _jsx(SmoothMarkdownText, { text: text, streaming: animate, resetKey: `missing-final-response:${messageId}`, statusType: animate ? "running" : "complete", onRevealComplete: animate ? onRevealComplete : undefined }) }));
|
|
791
772
|
}
|
|
@@ -849,9 +830,6 @@ export function AssistantMessage() {
|
|
|
849
830
|
return;
|
|
850
831
|
setRevealedMissingFinalResponseKey(missingFinalResponseAnimationKey);
|
|
851
832
|
}, [missingFinalResponseAnimationKey]);
|
|
852
|
-
const completedToolNames = isLast && chatRunning && !hasCompletedCustomUi && Array.isArray(msg.content)
|
|
853
|
-
? completedAssistantToolNamesAfterLastText(msg.content)
|
|
854
|
-
: [];
|
|
855
833
|
const shouldHoldCompletionFooter = isLast &&
|
|
856
834
|
((missingFinalResponseCandidate && !showMissingFinalResponse) ||
|
|
857
835
|
(animateMissingFinalResponse && !missingFinalResponseRevealed));
|
|
@@ -1004,15 +982,15 @@ export function AssistantMessage() {
|
|
|
1004
982
|
case "tool-call":
|
|
1005
983
|
if (shadowedToolCallIds.has(part.toolCallId))
|
|
1006
984
|
return null;
|
|
1007
|
-
return part.toolUI ? (_jsx(ToolActivityPresentation, { toolName: part.toolName, isRunning: part.status?.type === "running",
|
|
985
|
+
return part.toolUI ? (_jsx(ToolActivityPresentation, { toolName: part.toolName, isRunning: part.status?.type === "running", toolCallId: part.toolCallId, children: part.toolUI })) : (_jsx(ToolCallFallback, { ...part, isActiveTail: part.toolCallId === activeTailToolCallId }));
|
|
1008
986
|
default:
|
|
1009
987
|
return null;
|
|
1010
988
|
}
|
|
1011
|
-
} }) }),
|
|
989
|
+
} }) }), showInlineRunError && messageRunError && (_jsx(InlineRunErrorNotice, { info: messageRunError, durationMs: capturedDurationMs ?? persistedDurationMs, onRetry: isLast && messageRunError.recoverable
|
|
1012
990
|
? messageActions?.onRetryRunError
|
|
1013
991
|
: undefined })), missingWarningText == null &&
|
|
1014
992
|
missingFinalResponseNoticeText != null &&
|
|
1015
|
-
!showInlineRunError && (_jsx(MissingFinalResponseNotice, { messageId: msg.id, text: missingFinalResponseNoticeText, animate: animateMissingFinalResponse, onRevealComplete: handleMissingFinalResponseReveal })), isComplete && hasCodeAgentTools && msgContent && (_jsx(FilesChangedSummary, { parts: msgContent })), isComplete && (_jsx(McpConnectionSuggestion, { text: responseConnectionText, contextText: responseConnectionContext, variant: "response" }))] }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), isLast && (_jsx(TooltipProvider, { delayDuration: 400, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(ActionBarPrimitive.Reload, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Regenerate response", className: `flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 hover:bg-accent hover:text-foreground ${messageFooterFadeClassName} disabled:cursor-not-allowed disabled:opacity-40`, children: _jsx(IconRefresh, { className: "h-3.5 w-3.5" }) }) }) }), _jsx(TooltipContent, { side: "top", className: "text-xs", children: "Regenerate response" })] }) })), _jsx(MessageBranchPicker, {}), timestamp && (_jsx(MessageTimestamp, { timestamp: timestamp, className: messageFooterFadeClassName }))] }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : restoreState === "error" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: restoreError }), _jsx("button", { onClick: cancelRestore, className: "cursor-pointer rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Dismiss" })] })) : (_jsx(ThumbsFeedback, { threadId: cpCtx?.threadId ?? "", runId: messageRunId ?? "", messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }))] }))] }));
|
|
993
|
+
!showInlineRunError && (_jsx(MissingFinalResponseNotice, { messageId: msg.id, text: missingFinalResponseNoticeText, animate: animateMissingFinalResponse, onRevealComplete: handleMissingFinalResponseReveal })), isComplete && hasCodeAgentTools && msgContent && (_jsx(FilesChangedSummary, { parts: msgContent })), isComplete && (_jsx(McpConnectionSuggestion, { text: responseConnectionText, contextText: responseConnectionContext, variant: "response" }))] }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore, threadId: cpCtx?.threadId ?? "" }), isLast && (_jsx(TooltipProvider, { delayDuration: 400, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(ActionBarPrimitive.Reload, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Regenerate response", className: `flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 hover:bg-accent hover:text-foreground ${messageFooterFadeClassName} disabled:cursor-not-allowed disabled:opacity-40`, children: _jsx(IconRefresh, { className: "h-3.5 w-3.5" }) }) }) }), _jsx(TooltipContent, { side: "top", className: "text-xs", children: "Regenerate response" })] }) })), _jsx(MessageBranchPicker, {}), timestamp && (_jsx(MessageTimestamp, { timestamp: timestamp, className: messageFooterFadeClassName }))] }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : restoreState === "error" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: restoreError }), _jsx("button", { onClick: cancelRestore, className: "cursor-pointer rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Dismiss" })] })) : (_jsx(ThumbsFeedback, { threadId: cpCtx?.threadId ?? "", runId: messageRunId ?? "", messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }))] }))] }));
|
|
1016
994
|
}
|
|
1017
995
|
// ─── RunningActivityStatus / ThinkingIndicator ────────────────────────────────
|
|
1018
996
|
export function RunningActivityStatus({ label }) {
|
|
@@ -8,9 +8,8 @@ export declare const ChatRunningContext: React.Context<boolean>;
|
|
|
8
8
|
export declare const ChatRunDurationContext: React.Context<number | null>;
|
|
9
9
|
export declare const ASSISTANT_VISIBLE_TOOL_CALL_LIMIT = 3;
|
|
10
10
|
/**
|
|
11
|
-
* Keeps the
|
|
12
|
-
*
|
|
13
|
-
* untouched; this only animates the DOM's before/after positions.
|
|
11
|
+
* Keeps the tool-call stack layout-transparent. Tool-entry motion is disabled
|
|
12
|
+
* until it can stay stable while streaming calls are added and summarized.
|
|
14
13
|
*/
|
|
15
14
|
export declare function ToolCallStackMotion({ children, className, }: {
|
|
16
15
|
children: React.ReactNode;
|
|
@@ -55,10 +54,9 @@ export declare function toolCallHasPendingApproval(part: {
|
|
|
55
54
|
} | null;
|
|
56
55
|
}): boolean;
|
|
57
56
|
export declare const TOOL_LONG_RUNNING_HINT_DELAY_MS = 45000;
|
|
58
|
-
export declare function ToolActivityPresentation({ toolName, isRunning,
|
|
57
|
+
export declare function ToolActivityPresentation({ toolName, isRunning, toolCallId, suppressLongRunningHint, children, }: {
|
|
59
58
|
toolName: string;
|
|
60
59
|
isRunning: boolean;
|
|
61
|
-
isActiveTail: boolean;
|
|
62
60
|
toolCallId?: string;
|
|
63
61
|
suppressLongRunningHint?: boolean;
|
|
64
62
|
children: React.ReactNode;
|