@sqlrooms/ai-core 0.27.0 → 0.28.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/README.md +62 -521
- package/dist/AiSlice.d.ts +2 -0
- package/dist/AiSlice.d.ts.map +1 -1
- package/dist/AiSlice.js +175 -1
- package/dist/AiSlice.js.map +1 -1
- package/dist/chatTransport.d.ts +2 -2
- package/dist/chatTransport.js.map +1 -1
- package/dist/components/AnalysisResultsContainer.d.ts.map +1 -1
- package/dist/components/AnalysisResultsContainer.js +1 -1
- package/dist/components/AnalysisResultsContainer.js.map +1 -1
- package/dist/components/PromptSuggestions.js +2 -2
- package/dist/components/PromptSuggestions.js.map +1 -1
- package/dist/components/QueryControls.js +1 -1
- package/dist/components/QueryControls.js.map +1 -1
- package/dist/components/SessionControls.js +1 -1
- package/dist/components/SessionControls.js.map +1 -1
- package/dist/components/ToolCallInfo.js +1 -1
- package/dist/components/ToolCallInfo.js.map +1 -1
- package/dist/components/tools/ToolErrorMessage.d.ts.map +1 -1
- package/dist/components/tools/ToolErrorMessage.js +3 -2
- package/dist/components/tools/ToolErrorMessage.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,547 +1,88 @@
|
|
|
1
|
-
|
|
1
|
+
Core AI slice, chat UI primitives, and tool-streaming utilities for SQLRooms.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🤖 **AI Query Interface**: Natural language to SQL conversion
|
|
8
|
-
- 📊 **Automated Analysis**: AI-powered data analysis and insights
|
|
9
|
-
- 🔄 **State Management**: Zustand-based state management for AI features
|
|
10
|
-
- 🧩 **UI Components**: Ready-to-use components for AI interactions
|
|
11
|
-
- 📝 **Query History**: Track and manage AI query history
|
|
12
|
-
- 🎯 **Tool Integration**: Framework for AI tools and actions
|
|
13
|
-
- 🤖 **Agent Framework**: Framework for building AI agents
|
|
3
|
+
Use `@sqlrooms/ai-core` when you want lower-level control over AI state/transport/UI.
|
|
4
|
+
For most apps, use the higher-level `@sqlrooms/ai` package.
|
|
14
5
|
|
|
15
6
|
## Installation
|
|
16
7
|
|
|
17
8
|
```bash
|
|
18
|
-
npm install @sqlrooms/ai
|
|
19
|
-
# or
|
|
20
|
-
yarn add @sqlrooms/ai
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Basic Usage
|
|
24
|
-
|
|
25
|
-
### Setting Up SqlRooms AI Chat for Browser-only application
|
|
26
|
-
|
|
27
|
-
```tsx
|
|
28
|
-
import {createAiSlice, createAiSettingsSlice} from '@sqlrooms/ai';
|
|
29
|
-
import {createRoomStore} from '@sqlrooms/room-shell';
|
|
30
|
-
|
|
31
|
-
// Create a room store with AI capabilities
|
|
32
|
-
const {roomStore, useRoomStore} = createRoomStore({
|
|
33
|
-
// Base room configuration
|
|
34
|
-
...createRoomShellSlice({
|
|
35
|
-
config: {
|
|
36
|
-
// Your room configuration
|
|
37
|
-
},
|
|
38
|
-
}),
|
|
39
|
-
// Ai model config slice
|
|
40
|
-
...createAiSettingsSlice({})(set, get, store),
|
|
41
|
-
// Add AI slice
|
|
42
|
-
...createAiSlice({
|
|
43
|
-
getInstructions: () => {
|
|
44
|
-
return `You are an AI assistant that can answer questions and help with tasks.`;
|
|
45
|
-
},
|
|
46
|
-
initialPrompt: 'What insights can you provide from my data?',
|
|
47
|
-
tools: {
|
|
48
|
-
// Your tools
|
|
49
|
-
},
|
|
50
|
-
getInstructions: () => {
|
|
51
|
-
// add custom instructions here
|
|
52
|
-
return createDefaultAiInstructions(store);
|
|
53
|
-
},
|
|
54
|
-
})(set, get, store),
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
function MyApp() {
|
|
58
|
-
return (
|
|
59
|
-
<RoomStateProvider roomStore={roomStore}>
|
|
60
|
-
<MyDataApp />
|
|
61
|
-
</RoomStateProvider>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Setting Up SqlRooms AI Chat for Server-side application
|
|
67
|
-
|
|
68
|
-
- api/chat/route.ts
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
export async function POST(req: Request) {
|
|
72
|
-
const {messages} = await req.json();
|
|
73
|
-
|
|
74
|
-
const stream = createUIMessageStream({
|
|
75
|
-
execute: async ({writer}) => {
|
|
76
|
-
const result = streamText({
|
|
77
|
-
model: openai('gpt-4.1'),
|
|
78
|
-
system: systemPrompt,
|
|
79
|
-
messages,
|
|
80
|
-
tools: {
|
|
81
|
-
// Your tools: remove exeucte for client tools so they run on the client side
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
writer.merge(result.toUIMessageStream({originalMessages: messages}));
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return stream.toUIMessageStreamResponse();
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
- page.tsx
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
const {roomStore, useRoomStore} = createRoomStore({
|
|
96
|
-
...createRoomShellSlice({
|
|
97
|
-
// Your room configuration
|
|
98
|
-
})(set, get, store),
|
|
99
|
-
...createAiSettingsSlice({
|
|
100
|
-
// Your AI settings
|
|
101
|
-
})(set, get, store),
|
|
102
|
-
...createAiSlice({
|
|
103
|
-
chatEndPoint: '/api/chat', // Point to the server-side endpoint
|
|
104
|
-
tools: {
|
|
105
|
-
// Your tools
|
|
106
|
-
},
|
|
107
|
-
})(set, get, store),
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
function MyApp() {
|
|
111
|
-
return (
|
|
112
|
-
<RoomStateProvider roomStore={roomStore}>
|
|
113
|
-
<MyDataApp />
|
|
114
|
-
</RoomStateProvider>
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
See [ai-nextjs](https://github.com/sqlrooms/sqlrooms/tree/main/examples/ai-nextjs) for a complete example.
|
|
120
|
-
|
|
121
|
-
## Data Structure
|
|
122
|
-
|
|
123
|
-
The basic data structure of the AI package is:
|
|
124
|
-
|
|
125
|
-
```ts
|
|
126
|
-
ai: {
|
|
127
|
-
sessions: [
|
|
128
|
-
{
|
|
129
|
-
id: string, // CUID2 identifier
|
|
130
|
-
name: string, // Session display name
|
|
131
|
-
modelProvider: string, // e.g., 'openai', 'anthropic'
|
|
132
|
-
model: string, // e.g., 'gpt-4o', 'claude-3-5-sonnet'
|
|
133
|
-
createdAt: Date,
|
|
134
|
-
// Primary storage: Full conversation history (AI SDK v5 format)
|
|
135
|
-
uiMessages: UIMessage[],
|
|
136
|
-
// Secondary storage: Error messages and legacy compatibility
|
|
137
|
-
analysisResults: AnalysisResult[],
|
|
138
|
-
// Tool execution data
|
|
139
|
-
toolAdditionalData: Record<string, unknown>,
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
currentSessionId: string,
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Session Schema
|
|
147
|
-
|
|
148
|
-
Each session contains:
|
|
149
|
-
|
|
150
|
-
#### `uiMessages` - Complete Chat History
|
|
151
|
-
|
|
152
|
-
The `uiMessages` array stores the complete, flat conversation history using the Vercel AI SDK v5 `UIMessage` format. This includes:
|
|
153
|
-
|
|
154
|
-
- User messages
|
|
155
|
-
- Assistant messages
|
|
156
|
-
- Tool call messages
|
|
157
|
-
- All message parts (text, tool invocations, etc.)
|
|
158
|
-
|
|
159
|
-
This is the **primary data structure** and serves as:
|
|
160
|
-
|
|
161
|
-
- The full context for AI model interactions
|
|
162
|
-
- The source for displaying conversation history
|
|
163
|
-
- The base for reconstructing analysis results
|
|
164
|
-
|
|
165
|
-
```tsx
|
|
166
|
-
// Example: Accessing UI messages
|
|
167
|
-
const currentSession = useRoomStore((state) => state.ai.getCurrentSession());
|
|
168
|
-
const messages = currentSession?.uiMessages || [];
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
#### `analysisResults` - Structured Analysis View
|
|
172
|
-
|
|
173
|
-
The `analysisResults` array is a **derived structure** that organizes messages into user prompt → AI response pairs. It primarily serves to:
|
|
174
|
-
|
|
175
|
-
- Store error messages that occur during analysis
|
|
176
|
-
- Provide backward compatibility with legacy data
|
|
177
|
-
- Offer a simplified view of analysis history
|
|
178
|
-
|
|
179
|
-
Analysis results are dynamically generated from `uiMessages` using the `transformMessagesToAnalysisResults` utility function.
|
|
180
|
-
|
|
181
|
-
```ts
|
|
182
|
-
type AnalysisResult = {
|
|
183
|
-
id: string; // Matches the UIMessage.id
|
|
184
|
-
prompt: string; // User's question/request
|
|
185
|
-
errorMessage?: ErrorMessageSchema; // Error if analysis failed
|
|
186
|
-
isCompleted: boolean; // Whether AI finished responding
|
|
187
|
-
};
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### `toolAdditionalData` - Rich Tool Outputs
|
|
191
|
-
|
|
192
|
-
Each session also maintains a `toolAdditionalData` object that stores additional data from tool executions, keyed by `toolCallId`. This data is used for:
|
|
193
|
-
|
|
194
|
-
- Rendering tool-specific UI components
|
|
195
|
-
- Passing data between tool calls
|
|
196
|
-
- Preserving rich data that doesn't go back to the LLM
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
type ToolAdditionalData = Record<string, unknown>;
|
|
200
|
-
|
|
201
|
-
// Example: Storing tool additional data
|
|
202
|
-
const setToolData = useRoomStore((state) => state.ai.setSessionToolAdditionalData);
|
|
203
|
-
setToolData(sessionId, toolCallId, {chartData: [...]});
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Tools
|
|
207
|
-
|
|
208
|
-
In AI package, we provide a OpenAssistantTool type that supports not only `execute` function, but also `context` object and `component` object:
|
|
209
|
-
|
|
210
|
-
- `execute` needs to return
|
|
211
|
-
- llmResult: the result send back to LLM (no raw data)
|
|
212
|
-
- additionalData: the data will be used by `component` and next `tool`
|
|
213
|
-
- `context`
|
|
214
|
-
- provide e.g. runtime or async data for `execute`
|
|
215
|
-
- `execute` can access `context` via `options.context`
|
|
216
|
-
- `component`
|
|
217
|
-
- use `additionalData` to render a React component for this `tool`
|
|
218
|
-
|
|
219
|
-
For example, the `weather` tool is defined as follows:
|
|
220
|
-
|
|
221
|
-
```ts
|
|
222
|
-
const weatherTool: OpenAssistantTool = {
|
|
223
|
-
name: 'weather',
|
|
224
|
-
description: 'Get the weather in a city from a weather station',
|
|
225
|
-
parameters: z.object({cityName: z.string()}),
|
|
226
|
-
execute: async ({cityName}, options) => {
|
|
227
|
-
const getStation = options.context?.getStation;
|
|
228
|
-
const station = getStation ? await getStation(cityName) : null;
|
|
229
|
-
return {
|
|
230
|
-
llmResult: {
|
|
231
|
-
success: true,
|
|
232
|
-
details: `The weather in ${cityName} is sunny from weather station ${station}.`,
|
|
233
|
-
},
|
|
234
|
-
additionalData: {
|
|
235
|
-
weather: 'sunny',
|
|
236
|
-
station,
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
},
|
|
240
|
-
context: {
|
|
241
|
-
getStation: async (cityName: string) => {
|
|
242
|
-
const stations = {
|
|
243
|
-
'New York': '123',
|
|
244
|
-
'Los Angeles': '456',
|
|
245
|
-
Chicago: '789',
|
|
246
|
-
};
|
|
247
|
-
return stations[cityName];
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
component: WeatherStationComponent,
|
|
251
|
-
};
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Tool Execution Flow
|
|
255
|
-
|
|
256
|
-
1. User sends a prompt → creates a user `UIMessage`
|
|
257
|
-
2. AI processes and may call tools → creates assistant `UIMessage` with tool invocations
|
|
258
|
-
3. Tools execute and return:
|
|
259
|
-
- `llmResult`: Text summary sent back to the LLM
|
|
260
|
-
- `additionalData`: Rich data stored in `toolAdditionalData` for UI rendering
|
|
261
|
-
4. AI responds with final answer → creates assistant `UIMessage` with text
|
|
262
|
-
5. On completion: `uiMessages` updated, `analysisResult` created with user message ID
|
|
263
|
-
|
|
264
|
-
### Rendering Tool Results
|
|
265
|
-
|
|
266
|
-
```text
|
|
267
|
-
|--------------------------------|
|
|
268
|
-
| AnalysisResultsContainer |
|
|
269
|
-
|--------------------------------|
|
|
270
|
-
| |--------------------------| |
|
|
271
|
-
| | AnalysisResult | |
|
|
272
|
-
| | | |
|
|
273
|
-
| | ErrorMessage | |
|
|
274
|
-
| | ------------ | |
|
|
275
|
-
| | UIMessage | |
|
|
276
|
-
| | | |
|
|
277
|
-
| | |---------------------| | |
|
|
278
|
-
| | | Parts | | |
|
|
279
|
-
| | |---------------------| | |
|
|
280
|
-
| | | |---------------| | | |
|
|
281
|
-
| | | |TextPart | | | |
|
|
282
|
-
| | | |---------------| | | |
|
|
283
|
-
| | | |ToolPart | | | |
|
|
284
|
-
| | | |---------------| | | |
|
|
285
|
-
| | | ... | | |
|
|
286
|
-
| | |---------------------| | |
|
|
287
|
-
| | | |
|
|
288
|
-
| |--------------------------| |
|
|
289
|
-
|--------------------------------|
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Transfer Additional Tool Output Data to Client
|
|
293
|
-
|
|
294
|
-
#### The Problem
|
|
295
|
-
|
|
296
|
-
When tools execute, they often generate additional data (like detailed search results, charts, metadata) that needs to be sent to the client for UI rendering, but should NOT be included in the conversation history sent back to the LLM.
|
|
297
|
-
|
|
298
|
-
If the tool execution is done on the server side, the additional data needs to be transferred to the client side for UI rendering. We use the `data-tool-additional-output` data part type to transfer the additional data to the client.
|
|
299
|
-
|
|
300
|
-
#### Using `transient: true`
|
|
301
|
-
|
|
302
|
-
The AI SDK v5 provides a built-in solution through the `transient` flag on data parts. When you write a data part with `transient: true`, the SDK automatically prevents it from being added to the message history.
|
|
303
|
-
|
|
304
|
-
##### Backend Implementation (route.ts)
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
writer.write({
|
|
308
|
-
type: 'data-tool-additional-output',
|
|
309
|
-
transient: true, // Won't be added to message history
|
|
310
|
-
data: {
|
|
311
|
-
toolCallId: chunk.toolCallId,
|
|
312
|
-
toolName: chunk.toolName,
|
|
313
|
-
output: getToolAdditionalData(chunk.toolCallId),
|
|
314
|
-
timestamp: new Date().toISOString(),
|
|
315
|
-
},
|
|
316
|
-
});
|
|
9
|
+
npm install @sqlrooms/ai-core @sqlrooms/room-store @sqlrooms/ui zod
|
|
317
10
|
```
|
|
318
11
|
|
|
319
|
-
|
|
12
|
+
`@sqlrooms/ui` is a peer dependency used for Chat UI rendering/styling.
|
|
13
|
+
You typically import Chat components from `@sqlrooms/ai-core`, but `@sqlrooms/ui` must be installed for the visual components to work.
|
|
320
14
|
|
|
321
|
-
|
|
322
|
-
Backend (route.ts)
|
|
323
|
-
│
|
|
324
|
-
├─> Tool executes
|
|
325
|
-
│ └─> writer.write({
|
|
326
|
-
│ type: 'data-tool-additional-output',
|
|
327
|
-
│ transient: true, // ✅ SDK handles exclusion
|
|
328
|
-
│ data: {...}
|
|
329
|
-
│ })
|
|
330
|
-
│
|
|
331
|
-
↓
|
|
332
|
-
Client receives stream
|
|
333
|
-
│
|
|
334
|
-
├─> onData callback
|
|
335
|
-
│ └─> setSessionToolAdditionalData() ✅ Stores in toolAdditionalData
|
|
336
|
-
│
|
|
337
|
-
└─> messages array ✅ Automatically excludes transient data parts
|
|
15
|
+
## Store setup (core mode)
|
|
338
16
|
|
|
339
|
-
|
|
340
|
-
↓
|
|
341
|
-
Session Storage
|
|
342
|
-
↓
|
|
343
|
-
Backend/LLM
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Benefits of This Approach
|
|
347
|
-
|
|
348
|
-
1. **✅ Clean Conversation History**: Transient data parts never appear in message history
|
|
349
|
-
2. **✅ Efficient Token Usage**: No unnecessary data sent to the LLM
|
|
350
|
-
3. **✅ Proper Data Storage**: Tool data is stored separately in `toolAdditionalData`
|
|
351
|
-
4. **✅ UI Flexibility**: Components can access tool data via `toolAdditionalData[toolCallId]`
|
|
352
|
-
5. **✅ Simple & Native**: Uses built-in SDK feature, no custom utilities needed
|
|
353
|
-
6. **✅ Maintainable**: Follows SDK conventions and patterns
|
|
354
|
-
7. **✅ No Manual Filtering**: SDK handles exclusion automatically
|
|
355
|
-
|
|
356
|
-
#### Usage in Components
|
|
17
|
+
`createAiSlice` requires:
|
|
357
18
|
|
|
358
|
-
|
|
19
|
+
- `tools`
|
|
20
|
+
- `getInstructions`
|
|
359
21
|
|
|
360
22
|
```tsx
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
AI SDK v5 supports message annotations, but these are still part of the message structure. The `transient` flag is specifically designed for data that should only be sent once and not persist in conversation history.
|
|
368
|
-
|
|
369
|
-
## Agent Framework
|
|
370
|
-
|
|
371
|
-
The agent framework enables building autonomous AI agents that can use tools and make multi-step decisions. Built on top of AI SDK v5's `Experimental_Agent` class, it provides utilities for integrating agents as tools within the main chat interface.
|
|
372
|
-
|
|
373
|
-
### What are Agents?
|
|
374
|
-
|
|
375
|
-
Agents differ from regular tools in that they:
|
|
376
|
-
- Can autonomously decide which tools to call and when
|
|
377
|
-
- Execute multiple steps to accomplish a goal
|
|
378
|
-
- Maintain their own reasoning loop until completion
|
|
379
|
-
- Can be embedded as tools within the main conversation
|
|
380
|
-
|
|
381
|
-
### Creating an Agent Tool
|
|
382
|
-
|
|
383
|
-
Agent tools follow the same OpenAssistantTool pattern but use the `processAgentStream` utility to handle streaming and progress tracking:
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
import {Experimental_Agent as Agent, tool} from 'ai';
|
|
387
|
-
import {processAgentStream} from '@sqlrooms/ai';
|
|
23
|
+
import {createAiSlice, type AiSliceState} from '@sqlrooms/ai-core';
|
|
24
|
+
import {
|
|
25
|
+
BaseRoomStoreState,
|
|
26
|
+
createBaseRoomSlice,
|
|
27
|
+
createRoomStore,
|
|
28
|
+
} from '@sqlrooms/room-store';
|
|
388
29
|
import {z} from 'zod';
|
|
389
30
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
tools: {
|
|
405
|
-
weather: tool({
|
|
406
|
-
description: 'Get current weather in a location',
|
|
407
|
-
inputSchema: z.object({
|
|
408
|
-
location: z.string()
|
|
409
|
-
}),
|
|
410
|
-
execute: async ({location}) => ({
|
|
411
|
-
location,
|
|
412
|
-
temperature: 72 + Math.floor(Math.random() * 21) - 10
|
|
413
|
-
})
|
|
31
|
+
type State = BaseRoomStoreState & AiSliceState;
|
|
32
|
+
|
|
33
|
+
export const {roomStore, useRoomStore} = createRoomStore<State>(
|
|
34
|
+
(set, get, store) => ({
|
|
35
|
+
...createBaseRoomSlice()(set, get, store),
|
|
36
|
+
...createAiSlice({
|
|
37
|
+
getInstructions: () => 'You are a helpful analytics assistant.',
|
|
38
|
+
tools: {
|
|
39
|
+
echo: {
|
|
40
|
+
name: 'echo',
|
|
41
|
+
description: 'Echo text back',
|
|
42
|
+
parameters: z.object({text: z.string()}),
|
|
43
|
+
execute: async ({text}) => ({
|
|
44
|
+
llmResult: {success: true, details: `Echo: ${text}`},
|
|
414
45
|
}),
|
|
415
|
-
convertTemperature: tool({
|
|
416
|
-
description: 'Convert temperature units',
|
|
417
|
-
inputSchema: z.object({
|
|
418
|
-
temperature: z.number(),
|
|
419
|
-
from: z.enum(['F', 'C']),
|
|
420
|
-
to: z.enum(['F', 'C'])
|
|
421
|
-
}),
|
|
422
|
-
execute: async ({temperature, from, to}) => {
|
|
423
|
-
// Conversion logic
|
|
424
|
-
}
|
|
425
|
-
})
|
|
426
46
|
},
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const agentResult = await weatherAgent.stream({prompt});
|
|
432
|
-
|
|
433
|
-
// Process the stream and track progress
|
|
434
|
-
const resultText = await processAgentStream(
|
|
435
|
-
agentResult,
|
|
436
|
-
store,
|
|
437
|
-
options.toolCallId
|
|
438
|
-
);
|
|
439
|
-
|
|
440
|
-
return {
|
|
441
|
-
llmResult: {
|
|
442
|
-
success: true,
|
|
443
|
-
details: resultText
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
Use the agent as a tool in your main LLM:
|
|
452
|
-
|
|
453
|
-
```typescript
|
|
454
|
-
createAiSlice({
|
|
455
|
-
tools: {
|
|
456
|
-
query: QueryTool,
|
|
457
|
-
'agent-weather': weatherAgentTool(store) // ⚡ Agent as tool
|
|
458
|
-
}
|
|
459
|
-
})
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### The `processAgentStream` Utility
|
|
463
|
-
|
|
464
|
-
The `processAgentStream` function handles the complexity of integrating agent execution into the main conversation:
|
|
465
|
-
|
|
466
|
-
```typescript
|
|
467
|
-
await processAgentStream(agentResult, store, parentToolCallId, abortSignal)
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
**What it handles:**
|
|
471
|
-
|
|
472
|
-
1. **Progress Tracking**: Monitors all tool calls made by the agent in real-time
|
|
473
|
-
2. **State Updates**: Updates `toolAdditionalData` with agent progress for UI rendering
|
|
474
|
-
3. **Error Handling**: Captures and reports tool execution errors
|
|
475
|
-
4. **Result Aggregation**: Collects the final text output from the agent
|
|
476
|
-
|
|
477
|
-
**Stored Data Structure:**
|
|
478
|
-
|
|
479
|
-
Each agent tool call stores structured progress data:
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
interface AgentToolCallAdditionalData {
|
|
483
|
-
agentToolCalls: Array<{
|
|
484
|
-
toolCallId: string;
|
|
485
|
-
toolName: string;
|
|
486
|
-
output?: unknown;
|
|
487
|
-
errorText?: string;
|
|
488
|
-
state: 'pending' | 'success' | 'error';
|
|
489
|
-
}>;
|
|
490
|
-
finalOutput?: string;
|
|
491
|
-
timestamp: string;
|
|
492
|
-
}
|
|
47
|
+
},
|
|
48
|
+
})(set, get, store),
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
493
51
|
```
|
|
494
52
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
If you are using the `sqlrooms/ai-core` package, the rendering of agent progress is handled automatically.
|
|
498
|
-
|
|
499
|
-
However, you can also use the `useRoomStore` hook to access the agent progress data in your components to show real-time execution:
|
|
53
|
+
## Chat UI
|
|
500
54
|
|
|
501
55
|
```tsx
|
|
502
|
-
|
|
503
|
-
const agentData = currentSession?.toolAdditionalData?.[toolCallId] as AgentToolCallAdditionalData;
|
|
56
|
+
import {Chat} from '@sqlrooms/ai-core';
|
|
504
57
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
<
|
|
508
|
-
|
|
509
|
-
<
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
)}
|
|
518
|
-
</div>
|
|
519
|
-
);
|
|
58
|
+
export function AiPanel() {
|
|
59
|
+
return (
|
|
60
|
+
<Chat>
|
|
61
|
+
<Chat.Sessions />
|
|
62
|
+
<Chat.Messages />
|
|
63
|
+
<Chat.PromptSuggestions>
|
|
64
|
+
<Chat.PromptSuggestions.Item text="What trends should I investigate first?" />
|
|
65
|
+
</Chat.PromptSuggestions>
|
|
66
|
+
<Chat.Composer placeholder="Ask a question" />
|
|
67
|
+
</Chat>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
520
70
|
```
|
|
521
71
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
1. **Limit Steps**: Always use `stopWhen` to prevent infinite loops
|
|
525
|
-
2. **Specific Tools**: Give agents focused, domain-specific tools
|
|
526
|
-
3. **Clear Descriptions**: Write precise tool descriptions for better agent reasoning
|
|
527
|
-
4. **Error Handling**: Handle agent errors gracefully with try-catch in execute
|
|
528
|
-
5. **Progress UI**: Use `toolAdditionalData` to show agent progress to users
|
|
529
|
-
|
|
530
|
-
### Use Cases
|
|
531
|
-
|
|
532
|
-
- **Multi-step Analysis**: Agents that need to gather data from multiple sources
|
|
533
|
-
- **Decision Trees**: Complex workflows requiring conditional logic
|
|
534
|
-
- **Specialized Domains**: Weather, finance, or data analysis agents with domain-specific tools
|
|
535
|
-
- **Autonomous Tasks**: Tasks that require planning and execution without human intervention
|
|
536
|
-
|
|
72
|
+
## Useful exports
|
|
537
73
|
|
|
538
|
-
|
|
74
|
+
- Slice/hooks: `createAiSlice`, `useStoreWithAi`, `AiSliceState`
|
|
75
|
+
- Chat UI: `Chat`, `ModelSelector`, `QueryControls`, `PromptSuggestions`
|
|
76
|
+
- Legacy/compat components: `AnalysisResultsContainer`, `AnalysisResult`, `ErrorMessage`
|
|
77
|
+
- Tool/agent utilities:
|
|
78
|
+
- `convertToAiSDKTools`
|
|
79
|
+
- `cleanupPendingAnalysisResults`
|
|
80
|
+
- `fixIncompleteToolCalls`
|
|
81
|
+
- `processAgentStream`
|
|
82
|
+
- `updateAgentToolCallData`
|
|
539
83
|
|
|
540
|
-
|
|
541
|
-
- **Multiple Sessions**: Create and manage multiple analysis sessions for different purposes
|
|
542
|
-
- **Model Selection**: Switch between different AI models and providers
|
|
543
|
-
- **Result Management**: Save, delete, and organize analysis results
|
|
544
|
-
- **Conversation Context**: Maintain context across multiple queries in a session
|
|
545
|
-
- **Feedback Loop**: Collect user feedback to improve AI responses
|
|
84
|
+
## Related packages
|
|
546
85
|
|
|
547
|
-
|
|
86
|
+
- `@sqlrooms/ai` (recommended high-level integration)
|
|
87
|
+
- `@sqlrooms/ai-settings` (provider/model settings slice + UI)
|
|
88
|
+
- `@sqlrooms/ai-config` (config schemas and migrations)
|
package/dist/AiSlice.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ import { OpenAssistantToolSet } from '@openassistant/utils';
|
|
|
6
6
|
import type { AddToolResult, AiChatSendMessage, GetProviderOptions } from './types';
|
|
7
7
|
export type AiSliceState = {
|
|
8
8
|
ai: {
|
|
9
|
+
initialize?: () => Promise<void>;
|
|
10
|
+
destroy?: () => Promise<void>;
|
|
9
11
|
config: AiSliceConfig;
|
|
10
12
|
promptSuggestionsVisible: boolean;
|
|
11
13
|
/** Tracks API key errors per provider (e.g., 401/403 responses) */
|
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,EACL,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAEtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"AiSlice.d.ts","sourceRoot":"","sources":["../src/AiSlice.ts"],"names":[],"mappings":"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"}
|