@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 CHANGED
@@ -10,6 +10,30 @@ Build Smartlinks-powered apps in Node.js or the browser: list collections and pr
10
10
  • Rich resources: collections, products, proofs, assets, attestations, batches, variants, AI, and more
11
11
  • Optional iframe proxy mode for embedded apps
12
12
 
13
+ ## Start here
14
+
15
+ If you're new to the SDK, this is the easiest path:
16
+
17
+ 1. Initialize the SDK with your SmartLinks API base URL.
18
+ 2. Pick the guide that matches what you're building.
19
+ 3. Copy one of the working examples and adapt it to your collection/product IDs.
20
+
21
+ ### Pick a guide
22
+
23
+ - [docs/ai.md](docs/ai.md) — AI responses, chat, RAG, voice, streaming, and product assistants
24
+ - [docs/widgets.md](docs/widgets.md) — embeddable React components
25
+ - [docs/realtime.md](docs/realtime.md) — subscriptions and live updates
26
+ - [docs/iframe-responder.md](docs/iframe-responder.md) — iframe integration and parent/child messaging
27
+ - [docs/utils.md](docs/utils.md) — helper utilities and portal path generation
28
+
29
+ ### Most common use cases
30
+
31
+ - **Build an AI assistant** → start with [docs/ai.md](docs/ai.md)
32
+ - **Fetch collections/products** → see [Quick start](README.md#quick-start)
33
+ - **Authenticate admins or end users** → see [Authentication](README.md#authentication)
34
+ - **Upload and manage files** → see [Assets](README.md#assets)
35
+ - **Browse the full surface area** → use [API_SUMMARY.md](API_SUMMARY.md) as reference
36
+
13
37
  For the full list of functions and types, see the API summary:
14
38
  → [API Summary](API_SUMMARY.md)
15
39
 
@@ -55,6 +79,50 @@ if (first) {
55
79
  }
56
80
  ```
57
81
 
82
+ ### Quick start by scenario
83
+
84
+ **Public storefront or portal experience**
85
+
86
+ ```ts
87
+ import { initializeApi, collection, product } from '@proveanything/smartlinks'
88
+
89
+ initializeApi({ baseURL: 'https://smartlinks.app/api/v1' })
90
+
91
+ const collections = await collection.list(false)
92
+ const products = await product.list('collectionId', false)
93
+ ```
94
+
95
+ **Server-side admin scripts or back office tools**
96
+
97
+ ```ts
98
+ import { initializeApi, product } from '@proveanything/smartlinks'
99
+
100
+ initializeApi({
101
+ baseURL: 'https://smartlinks.app/api/v1',
102
+ apiKey: process.env.SMARTLINKS_API_KEY,
103
+ })
104
+
105
+ const created = await product.create('collectionId', { name: 'New product' })
106
+ console.log(created.id)
107
+ ```
108
+
109
+ **AI-powered assistant or setup flow**
110
+
111
+ ```ts
112
+ import { initializeApi, ai } from '@proveanything/smartlinks'
113
+
114
+ initializeApi({
115
+ baseURL: 'https://smartlinks.app/api/v1',
116
+ apiKey: process.env.SMARTLINKS_API_KEY,
117
+ })
118
+
119
+ const response = await ai.chat.responses.create('collectionId', {
120
+ input: 'Write a concise onboarding checklist for a new product launch.'
121
+ })
122
+
123
+ console.log(response.output_text)
124
+ ```
125
+
58
126
  ## Authentication
59
127
 
60
128
  Use the built-in helpers to log in and verify tokens. After a successful login, the SDK stores the bearer token for subsequent calls.
package/dist/api/ai.d.ts CHANGED
@@ -1,7 +1,16 @@
1
- import type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateImageRequest, AISearchPhotosRequest, AISearchPhotosPhoto } from "../types/ai";
2
- export type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateImageRequest, AISearchPhotosRequest, AISearchPhotosPhoto, };
3
- export declare namespace ai {
1
+ import type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ResponseTool, ResponseInputItem, ResponsesRequest, ResponsesResult, ResponsesStreamEvent, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, AIModelListParams, AIModelListResponse, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateImageRequest, AISearchPhotosRequest, AISearchPhotosPhoto } from "../types/ai";
2
+ export type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ResponseTool, ResponseInputItem, ResponsesRequest, ResponsesResult, ResponsesStreamEvent, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, AIModelListParams, AIModelListResponse, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateImageRequest, AISearchPhotosRequest, AISearchPhotosPhoto, };
3
+ declare namespace aiInternal {
4
4
  namespace chat {
5
+ namespace responses {
6
+ /**
7
+ * Create a Responses API request (streaming or non-streaming)
8
+ * @param collectionId - Collection identifier
9
+ * @param request - Responses API request
10
+ * @returns Responses API result or async iterable for streaming events
11
+ */
12
+ function create(collectionId: string, request: ResponsesRequest): Promise<ResponsesResult | AsyncIterable<ResponsesStreamEvent>>;
13
+ }
5
14
  namespace completions {
6
15
  /**
7
16
  * Create a chat completion (streaming or non-streaming)
@@ -16,10 +25,7 @@ export declare namespace ai {
16
25
  /**
17
26
  * List available AI models
18
27
  */
19
- function list(collectionId: string): Promise<{
20
- object: 'list';
21
- data: AIModel[];
22
- }>;
28
+ function list(collectionId: string, params?: AIModelListParams): Promise<AIModelListResponse>;
23
29
  /**
24
30
  * Get specific model information
25
31
  */
@@ -66,7 +72,7 @@ export declare namespace ai {
66
72
  */
67
73
  function generate(collectionId: string, request: TTSRequest): Promise<Blob>;
68
74
  }
69
- namespace publicApi {
75
+ namespace publicClient {
70
76
  /**
71
77
  * Chat with product assistant (RAG)
72
78
  */
@@ -133,3 +139,52 @@ export declare namespace ai {
133
139
  */
134
140
  function postChat(collectionId: string, params: any, admin?: boolean): Promise<any>;
135
141
  }
142
+ export declare const ai: {
143
+ chat: {
144
+ responses: {
145
+ create: typeof aiInternal.chat.responses.create;
146
+ };
147
+ completions: {
148
+ create: typeof aiInternal.chat.completions.create;
149
+ };
150
+ };
151
+ models: {
152
+ list: typeof aiInternal.models.list;
153
+ get: typeof aiInternal.models.get;
154
+ };
155
+ rag: {
156
+ indexDocument: typeof aiInternal.rag.indexDocument;
157
+ configureAssistant: typeof aiInternal.rag.configureAssistant;
158
+ };
159
+ sessions: {
160
+ stats: typeof aiInternal.sessions.stats;
161
+ };
162
+ rateLimit: {
163
+ reset: typeof aiInternal.rateLimit.reset;
164
+ };
165
+ podcast: {
166
+ generate: typeof aiInternal.podcast.generate;
167
+ getStatus: typeof aiInternal.podcast.getStatus;
168
+ };
169
+ tts: {
170
+ generate: typeof aiInternal.tts.generate;
171
+ };
172
+ public: {
173
+ chat: typeof aiInternal.publicClient.chat;
174
+ getSession: typeof aiInternal.publicClient.getSession;
175
+ clearSession: typeof aiInternal.publicClient.clearSession;
176
+ getRateLimit: typeof aiInternal.publicClient.getRateLimit;
177
+ getToken: typeof aiInternal.publicClient.getToken;
178
+ };
179
+ voice: {
180
+ isSupported: typeof aiInternal.voice.isSupported;
181
+ listen: typeof aiInternal.voice.listen;
182
+ speak: typeof aiInternal.voice.speak;
183
+ };
184
+ generateContent: typeof aiInternal.generateContent;
185
+ generateImage: typeof aiInternal.generateImage;
186
+ searchPhotos: typeof aiInternal.searchPhotos;
187
+ uploadFile: typeof aiInternal.uploadFile;
188
+ createCache: typeof aiInternal.createCache;
189
+ postChat: typeof aiInternal.postChat;
190
+ };
package/dist/api/ai.js CHANGED
@@ -1,13 +1,137 @@
1
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
2
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
3
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
5
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
6
+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
7
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
8
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
9
+ function fulfill(value) { resume("next", value); }
10
+ function reject(value) { resume("throw", value); }
11
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
12
+ };
1
13
  // src/api/ai.ts
2
14
  // AI endpoints: public and admin helpers
3
- import { post, request, del } from "../http";
4
- export var ai;
5
- (function (ai) {
15
+ import { post, request, del, getBaseURL, getApiHeaders } from "../http";
16
+ import { SmartlinksApiError } from "../types/error";
17
+ function encodeQueryParams(params) {
18
+ if (!params)
19
+ return '';
20
+ const query = new URLSearchParams();
21
+ Object.entries(params).forEach(([key, value]) => {
22
+ if (value)
23
+ query.append(key, value);
24
+ });
25
+ const search = query.toString();
26
+ return search ? `?${search}` : '';
27
+ }
28
+ async function createSseStream(path, body) {
29
+ var _a, _b, _c;
30
+ const baseURL = getBaseURL();
31
+ if (!baseURL) {
32
+ throw new Error('HTTP client is not initialized. Call initializeApi(...) first.');
33
+ }
34
+ const url = `${baseURL}${path}`;
35
+ const headers = Object.assign({ Accept: 'text/event-stream', 'Content-Type': 'application/json' }, getApiHeaders());
36
+ const response = await fetch(url, {
37
+ method: 'POST',
38
+ headers,
39
+ body: JSON.stringify(body),
40
+ });
41
+ if (!response.ok) {
42
+ let responseBody;
43
+ try {
44
+ responseBody = await response.json();
45
+ }
46
+ catch (_d) {
47
+ responseBody = null;
48
+ }
49
+ const code = response.status;
50
+ const message = (responseBody === null || responseBody === void 0 ? void 0 : responseBody.message) || ((_a = responseBody === null || responseBody === void 0 ? void 0 : responseBody.error) === null || _a === void 0 ? void 0 : _a.message) || `Request failed with status ${code}`;
51
+ throw new SmartlinksApiError(`Error ${code}: ${message}`, code, {
52
+ code,
53
+ errorCode: ((_b = responseBody === null || responseBody === void 0 ? void 0 : responseBody.error) === null || _b === void 0 ? void 0 : _b.code) || (responseBody === null || responseBody === void 0 ? void 0 : responseBody.errorCode),
54
+ message,
55
+ details: ((_c = responseBody === null || responseBody === void 0 ? void 0 : responseBody.error) === null || _c === void 0 ? void 0 : _c.details) || (responseBody === null || responseBody === void 0 ? void 0 : responseBody.details),
56
+ }, url);
57
+ }
58
+ if (!response.body) {
59
+ throw new Error('Streaming response body is unavailable in this environment');
60
+ }
61
+ return parseSseStream(response.body);
62
+ }
63
+ function parseSseStream(stream) {
64
+ return __asyncGenerator(this, arguments, function* parseSseStream_1() {
65
+ const reader = stream.getReader();
66
+ const decoder = new TextDecoder();
67
+ let buffer = '';
68
+ let dataLines = [];
69
+ while (true) {
70
+ const { done, value } = yield __await(reader.read());
71
+ if (done)
72
+ break;
73
+ buffer += decoder.decode(value, { stream: true });
74
+ const lines = buffer.split(/\r?\n/);
75
+ buffer = lines.pop() || '';
76
+ for (const rawLine of lines) {
77
+ const line = rawLine.trimEnd();
78
+ if (!line) {
79
+ if (!dataLines.length)
80
+ continue;
81
+ const payload = dataLines.join('\n');
82
+ dataLines = [];
83
+ if (payload === '[DONE]')
84
+ return yield __await(void 0);
85
+ try {
86
+ yield yield __await(JSON.parse(payload));
87
+ }
88
+ catch (_a) {
89
+ continue;
90
+ }
91
+ continue;
92
+ }
93
+ if (line.startsWith('data:')) {
94
+ dataLines.push(line.slice(5).trimStart());
95
+ }
96
+ }
97
+ }
98
+ if (dataLines.length) {
99
+ const payload = dataLines.join('\n');
100
+ if (payload !== '[DONE]') {
101
+ try {
102
+ yield yield __await(JSON.parse(payload));
103
+ }
104
+ catch (_b) {
105
+ return yield __await(void 0);
106
+ }
107
+ }
108
+ }
109
+ });
110
+ }
111
+ var aiInternal;
112
+ (function (aiInternal) {
6
113
  // ============================================================================
7
- // Chat Completions API (OpenAI-compatible)
114
+ // Chat APIs
8
115
  // ============================================================================
9
116
  let chat;
10
117
  (function (chat) {
118
+ let responses;
119
+ (function (responses) {
120
+ /**
121
+ * Create a Responses API request (streaming or non-streaming)
122
+ * @param collectionId - Collection identifier
123
+ * @param request - Responses API request
124
+ * @returns Responses API result or async iterable for streaming events
125
+ */
126
+ async function create(collectionId, request) {
127
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/v1/responses`;
128
+ if (request.stream) {
129
+ return createSseStream(path, request);
130
+ }
131
+ return post(path, request);
132
+ }
133
+ responses.create = create;
134
+ })(responses = chat.responses || (chat.responses = {}));
11
135
  let completions;
12
136
  (function (completions) {
13
137
  /**
@@ -19,14 +143,13 @@ export var ai;
19
143
  async function create(collectionId, request) {
20
144
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/v1/chat/completions`;
21
145
  if (request.stream) {
22
- // TODO: Implement streaming via SSE
23
- throw new Error('Streaming not yet implemented');
146
+ return createSseStream(path, request);
24
147
  }
25
148
  return post(path, request);
26
149
  }
27
150
  completions.create = create;
28
151
  })(completions = chat.completions || (chat.completions = {}));
29
- })(chat = ai.chat || (ai.chat = {}));
152
+ })(chat = aiInternal.chat || (aiInternal.chat = {}));
30
153
  // ============================================================================
31
154
  // Models API
32
155
  // ============================================================================
@@ -35,8 +158,11 @@ export var ai;
35
158
  /**
36
159
  * List available AI models
37
160
  */
38
- async function list(collectionId) {
39
- const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/models`;
161
+ async function list(collectionId, params) {
162
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/models${encodeQueryParams({
163
+ provider: params === null || params === void 0 ? void 0 : params.provider,
164
+ capability: params === null || params === void 0 ? void 0 : params.capability,
165
+ })}`;
40
166
  return request(path);
41
167
  }
42
168
  models.list = list;
@@ -48,7 +174,7 @@ export var ai;
48
174
  return request(path);
49
175
  }
50
176
  models.get = get;
51
- })(models = ai.models || (ai.models = {}));
177
+ })(models = aiInternal.models || (aiInternal.models = {}));
52
178
  // ============================================================================
53
179
  // RAG API
54
180
  // ============================================================================
@@ -70,7 +196,7 @@ export var ai;
70
196
  return post(path, request);
71
197
  }
72
198
  rag.configureAssistant = configureAssistant;
73
- })(rag = ai.rag || (ai.rag = {}));
199
+ })(rag = aiInternal.rag || (aiInternal.rag = {}));
74
200
  // ============================================================================
75
201
  // Sessions API
76
202
  // ============================================================================
@@ -84,7 +210,7 @@ export var ai;
84
210
  return request(path);
85
211
  }
86
212
  sessions.stats = stats;
87
- })(sessions = ai.sessions || (ai.sessions = {}));
213
+ })(sessions = aiInternal.sessions || (aiInternal.sessions = {}));
88
214
  // ============================================================================
89
215
  // Rate Limiting API
90
216
  // ============================================================================
@@ -98,7 +224,7 @@ export var ai;
98
224
  return post(path, {});
99
225
  }
100
226
  rateLimit.reset = reset;
101
- })(rateLimit = ai.rateLimit || (ai.rateLimit = {}));
227
+ })(rateLimit = aiInternal.rateLimit || (aiInternal.rateLimit = {}));
102
228
  // ============================================================================
103
229
  // Podcast API
104
230
  // ============================================================================
@@ -120,7 +246,7 @@ export var ai;
120
246
  return request(path);
121
247
  }
122
248
  podcast.getStatus = getStatus;
123
- })(podcast = ai.podcast || (ai.podcast = {}));
249
+ })(podcast = aiInternal.podcast || (aiInternal.podcast = {}));
124
250
  // ============================================================================
125
251
  // TTS API
126
252
  // ============================================================================
@@ -135,12 +261,12 @@ export var ai;
135
261
  return post(path, request);
136
262
  }
137
263
  tts.generate = generate;
138
- })(tts = ai.tts || (ai.tts = {}));
264
+ })(tts = aiInternal.tts || (aiInternal.tts = {}));
139
265
  // ============================================================================
140
266
  // Public API (no authentication required)
141
267
  // ============================================================================
142
- let publicApi;
143
- (function (publicApi) {
268
+ let publicClient;
269
+ (function (publicClient) {
144
270
  /**
145
271
  * Chat with product assistant (RAG)
146
272
  */
@@ -148,7 +274,7 @@ export var ai;
148
274
  const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/chat`;
149
275
  return post(path, request);
150
276
  }
151
- publicApi.chat = chat;
277
+ publicClient.chat = chat;
152
278
  /**
153
279
  * Get session history
154
280
  */
@@ -156,7 +282,7 @@ export var ai;
156
282
  const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/session/${encodeURIComponent(sessionId)}`;
157
283
  return request(path);
158
284
  }
159
- publicApi.getSession = getSession;
285
+ publicClient.getSession = getSession;
160
286
  /**
161
287
  * Clear session history
162
288
  */
@@ -164,7 +290,7 @@ export var ai;
164
290
  const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/session/${encodeURIComponent(sessionId)}`;
165
291
  return del(path);
166
292
  }
167
- publicApi.clearSession = clearSession;
293
+ publicClient.clearSession = clearSession;
168
294
  /**
169
295
  * Check rate limit status
170
296
  */
@@ -172,7 +298,7 @@ export var ai;
172
298
  const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/rate-limit/${encodeURIComponent(userId)}`;
173
299
  return request(path);
174
300
  }
175
- publicApi.getRateLimit = getRateLimit;
301
+ publicClient.getRateLimit = getRateLimit;
176
302
  /**
177
303
  * Generate ephemeral token for Gemini Live
178
304
  */
@@ -180,8 +306,8 @@ export var ai;
180
306
  const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/token`;
181
307
  return post(path, request);
182
308
  }
183
- publicApi.getToken = getToken;
184
- })(publicApi = ai.publicApi || (ai.publicApi = {}));
309
+ publicClient.getToken = getToken;
310
+ })(publicClient = aiInternal.publicClient || (aiInternal.publicClient = {}));
185
311
  // ============================================================================
186
312
  // Voice Helpers (Browser-only)
187
313
  // ============================================================================
@@ -245,7 +371,7 @@ export var ai;
245
371
  });
246
372
  }
247
373
  voice_1.speak = speak;
248
- })(voice = ai.voice || (ai.voice = {}));
374
+ })(voice = aiInternal.voice || (aiInternal.voice = {}));
249
375
  // ============================================================================
250
376
  // Legacy Methods (backwards compatibility)
251
377
  // ============================================================================
@@ -258,7 +384,7 @@ export var ai;
258
384
  const path = `${base}/collection/${encodeURIComponent(collectionId)}/ai/generateContent`;
259
385
  return post(path, params);
260
386
  }
261
- ai.generateContent = generateContent;
387
+ aiInternal.generateContent = generateContent;
262
388
  /**
263
389
  * Generate an image via AI (admin)
264
390
  */
@@ -266,7 +392,7 @@ export var ai;
266
392
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/generateImage`;
267
393
  return post(path, params);
268
394
  }
269
- ai.generateImage = generateImage;
395
+ aiInternal.generateImage = generateImage;
270
396
  /**
271
397
  * Search stock photos or similar via AI (admin)
272
398
  */
@@ -274,7 +400,7 @@ export var ai;
274
400
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/searchPhotos`;
275
401
  return post(path, params);
276
402
  }
277
- ai.searchPhotos = searchPhotos;
403
+ aiInternal.searchPhotos = searchPhotos;
278
404
  /**
279
405
  * Upload a file for AI usage (admin). Pass FormData for binary uploads.
280
406
  */
@@ -282,7 +408,7 @@ export var ai;
282
408
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/uploadFile`;
283
409
  return post(path, params);
284
410
  }
285
- ai.uploadFile = uploadFile;
411
+ aiInternal.uploadFile = uploadFile;
286
412
  /**
287
413
  * Create or warm a cache for AI (admin)
288
414
  */
@@ -290,7 +416,7 @@ export var ai;
290
416
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/createCache`;
291
417
  return post(path, params);
292
418
  }
293
- ai.createCache = createCache;
419
+ aiInternal.createCache = createCache;
294
420
  /**
295
421
  * Post a chat message to the AI (admin or public)
296
422
  */
@@ -299,5 +425,54 @@ export var ai;
299
425
  const path = `${base}/collection/${encodeURIComponent(collectionId)}/ai/postChat`;
300
426
  return post(path, params);
301
427
  }
302
- ai.postChat = postChat;
303
- })(ai || (ai = {}));
428
+ aiInternal.postChat = postChat;
429
+ })(aiInternal || (aiInternal = {}));
430
+ export const ai = {
431
+ chat: {
432
+ responses: {
433
+ create: aiInternal.chat.responses.create,
434
+ },
435
+ completions: {
436
+ create: aiInternal.chat.completions.create,
437
+ },
438
+ },
439
+ models: {
440
+ list: aiInternal.models.list,
441
+ get: aiInternal.models.get,
442
+ },
443
+ rag: {
444
+ indexDocument: aiInternal.rag.indexDocument,
445
+ configureAssistant: aiInternal.rag.configureAssistant,
446
+ },
447
+ sessions: {
448
+ stats: aiInternal.sessions.stats,
449
+ },
450
+ rateLimit: {
451
+ reset: aiInternal.rateLimit.reset,
452
+ },
453
+ podcast: {
454
+ generate: aiInternal.podcast.generate,
455
+ getStatus: aiInternal.podcast.getStatus,
456
+ },
457
+ tts: {
458
+ generate: aiInternal.tts.generate,
459
+ },
460
+ public: {
461
+ chat: aiInternal.publicClient.chat,
462
+ getSession: aiInternal.publicClient.getSession,
463
+ clearSession: aiInternal.publicClient.clearSession,
464
+ getRateLimit: aiInternal.publicClient.getRateLimit,
465
+ getToken: aiInternal.publicClient.getToken,
466
+ },
467
+ voice: {
468
+ isSupported: aiInternal.voice.isSupported,
469
+ listen: aiInternal.voice.listen,
470
+ speak: aiInternal.voice.speak,
471
+ },
472
+ generateContent: aiInternal.generateContent,
473
+ generateImage: aiInternal.generateImage,
474
+ searchPhotos: aiInternal.searchPhotos,
475
+ uploadFile: aiInternal.uploadFile,
476
+ createCache: aiInternal.createCache,
477
+ postChat: aiInternal.postChat,
478
+ };