@data-club/ai-hub 0.0.1
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/dist/auth/passwordPolicy.d.ts +55 -0
- package/dist/auth/passwordPolicy.d.ts.map +1 -0
- package/dist/auth/passwordPolicy.js +63 -0
- package/dist/auth/passwordPolicy.js.map +1 -0
- package/dist/auth/texts.d.ts +815 -0
- package/dist/auth/texts.d.ts.map +1 -0
- package/dist/auth/texts.js +429 -0
- package/dist/auth/texts.js.map +1 -0
- package/dist/client/AIHubClient.d.ts +1058 -0
- package/dist/client/AIHubClient.d.ts.map +1 -0
- package/dist/client/AIHubClient.js +950 -0
- package/dist/client/AIHubClient.js.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/sseParser.d.ts +41 -0
- package/dist/client/sseParser.d.ts.map +1 -0
- package/dist/client/sseParser.js +153 -0
- package/dist/client/sseParser.js.map +1 -0
- package/dist/client/tokenStorage.d.ts +56 -0
- package/dist/client/tokenStorage.d.ts.map +1 -0
- package/dist/client/tokenStorage.js +116 -0
- package/dist/client/tokenStorage.js.map +1 -0
- package/dist/components/AgentsPicker/index.d.ts +70 -0
- package/dist/components/AgentsPicker/index.d.ts.map +1 -0
- package/dist/components/AgentsPicker/index.js +63 -0
- package/dist/components/AgentsPicker/index.js.map +1 -0
- package/dist/components/AuthGate/index.d.ts +79 -0
- package/dist/components/AuthGate/index.d.ts.map +1 -0
- package/dist/components/AuthGate/index.js +61 -0
- package/dist/components/AuthGate/index.js.map +1 -0
- package/dist/components/CacheBadge/index.d.ts +88 -0
- package/dist/components/CacheBadge/index.d.ts.map +1 -0
- package/dist/components/CacheBadge/index.js +127 -0
- package/dist/components/CacheBadge/index.js.map +1 -0
- package/dist/components/ChangePassword/index.d.ts +109 -0
- package/dist/components/ChangePassword/index.d.ts.map +1 -0
- package/dist/components/ChangePassword/index.js +142 -0
- package/dist/components/ChangePassword/index.js.map +1 -0
- package/dist/components/ChatShell/ShellHeader.d.ts +44 -0
- package/dist/components/ChatShell/ShellHeader.d.ts.map +1 -0
- package/dist/components/ChatShell/ShellHeader.js +14 -0
- package/dist/components/ChatShell/ShellHeader.js.map +1 -0
- package/dist/components/ChatShell/UserMenu.d.ts +48 -0
- package/dist/components/ChatShell/UserMenu.d.ts.map +1 -0
- package/dist/components/ChatShell/UserMenu.js +86 -0
- package/dist/components/ChatShell/UserMenu.js.map +1 -0
- package/dist/components/ChatShell/index.d.ts +98 -0
- package/dist/components/ChatShell/index.d.ts.map +1 -0
- package/dist/components/ChatShell/index.js +124 -0
- package/dist/components/ChatShell/index.js.map +1 -0
- package/dist/components/DataClubAIHub/index.d.ts +132 -0
- package/dist/components/DataClubAIHub/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHub/index.js +124 -0
- package/dist/components/DataClubAIHub/index.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts +89 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js +199 -0
- package/dist/components/DataClubAIHubAdmin/AgentEditorModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts +33 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.js +137 -0
- package/dist/components/DataClubAIHubAdmin/AgentsPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts +50 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.js +93 -0
- package/dist/components/DataClubAIHubAdmin/CreateUserModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts +49 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js +94 -0
- package/dist/components/DataClubAIHubAdmin/PasswordRevealModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts +37 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js +44 -0
- package/dist/components/DataClubAIHubAdmin/ResetPasswordModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts +56 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js +158 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessageEditorModal.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts +29 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js +183 -0
- package/dist/components/DataClubAIHubAdmin/RotatingMessagesPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts +38 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js +294 -0
- package/dist/components/DataClubAIHubAdmin/SessionsOverviewPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts +36 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js +373 -0
- package/dist/components/DataClubAIHubAdmin/SettingsPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts +47 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.js +233 -0
- package/dist/components/DataClubAIHubAdmin/UsersPage.js.map +1 -0
- package/dist/components/DataClubAIHubAdmin/index.d.ts +87 -0
- package/dist/components/DataClubAIHubAdmin/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHubAdmin/index.js +137 -0
- package/dist/components/DataClubAIHubAdmin/index.js.map +1 -0
- package/dist/components/DataClubAIHubLogin/index.d.ts +113 -0
- package/dist/components/DataClubAIHubLogin/index.d.ts.map +1 -0
- package/dist/components/DataClubAIHubLogin/index.js +123 -0
- package/dist/components/DataClubAIHubLogin/index.js.map +1 -0
- package/dist/components/EffortControl/index.d.ts +57 -0
- package/dist/components/EffortControl/index.d.ts.map +1 -0
- package/dist/components/EffortControl/index.js +84 -0
- package/dist/components/EffortControl/index.js.map +1 -0
- package/dist/components/Layout/index.d.ts +63 -0
- package/dist/components/Layout/index.d.ts.map +1 -0
- package/dist/components/Layout/index.js +45 -0
- package/dist/components/Layout/index.js.map +1 -0
- package/dist/components/MainColumn/index.d.ts +69 -0
- package/dist/components/MainColumn/index.d.ts.map +1 -0
- package/dist/components/MainColumn/index.js +47 -0
- package/dist/components/MainColumn/index.js.map +1 -0
- package/dist/components/MarkdownRenderer/index.d.ts +66 -0
- package/dist/components/MarkdownRenderer/index.d.ts.map +1 -0
- package/dist/components/MarkdownRenderer/index.js +153 -0
- package/dist/components/MarkdownRenderer/index.js.map +1 -0
- package/dist/components/MessageInput/index.d.ts +85 -0
- package/dist/components/MessageInput/index.d.ts.map +1 -0
- package/dist/components/MessageInput/index.js +139 -0
- package/dist/components/MessageInput/index.js.map +1 -0
- package/dist/components/MessageList/index.d.ts +156 -0
- package/dist/components/MessageList/index.d.ts.map +1 -0
- package/dist/components/MessageList/index.js +352 -0
- package/dist/components/MessageList/index.js.map +1 -0
- package/dist/components/ReasoningSelector/index.d.ts +77 -0
- package/dist/components/ReasoningSelector/index.d.ts.map +1 -0
- package/dist/components/ReasoningSelector/index.js +156 -0
- package/dist/components/ReasoningSelector/index.js.map +1 -0
- package/dist/components/ReasoningView/index.d.ts +94 -0
- package/dist/components/ReasoningView/index.d.ts.map +1 -0
- package/dist/components/ReasoningView/index.js +83 -0
- package/dist/components/ReasoningView/index.js.map +1 -0
- package/dist/components/ScrollToPresentButton/index.d.ts +54 -0
- package/dist/components/ScrollToPresentButton/index.d.ts.map +1 -0
- package/dist/components/ScrollToPresentButton/index.js +44 -0
- package/dist/components/ScrollToPresentButton/index.js.map +1 -0
- package/dist/components/SessionsPanel/SessionTitleModal.d.ts +79 -0
- package/dist/components/SessionsPanel/SessionTitleModal.d.ts.map +1 -0
- package/dist/components/SessionsPanel/SessionTitleModal.js +102 -0
- package/dist/components/SessionsPanel/SessionTitleModal.js.map +1 -0
- package/dist/components/SessionsPanel/index.d.ts +100 -0
- package/dist/components/SessionsPanel/index.d.ts.map +1 -0
- package/dist/components/SessionsPanel/index.js +176 -0
- package/dist/components/SessionsPanel/index.js.map +1 -0
- package/dist/components/SystemNotice/index.d.ts +66 -0
- package/dist/components/SystemNotice/index.d.ts.map +1 -0
- package/dist/components/SystemNotice/index.js +81 -0
- package/dist/components/SystemNotice/index.js.map +1 -0
- package/dist/components/ThemeSwitcher/index.d.ts +66 -0
- package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
- package/dist/components/ThemeSwitcher/index.js +73 -0
- package/dist/components/ThemeSwitcher/index.js.map +1 -0
- package/dist/components/ToolCallView/formatContent.d.ts +36 -0
- package/dist/components/ToolCallView/formatContent.d.ts.map +1 -0
- package/dist/components/ToolCallView/formatContent.js +53 -0
- package/dist/components/ToolCallView/formatContent.js.map +1 -0
- package/dist/components/ToolCallView/index.d.ts +120 -0
- package/dist/components/ToolCallView/index.d.ts.map +1 -0
- package/dist/components/ToolCallView/index.js +104 -0
- package/dist/components/ToolCallView/index.js.map +1 -0
- package/dist/components/TpmBanner/index.d.ts +53 -0
- package/dist/components/TpmBanner/index.d.ts.map +1 -0
- package/dist/components/TpmBanner/index.js +116 -0
- package/dist/components/TpmBanner/index.js.map +1 -0
- package/dist/components/TurnStatusIndicator/index.d.ts +77 -0
- package/dist/components/TurnStatusIndicator/index.d.ts.map +1 -0
- package/dist/components/TurnStatusIndicator/index.js +122 -0
- package/dist/components/TurnStatusIndicator/index.js.map +1 -0
- package/dist/components/internal/PasswordInput.d.ts +62 -0
- package/dist/components/internal/PasswordInput.d.ts.map +1 -0
- package/dist/components/internal/PasswordInput.js +42 -0
- package/dist/components/internal/PasswordInput.js.map +1 -0
- package/dist/context/AIHubContext.d.ts +220 -0
- package/dist/context/AIHubContext.d.ts.map +1 -0
- package/dist/context/AIHubContext.js +19 -0
- package/dist/context/AIHubContext.js.map +1 -0
- package/dist/context/AIHubProvider.d.ts +75 -0
- package/dist/context/AIHubProvider.d.ts.map +1 -0
- package/dist/context/AIHubProvider.js +954 -0
- package/dist/context/AIHubProvider.js.map +1 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +9 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/theme.d.ts +43 -0
- package/dist/context/theme.d.ts.map +1 -0
- package/dist/context/theme.js +70 -0
- package/dist/context/theme.js.map +1 -0
- package/dist/context/useAIHub.d.ts +104 -0
- package/dist/context/useAIHub.d.ts.map +1 -0
- package/dist/context/useAIHub.js +63 -0
- package/dist/context/useAIHub.js.map +1 -0
- package/dist/context/useAIHubAuth.d.ts +44 -0
- package/dist/context/useAIHubAuth.d.ts.map +1 -0
- package/dist/context/useAIHubAuth.js +35 -0
- package/dist/context/useAIHubAuth.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/primitives/index.d.ts +99 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +97 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/state/affordances.d.ts +182 -0
- package/dist/state/affordances.d.ts.map +1 -0
- package/dist/state/affordances.js +189 -0
- package/dist/state/affordances.js.map +1 -0
- package/dist/state/stateReducer.d.ts +72 -0
- package/dist/state/stateReducer.d.ts.map +1 -0
- package/dist/state/stateReducer.js +122 -0
- package/dist/state/stateReducer.js.map +1 -0
- package/dist/stories/EffortControl.stories.d.ts +14 -0
- package/dist/stories/EffortControl.stories.d.ts.map +1 -0
- package/dist/stories/EffortControl.stories.js +43 -0
- package/dist/stories/EffortControl.stories.js.map +1 -0
- package/dist/stories/MarkdownRenderer.stories.d.ts +25 -0
- package/dist/stories/MarkdownRenderer.stories.d.ts.map +1 -0
- package/dist/stories/MarkdownRenderer.stories.js +178 -0
- package/dist/stories/MarkdownRenderer.stories.js.map +1 -0
- package/dist/stories/MessageBubble.stories.d.ts +21 -0
- package/dist/stories/MessageBubble.stories.d.ts.map +1 -0
- package/dist/stories/MessageBubble.stories.js +59 -0
- package/dist/stories/MessageBubble.stories.js.map +1 -0
- package/dist/stories/ReasoningView.stories.d.ts +18 -0
- package/dist/stories/ReasoningView.stories.d.ts.map +1 -0
- package/dist/stories/ReasoningView.stories.js +62 -0
- package/dist/stories/ReasoningView.stories.js.map +1 -0
- package/dist/stories/ScrollToPresentButton.stories.d.ts +18 -0
- package/dist/stories/ScrollToPresentButton.stories.d.ts.map +1 -0
- package/dist/stories/ScrollToPresentButton.stories.js +34 -0
- package/dist/stories/ScrollToPresentButton.stories.js.map +1 -0
- package/dist/stories/SystemNotice.stories.d.ts +17 -0
- package/dist/stories/SystemNotice.stories.d.ts.map +1 -0
- package/dist/stories/SystemNotice.stories.js +42 -0
- package/dist/stories/SystemNotice.stories.js.map +1 -0
- package/dist/stories/ThemeSwitcher.stories.d.ts +15 -0
- package/dist/stories/ThemeSwitcher.stories.d.ts.map +1 -0
- package/dist/stories/ThemeSwitcher.stories.js +35 -0
- package/dist/stories/ThemeSwitcher.stories.js.map +1 -0
- package/dist/stories/ToolCallView.stories.d.ts +20 -0
- package/dist/stories/ToolCallView.stories.d.ts.map +1 -0
- package/dist/stories/ToolCallView.stories.js +65 -0
- package/dist/stories/ToolCallView.stories.js.map +1 -0
- package/dist/stories/TpmBanner.stories.d.ts +24 -0
- package/dist/stories/TpmBanner.stories.d.ts.map +1 -0
- package/dist/stories/TpmBanner.stories.js +63 -0
- package/dist/stories/TpmBanner.stories.js.map +1 -0
- package/dist/stories/TurnStatusIndicator.stories.d.ts +25 -0
- package/dist/stories/TurnStatusIndicator.stories.d.ts.map +1 -0
- package/dist/stories/TurnStatusIndicator.stories.js +56 -0
- package/dist/stories/TurnStatusIndicator.stories.js.map +1 -0
- package/dist/stories/_mockProvider.d.ts +44 -0
- package/dist/stories/_mockProvider.d.ts.map +1 -0
- package/dist/stories/_mockProvider.js +84 -0
- package/dist/stories/_mockProvider.js.map +1 -0
- package/dist/types.d.ts +787 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/webcomponent/defineWebComponent.d.ts +106 -0
- package/dist/webcomponent/defineWebComponent.d.ts.map +1 -0
- package/dist/webcomponent/defineWebComponent.js +126 -0
- package/dist/webcomponent/defineWebComponent.js.map +1 -0
- package/dist/webcomponent/index.d.ts +7 -0
- package/dist/webcomponent/index.d.ts.map +1 -0
- package/dist/webcomponent/index.js +7 -0
- package/dist/webcomponent/index.js.map +1 -0
- package/package.json +63 -0
- package/src/__lint-canary__/step1-lint-canary.ts.disabled +28 -0
- package/src/auth/passwordPolicy.ts +75 -0
- package/src/auth/texts.ts +1294 -0
- package/src/client/AIHubClient.ts +1718 -0
- package/src/client/index.ts +30 -0
- package/src/client/sseParser.ts +168 -0
- package/src/client/tokenStorage.ts +131 -0
- package/src/components/AgentsPicker/index.tsx +147 -0
- package/src/components/AuthGate/index.tsx +132 -0
- package/src/components/CacheBadge/index.tsx +245 -0
- package/src/components/ChangePassword/index.tsx +375 -0
- package/src/components/ChatShell/ShellHeader.tsx +80 -0
- package/src/components/ChatShell/UserMenu.tsx +196 -0
- package/src/components/ChatShell/index.tsx +307 -0
- package/src/components/DataClubAIHub/index.tsx +300 -0
- package/src/components/DataClubAIHubAdmin/AgentEditorModal.tsx +505 -0
- package/src/components/DataClubAIHubAdmin/AgentsPage.tsx +342 -0
- package/src/components/DataClubAIHubAdmin/CreateUserModal.tsx +214 -0
- package/src/components/DataClubAIHubAdmin/PasswordRevealModal.tsx +204 -0
- package/src/components/DataClubAIHubAdmin/ResetPasswordModal.tsx +122 -0
- package/src/components/DataClubAIHubAdmin/RotatingMessageEditorModal.tsx +408 -0
- package/src/components/DataClubAIHubAdmin/RotatingMessagesPage.tsx +373 -0
- package/src/components/DataClubAIHubAdmin/SessionsOverviewPage.tsx +639 -0
- package/src/components/DataClubAIHubAdmin/SettingsPage.tsx +979 -0
- package/src/components/DataClubAIHubAdmin/UsersPage.tsx +495 -0
- package/src/components/DataClubAIHubAdmin/index.tsx +277 -0
- package/src/components/DataClubAIHubLogin/index.tsx +282 -0
- package/src/components/EffortControl/index.tsx +138 -0
- package/src/components/Layout/index.tsx +92 -0
- package/src/components/MainColumn/index.tsx +131 -0
- package/src/components/MarkdownRenderer/index.tsx +256 -0
- package/src/components/MessageInput/index.tsx +283 -0
- package/src/components/MessageList/index.tsx +753 -0
- package/src/components/ReasoningSelector/index.tsx +268 -0
- package/src/components/ReasoningView/index.tsx +183 -0
- package/src/components/ScrollToPresentButton/index.tsx +85 -0
- package/src/components/SessionsPanel/SessionTitleModal.tsx +256 -0
- package/src/components/SessionsPanel/index.tsx +406 -0
- package/src/components/SystemNotice/index.tsx +151 -0
- package/src/components/ThemeSwitcher/index.tsx +136 -0
- package/src/components/ToolCallView/formatContent.ts +50 -0
- package/src/components/ToolCallView/index.tsx +274 -0
- package/src/components/TpmBanner/index.tsx +172 -0
- package/src/components/TurnStatusIndicator/index.tsx +203 -0
- package/src/components/internal/PasswordInput.tsx +145 -0
- package/src/context/AIHubContext.ts +249 -0
- package/src/context/AIHubProvider.tsx +1084 -0
- package/src/context/index.ts +9 -0
- package/src/context/theme.ts +76 -0
- package/src/context/useAIHub.ts +151 -0
- package/src/context/useAIHubAuth.ts +65 -0
- package/src/index.ts +275 -0
- package/src/primitives/index.ts +101 -0
- package/src/state/affordances.ts +321 -0
- package/src/state/stateReducer.ts +131 -0
- package/src/stories/EffortControl.stories.tsx +63 -0
- package/src/stories/MarkdownRenderer.stories.tsx +201 -0
- package/src/stories/MessageBubble.stories.tsx +101 -0
- package/src/stories/ReasoningView.stories.tsx +81 -0
- package/src/stories/ScrollToPresentButton.stories.tsx +52 -0
- package/src/stories/SystemNotice.stories.tsx +59 -0
- package/src/stories/ThemeSwitcher.stories.tsx +55 -0
- package/src/stories/ToolCallView.stories.tsx +95 -0
- package/src/stories/TpmBanner.stories.tsx +93 -0
- package/src/stories/TurnStatusIndicator.stories.tsx +86 -0
- package/src/stories/_mockProvider.tsx +116 -0
- package/src/styles/CLASSES.md +356 -0
- package/src/styles/default.css +2937 -0
- package/src/types.ts +867 -0
- package/src/webcomponent/defineWebComponent.tsx +193 -0
- package/src/webcomponent/index.ts +11 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<MessageInput />` — auto-growing textarea + send/stop buttons + toolbar
|
|
3
|
+
* (effort dropdown + slot for custom toolbar items).
|
|
4
|
+
*
|
|
5
|
+
* Step 9 shipped the structural input (Enter to send, Shift+Enter for
|
|
6
|
+
* newline, auto-grow, send ↔ stop toggle). Step 10 layers in:
|
|
7
|
+
*
|
|
8
|
+
* - **Phase-aware stop label** — "Stop generation" during model phases,
|
|
9
|
+
* "Cancel tool" during `tool_executing` (§10.4 stop-button row notes
|
|
10
|
+
* the label change; the i18n keys are `stopGenerationButton` /
|
|
11
|
+
* `cancelToolButton`).
|
|
12
|
+
* - **Effort dropdown** — `<EffortControl />` in the toolbar, gated by
|
|
13
|
+
* the resolved `effortControlVisible` flag.
|
|
14
|
+
* - **Custom toolbar items slot** — `customInputToolbarItems` from the
|
|
15
|
+
* monolith (Tier 2) and `toolbar` from primitive composition (Tier 3).
|
|
16
|
+
* Rendered after the effort dropdown.
|
|
17
|
+
*
|
|
18
|
+
* Exported under `AIHub.Input`.
|
|
19
|
+
*
|
|
20
|
+
* @see SPECIFICATIONS.md §7.1 — exports
|
|
21
|
+
* @see SPECIFICATIONS.md §7.4 — reasoning effort
|
|
22
|
+
* @see SPECIFICATIONS.md §10.4 — predicate table
|
|
23
|
+
* @see ui-sketches/03-chat.md — input_area
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
useEffect,
|
|
28
|
+
useRef,
|
|
29
|
+
useState,
|
|
30
|
+
type KeyboardEvent,
|
|
31
|
+
type ReactNode,
|
|
32
|
+
} from "react";
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
resolveAIHubTexts,
|
|
36
|
+
type AIHubTexts,
|
|
37
|
+
type DeepPartial,
|
|
38
|
+
} from "../../auth/texts.js";
|
|
39
|
+
import { useAIHub } from "../../context/useAIHub.js";
|
|
40
|
+
import { chatAffordances } from "../../state/affordances.js";
|
|
41
|
+
|
|
42
|
+
import { EffortControl } from "../EffortControl/index.js";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* BEM class names emitted by `<MessageInput />`.
|
|
46
|
+
*/
|
|
47
|
+
export interface MessageInputClassNames {
|
|
48
|
+
/** Outer wrapper. */
|
|
49
|
+
root: string;
|
|
50
|
+
/** Form element. */
|
|
51
|
+
form: string;
|
|
52
|
+
/** Wrapper around the textarea + buttons. */
|
|
53
|
+
inputRow: string;
|
|
54
|
+
/** The textarea itself. */
|
|
55
|
+
textarea: string;
|
|
56
|
+
/** Toolbar row beneath the textarea (effort + custom items). */
|
|
57
|
+
toolbar: string;
|
|
58
|
+
/** Send button. */
|
|
59
|
+
sendButton: string;
|
|
60
|
+
/** Stop button (replaces send while streaming). */
|
|
61
|
+
stopButton: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const DEFAULT_CLASS_NAMES: MessageInputClassNames = Object.freeze({
|
|
65
|
+
root: "data-club-ai-hub__input-area",
|
|
66
|
+
form: "data-club-ai-hub__input-area__form",
|
|
67
|
+
inputRow: "data-club-ai-hub__input-area__row",
|
|
68
|
+
textarea: "data-club-ai-hub__input-area__textarea",
|
|
69
|
+
toolbar: "data-club-ai-hub__input-area__toolbar",
|
|
70
|
+
sendButton: "data-club-ai-hub__input-area__send",
|
|
71
|
+
stopButton: "data-club-ai-hub__input-area__stop",
|
|
72
|
+
}) as MessageInputClassNames;
|
|
73
|
+
|
|
74
|
+
/** Cap the textarea growth — past this many pixels it scrolls internally. */
|
|
75
|
+
const MAX_TEXTAREA_HEIGHT = 240;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Props for `<MessageInput />`.
|
|
79
|
+
*/
|
|
80
|
+
export interface MessageInputProps {
|
|
81
|
+
/** Show the toolbar row. Defaults to true. */
|
|
82
|
+
showToolbar?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Whether the effort dropdown renders inside the toolbar. Defaults to
|
|
85
|
+
* true. Set false to suppress (overridden upstream by the §8.4
|
|
86
|
+
* `effort_control_visible` toggle).
|
|
87
|
+
*/
|
|
88
|
+
showEffortControl?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Stop-button visibility flag from the §8.4 resolved stack. When
|
|
91
|
+
* false, the stop button is hidden during streaming and the input
|
|
92
|
+
* stays disabled until the server emits the terminal event. Default
|
|
93
|
+
* true.
|
|
94
|
+
*/
|
|
95
|
+
stopButtonEnabled?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Slot rendered after the effort dropdown — used by the monolith's
|
|
98
|
+
* `customInputToolbarItems` slot prop and by Tier-3 wrappers that
|
|
99
|
+
* pass a `toolbar` to `<AIHub.Input />` directly.
|
|
100
|
+
*/
|
|
101
|
+
toolbar?: ReactNode;
|
|
102
|
+
/** Extra class merged onto the root. */
|
|
103
|
+
className?: string;
|
|
104
|
+
/** Per-element class overrides. */
|
|
105
|
+
classNames?: Partial<MessageInputClassNames>;
|
|
106
|
+
/** Wrapper-supplied i18n. */
|
|
107
|
+
texts?: DeepPartial<AIHubTexts>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Renders the input area.
|
|
112
|
+
*
|
|
113
|
+
* @param props - see `MessageInputProps`.
|
|
114
|
+
* @returns the rendered input.
|
|
115
|
+
*/
|
|
116
|
+
export function MessageInput(props: MessageInputProps): ReactNode {
|
|
117
|
+
const {
|
|
118
|
+
sendMessage,
|
|
119
|
+
stop,
|
|
120
|
+
state,
|
|
121
|
+
activeSessionId,
|
|
122
|
+
messagesLoading,
|
|
123
|
+
isStoppingTurn,
|
|
124
|
+
pendingDraft,
|
|
125
|
+
consumePendingDraft,
|
|
126
|
+
} = useAIHub();
|
|
127
|
+
const texts = resolveAIHubTexts(props.texts);
|
|
128
|
+
const cls = { ...DEFAULT_CLASS_NAMES, ...(props.classNames ?? {}) };
|
|
129
|
+
const showToolbar = props.showToolbar ?? true;
|
|
130
|
+
const showEffortControl = props.showEffortControl ?? true;
|
|
131
|
+
const stopButtonEnabled = props.stopButtonEnabled ?? true;
|
|
132
|
+
|
|
133
|
+
const [text, setText] = useState("");
|
|
134
|
+
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
135
|
+
|
|
136
|
+
// Consume `pendingDraft` when it appears, and never twice for the
|
|
137
|
+
// same value. The functional `setText` callback reads React's truly
|
|
138
|
+
// current state at flush time, so this is robust against:
|
|
139
|
+
//
|
|
140
|
+
// 1. Provider re-rendering between the moment pendingDraft is set
|
|
141
|
+
// and the moment this effect runs (`consumePendingDraft` changes
|
|
142
|
+
// identity on every provider render, which forces the effect to
|
|
143
|
+
// re-fire — the functional update tolerates that).
|
|
144
|
+
// 2. A stale `textRef` (the previous implementation relied on a
|
|
145
|
+
// render-time `textRef.current = text` assignment, which was
|
|
146
|
+
// correct in theory but proved fragile in practice — the
|
|
147
|
+
// functional form removes the read-side step entirely).
|
|
148
|
+
//
|
|
149
|
+
// We also always call `consumePendingDraft()` once we've seen a
|
|
150
|
+
// non-null draft, even if the user has typed something — that way
|
|
151
|
+
// the draft doesn't loop back the next time the user clears the
|
|
152
|
+
// input (the contract is "one-shot push from the provider; consume
|
|
153
|
+
// exactly once").
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
if (pendingDraft === null) return;
|
|
156
|
+
setText((current) => (current.length === 0 ? pendingDraft : current));
|
|
157
|
+
consumePendingDraft();
|
|
158
|
+
}, [pendingDraft, consumePendingDraft]);
|
|
159
|
+
|
|
160
|
+
const affordances = chatAffordances(state);
|
|
161
|
+
const isStreaming = state.status === "running";
|
|
162
|
+
const disabled =
|
|
163
|
+
!activeSessionId ||
|
|
164
|
+
affordances.inputDisabled ||
|
|
165
|
+
messagesLoading ||
|
|
166
|
+
isStoppingTurn;
|
|
167
|
+
const canSend =
|
|
168
|
+
!isStreaming &&
|
|
169
|
+
text.trim().length > 0 &&
|
|
170
|
+
!!activeSessionId &&
|
|
171
|
+
!messagesLoading &&
|
|
172
|
+
!isStoppingTurn;
|
|
173
|
+
|
|
174
|
+
// Auto-grow the textarea up to MAX_TEXTAREA_HEIGHT.
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
const el = textareaRef.current;
|
|
177
|
+
if (!el) return;
|
|
178
|
+
el.style.height = "auto";
|
|
179
|
+
el.style.height = `${Math.min(el.scrollHeight, MAX_TEXTAREA_HEIGHT)}px`;
|
|
180
|
+
}, [text]);
|
|
181
|
+
|
|
182
|
+
// Focus the stop button when a turn starts so keyboard users can cancel
|
|
183
|
+
// without finding it. (§7.7.)
|
|
184
|
+
const stopButtonRef = useRef<HTMLButtonElement | null>(null);
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (isStreaming && stopButtonEnabled) {
|
|
187
|
+
stopButtonRef.current?.focus();
|
|
188
|
+
}
|
|
189
|
+
}, [isStreaming, stopButtonEnabled]);
|
|
190
|
+
|
|
191
|
+
function handleSubmit(): void {
|
|
192
|
+
const trimmed = text.trim();
|
|
193
|
+
if (!canSend || trimmed.length === 0) return;
|
|
194
|
+
setText("");
|
|
195
|
+
void sendMessage(trimmed);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function handleKeyDown(e: KeyboardEvent<HTMLTextAreaElement>): void {
|
|
199
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
200
|
+
e.preventDefault();
|
|
201
|
+
handleSubmit();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const rootClass = props.className
|
|
206
|
+
? `${cls.root} ${props.className}`
|
|
207
|
+
: cls.root;
|
|
208
|
+
|
|
209
|
+
// Phase-aware stop label per §10.4: "Stop generation" during the
|
|
210
|
+
// model_* phases; "Cancel tool" during `tool_executing`. The label
|
|
211
|
+
// is the visible text AND the `aria-label`.
|
|
212
|
+
const stopLabel =
|
|
213
|
+
state.phase === "tool_executing"
|
|
214
|
+
? texts.chat.cancelToolButton
|
|
215
|
+
: texts.chat.stopGenerationButton;
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<div className={rootClass} data-testid="message-input">
|
|
219
|
+
<form
|
|
220
|
+
className={cls.form}
|
|
221
|
+
onSubmit={(e) => {
|
|
222
|
+
e.preventDefault();
|
|
223
|
+
handleSubmit();
|
|
224
|
+
}}
|
|
225
|
+
>
|
|
226
|
+
<div className={cls.inputRow}>
|
|
227
|
+
<textarea
|
|
228
|
+
ref={textareaRef}
|
|
229
|
+
className={cls.textarea}
|
|
230
|
+
value={text}
|
|
231
|
+
onChange={(e) => setText(e.target.value)}
|
|
232
|
+
onKeyDown={handleKeyDown}
|
|
233
|
+
placeholder={texts.chat.inputPlaceholder}
|
|
234
|
+
disabled={disabled}
|
|
235
|
+
rows={1}
|
|
236
|
+
data-testid="message-input-textarea"
|
|
237
|
+
aria-label={texts.chat.inputPlaceholder}
|
|
238
|
+
/>
|
|
239
|
+
{isStreaming && stopButtonEnabled ? (
|
|
240
|
+
<button
|
|
241
|
+
ref={stopButtonRef}
|
|
242
|
+
type="button"
|
|
243
|
+
className={cls.stopButton}
|
|
244
|
+
onClick={() => {
|
|
245
|
+
if (isStoppingTurn) return;
|
|
246
|
+
void stop();
|
|
247
|
+
}}
|
|
248
|
+
disabled={isStoppingTurn}
|
|
249
|
+
aria-label={isStoppingTurn ? texts.chat.stoppingButton : stopLabel}
|
|
250
|
+
aria-busy={isStoppingTurn}
|
|
251
|
+
data-testid="message-input-stop"
|
|
252
|
+
data-stopping={isStoppingTurn ? "true" : "false"}
|
|
253
|
+
data-phase={state.phase ?? "none"}
|
|
254
|
+
>
|
|
255
|
+
{isStoppingTurn ? texts.chat.stoppingButton : stopLabel}
|
|
256
|
+
</button>
|
|
257
|
+
) : !isStreaming ? (
|
|
258
|
+
<button
|
|
259
|
+
type="submit"
|
|
260
|
+
className={cls.sendButton}
|
|
261
|
+
disabled={!canSend}
|
|
262
|
+
aria-label={texts.chat.sendButtonAriaLabel}
|
|
263
|
+
data-testid="message-input-send"
|
|
264
|
+
>
|
|
265
|
+
{texts.chat.sendButton}
|
|
266
|
+
</button>
|
|
267
|
+
) : null}
|
|
268
|
+
</div>
|
|
269
|
+
{showToolbar && (showEffortControl || props.toolbar) ? (
|
|
270
|
+
<div className={cls.toolbar} data-testid="message-input-toolbar">
|
|
271
|
+
{showEffortControl ? (
|
|
272
|
+
<EffortControl
|
|
273
|
+
disabled={disabled}
|
|
274
|
+
{...(props.texts !== undefined ? { texts: props.texts } : {})}
|
|
275
|
+
/>
|
|
276
|
+
) : null}
|
|
277
|
+
{props.toolbar}
|
|
278
|
+
</div>
|
|
279
|
+
) : null}
|
|
280
|
+
</form>
|
|
281
|
+
</div>
|
|
282
|
+
);
|
|
283
|
+
}
|