@agent-native/toolkit 0.228.0-nightly-20261111212500 → 0.228.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 +2 -0
- package/dist/app/agentkit/react/approval-card.d.ts.map +1 -1
- package/dist/app/agentkit/react/approval-card.js +5 -3
- package/dist/app/agentkit/react/approval-card.js.map +1 -1
- package/dist/app/agentkit/react/code-block.d.ts +32 -0
- package/dist/app/agentkit/react/code-block.d.ts.map +1 -0
- package/dist/app/agentkit/react/code-block.js +125 -0
- package/dist/app/agentkit/react/code-block.js.map +1 -0
- package/dist/app/agentkit/react/components.d.ts +33 -14
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +843 -168
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context-usage.d.ts +45 -0
- package/dist/app/agentkit/react/context-usage.d.ts.map +1 -0
- package/dist/app/agentkit/react/context-usage.js +93 -0
- package/dist/app/agentkit/react/context-usage.js.map +1 -0
- package/dist/app/agentkit/react/context.d.ts +42 -3
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +46 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/disclosure-content.d.ts +12 -0
- package/dist/app/agentkit/react/disclosure-content.d.ts.map +1 -0
- package/dist/app/agentkit/react/disclosure-content.js +33 -0
- package/dist/app/agentkit/react/disclosure-content.js.map +1 -0
- package/dist/app/agentkit/react/duration.d.ts +6 -0
- package/dist/app/agentkit/react/duration.d.ts.map +1 -0
- package/dist/app/agentkit/react/duration.js +21 -0
- package/dist/app/agentkit/react/duration.js.map +1 -0
- package/dist/app/agentkit/react/file-change.d.ts +33 -0
- package/dist/app/agentkit/react/file-change.d.ts.map +1 -0
- package/dist/app/agentkit/react/file-change.js +83 -0
- package/dist/app/agentkit/react/file-change.js.map +1 -0
- package/dist/app/agentkit/react/file-diff.d.ts +17 -0
- package/dist/app/agentkit/react/file-diff.d.ts.map +1 -0
- package/dist/app/agentkit/react/file-diff.js +94 -0
- package/dist/app/agentkit/react/file-diff.js.map +1 -0
- package/dist/app/agentkit/react/index.d.ts +7 -0
- package/dist/app/agentkit/react/index.d.ts.map +1 -1
- package/dist/app/agentkit/react/index.js +7 -0
- package/dist/app/agentkit/react/index.js.map +1 -1
- package/dist/app/agentkit/react/question-card.d.ts +67 -0
- package/dist/app/agentkit/react/question-card.d.ts.map +1 -0
- package/dist/app/agentkit/react/question-card.js +198 -0
- package/dist/app/agentkit/react/question-card.js.map +1 -0
- package/dist/app/agentkit/react/root.d.ts +3 -2
- package/dist/app/agentkit/react/root.d.ts.map +1 -1
- package/dist/app/agentkit/react/root.js +2 -2
- package/dist/app/agentkit/react/root.js.map +1 -1
- package/dist/app/agentkit/react/roving-focus.d.ts +4 -0
- package/dist/app/agentkit/react/roving-focus.d.ts.map +1 -0
- package/dist/app/agentkit/react/roving-focus.js +75 -0
- package/dist/app/agentkit/react/roving-focus.js.map +1 -0
- package/dist/app/agentkit/react/stack-trace.d.ts +34 -0
- package/dist/app/agentkit/react/stack-trace.d.ts.map +1 -0
- package/dist/app/agentkit/react/stack-trace.js +121 -0
- package/dist/app/agentkit/react/stack-trace.js.map +1 -0
- package/dist/app/agentkit/react/stop-button.d.ts.map +1 -1
- package/dist/app/agentkit/react/stop-button.js +22 -6
- package/dist/app/agentkit/react/stop-button.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +1306 -395
- package/dist/app/agentkit/react/terminal.d.ts +28 -0
- package/dist/app/agentkit/react/terminal.d.ts.map +1 -0
- package/dist/app/agentkit/react/terminal.js +84 -0
- package/dist/app/agentkit/react/terminal.js.map +1 -0
- package/dist/app/agentkit/react/trace.d.ts +31 -0
- package/dist/app/agentkit/react/trace.d.ts.map +1 -0
- package/dist/app/agentkit/react/trace.js +73 -0
- package/dist/app/agentkit/react/trace.js.map +1 -0
- package/dist/app/blocks/library/HighlightedCode.d.ts +2 -1
- package/dist/app/blocks/library/HighlightedCode.d.ts.map +1 -1
- package/dist/app/blocks/library/HighlightedCode.js +8 -111
- package/dist/app/blocks/library/HighlightedCode.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +23 -245
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +15 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +142 -2
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/history.js +1 -1
- package/dist/app/chat/agentkit-chat/history.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/agentkit-chat/labels.d.ts +5 -0
- package/dist/app/chat/agentkit-chat/labels.d.ts.map +1 -0
- package/dist/app/chat/agentkit-chat/labels.js +245 -0
- package/dist/app/chat/agentkit-chat/labels.js.map +1 -0
- package/dist/app/chat/agentkit-chat/questions.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/questions.js +1 -1
- package/dist/app/chat/agentkit-chat/questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/root.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/root.js +5 -64
- package/dist/app/chat/agentkit-chat/root.js.map +1 -1
- package/dist/app/chat/agentkit-chat/work-step-labels.d.ts +2 -0
- package/dist/app/chat/agentkit-chat/work-step-labels.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/work-step-labels.js +31 -0
- package/dist/app/chat/agentkit-chat/work-step-labels.js.map +1 -1
- package/dist/app/chat/chat/markdown-renderer.d.ts +2 -12
- package/dist/app/chat/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/app/chat/chat/markdown-renderer.js +2 -41
- package/dist/app/chat/chat/markdown-renderer.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +2 -2
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.js +2 -37
- package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
- package/dist/app/chat/tool-cells/BashCell.d.ts +3 -1
- package/dist/app/chat/tool-cells/BashCell.d.ts.map +1 -1
- package/dist/app/chat/tool-cells/BashCell.js +4 -40
- package/dist/app/chat/tool-cells/BashCell.js.map +1 -1
- package/dist/app/chat/tool-cells/EditCell.d.ts.map +1 -1
- package/dist/app/chat/tool-cells/EditCell.js +5 -108
- package/dist/app/chat/tool-cells/EditCell.js.map +1 -1
- package/dist/app/chat/tool-cells/FilesChangedSummary.d.ts.map +1 -1
- package/dist/app/chat/tool-cells/FilesChangedSummary.js +23 -81
- package/dist/app/chat/tool-cells/FilesChangedSummary.js.map +1 -1
- package/dist/app/chat/tool-cells/WriteCell.d.ts.map +1 -1
- package/dist/app/chat/tool-cells/WriteCell.js +5 -24
- package/dist/app/chat/tool-cells/WriteCell.js.map +1 -1
- package/dist/app/code-highlighter.d.ts +11 -0
- package/dist/app/code-highlighter.d.ts.map +1 -0
- package/dist/app/code-highlighter.js +122 -0
- package/dist/app/code-highlighter.js.map +1 -0
- package/dist/app/context-xray/ThreadContextRing.js +3 -3
- package/dist/app/context-xray/ThreadContextRing.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +22 -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 +22 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +22 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +22 -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 +22 -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 +22 -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 +22 -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 +22 -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 +22 -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 +22 -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 +22 -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 +22 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/onboarding/first-run-first-paint.d.ts +10 -0
- package/dist/app/onboarding/first-run-first-paint.d.ts.map +1 -0
- package/dist/app/onboarding/first-run-first-paint.js +22 -0
- package/dist/app/onboarding/first-run-first-paint.js.map +1 -0
- package/dist/app/onboarding/first-run-startup-gate.d.ts +3 -1
- package/dist/app/onboarding/first-run-startup-gate.d.ts.map +1 -1
- package/dist/app/onboarding/first-run-startup-gate.js +30 -6
- package/dist/app/onboarding/first-run-startup-gate.js.map +1 -1
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +9 -2
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/providers/BuilderSignupActivation.d.ts +2 -1
- package/dist/app/providers/BuilderSignupActivation.d.ts.map +1 -1
- package/dist/app/providers/BuilderSignupActivation.js +6 -3
- package/dist/app/providers/BuilderSignupActivation.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +11 -1
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/app/styles/agent-native.css +2 -2
- package/dist/app/styles/tokens/agent-kit.css +20 -3
- package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
- package/dist/composer/AgentSuggestionBar.js +2 -2
- package/dist/composer/AgentSuggestionBar.js.map +1 -1
- package/dist/composer/ComposerContextMenu.js +4 -4
- package/dist/composer/ComposerContextMenu.js.map +1 -1
- package/dist/composer/ComposerContextPicker.d.ts.map +1 -1
- package/dist/composer/ComposerContextPicker.js +2 -2
- package/dist/composer/ComposerContextPicker.js.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.d.ts.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.js +2 -2
- package/dist/composer/ComposerContextPickerDialog.js.map +1 -1
- package/dist/composer/ComposerModePicker.d.ts.map +1 -1
- package/dist/composer/ComposerModePicker.js +2 -1
- package/dist/composer/ComposerModePicker.js.map +1 -1
- package/dist/composer/ComposerPlusMenu.js +1 -1
- package/dist/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/composer/MentionChip.js +1 -1
- package/dist/composer/MentionChip.js.map +1 -1
- package/dist/composer/MentionPopover.d.ts +3 -0
- package/dist/composer/MentionPopover.d.ts.map +1 -1
- package/dist/composer/MentionPopover.js +34 -15
- package/dist/composer/MentionPopover.js.map +1 -1
- package/dist/composer/MessageQueueDrawer.d.ts.map +1 -1
- package/dist/composer/MessageQueueDrawer.js +14 -9
- package/dist/composer/MessageQueueDrawer.js.map +1 -1
- package/dist/composer/PastedTextChip.d.ts.map +1 -1
- package/dist/composer/PastedTextChip.js +14 -18
- package/dist/composer/PastedTextChip.js.map +1 -1
- package/dist/composer/PromptBar.js +1 -1
- package/dist/composer/PromptBar.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +11 -9
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/RealtimeVoiceMode.js +2 -2
- package/dist/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +52 -89
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts +3 -1
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +10 -8
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/composer-notice.js +3 -3
- package/dist/composer/composer-notice.js.map +1 -1
- package/dist/composer/extensions/FileReference.js +1 -1
- package/dist/composer/extensions/FileReference.js.map +1 -1
- package/dist/composer/extensions/SkillReference.js +1 -1
- package/dist/composer/extensions/SkillReference.js.map +1 -1
- package/dist/composer/popover-surface.d.ts +1 -1
- package/dist/composer/popover-surface.d.ts.map +1 -1
- package/dist/composer/popover-surface.js +1 -1
- package/dist/composer/popover-surface.js.map +1 -1
- package/dist/context-ui/ContextUsageRing.d.ts +1 -45
- package/dist/context-ui/ContextUsageRing.d.ts.map +1 -1
- package/dist/context-ui/ContextUsageRing.js +2 -87
- package/dist/context-ui/ContextUsageRing.js.map +1 -1
- package/dist/context-ui/index.d.ts +2 -2
- package/dist/context-ui/index.d.ts.map +1 -1
- package/dist/context-ui/index.js +2 -2
- package/dist/context-ui/index.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/approval-card.tsx +14 -2
- package/src/app/agentkit/react/code-block.spec.tsx +154 -0
- package/src/app/agentkit/react/code-block.tsx +317 -0
- package/src/app/agentkit/react/components.interaction.spec.tsx +7 -0
- package/src/app/agentkit/react/components.papercuts.spec.tsx +143 -2
- package/src/app/agentkit/react/components.spec.tsx +40 -47
- package/src/app/agentkit/react/components.tsx +1533 -413
- package/src/app/agentkit/react/composer-context.spec.tsx +35 -0
- package/src/app/agentkit/react/context-usage.tsx +353 -0
- package/src/app/agentkit/react/context.tsx +93 -1
- package/src/app/agentkit/react/disclosure-content.ts +42 -0
- package/src/app/agentkit/react/disclosures.spec.tsx +62 -4
- package/src/app/agentkit/react/duration.ts +22 -0
- package/src/app/agentkit/react/file-change.spec.tsx +124 -0
- package/src/app/agentkit/react/file-change.tsx +228 -0
- package/src/app/agentkit/react/file-diff.ts +110 -0
- package/src/app/agentkit/react/index.ts +7 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +565 -20
- package/src/app/agentkit/react/markdown.spec.tsx +18 -8
- package/src/app/agentkit/react/message-actions.spec.tsx +55 -1
- package/src/app/agentkit/react/notices.spec.tsx +4 -4
- package/src/app/agentkit/react/optimistic-send.spec.tsx +43 -0
- package/src/app/agentkit/react/question-card.spec.tsx +276 -0
- package/src/app/agentkit/react/question-card.tsx +533 -0
- package/src/app/agentkit/react/root.tsx +4 -0
- package/src/app/agentkit/react/roving-focus.spec.tsx +114 -0
- package/src/app/agentkit/react/roving-focus.ts +82 -0
- package/src/app/agentkit/react/stack-trace.spec.tsx +177 -0
- package/src/app/agentkit/react/stack-trace.tsx +281 -0
- package/src/app/agentkit/react/stop-button.spec.tsx +40 -0
- package/src/app/agentkit/react/stop-button.tsx +22 -5
- package/src/app/agentkit/react/styles.css +1306 -395
- package/src/app/agentkit/react/subagent-step.spec.tsx +554 -0
- package/src/app/agentkit/react/terminal.spec.tsx +228 -0
- package/src/app/agentkit/react/terminal.tsx +228 -0
- package/src/app/agentkit/react/trace.spec.tsx +120 -0
- package/src/app/agentkit/react/trace.tsx +239 -0
- package/src/app/blocks/library/HighlightedCode.tsx +14 -126
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +28 -12
- package/src/app/chat/AgentKitAssistantChat.tsx +27 -253
- package/src/app/chat/agentkit-chat/approval-card.spec.tsx +1 -0
- package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +381 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +236 -3
- package/src/app/chat/agentkit-chat/history.tsx +1 -1
- package/src/app/chat/agentkit-chat/index.ts +2 -0
- package/src/app/chat/agentkit-chat/labels.ts +259 -0
- package/src/app/chat/agentkit-chat/questions.ts +2 -0
- package/src/app/chat/agentkit-chat/root.spec.tsx +18 -0
- package/src/app/chat/agentkit-chat/root.tsx +5 -64
- package/src/app/chat/agentkit-chat/work-step-labels.ts +42 -0
- package/src/app/chat/chat/markdown-renderer.tsx +2 -59
- package/src/app/chat/chat/tool-call-display.spec.tsx +26 -14
- package/src/app/chat/chat/tool-call-display.tsx +2 -1
- package/src/app/chat/conversation/AgentConversation.tsx +2 -50
- package/src/app/chat/tool-cells/BashCell.tsx +14 -136
- package/src/app/chat/tool-cells/EditCell.tsx +11 -248
- package/src/app/chat/tool-cells/FilesChangedSummary.spec.tsx +62 -5
- package/src/app/chat/tool-cells/FilesChangedSummary.tsx +31 -162
- package/src/app/chat/tool-cells/WriteCell.tsx +11 -121
- package/src/app/code-highlighter.ts +131 -0
- package/src/app/context-xray/ThreadContextRing.tsx +7 -7
- package/src/app/i18n/catalogs/ar-SA.ts +22 -0
- package/src/app/i18n/catalogs/de-DE.ts +22 -0
- package/src/app/i18n/catalogs/en-US.ts +22 -0
- package/src/app/i18n/catalogs/es-ES.ts +22 -0
- package/src/app/i18n/catalogs/fr-FR.ts +22 -0
- package/src/app/i18n/catalogs/hi-IN.ts +22 -0
- package/src/app/i18n/catalogs/ja-JP.ts +22 -0
- package/src/app/i18n/catalogs/ko-KR.ts +22 -0
- package/src/app/i18n/catalogs/pt-BR.ts +22 -0
- package/src/app/i18n/catalogs/zh-CN.ts +22 -0
- package/src/app/i18n/catalogs/zh-TW.ts +22 -0
- package/src/app/onboarding/first-run-first-paint.spec.ts +39 -0
- package/src/app/onboarding/first-run-first-paint.ts +24 -0
- package/src/app/onboarding/first-run-startup-gate.spec.tsx +125 -13
- package/src/app/onboarding/first-run-startup-gate.tsx +48 -5
- package/src/app/providers/AppProviders.tsx +18 -0
- package/src/app/providers/BuilderSignupActivation.tsx +8 -2
- package/src/app/shared/AppShellSkeleton.spec.tsx +60 -1
- package/src/app/shared/AppShellSkeleton.tsx +31 -1
- package/src/app/styles/agent-native.css +2 -2
- package/src/app/styles/agent-native.spec.ts +2 -2
- package/src/app/styles/tokens/agent-kit.css +20 -3
- package/src/composer/AgentSuggestionBar.spec.tsx +3 -1
- package/src/composer/AgentSuggestionBar.tsx +5 -2
- package/src/composer/ComposerContextMenu.tsx +4 -4
- package/src/composer/ComposerContextPicker.tsx +8 -2
- package/src/composer/ComposerContextPickerDialog.tsx +5 -2
- package/src/composer/ComposerModePicker.tsx +2 -1
- package/src/composer/ComposerPlusMenu.tsx +1 -1
- package/src/composer/MentionChip.tsx +1 -1
- package/src/composer/MentionPopover.spec.tsx +108 -2
- package/src/composer/MentionPopover.tsx +93 -17
- package/src/composer/MessageQueueDrawer.spec.tsx +5 -5
- package/src/composer/MessageQueueDrawer.tsx +19 -12
- package/src/composer/PastedTextChip.spec.tsx +36 -0
- package/src/composer/PastedTextChip.tsx +52 -58
- package/src/composer/PromptBar.tsx +1 -1
- package/src/composer/PromptComposer.context.spec.tsx +2 -2
- package/src/composer/PromptComposer.submission.spec.tsx +27 -0
- package/src/composer/PromptComposer.tsx +17 -9
- package/src/composer/RealtimeVoiceMode.tsx +2 -2
- package/src/composer/TiptapComposer.model-picker.spec.tsx +23 -82
- package/src/composer/TiptapComposer.tsx +68 -145
- package/src/composer/VoiceButton.tsx +12 -7
- package/src/composer/composer-notice.tsx +3 -3
- package/src/composer/extensions/FileReference.tsx +1 -1
- package/src/composer/extensions/SkillReference.tsx +1 -1
- package/src/composer/popover-surface.ts +1 -1
- package/src/context-ui/ContextUsageRing.spec.tsx +33 -8
- package/src/context-ui/ContextUsageRing.tsx +13 -348
- package/src/context-ui/index.ts +7 -1
- package/dist/composer/ModelPickerParts.d.ts +0 -20
- package/dist/composer/ModelPickerParts.d.ts.map +0 -1
- package/dist/composer/ModelPickerParts.js +0 -77
- package/dist/composer/ModelPickerParts.js.map +0 -1
- package/src/composer/ModelPickerParts.tsx +0 -188
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { IconId, IconThumbUpFilled, IconThumbUp, IconThumbDownFilled, IconThumbDown, IconActivity,
|
|
2
|
+
import { IconId, IconThumbUpFilled, IconThumbUp, IconThumbDownFilled, IconThumbDown, IconActivity, IconAlertTriangle, IconArrowDown, IconArrowFork, IconBook2, IconBrain, IconChevronLeft, IconChevronRight, IconCircle, IconCircleCheck, IconClock, IconCode, IconCopy, IconDots, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconGitBranch, IconLoader2, IconMessage, IconMessageQuestion, IconPlugConnected, IconPlayerPause, IconPlayerPlay, IconPencil, IconRefresh, IconSearch, IconTerminal2, IconChecklist, IconBolt, IconPointFilled, IconTool, IconWorld, IconWorldDownload, IconX, } from "@tabler/icons-react";
|
|
3
3
|
import { createContext, createElement, Component, Fragment, isValidElement, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
|
|
4
4
|
import { createPortal } from "react-dom";
|
|
5
5
|
import ReactMarkdown from "react-markdown";
|
|
@@ -13,15 +13,25 @@ import { Skeleton } from "../../../ui/skeleton.js";
|
|
|
13
13
|
import { ApprovalCard, approvalOptionDecision, approvalRequestKind, } from "./approval-card.js";
|
|
14
14
|
import { createAgentKitComposerSubmission, snapshotComposerValue, } from "./composer-submission.js";
|
|
15
15
|
import { CoreFileStorageSetupContext } from "./core-file-storage.js";
|
|
16
|
+
import { AgentKitDeferClosedContentContext, useUntilFoundContent, } from "./disclosure-content.js";
|
|
16
17
|
import { splitAgentKitMessageContext } from "@agent-native/agentkit";
|
|
17
18
|
import { AgentKitCapabilityError, AgentKitUploadError, hasActiveAgentRuns, isCurrentAgentSuggestion, selectAgentSuggestions, } from "@agent-native/agentkit/client";
|
|
18
19
|
import { inferAgentActivityKind, } from "@agent-native/agentkit/protocol";
|
|
20
|
+
import { prettyLanguageName } from "../../code-highlighter.js";
|
|
21
|
+
import { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockTitle, } from "./code-block.js";
|
|
19
22
|
import { defaultAgentKitLabels, useAgentCapability, useAgentConnection, useAgentKit, useAgentKitBeginPendingSubmission, useAgentKitControl, useAgentKitMutation, useAgentKitPendingSubmissions, useAgentKitSelector, useAgentKitSubmissionStarting, useAgentThread, useAgentThreadLoadStatus, } from "./context.js";
|
|
23
|
+
import { formatAgentKitDuration } from "./duration.js";
|
|
24
|
+
import { FileChange } from "./file-change.js";
|
|
20
25
|
import { scheduleIdleMount } from "./idle-mount.js";
|
|
21
26
|
import { orderMessageContent } from "./message-content-order.js";
|
|
22
27
|
import { AGENTKIT_CLIENT_REQUEST_ID_METADATA_KEY, agentKitTurnInProgress, pendingSubmissionFiles, } from "./pending-submissions.js";
|
|
28
|
+
import { parseStackTrace, StackTrace } from "./stack-trace.js";
|
|
29
|
+
import { Terminal } from "./terminal.js";
|
|
30
|
+
export { formatAgentKitDuration };
|
|
31
|
+
import { useRovingFocus } from "./roving-focus.js";
|
|
23
32
|
import { useAgentKitStopButton } from "./stop-button.js";
|
|
24
33
|
import { AgentStreamingText, usePrefersReducedMotion, useStreamingRevealOrigin, } from "./streaming-text.js";
|
|
34
|
+
import { Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle, } from "./trace.js";
|
|
25
35
|
import { TranscriptGlide } from "./transcript-glide.js";
|
|
26
36
|
import { workedForRowChevronStyle, workedForRowSummaryStyle, } from "./transcript-layout.js";
|
|
27
37
|
import { registerChatThreadView } from "./viewed-threads.js";
|
|
@@ -93,7 +103,7 @@ function sameRenderedNode(previous, next) {
|
|
|
93
103
|
}
|
|
94
104
|
const AgentKitSurfaceBoundary = memo(function AgentKitSurfaceBoundary({ surface, resetKey, children, }) {
|
|
95
105
|
const { labels, onRenderError, threadId } = useAgentKit();
|
|
96
|
-
return (_jsx(AgentKitErrorBoundary, { resetKey: resetKey, fallback: _jsxs("div", { className: "agentkit-error", "data-render-surface": surface, role: "alert", children: [_jsx(
|
|
106
|
+
return (_jsx(AgentKitErrorBoundary, { resetKey: resetKey, fallback: _jsxs("div", { className: "agentkit-error", "data-render-surface": surface, role: "alert", children: [_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" }), _jsx("span", { children: labels.renderError })] }), onError: (error, info) => onRenderError?.({
|
|
97
107
|
error,
|
|
98
108
|
surface,
|
|
99
109
|
threadId,
|
|
@@ -157,14 +167,28 @@ function AgentLink({ href, children, }) {
|
|
|
157
167
|
const safeHref = safeAgentHref(href);
|
|
158
168
|
return safeHref ? (_jsx("a", { href: safeHref, ...agentLinkTargetProps(safeHref, origin), children: children })) : (_jsx("span", { children: children }));
|
|
159
169
|
}
|
|
160
|
-
function
|
|
170
|
+
function fencedCode(children) {
|
|
161
171
|
const code = Array.isArray(children) ? children[0] : children;
|
|
162
|
-
if (!
|
|
163
|
-
return undefined;
|
|
172
|
+
if (!isValidElement(code)) {
|
|
173
|
+
return { text: nodeText(children), language: undefined };
|
|
174
|
+
}
|
|
164
175
|
const className = code.props.className;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
176
|
+
return {
|
|
177
|
+
text: nodeText(code.props.children),
|
|
178
|
+
language: typeof className === "string"
|
|
179
|
+
? /(?:^|\s)language-([\w+#.-]+)/.exec(className)?.[1]
|
|
180
|
+
: undefined,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function nodeText(node) {
|
|
184
|
+
if (typeof node === "string" || typeof node === "number")
|
|
185
|
+
return `${node}`;
|
|
186
|
+
if (Array.isArray(node))
|
|
187
|
+
return node.map(nodeText).join("");
|
|
188
|
+
if (isValidElement(node)) {
|
|
189
|
+
return nodeText(node.props.children);
|
|
190
|
+
}
|
|
191
|
+
return "";
|
|
168
192
|
}
|
|
169
193
|
function AgentMarkdownCodeBlock({ children, node: _node, className, ...props }) {
|
|
170
194
|
// The header belongs to the block, so it fades in with the code.
|
|
@@ -174,34 +198,19 @@ function AgentMarkdownCodeBlock({ children, node: _node, className, ...props })
|
|
|
174
198
|
.filter((name) => name && name !== STREAMING_REVEAL_BLOCK_CLASS)
|
|
175
199
|
.join(" ") || undefined;
|
|
176
200
|
const { labels } = useAgentKit();
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const language = codeBlockLanguage(children);
|
|
185
|
-
const copy = async () => {
|
|
186
|
-
const text = preRef.current?.textContent ?? "";
|
|
187
|
-
if (!(await writeClipboardText(text)))
|
|
188
|
-
return;
|
|
189
|
-
setCopied(true);
|
|
190
|
-
if (copiedTimer.current)
|
|
191
|
-
clearTimeout(copiedTimer.current);
|
|
192
|
-
copiedTimer.current = setTimeout(() => setCopied(false), 2_000);
|
|
193
|
-
};
|
|
194
|
-
return (_jsxs("figure", { className: revealsAsBlock
|
|
195
|
-
? `agentkit-code-block ${STREAMING_REVEAL_BLOCK_CLASS}`
|
|
196
|
-
: "agentkit-code-block", children: [_jsxs("div", { className: "agentkit-code-block-header", children: [_jsx("span", { className: "agentkit-code-block-language", "aria-hidden": "true", children: language }), _jsx(IconButton, { label: copied ? labels.codeCopied : labels.copyCode, icon: copied ? (_jsx(IconCheck, { "aria-hidden": "true", size: 16 })) : (_jsx(IconCopy, { "aria-hidden": "true", size: 16 })), size: "compact", className: "size-6", onPress: () => void copy() })] }), _jsx("pre", { ...props, className: preClassName, ref: preRef, tabIndex: 0, role: "region", "aria-label": language
|
|
197
|
-
? labels.codeBlockLanguage.replace("{{language}}", () => language)
|
|
198
|
-
: labels.codeBlock, children: children })] }));
|
|
201
|
+
const { text, language } = fencedCode(children);
|
|
202
|
+
const languageName = prettyLanguageName(language);
|
|
203
|
+
return (_jsxs(CodeBlock, { className: revealsAsBlock ? STREAMING_REVEAL_BLOCK_CLASS : undefined, children: [_jsxs(CodeBlockHeader, { children: [_jsx(CodeBlockTitle, { "aria-hidden": "true", children: languageName }), _jsx(CodeBlockActions, { children: _jsx(CodeBlockCopyButton, { value: text }) })] }), _jsx(CodeBlockContent, { ...props, className: preClassName, language: language,
|
|
204
|
+
// A group, not a region: a landmark per code block buries the real ones.
|
|
205
|
+
role: "group", "aria-label": languageName
|
|
206
|
+
? labels.codeBlockLanguage.replace("{{language}}", () => languageName)
|
|
207
|
+
: labels.codeBlock, children: text })] }));
|
|
199
208
|
}
|
|
200
209
|
function AgentMarkdownTable({ node: _node, ...props }) {
|
|
201
210
|
const { labels } = useAgentKit();
|
|
202
211
|
const table = useRef(null);
|
|
203
212
|
useTableColumnGlide(table);
|
|
204
|
-
return (_jsx("div", { className: "agentkit-markdown-table", tabIndex: 0, role: "
|
|
213
|
+
return (_jsx("div", { className: "agentkit-markdown-table", tabIndex: 0, role: "group", "aria-label": labels.table, children: _jsx("table", { ref: table, ...props }) }));
|
|
205
214
|
}
|
|
206
215
|
function AgentMarkdownImage({ node: _node, src, alt, ...props }) {
|
|
207
216
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -331,12 +340,12 @@ function activityIcon(kind) {
|
|
|
331
340
|
}
|
|
332
341
|
}
|
|
333
342
|
const DISCLOSURE_ROW_INTERACTIVE = "button, a, input, textarea, select, [role='button'], [contenteditable='true']";
|
|
334
|
-
/**
|
|
335
|
-
export function AgentKitDisclosureSummary({ open, onToggle, label, icon, expandable = true, as = "button", controls, meta, className, rowClassName, style, chevronStyle, children, }) {
|
|
336
|
-
const content = children ?? (_jsxs(_Fragment, { children: [icon !== undefined ?
|
|
343
|
+
/** The label keeps its own styling; `TraceTitle` is for host rows. */
|
|
344
|
+
export function AgentKitDisclosureSummary({ open, onToggle, label, icon, expandable = true, as = "button", controls, meta, className, rowClassName, style, chevronStyle, status, children, }) {
|
|
345
|
+
const content = children ?? (_jsxs(_Fragment, { children: [_jsxs(TraceLine, { status: status, children: [icon !== undefined ? _jsx(TraceIcon, { children: icon }) : null, _jsx("span", { "data-slot": "trace-title", className: "agentkit-disclosure-label", children: label })] }), expandable && as === "button" ? (_jsx(IconChevronRight, { "aria-hidden": "true", className: "agentkit-icon agentkit-disclosure-chevron", "data-open": open ? "true" : "false", style: chevronStyle })) : null] }));
|
|
337
346
|
const trigger = as === "static" ? (_jsx("span", { className: ["agentkit-disclosure-summary", className]
|
|
338
347
|
.filter(Boolean)
|
|
339
|
-
.join(" "), "data-expandable": "false", style: style, children: content })) : (_jsx("button", { type: "button", className: ["agentkit-disclosure-summary", className]
|
|
348
|
+
.join(" "), "data-expandable": "false", style: style, children: content })) : (_jsx("button", { type: "button", "data-slot": expandable ? "trace-collapsible-trigger" : undefined, className: ["agentkit-disclosure-summary", className]
|
|
340
349
|
.filter(Boolean)
|
|
341
350
|
.join(" "), "data-expandable": expandable ? "true" : "false", "aria-expanded": expandable ? open : undefined, "aria-controls": expandable ? controls : undefined, "aria-disabled": expandable ? undefined : true, tabIndex: expandable ? undefined : -1, style: style, onClick: () => {
|
|
342
351
|
if (expandable)
|
|
@@ -361,36 +370,10 @@ export function AgentKitDisclosureSummary({ open, onToggle, label, icon, expanda
|
|
|
361
370
|
}
|
|
362
371
|
: undefined, children: [trigger, meta] }));
|
|
363
372
|
}
|
|
364
|
-
/**
|
|
365
|
-
const AgentKitDeferClosedContentContext = createContext(false);
|
|
366
|
-
/**
|
|
367
|
-
* Mounted while closed, like <details>, so find-in-page can reveal it. In a
|
|
368
|
-
* long thread, closed content mounts in the next idle period rather than with
|
|
369
|
-
* the transcript, so the history paints before every collapsed step renders.
|
|
370
|
-
*/
|
|
373
|
+
/** Mounted while closed, like <details>, so find-in-page can reveal it. */
|
|
371
374
|
export function AgentKitDisclosureContent({ id, open, onReveal, children, }) {
|
|
372
|
-
const ref =
|
|
373
|
-
|
|
374
|
-
revealRef.current = onReveal;
|
|
375
|
-
const deferClosed = useContext(AgentKitDeferClosedContentContext);
|
|
376
|
-
const [contentMounted, setContentMounted] = useState(open || !deferClosed);
|
|
377
|
-
if (open && !contentMounted)
|
|
378
|
-
setContentMounted(true);
|
|
379
|
-
useEffect(() => {
|
|
380
|
-
if (contentMounted)
|
|
381
|
-
return;
|
|
382
|
-
return scheduleIdleMount(() => setContentMounted(true));
|
|
383
|
-
}, [contentMounted]);
|
|
384
|
-
useEffect(() => {
|
|
385
|
-
const element = ref.current;
|
|
386
|
-
if (!element || open)
|
|
387
|
-
return;
|
|
388
|
-
element.setAttribute("hidden", "until-found");
|
|
389
|
-
const reveal = () => revealRef.current?.();
|
|
390
|
-
element.addEventListener("beforematch", reveal);
|
|
391
|
-
return () => element.removeEventListener("beforematch", reveal);
|
|
392
|
-
}, [open]);
|
|
393
|
-
return (_jsx("div", { ref: ref, id: id, className: "agentkit-disclosure-content", hidden: !open, children: contentMounted || open ? children : null }));
|
|
375
|
+
const { ref, mounted } = useUntilFoundContent(open, onReveal);
|
|
376
|
+
return (_jsx("div", { ref: ref, id: id, "data-slot": "trace-collapsible-content", "data-state": open ? "open" : "closed", className: "agentkit-disclosure-content", hidden: !open, children: mounted ? children : null }));
|
|
394
377
|
}
|
|
395
378
|
function interactionIcon(kind) {
|
|
396
379
|
const props = { "aria-hidden": true, className: "agentkit-icon" };
|
|
@@ -407,7 +390,7 @@ function interactionIcon(kind) {
|
|
|
407
390
|
case "completed":
|
|
408
391
|
return _jsx(IconCircleCheck, { ...props });
|
|
409
392
|
case "failed":
|
|
410
|
-
return _jsx(
|
|
393
|
+
return _jsx(IconAlertTriangle, { ...props });
|
|
411
394
|
case "closed":
|
|
412
395
|
return _jsx(IconX, { ...props });
|
|
413
396
|
default:
|
|
@@ -769,6 +752,54 @@ function formatActivityToolValue(value, labels = {}) {
|
|
|
769
752
|
const contentLimit = Math.max(0, ACTIVITY_TOOL_VALUE_LIMIT - omissionMarker.length - 1);
|
|
770
753
|
return `${formatted.slice(0, contentLimit).trimEnd()}…${omissionMarker}`;
|
|
771
754
|
}
|
|
755
|
+
/** Fields whose string is the program a tool runs, with its grammar. */
|
|
756
|
+
const ACTIVITY_TOOL_SOURCE_FIELDS = {
|
|
757
|
+
command: "bash",
|
|
758
|
+
script: undefined,
|
|
759
|
+
code: undefined,
|
|
760
|
+
};
|
|
761
|
+
function formatActivityToolInput(value, labels = {}) {
|
|
762
|
+
const source = activityToolSource(value);
|
|
763
|
+
if (!source) {
|
|
764
|
+
const text = formatActivityToolValue(value, labels);
|
|
765
|
+
return text ? { text } : undefined;
|
|
766
|
+
}
|
|
767
|
+
const text = formatActivityToolValue(source.text, labels);
|
|
768
|
+
if (!text)
|
|
769
|
+
return undefined;
|
|
770
|
+
const options = Object.entries(source.rest).flatMap(([key, option]) => {
|
|
771
|
+
const formatted = formatActivityToolValue(option, labels);
|
|
772
|
+
return formatted ? [[key, formatted.replace(/\s+/g, " ")]] : [];
|
|
773
|
+
});
|
|
774
|
+
return {
|
|
775
|
+
text,
|
|
776
|
+
language: source.language,
|
|
777
|
+
...(options.length ? { options } : {}),
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
function activityToolSource(value) {
|
|
781
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
782
|
+
return undefined;
|
|
783
|
+
}
|
|
784
|
+
const input = value;
|
|
785
|
+
const field = Object.keys(ACTIVITY_TOOL_SOURCE_FIELDS).find((key) => {
|
|
786
|
+
const text = input[key];
|
|
787
|
+
// `code` also names short values such as a country or a promo code.
|
|
788
|
+
return (typeof text === "string" &&
|
|
789
|
+
(key === "command" ? text.trim() !== "" : /\n|.{40}/.test(text)));
|
|
790
|
+
});
|
|
791
|
+
if (!field)
|
|
792
|
+
return undefined;
|
|
793
|
+
const languageField = ["language", "lang"].find((key) => typeof input[key] === "string");
|
|
794
|
+
const rest = Object.fromEntries(Object.entries(input).filter(([key, option]) => key !== field && key !== languageField && option !== undefined));
|
|
795
|
+
return {
|
|
796
|
+
text: input[field],
|
|
797
|
+
language: languageField
|
|
798
|
+
? input[languageField]
|
|
799
|
+
: ACTIVITY_TOOL_SOURCE_FIELDS[field],
|
|
800
|
+
rest,
|
|
801
|
+
};
|
|
802
|
+
}
|
|
772
803
|
function activityLabel(activity, workingLabel) {
|
|
773
804
|
const label = readableText(activity.label);
|
|
774
805
|
if (label.toLowerCase() === "processing")
|
|
@@ -778,7 +809,16 @@ function activityLabel(activity, workingLabel) {
|
|
|
778
809
|
workingLabel);
|
|
779
810
|
}
|
|
780
811
|
function AgentIdentityChip({ id, name, fallbackName = "Agent", kind, status, }) {
|
|
781
|
-
|
|
812
|
+
const { labels } = useAgentKit();
|
|
813
|
+
// The chip's tint and shimmer carry the state, so it is said in words too.
|
|
814
|
+
const statusLabel = status === "working"
|
|
815
|
+
? labels.taskStatusRunning
|
|
816
|
+
: status === "failed"
|
|
817
|
+
? labels.taskStatusFailed
|
|
818
|
+
: status === "waiting"
|
|
819
|
+
? labels.taskStatusAwaitingInput
|
|
820
|
+
: undefined;
|
|
821
|
+
return (_jsxs("span", { className: "agentkit-agent", "data-agent-id": id, "data-agent-kind": kind, "data-status": status, children: [status === "failed" ? (_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" })) : null, _jsx("span", { className: "agentkit-agent-name", children: readableText(name) || fallbackName }), statusLabel ? (_jsx("span", { className: "agentkit-visually-hidden", children: statusLabel })) : null] }));
|
|
782
822
|
}
|
|
783
823
|
function defaultInteractionLabel(interaction, labels) {
|
|
784
824
|
if (interaction.label)
|
|
@@ -805,8 +845,9 @@ function defaultInteractionLabel(interaction, labels) {
|
|
|
805
845
|
}
|
|
806
846
|
}
|
|
807
847
|
export function AgentInteractionItem({ value: interaction, threadId, }) {
|
|
808
|
-
const { slots, registry, labels } = useAgentKit();
|
|
848
|
+
const { slots, registry, labels, formatAgentInteractionDetail } = useAgentKit();
|
|
809
849
|
const thread = useAgentThreadSlice(sameAgents, threadId);
|
|
850
|
+
const showAgent = useContext(AgentSubagentStepContext) !== interaction.agentId;
|
|
810
851
|
const agent = thread.agents[interaction.agentId];
|
|
811
852
|
const target = interaction.targetAgentId
|
|
812
853
|
? thread.agents[interaction.targetAgentId]
|
|
@@ -832,8 +873,8 @@ export function AgentInteractionItem({ value: interaction, threadId, }) {
|
|
|
832
873
|
const label = readableText(interaction.label);
|
|
833
874
|
const visibleLabel = humanizeAgentLabel(label) ||
|
|
834
875
|
defaultInteractionLabel({ ...interaction, label: undefined }, labels);
|
|
835
|
-
const detail = readableText(interaction.detail);
|
|
836
|
-
return (_jsxs("div", { className: "agentkit-agent-interaction", "data-kind": interaction.kind, "data-scope": interaction.scope, children: [_jsxs(
|
|
876
|
+
const detail = readableText(formatAgentInteractionDetail?.(interaction) ?? interaction.detail);
|
|
877
|
+
return (_jsxs("div", { className: "agentkit-agent-interaction", "data-kind": interaction.kind, "data-scope": interaction.scope, children: [_jsxs(TraceLine, { className: "agentkit-agent-interaction-head", status: interaction.kind === "failed" ? "error" : undefined, children: [_jsx(TraceIcon, { children: interactionIcon(interaction.kind) }), !showAgent ? null : AgentRenderer ? (_jsx(AgentRenderer, { value: agent, threadId: threadId })) : (_jsx(AgentIdentityChip, { id: interaction.agentId, name: agentName, fallbackName: labels.assistant })), _jsx("span", { "data-slot": "trace-title", className: "agentkit-agent-interaction-label", children: visibleLabel }), target && TargetRenderer ? (_jsx(TargetRenderer, { value: target, threadId: threadId })) : interaction.targetAgentId ? (_jsx(AgentIdentityChip, { id: interaction.targetAgentId, name: targetName, fallbackName: labels.assistant })) : null, object ? _jsx(ObjectRenderer, { value: object, threadId: threadId }) : null] }), detail && (!object || interaction.kind === "failed") ? (_jsx("span", { ...(interaction.kind === "failed"
|
|
837
878
|
? SESSION_REPLAY_MASK_PROPS
|
|
838
879
|
: { title: detail }), className: "agentkit-agent-interaction-detail", children: detail })) : null] }));
|
|
839
880
|
}
|
|
@@ -860,11 +901,27 @@ export function AgentActivityItem({ value: activity, threadId, }) {
|
|
|
860
901
|
const thread = useAgentThreadSlice((previous, next) => previous.agents === next.agents &&
|
|
861
902
|
previous.tools[activity.id] === next.tools[activity.id]);
|
|
862
903
|
const [open, setOpen] = useState(false);
|
|
904
|
+
const showAgent = useContext(AgentSubagentStepContext) !== activity.agentId;
|
|
863
905
|
const agent = activity.agentId ? thread.agents[activity.agentId] : undefined;
|
|
864
906
|
const agentName = resolveAgentName(thread, activity.agentId, [activity.source, activity.object], labels.assistant);
|
|
865
907
|
const tool = thread.tools[activity.id];
|
|
866
|
-
const toolInput = useMemo(() => (tool ?
|
|
908
|
+
const toolInput = useMemo(() => (tool ? formatActivityToolInput(tool.input, labels) : undefined), [labels, tool]);
|
|
867
909
|
const toolResult = useMemo(() => (tool ? formatActivityToolValue(tool.output, labels) : undefined), [labels, tool]);
|
|
910
|
+
const stackTrace = useMemo(() => {
|
|
911
|
+
if (!tool)
|
|
912
|
+
return undefined;
|
|
913
|
+
const sources = [
|
|
914
|
+
toolResult,
|
|
915
|
+
formatActivityToolValue(tool.error?.details, labels),
|
|
916
|
+
formatActivityToolValue(tool.error?.message, labels),
|
|
917
|
+
];
|
|
918
|
+
for (const source of sources) {
|
|
919
|
+
const parsed = source ? parseStackTrace(source) : undefined;
|
|
920
|
+
if (parsed)
|
|
921
|
+
return { parsed, fromResult: source === toolResult };
|
|
922
|
+
}
|
|
923
|
+
return undefined;
|
|
924
|
+
}, [labels, tool, toolResult]);
|
|
868
925
|
const toolInputLabel = labels.toolInput;
|
|
869
926
|
const toolResultLabel = labels.toolResult;
|
|
870
927
|
const expandable = Boolean(activity.summary?.length || toolInput || toolResult);
|
|
@@ -877,6 +934,13 @@ export function AgentActivityItem({ value: activity, threadId, }) {
|
|
|
877
934
|
const object = activity.object ??
|
|
878
935
|
sourceObjectUnlessRepresented(activity.source, thread, [activity.agentId]);
|
|
879
936
|
const failed = activity.status === "failed";
|
|
937
|
+
const statusWords = activity.status === "running"
|
|
938
|
+
? labels.taskStatusRunning
|
|
939
|
+
: failed
|
|
940
|
+
? labels.taskStatusFailed
|
|
941
|
+
: activity.status === "cancelled"
|
|
942
|
+
? labels.runStopped
|
|
943
|
+
: undefined;
|
|
880
944
|
const errorPreview = activityErrorPreview(activity, tool, labels);
|
|
881
945
|
// A tool call names what it acted on, so rows in a group tell apart.
|
|
882
946
|
const toolObject = tool && !object
|
|
@@ -885,8 +949,41 @@ export function AgentActivityItem({ value: activity, threadId, }) {
|
|
|
885
949
|
const detail = tool || failed
|
|
886
950
|
? readableText(toolObject?.text)
|
|
887
951
|
: readableText(activity.detail);
|
|
888
|
-
const
|
|
889
|
-
|
|
952
|
+
const line = (_jsxs(TraceLine, { status: traceStatus(activity.status), children: [_jsx(TraceIcon, { children: failed ? (_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" })) : (_jsx(ActivitySourceIcon, { activity: activity, threadId: threadId })) }), _jsxs("span", { className: "agentkit-disclosure-label", children: [!showAgent ? null : agent && AgentRenderer ? (_jsx(AgentRenderer, { value: agent, threadId: threadId })) : activity.agentId ? (_jsx(AgentIdentityChip, { id: activity.agentId, name: agentName, fallbackName: labels.assistant })) : null, _jsx(TraceTitle, { className: "agentkit-activity-label", children: activityLabel(activity, labels.working) }), statusWords ? (_jsx("span", { className: "agentkit-visually-hidden", children: statusWords })) : null] })] }));
|
|
953
|
+
const meta = (_jsxs(_Fragment, { children: [object ? _jsx(ObjectRenderer, { value: object, threadId: threadId }) : null, detail ? (_jsx(TraceDescription, { ...(toolObject ? SESSION_REPLAY_MASK_PROPS : {}), title: toolObject ? undefined : detail, className: "agentkit-activity-detail", "data-kind": toolObject?.kind, children: detail })) : null] }));
|
|
954
|
+
const errorLine = errorPreview ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-activity-error", children: errorPreview })) : null;
|
|
955
|
+
const rootProps = {
|
|
956
|
+
className: "agentkit-activity-item",
|
|
957
|
+
"data-activity-kind": activity.kind,
|
|
958
|
+
"data-status": activity.status,
|
|
959
|
+
"data-open": expandable && open ? "true" : "false",
|
|
960
|
+
};
|
|
961
|
+
const fileChange = tool ? fileChangeTool(tool) : undefined;
|
|
962
|
+
if (fileChange) {
|
|
963
|
+
return (_jsxs("div", { ...rootProps, children: [_jsx(FileChange, { change: fileChange, running: activity.status === "running" }), errorLine] }));
|
|
964
|
+
}
|
|
965
|
+
const terminal = tool ? terminalTool(tool) : undefined;
|
|
966
|
+
if (terminal) {
|
|
967
|
+
return (_jsx("div", { ...rootProps, children: _jsx(Terminal, { command: terminal.command, output: typeof tool?.output === "string" ? tool.output : toolResult, running: activity.status === "running", exitCode: terminal.exitCode, durationMs: terminal.durationMs, timedOut: terminal.timedOut, failed: failed }) }));
|
|
968
|
+
}
|
|
969
|
+
if (!expandable) {
|
|
970
|
+
return (_jsxs("div", { ...rootProps, children: [_jsxs("div", { className: "agentkit-disclosure-row agentkit-activity-row", children: [_jsx("span", { className: "agentkit-disclosure-summary", "data-expandable": "false", children: line }), meta] }), errorLine] }));
|
|
971
|
+
}
|
|
972
|
+
return (_jsxs(TraceCollapsible, { ...rootProps, open: open, onOpenChange: setOpen, children: [_jsxs("div", { className: "agentkit-disclosure-row agentkit-activity-row", "data-expandable": "true", onClick: (event) => {
|
|
973
|
+
// Meta controls handle their own clicks; a text-selecting drag is no toggle.
|
|
974
|
+
const target = event.target;
|
|
975
|
+
if (target instanceof Element &&
|
|
976
|
+
target.closest(DISCLOSURE_ROW_INTERACTIVE))
|
|
977
|
+
return;
|
|
978
|
+
if (globalThis.getSelection()?.toString())
|
|
979
|
+
return;
|
|
980
|
+
setOpen((current) => !current);
|
|
981
|
+
}, children: [_jsx(TraceCollapsibleTrigger, { children: line }), meta] }), errorLine, _jsxs(TraceCollapsibleContent
|
|
982
|
+
// A fresh node on each toggle: the recorder can drop a block marker
|
|
983
|
+
// changed on a node it has recorded, and the closed body stays mounted.
|
|
984
|
+
, { keepMounted: true, ...(activity.status === "failed" || !open
|
|
985
|
+
? SESSION_REPLAY_BLOCK_PROPS
|
|
986
|
+
: {}), className: "agentkit-activity-summary", children: [activity.summary?.map((part, index) => {
|
|
890
987
|
const safePart = part.type === "text"
|
|
891
988
|
? {
|
|
892
989
|
...part,
|
|
@@ -896,7 +993,95 @@ export function AgentActivityItem({ value: activity, threadId, }) {
|
|
|
896
993
|
}
|
|
897
994
|
: part;
|
|
898
995
|
return safePart.type === "text" && !safePart.text ? null : (_jsx(AgentMessagePartView, { value: safePart, threadId: threadId }, `${activity.id}-summary-${index}`));
|
|
899
|
-
}), toolInput ? (
|
|
996
|
+
}), toolInput ? (_jsx(ActivityToolValue, { label: toolInputLabel, value: toolInput.text, language: toolInput.language, options: toolInput.options })) : null, stackTrace ? (_jsx(StackTrace, { trace: stackTrace.parsed, defaultOpen: true })) : null, toolResult && !(stackTrace?.fromResult && stackTrace.parsed.whole) ? (_jsx(ActivityToolValue, { label: toolResultLabel, value: toolResult })) : null] }, open ? "open" : "closed")] }));
|
|
997
|
+
}
|
|
998
|
+
function terminalTool(tool) {
|
|
999
|
+
const metadata = tool.metadata;
|
|
1000
|
+
if (metadata?.toolKind !== "bash" || typeof metadata.command !== "string") {
|
|
1001
|
+
return undefined;
|
|
1002
|
+
}
|
|
1003
|
+
return {
|
|
1004
|
+
command: metadata.command,
|
|
1005
|
+
exitCode: typeof metadata.exitCode === "number" || metadata.exitCode === null
|
|
1006
|
+
? metadata.exitCode
|
|
1007
|
+
: undefined,
|
|
1008
|
+
durationMs: typeof metadata.durationMs === "number" ? metadata.durationMs : undefined,
|
|
1009
|
+
timedOut: metadata.timedOut === true ? true : undefined,
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
function fileChangeTool(tool) {
|
|
1013
|
+
const metadata = tool.metadata;
|
|
1014
|
+
const kind = metadata?.toolKind;
|
|
1015
|
+
if ((kind !== "edit" && kind !== "write") ||
|
|
1016
|
+
typeof metadata?.filePath !== "string") {
|
|
1017
|
+
return undefined;
|
|
1018
|
+
}
|
|
1019
|
+
const text = (value) => typeof value === "string" ? value : undefined;
|
|
1020
|
+
return {
|
|
1021
|
+
filePath: metadata.filePath,
|
|
1022
|
+
kind,
|
|
1023
|
+
oldText: text(metadata.oldText),
|
|
1024
|
+
newText: text(metadata.newText),
|
|
1025
|
+
content: text(metadata.content),
|
|
1026
|
+
lineCount: typeof metadata.lineCount === "number" ? metadata.lineCount : undefined,
|
|
1027
|
+
truncated: metadata.truncated === true,
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function ActivityToolValue({ label, value, language: sourceLanguage, options, }) {
|
|
1031
|
+
const language = useMemo(() => sourceLanguage ?? (isJsonText(value) ? "json" : undefined), [sourceLanguage, value]);
|
|
1032
|
+
return (_jsxs(CodeBlock, { size: "sm", className: "agentkit-activity-summary-section", children: [_jsxs(CodeBlockHeader, { children: [_jsx(CodeBlockTitle, { children: label }), _jsx(CodeBlockActions, { children: _jsx(CodeBlockCopyButton, { value: value }) })] }), _jsx(CodeBlockContent, { wrap: true, language: language, role: "group", "aria-label": label, className: "agentkit-activity-summary-value", children: value }), options ? (_jsx(CodeBlockFooter, { children: _jsx("dl", { className: "agentkit-activity-tool-options", children: options.map(([key, option]) => (_jsxs("div", { children: [_jsx("dt", { children: key }), _jsx("dd", { children: option })] }, key))) }) })) : null] }));
|
|
1033
|
+
}
|
|
1034
|
+
function isJsonText(text) {
|
|
1035
|
+
const start = text.trimStart()[0];
|
|
1036
|
+
if (start !== "{" && start !== "[")
|
|
1037
|
+
return false;
|
|
1038
|
+
try {
|
|
1039
|
+
JSON.parse(text);
|
|
1040
|
+
return true;
|
|
1041
|
+
// coercion-ok: text that does not parse is the predicate's false answer.
|
|
1042
|
+
}
|
|
1043
|
+
catch {
|
|
1044
|
+
return false;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
/** The same page cited twice counts as one source. */
|
|
1048
|
+
export function AgentSources({ citations }) {
|
|
1049
|
+
const { labels } = useAgentKit();
|
|
1050
|
+
const sources = useMemo(() => {
|
|
1051
|
+
const seen = new Set();
|
|
1052
|
+
return citations.filter((citation) => {
|
|
1053
|
+
const key = safeAgentHref(citation.url) ?? `title:${citation.title}`;
|
|
1054
|
+
if (seen.has(key))
|
|
1055
|
+
return false;
|
|
1056
|
+
seen.add(key);
|
|
1057
|
+
return true;
|
|
1058
|
+
});
|
|
1059
|
+
}, [citations]);
|
|
1060
|
+
const label = (sources.length === 1
|
|
1061
|
+
? labels.workStepSourcesOne
|
|
1062
|
+
: labels.workStepSourcesOther).replace("{{count}}", () => `${sources.length}`);
|
|
1063
|
+
return (_jsx(Trace, { className: "agentkit-sources", children: _jsxs(TraceCollapsible, { children: [_jsx(TraceCollapsibleTrigger, { children: _jsxs(TraceLine, { children: [_jsx(TraceIcon, { children: _jsx(IconWorld, { "aria-hidden": "true", className: "agentkit-icon" }) }), _jsx("span", { className: "agentkit-disclosure-label", children: label })] }) }), _jsx(TraceCollapsibleContent, { keepMounted: true, children: _jsx("ul", { className: "agentkit-sources-list", children: sources.map((source, index) => (_jsx("li", { children: _jsx(AgentLink, { href: source.url, children: _jsxs(TraceLine, { children: [_jsx(TraceIcon, { children: _jsx(IconWorld, { "aria-hidden": "true", className: "agentkit-icon" }) }), _jsx(TraceTitle, { children: sourceTitle(source) })] }) }) }, `${index}:${source.url ?? source.title}`))) }) })] }) }));
|
|
1064
|
+
}
|
|
1065
|
+
function sourceTitle(source) {
|
|
1066
|
+
const title = readableText(source.title);
|
|
1067
|
+
if (title)
|
|
1068
|
+
return title;
|
|
1069
|
+
const href = safeAgentHref(source.url);
|
|
1070
|
+
if (!href)
|
|
1071
|
+
return source.title;
|
|
1072
|
+
try {
|
|
1073
|
+
return new URL(href).hostname;
|
|
1074
|
+
}
|
|
1075
|
+
catch {
|
|
1076
|
+
return href;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
function traceStatus(status) {
|
|
1080
|
+
return status === "running"
|
|
1081
|
+
? "running"
|
|
1082
|
+
: status === "failed"
|
|
1083
|
+
? "error"
|
|
1084
|
+
: undefined;
|
|
900
1085
|
}
|
|
901
1086
|
function ActivitySourceIcon({ activity, threadId, compact = false, }) {
|
|
902
1087
|
const { registry } = useAgentKit();
|
|
@@ -981,26 +1166,6 @@ function workedSummaryLabel(durationMs, labels, formatDuration) {
|
|
|
981
1166
|
? labels.workedFor.replace("{{duration}}", () => formatDuration(durationMs))
|
|
982
1167
|
: labels.worked;
|
|
983
1168
|
}
|
|
984
|
-
export function formatAgentKitDuration(ms, units = {}) {
|
|
985
|
-
const hour = units.hour ?? "h";
|
|
986
|
-
const minute = units.minute ?? "m";
|
|
987
|
-
const second = units.second ?? "s";
|
|
988
|
-
const totalSeconds = Math.max(0, Math.round(ms / 1_000));
|
|
989
|
-
if (totalSeconds < 60)
|
|
990
|
-
return `${Math.max(1, totalSeconds)}${second}`;
|
|
991
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
992
|
-
const seconds = totalSeconds % 60;
|
|
993
|
-
if (minutes < 60) {
|
|
994
|
-
return seconds === 0
|
|
995
|
-
? `${minutes}${minute}`
|
|
996
|
-
: `${minutes}${minute} ${seconds}${second}`;
|
|
997
|
-
}
|
|
998
|
-
const hours = Math.floor(minutes / 60);
|
|
999
|
-
const remainingMinutes = minutes % 60;
|
|
1000
|
-
return remainingMinutes === 0
|
|
1001
|
-
? `${hours}${hour}`
|
|
1002
|
-
: `${hours}${hour} ${remainingMinutes}${minute}`;
|
|
1003
|
-
}
|
|
1004
1169
|
function isVisibleReasoningPart(part) {
|
|
1005
1170
|
return (part.type === "reasoning" &&
|
|
1006
1171
|
part.visibility !== "hidden" &&
|
|
@@ -1527,7 +1692,7 @@ export const AgentActivityGroup = memo(function AgentActivityGroup({ runId, afte
|
|
|
1527
1692
|
AgentActivityItem;
|
|
1528
1693
|
return _jsx(Renderer, { value: call.activity, threadId: threadId }, call.id);
|
|
1529
1694
|
};
|
|
1530
|
-
return (_jsxs(_Fragment, { children: [resultCards, hasExpandableActivity || activelyWorking ? (_jsx(AgentWorkDisclosure, { label: baseSummaryLabel, failedCount: failedCount, icon: summaryIcon, running: visiblyRunning, expandable: hasExpandableActivity, runId: runId, messageId: messageId, current: currentActivity ? (_jsxs("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: [_jsx(ActivitySourceIcon, { activity: currentActivity, threadId: threadId, compact: true }), _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel })] })) : null, currentLabel: currentActivity ? (_jsx("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel }) })) : null, children: _jsx(AgentWorkStepList, { steps: steps, threadId: threadId, running: activelyWorking, renderCall: renderCall }) })) : (_jsx("div", { className: "agentkit-activities-static", children: summaryLabel || currentActivity ? (_jsx(AgentKitDisclosureSummary, { as: "static", className: "agentkit-activities-summary", open: false, onToggle: () => { }, expandable: false, icon: summaryIcon, label: summaryLabel ? (_jsx("span", { className: "agentkit-activities-label", children: summaryLabel })) : (_jsx("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel }) })) })) : null }))] }));
|
|
1695
|
+
return (_jsxs(_Fragment, { children: [resultCards, hasExpandableActivity || activelyWorking ? (_jsx(AgentWorkDisclosure, { label: baseSummaryLabel, failedCount: failedCount, icon: summaryIcon, running: visiblyRunning, expandable: hasExpandableActivity, runId: runId, messageId: messageId, current: currentActivity ? (_jsxs("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: [_jsx(ActivitySourceIcon, { activity: currentActivity, threadId: threadId, compact: true }), _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel })] })) : null, currentLabel: currentActivity ? (_jsx("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel }) })) : null, children: _jsx(AgentWorkStepList, { steps: steps, threadId: threadId, running: activelyWorking, renderCall: renderCall }) })) : (_jsx("div", { className: "agentkit-activities-static", children: summaryLabel || currentActivity ? (_jsx(AgentKitDisclosureSummary, { as: "static", className: "agentkit-activities-summary", open: false, onToggle: () => { }, expandable: false, status: summaryLabel ? undefined : "running", icon: summaryIcon, label: summaryLabel ? (_jsx("span", { className: "agentkit-activities-label", children: summaryLabel })) : (_jsx("span", { className: "agentkit-activities-current", "data-running": "true", "data-agentkit-current-activity": "true", children: _jsx("span", { className: "agentkit-activities-current-label agent-running-shimmer", children: currentActivityLabel }) })) })) : null }))] }));
|
|
1531
1696
|
});
|
|
1532
1697
|
const WORK_STEP_PREVIEW_COUNT = 6;
|
|
1533
1698
|
const WORK_GROUP_PREVIEW_COUNT = 4;
|
|
@@ -1642,7 +1807,7 @@ function AgentWorkGroupRow({ group, threadId, renderCall, }) {
|
|
|
1642
1807
|
]))
|
|
1643
1808
|
: undefined;
|
|
1644
1809
|
const reason = group.reason ? readableText(group.reason) : "";
|
|
1645
|
-
return (_jsxs("div", { className: "agentkit-work-group", "data-verb": group.verb, "data-failed": group.failed ? "true" : undefined, "data-running": group.running ? "true" : undefined, "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { rowClassName: "agentkit-activity-row agentkit-work-group-row", open: open, onToggle: () => setOpen((current) => !current), controls: contentId, icon: group.failed ? (_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" })) : ((source?.icon ??
|
|
1810
|
+
return (_jsxs("div", { className: "agentkit-work-group", "data-verb": group.verb, "data-failed": group.failed ? "true" : undefined, "data-running": group.running ? "true" : undefined, "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { rowClassName: "agentkit-activity-row agentkit-work-group-row", open: open, onToggle: () => setOpen((current) => !current), controls: contentId, status: group.failed ? "error" : group.running ? "running" : undefined, icon: group.failed ? (_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" })) : ((source?.icon ??
|
|
1646
1811
|
workVerbIcon(group.verb) ??
|
|
1647
1812
|
activityIcon(activity.kind))), label: _jsxs(_Fragment, { children: [agent && AgentRenderer ? (_jsx(AgentRenderer, { value: agent, threadId: threadId })) : activity.agentId ? (_jsx(AgentIdentityChip, { id: activity.agentId, name: resolveAgentName(thread, activity.agentId, [activity.source, activity.object], labels.assistant), fallbackName: labels.assistant })) : null, _jsx("span", { className: "agentkit-activity-label agentkit-work-group-label", children: label }), group.verb === "used" && !group.failed && count > 1 ? (_jsxs("span", { className: "agentkit-activity-cluster-count", children: ["\u00D7", count] })) : null] }), meta: reason || group.objects.length || reference ? (_jsxs("span", { className: "agentkit-work-group-meta", children: [reason ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-work-failure-reason", children: reason })) : null, _jsx(AgentWorkObjects, { objects: group.objects }), reference ? (_jsx(ObjectRenderer, { value: reference, threadId: threadId })) : null] })) : null }), _jsx(AgentKitDisclosureContent, { id: contentId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-activity-cluster-items", children: group.calls.map(renderCall) }) })] }));
|
|
1648
1813
|
}
|
|
@@ -1691,7 +1856,7 @@ function AgentWorkStepItem({ step, plain, threadId, renderCall, }) {
|
|
|
1691
1856
|
? step.groups
|
|
1692
1857
|
: step.groups.filter((group, index) => index < WORK_GROUP_PREVIEW_COUNT || group.failed);
|
|
1693
1858
|
const hiddenGroups = step.groups.length - groups.length;
|
|
1694
|
-
return (_jsxs("li", { className: "agentkit-work-step", "data-running": step.running ? "true" : undefined, "data-untitled": step.title ? undefined : "true", "data-open": open ? "true" : "false", children: [plain ? null : (_jsx("span", { className: "agentkit-work-step-marker", "aria-hidden": "true", children: _jsx(IconPointFilled, { className: "agentkit-icon" }) })), _jsxs("div", { className: "agentkit-work-step-content", children: [title ? (_jsx(AgentKitDisclosureSummary, { className: "agentkit-work-step-title", open: open, onToggle: () => setOpen((current) => !current), expandable: hasBody, as: hasBody ? "button" : "static", controls: hasBody ? bodyId : undefined, label: _jsx("span", { className: "agentkit-work-step-label", "data-active": step.active ? "true" : undefined, children: title }) })) : null, hasBody ? (_jsx(AgentKitDisclosureContent, { id: bodyId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-reasoning-content agentkit-work-step-body", children: ReasoningRenderer ? (_jsx(AgentKitWorkStepBodyContext.Provider, { value: true, children: _jsx(ReasoningRenderer, { value: { type: "reasoning", text: step.reasoning ?? "" }, threadId: threadId, active: step.active, resetKey: `${threadId}:${step.key}` }) })) : (_jsx(AgentMarkdown, { text: step.body, streaming: step.active })) }) })) : null, step.groups.length ? (_jsxs("ul", { ref: groupsRef, className: "agentkit-work-groups", role: "list", children: [groups.map((group) => (_jsx("li", { children: group.standalone ||
|
|
1859
|
+
return (_jsxs("li", { className: "agentkit-work-step", "data-running": step.running ? "true" : undefined, "data-untitled": step.title ? undefined : "true", "data-open": open ? "true" : "false", children: [plain ? null : (_jsx("span", { className: "agentkit-work-step-marker", "aria-hidden": "true", children: _jsx(IconPointFilled, { className: "agentkit-icon" }) })), _jsxs("div", { className: "agentkit-work-step-content", children: [title ? (_jsx(AgentKitDisclosureSummary, { className: "agentkit-work-step-title", open: open, onToggle: () => setOpen((current) => !current), status: step.active ? "running" : undefined, expandable: hasBody, as: hasBody ? "button" : "static", controls: hasBody ? bodyId : undefined, label: _jsx("span", { className: "agentkit-work-step-label", "data-active": step.active ? "true" : undefined, children: title }) })) : null, hasBody ? (_jsx(AgentKitDisclosureContent, { id: bodyId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-reasoning-content agentkit-work-step-body", children: ReasoningRenderer ? (_jsx(AgentKitWorkStepBodyContext.Provider, { value: true, children: _jsx(ReasoningRenderer, { value: { type: "reasoning", text: step.reasoning ?? "" }, threadId: threadId, active: step.active, resetKey: `${threadId}:${step.key}` }) })) : (_jsx(AgentMarkdown, { text: step.body, streaming: step.active })) }) })) : null, step.groups.length ? (_jsxs("ul", { ref: groupsRef, className: "agentkit-work-groups", role: "list", children: [groups.map((group) => (_jsx("li", { children: group.standalone ||
|
|
1695
1860
|
(group.verb === "used" &&
|
|
1696
1861
|
!group.failed &&
|
|
1697
1862
|
group.calls.length === 1) ? (group.calls.map(renderCall)) : (_jsx(AgentWorkGroupRow, { group: group, threadId: threadId, renderCall: renderCall })) }, group.key))), hiddenGroups ? (_jsx("li", { children: _jsxs("button", { type: "button", className: "agentkit-disclosure-summary agentkit-work-more", onClick: () => {
|
|
@@ -1756,7 +1921,7 @@ function AgentWorkDisclosure({ label, failedCount = 0, icon, running, expandable
|
|
|
1756
1921
|
// The row stays one mounted trigger from "Thinking" through the first
|
|
1757
1922
|
// activity, so it never flickers; until then it is not a tab stop. Finished
|
|
1758
1923
|
// work with nothing to expand is text, not a disabled button.
|
|
1759
|
-
const disclosure = (_jsxs("div", { className: "agentkit-activities", "data-running": running ? "true" : undefined, "data-expandable": expandable ? "true" : "false", "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { as: expandable || running ? "button" : "static", className: "agentkit-activities-summary", rowClassName: "agentkit-activities-row", open: open, onToggle: () => setOpen((value) => !value), expandable: expandable, controls: contentId, style: workedForRowSummaryStyle(workedForRowLayout), chevronStyle: workedForRowChevronStyle(workedForRowLayout), icon: icon, label: summaryLabel, children: summaryContent }), _jsxs(AgentKitDisclosureContent, { id: contentId, open: open, onReveal: expandable ? () => setOpen(true) : undefined, children: [runId && expandable && !running ? (_jsx(AgentRunDetails, { runId: runId, messageId: messageId, open: open })) : null, children] })] }));
|
|
1924
|
+
const disclosure = (_jsxs("div", { className: "agentkit-activities", "data-running": running ? "true" : undefined, "data-expandable": expandable ? "true" : "false", "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { as: expandable || running ? "button" : "static", className: "agentkit-activities-summary", rowClassName: "agentkit-activities-row", open: open, onToggle: () => setOpen((value) => !value), status: running ? "running" : undefined, expandable: expandable, controls: contentId, style: workedForRowSummaryStyle(workedForRowLayout), chevronStyle: workedForRowChevronStyle(workedForRowLayout), icon: icon, label: summaryLabel, children: summaryContent }), _jsxs(AgentKitDisclosureContent, { id: contentId, open: open, onReveal: expandable ? () => setOpen(true) : undefined, children: [runId && expandable && !running ? (_jsx(AgentRunDetails, { runId: runId, messageId: messageId, open: open })) : null, children] })] }));
|
|
1760
1925
|
// A reply's work sits on its footer line, live or finished, so the finish
|
|
1761
1926
|
// never moves it.
|
|
1762
1927
|
return footerHost ? createPortal(disclosure, footerHost) : disclosure;
|
|
@@ -1764,7 +1929,7 @@ function AgentWorkDisclosure({ label, failedCount = 0, icon, running, expandable
|
|
|
1764
1929
|
function AgentReasoningPartDisclosure({ label, text, active, resetKey, }) {
|
|
1765
1930
|
const [open, setOpen] = useState(false);
|
|
1766
1931
|
const contentId = useId();
|
|
1767
|
-
return (_jsxs("div", { className: "agentkit-reasoning", "data-active": active ? "true" : undefined, "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { className: "agentkit-reasoning-summary", open: open, onToggle: () => setOpen((value) => !value), controls: contentId, icon: activityIcon("reasoning"), label: _jsx("span", { className: "agentkit-reasoning-label", children: label }) }), _jsx(AgentKitDisclosureContent, { id: contentId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-reasoning-content", children: _jsx(AgentStreamingText, { text: text, active: active, resetKey: resetKey, children: (visibleText) => (_jsx(AgentMarkdown, { text: visibleText, streaming: active || visibleText !== text })) }) }) })] }));
|
|
1932
|
+
return (_jsxs("div", { className: "agentkit-reasoning", "data-active": active ? "true" : undefined, "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { className: "agentkit-reasoning-summary", open: open, onToggle: () => setOpen((value) => !value), controls: contentId, status: active ? "running" : undefined, icon: activityIcon("reasoning"), label: _jsx("span", { className: "agentkit-reasoning-label", children: label }) }), _jsx(AgentKitDisclosureContent, { id: contentId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-reasoning-content", children: _jsx(AgentStreamingText, { text: text, active: active, resetKey: resetKey, children: (visibleText) => (_jsx(AgentMarkdown, { text: visibleText, streaming: active || visibleText !== text })) }) }) })] }));
|
|
1768
1933
|
}
|
|
1769
1934
|
/** A reply's own reasoning as work steps, as a turn with tool calls lists it. */
|
|
1770
1935
|
function AgentReasoningSteps({ message, threadId, active, }) {
|
|
@@ -1781,12 +1946,28 @@ function AgentReasoningSteps({ message, threadId, active, }) {
|
|
|
1781
1946
|
: [])), [active, message]);
|
|
1782
1947
|
return (_jsx(AgentWorkStepList, { steps: steps, threadId: threadId, running: active, renderCall: () => null }));
|
|
1783
1948
|
}
|
|
1784
|
-
|
|
1785
|
-
const
|
|
1786
|
-
|
|
1787
|
-
|
|
1949
|
+
function collaborationSubjectId(entry, thread) {
|
|
1950
|
+
const isPrimary = (id) => id !== undefined && thread.agents[id]?.kind === "primary";
|
|
1951
|
+
if (entry.type === "activity") {
|
|
1952
|
+
const id = entry.value.agentId;
|
|
1953
|
+
return id && !isPrimary(id) ? id : undefined;
|
|
1954
|
+
}
|
|
1955
|
+
const { agentId, targetAgentId } = entry.value;
|
|
1956
|
+
if (isPrimary(agentId)) {
|
|
1957
|
+
return targetAgentId && !isPrimary(targetAgentId)
|
|
1958
|
+
? targetAgentId
|
|
1959
|
+
: undefined;
|
|
1960
|
+
}
|
|
1961
|
+
return agentId;
|
|
1962
|
+
}
|
|
1963
|
+
/** Each delegated agent's entries fold into one item where it first appears. */
|
|
1964
|
+
function agentCollaborationItems(thread, runEvents, labels, range) {
|
|
1788
1965
|
const entries = new Map();
|
|
1966
|
+
const firstSequence = new Map();
|
|
1967
|
+
const order = [];
|
|
1789
1968
|
const delegatedAgentIds = new Map();
|
|
1969
|
+
// A delegated agent's own tool calls leave the parent's work for its step.
|
|
1970
|
+
const delegatedToolAgentIds = new Map();
|
|
1790
1971
|
for (const event of runEvents) {
|
|
1791
1972
|
if (event.type === "activity.started" ||
|
|
1792
1973
|
event.type === "activity.updated" ||
|
|
@@ -1796,15 +1977,18 @@ export function AgentCollaborationFeed({ runId, afterSequence, throughSequence,
|
|
|
1796
1977
|
if (agentId)
|
|
1797
1978
|
delegatedAgentIds.set(event.activity.id, agentId);
|
|
1798
1979
|
}
|
|
1980
|
+
if (event.type === "tool.started" || event.type === "tool.updated") {
|
|
1981
|
+
const agentId = event.toolCall.agentId ?? thread.tools[event.toolCall.id]?.agentId;
|
|
1982
|
+
if (agentId)
|
|
1983
|
+
delegatedToolAgentIds.set(event.toolCall.id, agentId);
|
|
1984
|
+
}
|
|
1799
1985
|
}
|
|
1800
|
-
const firstSequence = new Map();
|
|
1801
|
-
const order = [];
|
|
1802
1986
|
const remember = (key, sequence, entry) => {
|
|
1803
1987
|
if (!entries.has(key)) {
|
|
1804
1988
|
order.push(key);
|
|
1805
1989
|
firstSequence.set(key, sequence);
|
|
1806
1990
|
}
|
|
1807
|
-
entries.set(key, entry);
|
|
1991
|
+
entries.set(key, { ...entry, sequence });
|
|
1808
1992
|
};
|
|
1809
1993
|
for (const event of runEvents) {
|
|
1810
1994
|
if (event.type === "agent.interaction") {
|
|
@@ -1825,18 +2009,341 @@ export function AgentCollaborationFeed({ runId, afterSequence, throughSequence,
|
|
|
1825
2009
|
value: { ...activity, agentId },
|
|
1826
2010
|
});
|
|
1827
2011
|
}
|
|
2012
|
+
const toolId = event.type === "tool.started" || event.type === "tool.updated"
|
|
2013
|
+
? event.toolCall.id
|
|
2014
|
+
: event.type === "tool.delta"
|
|
2015
|
+
? event.toolCallId
|
|
2016
|
+
: undefined;
|
|
2017
|
+
const toolAgentId = toolId ? delegatedToolAgentIds.get(toolId) : undefined;
|
|
2018
|
+
if (toolId && toolAgentId) {
|
|
2019
|
+
const tool = toolId in thread.tools
|
|
2020
|
+
? thread.tools[toolId]
|
|
2021
|
+
: event.type === "tool.started" || event.type === "tool.updated"
|
|
2022
|
+
? event.toolCall
|
|
2023
|
+
: undefined;
|
|
2024
|
+
if (tool) {
|
|
2025
|
+
remember(`tool:${toolId}`, event.sequence, {
|
|
2026
|
+
type: "activity",
|
|
2027
|
+
value: { ...toolToActivity(tool, labels), agentId: toolAgentId },
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
1828
2031
|
}
|
|
1829
|
-
const
|
|
2032
|
+
const items = [];
|
|
2033
|
+
const subagents = new Map();
|
|
2034
|
+
for (const key of order) {
|
|
1830
2035
|
const sequence = firstSequence.get(key);
|
|
1831
|
-
|
|
1832
|
-
|
|
2036
|
+
const entry = entries.get(key);
|
|
2037
|
+
if (!entry || sequence === undefined || !sequenceInRange(sequence, range)) {
|
|
2038
|
+
continue;
|
|
2039
|
+
}
|
|
2040
|
+
const agentId = collaborationSubjectId(entry, thread);
|
|
2041
|
+
if (!agentId) {
|
|
2042
|
+
items.push({ type: "entry", key, entry });
|
|
2043
|
+
continue;
|
|
2044
|
+
}
|
|
2045
|
+
const grouped = subagents.get(agentId);
|
|
2046
|
+
if (grouped) {
|
|
2047
|
+
grouped.push(entry);
|
|
2048
|
+
continue;
|
|
2049
|
+
}
|
|
2050
|
+
const created = [entry];
|
|
2051
|
+
subagents.set(agentId, created);
|
|
2052
|
+
items.push({
|
|
2053
|
+
type: "subagent",
|
|
2054
|
+
key: `subagent:${agentId}`,
|
|
2055
|
+
agentId,
|
|
2056
|
+
entries: created,
|
|
2057
|
+
});
|
|
2058
|
+
}
|
|
2059
|
+
return items;
|
|
2060
|
+
}
|
|
2061
|
+
/** The one task a Subagent step shows: the agent's active task, else its first. */
|
|
2062
|
+
function subagentStepTask(thread, agentId) {
|
|
2063
|
+
const agent = agentId in thread.agents ? thread.agents[agentId] : undefined;
|
|
2064
|
+
return Object.values(thread.tasks).find((candidate) => candidate.assignedAgentId === agentId &&
|
|
2065
|
+
(agent?.activeTaskId === undefined ||
|
|
2066
|
+
candidate.id === agent.activeTaskId));
|
|
2067
|
+
}
|
|
2068
|
+
/** Tasks the Subagent steps in this range of a run show. */
|
|
2069
|
+
function subagentStepTaskIds(thread, runId, labels, range) {
|
|
2070
|
+
const ids = new Set();
|
|
2071
|
+
for (const item of agentCollaborationItems(thread, agentRunEvents(thread, runId), labels, range)) {
|
|
2072
|
+
if (item.type !== "subagent")
|
|
2073
|
+
continue;
|
|
2074
|
+
const task = subagentStepTask(thread, item.agentId);
|
|
2075
|
+
if (task)
|
|
2076
|
+
ids.add(task.id);
|
|
2077
|
+
}
|
|
2078
|
+
return ids;
|
|
2079
|
+
}
|
|
2080
|
+
/** Set inside a Subagent step, so its rows do not repeat the agent's chip. */
|
|
2081
|
+
const AgentSubagentStepContext = createContext(undefined);
|
|
2082
|
+
const SUBAGENT_LIFECYCLE_KINDS = new Set([
|
|
2083
|
+
"started",
|
|
2084
|
+
"resumed",
|
|
2085
|
+
"delegated",
|
|
2086
|
+
"paused",
|
|
2087
|
+
"completed",
|
|
2088
|
+
"failed",
|
|
2089
|
+
"closed",
|
|
2090
|
+
]);
|
|
2091
|
+
function subagentState(agent, entries) {
|
|
2092
|
+
switch (agent?.status) {
|
|
2093
|
+
case "waiting":
|
|
2094
|
+
case "paused":
|
|
2095
|
+
return "paused";
|
|
2096
|
+
case "completed":
|
|
2097
|
+
return "completed";
|
|
2098
|
+
case "failed":
|
|
2099
|
+
return "failed";
|
|
2100
|
+
case "closed":
|
|
2101
|
+
return "closed";
|
|
2102
|
+
case "idle":
|
|
2103
|
+
case "working":
|
|
2104
|
+
case undefined:
|
|
2105
|
+
break;
|
|
2106
|
+
}
|
|
2107
|
+
// Status can stay "working" past its last event; a finished call is not a finished agent.
|
|
2108
|
+
const newestFirst = [...entries].sort((a, b) => b.sequence - a.sequence);
|
|
2109
|
+
for (const entry of newestFirst) {
|
|
2110
|
+
if (entry.type === "activity") {
|
|
2111
|
+
if (entry.value.status === "running")
|
|
2112
|
+
return "running";
|
|
2113
|
+
continue;
|
|
2114
|
+
}
|
|
2115
|
+
switch (entry.value.kind) {
|
|
2116
|
+
case "completed":
|
|
2117
|
+
return "completed";
|
|
2118
|
+
case "failed":
|
|
2119
|
+
return "failed";
|
|
2120
|
+
case "paused":
|
|
2121
|
+
return "paused";
|
|
2122
|
+
case "closed":
|
|
2123
|
+
return "closed";
|
|
2124
|
+
case "started":
|
|
2125
|
+
case "resumed":
|
|
2126
|
+
case "delegated":
|
|
2127
|
+
return "running";
|
|
2128
|
+
case "messaged":
|
|
2129
|
+
default:
|
|
2130
|
+
break;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
if (agent?.status === "working")
|
|
2134
|
+
return "running";
|
|
2135
|
+
const latest = newestFirst.at(0);
|
|
2136
|
+
return latest?.type === "activity" && latest.value.status === "failed"
|
|
2137
|
+
? "failed"
|
|
2138
|
+
: latest?.type === "activity" && latest.value.status === "completed"
|
|
2139
|
+
? "completed"
|
|
2140
|
+
: "running";
|
|
2141
|
+
}
|
|
2142
|
+
function metadataDurationMs(metadata) {
|
|
2143
|
+
const value = metadata?.durationMs;
|
|
2144
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
2145
|
+
? value
|
|
2146
|
+
: undefined;
|
|
2147
|
+
}
|
|
2148
|
+
function subagentDurationMs(agent, entries) {
|
|
2149
|
+
const fromAgent = metadataDurationMs(agent?.metadata);
|
|
2150
|
+
if (fromAgent !== undefined)
|
|
2151
|
+
return fromAgent;
|
|
2152
|
+
for (const entry of [...entries].sort((a, b) => b.sequence - a.sequence)) {
|
|
2153
|
+
const fromEntry = metadataDurationMs(entry.value.metadata);
|
|
2154
|
+
if (fromEntry !== undefined)
|
|
2155
|
+
return fromEntry;
|
|
2156
|
+
}
|
|
2157
|
+
const started = agent?.startedAt ? Date.parse(agent.startedAt) : Number.NaN;
|
|
2158
|
+
const completed = agent?.completedAt
|
|
2159
|
+
? Date.parse(agent.completedAt)
|
|
2160
|
+
: Number.NaN;
|
|
2161
|
+
return Number.isFinite(started) &&
|
|
2162
|
+
Number.isFinite(completed) &&
|
|
2163
|
+
completed >= started
|
|
2164
|
+
? completed - started
|
|
2165
|
+
: undefined;
|
|
2166
|
+
}
|
|
2167
|
+
/** One row per delegated agent, with its own calls and its result inside. */
|
|
2168
|
+
export function AgentSubagentStep({ agentId, entries, runId, threadId, }) {
|
|
2169
|
+
const { slots, registry, labels, formatWorkedForDuration, formatAgentInteractionDetail, } = useAgentKit();
|
|
2170
|
+
const thread = useAgentThreadSlice((previous, next) => sameAgentsAndTasks(previous, next) &&
|
|
2171
|
+
previous.tools === next.tools &&
|
|
2172
|
+
previous.runs === next.runs);
|
|
2173
|
+
const [open, setOpen] = useState(false);
|
|
2174
|
+
const agent = agentId in thread.agents ? thread.agents[agentId] : undefined;
|
|
2175
|
+
const AgentRenderer = agent
|
|
2176
|
+
? (registry.agents?.[agent.kind ?? ""] ??
|
|
2177
|
+
slots.agent ??
|
|
2178
|
+
AgentParticipantView)
|
|
2179
|
+
: undefined;
|
|
2180
|
+
const name = resolveAgentName(thread, agentId, entries.map((entry) => entry.value.source), labels.assistant);
|
|
2181
|
+
const runStatus = runId === undefined ? undefined : thread.runs[runId]?.status;
|
|
2182
|
+
const liveState = subagentState(agent, entries);
|
|
2183
|
+
// Agents can outlive their run, so one still "working" after it settled has stopped.
|
|
2184
|
+
const settledStatus = liveState !== "running"
|
|
2185
|
+
? undefined
|
|
2186
|
+
: runStatus === "completed"
|
|
2187
|
+
? "completed"
|
|
2188
|
+
: runStatus === "failed"
|
|
2189
|
+
? "failed"
|
|
2190
|
+
: runStatus === "cancelled"
|
|
2191
|
+
? "closed"
|
|
2192
|
+
: undefined;
|
|
2193
|
+
const state = settledStatus ?? liveState;
|
|
2194
|
+
const durationMs = state === "running" ? undefined : subagentDurationMs(agent, entries);
|
|
2195
|
+
const duration = durationMs === undefined
|
|
2196
|
+
? undefined
|
|
2197
|
+
: (formatWorkedForDuration?.(durationMs) ??
|
|
2198
|
+
formatAgentKitDuration(durationMs, {
|
|
2199
|
+
hour: labels.durationHourShort,
|
|
2200
|
+
minute: labels.durationMinuteShort,
|
|
2201
|
+
second: labels.durationSecondShort,
|
|
2202
|
+
}));
|
|
2203
|
+
const task = subagentStepTask(thread, agentId);
|
|
2204
|
+
const taskTitle = task ? humanizeAgentLabel(task.title) : "";
|
|
2205
|
+
const shownTaskTitle = taskTitle && taskTitle.toLocaleLowerCase() !== name.toLocaleLowerCase()
|
|
2206
|
+
? taskTitle
|
|
2207
|
+
: "";
|
|
2208
|
+
const newestFirst = [...entries].sort((a, b) => b.sequence - a.sequence);
|
|
2209
|
+
const latest = (pick) => {
|
|
2210
|
+
for (const entry of newestFirst) {
|
|
2211
|
+
const value = pick(entry);
|
|
2212
|
+
if (value !== undefined)
|
|
2213
|
+
return value;
|
|
2214
|
+
}
|
|
2215
|
+
return undefined;
|
|
2216
|
+
};
|
|
2217
|
+
// A call's detail is its output, which is no headline.
|
|
2218
|
+
const progress = state === "running"
|
|
2219
|
+
? latest((entry) => entry.type === "activity" &&
|
|
2220
|
+
entry.value.status === "running" &&
|
|
2221
|
+
!(entry.value.id in thread.tools) &&
|
|
2222
|
+
readableText(entry.value.detail)
|
|
2223
|
+
? entry.value
|
|
2224
|
+
: undefined)
|
|
2225
|
+
: undefined;
|
|
2226
|
+
const progressDetail = progress ? readableText(progress.detail) : "";
|
|
2227
|
+
const failureDetail = state === "failed"
|
|
2228
|
+
? latest((entry) => entry.type === "interaction" && entry.value.kind === "failed"
|
|
2229
|
+
? readableText(formatAgentInteractionDetail?.(entry.value) ??
|
|
2230
|
+
entry.value.detail) || undefined
|
|
2231
|
+
: entry.type === "activity" && entry.value.status === "failed"
|
|
2232
|
+
? readableText(entry.value.detail) || undefined
|
|
2233
|
+
: undefined)
|
|
2234
|
+
: undefined;
|
|
2235
|
+
const status = state === "running"
|
|
2236
|
+
? labels.agentWorking
|
|
2237
|
+
: state === "failed"
|
|
2238
|
+
? labels.agentFailed
|
|
2239
|
+
: state === "paused"
|
|
2240
|
+
? labels.agentPaused
|
|
2241
|
+
: state === "closed"
|
|
2242
|
+
? labels.agentClosed
|
|
2243
|
+
: duration
|
|
2244
|
+
? labels.agentWorkedFor.replace("{{duration}}", () => duration)
|
|
2245
|
+
: labels.agentCompleted;
|
|
2246
|
+
const content = entries.flatMap((entry) => {
|
|
2247
|
+
const key = `${entry.type}:${entry.value.id}`;
|
|
2248
|
+
if (entry.type === "interaction") {
|
|
2249
|
+
const interaction = entry.value;
|
|
2250
|
+
const Custom = registry.agentInteractions?.[interaction.kind] ??
|
|
2251
|
+
slots.agentInteraction;
|
|
2252
|
+
if (Custom) {
|
|
2253
|
+
return [_jsx(Custom, { value: interaction, threadId: threadId }, key)];
|
|
2254
|
+
}
|
|
2255
|
+
// The row's own status, duration and error line already say these.
|
|
2256
|
+
if (SUBAGENT_LIFECYCLE_KINDS.has(interaction.kind) &&
|
|
2257
|
+
(interaction.kind === "failed" ||
|
|
2258
|
+
!(interaction.label ||
|
|
2259
|
+
interaction.detail ||
|
|
2260
|
+
interaction.object ||
|
|
2261
|
+
interaction.targetAgentId))) {
|
|
2262
|
+
return [];
|
|
2263
|
+
}
|
|
2264
|
+
return [
|
|
2265
|
+
_jsx(AgentInteractionItem, { value: interaction, threadId: threadId }, key),
|
|
2266
|
+
];
|
|
2267
|
+
}
|
|
2268
|
+
const activity = entry.value;
|
|
2269
|
+
const Custom = registry.activities?.[activity.kind] ?? slots.activity;
|
|
2270
|
+
if (Custom) {
|
|
2271
|
+
return [_jsx(Custom, { value: activity, threadId: threadId }, key)];
|
|
2272
|
+
}
|
|
2273
|
+
if (activity.id in thread.tools) {
|
|
2274
|
+
return [
|
|
2275
|
+
_jsx(AgentActivityItem, { value: activity, threadId: threadId }, key),
|
|
2276
|
+
];
|
|
2277
|
+
}
|
|
2278
|
+
// The agent's report is the step's result, so it shows in place.
|
|
2279
|
+
const summary = (activity.summary ?? []).flatMap((part, partIndex) => {
|
|
2280
|
+
const safePart = part.type === "text"
|
|
2281
|
+
? {
|
|
2282
|
+
...part,
|
|
2283
|
+
text: part.text.trim()
|
|
2284
|
+
? formatActivityText(part.text, labels)
|
|
2285
|
+
: "",
|
|
2286
|
+
}
|
|
2287
|
+
: part;
|
|
2288
|
+
return safePart.type === "text" && !safePart.text
|
|
2289
|
+
? []
|
|
2290
|
+
: [
|
|
2291
|
+
_jsx(AgentMessagePartView, { value: safePart, threadId: threadId }, `${key}:summary:${partIndex}`),
|
|
2292
|
+
];
|
|
2293
|
+
});
|
|
2294
|
+
if (summary.length)
|
|
2295
|
+
return summary;
|
|
2296
|
+
// A summary-less "agent" activity is the status line the header carries.
|
|
2297
|
+
if (activity === progress || activity.kind === "agent")
|
|
2298
|
+
return [];
|
|
2299
|
+
return [
|
|
2300
|
+
_jsx(AgentActivityItem, { value: activity, threadId: threadId }, key),
|
|
2301
|
+
];
|
|
1833
2302
|
});
|
|
1834
|
-
|
|
2303
|
+
const failed = state === "failed";
|
|
2304
|
+
const line = (_jsxs(TraceLine, { status: state === "running" ? "running" : failed ? "error" : undefined, children: [_jsx(TraceIcon, { children: _jsx(IconArrowFork, { "aria-hidden": "true", className: "agentkit-icon" }) }), _jsxs("span", { className: "agentkit-disclosure-label", children: [agent && AgentRenderer ? (_jsx(AgentRenderer, { value: settledStatus ? { ...agent, status: settledStatus } : agent, threadId: threadId })) : (_jsx(AgentIdentityChip, { id: agentId, name: name, fallbackName: labels.assistant, ...(failed
|
|
2305
|
+
? { status: "failed" }
|
|
2306
|
+
: state === "running"
|
|
2307
|
+
? { status: "working" }
|
|
2308
|
+
: {}) })), _jsx(TraceTitle, { className: "agentkit-activity-label", children: status })] })] }));
|
|
2309
|
+
const detail = shownTaskTitle || progressDetail;
|
|
2310
|
+
const ObjectRenderer = slots.object ?? AgentObjectReferenceView;
|
|
2311
|
+
const taskObject = task
|
|
2312
|
+
? (task.object ??
|
|
2313
|
+
sourceObjectUnlessRepresented(task.source, thread, [agentId]))
|
|
2314
|
+
: undefined;
|
|
2315
|
+
const meta = detail || taskObject ? (_jsxs(_Fragment, { children: [taskObject ? (_jsx(ObjectRenderer, { value: taskObject, threadId: threadId })) : null, detail ? (_jsx(TraceDescription, { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-activity-detail", children: detail })) : null] })) : null;
|
|
2316
|
+
const errorLine = failureDetail ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-activity-error", children: failureDetail })) : null;
|
|
2317
|
+
const rootProps = {
|
|
2318
|
+
className: "agentkit-subagent-step",
|
|
2319
|
+
"data-agent-id": agentId,
|
|
2320
|
+
// Not data-state: the collapsible keeps its open state there.
|
|
2321
|
+
"data-status": state,
|
|
2322
|
+
};
|
|
2323
|
+
if (!content.length) {
|
|
2324
|
+
return (_jsxs("div", { ...rootProps, children: [_jsxs("div", { className: "agentkit-disclosure-row agentkit-activity-row", children: [_jsx("span", { className: "agentkit-disclosure-summary", "data-expandable": "false", children: line }), meta] }), errorLine] }));
|
|
2325
|
+
}
|
|
2326
|
+
return (_jsxs(TraceCollapsible, { ...rootProps, open: open, onOpenChange: setOpen, children: [_jsxs("div", { className: "agentkit-disclosure-row agentkit-activity-row", "data-expandable": "true", onClick: (event) => {
|
|
2327
|
+
const target = event.target;
|
|
2328
|
+
if (target instanceof Element &&
|
|
2329
|
+
target.closest(DISCLOSURE_ROW_INTERACTIVE))
|
|
2330
|
+
return;
|
|
2331
|
+
if (globalThis.getSelection()?.toString())
|
|
2332
|
+
return;
|
|
2333
|
+
setOpen((current) => !current);
|
|
2334
|
+
}, children: [_jsx(TraceCollapsibleTrigger, { children: line }), meta] }), errorLine, _jsx(TraceCollapsibleContent, { keepMounted: true, ...(failed || !open ? SESSION_REPLAY_BLOCK_PROPS : {}), className: "agentkit-subagent-content", children: _jsx(AgentSubagentStepContext.Provider, { value: agentId, children: content }) }, open ? "open" : "closed")] }));
|
|
2335
|
+
}
|
|
2336
|
+
export function AgentCollaborationFeed({ runId, afterSequence, throughSequence, }) {
|
|
2337
|
+
const { threadId, slots, registry, labels } = useAgentKit();
|
|
2338
|
+
const thread = useAgentThreadSlice((previous, next) => sameRunWork(previous, next, runId));
|
|
2339
|
+
const items = agentCollaborationItems(thread, agentRunEvents(thread, runId), labels, { afterSequence, throughSequence });
|
|
2340
|
+
if (items.length === 0)
|
|
1835
2341
|
return null;
|
|
1836
|
-
return (_jsx("section", { className: "agentkit-agent-feed", "aria-label": labels.agents, "data-agent-collaboration-feed": "true", children:
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
2342
|
+
return (_jsx("section", { className: "agentkit-agent-feed", "aria-label": labels.agents, "data-agent-collaboration-feed": "true", children: items.map((item) => {
|
|
2343
|
+
if (item.type === "subagent") {
|
|
2344
|
+
return (_jsx(AgentSubagentStep, { agentId: item.agentId, entries: item.entries, runId: runId, threadId: threadId }, item.key));
|
|
2345
|
+
}
|
|
2346
|
+
const { entry, key } = item;
|
|
1840
2347
|
if (entry.type === "interaction") {
|
|
1841
2348
|
const Renderer = registry.agentInteractions?.[entry.value.kind] ??
|
|
1842
2349
|
slots.agentInteraction ??
|
|
@@ -1898,8 +2405,11 @@ export function AgentTaskItem({ value: task, threadId, }) {
|
|
|
1898
2405
|
slots.agent ??
|
|
1899
2406
|
AgentParticipantView)
|
|
1900
2407
|
: undefined;
|
|
1901
|
-
const
|
|
1902
|
-
|
|
2408
|
+
const taskProgress = task.progress;
|
|
2409
|
+
const progress = taskProgress
|
|
2410
|
+
? labels.tasksProgress
|
|
2411
|
+
.replace("{{completed}}", () => String(taskProgress.completed))
|
|
2412
|
+
.replace("{{total}}", () => String(taskProgress.total))
|
|
1903
2413
|
: undefined;
|
|
1904
2414
|
const title = humanizeAgentLabel(task.title) ||
|
|
1905
2415
|
(task.assignedAgentId ? agentName : labels.untitledTask);
|
|
@@ -1909,7 +2419,11 @@ export function AgentTaskItem({ value: task, threadId, }) {
|
|
|
1909
2419
|
const showAgent = task.assignedAgentId &&
|
|
1910
2420
|
title.toLocaleLowerCase() !== agentName.toLocaleLowerCase();
|
|
1911
2421
|
const status = taskStatusPresentation(task.status, labels);
|
|
1912
|
-
return (_jsxs(
|
|
2422
|
+
return (_jsxs(TraceLine, { className: "agentkit-task-row", "data-status": task.status, status: task.status === "running"
|
|
2423
|
+
? "running"
|
|
2424
|
+
: task.status === "failed"
|
|
2425
|
+
? "error"
|
|
2426
|
+
: undefined, children: [_jsx(TraceIcon, { children: status.icon }), _jsx("span", { className: "agentkit-visually-hidden", children: status.label }), showAgent && agent && AgentRenderer ? (_jsx(AgentRenderer, { value: agent, threadId: threadId })) : showAgent && task.assignedAgentId ? (_jsx(AgentIdentityChip, { id: task.assignedAgentId, name: agentName, fallbackName: labels.assistant })) : null, _jsx(TraceTitle, { className: "agentkit-task-title", children: title }), object ? _jsx(ObjectRenderer, { value: object, threadId: threadId }) : null, detail ? (_jsx("span", { className: "agentkit-task-detail", title: detail, children: detail })) : null, progress ? (_jsx(TraceDescription, { className: "agentkit-task-progress", children: progress })) : null] }));
|
|
1913
2427
|
}
|
|
1914
2428
|
export function AgentTaskGroup({ runId, afterSequence, throughSequence, }) {
|
|
1915
2429
|
const { threadId, slots, registry, labels } = useAgentKit();
|
|
@@ -1931,14 +2445,23 @@ export function AgentTaskGroup({ runId, afterSequence, throughSequence, }) {
|
|
|
1931
2445
|
}
|
|
1932
2446
|
tasks.set(event.task.id, thread.tasks[event.task.id] ?? event.task);
|
|
1933
2447
|
}
|
|
2448
|
+
// Only the task a Subagent step shows moves out of this list.
|
|
2449
|
+
const stepTaskIds = subagentStepTaskIds(thread, runId, labels, {
|
|
2450
|
+
afterSequence,
|
|
2451
|
+
throughSequence,
|
|
2452
|
+
});
|
|
1934
2453
|
const selectedIds = ids.filter((id) => {
|
|
1935
2454
|
const sequence = firstSequence.get(id);
|
|
1936
2455
|
return (sequence !== undefined &&
|
|
1937
|
-
sequenceInRange(sequence, { afterSequence, throughSequence })
|
|
2456
|
+
sequenceInRange(sequence, { afterSequence, throughSequence }) &&
|
|
2457
|
+
!stepTaskIds.has(id));
|
|
1938
2458
|
});
|
|
1939
2459
|
if (selectedIds.length === 0)
|
|
1940
2460
|
return null;
|
|
1941
|
-
|
|
2461
|
+
const completedCount = selectedIds.filter((id) => tasks.get(id)?.status === "completed").length;
|
|
2462
|
+
return (_jsxs("div", { className: "agentkit-tasks", "data-open": open ? "true" : "false", children: [_jsx(AgentKitDisclosureSummary, { className: "agentkit-tasks-summary", open: open, onToggle: () => setOpen((value) => !value), controls: listId, icon: _jsx(IconChecklist, { "aria-hidden": "true", className: "agentkit-icon" }), label: _jsxs(_Fragment, { children: [_jsx("span", { children: labels.tasks }), _jsx("span", { className: "agentkit-tasks-count", children: labels.tasksProgress
|
|
2463
|
+
.replace("{{completed}}", () => String(completedCount))
|
|
2464
|
+
.replace("{{total}}", () => String(selectedIds.length)) })] }) }), _jsx(AgentKitDisclosureContent, { id: listId, open: open, onReveal: () => setOpen(true), children: _jsx("div", { className: "agentkit-tasks-list", children: selectedIds.map((id) => {
|
|
1942
2465
|
const task = tasks.get(id);
|
|
1943
2466
|
if (!task)
|
|
1944
2467
|
return null;
|
|
@@ -2168,11 +2691,11 @@ export function AgentConnectionRequestCard({ request, runId, providerLabel, retr
|
|
|
2168
2691
|
: labels.connectionConnectProvider.replace("{{provider}}", () => providerName);
|
|
2169
2692
|
const description = request.detail?.trim() ||
|
|
2170
2693
|
(adminRequired && !terminal ? labels.connectionAdminRequired : undefined);
|
|
2171
|
-
return (_jsxs(Surface, { as: "section", className: "agentkit-connection-request
|
|
2694
|
+
return (_jsxs(Surface, { as: "section", className: "agentkit-connection-request", elevation: "none", padding: "none", "data-status": request.status, "aria-labelledby": `${request.id}-title`, children: [_jsxs("div", { className: "agentkit-connection-request-copy", children: [_jsx(IconPlugConnected, { "aria-hidden": "true", className: "agentkit-icon" }), _jsxs("div", { children: [_jsx("h3", { id: `${request.id}-title`, children: title }), description ? _jsx("p", { children: description }) : null] })] }), !terminal && request.reason !== "admin_required" ? (_jsxs("div", { className: "agentkit-connection-request-actions", children: [_jsx(ActionButton, { emphasis: "outline", size: "compact", disabled: resolution.pending, onPress: () => resolve("decline"), children: labels.connectionNotNow }), _jsx(ActionButton, { className: "agentkit-primary-button", intent: "primary", size: "compact", disabled: resolution.pending || (!onConnectionRequest && !onConnect), pending: resolution.pending, onPress: () => resolve("connect"), children: resolution.pending
|
|
2172
2695
|
? labels.connectionConnecting
|
|
2173
2696
|
: retry
|
|
2174
2697
|
? labels.connectionRetry
|
|
2175
|
-
: labels.connectionConnect })] })) : request.status === "failed" && (onConnectionRequest || onConnect) ? (_jsx("div", { className: "agentkit-connection-request-actions", children: _jsx(ActionButton, { emphasis: "outline", size: "compact", disabled: resolution.pending, pending: resolution.pending, onPress: () => resolve("connect"), children: labels.connectionRetry }) })) : null, resolution.error ? (_jsxs("div", { className: "agentkit-command-error", role: "alert", children: [_jsx(
|
|
2698
|
+
: labels.connectionConnect })] })) : request.status === "failed" && (onConnectionRequest || onConnect) ? (_jsx("div", { className: "agentkit-connection-request-actions", children: _jsx(ActionButton, { emphasis: "outline", size: "compact", disabled: resolution.pending, pending: resolution.pending, onPress: () => resolve("connect"), children: labels.connectionRetry }) })) : null, resolution.error ? (_jsxs("div", { className: "agentkit-command-error", role: "alert", children: [_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" }), _jsx("span", { ...SESSION_REPLAY_MASK_PROPS, children: resolution.error.message })] })) : null] }));
|
|
2176
2699
|
}
|
|
2177
2700
|
function AgentWidgetActionButton({ widget, action, threadId, }) {
|
|
2178
2701
|
const control = useAgentKitControl(threadId);
|
|
@@ -2716,20 +3239,52 @@ function AgentMessageTimestamp({ createdAt, format, }) {
|
|
|
2716
3239
|
const fallback = formatAgentMessageTimestamp(createdAt);
|
|
2717
3240
|
return (_jsx("time", { dateTime: createdAt, title: fallback.title, children: format?.(createdAt) ?? fallback.text }));
|
|
2718
3241
|
}
|
|
3242
|
+
/** Enter and Space fire a click with no pointer detail. */
|
|
3243
|
+
function pressedByKeyboard(event) {
|
|
3244
|
+
return event?.detail === 0;
|
|
3245
|
+
}
|
|
3246
|
+
/** Keyboard presses only: focusing the composer on touch opens the on-screen keyboard. */
|
|
3247
|
+
function useRescueFocusToComposer(threadId) {
|
|
3248
|
+
const { requestComposerFocus } = useAgentKit();
|
|
3249
|
+
return useCallback(() => {
|
|
3250
|
+
requestAnimationFrame(() => {
|
|
3251
|
+
const active = document.activeElement;
|
|
3252
|
+
if (!active || active === document.body)
|
|
3253
|
+
requestComposerFocus(threadId);
|
|
3254
|
+
});
|
|
3255
|
+
}, [requestComposerFocus, threadId]);
|
|
3256
|
+
}
|
|
2719
3257
|
/**
|
|
2720
3258
|
* Names an icon-only message action on hover and keyboard focus. Below the
|
|
2721
3259
|
* button, so it never covers the message it acts on.
|
|
2722
3260
|
*/
|
|
2723
|
-
function MessageActionButton({ title, ...props }) {
|
|
2724
|
-
//
|
|
2725
|
-
//
|
|
2726
|
-
|
|
2727
|
-
const inactive = Boolean(props.disabled || props.pending);
|
|
3261
|
+
function MessageActionButton({ title, busy = false, unavailable = false, icon, onPress, className, ...props }) {
|
|
3262
|
+
// Only a native title explains a disabled button, never also the tooltip. An
|
|
3263
|
+
// unavailable one stays focusable and a press opens its tooltip: taps never hover.
|
|
3264
|
+
const inactive = Boolean(props.disabled || props.pending || busy);
|
|
2728
3265
|
const reason = inactive ? undefined : title;
|
|
2729
|
-
|
|
3266
|
+
const reasonId = useId();
|
|
3267
|
+
const [tooltipOpen, setTooltipOpen] = useState(false);
|
|
3268
|
+
return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { open: tooltipOpen, onOpenChange: setTooltipOpen, content: reason ? (_jsxs(_Fragment, { children: [props.label, _jsx("span", { className: "block text-muted-foreground", children: reason })] })) : (props.label), placement: "bottom", trigger: _jsx(IconButton, { ...props, icon: busy ? (_jsx(IconLoader2, { "aria-hidden": "true", className: "animate-spin" })) : (icon), ...(unavailable
|
|
3269
|
+
? {
|
|
3270
|
+
className: `${className ?? ""} aria-disabled:cursor-default aria-disabled:opacity-50`,
|
|
3271
|
+
}
|
|
3272
|
+
: className
|
|
3273
|
+
? { className }
|
|
3274
|
+
: {}), ...(busy ? { "aria-busy": true } : {}), ...(unavailable ? { "aria-disabled": true } : {}), ...(reason ? { "aria-describedby": reasonId } : {}), onPress: (event) => {
|
|
3275
|
+
if (unavailable) {
|
|
3276
|
+
if (reason)
|
|
3277
|
+
setTooltipOpen(true);
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3280
|
+
if (busy)
|
|
3281
|
+
return;
|
|
3282
|
+
onPress?.(event);
|
|
3283
|
+
}, ...(inactive && title !== undefined ? { title } : {}) }) }), reason ? (_jsx("span", { id: reasonId, hidden: true, children: reason })) : null] }));
|
|
2730
3284
|
}
|
|
2731
3285
|
export const AgentMessageActions = memo(function AgentMessageActions({ value: message, threadId, }) {
|
|
2732
3286
|
const { controller, labels, slots, onThreadForked, onCopyMessage, branchNavigation, } = useAgentKit();
|
|
3287
|
+
const rescueFocusToComposer = useRescueFocusToComposer(threadId);
|
|
2733
3288
|
const feedbackCapability = useAgentCapability("feedback");
|
|
2734
3289
|
const forkingCapability = useAgentCapability("threadForking");
|
|
2735
3290
|
const control = useAgentKitControl(threadId);
|
|
@@ -2773,6 +3328,10 @@ export const AgentMessageActions = memo(function AgentMessageActions({ value: me
|
|
|
2773
3328
|
const feedbackConfirmedTimer = useRef(null);
|
|
2774
3329
|
const requestIdCopiedTimer = useRef(null);
|
|
2775
3330
|
const toolbarRef = useRef(null);
|
|
3331
|
+
const actionsRef = useRef(null);
|
|
3332
|
+
// One tab stop per message: the toolbar for a reply, the row for a sent message.
|
|
3333
|
+
useRovingFocus(toolbarRef, isAssistant);
|
|
3334
|
+
useRovingFocus(actionsRef, !isAssistant);
|
|
2776
3335
|
const moreToggleRef = useRef(null);
|
|
2777
3336
|
const secondaryActionsRef = useRef(null);
|
|
2778
3337
|
const pendingFocusRef = useRef(null);
|
|
@@ -2903,22 +3462,21 @@ export const AgentMessageActions = memo(function AgentMessageActions({ value: me
|
|
|
2903
3462
|
forkAction.error ??
|
|
2904
3463
|
regenerateAction.error;
|
|
2905
3464
|
const placement = isAssistant ? "inline" : undefined;
|
|
2906
|
-
const copyButton = (_jsx(MessageActionButton, { label: copied ? labels.copied : labels.copy, icon: copyAction.pending ? (_jsx(IconLoader2, { "aria-hidden": "true", className: "animate-spin" })) : copied ? (_jsx(IconCircleCheck, { "aria-hidden": "true" })) : (_jsx(IconCopy, { "aria-hidden": "true" })), size: "compact", className: "size-6", "aria-busy": copyAction.pending || undefined, onPress: () => {
|
|
3465
|
+
const copyButton = (_jsx(MessageActionButton, { label: copied ? labels.copied : labels.copy, icon: copyAction.pending ? (_jsx(IconLoader2, { "aria-hidden": "true", className: "animate-spin" })) : copied ? (_jsx(IconCircleCheck, { "aria-hidden": "true" })) : (_jsx(IconCopy, { "aria-hidden": "true" })), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", "aria-busy": copyAction.pending || undefined, onPress: () => {
|
|
2907
3466
|
if (copyAction.pending)
|
|
2908
3467
|
return;
|
|
2909
3468
|
void copyAction.execute().catch(() => undefined);
|
|
2910
3469
|
} }));
|
|
2911
3470
|
const branchControls = branchNavigation && branchNavigation.count > 1 ? (_jsxs("div", { className: "agentkit-branch-navigation", role: "group", "aria-label": labels.branchPositionLabel
|
|
2912
3471
|
.replace("{{index}}", String(branchNavigation.index))
|
|
2913
|
-
.replace("{{count}}", String(branchNavigation.count)), children: [_jsx(MessageActionButton, { label: labels.previousBranch, icon: _jsx(IconChevronLeft, { "aria-hidden": "true" }), size: "compact", className: "size-6",
|
|
3472
|
+
.replace("{{count}}", String(branchNavigation.count)), children: [_jsx(MessageActionButton, { label: labels.previousBranch, icon: _jsx(IconChevronLeft, { "aria-hidden": "true" }), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", unavailable: branchNavigation.index <= 1, busy: branchNavigationAction.pending, onPress: () => void branchNavigationAction
|
|
2914
3473
|
.execute("previous")
|
|
2915
3474
|
.catch(() => undefined) }), _jsx("span", { "aria-hidden": "true", children: labels.branchPosition
|
|
2916
3475
|
.replace("{{index}}", String(branchNavigation.index))
|
|
2917
3476
|
.replace("{{count}}", String(branchNavigation.count)) }), _jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: labels.branchPositionLabel
|
|
2918
3477
|
.replace("{{index}}", String(branchNavigation.index))
|
|
2919
|
-
.replace("{{count}}", String(branchNavigation.count)) }), _jsx(MessageActionButton, { label: labels.nextBranch, icon: _jsx(IconChevronRight, { "aria-hidden": "true" }), size: "compact", className: "size-6",
|
|
2920
|
-
|
|
2921
|
-
const toolbar = isAssistant ? (_jsxs("div", { ref: toolbarRef, className: "agentkit-message-toolbar", role: "group", "aria-label": labels.messageActions, "data-placement": placement, "data-latest": isLastAssistantMessage ? "true" : undefined, "data-streaming": message.status === "streaming" ? "true" : undefined, "data-expanded": moreActionsOpen ? "true" : undefined, onKeyDown: (event) => {
|
|
3478
|
+
.replace("{{count}}", String(branchNavigation.count)) }), _jsx(MessageActionButton, { label: labels.nextBranch, icon: _jsx(IconChevronRight, { "aria-hidden": "true" }), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", unavailable: branchNavigation.index >= branchNavigation.count, busy: branchNavigationAction.pending, onPress: () => void branchNavigationAction.execute("next").catch(() => undefined) })] })) : null;
|
|
3479
|
+
const toolbar = isAssistant ? (_jsxs("div", { ref: toolbarRef, className: "agentkit-message-toolbar", role: "toolbar", "aria-label": labels.messageActions, "data-placement": placement, "data-latest": isLastAssistantMessage ? "true" : undefined, "data-streaming": message.status === "streaming" ? "true" : undefined, "data-expanded": moreActionsOpen ? "true" : undefined, onKeyDown: (event) => {
|
|
2922
3480
|
if (event.key !== "Escape" || !moreActionsOpen)
|
|
2923
3481
|
return;
|
|
2924
3482
|
event.preventDefault();
|
|
@@ -2949,7 +3507,7 @@ export const AgentMessageActions = memo(function AgentMessageActions({ value: me
|
|
|
2949
3507
|
const chosen = feedback === value;
|
|
2950
3508
|
const renderFeedbackButton = (toggle, open, contentId) => (_jsx(MessageActionButton, { label: value === "positive"
|
|
2951
3509
|
? labels.feedbackGood
|
|
2952
|
-
: labels.feedbackBad, icon: value === "positive" ? (chosen ? (_jsx(IconThumbUpFilled, { "aria-hidden": "true" })) : (_jsx(IconThumbUp, { "aria-hidden": "true" }))) : chosen ? (_jsx(IconThumbDownFilled, { "aria-hidden": "true" })) : (_jsx(IconThumbDown, { "aria-hidden": "true" })), size: "compact", className: "size-6", "data-message-action": `feedback-${value}`, "aria-pressed": chosen, "aria-haspopup": toggle ? "dialog" : undefined, "aria-expanded": toggle ? open : undefined, "aria-controls": toggle && open ? contentId : undefined,
|
|
3510
|
+
: labels.feedbackBad, icon: value === "positive" ? (chosen ? (_jsx(IconThumbUpFilled, { "aria-hidden": "true" })) : (_jsx(IconThumbUp, { "aria-hidden": "true" }))) : chosen ? (_jsx(IconThumbDownFilled, { "aria-hidden": "true" })) : (_jsx(IconThumbDown, { "aria-hidden": "true" })), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", "data-message-action": `feedback-${value}`, "aria-pressed": chosen, "aria-haspopup": toggle ? "dialog" : undefined, "aria-expanded": toggle ? open : undefined, "aria-controls": toggle && open ? contentId : undefined, unavailable: !feedbackCapability.enabled, busy: feedbackAction.pending, ...(feedbackCapability.reason === undefined
|
|
2953
3511
|
? {}
|
|
2954
3512
|
: { title: feedbackCapability.reason }), onPress: () => {
|
|
2955
3513
|
toggle?.();
|
|
@@ -2958,30 +3516,40 @@ export const AgentMessageActions = memo(function AgentMessageActions({ value: me
|
|
|
2958
3516
|
} }, value));
|
|
2959
3517
|
return value === "negative" && slots.feedbackNote ? (_jsx(slots.feedbackNote, { threadId: threadId, ...(runId ? { runId } : {}), ...(messageSeq >= 0 ? { messageSeq } : {}), renderTrigger: renderFeedbackButton }, value)) : (renderFeedbackButton());
|
|
2960
3518
|
})
|
|
2961
|
-
: null] }), hasSecondaryActions ? (_jsxs("div", { ref: secondaryActionsRef, id: secondaryActionsId, className: "agentkit-message-actions-set", "data-set": "secondary", "data-active": moreActionsOpen ? "true" : "false", inert: !moreActionsOpen, children: [showRetry ? (_jsx(MessageActionButton, { label: labels.regenerateResponse, icon: _jsx(IconRefresh, { "aria-hidden": "true" }), size: "compact", className: "size-6", "data-message-action": "retry",
|
|
2962
|
-
position.active ||
|
|
2963
|
-
!forkingCapability.enabled, ...(forkingCapability.reason === undefined
|
|
3519
|
+
: null] }), hasSecondaryActions ? (_jsxs("div", { ref: secondaryActionsRef, id: secondaryActionsId, className: "agentkit-message-actions-set", "data-set": "secondary", "data-active": moreActionsOpen ? "true" : "false", inert: !moreActionsOpen, children: [showRetry ? (_jsx(MessageActionButton, { label: labels.regenerateResponse, icon: _jsx(IconRefresh, { "aria-hidden": "true" }), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", "data-message-action": "retry", busy: regenerateAction.pending, unavailable: position.active || !forkingCapability.enabled, ...(forkingCapability.reason === undefined
|
|
2964
3520
|
? {}
|
|
2965
|
-
: { title: forkingCapability.reason }), onPress: () =>
|
|
3521
|
+
: { title: forkingCapability.reason }), onPress: (event) => {
|
|
3522
|
+
const keyboard = pressedByKeyboard(event);
|
|
3523
|
+
void regenerateAction
|
|
3524
|
+
.execute()
|
|
3525
|
+
.catch(() => undefined)
|
|
3526
|
+
// The new response replaces this toolbar.
|
|
3527
|
+
.finally(() => {
|
|
3528
|
+
if (keyboard)
|
|
3529
|
+
rescueFocusToComposer();
|
|
3530
|
+
});
|
|
3531
|
+
} })) : null, showFork ? (_jsx(MessageActionButton, { label: labels.forkFromHere, icon: _jsx(IconArrowFork, { "aria-hidden": "true" }), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", "data-message-action": "fork", busy: forkAction.pending, unavailable: !forkingCapability.enabled, ...(forkingCapability.reason === undefined
|
|
2966
3532
|
? {}
|
|
2967
|
-
: { title: forkingCapability.reason }), onPress: () => void forkAction.execute().catch(() => undefined) })) : null, requestId ? (_jsx(MessageActionButton, { label: requestIdCopied ? labels.copied : labels.copyRequestId, icon: requestIdAction.pending ? (_jsx(IconLoader2, { "aria-hidden": "true", className: "animate-spin" })) : requestIdCopied ? (_jsx(IconCircleCheck, { "aria-hidden": "true" })) : (_jsx(IconId, { "aria-hidden": "true" })), size: "compact", className: "size-6", "data-message-action": "request-id", "aria-busy": requestIdAction.pending || undefined, onPress: () => {
|
|
3533
|
+
: { title: forkingCapability.reason }), onPress: () => void forkAction.execute().catch(() => undefined) })) : null, requestId ? (_jsx(MessageActionButton, { label: requestIdCopied ? labels.copied : labels.copyRequestId, icon: requestIdAction.pending ? (_jsx(IconLoader2, { "aria-hidden": "true", className: "animate-spin" })) : requestIdCopied ? (_jsx(IconCircleCheck, { "aria-hidden": "true" })) : (_jsx(IconId, { "aria-hidden": "true" })), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", "data-message-action": "request-id", "aria-busy": requestIdAction.pending || undefined, onPress: () => {
|
|
2968
3534
|
if (requestIdAction.pending)
|
|
2969
3535
|
return;
|
|
2970
3536
|
void requestIdAction.execute().catch(() => undefined);
|
|
2971
3537
|
} })) : null] })) : null] }), hasSecondaryActions ? (_jsx(MessageActionButton, { elementRef: moreToggleRef, label: labels.moreMessageActions, icon: _jsx(IconDots, { "aria-hidden": "true" }), size: "compact",
|
|
2972
3538
|
// Hover is lighter than open, the toolkit's menu-trigger pattern,
|
|
2973
3539
|
// so pressing it reads as a change while the pointer is still on it.
|
|
2974
|
-
className: "agentkit-message-actions-toggle size-6 hover:bg-accent/60 aria-expanded:bg-accent aria-expanded:text-foreground", "data-message-actions-toggle": "", "aria-expanded": moreActionsOpen, "aria-controls": secondaryActionsId, onPress: () => setMoreActions(!moreActionsOpen, moreActionsOpen ? "toggle" : "secondary") })) : null, _jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: feedbackConfirmed
|
|
3540
|
+
className: "agentkit-message-actions-toggle size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)] hover:bg-accent/60 aria-expanded:bg-accent aria-expanded:text-foreground", "data-message-actions-toggle": "", "aria-expanded": moreActionsOpen, "aria-controls": secondaryActionsId, onPress: () => setMoreActions(!moreActionsOpen, moreActionsOpen ? "toggle" : "secondary") })) : null, _jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: feedbackConfirmed
|
|
2975
3541
|
? labels.feedbackSubmitted
|
|
2976
|
-
: requestIdCopied
|
|
3542
|
+
: requestIdCopied || copied
|
|
2977
3543
|
? labels.copied
|
|
2978
3544
|
: "" })] })) : null;
|
|
2979
|
-
return (_jsxs("div", { className: "agentkit-message-actions", "data-role": message.role, "data-placement": placement, "data-latest": isLastAssistantMessage ? "true" : undefined, "data-streaming": message.status === "streaming" ? "true" : undefined, "data-expanded": moreActionsOpen ? "true" : undefined, "data-has-error": footerError ? "true" : undefined,
|
|
3545
|
+
return (_jsxs("div", { ref: actionsRef, className: "agentkit-message-actions", "data-role": message.role, "data-placement": placement, "data-latest": isLastAssistantMessage ? "true" : undefined, "data-streaming": message.status === "streaming" ? "true" : undefined, "data-expanded": moreActionsOpen ? "true" : undefined, "data-has-error": footerError ? "true" : undefined, ...(isAssistant
|
|
3546
|
+
? {}
|
|
3547
|
+
: { role: "toolbar", "aria-label": labels.messageActions }), children: [isAssistant ? (_jsxs(_Fragment, { children: [_jsx("div", { ref: workHostRef, className: "agentkit-message-work-host" }), toolbar] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "agentkit-message-actions-leading", children: [copyButton, editContext?.enabled &&
|
|
2980
3548
|
message.metadata?.pendingSubmission !== true &&
|
|
2981
3549
|
forkingCapability.visible &&
|
|
2982
|
-
text.trim() ? (_jsx(MessageActionButton, { label: labels.editMessage, icon: _jsx(IconPencil, { "aria-hidden": "true" }), size: "compact", className: "size-6",
|
|
3550
|
+
text.trim() ? (_jsx(MessageActionButton, { label: labels.editMessage, icon: _jsx(IconPencil, { "aria-hidden": "true" }), size: "compact", className: "size-6 rounded-[var(--agent-kit-radius-xs,0.25rem)]", unavailable: position.active || !forkingCapability.enabled, ...(forkingCapability.reason === undefined
|
|
2983
3551
|
? {}
|
|
2984
|
-
: { title: forkingCapability.reason }), "aria-pressed": editContext.message?.id === message.id, onPress: () => editContext.setMessage(message) })) : null] }), _jsx("div", { className: "agentkit-message-actions-trailing", children: message.createdAt ? (_jsx(AgentMessageTimestamp, { createdAt: message.createdAt, format: labels.formatTimestamp })) : null })] })), footerError ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-command-error", role: "alert", children: footerError.message })) : null] }));
|
|
3552
|
+
: { title: forkingCapability.reason }), "aria-pressed": editContext.message?.id === message.id, onPress: () => editContext.setMessage(message) })) : null] }), _jsx("div", { className: "agentkit-message-actions-trailing", children: message.createdAt ? (_jsx(AgentMessageTimestamp, { createdAt: message.createdAt, format: labels.formatTimestamp })) : null }), _jsx("span", { className: "agentkit-visually-hidden", "aria-live": "polite", children: copied ? labels.copied : "" })] })), footerError ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "agentkit-command-error", role: "alert", children: footerError.message })) : null] }));
|
|
2985
3553
|
});
|
|
2986
3554
|
const AgentKitPostWidgetTextContext = createContext(undefined);
|
|
2987
3555
|
function shallowEqualArrays(previous, next) {
|
|
@@ -3030,12 +3598,16 @@ export const AgentMessageView = memo(function AgentMessageView({ value: message,
|
|
|
3030
3598
|
let hasSeenWidget = false;
|
|
3031
3599
|
const renderedContent = [];
|
|
3032
3600
|
let citationRun = [];
|
|
3601
|
+
let citationParts = [];
|
|
3033
3602
|
let citationRunKey = "";
|
|
3034
3603
|
const flushCitations = () => {
|
|
3035
3604
|
if (!citationRun.length)
|
|
3036
3605
|
return;
|
|
3037
|
-
renderedContent.push(
|
|
3606
|
+
renderedContent.push(
|
|
3607
|
+
// A host citation renderer keeps the inline run it was written for.
|
|
3608
|
+
slots.citation || registry.messageParts?.citation ? (_jsx("span", { className: "agentkit-citations", children: citationRun }, `citations:${citationRunKey}`)) : (_jsx(AgentSources, { citations: citationParts }, `citations:${citationRunKey}`)));
|
|
3038
3609
|
citationRun = [];
|
|
3610
|
+
citationParts = [];
|
|
3039
3611
|
};
|
|
3040
3612
|
orderedContent.forEach((item, index) => {
|
|
3041
3613
|
const isWidget = item.type === "widget" || item.part.type === "widget";
|
|
@@ -3053,13 +3625,14 @@ export const AgentMessageView = memo(function AgentMessageView({ value: message,
|
|
|
3053
3625
|
if (!citationRun.length)
|
|
3054
3626
|
citationRunKey = item.key;
|
|
3055
3627
|
citationRun.push(_jsx(Fragment, { children: content }, item.key));
|
|
3628
|
+
citationParts.push(item.part);
|
|
3056
3629
|
return;
|
|
3057
3630
|
}
|
|
3058
3631
|
flushCitations();
|
|
3059
3632
|
renderedContent.push(followsWidget ? (_jsx("div", { "data-post-widget-text": "true", children: content }, item.key)) : (_jsx(Fragment, { children: content }, item.key)));
|
|
3060
3633
|
});
|
|
3061
3634
|
flushCitations();
|
|
3062
|
-
return (_jsxs("article", { className: "agentkit-message", "data-role": message.role, "data-message-id": message.id, "data-pending": message.metadata?.pendingSubmission === true ? "true" : undefined, "data-editing": editing ? "true" : undefined, "aria-label": message.role === "user" ? labels.you : labels.assistant, "aria-busy": message.status === "streaming", children: [_jsxs("div", { className: "agentkit-message-content", children: [renderedContent, attachedAnnotations.length ? (_jsx("div", { className: "agentkit-annotations", children: attachedAnnotations.map((annotation) => (_jsx(AgentMessagePartView, { value: { type: "annotation", annotation }, threadId: threadId }, annotation.id))) })) : null, Supplement ? (_jsx(Supplement, { value: visibleMessage, threadId: threadId })) : null] }), _jsx(Actions, { value: slots.messageActions ? visibleMessage : message, threadId: threadId })] }));
|
|
3635
|
+
return (_jsxs("article", { className: "agentkit-message", "data-role": message.role, "data-message-id": message.id, "data-pending": message.metadata?.pendingSubmission === true ? "true" : undefined, "data-editing": editing ? "true" : undefined, "aria-label": message.role === "user" ? labels.you : labels.assistant, "aria-busy": message.status === "streaming", children: [_jsx("h2", { className: "agentkit-visually-hidden", children: message.role === "user" ? labels.you : labels.assistant }), _jsxs("div", { className: "agentkit-message-content", children: [renderedContent, attachedAnnotations.length ? (_jsx("div", { className: "agentkit-annotations", children: attachedAnnotations.map((annotation) => (_jsx(AgentMessagePartView, { value: { type: "annotation", annotation }, threadId: threadId }, annotation.id))) })) : null, Supplement ? (_jsx(Supplement, { value: visibleMessage, threadId: threadId })) : null] }), _jsx(Actions, { value: slots.messageActions ? visibleMessage : message, threadId: threadId })] }));
|
|
3063
3636
|
});
|
|
3064
3637
|
function stripAgentMessageContext(message) {
|
|
3065
3638
|
const metadata = stripAgentContextMetadata(message.metadata);
|
|
@@ -3107,14 +3680,12 @@ export function AgentRunFailure({ error, runId, threadId, }) {
|
|
|
3107
3680
|
setContinueFailed(true);
|
|
3108
3681
|
});
|
|
3109
3682
|
};
|
|
3110
|
-
//
|
|
3111
|
-
|
|
3112
|
-
const ToneIcon = tone === "warning" ? IconAlertTriangle : IconAlertCircle;
|
|
3113
|
-
return (_jsxs("div", { className: "agentkit-run-failure", "data-tone": tone, "data-error-code": error.code, "data-run-id": runId, "data-thread-id": threadId, role: !superseded && latestFailure ? "alert" : undefined, children: [_jsx(ToneIcon, { "aria-hidden": "true", className: "agentkit-icon" }), _jsxs("div", { className: "agentkit-run-failure-copy", children: [_jsx("strong", { children: labels.runFailed }), _jsx("span", { ...SESSION_REPLAY_MASK_PROPS, children: error.message }), canContinue ? (_jsx("div", { className: "agentkit-error-actions", children: _jsx(ActionButton, { emphasis: "outline", size: "compact", pending: continuing, onPress: continueRun, children: labels.continueRun }) })) : null, continueFailed && !superseded ? (_jsx("span", { className: "agentkit-command-error", role: "alert", children: labels.continueRunUnavailable })) : null] })] }));
|
|
3683
|
+
// Amber, not red, even when not retryable: a failed run destroys nothing.
|
|
3684
|
+
return (_jsxs("div", { className: "agentkit-run-failure", "data-tone": "warning", "data-error-code": error.code, "data-run-id": runId, "data-thread-id": threadId, role: !superseded && latestFailure ? "alert" : undefined, children: [_jsx(IconAlertTriangle, { "aria-hidden": "true", className: "agentkit-icon" }), _jsxs("div", { className: "agentkit-run-failure-copy", children: [_jsx("strong", { children: labels.runFailed }), _jsx("span", { ...SESSION_REPLAY_MASK_PROPS, children: error.message }), canContinue ? (_jsx("div", { className: "agentkit-error-actions", children: _jsx(ActionButton, { emphasis: "outline", size: "compact", pending: continuing, onPress: continueRun, children: labels.continueRun }) })) : null, continueFailed && !superseded ? (_jsx("span", { className: "agentkit-command-error", role: "alert", children: labels.continueRunUnavailable })) : null] })] }));
|
|
3114
3685
|
}
|
|
3115
3686
|
export function AgentConnectionErrorView({ error, threadId, recover, recovering, recoveryError, dismiss, }) {
|
|
3116
3687
|
const { labels } = useAgentKit();
|
|
3117
|
-
return (_jsxs(ComposerNotice, { tone:
|
|
3688
|
+
return (_jsxs(ComposerNotice, { tone: "warning", role: "alert", noticeId: "connection-error", className: "agentkit-connection-notice", rootProps: { "data-error-code": error.code, "data-thread-id": threadId }, onDismiss: dismiss, dismissLabel: labels.dismissNotice, actions: error.retryable ? (_jsx(ActionButton, { emphasis: "outline", size: "compact", className: "h-6 px-2 text-xs", pending: recovering, onPress: () => void recover().catch(() => undefined), children: labels.reconnect })) : undefined, children: [_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, children: error.message }), recoveryError ? (_jsx("span", { ...SESSION_REPLAY_MASK_PROPS, className: "block", children: recoveryError.message })) : null] }));
|
|
3118
3689
|
}
|
|
3119
3690
|
function hasActiveRuns(thread) {
|
|
3120
3691
|
return threadHasActiveRuns(thread);
|
|
@@ -3390,7 +3961,7 @@ inlineTextAttachments = false, beforeSend, }) {
|
|
|
3390
3961
|
editContext?.setMessage(null);
|
|
3391
3962
|
focusComposer();
|
|
3392
3963
|
}, [editContext, focusComposer, initialText]);
|
|
3393
|
-
const editingRow = editingMessage ? (_jsxs("div", { role: "group", "aria-labelledby": editingLabelId, className: "agentkit-editing-row flex h-6 min-w-0 items-center gap-2 text-xs text-muted-foreground", "data-agentkit-editing-row": "true", children: [_jsx(Tooltip, { placement: "top", align: "start", trigger: _jsxs("span", { tabIndex: 0, className: "inline-flex min-w-0 items-center gap-2 rounded-
|
|
3964
|
+
const editingRow = editingMessage ? (_jsxs("div", { role: "group", "aria-labelledby": editingLabelId, className: "agentkit-editing-row flex h-6 min-w-0 items-center gap-2 text-xs text-muted-foreground", "data-agentkit-editing-row": "true", children: [_jsx(Tooltip, { placement: "top", align: "start", trigger: _jsxs("span", { tabIndex: 0, className: "inline-flex min-w-0 items-center gap-2 rounded-[var(--agent-kit-radius-xs,0.25rem)] outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx(IconPencil, { "aria-hidden": "true", className: "size-4 shrink-0" }), _jsx("span", { id: editingLabelId, className: "truncate", children: labels.editingMessage })] }), content: labels.editingMessageHint }), _jsx(ActionButton, { emphasis: "ghost", size: "compact", className: "-me-2 ms-auto h-6 shrink-0 px-2 text-xs", onPress: cancelEditing, children: labels.cancelEditing })] })) : null;
|
|
3394
3965
|
useEffect(() => registerComposerFocus(threadId, focusComposer), [focusComposer, registerComposerFocus, threadId]);
|
|
3395
3966
|
// i18n-ignore: These type-level callback property names are not visible copy.
|
|
3396
3967
|
const submitMessage = async (text, files, references, // i18n-ignore: Type-only callback tuple, not rendered copy.
|
|
@@ -3518,6 +4089,9 @@ inlineTextAttachments = false, beforeSend, }) {
|
|
|
3518
4089
|
threadId: forkedThread.id,
|
|
3519
4090
|
text: payload.text,
|
|
3520
4091
|
attachments: [...payload.attachments],
|
|
4092
|
+
...(payload.references.length
|
|
4093
|
+
? { references: [...payload.references] }
|
|
4094
|
+
: {}),
|
|
3521
4095
|
options: payload.options,
|
|
3522
4096
|
metadata: sendMetadata,
|
|
3523
4097
|
onLocalSubmit,
|
|
@@ -3559,6 +4133,9 @@ inlineTextAttachments = false, beforeSend, }) {
|
|
|
3559
4133
|
const message = {
|
|
3560
4134
|
text: payload.text,
|
|
3561
4135
|
attachments: [...payload.attachments],
|
|
4136
|
+
...(payload.references.length
|
|
4137
|
+
? { references: [...payload.references] }
|
|
4138
|
+
: {}),
|
|
3562
4139
|
options: payload.options,
|
|
3563
4140
|
metadata: sendMetadata,
|
|
3564
4141
|
queueWhileRunning,
|
|
@@ -3857,6 +4434,8 @@ const AGENTKIT_HISTORY_ROW_CHUNK = 16;
|
|
|
3857
4434
|
const AGENTKIT_TRANSCRIPT_SCROLLBAR_IDLE_MS = 900;
|
|
3858
4435
|
/** Outlasts the reveal's bounded drain after a run ends. */
|
|
3859
4436
|
const AGENTKIT_TRANSCRIPT_GLIDE_AFTER_RUN_MS = 2_000;
|
|
4437
|
+
/** How much of the previous turn shows above an anchored message. */
|
|
4438
|
+
const AGENTKIT_TURN_ANCHOR_PEEK_PX = 32;
|
|
3860
4439
|
const AGENTKIT_TRANSCRIPT_SCROLL_KEYS = new Set([
|
|
3861
4440
|
"ArrowDown",
|
|
3862
4441
|
"ArrowUp",
|
|
@@ -3866,13 +4445,14 @@ const AGENTKIT_TRANSCRIPT_SCROLL_KEYS = new Set([
|
|
|
3866
4445
|
"PageUp",
|
|
3867
4446
|
" ",
|
|
3868
4447
|
]);
|
|
3869
|
-
|
|
4448
|
+
// Long enough for a screen reader to finish speaking between step names.
|
|
4449
|
+
const AGENTKIT_ACTIVITY_ANNOUNCE_INTERVAL_MS = 10_000;
|
|
3870
4450
|
export function isAgentKitTranscriptNearBottom(element, threshold = AGENTKIT_TRANSCRIPT_BOTTOM_THRESHOLD) {
|
|
3871
4451
|
return (element.scrollHeight - element.clientHeight - element.scrollTop <= threshold);
|
|
3872
4452
|
}
|
|
3873
4453
|
/** Layout-matching placeholder for a conversation whose history is loading. */
|
|
3874
4454
|
export function AgentKitTranscriptSkeleton({ label = defaultAgentKitLabels.loadingConversation, className, }) {
|
|
3875
|
-
return (_jsxs("div", { className: `agentkit-transcript-skeleton ${className ?? ""}`, role: "status", "aria-busy": "true", children: [_jsx("span", { className: "agentkit-visually-hidden", children: label }), _jsx("div", { className: "agentkit-transcript-skeleton-user", "aria-hidden": "true", children: _jsx(Skeleton, { className: "agentkit-transcript-skeleton-bubble ms-auto h-
|
|
4455
|
+
return (_jsxs("div", { className: `agentkit-transcript-skeleton ${className ?? ""}`, role: "status", "aria-busy": "true", children: [_jsx("span", { className: "agentkit-visually-hidden", children: label }), _jsx("div", { className: "agentkit-transcript-skeleton-user", "aria-hidden": "true", children: _jsx(Skeleton, { className: "agentkit-transcript-skeleton-bubble ms-auto h-11 w-2/5 rounded-[var(--agent-kit-radius-sm,0.5rem)]" }) }), _jsxs("div", { className: "agentkit-transcript-skeleton-assistant", "aria-hidden": "true", children: [_jsx(Skeleton, { className: "agentkit-transcript-skeleton-line h-4 w-full" }), _jsx(Skeleton, { className: "agentkit-transcript-skeleton-line h-4 w-11/12" }), _jsx(Skeleton, { className: "agentkit-transcript-skeleton-line h-4 w-3/5" })] })] }));
|
|
3876
4456
|
}
|
|
3877
4457
|
function AgentThreadUnavailable({ onStartNewChat, }) {
|
|
3878
4458
|
const { labels } = useAgentKit();
|
|
@@ -3914,6 +4494,14 @@ function currentRunActivityLabel(thread, runId, labels) {
|
|
|
3914
4494
|
}
|
|
3915
4495
|
return labels.working;
|
|
3916
4496
|
}
|
|
4497
|
+
// A run that stops to wait on the user is as much news as one that ends.
|
|
4498
|
+
const RUN_STATUS_ANNOUNCEMENTS = {
|
|
4499
|
+
completed: "responseReady",
|
|
4500
|
+
failed: "responseFailed",
|
|
4501
|
+
cancelled: "runStopped",
|
|
4502
|
+
awaiting_approval: "waitingForApproval",
|
|
4503
|
+
awaiting_input: "waitingForInput",
|
|
4504
|
+
};
|
|
3917
4505
|
/**
|
|
3918
4506
|
* One polite status region for the whole chat. The transcript itself stays
|
|
3919
4507
|
* aria-live="off": streamed text would otherwise be read token by token.
|
|
@@ -3924,6 +4512,8 @@ function AgentKitLiveStatus({ threadId }) {
|
|
|
3924
4512
|
const runId = latestRunId(thread);
|
|
3925
4513
|
const run = runId ? thread.runs[runId] : undefined;
|
|
3926
4514
|
const status = run?.status;
|
|
4515
|
+
// A failure with an error has its own alert; announcing it here reads it twice.
|
|
4516
|
+
const failureHasAlert = status === "failed" && Boolean(run?.error);
|
|
3927
4517
|
const running = status === "running";
|
|
3928
4518
|
const activityText = running && runId ? currentRunActivityLabel(thread, runId, labels) : "";
|
|
3929
4519
|
const [announcement, setAnnouncement] = useState("");
|
|
@@ -3940,14 +4530,16 @@ function AgentKitLiveStatus({ threadId }) {
|
|
|
3940
4530
|
if (!runId || previous.runId !== runId || previous.status === status) {
|
|
3941
4531
|
return;
|
|
3942
4532
|
}
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
4533
|
+
const announced = status ? RUN_STATUS_ANNOUNCEMENTS[status] : undefined;
|
|
4534
|
+
if (!announced)
|
|
4535
|
+
return;
|
|
4536
|
+
if (pendingTimerRef.current)
|
|
4537
|
+
clearTimeout(pendingTimerRef.current);
|
|
4538
|
+
pendingTimerRef.current = undefined;
|
|
4539
|
+
lastAnnouncedAtRef.current = Date.now();
|
|
4540
|
+
// Cleared rather than left on the last step name, which is stale now.
|
|
4541
|
+
setAnnouncement(failureHasAlert ? "" : labels[announced]);
|
|
4542
|
+
}, [failureHasAlert, labels, runId, status]);
|
|
3951
4543
|
useEffect(() => {
|
|
3952
4544
|
if (!activityText)
|
|
3953
4545
|
return;
|
|
@@ -3975,8 +4567,8 @@ function isTerminalRunStatus(status) {
|
|
|
3975
4567
|
export function AgentKitEmptyState({ text, children, className, }) {
|
|
3976
4568
|
return (_jsxs("div", { className: `agentkit-empty-state ${className ?? ""}`, "data-agentkit-empty-state": "true", children: [_jsx("p", { className: "agentkit-empty-state-greeting", children: text }), children] }));
|
|
3977
4569
|
}
|
|
3978
|
-
export function AgentKitChat({ title, toolbar, composer = true, composerProps, hasRenderedMessages = false, emptyComposerPlacement = "center", autoScroll = true, transcriptLayout, expectExistingThread, onStartNewChat, className, }) {
|
|
3979
|
-
const { controller, threadId, slots, registry, labels, onThreadForked, threadLoad, formatWorkedForDuration, } = useAgentKit();
|
|
4570
|
+
export function AgentKitChat({ title, toolbar, composer = true, composerProps, hasRenderedMessages = false, emptyComposerPlacement = "center", autoScroll = true, anchorTurns = true, transcriptLayout, expectExistingThread, onStartNewChat, className, }) {
|
|
4571
|
+
const { controller, threadId, slots, registry, labels, onThreadForked, threadLoad, formatWorkedForDuration, requestComposerFocus, } = useAgentKit();
|
|
3980
4572
|
const formatReasoningDuration = (ms) => formatWorkedForDuration?.(ms) ??
|
|
3981
4573
|
formatAgentKitDuration(ms, {
|
|
3982
4574
|
hour: labels.durationHourShort,
|
|
@@ -4045,6 +4637,9 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4045
4637
|
}, [threadId]);
|
|
4046
4638
|
useRealtimeVoiceTranscripts(controller, threadId, hasActiveRuns(thread));
|
|
4047
4639
|
const transcriptContentRef = useRef(null);
|
|
4640
|
+
const turnSpacerRef = useRef(null);
|
|
4641
|
+
// Set by a message sent in this thread; a thread that opens has no anchor.
|
|
4642
|
+
const turnAnchoredRef = useRef(false);
|
|
4048
4643
|
const fileDragDepthRef = useRef(0);
|
|
4049
4644
|
const followsTranscriptRef = useRef(true);
|
|
4050
4645
|
const programmaticScrollTopRef = useRef(undefined);
|
|
@@ -4212,7 +4807,35 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4212
4807
|
setTranscriptScrollbarVisible(true);
|
|
4213
4808
|
scheduleTranscriptScrollbarHide();
|
|
4214
4809
|
}, [scheduleTranscriptScrollbarHide]);
|
|
4810
|
+
// The spacer pads what the reply has not filled, so following the bottom holds
|
|
4811
|
+
// the sent message near the top. Sized imperatively so streaming never re-renders.
|
|
4812
|
+
const updateTurnSpacer = useCallback(() => {
|
|
4813
|
+
const transcript = transcriptRef.current;
|
|
4814
|
+
const content = transcriptContentRef.current;
|
|
4815
|
+
const spacer = turnSpacerRef.current;
|
|
4816
|
+
if (!transcript || !content || !spacer)
|
|
4817
|
+
return;
|
|
4818
|
+
// No stylesheet may size the spacer: its inline height is read back as-is.
|
|
4819
|
+
const current = Number.parseFloat(spacer.style.blockSize) || 0;
|
|
4820
|
+
const rows = content.querySelectorAll('.agentkit-message[data-role="user"]');
|
|
4821
|
+
const row = rows.length ? rows[rows.length - 1] : undefined;
|
|
4822
|
+
if (!anchorTurns || !turnAnchoredRef.current || !row) {
|
|
4823
|
+
if (current)
|
|
4824
|
+
spacer.style.blockSize = "";
|
|
4825
|
+
return;
|
|
4826
|
+
}
|
|
4827
|
+
const rowTop = row.getBoundingClientRect().top -
|
|
4828
|
+
transcript.getBoundingClientRect().top +
|
|
4829
|
+
transcript.scrollTop;
|
|
4830
|
+
const anchorTop = Math.max(0, rowTop - AGENTKIT_TURN_ANCHOR_PEEK_PX);
|
|
4831
|
+
const next = Math.max(0, Math.ceil(anchorTop +
|
|
4832
|
+
transcript.clientHeight -
|
|
4833
|
+
(transcript.scrollHeight - current)));
|
|
4834
|
+
if (next !== current)
|
|
4835
|
+
spacer.style.blockSize = next ? `${next}px` : "";
|
|
4836
|
+
}, [anchorTurns]);
|
|
4215
4837
|
const scrollTranscriptToBottom = useCallback(() => {
|
|
4838
|
+
updateTurnSpacer();
|
|
4216
4839
|
const transcript = transcriptRef.current;
|
|
4217
4840
|
if (!autoScroll || !transcript || !followsTranscriptRef.current)
|
|
4218
4841
|
return;
|
|
@@ -4220,13 +4843,14 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4220
4843
|
if (Math.abs(transcript.scrollTop - nextScrollTop) <= 1)
|
|
4221
4844
|
return;
|
|
4222
4845
|
writeTranscriptScrollTop(transcript, nextScrollTop);
|
|
4223
|
-
}, [autoScroll, writeTranscriptScrollTop]);
|
|
4846
|
+
}, [autoScroll, updateTurnSpacer, writeTranscriptScrollTop]);
|
|
4224
4847
|
const stopTranscriptGlide = useCallback(() => {
|
|
4225
4848
|
transcriptGlideRef.current?.glide.stop();
|
|
4226
4849
|
}, []);
|
|
4227
4850
|
// Streamed growth glides to the new bottom; anything else (opening a
|
|
4228
4851
|
// thread, a long jump) lands there at once instead of gliding through it.
|
|
4229
4852
|
const followTranscriptToBottom = useCallback(() => {
|
|
4853
|
+
updateTurnSpacer();
|
|
4230
4854
|
const transcript = transcriptRef.current;
|
|
4231
4855
|
if (!autoScroll || !transcript || !followsTranscriptRef.current)
|
|
4232
4856
|
return;
|
|
@@ -4244,7 +4868,22 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4244
4868
|
transcriptGlideRef.current = {
|
|
4245
4869
|
element: transcript,
|
|
4246
4870
|
glide: new TranscriptGlide({
|
|
4247
|
-
|
|
4871
|
+
// Size the spacer first so an anchored message holds still as the reply grows.
|
|
4872
|
+
element: {
|
|
4873
|
+
get scrollTop() {
|
|
4874
|
+
return transcript.scrollTop;
|
|
4875
|
+
},
|
|
4876
|
+
set scrollTop(value) {
|
|
4877
|
+
transcript.scrollTop = value;
|
|
4878
|
+
},
|
|
4879
|
+
get scrollHeight() {
|
|
4880
|
+
updateTurnSpacer();
|
|
4881
|
+
return transcript.scrollHeight;
|
|
4882
|
+
},
|
|
4883
|
+
get clientHeight() {
|
|
4884
|
+
return transcript.clientHeight;
|
|
4885
|
+
},
|
|
4886
|
+
},
|
|
4248
4887
|
write: (scrollTop) => writeTranscriptScrollTop(transcript, scrollTop),
|
|
4249
4888
|
following: () => followsTranscriptRef.current,
|
|
4250
4889
|
}),
|
|
@@ -4255,6 +4894,7 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4255
4894
|
autoScroll,
|
|
4256
4895
|
scrollTranscriptToBottom,
|
|
4257
4896
|
stopTranscriptGlide,
|
|
4897
|
+
updateTurnSpacer,
|
|
4258
4898
|
writeTranscriptScrollTop,
|
|
4259
4899
|
]);
|
|
4260
4900
|
useEffect(() => {
|
|
@@ -4340,6 +4980,7 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4340
4980
|
if (transcriptThreadIdRef.current !== threadId) {
|
|
4341
4981
|
transcriptThreadIdRef.current = threadId;
|
|
4342
4982
|
previousLastMessageIdRef.current = undefined;
|
|
4983
|
+
turnAnchoredRef.current = false;
|
|
4343
4984
|
transcriptGlidesUntilRef.current = 0;
|
|
4344
4985
|
jumps = true;
|
|
4345
4986
|
setTranscriptFollow(true);
|
|
@@ -4353,6 +4994,9 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4353
4994
|
if (lastMessage?.role === "user" &&
|
|
4354
4995
|
lastMessage.id !== previousLastMessageId) {
|
|
4355
4996
|
jumps = true;
|
|
4997
|
+
// Only a send anchors: the first render of an opened thread is not one.
|
|
4998
|
+
if (previousLastMessageId !== undefined)
|
|
4999
|
+
turnAnchoredRef.current = true;
|
|
4356
5000
|
setTranscriptFollow(true);
|
|
4357
5001
|
hideTranscriptScrollbar();
|
|
4358
5002
|
}
|
|
@@ -4375,6 +5019,28 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
4375
5019
|
stopTranscriptGlide,
|
|
4376
5020
|
threadId,
|
|
4377
5021
|
]);
|
|
5022
|
+
// Anchor from the pending submission so the message never lands at the bottom first.
|
|
5023
|
+
const newestPendingSubmissionId = pendingSubmissions.at(-1)?.id;
|
|
5024
|
+
const previousPendingSubmissionIdRef = useRef(newestPendingSubmissionId);
|
|
5025
|
+
useLayoutEffect(() => {
|
|
5026
|
+
const previous = previousPendingSubmissionIdRef.current;
|
|
5027
|
+
previousPendingSubmissionIdRef.current = newestPendingSubmissionId;
|
|
5028
|
+
if (!autoScroll ||
|
|
5029
|
+
!newestPendingSubmissionId ||
|
|
5030
|
+
newestPendingSubmissionId === previous) {
|
|
5031
|
+
return;
|
|
5032
|
+
}
|
|
5033
|
+
turnAnchoredRef.current = true;
|
|
5034
|
+
setTranscriptFollow(true);
|
|
5035
|
+
stopTranscriptGlide();
|
|
5036
|
+
scrollTranscriptToBottom();
|
|
5037
|
+
}, [
|
|
5038
|
+
autoScroll,
|
|
5039
|
+
newestPendingSubmissionId,
|
|
5040
|
+
scrollTranscriptToBottom,
|
|
5041
|
+
setTranscriptFollow,
|
|
5042
|
+
stopTranscriptGlide,
|
|
5043
|
+
]);
|
|
4378
5044
|
useLayoutEffect(() => {
|
|
4379
5045
|
const transcript = transcriptRef.current;
|
|
4380
5046
|
const content = transcriptContentRef.current;
|
|
@@ -5021,10 +5687,19 @@ export function AgentKitChat({ title, toolbar, composer = true, composerProps, h
|
|
|
5021
5687
|
observer.disconnect();
|
|
5022
5688
|
};
|
|
5023
5689
|
}, [hiddenHistoryRows, writeTranscriptScrollTop]);
|
|
5024
|
-
return (_jsx(ComposerNoticeScope, { children: _jsx(AgentMessageEditContext.Provider, { value: messageEditContext, children: _jsx(AgentMessageWorkHostsContext.Provider, { value: messageWorkHosts, children: _jsx(AgentKitTranscriptFollowContext.Provider, { value: followTranscriptOnSubmit, children: _jsxs("section", { "aria-label": typeof title === "string" ? title : undefined, className: `agentkit-chat ${className ?? ""}`, "data-empty": showEmptyState, "data-has-header": hasHeader, "data-empty-composer-placement": showEmptyState ? emptyComposerPlacement : "bottom", style: chatLaneStyle(transcriptLayout), onDragEnter: handleFileDragEnter, onDragOver: handleFileDragOver, onDragLeave: handleFileDragLeave, onDropCapture: handleFileDropCapture, onDrop: handleFileDrop, children: [fileDragActive ? (_jsx("div", { className: "agentkit-file-drop-overlay", role: "status", children: labels.dropFilesToAttach })) : null, hasHeader ? (_jsx(AgentKitSurfaceBoundary, { surface: "header", resetKey: threadId, children: _jsx(AgentKitRegionSlot, { slot: Header, threadId: threadId, children: _jsxs("header", { className: "agentkit-chat-header", "data-agentkit-region": "header", "data-agentkit-chat-header": "true", "data-has-title": showTitle, children: [showTitle ? (_jsx("div", { className: "agentkit-chat-title", children: title })) : null, toolbar ? (_jsx(AgentKitRegionSlot, { slot: Toolbar, threadId: threadId, children: _jsx("div", {
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5690
|
+
return (_jsx(ComposerNoticeScope, { children: _jsx(AgentMessageEditContext.Provider, { value: messageEditContext, children: _jsx(AgentMessageWorkHostsContext.Provider, { value: messageWorkHosts, children: _jsx(AgentKitTranscriptFollowContext.Provider, { value: followTranscriptOnSubmit, children: _jsxs("section", { "aria-label": typeof title === "string" ? title : undefined, className: `agentkit-chat ${className ?? ""}`, "data-empty": showEmptyState, "data-has-header": hasHeader, "data-empty-composer-placement": showEmptyState ? emptyComposerPlacement : "bottom", style: chatLaneStyle(transcriptLayout), onDragEnter: handleFileDragEnter, onDragOver: handleFileDragOver, onDragLeave: handleFileDragLeave, onDropCapture: handleFileDropCapture, onDrop: handleFileDrop, children: [fileDragActive ? (_jsx("div", { className: "agentkit-file-drop-overlay", role: "status", children: labels.dropFilesToAttach })) : null, hasHeader ? (_jsx(AgentKitSurfaceBoundary, { surface: "header", resetKey: threadId, children: _jsx(AgentKitRegionSlot, { slot: Header, threadId: threadId, children: _jsxs("header", { className: "agentkit-chat-header", "data-agentkit-region": "header", "data-agentkit-chat-header": "true", "data-has-title": showTitle, children: [showTitle ? (_jsx("div", { className: "agentkit-chat-title", children: title })) : null, toolbar ? (_jsx(AgentKitRegionSlot, { slot: Toolbar, threadId: threadId, children: _jsx("div", {
|
|
5691
|
+
// Host buttons carry the primitive's own radius
|
|
5692
|
+
// utility, which beats layered CSS.
|
|
5693
|
+
className: "agentkit-chat-toolbar [&_:is(button,[role=button])]:rounded-[var(--agentkit-radius-xs)]", children: toolbar }) })) : null] }) }) })) : null, composer && !showEmptyState ? (_jsx("button", { type: "button", className: "agentkit-skip-link", "data-agentkit-skip-link": "composer", onClick: () => requestComposerFocus(threadId), children: labels.skipToComposer })) : null, _jsx("div", { ref: transcriptRef, className: "agentkit-transcript", role: "region", "aria-label": labels.conversation, "aria-live": "off", tabIndex: 0, "data-follow": "true", "data-scrollbar-visible": transcriptScrollbarVisible, onKeyDown: handleTranscriptKeyDown, onPointerDown: handleTranscriptPointerDown, onScroll: handleTranscriptScroll, onTouchMove: revealTranscriptScrollbar, onWheel: revealTranscriptScrollbar, children: _jsxs("div", { ref: transcriptContentRef, className: "agentkit-transcript-content", "data-lane-offset-mode": transcriptLayout?.messageLaneOffsetMode ?? "clamped", style: transcriptContentStyle(transcriptLayout), children: [_jsxs(AgentKitRegionSlot, { slot: Transcript, threadId: threadId, children: [threadLoading ? (_jsx(AgentKitTranscriptSkeleton, { label: labels.loadingConversation })) : threadMissing ? (ThreadUnavailable ? (_jsx(ThreadUnavailable, { threadId: threadId })) : (_jsx(AgentThreadUnavailable, { onStartNewChat: onStartNewChat }))) : threadLoadFailed ? (_jsx(AgentThreadLoadFailed, { retry: hostLoadRetry ??
|
|
5694
|
+
(() => void recovery.execute().catch(() => undefined)), retrying: hostLoadRetry ? false : recovery.pending, retryError: hostLoadRetry ? undefined : recovery.error })) : showEmptyState ? (EmptyState ? (_jsx(EmptyState, { threadId: threadId })) : (_jsx(AgentKitEmptyState, { text: labels.emptyStateText }))) : null, _jsx(AgentKitPostWidgetTextContext.Provider, { value: transcriptLayout?.postWidgetText, children: _jsx(AgentKitDeferClosedContentContext.Provider, { value: longHistory, children: renderedTranscriptItems }) }), approvalEntries.map(([approvalId, request]) => (_jsx(AgentKitSurfaceBoundary, { surface: "approval", resetKey: `${approvalId}:${runRevision(thread.approvalRunIds[approvalId] ?? "")}`, children: Approval ? (_jsx(Approval, { value: request, threadId: threadId, runId: thread.approvalRunIds[approvalId] ?? "" })) : (_jsx(AgentApprovalPrompt, { request: request, runId: thread.approvalRunIds[approvalId] ?? "" })) }, `${threadId}:${approvalId}`))), connectionRequestEntries.map(([requestId, request]) => (_jsx(AgentKitSurfaceBoundary, { surface: "connection-request", resetKey: `${requestId}:${request.status}`, children: ConnectionRequest ? (_jsx(ConnectionRequest, { value: request, threadId: threadId, runId: thread.connectionRequestRunIds[requestId] ?? "" })) : (_jsx(AgentConnectionRequestCard, { request: request, runId: thread.connectionRequestRunIds[requestId] ?? "" })) }, `${threadId}:${requestId}`))), visibleConnectionError ? (_jsx(AgentKitSurfaceBoundary, { surface: "connection-error", resetKey: `${threadId}:${visibleConnectionError.code}`, children: _jsx(ErrorState, { error: visibleConnectionError, threadId: threadId, recover: recovery.execute, recovering: recovery.pending, ...(recovery.error === undefined
|
|
5695
|
+
? {}
|
|
5696
|
+
: { recoveryError: recovery.error }), dismiss: clearConnectionNotice }) })) : null] }), _jsx("div", { ref: turnSpacerRef, className: "agentkit-turn-spacer", "aria-hidden": "true" })] }) }), _jsx("div", { className: "agentkit-scroll-to-bottom-control", "data-visible": transcriptAwayFromBottom ? "true" : "false", "aria-hidden": transcriptAwayFromBottom ? undefined : true, inert: !transcriptAwayFromBottom, children: _jsx(IconButton, { label: labels.scrollToBottom, icon: _jsx(IconArrowDown, { "aria-hidden": "true" }), size: "compact", className: "rounded-[var(--agent-kit-radius-sm,0.5rem)] border border-[color:var(--agentkit-border)] bg-(--agentkit-surface) text-[color:var(--agentkit-text)] shadow-(--agent-kit-overlay-elevation) hover:bg-(--agentkit-subtle) hover:text-[color:var(--agentkit-text)]", onPress: (event) => {
|
|
5697
|
+
returnTranscriptToBottom();
|
|
5698
|
+
// The control goes inert at the bottom, which would drop
|
|
5699
|
+
// a keyboard user's focus to the page.
|
|
5700
|
+
if (pressedByKeyboard(event))
|
|
5701
|
+
requestComposerFocus(threadId);
|
|
5702
|
+
} }) }), _jsx(AgentKitLiveStatus, { threadId: threadId }), composer ? (_jsx("footer", { className: "agentkit-chat-footer", children: _jsx(AgentKitSurfaceBoundary, { surface: "composer", resetKey: threadId, children: _jsx(AgentKitRegionSlot, { slot: Footer, threadId: threadId, children: slots.composer ? (_jsx(Composer, { threadId: threadId })) : (_jsx(AgentKitComposer, { ...composerProps, threadId: threadId })) }) }) })) : null] }) }) }) }) }));
|
|
5028
5703
|
}
|
|
5029
5704
|
export { useAgentKitStopButton } from "./stop-button.js";
|
|
5030
5705
|
//# sourceMappingURL=components.js.map
|