diff --git a/web-app/src/containers/ChatInput.tsx b/web-app/src/containers/ChatInput.tsx index 3026a30f2..3d70e93f0 100644 --- a/web-app/src/containers/ChatInput.tsx +++ b/web-app/src/containers/ChatInput.tsx @@ -40,6 +40,8 @@ import { useShallow } from 'zustand/react/shallow' import { McpExtensionToolLoader } from './McpExtensionToolLoader' import { ExtensionTypeEnum, MCPExtension } from '@janhq/core' import { ExtensionManager } from '@/lib/extension' +import { useAnalytic } from '@/hooks/useAnalytic' +import posthog from 'posthog-js' type ChatInputProps = { className?: string @@ -88,6 +90,7 @@ const ChatInput = ({ const selectedModel = useModelProvider((state) => state.selectedModel) const selectedProvider = useModelProvider((state) => state.selectedProvider) const sendMessage = useChat() + const { productAnalytic } = useAnalytic() const [message, setMessage] = useState('') const [dropdownToolsAvailable, setDropdownToolsAvailable] = useState(false) const [tooltipToolsAvailable, setTooltipToolsAvailable] = useState(false) @@ -179,8 +182,7 @@ const ChatInput = ({ const mcpExtension = extensionManager.get(ExtensionTypeEnum.MCP) const MCPToolComponent = mcpExtension?.getToolComponent?.() - - const handleSendMesage = async (prompt: string) => { + const handleSendMessage = async (prompt: string) => { if (!selectedModel) { setMessage('Please select a model to start chatting.') return @@ -189,6 +191,19 @@ const ChatInput = ({ return } setMessage('') + + // Track message send event with PostHog (only if product analytics is enabled) + if (productAnalytic && selectedModel && selectedProvider) { + try { + posthog.capture('message_sent', { + model_provider: selectedProvider, + model_id: selectedModel.id, + }) + } catch (error) { + console.debug('Failed to track message send event:', error) + } + } + sendMessage( prompt, true, @@ -618,7 +633,7 @@ const ChatInput = ({ ) { e.preventDefault() // Submit the message when Enter is pressed without Shift - handleSendMesage(prompt) + handleSendMessage(prompt) // When Shift+Enter is pressed, a new line is added (default behavior) } }} @@ -706,74 +721,75 @@ const ChatInput = ({ )} {selectedModel?.capabilities?.includes('tools') && - hasActiveMCPServers && ( - MCPToolComponent ? ( - // Use custom MCP component - - ) : ( - // Use default tools dropdown - - + ) : ( + // Use default tools dropdown + + + - { + setDropdownToolsAvailable(false) + e.stopPropagation() + }} > -
{ - setDropdownToolsAvailable(false) - e.stopPropagation() + { + setDropdownToolsAvailable(isOpen) + if (isOpen) { + setTooltipToolsAvailable(false) + } }} > - { - setDropdownToolsAvailable(isOpen) - if (isOpen) { - setTooltipToolsAvailable(false) - } - }} - > - {(isOpen, toolsCount) => { - return ( -
- - {toolsCount > 0 && ( -
- - {toolsCount > 99 ? '99+' : toolsCount} - -
- )} -
- ) - }} -
-
-
- -

{t('tools')}

-
-
-
- ) - )} + {(isOpen, toolsCount) => { + return ( +
+ + {toolsCount > 0 && ( +
+ + {toolsCount > 99 ? '99+' : toolsCount} + +
+ )} +
+ ) + }} + + + + +

{t('tools')}

+
+
+
+ ))} {selectedModel?.capabilities?.includes('web_search') && ( @@ -846,7 +862,7 @@ const ChatInput = ({ size="icon" disabled={!prompt.trim() && uploadedFiles.length === 0} data-test-id="send-message-button" - onClick={() => handleSendMesage(prompt)} + onClick={() => handleSendMessage(prompt)} > {streamingContent ? (