@alquimia-ai/tools 1.13.1 → 2.0.1
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 +7 -17
- package/dist/actions/index.d.ts +7 -17
- package/dist/actions/index.js +45 -152
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/index.mjs +45 -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 +22 -2
- package/dist/hooks/index.d.ts +22 -2
- package/dist/hooks/index.js +283 -66
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +274 -67
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/next/index.d.mts +49 -0
- package/dist/next/index.d.ts +49 -0
- package/dist/next/index.js +332 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/index.mjs +309 -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 +147 -0
- package/dist/proxy.js.map +1 -0
- package/dist/proxy.mjs +126 -0
- package/dist/proxy.mjs.map +1 -0
- package/dist/sdk/index.d.mts +8 -14
- package/dist/sdk/index.d.ts +8 -14
- package/dist/sdk/index.js +49 -49
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/index.mjs +49 -49
- 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/types/index.d.mts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +1 -2
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +0 -17
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +0 -17
- package/dist/utils/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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/next.ts"],"sourcesContent":["import type { AlquimiaAdapter } from './index';\n\nexport interface NextJsAdapterOptions {\n inferRoute?: string; // default: '/api/chat'\n streamRoute?: string; // default: '/api/stream'\n attachmentRoute?: string; // default: '/api/attachments'\n}\n\nexport function createNextJsAdapter(options?: NextJsAdapterOptions): AlquimiaAdapter {\n const inferRoute = options?.inferRoute ?? '/api/chat';\n const streamRoute = options?.streamRoute ?? '/api/stream';\n const attachmentRoute = options?.attachmentRoute ?? '/api/attachments';\n\n return {\n resolveInferUrl(assistantId: string): string {\n return `${inferRoute}/chat/${assistantId}`;\n },\n resolveStreamUrl(streamId: string): string {\n return `${streamRoute}/${streamId}`;\n },\n resolveAttachmentUrl(streamId: string, attachmentId: string): string {\n return `${attachmentRoute}/${streamId}/${attachmentId}`;\n },\n };\n}\n"],"mappings":";AAQO,SAAS,oBAAoB,SAAiD;AACnF,QAAM,aAAa,SAAS,cAAc;AAC1C,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,kBAAkB,SAAS,mBAAmB;AAEpD,SAAO;AAAA,IACL,gBAAgB,aAA6B;AAC3C,aAAO,GAAG,UAAU,SAAS,WAAW;AAAA,IAC1C;AAAA,IACA,iBAAiB,UAA0B;AACzC,aAAO,GAAG,WAAW,IAAI,QAAQ;AAAA,IACnC;AAAA,IACA,qBAAqB,UAAkB,cAA8B;AACnE,aAAO,GAAG,eAAe,IAAI,QAAQ,IAAI,YAAY;AAAA,IACvD;AAAA,EACF;AACF;","names":[]}
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { AlquimiaSDK } from '../sdk/index.mjs';
|
|
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';
|
|
3
5
|
import { AlquimiaMessage, ToolEvent, AIMessageChunk, RatingData } from '../types/index.mjs';
|
|
4
6
|
import { createMessageId } from '../utils/index.mjs';
|
|
5
|
-
import '../providers-0Gi78uNQ.mjs';
|
|
6
7
|
import '@elastic/apm-rum';
|
|
7
8
|
import 'ai';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
interface UseAlquimiaConfig {
|
|
11
|
+
assistantId: string;
|
|
12
|
+
adapter: AlquimiaAdapter;
|
|
13
|
+
providers?: {
|
|
14
|
+
whisper?: WhisperProvider;
|
|
15
|
+
stableDiffusion?: StableDiffusionProvider;
|
|
16
|
+
characterization?: CharacterizationProvider;
|
|
17
|
+
ratings?: RatingsProvider;
|
|
18
|
+
logger?: LoggerProvider;
|
|
19
|
+
};
|
|
20
|
+
options?: {
|
|
21
|
+
enforceCharacterization?: boolean;
|
|
22
|
+
userId?: string;
|
|
23
|
+
extraData?: any;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
declare function useAlquimia(config: UseAlquimiaConfig): {
|
|
27
|
+
sdk: AlquimiaSDK;
|
|
10
28
|
activeTool: any;
|
|
11
29
|
cleanMessages: () => void;
|
|
12
30
|
createMessageId: typeof createMessageId;
|
|
@@ -22,7 +40,9 @@ declare function useAlquimia(sdk: AlquimiaSDK): {
|
|
|
22
40
|
handleLoadingCancel: () => void;
|
|
23
41
|
input: string;
|
|
24
42
|
isLoading: boolean;
|
|
43
|
+
isMessageLoading: boolean;
|
|
25
44
|
isMessageStreaming: boolean;
|
|
45
|
+
isStreamingLoading: boolean;
|
|
26
46
|
streamingMessageId: string | null;
|
|
27
47
|
isAudioRecording: boolean;
|
|
28
48
|
lastRequest: string | null;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { AlquimiaSDK } from '../sdk/index.js';
|
|
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';
|
|
3
5
|
import { AlquimiaMessage, ToolEvent, AIMessageChunk, RatingData } from '../types/index.js';
|
|
4
6
|
import { createMessageId } from '../utils/index.js';
|
|
5
|
-
import '../providers-BJTXCtI3.js';
|
|
6
7
|
import '@elastic/apm-rum';
|
|
7
8
|
import 'ai';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
interface UseAlquimiaConfig {
|
|
11
|
+
assistantId: string;
|
|
12
|
+
adapter: AlquimiaAdapter;
|
|
13
|
+
providers?: {
|
|
14
|
+
whisper?: WhisperProvider;
|
|
15
|
+
stableDiffusion?: StableDiffusionProvider;
|
|
16
|
+
characterization?: CharacterizationProvider;
|
|
17
|
+
ratings?: RatingsProvider;
|
|
18
|
+
logger?: LoggerProvider;
|
|
19
|
+
};
|
|
20
|
+
options?: {
|
|
21
|
+
enforceCharacterization?: boolean;
|
|
22
|
+
userId?: string;
|
|
23
|
+
extraData?: any;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
declare function useAlquimia(config: UseAlquimiaConfig): {
|
|
27
|
+
sdk: AlquimiaSDK;
|
|
10
28
|
activeTool: any;
|
|
11
29
|
cleanMessages: () => void;
|
|
12
30
|
createMessageId: typeof createMessageId;
|
|
@@ -22,7 +40,9 @@ declare function useAlquimia(sdk: AlquimiaSDK): {
|
|
|
22
40
|
handleLoadingCancel: () => void;
|
|
23
41
|
input: string;
|
|
24
42
|
isLoading: boolean;
|
|
43
|
+
isMessageLoading: boolean;
|
|
25
44
|
isMessageStreaming: boolean;
|
|
45
|
+
isStreamingLoading: boolean;
|
|
26
46
|
streamingMessageId: string | null;
|
|
27
47
|
isAudioRecording: boolean;
|
|
28
48
|
lastRequest: string | null;
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/hooks/index.ts
|
|
@@ -28,6 +38,205 @@ module.exports = __toCommonJS(hooks_exports);
|
|
|
28
38
|
// src/hooks/alquimia.hook.tsx
|
|
29
39
|
var import_react = require("react");
|
|
30
40
|
|
|
41
|
+
// src/sdk/alquimia-sdk.ts
|
|
42
|
+
var import_axios = __toESM(require("axios"));
|
|
43
|
+
var AlquimiaSDK = class {
|
|
44
|
+
constructor(assistantId, adapter, options = {}) {
|
|
45
|
+
this.conversationId = null;
|
|
46
|
+
this.sessionId = null;
|
|
47
|
+
this.streamId = null;
|
|
48
|
+
this.evaluationStrategy = null;
|
|
49
|
+
this.tools = [];
|
|
50
|
+
this.extraData = null;
|
|
51
|
+
this.assistantConfig = null;
|
|
52
|
+
this.forceProfile = {};
|
|
53
|
+
this.userId = null;
|
|
54
|
+
this.attachments = [];
|
|
55
|
+
this.attachmentResponses = [];
|
|
56
|
+
if (!assistantId) {
|
|
57
|
+
throw new Error("AlquimiaSDK: assistantId is required");
|
|
58
|
+
}
|
|
59
|
+
if (!adapter) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
"AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
this.assistantId = assistantId;
|
|
65
|
+
this.adapter = adapter;
|
|
66
|
+
this.enforceCharacterization = options.enforceCharacterization ?? true;
|
|
67
|
+
this.axiosInstance = import_axios.default.create();
|
|
68
|
+
this.axiosInstance.interceptors.response.use(
|
|
69
|
+
(response) => response,
|
|
70
|
+
async (error) => {
|
|
71
|
+
if (error.response?.status && this.loggerProvider) {
|
|
72
|
+
await this.loggerProvider.logError("Server Error", error, {
|
|
73
|
+
url: error.config.url,
|
|
74
|
+
method: error.config.method,
|
|
75
|
+
data: error.config.data,
|
|
76
|
+
status: error.response.status,
|
|
77
|
+
responseData: error.response.data
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return Promise.reject(error);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
this.textToSpeech = this.textToSpeech.bind(this);
|
|
84
|
+
this.speechToText = this.speechToText.bind(this);
|
|
85
|
+
}
|
|
86
|
+
withConversationId(conversationId) {
|
|
87
|
+
this.conversationId = conversationId;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
withAttachments(attachments) {
|
|
91
|
+
this.attachments = attachments;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
withWhisperProvider(provider) {
|
|
95
|
+
this.whisperProvider = provider;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
withStableDiffusionProvider(provider) {
|
|
99
|
+
this.stableDiffusionProvider = provider;
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
withAnalyzeCharacterizationProvider(provider) {
|
|
103
|
+
this.analyzeCharacterizationProvider = provider;
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
withRatingsProvider(provider) {
|
|
107
|
+
this.ratingsProvider = provider;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
withLoggerProvider(provider) {
|
|
111
|
+
this.loggerProvider = provider;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
withTools(tools) {
|
|
115
|
+
this.tools = tools;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
withExtraData(extraData) {
|
|
119
|
+
this.extraData = extraData;
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
withForceProfile(forceProfile) {
|
|
123
|
+
this.forceProfile = forceProfile;
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
withAssistantConfig(assistantConfig) {
|
|
127
|
+
this.assistantConfig = assistantConfig;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
withUserId(userId) {
|
|
131
|
+
this.userId = userId;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
getEnforceCharacterization() {
|
|
135
|
+
return this.enforceCharacterization ?? true;
|
|
136
|
+
}
|
|
137
|
+
getEvaluationStrategy() {
|
|
138
|
+
return this.evaluationStrategy;
|
|
139
|
+
}
|
|
140
|
+
textToSpeech(text) {
|
|
141
|
+
if (!this.whisperProvider) {
|
|
142
|
+
throw new Error("Whisper provider not initialized");
|
|
143
|
+
}
|
|
144
|
+
return this.whisperProvider.textToSpeech(text);
|
|
145
|
+
}
|
|
146
|
+
speechToText(audio) {
|
|
147
|
+
if (!this.whisperProvider) {
|
|
148
|
+
throw new Error("Whisper provider not initialized");
|
|
149
|
+
}
|
|
150
|
+
return this.whisperProvider.speechToText(audio);
|
|
151
|
+
}
|
|
152
|
+
async sendMessage(query, traceParent) {
|
|
153
|
+
if (!this.conversationId) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
"Conversation not initialized. Call withConversationId() before sendMessage()"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
const inferUrl = this.adapter.resolveInferUrl(this.assistantId);
|
|
159
|
+
const adapterHeaders = this.adapter.getHeaders?.() ?? {};
|
|
160
|
+
const initMessage = {
|
|
161
|
+
query,
|
|
162
|
+
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
|
+
user_id: this.userId,
|
|
168
|
+
attachments: this.attachments
|
|
169
|
+
};
|
|
170
|
+
const result = (await this.axiosInstance.post(inferUrl, initMessage, {
|
|
171
|
+
headers: {
|
|
172
|
+
"Content-Type": "application/json",
|
|
173
|
+
"x-trace-parent": traceParent || "",
|
|
174
|
+
...adapterHeaders
|
|
175
|
+
}
|
|
176
|
+
})).data;
|
|
177
|
+
this.evaluationStrategy = result?.config?.dante?.profile?.evaluation_strategy?.evaluation_strategy_id ?? null;
|
|
178
|
+
this.streamId = result.stream_id;
|
|
179
|
+
this.attachmentResponses = result.attachments ?? [];
|
|
180
|
+
this.attachments = [];
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
async generateImage(query) {
|
|
184
|
+
if (!this.stableDiffusionProvider) {
|
|
185
|
+
throw new Error("Stable Diffusion provider not initialized");
|
|
186
|
+
}
|
|
187
|
+
return this.stableDiffusionProvider.generateImage(query);
|
|
188
|
+
}
|
|
189
|
+
async analyzeCharacterization(text) {
|
|
190
|
+
if (!this.analyzeCharacterizationProvider) {
|
|
191
|
+
throw new Error("Analyze characterization provider not initialized");
|
|
192
|
+
}
|
|
193
|
+
return this.analyzeCharacterizationProvider.analyzeCharacterization(text);
|
|
194
|
+
}
|
|
195
|
+
async rate(data) {
|
|
196
|
+
if (!this.ratingsProvider) {
|
|
197
|
+
throw new Error("Ratings provider not initialized");
|
|
198
|
+
}
|
|
199
|
+
return this.ratingsProvider.rate(data);
|
|
200
|
+
}
|
|
201
|
+
async logInfo(message, data) {
|
|
202
|
+
if (!this.loggerProvider) {
|
|
203
|
+
throw new Error("Logger provider not initialized");
|
|
204
|
+
}
|
|
205
|
+
return this.loggerProvider.logInfo(message, data);
|
|
206
|
+
}
|
|
207
|
+
async logError(message, error, data) {
|
|
208
|
+
if (!this.loggerProvider) {
|
|
209
|
+
throw new Error("Logger provider not initialized");
|
|
210
|
+
}
|
|
211
|
+
return this.loggerProvider.logError(message, error, data);
|
|
212
|
+
}
|
|
213
|
+
getAttachmentResponses() {
|
|
214
|
+
return this.attachmentResponses;
|
|
215
|
+
}
|
|
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);
|
|
221
|
+
const adapterHeaders = this.adapter.getHeaders?.() ?? {};
|
|
222
|
+
const formData = new FormData();
|
|
223
|
+
formData.append("file", file);
|
|
224
|
+
await this.axiosInstance.post(url, formData, {
|
|
225
|
+
headers: { "Content-Type": "multipart/form-data", ...adapterHeaders }
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
getUrlStream() {
|
|
229
|
+
if (!this.streamId) {
|
|
230
|
+
throw new Error("Stream ID not initialized. Call sendMessage() first");
|
|
231
|
+
}
|
|
232
|
+
return this.adapter.resolveStreamUrl(this.streamId);
|
|
233
|
+
}
|
|
234
|
+
getStreamId() {
|
|
235
|
+
return this.streamId;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
var alquimia_sdk_default = AlquimiaSDK;
|
|
239
|
+
|
|
31
240
|
// src/utils/utils.ts
|
|
32
241
|
function getCookies(name) {
|
|
33
242
|
if (typeof document === "undefined") return void 0;
|
|
@@ -65,22 +274,6 @@ function mergeThinkingsByControlId(existingThinkings = [], newThinkings = []) {
|
|
|
65
274
|
}
|
|
66
275
|
return Array.from(thinkingsMap.values());
|
|
67
276
|
}
|
|
68
|
-
function extractAnswerContent(content) {
|
|
69
|
-
if (typeof content !== "string") return "";
|
|
70
|
-
const trimmed = content.trim();
|
|
71
|
-
if (trimmed.startsWith("{")) {
|
|
72
|
-
try {
|
|
73
|
-
const repaired = trimmed.replace(/(?<!\\)\n/g, "\\n");
|
|
74
|
-
const parsed = JSON.parse(repaired);
|
|
75
|
-
if (parsed && typeof parsed === "object" && "answer" in parsed) {
|
|
76
|
-
return parsed.answer;
|
|
77
|
-
}
|
|
78
|
-
} catch (e) {
|
|
79
|
-
return content;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return content;
|
|
83
|
-
}
|
|
84
277
|
function mergeToolerByControlId(currentTooler, toolEvent) {
|
|
85
278
|
const { event_class, control_id, data, status } = toolEvent;
|
|
86
279
|
const existingTool = currentTooler.find((t) => t.control_id === control_id);
|
|
@@ -127,7 +320,20 @@ function mergeToolEvents(initial, toolEvents) {
|
|
|
127
320
|
}
|
|
128
321
|
|
|
129
322
|
// src/hooks/alquimia.hook.tsx
|
|
130
|
-
function useAlquimia(
|
|
323
|
+
function useAlquimia(config) {
|
|
324
|
+
const sdk = (0, import_react.useMemo)(() => {
|
|
325
|
+
const instance = new alquimia_sdk_default(config.assistantId, config.adapter, {
|
|
326
|
+
enforceCharacterization: config.options?.enforceCharacterization
|
|
327
|
+
});
|
|
328
|
+
if (config.providers?.whisper) instance.withWhisperProvider(config.providers.whisper);
|
|
329
|
+
if (config.providers?.stableDiffusion) instance.withStableDiffusionProvider(config.providers.stableDiffusion);
|
|
330
|
+
if (config.providers?.characterization) instance.withAnalyzeCharacterizationProvider(config.providers.characterization);
|
|
331
|
+
if (config.providers?.ratings) instance.withRatingsProvider(config.providers.ratings);
|
|
332
|
+
if (config.providers?.logger) instance.withLoggerProvider(config.providers.logger);
|
|
333
|
+
if (config.options?.userId) instance.withUserId(config.options.userId);
|
|
334
|
+
if (config.options?.extraData) instance.withExtraData(config.options.extraData);
|
|
335
|
+
return instance;
|
|
336
|
+
}, [config.assistantId, config.adapter]);
|
|
131
337
|
const [input, setInput] = (0, import_react.useState)("");
|
|
132
338
|
const [isMessageLoading, setIsMessageLoading] = (0, import_react.useState)(false);
|
|
133
339
|
const [isStreamingLoading, setIsStreamingLoading] = (0, import_react.useState)(false);
|
|
@@ -162,9 +368,7 @@ function useAlquimia(sdk) {
|
|
|
162
368
|
}
|
|
163
369
|
function processMessageChunk(messageId, chunk, error_code, error_detail, stream_id, additionalInfo, loading, tooler, thinkings) {
|
|
164
370
|
setMessages((currentMessages) => {
|
|
165
|
-
const messageIndex = currentMessages.findIndex(
|
|
166
|
-
(message) => message?.id === messageId
|
|
167
|
-
);
|
|
371
|
+
const messageIndex = currentMessages.findIndex((message) => message?.id === messageId);
|
|
168
372
|
if (messageIndex !== -1) {
|
|
169
373
|
const updatedMessages = [...currentMessages];
|
|
170
374
|
const updatedMessage = {
|
|
@@ -178,10 +382,7 @@ function useAlquimia(sdk) {
|
|
|
178
382
|
additionalInfo,
|
|
179
383
|
created_at: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
180
384
|
loading,
|
|
181
|
-
tooler: mergeToolEvents(
|
|
182
|
-
updatedMessages[messageIndex]?.tooler || [],
|
|
183
|
-
tooler
|
|
184
|
-
),
|
|
385
|
+
tooler: mergeToolEvents(updatedMessages[messageIndex]?.tooler || [], tooler),
|
|
185
386
|
thinkings: mergeThinkingsByControlId(
|
|
186
387
|
updatedMessages[messageIndex]?.thinkings || [],
|
|
187
388
|
thinkings || []
|
|
@@ -236,11 +437,7 @@ function useAlquimia(sdk) {
|
|
|
236
437
|
setIsMessageLoading(true);
|
|
237
438
|
event.preventDefault();
|
|
238
439
|
if (input) {
|
|
239
|
-
await processAndSendMessage(input, {
|
|
240
|
-
traceParentId,
|
|
241
|
-
sessionId: sessionId2,
|
|
242
|
-
additionalInfo
|
|
243
|
-
});
|
|
440
|
+
await processAndSendMessage(input, { traceParentId, sessionId: sessionId2, additionalInfo });
|
|
244
441
|
}
|
|
245
442
|
setIsMessageLoading(false);
|
|
246
443
|
}
|
|
@@ -287,7 +484,7 @@ function useAlquimia(sdk) {
|
|
|
287
484
|
}
|
|
288
485
|
function getCookie(name) {
|
|
289
486
|
const cookies = document.cookie.split(";");
|
|
290
|
-
for (
|
|
487
|
+
for (const cookie of cookies) {
|
|
291
488
|
const [cookieName, cookieValue] = cookie.trim().split("=");
|
|
292
489
|
if (cookieName === name) {
|
|
293
490
|
return decodeURIComponent(cookieValue);
|
|
@@ -303,23 +500,22 @@ function useAlquimia(sdk) {
|
|
|
303
500
|
}
|
|
304
501
|
async function sendMessage(message, callBack, traceParentId, sessionId2) {
|
|
305
502
|
setIsStreamingLoading(true);
|
|
306
|
-
callBack({
|
|
307
|
-
type: "loading",
|
|
308
|
-
loading: true
|
|
309
|
-
});
|
|
503
|
+
callBack({ type: "loading", loading: true });
|
|
310
504
|
const conversationId = sessionId2 || getCookie("alquimia-session");
|
|
311
505
|
setIsMessageStreaming(true);
|
|
312
506
|
setActiveTool(null);
|
|
313
507
|
setLastRequest(message);
|
|
314
508
|
try {
|
|
315
509
|
const hasAttachments = attachments.length > 0;
|
|
316
|
-
const sdkCall = sdk.
|
|
510
|
+
const sdkCall = sdk.withConversationId(conversationId || "");
|
|
317
511
|
if (hasAttachments) {
|
|
318
|
-
sdkCall.withAttachments(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
512
|
+
sdkCall.withAttachments(
|
|
513
|
+
attachments.map((f) => ({
|
|
514
|
+
filename: f.name,
|
|
515
|
+
content_type: f.type,
|
|
516
|
+
content_size: f.size
|
|
517
|
+
}))
|
|
518
|
+
);
|
|
323
519
|
}
|
|
324
520
|
const response = await sdkCall.sendMessage(message, traceParentId);
|
|
325
521
|
if (hasAttachments) {
|
|
@@ -327,9 +523,7 @@ function useAlquimia(sdk) {
|
|
|
327
523
|
try {
|
|
328
524
|
const attachmentResponses = response.getAttachmentResponses();
|
|
329
525
|
await Promise.all(
|
|
330
|
-
attachments.map(
|
|
331
|
-
(file, i) => response.uploadAttachment(file, attachmentResponses[i])
|
|
332
|
-
)
|
|
526
|
+
attachments.map((file, i) => response.uploadAttachment(file, attachmentResponses[i]))
|
|
333
527
|
);
|
|
334
528
|
} catch (uploadError) {
|
|
335
529
|
setIsUploadingAttachments(false);
|
|
@@ -346,19 +540,47 @@ function useAlquimia(sdk) {
|
|
|
346
540
|
setIsUploadingAttachments(false);
|
|
347
541
|
clearAttachments();
|
|
348
542
|
}
|
|
349
|
-
const
|
|
543
|
+
const streamUrl = response.getUrlStream();
|
|
544
|
+
const streamId = response.getStreamId() || "";
|
|
545
|
+
const streamState = {
|
|
546
|
+
streamId,
|
|
547
|
+
connectedAt: Date.now(),
|
|
548
|
+
openedAt: null,
|
|
549
|
+
messagesReceived: 0,
|
|
550
|
+
lastMessageAt: null,
|
|
551
|
+
closedByClient: false
|
|
552
|
+
};
|
|
553
|
+
const eventSource = new EventSource(streamUrl);
|
|
350
554
|
eventSourceRef.current = eventSource;
|
|
351
555
|
const evaluationStrategy2 = response.getEvaluationStrategy();
|
|
352
556
|
setEvaluationStrategy(evaluationStrategy2);
|
|
353
|
-
eventSource.
|
|
354
|
-
|
|
355
|
-
|
|
557
|
+
eventSource.onopen = () => {
|
|
558
|
+
streamState.openedAt = Date.now();
|
|
559
|
+
};
|
|
560
|
+
eventSource.onmessage = (event) => {
|
|
561
|
+
streamState.messagesReceived++;
|
|
562
|
+
streamState.lastMessageAt = Date.now();
|
|
563
|
+
handleMessageEvent(event, callBack, eventSource, streamState);
|
|
564
|
+
};
|
|
565
|
+
eventSource.onerror = () => {
|
|
566
|
+
if (streamState.closedByClient) return;
|
|
567
|
+
streamState.closedByClient = true;
|
|
568
|
+
const elapsed = Date.now() - streamState.connectedAt;
|
|
569
|
+
const sinceLastMessage = streamState.lastMessageAt ? Date.now() - streamState.lastMessageAt : null;
|
|
356
570
|
cleanup(false, eventSource);
|
|
571
|
+
let errorDetail;
|
|
572
|
+
if (!streamState.openedAt) {
|
|
573
|
+
errorDetail = `Stream failed to connect (after ${elapsed}ms). URL: ${streamUrl}`;
|
|
574
|
+
} else if (streamState.messagesReceived === 0) {
|
|
575
|
+
errorDetail = `Stream connected but received no messages before error (open for ${elapsed}ms).`;
|
|
576
|
+
} else {
|
|
577
|
+
errorDetail = `Stream dropped after ${streamState.messagesReceived} message(s), ${sinceLastMessage}ms since last message (total ${elapsed}ms). Possible timeout.`;
|
|
578
|
+
}
|
|
357
579
|
callBack({
|
|
358
580
|
type: "error",
|
|
359
581
|
error_code: "STREAM_ERROR",
|
|
360
|
-
error_detail:
|
|
361
|
-
stream_id:
|
|
582
|
+
error_detail: errorDetail,
|
|
583
|
+
stream_id: streamId
|
|
362
584
|
});
|
|
363
585
|
};
|
|
364
586
|
} catch (error) {
|
|
@@ -374,46 +596,39 @@ function useAlquimia(sdk) {
|
|
|
374
596
|
});
|
|
375
597
|
}
|
|
376
598
|
}
|
|
377
|
-
function handleMessageEvent(event, callBack, eventSource) {
|
|
599
|
+
function handleMessageEvent(event, callBack, eventSource, streamState) {
|
|
378
600
|
const data = JSON.parse(event.data);
|
|
379
601
|
if (data.errors?.length) {
|
|
380
602
|
for (const error of data.errors) {
|
|
381
|
-
|
|
603
|
+
const detail = error.error_detail || (error.data != null ? `${error.data} (controlId: ${error.control_id})` : "Unknown error");
|
|
382
604
|
callBack({
|
|
383
605
|
type: "error",
|
|
384
606
|
error_code: error.event_class || error.status || "UNKNOWN_ERROR",
|
|
385
|
-
error_detail:
|
|
607
|
+
error_detail: detail,
|
|
386
608
|
stream_id: data.stream_id || ""
|
|
387
609
|
});
|
|
388
610
|
}
|
|
611
|
+
if (streamState) streamState.closedByClient = true;
|
|
389
612
|
cleanup(false, eventSource);
|
|
390
613
|
return;
|
|
391
614
|
}
|
|
392
615
|
if (data.tools_output?.length) {
|
|
393
|
-
callBack({
|
|
394
|
-
type: "answer",
|
|
395
|
-
answer: "",
|
|
396
|
-
tooler: data.tools_output
|
|
397
|
-
});
|
|
616
|
+
callBack({ type: "answer", answer: "", tooler: data.tools_output });
|
|
398
617
|
}
|
|
399
618
|
if (data.thinkings?.length) {
|
|
400
619
|
setHasThinkings(true);
|
|
401
|
-
callBack({
|
|
402
|
-
type: "answer",
|
|
403
|
-
thinkings: data.thinkings
|
|
404
|
-
});
|
|
620
|
+
callBack({ type: "answer", thinkings: data.thinkings });
|
|
405
621
|
}
|
|
406
622
|
const response = data.response;
|
|
407
|
-
const content = response?.event_class === "AssistantInferenceResponse" ?
|
|
623
|
+
const content = response?.event_class === "AssistantInferenceResponse" && typeof response.data === "string" ? response.data : null;
|
|
408
624
|
if (content) {
|
|
409
|
-
callBack({
|
|
410
|
-
|
|
411
|
-
answer: content
|
|
412
|
-
});
|
|
625
|
+
callBack({ type: "answer", answer: content });
|
|
626
|
+
if (streamState) streamState.closedByClient = true;
|
|
413
627
|
cleanup(false, eventSource);
|
|
414
628
|
}
|
|
415
629
|
}
|
|
416
630
|
return {
|
|
631
|
+
sdk,
|
|
417
632
|
activeTool,
|
|
418
633
|
cleanMessages,
|
|
419
634
|
createMessageId,
|
|
@@ -424,7 +639,9 @@ function useAlquimia(sdk) {
|
|
|
424
639
|
handleLoadingCancel,
|
|
425
640
|
input,
|
|
426
641
|
isLoading,
|
|
642
|
+
isMessageLoading,
|
|
427
643
|
isMessageStreaming,
|
|
644
|
+
isStreamingLoading,
|
|
428
645
|
streamingMessageId,
|
|
429
646
|
isAudioRecording,
|
|
430
647
|
lastRequest,
|