@sqlrooms/ai 0.26.1-rc.7 → 0.27.0-rc.1

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/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright 2025 Ilya Boyandin
3
+ Copyright 2025 SQLRooms Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
package/README.md CHANGED
@@ -87,7 +87,7 @@ const {roomStore, useRoomStore} = createRoomStore({
87
87
  }),
88
88
  // Add AI slice
89
89
  ...createAiSlice({
90
- initialAnalysisPrompt: 'What insights can you provide from my data?',
90
+ initialPrompt: 'What insights can you provide from my data?',
91
91
  // Optional: Add custom tools
92
92
  tools: {
93
93
  // Your custom tools
@@ -131,7 +131,7 @@ export const {roomStore, useRoomStore} = createRoomStore<RoomConfig, RoomState>(
131
131
  // Base room slice
132
132
  ...createRoomShellSlice({
133
133
  config: {
134
- ...createDefaultSqlEditorConfig(),
134
+ // Base room slice config
135
135
  },
136
136
  }),
137
137
  // AI settings slice
@@ -159,7 +159,7 @@ export const {roomStore, useRoomStore} = createRoomStore<RoomConfig, RoomState>(
159
159
  }),
160
160
  // AI slice
161
161
  ...createAiSlice({
162
- initialAnalysisPrompt: 'What insights can you provide from my data?',
162
+ initialPrompt: 'What insights can you provide from my data?',
163
163
  tools: {
164
164
  // Your custom tools
165
165
  },
@@ -218,13 +218,13 @@ function AnalysisPanel() {
218
218
 
219
219
  ```tsx
220
220
  function AiStatusIndicator() {
221
- const isRunningAnalysis = useRoomStore((state) => state.ai.isRunningAnalysis);
222
- const analysisPrompt = useRoomStore((state) => state.ai.analysisPrompt);
221
+ const isRunning = useRoomStore((state) => state.ai.isRunning);
222
+ const prompt = useRoomStore((state) => state.ai.prompt);
223
223
  const currentSession = useRoomStore((state) => state.ai.getCurrentSession());
224
224
  const lastResult =
225
225
  currentSession?.analysisResults[currentSession.analysisResults.length - 1];
226
226
 
227
- if (isRunningAnalysis) {
227
+ if (isRunning) {
228
228
  return <div>AI is analyzing your data...</div>;
229
229
  }
230
230
 
@@ -232,8 +232,8 @@ function AiStatusIndicator() {
232
232
  return <div>Error: {lastResult.errorMessage.message}</div>;
233
233
  }
234
234
 
235
- if (analysisPrompt) {
236
- return <div>Last query: "{analysisPrompt}"</div>;
235
+ if (prompt) {
236
+ return <div>Last query: "{prompt}"</div>;
237
237
  }
238
238
 
239
239
  return <div>Ask AI a question about your data</div>;
@@ -246,20 +246,20 @@ The AiSlice provides a comprehensive set of state fields and methods for managin
246
246
 
247
247
  ### State Fields
248
248
 
249
- #### `analysisPrompt`
249
+ #### `prompt`
250
250
 
251
251
  The current prompt text entered by the user for analysis.
252
252
 
253
253
  ```tsx
254
- const prompt = useRoomStore((state) => state.ai.analysisPrompt);
254
+ const prompt = useRoomStore((state) => state.ai.prompt);
255
255
  ```
256
256
 
257
- #### `isRunningAnalysis`
257
+ #### `isRunning`
258
258
 
259
259
  Boolean flag indicating whether an analysis is currently in progress.
260
260
 
261
261
  ```tsx
262
- const isRunning = useRoomStore((state) => state.ai.isRunningAnalysis);
262
+ const isRunning = useRoomStore((state) => state.ai.isRunning);
263
263
  ```
264
264
 
265
265
  #### `tools`
@@ -270,24 +270,24 @@ Record of available AI tools that can be used during analysis.
270
270
  const availableTools = useRoomStore((state) => state.ai.tools);
271
271
  ```
272
272
 
273
- #### `analysisAbortController`
273
+ #### `abortController`
274
274
 
275
275
  Optional AbortController instance that can be used to cancel an ongoing analysis.
276
276
 
277
277
  ```tsx
278
278
  const abortController = useRoomStore(
279
- (state) => state.ai.analysisAbortController,
279
+ (state) => state.ai.abortController,
280
280
  );
281
281
  ```
282
282
 
283
283
  ### Methods
284
284
 
285
- #### `setAnalysisPrompt(prompt: string)`
285
+ #### `setPrompt(prompt: string)`
286
286
 
287
287
  Sets the current analysis prompt text.
288
288
 
289
289
  ```tsx
290
- const setPrompt = useRoomStore((state) => state.ai.setAnalysisPrompt);
290
+ const setPrompt = useRoomStore((state) => state.ai.setPrompt);
291
291
  setPrompt('Analyze sales trends for the last quarter');
292
292
  ```
293
293
 
package/dist/index.d.ts CHANGED
@@ -10,14 +10,15 @@ export { createDefaultAiInstructions, formatTablesForLLM, } from './tools/defaul
10
10
  export { createAiSlice, useStoreWithAi } from '@sqlrooms/ai-core';
11
11
  export type { AiSliceState } from '@sqlrooms/ai-core';
12
12
  export { useScrollToBottom } from '@sqlrooms/ai-core';
13
- export { useAiChat } from '@sqlrooms/ai-core';
14
13
  export { AiThinkingDots } from '@sqlrooms/ai-core';
15
14
  export { cleanupPendingAnalysisResults, ToolAbortError } from '@sqlrooms/ai-core';
16
- export { convertToAiSDKTools, completeIncompleteToolCalls, } from '@sqlrooms/ai-core';
15
+ export { convertToAiSDKTools, fixIncompleteToolCalls } from '@sqlrooms/ai-core';
17
16
  export { processAgentStream, updateAgentToolCallData } from '@sqlrooms/ai-core';
18
17
  export type { AgentStreamResult, UIMessageChunk, AgentToolCall, AgentToolCallAdditionalData, } from '@sqlrooms/ai-core';
19
18
  export { AnalysisResultsContainer } from '@sqlrooms/ai-core';
20
19
  export { AnalysisResult } from '@sqlrooms/ai-core';
20
+ export { ErrorMessage } from '@sqlrooms/ai-core';
21
+ export type { ErrorMessageComponentProps } from '@sqlrooms/ai-core';
21
22
  export { PromptSuggestions } from '@sqlrooms/ai-core';
22
23
  export { ModelSelector } from '@sqlrooms/ai-core';
23
24
  export { SessionControls } from '@sqlrooms/ai-core';
@@ -30,6 +31,7 @@ export type { SessionType } from '@sqlrooms/ai-core';
30
31
  export { ToolErrorMessage } from '@sqlrooms/ai-core';
31
32
  export { ToolCallInfo } from '@sqlrooms/ai-core';
32
33
  export { ReasoningBox } from '@sqlrooms/ai-core';
34
+ export { Chat } from '@sqlrooms/ai-core';
33
35
  export { AiSliceConfig, createDefaultAiConfig, AiSettingsSliceConfig, AnalysisSessionSchema, AnalysisResultSchema, ErrorMessageSchema, } from '@sqlrooms/ai-config';
34
36
  export type { ToolUIPart, UIMessagePart } from '@sqlrooms/ai-config';
35
37
  export { createAiSettingsSlice, useStoreWithAiSettings, } from '@sqlrooms/ai-settings';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAChE,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,6BAA6B,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,kBAAkB,EAAE,uBAAuB,EAAC,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAGnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAC,oBAAoB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,6BAA6B,EAAC,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,14 +10,15 @@ export { createDefaultAiInstructions, formatTablesForLLM, } from './tools/defaul
10
10
  // From @sqlrooms/ai-core - State/Logic
11
11
  export { createAiSlice, useStoreWithAi } from '@sqlrooms/ai-core';
12
12
  export { useScrollToBottom } from '@sqlrooms/ai-core';
13
- export { useAiChat } from '@sqlrooms/ai-core';
14
13
  export { AiThinkingDots } from '@sqlrooms/ai-core';
15
14
  export { cleanupPendingAnalysisResults, ToolAbortError } from '@sqlrooms/ai-core';
16
- export { convertToAiSDKTools, completeIncompleteToolCalls, } from '@sqlrooms/ai-core';
15
+ export { convertToAiSDKTools, fixIncompleteToolCalls } from '@sqlrooms/ai-core';
17
16
  export { processAgentStream, updateAgentToolCallData } from '@sqlrooms/ai-core';
18
17
  // From @sqlrooms/ai-core - Components
18
+ // @deprecated Use `Chat.Messages` instead.
19
19
  export { AnalysisResultsContainer } from '@sqlrooms/ai-core';
20
20
  export { AnalysisResult } from '@sqlrooms/ai-core';
21
+ export { ErrorMessage } from '@sqlrooms/ai-core';
21
22
  export { PromptSuggestions } from '@sqlrooms/ai-core';
22
23
  export { ModelSelector } from '@sqlrooms/ai-core';
23
24
  export { SessionControls } from '@sqlrooms/ai-core';
@@ -29,6 +30,7 @@ export { SessionTitle } from '@sqlrooms/ai-core';
29
30
  export { ToolErrorMessage } from '@sqlrooms/ai-core';
30
31
  export { ToolCallInfo } from '@sqlrooms/ai-core';
31
32
  export { ReasoningBox } from '@sqlrooms/ai-core';
33
+ export { Chat } from '@sqlrooms/ai-core';
32
34
  // From @sqlrooms/ai-config
33
35
  export { AiSliceConfig, createDefaultAiConfig, AiSettingsSliceConfig, AnalysisSessionSchema, AnalysisResultSchema, ErrorMessageSchema, } from '@sqlrooms/ai-config';
34
36
  // From @sqlrooms/ai-settings - State/Logic
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAQ;AACR,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,GAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAErC,uCAAuC;AACvC,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,6BAA6B,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,kBAAkB,EAAE,uBAAuB,EAAC,MAAM,mBAAmB,CAAC;AAQ9E,sCAAsC;AACtC,OAAO,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,2BAA2B;AAC3B,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,2CAA2C;AAC3C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAC,6BAA6B,EAAC,MAAM,uBAAuB,CAAC;AAEpE,0CAA0C;AAC1C,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\n// Tools\nexport {QueryToolResult} from './tools/query/QueryToolResult';\nexport {\n QueryToolParameters,\n createQueryTool,\n getQuerySummary,\n type QueryToolLlmResult,\n type QueryToolAdditionalData,\n type QueryToolOptions,\n} from './tools/query/queryTool';\nexport {createDefaultAiTools} from './tools/defaultTools';\nexport type {DefaultToolsOptions} from './tools/defaultTools';\nexport {\n createDefaultAiInstructions,\n formatTablesForLLM,\n} from './tools/defaultInstructions';\n\n// From @sqlrooms/ai-core - State/Logic\nexport {createAiSlice, useStoreWithAi} from '@sqlrooms/ai-core';\nexport type {AiSliceState} from '@sqlrooms/ai-core';\nexport {useScrollToBottom} from '@sqlrooms/ai-core';\nexport {useAiChat} from '@sqlrooms/ai-core';\nexport {AiThinkingDots} from '@sqlrooms/ai-core';\nexport {cleanupPendingAnalysisResults, ToolAbortError} from '@sqlrooms/ai-core';\nexport {\n convertToAiSDKTools,\n completeIncompleteToolCalls,\n} from '@sqlrooms/ai-core';\nexport {processAgentStream, updateAgentToolCallData} from '@sqlrooms/ai-core';\nexport type {\n AgentStreamResult,\n UIMessageChunk,\n AgentToolCall,\n AgentToolCallAdditionalData,\n} from '@sqlrooms/ai-core';\n\n// From @sqlrooms/ai-core - Components\nexport {AnalysisResultsContainer} from '@sqlrooms/ai-core';\nexport {AnalysisResult} from '@sqlrooms/ai-core';\nexport {PromptSuggestions} from '@sqlrooms/ai-core';\nexport {ModelSelector} from '@sqlrooms/ai-core';\nexport {SessionControls} from '@sqlrooms/ai-core';\nexport {QueryControls} from '@sqlrooms/ai-core';\nexport {DeleteSessionDialog} from '@sqlrooms/ai-core';\nexport {SessionActions} from '@sqlrooms/ai-core';\nexport {SessionDropdown} from '@sqlrooms/ai-core';\nexport {SessionTitle} from '@sqlrooms/ai-core';\nexport type {SessionType} from '@sqlrooms/ai-core';\nexport {ToolErrorMessage} from '@sqlrooms/ai-core';\nexport {ToolCallInfo} from '@sqlrooms/ai-core';\nexport {ReasoningBox} from '@sqlrooms/ai-core';\n\n// From @sqlrooms/ai-config\nexport {\n AiSliceConfig,\n createDefaultAiConfig,\n AiSettingsSliceConfig,\n AnalysisSessionSchema,\n AnalysisResultSchema,\n ErrorMessageSchema,\n} from '@sqlrooms/ai-config';\nexport type {ToolUIPart, UIMessagePart} from '@sqlrooms/ai-config';\n\n// From @sqlrooms/ai-settings - State/Logic\nexport {\n createAiSettingsSlice,\n useStoreWithAiSettings,\n} from '@sqlrooms/ai-settings';\nexport type {AiSettingsSliceState} from '@sqlrooms/ai-settings';\nexport {createDefaultAiSettingsConfig} from '@sqlrooms/ai-settings';\n\n// From @sqlrooms/ai-settings - Components\nexport {AiSettingsPanel} from '@sqlrooms/ai-settings';\nexport {AiProvidersSettings} from '@sqlrooms/ai-settings';\nexport {AiModelsSettings} from '@sqlrooms/ai-settings';\nexport {AiModelParameters} from '@sqlrooms/ai-settings';\nexport {AiModelUsage} from '@sqlrooms/ai-settings';\nexport type {ModelUsageData} from '@sqlrooms/ai-settings';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAQ;AACR,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,GAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAErC,uCAAuC;AACvC,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,6BAA6B,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAC,mBAAmB,EAAE,sBAAsB,EAAC,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAC,kBAAkB,EAAE,uBAAuB,EAAC,MAAM,mBAAmB,CAAC;AAQ9E,sCAAsC;AACtC,2CAA2C;AAC3C,OAAO,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,IAAI,EAAC,MAAM,mBAAmB,CAAC;AAEvC,2BAA2B;AAC3B,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,2CAA2C;AAC3C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAC,6BAA6B,EAAC,MAAM,uBAAuB,CAAC;AAEpE,0CAA0C;AAC1C,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\n// Tools\nexport {QueryToolResult} from './tools/query/QueryToolResult';\nexport {\n QueryToolParameters,\n createQueryTool,\n getQuerySummary,\n type QueryToolLlmResult,\n type QueryToolAdditionalData,\n type QueryToolOptions,\n} from './tools/query/queryTool';\nexport {createDefaultAiTools} from './tools/defaultTools';\nexport type {DefaultToolsOptions} from './tools/defaultTools';\nexport {\n createDefaultAiInstructions,\n formatTablesForLLM,\n} from './tools/defaultInstructions';\n\n// From @sqlrooms/ai-core - State/Logic\nexport {createAiSlice, useStoreWithAi} from '@sqlrooms/ai-core';\nexport type {AiSliceState} from '@sqlrooms/ai-core';\nexport {useScrollToBottom} from '@sqlrooms/ai-core';\nexport {AiThinkingDots} from '@sqlrooms/ai-core';\nexport {cleanupPendingAnalysisResults, ToolAbortError} from '@sqlrooms/ai-core';\nexport {convertToAiSDKTools, fixIncompleteToolCalls} from '@sqlrooms/ai-core';\nexport {processAgentStream, updateAgentToolCallData} from '@sqlrooms/ai-core';\nexport type {\n AgentStreamResult,\n UIMessageChunk,\n AgentToolCall,\n AgentToolCallAdditionalData,\n} from '@sqlrooms/ai-core';\n\n// From @sqlrooms/ai-core - Components\n// @deprecated Use `Chat.Messages` instead.\nexport {AnalysisResultsContainer} from '@sqlrooms/ai-core';\nexport {AnalysisResult} from '@sqlrooms/ai-core';\nexport {ErrorMessage} from '@sqlrooms/ai-core';\nexport type {ErrorMessageComponentProps} from '@sqlrooms/ai-core';\nexport {PromptSuggestions} from '@sqlrooms/ai-core';\nexport {ModelSelector} from '@sqlrooms/ai-core';\nexport {SessionControls} from '@sqlrooms/ai-core';\nexport {QueryControls} from '@sqlrooms/ai-core';\nexport {DeleteSessionDialog} from '@sqlrooms/ai-core';\nexport {SessionActions} from '@sqlrooms/ai-core';\nexport {SessionDropdown} from '@sqlrooms/ai-core';\nexport {SessionTitle} from '@sqlrooms/ai-core';\nexport type {SessionType} from '@sqlrooms/ai-core';\nexport {ToolErrorMessage} from '@sqlrooms/ai-core';\nexport {ToolCallInfo} from '@sqlrooms/ai-core';\nexport {ReasoningBox} from '@sqlrooms/ai-core';\nexport {Chat} from '@sqlrooms/ai-core';\n\n// From @sqlrooms/ai-config\nexport {\n AiSliceConfig,\n createDefaultAiConfig,\n AiSettingsSliceConfig,\n AnalysisSessionSchema,\n AnalysisResultSchema,\n ErrorMessageSchema,\n} from '@sqlrooms/ai-config';\nexport type {ToolUIPart, UIMessagePart} from '@sqlrooms/ai-config';\n\n// From @sqlrooms/ai-settings - State/Logic\nexport {\n createAiSettingsSlice,\n useStoreWithAiSettings,\n} from '@sqlrooms/ai-settings';\nexport type {AiSettingsSliceState} from '@sqlrooms/ai-settings';\nexport {createDefaultAiSettingsConfig} from '@sqlrooms/ai-settings';\n\n// From @sqlrooms/ai-settings - Components\nexport {AiSettingsPanel} from '@sqlrooms/ai-settings';\nexport {AiProvidersSettings} from '@sqlrooms/ai-settings';\nexport {AiModelsSettings} from '@sqlrooms/ai-settings';\nexport {AiModelParameters} from '@sqlrooms/ai-settings';\nexport {AiModelUsage} from '@sqlrooms/ai-settings';\nexport type {ModelUsageData} from '@sqlrooms/ai-settings';\n"]}
@@ -4,9 +4,10 @@ import { StoreApi } from '@sqlrooms/room-shell';
4
4
  /**
5
5
  * Formats table schema information in a clean, LLM-friendly format
6
6
  * @param tables Array of DataTable objects from the DuckDB state
7
+ * @param currentDatabase The current local database name to filter by
7
8
  * @returns Formatted string representation of table schemas
8
9
  */
9
- export declare function formatTablesForLLM(tables: DataTable[]): string;
10
+ export declare function formatTablesForLLM(tables: DataTable[], currentDatabase?: string): string;
10
11
  /**
11
12
  * Returns the default system instructions for the AI assistant
12
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"defaultInstructions.d.ts","sourceRoot":"","sources":["../../src/tools/defaultInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,gBAAgB,EAAE,SAAS,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAmC9D;AA4DD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,GAC/C,MAAM,CAGR"}
1
+ {"version":3,"file":"defaultInstructions.d.ts","sourceRoot":"","sources":["../../src/tools/defaultInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,gBAAgB,EAAE,SAAS,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EAAE,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CAuCR;AA4DD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,GAC/C,MAAM,CAKR"}
@@ -1,16 +1,22 @@
1
1
  /**
2
2
  * Formats table schema information in a clean, LLM-friendly format
3
3
  * @param tables Array of DataTable objects from the DuckDB state
4
+ * @param currentDatabase The current local database name to filter by
4
5
  * @returns Formatted string representation of table schemas
5
6
  */
6
- export function formatTablesForLLM(tables) {
7
+ export function formatTablesForLLM(tables, currentDatabase) {
7
8
  if (!tables || tables.length === 0) {
8
9
  return 'No tables available in the database.';
9
10
  }
10
11
  return tables
11
12
  .filter((table) => {
12
13
  const schemaName = table.table?.schema || table.schema;
13
- return !schemaName || schemaName === 'main';
14
+ const databaseName = table.table?.database || table.database;
15
+ // Only include tables from 'main' schema and the current local database
16
+ // This excludes tables from attached databases (MotherDuck, Iceberg, knowledge base, etc.)
17
+ const isMainSchema = !schemaName || schemaName === 'main';
18
+ const isLocalDatabase = !databaseName || databaseName === currentDatabase;
19
+ return isMainSchema && isLocalDatabase;
14
20
  })
15
21
  .map((table) => {
16
22
  const tableName = table.table?.table || table.tableName;
@@ -20,14 +26,10 @@ export function formatTablesForLLM(tables) {
20
26
  : tableName;
21
27
  // Build table header with metadata
22
28
  const header = [fullTableName];
23
- if (table.isView)
24
- header.push('(view)');
25
29
  if (table.rowCount !== undefined)
26
30
  header.push(`[${table.rowCount.toLocaleString()} rows]`);
27
31
  // Format columns with proper indentation
28
- const columns = table.columns
29
- .map((col) => ` ${col.name}: ${col.type}`)
30
- .join('\n');
32
+ const columns = table.columns.map((col) => ` ${col.name}`).join('\n');
31
33
  // Add comment if available
32
34
  const comment = table.comment ? ` # ${table.comment}` : '';
33
35
  return `${header.join(' ')}\n${columns}${comment ? '\n' + comment : ''}`;
@@ -88,14 +90,16 @@ For your final answer:
88
90
  * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.
89
91
  * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.
90
92
 
91
- Available tables in the database (format: tableName [rowCount] followed by indented columns):
93
+ Available tables in the local databases (format: tableName [rowCount] followed by indented columns):
92
94
 
93
95
  `;
94
96
  /**
95
97
  * Returns the default system instructions for the AI assistant
96
98
  */
97
99
  export function createDefaultAiInstructions(store) {
98
- const tables = store.getState().db.tables;
99
- return `${DEFAULT_INSTRUCTIONS}\n${formatTablesForLLM(tables)}`;
100
+ const dbState = store.getState().db;
101
+ const tables = dbState.tables;
102
+ const currentDatabase = dbState.currentDatabase;
103
+ return `${DEFAULT_INSTRUCTIONS}\n${formatTablesForLLM(tables, currentDatabase)}`;
100
104
  }
101
105
  //# sourceMappingURL=defaultInstructions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultInstructions.js","sourceRoot":"","sources":["../../src/tools/defaultInstructions.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAChB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACvD,OAAO,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,CAAC;IAC9C,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC;QACxD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACvD,MAAM,aAAa,GACjB,UAAU,IAAI,UAAU,KAAK,MAAM;YACjC,CAAC,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE;YAC9B,CAAC,CAAC,SAAS,CAAC;QAEhB,mCAAmC;QACnC,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAE3D,yCAAyC;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;aAC1B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;aAC1C,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,2BAA2B;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5D,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3E,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD5B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAgD;IAEhD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC;IAC1C,OAAO,GAAG,oBAAoB,KAAK,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AAClE,CAAC","sourcesContent":["import {AiSliceState} from '@sqlrooms/ai-core';\nimport {DuckDbSliceState, DataTable} from '@sqlrooms/duckdb';\nimport {StoreApi} from '@sqlrooms/room-shell';\n\n/**\n * Formats table schema information in a clean, LLM-friendly format\n * @param tables Array of DataTable objects from the DuckDB state\n * @returns Formatted string representation of table schemas\n */\nexport function formatTablesForLLM(tables: DataTable[]): string {\n if (!tables || tables.length === 0) {\n return 'No tables available in the database.';\n }\n\n return tables\n .filter((table) => {\n const schemaName = table.table?.schema || table.schema;\n return !schemaName || schemaName === 'main';\n })\n .map((table) => {\n const tableName = table.table?.table || table.tableName;\n const schemaName = table.table?.schema || table.schema;\n const fullTableName =\n schemaName && schemaName !== 'main'\n ? `${schemaName}.${tableName}`\n : tableName;\n\n // Build table header with metadata\n const header = [fullTableName];\n if (table.isView) header.push('(view)');\n if (table.rowCount !== undefined)\n header.push(`[${table.rowCount.toLocaleString()} rows]`);\n\n // Format columns with proper indentation\n const columns = table.columns\n .map((col) => ` ${col.name}: ${col.type}`)\n .join('\\n');\n\n // Add comment if available\n const comment = table.comment ? ` # ${table.comment}` : '';\n\n return `${header.join(' ')}\\n${columns}${comment ? '\\n' + comment : ''}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * System prompt template for the AI assistant that provides instructions for:\n * - Using DuckDB-specific SQL syntax and functions\n * - Handling query results and error cases\n * - Creating visualizations with VegaLite\n * - Formatting final answers\n */\nconst DEFAULT_INSTRUCTIONS = `\nYou are analyzing tables in DuckDB database in the context of a room.\n\nInstructions for analysis:\n- When using 'query' tool, please assign parameter 'type' with value 'query'\n- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)\n- Some key DuckDB-specific functions to use:\n * regexp_matches() for regex (not regexp_like)\n * strftime() for date formatting (not to_char)\n * list_aggregate() for array operations\n * unnest() for array expansion\n * regr_sxy()\n * corr()\n * skewness()\n- Please always try to use SQL queries to answer users questions\n- Please run tool calls sequentially, don't run multiple tool calls in parallel\n- IMPORTANT: Do not list out raw query results in your response. Instead:\n * Describe the results in natural language\n * Provide summary statistics\n * Use comparisons and relative terms\n * Include only the most relevant values if necessary\n- Break down complex problems into smaller steps\n- Use \"SUMMARIZE table_name\"for quick overview of the table\n- Please don't modify data\n- IMPORTANT: When you receive an error response from a tool call (where success: false):\n * Stop making any further tool calls immediately\n * Return a final answer that includes the error message\n * Explain what went wrong and suggest possible fixes if applicable\n\nWhen creating visualizations:\n- Follow VegaLite syntax\n- Choose appropriate chart types based on the data and analysis goals\n- Use clear titles and axis labels\n- Consider color schemes for better readability\n- Add meaningful tooltips when relevant\n- Format numbers and dates appropriately\n- Use aggregations when dealing with large datasets\n\nFor your final answer:\n- Provide an explanation for how you got it\n- Explain your reasoning step by step\n- Include relevant statistics or metrics\n- For each prompt, please always provide the final answer.\n- IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:\n * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.\n * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.\n\nAvailable tables in the database (format: tableName [rowCount] followed by indented columns):\n\n`;\n\n/**\n * Returns the default system instructions for the AI assistant\n */\nexport function createDefaultAiInstructions(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n): string {\n const tables = store.getState().db.tables;\n return `${DEFAULT_INSTRUCTIONS}\\n${formatTablesForLLM(tables)}`;\n}\n"]}
1
+ {"version":3,"file":"defaultInstructions.js","sourceRoot":"","sources":["../../src/tools/defaultInstructions.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAmB,EACnB,eAAwB;IAExB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAChB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACvD,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC;QAE7D,wEAAwE;QACxE,2FAA2F;QAC3F,MAAM,YAAY,GAAG,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,CAAC;QAC1D,MAAM,eAAe,GAAG,CAAC,YAAY,IAAI,YAAY,KAAK,eAAe,CAAC;QAE1E,OAAO,YAAY,IAAI,eAAe,CAAC;IACzC,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC;QACxD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACvD,MAAM,aAAa,GACjB,UAAU,IAAI,UAAU,KAAK,MAAM;YACjC,CAAC,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE;YAC9B,CAAC,CAAC,SAAS,CAAC;QAEhB,mCAAmC;QACnC,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAE3D,yCAAyC;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvE,2BAA2B;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5D,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3E,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD5B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAgD;IAEhD,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAChD,OAAO,GAAG,oBAAoB,KAAK,kBAAkB,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC;AACnF,CAAC","sourcesContent":["import {AiSliceState} from '@sqlrooms/ai-core';\nimport {DuckDbSliceState, DataTable} from '@sqlrooms/duckdb';\nimport {StoreApi} from '@sqlrooms/room-shell';\n\n/**\n * Formats table schema information in a clean, LLM-friendly format\n * @param tables Array of DataTable objects from the DuckDB state\n * @param currentDatabase The current local database name to filter by\n * @returns Formatted string representation of table schemas\n */\nexport function formatTablesForLLM(\n tables: DataTable[],\n currentDatabase?: string,\n): string {\n if (!tables || tables.length === 0) {\n return 'No tables available in the database.';\n }\n\n return tables\n .filter((table) => {\n const schemaName = table.table?.schema || table.schema;\n const databaseName = table.table?.database || table.database;\n\n // Only include tables from 'main' schema and the current local database\n // This excludes tables from attached databases (MotherDuck, Iceberg, knowledge base, etc.)\n const isMainSchema = !schemaName || schemaName === 'main';\n const isLocalDatabase = !databaseName || databaseName === currentDatabase;\n\n return isMainSchema && isLocalDatabase;\n })\n .map((table) => {\n const tableName = table.table?.table || table.tableName;\n const schemaName = table.table?.schema || table.schema;\n const fullTableName =\n schemaName && schemaName !== 'main'\n ? `${schemaName}.${tableName}`\n : tableName;\n\n // Build table header with metadata\n const header = [fullTableName];\n if (table.rowCount !== undefined)\n header.push(`[${table.rowCount.toLocaleString()} rows]`);\n\n // Format columns with proper indentation\n const columns = table.columns.map((col) => ` ${col.name}`).join('\\n');\n\n // Add comment if available\n const comment = table.comment ? ` # ${table.comment}` : '';\n\n return `${header.join(' ')}\\n${columns}${comment ? '\\n' + comment : ''}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * System prompt template for the AI assistant that provides instructions for:\n * - Using DuckDB-specific SQL syntax and functions\n * - Handling query results and error cases\n * - Creating visualizations with VegaLite\n * - Formatting final answers\n */\nconst DEFAULT_INSTRUCTIONS = `\nYou are analyzing tables in DuckDB database in the context of a room.\n\nInstructions for analysis:\n- When using 'query' tool, please assign parameter 'type' with value 'query'\n- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)\n- Some key DuckDB-specific functions to use:\n * regexp_matches() for regex (not regexp_like)\n * strftime() for date formatting (not to_char)\n * list_aggregate() for array operations\n * unnest() for array expansion\n * regr_sxy()\n * corr()\n * skewness()\n- Please always try to use SQL queries to answer users questions\n- Please run tool calls sequentially, don't run multiple tool calls in parallel\n- IMPORTANT: Do not list out raw query results in your response. Instead:\n * Describe the results in natural language\n * Provide summary statistics\n * Use comparisons and relative terms\n * Include only the most relevant values if necessary\n- Break down complex problems into smaller steps\n- Use \"SUMMARIZE table_name\"for quick overview of the table\n- Please don't modify data\n- IMPORTANT: When you receive an error response from a tool call (where success: false):\n * Stop making any further tool calls immediately\n * Return a final answer that includes the error message\n * Explain what went wrong and suggest possible fixes if applicable\n\nWhen creating visualizations:\n- Follow VegaLite syntax\n- Choose appropriate chart types based on the data and analysis goals\n- Use clear titles and axis labels\n- Consider color schemes for better readability\n- Add meaningful tooltips when relevant\n- Format numbers and dates appropriately\n- Use aggregations when dealing with large datasets\n\nFor your final answer:\n- Provide an explanation for how you got it\n- Explain your reasoning step by step\n- Include relevant statistics or metrics\n- For each prompt, please always provide the final answer.\n- IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:\n * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.\n * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.\n\nAvailable tables in the local databases (format: tableName [rowCount] followed by indented columns):\n\n`;\n\n/**\n * Returns the default system instructions for the AI assistant\n */\nexport function createDefaultAiInstructions(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n): string {\n const dbState = store.getState().db;\n const tables = dbState.tables;\n const currentDatabase = dbState.currentDatabase;\n return `${DEFAULT_INSTRUCTIONS}\\n${formatTablesForLLM(tables, currentDatabase)}`;\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { ArrowDataTableValueFormatter } from '@sqlrooms/data-table';
1
2
  import * as arrow from 'apache-arrow';
2
3
  type QueryToolResultProps = {
3
4
  title: string;
@@ -6,6 +7,8 @@ type QueryToolResultProps = {
6
7
  arrowTable?: arrow.Table;
7
8
  /** Whether to show the SQL text in the result */
8
9
  showSql?: boolean;
10
+ /** Optional custom value formatter for binary/geometry data */
11
+ formatValue?: ArrowDataTableValueFormatter;
9
12
  };
10
13
  export declare function QueryToolResult(props: QueryToolResultProps): import("react/jsx-runtime").JSX.Element;
11
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"QueryToolResult.d.ts","sourceRoot":"","sources":["../../../src/tools/query/QueryToolResult.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CA6C1D"}
1
+ {"version":3,"file":"QueryToolResult.d.ts","sourceRoot":"","sources":["../../../src/tools/query/QueryToolResult.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,4BAA4B,EAAC,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACzB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,4BAA4B,CAAC;CAC5C,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CA+C1D"}
@@ -3,8 +3,8 @@ import { DataTableModal } from '@sqlrooms/data-table';
3
3
  import { Button, CopyButton, useDisclosure } from '@sqlrooms/ui';
4
4
  import { TableIcon } from 'lucide-react';
5
5
  export function QueryToolResult(props) {
6
- const { title, sqlQuery, showSql = true } = props;
6
+ const { title, sqlQuery, showSql = true, formatValue } = props;
7
7
  const tableModal = useDisclosure();
8
- return (_jsxs(_Fragment, { children: [showSql && (_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-1 text-gray-500 dark:text-gray-400", children: _jsxs(Button, { variant: "ghost", size: "xs", onClick: tableModal.onOpen, children: [_jsx(TableIcon, { className: "h-4 w-4" }), _jsx("h3", { className: "text-xs", children: "Show Query Result" })] }) }), 'arrowTable' in props ? (props.arrowTable ? (_jsx(DataTableModal, { title: title, arrowTable: props.arrowTable, tableModal: tableModal })) : (_jsx("div", { className: "p-4 text-xs", children: "No data" }))) : (_jsx(DataTableModal, { title: title, query: sqlQuery, tableModal: tableModal }))] }));
8
+ return (_jsxs(_Fragment, { children: [showSql && (_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-1 text-gray-500 dark:text-gray-400", children: _jsxs(Button, { variant: "ghost", size: "xs", onClick: tableModal.onOpen, children: [_jsx(TableIcon, { className: "h-4 w-4" }), _jsx("h3", { className: "text-xs", children: "Show Query Result" })] }) }), 'arrowTable' in props ? (props.arrowTable ? (_jsx(DataTableModal, { title: title, arrowTable: props.arrowTable, tableModal: tableModal, formatValue: formatValue })) : (_jsx("div", { className: "p-4 text-xs", children: "No data" }))) : (_jsx(DataTableModal, { title: title, query: sqlQuery, tableModal: tableModal, formatValue: formatValue }))] }));
9
9
  }
10
10
  //# sourceMappingURL=QueryToolResult.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryToolResult.js","sourceRoot":"","sources":["../../../src/tools/query/QueryToolResult.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAWvC,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAC,GAAG,KAAK,CAAC;IAChD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO,CACL,8BACG,OAAO,IAAI,CACV,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,CACP,EACD,cAAK,SAAS,EAAC,0DAA0D,YACvE,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,SAAS,kCAAuB,IACvC,GACL,EAEL,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,CACvB,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CACjB,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,KAAK,CAAC,UAAU,EAC5B,UAAU,EAAE,UAAU,GACtB,CACH,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,aAAa,wBAAc,CAC3C,CACF,CAAC,CAAC,CAAC,CACF,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,QAAQ,EACf,UAAU,EAAE,UAAU,GACtB,CACH,IACA,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import {DataTableModal} from '@sqlrooms/data-table';\nimport {Button, CopyButton, useDisclosure} from '@sqlrooms/ui';\nimport * as arrow from 'apache-arrow';\nimport {TableIcon} from 'lucide-react';\n\ntype QueryToolResultProps = {\n title: string;\n sqlQuery: string;\n /** Provided in case the query result is already an arrow table */\n arrowTable?: arrow.Table;\n /** Whether to show the SQL text in the result */\n showSql?: boolean;\n};\n\nexport function QueryToolResult(props: QueryToolResultProps) {\n const {title, sqlQuery, showSql = true} = props;\n const tableModal = useDisclosure();\n return (\n <>\n {showSql && (\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 )}\n <div className=\"flex items-center gap-1 text-gray-500 dark:text-gray-400\">\n <Button variant=\"ghost\" size=\"xs\" onClick={tableModal.onOpen}>\n <TableIcon className=\"h-4 w-4\" />\n <h3 className=\"text-xs\">Show Query Result</h3>\n </Button>\n </div>\n\n {'arrowTable' in props ? (\n props.arrowTable ? (\n <DataTableModal\n title={title}\n arrowTable={props.arrowTable}\n tableModal={tableModal}\n />\n ) : (\n <div className=\"p-4 text-xs\">No data</div>\n )\n ) : (\n <DataTableModal\n title={title}\n query={sqlQuery}\n tableModal={tableModal}\n />\n )}\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"QueryToolResult.js","sourceRoot":"","sources":["../../../src/tools/query/QueryToolResult.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAA+B,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAavC,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,WAAW,EAAC,GAAG,KAAK,CAAC;IAC7D,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO,CACL,8BACG,OAAO,IAAI,CACV,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,CACP,EACD,cAAK,SAAS,EAAC,0DAA0D,YACvE,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,SAAS,kCAAuB,IACvC,GACL,EAEL,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,CACvB,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CACjB,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,KAAK,CAAC,UAAU,EAC5B,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,GACxB,CACH,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,aAAa,wBAAc,CAC3C,CACF,CAAC,CAAC,CAAC,CACF,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,QAAQ,EACf,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,GACxB,CACH,IACA,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import {DataTableModal, ArrowDataTableValueFormatter} from '@sqlrooms/data-table';\nimport {Button, CopyButton, useDisclosure} from '@sqlrooms/ui';\nimport * as arrow from 'apache-arrow';\nimport {TableIcon} from 'lucide-react';\n\ntype QueryToolResultProps = {\n title: string;\n sqlQuery: string;\n /** Provided in case the query result is already an arrow table */\n arrowTable?: arrow.Table;\n /** Whether to show the SQL text in the result */\n showSql?: boolean;\n /** Optional custom value formatter for binary/geometry data */\n formatValue?: ArrowDataTableValueFormatter;\n};\n\nexport function QueryToolResult(props: QueryToolResultProps) {\n const {title, sqlQuery, showSql = true, formatValue} = props;\n const tableModal = useDisclosure();\n return (\n <>\n {showSql && (\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 )}\n <div className=\"flex items-center gap-1 text-gray-500 dark:text-gray-400\">\n <Button variant=\"ghost\" size=\"xs\" onClick={tableModal.onOpen}>\n <TableIcon className=\"h-4 w-4\" />\n <h3 className=\"text-xs\">Show Query Result</h3>\n </Button>\n </div>\n\n {'arrowTable' in props ? (\n props.arrowTable ? (\n <DataTableModal\n title={title}\n arrowTable={props.arrowTable}\n tableModal={tableModal}\n formatValue={formatValue}\n />\n ) : (\n <div className=\"p-4 text-xs\">No data</div>\n )\n ) : (\n <DataTableModal\n title={title}\n query={sqlQuery}\n tableModal={tableModal}\n formatValue={formatValue}\n />\n )}\n </>\n );\n}\n"]}
@@ -70,5 +70,5 @@ export declare function createQueryTool(store: StoreApi<AiSliceState & DuckDbSli
70
70
  * @param sqlQuery - SQL SELECT query to analyze
71
71
  * @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails
72
72
  */
73
- export declare function getQuerySummary(connector: DuckDbConnector, sqlQuery: string): Promise<Record<string, unknown>[] | null>;
73
+ export declare function getQuerySummary(connector: DuckDbConnector, sqlQuery: string, abortSignal?: AbortSignal): Promise<Record<string, unknown>[] | null>;
74
74
  //# sourceMappingURL=queryTool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryTool.d.ts","sourceRoot":"","sources":["../../../src/tools/query/queryTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAEL,eAAe,EACf,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAElD,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,OAAO,CAAC;QACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC;QAC1C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;KACvC,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,EAChD,OAAO,CAAC,EAAE,gBAAgB;;;;;;;;sBAcd,mBAAmB,YACjB;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAwG1C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,MAAM,6CAejB"}
1
+ {"version":3,"file":"queryTool.d.ts","sourceRoot":"","sources":["../../../src/tools/query/queryTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAEL,eAAe,EACf,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAElD,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,OAAO,CAAC;QACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC;QAC1C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;KACvC,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,YAAY,GAAG,gBAAgB,CAAC,EAChD,OAAO,CAAC,EAAE,gBAAgB;;;;;;;;sBAcd,mBAAmB,YACjB;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAsF1C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,WAAW,6CAkB1B"}
@@ -18,10 +18,6 @@ If a query fails, please don't try to run it again with the same syntax.`,
18
18
  const { type, sqlQuery } = params;
19
19
  const abortSignal = options?.abortSignal;
20
20
  try {
21
- // Check if aborted before starting
22
- if (abortSignal?.aborted) {
23
- throw new Error('Query execution was aborted');
24
- }
25
21
  const connector = await store.getState().db.getConnector();
26
22
  const parsedQuery = await store.getState().db.sqlSelectToJson(sqlQuery);
27
23
  if (parsedQuery.error &&
@@ -39,23 +35,12 @@ If a query fails, please don't try to run it again with the same syntax.`,
39
35
  throw new Error('Query is not a valid SELECT statement');
40
36
  }
41
37
  }
42
- // Check if aborted before running query
43
- if (abortSignal?.aborted) {
44
- throw new Error('Query execution was aborted');
45
- }
46
- const result = await connector.query(sqlQuery);
47
- // Check if aborted after query execution
48
- if (abortSignal?.aborted) {
49
- throw new Error('Query execution was aborted');
50
- }
38
+ const result = await connector.query(sqlQuery, { signal: abortSignal });
51
39
  const summaryData = await (async () => {
52
40
  if (!autoSummary)
53
41
  return null;
54
42
  if (parsedQuery.error)
55
43
  return null;
56
- // Check if aborted before generating summary
57
- if (abortSignal?.aborted)
58
- return null;
59
44
  const lastNode = parsedQuery.statements[parsedQuery.statements.length - 1]?.node;
60
45
  // Only get summary if the last statement isn't already a SUMMARIZE query
61
46
  if (lastNode?.type === 'SELECT_NODE' &&
@@ -66,7 +51,7 @@ If a query fails, please don't try to run it again with the same syntax.`,
66
51
  const lastStatement = statements[statements.length - 1];
67
52
  if (!lastStatement)
68
53
  return null;
69
- return await getQuerySummary(connector, lastStatement);
54
+ return await getQuerySummary(connector, lastStatement, abortSignal);
70
55
  })();
71
56
  // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM
72
57
  const firstRows = numberOfRowsToShareWithLLM > 0
@@ -106,14 +91,14 @@ If a query fails, please don't try to run it again with the same syntax.`,
106
91
  * @param sqlQuery - SQL SELECT query to analyze
107
92
  * @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails
108
93
  */
109
- export async function getQuerySummary(connector, sqlQuery) {
94
+ export async function getQuerySummary(connector, sqlQuery, abortSignal) {
110
95
  if (!sqlQuery.toLowerCase().trim().startsWith('select')) {
111
96
  return null;
112
97
  }
113
98
  try {
114
99
  const summaryResult = await connector.query(`SUMMARIZE (
115
100
  ${sqlQuery}
116
- )`);
101
+ )`, { signal: abortSignal });
117
102
  return arrowTableToJson(summaryResult);
118
103
  }
119
104
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"queryTool.js","sourceRoot":"","sources":["../../../src/tools/query/queryTool.ts"],"names":[],"mappings":"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","sourcesContent":["import {AiSliceState} from '@sqlrooms/ai-core';\nimport {\n arrowTableToJson,\n DuckDbConnector,\n DuckDbSliceState,\n splitSqlStatements,\n} from '@sqlrooms/duckdb';\nimport type {StoreApi} from '@sqlrooms/room-shell';\nimport {z} from 'zod';\nimport {QueryToolResult} from './QueryToolResult';\n\nexport const QueryToolParameters = z.object({\n type: z.literal('query'),\n sqlQuery: z.string(),\n reasoning: z.string(),\n});\n\nexport type QueryToolParameters = z.infer<typeof QueryToolParameters>;\n\nexport type QueryToolLlmResult = {\n success: boolean;\n data?: {\n type: 'query';\n summary: Record<string, unknown>[] | null;\n firstRows?: Record<string, unknown>[];\n };\n details?: string;\n errorMessage?: string;\n};\n\nexport type QueryToolAdditionalData = {\n title: string;\n sqlQuery: string;\n};\n\nexport type QueryToolOptions = {\n readOnly?: boolean;\n autoSummary?: boolean;\n numberOfRowsToShareWithLLM?: number;\n};\n\nexport function createQueryTool(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n options?: QueryToolOptions,\n) {\n const {\n readOnly = true,\n autoSummary = false,\n numberOfRowsToShareWithLLM = 0,\n } = options || {};\n return {\n name: 'query',\n description: `A tool for running SQL queries on the tables in the database.\nPlease only run one query at a time.\nIf a query fails, please don't try to run it again with the same syntax.`,\n parameters: QueryToolParameters,\n execute: async (\n params: QueryToolParameters,\n options?: {abortSignal?: AbortSignal},\n ) => {\n const {type, sqlQuery} = params;\n const abortSignal = options?.abortSignal;\n\n try {\n // Check if aborted before starting\n if (abortSignal?.aborted) {\n throw new Error('Query execution was aborted');\n }\n\n const connector = await store.getState().db.getConnector();\n const parsedQuery = await store.getState().db.sqlSelectToJson(sqlQuery);\n\n if (\n parsedQuery.error &&\n // Only SELECT statements can be serialized to json, so we ignore not implemented errors\n parsedQuery.error_type !== 'not implemented'\n ) {\n throw new Error(parsedQuery.error_message);\n }\n\n if (readOnly) {\n if (parsedQuery.error) {\n throw new Error(\n `Query is not a valid SELECT statement: ${parsedQuery.error_message}`,\n );\n }\n if (\n parsedQuery.statements.length !== 1 || // only one statement allowed\n parsedQuery.statements[0]?.node.type !== 'SELECT_NODE' // only SELECT statements allowed\n ) {\n throw new Error('Query is not a valid SELECT statement');\n }\n }\n\n // Check if aborted before running query\n if (abortSignal?.aborted) {\n throw new Error('Query execution was aborted');\n }\n\n const result = await connector.query(sqlQuery);\n\n // Check if aborted after query execution\n if (abortSignal?.aborted) {\n throw new Error('Query execution was aborted');\n }\n\n const summaryData = await (async () => {\n if (!autoSummary) return null;\n if (parsedQuery.error) return null;\n\n // Check if aborted before generating summary\n if (abortSignal?.aborted) return null;\n\n const lastNode =\n parsedQuery.statements[parsedQuery.statements.length - 1]?.node;\n\n // Only get summary if the last statement isn't already a SUMMARIZE query\n if (\n lastNode?.type === 'SELECT_NODE' &&\n lastNode?.from_table?.show_type === 'SUMMARY'\n ) {\n return arrowTableToJson(result);\n }\n const statements = splitSqlStatements(sqlQuery);\n const lastStatement = statements[statements.length - 1];\n if (!lastStatement) return null;\n return await getQuerySummary(connector, lastStatement);\n })();\n\n // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM\n const firstRows =\n numberOfRowsToShareWithLLM > 0\n ? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))\n : [];\n\n return {\n llmResult: {\n success: true,\n data: {\n type,\n summary: summaryData,\n ...(numberOfRowsToShareWithLLM > 0 ? {firstRows} : {}),\n },\n },\n additionalData: {\n title: 'Query Result',\n sqlQuery,\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n details: 'Query execution failed.',\n errorMessage:\n error instanceof Error ? error.message : 'Unknown error',\n },\n };\n }\n },\n component: QueryToolResult,\n };\n}\n\n/**\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 */\nexport async function getQuerySummary(\n connector: DuckDbConnector,\n sqlQuery: string,\n) {\n if (!sqlQuery.toLowerCase().trim().startsWith('select')) {\n return null;\n }\n\n try {\n const summaryResult = await connector.query(`SUMMARIZE (\n ${sqlQuery}\n )`);\n return arrowTableToJson(summaryResult);\n } catch (error) {\n console.warn('Failed to get summary for query. Error:', error);\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"queryTool.js","sourceRoot":"","sources":["../../../src/tools/query/queryTool.ts"],"names":[],"mappings":"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","sourcesContent":["import {AiSliceState} from '@sqlrooms/ai-core';\nimport {\n arrowTableToJson,\n DuckDbConnector,\n DuckDbSliceState,\n splitSqlStatements,\n} from '@sqlrooms/duckdb';\nimport type {StoreApi} from '@sqlrooms/room-shell';\nimport {z} from 'zod';\nimport {QueryToolResult} from './QueryToolResult';\n\nexport const QueryToolParameters = z.object({\n type: z.literal('query'),\n sqlQuery: z.string(),\n reasoning: z.string(),\n});\n\nexport type QueryToolParameters = z.infer<typeof QueryToolParameters>;\n\nexport type QueryToolLlmResult = {\n success: boolean;\n data?: {\n type: 'query';\n summary: Record<string, unknown>[] | null;\n firstRows?: Record<string, unknown>[];\n };\n details?: string;\n errorMessage?: string;\n};\n\nexport type QueryToolAdditionalData = {\n title: string;\n sqlQuery: string;\n};\n\nexport type QueryToolOptions = {\n readOnly?: boolean;\n autoSummary?: boolean;\n numberOfRowsToShareWithLLM?: number;\n};\n\nexport function createQueryTool(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n options?: QueryToolOptions,\n) {\n const {\n readOnly = true,\n autoSummary = false,\n numberOfRowsToShareWithLLM = 0,\n } = options || {};\n return {\n name: 'query',\n description: `A tool for running SQL queries on the tables in the database.\nPlease only run one query at a time.\nIf a query fails, please don't try to run it again with the same syntax.`,\n parameters: QueryToolParameters,\n execute: async (\n params: QueryToolParameters,\n options?: {abortSignal?: AbortSignal},\n ) => {\n const {type, sqlQuery} = params;\n const abortSignal = options?.abortSignal;\n\n try {\n const connector = await store.getState().db.getConnector();\n const parsedQuery = await store.getState().db.sqlSelectToJson(sqlQuery);\n\n if (\n parsedQuery.error &&\n // Only SELECT statements can be serialized to json, so we ignore not implemented errors\n parsedQuery.error_type !== 'not implemented'\n ) {\n throw new Error(parsedQuery.error_message);\n }\n\n if (readOnly) {\n if (parsedQuery.error) {\n throw new Error(\n `Query is not a valid SELECT statement: ${parsedQuery.error_message}`,\n );\n }\n if (\n parsedQuery.statements.length !== 1 || // only one statement allowed\n parsedQuery.statements[0]?.node.type !== 'SELECT_NODE' // only SELECT statements allowed\n ) {\n throw new Error('Query is not a valid SELECT statement');\n }\n }\n\n const result = await connector.query(sqlQuery, {signal: abortSignal});\n\n const summaryData = await (async () => {\n if (!autoSummary) return null;\n if (parsedQuery.error) return null;\n\n const lastNode =\n parsedQuery.statements[parsedQuery.statements.length - 1]?.node;\n\n // Only get summary if the last statement isn't already a SUMMARIZE query\n if (\n lastNode?.type === 'SELECT_NODE' &&\n lastNode?.from_table?.show_type === 'SUMMARY'\n ) {\n return arrowTableToJson(result);\n }\n const statements = splitSqlStatements(sqlQuery);\n const lastStatement = statements[statements.length - 1];\n if (!lastStatement) return null;\n return await getQuerySummary(connector, lastStatement, abortSignal);\n })();\n\n // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM\n const firstRows =\n numberOfRowsToShareWithLLM > 0\n ? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))\n : [];\n\n return {\n llmResult: {\n success: true,\n data: {\n type,\n summary: summaryData,\n ...(numberOfRowsToShareWithLLM > 0 ? {firstRows} : {}),\n },\n },\n additionalData: {\n title: 'Query Result',\n sqlQuery,\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n details: 'Query execution failed.',\n errorMessage:\n error instanceof Error ? error.message : 'Unknown error',\n },\n };\n }\n },\n component: QueryToolResult,\n };\n}\n\n/**\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 */\nexport async function getQuerySummary(\n connector: DuckDbConnector,\n sqlQuery: string,\n abortSignal?: AbortSignal,\n) {\n if (!sqlQuery.toLowerCase().trim().startsWith('select')) {\n return null;\n }\n\n try {\n const summaryResult = await connector.query(\n `SUMMARIZE (\n ${sqlQuery}\n )`,\n {signal: abortSignal},\n );\n return arrowTableToJson(summaryResult);\n } catch (error) {\n console.warn('Failed to get summary for query. Error:', error);\n return null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sqlrooms/ai",
3
- "version": "0.26.1-rc.7",
3
+ "version": "0.27.0-rc.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/index.js",
7
7
  "type": "module",
8
8
  "sideEffects": false,
9
- "author": "Ilya Boyandin <ilya@boyandin.me>",
9
+ "author": "SQLRooms Contributors",
10
10
  "license": "MIT",
11
11
  "repository": {
12
12
  "type": "git",
@@ -20,21 +20,14 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@openassistant/utils": "1.0.0-alpha.0",
23
- "@sqlrooms/ai-config": "0.26.1-rc.7",
24
- "@sqlrooms/ai-core": "0.26.1-rc.7",
25
- "@sqlrooms/ai-settings": "0.26.1-rc.7",
26
- "@sqlrooms/data-table": "0.26.1-rc.7",
27
- "@sqlrooms/duckdb": "0.26.1-rc.7",
28
- "@sqlrooms/room-shell": "0.26.1-rc.7",
29
- "@sqlrooms/ui": "0.26.1-rc.7",
30
- "@sqlrooms/utils": "0.26.1-rc.7",
31
- "ai": "^5.0.44",
32
- "immer": "^11.0.1",
33
- "lucide-react": "^0.555.0",
34
- "react-markdown": "^10.1.0",
35
- "recharts": "^2.12.7",
36
- "rehype-raw": "^7.0.0",
37
- "remark-gfm": "^4.0.0",
23
+ "@sqlrooms/ai-config": "0.27.0-rc.1",
24
+ "@sqlrooms/ai-core": "0.27.0-rc.1",
25
+ "@sqlrooms/ai-settings": "0.27.0-rc.1",
26
+ "@sqlrooms/data-table": "0.27.0-rc.1",
27
+ "@sqlrooms/duckdb": "0.27.0-rc.1",
28
+ "@sqlrooms/room-shell": "0.27.0-rc.1",
29
+ "@sqlrooms/ui": "0.27.0-rc.1",
30
+ "lucide-react": "^0.556.0",
38
31
  "zod": "^4.1.8"
39
32
  },
40
33
  "peerDependencies": {
@@ -49,5 +42,5 @@
49
42
  "typecheck": "tsc --noEmit",
50
43
  "typedoc": "typedoc"
51
44
  },
52
- "gitHead": "ca84c57cb88c90be981083ee366f83bc805ba899"
45
+ "gitHead": "392da9702a049dc3d57fa467bbbf52bf2db7ffd1"
53
46
  }