@sqlrooms/ai 0.24.13 → 0.24.15

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.d.ts CHANGED
@@ -5,13 +5,13 @@ import { z } from 'zod';
5
5
  import { AnalysisSessionSchema } from './schemas';
6
6
  export declare const AiSliceConfig: z.ZodObject<{
7
7
  ai: z.ZodObject<{
8
- sessions: z.ZodArray<z.ZodObject<{
8
+ sessions: z.ZodArray<z.ZodEffects<z.ZodObject<{
9
9
  id: z.ZodString;
10
10
  name: z.ZodString;
11
11
  modelProvider: z.ZodString;
12
12
  model: z.ZodString;
13
13
  customModelName: z.ZodOptional<z.ZodString>;
14
- ollamaBaseUrl: z.ZodOptional<z.ZodString>;
14
+ baseUrl: z.ZodOptional<z.ZodString>;
15
15
  analysisResults: z.ZodArray<z.ZodObject<{
16
16
  id: z.ZodString;
17
17
  prompt: z.ZodString;
@@ -241,7 +241,7 @@ export declare const AiSliceConfig: z.ZodObject<{
241
241
  } | undefined;
242
242
  }[];
243
243
  customModelName?: string | undefined;
244
- ollamaBaseUrl?: string | undefined;
244
+ baseUrl?: string | undefined;
245
245
  createdAt?: Date | undefined;
246
246
  }, {
247
247
  id: string;
@@ -258,12 +258,9 @@ export declare const AiSliceConfig: z.ZodObject<{
258
258
  } | undefined;
259
259
  }[];
260
260
  customModelName?: string | undefined;
261
- ollamaBaseUrl?: string | undefined;
261
+ baseUrl?: string | undefined;
262
262
  createdAt?: Date | undefined;
263
- }>, "many">;
264
- currentSessionId: z.ZodOptional<z.ZodString>;
265
- }, "strip", z.ZodTypeAny, {
266
- sessions: {
263
+ }>, {
267
264
  id: string;
268
265
  name: string;
269
266
  modelProvider: string;
@@ -300,11 +297,11 @@ export declare const AiSliceConfig: z.ZodObject<{
300
297
  } | undefined;
301
298
  }[];
302
299
  customModelName?: string | undefined;
303
- ollamaBaseUrl?: string | undefined;
300
+ baseUrl?: string | undefined;
304
301
  createdAt?: Date | undefined;
305
- }[];
306
- currentSessionId?: string | undefined;
307
- }, {
302
+ }, unknown>, "many">;
303
+ currentSessionId: z.ZodOptional<z.ZodString>;
304
+ }, "strip", z.ZodTypeAny, {
308
305
  sessions: {
309
306
  id: string;
310
307
  name: string;
@@ -314,16 +311,41 @@ export declare const AiSliceConfig: z.ZodObject<{
314
311
  id: string;
315
312
  isCompleted: boolean;
316
313
  prompt: string;
317
- streamMessage?: unknown;
314
+ streamMessage: {
315
+ parts?: ({
316
+ type: "text";
317
+ text: string;
318
+ isCompleted?: boolean | undefined;
319
+ additionalData?: any;
320
+ } | {
321
+ type: "tool-invocation";
322
+ toolInvocation: {
323
+ toolName: string;
324
+ toolCallId: string;
325
+ state: string;
326
+ args?: any;
327
+ result?: any;
328
+ };
329
+ isCompleted?: boolean | undefined;
330
+ additionalData?: any;
331
+ } | z.objectOutputType<{
332
+ type: z.ZodString;
333
+ additionalData: z.ZodOptional<z.ZodAny>;
334
+ isCompleted: z.ZodOptional<z.ZodBoolean>;
335
+ }, z.ZodTypeAny, "passthrough">)[] | undefined;
336
+ };
318
337
  errorMessage?: {
319
338
  error: string;
320
339
  } | undefined;
321
340
  }[];
322
341
  customModelName?: string | undefined;
323
- ollamaBaseUrl?: string | undefined;
342
+ baseUrl?: string | undefined;
324
343
  createdAt?: Date | undefined;
325
344
  }[];
326
345
  currentSessionId?: string | undefined;
346
+ }, {
347
+ sessions: unknown[];
348
+ currentSessionId?: string | undefined;
327
349
  }>;
328
350
  }, "strip", z.ZodTypeAny, {
329
351
  ai: {
@@ -364,31 +386,14 @@ export declare const AiSliceConfig: z.ZodObject<{
364
386
  } | undefined;
365
387
  }[];
366
388
  customModelName?: string | undefined;
367
- ollamaBaseUrl?: string | undefined;
389
+ baseUrl?: string | undefined;
368
390
  createdAt?: Date | undefined;
369
391
  }[];
370
392
  currentSessionId?: string | undefined;
371
393
  };
372
394
  }, {
373
395
  ai: {
374
- sessions: {
375
- id: string;
376
- name: string;
377
- modelProvider: string;
378
- model: string;
379
- analysisResults: {
380
- id: string;
381
- isCompleted: boolean;
382
- prompt: string;
383
- streamMessage?: unknown;
384
- errorMessage?: {
385
- error: string;
386
- } | undefined;
387
- }[];
388
- customModelName?: string | undefined;
389
- ollamaBaseUrl?: string | undefined;
390
- createdAt?: Date | undefined;
391
- }[];
396
+ sessions: unknown[];
392
397
  currentSessionId?: string | undefined;
393
398
  };
394
399
  }>;
@@ -406,7 +411,7 @@ export type AiSliceState = {
406
411
  cancelAnalysis: () => void;
407
412
  setAiModel: (modelProvider: string, model: string) => void;
408
413
  setCustomModelName: (customModelName: string) => void;
409
- setOllamaBaseUrl: (baseUrl: string) => void;
414
+ setBaseUrl: (baseUrl: string) => void;
410
415
  createSession: (name?: string, modelProvider?: string, model?: string) => void;
411
416
  switchSession: (sessionId: string) => void;
412
417
  renameSession: (sessionId: string, name: string) => void;
@@ -416,9 +421,13 @@ export type AiSliceState = {
416
421
  findToolComponent: (toolName: string) => React.ComponentType | undefined;
417
422
  };
418
423
  };
419
- export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>({ getApiKey, initialAnalysisPrompt, customTools, getInstructions, }: {
420
- getApiKey: (modelProvider: string) => string;
424
+ /**
425
+ * Configuration options for creating an AI slice
426
+ */
427
+ export interface AiSliceOptions {
428
+ /** Initial prompt to display in the analysis input */
421
429
  initialAnalysisPrompt?: string;
430
+ /** Custom tools to add to the AI assistant */
422
431
  customTools?: Record<string, AiSliceTool>;
423
432
  /**
424
433
  * Function to get custom instructions for the AI assistant
@@ -426,7 +435,26 @@ export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>
426
435
  * @returns The instructions string to use
427
436
  */
428
437
  getInstructions?: (tablesSchema: DataTable[]) => string;
429
- }): StateCreator<AiSliceState>;
438
+ /**
439
+ * Number of rows to share with LLM (default: 0)
440
+ */
441
+ numberOfRowsToShareWithLLM?: number;
442
+ }
443
+ /**
444
+ * API key configuration for the AI slice
445
+ */
446
+ export type AiSliceApiConfig = {
447
+ baseUrl: string;
448
+ getApiKey?: never;
449
+ } | {
450
+ getApiKey: (modelProvider: string) => string;
451
+ baseUrl?: never;
452
+ };
453
+ /**
454
+ * Complete configuration for creating an AI slice
455
+ */
456
+ export type CreateAiSliceConfig = AiSliceOptions & AiSliceApiConfig;
457
+ export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>(config: CreateAiSliceConfig): StateCreator<AiSliceState>;
430
458
  type RoomConfigWithAi = BaseRoomConfig & AiSliceConfig;
431
459
  type RoomShellSliceStateWithAi = RoomShellSliceState<RoomConfigWithAi> & AiSliceState;
432
460
  export declare function useStoreWithAi<T>(selector: (state: RoomShellSliceStateWithAi) => T): T;
@@ -1 +1 @@
1
- {"version":3,"file":"AiSlice.d.ts","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AiSlice.d.ts","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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"}
package/dist/AiSlice.js CHANGED
@@ -29,14 +29,15 @@ export function createDefaultAiConfig(props) {
29
29
  },
30
30
  };
31
31
  }
32
- export function createAiSlice({ getApiKey, initialAnalysisPrompt = '', customTools = {}, getInstructions, }) {
32
+ export function createAiSlice(config) {
33
+ const { getApiKey, baseUrl, initialAnalysisPrompt = '', customTools = {}, getInstructions, numberOfRowsToShareWithLLM, } = config;
33
34
  return createSlice((set, get, store) => {
34
35
  return {
35
36
  ai: {
36
37
  analysisPrompt: initialAnalysisPrompt,
37
38
  isRunningAnalysis: false,
38
39
  tools: {
39
- ...getDefaultTools(store),
40
+ ...getDefaultTools(store, numberOfRowsToShareWithLLM),
40
41
  ...customTools,
41
42
  },
42
43
  setAnalysisPrompt: (prompt) => {
@@ -70,14 +71,14 @@ export function createAiSlice({ getApiKey, initialAnalysisPrompt = '', customToo
70
71
  }));
71
72
  },
72
73
  /**
73
- * Set the Ollama base URL for the current session
74
- * @param baseUrl - The Ollama server URL to set
74
+ * Set the base URL for the current session
75
+ * @param baseUrl - The server URL to set
75
76
  */
76
- setOllamaBaseUrl: (baseUrl) => {
77
+ setBaseUrl: (baseUrl) => {
77
78
  set((state) => produce(state, (draft) => {
78
79
  const currentSession = getCurrentSessionFromState(draft);
79
80
  if (currentSession) {
80
- currentSession.ollamaBaseUrl = baseUrl;
81
+ currentSession.baseUrl = baseUrl;
81
82
  }
82
83
  }));
83
84
  },
@@ -117,7 +118,7 @@ export function createAiSlice({ getApiKey, initialAnalysisPrompt = '', customToo
117
118
  id: newSessionId,
118
119
  name: sessionName,
119
120
  modelProvider: modelProvider || currentSession?.modelProvider || 'openai',
120
- model: model || currentSession?.model || 'gpt-4o-mini',
121
+ model: model || currentSession?.model || 'gpt-4.1',
121
122
  analysisResults: [],
122
123
  createdAt: new Date(),
123
124
  });
@@ -205,14 +206,14 @@ export function createAiSlice({ getApiKey, initialAnalysisPrompt = '', customToo
205
206
  modelProvider: currentSession.modelProvider || 'openai',
206
207
  model: currentSession.model || 'gpt-4o-mini',
207
208
  customModelName: currentSession.customModelName,
208
- apiKey: getApiKey(currentSession.modelProvider || 'openai'),
209
- ...(currentSession.modelProvider === 'ollama' &&
210
- currentSession.ollamaBaseUrl && {
211
- baseUrl: currentSession.ollamaBaseUrl,
212
- }),
209
+ apiKey: getApiKey?.(currentSession.modelProvider || 'openai') || '',
210
+ baseUrl: currentSession.baseUrl || baseUrl,
213
211
  prompt: get().ai.analysisPrompt,
214
212
  abortController,
215
- tools: get().ai.tools,
213
+ tools: {
214
+ ...getDefaultTools(store, numberOfRowsToShareWithLLM),
215
+ ...customTools,
216
+ },
216
217
  getInstructions,
217
218
  onStreamResult: (isCompleted, streamMessage) => {
218
219
  set(makeResultsAppender({
@@ -1 +1 @@
1
- {"version":3,"file":"AiSlice.js","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {StreamMessage} from '@openassistant/core';\nimport {ExtendedTool} from '@openassistant/utils';\nimport {createId} from '@paralleldrive/cuid2';\nimport {DataTable} from '@sqlrooms/duckdb';\nimport {\n BaseRoomConfig,\n createSlice,\n RoomShellSliceState,\n useBaseRoomShellStore,\n type StateCreator,\n} from '@sqlrooms/room-shell';\nimport {produce, WritableDraft} from 'immer';\nimport {z} from 'zod';\nimport {getDefaultTools, runAnalysis} from './analysis';\nimport {\n AnalysisResultSchema,\n AnalysisSessionSchema,\n ErrorMessageSchema,\n} from './schemas';\n\nexport const AiSliceConfig = z.object({\n ai: z.object({\n sessions: z.array(AnalysisSessionSchema),\n currentSessionId: z.string().optional(),\n }),\n});\nexport type AiSliceConfig = z.infer<typeof AiSliceConfig>;\n\nexport function createDefaultAiConfig(\n props: Partial<AiSliceConfig['ai']>,\n): AiSliceConfig {\n const defaultSessionId = createId();\n return {\n ai: {\n sessions: [\n {\n id: defaultSessionId,\n name: 'Default Session',\n modelProvider: 'openai',\n model: 'gpt-4o-mini',\n analysisResults: [],\n createdAt: new Date(),\n },\n ],\n currentSessionId: defaultSessionId,\n ...props,\n },\n };\n}\n\n// template for the tool: Argument, LLM Result, Additional Data, Context\nexport type AiSliceTool = ExtendedTool<z.ZodTypeAny, unknown, unknown, unknown>;\n\nexport type AiSliceState = {\n ai: {\n analysisPrompt: string;\n isRunningAnalysis: boolean;\n tools: Record<string, AiSliceTool>;\n analysisAbortController?: AbortController;\n setAnalysisPrompt: (prompt: string) => void;\n startAnalysis: () => Promise<void>;\n cancelAnalysis: () => void;\n setAiModel: (modelProvider: string, model: string) => void;\n setCustomModelName: (customModelName: string) => void;\n setOllamaBaseUrl: (baseUrl: 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 getCurrentSession: () => AnalysisSessionSchema | undefined;\n deleteAnalysisResult: (sessionId: string, resultId: string) => void;\n findToolComponent: (toolName: string) => React.ComponentType | undefined;\n };\n};\n\nexport function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>({\n getApiKey,\n initialAnalysisPrompt = '',\n customTools = {},\n getInstructions,\n}: {\n getApiKey: (modelProvider: string) => string;\n initialAnalysisPrompt?: string;\n customTools?: Record<string, AiSliceTool>;\n /**\n * Function to get custom instructions for the AI assistant\n * @param tablesSchema - The schema of the tables in the database\n * @returns The instructions string to use\n */\n getInstructions?: (tablesSchema: DataTable[]) => string;\n}): StateCreator<AiSliceState> {\n return createSlice<PC, AiSliceState>((set, get, store) => {\n return {\n ai: {\n analysisPrompt: initialAnalysisPrompt,\n isRunningAnalysis: false,\n\n tools: {\n ...getDefaultTools(store),\n ...customTools,\n },\n\n setAnalysisPrompt: (prompt: string) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.analysisPrompt = prompt;\n }),\n );\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 * Set the custom model name for the current session\n * @param customModelName - The custom model name to set\n */\n setCustomModelName: (customModelName: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.customModelName = customModelName;\n }\n }),\n );\n },\n\n /**\n * Set the Ollama base URL for the current session\n * @param baseUrl - The Ollama server URL to set\n */\n setOllamaBaseUrl: (baseUrl: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.ollamaBaseUrl = baseUrl;\n }\n }),\n );\n },\n\n /**\n * Get the current active session\n */\n getCurrentSession: () => {\n const state = get();\n const {currentSessionId, sessions} = state.config.ai;\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 draft.config.ai.sessions.unshift({\n id: newSessionId,\n name: sessionName,\n modelProvider:\n modelProvider || currentSession?.modelProvider || 'openai',\n model: model || currentSession?.model || 'gpt-4o-mini',\n analysisResults: [],\n createdAt: new Date(),\n });\n draft.config.ai.currentSessionId = 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 draft.config.ai.currentSessionId = sessionId;\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.config.ai.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n session.name = name;\n }\n }),\n );\n },\n\n /**\n * Delete a session\n */\n deleteSession: (sessionId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const sessionIndex = draft.config.ai.sessions.findIndex(\n (s) => s.id === sessionId,\n );\n if (sessionIndex !== -1) {\n // Don't delete the last session\n if (draft.config.ai.sessions.length > 1) {\n draft.config.ai.sessions.splice(sessionIndex, 1);\n // If we deleted the current session, switch to another one\n if (draft.config.ai.currentSessionId === sessionId) {\n // Make sure there's at least one session before accessing its id\n if (draft.config.ai.sessions.length > 0) {\n const firstSession = draft.config.ai.sessions[0];\n if (firstSession) {\n draft.config.ai.currentSessionId = firstSession.id;\n }\n }\n }\n }\n }\n }),\n );\n },\n\n /**\n * Start the analysis\n * TODO: how to pass the history analysisResults?\n */\n startAnalysis: async () => {\n const resultId = createId();\n const abortController = new AbortController();\n const currentSession = get().ai.getCurrentSession();\n\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n\n set((state) =>\n produce(state, (draft) => {\n draft.ai.analysisAbortController = abortController;\n draft.ai.isRunningAnalysis = true;\n\n const session = draft.config.ai.sessions.find(\n (s) => s.id === draft.config.ai.currentSessionId,\n );\n\n if (session) {\n session.analysisResults.push({\n id: resultId,\n prompt: get().ai.analysisPrompt,\n streamMessage: {\n parts: [\n {\n type: 'text',\n text: '',\n },\n ],\n },\n isCompleted: false,\n });\n }\n }),\n );\n\n try {\n await runAnalysis({\n tableSchemas: get().db.tables,\n modelProvider: currentSession.modelProvider || 'openai',\n model: currentSession.model || 'gpt-4o-mini',\n customModelName: currentSession.customModelName,\n apiKey: getApiKey(currentSession.modelProvider || 'openai'),\n ...(currentSession.modelProvider === 'ollama' &&\n currentSession.ollamaBaseUrl && {\n baseUrl: currentSession.ollamaBaseUrl,\n }),\n prompt: get().ai.analysisPrompt,\n abortController,\n tools: get().ai.tools,\n getInstructions,\n onStreamResult: (isCompleted, streamMessage) => {\n set(\n makeResultsAppender({\n resultId,\n streamMessage,\n isCompleted,\n }),\n );\n },\n });\n } catch (err) {\n set(\n makeResultsAppender({\n resultId,\n isCompleted: true,\n errorMessage: {\n error: err instanceof Error ? err.message : String(err),\n },\n }),\n );\n } finally {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.isRunningAnalysis = false;\n draft.ai.analysisPrompt = '';\n }),\n );\n }\n },\n\n cancelAnalysis: () => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.isRunningAnalysis = false;\n }),\n );\n get().ai.analysisAbortController?.abort('Analysis cancelled');\n },\n\n /**\n * Delete an analysis result from a session\n */\n deleteAnalysisResult: (sessionId: string, resultId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.config.ai.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n session.analysisResults = session.analysisResults.filter(\n (r) => r.id !== resultId,\n );\n }\n }),\n );\n },\n\n findToolComponent: (toolName: string) => {\n return Object.entries(get().ai.tools).find(\n ([name]) => name === toolName,\n )?.[1]?.component as React.ComponentType;\n },\n },\n };\n });\n}\n\n/**\n * Helper function to get the current session from state\n */\nfunction getCurrentSessionFromState<PC extends BaseRoomConfig & AiSliceConfig>(\n state: RoomShellSliceState<PC> | WritableDraft<RoomShellSliceState<PC>>,\n): AnalysisSessionSchema | undefined {\n const {currentSessionId, sessions} = state.config.ai;\n return sessions.find((session) => session.id === currentSessionId);\n}\n\nfunction findResultById(\n analysisResults: AnalysisResultSchema[],\n id: string,\n): AnalysisResultSchema | undefined {\n return analysisResults.find((result) => result.id === id);\n}\n\n/**\n * Appends the tool results, tool calls, and analysis to the state\n *\n * @param resultId - The id of the result to append to\n * @param message - The message to append to the state. The structure of the message is defined as:\n * - reasoning: string The reasoning of the assistant\n * - toolCallMessages: ToolCallMessage[] The tool call messages\n * - text: string The final text message\n * @param isCompleted - Whether the analysis is completed\n * @returns The new state\n */\nfunction makeResultsAppender<PC extends BaseRoomConfig & AiSliceConfig>({\n resultId,\n streamMessage,\n errorMessage,\n isCompleted,\n}: {\n resultId: string;\n streamMessage?: StreamMessage;\n errorMessage?: ErrorMessageSchema;\n isCompleted?: boolean;\n}) {\n return (state: RoomShellSliceState<PC>) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n\n const result = findResultById(currentSession.analysisResults, resultId);\n if (result) {\n if (streamMessage && streamMessage.parts) {\n // copy all properties from streamMessage\n const newStreamMessage = {\n parts: streamMessage.parts.map((part) => {\n if (part.type === 'text') {\n return {\n type: 'text' as const,\n text: part.text,\n additionalData: part.additionalData,\n isCompleted: part.isCompleted,\n };\n } else if (part.type === 'tool-invocation') {\n return {\n type: 'tool-invocation' as const,\n toolInvocation: {\n toolCallId: part.toolInvocation.toolCallId,\n toolName: part.toolInvocation.toolName,\n args: part.toolInvocation.args,\n state: part.toolInvocation.state,\n result:\n part.toolInvocation.state === 'result'\n ? part.toolInvocation.result\n : undefined,\n },\n additionalData: part.additionalData,\n isCompleted: part.isCompleted,\n };\n } else {\n // TODO: handle other part types later\n return part;\n }\n }),\n };\n\n result.streamMessage = newStreamMessage as StreamMessage;\n }\n if (errorMessage) {\n result.errorMessage = errorMessage;\n }\n if (isCompleted) {\n result.isCompleted = isCompleted;\n }\n } else {\n console.error('Result not found', resultId);\n }\n });\n}\n\ntype RoomConfigWithAi = BaseRoomConfig & AiSliceConfig;\ntype RoomShellSliceStateWithAi = RoomShellSliceState<RoomConfigWithAi> &\n AiSliceState;\n\nexport function useStoreWithAi<T>(\n selector: (state: RoomShellSliceStateWithAi) => T,\n): T {\n return useBaseRoomShellStore<\n BaseRoomConfig & AiSliceConfig,\n RoomShellSliceState<RoomConfigWithAi>,\n T\n >((state) => selector(state as unknown as RoomShellSliceStateWithAi));\n}\n"]}
1
+ {"version":3,"file":"AiSlice.js","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {StreamMessage} from '@openassistant/core';\nimport {ExtendedTool} from '@openassistant/utils';\nimport {createId} from '@paralleldrive/cuid2';\nimport {DataTable} from '@sqlrooms/duckdb';\nimport {\n BaseRoomConfig,\n createSlice,\n RoomShellSliceState,\n useBaseRoomShellStore,\n type StateCreator,\n} from '@sqlrooms/room-shell';\nimport {produce, WritableDraft} from 'immer';\nimport {z} from 'zod';\nimport {getDefaultTools, runAnalysis} from './analysis';\nimport {\n AnalysisResultSchema,\n AnalysisSessionSchema,\n ErrorMessageSchema,\n} from './schemas';\n\nexport const AiSliceConfig = z.object({\n ai: z.object({\n sessions: z.array(AnalysisSessionSchema),\n currentSessionId: z.string().optional(),\n }),\n});\nexport type AiSliceConfig = z.infer<typeof AiSliceConfig>;\n\nexport function createDefaultAiConfig(\n props: Partial<AiSliceConfig['ai']>,\n): AiSliceConfig {\n const defaultSessionId = createId();\n return {\n ai: {\n sessions: [\n {\n id: defaultSessionId,\n name: 'Default Session',\n modelProvider: 'openai',\n model: 'gpt-4o-mini',\n analysisResults: [],\n createdAt: new Date(),\n },\n ],\n currentSessionId: defaultSessionId,\n ...props,\n },\n };\n}\n\n// template for the tool: Argument, LLM Result, Additional Data, Context\nexport type AiSliceTool = ExtendedTool<z.ZodTypeAny, unknown, unknown, unknown>;\n\nexport type AiSliceState = {\n ai: {\n analysisPrompt: string;\n isRunningAnalysis: boolean;\n tools: Record<string, AiSliceTool>;\n analysisAbortController?: AbortController;\n setAnalysisPrompt: (prompt: string) => void;\n startAnalysis: () => Promise<void>;\n cancelAnalysis: () => void;\n setAiModel: (modelProvider: string, model: string) => void;\n setCustomModelName: (customModelName: string) => void;\n setBaseUrl: (baseUrl: 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 getCurrentSession: () => AnalysisSessionSchema | undefined;\n deleteAnalysisResult: (sessionId: string, resultId: string) => void;\n findToolComponent: (toolName: string) => React.ComponentType | undefined;\n };\n};\n\n/**\n * Configuration options for creating an AI slice\n */\nexport interface AiSliceOptions {\n /** Initial prompt to display in the analysis input */\n initialAnalysisPrompt?: string;\n /** Custom tools to add to the AI assistant */\n customTools?: Record<string, AiSliceTool>;\n /**\n * Function to get custom instructions for the AI assistant\n * @param tablesSchema - The schema of the tables in the database\n * @returns The instructions string to use\n */\n getInstructions?: (tablesSchema: DataTable[]) => string;\n /**\n * Number of rows to share with LLM (default: 0)\n */\n numberOfRowsToShareWithLLM?: number;\n}\n\n/**\n * API key configuration for the AI slice\n */\nexport type AiSliceApiConfig =\n | {baseUrl: string; getApiKey?: never}\n | {getApiKey: (modelProvider: string) => string; baseUrl?: never};\n\n/**\n * Complete configuration for creating an AI slice\n */\nexport type CreateAiSliceConfig = AiSliceOptions & AiSliceApiConfig;\n\nexport function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>(\n config: CreateAiSliceConfig,\n): StateCreator<AiSliceState> {\n const {\n getApiKey,\n baseUrl,\n initialAnalysisPrompt = '',\n customTools = {},\n getInstructions,\n numberOfRowsToShareWithLLM,\n } = config;\n\n return createSlice<PC, AiSliceState>((set, get, store) => {\n return {\n ai: {\n analysisPrompt: initialAnalysisPrompt,\n isRunningAnalysis: false,\n\n tools: {\n ...getDefaultTools(store, numberOfRowsToShareWithLLM),\n ...customTools,\n },\n\n setAnalysisPrompt: (prompt: string) => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.analysisPrompt = prompt;\n }),\n );\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 * Set the custom model name for the current session\n * @param customModelName - The custom model name to set\n */\n setCustomModelName: (customModelName: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.customModelName = customModelName;\n }\n }),\n );\n },\n\n /**\n * Set the base URL for the current session\n * @param baseUrl - The server URL to set\n */\n setBaseUrl: (baseUrl: string) => {\n set((state) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (currentSession) {\n currentSession.baseUrl = baseUrl;\n }\n }),\n );\n },\n\n /**\n * Get the current active session\n */\n getCurrentSession: () => {\n const state = get();\n const {currentSessionId, sessions} = state.config.ai;\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 draft.config.ai.sessions.unshift({\n id: newSessionId,\n name: sessionName,\n modelProvider:\n modelProvider || currentSession?.modelProvider || 'openai',\n model: model || currentSession?.model || 'gpt-4.1',\n analysisResults: [],\n createdAt: new Date(),\n });\n draft.config.ai.currentSessionId = 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 draft.config.ai.currentSessionId = sessionId;\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.config.ai.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n session.name = name;\n }\n }),\n );\n },\n\n /**\n * Delete a session\n */\n deleteSession: (sessionId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const sessionIndex = draft.config.ai.sessions.findIndex(\n (s) => s.id === sessionId,\n );\n if (sessionIndex !== -1) {\n // Don't delete the last session\n if (draft.config.ai.sessions.length > 1) {\n draft.config.ai.sessions.splice(sessionIndex, 1);\n // If we deleted the current session, switch to another one\n if (draft.config.ai.currentSessionId === sessionId) {\n // Make sure there's at least one session before accessing its id\n if (draft.config.ai.sessions.length > 0) {\n const firstSession = draft.config.ai.sessions[0];\n if (firstSession) {\n draft.config.ai.currentSessionId = firstSession.id;\n }\n }\n }\n }\n }\n }),\n );\n },\n\n /**\n * Start the analysis\n * TODO: how to pass the history analysisResults?\n */\n startAnalysis: async () => {\n const resultId = createId();\n const abortController = new AbortController();\n const currentSession = get().ai.getCurrentSession();\n\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n\n set((state) =>\n produce(state, (draft) => {\n draft.ai.analysisAbortController = abortController;\n draft.ai.isRunningAnalysis = true;\n\n const session = draft.config.ai.sessions.find(\n (s) => s.id === draft.config.ai.currentSessionId,\n );\n\n if (session) {\n session.analysisResults.push({\n id: resultId,\n prompt: get().ai.analysisPrompt,\n streamMessage: {\n parts: [\n {\n type: 'text',\n text: '',\n },\n ],\n },\n isCompleted: false,\n });\n }\n }),\n );\n\n try {\n await runAnalysis({\n tableSchemas: get().db.tables,\n modelProvider: currentSession.modelProvider || 'openai',\n model: currentSession.model || 'gpt-4o-mini',\n customModelName: currentSession.customModelName,\n apiKey:\n getApiKey?.(currentSession.modelProvider || 'openai') || '',\n baseUrl: currentSession.baseUrl || baseUrl,\n prompt: get().ai.analysisPrompt,\n abortController,\n tools: {\n ...getDefaultTools(store, numberOfRowsToShareWithLLM),\n ...customTools,\n },\n getInstructions,\n onStreamResult: (isCompleted, streamMessage) => {\n set(\n makeResultsAppender({\n resultId,\n streamMessage,\n isCompleted,\n }),\n );\n },\n });\n } catch (err) {\n set(\n makeResultsAppender({\n resultId,\n isCompleted: true,\n errorMessage: {\n error: err instanceof Error ? err.message : String(err),\n },\n }),\n );\n } finally {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.isRunningAnalysis = false;\n draft.ai.analysisPrompt = '';\n }),\n );\n }\n },\n\n cancelAnalysis: () => {\n set((state) =>\n produce(state, (draft) => {\n draft.ai.isRunningAnalysis = false;\n }),\n );\n get().ai.analysisAbortController?.abort('Analysis cancelled');\n },\n\n /**\n * Delete an analysis result from a session\n */\n deleteAnalysisResult: (sessionId: string, resultId: string) => {\n set((state) =>\n produce(state, (draft) => {\n const session = draft.config.ai.sessions.find(\n (s) => s.id === sessionId,\n );\n if (session) {\n session.analysisResults = session.analysisResults.filter(\n (r) => r.id !== resultId,\n );\n }\n }),\n );\n },\n\n findToolComponent: (toolName: string) => {\n return Object.entries(get().ai.tools).find(\n ([name]) => name === toolName,\n )?.[1]?.component as React.ComponentType;\n },\n },\n };\n });\n}\n\n/**\n * Helper function to get the current session from state\n */\nfunction getCurrentSessionFromState<PC extends BaseRoomConfig & AiSliceConfig>(\n state: RoomShellSliceState<PC> | WritableDraft<RoomShellSliceState<PC>>,\n): AnalysisSessionSchema | undefined {\n const {currentSessionId, sessions} = state.config.ai;\n return sessions.find((session) => session.id === currentSessionId);\n}\n\nfunction findResultById(\n analysisResults: AnalysisResultSchema[],\n id: string,\n): AnalysisResultSchema | undefined {\n return analysisResults.find((result) => result.id === id);\n}\n\n/**\n * Appends the tool results, tool calls, and analysis to the state\n *\n * @param resultId - The id of the result to append to\n * @param message - The message to append to the state. The structure of the message is defined as:\n * - reasoning: string The reasoning of the assistant\n * - toolCallMessages: ToolCallMessage[] The tool call messages\n * - text: string The final text message\n * @param isCompleted - Whether the analysis is completed\n * @returns The new state\n */\nfunction makeResultsAppender<PC extends BaseRoomConfig & AiSliceConfig>({\n resultId,\n streamMessage,\n errorMessage,\n isCompleted,\n}: {\n resultId: string;\n streamMessage?: StreamMessage;\n errorMessage?: ErrorMessageSchema;\n isCompleted?: boolean;\n}) {\n return (state: RoomShellSliceState<PC>) =>\n produce(state, (draft) => {\n const currentSession = getCurrentSessionFromState(draft);\n if (!currentSession) {\n console.error('No current session found');\n return;\n }\n\n const result = findResultById(currentSession.analysisResults, resultId);\n if (result) {\n if (streamMessage && streamMessage.parts) {\n // copy all properties from streamMessage\n const newStreamMessage = {\n parts: streamMessage.parts.map((part) => {\n if (part.type === 'text') {\n return {\n type: 'text' as const,\n text: part.text,\n additionalData: part.additionalData,\n isCompleted: part.isCompleted,\n };\n } else if (part.type === 'tool-invocation') {\n return {\n type: 'tool-invocation' as const,\n toolInvocation: {\n toolCallId: part.toolInvocation.toolCallId,\n toolName: part.toolInvocation.toolName,\n args: part.toolInvocation.args,\n state: part.toolInvocation.state,\n result:\n part.toolInvocation.state === 'result'\n ? part.toolInvocation.result\n : undefined,\n },\n additionalData: part.additionalData,\n isCompleted: part.isCompleted,\n };\n } else {\n // TODO: handle other part types later\n return part;\n }\n }),\n };\n\n result.streamMessage = newStreamMessage as StreamMessage;\n }\n if (errorMessage) {\n result.errorMessage = errorMessage;\n }\n if (isCompleted) {\n result.isCompleted = isCompleted;\n }\n } else {\n console.error('Result not found', resultId);\n }\n });\n}\n\ntype RoomConfigWithAi = BaseRoomConfig & AiSliceConfig;\ntype RoomShellSliceStateWithAi = RoomShellSliceState<RoomConfigWithAi> &\n AiSliceState;\n\nexport function useStoreWithAi<T>(\n selector: (state: RoomShellSliceStateWithAi) => T,\n): T {\n return useBaseRoomShellStore<\n BaseRoomConfig & AiSliceConfig,\n RoomShellSliceState<RoomConfigWithAi>,\n T\n >((state) => selector(state as unknown as RoomShellSliceStateWithAi));\n}\n"]}
@@ -62,6 +62,6 @@ export declare function runAnalysis({ name, tableSchemas, modelProvider, model,
62
62
  * Includes:
63
63
  * - query: Executes SQL queries against DuckDB
64
64
  */
65
- export declare function getDefaultTools(store: StoreApi<AiSliceState & DuckDbSliceState>): Record<string, AiSliceTool>;
65
+ export declare function getDefaultTools(store: StoreApi<AiSliceState & DuckDbSliceState>, numberOfRowsToShareWithLLM?: number): Record<string, AiSliceTool>;
66
66
  export {};
67
67
  //# sourceMappingURL=analysis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,SAAS,EAET,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,YAAY,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAC,oBAAoB,EAAsB,MAAM,WAAW,CAAC;AAyDpE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,SAAS,EAAE,GAAG,MAAM,CAExE;AA0BD;;GAEG;AACH,KAAK,kBAAkB,GAAG;IACxB,YAAY,EAAE,SAAS,EAAE,CAAC;IAE1B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IAEtB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IAEd,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IAEf,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IAEf,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mEAAmE;IACnE,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAEzC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEpC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,MAAM,CAAC;IAExD;;;;OAIG;IACH,cAAc,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/E,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,EAChC,IAAoB,EACpB,YAAY,EACZ,aAAa,EACb,KAAK,EACL,eAAe,EACf,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,cAAc,EACd,QAAY,EACZ,KAAU,EACV,eAAe,EACf,OAAO,GACR,EAAE,kBAAkB;;;GAgDpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,GAC/C,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAkD7B"}
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,SAAS,EAET,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,YAAY,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAC,oBAAoB,EAAsB,MAAM,WAAW,CAAC;AA4DpE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,SAAS,EAAE,GAAG,MAAM,CAExE;AA0BD;;GAEG;AACH,KAAK,kBAAkB,GAAG;IACxB,YAAY,EAAE,SAAS,EAAE,CAAC;IAE1B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IAEtB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IAEd,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IAEf,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IAEf,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mEAAmE;IACnE,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAEzC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEpC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,MAAM,CAAC;IAExD;;;;OAIG;IACH,cAAc,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/E,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,EAChC,IAAoB,EACpB,YAAY,EACZ,aAAa,EACb,KAAK,EACL,eAAe,EACf,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,cAAc,EACd,QAAY,EACZ,KAAU,EACV,eAAe,EACf,OAAO,GACR,EAAE,kBAAkB;;;GAgDpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,EAChD,0BAA0B,GAAE,MAAU,GACrC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAmD7B"}
package/dist/analysis.js CHANGED
@@ -54,6 +54,9 @@ For your final answer:
54
54
  - Explain your reasoning step by step
55
55
  - Include relevant statistics or metrics
56
56
  - For each prompt, please always provide the final answer.
57
+ - IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:
58
+ * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.
59
+ * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.
57
60
 
58
61
  Please use the following schema for the tables:
59
62
  `;
@@ -110,7 +113,7 @@ export async function runAnalysis({ name = 'sqlrooms-ai', tableSchemas, modelPro
110
113
  toolChoice: 'auto', // this will enable streaming
111
114
  maxSteps,
112
115
  ...(abortController ? { abortController } : {}),
113
- ...(modelProvider === 'ollama' && baseUrl ? { baseUrl } : {}),
116
+ baseUrl, // ollama base url or LLM proxy server url
114
117
  });
115
118
  // restore ai messages from historyAnalysis?
116
119
  if (historyAnalysis) {
@@ -135,14 +138,13 @@ export async function runAnalysis({ name = 'sqlrooms-ai', tableSchemas, modelPro
135
138
  * Includes:
136
139
  * - query: Executes SQL queries against DuckDB
137
140
  */
138
- export function getDefaultTools(store) {
141
+ export function getDefaultTools(store, numberOfRowsToShareWithLLM = 0) {
139
142
  return {
140
143
  query: extendedTool({
141
144
  description: `A tool for running SQL queries on the tables in the database.
142
145
  Please only run one query at a time.
143
146
  If a query fails, please don't try to run it again with the same syntax.`,
144
147
  parameters: QueryToolParameters,
145
- // TODO: specify the return type e.g. Promise<Partial<ToolCallMessage>>
146
148
  execute: async ({ type, sqlQuery }) => {
147
149
  try {
148
150
  const connector = await store.getState().db.getConnector();
@@ -152,16 +154,17 @@ If a query fails, please don't try to run it again with the same syntax.`,
152
154
  const summaryData = sqlQuery.toLowerCase().includes('summarize')
153
155
  ? arrowTableToJson(result)
154
156
  : await getQuerySummary(connector, sqlQuery);
155
- // Get first 2 rows of the result as a json object
156
- const subResult = result.slice(0, 2);
157
- const firstTwoRows = arrowTableToJson(subResult);
157
+ // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM
158
+ const firstRows = numberOfRowsToShareWithLLM > 0
159
+ ? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))
160
+ : [];
158
161
  return {
159
162
  llmResult: {
160
163
  success: true,
161
164
  data: {
162
165
  type,
163
166
  summary: summaryData,
164
- firstTwoRows,
167
+ ...(numberOfRowsToShareWithLLM > 0 ? { firstRows } : {}),
165
168
  },
166
169
  },
167
170
  additionalData: {
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createAssistant,\n rebuildMessages,\n StreamMessage,\n} from '@openassistant/core';\nimport {extendedTool} from '@openassistant/utils';\nimport {\n arrowTableToJson,\n DataTable,\n DuckDbConnector,\n DuckDbSliceState,\n} from '@sqlrooms/duckdb';\nimport type {StoreApi} from '@sqlrooms/room-shell';\nimport {AiSliceState, AiSliceTool} from './AiSlice';\nimport {QueryToolResult} from './components/tools/QueryToolResult';\nimport {AnalysisResultSchema, QueryToolParameters} from './schemas';\nimport {convertToCoreMessages} from 'ai';\n\n/**\n * System prompt template for the AI assistant that provides instructions for:\n * - Using DuckDB-specific SQL syntax and functions\n * - Handling query results and error cases\n * - Creating visualizations with VegaLite\n * - Formatting final answers\n */\nconst DEFAULT_INSTRUCTIONS = `\nYou are analyzing tables in DuckDB database in the context of a room.\n\nInstructions for analysis:\n- When using 'query' tool, please assign parameter 'type' with value 'query'\n- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)\n- Some key DuckDB-specific functions to use:\n * regexp_matches() for regex (not regexp_like)\n * strftime() for date formatting (not to_char)\n * list_aggregate() for array operations\n * unnest() for array expansion\n * regr_sxy()\n * corr()\n * skewness()\n- Please always try to use SQL queries to answer users questions\n- Please run tool calls sequentially, don't run multiple tool calls in parallel\n- IMPORTANT: Do not list out raw query results in your response. Instead:\n * Describe the results in natural language\n * Provide summary statistics\n * Use comparisons and relative terms\n * Include only the most relevant values if necessary\n- Break down complex problems into smaller steps\n- Use \"SUMMARIZE table_name\"for quick overview of the table\n- Please don't modify data\n- IMPORTANT: When you receive an error response from a tool call (where success: false):\n * Stop making any further tool calls immediately\n * Return a final answer that includes the error message\n * Explain what went wrong and suggest possible fixes if applicable\n\nWhen creating visualizations:\n- Follow VegaLite syntax\n- Choose appropriate chart types based on the data and analysis goals\n- Use clear titles and axis labels\n- Consider color schemes for better readability\n- Add meaningful tooltips when relevant\n- Format numbers and dates appropriately\n- Use aggregations when dealing with large datasets\n\nFor your final answer:\n- Provide an explanation for how you got it\n- Explain your reasoning step by step\n- Include relevant statistics or metrics\n- For each prompt, please always provide the final answer.\n\nPlease use the following schema for the tables:\n`;\n\n/**\n * Returns the default system instructions for the AI assistant\n */\nexport function getDefaultInstructions(tablesSchema: DataTable[]): string {\n return `${DEFAULT_INSTRUCTIONS}\\n${JSON.stringify(tablesSchema)}`;\n}\n\n/**\n * Generates summary statistics for a SQL query result\n * @param connector - DuckDB connection instance\n * @param sqlQuery - SQL SELECT query to analyze\n * @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails\n */\nasync function getQuerySummary(connector: DuckDbConnector, sqlQuery: string) {\n if (!sqlQuery.toLowerCase().trim().startsWith('select')) {\n return null;\n }\n\n try {\n const viewName = `temp_result_${Date.now()}`; // unique view name to avoid conflicts\n await connector.query(`CREATE TEMPORARY VIEW ${viewName} AS ${sqlQuery}`);\n const summaryResult = await connector.query(`SUMMARIZE ${viewName}`);\n const summaryData = arrowTableToJson(summaryResult);\n await connector.query(`DROP VIEW IF EXISTS ${viewName}`);\n return summaryData;\n } catch (error) {\n console.warn('Failed to get summary:', error);\n return null;\n }\n}\n\n/**\n * Configuration options for running an AI analysis session\n */\ntype AnalysisParameters = {\n tableSchemas: DataTable[];\n\n /** Assistant instance identifier (default: 'sqlrooms-ai') */\n name?: string;\n\n /** AI model provider (e.g., 'openai', 'anthropic') */\n modelProvider: string;\n\n /** Model identifier (e.g., 'gpt-4', 'claude-3') */\n model: string;\n\n /** Custom model name for Ollama (used when model is 'custom') */\n customModelName?: string;\n\n /** Authentication key for the model provider's API */\n apiKey: string;\n\n /** Analysis prompt or question to be processed */\n prompt: string;\n\n /** Optional controller for canceling the analysis operation */\n abortController?: AbortController;\n\n /** Maximum number of analysis steps allowed (default: 100) */\n maxSteps?: number;\n\n /** The history of analysis results (e.g. saved in localStorage) */\n historyAnalysis?: AnalysisResultSchema[];\n\n /** Tools to use in the analysis */\n tools?: Record<string, AiSliceTool>;\n\n /** Base URL for Ollama provider (required when modelProvider is 'ollama') */\n baseUrl?: string;\n\n /**\n * Function to get custom instructions for the AI assistant\n * @param tablesSchema - The schema of the tables in the database\n * @returns The instructions string to use\n */\n getInstructions?: (tablesSchema: DataTable[]) => string;\n\n /**\n * Callback for handling streaming results\n * @param isCompleted - Indicates if this is the final message in the stream\n * @param streamMessage - Current message content being streamed\n */\n onStreamResult: (isCompleted: boolean, streamMessage?: StreamMessage) => void;\n};\n\n/**\n * Executes an AI analysis session on the room data\n *\n * @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.\n * @returns Object containing tool calls executed and the final analysis result\n */\nexport async function runAnalysis({\n name = 'sqlrooms-ai',\n tableSchemas,\n modelProvider,\n model,\n customModelName,\n apiKey,\n prompt,\n abortController,\n historyAnalysis,\n onStreamResult,\n maxSteps = 5,\n tools = {},\n getInstructions,\n baseUrl,\n}: AnalysisParameters) {\n // Use custom model name if model is 'custom' and customModelName is provided\n const actualModel =\n model === 'custom' && customModelName ? customModelName : model;\n\n // get the singleton assistant instance\n const assistant = await createAssistant({\n name,\n modelProvider,\n model: actualModel,\n apiKey,\n version: 'v1',\n instructions: getInstructions\n ? getInstructions(tableSchemas)\n : getDefaultInstructions(tableSchemas),\n tools: tools,\n temperature: 0,\n toolChoice: 'auto', // this will enable streaming\n maxSteps,\n ...(abortController ? {abortController} : {}),\n ...(modelProvider === 'ollama' && baseUrl ? {baseUrl} : {}),\n });\n\n // restore ai messages from historyAnalysis?\n if (historyAnalysis) {\n const historyMessages = historyAnalysis.map((analysis) => ({\n prompt: analysis.prompt,\n response: analysis.streamMessage as StreamMessage,\n }));\n const initialMessages = rebuildMessages(historyMessages);\n assistant.setMessages(convertToCoreMessages(initialMessages));\n }\n\n // process the prompt\n const newMessages = await assistant.processTextMessage({\n textMessage: prompt,\n streamMessageCallback: ({\n isCompleted,\n message,\n }: {\n isCompleted?: boolean;\n message?: StreamMessage;\n }) => {\n onStreamResult(isCompleted ?? false, message);\n },\n });\n\n return newMessages;\n}\n\n/**\n * Default tools available to the AI assistant for data analysis\n * Includes:\n * - query: Executes SQL queries against DuckDB\n */\nexport function getDefaultTools(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n): Record<string, AiSliceTool> {\n return {\n query: extendedTool({\n description: `A tool for running SQL queries on the tables in the database.\nPlease only run one query at a time.\nIf a query fails, please don't try to run it again with the same syntax.`,\n parameters: QueryToolParameters,\n // TODO: specify the return type e.g. Promise<Partial<ToolCallMessage>>\n execute: async ({type, sqlQuery}) => {\n try {\n const connector = await store.getState().db.getConnector();\n // TODO use options.abortSignal: maybe call db.cancelPendingQuery\n const result = await connector.query(sqlQuery);\n // Only get summary if the query isn't already a SUMMARIZE query\n const summaryData = sqlQuery.toLowerCase().includes('summarize')\n ? arrowTableToJson(result)\n : await getQuerySummary(connector, sqlQuery);\n\n // Get first 2 rows of the result as a json object\n const subResult = result.slice(0, 2);\n const firstTwoRows = arrowTableToJson(subResult);\n\n return {\n llmResult: {\n success: true,\n data: {\n type,\n summary: summaryData,\n firstTwoRows,\n },\n },\n additionalData: {\n title: 'Query Result',\n sqlQuery,\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n details: 'Query execution failed.',\n errorMessage:\n error instanceof Error ? error.message : 'Unknown error',\n },\n };\n }\n },\n component: QueryToolResult,\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createAssistant,\n rebuildMessages,\n StreamMessage,\n} from '@openassistant/core';\nimport {extendedTool} from '@openassistant/utils';\nimport {\n arrowTableToJson,\n DataTable,\n DuckDbConnector,\n DuckDbSliceState,\n} from '@sqlrooms/duckdb';\nimport type {StoreApi} from '@sqlrooms/room-shell';\nimport {AiSliceState, AiSliceTool} from './AiSlice';\nimport {QueryToolResult} from './components/tools/QueryToolResult';\nimport {AnalysisResultSchema, QueryToolParameters} from './schemas';\nimport {convertToCoreMessages} from 'ai';\n\n/**\n * System prompt template for the AI assistant that provides instructions for:\n * - Using DuckDB-specific SQL syntax and functions\n * - Handling query results and error cases\n * - Creating visualizations with VegaLite\n * - Formatting final answers\n */\nconst DEFAULT_INSTRUCTIONS = `\nYou are analyzing tables in DuckDB database in the context of a room.\n\nInstructions for analysis:\n- When using 'query' tool, please assign parameter 'type' with value 'query'\n- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)\n- Some key DuckDB-specific functions to use:\n * regexp_matches() for regex (not regexp_like)\n * strftime() for date formatting (not to_char)\n * list_aggregate() for array operations\n * unnest() for array expansion\n * regr_sxy()\n * corr()\n * skewness()\n- Please always try to use SQL queries to answer users questions\n- Please run tool calls sequentially, don't run multiple tool calls in parallel\n- IMPORTANT: Do not list out raw query results in your response. Instead:\n * Describe the results in natural language\n * Provide summary statistics\n * Use comparisons and relative terms\n * Include only the most relevant values if necessary\n- Break down complex problems into smaller steps\n- Use \"SUMMARIZE table_name\"for quick overview of the table\n- Please don't modify data\n- IMPORTANT: When you receive an error response from a tool call (where success: false):\n * Stop making any further tool calls immediately\n * Return a final answer that includes the error message\n * Explain what went wrong and suggest possible fixes if applicable\n\nWhen creating visualizations:\n- Follow VegaLite syntax\n- Choose appropriate chart types based on the data and analysis goals\n- Use clear titles and axis labels\n- Consider color schemes for better readability\n- Add meaningful tooltips when relevant\n- Format numbers and dates appropriately\n- Use aggregations when dealing with large datasets\n\nFor your final answer:\n- Provide an explanation for how you got it\n- Explain your reasoning step by step\n- Include relevant statistics or metrics\n- For each prompt, please always provide the final answer.\n- IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:\n * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.\n * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.\n\nPlease use the following schema for the tables:\n`;\n\n/**\n * Returns the default system instructions for the AI assistant\n */\nexport function getDefaultInstructions(tablesSchema: DataTable[]): string {\n return `${DEFAULT_INSTRUCTIONS}\\n${JSON.stringify(tablesSchema)}`;\n}\n\n/**\n * Generates summary statistics for a SQL query result\n * @param connector - DuckDB connection instance\n * @param sqlQuery - SQL SELECT query to analyze\n * @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails\n */\nasync function getQuerySummary(connector: DuckDbConnector, sqlQuery: string) {\n if (!sqlQuery.toLowerCase().trim().startsWith('select')) {\n return null;\n }\n\n try {\n const viewName = `temp_result_${Date.now()}`; // unique view name to avoid conflicts\n await connector.query(`CREATE TEMPORARY VIEW ${viewName} AS ${sqlQuery}`);\n const summaryResult = await connector.query(`SUMMARIZE ${viewName}`);\n const summaryData = arrowTableToJson(summaryResult);\n await connector.query(`DROP VIEW IF EXISTS ${viewName}`);\n return summaryData;\n } catch (error) {\n console.warn('Failed to get summary:', error);\n return null;\n }\n}\n\n/**\n * Configuration options for running an AI analysis session\n */\ntype AnalysisParameters = {\n tableSchemas: DataTable[];\n\n /** Assistant instance identifier (default: 'sqlrooms-ai') */\n name?: string;\n\n /** AI model provider (e.g., 'openai', 'anthropic') */\n modelProvider: string;\n\n /** Model identifier (e.g., 'gpt-4', 'claude-3') */\n model: string;\n\n /** Custom model name for Ollama (used when model is 'custom') */\n customModelName?: string;\n\n /** Authentication key for the model provider's API */\n apiKey: string;\n\n /** Analysis prompt or question to be processed */\n prompt: string;\n\n /** Optional controller for canceling the analysis operation */\n abortController?: AbortController;\n\n /** Maximum number of analysis steps allowed (default: 100) */\n maxSteps?: number;\n\n /** The history of analysis results (e.g. saved in localStorage) */\n historyAnalysis?: AnalysisResultSchema[];\n\n /** Tools to use in the analysis */\n tools?: Record<string, AiSliceTool>;\n\n /** Base URL for Ollama provider (required when modelProvider is 'ollama') */\n baseUrl?: string;\n\n /**\n * Function to get custom instructions for the AI assistant\n * @param tablesSchema - The schema of the tables in the database\n * @returns The instructions string to use\n */\n getInstructions?: (tablesSchema: DataTable[]) => string;\n\n /**\n * Callback for handling streaming results\n * @param isCompleted - Indicates if this is the final message in the stream\n * @param streamMessage - Current message content being streamed\n */\n onStreamResult: (isCompleted: boolean, streamMessage?: StreamMessage) => void;\n};\n\n/**\n * Executes an AI analysis session on the room data\n *\n * @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.\n * @returns Object containing tool calls executed and the final analysis result\n */\nexport async function runAnalysis({\n name = 'sqlrooms-ai',\n tableSchemas,\n modelProvider,\n model,\n customModelName,\n apiKey,\n prompt,\n abortController,\n historyAnalysis,\n onStreamResult,\n maxSteps = 5,\n tools = {},\n getInstructions,\n baseUrl,\n}: AnalysisParameters) {\n // Use custom model name if model is 'custom' and customModelName is provided\n const actualModel =\n model === 'custom' && customModelName ? customModelName : model;\n\n // get the singleton assistant instance\n const assistant = await createAssistant({\n name,\n modelProvider,\n model: actualModel,\n apiKey,\n version: 'v1',\n instructions: getInstructions\n ? getInstructions(tableSchemas)\n : getDefaultInstructions(tableSchemas),\n tools: tools,\n temperature: 0,\n toolChoice: 'auto', // this will enable streaming\n maxSteps,\n ...(abortController ? {abortController} : {}),\n baseUrl, // ollama base url or LLM proxy server url\n });\n\n // restore ai messages from historyAnalysis?\n if (historyAnalysis) {\n const historyMessages = historyAnalysis.map((analysis) => ({\n prompt: analysis.prompt,\n response: analysis.streamMessage as StreamMessage,\n }));\n const initialMessages = rebuildMessages(historyMessages);\n assistant.setMessages(convertToCoreMessages(initialMessages));\n }\n\n // process the prompt\n const newMessages = await assistant.processTextMessage({\n textMessage: prompt,\n streamMessageCallback: ({\n isCompleted,\n message,\n }: {\n isCompleted?: boolean;\n message?: StreamMessage;\n }) => {\n onStreamResult(isCompleted ?? false, message);\n },\n });\n\n return newMessages;\n}\n\n/**\n * Default tools available to the AI assistant for data analysis\n * Includes:\n * - query: Executes SQL queries against DuckDB\n */\nexport function getDefaultTools(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n numberOfRowsToShareWithLLM: number = 0,\n): Record<string, AiSliceTool> {\n return {\n query: extendedTool({\n description: `A tool for running SQL queries on the tables in the database.\nPlease only run one query at a time.\nIf a query fails, please don't try to run it again with the same syntax.`,\n parameters: QueryToolParameters,\n execute: async ({type, sqlQuery}) => {\n try {\n const connector = await store.getState().db.getConnector();\n // TODO use options.abortSignal: maybe call db.cancelPendingQuery\n const result = await connector.query(sqlQuery);\n // Only get summary if the query isn't already a SUMMARIZE query\n const summaryData = sqlQuery.toLowerCase().includes('summarize')\n ? arrowTableToJson(result)\n : await getQuerySummary(connector, sqlQuery);\n\n // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM\n const firstRows =\n numberOfRowsToShareWithLLM > 0\n ? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))\n : [];\n\n return {\n llmResult: {\n success: true,\n data: {\n type,\n summary: summaryData,\n ...(numberOfRowsToShareWithLLM > 0 ? {firstRows} : {}),\n },\n },\n additionalData: {\n title: 'Query Result',\n sqlQuery,\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n details: 'Query execution failed.',\n errorMessage:\n error instanceof Error ? error.message : 'Unknown error',\n },\n };\n }\n },\n component: QueryToolResult,\n }),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AA6GF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDAyEzB,CAAC"}
1
+ {"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AA6GF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDA0EzB,CAAC"}
@@ -94,9 +94,9 @@ export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
94
94
  return null;
95
95
  }
96
96
  }, [thinkContents, expandedThink, toggleThinkExpansion]);
97
- return (_jsx("div", { className: "flex flex-col gap-5", children: _jsx(MessageContainer, { isSuccess: true, type: props.isAnswer ? 'answer' : 'thinking', content: props, children: _jsx(Markdown, { className: "prose dark:prose-invert max-w-none text-sm", remarkPlugins: [remarkGfm], rehypePlugins: [rehypeRaw], components: {
98
- // @ts-expect-error - Custom HTML element not in react-markdown types
99
- 'think-block': thinkBlockComponent,
100
- }, children: processedContent }) }) }));
97
+ return (_jsx("div", { className: "flex flex-col gap-5", children: _jsx(MessageContainer, { isSuccess: true, type: props.isAnswer ? 'answer' : 'thinking', content: props, children: _jsx("div", { className: "prose dark:prose-invert max-w-none text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeRaw], components: {
98
+ // @ts-expect-error - Custom HTML element not in react-markdown types
99
+ 'think-block': thinkBlockComponent,
100
+ }, children: processedContent }) }) }) }));
101
101
  });
102
102
  //# sourceMappingURL=AnalysisAnswer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useState, useCallback, useMemo} from 'react';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\nimport {truncate} from '@sqlrooms/utils';\nimport {MessageContainer} from './MessageContainer';\nimport {BrainIcon} from 'lucide-react';\nimport {cn} from '@sqlrooms/ui';\n\ntype AnalysisAnswerProps = {\n content: string;\n isAnswer: boolean;\n};\n\ntype ThinkContent = {\n content: string;\n isComplete: boolean;\n index: number;\n};\n\n// Constants moved outside component to prevent recreation\nconst THINK_WORD_LIMIT = 10;\nconst COMPLETE_THINK_REGEX = /<think>([\\s\\S]*?)<\\/think>/g;\nconst INCOMPLETE_THINK_REGEX = /<think>([\\s\\S]*)$/;\n\n/**\n * Processes content and extracts think content in one pass\n */\nconst processContent = (\n originalContent: string,\n): {\n processedContent: string;\n thinkContents: ThinkContent[];\n} => {\n const thinkContents: ThinkContent[] = [];\n let processedContent = originalContent;\n let index = 0;\n\n // Replace complete think tags\n processedContent = processedContent.replace(\n COMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: true,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n // Replace incomplete think tags (no closing tag)\n processedContent = processedContent.replace(\n INCOMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: false,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n return {processedContent, thinkContents};\n};\n\n/**\n * ThinkBlock component for rendering individual think blocks\n */\nconst ThinkBlock = React.memo<{\n className?: string;\n thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion, className}) => {\n const {content, isComplete, index} = thinkContent;\n\n const displayText =\n isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;\n const needsTruncation =\n isComplete && content.split(' ').length > THINK_WORD_LIMIT;\n\n return (\n <span\n key={`think-${index}`}\n className={cn(\n 'inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400',\n isExpanded && 'bg-gray-50 dark:bg-gray-800/50',\n className,\n )}\n >\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <BrainIcon\n className=\"mb-1 inline-block opacity-60 grayscale\"\n size={12}\n />{' '}\n {displayText}\n </span>\n </span>{' '}\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300\"\n >\n {isExpanded ? 'Show less' : 'Show more thinking'}\n </button>\n )}\n </span>\n );\n});\n\nThinkBlock.displayName = 'ThinkBlock';\n\n/**\n * Renders an analysis answer with markdown content of the final streaming response.\n * Supports streaming think content that may arrive in chunks (e.g., \"<think>Hello\" before \"</think>\").\n *\n * @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.\n * @returns {JSX.Element} The rendered answer tool call\n */\nexport const AnalysisAnswer = React.memo(function AnalysisAnswer(\n props: AnalysisAnswerProps,\n) {\n const [expandedThink, setExpandedThink] = useState<Set<string>>(new Set());\n\n const toggleThinkExpansion = useCallback((content: string) => {\n setExpandedThink((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(content)) {\n newExpanded.delete(content);\n } else {\n newExpanded.add(content);\n }\n return newExpanded;\n });\n }, []);\n\n // Memoize content processing to avoid recalculation on every render\n const {processedContent, thinkContents} = useMemo(\n () => processContent(props.content),\n [props.content],\n );\n\n // Memoize the think-block component to prevent unnecessary re-renders\n const thinkBlockComponent = useCallback(\n (thinkBlock: any) => {\n try {\n const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);\n const thinkContent = thinkContents[index];\n\n if (!thinkContent) {\n console.warn(`Think content not found for index: ${index}`);\n return null;\n }\n\n const isExpanded = expandedThink.has(thinkContent.content);\n\n return (\n <ThinkBlock\n thinkContent={thinkContent}\n isExpanded={isExpanded}\n onToggleExpansion={toggleThinkExpansion}\n />\n );\n } catch (error) {\n console.error('Error rendering think block:', error);\n return null;\n }\n },\n [thinkContents, expandedThink, toggleThinkExpansion],\n );\n\n return (\n <div className=\"flex flex-col gap-5\">\n <MessageContainer\n isSuccess={true}\n type={props.isAnswer ? 'answer' : 'thinking'}\n content={props}\n >\n <Markdown\n className=\"prose dark:prose-invert max-w-none text-sm\"\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n // @ts-expect-error - Custom HTML element not in react-markdown types\n 'think-block': thinkBlockComponent,\n }}\n >\n {processedContent}\n </Markdown>\n </MessageContainer>\n </div>\n );\n});\n"]}
1
+ {"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useState, useCallback, useMemo} from 'react';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\nimport {truncate} from '@sqlrooms/utils';\nimport {MessageContainer} from './MessageContainer';\nimport {BrainIcon} from 'lucide-react';\nimport {cn} from '@sqlrooms/ui';\n\ntype AnalysisAnswerProps = {\n content: string;\n isAnswer: boolean;\n};\n\ntype ThinkContent = {\n content: string;\n isComplete: boolean;\n index: number;\n};\n\n// Constants moved outside component to prevent recreation\nconst THINK_WORD_LIMIT = 10;\nconst COMPLETE_THINK_REGEX = /<think>([\\s\\S]*?)<\\/think>/g;\nconst INCOMPLETE_THINK_REGEX = /<think>([\\s\\S]*)$/;\n\n/**\n * Processes content and extracts think content in one pass\n */\nconst processContent = (\n originalContent: string,\n): {\n processedContent: string;\n thinkContents: ThinkContent[];\n} => {\n const thinkContents: ThinkContent[] = [];\n let processedContent = originalContent;\n let index = 0;\n\n // Replace complete think tags\n processedContent = processedContent.replace(\n COMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: true,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n // Replace incomplete think tags (no closing tag)\n processedContent = processedContent.replace(\n INCOMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: false,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n return {processedContent, thinkContents};\n};\n\n/**\n * ThinkBlock component for rendering individual think blocks\n */\nconst ThinkBlock = React.memo<{\n className?: string;\n thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion, className}) => {\n const {content, isComplete, index} = thinkContent;\n\n const displayText =\n isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;\n const needsTruncation =\n isComplete && content.split(' ').length > THINK_WORD_LIMIT;\n\n return (\n <span\n key={`think-${index}`}\n className={cn(\n 'inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400',\n isExpanded && 'bg-gray-50 dark:bg-gray-800/50',\n className,\n )}\n >\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <BrainIcon\n className=\"mb-1 inline-block opacity-60 grayscale\"\n size={12}\n />{' '}\n {displayText}\n </span>\n </span>{' '}\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300\"\n >\n {isExpanded ? 'Show less' : 'Show more thinking'}\n </button>\n )}\n </span>\n );\n});\n\nThinkBlock.displayName = 'ThinkBlock';\n\n/**\n * Renders an analysis answer with markdown content of the final streaming response.\n * Supports streaming think content that may arrive in chunks (e.g., \"<think>Hello\" before \"</think>\").\n *\n * @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.\n * @returns {JSX.Element} The rendered answer tool call\n */\nexport const AnalysisAnswer = React.memo(function AnalysisAnswer(\n props: AnalysisAnswerProps,\n) {\n const [expandedThink, setExpandedThink] = useState<Set<string>>(new Set());\n\n const toggleThinkExpansion = useCallback((content: string) => {\n setExpandedThink((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(content)) {\n newExpanded.delete(content);\n } else {\n newExpanded.add(content);\n }\n return newExpanded;\n });\n }, []);\n\n // Memoize content processing to avoid recalculation on every render\n const {processedContent, thinkContents} = useMemo(\n () => processContent(props.content),\n [props.content],\n );\n\n // Memoize the think-block component to prevent unnecessary re-renders\n const thinkBlockComponent = useCallback(\n (thinkBlock: any) => {\n try {\n const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);\n const thinkContent = thinkContents[index];\n\n if (!thinkContent) {\n console.warn(`Think content not found for index: ${index}`);\n return null;\n }\n\n const isExpanded = expandedThink.has(thinkContent.content);\n\n return (\n <ThinkBlock\n thinkContent={thinkContent}\n isExpanded={isExpanded}\n onToggleExpansion={toggleThinkExpansion}\n />\n );\n } catch (error) {\n console.error('Error rendering think block:', error);\n return null;\n }\n },\n [thinkContents, expandedThink, toggleThinkExpansion],\n );\n\n return (\n <div className=\"flex flex-col gap-5\">\n <MessageContainer\n isSuccess={true}\n type={props.isAnswer ? 'answer' : 'thinking'}\n content={props}\n >\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n // @ts-expect-error - Custom HTML element not in react-markdown types\n 'think-block': thinkBlockComponent,\n }}\n >\n {processedContent}\n </Markdown>\n </div>\n </MessageContainer>\n </div>\n );\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorMessage.d.ts","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,2CAWzD"}
1
+ {"version":3,"file":"ErrorMessage.d.ts","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,2CAQzD"}
@@ -3,6 +3,6 @@ import Markdown from 'react-markdown';
3
3
  import remarkGfm from 'remark-gfm';
4
4
  import { MessageContainer } from './MessageContainer';
5
5
  export function ErrorMessage(props) {
6
- return (_jsx(MessageContainer, { isSuccess: false, type: "error", content: props, children: _jsx(Markdown, { className: "prose dark:prose-invert max-w-none text-sm", remarkPlugins: [remarkGfm], children: props.errorMessage }) }));
6
+ return (_jsx(MessageContainer, { isSuccess: false, type: "error", content: props, children: _jsx("div", { className: "prose dark:prose-invert max-w-none text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], children: props.errorMessage }) }) }));
7
7
  }
8
8
  //# sourceMappingURL=ErrorMessage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorMessage.js","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":";AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,OAAO,CACL,KAAC,gBAAgB,IAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,KAAK,YAC7D,KAAC,QAAQ,IACP,SAAS,EAAC,4CAA4C,EACtD,aAAa,EAAE,CAAC,SAAS,CAAC,YAEzB,KAAK,CAAC,YAAY,GACV,GACM,CACpB,CAAC;AACJ,CAAC","sourcesContent":["import Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport {MessageContainer} from './MessageContainer';\n\nexport function ErrorMessage(props: {errorMessage: string}) {\n return (\n <MessageContainer isSuccess={false} type=\"error\" content={props}>\n <Markdown\n className=\"prose dark:prose-invert max-w-none text-sm\"\n remarkPlugins={[remarkGfm]}\n >\n {props.errorMessage}\n </Markdown>\n </MessageContainer>\n );\n}\n"]}
1
+ {"version":3,"file":"ErrorMessage.js","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":";AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,OAAO,CACL,KAAC,gBAAgB,IAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,KAAK,YAC7D,cAAK,SAAS,EAAC,4CAA4C,YACzD,KAAC,QAAQ,IAAC,aAAa,EAAE,CAAC,SAAS,CAAC,YAAG,KAAK,CAAC,YAAY,GAAY,GACjE,GACW,CACpB,CAAC;AACJ,CAAC","sourcesContent":["import Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport {MessageContainer} from './MessageContainer';\n\nexport function ErrorMessage(props: {errorMessage: string}) {\n return (\n <MessageContainer isSuccess={false} type=\"error\" content={props}>\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown remarkPlugins={[remarkGfm]}>{props.errorMessage}</Markdown>\n </div>\n </MessageContainer>\n );\n}\n"]}
package/dist/schemas.d.ts CHANGED
@@ -213,13 +213,13 @@ export declare const AnalysisResultSchema: z.ZodObject<{
213
213
  } | undefined;
214
214
  }>;
215
215
  export type AnalysisResultSchema = z.infer<typeof AnalysisResultSchema>;
216
- export declare const AnalysisSessionSchema: z.ZodObject<{
216
+ export declare const AnalysisSessionSchema: z.ZodEffects<z.ZodObject<{
217
217
  id: z.ZodString;
218
218
  name: z.ZodString;
219
219
  modelProvider: z.ZodString;
220
220
  model: z.ZodString;
221
221
  customModelName: z.ZodOptional<z.ZodString>;
222
- ollamaBaseUrl: z.ZodOptional<z.ZodString>;
222
+ baseUrl: z.ZodOptional<z.ZodString>;
223
223
  analysisResults: z.ZodArray<z.ZodObject<{
224
224
  id: z.ZodString;
225
225
  prompt: z.ZodString;
@@ -449,7 +449,7 @@ export declare const AnalysisSessionSchema: z.ZodObject<{
449
449
  } | undefined;
450
450
  }[];
451
451
  customModelName?: string | undefined;
452
- ollamaBaseUrl?: string | undefined;
452
+ baseUrl?: string | undefined;
453
453
  createdAt?: Date | undefined;
454
454
  }, {
455
455
  id: string;
@@ -466,8 +466,47 @@ export declare const AnalysisSessionSchema: z.ZodObject<{
466
466
  } | undefined;
467
467
  }[];
468
468
  customModelName?: string | undefined;
469
- ollamaBaseUrl?: string | undefined;
469
+ baseUrl?: string | undefined;
470
470
  createdAt?: Date | undefined;
471
- }>;
471
+ }>, {
472
+ id: string;
473
+ name: string;
474
+ modelProvider: string;
475
+ model: string;
476
+ analysisResults: {
477
+ id: string;
478
+ isCompleted: boolean;
479
+ prompt: string;
480
+ streamMessage: {
481
+ parts?: ({
482
+ type: "text";
483
+ text: string;
484
+ isCompleted?: boolean | undefined;
485
+ additionalData?: any;
486
+ } | {
487
+ type: "tool-invocation";
488
+ toolInvocation: {
489
+ toolName: string;
490
+ toolCallId: string;
491
+ state: string;
492
+ args?: any;
493
+ result?: any;
494
+ };
495
+ isCompleted?: boolean | undefined;
496
+ additionalData?: any;
497
+ } | z.objectOutputType<{
498
+ type: z.ZodString;
499
+ additionalData: z.ZodOptional<z.ZodAny>;
500
+ isCompleted: z.ZodOptional<z.ZodBoolean>;
501
+ }, z.ZodTypeAny, "passthrough">)[] | undefined;
502
+ };
503
+ errorMessage?: {
504
+ error: string;
505
+ } | undefined;
506
+ }[];
507
+ customModelName?: string | undefined;
508
+ baseUrl?: string | undefined;
509
+ createdAt?: Date | undefined;
510
+ }, unknown>;
472
511
  export type AnalysisSessionSchema = z.infer<typeof AnalysisSessionSchema>;
473
512
  //# sourceMappingURL=schemas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AA6DpE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAoB4nC,CAAC;sBAAqB,CAAC;;;;;oBAAyG,CAAC;sBAAqB,CAAC;;;;;;;;;;oBAAkR,CAAC;sBAAqB,CAAC;;;;;;;;;;oBAAgO,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAA9Q,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;oBAAgO,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;oBAA9Q,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAvB,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;EAd3lD,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAW2nC,CAAC;0BAAqB,CAAC;;;;;wBAAyG,CAAC;0BAAqB,CAAC;;;;;;;;;;wBAAkR,CAAC;0BAAqB,CAAC;;;;;;;;;;wBAAgO,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAA9Q,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;wBAAgO,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;wBAA9Q,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAvB,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAvB,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAF3lD,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAgEpE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA4C4f,CAAC;sBAAqB,CAAC;;;;;oBAAyG,CAAC;sBAAqB,CAAC;;;;;;;;;;oBAAkR,CAAC;sBAAqB,CAAC;;;;;;;;;;oBAAgO,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAA9Q,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;oBAAgO,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;oBAA9Q,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAvB,CAAC;sBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;EAtC39B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAmCxE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAE2f,CAAC;0BAAqB,CAAC;;;;;wBAAyG,CAAC;0BAAqB,CAAC;;;;;;;;;;wBAAkR,CAAC;0BAAqB,CAAC;;;;;;;;;;wBAAgO,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAA9Q,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;wBAAgO,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;wBAA9Q,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAvB,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAvB,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAvB,CAAC;0BAAqB,CAAC;;;;;;;;;;;;;;;;;WAFl6B,CAAC;AAC5D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
package/dist/schemas.js CHANGED
@@ -65,14 +65,29 @@ export const AnalysisResultSchema = z.object({
65
65
  errorMessage: ErrorMessageSchema.optional(),
66
66
  isCompleted: z.boolean(),
67
67
  });
68
- export const AnalysisSessionSchema = z.object({
68
+ // migrate from old ollamaBaseUrl to new baseUrl
69
+ const migrateAnalysisSession = z.preprocess((data) => {
70
+ if (data &&
71
+ typeof data === 'object' &&
72
+ 'ollamaBaseUrl' in data &&
73
+ !('baseUrl' in data)) {
74
+ // migrate from old ollamaBaseUrl to new baseUrl
75
+ const { ollamaBaseUrl, ...rest } = data;
76
+ return {
77
+ ...rest,
78
+ baseUrl: ollamaBaseUrl,
79
+ };
80
+ }
81
+ return data;
82
+ }, z.object({
69
83
  id: z.string().cuid2(),
70
84
  name: z.string(),
71
85
  modelProvider: z.string(),
72
86
  model: z.string(),
73
87
  customModelName: z.string().optional(),
74
- ollamaBaseUrl: z.string().optional(),
88
+ baseUrl: z.string().optional(),
75
89
  analysisResults: z.array(AnalysisResultSchema),
76
90
  createdAt: z.coerce.date().optional(),
77
- });
91
+ }));
92
+ export const AnalysisSessionSchema = migrateAnalysisSession;
78
93
  //# sourceMappingURL=schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import {z} from 'zod';\nimport {StreamMessagePartSchema} from '@openassistant/core';\n\nexport const QueryToolParameters = z.object({\n type: z.literal('query'),\n sqlQuery: z.string(),\n reasoning: z.string(),\n});\nexport type QueryToolParameters = z.infer<typeof QueryToolParameters>;\n\nexport const ErrorMessageSchema = z.object({\n error: z.string(),\n});\nexport type ErrorMessageSchema = z.infer<typeof ErrorMessageSchema>;\n\n// migrate from old streamMessage to new streamMessage\nconst migrateStreamMessage = z.preprocess(\n (data) => {\n if (\n data &&\n typeof data === 'object' &&\n 'toolCallMessages' in data &&\n 'parts' in data\n ) {\n // migrate from old streamMessage to new streamMessage\n const parts = (data as any).parts as any[];\n\n const newParts = [];\n for (const part of parts) {\n if (part.type === 'text') {\n const text = part.text;\n newParts.push({\n type: 'text',\n text,\n });\n } else if (part.type === 'tool') {\n const toolCallMessages = part.toolCallMessages;\n for (const toolCallMessage of toolCallMessages) {\n const toolCallId = toolCallMessage.toolCallId;\n const toolName = toolCallMessage.toolName;\n const args = toolCallMessage.args;\n const isCompleted = toolCallMessage.isCompleted;\n const llmResult = toolCallMessage.llmResult;\n const additionalData = toolCallMessage.additionalData;\n\n const toolInvocation = {\n toolCallId,\n toolName,\n args,\n state: isCompleted ? 'result' : 'call',\n result: llmResult,\n };\n\n newParts.push({\n type: 'tool-invocation',\n toolInvocation,\n additionalData,\n isCompleted,\n });\n }\n }\n }\n\n return {\n parts: newParts,\n };\n }\n return data;\n },\n z.object({\n parts: z.array(StreamMessagePartSchema).optional(),\n }),\n);\n\nexport const AnalysisResultSchema = z.object({\n id: z.string().cuid2(),\n prompt: z.string(),\n streamMessage: migrateStreamMessage,\n errorMessage: ErrorMessageSchema.optional(),\n isCompleted: z.boolean(),\n});\nexport type AnalysisResultSchema = z.infer<typeof AnalysisResultSchema>;\n\nexport const AnalysisSessionSchema = z.object({\n id: z.string().cuid2(),\n name: z.string(),\n modelProvider: z.string(),\n model: z.string(),\n customModelName: z.string().optional(),\n ollamaBaseUrl: z.string().optional(),\n analysisResults: z.array(AnalysisResultSchema),\n createdAt: z.coerce.date().optional(),\n});\nexport type AnalysisSessionSchema = z.infer<typeof AnalysisSessionSchema>;\n"]}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import {z} from 'zod';\nimport {StreamMessagePartSchema} from '@openassistant/core';\n\nexport const QueryToolParameters = z.object({\n type: z.literal('query'),\n sqlQuery: z.string(),\n reasoning: z.string(),\n});\nexport type QueryToolParameters = z.infer<typeof QueryToolParameters>;\n\nexport const ErrorMessageSchema = z.object({\n error: z.string(),\n});\nexport type ErrorMessageSchema = z.infer<typeof ErrorMessageSchema>;\n\n// migrate from old streamMessage to new streamMessage\nconst migrateStreamMessage = z.preprocess(\n (data) => {\n if (\n data &&\n typeof data === 'object' &&\n 'toolCallMessages' in data &&\n 'parts' in data\n ) {\n // migrate from old streamMessage to new streamMessage\n const parts = (data as {parts: Record<string, unknown>[]}).parts;\n\n const newParts = [];\n for (const part of parts) {\n if (part.type === 'text') {\n const text = part.text;\n newParts.push({\n type: 'text',\n text,\n });\n } else if (part.type === 'tool') {\n const toolCallMessages = part.toolCallMessages as Record<\n string,\n unknown\n >[];\n for (const toolCallMessage of toolCallMessages) {\n const toolCallId = toolCallMessage.toolCallId;\n const toolName = toolCallMessage.toolName;\n const args = toolCallMessage.args;\n const isCompleted = toolCallMessage.isCompleted;\n const llmResult = toolCallMessage.llmResult;\n const additionalData = toolCallMessage.additionalData;\n\n const toolInvocation = {\n toolCallId,\n toolName,\n args,\n state: isCompleted ? 'result' : 'call',\n result: llmResult,\n };\n\n newParts.push({\n type: 'tool-invocation',\n toolInvocation,\n additionalData,\n isCompleted,\n });\n }\n }\n }\n\n return {\n parts: newParts,\n };\n }\n return data;\n },\n z.object({\n parts: z.array(StreamMessagePartSchema).optional(),\n }),\n);\n\nexport const AnalysisResultSchema = z.object({\n id: z.string().cuid2(),\n prompt: z.string(),\n streamMessage: migrateStreamMessage,\n errorMessage: ErrorMessageSchema.optional(),\n isCompleted: z.boolean(),\n});\nexport type AnalysisResultSchema = z.infer<typeof AnalysisResultSchema>;\n\n// migrate from old ollamaBaseUrl to new baseUrl\nconst migrateAnalysisSession = z.preprocess(\n (data) => {\n if (\n data &&\n typeof data === 'object' &&\n 'ollamaBaseUrl' in data &&\n !('baseUrl' in data)\n ) {\n // migrate from old ollamaBaseUrl to new baseUrl\n const {ollamaBaseUrl, ...rest} = data as {ollamaBaseUrl: string} & Record<\n string,\n unknown\n >;\n return {\n ...rest,\n baseUrl: ollamaBaseUrl,\n };\n }\n return data;\n },\n z.object({\n id: z.string().cuid2(),\n name: z.string(),\n modelProvider: z.string(),\n model: z.string(),\n customModelName: z.string().optional(),\n baseUrl: z.string().optional(),\n analysisResults: z.array(AnalysisResultSchema),\n createdAt: z.coerce.date().optional(),\n }),\n);\n\nexport const AnalysisSessionSchema = migrateAnalysisSession;\nexport type AnalysisSessionSchema = z.infer<typeof AnalysisSessionSchema>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/ai",
3
- "version": "0.24.13",
3
+ "version": "0.24.15",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/index.js",
@@ -19,20 +19,20 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@ai-sdk/provider": "^1.1.3",
22
- "@openassistant/core": "0.5.14-alpha.2",
23
- "@openassistant/utils": "0.5.14-alpha.2",
22
+ "@openassistant/core": "0.5.17",
23
+ "@openassistant/utils": "0.5.17",
24
24
  "@paralleldrive/cuid2": "^2.2.2",
25
- "@sqlrooms/data-table": "0.24.13",
26
- "@sqlrooms/duckdb": "0.24.13",
27
- "@sqlrooms/monaco-editor": "0.24.13",
28
- "@sqlrooms/room-config": "0.24.13",
29
- "@sqlrooms/room-shell": "0.24.13",
30
- "@sqlrooms/ui": "0.24.13",
31
- "@sqlrooms/utils": "0.24.13",
25
+ "@sqlrooms/data-table": "0.24.15",
26
+ "@sqlrooms/duckdb": "0.24.15",
27
+ "@sqlrooms/monaco-editor": "0.24.15",
28
+ "@sqlrooms/room-config": "0.24.15",
29
+ "@sqlrooms/room-shell": "0.24.15",
30
+ "@sqlrooms/ui": "0.24.15",
31
+ "@sqlrooms/utils": "0.24.15",
32
32
  "ai": "^4.3.19",
33
33
  "immer": "^10.1.1",
34
34
  "lucide-react": "^0.475.0",
35
- "react-markdown": "^9.1.0",
35
+ "react-markdown": "^10.1.0",
36
36
  "rehype-raw": "^7.0.0",
37
37
  "remark-gfm": "^4.0.0",
38
38
  "zod": "^3.25.73"
@@ -48,5 +48,5 @@
48
48
  "typecheck": "tsc --noEmit",
49
49
  "typedoc": "typedoc"
50
50
  },
51
- "gitHead": "24b90fcf3302fe94164268ab901f5784c99ffb32"
51
+ "gitHead": "9388ad51033a365069bad9a14df24a0688b6a592"
52
52
  }