@proveanything/smartlinks 1.7.6 → 1.7.9
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 +68 -0
- package/dist/api/ai.d.ts +63 -8
- package/dist/api/ai.js +206 -31
- package/dist/docs/API_SUMMARY.md +192 -85
- package/dist/docs/ai.md +261 -47
- package/dist/openapi.yaml +272 -11
- package/dist/types/ai.d.ts +87 -0
- package/docs/API_SUMMARY.md +192 -85
- package/docs/ai.md +261 -47
- package/openapi.yaml +272 -11
- package/package.json +1 -1
package/docs/ai.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SmartLinks AI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build AI-powered SmartLinks experiences with a practical SDK guide for responses, chat, product assistants, streaming, voice, and real-world integration patterns.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,6 +9,7 @@ Complete guide to using AI capabilities in the SmartLinks SDK, including chat co
|
|
|
9
9
|
- [Overview](#overview)
|
|
10
10
|
- [Quick Start](#quick-start)
|
|
11
11
|
- [Authentication](#authentication)
|
|
12
|
+
- [Responses API](#responses-api)
|
|
12
13
|
- [Chat Completions](#chat-completions)
|
|
13
14
|
- [RAG: Product Assistants](#rag-product-assistants)
|
|
14
15
|
- [Voice Integration](#voice-integration)
|
|
@@ -25,12 +26,32 @@ Complete guide to using AI capabilities in the SmartLinks SDK, including chat co
|
|
|
25
26
|
|
|
26
27
|
## Overview
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
This guide is written for SDK users building real products, not backend operators. It focuses on the public SDK surface, recommended starting points, and examples you can adapt directly.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
### Start with the path that matches your job
|
|
32
|
+
|
|
33
|
+
| If you want to... | Start here |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Build a new AI workflow | Use [Responses API](#responses-api) |
|
|
36
|
+
| Add compatibility with existing chat clients | Use [Chat Completions](#chat-completions) |
|
|
37
|
+
| Build a product/manual assistant | Use [RAG: Product Assistants](#rag-product-assistants) |
|
|
38
|
+
| Add spoken input/output | Use [Voice Integration](#voice-integration) |
|
|
39
|
+
| Add progressive rendering | Use [Streaming Responses](#streaming-responses) or [Streaming Chat](#streaming-chat) |
|
|
40
|
+
|
|
41
|
+
### Recommended starting points
|
|
42
|
+
|
|
43
|
+
- New AI features: start with `ai.chat.responses.create(...)`
|
|
44
|
+
- Product/manual assistants: start with `ai.public.chat(...)`
|
|
45
|
+
- Existing OpenAI-style clients: use `ai.chat.completions.create(...)`
|
|
46
|
+
- Real-time voice: use `ai.public.getToken(...)` and your provider's live client
|
|
47
|
+
|
|
48
|
+
SmartLinks AI provides five main capabilities:
|
|
49
|
+
|
|
50
|
+
1. **Responses API** - Preferred API for agentic workflows, multimodal inputs, and tool-driven responses
|
|
51
|
+
2. **Chat Completions** - OpenAI-compatible text generation with streaming and tool calling
|
|
52
|
+
3. **RAG (Retrieval-Augmented Generation)** - Document-grounded Q&A for product assistants
|
|
53
|
+
4. **Voice Integration** - Voice-to-text and text-to-voice for hands-free interaction
|
|
54
|
+
5. **Podcast Generation** - NotebookLM-style multi-voice conversational podcasts from documents
|
|
34
55
|
|
|
35
56
|
### Key Features
|
|
36
57
|
|
|
@@ -40,6 +61,7 @@ SmartLinks AI provides four main capabilities:
|
|
|
40
61
|
- ✅ Session management for conversations
|
|
41
62
|
- ✅ Voice input/output helpers
|
|
42
63
|
- ✅ Tool/function calling support
|
|
64
|
+
- ✅ OpenAI-style Responses API support
|
|
43
65
|
- ✅ Document indexing and retrieval
|
|
44
66
|
- ✅ Customizable assistant behavior
|
|
45
67
|
|
|
@@ -47,6 +69,10 @@ SmartLinks AI provides four main capabilities:
|
|
|
47
69
|
|
|
48
70
|
## Quick Start
|
|
49
71
|
|
|
72
|
+
If you're only reading one section, start here. The three snippets below cover the most common public SDK use cases.
|
|
73
|
+
|
|
74
|
+
### 1. Generate a response
|
|
75
|
+
|
|
50
76
|
```typescript
|
|
51
77
|
import { initializeApi, ai } from '@proveanything/smartlinks';
|
|
52
78
|
|
|
@@ -56,15 +82,44 @@ initializeApi({
|
|
|
56
82
|
apiKey: process.env.SMARTLINKS_API_KEY // Required for admin endpoints
|
|
57
83
|
});
|
|
58
84
|
|
|
59
|
-
//
|
|
60
|
-
const response = await ai.chat.
|
|
85
|
+
// Preferred: create a response
|
|
86
|
+
const response = await ai.chat.responses.create('my-collection', {
|
|
61
87
|
model: 'google/gemini-2.5-flash',
|
|
62
|
-
|
|
63
|
-
{ role: 'user', content: 'Hello!' }
|
|
64
|
-
]
|
|
88
|
+
input: 'Summarize the key safety steps for descaling a coffee maker.'
|
|
65
89
|
});
|
|
66
90
|
|
|
67
|
-
console.log(response.
|
|
91
|
+
console.log(response.output_text);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. Build a product assistant
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { initializeApi, ai } from '@proveanything/smartlinks';
|
|
98
|
+
|
|
99
|
+
initializeApi({ baseURL: 'https://smartlinks.app/api/v1' });
|
|
100
|
+
|
|
101
|
+
const answer = await ai.public.chat('my-collection', {
|
|
102
|
+
productId: 'coffee-maker-deluxe',
|
|
103
|
+
userId: 'user-123',
|
|
104
|
+
message: 'How do I descale this machine?'
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
console.log(answer.message);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Stream output into your UI
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const stream = await ai.chat.responses.create('my-collection', {
|
|
114
|
+
input: 'Write a launch checklist for a new product page.',
|
|
115
|
+
stream: true
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
for await (const event of stream) {
|
|
119
|
+
if (event.type === 'response.output_text.delta') {
|
|
120
|
+
updateUi(event.delta);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
68
123
|
```
|
|
69
124
|
|
|
70
125
|
---
|
|
@@ -90,7 +145,7 @@ Public endpoints don't require an API key but are rate-limited by `userId`:
|
|
|
90
145
|
|
|
91
146
|
```typescript
|
|
92
147
|
// No API key needed
|
|
93
|
-
const response = await ai.
|
|
148
|
+
const response = await ai.public.chat('my-collection', {
|
|
94
149
|
productId: 'coffee-maker',
|
|
95
150
|
userId: 'user-123',
|
|
96
151
|
message: 'How do I clean this?'
|
|
@@ -99,9 +154,108 @@ const response = await ai.publicApi.chat({
|
|
|
99
154
|
|
|
100
155
|
---
|
|
101
156
|
|
|
157
|
+
## Responses API
|
|
158
|
+
|
|
159
|
+
The Responses API is the recommended starting point for new integrations. Use it when you want a single endpoint for structured input, tool use, and streaming output.
|
|
160
|
+
|
|
161
|
+
### Basic Response
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const response = await ai.chat.responses.create('my-collection', {
|
|
165
|
+
model: 'google/gemini-2.5-flash',
|
|
166
|
+
input: 'Write a friendly two-sentence welcome for a product assistant.'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
console.log(response.output_text);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Multimessage Input
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const response = await ai.chat.responses.create('my-collection', {
|
|
176
|
+
model: 'google/gemini-2.5-flash',
|
|
177
|
+
input: [
|
|
178
|
+
{
|
|
179
|
+
role: 'system',
|
|
180
|
+
content: [
|
|
181
|
+
{ type: 'input_text', text: 'You are a concise support assistant.' }
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
role: 'user',
|
|
186
|
+
content: [
|
|
187
|
+
{ type: 'input_text', text: 'Give me three troubleshooting steps for a grinder that will not start.' }
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
console.log(response.output_text);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Streaming Responses
|
|
197
|
+
|
|
198
|
+
When you pass `stream: true`, the SDK returns an `AsyncIterable` of SSE events instead of a final JSON object. You do not need to parse raw SSE frames yourself — just iterate with `for await...of`.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const result = await ai.chat.responses.create('my-collection', {
|
|
202
|
+
input: 'Summarize the manual',
|
|
203
|
+
stream: true
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
for await (const event of result) {
|
|
207
|
+
if (event.type === 'response.output_text.delta') {
|
|
208
|
+
process.stdout.write(event.delta);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
If you omit `stream: true`, the same method returns the final `ResponsesResult` object instead.
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const stream = await ai.chat.responses.create('my-collection', {
|
|
217
|
+
model: 'google/gemini-2.5-flash',
|
|
218
|
+
input: 'Explain how to descale an espresso machine step by step.',
|
|
219
|
+
stream: true
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
for await (const event of stream) {
|
|
223
|
+
if (event.type === 'response.output_text.delta') {
|
|
224
|
+
process.stdout.write(event.delta);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Tool Calling
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const response = await ai.chat.responses.create('my-collection', {
|
|
233
|
+
model: 'google/gemini-2.5-flash',
|
|
234
|
+
input: 'What is the weather in Paris?',
|
|
235
|
+
tools: [
|
|
236
|
+
{
|
|
237
|
+
type: 'function',
|
|
238
|
+
name: 'get_weather',
|
|
239
|
+
description: 'Get the current weather for a city',
|
|
240
|
+
parameters: {
|
|
241
|
+
type: 'object',
|
|
242
|
+
properties: {
|
|
243
|
+
location: { type: 'string' }
|
|
244
|
+
},
|
|
245
|
+
required: ['location']
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
console.log(response.output);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
102
256
|
## Chat Completions
|
|
103
257
|
|
|
104
|
-
OpenAI-compatible chat completions with streaming and tool calling support.
|
|
258
|
+
OpenAI-compatible chat completions with streaming and tool calling support. Use this for compatibility with existing Chat Completions integrations; prefer the Responses API for new agentic features.
|
|
105
259
|
|
|
106
260
|
### Basic Chat
|
|
107
261
|
|
|
@@ -122,6 +276,12 @@ console.log(response.choices[0].message.content);
|
|
|
122
276
|
|
|
123
277
|
Stream responses in real-time for better UX:
|
|
124
278
|
|
|
279
|
+
- Set `stream: true`
|
|
280
|
+
- The SDK returns an `AsyncIterable<ChatCompletionChunk>`
|
|
281
|
+
- Iterate over chunks with `for await...of`
|
|
282
|
+
- Read incremental text from `chunk.choices[0]?.delta?.content`
|
|
283
|
+
- If `stream` is omitted or `false`, the method returns the normal `ChatCompletionResponse`
|
|
284
|
+
|
|
125
285
|
```typescript
|
|
126
286
|
const stream = await ai.chat.completions.create('my-collection', {
|
|
127
287
|
model: 'google/gemini-2.5-flash',
|
|
@@ -188,6 +348,15 @@ if (toolCall) {
|
|
|
188
348
|
// List all available models
|
|
189
349
|
const models = await ai.models.list('my-collection');
|
|
190
350
|
|
|
351
|
+
// Or filter by provider / capability
|
|
352
|
+
const openAiModels = await ai.models.list('my-collection', {
|
|
353
|
+
provider: 'openai'
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const visionModels = await ai.models.list('my-collection', {
|
|
357
|
+
capability: 'vision'
|
|
358
|
+
});
|
|
359
|
+
|
|
191
360
|
models.data.forEach(model => {
|
|
192
361
|
console.log(`${model.name}`);
|
|
193
362
|
console.log(` Provider: ${model.provider}`);
|
|
@@ -200,13 +369,18 @@ const model = await ai.models.get('my-collection', 'google/gemini-2.5-flash');
|
|
|
200
369
|
console.log(model.capabilities); // ['text', 'vision', 'audio', 'code']
|
|
201
370
|
```
|
|
202
371
|
|
|
372
|
+
Use `ai.models.list(collectionId)` as the source of truth for what your collection can use at runtime. The public docs provide recommendations, but actual availability depends on the SmartLinks model catalog exposed to that collection.
|
|
373
|
+
|
|
203
374
|
**Recommended Models:**
|
|
204
375
|
|
|
205
376
|
| Model | Use Case | Speed | Cost |
|
|
206
377
|
|-------|----------|-------|------|
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `google/gemini-2.5-
|
|
378
|
+
| `openai/gpt-5.4` | Default for new agentic and structured-output workflows | Balanced | Medium |
|
|
379
|
+
| `openai/gpt-5-mini` | Lower-cost general purpose and JSON tasks | Fast | Low |
|
|
380
|
+
| `google/gemini-2.5-flash` | Fast multimodal and cost-sensitive general use | Fast | Low |
|
|
381
|
+
| `google/gemini-2.5-pro` | Complex reasoning and heavier multimodal tasks | Slower | Higher |
|
|
382
|
+
|
|
383
|
+
If you want a safe default for most new work, start with `openai/gpt-5.4`. If you want a lower-cost fallback, use `openai/gpt-5-mini` or `google/gemini-2.5-flash` depending on your latency and pricing goals.
|
|
210
384
|
|
|
211
385
|
---
|
|
212
386
|
|
|
@@ -268,7 +442,7 @@ Users can chat with the product assistant without authentication:
|
|
|
268
442
|
|
|
269
443
|
```typescript
|
|
270
444
|
// First question
|
|
271
|
-
const response = await ai.
|
|
445
|
+
const response = await ai.public.chat('my-collection', {
|
|
272
446
|
productId: 'coffee-maker-deluxe',
|
|
273
447
|
userId: 'user-123',
|
|
274
448
|
message: 'How do I descale my coffee maker?'
|
|
@@ -328,8 +502,31 @@ console.log('Rate-limited users:', stats.rateLimitedUsers);
|
|
|
328
502
|
|
|
329
503
|
Enable voice input and output for hands-free interaction.
|
|
330
504
|
|
|
505
|
+
### Voice Patterns
|
|
506
|
+
|
|
507
|
+
The SDK supports three practical voice patterns:
|
|
508
|
+
|
|
509
|
+
| Pattern | Best For | SDK Building Blocks |
|
|
510
|
+
|---------|----------|---------------------|
|
|
511
|
+
| Voice → Text → AI → Text | Manual helper Q&A, troubleshooting steps | `ai.voice.listen()` + `ai.public.chat()` |
|
|
512
|
+
| Voice → Text → AI → Voice | Hands-free assistants, accessibility | `ai.voice.listen()` + `ai.public.chat()` + `ai.voice.speak()` or `ai.tts.generate()` |
|
|
513
|
+
| Real-time Voice | Low-latency spoken conversation | `ai.public.getToken()` + Gemini Live client |
|
|
514
|
+
|
|
515
|
+
### Current SDK Support
|
|
516
|
+
|
|
517
|
+
- `ai.voice.listen()` and `ai.voice.speak()` are browser helpers built on the Web Speech APIs.
|
|
518
|
+
- `ai.public.getToken()` generates ephemeral tokens for Gemini Live sessions.
|
|
519
|
+
- `ai.tts.generate()` supports server-side text-to-speech generation.
|
|
520
|
+
- The SDK does not currently expose a first-class transcription endpoint like Whisper; if you need that flow, implement it as your own backend endpoint and feed the transcribed text into `ai.public.chat()` or `ai.chat.responses.create()`.
|
|
521
|
+
|
|
522
|
+
### Recommended Approach
|
|
523
|
+
|
|
524
|
+
For product assistants and RAG-backed support, start with Voice → Text → AI → Text/Voice. It gives you the best control over retrieval, session history, and cost. Use Gemini Live when low-latency spoken conversation matters more than deep document grounding.
|
|
525
|
+
|
|
331
526
|
### Browser Voice Helpers
|
|
332
527
|
|
|
528
|
+
These helpers are browser-only and rely on native speech recognition / speech synthesis support.
|
|
529
|
+
|
|
333
530
|
```typescript
|
|
334
531
|
// Check if voice is supported
|
|
335
532
|
if (ai.voice.isSupported()) {
|
|
@@ -396,7 +593,7 @@ class ProductVoiceAssistant {
|
|
|
396
593
|
}
|
|
397
594
|
|
|
398
595
|
async getRemainingQuestions(): Promise<number> {
|
|
399
|
-
const status = await ai.
|
|
596
|
+
const status = await ai.public.getRateLimit(this.collectionId, this.userId);
|
|
400
597
|
return status.remaining;
|
|
401
598
|
}
|
|
402
599
|
}
|
|
@@ -417,9 +614,11 @@ console.log(`${remaining} questions remaining`);
|
|
|
417
614
|
|
|
418
615
|
Generate ephemeral tokens for Gemini Live (multimodal voice):
|
|
419
616
|
|
|
617
|
+
Use this path for real-time voice sessions. The SDK only issues the short-lived token; the actual live connection is made with the provider client.
|
|
618
|
+
|
|
420
619
|
```typescript
|
|
421
620
|
// Generate token for voice session
|
|
422
|
-
const token = await ai.
|
|
621
|
+
const token = await ai.public.getToken('my-collection', {
|
|
423
622
|
settings: {
|
|
424
623
|
ttl: 3600, // 1 hour
|
|
425
624
|
voice: 'alloy',
|
|
@@ -434,6 +633,17 @@ console.log('Expires at:', new Date(token.expiresAt));
|
|
|
434
633
|
// (See Google's Gemini documentation)
|
|
435
634
|
```
|
|
436
635
|
|
|
636
|
+
### Voice + RAG Guidance
|
|
637
|
+
|
|
638
|
+
For document-grounded assistants, prefer this pattern:
|
|
639
|
+
|
|
640
|
+
1. Capture voice with `ai.voice.listen()` or your own transcription flow.
|
|
641
|
+
2. Send the transcribed text to `ai.public.chat()`.
|
|
642
|
+
3. Render the text response for readability.
|
|
643
|
+
4. Optionally speak the answer with `ai.voice.speak()` or `ai.tts.generate()`.
|
|
644
|
+
|
|
645
|
+
This is usually a better fit for manuals and procedural guidance than trying to use a live voice session as the primary retrieval layer.
|
|
646
|
+
|
|
437
647
|
---
|
|
438
648
|
|
|
439
649
|
## Podcast Generation
|
|
@@ -917,7 +1127,7 @@ const audioBlob = await ai.tts.generate('my-collection', {
|
|
|
917
1127
|
|
|
918
1128
|
### Public Endpoints
|
|
919
1129
|
|
|
920
|
-
#### `ai.
|
|
1130
|
+
#### `ai.public.chat(collectionId, request)`
|
|
921
1131
|
|
|
922
1132
|
Chat with product assistant (no auth required).
|
|
923
1133
|
|
|
@@ -930,7 +1140,7 @@ Chat with product assistant (no auth required).
|
|
|
930
1140
|
|
|
931
1141
|
---
|
|
932
1142
|
|
|
933
|
-
#### `ai.
|
|
1143
|
+
#### `ai.public.getSession(collectionId, sessionId)`
|
|
934
1144
|
|
|
935
1145
|
Get conversation history.
|
|
936
1146
|
|
|
@@ -938,7 +1148,7 @@ Get conversation history.
|
|
|
938
1148
|
|
|
939
1149
|
---
|
|
940
1150
|
|
|
941
|
-
#### `ai.
|
|
1151
|
+
#### `ai.public.clearSession(collectionId, sessionId)`
|
|
942
1152
|
|
|
943
1153
|
Clear conversation history.
|
|
944
1154
|
|
|
@@ -946,7 +1156,7 @@ Clear conversation history.
|
|
|
946
1156
|
|
|
947
1157
|
---
|
|
948
1158
|
|
|
949
|
-
#### `ai.
|
|
1159
|
+
#### `ai.public.getRateLimit(collectionId, userId)`
|
|
950
1160
|
|
|
951
1161
|
Check rate limit status.
|
|
952
1162
|
|
|
@@ -954,7 +1164,7 @@ Check rate limit status.
|
|
|
954
1164
|
|
|
955
1165
|
---
|
|
956
1166
|
|
|
957
|
-
#### `ai.
|
|
1167
|
+
#### `ai.public.getToken(collectionId, request)`
|
|
958
1168
|
|
|
959
1169
|
Generate ephemeral token for Gemini Live.
|
|
960
1170
|
|
|
@@ -985,7 +1195,7 @@ async function createProductFAQ() {
|
|
|
985
1195
|
});
|
|
986
1196
|
|
|
987
1197
|
// 3. Answer user questions
|
|
988
|
-
const answer = await ai.
|
|
1198
|
+
const answer = await ai.public.chat(collectionId, {
|
|
989
1199
|
productId,
|
|
990
1200
|
userId: 'user-123',
|
|
991
1201
|
message: 'How do I make espresso?'
|
|
@@ -1032,7 +1242,7 @@ async function chatConversation() {
|
|
|
1032
1242
|
const productId = 'coffee-maker-deluxe';
|
|
1033
1243
|
|
|
1034
1244
|
// Question 1
|
|
1035
|
-
const a1 = await ai.
|
|
1245
|
+
const a1 = await ai.public.chat(collectionId, {
|
|
1036
1246
|
productId,
|
|
1037
1247
|
userId,
|
|
1038
1248
|
message: 'How do I clean the machine?',
|
|
@@ -1041,7 +1251,7 @@ async function chatConversation() {
|
|
|
1041
1251
|
console.log('A1:', a1.message);
|
|
1042
1252
|
|
|
1043
1253
|
// Question 2 (references previous context)
|
|
1044
|
-
const a2 = await ai.
|
|
1254
|
+
const a2 = await ai.public.chat(collectionId, {
|
|
1045
1255
|
productId,
|
|
1046
1256
|
userId,
|
|
1047
1257
|
message: 'How often should I do that?',
|
|
@@ -1050,7 +1260,7 @@ async function chatConversation() {
|
|
|
1050
1260
|
console.log('A2:', a2.message);
|
|
1051
1261
|
|
|
1052
1262
|
// Get full history
|
|
1053
|
-
const session = await ai.
|
|
1263
|
+
const session = await ai.public.getSession(collectionId, sessionId);
|
|
1054
1264
|
console.log('Full conversation:', session.messages);
|
|
1055
1265
|
}
|
|
1056
1266
|
```
|
|
@@ -1075,7 +1285,7 @@ export function useProductAssistant(
|
|
|
1075
1285
|
setError(null);
|
|
1076
1286
|
|
|
1077
1287
|
try {
|
|
1078
|
-
const response = await ai.
|
|
1288
|
+
const response = await ai.public.chat(collectionId, {
|
|
1079
1289
|
productId,
|
|
1080
1290
|
userId,
|
|
1081
1291
|
message
|
|
@@ -1251,7 +1461,7 @@ import { SmartLinksAIError } from '@proveanything/smartlinks';
|
|
|
1251
1461
|
|
|
1252
1462
|
async function robustChat() {
|
|
1253
1463
|
try {
|
|
1254
|
-
const response = await ai.
|
|
1464
|
+
const response = await ai.public.chat('my-collection', {
|
|
1255
1465
|
productId: 'coffee-maker',
|
|
1256
1466
|
userId: 'user-123',
|
|
1257
1467
|
message: 'Help!'
|
|
@@ -1295,7 +1505,7 @@ async function chatWithRetry(
|
|
|
1295
1505
|
|
|
1296
1506
|
while (retries < maxRetries) {
|
|
1297
1507
|
try {
|
|
1298
|
-
return await ai.
|
|
1508
|
+
return await ai.public.chat('my-collection', request);
|
|
1299
1509
|
} catch (error) {
|
|
1300
1510
|
if (error instanceof SmartLinksAIError && error.isRateLimitError()) {
|
|
1301
1511
|
if (retries === maxRetries - 1) throw error;
|
|
@@ -1345,7 +1555,7 @@ X-RateLimit-Reset: 1707300000000
|
|
|
1345
1555
|
|
|
1346
1556
|
```typescript
|
|
1347
1557
|
// Check rate limit status before making requests
|
|
1348
|
-
const status = await ai.
|
|
1558
|
+
const status = await ai.public.getRateLimit('my-collection', 'user-123');
|
|
1349
1559
|
|
|
1350
1560
|
console.log('Used:', status.used);
|
|
1351
1561
|
console.log('Remaining:', status.remaining);
|
|
@@ -1353,7 +1563,7 @@ console.log('Resets at:', new Date(status.resetAt));
|
|
|
1353
1563
|
|
|
1354
1564
|
if (status.remaining > 0) {
|
|
1355
1565
|
// Safe to make request
|
|
1356
|
-
await ai.
|
|
1566
|
+
await ai.public.chat(/* ... */);
|
|
1357
1567
|
} else {
|
|
1358
1568
|
// Show user when they can ask again
|
|
1359
1569
|
console.log('Rate limit reached. Try again at:', status.resetAt);
|
|
@@ -1375,23 +1585,27 @@ console.log('Rate limit reset for user-123');
|
|
|
1375
1585
|
### 1. Choose the Right Model
|
|
1376
1586
|
|
|
1377
1587
|
```typescript
|
|
1378
|
-
// For
|
|
1379
|
-
await ai.chat.
|
|
1380
|
-
model: '
|
|
1381
|
-
|
|
1588
|
+
// For most new workflows (recommended default)
|
|
1589
|
+
await ai.chat.responses.create('my-collection', {
|
|
1590
|
+
model: 'openai/gpt-5.4',
|
|
1591
|
+
input: 'Create a concise onboarding checklist.'
|
|
1382
1592
|
});
|
|
1383
1593
|
|
|
1384
|
-
// For
|
|
1385
|
-
await ai.chat.
|
|
1386
|
-
model: '
|
|
1387
|
-
|
|
1594
|
+
// For lower-cost structured or JSON-oriented work
|
|
1595
|
+
await ai.chat.responses.create('my-collection', {
|
|
1596
|
+
model: 'openai/gpt-5-mini',
|
|
1597
|
+
input: 'Return a color palette as JSON.'
|
|
1388
1598
|
});
|
|
1389
1599
|
|
|
1390
|
-
// For
|
|
1600
|
+
// For fast multimodal or cost-sensitive general use
|
|
1391
1601
|
await ai.chat.completions.create('my-collection', {
|
|
1392
|
-
model: 'google/gemini-2.5-
|
|
1602
|
+
model: 'google/gemini-2.5-flash',
|
|
1393
1603
|
messages: [...]
|
|
1394
1604
|
});
|
|
1605
|
+
|
|
1606
|
+
// When you need the actual available catalog for this collection
|
|
1607
|
+
const available = await ai.models.list('my-collection');
|
|
1608
|
+
console.log(available.data.map(model => model.id));
|
|
1395
1609
|
```
|
|
1396
1610
|
|
|
1397
1611
|
### 2. Use Streaming for Long Responses
|
|
@@ -1443,7 +1657,7 @@ Show clear feedback to users:
|
|
|
1443
1657
|
|
|
1444
1658
|
```typescript
|
|
1445
1659
|
try {
|
|
1446
|
-
await ai.
|
|
1660
|
+
await ai.public.chat('my-collection', {...});
|
|
1447
1661
|
} catch (error) {
|
|
1448
1662
|
if (error instanceof SmartLinksAIError && error.isRateLimitError()) {
|
|
1449
1663
|
const resetTime = new Date(error.resetAt!);
|
|
@@ -1649,7 +1863,7 @@ interface AIContentResponse {
|
|
|
1649
1863
|
|
|
1650
1864
|
/**
|
|
1651
1865
|
* Pre-built RAG configuration. When provided, the assistant can use
|
|
1652
|
-
|
|
1866
|
+
* SL.ai.public.chat() to ground answers in indexed product documents.
|
|
1653
1867
|
*/
|
|
1654
1868
|
ragHint?: {
|
|
1655
1869
|
/** The product ID whose indexed documents should be queried */
|
|
@@ -1669,7 +1883,7 @@ interface AIContentResponse {
|
|
|
1669
1883
|
/**
|
|
1670
1884
|
* How the assistant should use this content:
|
|
1671
1885
|
* - 'context' (default): inject text into the system prompt
|
|
1672
|
-
|
|
1886
|
+
* - 'rag': use ragHint to query indexed docs via SL.ai.public.chat()
|
|
1673
1887
|
* - 'hybrid': inject text as context AND ground answers via RAG
|
|
1674
1888
|
*/
|
|
1675
1889
|
strategy?: 'context' | 'rag' | 'hybrid';
|