@sqlrooms/ai-core 0.28.0-rc.0 → 0.28.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/dist/AiSlice.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
2
  import { createDefaultAiConfig, } from '@sqlrooms/ai-config';
3
- import { createSlice, useBaseRoomStore, } from '@sqlrooms/room-store';
3
+ import { createSlice, registerCommandsForOwner, unregisterCommandsForOwner, useBaseRoomStore, } from '@sqlrooms/room-store';
4
4
  import { produce } from 'immer';
5
5
  import { generateText, } from 'ai';
6
6
  import { createChatHandlers, createLocalChatTransportFactory, createRemoteChatTransportFactory, convertToAiSDKTools, } from './chatTransport';
@@ -8,6 +8,8 @@ import { ABORT_EVENT, AI_DEFAULT_TEMPERATURE, ANALYSIS_CANCELLED, ANALYSIS_PENDI
8
8
  import { hasAiSettingsConfig } from './hasAiSettingsConfig';
9
9
  import { cleanupPendingAnalysisResults, ToolAbortError, fixIncompleteToolCalls, } from './utils';
10
10
  import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
11
+ import { z } from 'zod';
12
+ const AI_COMMAND_OWNER = '@sqlrooms/ai-core';
11
13
  export function createAiSlice(params) {
12
14
  const { initialPrompt = '', tools, getApiKey, getBaseUrl, maxSteps = 50, getInstructions, defaultProvider = 'openai', defaultModel = 'gpt-4.1', getCustomModel, getProviderOptions, chatEndPoint = '', chatHeaders = {}, } = params;
13
15
  return createSlice((set, get, store) => {
@@ -59,6 +61,12 @@ export function createAiSlice(params) {
59
61
  }
60
62
  return {
61
63
  ai: {
64
+ initialize: async () => {
65
+ registerCommandsForOwner(store, AI_COMMAND_OWNER, createAiCommands());
66
+ },
67
+ destroy: async () => {
68
+ unregisterCommandsForOwner(store, AI_COMMAND_OWNER);
69
+ },
62
70
  config: baseConfig,
63
71
  promptSuggestionsVisible: true,
64
72
  apiKeyErrors: {},
@@ -722,6 +730,172 @@ function getCurrentSessionFromState(state) {
722
730
  const { currentSessionId, sessions } = state.ai.config;
723
731
  return sessions.find((session) => session.id === currentSessionId);
724
732
  }
733
+ const AiCreateSessionInput = z
734
+ .object({
735
+ name: z.string().optional().describe('Optional session name.'),
736
+ modelProvider: z
737
+ .string()
738
+ .optional()
739
+ .describe('Optional model provider ID.'),
740
+ model: z.string().optional().describe('Optional model ID.'),
741
+ })
742
+ .default({});
743
+ const AiSessionIdInput = z.object({
744
+ sessionId: z.string().describe('Target AI session ID.'),
745
+ });
746
+ const AiRenameSessionInput = z.object({
747
+ sessionId: z.string().describe('Target AI session ID.'),
748
+ name: z.string().min(1).describe('New session name.'),
749
+ });
750
+ function createAiCommands() {
751
+ const ensureSessionExists = (state, sessionId) => {
752
+ if (!state.ai.config.sessions.some((session) => session.id === sessionId)) {
753
+ throw new Error(`Unknown AI session "${sessionId}".`);
754
+ }
755
+ };
756
+ return [
757
+ {
758
+ id: 'ai.create-session',
759
+ name: 'Create AI session',
760
+ description: 'Start a new AI chat session',
761
+ group: 'AI',
762
+ keywords: ['ai', 'chat', 'session', 'new'],
763
+ inputSchema: AiCreateSessionInput,
764
+ inputDescription: 'Optionally provide name, modelProvider, and model for the new session.',
765
+ metadata: {
766
+ readOnly: false,
767
+ idempotent: false,
768
+ riskLevel: 'low',
769
+ },
770
+ execute: ({ getState }, input) => {
771
+ const { name, modelProvider, model } = input ?? {};
772
+ getState().ai.createSession(name, modelProvider, model);
773
+ return {
774
+ success: true,
775
+ commandId: 'ai.create-session',
776
+ message: 'Created AI session.',
777
+ };
778
+ },
779
+ },
780
+ {
781
+ id: 'ai.switch-session',
782
+ name: 'Switch AI session',
783
+ description: 'Switch current AI session by ID',
784
+ group: 'AI',
785
+ keywords: ['ai', 'chat', 'session', 'switch'],
786
+ inputSchema: AiSessionIdInput,
787
+ inputDescription: 'Provide sessionId to activate.',
788
+ metadata: {
789
+ readOnly: false,
790
+ idempotent: true,
791
+ riskLevel: 'low',
792
+ },
793
+ validateInput: (input, { getState }) => {
794
+ ensureSessionExists(getState(), input.sessionId);
795
+ },
796
+ execute: ({ getState }, input) => {
797
+ const { sessionId } = input;
798
+ getState().ai.switchSession(sessionId);
799
+ return {
800
+ success: true,
801
+ commandId: 'ai.switch-session',
802
+ message: `Switched to AI session "${sessionId}".`,
803
+ };
804
+ },
805
+ },
806
+ {
807
+ id: 'ai.rename-session',
808
+ name: 'Rename AI session',
809
+ description: 'Rename AI session by ID',
810
+ group: 'AI',
811
+ keywords: ['ai', 'chat', 'session', 'rename'],
812
+ inputSchema: AiRenameSessionInput,
813
+ inputDescription: 'Provide sessionId and new name.',
814
+ metadata: {
815
+ readOnly: false,
816
+ idempotent: true,
817
+ riskLevel: 'low',
818
+ },
819
+ validateInput: (input, { getState }) => {
820
+ ensureSessionExists(getState(), input.sessionId);
821
+ },
822
+ execute: ({ getState }, input) => {
823
+ const { sessionId, name } = input;
824
+ getState().ai.renameSession(sessionId, name);
825
+ return {
826
+ success: true,
827
+ commandId: 'ai.rename-session',
828
+ message: `Renamed AI session "${sessionId}".`,
829
+ };
830
+ },
831
+ },
832
+ {
833
+ id: 'ai.delete-session',
834
+ name: 'Delete AI session',
835
+ description: 'Delete AI session by ID',
836
+ group: 'AI',
837
+ keywords: ['ai', 'chat', 'session', 'delete'],
838
+ inputSchema: AiSessionIdInput,
839
+ inputDescription: 'Provide sessionId to delete.',
840
+ metadata: {
841
+ readOnly: false,
842
+ idempotent: true,
843
+ riskLevel: 'medium',
844
+ requiresConfirmation: true,
845
+ },
846
+ validateInput: (input, { getState }) => {
847
+ const state = getState();
848
+ const { sessionId } = input;
849
+ ensureSessionExists(state, sessionId);
850
+ if (state.ai.config.sessions.length <= 1) {
851
+ throw new Error('Cannot delete the last remaining AI session.');
852
+ }
853
+ },
854
+ execute: ({ getState }, input) => {
855
+ const { sessionId } = input;
856
+ getState().ai.deleteSession(sessionId);
857
+ return {
858
+ success: true,
859
+ commandId: 'ai.delete-session',
860
+ message: `Deleted AI session "${sessionId}".`,
861
+ };
862
+ },
863
+ },
864
+ {
865
+ id: 'ai.cancel-current-analysis',
866
+ name: 'Cancel current AI analysis',
867
+ description: 'Stop the currently running AI response',
868
+ group: 'AI',
869
+ keywords: ['ai', 'chat', 'cancel', 'stop', 'analysis'],
870
+ metadata: {
871
+ readOnly: false,
872
+ idempotent: true,
873
+ riskLevel: 'low',
874
+ },
875
+ isEnabled: ({ getState }) => {
876
+ const currentSession = getState().ai.getCurrentSession();
877
+ return Boolean(currentSession?.isRunning);
878
+ },
879
+ execute: ({ getState }) => {
880
+ const currentSession = getState().ai.getCurrentSession();
881
+ if (!currentSession) {
882
+ return {
883
+ success: false,
884
+ commandId: 'ai.cancel-current-analysis',
885
+ message: 'No active session.',
886
+ error: 'no active session',
887
+ };
888
+ }
889
+ getState().ai.cancelAnalysis(currentSession.id);
890
+ return {
891
+ success: true,
892
+ commandId: 'ai.cancel-current-analysis',
893
+ message: `Cancelled analysis for session "${currentSession.id}".`,
894
+ };
895
+ },
896
+ },
897
+ ];
898
+ }
725
899
  export function useStoreWithAi(selector) {
726
900
  return useBaseRoomStore((state) => selector(state));
727
901
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AiSlice.js","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n AiSliceConfig,\n AnalysisResultSchema,\n AnalysisSessionSchema,\n createDefaultAiConfig,\n} from '@sqlrooms/ai-config';\nimport {\n createSlice,\n useBaseRoomStore,\n type StateCreator,\n} from '@sqlrooms/room-store';\nimport {produce} from 'immer';\nimport {\n UIMessage,\n DefaultChatTransport,\n LanguageModel,\n ChatOnDataCallback,\n generateText,\n} from 'ai';\nimport {\n createChatHandlers,\n createLocalChatTransportFactory,\n createRemoteChatTransportFactory,\n ToolCall,\n convertToAiSDKTools,\n} from './chatTransport';\nimport {\n ABORT_EVENT,\n AI_DEFAULT_TEMPERATURE,\n ANALYSIS_CANCELLED,\n ANALYSIS_PENDING_ID,\n SESSION_DELETED,\n TOOL_CALL_CANCELLED,\n} from './constants';\nimport {hasAiSettingsConfig} from './hasAiSettingsConfig';\nimport {OpenAssistantToolSet} from '@openassistant/utils';\nimport type {\n AddToolResult,\n AiChatSendMessage,\n GetProviderOptions,\n} from './types';\nimport {\n cleanupPendingAnalysisResults,\n ToolAbortError,\n fixIncompleteToolCalls,\n} from './utils';\nimport {createOpenAICompatible} from '@ai-sdk/openai-compatible';\n\nexport type AiSliceState = {\n ai: {\n config: AiSliceConfig;\n promptSuggestionsVisible: boolean;\n /** Tracks API key errors per provider (e.g., 401/403 responses) */\n apiKeyErrors: Record<string, boolean>;\n tools: OpenAssistantToolSet;\n getProviderOptions?: GetProviderOptions;\n setConfig: (config: AiSliceConfig) => void;\n setPromptSuggestionsVisible: (visible: boolean) => void;\n /** Set API key error flag for a provider */\n setApiKeyError: (provider: string, hasError: boolean) => void;\n /** Check if there's an API key error for the current provider */\n hasApiKeyError: () => boolean;\n getAbortController: (sessionId: string) => AbortController | undefined;\n setAbortController: (\n sessionId: string,\n controller: AbortController | undefined,\n ) => void;\n setChatStop: (sessionId: string, stop: (() => void) | undefined) => void;\n getChatStop: (sessionId: string) => (() => void) | undefined;\n setChatSendMessage: (\n sessionId: string,\n sendMessage: AiChatSendMessage | undefined,\n ) => void;\n getChatSendMessage: (sessionId: string) => AiChatSendMessage | undefined;\n setAddToolResult: (\n sessionId: string,\n addToolResult: AddToolResult | undefined,\n ) => void;\n getAddToolResult: (sessionId: string) => AddToolResult | undefined;\n waitForToolResult: (\n sessionId: string,\n toolCallId: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n /** Map toolCallId -> sessionId for long-running tool streams (e.g. agent tools) */\n setToolCallSession: (\n toolCallId: string,\n sessionId: string | undefined,\n ) => void;\n getToolCallSession: (toolCallId: string) => string | undefined;\n setPrompt: (sessionId: string, prompt: string) => void;\n getPrompt: (sessionId: string) => string;\n setIsRunning: (sessionId: string, isRunning: boolean) => void;\n getIsRunning: (sessionId: string) => boolean;\n addAnalysisResult: (message: UIMessage) => void;\n sendPrompt: (\n prompt: string,\n options?: {\n systemInstructions?: string;\n modelProvider?: string;\n modelName?: string;\n baseUrl?: string;\n abortSignal?: AbortSignal;\n useTools?: boolean;\n },\n ) => Promise<string>;\n startAnalysis: (sessionId: string) => Promise<void>;\n cancelAnalysis: (sessionId: string) => void;\n setAiModel: (modelProvider: string, model: string) => void;\n createSession: (\n name?: string,\n modelProvider?: string,\n model?: string,\n ) => void;\n switchSession: (sessionId: string) => void;\n renameSession: (sessionId: string, name: string) => void;\n deleteSession: (sessionId: string) => void;\n setOpenSessionTabs: (tabs: string[]) => void;\n getCurrentSession: () => AnalysisSessionSchema | undefined;\n setSessionUiMessages: (sessionId: string, uiMessages: UIMessage[]) => void;\n setSessionToolAdditionalData: (\n sessionId: string,\n toolCallId: string,\n additionalData: unknown,\n ) => void;\n getAnalysisResults: () => AnalysisResultSchema[] | undefined;\n deleteAnalysisResult: (sessionId: string, resultId: string) => void;\n getAssistantMessageParts: (analysisResultId: string) => UIMessage['parts'];\n findToolComponent: (toolName: string) => React.ComponentType | undefined;\n getApiKeyFromSettings: () => string;\n getBaseUrlFromSettings: () => string | undefined;\n getMaxStepsFromSettings: () => number;\n getFullInstructions: () => string;\n getLocalChatTransport: (\n sessionId: string,\n ) => DefaultChatTransport<UIMessage>;\n /** Optional remote endpoint to use for chat; if empty, local transport is used */\n chatEndPoint: string;\n chatHeaders: Record<string, string>;\n getRemoteChatTransport: (\n sessionId: string,\n endpoint: string,\n headers?: Record<string, string>,\n ) => DefaultChatTransport<UIMessage>;\n onChatFinish: (args: {\n sessionId: string;\n messages: UIMessage[];\n isError?: boolean;\n }) => void;\n onChatToolCall: (args: {\n sessionId: string;\n toolCall: ToolCall;\n addToolResult?: AddToolResult;\n }) => Promise<void> | void;\n onChatData: (\n sessionId: string,\n dataPart: Parameters<ChatOnDataCallback<UIMessage>>[0],\n ) => void;\n onChatError: (sessionId: string, error: unknown) => void;\n };\n};\n\n/**\n * Configuration options for creating an AI slice\n */\nexport interface AiSliceOptions {\n config?: Partial<AiSliceConfig>;\n initialPrompt?: string;\n tools: OpenAssistantToolSet;\n getInstructions: () => string;\n defaultProvider?: string;\n defaultModel?: string;\n /** Provide a pre-configured model client for a provider (e.g., Azure). */\n getCustomModel?: () => LanguageModel | undefined;\n getProviderOptions?: GetProviderOptions;\n maxSteps?: number;\n getApiKey?: (modelProvider: string) => string;\n getBaseUrl?: () => string;\n /** Optional remote endpoint to use for chat; if empty, local transport is used */\n chatEndPoint?: string;\n /** Optional headers to send with remote endpoint */\n chatHeaders?: Record<string, string>;\n}\n\nexport function createAiSlice(\n params: AiSliceOptions,\n): StateCreator<AiSliceState> {\n const {\n initialPrompt = '',\n tools,\n getApiKey,\n getBaseUrl,\n maxSteps = 50,\n getInstructions,\n defaultProvider = 'openai',\n defaultModel = 'gpt-4.1',\n getCustomModel,\n getProviderOptions,\n chatEndPoint = '',\n chatHeaders = {},\n } = params;\n\n return createSlice<AiSliceState>((set, get, store) => {\n // Clean up pending analysis results from persisted config\n const cleanedConfig = params.config?.sessions\n ? {\n ...params.config,\n sessions: params.config.sessions.map((session) => {\n const cleaned = cleanupPendingAnalysisResults(session);\n const completedUiMessages = Array.isArray(cleaned.uiMessages)\n ? fixIncompleteToolCalls(\n (cleaned.uiMessages as unknown as UIMessage[]) || [],\n )\n : [];\n return {\n ...cleaned,\n uiMessages:\n completedUiMessages as unknown as AnalysisSessionSchema['uiMessages'],\n };\n }),\n }\n : params.config;\n\n // Create persistent Maps (outside of immer draft)\n const pendingToolCallResolvers = new Map<\n string,\n {resolve: () => void; reject: (error: Error) => void}\n >();\n\n const toolCallToSessionId = new Map<string, string>();\n const sessionAbortControllers = new Map<string, AbortController>();\n const sessionChatStops = new Map<string, () => void>();\n const sessionChatSendMessages = new Map<string, AiChatSendMessage>();\n const sessionAddToolResults = new Map<string, AddToolResult>();\n\n // Initialize base config and ensure the initial session respects default provider/model\n const baseConfig = createDefaultAiConfig(cleanedConfig);\n if (!cleanedConfig?.sessions || cleanedConfig.sessions.length === 0) {\n const firstSession = baseConfig.sessions[0];\n if (firstSession) {\n firstSession.modelProvider = defaultProvider;\n firstSession.model = defaultModel;\n firstSession.prompt = initialPrompt;\n firstSession.isRunning = false;\n }\n }\n\n // Clean up openSessionTabs for sessions that no longer exist and ensure it's initialized\n const sessionIdSet = new Set(baseConfig.sessions.map((s) => s.id));\n if (baseConfig.openSessionTabs && baseConfig.openSessionTabs.length > 0) {\n baseConfig.openSessionTabs = baseConfig.openSessionTabs.filter((id) =>\n sessionIdSet.has(id),\n );\n }\n // Ensure openSessionTabs is initialized with current session if empty/missing\n if (\n !baseConfig.openSessionTabs ||\n baseConfig.openSessionTabs.length === 0\n ) {\n baseConfig.openSessionTabs = baseConfig.currentSessionId\n ? [baseConfig.currentSessionId]\n : [];\n }\n\n return {\n ai: {\n config: baseConfig,\n promptSuggestionsVisible: true,\n apiKeyErrors: {},\n tools,\n getProviderOptions,\n waitForToolResult: (\n sessionId: string,\n toolCallId: string,\n abortSignal?: AbortSignal,\n ) => {\n const key = `${sessionId}:${toolCallId}`;\n return new Promise<void>((resolve, reject) => {\n // Set up abort handler\n const abortHandler = () => {\n const resolver = pendingToolCallResolvers.get(key);\n if (resolver) {\n pendingToolCallResolvers.delete(key);\n resolver.reject(new Error(TOOL_CALL_CANCELLED));\n }\n };\n\n if (abortSignal) {\n if (abortSignal.aborted) {\n reject(new Error(TOOL_CALL_CANCELLED));\n return;\n }\n abortSignal.addEventListener(ABORT_EVENT, abortHandler, {\n once: true,\n });\n }\n\n // Store resolver (overwrites any existing one, which is fine for our use case)\n pendingToolCallResolvers.set(key, {\n resolve: () => {\n if (abortSignal) {\n abortSignal.removeEventListener(ABORT_EVENT, abortHandler);\n }\n pendingToolCallResolvers.delete(key);\n resolve();\n },\n reject: (error: Error) => {\n if (abortSignal) {\n abortSignal.removeEventListener(ABORT_EVENT, abortHandler);\n }\n pendingToolCallResolvers.delete(key);\n reject(error);\n },\n });\n });\n },\n\n setToolCallSession: (\n toolCallId: string,\n sessionId: string | undefined,\n ) => {\n if (!toolCallId) return;\n if (sessionId) {\n toolCallToSessionId.set(toolCallId, sessionId);\n } else {\n toolCallToSessionId.delete(toolCallId);\n }\n },\n getToolCallSession: (toolCallId: string) => {\n if (!toolCallId) return undefined;\n return toolCallToSessionId.get(toolCallId);\n },\n\n getAbortController: (sessionId: string) => {\n return sessionAbortControllers.get(sessionId);\n },\n setAbortController: (\n sessionId: string,\n controller: AbortController | undefined,\n ) => {\n if (controller) {\n sessionAbortControllers.set(sessionId, controller);\n } else {\n sessionAbortControllers.delete(sessionId);\n }\n },\n\n setChatStop: (sessionId: string, stopFn: (() => void) | undefined) => {\n if (stopFn) {\n sessionChatStops.set(sessionId, stopFn);\n } else {\n sessionChatStops.delete(sessionId);\n }\n },\n getChatStop: (sessionId: string) => {\n return sessionChatStops.get(sessionId);\n },\n\n setChatSendMessage: (\n sessionId: string,\n sendMessageFn: AiChatSendMessage | undefined,\n ) => {\n if (sendMessageFn) {\n sessionChatSendMessages.set(sessionId, sendMessageFn);\n } else {\n sessionChatSendMessages.delete(sessionId);\n }\n },\n getChatSendMessage: (sessionId: string) => {\n return sessionChatSendMessages.get(sessionId);\n },\n\n setAddToolResult: (\n sessionId: string,\n addToolResultFn: AddToolResult | undefined,\n ) => {\n if (addToolResultFn) {\n // Wrap addToolResult to intercept calls and resolve pending promises\n const wrappedAddToolResult: AddToolResult = (options) => {\n addToolResultFn(options);\n const key = `${sessionId}:${options.toolCallId}`;\n const resolver = pendingToolCallResolvers.get(key);\n if (resolver) {\n resolver.resolve();\n }\n // Tool is complete (success or error), we can drop toolCall->session mapping.\n toolCallToSessionId.delete(options.toolCallId);\n };\n sessionAddToolResults.set(sessionId, wrappedAddToolResult);\n } else {\n sessionAddToolResults.delete(sessionId);\n }\n },\n getAddToolResult: (sessionId: string) => {\n return sessionAddToolResults.get(sessionId);\n },\n\n setConfig: (config: AiSliceConfig) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.config = config;\n }),\n );\n },\n\n setPromptSuggestionsVisible: (visible: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.promptSuggestionsVisible = visible;\n }),\n );\n },\n\n setApiKeyError: (provider: string, hasError: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n if (hasError) {\n draft.ai.apiKeyErrors[provider] = true;\n } else {\n delete draft.ai.apiKeyErrors[provider];\n }\n }),\n );\n },\n\n hasApiKeyError: () => {\n const state = get();\n const currentSession = state.ai.getCurrentSession();\n const provider = currentSession?.modelProvider || defaultProvider;\n return Boolean(state.ai.apiKeyErrors[provider]);\n },\n\n setPrompt: (sessionId: string, prompt: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.prompt = prompt;\n }\n }),\n );\n },\n getPrompt: (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n return session?.prompt || '';\n },\n\n setIsRunning: (sessionId: string, isRunning: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.isRunning = isRunning;\n }\n }),\n );\n },\n getIsRunning: (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n return session?.isRunning || false;\n },\n\n /**\n * Set the AI model for the current session\n * @param model - The model to set\n */\n setAiModel: (modelProvider: string, model: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.modelProvider = modelProvider;\n currentSession.model = model;\n }\n }),\n );\n },\n\n /**\n * Get the current active session\n */\n getCurrentSession: () => {\n const state = get();\n const {currentSessionId, sessions} = state.ai.config;\n return sessions.find((session) => session.id === currentSessionId);\n },\n\n /**\n * Create a new session with the given name and model settings\n */\n createSession: (\n name?: string,\n modelProvider?: string,\n model?: string,\n ) => {\n const currentSession = get().ai.getCurrentSession();\n const newSessionId = createId();\n\n // Generate a default name if none is provided\n let sessionName = name;\n if (!sessionName) {\n // Generate a human-readable date and time for the session name\n const now = new Date();\n const formattedDate = now.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n const formattedTime = now.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: 'numeric',\n hour12: true,\n });\n sessionName = `Session ${formattedDate} at ${formattedTime}`;\n }\n\n set((state) =>\n produce(state, (draft) => {\n const now = Date.now();\n // Add to AI sessions with per-session state\n draft.ai.config.sessions.unshift({\n id: newSessionId,\n name: sessionName,\n modelProvider:\n modelProvider ||\n currentSession?.modelProvider ||\n defaultProvider,\n model: model || currentSession?.model || defaultModel,\n analysisResults: [],\n createdAt: new Date(),\n uiMessages: [],\n toolAdditionalData: {},\n messagesRevision: 0,\n prompt: '',\n isRunning: false,\n lastOpenedAt: now,\n });\n draft.ai.config.currentSessionId = newSessionId;\n // Add new session to open tabs\n if (!draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs = [];\n }\n draft.ai.config.openSessionTabs.push(newSessionId);\n }),\n );\n },\n\n /**\n * Switch to a different session\n */\n switchSession: (sessionId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const now = Date.now();\n draft.ai.config.currentSessionId = sessionId;\n // Ensure current session is always in openSessionTabs\n if (!draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs = [];\n }\n if (!draft.ai.config.openSessionTabs.includes(sessionId)) {\n draft.ai.config.openSessionTabs.push(sessionId);\n }\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.lastOpenedAt = now;\n }\n }),\n );\n },\n\n /**\n * Set the list of open session tab IDs\n */\n setOpenSessionTabs: (tabs: string[]) => {\n set((state) =>\n produce(state, (draft) => {\n // Filter out any tabs for sessions that no longer exist\n const sessionIdSet = new Set(\n draft.ai.config.sessions.map((s) => s.id),\n );\n draft.ai.config.openSessionTabs = tabs.filter((id) =>\n sessionIdSet.has(id),\n );\n }),\n );\n },\n\n /**\n * Rename an existing session\n */\n renameSession: (sessionId: string, name: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.name = name;\n }\n }),\n );\n },\n\n /**\n * Delete a session and clean up its resources\n */\n deleteSession: (sessionId: string) => {\n // Clean up per-session state\n const abortController = sessionAbortControllers.get(sessionId);\n if (abortController) {\n abortController.abort(SESSION_DELETED);\n }\n sessionAbortControllers.delete(sessionId);\n sessionChatStops.delete(sessionId);\n sessionChatSendMessages.delete(sessionId);\n sessionAddToolResults.delete(sessionId);\n const now = Date.now();\n\n set((state) =>\n produce(state, (draft) => {\n const sessionIndex = draft.ai.config.sessions.findIndex(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (sessionIndex !== -1) {\n // Don't delete the last session\n if (draft.ai.config.sessions.length > 1) {\n draft.ai.config.sessions.splice(sessionIndex, 1);\n // Remove from open tabs\n if (draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs =\n draft.ai.config.openSessionTabs.filter(\n (id) => id !== sessionId,\n );\n }\n // If we deleted the current session, switch to another one\n if (draft.ai.config.currentSessionId === sessionId) {\n // Make sure there's at least one session before accessing its id\n if (draft.ai.config.sessions.length > 0) {\n const firstSession = draft.ai.config.sessions[0];\n if (firstSession) {\n draft.ai.config.currentSessionId = firstSession.id;\n firstSession.lastOpenedAt = now;\n }\n }\n }\n }\n }\n }),\n );\n },\n\n /**\n * Save the Ai SDK UI messages for a session\n */\n setSessionUiMessages: (sessionId: string, uiMessages: UIMessage[]) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n // store the latest UI messages from the chat hook\n // Create a deep copy to avoid read-only property issues\n session.uiMessages = JSON.parse(JSON.stringify(uiMessages));\n }\n }),\n );\n },\n\n /**\n * Save additional data for a session\n */\n setSessionToolAdditionalData: (\n sessionId: string,\n toolCallId: string,\n additionalData: unknown,\n ) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n if (!session.toolAdditionalData) {\n session.toolAdditionalData = {};\n }\n session.toolAdditionalData[toolCallId] = additionalData;\n }\n }),\n );\n },\n\n findToolComponent: (toolName: string) => {\n return get().ai.tools[toolName]?.component as React.ComponentType;\n },\n\n getBaseUrlFromSettings: () => {\n // First try the getBaseUrl function if provided\n const baseUrlFromFunction = getBaseUrl?.();\n if (baseUrlFromFunction) {\n return baseUrlFromFunction;\n }\n\n // Fall back to settings\n const store = get();\n if (hasAiSettingsConfig(store)) {\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.baseUrl;\n }\n const provider =\n store.aiSettings.config.providers[currentSession.modelProvider];\n return provider?.baseUrl;\n }\n }\n return undefined;\n },\n\n getApiKeyFromSettings: () => {\n const store = get();\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n // First try the getApiKey function if provided\n const apiKeyFromFunction = getApiKey?.(\n currentSession.modelProvider || 'openai',\n );\n if (apiKeyFromFunction) {\n return apiKeyFromFunction;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.apiKey || '';\n } else {\n const provider =\n store.aiSettings.config.providers?.[\n currentSession.modelProvider\n ];\n return provider?.apiKey || '';\n }\n }\n }\n return '';\n },\n\n getMaxStepsFromSettings: () => {\n const store = get();\n // First try the maxSteps parameter if provided\n if (maxSteps && Number.isFinite(maxSteps) && maxSteps > 0) {\n return maxSteps;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n const settingsMaxSteps =\n store.aiSettings.config.modelParameters.maxSteps;\n if (Number.isFinite(settingsMaxSteps) && settingsMaxSteps > 0) {\n return settingsMaxSteps;\n }\n }\n return 50;\n },\n\n getFullInstructions: () => {\n const store = get();\n\n let instructions = getInstructions();\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n // get additional instructions from settings\n const {additionalInstruction} =\n store.aiSettings.config.modelParameters;\n if (additionalInstruction) {\n instructions = `${instructions}\\n\\nAdditional Instructions:\\n\\n${additionalInstruction}`;\n }\n }\n return instructions;\n },\n\n sendPrompt: async (\n prompt: string,\n options: {\n systemInstructions?: string;\n modelProvider?: string;\n modelName?: string;\n baseUrl?: string;\n useTools?: boolean;\n abortSignal?: AbortSignal;\n } = {},\n ) => {\n // One-shot generateText path with explicit abort lifecycle management\n const state = get();\n const currentSession = state.ai.getCurrentSession(); // only used when no model provider is provided\n const {\n systemInstructions,\n modelProvider,\n modelName,\n baseUrl,\n abortSignal,\n useTools = false,\n } = options;\n\n if (abortSignal?.aborted) {\n throw new ToolAbortError(TOOL_CALL_CANCELLED);\n }\n\n const provider =\n modelProvider || currentSession?.modelProvider || defaultProvider;\n const modelId = modelName || currentSession?.model || defaultModel;\n const baseURL = baseUrl ?? state.ai.getBaseUrlFromSettings() ?? '';\n const tools = state.ai.tools;\n\n const toolsWithoutExecute = Object.fromEntries(\n Object.entries(tools).filter(([, tool]) => !tool.execute),\n );\n\n const model = createOpenAICompatible({\n apiKey: state.ai.getApiKeyFromSettings(),\n name: provider,\n baseURL,\n }).chatModel(modelId);\n\n try {\n const response = await generateText({\n model,\n temperature: AI_DEFAULT_TEMPERATURE,\n messages: [{role: 'user', content: prompt}],\n system: systemInstructions || state.ai.getFullInstructions(),\n abortSignal: abortSignal,\n ...(useTools\n ? {tools: convertToAiSDKTools(toolsWithoutExecute)}\n : {}),\n });\n return response.text;\n } catch (error) {\n const errorName =\n typeof error === 'object' && error && 'name' in error\n ? String((error as {name?: unknown}).name)\n : '';\n if (abortSignal?.aborted || errorName === 'AbortError') {\n throw new ToolAbortError(TOOL_CALL_CANCELLED);\n }\n console.error('Error generating text:', error);\n return 'error: can not generate response';\n }\n },\n\n /**\n * Start the analysis for a specific session\n */\n startAnalysis: async (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n\n if (!session) {\n console.error('Session not found:', sessionId);\n return;\n }\n\n const sendMessage = state.ai.getChatSendMessage(sessionId);\n if (!sendMessage) {\n console.error(\n 'No sendMessage function found for session:',\n sessionId,\n );\n return;\n }\n\n const abortController = new AbortController();\n const promptText = session.prompt || '';\n\n // Store abort controller for this session\n state.ai.setAbortController(sessionId, abortController);\n\n set((stateToUpdate) =>\n produce(stateToUpdate, (draft) => {\n const draftSession = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (draftSession) {\n draftSession.isRunning = true;\n draftSession.prompt = '';\n draft.ai.promptSuggestionsVisible = false;\n\n // Remove any existing pending results\n draftSession.analysisResults =\n draftSession.analysisResults.filter(\n (result: AnalysisResultSchema) =>\n result.id !== ANALYSIS_PENDING_ID,\n );\n\n // Add incomplete analysis result with a temporary ID\n draftSession.analysisResults.push({\n id: ANALYSIS_PENDING_ID,\n prompt: promptText,\n isCompleted: false,\n });\n }\n }),\n );\n\n // Send the message through the session's chat instance\n sendMessage({text: promptText});\n },\n\n cancelAnalysis: (sessionId: string) => {\n const state = get();\n const abortController = state.ai.getAbortController(sessionId);\n const stopFn = state.ai.getChatStop(sessionId);\n\n // Stop local chat streaming immediately if available\n stopFn?.();\n\n abortController?.abort(ANALYSIS_CANCELLED);\n\n set((stateToUpdate) =>\n produce(stateToUpdate, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.isRunning = false;\n }\n // Keep abort controller so handlers can check signal.aborted\n // It will be cleared by onChatFinish\n }),\n );\n },\n\n /**\n * Get the assistant message parts for a given analysis result ID\n * @param analysisResultId - The ID of the analysis result (user message ID)\n * @returns Array of message parts from the assistant's response\n */\n getAssistantMessageParts: (analysisResultId: string) => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) return [];\n\n const uiMessages = currentSession.uiMessages as UIMessage[];\n // Find the user message with analysisResultId\n const userMessageIndex = uiMessages.findIndex(\n (msg) => msg.id === analysisResultId && msg.role === 'user',\n );\n if (userMessageIndex === -1) return [];\n\n // Find the next assistant message after this user message\n for (let i = userMessageIndex + 1; i < uiMessages.length; i++) {\n const msg = uiMessages[i];\n if (msg?.role === 'assistant') {\n return msg.parts;\n }\n if (msg?.role === 'user') {\n // Hit next user message without finding assistant response\n break;\n }\n }\n return [];\n },\n\n /**\n * Delete an analysis result from a session\n * - remove the corresponding prompt-response pair from uiMessages\n * - remove the associated toolAdditionalData\n */\n deleteAnalysisResult: (sessionId: string, resultId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.analysisResults = session.analysisResults.filter(\n (r: AnalysisResultSchema) => r.id !== resultId,\n );\n // Remove corresponding prompt-response pair from uiMessages\n const uiMessages = session.uiMessages as UIMessage[];\n const userMessageIndex = uiMessages.findIndex(\n (msg) => msg.id === resultId && msg.role === 'user',\n );\n\n if (userMessageIndex !== -1) {\n // Find the next user message (or end of array) to determine response boundary\n let nextUserIndex = userMessageIndex + 1;\n const toolCallIdsToDelete: Set<string> = new Set();\n\n while (\n nextUserIndex < uiMessages.length &&\n uiMessages[nextUserIndex]?.role !== 'user'\n ) {\n const msg = uiMessages[nextUserIndex];\n // Extract toolCallId from message parts\n if (msg?.parts) {\n for (const part of msg.parts) {\n // Check for tool-* or dynamic-tool parts that have toolCallId\n if (\n 'toolCallId' in part &&\n typeof part.toolCallId === 'string'\n ) {\n toolCallIdsToDelete.add(part.toolCallId);\n }\n }\n }\n nextUserIndex++;\n }\n\n // Remove the user message and all assistant messages until the next user message\n session.uiMessages.splice(\n userMessageIndex,\n nextUserIndex - userMessageIndex,\n );\n\n // Increment messagesRevision to force useChat reset\n session.messagesRevision =\n (session.messagesRevision || 0) + 1;\n\n // Clean up toolAdditionalData for deleted messages\n if (session.toolAdditionalData) {\n // Remove data keyed by the toolCallId from the deleted messages\n toolCallIdsToDelete.forEach((toolCallId) => {\n if (session.toolAdditionalData![toolCallId]) {\n delete session.toolAdditionalData![toolCallId];\n }\n });\n }\n }\n }\n }),\n );\n },\n\n /**\n * Get analysis results for the current session by transforming UI messages\n * into structured analysis results (user prompt → AI response pairs).\n *\n * @returns Array of analysis results for the current session\n */\n getAnalysisResults: () => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) return undefined;\n\n return currentSession.analysisResults;\n },\n\n /**\n * Add an analysis result to the current session\n * - add the message to the uiMessages\n * - add the analysis result to the analysisResults\n */\n addAnalysisResult: (message: UIMessage) => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n set((state) =>\n produce(state, (draft) => {\n // Extract text content from message parts\n const textContent =\n message.parts\n ?.filter((part) => part.type === 'text')\n ?.map((part) => (part as {text: string}).text)\n ?.join('') || '';\n\n draft.ai.config.sessions\n .find((s: AnalysisSessionSchema) => s.id === currentSession?.id)\n ?.analysisResults.push({\n id: message.id,\n prompt: textContent,\n isCompleted: true,\n });\n }),\n );\n },\n\n // Chat transport configuration\n chatEndPoint,\n chatHeaders,\n\n getLocalChatTransport: (sessionId: string) => {\n return createLocalChatTransportFactory({\n store,\n defaultProvider: defaultProvider,\n defaultModel: defaultModel,\n getInstructions: () => store.getState().ai.getFullInstructions(),\n getCustomModel,\n sessionId,\n })();\n },\n\n getRemoteChatTransport: (\n sessionId: string,\n endpoint: string,\n headers?: Record<string, string>,\n ) =>\n createRemoteChatTransportFactory({\n store,\n defaultProvider,\n defaultModel,\n sessionId,\n })(endpoint, headers),\n\n ...createChatHandlers({store}),\n },\n };\n });\n}\n\n/**\n * Helper function to get the current session from state\n */\nfunction getCurrentSessionFromState(\n state: AiSliceState,\n): AnalysisSessionSchema | undefined {\n const {currentSessionId, sessions} = state.ai.config;\n return sessions.find((session) => session.id === currentSessionId);\n}\n\nexport function useStoreWithAi<T>(selector: (state: AiSliceState) => T): T {\n return useBaseRoomStore<AiSliceState, T>((state) => selector(state));\n}\n"]}
1
+ {"version":3,"file":"AiSlice.js","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n AiSliceConfig,\n AnalysisResultSchema,\n AnalysisSessionSchema,\n createDefaultAiConfig,\n} from '@sqlrooms/ai-config';\nimport {\n BaseRoomStoreState,\n createSlice,\n registerCommandsForOwner,\n RoomCommand,\n unregisterCommandsForOwner,\n useBaseRoomStore,\n type StateCreator,\n} from '@sqlrooms/room-store';\nimport {produce} from 'immer';\nimport {\n UIMessage,\n DefaultChatTransport,\n LanguageModel,\n ChatOnDataCallback,\n generateText,\n} from 'ai';\nimport {\n createChatHandlers,\n createLocalChatTransportFactory,\n createRemoteChatTransportFactory,\n ToolCall,\n convertToAiSDKTools,\n} from './chatTransport';\nimport {\n ABORT_EVENT,\n AI_DEFAULT_TEMPERATURE,\n ANALYSIS_CANCELLED,\n ANALYSIS_PENDING_ID,\n SESSION_DELETED,\n TOOL_CALL_CANCELLED,\n} from './constants';\nimport {hasAiSettingsConfig} from './hasAiSettingsConfig';\nimport {OpenAssistantToolSet} from '@openassistant/utils';\nimport type {\n AddToolResult,\n AiChatSendMessage,\n GetProviderOptions,\n} from './types';\nimport {\n cleanupPendingAnalysisResults,\n ToolAbortError,\n fixIncompleteToolCalls,\n} from './utils';\nimport {createOpenAICompatible} from '@ai-sdk/openai-compatible';\nimport {z} from 'zod';\n\nconst AI_COMMAND_OWNER = '@sqlrooms/ai-core';\n\nexport type AiSliceState = {\n ai: {\n initialize?: () => Promise<void>;\n destroy?: () => Promise<void>;\n config: AiSliceConfig;\n promptSuggestionsVisible: boolean;\n /** Tracks API key errors per provider (e.g., 401/403 responses) */\n apiKeyErrors: Record<string, boolean>;\n tools: OpenAssistantToolSet;\n getProviderOptions?: GetProviderOptions;\n setConfig: (config: AiSliceConfig) => void;\n setPromptSuggestionsVisible: (visible: boolean) => void;\n /** Set API key error flag for a provider */\n setApiKeyError: (provider: string, hasError: boolean) => void;\n /** Check if there's an API key error for the current provider */\n hasApiKeyError: () => boolean;\n getAbortController: (sessionId: string) => AbortController | undefined;\n setAbortController: (\n sessionId: string,\n controller: AbortController | undefined,\n ) => void;\n setChatStop: (sessionId: string, stop: (() => void) | undefined) => void;\n getChatStop: (sessionId: string) => (() => void) | undefined;\n setChatSendMessage: (\n sessionId: string,\n sendMessage: AiChatSendMessage | undefined,\n ) => void;\n getChatSendMessage: (sessionId: string) => AiChatSendMessage | undefined;\n setAddToolResult: (\n sessionId: string,\n addToolResult: AddToolResult | undefined,\n ) => void;\n getAddToolResult: (sessionId: string) => AddToolResult | undefined;\n waitForToolResult: (\n sessionId: string,\n toolCallId: string,\n abortSignal?: AbortSignal,\n ) => Promise<void>;\n /** Map toolCallId -> sessionId for long-running tool streams (e.g. agent tools) */\n setToolCallSession: (\n toolCallId: string,\n sessionId: string | undefined,\n ) => void;\n getToolCallSession: (toolCallId: string) => string | undefined;\n setPrompt: (sessionId: string, prompt: string) => void;\n getPrompt: (sessionId: string) => string;\n setIsRunning: (sessionId: string, isRunning: boolean) => void;\n getIsRunning: (sessionId: string) => boolean;\n addAnalysisResult: (message: UIMessage) => void;\n sendPrompt: (\n prompt: string,\n options?: {\n systemInstructions?: string;\n modelProvider?: string;\n modelName?: string;\n baseUrl?: string;\n abortSignal?: AbortSignal;\n useTools?: boolean;\n },\n ) => Promise<string>;\n startAnalysis: (sessionId: string) => Promise<void>;\n cancelAnalysis: (sessionId: string) => void;\n setAiModel: (modelProvider: string, model: string) => void;\n createSession: (\n name?: string,\n modelProvider?: string,\n model?: string,\n ) => void;\n switchSession: (sessionId: string) => void;\n renameSession: (sessionId: string, name: string) => void;\n deleteSession: (sessionId: string) => void;\n setOpenSessionTabs: (tabs: string[]) => void;\n getCurrentSession: () => AnalysisSessionSchema | undefined;\n setSessionUiMessages: (sessionId: string, uiMessages: UIMessage[]) => void;\n setSessionToolAdditionalData: (\n sessionId: string,\n toolCallId: string,\n additionalData: unknown,\n ) => void;\n getAnalysisResults: () => AnalysisResultSchema[] | undefined;\n deleteAnalysisResult: (sessionId: string, resultId: string) => void;\n getAssistantMessageParts: (analysisResultId: string) => UIMessage['parts'];\n findToolComponent: (toolName: string) => React.ComponentType | undefined;\n getApiKeyFromSettings: () => string;\n getBaseUrlFromSettings: () => string | undefined;\n getMaxStepsFromSettings: () => number;\n getFullInstructions: () => string;\n getLocalChatTransport: (\n sessionId: string,\n ) => DefaultChatTransport<UIMessage>;\n /** Optional remote endpoint to use for chat; if empty, local transport is used */\n chatEndPoint: string;\n chatHeaders: Record<string, string>;\n getRemoteChatTransport: (\n sessionId: string,\n endpoint: string,\n headers?: Record<string, string>,\n ) => DefaultChatTransport<UIMessage>;\n onChatFinish: (args: {\n sessionId: string;\n messages: UIMessage[];\n isError?: boolean;\n }) => void;\n onChatToolCall: (args: {\n sessionId: string;\n toolCall: ToolCall;\n addToolResult?: AddToolResult;\n }) => Promise<void> | void;\n onChatData: (\n sessionId: string,\n dataPart: Parameters<ChatOnDataCallback<UIMessage>>[0],\n ) => void;\n onChatError: (sessionId: string, error: unknown) => void;\n };\n};\n\n/**\n * Configuration options for creating an AI slice\n */\nexport interface AiSliceOptions {\n config?: Partial<AiSliceConfig>;\n initialPrompt?: string;\n tools: OpenAssistantToolSet;\n getInstructions: () => string;\n defaultProvider?: string;\n defaultModel?: string;\n /** Provide a pre-configured model client for a provider (e.g., Azure). */\n getCustomModel?: () => LanguageModel | undefined;\n getProviderOptions?: GetProviderOptions;\n maxSteps?: number;\n getApiKey?: (modelProvider: string) => string;\n getBaseUrl?: () => string;\n /** Optional remote endpoint to use for chat; if empty, local transport is used */\n chatEndPoint?: string;\n /** Optional headers to send with remote endpoint */\n chatHeaders?: Record<string, string>;\n}\n\nexport function createAiSlice(\n params: AiSliceOptions,\n): StateCreator<AiSliceState> {\n const {\n initialPrompt = '',\n tools,\n getApiKey,\n getBaseUrl,\n maxSteps = 50,\n getInstructions,\n defaultProvider = 'openai',\n defaultModel = 'gpt-4.1',\n getCustomModel,\n getProviderOptions,\n chatEndPoint = '',\n chatHeaders = {},\n } = params;\n\n return createSlice<AiSliceState>((set, get, store) => {\n // Clean up pending analysis results from persisted config\n const cleanedConfig = params.config?.sessions\n ? {\n ...params.config,\n sessions: params.config.sessions.map((session) => {\n const cleaned = cleanupPendingAnalysisResults(session);\n const completedUiMessages = Array.isArray(cleaned.uiMessages)\n ? fixIncompleteToolCalls(\n (cleaned.uiMessages as unknown as UIMessage[]) || [],\n )\n : [];\n return {\n ...cleaned,\n uiMessages:\n completedUiMessages as unknown as AnalysisSessionSchema['uiMessages'],\n };\n }),\n }\n : params.config;\n\n // Create persistent Maps (outside of immer draft)\n const pendingToolCallResolvers = new Map<\n string,\n {resolve: () => void; reject: (error: Error) => void}\n >();\n\n const toolCallToSessionId = new Map<string, string>();\n const sessionAbortControllers = new Map<string, AbortController>();\n const sessionChatStops = new Map<string, () => void>();\n const sessionChatSendMessages = new Map<string, AiChatSendMessage>();\n const sessionAddToolResults = new Map<string, AddToolResult>();\n\n // Initialize base config and ensure the initial session respects default provider/model\n const baseConfig = createDefaultAiConfig(cleanedConfig);\n if (!cleanedConfig?.sessions || cleanedConfig.sessions.length === 0) {\n const firstSession = baseConfig.sessions[0];\n if (firstSession) {\n firstSession.modelProvider = defaultProvider;\n firstSession.model = defaultModel;\n firstSession.prompt = initialPrompt;\n firstSession.isRunning = false;\n }\n }\n\n // Clean up openSessionTabs for sessions that no longer exist and ensure it's initialized\n const sessionIdSet = new Set(baseConfig.sessions.map((s) => s.id));\n if (baseConfig.openSessionTabs && baseConfig.openSessionTabs.length > 0) {\n baseConfig.openSessionTabs = baseConfig.openSessionTabs.filter((id) =>\n sessionIdSet.has(id),\n );\n }\n // Ensure openSessionTabs is initialized with current session if empty/missing\n if (\n !baseConfig.openSessionTabs ||\n baseConfig.openSessionTabs.length === 0\n ) {\n baseConfig.openSessionTabs = baseConfig.currentSessionId\n ? [baseConfig.currentSessionId]\n : [];\n }\n\n return {\n ai: {\n initialize: async () => {\n registerCommandsForOwner(store, AI_COMMAND_OWNER, createAiCommands());\n },\n destroy: async () => {\n unregisterCommandsForOwner(store, AI_COMMAND_OWNER);\n },\n config: baseConfig,\n promptSuggestionsVisible: true,\n apiKeyErrors: {},\n tools,\n getProviderOptions,\n waitForToolResult: (\n sessionId: string,\n toolCallId: string,\n abortSignal?: AbortSignal,\n ) => {\n const key = `${sessionId}:${toolCallId}`;\n return new Promise<void>((resolve, reject) => {\n // Set up abort handler\n const abortHandler = () => {\n const resolver = pendingToolCallResolvers.get(key);\n if (resolver) {\n pendingToolCallResolvers.delete(key);\n resolver.reject(new Error(TOOL_CALL_CANCELLED));\n }\n };\n\n if (abortSignal) {\n if (abortSignal.aborted) {\n reject(new Error(TOOL_CALL_CANCELLED));\n return;\n }\n abortSignal.addEventListener(ABORT_EVENT, abortHandler, {\n once: true,\n });\n }\n\n // Store resolver (overwrites any existing one, which is fine for our use case)\n pendingToolCallResolvers.set(key, {\n resolve: () => {\n if (abortSignal) {\n abortSignal.removeEventListener(ABORT_EVENT, abortHandler);\n }\n pendingToolCallResolvers.delete(key);\n resolve();\n },\n reject: (error: Error) => {\n if (abortSignal) {\n abortSignal.removeEventListener(ABORT_EVENT, abortHandler);\n }\n pendingToolCallResolvers.delete(key);\n reject(error);\n },\n });\n });\n },\n\n setToolCallSession: (\n toolCallId: string,\n sessionId: string | undefined,\n ) => {\n if (!toolCallId) return;\n if (sessionId) {\n toolCallToSessionId.set(toolCallId, sessionId);\n } else {\n toolCallToSessionId.delete(toolCallId);\n }\n },\n getToolCallSession: (toolCallId: string) => {\n if (!toolCallId) return undefined;\n return toolCallToSessionId.get(toolCallId);\n },\n\n getAbortController: (sessionId: string) => {\n return sessionAbortControllers.get(sessionId);\n },\n setAbortController: (\n sessionId: string,\n controller: AbortController | undefined,\n ) => {\n if (controller) {\n sessionAbortControllers.set(sessionId, controller);\n } else {\n sessionAbortControllers.delete(sessionId);\n }\n },\n\n setChatStop: (sessionId: string, stopFn: (() => void) | undefined) => {\n if (stopFn) {\n sessionChatStops.set(sessionId, stopFn);\n } else {\n sessionChatStops.delete(sessionId);\n }\n },\n getChatStop: (sessionId: string) => {\n return sessionChatStops.get(sessionId);\n },\n\n setChatSendMessage: (\n sessionId: string,\n sendMessageFn: AiChatSendMessage | undefined,\n ) => {\n if (sendMessageFn) {\n sessionChatSendMessages.set(sessionId, sendMessageFn);\n } else {\n sessionChatSendMessages.delete(sessionId);\n }\n },\n getChatSendMessage: (sessionId: string) => {\n return sessionChatSendMessages.get(sessionId);\n },\n\n setAddToolResult: (\n sessionId: string,\n addToolResultFn: AddToolResult | undefined,\n ) => {\n if (addToolResultFn) {\n // Wrap addToolResult to intercept calls and resolve pending promises\n const wrappedAddToolResult: AddToolResult = (options) => {\n addToolResultFn(options);\n const key = `${sessionId}:${options.toolCallId}`;\n const resolver = pendingToolCallResolvers.get(key);\n if (resolver) {\n resolver.resolve();\n }\n // Tool is complete (success or error), we can drop toolCall->session mapping.\n toolCallToSessionId.delete(options.toolCallId);\n };\n sessionAddToolResults.set(sessionId, wrappedAddToolResult);\n } else {\n sessionAddToolResults.delete(sessionId);\n }\n },\n getAddToolResult: (sessionId: string) => {\n return sessionAddToolResults.get(sessionId);\n },\n\n setConfig: (config: AiSliceConfig) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.config = config;\n }),\n );\n },\n\n setPromptSuggestionsVisible: (visible: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.promptSuggestionsVisible = visible;\n }),\n );\n },\n\n setApiKeyError: (provider: string, hasError: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n if (hasError) {\n draft.ai.apiKeyErrors[provider] = true;\n } else {\n delete draft.ai.apiKeyErrors[provider];\n }\n }),\n );\n },\n\n hasApiKeyError: () => {\n const state = get();\n const currentSession = state.ai.getCurrentSession();\n const provider = currentSession?.modelProvider || defaultProvider;\n return Boolean(state.ai.apiKeyErrors[provider]);\n },\n\n setPrompt: (sessionId: string, prompt: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.prompt = prompt;\n }\n }),\n );\n },\n getPrompt: (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n return session?.prompt || '';\n },\n\n setIsRunning: (sessionId: string, isRunning: boolean) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.isRunning = isRunning;\n }\n }),\n );\n },\n getIsRunning: (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n return session?.isRunning || false;\n },\n\n /**\n * Set the AI model for the current session\n * @param model - The model to set\n */\n setAiModel: (modelProvider: string, model: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.modelProvider = modelProvider;\n currentSession.model = model;\n }\n }),\n );\n },\n\n /**\n * Get the current active session\n */\n getCurrentSession: () => {\n const state = get();\n const {currentSessionId, sessions} = state.ai.config;\n return sessions.find((session) => session.id === currentSessionId);\n },\n\n /**\n * Create a new session with the given name and model settings\n */\n createSession: (\n name?: string,\n modelProvider?: string,\n model?: string,\n ) => {\n const currentSession = get().ai.getCurrentSession();\n const newSessionId = createId();\n\n // Generate a default name if none is provided\n let sessionName = name;\n if (!sessionName) {\n // Generate a human-readable date and time for the session name\n const now = new Date();\n const formattedDate = now.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n const formattedTime = now.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: 'numeric',\n hour12: true,\n });\n sessionName = `Session ${formattedDate} at ${formattedTime}`;\n }\n\n set((state) =>\n produce(state, (draft) => {\n const now = Date.now();\n // Add to AI sessions with per-session state\n draft.ai.config.sessions.unshift({\n id: newSessionId,\n name: sessionName,\n modelProvider:\n modelProvider ||\n currentSession?.modelProvider ||\n defaultProvider,\n model: model || currentSession?.model || defaultModel,\n analysisResults: [],\n createdAt: new Date(),\n uiMessages: [],\n toolAdditionalData: {},\n messagesRevision: 0,\n prompt: '',\n isRunning: false,\n lastOpenedAt: now,\n });\n draft.ai.config.currentSessionId = newSessionId;\n // Add new session to open tabs\n if (!draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs = [];\n }\n draft.ai.config.openSessionTabs.push(newSessionId);\n }),\n );\n },\n\n /**\n * Switch to a different session\n */\n switchSession: (sessionId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const now = Date.now();\n draft.ai.config.currentSessionId = sessionId;\n // Ensure current session is always in openSessionTabs\n if (!draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs = [];\n }\n if (!draft.ai.config.openSessionTabs.includes(sessionId)) {\n draft.ai.config.openSessionTabs.push(sessionId);\n }\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.lastOpenedAt = now;\n }\n }),\n );\n },\n\n /**\n * Set the list of open session tab IDs\n */\n setOpenSessionTabs: (tabs: string[]) => {\n set((state) =>\n produce(state, (draft) => {\n // Filter out any tabs for sessions that no longer exist\n const sessionIdSet = new Set(\n draft.ai.config.sessions.map((s) => s.id),\n );\n draft.ai.config.openSessionTabs = tabs.filter((id) =>\n sessionIdSet.has(id),\n );\n }),\n );\n },\n\n /**\n * Rename an existing session\n */\n renameSession: (sessionId: string, name: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.name = name;\n }\n }),\n );\n },\n\n /**\n * Delete a session and clean up its resources\n */\n deleteSession: (sessionId: string) => {\n // Clean up per-session state\n const abortController = sessionAbortControllers.get(sessionId);\n if (abortController) {\n abortController.abort(SESSION_DELETED);\n }\n sessionAbortControllers.delete(sessionId);\n sessionChatStops.delete(sessionId);\n sessionChatSendMessages.delete(sessionId);\n sessionAddToolResults.delete(sessionId);\n const now = Date.now();\n\n set((state) =>\n produce(state, (draft) => {\n const sessionIndex = draft.ai.config.sessions.findIndex(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (sessionIndex !== -1) {\n // Don't delete the last session\n if (draft.ai.config.sessions.length > 1) {\n draft.ai.config.sessions.splice(sessionIndex, 1);\n // Remove from open tabs\n if (draft.ai.config.openSessionTabs) {\n draft.ai.config.openSessionTabs =\n draft.ai.config.openSessionTabs.filter(\n (id) => id !== sessionId,\n );\n }\n // If we deleted the current session, switch to another one\n if (draft.ai.config.currentSessionId === sessionId) {\n // Make sure there's at least one session before accessing its id\n if (draft.ai.config.sessions.length > 0) {\n const firstSession = draft.ai.config.sessions[0];\n if (firstSession) {\n draft.ai.config.currentSessionId = firstSession.id;\n firstSession.lastOpenedAt = now;\n }\n }\n }\n }\n }\n }),\n );\n },\n\n /**\n * Save the Ai SDK UI messages for a session\n */\n setSessionUiMessages: (sessionId: string, uiMessages: UIMessage[]) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n // store the latest UI messages from the chat hook\n // Create a deep copy to avoid read-only property issues\n session.uiMessages = JSON.parse(JSON.stringify(uiMessages));\n }\n }),\n );\n },\n\n /**\n * Save additional data for a session\n */\n setSessionToolAdditionalData: (\n sessionId: string,\n toolCallId: string,\n additionalData: unknown,\n ) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n if (!session.toolAdditionalData) {\n session.toolAdditionalData = {};\n }\n session.toolAdditionalData[toolCallId] = additionalData;\n }\n }),\n );\n },\n\n findToolComponent: (toolName: string) => {\n return get().ai.tools[toolName]?.component as React.ComponentType;\n },\n\n getBaseUrlFromSettings: () => {\n // First try the getBaseUrl function if provided\n const baseUrlFromFunction = getBaseUrl?.();\n if (baseUrlFromFunction) {\n return baseUrlFromFunction;\n }\n\n // Fall back to settings\n const store = get();\n if (hasAiSettingsConfig(store)) {\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.baseUrl;\n }\n const provider =\n store.aiSettings.config.providers[currentSession.modelProvider];\n return provider?.baseUrl;\n }\n }\n return undefined;\n },\n\n getApiKeyFromSettings: () => {\n const store = get();\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n // First try the getApiKey function if provided\n const apiKeyFromFunction = getApiKey?.(\n currentSession.modelProvider || 'openai',\n );\n if (apiKeyFromFunction) {\n return apiKeyFromFunction;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.apiKey || '';\n } else {\n const provider =\n store.aiSettings.config.providers?.[\n currentSession.modelProvider\n ];\n return provider?.apiKey || '';\n }\n }\n }\n return '';\n },\n\n getMaxStepsFromSettings: () => {\n const store = get();\n // First try the maxSteps parameter if provided\n if (maxSteps && Number.isFinite(maxSteps) && maxSteps > 0) {\n return maxSteps;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n const settingsMaxSteps =\n store.aiSettings.config.modelParameters.maxSteps;\n if (Number.isFinite(settingsMaxSteps) && settingsMaxSteps > 0) {\n return settingsMaxSteps;\n }\n }\n return 50;\n },\n\n getFullInstructions: () => {\n const store = get();\n\n let instructions = getInstructions();\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n // get additional instructions from settings\n const {additionalInstruction} =\n store.aiSettings.config.modelParameters;\n if (additionalInstruction) {\n instructions = `${instructions}\\n\\nAdditional Instructions:\\n\\n${additionalInstruction}`;\n }\n }\n return instructions;\n },\n\n sendPrompt: async (\n prompt: string,\n options: {\n systemInstructions?: string;\n modelProvider?: string;\n modelName?: string;\n baseUrl?: string;\n useTools?: boolean;\n abortSignal?: AbortSignal;\n } = {},\n ) => {\n // One-shot generateText path with explicit abort lifecycle management\n const state = get();\n const currentSession = state.ai.getCurrentSession(); // only used when no model provider is provided\n const {\n systemInstructions,\n modelProvider,\n modelName,\n baseUrl,\n abortSignal,\n useTools = false,\n } = options;\n\n if (abortSignal?.aborted) {\n throw new ToolAbortError(TOOL_CALL_CANCELLED);\n }\n\n const provider =\n modelProvider || currentSession?.modelProvider || defaultProvider;\n const modelId = modelName || currentSession?.model || defaultModel;\n const baseURL = baseUrl ?? state.ai.getBaseUrlFromSettings() ?? '';\n const tools = state.ai.tools;\n\n const toolsWithoutExecute = Object.fromEntries(\n Object.entries(tools).filter(([, tool]) => !tool.execute),\n );\n\n const model = createOpenAICompatible({\n apiKey: state.ai.getApiKeyFromSettings(),\n name: provider,\n baseURL,\n }).chatModel(modelId);\n\n try {\n const response = await generateText({\n model,\n temperature: AI_DEFAULT_TEMPERATURE,\n messages: [{role: 'user', content: prompt}],\n system: systemInstructions || state.ai.getFullInstructions(),\n abortSignal: abortSignal,\n ...(useTools\n ? {tools: convertToAiSDKTools(toolsWithoutExecute)}\n : {}),\n });\n return response.text;\n } catch (error) {\n const errorName =\n typeof error === 'object' && error && 'name' in error\n ? String((error as {name?: unknown}).name)\n : '';\n if (abortSignal?.aborted || errorName === 'AbortError') {\n throw new ToolAbortError(TOOL_CALL_CANCELLED);\n }\n console.error('Error generating text:', error);\n return 'error: can not generate response';\n }\n },\n\n /**\n * Start the analysis for a specific session\n */\n startAnalysis: async (sessionId: string) => {\n const state = get();\n const session = state.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n\n if (!session) {\n console.error('Session not found:', sessionId);\n return;\n }\n\n const sendMessage = state.ai.getChatSendMessage(sessionId);\n if (!sendMessage) {\n console.error(\n 'No sendMessage function found for session:',\n sessionId,\n );\n return;\n }\n\n const abortController = new AbortController();\n const promptText = session.prompt || '';\n\n // Store abort controller for this session\n state.ai.setAbortController(sessionId, abortController);\n\n set((stateToUpdate) =>\n produce(stateToUpdate, (draft) => {\n const draftSession = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (draftSession) {\n draftSession.isRunning = true;\n draftSession.prompt = '';\n draft.ai.promptSuggestionsVisible = false;\n\n // Remove any existing pending results\n draftSession.analysisResults =\n draftSession.analysisResults.filter(\n (result: AnalysisResultSchema) =>\n result.id !== ANALYSIS_PENDING_ID,\n );\n\n // Add incomplete analysis result with a temporary ID\n draftSession.analysisResults.push({\n id: ANALYSIS_PENDING_ID,\n prompt: promptText,\n isCompleted: false,\n });\n }\n }),\n );\n\n // Send the message through the session's chat instance\n sendMessage({text: promptText});\n },\n\n cancelAnalysis: (sessionId: string) => {\n const state = get();\n const abortController = state.ai.getAbortController(sessionId);\n const stopFn = state.ai.getChatStop(sessionId);\n\n // Stop local chat streaming immediately if available\n stopFn?.();\n\n abortController?.abort(ANALYSIS_CANCELLED);\n\n set((stateToUpdate) =>\n produce(stateToUpdate, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.isRunning = false;\n }\n // Keep abort controller so handlers can check signal.aborted\n // It will be cleared by onChatFinish\n }),\n );\n },\n\n /**\n * Get the assistant message parts for a given analysis result ID\n * @param analysisResultId - The ID of the analysis result (user message ID)\n * @returns Array of message parts from the assistant's response\n */\n getAssistantMessageParts: (analysisResultId: string) => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) return [];\n\n const uiMessages = currentSession.uiMessages as UIMessage[];\n // Find the user message with analysisResultId\n const userMessageIndex = uiMessages.findIndex(\n (msg) => msg.id === analysisResultId && msg.role === 'user',\n );\n if (userMessageIndex === -1) return [];\n\n // Find the next assistant message after this user message\n for (let i = userMessageIndex + 1; i < uiMessages.length; i++) {\n const msg = uiMessages[i];\n if (msg?.role === 'assistant') {\n return msg.parts;\n }\n if (msg?.role === 'user') {\n // Hit next user message without finding assistant response\n break;\n }\n }\n return [];\n },\n\n /**\n * Delete an analysis result from a session\n * - remove the corresponding prompt-response pair from uiMessages\n * - remove the associated toolAdditionalData\n */\n deleteAnalysisResult: (sessionId: string, resultId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.ai.config.sessions.find(\n (s: AnalysisSessionSchema) => s.id === sessionId,\n );\n if (session) {\n session.analysisResults = session.analysisResults.filter(\n (r: AnalysisResultSchema) => r.id !== resultId,\n );\n // Remove corresponding prompt-response pair from uiMessages\n const uiMessages = session.uiMessages as UIMessage[];\n const userMessageIndex = uiMessages.findIndex(\n (msg) => msg.id === resultId && msg.role === 'user',\n );\n\n if (userMessageIndex !== -1) {\n // Find the next user message (or end of array) to determine response boundary\n let nextUserIndex = userMessageIndex + 1;\n const toolCallIdsToDelete: Set<string> = new Set();\n\n while (\n nextUserIndex < uiMessages.length &&\n uiMessages[nextUserIndex]?.role !== 'user'\n ) {\n const msg = uiMessages[nextUserIndex];\n // Extract toolCallId from message parts\n if (msg?.parts) {\n for (const part of msg.parts) {\n // Check for tool-* or dynamic-tool parts that have toolCallId\n if (\n 'toolCallId' in part &&\n typeof part.toolCallId === 'string'\n ) {\n toolCallIdsToDelete.add(part.toolCallId);\n }\n }\n }\n nextUserIndex++;\n }\n\n // Remove the user message and all assistant messages until the next user message\n session.uiMessages.splice(\n userMessageIndex,\n nextUserIndex - userMessageIndex,\n );\n\n // Increment messagesRevision to force useChat reset\n session.messagesRevision =\n (session.messagesRevision || 0) + 1;\n\n // Clean up toolAdditionalData for deleted messages\n if (session.toolAdditionalData) {\n // Remove data keyed by the toolCallId from the deleted messages\n toolCallIdsToDelete.forEach((toolCallId) => {\n if (session.toolAdditionalData![toolCallId]) {\n delete session.toolAdditionalData![toolCallId];\n }\n });\n }\n }\n }\n }),\n );\n },\n\n /**\n * Get analysis results for the current session by transforming UI messages\n * into structured analysis results (user prompt → AI response pairs).\n *\n * @returns Array of analysis results for the current session\n */\n getAnalysisResults: () => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) return undefined;\n\n return currentSession.analysisResults;\n },\n\n /**\n * Add an analysis result to the current session\n * - add the message to the uiMessages\n * - add the analysis result to the analysisResults\n */\n addAnalysisResult: (message: UIMessage) => {\n const currentSession = get().ai.getCurrentSession();\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n set((state) =>\n produce(state, (draft) => {\n // Extract text content from message parts\n const textContent =\n message.parts\n ?.filter((part) => part.type === 'text')\n ?.map((part) => (part as {text: string}).text)\n ?.join('') || '';\n\n draft.ai.config.sessions\n .find((s: AnalysisSessionSchema) => s.id === currentSession?.id)\n ?.analysisResults.push({\n id: message.id,\n prompt: textContent,\n isCompleted: true,\n });\n }),\n );\n },\n\n // Chat transport configuration\n chatEndPoint,\n chatHeaders,\n\n getLocalChatTransport: (sessionId: string) => {\n return createLocalChatTransportFactory({\n store,\n defaultProvider: defaultProvider,\n defaultModel: defaultModel,\n getInstructions: () => store.getState().ai.getFullInstructions(),\n getCustomModel,\n sessionId,\n })();\n },\n\n getRemoteChatTransport: (\n sessionId: string,\n endpoint: string,\n headers?: Record<string, string>,\n ) =>\n createRemoteChatTransportFactory({\n store,\n defaultProvider,\n defaultModel,\n sessionId,\n })(endpoint, headers),\n\n ...createChatHandlers({store}),\n },\n };\n });\n}\n\n/**\n * Helper function to get the current session from state\n */\nfunction getCurrentSessionFromState(\n state: AiSliceState,\n): AnalysisSessionSchema | undefined {\n const {currentSessionId, sessions} = state.ai.config;\n return sessions.find((session) => session.id === currentSessionId);\n}\n\ntype AiCommandStoreState = BaseRoomStoreState & AiSliceState;\n\nconst AiCreateSessionInput = z\n .object({\n name: z.string().optional().describe('Optional session name.'),\n modelProvider: z\n .string()\n .optional()\n .describe('Optional model provider ID.'),\n model: z.string().optional().describe('Optional model ID.'),\n })\n .default({});\ntype AiCreateSessionInput = z.infer<typeof AiCreateSessionInput>;\n\nconst AiSessionIdInput = z.object({\n sessionId: z.string().describe('Target AI session ID.'),\n});\ntype AiSessionIdInput = z.infer<typeof AiSessionIdInput>;\n\nconst AiRenameSessionInput = z.object({\n sessionId: z.string().describe('Target AI session ID.'),\n name: z.string().min(1).describe('New session name.'),\n});\ntype AiRenameSessionInput = z.infer<typeof AiRenameSessionInput>;\n\nfunction createAiCommands(): RoomCommand<AiCommandStoreState>[] {\n const ensureSessionExists = (\n state: AiCommandStoreState,\n sessionId: string,\n ) => {\n if (!state.ai.config.sessions.some((session) => session.id === sessionId)) {\n throw new Error(`Unknown AI session \"${sessionId}\".`);\n }\n };\n\n return [\n {\n id: 'ai.create-session',\n name: 'Create AI session',\n description: 'Start a new AI chat session',\n group: 'AI',\n keywords: ['ai', 'chat', 'session', 'new'],\n inputSchema: AiCreateSessionInput,\n inputDescription:\n 'Optionally provide name, modelProvider, and model for the new session.',\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'low',\n },\n execute: ({getState}, input) => {\n const {name, modelProvider, model} =\n (input as AiCreateSessionInput | undefined) ?? {};\n getState().ai.createSession(name, modelProvider, model);\n return {\n success: true,\n commandId: 'ai.create-session',\n message: 'Created AI session.',\n };\n },\n },\n {\n id: 'ai.switch-session',\n name: 'Switch AI session',\n description: 'Switch current AI session by ID',\n group: 'AI',\n keywords: ['ai', 'chat', 'session', 'switch'],\n inputSchema: AiSessionIdInput,\n inputDescription: 'Provide sessionId to activate.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n validateInput: (input, {getState}) => {\n ensureSessionExists(getState(), (input as AiSessionIdInput).sessionId);\n },\n execute: ({getState}, input) => {\n const {sessionId} = input as AiSessionIdInput;\n getState().ai.switchSession(sessionId);\n return {\n success: true,\n commandId: 'ai.switch-session',\n message: `Switched to AI session \"${sessionId}\".`,\n };\n },\n },\n {\n id: 'ai.rename-session',\n name: 'Rename AI session',\n description: 'Rename AI session by ID',\n group: 'AI',\n keywords: ['ai', 'chat', 'session', 'rename'],\n inputSchema: AiRenameSessionInput,\n inputDescription: 'Provide sessionId and new name.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n validateInput: (input, {getState}) => {\n ensureSessionExists(\n getState(),\n (input as AiRenameSessionInput).sessionId,\n );\n },\n execute: ({getState}, input) => {\n const {sessionId, name} = input as AiRenameSessionInput;\n getState().ai.renameSession(sessionId, name);\n return {\n success: true,\n commandId: 'ai.rename-session',\n message: `Renamed AI session \"${sessionId}\".`,\n };\n },\n },\n {\n id: 'ai.delete-session',\n name: 'Delete AI session',\n description: 'Delete AI session by ID',\n group: 'AI',\n keywords: ['ai', 'chat', 'session', 'delete'],\n inputSchema: AiSessionIdInput,\n inputDescription: 'Provide sessionId to delete.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'medium',\n requiresConfirmation: true,\n },\n validateInput: (input, {getState}) => {\n const state = getState();\n const {sessionId} = input as AiSessionIdInput;\n ensureSessionExists(state, sessionId);\n if (state.ai.config.sessions.length <= 1) {\n throw new Error('Cannot delete the last remaining AI session.');\n }\n },\n execute: ({getState}, input) => {\n const {sessionId} = input as AiSessionIdInput;\n getState().ai.deleteSession(sessionId);\n return {\n success: true,\n commandId: 'ai.delete-session',\n message: `Deleted AI session \"${sessionId}\".`,\n };\n },\n },\n {\n id: 'ai.cancel-current-analysis',\n name: 'Cancel current AI analysis',\n description: 'Stop the currently running AI response',\n group: 'AI',\n keywords: ['ai', 'chat', 'cancel', 'stop', 'analysis'],\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n isEnabled: ({getState}) => {\n const currentSession = getState().ai.getCurrentSession();\n return Boolean(currentSession?.isRunning);\n },\n execute: ({getState}) => {\n const currentSession = getState().ai.getCurrentSession();\n if (!currentSession) {\n return {\n success: false,\n commandId: 'ai.cancel-current-analysis',\n message: 'No active session.',\n error: 'no active session',\n };\n }\n getState().ai.cancelAnalysis(currentSession.id);\n return {\n success: true,\n commandId: 'ai.cancel-current-analysis',\n message: `Cancelled analysis for session \"${currentSession.id}\".`,\n };\n },\n },\n ];\n}\n\nexport function useStoreWithAi<T>(selector: (state: AiSliceState) => T): T {\n return useBaseRoomStore<AiSliceState, T>((state) => selector(state));\n}\n"]}
@@ -19,8 +19,8 @@ export type ChatTransportConfig = {
19
19
  getInstructions: () => string;
20
20
  /**
21
21
  * Optional: supply a pre-configured custom model.
22
- * e.g. import {xai} from "@ai-sdk/xai";
23
- * getCustomModel: () => xai('grok-4')
22
+ * e.g. import {anthropic} from "@ai-sdk/anthropic";
23
+ * getCustomModel: () => anthropic('claude-sonnet-4-5')
24
24
  * If provided, this model will be used instead of the default OpenAI-compatible client.
25
25
  */
26
26
  getCustomModel?: () => LanguageModel | undefined;