@smythos/sre 1.5.60 → 1.5.63
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 +15 -15
- package/dist/index.js.map +1 -1
- package/dist/types/subsystems/LLMManager/LLM.service/LLMConnector.d.ts +1 -1
- package/package.json +1 -1
- package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +18 -15
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +7 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +7 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +49 -34
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +7 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +101 -86
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +7 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +7 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +79 -64
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +7 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Connector } from '@sre/Core/Connector.class';
|
|
2
2
|
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
3
|
-
import type {
|
|
3
|
+
import type { APIKeySource, ILLMRequestFuncParams, TLLMChatResponse, TLLMConnectorParams, TLLMMessageBlock, TLLMRequestBody, TLLMToolResultMessageBlock, ToolData } from '@sre/types/LLM.types';
|
|
4
4
|
import EventEmitter from 'events';
|
|
5
5
|
import { Readable } from 'stream';
|
|
6
6
|
export interface ILLMConnectorRequest {
|
package/package.json
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
import { Connector } from '@sre/Core/Connector.class';
|
|
2
2
|
import { ConnectorService } from '@sre/Core/ConnectorsService';
|
|
3
|
+
import { JSONContent } from '@sre/helpers/JsonContent.helper';
|
|
3
4
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
5
|
+
import { ModelsProviderConnector } from '@sre/LLMManager/ModelsProvider.service/ModelsProviderConnector';
|
|
4
6
|
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
5
|
-
import {
|
|
7
|
+
import { AccountConnector } from '@sre/Security/Account.service/AccountConnector';
|
|
8
|
+
import { VaultConnector } from '@sre/Security/Vault.service/VaultConnector';
|
|
6
9
|
import type {
|
|
7
|
-
TLLMConnectorParams,
|
|
8
|
-
TLLMMessageBlock,
|
|
9
|
-
TLLMToolResultMessageBlock,
|
|
10
|
-
ToolData,
|
|
11
10
|
APIKeySource,
|
|
12
|
-
TLLMModel,
|
|
13
11
|
ILLMRequestFuncParams,
|
|
14
12
|
TLLMChatResponse,
|
|
13
|
+
TLLMConnectorParams,
|
|
14
|
+
TLLMMessageBlock,
|
|
15
|
+
TLLMModel,
|
|
16
|
+
TLLMPreparedParams,
|
|
15
17
|
TLLMRequestBody,
|
|
18
|
+
TLLMToolResultMessageBlock,
|
|
19
|
+
ToolData,
|
|
16
20
|
TOpenAIToolsInfo,
|
|
17
|
-
TxAIToolsInfo,
|
|
18
|
-
TLLMPreparedParams,
|
|
19
21
|
TToolsInfo,
|
|
22
|
+
TxAIToolsInfo,
|
|
20
23
|
} from '@sre/types/LLM.types';
|
|
24
|
+
import { TCustomLLMModel } from '@sre/types/LLM.types';
|
|
21
25
|
import EventEmitter from 'events';
|
|
22
26
|
import { Readable } from 'stream';
|
|
23
|
-
import { AccountConnector } from '@sre/Security/Account.service/AccountConnector';
|
|
24
|
-
import { VaultConnector } from '@sre/Security/Vault.service/VaultConnector';
|
|
25
|
-
import { TCustomLLMModel } from '@sre/types/LLM.types';
|
|
26
|
-
import config from '@sre/config';
|
|
27
|
-
import { ModelsProviderConnector } from '@sre/LLMManager/ModelsProvider.service/ModelsProviderConnector';
|
|
28
27
|
import { getLLMCredentials } from './LLMCredentials.helper';
|
|
29
28
|
|
|
30
|
-
const
|
|
29
|
+
const logger = Logger('LLMConnector');
|
|
31
30
|
|
|
32
31
|
export interface ILLMConnectorRequest {
|
|
33
32
|
// chatRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<any>;
|
|
@@ -100,11 +99,12 @@ export abstract class LLMConnector extends Connector {
|
|
|
100
99
|
this.vaultConnector = ConnectorService.getVaultConnector();
|
|
101
100
|
|
|
102
101
|
if (!this.vaultConnector || !this.vaultConnector.valid) {
|
|
103
|
-
|
|
102
|
+
logger.warn(`Vault Connector unavailable for ${candidate.id} `);
|
|
104
103
|
}
|
|
105
104
|
|
|
106
105
|
const _request: ILLMConnectorRequest = {
|
|
107
106
|
request: async (params: TLLMConnectorParams) => {
|
|
107
|
+
logger.debug(`request ${this.name}`, candidate);
|
|
108
108
|
const preparedParams = await this.prepareParams(candidate, params);
|
|
109
109
|
|
|
110
110
|
const provider = preparedParams.modelInfo.provider;
|
|
@@ -129,6 +129,7 @@ export abstract class LLMConnector extends Connector {
|
|
|
129
129
|
return response;
|
|
130
130
|
},
|
|
131
131
|
streamRequest: async (params: TLLMConnectorParams) => {
|
|
132
|
+
logger.debug(`streamRequest ${this.name}`, candidate);
|
|
132
133
|
const preparedParams = await this.prepareParams(candidate, params);
|
|
133
134
|
|
|
134
135
|
const provider = preparedParams.modelInfo.provider?.toLowerCase();
|
|
@@ -156,6 +157,7 @@ export abstract class LLMConnector extends Connector {
|
|
|
156
157
|
},
|
|
157
158
|
|
|
158
159
|
imageGenRequest: async (params: any) => {
|
|
160
|
+
logger.debug(`imageGenRequest ${this.name}`, candidate);
|
|
159
161
|
const preparedParams = await this.prepareParams(candidate, params);
|
|
160
162
|
|
|
161
163
|
const response = await this.imageGenRequest({
|
|
@@ -175,6 +177,7 @@ export abstract class LLMConnector extends Connector {
|
|
|
175
177
|
return response;
|
|
176
178
|
},
|
|
177
179
|
imageEditRequest: async (params: any) => {
|
|
180
|
+
logger.debug(`imageEditRequest ${this.name}`, candidate);
|
|
178
181
|
const preparedParams = await this.prepareParams(candidate, params);
|
|
179
182
|
|
|
180
183
|
const response = await this.imageEditRequest({
|
|
@@ -25,6 +25,9 @@ import { JSONContent } from '@sre/helpers/JsonContent.helper';
|
|
|
25
25
|
import { LLMConnector } from '../LLMConnector';
|
|
26
26
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
27
27
|
import { SUPPORTED_MIME_TYPES_MAP } from '@sre/constants';
|
|
28
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
29
|
+
|
|
30
|
+
const logger = Logger('AnthropicConnector');
|
|
28
31
|
|
|
29
32
|
const PREFILL_TEXT_FOR_JSON_RESPONSE = '{';
|
|
30
33
|
const LEGACY_THINKING_MODELS = ['smythos/claude-3.7-sonnet-thinking', 'claude-3.7-sonnet-thinking'];
|
|
@@ -49,6 +52,7 @@ export class AnthropicConnector extends LLMConnector {
|
|
|
49
52
|
|
|
50
53
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
51
54
|
try {
|
|
55
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
52
56
|
const anthropic = await this.getClient(context);
|
|
53
57
|
const result = await anthropic.messages.create(body);
|
|
54
58
|
const message: Anthropic.MessageParam = {
|
|
@@ -104,12 +108,14 @@ export class AnthropicConnector extends LLMConnector {
|
|
|
104
108
|
usage,
|
|
105
109
|
};
|
|
106
110
|
} catch (error) {
|
|
111
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
107
112
|
throw error;
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
112
117
|
try {
|
|
118
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
113
119
|
const emitter = new EventEmitter();
|
|
114
120
|
const usage_data = [];
|
|
115
121
|
|
|
@@ -199,6 +205,7 @@ export class AnthropicConnector extends LLMConnector {
|
|
|
199
205
|
|
|
200
206
|
return emitter;
|
|
201
207
|
} catch (error: any) {
|
|
208
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
202
209
|
throw error;
|
|
203
210
|
}
|
|
204
211
|
}
|
|
@@ -30,6 +30,9 @@ import { isJSONString } from '@sre/utils/general.utils';
|
|
|
30
30
|
import { LLMConnector } from '../LLMConnector';
|
|
31
31
|
import { JSONContent } from '@sre/helpers/JsonContent.helper';
|
|
32
32
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
33
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
34
|
+
|
|
35
|
+
const logger = Logger('BedrockConnector');
|
|
33
36
|
|
|
34
37
|
// TODO [Forhad]: Need to adjust some type definitions
|
|
35
38
|
|
|
@@ -50,6 +53,7 @@ export class BedrockConnector extends LLMConnector {
|
|
|
50
53
|
|
|
51
54
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
52
55
|
try {
|
|
56
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
53
57
|
const bedrock = await this.getClient(context);
|
|
54
58
|
const command = new ConverseCommand(body);
|
|
55
59
|
const response: ConverseCommandOutput = await bedrock.send(command);
|
|
@@ -91,6 +95,7 @@ export class BedrockConnector extends LLMConnector {
|
|
|
91
95
|
usage,
|
|
92
96
|
};
|
|
93
97
|
} catch (error: any) {
|
|
98
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
94
99
|
throw error?.error || error;
|
|
95
100
|
}
|
|
96
101
|
}
|
|
@@ -99,6 +104,7 @@ export class BedrockConnector extends LLMConnector {
|
|
|
99
104
|
const emitter = new EventEmitter();
|
|
100
105
|
|
|
101
106
|
try {
|
|
107
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
102
108
|
const bedrock = await this.getClient(context);
|
|
103
109
|
const command = new ConverseStreamCommand(body);
|
|
104
110
|
const response: ConverseStreamCommandOutput = await bedrock.send(command);
|
|
@@ -189,6 +195,7 @@ export class BedrockConnector extends LLMConnector {
|
|
|
189
195
|
return emitter;
|
|
190
196
|
} catch (error: unknown) {
|
|
191
197
|
const typedError = error as Error;
|
|
198
|
+
logger.error(`streamRequest ${this.name}`, typedError, acRequest.candidate);
|
|
192
199
|
emitter.emit(TLLMEvent.Error, typedError?.['error'] || typedError);
|
|
193
200
|
return emitter;
|
|
194
201
|
}
|
|
@@ -2,54 +2,69 @@ import { JSONContent } from '@sre/helpers/JsonContent.helper';
|
|
|
2
2
|
import { LLMConnector } from '../LLMConnector';
|
|
3
3
|
import EventEmitter from 'events';
|
|
4
4
|
import { APIKeySource, ILLMRequestFuncParams, TLLMChatResponse, TLLMPreparedParams } from '@sre/types/LLM.types';
|
|
5
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
6
|
+
|
|
7
|
+
const logger = Logger('EchoConnector');
|
|
5
8
|
|
|
6
9
|
export class EchoConnector extends LLMConnector {
|
|
7
10
|
public name = 'LLM:Echo';
|
|
8
11
|
|
|
9
12
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
content
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
try {
|
|
14
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
15
|
+
const content = body?.messages?.[0]?.content; // As Echo model only used in PromptGenerator so we can assume the first message is the user message to echo
|
|
16
|
+
return {
|
|
17
|
+
content,
|
|
18
|
+
finishReason: 'stop',
|
|
19
|
+
useTool: false,
|
|
20
|
+
toolsData: [],
|
|
21
|
+
message: { content, role: 'assistant' },
|
|
22
|
+
usage: {},
|
|
23
|
+
} as TLLMChatResponse;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
try {
|
|
32
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
33
|
+
const emitter = new EventEmitter();
|
|
34
|
+
let content = '';
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
if (Array.isArray(body?.messages)) {
|
|
37
|
+
content = body?.messages?.filter((m) => m.role === 'user').pop()?.content;
|
|
38
|
+
}
|
|
39
|
+
//params?.messages?.[0]?.content;
|
|
29
40
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
// Process stream asynchronously as we need to return emitter immediately
|
|
42
|
+
(async () => {
|
|
43
|
+
// Simulate streaming by splitting content into chunks
|
|
44
|
+
const chunks = content.split(' ');
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
47
|
+
// Simulate network delay
|
|
48
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
const isLastChunk = i === chunks.length - 1;
|
|
51
|
+
// Add space between chunks except for the last one to avoid trailing space in file URLs
|
|
52
|
+
const delta = { content: chunks[i] + (isLastChunk ? '' : ' ') };
|
|
53
|
+
emitter.emit('data', delta);
|
|
54
|
+
emitter.emit('content', delta.content);
|
|
55
|
+
}
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
// Emit end event after all chunks are processed
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
emitter.emit('end', [], []); // Empty arrays for toolsData and usage_data
|
|
60
|
+
}, 100);
|
|
61
|
+
})();
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
return emitter;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
protected async reqBodyAdapter(params: TLLMPreparedParams): Promise<any> {
|
|
@@ -32,9 +32,12 @@ import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
|
32
32
|
|
|
33
33
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
34
34
|
import { SUPPORTED_MIME_TYPES_MAP } from '@sre/constants';
|
|
35
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
35
36
|
|
|
36
37
|
import { LLMConnector } from '../LLMConnector';
|
|
37
38
|
|
|
39
|
+
const logger = Logger('GoogleAIConnector');
|
|
40
|
+
|
|
38
41
|
const MODELS_SUPPORT_SYSTEM_INSTRUCTION = [
|
|
39
42
|
'gemini-1.5-pro-exp-0801',
|
|
40
43
|
'gemini-1.5-pro-latest',
|
|
@@ -76,6 +79,7 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
76
79
|
|
|
77
80
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
78
81
|
try {
|
|
82
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
79
83
|
const prompt = body.messages;
|
|
80
84
|
delete body.messages;
|
|
81
85
|
|
|
@@ -121,11 +125,13 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
121
125
|
usage,
|
|
122
126
|
};
|
|
123
127
|
} catch (error: any) {
|
|
128
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
124
129
|
throw error;
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
134
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
129
135
|
const emitter = new EventEmitter();
|
|
130
136
|
|
|
131
137
|
const prompt = body.messages;
|
|
@@ -189,6 +195,7 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
189
195
|
|
|
190
196
|
return emitter;
|
|
191
197
|
} catch (error: any) {
|
|
198
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
192
199
|
throw error;
|
|
193
200
|
}
|
|
194
201
|
}
|
|
@@ -19,6 +19,9 @@ import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
|
19
19
|
|
|
20
20
|
import { LLMConnector } from '../LLMConnector';
|
|
21
21
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
22
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
23
|
+
|
|
24
|
+
const logger = Logger('GroqConnector');
|
|
22
25
|
|
|
23
26
|
type ChatCompletionCreateParams = {
|
|
24
27
|
model: string;
|
|
@@ -48,105 +51,117 @@ export class GroqConnector extends LLMConnector {
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
try {
|
|
55
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
56
|
+
const groq = await this.getClient(context);
|
|
57
|
+
const result = await groq.chat.completions.create(body);
|
|
58
|
+
const message = result?.choices?.[0]?.message;
|
|
59
|
+
const finishReason = result?.choices?.[0]?.finish_reason;
|
|
60
|
+
const toolCalls = message?.tool_calls;
|
|
61
|
+
const usage = result.usage;
|
|
62
|
+
this.reportUsage(usage, {
|
|
63
|
+
modelEntryName: context.modelEntryName,
|
|
64
|
+
keySource: context.isUserKey ? APIKeySource.User : APIKeySource.Smyth,
|
|
65
|
+
agentId: context.agentId,
|
|
66
|
+
teamId: context.teamId,
|
|
67
|
+
});
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
let toolsData: ToolData[] = [];
|
|
70
|
+
let useTool = false;
|
|
71
|
+
|
|
72
|
+
if (toolCalls) {
|
|
73
|
+
toolsData = toolCalls.map((tool, index) => ({
|
|
74
|
+
index,
|
|
75
|
+
id: tool.id,
|
|
76
|
+
type: tool.type,
|
|
77
|
+
name: tool.function.name,
|
|
78
|
+
arguments: tool.function.arguments,
|
|
79
|
+
role: TLLMMessageRole.Assistant,
|
|
80
|
+
}));
|
|
81
|
+
useTool = true;
|
|
82
|
+
}
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
return {
|
|
85
|
+
content: message?.content ?? '',
|
|
86
|
+
finishReason,
|
|
87
|
+
useTool,
|
|
88
|
+
toolsData,
|
|
89
|
+
message,
|
|
90
|
+
usage,
|
|
91
|
+
};
|
|
92
|
+
} catch (error) {
|
|
93
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
try {
|
|
100
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
101
|
+
const emitter = new EventEmitter();
|
|
102
|
+
const usage_data = [];
|
|
103
|
+
|
|
104
|
+
const groq = await this.getClient(context);
|
|
105
|
+
const stream = await groq.chat.completions.create({ ...body, stream: true, stream_options: { include_usage: true } });
|
|
106
|
+
|
|
107
|
+
let toolsData: ToolData[] = [];
|
|
108
|
+
|
|
109
|
+
(async () => {
|
|
110
|
+
for await (const chunk of stream as any) {
|
|
111
|
+
const delta = chunk.choices[0]?.delta;
|
|
112
|
+
const usage = chunk['x_groq']?.usage || chunk['usage'];
|
|
113
|
+
|
|
114
|
+
if (usage) {
|
|
115
|
+
usage_data.push(usage);
|
|
116
|
+
}
|
|
117
|
+
emitter.emit('data', delta);
|
|
118
|
+
|
|
119
|
+
if (delta?.content) {
|
|
120
|
+
emitter.emit('content', delta.content);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (delta?.tool_calls) {
|
|
124
|
+
delta.tool_calls.forEach((toolCall, index) => {
|
|
125
|
+
if (!toolsData[index]) {
|
|
126
|
+
toolsData[index] = {
|
|
127
|
+
index,
|
|
128
|
+
id: toolCall.id,
|
|
129
|
+
type: toolCall.type,
|
|
130
|
+
name: toolCall.function?.name,
|
|
131
|
+
arguments: toolCall.function?.arguments,
|
|
132
|
+
role: 'assistant',
|
|
133
|
+
};
|
|
134
|
+
} else {
|
|
135
|
+
toolsData[index].arguments += toolCall.function?.arguments || '';
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
105
139
|
}
|
|
106
|
-
emitter.emit('data', delta);
|
|
107
140
|
|
|
108
|
-
if (
|
|
109
|
-
emitter.emit(
|
|
141
|
+
if (toolsData.length > 0) {
|
|
142
|
+
emitter.emit(TLLMEvent.ToolInfo, toolsData);
|
|
110
143
|
}
|
|
111
144
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
name: toolCall.function?.name,
|
|
120
|
-
arguments: toolCall.function?.arguments,
|
|
121
|
-
role: 'assistant',
|
|
122
|
-
};
|
|
123
|
-
} else {
|
|
124
|
-
toolsData[index].arguments += toolCall.function?.arguments || '';
|
|
125
|
-
}
|
|
145
|
+
usage_data.forEach((usage) => {
|
|
146
|
+
// probably we can acc them and send them as one event
|
|
147
|
+
this.reportUsage(usage, {
|
|
148
|
+
modelEntryName: context.modelEntryName,
|
|
149
|
+
keySource: context.isUserKey ? APIKeySource.User : APIKeySource.Smyth,
|
|
150
|
+
agentId: context.agentId,
|
|
151
|
+
teamId: context.teamId,
|
|
126
152
|
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (toolsData.length > 0) {
|
|
131
|
-
emitter.emit(TLLMEvent.ToolInfo, toolsData);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
usage_data.forEach((usage) => {
|
|
135
|
-
// probably we can acc them and send them as one event
|
|
136
|
-
this.reportUsage(usage, {
|
|
137
|
-
modelEntryName: context.modelEntryName,
|
|
138
|
-
keySource: context.isUserKey ? APIKeySource.User : APIKeySource.Smyth,
|
|
139
|
-
agentId: context.agentId,
|
|
140
|
-
teamId: context.teamId,
|
|
141
153
|
});
|
|
142
|
-
});
|
|
143
154
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
setTimeout(() => {
|
|
156
|
+
emitter.emit('end', toolsData);
|
|
157
|
+
}, 100);
|
|
158
|
+
})();
|
|
148
159
|
|
|
149
|
-
|
|
160
|
+
return emitter;
|
|
161
|
+
} catch (error: any) {
|
|
162
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
150
165
|
}
|
|
151
166
|
|
|
152
167
|
protected async reqBodyAdapter(params: TLLMPreparedParams): Promise<ChatCompletionCreateParams> {
|
|
@@ -19,6 +19,9 @@ import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
|
19
19
|
|
|
20
20
|
import { LLMConnector } from '../LLMConnector';
|
|
21
21
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
22
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
23
|
+
|
|
24
|
+
const logger = Logger('PerplexityConnector');
|
|
22
25
|
|
|
23
26
|
type ChatCompletionParams = {
|
|
24
27
|
model: string;
|
|
@@ -57,6 +60,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
57
60
|
|
|
58
61
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
59
62
|
try {
|
|
63
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
60
64
|
const perplexity = await this.getClient(context);
|
|
61
65
|
const response = await perplexity.post('/chat/completions', body);
|
|
62
66
|
|
|
@@ -80,6 +84,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
80
84
|
usage,
|
|
81
85
|
};
|
|
82
86
|
} catch (error) {
|
|
87
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
83
88
|
throw error;
|
|
84
89
|
}
|
|
85
90
|
}
|
|
@@ -91,6 +96,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
91
96
|
|
|
92
97
|
setTimeout(() => {
|
|
93
98
|
try {
|
|
99
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
94
100
|
this.request({ acRequest, body, context })
|
|
95
101
|
.then((respose) => {
|
|
96
102
|
const finishReason = respose.finishReason;
|
|
@@ -105,6 +111,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
105
111
|
});
|
|
106
112
|
//emitter.emit('finishReason', respose.finishReason);
|
|
107
113
|
} catch (error) {
|
|
114
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
108
115
|
emitter.emit('error', error.message || error.toString());
|
|
109
116
|
}
|
|
110
117
|
}, 100);
|
|
@@ -23,6 +23,9 @@ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.cla
|
|
|
23
23
|
|
|
24
24
|
import { LLMConnector } from '../LLMConnector';
|
|
25
25
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
26
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
27
|
+
|
|
28
|
+
const logger = Logger('VertexAIConnector');
|
|
26
29
|
|
|
27
30
|
//TODO: [AHMED/FORHAD]: test the usage reporting for VertexAI because by the time we were implementing the feature of usage reporting
|
|
28
31
|
// we had no access to VertexAI so we assumed it is working (potential bug)
|
|
@@ -48,6 +51,7 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
48
51
|
|
|
49
52
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
50
53
|
try {
|
|
54
|
+
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
51
55
|
const vertexAI = await this.getClient(context);
|
|
52
56
|
|
|
53
57
|
// Separate contents from model configuration
|
|
@@ -101,6 +105,7 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
101
105
|
useTool,
|
|
102
106
|
};
|
|
103
107
|
} catch (error) {
|
|
108
|
+
logger.error(`request ${this.name}`, error, acRequest.candidate);
|
|
104
109
|
throw error;
|
|
105
110
|
}
|
|
106
111
|
}
|
|
@@ -110,6 +115,7 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
110
115
|
|
|
111
116
|
setTimeout(async () => {
|
|
112
117
|
try {
|
|
118
|
+
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
113
119
|
const vertexAI = await this.getClient(context);
|
|
114
120
|
|
|
115
121
|
// Separate contents from model configuration
|
|
@@ -174,6 +180,7 @@ export class VertexAIConnector extends LLMConnector {
|
|
|
174
180
|
emitter.emit('end', toolsData, usageData, finishReason);
|
|
175
181
|
}, 100);
|
|
176
182
|
} catch (error) {
|
|
183
|
+
logger.error(`streamRequest ${this.name}`, error, acRequest.candidate);
|
|
177
184
|
emitter.emit('error', error);
|
|
178
185
|
}
|
|
179
186
|
}, 100);
|