@squidcloud/cli 1.0.445 → 1.0.447
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/index.js +3 -6
- package/dist/resources/claude/skills/squid-development/SKILL.md +66 -2473
- package/dist/resources/claude/skills/squid-development/reference/admin.md +242 -0
- package/dist/resources/claude/skills/squid-development/reference/ai.md +773 -0
- package/dist/resources/claude/skills/squid-development/reference/api.md +87 -0
- package/dist/resources/claude/skills/squid-development/reference/backend.md +462 -0
- package/dist/resources/claude/skills/squid-development/reference/client.md +442 -0
- package/dist/resources/claude/skills/squid-development/reference/connectors.md +33 -0
- package/dist/resources/claude/skills/squid-development/reference/console.md +189 -0
- package/dist/resources/claude/skills/squid-development/reference/databases.md +472 -0
- package/dist/resources/claude/skills/squid-development/reference/openai.md +98 -0
- package/dist/resources/claude/skills/squid-development/reference/security.md +356 -0
- package/package.json +2 -2
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
# AI Features
|
|
2
|
+
|
|
3
|
+
Squid provides comprehensive AI capabilities including agents, knowledge bases, image/audio processing, and AI-powered queries.
|
|
4
|
+
|
|
5
|
+
**REST API:** Most AI features are also available via REST API. See [api.md](api.md) or https://docs.getsquid.ai/reference-docs/api/
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
- Supported Models
|
|
9
|
+
- AI Agents
|
|
10
|
+
- Knowledge Bases
|
|
11
|
+
- AI Files
|
|
12
|
+
- Image & Audio
|
|
13
|
+
- AI Query & API Call
|
|
14
|
+
- Application Settings
|
|
15
|
+
- Backend Decorators
|
|
16
|
+
- MCP (Model Context Protocol)
|
|
17
|
+
- LLM Services
|
|
18
|
+
- AI Functions Configurator
|
|
19
|
+
|
|
20
|
+
## Supported Models
|
|
21
|
+
|
|
22
|
+
Squid supports multiple AI providers and models. The available models are defined as TypeScript constants:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import {
|
|
26
|
+
// Chat model constants (by provider)
|
|
27
|
+
OPENAI_CHAT_MODEL_NAMES,
|
|
28
|
+
ANTHROPIC_CHAT_MODEL_NAMES,
|
|
29
|
+
GEMINI_CHAT_MODEL_NAMES,
|
|
30
|
+
GROK_CHAT_MODEL_NAMES,
|
|
31
|
+
VENDOR_AI_CHAT_MODEL_NAMES, // All chat models combined
|
|
32
|
+
|
|
33
|
+
// Embedding model constants
|
|
34
|
+
AI_EMBEDDINGS_MODEL_NAMES,
|
|
35
|
+
OPENAI_EMBEDDINGS_MODEL_NAMES,
|
|
36
|
+
VOYAGE_EMBEDDING_MODEL_NAMES,
|
|
37
|
+
|
|
38
|
+
// Image generation model constants
|
|
39
|
+
AI_IMAGE_MODEL_NAMES,
|
|
40
|
+
OPENAI_IMAGE_MODEL_NAMES,
|
|
41
|
+
STABLE_DIFFUSION_MODEL_NAMES,
|
|
42
|
+
FLUX_MODEL_NAMES,
|
|
43
|
+
|
|
44
|
+
// Audio model constants
|
|
45
|
+
AI_AUDIO_TRANSCRIPTION_MODEL_NAMES,
|
|
46
|
+
OPENAI_AUDIO_CREATE_SPEECH_MODEL_NAMES,
|
|
47
|
+
|
|
48
|
+
// Type definitions
|
|
49
|
+
AiChatModelName,
|
|
50
|
+
AiEmbeddingsModelName,
|
|
51
|
+
AiImageModelName,
|
|
52
|
+
AiAudioTranscriptionModelName,
|
|
53
|
+
AiAudioCreateSpeechModelName,
|
|
54
|
+
} from '@squidcloud/client';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Model Categories:**
|
|
58
|
+
- **Chat Models**: Used for AI Agents, AI Query, etc. (OpenAI, Anthropic, Gemini, Grok)
|
|
59
|
+
- **Embedding Models**: Used for Knowledge Bases (OpenAI, Voyage)
|
|
60
|
+
- **Image Generation Models**: Used for image creation (DALL-E, Stable Diffusion, Flux)
|
|
61
|
+
- **Audio Models**: Transcription (Whisper, GPT-4o) and Text-to-Speech (TTS-1, GPT-4o-mini-tts)
|
|
62
|
+
|
|
63
|
+
## AI Agents
|
|
64
|
+
|
|
65
|
+
AI Agents are powerful, configurable AI assistants that can interact with your data, call functions, connect to integrations, and collaborate with other agents.
|
|
66
|
+
|
|
67
|
+
REST API: [Agent API](https://docs.getsquid.ai/reference-docs/api/#tag/Agent) | OpenAI-specific features: [openai.md](openai.md)
|
|
68
|
+
|
|
69
|
+
### Agent Capabilities
|
|
70
|
+
|
|
71
|
+
An AI Agent can:
|
|
72
|
+
- Maintain conversation history (**memory is enabled by default**)
|
|
73
|
+
- Call backend functions decorated with `@aiFunction`
|
|
74
|
+
- Query databases and APIs through connected integrations
|
|
75
|
+
- Search knowledge bases for relevant information
|
|
76
|
+
- Collaborate with other AI agents
|
|
77
|
+
- Process voice input and generate voice output
|
|
78
|
+
- Accept files as part of chat requests
|
|
79
|
+
|
|
80
|
+
### Creating and Managing Agents
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const aiClient = squid.ai();
|
|
84
|
+
|
|
85
|
+
// Get the built-in agent (no ID required)
|
|
86
|
+
const builtInAgent = aiClient.agent();
|
|
87
|
+
|
|
88
|
+
// Get a custom agent by ID
|
|
89
|
+
const myAgent = aiClient.agent('my-agent-id');
|
|
90
|
+
|
|
91
|
+
// Get an agent with an Agent API key (allows calling without App API key, bypasses @secureAiAgent methods)
|
|
92
|
+
const agentWithKey = aiClient.agent('my-agent-id', {
|
|
93
|
+
apiKey: 'your-agent-api-key'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Create or update an agent
|
|
97
|
+
await myAgent.upsert({
|
|
98
|
+
description: 'Customer support assistant',
|
|
99
|
+
isPublic: false, // Whether the agent is publicly accessible
|
|
100
|
+
auditLog: true, // Enable audit logging for compliance
|
|
101
|
+
options: {
|
|
102
|
+
model: 'gpt-5-mini', // or 'claude-sonnet-4-5-20250929', 'gemini-3-flash'
|
|
103
|
+
instructions: 'You are a helpful customer support assistant. Be concise and professional.',
|
|
104
|
+
temperature: 0.7
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Get agent details
|
|
109
|
+
const agentInfo = await myAgent.get();
|
|
110
|
+
console.log(agentInfo.id, agentInfo.description, agentInfo.options.model);
|
|
111
|
+
|
|
112
|
+
// Update specific properties
|
|
113
|
+
await myAgent.updateInstructions('You are a technical support specialist.');
|
|
114
|
+
await myAgent.updateModel('claude-sonnet-4-5-20250929');
|
|
115
|
+
await myAgent.updateGuardrails(['no-harmful-content']);
|
|
116
|
+
|
|
117
|
+
// Delete an agent
|
|
118
|
+
await myAgent.delete();
|
|
119
|
+
|
|
120
|
+
// List all agents
|
|
121
|
+
const agents = await squid.ai().listAgents();
|
|
122
|
+
agents.forEach(agent => console.log(`${agent.id}: ${agent.description}`));
|
|
123
|
+
|
|
124
|
+
// Manage agent API keys
|
|
125
|
+
const apiKey = await myAgent.regenerateApiKey();
|
|
126
|
+
console.log('New API key:', apiKey);
|
|
127
|
+
|
|
128
|
+
const existingKey = await myAgent.getApiKey();
|
|
129
|
+
console.log('Current API key:', existingKey);
|
|
130
|
+
|
|
131
|
+
// Update agent options at specific path
|
|
132
|
+
await myAgent.setAgentOptionInPath('temperature', 0.9);
|
|
133
|
+
await myAgent.setAgentOptionInPath('options.maxTokens', 2000);
|
|
134
|
+
|
|
135
|
+
// Update connected agents
|
|
136
|
+
await myAgent.updateConnectedAgents([
|
|
137
|
+
{ agentId: 'helper-agent', description: 'Helps with tasks' }
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
// Update or delete custom guardrails
|
|
141
|
+
await myAgent.updateCustomGuardrails('Never reveal sensitive information');
|
|
142
|
+
await myAgent.deleteCustomGuardrail();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Agent Lifecycle
|
|
146
|
+
|
|
147
|
+
1. **Creation** - Use `upsert()` to create a new agent with an ID
|
|
148
|
+
2. **Active** - Agent can process requests
|
|
149
|
+
3. **Update** - Use `upsert()` or specific update methods
|
|
150
|
+
4. **Deletion** - Use `delete()` to permanently remove the agent
|
|
151
|
+
|
|
152
|
+
**Important Notes:**
|
|
153
|
+
- Agent IDs are permanent - once created, you cannot change the ID
|
|
154
|
+
- Deleting an agent does not delete associated chat history
|
|
155
|
+
- The built-in agent (accessed via `agent()` with no ID) cannot be deleted
|
|
156
|
+
- **Agent API Keys**: You can pass an options object with an `apiKey` when calling `agent()`:
|
|
157
|
+
- Allows calling agent methods without requiring an App API key
|
|
158
|
+
- Bypasses any `@secureAiAgent` security methods when calling agent ask functions
|
|
159
|
+
- Useful for direct agent access without app-level authentication
|
|
160
|
+
|
|
161
|
+
### Connecting Resources to Agents
|
|
162
|
+
|
|
163
|
+
Agents become powerful when connected to resources:
|
|
164
|
+
- **Other AI agents** (`connectedAgents`) - Agent collaboration
|
|
165
|
+
- **Backend functions** (`functions`) - Custom logic via `@aiFunction` decorators
|
|
166
|
+
- **Integrations** (`connectedIntegrations`) - Database/API queries
|
|
167
|
+
- **Knowledge bases** (`connectedKnowledgeBases`) - RAG (Retrieval Augmented Generation)
|
|
168
|
+
|
|
169
|
+
#### Connected Agents
|
|
170
|
+
|
|
171
|
+
Allow one agent to call another agent as a specialized sub-task handler.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
const response = await agent.ask('Analyze our sales data and send report to team', {
|
|
175
|
+
connectedAgents: [
|
|
176
|
+
{
|
|
177
|
+
agentId: 'data-analyst-agent',
|
|
178
|
+
description: 'Analyzes sales data and generates reports'
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
agentId: 'email-sender-agent',
|
|
182
|
+
description: 'Sends emails to team members'
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Functions
|
|
189
|
+
|
|
190
|
+
Connect backend functions decorated with `@aiFunction` that the agent can call.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Backend function
|
|
194
|
+
@aiFunction('Gets current inventory for a product', [
|
|
195
|
+
{ name: 'productId', type: 'string', required: true, description: 'Product ID' }
|
|
196
|
+
])
|
|
197
|
+
async getInventory({ productId }: { productId: string }): Promise<number> {
|
|
198
|
+
return await db.inventory.get(productId);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Client - Agent uses the function
|
|
202
|
+
const response = await agent.ask('How many units of product-123 do we have?', {
|
|
203
|
+
functions: ['getInventory'] // Function name or ID
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// With predefined parameters (hidden from AI)
|
|
207
|
+
const response = await agent.ask('Send notification', {
|
|
208
|
+
functions: [
|
|
209
|
+
{
|
|
210
|
+
functionId: 'sendEmail',
|
|
211
|
+
context: { apiKey: 'secret-key' } // Passed to function but hidden from AI
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### Connected Integrations
|
|
218
|
+
|
|
219
|
+
Connect database or API integrations so the agent can query them directly.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
const response = await agent.ask('Show me active users from last week', {
|
|
223
|
+
connectedIntegrations: [
|
|
224
|
+
{
|
|
225
|
+
integrationId: 'postgres-db',
|
|
226
|
+
integrationType: 'database',
|
|
227
|
+
description: 'Main application database with users, orders, and products',
|
|
228
|
+
instructions: 'Only query the users table unless explicitly asked otherwise',
|
|
229
|
+
options: {
|
|
230
|
+
// Integration-specific options
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
integrationId: 'stripe-api',
|
|
235
|
+
integrationType: 'api',
|
|
236
|
+
description: 'Stripe payment API for retrieving payment information'
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### Connected Knowledge Bases
|
|
243
|
+
|
|
244
|
+
Connect knowledge bases for RAG - agent retrieves relevant context before answering.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const response = await agent.ask('What is our return policy?', {
|
|
248
|
+
connectedKnowledgeBases: [
|
|
249
|
+
{
|
|
250
|
+
knowledgeBaseId: 'company-policies-kb',
|
|
251
|
+
description: 'Use this when asked about company policies, procedures, or guidelines'
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
knowledgeBaseId: 'product-docs-kb',
|
|
255
|
+
description: 'Use this when asked about product features, specifications, or usage'
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Agent Chat Methods
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
const agent = squid.ai().agent('my-agent');
|
|
265
|
+
|
|
266
|
+
// Chat (streaming) - Returns RxJS Observable
|
|
267
|
+
// IMPORTANT: Streaming behavior:
|
|
268
|
+
// - NO connected resources: streams token-by-token
|
|
269
|
+
// - HAS connected resources: emits ONCE with complete response
|
|
270
|
+
const chatObs = agent.chat('What is your return policy?', {
|
|
271
|
+
// Memory management
|
|
272
|
+
memoryOptions: {
|
|
273
|
+
memoryMode: 'read-write', // 'none' | 'read-only' | 'read-write'
|
|
274
|
+
memoryId: 'user-123', // Unique per user/session
|
|
275
|
+
expirationMinutes: 1440 // 24 hours
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
// Connected resources (can also be set on agent.upsert)
|
|
279
|
+
connectedAgents: [{ agentId: 'specialist-agent', description: 'Handles X' }],
|
|
280
|
+
functions: ['function1', 'function2'],
|
|
281
|
+
connectedIntegrations: [{ integrationId: 'db', integrationType: 'database', description: '...' }],
|
|
282
|
+
connectedKnowledgeBases: [{ knowledgeBaseId: 'kb1', description: 'When to use this KB' }],
|
|
283
|
+
|
|
284
|
+
// Model & generation
|
|
285
|
+
model: 'gpt-5-mini', // Override agent's default model
|
|
286
|
+
temperature: 0.7,
|
|
287
|
+
maxTokens: 4000,
|
|
288
|
+
maxOutputTokens: 2000,
|
|
289
|
+
instructions: 'Additional instructions for this request only',
|
|
290
|
+
responseFormat: 'json_object', // or 'text'
|
|
291
|
+
verbosity: 'medium', // 'low' | 'medium' | 'high' (OpenAI only)
|
|
292
|
+
reasoningEffort: 'high', // 'minimal' | 'low' | 'medium' | 'high' (for reasoning models)
|
|
293
|
+
|
|
294
|
+
// Context & RAG
|
|
295
|
+
disableContext: false,
|
|
296
|
+
enablePromptRewriteForRag: false,
|
|
297
|
+
includeReference: false,
|
|
298
|
+
contextMetadataFilterForKnowledgeBase: {
|
|
299
|
+
'kb-id': { category: 'documentation' }
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
// Guardrails & quotas
|
|
303
|
+
guardrails: ['no-harmful-content', 'no-pii'],
|
|
304
|
+
quotas: {
|
|
305
|
+
maxAiCallStackSize: 5
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
// Files & voice
|
|
309
|
+
fileUrls: [
|
|
310
|
+
{ id: 'file1', type: 'image', purpose: 'context', url: 'https://...', description: 'Product image' }
|
|
311
|
+
],
|
|
312
|
+
voiceOptions: {
|
|
313
|
+
modelName: 'tts-1',
|
|
314
|
+
voice: 'alloy', // alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, shimmer, verse
|
|
315
|
+
speed: 1.0
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
// Advanced
|
|
319
|
+
smoothTyping: true,
|
|
320
|
+
useCodeInterpreter: 'llm', // 'none' | 'llm' (OpenAI/Gemini only)
|
|
321
|
+
executionPlanOptions: {
|
|
322
|
+
enabled: true,
|
|
323
|
+
model: 'gpt-5-mini',
|
|
324
|
+
reasoningEffort: 'high',
|
|
325
|
+
allowClarificationQuestions: false
|
|
326
|
+
},
|
|
327
|
+
agentContext: { userId: '123', role: 'admin' },
|
|
328
|
+
includeMetadata: false
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
chatObs.subscribe(text => {
|
|
332
|
+
console.log(text);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// Ask (complete response - same options as chat)
|
|
336
|
+
const response = await agent.ask('Question?', { /* same options */ });
|
|
337
|
+
|
|
338
|
+
// Ask with annotations (includes file references, citations)
|
|
339
|
+
const result = await agent.askWithAnnotations('Question?', { /* same options */ });
|
|
340
|
+
console.log(result.responseString);
|
|
341
|
+
console.log(result.annotations);
|
|
342
|
+
|
|
343
|
+
// Ask asynchronously (doesn't wait for response, uses job system)
|
|
344
|
+
await agent.askAsync('Long running task', 'job-id-123', { /* same options */ });
|
|
345
|
+
// Check job status later with squid.job().getJob('job-id-123')
|
|
346
|
+
|
|
347
|
+
// Voice responses
|
|
348
|
+
const voiceResult = await agent.askWithVoiceResponse('Hello', {
|
|
349
|
+
voiceOptions: { modelName: 'tts-1', voice: 'alloy', speed: 1.0 }
|
|
350
|
+
});
|
|
351
|
+
console.log(voiceResult.responseString);
|
|
352
|
+
console.log(voiceResult.voiceResponseFile);
|
|
353
|
+
|
|
354
|
+
// Transcribe audio and chat
|
|
355
|
+
const transcribeResult = await agent.transcribeAndChat(audioFile);
|
|
356
|
+
console.log(transcribeResult.transcribedPrompt);
|
|
357
|
+
transcribeResult.responseStream.subscribe(text => console.log(text));
|
|
358
|
+
|
|
359
|
+
// Transcribe audio and ask (non-streaming)
|
|
360
|
+
const askResult = await agent.transcribeAndAsk(audioFile, { /* ask options */ });
|
|
361
|
+
console.log(askResult.transcribedPrompt);
|
|
362
|
+
console.log(askResult.response);
|
|
363
|
+
|
|
364
|
+
// Transcribe audio and get voice response
|
|
365
|
+
const voiceResponse = await agent.transcribeAndAskWithVoiceResponse(audioFile, {
|
|
366
|
+
voiceOptions: { modelName: 'tts-1', voice: 'alloy' }
|
|
367
|
+
});
|
|
368
|
+
console.log(voiceResponse.transcribedPrompt);
|
|
369
|
+
console.log(voiceResponse.responseString);
|
|
370
|
+
console.log(voiceResponse.voiceResponseFile);
|
|
371
|
+
|
|
372
|
+
// Get chat history
|
|
373
|
+
const history = await agent.getChatHistory('memory-id-123');
|
|
374
|
+
|
|
375
|
+
// Provide feedback on responses
|
|
376
|
+
await agent.provideFeedback('Great response! Very helpful.');
|
|
377
|
+
|
|
378
|
+
// Observe status updates (for long-running operations)
|
|
379
|
+
agent.observeStatusUpdates().subscribe(status => {
|
|
380
|
+
console.log(status.title, status.tags);
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Knowledge Bases
|
|
385
|
+
|
|
386
|
+
Knowledge bases store and index documents for RAG. REST API: [KnowledgeBase API](https://docs.getsquid.ai/reference-docs/api/#tag/KnowledgeBase)
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
const kb = squid.ai().knowledgeBase('product-docs');
|
|
390
|
+
|
|
391
|
+
// Get knowledge base details
|
|
392
|
+
const kbDetails = await kb.getKnowledgeBase();
|
|
393
|
+
console.log(kbDetails);
|
|
394
|
+
|
|
395
|
+
// Create or update knowledge base
|
|
396
|
+
await kb.upsertKnowledgeBase({
|
|
397
|
+
description: 'Product documentation knowledge base',
|
|
398
|
+
// ...other options
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Delete knowledge base
|
|
402
|
+
await kb.delete();
|
|
403
|
+
|
|
404
|
+
// List all knowledge bases
|
|
405
|
+
const allKBs = await squid.ai().listKnowledgeBases();
|
|
406
|
+
|
|
407
|
+
// Upsert context (with or without file)
|
|
408
|
+
await kb.upsertContext({
|
|
409
|
+
contextId: 'doc-123',
|
|
410
|
+
text: 'Product documentation...',
|
|
411
|
+
metadata: { category: 'user-guide', version: '2.0' }
|
|
412
|
+
}, optionalFile);
|
|
413
|
+
|
|
414
|
+
// Batch upsert
|
|
415
|
+
await kb.upsertContexts([
|
|
416
|
+
{ contextId: 'doc-1', text: '...' },
|
|
417
|
+
{ contextId: 'doc-2', text: '...' }
|
|
418
|
+
], optionalFiles);
|
|
419
|
+
|
|
420
|
+
// Search with prompt
|
|
421
|
+
const results = await kb.searchContextsWithPrompt({
|
|
422
|
+
prompt: 'How do I reset password?',
|
|
423
|
+
limit: 5,
|
|
424
|
+
metadata: { category: 'user-guide' }
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Search by context ID
|
|
428
|
+
const related = await kb.searchContextsWithContextId({
|
|
429
|
+
contextId: 'doc-123',
|
|
430
|
+
limit: 10
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
// Semantic search (returns chunks)
|
|
434
|
+
const searchResults = await kb.search({
|
|
435
|
+
prompt: 'authentication',
|
|
436
|
+
limit: 10
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// Get context
|
|
440
|
+
const context = await kb.getContext('doc-123');
|
|
441
|
+
|
|
442
|
+
// List contexts
|
|
443
|
+
const allContexts = await kb.listContexts(1000); // truncateTextAfter
|
|
444
|
+
const contextIds = await kb.listContextIds();
|
|
445
|
+
|
|
446
|
+
// Download context
|
|
447
|
+
const download = await kb.downloadContext('doc-123');
|
|
448
|
+
|
|
449
|
+
// Delete contexts
|
|
450
|
+
await kb.deleteContext('doc-123');
|
|
451
|
+
await kb.deleteContexts(['doc-1', 'doc-2']);
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## AI Files
|
|
455
|
+
|
|
456
|
+
Manage files stored with AI providers (OpenAI, etc.) for use with agents.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
const aiFiles = squid.ai().files('openai'); // provider: 'openai' | 'anthropic' | etc.
|
|
460
|
+
|
|
461
|
+
// Upload file to AI provider
|
|
462
|
+
const fileId = await aiFiles.uploadFile({
|
|
463
|
+
file: myFile, // Browser File object
|
|
464
|
+
purpose: 'assistants'
|
|
465
|
+
});
|
|
466
|
+
console.log('Uploaded file ID:', fileId);
|
|
467
|
+
|
|
468
|
+
// Delete file from AI provider
|
|
469
|
+
const deleted = await aiFiles.deleteFile(fileId);
|
|
470
|
+
console.log('File deleted:', deleted);
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Image & Audio
|
|
474
|
+
|
|
475
|
+
REST API: [AI Image API](https://docs.getsquid.ai/reference-docs/api/#tag/AI-Image), [AI Audio API](https://docs.getsquid.ai/reference-docs/api/#tag/AI-Audio) | OpenAI-specific: [openai.md](openai.md)
|
|
476
|
+
|
|
477
|
+
### Image Generation
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
// Generate image
|
|
481
|
+
const imageUrl = await squid.ai().image().generate(
|
|
482
|
+
'A futuristic city',
|
|
483
|
+
{ size: '1024x1024', quality: 'hd' }
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// Remove background
|
|
487
|
+
const noBgBase64 = await squid.ai().image().removeBackground(imageFile);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Audio Processing
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
// Transcribe audio
|
|
494
|
+
const text = await squid.ai().audio().transcribe(audioFile, {
|
|
495
|
+
language: 'en'
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// Text-to-speech
|
|
499
|
+
const audioFile = await squid.ai().audio().createSpeech(
|
|
500
|
+
'Hello world',
|
|
501
|
+
{ modelName: 'tts-1', voice: 'alloy', speed: 1.0 }
|
|
502
|
+
);
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
## AI Query & API Call
|
|
506
|
+
|
|
507
|
+
AI Query allows you to query your database using natural language prompts. REST API: [Database API](https://docs.getsquid.ai/reference-docs/api/#tag/Database)
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
// Natural language database query (basic)
|
|
511
|
+
const result = await squid.ai().executeAiQuery(
|
|
512
|
+
'built_in_db',
|
|
513
|
+
'Show me all active users who registered last month'
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
// With options
|
|
517
|
+
const result = await squid.ai().executeAiQuery(
|
|
518
|
+
'built_in_db',
|
|
519
|
+
'Show me all active users who registered last month',
|
|
520
|
+
{
|
|
521
|
+
instructions: 'Only query the users collection',
|
|
522
|
+
enableRawResults: true,
|
|
523
|
+
selectCollectionsOptions: {
|
|
524
|
+
collectionsToUse: ['users']
|
|
525
|
+
},
|
|
526
|
+
generateQueryOptions: {
|
|
527
|
+
maxErrorCorrections: 3
|
|
528
|
+
},
|
|
529
|
+
analyzeResultsOptions: {
|
|
530
|
+
enableCodeInterpreter: true
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
// AI-powered API call
|
|
536
|
+
const apiResult = await squid.ai().executeAiApiCall(
|
|
537
|
+
'stripe-api',
|
|
538
|
+
'Create a $50 charge for customer cus_123',
|
|
539
|
+
['create-charge'], // allowed endpoints
|
|
540
|
+
true // provide explanation
|
|
541
|
+
);
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Application Settings
|
|
545
|
+
|
|
546
|
+
Manage AI provider settings and API keys for your application.
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
const aiClient = squid.ai();
|
|
550
|
+
|
|
551
|
+
// Get application AI settings
|
|
552
|
+
const settings = await aiClient.getApplicationAiSettings();
|
|
553
|
+
|
|
554
|
+
// Set application AI settings
|
|
555
|
+
await aiClient.setApplicationAiSettings({
|
|
556
|
+
defaultModel: 'gpt-5-mini',
|
|
557
|
+
// ... other settings
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// Set AI provider API key secret
|
|
561
|
+
await aiClient.setAiProviderApiKeySecret(
|
|
562
|
+
'openai', // providerType
|
|
563
|
+
'OPENAI_API_KEY' // secret key name
|
|
564
|
+
);
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
## Backend Decorators
|
|
568
|
+
|
|
569
|
+
### @aiFunction
|
|
570
|
+
|
|
571
|
+
Exposes function to AI agents. Agents automatically call these functions based on user prompts.
|
|
572
|
+
|
|
573
|
+
```typescript
|
|
574
|
+
// Simple form: description and params array
|
|
575
|
+
@aiFunction('Returns the names of the pirates crew on a given ship name', [
|
|
576
|
+
{ name: 'shipName', type: 'string', required: true, description: 'The name of the ship' }
|
|
577
|
+
])
|
|
578
|
+
async getShipCrew({ shipName }: { shipName: string }): Promise<string[]> {
|
|
579
|
+
const crew = await getCrew(shipName);
|
|
580
|
+
return crew.map(m => m.name);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Options object form with more control
|
|
584
|
+
@aiFunction({
|
|
585
|
+
id: 'custom-function-id',
|
|
586
|
+
description: 'Get user profile',
|
|
587
|
+
params: [
|
|
588
|
+
{ name: 'userId', type: 'string', required: true, description: 'User ID' }
|
|
589
|
+
],
|
|
590
|
+
attributes: {
|
|
591
|
+
integrationType: ['salesforce']
|
|
592
|
+
}
|
|
593
|
+
})
|
|
594
|
+
async getUserProfile(
|
|
595
|
+
params: { userId: string },
|
|
596
|
+
context: AiFunctionCallContext
|
|
597
|
+
): Promise<User> {
|
|
598
|
+
console.log('Agent ID:', context.agentId);
|
|
599
|
+
console.log('Agent context:', context.agentContext);
|
|
600
|
+
console.log('Function context:', context.functionContext);
|
|
601
|
+
return { userId: params.userId, name: 'John' };
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Parameter types: 'string' | 'number' | 'boolean' | 'date' | 'files'
|
|
605
|
+
@aiFunction('Books a hotel room', [
|
|
606
|
+
{ name: 'hotelName', type: 'string', required: true, description: 'Name of hotel' },
|
|
607
|
+
{ name: 'checkInDate', type: 'date', required: true, description: 'Check-in date' },
|
|
608
|
+
{ name: 'numberOfGuests', type: 'number', required: true, description: 'Number of guests' },
|
|
609
|
+
{ name: 'breakfast', type: 'boolean', required: false, description: 'Include breakfast' },
|
|
610
|
+
{ name: 'roomType', type: 'string', required: true, description: 'Type of room',
|
|
611
|
+
enum: ['single', 'double', 'suite'] }
|
|
612
|
+
])
|
|
613
|
+
async bookHotel(args: BookingArgs): Promise<string> {
|
|
614
|
+
return `Booked ${args.roomType} room at ${args.hotelName}`;
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### AI Security Decorators
|
|
619
|
+
|
|
620
|
+
For `@secureAiAgent` and `@secureAiQuery`, see [security.md](security.md#ai-security).
|
|
621
|
+
|
|
622
|
+
## MCP (Model Context Protocol)
|
|
623
|
+
|
|
624
|
+
Squid supports MCP for extending agent capabilities.
|
|
625
|
+
|
|
626
|
+
### @mcpServer
|
|
627
|
+
|
|
628
|
+
Define an MCP server that agents can connect to. The decorator is a class decorator.
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
@mcpServer({
|
|
632
|
+
id: 'my-mcp-server',
|
|
633
|
+
name: 'My MCP Server',
|
|
634
|
+
description: 'A server that provides custom tools',
|
|
635
|
+
version: '1.0.0'
|
|
636
|
+
})
|
|
637
|
+
export class MyMcpServer extends SquidService {
|
|
638
|
+
// MCP tools defined here
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
**McpServerOptions:**
|
|
643
|
+
- `id` (string): Unique ID for this MCP server (used in MCP URL)
|
|
644
|
+
- `name` (string): The MCP name exposed in the manifest
|
|
645
|
+
- `description` (string): Description of the MCP server
|
|
646
|
+
- `version` (string): Version of the MCP server
|
|
647
|
+
|
|
648
|
+
### @mcpTool
|
|
649
|
+
|
|
650
|
+
Define tools that MCP-connected agents can use. Takes an options object with description and inputSchema (JSON Schema).
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
@mcpTool({
|
|
654
|
+
description: 'Searches the database for records matching the query',
|
|
655
|
+
inputSchema: {
|
|
656
|
+
type: 'object',
|
|
657
|
+
properties: {
|
|
658
|
+
query: { type: 'string', description: 'Search query' },
|
|
659
|
+
limit: { type: 'number', description: 'Max results to return' }
|
|
660
|
+
},
|
|
661
|
+
required: ['query']
|
|
662
|
+
}
|
|
663
|
+
})
|
|
664
|
+
async searchDatabase({ query, limit = 10 }: { query: string; limit?: number }): Promise<SearchResults> {
|
|
665
|
+
return await this.squid.collection('records')
|
|
666
|
+
.query()
|
|
667
|
+
.like('content', `%${query}%`)
|
|
668
|
+
.limit(limit)
|
|
669
|
+
.snapshot();
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**McpToolMetadataOptions:**
|
|
674
|
+
- `description` (string): Describes the tool's capabilities (used by AI to determine when to call it)
|
|
675
|
+
- `inputSchema` (JSONSchema): Parameters for the MCP tool
|
|
676
|
+
- `outputSchema?` (JSONSchema): Optional output schema
|
|
677
|
+
|
|
678
|
+
### @mcpAuthorizer
|
|
679
|
+
|
|
680
|
+
Authorize MCP connections. This decorator takes no arguments and is applied within an MCP server class.
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
@mcpAuthorizer()
|
|
684
|
+
authorizeMcp(): boolean {
|
|
685
|
+
return this.isAuthenticated();
|
|
686
|
+
}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
## LLM Services
|
|
690
|
+
|
|
691
|
+
For custom LLM integrations. LLM services allow you to integrate custom AI models with Squid's AI infrastructure.
|
|
692
|
+
|
|
693
|
+
### @llmService
|
|
694
|
+
|
|
695
|
+
Define a custom LLM service. This is a class decorator that registers custom AI models.
|
|
696
|
+
|
|
697
|
+
```typescript
|
|
698
|
+
import { llmService, llmAsk, SquidLlmService } from '@squidcloud/backend';
|
|
699
|
+
|
|
700
|
+
const MY_MODELS = {
|
|
701
|
+
'my-model-v1': { displayName: 'My Model v1', maxTokens: 4096 },
|
|
702
|
+
'my-model-v2': { displayName: 'My Model v2', maxTokens: 8192 }
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
@llmService({ models: MY_MODELS, supportsFunctions: true })
|
|
706
|
+
export class CustomLlmService extends SquidLlmService {
|
|
707
|
+
@llmAsk()
|
|
708
|
+
async ask(prompt: string): Promise<string> {
|
|
709
|
+
// Custom LLM implementation
|
|
710
|
+
const response = await callMyCustomLlm(prompt);
|
|
711
|
+
return response;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
**LlmServiceOptions:**
|
|
717
|
+
- `models` (Record<string, ModelMetadata>): Map of model names to their metadata
|
|
718
|
+
- `supportsFunctions?` (boolean): Whether the LLM supports function calling
|
|
719
|
+
|
|
720
|
+
**Note:** Custom LLM services extend `SquidLlmService`, not `SquidService`.
|
|
721
|
+
|
|
722
|
+
## AI Functions Configurator
|
|
723
|
+
|
|
724
|
+
Configure which AI functions are available to agents for specific integration types. This allows you to override or exclude functions and set predefined parameters.
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
import { aiFunctionsConfigurator, AiFunctionsConfiguratorRequest, AiFunctionsConfiguratorResponse } from '@squidcloud/backend';
|
|
728
|
+
|
|
729
|
+
@aiFunctionsConfigurator({ integrationTypes: ['salesforce', 'hubspot'] })
|
|
730
|
+
configureAiFunctions(request: AiFunctionsConfiguratorRequest): AiFunctionsConfiguratorResponse {
|
|
731
|
+
console.log('Integration ID:', request.integrationId);
|
|
732
|
+
console.log('Integration type:', request.integrationType);
|
|
733
|
+
|
|
734
|
+
return {
|
|
735
|
+
functionOverrides: {
|
|
736
|
+
'getInventory': {
|
|
737
|
+
id: 'getInventory',
|
|
738
|
+
isExcluded: false,
|
|
739
|
+
predefinedParameters: { region: 'us-west-2' }
|
|
740
|
+
},
|
|
741
|
+
'processPayment': {
|
|
742
|
+
id: 'processPayment',
|
|
743
|
+
isExcluded: !this.isAuthenticated(),
|
|
744
|
+
predefinedParameters: {}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
**AiFunctionsConfiguratorMetadataOptions:**
|
|
752
|
+
- `id?` (string): Unique configurator ID (defaults to function name)
|
|
753
|
+
- `integrationTypes` (IntegrationType[]): Integration types this configurator applies to
|
|
754
|
+
|
|
755
|
+
**AiFunctionsConfiguratorRequest:**
|
|
756
|
+
- `integrationId`: ID of the connected integration
|
|
757
|
+
- `integrationType`: Type of the integration
|
|
758
|
+
- `metadata`: Current connected integration metadata
|
|
759
|
+
|
|
760
|
+
**AiFunctionsConfiguratorResponse:**
|
|
761
|
+
- `functionOverrides`: Map of function ID to override details
|
|
762
|
+
- `id`: Function ID
|
|
763
|
+
- `isExcluded?`: If true, function won't be available
|
|
764
|
+
- `predefinedParameters`: Parameters to fill with predefined values
|
|
765
|
+
|
|
766
|
+
## Best Practices
|
|
767
|
+
|
|
768
|
+
1. **Use memoryOptions for AI conversations** - Not deprecated chatId
|
|
769
|
+
2. **Agent IDs are permanent** - Plan naming carefully, cannot be changed after creation
|
|
770
|
+
3. **Memory is enabled by default** - Set `memoryMode: 'none'` to disable conversation history
|
|
771
|
+
4. **Streaming behavior differs with connected resources** - No resources: streams token-by-token; Has resources: emits once with complete response
|
|
772
|
+
5. **Deleting an agent doesn't delete chat history** - History persists independently
|
|
773
|
+
6. **Custom LLM services extend SquidLlmService** - Not SquidService
|