@agent-native/toolkit 0.221.0-same-host-mcp-20261027-20261027081850 → 0.221.0
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/agent-native.eject.json +16 -1
- package/dist/app/agentkit/react/components.d.ts +5 -3
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +103 -42
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +93 -65
- package/dist/app/agentkit/react/voice-transcripts.d.ts +22 -1
- package/dist/app/agentkit/react/voice-transcripts.d.ts.map +1 -1
- package/dist/app/agentkit/react/voice-transcripts.js +209 -8
- package/dist/app/agentkit/react/voice-transcripts.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +55 -40
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +1 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +18 -6
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/index.js +1 -1
- package/dist/app/chat/agentkit-chat/index.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +5 -1
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/reply-connection-suggestion.d.ts +29 -0
- package/dist/app/chat/reply-connection-suggestion.d.ts.map +1 -0
- package/dist/app/chat/reply-connection-suggestion.js +42 -0
- package/dist/app/chat/reply-connection-suggestion.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +7 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +7 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +7 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +7 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +7 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +7 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +7 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +7 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +7 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +7 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +7 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +7 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/mcp-approval/McpApprovalReview.d.ts +25 -0
- package/dist/app/mcp-approval/McpApprovalReview.d.ts.map +1 -0
- package/dist/app/mcp-approval/McpApprovalReview.js +342 -0
- package/dist/app/mcp-approval/McpApprovalReview.js.map +1 -0
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +299 -71
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/GettingStartedCard.js +1 -1
- package/dist/app/onboarding/GettingStartedCard.js.map +1 -1
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts +2 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts.map +1 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js +8 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js.map +1 -0
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +14 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.d.ts +2 -4
- package/dist/app/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.js +59 -36
- package/dist/app/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.d.ts.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.js +14 -1
- package/dist/app/settings/account/PreferencesSettings.js.map +1 -1
- package/dist/app/settings/account/ThemeFamilySettings.js +2 -2
- package/dist/app/settings/account/ThemeFamilySettings.js.map +1 -1
- package/dist/app/settings/account/search-entries.d.ts +1 -0
- package/dist/app/settings/account/search-entries.d.ts.map +1 -1
- package/dist/app/settings/account/search-entries.js +5 -0
- package/dist/app/settings/account/search-entries.js.map +1 -1
- package/dist/app/settings/shell/SettingsShell.d.ts.map +1 -1
- package/dist/app/settings/shell/SettingsShell.js +26 -2
- package/dist/app/settings/shell/SettingsShell.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +4 -10
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/app/shared/EnvironmentBadge.d.ts +2 -1
- package/dist/app/shared/EnvironmentBadge.d.ts.map +1 -1
- package/dist/app/shared/EnvironmentBadge.js +2 -3
- package/dist/app/shared/EnvironmentBadge.js.map +1 -1
- package/dist/app/shared/is-builder-io-employee.d.ts +8 -0
- package/dist/app/shared/is-builder-io-employee.d.ts.map +1 -0
- package/dist/app/shared/is-builder-io-employee.js +10 -0
- package/dist/app/shared/is-builder-io-employee.js.map +1 -0
- package/dist/app/styles/agent-conversation.css +30 -17
- package/dist/app/styles/theme-families.css +22 -5
- package/dist/app/styles/tokens/agent-kit.css +3 -3
- package/dist/composer/PromptComposer.d.ts +15 -3
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +74 -16
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/RealtimeVoiceMode.d.ts +7 -0
- package/dist/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/RealtimeVoiceMode.js +9 -2
- package/dist/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +7 -0
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +12 -4
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts +2 -0
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +5 -4
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/index.d.ts +2 -2
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -1
- package/dist/composer/index.js.map +1 -1
- package/dist/composer/prompt-attachments.d.ts +20 -0
- package/dist/composer/prompt-attachments.d.ts.map +1 -1
- package/dist/composer/prompt-attachments.js +188 -11
- package/dist/composer/prompt-attachments.js.map +1 -1
- package/dist/composer/realtime-voice-transcript.d.ts +27 -0
- package/dist/composer/realtime-voice-transcript.d.ts.map +1 -1
- package/dist/composer/realtime-voice-transcript.js +34 -1
- package/dist/composer/realtime-voice-transcript.js.map +1 -1
- package/dist/composer/realtime-voice-turn-metrics.d.ts +43 -0
- package/dist/composer/realtime-voice-turn-metrics.d.ts.map +1 -0
- package/dist/composer/realtime-voice-turn-metrics.js +132 -0
- package/dist/composer/realtime-voice-turn-metrics.js.map +1 -0
- package/dist/composer/runtime-adapters.d.ts +4 -1
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.d.ts +61 -9
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.js +536 -99
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/composer/voice-chat-icon.d.ts +7 -0
- package/dist/composer/voice-chat-icon.d.ts.map +1 -0
- package/dist/composer/voice-chat-icon.js +14 -0
- package/dist/composer/voice-chat-icon.js.map +1 -0
- package/dist/editor/DragHandle.d.ts +12 -1
- package/dist/editor/DragHandle.d.ts.map +1 -1
- package/dist/editor/DragHandle.js +165 -41
- package/dist/editor/DragHandle.js.map +1 -1
- package/dist/editor/RegistryBlockNode.d.ts +20 -0
- package/dist/editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/editor/RegistryBlockNode.js +58 -13
- package/dist/editor/RegistryBlockNode.js.map +1 -1
- package/dist/editor/index.d.ts +2 -2
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/editor/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +5 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +14 -4
- package/src/app/agentkit/react/components.regenerate-readiness.spec.tsx +3 -1
- package/src/app/agentkit/react/components.spec.tsx +24 -4
- package/src/app/agentkit/react/components.tsx +174 -44
- package/src/app/agentkit/react/composer-context.spec.tsx +3 -0
- package/src/app/agentkit/react/disclosures.spec.tsx +124 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +8 -2
- package/src/app/agentkit/react/message-actions.spec.tsx +161 -5
- package/src/app/agentkit/react/saved-reply-reload.spec.tsx +206 -0
- package/src/app/agentkit/react/styles.css +93 -65
- package/src/app/agentkit/react/voice-transcripts.spec.tsx +239 -4
- package/src/app/agentkit/react/voice-transcripts.ts +245 -8
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +59 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +74 -62
- package/src/app/chat/agentkit-chat/guided-answers-context.spec.ts +9 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +17 -7
- package/src/app/chat/agentkit-chat/index.ts +1 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +45 -0
- package/src/app/chat/chat/run-recovery.tsx +6 -1
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/reply-connection-suggestion.spec.ts +121 -0
- package/src/app/chat/reply-connection-suggestion.ts +76 -0
- package/src/app/i18n/catalogs/ar-SA.ts +10 -0
- package/src/app/i18n/catalogs/de-DE.ts +10 -0
- package/src/app/i18n/catalogs/en-US.ts +10 -0
- package/src/app/i18n/catalogs/es-ES.ts +10 -0
- package/src/app/i18n/catalogs/fr-FR.ts +10 -0
- package/src/app/i18n/catalogs/hi-IN.ts +10 -0
- package/src/app/i18n/catalogs/ja-JP.ts +10 -0
- package/src/app/i18n/catalogs/ko-KR.ts +10 -0
- package/src/app/i18n/catalogs/pt-BR.ts +10 -0
- package/src/app/i18n/catalogs/zh-CN.ts +10 -0
- package/src/app/i18n/catalogs/zh-TW.ts +10 -0
- package/src/app/mcp-approval/McpApprovalReview.spec.tsx +687 -0
- package/src/app/mcp-approval/McpApprovalReview.tsx +913 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +736 -26
- package/src/app/onboarding/FirstRunOnboarding.tsx +473 -145
- package/src/app/onboarding/GettingStartedCard.tsx +1 -1
- package/src/app/onboarding/first-run-builder-credits-flag.spec.ts +13 -0
- package/src/app/onboarding/first-run-builder-credits-flag.ts +9 -0
- package/src/app/providers/AppProviders.spec.tsx +109 -0
- package/src/app/providers/AppProviders.tsx +53 -1
- package/src/app/resources/McpConnectionSuggestion.spec.ts +77 -12
- package/src/app/resources/McpConnectionSuggestion.tsx +69 -51
- package/src/app/settings/VoiceChatSettings.spec.tsx +6 -1
- package/src/app/settings/account/PreferencesSettings.spec.tsx +73 -0
- package/src/app/settings/account/PreferencesSettings.tsx +24 -7
- package/src/app/settings/account/ThemeFamilySettings.tsx +2 -2
- package/src/app/settings/account/search-entries.spec.ts +14 -0
- package/src/app/settings/account/search-entries.ts +9 -0
- package/src/app/settings/shell/SettingsShell.tsx +29 -2
- package/src/app/shared/AppShellSkeleton.spec.tsx +2 -2
- package/src/app/shared/AppShellSkeleton.tsx +3 -16
- package/src/app/shared/EnvironmentBadge.tsx +3 -4
- package/src/app/shared/is-builder-io-employee.ts +17 -0
- package/src/app/styles/agent-conversation.css +30 -17
- package/src/app/styles/theme-families.css +22 -5
- package/src/app/styles/theme-families.spec.ts +73 -0
- package/src/app/styles/tokens/agent-kit.css +3 -3
- package/src/composer/AgentSuggestionBar.overflow.spec.tsx +1 -1
- package/src/composer/AttachmentChip.spec.tsx +87 -0
- package/src/composer/PromptComposer.context.spec.tsx +8 -4
- package/src/composer/PromptComposer.setup-card.spec.tsx +170 -0
- package/src/composer/PromptComposer.tsx +125 -14
- package/src/composer/RealtimeVoiceMode.spec.tsx +48 -0
- package/src/composer/RealtimeVoiceMode.tsx +45 -2
- package/src/composer/TiptapComposer.tsx +25 -0
- package/src/composer/TiptapComposer.voice-toolbar.spec.tsx +4 -1
- package/src/composer/VoiceButton.tsx +8 -3
- package/src/composer/index.ts +4 -0
- package/src/composer/prompt-attachments.spec.ts +160 -8
- package/src/composer/prompt-attachments.ts +221 -12
- package/src/composer/realtime-voice-transcript.spec.ts +36 -0
- package/src/composer/realtime-voice-transcript.ts +56 -1
- package/src/composer/realtime-voice-turn-metrics.spec.ts +175 -0
- package/src/composer/realtime-voice-turn-metrics.ts +192 -0
- package/src/composer/runtime-adapters.tsx +5 -1
- package/src/composer/useRealtimeVoiceMode.session.spec.tsx +487 -2
- package/src/composer/useRealtimeVoiceMode.spec.ts +267 -65
- package/src/composer/useRealtimeVoiceMode.tsx +716 -139
- package/src/composer/voice-chat-icon.tsx +19 -0
- package/src/editor/DragHandle.spec.ts +217 -0
- package/src/editor/DragHandle.ts +214 -55
- package/src/editor/RegistryBlockNode.spec.ts +172 -2
- package/src/editor/RegistryBlockNode.tsx +91 -13
- package/src/editor/index.ts +4 -0
- package/src/styles.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -108,6 +108,7 @@ import {
|
|
|
108
108
|
ComposerNotice,
|
|
109
109
|
ComposerNoticeScope,
|
|
110
110
|
} from "../../../composer/composer-notice.js";
|
|
111
|
+
import { useComposerRuntimeAdapters } from "../../../composer/runtime-adapters.js";
|
|
111
112
|
import { Dialog, Tooltip } from "../../../design-system/index.js";
|
|
112
113
|
import { useTableColumnGlide } from "../../../table-column-glide.js";
|
|
113
114
|
import { Skeleton } from "../../../ui/skeleton.js";
|
|
@@ -2263,6 +2264,7 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({
|
|
|
2263
2264
|
isCurrentSegment = true,
|
|
2264
2265
|
messageId,
|
|
2265
2266
|
foldedReasoningMessageId,
|
|
2267
|
+
summarizesTurn = false,
|
|
2266
2268
|
}: {
|
|
2267
2269
|
runId?: RunId;
|
|
2268
2270
|
afterSequence?: number;
|
|
@@ -2273,9 +2275,17 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({
|
|
|
2273
2275
|
messageId?: string;
|
|
2274
2276
|
/** A saved reply whose reasoning before its answer joins this group. */
|
|
2275
2277
|
foldedReasoningMessageId?: string;
|
|
2278
|
+
/** This segment is its run's whole turn, so it shows a row with no work. */
|
|
2279
|
+
summarizesTurn?: boolean;
|
|
2276
2280
|
}) {
|
|
2277
|
-
const {
|
|
2278
|
-
|
|
2281
|
+
const {
|
|
2282
|
+
threadId,
|
|
2283
|
+
slots,
|
|
2284
|
+
registry,
|
|
2285
|
+
labels,
|
|
2286
|
+
formatWorkedForDuration,
|
|
2287
|
+
loadRunUsage,
|
|
2288
|
+
} = useAgentKit();
|
|
2279
2289
|
const thread = useAgentThreadSlice((previous, next) =>
|
|
2280
2290
|
sameRunWork(previous, next, runId),
|
|
2281
2291
|
);
|
|
@@ -2554,9 +2564,15 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({
|
|
|
2554
2564
|
event.type === "run.failed" ||
|
|
2555
2565
|
event.type === "run.cancelled"),
|
|
2556
2566
|
);
|
|
2567
|
+
// A local run, such as voice chat's, never starts on the server, so it
|
|
2568
|
+
// stays queued while it works; its own events show it is working.
|
|
2569
|
+
const localRunWorking =
|
|
2570
|
+
run?.status === "queued" && runEvents.length > 0 && !hasTerminalRunEvent;
|
|
2557
2571
|
const activelyWorking =
|
|
2558
2572
|
isCurrentSegment &&
|
|
2559
|
-
(run
|
|
2573
|
+
(run
|
|
2574
|
+
? run.status === "running" || localRunWorking
|
|
2575
|
+
: running && !hasTerminalRunEvent);
|
|
2560
2576
|
const waitingLabel =
|
|
2561
2577
|
isCurrentSegment && run?.status === "awaiting_approval"
|
|
2562
2578
|
? labels.waitingForApproval
|
|
@@ -2572,12 +2588,48 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({
|
|
|
2572
2588
|
(afterSequence === undefined &&
|
|
2573
2589
|
run !== undefined &&
|
|
2574
2590
|
["completed", "failed", "cancelled"].includes(run.status)));
|
|
2591
|
+
const formatDuration = (ms: number) =>
|
|
2592
|
+
formatWorkedForDuration?.(ms) ??
|
|
2593
|
+
formatAgentKitDuration(ms, {
|
|
2594
|
+
hour: labels.durationHourShort,
|
|
2595
|
+
minute: labels.durationMinuteShort,
|
|
2596
|
+
second: labels.durationSecondShort,
|
|
2597
|
+
});
|
|
2575
2598
|
if (
|
|
2576
2599
|
activityItems.length === 0 &&
|
|
2577
2600
|
durableToolResults.length === 0 &&
|
|
2578
2601
|
!activelyWorking
|
|
2579
2602
|
) {
|
|
2580
|
-
|
|
2603
|
+
const runFinished = run
|
|
2604
|
+
? ["completed", "failed", "cancelled"].includes(run.status)
|
|
2605
|
+
: hasTerminalRunEvent;
|
|
2606
|
+
// Untimed or under a second, a bare "Worked" would read as instant.
|
|
2607
|
+
if (
|
|
2608
|
+
!summarizesTurn ||
|
|
2609
|
+
!runFinished ||
|
|
2610
|
+
durationMs === undefined ||
|
|
2611
|
+
durationMs < 1_000
|
|
2612
|
+
) {
|
|
2613
|
+
return null;
|
|
2614
|
+
}
|
|
2615
|
+
// With no steps, the run's details (cost, model) are what it opens to, so
|
|
2616
|
+
// it opens only when it can show one of them.
|
|
2617
|
+
const selectedModel = selectedRunModel(thread.messages, messageId);
|
|
2618
|
+
const hasRunDetails =
|
|
2619
|
+
runId !== undefined &&
|
|
2620
|
+
(loadRunUsage !== undefined ||
|
|
2621
|
+
(selectedModel !== undefined && selectedModel !== "auto"));
|
|
2622
|
+
return (
|
|
2623
|
+
<AgentWorkDisclosure
|
|
2624
|
+
label={workedSummaryLabel(durationMs, labels, formatDuration)}
|
|
2625
|
+
icon={<IconClock aria-hidden="true" className="agentkit-icon" />}
|
|
2626
|
+
expandable={hasRunDetails}
|
|
2627
|
+
{...(runId === undefined ? {} : { runId })}
|
|
2628
|
+
{...(messageId === undefined ? {} : { messageId })}
|
|
2629
|
+
>
|
|
2630
|
+
{null}
|
|
2631
|
+
</AgentWorkDisclosure>
|
|
2632
|
+
);
|
|
2581
2633
|
}
|
|
2582
2634
|
const currentActivity = activelyWorking
|
|
2583
2635
|
? (latestRunningUsefulActivity?.activity ??
|
|
@@ -2619,13 +2671,6 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({
|
|
|
2619
2671
|
});
|
|
2620
2672
|
const steps = agentWorkSteps(workItems);
|
|
2621
2673
|
const hasExpandableActivity = steps.length > 0;
|
|
2622
|
-
const formatDuration = (ms: number) =>
|
|
2623
|
-
formatWorkedForDuration?.(ms) ??
|
|
2624
|
-
formatAgentKitDuration(ms, {
|
|
2625
|
-
hour: labels.durationHourShort,
|
|
2626
|
-
minute: labels.durationMinuteShort,
|
|
2627
|
-
second: labels.durationSecondShort,
|
|
2628
|
-
});
|
|
2629
2674
|
const failedCount = steps.reduce((sum, step) => sum + step.failedCount, 0);
|
|
2630
2675
|
const reasoningMessageIds = activityItems.flatMap((activity) => {
|
|
2631
2676
|
const entry = reasoningEntries.get(activity.id);
|
|
@@ -3351,7 +3396,8 @@ function AgentWorkDisclosure({
|
|
|
3351
3396
|
/>
|
|
3352
3397
|
) : undefined;
|
|
3353
3398
|
// The row stays one mounted trigger from "Thinking" through the first
|
|
3354
|
-
// activity, so it never flickers; until then it is not a tab stop.
|
|
3399
|
+
// activity, so it never flickers; until then it is not a tab stop. Finished
|
|
3400
|
+
// work with nothing to expand is text, not a disabled button.
|
|
3355
3401
|
const disclosure = (
|
|
3356
3402
|
<div
|
|
3357
3403
|
ref={handoff.inPlaceRef}
|
|
@@ -3362,6 +3408,7 @@ function AgentWorkDisclosure({
|
|
|
3362
3408
|
data-handoff={handoff.leavingHeight ? "enter" : undefined}
|
|
3363
3409
|
>
|
|
3364
3410
|
<AgentKitDisclosureSummary
|
|
3411
|
+
as={expandable || running ? "button" : "static"}
|
|
3365
3412
|
className="agentkit-activities-summary"
|
|
3366
3413
|
rowClassName="agentkit-activities-row"
|
|
3367
3414
|
open={open}
|
|
@@ -4826,6 +4873,21 @@ function messageMetadataString(
|
|
|
4826
4873
|
return undefined;
|
|
4827
4874
|
}
|
|
4828
4875
|
|
|
4876
|
+
/** The model a reply, or the request before it, was sent with. */
|
|
4877
|
+
function selectedRunModel(
|
|
4878
|
+
messages: readonly AgentMessage[],
|
|
4879
|
+
messageId: string | undefined,
|
|
4880
|
+
): string | undefined {
|
|
4881
|
+
if (!messageId) return undefined;
|
|
4882
|
+
return (
|
|
4883
|
+
messageMetadataString(
|
|
4884
|
+
agentMessagesById(messages).get(messageId)?.message,
|
|
4885
|
+
"model",
|
|
4886
|
+
) ??
|
|
4887
|
+
messageMetadataString(findPreviousUserMessage(messages, messageId), "model")
|
|
4888
|
+
);
|
|
4889
|
+
}
|
|
4890
|
+
|
|
4829
4891
|
/**
|
|
4830
4892
|
* A finished reply's footer offers a host under its message id, and the
|
|
4831
4893
|
* reply's work row portals into it so it shares the line with the controls.
|
|
@@ -5024,17 +5086,9 @@ function AgentRunDetails({
|
|
|
5024
5086
|
toolIds.add(event.activity.id);
|
|
5025
5087
|
}
|
|
5026
5088
|
}
|
|
5027
|
-
const reply = messageId
|
|
5028
|
-
? agentMessagesById(thread.messages).get(messageId)?.message
|
|
5029
|
-
: undefined;
|
|
5030
|
-
const request = messageId
|
|
5031
|
-
? findPreviousUserMessage(thread.messages, messageId)
|
|
5032
|
-
: undefined;
|
|
5033
5089
|
return {
|
|
5034
5090
|
toolCalls: toolIds.size,
|
|
5035
|
-
model:
|
|
5036
|
-
messageMetadataString(reply, "model") ??
|
|
5037
|
-
messageMetadataString(request, "model"),
|
|
5091
|
+
model: selectedRunModel(thread.messages, messageId),
|
|
5038
5092
|
};
|
|
5039
5093
|
},
|
|
5040
5094
|
(previous, next) =>
|
|
@@ -5065,10 +5119,11 @@ function AgentRunDetails({
|
|
|
5065
5119
|
if (billing.incomplete) {
|
|
5066
5120
|
return { key: labels.runCreditsUsed, value: labels.runDetailIncomplete };
|
|
5067
5121
|
}
|
|
5068
|
-
//
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5122
|
+
// Zero credits give way to a provider charge, which is the real cost.
|
|
5123
|
+
if (
|
|
5124
|
+
billing.builderCredits !== null &&
|
|
5125
|
+
(billing.builderCredits !== 0 || !billing.providerCostUsd)
|
|
5126
|
+
) {
|
|
5072
5127
|
return {
|
|
5073
5128
|
key: labels.runCreditsUsed,
|
|
5074
5129
|
value: formatRunUsageAmount(
|
|
@@ -5079,9 +5134,9 @@ function AgentRunDetails({
|
|
|
5079
5134
|
billing.builderCreditsSource,
|
|
5080
5135
|
labels,
|
|
5081
5136
|
),
|
|
5137
|
+
measuredZero: billing.builderCredits === 0,
|
|
5082
5138
|
};
|
|
5083
5139
|
}
|
|
5084
|
-
if (billing.providerCostUsd === 0) return null;
|
|
5085
5140
|
if (billing.providerCostUsd !== null) {
|
|
5086
5141
|
const usd = billing.providerCostUsd;
|
|
5087
5142
|
return {
|
|
@@ -5098,6 +5153,7 @@ function AgentRunDetails({
|
|
|
5098
5153
|
billing.providerCostSource,
|
|
5099
5154
|
labels,
|
|
5100
5155
|
),
|
|
5156
|
+
measuredZero: usd === 0,
|
|
5101
5157
|
};
|
|
5102
5158
|
}
|
|
5103
5159
|
return { key: labels.runCreditsUsed, value: labels.runDetailNotRecorded };
|
|
@@ -5110,7 +5166,6 @@ function AgentRunDetails({
|
|
|
5110
5166
|
details.model;
|
|
5111
5167
|
const model = reportedModel === "auto" ? undefined : reportedModel;
|
|
5112
5168
|
const rows: { id: string; key: string; value: ReactNode }[] = [
|
|
5113
|
-
...(credits ? [{ id: "credits", ...credits }] : []),
|
|
5114
5169
|
...(details.toolCalls > 0
|
|
5115
5170
|
? [
|
|
5116
5171
|
{
|
|
@@ -5130,6 +5185,12 @@ function AgentRunDetails({
|
|
|
5130
5185
|
]
|
|
5131
5186
|
: []),
|
|
5132
5187
|
];
|
|
5188
|
+
// A measured zero has nothing to tell beside other details; a missing or
|
|
5189
|
+
// failed reading always shows, so it is never mistaken for a free run. Alone,
|
|
5190
|
+
// the zero still shows, so a row that opened to its details is never empty.
|
|
5191
|
+
if (credits && (!credits.measuredZero || rows.length === 0)) {
|
|
5192
|
+
rows.unshift({ id: "credits", key: credits.key, value: credits.value });
|
|
5193
|
+
}
|
|
5133
5194
|
if (rows.length === 0) return null;
|
|
5134
5195
|
return (
|
|
5135
5196
|
<dl
|
|
@@ -5221,6 +5282,42 @@ function AgentMessageTimestamp({
|
|
|
5221
5282
|
);
|
|
5222
5283
|
}
|
|
5223
5284
|
|
|
5285
|
+
/**
|
|
5286
|
+
* Names an icon-only message action on hover and keyboard focus. Below the
|
|
5287
|
+
* button, so it never covers the message it acts on.
|
|
5288
|
+
*/
|
|
5289
|
+
function MessageActionButton({
|
|
5290
|
+
title,
|
|
5291
|
+
...props
|
|
5292
|
+
}: ComponentPropsWithoutRef<typeof IconButton>) {
|
|
5293
|
+
// A disabled button gets no pointer events, so only a native title can
|
|
5294
|
+
// explain it; an enabled one shows the reason in its tooltip instead, so a
|
|
5295
|
+
// degraded action never opens both.
|
|
5296
|
+
const inactive = Boolean(props.disabled || props.pending);
|
|
5297
|
+
const reason = inactive ? undefined : title;
|
|
5298
|
+
return (
|
|
5299
|
+
<Tooltip
|
|
5300
|
+
content={
|
|
5301
|
+
reason ? (
|
|
5302
|
+
<>
|
|
5303
|
+
{props.label}
|
|
5304
|
+
<span className="block text-muted-foreground">{reason}</span>
|
|
5305
|
+
</>
|
|
5306
|
+
) : (
|
|
5307
|
+
props.label
|
|
5308
|
+
)
|
|
5309
|
+
}
|
|
5310
|
+
placement="bottom"
|
|
5311
|
+
trigger={
|
|
5312
|
+
<IconButton
|
|
5313
|
+
{...props}
|
|
5314
|
+
{...(inactive && title !== undefined ? { title } : {})}
|
|
5315
|
+
/>
|
|
5316
|
+
}
|
|
5317
|
+
/>
|
|
5318
|
+
);
|
|
5319
|
+
}
|
|
5320
|
+
|
|
5224
5321
|
export const AgentMessageActions = memo(function AgentMessageActions({
|
|
5225
5322
|
value: message,
|
|
5226
5323
|
threadId,
|
|
@@ -5434,7 +5531,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5434
5531
|
regenerateAction.error;
|
|
5435
5532
|
const placement = isAssistant ? "inline" : undefined;
|
|
5436
5533
|
const copyButton = (
|
|
5437
|
-
<
|
|
5534
|
+
<MessageActionButton
|
|
5438
5535
|
label={copied ? labels.copied : labels.copy}
|
|
5439
5536
|
icon={
|
|
5440
5537
|
copied ? (
|
|
@@ -5458,7 +5555,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5458
5555
|
.replace("{{index}}", String(branchNavigation.index))
|
|
5459
5556
|
.replace("{{count}}", String(branchNavigation.count))}
|
|
5460
5557
|
>
|
|
5461
|
-
<
|
|
5558
|
+
<MessageActionButton
|
|
5462
5559
|
label={labels.previousBranch}
|
|
5463
5560
|
icon={<IconChevronLeft aria-hidden="true" />}
|
|
5464
5561
|
size="compact"
|
|
@@ -5483,7 +5580,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5483
5580
|
.replace("{{index}}", String(branchNavigation.index))
|
|
5484
5581
|
.replace("{{count}}", String(branchNavigation.count))}
|
|
5485
5582
|
</span>
|
|
5486
|
-
<
|
|
5583
|
+
<MessageActionButton
|
|
5487
5584
|
label={labels.nextBranch}
|
|
5488
5585
|
icon={<IconChevronRight aria-hidden="true" />}
|
|
5489
5586
|
size="compact"
|
|
@@ -5543,7 +5640,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5543
5640
|
? (["positive", "negative"] as const).map((value) => {
|
|
5544
5641
|
const chosen = feedback === value;
|
|
5545
5642
|
return (
|
|
5546
|
-
<
|
|
5643
|
+
<MessageActionButton
|
|
5547
5644
|
key={value}
|
|
5548
5645
|
label={
|
|
5549
5646
|
value === "positive"
|
|
@@ -5589,7 +5686,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5589
5686
|
inert={!moreActionsOpen}
|
|
5590
5687
|
>
|
|
5591
5688
|
{showRetry ? (
|
|
5592
|
-
<
|
|
5689
|
+
<MessageActionButton
|
|
5593
5690
|
label={labels.regenerateResponse}
|
|
5594
5691
|
icon={<IconRefresh aria-hidden="true" />}
|
|
5595
5692
|
size="compact"
|
|
@@ -5601,14 +5698,16 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5601
5698
|
position.active ||
|
|
5602
5699
|
!forkingCapability.enabled
|
|
5603
5700
|
}
|
|
5604
|
-
|
|
5701
|
+
{...(forkingCapability.reason === undefined
|
|
5702
|
+
? {}
|
|
5703
|
+
: { title: forkingCapability.reason })}
|
|
5605
5704
|
onPress={() =>
|
|
5606
5705
|
void regenerateAction.execute().catch(() => undefined)
|
|
5607
5706
|
}
|
|
5608
5707
|
/>
|
|
5609
5708
|
) : null}
|
|
5610
5709
|
{showFork ? (
|
|
5611
|
-
<
|
|
5710
|
+
<MessageActionButton
|
|
5612
5711
|
label={labels.forkFromHere}
|
|
5613
5712
|
icon={<IconArrowFork aria-hidden="true" />}
|
|
5614
5713
|
size="compact"
|
|
@@ -5623,7 +5722,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5623
5722
|
/>
|
|
5624
5723
|
) : null}
|
|
5625
5724
|
{requestId ? (
|
|
5626
|
-
<
|
|
5725
|
+
<MessageActionButton
|
|
5627
5726
|
label={requestIdCopied ? labels.copied : labels.copyRequestId}
|
|
5628
5727
|
icon={
|
|
5629
5728
|
requestIdCopied ? (
|
|
@@ -5645,7 +5744,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5645
5744
|
) : null}
|
|
5646
5745
|
</div>
|
|
5647
5746
|
{hasSecondaryActions ? (
|
|
5648
|
-
<
|
|
5747
|
+
<MessageActionButton
|
|
5649
5748
|
elementRef={moreToggleRef}
|
|
5650
5749
|
label={labels.moreMessageActions}
|
|
5651
5750
|
icon={<IconDots aria-hidden="true" />}
|
|
@@ -5696,13 +5795,15 @@ export const AgentMessageActions = memo(function AgentMessageActions({
|
|
|
5696
5795
|
message.metadata?.pendingSubmission !== true &&
|
|
5697
5796
|
forkingCapability.visible &&
|
|
5698
5797
|
text.trim() ? (
|
|
5699
|
-
<
|
|
5798
|
+
<MessageActionButton
|
|
5700
5799
|
label={labels.editMessage}
|
|
5701
5800
|
icon={<IconPencil aria-hidden="true" />}
|
|
5702
5801
|
size="compact"
|
|
5703
5802
|
className="size-6"
|
|
5704
5803
|
disabled={position.active || !forkingCapability.enabled}
|
|
5705
|
-
|
|
5804
|
+
{...(forkingCapability.reason === undefined
|
|
5805
|
+
? {}
|
|
5806
|
+
: { title: forkingCapability.reason })}
|
|
5706
5807
|
aria-pressed={editContext.message?.id === message.id}
|
|
5707
5808
|
onPress={() => editContext.setMessage(message)}
|
|
5708
5809
|
/>
|
|
@@ -6069,6 +6170,7 @@ export interface AgentKitComposerProps extends Omit<
|
|
|
6069
6170
|
| "onSlashCommand"
|
|
6070
6171
|
| "plusMenuMode"
|
|
6071
6172
|
| "voiceEnabled"
|
|
6173
|
+
| "onVoiceChatStart"
|
|
6072
6174
|
| "autoFocus"
|
|
6073
6175
|
| "disabled"
|
|
6074
6176
|
| "isReferenceTarget"
|
|
@@ -6096,6 +6198,7 @@ export interface AgentKitComposerProps extends Omit<
|
|
|
6096
6198
|
| "modelStatusChecksEnabled"
|
|
6097
6199
|
| "showMissingApiKeySetup"
|
|
6098
6200
|
| "setupCardVisible"
|
|
6201
|
+
| "onModelConnectionRequiredChange"
|
|
6099
6202
|
| "contextUsageSlot"
|
|
6100
6203
|
| "attachmentsEnabled"
|
|
6101
6204
|
| "onAttachmentRequest"
|
|
@@ -6167,6 +6270,7 @@ export function AgentKitComposer({
|
|
|
6167
6270
|
onSlashCommand,
|
|
6168
6271
|
plusMenuMode,
|
|
6169
6272
|
voiceEnabled = false,
|
|
6273
|
+
onVoiceChatStart,
|
|
6170
6274
|
autoFocus = true,
|
|
6171
6275
|
toolbarSlot,
|
|
6172
6276
|
disabled,
|
|
@@ -6196,6 +6300,7 @@ export function AgentKitComposer({
|
|
|
6196
6300
|
requireAgentEngine = false,
|
|
6197
6301
|
showMissingApiKeySetup,
|
|
6198
6302
|
setupCardVisible,
|
|
6303
|
+
onModelConnectionRequiredChange,
|
|
6199
6304
|
contextUsageSlot,
|
|
6200
6305
|
attachmentsEnabled,
|
|
6201
6306
|
onAttachmentRequest,
|
|
@@ -6215,7 +6320,10 @@ export function AgentKitComposer({
|
|
|
6215
6320
|
onRetryContextItem,
|
|
6216
6321
|
contextMenuItems,
|
|
6217
6322
|
attachmentAdapter,
|
|
6218
|
-
|
|
6323
|
+
// AgentKit always uploads attached files and the server reads their text,
|
|
6324
|
+
// so also pasting a text file into the message sends it twice: the copy
|
|
6325
|
+
// here has only a weak truncation note and a read failure here is silent.
|
|
6326
|
+
inlineTextAttachments = false,
|
|
6219
6327
|
beforeSend,
|
|
6220
6328
|
}: AgentKitComposerProps) {
|
|
6221
6329
|
const {
|
|
@@ -6327,13 +6435,14 @@ export function AgentKitComposer({
|
|
|
6327
6435
|
};
|
|
6328
6436
|
}, []);
|
|
6329
6437
|
const [attachmentError, setAttachmentError] = useState<string | null>(null);
|
|
6438
|
+
const composerTranslate = useComposerRuntimeAdapters().translate;
|
|
6330
6439
|
useEffect(() => {
|
|
6331
6440
|
setAttachmentError(null);
|
|
6332
6441
|
setStopError(null);
|
|
6333
6442
|
}, [threadId]);
|
|
6334
6443
|
const composerAttachmentAdapter = useMemo(
|
|
6335
|
-
() => attachmentAdapter ?? createChatAttachmentAdapter(),
|
|
6336
|
-
[attachmentAdapter],
|
|
6444
|
+
() => attachmentAdapter ?? createChatAttachmentAdapter(composerTranslate),
|
|
6445
|
+
[attachmentAdapter, composerTranslate],
|
|
6337
6446
|
);
|
|
6338
6447
|
const starting = useAgentKitSubmissionStarting(threadId);
|
|
6339
6448
|
const active = hasActiveRuns(thread) || starting;
|
|
@@ -6423,7 +6532,7 @@ export function AgentKitComposer({
|
|
|
6423
6532
|
<div
|
|
6424
6533
|
role="group"
|
|
6425
6534
|
aria-labelledby={editingLabelId}
|
|
6426
|
-
className="agentkit-editing-row flex h-6 min-w-0 items-center gap-
|
|
6535
|
+
className="agentkit-editing-row flex h-6 min-w-0 items-center gap-2 text-xs text-muted-foreground"
|
|
6427
6536
|
data-agentkit-editing-row="true"
|
|
6428
6537
|
>
|
|
6429
6538
|
<Tooltip
|
|
@@ -6432,7 +6541,7 @@ export function AgentKitComposer({
|
|
|
6432
6541
|
trigger={
|
|
6433
6542
|
<span
|
|
6434
6543
|
tabIndex={0}
|
|
6435
|
-
className="inline-flex min-w-0 items-center gap-
|
|
6544
|
+
className="inline-flex min-w-0 items-center gap-2 rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
6436
6545
|
>
|
|
6437
6546
|
<IconPencil aria-hidden="true" className="size-4 shrink-0" />
|
|
6438
6547
|
<span id={editingLabelId} className="truncate">
|
|
@@ -6910,6 +7019,7 @@ export function AgentKitComposer({
|
|
|
6910
7019
|
requireAgentEngine,
|
|
6911
7020
|
showMissingApiKeySetup,
|
|
6912
7021
|
setupCardVisible,
|
|
7022
|
+
onModelConnectionRequiredChange,
|
|
6913
7023
|
contextUsageSlot,
|
|
6914
7024
|
layoutVariant,
|
|
6915
7025
|
toolbarSlot,
|
|
@@ -6923,6 +7033,7 @@ export function AgentKitComposer({
|
|
|
6923
7033
|
slashSkills,
|
|
6924
7034
|
onSlashCommand,
|
|
6925
7035
|
voiceEnabled,
|
|
7036
|
+
onVoiceChatStart,
|
|
6926
7037
|
replyPlaceholder: placeholder ?? labels.composerReplyPlaceholder,
|
|
6927
7038
|
onEscape: editingMessage ? cancelEditing : undefined,
|
|
6928
7039
|
initialText: composerInitialText,
|
|
@@ -8295,6 +8406,7 @@ export function AgentKitChat({
|
|
|
8295
8406
|
throughSequence,
|
|
8296
8407
|
messageId,
|
|
8297
8408
|
foldedReasoningMessageId,
|
|
8409
|
+
summarizesTurn,
|
|
8298
8410
|
}: {
|
|
8299
8411
|
runId: RunId;
|
|
8300
8412
|
anchor: string;
|
|
@@ -8302,6 +8414,7 @@ export function AgentKitChat({
|
|
|
8302
8414
|
throughSequence?: number | undefined;
|
|
8303
8415
|
messageId?: string | undefined;
|
|
8304
8416
|
foldedReasoningMessageId?: string | undefined;
|
|
8417
|
+
summarizesTurn?: boolean | undefined;
|
|
8305
8418
|
}) => {
|
|
8306
8419
|
const key = `run-work:${threadId}:${runId}:${anchor}`;
|
|
8307
8420
|
const resetKey = `${anchor}:${runRevision(runId)}`;
|
|
@@ -8313,6 +8426,7 @@ export function AgentKitChat({
|
|
|
8313
8426
|
throughSequence,
|
|
8314
8427
|
messageId,
|
|
8315
8428
|
foldedReasoningMessageId,
|
|
8429
|
+
summarizesTurn,
|
|
8316
8430
|
],
|
|
8317
8431
|
() =>
|
|
8318
8432
|
renderRunWorkElement({
|
|
@@ -8323,6 +8437,7 @@ export function AgentKitChat({
|
|
|
8323
8437
|
throughSequence,
|
|
8324
8438
|
messageId,
|
|
8325
8439
|
foldedReasoningMessageId,
|
|
8440
|
+
summarizesTurn,
|
|
8326
8441
|
}),
|
|
8327
8442
|
);
|
|
8328
8443
|
};
|
|
@@ -8334,6 +8449,7 @@ export function AgentKitChat({
|
|
|
8334
8449
|
throughSequence,
|
|
8335
8450
|
messageId,
|
|
8336
8451
|
foldedReasoningMessageId,
|
|
8452
|
+
summarizesTurn,
|
|
8337
8453
|
}: {
|
|
8338
8454
|
key: string;
|
|
8339
8455
|
resetKey: string;
|
|
@@ -8342,6 +8458,7 @@ export function AgentKitChat({
|
|
|
8342
8458
|
throughSequence?: number | undefined;
|
|
8343
8459
|
messageId?: string | undefined;
|
|
8344
8460
|
foldedReasoningMessageId?: string | undefined;
|
|
8461
|
+
summarizesTurn?: boolean | undefined;
|
|
8345
8462
|
}) => (
|
|
8346
8463
|
<AgentKitSurfaceBoundary key={key} surface="activity" resetKey={resetKey}>
|
|
8347
8464
|
<AgentCollaborationFeed
|
|
@@ -8362,6 +8479,7 @@ export function AgentKitChat({
|
|
|
8362
8479
|
isCurrentSegment={throughSequence === undefined}
|
|
8363
8480
|
messageId={messageId}
|
|
8364
8481
|
foldedReasoningMessageId={foldedReasoningMessageId}
|
|
8482
|
+
summarizesTurn={summarizesTurn}
|
|
8365
8483
|
/>
|
|
8366
8484
|
</AgentKitSurfaceBoundary>
|
|
8367
8485
|
);
|
|
@@ -8535,10 +8653,21 @@ export function AgentKitChat({
|
|
|
8535
8653
|
isAssistantBoundary && runId
|
|
8536
8654
|
? previousSegmentEndByRun.get(runId)
|
|
8537
8655
|
: undefined;
|
|
8656
|
+
// A turn that only answered still gets one "Worked for" row: it is the
|
|
8657
|
+
// run's only reply, nothing ran after it, and it shows no reasoning row.
|
|
8658
|
+
const summarizesTurn = Boolean(
|
|
8659
|
+
isAssistantBoundary &&
|
|
8660
|
+
runId &&
|
|
8661
|
+
previousAssistant === undefined &&
|
|
8662
|
+
lastAssistantMessagesByRun.get(runId)?.id === message.id &&
|
|
8663
|
+
!hasRunWork(runId, sequence) &&
|
|
8664
|
+
!hasVisibleReasoning(message),
|
|
8665
|
+
);
|
|
8538
8666
|
const rendersRunWork = Boolean(
|
|
8539
8667
|
isAssistantBoundary &&
|
|
8540
8668
|
runId &&
|
|
8541
|
-
|
|
8669
|
+
(summarizesTurn ||
|
|
8670
|
+
hasRunWork(runId, previousAssistant?.sequence, sequence)),
|
|
8542
8671
|
);
|
|
8543
8672
|
// A saved reply's reasoning before its answer joins the work group above
|
|
8544
8673
|
// it, so the turn shows one disclosure; the stream did not place it there.
|
|
@@ -8556,6 +8685,7 @@ export function AgentKitChat({
|
|
|
8556
8685
|
throughSequence: sequence,
|
|
8557
8686
|
messageId: message.id,
|
|
8558
8687
|
foldedReasoningMessageId: foldsReasoning ? message.id : undefined,
|
|
8688
|
+
summarizesTurn,
|
|
8559
8689
|
}),
|
|
8560
8690
|
);
|
|
8561
8691
|
}
|
|
@@ -247,6 +247,9 @@ describe("AgentKit composer context submission", () => {
|
|
|
247
247
|
),
|
|
248
248
|
);
|
|
249
249
|
expect(capture.props?.contextMenuItems).toBe(contextMenuItems);
|
|
250
|
+
// Files are uploaded and read by the server; inlining them too would send
|
|
251
|
+
// each text file twice.
|
|
252
|
+
expect(capture.props?.inlineTextAttachments).toBe(false);
|
|
250
253
|
expect(
|
|
251
254
|
capture.props?.contextMenuItems?.[0].picker?.onSelect,
|
|
252
255
|
).toBeUndefined();
|
|
@@ -904,3 +904,127 @@ describe("work before a message sent into the running turn", () => {
|
|
|
904
904
|
).toBeTruthy();
|
|
905
905
|
});
|
|
906
906
|
});
|
|
907
|
+
|
|
908
|
+
describe("a turn that only answered", () => {
|
|
909
|
+
const reply: AgentMessage = {
|
|
910
|
+
...answer([{ type: "text", text: "Answer." }]),
|
|
911
|
+
metadata: { model: "claude-sonnet-5-5" },
|
|
912
|
+
};
|
|
913
|
+
// Production runs report this before the model answers; it is not work.
|
|
914
|
+
const startingAgent = {
|
|
915
|
+
type: "activity.started" as const,
|
|
916
|
+
occurredAt: at(100),
|
|
917
|
+
activity: {
|
|
918
|
+
id: `agentkit:internal:${RUN}:starting-agent`,
|
|
919
|
+
kind: "model",
|
|
920
|
+
label: "Starting agent",
|
|
921
|
+
status: "running" as const,
|
|
922
|
+
},
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
function answeredAt(
|
|
926
|
+
ms: number,
|
|
927
|
+
work: Array<Omit<AgentEvent, "id" | "threadId" | "runId" | "sequence">>,
|
|
928
|
+
finished = true,
|
|
929
|
+
): AgentEvent[] {
|
|
930
|
+
return [
|
|
931
|
+
{ type: "run.started", occurredAt: at(0) },
|
|
932
|
+
...work,
|
|
933
|
+
{ type: "message.completed", occurredAt: at(ms), message: reply },
|
|
934
|
+
...(finished
|
|
935
|
+
? [{ type: "run.completed", occurredAt: at(ms + 500) }]
|
|
936
|
+
: []),
|
|
937
|
+
].map(
|
|
938
|
+
(event, index) =>
|
|
939
|
+
({
|
|
940
|
+
...event,
|
|
941
|
+
id: `event-${index}`,
|
|
942
|
+
threadId: THREAD,
|
|
943
|
+
runId: RUN,
|
|
944
|
+
sequence: index + 1,
|
|
945
|
+
}) as AgentEvent,
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
it("shows a Worked for row under its reply that opens to the run details", async () => {
|
|
950
|
+
for (const work of [[startingAgent], []]) {
|
|
951
|
+
const container = await renderThread(
|
|
952
|
+
[user, reply],
|
|
953
|
+
answeredAt(4_000, work),
|
|
954
|
+
);
|
|
955
|
+
const rows = container.querySelectorAll<HTMLElement>(
|
|
956
|
+
".agentkit-activities",
|
|
957
|
+
);
|
|
958
|
+
expect(rows).toHaveLength(1);
|
|
959
|
+
const row = rows[0]!;
|
|
960
|
+
expect(
|
|
961
|
+
row.querySelector(".agentkit-activities-summary")?.textContent,
|
|
962
|
+
).toBe("Worked for 4s");
|
|
963
|
+
expect(row.closest(".agentkit-message-actions")).not.toBeNull();
|
|
964
|
+
const trigger = row.querySelector<HTMLElement>(
|
|
965
|
+
".agentkit-disclosure-summary",
|
|
966
|
+
);
|
|
967
|
+
expectSharedSummary(trigger);
|
|
968
|
+
await click(trigger);
|
|
969
|
+
expect(row.dataset.open).toBe("true");
|
|
970
|
+
expect(row.querySelector(".agentkit-run-details")?.textContent).toContain(
|
|
971
|
+
"claude-sonnet-5-5",
|
|
972
|
+
);
|
|
973
|
+
expect(row.querySelector(".agentkit-work-steps")).toBeNull();
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
|
|
977
|
+
it("shows text when the run has no details to open to", async () => {
|
|
978
|
+
const unnamed: AgentMessage = { ...reply, metadata: {} };
|
|
979
|
+
const container = await renderThread(
|
|
980
|
+
[user, unnamed],
|
|
981
|
+
answeredAt(4_000, [startingAgent]).map((event) =>
|
|
982
|
+
event.type === "message.completed"
|
|
983
|
+
? { ...event, message: unnamed }
|
|
984
|
+
: event,
|
|
985
|
+
),
|
|
986
|
+
);
|
|
987
|
+
const row = container.querySelector<HTMLElement>(".agentkit-activities");
|
|
988
|
+
expect(row?.dataset.expandable).toBe("false");
|
|
989
|
+
expect(
|
|
990
|
+
row?.querySelector(".agentkit-activities-summary")?.textContent,
|
|
991
|
+
).toBe("Worked for 4s");
|
|
992
|
+
expect(row?.querySelector("button")).toBeNull();
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
it("shows no row under a second, untimed, or still running", async () => {
|
|
996
|
+
const instant = await renderThread(
|
|
997
|
+
[user, reply],
|
|
998
|
+
answeredAt(600, [startingAgent]),
|
|
999
|
+
);
|
|
1000
|
+
expect(instant.querySelector(".agentkit-activities")).toBeNull();
|
|
1001
|
+
|
|
1002
|
+
const streaming = await renderThread(
|
|
1003
|
+
[user, { ...reply, status: "streaming" }],
|
|
1004
|
+
answeredAt(4_000, [startingAgent], false),
|
|
1005
|
+
);
|
|
1006
|
+
expect(streaming.querySelector(".agentkit-activities")).toBeNull();
|
|
1007
|
+
|
|
1008
|
+
// A reloaded thread has no run timing.
|
|
1009
|
+
const reloaded = await renderThread([user, reply], []);
|
|
1010
|
+
expect(reloaded.querySelector(".agentkit-activities")).toBeNull();
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
it("keeps one expandable row for a turn with activity", async () => {
|
|
1014
|
+
const container = await renderThread(
|
|
1015
|
+
[user, reply],
|
|
1016
|
+
answeredAt(4_000, [startingAgent, ...activityEvents(1)]),
|
|
1017
|
+
);
|
|
1018
|
+
const rows = container.querySelectorAll<HTMLElement>(
|
|
1019
|
+
".agentkit-activities",
|
|
1020
|
+
);
|
|
1021
|
+
expect(rows).toHaveLength(1);
|
|
1022
|
+
expect(rows[0]!.dataset.expandable).toBe("true");
|
|
1023
|
+
expectSharedSummary(
|
|
1024
|
+
rows[0]!.querySelector<HTMLElement>(".agentkit-disclosure-summary"),
|
|
1025
|
+
);
|
|
1026
|
+
expect(
|
|
1027
|
+
rows[0]!.querySelector(".agentkit-activities-summary")?.textContent,
|
|
1028
|
+
).toBe("Worked for 4s");
|
|
1029
|
+
});
|
|
1030
|
+
});
|