@sqlrooms/ai 0.24.12 → 0.24.14

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;
@@ -44,7 +44,15 @@ export declare const AiSliceConfig: z.ZodObject<{
44
44
  toolCallId: string;
45
45
  state: string;
46
46
  args?: any;
47
- result?: any;
47
+ result
48
+ /**
49
+ * Set the AI model for the current session
50
+ * @param model - The model to set
51
+ */
52
+ ? /**
53
+ * Set the AI model for the current session
54
+ * @param model - The model to set
55
+ */: any;
48
56
  }, {
49
57
  toolName: string;
50
58
  toolCallId: string;
@@ -241,7 +249,7 @@ export declare const AiSliceConfig: z.ZodObject<{
241
249
  } | undefined;
242
250
  }[];
243
251
  customModelName?: string | undefined;
244
- ollamaBaseUrl?: string | undefined;
252
+ baseUrl?: string | undefined;
245
253
  createdAt?: Date | undefined;
246
254
  }, {
247
255
  id: string;
@@ -258,12 +266,9 @@ export declare const AiSliceConfig: z.ZodObject<{
258
266
  } | undefined;
259
267
  }[];
260
268
  customModelName?: string | undefined;
261
- ollamaBaseUrl?: string | undefined;
269
+ baseUrl?: string | undefined;
262
270
  createdAt?: Date | undefined;
263
- }>, "many">;
264
- currentSessionId: z.ZodOptional<z.ZodString>;
265
- }, "strip", z.ZodTypeAny, {
266
- sessions: {
271
+ }>, {
267
272
  id: string;
268
273
  name: string;
269
274
  modelProvider: string;
@@ -300,11 +305,11 @@ export declare const AiSliceConfig: z.ZodObject<{
300
305
  } | undefined;
301
306
  }[];
302
307
  customModelName?: string | undefined;
303
- ollamaBaseUrl?: string | undefined;
308
+ baseUrl?: string | undefined;
304
309
  createdAt?: Date | undefined;
305
- }[];
306
- currentSessionId?: string | undefined;
307
- }, {
310
+ }, unknown>, "many">;
311
+ currentSessionId: z.ZodOptional<z.ZodString>;
312
+ }, "strip", z.ZodTypeAny, {
308
313
  sessions: {
309
314
  id: string;
310
315
  name: string;
@@ -314,16 +319,41 @@ export declare const AiSliceConfig: z.ZodObject<{
314
319
  id: string;
315
320
  isCompleted: boolean;
316
321
  prompt: string;
317
- streamMessage?: unknown;
322
+ streamMessage: {
323
+ parts?: ({
324
+ type: "text";
325
+ text: string;
326
+ isCompleted?: boolean | undefined;
327
+ additionalData?: any;
328
+ } | {
329
+ type: "tool-invocation";
330
+ toolInvocation: {
331
+ toolName: string;
332
+ toolCallId: string;
333
+ state: string;
334
+ args?: any;
335
+ result?: any;
336
+ };
337
+ isCompleted?: boolean | undefined;
338
+ additionalData?: any;
339
+ } | z.objectOutputType<{
340
+ type: z.ZodString;
341
+ additionalData: z.ZodOptional<z.ZodAny>;
342
+ isCompleted: z.ZodOptional<z.ZodBoolean>;
343
+ }, z.ZodTypeAny, "passthrough">)[] | undefined;
344
+ };
318
345
  errorMessage?: {
319
346
  error: string;
320
347
  } | undefined;
321
348
  }[];
322
349
  customModelName?: string | undefined;
323
- ollamaBaseUrl?: string | undefined;
350
+ baseUrl?: string | undefined;
324
351
  createdAt?: Date | undefined;
325
352
  }[];
326
353
  currentSessionId?: string | undefined;
354
+ }, {
355
+ sessions: unknown[];
356
+ currentSessionId?: string | undefined;
327
357
  }>;
328
358
  }, "strip", z.ZodTypeAny, {
329
359
  ai: {
@@ -364,31 +394,14 @@ export declare const AiSliceConfig: z.ZodObject<{
364
394
  } | undefined;
365
395
  }[];
366
396
  customModelName?: string | undefined;
367
- ollamaBaseUrl?: string | undefined;
397
+ baseUrl?: string | undefined;
368
398
  createdAt?: Date | undefined;
369
399
  }[];
370
400
  currentSessionId?: string | undefined;
371
401
  };
372
402
  }, {
373
403
  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
- }[];
404
+ sessions: unknown[];
392
405
  currentSessionId?: string | undefined;
393
406
  };
394
407
  }>;
@@ -406,7 +419,7 @@ export type AiSliceState = {
406
419
  cancelAnalysis: () => void;
407
420
  setAiModel: (modelProvider: string, model: string) => void;
408
421
  setCustomModelName: (customModelName: string) => void;
409
- setOllamaBaseUrl: (baseUrl: string) => void;
422
+ setBaseUrl: (baseUrl: string) => void;
410
423
  createSession: (name?: string, modelProvider?: string, model?: string) => void;
411
424
  switchSession: (sessionId: string) => void;
412
425
  renameSession: (sessionId: string, name: string) => void;
@@ -416,9 +429,13 @@ export type AiSliceState = {
416
429
  findToolComponent: (toolName: string) => React.ComponentType | undefined;
417
430
  };
418
431
  };
419
- export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>({ getApiKey, initialAnalysisPrompt, customTools, getInstructions, }: {
420
- getApiKey: (modelProvider: string) => string;
432
+ /**
433
+ * Configuration options for creating an AI slice
434
+ */
435
+ export interface AiSliceOptions {
436
+ /** Initial prompt to display in the analysis input */
421
437
  initialAnalysisPrompt?: string;
438
+ /** Custom tools to add to the AI assistant */
422
439
  customTools?: Record<string, AiSliceTool>;
423
440
  /**
424
441
  * Function to get custom instructions for the AI assistant
@@ -426,7 +443,22 @@ export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>
426
443
  * @returns The instructions string to use
427
444
  */
428
445
  getInstructions?: (tablesSchema: DataTable[]) => string;
429
- }): StateCreator<AiSliceState>;
446
+ }
447
+ /**
448
+ * API key configuration for the AI slice
449
+ */
450
+ export type AiSliceApiConfig = {
451
+ baseUrl: string;
452
+ getApiKey?: never;
453
+ } | {
454
+ getApiKey: (modelProvider: string) => string;
455
+ baseUrl?: never;
456
+ };
457
+ /**
458
+ * Complete configuration for creating an AI slice
459
+ */
460
+ export type CreateAiSliceConfig = AiSliceOptions & AiSliceApiConfig;
461
+ export declare function createAiSlice<PC extends BaseRoomConfig & AiSliceConfig>(config: CreateAiSliceConfig): StateCreator<AiSliceState>;
430
462
  type RoomConfigWithAi = BaseRoomConfig & AiSliceConfig;
431
463
  type RoomShellSliceStateWithAi = RoomShellSliceState<RoomConfigWithAi> & AiSliceState;
432
464
  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,7 +29,8 @@ 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, } = config;
33
34
  return createSlice((set, get, store) => {
34
35
  return {
35
36
  ai: {
@@ -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
  },
@@ -205,11 +206,8 @@ 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
213
  tools: get().ai.tools,
@@ -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\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 } = config;\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 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-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:\n getApiKey?.(currentSession.modelProvider || 'openai') || '',\n baseUrl: currentSession.baseUrl || baseUrl,\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"]}
package/dist/analysis.js CHANGED
@@ -110,7 +110,7 @@ export async function runAnalysis({ name = 'sqlrooms-ai', tableSchemas, modelPro
110
110
  toolChoice: 'auto', // this will enable streaming
111
111
  maxSteps,
112
112
  ...(abortController ? { abortController } : {}),
113
- ...(modelProvider === 'ollama' && baseUrl ? { baseUrl } : {}),
113
+ baseUrl, // ollama base url or LLM proxy server url
114
114
  });
115
115
  // restore ai messages from historyAnalysis?
116
116
  if (historyAnalysis) {
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,GAEhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,gBAAgB,GAIjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAC,eAAe,EAAC,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAuB,mBAAmB,EAAC,MAAM,WAAW,CAAC;AACpE,OAAO,EAAC,qBAAqB,EAAC,MAAM,IAAI,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6C5B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAAyB;IAC9D,OAAO,GAAG,oBAAoB,KAAK,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAAC,SAA0B,EAAE,QAAgB;IACzE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,sCAAsC;QACpF,MAAM,SAAS,CAAC,KAAK,CAAC,yBAAyB,QAAQ,OAAO,QAAQ,EAAE,CAAC,CAAC;QAC1E,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,SAAS,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAwDD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,IAAI,GAAG,aAAa,EACpB,YAAY,EACZ,aAAa,EACb,KAAK,EACL,eAAe,EACf,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,cAAc,EACd,QAAQ,GAAG,CAAC,EACZ,KAAK,GAAG,EAAE,EACV,eAAe,EACf,OAAO,GACY;IACnB,6EAA6E;IAC7E,MAAM,WAAW,GACf,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC;IAElE,uCAAuC;IACvC,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;QACtC,IAAI;QACJ,aAAa;QACb,KAAK,EAAE,WAAW;QAClB,MAAM;QACN,OAAO,EAAE,IAAI;QACb,YAAY,EAAE,eAAe;YAC3B,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC;YAC/B,CAAC,CAAC,sBAAsB,CAAC,YAAY,CAAC;QACxC,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,MAAM,EAAE,6BAA6B;QACjD,QAAQ;QACR,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAC,eAAe,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,aAAa,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC,CAAC;IAEH,4CAA4C;IAC5C,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,eAAe,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACzD,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,aAA8B;SAClD,CAAC,CAAC,CAAC;QACJ,MAAM,eAAe,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QACzD,SAAS,CAAC,WAAW,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC;QACrD,WAAW,EAAE,MAAM;QACnB,qBAAqB,EAAE,CAAC,EACtB,WAAW,EACX,OAAO,GAIR,EAAE,EAAE;YACH,cAAc,CAAC,WAAW,IAAI,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAgD;IAEhD,OAAO;QACL,KAAK,EAAE,YAAY,CAAC;YAClB,WAAW,EAAE;;yEAEsD;YACnE,UAAU,EAAE,mBAAmB;YAC/B,uEAAuE;YACvE,OAAO,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC,EAAE,EAAE;gBAClC,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;oBAC3D,iEAAiE;oBACjE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC/C,gEAAgE;oBAChE,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;wBAC9D,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;wBAC1B,CAAC,CAAC,MAAM,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAE/C,kDAAkD;oBAClD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACrC,MAAM,YAAY,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;oBAEjD,OAAO;wBACL,SAAS,EAAE;4BACT,OAAO,EAAE,IAAI;4BACb,IAAI,EAAE;gCACJ,IAAI;gCACJ,OAAO,EAAE,WAAW;gCACpB,YAAY;6BACb;yBACF;wBACD,cAAc,EAAE;4BACd,KAAK,EAAE,cAAc;4BACrB,QAAQ;yBACT;qBACF,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO;wBACL,SAAS,EAAE;4BACT,OAAO,EAAE,KAAK;4BACd,OAAO,EAAE,yBAAyB;4BAClC,YAAY,EACV,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;yBAC3D;qBACF,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,SAAS,EAAE,eAAe;SAC3B,CAAC;KACH,CAAC;AACJ,CAAC","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\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): 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 +1 @@
1
- {"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAM5D,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAoGF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDAwEzB,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,iDAyEzB,CAAC"}
@@ -1,9 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useState, useCallback, useMemo } from 'react';
3
3
  import Markdown from 'react-markdown';
4
+ import remarkGfm from 'remark-gfm';
4
5
  import rehypeRaw from 'rehype-raw';
5
6
  import { truncate } from '@sqlrooms/utils';
6
7
  import { MessageContainer } from './MessageContainer';
8
+ import { BrainIcon } from 'lucide-react';
9
+ import { cn } from '@sqlrooms/ui';
7
10
  // Constants moved outside component to prevent recreation
8
11
  const THINK_WORD_LIMIT = 10;
9
12
  const COMPLETE_THINK_REGEX = /<think>([\s\S]*?)<\/think>/g;
@@ -44,11 +47,11 @@ const processContent = (originalContent) => {
44
47
  /**
45
48
  * ThinkBlock component for rendering individual think blocks
46
49
  */
47
- const ThinkBlock = React.memo(({ thinkContent, isExpanded, onToggleExpansion }) => {
50
+ const ThinkBlock = React.memo(({ thinkContent, isExpanded, onToggleExpansion, className }) => {
48
51
  const { content, isComplete, index } = thinkContent;
49
52
  const displayText = isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;
50
53
  const needsTruncation = isComplete && content.split(' ').length > THINK_WORD_LIMIT;
51
- return (_jsx("div", { className: "inline-block", children: _jsxs("span", { className: "rounded-lg bg-gray-50 px-3 py-2 text-sm font-normal text-gray-100 dark:bg-gray-800/50 dark:text-gray-400", children: [_jsx("span", { className: "inline-flex items-start gap-2", children: _jsxs("span", { className: "text-gray-400", children: [_jsx("span", { className: "inline-block opacity-60 grayscale", children: "\uD83D\uDCAD" }), ' ', displayText] }) }), needsTruncation && (_jsx("button", { onClick: () => onToggleExpansion(content), className: "ml-2 text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300", children: isExpanded ? 'Show less' : 'Show more' }))] }) }, `think-${index}`));
54
+ return (_jsxs("span", { className: cn('inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400', isExpanded && 'bg-gray-50 dark:bg-gray-800/50', className), children: [_jsx("span", { className: "inline-flex items-start gap-2", children: _jsxs("span", { className: "text-gray-400", children: [_jsx(BrainIcon, { className: "mb-1 inline-block opacity-60 grayscale", size: 12 }), ' ', displayText] }) }), ' ', needsTruncation && (_jsx("button", { onClick: () => onToggleExpansion(content), className: "text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300", children: isExpanded ? 'Show less' : 'Show more thinking' }))] }, `think-${index}`));
52
55
  });
53
56
  ThinkBlock.displayName = 'ThinkBlock';
54
57
  /**
@@ -91,7 +94,7 @@ export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
91
94
  return null;
92
95
  }
93
96
  }, [thinkContents, expandedThink, toggleThinkExpansion]);
94
- 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", rehypePlugins: [rehypeRaw], components: {
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: {
95
98
  // @ts-expect-error - Custom HTML element not in react-markdown types
96
99
  'think-block': thinkBlockComponent,
97
100
  }, children: processedContent }) }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAapD,0DAA0D;AAC1D,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,cAAc,GAAG,CACrB,eAAuB,EAIvB,EAAE;IACF,MAAM,aAAa,GAAmB,EAAE,CAAC;IACzC,IAAI,gBAAgB,GAAG,eAAe,CAAC;IACvC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,8BAA8B;IAC9B,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CACzC,oBAAoB,EACpB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACjB,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,IAAI,CAAC;gBACjB,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;gBACvB,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,KAAK,EAAE;aACf,CAAC,CAAC;YACH,OAAO,gCAAgC,KAAK,GAAG,CAAC,sBAAsB,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CACF,CAAC;IAEF,iDAAiD;IACjD,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CACzC,sBAAsB,EACtB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACjB,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,IAAI,CAAC;gBACjB,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;gBACvB,UAAU,EAAE,KAAK;gBACjB,KAAK,EAAE,KAAK,EAAE;aACf,CAAC,CAAC;YACH,OAAO,gCAAgC,KAAK,GAAG,CAAC,sBAAsB,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CACF,CAAC;IAEF,OAAO,EAAC,gBAAgB,EAAE,aAAa,EAAC,CAAC;AAC3C,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAI1B,CAAC,EAAC,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAC,EAAE,EAAE;IACnD,MAAM,EAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAC,GAAG,YAAY,CAAC;IAElD,MAAM,WAAW,GACf,UAAU,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5E,MAAM,eAAe,GACnB,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,gBAAgB,CAAC;IAE7D,OAAO,CACL,cAA4B,SAAS,EAAC,cAAc,YAClD,gBAAM,SAAS,EAAC,0GAA0G,aACxH,eAAM,SAAS,EAAC,+BAA+B,YAC7C,gBAAM,SAAS,EAAC,eAAe,aAC7B,eAAM,SAAS,EAAC,mCAAmC,6BAAU,EAAC,GAAG,EAChE,WAAW,IACP,GACF,EACN,eAAe,IAAI,CAClB,iBACE,OAAO,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,EACzC,SAAS,EAAC,sGAAsG,YAE/G,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,GAChC,CACV,IACI,IAhBC,SAAS,KAAK,EAAE,CAiBpB,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,cAAc,CAC9D,KAA0B;IAE1B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAE3E,MAAM,oBAAoB,GAAG,WAAW,CAAC,CAAC,OAAe,EAAE,EAAE;QAC3D,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,oEAAoE;IACpE,MAAM,EAAC,gBAAgB,EAAE,aAAa,EAAC,GAAG,OAAO,CAC/C,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,EACnC,CAAC,KAAK,CAAC,OAAO,CAAC,CAChB,CAAC;IAEF,sEAAsE;IACtE,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,UAAe,EAAE,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YACpE,MAAM,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YAE1C,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAE3D,OAAO,CACL,KAAC,UAAU,IACT,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,oBAAoB,GACvC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,aAAa,EAAE,oBAAoB,CAAC,CACrD,CAAC;IAEF,OAAO,CACL,cAAK,SAAS,EAAC,qBAAqB,YAClC,KAAC,gBAAgB,IACf,SAAS,EAAE,IAAI,EACf,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,EAC5C,OAAO,EAAE,KAAK,YAEd,KAAC,QAAQ,IACP,SAAS,EAAC,4CAA4C,EACtD,aAAa,EAAE,CAAC,SAAS,CAAC,EAC1B,UAAU,EAAE;oBACV,qEAAqE;oBACrE,aAAa,EAAE,mBAAmB;iBACnC,YAEA,gBAAgB,GACR,GACM,GACf,CACP,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import React, {useState, useCallback, useMemo} from 'react';\nimport Markdown from 'react-markdown';\nimport rehypeRaw from 'rehype-raw';\nimport {truncate} from '@sqlrooms/utils';\nimport {MessageContainer} from './MessageContainer';\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 thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion}) => {\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 <div key={`think-${index}`} className=\"inline-block\">\n <span className=\"rounded-lg bg-gray-50 px-3 py-2 text-sm font-normal text-gray-100 dark:bg-gray-800/50 dark:text-gray-400\">\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <span className=\"inline-block opacity-60 grayscale\">💭</span>{' '}\n {displayText}\n </span>\n </span>\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"ml-2 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'}\n </button>\n )}\n </span>\n </div>\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 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 <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 +1 @@
1
- {"version":3,"file":"AnalysisResult.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAC,oBAAoB,EAAC,MAAM,YAAY,CAAC;AAKhD;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC;AAaF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAiHxD,CAAC"}
1
+ {"version":3,"file":"AnalysisResult.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAC,oBAAoB,EAAC,MAAM,YAAY,CAAC;AAKhD;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC;AAaF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA8FxD,CAAC"}
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { JsonMonacoEditor } from '@sqlrooms/monaco-editor';
3
- import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Popover, PopoverContent, PopoverTrigger, } from '@sqlrooms/ui';
4
- import { CodeIcon, SquareTerminalIcon, TrashIcon } from 'lucide-react';
2
+ import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, CopyButton, } from '@sqlrooms/ui';
3
+ import { SquareTerminalIcon, TrashIcon, } from 'lucide-react';
5
4
  import { useState } from 'react';
6
5
  import { AnalysisAnswer } from './AnalysisAnswer';
7
6
  import { ErrorMessage } from './ErrorMessage';
@@ -32,14 +31,7 @@ export const AnalysisResult = ({ result, onDeleteAnalysisResult, }) => {
32
31
  const { id, prompt, errorMessage, streamMessage } = result;
33
32
  const parts = streamMessage.parts;
34
33
  const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
35
- return (_jsxs("div", { className: "group flex w-full flex-col gap-2 text-sm", children: [_jsx("div", { className: "mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100", children: _jsxs("div", { className: "flex w-full items-center gap-2 rounded-md border p-4 text-sm", children: [_jsx(SquareTerminalIcon, { className: "h-4 w-4" }), _jsx("div", { className: "flex-1", children: prompt }), _jsxs("div", { className: "flex gap-2 opacity-0 transition-opacity group-hover:opacity-100", children: [_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: _jsx(CodeIcon, { className: "h-4 w-4" }) }) }), _jsx(PopoverContent, { className: "max-h-[400px] w-[400px] overflow-auto", align: "end", side: "right", children: _jsx(JsonMonacoEditor, { value: stringifyResult(result), readOnly: true, className: "h-[300px]", options: {
36
- minimap: { enabled: false },
37
- scrollBeyondLastLine: false,
38
- automaticLayout: true,
39
- folding: true,
40
- lineNumbers: false,
41
- wordWrap: 'on',
42
- } }) })] }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => setShowDeleteConfirmation(true), children: _jsx(TrashIcon, { className: "h-4 w-4" }) }), _jsx(Dialog, { open: showDeleteConfirmation, onOpenChange: setShowDeleteConfirmation, children: _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Confirm Deletion" }), _jsx(DialogDescription, { children: "Are you sure you want to delete this analysis result? This action cannot be undone." })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setShowDeleteConfirmation(false), children: "Cancel" }), _jsx(Button, { variant: "destructive", onClick: () => {
34
+ return (_jsxs("div", { className: "group flex w-full flex-col gap-2 text-sm", children: [_jsx("div", { className: "mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100", children: _jsxs("div", { className: "bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm", children: [_jsx(SquareTerminalIcon, { className: "h-4 w-4" }), _jsx("div", { className: "flex-1", children: prompt }), _jsxs("div", { className: "flex gap-2 opacity-0 transition-opacity group-hover:opacity-100", children: [_jsx(CopyButton, { text: prompt, variant: "ghost", size: "icon", className: "h-6 w-6", ariaLabel: "Copy prompt" }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => setShowDeleteConfirmation(true), children: _jsx(TrashIcon, { className: "h-4 w-4" }) }), _jsx(Dialog, { open: showDeleteConfirmation, onOpenChange: setShowDeleteConfirmation, children: _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Confirm Deletion" }), _jsx(DialogDescription, { children: "Are you sure you want to delete this analysis result? This action cannot be undone." })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setShowDeleteConfirmation(false), children: "Cancel" }), _jsx(Button, { variant: "destructive", onClick: () => {
43
35
  onDeleteAnalysisResult(id);
44
36
  setShowDeleteConfirmation(false);
45
37
  }, children: "Delete" })] })] }) })] })] }) }), parts?.map((part, index) => (_jsxs("div", { children: [part.type === 'text' && (_jsx(AnalysisAnswer, { content: part.text, isAnswer: index === (streamMessage.parts?.length || 0) - 1 })), part.type === 'tool-invocation' && (_jsx("div", { children: _jsx(ToolResult, { toolInvocation: part.toolInvocation, additionalData: part.additionalData, isCompleted: result.isCompleted }, part.toolInvocation.toolCallId) }))] }, index))), errorMessage && _jsx(ErrorMessage, { errorMessage: errorMessage.error })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"AnalysisResult.js","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"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","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {StreamMessagePart} from '@openassistant/core';\nimport {CodeIcon, SquareTerminalIcon, TrashIcon} from 'lucide-react';\nimport {useState} from 'react';\nimport {AnalysisResultSchema} from '../schemas';\nimport {AnalysisAnswer} from './AnalysisAnswer';\nimport {ErrorMessage} from './ErrorMessage';\nimport {ToolResult} from './tools/ToolResult';\n\n/**\n * Props for the AnalysisResult component\n * @property {AnalysisResultSchema} result - The result of the analysis containing prompt, tool calls, and analysis data\n */\ntype AnalysisResultProps = {\n result: AnalysisResultSchema;\n onDeleteAnalysisResult: (id: string) => void;\n};\n\n/**\n * Stringify the result of the analysis, excluding toolCallMessages.\n * Used to display raw result data in a code view.\n *\n * @param result - The complete analysis result\n * @returns A JSON string representation of the result without toolCallMessages\n */\nconst stringifyResult = (result: AnalysisResultSchema) => {\n return JSON.stringify(result, null, 2);\n};\n\n/**\n * Component that displays the results of an AI analysis.\n * Shows the original prompt, intermediate tool calls, final analysis text,\n * and any tool results.\n *\n * @component\n * @param props - Component props\n * @param props.result - The analysis result data to display\n * @returns A React component displaying the analysis results\n */\nexport const AnalysisResult: React.FC<AnalysisResultProps> = ({\n result,\n onDeleteAnalysisResult,\n}) => {\n // the toolResults are reasoning steps that the LLM took to achieve the final result\n // by calling function tools to answer the prompt\n const {id, prompt, errorMessage, streamMessage} = result;\n const parts = streamMessage.parts as StreamMessagePart[];\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);\n\n return (\n <div className=\"group flex w-full flex-col gap-2 text-sm\">\n <div className=\"mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100\">\n <div className=\"flex w-full items-center gap-2 rounded-md border p-4 text-sm\">\n <SquareTerminalIcon className=\"h-4 w-4\" />\n {/** render prompt */}\n <div className=\"flex-1\">{prompt}</div>\n <div className=\"flex gap-2 opacity-0 transition-opacity group-hover:opacity-100\">\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <CodeIcon className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"max-h-[400px] w-[400px] overflow-auto\"\n align=\"end\"\n side=\"right\"\n >\n <JsonMonacoEditor\n value={stringifyResult(result)}\n readOnly={true}\n className=\"h-[300px]\"\n options={{\n minimap: {enabled: false},\n scrollBeyondLastLine: false,\n automaticLayout: true,\n folding: true,\n lineNumbers: false,\n wordWrap: 'on',\n }}\n />\n </PopoverContent>\n </Popover>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={() => setShowDeleteConfirmation(true)}\n >\n <TrashIcon className=\"h-4 w-4\" />\n </Button>\n\n {/* Delete Confirmation Dialog */}\n <Dialog\n open={showDeleteConfirmation}\n onOpenChange={setShowDeleteConfirmation}\n >\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Confirm Deletion</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this analysis result? This\n action cannot be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setShowDeleteConfirmation(false)}\n >\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => {\n onDeleteAnalysisResult(id);\n setShowDeleteConfirmation(false);\n }}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n </div>\n </div>\n {/** render parts */}\n {parts?.map((part, index) => (\n <div key={index}>\n {part.type === 'text' && (\n <AnalysisAnswer\n content={part.text}\n isAnswer={index === (streamMessage.parts?.length || 0) - 1}\n />\n )}\n {part.type === 'tool-invocation' && (\n <div>\n <ToolResult\n key={part.toolInvocation.toolCallId}\n toolInvocation={part.toolInvocation}\n additionalData={part.additionalData}\n isCompleted={result.isCompleted}\n />\n </div>\n )}\n </div>\n ))}\n {/** render error message */}\n {errorMessage && <ErrorMessage errorMessage={errorMessage.error} />}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"AnalysisResult.js","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"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","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Popover,\n PopoverContent,\n PopoverTrigger,\n CopyButton,\n} from '@sqlrooms/ui';\nimport {StreamMessagePart} from '@openassistant/core';\nimport {\n ClipboardIcon,\n CodeIcon,\n SquareTerminalIcon,\n TrashIcon,\n CheckIcon,\n} from 'lucide-react';\nimport {useState} from 'react';\nimport {AnalysisResultSchema} from '../schemas';\nimport {AnalysisAnswer} from './AnalysisAnswer';\nimport {ErrorMessage} from './ErrorMessage';\nimport {ToolResult} from './tools/ToolResult';\n\n/**\n * Props for the AnalysisResult component\n * @property {AnalysisResultSchema} result - The result of the analysis containing prompt, tool calls, and analysis data\n */\ntype AnalysisResultProps = {\n result: AnalysisResultSchema;\n onDeleteAnalysisResult: (id: string) => void;\n};\n\n/**\n * Stringify the result of the analysis, excluding toolCallMessages.\n * Used to display raw result data in a code view.\n *\n * @param result - The complete analysis result\n * @returns A JSON string representation of the result without toolCallMessages\n */\nconst stringifyResult = (result: AnalysisResultSchema) => {\n return JSON.stringify(result, null, 2);\n};\n\n/**\n * Component that displays the results of an AI analysis.\n * Shows the original prompt, intermediate tool calls, final analysis text,\n * and any tool results.\n *\n * @component\n * @param props - Component props\n * @param props.result - The analysis result data to display\n * @returns A React component displaying the analysis results\n */\nexport const AnalysisResult: React.FC<AnalysisResultProps> = ({\n result,\n onDeleteAnalysisResult,\n}) => {\n // the toolResults are reasoning steps that the LLM took to achieve the final result\n // by calling function tools to answer the prompt\n const {id, prompt, errorMessage, streamMessage} = result;\n const parts = streamMessage.parts as StreamMessagePart[];\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);\n\n return (\n <div className=\"group flex w-full flex-col gap-2 text-sm\">\n <div className=\"mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100\">\n <div className=\"bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm\">\n <SquareTerminalIcon className=\"h-4 w-4\" />\n {/** render prompt */}\n <div className=\"flex-1\">{prompt}</div>\n <div className=\"flex gap-2 opacity-0 transition-opacity group-hover:opacity-100\">\n <CopyButton\n text={prompt}\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n ariaLabel=\"Copy prompt\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={() => setShowDeleteConfirmation(true)}\n >\n <TrashIcon className=\"h-4 w-4\" />\n </Button>\n\n {/* Delete Confirmation Dialog */}\n <Dialog\n open={showDeleteConfirmation}\n onOpenChange={setShowDeleteConfirmation}\n >\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Confirm Deletion</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this analysis result? This\n action cannot be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setShowDeleteConfirmation(false)}\n >\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => {\n onDeleteAnalysisResult(id);\n setShowDeleteConfirmation(false);\n }}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n </div>\n </div>\n {/** render parts */}\n {parts?.map((part, index) => (\n <div key={index}>\n {part.type === 'text' && (\n <AnalysisAnswer\n content={part.text}\n isAnswer={index === (streamMessage.parts?.length || 0) - 1}\n />\n )}\n {part.type === 'tool-invocation' && (\n <div>\n <ToolResult\n key={part.toolInvocation.toolCallId}\n toolInvocation={part.toolInvocation}\n additionalData={part.additionalData}\n isCompleted={result.isCompleted}\n />\n </div>\n )}\n </div>\n ))}\n {/** render error message */}\n {errorMessage && <ErrorMessage errorMessage={errorMessage.error} />}\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorMessage.d.ts","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":"AAGA,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,2CAQzD"}
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,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import Markdown from 'react-markdown';
3
+ import remarkGfm from 'remark-gfm';
3
4
  import { MessageContainer } from './MessageContainer';
4
5
  export function ErrorMessage(props) {
5
- return (_jsx(MessageContainer, { isSuccess: false, type: "error", content: props, children: _jsx(Markdown, { className: "prose dark:prose-invert max-w-none text-sm", children: props.errorMessage }) }));
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
7
  }
7
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,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,IAAC,SAAS,EAAC,4CAA4C,YAC7D,KAAK,CAAC,YAAY,GACV,GACM,CACpB,CAAC;AACJ,CAAC","sourcesContent":["import Markdown from 'react-markdown';\nimport {MessageContainer} from './MessageContainer';\n\nexport function ErrorMessage(props: {errorMessage: string}) {\n return (\n <MessageContainer isSuccess={false} type=\"error\" content={props}>\n <Markdown className=\"prose dark:prose-invert max-w-none text-sm\">\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,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 +1 @@
1
- {"version":3,"file":"MessageContainer.d.ts","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":"AAWA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAmE5D,CAAC"}
1
+ {"version":3,"file":"MessageContainer.d.ts","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":"AAWA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAsC5D,CAAC"}
@@ -1,17 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { JsonMonacoEditor } from '@sqlrooms/monaco-editor';
3
- import { Badge, Button, cn, Popover, PopoverContent, PopoverTrigger, } from '@sqlrooms/ui';
4
- import { CodeIcon, XCircleIcon } from 'lucide-react';
2
+ import { Badge, cn, } from '@sqlrooms/ui';
3
+ import { XCircleIcon } from 'lucide-react';
5
4
  export const MessageContainer = ({ className, type,
6
5
  // borderColor,
7
6
  content, children, }) => {
8
- return (_jsxs("div", { className: cn('group relative px-5 py-2 text-xs', className, type === 'error' && 'border-destructive rounded-md border py-4'), children: [type === 'error' && (_jsxs(Badge, { variant: "secondary", className: cn('absolute left-2 top-[-12px] flex items-center gap-1 border text-xs', 'border-destructive bg-background'), children: [_jsx(XCircleIcon, { className: "h-3 w-3 text-red-500" }), type] })), _jsx("div", { className: "absolute right-2 top-2 opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: _jsx(CodeIcon, { className: "h-4 w-4" }) }) }), _jsx(PopoverContent, { className: "max-h-[300px] w-[400px] overflow-auto p-4", side: "right", align: "start", children: _jsx(JsonMonacoEditor, { value: JSON.stringify(content, null, 2), readOnly: true, className: "h-[250px]", options: {
9
- minimap: { enabled: false },
10
- scrollBeyondLastLine: false,
11
- automaticLayout: true,
12
- folding: true,
13
- lineNumbers: false,
14
- wordWrap: 'on',
15
- } }) })] }) }), _jsx("div", { className: "flex flex-col gap-5", children: children })] }));
7
+ return (_jsxs("div", { className: cn('group relative px-5 py-2 text-xs', className, type === 'error' && 'border-destructive rounded-md border py-4'), children: [type === 'error' && (_jsxs(Badge, { variant: "secondary", className: cn('absolute left-2 top-[-12px] flex items-center gap-1 border text-xs', 'border-destructive bg-background'), children: [_jsx(XCircleIcon, { className: "h-3 w-3 text-red-500" }), type] })), _jsx("div", { className: "flex flex-col gap-5", children: children })] }));
16
8
  };
17
9
  //# sourceMappingURL=MessageContainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageContainer.js","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,KAAK,EACL,MAAM,EACN,EAAE,EACF,OAAO,EACP,cAAc,EACd,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,QAAQ,EAAE,WAAW,EAAC,MAAM,cAAc,CAAC;AAWnD,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,EACT,IAAI;AACJ,eAAe;AACf,OAAO,EACP,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,kCAAkC,EAClC,SAAS,EACT,IAAI,KAAK,OAAO,IAAI,2CAA2C,CAGhE,aAEA,IAAI,KAAK,OAAO,IAAI,CACnB,MAAC,KAAK,IACJ,OAAO,EAAC,WAAW,EACnB,SAAS,EAAE,EAAE,CACX,oEAAoE,EACpE,kCAAkC,CAEnC,aAKD,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAE/C,IAAI,IACC,CACT,EAED,cAAK,SAAS,EAAC,0FAA0F,YACvG,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,SAAS,YACrD,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,GACzB,GACM,EACjB,KAAC,cAAc,IACb,SAAS,EAAC,2CAA2C,EACrD,IAAI,EAAC,OAAO,EACZ,KAAK,EAAC,OAAO,YAEb,KAAC,gBAAgB,IACf,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EACvC,QAAQ,EAAE,IAAI,EACd,SAAS,EAAC,WAAW,EACrB,OAAO,EAAE;oCACP,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC;oCACzB,oBAAoB,EAAE,KAAK;oCAC3B,eAAe,EAAE,IAAI;oCACrB,OAAO,EAAE,IAAI;oCACb,WAAW,EAAE,KAAK;oCAClB,QAAQ,EAAE,IAAI;iCACf,GACD,GACa,IACT,GACN,EAEN,cAAK,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAO,IACjD,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Badge,\n Button,\n cn,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {CodeIcon, XCircleIcon} from 'lucide-react';\n\ntype MessageContainerProps = {\n className?: string;\n isSuccess: boolean;\n // borderColor: string;\n type: string;\n content: object;\n children: React.ReactNode;\n};\n\nexport const MessageContainer: React.FC<MessageContainerProps> = ({\n className,\n type,\n // borderColor,\n content,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'group relative px-5 py-2 text-xs',\n className,\n type === 'error' && 'border-destructive rounded-md border py-4',\n // borderColor,\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {type === 'error' && (\n <Badge\n variant=\"secondary\"\n className={cn(\n 'absolute left-2 top-[-12px] flex items-center gap-1 border text-xs',\n 'border-destructive bg-background',\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {/* {isSuccess ? ( */}\n {/* <CheckCircle2Icon className=\"h-3 w-3 text-green-500\" /> */}\n {/* ) : ( */}\n <XCircleIcon className=\"h-3 w-3 text-red-500\" />\n {/* )} */}\n {type}\n </Badge>\n )}\n\n <div className=\"absolute right-2 top-2 opacity-0 transition-opacity duration-200 group-hover:opacity-100\">\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <CodeIcon className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"max-h-[300px] w-[400px] overflow-auto p-4\"\n side=\"right\"\n align=\"start\"\n >\n <JsonMonacoEditor\n value={JSON.stringify(content, null, 2)}\n readOnly={true}\n className=\"h-[250px]\"\n options={{\n minimap: {enabled: false},\n scrollBeyondLastLine: false,\n automaticLayout: true,\n folding: true,\n lineNumbers: false,\n wordWrap: 'on',\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n\n <div className=\"flex flex-col gap-5\">{children}</div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"MessageContainer.js","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,KAAK,EAEL,EAAE,GAIH,MAAM,cAAc,CAAC;AACtB,OAAO,EAAW,WAAW,EAAC,MAAM,cAAc,CAAC;AAWnD,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,EACT,IAAI;AACJ,eAAe;AACf,OAAO,EACP,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,kCAAkC,EAClC,SAAS,EACT,IAAI,KAAK,OAAO,IAAI,2CAA2C,CAGhE,aAEA,IAAI,KAAK,OAAO,IAAI,CACnB,MAAC,KAAK,IACJ,OAAO,EAAC,WAAW,EACnB,SAAS,EAAE,EAAE,CACX,oEAAoE,EACpE,kCAAkC,CAEnC,aAKD,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAE/C,IAAI,IACC,CACT,EAED,cAAK,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAO,IACjD,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Badge,\n Button,\n cn,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {CodeIcon, XCircleIcon} from 'lucide-react';\n\ntype MessageContainerProps = {\n className?: string;\n isSuccess: boolean;\n // borderColor: string;\n type: string;\n content: object;\n children: React.ReactNode;\n};\n\nexport const MessageContainer: React.FC<MessageContainerProps> = ({\n className,\n type,\n // borderColor,\n content,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'group relative px-5 py-2 text-xs',\n className,\n type === 'error' && 'border-destructive rounded-md border py-4',\n // borderColor,\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {type === 'error' && (\n <Badge\n variant=\"secondary\"\n className={cn(\n 'absolute left-2 top-[-12px] flex items-center gap-1 border text-xs',\n 'border-destructive bg-background',\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {/* {isSuccess ? ( */}\n {/* <CheckCircle2Icon className=\"h-3 w-3 text-green-500\" /> */}\n {/* ) : ( */}\n <XCircleIcon className=\"h-3 w-3 text-red-500\" />\n {/* )} */}\n {type}\n </Badge>\n )}\n\n <div className=\"flex flex-col gap-5\">{children}</div>\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../../src/components/QueryControls.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,iBAAiB,EAAiC,MAAM,OAAO,CAAC;AAGxE,KAAK,kBAAkB,GAAG,iBAAiB,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyGtD,CAAC"}
1
+ {"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../../src/components/QueryControls.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,iBAAiB,EAAiC,MAAM,OAAO,CAAC;AAGxE,KAAK,kBAAkB,GAAG,iBAAiB,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6FtD,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, cn, Spinner, Textarea } from '@sqlrooms/ui';
2
+ import { Button, cn, Textarea } from '@sqlrooms/ui';
3
3
  import { ArrowUpIcon, OctagonXIcon } from 'lucide-react';
4
4
  import { useCallback, useRef, useEffect } from 'react';
5
5
  import { useStoreWithAi } from '../AiSlice';
6
- export const QueryControls = ({ className, placeholder = 'Type here what would you like to learn about the data?', children, }) => {
6
+ export const QueryControls = ({ className, placeholder = 'What would you like to learn about the data?', children, }) => {
7
7
  const textareaRef = useRef(null);
8
8
  const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);
9
9
  const runAnalysis = useStoreWithAi((s) => s.ai.startAnalysis);
@@ -39,7 +39,7 @@ export const QueryControls = ({ className, placeholder = 'Type here what would y
39
39
  }
40
40
  }
41
41
  }, [isRunningAnalysis, model, analysisPrompt, runAnalysis]);
42
- const canStart = Boolean(!isRunningAnalysis && model && analysisPrompt.trim().length);
43
- return (_jsx("div", { className: cn('flex w-full flex-col items-center justify-center gap-4', className), children: _jsx("div", { className: "relative w-full overflow-hidden p-[1px]", children: _jsxs("div", { className: "flex flex-col", children: [_jsx(Textarea, { ref: textareaRef, disabled: isRunningAnalysis, className: "bg-muted/50 h-[100px] resize-none", value: analysisPrompt, onChange: (e) => setAnalysisPrompt(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: true }), _jsxs("div", { className: "bg-muted/30 flex w-full items-center justify-between gap-2 p-2", children: [_jsx("div", { children: children }), _jsx("div", { className: "flex-1" }), _jsxs("div", { children: [isRunningAnalysis && (_jsxs(Button, { variant: "outline", className: "rounded-full", onClick: cancelAnalysis, children: [_jsx(OctagonXIcon, { className: "h-4 w-4" }), "Stop"] })), _jsx(Button, { className: "h-10 w-10 rounded-full", variant: "default", size: "icon", onClick: runAnalysis, disabled: !canStart, children: isRunningAnalysis ? (_jsx("div", { className: "flex items-center gap-2", children: _jsx(Spinner, { className: "h-4 w-4" }) })) : (_jsx(ArrowUpIcon, {})) })] })] })] }) }) }));
42
+ const canStart = Boolean(model && analysisPrompt.trim().length);
43
+ return (_jsx("div", { className: cn('flex w-full flex-col items-center justify-center gap-4', className), children: _jsx("div", { className: "bg-muted/50 flex h-full w-full flex-row items-center gap-2 rounded-md border", children: _jsxs("div", { className: "flex w-full flex-col gap-1 overflow-hidden", children: [_jsx(Textarea, { ref: textareaRef, disabled: isRunningAnalysis, className: "min-h-[30px] resize-none border-none p-2 text-sm outline-none focus-visible:ring-0", autoResize: true, value: analysisPrompt, onChange: (e) => setAnalysisPrompt(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: true }), _jsx("div", { className: "align-stretch flex w-full items-center gap-2 overflow-hidden", children: _jsxs("div", { className: "flex h-full w-full min-w-0 items-center gap-2 overflow-hidden", children: [_jsx("div", { className: "min-w-0 flex-1 overflow-hidden pl-2", children: _jsx("div", { className: "flex flex-nowrap items-center gap-2 overflow-x-auto py-1", children: children }) }), _jsx("div", { className: "ml-auto shrink-0 pr-2", children: _jsx(Button, { className: "h-8 w-8 rounded-full", variant: "default", size: "icon", onClick: isRunningAnalysis ? cancelAnalysis : runAnalysis, disabled: !canStart, children: isRunningAnalysis ? _jsx(OctagonXIcon, {}) : _jsx(ArrowUpIcon, {}) }) })] }) })] }) }) }));
44
44
  };
45
45
  //# sourceMappingURL=QueryControls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryControls.js","sourceRoot":"","sources":["../../src/components/QueryControls.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Button, cn, Spinner, Textarea} from '@sqlrooms/ui';\nimport {ArrowUpIcon, OctagonXIcon} from 'lucide-react';\nimport {PropsWithChildren, useCallback, useRef, useEffect} from 'react';\nimport {useStoreWithAi} from '../AiSlice';\n\ntype QueryControlsProps = PropsWithChildren<{\n className?: string;\n placeholder?: string;\n}>;\n\nexport const QueryControls: React.FC<QueryControlsProps> = ({\n className,\n placeholder = 'Type here what would you like to learn about the data?',\n children,\n}) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);\n const runAnalysis = useStoreWithAi((s) => s.ai.startAnalysis);\n const cancelAnalysis = useStoreWithAi((s) => s.ai.cancelAnalysis);\n const analysisPrompt = useStoreWithAi((s) => s.ai.analysisPrompt);\n const isDataAvailable = useStoreWithAi((s) => s.room.isDataAvailable);\n const setAnalysisPrompt = useStoreWithAi((s) => s.ai.setAnalysisPrompt);\n const currentSession = useStoreWithAi((s) => s.ai.getCurrentSession());\n const model = currentSession?.model;\n\n useEffect(() => {\n if (!isDataAvailable) return;\n // Focus the textarea when the component mounts\n // Using a small timeout ensures the data is loaded and\n // add timeout to prevent aria hidden warning caused by the\n // loading progress dialog being still open\n const timer = setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n }, 500);\n\n return () => clearTimeout(timer);\n }, [isDataAvailable]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (\n e.key === 'Enter' &&\n !e.shiftKey &&\n !e.ctrlKey &&\n !e.altKey &&\n !e.metaKey\n ) {\n e.preventDefault();\n if (!isRunningAnalysis && model && analysisPrompt.trim().length) {\n runAnalysis();\n }\n }\n },\n [isRunningAnalysis, model, analysisPrompt, runAnalysis],\n );\n\n const canStart = Boolean(\n !isRunningAnalysis && model && analysisPrompt.trim().length,\n );\n return (\n <div\n className={cn(\n 'flex w-full flex-col items-center justify-center gap-4',\n className,\n )}\n >\n <div className=\"relative w-full overflow-hidden p-[1px]\">\n <div className=\"flex flex-col\">\n <Textarea\n ref={textareaRef}\n disabled={isRunningAnalysis}\n className=\"bg-muted/50 h-[100px] resize-none\"\n value={analysisPrompt}\n onChange={(e) => setAnalysisPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n autoFocus\n />\n <div className=\"bg-muted/30 flex w-full items-center justify-between gap-2 p-2\">\n <div>{children}</div>\n <div className=\"flex-1\" />\n <div>\n {isRunningAnalysis && (\n <Button\n variant=\"outline\"\n className=\"rounded-full\"\n onClick={cancelAnalysis}\n >\n <OctagonXIcon className=\"h-4 w-4\" />\n Stop\n </Button>\n )}\n <Button\n className=\"h-10 w-10 rounded-full\"\n variant=\"default\"\n size=\"icon\"\n onClick={runAnalysis}\n disabled={!canStart}\n >\n {isRunningAnalysis ? (\n <div className=\"flex items-center gap-2\">\n <Spinner className=\"h-4 w-4\" />\n </div>\n ) : (\n <ArrowUpIcon />\n )}\n </Button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"QueryControls.js","sourceRoot":"","sources":["../../src/components/QueryControls.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Button, cn, Spinner, Textarea} from '@sqlrooms/ui';\nimport {ArrowUpIcon, OctagonXIcon} from 'lucide-react';\nimport {PropsWithChildren, useCallback, useRef, useEffect} from 'react';\nimport {useStoreWithAi} from '../AiSlice';\n\ntype QueryControlsProps = PropsWithChildren<{\n className?: string;\n placeholder?: string;\n}>;\n\nexport const QueryControls: React.FC<QueryControlsProps> = ({\n className,\n placeholder = 'What would you like to learn about the data?',\n children,\n}) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);\n const runAnalysis = useStoreWithAi((s) => s.ai.startAnalysis);\n const cancelAnalysis = useStoreWithAi((s) => s.ai.cancelAnalysis);\n const analysisPrompt = useStoreWithAi((s) => s.ai.analysisPrompt);\n const isDataAvailable = useStoreWithAi((s) => s.room.isDataAvailable);\n const setAnalysisPrompt = useStoreWithAi((s) => s.ai.setAnalysisPrompt);\n const currentSession = useStoreWithAi((s) => s.ai.getCurrentSession());\n const model = currentSession?.model;\n\n useEffect(() => {\n if (!isDataAvailable) return;\n // Focus the textarea when the component mounts\n // Using a small timeout ensures the data is loaded and\n // add timeout to prevent aria hidden warning caused by the\n // loading progress dialog being still open\n const timer = setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n }, 500);\n\n return () => clearTimeout(timer);\n }, [isDataAvailable]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (\n e.key === 'Enter' &&\n !e.shiftKey &&\n !e.ctrlKey &&\n !e.altKey &&\n !e.metaKey\n ) {\n e.preventDefault();\n if (!isRunningAnalysis && model && analysisPrompt.trim().length) {\n runAnalysis();\n }\n }\n },\n [isRunningAnalysis, model, analysisPrompt, runAnalysis],\n );\n\n const canStart = Boolean(model && analysisPrompt.trim().length);\n return (\n <div\n className={cn(\n 'flex w-full flex-col items-center justify-center gap-4',\n className,\n )}\n >\n <div className=\"bg-muted/50 flex h-full w-full flex-row items-center gap-2 rounded-md border\">\n <div className=\"flex w-full flex-col gap-1 overflow-hidden\">\n <Textarea\n ref={textareaRef}\n disabled={isRunningAnalysis}\n className=\"min-h-[30px] resize-none border-none p-2 text-sm outline-none focus-visible:ring-0\"\n autoResize\n value={analysisPrompt}\n onChange={(e) => setAnalysisPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n autoFocus\n />\n <div className=\"align-stretch flex w-full items-center gap-2 overflow-hidden\">\n <div className=\"flex h-full w-full min-w-0 items-center gap-2 overflow-hidden\">\n <div className=\"min-w-0 flex-1 overflow-hidden pl-2\">\n <div className=\"flex flex-nowrap items-center gap-2 overflow-x-auto py-1\">\n {children}\n </div>\n </div>\n <div className=\"ml-auto shrink-0 pr-2\">\n <Button\n className=\"h-8 w-8 rounded-full\"\n variant=\"default\"\n size=\"icon\"\n onClick={isRunningAnalysis ? cancelAnalysis : runAnalysis}\n disabled={!canStart}\n >\n {isRunningAnalysis ? <OctagonXIcon /> : <ArrowUpIcon />}\n </Button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryToolResult.d.ts","sourceRoot":"","sources":["../../../src/components/tools/QueryToolResult.tsx"],"names":[],"mappings":"AAIA,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,oBAAoB,2CAiBtE"}
1
+ {"version":3,"file":"QueryToolResult.d.ts","sourceRoot":"","sources":["../../../src/components/tools/QueryToolResult.tsx"],"names":[],"mappings":"AAIA,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,oBAAoB,2CA0BtE"}
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { DataTableModal } from '@sqlrooms/data-table';
3
- import { Button, useDisclosure } from '@sqlrooms/ui';
3
+ import { Button, CopyButton, useDisclosure } from '@sqlrooms/ui';
4
4
  import { TableIcon } from 'lucide-react';
5
5
  export function QueryToolResult({ title, sqlQuery }) {
6
6
  const tableModal = useDisclosure();
7
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground bg-muted max-h-20 w-full overflow-auto whitespace-pre-wrap rounded-md p-2 font-mono text-xs", children: sqlQuery }), _jsx("div", { children: _jsxs(Button, { variant: "ghost", size: "sm", onClick: tableModal.onOpen, children: [_jsx(TableIcon, { className: "h-4 w-4" }), _jsx("h3", { className: "ml-1 text-xs", children: "Show Query Result" })] }) }), _jsx(DataTableModal, { title: title, query: sqlQuery, tableModal: tableModal })] }));
7
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground bg-muted relative max-h-[150px] w-full overflow-auto rounded-md p-2 font-mono text-xs", children: [_jsx("pre", { className: "whitespace-pre-wrap break-words pr-8", children: sqlQuery }), _jsx("div", { className: "absolute right-1 top-1", children: _jsx(CopyButton, { text: sqlQuery, variant: "ghost", size: "icon", className: "h-6 w-6", ariaLabel: "Copy SQL" }) })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs(Button, { variant: "ghost", size: "sm", onClick: tableModal.onOpen, children: [_jsx(TableIcon, { className: "h-4 w-4" }), _jsx("h3", { className: "ml-1 text-xs", children: "Show Query Result" })] }) }), _jsx(DataTableModal, { title: title, query: sqlQuery, tableModal: tableModal })] }));
8
8
  }
9
9
  //# sourceMappingURL=QueryToolResult.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryToolResult.js","sourceRoot":"","sources":["../../../src/components/tools/QueryToolResult.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,MAAM,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AACnD,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAOvC,MAAM,UAAU,eAAe,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAuB;IACrE,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO,CACL,8BACE,cAAK,SAAS,EAAC,mHAAmH,YAC/H,QAAQ,GACL,EACN,wBACE,MAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,UAAU,CAAC,MAAM,aAC1D,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,EACjC,aAAI,SAAS,EAAC,cAAc,kCAAuB,IAC5C,GACL,EAEN,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,GAAI,IACxE,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import {DataTableModal} from '@sqlrooms/data-table';\nimport {Button, useDisclosure} from '@sqlrooms/ui';\nimport {TableIcon} from 'lucide-react';\n\ntype QueryToolResultProps = {\n title: string;\n sqlQuery: string;\n};\n\nexport function QueryToolResult({title, sqlQuery}: QueryToolResultProps) {\n const tableModal = useDisclosure();\n return (\n <>\n <div className=\"text-muted-foreground bg-muted max-h-20 w-full overflow-auto whitespace-pre-wrap rounded-md p-2 font-mono text-xs\">\n {sqlQuery}\n </div>\n <div>\n <Button variant=\"ghost\" size=\"sm\" onClick={tableModal.onOpen}>\n <TableIcon className=\"h-4 w-4\" />\n <h3 className=\"ml-1 text-xs\">Show Query Result</h3>\n </Button>\n </div>\n\n <DataTableModal title={title} query={sqlQuery} tableModal={tableModal} />\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"QueryToolResult.js","sourceRoot":"","sources":["../../../src/components/tools/QueryToolResult.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAOvC,MAAM,UAAU,eAAe,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAuB;IACrE,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO,CACL,8BACE,eAAK,SAAS,EAAC,6GAA6G,aAC1H,cAAK,SAAS,EAAC,sCAAsC,YAAE,QAAQ,GAAO,EACtE,cAAK,SAAS,EAAC,wBAAwB,YACrC,KAAC,UAAU,IACT,IAAI,EAAE,QAAQ,EACd,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,SAAS,EACnB,SAAS,EAAC,UAAU,GACpB,GACE,IACF,EACN,cAAK,SAAS,EAAC,yBAAyB,YACtC,MAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,UAAU,CAAC,MAAM,aAC1D,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,EACjC,aAAI,SAAS,EAAC,cAAc,kCAAuB,IAC5C,GACL,EAEN,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,GAAI,IACxE,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import {DataTableModal} from '@sqlrooms/data-table';\nimport {Button, CopyButton, useDisclosure} from '@sqlrooms/ui';\nimport {TableIcon} from 'lucide-react';\n\ntype QueryToolResultProps = {\n title: string;\n sqlQuery: string;\n};\n\nexport function QueryToolResult({title, sqlQuery}: QueryToolResultProps) {\n const tableModal = useDisclosure();\n return (\n <>\n <div className=\"text-muted-foreground bg-muted relative max-h-[150px] w-full overflow-auto rounded-md p-2 font-mono text-xs\">\n <pre className=\"whitespace-pre-wrap break-words pr-8\">{sqlQuery}</pre>\n <div className=\"absolute right-1 top-1\">\n <CopyButton\n text={sqlQuery}\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n ariaLabel=\"Copy SQL\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={tableModal.onOpen}>\n <TableIcon className=\"h-4 w-4\" />\n <h3 className=\"ml-1 text-xs\">Show Query Result</h3>\n </Button>\n </div>\n\n <DataTableModal title={title} query={sqlQuery} tableModal={tableModal} />\n </>\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.12",
3
+ "version": "0.24.14",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/index.js",
@@ -19,21 +19,22 @@
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.12",
26
- "@sqlrooms/duckdb": "0.24.12",
27
- "@sqlrooms/monaco-editor": "0.24.12",
28
- "@sqlrooms/room-config": "0.24.12",
29
- "@sqlrooms/room-shell": "0.24.12",
30
- "@sqlrooms/ui": "0.24.12",
31
- "@sqlrooms/utils": "0.24.12",
25
+ "@sqlrooms/data-table": "0.24.14",
26
+ "@sqlrooms/duckdb": "0.24.14",
27
+ "@sqlrooms/monaco-editor": "0.24.14",
28
+ "@sqlrooms/room-config": "0.24.14",
29
+ "@sqlrooms/room-shell": "0.24.14",
30
+ "@sqlrooms/ui": "0.24.14",
31
+ "@sqlrooms/utils": "0.24.14",
32
32
  "ai": "^4.3.19",
33
33
  "immer": "^10.1.1",
34
34
  "lucide-react": "^0.475.0",
35
35
  "react-markdown": "^9.1.0",
36
36
  "rehype-raw": "^7.0.0",
37
+ "remark-gfm": "^4.0.0",
37
38
  "zod": "^3.25.73"
38
39
  },
39
40
  "peerDependencies": {
@@ -47,5 +48,5 @@
47
48
  "typecheck": "tsc --noEmit",
48
49
  "typedoc": "typedoc"
49
50
  },
50
- "gitHead": "f3ce3a79a8ae548a619a7e6bda1f1b21fffd2e1f"
51
+ "gitHead": "ecde53ffece563b8151b5b7139b444827add7135"
51
52
  }