@flanksource/clicky-ui 0.3.44 → 0.3.46
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/README.md +24 -0
- package/dist/ai.cjs +4 -2
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +3 -1
- package/dist/components/MdxEditorField.cjs +40 -22
- package/dist/components/MdxEditorField.cjs.map +1 -1
- package/dist/components/MdxEditorField.d.ts.map +1 -1
- package/dist/components/MdxEditorField.js +41 -23
- package/dist/components/MdxEditorField.js.map +1 -1
- package/dist/components/json-schema-form-item-summary.cjs +6 -1
- package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
- package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
- package/dist/components/json-schema-form-item-summary.js +6 -1
- package/dist/components/json-schema-form-item-summary.js.map +1 -1
- package/dist/data/AccessMark.cjs +23 -0
- package/dist/data/AccessMark.cjs.map +1 -0
- package/dist/data/AccessMark.d.ts +11 -0
- package/dist/data/AccessMark.d.ts.map +1 -0
- package/dist/data/AccessMark.js +23 -0
- package/dist/data/AccessMark.js.map +1 -0
- package/dist/data/CodeBlock.cjs +3 -2
- package/dist/data/CodeBlock.cjs.map +1 -1
- package/dist/data/CodeBlock.d.ts +3 -1
- package/dist/data/CodeBlock.d.ts.map +1 -1
- package/dist/data/CodeBlock.js +3 -2
- package/dist/data/CodeBlock.js.map +1 -1
- package/dist/data/CodeDiff.cjs +116 -23
- package/dist/data/CodeDiff.cjs.map +1 -1
- package/dist/data/CodeDiff.d.ts +26 -0
- package/dist/data/CodeDiff.d.ts.map +1 -1
- package/dist/data/CodeDiff.js +116 -23
- package/dist/data/CodeDiff.js.map +1 -1
- package/dist/data/GraphDiagram.cjs +75 -11
- package/dist/data/GraphDiagram.cjs.map +1 -1
- package/dist/data/GraphDiagram.d.ts +17 -2
- package/dist/data/GraphDiagram.d.ts.map +1 -1
- package/dist/data/GraphDiagram.js +76 -12
- package/dist/data/GraphDiagram.js.map +1 -1
- package/dist/data/GraphDiagramGroups.cjs +100 -0
- package/dist/data/GraphDiagramGroups.cjs.map +1 -0
- package/dist/data/GraphDiagramGroups.d.ts +24 -0
- package/dist/data/GraphDiagramGroups.d.ts.map +1 -0
- package/dist/data/GraphDiagramGroups.js +100 -0
- package/dist/data/GraphDiagramGroups.js.map +1 -0
- package/dist/data/GraphDiagramNodes.cjs +46 -51
- package/dist/data/GraphDiagramNodes.cjs.map +1 -1
- package/dist/data/GraphDiagramNodes.d.ts +8 -9
- package/dist/data/GraphDiagramNodes.d.ts.map +1 -1
- package/dist/data/GraphDiagramNodes.js +46 -51
- package/dist/data/GraphDiagramNodes.js.map +1 -1
- package/dist/data/JsonView.cjs +118 -49
- package/dist/data/JsonView.cjs.map +1 -1
- package/dist/data/JsonView.d.ts +13 -10
- package/dist/data/JsonView.d.ts.map +1 -1
- package/dist/data/JsonView.js +118 -49
- package/dist/data/JsonView.js.map +1 -1
- package/dist/data/MarkdownEditor.cjs +2 -2
- package/dist/data/MarkdownEditor.cjs.map +1 -1
- package/dist/data/MarkdownEditor.js +2 -2
- package/dist/data/MarkdownEditor.js.map +1 -1
- package/dist/data/TreeNode.cjs +1 -1
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +1 -1
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.cjs +90 -249
- package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.d.ts +2 -5
- package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.js +91 -250
- package/dist/data/ai/AdvancedChatConfig.js.map +1 -1
- package/dist/data/ai/ChatButton.cjs +2 -0
- package/dist/data/ai/ChatButton.cjs.map +1 -1
- package/dist/data/ai/ChatButton.d.ts +1 -1
- package/dist/data/ai/ChatButton.d.ts.map +1 -1
- package/dist/data/ai/ChatButton.js +2 -0
- package/dist/data/ai/ChatButton.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +5 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.d.ts +5 -1
- package/dist/data/ai/ChatFab.d.ts.map +1 -1
- package/dist/data/ai/ChatFab.js +5 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +2 -8
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +2 -8
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.cjs +0 -5
- package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.d.ts +0 -2
- package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.js +0 -5
- package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs +2 -2
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.js +2 -2
- package/dist/data/ai/PromptRunEditor/runtimeActions.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.cjs +3 -6
- package/dist/data/ai/SessionInspector.approvals.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.js +3 -6
- package/dist/data/ai/SessionInspector.approvals.js.map +1 -1
- package/dist/data/ai/SessionViewer.cjs +13 -4
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +5 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.header.cjs +1 -1
- package/dist/data/ai/SessionViewer.header.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.header.js +1 -1
- package/dist/data/ai/SessionViewer.header.js.map +1 -1
- package/dist/data/ai/SessionViewer.js +13 -4
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.model.cjs +2 -0
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +1 -0
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js +2 -0
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.rows.cjs +41 -27
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts +4 -2
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +41 -27
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SessionViewer.tokens.cjs +35 -0
- package/dist/data/ai/SessionViewer.tokens.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tokens.d.ts +5 -0
- package/dist/data/ai/SessionViewer.tokens.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tokens.js +35 -0
- package/dist/data/ai/SessionViewer.tokens.js.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.cjs +128 -0
- package/dist/data/ai/SessionViewer.tool-cost.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.d.ts +6 -0
- package/dist/data/ai/SessionViewer.tool-cost.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.js +128 -0
- package/dist/data/ai/SessionViewer.tool-cost.js.map +1 -0
- package/dist/data/ai/SessionViewer.tool-details.cjs +3 -1
- package/dist/data/ai/SessionViewer.tool-details.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-details.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-details.js +3 -1
- package/dist/data/ai/SessionViewer.tool-details.js.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.cjs +55 -35
- package/dist/data/ai/SessionViewer.tool-row.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts +2 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.js +55 -35
- package/dist/data/ai/SessionViewer.tool-row.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +4 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.cjs +18 -1
- package/dist/data/ai/SessionViewerMenu.cjs.map +1 -1
- package/dist/data/ai/SessionViewerMenu.d.ts +6 -1
- package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.js +18 -1
- package/dist/data/ai/SessionViewerMenu.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +149 -143
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts +20 -6
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +151 -146
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/ToolPreferences.model.cjs +14 -10
- package/dist/data/ai/ToolPreferences.model.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.model.d.ts +1 -0
- package/dist/data/ai/ToolPreferences.model.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.model.js +15 -11
- package/dist/data/ai/ToolPreferences.model.js.map +1 -1
- package/dist/data/ai/ToolPreferencesList.cjs +1 -0
- package/dist/data/ai/ToolPreferencesList.cjs.map +1 -1
- package/dist/data/ai/ToolPreferencesList.d.ts +4 -1
- package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferencesList.js +2 -1
- package/dist/data/ai/ToolPreferencesList.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.cjs +52 -53
- package/dist/data/ai/ToolSchemaBrowser.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.d.ts +6 -3
- package/dist/data/ai/ToolSchemaBrowser.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs +9 -13
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts +5 -2
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js +9 -13
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.js +53 -54
- package/dist/data/ai/ToolSchemaBrowser.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.cjs +19 -27
- package/dist/data/ai/ToolSchemaBrowser.model.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts +9 -6
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.js +20 -28
- package/dist/data/ai/ToolSchemaBrowser.model.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs +12 -213
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts +1 -3
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js +13 -214
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.strategies.cjs +54 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.d.ts +9 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.js +54 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.cjs +179 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.d.ts +20 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.js +179 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.js.map +1 -0
- package/dist/data/ai/index.d.ts +2 -2
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.cjs +8 -28
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.cjs.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.d.ts.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.js +9 -29
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.js.map +1 -1
- package/dist/data/ai/session-token-sizing.d.ts +32 -0
- package/dist/data/ai/session-token-sizing.d.ts.map +1 -0
- package/dist/data/ai/use-session-token-sizing.cjs +73 -0
- package/dist/data/ai/use-session-token-sizing.cjs.map +1 -0
- package/dist/data/ai/use-session-token-sizing.d.ts +21 -0
- package/dist/data/ai/use-session-token-sizing.d.ts.map +1 -0
- package/dist/data/ai/use-session-token-sizing.js +73 -0
- package/dist/data/ai/use-session-token-sizing.js.map +1 -0
- package/dist/data/call-graph/CallGraph.cjs +269 -0
- package/dist/data/call-graph/CallGraph.cjs.map +1 -0
- package/dist/data/call-graph/CallGraph.d.ts +78 -0
- package/dist/data/call-graph/CallGraph.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraph.js +269 -0
- package/dist/data/call-graph/CallGraph.js.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.cjs +39 -0
- package/dist/data/call-graph/CallGraphGlyphs.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.d.ts +19 -0
- package/dist/data/call-graph/CallGraphGlyphs.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.js +39 -0
- package/dist/data/call-graph/CallGraphGlyphs.js.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.cjs +51 -0
- package/dist/data/call-graph/CallGraphMembers.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.d.ts +22 -0
- package/dist/data/call-graph/CallGraphMembers.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.js +51 -0
- package/dist/data/call-graph/CallGraphMembers.js.map +1 -0
- package/dist/data/call-graph/CallGraphParts.cjs +204 -0
- package/dist/data/call-graph/CallGraphParts.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphParts.d.ts +44 -0
- package/dist/data/call-graph/CallGraphParts.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphParts.js +204 -0
- package/dist/data/call-graph/CallGraphParts.js.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.cjs +198 -0
- package/dist/data/call-graph/CallGraphToolbar.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.d.ts +55 -0
- package/dist/data/call-graph/CallGraphToolbar.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.js +198 -0
- package/dist/data/call-graph/CallGraphToolbar.js.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.cjs +75 -0
- package/dist/data/call-graph/call-graph-exclude.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.d.ts +31 -0
- package/dist/data/call-graph/call-graph-exclude.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.js +75 -0
- package/dist/data/call-graph/call-graph-exclude.js.map +1 -0
- package/dist/data/call-graph/call-graph-labels.cjs +96 -0
- package/dist/data/call-graph/call-graph-labels.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-labels.d.ts +53 -0
- package/dist/data/call-graph/call-graph-labels.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-labels.js +96 -0
- package/dist/data/call-graph/call-graph-labels.js.map +1 -0
- package/dist/data/call-graph/call-graph-model.cjs +312 -0
- package/dist/data/call-graph/call-graph-model.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-model.d.ts +138 -0
- package/dist/data/call-graph/call-graph-model.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-model.js +312 -0
- package/dist/data/call-graph/call-graph-model.js.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.cjs +195 -0
- package/dist/data/call-graph/call-graph-vocabulary.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.d.ts +76 -0
- package/dist/data/call-graph/call-graph-vocabulary.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.js +195 -0
- package/dist/data/call-graph/call-graph-vocabulary.js.map +1 -0
- package/dist/data/call-graph/call-graph.fixtures.d.ts +63 -0
- package/dist/data/call-graph/call-graph.fixtures.d.ts.map +1 -0
- package/dist/data/call-graph/index.d.ts +7 -0
- package/dist/data/call-graph/index.d.ts.map +1 -0
- package/dist/data/call-graph/types.cjs +5 -0
- package/dist/data/call-graph/types.cjs.map +1 -0
- package/dist/data/call-graph/types.d.ts +140 -0
- package/dist/data/call-graph/types.d.ts.map +1 -0
- package/dist/data/call-graph/types.js +5 -0
- package/dist/data/call-graph/types.js.map +1 -0
- package/dist/data/call-graph/use-call-graph.cjs +93 -0
- package/dist/data/call-graph/use-call-graph.cjs.map +1 -0
- package/dist/data/call-graph/use-call-graph.d.ts +24 -0
- package/dist/data/call-graph/use-call-graph.d.ts.map +1 -0
- package/dist/data/call-graph/use-call-graph.js +93 -0
- package/dist/data/call-graph/use-call-graph.js.map +1 -0
- package/dist/data/chat/Chat.cjs +39 -15
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.cjs +2 -2
- package/dist/data/chat/Chat.fixtures.cjs.map +1 -1
- package/dist/data/chat/Chat.fixtures.js +2 -2
- package/dist/data/chat/Chat.fixtures.js.map +1 -1
- package/dist/data/chat/Chat.js +40 -16
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +3 -6
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +3 -6
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/ContextMeter.bar.cjs +5 -8
- package/dist/data/chat/ContextMeter.bar.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.bar.d.ts +1 -1
- package/dist/data/chat/ContextMeter.bar.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.bar.js +5 -8
- package/dist/data/chat/ContextMeter.bar.js.map +1 -1
- package/dist/data/chat/ContextMeter.cjs +18 -19
- package/dist/data/chat/ContextMeter.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.d.ts +1 -1
- package/dist/data/chat/ContextMeter.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.js +18 -19
- package/dist/data/chat/ContextMeter.js.map +1 -1
- package/dist/data/chat/Conversation.cjs +2 -1
- package/dist/data/chat/Conversation.cjs.map +1 -1
- package/dist/data/chat/Conversation.d.ts +4 -1
- package/dist/data/chat/Conversation.d.ts.map +1 -1
- package/dist/data/chat/Conversation.js +2 -1
- package/dist/data/chat/Conversation.js.map +1 -1
- package/dist/data/chat/Message.cjs +39 -12
- package/dist/data/chat/Message.cjs.map +1 -1
- package/dist/data/chat/Message.d.ts +1 -1
- package/dist/data/chat/Message.d.ts.map +1 -1
- package/dist/data/chat/Message.js +40 -13
- package/dist/data/chat/Message.js.map +1 -1
- package/dist/data/chat/ToolCall.cjs +60 -5
- package/dist/data/chat/ToolCall.cjs.map +1 -1
- package/dist/data/chat/ToolCall.d.ts +7 -2
- package/dist/data/chat/ToolCall.d.ts.map +1 -1
- package/dist/data/chat/ToolCall.js +60 -5
- package/dist/data/chat/ToolCall.js.map +1 -1
- package/dist/data/chat/approval.cjs.map +1 -1
- package/dist/data/chat/approval.d.ts +2 -2
- package/dist/data/chat/approval.d.ts.map +1 -1
- package/dist/data/chat/approval.js.map +1 -1
- package/dist/data/chat/tool-policy.cjs +59 -2
- package/dist/data/chat/tool-policy.cjs.map +1 -1
- package/dist/data/chat/tool-policy.d.ts +9 -0
- package/dist/data/chat/tool-policy.d.ts.map +1 -1
- package/dist/data/chat/tool-policy.js +59 -2
- package/dist/data/chat/tool-policy.js.map +1 -1
- package/dist/data/chat/types.cjs +6 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +13 -4
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js +7 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/chat/usage-snapshot.cjs +11 -6
- package/dist/data/chat/usage-snapshot.cjs.map +1 -1
- package/dist/data/chat/usage-snapshot.d.ts +0 -1
- package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
- package/dist/data/chat/usage-snapshot.js +11 -6
- package/dist/data/chat/usage-snapshot.js.map +1 -1
- package/dist/data/data-access.cjs +8 -0
- package/dist/data/data-access.cjs.map +1 -0
- package/dist/data/data-access.d.ts +5 -0
- package/dist/data/data-access.d.ts.map +1 -0
- package/dist/data/data-access.js +8 -0
- package/dist/data/data-access.js.map +1 -0
- package/dist/data/diagnostics/StackFrameRow.cjs +3 -3
- package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.js +3 -3
- package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
- package/dist/data/git/GitChangeList.cjs +6 -2
- package/dist/data/git/GitChangeList.cjs.map +1 -1
- package/dist/data/git/GitChangeList.d.ts +6 -1
- package/dist/data/git/GitChangeList.d.ts.map +1 -1
- package/dist/data/git/GitChangeList.js +6 -2
- package/dist/data/git/GitChangeList.js.map +1 -1
- package/dist/data/graph-columns-layout.cjs +61 -14
- package/dist/data/graph-columns-layout.cjs.map +1 -1
- package/dist/data/graph-columns-layout.d.ts +42 -0
- package/dist/data/graph-columns-layout.d.ts.map +1 -1
- package/dist/data/graph-columns-layout.js +61 -14
- package/dist/data/graph-columns-layout.js.map +1 -1
- package/dist/data/graph-diagram-model.cjs +5 -0
- package/dist/data/graph-diagram-model.cjs.map +1 -1
- package/dist/data/graph-diagram-model.d.ts +24 -0
- package/dist/data/graph-diagram-model.d.ts.map +1 -1
- package/dist/data/graph-diagram-model.js +5 -0
- package/dist/data/graph-diagram-model.js.map +1 -1
- package/dist/data/graph-edge-routing.cjs +9 -3
- package/dist/data/graph-edge-routing.cjs.map +1 -1
- package/dist/data/graph-edge-routing.d.ts +2 -0
- package/dist/data/graph-edge-routing.d.ts.map +1 -1
- package/dist/data/graph-edge-routing.js +9 -3
- package/dist/data/graph-edge-routing.js.map +1 -1
- package/dist/data/graph-group-window.cjs +60 -0
- package/dist/data/graph-group-window.cjs.map +1 -0
- package/dist/data/graph-group-window.d.ts +33 -0
- package/dist/data/graph-group-window.d.ts.map +1 -0
- package/dist/data/graph-group-window.js +60 -0
- package/dist/data/graph-group-window.js.map +1 -0
- package/dist/data/json-view/JsonSource.cjs +84 -0
- package/dist/data/json-view/JsonSource.cjs.map +1 -0
- package/dist/data/json-view/JsonSource.d.ts +7 -0
- package/dist/data/json-view/JsonSource.d.ts.map +1 -0
- package/dist/data/json-view/JsonSource.js +84 -0
- package/dist/data/json-view/JsonSource.js.map +1 -0
- package/dist/data/json-view/parse-prefix.cjs +132 -0
- package/dist/data/json-view/parse-prefix.cjs.map +1 -0
- package/dist/data/json-view/parse-prefix.d.ts +11 -0
- package/dist/data/json-view/parse-prefix.d.ts.map +1 -0
- package/dist/data/json-view/parse-prefix.js +132 -0
- package/dist/data/json-view/parse-prefix.js.map +1 -0
- package/dist/data/json-view/parse-source.cjs +62 -0
- package/dist/data/json-view/parse-source.cjs.map +1 -0
- package/dist/data/json-view/parse-source.d.ts +16 -0
- package/dist/data/json-view/parse-source.d.ts.map +1 -0
- package/dist/data/json-view/parse-source.js +62 -0
- package/dist/data/json-view/parse-source.js.map +1 -0
- package/dist/data/json-view/story-fixtures.d.ts +6 -0
- package/dist/data/json-view/story-fixtures.d.ts.map +1 -0
- package/dist/data/json-view/types.d.ts +14 -0
- package/dist/data/json-view/types.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.cjs +2 -5
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +2 -4
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.cjs +2 -2
- package/dist/data/runtime/RuntimeBar.fields.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.js +2 -2
- package/dist/data/runtime/RuntimeBar.fields.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.js +2 -5
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs +4 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.js +5 -2
- package/dist/data/runtime/RuntimeBar.selection.js.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.cjs +1 -5
- package/dist/data/runtime/RuntimeBarActions.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.js +1 -5
- package/dist/data/runtime/RuntimeBarActions.js.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.cjs +6 -14
- package/dist/data/runtime/RuntimeBarIdentity.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.d.ts +0 -1
- package/dist/data/runtime/RuntimeBarIdentity.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.js +6 -14
- package/dist/data/runtime/RuntimeBarIdentity.js.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.cjs +8 -27
- package/dist/data/runtime/RuntimeBarLayout.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.js +8 -27
- package/dist/data/runtime/RuntimeBarLayout.js.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.cjs +1 -5
- package/dist/data/runtime/RuntimeBarSegment.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.js +1 -5
- package/dist/data/runtime/RuntimeBarSegment.js.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.cjs +4 -10
- package/dist/data/runtime/use-runtime-bar-overflow.cjs.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts +1 -2
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.js +4 -10
- package/dist/data/runtime/use-runtime-bar-overflow.js.map +1 -1
- package/dist/data/test-runner/TestRunner.fixtures.d.ts +0 -20
- package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.large-fixtures.d.ts +22 -0
- package/dist/data/test-runner/TestRunner.large-fixtures.d.ts.map +1 -0
- package/dist/data/use-group-windows.cjs +50 -0
- package/dist/data/use-group-windows.cjs.map +1 -0
- package/dist/data/use-group-windows.d.ts +27 -0
- package/dist/data/use-group-windows.d.ts.map +1 -0
- package/dist/data/use-group-windows.js +50 -0
- package/dist/data/use-group-windows.js.map +1 -0
- package/dist/data/use-pan-zoom.cjs +23 -10
- package/dist/data/use-pan-zoom.cjs.map +1 -1
- package/dist/data/use-pan-zoom.d.ts +16 -2
- package/dist/data/use-pan-zoom.d.ts.map +1 -1
- package/dist/data/use-pan-zoom.js +23 -10
- package/dist/data/use-pan-zoom.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +36 -2
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +5 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +35 -1
- package/dist/data.js.map +1 -1
- package/dist/hooks/event-hub.cjs +229 -0
- package/dist/hooks/event-hub.cjs.map +1 -0
- package/dist/hooks/event-hub.d.ts +26 -0
- package/dist/hooks/event-hub.d.ts.map +1 -0
- package/dist/hooks/event-hub.js +229 -0
- package/dist/hooks/event-hub.js.map +1 -0
- package/dist/hooks.cjs +2 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +40 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/Workspace.cjs +13 -4
- package/dist/layout/Workspace.cjs.map +1 -1
- package/dist/layout/Workspace.d.ts +7 -2
- package/dist/layout/Workspace.d.ts.map +1 -1
- package/dist/layout/Workspace.js +13 -4
- package/dist/layout/Workspace.js.map +1 -1
- package/dist/lib/permission-strategies.cjs +71 -11
- package/dist/lib/permission-strategies.cjs.map +1 -1
- package/dist/lib/permission-strategies.d.ts +3 -0
- package/dist/lib/permission-strategies.d.ts.map +1 -1
- package/dist/lib/permission-strategies.js +71 -11
- package/dist/lib/permission-strategies.js.map +1 -1
- package/dist/overlay/modalStack.cjs +13 -6
- package/dist/overlay/modalStack.cjs.map +1 -1
- package/dist/overlay/modalStack.d.ts.map +1 -1
- package/dist/overlay/modalStack.js +13 -6
- package/dist/overlay/modalStack.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -3
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs +0 -57
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs.map +0 -1
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts +0 -7
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts.map +0 -1
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js +0 -57
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.cjs +0 -8
- package/dist/data/runtime/RuntimeBar.context.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.d.ts +0 -2
- package/dist/data/runtime/RuntimeBar.context.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.js +0 -8
- package/dist/data/runtime/RuntimeBar.context.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Conversation.cjs","sources":["../../../src/data/chat/Conversation.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiArrowDown, UiCheck, UiCircleX, UiCopy, UiLoader } from \"../../icons\";\nimport { Message, type MessageActionHandlers } from \"./Message\";\nimport type { ChatStatus, UIMessage } from \"./types\";\n\nexport type ConversationProps = MessageActionHandlers & {\n messages: UIMessage[];\n /** Current chat status; used for transient pending/error affordances. */\n status?: ChatStatus | undefined;\n /** Last request error from the chat transport, if any. */\n error?: Error | undefined;\n /** Clears the visible transport error. */\n onClearError?: (() => void) | undefined;\n /** Conversation/thread id, surfaced in the copyable error report. */\n sessionId?: string | undefined;\n /** Selected model id, surfaced in the copyable error report. */\n model?: string | undefined;\n /** Shown when there are no messages yet. */\n emptyState?: React.ReactNode;\n className?: string;\n};\n\n/** A scrollable message log that sticks to the bottom as new content streams\n * in, unless the user has scrolled up — in which case a jump-to-bottom button\n * appears. */\nexport function Conversation({\n messages,\n status,\n error,\n onClearError,\n sessionId,\n model,\n emptyState,\n className,\n ...actions\n}: ConversationProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const [pinned, setPinned] = useState(true);\n const isWaiting = status === \"submitted\" || (status === \"streaming\" && !hasVisibleAssistantResponse(messages));\n const errorText = error?.message || (status === \"error\" ? \"The assistant request failed.\" : undefined);\n\n const onScroll = () => {\n const el = scrollRef.current;\n if (!el) return;\n const distance = el.scrollHeight - el.scrollTop - el.clientHeight;\n setPinned(distance < 32);\n };\n\n useEffect(() => {\n const el = scrollRef.current;\n if (el && pinned) {\n el.scrollTop = el.scrollHeight;\n }\n });\n\n const scrollToBottom = () => {\n const el = scrollRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n };\n\n return (\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={scrollRef}\n onScroll={onScroll}\n role=\"log\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n >\n {messages.length === 0 && emptyState ? (\n <div className=\"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState}\n </div>\n ) : (\n <div className=\"flex flex-col gap-8 p-4\">\n {messages.map((message) => (\n <Message key={message.id} message={message} {...actions} />\n ))}\n {isWaiting && <LoadingIndicator />}\n {errorText && (\n <ErrorNotice\n message={errorText}\n error={error}\n sessionId={sessionId}\n model={model}\n onClear={onClearError}\n />\n )}\n </div>\n )}\n </div>\n\n {!pinned && messages.length > 0 && (\n <button\n type=\"button\"\n aria-label=\"Scroll to latest\"\n onClick={scrollToBottom}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-muted-foreground shadow-md hover:text-foreground\"\n >\n <Icon icon={UiArrowDown} className=\"size-4\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction hasVisibleAssistantResponse(messages: UIMessage[]) {\n const last = messages[messages.length - 1];\n if (last?.role !== \"assistant\") return false;\n return last.parts.some((part) => {\n if (part.type === \"step-start\") return false;\n if (part.type === \"text\" || part.type === \"reasoning\") return part.text.length > 0;\n return true;\n });\n}\n\nfunction LoadingIndicator() {\n return (\n <div className=\"flex w-full max-w-[95%] items-center gap-2 text-sm text-muted-foreground\">\n <Icon icon={UiLoader} className=\"size-4 shrink-0 animate-spin\" />\n <span>Waiting for response...</span>\n </div>\n );\n}\n\ntype ErrorReport = {\n message: string;\n error?: Error | undefined;\n sessionId?: string | undefined;\n model?: string | undefined;\n};\n\n/** Assembles a support-ready plain-text report: the error, the session/model\n * that produced it, the page, and the full stack/cause — everything needed to\n * file or triage the failure without a back-and-forth. */\nfunction buildErrorReport({ message, error, sessionId, model }: ErrorReport): string {\n const lines = [`Error: ${message}`];\n if (error?.name && error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (sessionId) lines.push(`Session: ${sessionId}`);\n if (model) lines.push(`Model: ${model}`);\n if (typeof window !== \"undefined\") lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) lines.push(`User agent: ${navigator.userAgent}`);\n lines.push(`Time: ${new Date().toISOString()}`);\n const cause = (error as { cause?: unknown } | undefined)?.cause;\n const detail = error?.stack ?? (cause != null ? String(cause) : \"\");\n if (detail.trim() && detail.trim() !== message) lines.push(\"\", detail.trim());\n return lines.join(\"\\n\");\n}\n\nfunction ErrorNotice({ message, error, sessionId, model, onClear }: ErrorReport & { onClear?: (() => void) | undefined }) {\n const [copied, setCopied] = useState(false);\n const copyReport = () => {\n const clip = typeof navigator !== \"undefined\" ? navigator.clipboard : undefined;\n if (!clip) return;\n void clip\n .writeText(buildErrorReport({ message, error, sessionId, model }))\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {});\n };\n return (\n <div\n role=\"alert\"\n className=\"flex w-full max-w-[95%] items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n <Icon icon={UiCircleX} className=\"mt-0.5 size-4 shrink-0\" />\n <div className=\"min-w-0 flex-1 whitespace-pre-wrap break-words\">{message}</div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Copy error details\"\n title=\"Copy session id, model, page and full error\"\n className=\"inline-flex items-center gap-1 text-xs underline-offset-2 hover:underline\"\n onClick={copyReport}\n >\n <Icon icon={copied ? UiCheck : UiCopy} className=\"size-3.5\" />\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n {onClear && (\n <button type=\"button\" className=\"text-xs underline-offset-2 hover:underline\" onClick={onClear}>\n Dismiss\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useRef","useState","useEffect","jsxs","jsx","cn","Message","Icon","UiArrowDown","UiLoader","UiCircleX","UiCheck","UiCopy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Conversation.cjs","sources":["../../../src/data/chat/Conversation.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiArrowDown, UiCheck, UiCircleX, UiCopy, UiLoader } from \"../../icons\";\nimport { Message, type MessageActionHandlers } from \"./Message\";\nimport type { ChatStatus, UIMessage } from \"./types\";\n\nexport type ConversationProps = MessageActionHandlers & {\n messages: UIMessage[];\n /** Current chat status; used for transient pending/error affordances. */\n status?: ChatStatus | undefined;\n /** Last request error from the chat transport, if any. */\n error?: Error | undefined;\n /** Clears the visible transport error. */\n onClearError?: (() => void) | undefined;\n /** Conversation/thread id, surfaced in the copyable error report. */\n sessionId?: string | undefined;\n /** Selected model id, surfaced in the copyable error report. */\n model?: string | undefined;\n /** Hide the waiting indicator because another control (e.g. an approval\n * button) is already showing progress. */\n suppressWaiting?: boolean | undefined;\n /** Shown when there are no messages yet. */\n emptyState?: React.ReactNode;\n className?: string;\n};\n\n/** A scrollable message log that sticks to the bottom as new content streams\n * in, unless the user has scrolled up — in which case a jump-to-bottom button\n * appears. */\nexport function Conversation({\n messages,\n status,\n error,\n onClearError,\n sessionId,\n model,\n suppressWaiting,\n emptyState,\n className,\n ...actions\n}: ConversationProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const [pinned, setPinned] = useState(true);\n const isWaiting =\n !suppressWaiting &&\n (status === \"submitted\" || (status === \"streaming\" && !hasVisibleAssistantResponse(messages)));\n const errorText = error?.message || (status === \"error\" ? \"The assistant request failed.\" : undefined);\n\n const onScroll = () => {\n const el = scrollRef.current;\n if (!el) return;\n const distance = el.scrollHeight - el.scrollTop - el.clientHeight;\n setPinned(distance < 32);\n };\n\n useEffect(() => {\n const el = scrollRef.current;\n if (el && pinned) {\n el.scrollTop = el.scrollHeight;\n }\n });\n\n const scrollToBottom = () => {\n const el = scrollRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n };\n\n return (\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={scrollRef}\n onScroll={onScroll}\n role=\"log\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n >\n {messages.length === 0 && emptyState ? (\n <div className=\"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState}\n </div>\n ) : (\n <div className=\"flex flex-col gap-8 p-4\">\n {messages.map((message) => (\n <Message key={message.id} message={message} {...actions} />\n ))}\n {isWaiting && <LoadingIndicator />}\n {errorText && (\n <ErrorNotice\n message={errorText}\n error={error}\n sessionId={sessionId}\n model={model}\n onClear={onClearError}\n />\n )}\n </div>\n )}\n </div>\n\n {!pinned && messages.length > 0 && (\n <button\n type=\"button\"\n aria-label=\"Scroll to latest\"\n onClick={scrollToBottom}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-muted-foreground shadow-md hover:text-foreground\"\n >\n <Icon icon={UiArrowDown} className=\"size-4\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction hasVisibleAssistantResponse(messages: UIMessage[]) {\n const last = messages[messages.length - 1];\n if (last?.role !== \"assistant\") return false;\n return last.parts.some((part) => {\n if (part.type === \"step-start\") return false;\n if (part.type === \"text\" || part.type === \"reasoning\") return part.text.length > 0;\n return true;\n });\n}\n\nfunction LoadingIndicator() {\n return (\n <div className=\"flex w-full max-w-[95%] items-center gap-2 text-sm text-muted-foreground\">\n <Icon icon={UiLoader} className=\"size-4 shrink-0 animate-spin\" />\n <span>Waiting for response...</span>\n </div>\n );\n}\n\ntype ErrorReport = {\n message: string;\n error?: Error | undefined;\n sessionId?: string | undefined;\n model?: string | undefined;\n};\n\n/** Assembles a support-ready plain-text report: the error, the session/model\n * that produced it, the page, and the full stack/cause — everything needed to\n * file or triage the failure without a back-and-forth. */\nfunction buildErrorReport({ message, error, sessionId, model }: ErrorReport): string {\n const lines = [`Error: ${message}`];\n if (error?.name && error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (sessionId) lines.push(`Session: ${sessionId}`);\n if (model) lines.push(`Model: ${model}`);\n if (typeof window !== \"undefined\") lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) lines.push(`User agent: ${navigator.userAgent}`);\n lines.push(`Time: ${new Date().toISOString()}`);\n const cause = (error as { cause?: unknown } | undefined)?.cause;\n const detail = error?.stack ?? (cause != null ? String(cause) : \"\");\n if (detail.trim() && detail.trim() !== message) lines.push(\"\", detail.trim());\n return lines.join(\"\\n\");\n}\n\nfunction ErrorNotice({ message, error, sessionId, model, onClear }: ErrorReport & { onClear?: (() => void) | undefined }) {\n const [copied, setCopied] = useState(false);\n const copyReport = () => {\n const clip = typeof navigator !== \"undefined\" ? navigator.clipboard : undefined;\n if (!clip) return;\n void clip\n .writeText(buildErrorReport({ message, error, sessionId, model }))\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {});\n };\n return (\n <div\n role=\"alert\"\n className=\"flex w-full max-w-[95%] items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n <Icon icon={UiCircleX} className=\"mt-0.5 size-4 shrink-0\" />\n <div className=\"min-w-0 flex-1 whitespace-pre-wrap break-words\">{message}</div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Copy error details\"\n title=\"Copy session id, model, page and full error\"\n className=\"inline-flex items-center gap-1 text-xs underline-offset-2 hover:underline\"\n onClick={copyReport}\n >\n <Icon icon={copied ? UiCheck : UiCopy} className=\"size-3.5\" />\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n {onClear && (\n <button type=\"button\" className=\"text-xs underline-offset-2 hover:underline\" onClick={onClear}>\n Dismiss\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useRef","useState","useEffect","jsxs","jsx","cn","Message","Icon","UiArrowDown","UiLoader","UiCircleX","UiCheck","UiCopy"],"mappings":"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"}
|
|
@@ -12,6 +12,9 @@ export type ConversationProps = MessageActionHandlers & {
|
|
|
12
12
|
sessionId?: string | undefined;
|
|
13
13
|
/** Selected model id, surfaced in the copyable error report. */
|
|
14
14
|
model?: string | undefined;
|
|
15
|
+
/** Hide the waiting indicator because another control (e.g. an approval
|
|
16
|
+
* button) is already showing progress. */
|
|
17
|
+
suppressWaiting?: boolean | undefined;
|
|
15
18
|
/** Shown when there are no messages yet. */
|
|
16
19
|
emptyState?: React.ReactNode;
|
|
17
20
|
className?: string;
|
|
@@ -19,5 +22,5 @@ export type ConversationProps = MessageActionHandlers & {
|
|
|
19
22
|
/** A scrollable message log that sticks to the bottom as new content streams
|
|
20
23
|
* in, unless the user has scrolled up — in which case a jump-to-bottom button
|
|
21
24
|
* appears. */
|
|
22
|
-
export declare function Conversation({ messages, status, error, onClearError, sessionId, model, emptyState, className, ...actions }: ConversationProps): import("react").JSX.Element;
|
|
25
|
+
export declare function Conversation({ messages, status, error, onClearError, sessionId, model, suppressWaiting, emptyState, className, ...actions }: ConversationProps): import("react").JSX.Element;
|
|
23
26
|
//# sourceMappingURL=Conversation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Conversation.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAW,KAAK,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG;IACtD,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC1B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACxC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,4CAA4C;IAC5C,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;eAEe;AACf,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,KAAK,EACL,YAAY,EACZ,SAAS,EACT,KAAK,EACL,UAAU,EACV,SAAS,EACT,GAAG,OAAO,EACX,EAAE,iBAAiB,+
|
|
1
|
+
{"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Conversation.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAW,KAAK,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG;IACtD,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC1B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACxC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;+CAC2C;IAC3C,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;eAEe;AACf,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,KAAK,EACL,YAAY,EACZ,SAAS,EACT,KAAK,EACL,eAAe,EACf,UAAU,EACV,SAAS,EACT,GAAG,OAAO,EACX,EAAE,iBAAiB,+BAsEnB"}
|
|
@@ -15,13 +15,14 @@ function Conversation({
|
|
|
15
15
|
onClearError,
|
|
16
16
|
sessionId,
|
|
17
17
|
model,
|
|
18
|
+
suppressWaiting,
|
|
18
19
|
emptyState,
|
|
19
20
|
className,
|
|
20
21
|
...actions
|
|
21
22
|
}) {
|
|
22
23
|
const scrollRef = useRef(null);
|
|
23
24
|
const [pinned, setPinned] = useState(true);
|
|
24
|
-
const isWaiting = status === "submitted" || status === "streaming" && !hasVisibleAssistantResponse(messages);
|
|
25
|
+
const isWaiting = !suppressWaiting && (status === "submitted" || status === "streaming" && !hasVisibleAssistantResponse(messages));
|
|
25
26
|
const errorText = (error == null ? void 0 : error.message) || (status === "error" ? "The assistant request failed." : void 0);
|
|
26
27
|
const onScroll = () => {
|
|
27
28
|
const el = scrollRef.current;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Conversation.js","sources":["../../../src/data/chat/Conversation.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiArrowDown, UiCheck, UiCircleX, UiCopy, UiLoader } from \"../../icons\";\nimport { Message, type MessageActionHandlers } from \"./Message\";\nimport type { ChatStatus, UIMessage } from \"./types\";\n\nexport type ConversationProps = MessageActionHandlers & {\n messages: UIMessage[];\n /** Current chat status; used for transient pending/error affordances. */\n status?: ChatStatus | undefined;\n /** Last request error from the chat transport, if any. */\n error?: Error | undefined;\n /** Clears the visible transport error. */\n onClearError?: (() => void) | undefined;\n /** Conversation/thread id, surfaced in the copyable error report. */\n sessionId?: string | undefined;\n /** Selected model id, surfaced in the copyable error report. */\n model?: string | undefined;\n /** Shown when there are no messages yet. */\n emptyState?: React.ReactNode;\n className?: string;\n};\n\n/** A scrollable message log that sticks to the bottom as new content streams\n * in, unless the user has scrolled up — in which case a jump-to-bottom button\n * appears. */\nexport function Conversation({\n messages,\n status,\n error,\n onClearError,\n sessionId,\n model,\n emptyState,\n className,\n ...actions\n}: ConversationProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const [pinned, setPinned] = useState(true);\n const isWaiting = status === \"submitted\" || (status === \"streaming\" && !hasVisibleAssistantResponse(messages));\n const errorText = error?.message || (status === \"error\" ? \"The assistant request failed.\" : undefined);\n\n const onScroll = () => {\n const el = scrollRef.current;\n if (!el) return;\n const distance = el.scrollHeight - el.scrollTop - el.clientHeight;\n setPinned(distance < 32);\n };\n\n useEffect(() => {\n const el = scrollRef.current;\n if (el && pinned) {\n el.scrollTop = el.scrollHeight;\n }\n });\n\n const scrollToBottom = () => {\n const el = scrollRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n };\n\n return (\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={scrollRef}\n onScroll={onScroll}\n role=\"log\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n >\n {messages.length === 0 && emptyState ? (\n <div className=\"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState}\n </div>\n ) : (\n <div className=\"flex flex-col gap-8 p-4\">\n {messages.map((message) => (\n <Message key={message.id} message={message} {...actions} />\n ))}\n {isWaiting && <LoadingIndicator />}\n {errorText && (\n <ErrorNotice\n message={errorText}\n error={error}\n sessionId={sessionId}\n model={model}\n onClear={onClearError}\n />\n )}\n </div>\n )}\n </div>\n\n {!pinned && messages.length > 0 && (\n <button\n type=\"button\"\n aria-label=\"Scroll to latest\"\n onClick={scrollToBottom}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-muted-foreground shadow-md hover:text-foreground\"\n >\n <Icon icon={UiArrowDown} className=\"size-4\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction hasVisibleAssistantResponse(messages: UIMessage[]) {\n const last = messages[messages.length - 1];\n if (last?.role !== \"assistant\") return false;\n return last.parts.some((part) => {\n if (part.type === \"step-start\") return false;\n if (part.type === \"text\" || part.type === \"reasoning\") return part.text.length > 0;\n return true;\n });\n}\n\nfunction LoadingIndicator() {\n return (\n <div className=\"flex w-full max-w-[95%] items-center gap-2 text-sm text-muted-foreground\">\n <Icon icon={UiLoader} className=\"size-4 shrink-0 animate-spin\" />\n <span>Waiting for response...</span>\n </div>\n );\n}\n\ntype ErrorReport = {\n message: string;\n error?: Error | undefined;\n sessionId?: string | undefined;\n model?: string | undefined;\n};\n\n/** Assembles a support-ready plain-text report: the error, the session/model\n * that produced it, the page, and the full stack/cause — everything needed to\n * file or triage the failure without a back-and-forth. */\nfunction buildErrorReport({ message, error, sessionId, model }: ErrorReport): string {\n const lines = [`Error: ${message}`];\n if (error?.name && error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (sessionId) lines.push(`Session: ${sessionId}`);\n if (model) lines.push(`Model: ${model}`);\n if (typeof window !== \"undefined\") lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) lines.push(`User agent: ${navigator.userAgent}`);\n lines.push(`Time: ${new Date().toISOString()}`);\n const cause = (error as { cause?: unknown } | undefined)?.cause;\n const detail = error?.stack ?? (cause != null ? String(cause) : \"\");\n if (detail.trim() && detail.trim() !== message) lines.push(\"\", detail.trim());\n return lines.join(\"\\n\");\n}\n\nfunction ErrorNotice({ message, error, sessionId, model, onClear }: ErrorReport & { onClear?: (() => void) | undefined }) {\n const [copied, setCopied] = useState(false);\n const copyReport = () => {\n const clip = typeof navigator !== \"undefined\" ? navigator.clipboard : undefined;\n if (!clip) return;\n void clip\n .writeText(buildErrorReport({ message, error, sessionId, model }))\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {});\n };\n return (\n <div\n role=\"alert\"\n className=\"flex w-full max-w-[95%] items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n <Icon icon={UiCircleX} className=\"mt-0.5 size-4 shrink-0\" />\n <div className=\"min-w-0 flex-1 whitespace-pre-wrap break-words\">{message}</div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Copy error details\"\n title=\"Copy session id, model, page and full error\"\n className=\"inline-flex items-center gap-1 text-xs underline-offset-2 hover:underline\"\n onClick={copyReport}\n >\n <Icon icon={copied ? UiCheck : UiCopy} className=\"size-3.5\" />\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n {onClear && (\n <button type=\"button\" className=\"text-xs underline-offset-2 hover:underline\" onClick={onClear}>\n Dismiss\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Conversation.js","sources":["../../../src/data/chat/Conversation.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiArrowDown, UiCheck, UiCircleX, UiCopy, UiLoader } from \"../../icons\";\nimport { Message, type MessageActionHandlers } from \"./Message\";\nimport type { ChatStatus, UIMessage } from \"./types\";\n\nexport type ConversationProps = MessageActionHandlers & {\n messages: UIMessage[];\n /** Current chat status; used for transient pending/error affordances. */\n status?: ChatStatus | undefined;\n /** Last request error from the chat transport, if any. */\n error?: Error | undefined;\n /** Clears the visible transport error. */\n onClearError?: (() => void) | undefined;\n /** Conversation/thread id, surfaced in the copyable error report. */\n sessionId?: string | undefined;\n /** Selected model id, surfaced in the copyable error report. */\n model?: string | undefined;\n /** Hide the waiting indicator because another control (e.g. an approval\n * button) is already showing progress. */\n suppressWaiting?: boolean | undefined;\n /** Shown when there are no messages yet. */\n emptyState?: React.ReactNode;\n className?: string;\n};\n\n/** A scrollable message log that sticks to the bottom as new content streams\n * in, unless the user has scrolled up — in which case a jump-to-bottom button\n * appears. */\nexport function Conversation({\n messages,\n status,\n error,\n onClearError,\n sessionId,\n model,\n suppressWaiting,\n emptyState,\n className,\n ...actions\n}: ConversationProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const [pinned, setPinned] = useState(true);\n const isWaiting =\n !suppressWaiting &&\n (status === \"submitted\" || (status === \"streaming\" && !hasVisibleAssistantResponse(messages)));\n const errorText = error?.message || (status === \"error\" ? \"The assistant request failed.\" : undefined);\n\n const onScroll = () => {\n const el = scrollRef.current;\n if (!el) return;\n const distance = el.scrollHeight - el.scrollTop - el.clientHeight;\n setPinned(distance < 32);\n };\n\n useEffect(() => {\n const el = scrollRef.current;\n if (el && pinned) {\n el.scrollTop = el.scrollHeight;\n }\n });\n\n const scrollToBottom = () => {\n const el = scrollRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n };\n\n return (\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={scrollRef}\n onScroll={onScroll}\n role=\"log\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n >\n {messages.length === 0 && emptyState ? (\n <div className=\"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState}\n </div>\n ) : (\n <div className=\"flex flex-col gap-8 p-4\">\n {messages.map((message) => (\n <Message key={message.id} message={message} {...actions} />\n ))}\n {isWaiting && <LoadingIndicator />}\n {errorText && (\n <ErrorNotice\n message={errorText}\n error={error}\n sessionId={sessionId}\n model={model}\n onClear={onClearError}\n />\n )}\n </div>\n )}\n </div>\n\n {!pinned && messages.length > 0 && (\n <button\n type=\"button\"\n aria-label=\"Scroll to latest\"\n onClick={scrollToBottom}\n className=\"absolute bottom-3 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-muted-foreground shadow-md hover:text-foreground\"\n >\n <Icon icon={UiArrowDown} className=\"size-4\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction hasVisibleAssistantResponse(messages: UIMessage[]) {\n const last = messages[messages.length - 1];\n if (last?.role !== \"assistant\") return false;\n return last.parts.some((part) => {\n if (part.type === \"step-start\") return false;\n if (part.type === \"text\" || part.type === \"reasoning\") return part.text.length > 0;\n return true;\n });\n}\n\nfunction LoadingIndicator() {\n return (\n <div className=\"flex w-full max-w-[95%] items-center gap-2 text-sm text-muted-foreground\">\n <Icon icon={UiLoader} className=\"size-4 shrink-0 animate-spin\" />\n <span>Waiting for response...</span>\n </div>\n );\n}\n\ntype ErrorReport = {\n message: string;\n error?: Error | undefined;\n sessionId?: string | undefined;\n model?: string | undefined;\n};\n\n/** Assembles a support-ready plain-text report: the error, the session/model\n * that produced it, the page, and the full stack/cause — everything needed to\n * file or triage the failure without a back-and-forth. */\nfunction buildErrorReport({ message, error, sessionId, model }: ErrorReport): string {\n const lines = [`Error: ${message}`];\n if (error?.name && error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (sessionId) lines.push(`Session: ${sessionId}`);\n if (model) lines.push(`Model: ${model}`);\n if (typeof window !== \"undefined\") lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) lines.push(`User agent: ${navigator.userAgent}`);\n lines.push(`Time: ${new Date().toISOString()}`);\n const cause = (error as { cause?: unknown } | undefined)?.cause;\n const detail = error?.stack ?? (cause != null ? String(cause) : \"\");\n if (detail.trim() && detail.trim() !== message) lines.push(\"\", detail.trim());\n return lines.join(\"\\n\");\n}\n\nfunction ErrorNotice({ message, error, sessionId, model, onClear }: ErrorReport & { onClear?: (() => void) | undefined }) {\n const [copied, setCopied] = useState(false);\n const copyReport = () => {\n const clip = typeof navigator !== \"undefined\" ? navigator.clipboard : undefined;\n if (!clip) return;\n void clip\n .writeText(buildErrorReport({ message, error, sessionId, model }))\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {});\n };\n return (\n <div\n role=\"alert\"\n className=\"flex w-full max-w-[95%] items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n <Icon icon={UiCircleX} className=\"mt-0.5 size-4 shrink-0\" />\n <div className=\"min-w-0 flex-1 whitespace-pre-wrap break-words\">{message}</div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Copy error details\"\n title=\"Copy session id, model, page and full error\"\n className=\"inline-flex items-center gap-1 text-xs underline-offset-2 hover:underline\"\n onClick={copyReport}\n >\n <Icon icon={copied ? UiCheck : UiCopy} className=\"size-3.5\" />\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n {onClear && (\n <button type=\"button\" className=\"text-xs underline-offset-2 hover:underline\" onClick={onClear}>\n Dismiss\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,7 @@ function Message({
|
|
|
23
23
|
}
|
|
24
24
|
const isUser = message.role === "user";
|
|
25
25
|
const text = message.parts.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
26
|
+
const { subcalls, nested } = groupSubagentCalls(message.parts);
|
|
26
27
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
27
28
|
"div",
|
|
28
29
|
{
|
|
@@ -39,16 +40,20 @@ function Message({
|
|
|
39
40
|
"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm",
|
|
40
41
|
isUser && "rounded-lg bg-secondary px-4 py-3 text-secondary-foreground"
|
|
41
42
|
),
|
|
42
|
-
children: message.parts.map(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
children: message.parts.map(
|
|
44
|
+
(part, i) => nested.has(part) ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
+
MessagePart,
|
|
46
|
+
{
|
|
47
|
+
part,
|
|
48
|
+
isUser,
|
|
49
|
+
onApprove,
|
|
50
|
+
renderToolResult,
|
|
51
|
+
subcalls: isToolPart(part) ? subcalls.get(part.toolCallId) : void 0,
|
|
52
|
+
subcallsByParent: subcalls
|
|
53
|
+
},
|
|
54
|
+
`${message.id}-${i}`
|
|
55
|
+
)
|
|
56
|
+
)
|
|
52
57
|
}
|
|
53
58
|
),
|
|
54
59
|
!isUser && text && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -62,6 +67,24 @@ function Message({
|
|
|
62
67
|
}
|
|
63
68
|
);
|
|
64
69
|
}
|
|
70
|
+
function isToolPart(part) {
|
|
71
|
+
return types.isDynamicToolPart(part) || types.isTypedToolPart(part);
|
|
72
|
+
}
|
|
73
|
+
function groupSubagentCalls(parts) {
|
|
74
|
+
const callIds = new Set(
|
|
75
|
+
parts.filter(isToolPart).map((part) => part.toolCallId)
|
|
76
|
+
);
|
|
77
|
+
const subcalls = /* @__PURE__ */ new Map();
|
|
78
|
+
const nested = /* @__PURE__ */ new Set();
|
|
79
|
+
for (const part of parts) {
|
|
80
|
+
if (!isToolPart(part)) continue;
|
|
81
|
+
const parent = types.toolPartParentId(part);
|
|
82
|
+
if (!parent || !callIds.has(parent)) continue;
|
|
83
|
+
subcalls.set(parent, [...subcalls.get(parent) ?? [], part]);
|
|
84
|
+
nested.add(part);
|
|
85
|
+
}
|
|
86
|
+
return { subcalls, nested };
|
|
87
|
+
}
|
|
65
88
|
function ForkSeedMessage({
|
|
66
89
|
message,
|
|
67
90
|
className
|
|
@@ -90,7 +113,9 @@ function MessagePart({
|
|
|
90
113
|
part,
|
|
91
114
|
isUser,
|
|
92
115
|
onApprove,
|
|
93
|
-
renderToolResult
|
|
116
|
+
renderToolResult,
|
|
117
|
+
subcalls,
|
|
118
|
+
subcallsByParent
|
|
94
119
|
}) {
|
|
95
120
|
if (part.type === "text") {
|
|
96
121
|
if (isUser) {
|
|
@@ -104,12 +129,14 @@ function MessagePart({
|
|
|
104
129
|
if (types.isFilePart(part)) {
|
|
105
130
|
return /* @__PURE__ */ jsxRuntime.jsx(MessageFilePart.MessageFilePart, { part });
|
|
106
131
|
}
|
|
107
|
-
if (
|
|
132
|
+
if (isToolPart(part)) {
|
|
108
133
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
134
|
ToolCall.ToolCall,
|
|
110
135
|
{
|
|
111
136
|
part,
|
|
112
137
|
onApprove,
|
|
138
|
+
subcalls,
|
|
139
|
+
subcallsByParent,
|
|
113
140
|
...renderToolResult ? { renderToolResult } : {}
|
|
114
141
|
}
|
|
115
142
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.cjs","sources":["../../../src/data/chat/Message.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiGitBranch } from \"../../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { ToolCall } from \"./ToolCall\";\nimport { MessageActions } from \"./MessageActions\";\nimport { Reasoning } from \"./Reasoning\";\nimport type { UIMessage } from \"./types\";\nimport {\n isDynamicToolPart,\n isTypedToolPart,\n isReasoningPart,\n isFilePart,\n type AnyToolPart,\n type ToolResultRenderer,\n} from \"./types\";\nimport { forkSeedProvenance, isForkSeedMessage } from \"./fork-seed\";\nimport { MessageFilePart } from \"./MessageFilePart\";\n\n/** Callbacks the conversation threads down to each message. */\nexport type MessageActionHandlers = {\n /** Re-generate the assistant message with the given id. */\n onRegenerate?: ((messageId: string) => void) | undefined;\n /** Respond to a tool approval request. */\n onApprove?:\n | ((approvalId: string, approved: boolean, reason?: string) => void)\n | undefined;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n};\n\nexport type MessageProps = MessageActionHandlers & {\n message: UIMessage;\n className?: string;\n};\n\n/** Renders one chat message. User messages are right-aligned bubbles; assistant\n * messages render text as markdown, reasoning and tool parts inline, file parts\n * as thumbnails/chips, and a hover action row (copy / regenerate). */\nexport function Message({\n message,\n className,\n onRegenerate,\n onApprove,\n renderToolResult,\n}: MessageProps) {\n if (isForkSeedMessage(message)) {\n return <ForkSeedMessage message={message} className={className} />;\n }\n const isUser = message.role === \"user\";\n const text = message.parts\n .filter((p) => p.type === \"text\")\n .map((p) => (p as { text: string }).text)\n .join(\"\");\n\n return (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n isUser ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm\",\n isUser &&\n \"rounded-lg bg-secondary px-4 py-3 text-secondary-foreground\",\n )}\n >\n {message.parts.map((part, i)
|
|
1
|
+
{"version":3,"file":"Message.cjs","sources":["../../../src/data/chat/Message.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiGitBranch } from \"../../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { ToolCall } from \"./ToolCall\";\nimport { MessageActions } from \"./MessageActions\";\nimport { Reasoning } from \"./Reasoning\";\nimport type { UIMessage } from \"./types\";\nimport {\n isDynamicToolPart,\n isTypedToolPart,\n isReasoningPart,\n isFilePart,\n toolPartParentId,\n type AnyToolPart,\n type ToolResultRenderer,\n} from \"./types\";\nimport { forkSeedProvenance, isForkSeedMessage } from \"./fork-seed\";\nimport { MessageFilePart } from \"./MessageFilePart\";\n\n/** Callbacks the conversation threads down to each message. */\nexport type MessageActionHandlers = {\n /** Re-generate the assistant message with the given id. */\n onRegenerate?: ((messageId: string) => void) | undefined;\n /** Respond to a tool approval request. */\n onApprove?:\n | ((approvalId: string, approved: boolean, reason?: string) => void | Promise<unknown>)\n | undefined;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n};\n\nexport type MessageProps = MessageActionHandlers & {\n message: UIMessage;\n className?: string;\n};\n\n/** Renders one chat message. User messages are right-aligned bubbles; assistant\n * messages render text as markdown, reasoning and tool parts inline, file parts\n * as thumbnails/chips, and a hover action row (copy / regenerate). */\nexport function Message({\n message,\n className,\n onRegenerate,\n onApprove,\n renderToolResult,\n}: MessageProps) {\n if (isForkSeedMessage(message)) {\n return <ForkSeedMessage message={message} className={className} />;\n }\n const isUser = message.role === \"user\";\n const text = message.parts\n .filter((p) => p.type === \"text\")\n .map((p) => (p as { text: string }).text)\n .join(\"\");\n const { subcalls, nested } = groupSubagentCalls(message.parts);\n\n return (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n isUser ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm\",\n isUser &&\n \"rounded-lg bg-secondary px-4 py-3 text-secondary-foreground\",\n )}\n >\n {message.parts.map((part, i) =>\n nested.has(part) ? null : (\n <MessagePart\n key={`${message.id}-${i}`}\n part={part}\n isUser={isUser}\n onApprove={onApprove}\n renderToolResult={renderToolResult}\n subcalls={isToolPart(part) ? subcalls.get(part.toolCallId) : undefined}\n subcallsByParent={subcalls}\n />\n ),\n )}\n </div>\n\n {!isUser && text && (\n <MessageActions\n text={text}\n onRegenerate={\n onRegenerate ? () => onRegenerate(message.id) : undefined\n }\n />\n )}\n </div>\n );\n}\n\ntype MessagePartValue = UIMessage[\"parts\"][number];\n\nfunction isToolPart(part: MessagePartValue): part is AnyToolPart {\n return isDynamicToolPart(part) || isTypedToolPart(part);\n}\n\n/** Groups a subagent's tool calls under the call that spawned it. A call whose\n * parent is not in this message (e.g. a resumed turn) stays top-level. */\nfunction groupSubagentCalls(parts: UIMessage[\"parts\"]) {\n const callIds = new Set(\n parts.filter(isToolPart).map((part) => part.toolCallId),\n );\n const subcalls = new Map<string, AnyToolPart[]>();\n const nested = new Set<MessagePartValue>();\n for (const part of parts) {\n if (!isToolPart(part)) continue;\n const parent = toolPartParentId(part);\n if (!parent || !callIds.has(parent)) continue;\n subcalls.set(parent, [...(subcalls.get(parent) ?? []), part]);\n nested.add(part);\n }\n return { subcalls, nested };\n}\n\nfunction ForkSeedMessage({\n message,\n className,\n}: {\n message: UIMessage;\n className?: string | undefined;\n}) {\n const provenance = forkSeedProvenance(message);\n const transcript = message.parts\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\\n\");\n const label = provenance.title\n ? `Forked from ${provenance.title}`\n : \"Forked from another conversation\";\n return (\n <details\n className={cn(\n \"group/fork max-w-full self-center rounded-full border border-border bg-muted/40 px-3 py-1.5 text-xs text-muted-foreground open:w-full open:rounded-lg\",\n className,\n )}\n >\n <summary className=\"flex cursor-pointer list-none items-center justify-center gap-1.5 font-medium text-foreground/80\">\n <Icon icon={UiGitBranch} className=\"size-3.5\" />\n <span>{label}</span>\n </summary>\n {transcript && (\n <pre className=\"mt-2 max-h-64 overflow-auto whitespace-pre-wrap border-t border-border pt-2 font-mono text-[11px] text-muted-foreground\">\n {transcript}\n </pre>\n )}\n </details>\n );\n}\n\nfunction MessagePart({\n part,\n isUser,\n onApprove,\n renderToolResult,\n subcalls,\n subcallsByParent,\n}: {\n part: MessagePartValue;\n isUser: boolean;\n onApprove: MessageActionHandlers[\"onApprove\"];\n renderToolResult: MessageActionHandlers[\"renderToolResult\"];\n subcalls: AnyToolPart[] | undefined;\n subcallsByParent: ReadonlyMap<string, AnyToolPart[]>;\n}) {\n if (part.type === \"text\") {\n if (isUser) {\n return (\n <span className=\"whitespace-pre-wrap break-words\">{part.text}</span>\n );\n }\n return <Markdown text={part.text} />;\n }\n if (isReasoningPart(part)) {\n return <Reasoning text={part.text} />;\n }\n if (isFilePart(part)) {\n return <MessageFilePart part={part} />;\n }\n if (isToolPart(part)) {\n return (\n <ToolCall\n part={part}\n onApprove={onApprove}\n subcalls={subcalls}\n subcallsByParent={subcallsByParent}\n {...(renderToolResult ? { renderToolResult } : {})}\n />\n );\n }\n return null;\n}\n"],"names":["isForkSeedMessage","jsx","jsxs","cn","MessageActions","isDynamicToolPart","isTypedToolPart","toolPartParentId","forkSeedProvenance","Icon","UiGitBranch","Markdown","isReasoningPart","Reasoning","isFilePart","MessageFilePart","ToolCall"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ export type MessageActionHandlers = {
|
|
|
4
4
|
/** Re-generate the assistant message with the given id. */
|
|
5
5
|
onRegenerate?: ((messageId: string) => void) | undefined;
|
|
6
6
|
/** Respond to a tool approval request. */
|
|
7
|
-
onApprove?: ((approvalId: string, approved: boolean, reason?: string) => void) | undefined;
|
|
7
|
+
onApprove?: ((approvalId: string, approved: boolean, reason?: string) => void | Promise<unknown>) | undefined;
|
|
8
8
|
/** Optional host renderer for recognized completed tool outputs. */
|
|
9
9
|
renderToolResult?: ToolResultRenderer;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Message.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Message.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAOL,KAAK,kBAAkB,EACxB,MAAM,SAAS,CAAC;AAIjB,+DAA+D;AAC/D,MAAM,MAAM,qBAAqB,GAAG;IAClC,2DAA2D;IAC3D,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzD,0CAA0C;IAC1C,SAAS,CAAC,EACN,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GACrF,SAAS,CAAC;IACd,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG;IACjD,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;uEAEuE;AACvE,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,SAAS,EACT,YAAY,EACZ,SAAS,EACT,gBAAgB,GACjB,EAAE,YAAY,+BAmDd"}
|
|
@@ -5,7 +5,7 @@ import { Markdown } from "../Markdown.js";
|
|
|
5
5
|
import { ToolCall } from "./ToolCall.js";
|
|
6
6
|
import { MessageActions } from "./MessageActions.js";
|
|
7
7
|
import { Reasoning } from "./Reasoning.js";
|
|
8
|
-
import { isReasoningPart, isFilePart, isDynamicToolPart, isTypedToolPart } from "./types.js";
|
|
8
|
+
import { toolPartParentId, isReasoningPart, isFilePart, isDynamicToolPart, isTypedToolPart } from "./types.js";
|
|
9
9
|
import { isForkSeedMessage, forkSeedProvenance } from "./fork-seed.js";
|
|
10
10
|
import { MessageFilePart } from "./MessageFilePart.js";
|
|
11
11
|
import { UiGitBranch } from "../../icons/components/UiGitBranch.js";
|
|
@@ -21,6 +21,7 @@ function Message({
|
|
|
21
21
|
}
|
|
22
22
|
const isUser = message.role === "user";
|
|
23
23
|
const text = message.parts.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
24
|
+
const { subcalls, nested } = groupSubagentCalls(message.parts);
|
|
24
25
|
return /* @__PURE__ */ jsxs(
|
|
25
26
|
"div",
|
|
26
27
|
{
|
|
@@ -37,16 +38,20 @@ function Message({
|
|
|
37
38
|
"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm",
|
|
38
39
|
isUser && "rounded-lg bg-secondary px-4 py-3 text-secondary-foreground"
|
|
39
40
|
),
|
|
40
|
-
children: message.parts.map(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
children: message.parts.map(
|
|
42
|
+
(part, i) => nested.has(part) ? null : /* @__PURE__ */ jsx(
|
|
43
|
+
MessagePart,
|
|
44
|
+
{
|
|
45
|
+
part,
|
|
46
|
+
isUser,
|
|
47
|
+
onApprove,
|
|
48
|
+
renderToolResult,
|
|
49
|
+
subcalls: isToolPart(part) ? subcalls.get(part.toolCallId) : void 0,
|
|
50
|
+
subcallsByParent: subcalls
|
|
51
|
+
},
|
|
52
|
+
`${message.id}-${i}`
|
|
53
|
+
)
|
|
54
|
+
)
|
|
50
55
|
}
|
|
51
56
|
),
|
|
52
57
|
!isUser && text && /* @__PURE__ */ jsx(
|
|
@@ -60,6 +65,24 @@ function Message({
|
|
|
60
65
|
}
|
|
61
66
|
);
|
|
62
67
|
}
|
|
68
|
+
function isToolPart(part) {
|
|
69
|
+
return isDynamicToolPart(part) || isTypedToolPart(part);
|
|
70
|
+
}
|
|
71
|
+
function groupSubagentCalls(parts) {
|
|
72
|
+
const callIds = new Set(
|
|
73
|
+
parts.filter(isToolPart).map((part) => part.toolCallId)
|
|
74
|
+
);
|
|
75
|
+
const subcalls = /* @__PURE__ */ new Map();
|
|
76
|
+
const nested = /* @__PURE__ */ new Set();
|
|
77
|
+
for (const part of parts) {
|
|
78
|
+
if (!isToolPart(part)) continue;
|
|
79
|
+
const parent = toolPartParentId(part);
|
|
80
|
+
if (!parent || !callIds.has(parent)) continue;
|
|
81
|
+
subcalls.set(parent, [...subcalls.get(parent) ?? [], part]);
|
|
82
|
+
nested.add(part);
|
|
83
|
+
}
|
|
84
|
+
return { subcalls, nested };
|
|
85
|
+
}
|
|
63
86
|
function ForkSeedMessage({
|
|
64
87
|
message,
|
|
65
88
|
className
|
|
@@ -88,7 +111,9 @@ function MessagePart({
|
|
|
88
111
|
part,
|
|
89
112
|
isUser,
|
|
90
113
|
onApprove,
|
|
91
|
-
renderToolResult
|
|
114
|
+
renderToolResult,
|
|
115
|
+
subcalls,
|
|
116
|
+
subcallsByParent
|
|
92
117
|
}) {
|
|
93
118
|
if (part.type === "text") {
|
|
94
119
|
if (isUser) {
|
|
@@ -102,12 +127,14 @@ function MessagePart({
|
|
|
102
127
|
if (isFilePart(part)) {
|
|
103
128
|
return /* @__PURE__ */ jsx(MessageFilePart, { part });
|
|
104
129
|
}
|
|
105
|
-
if (
|
|
130
|
+
if (isToolPart(part)) {
|
|
106
131
|
return /* @__PURE__ */ jsx(
|
|
107
132
|
ToolCall,
|
|
108
133
|
{
|
|
109
134
|
part,
|
|
110
135
|
onApprove,
|
|
136
|
+
subcalls,
|
|
137
|
+
subcallsByParent,
|
|
111
138
|
...renderToolResult ? { renderToolResult } : {}
|
|
112
139
|
}
|
|
113
140
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.js","sources":["../../../src/data/chat/Message.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiGitBranch } from \"../../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { ToolCall } from \"./ToolCall\";\nimport { MessageActions } from \"./MessageActions\";\nimport { Reasoning } from \"./Reasoning\";\nimport type { UIMessage } from \"./types\";\nimport {\n isDynamicToolPart,\n isTypedToolPart,\n isReasoningPart,\n isFilePart,\n type AnyToolPart,\n type ToolResultRenderer,\n} from \"./types\";\nimport { forkSeedProvenance, isForkSeedMessage } from \"./fork-seed\";\nimport { MessageFilePart } from \"./MessageFilePart\";\n\n/** Callbacks the conversation threads down to each message. */\nexport type MessageActionHandlers = {\n /** Re-generate the assistant message with the given id. */\n onRegenerate?: ((messageId: string) => void) | undefined;\n /** Respond to a tool approval request. */\n onApprove?:\n | ((approvalId: string, approved: boolean, reason?: string) => void)\n | undefined;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n};\n\nexport type MessageProps = MessageActionHandlers & {\n message: UIMessage;\n className?: string;\n};\n\n/** Renders one chat message. User messages are right-aligned bubbles; assistant\n * messages render text as markdown, reasoning and tool parts inline, file parts\n * as thumbnails/chips, and a hover action row (copy / regenerate). */\nexport function Message({\n message,\n className,\n onRegenerate,\n onApprove,\n renderToolResult,\n}: MessageProps) {\n if (isForkSeedMessage(message)) {\n return <ForkSeedMessage message={message} className={className} />;\n }\n const isUser = message.role === \"user\";\n const text = message.parts\n .filter((p) => p.type === \"text\")\n .map((p) => (p as { text: string }).text)\n .join(\"\");\n\n return (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n isUser ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm\",\n isUser &&\n \"rounded-lg bg-secondary px-4 py-3 text-secondary-foreground\",\n )}\n >\n {message.parts.map((part, i)
|
|
1
|
+
{"version":3,"file":"Message.js","sources":["../../../src/data/chat/Message.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiGitBranch } from \"../../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { ToolCall } from \"./ToolCall\";\nimport { MessageActions } from \"./MessageActions\";\nimport { Reasoning } from \"./Reasoning\";\nimport type { UIMessage } from \"./types\";\nimport {\n isDynamicToolPart,\n isTypedToolPart,\n isReasoningPart,\n isFilePart,\n toolPartParentId,\n type AnyToolPart,\n type ToolResultRenderer,\n} from \"./types\";\nimport { forkSeedProvenance, isForkSeedMessage } from \"./fork-seed\";\nimport { MessageFilePart } from \"./MessageFilePart\";\n\n/** Callbacks the conversation threads down to each message. */\nexport type MessageActionHandlers = {\n /** Re-generate the assistant message with the given id. */\n onRegenerate?: ((messageId: string) => void) | undefined;\n /** Respond to a tool approval request. */\n onApprove?:\n | ((approvalId: string, approved: boolean, reason?: string) => void | Promise<unknown>)\n | undefined;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n};\n\nexport type MessageProps = MessageActionHandlers & {\n message: UIMessage;\n className?: string;\n};\n\n/** Renders one chat message. User messages are right-aligned bubbles; assistant\n * messages render text as markdown, reasoning and tool parts inline, file parts\n * as thumbnails/chips, and a hover action row (copy / regenerate). */\nexport function Message({\n message,\n className,\n onRegenerate,\n onApprove,\n renderToolResult,\n}: MessageProps) {\n if (isForkSeedMessage(message)) {\n return <ForkSeedMessage message={message} className={className} />;\n }\n const isUser = message.role === \"user\";\n const text = message.parts\n .filter((p) => p.type === \"text\")\n .map((p) => (p as { text: string }).text)\n .join(\"\");\n const { subcalls, nested } = groupSubagentCalls(message.parts);\n\n return (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n isUser ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm\",\n isUser &&\n \"rounded-lg bg-secondary px-4 py-3 text-secondary-foreground\",\n )}\n >\n {message.parts.map((part, i) =>\n nested.has(part) ? null : (\n <MessagePart\n key={`${message.id}-${i}`}\n part={part}\n isUser={isUser}\n onApprove={onApprove}\n renderToolResult={renderToolResult}\n subcalls={isToolPart(part) ? subcalls.get(part.toolCallId) : undefined}\n subcallsByParent={subcalls}\n />\n ),\n )}\n </div>\n\n {!isUser && text && (\n <MessageActions\n text={text}\n onRegenerate={\n onRegenerate ? () => onRegenerate(message.id) : undefined\n }\n />\n )}\n </div>\n );\n}\n\ntype MessagePartValue = UIMessage[\"parts\"][number];\n\nfunction isToolPart(part: MessagePartValue): part is AnyToolPart {\n return isDynamicToolPart(part) || isTypedToolPart(part);\n}\n\n/** Groups a subagent's tool calls under the call that spawned it. A call whose\n * parent is not in this message (e.g. a resumed turn) stays top-level. */\nfunction groupSubagentCalls(parts: UIMessage[\"parts\"]) {\n const callIds = new Set(\n parts.filter(isToolPart).map((part) => part.toolCallId),\n );\n const subcalls = new Map<string, AnyToolPart[]>();\n const nested = new Set<MessagePartValue>();\n for (const part of parts) {\n if (!isToolPart(part)) continue;\n const parent = toolPartParentId(part);\n if (!parent || !callIds.has(parent)) continue;\n subcalls.set(parent, [...(subcalls.get(parent) ?? []), part]);\n nested.add(part);\n }\n return { subcalls, nested };\n}\n\nfunction ForkSeedMessage({\n message,\n className,\n}: {\n message: UIMessage;\n className?: string | undefined;\n}) {\n const provenance = forkSeedProvenance(message);\n const transcript = message.parts\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\\n\");\n const label = provenance.title\n ? `Forked from ${provenance.title}`\n : \"Forked from another conversation\";\n return (\n <details\n className={cn(\n \"group/fork max-w-full self-center rounded-full border border-border bg-muted/40 px-3 py-1.5 text-xs text-muted-foreground open:w-full open:rounded-lg\",\n className,\n )}\n >\n <summary className=\"flex cursor-pointer list-none items-center justify-center gap-1.5 font-medium text-foreground/80\">\n <Icon icon={UiGitBranch} className=\"size-3.5\" />\n <span>{label}</span>\n </summary>\n {transcript && (\n <pre className=\"mt-2 max-h-64 overflow-auto whitespace-pre-wrap border-t border-border pt-2 font-mono text-[11px] text-muted-foreground\">\n {transcript}\n </pre>\n )}\n </details>\n );\n}\n\nfunction MessagePart({\n part,\n isUser,\n onApprove,\n renderToolResult,\n subcalls,\n subcallsByParent,\n}: {\n part: MessagePartValue;\n isUser: boolean;\n onApprove: MessageActionHandlers[\"onApprove\"];\n renderToolResult: MessageActionHandlers[\"renderToolResult\"];\n subcalls: AnyToolPart[] | undefined;\n subcallsByParent: ReadonlyMap<string, AnyToolPart[]>;\n}) {\n if (part.type === \"text\") {\n if (isUser) {\n return (\n <span className=\"whitespace-pre-wrap break-words\">{part.text}</span>\n );\n }\n return <Markdown text={part.text} />;\n }\n if (isReasoningPart(part)) {\n return <Reasoning text={part.text} />;\n }\n if (isFilePart(part)) {\n return <MessageFilePart part={part} />;\n }\n if (isToolPart(part)) {\n return (\n <ToolCall\n part={part}\n onApprove={onApprove}\n subcalls={subcalls}\n subcallsByParent={subcallsByParent}\n {...(renderToolResult ? { renderToolResult } : {})}\n />\n );\n }\n return null;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -46,10 +46,13 @@ function ToolCall({
|
|
|
46
46
|
renderToolResult,
|
|
47
47
|
tool,
|
|
48
48
|
registry: registryProp,
|
|
49
|
+
subcalls = [],
|
|
50
|
+
subcallsByParent,
|
|
49
51
|
className
|
|
50
52
|
}) {
|
|
51
53
|
const needsApproval = part.state === "approval-requested";
|
|
52
|
-
const [
|
|
54
|
+
const [userOpen, setOpen] = react.useState(defaultOpen || needsApproval);
|
|
55
|
+
const open = userOpen || needsApproval || hasPendingApproval(subcalls, subcallsByParent);
|
|
53
56
|
const contextRegistry = context.useToolRenderRegistry();
|
|
54
57
|
const registry = registryProp ?? contextRegistry;
|
|
55
58
|
const status = STATUS_ICON[part.state];
|
|
@@ -90,6 +93,7 @@ function ToolCall({
|
|
|
90
93
|
className: utils.cn("size-3 shrink-0", status.className)
|
|
91
94
|
}
|
|
92
95
|
),
|
|
96
|
+
subcalls.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-xs", children: subcallsLabel(subcalls) }) : null,
|
|
93
97
|
!open && summary ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-xs", children: summary }) : null
|
|
94
98
|
] }),
|
|
95
99
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -116,24 +120,72 @@ function ToolCall({
|
|
|
116
120
|
output: normalized.value,
|
|
117
121
|
...renderToolResult ? { renderToolResult } : {}
|
|
118
122
|
}
|
|
123
|
+
),
|
|
124
|
+
subcalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
125
|
+
"div",
|
|
126
|
+
{
|
|
127
|
+
"data-slot": "tool-call-subcalls",
|
|
128
|
+
className: "border-l border-border pl-2",
|
|
129
|
+
children: subcalls.map((call) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
130
|
+
ToolCall,
|
|
131
|
+
{
|
|
132
|
+
part: call,
|
|
133
|
+
subcalls: subcallsByParent == null ? void 0 : subcallsByParent.get(call.toolCallId),
|
|
134
|
+
subcallsByParent,
|
|
135
|
+
onApprove,
|
|
136
|
+
registry,
|
|
137
|
+
...renderToolResult ? { renderToolResult } : {}
|
|
138
|
+
},
|
|
139
|
+
call.toolCallId
|
|
140
|
+
))
|
|
141
|
+
}
|
|
119
142
|
)
|
|
120
143
|
] }),
|
|
121
144
|
needsApproval && /* @__PURE__ */ jsxRuntime.jsx(ApprovalControls, { part, onApprove })
|
|
122
145
|
] });
|
|
123
146
|
}
|
|
147
|
+
function hasPendingApproval(calls, grouped) {
|
|
148
|
+
return calls.some(
|
|
149
|
+
(call) => call.state === "approval-requested" || hasPendingApproval((grouped == null ? void 0 : grouped.get(call.toolCallId)) ?? [], grouped)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
function subcallsLabel(subcalls) {
|
|
153
|
+
const running = subcalls.filter(
|
|
154
|
+
(call) => call.state === "input-streaming" || call.state === "input-available"
|
|
155
|
+
).length;
|
|
156
|
+
const count = `${subcalls.length} ${subcalls.length === 1 ? "call" : "calls"}`;
|
|
157
|
+
return running > 0 ? `${count} · ${running} running` : count;
|
|
158
|
+
}
|
|
124
159
|
function ApprovalControls({
|
|
125
160
|
part,
|
|
126
161
|
onApprove
|
|
127
162
|
}) {
|
|
163
|
+
const [pending, setPending] = react.useState();
|
|
164
|
+
const [error, setError] = react.useState();
|
|
128
165
|
const approval = "approval" in part ? part.approval : void 0;
|
|
129
166
|
if (!approval || !onApprove) return null;
|
|
130
|
-
|
|
167
|
+
const decide = async (approved) => {
|
|
168
|
+
setPending(approved ? "approve" : "deny");
|
|
169
|
+
setError(void 0);
|
|
170
|
+
try {
|
|
171
|
+
await onApprove(approval.id, approved);
|
|
172
|
+
} catch (cause) {
|
|
173
|
+
setError(
|
|
174
|
+
`Cannot ${approved ? "approve" : "deny"} tool call: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
175
|
+
);
|
|
176
|
+
} finally {
|
|
177
|
+
setPending(void 0);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-2 pl-4", children: [
|
|
131
181
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
132
182
|
button.Button,
|
|
133
183
|
{
|
|
134
184
|
type: "button",
|
|
135
185
|
size: "sm",
|
|
136
|
-
|
|
186
|
+
loading: pending === "approve",
|
|
187
|
+
disabled: pending !== void 0,
|
|
188
|
+
onClick: () => void decide(true),
|
|
137
189
|
children: "Approve"
|
|
138
190
|
}
|
|
139
191
|
),
|
|
@@ -143,10 +195,13 @@ function ApprovalControls({
|
|
|
143
195
|
type: "button",
|
|
144
196
|
size: "sm",
|
|
145
197
|
variant: "outline",
|
|
146
|
-
|
|
198
|
+
loading: pending === "deny",
|
|
199
|
+
disabled: pending !== void 0,
|
|
200
|
+
onClick: () => void decide(false),
|
|
147
201
|
children: "Deny"
|
|
148
202
|
}
|
|
149
|
-
)
|
|
203
|
+
),
|
|
204
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "alert", className: "w-full text-xs text-destructive", children: error })
|
|
150
205
|
] });
|
|
151
206
|
}
|
|
152
207
|
function ToolOutput({
|