@proveanything/smartlinks 1.7.5 → 1.7.8
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/api/order.d.ts +16 -105
- package/dist/api/order.js +22 -152
- package/dist/docs/API_SUMMARY.md +219 -117
- package/dist/docs/ai.md +236 -34
- package/dist/openapi.yaml +337 -176
- package/dist/types/ai.d.ts +87 -0
- package/dist/types/order.d.ts +29 -15
- package/docs/API_SUMMARY.md +219 -117
- package/docs/ai.md +236 -34
- package/openapi.yaml +337 -176
- 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,12 @@ 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 googleVisionModels = await ai.models.list('my-collection', {
|
|
353
|
+
provider: 'google',
|
|
354
|
+
capability: 'vision'
|
|
355
|
+
});
|
|
356
|
+
|
|
191
357
|
models.data.forEach(model => {
|
|
192
358
|
console.log(`${model.name}`);
|
|
193
359
|
console.log(` Provider: ${model.provider}`);
|
|
@@ -268,7 +434,7 @@ Users can chat with the product assistant without authentication:
|
|
|
268
434
|
|
|
269
435
|
```typescript
|
|
270
436
|
// First question
|
|
271
|
-
const response = await ai.
|
|
437
|
+
const response = await ai.public.chat('my-collection', {
|
|
272
438
|
productId: 'coffee-maker-deluxe',
|
|
273
439
|
userId: 'user-123',
|
|
274
440
|
message: 'How do I descale my coffee maker?'
|
|
@@ -328,8 +494,31 @@ console.log('Rate-limited users:', stats.rateLimitedUsers);
|
|
|
328
494
|
|
|
329
495
|
Enable voice input and output for hands-free interaction.
|
|
330
496
|
|
|
497
|
+
### Voice Patterns
|
|
498
|
+
|
|
499
|
+
The SDK supports three practical voice patterns:
|
|
500
|
+
|
|
501
|
+
| Pattern | Best For | SDK Building Blocks |
|
|
502
|
+
|---------|----------|---------------------|
|
|
503
|
+
| Voice → Text → AI → Text | Manual helper Q&A, troubleshooting steps | `ai.voice.listen()` + `ai.public.chat()` |
|
|
504
|
+
| Voice → Text → AI → Voice | Hands-free assistants, accessibility | `ai.voice.listen()` + `ai.public.chat()` + `ai.voice.speak()` or `ai.tts.generate()` |
|
|
505
|
+
| Real-time Voice | Low-latency spoken conversation | `ai.public.getToken()` + Gemini Live client |
|
|
506
|
+
|
|
507
|
+
### Current SDK Support
|
|
508
|
+
|
|
509
|
+
- `ai.voice.listen()` and `ai.voice.speak()` are browser helpers built on the Web Speech APIs.
|
|
510
|
+
- `ai.public.getToken()` generates ephemeral tokens for Gemini Live sessions.
|
|
511
|
+
- `ai.tts.generate()` supports server-side text-to-speech generation.
|
|
512
|
+
- 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()`.
|
|
513
|
+
|
|
514
|
+
### Recommended Approach
|
|
515
|
+
|
|
516
|
+
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.
|
|
517
|
+
|
|
331
518
|
### Browser Voice Helpers
|
|
332
519
|
|
|
520
|
+
These helpers are browser-only and rely on native speech recognition / speech synthesis support.
|
|
521
|
+
|
|
333
522
|
```typescript
|
|
334
523
|
// Check if voice is supported
|
|
335
524
|
if (ai.voice.isSupported()) {
|
|
@@ -396,7 +585,7 @@ class ProductVoiceAssistant {
|
|
|
396
585
|
}
|
|
397
586
|
|
|
398
587
|
async getRemainingQuestions(): Promise<number> {
|
|
399
|
-
const status = await ai.
|
|
588
|
+
const status = await ai.public.getRateLimit(this.collectionId, this.userId);
|
|
400
589
|
return status.remaining;
|
|
401
590
|
}
|
|
402
591
|
}
|
|
@@ -417,9 +606,11 @@ console.log(`${remaining} questions remaining`);
|
|
|
417
606
|
|
|
418
607
|
Generate ephemeral tokens for Gemini Live (multimodal voice):
|
|
419
608
|
|
|
609
|
+
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.
|
|
610
|
+
|
|
420
611
|
```typescript
|
|
421
612
|
// Generate token for voice session
|
|
422
|
-
const token = await ai.
|
|
613
|
+
const token = await ai.public.getToken('my-collection', {
|
|
423
614
|
settings: {
|
|
424
615
|
ttl: 3600, // 1 hour
|
|
425
616
|
voice: 'alloy',
|
|
@@ -434,6 +625,17 @@ console.log('Expires at:', new Date(token.expiresAt));
|
|
|
434
625
|
// (See Google's Gemini documentation)
|
|
435
626
|
```
|
|
436
627
|
|
|
628
|
+
### Voice + RAG Guidance
|
|
629
|
+
|
|
630
|
+
For document-grounded assistants, prefer this pattern:
|
|
631
|
+
|
|
632
|
+
1. Capture voice with `ai.voice.listen()` or your own transcription flow.
|
|
633
|
+
2. Send the transcribed text to `ai.public.chat()`.
|
|
634
|
+
3. Render the text response for readability.
|
|
635
|
+
4. Optionally speak the answer with `ai.voice.speak()` or `ai.tts.generate()`.
|
|
636
|
+
|
|
637
|
+
This is usually a better fit for manuals and procedural guidance than trying to use a live voice session as the primary retrieval layer.
|
|
638
|
+
|
|
437
639
|
---
|
|
438
640
|
|
|
439
641
|
## Podcast Generation
|
|
@@ -917,7 +1119,7 @@ const audioBlob = await ai.tts.generate('my-collection', {
|
|
|
917
1119
|
|
|
918
1120
|
### Public Endpoints
|
|
919
1121
|
|
|
920
|
-
#### `ai.
|
|
1122
|
+
#### `ai.public.chat(collectionId, request)`
|
|
921
1123
|
|
|
922
1124
|
Chat with product assistant (no auth required).
|
|
923
1125
|
|
|
@@ -930,7 +1132,7 @@ Chat with product assistant (no auth required).
|
|
|
930
1132
|
|
|
931
1133
|
---
|
|
932
1134
|
|
|
933
|
-
#### `ai.
|
|
1135
|
+
#### `ai.public.getSession(collectionId, sessionId)`
|
|
934
1136
|
|
|
935
1137
|
Get conversation history.
|
|
936
1138
|
|
|
@@ -938,7 +1140,7 @@ Get conversation history.
|
|
|
938
1140
|
|
|
939
1141
|
---
|
|
940
1142
|
|
|
941
|
-
#### `ai.
|
|
1143
|
+
#### `ai.public.clearSession(collectionId, sessionId)`
|
|
942
1144
|
|
|
943
1145
|
Clear conversation history.
|
|
944
1146
|
|
|
@@ -946,7 +1148,7 @@ Clear conversation history.
|
|
|
946
1148
|
|
|
947
1149
|
---
|
|
948
1150
|
|
|
949
|
-
#### `ai.
|
|
1151
|
+
#### `ai.public.getRateLimit(collectionId, userId)`
|
|
950
1152
|
|
|
951
1153
|
Check rate limit status.
|
|
952
1154
|
|
|
@@ -954,7 +1156,7 @@ Check rate limit status.
|
|
|
954
1156
|
|
|
955
1157
|
---
|
|
956
1158
|
|
|
957
|
-
#### `ai.
|
|
1159
|
+
#### `ai.public.getToken(collectionId, request)`
|
|
958
1160
|
|
|
959
1161
|
Generate ephemeral token for Gemini Live.
|
|
960
1162
|
|
|
@@ -985,7 +1187,7 @@ async function createProductFAQ() {
|
|
|
985
1187
|
});
|
|
986
1188
|
|
|
987
1189
|
// 3. Answer user questions
|
|
988
|
-
const answer = await ai.
|
|
1190
|
+
const answer = await ai.public.chat(collectionId, {
|
|
989
1191
|
productId,
|
|
990
1192
|
userId: 'user-123',
|
|
991
1193
|
message: 'How do I make espresso?'
|
|
@@ -1032,7 +1234,7 @@ async function chatConversation() {
|
|
|
1032
1234
|
const productId = 'coffee-maker-deluxe';
|
|
1033
1235
|
|
|
1034
1236
|
// Question 1
|
|
1035
|
-
const a1 = await ai.
|
|
1237
|
+
const a1 = await ai.public.chat(collectionId, {
|
|
1036
1238
|
productId,
|
|
1037
1239
|
userId,
|
|
1038
1240
|
message: 'How do I clean the machine?',
|
|
@@ -1041,7 +1243,7 @@ async function chatConversation() {
|
|
|
1041
1243
|
console.log('A1:', a1.message);
|
|
1042
1244
|
|
|
1043
1245
|
// Question 2 (references previous context)
|
|
1044
|
-
const a2 = await ai.
|
|
1246
|
+
const a2 = await ai.public.chat(collectionId, {
|
|
1045
1247
|
productId,
|
|
1046
1248
|
userId,
|
|
1047
1249
|
message: 'How often should I do that?',
|
|
@@ -1050,7 +1252,7 @@ async function chatConversation() {
|
|
|
1050
1252
|
console.log('A2:', a2.message);
|
|
1051
1253
|
|
|
1052
1254
|
// Get full history
|
|
1053
|
-
const session = await ai.
|
|
1255
|
+
const session = await ai.public.getSession(collectionId, sessionId);
|
|
1054
1256
|
console.log('Full conversation:', session.messages);
|
|
1055
1257
|
}
|
|
1056
1258
|
```
|
|
@@ -1075,7 +1277,7 @@ export function useProductAssistant(
|
|
|
1075
1277
|
setError(null);
|
|
1076
1278
|
|
|
1077
1279
|
try {
|
|
1078
|
-
const response = await ai.
|
|
1280
|
+
const response = await ai.public.chat(collectionId, {
|
|
1079
1281
|
productId,
|
|
1080
1282
|
userId,
|
|
1081
1283
|
message
|
|
@@ -1251,7 +1453,7 @@ import { SmartLinksAIError } from '@proveanything/smartlinks';
|
|
|
1251
1453
|
|
|
1252
1454
|
async function robustChat() {
|
|
1253
1455
|
try {
|
|
1254
|
-
const response = await ai.
|
|
1456
|
+
const response = await ai.public.chat('my-collection', {
|
|
1255
1457
|
productId: 'coffee-maker',
|
|
1256
1458
|
userId: 'user-123',
|
|
1257
1459
|
message: 'Help!'
|
|
@@ -1295,7 +1497,7 @@ async function chatWithRetry(
|
|
|
1295
1497
|
|
|
1296
1498
|
while (retries < maxRetries) {
|
|
1297
1499
|
try {
|
|
1298
|
-
return await ai.
|
|
1500
|
+
return await ai.public.chat('my-collection', request);
|
|
1299
1501
|
} catch (error) {
|
|
1300
1502
|
if (error instanceof SmartLinksAIError && error.isRateLimitError()) {
|
|
1301
1503
|
if (retries === maxRetries - 1) throw error;
|
|
@@ -1345,7 +1547,7 @@ X-RateLimit-Reset: 1707300000000
|
|
|
1345
1547
|
|
|
1346
1548
|
```typescript
|
|
1347
1549
|
// Check rate limit status before making requests
|
|
1348
|
-
const status = await ai.
|
|
1550
|
+
const status = await ai.public.getRateLimit('my-collection', 'user-123');
|
|
1349
1551
|
|
|
1350
1552
|
console.log('Used:', status.used);
|
|
1351
1553
|
console.log('Remaining:', status.remaining);
|
|
@@ -1353,7 +1555,7 @@ console.log('Resets at:', new Date(status.resetAt));
|
|
|
1353
1555
|
|
|
1354
1556
|
if (status.remaining > 0) {
|
|
1355
1557
|
// Safe to make request
|
|
1356
|
-
await ai.
|
|
1558
|
+
await ai.public.chat(/* ... */);
|
|
1357
1559
|
} else {
|
|
1358
1560
|
// Show user when they can ask again
|
|
1359
1561
|
console.log('Rate limit reached. Try again at:', status.resetAt);
|
|
@@ -1443,7 +1645,7 @@ Show clear feedback to users:
|
|
|
1443
1645
|
|
|
1444
1646
|
```typescript
|
|
1445
1647
|
try {
|
|
1446
|
-
await ai.
|
|
1648
|
+
await ai.public.chat('my-collection', {...});
|
|
1447
1649
|
} catch (error) {
|
|
1448
1650
|
if (error instanceof SmartLinksAIError && error.isRateLimitError()) {
|
|
1449
1651
|
const resetTime = new Date(error.resetAt!);
|
|
@@ -1649,7 +1851,7 @@ interface AIContentResponse {
|
|
|
1649
1851
|
|
|
1650
1852
|
/**
|
|
1651
1853
|
* Pre-built RAG configuration. When provided, the assistant can use
|
|
1652
|
-
|
|
1854
|
+
* SL.ai.public.chat() to ground answers in indexed product documents.
|
|
1653
1855
|
*/
|
|
1654
1856
|
ragHint?: {
|
|
1655
1857
|
/** The product ID whose indexed documents should be queried */
|
|
@@ -1669,7 +1871,7 @@ interface AIContentResponse {
|
|
|
1669
1871
|
/**
|
|
1670
1872
|
* How the assistant should use this content:
|
|
1671
1873
|
* - 'context' (default): inject text into the system prompt
|
|
1672
|
-
|
|
1874
|
+
* - 'rag': use ragHint to query indexed docs via SL.ai.public.chat()
|
|
1673
1875
|
* - 'hybrid': inject text as context AND ground answers via RAG
|
|
1674
1876
|
*/
|
|
1675
1877
|
strategy?: 'context' | 'rag' | 'hybrid';
|