@sqlrooms/ai 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AiSlice.d.ts +4 -9
- package/dist/AiSlice.d.ts.map +1 -1
- package/dist/AiSlice.js +10 -23
- package/dist/AnalysisResultsContainer.js +1 -1
- package/dist/QueryControls.d.ts.map +1 -1
- package/dist/QueryControls.js +7 -16
- package/dist/analysis.d.ts +0 -1
- package/dist/analysis.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/AiSlice.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProjectState } from '@sqlrooms/project-builder';
|
|
1
|
+
import { ProjectState, type StateCreator } from '@sqlrooms/project-builder';
|
|
2
2
|
import { BaseProjectConfig } from '@sqlrooms/project-config';
|
|
3
3
|
import { CoreAssistantMessage, CoreToolMessage, CoreUserMessage, LanguageModelV1 } from 'ai';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -340,14 +340,10 @@ export type AiSliceConfig = z.infer<typeof AiSliceConfig>;
|
|
|
340
340
|
export declare function createDefaultAiConfig(): AiSliceConfig;
|
|
341
341
|
export type AiSliceState = {
|
|
342
342
|
ai: {
|
|
343
|
-
supportedModels: string[];
|
|
344
343
|
analysisPrompt: string;
|
|
345
344
|
isRunningAnalysis: boolean;
|
|
346
345
|
analysisAbortController?: AbortController;
|
|
347
|
-
apiKey: string | null;
|
|
348
|
-
setAiModel: (model: string) => void;
|
|
349
346
|
setAnalysisPrompt: (prompt: string) => void;
|
|
350
|
-
setApiKey: (key: string) => void;
|
|
351
347
|
startAnalysis: () => Promise<void>;
|
|
352
348
|
cancelAnalysis: () => void;
|
|
353
349
|
messagesById: Map<string, AiMessage>;
|
|
@@ -355,10 +351,9 @@ export type AiSliceState = {
|
|
|
355
351
|
getMessages: () => AiMessage[];
|
|
356
352
|
};
|
|
357
353
|
};
|
|
358
|
-
export declare function createAiSlice<PC extends BaseProjectConfig & AiSliceConfig>({
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}): import("zustand").StateCreator<AiSliceState>;
|
|
354
|
+
export declare function createAiSlice<PC extends BaseProjectConfig & AiSliceConfig>({ createModel, }: {
|
|
355
|
+
createModel: (model: string) => LanguageModelV1;
|
|
356
|
+
}): StateCreator<AiSliceState>;
|
|
362
357
|
type ProjectConfigWithAi = BaseProjectConfig & AiSliceConfig;
|
|
363
358
|
type ProjectStateWithAi = ProjectState<ProjectConfigWithAi> & AiSliceState;
|
|
364
359
|
export declare function useStoreWithAi<T>(selector: (state: ProjectStateWithAi) => 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,EAEL,YAAY,
|
|
1
|
+
{"version":3,"file":"AiSlice.d.ts","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,YAAY,EAEZ,KAAK,YAAY,EAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,eAAe,EAChB,MAAM,IAAI,CAAC;AAEZ,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAQtB,KAAK,SAAS,GAAG,CAAC,eAAe,GAAG,oBAAoB,GAAG,eAAe,CAAC,GAAG;IAC5E,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,wBAAgB,qBAAqB,IAAI,aAAa,CAOrD;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE;QACF,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,uBAAuB,CAAC,EAAE,eAAe,CAAC;QAC1C,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5C,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,cAAc,EAAE,MAAM,IAAI,CAAC;QAC3B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACrC,WAAW,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;QAC7C,WAAW,EAAE,MAAM,SAAS,EAAE,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,SAAS,iBAAiB,GAAG,aAAa,EAAE,EAC1E,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,eAAe,CAAC;CACjD,GAAG,YAAY,CAAC,YAAY,CAAC,CAwJ7B;AAsCD,KAAK,mBAAmB,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAC7D,KAAK,kBAAkB,GAAG,YAAY,CAAC,mBAAmB,CAAC,GAAG,YAAY,CAAC;AAE3E,wBAAgB,cAAc,CAAC,CAAC,EAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,CAAC,GACzC,CAAC,CAMH"}
|
package/dist/AiSlice.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createId } from '@paralleldrive/cuid2';
|
|
2
|
-
import {
|
|
2
|
+
import { createSlice, useBaseProjectStore, } from '@sqlrooms/project-builder';
|
|
3
3
|
import { produce } from 'immer';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { runAnalysis } from './analysis';
|
|
@@ -18,29 +18,22 @@ export function createDefaultAiConfig() {
|
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
export function createAiSlice({
|
|
22
|
-
return
|
|
21
|
+
export function createAiSlice({ createModel, }) {
|
|
22
|
+
return createSlice((set, get) => ({
|
|
23
23
|
ai: {
|
|
24
|
-
supportedModels,
|
|
25
24
|
analysisPrompt: 'Describe the data in the table and make a chart providing an overview.',
|
|
26
25
|
isRunningAnalysis: false,
|
|
27
26
|
messagesById: new Map(),
|
|
28
|
-
apiKey:
|
|
29
|
-
? localStorage.getItem('ai_api_key')
|
|
30
|
-
: null,
|
|
31
|
-
setApiKey: (key) => {
|
|
32
|
-
localStorage.setItem('ai_api_key', key);
|
|
33
|
-
set((state) => produce(state, (draft) => {
|
|
34
|
-
draft.ai.apiKey = key;
|
|
35
|
-
}));
|
|
36
|
-
},
|
|
27
|
+
apiKey: null,
|
|
37
28
|
setAnalysisPrompt: (prompt) => {
|
|
38
29
|
set((state) => produce(state, (draft) => {
|
|
39
30
|
draft.ai.analysisPrompt = prompt;
|
|
40
31
|
}));
|
|
41
32
|
},
|
|
42
33
|
setAiModel: (model) => {
|
|
43
|
-
set(
|
|
34
|
+
set((state) => produce(state, (draft) => {
|
|
35
|
+
draft.project.config.ai.model = model;
|
|
36
|
+
}));
|
|
44
37
|
},
|
|
45
38
|
/**
|
|
46
39
|
* Add messages to the project store uniquely by id
|
|
@@ -71,15 +64,10 @@ export function createAiSlice({ supportedModels, createModel, }) {
|
|
|
71
64
|
startAnalysis: async () => {
|
|
72
65
|
const resultId = createId();
|
|
73
66
|
const abortController = new AbortController();
|
|
74
|
-
const { apiKey } = get().ai;
|
|
75
|
-
const model = get().projectConfig.ai.model;
|
|
76
|
-
if (!apiKey) {
|
|
77
|
-
throw new Error('OpenAI API key is required');
|
|
78
|
-
}
|
|
79
67
|
set((state) => produce(state, (draft) => {
|
|
80
68
|
draft.ai.analysisAbortController = abortController;
|
|
81
69
|
draft.ai.isRunningAnalysis = true;
|
|
82
|
-
draft.
|
|
70
|
+
draft.project.config.ai.analysisResults.push({
|
|
83
71
|
id: resultId,
|
|
84
72
|
prompt: get().ai.analysisPrompt,
|
|
85
73
|
toolResults: [],
|
|
@@ -98,7 +86,7 @@ export function createAiSlice({ supportedModels, createModel, }) {
|
|
|
98
86
|
}));
|
|
99
87
|
try {
|
|
100
88
|
const { toolResults, toolCalls, ...rest } = await runAnalysis({
|
|
101
|
-
model: createModel(model
|
|
89
|
+
model: createModel(get().project.config.ai.model),
|
|
102
90
|
// prompt: get().analysisPrompt,
|
|
103
91
|
messages: get().ai.getMessages(),
|
|
104
92
|
onStepFinish: (event) => {
|
|
@@ -111,7 +99,6 @@ export function createAiSlice({ supportedModels, createModel, }) {
|
|
|
111
99
|
}));
|
|
112
100
|
},
|
|
113
101
|
abortSignal: abortController.signal,
|
|
114
|
-
apiKey,
|
|
115
102
|
});
|
|
116
103
|
console.log('final result', { toolResults, toolCalls, ...rest });
|
|
117
104
|
get().ai.addMessages([
|
|
@@ -176,7 +163,7 @@ function findResultById(analysisResults, id) {
|
|
|
176
163
|
*/
|
|
177
164
|
function makeResultsAppender({ resultId, toolResults, toolCalls, }) {
|
|
178
165
|
return (state) => produce(state, (draft) => {
|
|
179
|
-
const result = findResultById(draft.
|
|
166
|
+
const result = findResultById(draft.project.config.ai.analysisResults, resultId);
|
|
180
167
|
if (result) {
|
|
181
168
|
result.toolResults = [...result.toolResults, ...toolResults];
|
|
182
169
|
result.toolCalls = [...result.toolCalls, ...toolCalls];
|
|
@@ -7,7 +7,7 @@ import { AnalysisResult } from './AnalysisResult';
|
|
|
7
7
|
import { useScrollToBottom, useScrollToBottomButton, } from './hooks/use-scroll-to-bottom';
|
|
8
8
|
export const AnalysisResultsContainer = () => {
|
|
9
9
|
const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);
|
|
10
|
-
const analysisResults = useStoreWithAi((s) => s.
|
|
10
|
+
const analysisResults = useStoreWithAi((s) => s.project.config.ai.analysisResults);
|
|
11
11
|
const [messagesContainerRef, messagesEndRef] = useScrollToBottom();
|
|
12
12
|
const { showButton, scrollToBottom } = useScrollToBottomButton(messagesContainerRef);
|
|
13
13
|
return (_jsxs("div", { className: "flex relative h-full w-full overflow-hidden", children: [_jsxs("div", { className: "flex flex-grow flex-col w-full gap-4 p-4 overflow-auto", ref: messagesContainerRef, children: [_jsxs("div", { className: "flex flex-col gap-10 ", children: [analysisResults.map((result) => (_jsx(AnalysisResult, { result: result }, result.id))), _jsx("div", { className: "h-20" }), messagesEndRef && (_jsx("div", { ref: messagesEndRef, className: "shrink-0 min-w-[24px] min-h-[24px]" }))] }), isRunningAnalysis && _jsx(SkeletonPane, { className: "p-4" })] }), _jsx("div", { className: "absolute inset-x-0 bottom-0 pointer-events-none flex justify-center", children: _jsx("button", { onClick: scrollToBottom, className: cn('pointer-events-auto bg-primary hover:bg-primary/90 text-primary-foreground z-50', 'rounded-full p-2 shadow-md transition-all duration-200 opacity-0 translate-y-4 mb-6', showButton && 'opacity-100 translate-y-0'), "aria-label": "Scroll to bottom", children: _jsx(ChevronDown, { className: "w-5 h-5" }) }) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../src/QueryControls.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueryControls.d.ts","sourceRoot":"","sources":["../src/QueryControls.tsx"],"names":[],"mappings":"AAKA,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsEtD,CAAC"}
|
package/dist/QueryControls.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, cn,
|
|
3
|
-
import {
|
|
2
|
+
import { Button, cn, Spinner, Textarea } from '@sqlrooms/ui';
|
|
3
|
+
import { OctagonXIcon } from 'lucide-react';
|
|
4
4
|
import { useCallback } from 'react';
|
|
5
5
|
import { useStoreWithAi } from './AiSlice';
|
|
6
6
|
export const QueryControls = ({ className }) => {
|
|
@@ -9,11 +9,7 @@ export const QueryControls = ({ className }) => {
|
|
|
9
9
|
const cancelAnalysis = useStoreWithAi((s) => s.ai.cancelAnalysis);
|
|
10
10
|
const analysisPrompt = useStoreWithAi((s) => s.ai.analysisPrompt);
|
|
11
11
|
const setAnalysisPrompt = useStoreWithAi((s) => s.ai.setAnalysisPrompt);
|
|
12
|
-
const
|
|
13
|
-
const setApiKey = useStoreWithAi((s) => s.ai.setApiKey);
|
|
14
|
-
const model = useStoreWithAi((s) => s.projectConfig.ai.model);
|
|
15
|
-
const setAiModel = useStoreWithAi((s) => s.ai.setAiModel);
|
|
16
|
-
const supportedModels = useStoreWithAi((s) => s.ai.supportedModels);
|
|
12
|
+
const model = useStoreWithAi((s) => s.project.config.ai.model);
|
|
17
13
|
const handleKeyDown = useCallback((e) => {
|
|
18
14
|
if (e.key === 'Enter' &&
|
|
19
15
|
!e.shiftKey &&
|
|
@@ -21,16 +17,11 @@ export const QueryControls = ({ className }) => {
|
|
|
21
17
|
!e.altKey &&
|
|
22
18
|
!e.metaKey) {
|
|
23
19
|
e.preventDefault();
|
|
24
|
-
if (!isRunningAnalysis &&
|
|
25
|
-
apiKey &&
|
|
26
|
-
model &&
|
|
27
|
-
analysisPrompt.trim().length) {
|
|
20
|
+
if (!isRunningAnalysis && model && analysisPrompt.trim().length) {
|
|
28
21
|
runAnalysis();
|
|
29
22
|
}
|
|
30
23
|
}
|
|
31
|
-
}, [isRunningAnalysis,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
!model ||
|
|
35
|
-
!analysisPrompt.trim().length, children: isRunningAnalysis ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Spinner, { className: "w-4 h-4" }), " Running\u2026"] })) : ('Start Analysis') })] })] })] }));
|
|
24
|
+
}, [isRunningAnalysis, model, analysisPrompt, runAnalysis]);
|
|
25
|
+
const canStart = Boolean(!isRunningAnalysis && model && analysisPrompt.trim().length);
|
|
26
|
+
return (_jsxs("div", { className: cn('flex flex-col items-center justify-center gap-4 w-full p-4', className), children: [_jsx("div", { className: "flex items-center justify-between gap-4 w-full", children: _jsx("div", { className: "font-semibold text-lg pl-1", children: "What would you like to learn about the data?" }) }), _jsxs("div", { className: "relative w-full", children: [_jsx(Textarea, { disabled: isRunningAnalysis, className: "h-[100px] bg-gray-800", value: analysisPrompt, onChange: (e) => setAnalysisPrompt(e.target.value), onKeyDown: handleKeyDown }), _jsxs("div", { className: "absolute top-1 right-1 flex items-center gap-2", children: [isRunningAnalysis && (_jsxs(Button, { variant: "outline", onClick: cancelAnalysis, children: [_jsx(OctagonXIcon, { className: "w-4 h-4" }), "Stop"] })), _jsx(Button, { variant: "outline", onClick: runAnalysis, disabled: !canStart, children: isRunningAnalysis ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Spinner, { className: "w-4 h-4" }), " Running\u2026"] })) : ('Start Analysis') })] })] })] }));
|
|
36
27
|
};
|
package/dist/analysis.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { StepResult, ToolExecutionOptions } from 'ai';
|
|
|
9
9
|
export declare function runAnalysis({ model, abortSignal, onStepFinish, maxSteps, messages, }: {
|
|
10
10
|
abortSignal?: AbortSignal;
|
|
11
11
|
onStepFinish?: (event: StepResult<typeof TOOLS>) => Promise<void> | void;
|
|
12
|
-
apiKey: string;
|
|
13
12
|
model: LanguageModelV1;
|
|
14
13
|
maxSteps?: number;
|
|
15
14
|
messages?: any[];
|
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,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAe,UAAU,EAAQ,oBAAoB,EAAC,MAAM,IAAI,CAAC;AAOxE;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EAEL,WAAW,EACX,YAAY,EACZ,QAAc,EACd,QAAQ,GACT,EAAE;IAED,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzE,
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAe,UAAU,EAAQ,oBAAoB,EAAC,MAAM,IAAI,CAAC;AAOxE;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EAEL,WAAW,EACX,YAAY,EACZ,QAAc,EACd,QAAQ,GACT,EAAE;IAED,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzE,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;CAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA+BA;AAED,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DV,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@ai-sdk/provider": "^1.0.7",
|
|
23
23
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
24
|
-
"@sqlrooms/duckdb": "0.
|
|
25
|
-
"@sqlrooms/project-builder": "0.
|
|
26
|
-
"@sqlrooms/project-config": "0.
|
|
27
|
-
"@sqlrooms/ui": "0.
|
|
28
|
-
"@sqlrooms/vega": "0.
|
|
24
|
+
"@sqlrooms/duckdb": "0.3.0",
|
|
25
|
+
"@sqlrooms/project-builder": "0.3.0",
|
|
26
|
+
"@sqlrooms/project-config": "0.3.0",
|
|
27
|
+
"@sqlrooms/ui": "0.3.0",
|
|
28
|
+
"@sqlrooms/vega": "0.3.0",
|
|
29
29
|
"ai": "^4.1.28",
|
|
30
30
|
"immer": "^10.1.1",
|
|
31
31
|
"lucide-react": "^0.475.0",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"lint": "eslint .",
|
|
44
44
|
"typedoc": "typedoc"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "8586d4dd135d46c9c03ea65baa5a822287a5f07b"
|
|
47
47
|
}
|