@reverbia/sdk 1.0.0-next.20251202225102 → 1.0.0-next.20251204090034

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.
@@ -3145,33 +3145,33 @@ var require_detect_libc = __commonJS({
3145
3145
  }
3146
3146
  return null;
3147
3147
  };
3148
- var version2 = async () => {
3149
- let version3 = null;
3148
+ var version3 = async () => {
3149
+ let version4 = null;
3150
3150
  if (isLinux()) {
3151
- version3 = await versionFromFilesystem();
3152
- if (!version3) {
3153
- version3 = versionFromReport();
3151
+ version4 = await versionFromFilesystem();
3152
+ if (!version4) {
3153
+ version4 = versionFromReport();
3154
3154
  }
3155
- if (!version3) {
3155
+ if (!version4) {
3156
3156
  const out = await safeCommand();
3157
- version3 = versionFromCommand(out);
3157
+ version4 = versionFromCommand(out);
3158
3158
  }
3159
3159
  }
3160
- return version3;
3160
+ return version4;
3161
3161
  };
3162
3162
  var versionSync = () => {
3163
- let version3 = null;
3163
+ let version4 = null;
3164
3164
  if (isLinux()) {
3165
- version3 = versionFromFilesystemSync();
3166
- if (!version3) {
3167
- version3 = versionFromReport();
3165
+ version4 = versionFromFilesystemSync();
3166
+ if (!version4) {
3167
+ version4 = versionFromReport();
3168
3168
  }
3169
- if (!version3) {
3169
+ if (!version4) {
3170
3170
  const out = safeCommandSync();
3171
- version3 = versionFromCommand(out);
3171
+ version4 = versionFromCommand(out);
3172
3172
  }
3173
3173
  }
3174
- return version3;
3174
+ return version4;
3175
3175
  };
3176
3176
  module2.exports = {
3177
3177
  GLIBC,
@@ -3180,7 +3180,7 @@ var require_detect_libc = __commonJS({
3180
3180
  familySync,
3181
3181
  isNonGlibcLinux,
3182
3182
  isNonGlibcLinuxSync,
3183
- version: version2,
3183
+ version: version3,
3184
3184
  versionSync
3185
3185
  };
3186
3186
  }
@@ -3370,31 +3370,31 @@ var require_semver = __commonJS({
3370
3370
  var parseOptions = require_parse_options();
3371
3371
  var { compareIdentifiers } = require_identifiers();
3372
3372
  var SemVer = class _SemVer {
3373
- constructor(version2, options) {
3373
+ constructor(version3, options) {
3374
3374
  options = parseOptions(options);
3375
- if (version2 instanceof _SemVer) {
3376
- if (version2.loose === !!options.loose && version2.includePrerelease === !!options.includePrerelease) {
3377
- return version2;
3375
+ if (version3 instanceof _SemVer) {
3376
+ if (version3.loose === !!options.loose && version3.includePrerelease === !!options.includePrerelease) {
3377
+ return version3;
3378
3378
  } else {
3379
- version2 = version2.version;
3379
+ version3 = version3.version;
3380
3380
  }
3381
- } else if (typeof version2 !== "string") {
3382
- throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version2}".`);
3381
+ } else if (typeof version3 !== "string") {
3382
+ throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version3}".`);
3383
3383
  }
3384
- if (version2.length > MAX_LENGTH) {
3384
+ if (version3.length > MAX_LENGTH) {
3385
3385
  throw new TypeError(
3386
3386
  `version is longer than ${MAX_LENGTH} characters`
3387
3387
  );
3388
3388
  }
3389
- debug("SemVer", version2, options);
3389
+ debug("SemVer", version3, options);
3390
3390
  this.options = options;
3391
3391
  this.loose = !!options.loose;
3392
3392
  this.includePrerelease = !!options.includePrerelease;
3393
- const m = version2.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
3393
+ const m = version3.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
3394
3394
  if (!m) {
3395
- throw new TypeError(`Invalid Version: ${version2}`);
3395
+ throw new TypeError(`Invalid Version: ${version3}`);
3396
3396
  }
3397
- this.raw = version2;
3397
+ this.raw = version3;
3398
3398
  this.major = +m[1];
3399
3399
  this.minor = +m[2];
3400
3400
  this.patch = +m[3];
@@ -3644,12 +3644,12 @@ var require_parse = __commonJS({
3644
3644
  "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/parse.js"(exports2, module2) {
3645
3645
  "use strict";
3646
3646
  var SemVer = require_semver();
3647
- var parse = (version2, options, throwErrors = false) => {
3648
- if (version2 instanceof SemVer) {
3649
- return version2;
3647
+ var parse = (version3, options, throwErrors = false) => {
3648
+ if (version3 instanceof SemVer) {
3649
+ return version3;
3650
3650
  }
3651
3651
  try {
3652
- return new SemVer(version2, options);
3652
+ return new SemVer(version3, options);
3653
3653
  } catch (er) {
3654
3654
  if (!throwErrors) {
3655
3655
  return null;
@@ -3668,24 +3668,24 @@ var require_coerce = __commonJS({
3668
3668
  var SemVer = require_semver();
3669
3669
  var parse = require_parse();
3670
3670
  var { safeRe: re, t } = require_re();
3671
- var coerce = (version2, options) => {
3672
- if (version2 instanceof SemVer) {
3673
- return version2;
3671
+ var coerce = (version3, options) => {
3672
+ if (version3 instanceof SemVer) {
3673
+ return version3;
3674
3674
  }
3675
- if (typeof version2 === "number") {
3676
- version2 = String(version2);
3675
+ if (typeof version3 === "number") {
3676
+ version3 = String(version3);
3677
3677
  }
3678
- if (typeof version2 !== "string") {
3678
+ if (typeof version3 !== "string") {
3679
3679
  return null;
3680
3680
  }
3681
3681
  options = options || {};
3682
3682
  let match = null;
3683
3683
  if (!options.rtl) {
3684
- match = version2.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]);
3684
+ match = version3.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]);
3685
3685
  } else {
3686
3686
  const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL];
3687
3687
  let next;
3688
- while ((next = coerceRtlRegex.exec(version2)) && (!match || match.index + match[0].length !== version2.length)) {
3688
+ while ((next = coerceRtlRegex.exec(version3)) && (!match || match.index + match[0].length !== version3.length)) {
3689
3689
  if (!match || next.index + next[0].length !== match.index + match[0].length) {
3690
3690
  match = next;
3691
3691
  }
@@ -3914,19 +3914,19 @@ var require_comparator = __commonJS({
3914
3914
  toString() {
3915
3915
  return this.value;
3916
3916
  }
3917
- test(version2) {
3918
- debug("Comparator.test", version2, this.options.loose);
3919
- if (this.semver === ANY || version2 === ANY) {
3917
+ test(version3) {
3918
+ debug("Comparator.test", version3, this.options.loose);
3919
+ if (this.semver === ANY || version3 === ANY) {
3920
3920
  return true;
3921
3921
  }
3922
- if (typeof version2 === "string") {
3922
+ if (typeof version3 === "string") {
3923
3923
  try {
3924
- version2 = new SemVer(version2, this.options);
3924
+ version3 = new SemVer(version3, this.options);
3925
3925
  } catch (er) {
3926
3926
  return false;
3927
3927
  }
3928
3928
  }
3929
- return cmp(version2, this.operator, this.semver, this.options);
3929
+ return cmp(version3, this.operator, this.semver, this.options);
3930
3930
  }
3931
3931
  intersects(comp, options) {
3932
3932
  if (!(comp instanceof _Comparator)) {
@@ -4102,19 +4102,19 @@ var require_range = __commonJS({
4102
4102
  });
4103
4103
  }
4104
4104
  // if ANY of the sets match ALL of its comparators, then pass
4105
- test(version2) {
4106
- if (!version2) {
4105
+ test(version3) {
4106
+ if (!version3) {
4107
4107
  return false;
4108
4108
  }
4109
- if (typeof version2 === "string") {
4109
+ if (typeof version3 === "string") {
4110
4110
  try {
4111
- version2 = new SemVer(version2, this.options);
4111
+ version3 = new SemVer(version3, this.options);
4112
4112
  } catch (er) {
4113
4113
  return false;
4114
4114
  }
4115
4115
  }
4116
4116
  for (let i = 0; i < this.set.length; i++) {
4117
- if (testSet(this.set[i], version2, this.options)) {
4117
+ if (testSet(this.set[i], version3, this.options)) {
4118
4118
  return true;
4119
4119
  }
4120
4120
  }
@@ -4329,13 +4329,13 @@ var require_range = __commonJS({
4329
4329
  }
4330
4330
  return `${from} ${to}`.trim();
4331
4331
  };
4332
- var testSet = (set, version2, options) => {
4332
+ var testSet = (set, version3, options) => {
4333
4333
  for (let i = 0; i < set.length; i++) {
4334
- if (!set[i].test(version2)) {
4334
+ if (!set[i].test(version3)) {
4335
4335
  return false;
4336
4336
  }
4337
4337
  }
4338
- if (version2.prerelease.length && !options.includePrerelease) {
4338
+ if (version3.prerelease.length && !options.includePrerelease) {
4339
4339
  for (let i = 0; i < set.length; i++) {
4340
4340
  debug(set[i].semver);
4341
4341
  if (set[i].semver === Comparator.ANY) {
@@ -4343,7 +4343,7 @@ var require_range = __commonJS({
4343
4343
  }
4344
4344
  if (set[i].semver.prerelease.length > 0) {
4345
4345
  const allowed = set[i].semver;
4346
- if (allowed.major === version2.major && allowed.minor === version2.minor && allowed.patch === version2.patch) {
4346
+ if (allowed.major === version3.major && allowed.minor === version3.minor && allowed.patch === version3.patch) {
4347
4347
  return true;
4348
4348
  }
4349
4349
  }
@@ -4360,13 +4360,13 @@ var require_satisfies = __commonJS({
4360
4360
  "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/satisfies.js"(exports2, module2) {
4361
4361
  "use strict";
4362
4362
  var Range = require_range();
4363
- var satisfies = (version2, range, options) => {
4363
+ var satisfies = (version3, range, options) => {
4364
4364
  try {
4365
4365
  range = new Range(range, options);
4366
4366
  } catch (er) {
4367
4367
  return false;
4368
4368
  }
4369
- return range.test(version2);
4369
+ return range.test(version3);
4370
4370
  };
4371
4371
  module2.exports = satisfies;
4372
4372
  }
@@ -38191,9 +38191,9 @@ ${fake_token_around_image}${global_img_token}` + image_token.repeat(image_seq_le
38191
38191
  );
38192
38192
  } else if (typeof process !== "undefined" && process?.release?.name === "node") {
38193
38193
  const IS_CI = !!process.env?.TESTING_REMOTELY;
38194
- const version2 = _env_js__WEBPACK_IMPORTED_MODULE_2__.env.version;
38194
+ const version3 = _env_js__WEBPACK_IMPORTED_MODULE_2__.env.version;
38195
38195
  const headers = new Headers();
38196
- headers.set("User-Agent", `transformers.js/${version2}; is_ci/${IS_CI};`);
38196
+ headers.set("User-Agent", `transformers.js/${version3}; is_ci/${IS_CI};`);
38197
38197
  const isHFURL = isValidUrl(urlOrPath, ["http:", "https:"], ["huggingface.co", "hf.co"]);
38198
38198
  if (isHFURL) {
38199
38199
  const token = process.env?.HF_TOKEN ?? process.env?.HF_ACCESS_TOKEN;
@@ -46682,7 +46682,9 @@ __export(index_exports, {
46682
46682
  useEncryption: () => useEncryption,
46683
46683
  useImageGeneration: () => useImageGeneration,
46684
46684
  useMemory: () => useMemory,
46685
- useModels: () => useModels
46685
+ useModels: () => useModels,
46686
+ usePdf: () => usePdf,
46687
+ useSearch: () => useSearch
46686
46688
  });
46687
46689
  module.exports = __toCommonJS(index_exports);
46688
46690
 
@@ -48447,6 +48449,16 @@ var getApiV1Models = (options) => {
48447
48449
  ...options
48448
48450
  });
48449
48451
  };
48452
+ var postApiV1Search = (options) => {
48453
+ return (options.client ?? client).post({
48454
+ url: "/api/v1/search",
48455
+ ...options,
48456
+ headers: {
48457
+ "Content-Type": "application/json",
48458
+ ...options.headers
48459
+ }
48460
+ });
48461
+ };
48450
48462
 
48451
48463
  // src/lib/memory/constants.ts
48452
48464
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Snowflake/snowflake-arctic-embed-xs";
@@ -48820,23 +48832,100 @@ function useMemory(options = {}) {
48820
48832
  };
48821
48833
  }
48822
48834
 
48823
- // src/react/useModels.ts
48835
+ // src/react/usePdf.ts
48824
48836
  var import_react4 = require("react");
48837
+
48838
+ // src/lib/pdf.ts
48839
+ var pdfjs = __toESM(require("pdfjs-dist"));
48840
+ pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
48841
+ async function extractTextFromPdf(pdfDataUrl) {
48842
+ try {
48843
+ const loadingTask = pdfjs.getDocument(pdfDataUrl);
48844
+ const pdf = await loadingTask.promise;
48845
+ const textParts = [];
48846
+ for (let i = 1; i <= pdf.numPages; i++) {
48847
+ const page = await pdf.getPage(i);
48848
+ const textContent = await page.getTextContent();
48849
+ const pageText = textContent.items.map((item) => item.str).join(" ");
48850
+ if (pageText.trim()) {
48851
+ textParts.push(pageText);
48852
+ }
48853
+ }
48854
+ return textParts.join("\n\n");
48855
+ } catch (error) {
48856
+ console.error("Error extracting text from PDF:", error);
48857
+ throw error;
48858
+ }
48859
+ }
48860
+
48861
+ // src/react/usePdf.ts
48862
+ var PDF_MIME_TYPE = "application/pdf";
48863
+ function usePdf() {
48864
+ const [isProcessing, setIsProcessing] = (0, import_react4.useState)(false);
48865
+ const [error, setError] = (0, import_react4.useState)(null);
48866
+ const extractPdfContext = (0, import_react4.useCallback)(
48867
+ async (files) => {
48868
+ setIsProcessing(true);
48869
+ setError(null);
48870
+ try {
48871
+ const pdfFiles = files.filter(
48872
+ (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
48873
+ );
48874
+ if (pdfFiles.length === 0) {
48875
+ return null;
48876
+ }
48877
+ const contexts = await Promise.all(
48878
+ pdfFiles.map(async (file) => {
48879
+ try {
48880
+ const text = await extractTextFromPdf(file.url);
48881
+ if (!text.trim()) {
48882
+ console.warn(`No text found in PDF ${file.filename}`);
48883
+ return null;
48884
+ }
48885
+ return `[Context from PDF attachment ${file.filename}]:
48886
+ ${text}`;
48887
+ } catch (err) {
48888
+ console.error(`Failed to process PDF ${file.filename}:`, err);
48889
+ return null;
48890
+ }
48891
+ })
48892
+ );
48893
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
48894
+ return mergedContext || null;
48895
+ } catch (err) {
48896
+ const processedError = err instanceof Error ? err : new Error(String(err));
48897
+ setError(processedError);
48898
+ throw processedError;
48899
+ } finally {
48900
+ setIsProcessing(false);
48901
+ }
48902
+ },
48903
+ []
48904
+ );
48905
+ return {
48906
+ extractPdfContext,
48907
+ isProcessing,
48908
+ error
48909
+ };
48910
+ }
48911
+
48912
+ // src/react/useModels.ts
48913
+ var import_react5 = require("react");
48825
48914
  function useModels(options = {}) {
48826
48915
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
48827
- const [models, setModels] = (0, import_react4.useState)([]);
48828
- const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
48829
- const [error, setError] = (0, import_react4.useState)(null);
48830
- const getTokenRef = (0, import_react4.useRef)(getToken);
48831
- const baseUrlRef = (0, import_react4.useRef)(baseUrl);
48832
- const providerRef = (0, import_react4.useRef)(provider);
48833
- const abortControllerRef = (0, import_react4.useRef)(null);
48834
- (0, import_react4.useEffect)(() => {
48916
+ const [models, setModels] = (0, import_react5.useState)([]);
48917
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
48918
+ const [error, setError] = (0, import_react5.useState)(null);
48919
+ const getTokenRef = (0, import_react5.useRef)(getToken);
48920
+ const baseUrlRef = (0, import_react5.useRef)(baseUrl);
48921
+ const providerRef = (0, import_react5.useRef)(provider);
48922
+ const abortControllerRef = (0, import_react5.useRef)(null);
48923
+ (0, import_react5.useEffect)(() => {
48835
48924
  getTokenRef.current = getToken;
48836
48925
  baseUrlRef.current = baseUrl;
48837
48926
  providerRef.current = provider;
48838
48927
  });
48839
- (0, import_react4.useEffect)(() => {
48928
+ (0, import_react5.useEffect)(() => {
48840
48929
  return () => {
48841
48930
  if (abortControllerRef.current) {
48842
48931
  abortControllerRef.current.abort();
@@ -48844,7 +48933,7 @@ function useModels(options = {}) {
48844
48933
  }
48845
48934
  };
48846
48935
  }, []);
48847
- const fetchModels = (0, import_react4.useCallback)(async () => {
48936
+ const fetchModels = (0, import_react5.useCallback)(async () => {
48848
48937
  if (abortControllerRef.current) {
48849
48938
  abortControllerRef.current.abort();
48850
48939
  }
@@ -48902,12 +48991,12 @@ function useModels(options = {}) {
48902
48991
  }
48903
48992
  }
48904
48993
  }, []);
48905
- const refetch = (0, import_react4.useCallback)(async () => {
48994
+ const refetch = (0, import_react5.useCallback)(async () => {
48906
48995
  setModels([]);
48907
48996
  await fetchModels();
48908
48997
  }, [fetchModels]);
48909
- const hasFetchedRef = (0, import_react4.useRef)(false);
48910
- (0, import_react4.useEffect)(() => {
48998
+ const hasFetchedRef = (0, import_react5.useRef)(false);
48999
+ (0, import_react5.useEffect)(() => {
48911
49000
  if (autoFetch && !hasFetchedRef.current) {
48912
49001
  hasFetchedRef.current = true;
48913
49002
  fetchModels();
@@ -48924,13 +49013,97 @@ function useModels(options = {}) {
48924
49013
  };
48925
49014
  }
48926
49015
 
49016
+ // src/react/useSearch.ts
49017
+ var import_react6 = require("react");
49018
+ function useSearch(options = {}) {
49019
+ const { getToken, baseUrl = BASE_URL, onError } = options;
49020
+ const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
49021
+ const [results, setResults] = (0, import_react6.useState)(null);
49022
+ const [response, setResponse] = (0, import_react6.useState)(null);
49023
+ const [error, setError] = (0, import_react6.useState)(null);
49024
+ const abortControllerRef = (0, import_react6.useRef)(null);
49025
+ (0, import_react6.useEffect)(() => {
49026
+ return () => {
49027
+ if (abortControllerRef.current) {
49028
+ abortControllerRef.current.abort();
49029
+ abortControllerRef.current = null;
49030
+ }
49031
+ };
49032
+ }, []);
49033
+ const search = (0, import_react6.useCallback)(
49034
+ async (query, searchOptions = {}) => {
49035
+ if (abortControllerRef.current) {
49036
+ abortControllerRef.current.abort();
49037
+ }
49038
+ const abortController = new AbortController();
49039
+ abortControllerRef.current = abortController;
49040
+ setIsLoading(true);
49041
+ setError(null);
49042
+ setResults(null);
49043
+ setResponse(null);
49044
+ try {
49045
+ let token;
49046
+ if (getToken) {
49047
+ token = await getToken() ?? void 0;
49048
+ }
49049
+ if (abortController.signal.aborted) return null;
49050
+ const queryArray = Array.isArray(query) ? query : [query];
49051
+ const res = await postApiV1Search({
49052
+ baseUrl,
49053
+ body: {
49054
+ query: queryArray,
49055
+ ...searchOptions
49056
+ },
49057
+ headers: token ? {
49058
+ Authorization: `Bearer ${token}`
49059
+ } : void 0,
49060
+ signal: abortController.signal
49061
+ });
49062
+ if (res.error) {
49063
+ const errorMsg = res.error.error || res.error.message || "Failed to perform search";
49064
+ throw new Error(errorMsg);
49065
+ }
49066
+ if (res.data) {
49067
+ setResponse(res.data);
49068
+ setResults(res.data.results || []);
49069
+ return res.data;
49070
+ }
49071
+ return null;
49072
+ } catch (err) {
49073
+ if (err instanceof Error && err.name === "AbortError") {
49074
+ return null;
49075
+ }
49076
+ const errorObj = err instanceof Error ? err : new Error(String(err));
49077
+ setError(errorObj);
49078
+ if (onError) {
49079
+ onError(errorObj);
49080
+ }
49081
+ return null;
49082
+ } finally {
49083
+ if (abortControllerRef.current === abortController) {
49084
+ setIsLoading(false);
49085
+ abortControllerRef.current = null;
49086
+ }
49087
+ }
49088
+ },
49089
+ [baseUrl, getToken, onError]
49090
+ );
49091
+ return {
49092
+ isLoading,
49093
+ search,
49094
+ results,
49095
+ response,
49096
+ error
49097
+ };
49098
+ }
49099
+
48927
49100
  // src/react/useImageGeneration.ts
48928
- var import_react5 = require("react");
49101
+ var import_react7 = require("react");
48929
49102
  function useImageGeneration(options = {}) {
48930
49103
  const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
48931
- const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
48932
- const abortControllerRef = (0, import_react5.useRef)(null);
48933
- (0, import_react5.useEffect)(() => {
49104
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
49105
+ const abortControllerRef = (0, import_react7.useRef)(null);
49106
+ (0, import_react7.useEffect)(() => {
48934
49107
  return () => {
48935
49108
  if (abortControllerRef.current) {
48936
49109
  abortControllerRef.current.abort();
@@ -48938,13 +49111,13 @@ function useImageGeneration(options = {}) {
48938
49111
  }
48939
49112
  };
48940
49113
  }, []);
48941
- const stop = (0, import_react5.useCallback)(() => {
49114
+ const stop = (0, import_react7.useCallback)(() => {
48942
49115
  if (abortControllerRef.current) {
48943
49116
  abortControllerRef.current.abort();
48944
49117
  abortControllerRef.current = null;
48945
49118
  }
48946
49119
  }, []);
48947
- const generateImage = (0, import_react5.useCallback)(
49120
+ const generateImage = (0, import_react7.useCallback)(
48948
49121
  async (args) => {
48949
49122
  if (abortControllerRef.current) {
48950
49123
  abortControllerRef.current.abort();
@@ -49075,7 +49248,9 @@ var extractConversationContext = (messages, maxMessages = 3) => {
49075
49248
  useEncryption,
49076
49249
  useImageGeneration,
49077
49250
  useMemory,
49078
- useModels
49251
+ useModels,
49252
+ usePdf,
49253
+ useSearch
49079
49254
  });
49080
49255
  /*! Bundled license information:
49081
49256
 
@@ -288,6 +288,80 @@ type LlmapiModelTopProvider = {
288
288
  * Role is the message role (system, user, assistant)
289
289
  */
290
290
  type LlmapiRole = string;
291
+ /**
292
+ * ExtraFields contains additional metadata.
293
+ */
294
+ type LlmapiSearchExtraFields = {
295
+ /**
296
+ * RequestType is always "search".
297
+ */
298
+ request_type?: string;
299
+ /**
300
+ * SearchProvider is the search provider used (e.g., "perplexity", "google-pse").
301
+ */
302
+ search_provider?: string;
303
+ };
304
+ type LlmapiSearchRequest = {
305
+ /**
306
+ * Country code filter (e.g., "US", "GB", "DE").
307
+ */
308
+ country?: string;
309
+ /**
310
+ * Maximum number of results to return (1-20). Default: 10.
311
+ */
312
+ max_results?: number;
313
+ /**
314
+ * Maximum tokens per page to process. Default: 1024.
315
+ */
316
+ max_tokens_per_page?: number;
317
+ /**
318
+ * Search query. Can be a single string or array of strings.
319
+ */
320
+ query?: Array<string>;
321
+ /**
322
+ * List of domains to filter results (max 20 domains).
323
+ */
324
+ search_domain_filter?: Array<string>;
325
+ /**
326
+ * The search provider to use.
327
+ */
328
+ search_tool_name?: string;
329
+ };
330
+ type LlmapiSearchResponse = {
331
+ extra_fields?: LlmapiSearchExtraFields;
332
+ /**
333
+ * List of search results.
334
+ */
335
+ results?: Array<LlmapiSearchResult>;
336
+ usage?: LlmapiSearchUsage;
337
+ };
338
+ type LlmapiSearchResult = {
339
+ /**
340
+ * Optional publication or last updated date.
341
+ */
342
+ date?: string;
343
+ /**
344
+ * Text snippet from the result.
345
+ */
346
+ snippet?: string;
347
+ /**
348
+ * Title of the search result.
349
+ */
350
+ title?: string;
351
+ /**
352
+ * URL of the search result.
353
+ */
354
+ url?: string;
355
+ };
356
+ /**
357
+ * Usage contains usage information.
358
+ */
359
+ type LlmapiSearchUsage = {
360
+ /**
361
+ * CostMicroUSD is the cost of this search in micro-dollars (USD × 1,000,000).
362
+ */
363
+ cost_micro_usd?: number;
364
+ };
291
365
 
292
366
  /**
293
367
  * Parameter definition for a client-side tool
@@ -614,6 +688,17 @@ type UseMemoryResult = {
614
688
  */
615
689
  declare function useMemory(options?: UseMemoryOptions): UseMemoryResult;
616
690
 
691
+ interface PdfFile {
692
+ url: string;
693
+ mediaType?: string;
694
+ filename?: string;
695
+ }
696
+ declare function usePdf(): {
697
+ extractPdfContext: (files: PdfFile[]) => Promise<string | null>;
698
+ isProcessing: boolean;
699
+ error: Error | null;
700
+ };
701
+
617
702
  type UseModelsOptions = {
618
703
  /**
619
704
  * Custom function to get auth token for API calls
@@ -644,6 +729,47 @@ type UseModelsResult = {
644
729
  */
645
730
  declare function useModels(options?: UseModelsOptions): UseModelsResult;
646
731
 
732
+ type UseSearchOptions = {
733
+ /**
734
+ * Custom function to get auth token for API calls
735
+ */
736
+ getToken?: () => Promise<string | null>;
737
+ /**
738
+ * Optional base URL for the API requests.
739
+ */
740
+ baseUrl?: string;
741
+ /**
742
+ * Callback function to be called when an error is encountered.
743
+ */
744
+ onError?: (error: Error) => void;
745
+ };
746
+ type SearchOptions = Omit<LlmapiSearchRequest, "query">;
747
+ type UseSearchResult = {
748
+ isLoading: boolean;
749
+ search: (query: string | string[], options?: SearchOptions) => Promise<LlmapiSearchResponse | null>;
750
+ results: LlmapiSearchResult[] | null;
751
+ response: LlmapiSearchResponse | null;
752
+ error: Error | null;
753
+ };
754
+ /**
755
+ * React hook for performing search operations using the AI SDK.
756
+ *
757
+ * @param options - Configuration options for the search hook
758
+ * @returns Object containing search function, results, loading state, and error
759
+ *
760
+ * @example
761
+ * ```tsx
762
+ * const { search, results, isLoading } = useSearch({
763
+ * getToken: async () => "my-token"
764
+ * });
765
+ *
766
+ * const handleSearch = async () => {
767
+ * await search("What is ZetaChain?");
768
+ * };
769
+ * ```
770
+ */
771
+ declare function useSearch(options?: UseSearchOptions): UseSearchResult;
772
+
647
773
  type UseImageGenerationOptions = {
648
774
  /**
649
775
  * Custom function to get auth token for API calls
@@ -731,4 +857,4 @@ declare function executeTool(tool: ClientTool, params: Record<string, unknown>):
731
857
  error?: string;
732
858
  }>;
733
859
 
734
- export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels };
860
+ export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type PdfFile, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, usePdf, useSearch };
@@ -288,6 +288,80 @@ type LlmapiModelTopProvider = {
288
288
  * Role is the message role (system, user, assistant)
289
289
  */
290
290
  type LlmapiRole = string;
291
+ /**
292
+ * ExtraFields contains additional metadata.
293
+ */
294
+ type LlmapiSearchExtraFields = {
295
+ /**
296
+ * RequestType is always "search".
297
+ */
298
+ request_type?: string;
299
+ /**
300
+ * SearchProvider is the search provider used (e.g., "perplexity", "google-pse").
301
+ */
302
+ search_provider?: string;
303
+ };
304
+ type LlmapiSearchRequest = {
305
+ /**
306
+ * Country code filter (e.g., "US", "GB", "DE").
307
+ */
308
+ country?: string;
309
+ /**
310
+ * Maximum number of results to return (1-20). Default: 10.
311
+ */
312
+ max_results?: number;
313
+ /**
314
+ * Maximum tokens per page to process. Default: 1024.
315
+ */
316
+ max_tokens_per_page?: number;
317
+ /**
318
+ * Search query. Can be a single string or array of strings.
319
+ */
320
+ query?: Array<string>;
321
+ /**
322
+ * List of domains to filter results (max 20 domains).
323
+ */
324
+ search_domain_filter?: Array<string>;
325
+ /**
326
+ * The search provider to use.
327
+ */
328
+ search_tool_name?: string;
329
+ };
330
+ type LlmapiSearchResponse = {
331
+ extra_fields?: LlmapiSearchExtraFields;
332
+ /**
333
+ * List of search results.
334
+ */
335
+ results?: Array<LlmapiSearchResult>;
336
+ usage?: LlmapiSearchUsage;
337
+ };
338
+ type LlmapiSearchResult = {
339
+ /**
340
+ * Optional publication or last updated date.
341
+ */
342
+ date?: string;
343
+ /**
344
+ * Text snippet from the result.
345
+ */
346
+ snippet?: string;
347
+ /**
348
+ * Title of the search result.
349
+ */
350
+ title?: string;
351
+ /**
352
+ * URL of the search result.
353
+ */
354
+ url?: string;
355
+ };
356
+ /**
357
+ * Usage contains usage information.
358
+ */
359
+ type LlmapiSearchUsage = {
360
+ /**
361
+ * CostMicroUSD is the cost of this search in micro-dollars (USD × 1,000,000).
362
+ */
363
+ cost_micro_usd?: number;
364
+ };
291
365
 
292
366
  /**
293
367
  * Parameter definition for a client-side tool
@@ -614,6 +688,17 @@ type UseMemoryResult = {
614
688
  */
615
689
  declare function useMemory(options?: UseMemoryOptions): UseMemoryResult;
616
690
 
691
+ interface PdfFile {
692
+ url: string;
693
+ mediaType?: string;
694
+ filename?: string;
695
+ }
696
+ declare function usePdf(): {
697
+ extractPdfContext: (files: PdfFile[]) => Promise<string | null>;
698
+ isProcessing: boolean;
699
+ error: Error | null;
700
+ };
701
+
617
702
  type UseModelsOptions = {
618
703
  /**
619
704
  * Custom function to get auth token for API calls
@@ -644,6 +729,47 @@ type UseModelsResult = {
644
729
  */
645
730
  declare function useModels(options?: UseModelsOptions): UseModelsResult;
646
731
 
732
+ type UseSearchOptions = {
733
+ /**
734
+ * Custom function to get auth token for API calls
735
+ */
736
+ getToken?: () => Promise<string | null>;
737
+ /**
738
+ * Optional base URL for the API requests.
739
+ */
740
+ baseUrl?: string;
741
+ /**
742
+ * Callback function to be called when an error is encountered.
743
+ */
744
+ onError?: (error: Error) => void;
745
+ };
746
+ type SearchOptions = Omit<LlmapiSearchRequest, "query">;
747
+ type UseSearchResult = {
748
+ isLoading: boolean;
749
+ search: (query: string | string[], options?: SearchOptions) => Promise<LlmapiSearchResponse | null>;
750
+ results: LlmapiSearchResult[] | null;
751
+ response: LlmapiSearchResponse | null;
752
+ error: Error | null;
753
+ };
754
+ /**
755
+ * React hook for performing search operations using the AI SDK.
756
+ *
757
+ * @param options - Configuration options for the search hook
758
+ * @returns Object containing search function, results, loading state, and error
759
+ *
760
+ * @example
761
+ * ```tsx
762
+ * const { search, results, isLoading } = useSearch({
763
+ * getToken: async () => "my-token"
764
+ * });
765
+ *
766
+ * const handleSearch = async () => {
767
+ * await search("What is ZetaChain?");
768
+ * };
769
+ * ```
770
+ */
771
+ declare function useSearch(options?: UseSearchOptions): UseSearchResult;
772
+
647
773
  type UseImageGenerationOptions = {
648
774
  /**
649
775
  * Custom function to get auth token for API calls
@@ -731,4 +857,4 @@ declare function executeTool(tool: ClientTool, params: Record<string, unknown>):
731
857
  error?: string;
732
858
  }>;
733
859
 
734
- export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels };
860
+ export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type PdfFile, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, usePdf, useSearch };
@@ -1761,6 +1761,16 @@ var getApiV1Models = (options) => {
1761
1761
  ...options
1762
1762
  });
1763
1763
  };
1764
+ var postApiV1Search = (options) => {
1765
+ return (options.client ?? client).post({
1766
+ url: "/api/v1/search",
1767
+ ...options,
1768
+ headers: {
1769
+ "Content-Type": "application/json",
1770
+ ...options.headers
1771
+ }
1772
+ });
1773
+ };
1764
1774
 
1765
1775
  // src/lib/memory/constants.ts
1766
1776
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Snowflake/snowflake-arctic-embed-xs";
@@ -2134,13 +2144,90 @@ function useMemory(options = {}) {
2134
2144
  };
2135
2145
  }
2136
2146
 
2147
+ // src/react/usePdf.ts
2148
+ import { useCallback as useCallback3, useState as useState2 } from "react";
2149
+
2150
+ // src/lib/pdf.ts
2151
+ import * as pdfjs from "pdfjs-dist";
2152
+ pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
2153
+ async function extractTextFromPdf(pdfDataUrl) {
2154
+ try {
2155
+ const loadingTask = pdfjs.getDocument(pdfDataUrl);
2156
+ const pdf = await loadingTask.promise;
2157
+ const textParts = [];
2158
+ for (let i = 1; i <= pdf.numPages; i++) {
2159
+ const page = await pdf.getPage(i);
2160
+ const textContent = await page.getTextContent();
2161
+ const pageText = textContent.items.map((item) => item.str).join(" ");
2162
+ if (pageText.trim()) {
2163
+ textParts.push(pageText);
2164
+ }
2165
+ }
2166
+ return textParts.join("\n\n");
2167
+ } catch (error) {
2168
+ console.error("Error extracting text from PDF:", error);
2169
+ throw error;
2170
+ }
2171
+ }
2172
+
2173
+ // src/react/usePdf.ts
2174
+ var PDF_MIME_TYPE = "application/pdf";
2175
+ function usePdf() {
2176
+ const [isProcessing, setIsProcessing] = useState2(false);
2177
+ const [error, setError] = useState2(null);
2178
+ const extractPdfContext = useCallback3(
2179
+ async (files) => {
2180
+ setIsProcessing(true);
2181
+ setError(null);
2182
+ try {
2183
+ const pdfFiles = files.filter(
2184
+ (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
2185
+ );
2186
+ if (pdfFiles.length === 0) {
2187
+ return null;
2188
+ }
2189
+ const contexts = await Promise.all(
2190
+ pdfFiles.map(async (file) => {
2191
+ try {
2192
+ const text = await extractTextFromPdf(file.url);
2193
+ if (!text.trim()) {
2194
+ console.warn(`No text found in PDF ${file.filename}`);
2195
+ return null;
2196
+ }
2197
+ return `[Context from PDF attachment ${file.filename}]:
2198
+ ${text}`;
2199
+ } catch (err) {
2200
+ console.error(`Failed to process PDF ${file.filename}:`, err);
2201
+ return null;
2202
+ }
2203
+ })
2204
+ );
2205
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
2206
+ return mergedContext || null;
2207
+ } catch (err) {
2208
+ const processedError = err instanceof Error ? err : new Error(String(err));
2209
+ setError(processedError);
2210
+ throw processedError;
2211
+ } finally {
2212
+ setIsProcessing(false);
2213
+ }
2214
+ },
2215
+ []
2216
+ );
2217
+ return {
2218
+ extractPdfContext,
2219
+ isProcessing,
2220
+ error
2221
+ };
2222
+ }
2223
+
2137
2224
  // src/react/useModels.ts
2138
- import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef4, useState as useState2 } from "react";
2225
+ import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef4, useState as useState3 } from "react";
2139
2226
  function useModels(options = {}) {
2140
2227
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
2141
- const [models, setModels] = useState2([]);
2142
- const [isLoading, setIsLoading] = useState2(false);
2143
- const [error, setError] = useState2(null);
2228
+ const [models, setModels] = useState3([]);
2229
+ const [isLoading, setIsLoading] = useState3(false);
2230
+ const [error, setError] = useState3(null);
2144
2231
  const getTokenRef = useRef4(getToken);
2145
2232
  const baseUrlRef = useRef4(baseUrl);
2146
2233
  const providerRef = useRef4(provider);
@@ -2158,7 +2245,7 @@ function useModels(options = {}) {
2158
2245
  }
2159
2246
  };
2160
2247
  }, []);
2161
- const fetchModels = useCallback3(async () => {
2248
+ const fetchModels = useCallback4(async () => {
2162
2249
  if (abortControllerRef.current) {
2163
2250
  abortControllerRef.current.abort();
2164
2251
  }
@@ -2216,7 +2303,7 @@ function useModels(options = {}) {
2216
2303
  }
2217
2304
  }
2218
2305
  }, []);
2219
- const refetch = useCallback3(async () => {
2306
+ const refetch = useCallback4(async () => {
2220
2307
  setModels([]);
2221
2308
  await fetchModels();
2222
2309
  }, [fetchModels]);
@@ -2238,13 +2325,97 @@ function useModels(options = {}) {
2238
2325
  };
2239
2326
  }
2240
2327
 
2328
+ // src/react/useSearch.ts
2329
+ import { useCallback as useCallback5, useEffect as useEffect4, useRef as useRef5, useState as useState4 } from "react";
2330
+ function useSearch(options = {}) {
2331
+ const { getToken, baseUrl = BASE_URL, onError } = options;
2332
+ const [isLoading, setIsLoading] = useState4(false);
2333
+ const [results, setResults] = useState4(null);
2334
+ const [response, setResponse] = useState4(null);
2335
+ const [error, setError] = useState4(null);
2336
+ const abortControllerRef = useRef5(null);
2337
+ useEffect4(() => {
2338
+ return () => {
2339
+ if (abortControllerRef.current) {
2340
+ abortControllerRef.current.abort();
2341
+ abortControllerRef.current = null;
2342
+ }
2343
+ };
2344
+ }, []);
2345
+ const search = useCallback5(
2346
+ async (query, searchOptions = {}) => {
2347
+ if (abortControllerRef.current) {
2348
+ abortControllerRef.current.abort();
2349
+ }
2350
+ const abortController = new AbortController();
2351
+ abortControllerRef.current = abortController;
2352
+ setIsLoading(true);
2353
+ setError(null);
2354
+ setResults(null);
2355
+ setResponse(null);
2356
+ try {
2357
+ let token;
2358
+ if (getToken) {
2359
+ token = await getToken() ?? void 0;
2360
+ }
2361
+ if (abortController.signal.aborted) return null;
2362
+ const queryArray = Array.isArray(query) ? query : [query];
2363
+ const res = await postApiV1Search({
2364
+ baseUrl,
2365
+ body: {
2366
+ query: queryArray,
2367
+ ...searchOptions
2368
+ },
2369
+ headers: token ? {
2370
+ Authorization: `Bearer ${token}`
2371
+ } : void 0,
2372
+ signal: abortController.signal
2373
+ });
2374
+ if (res.error) {
2375
+ const errorMsg = res.error.error || res.error.message || "Failed to perform search";
2376
+ throw new Error(errorMsg);
2377
+ }
2378
+ if (res.data) {
2379
+ setResponse(res.data);
2380
+ setResults(res.data.results || []);
2381
+ return res.data;
2382
+ }
2383
+ return null;
2384
+ } catch (err) {
2385
+ if (err instanceof Error && err.name === "AbortError") {
2386
+ return null;
2387
+ }
2388
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2389
+ setError(errorObj);
2390
+ if (onError) {
2391
+ onError(errorObj);
2392
+ }
2393
+ return null;
2394
+ } finally {
2395
+ if (abortControllerRef.current === abortController) {
2396
+ setIsLoading(false);
2397
+ abortControllerRef.current = null;
2398
+ }
2399
+ }
2400
+ },
2401
+ [baseUrl, getToken, onError]
2402
+ );
2403
+ return {
2404
+ isLoading,
2405
+ search,
2406
+ results,
2407
+ response,
2408
+ error
2409
+ };
2410
+ }
2411
+
2241
2412
  // src/react/useImageGeneration.ts
2242
- import { useCallback as useCallback4, useEffect as useEffect4, useRef as useRef5, useState as useState3 } from "react";
2413
+ import { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef6, useState as useState5 } from "react";
2243
2414
  function useImageGeneration(options = {}) {
2244
2415
  const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
2245
- const [isLoading, setIsLoading] = useState3(false);
2246
- const abortControllerRef = useRef5(null);
2247
- useEffect4(() => {
2416
+ const [isLoading, setIsLoading] = useState5(false);
2417
+ const abortControllerRef = useRef6(null);
2418
+ useEffect5(() => {
2248
2419
  return () => {
2249
2420
  if (abortControllerRef.current) {
2250
2421
  abortControllerRef.current.abort();
@@ -2252,13 +2423,13 @@ function useImageGeneration(options = {}) {
2252
2423
  }
2253
2424
  };
2254
2425
  }, []);
2255
- const stop = useCallback4(() => {
2426
+ const stop = useCallback6(() => {
2256
2427
  if (abortControllerRef.current) {
2257
2428
  abortControllerRef.current.abort();
2258
2429
  abortControllerRef.current = null;
2259
2430
  }
2260
2431
  }, []);
2261
- const generateImage = useCallback4(
2432
+ const generateImage = useCallback6(
2262
2433
  async (args) => {
2263
2434
  if (abortControllerRef.current) {
2264
2435
  abortControllerRef.current.abort();
@@ -2388,5 +2559,7 @@ export {
2388
2559
  useEncryption,
2389
2560
  useImageGeneration,
2390
2561
  useMemory,
2391
- useModels
2562
+ useModels,
2563
+ usePdf,
2564
+ useSearch
2392
2565
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reverbia/sdk",
3
- "version": "1.0.0-next.20251202225102",
3
+ "version": "1.0.0-next.20251204090034",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -57,7 +57,8 @@
57
57
  "homepage": "https://github.com/zeta-chain/ai-sdk#readme",
58
58
  "dependencies": {
59
59
  "@huggingface/transformers": "^3.8.0",
60
- "@reverbia/portal": "1.0.0-next.20251201184846",
60
+ "pdfjs-dist": "^4.10.38",
61
+ "@reverbia/portal": "1.0.0-next.20251202220311",
61
62
  "ai": "5.0.93"
62
63
  },
63
64
  "devDependencies": {