@futdevpro/nts-dynamo 1.14.35 → 1.14.37
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/build/_modules/ai/_models/ai-input-interfaces.d.ts +20 -28
- package/build/_modules/ai/_models/ai-input-interfaces.d.ts.map +1 -1
- package/build/_modules/ai/_models/ai-input-interfaces.js +3 -0
- package/build/_modules/ai/_models/ai-input-interfaces.js.map +1 -1
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.d.ts +14 -58
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.d.ts.map +1 -1
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.js +138 -147
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.js.map +1 -1
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.d.ts +27 -180
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.d.ts.map +1 -1
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.js +147 -328
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.js.map +1 -1
- package/build/_modules/ai/_services/ai-llm-chat.service-base.d.ts +22 -14
- package/build/_modules/ai/_services/ai-llm-chat.service-base.d.ts.map +1 -1
- package/build/_modules/ai/_services/ai-llm-chat.service-base.js.map +1 -1
- package/build/_modules/ai/_services/ai-llm.service-base.d.ts +52 -21
- package/build/_modules/ai/_services/ai-llm.service-base.d.ts.map +1 -1
- package/build/_modules/ai/_services/ai-llm.service-base.js +171 -0
- package/build/_modules/ai/_services/ai-llm.service-base.js.map +1 -1
- package/build/_modules/ai/_services/ai-provider.service-base.d.ts +1 -1
- package/build/_modules/ai/_services/ai-provider.service-base.d.ts.map +1 -1
- package/build/_modules/assistant/_services/ass-io.control-service.js +2 -2
- package/build/_modules/assistant/_services/ass-io.control-service.js.map +1 -1
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.d.ts +8 -2
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.d.ts.map +1 -1
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.js +31 -0
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.js.map +1 -1
- package/build/_modules/bot/_models/bot-message-wrapper.interface.d.ts +6 -1
- package/build/_modules/bot/_models/bot-message-wrapper.interface.d.ts.map +1 -1
- package/build/_modules/bot/_models/bot-message-wrapper.interface.js +39 -0
- package/build/_modules/bot/_models/bot-message-wrapper.interface.js.map +1 -1
- package/build/_modules/bot/_models/bot-user-wrapper.interface.d.ts +2 -1
- package/build/_modules/bot/_models/bot-user-wrapper.interface.d.ts.map +1 -1
- package/build/_modules/bot/_models/bot-user-wrapper.interface.js +18 -0
- package/build/_modules/bot/_models/bot-user-wrapper.interface.js.map +1 -1
- package/build/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.js +9 -6
- package/build/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.js.map +1 -1
- package/build/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.js +9 -6
- package/build/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.js.map +1 -1
- package/build/_modules/discord-assistant/_services/dias-chunk.data-service.js +9 -9
- package/build/_modules/discord-assistant/_services/dias-chunk.data-service.js.map +1 -1
- package/build/_modules/discord-assistant/_services/dias-io.control-service.js +2 -2
- package/build/_modules/discord-assistant/_services/dias-io.control-service.js.map +1 -1
- package/package.json +1 -1
- package/src/_modules/ai/_models/ai-input-interfaces.ts +63 -26
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +99 -139
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +246 -294
- package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +36 -16
- package/src/_modules/ai/_services/ai-llm.service-base.ts +272 -28
- package/src/_modules/ai/_services/ai-provider.service-base.ts +1 -1
- package/src/_modules/assistant/_services/ass-io.control-service.ts +2 -2
- package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +30 -4
- package/src/_modules/bot/_models/bot-message-wrapper.interface.ts +24 -2
- package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +8 -2
- package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.ts +6 -6
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +6 -6
- package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +9 -9
- package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +2 -2
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { DyNTS_AI_LLM_ServiceBase } from './ai-llm.service-base';
|
|
2
|
-
import { DyFM_AI_Message } from '@futdevpro/fsm-dynamo/ai';
|
|
2
|
+
import { DyFM_AI_Message, DyFM_AI_CallSettings } from '@futdevpro/fsm-dynamo/ai';
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
DyFM_AI_ConversationBase_Input,
|
|
5
5
|
DyFM_AI_ConversationSelect_Input,
|
|
6
6
|
DyFM_AI_ConversationGenericSelect_Input,
|
|
7
7
|
DyFM_AI_ConversationMultiSelect_Input,
|
|
8
8
|
DyFM_AI_ConversationGenericMultiSelect_Input,
|
|
9
9
|
DyFM_AI_ConversationJSONKeysDescription_Input,
|
|
10
10
|
DyFM_AI_ConversationJSONExactKeys_Input,
|
|
11
|
-
DyFM_AI_ConversationGetAnswer_Input
|
|
12
11
|
} from '../_models/ai-input-interfaces';
|
|
12
|
+
import { DyFM_getLocalStackLocation, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Abstract base class for LLM Chat services
|
|
16
16
|
* Extends LLM service with conversation management capabilities
|
|
17
17
|
*/
|
|
18
|
-
export abstract class DyNTS_AI_LLMChat_ServiceBase
|
|
18
|
+
export abstract class DyNTS_AI_LLMChat_ServiceBase<
|
|
19
|
+
T_AISettings extends DyFM_AI_CallSettings = DyFM_AI_CallSettings
|
|
20
|
+
> extends DyNTS_AI_LLM_ServiceBase<T_AISettings> {
|
|
19
21
|
// History management
|
|
20
22
|
/**
|
|
21
23
|
* Add a message to the conversation history
|
|
@@ -33,16 +35,34 @@ export abstract class DyNTS_AI_LLMChat_ServiceBase extends DyNTS_AI_LLM_ServiceB
|
|
|
33
35
|
/* abstract getHistory(issuer: string): DyFM_AI_Message[]; */
|
|
34
36
|
|
|
35
37
|
// Conversation methods (from OAI_LLMChat_ServiceBase)
|
|
36
|
-
abstract
|
|
37
|
-
abstract
|
|
38
|
-
abstract
|
|
39
|
-
|
|
40
|
-
abstract
|
|
41
|
-
abstract
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
abstract
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
abstract
|
|
38
|
+
abstract requestSimpleMessageInConversation(set: DyFM_AI_ConversationBase_Input<T_AISettings>): Promise<string>;
|
|
39
|
+
abstract requestYesNoInConversation(set: DyFM_AI_ConversationBase_Input<T_AISettings>): Promise<boolean>;
|
|
40
|
+
abstract requestPercentageInConversation(set: DyFM_AI_ConversationBase_Input<T_AISettings>): Promise<number>;
|
|
41
|
+
|
|
42
|
+
/* abstract selectQuestionInConversation(set: DyFM_AI_ConversationSelect_Input): Promise<string>; */
|
|
43
|
+
abstract requestSelectInConversation<T>(
|
|
44
|
+
set: DyFM_AI_ConversationGenericSelect_Input<T, T_AISettings>
|
|
45
|
+
): Promise<T | { unparsableResult: string }>;
|
|
46
|
+
/* abstract multipleSelectQuestionInConversationWithOptions(
|
|
47
|
+
set: DyFM_AI_ConversationMultiSelect_Input<T_AISettings>
|
|
48
|
+
): Promise<string[]>; */
|
|
49
|
+
abstract requestMultiselectInConversation<T>(
|
|
50
|
+
set: DyFM_AI_ConversationGenericMultiSelect_Input<T, T_AISettings>
|
|
51
|
+
): Promise<T[] | { unparsableResult: string }>;
|
|
52
|
+
|
|
53
|
+
abstract requestJSONInConversation<T = any>(
|
|
54
|
+
set: DyFM_AI_ConversationBase_Input<T_AISettings>
|
|
55
|
+
): Promise<T | { unparsableResult: string }>;
|
|
56
|
+
abstract requestJSONInConversationWithKeysDescription<T>(
|
|
57
|
+
set: DyFM_AI_ConversationJSONKeysDescription_Input<T_AISettings>
|
|
58
|
+
): Promise<T | { unparsableResult: string }>;
|
|
59
|
+
abstract requestJSONInConversationWithExactKeys<T>(
|
|
60
|
+
set: DyFM_AI_ConversationJSONExactKeys_Input<T_AISettings>
|
|
61
|
+
): Promise<T | { unparsableResult: string }>;
|
|
62
|
+
//abstract getQuestionAnswerInConversation(set: DyFM_AI_ConversationQuestion_Input): Promise<string>;
|
|
63
|
+
//abstract getAnswerInConversation(set: DyFM_AI_ConversationGetAnswer_Input): Promise<string>;
|
|
64
|
+
|
|
65
|
+
abstract requestListInConversation(
|
|
66
|
+
set: DyFM_AI_ConversationBase_Input<T_AISettings>
|
|
67
|
+
): Promise<string[] | { unparsableResult: string }>;
|
|
48
68
|
}
|
|
@@ -1,72 +1,101 @@
|
|
|
1
1
|
import { DyNTS_AI_Provider_ServiceBase } from './ai-provider.service-base';
|
|
2
|
-
import { DyFM_AI_CallSettings, DyFM_AI_Message, DyFM_AI_LLM_Response } from '@futdevpro/fsm-dynamo/ai';
|
|
3
|
-
import { DyFM_Error_Settings } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
import { DyFM_AI_CallSettings, DyFM_AI_Message, DyFM_AI_LLM_Response, DyFM_AI_MessageRole } from '@futdevpro/fsm-dynamo/ai';
|
|
3
|
+
import { DyFM_Error, DyFM_Error_Settings, DyFM_getLocalStackLocation, DyFM_Log, DyFM_Object } from '@futdevpro/fsm-dynamo';
|
|
4
4
|
import {
|
|
5
|
-
DyFM_AI_Question_Input,
|
|
6
|
-
DyFM_AI_ListSelect_Input,
|
|
7
5
|
DyFM_AI_GenericSelect_Input,
|
|
8
|
-
DyFM_AI_MultiSelect_Input,
|
|
9
6
|
DyFM_AI_GenericMultiSelect_Input,
|
|
10
7
|
DyFM_AI_JSONKeysDescription_Input,
|
|
11
8
|
DyFM_AI_JSONExactKeys_Input,
|
|
12
|
-
|
|
9
|
+
DyFM_AI_Message_Input,
|
|
13
10
|
} from '../_models/ai-input-interfaces';
|
|
11
|
+
import { Items } from 'openai/resources/conversations/items';
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Abstract base class for LLM services
|
|
17
15
|
* Defines all methods that must be implemented by AI providers
|
|
18
16
|
*/
|
|
19
|
-
export abstract class DyNTS_AI_LLM_ServiceBase
|
|
17
|
+
export abstract class DyNTS_AI_LLM_ServiceBase<
|
|
18
|
+
T_AISettings extends DyFM_AI_CallSettings = DyFM_AI_CallSettings
|
|
19
|
+
> extends DyNTS_AI_Provider_ServiceBase {
|
|
20
20
|
/** Default settings for LLM calls */
|
|
21
|
-
abstract readonly defaultSettings:
|
|
21
|
+
abstract readonly defaultSettings: T_AISettings;
|
|
22
22
|
|
|
23
23
|
/** Default model to use for LLM calls */
|
|
24
|
-
abstract readonly defaultModel: string;
|
|
24
|
+
/* abstract readonly defaultModel: string; */
|
|
25
25
|
|
|
26
26
|
/** Provider-specific predefined requests */
|
|
27
27
|
abstract readonly predefinedRequests: any;
|
|
28
|
+
|
|
29
|
+
_debugLog: boolean = false;
|
|
30
|
+
get debugLog(): boolean {
|
|
31
|
+
return this.defaultSettings?.debugLog ?? this._debugLog;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get defaultSystemPrompt(): string {
|
|
35
|
+
return this.defaultSettings.systemPrompt;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get defaultModel(): string {
|
|
39
|
+
return this.defaultSettings.useModel;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
defaultLogReplacer: string = '...long-context...';
|
|
28
43
|
|
|
29
44
|
// Core abstract methods
|
|
30
45
|
/**
|
|
31
46
|
* Call LLM with system and user messages
|
|
32
47
|
*/
|
|
33
|
-
abstract callLLM(
|
|
48
|
+
/* abstract callLLM(
|
|
34
49
|
systemMessage: string,
|
|
35
50
|
userMessage: string,
|
|
36
51
|
settings?: DyFM_AI_CallSettings,
|
|
37
52
|
issuer?: string
|
|
38
|
-
): Promise<string>;
|
|
53
|
+
): Promise<string>; */
|
|
39
54
|
|
|
40
55
|
/**
|
|
41
56
|
* Call LLM with message history
|
|
42
57
|
*/
|
|
43
|
-
abstract callLLMWithHistory(
|
|
58
|
+
/* abstract callLLMWithHistory(
|
|
44
59
|
messages: DyFM_AI_Message[],
|
|
45
60
|
settings?: DyFM_AI_CallSettings,
|
|
46
61
|
issuer?: string
|
|
47
|
-
): Promise<string>;
|
|
62
|
+
): Promise<string>; */
|
|
48
63
|
|
|
49
64
|
/**
|
|
50
65
|
* Call LLM and return raw response
|
|
51
66
|
*/
|
|
52
|
-
abstract callLLMRaw(
|
|
67
|
+
/* abstract callLLMRaw(
|
|
53
68
|
messages: DyFM_AI_Message[],
|
|
54
69
|
settings?: DyFM_AI_CallSettings,
|
|
55
70
|
issuer?: string
|
|
56
|
-
): Promise<DyFM_AI_LLM_Response>;
|
|
71
|
+
): Promise<DyFM_AI_LLM_Response>; */
|
|
57
72
|
|
|
58
73
|
// Question methods (from OAI_LLM_ServiceBase)
|
|
59
|
-
abstract
|
|
60
|
-
abstract
|
|
61
|
-
abstract
|
|
62
|
-
|
|
63
|
-
abstract
|
|
64
|
-
abstract
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
abstract
|
|
68
|
-
abstract
|
|
69
|
-
|
|
74
|
+
abstract requestSimpleMessage(set: DyFM_AI_Message_Input<T_AISettings>): Promise<string>;
|
|
75
|
+
abstract requestYesNo(set: DyFM_AI_Message_Input<T_AISettings>): Promise<boolean>;
|
|
76
|
+
abstract requestPercentage(set: DyFM_AI_Message_Input<T_AISettings>): Promise<number>;
|
|
77
|
+
|
|
78
|
+
/* abstract askSelectQuestion(set: DyFM_AI_ListSelect_Input): Promise<string>; */
|
|
79
|
+
abstract requestSelect<T>(
|
|
80
|
+
set: DyFM_AI_GenericSelect_Input<T, T_AISettings>
|
|
81
|
+
): Promise<T | { unparsableResult: string }>;
|
|
82
|
+
/* abstract askMultipleSelectQuestionWithOptions(set: DyFM_AI_MultiSelect_Input): Promise<string[]>; */
|
|
83
|
+
abstract requestMultiselect<T>(
|
|
84
|
+
set: DyFM_AI_GenericMultiSelect_Input<T, T_AISettings>
|
|
85
|
+
): Promise<T[] | { unparsableResult: string }>;
|
|
86
|
+
|
|
87
|
+
abstract requestJSON<T>(set: DyFM_AI_Message_Input<T_AISettings>): Promise<T | { unparsableResult: string }>;
|
|
88
|
+
abstract requestJSONQuestionWithKeysDescription<T>(
|
|
89
|
+
set: DyFM_AI_JSONKeysDescription_Input<T_AISettings>
|
|
90
|
+
): Promise<T | { unparsableResult: string }>;
|
|
91
|
+
/* abstract askJSONQuestionWithExactKeys(set: DyFM_AI_JSONExactKeys_Input): Promise<object>; */
|
|
92
|
+
abstract requestJSONWithExactKeys<T>(
|
|
93
|
+
set: DyFM_AI_JSONExactKeys_Input<T_AISettings>
|
|
94
|
+
): Promise<T | { unparsableResult: string }>;
|
|
95
|
+
/* abstract sendMessage(set: DyFM_AI_SimpleMessage_Input): Promise<string>; */
|
|
96
|
+
|
|
97
|
+
/* abstract requestStringList(set: DyFM_AI_Base_Input<T_AISettings>): Promise<string[] | { unparsableResult: string }>; */
|
|
98
|
+
abstract requestList<T>(set: DyFM_AI_Message_Input<T_AISettings>): Promise<T[] | { unparsableResult: string }>;
|
|
70
99
|
|
|
71
100
|
// Helper methods
|
|
72
101
|
/* protected abstract getDefaultErrorSettings(
|
|
@@ -75,7 +104,222 @@ export abstract class DyNTS_AI_LLM_ServiceBase extends DyNTS_AI_Provider_Service
|
|
|
75
104
|
issuer?: string
|
|
76
105
|
): DyFM_Error_Settings; */
|
|
77
106
|
|
|
78
|
-
protected abstract getTextListAsText(list: string[]): string;
|
|
107
|
+
/* protected abstract getTextListAsText(list: string[]): string; */
|
|
79
108
|
|
|
80
|
-
protected abstract logQuestion(set:
|
|
109
|
+
/* protected abstract logQuestion(set: DyFM_AI_Base_Input<T_AISettings>): void; */
|
|
110
|
+
|
|
111
|
+
protected convertAnswerToBoolean(answer: string): boolean {
|
|
112
|
+
return answer.toUpperCase().includes(this.predefinedRequests.yesNo.upperCaseYes);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected convertAnswerToNumber(answer: string, message: string): number {
|
|
116
|
+
if (this.isAnswerValid(answer, message)) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isNaN(+answer)) {
|
|
121
|
+
DyFM_Log.T_error(
|
|
122
|
+
'DyNTS_AI_LLMChat_ServiceBase.convertAnswerToNumber got an invalid answer',
|
|
123
|
+
{
|
|
124
|
+
question: message,
|
|
125
|
+
answer: answer,
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return +answer;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected convertAnswerToSelectOption<T>(answer: string, message: string, options: T[]): T {
|
|
136
|
+
if (this.isAnswerValid(answer, message)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
answer = answer.toLocaleUpperCase();
|
|
141
|
+
|
|
142
|
+
const stringifiedOptions: string[] = this.stringifySelectOptions(options);
|
|
143
|
+
for (const stringifiedItem of stringifiedOptions) {
|
|
144
|
+
if (answer.includes(stringifiedItem.toLocaleUpperCase())) {
|
|
145
|
+
const parsedItem: T | { unparsableResult: string } = DyFM_Object.safeParseJSON<T>(stringifiedItem);
|
|
146
|
+
|
|
147
|
+
if ((parsedItem as { unparsableResult: string }).unparsableResult) {
|
|
148
|
+
DyFM_Log.T_error(
|
|
149
|
+
'DyNTS_AI_LLMChat_ServiceBase.convertAnswerToSelectOption got an invalid answer',
|
|
150
|
+
{
|
|
151
|
+
question: message,
|
|
152
|
+
answer: answer,
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
return stringifiedItem as T;
|
|
157
|
+
} else {
|
|
158
|
+
return parsedItem as T;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
protected convertAnswerToSelectOptions<T>(answer: string, message: string, options: T[]): T[] {
|
|
167
|
+
if (this.isAnswerValid(answer, message)) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const enrichedOptions: { stringifiedOption: string, parsedOption: T }[] = options.map(
|
|
172
|
+
(option: T) => ({
|
|
173
|
+
stringifiedOption: this.stringifySelectOption(option),
|
|
174
|
+
parsedOption: option
|
|
175
|
+
})
|
|
176
|
+
);
|
|
177
|
+
const result: T[] = [];
|
|
178
|
+
|
|
179
|
+
for (const item of enrichedOptions) {
|
|
180
|
+
if (answer.includes(item.stringifiedOption)) {
|
|
181
|
+
result.push(item.parsedOption);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
protected convertAnswerToJSON<T>(answer: string, message: string): T {
|
|
189
|
+
if (this.isAnswerValid(answer, message)) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const parsedItem: T | { unparsableResult: string } = DyFM_Object.safeParseJSON<T>(answer);
|
|
194
|
+
if ((parsedItem as { unparsableResult: string }).unparsableResult) {
|
|
195
|
+
DyFM_Log.T_error(
|
|
196
|
+
'DyNTS_AI_LLMChat_ServiceBase.convertAnswerToJSON got an invalid answer',
|
|
197
|
+
{
|
|
198
|
+
question: message,
|
|
199
|
+
answer: answer,
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return parsedItem as T;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
protected convertAnswerToList<T>(answer: string, message: string): T[] {
|
|
210
|
+
if (this.isAnswerValid(answer, message)) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return DyFM_Object.safeParseList<T[]>(answer);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
protected stringifySelectOptions<T>(options: T[]): string[] {
|
|
218
|
+
return options.map(item => this.stringifySelectOption(item));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
protected stringifySelectOption<T>(option: T): string {
|
|
222
|
+
return JSON.stringify(option);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
protected isAnswerValid(answer: string, message: string): boolean {
|
|
226
|
+
if (!answer?.trim?.()?.length) {
|
|
227
|
+
DyFM_Log.T_error(
|
|
228
|
+
'DyNTS_AI_LLMChat_ServiceBase.convertAnswerToSelectOption got an invalid answer',
|
|
229
|
+
{
|
|
230
|
+
question: message,
|
|
231
|
+
answer: answer,
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* olvasható mondatszerű-listaszerű formába teszi a listaelemeket
|
|
243
|
+
* pl.: ['a', 'b', 'c'] -> '"a", "b" or "c"'
|
|
244
|
+
*/
|
|
245
|
+
protected getTextListAsText(list: string[]): string {
|
|
246
|
+
list = list.filter(item => item?.trim()).map(item => `"${item}"`);
|
|
247
|
+
|
|
248
|
+
/* list = list.map(item => item.toLocaleLowerCase()); */
|
|
249
|
+
|
|
250
|
+
list.push(list.pop() + ' or ' + list.pop());
|
|
251
|
+
|
|
252
|
+
return list.join(', ');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
protected logQuestion(
|
|
256
|
+
set: DyFM_AI_Message_Input<T_AISettings>
|
|
257
|
+
): void {
|
|
258
|
+
if (set.settings?.debugLog ?? this._debugLog) {
|
|
259
|
+
console.log('\n - ', set.message);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
protected getDefaultSystemMessage(settings: T_AISettings): DyFM_AI_Message {
|
|
264
|
+
return {
|
|
265
|
+
role: DyFM_AI_MessageRole.system,
|
|
266
|
+
content: settings?.systemPrompt || this.defaultSystemPrompt,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
protected validateConversation(conversation: DyFM_AI_Message[]): void {
|
|
271
|
+
conversation.forEach((message: DyFM_AI_Message, index: number) => {
|
|
272
|
+
if (!message.role) {
|
|
273
|
+
throw new DyFM_Error({
|
|
274
|
+
message: `Message has no role at index ${index}`,
|
|
275
|
+
additionalContent: {
|
|
276
|
+
invalidMessage: message,
|
|
277
|
+
conversation: conversation,
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (!message.content) {
|
|
283
|
+
throw new DyFM_Error({
|
|
284
|
+
message: `Message has no content at index ${index}`,
|
|
285
|
+
additionalContent: {
|
|
286
|
+
invalidMessage: message,
|
|
287
|
+
conversation: conversation,
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
protected logAnswer(answer: string): void {
|
|
295
|
+
if (this._debugLog) {
|
|
296
|
+
console.log(' - answer: ', answer);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
|
303
|
+
// LLM CHAT METHODS //
|
|
304
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
protected logConversation(
|
|
308
|
+
set: {
|
|
309
|
+
conversation: DyFM_AI_Message[],
|
|
310
|
+
debugLog?: boolean,
|
|
311
|
+
/** this is used to readably replace too long contents to eg '...' in logs */
|
|
312
|
+
replaceThisInLog?: string,
|
|
313
|
+
}
|
|
314
|
+
) {
|
|
315
|
+
if (set.debugLog || this._debugLog) {
|
|
316
|
+
DyFM_Log.info('Conversation log at', DyFM_getLocalStackLocation());
|
|
317
|
+
|
|
318
|
+
set.conversation.forEach(message => {
|
|
319
|
+
console.log(
|
|
320
|
+
` - ${message.role}: ${message.content.replace(set.replaceThisInLog, this.defaultLogReplacer)}`
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
81
325
|
}
|
|
@@ -18,7 +18,7 @@ export abstract class DyNTS_AI_Provider_ServiceBase extends DyNTS_SingletonServi
|
|
|
18
18
|
* Initialize the provider with configuration
|
|
19
19
|
* @param config - Provider-specific configuration
|
|
20
20
|
*/
|
|
21
|
-
abstract
|
|
21
|
+
abstract setup(config: DyFM_AI_Config): void;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Test the connection to the AI provider
|
|
@@ -44,12 +44,12 @@ export abstract class DyNTS_Ass_IO_ControlService extends DyNTS_Bot_IO_ControlSe
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
// Get AI response using EXISTING getAnswerInConversation method
|
|
47
|
-
const aiResult: string = await this.aiProvider.
|
|
47
|
+
const aiResult: string = await this.aiProvider.requestSimpleMessageInConversation({
|
|
48
48
|
conversation: aiMessages,
|
|
49
|
-
issuer: issuer,
|
|
50
49
|
settings: {
|
|
51
50
|
systemPrompt: this.mainBot_CS.defaultSystemPrompt,
|
|
52
51
|
},
|
|
52
|
+
issuer: issuer,
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// Reply via same provider the message came from
|
|
@@ -1,25 +1,51 @@
|
|
|
1
1
|
import { DyNTS_Bot_MessagingProvider_ServiceBase } from '../_services/bot-messaging-provider.service-base';
|
|
2
|
+
import { DyNTS_Bot_MessageWrapper } from './bot-message-wrapper.interface';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Wraps a bot channel with provider context
|
|
5
6
|
* This ensures channels include the provider information needed for platform-specific operations
|
|
6
7
|
*/
|
|
7
|
-
export
|
|
8
|
-
T_MessagingPlatformChannel extends any = any
|
|
8
|
+
export class DyNTS_Bot_ChannelWrapper<
|
|
9
|
+
T_MessagingPlatformChannel extends any = any,
|
|
10
|
+
T_MessagingPlatformMessage extends any = any,
|
|
9
11
|
> {
|
|
10
12
|
id: string;
|
|
11
13
|
name: string;
|
|
12
14
|
isTextBased: boolean;
|
|
13
15
|
isDM: boolean;
|
|
14
|
-
|
|
16
|
+
|
|
15
17
|
rawPlatformChannel: T_MessagingPlatformChannel;
|
|
16
18
|
|
|
17
19
|
/** Reference to the provider instance for platform-specific operations */
|
|
18
20
|
provider: DyNTS_Bot_MessagingProvider_ServiceBase<
|
|
19
21
|
T_MessagingPlatformChannel,
|
|
20
|
-
|
|
22
|
+
T_MessagingPlatformMessage, //DyNTS_Bot_MessageWrapper<any>,
|
|
21
23
|
any, //DyNTS_Bot_UserWrapper<any>,
|
|
22
24
|
any
|
|
23
25
|
>;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
set: Partial<DyNTS_Bot_ChannelWrapper<T_MessagingPlatformChannel, T_MessagingPlatformMessage>>
|
|
29
|
+
) {
|
|
30
|
+
Object.assign(this, set);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async sendMessage(content: string, issuer: string): Promise<DyNTS_Bot_MessageWrapper<T_MessagingPlatformMessage>> {
|
|
34
|
+
return await this.provider.sendMessageToChannel(this, content, issuer);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async sendTyping(): Promise<void> {
|
|
38
|
+
await this.provider.sendTyping(this);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async fetchMessages(limit: number): Promise<DyNTS_Bot_MessageWrapper<T_MessagingPlatformMessage>[]> {
|
|
42
|
+
return await this.provider.fetchMessages(this, limit);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* async fetchAllMessagesWi */
|
|
46
|
+
|
|
47
|
+
async clear(): Promise<void> {
|
|
48
|
+
await this.provider.clearChannel(this);
|
|
49
|
+
}
|
|
24
50
|
}
|
|
25
51
|
|
|
@@ -5,7 +5,7 @@ import { DyNTS_Bot_MessagingProvider_ServiceBase } from '../_services/bot-messag
|
|
|
5
5
|
* This ensures messages include the provider information needed to send replies
|
|
6
6
|
* back through the correct platform
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export class DyNTS_Bot_MessageWrapper<
|
|
9
9
|
T_MessagingPlatformMessage extends any = any,
|
|
10
10
|
> {
|
|
11
11
|
id: string;
|
|
@@ -20,7 +20,7 @@ export interface DyNTS_Bot_MessageWrapper<
|
|
|
20
20
|
replyToMessageId?: string;
|
|
21
21
|
mentions: string[]; // user IDs
|
|
22
22
|
issuer: string;
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
rawPlatformMessage: T_MessagingPlatformMessage; // Original platform message for platform-specific operations
|
|
25
25
|
|
|
26
26
|
/** Reference to the provider instance for sending replies */
|
|
@@ -30,5 +30,27 @@ export interface DyNTS_Bot_MessageWrapper<
|
|
|
30
30
|
any, //DyNTS_Bot_ChannelWrapper<any>,
|
|
31
31
|
any //DyNTS_Bot_UserWrapper<any>
|
|
32
32
|
>;
|
|
33
|
+
|
|
34
|
+
constructor(
|
|
35
|
+
set: Partial<DyNTS_Bot_MessageWrapper<T_MessagingPlatformMessage>>
|
|
36
|
+
) {
|
|
37
|
+
Object.assign(this, set);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async reply(content: string): Promise<DyNTS_Bot_MessageWrapper<T_MessagingPlatformMessage>> {
|
|
41
|
+
return await this.provider.replyToMessage(this, content);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async sendTyping(): Promise<void> {
|
|
45
|
+
await this.provider.sendTypingForMessage(this);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async fetchMessages(limit: number): Promise<DyNTS_Bot_MessageWrapper<T_MessagingPlatformMessage>[]> {
|
|
49
|
+
return await this.provider.fetchMessagesForMessage(this, limit);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async delete(): Promise<void> {
|
|
53
|
+
await this.provider.deleteMessage(this);
|
|
54
|
+
}
|
|
33
55
|
}
|
|
34
56
|
|
|
@@ -4,7 +4,7 @@ import { DyNTS_Bot_MessagingProvider_ServiceBase } from '../_services/bot-messag
|
|
|
4
4
|
* Wraps a bot user with provider context
|
|
5
5
|
* This ensures users include the provider information needed for platform-specific operations
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export class DyNTS_Bot_UserWrapper<
|
|
8
8
|
T_MessagingPlatformUser extends any = any,
|
|
9
9
|
/* T_MessagingPlatformService extends DyNTS_Bot_MessagingProvider_ServiceBase<
|
|
10
10
|
any, //DyNTS_Bot_ChannelWrapper<any> ,
|
|
@@ -23,7 +23,7 @@ export interface DyNTS_Bot_UserWrapper<
|
|
|
23
23
|
username: string;
|
|
24
24
|
displayName: string;
|
|
25
25
|
isBot: boolean;
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
rawPlatformUser: T_MessagingPlatformUser;
|
|
28
28
|
|
|
29
29
|
/** Reference to the provider instance for platform-specific operations */
|
|
@@ -32,5 +32,11 @@ export interface DyNTS_Bot_UserWrapper<
|
|
|
32
32
|
any, //DyNTS_Bot_MessageWrapper<any> ,
|
|
33
33
|
T_MessagingPlatformUser
|
|
34
34
|
>;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
set: Partial<DyNTS_Bot_UserWrapper<T_MessagingPlatformUser>>
|
|
38
|
+
) {
|
|
39
|
+
Object.assign(this, set);
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
|
package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.ts
CHANGED
|
@@ -486,7 +486,7 @@ export class DyNTS_DiB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
486
486
|
}
|
|
487
487
|
|
|
488
488
|
wrapMessage(message: Message): DyNTS_DiB_Message {
|
|
489
|
-
return {
|
|
489
|
+
return new DyNTS_Bot_MessageWrapper<Message>({
|
|
490
490
|
id: message.id,
|
|
491
491
|
content: message.content,
|
|
492
492
|
authorId: message.author.id,
|
|
@@ -503,11 +503,11 @@ export class DyNTS_DiB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
503
503
|
issuer: message.author.id,
|
|
504
504
|
|
|
505
505
|
provider: this,
|
|
506
|
-
};
|
|
506
|
+
});
|
|
507
507
|
}
|
|
508
508
|
|
|
509
509
|
wrapChannel(channel: Channel): DyNTS_DiB_Channel {
|
|
510
|
-
return {
|
|
510
|
+
return new DyNTS_Bot_ChannelWrapper<Channel>({
|
|
511
511
|
id: channel.id,
|
|
512
512
|
name: (channel as TextChannel).name || ('DM Channel with ' + (channel as DMChannel).recipient.username),
|
|
513
513
|
isTextBased: channel.isTextBased(),
|
|
@@ -515,11 +515,11 @@ export class DyNTS_DiB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
515
515
|
rawPlatformChannel: channel,
|
|
516
516
|
|
|
517
517
|
provider: this,
|
|
518
|
-
};
|
|
518
|
+
});
|
|
519
519
|
}
|
|
520
520
|
|
|
521
521
|
wrapUser(user: GuildMember): DyNTS_DiB_User {
|
|
522
|
-
return {
|
|
522
|
+
return new DyNTS_Bot_UserWrapper<GuildMember>({
|
|
523
523
|
id: user.user.id,
|
|
524
524
|
username: user.user.username,
|
|
525
525
|
displayName: user.displayName,
|
|
@@ -527,6 +527,6 @@ export class DyNTS_DiB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
527
527
|
rawPlatformUser: user,
|
|
528
528
|
|
|
529
529
|
provider: this,
|
|
530
|
-
};
|
|
530
|
+
});
|
|
531
531
|
}
|
|
532
532
|
}
|
package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts
CHANGED
|
@@ -386,7 +386,7 @@ export class DyNTS_DyB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
wrapMessage(msgMessage: any): DyNTS_Bot_MessageWrapper<DyFM_Msg_Message> {
|
|
389
|
-
return {
|
|
389
|
+
return new DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>({
|
|
390
390
|
id: msgMessage._id || msgMessage.id,
|
|
391
391
|
content: msgMessage.content || '',
|
|
392
392
|
authorId: msgMessage.senderId || msgMessage.authorId,
|
|
@@ -403,28 +403,28 @@ export class DyNTS_DyB_MessagingProvider_ControlService extends DyNTS_Bot_Messag
|
|
|
403
403
|
issuer: msgMessage.issuer || 'unknown',
|
|
404
404
|
|
|
405
405
|
provider: this,
|
|
406
|
-
};
|
|
406
|
+
});
|
|
407
407
|
}
|
|
408
408
|
|
|
409
409
|
wrapChannel(conversation: any): DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> {
|
|
410
|
-
return {
|
|
410
|
+
return new DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>({
|
|
411
411
|
id: conversation._id || conversation.id,
|
|
412
412
|
name: conversation.name || conversation.platformChannelId || 'unknown',
|
|
413
413
|
isTextBased: true,
|
|
414
414
|
isDM: conversation.type === 'direct',
|
|
415
415
|
rawPlatformChannel: conversation,
|
|
416
416
|
provider: this
|
|
417
|
-
};
|
|
417
|
+
});
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
wrapUser(user: any): DyNTS_Bot_UserWrapper<DyFM_Msg_Participant> {
|
|
421
|
-
return {
|
|
421
|
+
return new DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>({
|
|
422
422
|
id: user.userId || user.id,
|
|
423
423
|
username: user.username || user.userId || user.id,
|
|
424
424
|
displayName: user.displayName || user.username || user.userId,
|
|
425
425
|
isBot: user.isBot || false,
|
|
426
426
|
rawPlatformUser: user,
|
|
427
427
|
provider: this
|
|
428
|
-
};
|
|
428
|
+
});
|
|
429
429
|
}
|
|
430
430
|
}
|