@sqlrooms/ai-core 0.26.0-rc.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/LICENSE.md +9 -0
- package/README.md +488 -0
- package/dist/AiSlice.d.ts +52 -0
- package/dist/AiSlice.d.ts.map +1 -0
- package/dist/AiSlice.js +367 -0
- package/dist/AiSlice.js.map +1 -0
- package/dist/analysis.d.ts +51 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +43 -0
- package/dist/analysis.js.map +1 -0
- package/dist/components/AnalysisAnswer.d.ts +15 -0
- package/dist/components/AnalysisAnswer.d.ts.map +1 -0
- package/dist/components/AnalysisAnswer.js +102 -0
- package/dist/components/AnalysisAnswer.js.map +1 -0
- package/dist/components/AnalysisResult.d.ts +22 -0
- package/dist/components/AnalysisResult.d.ts.map +1 -0
- package/dist/components/AnalysisResult.js +39 -0
- package/dist/components/AnalysisResult.js.map +1 -0
- package/dist/components/AnalysisResultsContainer.d.ts +5 -0
- package/dist/components/AnalysisResultsContainer.d.ts.map +1 -0
- package/dist/components/AnalysisResultsContainer.js +26 -0
- package/dist/components/AnalysisResultsContainer.js.map +1 -0
- package/dist/components/ErrorMessage.d.ts +4 -0
- package/dist/components/ErrorMessage.d.ts.map +1 -0
- package/dist/components/ErrorMessage.js +8 -0
- package/dist/components/ErrorMessage.js.map +1 -0
- package/dist/components/MessageContainer.d.ts +10 -0
- package/dist/components/MessageContainer.d.ts.map +1 -0
- package/dist/components/MessageContainer.js +9 -0
- package/dist/components/MessageContainer.js.map +1 -0
- package/dist/components/ModelSelector.d.ts +13 -0
- package/dist/components/ModelSelector.d.ts.map +1 -0
- package/dist/components/ModelSelector.js +34 -0
- package/dist/components/ModelSelector.js.map +1 -0
- package/dist/components/QueryControls.d.ts +10 -0
- package/dist/components/QueryControls.d.ts.map +1 -0
- package/dist/components/QueryControls.js +52 -0
- package/dist/components/QueryControls.js.map +1 -0
- package/dist/components/SessionControls.d.ts +17 -0
- package/dist/components/SessionControls.d.ts.map +1 -0
- package/dist/components/SessionControls.js +20 -0
- package/dist/components/SessionControls.js.map +1 -0
- package/dist/components/session/DeleteSessionButton.d.ts +19 -0
- package/dist/components/session/DeleteSessionButton.d.ts.map +1 -0
- package/dist/components/session/DeleteSessionButton.js +54 -0
- package/dist/components/session/DeleteSessionButton.js.map +1 -0
- package/dist/components/session/DeleteSessionDialog.d.ts +27 -0
- package/dist/components/session/DeleteSessionDialog.d.ts.map +1 -0
- package/dist/components/session/DeleteSessionDialog.js +19 -0
- package/dist/components/session/DeleteSessionDialog.js.map +1 -0
- package/dist/components/session/SessionActions.d.ts +18 -0
- package/dist/components/session/SessionActions.d.ts.map +1 -0
- package/dist/components/session/SessionActions.js +19 -0
- package/dist/components/session/SessionActions.js.map +1 -0
- package/dist/components/session/SessionDropdown.d.ts +18 -0
- package/dist/components/session/SessionDropdown.d.ts.map +1 -0
- package/dist/components/session/SessionDropdown.js +21 -0
- package/dist/components/session/SessionDropdown.js.map +1 -0
- package/dist/components/session/SessionTitle.d.ts +18 -0
- package/dist/components/session/SessionTitle.d.ts.map +1 -0
- package/dist/components/session/SessionTitle.js +22 -0
- package/dist/components/session/SessionTitle.js.map +1 -0
- package/dist/components/session/SessionType.d.ts +24 -0
- package/dist/components/session/SessionType.d.ts.map +1 -0
- package/dist/components/session/SessionType.js +2 -0
- package/dist/components/session/SessionType.js.map +1 -0
- package/dist/components/session/index.d.ts +7 -0
- package/dist/components/session/index.d.ts.map +1 -0
- package/dist/components/session/index.js +7 -0
- package/dist/components/session/index.js.map +1 -0
- package/dist/components/tools/ToolErrorMessage.d.ts +39 -0
- package/dist/components/tools/ToolErrorMessage.d.ts.map +1 -0
- package/dist/components/tools/ToolErrorMessage.js +20 -0
- package/dist/components/tools/ToolErrorMessage.js.map +1 -0
- package/dist/components/tools/ToolResult.d.ts +11 -0
- package/dist/components/tools/ToolResult.d.ts.map +1 -0
- package/dist/components/tools/ToolResult.js +29 -0
- package/dist/components/tools/ToolResult.js.map +1 -0
- package/dist/components/tools/ToolResultErrorBoundary.d.ts +19 -0
- package/dist/components/tools/ToolResultErrorBoundary.d.ts.map +1 -0
- package/dist/components/tools/ToolResultErrorBoundary.js +24 -0
- package/dist/components/tools/ToolResultErrorBoundary.js.map +1 -0
- package/dist/hasAiSettingsConfig.d.ts +13 -0
- package/dist/hasAiSettingsConfig.d.ts.map +1 -0
- package/dist/hasAiSettingsConfig.js +16 -0
- package/dist/hasAiSettingsConfig.js.map +1 -0
- package/dist/hooks/useScrollToBottom.d.ts +82 -0
- package/dist/hooks/useScrollToBottom.d.ts.map +1 -0
- package/dist/hooks/useScrollToBottom.js +142 -0
- package/dist/hooks/useScrollToBottom.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +31 -0
- package/dist/utils.js.map +1 -0
- package/package.json +51 -0
package/dist/AiSlice.js
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
2
|
+
import { createDefaultAiConfig, } from '@sqlrooms/ai-config';
|
|
3
|
+
import { createBaseSlice, useBaseRoomStore, } from '@sqlrooms/room-store';
|
|
4
|
+
import { produce } from 'immer';
|
|
5
|
+
import { runAnalysis } from './analysis';
|
|
6
|
+
import { hasAiSettingsConfig } from './hasAiSettingsConfig';
|
|
7
|
+
export function createAiSlice(params) {
|
|
8
|
+
const { defaultProvider = 'openai', defaultModel = 'gpt-4.1', initialAnalysisPrompt = '', tools, getApiKey, getBaseUrl, maxSteps, getInstructions, } = params;
|
|
9
|
+
return createBaseSlice((set, get, store) => {
|
|
10
|
+
return {
|
|
11
|
+
ai: {
|
|
12
|
+
config: createDefaultAiConfig(params.config),
|
|
13
|
+
analysisPrompt: initialAnalysisPrompt,
|
|
14
|
+
isRunningAnalysis: false,
|
|
15
|
+
tools,
|
|
16
|
+
setAnalysisPrompt: (prompt) => {
|
|
17
|
+
set((state) => produce(state, (draft) => {
|
|
18
|
+
draft.ai.analysisPrompt = prompt;
|
|
19
|
+
}));
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* Set the AI model for the current session
|
|
23
|
+
* @param model - The model to set
|
|
24
|
+
*/
|
|
25
|
+
setAiModel: (modelProvider, model) => {
|
|
26
|
+
set((state) => produce(state, (draft) => {
|
|
27
|
+
const currentSession = getCurrentSessionFromState(draft);
|
|
28
|
+
if (currentSession) {
|
|
29
|
+
currentSession.modelProvider = modelProvider;
|
|
30
|
+
currentSession.model = model;
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Get the current active session
|
|
36
|
+
*/
|
|
37
|
+
getCurrentSession: () => {
|
|
38
|
+
const state = get();
|
|
39
|
+
const { currentSessionId, sessions } = state.ai.config;
|
|
40
|
+
return sessions.find((session) => session.id === currentSessionId);
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Create a new session with the given name and model settings
|
|
44
|
+
*/
|
|
45
|
+
createSession: (name, modelProvider, model) => {
|
|
46
|
+
const currentSession = get().ai.getCurrentSession();
|
|
47
|
+
const newSessionId = createId();
|
|
48
|
+
// Generate a default name if none is provided
|
|
49
|
+
let sessionName = name;
|
|
50
|
+
if (!sessionName) {
|
|
51
|
+
// Generate a human-readable date and time for the session name
|
|
52
|
+
const now = new Date();
|
|
53
|
+
const formattedDate = now.toLocaleDateString('en-US', {
|
|
54
|
+
month: 'short',
|
|
55
|
+
day: 'numeric',
|
|
56
|
+
year: 'numeric',
|
|
57
|
+
});
|
|
58
|
+
const formattedTime = now.toLocaleTimeString('en-US', {
|
|
59
|
+
hour: 'numeric',
|
|
60
|
+
minute: 'numeric',
|
|
61
|
+
hour12: true,
|
|
62
|
+
});
|
|
63
|
+
sessionName = `Session ${formattedDate} at ${formattedTime}`;
|
|
64
|
+
}
|
|
65
|
+
set((state) => produce(state, (draft) => {
|
|
66
|
+
// Add to AI sessions
|
|
67
|
+
draft.ai.config.sessions.unshift({
|
|
68
|
+
id: newSessionId,
|
|
69
|
+
name: sessionName,
|
|
70
|
+
modelProvider: modelProvider || currentSession?.modelProvider || 'openai',
|
|
71
|
+
model: model || currentSession?.model || 'gpt-4.1',
|
|
72
|
+
analysisResults: [],
|
|
73
|
+
createdAt: new Date(),
|
|
74
|
+
});
|
|
75
|
+
draft.ai.config.currentSessionId = newSessionId;
|
|
76
|
+
}));
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Switch to a different session
|
|
80
|
+
*/
|
|
81
|
+
switchSession: (sessionId) => {
|
|
82
|
+
set((state) => produce(state, (draft) => {
|
|
83
|
+
draft.ai.config.currentSessionId = sessionId;
|
|
84
|
+
}));
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Rename an existing session
|
|
88
|
+
*/
|
|
89
|
+
renameSession: (sessionId, name) => {
|
|
90
|
+
set((state) => produce(state, (draft) => {
|
|
91
|
+
const session = draft.ai.config.sessions.find((s) => s.id === sessionId);
|
|
92
|
+
if (session) {
|
|
93
|
+
session.name = name;
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
},
|
|
97
|
+
/**
|
|
98
|
+
* Delete a session
|
|
99
|
+
*/
|
|
100
|
+
deleteSession: (sessionId) => {
|
|
101
|
+
set((state) => produce(state, (draft) => {
|
|
102
|
+
const sessionIndex = draft.ai.config.sessions.findIndex((s) => s.id === sessionId);
|
|
103
|
+
if (sessionIndex !== -1) {
|
|
104
|
+
// Don't delete the last session
|
|
105
|
+
if (draft.ai.config.sessions.length > 1) {
|
|
106
|
+
draft.ai.config.sessions.splice(sessionIndex, 1);
|
|
107
|
+
// If we deleted the current session, switch to another one
|
|
108
|
+
if (draft.ai.config.currentSessionId === sessionId) {
|
|
109
|
+
// Make sure there's at least one session before accessing its id
|
|
110
|
+
if (draft.ai.config.sessions.length > 0) {
|
|
111
|
+
const firstSession = draft.ai.config.sessions[0];
|
|
112
|
+
if (firstSession) {
|
|
113
|
+
draft.ai.config.currentSessionId = firstSession.id;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}));
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* Start the analysis
|
|
123
|
+
* TODO: how to pass the history analysisResults?
|
|
124
|
+
*/
|
|
125
|
+
startAnalysis: async () => {
|
|
126
|
+
const resultId = createId();
|
|
127
|
+
const abortController = new AbortController();
|
|
128
|
+
const currentSession = get().ai.getCurrentSession();
|
|
129
|
+
if (!currentSession) {
|
|
130
|
+
console.error('No current session found');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
set((state) => produce(state, (draft) => {
|
|
134
|
+
draft.ai.analysisAbortController = abortController;
|
|
135
|
+
draft.ai.isRunningAnalysis = true;
|
|
136
|
+
const session = draft.ai.config.sessions.find((s) => s.id === draft.ai.config.currentSessionId);
|
|
137
|
+
if (session) {
|
|
138
|
+
session.analysisResults.push({
|
|
139
|
+
id: resultId,
|
|
140
|
+
prompt: get().ai.analysisPrompt,
|
|
141
|
+
streamMessage: {
|
|
142
|
+
parts: [
|
|
143
|
+
{
|
|
144
|
+
type: 'text',
|
|
145
|
+
text: '',
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
isCompleted: false,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}));
|
|
153
|
+
try {
|
|
154
|
+
await runAnalysis({
|
|
155
|
+
modelProvider: currentSession.modelProvider || defaultProvider,
|
|
156
|
+
model: currentSession.model || defaultModel,
|
|
157
|
+
apiKey: get().ai.getApiKeyFromSettings(),
|
|
158
|
+
baseUrl: get().ai.getBaseUrlFromSettings(),
|
|
159
|
+
prompt: get().ai.analysisPrompt,
|
|
160
|
+
abortController,
|
|
161
|
+
tools: get().ai.tools,
|
|
162
|
+
maxSteps: get().ai.getMaxStepsFromSettings(),
|
|
163
|
+
getInstructions: get().ai.getFullInstructions,
|
|
164
|
+
historyAnalysis: currentSession.analysisResults,
|
|
165
|
+
onStreamResult: (isCompleted, streamMessage) => {
|
|
166
|
+
set(makeResultsAppender({
|
|
167
|
+
resultId,
|
|
168
|
+
streamMessage,
|
|
169
|
+
isCompleted,
|
|
170
|
+
}));
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
set(makeResultsAppender({
|
|
176
|
+
resultId,
|
|
177
|
+
isCompleted: true,
|
|
178
|
+
errorMessage: {
|
|
179
|
+
error: err instanceof Error ? err.message : String(err),
|
|
180
|
+
},
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
set((state) => produce(state, (draft) => {
|
|
185
|
+
draft.ai.isRunningAnalysis = false;
|
|
186
|
+
draft.ai.analysisPrompt = '';
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
cancelAnalysis: () => {
|
|
191
|
+
set((state) => produce(state, (draft) => {
|
|
192
|
+
draft.ai.isRunningAnalysis = false;
|
|
193
|
+
}));
|
|
194
|
+
get().ai.analysisAbortController?.abort('Analysis cancelled');
|
|
195
|
+
},
|
|
196
|
+
/**
|
|
197
|
+
* Delete an analysis result from a session
|
|
198
|
+
*/
|
|
199
|
+
deleteAnalysisResult: (sessionId, resultId) => {
|
|
200
|
+
set((state) => produce(state, (draft) => {
|
|
201
|
+
const session = draft.ai.config.sessions.find((s) => s.id === sessionId);
|
|
202
|
+
if (session) {
|
|
203
|
+
session.analysisResults = session.analysisResults.filter((r) => r.id !== resultId);
|
|
204
|
+
}
|
|
205
|
+
}));
|
|
206
|
+
},
|
|
207
|
+
findToolComponent: (toolName) => {
|
|
208
|
+
return Object.entries(get().ai.tools).find(([name]) => name === toolName)?.[1]?.component;
|
|
209
|
+
},
|
|
210
|
+
getBaseUrlFromSettings: () => {
|
|
211
|
+
// First try the getBaseUrl function if provided
|
|
212
|
+
const baseUrlFromFunction = getBaseUrl?.();
|
|
213
|
+
if (baseUrlFromFunction) {
|
|
214
|
+
return baseUrlFromFunction;
|
|
215
|
+
}
|
|
216
|
+
// Fall back to settings
|
|
217
|
+
const store = get();
|
|
218
|
+
if (hasAiSettingsConfig(store)) {
|
|
219
|
+
const currentSession = getCurrentSessionFromState(store);
|
|
220
|
+
if (currentSession) {
|
|
221
|
+
if (currentSession.modelProvider === 'custom') {
|
|
222
|
+
const customModel = store.aiSettings.config.customModels.find((m) => m.modelName === currentSession.model);
|
|
223
|
+
return customModel?.baseUrl;
|
|
224
|
+
}
|
|
225
|
+
const provider = store.aiSettings.config.providers[currentSession.modelProvider];
|
|
226
|
+
return provider?.baseUrl;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return undefined;
|
|
230
|
+
},
|
|
231
|
+
getApiKeyFromSettings: () => {
|
|
232
|
+
const store = get();
|
|
233
|
+
const currentSession = getCurrentSessionFromState(store);
|
|
234
|
+
if (currentSession) {
|
|
235
|
+
// First try the getApiKey function if provided
|
|
236
|
+
const apiKeyFromFunction = getApiKey?.(currentSession.modelProvider || defaultProvider);
|
|
237
|
+
if (apiKeyFromFunction) {
|
|
238
|
+
return apiKeyFromFunction;
|
|
239
|
+
}
|
|
240
|
+
// Fall back to settings
|
|
241
|
+
if (hasAiSettingsConfig(store)) {
|
|
242
|
+
if (currentSession.modelProvider === 'custom') {
|
|
243
|
+
const customModel = store.aiSettings.config.customModels.find((m) => m.modelName === currentSession.model);
|
|
244
|
+
return customModel?.apiKey || '';
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
const provider = store.aiSettings.config.providers?.[currentSession.modelProvider];
|
|
248
|
+
return provider?.apiKey || '';
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return '';
|
|
253
|
+
},
|
|
254
|
+
getMaxStepsFromSettings: () => {
|
|
255
|
+
const store = get();
|
|
256
|
+
// First try the maxSteps parameter if provided
|
|
257
|
+
if (maxSteps && Number.isFinite(maxSteps) && maxSteps > 0) {
|
|
258
|
+
return maxSteps;
|
|
259
|
+
}
|
|
260
|
+
// Fall back to settings
|
|
261
|
+
if (hasAiSettingsConfig(store)) {
|
|
262
|
+
const settingsMaxSteps = store.aiSettings.config.modelParameters.maxSteps;
|
|
263
|
+
if (Number.isFinite(settingsMaxSteps) && settingsMaxSteps > 0) {
|
|
264
|
+
return settingsMaxSteps;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return 5;
|
|
268
|
+
},
|
|
269
|
+
getFullInstructions: () => {
|
|
270
|
+
const store = get();
|
|
271
|
+
let instructions = getInstructions();
|
|
272
|
+
// Fall back to settings
|
|
273
|
+
if (hasAiSettingsConfig(store)) {
|
|
274
|
+
// get additional instructions from settings
|
|
275
|
+
const { additionalInstruction } = store.aiSettings.config.modelParameters;
|
|
276
|
+
if (additionalInstruction) {
|
|
277
|
+
instructions = `${instructions}\n\nAdditional Instructions:\n\n${additionalInstruction}`;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return instructions;
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Helper function to get the current session from state
|
|
288
|
+
*/
|
|
289
|
+
function getCurrentSessionFromState(state) {
|
|
290
|
+
const { currentSessionId, sessions } = state.ai.config;
|
|
291
|
+
return sessions.find((session) => session.id === currentSessionId);
|
|
292
|
+
}
|
|
293
|
+
function findResultById(analysisResults, id) {
|
|
294
|
+
return analysisResults.find((result) => result.id === id);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Appends the tool results, tool calls, and analysis to the state
|
|
298
|
+
*
|
|
299
|
+
* @param resultId - The id of the result to append to
|
|
300
|
+
* @param message - The message to append to the state. The structure of the message is defined as:
|
|
301
|
+
* - reasoning: string The reasoning of the assistant
|
|
302
|
+
* - toolCallMessages: ToolCallMessage[] The tool call messages
|
|
303
|
+
* - text: string The final text message
|
|
304
|
+
* @param isCompleted - Whether the analysis is completed
|
|
305
|
+
* @returns The new state
|
|
306
|
+
*/
|
|
307
|
+
function makeResultsAppender({ resultId, streamMessage, errorMessage, isCompleted, }) {
|
|
308
|
+
return (state) => produce(state, (draft) => {
|
|
309
|
+
const currentSession = getCurrentSessionFromState(draft);
|
|
310
|
+
if (!currentSession) {
|
|
311
|
+
console.error('No current session found');
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const result = findResultById(currentSession.analysisResults, resultId);
|
|
315
|
+
if (result) {
|
|
316
|
+
if (streamMessage && streamMessage.parts) {
|
|
317
|
+
// copy all properties from streamMessage
|
|
318
|
+
const newStreamMessage = {
|
|
319
|
+
parts: streamMessage.parts.map((part) => {
|
|
320
|
+
if (part.type === 'text') {
|
|
321
|
+
return {
|
|
322
|
+
type: 'text',
|
|
323
|
+
text: part.text,
|
|
324
|
+
additionalData: part.additionalData,
|
|
325
|
+
isCompleted: part.isCompleted,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
else if (part.type === 'tool-invocation') {
|
|
329
|
+
return {
|
|
330
|
+
type: 'tool-invocation',
|
|
331
|
+
toolInvocation: {
|
|
332
|
+
toolCallId: part.toolInvocation.toolCallId,
|
|
333
|
+
toolName: part.toolInvocation.toolName,
|
|
334
|
+
args: part.toolInvocation.args,
|
|
335
|
+
state: part.toolInvocation.state,
|
|
336
|
+
result: part.toolInvocation.state === 'result'
|
|
337
|
+
? part.toolInvocation.result
|
|
338
|
+
: undefined,
|
|
339
|
+
},
|
|
340
|
+
additionalData: part.additionalData,
|
|
341
|
+
isCompleted: part.isCompleted,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
// TODO: handle other part types later
|
|
346
|
+
return part;
|
|
347
|
+
}
|
|
348
|
+
}),
|
|
349
|
+
};
|
|
350
|
+
result.streamMessage = newStreamMessage;
|
|
351
|
+
}
|
|
352
|
+
if (errorMessage) {
|
|
353
|
+
result.errorMessage = errorMessage;
|
|
354
|
+
}
|
|
355
|
+
if (isCompleted) {
|
|
356
|
+
result.isCompleted = isCompleted;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
console.error('Result not found', resultId);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
export function useStoreWithAi(selector) {
|
|
365
|
+
return useBaseRoomStore((state) => selector(state));
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=AiSlice.js.map
|
|
@@ -0,0 +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 {\n AiSliceConfig,\n AnalysisResultSchema,\n AnalysisSessionSchema,\n createDefaultAiConfig,\n ErrorMessageSchema,\n} from '@sqlrooms/ai-config';\nimport {\n BaseRoomConfig,\n createBaseSlice,\n RoomState,\n useBaseRoomStore,\n type StateCreator,\n} from '@sqlrooms/room-store';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {runAnalysis} from './analysis';\nimport {hasAiSettingsConfig} from './hasAiSettingsConfig';\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 config: AiSliceConfig;\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 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 getApiKeyFromSettings: () => string;\n getBaseUrlFromSettings: () => string | undefined;\n getMaxStepsFromSettings: () => number;\n getFullInstructions: () => string;\n };\n};\n\n/**\n * Configuration options for creating an AI slice\n */\nexport interface AiSliceOptions {\n config?: Partial<AiSliceConfig>;\n /** Initial prompt to display in the analysis input */\n initialAnalysisPrompt?: string;\n /** Tools to add to the AI assistant */\n tools: Record<string, AiSliceTool>;\n\n /**\n * Function to get custom instructions for the AI assistant\n * @returns The instructions string to use\n */\n getInstructions: () => string;\n defaultProvider?: string;\n defaultModel?: string;\n maxSteps?: number;\n getApiKey?: (modelProvider: string) => string;\n getBaseUrl?: () => string;\n}\n\nexport function createAiSlice<PC extends BaseRoomConfig>(\n params: AiSliceOptions,\n): StateCreator<AiSliceState> {\n const {\n defaultProvider = 'openai',\n defaultModel = 'gpt-4.1',\n initialAnalysisPrompt = '',\n tools,\n getApiKey,\n getBaseUrl,\n maxSteps,\n getInstructions,\n } = params;\n\n return createBaseSlice<PC, AiSliceState>((set, get, store) => {\n return {\n ai: {\n config: createDefaultAiConfig(params.config),\n\n analysisPrompt: initialAnalysisPrompt,\n isRunningAnalysis: false,\n\n tools,\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 * Get the current active session\n */\n getCurrentSession: () => {\n const state = get();\n const {currentSessionId, sessions} = state.ai.config;\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 // Add to AI sessions\n draft.ai.config.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.ai.config.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.ai.config.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.ai.config.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.ai.config.sessions.findIndex(\n (s) => s.id === sessionId,\n );\n if (sessionIndex !== -1) {\n // Don't delete the last session\n if (draft.ai.config.sessions.length > 1) {\n draft.ai.config.sessions.splice(sessionIndex, 1);\n // If we deleted the current session, switch to another one\n if (draft.ai.config.currentSessionId === sessionId) {\n // Make sure there's at least one session before accessing its id\n if (draft.ai.config.sessions.length > 0) {\n const firstSession = draft.ai.config.sessions[0];\n if (firstSession) {\n draft.ai.config.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.ai.config.sessions.find(\n (s) => s.id === draft.ai.config.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 modelProvider: currentSession.modelProvider || defaultProvider,\n model: currentSession.model || defaultModel,\n apiKey: get().ai.getApiKeyFromSettings(),\n baseUrl: get().ai.getBaseUrlFromSettings(),\n prompt: get().ai.analysisPrompt,\n abortController,\n tools: get().ai.tools,\n maxSteps: get().ai.getMaxStepsFromSettings(),\n getInstructions: get().ai.getFullInstructions,\n historyAnalysis: currentSession.analysisResults,\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.ai.config.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 getBaseUrlFromSettings: () => {\n // First try the getBaseUrl function if provided\n const baseUrlFromFunction = getBaseUrl?.();\n if (baseUrlFromFunction) {\n return baseUrlFromFunction;\n }\n\n // Fall back to settings\n const store = get();\n if (hasAiSettingsConfig(store)) {\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.baseUrl;\n }\n const provider =\n store.aiSettings.config.providers[currentSession.modelProvider];\n return provider?.baseUrl;\n }\n }\n return undefined;\n },\n\n getApiKeyFromSettings: () => {\n const store = get();\n const currentSession = getCurrentSessionFromState(store);\n if (currentSession) {\n // First try the getApiKey function if provided\n const apiKeyFromFunction = getApiKey?.(\n currentSession.modelProvider || defaultProvider,\n );\n if (apiKeyFromFunction) {\n return apiKeyFromFunction;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n if (currentSession.modelProvider === 'custom') {\n const customModel = store.aiSettings.config.customModels.find(\n (m: {modelName: string}) =>\n m.modelName === currentSession.model,\n );\n return customModel?.apiKey || '';\n } else {\n const provider =\n store.aiSettings.config.providers?.[\n currentSession.modelProvider\n ];\n return provider?.apiKey || '';\n }\n }\n }\n return '';\n },\n\n getMaxStepsFromSettings: () => {\n const store = get();\n // First try the maxSteps parameter if provided\n if (maxSteps && Number.isFinite(maxSteps) && maxSteps > 0) {\n return maxSteps;\n }\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n const settingsMaxSteps =\n store.aiSettings.config.modelParameters.maxSteps;\n if (Number.isFinite(settingsMaxSteps) && settingsMaxSteps > 0) {\n return settingsMaxSteps;\n }\n }\n return 5;\n },\n\n getFullInstructions: () => {\n const store = get();\n\n let instructions = getInstructions();\n\n // Fall back to settings\n if (hasAiSettingsConfig(store)) {\n // get additional instructions from settings\n const {additionalInstruction} =\n store.aiSettings.config.modelParameters;\n if (additionalInstruction) {\n instructions = `${instructions}\\n\\nAdditional Instructions:\\n\\n${additionalInstruction}`;\n }\n }\n return instructions;\n },\n },\n };\n });\n}\n\n/**\n * Helper function to get the current session from state\n */\nfunction getCurrentSessionFromState<PC extends BaseRoomConfig>(\n state: AiSliceState,\n): AnalysisSessionSchema | undefined {\n const {currentSessionId, sessions} = state.ai.config;\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({\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: AiSliceState) =>\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\nexport function useStoreWithAi<\n T,\n PC extends BaseRoomConfig,\n S extends RoomState<PC> & AiSliceState,\n>(selector: (state: S) => T): T {\n return useBaseRoomStore<PC, RoomState<PC>, T>((state) =>\n selector(state as unknown as S),\n );\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { StreamMessage } from '@openassistant/core';
|
|
2
|
+
import { AnalysisResultSchema } from '@sqlrooms/ai-config';
|
|
3
|
+
import { AiSliceTool } from './AiSlice';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for running an AI analysis session
|
|
6
|
+
*/
|
|
7
|
+
type AnalysisParameters = {
|
|
8
|
+
/** Assistant instance identifier (default: 'sqlrooms-ai') */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** AI model provider (e.g., 'openai', 'anthropic') */
|
|
11
|
+
modelProvider: string;
|
|
12
|
+
/** Model identifier (e.g., 'gpt-4', 'claude-3') */
|
|
13
|
+
model: string;
|
|
14
|
+
/** Authentication key for the model provider's API */
|
|
15
|
+
apiKey: string;
|
|
16
|
+
/** Analysis prompt or question to be processed */
|
|
17
|
+
prompt: string;
|
|
18
|
+
/** Optional controller for canceling the analysis operation */
|
|
19
|
+
abortController?: AbortController;
|
|
20
|
+
/** Maximum number of analysis steps allowed (default: 100) */
|
|
21
|
+
maxSteps?: number;
|
|
22
|
+
/** The history of analysis results (e.g. saved in localStorage) */
|
|
23
|
+
historyAnalysis?: AnalysisResultSchema[];
|
|
24
|
+
/** Tools to use in the analysis */
|
|
25
|
+
tools?: Record<string, AiSliceTool>;
|
|
26
|
+
/** Base URL for Ollama provider (required when modelProvider is 'ollama') */
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Function to get custom instructions for the AI assistant
|
|
30
|
+
* @returns The instructions string to use
|
|
31
|
+
*/
|
|
32
|
+
getInstructions: () => string;
|
|
33
|
+
/**
|
|
34
|
+
* Callback for handling streaming results
|
|
35
|
+
* @param isCompleted - Indicates if this is the final message in the stream
|
|
36
|
+
* @param streamMessage - Current message content being streamed
|
|
37
|
+
*/
|
|
38
|
+
onStreamResult: (isCompleted: boolean, streamMessage?: StreamMessage) => void;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Executes an AI analysis session on the room data
|
|
42
|
+
*
|
|
43
|
+
* @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.
|
|
44
|
+
* @returns Object containing tool calls executed and the final analysis result
|
|
45
|
+
*/
|
|
46
|
+
export declare function runAnalysis({ name, modelProvider, model, apiKey, prompt, abortController, historyAnalysis, onStreamResult, maxSteps, tools, getInstructions, baseUrl, }: AnalysisParameters): Promise<{
|
|
47
|
+
streamMessage: StreamMessage;
|
|
48
|
+
messages: import("ai").CoreMessage[];
|
|
49
|
+
}>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAEtC;;GAEG;AACH,KAAK,kBAAkB,GAAG;IACxB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IAEtB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IAEd,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;;;OAGG;IACH,eAAe,EAAE,MAAM,MAAM,CAAC;IAE9B;;;;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,aAAa,EACb,KAAK,EACL,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,cAAc,EACd,QAAY,EACZ,KAAU,EACV,eAAe,EACf,OAAO,GACR,EAAE,kBAAkB;;;GA0CpB"}
|
package/dist/analysis.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createAssistant, rebuildMessages, } from '@openassistant/core';
|
|
2
|
+
import { convertToCoreMessages } from 'ai';
|
|
3
|
+
/**
|
|
4
|
+
* Executes an AI analysis session on the room data
|
|
5
|
+
*
|
|
6
|
+
* @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.
|
|
7
|
+
* @returns Object containing tool calls executed and the final analysis result
|
|
8
|
+
*/
|
|
9
|
+
export async function runAnalysis({ name = 'sqlrooms-ai', modelProvider, model, apiKey, prompt, abortController, historyAnalysis, onStreamResult, maxSteps = 5, tools = {}, getInstructions, baseUrl, }) {
|
|
10
|
+
// get the singleton assistant instance
|
|
11
|
+
const assistant = await createAssistant({
|
|
12
|
+
name,
|
|
13
|
+
modelProvider,
|
|
14
|
+
model,
|
|
15
|
+
apiKey,
|
|
16
|
+
version: 'v1',
|
|
17
|
+
instructions: getInstructions(),
|
|
18
|
+
tools: tools,
|
|
19
|
+
temperature: 0,
|
|
20
|
+
toolChoice: 'auto', // this will enable streaming
|
|
21
|
+
maxSteps,
|
|
22
|
+
...(abortController ? { abortController } : {}),
|
|
23
|
+
baseUrl, // ollama base url or LLM proxy server url
|
|
24
|
+
});
|
|
25
|
+
// restore ai messages from historyAnalysis?
|
|
26
|
+
if (historyAnalysis) {
|
|
27
|
+
const historyMessages = historyAnalysis.map((analysis) => ({
|
|
28
|
+
prompt: analysis.prompt,
|
|
29
|
+
response: analysis.streamMessage,
|
|
30
|
+
}));
|
|
31
|
+
const initialMessages = rebuildMessages(historyMessages);
|
|
32
|
+
assistant.setMessages(convertToCoreMessages(initialMessages));
|
|
33
|
+
}
|
|
34
|
+
// process the prompt
|
|
35
|
+
const newMessages = await assistant.processTextMessage({
|
|
36
|
+
textMessage: prompt,
|
|
37
|
+
streamMessageCallback: ({ isCompleted, message, }) => {
|
|
38
|
+
onStreamResult(isCompleted ?? false, message);
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
return newMessages;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,GAEhB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,qBAAqB,EAAC,MAAM,IAAI,CAAC;AAmDzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,IAAI,GAAG,aAAa,EACpB,aAAa,EACb,KAAK,EACL,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,cAAc,EACd,QAAQ,GAAG,CAAC,EACZ,KAAK,GAAG,EAAE,EACV,eAAe,EACf,OAAO,GACY;IACnB,uCAAuC;IACvC,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;QACtC,IAAI;QACJ,aAAa;QACb,KAAK;QACL,MAAM;QACN,OAAO,EAAE,IAAI;QACb,YAAY,EAAE,eAAe,EAAE;QAC/B,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,MAAM,EAAE,6BAA6B;QACjD,QAAQ;QACR,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAC,eAAe,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,0CAA0C;KACpD,CAAC,CAAC;IAEH,4CAA4C;IAC5C,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,eAAe,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACzD,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,aAA8B;SAClD,CAAC,CAAC,CAAC;QACJ,MAAM,eAAe,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QACzD,SAAS,CAAC,WAAW,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC;QACrD,WAAW,EAAE,MAAM;QACnB,qBAAqB,EAAE,CAAC,EACtB,WAAW,EACX,OAAO,GAIR,EAAE,EAAE;YACH,cAAc,CAAC,WAAW,IAAI,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import {\n createAssistant,\n rebuildMessages,\n StreamMessage,\n} from '@openassistant/core';\nimport {AnalysisResultSchema} from '@sqlrooms/ai-config';\nimport {convertToCoreMessages} from 'ai';\nimport {AiSliceTool} from './AiSlice';\n\n/**\n * Configuration options for running an AI analysis session\n */\ntype AnalysisParameters = {\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 /** 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 * @returns The instructions string to use\n */\n getInstructions: () => 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 modelProvider,\n model,\n apiKey,\n prompt,\n abortController,\n historyAnalysis,\n onStreamResult,\n maxSteps = 5,\n tools = {},\n getInstructions,\n baseUrl,\n}: AnalysisParameters) {\n // get the singleton assistant instance\n const assistant = await createAssistant({\n name,\n modelProvider,\n model,\n apiKey,\n version: 'v1',\n instructions: getInstructions(),\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"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type AnalysisAnswerProps = {
|
|
3
|
+
content: string;
|
|
4
|
+
isAnswer: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Renders an analysis answer with markdown content of the final streaming response.
|
|
8
|
+
* Supports streaming think content that may arrive in chunks (e.g., "<think>Hello" before "</think>").
|
|
9
|
+
*
|
|
10
|
+
* @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.
|
|
11
|
+
* @returns {JSX.Element} The rendered answer tool call
|
|
12
|
+
*/
|
|
13
|
+
export declare const AnalysisAnswer: React.NamedExoticComponent<AnalysisAnswerProps>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=AnalysisAnswer.d.ts.map
|
|
@@ -0,0 +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,iDA0EzB,CAAC"}
|