@jini-ai/chat 0.1.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/LICENSE +201 -0
- package/README.md +109 -0
- package/dist/core/agentic/chat-capabilities.d.ts +19 -0
- package/dist/core/agentic/chat-capabilities.d.ts.map +1 -0
- package/dist/core/agentic/chat-capabilities.js +106 -0
- package/dist/core/agentic/chat-capabilities.js.map +1 -0
- package/dist/core/agentic/index.d.ts +22 -0
- package/dist/core/agentic/index.d.ts.map +1 -0
- package/dist/core/agentic/index.js +21 -0
- package/dist/core/agentic/index.js.map +1 -0
- package/dist/core/events.d.ts +84 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +14 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +40 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/messages.d.ts +53 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +16 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/partial-json.d.ts +36 -0
- package/dist/core/partial-json.d.ts.map +1 -0
- package/dist/core/partial-json.js +119 -0
- package/dist/core/partial-json.js.map +1 -0
- package/dist/core/persistence/index.d.ts +11 -0
- package/dist/core/persistence/index.d.ts.map +1 -0
- package/dist/core/persistence/index.js +11 -0
- package/dist/core/persistence/index.js.map +1 -0
- package/dist/core/persistence/ports.d.ts +124 -0
- package/dist/core/persistence/ports.d.ts.map +1 -0
- package/dist/core/persistence/ports.js +2 -0
- package/dist/core/persistence/ports.js.map +1 -0
- package/dist/core/persistence/title.d.ts +35 -0
- package/dist/core/persistence/title.d.ts.map +1 -0
- package/dist/core/persistence/title.js +137 -0
- package/dist/core/persistence/title.js.map +1 -0
- package/dist/core/question-form/format.d.ts +27 -0
- package/dist/core/question-form/format.d.ts.map +1 -0
- package/dist/core/question-form/format.js +45 -0
- package/dist/core/question-form/format.js.map +1 -0
- package/dist/core/question-form/normalize.d.ts +30 -0
- package/dist/core/question-form/normalize.d.ts.map +1 -0
- package/dist/core/question-form/normalize.js +192 -0
- package/dist/core/question-form/normalize.js.map +1 -0
- package/dist/core/question-form/scan.d.ts +50 -0
- package/dist/core/question-form/scan.d.ts.map +1 -0
- package/dist/core/question-form/scan.js +404 -0
- package/dist/core/question-form/scan.js.map +1 -0
- package/dist/core/question-form/types.d.ts +83 -0
- package/dist/core/question-form/types.d.ts.map +1 -0
- package/dist/core/question-form/types.js +11 -0
- package/dist/core/question-form/types.js.map +1 -0
- package/dist/core/question-form.d.ts +39 -0
- package/dist/core/question-form.d.ts.map +1 -0
- package/dist/core/question-form.js +4 -0
- package/dist/core/question-form.js.map +1 -0
- package/dist/core/todos.d.ts +70 -0
- package/dist/core/todos.d.ts.map +1 -0
- package/dist/core/todos.js +175 -0
- package/dist/core/todos.js.map +1 -0
- package/dist/core/tool-events.d.ts +18 -0
- package/dist/core/tool-events.d.ts.map +1 -0
- package/dist/core/tool-events.js +36 -0
- package/dist/core/tool-events.js.map +1 -0
- package/dist/core/tools.d.ts +51 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +41 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/core/transcript.d.ts +81 -0
- package/dist/core/transcript.d.ts.map +1 -0
- package/dist/core/transcript.js +133 -0
- package/dist/core/transcript.js.map +1 -0
- package/dist/core/transport.d.ts +109 -0
- package/dist/core/transport.d.ts.map +1 -0
- package/dist/core/transport.js +2 -0
- package/dist/core/transport.js.map +1 -0
- package/dist/core/util/index.d.ts +16 -0
- package/dist/core/util/index.d.ts.map +1 -0
- package/dist/core/util/index.js +16 -0
- package/dist/core/util/index.js.map +1 -0
- package/dist/core/util/manifest.d.ts +39 -0
- package/dist/core/util/manifest.d.ts.map +1 -0
- package/dist/core/util/manifest.js +173 -0
- package/dist/core/util/manifest.js.map +1 -0
- package/dist/core/util/markdown-context.d.ts +47 -0
- package/dist/core/util/markdown-context.d.ts.map +1 -0
- package/dist/core/util/markdown-context.js +125 -0
- package/dist/core/util/markdown-context.js.map +1 -0
- package/dist/core/util/markup-attributes.d.ts +20 -0
- package/dist/core/util/markup-attributes.d.ts.map +1 -0
- package/dist/core/util/markup-attributes.js +33 -0
- package/dist/core/util/markup-attributes.js.map +1 -0
- package/dist/core/util/parser.d.ts +42 -0
- package/dist/core/util/parser.d.ts.map +1 -0
- package/dist/core/util/parser.js +238 -0
- package/dist/core/util/parser.js.map +1 -0
- package/dist/core/util/pointer.d.ts +28 -0
- package/dist/core/util/pointer.d.ts.map +1 -0
- package/dist/core/util/pointer.js +75 -0
- package/dist/core/util/pointer.js.map +1 -0
- package/dist/core/util/recover.d.ts +40 -0
- package/dist/core/util/recover.d.ts.map +1 -0
- package/dist/core/util/recover.js +117 -0
- package/dist/core/util/recover.js.map +1 -0
- package/dist/core/util/strip.d.ts +112 -0
- package/dist/core/util/strip.d.ts.map +1 -0
- package/dist/core/util/strip.js +333 -0
- package/dist/core/util/strip.js.map +1 -0
- package/dist/core/util/types.d.ts +31 -0
- package/dist/core/util/types.d.ts.map +1 -0
- package/dist/core/util/types.js +2 -0
- package/dist/core/util/types.js.map +1 -0
- package/dist/core/util/validate.d.ts +50 -0
- package/dist/core/util/validate.d.ts.map +1 -0
- package/dist/core/util/validate.js +202 -0
- package/dist/core/util/validate.js.map +1 -0
- package/dist/react/agent-bridge/frontend-session-bridge.d.ts +45 -0
- package/dist/react/agent-bridge/frontend-session-bridge.d.ts.map +1 -0
- package/dist/react/agent-bridge/frontend-session-bridge.js +214 -0
- package/dist/react/agent-bridge/frontend-session-bridge.js.map +1 -0
- package/dist/react/artifact-types.d.ts +61 -0
- package/dist/react/artifact-types.d.ts.map +1 -0
- package/dist/react/artifact-types.js +33 -0
- package/dist/react/artifact-types.js.map +1 -0
- package/dist/react/chat-pane.d.ts +21 -0
- package/dist/react/chat-pane.d.ts.map +1 -0
- package/dist/react/chat-pane.js +20 -0
- package/dist/react/chat-pane.js.map +1 -0
- package/dist/react/components/A2uiSurfaceCard.d.ts +35 -0
- package/dist/react/components/A2uiSurfaceCard.d.ts.map +1 -0
- package/dist/react/components/A2uiSurfaceCard.js +272 -0
- package/dist/react/components/A2uiSurfaceCard.js.map +1 -0
- package/dist/react/components/AttachmentTray.d.ts +6 -0
- package/dist/react/components/AttachmentTray.d.ts.map +1 -0
- package/dist/react/components/AttachmentTray.js +30 -0
- package/dist/react/components/AttachmentTray.js.map +1 -0
- package/dist/react/components/ChatFab.d.ts +8 -0
- package/dist/react/components/ChatFab.d.ts.map +1 -0
- package/dist/react/components/ChatFab.js +24 -0
- package/dist/react/components/ChatFab.js.map +1 -0
- package/dist/react/components/Composer.d.ts +34 -0
- package/dist/react/components/Composer.d.ts.map +1 -0
- package/dist/react/components/Composer.js +300 -0
- package/dist/react/components/Composer.js.map +1 -0
- package/dist/react/components/ComposerDiscovery.d.ts +46 -0
- package/dist/react/components/ComposerDiscovery.d.ts.map +1 -0
- package/dist/react/components/ComposerDiscovery.js +38 -0
- package/dist/react/components/ComposerDiscovery.js.map +1 -0
- package/dist/react/components/ConversationList.d.ts +31 -0
- package/dist/react/components/ConversationList.d.ts.map +1 -0
- package/dist/react/components/ConversationList.js +221 -0
- package/dist/react/components/ConversationList.js.map +1 -0
- package/dist/react/components/ExtEventErrorBoundary.d.ts +35 -0
- package/dist/react/components/ExtEventErrorBoundary.d.ts.map +1 -0
- package/dist/react/components/ExtEventErrorBoundary.js +38 -0
- package/dist/react/components/ExtEventErrorBoundary.js.map +1 -0
- package/dist/react/components/Icon.d.ts +17 -0
- package/dist/react/components/Icon.d.ts.map +1 -0
- package/dist/react/components/Icon.js +46 -0
- package/dist/react/components/Icon.js.map +1 -0
- package/dist/react/components/JiniChatProvider.d.ts +45 -0
- package/dist/react/components/JiniChatProvider.d.ts.map +1 -0
- package/dist/react/components/JiniChatProvider.js +44 -0
- package/dist/react/components/JiniChatProvider.js.map +1 -0
- package/dist/react/components/Markdown.d.ts +5 -0
- package/dist/react/components/Markdown.d.ts.map +1 -0
- package/dist/react/components/Markdown.js +390 -0
- package/dist/react/components/Markdown.js.map +1 -0
- package/dist/react/components/McpUiSurfaceCard.d.ts +51 -0
- package/dist/react/components/McpUiSurfaceCard.d.ts.map +1 -0
- package/dist/react/components/McpUiSurfaceCard.js +159 -0
- package/dist/react/components/McpUiSurfaceCard.js.map +1 -0
- package/dist/react/components/MessageList.d.ts +15 -0
- package/dist/react/components/MessageList.d.ts.map +1 -0
- package/dist/react/components/MessageList.js +81 -0
- package/dist/react/components/MessageList.js.map +1 -0
- package/dist/react/components/MessageRow.d.ts +60 -0
- package/dist/react/components/MessageRow.d.ts.map +1 -0
- package/dist/react/components/MessageRow.js +156 -0
- package/dist/react/components/MessageRow.js.map +1 -0
- package/dist/react/components/NextStepActions.d.ts +34 -0
- package/dist/react/components/NextStepActions.d.ts.map +1 -0
- package/dist/react/components/NextStepActions.js +9 -0
- package/dist/react/components/NextStepActions.js.map +1 -0
- package/dist/react/components/QuestionForm.d.ts +26 -0
- package/dist/react/components/QuestionForm.d.ts.map +1 -0
- package/dist/react/components/QuestionForm.js +238 -0
- package/dist/react/components/QuestionForm.js.map +1 -0
- package/dist/react/components/QuestionsPanel.d.ts +13 -0
- package/dist/react/components/QuestionsPanel.d.ts.map +1 -0
- package/dist/react/components/QuestionsPanel.js +33 -0
- package/dist/react/components/QuestionsPanel.js.map +1 -0
- package/dist/react/components/TodoCard.d.ts +8 -0
- package/dist/react/components/TodoCard.d.ts.map +1 -0
- package/dist/react/components/TodoCard.js +29 -0
- package/dist/react/components/TodoCard.js.map +1 -0
- package/dist/react/components/ToolCard.d.ts +22 -0
- package/dist/react/components/ToolCard.d.ts.map +1 -0
- package/dist/react/components/ToolCard.js +298 -0
- package/dist/react/components/ToolCard.js.map +1 -0
- package/dist/react/components/composer-discovery.d.ts +107 -0
- package/dist/react/components/composer-discovery.d.ts.map +1 -0
- package/dist/react/components/composer-discovery.js +176 -0
- package/dist/react/components/composer-discovery.js.map +1 -0
- package/dist/react/ext-event-renderer-registry.d.ts +51 -0
- package/dist/react/ext-event-renderer-registry.d.ts.map +1 -0
- package/dist/react/ext-event-renderer-registry.js +20 -0
- package/dist/react/ext-event-renderer-registry.js.map +1 -0
- package/dist/react/features/chat-pane/agent-tools.d.ts +14 -0
- package/dist/react/features/chat-pane/agent-tools.d.ts.map +1 -0
- package/dist/react/features/chat-pane/agent-tools.js +22 -0
- package/dist/react/features/chat-pane/agent-tools.js.map +1 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +12 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts.map +1 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +106 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.js.map +1 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts +10 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts.map +1 -0
- package/dist/react/features/chat-pane/components/ChatPane.js +169 -0
- package/dist/react/features/chat-pane/components/ChatPane.js.map +1 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts +21 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts.map +1 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +213 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js.map +1 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts +70 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts.map +1 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js +76 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +258 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +66 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +224 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +252 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts +16 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js +59 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js +74 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +88 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/index.d.ts +12 -0
- package/dist/react/features/chat-pane/index.d.ts.map +1 -0
- package/dist/react/features/chat-pane/index.js +11 -0
- package/dist/react/features/chat-pane/index.js.map +1 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts +12 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js +102 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js.map +1 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.d.ts +10 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.js +137 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js +258 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts +66 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js +223 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js +252 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js +60 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js +83 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/styles.d.ts +2 -0
- package/dist/react/features/chat-pane/react/styles.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/styles.js +863 -0
- package/dist/react/features/chat-pane/react/styles.js.map +1 -0
- package/dist/react/features/chat-pane/rules.d.ts +31 -0
- package/dist/react/features/chat-pane/rules.d.ts.map +1 -0
- package/dist/react/features/chat-pane/rules.js +81 -0
- package/dist/react/features/chat-pane/rules.js.map +1 -0
- package/dist/react/features/chat-pane/styles.d.ts +2 -0
- package/dist/react/features/chat-pane/styles.d.ts.map +1 -0
- package/dist/react/features/chat-pane/styles.js +1327 -0
- package/dist/react/features/chat-pane/styles.js.map +1 -0
- package/dist/react/features/chat-pane/types.d.ts +248 -0
- package/dist/react/features/chat-pane/types.d.ts.map +1 -0
- package/dist/react/features/chat-pane/types.js +2 -0
- package/dist/react/features/chat-pane/types.js.map +1 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +7 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts.map +1 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.js +20 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.js.map +1 -0
- package/dist/react/features/model-picker/components/ModelPicker.d.ts +9 -0
- package/dist/react/features/model-picker/components/ModelPicker.d.ts.map +1 -0
- package/dist/react/features/model-picker/components/ModelPicker.js +34 -0
- package/dist/react/features/model-picker/components/ModelPicker.js.map +1 -0
- package/dist/react/features/model-picker/constants.d.ts +6 -0
- package/dist/react/features/model-picker/constants.d.ts.map +1 -0
- package/dist/react/features/model-picker/constants.js +9 -0
- package/dist/react/features/model-picker/constants.js.map +1 -0
- package/dist/react/features/model-picker/dependencies.d.ts +11 -0
- package/dist/react/features/model-picker/dependencies.d.ts.map +1 -0
- package/dist/react/features/model-picker/dependencies.js +10 -0
- package/dist/react/features/model-picker/dependencies.js.map +1 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +27 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts.map +1 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +62 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js.map +1 -0
- package/dist/react/features/model-picker/index.d.ts +32 -0
- package/dist/react/features/model-picker/index.d.ts.map +1 -0
- package/dist/react/features/model-picker/index.js +29 -0
- package/dist/react/features/model-picker/index.js.map +1 -0
- package/dist/react/features/model-picker/ports.d.ts +11 -0
- package/dist/react/features/model-picker/ports.d.ts.map +1 -0
- package/dist/react/features/model-picker/ports.js +2 -0
- package/dist/react/features/model-picker/ports.js.map +1 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts +7 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js +20 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js.map +1 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.d.ts +9 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.js +34 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.js.map +1 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts +27 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js +62 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js.map +1 -0
- package/dist/react/features/model-picker/rules.d.ts +26 -0
- package/dist/react/features/model-picker/rules.d.ts.map +1 -0
- package/dist/react/features/model-picker/rules.js +84 -0
- package/dist/react/features/model-picker/rules.js.map +1 -0
- package/dist/react/features/model-picker/types.d.ts +38 -0
- package/dist/react/features/model-picker/types.d.ts.map +1 -0
- package/dist/react/features/model-picker/types.js +2 -0
- package/dist/react/features/model-picker/types.js.map +1 -0
- package/dist/react/hooks/composer-draft-cache.d.ts +65 -0
- package/dist/react/hooks/composer-draft-cache.d.ts.map +1 -0
- package/dist/react/hooks/composer-draft-cache.js +89 -0
- package/dist/react/hooks/composer-draft-cache.js.map +1 -0
- package/dist/react/hooks/context.d.ts +18 -0
- package/dist/react/hooks/context.d.ts.map +1 -0
- package/dist/react/hooks/context.js +60 -0
- package/dist/react/hooks/context.js.map +1 -0
- package/dist/react/hooks/testing/fake-transport.d.ts +34 -0
- package/dist/react/hooks/testing/fake-transport.d.ts.map +1 -0
- package/dist/react/hooks/testing/fake-transport.js +46 -0
- package/dist/react/hooks/testing/fake-transport.js.map +1 -0
- package/dist/react/hooks/useArtifactStream.d.ts +18 -0
- package/dist/react/hooks/useArtifactStream.d.ts.map +1 -0
- package/dist/react/hooks/useArtifactStream.js +55 -0
- package/dist/react/hooks/useArtifactStream.js.map +1 -0
- package/dist/react/hooks/useChatFabDrag.d.ts +25 -0
- package/dist/react/hooks/useChatFabDrag.d.ts.map +1 -0
- package/dist/react/hooks/useChatFabDrag.js +88 -0
- package/dist/react/hooks/useChatFabDrag.js.map +1 -0
- package/dist/react/hooks/useComposer.d.ts +48 -0
- package/dist/react/hooks/useComposer.d.ts.map +1 -0
- package/dist/react/hooks/useComposer.js +121 -0
- package/dist/react/hooks/useComposer.js.map +1 -0
- package/dist/react/hooks/useConversation.d.ts +34 -0
- package/dist/react/hooks/useConversation.d.ts.map +1 -0
- package/dist/react/hooks/useConversation.js +163 -0
- package/dist/react/hooks/useConversation.js.map +1 -0
- package/dist/react/hooks/useCopyToClipboard.d.ts +14 -0
- package/dist/react/hooks/useCopyToClipboard.d.ts.map +1 -0
- package/dist/react/hooks/useCopyToClipboard.js +98 -0
- package/dist/react/hooks/useCopyToClipboard.js.map +1 -0
- package/dist/react/hooks/useExtEventGroups.d.ts +7 -0
- package/dist/react/hooks/useExtEventGroups.d.ts.map +1 -0
- package/dist/react/hooks/useExtEventGroups.js +32 -0
- package/dist/react/hooks/useExtEventGroups.js.map +1 -0
- package/dist/react/hooks/useLatestOperation.d.ts +31 -0
- package/dist/react/hooks/useLatestOperation.d.ts.map +1 -0
- package/dist/react/hooks/useLatestOperation.js +74 -0
- package/dist/react/hooks/useLatestOperation.js.map +1 -0
- package/dist/react/hooks/usePinnedTodos.d.ts +15 -0
- package/dist/react/hooks/usePinnedTodos.d.ts.map +1 -0
- package/dist/react/hooks/usePinnedTodos.js +43 -0
- package/dist/react/hooks/usePinnedTodos.js.map +1 -0
- package/dist/react/hooks/useQuestionForms.d.ts +28 -0
- package/dist/react/hooks/useQuestionForms.d.ts.map +1 -0
- package/dist/react/hooks/useQuestionForms.js +113 -0
- package/dist/react/hooks/useQuestionForms.js.map +1 -0
- package/dist/react/hooks/useRunStream.d.ts +27 -0
- package/dist/react/hooks/useRunStream.d.ts.map +1 -0
- package/dist/react/hooks/useRunStream.js +180 -0
- package/dist/react/hooks/useRunStream.js.map +1 -0
- package/dist/react/hooks/useToolTimeline.d.ts +33 -0
- package/dist/react/hooks/useToolTimeline.d.ts.map +1 -0
- package/dist/react/hooks/useToolTimeline.js +47 -0
- package/dist/react/hooks/useToolTimeline.js.map +1 -0
- package/dist/react/index.d.ts +158 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +118 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/message-blocks.d.ts +86 -0
- package/dist/react/message-blocks.d.ts.map +1 -0
- package/dist/react/message-blocks.js +78 -0
- package/dist/react/message-blocks.js.map +1 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +9 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts.map +1 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +29 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js.map +1 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +30 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts.map +1 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.js +44 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.js.map +1 -0
- package/dist/react/slots.d.ts +215 -0
- package/dist/react/slots.d.ts.map +1 -0
- package/dist/react/slots.js +2 -0
- package/dist/react/slots.js.map +1 -0
- package/dist/react/styles/reference.css +298 -0
- package/dist/react/tool-renderer-registry.d.ts +41 -0
- package/dist/react/tool-renderer-registry.d.ts.map +1 -0
- package/dist/react/tool-renderer-registry.js +22 -0
- package/dist/react/tool-renderer-registry.js.map +1 -0
- package/dist/react/util/defined-props.d.ts +31 -0
- package/dist/react/util/defined-props.d.ts.map +1 -0
- package/dist/react/util/defined-props.js +28 -0
- package/dist/react/util/defined-props.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { WorkingDirPicker } from '@jini-ai/ui';
|
|
4
|
+
import { Composer } from '../../../components/Composer.js';
|
|
5
|
+
import { appendComposerDiscovery } from '../../../components/composer-discovery.js';
|
|
6
|
+
import { MessageList } from '../../../components/MessageList.js';
|
|
7
|
+
import { useT } from '../../../hooks/context.js';
|
|
8
|
+
import { definedProps } from '../../../util/defined-props.js';
|
|
9
|
+
import { useChatPane } from '../hooks/useChatPane.hooks.js';
|
|
10
|
+
import { useChatPaneAgentControl } from '../hooks/useChatPaneAgentControl.hooks.js';
|
|
11
|
+
import { useChatPaneControlsHeight } from '../hooks/useChatPaneControlsHeight.hooks.js';
|
|
12
|
+
import { useChatPaneFileDrop, } from '../hooks/useChatPaneFileDrop.hooks.js';
|
|
13
|
+
import { useChatPaneRuntimeInventory, } from '../hooks/useChatPaneRuntimeInventory.hooks.js';
|
|
14
|
+
import { CHAT_PANE_STYLES } from '../styles.js';
|
|
15
|
+
import { AgentRuntimePicker } from './AgentRuntimePicker.js';
|
|
16
|
+
const EMPTY_AGENTS = [];
|
|
17
|
+
function defaultHeader(title, onReset, t) {
|
|
18
|
+
return (_jsxs("div", { className: "jini-chat-pane__header", children: [_jsxs("div", { className: "jini-chat-pane__heading", children: [_jsx("span", { className: "jini-chat-pane__eyebrow", children: t('Workspace chat') }), _jsx("h1", { className: "jini-chat-pane__title", children: title ?? t('Chat') })] }), _jsx("button", { type: "button", className: "jini-chat-pane__new-thread", onClick: onReset, children: t('New thread') })] }));
|
|
19
|
+
}
|
|
20
|
+
/** Collapses `header ?? defaultHeader(...)` out of `ChatPane` itself — nesting is what taxes the
|
|
21
|
+
* `??` in the caller's score, not the branch itself. */
|
|
22
|
+
function resolveChatPaneHeader(header, title, onReset, t) {
|
|
23
|
+
return header ?? defaultHeader(title, onReset, t);
|
|
24
|
+
}
|
|
25
|
+
function chatPaneClassName(variant, className) {
|
|
26
|
+
return `jini-chat-pane jini-chat-pane--${variant}${className ? ` ${className}` : ''}`;
|
|
27
|
+
}
|
|
28
|
+
function resolveRuntimeAccessView(runtimeAccess, injectedAgents, scanningAgents, daemonOnline, onRescanAgents, inventory) {
|
|
29
|
+
if (runtimeAccess === undefined) {
|
|
30
|
+
return { agents: injectedAgents, scanningAgents, daemonOnline, rescanAgents: onRescanAgents };
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
agents: inventory.agents,
|
|
34
|
+
scanningAgents: inventory.scanningAgents,
|
|
35
|
+
daemonOnline: inventory.daemonOnline,
|
|
36
|
+
rescanAgents: () => void inventory.rescanAgents(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function ChatPaneSuggestionsRow({ suggestions, onSelect, t }) {
|
|
40
|
+
if (suggestions.length === 0)
|
|
41
|
+
return null;
|
|
42
|
+
return (_jsx("div", { className: "jini-chat-pane__suggestions", "aria-label": t('Example prompts'), children: suggestions.map((suggestion) => (_jsx("button", { type: "button", className: "jini-chat-pane__suggestion", onClick: () => onSelect(suggestion), children: suggestion }, suggestion))) }));
|
|
43
|
+
}
|
|
44
|
+
/** The pane's stack of mutually-independent error/status banners — each condition is its own
|
|
45
|
+
* source of truth, so they are rendered as siblings rather than folded into one derived state. */
|
|
46
|
+
function ChatPaneStatusMessages({ unavailable, scanningAgents, conversationError, attachmentError, dropReadError, workingDirectoryError, workingDirectoryPending, workingDirectoryInvalid, runtimeInventoryError, t, }) {
|
|
47
|
+
return (_jsxs(_Fragment, { children: [unavailable && scanningAgents ? (_jsx("div", { className: "jini-chat-pane__status", role: "status", children: t('Loading available CLIs') })) : unavailable ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: t('No usable CLI is selected.') })) : null, conversationError ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: conversationError.message })) : null, attachmentError ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: attachmentError.message })) : null, dropReadError ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: dropReadError })) : null, workingDirectoryError ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: workingDirectoryError.message })) : null, workingDirectoryPending ? (_jsx("div", { className: "jini-chat-pane__status", role: "status", children: t('Checking working directory…') })) : workingDirectoryInvalid ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: t('Working directory is unavailable.') })) : null, runtimeInventoryError ? (_jsx("div", { className: "jini-chat-pane__error", role: "alert", children: runtimeInventoryError.message })) : null] }));
|
|
48
|
+
}
|
|
49
|
+
function ChatPaneWorkingDirectoryBlock({ workingDirectoryAccess, pane, t, }) {
|
|
50
|
+
if (workingDirectoryAccess) {
|
|
51
|
+
return (_jsx("div", { className: "jini-chat-pane__workdir", children: _jsx(WorkingDirPicker, { workingDir: pane.workingDirectory, recentDirs: [...pane.recentDirectories], onPickDirectory: () => void pane.pickWorkingDirectory(), onSelectRecent: (directory) => void pane.selectRecentDirectory(directory), placement: "up", onClear: pane.clearWorkingDirectory, invalid: pane.workingDirectoryInvalid, onOpen: () => void pane.openWorkingDirectoryPicker(), labels: { trigger: t('Select working directory') } }) }));
|
|
52
|
+
}
|
|
53
|
+
if (pane.workingDirectory) {
|
|
54
|
+
return (_jsxs("div", { className: "jini-chat-pane__workdir", children: [_jsx("strong", { children: t('Working directory') }), _jsx("code", { children: pane.workingDirectory })] }));
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/** `uploadAttachments === undefined` gates BOTH of these — a temporarily-disabled composer still
|
|
59
|
+
* consumes a file drop so the browser cannot navigate away to the local file (see
|
|
60
|
+
* `useChatPaneFileDrop`'s module doc), so the drop handlers stay attached even when the picker
|
|
61
|
+
* itself is hidden. Shared here so `ChatPaneComposerArea` pays for the branch once, at module
|
|
62
|
+
* scope, instead of per call site. */
|
|
63
|
+
function resolveDropTargetProps(uploadAttachments, fileDrop) {
|
|
64
|
+
return uploadAttachments === undefined ? {} : fileDrop.targetProps;
|
|
65
|
+
}
|
|
66
|
+
function resolveComposerAttachmentPicker(uploadAttachments, pane, attachmentAccept) {
|
|
67
|
+
if (uploadAttachments === undefined)
|
|
68
|
+
return {};
|
|
69
|
+
return {
|
|
70
|
+
attachmentPicker: definedProps({
|
|
71
|
+
onFiles: pane.addAttachments,
|
|
72
|
+
uploading: pane.isUploadingAttachments,
|
|
73
|
+
accept: attachmentAccept,
|
|
74
|
+
}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** The drop target, composer, and working-directory block — everything below the status banners
|
|
78
|
+
* that reads/writes the live pane. Cancelling an in-flight run is not a separate control here: it
|
|
79
|
+
* lives in the composer's own trailing button, which swaps from send to stop while streaming (see
|
|
80
|
+
* `Composer`'s `running`/`onCancel` props) — the same control an operator's attention is already
|
|
81
|
+
* on, rather than a second affordance elsewhere in the pane they'd have to go find. */
|
|
82
|
+
function ChatPaneComposerArea({ fileDrop, uploadAttachments, pane, disabled, unavailable, placeholder, slots, attachmentAccept, workingDirectoryAccess, t, }) {
|
|
83
|
+
return (_jsxs("div", { className: `jini-chat-pane__drop-target${fileDrop.draggingFiles ? ' is-dragging-files' : ''}`, "data-testid": "chat-pane-file-drop-target", "data-dragging-files": fileDrop.draggingFiles ? 'true' : 'false', ...resolveDropTargetProps(uploadAttachments, fileDrop), children: [fileDrop.draggingFiles ? (_jsx("span", { className: "jini-chat-pane__drop-announcement", role: "status", children: t('Drop files to attach') })) : null, _jsx(Composer, { composer: pane.composer, onSend: () => void pane.send(), disabled: disabled || unavailable || pane.conversation.isStreaming, sendDisabled: !pane.canSend, running: pane.conversation.isStreaming, onCancel: pane.conversation.cancel, ...definedProps({ placeholder }), slots: slots, ...resolveComposerAttachmentPicker(uploadAttachments, pane, attachmentAccept) }), _jsx(ChatPaneWorkingDirectoryBlock, { workingDirectoryAccess: workingDirectoryAccess, pane: pane, t: t })] }));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Renders the self-contained chat-pane composition, including runtime and
|
|
87
|
+
* working-directory orchestration owned by `@jini-ai/chat-react`.
|
|
88
|
+
*
|
|
89
|
+
* @complexity Time/space: O(n) in rendered messages, agents, and suggestions.
|
|
90
|
+
* @overallScore 100/100
|
|
91
|
+
*/
|
|
92
|
+
export function ChatPane({ transport, agents: injectedAgents = EMPTY_AGENTS, runtimeAccess, runtimeStatusPollMs = 5_000, title, variant = 'workspace', initialMessages, conversationId, initialSelection, selection: controlledSelection, onSelectionChange, runContext, agentControl, onActivityChange, onMessagesChange, onRescanAgents, scanningAgents = false, daemonOnline = true, executionMode = 'local', apiModeAvailable = false, onExecutionModeChange, byokRuntime, onByokModelChange, initialDraft, composerHandle, placeholder, suggestions = [], workingDirectory, initialWorkingDirectory, onChangeWorkingDirectory, workingDirectoryAccess, projectFileNames, uploadAttachments, attachmentAccept, disabled = false, runtimePickerPlacement = 'up', composerSlots, header, leadingAccessory, footer, className, style, }) {
|
|
93
|
+
const t = useT();
|
|
94
|
+
const inventory = useChatPaneRuntimeInventory(definedProps({
|
|
95
|
+
access: runtimeAccess,
|
|
96
|
+
initialAgents: injectedAgents,
|
|
97
|
+
pollIntervalMs: runtimeStatusPollMs,
|
|
98
|
+
}));
|
|
99
|
+
const runtimeView = resolveRuntimeAccessView(runtimeAccess, injectedAgents, scanningAgents, daemonOnline, onRescanAgents, inventory);
|
|
100
|
+
const pane = useChatPane(definedProps({
|
|
101
|
+
transport,
|
|
102
|
+
agents: runtimeView.agents,
|
|
103
|
+
initialMessages,
|
|
104
|
+
conversationId,
|
|
105
|
+
initialSelection,
|
|
106
|
+
selection: controlledSelection,
|
|
107
|
+
onSelectionChange,
|
|
108
|
+
runContext,
|
|
109
|
+
initialDraft,
|
|
110
|
+
uploadAttachments,
|
|
111
|
+
onActivityChange,
|
|
112
|
+
onMessagesChange,
|
|
113
|
+
workingDirectory,
|
|
114
|
+
initialWorkingDirectory,
|
|
115
|
+
onChangeWorkingDirectory,
|
|
116
|
+
workingDirectoryAccess,
|
|
117
|
+
}));
|
|
118
|
+
// Mirrors `Composer.tsx`'s own `draftRef`: `composerHandle.insertText` (below) is called from
|
|
119
|
+
// OUTSIDE any render, so it cannot close over `pane.composer.draft` directly — that would freeze
|
|
120
|
+
// it at whatever the draft was on the render that captured it. Reassigned unconditionally every
|
|
121
|
+
// render, same as its counterpart.
|
|
122
|
+
const composerDraftRef = useRef(pane.composer.draft);
|
|
123
|
+
composerDraftRef.current = pane.composer.draft;
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if (!composerHandle)
|
|
126
|
+
return;
|
|
127
|
+
composerHandle.current = {
|
|
128
|
+
insertText: (text) => {
|
|
129
|
+
pane.composer.setDraft(appendComposerDiscovery(composerDraftRef.current, text));
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
return () => {
|
|
133
|
+
composerHandle.current = null;
|
|
134
|
+
};
|
|
135
|
+
// `pane.composer` is a fresh object every render `useComposer` produces (see its own `useMemo`
|
|
136
|
+
// deps), so depending on it here just means this effect re-publishes a new (equally correct)
|
|
137
|
+
// closure on every render rather than genuinely skipping renders — cheap, and it keeps
|
|
138
|
+
// `pane.composer.setDraft` from ever going stale if that reference ever changes.
|
|
139
|
+
}, [composerHandle, pane.composer]);
|
|
140
|
+
// No `runContext` here on purpose: agent-driven sends go through `pane.sendPrompt`, which builds
|
|
141
|
+
// the context from the SAME `runContext` already handed to `useChatPane` above. A second copy
|
|
142
|
+
// would be a second source of truth that could silently drift from the composer's.
|
|
143
|
+
useChatPaneAgentControl(pane, definedProps({
|
|
144
|
+
enabled: agentControl?.enabled ?? false,
|
|
145
|
+
bridgeAccess: agentControl?.bridgeAccess,
|
|
146
|
+
}));
|
|
147
|
+
// Selection resolution only returns available agents, so absence is the
|
|
148
|
+
// single fail-closed state the view needs to represent.
|
|
149
|
+
const unavailable = pane.selectedAgent === undefined;
|
|
150
|
+
const fileDrop = useChatPaneFileDrop({
|
|
151
|
+
enabled: uploadAttachments !== undefined
|
|
152
|
+
&& !disabled
|
|
153
|
+
&& !unavailable
|
|
154
|
+
&& !pane.conversation.isStreaming
|
|
155
|
+
&& !pane.isUploadingAttachments,
|
|
156
|
+
onFiles: pane.addAttachments,
|
|
157
|
+
});
|
|
158
|
+
// `composerSlots`'s type excludes both `leadingAccessories` and `footerAccessories` (see
|
|
159
|
+
// `ChatPaneProps.composerSlots`'s doc), so the two explicit keys below are never overwriting a
|
|
160
|
+
// caller-supplied value — they are the ONLY source for both.
|
|
161
|
+
const slots = definedProps({
|
|
162
|
+
...composerSlots,
|
|
163
|
+
leadingAccessories: leadingAccessory,
|
|
164
|
+
footerAccessories: (_jsx(AgentRuntimePicker, { agents: runtimeView.agents, value: pane.selection, onChange: pane.setSelection, ...definedProps({ onRescan: runtimeView.rescanAgents }), scanning: runtimeView.scanningAgents, daemonOnline: runtimeView.daemonOnline, placement: runtimePickerPlacement, executionMode: executionMode, apiModeAvailable: apiModeAvailable, ...definedProps({ onExecutionModeChange, byokRuntime, onByokModelChange }) })),
|
|
165
|
+
});
|
|
166
|
+
const { rootRef, controlsRef } = useChatPaneControlsHeight();
|
|
167
|
+
return (_jsxs("section", { className: chatPaneClassName(variant, className), style: style, "data-activity": pane.activity, ref: rootRef, children: [_jsx("style", { "data-jini-chat-pane-styles": "true", children: CHAT_PANE_STYLES }), resolveChatPaneHeader(header, title, pane.reset, t), _jsxs("div", { className: "jini-chat-pane__body", children: [_jsx(MessageList, { messages: pane.conversation.messages, isStreaming: pane.conversation.isStreaming, scrollIntent: pane.conversation.scrollIntent, onScrolled: pane.conversation.acknowledgeScroll, ...(projectFileNames === undefined ? {} : { projectFileNames: new Set(projectFileNames) }) }), _jsxs("div", { className: "jini-chat-pane__controls", ref: controlsRef, children: [_jsx(ChatPaneSuggestionsRow, { suggestions: suggestions, onSelect: pane.composer.setDraft, t: t }), _jsx(ChatPaneStatusMessages, { unavailable: unavailable, scanningAgents: runtimeView.scanningAgents, conversationError: pane.conversation.error, attachmentError: pane.attachmentError, dropReadError: fileDrop.dropReadError, workingDirectoryError: pane.workingDirectoryError, workingDirectoryPending: pane.workingDirectoryPending, workingDirectoryInvalid: pane.workingDirectoryInvalid, runtimeInventoryError: inventory.runtimeInventoryError, t: t }), _jsx(ChatPaneComposerArea, { fileDrop: fileDrop, uploadAttachments: uploadAttachments, pane: pane, disabled: disabled, unavailable: unavailable, placeholder: placeholder, slots: slots, attachmentAccept: attachmentAccept, workingDirectoryAccess: workingDirectoryAccess, t: t })] })] }), footer] }));
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=ChatPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatPane.js","sourceRoot":"","sources":["../../../../../src/react/features/chat-pane/components/ChatPane.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAQ9D,OAAO,EAAE,WAAW,EAA0B,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EACL,mBAAmB,GAGpB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,2BAA2B,GAE5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,YAAY,GAAyC,EAAE,CAAC;AAE9D,SAAS,aAAa,CACpB,KAAyB,EACzB,OAAmB,EACnB,CAA0B;IAE1B,OAAO,CACL,eAAK,SAAS,EAAC,wBAAwB,aACrC,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAM,SAAS,EAAC,yBAAyB,YAAE,CAAC,CAAC,gBAAgB,CAAC,GAAQ,EACtE,aAAI,SAAS,EAAC,uBAAuB,YAAE,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,GAAM,IAC3D,EACN,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,4BAA4B,EAAC,OAAO,EAAE,OAAO,YAC1E,CAAC,CAAC,YAAY,CAAC,GACT,IACL,CACP,CAAC;AACJ,CAAC;AAED;wDACwD;AACxD,SAAS,qBAAqB,CAC5B,MAA6B,EAC7B,KAAyB,EACzB,OAAmB,EACnB,CAA0B;IAE1B,OAAO,MAAM,IAAI,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAwB,EAAE,SAA6B;IAChF,OAAO,kCAAkC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACxF,CAAC;AAWD,SAAS,wBAAwB,CAC/B,aAAgD,EAChD,cAAwC,EACxC,cAAuB,EACvB,YAAqB,EACrB,cAAwC,EACxC,SAA4C;IAE5C,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC;IAChG,CAAC;IACD,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,YAAY,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,YAAY,EAAE;KAClD,CAAC;AACJ,CAAC;AAQD,SAAS,sBAAsB,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAA+B;IACvF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,CACL,cAAK,SAAS,EAAC,6BAA6B,gBAAa,CAAC,CAAC,iBAAiB,CAAC,YAC1E,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAC/B,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,4BAA4B,EAEtC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,YAElC,UAAU,IAHN,UAAU,CAIR,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAeD;kGACkG;AAClG,SAAS,sBAAsB,CAAC,EAC9B,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,CAAC,GAC2B;IAC5B,OAAO,CACL,8BAMG,WAAW,IAAI,cAAc,CAAC,CAAC,CAAC,CAC/B,cAAK,SAAS,EAAC,wBAAwB,EAAC,IAAI,EAAC,QAAQ,YAClD,CAAC,CAAC,wBAAwB,CAAC,GACxB,CACP,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAChB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAAE,CAAC,CAAC,4BAA4B,CAAC,GAAO,CAC5F,CAAC,CAAC,CAAC,IAAI,EACP,iBAAiB,CAAC,CAAC,CAAC,CACnB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAAE,iBAAiB,CAAC,OAAO,GAAO,CACtF,CAAC,CAAC,CAAC,IAAI,EACP,eAAe,CAAC,CAAC,CAAC,CACjB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAAE,eAAe,CAAC,OAAO,GAAO,CACpF,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,CAAC,CAAC,CACf,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAAE,aAAa,GAAO,CAC1E,CAAC,CAAC,CAAC,IAAI,EACP,qBAAqB,CAAC,CAAC,CAAC,CACvB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAAE,qBAAqB,CAAC,OAAO,GAAO,CAC1F,CAAC,CAAC,CAAC,IAAI,EACP,uBAAuB,CAAC,CAAC,CAAC,CACzB,cAAK,SAAS,EAAC,wBAAwB,EAAC,IAAI,EAAC,QAAQ,YAClD,CAAC,CAAC,6BAA6B,CAAC,GAC7B,CACP,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAC5B,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAChD,CAAC,CAAC,mCAAmC,CAAC,GACnC,CACP,CAAC,CAAC,CAAC,IAAI,EACP,qBAAqB,CAAC,CAAC,CAAC,CACvB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAChD,qBAAqB,CAAC,OAAO,GAC1B,CACP,CAAC,CAAC,CAAC,IAAI,IACP,CACJ,CAAC;AACJ,CAAC;AAQD,SAAS,6BAA6B,CAAC,EACrC,sBAAsB,EACtB,IAAI,EACJ,CAAC,GACkC;IACnC,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,CACL,cAAK,SAAS,EAAC,yBAAyB,YACtC,KAAC,gBAAgB,IACf,UAAU,EAAE,IAAI,CAAC,gBAAgB,EACjC,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,EACvC,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,oBAAoB,EAAE,EACvD,cAAc,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EACzE,SAAS,EAAC,IAAI,EACd,OAAO,EAAE,IAAI,CAAC,qBAAqB,EACnC,OAAO,EAAE,IAAI,CAAC,uBAAuB,EACrC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,0BAA0B,EAAE,EACpD,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,0BAA0B,CAAC,EAAE,GAClD,GACE,CACP,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,2BAAS,CAAC,CAAC,mBAAmB,CAAC,GAAU,EACzC,yBAAO,IAAI,CAAC,gBAAgB,GAAQ,IAChC,CACP,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;sCAIsC;AACtC,SAAS,sBAAsB,CAC7B,iBAAqD,EACrD,QAAmC;IAEnC,OAAO,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;AACrE,CAAC;AAED,SAAS,+BAA+B,CACtC,iBAAqD,EACrD,IAAuB,EACvB,gBAAmD;IAEnD,IAAI,iBAAiB,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAC/C,OAAO;QACL,gBAAgB,EAAE,YAAY,CAAC;YAC7B,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,SAAS,EAAE,IAAI,CAAC,sBAAsB;YACtC,MAAM,EAAE,gBAAgB;SACzB,CAAC;KACH,CAAC;AACJ,CAAC;AAeD;;;;uFAIuF;AACvF,SAAS,oBAAoB,CAAC,EAC5B,QAAQ,EACR,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,WAAW,EACX,KAAK,EACL,gBAAgB,EAChB,sBAAsB,EACtB,CAAC,GACyB;IAC1B,OAAO,CACL,eACE,SAAS,EAAE,8BAA8B,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,iBACjF,4BAA4B,yBACnB,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAC1D,sBAAsB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAEtD,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CACxB,eAAM,SAAS,EAAC,mCAAmC,EAAC,IAAI,EAAC,QAAQ,YAC9D,CAAC,CAAC,sBAAsB,CAAC,GACrB,CACR,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,QAAQ,IACP,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,EAC9B,QAAQ,EAAE,QAAQ,IAAI,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAClE,YAAY,EAAE,CAAC,IAAI,CAAC,OAAO,EAC3B,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EACtC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,KAC9B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EACjC,KAAK,EAAE,KAAK,KACR,+BAA+B,CAAC,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,CAAC,GAC9E,EACF,KAAC,6BAA6B,IAAC,sBAAsB,EAAE,sBAAsB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,GAAI,IAC/F,CACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,SAAS,EACT,MAAM,EAAE,cAAc,GAAG,YAAY,EACrC,aAAa,EACb,mBAAmB,GAAG,KAAK,EAC3B,KAAK,EACL,OAAO,GAAG,WAAW,EACrB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,GAAG,KAAK,EACtB,YAAY,GAAG,IAAI,EACnB,aAAa,GAAG,OAAO,EACvB,gBAAgB,GAAG,KAAK,EACxB,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,GAAG,EAAE,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,GAAG,KAAK,EAChB,sBAAsB,GAAG,IAAI,EAC7B,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,SAAS,EACT,KAAK,GACS;IACd,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,SAAS,GAAG,2BAA2B,CAAC,YAAY,CAAC;QACzD,MAAM,EAAE,aAAa;QACrB,aAAa,EAAE,cAAc;QAC7B,cAAc,EAAE,mBAAmB;KACpC,CAAC,CAAC,CAAC;IACJ,MAAM,WAAW,GAAG,wBAAwB,CAC1C,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,cAAc,EACd,SAAS,CACV,CAAC;IACF,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC;QACpC,SAAS;QACT,MAAM,EAAE,WAAW,CAAC,MAAM;QAC1B,eAAe;QACf,cAAc;QACd,gBAAgB;QAChB,SAAS,EAAE,mBAAmB;QAC9B,iBAAiB;QACjB,UAAU;QACV,YAAY;QACZ,iBAAiB;QACjB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,uBAAuB;QACvB,wBAAwB;QACxB,sBAAsB;KACvB,CAAC,CAAC,CAAC;IACJ,8FAA8F;IAC9F,iGAAiG;IACjG,gGAAgG;IAChG,mCAAmC;IACnC,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC/C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,cAAc;YAAE,OAAO;QAC5B,cAAc,CAAC,OAAO,GAAG;YACvB,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAClF,CAAC;SACF,CAAC;QACF,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,CAAC,CAAC;QACF,+FAA+F;QAC/F,6FAA6F;QAC7F,uFAAuF;QACvF,iFAAiF;IACnF,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpC,iGAAiG;IACjG,8FAA8F;IAC9F,mFAAmF;IACnF,uBAAuB,CAAC,IAAI,EAAE,YAAY,CAAC;QACzC,OAAO,EAAE,YAAY,EAAE,OAAO,IAAI,KAAK;QACvC,YAAY,EAAE,YAAY,EAAE,YAAY;KACzC,CAAC,CAAC,CAAC;IACJ,wEAAwE;IACxE,wDAAwD;IACxD,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC;IACrD,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,OAAO,EAAE,iBAAiB,KAAK,SAAS;eACnC,CAAC,QAAQ;eACT,CAAC,WAAW;eACZ,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW;eAC9B,CAAC,IAAI,CAAC,sBAAsB;QACjC,OAAO,EAAE,IAAI,CAAC,cAAc;KAC7B,CAAC,CAAC;IACH,yFAAyF;IACzF,+FAA+F;IAC/F,6DAA6D;IAC7D,MAAM,KAAK,GAAkB,YAAY,CAAC;QACxC,GAAG,aAAa;QAChB,kBAAkB,EAAE,gBAAgB;QACpC,iBAAiB,EAAE,CACjB,KAAC,kBAAkB,IACjB,MAAM,EAAE,WAAW,CAAC,MAAM,EAC1B,KAAK,EAAE,IAAI,CAAC,SAAS,EACrB,QAAQ,EAAE,IAAI,CAAC,YAAY,KACvB,YAAY,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,YAAY,EAAE,CAAC,EACxD,QAAQ,EAAE,WAAW,CAAC,cAAc,EACpC,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,SAAS,EAAE,sBAAsB,EACjC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,gBAAgB,KAC9B,YAAY,CAAC,EAAE,qBAAqB,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,GAC3E,CACH;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,yBAAyB,EAAE,CAAC;IAE7D,OAAO,CACL,mBACE,SAAS,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,EAChD,KAAK,EAAE,KAAK,mBACG,IAAI,CAAC,QAAQ,EAC5B,GAAG,EAAE,OAAO,aAEZ,8CAAkC,MAAM,YAAE,gBAAgB,GAAS,EAClE,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EACpD,eAAK,SAAS,EAAC,sBAAsB,aACnC,KAAC,WAAW,IACV,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EACpC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAC1C,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,EAC5C,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB,KAC3C,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAC3F,EACF,eAAK,SAAS,EAAC,0BAA0B,EAAC,GAAG,EAAE,WAAW,aACxD,KAAC,sBAAsB,IAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAI,EAC5F,KAAC,sBAAsB,IACrB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,WAAW,CAAC,cAAc,EAC1C,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,EAC1C,eAAe,EAAE,IAAI,CAAC,eAAe,EACrC,aAAa,EAAE,QAAQ,CAAC,aAAa,EACrC,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,EACjD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EACrD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EACrD,qBAAqB,EAAE,SAAS,CAAC,qBAAqB,EACtD,CAAC,EAAE,CAAC,GACJ,EACF,KAAC,oBAAoB,IACnB,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,EACZ,gBAAgB,EAAE,gBAAgB,EAClC,sBAAsB,EAAE,sBAAsB,EAC9C,CAAC,EAAE,CAAC,GACJ,IACE,IACF,EACL,MAAM,IACC,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ChatPaneProps } from './types.js';
|
|
2
|
+
export interface CreateDaemonAttachmentUploaderOptions {
|
|
3
|
+
/** Per-file cap checked before any request is sent. Defaults to 20 MB, matching the route pack. */
|
|
4
|
+
readonly maxAttachmentBytes?: number;
|
|
5
|
+
/** Files per composer turn. Defaults to 10, matching the route pack. */
|
|
6
|
+
readonly maxAttachmentCount?: number;
|
|
7
|
+
/** Total bytes per composer turn. Defaults to 50 MB, matching the route pack. */
|
|
8
|
+
readonly maxBatchBytes?: number;
|
|
9
|
+
/** Abort deadline for one call, covering every file in it. Defaults to 30s. */
|
|
10
|
+
readonly timeoutMs?: number;
|
|
11
|
+
/** In-flight uploads. Defaults to 2 — enough to hide latency, few enough to stay ordered and cheap. */
|
|
12
|
+
readonly concurrency?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds a `ChatPaneProps['uploadAttachments']` bound to one daemon.
|
|
16
|
+
*
|
|
17
|
+
* @param baseUrl Origin (or same-origin path prefix) the daemon's API is reachable at. Pass `''`
|
|
18
|
+
* when the page is served through a proxy that already forwards `/api`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createDaemonAttachmentUploader(baseUrl: string, options?: CreateDaemonAttachmentUploaderOptions): NonNullable<ChatPaneProps['uploadAttachments']>;
|
|
21
|
+
//# sourceMappingURL=create-daemon-attachment-uploader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-daemon-attachment-uploader.d.ts","sourceRoot":"","sources":["../../../../src/react/features/chat-pane/create-daemon-attachment-uploader.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAmC,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjF,MAAM,WAAW,qCAAqC;IACpD,mGAAmG;IACnG,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,wEAAwE;IACxE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,uGAAuG;IACvG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAiED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,qCAA0C,GAClD,WAAW,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CA0IjD"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module create-daemon-attachment-uploader
|
|
3
|
+
*
|
|
4
|
+
* The client half of `@jini-ai/http-kit`'s attachment capability: a ready-made
|
|
5
|
+
* `ChatPaneProps['uploadAttachments']` that talks to `POST`/`DELETE /api/attachments`.
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <ChatPane transport={transport} uploadAttachments={createDaemonAttachmentUploader(daemonUrl)} />
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* That one line is the whole wire-up for composer drag-and-drop and the file picker — `ChatPane`
|
|
12
|
+
* gates both on `uploadAttachments` being present (see `ChatPane.tsx`'s `resolveDropTargetProps`).
|
|
13
|
+
*
|
|
14
|
+
* **Why the client enforces quotas at all**, when the daemon enforces them anyway: a user who drags
|
|
15
|
+
* in a 400 MB video should be told immediately, not after the browser has finished streaming it to
|
|
16
|
+
* localhost. These checks are a courtesy, never the security boundary — the daemon re-derives every
|
|
17
|
+
* one of them, and only its answer decides anything.
|
|
18
|
+
*
|
|
19
|
+
* **Bounded concurrency, preserved order.** Two workers pull from a shared index, so at most two
|
|
20
|
+
* requests are in flight while results still land at their input positions. The first failure aborts
|
|
21
|
+
* the rest and deletes whatever already landed, so a partly-uploaded turn never leaves files behind
|
|
22
|
+
* on the daemon waiting for their TTL.
|
|
23
|
+
*
|
|
24
|
+
* **`content-type` is always `application/octet-stream`**, deliberately not `file.type`. The daemon
|
|
25
|
+
* sniffs the real kind from the leading bytes and ignores this header entirely, so forwarding the
|
|
26
|
+
* browser's guess buys nothing — and actively breaks things: a dropped `.json` file gets
|
|
27
|
+
* `content-type: application/json` from the browser, which an app-wide `express.json()` on the
|
|
28
|
+
* daemon then claims, draining the request stream before the upload route can read a byte. A fixed
|
|
29
|
+
* octet-stream type is immune to every body parser.
|
|
30
|
+
*/
|
|
31
|
+
import { FETCH_TIMEOUT_MS, fetchWithTimeout } from '@jini-ai/platform/fetch-with-timeout';
|
|
32
|
+
const DEFAULTS = {
|
|
33
|
+
maxAttachmentBytes: 20 * 1024 * 1024,
|
|
34
|
+
maxAttachmentCount: 10,
|
|
35
|
+
maxBatchBytes: 50 * 1024 * 1024,
|
|
36
|
+
timeoutMs: 30_000,
|
|
37
|
+
concurrency: 2,
|
|
38
|
+
};
|
|
39
|
+
const BATCH_USAGE_TTL_MS = 60 * 60 * 1_000;
|
|
40
|
+
const MAX_TRACKED_BATCHES = 100;
|
|
41
|
+
/** Renders a byte cap the way a person reads it, so the message a user sees says "20 MB". */
|
|
42
|
+
function formatByteLimit(bytes) {
|
|
43
|
+
const megabytes = bytes / (1024 * 1024);
|
|
44
|
+
return Number.isInteger(megabytes) ? `${megabytes} MB` : `${bytes} bytes`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Per-uploader running totals, so a user who drops three files and then two more is held to the
|
|
48
|
+
* same per-turn quota as one who drops five at once. Bounded in both age and size: a composer that
|
|
49
|
+
* is open for days must not accumulate one entry per turn forever.
|
|
50
|
+
*/
|
|
51
|
+
function pruneBatchUsage(batchUsage, now) {
|
|
52
|
+
for (const [batchId, usage] of batchUsage) {
|
|
53
|
+
if (now - usage.touchedAt >= BATCH_USAGE_TTL_MS)
|
|
54
|
+
batchUsage.delete(batchId);
|
|
55
|
+
}
|
|
56
|
+
if (batchUsage.size >= MAX_TRACKED_BATCHES) {
|
|
57
|
+
// Evicts oldest-first (a Map iterates in insertion order) until there is room for one more. A
|
|
58
|
+
// Map at or above the cap is necessarily non-empty, so slicing its keys is total — expressed
|
|
59
|
+
// this way rather than as a `keys().next().value` loop, whose `undefined` case could not happen
|
|
60
|
+
// and so could never be tested.
|
|
61
|
+
const excess = [...batchUsage.keys()].slice(0, batchUsage.size - MAX_TRACKED_BATCHES + 1);
|
|
62
|
+
for (const batchId of excess)
|
|
63
|
+
batchUsage.delete(batchId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Pulls the most useful message out of whichever error envelope the daemon used. */
|
|
67
|
+
async function messageForFailedUpload(response, fallback) {
|
|
68
|
+
try {
|
|
69
|
+
const body = (await response.json());
|
|
70
|
+
return body.error?.message ?? body.message ?? fallback;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// A non-JSON body (an HTML error page from a proxy, an empty 502) tells the user nothing useful.
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Builds a `ChatPaneProps['uploadAttachments']` bound to one daemon.
|
|
79
|
+
*
|
|
80
|
+
* @param baseUrl Origin (or same-origin path prefix) the daemon's API is reachable at. Pass `''`
|
|
81
|
+
* when the page is served through a proxy that already forwards `/api`.
|
|
82
|
+
*/
|
|
83
|
+
export function createDaemonAttachmentUploader(baseUrl, options = {}) {
|
|
84
|
+
const maxAttachmentBytes = options.maxAttachmentBytes ?? DEFAULTS.maxAttachmentBytes;
|
|
85
|
+
const maxAttachmentCount = options.maxAttachmentCount ?? DEFAULTS.maxAttachmentCount;
|
|
86
|
+
const maxBatchBytes = options.maxBatchBytes ?? DEFAULTS.maxBatchBytes;
|
|
87
|
+
const timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;
|
|
88
|
+
const concurrency = options.concurrency ?? DEFAULTS.concurrency;
|
|
89
|
+
const endpoint = `${baseUrl.replace(/\/$/u, '')}/api/attachments`;
|
|
90
|
+
// Per-uploader, not module-level: two panes pointed at two daemons must not share a quota.
|
|
91
|
+
const batchUsage = new Map();
|
|
92
|
+
async function uploadOne(file, batchId, signal) {
|
|
93
|
+
const query = new URLSearchParams({ batch: batchId, name: file.name });
|
|
94
|
+
const response = await fetch(`${endpoint}?${query}`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
// Fixed, not `file.type` — see this module's doc.
|
|
97
|
+
headers: { 'content-type': 'application/octet-stream' },
|
|
98
|
+
body: file,
|
|
99
|
+
signal,
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
throw new Error(await messageForFailedUpload(response, `Could not attach ${file.name}`));
|
|
103
|
+
}
|
|
104
|
+
const body = (await response.json());
|
|
105
|
+
if (!body.attachment) {
|
|
106
|
+
throw new Error(`The daemon did not return an attachment for ${file.name}`);
|
|
107
|
+
}
|
|
108
|
+
return body.attachment;
|
|
109
|
+
}
|
|
110
|
+
async function deletePartialUpload(batchId, attachments) {
|
|
111
|
+
if (attachments.length === 0)
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
// QUICK, not `uploadOne`'s own composed timeout: unlike the upload itself, this has no
|
|
115
|
+
// caller-supplied signal to compose with and no large body — it is a small best-effort JSON
|
|
116
|
+
// DELETE, and an unprotected `fetch` here would hang `uploadAttachments`'s rejection (the
|
|
117
|
+
// `await` below) on a stalled daemon instead of surfacing `firstError` promptly.
|
|
118
|
+
await fetchWithTimeout(endpoint, {
|
|
119
|
+
method: 'DELETE',
|
|
120
|
+
headers: { 'content-type': 'application/json' },
|
|
121
|
+
body: JSON.stringify({ batchId, paths: attachments.map((attachment) => attachment.path) }),
|
|
122
|
+
}, { timeoutMs: FETCH_TIMEOUT_MS.QUICK });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Best effort by design: the daemon expires unclaimed uploads on its own, so a failed cleanup
|
|
126
|
+
// costs disk until the TTL rather than leaking indefinitely. Never worth failing the turn for.
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return async function uploadAttachments(files, uploadOptions) {
|
|
130
|
+
if (files.length === 0)
|
|
131
|
+
return [];
|
|
132
|
+
const now = Date.now();
|
|
133
|
+
pruneBatchUsage(batchUsage, now);
|
|
134
|
+
const batchId = uploadOptions?.batchId ?? crypto.randomUUID();
|
|
135
|
+
const incomingBytes = files.reduce((total, file) => total + file.size, 0);
|
|
136
|
+
const current = batchUsage.get(batchId) ?? { count: 0, bytes: 0, touchedAt: now };
|
|
137
|
+
if (files.some((file) => file.size > maxAttachmentBytes)) {
|
|
138
|
+
throw new Error(`Each attachment must be ${formatByteLimit(maxAttachmentBytes)} or smaller.`);
|
|
139
|
+
}
|
|
140
|
+
if (current.count + files.length > maxAttachmentCount) {
|
|
141
|
+
throw new Error(`You can attach at most ${maxAttachmentCount} files to one message.`);
|
|
142
|
+
}
|
|
143
|
+
if (current.bytes + incomingBytes > maxBatchBytes) {
|
|
144
|
+
throw new Error(`Attachments for one message must total ${formatByteLimit(maxBatchBytes)} or less.`);
|
|
145
|
+
}
|
|
146
|
+
// Reserved up front and rolled back on failure, so two overlapping calls for the same turn
|
|
147
|
+
// cannot each see the same free headroom.
|
|
148
|
+
batchUsage.set(batchId, {
|
|
149
|
+
count: current.count + files.length,
|
|
150
|
+
bytes: current.bytes + incomingBytes,
|
|
151
|
+
touchedAt: now,
|
|
152
|
+
});
|
|
153
|
+
const controller = new AbortController();
|
|
154
|
+
const abortFromParent = () => controller.abort(uploadOptions?.signal.reason);
|
|
155
|
+
uploadOptions?.signal.addEventListener('abort', abortFromParent, { once: true });
|
|
156
|
+
if (uploadOptions?.signal.aborted)
|
|
157
|
+
abortFromParent();
|
|
158
|
+
const timeout = globalThis.setTimeout(() => controller.abort(new DOMException('Attachment upload timed out', 'TimeoutError')), timeoutMs);
|
|
159
|
+
const uploaded = new Array(files.length);
|
|
160
|
+
let nextIndex = 0;
|
|
161
|
+
let firstError;
|
|
162
|
+
const worker = async () => {
|
|
163
|
+
while (!controller.signal.aborted) {
|
|
164
|
+
const index = nextIndex;
|
|
165
|
+
nextIndex += 1;
|
|
166
|
+
const file = files[index];
|
|
167
|
+
if (file === undefined)
|
|
168
|
+
return;
|
|
169
|
+
try {
|
|
170
|
+
uploaded[index] = await uploadOne(file, batchId, controller.signal);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
// Kept, not thrown: aborting stops the sibling worker, and the *first* failure is the one
|
|
174
|
+
// worth reporting — the aborts it causes are noise.
|
|
175
|
+
firstError ??= error;
|
|
176
|
+
controller.abort();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const settled = () => uploaded.filter((attachment) => attachment !== undefined);
|
|
181
|
+
// The failure is captured rather than rethrown from inside the `try`, so that the timer/listener
|
|
182
|
+
// teardown in `finally` has exactly two reachable paths (the turn succeeded, or it did not)
|
|
183
|
+
// instead of a third that a rethrowing `catch` would create and nothing could ever exercise.
|
|
184
|
+
let failure;
|
|
185
|
+
let succeeded = false;
|
|
186
|
+
try {
|
|
187
|
+
await Promise.all(Array.from({ length: concurrency }, worker));
|
|
188
|
+
if (firstError !== undefined)
|
|
189
|
+
throw firstError;
|
|
190
|
+
if (controller.signal.aborted) {
|
|
191
|
+
throw controller.signal.reason instanceof Error
|
|
192
|
+
? controller.signal.reason
|
|
193
|
+
: new Error('Attachment upload was canceled.');
|
|
194
|
+
}
|
|
195
|
+
succeeded = true;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
failure = error;
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
globalThis.clearTimeout(timeout);
|
|
202
|
+
uploadOptions?.signal.removeEventListener('abort', abortFromParent);
|
|
203
|
+
}
|
|
204
|
+
if (succeeded)
|
|
205
|
+
return settled();
|
|
206
|
+
// Roll the reservation back only after the daemon-side files are gone, so a retry of this turn
|
|
207
|
+
// starts from a clean slate on both sides.
|
|
208
|
+
await deletePartialUpload(batchId, settled());
|
|
209
|
+
batchUsage.set(batchId, current);
|
|
210
|
+
throw failure;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=create-daemon-attachment-uploader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-daemon-attachment-uploader.js","sourceRoot":"","sources":["../../../../src/react/features/chat-pane/create-daemon-attachment-uploader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module create-mcp-ui-tool-caller
|
|
3
|
+
*
|
|
4
|
+
* The client half of the MCP-UI two-step confirmation pattern: a ready-made
|
|
5
|
+
* {@link McpUiToolCallHandler} that relays a View's `tools/call` to an HTTP endpoint.
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* registerMcpUiSurfaceRenderer({ onToolCall: createMcpUiToolCaller('') });
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* That one line completes the loop. `@jini-ai/daemon`'s `delegated-tool-bridge.ts` splits a UI
|
|
12
|
+
* resource out of a tool result and emits it as an `mcp-ui` run event; `McpUiSurfaceCard` renders it
|
|
13
|
+
* in a sandboxed iframe; and when the human clicks, the View posts a `tools/call` that arrives here
|
|
14
|
+
* and is forwarded to the host's own endpoint. Sibling of `create-daemon-attachment-uploader.ts`,
|
|
15
|
+
* and deliberately the same shape: a host supplies a base URL, not a transport.
|
|
16
|
+
*
|
|
17
|
+
* ## Why this is a separate round trip rather than reusing the run's tool channel
|
|
18
|
+
*
|
|
19
|
+
* `McpUiToolCallHandler` receives only the call — no `runId`. That is not an oversight to work
|
|
20
|
+
* around: the second step of a confirmation is genuinely **not** part of the agent's run. The run
|
|
21
|
+
* that raised the dialog may have finished, the page may have been reloaded, and the human may click
|
|
22
|
+
* minutes later. Binding redemption to a live run would make a confirmation expire for reasons that
|
|
23
|
+
* have nothing to do with the decision being confirmed.
|
|
24
|
+
*
|
|
25
|
+
* So the endpoint this calls is a host-authenticated one (a browser session, typically), not the
|
|
26
|
+
* daemon's run-scoped `/api/delegated-tool-calls`. **The human's own credentials are what authorize
|
|
27
|
+
* the second step** — which is the entire point of the pattern. The agent never had them.
|
|
28
|
+
*
|
|
29
|
+
* ## What this deliberately does NOT do
|
|
30
|
+
*
|
|
31
|
+
* It performs no validation of `toolName` or `params` and holds no allow-list. A View's HTML is
|
|
32
|
+
* untrusted — it came over a wire from a tool author — so any check here is a check the attacker
|
|
33
|
+
* writes both sides of. The server endpoint is the security boundary: it re-authenticates, and the
|
|
34
|
+
* single-use token minted into the dialog is what proves a human saw it. Adding a client-side
|
|
35
|
+
* allow-list would suggest a protection that is not real.
|
|
36
|
+
*/
|
|
37
|
+
import type { McpUiToolCallHandler } from '@jini-ai/ui/mcp-ui';
|
|
38
|
+
export interface CreateMcpUiToolCallerOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Path appended to `baseUrl`. Defaults to `/api/mcp-ui/tool-calls`.
|
|
41
|
+
*
|
|
42
|
+
* Hosts mounting the redemption route inside an already-authenticated admin API will need this —
|
|
43
|
+
* e.g. `/api/admin/v1/mcp-ui/tool-calls`.
|
|
44
|
+
*/
|
|
45
|
+
readonly path?: string;
|
|
46
|
+
/** Abandon a call after this many ms. Defaults to 30s — a human already clicked; this only bounds a hung server. */
|
|
47
|
+
readonly timeoutMs?: number;
|
|
48
|
+
/** Extra headers per request (e.g. a CSRF token). `content-type` is always set and cannot be overridden. */
|
|
49
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
50
|
+
}
|
|
51
|
+
/** Body posted for one confirmed action. Kept flat so a server can validate it without a schema library. */
|
|
52
|
+
export interface McpUiToolCallRequest {
|
|
53
|
+
readonly toolName: string;
|
|
54
|
+
readonly params: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builds an {@link McpUiToolCallHandler} that POSTs `{toolName, params}` and returns the parsed
|
|
58
|
+
* response.
|
|
59
|
+
*
|
|
60
|
+
* A non-2xx response throws with the server's own message where one is available. That matters:
|
|
61
|
+
* `useMcpUiHost` relays a rejection to the View as a JSON-RPC error, so the dialog can print the
|
|
62
|
+
* real reason ("this confirmation has expired") instead of hanging on "Working…". Swallowing the
|
|
63
|
+
* error here would strand the human at a spinner with no way to tell a denial from a dead server.
|
|
64
|
+
*
|
|
65
|
+
* @param baseUrl - Origin to call. `''` for same-origin, which is the common case for an admin UI
|
|
66
|
+
* proxied to its own API.
|
|
67
|
+
* @complexity O(1) — one request per call.
|
|
68
|
+
*/
|
|
69
|
+
export declare function createMcpUiToolCaller(baseUrl: string, options?: CreateMcpUiToolCallerOptions): McpUiToolCallHandler;
|
|
70
|
+
//# sourceMappingURL=create-mcp-ui-tool-caller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-mcp-ui-tool-caller.d.ts","sourceRoot":"","sources":["../../../../src/react/features/chat-pane/create-mcp-ui-tool-caller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,KAAK,EAAiB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oHAAoH;IACpH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4GAA4G;IAC5G,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAKD,4GAA4G;AAC5G,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CA+CtB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const DEFAULT_PATH = '/api/mcp-ui/tool-calls';
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
3
|
+
function errorTextFrom(body, status) {
|
|
4
|
+
if (typeof body === 'string' && body.length > 0)
|
|
5
|
+
return body;
|
|
6
|
+
if (typeof body === 'object' && body !== null) {
|
|
7
|
+
const record = body;
|
|
8
|
+
const message = record['error'] ?? record['message'];
|
|
9
|
+
if (typeof message === 'string' && message.length > 0)
|
|
10
|
+
return message;
|
|
11
|
+
}
|
|
12
|
+
return `Request failed with status ${status}.`;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds an {@link McpUiToolCallHandler} that POSTs `{toolName, params}` and returns the parsed
|
|
16
|
+
* response.
|
|
17
|
+
*
|
|
18
|
+
* A non-2xx response throws with the server's own message where one is available. That matters:
|
|
19
|
+
* `useMcpUiHost` relays a rejection to the View as a JSON-RPC error, so the dialog can print the
|
|
20
|
+
* real reason ("this confirmation has expired") instead of hanging on "Working…". Swallowing the
|
|
21
|
+
* error here would strand the human at a spinner with no way to tell a denial from a dead server.
|
|
22
|
+
*
|
|
23
|
+
* @param baseUrl - Origin to call. `''` for same-origin, which is the common case for an admin UI
|
|
24
|
+
* proxied to its own API.
|
|
25
|
+
* @complexity O(1) — one request per call.
|
|
26
|
+
*/
|
|
27
|
+
export function createMcpUiToolCaller(baseUrl, options = {}) {
|
|
28
|
+
const path = options.path ?? DEFAULT_PATH;
|
|
29
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
30
|
+
const endpoint = `${baseUrl.replace(/\/$/u, '')}${path}`;
|
|
31
|
+
return async (call) => {
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
34
|
+
try {
|
|
35
|
+
// `{name, arguments}` on the MCP-UI side becomes `{toolName, params}` on the wire: `arguments`
|
|
36
|
+
// is a reserved word in a JS function scope and reads badly in a server handler, and the
|
|
37
|
+
// renamed pair matches what the reference implementation's redemption route already accepts.
|
|
38
|
+
const request = {
|
|
39
|
+
toolName: call.name,
|
|
40
|
+
params: { ...call.arguments },
|
|
41
|
+
};
|
|
42
|
+
const response = await fetch(endpoint, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
// Same-origin cookie session is the usual authenticator for the human's second step.
|
|
45
|
+
credentials: 'same-origin',
|
|
46
|
+
headers: { ...options.headers, 'content-type': 'application/json' },
|
|
47
|
+
body: JSON.stringify(request),
|
|
48
|
+
signal: controller.signal,
|
|
49
|
+
});
|
|
50
|
+
const raw = await response.text();
|
|
51
|
+
let parsed = raw;
|
|
52
|
+
if (raw.length > 0) {
|
|
53
|
+
try {
|
|
54
|
+
parsed = JSON.parse(raw);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Left as text — a proxy's HTML error page is more useful surfaced verbatim than swapped
|
|
58
|
+
// for a generic "invalid JSON", which would hide what actually answered.
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!response.ok)
|
|
62
|
+
throw new Error(errorTextFrom(parsed, response.status));
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
67
|
+
throw new Error(`Timed out after ${timeoutMs}ms waiting for the server.`);
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=create-mcp-ui-tool-caller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-mcp-ui-tool-caller.js","sourceRoot":"","sources":["../../../../src/react/features/chat-pane/create-mcp-ui-tool-caller.ts"],"names":[],"mappings":"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"}
|