@alquimia-ai/tools 1.13.2 → 2.1.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.
- package/dist/actions/index.d.mts +2 -17
- package/dist/actions/index.d.ts +2 -17
- package/dist/actions/index.js +47 -152
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/index.mjs +47 -152
- package/dist/actions/index.mjs.map +1 -1
- package/dist/adapters/fetch.d.mts +12 -0
- package/dist/adapters/fetch.d.ts +12 -0
- package/dist/adapters/fetch.js +44 -0
- package/dist/adapters/fetch.js.map +1 -0
- package/dist/adapters/fetch.mjs +23 -0
- package/dist/adapters/fetch.mjs.map +1 -0
- package/dist/adapters/index.d.mts +11 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.js +19 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/index.mjs +1 -0
- package/dist/adapters/index.mjs.map +1 -0
- package/dist/adapters/next.d.mts +10 -0
- package/dist/adapters/next.d.ts +10 -0
- package/dist/adapters/next.js +42 -0
- package/dist/adapters/next.js.map +1 -0
- package/dist/adapters/next.mjs +21 -0
- package/dist/adapters/next.mjs.map +1 -0
- package/dist/hooks/index.d.mts +23 -4
- package/dist/hooks/index.d.ts +23 -4
- package/dist/hooks/index.js +292 -57
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +283 -58
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/next/index.d.mts +46 -0
- package/dist/next/index.d.ts +46 -0
- package/dist/next/index.js +337 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/index.mjs +314 -0
- package/dist/next/index.mjs.map +1 -0
- package/dist/providers/index.d.mts +7 -3
- package/dist/providers/index.d.ts +7 -3
- package/dist/providers/index.js +15 -14
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/index.mjs +15 -14
- package/dist/providers/index.mjs.map +1 -1
- package/dist/proxy.d.mts +15 -0
- package/dist/proxy.d.ts +15 -0
- package/dist/proxy.js +170 -0
- package/dist/proxy.js.map +1 -0
- package/dist/proxy.mjs +149 -0
- package/dist/proxy.mjs.map +1 -0
- package/dist/sdk/index.d.mts +22 -20
- package/dist/sdk/index.d.ts +22 -20
- package/dist/sdk/index.js +85 -66
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/index.mjs +85 -66
- package/dist/sdk/index.mjs.map +1 -1
- package/dist/services/index.d.mts +25 -3
- package/dist/services/index.d.ts +25 -3
- package/dist/session.action-DirvOWt0.d.mts +3 -0
- package/dist/session.action-DirvOWt0.d.ts +3 -0
- package/dist/types/index.d.mts +79 -18
- package/dist/types/index.d.ts +79 -18
- package/dist/types/index.js.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/package.json +35 -5
- package/dist/providers/elastic/index.d.mts +0 -23
- package/dist/providers/elastic/index.d.ts +0 -23
- package/dist/providers/elastic/index.js +0 -102
- package/dist/providers/elastic/index.js.map +0 -1
- package/dist/providers/elastic/index.mjs +0 -69
- package/dist/providers/elastic/index.mjs.map +0 -1
- package/dist/services/apm/index.d.mts +0 -26
- package/dist/services/apm/index.d.ts +0 -26
- package/dist/services/apm/index.js +0 -86
- package/dist/services/apm/index.js.map +0 -1
- package/dist/services/apm/index.mjs +0 -63
- package/dist/services/apm/index.mjs.map +0 -1
package/dist/hooks/index.mjs
CHANGED
|
@@ -1,5 +1,223 @@
|
|
|
1
1
|
// src/hooks/alquimia.hook.tsx
|
|
2
|
-
import { useRef, useState } from "react";
|
|
2
|
+
import { useMemo, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
// src/sdk/alquimia-sdk.ts
|
|
5
|
+
import axios from "axios";
|
|
6
|
+
var AlquimiaSDK = class {
|
|
7
|
+
constructor(assistantId, adapter, options = {}) {
|
|
8
|
+
this.conversationId = null;
|
|
9
|
+
this.sessionId = null;
|
|
10
|
+
// Internal subscription id from infer (`taskid` on the wire).
|
|
11
|
+
this.streamId = null;
|
|
12
|
+
this.tools = [];
|
|
13
|
+
this.extraInstructions = null;
|
|
14
|
+
this.assistantConfig = null;
|
|
15
|
+
this.userId = null;
|
|
16
|
+
this.attachments = [];
|
|
17
|
+
this.attachmentResponses = [];
|
|
18
|
+
if (!assistantId) {
|
|
19
|
+
throw new Error("AlquimiaSDK: assistantId is required");
|
|
20
|
+
}
|
|
21
|
+
if (!adapter) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()"
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
this.assistantId = assistantId;
|
|
27
|
+
this.adapter = adapter;
|
|
28
|
+
this.enforceCharacterization = options.enforceCharacterization ?? true;
|
|
29
|
+
this.axiosInstance = axios.create();
|
|
30
|
+
this.axiosInstance.interceptors.response.use(
|
|
31
|
+
(response) => response,
|
|
32
|
+
async (error) => {
|
|
33
|
+
if (error.response?.status && this.loggerProvider) {
|
|
34
|
+
await this.loggerProvider.logError("Server Error", error, {
|
|
35
|
+
url: error.config.url,
|
|
36
|
+
method: error.config.method,
|
|
37
|
+
data: error.config.data,
|
|
38
|
+
status: error.response.status,
|
|
39
|
+
responseData: error.response.data
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return Promise.reject(error);
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
this.textToSpeech = this.textToSpeech.bind(this);
|
|
46
|
+
this.speechToText = this.speechToText.bind(this);
|
|
47
|
+
}
|
|
48
|
+
withConversationId(conversationId) {
|
|
49
|
+
this.conversationId = conversationId;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
withAttachments(attachments) {
|
|
53
|
+
this.attachments = attachments;
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
withWhisperProvider(provider) {
|
|
57
|
+
this.whisperProvider = provider;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
withStableDiffusionProvider(provider) {
|
|
61
|
+
this.stableDiffusionProvider = provider;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
withAnalyzeCharacterizationProvider(provider) {
|
|
65
|
+
this.analyzeCharacterizationProvider = provider;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
withRatingsProvider(provider) {
|
|
69
|
+
this.ratingsProvider = provider;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
withLoggerProvider(provider) {
|
|
73
|
+
this.loggerProvider = provider;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
withTools(tools) {
|
|
77
|
+
this.tools = tools;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
withExtraInstructions(extraInstructions) {
|
|
81
|
+
this.extraInstructions = extraInstructions;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
withAssistantConfig(assistantConfig) {
|
|
85
|
+
this.assistantConfig = assistantConfig;
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
withUserId(userId) {
|
|
89
|
+
this.userId = userId;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
getEnforceCharacterization() {
|
|
93
|
+
return this.enforceCharacterization ?? true;
|
|
94
|
+
}
|
|
95
|
+
textToSpeech(text) {
|
|
96
|
+
if (!this.whisperProvider) {
|
|
97
|
+
throw new Error("Whisper provider not initialized");
|
|
98
|
+
}
|
|
99
|
+
return this.whisperProvider.textToSpeech(text);
|
|
100
|
+
}
|
|
101
|
+
speechToText(audio) {
|
|
102
|
+
if (!this.whisperProvider) {
|
|
103
|
+
throw new Error("Whisper provider not initialized");
|
|
104
|
+
}
|
|
105
|
+
return this.whisperProvider.speechToText(audio);
|
|
106
|
+
}
|
|
107
|
+
async sendMessage(query, traceParent) {
|
|
108
|
+
if (!this.conversationId) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
"Conversation not initialized. Call withConversationId() before sendMessage()"
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const inferUrl = this.adapter.resolveInferUrl(this.assistantId);
|
|
114
|
+
const adapterHeaders = this.adapter.getHeaders?.() ?? {};
|
|
115
|
+
const hasClientTools = Array.isArray(this.tools) && this.tools.length > 0;
|
|
116
|
+
const initMessage = {
|
|
117
|
+
query,
|
|
118
|
+
session_id: this.conversationId,
|
|
119
|
+
user_id: this.userId,
|
|
120
|
+
...this.extraInstructions && { extra_instructions: this.extraInstructions },
|
|
121
|
+
...this.assistantConfig && { config: this.assistantConfig },
|
|
122
|
+
...hasClientTools && {
|
|
123
|
+
evaluation_strategy: {
|
|
124
|
+
evaluation_strategy_id: "native",
|
|
125
|
+
tool_schemas: this.tools
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const result = (await this.axiosInstance.post(inferUrl, initMessage, {
|
|
130
|
+
headers: {
|
|
131
|
+
"Content-Type": "application/json",
|
|
132
|
+
"x-trace-parent": traceParent || "",
|
|
133
|
+
...adapterHeaders,
|
|
134
|
+
...this.buildIdentityHeaders()
|
|
135
|
+
}
|
|
136
|
+
})).data;
|
|
137
|
+
this.streamId = result.taskid ?? null;
|
|
138
|
+
this.attachmentResponses = result.attachments ?? [];
|
|
139
|
+
this.attachments = [];
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
async generateImage(query) {
|
|
143
|
+
if (!this.stableDiffusionProvider) {
|
|
144
|
+
throw new Error("Stable Diffusion provider not initialized");
|
|
145
|
+
}
|
|
146
|
+
return this.stableDiffusionProvider.generateImage(query);
|
|
147
|
+
}
|
|
148
|
+
async analyzeCharacterization(text) {
|
|
149
|
+
if (!this.analyzeCharacterizationProvider) {
|
|
150
|
+
throw new Error("Analyze characterization provider not initialized");
|
|
151
|
+
}
|
|
152
|
+
return this.analyzeCharacterizationProvider.analyzeCharacterization(text);
|
|
153
|
+
}
|
|
154
|
+
async rate(data) {
|
|
155
|
+
if (!this.ratingsProvider) {
|
|
156
|
+
throw new Error("Ratings provider not initialized");
|
|
157
|
+
}
|
|
158
|
+
return this.ratingsProvider.rate(data);
|
|
159
|
+
}
|
|
160
|
+
async logInfo(message, data) {
|
|
161
|
+
if (!this.loggerProvider) {
|
|
162
|
+
throw new Error("Logger provider not initialized");
|
|
163
|
+
}
|
|
164
|
+
return this.loggerProvider.logInfo(message, data);
|
|
165
|
+
}
|
|
166
|
+
async logError(message, error, data) {
|
|
167
|
+
if (!this.loggerProvider) {
|
|
168
|
+
throw new Error("Logger provider not initialized");
|
|
169
|
+
}
|
|
170
|
+
return this.loggerProvider.logError(message, error, data);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* @deprecated The runtime no longer returns attachment IDs from the infer
|
|
174
|
+
* response — attachments are uploaded as standalone blobs and linked to the
|
|
175
|
+
* session via headers. Always returns `[]`; kept for source compatibility.
|
|
176
|
+
*/
|
|
177
|
+
getAttachmentResponses() {
|
|
178
|
+
return this.attachmentResponses;
|
|
179
|
+
}
|
|
180
|
+
async uploadAttachment(file, _attachmentId) {
|
|
181
|
+
const url = this.adapter.resolveBlobUploadUrl();
|
|
182
|
+
const adapterHeaders = this.adapter.getHeaders?.() ?? {};
|
|
183
|
+
const formData = new FormData();
|
|
184
|
+
formData.append("file", file);
|
|
185
|
+
await this.axiosInstance.post(url, formData, {
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "multipart/form-data",
|
|
188
|
+
...adapterHeaders,
|
|
189
|
+
...this.buildIdentityHeaders()
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Identity headers (kebab-case) required by `/context/blob/upload` and
|
|
195
|
+
* the rest of the runtime's internal endpoints introduced in v0.2.0→next.
|
|
196
|
+
*/
|
|
197
|
+
buildIdentityHeaders() {
|
|
198
|
+
const headers = {
|
|
199
|
+
"assistant-id": this.assistantId
|
|
200
|
+
};
|
|
201
|
+
if (this.conversationId) headers["session-id"] = this.conversationId;
|
|
202
|
+
if (this.userId) headers["user-id"] = this.userId;
|
|
203
|
+
if (this.streamId) headers["task-id"] = this.streamId;
|
|
204
|
+
return headers;
|
|
205
|
+
}
|
|
206
|
+
getUrlStream() {
|
|
207
|
+
if (!this.streamId) {
|
|
208
|
+
throw new Error("Stream ID not initialized. Call sendMessage() first");
|
|
209
|
+
}
|
|
210
|
+
return this.adapter.resolveStreamUrl(this.streamId);
|
|
211
|
+
}
|
|
212
|
+
getStreamId() {
|
|
213
|
+
return this.streamId;
|
|
214
|
+
}
|
|
215
|
+
/** Alias for {@link getStreamId} — same value as infer `taskid`. */
|
|
216
|
+
getTaskId() {
|
|
217
|
+
return this.streamId;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
var alquimia_sdk_default = AlquimiaSDK;
|
|
3
221
|
|
|
4
222
|
// src/utils/utils.ts
|
|
5
223
|
function getCookies(name) {
|
|
@@ -84,7 +302,20 @@ function mergeToolEvents(initial, toolEvents) {
|
|
|
84
302
|
}
|
|
85
303
|
|
|
86
304
|
// src/hooks/alquimia.hook.tsx
|
|
87
|
-
function useAlquimia(
|
|
305
|
+
function useAlquimia(config) {
|
|
306
|
+
const sdk = useMemo(() => {
|
|
307
|
+
const instance = new alquimia_sdk_default(config.assistantId, config.adapter, {
|
|
308
|
+
enforceCharacterization: config.options?.enforceCharacterization
|
|
309
|
+
});
|
|
310
|
+
if (config.providers?.whisper) instance.withWhisperProvider(config.providers.whisper);
|
|
311
|
+
if (config.providers?.stableDiffusion) instance.withStableDiffusionProvider(config.providers.stableDiffusion);
|
|
312
|
+
if (config.providers?.characterization) instance.withAnalyzeCharacterizationProvider(config.providers.characterization);
|
|
313
|
+
if (config.providers?.ratings) instance.withRatingsProvider(config.providers.ratings);
|
|
314
|
+
if (config.providers?.logger) instance.withLoggerProvider(config.providers.logger);
|
|
315
|
+
if (config.options?.userId) instance.withUserId(config.options.userId);
|
|
316
|
+
if (config.options?.extraInstructions) instance.withExtraInstructions(config.options.extraInstructions);
|
|
317
|
+
return instance;
|
|
318
|
+
}, [config.assistantId, config.adapter]);
|
|
88
319
|
const [input, setInput] = useState("");
|
|
89
320
|
const [isMessageLoading, setIsMessageLoading] = useState(false);
|
|
90
321
|
const [isStreamingLoading, setIsStreamingLoading] = useState(false);
|
|
@@ -93,10 +324,10 @@ function useAlquimia(sdk) {
|
|
|
93
324
|
const [isAudioRecording, setIsAudioRecording] = useState(false);
|
|
94
325
|
const [messages, setMessages] = useState([]);
|
|
95
326
|
const eventSourceRef = useRef(null);
|
|
327
|
+
const streamUserCancelledRef = useRef(false);
|
|
96
328
|
const [sessionId, setSessionId] = useState(null);
|
|
97
329
|
const [activeTool, setActiveTool] = useState(null);
|
|
98
330
|
const [lastRequest, setLastRequest] = useState(null);
|
|
99
|
-
const [evaluationStrategy, setEvaluationStrategy] = useState("");
|
|
100
331
|
const [hasThinkings, setHasThinkings] = useState(false);
|
|
101
332
|
const [attachments, setAttachments] = useState([]);
|
|
102
333
|
const [isUploadingAttachments, setIsUploadingAttachments] = useState(false);
|
|
@@ -117,11 +348,9 @@ function useAlquimia(sdk) {
|
|
|
117
348
|
function clearAttachments() {
|
|
118
349
|
setAttachments([]);
|
|
119
350
|
}
|
|
120
|
-
function processMessageChunk(messageId, chunk, error_code, error_detail,
|
|
351
|
+
function processMessageChunk(messageId, chunk, error_code, error_detail, taskid, additionalInfo, loading, tooler, thinkings) {
|
|
121
352
|
setMessages((currentMessages) => {
|
|
122
|
-
const messageIndex = currentMessages.findIndex(
|
|
123
|
-
(message) => message?.id === messageId
|
|
124
|
-
);
|
|
353
|
+
const messageIndex = currentMessages.findIndex((message) => message?.id === messageId);
|
|
125
354
|
if (messageIndex !== -1) {
|
|
126
355
|
const updatedMessages = [...currentMessages];
|
|
127
356
|
const updatedMessage = {
|
|
@@ -131,14 +360,11 @@ function useAlquimia(sdk) {
|
|
|
131
360
|
role: updatedMessages[messageIndex]?.role || "assistant",
|
|
132
361
|
error_code,
|
|
133
362
|
error_detail,
|
|
134
|
-
|
|
363
|
+
taskid,
|
|
135
364
|
additionalInfo,
|
|
136
365
|
created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
137
366
|
loading,
|
|
138
|
-
tooler: mergeToolEvents(
|
|
139
|
-
updatedMessages[messageIndex]?.tooler || [],
|
|
140
|
-
tooler
|
|
141
|
-
),
|
|
367
|
+
tooler: mergeToolEvents(updatedMessages[messageIndex]?.tooler || [], tooler),
|
|
142
368
|
thinkings: mergeThinkingsByControlId(
|
|
143
369
|
updatedMessages[messageIndex]?.thinkings || [],
|
|
144
370
|
thinkings || []
|
|
@@ -155,7 +381,7 @@ function useAlquimia(sdk) {
|
|
|
155
381
|
id: messageId,
|
|
156
382
|
error_code,
|
|
157
383
|
error_detail,
|
|
158
|
-
|
|
384
|
+
taskid,
|
|
159
385
|
created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
160
386
|
loading,
|
|
161
387
|
tooler: mergeToolEvents([], tooler),
|
|
@@ -177,7 +403,7 @@ function useAlquimia(sdk) {
|
|
|
177
403
|
chunk?.answer || "",
|
|
178
404
|
chunk?.error_code,
|
|
179
405
|
chunk?.error_detail,
|
|
180
|
-
chunk?.
|
|
406
|
+
chunk?.taskid,
|
|
181
407
|
options?.additionalInfo,
|
|
182
408
|
chunk?.loading,
|
|
183
409
|
chunk?.tooler,
|
|
@@ -193,11 +419,7 @@ function useAlquimia(sdk) {
|
|
|
193
419
|
setIsMessageLoading(true);
|
|
194
420
|
event.preventDefault();
|
|
195
421
|
if (input) {
|
|
196
|
-
await processAndSendMessage(input, {
|
|
197
|
-
traceParentId,
|
|
198
|
-
sessionId: sessionId2,
|
|
199
|
-
additionalInfo
|
|
200
|
-
});
|
|
422
|
+
await processAndSendMessage(input, { traceParentId, sessionId: sessionId2, additionalInfo });
|
|
201
423
|
}
|
|
202
424
|
setIsMessageLoading(false);
|
|
203
425
|
}
|
|
@@ -221,6 +443,7 @@ function useAlquimia(sdk) {
|
|
|
221
443
|
setMessages(messages2);
|
|
222
444
|
}
|
|
223
445
|
function handleLoadingCancel() {
|
|
446
|
+
streamUserCancelledRef.current = true;
|
|
224
447
|
eventSourceRef.current?.close();
|
|
225
448
|
eventSourceRef.current = null;
|
|
226
449
|
setIsMessageLoading(false);
|
|
@@ -244,7 +467,7 @@ function useAlquimia(sdk) {
|
|
|
244
467
|
}
|
|
245
468
|
function getCookie(name) {
|
|
246
469
|
const cookies = document.cookie.split(";");
|
|
247
|
-
for (
|
|
470
|
+
for (const cookie of cookies) {
|
|
248
471
|
const [cookieName, cookieValue] = cookie.trim().split("=");
|
|
249
472
|
if (cookieName === name) {
|
|
250
473
|
return decodeURIComponent(cookieValue);
|
|
@@ -260,23 +483,22 @@ function useAlquimia(sdk) {
|
|
|
260
483
|
}
|
|
261
484
|
async function sendMessage(message, callBack, traceParentId, sessionId2) {
|
|
262
485
|
setIsStreamingLoading(true);
|
|
263
|
-
callBack({
|
|
264
|
-
type: "loading",
|
|
265
|
-
loading: true
|
|
266
|
-
});
|
|
486
|
+
callBack({ type: "loading", loading: true });
|
|
267
487
|
const conversationId = sessionId2 || getCookie("alquimia-session");
|
|
268
488
|
setIsMessageStreaming(true);
|
|
269
489
|
setActiveTool(null);
|
|
270
490
|
setLastRequest(message);
|
|
271
491
|
try {
|
|
272
492
|
const hasAttachments = attachments.length > 0;
|
|
273
|
-
const sdkCall = sdk.
|
|
493
|
+
const sdkCall = sdk.withConversationId(conversationId || "");
|
|
274
494
|
if (hasAttachments) {
|
|
275
|
-
sdkCall.withAttachments(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
495
|
+
sdkCall.withAttachments(
|
|
496
|
+
attachments.map((f) => ({
|
|
497
|
+
filename: f.name,
|
|
498
|
+
content_type: f.type,
|
|
499
|
+
content_size: f.size
|
|
500
|
+
}))
|
|
501
|
+
);
|
|
280
502
|
}
|
|
281
503
|
const response = await sdkCall.sendMessage(message, traceParentId);
|
|
282
504
|
if (hasAttachments) {
|
|
@@ -284,9 +506,7 @@ function useAlquimia(sdk) {
|
|
|
284
506
|
try {
|
|
285
507
|
const attachmentResponses = response.getAttachmentResponses();
|
|
286
508
|
await Promise.all(
|
|
287
|
-
attachments.map(
|
|
288
|
-
(file, i) => response.uploadAttachment(file, attachmentResponses[i])
|
|
289
|
-
)
|
|
509
|
+
attachments.map((file, i) => response.uploadAttachment(file, attachmentResponses[i]))
|
|
290
510
|
);
|
|
291
511
|
} catch (uploadError) {
|
|
292
512
|
setIsUploadingAttachments(false);
|
|
@@ -305,6 +525,7 @@ function useAlquimia(sdk) {
|
|
|
305
525
|
}
|
|
306
526
|
const streamUrl = response.getUrlStream();
|
|
307
527
|
const streamId = response.getStreamId() || "";
|
|
528
|
+
streamUserCancelledRef.current = false;
|
|
308
529
|
const streamState = {
|
|
309
530
|
streamId,
|
|
310
531
|
connectedAt: Date.now(),
|
|
@@ -315,8 +536,6 @@ function useAlquimia(sdk) {
|
|
|
315
536
|
};
|
|
316
537
|
const eventSource = new EventSource(streamUrl);
|
|
317
538
|
eventSourceRef.current = eventSource;
|
|
318
|
-
const evaluationStrategy2 = response.getEvaluationStrategy();
|
|
319
|
-
setEvaluationStrategy(evaluationStrategy2);
|
|
320
539
|
eventSource.onopen = () => {
|
|
321
540
|
streamState.openedAt = Date.now();
|
|
322
541
|
};
|
|
@@ -327,23 +546,37 @@ function useAlquimia(sdk) {
|
|
|
327
546
|
};
|
|
328
547
|
eventSource.onerror = () => {
|
|
329
548
|
if (streamState.closedByClient) return;
|
|
549
|
+
if (streamUserCancelledRef.current) {
|
|
550
|
+
streamUserCancelledRef.current = false;
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
330
553
|
streamState.closedByClient = true;
|
|
331
554
|
const elapsed = Date.now() - streamState.connectedAt;
|
|
332
555
|
const sinceLastMessage = streamState.lastMessageAt ? Date.now() - streamState.lastMessageAt : null;
|
|
333
556
|
cleanup(false, eventSource);
|
|
334
557
|
let errorDetail;
|
|
335
558
|
if (!streamState.openedAt) {
|
|
336
|
-
errorDetail =
|
|
559
|
+
errorDetail = "Could not open the live response. Check your connection and try again.";
|
|
337
560
|
} else if (streamState.messagesReceived === 0) {
|
|
338
|
-
errorDetail =
|
|
561
|
+
errorDetail = "No response was received. Try again in a moment.";
|
|
339
562
|
} else {
|
|
340
|
-
errorDetail =
|
|
563
|
+
errorDetail = "The response was interrupted. Try again.";
|
|
564
|
+
}
|
|
565
|
+
if (typeof console !== "undefined" && console.debug) {
|
|
566
|
+
console.debug("[Alquimia] SSE transport error", {
|
|
567
|
+
streamUrl,
|
|
568
|
+
taskId: streamId,
|
|
569
|
+
opened: Boolean(streamState.openedAt),
|
|
570
|
+
messagesReceived: streamState.messagesReceived,
|
|
571
|
+
elapsedMs: elapsed,
|
|
572
|
+
sinceLastMessageMs: sinceLastMessage
|
|
573
|
+
});
|
|
341
574
|
}
|
|
342
575
|
callBack({
|
|
343
576
|
type: "error",
|
|
344
577
|
error_code: "STREAM_ERROR",
|
|
345
578
|
error_detail: errorDetail,
|
|
346
|
-
|
|
579
|
+
taskid: streamId
|
|
347
580
|
});
|
|
348
581
|
};
|
|
349
582
|
} catch (error) {
|
|
@@ -354,13 +587,14 @@ function useAlquimia(sdk) {
|
|
|
354
587
|
setStreamingMessageId(null);
|
|
355
588
|
callBack({
|
|
356
589
|
type: "error",
|
|
357
|
-
error_code: error.status
|
|
590
|
+
error_code: error.response?.status != null ? String(error.response.status) : "REQUEST_ERROR",
|
|
358
591
|
error_detail: errMessage
|
|
359
592
|
});
|
|
360
593
|
}
|
|
361
594
|
}
|
|
362
595
|
function handleMessageEvent(event, callBack, eventSource, streamState) {
|
|
363
596
|
const data = JSON.parse(event.data);
|
|
597
|
+
const eventTaskId = data.taskid || "";
|
|
364
598
|
if (data.errors?.length) {
|
|
365
599
|
for (const error of data.errors) {
|
|
366
600
|
const detail = error.error_detail || (error.data != null ? `${error.data} (controlId: ${error.control_id})` : "Unknown error");
|
|
@@ -368,7 +602,7 @@ function useAlquimia(sdk) {
|
|
|
368
602
|
type: "error",
|
|
369
603
|
error_code: error.event_class || error.status || "UNKNOWN_ERROR",
|
|
370
604
|
error_detail: detail,
|
|
371
|
-
|
|
605
|
+
taskid: eventTaskId
|
|
372
606
|
});
|
|
373
607
|
}
|
|
374
608
|
if (streamState) streamState.closedByClient = true;
|
|
@@ -376,31 +610,21 @@ function useAlquimia(sdk) {
|
|
|
376
610
|
return;
|
|
377
611
|
}
|
|
378
612
|
if (data.tools_output?.length) {
|
|
379
|
-
callBack({
|
|
380
|
-
type: "answer",
|
|
381
|
-
answer: "",
|
|
382
|
-
tooler: data.tools_output
|
|
383
|
-
});
|
|
613
|
+
callBack({ type: "answer", answer: "", tooler: data.tools_output });
|
|
384
614
|
}
|
|
385
615
|
if (data.thinkings?.length) {
|
|
386
616
|
setHasThinkings(true);
|
|
387
|
-
callBack({
|
|
388
|
-
type: "answer",
|
|
389
|
-
thinkings: data.thinkings
|
|
390
|
-
});
|
|
617
|
+
callBack({ type: "answer", thinkings: data.thinkings });
|
|
391
618
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
callBack({
|
|
396
|
-
type: "answer",
|
|
397
|
-
answer: content
|
|
398
|
-
});
|
|
619
|
+
if (data.event_class === "AssistantInferenceResponse") {
|
|
620
|
+
const final = data;
|
|
621
|
+
callBack({ type: "answer", answer: final.data });
|
|
399
622
|
if (streamState) streamState.closedByClient = true;
|
|
400
623
|
cleanup(false, eventSource);
|
|
401
624
|
}
|
|
402
625
|
}
|
|
403
626
|
return {
|
|
627
|
+
sdk,
|
|
404
628
|
activeTool,
|
|
405
629
|
cleanMessages,
|
|
406
630
|
createMessageId,
|
|
@@ -411,7 +635,9 @@ function useAlquimia(sdk) {
|
|
|
411
635
|
handleLoadingCancel,
|
|
412
636
|
input,
|
|
413
637
|
isLoading,
|
|
638
|
+
isMessageLoading,
|
|
414
639
|
isMessageStreaming,
|
|
640
|
+
isStreamingLoading,
|
|
415
641
|
streamingMessageId,
|
|
416
642
|
isAudioRecording,
|
|
417
643
|
lastRequest,
|
|
@@ -424,7 +650,6 @@ function useAlquimia(sdk) {
|
|
|
424
650
|
setSessionId,
|
|
425
651
|
setLastRequest,
|
|
426
652
|
setIsAudioRecording,
|
|
427
|
-
evaluationStrategy,
|
|
428
653
|
hasThinkings,
|
|
429
654
|
attachments,
|
|
430
655
|
addAttachment,
|