@hazeljs/messaging 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/README.md +190 -0
- package/dist/adapters/slack.adapter.d.ts +20 -0
- package/dist/adapters/slack.adapter.d.ts.map +1 -0
- package/dist/adapters/slack.adapter.js +28 -0
- package/dist/adapters/slack.adapter.js.map +1 -0
- package/dist/adapters/slack.adapter.test.d.ts +2 -0
- package/dist/adapters/slack.adapter.test.d.ts.map +1 -0
- package/dist/adapters/slack.adapter.test.js +56 -0
- package/dist/adapters/slack.adapter.test.js.map +1 -0
- package/dist/adapters/teams.adapter.d.ts +20 -0
- package/dist/adapters/teams.adapter.d.ts.map +1 -0
- package/dist/adapters/teams.adapter.js +28 -0
- package/dist/adapters/teams.adapter.js.map +1 -0
- package/dist/adapters/teams.adapter.test.d.ts +2 -0
- package/dist/adapters/teams.adapter.test.d.ts.map +1 -0
- package/dist/adapters/teams.adapter.test.js +56 -0
- package/dist/adapters/teams.adapter.test.js.map +1 -0
- package/dist/adapters/telegram.adapter.d.ts +24 -0
- package/dist/adapters/telegram.adapter.d.ts.map +1 -0
- package/dist/adapters/telegram.adapter.js +70 -0
- package/dist/adapters/telegram.adapter.js.map +1 -0
- package/dist/adapters/telegram.adapter.test.d.ts +2 -0
- package/dist/adapters/telegram.adapter.test.d.ts.map +1 -0
- package/dist/adapters/telegram.adapter.test.js +154 -0
- package/dist/adapters/telegram.adapter.test.js.map +1 -0
- package/dist/adapters/viber.adapter.d.ts +29 -0
- package/dist/adapters/viber.adapter.d.ts.map +1 -0
- package/dist/adapters/viber.adapter.js +98 -0
- package/dist/adapters/viber.adapter.js.map +1 -0
- package/dist/adapters/viber.adapter.test.d.ts +2 -0
- package/dist/adapters/viber.adapter.test.d.ts.map +1 -0
- package/dist/adapters/viber.adapter.test.js +89 -0
- package/dist/adapters/viber.adapter.test.js.map +1 -0
- package/dist/adapters/whatsapp.adapter.d.ts +26 -0
- package/dist/adapters/whatsapp.adapter.d.ts.map +1 -0
- package/dist/adapters/whatsapp.adapter.js +87 -0
- package/dist/adapters/whatsapp.adapter.js.map +1 -0
- package/dist/adapters/whatsapp.adapter.test.d.ts +2 -0
- package/dist/adapters/whatsapp.adapter.test.d.ts.map +1 -0
- package/dist/adapters/whatsapp.adapter.test.js +198 -0
- package/dist/adapters/whatsapp.adapter.test.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/messaging-kafka.bootstrap.d.ts +14 -0
- package/dist/messaging-kafka.bootstrap.d.ts.map +1 -0
- package/dist/messaging-kafka.bootstrap.js +42 -0
- package/dist/messaging-kafka.bootstrap.js.map +1 -0
- package/dist/messaging-kafka.bootstrap.test.d.ts +2 -0
- package/dist/messaging-kafka.bootstrap.test.d.ts.map +1 -0
- package/dist/messaging-kafka.bootstrap.test.js +34 -0
- package/dist/messaging-kafka.bootstrap.test.js.map +1 -0
- package/dist/messaging-kafka.consumer.d.ts +10 -0
- package/dist/messaging-kafka.consumer.d.ts.map +1 -0
- package/dist/messaging-kafka.consumer.js +80 -0
- package/dist/messaging-kafka.consumer.js.map +1 -0
- package/dist/messaging-kafka.consumer.test.d.ts +2 -0
- package/dist/messaging-kafka.consumer.test.d.ts.map +1 -0
- package/dist/messaging-kafka.consumer.test.js +129 -0
- package/dist/messaging-kafka.consumer.test.js.map +1 -0
- package/dist/messaging-kafka.types.d.ts +10 -0
- package/dist/messaging-kafka.types.d.ts.map +1 -0
- package/dist/messaging-kafka.types.js +5 -0
- package/dist/messaging-kafka.types.js.map +1 -0
- package/dist/messaging-kafka.types.test.d.ts +2 -0
- package/dist/messaging-kafka.types.test.d.ts.map +1 -0
- package/dist/messaging-kafka.types.test.js +12 -0
- package/dist/messaging-kafka.types.test.js.map +1 -0
- package/dist/messaging.controller.d.ts +27 -0
- package/dist/messaging.controller.d.ts.map +1 -0
- package/dist/messaging.controller.js +151 -0
- package/dist/messaging.controller.js.map +1 -0
- package/dist/messaging.controller.test.d.ts +2 -0
- package/dist/messaging.controller.test.d.ts.map +1 -0
- package/dist/messaging.controller.test.js +221 -0
- package/dist/messaging.controller.test.js.map +1 -0
- package/dist/messaging.module.d.ts +75 -0
- package/dist/messaging.module.d.ts.map +1 -0
- package/dist/messaging.module.js +160 -0
- package/dist/messaging.module.js.map +1 -0
- package/dist/messaging.module.test.d.ts +2 -0
- package/dist/messaging.module.test.d.ts.map +1 -0
- package/dist/messaging.module.test.js +147 -0
- package/dist/messaging.module.test.js.map +1 -0
- package/dist/messaging.service.d.ts +42 -0
- package/dist/messaging.service.d.ts.map +1 -0
- package/dist/messaging.service.js +109 -0
- package/dist/messaging.service.js.map +1 -0
- package/dist/messaging.service.test.d.ts +2 -0
- package/dist/messaging.service.test.d.ts.map +1 -0
- package/dist/messaging.service.test.js +163 -0
- package/dist/messaging.service.test.js.map +1 -0
- package/dist/store/conversation-context.interface.d.ts +17 -0
- package/dist/store/conversation-context.interface.d.ts.map +1 -0
- package/dist/store/conversation-context.interface.js +7 -0
- package/dist/store/conversation-context.interface.js.map +1 -0
- package/dist/store/memory-conversation-context.d.ts +11 -0
- package/dist/store/memory-conversation-context.d.ts.map +1 -0
- package/dist/store/memory-conversation-context.js +22 -0
- package/dist/store/memory-conversation-context.js.map +1 -0
- package/dist/store/memory-conversation-context.test.d.ts +2 -0
- package/dist/store/memory-conversation-context.test.d.ts.map +1 -0
- package/dist/store/memory-conversation-context.test.js +69 -0
- package/dist/store/memory-conversation-context.test.js.map +1 -0
- package/dist/store/redis-conversation-context.d.ts +24 -0
- package/dist/store/redis-conversation-context.d.ts.map +1 -0
- package/dist/store/redis-conversation-context.js +37 -0
- package/dist/store/redis-conversation-context.js.map +1 -0
- package/dist/store/redis-conversation-context.test.d.ts +2 -0
- package/dist/store/redis-conversation-context.test.d.ts.map +1 -0
- package/dist/store/redis-conversation-context.test.js +85 -0
- package/dist/store/redis-conversation-context.test.js.map +1 -0
- package/dist/types/message.types.d.ts +55 -0
- package/dist/types/message.types.d.ts.map +1 -0
- package/dist/types/message.types.js +7 -0
- package/dist/types/message.types.js.map +1 -0
- package/dist/types/response-handler.types.d.ts +47 -0
- package/dist/types/response-handler.types.d.ts.map +1 -0
- package/dist/types/response-handler.types.js +3 -0
- package/dist/types/response-handler.types.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var MessagingModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MessagingModule = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Messaging Module - Multichannel bot with LLM integration
|
|
13
|
+
* Supports Kafka (async, horizontally scalable) and Redis (context store)
|
|
14
|
+
*/
|
|
15
|
+
const core_1 = require("@hazeljs/core");
|
|
16
|
+
const messaging_service_1 = require("./messaging.service");
|
|
17
|
+
const messaging_controller_1 = require("./messaging.controller");
|
|
18
|
+
const telegram_adapter_1 = require("./adapters/telegram.adapter");
|
|
19
|
+
const whatsapp_adapter_1 = require("./adapters/whatsapp.adapter");
|
|
20
|
+
const viber_adapter_1 = require("./adapters/viber.adapter");
|
|
21
|
+
const slack_adapter_1 = require("./adapters/slack.adapter");
|
|
22
|
+
const teams_adapter_1 = require("./adapters/teams.adapter");
|
|
23
|
+
const redis_conversation_context_1 = require("./store/redis-conversation-context");
|
|
24
|
+
const memory_conversation_context_1 = require("./store/memory-conversation-context");
|
|
25
|
+
let MessagingModule = MessagingModule_1 = class MessagingModule {
|
|
26
|
+
/**
|
|
27
|
+
* Configure MessagingModule with channels and AI.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { MessagingModule } from '@hazeljs/messaging';
|
|
32
|
+
* import { OpenAIProvider } from '@hazeljs/ai';
|
|
33
|
+
*
|
|
34
|
+
* imports: [
|
|
35
|
+
* MessagingModule.forRoot({
|
|
36
|
+
* aiProvider: new OpenAIProvider(),
|
|
37
|
+
* systemPrompt: 'You are a helpful support bot.',
|
|
38
|
+
* channels: {
|
|
39
|
+
* telegram: { botToken: process.env.TELEGRAM_BOT_TOKEN! },
|
|
40
|
+
* whatsapp: {
|
|
41
|
+
* accessToken: process.env.WHATSAPP_ACCESS_TOKEN!,
|
|
42
|
+
* phoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,
|
|
43
|
+
* },
|
|
44
|
+
* },
|
|
45
|
+
* }),
|
|
46
|
+
* ]
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
static forRoot(options = {}) {
|
|
50
|
+
MessagingModule_1.options = options;
|
|
51
|
+
const channels = options.channels ?? {};
|
|
52
|
+
const adapters = [];
|
|
53
|
+
const imports = [];
|
|
54
|
+
if (channels.telegram?.botToken) {
|
|
55
|
+
adapters.push(new telegram_adapter_1.TelegramAdapter({ botToken: channels.telegram.botToken }));
|
|
56
|
+
}
|
|
57
|
+
if (channels.whatsapp?.accessToken) {
|
|
58
|
+
adapters.push(new whatsapp_adapter_1.WhatsAppAdapter({
|
|
59
|
+
accessToken: channels.whatsapp.accessToken,
|
|
60
|
+
phoneNumberId: channels.whatsapp.phoneNumberId,
|
|
61
|
+
apiVersion: channels.whatsapp.apiVersion,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
if (channels.viber?.authToken) {
|
|
65
|
+
adapters.push(new viber_adapter_1.ViberAdapter({ authToken: channels.viber.authToken }));
|
|
66
|
+
}
|
|
67
|
+
if (channels.slack?.webhookUrl) {
|
|
68
|
+
adapters.push(new slack_adapter_1.SlackAdapter({ webhookUrl: channels.slack.webhookUrl }));
|
|
69
|
+
}
|
|
70
|
+
if (channels.teams?.webhookUrl) {
|
|
71
|
+
adapters.push(new teams_adapter_1.TeamsAdapter({ webhookUrl: channels.teams.webhookUrl }));
|
|
72
|
+
}
|
|
73
|
+
const useKafka = !!options.kafka;
|
|
74
|
+
let contextStore;
|
|
75
|
+
if (options.redis?.client) {
|
|
76
|
+
contextStore = new redis_conversation_context_1.RedisConversationContextStore({
|
|
77
|
+
client: options.redis.client,
|
|
78
|
+
ttlSeconds: options.redis.ttlSeconds,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else if (options.redis?.host || options.redis?.port) {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- ioredis is optional peer dep
|
|
83
|
+
const Redis = require('ioredis');
|
|
84
|
+
const client = new Redis({
|
|
85
|
+
host: options.redis.host ?? 'localhost',
|
|
86
|
+
port: options.redis.port ?? 6379,
|
|
87
|
+
password: options.redis.password,
|
|
88
|
+
});
|
|
89
|
+
contextStore = new redis_conversation_context_1.RedisConversationContextStore({
|
|
90
|
+
client,
|
|
91
|
+
ttlSeconds: options.redis.ttlSeconds,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
contextStore = new memory_conversation_context_1.MemoryConversationContextStore();
|
|
96
|
+
}
|
|
97
|
+
const providers = [
|
|
98
|
+
{
|
|
99
|
+
provide: messaging_service_1.MessagingService,
|
|
100
|
+
useFactory: () => new messaging_service_1.MessagingService({
|
|
101
|
+
aiProvider: options.aiProvider,
|
|
102
|
+
systemPrompt: options.systemPrompt,
|
|
103
|
+
model: options.model,
|
|
104
|
+
temperature: options.temperature,
|
|
105
|
+
maxTokens: options.maxTokens,
|
|
106
|
+
maxContextTurns: options.maxContextTurns,
|
|
107
|
+
customHandler: options.customHandler,
|
|
108
|
+
agentHandler: options.agentHandler,
|
|
109
|
+
ragService: options.ragService,
|
|
110
|
+
ragTopK: options.ragTopK,
|
|
111
|
+
ragMinScore: options.ragMinScore,
|
|
112
|
+
}, contextStore),
|
|
113
|
+
},
|
|
114
|
+
{ provide: messaging_controller_1.MESSAGING_ADAPTERS, useValue: adapters },
|
|
115
|
+
{ provide: messaging_controller_1.MESSAGING_USE_KAFKA, useValue: useKafka },
|
|
116
|
+
...(useKafka
|
|
117
|
+
? [
|
|
118
|
+
{
|
|
119
|
+
provide: messaging_controller_1.MESSAGING_KAFKA_PRODUCER,
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- @hazeljs/kafka is optional
|
|
121
|
+
useExisting: require('@hazeljs/kafka').KafkaProducerService,
|
|
122
|
+
},
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- lazy load when Kafka enabled
|
|
124
|
+
require('./messaging-kafka.consumer').MessagingKafkaConsumer,
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- lazy load when Kafka enabled
|
|
126
|
+
require('./messaging-kafka.bootstrap').MessagingKafkaBootstrap,
|
|
127
|
+
]
|
|
128
|
+
: [{ provide: messaging_controller_1.MESSAGING_KAFKA_PRODUCER, useValue: null }]),
|
|
129
|
+
];
|
|
130
|
+
if (useKafka) {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- @hazeljs/kafka is optional
|
|
132
|
+
const { KafkaModule } = require('@hazeljs/kafka');
|
|
133
|
+
KafkaModule.forRoot({
|
|
134
|
+
clientId: 'messaging',
|
|
135
|
+
brokers: options.kafka?.brokers ?? ['localhost:9092'],
|
|
136
|
+
...options.kafka,
|
|
137
|
+
});
|
|
138
|
+
imports.push(KafkaModule);
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
module: MessagingModule_1,
|
|
142
|
+
imports: imports.length > 0 ? imports : undefined,
|
|
143
|
+
providers,
|
|
144
|
+
controllers: [messaging_controller_1.MessagingController],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
static getOptions() {
|
|
148
|
+
return MessagingModule_1.options;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
exports.MessagingModule = MessagingModule;
|
|
152
|
+
MessagingModule.options = {};
|
|
153
|
+
exports.MessagingModule = MessagingModule = MessagingModule_1 = __decorate([
|
|
154
|
+
(0, core_1.HazelModule)({
|
|
155
|
+
providers: [messaging_service_1.MessagingService],
|
|
156
|
+
controllers: [messaging_controller_1.MessagingController],
|
|
157
|
+
exports: [messaging_service_1.MessagingService],
|
|
158
|
+
})
|
|
159
|
+
], MessagingModule);
|
|
160
|
+
//# sourceMappingURL=messaging.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.module.js","sourceRoot":"","sources":["../src/messaging.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.module.test.d.ts","sourceRoot":"","sources":["../src/messaging.module.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* MessagingModule tests - tests forRoot without Kafka/Redis to avoid dynamic requires
|
|
5
|
+
*/
|
|
6
|
+
jest.mock('ioredis', () => {
|
|
7
|
+
return jest.fn().mockImplementation(() => ({
|
|
8
|
+
get: jest.fn().mockResolvedValue(null),
|
|
9
|
+
setex: jest.fn().mockResolvedValue('OK'),
|
|
10
|
+
del: jest.fn().mockResolvedValue(0),
|
|
11
|
+
}));
|
|
12
|
+
});
|
|
13
|
+
jest.mock('@hazeljs/kafka', () => ({
|
|
14
|
+
KafkaModule: { forRoot: jest.fn() },
|
|
15
|
+
KafkaProducerService: {},
|
|
16
|
+
KafkaSubscribe: () => () => { },
|
|
17
|
+
KafkaConsumer: () => () => { },
|
|
18
|
+
}));
|
|
19
|
+
const messaging_module_1 = require("./messaging.module");
|
|
20
|
+
const messaging_controller_1 = require("./messaging.controller");
|
|
21
|
+
const messaging_service_1 = require("./messaging.service");
|
|
22
|
+
describe('MessagingModule', () => {
|
|
23
|
+
describe('forRoot', () => {
|
|
24
|
+
it('returns dynamic module structure', () => {
|
|
25
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
26
|
+
systemPrompt: 'Test bot',
|
|
27
|
+
channels: {
|
|
28
|
+
telegram: { botToken: 'test-token' },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
expect(result).toHaveProperty('module', messaging_module_1.MessagingModule);
|
|
32
|
+
expect(result).toHaveProperty('providers');
|
|
33
|
+
expect(result).toHaveProperty('controllers');
|
|
34
|
+
expect(Array.isArray(result.providers)).toBe(true);
|
|
35
|
+
expect(result.controllers).toContain(messaging_controller_1.MessagingController);
|
|
36
|
+
});
|
|
37
|
+
it('creates adapters for configured channels', () => {
|
|
38
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
39
|
+
channels: {
|
|
40
|
+
telegram: { botToken: 't1' },
|
|
41
|
+
whatsapp: {
|
|
42
|
+
accessToken: 'a1',
|
|
43
|
+
phoneNumberId: 'p1',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const adaptersProvider = result.providers?.find((p) => p &&
|
|
48
|
+
typeof p === 'object' &&
|
|
49
|
+
'useValue' in p &&
|
|
50
|
+
Array.isArray(p.useValue));
|
|
51
|
+
expect(adaptersProvider?.useValue).toHaveLength(2);
|
|
52
|
+
expect(adaptersProvider?.useValue[0].channel).toBe('telegram');
|
|
53
|
+
expect(adaptersProvider?.useValue[1].channel).toBe('whatsapp');
|
|
54
|
+
});
|
|
55
|
+
it('creates viber adapter when viber authToken provided', () => {
|
|
56
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
57
|
+
channels: {
|
|
58
|
+
telegram: { botToken: 't1' },
|
|
59
|
+
viber: { authToken: 'viber-auth' },
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
const adaptersProvider = result.providers?.find((p) => p &&
|
|
63
|
+
typeof p === 'object' &&
|
|
64
|
+
'useValue' in p &&
|
|
65
|
+
Array.isArray(p.useValue));
|
|
66
|
+
expect(adaptersProvider?.useValue).toHaveLength(2);
|
|
67
|
+
const channels = adaptersProvider?.useValue.map((a) => a.channel) ?? [];
|
|
68
|
+
expect(channels).toContain('telegram');
|
|
69
|
+
expect(channels).toContain('viber');
|
|
70
|
+
});
|
|
71
|
+
it('creates MessagingService with useFactory', () => {
|
|
72
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
73
|
+
channels: { telegram: { botToken: 't' } },
|
|
74
|
+
});
|
|
75
|
+
const svcProvider = result.providers?.find((p) => p &&
|
|
76
|
+
typeof p === 'object' &&
|
|
77
|
+
'useFactory' in p &&
|
|
78
|
+
p.provide?.name === 'MessagingService');
|
|
79
|
+
expect(svcProvider?.useFactory).toBeDefined();
|
|
80
|
+
const service = svcProvider?.useFactory?.();
|
|
81
|
+
expect(service).toBeInstanceOf(messaging_service_1.MessagingService);
|
|
82
|
+
});
|
|
83
|
+
it('does not include Kafka when kafka config absent', () => {
|
|
84
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
85
|
+
channels: { telegram: { botToken: 't' } },
|
|
86
|
+
});
|
|
87
|
+
const kafkaProvider = result.providers?.find((p) => p &&
|
|
88
|
+
typeof p === 'object' &&
|
|
89
|
+
'useValue' in p &&
|
|
90
|
+
p.useValue === null);
|
|
91
|
+
expect(kafkaProvider).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
it('uses Redis with host/port when redis.client not provided', () => {
|
|
94
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
95
|
+
channels: { telegram: { botToken: 't' } },
|
|
96
|
+
redis: { host: 'redis.example.com', port: 6380 },
|
|
97
|
+
});
|
|
98
|
+
const svcProvider = result.providers?.find((p) => p &&
|
|
99
|
+
typeof p === 'object' &&
|
|
100
|
+
'useFactory' in p &&
|
|
101
|
+
p.provide?.name === 'MessagingService');
|
|
102
|
+
const service = svcProvider?.useFactory?.();
|
|
103
|
+
expect(service).toBeInstanceOf(messaging_service_1.MessagingService);
|
|
104
|
+
});
|
|
105
|
+
it('includes Kafka providers and imports when kafka config provided', () => {
|
|
106
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
107
|
+
channels: { telegram: { botToken: 't' } },
|
|
108
|
+
kafka: { brokers: ['localhost:9092'] },
|
|
109
|
+
});
|
|
110
|
+
expect(result.imports).toBeDefined();
|
|
111
|
+
expect(Array.isArray(result.imports)).toBe(true);
|
|
112
|
+
expect(result.imports.length).toBeGreaterThan(0);
|
|
113
|
+
});
|
|
114
|
+
it('uses RedisConversationContextStore when redis.client provided', () => {
|
|
115
|
+
const mockRedis = {
|
|
116
|
+
get: jest.fn().mockResolvedValue(null),
|
|
117
|
+
setex: jest.fn().mockResolvedValue('OK'),
|
|
118
|
+
del: jest.fn().mockResolvedValue(0),
|
|
119
|
+
};
|
|
120
|
+
const result = messaging_module_1.MessagingModule.forRoot({
|
|
121
|
+
channels: { telegram: { botToken: 't' } },
|
|
122
|
+
redis: {
|
|
123
|
+
client: mockRedis,
|
|
124
|
+
ttlSeconds: 7200,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const svcProvider = result.providers?.find((p) => p &&
|
|
128
|
+
typeof p === 'object' &&
|
|
129
|
+
'useFactory' in p &&
|
|
130
|
+
p.provide?.name === 'MessagingService');
|
|
131
|
+
const service = svcProvider?.useFactory?.();
|
|
132
|
+
expect(service).toBeInstanceOf(messaging_service_1.MessagingService);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe('getOptions', () => {
|
|
136
|
+
it('returns last forRoot options', () => {
|
|
137
|
+
messaging_module_1.MessagingModule.forRoot({
|
|
138
|
+
systemPrompt: 'Custom',
|
|
139
|
+
model: 'gpt-4',
|
|
140
|
+
});
|
|
141
|
+
const opts = messaging_module_1.MessagingModule.getOptions();
|
|
142
|
+
expect(opts.systemPrompt).toBe('Custom');
|
|
143
|
+
expect(opts.model).toBe('gpt-4');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=messaging.module.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.module.test.js","sourceRoot":"","sources":["../src/messaging.module.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { IncomingMessage } from './types/message.types';
|
|
2
|
+
import type { IAIProvider } from '@hazeljs/ai';
|
|
3
|
+
import type { IConversationContextStore } from './store/conversation-context.interface';
|
|
4
|
+
import type { AgentHandler, IRAGSearch } from './types/response-handler.types';
|
|
5
|
+
export interface MessagingServiceOptions {
|
|
6
|
+
/** AI provider for LLM responses */
|
|
7
|
+
aiProvider?: IAIProvider;
|
|
8
|
+
/** System prompt for the bot */
|
|
9
|
+
systemPrompt?: string;
|
|
10
|
+
/** Model name (provider-specific) */
|
|
11
|
+
model?: string;
|
|
12
|
+
/** Temperature 0-1 */
|
|
13
|
+
temperature?: number;
|
|
14
|
+
/** Max tokens for response */
|
|
15
|
+
maxTokens?: number;
|
|
16
|
+
/** Max conversation turns to keep in context */
|
|
17
|
+
maxContextTurns?: number;
|
|
18
|
+
/** Custom handler - overrides everything when provided */
|
|
19
|
+
customHandler?: (msg: IncomingMessage) => Promise<string> | string;
|
|
20
|
+
/** Agent handler - CSR-style: tools, RAG, external APIs (e.g. csrService.chat) */
|
|
21
|
+
agentHandler?: AgentHandler;
|
|
22
|
+
/** RAG service - augments LLM with knowledge base search (when not using agentHandler) */
|
|
23
|
+
ragService?: IRAGSearch;
|
|
24
|
+
/** Number of RAG docs to retrieve (default: 5) */
|
|
25
|
+
ragTopK?: number;
|
|
26
|
+
/** Min similarity score for RAG results (0-1, default: 0.5) */
|
|
27
|
+
ragMinScore?: number;
|
|
28
|
+
/** Context store - defaults to memory; use Redis for horizontal scaling */
|
|
29
|
+
contextStore?: IConversationContextStore;
|
|
30
|
+
}
|
|
31
|
+
export declare class MessagingService {
|
|
32
|
+
private options;
|
|
33
|
+
private store;
|
|
34
|
+
constructor(options?: MessagingServiceOptions, contextStore?: IConversationContextStore);
|
|
35
|
+
/** Generate bot response for an incoming message */
|
|
36
|
+
handleMessage(message: IncomingMessage): Promise<string>;
|
|
37
|
+
/** Clear conversation history for a session */
|
|
38
|
+
clearSession(sessionId: string): Promise<void>;
|
|
39
|
+
/** Get current options */
|
|
40
|
+
getOptions(): MessagingServiceOptions;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=messaging.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.service.d.ts","sourceRoot":"","sources":["../src/messaging.service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAExF,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAQ/E,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACnE,kFAAkF;IAClF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,0FAA0F;IAC1F,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,yBAAyB,CAAC;CAC1C;AAED,qBACa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CASX;IAEJ,OAAO,CAAC,KAAK,CAA4B;gBAE7B,OAAO,GAAE,uBAA4B,EAAE,YAAY,CAAC,EAAE,yBAAyB;IAc3F,oDAAoD;IAC9C,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IA8F9D,+CAA+C;IACzC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,0BAA0B;IAC1B,UAAU,IAAI,uBAAuB;CAGtC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MessagingService = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Messaging Service - LLM/Agent-powered bot response generation
|
|
15
|
+
* Uses IConversationContextStore (memory or Redis) for horizontally scalable context
|
|
16
|
+
* Supports: plain LLM, RAG-augmented, Agent (tools + RAG like CSR), custom handler
|
|
17
|
+
*/
|
|
18
|
+
const core_1 = require("@hazeljs/core");
|
|
19
|
+
const memory_conversation_context_1 = require("./store/memory-conversation-context");
|
|
20
|
+
const DEFAULT_SYSTEM_PROMPT = `You are a helpful, friendly assistant in a messaging app.
|
|
21
|
+
Keep responses concise and conversational. Adapt your tone to be natural for chat.`;
|
|
22
|
+
const RAG_CONTEXT_PREFIX = `Use the following context from the knowledge base to answer.
|
|
23
|
+
If the context doesn't contain relevant information, say so. Cite sources when helpful.\n\n---\n`;
|
|
24
|
+
let MessagingService = class MessagingService {
|
|
25
|
+
constructor(options = {}, contextStore) {
|
|
26
|
+
this.options = {
|
|
27
|
+
systemPrompt: DEFAULT_SYSTEM_PROMPT,
|
|
28
|
+
model: 'gpt-4o-mini',
|
|
29
|
+
temperature: 0.7,
|
|
30
|
+
maxTokens: 500,
|
|
31
|
+
maxContextTurns: 10,
|
|
32
|
+
ragTopK: 5,
|
|
33
|
+
ragMinScore: 0.5,
|
|
34
|
+
...options,
|
|
35
|
+
};
|
|
36
|
+
this.store = contextStore ?? options.contextStore ?? new memory_conversation_context_1.MemoryConversationContextStore();
|
|
37
|
+
}
|
|
38
|
+
/** Generate bot response for an incoming message */
|
|
39
|
+
async handleMessage(message) {
|
|
40
|
+
const store = this.store;
|
|
41
|
+
const sessionId = message.sessionId ?? `default:${message.channel}:${message.userId}`;
|
|
42
|
+
if (this.options.customHandler) {
|
|
43
|
+
const reply = await Promise.resolve(this.options.customHandler(message));
|
|
44
|
+
await store.appendTurn(sessionId, { role: 'user', content: message.text }, this.options.maxContextTurns);
|
|
45
|
+
if (reply) {
|
|
46
|
+
await store.appendTurn(sessionId, { role: 'assistant', content: reply }, this.options.maxContextTurns);
|
|
47
|
+
}
|
|
48
|
+
return reply;
|
|
49
|
+
}
|
|
50
|
+
if (this.options.agentHandler) {
|
|
51
|
+
await store.appendTurn(sessionId, { role: 'user', content: message.text }, this.options.maxContextTurns);
|
|
52
|
+
const turns = await store.getTurns(sessionId);
|
|
53
|
+
const result = await this.options.agentHandler({
|
|
54
|
+
message,
|
|
55
|
+
sessionId,
|
|
56
|
+
conversationTurns: turns,
|
|
57
|
+
});
|
|
58
|
+
const reply = typeof result === 'string' ? result : result.response;
|
|
59
|
+
if (reply) {
|
|
60
|
+
await store.appendTurn(sessionId, { role: 'assistant', content: reply }, this.options.maxContextTurns);
|
|
61
|
+
}
|
|
62
|
+
return reply;
|
|
63
|
+
}
|
|
64
|
+
const provider = this.options.aiProvider;
|
|
65
|
+
if (!provider) {
|
|
66
|
+
throw new Error('MessagingService requires aiProvider, agentHandler, or customHandler. Configure via MessagingModule.forRoot().');
|
|
67
|
+
}
|
|
68
|
+
await store.appendTurn(sessionId, { role: 'user', content: message.text }, this.options.maxContextTurns);
|
|
69
|
+
const turns = await store.getTurns(sessionId);
|
|
70
|
+
let systemPrompt = this.options.systemPrompt;
|
|
71
|
+
if (this.options.ragService) {
|
|
72
|
+
const results = await this.options.ragService.search(message.text, {
|
|
73
|
+
topK: this.options.ragTopK,
|
|
74
|
+
minScore: this.options.ragMinScore,
|
|
75
|
+
});
|
|
76
|
+
if (results.length > 0) {
|
|
77
|
+
const context = results.map((r, i) => `[${i + 1}] ${r.content}`).join('\n\n');
|
|
78
|
+
systemPrompt = `${systemPrompt}\n\n${RAG_CONTEXT_PREFIX}Context:\n${context}\n---\n`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const messages = [
|
|
82
|
+
{ role: 'system', content: systemPrompt },
|
|
83
|
+
...turns.map((t) => ({ role: t.role, content: t.content })),
|
|
84
|
+
];
|
|
85
|
+
const response = await provider.complete({
|
|
86
|
+
messages,
|
|
87
|
+
model: this.options.model,
|
|
88
|
+
temperature: this.options.temperature,
|
|
89
|
+
maxTokens: this.options.maxTokens,
|
|
90
|
+
});
|
|
91
|
+
const reply = response.content?.trim() ?? 'I could not generate a response.';
|
|
92
|
+
await store.appendTurn(sessionId, { role: 'assistant', content: reply }, this.options.maxContextTurns);
|
|
93
|
+
return reply;
|
|
94
|
+
}
|
|
95
|
+
/** Clear conversation history for a session */
|
|
96
|
+
async clearSession(sessionId) {
|
|
97
|
+
await this.store.clearSession(sessionId);
|
|
98
|
+
}
|
|
99
|
+
/** Get current options */
|
|
100
|
+
getOptions() {
|
|
101
|
+
return { ...this.options };
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.MessagingService = MessagingService;
|
|
105
|
+
exports.MessagingService = MessagingService = __decorate([
|
|
106
|
+
(0, core_1.Service)(),
|
|
107
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
108
|
+
], MessagingService);
|
|
109
|
+
//# sourceMappingURL=messaging.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.service.js","sourceRoot":"","sources":["../src/messaging.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging.service.test.d.ts","sourceRoot":"","sources":["../src/messaging.service.test.ts"],"names":[],"mappings":""}
|