@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.
- package/dist/actions/index.d.mts +2 -7
- package/dist/actions/index.d.ts +2 -7
- package/dist/actions/index.js +10 -8
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/index.mjs +10 -8
- package/dist/actions/index.mjs.map +1 -1
- package/dist/adapters/fetch.d.mts +2 -1
- package/dist/adapters/fetch.d.ts +2 -1
- package/dist/adapters/fetch.js +6 -4
- package/dist/adapters/fetch.js.map +1 -1
- package/dist/adapters/fetch.mjs +6 -4
- package/dist/adapters/fetch.mjs.map +1 -1
- package/dist/adapters/index.d.mts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/next.d.mts +2 -1
- package/dist/adapters/next.d.ts +2 -1
- package/dist/adapters/next.js +7 -5
- package/dist/adapters/next.js.map +1 -1
- package/dist/adapters/next.mjs +7 -5
- package/dist/adapters/next.mjs.map +1 -1
- package/dist/hooks/index.d.mts +5 -3
- package/dist/hooks/index.d.ts +5 -3
- package/dist/hooks/index.js +266 -65
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +248 -47
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/next/index.d.mts +6 -9
- package/dist/next/index.d.ts +6 -9
- package/dist/next/index.js +69 -64
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +69 -64
- package/dist/next/index.mjs.map +1 -1
- package/dist/proxy.d.mts +2 -2
- package/dist/proxy.d.ts +2 -2
- package/dist/proxy.js +32 -9
- package/dist/proxy.js.map +1 -1
- package/dist/proxy.mjs +32 -9
- package/dist/proxy.mjs.map +1 -1
- package/dist/sdk/index.d.mts +15 -7
- package/dist/sdk/index.d.ts +15 -7
- package/dist/sdk/index.js +45 -26
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/index.mjs +45 -26
- package/dist/sdk/index.mjs.map +1 -1
- 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/dist/types-CIqszY3g.d.mts +53 -0
- package/dist/types-CIqszY3g.d.ts +53 -0
- package/dist/worklog/index.d.mts +29 -0
- package/dist/worklog/index.d.ts +29 -0
- package/dist/worklog/index.js +218 -0
- package/dist/worklog/index.js.map +1 -0
- package/dist/worklog/index.mjs +195 -0
- package/dist/worklog/index.mjs.map +1 -0
- package/package.json +6 -1
package/dist/hooks/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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;
|
package/dist/hooks/index.js
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
-
|
|
119
|
-
this.
|
|
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
|
-
|
|
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.
|
|
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,
|
|
217
|
-
|
|
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: {
|
|
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,
|
|
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?.
|
|
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,
|
|
338
|
-
const [isMessageLoading, setIsMessageLoading] = (0,
|
|
339
|
-
const [isStreamingLoading, setIsStreamingLoading] = (0,
|
|
340
|
-
const [isMessageStreaming, setIsMessageStreaming] = (0,
|
|
341
|
-
const [streamingMessageId, setStreamingMessageId] = (0,
|
|
342
|
-
const [isAudioRecording, setIsAudioRecording] = (0,
|
|
343
|
-
const [messages, setMessages] = (0,
|
|
344
|
-
const eventSourceRef = (0,
|
|
345
|
-
const
|
|
346
|
-
const [
|
|
347
|
-
const [
|
|
348
|
-
const [
|
|
349
|
-
const [hasThinkings, setHasThinkings] = (0,
|
|
350
|
-
const
|
|
351
|
-
const [
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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?.
|
|
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 =
|
|
761
|
+
errorDetail = "Could not open the live response. Check your connection and try again.";
|
|
574
762
|
} else if (streamState.messagesReceived === 0) {
|
|
575
|
-
errorDetail =
|
|
763
|
+
errorDetail = "No response was received. Try again in a moment.";
|
|
576
764
|
} else {
|
|
577
|
-
errorDetail =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
623
|
-
|
|
624
|
-
|
|
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
|
|
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,
|
|
689
|
-
const [hasReviewed, setHasReviewed] = (0,
|
|
690
|
-
const [state, dispatch] = (0,
|
|
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
|
};
|