@interopio/io-assist-react 1.0.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/README.internal.md +467 -0
- package/README.md +503 -0
- package/changelog.md +2 -0
- package/dist/IoAssist.d.ts +12 -0
- package/dist/actions/abortActiveStream.d.ts +2 -0
- package/dist/actions/deleteThread.d.ts +2 -0
- package/dist/actions/elicitation.d.ts +13 -0
- package/dist/actions/initIoAiWeb.d.ts +3 -0
- package/dist/actions/initIoConnect.d.ts +9 -0
- package/dist/actions/mcpAppEvents.d.ts +4 -0
- package/dist/actions/newConversation.d.ts +2 -0
- package/dist/actions/processResponseStream.d.ts +3 -0
- package/dist/actions/renameThread.d.ts +2 -0
- package/dist/actions/sampling.d.ts +5 -0
- package/dist/actions/selectThread.d.ts +2 -0
- package/dist/actions/sendUserMessage.d.ts +3 -0
- package/dist/actions/toggleFavoritePrompt.d.ts +7 -0
- package/dist/actions/toggleTool.d.ts +2 -0
- package/dist/components/chat/ActivePanelModal.d.ts +6 -0
- package/dist/components/chat/AiDisclaimer.d.ts +6 -0
- package/dist/components/chat/Chat.d.ts +2 -0
- package/dist/components/chat/ConfirmModal.d.ts +8 -0
- package/dist/components/chat/WelcomeHeading.d.ts +6 -0
- package/dist/components/header/Header.d.ts +2 -0
- package/dist/components/input-area/InputArea.d.ts +8 -0
- package/dist/components/messages/AssistantMessage.d.ts +10 -0
- package/dist/components/messages/McpAppResource.d.ts +11 -0
- package/dist/components/messages/MdFormatter.d.ts +6 -0
- package/dist/components/messages/MessageArea.d.ts +7 -0
- package/dist/components/messages/ToolMessage.d.ts +9 -0
- package/dist/components/messages/ToolTraceMessage.d.ts +9 -0
- package/dist/components/messages/UserMessage.d.ts +9 -0
- package/dist/components/messages/mdUtils.d.ts +1 -0
- package/dist/components/messages/prismTwilightTheme.d.ts +2 -0
- package/dist/components/prompt/FavoritePromptList.d.ts +2 -0
- package/dist/components/prompt/PromptListItem.d.ts +8 -0
- package/dist/components/prompt/PromptListPanel.d.ts +6 -0
- package/dist/components/scroll-area/ScrollArea.d.ts +33 -0
- package/dist/components/shared/Icon.d.ts +8 -0
- package/dist/components/shared/IconButton.d.ts +11 -0
- package/dist/components/shared/Modal.d.ts +12 -0
- package/dist/components/shared/SearchInput.d.ts +8 -0
- package/dist/components/shared/ToggleInput.d.ts +8 -0
- package/dist/components/shared/Tooltip.d.ts +10 -0
- package/dist/components/shared/icons.d.ts +37 -0
- package/dist/components/threads/ThreadHistory.d.ts +6 -0
- package/dist/components/threads/ThreadHistoryListItem.d.ts +18 -0
- package/dist/components/threads/ThreadHistoryPanel.d.ts +7 -0
- package/dist/components/tool/ToolListItem.d.ts +8 -0
- package/dist/components/tool/ToolListPanel.d.ts +2 -0
- package/dist/components/working-context-panel/WorkingContextPanel.d.ts +2 -0
- package/dist/constants/modalActions.d.ts +11 -0
- package/dist/constants/uiStrings.d.ts +141 -0
- package/dist/context/IoAssistContext.d.ts +14 -0
- package/dist/files/inter-latin-wght-normal.woff2 +0 -0
- package/dist/hooks/useHoverMouseFollow.d.ts +27 -0
- package/dist/hooks/useIoAiWebApi.d.ts +19 -0
- package/dist/hooks/useIoAiWebBootstrap.d.ts +8 -0
- package/dist/hooks/useIoConnectApi.d.ts +12 -0
- package/dist/hooks/useIoConnectBootstrap.d.ts +10 -0
- package/dist/hooks/useIsMobileViewport.d.ts +1 -0
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3624 -0
- package/dist/index.js.map +1 -0
- package/dist/stores/agent.d.ts +15 -0
- package/dist/stores/app-lifecycle.d.ts +21 -0
- package/dist/stores/confirm-modal.d.ts +29 -0
- package/dist/stores/index.d.ts +32 -0
- package/dist/stores/mcp-apps.d.ts +13 -0
- package/dist/stores/message.d.ts +33 -0
- package/dist/stores/prompt.d.ts +16 -0
- package/dist/stores/response-stream.d.ts +31 -0
- package/dist/stores/thread.d.ts +17 -0
- package/dist/stores/tool.d.ts +15 -0
- package/dist/stores/working-context.d.ts +16 -0
- package/dist/styles.css +1 -0
- package/dist/types/agent.d.ts +8 -0
- package/dist/types/config.d.ts +40 -0
- package/dist/types/icon.d.ts +5 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/loading.d.ts +38 -0
- package/dist/types/message.d.ts +56 -0
- package/dist/types/panel.d.ts +6 -0
- package/dist/types/prompt.d.ts +17 -0
- package/dist/types/stream.d.ts +22 -0
- package/dist/types/thread.d.ts +15 -0
- package/dist/types/tool.d.ts +15 -0
- package/dist/utils/confirmModal.d.ts +5 -0
- package/dist/utils/ioModals.d.ts +21 -0
- package/dist/utils/logger.d.ts +34 -0
- package/dist/utils/mcpAppModal.d.ts +3 -0
- package/dist/utils/messageConverter.d.ts +3 -0
- package/dist/utils/messageUtils.d.ts +16 -0
- package/dist/utils/safeStringify.d.ts +1 -0
- package/dist/utils/streamUtils.d.ts +15 -0
- package/dist/utils/threadUtils.d.ts +16 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/constants/uiStrings.ts","../src/types/message.ts","../src/types/tool.ts","../src/types/panel.ts","../src/types/stream.ts","../src/types/loading.ts","../src/stores/agent.ts","../src/stores/app-lifecycle.ts","../src/stores/confirm-modal.ts","../src/stores/mcp-apps.ts","../src/stores/message.ts","../src/stores/prompt.ts","../src/stores/response-stream.ts","../src/stores/thread.ts","../src/stores/tool.ts","../src/stores/working-context.ts","../src/stores/index.ts","../src/context/IoAssistContext.tsx","../src/utils/logger.ts","../src/actions/toggleFavoritePrompt.ts","../src/hooks/useIoConnectApi.ts","../src/components/shared/Icon.tsx","../src/components/shared/icons.tsx","../src/components/prompt/PromptListItem.tsx","../src/components/shared/SearchInput.tsx","../src/components/prompt/PromptListPanel.tsx","../src/components/shared/IconButton.tsx","../src/components/shared/Modal.tsx","../src/components/shared/ToggleInput.tsx","../src/components/shared/Tooltip.tsx","../src/components/tool/ToolListItem.tsx","../src/actions/abortActiveStream.ts","../src/actions/newConversation.ts","../src/actions/deleteThread.ts","../src/actions/renameThread.ts","../src/utils/safeStringify.ts","../src/utils/messageConverter.ts","../src/utils/threadUtils.ts","../src/actions/selectThread.ts","../src/utils/streamUtils.ts","../src/actions/processResponseStream.ts","../src/actions/sendUserMessage.ts","../src/actions/toggleTool.ts","../src/hooks/useIoAiWebApi.ts","../src/components/tool/ToolListPanel.tsx","../src/components/messages/prismTwilightTheme.ts","../src/components/messages/MdFormatter.tsx","../src/components/messages/mdUtils.ts","../src/components/working-context-panel/WorkingContextPanel.tsx","../src/components/chat/ActivePanelModal.tsx","../src/components/chat/AiDisclaimer.tsx","../src/utils/confirmModal.ts","../src/components/chat/ConfirmModal.tsx","../src/components/chat/WelcomeHeading.tsx","../src/hooks/useIsMobileViewport.ts","../src/hooks/useHoverMouseFollow.ts","../src/components/header/Header.tsx","../src/components/input-area/InputArea.tsx","../src/components/messages/AssistantMessage.tsx","../src/components/messages/McpAppResource.tsx","../src/components/messages/ToolMessage.tsx","../src/components/messages/ToolTraceMessage.tsx","../src/components/messages/UserMessage.tsx","../src/utils/messageUtils.ts","../src/components/scroll-area/ScrollArea.tsx","../src/components/messages/MessageArea.tsx","../src/components/prompt/FavoritePromptList.tsx","../src/components/threads/ThreadHistoryListItem.tsx","../src/components/threads/ThreadHistory.tsx","../src/components/threads/ThreadHistoryPanel.tsx","../src/components/chat/Chat.tsx","../src/constants/modalActions.ts","../src/utils/ioModals.ts","../src/actions/elicitation.ts","../src/utils/mcpAppModal.ts","../src/actions/mcpAppEvents.ts","../src/actions/sampling.ts","../src/actions/initIoAiWeb.ts","../src/hooks/useIoAiWebBootstrap.ts","../src/actions/initIoConnect.ts","../src/hooks/useIoConnectBootstrap.ts","../src/IoAssist.tsx"],"sourcesContent":["export const UI_STRINGS = {\n GENERAL: {\n WELCOME_MESSAGE: (user?: string) =>\n user\n ? `Welcome, ${user}! How can I assist you today?`\n : 'Welcome! How can I assist you today?',\n AI_CONTENT_INFO: 'AI-generated content may be incorrect',\n INITIALIZING_SERVICES: 'Initializing services, please wait...',\n CANNOT_CONNECT_TO_IO: 'Cannot connect to IO.',\n IO_INTEL_INIT_ERROR:\n 'Error initializing IO Intel Web API. Please check your configuration and refresh the page to try again.',\n DOCUMENTATION_LINK: (url?: string) =>\n `For more information, please refer to the documentation: ${url && url.length > 0 ? url : 'https://docs-ai.interop.io/'}`,\n REFRESH: 'Refresh',\n EDIT: 'Edit',\n DELETE: 'Delete',\n SAVE: 'Save',\n CANCEL: 'Cancel',\n CONFIRM: 'Confirm',\n SUBMIT: 'Submit',\n SEARCH: 'Search',\n LOADING: 'Loading',\n COPY: 'Copy',\n RELOAD: 'Reload',\n NO_SEARCH_RESULTS: 'No results found',\n },\n INPUT_COMPONENT: {\n DEFAULT_PLACEHOLDER: 'Enter text here',\n INPUT_PLACEHOLDER: 'Type your message...',\n AI_DISCLAIMER: 'Ai-generated content may be incorrect',\n },\n PANEL_COMPONENT: {\n DEFAULT_TITLE: 'Panel',\n CLOSE_BUTTON: 'Close',\n },\n WORKING_CONTEXT_PANEL_COMPONENT: {\n TITLE: 'Working Context',\n VIEW_WORKING_CONTEXT_BUTTON: 'View Context',\n LOADING_CONTEXT: 'Loading working context...',\n CALLOUT_TEXT:\n 'The working context provides additional information to assist the agent in generating accurate responses.',\n },\n CHAT_COMPONENT: {\n LOGOUT: 'Logout',\n },\n THREAD_HISTORY_COMPONENT: {\n NO_THREADS: 'No available message threads.',\n LOADING_THREADS: 'Loading threads...',\n NEW_CONVERSATION: 'New Conversation',\n DIVIDERS: {\n JUST_NOW: 'Just now',\n FIVE_MINS_AGO: '5 mins ago',\n THIRTY_MINS_AGO: '30 mins ago',\n ONE_HOUR_AGO: '1 hour ago',\n TWO_HOURS_AGO: '2 hours ago',\n SIX_HOURS_AGO: '6 hours ago',\n TWELVE_HOURS_AGO: '12 hours ago',\n TODAY: 'Today',\n YESTERDAY: 'Yesterday',\n TWO_DAYS_AGO: '2 days ago',\n LAST_WEEK: 'Last Week',\n TWO_WEEKS_AGO: '2 weeks ago',\n ONE_MONTH_AGO: '1 month ago',\n THREE_MONTHS_AGO: '3 months ago',\n SIX_MONTHS_AGO: '6 months ago',\n MORE_THAN_YEAR_AGO: 'more than 1 year ago',\n },\n },\n PROMPT_LIST_COMPONENT: {\n AVAILABLE_PROMPTS: 'Available Prompts',\n FAVORITE_PROMPTS: 'Favorite Prompts',\n NO_PROMPTS: 'No prompts available.',\n NO_PROMPTS_CONFIGURED:\n 'No prompts are available. Prompts should be provided as a configuration.',\n LOADING_PROMPTS: 'Loading prompts...',\n NO_FAVORITE_PROMPTS: 'No favorite prompts available.',\n NO_PROMPTS_SEE_MORE: 'See more',\n INPUT_TOOLTIP: 'Search prompts...',\n },\n TOOL_LIST_COMPONENT: {\n AVAILABLE_TOOLS: 'Available Tools',\n NO_FILTERED_TOOLS: 'No tools matching your search.',\n NO_TOOLS: 'There are currently no tools available.',\n NO_TOOLS_SEE_MORE: 'See more',\n LOADING_TOOLS: 'Loading tools...',\n INPUT_TOOLTIP: 'Search tools...',\n ENABLE_BUTTON: 'Enable',\n DISABLE_BUTTON: 'Disable',\n },\n TOOL_MESSAGE: {\n TOOL_EXECUTION_SUCCESS: 'Tool executed successfully.',\n TOOL_EXECUTION_PENDING: 'Tool execution in progress...',\n },\n TOOL_TRACE_MESSAGE: {\n EXPAND_BUTTON_TEXT: 'Show Tool Trace Details',\n COLLAPSE_BUTTON_TEXT: 'Hide Tool Trace Details',\n CLOSE_BUTTON_TEXT: 'Close',\n },\n\n // ── Aliases used by panel + layout components ──────────────────────────\n\n THREAD_HISTORY: {\n NEW_CONVERSATION: 'New Conversation',\n NO_CONVERSATIONS: 'No conversations yet.',\n },\n WORKING_CONTEXT_PANEL: {\n TITLE: 'Working Context',\n DESCRIPTION:\n 'The working context provides additional information to assist the agent in generating accurate responses.',\n EMPTY: 'No working context available.',\n },\n PROMPT_LIST_PANEL: {\n TITLE: 'Prompts',\n SEARCH_PLACEHOLDER: 'Search prompts...',\n EMPTY: 'No prompts available.',\n },\n TOOL_LIST_PANEL: {\n TITLE: 'Tools',\n SEARCH_PLACEHOLDER: 'Search tools...',\n EMPTY: 'There are currently no tools available.',\n NO_SEARCH_MATCH: 'No tools matching your search.',\n LOADING: 'Loading tools...',\n SERVER_LABEL: 'Server:',\n },\n WELCOME_SCREEN: {\n TITLE: 'Welcome {name}, how can I help?',\n SUBTITLE: 'Ask me anything or pick a quick prompt below.',\n FAVORITE_PROMPTS_LABEL: 'Favorite Prompts',\n },\n LOADING_STATE: {\n LOADING: 'Initializing services, please wait...',\n ERROR: 'Error initializing IO Intel Web API. Please check your configuration and refresh the page to try again.',\n RETRY: 'Refresh',\n },\n SAMPLING_MODAL: {\n TITLE: 'io.Assist',\n HEADING: 'Permission to Proceed',\n TEXT: `I can dive deeper to give a clearer answer, but I'll need your permission first. Continue?`,\n },\n ELICITATION_MODAL: {\n TITLE: 'io.Assist',\n HEADING: 'Permission to Proceed',\n FALLBACK_TEXT: `I can dive deeper to give a clearer answer, but I'll need your permission first. Continue?`,\n },\n MCP_APP_REPLACE_MODAL: {\n TITLE: 'MCP App Already Open',\n HEADING: 'Replace Existing Instance?',\n TEXT: (toolName: string) =>\n `An instance of \"${toolName}\" is already open in the workspace. Replace it with the new instance, or open it alongside as a new instance?`,\n REPLACE_BUTTON: 'Replace',\n NEW_INSTANCE_BUTTON: 'New Instance',\n },\n};\n","export const UI_MESSAGE_ROLES = {\n USER: 'user',\n ASSISTANT: 'assistant',\n TOOL: 'tool',\n} as const;\n\nexport type UIMessageRole = (typeof UI_MESSAGE_ROLES)[keyof typeof UI_MESSAGE_ROLES];\n\nexport const TOOL_RESULT_TYPES = {\n TEXT: 'text',\n IMAGE: 'image',\n AUDIO: 'audio',\n} as const;\n\nexport type ToolResultType = (typeof TOOL_RESULT_TYPES)[keyof typeof TOOL_RESULT_TYPES];\n\nexport type UIMessageBase = {\n id: string;\n role: UIMessageRole;\n content?: string;\n displayFooter?: boolean;\n responseForUserQueryId?: string;\n isLastMessage?: boolean;\n isNew?: boolean;\n};\n\nexport type UIUserMessage = UIMessageBase & {\n role: typeof UI_MESSAGE_ROLES.USER;\n};\n\nexport type UIAssistantMessage = UIMessageBase & {\n role: typeof UI_MESSAGE_ROLES.ASSISTANT;\n};\n\nexport type ToolTextResult = { type: typeof TOOL_RESULT_TYPES.TEXT; text: string };\nexport type ToolImageResult = {\n type: typeof TOOL_RESULT_TYPES.IMAGE;\n data: string;\n mimeType: string;\n};\nexport type ToolAudioResult = {\n type: typeof TOOL_RESULT_TYPES.AUDIO;\n data: string;\n mimeType: string;\n};\nexport type ToolResult = ToolTextResult | ToolImageResult | ToolAudioResult;\n\nexport type UIToolMessage = UIMessageBase & {\n toolName: string;\n role: typeof UI_MESSAGE_ROLES.TOOL;\n args?: Record<string, unknown>;\n result?: ToolResult | [ToolResult];\n isExpanded?: boolean;\n};\n\nexport type UIMessage = UIUserMessage | UIAssistantMessage | UIToolMessage;\n\nexport type ToolTraceState = {\n stateForMessageId: string;\n executedTools: UIToolMessage[];\n uiMessage: string;\n isExpanded?: boolean;\n};\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nexport const TOOL_STATES = {\n IDLE: 'IDLE',\n ENABLING_DISABLING: 'ENABLING_DISABLING',\n} as const;\n\nexport type ToolState = (typeof TOOL_STATES)[keyof typeof TOOL_STATES];\n\nexport type UITool = {\n name: string;\n description: string;\n enabled: boolean;\n icon?: string;\n mcpServerName?: string;\n state: ToolState;\n rawTool: IoAiWeb.Tools.Tool;\n};\n","export const PANEL_CONTENT = {\n WORKING_CONTEXT: 'working-context',\n PROMPTS: 'prompts',\n TOOLS: 'tools',\n} as const;\n\nexport type PanelContent = (typeof PANEL_CONTENT)[keyof typeof PANEL_CONTENT] | null;\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nexport type GetResponseParams = {\n messages: IoAiWeb.Agents.AgentMessage[];\n instructions?: string;\n system?: string;\n memory?: {\n thread: string;\n resource: string;\n };\n modelSettings?: {\n maxTokens?: number;\n temperature?: number;\n };\n};\n\nexport const RESPONSE_STREAM_STATUS = {\n IDLE: 'idle',\n STREAMING: 'streaming',\n COMPLETED: 'completed',\n ERROR: 'error',\n ABORTED: 'aborted',\n} as const;\n\nexport type ResponseStreamStatus =\n (typeof RESPONSE_STREAM_STATUS)[keyof typeof RESPONSE_STREAM_STATUS];\n","export const LOADING_STATES = {\n NOT_STARTED: 'not-started',\n LOADING: 'loading',\n SUCCESS: 'success',\n ERROR: 'error',\n} as const;\n\nexport type LoadingState =\n | { type: typeof LOADING_STATES.NOT_STARTED }\n | { type: typeof LOADING_STATES.LOADING }\n | { type: typeof LOADING_STATES.SUCCESS }\n | { type: typeof LOADING_STATES.ERROR; message: string };\n\nexport const MESSAGES_LOADING_STATE = {\n NOT_STARTED: 'NOT_STARTED',\n LOADING_RESPONSE: 'LOADING_RESPONSE',\n LOADING_FROM_THREAD: 'LOADING_FROM_THREAD',\n GET_RESPONSE_SUCCESS: 'GET_RESPONSE_SUCCESS',\n FETCH_MESSAGES_FROM_THREAD_SUCCESS: 'FETCH_MESSAGES_FROM_THREAD_SUCCESS',\n ERROR: 'ERROR',\n} as const;\n\nexport type MessagesLoadingState =\n | { type: typeof MESSAGES_LOADING_STATE.NOT_STARTED }\n | { type: typeof MESSAGES_LOADING_STATE.LOADING_RESPONSE }\n | { type: typeof MESSAGES_LOADING_STATE.LOADING_FROM_THREAD }\n | { type: typeof MESSAGES_LOADING_STATE.GET_RESPONSE_SUCCESS }\n | { type: typeof MESSAGES_LOADING_STATE.FETCH_MESSAGES_FROM_THREAD_SUCCESS }\n | { type: typeof MESSAGES_LOADING_STATE.ERROR; message: string };\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport { LOADING_STATES, type LoadingState, type UIAgent } from '../types';\n\nexport type AgentSlice = {\n agents: UIAgent[];\n selectedAgent: UIAgent | null;\n agentsLoadingState: LoadingState;\n setAgents: (agents: UIAgent[]) => void;\n setSelectedAgent: (agent: UIAgent | null) => void;\n setAgentsLoadingState: (state: LoadingState) => void;\n};\n\nexport const createAgentSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n AgentSlice\n> = (set) => ({\n agents: [],\n selectedAgent: null,\n agentsLoadingState: { type: LOADING_STATES.NOT_STARTED },\n setAgents: (agents) => set({ agents }),\n setSelectedAgent: (agent) => set({ selectedAgent: agent }),\n setAgentsLoadingState: (state) => set({ agentsLoadingState: state }),\n});\n","import type { IoAiWeb } from '@interopio/ai-web';\nimport type { IOConnectBrowser } from '@interopio/browser';\nimport type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport { LOADING_STATES, type LoadingState } from '../types';\n\nexport type AppLifecycleSlice = {\n appLoadingState: LoadingState;\n isIoConnectReady: boolean;\n isDarkMode: boolean;\n ioConnectApi: IOConnectBrowser.API | null;\n ioAiWebApi: IoAiWeb.API | null;\n setAppLoadingState: (state: LoadingState) => void;\n setIsIoConnectReady: (ready: boolean) => void;\n setIsDarkMode: (dark: boolean) => void;\n setIoConnectApi: (api: IOConnectBrowser.API | null) => void;\n setIoAiWebApi: (api: IoAiWeb.API | null) => void;\n};\n\nexport const createAppLifecycleSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n AppLifecycleSlice\n> = (set) => ({\n appLoadingState: { type: LOADING_STATES.NOT_STARTED },\n isIoConnectReady: false,\n isDarkMode: false,\n ioConnectApi: null,\n ioAiWebApi: null,\n setAppLoadingState: (state) => set({ appLoadingState: state }),\n setIsIoConnectReady: (ready) => set({ isIoConnectReady: ready }),\n setIsDarkMode: (dark) => set({ isDarkMode: dark }),\n setIoConnectApi: (api) => set({ ioConnectApi: api }),\n setIoAiWebApi: (api) => set({ ioAiWebApi: api }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport type { PanelContent } from '../types';\n\nexport type ConfirmModalButton = {\n id: string;\n label: string;\n variant: 'primary' | 'default';\n};\n\nexport type ConfirmModalConfig = {\n title: string;\n heading: string;\n text: string;\n buttons: ConfirmModalButton[];\n /** Show an X close icon in the header. Defaults to false (matches ng). */\n isHeaderCloseButtonDisplayed?: boolean;\n};\n\nexport type ConfirmModalSlice = {\n isThreadHistoryVisible: boolean;\n activePanelContent: PanelContent;\n currentConfirmModal: ConfirmModalConfig | null;\n setIsThreadHistoryVisible: (visible: boolean) => void;\n setActivePanelContent: (content: PanelContent) => void;\n showConfirmModal: (config: ConfirmModalConfig) => void;\n closeConfirmModal: () => void;\n};\n\nexport const createConfirmModalSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n ConfirmModalSlice\n> = (set) => ({\n isThreadHistoryVisible: false,\n activePanelContent: null,\n currentConfirmModal: null,\n setIsThreadHistoryVisible: (visible) => set({ isThreadHistoryVisible: visible }),\n setActivePanelContent: (content) => set({ activePanelContent: content }),\n showConfirmModal: (config) => set({ currentConfirmModal: config }),\n closeConfirmModal: () => set({ currentConfirmModal: null }),\n});\n","import type { IoAiWeb } from '@interopio/ai-web';\nimport type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\n\nexport type McpAppsSlice = {\n mcpAppInstances: IoAiWeb.McpApps.AppInstance[];\n addMcpApp: (instance: IoAiWeb.McpApps.AppInstance) => void;\n removeMcpApp: (instanceId: string) => void;\n resetMcpApps: () => void;\n};\n\nexport const createMcpAppsSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n McpAppsSlice\n> = (set) => ({\n mcpAppInstances: [],\n addMcpApp: (instance) =>\n set((s) => {\n if (s.mcpAppInstances.find((a) => a.id === instance.id)) return {};\n return { mcpAppInstances: [...s.mcpAppInstances, instance] };\n }),\n removeMcpApp: (instanceId) =>\n set((s) => ({\n mcpAppInstances: s.mcpAppInstances.filter((a) => a.id !== instanceId),\n })),\n resetMcpApps: () => set({ mcpAppInstances: [] }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport {\n MESSAGES_LOADING_STATE,\n type MessagesLoadingState,\n type ToolTraceState,\n type UIMessage,\n} from '../types';\n\nexport type MessageSlice = {\n messages: UIMessage[];\n isGeneratingResponse: boolean;\n messageLoadingState: MessagesLoadingState;\n isLastResponseSuccess: boolean;\n toolTraceState: ToolTraceState[];\n /**\n * Monotonically-increasing counter incremented every time we want the chat\n * to snap the latest content to the top of the visible viewport (imperative\n * one-shot trigger, called from `sendUserMessage`). ScrollArea subscribes\n * and reacts to each tick.\n */\n scrollAnchorRequestId: number;\n setMessages: (messages: UIMessage[]) => void;\n addMessage: (message: UIMessage) => void;\n updateMessage: (id: string, changes: Partial<UIMessage>) => void;\n clearMessages: () => void;\n setIsGeneratingResponse: (generating: boolean) => void;\n setMessageLoadingState: (state: MessagesLoadingState) => void;\n setIsLastResponseSuccess: (success: boolean) => void;\n setToolTraceState: (state: ToolTraceState[]) => void;\n toggleToolTrace: (messageId: string) => void;\n toggleToolMessage: (toolMessageId: string, parentId: string) => void;\n mergeAccumulatedStreamContent: (threadId: string) => void;\n requestScrollAnchor: () => void;\n};\n\nexport const createMessageSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n MessageSlice\n> = (set) => ({\n messages: [],\n isGeneratingResponse: false,\n messageLoadingState: { type: MESSAGES_LOADING_STATE.NOT_STARTED },\n isLastResponseSuccess: false,\n toolTraceState: [],\n scrollAnchorRequestId: 0,\n requestScrollAnchor: () => set((s) => ({ scrollAnchorRequestId: s.scrollAnchorRequestId + 1 })),\n setMessages: (messages) => set({ messages }),\n addMessage: (message) => set((s) => ({ messages: [...s.messages, message] })),\n updateMessage: (id, changes) =>\n set((s) => ({\n messages: s.messages.map((m) =>\n m.id === id ? ({ ...m, ...changes } as UIMessage) : m,\n ),\n })),\n clearMessages: () =>\n set({\n messages: [],\n toolTraceState: [],\n isLastResponseSuccess: false,\n messageLoadingState: { type: MESSAGES_LOADING_STATE.NOT_STARTED },\n }),\n setIsGeneratingResponse: (generating) => set({ isGeneratingResponse: generating }),\n setMessageLoadingState: (state) => set({ messageLoadingState: state }),\n setIsLastResponseSuccess: (success) => set({ isLastResponseSuccess: success }),\n setToolTraceState: (state) => set({ toolTraceState: state }),\n toggleToolTrace: (messageId) =>\n set((s) => ({\n toolTraceState: s.toolTraceState.map((t) =>\n t.stateForMessageId === messageId ? { ...t, isExpanded: !t.isExpanded } : t,\n ),\n })),\n toggleToolMessage: (toolMessageId, parentId) =>\n set((s) => ({\n toolTraceState: s.toolTraceState.map((t) =>\n t.stateForMessageId === parentId\n ? {\n ...t,\n executedTools: t.executedTools.map((tool) =>\n tool.id === toolMessageId\n ? { ...tool, isExpanded: !tool.isExpanded }\n : tool,\n ),\n }\n : t,\n ),\n })),\n mergeAccumulatedStreamContent: (threadId) =>\n set((s) => {\n const stream = s.streamsByThreadId[threadId];\n if (!stream) return {};\n\n let updatedMessages = [...s.messages];\n\n if (\n stream.userMessage &&\n !updatedMessages.some((m) => m.id === stream.userMessage!.id)\n ) {\n updatedMessages.push(stream.userMessage);\n }\n\n for (const toolMsg of stream.toolMessages) {\n if (!updatedMessages.some((m) => m.id === toolMsg.id)) {\n updatedMessages.push(toolMsg);\n }\n }\n\n // Anchor for the assistant bubble and its tool trace. Fall back to a\n // synthesised id only when buffered tools exist without any assistant\n // text — we still need a stable parent id for the trace.\n const assistantId =\n stream.messageId ??\n (stream.toolMessages.length > 0 ? `accumulated-${Date.now()}` : null);\n\n if (stream.content && stream.content.trim() !== '') {\n const existingIdx = updatedMessages.findIndex(\n (m) => m.id === assistantId && m.role === 'assistant',\n );\n\n if (existingIdx >= 0) {\n updatedMessages = updatedMessages.map((msg, idx) =>\n idx === existingIdx ? { ...msg, content: stream.content } : msg,\n );\n } else if (assistantId) {\n updatedMessages.push({\n id: assistantId,\n role: 'assistant' as const,\n content: stream.content,\n });\n }\n } else if (\n assistantId &&\n stream.toolMessages.length > 0 &&\n !updatedMessages.some((m) => m.id === assistantId && m.role === 'assistant')\n ) {\n updatedMessages.push({\n id: assistantId,\n role: 'assistant' as const,\n content: '',\n });\n }\n\n let nextToolTraceState = s.toolTraceState;\n if (assistantId && stream.toolMessages.length > 0) {\n const n = stream.toolMessages.length;\n const trace: ToolTraceState = {\n stateForMessageId: assistantId,\n executedTools: stream.toolMessages,\n uiMessage: `Used ${n} tool${n !== 1 ? 's' : ''}`,\n isExpanded: false,\n };\n const existingIdx = nextToolTraceState.findIndex(\n (t) => t.stateForMessageId === assistantId,\n );\n nextToolTraceState =\n existingIdx >= 0\n ? nextToolTraceState.map((t, i) => (i === existingIdx ? trace : t))\n : [...nextToolTraceState, trace];\n }\n\n const messagesChanged = updatedMessages.length !== s.messages.length;\n const tracesChanged = nextToolTraceState !== s.toolTraceState;\n if (!messagesChanged && !tracesChanged) return {};\n\n const patch: Partial<Pick<MessageSlice, 'messages' | 'toolTraceState'>> = {};\n if (messagesChanged) patch.messages = updatedMessages;\n if (tracesChanged) patch.toolTraceState = nextToolTraceState;\n return patch;\n }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport type { Prompt } from '../types';\n\nexport type PromptSlice = {\n allPrompts: Prompt[];\n favoritePromptNames: string[];\n selectedPrompt: Prompt | null;\n setAllPrompts: (prompts: Prompt[]) => void;\n setFavoritePromptNames: (names: string[]) => void;\n toggleFavoritePrompt: (name: string) => void;\n setSelectedPrompt: (prompt: Prompt | null) => void;\n};\n\nexport const createPromptSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n PromptSlice\n> = (set) => ({\n allPrompts: [],\n favoritePromptNames: [],\n selectedPrompt: null,\n setAllPrompts: (prompts) => set({ allPrompts: prompts }),\n setFavoritePromptNames: (names) => set({ favoritePromptNames: names }),\n toggleFavoritePrompt: (name) =>\n set((s) => {\n const isFav = s.favoritePromptNames.includes(name);\n return {\n favoritePromptNames: isFav\n ? s.favoritePromptNames.filter((n) => n !== name)\n : [...s.favoritePromptNames, name],\n };\n }),\n setSelectedPrompt: (prompt) => set({ selectedPrompt: prompt }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport {\n RESPONSE_STREAM_STATUS,\n type ResponseStreamStatus,\n type UIToolMessage,\n type UIUserMessage,\n} from '../types';\n\nexport type StreamState = {\n status: ResponseStreamStatus;\n content: string;\n messageId: string | null;\n errorMessage?: string;\n userMessage: UIUserMessage | null;\n toolMessages: UIToolMessage[];\n};\n\nexport type ResponseStreamSlice = {\n streamsByThreadId: Record<string, StreamState>;\n completionNotifications: string[];\n startStream: (threadId: string, userMessage: UIUserMessage | null) => void;\n updateStreamContent: (threadId: string, content: string, messageId: string) => void;\n addStreamToolMessage: (threadId: string, toolMessage: UIToolMessage) => void;\n completeStream: (threadId: string, shouldNotify: boolean) => void;\n failStream: (threadId: string, errorMessage: string) => void;\n abortStream: (threadId: string) => void;\n untrackStream: (threadId: string) => void;\n setStreamState: (threadId: string, state: Partial<StreamState>) => void;\n clearStreamState: (threadId: string) => void;\n addCompletionNotification: (threadId: string) => void;\n clearCompletionNotification: (threadId: string) => void;\n clearAllCompletionNotifications: () => void;\n};\n\nexport const createResponseStreamSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n ResponseStreamSlice\n> = (set) => ({\n streamsByThreadId: {},\n completionNotifications: [],\n startStream: (threadId, userMessage) =>\n set((s) => ({\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: {\n status: RESPONSE_STREAM_STATUS.STREAMING,\n content: '',\n messageId: null,\n userMessage,\n toolMessages: [],\n },\n },\n })),\n updateStreamContent: (threadId, content, messageId) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing || existing.status !== RESPONSE_STREAM_STATUS.STREAMING) return {};\n return {\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: { ...existing, content, messageId },\n },\n };\n }),\n addStreamToolMessage: (threadId, toolMessage) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing || existing.status !== RESPONSE_STREAM_STATUS.STREAMING) return {};\n const idx = existing.toolMessages.findIndex((t) => t.id === toolMessage.id);\n const updatedToolMessages =\n idx >= 0\n ? existing.toolMessages.map((t, i) =>\n i === idx ? { ...t, ...toolMessage } : t,\n )\n : [...existing.toolMessages, toolMessage];\n return {\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: { ...existing, toolMessages: updatedToolMessages },\n },\n };\n }),\n completeStream: (threadId, shouldNotify) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing) return {};\n return {\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: { ...existing, status: RESPONSE_STREAM_STATUS.COMPLETED },\n },\n completionNotifications: shouldNotify\n ? [...new Set([...s.completionNotifications, threadId])]\n : s.completionNotifications,\n };\n }),\n failStream: (threadId, errorMessage) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing) return {};\n return {\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: { ...existing, status: RESPONSE_STREAM_STATUS.ERROR, errorMessage },\n },\n };\n }),\n abortStream: (threadId) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing) return {};\n return {\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: { ...existing, status: RESPONSE_STREAM_STATUS.ABORTED },\n },\n };\n }),\n untrackStream: (threadId) =>\n set((s) => {\n const existing = s.streamsByThreadId[threadId];\n if (!existing) return {};\n const isTerminal =\n existing.status === RESPONSE_STREAM_STATUS.COMPLETED ||\n existing.status === RESPONSE_STREAM_STATUS.ERROR ||\n existing.status === RESPONSE_STREAM_STATUS.ABORTED;\n if (!isTerminal) return {};\n const next = { ...s.streamsByThreadId };\n delete next[threadId];\n return { streamsByThreadId: next };\n }),\n setStreamState: (threadId, state) =>\n set((s) => ({\n streamsByThreadId: {\n ...s.streamsByThreadId,\n [threadId]: {\n ...(s.streamsByThreadId[threadId] ?? {\n status: RESPONSE_STREAM_STATUS.IDLE,\n content: '',\n messageId: null,\n userMessage: null,\n toolMessages: [],\n }),\n ...state,\n },\n },\n })),\n clearStreamState: (threadId) =>\n set((s) => {\n const next = { ...s.streamsByThreadId };\n delete next[threadId];\n return { streamsByThreadId: next };\n }),\n addCompletionNotification: (threadId) =>\n set((s) => ({\n completionNotifications: [...new Set([...s.completionNotifications, threadId])],\n })),\n clearCompletionNotification: (threadId) =>\n set((s) => ({\n completionNotifications: s.completionNotifications.filter((id) => id !== threadId),\n })),\n clearAllCompletionNotifications: () => set({ completionNotifications: [] }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport { LOADING_STATES, type LoadingState, type UIThread } from '../types';\n\nexport type ThreadSlice = {\n threads: UIThread[];\n activeThreadId: string | null;\n threadLoadingState: LoadingState;\n setThreads: (threads: UIThread[]) => void;\n updateThread: (id: string, changes: Partial<UIThread>) => void;\n removeThread: (id: string) => void;\n setActiveThreadId: (id: string | null) => void;\n setThreadLoadingState: (state: LoadingState) => void;\n};\n\nexport const createThreadSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n ThreadSlice\n> = (set) => ({\n threads: [],\n activeThreadId: null,\n threadLoadingState: { type: LOADING_STATES.NOT_STARTED },\n setThreads: (threads) => set({ threads }),\n updateThread: (id, changes) =>\n set((s) => ({\n threads: s.threads.map((t) => (t.id === id ? { ...t, ...changes } : t)),\n })),\n removeThread: (id) => set((s) => ({ threads: s.threads.filter((t) => t.id !== id) })),\n setActiveThreadId: (id) => set({ activeThreadId: id }),\n setThreadLoadingState: (state) => set({ threadLoadingState: state }),\n});\n","import type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport { LOADING_STATES, type LoadingState, type UITool } from '../types';\n\nexport type ToolSlice = {\n tools: UITool[];\n toolLoadingState: LoadingState;\n setTools: (tools: UITool[]) => void;\n updateToolEnabled: (name: string, enabled: boolean) => void;\n updateToolState: (name: string, toolState: UITool['state']) => void;\n setToolLoadingState: (state: LoadingState) => void;\n};\n\nexport const createToolSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n ToolSlice\n> = (set) => ({\n tools: [],\n toolLoadingState: { type: LOADING_STATES.NOT_STARTED },\n setTools: (tools) => set({ tools }),\n updateToolEnabled: (name, enabled) =>\n set((s) => ({\n tools: s.tools.map((t) => (t.name === name ? { ...t, enabled } : t)),\n })),\n updateToolState: (name, toolState) =>\n set((s) => ({\n tools: s.tools.map((t) => (t.name === name ? { ...t, state: toolState } : t)),\n })),\n setToolLoadingState: (state) => set({ toolLoadingState: state }),\n});\n","import type { IoIntelWorkingContext } from '@interopio/working-context';\nimport type { StateCreator } from 'zustand';\n\nimport type { IoAssistStore } from './index';\nimport { LOADING_STATES, type LoadingState } from '../types';\n\nexport type WorkingContextSlice = {\n isWorkingContextEnabled: boolean;\n workingContext: Record<string, IoIntelWorkingContext.Property> | null;\n workingContextLoadingState: LoadingState;\n setIsWorkingContextEnabled: (enabled: boolean) => void;\n setWorkingContext: (ctx: Record<string, IoIntelWorkingContext.Property> | null) => void;\n setWorkingContextLoadingState: (state: LoadingState) => void;\n};\n\nexport const createWorkingContextSlice: StateCreator<\n IoAssistStore,\n [['zustand/subscribeWithSelector', never]],\n [],\n WorkingContextSlice\n> = (set) => ({\n isWorkingContextEnabled: false,\n workingContext: null,\n workingContextLoadingState: { type: LOADING_STATES.NOT_STARTED },\n setIsWorkingContextEnabled: (enabled) => set({ isWorkingContextEnabled: enabled }),\n setWorkingContext: (ctx) => set({ workingContext: ctx }),\n setWorkingContextLoadingState: (state) => set({ workingContextLoadingState: state }),\n});\n","import { create } from 'zustand';\nimport { subscribeWithSelector } from 'zustand/middleware';\n\nimport { createAgentSlice, type AgentSlice } from './agent';\nimport { createAppLifecycleSlice, type AppLifecycleSlice } from './app-lifecycle';\nimport { createConfirmModalSlice, type ConfirmModalSlice } from './confirm-modal';\nimport { createMcpAppsSlice, type McpAppsSlice } from './mcp-apps';\nimport { createMessageSlice, type MessageSlice } from './message';\nimport { createPromptSlice, type PromptSlice } from './prompt';\nimport { createResponseStreamSlice, type ResponseStreamSlice } from './response-stream';\nimport { createThreadSlice, type ThreadSlice } from './thread';\nimport { createToolSlice, type ToolSlice } from './tool';\nimport { createWorkingContextSlice, type WorkingContextSlice } from './working-context';\n\nexport type IoAssistStore = AppLifecycleSlice &\n AgentSlice &\n ThreadSlice &\n MessageSlice &\n ResponseStreamSlice &\n PromptSlice &\n ToolSlice &\n WorkingContextSlice &\n McpAppsSlice &\n ConfirmModalSlice;\n\nexport const createIoAssistStore = () =>\n create<IoAssistStore>()(\n subscribeWithSelector((...a) => ({\n ...createAppLifecycleSlice(...a),\n ...createAgentSlice(...a),\n ...createThreadSlice(...a),\n ...createMessageSlice(...a),\n ...createResponseStreamSlice(...a),\n ...createPromptSlice(...a),\n ...createToolSlice(...a),\n ...createWorkingContextSlice(...a),\n ...createMcpAppsSlice(...a),\n ...createConfirmModalSlice(...a),\n })),\n );\n\n// Singleton instance for global usage\nexport const ioAssistStore = createIoAssistStore();\n\nexport type IoAssistStoreInstance = ReturnType<typeof createIoAssistStore>;\n\n// Re-export domain types frequently imported alongside the store\nexport type { ConfirmModalButton, ConfirmModalConfig } from './confirm-modal';\nexport type { StreamState } from './response-stream';\n","import React, { createContext, useContext, type ReactNode } from 'react';\nimport { useStore } from 'zustand';\n\nimport { type IoAssistStore, ioAssistStore } from '../stores';\nimport type { IoAssistStaticConfig, IoAssistDynamicConfig } from '../types';\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nexport const IoAssistConfigContext = createContext<IoAssistStaticConfig | null>(null);\nexport const IoAssistDynamicConfigContext = createContext<IoAssistDynamicConfig | null>(null);\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\nexport type IoAssistProviderProps = {\n staticConfig: IoAssistStaticConfig;\n dynamicConfig: IoAssistDynamicConfig;\n children: ReactNode;\n};\n\nexport const IoAssistProvider: React.FC<IoAssistProviderProps> = ({\n staticConfig,\n dynamicConfig,\n children,\n}) => {\n return (\n <IoAssistConfigContext.Provider value={staticConfig}>\n <IoAssistDynamicConfigContext.Provider value={dynamicConfig}>\n {children}\n </IoAssistDynamicConfigContext.Provider>\n </IoAssistConfigContext.Provider>\n );\n};\n\n// ─── Hooks ────────────────────────────────────────────────────────────────────\n\nexport function useIoAssistStore<T>(selector: (store: IoAssistStore) => T): T {\n return useStore(ioAssistStore, selector);\n}\n\nexport function useIoAssistConfig(): IoAssistStaticConfig {\n const config = useContext(IoAssistConfigContext);\n\n if (!config) {\n throw new Error('useIoAssistConfig must be used inside IoAssistProvider');\n }\n\n return config;\n}\n\nexport function useIoAssistDynamicConfig(): IoAssistDynamicConfig {\n const config = useContext(IoAssistDynamicConfigContext);\n\n if (!config) {\n throw new Error('useIoAssistDynamicConfig must be used inside IoAssistProvider');\n }\n\n return config;\n}\n","import type { IOConnectCore } from '@interopio/core';\n\nconst LIB_NAME = 'io-assist';\n\n/**\n * Centralized logging service for the io-assist React clone.\n *\n * Wraps the IO Connect Logger API (`IOConnectCore.Logger.API`) and provides\n * namespaced sub-loggers per subsystem. Before IO Connect is initialized,\n * calls to `get()` fall back to `console`.\n *\n * The handle returned by `get()` is stable — call sites may cache it at\n * module scope and it will transparently switch from the console fallback\n * to the real IO Connect sub-logger once `setLogger()` runs.\n *\n * Initialized automatically by `initIoConnect` when IO Connect becomes ready.\n *\n * @example\n * ```ts\n * import { logger } from '../utils/logger';\n *\n * const LOGGER_NAME = 'Sampling';\n * const log = logger.get(LOGGER_NAME);\n * log.info('Processing message stream');\n * log.warn('Unexpected chunk type');\n * log.error('Stream failed', error);\n * ```\n */\nclass Logger {\n private _logger: IOConnectCore.Logger.API | undefined;\n private readonly _subLoggers = new Map<string, IOConnectCore.Logger.API>();\n\n public setLogger(ioLogger: IOConnectCore.Logger.API): void {\n this._logger = ioLogger;\n this._subLoggers.clear();\n }\n\n public get isInitialized(): boolean {\n return this._logger !== undefined;\n }\n\n public get(subSystem: string): IOConnectCore.Logger.API {\n const fullName = `${LIB_NAME}.${subSystem}`;\n const resolve = (): IOConnectCore.Logger.API => {\n if (!this._logger) {\n return console as unknown as IOConnectCore.Logger.API;\n }\n let cached = this._subLoggers.get(fullName);\n if (!cached) {\n cached = this._logger.subLogger(fullName);\n this._subLoggers.set(fullName, cached);\n }\n return cached;\n };\n\n return new Proxy({} as IOConnectCore.Logger.API, {\n get: (_, prop) => {\n const target = resolve() as unknown as Record<string | symbol, unknown>;\n const value = target[prop];\n return typeof value === 'function'\n ? (value as (...args: unknown[]) => unknown).bind(target)\n : value;\n },\n });\n }\n}\n\nexport const logger = new Logger();\n","import type { IoAssistStoreInstance } from '../stores';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'ToggleFavoritePrompt';\nconst log = logger.get(LOGGER_NAME);\n\n/**\n * Toggle a prompt's favorite status and persist the new list to\n * `io.prefs`. The store mutation is optimistic; if `prefs.update` fails,\n * the previous list is restored.\n */\nexport async function toggleFavoritePrompt(\n store: IoAssistStoreInstance,\n name: string,\n): Promise<void> {\n const before = store.getState().favoritePromptNames;\n store.getState().toggleFavoritePrompt(name);\n const after = store.getState().favoritePromptNames;\n\n const api = store.getState().ioConnectApi;\n if (!api?.prefs) return;\n\n try {\n await api.prefs.update({ favoritePrompts: after });\n } catch (err) {\n log.error(\n 'Failed to persist favorite prompts',\n err instanceof Error ? err : new Error(String(err)),\n );\n store.getState().setFavoritePromptNames(before);\n }\n}\n","import type { IOConnectBrowser } from '@interopio/browser';\nimport { useMemo } from 'react';\n\nimport { toggleFavoritePrompt } from '../actions/toggleFavoritePrompt';\nimport { useIoAssistStore } from '../context/IoAssistContext';\nimport { ioAssistStore } from '../stores';\n\nexport type UseIoConnectApi = {\n api: IOConnectBrowser.API | null;\n isReady: boolean;\n toggleFavoritePrompt: (name: string) => Promise<void>;\n};\n\n/**\n * Accessor hook for the io.Connect SDK instance with persistence-aware\n * orchestrations baked in. Pairs with `useIoConnect()` which boots the\n * SDK once at the app root.\n */\nexport function useIoConnectApi(): UseIoConnectApi {\n const api = useIoAssistStore((s) => s.ioConnectApi);\n\n return useMemo<UseIoConnectApi>(\n () => ({\n api,\n isReady: api !== null,\n toggleFavoritePrompt: (name) => toggleFavoritePrompt(ioAssistStore, name),\n }),\n [api],\n );\n}\n","import React from 'react';\n\ntype IconProps = {\n size?: number;\n className?: string;\n children: React.ReactNode;\n};\n\nexport const Icon: React.FC<IconProps> = ({ size = 16, className, children }) => (\n <span\n className={[\n 'pointer-events-none inline-flex items-center justify-center',\n className ?? '',\n ].join(' ')}\n style={{ width: `${size}px`, height: `${size}px` }}\n >\n {children}\n </span>\n);\n","import React from 'react';\n\n// ─── Navigation & Layout ──────────────────────────────────────────────────────\n\nexport const ThreadHistoryIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill=\"currentColor\"\n d=\"M0 1.64C0 0.73 0.73 0 1.64 0L10.36 0C11.27 0 12 0.73 12 1.64L12 10.36C12 11.27 11.27 12 10.36 12L1.64 12C0.73 12 0 11.27 0 10.36L0 1.64ZM10.36 11.18C10.81 11.18 11.18 10.82 11.18 10.36L11.18 1.64C11.18 1.18 10.82 0.82 10.36 0.82L4.5 0.82L4.5 11.18L10.36 11.18ZM0.82 10.36C0.82 10.82 1.18 11.18 1.64 11.18L3.75 11.18L3.75 0.82L1.64 0.82C1.18 0.82 0.82 1.18 0.82 1.64L0.82 10.36ZM1.5 7.5L3 7.5L3 8.25L1.5 8.25L1.5 7.5ZM3 5.25L3 6L1.5 6L1.5 5.25L3 5.25ZM3 3L3 3.75L1.5 3.75L1.5 3L3 3Z\"\n />\n </svg>\n);\n\nexport const CloseIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const HomeIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 13 13\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill=\"currentColor\"\n d=\"M10.64 1.13C10.36 0.82 9.87 0.82 9.59 1.13L8.95 1.73L10.31 3.09L10.92 2.46C11.23 2.18 11.23 1.69 10.92 1.41L10.64 1.13ZM4.43 6.28C4.31 6.38 4.24 6.52 4.22 6.63L3.87 8.18L5.41 7.83C5.53 7.8 5.67 7.73 5.77 7.62L9.77 3.61L8.44 2.27L4.43 6.28ZM9.05 0.59C9.63 0 10.59 0 11.18 0.59L11.46 0.87C12.05 1.45 12.05 2.41 11.46 3L6.3 8.16C6.09 8.37 5.84 8.51 5.58 8.55L3.45 9.05C3.33 9.07 3.19 9.05 3.09 8.95C3 8.86 2.98 8.72 3 8.6L3.49 6.47C3.56 6.21 3.68 5.95 3.89 5.74L9.05 0.59ZM1.88 1.55H4.88C5.06 1.55 5.25 1.73 5.25 1.92C5.25 2.13 5.06 2.3 4.88 2.3H1.88C1.24 2.3 0.75 2.81 0.75 3.42V10.17C0.75 10.8 1.24 11.3 1.88 11.3H8.63C9.23 11.3 9.75 10.8 9.75 10.17V7.17C9.75 6.98 9.91 6.8 10.13 6.8C10.31 6.8 10.5 6.98 10.5 7.17V10.17C10.5 11.23 9.66 12.05 8.63 12.05H1.88C0.82 12.05 0 11.23 0 10.17V3.42C0 2.39 0.82 1.55 1.88 1.55Z\"\n />\n </svg>\n);\n\nexport const ChevronIcon: React.FC<{ expanded: boolean }> = ({ expanded }) => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={`shrink-0 transition-transform ${expanded ? 'rotate-90' : ''}`}\n aria-hidden\n >\n <path\n d=\"M9 6l6 6-6 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const ChevronRightIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path\n d=\"M9 6l6 6-6 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const ChevronUpIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path\n d=\"M6 15l6-6 6 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const ChevronDownIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden>\n <path\n d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const CircleFilledIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 8 8\" aria-hidden>\n <circle cx=\"4\" cy=\"4\" r=\"3.5\" fill=\"currentColor\" />\n </svg>\n);\n\nexport const CircleOutlineIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 8 8\" aria-hidden>\n <circle cx=\"4\" cy=\"4\" r=\"3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" />\n </svg>\n);\n\n// ─── Actions ──────────────────────────────────────────────────────────────────\n\nexport const CopyIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect\n x=\"9\"\n y=\"9\"\n width=\"13\"\n height=\"13\"\n rx=\"2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const CheckIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M20 6L9 17l-5-5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const ReloadIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M1 4v6h6M23 20v-6h-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M20.49 9A9 9 0 005.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 013.51 15\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const PencilIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const TrashIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <polyline\n points=\"3 6 5 6 21 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 11v6M14 11v6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const SearchIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" {...props}>\n <circle cx=\"11\" cy=\"11\" r=\"8\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"m21 21-4.35-4.35\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const InfoIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"M12 16v-4M12 8h.01\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\n// ─── Input Area ───────────────────────────────────────────────────────────────\n\nexport const ArrowUpIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M11.293 4.293a1 1 0 011.414 0l7 7a1 1 0 01-1.414 1.414L13 7.414V19a1 1 0 11-2 0V7.414l-5.293 5.293a1 1 0 01-1.414-1.414l7-7z\" />\n </svg>\n);\n\nexport const PaperPlaneIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"rotate-45\"\n >\n <path d=\"M21.43 2.57a1.5 1.5 0 00-1.61-.33L2.93 8.83a1.5 1.5 0 00-.12 2.76l6.34 2.85a.5.5 0 00.57-.1l6.7-6.69a.5.5 0 01.71.71l-6.69 6.7a.5.5 0 00-.1.57l2.85 6.34a1.5 1.5 0 002.76-.12l6.59-16.89a1.5 1.5 0 00-.33-1.61z\" />\n </svg>\n);\n\nexport const StopIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n </svg>\n);\n\nexport const PromptIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const ToolIcon = () => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// Bookmark-style icon (matches ng app-icon PROMPT_PANEL variant)\nexport const PromptPanelIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 12 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill=\"currentColor\"\n d=\"M0 1.5C0 0.69 0.66 0 1.5 0H10.5C11.31 0 12 0.69 12 1.5V15.31C12 15.72 11.69 16 11.28 16C11.16 16 11.03 15.97 10.91 15.91L6 12.63L1.06 15.91C0.94 15.97 0.81 16 0.69 16C0.28 16 0 15.72 0 15.31V1.5ZM1.5 1C1.22 1 1 1.25 1 1.5V14.75L5.72 11.59C5.88 11.5 6.09 11.5 6.25 11.59L11 14.75V1.5C11 1.25 10.75 1 10.5 1H1.5Z\"\n />\n </svg>\n);\n\n// Sliders / row-toggles icon (matches ng app-icon TOOL_PANEL variant)\nexport const ToolPanelIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 16 13\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill=\"currentColor\"\n d=\"M1 2H2V1H1V2ZM0 0.75C0 0.34 0.31 0 0.75 0H2.25C2.66 0 3 0.34 3 0.75V2.25C3 2.69 2.66 3 2.25 3H0.75C0.31 3 0 2.69 0 2.25V0.75ZM5 1H15C15.25 1 15.5 1.25 15.5 1.5C15.5 1.78 15.25 2 15 2H5C4.72 2 4.5 1.78 4.5 1.5C4.5 1.25 4.72 1 5 1ZM5 6H15C15.25 6 15.5 6.25 15.5 6.5C15.5 6.78 15.25 7 15 7H5C4.72 7 4.5 6.78 4.5 6.5C4.5 6.25 4.72 6 5 6ZM5 11H15C15.25 11 15.5 11.25 15.5 11.5C15.5 11.78 15.25 12 15 12H5C4.72 12 4.5 11.78 4.5 11.5C4.5 11.25 4.72 11 5 11ZM1 6V7H2V6H1ZM0.75 5H2.25C2.66 5 3 5.34 3 5.75V7.25C3 7.69 2.66 8 2.25 8H0.75C0.31 8 0 7.69 0 7.25V5.75C0 5.34 0.31 5 0.75 5ZM1 12H2V11H1V12ZM0 10.75C0 10.34 0.31 10 0.75 10H2.25C2.66 10 3 10.34 3 10.75V12.25C3 12.69 2.66 13 2.25 13H0.75C0.31 13 0 12.69 0 12.25V10.75Z\"\n />\n </svg>\n);\n\n// ─── Prompts & Favorites ──────────────────────────────────────────────────────\n\nexport const PromptDotIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"1.5\" y=\"2.5\" width=\"13\" height=\"11\" rx=\"1.5\" stroke=\"currentColor\" />\n <path d=\"M4 6h8M4 9h5\" stroke=\"currentColor\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const StarFilledIcon = () => (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 12 12\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M6 0.75l1.6 3.27 3.6.52-2.6 2.55.62 3.59L6 9.4l-3.22 1.7.61-3.59L.79 4.54l3.6-.52L6 .75z\" />\n </svg>\n);\n\nexport const StarIcon: React.FC<{ filled: boolean }> = ({ filled }) => (\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill={filled ? 'currentColor' : 'none'}>\n <polygon\n points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// ─── Spinners & Loading ───────────────────────────────────────────────────────\n\nexport const Spinner: React.FC<{ className?: string }> = ({ className }) => {\n return (\n <svg\n className={['animate-spin text-text-default', className ?? ''].join(' ')}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n};\n\nexport const SpinnerIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" {...props}>\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray=\"31.4\"\n strokeDashoffset=\"10\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\n// ─── Branding ─────────────────────────────────────────────────────────────────\n\nexport const IoAssistLogoDark = () => (\n <svg width=\"68\" height=\"14\" viewBox=\"0 0 68 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.220798 3.28877H1.38651V13.2145H0.220798V3.28877ZM0.255084 1.38592C0.106512 1.22592 0.0322266 1.04306 0.0322266 0.837346C0.0322266 0.631632 0.106512 0.454489 0.255084 0.305918C0.415084 0.145918 0.597941 0.065918 0.803655 0.065918C1.00937 0.065918 1.18651 0.145918 1.33508 0.305918C1.49508 0.454489 1.57508 0.631632 1.57508 0.837346C1.57508 1.04306 1.49508 1.22592 1.33508 1.38592C1.18651 1.53449 1.00937 1.60877 0.803655 1.60877C0.597941 1.60877 0.415084 1.53449 0.255084 1.38592Z\"\n fill=\"white\"\n />\n <path\n d=\"M8.38897 12.3745C9.5204 12.3745 10.4804 11.9745 11.269 11.1745C12.069 10.3631 12.469 9.38592 12.469 8.24306C12.469 7.11163 12.069 6.14592 11.269 5.34592C10.4804 4.53449 9.5204 4.12877 8.38897 4.12877C7.26897 4.12877 6.30897 4.53449 5.50897 5.34592C4.70897 6.14592 4.30897 7.11163 4.30897 8.24306C4.30897 9.38592 4.70897 10.3631 5.50897 11.1745C6.30897 11.9745 7.26897 12.3745 8.38897 12.3745ZM8.38897 13.5059C6.93754 13.5059 5.69182 12.9916 4.65182 11.9631C3.62325 10.9345 3.10897 9.69449 3.10897 8.24306C3.10897 6.79163 3.62325 5.55735 4.65182 4.5402C5.69182 3.51163 6.93754 2.99735 8.38897 2.99735C9.85182 2.99735 11.0975 3.51163 12.1261 4.5402C13.1547 5.55735 13.669 6.79163 13.669 8.24306C13.669 9.69449 13.1547 10.9345 12.1261 11.9631C11.0975 12.9916 9.85182 13.5059 8.38897 13.5059Z\"\n fill=\"white\"\n />\n <path\n d=\"M16.4192 13.4039C16.072 13.4039 15.78 13.2855 15.5433 13.0488C15.3066 12.812 15.1882 12.528 15.1882 12.1965C15.1882 11.8651 15.3066 11.581 15.5433 11.3443C15.78 11.1076 16.072 10.9892 16.4192 10.9892C16.7349 10.9892 17.0111 11.1076 17.2478 11.3443C17.4845 11.581 17.6029 11.8651 17.6029 12.1965C17.6029 12.528 17.4845 12.812 17.2478 13.0488C17.0111 13.2855 16.7349 13.4039 16.4192 13.4039Z\"\n fill=\"#F25F1F\"\n />\n <path\n d=\"M22.7104 9.13449H28.1276L25.4361 2.08877H25.4018L22.7104 9.13449ZM30.9733 13.2145H29.7047L28.5733 10.2831H22.2476L21.1161 13.2145H19.8647L24.8361 0.357346H26.0018L30.9733 13.2145Z\"\n fill=\"white\"\n />\n <path\n d=\"M39.5573 5.84306H38.3744C38.3744 5.35163 38.1459 4.94592 37.6887 4.62592C37.243 4.29449 36.6487 4.12877 35.9059 4.12877C35.1401 4.12877 34.5401 4.26592 34.1059 4.5402C33.6716 4.80306 33.4544 5.15735 33.4544 5.60306C33.4544 6.11735 33.6144 6.51735 33.9344 6.80306C34.2544 7.07735 34.6544 7.24878 35.1344 7.31735C35.6144 7.38592 36.1287 7.47163 36.6773 7.57449C37.2373 7.66592 37.7573 7.7802 38.2373 7.91735C38.7173 8.05449 39.1173 8.3402 39.4373 8.77449C39.7573 9.19735 39.9173 9.76877 39.9173 10.4888C39.9173 11.4373 39.5573 12.1802 38.8373 12.7173C38.1287 13.2431 37.1516 13.5059 35.9059 13.5059C34.7059 13.5059 33.7402 13.2031 33.0087 12.5973C32.2773 11.9802 31.9116 11.1916 31.9116 10.2316H33.0944C33.0944 10.8602 33.3459 11.3745 33.8487 11.7745C34.3516 12.1745 35.0373 12.3745 35.9059 12.3745C36.7973 12.3745 37.4887 12.2088 37.9801 11.8773C38.4716 11.5345 38.7173 11.0545 38.7173 10.4373C38.7173 10.0031 38.5973 9.6602 38.3573 9.40877C38.1173 9.14592 37.8087 8.96306 37.4316 8.8602C37.0544 8.75735 36.6373 8.67735 36.1801 8.6202C35.723 8.56306 35.2602 8.49449 34.7916 8.41449C34.3344 8.32306 33.9173 8.19163 33.5401 8.0202C33.163 7.83735 32.8544 7.55163 32.6144 7.16306C32.3744 6.76306 32.2544 6.25449 32.2544 5.63735C32.2544 4.7802 32.5973 4.12877 33.283 3.68306C33.9802 3.22592 34.8544 2.99735 35.9059 2.99735C36.9916 2.99735 37.8716 3.26592 38.5459 3.80306C39.2201 4.32877 39.5573 5.00877 39.5573 5.84306Z\"\n fill=\"white\"\n />\n <path\n d=\"M48.9323 5.84306H47.7494C47.7494 5.35163 47.5209 4.94592 47.0637 4.62592C46.618 4.29449 46.0237 4.12877 45.2809 4.12877C44.5151 4.12877 43.9151 4.26592 43.4809 4.5402C43.0466 4.80306 42.8294 5.15735 42.8294 5.60306C42.8294 6.11735 42.9894 6.51735 43.3094 6.80306C43.6294 7.07735 44.0294 7.24878 44.5094 7.31735C44.9894 7.38592 45.5037 7.47163 46.0523 7.57449C46.6123 7.66592 47.1323 7.7802 47.6123 7.91735C48.0923 8.05449 48.4923 8.3402 48.8123 8.77449C49.1323 9.19735 49.2923 9.76877 49.2923 10.4888C49.2923 11.4373 48.9323 12.1802 48.2123 12.7173C47.5037 13.2431 46.5266 13.5059 45.2809 13.5059C44.0809 13.5059 43.1151 13.2031 42.3837 12.5973C41.6523 11.9802 41.2866 11.1916 41.2866 10.2316H42.4694C42.4694 10.8602 42.7209 11.3745 43.2237 11.7745C43.7266 12.1745 44.4123 12.3745 45.2809 12.3745C46.1723 12.3745 46.8637 12.2088 47.3551 11.8773C47.8466 11.5345 48.0923 11.0545 48.0923 10.4373C48.0923 10.0031 47.9723 9.6602 47.7323 9.40877C47.4923 9.14592 47.1837 8.96306 46.8066 8.8602C46.4294 8.75735 46.0123 8.67735 45.5551 8.6202C45.098 8.56306 44.6352 8.49449 44.1666 8.41449C43.7094 8.32306 43.2923 8.19163 42.9151 8.0202C42.538 7.83735 42.2294 7.55163 41.9894 7.16306C41.7494 6.76306 41.6294 6.25449 41.6294 5.63735C41.6294 4.7802 41.9723 4.12877 42.658 3.68306C43.3551 3.22592 44.2294 2.99735 45.2809 2.99735C46.3666 2.99735 47.2466 3.26592 47.9209 3.80306C48.5951 4.32877 48.9323 5.00877 48.9323 5.84306Z\"\n fill=\"white\"\n />\n <path\n d=\"M51.0044 3.28877H52.1701V13.2145H51.0044V3.28877ZM51.0387 1.38592C50.8901 1.22592 50.8159 1.04306 50.8159 0.837346C50.8159 0.631632 50.8901 0.454489 51.0387 0.305918C51.1987 0.145918 51.3816 0.065918 51.5873 0.065918C51.793 0.065918 51.9701 0.145918 52.1187 0.305918C52.2787 0.454489 52.3587 0.631632 52.3587 0.837346C52.3587 1.04306 52.2787 1.22592 52.1187 1.38592C51.9701 1.53449 51.793 1.60877 51.5873 1.60877C51.3816 1.60877 51.1987 1.53449 51.0387 1.38592Z\"\n fill=\"white\"\n />\n <path\n d=\"M61.5383 5.84306H60.3555C60.3555 5.35163 60.1269 4.94592 59.6697 4.62592C59.224 4.29449 58.6297 4.12877 57.8869 4.12877C57.1212 4.12877 56.5212 4.26592 56.0869 4.5402C55.6526 4.80306 55.4355 5.15735 55.4355 5.60306C55.4355 6.11735 55.5955 6.51735 55.9155 6.80306C56.2355 7.07735 56.6355 7.24878 57.1155 7.31735C57.5955 7.38592 58.1097 7.47163 58.6583 7.57449C59.2183 7.66592 59.7383 7.7802 60.2183 7.91735C60.6983 8.05449 61.0983 8.3402 61.4183 8.77449C61.7383 9.19735 61.8983 9.76877 61.8983 10.4888C61.8983 11.4373 61.5383 12.1802 60.8183 12.7173C60.1097 13.2431 59.1326 13.5059 57.8869 13.5059C56.6869 13.5059 55.7212 13.2031 54.9897 12.5973C54.2583 11.9802 53.8926 11.1916 53.8926 10.2316H55.0755C55.0755 10.8602 55.3269 11.3745 55.8297 11.7745C56.3326 12.1745 57.0183 12.3745 57.8869 12.3745C58.7783 12.3745 59.4697 12.2088 59.9612 11.8773C60.4526 11.5345 60.6983 11.0545 60.6983 10.4373C60.6983 10.0031 60.5783 9.6602 60.3383 9.40877C60.0983 9.14592 59.7897 8.96306 59.4126 8.8602C59.0355 8.75735 58.6183 8.67735 58.1612 8.6202C57.704 8.56306 57.2412 8.49449 56.7726 8.41449C56.3155 8.32306 55.8983 8.19163 55.5212 8.0202C55.144 7.83735 54.8355 7.55163 54.5955 7.16306C54.3555 6.76306 54.2355 6.25449 54.2355 5.63735C54.2355 4.7802 54.5783 4.12877 55.264 3.68306C55.9612 3.22592 56.8355 2.99735 57.8869 2.99735C58.9726 2.99735 59.8526 3.26592 60.5269 3.80306C61.2012 4.32877 61.5383 5.00877 61.5383 5.84306Z\"\n fill=\"white\"\n />\n <path\n d=\"M65.2562 4.45449V10.8831C65.2562 11.2716 65.3647 11.5631 65.5819 11.7573C65.799 11.9516 66.079 12.0488 66.4219 12.0488H67.3133V13.2145H66.4219C65.759 13.2145 65.2047 13.0031 64.759 12.5802C64.3133 12.1573 64.0905 11.5916 64.0905 10.8831V4.45449H62.9247V3.28877H64.0905V1.04306H65.2562V3.28877H67.3133V4.45449H65.2562Z\"\n fill=\"white\"\n />\n </svg>\n);\n\nexport const IoAssistLogoLight = () => (\n <svg width=\"68\" height=\"14\" viewBox=\"0 0 121 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.336735 5.7551H2.41837V23.4796H0.336735V5.7551ZM0.397959 2.35714C0.132653 2.07143 0 1.7449 0 1.37755C0 1.0102 0.132653 0.693878 0.397959 0.428571C0.683674 0.142857 1.0102 0 1.37755 0C1.7449 0 2.06122 0.142857 2.32653 0.428571C2.61225 0.693878 2.7551 1.0102 2.7551 1.37755C2.7551 1.7449 2.61225 2.07143 2.32653 2.35714C2.06122 2.62245 1.7449 2.7551 1.37755 2.7551C1.0102 2.7551 0.683674 2.62245 0.397959 2.35714Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M14.9228 21.9796C16.9432 21.9796 18.6574 21.2653 20.0656 19.8367C21.4942 18.3878 22.2085 16.6429 22.2085 14.602C22.2085 12.5816 21.4942 10.8571 20.0656 9.42857C18.6574 7.97959 16.9432 7.2551 14.9228 7.2551C12.9228 7.2551 11.2085 7.97959 9.77989 9.42857C8.35132 10.8571 7.63704 12.5816 7.63704 14.602C7.63704 16.6429 8.35132 18.3878 9.77989 19.8367C11.2085 21.2653 12.9228 21.9796 14.9228 21.9796ZM14.9228 24C12.3309 24 10.1064 23.0816 8.24928 21.2449C6.41255 19.4082 5.49418 17.1939 5.49418 14.602C5.49418 12.0102 6.41255 9.80612 8.24928 7.98979C10.1064 6.15306 12.3309 5.23469 14.9228 5.23469C17.535 5.23469 19.7595 6.15306 21.5962 7.98979C23.433 9.80612 24.3513 12.0102 24.3513 14.602C24.3513 17.1939 23.433 19.4082 21.5962 21.2449C19.7595 23.0816 17.535 24 14.9228 24Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M29.2625 23.8178C28.6425 23.8178 28.1211 23.6064 27.6984 23.1837C27.2756 22.7609 27.0643 22.2536 27.0643 21.6618C27.0643 21.07 27.2756 20.5627 27.6984 20.1399C28.1211 19.7172 28.6425 19.5058 29.2625 19.5058C29.8262 19.5058 30.3194 19.7172 30.7421 20.1399C31.1648 20.5627 31.3762 21.07 31.3762 21.6618C31.3762 22.2536 31.1648 22.7609 30.7421 23.1837C30.3194 23.6064 29.8262 23.8178 29.2625 23.8178Z\"\n fill=\"#F25F1F\"\n />\n <path\n d=\"M40.4968 16.1939H50.1702L45.3641 3.61224H45.3029L40.4968 16.1939ZM55.2519 23.4796H52.9866L50.9662 18.2449H39.6702L37.6498 23.4796H35.4151L44.2927 0.520407H46.3743L55.2519 23.4796Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M70.5805 10.3163H68.4682C68.4682 9.43878 68.0601 8.71428 67.2437 8.14286C66.4478 7.55102 65.3866 7.2551 64.0601 7.2551C62.6927 7.2551 61.6213 7.5 60.8458 7.98979C60.0703 8.45918 59.6825 9.09184 59.6825 9.88775C59.6825 10.8061 59.9682 11.5204 60.5397 12.0306C61.1111 12.5204 61.8254 12.8265 62.6825 12.949C63.5397 13.0714 64.458 13.2245 65.4376 13.4082C66.4376 13.5714 67.3662 13.7755 68.2233 14.0204C69.0805 14.2653 69.7948 14.7755 70.3662 15.551C70.9376 16.3061 71.2233 17.3265 71.2233 18.6122C71.2233 20.3061 70.5805 21.6327 69.2948 22.5918C68.0295 23.5306 66.2846 24 64.0601 24C61.9172 24 60.1927 23.4592 58.8866 22.3776C57.5805 21.2755 56.9274 19.8673 56.9274 18.1531H59.0397C59.0397 19.2755 59.4886 20.1939 60.3866 20.9082C61.2846 21.6224 62.509 21.9796 64.0601 21.9796C65.6519 21.9796 66.8866 21.6837 67.7642 21.0918C68.6417 20.4796 69.0805 19.6224 69.0805 18.5204C69.0805 17.7449 68.8662 17.1327 68.4376 16.6837C68.009 16.2143 67.458 15.8878 66.7846 15.7041C66.1111 15.5204 65.3662 15.3776 64.5499 15.2755C63.7335 15.1735 62.907 15.051 62.0703 14.9082C61.254 14.7449 60.5091 14.5102 59.8356 14.2041C59.1621 13.8776 58.6111 13.3673 58.1825 12.6735C57.754 11.9592 57.5397 11.051 57.5397 9.94898C57.5397 8.41837 58.1519 7.2551 59.3764 6.45918C60.6213 5.64286 62.1825 5.23469 64.0601 5.23469C65.9988 5.23469 67.5703 5.71429 68.7744 6.67347C69.9784 7.61224 70.5805 8.82653 70.5805 10.3163Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M87.3216 10.3163H85.2093C85.2093 9.43878 84.8011 8.71428 83.9848 8.14286C83.1889 7.55102 82.1277 7.2551 80.8011 7.2551C79.4338 7.2551 78.3624 7.5 77.5869 7.98979C76.8113 8.45918 76.4236 9.09184 76.4236 9.88775C76.4236 10.8061 76.7093 11.5204 77.2807 12.0306C77.8522 12.5204 78.5664 12.8265 79.4236 12.949C80.2807 13.0714 81.1991 13.2245 82.1787 13.4082C83.1787 13.5714 84.1073 13.7755 84.9644 14.0204C85.8216 14.2653 86.5358 14.7755 87.1073 15.551C87.6787 16.3061 87.9644 17.3265 87.9644 18.6122C87.9644 20.3061 87.3216 21.6327 86.0358 22.5918C84.7705 23.5306 83.0256 24 80.8011 24C78.6583 24 76.9338 23.4592 75.6277 22.3776C74.3215 21.2755 73.6685 19.8673 73.6685 18.1531H75.7807C75.7807 19.2755 76.2297 20.1939 77.1277 20.9082C78.0256 21.6224 79.2501 21.9796 80.8011 21.9796C82.393 21.9796 83.6277 21.6837 84.5052 21.0918C85.3828 20.4796 85.8215 19.6224 85.8215 18.5204C85.8215 17.7449 85.6073 17.1327 85.1787 16.6837C84.7501 16.2143 84.1991 15.8878 83.5256 15.7041C82.8522 15.5204 82.1073 15.3776 81.2909 15.2755C80.4746 15.1735 79.6481 15.051 78.8113 14.9082C77.995 14.7449 77.2501 14.5102 76.5767 14.2041C75.9032 13.8776 75.3522 13.3673 74.9236 12.6735C74.495 11.9592 74.2807 11.051 74.2807 9.94898C74.2807 8.41837 74.893 7.2551 76.1175 6.45918C77.3624 5.64286 78.9236 5.23469 80.8011 5.23469C82.7399 5.23469 84.3113 5.71429 85.5154 6.67347C86.7195 7.61224 87.3216 8.82653 87.3216 10.3163Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M91.0218 5.7551H93.1034V23.4796H91.0218V5.7551ZM91.083 2.35714C90.8177 2.07143 90.6851 1.7449 90.6851 1.37755C90.6851 1.0102 90.8177 0.693878 91.083 0.428571C91.3687 0.142857 91.6953 0 92.0626 0C92.43 0 92.7463 0.142857 93.0116 0.428571C93.2973 0.693878 93.4402 1.0102 93.4402 1.37755C93.4402 1.7449 93.2973 2.07143 93.0116 2.35714C92.7463 2.62245 92.43 2.7551 92.0626 2.7551C91.6953 2.7551 91.3687 2.62245 91.083 2.35714Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M109.832 10.3163H107.72C107.72 9.43878 107.312 8.71428 106.496 8.14286C105.7 7.55102 104.638 7.2551 103.312 7.2551C101.945 7.2551 100.873 7.5 100.098 7.98979C99.3221 8.45918 98.9343 9.09184 98.9343 9.88775C98.9343 10.8061 99.2201 11.5204 99.7915 12.0306C100.363 12.5204 101.077 12.8265 101.934 12.949C102.791 13.0714 103.71 13.2245 104.689 13.4082C105.689 13.5714 106.618 13.7755 107.475 14.0204C108.332 14.2653 109.047 14.7755 109.618 15.551C110.189 16.3061 110.475 17.3265 110.475 18.6122C110.475 20.3061 109.832 21.6327 108.547 22.5918C107.281 23.5306 105.536 24 103.312 24C101.169 24 99.4446 23.4592 98.1384 22.3776C96.8323 21.2755 96.1792 19.8673 96.1792 18.1531H98.2915C98.2915 19.2755 98.7405 20.1939 99.6384 20.9082C100.536 21.6224 101.761 21.9796 103.312 21.9796C104.904 21.9796 106.138 21.6837 107.016 21.0918C107.894 20.4796 108.332 19.6224 108.332 18.5204C108.332 17.7449 108.118 17.1327 107.689 16.6837C107.261 16.2143 106.71 15.8878 106.036 15.7041C105.363 15.5204 104.618 15.3776 103.802 15.2755C102.985 15.1735 102.159 15.051 101.322 14.9082C100.506 14.7449 99.7609 14.5102 99.0874 14.2041C98.4139 13.8776 97.8629 13.3673 97.4343 12.6735C97.0058 11.9592 96.7915 11.051 96.7915 9.94898C96.7915 8.41837 97.4037 7.2551 98.6282 6.45918C99.8731 5.64286 101.434 5.23469 103.312 5.23469C105.251 5.23469 106.822 5.71429 108.026 6.67347C109.23 7.61224 109.832 8.82653 109.832 10.3163Z\"\n fill=\"#26272A\"\n />\n <path\n d=\"M116.471 7.83673V19.3163C116.471 20.0102 116.665 20.5306 117.053 20.8776C117.441 21.2245 117.941 21.398 118.553 21.398H120.145V23.4796H118.553C117.369 23.4796 116.38 23.102 115.584 22.3469C114.788 21.5918 114.39 20.5816 114.39 19.3163V7.83673H112.308V5.7551H114.39V1.7449H116.471V5.7551H120.145V7.83673H116.471Z\"\n fill=\"#26272A\"\n />\n </svg>\n);\n","import React, { useState } from 'react';\n\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { useIoConnectApi } from '../../hooks/useIoConnectApi';\nimport type { Prompt } from '../../types';\nimport { Icon } from '../shared/Icon';\nimport { PromptDotIcon, StarIcon, StarFilledIcon } from '../shared/icons';\n\ntype Props = {\n prompt: Prompt;\n isDisplayedInFavoriteList: boolean;\n};\n\nexport const PromptListItem: React.FC<Props> = ({ prompt, isDisplayedInFavoriteList }) => {\n const [isHovered, setIsHovered] = useState(false);\n const favoritePromptNames = useIoAssistStore((s) => s.favoritePromptNames);\n const setSelectedPrompt = useIoAssistStore((s) => s.setSelectedPrompt);\n const setActivePanelContent = useIoAssistStore((s) => s.setActivePanelContent);\n const { toggleFavoritePrompt } = useIoConnectApi();\n\n const isFavorite = favoritePromptNames.includes(prompt.name);\n\n const handleSelect = () => {\n setSelectedPrompt({ id: prompt.id, name: prompt.name, description: prompt.description });\n if (!isDisplayedInFavoriteList) {\n setActivePanelContent(null);\n }\n };\n\n const handleToggleFavorite = (e: React.MouseEvent) => {\n e.stopPropagation();\n void toggleFavoritePrompt(prompt.name);\n };\n\n const hostClasses = [\n 'flex w-full',\n isDisplayedInFavoriteList\n ? 'md:w-auto md:max-w-[352px] md:min-w-[250px] border border-border-default hover:border-border-hover rounded-2xl bg-app-background-secondary'\n : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const rowClasses = [\n 'flex flex-1 justify-between items-center p-2 gap-2 cursor-pointer min-w-0',\n isDisplayedInFavoriteList\n ? 'h-[48px] rounded-2xl'\n : ['rounded-md', isHovered ? 'bg-app-background-secondary' : '']\n .filter(Boolean)\n .join(' '),\n ].join(' ');\n\n return (\n <div\n data-testid=\"prompt-list-item\"\n data-prompt-name={prompt.name}\n className={hostClasses}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n role=\"button\"\n tabIndex={0}\n className={rowClasses}\n onClick={handleSelect}\n onKeyUp={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleSelect();\n }}\n title={prompt.description || undefined}\n >\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-full text-text-default\">\n <Icon size={16}>\n <PromptDotIcon />\n </Icon>\n </span>\n\n <span\n className={[\n 'flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap text-xs',\n isHovered ? 'text-text-states-hover' : 'text-text-default',\n ].join(' ')}\n >\n {prompt.name}\n </span>\n\n <button\n type=\"button\"\n data-testid=\"prompt-favorite-toggle\"\n aria-pressed={isFavorite}\n aria-label={isFavorite ? 'Remove from favorites' : 'Add to favorites'}\n title={isFavorite ? 'Remove from favorites' : 'Add to favorites'}\n className={[\n 'p-2 ps-1 shrink-0 inline-flex items-center justify-center cursor-pointer bg-transparent border-0',\n isFavorite\n ? 'text-yellow-400'\n : isHovered\n ? 'text-text-default hover:text-yellow-400'\n : 'text-text-states-disabled',\n ].join(' ')}\n onClick={handleToggleFavorite}\n >\n <Icon size={12}>\n {isFavorite ? <StarFilledIcon /> : <StarIcon filled={false} />}\n </Icon>\n </button>\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\n\nimport { Icon } from './Icon';\nimport { SearchIcon, CloseIcon } from './icons';\n\ntype Props = {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n};\n\n// Sticky search input — visual parity with ng app-input (search variant): a\n// bordered cell with leading search icon, trailing clear-X (only when filled),\n// and hover / focus-within state swaps on bg + border.\nexport const SearchInput: React.FC<Props> = ({ value, onChange, placeholder }) => {\n const [isActive, setIsActive] = useState(false);\n const hasValue = value.length > 0;\n\n return (\n <div className=\"sticky top-0 z-10 bg-panel-background pb-1\">\n <div\n className={[\n 'flex flex-col items-start justify-center w-full p-2 mb-1 rounded-input-radius border',\n 'bg-input-background border-input-border',\n !isActive && 'hover:bg-input-background-hover hover:border-input-border-hover',\n isActive && 'bg-input-background-active border-input-border-active',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <div className=\"flex gap-2 items-center w-full\">\n <span\n className={[\n 'inline-flex items-center justify-center',\n isActive ? 'text-input-icon-active' : 'text-input-icon',\n ].join(' ')}\n >\n <Icon size={12}>\n <SearchIcon />\n </Icon>\n </span>\n\n <input\n type=\"text\"\n aria-label={placeholder}\n className={[\n 'flex-1 min-w-0 bg-transparent border-0 outline-none text-xs',\n isActive ? 'text-input-text-active' : 'text-input-text',\n ].join(' ')}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n onFocus={() => setIsActive(true)}\n onBlur={() => setIsActive(false)}\n />\n\n {hasValue && (\n <button\n type=\"button\"\n className={[\n 'inline-flex items-center justify-center cursor-pointer',\n isActive ? 'text-input-icon-active' : 'text-input-icon',\n ].join(' ')}\n onClick={() => onChange('')}\n aria-label=\"Clear search\"\n >\n <Icon size={12}>\n <CloseIcon />\n </Icon>\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useMemo, useState } from 'react';\n\nimport { PromptListItem } from './PromptListItem';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport type { Prompt } from '../../types';\nimport { SearchInput } from '../shared/SearchInput';\n\nconst DOCS_URL = 'https://docs-ai.interop.io/';\nconst UNCATEGORIZED_CATEGORY_NAME = 'Default Prompts';\n\ntype PromptGroup = {\n category: string;\n prompts: Prompt[];\n};\n\ntype Props = {\n className?: string;\n};\n\nconst sortPromptsAlphabetically = (prompts: Prompt[]): Prompt[] =>\n [...prompts].sort((a, b) => a.name.localeCompare(b.name));\n\nexport const PromptListPanel: React.FC<Props> = ({ className }) => {\n const allPrompts = useIoAssistStore((s) => s.allPrompts);\n\n const [search, setSearch] = useState('');\n\n const hasAnyPrompts = allPrompts.length > 0;\n\n const filteredPrompts = useMemo<Prompt[]>(() => {\n const lower = search.trim().toLowerCase();\n if (!lower) return allPrompts;\n return allPrompts.filter((p) => p.name.toLowerCase().includes(lower));\n }, [allPrompts, search]);\n\n const promptGroups = useMemo<PromptGroup[]>(() => {\n const categoryMap = new Map<string, Prompt[]>();\n for (const prompt of filteredPrompts) {\n const category = prompt.category || UNCATEGORIZED_CATEGORY_NAME;\n const existing = categoryMap.get(category) || [];\n categoryMap.set(category, [...existing, prompt]);\n }\n\n const groups: PromptGroup[] = Array.from(categoryMap.entries()).map(\n ([category, prompts]) => ({\n category,\n prompts: sortPromptsAlphabetically(prompts),\n }),\n );\n\n return groups.sort((a, b) => {\n if (a.category === UNCATEGORIZED_CATEGORY_NAME) return 1;\n if (b.category === UNCATEGORIZED_CATEGORY_NAME) return -1;\n return a.category.localeCompare(b.category);\n });\n }, [filteredPrompts]);\n\n const noFilteredPrompts = filteredPrompts.length === 0;\n\n const onDocsLinkClick = (): void => {\n window.open(DOCS_URL, '_blank', 'noopener,noreferrer');\n };\n\n return (\n <div\n data-testid=\"prompt-list\"\n className={['flex flex-col w-full', className ?? ''].filter(Boolean).join(' ')}\n >\n {hasAnyPrompts && (\n <SearchInput\n value={search}\n onChange={setSearch}\n placeholder={UI_STRINGS.PROMPT_LIST_COMPONENT.INPUT_TOOLTIP}\n />\n )}\n\n <div className=\"flex flex-col w-full gap-[10px] py-2 min-h-0\">\n {!hasAnyPrompts && (\n <div className=\"flex justify-center items-center h-16\">\n <div className=\"flex flex-col items-center gap-2 text-center px-4\">\n <span className=\"text-text-default\">\n {UI_STRINGS.PROMPT_LIST_COMPONENT.NO_PROMPTS_CONFIGURED}\n </span>\n <button\n type=\"button\"\n className=\"text-xs text-blue-500 hover:text-blue-600 underline cursor-pointer\"\n onClick={onDocsLinkClick}\n >\n {UI_STRINGS.PROMPT_LIST_COMPONENT.NO_PROMPTS_SEE_MORE}\n </button>\n </div>\n </div>\n )}\n\n {hasAnyPrompts && noFilteredPrompts && (\n <div className=\"flex justify-center items-center h-16\">\n <span className=\"text-text-default\">\n {UI_STRINGS.PROMPT_LIST_COMPONENT.NO_PROMPTS}\n </span>\n </div>\n )}\n\n {!noFilteredPrompts && (\n <div className=\"w-full min-h-0 flex flex-col gap-3 overflow-y-auto overflow-x-hidden custom-scrollbar\">\n {promptGroups.map((group) => (\n <React.Fragment key={group.category}>\n <div className=\"flex items-center px-2 py-1 mb-1\">\n <span\n data-testid=\"prompt-category\"\n className=\"text-[10px] font-normal text-text-default leading-[13px] tracking-[0.1px]\"\n >\n {group.category}\n </span>\n </div>\n {group.prompts.map((prompt) => (\n <PromptListItem\n key={prompt.name}\n prompt={prompt}\n isDisplayedInFavoriteList={false}\n />\n ))}\n </React.Fragment>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nimport { Icon } from './Icon';\n\ntype IconButtonVariant = 'default' | 'danger';\n\ntype IconButtonProps = {\n size?: number;\n containerSize?: number;\n testId?: string;\n variant?: IconButtonVariant;\n children: React.ReactNode;\n} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'>;\n\nconst ICON_BUTTON_HOVER_BY_VARIANT: Record<IconButtonVariant, string> = {\n default: 'hover:text-text-states-hover',\n danger: 'hover:text-app-danger',\n};\n\nexport const IconButton: React.FC<IconButtonProps> = ({\n size = 16,\n containerSize,\n className,\n testId,\n style,\n type = 'button',\n variant = 'default',\n children,\n ...rest\n}) => (\n <button\n type={type}\n data-testid={testId}\n className={[\n 'flex items-center justify-center cursor-pointer transition-colors rounded-full text-text-default disabled:opacity-50 disabled:cursor-not-allowed',\n ICON_BUTTON_HOVER_BY_VARIANT[variant],\n className ?? '',\n ].join(' ')}\n style={{\n ...(containerSize\n ? { width: `${containerSize}px`, height: `${containerSize}px` }\n : null),\n ...style,\n }}\n {...rest}\n >\n <Icon size={size}>{children}</Icon>\n </button>\n);\n","import React, { useEffect } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { IconButton } from './IconButton';\nimport { CloseIcon } from './icons';\n\ntype ModalProps = {\n open: boolean;\n onClose?: () => void;\n title?: string;\n showCloseIcon?: boolean;\n footer?: React.ReactNode;\n testId?: string;\n children: React.ReactNode;\n};\n\nexport const Modal: React.FC<ModalProps> = ({\n open,\n onClose,\n title,\n showCloseIcon = false,\n footer,\n testId = 'modal',\n children,\n}) => {\n useEffect(() => {\n if (!open || !onClose) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [open, onClose]);\n\n if (!open) return null;\n if (typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n data-testid={testId}\n role=\"presentation\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/[0.32]\"\n onClick={(e) => {\n if (e.target === e.currentTarget) onClose?.();\n }}\n onKeyDown={(e) => e.key === 'Escape' && onClose?.()}\n >\n <dialog\n aria-modal=\"true\"\n aria-label={title}\n open\n className=\"static flex flex-col box-border overflow-hidden bg-panel-background rounded-2xl border border-panel-border shadow-panel-box-shadow w-auto min-w-[320px] md:min-w-[540px] max-w-[960px] max-h-[90vh] p-0 m-0\"\n >\n <div className=\"flex justify-end items-center gap-2 px-6 pt-6 text-text-black-white text-xl font-weight-600 shrink-0\">\n {title && (\n <span className=\"flex flex-1 items-center text-text-black-white leading-[24px] truncate\">\n {title}\n </span>\n )}\n {showCloseIcon && onClose && (\n <IconButton\n size={20}\n containerSize={28}\n onClick={onClose}\n title=\"Close\"\n className=\"rounded-lg text-text-black-white hover:bg-app-icon-background-hover\"\n >\n <CloseIcon />\n </IconButton>\n )}\n </div>\n\n <div className=\"flex-1 min-h-0 overflow-y-auto overflow-x-hidden custom-scrollbar mt-3\">\n {children}\n </div>\n\n {footer && (\n <div className=\"flex justify-end gap-2 shrink-0 w-full px-6 pb-6 pt-3\">\n {footer}\n </div>\n )}\n </dialog>\n </div>,\n document.body,\n );\n};\n","import React from 'react';\n\nimport { Icon } from './Icon';\nimport { CheckIcon, CloseIcon } from './icons';\n\ntype Props = {\n isChecked: boolean;\n onToggle: () => void;\n isDisabled?: boolean;\n};\n\n// Matches ng app-toggle: 34x16 track with sliding 12x12 circle and a check/close\n// icon in the opposite half.\nexport const ToggleInput: React.FC<Props> = ({ isChecked, onToggle, isDisabled = false }) => {\n const toggleSwitch = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!isDisabled) onToggle();\n };\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isDisabled) return;\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n onToggle();\n }\n };\n\n return (\n <div\n role=\"switch\"\n aria-checked={isChecked}\n aria-disabled={isDisabled}\n tabIndex={isDisabled ? -1 : 0}\n onClick={toggleSwitch}\n onKeyDown={handleKeyDown}\n className={[\n 'relative inline-flex items-center w-[34px] h-[16px] rounded-full transition-colors duration-300 ease-in-out',\n isDisabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n !isChecked && !isDisabled ? 'hover:bg-toggle-background-hover-disabled' : '',\n isChecked && !isDisabled ? 'hover:bg-toggle-background-hover-enabled' : '',\n isChecked ? 'bg-toggle-background-enabled' : 'bg-toggle-background-disabled',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <div\n className={[\n 'flex flex-1 transition-all duration-300',\n isChecked ? 'justify-start' : 'justify-end',\n ].join(' ')}\n >\n <span className=\"m-[4px] inline-flex items-center justify-center text-text-states-active\">\n <Icon size={10}>{isChecked ? <CheckIcon /> : <CloseIcon />}</Icon>\n </span>\n </div>\n\n <div\n className={[\n 'absolute w-[12px] h-[12px] bg-toggle-circle rounded-full transition-all duration-300 ease-in-out',\n isChecked ? 'left-[20px]' : 'left-[2px]',\n ].join(' ')}\n />\n </div>\n );\n};\n","import React, { useState, useRef, useLayoutEffect, useEffect, useCallback } from 'react';\n\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';\n\ntype Props = {\n content: React.ReactNode;\n position?: TooltipPosition;\n offset?: number;\n children: React.ReactNode;\n};\n\nconst VIEWPORT_PADDING = 8;\n\n// Reusable hover/focus tooltip — mirrors ng AppTooltipComponent. The bubble\n// mounts invisible, we measure + clamp to the viewport, then fade it in once\n// positioned. Capture-phase scroll + resize listeners keep it stuck to the\n// trigger while open (improves on ng, which only listened to window:scroll).\nexport const Tooltip: React.FC<Props> = ({ content, position = 'top', offset = 14, children }) => {\n const triggerRef = useRef<HTMLSpanElement>(null);\n const bubbleRef = useRef<HTMLDivElement>(null);\n const [visible, setVisible] = useState(false);\n const [isPositioned, setIsPositioned] = useState(false);\n const [coords, setCoords] = useState({ x: 0, y: 0 });\n\n const updatePosition = useCallback(() => {\n const triggerEl = triggerRef.current;\n const bubbleEl = bubbleRef.current;\n if (!triggerEl || !bubbleEl) return;\n\n const t = triggerEl.getBoundingClientRect();\n const b = bubbleEl.getBoundingClientRect();\n\n let x = 0;\n let y = 0;\n\n if (position === 'top') {\n x = t.left + t.width / 2 - b.width / 2;\n y = t.top - b.height - offset;\n x = Math.max(\n VIEWPORT_PADDING,\n Math.min(x, window.innerWidth - b.width - VIEWPORT_PADDING),\n );\n } else if (position === 'bottom') {\n x = t.left + t.width / 2 - b.width / 2;\n y = t.bottom + offset;\n x = Math.max(\n VIEWPORT_PADDING,\n Math.min(x, window.innerWidth - b.width - VIEWPORT_PADDING),\n );\n } else if (position === 'left') {\n x = t.left - b.width - offset;\n y = t.top + t.height / 2 - b.height / 2;\n y = Math.max(\n VIEWPORT_PADDING,\n Math.min(y, window.innerHeight - b.height - VIEWPORT_PADDING),\n );\n } else if (position === 'right') {\n x = t.right + offset;\n y = t.top + t.height / 2 - b.height / 2;\n y = Math.max(\n VIEWPORT_PADDING,\n Math.min(y, window.innerHeight - b.height - VIEWPORT_PADDING),\n );\n }\n\n setCoords({ x, y });\n }, [position, offset]);\n\n useLayoutEffect(() => {\n if (!visible) return;\n updatePosition();\n setIsPositioned(true);\n }, [visible, updatePosition]);\n\n useEffect(() => {\n if (!visible) return;\n const onChange = () => updatePosition();\n window.addEventListener('scroll', onChange, true);\n window.addEventListener('resize', onChange);\n return () => {\n window.removeEventListener('scroll', onChange, true);\n window.removeEventListener('resize', onChange);\n };\n }, [visible, updatePosition]);\n\n const show = () => {\n setIsPositioned(false);\n setVisible(true);\n };\n const hide = () => {\n setVisible(false);\n setIsPositioned(false);\n };\n\n return (\n <span\n ref={triggerRef}\n className=\"inline-block\"\n onMouseEnter={show}\n onMouseLeave={hide}\n onFocus={show}\n onBlur={hide}\n >\n {children}\n {visible && (\n <div\n ref={bubbleRef}\n className={[\n 'fixed z-[999999] pointer-events-none transition-opacity duration-150',\n isPositioned ? 'opacity-100' : 'opacity-0',\n ].join(' ')}\n style={{ left: `${coords.x}px`, top: `${coords.y}px` }}\n >\n {content}\n </div>\n )}\n </span>\n );\n};\n","import React, { useState } from 'react';\n\nimport type { UITool } from '../../types';\nimport { Icon } from '../shared/Icon';\nimport { InfoIcon } from '../shared/icons';\nimport { ToggleInput } from '../shared/ToggleInput';\nimport { Tooltip } from '../shared/Tooltip';\n\ntype Props = {\n tool: UITool;\n onToggle: (tool: UITool) => void;\n};\n\nexport const ToolListItem: React.FC<Props> = ({ tool, onToggle }) => {\n const [isHovered, setIsHovered] = useState(false);\n\n return (\n <div\n data-testid=\"tool-list-item\"\n data-tool-name={tool.name}\n className={[\n 'flex justify-between items-center px-2 py-1 gap-2 cursor-pointer rounded-md w-full',\n isHovered ? 'bg-app-background-secondary' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <ToggleInput isChecked={tool.enabled} onToggle={() => onToggle(tool)} />\n\n <span\n className={[\n 'flex flex-1 text-xs',\n isHovered ? 'text-text-states-hover' : 'text-text-default',\n ].join(' ')}\n >\n {tool.name}\n </span>\n\n <Tooltip\n content={\n <div className=\"flex justify-center bg-app-background-secondary text-text-default border border-border-default p-4 rounded-md leading-[17px] text-xs min-w-[240px] max-w-[320px]\">\n <div>\n <span className=\"text-text-states-active font-weight-600\">\n Server name:{' '}\n </span>\n {tool.mcpServerName}\n </div>\n </div>\n }\n >\n <span\n className={[\n 'inline-flex items-center justify-center rounded-sm hover:bg-app-icon-background-hover',\n isHovered ? 'text-text-states-active' : 'text-text-default',\n ].join(' ')}\n aria-label=\"Tool info\"\n >\n <Icon size={12}>\n <InfoIcon />\n </Icon>\n </span>\n </Tooltip>\n </div>\n );\n};\n","import type { IoAssistStoreInstance } from '../stores';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'AbortActiveStream';\nconst log = logger.get(LOGGER_NAME);\n\nexport function abortActiveStream(store: IoAssistStoreInstance): void {\n const state = store.getState();\n const selectedAgent = state.selectedAgent;\n const threadId = state.activeThreadId;\n\n if (!selectedAgent || !threadId) return;\n\n try {\n selectedAgent.rawAgent.abortOperation(threadId);\n } catch (error) {\n log.warn(\n `Failed to abort operation for thread ${threadId}: ${\n (error as Error)?.message ?? error\n }`,\n );\n }\n\n const after = store.getState();\n after.abortStream(threadId);\n after.untrackStream(threadId);\n after.setIsGeneratingResponse(false);\n}\n","import type { IoAssistStoreInstance } from '../stores';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'NewConversation';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function newConversation(store: IoAssistStoreInstance): Promise<void> {\n const state = store.getState();\n state.clearMessages();\n state.setActiveThreadId(null);\n state.resetMcpApps();\n\n const api = state.ioAiWebApi;\n if (!api?.mcpApps) return;\n\n try {\n await api.mcpApps.closeAll();\n } catch (err) {\n log.error(\n 'Failed to close MCP apps on new conversation',\n err instanceof Error ? err : new Error(String(err)),\n );\n }\n}\n","import type { IoAssistStoreInstance } from '../stores';\nimport { newConversation } from './newConversation';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'DeleteThread';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function deleteThread(store: IoAssistStoreInstance, threadId: string): Promise<void> {\n const state = store.getState();\n const thread = state.threads.find((t) => t.id === threadId);\n if (!thread) return;\n const wasActive = state.activeThreadId === threadId;\n\n try {\n await thread.delete();\n } catch {\n log.error(`Failed to delete thread on server: ${threadId}`);\n return;\n }\n\n const next = store.getState();\n next.removeThread(threadId);\n next.untrackStream(threadId);\n\n if (wasActive) {\n await newConversation(store);\n }\n}\n","import type { IoAssistStoreInstance } from '../stores';\n\nexport async function renameThread(\n store: IoAssistStoreInstance,\n threadId: string,\n title: string,\n): Promise<void> {\n const trimmed = title.trim();\n if (!trimmed) return;\n\n const state = store.getState();\n const thread = state.threads.find((t) => t.id === threadId);\n if (!thread) return;\n\n const previousTitle = thread.title;\n state.updateThread(threadId, { title: trimmed });\n\n try {\n await thread.update({ title: trimmed });\n } catch {\n store.getState().updateThread(threadId, { title: previousTitle });\n }\n}\n","export function safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n","import {\n type UIMessage,\n type UIToolMessage,\n UI_MESSAGE_ROLES,\n type UIUserMessage,\n type UIAssistantMessage,\n} from '../types';\nimport { logger } from './logger';\nimport { safeStringify } from './safeStringify';\n\nconst LOGGER_NAME = 'MessageConverter';\nconst log = logger.get(LOGGER_NAME);\n\n// The raw thread-message payload from `IoAiWeb.Threads.GetMessagesResponse.messages`\n// is `any[]` in the upstream d.ts — we narrow via these shape descriptors\n// rather than `any`.\ntype RawTextPart = { type: 'text'; text?: string };\ntype RawToolInvocationPart = {\n type: 'tool-invocation';\n id?: string;\n toolInvocation?: {\n toolCallId?: string;\n toolName?: string;\n args?: Record<string, unknown>;\n result?: UIToolMessage['result'];\n };\n};\ntype RawMessagePart = RawTextPart | RawToolInvocationPart;\n\ntype RawMessageContent =\n | string\n | { text?: string; parts?: RawMessagePart[] }\n | { text?: string }[]\n | null\n | undefined;\n\ntype RawThreadMessage = {\n id: string;\n role: 'user' | 'assistant' | string;\n content?: RawMessageContent;\n};\n\nexport function convertThreadMessages(rawMessages: unknown[]): UIMessage[] {\n const result: UIMessage[] = [];\n const toolCallMap = new Map<string, UIToolMessage>();\n\n for (const raw of rawMessages) {\n const msg = raw as RawThreadMessage;\n if (msg.role === 'user') {\n const content = extractTextContent(msg.content);\n result.push({ id: msg.id, role: UI_MESSAGE_ROLES.USER, content } as UIUserMessage);\n }\n\n if (msg.role === 'assistant') {\n const contentObj =\n msg.content && typeof msg.content === 'object' && !Array.isArray(msg.content)\n ? msg.content\n : null;\n const parts: RawMessagePart[] = contentObj?.parts ?? [];\n\n if (parts.length === 0) {\n const content = extractTextContent(msg.content);\n if (content.trim()) {\n result.push({\n id: msg.id,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content,\n } as UIAssistantMessage);\n }\n continue;\n }\n\n for (let partIndex = 0; partIndex < parts.length; partIndex++) {\n const part = parts[partIndex];\n if (part.type === 'text' && part.text?.trim()) {\n result.push({\n id: `${msg.id}_text_${partIndex}`,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: part.text,\n } as UIAssistantMessage);\n }\n\n if (part.type === 'tool-invocation') {\n const inv = part.toolInvocation;\n const toolCallId = inv?.toolCallId ?? part.id;\n if (!toolCallId) continue;\n\n if (toolCallMap.has(toolCallId)) {\n const existing = toolCallMap.get(toolCallId)!;\n if (inv?.result !== undefined) existing.result = inv.result;\n } else {\n const toolMsg: UIToolMessage = {\n id: toolCallId,\n role: UI_MESSAGE_ROLES.TOOL,\n toolName: inv?.toolName ?? 'unknown',\n args: inv?.args ?? {},\n result: inv?.result,\n };\n toolCallMap.set(toolCallId, toolMsg);\n result.push(toolMsg);\n }\n }\n }\n }\n }\n\n log.debug(`Converted messages: ${safeStringify(result)}`);\n return result;\n}\n\nexport function extractTextContent(content: unknown): string {\n if (content == null) return '';\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content.map((c) => (c as { text?: string })?.text ?? '').join('');\n }\n if (typeof content === 'object') {\n const obj = content as { parts?: unknown; text?: unknown };\n if (Array.isArray(obj.parts)) {\n return (obj.parts as RawMessagePart[])\n .filter((p): p is RawTextPart => p.type === 'text')\n .map((p) => p.text ?? '')\n .join('');\n }\n if (typeof obj.text === 'string') return obj.text;\n }\n return JSON.stringify(content);\n}\n","import { UI_STRINGS } from '../constants/uiStrings';\nimport type { UIMessage, UIThread, ToolTraceState } from '../types';\nimport { UI_MESSAGE_ROLES } from '../types';\nimport { logger } from './logger';\nimport { safeStringify } from './safeStringify';\n\nconst LOGGER_NAME = 'ThreadUtils';\nconst log = logger.get(LOGGER_NAME);\n\nexport type ThreadGroup = {\n label: string;\n threads: UIThread[];\n};\n\nconst DIV = UI_STRINGS.THREAD_HISTORY_COMPONENT.DIVIDERS;\n\nconst MS = {\n minute: 60 * 1000,\n hour: 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n week: 7 * 24 * 60 * 60 * 1000,\n month: 30 * 24 * 60 * 60 * 1000,\n};\n\nfunction getBucketLabel(diff: number): string {\n if (diff < MS.minute) return DIV.JUST_NOW;\n if (diff < 5 * MS.minute) return DIV.FIVE_MINS_AGO;\n if (diff < 30 * MS.minute) return DIV.THIRTY_MINS_AGO;\n if (diff < MS.hour) return DIV.ONE_HOUR_AGO;\n if (diff < 2 * MS.hour) return DIV.TWO_HOURS_AGO;\n if (diff < 6 * MS.hour) return DIV.SIX_HOURS_AGO;\n if (diff < 12 * MS.hour) return DIV.TWELVE_HOURS_AGO;\n if (diff < MS.day) return DIV.TODAY;\n if (diff < 2 * MS.day) return DIV.YESTERDAY;\n if (diff < 3 * MS.day) return DIV.TWO_DAYS_AGO;\n if (diff < MS.week) return DIV.LAST_WEEK;\n if (diff < 2 * MS.week) return DIV.TWO_WEEKS_AGO;\n if (diff < MS.month) return DIV.ONE_MONTH_AGO;\n if (diff < 3 * MS.month) return DIV.THREE_MONTHS_AGO;\n if (diff < 6 * MS.month) return DIV.SIX_MONTHS_AGO;\n return DIV.MORE_THAN_YEAR_AGO;\n}\n\n/**\n * Groups threads into time buckets for display in the thread history sidebar.\n * Threads are sorted newest-first within each group.\n */\nexport function groupThreadsByTime(threads: UIThread[]): ThreadGroup[] {\n const now = Date.now();\n const groups = new Map<string, UIThread[]>();\n const labelOrder: string[] = [];\n\n const sorted = [...threads].sort(\n (a, b) => (b.updatedAt ?? b.createdAt).getTime() - (a.updatedAt ?? a.createdAt).getTime(),\n );\n\n for (const thread of sorted) {\n const date = thread.updatedAt ?? thread.createdAt;\n const diff = now - date.getTime();\n const label = getBucketLabel(diff);\n\n if (!groups.has(label)) {\n groups.set(label, []);\n labelOrder.push(label);\n }\n\n groups.get(label)!.push(thread);\n }\n\n return labelOrder.map((label) => ({\n label,\n threads: groups.get(label)!,\n }));\n}\n\n/**\n * Builds ToolTraceState[] from a flat UIMessage[] (e.g. loaded from thread history).\n * Groups tool messages under the preceding user/assistant message ID.\n */\nexport function buildToolTraceFromMessages(messages: UIMessage[]): ToolTraceState[] {\n const traces: ToolTraceState[] = [];\n let currentParentId: string | null = null;\n let currentTrace: ToolTraceState | null = null;\n\n for (const msg of messages) {\n if (msg.role === UI_MESSAGE_ROLES.USER || msg.role === UI_MESSAGE_ROLES.ASSISTANT) {\n if (currentTrace) {\n traces.push(currentTrace);\n currentTrace = null;\n }\n currentParentId = msg.id;\n }\n if (msg.role === UI_MESSAGE_ROLES.TOOL && currentParentId) {\n if (!currentTrace) {\n currentTrace = {\n stateForMessageId: currentParentId,\n executedTools: [],\n uiMessage: '',\n isExpanded: false,\n };\n }\n currentTrace.executedTools.push(msg);\n }\n }\n if (currentTrace) traces.push(currentTrace);\n\n for (const trace of traces) {\n const n = trace.executedTools.length;\n trace.uiMessage = n > 0 ? `Used ${n} tool${n !== 1 ? 's' : ''}` : '';\n }\n\n log.debug(`Built tool traces: ${safeStringify(traces)}`);\n return traces;\n}\n\nexport function generateThreadTitle(firstUserMessage: string): string {\n const trimmed = firstUserMessage.trim();\n if (trimmed.length <= 50) return trimmed;\n return trimmed.substring(0, 47) + '...';\n}\n","import type { IoAssistStoreInstance } from '../stores';\nimport { MESSAGES_LOADING_STATE, RESPONSE_STREAM_STATUS, UI_MESSAGE_ROLES } from '../types';\nimport type { UIMessage, UIToolMessage } from '../types';\nimport { logger } from '../utils/logger';\nimport { convertThreadMessages } from '../utils/messageConverter';\nimport { buildToolTraceFromMessages } from '../utils/threadUtils';\n\nconst LOGGER_NAME = 'SelectThread';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function selectThread(store: IoAssistStoreInstance, threadId: string): Promise<void> {\n const state = store.getState();\n const thread = state.threads.find((t) => t.id === threadId);\n\n state.clearCompletionNotification(threadId);\n\n if (state.activeThreadId && state.activeThreadId !== threadId) {\n state.untrackStream(state.activeThreadId);\n }\n\n state.setActiveThreadId(threadId);\n state.clearMessages();\n state.resetMcpApps();\n state.setIsThreadHistoryVisible(false);\n\n if (!thread) return;\n\n state.setMessageLoadingState({ type: MESSAGES_LOADING_STATE.LOADING_FROM_THREAD });\n try {\n const response = await thread.getMessages({ limit: 100 });\n // `IoAiWeb.Threads.GetMessagesResponse.messages` is itself `any[]` upstream — the\n // shape isn't typed on the d.ts. Treat as `unknown[]` at this boundary and let\n // `convertThreadMessages` narrow via type-guards.\n const rawMessages: unknown[] = Array.isArray(response)\n ? response\n : (response?.messages ?? []);\n\n const messages: UIMessage[] = convertThreadMessages(rawMessages);\n const toolTraces = buildToolTraceFromMessages(messages);\n store.getState().setMessages(messages);\n store.getState().setToolTraceState(toolTraces);\n\n // Restore MCP app instances for the thread — mirrors ng's\n // createMcpAppsOnThreadFetch$ effect. Without this, reopening a\n // thread leaves the workspace windows empty because the SDK\n // doesn't reattach app instances on its own.\n const mcpApps = store.getState().ioAiWebApi?.mcpApps;\n if (mcpApps) {\n const apps = messages\n .filter((m): m is UIToolMessage => m.role === UI_MESSAGE_ROLES.TOOL)\n .map((m) => ({\n toolCallId: m.id,\n toolName: m.toolName,\n toolInput: m.args,\n toolResult: m.result,\n }));\n const restoreApps =\n apps.length > 0 ? mcpApps.recreate({ threadId, apps }) : mcpApps.closeAll();\n Promise.resolve(restoreApps).catch((err: unknown) =>\n log.error('Failed to restore MCP apps on thread reopen', err as Error),\n );\n }\n\n const threadStream = store.getState().streamsByThreadId[threadId];\n if (threadStream?.status === RESPONSE_STREAM_STATUS.STREAMING) {\n store.getState().mergeAccumulatedStreamContent(threadId);\n }\n\n store.getState().setMessageLoadingState({\n type: MESSAGES_LOADING_STATE.FETCH_MESSAGES_FROM_THREAD_SUCCESS,\n });\n } catch (error) {\n store.getState().setMessageLoadingState({\n type: MESSAGES_LOADING_STATE.ERROR,\n message: error instanceof Error ? error.message : 'Failed to load messages',\n });\n }\n}\n","import { UI_MESSAGE_ROLES } from '../types';\nimport type { UIMessage, UIToolMessage, ToolTraceState } from '../types';\n\n/**\n * Slice of the message store that `ensureAssistantMessage` reads/writes.\n * Typed as a structural subset so the helper isn't coupled to the full store.\n */\ntype EnsureAssistantStateSlice = {\n messages: UIMessage[];\n addMessage: (message: UIMessage) => void;\n};\n\n/**\n * Processes AG-UI stream events from agent.stream() and updates the Zustand store.\n * Handles both active thread streaming (writes to messageStore) and background\n * thread streaming (buffers into responseStreamStore for later merge).\n */\nfunction traceLabelFor(count: number): string {\n return count > 0 ? `Used ${count} tool${count !== 1 ? 's' : ''}` : '';\n}\n\nexport function withTraceLabel(traces: ToolTraceState[], messageId: string): ToolTraceState[] {\n return traces.map((t) =>\n t.stateForMessageId === messageId\n ? { ...t, uiMessage: traceLabelFor(t.executedTools.length) }\n : t,\n );\n}\n\nexport function withAllTraceLabelsFinalized(traces: ToolTraceState[]): ToolTraceState[] {\n return traces.map((t) => ({\n ...t,\n uiMessage: traceLabelFor(t.executedTools.length),\n }));\n}\n\nexport function withExecutedToolUpdated(\n traces: ToolTraceState[],\n toolCallId: string,\n changes: Partial<UIToolMessage>,\n): ToolTraceState[] {\n return traces.map((t) => ({\n ...t,\n executedTools: t.executedTools.map((tool) =>\n tool.id === toolCallId ? { ...tool, ...changes } : tool,\n ),\n }));\n}\n\nexport function withToolAppendedToTrace(\n traces: ToolTraceState[],\n parentMessageId: string,\n toolMessage: UIToolMessage,\n): ToolTraceState[] {\n const existing = traces.find(\n (t) =>\n t.stateForMessageId === parentMessageId ||\n t.executedTools.some((et) => et.id === toolMessage.id),\n );\n\n if (!existing) {\n return [\n ...traces,\n {\n stateForMessageId: parentMessageId,\n executedTools: [toolMessage],\n uiMessage: 'Executing tools...',\n isExpanded: false,\n },\n ];\n }\n\n return traces.map((t) =>\n t.stateForMessageId === existing.stateForMessageId\n ? { ...t, executedTools: [...t.executedTools, toolMessage] }\n : t,\n );\n}\n\n// Returns the message id we should write to. If no assistant message exists\n// yet for `currentMessageId`, creates one (using `incomingId` if provided)\n// and returns the new id.\nexport function ensureAssistantMessage(\n state: EnsureAssistantStateSlice,\n currentMessageId: string,\n incomingId?: string,\n): string {\n const exists =\n currentMessageId && state.messages.some((m: UIMessage) => m.id === currentMessageId);\n if (exists) return currentMessageId;\n\n const id = currentMessageId || incomingId || crypto.randomUUID();\n state.addMessage({\n id,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: '',\n });\n return id;\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport type { IoAssistStoreInstance } from '../stores';\nimport { UI_MESSAGE_ROLES, MESSAGES_LOADING_STATE, TOOL_RESULT_TYPES } from '../types';\nimport type { UIMessage, UIToolMessage } from '../types';\nimport { logger } from '../utils/logger';\nimport { safeStringify } from '../utils/safeStringify';\nimport {\n ensureAssistantMessage,\n withTraceLabel,\n withAllTraceLabelsFinalized,\n withExecutedToolUpdated,\n withToolAppendedToTrace,\n} from '../utils/streamUtils';\n\nconst LOGGER_NAME = 'ResponseStream';\nconst log = logger.get(LOGGER_NAME);\n\ntype ToolCallState = {\n args: string;\n toolName?: string;\n};\n\n/**\n * AG-UI event with the optional payload fields we read off it. The upstream\n * `IoAiWeb.Agents.StreamEvent` has a `[key: string]: unknown` index signature\n * — this narrows the per-case payload fields without resorting to `any`. The\n * `type` discriminant is widened to include extension events some backends\n * emit (`TEXT_MESSAGE_CHUNK`, `MESSAGES_SNAPSHOT`) that aren't yet listed in\n * `IoAiWeb.Agents.StreamEventType`.\n */\ntype AgUiEventType = IoAiWeb.Agents.StreamEventType | 'TEXT_MESSAGE_CHUNK' | 'MESSAGES_SNAPSHOT';\n\ntype AgUiEvent = Omit<IoAiWeb.Agents.StreamEvent, 'type'> & {\n type: AgUiEventType;\n messageId?: string;\n delta?: string;\n content?: string | { text?: string } | unknown;\n toolCallId?: string;\n toolCallName?: string;\n messages?: unknown[];\n};\n\nexport async function processResponseStream(\n runHandle: IoAiWeb.Agents.StreamResponse,\n threadId: string,\n store: IoAssistStoreInstance,\n isActiveThread: () => boolean,\n): Promise<void> {\n if (!runHandle || typeof runHandle.subscribe !== 'function') {\n throw new Error('Invalid response stream object');\n }\n\n const toolCallArgsMap = new Map<string, ToolCallState>();\n let streamedContent = '';\n let currentMessageId = '';\n // Tracks whether currentMessageId was created as a synthetic placeholder\n // for a tool call that fired before any TEXT_MESSAGE_START.\n let hasSyntheticPlaceholder = false;\n\n return new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line prefer-const\n let subscription: { unsubscribe?: () => void } | undefined;\n const safeUnsubscribe = () => subscription?.unsubscribe?.();\n subscription = runHandle.subscribe({\n next: (rawEvent: IoAiWeb.Agents.StreamEvent) => {\n const event: AgUiEvent = rawEvent;\n const state = store.getState();\n const isBackground = !isActiveThread();\n\n // Debug: log every AG-UI event so multi-turn / sampling-continuation\n // flows are diagnosable from the browser console.\n log.debug(`AG-UI event ${event?.type ?? 'unknown'}: ${safeStringify(event)}`);\n\n switch (event.type) {\n case 'TEXT_MESSAGE_START': {\n const incomingId: string | undefined = event.messageId;\n\n // Reuse the synthetic placeholder only when this TEXT_MESSAGE_START\n // belongs to the SAME turn that created it. A new turn (after a\n // sampling/tool-result continuation) arrives with a different\n // messageId — in that case we must create a fresh assistant\n // message so its text isn't appended to the prior turn's bubble.\n const sameTurnAsPlaceholder =\n hasSyntheticPlaceholder &&\n (!incomingId || incomingId === currentMessageId);\n\n if (sameTurnAsPlaceholder) {\n streamedContent = '';\n hasSyntheticPlaceholder = false;\n } else {\n currentMessageId = incomingId || crypto.randomUUID();\n streamedContent = '';\n hasSyntheticPlaceholder = false;\n\n if (!isBackground) {\n state.addMessage({\n id: currentMessageId,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: '',\n });\n }\n }\n break;\n }\n\n case 'TEXT_MESSAGE_CONTENT': {\n streamedContent += event.delta || '';\n\n if (isBackground) {\n state.setStreamState(threadId, {\n content: streamedContent,\n messageId: currentMessageId,\n });\n return;\n }\n\n // Defensive: some backends emit TEXT_MESSAGE_CONTENT without a\n // preceding TEXT_MESSAGE_START (e.g. on turn-2 continuation\n // after a sampling result). Create an assistant message on the\n // fly so the streamed text actually renders.\n const ensuredId = ensureAssistantMessage(\n state,\n currentMessageId,\n event.messageId,\n );\n if (ensuredId !== currentMessageId) {\n currentMessageId = ensuredId;\n }\n\n state.updateMessage(currentMessageId, { content: streamedContent });\n break;\n }\n\n case 'TEXT_MESSAGE_END':\n // Treat end-of-text as a turn boundary so any TOOL_CALL_START\n // that follows in the SAME turn doesn't reuse this message id\n // for a synthetic placeholder check on a later turn.\n hasSyntheticPlaceholder = false;\n break;\n\n case 'TEXT_MESSAGE_CHUNK': {\n // Combined start+content+end shorthand some backends emit.\n const chunkId: string | undefined = event.messageId;\n if (chunkId && chunkId !== currentMessageId) {\n currentMessageId = chunkId;\n streamedContent = '';\n hasSyntheticPlaceholder = false;\n if (!isBackground) {\n state.addMessage({\n id: currentMessageId,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: '',\n });\n }\n }\n const chunkText =\n event.delta ?? (typeof event.content === 'string' ? event.content : '');\n streamedContent += chunkText || '';\n if (isBackground) {\n state.setStreamState(threadId, {\n content: streamedContent,\n messageId: currentMessageId,\n });\n } else {\n const ensuredId = ensureAssistantMessage(\n state,\n currentMessageId,\n chunkId,\n );\n if (ensuredId !== currentMessageId) currentMessageId = ensuredId;\n state.updateMessage(currentMessageId, { content: streamedContent });\n }\n break;\n }\n\n case 'MESSAGES_SNAPSHOT': {\n // Reconciliation event some backends emit at the end of a turn.\n // If the snapshot contains an assistant message with content that\n // hasn't been streamed (e.g. turn-2 after sampling), surface it.\n if (isBackground) break;\n const snapshotMessages: unknown[] = Array.isArray(event.messages)\n ? (event.messages as unknown[])\n : [];\n for (const raw of snapshotMessages) {\n const m = raw as {\n id?: string;\n role?: string;\n content?: string | { text?: string };\n };\n if (m?.role !== 'assistant') continue;\n const text =\n typeof m.content === 'string' ? m.content : (m.content?.text ?? '');\n if (!text) continue;\n const messageId = m.id ?? crypto.randomUUID();\n const existing = state.messages.find(\n (x: UIMessage) => x.id === messageId,\n );\n if (existing) {\n if (!existing.content || existing.content.length < text.length) {\n state.updateMessage(messageId, { content: text });\n }\n } else {\n state.addMessage({\n id: messageId,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: text,\n });\n }\n }\n break;\n }\n\n case 'TOOL_CALL_START': {\n streamedContent = '';\n\n // If no assistant message has started yet, create a synthetic\n // placeholder so the trace has a real message ID to anchor to.\n if (!currentMessageId) {\n currentMessageId = crypto.randomUUID();\n hasSyntheticPlaceholder = true;\n if (!isBackground) {\n state.addMessage({\n id: currentMessageId,\n role: UI_MESSAGE_ROLES.ASSISTANT,\n content: '',\n });\n }\n }\n\n const toolMessage: UIToolMessage = {\n id: event.toolCallId || crypto.randomUUID(),\n toolName: event.toolCallName || 'unknown',\n args: {},\n role: UI_MESSAGE_ROLES.TOOL,\n };\n\n toolCallArgsMap.set(toolMessage.id, {\n args: '',\n toolName: toolMessage.toolName,\n });\n\n if (isBackground) {\n const currentStream = state.streamsByThreadId[threadId];\n state.setStreamState(threadId, {\n toolMessages: [...(currentStream?.toolMessages ?? []), toolMessage],\n });\n return;\n }\n\n state.addMessage(toolMessage);\n\n state.setToolTraceState(\n withToolAppendedToTrace(\n state.toolTraceState,\n currentMessageId,\n toolMessage,\n ),\n );\n break;\n }\n\n case 'TOOL_CALL_ARGS': {\n const toolCallId = event.toolCallId || '';\n if (!toolCallId) return;\n\n const current = toolCallArgsMap.get(toolCallId) || { args: '' };\n toolCallArgsMap.set(toolCallId, {\n ...current,\n args: current.args + (event.delta || ''),\n });\n break;\n }\n\n case 'TOOL_CALL_END': {\n const toolCallId = event.toolCallId || '';\n if (!toolCallId) return;\n\n const toolCallState = toolCallArgsMap.get(toolCallId);\n let parsedArgs: Record<string, unknown> = {};\n\n try {\n parsedArgs = JSON.parse(toolCallState?.args || '{}');\n } catch {\n parsedArgs = {};\n }\n\n if (isBackground) {\n const currentStream = state.streamsByThreadId[threadId];\n state.setStreamState(threadId, {\n toolMessages: (currentStream?.toolMessages ?? []).map((tm) =>\n tm.id === toolCallId ? { ...tm, args: parsedArgs } : tm,\n ),\n });\n } else {\n state.updateMessage(toolCallId, { args: parsedArgs });\n\n // Chain pure helpers over the same starting array, then commit once.\n let nextTraces = withExecutedToolUpdated(\n state.toolTraceState,\n toolCallId,\n { args: parsedArgs },\n );\n nextTraces = withTraceLabel(nextTraces, currentMessageId);\n state.setToolTraceState(nextTraces);\n }\n break;\n }\n\n case 'TOOL_CALL_RESULT': {\n const resultToolCallId = event.toolCallId || '';\n if (!resultToolCallId) return;\n\n // AG-UI carries the tool result on `event.content` (string or object),\n // NOT `event.result`. When it's a string, try to JSON.parse it; on\n // parse failure, wrap as a TEXT ToolResult to match ng's behaviour.\n let result: unknown = event.content;\n if (typeof result === 'string') {\n try {\n result = JSON.parse(result);\n } catch {\n result = { type: TOOL_RESULT_TYPES.TEXT, text: result };\n }\n }\n\n if (isBackground) {\n const currentStream = state.streamsByThreadId[threadId];\n state.setStreamState(threadId, {\n toolMessages: (currentStream?.toolMessages ?? []).map((tm) =>\n tm.id === resultToolCallId\n ? { ...tm, result: result as UIToolMessage['result'] }\n : tm,\n ),\n });\n } else {\n state.updateMessage(resultToolCallId, {\n result,\n } as Partial<UIToolMessage>);\n\n let nextTraces = withExecutedToolUpdated(\n state.toolTraceState,\n resultToolCallId,\n { result } as Partial<UIToolMessage>,\n );\n nextTraces = withTraceLabel(nextTraces, currentMessageId);\n state.setToolTraceState(nextTraces);\n }\n break;\n }\n }\n },\n error: (error: Error) => {\n const storeState = store.getState();\n storeState.failStream(\n threadId,\n error.message || 'Error during response generation',\n );\n storeState.setIsGeneratingResponse(false);\n storeState.setIsLastResponseSuccess(false);\n storeState.setMessageLoadingState({\n type: MESSAGES_LOADING_STATE.ERROR,\n message: error.message || 'Error during response generation',\n });\n safeUnsubscribe();\n reject(error);\n },\n complete: () => {\n const finalState = store.getState();\n\n // Finalize all trace labels for this assistant turn\n if (isActiveThread()) {\n finalState.setToolTraceState(\n withAllTraceLabelsFinalized(finalState.toolTraceState),\n );\n }\n\n const shouldNotify = !isActiveThread();\n finalState.completeStream(threadId, shouldNotify);\n\n finalState.setIsGeneratingResponse(false);\n finalState.setIsLastResponseSuccess(true);\n finalState.setMessageLoadingState({\n type: MESSAGES_LOADING_STATE.GET_RESPONSE_SUCCESS,\n });\n safeUnsubscribe();\n resolve();\n },\n });\n });\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport type { IoAssistStoreInstance } from '../stores';\nimport { UI_MESSAGE_ROLES, MESSAGES_LOADING_STATE } from '../types';\nimport type { IoAssistDynamicConfig, UIThread, UIUserMessage } from '../types';\nimport { processResponseStream } from './processResponseStream';\nimport { logger } from '../utils/logger';\nimport { safeStringify } from '../utils/safeStringify';\n\nconst LOGGER_NAME = 'SendUserMessage';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function sendUserMessage(store: IoAssistStoreInstance, text: string, dynamicConfig: IoAssistDynamicConfig): Promise<void> {\n log.debug(`sendUserMessage called with text: ${text}`);\n const state = store.getState();\n const selectedAgent = state.selectedAgent;\n const ioIntelWeb = state.ioAiWebApi;\n\n if (!selectedAgent || !ioIntelWeb) {\n throw new Error('Agent or IoAiWeb API not ready');\n }\n\n let threadId = state.activeThreadId;\n if (!threadId) {\n threadId = crypto.randomUUID();\n state.setActiveThreadId(threadId);\n }\n\n const userId = dynamicConfig.user.id;\n const userMessage: UIUserMessage = {\n id: crypto.randomUUID(),\n role: UI_MESSAGE_ROLES.USER,\n content: text,\n };\n\n state.addMessage(userMessage);\n // One-shot imperative snap: pin the just-sent message to the top of the\n // visible chat. Done here so it fires for both InputArea-driven sends and\n // any other call site of sendUserMessage (e.g. MCP-app message forwarding).\n state.requestScrollAnchor();\n state.setIsGeneratingResponse(true);\n state.setIsLastResponseSuccess(false);\n state.setMessageLoadingState({ type: MESSAGES_LOADING_STATE.LOADING_RESPONSE });\n\n // Send only the new user message — the server reconstructs conversation\n // history from thread memory. Sending all UI messages caused duplicates\n // because the server was writing them again on top of what it already had.\n // Mirrors Angular's input-area-send-button which passes only [userMessage].\n const streamParams = {\n messages: [{ id: userMessage.id, role: userMessage.role, content: userMessage.content ?? '' }],\n memory: { thread: threadId, resource: userId },\n resourceId: userId,\n tools: { autoIncludeEnabled: true },\n };\n\n try {\n log.debug(`Initiating agent stream with params: ${safeStringify(streamParams)}`);\n const runHandle = await selectedAgent.rawAgent.stream(streamParams);\n\n // Store userMessage in stream state before streaming begins\n // (mirrors Angular's _dispatchStreamForThread)\n store.getState().startStream(threadId, userMessage);\n\n await processResponseStream(runHandle, threadId, store, () => store.getState().activeThreadId === threadId);\n\n await refreshThreads(ioIntelWeb, selectedAgent.rawAgent.id, userId, store);\n } catch (error) {\n state.setIsGeneratingResponse(false);\n state.setIsLastResponseSuccess(false);\n state.setMessageLoadingState({\n type: MESSAGES_LOADING_STATE.ERROR,\n message: error instanceof Error ? error.message : 'Error during response generation',\n });\n log.error('Send message failed', error instanceof Error ? error : new Error(String(error)));\n }\n}\n\nasync function refreshThreads(ioIntelWeb: IoAiWeb.API, agentId: string, userId: string, store: IoAssistStoreInstance): Promise<void> {\n try {\n const rawThreads = await ioIntelWeb.threads.list({ agentId, resourceId: userId });\n\n const threads: UIThread[] = rawThreads.map((t) => ({\n id: t.id,\n title: t.title || t.id.substring(0, 8),\n createdAt: t.createdAt ? new Date(t.createdAt) : new Date(),\n updatedAt: t.updatedAt ? new Date(t.updatedAt) : undefined,\n rawThread: t,\n update: (params: { title: string }) => t.update(params),\n delete: () => t.delete(),\n getMessages: (params: { limit: number }) => t.getMessages(params),\n }));\n\n store.getState().setThreads(threads);\n } catch {\n // Non-critical – silently ignore\n }\n}\n","import type { IoAssistStoreInstance } from '../stores';\nimport { TOOL_STATES } from '../types';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'ToggleTool';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function toggleTool(\n store: IoAssistStoreInstance,\n name: string,\n enabled: boolean,\n): Promise<void> {\n const state = store.getState();\n const api = state.ioAiWebApi;\n if (!api?.tools) return;\n\n state.updateToolState(name, TOOL_STATES.ENABLING_DISABLING);\n try {\n const updated = await api.tools.toggleTool(name, enabled);\n store.getState().updateToolEnabled(name, updated?.enabled ?? enabled);\n } catch (err) {\n log.error('toggleTool error', err instanceof Error ? err : new Error(String(err)));\n } finally {\n store.getState().updateToolState(name, TOOL_STATES.IDLE);\n }\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\nimport { useMemo } from 'react';\n\nimport { abortActiveStream } from '../actions/abortActiveStream';\nimport { deleteThread } from '../actions/deleteThread';\nimport { newConversation } from '../actions/newConversation';\nimport { renameThread } from '../actions/renameThread';\nimport { selectThread } from '../actions/selectThread';\nimport { sendUserMessage } from '../actions/sendUserMessage';\nimport { toggleTool } from '../actions/toggleTool';\nimport { useIoAssistStore, useIoAssistDynamicConfig } from '../context/IoAssistContext';\nimport { ioAssistStore } from '../stores';\n\nexport type UseIoAiWebApi = {\n api: IoAiWeb.API | null;\n isReady: boolean;\n sendMessage: (text: string) => Promise<void>;\n abortMessage: () => void;\n newConversation: () => Promise<void>;\n selectThread: (threadId: string) => Promise<void>;\n renameThread: (threadId: string, title: string) => Promise<void>;\n deleteThread: (threadId: string) => Promise<void>;\n toggleTool: (name: string, enabled: boolean) => Promise<void>;\n};\n\n/**\n * Accessor hook for the IoAiWeb SDK instance with the most-used\n * orchestrations baked in. Pairs with `useIoAiWebBootstrap()` which\n * boots the SDK once at the app root.\n *\n */\nexport function useIoAiWebApi(): UseIoAiWebApi {\n const api = useIoAssistStore((s) => s.ioAiWebApi);\n const dynamicConfig = useIoAssistDynamicConfig();\n\n return useMemo<UseIoAiWebApi>(\n () => ({\n api,\n isReady: api !== null,\n sendMessage: (text) => sendUserMessage(ioAssistStore, text, dynamicConfig),\n abortMessage: () => abortActiveStream(ioAssistStore),\n newConversation: () => newConversation(ioAssistStore),\n selectThread: (id) => selectThread(ioAssistStore, id),\n renameThread: (id, title) => renameThread(ioAssistStore, id, title),\n deleteThread: (id) => deleteThread(ioAssistStore, id),\n toggleTool: (name, enabled) => toggleTool(ioAssistStore, name, enabled),\n }),\n [api, dynamicConfig],\n );\n}\n","import React, { useState, useMemo } from 'react';\n\nimport { ToolListItem } from './ToolListItem';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { useIoAiWebApi } from '../../hooks/useIoAiWebApi';\nimport { LOADING_STATES } from '../../types/loading';\nimport { TOOL_STATES, type UITool } from '../../types/tool';\nimport { SearchInput } from '../shared/SearchInput';\n\nconst DOCS_URL = 'https://docs-ai.interop.io/';\n\nexport const ToolListPanel: React.FC = () => {\n const tools = useIoAssistStore((s) => s.tools);\n const toolLoadingState = useIoAssistStore((s) => s.toolLoadingState);\n const { toggleTool } = useIoAiWebApi();\n\n const [search, setSearch] = useState('');\n\n const isLoading = toolLoadingState.type === LOADING_STATES.LOADING;\n const hasTools = tools.length > 0;\n\n const filteredTools = useMemo(() => {\n if (!search) return tools;\n const lower = search.toLowerCase();\n return tools.filter((t) => t.name.toLowerCase().includes(lower));\n }, [tools, search]);\n\n const hasFilteredTools = !isLoading && filteredTools.length > 0;\n\n const handleToggle = (tool: UITool) => {\n if (tool.state !== TOOL_STATES.IDLE) return;\n void toggleTool(tool.name, !tool.enabled);\n };\n\n const onDocsLinkClick = (): void => {\n window.open(DOCS_URL, '_blank', 'noopener,noreferrer');\n };\n\n return (\n <div data-testid=\"tool-list\" className=\"flex flex-col\">\n {!isLoading && hasTools && (\n <SearchInput\n value={search}\n onChange={setSearch}\n placeholder={UI_STRINGS.TOOL_LIST_COMPONENT.INPUT_TOOLTIP}\n />\n )}\n\n <div className=\"flex flex-col items-center pt-2\">\n {isLoading && (\n <span className=\"text-text-default\">\n {UI_STRINGS.TOOL_LIST_COMPONENT.LOADING_TOOLS}\n </span>\n )}\n\n {hasFilteredTools &&\n filteredTools.map((tool) => (\n <ToolListItem key={tool.name} tool={tool} onToggle={handleToggle} />\n ))}\n\n {hasTools && !hasFilteredTools && !isLoading && (\n <span className=\"text-text-default\">\n {UI_STRINGS.TOOL_LIST_COMPONENT.NO_FILTERED_TOOLS}\n </span>\n )}\n\n {!hasTools && !isLoading && (\n <div className=\"flex flex-col items-center gap-2 text-center px-4\">\n <span className=\"text-text-default\">\n {UI_STRINGS.TOOL_LIST_COMPONENT.NO_TOOLS}\n </span>\n <button\n type=\"button\"\n className=\"text-xs text-blue-500 hover:text-blue-600 underline cursor-pointer\"\n onClick={onDocsLinkClick}\n >\n {UI_STRINGS.TOOL_LIST_COMPONENT.NO_TOOLS_SEE_MORE}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import type { PrismTheme } from 'prism-react-renderer';\n\nexport const prismTwilight: PrismTheme = {\n plain: {\n color: '#ffffff',\n backgroundColor: 'hsl(0, 0%, 8%)',\n },\n styles: [\n {\n types: ['comment', 'prolog', 'doctype', 'cdata'],\n style: { color: 'hsl(0, 0%, 47%)' },\n },\n {\n types: ['punctuation', 'namespace'],\n style: { opacity: 0.7 },\n },\n {\n types: ['tag', 'boolean', 'number', 'deleted'],\n style: { color: 'hsl(14, 58%, 55%)' },\n },\n {\n types: ['keyword', 'property', 'selector', 'constant', 'symbol', 'builtin'],\n style: { color: 'hsl(53, 89%, 79%)' },\n },\n {\n types: [\n 'attr-name',\n 'attr-value',\n 'string',\n 'char',\n 'operator',\n 'entity',\n 'url',\n 'variable',\n 'inserted',\n ],\n style: { color: 'hsl(76, 21%, 52%)' },\n },\n {\n types: ['atrule'],\n style: { color: 'hsl(218, 22%, 55%)' },\n },\n {\n types: ['regex', 'important'],\n style: { color: 'hsl(42, 75%, 65%)' },\n },\n {\n types: ['important', 'bold'],\n style: { fontWeight: 'bold' },\n },\n {\n types: ['italic'],\n style: { fontStyle: 'italic' },\n },\n ],\n};\n","import { Highlight } from 'prism-react-renderer';\nimport React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport type { Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { prismTwilight } from './prismTwilightTheme';\n\ntype MdFormatterProps = {\n content: string;\n};\n\nconst CodeBlock: React.FC<{ className?: string; children?: React.ReactNode }> = ({\n className,\n children,\n}) => {\n const code = String(children).replace(/\\n$/, '');\n const rawLanguage = className?.replace(/^language-/, '') ?? '';\n\n return (\n <div className=\"io-assist-code-theme my-2\">\n <Highlight code={code} language={rawLanguage} theme={prismTwilight}>\n {({ className: prismClassName, style, tokens, getLineProps, getTokenProps }) => (\n <pre\n className={`p-3 m-0 rounded-2xl overflow-x-auto ${prismClassName} `}\n style={style}\n >\n <code\n className={`block whitespace-pre-wrap break-words max-w-full box-border text-sm leading-normal`}\n >\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </code>\n </pre>\n )}\n </Highlight>\n </div>\n );\n};\n\nconst components: Components = {\n code({ className, children, ...props }) {\n const isInline = !className && typeof children === 'string' && !children.includes('\\n');\n if (isInline) {\n return (\n <code\n className=\"bg-app-background-secondary px-1.5 py-0.5 rounded text-sm font-mono text-text-states-active\"\n {...props}\n >\n {children}\n </code>\n );\n }\n return <CodeBlock className={className}>{children}</CodeBlock>;\n },\n pre({ children }) {\n return <>{children}</>;\n },\n a({ href, title, children }) {\n return (\n <a\n href={href}\n title={title ?? ''}\n className=\"text-app-accent-color-1\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </a>\n );\n },\n table({ children }) {\n return (\n <div className=\"relative z-1 my-2 p-0\">\n <div className=\"absolute z-0 top-[-2px] left-[-2px] size-[calc(100%+4px)] bg-[linear-gradient(90deg,var(--app-accent-color-1),var(--app-accent-color-2))]\" />\n <table className=\"relative z-1 w-full border-collapse\">{children}</table>\n </div>\n );\n },\n thead({ children }) {\n return (\n <thead className=\"relative z-1 text-left font-semibold text-text-states-active bg-app-background-secondary\">\n {children}\n </thead>\n );\n },\n th({ children }) {\n return <th className=\"px-4 py-3\">{children}</th>;\n },\n td({ children }) {\n return <td className=\"px-4 py-3 text-text-default\">{children}</td>;\n },\n tr({ children, ...props }) {\n return (\n <tr className=\"even:bg-app-background-secondary odd:bg-app-background\" {...props}>\n {children}\n </tr>\n );\n },\n ul({ children }) {\n return (\n <ul className=\"list-disc pl-5 my-2 text-sm font-normal leading-[19px] text-text-default\">\n {children}\n </ul>\n );\n },\n ol({ children }) {\n return (\n <ol className=\"list-decimal pl-5 my-2 text-sm font-normal leading-[19px] text-text-default\">\n {children}\n </ol>\n );\n },\n li({ children }) {\n return <li className=\"py-1\">{children}</li>;\n },\n blockquote({ children }) {\n return (\n <blockquote className=\"p-4 my-4 rounded-2xl text-text-default flex flex-col gap-1 relative border border-app-accent-color-1\">\n {children}\n </blockquote>\n );\n },\n hr() {\n return (\n <div className=\"relative z-1 my-2 py-2\">\n <div className=\"absolute p-0 z-0 top-0 left-0 w-full h-px bg-[linear-gradient(90deg,var(--app-accent-color-1),var(--app-accent-color-2))]\" />\n </div>\n );\n },\n p({ children }) {\n return (\n <p className=\"text-base font-normal leading-[19px] my-2 first:mt-0 last:mb-0\">\n {children}\n </p>\n );\n },\n strong({ children }) {\n return <strong className=\"font-semibold\">{children}</strong>;\n },\n h1({ children }) {\n return <h1 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h1>;\n },\n h2({ children }) {\n return <h2 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h2>;\n },\n h3({ children }) {\n return <h3 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h3>;\n },\n h4({ children }) {\n return <h4 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h4>;\n },\n h5({ children }) {\n return <h5 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h5>;\n },\n h6({ children }) {\n return <h6 className=\"font-default text-[revert] font-[revert] my-[revert]\">{children}</h6>;\n },\n};\n\nexport const MdFormatter: React.FC<MdFormatterProps> = ({ content }) => {\n return (\n <div className=\"io-assist-md w-full max-w-full box-border flex flex-col px-0.5\">\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>\n {content}\n </ReactMarkdown>\n </div>\n );\n};\n","export const textToJSONMarkdown = (content: unknown): string => {\n return '```json\\n' + JSON.stringify(content, null, 2) + '\\n```';\n};\n","import React from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { MdFormatter } from '../messages/MdFormatter';\nimport { textToJSONMarkdown } from '../messages/mdUtils';\nimport { Icon } from '../shared/Icon';\nimport { InfoIcon } from '../shared/icons';\n\nexport const WorkingContextPanel: React.FC = () => {\n const workingContext = useIoAssistStore((s) => s.workingContext);\n\n return (\n <div\n data-testid=\"working-context-panel\"\n className=\"working-context-panel flex flex-1 flex-col p-4 gap-4\"\n >\n <div className=\"flex items-center gap-2 mb-4 p-4 bg-app-background-secondary border border-border-default rounded\">\n <Icon size={20} className=\"text-app-accent-color-1 shrink-0\">\n <InfoIcon />\n </Icon>\n <p className=\"text-sm text-proto-text-default\">\n {UI_STRINGS.WORKING_CONTEXT_PANEL.DESCRIPTION}\n </p>\n </div>\n\n <MdFormatter content={textToJSONMarkdown(workingContext ?? {})} />\n </div>\n );\n};\n","import React from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { PANEL_CONTENT } from '../../types/panel';\nimport { PromptListPanel } from '../prompt/PromptListPanel';\nimport { Modal } from '../shared/Modal';\nimport { ToolListPanel } from '../tool/ToolListPanel';\nimport { WorkingContextPanel } from '../working-context-panel/WorkingContextPanel';\n\n/**\n * Renders the currently-active panel (working-context / prompts / tools) inside\n * a centered modal. Mirrors the io-assist-ng OverlayService + AppPanel pattern.\n */\nexport const ActivePanelModal: React.FC = () => {\n const activePanelContent = useIoAssistStore((s) => s.activePanelContent);\n const setActivePanelContent = useIoAssistStore((s) => s.setActivePanelContent);\n\n if (!activePanelContent) return null;\n\n const title =\n activePanelContent === PANEL_CONTENT.WORKING_CONTEXT\n ? UI_STRINGS.WORKING_CONTEXT_PANEL.TITLE\n : activePanelContent === PANEL_CONTENT.PROMPTS\n ? UI_STRINGS.PROMPT_LIST_COMPONENT.AVAILABLE_PROMPTS\n : UI_STRINGS.TOOL_LIST_COMPONENT.AVAILABLE_TOOLS;\n\n const close = () => setActivePanelContent(null);\n\n return (\n <Modal open onClose={close} title={title} showCloseIcon testId=\"active-panel-modal\">\n <div className=\"px-3 pb-6\">\n {activePanelContent === PANEL_CONTENT.WORKING_CONTEXT && <WorkingContextPanel />}\n {activePanelContent === PANEL_CONTENT.PROMPTS && <PromptListPanel />}\n {activePanelContent === PANEL_CONTENT.TOOLS && <ToolListPanel />}\n </div>\n </Modal>\n );\n};\n","import React from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\n\ntype Props = {\n showMessageArea: boolean;\n};\n\nexport const AiDisclaimer: React.FC<Props> = ({ showMessageArea }) => (\n <div\n className={[\n 'flex justify-center items-end text-center p-4',\n showMessageArea ? 'pt-4' : 'flex-1 pt-0',\n ].join(' ')}\n >\n <span className=\"text-xs text-text-default tracking-wide\">\n {UI_STRINGS.GENERAL.AI_CONTENT_INFO}\n </span>\n </div>\n);\n","import { ioAssistStore, type ConfirmModalConfig } from '../stores';\n\n// Distinct sentinel returned when a second showConfirmModal call arrives while\n// one is still open. Callers can detect this and avoid mapping silent preemption\n// onto business actions (e.g. \"user denied sampling\" or \"create new instance\").\nexport const MODAL_PREEMPTED = Symbol('confirmModal.preempted');\nexport type ConfirmModalResult = string | null | typeof MODAL_PREEMPTED;\n\ntype Resolver = (result: ConfirmModalResult) => void;\nlet activeResolver: Resolver | null = null;\n\nexport function showConfirmModal(config: ConfirmModalConfig): Promise<ConfirmModalResult> {\n if (activeResolver) {\n activeResolver(MODAL_PREEMPTED);\n activeResolver = null;\n }\n\n ioAssistStore.getState().showConfirmModal(config);\n\n return new Promise<ConfirmModalResult>((resolve) => {\n activeResolver = resolve;\n });\n}\n\nexport function resolveConfirmModal(buttonId: string | null): void {\n const resolver = activeResolver;\n activeResolver = null;\n ioAssistStore.getState().closeConfirmModal();\n if (resolver) resolver(buttonId);\n}\n","import React from 'react';\n\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { resolveConfirmModal } from '../../utils/confirmModal';\nimport { Modal } from '../shared/Modal';\n\n/**\n * Async question-style dialog backed by `currentConfirmModal` store state:\n * sampling consent, elicitation, mcp-replace. Renders `{heading, text, buttons}`\n * config and resolves the promise returned by `showConfirmModal` with the\n * clicked button id.\n */\nexport const ConfirmModal: React.FC = () => {\n const confirmModal = useIoAssistStore((s) => s.currentConfirmModal);\n\n if (!confirmModal) return null;\n\n const close = () => resolveConfirmModal(null);\n const showCloseIcon = confirmModal.isHeaderCloseButtonDisplayed ?? false;\n\n const footer =\n confirmModal.buttons.length > 0\n ? confirmModal.buttons.map((btn) => {\n const isPrimary = btn.variant === 'primary';\n return (\n <button\n key={btn.id}\n data-testid={`confirm-modal-${btn.id}`}\n type=\"button\"\n onClick={() => resolveConfirmModal(btn.id)}\n className={\n isPrimary\n ? 'flex justify-center items-center rounded-sm cursor-pointer gap-1 px-spacing-6 py-spacing-3 bg-button-submit-background text-white hover:opacity-95 transition-opacity'\n : 'flex justify-center items-center rounded-sm cursor-pointer gap-1 px-spacing-6 py-spacing-3 border border-border-default text-text-default hover:text-text-states-active hover:border-border-hover transition-colors'\n }\n >\n {btn.label}\n </button>\n );\n })\n : null;\n\n return (\n <Modal\n open\n onClose={close}\n title={confirmModal.title}\n showCloseIcon={showCloseIcon}\n footer={footer}\n testId=\"confirm-modal\"\n >\n <div className=\"flex flex-col gap-2 px-6 pb-2\">\n {confirmModal.heading && (\n <span className=\"text-text-black-white text-lg\">{confirmModal.heading}</span>\n )}\n {confirmModal.text && (\n <span className=\"text-text-default text-sm whitespace-pre-wrap break-words\">\n {confirmModal.text}\n </span>\n )}\n </div>\n </Modal>\n );\n};\n","import React from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\n\ntype Props = {\n agentName: string;\n};\n\nexport const WelcomeHeading: React.FC<Props> = ({ agentName }) => (\n <div className=\"flex flex-col gap-3 items-center px-4 pt-[160px]\">\n <h2 className=\"text-[28px] md:text-[44px] font-bold text-text-states-active text-center\">\n {UI_STRINGS.GENERAL.WELCOME_MESSAGE(agentName)}\n </h2>\n </div>\n);\n","import { useEffect, useState } from 'react';\n\nconst MD_BREAKPOINT_QUERY = '(min-width: 768px)';\n\nexport function useIsMobileViewport(): boolean {\n const [isMobile, setIsMobile] = useState(() => {\n if (typeof window === 'undefined') return false;\n return !window.matchMedia(MD_BREAKPOINT_QUERY).matches;\n });\n\n useEffect(() => {\n const mq = window.matchMedia(MD_BREAKPOINT_QUERY);\n const handler = (e: MediaQueryListEvent) => setIsMobile(!e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isMobile;\n}\n","import { useRef, useCallback, useEffect } from 'react';\n\ntype Options = {\n /**\n * CSS `background` value for an always-visible gradient ring painted\n * behind the hover ring. The hover ring fades in on top of it.\n */\n staticGradient?: string;\n};\n\n/**\n * Hook that replicates the Angular `[animationEffect]=\"AnimationType.HOVER_MOUSE_FOLLOW\"` behavior.\n * Adds a gradient border glow that rotates to follow the mouse position on hover.\n * Pass `staticGradient` to keep an at-rest gradient ring visible behind it.\n *\n * Usage:\n * ```tsx\n * const { ref, handlers } = useHoverMouseFollow();\n * <button ref={ref} {...handlers}>Content</button>\n * ```\n */\nexport function useHoverMouseFollow<T extends HTMLElement = HTMLElement>(options: Options = {}) {\n const { staticGradient } = options;\n const ref = useRef<T>(null);\n const blurLayerRef = useRef<HTMLDivElement | null>(null);\n const gradientLayerRef = useRef<HTMLDivElement | null>(null);\n const blurGradientRef = useRef<HTMLDivElement | null>(null);\n const mainGradientRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n // Match Angular host styles: relative + isolate stacking context + transparent border on hover\n const position = getComputedStyle(el).position;\n const originalPosition = el.style.position;\n if (position === 'static') {\n el.style.position = 'relative';\n }\n el.style.transition = 'border-color 0.2s';\n el.style.isolation = 'isolate';\n\n // Background layer (z-index: -1) — preserves the button's background behind content, above gradients\n const bgLayer = document.createElement('div');\n bgLayer.className = 'animation-effect__background';\n bgLayer.style.cssText = `\n position: absolute; inset: 0; border-radius: inherit;\n background: inherit; z-index: -1; pointer-events: none;\n `;\n\n // Gradient layer (sharp, z-index: -2) — uses CSS mask to show only the 1px border ring\n const gradientLayer = document.createElement('div');\n gradientLayer.className = 'animation-effect__gradient-layer';\n gradientLayer.style.cssText = `\n overflow: hidden; border-radius: inherit; position: absolute; inset: -1px;\n pointer-events: none; opacity: 0; transition: opacity 400ms linear; z-index: -2;\n -webkit-mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n -webkit-mask-composite: xor;\n mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n mask-composite: exclude;\n padding: 1px;\n `;\n\n // Blur layer (z-index: -2, with blur) — same mask technique\n const blurLayer = document.createElement('div');\n blurLayer.className = 'animation-effect__blur-layer';\n blurLayer.style.cssText = `\n overflow: hidden; border-radius: inherit; position: absolute; inset: -1px;\n pointer-events: none; opacity: 0; transition: opacity 400ms linear; z-index: -2;\n -webkit-mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n -webkit-mask-composite: xor;\n mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n mask-composite: exclude;\n padding: 1px; filter: blur(3px);\n `;\n\n // Main rotating gradient inside gradient layer\n const mainGradient = document.createElement('div');\n mainGradient.style.cssText = `\n background: conic-gradient(from 0deg, var(--app-accent-color-1) 0deg, var(--app-accent-color-2) 180deg, var(--app-accent-color-1) 360deg);\n width: 1500%; height: 1500%; top: -700%; left: -700%; position: absolute;\n `;\n\n // Blur rotating gradient inside blur layer\n const blurGradient = document.createElement('div');\n blurGradient.style.cssText = `\n background: conic-gradient(from 0deg, var(--app-accent-color-1) 0deg, var(--app-accent-color-2) 180deg, var(--app-accent-color-1) 360deg);\n width: 1500%; height: 1500%; top: -700%; left: -700%; position: absolute;\n `;\n\n gradientLayer.appendChild(mainGradient);\n blurLayer.appendChild(blurGradient);\n\n // Insert layers before content (z-index: -2/-1 keeps them behind due to isolation)\n el.insertBefore(bgLayer, el.firstChild);\n el.insertBefore(gradientLayer, el.firstChild);\n el.insertBefore(blurLayer, el.firstChild);\n\n // Optional always-visible gradient ring. Inserted LAST so it lands at\n // DOM position 0 — same z-index as the hover ring (-2), but painted\n // first so the hover layers (opacity 0→1) fade in on top of it.\n let staticLayer: HTMLDivElement | null = null;\n if (staticGradient) {\n staticLayer = document.createElement('div');\n staticLayer.className = 'animation-effect__static-layer';\n staticLayer.style.cssText = `\n border-radius: inherit; position: absolute; inset: -1px;\n pointer-events: none; z-index: -2;\n -webkit-mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n -webkit-mask-composite: xor;\n mask: linear-gradient(#fff 0, #fff 0) content-box, linear-gradient(#fff 0, #fff 0);\n mask-composite: exclude;\n padding: 1px;\n background: ${staticGradient};\n `;\n el.insertBefore(staticLayer, el.firstChild);\n }\n\n blurLayerRef.current = blurLayer;\n gradientLayerRef.current = gradientLayer;\n blurGradientRef.current = blurGradient;\n mainGradientRef.current = mainGradient;\n\n return () => {\n bgLayer.remove();\n gradientLayer.remove();\n blurLayer.remove();\n staticLayer?.remove();\n el.style.isolation = '';\n el.style.transition = '';\n el.style.position = originalPosition;\n };\n }, [staticGradient]);\n\n const onMouseEnter = useCallback(() => {\n const el = ref.current;\n if (!el || !blurLayerRef.current || !gradientLayerRef.current) return;\n el.style.border = '0.8px solid transparent';\n blurLayerRef.current.style.opacity = '1';\n gradientLayerRef.current.style.opacity = '1';\n }, []);\n\n const onMouseLeave = useCallback(() => {\n const el = ref.current;\n if (!el || !blurLayerRef.current || !gradientLayerRef.current) return;\n el.style.border = '';\n blurLayerRef.current.style.opacity = '0';\n gradientLayerRef.current.style.opacity = '0';\n }, []);\n\n const onMouseMove = useCallback((event: React.MouseEvent) => {\n const el = ref.current;\n if (!el || !blurGradientRef.current || !mainGradientRef.current) return;\n\n const rect = el.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const centerX = rect.width / 2;\n const centerY = rect.height / 2;\n const deltaX = x - centerX;\n const deltaY = y - centerY;\n let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);\n angle = (angle + 360) % 360;\n\n blurGradientRef.current.style.transform = `rotate(${angle}deg)`;\n mainGradientRef.current.style.transform = `rotate(${angle}deg)`;\n }, []);\n\n return {\n ref,\n handlers: { onMouseEnter, onMouseLeave, onMouseMove },\n };\n}\n","import React from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { useHoverMouseFollow } from '../../hooks/useHoverMouseFollow';\nimport { useIoAiWebApi } from '../../hooks/useIoAiWebApi';\nimport { MESSAGES_LOADING_STATE } from '../../types/loading';\nimport { PANEL_CONTENT } from '../../types/panel';\nimport { IconButton } from '../shared/IconButton';\nimport { HomeIcon, ThreadHistoryIcon } from '../shared/icons';\n\nexport const Header: React.FC = () => {\n const isThreadHistoryVisible = useIoAssistStore((s) => s.isThreadHistoryVisible);\n const messagesLength = useIoAssistStore((s) => s.messages.length);\n const messageLoadingState = useIoAssistStore((s) => s.messageLoadingState);\n const completionNotifications = useIoAssistStore((s) => s.completionNotifications);\n const isWorkingContextEnabled = useIoAssistStore((s) => s.isWorkingContextEnabled);\n const setIsThreadHistoryVisible = useIoAssistStore((s) => s.setIsThreadHistoryVisible);\n const setActivePanelContent = useIoAssistStore((s) => s.setActivePanelContent);\n const { newConversation } = useIoAiWebApi();\n\n const hasMessages = messagesLength > 0;\n const isMessageLoading =\n messageLoadingState.type === MESSAGES_LOADING_STATE.LOADING_RESPONSE ||\n messageLoadingState.type === MESSAGES_LOADING_STATE.LOADING_FROM_THREAD;\n const hasNotification = completionNotifications.length > 0;\n const showThreadToggle = !isThreadHistoryVisible;\n const showHomeButton = isMessageLoading || hasMessages;\n\n const handleShowThreadHistory = () => {\n setIsThreadHistoryVisible(true);\n };\n\n const handleNewConversation = () => {\n void newConversation();\n };\n\n const handleWorkingContextOpen = () => {\n setActivePanelContent(PANEL_CONTENT.WORKING_CONTEXT);\n };\n\n const { ref: wcButtonRef, handlers: wcButtonHandlers } =\n useHoverMouseFollow<HTMLButtonElement>();\n\n return (\n <div\n data-testid=\"header\"\n className=\"flex w-full items-center justify-start px-4 py-2 gap-4\"\n >\n {showThreadToggle || showHomeButton ? (\n <div className=\"flex\">\n {showThreadToggle && (\n <div className=\"relative\">\n <IconButton\n size={12}\n containerSize={24}\n onClick={handleShowThreadHistory}\n title=\"Thread history\"\n >\n <ThreadHistoryIcon />\n </IconButton>\n {hasNotification && (\n <span className=\"absolute -top-1 -right-1 size-2.5 rounded-full bg-orange-500\" />\n )}\n </div>\n )}\n\n {showHomeButton && (\n <IconButton\n size={12}\n containerSize={24}\n testId=\"header-new-conversation\"\n onClick={handleNewConversation}\n title=\"New conversation\"\n >\n <HomeIcon />\n </IconButton>\n )}\n </div>\n ) : null}\n\n {isWorkingContextEnabled && (\n <button\n type=\"button\"\n ref={wcButtonRef}\n className=\"flex justify-center items-center px-2 py-[5px] border-[1px] border-button-border-default bg-transparent rounded-[4px] text-text-default cursor-pointer hover:text-text-states-hover font-weight-400 text-xs leading-[100%]\"\n onClick={handleWorkingContextOpen}\n {...wcButtonHandlers}\n >\n {UI_STRINGS.WORKING_CONTEXT_PANEL_COMPONENT.VIEW_WORKING_CONTEXT_BUTTON}\n </button>\n )}\n </div>\n );\n};\n","import React, {\n useState,\n useRef,\n useCallback,\n useEffect,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react';\n\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { useHoverMouseFollow } from '../../hooks/useHoverMouseFollow';\nimport { UI_MESSAGE_ROLES } from '../../types/message';\nimport { PANEL_CONTENT } from '../../types/panel';\nimport { RESPONSE_STREAM_STATUS } from '../../types/stream';\nimport { Icon } from '../shared/Icon';\nimport { IconButton } from '../shared/IconButton';\nimport {\n ArrowUpIcon,\n PaperPlaneIcon,\n StopIcon,\n PromptPanelIcon,\n ToolPanelIcon,\n} from '../shared/icons';\n\ntype Props = {\n onSend: (text: string) => void;\n onAbort: () => void;\n className?: string;\n};\n\nconst MIN_HEIGHT = 17;\nconst MAX_HEIGHT = 260;\n\nexport const InputArea: React.FC<Props> = ({ onSend, onAbort, className }) => {\n const [inputValue, setInputValue] = useState('');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const { ref: hoverRef, handlers: hoverHandlers } = useHoverMouseFollow<HTMLDivElement>({\n staticGradient:\n 'linear-gradient(135deg, var(--app-accent-color-1), var(--app-accent-color-1), var(--app-accent-color-2, var(--app-accent-color-1)))',\n });\n const currentMsgIndexRef = useRef<number | null>(null);\n\n // Per-thread: a stream on a background thread must not disable the input\n // on the currently-active one. Reading the active thread's stream status\n // directly (instead of the global isGeneratingResponse flag) keeps the\n // button state in sync with which thread the user is looking at.\n const isGenerating = useIoAssistStore((s) => {\n const id = s.activeThreadId;\n return !!id && s.streamsByThreadId[id]?.status === RESPONSE_STREAM_STATUS.STREAMING;\n });\n const messages = useIoAssistStore((s) => s.messages);\n const selectedPrompt = useIoAssistStore((s) => s.selectedPrompt);\n const setSelectedPrompt = useIoAssistStore((s) => s.setSelectedPrompt);\n\n const userMessages = messages.filter((m) => m.role === UI_MESSAGE_ROLES.USER);\n\n const updateValue = useCallback((value: string) => {\n setInputValue(value);\n\n // Resize textarea\n requestAnimationFrame(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = `${MIN_HEIGHT}px`;\n if (value.trim() !== '') {\n el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;\n }\n });\n }, []);\n\n const updateInputValue = (e: ChangeEvent<HTMLTextAreaElement>) => {\n updateValue(e.target.value);\n currentMsgIndexRef.current = null;\n };\n\n useEffect(() => {\n if (selectedPrompt?.description) {\n updateValue(selectedPrompt.description);\n setSelectedPrompt(null);\n }\n }, [selectedPrompt, updateValue, setSelectedPrompt]);\n\n const handleSend = useCallback(() => {\n const trimmed = inputValue.trim();\n if (!trimmed || isGenerating) return;\n\n onSend(trimmed);\n updateValue('');\n currentMsgIndexRef.current = null;\n }, [inputValue, isGenerating, onSend, updateValue]);\n\n // Single button: send when idle with text, stop when generating\n const handleSendOrStop = useCallback(() => {\n if (isGenerating) {\n onAbort();\n } else {\n handleSend();\n }\n }, [isGenerating, onAbort, handleSend]);\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n return;\n }\n\n if (e.key === 'ArrowUp' && e.shiftKey) {\n e.preventDefault();\n browseMessages('up');\n return;\n }\n\n if (e.key === 'ArrowDown' && e.shiftKey) {\n e.preventDefault();\n browseMessages('down');\n return;\n }\n };\n\n const browseMessages = (direction: 'up' | 'down') => {\n if (userMessages.length === 0) return;\n\n const currentMsgIndex = currentMsgIndexRef.current;\n let nextIndex: number;\n\n if (currentMsgIndex === null) {\n nextIndex = direction === 'up' ? userMessages.length - 1 : 0;\n } else {\n if (direction === 'up' && currentMsgIndex > 0) {\n nextIndex = currentMsgIndex - 1;\n } else if (direction === 'down' && currentMsgIndex < userMessages.length - 1) {\n nextIndex = currentMsgIndex + 1;\n } else {\n return;\n }\n }\n\n currentMsgIndexRef.current = nextIndex;\n updateValue(userMessages[nextIndex].content ?? '');\n };\n\n // Three-state: disabled (empty+idle), send (text+idle), stop (generating)\n const buttonState: 'disabled' | 'send' | 'stop' = isGenerating\n ? 'stop'\n : inputValue.trim().length > 0\n ? 'send'\n : 'disabled';\n\n return (\n <div\n data-testid=\"input-area\"\n className={['input-area w-full', className ?? ''].filter(Boolean).join(' ')}\n >\n <div className=\"relative w-full\">\n <div\n ref={hoverRef}\n {...hoverHandlers}\n className=\"relative rounded-2xl border-[1px] border-button-border-default bg-transparent\"\n >\n <div className=\"flex flex-col gap-4 p-4\">\n {/* Textarea */}\n <div className=\"flex gap-3 items-start px-2\">\n <textarea\n ref={textareaRef}\n data-testid=\"input-textarea\"\n aria-label={UI_STRINGS.INPUT_COMPONENT.INPUT_PLACEHOLDER}\n placeholder={UI_STRINGS.INPUT_COMPONENT.INPUT_PLACEHOLDER}\n rows={1}\n className=\"flex-1 custom-scrollbar custom-scrollbar-no-gutter text-text-default text-sm leading-4 resize-none border-none outline-none overflow-y-auto whitespace-pre-wrap placeholder:text-text-states-disabled hover:text-text-states-active bg-transparent\"\n style={{\n height: `${MIN_HEIGHT}px`,\n minHeight: `${MIN_HEIGHT}px`,\n maxHeight: `${MAX_HEIGHT}px`,\n }}\n value={inputValue}\n onChange={updateInputValue}\n onKeyDown={handleKeyDown}\n />\n </div>\n\n <div className=\"flex gap-3 items-center justify-between\">\n <ActionBar />\n\n <button\n type=\"button\"\n data-testid={\n buttonState === 'stop' ? 'abort-button' : 'send-button'\n }\n className={[\n 'flex size-8 shrink-0 items-center justify-center rounded-full transition-colors',\n buttonState === 'send' &&\n 'bg-app-accent-color-1 text-white hover:opacity-90 cursor-pointer',\n buttonState === 'stop' &&\n 'bg-app-accent-color-1 text-white hover:opacity-90 cursor-pointer',\n buttonState === 'disabled' &&\n 'bg-app-icon-background-disabled text-text-states-disabled cursor-not-allowed',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={handleSendOrStop}\n disabled={buttonState === 'disabled'}\n title={buttonState === 'stop' ? 'Stop generation' : 'Send message'}\n >\n <Icon\n size={\n buttonState === 'stop'\n ? 14\n : buttonState === 'send'\n ? 18\n : 16\n }\n >\n {buttonState === 'stop' ? (\n <StopIcon />\n ) : buttonState === 'send' ? (\n <ArrowUpIcon />\n ) : (\n <PaperPlaneIcon />\n )}\n </Icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nconst ActionBar: React.FC = () => {\n const setActivePanelContent = useIoAssistStore((s) => s.setActivePanelContent);\n\n return (\n <div className=\"flex flex-1 gap-0.5\">\n <IconButton\n size={16}\n containerSize={24}\n className=\"hover:bg-app-icon-background-hover\"\n onClick={() => setActivePanelContent(PANEL_CONTENT.PROMPTS)}\n title=\"Browse prompts\"\n aria-label=\"Browse prompts\"\n >\n <PromptPanelIcon />\n </IconButton>\n <IconButton\n size={16}\n containerSize={24}\n className=\"hover:bg-app-icon-background-hover\"\n onClick={() => setActivePanelContent(PANEL_CONTENT.TOOLS)}\n title=\"Manage tools\"\n aria-label=\"Manage tools\"\n >\n <ToolPanelIcon />\n </IconButton>\n </div>\n );\n};\n","import React, { useState, useCallback } from 'react';\n\nimport { MdFormatter } from './MdFormatter';\nimport type { UIAssistantMessage } from '../../types';\nimport { IconButton } from '../shared/IconButton';\nimport { CopyIcon, CheckIcon, ReloadIcon } from '../shared/icons';\n\ntype Props = {\n message: UIAssistantMessage;\n isLast?: boolean;\n onReload?: () => void;\n isGenerating?: boolean;\n};\n\nexport const AssistantMessage: React.FC<Props> = ({\n message,\n isLast = false,\n onReload,\n isGenerating = false,\n}) => {\n const [copied, setCopied] = useState(false);\n const showFooter = isLast && !isGenerating && !!message.content?.trim();\n\n const handleCopy = useCallback(() => {\n const text = message.content ?? '';\n navigator.clipboard.writeText(text).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n }, [message.content]);\n\n return (\n <div\n data-testid=\"assistant-message\"\n className=\"flex flex-col flex-1 self-stretch text-text-states-active font-weight-weight-400 leading-[19px] safe-word-break\"\n >\n {message.content && (\n <div data-testid=\"assistant-message-text\">\n <MdFormatter content={message.content} />\n </div>\n )}\n\n {showFooter && (\n <div\n data-testid=\"message-footer\"\n className=\"flex flex-1 gap-[2px] text-text-secondary\"\n >\n <IconButton\n size={12}\n containerSize={24}\n testId=\"message-copy-button\"\n onClick={handleCopy}\n title={copied ? 'Copied' : 'Copy response'}\n className=\"hover:bg-app-icon-background-hover\"\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </IconButton>\n {onReload && (\n <IconButton\n size={12}\n containerSize={24}\n testId=\"message-reload-button\"\n onClick={onReload}\n title=\"Reload response\"\n className=\"hover:bg-app-icon-background-hover\"\n >\n <ReloadIcon />\n </IconButton>\n )}\n </div>\n )}\n </div>\n );\n};\n","import type { IoAiWeb } from '@interopio/ai-web';\nimport React, { useRef, useEffect } from 'react';\n\ntype Props = {\n appInstance: IoAiWeb.McpApps.AppInstance;\n};\n\n/**\n * Mounts the SDK-provided DOM element of an MCP App instance into a container div.\n * The element is owned by the SDK — do not remove it on unmount, just detach.\n */\nexport const McpAppResource: React.FC<Props> = ({ appInstance }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const mountedIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n if (!appInstance?.element) return;\n if (mountedIdRef.current === appInstance.id) return;\n\n // Clear previous and mount new element\n while (container.firstChild) container.removeChild(container.firstChild);\n container.appendChild(appInstance.element);\n mountedIdRef.current = appInstance.id;\n }, [appInstance]);\n\n return (\n <div\n data-testid=\"mcp-app-resource\"\n className=\"rounded-xl border border-border-default bg-app-background-secondary overflow-hidden\"\n >\n <div ref={containerRef} data-testid=\"mcp-app-iframe\" className=\"w-full min-h-48\" />\n </div>\n );\n};\n","import React, { useMemo } from 'react';\n\nimport { MdFormatter } from './MdFormatter';\nimport { textToJSONMarkdown } from './mdUtils';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { TOOL_RESULT_TYPES, type ToolResult, type UIToolMessage } from '../../types/message';\nimport {\n ChevronDownIcon,\n ChevronUpIcon,\n CircleFilledIcon,\n CircleOutlineIcon,\n} from '../shared/icons';\n\ntype Props = {\n tool: UIToolMessage;\n parentToolTraceId: string;\n onToggle: (toolId: string, parentId: string) => void;\n};\n\nconst parseTextResult = (result: ToolResult): unknown => {\n if (result.type !== TOOL_RESULT_TYPES.TEXT) return result;\n try {\n return { type: result.type, text: JSON.parse(result.text) };\n } catch {\n return { type: result.type, text: result.text };\n }\n};\n\nconst resultToJSONMarkdown = (result: UIToolMessage['result']): string => {\n if (result === undefined || result === null) return 'No result available.';\n if (!Array.isArray(result)) return textToJSONMarkdown(parseTextResult(result));\n return result.map((r) => textToJSONMarkdown(parseTextResult(r))).join('\\n\\n---\\n\\n');\n};\n\nexport const ToolMessage: React.FC<Props> = ({ tool, parentToolTraceId, onToggle }) => {\n const hasResult = tool.result !== undefined && tool.result !== null;\n const isExpanded = !!tool.isExpanded;\n\n const argsMd = useMemo(() => textToJSONMarkdown(tool.args ?? {}), [tool.args]);\n const resultMd = useMemo(() => resultToJSONMarkdown(tool.result), [tool.result]);\n\n return (\n <div\n data-testid=\"tool-message\"\n className=\"flex flex-col justify-start py-2 px-[3px] text-[13px] font-medium leading-[100%] text-text-states-active\"\n >\n <div className=\"flex items-center gap-2 px-1\">\n <span\n title={\n hasResult\n ? UI_STRINGS.TOOL_MESSAGE.TOOL_EXECUTION_SUCCESS\n : UI_STRINGS.TOOL_MESSAGE.TOOL_EXECUTION_PENDING\n }\n className={[\n 'w-2 h-2 shrink-0 inline-flex items-center justify-center',\n hasResult ? 'text-app-accent-color-1' : 'text-text-states-active',\n ].join(' ')}\n >\n {hasResult ? <CircleFilledIcon /> : <CircleOutlineIcon />}\n </span>\n\n <button\n type=\"button\"\n data-testid=\"tool-message-header\"\n className=\"flex flex-1 items-center cursor-pointer text-left\"\n onClick={() => onToggle(tool.id, parentToolTraceId)}\n >\n <div className=\"flex flex-1 ps-2 items-center\">{tool.toolName}</div>\n <span className=\"size-3 shrink-0 inline-flex items-center justify-center\">\n {isExpanded ? <ChevronUpIcon /> : <ChevronDownIcon />}\n </span>\n </button>\n </div>\n\n {isExpanded && (\n <div className=\"flex flex-col gap-4 pt-2 px-2 w-full\">\n <div className=\"px-3 border-l border-text-default\">\n <div className=\"px-2 flex flex-col\">\n <span>Input</span>\n <MdFormatter content={argsMd} />\n\n <span>Output</span>\n <MdFormatter content={resultMd} />\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\n\nimport { ToolMessage } from './ToolMessage';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport type { ToolTraceState } from '../../types';\nimport { ChevronDownIcon, ChevronRightIcon } from '../shared/icons';\n\ntype ToolTraceProps = {\n trace: ToolTraceState;\n onToggle: (messageId: string) => void;\n onToggleTool: (toolId: string, parentId: string) => void;\n};\n\nconst GRADIENT_MASK = 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)';\n\nexport const ToolTraceMessage: React.FC<ToolTraceProps> = ({ trace, onToggle, onToggleTool }) => {\n const uiMessage = trace.uiMessage || 'No UI Message';\n const executedTools = trace.executedTools;\n const isExpanded = !!trace.isExpanded;\n const hasTools = executedTools.length > 0;\n\n const handleToggle = (): void => {\n if (!hasTools) return;\n onToggle(trace.stateForMessageId);\n };\n\n return (\n <div\n data-testid=\"tool-trace-message\"\n id={`tool-trace-message-${trace.stateForMessageId}`}\n className=\"relative flex flex-col flex-1 gap-2 text-text-default rounded-[8px] isolate\"\n >\n {isExpanded && (\n <>\n {/* Solid background sits behind the gradient ring so the mask cutout reveals it. */}\n <div\n aria-hidden\n className=\"absolute inset-0 z-[-2] rounded-[8px] pointer-events-none bg-app-background\"\n />\n <div\n aria-hidden\n className=\"absolute inset-0 z-[-1] p-px rounded-[8px] pointer-events-none bg-[linear-gradient(90deg,var(--app-accent-color-1),var(--app-accent-color-2))]\"\n style={{\n mask: GRADIENT_MASK,\n WebkitMask: GRADIENT_MASK,\n maskComposite: 'exclude',\n WebkitMaskComposite: 'xor',\n }}\n />\n </>\n )}\n\n <div className=\"relative flex flex-col gap-2 px-4 py-6\">\n <button\n type=\"button\"\n data-testid=\"tool-trace-header\"\n tabIndex={0}\n className={[\n 'flex items-center gap-2 text-left transition-colors hover:text-text-states-active',\n hasTools ? 'cursor-pointer' : 'cursor-default',\n isExpanded ? 'flex-row-reverse justify-end' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={handleToggle}\n >\n <span className=\"text-[13px] leading-[19px]\">{uiMessage}</span>\n\n {hasTools && (\n <span\n className={[\n 'w-3 h-3 shrink-0 inline-flex items-center justify-center',\n isExpanded ? 'text-app-accent-color-1' : 'text-text-default',\n ].join(' ')}\n title={\n isExpanded\n ? UI_STRINGS.TOOL_TRACE_MESSAGE.COLLAPSE_BUTTON_TEXT\n : UI_STRINGS.TOOL_TRACE_MESSAGE.EXPAND_BUTTON_TEXT\n }\n >\n {isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\n </span>\n )}\n </button>\n\n {isExpanded && hasTools && (\n <>\n <div data-testid=\"tool-trace-body\" className=\"flex flex-col\">\n {executedTools.map((tool) => (\n <ToolMessage\n key={tool.id}\n tool={tool}\n parentToolTraceId={trace.stateForMessageId}\n onToggle={onToggleTool}\n />\n ))}\n </div>\n\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n data-testid=\"tool-trace-close-button\"\n className=\"px-3 py-1.5 rounded-[6px] text-sm text-text-default border border-border-default transition-colors hover:bg-app-icon-background-hover\"\n onClick={handleToggle}\n >\n {UI_STRINGS.TOOL_TRACE_MESSAGE.CLOSE_BUTTON_TEXT}\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nimport type { UIUserMessage } from '../../types';\nimport { Spinner } from '../shared/icons';\n\ntype Props = {\n message: UIUserMessage;\n isLast?: boolean;\n isGenerating?: boolean;\n};\n\nexport const UserMessage: React.FC<Props> = ({ message, isLast = false, isGenerating = false }) => {\n const showSpinner = isLast && isGenerating;\n\n return (\n <div data-testid=\"user-message\" className=\"flex flex-col justify-end\">\n <div className=\"flex items-end justify-end\">\n <div className=\"flex items-end px-2\">\n {showSpinner && <Spinner className=\"size-5\" />}\n </div>\n\n <div className=\"flex min-w-0\">\n <div className=\"p-4 list-none text-[14px] leading-[18px] font-weight-weight-400 text-user-message-text bg-user-message-background rounded-2xl max-w-[620px] min-w-0 whitespace-pre-wrap break-words\">\n {message.content ?? ''}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport { UI_MESSAGE_ROLES } from '../types';\nimport type { UIAssistantMessage, UIMessage, UIUserMessage, ToolTraceState } from '../types';\n\nexport type RenderItem =\n | { type: 'user'; message: UIUserMessage }\n | { type: 'assistant'; message: UIAssistantMessage }\n | { type: 'tool-trace'; trace: ToolTraceState }\n | { type: 'mcp-app'; app: IoAiWeb.McpApps.AppInstance };\n\nexport function buildRenderList(\n messages: UIMessage[],\n toolTraces: ToolTraceState[],\n mcpAppInstances: IoAiWeb.McpApps.AppInstance[] = [],\n): RenderItem[] {\n const result: RenderItem[] = [];\n const toolMessageIds = new Set(toolTraces.flatMap((t) => t.executedTools.map((et) => et.id)));\n\n const messageRoleById = new Map<string, string>();\n const messageIndexById = new Map<string, number>();\n messages.forEach((m, i) => {\n messageRoleById.set(m.id, m.role);\n messageIndexById.set(m.id, i);\n });\n\n // Resolve each trace to an assistant message id. If a trace is anchored on a\n // user (or otherwise non-assistant) message — which happens when history is\n // loaded as user → tool → assistant and the parent is captured before the\n // assistant arrives — re-anchor it to the next assistant in the sequence and\n // render it above that assistant.\n const traceByAssistantIdAfter = new Map<string, ToolTraceState>();\n const traceByAssistantIdBefore = new Map<string, ToolTraceState>();\n const assistantIdByTrace = new Map<ToolTraceState, string>();\n for (const trace of toolTraces) {\n const targetRole = messageRoleById.get(trace.stateForMessageId);\n if (targetRole === UI_MESSAGE_ROLES.ASSISTANT) {\n traceByAssistantIdAfter.set(trace.stateForMessageId, trace);\n assistantIdByTrace.set(trace, trace.stateForMessageId);\n continue;\n }\n const startIdx = messageIndexById.get(trace.stateForMessageId) ?? -1;\n for (let i = startIdx + 1; i < messages.length; i++) {\n if (messages[i].role === UI_MESSAGE_ROLES.ASSISTANT) {\n traceByAssistantIdBefore.set(messages[i].id, trace);\n assistantIdByTrace.set(trace, messages[i].id);\n break;\n }\n }\n }\n\n // Index: tool-call id → owning trace. AppInstance.id is the toolCallId\n // (libs/ai-web/src/domains/mcp-apps/instance.ts:80), so apps are matched to\n // a trace via that id and then rendered under that trace's assistant message.\n const traceByToolCallId = new Map<string, ToolTraceState>();\n for (const trace of toolTraces) {\n for (const et of trace.executedTools) {\n traceByToolCallId.set(et.id, trace);\n }\n }\n\n const mcpAppsByAssistantId = new Map<string, IoAiWeb.McpApps.AppInstance[]>();\n for (const app of mcpAppInstances) {\n const trace = traceByToolCallId.get(app.id);\n if (!trace) continue;\n const assistantId = assistantIdByTrace.get(trace);\n if (!assistantId) continue;\n const bucket = mcpAppsByAssistantId.get(assistantId) ?? [];\n bucket.push(app);\n mcpAppsByAssistantId.set(assistantId, bucket);\n }\n\n for (const message of messages) {\n // Skip raw tool messages — they're rendered inside traces\n if (message.role === UI_MESSAGE_ROLES.TOOL && toolMessageIds.has(message.id)) {\n continue;\n }\n\n if (message.role === UI_MESSAGE_ROLES.USER) {\n result.push({ type: 'user', message });\n continue;\n }\n\n if (message.role === UI_MESSAGE_ROLES.ASSISTANT) {\n const traceBefore = traceByAssistantIdBefore.get(message.id);\n if (traceBefore) {\n result.push({ type: 'tool-trace', trace: traceBefore });\n }\n\n result.push({ type: 'assistant', message });\n\n const traceAfter = traceByAssistantIdAfter.get(message.id);\n if (traceAfter) {\n result.push({ type: 'tool-trace', trace: traceAfter });\n }\n\n const apps = mcpAppsByAssistantId.get(message.id);\n if (apps) {\n for (const app of apps) result.push({ type: 'mcp-app', app });\n }\n continue;\n }\n }\n\n return result;\n}\n","import React, { useRef, useEffect, useCallback, useState } from 'react';\n\nimport { Icon } from '../shared/Icon';\nimport { ChevronDownIcon } from '../shared/icons';\n\ntype Props = {\n children: React.ReactNode;\n className?: string;\n /**\n * When true, hold the bottom spacer expanded so newly-added content stays\n * anchored near the top of the visible viewport as the assistant streams.\n * When false, the spacer collapses by the overflow as content grows.\n * Used for the *continuous* anchoring concern, NOT the one-shot snap.\n */\n shouldExpandSpacer?: boolean;\n /** Force-scroll to bottom when this flips true (e.g. after a thread fetch). */\n isForceScrollToBottomEnabled?: boolean;\n /**\n * Monotonically-increasing counter. Every time it changes, the component\n * fires a one-shot \"snap to top\" (expand spacer + scrollToBottom). This\n * is the imperative path used when the user sends a new message —\n * deterministic, not derived from any other state.\n */\n snapToTopTrigger?: number;\n};\n\nconst SCROLL_THRESHOLD = 20;\nconst EXPANDED_SPACER_OFFSET = 150;\n\n/**\n * Mirrors `libs/io-assist-ng/.../scroll-area.component.html/.ts`:\n * - host is `flex flex-col flex-1 min-h-0 relative`\n * - the inner scroller has `overflow-y-auto custom-scrollbar custom-scrollbar-no-gutter`\n * - the scroll-to-bottom button is rendered on the host (NOT inside the\n * scroller), so its `absolute bottom-5` sits at the viewport bottom rather\n * than at `scrollHeight - 5px` (which is what we'd get if we placed it\n * inside the scrollable element)\n * - the spacer sits at the bottom of the scroller content\n */\nexport const ScrollArea: React.FC<Props> = ({\n children,\n className = '',\n shouldExpandSpacer = false,\n isForceScrollToBottomEnabled = false,\n snapToTopTrigger,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [showScrollButton, setShowScrollButton] = useState(false);\n\n // Mirror the props into a ref so the MutationObserver callback (set up\n // once) always sees the latest values without needing to recreate.\n const propsRef = useRef({ shouldExpandSpacer, isForceScrollToBottomEnabled });\n propsRef.current = { shouldExpandSpacer, isForceScrollToBottomEnabled };\n\n const isCloseToBottom = useCallback((): boolean => {\n const el = containerRef.current;\n if (!el) return true;\n return el.scrollHeight - el.scrollTop - el.clientHeight <= SCROLL_THRESHOLD;\n }, []);\n\n const scrollToBottom = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, []);\n\n const handleSpacerBehavior = useCallback(() => {\n const container = containerRef.current;\n const spacer = spacerRef.current;\n if (!container || !spacer) return;\n\n if (propsRef.current.shouldExpandSpacer) {\n // Hold the spacer expanded while we wait for the assistant to\n // start responding — keeps the user message anchored near the top.\n spacer.style.minHeight = `${Math.max(0, container.clientHeight - EXPANDED_SPACER_OFFSET)}px`;\n return;\n }\n\n const overflow = container.scrollHeight - container.scrollTop - container.clientHeight;\n if (overflow <= SCROLL_THRESHOLD) return;\n const newHeight = Math.max(spacer.offsetHeight - overflow, 0);\n spacer.style.minHeight = `${newHeight}px`;\n }, []);\n\n const snapToTop = useCallback(() => {\n const container = containerRef.current;\n const spacer = spacerRef.current;\n if (!container || !spacer) return;\n spacer.style.minHeight = `${Math.max(0, container.clientHeight - EXPANDED_SPACER_OFFSET)}px`;\n // Reading scrollHeight here flushes layout before we set scrollTop.\n container.scrollTop = container.scrollHeight;\n }, []);\n\n const handleScroll = useCallback(() => {\n setShowScrollButton(!isCloseToBottom());\n }, [isCloseToBottom]);\n\n // MutationObserver + ResizeObserver set up ONCE — the propsRef pattern\n // keeps the closure fresh without tear-down/re-setup on every prop change.\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const mo = new MutationObserver(() => {\n handleSpacerBehavior();\n setShowScrollButton(!isCloseToBottom());\n });\n mo.observe(container, { childList: true, subtree: true, characterData: true });\n\n const ro = new ResizeObserver(() => handleSpacerBehavior());\n ro.observe(container);\n\n return () => {\n mo.disconnect();\n ro.disconnect();\n };\n }, [handleSpacerBehavior, isCloseToBottom, scrollToBottom]);\n\n // Imperative one-shot snap — fired by the store's `requestScrollAnchor`\n // counter, currently incremented inside `sendUserMessage` immediately\n // after a new user message is added. Deterministic; no derivation chain.\n // We rAF to ensure the new user-message DOM has committed before we\n // measure clientHeight / scrollHeight.\n useEffect(() => {\n if (snapToTopTrigger === undefined || snapToTopTrigger === 0) return;\n const id = requestAnimationFrame(() => snapToTop());\n return () => cancelAnimationFrame(id);\n }, [snapToTopTrigger, snapToTop]);\n\n // Snap to the bottom when `isForceScrollToBottomEnabled` becomes true\n // (e.g. after a thread fetch — messages are committed BEFORE this flag\n // flips, so the MO has nothing left to observe at flip time).\n useEffect(() => {\n if (!isForceScrollToBottomEnabled) return;\n const id = requestAnimationFrame(() => scrollToBottom());\n return () => cancelAnimationFrame(id);\n }, [isForceScrollToBottomEnabled, scrollToBottom]);\n\n return (\n <div className={`relative flex flex-col flex-1 min-h-0 ${className}`}>\n <div\n ref={containerRef}\n className=\"flex flex-col flex-1 min-h-0 overflow-y-auto custom-scrollbar custom-scrollbar-no-gutter\"\n onScroll={handleScroll}\n >\n {children}\n\n {/* Bottom spacer (mirrors ng's `<div #spacerElement>`). No CSS\n transition — the spacer's min-height changes are reads-after-writes\n that need to flush layout immediately so `scrollHeight` is accurate\n when we set `scrollTop`. Animating the change made the snap miss. */}\n <div ref={spacerRef} className=\"shrink-0\" />\n </div>\n\n {showScrollButton && (\n <button\n type=\"button\"\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className=\"absolute bottom-5 left-1/2 -translate-x-1/2 z-10 size-8 rounded-full bg-app-background-secondary border border-border-default shadow flex items-center justify-center text-text-secondary hover:text-text-states-hover hover:border-border-hover transition-colors\"\n onClick={() => scrollToBottom()}\n >\n <Icon size={14}>\n <ChevronDownIcon />\n </Icon>\n </button>\n )}\n </div>\n );\n};\n","import type { IoAiWeb } from '@interopio/ai-web';\nimport React from 'react';\n\nimport { AssistantMessage } from './AssistantMessage';\nimport { McpAppResource } from './McpAppResource';\nimport { ToolTraceMessage } from './ToolTraceMessage';\nimport { UserMessage } from './UserMessage';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { MESSAGES_LOADING_STATE } from '../../types/loading';\nimport { UI_MESSAGE_ROLES } from '../../types/message';\nimport { RESPONSE_STREAM_STATUS } from '../../types/stream';\nimport { buildRenderList } from '../../utils/messageUtils';\nimport { ScrollArea } from '../scroll-area/ScrollArea';\n\ntype Props = {\n onReloadResponse: () => void;\n className?: string;\n};\n\nexport const MessageArea: React.FC<Props> = ({ onReloadResponse, className }) => {\n const messages = useIoAssistStore((s) => s.messages);\n const toolTraceState = useIoAssistStore((s) => s.toolTraceState);\n const isGenerating = useIoAssistStore((s) => {\n const id = s.activeThreadId;\n return !!id && s.streamsByThreadId[id]?.status === RESPONSE_STREAM_STATUS.STREAMING;\n });\n const messageLoadingState = useIoAssistStore((s) => s.messageLoadingState);\n const mcpAppInstances = useIoAssistStore((s) => s.mcpAppInstances);\n const activeThreadId = useIoAssistStore((s) => s.activeThreadId);\n const toggleToolTrace = useIoAssistStore((s) => s.toggleToolTrace);\n const toggleToolMessage = useIoAssistStore((s) => s.toggleToolMessage);\n const scrollAnchorRequestId = useIoAssistStore((s) => s.scrollAnchorRequestId);\n\n const visibleMcpApps = mcpAppInstances.filter((app: IoAiWeb.McpApps.AppInstance) => {\n // Only inline-rendered MCP apps have a DOM element. Workspace-mode apps\n // are rendered by io.Connect as workspace panels, not in the chat.\n if (app.displayMode === 'workspace') return false;\n return !activeThreadId || !app.threadId || app.threadId === activeThreadId;\n });\n\n const renderedMessages = buildRenderList(messages, toolTraceState, visibleMcpApps);\n\n const lastMessage = messages[messages.length - 1];\n const isLastAssistant = lastMessage?.role === UI_MESSAGE_ROLES.ASSISTANT;\n const isLastUser = lastMessage?.role === UI_MESSAGE_ROLES.USER;\n const lastUserMessage = [...messages].reverse().find((m) => m.role === UI_MESSAGE_ROLES.USER);\n\n const isSuccessFetchedFromThread =\n messageLoadingState.type === MESSAGES_LOADING_STATE.FETCH_MESSAGES_FROM_THREAD_SUCCESS;\n\n return (\n <ScrollArea\n shouldExpandSpacer={isLastUser}\n isForceScrollToBottomEnabled={isSuccessFetchedFromThread}\n snapToTopTrigger={scrollAnchorRequestId}\n className={className}\n >\n {/* Loading thread messages spinner */}\n {messageLoadingState.type === MESSAGES_LOADING_STATE.LOADING_FROM_THREAD && (\n <div className=\"flex flex-1 justify-center items-center p-4\">\n <div className=\"flex gap-1\">\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n className=\"size-1.5 rounded-full bg-app-accent-color-1\"\n style={{\n animationDelay: `${i * 0.15}s`,\n animation: `rise 0.6s cubic-bezier(0.16,1,0.3,1) ${i * 0.15}s infinite alternate`,\n }}\n />\n ))}\n </div>\n </div>\n )}\n\n <div\n data-testid=\"message-list\"\n className=\"flex flex-1 flex-col gap-8 w-full min-w-[200px] max-w-[920px] md:max-w-[720px] mx-auto px-3\"\n >\n {renderedMessages.map((item) => {\n if (item.type === 'user') {\n const isLast = isGenerating\n ? item.message.id === lastUserMessage?.id\n : item.message.id === lastMessage?.id && isLastUser;\n return (\n <UserMessage\n key={item.message.id}\n message={item.message}\n isLast={isLast}\n isGenerating={isGenerating}\n />\n );\n }\n\n if (item.type === 'assistant') {\n const isLast = item.message.id === lastMessage?.id && isLastAssistant;\n return (\n <AssistantMessage\n key={item.message.id}\n message={item.message}\n isLast={isLast}\n isGenerating={isGenerating}\n onReload={isLast ? onReloadResponse : undefined}\n />\n );\n }\n\n if (item.type === 'tool-trace') {\n return (\n <ToolTraceMessage\n key={`trace-${item.trace.stateForMessageId}`}\n trace={item.trace}\n onToggle={toggleToolTrace}\n onToggleTool={toggleToolMessage}\n />\n );\n }\n\n if (item.type === 'mcp-app') {\n return <McpAppResource key={item.app.id} appInstance={item.app} />;\n }\n\n return null;\n })}\n </div>\n </ScrollArea>\n );\n};\n","import React from 'react';\n\nimport { PromptListItem } from './PromptListItem';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\n\nexport const FavoritePromptList: React.FC = () => {\n const allPrompts = useIoAssistStore((s) => s.allPrompts);\n const favoritePromptNames = useIoAssistStore((s) => s.favoritePromptNames);\n\n const favorites = allPrompts.filter((p) => favoritePromptNames.includes(p.name));\n\n if (favorites.length === 0) return null;\n\n return (\n <div\n data-testid=\"favorite-prompt-list\"\n className={'flex flex-col w-full gap-[10px] py-2 max-w-[920px] w-full px-4'}\n >\n <div className=\"flex items-center p-2 w-full shrink-0\">\n <span className=\"text-[10px] leading-[13px] tracking-[0.1px] text-text-default\">\n {UI_STRINGS.PROMPT_LIST_COMPONENT.FAVORITE_PROMPTS}\n </span>\n </div>\n\n <div className=\"w-full flex flex-col md:flex-row md:flex-wrap md:justify-center gap-3\">\n {favorites.map((prompt) => (\n <PromptListItem\n key={prompt.name}\n prompt={prompt}\n isDisplayedInFavoriteList={true}\n />\n ))}\n </div>\n </div>\n );\n};\n","import React, { useRef, useEffect } from 'react';\n\nimport { RESPONSE_STREAM_STATUS } from '../../types/stream';\nimport { IconButton } from '../shared/IconButton';\nimport { PencilIcon, TrashIcon, Spinner } from '../shared/icons';\n\ntype ThreadHistoryListItemProps = {\n threadId: string;\n title: string;\n isActive: boolean;\n isEditing: boolean;\n editValue: string;\n hasNotification: boolean;\n streamStatus?: string;\n onSelect: (threadId: string) => void;\n onStartEditing: (threadId: string, title: string, e: React.MouseEvent) => void;\n onCommitEdit: (threadId: string) => void;\n onEditChange: (value: string) => void;\n onEditKeyDown: (e: React.KeyboardEvent, threadId: string) => void;\n onDelete: (threadId: string, e: React.MouseEvent) => void;\n};\n\nexport const ThreadHistoryListItem: React.FC<ThreadHistoryListItemProps> = ({\n threadId,\n title,\n isActive,\n isEditing,\n editValue,\n hasNotification,\n streamStatus,\n onSelect,\n onStartEditing,\n onCommitEdit,\n onEditChange,\n onEditKeyDown,\n onDelete,\n}) => {\n const editRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (isEditing && editRef.current) {\n editRef.current.focus();\n editRef.current.select();\n }\n }, [isEditing]);\n\n const isThreadStreaming = streamStatus === RESPONSE_STREAM_STATUS.STREAMING;\n const showNotificationBadge = hasNotification && !isActive;\n const isThreadActionPending = isThreadStreaming;\n\n return (\n <div\n role=\"button\"\n data-testid=\"thread-history-item\"\n data-thread-id={threadId}\n data-active={isActive ? 'true' : 'false'}\n aria-current={isActive ? 'true' : undefined}\n tabIndex={0}\n className={[\n 'group flex flex-1 justify-start gap-2 px-4 h-8 rounded-md cursor-pointer hover:bg-thread-list-item-hover-background',\n isActive ? 'bg-thread-list-item-hover-background' : '',\n ].join(' ')}\n onClick={() => !isEditing && onSelect(threadId)}\n onKeyUp={(e) => e.key === 'Enter' && !isEditing && onSelect(threadId)}\n >\n <div className=\"flex items-center gap-2 cursor-pointer p-2 flex-1 min-w-0\">\n {!isEditing && (\n <div\n className={[\n 'flex items-center text-xs flex-1 min-w-0 overflow-hidden',\n isActive ? 'text-text-states-active' : 'text-text-default',\n ].join(' ')}\n >\n {showNotificationBadge && (\n <span\n data-testid=\"thread-notification-dot\"\n className=\"size-2 rounded-full bg-orange-500 mr-2 flex-shrink-0\"\n title=\"New response available\"\n />\n )}\n <span className=\"truncate block\" title={title}>\n {title}\n </span>\n {isThreadActionPending && (\n <Spinner className=\"ml-2 flex-shrink-0 size-5 \" />\n )}\n </div>\n )}\n\n {isEditing && (\n <input\n ref={editRef}\n data-testid=\"thread-rename-input\"\n aria-label=\"Rename thread\"\n className=\"flex-1 px-2 border border-border-default rounded text-text-default text-xs bg-transparent outline-none\"\n value={editValue}\n onChange={(e) => onEditChange(e.target.value)}\n onBlur={() => onCommitEdit(threadId)}\n onKeyDown={(e) => onEditKeyDown(e, threadId)}\n onClick={(e) => e.stopPropagation()}\n />\n )}\n\n {/* Thread Action Buttons */}\n <div\n className={[\n 'gap-2 ml-auto items-center',\n isActive ? 'flex' : 'hidden group-hover:flex',\n ].join(' ')}\n >\n <IconButton\n size={12}\n tabIndex={isActive ? 0 : -1}\n title=\"Rename\"\n disabled={isThreadActionPending}\n onClick={(e) => onStartEditing(threadId, title, e)}\n >\n <PencilIcon />\n </IconButton>\n <IconButton\n size={12}\n tabIndex={isActive ? 0 : -1}\n title=\"Delete\"\n disabled={isActive || isThreadActionPending}\n onClick={(e) => onDelete(threadId, e)}\n >\n <TrashIcon />\n </IconButton>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\n\nimport { ThreadHistoryListItem } from './ThreadHistoryListItem';\nimport { UI_STRINGS } from '../../constants/uiStrings';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { useIoAiWebApi } from '../../hooks/useIoAiWebApi';\nimport { LOADING_STATES } from '../../types/loading';\nimport { groupThreadsByTime } from '../../utils/threadUtils';\nimport { Spinner } from '../shared/icons';\n\ntype ThreadHistoryProps = {\n onThreadSelected?: () => void;\n};\n\nexport const ThreadHistory: React.FC<ThreadHistoryProps> = ({ onThreadSelected }) => {\n const threads = useIoAssistStore((s) => s.threads);\n const activeThreadId = useIoAssistStore((s) => s.activeThreadId);\n const completionNotifications = useIoAssistStore((s) => s.completionNotifications);\n const streamsByThreadId = useIoAssistStore((s) => s.streamsByThreadId);\n const threadLoadingState = useIoAssistStore((s) => s.threadLoadingState);\n\n const { selectThread, renameThread, deleteThread } = useIoAiWebApi();\n\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editValue, setEditValue] = useState('');\n\n const groups = groupThreadsByTime(threads);\n const isFetchingThreads = threadLoadingState.type === LOADING_STATES.LOADING;\n\n const startEditing = (threadId: string, currentTitle: string, e: React.MouseEvent) => {\n e.stopPropagation();\n setEditingId(threadId);\n setEditValue(currentTitle);\n };\n\n const commitEdit = (threadId: string) => {\n void renameThread(threadId, editValue);\n setEditingId(null);\n };\n\n const handleEditKeyDown = (e: React.KeyboardEvent, threadId: string) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commitEdit(threadId);\n } else if (e.key === 'Escape') {\n setEditingId(null);\n }\n };\n\n const handleDelete = (threadId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n void deleteThread(threadId);\n };\n\n const handleSelectThread = async (threadId: string): Promise<void> => {\n await selectThread(threadId);\n onThreadSelected?.();\n };\n\n return (\n <div\n data-testid=\"thread-history\"\n className=\"flex flex-1 flex-col p-2 overflow-y-scroll custom-scrollbar custom-scrollbar-no-gutter\"\n >\n {isFetchingThreads && (\n <div className=\"flex flex-1 justify-center items-center\">\n <Spinner />\n </div>\n )}\n\n {!isFetchingThreads && groups.length === 0 && (\n <p className=\"flex flex-1 justify-center items-center text-text-default text-xs\">\n {UI_STRINGS.THREAD_HISTORY_COMPONENT.NO_THREADS}\n </p>\n )}\n\n {!isFetchingThreads &&\n groups.map((group) => (\n <div key={group.label} data-testid=\"thread-history-list\">\n <div data-testid=\"thread-history-divider\" className=\"p-2 pb-0\">\n <span className=\"text-xs text-proto-text-disabled cursor-default\">\n {group.label}\n </span>\n </div>\n {group.threads.map((thread) => (\n <ThreadHistoryListItem\n key={thread.id}\n threadId={thread.id}\n title={thread.title ?? thread.id}\n isActive={thread.id === activeThreadId}\n isEditing={editingId === thread.id}\n editValue={editValue}\n hasNotification={completionNotifications.includes(thread.id)}\n streamStatus={streamsByThreadId[thread.id]?.status}\n onSelect={(id) => void handleSelectThread(id)}\n onStartEditing={startEditing}\n onCommitEdit={commitEdit}\n onEditChange={setEditValue}\n onEditKeyDown={handleEditKeyDown}\n onDelete={handleDelete}\n />\n ))}\n </div>\n ))}\n </div>\n );\n};\n","import React from 'react';\n\nimport { ThreadHistory } from './ThreadHistory';\nimport { useIoAssistStore } from '../../context/IoAssistContext';\nimport { IconButton } from '../shared/IconButton';\nimport { ThreadHistoryIcon } from '../shared/icons';\nimport { IoAssistLogoDark, IoAssistLogoLight } from '../shared/icons';\n\ntype ThreadHistoryPanelProps = {\n userId: string;\n className?: string;\n};\n\nexport const ThreadHistoryPanel: React.FC<ThreadHistoryPanelProps> = ({ userId, className }) => {\n const setIsThreadHistoryVisible = useIoAssistStore((s) => s.setIsThreadHistoryVisible);\n const isDarkMode = useIoAssistStore((s) => s.isDarkMode);\n\n const hideThreadHistory = () => setIsThreadHistoryVisible(false);\n\n const userInitial = userId ? userId.charAt(0).toUpperCase() : 'U';\n const hasUsername = !!userId;\n\n return (\n <aside\n data-testid=\"sidebar\"\n className={[\n 'flex flex-col h-full w-[368px] min-w-[368px] max-w-[368px] bg-app-background-secondary',\n className ?? '',\n ].join(' ')}\n >\n <div className=\"flex items-center gap-4 px-4 py-2\">\n <IconButton\n size={12}\n containerSize={24}\n onClick={hideThreadHistory}\n title=\"Thread history\"\n >\n <ThreadHistoryIcon />\n </IconButton>\n {isDarkMode ? <IoAssistLogoDark /> : <IoAssistLogoLight />}\n </div>\n\n <ThreadHistory />\n\n {hasUsername && (\n <div className=\"flex items-center gap-3 px-4 py-3 mt-auto border-t border-border-default\">\n <div className=\"flex items-center justify-center size-6 rounded-full bg-app-accent-color-1 text-white font-semibold text-[12px] flex-shrink-0\">\n {userInitial}\n </div>\n <div className=\"flex flex-col flex-1 min-w-0\">\n <span\n className=\"text-text-default text-[12px] leading-[12px] font-normal truncate\"\n title={userId}\n >\n {userId}\n </span>\n </div>\n </div>\n )}\n </aside>\n );\n};\n","import React, { useEffect } from 'react';\n\nimport { ActivePanelModal } from './ActivePanelModal';\nimport { AiDisclaimer } from './AiDisclaimer';\nimport { ConfirmModal } from './ConfirmModal';\nimport { WelcomeHeading } from './WelcomeHeading';\nimport { useIoAssistStore, useIoAssistDynamicConfig } from '../../context/IoAssistContext';\nimport { useIoAiWebApi } from '../../hooks/useIoAiWebApi';\nimport { useIsMobileViewport } from '../../hooks/useIsMobileViewport';\nimport { MESSAGES_LOADING_STATE } from '../../types/loading';\nimport { Header } from '../header/Header';\nimport { InputArea } from '../input-area/InputArea';\nimport { MessageArea } from '../messages/MessageArea';\nimport { FavoritePromptList } from '../prompt/FavoritePromptList';\nimport { ThreadHistoryPanel } from '../threads/ThreadHistoryPanel';\n\nexport const Chat: React.FC = () => {\n const dynamicConfig = useIoAssistDynamicConfig();\n const isThreadHistoryVisible = useIoAssistStore((s) => s.isThreadHistoryVisible);\n const setIsThreadHistoryVisible = useIoAssistStore((s) => s.setIsThreadHistoryVisible);\n const messages = useIoAssistStore((s) => s.messages);\n const messageLoadingState = useIoAssistStore((s) => s.messageLoadingState);\n const favoritePromptNames = useIoAssistStore((s) => s.favoritePromptNames);\n\n const { sendMessage, abortMessage } = useIoAiWebApi();\n\n const isMobile = useIsMobileViewport();\n\n const hasMessages = messages.length > 0;\n const isLoadingThread = messageLoadingState.type === MESSAGES_LOADING_STATE.LOADING_FROM_THREAD;\n const showMessageArea = hasMessages || isLoadingThread;\n const showWelcomeMessage = !showMessageArea;\n const showFavoritePrompts = showWelcomeMessage && favoritePromptNames.length > 0;\n const agentName = dynamicConfig.user.name ?? dynamicConfig.user.id;\n\n // Auto-close sidebar when the viewport shrinks below md (parity with ng's\n // ResponsiveUIService effect). Intentionally depends only on `isMobile` so\n // it fires on the false→true transition; including `isThreadHistoryVisible`\n // would race the Header's open action and slam it shut on mobile.\n useEffect(() => {\n if (isMobile) {\n setIsThreadHistoryVisible(false);\n }\n }, [isMobile, setIsThreadHistoryVisible]);\n\n const handleSend = (text: string): void => {\n sendMessage(text);\n };\n\n const handleReload = (): void => {\n const lastUser = [...messages].reverse().find((m) => m.role === 'user');\n if (lastUser && 'content' in lastUser && typeof lastUser.content === 'string') {\n sendMessage(lastUser.content);\n }\n };\n\n const closeSidebar = (): void => setIsThreadHistoryVisible(false);\n\n const scrollableClassNames = [\n 'flex flex-col flex-1 min-h-0 pb-0 w-full overflow-x-hidden overflow-auto',\n 'custom-scrollbar custom-scrollbar-no-gutter',\n showMessageArea ? 'pt-0 gap-0' : 'pt-24 md:pt-20 gap-12 md:gap-14',\n ].join(' ');\n\n const innerColumnClassNames = [\n 'flex flex-1 min-h-0 flex-col items-center w-full',\n showMessageArea ? 'gap-0' : 'gap-6',\n ].join(' ');\n\n return (\n <div\n data-testid=\"io-assist-root\"\n className=\"flex h-full w-full overflow-hidden bg-app-background\"\n >\n <div data-testid=\"chat\" className=\"flex flex-1 min-h-0 overflow-hidden\">\n {isThreadHistoryVisible && isMobile && (\n <div\n role=\"presentation\"\n className=\"fixed inset-0 z-20 bg-black/45\"\n onClick={closeSidebar}\n onKeyDown={(e) => e.key === 'Escape' && closeSidebar()}\n />\n )}\n\n {isThreadHistoryVisible && (\n <ThreadHistoryPanel\n userId={dynamicConfig.user.id}\n className={\n isMobile ? 'fixed left-0 top-0 h-full z-30' : 'relative h-full shrink-0'\n }\n />\n )}\n\n <div className=\"flex flex-col flex-1 min-h-0 min-w-0 items-center justify-end relative\">\n <Header />\n\n <div className={scrollableClassNames}>\n {showWelcomeMessage && <WelcomeHeading agentName={agentName} />}\n\n <div className={innerColumnClassNames}>\n {showMessageArea && (\n <MessageArea\n onReloadResponse={handleReload}\n className=\"flex-1 flex flex-col min-h-0 w-full\"\n />\n )}\n\n <InputArea\n onSend={handleSend}\n onAbort={abortMessage}\n className=\"max-w-[920px] md:max-w-[720px] w-full px-4\"\n />\n\n {showFavoritePrompts && <FavoritePromptList />}\n\n <AiDisclaimer showMessageArea={showMessageArea} />\n </div>\n </div>\n </div>\n </div>\n\n <ActivePanelModal />\n <ConfirmModal />\n </div>\n );\n};\n","export const ELICITATION_ACTION = {\n ACCEPT: 'accept',\n DECLINE: 'decline',\n CANCEL: 'cancel',\n} as const;\n\nexport type ElicitationAction = (typeof ELICITATION_ACTION)[keyof typeof ELICITATION_ACTION];\n\nexport const SAMPLING_ACTION = {\n ACCEPT: 'accept',\n DECLINE: 'decline',\n} as const;\n\nexport type SamplingAction = (typeof SAMPLING_ACTION)[keyof typeof SAMPLING_ACTION];\n","import { ioAssistStore } from '../stores';\n\nexport type ModalsDialogButton = {\n variant: 'primary' | 'outline';\n text: string;\n id: string;\n};\n\nexport type ModalsDialogRequest = {\n templateName: 'noInputsConfirmationDialog';\n variables: {\n title: string;\n heading: string;\n text: string;\n actionButtons: ModalsDialogButton[];\n };\n};\n\nexport type ModalsDialogResponse = {\n responseButtonClicked?: { id: string };\n};\n\nexport async function isModalsAvailable(): Promise<boolean> {\n const ioConnectApi = ioAssistStore.getState().ioConnectApi;\n const modalsAPI = ioConnectApi?.modals;\n const dialogsAPI = modalsAPI?.dialogs;\n if (!modalsAPI || !dialogsAPI) return false;\n\n try {\n const status = await modalsAPI.getStatus();\n if (!status) return false;\n return status.platformConfigured === true;\n } catch {\n return false;\n }\n}\n\nexport function requestModalDialog(options: ModalsDialogRequest): Promise<ModalsDialogResponse> {\n const ioConnectApi = ioAssistStore.getState().ioConnectApi;\n if (!ioConnectApi?.modals?.dialogs) {\n return Promise.reject(new Error('IO Connect Modals API is not available.'));\n }\n return ioConnectApi.modals.dialogs.request(options);\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport { ELICITATION_ACTION } from '../constants/modalActions';\nimport type { ElicitationAction } from '../constants/modalActions';\nimport { UI_STRINGS } from '../constants/uiStrings';\nimport { ioAssistStore } from '../stores';\nimport { showConfirmModal, MODAL_PREEMPTED } from '../utils/confirmModal';\nimport { isModalsAvailable, requestModalDialog } from '../utils/ioModals';\nimport { logger } from '../utils/logger';\nimport { safeStringify } from '../utils/safeStringify';\n\nconst LOGGER_NAME = 'Elicitation';\nconst log = logger.get(LOGGER_NAME);\n\ntype ElicitationResponse =\n | { action: typeof ELICITATION_ACTION.ACCEPT; content: Record<string, unknown> }\n | { action: typeof ELICITATION_ACTION.DECLINE }\n | { action: typeof ELICITATION_ACTION.CANCEL };\n\nexport function selectElicitation(\n mcp: IoAiWeb.MCPConfig | undefined,\n): (serverName: string, params: IoAiWeb.ElicitationRequestParams) => Promise<ElicitationResponse> {\n const custom = mcp?.clientsConfig?.capabilities?.elicitation?.handler;\n if (typeof custom === 'function') {\n log.warn('Using a custom elicitation handler provided by user configuration.');\n return custom;\n }\n log.warn('No custom elicitation handler provided. Using built-in handler.');\n return handleElicitationRequest;\n}\n\nexport async function handleElicitationRequest(\n serverName: string,\n request: IoAiWeb.ElicitationRequestParams,\n): Promise<ElicitationResponse> {\n const requestThreadId: string | undefined = request?._meta?.threadId;\n const activeThreadId = ioAssistStore.getState().activeThreadId;\n const isFromBackgroundThread = Boolean(\n requestThreadId && activeThreadId && activeThreadId !== requestThreadId,\n );\n\n if (isFromBackgroundThread) {\n log.warn(\n `Elicitation request rejected: active thread (${activeThreadId}) does not match request thread (${requestThreadId})`,\n );\n return buildResponse(\n ELICITATION_ACTION.CANCEL,\n 'Elicitation request rejected: User was not on the thread that the elicitation request was intended for.',\n );\n }\n\n if (!validateElicitationRequest(request)) {\n return buildResponse(ELICITATION_ACTION.CANCEL, 'Elicitation request validation failed.');\n }\n\n try {\n return await getElicitationModalResponse(serverName, request);\n } catch (error) {\n const message =\n 'Error occurred while getting elicitation modal response. Request canceled. ' +\n (error instanceof Error ? error.message : String(error));\n return buildResponse(ELICITATION_ACTION.CANCEL, message);\n }\n}\n\nfunction validateElicitationRequest(request: IoAiWeb.ElicitationRequestParams): boolean {\n const meta = request?._meta;\n if (!meta || !meta.toolName) {\n log.warn('Elicitation request is missing required _meta.toolName field.');\n return false;\n }\n const toolName = meta.toolName;\n if (typeof toolName !== 'string' || toolName.trim().length === 0) {\n log.warn('Elicitation request has invalid _meta.toolName field.');\n return false;\n }\n if (!toolName.startsWith('io_connect')) {\n log.warn('Elicitation request is not intended for io_connect.');\n return false;\n }\n return true;\n}\n\nasync function getElicitationModalResponse(\n serverName: string,\n request: IoAiWeb.ElicitationRequestParams,\n): Promise<ElicitationResponse> {\n log.info(\n `Showing elicitation request from server: ${serverName}, requesting: ${safeStringify(request)}`,\n );\n\n const text =\n typeof request?.message === 'string'\n ? request.message\n : UI_STRINGS.ELICITATION_MODAL.FALLBACK_TEXT;\n\n const modalsAvailable = await isModalsAvailable();\n const buttonId = modalsAvailable\n ? await getModalsApiResponse(text)\n : await getBuiltInPanelResponse(text);\n\n if (buttonId === ELICITATION_ACTION.ACCEPT) return buildResponse(ELICITATION_ACTION.ACCEPT);\n if (buttonId === ELICITATION_ACTION.DECLINE) return buildResponse(ELICITATION_ACTION.DECLINE);\n return buildResponse(\n ELICITATION_ACTION.CANCEL,\n 'Elicitation dialog was closed without a response.',\n );\n}\n\nasync function getModalsApiResponse(text: string): Promise<string | null> {\n const response = await requestModalDialog({\n templateName: 'noInputsConfirmationDialog',\n variables: {\n title: UI_STRINGS.ELICITATION_MODAL.TITLE,\n heading: UI_STRINGS.ELICITATION_MODAL.HEADING,\n text,\n actionButtons: [\n { variant: 'primary', text: 'Accept', id: ELICITATION_ACTION.ACCEPT },\n { variant: 'outline', text: 'Decline', id: ELICITATION_ACTION.DECLINE },\n { variant: 'outline', text: 'Cancel', id: ELICITATION_ACTION.CANCEL },\n ],\n },\n });\n return response?.responseButtonClicked?.id ?? null;\n}\n\nasync function getBuiltInPanelResponse(text: string): Promise<string | null> {\n const result = await showConfirmModal({\n title: UI_STRINGS.ELICITATION_MODAL.TITLE,\n heading: UI_STRINGS.ELICITATION_MODAL.HEADING,\n text,\n buttons: [\n { id: ELICITATION_ACTION.ACCEPT, label: 'Accept', variant: 'primary' },\n { id: ELICITATION_ACTION.DECLINE, label: 'Decline', variant: 'default' },\n { id: ELICITATION_ACTION.CANCEL, label: 'Cancel', variant: 'default' },\n ],\n });\n if (result === MODAL_PREEMPTED) {\n log.warn('Elicitation modal was preempted by another modal; treating as cancel.');\n return ELICITATION_ACTION.CANCEL;\n }\n return result;\n}\n\nfunction buildResponse(action: ElicitationAction, logMessage?: string): ElicitationResponse {\n if (action === ELICITATION_ACTION.ACCEPT) {\n log.info(logMessage ?? 'User accepted the elicitation request.');\n return { action: ELICITATION_ACTION.ACCEPT, content: {} };\n }\n if (action === ELICITATION_ACTION.DECLINE) {\n log.info(logMessage ?? 'User declined the elicitation request.');\n return { action: ELICITATION_ACTION.DECLINE };\n }\n log.info(logMessage ?? 'User canceled the elicitation request.');\n return { action: ELICITATION_ACTION.CANCEL };\n}\n","import { showConfirmModal, MODAL_PREEMPTED } from './confirmModal';\nimport { isModalsAvailable, requestModalDialog } from './ioModals';\nimport { logger } from './logger';\nimport { UI_STRINGS } from '../constants/uiStrings';\n\nconst LOGGER_NAME = 'McpAppsModal';\nconst log = logger.get(LOGGER_NAME);\n\ntype ReplaceChoice = 'recreate' | 'newInstance';\n\nexport async function showMcpAppReplaceModal(toolName: string): Promise<ReplaceChoice> {\n try {\n const modalsAvailable = await isModalsAvailable();\n return modalsAvailable\n ? await getModalsApiResponse(toolName)\n : await getBuiltInPanelResponse(toolName);\n } catch (error) {\n log.warn(\n `MCP app replace modal failed, defaulting to recreate: ${error instanceof Error ? error.message : String(error)}`,\n );\n return 'recreate';\n }\n}\n\nasync function getModalsApiResponse(toolName: string): Promise<ReplaceChoice> {\n const strings = UI_STRINGS.MCP_APP_REPLACE_MODAL;\n const response = await requestModalDialog({\n templateName: 'noInputsConfirmationDialog',\n variables: {\n title: strings.TITLE,\n heading: strings.HEADING,\n text: strings.TEXT(toolName),\n actionButtons: [\n { variant: 'primary', text: strings.REPLACE_BUTTON, id: 'replace' },\n { variant: 'outline', text: strings.NEW_INSTANCE_BUTTON, id: 'new' },\n ],\n },\n });\n return response?.responseButtonClicked?.id === 'replace' ? 'recreate' : 'newInstance';\n}\n\nasync function getBuiltInPanelResponse(toolName: string): Promise<ReplaceChoice> {\n const strings = UI_STRINGS.MCP_APP_REPLACE_MODAL;\n const buttonId = await showConfirmModal({\n title: strings.TITLE,\n heading: strings.HEADING,\n text: strings.TEXT(toolName),\n buttons: [\n { id: 'replace', label: strings.REPLACE_BUTTON, variant: 'primary' },\n { id: 'new', label: strings.NEW_INSTANCE_BUTTON, variant: 'default' },\n ],\n });\n if (buttonId === MODAL_PREEMPTED) {\n log.warn(\n `MCP app replace modal for \"${toolName}\" was preempted by another modal; defaulting to recreate.`,\n );\n return 'recreate';\n }\n return buttonId === 'replace' ? 'recreate' : 'newInstance';\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport type { IoAssistStoreInstance } from '../stores';\nimport type { IoAssistDynamicConfig } from '../types';\nimport { sendUserMessage } from './sendUserMessage';\nimport { logger } from '../utils/logger';\nimport { showMcpAppReplaceModal } from '../utils/mcpAppModal';\nimport { safeStringify } from '../utils/safeStringify';\n\nconst LOGGER_NAME = 'McpAppEvents';\nconst log = logger.get(LOGGER_NAME);\n\ntype AppInstance = IoAiWeb.McpApps.AppInstance;\n\nexport function wireMcpAppEvents(\n ioIntelWeb: IoAiWeb.API,\n store: IoAssistStoreInstance,\n dynamicConfig: IoAssistDynamicConfig,\n): void {\n if (!ioIntelWeb.mcpApps) {\n log.warn(\n 'ioIntelWeb.mcpApps is not available — MCP app + recreate prompt will not work. Check the mcpApps config + sandboxProxyUrl.',\n );\n return;\n }\n\n log.debug(\n `Wiring MCP app handlers: ${safeStringify({\n hasOnAppCreated: typeof ioIntelWeb.mcpApps.onAppCreated === 'function',\n hasOnRecreateRequested: typeof ioIntelWeb.mcpApps.onRecreateRequested === 'function',\n hasOnAppRecreated: typeof ioIntelWeb.mcpApps.onAppRecreated === 'function',\n })}`,\n );\n\n let recreateModalOpen = false;\n // Per-app onMessage unsubscribers so we can clean up on recreate.\n const chatMessageUnsubs = new Map<string, () => void>();\n\n ioIntelWeb.mcpApps.onAppCreated((app: AppInstance) => {\n log.debug(\n `mcpApps.onAppCreated: ${safeStringify({ id: app?.id, threadId: app?.threadId, hasElement: !!app?.element, hasOnMessage: typeof app?.onMessage === 'function' })}`,\n );\n const activeThreadId = store.getState().activeThreadId;\n if (activeThreadId && app.threadId !== activeThreadId) return;\n store.getState().addMcpApp(app);\n subscribeAppToChat(app, store, dynamicConfig, chatMessageUnsubs);\n });\n\n ioIntelWeb.mcpApps.onRecreateRequested((event: IoAiWeb.McpApps.RecreateRequestEvent) => {\n log.debug(\n `mcpApps.onRecreateRequested fired: ${safeStringify({ toolName: event?.toolName, hasSelect: typeof event?.select === 'function' })}`,\n );\n // While a recreate prompt is already on screen, auto-select 'recreate'\n // for subsequent events so dialogs don't stack (mirrors Angular).\n if (recreateModalOpen) {\n event.select('recreate').catch(() => undefined);\n return;\n }\n recreateModalOpen = true;\n\n showMcpAppReplaceModal(event.toolName ?? 'this app')\n .then((choice) => event.select(choice))\n .catch(() => event.select('recreate').catch(() => undefined))\n .finally(() => {\n recreateModalOpen = false;\n });\n });\n\n ioIntelWeb.mcpApps.onAppRecreated((event: IoAiWeb.McpApps.AppRecreatedEvent) => {\n store.getState().removeMcpApp(event.oldId);\n const oldUnsub = chatMessageUnsubs.get(event.oldId);\n if (oldUnsub) {\n try {\n oldUnsub();\n } catch {\n /* noop */\n }\n chatMessageUnsubs.delete(event.oldId);\n }\n });\n}\n\nfunction subscribeAppToChat(\n app: AppInstance,\n store: IoAssistStoreInstance,\n dynamicConfig: IoAssistDynamicConfig,\n unsubs: Map<string, () => void>,\n): void {\n if (typeof app?.onMessage !== 'function') {\n log.warn(`MCP app instance has no onMessage method: ${safeStringify({ id: app?.id })}`);\n return;\n }\n\n const unsub = app.onMessage((text: string) => {\n log.debug(`MCP app sent chat message: ${safeStringify({ appId: app.id, text })}`);\n const activeThreadId = store.getState().activeThreadId;\n if (!activeThreadId) return;\n if (app.threadId && app.threadId !== activeThreadId) return;\n // Forward as a user message and stream the response — same as the\n // user typing into the input area.\n void sendUserMessage(store, text, dynamicConfig);\n });\n\n unsubs.set(app.id, unsub);\n}\n","import type { IoAiWeb } from '@interopio/ai-web';\n\nimport { SAMPLING_ACTION } from '../constants/modalActions';\nimport { UI_STRINGS } from '../constants/uiStrings';\nimport { ioAssistStore } from '../stores';\nimport { showConfirmModal, MODAL_PREEMPTED } from '../utils/confirmModal';\nimport { isModalsAvailable, requestModalDialog } from '../utils/ioModals';\nimport { logger } from '../utils/logger';\nimport { extractTextContent } from '../utils/messageConverter';\nimport { safeStringify } from '../utils/safeStringify';\n\nconst LOGGER_NAME = 'Sampling';\nconst log = logger.get(LOGGER_NAME);\n\ntype SamplingResponse = IoAiWeb.SamplingSuccessResponse | IoAiWeb.SamplingErrorResponse;\n\ntype SamplingMessage = IoAiWeb.SamplingRequestParams['messages'][number];\n\nexport function selectSampling(\n mcp: IoAiWeb.MCPConfig | undefined,\n): (serverName: string, params: IoAiWeb.SamplingRequestParams) => Promise<SamplingResponse> {\n const custom = mcp?.clientsConfig?.capabilities?.sampling?.handler;\n if (typeof custom === 'function') {\n log.warn('Using a custom sampling handler provided by user configuration.');\n return custom;\n }\n log.warn('No custom sampling handler provided. Using built-in handler.');\n return handleSamplingRequest;\n}\n\nexport async function handleSamplingRequest(\n serverName: string,\n request: IoAiWeb.SamplingRequestParams,\n): Promise<SamplingResponse> {\n const requestThreadId: string | undefined = request?._meta?.threadId;\n const activeThreadId = ioAssistStore.getState().activeThreadId;\n const isFromBackgroundThread = Boolean(\n requestThreadId && activeThreadId && activeThreadId !== requestThreadId,\n );\n\n if (isFromBackgroundThread) {\n log.warn(\n `Sampling request rejected: active thread (${activeThreadId}) does not match request thread (${requestThreadId})`,\n );\n return {\n code: -1,\n message:\n 'Sampling request rejected: User was not on the thread that the request was intended for.',\n };\n }\n\n try {\n return await getSamplingModalResponse(serverName, request);\n } catch (error) {\n log.error(\n `Error occurred while getting sampling modal response: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { code: -1, message: 'An error occurred while processing the sampling request.' };\n }\n}\n\nasync function getSamplingModalResponse(\n serverName: string,\n request: IoAiWeb.SamplingRequestParams,\n): Promise<SamplingResponse> {\n log.info(\n `Showing sampling request from server: ${serverName}, requesting: ${safeStringify(request)}`,\n );\n\n const modalsAvailable = await isModalsAvailable();\n const accepted = modalsAvailable\n ? await getModalsApiResponse()\n : await getBuiltInPanelResponse();\n\n if (accepted) {\n log.info('User approved the sampling request.');\n return await getSamplingResponse(request);\n }\n\n log.info('User denied the sampling request.');\n return { code: -1, message: 'User denied the sampling request.' };\n}\n\nasync function getModalsApiResponse(): Promise<boolean> {\n const response = await requestModalDialog({\n templateName: 'noInputsConfirmationDialog',\n variables: {\n title: UI_STRINGS.SAMPLING_MODAL.TITLE,\n heading: UI_STRINGS.SAMPLING_MODAL.HEADING,\n text: UI_STRINGS.SAMPLING_MODAL.TEXT,\n actionButtons: [\n { variant: 'primary', text: 'Continue', id: 'yes' },\n { variant: 'outline', text: 'Cancel', id: 'no' },\n ],\n },\n });\n return response?.responseButtonClicked?.id === 'yes';\n}\n\nasync function getBuiltInPanelResponse(): Promise<boolean> {\n const buttonId = await showConfirmModal({\n title: UI_STRINGS.SAMPLING_MODAL.TITLE,\n heading: UI_STRINGS.SAMPLING_MODAL.HEADING,\n text: UI_STRINGS.SAMPLING_MODAL.TEXT,\n buttons: [\n { id: SAMPLING_ACTION.ACCEPT, label: 'Continue', variant: 'primary' },\n { id: SAMPLING_ACTION.DECLINE, label: 'Cancel', variant: 'default' },\n ],\n });\n if (buttonId === MODAL_PREEMPTED) {\n log.warn('Sampling consent modal was preempted by another modal; treating as decline.');\n return false;\n }\n return buttonId === SAMPLING_ACTION.ACCEPT;\n}\n\nasync function getSamplingResponse(\n request: IoAiWeb.SamplingRequestParams,\n): Promise<SamplingResponse> {\n const selectedAgent = ioAssistStore.getState().selectedAgent;\n if (!selectedAgent) {\n return { code: -1, message: 'No agent available for sampling.' };\n }\n\n log.debug(`Preparing to generate sampling response with request: ${safeStringify(request)}`);\n\n type FormattedMessage = {\n id: string;\n role: SamplingMessage['role'] | 'system';\n content: string;\n };\n\n const formattedMessages: FormattedMessage[] = (request?.messages ?? []).map(\n (element: SamplingMessage) => ({\n id: crypto.randomUUID(),\n role: element?.role,\n content: extractTextContent(element?.content),\n }),\n );\n\n log.debug(`Formatted messages for sampling request: ${safeStringify(formattedMessages)}`);\n\n if (request?.systemPrompt) {\n formattedMessages.unshift({\n id: crypto.randomUUID(),\n role: 'system',\n content: request.systemPrompt,\n });\n }\n\n const params = {\n messages: formattedMessages,\n instructions: request?.systemPrompt,\n system: request?.systemPrompt,\n modelSettings: {\n maxTokens: request?.maxTokens,\n temperature: request?.temperature ?? undefined,\n },\n requestContext: {\n modelPreferences: request?.modelPreferences || undefined,\n },\n structuredOutput: {\n schema: request?._meta?.structuredOutput,\n },\n tools: { autoIncludeEnabled: false },\n };\n\n try {\n const response = await selectedAgent.rawAgent.generate(params);\n if (!response) {\n return {\n code: -1,\n message: 'Failed to generate response for sampling success response.',\n };\n }\n\n const finalMessage: IoAiWeb.SamplingSuccessResponse = {\n role: 'assistant',\n content: { type: 'text', text: response.text ?? '' },\n model: selectedAgent.modelId ?? 'unknown',\n stopReason: 'endTurn',\n };\n\n log.info(`Generated response for sampling success: ${safeStringify(finalMessage)}`);\n return finalMessage;\n } catch (error) {\n log.error(\n `Failed to generate sampling response: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { code: -1, message: 'Failed to generate sampling response.' };\n }\n}\n","// SDK adapter: initialises IoAiWeb after io.Connect is ready, then runs the\n// post-init data loaders (agents, threads, prompts, tools, working context).\n// This module mutates the store via `store.getState().setX()` — selectors are\n// reserved for render-coupled reads in the React tree.\n\nimport type { IoAiWeb } from '@interopio/ai-web';\nimport type { IoIntelWorkingContext } from '@interopio/working-context';\n\nimport type { IoAssistStoreInstance } from '../stores';\nimport { LOADING_STATES, TOOL_STATES } from '../types';\nimport type { IoAssistDynamicConfig, IoAssistPrompt, IoAssistPromptCategory, IoAssistStaticConfig, Prompt, UIAgent, UIThread, UITool } from '../types';\nimport { selectElicitation } from './elicitation';\nimport { wireMcpAppEvents } from './mcpAppEvents';\nimport { selectSampling } from './sampling';\nimport { logger } from '../utils/logger';\n\nconst LOGGER_NAME = 'InitIoAiWeb';\nconst log = logger.get(LOGGER_NAME);\n\nexport async function initIoAiWeb(staticConfig: IoAssistStaticConfig, dynamicConfig: IoAssistDynamicConfig, store: IoAssistStoreInstance): Promise<void> {\n try {\n const { IoAiWebFactory } = await import('@interopio/ai-web');\n\n const ioApi = store.getState().ioConnectApi;\n if (!ioApi) throw new Error('io.Connect API not available');\n\n const webConfig = buildWebConfig(staticConfig, dynamicConfig);\n\n const ioIntelWeb = await IoAiWebFactory(ioApi, webConfig);\n\n log.info('IoAiWeb initialised successfully.');\n\n // Expose globally for debugging\n // (window as Window & { intel?: IoAiWeb.API }).intel = ioIntelWeb;\n\n const state = store.getState();\n state.setIoAiWebApi(ioIntelWeb);\n state.setAppLoadingState({ type: LOADING_STATES.SUCCESS });\n\n // Wire MCP app lifecycle events synchronously after init (mirrors Angular's\n // McpAppsService.attach()) so we don't miss any events that fire before\n // the post-init Promise.all() resolves.\n wireMcpAppEvents(ioIntelWeb, store, dynamicConfig);\n\n const userId = dynamicConfig.user.id ?? '';\n\n // Post-init tasks\n await Promise.all([\n listAgents(ioIntelWeb, staticConfig.defaultAgentName, userId, store),\n loadPrompts(staticConfig.defaultPrompts ?? [], store),\n loadTools(ioIntelWeb, store),\n checkWorkingContext(ioIntelWeb, store),\n ]);\n\n const toolsApi = ioIntelWeb.tools as IoAiWeb.Tools.API & {\n onChanged?: (cb: () => void) => void;\n };\n if (typeof toolsApi.onChanged === 'function') {\n toolsApi.onChanged(() => {\n loadTools(ioIntelWeb, store);\n });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to initialise IO Intel Web API';\n\n store.getState().setAppLoadingState({ type: LOADING_STATES.ERROR, message });\n log.error('IoAiWeb initialisation failed.', error instanceof Error ? error : new Error(String(error)));\n }\n}\n\nfunction buildWebConfig(staticConfig: IoAssistStaticConfig, dynamicConfig: IoAssistDynamicConfig): IoAiWeb.WebConfig {\n const agentServer: IoAiWeb.AgentServerConfig = {\n ...staticConfig.aiWebConfig.agentServer,\n headers: {\n ...(dynamicConfig.agentServer?.headers ?? {}),\n },\n };\n\n const config: IoAiWeb.WebConfig = { agentServer };\n\n if (staticConfig.aiWebConfig.mcp) {\n config.mcp = buildMcpConfig(staticConfig.aiWebConfig.mcp);\n }\n\n if (staticConfig.workingContext) {\n config.context = staticConfig.workingContext;\n }\n\n return config;\n}\n\n/**\n * Mirrors Angular's IoAiWebService.buildMcpConfig(): injects sampling +\n * elicitation handlers. Custom handlers from user config take precedence;\n * otherwise the built-in overlay-driven handlers are used.\n */\nfunction buildMcpConfig(mcp: IoAiWeb.MCPConfig): IoAiWeb.MCPConfig {\n return {\n ...mcp,\n clientsConfig: {\n ...mcp.clientsConfig,\n capabilities: {\n ...mcp.clientsConfig?.capabilities,\n sampling: { handler: selectSampling(mcp) },\n elicitation: { handler: selectElicitation(mcp) },\n },\n },\n };\n}\n\nasync function listAgents(ioIntelWeb: IoAiWeb.API, defaultAgentName: string | undefined, userId: string, store: IoAssistStoreInstance): Promise<void> {\n const state = store.getState();\n state.setAgentsLoadingState({ type: LOADING_STATES.LOADING });\n\n try {\n const rawAgents = await ioIntelWeb.agents.list();\n\n const agents: UIAgent[] = rawAgents.map((a) => ({\n id: a.id,\n name: a.name,\n // `description` is not on IoAiWeb.Agents.Agent's typed surface but some\n // backends surface it via the raw payload — read defensively.\n description: (a as IoAiWeb.Agents.Agent & { description?: string }).description,\n modelId: a.modelId,\n rawAgent: a,\n }));\n\n state.setAgents(agents);\n state.setAgentsLoadingState({ type: LOADING_STATES.SUCCESS });\n\n // Select the default agent or first\n const selected = defaultAgentName ? (agents.find((a) => a.name === defaultAgentName) ?? agents[0]) : agents[0];\n\n if (selected) {\n state.setSelectedAgent(selected);\n\n // Fetch threads for this agent\n await fetchThreads(ioIntelWeb, selected.rawAgent.id, userId, store);\n }\n } catch (error) {\n store.getState().setAgentsLoadingState({\n type: LOADING_STATES.ERROR,\n message: error instanceof Error ? error.message : 'Failed to load agents',\n });\n }\n}\n\nasync function fetchThreads(ioIntelWeb: IoAiWeb.API, agentId: string, userId: string, store: IoAssistStoreInstance): Promise<void> {\n const state = store.getState();\n\n state.setThreadLoadingState({ type: LOADING_STATES.LOADING });\n\n try {\n const rawThreads = await ioIntelWeb.threads.list({\n agentId,\n resourceId: userId,\n });\n\n const threads: UIThread[] = rawThreads.map((t) => ({\n id: t.id,\n title: t.title || t.id.substring(0, 8),\n createdAt: t.createdAt ? new Date(t.createdAt) : new Date(),\n updatedAt: t.updatedAt ? new Date(t.updatedAt) : undefined,\n rawThread: t,\n update: (params: { title: string }) => t.update(params),\n delete: () => t.delete(),\n getMessages: (params: { limit: number }) => t.getMessages(params),\n }));\n\n state.setThreads(threads);\n state.setThreadLoadingState({ type: LOADING_STATES.SUCCESS });\n } catch (error) {\n store.getState().setThreadLoadingState({\n type: LOADING_STATES.ERROR,\n message: error instanceof Error ? error.message : 'Failed to load threads',\n });\n }\n}\n\nfunction loadPrompts(defaultPrompts: IoAssistPromptCategory[], store: IoAssistStoreInstance): void {\n const allPrompts: Prompt[] = defaultPrompts.flatMap((category) =>\n (category.prompts ?? []).map((p: IoAssistPrompt, i: number) => ({\n id: `${category.category ?? 'default'}-${i}-${p.name}`,\n name: p.name,\n description: p.prompt,\n category: category.category,\n iconResource: p.iconResource,\n }))\n );\n\n store.getState().setAllPrompts(allPrompts);\n}\n\nasync function loadTools(ioIntelWeb: IoAiWeb.API, store: IoAssistStoreInstance): Promise<void> {\n const state = store.getState();\n state.setToolLoadingState({ type: LOADING_STATES.LOADING });\n\n try {\n const rawTools = await ioIntelWeb.tools.list();\n\n const tools: UITool[] = rawTools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n enabled: t.enabled ?? true,\n mcpServerName: t.source?.mcpName ?? undefined,\n state: TOOL_STATES.IDLE,\n rawTool: t,\n }));\n\n state.setTools(tools);\n state.setToolLoadingState({ type: LOADING_STATES.SUCCESS });\n } catch {\n state.setToolLoadingState({ type: LOADING_STATES.ERROR, message: 'Failed to load tools' });\n }\n}\n\nasync function checkWorkingContext(ioIntelWeb: IoAiWeb.API, store: IoAssistStoreInstance): Promise<void> {\n const state = store.getState();\n\n try {\n if (!ioIntelWeb.context) {\n state.setIsWorkingContextEnabled(false);\n return;\n }\n\n state.setIsWorkingContextEnabled(true);\n state.setWorkingContextLoadingState({ type: LOADING_STATES.LOADING });\n\n const ctx = await ioIntelWeb.context.get();\n state.setWorkingContext(ctx ?? null);\n state.setWorkingContextLoadingState({ type: LOADING_STATES.SUCCESS });\n\n ioIntelWeb.context.onChanged((newCtx: Record<string, IoIntelWorkingContext.Property>) => {\n store.getState().setWorkingContext(newCtx);\n });\n } catch {\n state.setIsWorkingContextEnabled(false);\n }\n}\n","import { useEffect, useRef } from 'react';\n\nimport { initIoAiWeb } from '../actions/initIoAiWeb';\nimport {\n useIoAssistStore,\n useIoAssistConfig,\n useIoAssistDynamicConfig,\n} from '../context/IoAssistContext';\nimport { ioAssistStore } from '../stores';\nimport { LOADING_STATES } from '../types';\n\n/**\n * Initialises IoAiWeb once io.Connect is ready.\n * Triggers agent listing and prompt parsing after successful init.\n *\n * Thin React shell — the actual SDK adapter lives in\n * `actions/initIoAiWeb.ts`. Mirrors ng's IoAiWebService pattern.\n */\nexport function useIoAiWebBootstrap(): void {\n const isIoConnectReady = useIoAssistStore((s) => s.isIoConnectReady);\n const appLoadingState = useIoAssistStore((s) => s.appLoadingState);\n const staticConfig = useIoAssistConfig();\n const dynamicConfig = useIoAssistDynamicConfig();\n\n const initialised = useRef(false);\n\n useEffect(() => {\n if (!isIoConnectReady) return;\n if (initialised.current) return;\n if (appLoadingState.type !== LOADING_STATES.NOT_STARTED) return;\n initialised.current = true;\n\n void initIoAiWeb(staticConfig, dynamicConfig, ioAssistStore);\n }, [isIoConnectReady, staticConfig, dynamicConfig, appLoadingState.type]);\n}\n","// SDK adapter: bridges the io.Connect factory (browser or desktop) into the\n// store. Pure side-effect module; no React. Mirrors ng's IoService.\n\nimport type { IOConnectBrowser } from '@interopio/browser';\nimport type { IOConnectDesktop } from '@interopio/desktop';\n\nimport type { IoAssistStaticConfig } from '../types';\nimport { logger } from '../utils/logger';\n\nexport type IoConnectStoreSetters = {\n setIoConnectApi: (api: IOConnectBrowser.API) => void;\n setIsIoConnectReady: (ready: boolean) => void;\n setFavoritePromptNames: (names: string[]) => void;\n setIsDarkMode: (dark: boolean) => void;\n};\n\nexport async function initIoConnect(config: IoAssistStaticConfig, store: IoConnectStoreSetters): Promise<void> {\n const { setIoConnectApi, setIsIoConnectReady, setFavoritePromptNames, setIsDarkMode } = store;\n\n const applyAndSync = (themeName: string) => {\n applyTheme(themeName);\n setIsDarkMode(themeName === 'dark');\n };\n\n try {\n let ioApi: IOConnectBrowser.API | IOConnectDesktop.API;\n\n const desktopConfig = config.connectConfig?.desktop;\n const browserConfig = config.connectConfig?.browser;\n\n if (desktopConfig?.factory) {\n ioApi = await desktopConfig.factory(desktopConfig.config);\n } else if (browserConfig?.factory) {\n ioApi = await browserConfig.factory(browserConfig.config);\n } else {\n throw new Error('No io.Connect factory provided. Supply connectConfig.browser or connectConfig.desktop.');\n }\n\n // Debug-only global. NOT required by IoAiWebFactory — the factory takes\n // `ioApi` as a direct argument and never reads `window.io`. Host apps that\n // need a global set their own. Commented out to verify nothing depends on it.\n // (window as Window & { io?: IOConnectBrowser.API | IOConnectDesktop.API }).io = ioApi;\n\n logger.setLogger(ioApi.logger);\n\n setIoConnectApi(ioApi as IOConnectBrowser.API);\n setIsIoConnectReady(true);\n\n const themesApi = ioApi.themes;\n if (themesApi) {\n try {\n const currentTheme = await themesApi.getCurrent();\n if (currentTheme) applyAndSync(currentTheme.name);\n themesApi.onChanged((theme: { name: string }) => applyAndSync(theme.name));\n } catch {\n // Theme API not available in all configurations — apply dark as fallback\n applyAndSync('dark');\n }\n } else {\n applyAndSync('dark');\n }\n\n try {\n const prefs = await ioApi.prefs?.get();\n if (prefs?.data?.favoritePrompts) {\n setFavoritePromptNames(prefs.data.favoritePrompts as string[]);\n }\n } catch (error) {\n console.error('[io-assist-react] io.Connect prefs not available:', error);\n }\n } catch (error) {\n setIsIoConnectReady(false);\n console.error('[io-assist-react] io.Connect initialisation failed:', error);\n }\n}\n\nfunction applyTheme(themeName: string): void {\n document.documentElement.className = '';\n document.documentElement.classList.add(themeName);\n}\n","import { useEffect, useRef } from 'react';\n\nimport { initIoConnect } from '../actions/initIoConnect';\nimport { useIoAssistConfig, useIoAssistStore } from '../context/IoAssistContext';\n\n/**\n * Manages the io.Connect lifecycle:\n * 1. Initialises IOBrowser or IODesktop from static config\n * 2. Sets isIoConnectReady when connected\n * 3. Subscribes to theme changes → applies dark/light class to <html>\n *\n * Thin React shell — the actual SDK adapter lives in\n * `actions/initIoConnect.ts`. Mirrors ng's IoService pattern.\n */\nexport function useIoConnectBootstrap(): void {\n const config = useIoAssistConfig();\n const setIoConnectApi = useIoAssistStore((s) => s.setIoConnectApi);\n const setIsIoConnectReady = useIoAssistStore((s) => s.setIsIoConnectReady);\n const setFavoritePromptNames = useIoAssistStore((s) => s.setFavoritePromptNames);\n const setIsDarkMode = useIoAssistStore((s) => s.setIsDarkMode);\n const initialised = useRef(false);\n\n useEffect(() => {\n if (initialised.current) return;\n initialised.current = true;\n\n void initIoConnect(config, {\n setIoConnectApi,\n setIsIoConnectReady,\n setFavoritePromptNames,\n setIsDarkMode,\n });\n }, [config, setIoConnectApi, setIsIoConnectReady, setFavoritePromptNames, setIsDarkMode]);\n}\n","import React from 'react';\n\nimport { Chat } from './components/chat/Chat';\nimport { Spinner } from './components/shared/icons';\nimport { UI_STRINGS } from './constants/uiStrings';\nimport { IoAssistProvider } from './context/IoAssistContext';\nimport { useIoAssistStore } from './context/IoAssistContext';\nimport { useIoAiWebBootstrap } from './hooks/useIoAiWebBootstrap';\nimport { useIoConnectBootstrap } from './hooks/useIoConnectBootstrap';\nimport type { IoAssistStaticConfig, IoAssistDynamicConfig } from './types';\nimport { LOADING_STATES } from './types/loading';\n\ntype Props = {\n staticConfig: IoAssistStaticConfig;\n dynamicConfig: IoAssistDynamicConfig;\n};\n\n/**\n * Root IoAssist component.\n * Wrap in your own router/auth shell and pass validated configs.\n */\nexport function IoAssist({ staticConfig, dynamicConfig }: Props): React.JSX.Element {\n return (\n <IoAssistProvider staticConfig={staticConfig} dynamicConfig={dynamicConfig}>\n <IoAssistInner />\n </IoAssistProvider>\n );\n}\n\nconst IoAssistInner: React.FC = () => {\n useIoConnectBootstrap();\n useIoAiWebBootstrap();\n\n const appLoadingState = useIoAssistStore((s) => s.appLoadingState);\n\n if (\n appLoadingState.type === LOADING_STATES.LOADING ||\n appLoadingState.type === LOADING_STATES.NOT_STARTED\n ) {\n return <LoadingScreen />;\n }\n\n if (appLoadingState.type === LOADING_STATES.ERROR) {\n return <ErrorScreen onRetry={() => window.location.reload()} />;\n }\n\n return <Chat />;\n};\n\nconst LoadingScreen: React.FC = () => (\n <div className=\"flex items-center justify-center w-full h-full bg-app-background\">\n <Spinner className=\"size-10\" />\n </div>\n);\n\nconst ErrorScreen: React.FC<{ onRetry: () => void }> = ({ onRetry }) => (\n <div className=\"flex items-center justify-center w-full h-full bg-app-background\">\n <div className=\"flex flex-col items-center gap-4 text-center px-6 max-w-sm\">\n <p className=\"text-4xl\">⚠️</p>\n <p className=\"text-sm font-medium text-text-default\">\n {UI_STRINGS.LOADING_STATE.ERROR}\n </p>\n <button\n type=\"button\"\n className=\"px-4 py-2 rounded-xl bg-app-accent-color-1 text-white text-sm hover:opacity-90 transition-opacity\"\n onClick={onRetry}\n >\n {UI_STRINGS.LOADING_STATE.RETRY}\n </button>\n </div>\n </div>\n);\n"],"names":["UI_STRINGS","user","url","toolName","UI_MESSAGE_ROLES","TOOL_RESULT_TYPES","TOOL_STATES","PANEL_CONTENT","RESPONSE_STREAM_STATUS","LOADING_STATES","MESSAGES_LOADING_STATE","createAgentSlice","set","agents","agent","state","createAppLifecycleSlice","ready","dark","api","createConfirmModalSlice","visible","content","config","createMcpAppsSlice","instance","s","a","instanceId","createMessageSlice","messages","message","id","changes","m","generating","success","messageId","t","toolMessageId","parentId","tool","threadId","stream","updatedMessages","toolMsg","assistantId","existingIdx","msg","idx","nextToolTraceState","n","trace","i","messagesChanged","tracesChanged","patch","createPromptSlice","prompts","names","name","prompt","createResponseStreamSlice","userMessage","existing","toolMessage","updatedToolMessages","shouldNotify","errorMessage","next","createThreadSlice","threads","createToolSlice","tools","enabled","toolState","createWorkingContextSlice","ctx","createIoAssistStore","create","subscribeWithSelector","ioAssistStore","IoAssistConfigContext","createContext","IoAssistDynamicConfigContext","IoAssistProvider","staticConfig","dynamicConfig","children","jsx","useIoAssistStore","selector","useStore","useIoAssistConfig","useContext","useIoAssistDynamicConfig","LIB_NAME","Logger","ioLogger","subSystem","fullName","resolve","cached","_","prop","target","value","logger","LOGGER_NAME","log","toggleFavoritePrompt","store","before","after","err","useIoConnectApi","useMemo","Icon","size","className","ThreadHistoryIcon","CloseIcon","HomeIcon","ChevronRightIcon","ChevronUpIcon","ChevronDownIcon","CircleFilledIcon","CircleOutlineIcon","CopyIcon","jsxs","CheckIcon","ReloadIcon","PencilIcon","TrashIcon","SearchIcon","props","InfoIcon","ArrowUpIcon","PaperPlaneIcon","StopIcon","PromptPanelIcon","ToolPanelIcon","PromptDotIcon","StarFilledIcon","StarIcon","filled","Spinner","IoAssistLogoDark","IoAssistLogoLight","PromptListItem","isDisplayedInFavoriteList","isHovered","setIsHovered","useState","favoritePromptNames","setSelectedPrompt","setActivePanelContent","isFavorite","handleSelect","handleToggleFavorite","e","hostClasses","rowClasses","SearchInput","onChange","placeholder","isActive","setIsActive","hasValue","DOCS_URL","UNCATEGORIZED_CATEGORY_NAME","sortPromptsAlphabetically","b","PromptListPanel","allPrompts","search","setSearch","hasAnyPrompts","filteredPrompts","lower","promptGroups","categoryMap","category","noFilteredPrompts","onDocsLinkClick","group","React","ICON_BUTTON_HOVER_BY_VARIANT","IconButton","containerSize","testId","style","type","variant","rest","Modal","open","onClose","title","showCloseIcon","footer","useEffect","onKey","createPortal","ToggleInput","isChecked","onToggle","isDisabled","VIEWPORT_PADDING","Tooltip","position","offset","triggerRef","useRef","bubbleRef","setVisible","isPositioned","setIsPositioned","coords","setCoords","updatePosition","useCallback","triggerEl","bubbleEl","x","y","useLayoutEffect","show","hide","ToolListItem","abortActiveStream","selectedAgent","error","newConversation","deleteThread","thread","wasActive","renameThread","trimmed","previousTitle","safeStringify","convertThreadMessages","rawMessages","result","toolCallMap","raw","extractTextContent","parts","partIndex","part","inv","toolCallId","c","obj","p","DIV","MS","getBucketLabel","diff","groupThreadsByTime","now","groups","labelOrder","sorted","date","label","buildToolTraceFromMessages","traces","currentParentId","currentTrace","selectThread","response","toolTraces","mcpApps","apps","restoreApps","traceLabelFor","count","withTraceLabel","withAllTraceLabelsFinalized","withExecutedToolUpdated","withToolAppendedToTrace","parentMessageId","et","ensureAssistantMessage","currentMessageId","incomingId","processResponseStream","runHandle","isActiveThread","toolCallArgsMap","streamedContent","hasSyntheticPlaceholder","reject","subscription","safeUnsubscribe","rawEvent","event","isBackground","ensuredId","chunkId","chunkText","snapshotMessages","text","currentStream","current","toolCallState","parsedArgs","tm","nextTraces","resultToolCallId","storeState","finalState","sendUserMessage","ioIntelWeb","userId","streamParams","refreshThreads","agentId","params","toggleTool","updated","useIoAiWebApi","ToolListPanel","toolLoadingState","isLoading","hasTools","filteredTools","hasFilteredTools","handleToggle","prismTwilight","CodeBlock","code","rawLanguage","Highlight","prismClassName","tokens","getLineProps","getTokenProps","line","token","key","components","href","MdFormatter","ReactMarkdown","remarkGfm","textToJSONMarkdown","WorkingContextPanel","workingContext","ActivePanelModal","activePanelContent","AiDisclaimer","showMessageArea","MODAL_PREEMPTED","activeResolver","showConfirmModal","resolveConfirmModal","buttonId","resolver","ConfirmModal","confirmModal","close","btn","isPrimary","WelcomeHeading","agentName","MD_BREAKPOINT_QUERY","useIsMobileViewport","isMobile","setIsMobile","mq","handler","useHoverMouseFollow","options","staticGradient","ref","blurLayerRef","gradientLayerRef","blurGradientRef","mainGradientRef","el","originalPosition","bgLayer","gradientLayer","blurLayer","mainGradient","blurGradient","staticLayer","onMouseEnter","onMouseLeave","onMouseMove","rect","centerX","centerY","deltaX","deltaY","angle","Header","isThreadHistoryVisible","messagesLength","messageLoadingState","completionNotifications","isWorkingContextEnabled","setIsThreadHistoryVisible","hasMessages","isMessageLoading","hasNotification","showThreadToggle","showHomeButton","handleShowThreadHistory","handleNewConversation","handleWorkingContextOpen","wcButtonRef","wcButtonHandlers","MIN_HEIGHT","MAX_HEIGHT","InputArea","onSend","onAbort","inputValue","setInputValue","textareaRef","hoverRef","hoverHandlers","currentMsgIndexRef","isGenerating","selectedPrompt","userMessages","updateValue","updateInputValue","handleSend","handleSendOrStop","handleKeyDown","browseMessages","direction","currentMsgIndex","nextIndex","buttonState","ActionBar","AssistantMessage","isLast","onReload","copied","setCopied","showFooter","handleCopy","McpAppResource","appInstance","containerRef","mountedIdRef","container","parseTextResult","resultToJSONMarkdown","r","ToolMessage","parentToolTraceId","hasResult","isExpanded","argsMd","resultMd","GRADIENT_MASK","ToolTraceMessage","onToggleTool","uiMessage","executedTools","Fragment","UserMessage","buildRenderList","mcpAppInstances","toolMessageIds","messageRoleById","messageIndexById","traceByAssistantIdAfter","traceByAssistantIdBefore","assistantIdByTrace","startIdx","traceByToolCallId","mcpAppsByAssistantId","app","bucket","traceBefore","traceAfter","SCROLL_THRESHOLD","EXPANDED_SPACER_OFFSET","ScrollArea","shouldExpandSpacer","isForceScrollToBottomEnabled","snapToTopTrigger","spacerRef","showScrollButton","setShowScrollButton","propsRef","isCloseToBottom","scrollToBottom","handleSpacerBehavior","spacer","overflow","newHeight","snapToTop","handleScroll","mo","ro","MessageArea","onReloadResponse","toolTraceState","activeThreadId","toggleToolTrace","toggleToolMessage","scrollAnchorRequestId","visibleMcpApps","renderedMessages","lastMessage","isLastAssistant","isLastUser","lastUserMessage","isSuccessFetchedFromThread","item","FavoritePromptList","favorites","ThreadHistoryListItem","isEditing","editValue","streamStatus","onSelect","onStartEditing","onCommitEdit","onEditChange","onEditKeyDown","onDelete","editRef","isThreadStreaming","showNotificationBadge","isThreadActionPending","ThreadHistory","onThreadSelected","streamsByThreadId","threadLoadingState","editingId","setEditingId","setEditValue","isFetchingThreads","startEditing","currentTitle","commitEdit","handleEditKeyDown","handleDelete","handleSelectThread","ThreadHistoryPanel","isDarkMode","hideThreadHistory","userInitial","hasUsername","Chat","sendMessage","abortMessage","isLoadingThread","showWelcomeMessage","showFavoritePrompts","handleReload","lastUser","closeSidebar","scrollableClassNames","innerColumnClassNames","ELICITATION_ACTION","SAMPLING_ACTION","isModalsAvailable","modalsAPI","dialogsAPI","status","requestModalDialog","ioConnectApi","selectElicitation","mcp","custom","handleElicitationRequest","serverName","request","requestThreadId","buildResponse","validateElicitationRequest","getElicitationModalResponse","meta","getModalsApiResponse","getBuiltInPanelResponse","action","logMessage","showMcpAppReplaceModal","strings","wireMcpAppEvents","recreateModalOpen","chatMessageUnsubs","subscribeAppToChat","choice","oldUnsub","unsubs","unsub","selectSampling","handleSamplingRequest","getSamplingModalResponse","getSamplingResponse","formattedMessages","element","finalMessage","initIoAiWeb","IoAiWebFactory","ioApi","webConfig","buildWebConfig","listAgents","loadPrompts","loadTools","checkWorkingContext","toolsApi","buildMcpConfig","defaultAgentName","selected","fetchThreads","defaultPrompts","newCtx","useIoAiWebBootstrap","isIoConnectReady","appLoadingState","initialised","initIoConnect","setIoConnectApi","setIsIoConnectReady","setFavoritePromptNames","setIsDarkMode","applyAndSync","themeName","applyTheme","desktopConfig","browserConfig","themesApi","currentTheme","theme","prefs","useIoConnectBootstrap","IoAssist","IoAssistInner","LoadingScreen","ErrorScreen","onRetry"],"mappings":"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"}
|