@alquimia-ai/tools 2.4.0 → 2.7.0

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.
Files changed (77) hide show
  1. package/README.md +529 -19
  2. package/dist/actions/index.d.mts +2 -2
  3. package/dist/actions/index.d.ts +2 -2
  4. package/dist/actions/index.js +1 -1
  5. package/dist/actions/index.js.map +1 -1
  6. package/dist/actions/index.mjs +1 -1
  7. package/dist/actions/index.mjs.map +1 -1
  8. package/dist/{actions-CZU_GRy5.d.mts → actions-BjDPJdyA.d.mts} +1 -1
  9. package/dist/{actions-B0hfoYRd.d.ts → actions-CP1d4Ye1.d.ts} +1 -1
  10. package/dist/adapters/index.d.mts +2 -2
  11. package/dist/adapters/index.d.ts +2 -2
  12. package/dist/adapters/index.js.map +1 -1
  13. package/dist/genui/index.d.mts +3 -3
  14. package/dist/genui/index.d.ts +3 -3
  15. package/dist/genui/index.js +9 -1
  16. package/dist/genui/index.js.map +1 -1
  17. package/dist/genui/index.mjs +9 -1
  18. package/dist/genui/index.mjs.map +1 -1
  19. package/dist/hooks/index.d.mts +10 -10
  20. package/dist/hooks/index.d.ts +10 -10
  21. package/dist/hooks/index.js +88 -12
  22. package/dist/hooks/index.js.map +1 -1
  23. package/dist/hooks/index.mjs +88 -12
  24. package/dist/hooks/index.mjs.map +1 -1
  25. package/dist/next/index.js +23 -6
  26. package/dist/next/index.js.map +1 -1
  27. package/dist/next/index.mjs +23 -6
  28. package/dist/next/index.mjs.map +1 -1
  29. package/dist/providers/index.d.mts +4 -4
  30. package/dist/providers/index.d.ts +4 -4
  31. package/dist/providers/index.js +111 -110
  32. package/dist/providers/index.js.map +1 -1
  33. package/dist/providers/index.mjs +111 -110
  34. package/dist/providers/index.mjs.map +1 -1
  35. package/dist/{providers-BJTXCtI3.d.ts → providers-B4IOiGfr.d.mts} +8 -8
  36. package/dist/{providers-0Gi78uNQ.d.mts → providers-mx21gNgZ.d.ts} +8 -8
  37. package/dist/proxy.d.mts +4 -4
  38. package/dist/proxy.d.ts +4 -4
  39. package/dist/proxy.js +23 -6
  40. package/dist/proxy.js.map +1 -1
  41. package/dist/proxy.mjs +23 -6
  42. package/dist/proxy.mjs.map +1 -1
  43. package/dist/sdk/index.d.mts +39 -5
  44. package/dist/sdk/index.d.ts +39 -5
  45. package/dist/sdk/index.js +49 -6
  46. package/dist/sdk/index.js.map +1 -1
  47. package/dist/sdk/index.mjs +49 -6
  48. package/dist/sdk/index.mjs.map +1 -1
  49. package/dist/services/index.d.mts +3 -3
  50. package/dist/services/index.d.ts +3 -3
  51. package/dist/services/index.js.map +1 -1
  52. package/dist/services/index.mjs.map +1 -1
  53. package/dist/type-61gaZga-.d.mts +356 -0
  54. package/dist/type-D-JaSMkV.d.ts +356 -0
  55. package/dist/types/index.d.mts +80 -304
  56. package/dist/types/index.d.ts +80 -304
  57. package/dist/types/index.js.map +1 -1
  58. package/dist/types/index.mjs.map +1 -1
  59. package/dist/{types-DnfWUE9V.d.mts → types-CMVbyEv8.d.mts} +3 -2
  60. package/dist/{types-DnfWUE9V.d.ts → types-CMVbyEv8.d.ts} +3 -2
  61. package/dist/types-lOliroPw.d.mts +111 -0
  62. package/dist/types-lOliroPw.d.ts +111 -0
  63. package/dist/utils/index.d.mts +2 -2
  64. package/dist/utils/index.d.ts +2 -2
  65. package/dist/utils/index.js +1 -1
  66. package/dist/utils/index.js.map +1 -1
  67. package/dist/utils/index.mjs +1 -1
  68. package/dist/utils/index.mjs.map +1 -1
  69. package/dist/worklog/index.d.mts +5 -2
  70. package/dist/worklog/index.d.ts +5 -2
  71. package/dist/worklog/index.js +22 -1
  72. package/dist/worklog/index.js.map +1 -1
  73. package/dist/worklog/index.mjs +22 -1
  74. package/dist/worklog/index.mjs.map +1 -1
  75. package/package.json +1 -1
  76. package/dist/types-Dvu9y4WM.d.mts +0 -53
  77. package/dist/types-Dvu9y4WM.d.ts +0 -53
@@ -1,13 +1,13 @@
1
1
  import * as react from 'react';
2
2
  import { AlquimiaSDK } from '../sdk/index.mjs';
3
3
  import { AlquimiaAdapter } from '../adapters/index.mjs';
4
- import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-0Gi78uNQ.mjs';
5
- import { GenuiSurfaceItem, AlquimiaMessage, ToolEvent, AIMessageChunk, RatingData } from '../types/index.mjs';
4
+ import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-B4IOiGfr.mjs';
5
+ import { G as GenuiSurfaceItem, e as AlquimiaMessage, F as ToolEvent, a as AIMessageChunk, R as RatingData } from '../type-61gaZga-.mjs';
6
+ import { T as ToolExecutionResponse } from '../types-CMVbyEv8.mjs';
7
+ import { a as WorklogState } from '../types-lOliroPw.mjs';
6
8
  import { createMessageId } from '../utils/index.mjs';
7
- import { W as WorklogState } from '../types-Dvu9y4WM.mjs';
8
- import { T as ToolExecutionResponse } from '../types-DnfWUE9V.mjs';
9
9
  import { C as CatalogManifest } from '../registry-Bcu_ZYL1.mjs';
10
- import { U as UIAction } from '../actions-CZU_GRy5.mjs';
10
+ import { U as UIAction } from '../actions-BjDPJdyA.mjs';
11
11
  import '@elastic/apm-rum';
12
12
  import 'ai';
13
13
  import 'zod';
@@ -74,7 +74,7 @@ declare function useAlquimia(config: UseAlquimiaConfig): {
74
74
  messages: AlquimiaMessage[];
75
75
  populateMessages: (messages: AlquimiaMessage[]) => void;
76
76
  processMessageChunk: (messageId: string, chunk: string, error_code?: string, error_detail?: string, taskid?: string, additionalInfo?: string, loading?: boolean, tooler?: ToolEvent[], thinkings?: any[]) => void;
77
- sendMessage: (message: string, callBack: (chunk: AIMessageChunk) => void, traceParentId?: string, sessionId?: string) => Promise<void>;
77
+ sendMessage: (message: string, callBack: (_chunk: AIMessageChunk) => void, traceParentId?: string, sessionId?: string) => Promise<void>;
78
78
  sessionId: string | null;
79
79
  setActiveTool: react.Dispatch<any>;
80
80
  setSessionId: react.Dispatch<react.SetStateAction<string | null>>;
@@ -93,11 +93,11 @@ declare function useAlquimia(config: UseAlquimiaConfig): {
93
93
  interface UseRatingsParams {
94
94
  assistantId: string;
95
95
  topicId: string;
96
- sendRating: (ratingData: RatingData) => Promise<any>;
97
- onError?: (componentName: string, error: Error) => void;
96
+ sendRating: (_ratingData: RatingData) => Promise<any>;
97
+ onError?: (_componentName: string, _error: Error) => void;
98
98
  }
99
- declare function useRatings({ assistantId, sendRating, topicId }: UseRatingsParams): {
100
- handleRate: (key: string, value: any | string, onHandleRateSuccess: (success: boolean, err?: string) => void) => Promise<void>;
99
+ declare function useRatings({ assistantId, sendRating, topicId, onError }: UseRatingsParams): {
100
+ handleRate: (key: string, value: any | string, onHandleRateSuccess: (_success: boolean, _err?: string) => void) => Promise<void>;
101
101
  ratingStars: number;
102
102
  ratingThumbs: "" | "thumbsUp" | "thumbsDown";
103
103
  ratingComment: string;
@@ -1,13 +1,13 @@
1
1
  import * as react from 'react';
2
2
  import { AlquimiaSDK } from '../sdk/index.js';
3
3
  import { AlquimiaAdapter } from '../adapters/index.js';
4
- import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-BJTXCtI3.js';
5
- import { GenuiSurfaceItem, AlquimiaMessage, ToolEvent, AIMessageChunk, RatingData } from '../types/index.js';
4
+ import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-mx21gNgZ.js';
5
+ import { G as GenuiSurfaceItem, e as AlquimiaMessage, F as ToolEvent, a as AIMessageChunk, R as RatingData } from '../type-D-JaSMkV.js';
6
+ import { T as ToolExecutionResponse } from '../types-CMVbyEv8.js';
7
+ import { a as WorklogState } from '../types-lOliroPw.js';
6
8
  import { createMessageId } from '../utils/index.js';
7
- import { W as WorklogState } from '../types-Dvu9y4WM.js';
8
- import { T as ToolExecutionResponse } from '../types-DnfWUE9V.js';
9
9
  import { C as CatalogManifest } from '../registry-Bcu_ZYL1.js';
10
- import { U as UIAction } from '../actions-B0hfoYRd.js';
10
+ import { U as UIAction } from '../actions-CP1d4Ye1.js';
11
11
  import '@elastic/apm-rum';
12
12
  import 'ai';
13
13
  import 'zod';
@@ -74,7 +74,7 @@ declare function useAlquimia(config: UseAlquimiaConfig): {
74
74
  messages: AlquimiaMessage[];
75
75
  populateMessages: (messages: AlquimiaMessage[]) => void;
76
76
  processMessageChunk: (messageId: string, chunk: string, error_code?: string, error_detail?: string, taskid?: string, additionalInfo?: string, loading?: boolean, tooler?: ToolEvent[], thinkings?: any[]) => void;
77
- sendMessage: (message: string, callBack: (chunk: AIMessageChunk) => void, traceParentId?: string, sessionId?: string) => Promise<void>;
77
+ sendMessage: (message: string, callBack: (_chunk: AIMessageChunk) => void, traceParentId?: string, sessionId?: string) => Promise<void>;
78
78
  sessionId: string | null;
79
79
  setActiveTool: react.Dispatch<any>;
80
80
  setSessionId: react.Dispatch<react.SetStateAction<string | null>>;
@@ -93,11 +93,11 @@ declare function useAlquimia(config: UseAlquimiaConfig): {
93
93
  interface UseRatingsParams {
94
94
  assistantId: string;
95
95
  topicId: string;
96
- sendRating: (ratingData: RatingData) => Promise<any>;
97
- onError?: (componentName: string, error: Error) => void;
96
+ sendRating: (_ratingData: RatingData) => Promise<any>;
97
+ onError?: (_componentName: string, _error: Error) => void;
98
98
  }
99
- declare function useRatings({ assistantId, sendRating, topicId }: UseRatingsParams): {
100
- handleRate: (key: string, value: any | string, onHandleRateSuccess: (success: boolean, err?: string) => void) => Promise<void>;
99
+ declare function useRatings({ assistantId, sendRating, topicId, onError }: UseRatingsParams): {
100
+ handleRate: (key: string, value: any | string, onHandleRateSuccess: (_success: boolean, _err?: string) => void) => Promise<void>;
101
101
  ratingStars: number;
102
102
  ratingThumbs: "" | "thumbsUp" | "thumbsDown";
103
103
  ratingComment: string;
@@ -46,6 +46,11 @@ var AlquimiaSDK = class {
46
46
  this.sessionId = null;
47
47
  // Internal subscription id from infer (`taskid` on the wire).
48
48
  this.streamId = null;
49
+ // W3C traceparent for the current turn, so infer and stream share one trace.
50
+ this.traceParent = null;
51
+ // Registry version tag resolved by the runtime for this task (v0.5.1), so
52
+ // the tool-completion half of the turn lands on the same agentspace version.
53
+ this.versionTag = null;
49
54
  this.tools = [];
50
55
  this.extraInstructions = null;
51
56
  this.assistantConfig = null;
@@ -126,6 +131,19 @@ var AlquimiaSDK = class {
126
131
  this.userId = userId;
127
132
  return this;
128
133
  }
134
+ /**
135
+ * Pin inference to a cached registry version. Sent as the `version_tag`
136
+ * query parameter, which `POST /event/infer/{assistant_id}` accepts from
137
+ * **runtime v0.5.2** onward; older runtimes ignore it.
138
+ *
139
+ * Works on every version: pass a versioned assistant ref
140
+ * (`<agentspace>/<assistant>[:<tag>]`) as the `assistantId` instead — the
141
+ * runtime parses the tag out of the path itself.
142
+ */
143
+ withVersionTag(versionTag) {
144
+ this.versionTag = versionTag;
145
+ return this;
146
+ }
129
147
  getEnforceCharacterization() {
130
148
  return this.enforceCharacterization ?? true;
131
149
  }
@@ -141,19 +159,29 @@ var AlquimiaSDK = class {
141
159
  }
142
160
  return this.whisperProvider.speechToText(audio);
143
161
  }
144
- async sendMessage(query, traceParent) {
162
+ async sendMessage(query, options = {}) {
145
163
  if (!this.conversationId) {
146
164
  throw new Error(
147
165
  "Conversation not initialized. Call withConversationId() before sendMessage()"
148
166
  );
149
167
  }
150
- const inferUrl = this.adapter.resolveInferUrl(this.assistantId);
168
+ const opts = typeof options === "string" ? { traceParent: options } : options;
169
+ if (query === void 0 && !opts.inputAudio) {
170
+ throw new Error(
171
+ "AlquimiaSDK: sendMessage needs a query, an inputAudio blob, or both"
172
+ );
173
+ }
174
+ const baseInferUrl = this.adapter.resolveInferUrl(this.assistantId);
175
+ const inferUrl = this.versionTag ? `${baseInferUrl}${baseInferUrl.includes("?") ? "&" : "?"}version_tag=${encodeURIComponent(this.versionTag)}` : baseInferUrl;
151
176
  const adapterHeaders = this.adapter.getHeaders?.() ?? {};
152
177
  const hasClientTools = Array.isArray(this.tools) && this.tools.length > 0;
153
178
  const initMessage = {
154
- query,
179
+ ...query !== void 0 && { query },
155
180
  session_id: this.conversationId,
156
181
  user_id: this.userId,
182
+ ...opts.inputAudio && { input_audio: opts.inputAudio },
183
+ // Only sent when set: the runtime defaults `output_audio` to true.
184
+ ...opts.outputAudio !== void 0 && { output_audio: opts.outputAudio },
157
185
  ...this.extraInstructions && { extra_instructions: this.extraInstructions },
158
186
  ...this.assistantConfig && { config: this.assistantConfig },
159
187
  ...hasClientTools && {
@@ -166,12 +194,14 @@ var AlquimiaSDK = class {
166
194
  const result = (await this.axiosInstance.post(inferUrl, initMessage, {
167
195
  headers: {
168
196
  "Content-Type": "application/json",
169
- "x-trace-parent": traceParent || "",
197
+ ...opts.traceParent && { "x-trace-parent": opts.traceParent },
170
198
  ...adapterHeaders,
171
199
  ...this.buildIdentityHeaders()
172
200
  }
173
201
  })).data;
202
+ this.traceParent = opts.traceParent ?? null;
174
203
  this.streamId = result.taskid ?? null;
204
+ this.versionTag = result.versiontag ?? this.versionTag;
175
205
  this.attachmentResponses = result.attachments ?? [];
176
206
  this.attachments = [];
177
207
  return this;
@@ -198,6 +228,7 @@ var AlquimiaSDK = class {
198
228
  ...this.streamId && { taskid: this.streamId },
199
229
  ...this.conversationId && { sessionid: this.conversationId },
200
230
  ...this.userId && { userid: this.userId },
231
+ ...this.versionTag && { versiontag: this.versionTag },
201
232
  ...adapterHeaders
202
233
  };
203
234
  await this.axiosInstance.post(url, response, { headers });
@@ -240,18 +271,23 @@ var AlquimiaSDK = class {
240
271
  getAttachmentResponses() {
241
272
  return this.attachmentResponses;
242
273
  }
274
+ /**
275
+ * Upload a file into the session context. Returns the runtime {@link RuntimeBlob},
276
+ * which is what `sendMessage`'s `inputAudio` expects for audio inference.
277
+ */
243
278
  async uploadAttachment(file, _attachmentId) {
244
279
  const url = this.adapter.resolveBlobUploadUrl();
245
280
  const adapterHeaders = this.adapter.getHeaders?.() ?? {};
246
281
  const formData = new FormData();
247
282
  formData.append("file", file);
248
- await this.axiosInstance.post(url, formData, {
283
+ const response = await this.axiosInstance.post(url, formData, {
249
284
  headers: {
250
285
  "Content-Type": "multipart/form-data",
251
286
  ...adapterHeaders,
252
287
  ...this.buildIdentityHeaders()
253
288
  }
254
289
  });
290
+ return response.data;
255
291
  }
256
292
  /**
257
293
  * Identity headers (kebab-case) required by `/context/blob/upload` and
@@ -270,7 +306,10 @@ var AlquimiaSDK = class {
270
306
  if (!this.streamId) {
271
307
  throw new Error("Stream ID not initialized. Call sendMessage() first");
272
308
  }
273
- return this.adapter.resolveStreamUrl(this.streamId);
309
+ const url = this.adapter.resolveStreamUrl(this.streamId);
310
+ if (!this.traceParent) return url;
311
+ const separator = url.includes("?") ? "&" : "?";
312
+ return `${url}${separator}trace_parent=${encodeURIComponent(this.traceParent)}`;
274
313
  }
275
314
  getStreamId() {
276
315
  return this.streamId;
@@ -279,6 +318,10 @@ var AlquimiaSDK = class {
279
318
  getTaskId() {
280
319
  return this.streamId;
281
320
  }
321
+ /** Registry version tag resolved by the runtime for the current task, if any. */
322
+ getVersionTag() {
323
+ return this.versionTag;
324
+ }
282
325
  };
283
326
  var alquimia_sdk_default = AlquimiaSDK;
284
327
 
@@ -383,6 +426,14 @@ var agentTitle = (r) => {
383
426
  return typeof name === "string" && name.length > 0 ? `Agent: ${name}` : "Agent-to-agent";
384
427
  };
385
428
  var constTitle = (label) => () => label;
429
+ var shieldBlockTitle = (r) => {
430
+ const id = asRecord(r.data).shield_id;
431
+ return typeof id === "string" && id.length > 0 ? `Blocked by ${id}` : "Blocked by safeguard";
432
+ };
433
+ var knowledgeTitle = (r) => {
434
+ const query = asRecord(r.data).query;
435
+ return typeof query === "string" && query.length > 0 ? `Knowledge: ${query}` : "Knowledge retrieval";
436
+ };
386
437
  var EVENT_REGISTRY = {
387
438
  // Run envelope
388
439
  AssistantInference: { kind: "answer", role: "run-open", title: constTitle("Inference started") },
@@ -390,6 +441,9 @@ var EVENT_REGISTRY = {
390
441
  // Safeguard
391
442
  ShieldInference: { kind: "safeguard", role: "open", title: constTitle("Safeguard") },
392
443
  ShieldInferenceResponse: { kind: "safeguard", role: "close", title: constTitle("Safeguard") },
444
+ // Emitted when a shield enforcement decision blocks the request (core 0.5.x).
445
+ // Response-only: the reducer opens it already closed when no command matched.
446
+ ShieldBlockedResponse: { kind: "safeguard", role: "close", title: shieldBlockTitle },
393
447
  // Reasoning
394
448
  ResponseInference: { kind: "reasoning", role: "open", title: constTitle("Reasoning") },
395
449
  ResponseInferenceResponse: { kind: "reasoning", role: "close", title: constTitle("Reasoning") },
@@ -407,6 +461,14 @@ var EVENT_REGISTRY = {
407
461
  A2AInference: { kind: "a2a", role: "open", title: agentTitle },
408
462
  AgentDiscovery: { kind: "a2a", role: "open", title: constTitle("Agent discovery") },
409
463
  AgentDiscoveryResponse: { kind: "a2a", role: "close", title: constTitle("Agent discovery") },
464
+ // Knowledge retrieval (RAG) — core 0.5.x
465
+ KnowledgeRetrieval: { kind: "knowledge", role: "open", title: knowledgeTitle },
466
+ KnowledgeRetrievalResponse: { kind: "knowledge", role: "close", title: knowledgeTitle },
467
+ // Speech pipeline — core 0.5.x
468
+ SpeechTranscription: { kind: "speech", role: "open", title: constTitle("Speech-to-text") },
469
+ SpeechTranscriptionResponse: { kind: "speech", role: "close", title: constTitle("Speech-to-text") },
470
+ SpeechSynthesis: { kind: "speech", role: "open", title: constTitle("Text-to-speech") },
471
+ SpeechSynthesisResponse: { kind: "speech", role: "close", title: constTitle("Text-to-speech") },
410
472
  // Memory / persistence
411
473
  ContextPersistence: { kind: "memory", role: "open", title: constTitle("Memory persistence") },
412
474
  ContextFlush: { kind: "memory", role: "open", title: constTitle("Memory flush") },
@@ -523,7 +585,9 @@ function frameToRecord(frame) {
523
585
  control_id: frame.control_id ?? null,
524
586
  data: frame.data,
525
587
  status,
526
- date_submitted: typeof frame.date_submitted === "string" ? frame.date_submitted : ""
588
+ date_submitted: typeof frame.date_submitted === "string" ? frame.date_submitted : "",
589
+ entry_hash: frame.entry_hash ?? null,
590
+ previous_hash: frame.previous_hash ?? null
527
591
  };
528
592
  }
529
593
 
@@ -732,7 +796,15 @@ var surfaceShape = import_zod3.z.object({
732
796
  });
733
797
  var UAX31_ID = /^[\p{XID_Start}_][\p{XID_Continue}]*$/u;
734
798
  function validateProps(node, def2) {
735
- const { id, component, children, child, binding, action, ...props } = node;
799
+ const {
800
+ id,
801
+ component: _component,
802
+ children: _children,
803
+ child: _child,
804
+ binding: _binding,
805
+ action: _action,
806
+ ...props
807
+ } = node;
736
808
  const parsed = def2.schema.safeParse(props);
737
809
  if (parsed.success) return { ok: true, value: parsed.data, errors: [] };
738
810
  return {
@@ -1395,14 +1467,14 @@ function ratingReducer(state, action) {
1395
1467
  return state;
1396
1468
  }
1397
1469
  }
1398
- function useRatings({ assistantId, sendRating, topicId }) {
1470
+ function useRatings({ assistantId, sendRating, topicId, onError }) {
1399
1471
  const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
1400
1472
  const [hasReviewed, setHasReviewed] = (0, import_react3.useState)(false);
1401
1473
  const [state, dispatch] = (0, import_react3.useReducer)(ratingReducer, initialState);
1402
1474
  const setRatingStars = (rating) => {
1403
1475
  dispatch({ type: "SET_RATING_STARS", payload: rating });
1404
1476
  };
1405
- const setRatingThumbs = (rating) => {
1477
+ const _setRatingThumbs = (rating) => {
1406
1478
  dispatch({ type: "SET_RATING_THUMBS", payload: rating });
1407
1479
  };
1408
1480
  const setRatingComment = (comment) => {
@@ -1425,7 +1497,9 @@ function useRatings({ assistantId, sendRating, topicId }) {
1425
1497
  const response = await sendRating(ratingObj);
1426
1498
  if (!response.success) {
1427
1499
  setIsLoading(false);
1428
- onHandleRateSuccess(false, response.error.message);
1500
+ const error = new Error(response.error?.message ?? "Failed to send rating");
1501
+ onHandleRateSuccess(false, error.message);
1502
+ onError?.("useRatings", error);
1429
1503
  return;
1430
1504
  }
1431
1505
  if (key === "score") {
@@ -1438,7 +1512,9 @@ function useRatings({ assistantId, sendRating, topicId }) {
1438
1512
  onHandleRateSuccess(true);
1439
1513
  } catch (err) {
1440
1514
  setIsLoading(false);
1441
- onHandleRateSuccess(false, String(err));
1515
+ const error = err instanceof Error ? err : new Error(String(err));
1516
+ onHandleRateSuccess(false, error.message);
1517
+ onError?.("useRatings", error);
1442
1518
  }
1443
1519
  };
1444
1520
  return {