@smythos/sre 1.5.37 → 1.5.40
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/index.js +65 -45
- package/dist/index.js.map +1 -1
- package/dist/types/Components/ECMASandbox.class.d.ts +14 -0
- package/dist/types/Components/MemoryDeleteKeyVal.class.d.ts +19 -0
- package/dist/types/Components/MemoryReadKeyVal.class.d.ts +17 -0
- package/dist/types/Components/MemoryWriteKeyVal.class.d.ts +17 -0
- package/dist/types/Components/MemoryWriteObject.class.d.ts +19 -0
- package/dist/types/Components/index.d.ts +10 -0
- package/dist/types/Core/ConnectorsService.d.ts +2 -1
- package/dist/types/helpers/ECMASandbox.helper.d.ts +3 -0
- package/dist/types/helpers/Log.helper.d.ts +1 -1
- package/dist/types/index.d.ts +8 -1
- package/dist/types/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.d.ts +19 -0
- package/dist/types/subsystems/LLMManager/LLM.helper.d.ts +21 -10
- package/dist/types/subsystems/LLMManager/LLM.service/LLMConnector.d.ts +5 -5
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Echo.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Groq.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +3 -4
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.d.ts +19 -14
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +95 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.d.ts +87 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.d.ts +85 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.d.ts +49 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +146 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.d.ts +10 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.d.ts +4 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/types.d.ts +38 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +1 -2
- package/dist/types/subsystems/Security/Vault.service/connectors/JSONFileVault.class.d.ts +5 -0
- package/dist/types/types/LLM.types.d.ts +82 -37
- package/dist/types/utils/data.utils.d.ts +2 -1
- package/package.json +4 -3
- package/src/Components/APICall/APICall.class.ts +2 -1
- package/src/Components/Component.class.ts +1 -1
- package/src/Components/ECMASandbox.class.ts +71 -0
- package/src/Components/GenAILLM.class.ts +1 -1
- package/src/Components/MemoryDeleteKeyVal.class.ts +70 -0
- package/src/Components/MemoryReadKeyVal.class.ts +66 -0
- package/src/Components/MemoryWriteKeyVal.class.ts +62 -0
- package/src/Components/MemoryWriteObject.class.ts +97 -0
- package/src/Components/index.ts +10 -0
- package/src/Core/ConnectorsService.ts +3 -3
- package/src/helpers/Conversation.helper.ts +11 -3
- package/src/helpers/ECMASandbox.helper.ts +54 -0
- package/src/helpers/Log.helper.ts +57 -17
- package/src/index.ts +192 -185
- package/src/index.ts.bak +192 -185
- package/src/subsystems/AgentManager/Agent.class.ts +11 -6
- package/src/subsystems/AgentManager/AgentRuntime.class.ts +13 -13
- package/src/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.ts +131 -0
- package/src/subsystems/ComputeManager/Code.service/index.ts +2 -0
- package/src/subsystems/LLMManager/LLM.helper.ts +57 -27
- package/src/subsystems/LLMManager/LLM.inference.ts +4 -0
- package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +125 -28
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +18 -17
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +2 -6
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +26 -17
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +314 -84
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +455 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +528 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +100 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.ts +81 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +853 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.ts +37 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.ts +4 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/types.ts +37 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +0 -5
- package/src/subsystems/LLMManager/LLM.service/index.ts +1 -1
- package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +2 -2
- package/src/subsystems/LLMManager/models.ts +1 -1
- package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +18 -0
- package/src/subsystems/MemoryManager/RuntimeContext.ts +33 -16
- package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +68 -42
- package/src/types/LLM.types.ts +91 -43
- package/src/utils/data.utils.ts +3 -2
- package/src/subsystems/LLMManager/LLM.service/connectors/OpenAI.class.ts +0 -848
|
@@ -3,16 +3,23 @@ import EventEmitter from 'events';
|
|
|
3
3
|
|
|
4
4
|
import { JSON_RESPONSE_INSTRUCTION, BUILT_IN_MODEL_PREFIX } from '@sre/constants';
|
|
5
5
|
import {
|
|
6
|
-
TLLMParams,
|
|
7
6
|
TCustomLLMModel,
|
|
8
7
|
APIKeySource,
|
|
9
8
|
TVertexAISettings,
|
|
10
9
|
ILLMRequestFuncParams,
|
|
11
10
|
TGoogleAIRequestBody,
|
|
12
|
-
TLLMConnectorParams,
|
|
13
11
|
ILLMRequestContext,
|
|
12
|
+
TLLMPreparedParams,
|
|
13
|
+
TLLMMessageBlock,
|
|
14
|
+
ToolData,
|
|
15
|
+
TLLMToolResultMessageBlock,
|
|
16
|
+
TLLMMessageRole,
|
|
17
|
+
TLLMChatResponse,
|
|
18
|
+
TLLMEvent,
|
|
14
19
|
} from '@sre/types/LLM.types';
|
|
15
20
|
import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
21
|
+
import { BinaryInput } from '@sre/helpers/BinaryInput.helper';
|
|
22
|
+
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
16
23
|
|
|
17
24
|
import { LLMConnector } from '../LLMConnector';
|
|
18
25
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
@@ -32,38 +39,66 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
32
39
|
return new VertexAI({
|
|
33
40
|
project: projectId,
|
|
34
41
|
location: region,
|
|
42
|
+
apiEndpoint: (modelInfo?.settings as TVertexAISettings)?.apiEndpoint,
|
|
35
43
|
googleAuthOptions: {
|
|
36
44
|
credentials: credentials as any,
|
|
37
45
|
},
|
|
38
46
|
});
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<
|
|
42
|
-
const messages = body.messages;
|
|
43
|
-
delete body.messages;
|
|
44
|
-
|
|
49
|
+
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
45
50
|
try {
|
|
46
51
|
const vertexAI = await this.getClient(context);
|
|
47
|
-
const generativeModel = vertexAI.getGenerativeModel(body);
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
53
|
+
// Separate contents from model configuration
|
|
54
|
+
const contents = body.contents;
|
|
55
|
+
delete body.contents;
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// VertexAI expects contents in a specific format: {contents: [...]}
|
|
58
|
+
const requestParam = { contents };
|
|
59
|
+
|
|
60
|
+
const model = vertexAI.getGenerativeModel(body);
|
|
61
|
+
|
|
62
|
+
const result = await model.generateContent(requestParam);
|
|
63
|
+
const response = await result.response;
|
|
64
|
+
|
|
65
|
+
const content = response.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
66
|
+
const finishReason = response.candidates?.[0]?.finishReason || 'stop';
|
|
67
|
+
const usage = response.usageMetadata;
|
|
68
|
+
|
|
69
|
+
let toolsData: ToolData[] = [];
|
|
70
|
+
let useTool = false;
|
|
71
|
+
|
|
72
|
+
// Check for function calls in the response
|
|
73
|
+
const functionCalls = response.candidates?.[0]?.content?.parts?.filter((part) => part.functionCall);
|
|
74
|
+
if (functionCalls && functionCalls.length > 0) {
|
|
75
|
+
functionCalls.forEach((call, index) => {
|
|
76
|
+
toolsData.push({
|
|
77
|
+
index,
|
|
78
|
+
id: call.functionCall?.name + '_' + index, // VertexAI doesn't provide IDs like Anthropic
|
|
79
|
+
type: 'function',
|
|
80
|
+
name: call.functionCall?.name,
|
|
81
|
+
arguments: call.functionCall?.args,
|
|
82
|
+
role: TLLMMessageRole.Assistant,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
useTool = true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (usage) {
|
|
89
|
+
this.reportUsage(usage, {
|
|
90
|
+
modelEntryName: context.modelEntryName,
|
|
91
|
+
keySource: context.isUserKey ? APIKeySource.User : APIKeySource.Smyth,
|
|
92
|
+
agentId: context.agentId,
|
|
93
|
+
teamId: context.teamId,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
59
96
|
|
|
60
97
|
return {
|
|
61
98
|
content,
|
|
62
|
-
finishReason
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
message: { content, role: 'assistant' },
|
|
66
|
-
usage,
|
|
99
|
+
finishReason,
|
|
100
|
+
toolsData,
|
|
101
|
+
useTool,
|
|
67
102
|
};
|
|
68
103
|
} catch (error) {
|
|
69
104
|
throw error;
|
|
@@ -71,85 +106,125 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
71
106
|
}
|
|
72
107
|
|
|
73
108
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
74
|
-
// Simulate streaming similar to Perplexity's approach - fallback to regular request
|
|
75
109
|
const emitter = new EventEmitter();
|
|
76
110
|
|
|
77
|
-
setTimeout(() => {
|
|
111
|
+
setTimeout(async () => {
|
|
78
112
|
try {
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
113
|
+
const vertexAI = await this.getClient(context);
|
|
114
|
+
|
|
115
|
+
// Separate contents from model configuration
|
|
116
|
+
const contents = body.contents;
|
|
117
|
+
delete body.contents;
|
|
118
|
+
|
|
119
|
+
const vertexModel = vertexAI.getGenerativeModel(body);
|
|
120
|
+
|
|
121
|
+
// VertexAI expects contents in a specific format: {contents: [...]}
|
|
122
|
+
const requestParam = { contents };
|
|
123
|
+
|
|
124
|
+
const streamResult = await vertexModel.generateContentStream(requestParam);
|
|
125
|
+
|
|
126
|
+
let toolsData: ToolData[] = [];
|
|
127
|
+
let usageData: any[] = [];
|
|
128
|
+
|
|
129
|
+
for await (const chunk of streamResult.stream) {
|
|
130
|
+
const chunkText = chunk.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
131
|
+
if (chunkText) {
|
|
132
|
+
emitter.emit('content', chunkText);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const aggregatedResponse = await streamResult.response;
|
|
137
|
+
|
|
138
|
+
// Check for function calls in the final response (like Anthropic does)
|
|
139
|
+
const functionCalls = aggregatedResponse.candidates?.[0]?.content?.parts?.filter((part) => part.functionCall);
|
|
140
|
+
if (functionCalls && functionCalls.length > 0) {
|
|
141
|
+
functionCalls.forEach((call, index) => {
|
|
142
|
+
toolsData.push({
|
|
143
|
+
index,
|
|
144
|
+
id: call.functionCall?.name + '_' + index,
|
|
145
|
+
type: 'function',
|
|
146
|
+
name: call.functionCall?.name,
|
|
147
|
+
arguments: call.functionCall?.args,
|
|
148
|
+
role: TLLMMessageRole.Assistant,
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
emitter.emit(TLLMEvent.ToolInfo, toolsData);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const usage = aggregatedResponse.usageMetadata;
|
|
156
|
+
|
|
157
|
+
if (usage) {
|
|
158
|
+
const reportedUsage = this.reportUsage(usage, {
|
|
159
|
+
modelEntryName: context.modelEntryName,
|
|
160
|
+
keySource: context.isUserKey ? APIKeySource.User : APIKeySource.Smyth,
|
|
161
|
+
agentId: context.agentId,
|
|
162
|
+
teamId: context.teamId,
|
|
91
163
|
});
|
|
164
|
+
usageData.push(reportedUsage);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const finishReason = (aggregatedResponse.candidates?.[0]?.finishReason || 'stop').toLowerCase();
|
|
168
|
+
|
|
169
|
+
if (finishReason !== 'stop') {
|
|
170
|
+
emitter.emit('interrupted', finishReason);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
setTimeout(() => {
|
|
174
|
+
emitter.emit('end', toolsData, usageData, finishReason);
|
|
175
|
+
}, 100);
|
|
92
176
|
} catch (error) {
|
|
93
|
-
emitter.emit('error', error
|
|
177
|
+
emitter.emit('error', error);
|
|
94
178
|
}
|
|
95
179
|
}, 100);
|
|
96
180
|
|
|
97
181
|
return emitter;
|
|
98
182
|
}
|
|
99
183
|
|
|
100
|
-
protected async
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
protected async reqBodyAdapter(params: TLLMParams): Promise<TGoogleAIRequestBody> {
|
|
105
|
-
let messages = params?.messages || [];
|
|
106
|
-
|
|
107
|
-
//#region Separate system message and add JSON response instruction if needed
|
|
108
|
-
let systemInstruction;
|
|
109
|
-
const { systemMessage, otherMessages } = LLMHelper.separateSystemMessages(messages);
|
|
184
|
+
protected async reqBodyAdapter(params: TLLMPreparedParams): Promise<TGoogleAIRequestBody> {
|
|
185
|
+
const model = params?.model;
|
|
186
|
+
const { messages, systemMessage } = await this.prepareMessages(params);
|
|
110
187
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
messages = otherMessages;
|
|
188
|
+
let body: any = {
|
|
189
|
+
model: model as string,
|
|
190
|
+
contents: messages, // This will be separated in the request methods
|
|
191
|
+
};
|
|
116
192
|
|
|
117
193
|
const responseFormat = params?.responseFormat || '';
|
|
194
|
+
let systemInstruction = systemMessage || '';
|
|
195
|
+
|
|
118
196
|
if (responseFormat === 'json') {
|
|
119
|
-
systemInstruction
|
|
197
|
+
systemInstruction += (systemInstruction ? '\n\n' : '') + JSON_RESPONSE_INSTRUCTION;
|
|
120
198
|
}
|
|
121
|
-
//#endregion Separate system message and add JSON response instruction if needed
|
|
122
|
-
|
|
123
|
-
const modelInfo = params.modelInfo as TCustomLLMModel;
|
|
124
|
-
|
|
125
|
-
let body: TGoogleAIRequestBody = {
|
|
126
|
-
model: modelInfo?.settings?.customModel || modelInfo?.settings?.foundationModel,
|
|
127
|
-
messages,
|
|
128
|
-
};
|
|
129
199
|
|
|
130
200
|
const config: GenerationConfig = {};
|
|
131
201
|
|
|
132
|
-
if (params
|
|
133
|
-
if (params
|
|
134
|
-
if (params
|
|
135
|
-
if (params
|
|
136
|
-
if (params
|
|
202
|
+
if (params.maxTokens !== undefined) config.maxOutputTokens = params.maxTokens;
|
|
203
|
+
if (params.temperature !== undefined) config.temperature = params.temperature;
|
|
204
|
+
if (params.topP !== undefined) config.topP = params.topP;
|
|
205
|
+
if (params.topK !== undefined) config.topK = params.topK;
|
|
206
|
+
if (params.stopSequences?.length) config.stopSequences = params.stopSequences;
|
|
137
207
|
|
|
138
208
|
if (systemInstruction) {
|
|
139
|
-
body.systemInstruction =
|
|
209
|
+
body.systemInstruction = {
|
|
210
|
+
role: 'system',
|
|
211
|
+
parts: [{ text: systemInstruction }],
|
|
212
|
+
};
|
|
140
213
|
}
|
|
141
214
|
|
|
142
215
|
if (Object.keys(config).length > 0) {
|
|
143
|
-
body.generationConfig = config
|
|
216
|
+
body.generationConfig = config;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Handle tools configuration
|
|
220
|
+
if (params?.toolsConfig?.tools && params?.toolsConfig?.tools.length > 0) {
|
|
221
|
+
body.tools = this.formatToolsForVertexAI(params.toolsConfig.tools);
|
|
144
222
|
}
|
|
145
223
|
|
|
146
224
|
return body;
|
|
147
225
|
}
|
|
148
226
|
|
|
149
|
-
protected reportUsage(
|
|
150
|
-
usage: UsageMetadata & { cachedContentTokenCount?: number },
|
|
151
|
-
metadata: { modelEntryName: string; keySource: APIKeySource; agentId: string; teamId: string }
|
|
152
|
-
) {
|
|
227
|
+
protected reportUsage(usage: UsageMetadata, metadata: { modelEntryName: string; keySource: APIKeySource; agentId: string; teamId: string }) {
|
|
153
228
|
// SmythOS (built-in) models have a prefix, so we need to remove it to get the model name
|
|
154
229
|
const modelName = metadata.modelEntryName.replace(BUILT_IN_MODEL_PREFIX, '');
|
|
155
230
|
|
|
@@ -168,26 +243,181 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
168
243
|
return usageData;
|
|
169
244
|
}
|
|
170
245
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
246
|
+
private async prepareMessages(params: TLLMPreparedParams) {
|
|
247
|
+
const messages = params?.messages || [];
|
|
248
|
+
const files: BinaryInput[] = params?.files || [];
|
|
174
249
|
|
|
175
|
-
|
|
176
|
-
const _messages = LLMHelper.removeDuplicateUserMessages(messages);
|
|
250
|
+
let processedMessages = [...messages];
|
|
177
251
|
|
|
178
|
-
|
|
179
|
-
|
|
252
|
+
// Handle system messages - VertexAI uses systemInstruction separately
|
|
253
|
+
const { systemMessage, otherMessages } = LLMHelper.separateSystemMessages(processedMessages);
|
|
254
|
+
processedMessages = otherMessages;
|
|
180
255
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
256
|
+
// Handle files if present
|
|
257
|
+
if (files?.length > 0) {
|
|
258
|
+
const fileData = await this.processFiles(files, params.agentId);
|
|
259
|
+
|
|
260
|
+
// Add file data to the last user message
|
|
261
|
+
const userMessage = processedMessages.pop();
|
|
262
|
+
if (userMessage) {
|
|
263
|
+
const content = [{ text: userMessage.content as string }, ...fileData];
|
|
264
|
+
processedMessages.push({
|
|
265
|
+
role: userMessage.role,
|
|
266
|
+
parts: content,
|
|
267
|
+
});
|
|
185
268
|
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Convert messages to VertexAI format
|
|
272
|
+
let vertexAIMessages = this.convertMessagesToVertexAIFormat(processedMessages);
|
|
273
|
+
|
|
274
|
+
// Ensure we have at least one message with content
|
|
275
|
+
if (!vertexAIMessages || vertexAIMessages.length === 0) {
|
|
276
|
+
vertexAIMessages = [
|
|
277
|
+
{
|
|
278
|
+
role: 'user',
|
|
279
|
+
parts: [{ text: 'Hello' }],
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
messages: vertexAIMessages,
|
|
286
|
+
systemMessage: (systemMessage as any)?.content || '',
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private async processFiles(files: BinaryInput[], agentId: string) {
|
|
291
|
+
const fileData = [];
|
|
292
|
+
|
|
293
|
+
for (const file of files) {
|
|
294
|
+
const bufferData = await file.readData(AccessCandidate.agent(agentId));
|
|
295
|
+
const base64Data = bufferData.toString('base64');
|
|
296
|
+
|
|
297
|
+
fileData.push({
|
|
298
|
+
inlineData: {
|
|
299
|
+
data: base64Data,
|
|
300
|
+
mimeType: file.mimetype,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return fileData;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private convertMessagesToVertexAIFormat(messages: TLLMMessageBlock[]) {
|
|
309
|
+
return messages
|
|
310
|
+
.filter((message) => message && (message.content || message.parts))
|
|
311
|
+
.map((message) => {
|
|
312
|
+
let parts;
|
|
313
|
+
|
|
314
|
+
if (typeof message.content === 'string') {
|
|
315
|
+
parts = message.content.trim() ? [{ text: message.content.trim() }] : [{ text: 'Continue' }];
|
|
316
|
+
} else if (message.parts && Array.isArray(message.parts)) {
|
|
317
|
+
parts = message.parts;
|
|
318
|
+
} else if (message.content) {
|
|
319
|
+
parts = [{ text: String(message.content) || 'Continue' }];
|
|
320
|
+
} else {
|
|
321
|
+
parts = [{ text: 'Continue' }];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
role: message.role === TLLMMessageRole.Assistant ? 'model' : 'user',
|
|
326
|
+
parts,
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
private formatToolsForVertexAI(tools: any[]) {
|
|
332
|
+
return [
|
|
333
|
+
{
|
|
334
|
+
functionDeclarations: tools.map((tool) => ({
|
|
335
|
+
name: tool.name,
|
|
336
|
+
description: tool.description || '',
|
|
337
|
+
parameters: {
|
|
338
|
+
type: 'object',
|
|
339
|
+
properties: tool.properties || {},
|
|
340
|
+
required: tool.requiredFields || [],
|
|
341
|
+
},
|
|
342
|
+
})),
|
|
343
|
+
},
|
|
344
|
+
];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
public formatToolsConfig({ toolDefinitions, toolChoice = 'auto' }) {
|
|
348
|
+
const tools = toolDefinitions.map((tool) => {
|
|
349
|
+
const { name, description, properties, requiredFields } = tool;
|
|
186
350
|
|
|
187
351
|
return {
|
|
188
|
-
|
|
189
|
-
|
|
352
|
+
name,
|
|
353
|
+
description,
|
|
354
|
+
properties,
|
|
355
|
+
requiredFields,
|
|
190
356
|
};
|
|
191
357
|
});
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
tools,
|
|
361
|
+
toolChoice: {
|
|
362
|
+
type: toolChoice,
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
public transformToolMessageBlocks({
|
|
368
|
+
messageBlock,
|
|
369
|
+
toolsData,
|
|
370
|
+
}: {
|
|
371
|
+
messageBlock: TLLMMessageBlock;
|
|
372
|
+
toolsData: ToolData[];
|
|
373
|
+
}): TLLMToolResultMessageBlock[] {
|
|
374
|
+
const messageBlocks: TLLMToolResultMessageBlock[] = [];
|
|
375
|
+
|
|
376
|
+
if (messageBlock) {
|
|
377
|
+
const parts = [];
|
|
378
|
+
|
|
379
|
+
if (typeof messageBlock.content === 'string') {
|
|
380
|
+
parts.push({ text: messageBlock.content });
|
|
381
|
+
} else if (Array.isArray(messageBlock.content)) {
|
|
382
|
+
parts.push(...messageBlock.content);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (messageBlock.tool_calls) {
|
|
386
|
+
const functionCalls = messageBlock.tool_calls.map((toolCall: any) => ({
|
|
387
|
+
functionCall: {
|
|
388
|
+
name: toolCall?.function?.name,
|
|
389
|
+
args:
|
|
390
|
+
typeof toolCall?.function?.arguments === 'string'
|
|
391
|
+
? JSON.parse(toolCall.function.arguments)
|
|
392
|
+
: toolCall?.function?.arguments || {},
|
|
393
|
+
},
|
|
394
|
+
}));
|
|
395
|
+
parts.push(...functionCalls);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
messageBlocks.push({
|
|
399
|
+
role: messageBlock.role,
|
|
400
|
+
parts,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Transform tool results
|
|
405
|
+
const toolResults = toolsData.map((toolData) => ({
|
|
406
|
+
role: TLLMMessageRole.User,
|
|
407
|
+
parts: [
|
|
408
|
+
{
|
|
409
|
+
functionResponse: {
|
|
410
|
+
name: toolData.name,
|
|
411
|
+
response: {
|
|
412
|
+
name: toolData.name,
|
|
413
|
+
content: toolData.result,
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
}));
|
|
419
|
+
|
|
420
|
+
messageBlocks.push(...toolResults);
|
|
421
|
+
return messageBlocks;
|
|
192
422
|
}
|
|
193
423
|
}
|