@smythos/sre 1.6.14 → 1.7.5
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/CHANGELOG +15 -0
- package/dist/index.js +66 -58
- package/dist/index.js.map +1 -1
- package/dist/types/Components/APIEndpoint.class.d.ts +2 -8
- package/dist/types/Components/Component.class.d.ts +9 -0
- package/dist/types/Components/Triggers/Gmail.trigger.d.ts +0 -17
- package/dist/types/Components/Triggers/JobScheduler.trigger.d.ts +10 -0
- package/dist/types/Components/Triggers/Trigger.class.d.ts +11 -0
- package/dist/types/Components/index.d.ts +6 -0
- package/dist/types/Core/Connector.class.d.ts +1 -0
- package/dist/types/Core/ConnectorsService.d.ts +2 -0
- package/dist/types/Core/HookService.d.ts +1 -1
- package/dist/types/helpers/BinaryInput.helper.d.ts +1 -1
- package/dist/types/helpers/Conversation.helper.d.ts +2 -0
- package/dist/types/helpers/Crypto.helper.d.ts +8 -0
- package/dist/types/helpers/LocalCache.helper.d.ts +18 -0
- package/dist/types/helpers/TemplateString.helper.d.ts +2 -1
- package/dist/types/index.d.ts +13 -0
- package/dist/types/subsystems/AgentManager/Agent.class.d.ts +4 -2
- package/dist/types/subsystems/AgentManager/AgentData.service/AgentDataConnector.d.ts +13 -0
- package/dist/types/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.d.ts +1 -4
- package/dist/types/subsystems/AgentManager/Scheduler.service/Job.class.d.ts +29 -6
- package/dist/types/subsystems/AgentManager/Scheduler.service/SchedulerConnector.d.ts +11 -3
- package/dist/types/subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class.d.ts +31 -7
- package/dist/types/subsystems/IO/VectorDB.service/VectorDBConnector.d.ts +4 -4
- package/dist/types/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.d.ts +2 -2
- package/dist/types/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.d.ts +2 -2
- package/dist/types/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.d.ts +2 -2
- package/dist/types/subsystems/IO/VectorDB.service/embed/BaseEmbedding.d.ts +16 -9
- package/dist/types/subsystems/IO/VectorDB.service/embed/index.d.ts +4 -1
- package/dist/types/subsystems/LLMManager/LLM.inference.d.ts +36 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +2 -5
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +3 -6
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +7 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +2 -5
- package/dist/types/types/Agent.types.d.ts +1 -0
- package/dist/types/types/LLM.types.d.ts +56 -36
- package/dist/types/types/SRE.types.d.ts +4 -1
- package/dist/types/types/VectorDB.types.d.ts +6 -3
- package/dist/types/utils/string.utils.d.ts +0 -4
- package/package.json +6 -2
- package/src/Components/APICall/OAuth.helper.ts +30 -35
- package/src/Components/APIEndpoint.class.ts +25 -6
- package/src/Components/Classifier.class.ts +8 -2
- package/src/Components/Component.class.ts +11 -0
- package/src/Components/GenAILLM.class.ts +11 -7
- package/src/Components/LLMAssistant.class.ts +12 -3
- package/src/Components/ScrapflyWebScrape.class.ts +8 -1
- package/src/Components/TavilyWebSearch.class.ts +4 -1
- package/src/Components/Triggers/Gmail.trigger.ts +282 -0
- package/src/Components/Triggers/JobScheduler.trigger.ts +45 -0
- package/src/Components/Triggers/README.md +3 -0
- package/src/Components/Triggers/Trigger.class.ts +101 -0
- package/src/Components/Triggers/WhatsApp.trigger.ts +219 -0
- package/src/Components/index.ts +8 -0
- package/src/Core/AgentProcess.helper.ts +4 -6
- package/src/Core/Connector.class.ts +11 -3
- package/src/Core/ConnectorsService.ts +5 -0
- package/src/Core/ExternalEventsReceiver.ts +317 -0
- package/src/Core/HookService.ts +20 -6
- package/src/Core/SmythRuntime.class.ts +20 -2
- package/src/Core/SystemEvents.ts +17 -0
- package/src/Core/boot.ts +2 -0
- package/src/helpers/BinaryInput.helper.ts +8 -8
- package/src/helpers/Conversation.helper.ts +46 -12
- package/src/helpers/Crypto.helper.ts +28 -0
- package/src/helpers/LocalCache.helper.ts +18 -0
- package/src/helpers/TemplateString.helper.ts +20 -9
- package/src/index.ts +13 -0
- package/src/index.ts.bak +13 -0
- package/src/subsystems/AGENTS.md +594 -0
- package/src/subsystems/AgentManager/Agent.class.ts +73 -21
- package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +30 -6
- package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +2 -2
- package/src/subsystems/AgentManager/AgentLogger.class.ts +1 -1
- package/src/subsystems/AgentManager/AgentRuntime.class.ts +34 -5
- package/src/subsystems/AgentManager/Scheduler.service/Job.class.ts +414 -0
- package/src/subsystems/AgentManager/Scheduler.service/Schedule.class.ts +200 -0
- package/src/subsystems/AgentManager/Scheduler.service/SchedulerConnector.ts +200 -0
- package/src/subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class.ts +767 -0
- package/src/subsystems/AgentManager/Scheduler.service/index.ts +11 -0
- package/src/subsystems/IO/VectorDB.service/VectorDBConnector.ts +15 -4
- package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +32 -11
- package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +27 -10
- package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +25 -9
- package/src/subsystems/IO/VectorDB.service/embed/BaseEmbedding.ts +182 -12
- package/src/subsystems/IO/VectorDB.service/embed/GoogleEmbedding.ts +1 -1
- package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +1 -1
- package/src/subsystems/IO/VectorDB.service/embed/index.ts +12 -2
- package/src/subsystems/LLMManager/LLM.inference.ts +76 -17
- package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +61 -2
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +3 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +3 -1
- package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +5 -1
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +247 -56
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +3 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +28 -21
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +3 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +121 -33
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +38 -27
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +3 -2
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +117 -20
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +3 -0
- package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +3 -8
- package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +4 -1
- package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +12 -0
- package/src/subsystems/MemoryManager/LLMContext.ts +3 -8
- package/src/subsystems/MemoryManager/RuntimeContext.ts +10 -9
- package/src/subsystems/Security/Credentials/Credentials.class.ts +1 -0
- package/src/subsystems/Security/Credentials/ManagedOAuth2Credentials.class.ts +106 -0
- package/src/types/Agent.types.ts +1 -0
- package/src/types/LLM.types.ts +68 -40
- package/src/types/SRE.types.ts +3 -0
- package/src/types/VectorDB.types.ts +7 -3
- package/src/utils/string.utils.ts +193 -191
|
@@ -3,12 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import EventEmitter from 'events';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
GoogleGenAI,
|
|
8
|
-
FunctionCallingConfigMode,
|
|
9
|
-
FileState,
|
|
10
|
-
type GenerateContentResponseUsageMetadata,
|
|
11
|
-
} from '@google/genai/node';
|
|
6
|
+
import { GoogleGenAI, FunctionCallingConfigMode, FileState, type GenerateContentResponseUsageMetadata } from '@google/genai/node';
|
|
12
7
|
|
|
13
8
|
import { JSON_RESPONSE_INSTRUCTION, BUILT_IN_MODEL_PREFIX } from '@sre/constants';
|
|
14
9
|
import { BinaryInput } from '@sre/helpers/BinaryInput.helper';
|
|
@@ -40,6 +35,7 @@ import { SUPPORTED_MIME_TYPES_MAP } from '@sre/constants';
|
|
|
40
35
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
41
36
|
|
|
42
37
|
import { LLMConnector } from '../LLMConnector';
|
|
38
|
+
import { hookAsync } from '@sre/Core/HookService';
|
|
43
39
|
|
|
44
40
|
const logger = Logger('GoogleAIConnector');
|
|
45
41
|
|
|
@@ -90,6 +86,7 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
90
86
|
return new GoogleGenAI({ apiKey });
|
|
91
87
|
}
|
|
92
88
|
|
|
89
|
+
@hookAsync('LLMConnector.request')
|
|
93
90
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
94
91
|
try {
|
|
95
92
|
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
@@ -160,6 +157,7 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
160
157
|
}
|
|
161
158
|
}
|
|
162
159
|
|
|
160
|
+
@hookAsync('LLMConnector.streamRequest')
|
|
163
161
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
164
162
|
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
165
163
|
const emitter = new EventEmitter();
|
|
@@ -436,9 +434,10 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
436
434
|
return body;
|
|
437
435
|
}
|
|
438
436
|
|
|
439
|
-
private normalizePrompt(
|
|
440
|
-
|
|
441
|
-
|
|
437
|
+
private normalizePrompt(prompt: TGoogleAIRequestBody['messages'] | TGoogleAIRequestBody['contents']): {
|
|
438
|
+
contents: any;
|
|
439
|
+
config?: Record<string, any>;
|
|
440
|
+
} {
|
|
442
441
|
if (prompt == null) {
|
|
443
442
|
return { contents: '' };
|
|
444
443
|
}
|
|
@@ -627,87 +626,279 @@ export class GoogleAIConnector extends LLMConnector {
|
|
|
627
626
|
}): TLLMToolResultMessageBlock[] {
|
|
628
627
|
const messageBlocks: TLLMToolResultMessageBlock[] = [];
|
|
629
628
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
629
|
+
const parseFunctionArgs = (args: unknown) => {
|
|
630
|
+
if (typeof args === 'string') {
|
|
631
|
+
try {
|
|
632
|
+
return JSON.parse(args);
|
|
633
|
+
} catch {
|
|
634
|
+
return args;
|
|
635
|
+
}
|
|
636
636
|
}
|
|
637
|
+
return args ?? {};
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
const parseFunctionResponse = (response: unknown): any => {
|
|
641
|
+
if (typeof response === 'string') {
|
|
642
|
+
try {
|
|
643
|
+
const parsed = JSON.parse(response);
|
|
644
|
+
if (typeof parsed === 'string' && parsed !== response) {
|
|
645
|
+
return parseFunctionResponse(parsed);
|
|
646
|
+
}
|
|
647
|
+
return parsed;
|
|
648
|
+
} catch {
|
|
649
|
+
return response;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return response ?? {};
|
|
653
|
+
};
|
|
637
654
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
655
|
+
if (messageBlock) {
|
|
656
|
+
const content: any[] = [];
|
|
657
|
+
|
|
658
|
+
if (Array.isArray(messageBlock.parts) && messageBlock.parts.length > 0) {
|
|
659
|
+
for (const part of messageBlock.parts) {
|
|
660
|
+
if (!part) continue;
|
|
661
|
+
|
|
662
|
+
if (typeof part.text === 'string' && part.text.trim()) {
|
|
663
|
+
content.push({ text: part.text.trim() });
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (part.functionCall) {
|
|
668
|
+
content.push({
|
|
643
669
|
functionCall: {
|
|
644
|
-
name:
|
|
645
|
-
args:
|
|
670
|
+
name: part.functionCall.name,
|
|
671
|
+
args: parseFunctionArgs(part.functionCall.args),
|
|
646
672
|
},
|
|
647
|
-
})
|
|
648
|
-
|
|
673
|
+
});
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (part.functionResponse) {
|
|
678
|
+
content.push({
|
|
679
|
+
functionResponse: {
|
|
680
|
+
name: part.functionResponse.name,
|
|
681
|
+
response: parseFunctionResponse(part.functionResponse.response),
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if ((part as any).inlineData) {
|
|
688
|
+
content.push({ inlineData: (part as any).inlineData });
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
} else {
|
|
692
|
+
if (typeof messageBlock.content === 'string' && messageBlock.content.trim()) {
|
|
693
|
+
content.push({ text: messageBlock.content.trim() });
|
|
694
|
+
} else if (Array.isArray(messageBlock.content) && messageBlock.content.length > 0) {
|
|
695
|
+
content.push(...messageBlock.content);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
const hasFunctionCall = content.some((part) => part.functionCall);
|
|
700
|
+
if (!hasFunctionCall && toolsData.length > 0) {
|
|
701
|
+
toolsData.forEach((toolCall) => {
|
|
702
|
+
content.push({
|
|
703
|
+
functionCall: {
|
|
704
|
+
name: toolCall.name,
|
|
705
|
+
args: parseFunctionArgs(toolCall.arguments),
|
|
706
|
+
},
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (content.length > 0) {
|
|
712
|
+
let role = messageBlock.role;
|
|
713
|
+
if (role === TLLMMessageRole.Assistant) {
|
|
714
|
+
role = TLLMMessageRole.Model;
|
|
649
715
|
}
|
|
716
|
+
|
|
717
|
+
messageBlocks.push({
|
|
718
|
+
role,
|
|
719
|
+
parts: content,
|
|
720
|
+
});
|
|
650
721
|
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const functionResponseParts = toolsData
|
|
725
|
+
.filter((toolData) => toolData.result !== undefined)
|
|
726
|
+
.map((toolData) => ({
|
|
727
|
+
functionResponse: {
|
|
728
|
+
name: toolData.name,
|
|
729
|
+
response: parseFunctionResponse(toolData.result),
|
|
730
|
+
},
|
|
731
|
+
}));
|
|
651
732
|
|
|
733
|
+
if (functionResponseParts.length > 0) {
|
|
652
734
|
messageBlocks.push({
|
|
653
|
-
role:
|
|
654
|
-
parts:
|
|
735
|
+
role: TLLMMessageRole.Function,
|
|
736
|
+
parts: functionResponseParts,
|
|
655
737
|
});
|
|
656
738
|
}
|
|
657
739
|
|
|
658
|
-
|
|
659
|
-
(toolData): TLLMToolResultMessageBlock => ({
|
|
660
|
-
role: TLLMMessageRole.User,
|
|
661
|
-
parts: [
|
|
662
|
-
{
|
|
663
|
-
functionResponse: {
|
|
664
|
-
name: toolData.name,
|
|
665
|
-
response: {
|
|
666
|
-
name: toolData.name,
|
|
667
|
-
content: typeof toolData.result === 'string' ? toolData.result : JSON.stringify(toolData.result),
|
|
668
|
-
},
|
|
669
|
-
},
|
|
670
|
-
},
|
|
671
|
-
],
|
|
672
|
-
})
|
|
673
|
-
);
|
|
674
|
-
|
|
675
|
-
return [...messageBlocks, ...transformedToolsData];
|
|
740
|
+
return messageBlocks;
|
|
676
741
|
}
|
|
677
742
|
|
|
678
743
|
public getConsistentMessages(messages: TLLMMessageBlock[]): TLLMMessageBlock[] {
|
|
679
744
|
const _messages = LLMHelper.removeDuplicateUserMessages(messages);
|
|
680
745
|
|
|
681
746
|
return _messages.map((message) => {
|
|
682
|
-
const _message = { ...message };
|
|
683
|
-
|
|
747
|
+
const _message: TLLMMessageBlock = { ...message };
|
|
748
|
+
|
|
749
|
+
const parseFunctionArgs = (args: unknown) => {
|
|
750
|
+
if (typeof args === 'string') {
|
|
751
|
+
try {
|
|
752
|
+
return JSON.parse(args);
|
|
753
|
+
} catch {
|
|
754
|
+
return args;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
return args ?? {};
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
const parseFunctionResponse = (response: unknown) => {
|
|
762
|
+
if (typeof response === 'string') {
|
|
763
|
+
try {
|
|
764
|
+
return JSON.parse(response);
|
|
765
|
+
} catch {
|
|
766
|
+
return response;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return response;
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
const pushTextPart = (parts: any[], text?: string) => {
|
|
774
|
+
const value = typeof text === 'string' && text.trim() ? text : undefined;
|
|
775
|
+
if (value) {
|
|
776
|
+
parts.push({ text: value });
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
const normalizedParts: any[] = [];
|
|
684
781
|
|
|
685
782
|
// Map roles to valid Google AI roles
|
|
686
783
|
switch (_message.role) {
|
|
687
784
|
case TLLMMessageRole.Assistant:
|
|
688
785
|
case TLLMMessageRole.System:
|
|
786
|
+
case TLLMMessageRole.Model:
|
|
689
787
|
_message.role = TLLMMessageRole.Model;
|
|
690
788
|
break;
|
|
789
|
+
case TLLMMessageRole.Function:
|
|
790
|
+
case TLLMMessageRole.Tool:
|
|
791
|
+
_message.role = TLLMMessageRole.Function;
|
|
792
|
+
break;
|
|
691
793
|
case TLLMMessageRole.User:
|
|
692
|
-
// User role is already valid
|
|
693
794
|
break;
|
|
694
795
|
default:
|
|
695
|
-
_message.role = TLLMMessageRole.User;
|
|
796
|
+
_message.role = TLLMMessageRole.User;
|
|
696
797
|
}
|
|
697
798
|
|
|
698
|
-
|
|
799
|
+
if (Array.isArray(message?.parts)) {
|
|
800
|
+
for (const part of message.parts) {
|
|
801
|
+
if (!part) continue;
|
|
802
|
+
|
|
803
|
+
const normalizedPart: any = { ...part };
|
|
804
|
+
|
|
805
|
+
if (typeof normalizedPart.text === 'string') {
|
|
806
|
+
normalizedPart.text = normalizedPart.text.trim() || '...';
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (part.functionCall) {
|
|
810
|
+
normalizedPart.functionCall = {
|
|
811
|
+
name: part.functionCall.name,
|
|
812
|
+
args: parseFunctionArgs(part.functionCall.args),
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (part.functionResponse) {
|
|
817
|
+
normalizedPart.functionResponse = {
|
|
818
|
+
name: part.functionResponse.name,
|
|
819
|
+
response: parseFunctionResponse(part.functionResponse.response),
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const hasMeaningfulContent = Object.values(normalizedPart).some((value) => value !== undefined && value !== null && value !== '');
|
|
824
|
+
|
|
825
|
+
if (hasMeaningfulContent) {
|
|
826
|
+
normalizedParts.push(normalizedPart);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (!normalizedParts.length && Array.isArray(message?.content)) {
|
|
832
|
+
for (const contentPart of message.content) {
|
|
833
|
+
if (!contentPart) continue;
|
|
834
|
+
|
|
835
|
+
if (typeof contentPart === 'string') {
|
|
836
|
+
pushTextPart(normalizedParts, contentPart);
|
|
837
|
+
} else if (typeof contentPart === 'object') {
|
|
838
|
+
if ('text' in contentPart && typeof contentPart.text === 'string') {
|
|
839
|
+
pushTextPart(normalizedParts, contentPart.text);
|
|
840
|
+
} else if ('functionCall' in contentPart && (contentPart as any).functionCall) {
|
|
841
|
+
const functionCallPart = (contentPart as any).functionCall;
|
|
842
|
+
normalizedParts.push({
|
|
843
|
+
functionCall: {
|
|
844
|
+
name: functionCallPart.name,
|
|
845
|
+
args: parseFunctionArgs(functionCallPart.args),
|
|
846
|
+
},
|
|
847
|
+
});
|
|
848
|
+
} else if ('functionResponse' in contentPart && (contentPart as any).functionResponse) {
|
|
849
|
+
const functionResponsePart = (contentPart as any).functionResponse;
|
|
850
|
+
normalizedParts.push({
|
|
851
|
+
functionResponse: {
|
|
852
|
+
name: functionResponsePart.name,
|
|
853
|
+
response: parseFunctionResponse(functionResponsePart.response),
|
|
854
|
+
},
|
|
855
|
+
});
|
|
856
|
+
} else {
|
|
857
|
+
const fallbackText = typeof (contentPart as any)?.toString === 'function' ? (contentPart as any).toString() : '';
|
|
858
|
+
if (fallbackText && fallbackText !== '[object Object]') {
|
|
859
|
+
pushTextPart(normalizedParts, fallbackText);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (!normalizedParts.length) {
|
|
867
|
+
if (typeof message?.content === 'string') {
|
|
868
|
+
pushTextPart(normalizedParts, message.content);
|
|
869
|
+
} else if (message?.content && typeof message.content === 'object') {
|
|
870
|
+
if ('text' in (message.content as any)) {
|
|
871
|
+
pushTextPart(normalizedParts, (message.content as any).text);
|
|
872
|
+
} else {
|
|
873
|
+
const fallbackText = typeof (message.content as any)?.toString === 'function' ? (message.content as any).toString() : '';
|
|
874
|
+
if (fallbackText && fallbackText !== '[object Object]') {
|
|
875
|
+
pushTextPart(normalizedParts, fallbackText);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (Array.isArray(message?.tool_calls) && message.tool_calls.length > 0) {
|
|
882
|
+
for (const toolCall of message.tool_calls) {
|
|
883
|
+
if (!toolCall?.function?.name) continue;
|
|
884
|
+
|
|
885
|
+
normalizedParts.push({
|
|
886
|
+
functionCall: {
|
|
887
|
+
name: toolCall.function.name,
|
|
888
|
+
args: parseFunctionArgs(toolCall.function.arguments),
|
|
889
|
+
},
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
699
893
|
|
|
700
|
-
if (
|
|
701
|
-
|
|
702
|
-
} else if (Array.isArray(_message?.content)) {
|
|
703
|
-
textContent = _message.content.map((textBlock) => textBlock?.text || '...').join(' ');
|
|
704
|
-
} else if (_message?.content) {
|
|
705
|
-
textContent = (_message.content as string) || '...';
|
|
894
|
+
if (!normalizedParts.length) {
|
|
895
|
+
normalizedParts.push({ text: '...' });
|
|
706
896
|
}
|
|
707
897
|
|
|
708
|
-
_message.parts =
|
|
898
|
+
_message.parts = normalizedParts as any;
|
|
709
899
|
|
|
710
900
|
delete _message.content; // Remove content to avoid error
|
|
901
|
+
delete (_message as any).tool_calls;
|
|
711
902
|
|
|
712
903
|
return _message;
|
|
713
904
|
});
|
|
@@ -20,6 +20,7 @@ import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
|
20
20
|
import { LLMConnector } from '../LLMConnector';
|
|
21
21
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
22
22
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
23
|
+
import { hookAsync } from '@sre/Core/HookService';
|
|
23
24
|
|
|
24
25
|
const logger = Logger('GroqConnector');
|
|
25
26
|
|
|
@@ -50,6 +51,7 @@ export class GroqConnector extends LLMConnector {
|
|
|
50
51
|
return new Groq({ apiKey });
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
@hookAsync('LLMConnector.request')
|
|
53
55
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
54
56
|
try {
|
|
55
57
|
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
@@ -95,6 +97,7 @@ export class GroqConnector extends LLMConnector {
|
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
@hookAsync('LLMConnector.streamRequest')
|
|
98
101
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
99
102
|
try {
|
|
100
103
|
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ollama, ChatResponse } from 'ollama';
|
|
1
|
+
import { Ollama, ChatResponse, type ChatRequest } from 'ollama';
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
3
|
|
|
4
4
|
import { JSON_RESPONSE_INSTRUCTION, BUILT_IN_MODEL_PREFIX } from '@sre/constants';
|
|
@@ -14,12 +14,14 @@ import {
|
|
|
14
14
|
TLLMPreparedParams,
|
|
15
15
|
TLLMToolResultMessageBlock,
|
|
16
16
|
TLLMRequestBody,
|
|
17
|
+
BasicCredentials,
|
|
17
18
|
} from '@sre/types/LLM.types';
|
|
18
19
|
import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
19
20
|
|
|
20
21
|
import { LLMConnector } from '../LLMConnector';
|
|
21
22
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
22
23
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
24
|
+
import { hookAsync } from '@sre/Core/HookService';
|
|
23
25
|
|
|
24
26
|
const logger = Logger('OllamaConnector');
|
|
25
27
|
|
|
@@ -44,33 +46,37 @@ export class OllamaConnector extends LLMConnector {
|
|
|
44
46
|
// Extract baseURL and sanitize it for Ollama SDK
|
|
45
47
|
let host = 'http://localhost:11434';
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
const apiKey = (context.credentials as BasicCredentials)?.apiKey;
|
|
50
|
+
const baseURL = context?.modelInfo?.baseURL;
|
|
51
|
+
|
|
52
|
+
if (baseURL) {
|
|
53
|
+
// Extract base URL (origin) using URL class
|
|
54
|
+
const url = new URL(baseURL);
|
|
55
|
+
host = url.origin;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const config: { host: string; headers?: { Authorization?: string } } = { host };
|
|
59
|
+
|
|
60
|
+
if (apiKey) {
|
|
61
|
+
config.headers = {
|
|
62
|
+
Authorization: `Bearer ${apiKey}`,
|
|
63
|
+
};
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
// No API key validation required for Ollama (local by default)
|
|
62
|
-
return new Ollama(
|
|
67
|
+
return new Ollama(config);
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
@hookAsync('LLMConnector.request')
|
|
65
71
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
66
72
|
try {
|
|
67
73
|
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
68
74
|
const ollama = this.getClient(context);
|
|
69
75
|
|
|
70
|
-
const result = await ollama.chat({
|
|
76
|
+
const result = (await ollama.chat({
|
|
71
77
|
...body,
|
|
72
78
|
stream: false,
|
|
73
|
-
}) as unknown as ChatResponse;
|
|
79
|
+
})) as unknown as ChatResponse;
|
|
74
80
|
|
|
75
81
|
const message = result.message;
|
|
76
82
|
const finishReason = result.done_reason || 'stop';
|
|
@@ -117,6 +123,7 @@ export class OllamaConnector extends LLMConnector {
|
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
125
|
|
|
126
|
+
@hookAsync('LLMConnector.streamRequest')
|
|
120
127
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
121
128
|
try {
|
|
122
129
|
logger.debug(`streamRequest ${this.name}`, acRequest.candidate);
|
|
@@ -124,10 +131,10 @@ export class OllamaConnector extends LLMConnector {
|
|
|
124
131
|
const usage_data = [];
|
|
125
132
|
|
|
126
133
|
const ollama = this.getClient(context);
|
|
127
|
-
const stream = await ollama.chat({
|
|
134
|
+
const stream = (await ollama.chat({
|
|
128
135
|
...body,
|
|
129
136
|
stream: true,
|
|
130
|
-
}) as AsyncIterable<ChatResponse>;
|
|
137
|
+
})) as AsyncIterable<ChatResponse>;
|
|
131
138
|
|
|
132
139
|
let toolsData: ToolData[] = [];
|
|
133
140
|
let fullContent = '';
|
|
@@ -159,7 +166,7 @@ export class OllamaConnector extends LLMConnector {
|
|
|
159
166
|
toolsData[index].arguments += toolCall.function.arguments;
|
|
160
167
|
} else {
|
|
161
168
|
// For object arguments, merge them properly
|
|
162
|
-
toolsData[index].arguments = { ...toolsData[index].arguments as any, ...toolCall.function?.arguments };
|
|
169
|
+
toolsData[index].arguments = { ...(toolsData[index].arguments as any), ...toolCall.function?.arguments };
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
});
|
|
@@ -237,7 +244,7 @@ export class OllamaConnector extends LLMConnector {
|
|
|
237
244
|
|
|
238
245
|
// Handle tools
|
|
239
246
|
if (params.toolsConfig?.tools) {
|
|
240
|
-
body.tools = params.toolsConfig.tools.map(tool => ({
|
|
247
|
+
body.tools = params.toolsConfig.tools.map((tool) => ({
|
|
241
248
|
type: 'function',
|
|
242
249
|
function: {
|
|
243
250
|
name: tool.function.name,
|
|
@@ -359,4 +366,4 @@ export class OllamaConnector extends LLMConnector {
|
|
|
359
366
|
return _message;
|
|
360
367
|
});
|
|
361
368
|
}
|
|
362
|
-
}
|
|
369
|
+
}
|
|
@@ -20,6 +20,7 @@ import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
|
20
20
|
import { LLMConnector } from '../LLMConnector';
|
|
21
21
|
import { SystemEvents } from '@sre/Core/SystemEvents';
|
|
22
22
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
23
|
+
import { hookAsync } from '@sre/Core/HookService';
|
|
23
24
|
|
|
24
25
|
const logger = Logger('PerplexityConnector');
|
|
25
26
|
|
|
@@ -58,6 +59,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
@hookAsync('LLMConnector.request')
|
|
61
63
|
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
62
64
|
try {
|
|
63
65
|
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
@@ -89,6 +91,7 @@ export class PerplexityConnector extends LLMConnector {
|
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
@hookAsync('LLMConnector.streamRequest')
|
|
92
95
|
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
93
96
|
//throw new Error('Multimodal request is not supported for Perplexity.');
|
|
94
97
|
//fallback to chatRequest
|