@wabot-dev/framework 0.9.17 → 0.9.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/addon/async/in-memory/InMemoryCronJobRepository.js +74 -3
- package/dist/src/addon/async/in-memory/InMemoryJobRepository.js +75 -3
- package/dist/src/addon/async/pg/PgCronJobRepository.js +1 -2
- package/dist/src/addon/async/pg/PgJobRepository.js +1 -2
- package/dist/src/addon/async/pg/PgTransactionAdapter.js +3 -2
- package/dist/src/addon/auth/api-key/PgApiKeyRepository.js +3 -3
- package/dist/src/addon/auth/jwt/PgJwtRefreshTokenRepository.js +1 -1
- package/dist/src/addon/chat-bot/anthropic/AnthropicChatAdapter.js +2 -5
- package/dist/src/addon/chat-bot/deepseek/DeepSeekChatAdapter.js +2 -6
- package/dist/src/addon/chat-bot/google/GoogleChatAdapter.js +2 -5
- package/dist/src/addon/chat-bot/in-memory/InMemoryChatRepository.js +1 -1
- package/dist/src/addon/chat-bot/openia/OpenaiChatAdapter.js +4 -6
- package/dist/src/addon/chat-bot/openrouter/OpenRouterChatAdapter.js +2 -6
- package/dist/src/addon/chat-bot/pg/PgChatMemory.js +2 -2
- package/dist/src/addon/chat-bot/pg/PgChatRepository.js +2 -2
- package/dist/src/addon/chat-controller/telegram/@telegram.js +3 -1
- package/dist/src/addon/chat-controller/telegram/TelegramChannel.js +4 -1
- package/dist/src/addon/chat-controller/telegram/markdownToTelegramHtml.js +45 -0
- package/dist/src/feature/chat-bot/ChatBot.js +22 -3
- package/dist/src/feature/mindset/MindsetOperator.js +87 -27
- package/dist/src/feature/mindset/buildParameterSchema.js +155 -0
- package/dist/src/feature/pg/@pgExtension.js +1 -2
- package/dist/src/feature/repository/MemoryRepositoryAdapter.js +93 -7
- package/dist/src/index.d.ts +47 -8
- package/dist/src/index.js +1 -0
- package/package.json +1 -1
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
2
4
|
import { generate } from 'short-uuid';
|
|
3
5
|
import { singleton } from '../../../core/injection/index.js';
|
|
6
|
+
import { Logger } from '../../../core/logger/Logger.js';
|
|
7
|
+
import '../../../feature/async/AsyncMetadataStore.js';
|
|
8
|
+
import '../../../feature/async/TransactionMetadataStore.js';
|
|
9
|
+
import '../../../feature/async/Async.js';
|
|
10
|
+
import { CronJob } from '../../../feature/async/CronJob.js';
|
|
11
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
12
|
+
import '../../../feature/async/JobRepository.js';
|
|
13
|
+
import '../../../feature/async/JobRunner.js';
|
|
14
|
+
import '../../../feature/async/JobScheduler.js';
|
|
15
|
+
import '../../../feature/async/JobWatchdog.js';
|
|
16
|
+
import '../../../feature/async/CronScheduler.js';
|
|
4
17
|
|
|
18
|
+
const CRON_JOBS_FILE = '.wabot/in-memory/cron-jobs.json';
|
|
19
|
+
const MAX_CRON_JOBS = 32;
|
|
20
|
+
const logger = new Logger('wabot:in-memory-cron-job-repository');
|
|
5
21
|
let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
22
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
6
23
|
items = new Map();
|
|
24
|
+
constructor() {
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
7
27
|
async create(cronJob) {
|
|
8
28
|
if (cronJob.wasCreated())
|
|
9
29
|
throw new Error('CronJob already created');
|
|
@@ -11,6 +31,8 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
11
31
|
cronJob['data'].createdAt = new Date().getTime();
|
|
12
32
|
cronJob.validate();
|
|
13
33
|
this.items.set(cronJob.id, cronJob);
|
|
34
|
+
this.enforceLimit();
|
|
35
|
+
this.persist();
|
|
14
36
|
}
|
|
15
37
|
async findDue(date) {
|
|
16
38
|
const now = (date ?? new Date()).getTime();
|
|
@@ -28,7 +50,8 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
28
50
|
if (!cronJob.wasCreated())
|
|
29
51
|
throw new Error('CronJob was not created');
|
|
30
52
|
cronJob.validate();
|
|
31
|
-
this.
|
|
53
|
+
this.touch(cronJob);
|
|
54
|
+
this.persist();
|
|
32
55
|
}
|
|
33
56
|
async findByName(name) {
|
|
34
57
|
for (const c of this.items.values()) {
|
|
@@ -37,9 +60,57 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
37
60
|
}
|
|
38
61
|
return null;
|
|
39
62
|
}
|
|
63
|
+
touch(item) {
|
|
64
|
+
this.items.delete(item.id);
|
|
65
|
+
this.items.set(item.id, item);
|
|
66
|
+
}
|
|
67
|
+
enforceLimit() {
|
|
68
|
+
while (this.items.size > MAX_CRON_JOBS) {
|
|
69
|
+
const oldestKey = this.items.keys().next().value;
|
|
70
|
+
if (oldestKey === undefined)
|
|
71
|
+
break;
|
|
72
|
+
this.items.delete(oldestKey);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
filePath() {
|
|
76
|
+
return path.resolve(process.cwd(), CRON_JOBS_FILE);
|
|
77
|
+
}
|
|
78
|
+
load() {
|
|
79
|
+
const file = this.filePath();
|
|
80
|
+
if (!fs.existsSync(file))
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
84
|
+
const parsed = JSON.parse(raw);
|
|
85
|
+
if (!Array.isArray(parsed))
|
|
86
|
+
return;
|
|
87
|
+
for (const data of parsed) {
|
|
88
|
+
if (!data?.id)
|
|
89
|
+
continue;
|
|
90
|
+
const cronJob = new CronJob(data);
|
|
91
|
+
this.items.set(cronJob.id, cronJob);
|
|
92
|
+
}
|
|
93
|
+
this.enforceLimit();
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
persist() {
|
|
100
|
+
const file = this.filePath();
|
|
101
|
+
try {
|
|
102
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
103
|
+
const data = [...this.items.values()].map((c) => c['data']);
|
|
104
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
40
110
|
};
|
|
41
111
|
InMemoryCronJobRepository = __decorate([
|
|
42
|
-
singleton()
|
|
112
|
+
singleton(),
|
|
113
|
+
__metadata("design:paramtypes", [])
|
|
43
114
|
], InMemoryCronJobRepository);
|
|
44
115
|
|
|
45
116
|
export { InMemoryCronJobRepository };
|
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
2
4
|
import { generate } from 'short-uuid';
|
|
3
5
|
import { singleton } from '../../../core/injection/index.js';
|
|
6
|
+
import { Logger } from '../../../core/logger/Logger.js';
|
|
7
|
+
import '../../../feature/async/AsyncMetadataStore.js';
|
|
8
|
+
import '../../../feature/async/TransactionMetadataStore.js';
|
|
9
|
+
import '../../../feature/async/Async.js';
|
|
10
|
+
import '../../../_virtual/index.js';
|
|
11
|
+
import { Job } from '../../../feature/async/Job.js';
|
|
12
|
+
import '../../../feature/async/JobRepository.js';
|
|
13
|
+
import '../../../feature/async/JobRunner.js';
|
|
14
|
+
import '../../../feature/async/JobScheduler.js';
|
|
15
|
+
import '../../../feature/async/JobWatchdog.js';
|
|
16
|
+
import '../../../feature/async/CronScheduler.js';
|
|
4
17
|
|
|
18
|
+
const JOBS_FILE = '.wabot/in-memory/jobs.json';
|
|
19
|
+
const MAX_JOBS = 32;
|
|
20
|
+
const logger = new Logger('wabot:in-memory-job-repository');
|
|
5
21
|
let InMemoryJobRepository = class InMemoryJobRepository {
|
|
22
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
6
23
|
items = new Map();
|
|
24
|
+
constructor() {
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
7
27
|
async find(id) {
|
|
8
28
|
return this.items.get(id) ?? null;
|
|
9
29
|
}
|
|
@@ -26,15 +46,19 @@ let InMemoryJobRepository = class InMemoryJobRepository {
|
|
|
26
46
|
item['data'].createdAt = new Date().getTime();
|
|
27
47
|
item.validate();
|
|
28
48
|
this.items.set(item.id, item);
|
|
49
|
+
this.enforceLimit();
|
|
50
|
+
this.persist();
|
|
29
51
|
}
|
|
30
52
|
async update(item) {
|
|
31
53
|
if (!item.wasCreated())
|
|
32
54
|
throw new Error('Job was not created');
|
|
33
55
|
item.validate();
|
|
34
|
-
this.
|
|
56
|
+
this.touch(item);
|
|
57
|
+
this.persist();
|
|
35
58
|
}
|
|
36
59
|
async delete(item) {
|
|
37
60
|
this.items.delete(item.id);
|
|
61
|
+
this.persist();
|
|
38
62
|
}
|
|
39
63
|
async findPendingForRunFrom(date, limit) {
|
|
40
64
|
const now = date.getTime();
|
|
@@ -67,9 +91,57 @@ let InMemoryJobRepository = class InMemoryJobRepository {
|
|
|
67
91
|
}
|
|
68
92
|
return count;
|
|
69
93
|
}
|
|
94
|
+
touch(item) {
|
|
95
|
+
this.items.delete(item.id);
|
|
96
|
+
this.items.set(item.id, item);
|
|
97
|
+
}
|
|
98
|
+
enforceLimit() {
|
|
99
|
+
while (this.items.size > MAX_JOBS) {
|
|
100
|
+
const oldestKey = this.items.keys().next().value;
|
|
101
|
+
if (oldestKey === undefined)
|
|
102
|
+
break;
|
|
103
|
+
this.items.delete(oldestKey);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
filePath() {
|
|
107
|
+
return path.resolve(process.cwd(), JOBS_FILE);
|
|
108
|
+
}
|
|
109
|
+
load() {
|
|
110
|
+
const file = this.filePath();
|
|
111
|
+
if (!fs.existsSync(file))
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
115
|
+
const parsed = JSON.parse(raw);
|
|
116
|
+
if (!Array.isArray(parsed))
|
|
117
|
+
return;
|
|
118
|
+
for (const data of parsed) {
|
|
119
|
+
if (!data?.id)
|
|
120
|
+
continue;
|
|
121
|
+
const job = new Job(data);
|
|
122
|
+
this.items.set(job.id, job);
|
|
123
|
+
}
|
|
124
|
+
this.enforceLimit();
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
persist() {
|
|
131
|
+
const file = this.filePath();
|
|
132
|
+
try {
|
|
133
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
134
|
+
const data = [...this.items.values()].map((j) => j['data']);
|
|
135
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
70
141
|
};
|
|
71
142
|
InMemoryJobRepository = __decorate([
|
|
72
|
-
singleton()
|
|
143
|
+
singleton(),
|
|
144
|
+
__metadata("design:paramtypes", [])
|
|
73
145
|
], InMemoryJobRepository);
|
|
74
146
|
|
|
75
147
|
export { InMemoryJobRepository };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
3
|
import { CronJob } from '../../../feature/async/CronJob.js';
|
|
4
|
-
import '
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
4
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
5
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
7
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
3
|
import { singleton } from '../../../core/injection/index.js';
|
|
4
|
-
import '
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
4
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
5
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
7
|
import { withPgClient } from '../../../feature/pg/withPgClient.js';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import '../../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import { withPgClient } from '../../../feature/pg/withPgClient.js';
|
|
7
6
|
import 'debug';
|
|
8
7
|
import '../../../feature/pg/PgLocker.js';
|
|
8
|
+
import 'short-uuid';
|
|
9
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
9
10
|
import 'node:crypto';
|
|
10
11
|
import '../../../feature/pg/pgStorage.js';
|
|
11
12
|
import { withPgTransaction } from '../../../feature/pg/withPgTransaction.js';
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
|
-
import '
|
|
4
|
-
import { CustomError } from '../../../core/error/CustomError.js';
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
3
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
4
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
5
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
6
|
import '../../../feature/pg/withPgClient.js';
|
|
9
7
|
import 'debug';
|
|
8
|
+
import { CustomError } from '../../../core/error/CustomError.js';
|
|
10
9
|
import '../../../feature/pg/PgLocker.js';
|
|
11
10
|
import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
|
|
12
11
|
import 'node:crypto';
|
|
13
12
|
import '../../../feature/pg/pgStorage.js';
|
|
14
13
|
import { Pool } from 'pg';
|
|
15
14
|
import { ApiKey } from './ApiKey.js';
|
|
15
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
16
16
|
|
|
17
17
|
let PgApiKeyRepository = class PgApiKeyRepository extends PgCrudRepository {
|
|
18
18
|
constructor(pool) {
|
|
@@ -2,7 +2,7 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
3
|
import { CustomError } from '../../../core/error/CustomError.js';
|
|
4
4
|
import '../../../core/error/setupErrorHandlers.js';
|
|
5
|
-
import '
|
|
5
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
6
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
7
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
8
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -167,11 +167,8 @@ let AnthropicChatAdapter = class AnthropicChatAdapter {
|
|
|
167
167
|
description: tool.description,
|
|
168
168
|
input_schema: {
|
|
169
169
|
type: 'object',
|
|
170
|
-
properties: tool.parameters.reduce((prev, param) => ({
|
|
171
|
-
|
|
172
|
-
[param.name]: { type: param.type, description: param.description },
|
|
173
|
-
}), {}),
|
|
174
|
-
required: tool.parameters.map((param) => param.name),
|
|
170
|
+
properties: tool.parameters.reduce((prev, param) => ({ ...prev, [param.name]: param.schema }), {}),
|
|
171
|
+
required: tool.parameters.filter((p) => p.required).map((p) => p.name),
|
|
175
172
|
},
|
|
176
173
|
};
|
|
177
174
|
}
|
|
@@ -122,14 +122,10 @@ let DeepSeekChatAdapter = class DeepSeekChatAdapter {
|
|
|
122
122
|
description: tool.description,
|
|
123
123
|
parameters: {
|
|
124
124
|
type: 'object',
|
|
125
|
-
properties: tool.parameters.reduce((prev, param) => ({
|
|
126
|
-
|
|
127
|
-
[param.name]: { type: param.type, description: param.description },
|
|
128
|
-
}), {}),
|
|
129
|
-
required: tool.parameters.map((param) => param.name),
|
|
125
|
+
properties: tool.parameters.reduce((prev, param) => ({ ...prev, [param.name]: param.schema }), {}),
|
|
126
|
+
required: tool.parameters.filter((p) => p.required).map((p) => p.name),
|
|
130
127
|
additionalProperties: false,
|
|
131
128
|
},
|
|
132
|
-
strict: true,
|
|
133
129
|
},
|
|
134
130
|
};
|
|
135
131
|
}
|
|
@@ -169,11 +169,8 @@ let GoogleChatAdapter = class GoogleChatAdapter {
|
|
|
169
169
|
description: tool.description,
|
|
170
170
|
parametersJsonSchema: {
|
|
171
171
|
type: 'object',
|
|
172
|
-
properties: tool.parameters.reduce((prev, param) => ({
|
|
173
|
-
|
|
174
|
-
[param.name]: { type: param.type, description: param.description },
|
|
175
|
-
}), {}),
|
|
176
|
-
required: tool.parameters.map((param) => param.name),
|
|
172
|
+
properties: tool.parameters.reduce((prev, param) => ({ ...prev, [param.name]: param.schema }), {}),
|
|
173
|
+
required: tool.parameters.filter((p) => p.required).map((p) => p.name),
|
|
177
174
|
additionalProperties: false,
|
|
178
175
|
},
|
|
179
176
|
};
|
|
@@ -16,7 +16,7 @@ import '../../../core/error/setupErrorHandlers.js';
|
|
|
16
16
|
|
|
17
17
|
const CHATS_FILE = '.wabot/in-memory/chats.json';
|
|
18
18
|
const MEMORY_DIR = '.wabot/in-memory';
|
|
19
|
-
const MAX_CHATS =
|
|
19
|
+
const MAX_CHATS = 32;
|
|
20
20
|
const logger = new Logger('wabot:in-memory-chat-repository');
|
|
21
21
|
let InMemoryChatRepository = class InMemoryChatRepository {
|
|
22
22
|
// Ordered least-recently-active first, most-recent last.
|
|
@@ -129,20 +129,18 @@ let OpenaiChatAdapter = class OpenaiChatAdapter {
|
|
|
129
129
|
];
|
|
130
130
|
}
|
|
131
131
|
mapTool(tool) {
|
|
132
|
+
const allRequired = tool.parameters.every((p) => p.required);
|
|
132
133
|
return {
|
|
133
134
|
type: 'function',
|
|
134
135
|
name: tool.name,
|
|
135
136
|
description: tool.description,
|
|
136
137
|
parameters: {
|
|
137
138
|
type: 'object',
|
|
138
|
-
properties: tool.parameters.reduce((prev, param) => ({
|
|
139
|
-
|
|
140
|
-
[param.name]: { type: param.type, description: param.description },
|
|
141
|
-
}), {}),
|
|
142
|
-
required: tool.parameters.map((param) => param.name),
|
|
139
|
+
properties: tool.parameters.reduce((prev, param) => ({ ...prev, [param.name]: param.schema }), {}),
|
|
140
|
+
required: tool.parameters.filter((p) => p.required).map((p) => p.name),
|
|
143
141
|
additionalProperties: false,
|
|
144
142
|
},
|
|
145
|
-
strict:
|
|
143
|
+
strict: allRequired,
|
|
146
144
|
};
|
|
147
145
|
}
|
|
148
146
|
mapResponse(response, modelName) {
|
|
@@ -146,14 +146,10 @@ let OpenRouterChatAdapter = class OpenRouterChatAdapter {
|
|
|
146
146
|
description: tool.description,
|
|
147
147
|
parameters: {
|
|
148
148
|
type: 'object',
|
|
149
|
-
properties: tool.parameters.reduce((prev, param) => ({
|
|
150
|
-
|
|
151
|
-
[param.name]: { type: param.type, description: param.description },
|
|
152
|
-
}), {}),
|
|
153
|
-
required: tool.parameters.map((param) => param.name),
|
|
149
|
+
properties: tool.parameters.reduce((prev, param) => ({ ...prev, [param.name]: param.schema }), {}),
|
|
150
|
+
required: tool.parameters.filter((p) => p.required).map((p) => p.name),
|
|
154
151
|
additionalProperties: false,
|
|
155
152
|
},
|
|
156
|
-
strict: true,
|
|
157
153
|
},
|
|
158
154
|
};
|
|
159
155
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import '../../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -17,6 +16,7 @@ import '../../../feature/chat-bot/UnionChatAdapter.js';
|
|
|
17
16
|
import '../../../feature/chat-bot/metadata/ChatAdapterMetadataStore.js';
|
|
18
17
|
import 'uuid';
|
|
19
18
|
import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
|
|
19
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
20
20
|
|
|
21
21
|
class PgChatMemory extends PgCrudRepository {
|
|
22
22
|
chatId;
|
|
@@ -2,8 +2,7 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
3
|
import { PgChatMemory } from './PgChatMemory.js';
|
|
4
4
|
import { singleton } from '../../../core/injection/index.js';
|
|
5
|
-
import '
|
|
6
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
5
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
8
7
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
9
8
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -20,6 +19,7 @@ import '../../../feature/chat-bot/UnionChatAdapter.js';
|
|
|
20
19
|
import '../../../feature/chat-bot/metadata/ChatAdapterMetadataStore.js';
|
|
21
20
|
import 'uuid';
|
|
22
21
|
import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
|
|
22
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
23
23
|
|
|
24
24
|
let PgChatRepository = class PgChatRepository extends PgCrudRepository {
|
|
25
25
|
constructor(pool) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { container } from '../../../core/injection/index.js';
|
|
2
|
+
import { resolveConfigReferences } from '../../../core/config/resolver.js';
|
|
2
3
|
import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
|
|
3
4
|
import '../../../feature/chat-controller/ChatResolver.js';
|
|
4
5
|
import '../../../feature/chat-controller/runChatControllers.js';
|
|
@@ -7,12 +8,13 @@ import { TelegramChannelConfig } from './TelegramChannelConfig.js';
|
|
|
7
8
|
|
|
8
9
|
function telegram(config) {
|
|
9
10
|
return function (target, propertyKey) {
|
|
11
|
+
const resolved = resolveConfigReferences(config);
|
|
10
12
|
const store = container.resolve(ControllerMetadataStore);
|
|
11
13
|
store.saveChannelMetadata({
|
|
12
14
|
channelConstructor: TelegramChannel,
|
|
13
15
|
functionName: propertyKey.toString(),
|
|
14
16
|
controllerConstructor: target.constructor,
|
|
15
|
-
channelConfig: new TelegramChannelConfig(
|
|
17
|
+
channelConfig: new TelegramChannelConfig(resolved.botToken),
|
|
16
18
|
});
|
|
17
19
|
};
|
|
18
20
|
}
|
|
@@ -2,6 +2,7 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { Bot } from 'grammy';
|
|
3
3
|
import { TelegramChannelConfig } from './TelegramChannelConfig.js';
|
|
4
4
|
import { injectable } from '../../../core/injection/index.js';
|
|
5
|
+
import { markdownToTelegramHtml } from './markdownToTelegramHtml.js';
|
|
5
6
|
import { telegramChannelName } from './telegramChannelName.js';
|
|
6
7
|
|
|
7
8
|
var TelegramChannel_1;
|
|
@@ -35,7 +36,9 @@ let TelegramChannel = class TelegramChannel {
|
|
|
35
36
|
reply: async (replyMessage) => {
|
|
36
37
|
if (!replyMessage.text)
|
|
37
38
|
return;
|
|
38
|
-
await ctx.reply(replyMessage.text)
|
|
39
|
+
await ctx.reply(markdownToTelegramHtml(replyMessage.text), {
|
|
40
|
+
parse_mode: 'HTML',
|
|
41
|
+
});
|
|
39
42
|
},
|
|
40
43
|
});
|
|
41
44
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const PH_OPEN = '';
|
|
2
|
+
const PH_CLOSE = '';
|
|
3
|
+
function escapeHtml(text) {
|
|
4
|
+
return text
|
|
5
|
+
.replace(/&/g, '&')
|
|
6
|
+
.replace(/</g, '<')
|
|
7
|
+
.replace(/>/g, '>');
|
|
8
|
+
}
|
|
9
|
+
function markdownToTelegramHtml(input) {
|
|
10
|
+
if (!input)
|
|
11
|
+
return input;
|
|
12
|
+
const reserved = [];
|
|
13
|
+
const reserve = (html) => {
|
|
14
|
+
const token = `${PH_OPEN}${reserved.length}${PH_CLOSE}`;
|
|
15
|
+
reserved.push(html);
|
|
16
|
+
return token;
|
|
17
|
+
};
|
|
18
|
+
let text = input.replace(/\r\n/g, '\n');
|
|
19
|
+
text = text.replace(/```(\w+)?\n?([\s\S]*?)```/g, (_, lang, code) => {
|
|
20
|
+
const escaped = escapeHtml(code.replace(/\n$/, ''));
|
|
21
|
+
if (lang)
|
|
22
|
+
return reserve(`<pre><code class="language-${lang}">${escaped}</code></pre>`);
|
|
23
|
+
return reserve(`<pre>${escaped}</pre>`);
|
|
24
|
+
});
|
|
25
|
+
text = text.replace(/`([^`\n]+)`/g, (_, code) => {
|
|
26
|
+
return reserve(`<code>${escapeHtml(code)}</code>`);
|
|
27
|
+
});
|
|
28
|
+
text = text.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_, label, url) => {
|
|
29
|
+
return reserve(`<a href="${escapeHtml(url)}">${escapeHtml(label)}</a>`);
|
|
30
|
+
});
|
|
31
|
+
text = escapeHtml(text);
|
|
32
|
+
text = text.replace(/^(#{1,6})\s+(.+)$/gm, (_, _hashes, content) => `<b>${content.trim()}</b>`);
|
|
33
|
+
text = text.replace(/^>\s?(.*)$/gm, '<blockquote>$1</blockquote>');
|
|
34
|
+
text = text.replace(/<\/blockquote>\n<blockquote>/g, '\n');
|
|
35
|
+
text = text.replace(/\*\*([^\n*]+?)\*\*/g, '<b>$1</b>');
|
|
36
|
+
text = text.replace(/__([^\n_]+?)__/g, '<b>$1</b>');
|
|
37
|
+
text = text.replace(/(^|[\s(>])\*([^\s*][^*\n]*?)\*(?=[\s).,!?:;]|$)/g, '$1<i>$2</i>');
|
|
38
|
+
text = text.replace(/(^|[\s(>])_([^\s_][^_\n]*?)_(?=[\s).,!?:;]|$)/g, '$1<i>$2</i>');
|
|
39
|
+
text = text.replace(/~~([^\n~]+?)~~/g, '<s>$1</s>');
|
|
40
|
+
text = text.replace(/^[ \t]*[-*+]\s+(.+)$/gm, '• $1');
|
|
41
|
+
text = text.replace(new RegExp(`${PH_OPEN}(\\d+)${PH_CLOSE}`, 'g'), (_, idx) => reserved[Number(idx)]);
|
|
42
|
+
return text;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { markdownToTelegramHtml };
|
|
@@ -5,11 +5,20 @@ import { MindsetOperator } from '../mindset/MindsetOperator.js';
|
|
|
5
5
|
import { ChatAdapter } from './ChatAdapter.js';
|
|
6
6
|
import { ChatItem } from './ChatItem.js';
|
|
7
7
|
import { ChatMemory } from './ChatMemory.js';
|
|
8
|
+
import { Logger } from '../../core/logger/Logger.js';
|
|
8
9
|
|
|
10
|
+
const MAX_CONSECUTIVE_INVALID_ARGS = 2;
|
|
11
|
+
function isInvalidArgsResult(result) {
|
|
12
|
+
if (!result)
|
|
13
|
+
return false;
|
|
14
|
+
return (result.startsWith('{"error":"INVALID_ARGUMENTS"') ||
|
|
15
|
+
result.startsWith('{"error":"INVALID_JSON_ARGUMENTS"'));
|
|
16
|
+
}
|
|
9
17
|
let ChatBot = class ChatBot {
|
|
10
18
|
memory;
|
|
11
19
|
adapter;
|
|
12
20
|
mindset;
|
|
21
|
+
logger = new Logger('wabot:chat-bot');
|
|
13
22
|
constructor(memory, adapter, mindset) {
|
|
14
23
|
this.memory = memory;
|
|
15
24
|
this.adapter = adapter;
|
|
@@ -21,9 +30,9 @@ let ChatBot = class ChatBot {
|
|
|
21
30
|
humanMessage: message,
|
|
22
31
|
});
|
|
23
32
|
await this.memory.create(newChatItem);
|
|
24
|
-
await this.processLoop(callback);
|
|
33
|
+
await this.processLoop(callback, 0);
|
|
25
34
|
}
|
|
26
|
-
async processLoop(callback) {
|
|
35
|
+
async processLoop(callback, invalidArgsCount) {
|
|
27
36
|
const prevItems = await this.memory.findLastItems(16);
|
|
28
37
|
if (prevItems.length === 0) {
|
|
29
38
|
return;
|
|
@@ -53,6 +62,12 @@ let ChatBot = class ChatBot {
|
|
|
53
62
|
for (const newItemData of newItemsData) {
|
|
54
63
|
if (newItemData.type === 'functionCall') {
|
|
55
64
|
newItemData.functionCall.result = await this.mindset.callFunction(newItemData.functionCall.name, newItemData.functionCall.arguments ?? '{}');
|
|
65
|
+
if (isInvalidArgsResult(newItemData.functionCall.result)) {
|
|
66
|
+
invalidArgsCount++;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
invalidArgsCount = 0;
|
|
70
|
+
}
|
|
56
71
|
}
|
|
57
72
|
else if (newItemData.type === 'botMessage') {
|
|
58
73
|
newItemData.botMessage.senderName = identity.name;
|
|
@@ -63,10 +78,14 @@ let ChatBot = class ChatBot {
|
|
|
63
78
|
await callback(newChatItem.botMessage);
|
|
64
79
|
}
|
|
65
80
|
}
|
|
81
|
+
if (invalidArgsCount >= MAX_CONSECUTIVE_INVALID_ARGS) {
|
|
82
|
+
this.logger.warn(`Aborting chat loop after ${invalidArgsCount} consecutive invalid-argument function calls`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
66
85
|
if (newItemsData.length == 0 || newItemsData[newItemsData.length - 1].type === 'botMessage') {
|
|
67
86
|
return;
|
|
68
87
|
}
|
|
69
|
-
await this.processLoop(callback);
|
|
88
|
+
await this.processLoop(callback, invalidArgsCount);
|
|
70
89
|
}
|
|
71
90
|
};
|
|
72
91
|
ChatBot = __decorate([
|
|
@@ -7,6 +7,8 @@ import '../../core/validation/metadata/ValidationMetadataStore.js';
|
|
|
7
7
|
import { CustomError, errorToPlainObject } from '../../core/error/CustomError.js';
|
|
8
8
|
import '../../core/error/setupErrorHandlers.js';
|
|
9
9
|
import { Logger } from '../../core/logger/Logger.js';
|
|
10
|
+
import { DescriptionMetadataStore } from '../../core/description/metadata/DescriptionMetadataStore.js';
|
|
11
|
+
import { buildPropertySchema } from './buildParameterSchema.js';
|
|
10
12
|
import { Container } from '../../core/injection/Container.js';
|
|
11
13
|
|
|
12
14
|
const MODEL_KIND_FALLBACK = {
|
|
@@ -16,11 +18,13 @@ const MODEL_KIND_FALLBACK = {
|
|
|
16
18
|
let MindsetOperator = class MindsetOperator {
|
|
17
19
|
mindset;
|
|
18
20
|
container;
|
|
21
|
+
descriptionStore;
|
|
19
22
|
logger = new Logger('wabot:mindset-operator');
|
|
20
23
|
metadata;
|
|
21
|
-
constructor(mindset, container, metadataStore) {
|
|
24
|
+
constructor(mindset, container, metadataStore, descriptionStore) {
|
|
22
25
|
this.mindset = mindset;
|
|
23
26
|
this.container = container;
|
|
27
|
+
this.descriptionStore = descriptionStore;
|
|
24
28
|
this.metadata = metadataStore.getMindsetInfo(this.mindset.constructor);
|
|
25
29
|
}
|
|
26
30
|
context() {
|
|
@@ -107,38 +111,37 @@ let MindsetOperator = class MindsetOperator {
|
|
|
107
111
|
return systemPrompt;
|
|
108
112
|
}
|
|
109
113
|
tools() {
|
|
114
|
+
const deps = {
|
|
115
|
+
descriptionStore: this.descriptionStore,
|
|
116
|
+
};
|
|
110
117
|
return this.metadata.modules
|
|
111
118
|
.map((module) => module.functions.map((fn) => {
|
|
119
|
+
const argsValidatorsInfo = fn.argsValidatorsInfo;
|
|
120
|
+
const propertyValidators = argsValidatorsInfo?.properties ?? {};
|
|
112
121
|
return {
|
|
113
122
|
language: module.config?.language ?? 'english',
|
|
114
123
|
name: fn.name,
|
|
115
124
|
description: fn.description,
|
|
116
|
-
parameters: fn.argsDescriptions.map((
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
parameters: fn.argsDescriptions.map((arg) => {
|
|
126
|
+
const propInfo = propertyValidators[arg.propertyName];
|
|
127
|
+
const schema = buildPropertySchema(propInfo?.validators ?? [], this.paramDescription(arg.description, arg.typeDescriptor), deps);
|
|
128
|
+
return {
|
|
129
|
+
name: arg.propertyName,
|
|
130
|
+
required: !propInfo?.isOptional,
|
|
131
|
+
schema,
|
|
132
|
+
};
|
|
133
|
+
}),
|
|
121
134
|
};
|
|
122
135
|
}))
|
|
123
136
|
.flat();
|
|
124
137
|
}
|
|
125
138
|
paramDescription(rawDescription, rawType) {
|
|
126
|
-
let description =
|
|
127
|
-
### description (in your main language)
|
|
128
|
-
${rawDescription.replaceAll('#', ' ')}
|
|
129
|
-
`;
|
|
139
|
+
let description = rawDescription.replaceAll('#', ' ').trim();
|
|
130
140
|
if (rawType === 'date') {
|
|
131
|
-
description = `${description}
|
|
132
|
-
### format: ISO 8681 - YYYY-MM-DDTHH:mm:ssZ
|
|
133
|
-
`;
|
|
141
|
+
description = `${description}\nFormat: ISO 8601 - YYYY-MM-DDTHH:mm:ssZ`;
|
|
134
142
|
}
|
|
135
143
|
return description;
|
|
136
144
|
}
|
|
137
|
-
paramType(rawType) {
|
|
138
|
-
if (rawType === 'date')
|
|
139
|
-
return 'string';
|
|
140
|
-
return rawType;
|
|
141
|
-
}
|
|
142
145
|
async callFunction(name, params) {
|
|
143
146
|
const fnMetadata = this.metadata.modules
|
|
144
147
|
.map((module) => module.functions)
|
|
@@ -151,16 +154,37 @@ let MindsetOperator = class MindsetOperator {
|
|
|
151
154
|
message: `Function '${name}' is not registered in mindset tools`,
|
|
152
155
|
});
|
|
153
156
|
}
|
|
157
|
+
let paramsObj;
|
|
154
158
|
try {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
paramsObj = JSON.parse(params);
|
|
160
|
+
}
|
|
161
|
+
catch (parseError) {
|
|
162
|
+
const aiResponse = JSON.stringify({
|
|
163
|
+
error: 'INVALID_JSON_ARGUMENTS',
|
|
164
|
+
message: 'The function call arguments are not valid JSON. Re-issue the call with a valid JSON object.',
|
|
165
|
+
details: parseError instanceof Error ? parseError.message : String(parseError),
|
|
166
|
+
});
|
|
167
|
+
this.logger.error(`Function '${name}' received non-JSON arguments`, { params, parseError });
|
|
168
|
+
return aiResponse;
|
|
169
|
+
}
|
|
170
|
+
const modelValidationInfo = fnMetadata.argsValidatorsInfo;
|
|
171
|
+
if (modelValidationInfo) {
|
|
172
|
+
const validation = validateModel(paramsObj, modelValidationInfo);
|
|
173
|
+
if (validation.error) {
|
|
174
|
+
const aiResponse = JSON.stringify({
|
|
175
|
+
error: 'INVALID_ARGUMENTS',
|
|
176
|
+
message: 'The provided arguments did not pass validation. Inspect the errors below and re-issue the call with corrected arguments.',
|
|
177
|
+
details: this.flattenValidationError(validation.error),
|
|
178
|
+
});
|
|
179
|
+
this.logger.warn(`Function '${name}' received invalid arguments`, {
|
|
180
|
+
params,
|
|
181
|
+
errors: validation.error,
|
|
182
|
+
});
|
|
183
|
+
return aiResponse;
|
|
163
184
|
}
|
|
185
|
+
paramsObj = validation.value;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
164
188
|
const module = this.container.resolve(fnMetadata.moduleConstructor);
|
|
165
189
|
const response = await module[name](paramsObj);
|
|
166
190
|
if (!response) {
|
|
@@ -179,6 +203,41 @@ let MindsetOperator = class MindsetOperator {
|
|
|
179
203
|
return aiResponse;
|
|
180
204
|
}
|
|
181
205
|
}
|
|
206
|
+
flattenValidationError(error, path = '') {
|
|
207
|
+
const out = [];
|
|
208
|
+
if (!error)
|
|
209
|
+
return out;
|
|
210
|
+
if (Array.isArray(error?.items)) {
|
|
211
|
+
error.items.forEach((itemErrors, idx) => {
|
|
212
|
+
if (!itemErrors)
|
|
213
|
+
return;
|
|
214
|
+
const itemPath = `${path}[${idx}]`;
|
|
215
|
+
if (Array.isArray(itemErrors)) {
|
|
216
|
+
itemErrors.forEach((ie) => out.push(...this.flattenValidationError(ie, itemPath)));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
out.push(...this.flattenValidationError(itemErrors, itemPath));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (out.length > 0)
|
|
223
|
+
return out;
|
|
224
|
+
}
|
|
225
|
+
if (error?.properties && typeof error.properties === 'object') {
|
|
226
|
+
for (const propName in error.properties) {
|
|
227
|
+
const propErrors = error.properties[propName];
|
|
228
|
+
const propPath = path ? `${path}.${propName}` : propName;
|
|
229
|
+
if (Array.isArray(propErrors)) {
|
|
230
|
+
propErrors.forEach((pe) => out.push(...this.flattenValidationError(pe, propPath)));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (out.length > 0)
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
if (typeof error.description === 'string') {
|
|
237
|
+
out.push({ path: path || '(root)', message: error.description });
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
182
241
|
async functionResponseToString(response) {
|
|
183
242
|
if (response instanceof Response) {
|
|
184
243
|
const contentType = response.headers.get('Content-Type') || '';
|
|
@@ -232,7 +291,8 @@ MindsetOperator = __decorate([
|
|
|
232
291
|
injectable(),
|
|
233
292
|
__metadata("design:paramtypes", [Mindset,
|
|
234
293
|
Container,
|
|
235
|
-
MindsetMetadataStore
|
|
294
|
+
MindsetMetadataStore,
|
|
295
|
+
DescriptionMetadataStore])
|
|
236
296
|
], MindsetOperator);
|
|
237
297
|
|
|
238
298
|
export { MindsetOperator };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import '../../core/injection/index.js';
|
|
2
|
+
import { validateModel } from '../../core/validation/core/validateModel.js';
|
|
3
|
+
import '../../core/validation/metadata/ValidationMetadataStore.js';
|
|
4
|
+
import { validateArray } from '../../core/validation/core/validateArray.js';
|
|
5
|
+
import { validateIsBoolean } from '../../core/validation/validators/is-boolean/validateIsBoolean.js';
|
|
6
|
+
import { validateIsDate } from '../../core/validation/validators/is-date/validateIsDate.js';
|
|
7
|
+
import { validateIsIn } from '../../core/validation/validators/is-in/validateIsIn.js';
|
|
8
|
+
import { validateIsNotEmpty } from '../../core/validation/validators/is-not-empty/validateIsNotEmpty.js';
|
|
9
|
+
import { validateIsNumber } from '../../core/validation/validators/is-number/validateIsNumber.js';
|
|
10
|
+
import { validateIsString } from '../../core/validation/validators/is-string/validateIsString.js';
|
|
11
|
+
import { validateMax } from '../../core/validation/validators/max/validateMax.js';
|
|
12
|
+
import { validateMin } from '../../core/validation/validators/min/validateMin.js';
|
|
13
|
+
import { validateIsRecord } from '../../core/validation/validators/is-record/validateIsRecord.js';
|
|
14
|
+
|
|
15
|
+
function buildPropertySchema(validators, description, deps) {
|
|
16
|
+
const schema = { type: 'string' };
|
|
17
|
+
if (description)
|
|
18
|
+
schema.description = description;
|
|
19
|
+
let typeAssigned = false;
|
|
20
|
+
for (const v of validators) {
|
|
21
|
+
const { validator, validatorOptions } = v;
|
|
22
|
+
if (validator === validateIsString) {
|
|
23
|
+
schema.type = 'string';
|
|
24
|
+
typeAssigned = true;
|
|
25
|
+
}
|
|
26
|
+
else if (validator === validateIsNumber) {
|
|
27
|
+
schema.type = 'number';
|
|
28
|
+
typeAssigned = true;
|
|
29
|
+
}
|
|
30
|
+
else if (validator === validateIsBoolean) {
|
|
31
|
+
schema.type = 'boolean';
|
|
32
|
+
typeAssigned = true;
|
|
33
|
+
}
|
|
34
|
+
else if (validator === validateIsDate) {
|
|
35
|
+
schema.type = 'string';
|
|
36
|
+
schema.format = 'date-time';
|
|
37
|
+
typeAssigned = true;
|
|
38
|
+
}
|
|
39
|
+
else if (validator === validateArray) {
|
|
40
|
+
schema.type = 'array';
|
|
41
|
+
typeAssigned = true;
|
|
42
|
+
const arrOpts = validatorOptions;
|
|
43
|
+
if (arrOpts?.minLength != null)
|
|
44
|
+
schema.minItems = arrOpts.minLength;
|
|
45
|
+
if (arrOpts?.maxLength != null)
|
|
46
|
+
schema.maxItems = arrOpts.maxLength;
|
|
47
|
+
if (arrOpts?.itemsValidator && arrOpts.itemsValidator.length > 0) {
|
|
48
|
+
const itemValidatorInfos = arrOpts.itemsValidator.map((iv, idx) => ({
|
|
49
|
+
propertyName: `__item_${idx}`,
|
|
50
|
+
validator: iv.validator,
|
|
51
|
+
validatorOptions: iv.options,
|
|
52
|
+
}));
|
|
53
|
+
schema.items = buildPropertySchema(itemValidatorInfos, undefined, deps);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
schema.items = { type: 'string' };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (validator === validateModel) {
|
|
60
|
+
const modelInfo = validatorOptions;
|
|
61
|
+
schema.type = 'object';
|
|
62
|
+
typeAssigned = true;
|
|
63
|
+
if (modelInfo) {
|
|
64
|
+
const built = buildModelSchema(modelInfo, deps);
|
|
65
|
+
schema.properties = built.properties;
|
|
66
|
+
if (built.required && built.required.length > 0) {
|
|
67
|
+
schema.required = built.required;
|
|
68
|
+
}
|
|
69
|
+
schema.additionalProperties = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (validator === validateIsRecord) {
|
|
73
|
+
schema.type = 'object';
|
|
74
|
+
typeAssigned = true;
|
|
75
|
+
const opts = validatorOptions;
|
|
76
|
+
if (opts) {
|
|
77
|
+
schema.additionalProperties = { type: opts.valueType };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (validator === validateIsIn) {
|
|
81
|
+
const opts = validatorOptions;
|
|
82
|
+
if (opts) {
|
|
83
|
+
schema.enum = [...opts.values];
|
|
84
|
+
if (!typeAssigned) {
|
|
85
|
+
const sample = opts.values.find((x) => x != null);
|
|
86
|
+
const t = typeof sample;
|
|
87
|
+
if (t === 'string' || t === 'number' || t === 'boolean') {
|
|
88
|
+
schema.type = t;
|
|
89
|
+
typeAssigned = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (validator === validateMin) {
|
|
95
|
+
const opts = validatorOptions;
|
|
96
|
+
const limit = opts && Number(opts.limit);
|
|
97
|
+
if (limit != null && !Number.isNaN(limit)) {
|
|
98
|
+
if (schema.type === 'string') {
|
|
99
|
+
schema.minLength = limit;
|
|
100
|
+
}
|
|
101
|
+
else if (schema.type === 'array') {
|
|
102
|
+
schema.minItems = limit;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
schema.minimum = limit;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (validator === validateMax) {
|
|
110
|
+
const opts = validatorOptions;
|
|
111
|
+
const limit = opts && Number(opts.limit);
|
|
112
|
+
if (limit != null && !Number.isNaN(limit)) {
|
|
113
|
+
if (schema.type === 'string') {
|
|
114
|
+
schema.maxLength = limit;
|
|
115
|
+
}
|
|
116
|
+
else if (schema.type === 'array') {
|
|
117
|
+
schema.maxItems = limit;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
schema.maximum = limit;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (validator === validateIsNotEmpty) {
|
|
125
|
+
if (schema.type === 'array') {
|
|
126
|
+
if (schema.minItems == null || schema.minItems < 1)
|
|
127
|
+
schema.minItems = 1;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
if (schema.minLength == null || schema.minLength < 1)
|
|
131
|
+
schema.minLength = 1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return schema;
|
|
136
|
+
}
|
|
137
|
+
function buildModelSchema(modelInfo, deps) {
|
|
138
|
+
const properties = {};
|
|
139
|
+
const required = [];
|
|
140
|
+
const descriptions = deps.descriptionStore.getModelDescriptions(modelInfo.modelConstructor);
|
|
141
|
+
const descByName = new Map(descriptions.map((d) => [d.propertyName, d]));
|
|
142
|
+
for (const propertyName in modelInfo.properties) {
|
|
143
|
+
const propInfo = modelInfo.properties[propertyName];
|
|
144
|
+
if (!propInfo)
|
|
145
|
+
continue;
|
|
146
|
+
const desc = descByName.get(propertyName)?.description;
|
|
147
|
+
const schema = buildPropertySchema(propInfo.validators ?? [], desc, deps);
|
|
148
|
+
properties[propertyName] = schema;
|
|
149
|
+
if (!propInfo.isOptional)
|
|
150
|
+
required.push(propertyName);
|
|
151
|
+
}
|
|
152
|
+
return { properties, required };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { buildModelSchema, buildPropertySchema };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { container } from '../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import { RepositoryMetadataStore } from '../repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import { PgRepositoryBase } from './PgRepositoryBase.js';
|
|
@@ -1,12 +1,80 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
1
3
|
import { generate } from 'short-uuid';
|
|
2
4
|
import { CustomError } from '../../core/error/CustomError.js';
|
|
3
5
|
import '../../core/error/setupErrorHandlers.js';
|
|
6
|
+
import { Logger } from '../../core/logger/Logger.js';
|
|
4
7
|
import { evaluateQueryAst } from './evaluateQueryAst.js';
|
|
5
8
|
|
|
9
|
+
const DEFAULT_PERSIST_DIR = '.wabot/in-memory';
|
|
10
|
+
const DEFAULT_MAX_ITEMS = 32;
|
|
11
|
+
const logger = new Logger('wabot:memory-repository-adapter');
|
|
6
12
|
function cloneEntity(config, item) {
|
|
7
13
|
const data = JSON.parse(JSON.stringify(item['data']));
|
|
8
14
|
return new config.constructor(data);
|
|
9
15
|
}
|
|
16
|
+
class MemoryStore {
|
|
17
|
+
config;
|
|
18
|
+
persistOptions;
|
|
19
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
20
|
+
items = new Map();
|
|
21
|
+
constructor(config, persistOptions) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.persistOptions = persistOptions;
|
|
24
|
+
this.load();
|
|
25
|
+
}
|
|
26
|
+
touch(item) {
|
|
27
|
+
this.items.delete(item.id);
|
|
28
|
+
this.items.set(item.id, item);
|
|
29
|
+
}
|
|
30
|
+
enforceLimit() {
|
|
31
|
+
while (this.items.size > this.persistOptions.maxItems) {
|
|
32
|
+
const oldest = this.items.keys().next().value;
|
|
33
|
+
if (oldest === undefined)
|
|
34
|
+
break;
|
|
35
|
+
this.items.delete(oldest);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
persist() {
|
|
39
|
+
if (!this.persistOptions.enabled)
|
|
40
|
+
return;
|
|
41
|
+
const file = this.filePath();
|
|
42
|
+
try {
|
|
43
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
44
|
+
const data = [...this.items.values()].map((i) => i['data']);
|
|
45
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
load() {
|
|
52
|
+
if (!this.persistOptions.enabled)
|
|
53
|
+
return;
|
|
54
|
+
const file = this.filePath();
|
|
55
|
+
if (!fs.existsSync(file))
|
|
56
|
+
return;
|
|
57
|
+
try {
|
|
58
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
59
|
+
const parsed = JSON.parse(raw);
|
|
60
|
+
if (!Array.isArray(parsed))
|
|
61
|
+
return;
|
|
62
|
+
for (const data of parsed) {
|
|
63
|
+
if (!data?.id)
|
|
64
|
+
continue;
|
|
65
|
+
const item = new this.config.constructor(data);
|
|
66
|
+
this.items.set(data.id, item);
|
|
67
|
+
}
|
|
68
|
+
this.enforceLimit();
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
filePath() {
|
|
75
|
+
return path.resolve(process.cwd(), this.persistOptions.dir, `${this.config.table}.json`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
10
78
|
class MemoryRepositoryExtension {
|
|
11
79
|
items;
|
|
12
80
|
config;
|
|
@@ -19,12 +87,15 @@ class MemoryRepositoryExtension {
|
|
|
19
87
|
}
|
|
20
88
|
}
|
|
21
89
|
class MemoryRepositoryRuntime {
|
|
22
|
-
|
|
90
|
+
store;
|
|
23
91
|
config;
|
|
24
|
-
constructor(
|
|
25
|
-
this.
|
|
92
|
+
constructor(store, config) {
|
|
93
|
+
this.store = store;
|
|
26
94
|
this.config = config;
|
|
27
95
|
}
|
|
96
|
+
get items() {
|
|
97
|
+
return this.store.items;
|
|
98
|
+
}
|
|
28
99
|
async find(id) {
|
|
29
100
|
const item = this.items.get(id);
|
|
30
101
|
return item ? cloneEntity(this.config, item) : null;
|
|
@@ -58,17 +129,22 @@ class MemoryRepositoryRuntime {
|
|
|
58
129
|
item['data'].id = generate();
|
|
59
130
|
item['data'].createdAt = new Date().getTime();
|
|
60
131
|
item.validate();
|
|
61
|
-
|
|
132
|
+
const stored = cloneEntity(this.config, item);
|
|
133
|
+
this.store.touch(stored);
|
|
134
|
+
this.store.enforceLimit();
|
|
135
|
+
this.store.persist();
|
|
62
136
|
}
|
|
63
137
|
async update(item) {
|
|
64
138
|
item.validate();
|
|
65
139
|
if (!this.items.has(item.id)) {
|
|
66
140
|
throw new Error(`Update failed: no affected rows`);
|
|
67
141
|
}
|
|
68
|
-
this.
|
|
142
|
+
this.store.touch(cloneEntity(this.config, item));
|
|
143
|
+
this.store.persist();
|
|
69
144
|
}
|
|
70
145
|
async delete(item) {
|
|
71
146
|
this.items.delete(item.id);
|
|
147
|
+
this.store.persist();
|
|
72
148
|
}
|
|
73
149
|
async runQuery(ast, args) {
|
|
74
150
|
const result = evaluateQueryAst(this.items.values(), ast, args);
|
|
@@ -85,16 +161,26 @@ class MemoryRepositoryRuntime {
|
|
|
85
161
|
for (const item of matched) {
|
|
86
162
|
this.items.delete(item.id);
|
|
87
163
|
}
|
|
164
|
+
if (matched.length > 0)
|
|
165
|
+
this.store.persist();
|
|
88
166
|
}
|
|
89
167
|
}
|
|
90
168
|
const MEMORY_ADAPTER_ID = Symbol('wabot:memory-adapter');
|
|
91
169
|
class MemoryRepositoryAdapter {
|
|
92
170
|
id = MEMORY_ADAPTER_ID;
|
|
93
171
|
stores = new Map();
|
|
172
|
+
persistOptions;
|
|
173
|
+
constructor(options = {}) {
|
|
174
|
+
this.persistOptions = {
|
|
175
|
+
enabled: options.persist ?? true,
|
|
176
|
+
dir: options.dir ?? DEFAULT_PERSIST_DIR,
|
|
177
|
+
maxItems: options.maxItems ?? DEFAULT_MAX_ITEMS,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
94
180
|
getStore(config) {
|
|
95
181
|
let store = this.stores.get(config);
|
|
96
182
|
if (!store) {
|
|
97
|
-
store = new
|
|
183
|
+
store = new MemoryStore(config, this.persistOptions);
|
|
98
184
|
this.stores.set(config, store);
|
|
99
185
|
}
|
|
100
186
|
return store;
|
|
@@ -103,7 +189,7 @@ class MemoryRepositoryAdapter {
|
|
|
103
189
|
return new MemoryRepositoryRuntime(this.getStore(config), config);
|
|
104
190
|
}
|
|
105
191
|
buildExtension(config, ExtensionCtor) {
|
|
106
|
-
return new ExtensionCtor(this.getStore(config), config);
|
|
192
|
+
return new ExtensionCtor(this.getStore(config).items, config);
|
|
107
193
|
}
|
|
108
194
|
}
|
|
109
195
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -867,10 +867,26 @@ declare class MindsetMetadataStore {
|
|
|
867
867
|
};
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
+
interface IMindsetParameterSchema {
|
|
871
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
|
|
872
|
+
description?: string;
|
|
873
|
+
enum?: (string | number | boolean | null)[];
|
|
874
|
+
format?: string;
|
|
875
|
+
minimum?: number;
|
|
876
|
+
maximum?: number;
|
|
877
|
+
minLength?: number;
|
|
878
|
+
maxLength?: number;
|
|
879
|
+
minItems?: number;
|
|
880
|
+
maxItems?: number;
|
|
881
|
+
items?: IMindsetParameterSchema;
|
|
882
|
+
properties?: Record<string, IMindsetParameterSchema>;
|
|
883
|
+
required?: string[];
|
|
884
|
+
additionalProperties?: boolean | IMindsetParameterSchema;
|
|
885
|
+
}
|
|
870
886
|
interface IMindsetToolParameter {
|
|
871
|
-
type: string;
|
|
872
887
|
name: string;
|
|
873
|
-
|
|
888
|
+
required: boolean;
|
|
889
|
+
schema: IMindsetParameterSchema;
|
|
874
890
|
}
|
|
875
891
|
|
|
876
892
|
interface IMindsetTool {
|
|
@@ -883,9 +899,10 @@ interface IMindsetTool {
|
|
|
883
899
|
declare class MindsetOperator implements IMindset {
|
|
884
900
|
private mindset;
|
|
885
901
|
private container;
|
|
902
|
+
private descriptionStore;
|
|
886
903
|
private logger;
|
|
887
904
|
private metadata;
|
|
888
|
-
constructor(mindset: Mindset, container: Container, metadataStore: MindsetMetadataStore);
|
|
905
|
+
constructor(mindset: Mindset, container: Container, metadataStore: MindsetMetadataStore, descriptionStore: DescriptionMetadataStore);
|
|
889
906
|
context(): Promise<string>;
|
|
890
907
|
identity(): Promise<IMindsetIdentity>;
|
|
891
908
|
skills(): Promise<string>;
|
|
@@ -898,8 +915,8 @@ declare class MindsetOperator implements IMindset {
|
|
|
898
915
|
systemPrompt(): Promise<string>;
|
|
899
916
|
tools(): IMindsetTool[];
|
|
900
917
|
protected paramDescription(rawDescription: string, rawType: string): string;
|
|
901
|
-
protected paramType(rawType: string): string;
|
|
902
918
|
callFunction(name: string, params: string): Promise<string>;
|
|
919
|
+
private flattenValidationError;
|
|
903
920
|
functionResponseToString(response: any): Promise<string>;
|
|
904
921
|
functionErrorToString(error: any): Promise<string>;
|
|
905
922
|
}
|
|
@@ -1028,9 +1045,10 @@ declare class ChatBot implements IChatBot {
|
|
|
1028
1045
|
private memory;
|
|
1029
1046
|
private adapter;
|
|
1030
1047
|
private mindset;
|
|
1048
|
+
private logger;
|
|
1031
1049
|
constructor(memory: ChatMemory, adapter: ChatAdapter, mindset: MindsetOperator);
|
|
1032
1050
|
sendMessage(message: IChatMessage, callback: (message: IChatMessage) => Promise<void>): Promise<void>;
|
|
1033
|
-
protected processLoop(callback: (message: IChatMessage) => Promise<void
|
|
1051
|
+
protected processLoop(callback: (message: IChatMessage) => Promise<void>, invalidArgsCount: number): Promise<void>;
|
|
1034
1052
|
}
|
|
1035
1053
|
|
|
1036
1054
|
interface IChatRepository {
|
|
@@ -1373,6 +1391,11 @@ interface IRepositoryAdapter {
|
|
|
1373
1391
|
buildExtension?<E>(config: IRepositoryConfig<any>, ExtensionCtor: IConstructor<E>): E;
|
|
1374
1392
|
}
|
|
1375
1393
|
|
|
1394
|
+
interface IMemoryRepositoryAdapterOptions {
|
|
1395
|
+
persist?: boolean;
|
|
1396
|
+
dir?: string;
|
|
1397
|
+
maxItems?: number;
|
|
1398
|
+
}
|
|
1376
1399
|
declare class MemoryRepositoryExtension<P extends Entity<IEntityData>> {
|
|
1377
1400
|
protected readonly items: Map<string, P>;
|
|
1378
1401
|
protected readonly config: IRepositoryConfig<P>;
|
|
@@ -1383,6 +1406,8 @@ declare const MEMORY_ADAPTER_ID: unique symbol;
|
|
|
1383
1406
|
declare class MemoryRepositoryAdapter implements IRepositoryAdapter {
|
|
1384
1407
|
readonly id: symbol;
|
|
1385
1408
|
private stores;
|
|
1409
|
+
private readonly persistOptions;
|
|
1410
|
+
constructor(options?: IMemoryRepositoryAdapterOptions);
|
|
1386
1411
|
private getStore;
|
|
1387
1412
|
build<P extends Entity<IEntityData>>(config: IRepositoryConfig<P>): IRepositoryRuntime<P>;
|
|
1388
1413
|
buildExtension<E>(config: IRepositoryConfig<any>, ExtensionCtor: IConstructor<E>): E;
|
|
@@ -1645,6 +1670,7 @@ declare class PgTransactionAdapter implements ITransactionAdapter {
|
|
|
1645
1670
|
|
|
1646
1671
|
declare class InMemoryJobRepository implements IJobRepository {
|
|
1647
1672
|
private items;
|
|
1673
|
+
constructor();
|
|
1648
1674
|
find(id: string): Promise<Job | null>;
|
|
1649
1675
|
findOrThrow(id: string): Promise<Job>;
|
|
1650
1676
|
findByIds(ids: string[]): Promise<Job[]>;
|
|
@@ -1655,15 +1681,26 @@ declare class InMemoryJobRepository implements IJobRepository {
|
|
|
1655
1681
|
findPendingForRunFrom(date: Date, limit: number): Promise<Job[]>;
|
|
1656
1682
|
findRunningJobs(): Promise<Job[]>;
|
|
1657
1683
|
countRunningByCommand(commandName: string): Promise<number>;
|
|
1684
|
+
private touch;
|
|
1685
|
+
private enforceLimit;
|
|
1686
|
+
private filePath;
|
|
1687
|
+
private load;
|
|
1688
|
+
private persist;
|
|
1658
1689
|
}
|
|
1659
1690
|
|
|
1660
1691
|
declare class InMemoryCronJobRepository implements ICronJobRepository {
|
|
1661
1692
|
private items;
|
|
1693
|
+
constructor();
|
|
1662
1694
|
create(cronJob: CronJob): Promise<void>;
|
|
1663
1695
|
findDue(date?: Date): Promise<CronJob[]>;
|
|
1664
1696
|
findOrThrow(id: string): Promise<CronJob>;
|
|
1665
1697
|
update(cronJob: CronJob): Promise<void>;
|
|
1666
1698
|
findByName(name: string): Promise<CronJob | null>;
|
|
1699
|
+
private touch;
|
|
1700
|
+
private enforceLimit;
|
|
1701
|
+
private filePath;
|
|
1702
|
+
private load;
|
|
1703
|
+
private persist;
|
|
1667
1704
|
}
|
|
1668
1705
|
|
|
1669
1706
|
declare function apiKeyHandshakeGuard(): (target: IConstructor<any>) => void;
|
|
@@ -2138,9 +2175,9 @@ declare class SocketChannel implements IChatChannel {
|
|
|
2138
2175
|
}
|
|
2139
2176
|
|
|
2140
2177
|
interface ITelegramChannelConfig {
|
|
2141
|
-
botToken: string
|
|
2178
|
+
botToken: string | ConfigReference<string>;
|
|
2142
2179
|
}
|
|
2143
|
-
declare class TelegramChannelConfig
|
|
2180
|
+
declare class TelegramChannelConfig {
|
|
2144
2181
|
botToken: string;
|
|
2145
2182
|
constructor(botToken: string);
|
|
2146
2183
|
}
|
|
@@ -2168,6 +2205,8 @@ declare class TelegramChannel implements IChatChannel {
|
|
|
2168
2205
|
disconnect(): void;
|
|
2169
2206
|
}
|
|
2170
2207
|
|
|
2208
|
+
declare function markdownToTelegramHtml(input: string): string;
|
|
2209
|
+
|
|
2171
2210
|
interface IWhatsAppCloudTemplateResponse {
|
|
2172
2211
|
data: IWhatsAppCloudTemplate[];
|
|
2173
2212
|
paging: IWhatsAppCloudApiPaging;
|
|
@@ -2485,4 +2524,4 @@ declare function HtmlModule(options: IHtmlModuleOptions): {
|
|
|
2485
2524
|
new (): {};
|
|
2486
2525
|
};
|
|
2487
2526
|
|
|
2488
|
-
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatAdapterMetadataStore, ChatAdapterRegistry, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatOperator, ChatRepository, ChatResolver, type ClientMap, CmdChannel, CmdChannelConfig, CmdChannelServer, type CmdClientMessage, type CmdServerMessage, type ConfigReference, type ConfigReferenceType, ConfigResolver, Container, ControllerMetadataStore, CronJob, CronJobRepository, CrudRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IBuiltQuery, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterDecoratorConfig, type IChatAdapterMetadata, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatMessageDocument, type IChatMessageFile, type IChatMessageImage, type IChatMessagesPrivateFile, type IChatMessagesPublicFile, type IChatRepository, type IChatType, type ICmdChannelEntry, type ICmdChannelHandlers, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronHandler, type ICronJobData, type ICronJobRepository, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IExtractChatMessageTextOptions, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type ILockKey, type ILocker, type ILockerKey, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModelKind, type IMindsetModelRef, type IMindsetModels, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IProjectRunnerConfig, type IPropertyValidatorInfo, type IQueryAst, type IQueryCondition, type IQueryMethodMetadata, type IQueryOrderBy, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRepositoryAdapter, type IRepositoryConfig, type IRepositoryRuntime, type IRestControllerConfig, type IRestControllerMetadata, type IScanProjectFilesOptions, type IScheduleAt, type IScheduleDelay, type ISendWhatsAppMessageReq, type ISendWhatsAppTemplateReq, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type ITransactionAdapter, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelConfig, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWasenderReceivedMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppSender, type IWhatsAppTemplateData, type IWhatsAppTemplateParameter, type IchatControllerConfig, InMemoryChatMemory, InMemoryChatRepository, InMemoryCronJobRepository, InMemoryJobRepository, InMemoryLockKey, InMemoryLocker, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, MEMORY_ADAPTER_ID, Mapper, MemoryRepositoryAdapter, MemoryRepositoryExtension, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenRouterChatAdapter, OpenaiChatAdapter, PG_ADAPTER_ID, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJsonRepositoryAdapter, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgRepositoryBase as PgRepositoryExtension, PgTransactionAdapter, ProjectRunner, type QueryConnector, type QueryOperator, type QueryPrefix, Random, RemoteApiKeyRepository, RepositoryAdapterRegistry, RepositoryMetadataStore, type ResolvedConfig, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelMessageFile, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, TransactionMetadataStore, UnionChatAdapter, ValidationMetadataStore, WabotChatAdapter, WasenderChannel, WasenderChannelConfig, WasenderReceiver, WasenderSender, WasenderWebhookController, WhatsAppApiSender, WhatsAppReceiverByCloudApi, WhatsAppSender, apiKeyGuard, apiKeyHandshakeGuard, bool, boolArr, buildQuerySql, chatAdapter, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, cmdChannelSocketPath, command, commandHandler, container, cronHandler, description, errorToPlainObject, evaluateQueryAst, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isChatMessageEmpty, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isRetryableError, isString, jwtGuard, jwtHandshakeGuard, max, memExtension, middleware, min, mindset, mindsetModule, modelInfo, num, numArr, obj, onDelete, onGet, onPost, onPut, onSocketEvent, parseQueryMethodName, pgExtension, pgStorage, query, queryExtension, readJsonFromFile, repository, resolveConfigReferences, restController, run, runChatAdapters, runChatControllers, runCmdClient, runCommandHandlers, runCronHandlers, runRestControllers, runSocketControllers, safeJsonParse, scanProjectFiles, scoped, setupErrorHandlers, singleton, socket, socketChannelName, socketController, stopCommandHandlers, stopCronHandlers, str, strArr, telegram, telegramChannelName, transaction, validateAndTransform, validateArray, validateIsBoolean, validateIsDate, validateIsIn, validateIsNotEmpty, validateIsNumber, validateIsPresent, validateIsRecord, validateIsString, validateMax, validateMin, validateModel, wasender, wasenderChannelName, withPgClient, withPgTransaction, writeJsonToFile };
|
|
2527
|
+
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatAdapterMetadataStore, ChatAdapterRegistry, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatOperator, ChatRepository, ChatResolver, type ClientMap, CmdChannel, CmdChannelConfig, CmdChannelServer, type CmdClientMessage, type CmdServerMessage, type ConfigReference, type ConfigReferenceType, ConfigResolver, Container, ControllerMetadataStore, CronJob, CronJobRepository, CrudRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IBuiltQuery, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterDecoratorConfig, type IChatAdapterMetadata, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatMessageDocument, type IChatMessageFile, type IChatMessageImage, type IChatMessagesPrivateFile, type IChatMessagesPublicFile, type IChatRepository, type IChatType, type ICmdChannelEntry, type ICmdChannelHandlers, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronHandler, type ICronJobData, type ICronJobRepository, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IExtractChatMessageTextOptions, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type ILockKey, type ILocker, type ILockerKey, type IMemoryRepositoryAdapterOptions, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModelKind, type IMindsetModelRef, type IMindsetModels, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetParameterSchema, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IProjectRunnerConfig, type IPropertyValidatorInfo, type IQueryAst, type IQueryCondition, type IQueryMethodMetadata, type IQueryOrderBy, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRepositoryAdapter, type IRepositoryConfig, type IRepositoryRuntime, type IRestControllerConfig, type IRestControllerMetadata, type IScanProjectFilesOptions, type IScheduleAt, type IScheduleDelay, type ISendWhatsAppMessageReq, type ISendWhatsAppTemplateReq, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type ITransactionAdapter, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelConfig, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWasenderReceivedMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppSender, type IWhatsAppTemplateData, type IWhatsAppTemplateParameter, type IchatControllerConfig, InMemoryChatMemory, InMemoryChatRepository, InMemoryCronJobRepository, InMemoryJobRepository, InMemoryLockKey, InMemoryLocker, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, MEMORY_ADAPTER_ID, Mapper, MemoryRepositoryAdapter, MemoryRepositoryExtension, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenRouterChatAdapter, OpenaiChatAdapter, PG_ADAPTER_ID, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJsonRepositoryAdapter, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgRepositoryBase as PgRepositoryExtension, PgTransactionAdapter, ProjectRunner, type QueryConnector, type QueryOperator, type QueryPrefix, Random, RemoteApiKeyRepository, RepositoryAdapterRegistry, RepositoryMetadataStore, type ResolvedConfig, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelMessageFile, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, TransactionMetadataStore, UnionChatAdapter, ValidationMetadataStore, WabotChatAdapter, WasenderChannel, WasenderChannelConfig, WasenderReceiver, WasenderSender, WasenderWebhookController, WhatsAppApiSender, WhatsAppReceiverByCloudApi, WhatsAppSender, apiKeyGuard, apiKeyHandshakeGuard, bool, boolArr, buildQuerySql, chatAdapter, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, cmdChannelSocketPath, command, commandHandler, container, cronHandler, description, errorToPlainObject, evaluateQueryAst, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isChatMessageEmpty, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isRetryableError, isString, jwtGuard, jwtHandshakeGuard, markdownToTelegramHtml, max, memExtension, middleware, min, mindset, mindsetModule, modelInfo, num, numArr, obj, onDelete, onGet, onPost, onPut, onSocketEvent, parseQueryMethodName, pgExtension, pgStorage, query, queryExtension, readJsonFromFile, repository, resolveConfigReferences, restController, run, runChatAdapters, runChatControllers, runCmdClient, runCommandHandlers, runCronHandlers, runRestControllers, runSocketControllers, safeJsonParse, scanProjectFiles, scoped, setupErrorHandlers, singleton, socket, socketChannelName, socketController, stopCommandHandlers, stopCronHandlers, str, strArr, telegram, telegramChannelName, transaction, validateAndTransform, validateArray, validateIsBoolean, validateIsDate, validateIsIn, validateIsNotEmpty, validateIsNumber, validateIsPresent, validateIsRecord, validateIsString, validateMax, validateMin, validateModel, wasender, wasenderChannelName, withPgClient, withPgTransaction, writeJsonToFile };
|
package/dist/src/index.js
CHANGED
|
@@ -177,6 +177,7 @@ export { telegram } from './addon/chat-controller/telegram/@telegram.js';
|
|
|
177
177
|
export { TelegramChannelConfig } from './addon/chat-controller/telegram/TelegramChannelConfig.js';
|
|
178
178
|
export { TelegramChannel } from './addon/chat-controller/telegram/TelegramChannel.js';
|
|
179
179
|
export { telegramChannelName } from './addon/chat-controller/telegram/telegramChannelName.js';
|
|
180
|
+
export { markdownToTelegramHtml } from './addon/chat-controller/telegram/markdownToTelegramHtml.js';
|
|
180
181
|
export { WhatsAppReceiverByCloudApi } from './addon/chat-controller/whatsapp/cloud-api/WhatsAppReceiverByCloudApi.js';
|
|
181
182
|
export { WhatsAppApiSender } from './addon/chat-controller/whatsapp/cloud-api/WhatsAppApiSender.js';
|
|
182
183
|
export { wasender } from './addon/chat-controller/whatsapp/wasender/@wasender.js';
|