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