@alquimia-ai/tools 2.0.1 → 2.2.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 (60) hide show
  1. package/dist/actions/index.d.mts +2 -7
  2. package/dist/actions/index.d.ts +2 -7
  3. package/dist/actions/index.js +10 -8
  4. package/dist/actions/index.js.map +1 -1
  5. package/dist/actions/index.mjs +10 -8
  6. package/dist/actions/index.mjs.map +1 -1
  7. package/dist/adapters/fetch.d.mts +2 -1
  8. package/dist/adapters/fetch.d.ts +2 -1
  9. package/dist/adapters/fetch.js +6 -4
  10. package/dist/adapters/fetch.js.map +1 -1
  11. package/dist/adapters/fetch.mjs +6 -4
  12. package/dist/adapters/fetch.mjs.map +1 -1
  13. package/dist/adapters/index.d.mts +1 -1
  14. package/dist/adapters/index.d.ts +1 -1
  15. package/dist/adapters/index.js.map +1 -1
  16. package/dist/adapters/next.d.mts +2 -1
  17. package/dist/adapters/next.d.ts +2 -1
  18. package/dist/adapters/next.js +7 -5
  19. package/dist/adapters/next.js.map +1 -1
  20. package/dist/adapters/next.mjs +7 -5
  21. package/dist/adapters/next.mjs.map +1 -1
  22. package/dist/hooks/index.d.mts +5 -3
  23. package/dist/hooks/index.d.ts +5 -3
  24. package/dist/hooks/index.js +266 -65
  25. package/dist/hooks/index.js.map +1 -1
  26. package/dist/hooks/index.mjs +248 -47
  27. package/dist/hooks/index.mjs.map +1 -1
  28. package/dist/next/index.d.mts +6 -9
  29. package/dist/next/index.d.ts +6 -9
  30. package/dist/next/index.js +69 -64
  31. package/dist/next/index.js.map +1 -1
  32. package/dist/next/index.mjs +69 -64
  33. package/dist/next/index.mjs.map +1 -1
  34. package/dist/proxy.d.mts +2 -2
  35. package/dist/proxy.d.ts +2 -2
  36. package/dist/proxy.js +32 -9
  37. package/dist/proxy.js.map +1 -1
  38. package/dist/proxy.mjs +32 -9
  39. package/dist/proxy.mjs.map +1 -1
  40. package/dist/sdk/index.d.mts +15 -7
  41. package/dist/sdk/index.d.ts +15 -7
  42. package/dist/sdk/index.js +45 -26
  43. package/dist/sdk/index.js.map +1 -1
  44. package/dist/sdk/index.mjs +45 -26
  45. package/dist/sdk/index.mjs.map +1 -1
  46. package/dist/session.action-DirvOWt0.d.mts +3 -0
  47. package/dist/session.action-DirvOWt0.d.ts +3 -0
  48. package/dist/types/index.d.mts +79 -18
  49. package/dist/types/index.d.ts +79 -18
  50. package/dist/types/index.js.map +1 -1
  51. package/dist/types/index.mjs.map +1 -1
  52. package/dist/types-CIqszY3g.d.mts +53 -0
  53. package/dist/types-CIqszY3g.d.ts +53 -0
  54. package/dist/worklog/index.d.mts +29 -0
  55. package/dist/worklog/index.d.ts +29 -0
  56. package/dist/worklog/index.js +218 -0
  57. package/dist/worklog/index.js.map +1 -0
  58. package/dist/worklog/index.mjs +195 -0
  59. package/dist/worklog/index.mjs.map +1 -0
  60. package/package.json +6 -1
@@ -4,6 +4,7 @@ import { AlquimiaAdapter } from '../adapters/index.js';
4
4
  import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-BJTXCtI3.js';
5
5
  import { AlquimiaMessage, ToolEvent, AIMessageChunk, RatingData } from '../types/index.js';
6
6
  import { createMessageId } from '../utils/index.js';
7
+ import { W as WorklogState } from '../types-CIqszY3g.js';
7
8
  import '@elastic/apm-rum';
8
9
  import 'ai';
9
10
 
@@ -20,7 +21,8 @@ interface UseAlquimiaConfig {
20
21
  options?: {
21
22
  enforceCharacterization?: boolean;
22
23
  userId?: string;
23
- extraData?: any;
24
+ extraInstructions?: Record<string, string>;
25
+ worklog?: boolean;
24
26
  };
25
27
  }
26
28
  declare function useAlquimia(config: UseAlquimiaConfig): {
@@ -48,15 +50,15 @@ declare function useAlquimia(config: UseAlquimiaConfig): {
48
50
  lastRequest: string | null;
49
51
  messages: AlquimiaMessage[];
50
52
  populateMessages: (messages: AlquimiaMessage[]) => void;
51
- processMessageChunk: (messageId: string, chunk: string, error_code?: string, error_detail?: string, stream_id?: string, additionalInfo?: string, loading?: boolean, tooler?: ToolEvent[], thinkings?: any[]) => void;
53
+ processMessageChunk: (messageId: string, chunk: string, error_code?: string, error_detail?: string, taskid?: string, additionalInfo?: string, loading?: boolean, tooler?: ToolEvent[], thinkings?: any[]) => void;
52
54
  sendMessage: (message: string, callBack: (chunk: AIMessageChunk) => void, traceParentId?: string, sessionId?: string) => Promise<void>;
53
55
  sessionId: string | null;
54
56
  setActiveTool: react.Dispatch<any>;
55
57
  setSessionId: react.Dispatch<react.SetStateAction<string | null>>;
56
58
  setLastRequest: react.Dispatch<react.SetStateAction<string | null>>;
57
59
  setIsAudioRecording: react.Dispatch<react.SetStateAction<boolean>>;
58
- evaluationStrategy: string;
59
60
  hasThinkings: boolean;
61
+ worklog: WorklogState | undefined;
60
62
  attachments: File[];
61
63
  addAttachment: (file: File) => void;
62
64
  addAttachments: (files: File[]) => void;
@@ -36,7 +36,7 @@ __export(hooks_exports, {
36
36
  module.exports = __toCommonJS(hooks_exports);
37
37
 
38
38
  // src/hooks/alquimia.hook.tsx
39
- var import_react = require("react");
39
+ var import_react2 = require("react");
40
40
 
41
41
  // src/sdk/alquimia-sdk.ts
42
42
  var import_axios = __toESM(require("axios"));
@@ -44,12 +44,11 @@ var AlquimiaSDK = class {
44
44
  constructor(assistantId, adapter, options = {}) {
45
45
  this.conversationId = null;
46
46
  this.sessionId = null;
47
+ // Internal subscription id from infer (`taskid` on the wire).
47
48
  this.streamId = null;
48
- this.evaluationStrategy = null;
49
49
  this.tools = [];
50
- this.extraData = null;
50
+ this.extraInstructions = null;
51
51
  this.assistantConfig = null;
52
- this.forceProfile = {};
53
52
  this.userId = null;
54
53
  this.attachments = [];
55
54
  this.attachmentResponses = [];
@@ -115,12 +114,8 @@ var AlquimiaSDK = class {
115
114
  this.tools = tools;
116
115
  return this;
117
116
  }
118
- withExtraData(extraData) {
119
- this.extraData = extraData;
120
- return this;
121
- }
122
- withForceProfile(forceProfile) {
123
- this.forceProfile = forceProfile;
117
+ withExtraInstructions(extraInstructions) {
118
+ this.extraInstructions = extraInstructions;
124
119
  return this;
125
120
  }
126
121
  withAssistantConfig(assistantConfig) {
@@ -134,9 +129,6 @@ var AlquimiaSDK = class {
134
129
  getEnforceCharacterization() {
135
130
  return this.enforceCharacterization ?? true;
136
131
  }
137
- getEvaluationStrategy() {
138
- return this.evaluationStrategy;
139
- }
140
132
  textToSpeech(text) {
141
133
  if (!this.whisperProvider) {
142
134
  throw new Error("Whisper provider not initialized");
@@ -157,25 +149,29 @@ var AlquimiaSDK = class {
157
149
  }
158
150
  const inferUrl = this.adapter.resolveInferUrl(this.assistantId);
159
151
  const adapterHeaders = this.adapter.getHeaders?.() ?? {};
152
+ const hasClientTools = Array.isArray(this.tools) && this.tools.length > 0;
160
153
  const initMessage = {
161
154
  query,
162
155
  session_id: this.conversationId,
163
- ...this.extraData && { extra_data: this.extraData },
164
- force_profile: this.forceProfile,
165
- ...this.assistantConfig && { config: this.assistantConfig },
166
- tools: this.tools,
167
156
  user_id: this.userId,
168
- attachments: this.attachments
157
+ ...this.extraInstructions && { extra_instructions: this.extraInstructions },
158
+ ...this.assistantConfig && { config: this.assistantConfig },
159
+ ...hasClientTools && {
160
+ evaluation_strategy: {
161
+ evaluation_strategy_id: "native",
162
+ tool_schemas: this.tools
163
+ }
164
+ }
169
165
  };
170
166
  const result = (await this.axiosInstance.post(inferUrl, initMessage, {
171
167
  headers: {
172
168
  "Content-Type": "application/json",
173
169
  "x-trace-parent": traceParent || "",
174
- ...adapterHeaders
170
+ ...adapterHeaders,
171
+ ...this.buildIdentityHeaders()
175
172
  }
176
173
  })).data;
177
- this.evaluationStrategy = result?.config?.dante?.profile?.evaluation_strategy?.evaluation_strategy_id ?? null;
178
- this.streamId = result.stream_id;
174
+ this.streamId = result.taskid ?? null;
179
175
  this.attachmentResponses = result.attachments ?? [];
180
176
  this.attachments = [];
181
177
  return this;
@@ -210,21 +206,40 @@ var AlquimiaSDK = class {
210
206
  }
211
207
  return this.loggerProvider.logError(message, error, data);
212
208
  }
209
+ /**
210
+ * @deprecated The runtime no longer returns attachment IDs from the infer
211
+ * response — attachments are uploaded as standalone blobs and linked to the
212
+ * session via headers. Always returns `[]`; kept for source compatibility.
213
+ */
213
214
  getAttachmentResponses() {
214
215
  return this.attachmentResponses;
215
216
  }
216
- async uploadAttachment(file, attachmentId) {
217
- if (!this.streamId || !attachmentId) {
218
- throw new Error("Stream or attachment ID not initialized");
219
- }
220
- const url = this.adapter.resolveAttachmentUrl(this.streamId, attachmentId);
217
+ async uploadAttachment(file, _attachmentId) {
218
+ const url = this.adapter.resolveBlobUploadUrl();
221
219
  const adapterHeaders = this.adapter.getHeaders?.() ?? {};
222
220
  const formData = new FormData();
223
221
  formData.append("file", file);
224
222
  await this.axiosInstance.post(url, formData, {
225
- headers: { "Content-Type": "multipart/form-data", ...adapterHeaders }
223
+ headers: {
224
+ "Content-Type": "multipart/form-data",
225
+ ...adapterHeaders,
226
+ ...this.buildIdentityHeaders()
227
+ }
226
228
  });
227
229
  }
230
+ /**
231
+ * Identity headers (kebab-case) required by `/context/blob/upload` and
232
+ * the rest of the runtime's internal endpoints introduced in v0.2.0→next.
233
+ */
234
+ buildIdentityHeaders() {
235
+ const headers = {
236
+ "assistant-id": this.assistantId
237
+ };
238
+ if (this.conversationId) headers["session-id"] = this.conversationId;
239
+ if (this.userId) headers["user-id"] = this.userId;
240
+ if (this.streamId) headers["task-id"] = this.streamId;
241
+ return headers;
242
+ }
228
243
  getUrlStream() {
229
244
  if (!this.streamId) {
230
245
  throw new Error("Stream ID not initialized. Call sendMessage() first");
@@ -234,6 +249,10 @@ var AlquimiaSDK = class {
234
249
  getStreamId() {
235
250
  return this.streamId;
236
251
  }
252
+ /** Alias for {@link getStreamId} — same value as infer `taskid`. */
253
+ getTaskId() {
254
+ return this.streamId;
255
+ }
237
256
  };
238
257
  var alquimia_sdk_default = AlquimiaSDK;
239
258
 
@@ -319,9 +338,169 @@ function mergeToolEvents(initial, toolEvents) {
319
338
  );
320
339
  }
321
340
 
341
+ // src/worklog/types.ts
342
+ function initialWorklogState(taskId = null) {
343
+ return { taskId, status: "idle", answer: null, nodes: [], index: {}, raw: [] };
344
+ }
345
+
346
+ // src/worklog/registry.ts
347
+ var asRecord = (data) => data && typeof data === "object" ? data : {};
348
+ var toolTitle = (r) => {
349
+ const name = asRecord(r.data).name;
350
+ return typeof name === "string" && name.length > 0 ? `Tool: ${name}` : "Tool";
351
+ };
352
+ var agentTitle = (r) => {
353
+ const name = asRecord(r.data).name;
354
+ return typeof name === "string" && name.length > 0 ? `Agent: ${name}` : "Agent-to-agent";
355
+ };
356
+ var constTitle = (label) => () => label;
357
+ var EVENT_REGISTRY = {
358
+ // Run envelope
359
+ AssistantInference: { kind: "answer", role: "run-open", title: constTitle("Inference started") },
360
+ AssistantInferenceResponse: { kind: "answer", role: "run-close", title: constTitle("Answer") },
361
+ // Safeguard
362
+ ShieldInference: { kind: "safeguard", role: "open", title: constTitle("Safeguard") },
363
+ ShieldInferenceResponse: { kind: "safeguard", role: "close", title: constTitle("Safeguard") },
364
+ // Reasoning
365
+ ResponseInference: { kind: "reasoning", role: "open", title: constTitle("Reasoning") },
366
+ ResponseInferenceResponse: { kind: "reasoning", role: "close", title: constTitle("Reasoning") },
367
+ // Tools (server + subclasses) and their responses
368
+ ServerToolExecution: { kind: "tool", role: "open", title: toolTitle },
369
+ BuiltinToolExecution: { kind: "tool", role: "open", title: toolTitle },
370
+ UnknownToolExecution: { kind: "tool", role: "open", title: toolTitle },
371
+ ClientToolExecution: { kind: "tool", role: "open", title: toolTitle, pending: true },
372
+ ToolExecutionResponse: { kind: "tool", role: "close", title: toolTitle },
373
+ BuiltinToolExecutionResponse: { kind: "tool", role: "close", title: toolTitle },
374
+ // Tool schema discovery
375
+ ToolSchema: { kind: "tool", role: "open", title: constTitle("Tool schema") },
376
+ ToolSchemaResponse: { kind: "tool", role: "close", title: constTitle("Tool schema") },
377
+ // Agent-to-agent
378
+ A2AInference: { kind: "a2a", role: "open", title: agentTitle },
379
+ AgentDiscovery: { kind: "a2a", role: "open", title: constTitle("Agent discovery") },
380
+ AgentDiscoveryResponse: { kind: "a2a", role: "close", title: constTitle("Agent discovery") },
381
+ // Memory / persistence
382
+ ContextPersistence: { kind: "memory", role: "open", title: constTitle("Memory persistence") },
383
+ ContextFlush: { kind: "memory", role: "open", title: constTitle("Memory flush") },
384
+ ContextFlushResponse: { kind: "memory", role: "close", title: constTitle("Memory flush") },
385
+ // Human approval
386
+ HumanApprovalRequired: {
387
+ kind: "tool",
388
+ role: "open",
389
+ title: constTitle("Human approval required"),
390
+ pending: true
391
+ },
392
+ HumanApprovalRequiredResponse: { kind: "tool", role: "close", title: constTitle("Human approval") }
393
+ };
394
+ function resolveInterpreter(eventClass) {
395
+ if (Object.prototype.hasOwnProperty.call(EVENT_REGISTRY, eventClass)) {
396
+ return EVENT_REGISTRY[eventClass];
397
+ }
398
+ return {
399
+ kind: "unknown",
400
+ role: "open",
401
+ title: (r) => r.event_class
402
+ };
403
+ }
404
+
405
+ // src/worklog/reducer.ts
406
+ var asString = (v) => typeof v === "string" ? v : v == null ? "" : JSON.stringify(v);
407
+ var nodeDepth = (record) => {
408
+ const d = record.data && typeof record.data === "object" ? record.data.depth : void 0;
409
+ return typeof d === "number" ? d : 0;
410
+ };
411
+ var makeOpenNode = (record, interp, id) => ({
412
+ id,
413
+ kind: interp.kind,
414
+ eventClass: record.event_class,
415
+ status: interp.pending ? "pending" : "running",
416
+ title: interp.title(record),
417
+ startedAt: record.date_submitted,
418
+ depth: nodeDepth(record),
419
+ children: [],
420
+ command: record.data,
421
+ raw: [record]
422
+ });
423
+ var makeClosedNode = (record, interp, id) => ({
424
+ id,
425
+ kind: interp.kind,
426
+ eventClass: record.event_class,
427
+ status: record.status === "error" ? "failed" : "completed",
428
+ title: interp.title(record),
429
+ startedAt: record.date_submitted,
430
+ endedAt: record.date_submitted,
431
+ depth: nodeDepth(record),
432
+ children: [],
433
+ response: record.data,
434
+ error: record.status === "error" ? asString(record.data) : void 0,
435
+ raw: [record]
436
+ });
437
+ function reduceWorklog(state, record) {
438
+ const interp = resolveInterpreter(record.event_class);
439
+ const next = {
440
+ ...state,
441
+ nodes: state.nodes.slice(),
442
+ index: { ...state.index },
443
+ raw: [...state.raw, record]
444
+ };
445
+ if (interp.role === "ignore") return next;
446
+ if (interp.role === "run-open") {
447
+ next.status = "running";
448
+ return next;
449
+ }
450
+ if (interp.role === "run-close") {
451
+ next.answer = asString(record.data) || null;
452
+ next.status = record.status === "error" ? "error" : "success";
453
+ return next;
454
+ }
455
+ const key = record.control_id ?? `${record.event_class}-${next.raw.length}`;
456
+ if (interp.role === "close") {
457
+ const pos2 = Object.prototype.hasOwnProperty.call(next.index, key) ? next.index[key] : void 0;
458
+ if (pos2 != null) {
459
+ const existing = next.nodes[pos2];
460
+ next.nodes[pos2] = {
461
+ ...existing,
462
+ status: record.status === "error" ? "failed" : "completed",
463
+ endedAt: record.date_submitted,
464
+ response: record.data,
465
+ error: record.status === "error" ? asString(record.data) : existing.error,
466
+ raw: [...existing.raw, record]
467
+ };
468
+ } else {
469
+ next.index[key] = next.nodes.length;
470
+ next.nodes.push(makeClosedNode(record, interp, key));
471
+ }
472
+ if (record.status === "error") next.status = "error";
473
+ return next;
474
+ }
475
+ const pos = Object.prototype.hasOwnProperty.call(next.index, key) ? next.index[key] : void 0;
476
+ if (pos != null) {
477
+ const existing = next.nodes[pos];
478
+ next.nodes[pos] = { ...existing, raw: [...existing.raw, record] };
479
+ } else {
480
+ next.index[key] = next.nodes.length;
481
+ next.nodes.push(makeOpenNode(record, interp, key));
482
+ }
483
+ return next;
484
+ }
485
+
486
+ // src/worklog/use-worklog.ts
487
+ var import_react = require("react");
488
+
489
+ // src/worklog/from-frame.ts
490
+ function frameToRecord(frame) {
491
+ const status = frame.status === "success" || frame.status === "error" ? frame.status : null;
492
+ return {
493
+ event_class: typeof frame.event_class === "string" && frame.event_class.length > 0 ? frame.event_class : "Unknown",
494
+ control_id: frame.control_id ?? null,
495
+ data: frame.data,
496
+ status,
497
+ date_submitted: typeof frame.date_submitted === "string" ? frame.date_submitted : ""
498
+ };
499
+ }
500
+
322
501
  // src/hooks/alquimia.hook.tsx
323
502
  function useAlquimia(config) {
324
- const sdk = (0, import_react.useMemo)(() => {
503
+ const sdk = (0, import_react2.useMemo)(() => {
325
504
  const instance = new alquimia_sdk_default(config.assistantId, config.adapter, {
326
505
  enforceCharacterization: config.options?.enforceCharacterization
327
506
  });
@@ -331,24 +510,28 @@ function useAlquimia(config) {
331
510
  if (config.providers?.ratings) instance.withRatingsProvider(config.providers.ratings);
332
511
  if (config.providers?.logger) instance.withLoggerProvider(config.providers.logger);
333
512
  if (config.options?.userId) instance.withUserId(config.options.userId);
334
- if (config.options?.extraData) instance.withExtraData(config.options.extraData);
513
+ if (config.options?.extraInstructions) instance.withExtraInstructions(config.options.extraInstructions);
335
514
  return instance;
336
515
  }, [config.assistantId, config.adapter]);
337
- const [input, setInput] = (0, import_react.useState)("");
338
- const [isMessageLoading, setIsMessageLoading] = (0, import_react.useState)(false);
339
- const [isStreamingLoading, setIsStreamingLoading] = (0, import_react.useState)(false);
340
- const [isMessageStreaming, setIsMessageStreaming] = (0, import_react.useState)(false);
341
- const [streamingMessageId, setStreamingMessageId] = (0, import_react.useState)(null);
342
- const [isAudioRecording, setIsAudioRecording] = (0, import_react.useState)(false);
343
- const [messages, setMessages] = (0, import_react.useState)([]);
344
- const eventSourceRef = (0, import_react.useRef)(null);
345
- const [sessionId, setSessionId] = (0, import_react.useState)(null);
346
- const [activeTool, setActiveTool] = (0, import_react.useState)(null);
347
- const [lastRequest, setLastRequest] = (0, import_react.useState)(null);
348
- const [evaluationStrategy, setEvaluationStrategy] = (0, import_react.useState)("");
349
- const [hasThinkings, setHasThinkings] = (0, import_react.useState)(false);
350
- const [attachments, setAttachments] = (0, import_react.useState)([]);
351
- const [isUploadingAttachments, setIsUploadingAttachments] = (0, import_react.useState)(false);
516
+ const [input, setInput] = (0, import_react2.useState)("");
517
+ const [isMessageLoading, setIsMessageLoading] = (0, import_react2.useState)(false);
518
+ const [isStreamingLoading, setIsStreamingLoading] = (0, import_react2.useState)(false);
519
+ const [isMessageStreaming, setIsMessageStreaming] = (0, import_react2.useState)(false);
520
+ const [streamingMessageId, setStreamingMessageId] = (0, import_react2.useState)(null);
521
+ const [isAudioRecording, setIsAudioRecording] = (0, import_react2.useState)(false);
522
+ const [messages, setMessages] = (0, import_react2.useState)([]);
523
+ const eventSourceRef = (0, import_react2.useRef)(null);
524
+ const streamUserCancelledRef = (0, import_react2.useRef)(false);
525
+ const [sessionId, setSessionId] = (0, import_react2.useState)(null);
526
+ const [activeTool, setActiveTool] = (0, import_react2.useState)(null);
527
+ const [lastRequest, setLastRequest] = (0, import_react2.useState)(null);
528
+ const [hasThinkings, setHasThinkings] = (0, import_react2.useState)(false);
529
+ const worklogEnabled = config.options?.worklog ?? false;
530
+ const [worklog, setWorklog] = (0, import_react2.useState)(
531
+ worklogEnabled ? initialWorklogState() : void 0
532
+ );
533
+ const [attachments, setAttachments] = (0, import_react2.useState)([]);
534
+ const [isUploadingAttachments, setIsUploadingAttachments] = (0, import_react2.useState)(false);
352
535
  const isLoading = isMessageLoading || isStreamingLoading || isUploadingAttachments;
353
536
  function cleanMessages() {
354
537
  setMessages([]);
@@ -366,7 +549,7 @@ function useAlquimia(config) {
366
549
  function clearAttachments() {
367
550
  setAttachments([]);
368
551
  }
369
- function processMessageChunk(messageId, chunk, error_code, error_detail, stream_id, additionalInfo, loading, tooler, thinkings) {
552
+ function processMessageChunk(messageId, chunk, error_code, error_detail, taskid, additionalInfo, loading, tooler, thinkings) {
370
553
  setMessages((currentMessages) => {
371
554
  const messageIndex = currentMessages.findIndex((message) => message?.id === messageId);
372
555
  if (messageIndex !== -1) {
@@ -378,7 +561,7 @@ function useAlquimia(config) {
378
561
  role: updatedMessages[messageIndex]?.role || "assistant",
379
562
  error_code,
380
563
  error_detail,
381
- stream_id,
564
+ taskid,
382
565
  additionalInfo,
383
566
  created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
384
567
  loading,
@@ -399,7 +582,7 @@ function useAlquimia(config) {
399
582
  id: messageId,
400
583
  error_code,
401
584
  error_detail,
402
- stream_id,
585
+ taskid,
403
586
  created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
404
587
  loading,
405
588
  tooler: mergeToolEvents([], tooler),
@@ -421,7 +604,7 @@ function useAlquimia(config) {
421
604
  chunk?.answer || "",
422
605
  chunk?.error_code,
423
606
  chunk?.error_detail,
424
- chunk?.stream_id,
607
+ chunk?.taskid,
425
608
  options?.additionalInfo,
426
609
  chunk?.loading,
427
610
  chunk?.tooler,
@@ -461,6 +644,7 @@ function useAlquimia(config) {
461
644
  setMessages(messages2);
462
645
  }
463
646
  function handleLoadingCancel() {
647
+ streamUserCancelledRef.current = true;
464
648
  eventSourceRef.current?.close();
465
649
  eventSourceRef.current = null;
466
650
  setIsMessageLoading(false);
@@ -542,6 +726,7 @@ function useAlquimia(config) {
542
726
  }
543
727
  const streamUrl = response.getUrlStream();
544
728
  const streamId = response.getStreamId() || "";
729
+ streamUserCancelledRef.current = false;
545
730
  const streamState = {
546
731
  streamId,
547
732
  connectedAt: Date.now(),
@@ -550,10 +735,9 @@ function useAlquimia(config) {
550
735
  lastMessageAt: null,
551
736
  closedByClient: false
552
737
  };
738
+ if (worklogEnabled) setWorklog(initialWorklogState());
553
739
  const eventSource = new EventSource(streamUrl);
554
740
  eventSourceRef.current = eventSource;
555
- const evaluationStrategy2 = response.getEvaluationStrategy();
556
- setEvaluationStrategy(evaluationStrategy2);
557
741
  eventSource.onopen = () => {
558
742
  streamState.openedAt = Date.now();
559
743
  };
@@ -564,23 +748,37 @@ function useAlquimia(config) {
564
748
  };
565
749
  eventSource.onerror = () => {
566
750
  if (streamState.closedByClient) return;
751
+ if (streamUserCancelledRef.current) {
752
+ streamUserCancelledRef.current = false;
753
+ return;
754
+ }
567
755
  streamState.closedByClient = true;
568
756
  const elapsed = Date.now() - streamState.connectedAt;
569
757
  const sinceLastMessage = streamState.lastMessageAt ? Date.now() - streamState.lastMessageAt : null;
570
758
  cleanup(false, eventSource);
571
759
  let errorDetail;
572
760
  if (!streamState.openedAt) {
573
- errorDetail = `Stream failed to connect (after ${elapsed}ms). URL: ${streamUrl}`;
761
+ errorDetail = "Could not open the live response. Check your connection and try again.";
574
762
  } else if (streamState.messagesReceived === 0) {
575
- errorDetail = `Stream connected but received no messages before error (open for ${elapsed}ms).`;
763
+ errorDetail = "No response was received. Try again in a moment.";
576
764
  } else {
577
- errorDetail = `Stream dropped after ${streamState.messagesReceived} message(s), ${sinceLastMessage}ms since last message (total ${elapsed}ms). Possible timeout.`;
765
+ errorDetail = "The response was interrupted. Try again.";
766
+ }
767
+ if (typeof console !== "undefined" && console.debug) {
768
+ console.debug("[Alquimia] SSE transport error", {
769
+ streamUrl,
770
+ taskId: streamId,
771
+ opened: Boolean(streamState.openedAt),
772
+ messagesReceived: streamState.messagesReceived,
773
+ elapsedMs: elapsed,
774
+ sinceLastMessageMs: sinceLastMessage
775
+ });
578
776
  }
579
777
  callBack({
580
778
  type: "error",
581
779
  error_code: "STREAM_ERROR",
582
780
  error_detail: errorDetail,
583
- stream_id: streamId
781
+ taskid: streamId
584
782
  });
585
783
  };
586
784
  } catch (error) {
@@ -591,13 +789,17 @@ function useAlquimia(config) {
591
789
  setStreamingMessageId(null);
592
790
  callBack({
593
791
  type: "error",
594
- error_code: error.status?.toString() || "REQUEST_ERROR",
792
+ error_code: error.response?.status != null ? String(error.response.status) : "REQUEST_ERROR",
595
793
  error_detail: errMessage
596
794
  });
597
795
  }
598
796
  }
599
797
  function handleMessageEvent(event, callBack, eventSource, streamState) {
600
798
  const data = JSON.parse(event.data);
799
+ if (worklogEnabled) {
800
+ setWorklog((prev) => reduceWorklog(prev ?? initialWorklogState(), frameToRecord(data)));
801
+ }
802
+ const eventTaskId = data.taskid || "";
601
803
  if (data.errors?.length) {
602
804
  for (const error of data.errors) {
603
805
  const detail = error.error_detail || (error.data != null ? `${error.data} (controlId: ${error.control_id})` : "Unknown error");
@@ -605,7 +807,7 @@ function useAlquimia(config) {
605
807
  type: "error",
606
808
  error_code: error.event_class || error.status || "UNKNOWN_ERROR",
607
809
  error_detail: detail,
608
- stream_id: data.stream_id || ""
810
+ taskid: eventTaskId
609
811
  });
610
812
  }
611
813
  if (streamState) streamState.closedByClient = true;
@@ -619,10 +821,9 @@ function useAlquimia(config) {
619
821
  setHasThinkings(true);
620
822
  callBack({ type: "answer", thinkings: data.thinkings });
621
823
  }
622
- const response = data.response;
623
- const content = response?.event_class === "AssistantInferenceResponse" && typeof response.data === "string" ? response.data : null;
624
- if (content) {
625
- callBack({ type: "answer", answer: content });
824
+ if (data.event_class === "AssistantInferenceResponse") {
825
+ const final = data;
826
+ callBack({ type: "answer", answer: final.data });
626
827
  if (streamState) streamState.closedByClient = true;
627
828
  cleanup(false, eventSource);
628
829
  }
@@ -654,8 +855,8 @@ function useAlquimia(config) {
654
855
  setSessionId,
655
856
  setLastRequest,
656
857
  setIsAudioRecording,
657
- evaluationStrategy,
658
858
  hasThinkings,
859
+ worklog,
659
860
  attachments,
660
861
  addAttachment,
661
862
  addAttachments,
@@ -666,7 +867,7 @@ function useAlquimia(config) {
666
867
  }
667
868
 
668
869
  // src/hooks/useRatings.ts
669
- var import_react2 = require("react");
870
+ var import_react3 = require("react");
670
871
  var initialState = {
671
872
  ratingStars: 0,
672
873
  ratingThumbs: "",
@@ -685,9 +886,9 @@ function ratingReducer(state, action) {
685
886
  }
686
887
  }
687
888
  function useRatings({ assistantId, sendRating, topicId }) {
688
- const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
689
- const [hasReviewed, setHasReviewed] = (0, import_react2.useState)(false);
690
- const [state, dispatch] = (0, import_react2.useReducer)(ratingReducer, initialState);
889
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
890
+ const [hasReviewed, setHasReviewed] = (0, import_react3.useState)(false);
891
+ const [state, dispatch] = (0, import_react3.useReducer)(ratingReducer, initialState);
691
892
  const setRatingStars = (rating) => {
692
893
  dispatch({ type: "SET_RATING_STARS", payload: rating });
693
894
  };