@reverbia/sdk 1.0.0-next.20251209090511 → 1.0.0-next.20251209143100

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.
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  useChat: () => useChat,
24
- useImageGeneration: () => useImageGeneration
24
+ useImageGeneration: () => useImageGeneration,
25
+ useModels: () => useModels
25
26
  });
26
27
  module.exports = __toCommonJS(index_exports);
27
28
 
@@ -1129,6 +1130,12 @@ var postApiV1ImagesGenerations = (options) => {
1129
1130
  }
1130
1131
  });
1131
1132
  };
1133
+ var getApiV1Models = (options) => {
1134
+ return (options?.client ?? client).get({
1135
+ url: "/api/v1/models",
1136
+ ...options
1137
+ });
1138
+ };
1132
1139
 
1133
1140
  // src/react/useImageGeneration.ts
1134
1141
  function useImageGeneration(options = {}) {
@@ -1210,8 +1217,113 @@ function useImageGeneration(options = {}) {
1210
1217
  stop
1211
1218
  };
1212
1219
  }
1220
+
1221
+ // src/react/useModels.ts
1222
+ var import_react3 = require("react");
1223
+ function useModels(options = {}) {
1224
+ const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
1225
+ const [models, setModels] = (0, import_react3.useState)([]);
1226
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
1227
+ const [error, setError] = (0, import_react3.useState)(null);
1228
+ const getTokenRef = (0, import_react3.useRef)(getToken);
1229
+ const baseUrlRef = (0, import_react3.useRef)(baseUrl);
1230
+ const providerRef = (0, import_react3.useRef)(provider);
1231
+ const abortControllerRef = (0, import_react3.useRef)(null);
1232
+ (0, import_react3.useEffect)(() => {
1233
+ getTokenRef.current = getToken;
1234
+ baseUrlRef.current = baseUrl;
1235
+ providerRef.current = provider;
1236
+ });
1237
+ (0, import_react3.useEffect)(() => {
1238
+ return () => {
1239
+ if (abortControllerRef.current) {
1240
+ abortControllerRef.current.abort();
1241
+ abortControllerRef.current = null;
1242
+ }
1243
+ };
1244
+ }, []);
1245
+ const fetchModels = (0, import_react3.useCallback)(async () => {
1246
+ if (abortControllerRef.current) {
1247
+ abortControllerRef.current.abort();
1248
+ }
1249
+ const abortController = new AbortController();
1250
+ abortControllerRef.current = abortController;
1251
+ const signal = abortController.signal;
1252
+ setIsLoading(true);
1253
+ setError(null);
1254
+ try {
1255
+ let token;
1256
+ if (getTokenRef.current) {
1257
+ token = await getTokenRef.current() ?? void 0;
1258
+ }
1259
+ if (signal.aborted) return;
1260
+ const headers = {};
1261
+ if (token) {
1262
+ headers["Authorization"] = `Bearer ${token}`;
1263
+ }
1264
+ let allModels = [];
1265
+ let nextPageToken;
1266
+ do {
1267
+ if (signal.aborted) return;
1268
+ const response = await getApiV1Models({
1269
+ baseUrl: baseUrlRef.current,
1270
+ headers,
1271
+ query: {
1272
+ provider: providerRef.current,
1273
+ page_token: nextPageToken
1274
+ },
1275
+ signal
1276
+ });
1277
+ if (response.error) {
1278
+ const errorMsg = response.error.error ?? "Failed to fetch models";
1279
+ throw new Error(errorMsg);
1280
+ }
1281
+ if (response.data) {
1282
+ const newModels = response.data.data || [];
1283
+ allModels = [...allModels, ...newModels];
1284
+ nextPageToken = response.data.next_page_token;
1285
+ }
1286
+ } while (nextPageToken);
1287
+ if (signal.aborted) return;
1288
+ setModels(allModels);
1289
+ } catch (err) {
1290
+ if (err instanceof Error && err.name === "AbortError") {
1291
+ return;
1292
+ }
1293
+ setError(err instanceof Error ? err : new Error(String(err)));
1294
+ } finally {
1295
+ if (!signal.aborted) {
1296
+ setIsLoading(false);
1297
+ }
1298
+ if (abortControllerRef.current === abortController) {
1299
+ abortControllerRef.current = null;
1300
+ }
1301
+ }
1302
+ }, []);
1303
+ const refetch = (0, import_react3.useCallback)(async () => {
1304
+ setModels([]);
1305
+ await fetchModels();
1306
+ }, [fetchModels]);
1307
+ const hasFetchedRef = (0, import_react3.useRef)(false);
1308
+ (0, import_react3.useEffect)(() => {
1309
+ if (autoFetch && !hasFetchedRef.current) {
1310
+ hasFetchedRef.current = true;
1311
+ fetchModels();
1312
+ }
1313
+ if (!autoFetch) {
1314
+ hasFetchedRef.current = false;
1315
+ }
1316
+ }, [autoFetch, fetchModels]);
1317
+ return {
1318
+ models,
1319
+ isLoading,
1320
+ error,
1321
+ refetch
1322
+ };
1323
+ }
1213
1324
  // Annotate the CommonJS export names for ESM import in node:
1214
1325
  0 && (module.exports = {
1215
1326
  useChat,
1216
- useImageGeneration
1327
+ useImageGeneration,
1328
+ useModels
1217
1329
  });
@@ -191,6 +191,99 @@ type LlmapiMessageContentPart = {
191
191
  */
192
192
  type?: string;
193
193
  };
194
+ type LlmapiModel = {
195
+ architecture?: LlmapiModelArchitecture;
196
+ /**
197
+ * CanonicalSlug is the canonical slug for the model
198
+ */
199
+ canonical_slug?: string;
200
+ /**
201
+ * ContextLength is the maximum context length in tokens
202
+ */
203
+ context_length?: number;
204
+ /**
205
+ * Created is the Unix timestamp of when the model was created
206
+ */
207
+ created?: number;
208
+ /**
209
+ * DefaultParameters contains default parameter values
210
+ */
211
+ default_parameters?: {
212
+ [key: string]: unknown;
213
+ };
214
+ /**
215
+ * Description describes the model and its capabilities
216
+ */
217
+ description?: string;
218
+ /**
219
+ * HuggingFaceID is the Hugging Face model identifier
220
+ */
221
+ hugging_face_id?: string;
222
+ /**
223
+ * ID is the model identifier (e.g., "openai/gpt-4")
224
+ */
225
+ id?: string;
226
+ /**
227
+ * MaxInputTokens is the maximum input tokens
228
+ */
229
+ max_input_tokens?: number;
230
+ /**
231
+ * MaxOutputTokens is the maximum output tokens
232
+ */
233
+ max_output_tokens?: number;
234
+ /**
235
+ * Name is the human-readable model name (optional)
236
+ */
237
+ name?: string;
238
+ /**
239
+ * OwnedBy is the organization that owns the model
240
+ */
241
+ owned_by?: string;
242
+ per_request_limits?: LlmapiModelPerRequestLimits;
243
+ pricing?: LlmapiModelPricing;
244
+ /**
245
+ * SupportedMethods is a list of supported API methods
246
+ */
247
+ supported_methods?: Array<string>;
248
+ /**
249
+ * SupportedParameters is a list of supported parameter names
250
+ */
251
+ supported_parameters?: Array<string>;
252
+ top_provider?: LlmapiModelTopProvider;
253
+ };
254
+ /**
255
+ * Architecture describes the model's technical capabilities
256
+ */
257
+ type LlmapiModelArchitecture = {
258
+ instruct_type?: string;
259
+ modality?: string;
260
+ prompt_formatting?: string;
261
+ tokenizer?: string;
262
+ };
263
+ /**
264
+ * PerRequestLimits contains rate limiting information
265
+ */
266
+ type LlmapiModelPerRequestLimits = {
267
+ completion_tokens?: number;
268
+ prompt_tokens?: number;
269
+ };
270
+ /**
271
+ * Pricing contains the pricing structure for using this model
272
+ */
273
+ type LlmapiModelPricing = {
274
+ completion?: string;
275
+ image?: string;
276
+ prompt?: string;
277
+ request?: string;
278
+ };
279
+ /**
280
+ * TopProvider contains configuration details for the primary provider
281
+ */
282
+ type LlmapiModelTopProvider = {
283
+ context_length?: number;
284
+ is_moderated?: boolean;
285
+ max_completion_tokens?: number;
286
+ };
194
287
  /**
195
288
  * Role is the message role (system, user, assistant)
196
289
  */
@@ -340,4 +433,34 @@ type UseImageGenerationResult = {
340
433
  */
341
434
  declare function useImageGeneration(options?: UseImageGenerationOptions): UseImageGenerationResult;
342
435
 
343
- export { useChat, useImageGeneration };
436
+ type UseModelsOptions = {
437
+ /**
438
+ * Custom function to get auth token for API calls
439
+ */
440
+ getToken?: () => Promise<string | null>;
441
+ /**
442
+ * Optional base URL for the API requests.
443
+ */
444
+ baseUrl?: string;
445
+ /**
446
+ * Optional filter for specific provider (e.g. "openai")
447
+ */
448
+ provider?: string;
449
+ /**
450
+ * Whether to fetch models automatically on mount (default: true)
451
+ */
452
+ autoFetch?: boolean;
453
+ };
454
+ type UseModelsResult = {
455
+ models: LlmapiModel[];
456
+ isLoading: boolean;
457
+ error: Error | null;
458
+ refetch: () => Promise<void>;
459
+ };
460
+ /**
461
+ * React hook for fetching available LLM models.
462
+ * Automatically fetches all available models.
463
+ */
464
+ declare function useModels(options?: UseModelsOptions): UseModelsResult;
465
+
466
+ export { type UseModelsOptions, type UseModelsResult, useChat, useImageGeneration, useModels };
@@ -191,6 +191,99 @@ type LlmapiMessageContentPart = {
191
191
  */
192
192
  type?: string;
193
193
  };
194
+ type LlmapiModel = {
195
+ architecture?: LlmapiModelArchitecture;
196
+ /**
197
+ * CanonicalSlug is the canonical slug for the model
198
+ */
199
+ canonical_slug?: string;
200
+ /**
201
+ * ContextLength is the maximum context length in tokens
202
+ */
203
+ context_length?: number;
204
+ /**
205
+ * Created is the Unix timestamp of when the model was created
206
+ */
207
+ created?: number;
208
+ /**
209
+ * DefaultParameters contains default parameter values
210
+ */
211
+ default_parameters?: {
212
+ [key: string]: unknown;
213
+ };
214
+ /**
215
+ * Description describes the model and its capabilities
216
+ */
217
+ description?: string;
218
+ /**
219
+ * HuggingFaceID is the Hugging Face model identifier
220
+ */
221
+ hugging_face_id?: string;
222
+ /**
223
+ * ID is the model identifier (e.g., "openai/gpt-4")
224
+ */
225
+ id?: string;
226
+ /**
227
+ * MaxInputTokens is the maximum input tokens
228
+ */
229
+ max_input_tokens?: number;
230
+ /**
231
+ * MaxOutputTokens is the maximum output tokens
232
+ */
233
+ max_output_tokens?: number;
234
+ /**
235
+ * Name is the human-readable model name (optional)
236
+ */
237
+ name?: string;
238
+ /**
239
+ * OwnedBy is the organization that owns the model
240
+ */
241
+ owned_by?: string;
242
+ per_request_limits?: LlmapiModelPerRequestLimits;
243
+ pricing?: LlmapiModelPricing;
244
+ /**
245
+ * SupportedMethods is a list of supported API methods
246
+ */
247
+ supported_methods?: Array<string>;
248
+ /**
249
+ * SupportedParameters is a list of supported parameter names
250
+ */
251
+ supported_parameters?: Array<string>;
252
+ top_provider?: LlmapiModelTopProvider;
253
+ };
254
+ /**
255
+ * Architecture describes the model's technical capabilities
256
+ */
257
+ type LlmapiModelArchitecture = {
258
+ instruct_type?: string;
259
+ modality?: string;
260
+ prompt_formatting?: string;
261
+ tokenizer?: string;
262
+ };
263
+ /**
264
+ * PerRequestLimits contains rate limiting information
265
+ */
266
+ type LlmapiModelPerRequestLimits = {
267
+ completion_tokens?: number;
268
+ prompt_tokens?: number;
269
+ };
270
+ /**
271
+ * Pricing contains the pricing structure for using this model
272
+ */
273
+ type LlmapiModelPricing = {
274
+ completion?: string;
275
+ image?: string;
276
+ prompt?: string;
277
+ request?: string;
278
+ };
279
+ /**
280
+ * TopProvider contains configuration details for the primary provider
281
+ */
282
+ type LlmapiModelTopProvider = {
283
+ context_length?: number;
284
+ is_moderated?: boolean;
285
+ max_completion_tokens?: number;
286
+ };
194
287
  /**
195
288
  * Role is the message role (system, user, assistant)
196
289
  */
@@ -340,4 +433,34 @@ type UseImageGenerationResult = {
340
433
  */
341
434
  declare function useImageGeneration(options?: UseImageGenerationOptions): UseImageGenerationResult;
342
435
 
343
- export { useChat, useImageGeneration };
436
+ type UseModelsOptions = {
437
+ /**
438
+ * Custom function to get auth token for API calls
439
+ */
440
+ getToken?: () => Promise<string | null>;
441
+ /**
442
+ * Optional base URL for the API requests.
443
+ */
444
+ baseUrl?: string;
445
+ /**
446
+ * Optional filter for specific provider (e.g. "openai")
447
+ */
448
+ provider?: string;
449
+ /**
450
+ * Whether to fetch models automatically on mount (default: true)
451
+ */
452
+ autoFetch?: boolean;
453
+ };
454
+ type UseModelsResult = {
455
+ models: LlmapiModel[];
456
+ isLoading: boolean;
457
+ error: Error | null;
458
+ refetch: () => Promise<void>;
459
+ };
460
+ /**
461
+ * React hook for fetching available LLM models.
462
+ * Automatically fetches all available models.
463
+ */
464
+ declare function useModels(options?: UseModelsOptions): UseModelsResult;
465
+
466
+ export { type UseModelsOptions, type UseModelsResult, useChat, useImageGeneration, useModels };
@@ -1102,6 +1102,12 @@ var postApiV1ImagesGenerations = (options) => {
1102
1102
  }
1103
1103
  });
1104
1104
  };
1105
+ var getApiV1Models = (options) => {
1106
+ return (options?.client ?? client).get({
1107
+ url: "/api/v1/models",
1108
+ ...options
1109
+ });
1110
+ };
1105
1111
 
1106
1112
  // src/react/useImageGeneration.ts
1107
1113
  function useImageGeneration(options = {}) {
@@ -1183,7 +1189,112 @@ function useImageGeneration(options = {}) {
1183
1189
  stop
1184
1190
  };
1185
1191
  }
1192
+
1193
+ // src/react/useModels.ts
1194
+ import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
1195
+ function useModels(options = {}) {
1196
+ const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
1197
+ const [models, setModels] = useState3([]);
1198
+ const [isLoading, setIsLoading] = useState3(false);
1199
+ const [error, setError] = useState3(null);
1200
+ const getTokenRef = useRef3(getToken);
1201
+ const baseUrlRef = useRef3(baseUrl);
1202
+ const providerRef = useRef3(provider);
1203
+ const abortControllerRef = useRef3(null);
1204
+ useEffect3(() => {
1205
+ getTokenRef.current = getToken;
1206
+ baseUrlRef.current = baseUrl;
1207
+ providerRef.current = provider;
1208
+ });
1209
+ useEffect3(() => {
1210
+ return () => {
1211
+ if (abortControllerRef.current) {
1212
+ abortControllerRef.current.abort();
1213
+ abortControllerRef.current = null;
1214
+ }
1215
+ };
1216
+ }, []);
1217
+ const fetchModels = useCallback3(async () => {
1218
+ if (abortControllerRef.current) {
1219
+ abortControllerRef.current.abort();
1220
+ }
1221
+ const abortController = new AbortController();
1222
+ abortControllerRef.current = abortController;
1223
+ const signal = abortController.signal;
1224
+ setIsLoading(true);
1225
+ setError(null);
1226
+ try {
1227
+ let token;
1228
+ if (getTokenRef.current) {
1229
+ token = await getTokenRef.current() ?? void 0;
1230
+ }
1231
+ if (signal.aborted) return;
1232
+ const headers = {};
1233
+ if (token) {
1234
+ headers["Authorization"] = `Bearer ${token}`;
1235
+ }
1236
+ let allModels = [];
1237
+ let nextPageToken;
1238
+ do {
1239
+ if (signal.aborted) return;
1240
+ const response = await getApiV1Models({
1241
+ baseUrl: baseUrlRef.current,
1242
+ headers,
1243
+ query: {
1244
+ provider: providerRef.current,
1245
+ page_token: nextPageToken
1246
+ },
1247
+ signal
1248
+ });
1249
+ if (response.error) {
1250
+ const errorMsg = response.error.error ?? "Failed to fetch models";
1251
+ throw new Error(errorMsg);
1252
+ }
1253
+ if (response.data) {
1254
+ const newModels = response.data.data || [];
1255
+ allModels = [...allModels, ...newModels];
1256
+ nextPageToken = response.data.next_page_token;
1257
+ }
1258
+ } while (nextPageToken);
1259
+ if (signal.aborted) return;
1260
+ setModels(allModels);
1261
+ } catch (err) {
1262
+ if (err instanceof Error && err.name === "AbortError") {
1263
+ return;
1264
+ }
1265
+ setError(err instanceof Error ? err : new Error(String(err)));
1266
+ } finally {
1267
+ if (!signal.aborted) {
1268
+ setIsLoading(false);
1269
+ }
1270
+ if (abortControllerRef.current === abortController) {
1271
+ abortControllerRef.current = null;
1272
+ }
1273
+ }
1274
+ }, []);
1275
+ const refetch = useCallback3(async () => {
1276
+ setModels([]);
1277
+ await fetchModels();
1278
+ }, [fetchModels]);
1279
+ const hasFetchedRef = useRef3(false);
1280
+ useEffect3(() => {
1281
+ if (autoFetch && !hasFetchedRef.current) {
1282
+ hasFetchedRef.current = true;
1283
+ fetchModels();
1284
+ }
1285
+ if (!autoFetch) {
1286
+ hasFetchedRef.current = false;
1287
+ }
1288
+ }, [autoFetch, fetchModels]);
1289
+ return {
1290
+ models,
1291
+ isLoading,
1292
+ error,
1293
+ refetch
1294
+ };
1295
+ }
1186
1296
  export {
1187
1297
  useChat,
1188
- useImageGeneration
1298
+ useImageGeneration,
1299
+ useModels
1189
1300
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reverbia/sdk",
3
- "version": "1.0.0-next.20251209090511",
3
+ "version": "1.0.0-next.20251209143100",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",