mm_os 4.2.6 → 4.2.8

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.
Files changed (74) hide show
  1. package/README.md +1 -1
  2. package/README_EN.md +2 -2
  3. package/adapter/adapter.js +105 -52
  4. package/adapter/custom_persistence.js +32 -31
  5. package/adapter/mqtt.js +59 -79
  6. package/adapter/socket.js +188 -58
  7. package/adapter/web.js +92 -68
  8. package/adapter/websocket.js +43 -146
  9. package/com/api/drive.js +732 -708
  10. package/com/api/index.js +196 -198
  11. package/com/cmd/config.tpl.json +48 -122
  12. package/com/cmd/drive.js +176 -1548
  13. package/com/cmd/index.js +287 -1066
  14. package/com/cmd/job/config.json +66 -0
  15. package/com/cmd/job/index.js +241 -0
  16. package/com/cmd/job/test.js +188 -0
  17. package/com/cmd/script.tpl.js +12 -33
  18. package/com/db/drive.js +2206 -2019
  19. package/com/db/index.js +241 -242
  20. package/com/event/config.tpl.json +3 -1
  21. package/com/event/drive.js +3 -1
  22. package/com/event/index.js +73 -49
  23. package/com/event/script.tpl.js +1 -1
  24. package/com/mqtt/config.tpl.json +16 -8
  25. package/com/mqtt/drive.js +696 -676
  26. package/com/mqtt/index.js +1012 -822
  27. package/com/mqtt/index.test.js +503 -0
  28. package/com/mqtt/mm_mqtt.js +446 -420
  29. package/com/mqtt/script.tpl.js +3 -7
  30. package/com/nav/drive.js +7 -7
  31. package/com/nav/index.js +228 -231
  32. package/com/param/index.js +19 -17
  33. package/com/pendant/index.js +467 -441
  34. package/com/socket/drive.js +679 -616
  35. package/com/socket/index.js +94 -48
  36. package/com/sql/drive.js +1283 -1259
  37. package/com/sql/index.js +152 -150
  38. package/com/static/drive.js +1 -1
  39. package/com/static/index.js +232 -226
  40. package/com/task/drive.js +428 -405
  41. package/com/task/index.js +154 -148
  42. package/com/template/drive.js +1 -1
  43. package/com/template/index.js +141 -138
  44. package/com.js +87 -6
  45. package/common/middleware/web_after/index.js +4 -10
  46. package/common/middleware/web_base/index.js +1 -1
  47. package/common/middleware/web_cors/index.js +1 -1
  48. package/common/middleware/web_error/index.js +131 -119
  49. package/common/middleware/web_error/middleware.json +2 -1
  50. package/common/middleware/web_logger/index.js +1 -1
  51. package/common/middleware/web_main/index.js +2 -0
  52. package/common/middleware/web_static/index.js +2 -2
  53. package/common/middleware/web_waf/index.js +1 -1
  54. package/core/app/config.tpl.json +4 -4
  55. package/core/app/index.js +710 -534
  56. package/core/middleware/index.js +1 -9
  57. package/core/mod/config.tpl.json +1 -1
  58. package/core/model/config.tpl.json +1 -1
  59. package/core/plugin/config.tpl.json +15 -3
  60. package/core/plugin/index.js +31 -0
  61. package/core/pusher/index.js +158 -161
  62. package/core/scene/loop.js +1306 -1255
  63. package/core/store/index.js +1794 -1755
  64. package/core/store/sql.js +1488 -1464
  65. package/core/zone/bat/index.js +744 -728
  66. package/core/zone/config.tpl.json +3 -3
  67. package/core/zone/index.js +655 -616
  68. package/os.js +0 -4
  69. package/package.json +16 -16
  70. package/server.js +583 -427
  71. package/com/cmd/nlp.js +0 -525
  72. package/core/app/index copy.js +0 -611
  73. package/software.js +0 -194
  74. package/tcp.js +0 -279
package/com/cmd/nlp.js DELETED
@@ -1,525 +0,0 @@
1
- require('mm_expand');
2
- const { Nlp } = require('@nlpjs/basic');
3
-
4
- /**
5
- * 自然语言处理类
6
- */
7
- class NLP {
8
- static config = {
9
- languages: ['zh', 'en'],
10
- language: 'zh',
11
- dir: './nlp',
12
- // 模型文件
13
- model: './model.nlp',
14
- // 正则表达式文件
15
- regex: './regex.json'
16
- };
17
-
18
- /**
19
- * 构造函数
20
- * @param {Object} config - 配置参数
21
- */
22
- constructor(config) {
23
- this.config = {
24
- ...NLP.config,
25
- ...config
26
- };
27
- this._preset();
28
- }
29
- }
30
-
31
- /**
32
- * 获取模型文件路径
33
- * @returns {string} 模型文件路径
34
- */
35
- NLP.prototype.getModelFile = function () {
36
- return this.config.model.fullname(this.config.dir);
37
- };
38
-
39
- /**
40
- * 获取正则表达式文件路径
41
- * @returns {string} 正则表达式文件路径
42
- */
43
- NLP.prototype.getRegexFile = function () {
44
- return this.config.regex.fullname(this.config.dir);
45
- };
46
-
47
- /**
48
- * 预设
49
- * @returns {string} 语言
50
- */
51
- NLP.prototype._preset = function () {
52
- console.log('[_init] 开始初始化NLP管理器');
53
- console.log('[_init] 配置:', JSON.stringify(this.config, null, 2));
54
-
55
- // 初始化NLP管理器
56
- this.nlp = new Nlp(this.config);
57
- console.log('[_init] NLP管理器创建成功');
58
-
59
- this.load();
60
- console.log('[_init] 初始化完成');
61
- };
62
-
63
- /**
64
- * 加载模型
65
- * @param {string} model_file - 模型文件路径
66
- * @param {string} regex_file - 正则表达式文件路径
67
- */
68
- NLP.prototype.load = function (model_file, regex_file) {
69
- this.loadRegex(regex_file);
70
- this.loadModel(model_file);
71
- };
72
-
73
- /**
74
- * 加载模型
75
- * @param {string} file - 模型文件路径
76
- */
77
- NLP.prototype.loadModel = async function (file) {
78
- let f = file || this.getModelFile();
79
- console.log(`[loadModel] 加载模型文件: ${f}`);
80
- let json = f.loadJson();
81
- if (json) {
82
- this.nlp.fromJSON(json);
83
- }
84
- };
85
-
86
- /**
87
- * 加载正则表达式
88
- * @param {string} file - 正则表达式文件路径
89
- */
90
- NLP.prototype.loadRegex = function (file) {
91
- let f = file || this.getRegexFile();
92
- console.log(`[loadRegex] 加载正则表达式文件: ${f}`);
93
- this.regex = f.loadJson();
94
- };
95
-
96
- /**
97
- * 保存模型
98
- * @param {string} model_file - 模型文件路径
99
- * @param {string} regex_file - 正则表达式文件路径
100
- */
101
- NLP.prototype.save = function (model_file, regex_file) {
102
- console.log(`[save] 开始保存模型...`);
103
- // 保存模型
104
- this.saveModel(model_file);
105
- console.log(`[save] 模型保存成功`);
106
-
107
- // 保存正则表达式
108
- this.saveRegex(regex_file);
109
- console.log(`[save] 正则表达式保存成功`);
110
- };
111
-
112
- /**
113
- * 保存模型
114
- * @param {string} file - 模型文件路径
115
- */
116
- NLP.prototype.saveModel = function (file) {
117
- let model = this.nlp.toJSON();
118
- let f = file || this.getModelFile();
119
- console.log(`[saveModel] 保存模型文件: ${f}`);
120
- f.saveJson(model);
121
- };
122
-
123
- /**
124
- * 保存正则表达式
125
- * @param {string} file - 正则表达式文件路径
126
- */
127
- NLP.prototype.saveRegex = function (file) {
128
- let f = file || this.getRegexFile();
129
- console.log(`[saveRegex] 保存正则表达式文件: ${f}`);
130
- f.saveJson(this.regex);
131
- };
132
-
133
- /**
134
- * 添加文档
135
- * @param {string} doc - 文档
136
- * @param {string} intent - 指令
137
- */
138
- NLP.prototype.addDocument = function (doc, intent) {
139
- console.log(`[addDocument] 添加文档: "${doc}" -> "${intent}"`);
140
- console.log(`[addDocument] 语言配置: ${this.config.language}`);
141
-
142
- try {
143
- // 明确指定locale
144
- this.nlp.addDocument(this.config.language, doc, intent);
145
- console.log(`[addDocument] 文档添加完成`);
146
- } catch (error) {
147
- console.log(`[addDocument] 添加文档失败:`, error.message);
148
- throw error;
149
- }
150
- };
151
-
152
- /**
153
- * 添加命名实体识别文本
154
- * @param {string} name - 命名实体名称
155
- * @param {string} value - 值
156
- * @param {Array} langs - 语言数组
157
- * @param {Array} values - 值数组
158
- */
159
- NLP.prototype.addNamedEntityText = function (name, value, langs, values) {
160
- this.nlp.addNamedEntityText(name, value, langs, values);
161
- };
162
-
163
- /**
164
- * 处理文本
165
- * @param {string} text - 输入文本
166
- * @returns {Object} 响应对象
167
- */
168
- NLP.prototype.process = async function (text) {
169
- let res = await this.nlp.process(this.config.language, text);
170
- return res;
171
- };
172
-
173
- /**
174
- * 提取参数词汇
175
- * @param {Object} params - 参数
176
- * @returns {Array} 词汇数组
177
- */
178
- NLP.prototype._extractWords = function (params) {
179
- let words = [];
180
-
181
- if (!Array.isArray(params)) {
182
- return words;
183
- }
184
-
185
- for (let i = 0; i < params.length; i++) {
186
- let param = params[i];
187
- if (!param || !param.example) {
188
- continue;
189
- }
190
- let arr = param.example.split(';');
191
- for (let n = 0; n < arr.length; n++) {
192
- let text = arr[n];
193
- let values = text.split('|');
194
- // 提取所有值,而不仅仅是第一个
195
- for (let k = 0; k < values.length; k++) {
196
- let value = values[k].trim();
197
- if (value) {
198
- words.push({
199
- name: param.name,
200
- value,
201
- values
202
- });
203
- }
204
- }
205
- }
206
- }
207
- return words;
208
- };
209
-
210
- /**
211
- * 训练文档
212
- * @param {string} intent - 指令
213
- * @param {Array} examples - 示例数组
214
- * @param {Array} words - 词汇数组
215
- */
216
- NLP.prototype._trainDocuments = function (intent, examples, words) {
217
- if (!Array.isArray(examples)) {
218
- return;
219
- }
220
-
221
- for (const tpl of examples) {
222
- if (tpl.indexOf('](') === -1) {
223
- let docs = this.toDocs(tpl, words);
224
- for (const doc of docs) {
225
- this.addDocument(doc, intent);
226
- }
227
- }
228
- else {
229
- this.addDocument(tpl, intent);
230
- }
231
- }
232
- };
233
-
234
- /**
235
- * 训练命名实体识别模型
236
- * @param {Array} words - 词汇数组
237
- * @param {string} lang - 语言
238
- */
239
- NLP.prototype._trainNamedEntities = function (words, lang) {
240
- if (!Array.isArray(words)) {
241
- return;
242
- }
243
-
244
- for (const word of words) {
245
- let { name, value, values } = word;
246
- this.addNamedEntityText(name, value, [lang], values);
247
- }
248
- };
249
-
250
- /**
251
- * 训练模型
252
- * @param {string} intent - 指令,格式xxx_xxx
253
- * @param {string} example - 示例组
254
- * @param {Object} params - 参数
255
- */
256
- NLP.prototype.train = async function (intent, example, params) {
257
- console.log(`[train] 开始训练模型,意图: "${intent}"`);
258
- console.log(`[train] 示例组: "${example}"`);
259
- console.log(`[train] 参数:`, JSON.stringify(params, null, 2));
260
-
261
- // 参数校验
262
- if (typeof intent !== 'string') {
263
- throw new TypeError('指令必须是字符串');
264
- }
265
- if (typeof example !== 'string') {
266
- throw new TypeError('示例组必须是字符串');
267
- }
268
- if (!Array.isArray(params)) {
269
- throw new TypeError('参数必须是数组');
270
- }
271
-
272
- try {
273
- let lang = this.config.language;
274
- let examples = example.split(';');
275
- console.log(`[train] 拆分后的示例:`, examples);
276
-
277
- let words = this._extractWords(params);
278
- console.log(`[train] 提取的词汇:`, words);
279
-
280
- this._trainDocuments(intent, examples, words);
281
- console.log(`[train] 文档训练完成`);
282
-
283
- this._trainNamedEntities(words, lang);
284
- console.log(`[train] 命名实体训练完成`);
285
-
286
- // 训练模型
287
- console.log(`[train] 开始模型训练...`);
288
- try {
289
- await this.nlp.train({
290
- trainByDomain: false,
291
- useNeural: false,
292
- log: false
293
- });
294
- console.log(`[train] 模型训练完成`);
295
- } catch (error) {
296
- // 如果训练过程中出现文件保存错误,继续执行
297
- if (error.message.includes('File cannot be written in web')) {
298
- console.log(`[train] 模型训练完成(文件保存错误已忽略)`);
299
- } else {
300
- throw error;
301
- }
302
- }
303
- } catch (error) {
304
- console.log(`[train] 训练失败:`, error.message);
305
- console.log(`[train] 错误堆栈:`, error.stack);
306
- // 异步方法返回相应类型值,这里返回undefined
307
- return undefined;
308
- }
309
- };
310
-
311
- /**
312
- * 转为文档
313
- * @param {string} tpl - 模板
314
- * @param {Array} words - 词汇数组
315
- */
316
- NLP.prototype.toDocs = function (tpl, words) {
317
- let docs = [tpl]; // 先添加原始模板
318
-
319
- // 将大白话转为训练文档,例如:“我想听邓紫棋的喜欢你”转换为“我想听[邓紫棋](singer)的[喜欢你](music_name)”
320
- // 正确的逻辑:模板包含value字段的词,替换为values中的词加上标注
321
-
322
- // 第一步:收集所有词汇的替换信息
323
- let word_replacements = [];
324
-
325
- for (let i = 0; i < words.length; i++) {
326
- let word = words[i];
327
- if (!word || !word.value) continue;
328
- let { name, value, values } = word;
329
-
330
- // 检查模板是否包含value字段的词
331
- if (!tpl.includes(value)) {
332
- continue;
333
- }
334
-
335
- let replacements = [];
336
-
337
- // 处理每个词汇的values数组
338
- for (let j = 0; j < values.length; j++) {
339
- let value_str = values[j];
340
- let value_arr = value_str.split('|');
341
-
342
- for (let k = 0; k < value_arr.length; k++) {
343
- let val = value_arr[k].trim();
344
- if (val) {
345
- replacements.push({
346
- name: name,
347
- original_value: value, // 模板中实际出现的词
348
- replacement_value: val, // 要替换成的词
349
- replacement: `[${val}](${name})`
350
- });
351
- }
352
- }
353
- }
354
-
355
- if (replacements.length > 0) {
356
- word_replacements.push(replacements);
357
- }
358
- }
359
-
360
- // 第二步:生成所有词汇值的笛卡尔积组合
361
- if (word_replacements.length > 0) {
362
- let combinations = this._generateCartesianProduct(word_replacements);
363
-
364
- for (let combination of combinations) {
365
- let doc = tpl;
366
-
367
- for (let replacement of combination) {
368
- // 将模板中的original_value替换为replacement
369
- doc = doc.replace(replacement.original_value, replacement.replacement);
370
- }
371
-
372
- if (!docs.includes(doc)) {
373
- docs.push(doc);
374
- }
375
- }
376
- }
377
-
378
- return docs;
379
- };
380
-
381
- /**
382
- * 生成笛卡尔积
383
- * @param {Array} arrays - 输入数组的数组
384
- * @returns {Array} 笛卡尔积结果
385
- */
386
- NLP.prototype._generateCartesianProduct = function (arrays) {
387
- if (arrays.length === 0) return [[]];
388
-
389
- let result = [];
390
-
391
- function cartesianHelper(arr, index, current) {
392
- if (index === arrays.length) {
393
- result.push([...current]);
394
- return;
395
- }
396
-
397
- for (let i = 0; i < arrays[index].length; i++) {
398
- current.push(arrays[index][i]);
399
- cartesianHelper(arr, index + 1, current);
400
- current.pop();
401
- }
402
- }
403
-
404
- cartesianHelper(arrays, 0, []);
405
- return result;
406
- };
407
-
408
- /**
409
- * 生成正则表达式
410
- * @returns {Object} 正则表达式对象
411
- */
412
- NLP.prototype.genRegex = function (examples) {
413
- // 生成正则表达式
414
- let regex = {};
415
- for (const example of examples) {
416
- let res = this.process(example);
417
- let intent = res.intent;
418
- if (!regex[intent]) {
419
- regex[intent] = [];
420
- }
421
- let rules = this.buildRule(example, res);
422
- regex[intent].push(...rules);
423
- }
424
- return regex;
425
- };
426
-
427
- /**
428
- * 构建正则表达式
429
- * @param {string} text - 文本
430
- * @param {Object} res - 处理结果
431
- * @returns {array} 正则表达式数组
432
- */
433
- NLP.prototype.buildRule = function (text, res) {
434
- let rules = [];
435
- for (const entity of res.entities) {
436
- let regex =
437
- rules.push({
438
- // 正则表达式
439
- regex,
440
- // 参数名
441
- props: []
442
- });
443
- }
444
- return rules;
445
- };
446
-
447
- /**
448
- * 获取正则表达式数组
449
- * @returns {array} 正则表达式数组
450
- */
451
- NLP.prototype._getRegexs = function () {
452
- let regexs = ['[a-zA-Z0-9_]+', '[\\u4e00-\\u9fa5]+', '[\\s\\S]+', '\\d+', '\\w+', '\\S+', '(.*)'];
453
- return regexs;
454
- };
455
-
456
- /**
457
- * 获取符合的正则表达式
458
- * @param {string} text - 文本
459
- * @returns {array} 符合的正则表达式数组
460
- */
461
- NLP.prototype._extractRegexs = function (text) {
462
- let regexs = this._getRegexs();
463
- let arr = [];
464
- for (const re of regexs) {
465
- let m = text.match(re);
466
- if (m) {
467
- arr.push(re);
468
- }
469
- }
470
- return arr;
471
- };
472
-
473
- /**
474
- * 通过正则表达式提取关键词
475
- * @param {string} regex - 正则表达式
476
- * @param {string} text - 文本
477
- * @returns {array} 关键词数组
478
- */
479
- NLP.prototype._extractKeywords = function (regex, text) {
480
- let matches = text.match(regex);
481
- return matches;
482
- };
483
-
484
- /**
485
- * 聊天
486
- * @param {string} text - 输入文本
487
- * @returns {Object} 响应对象
488
- */
489
- NLP.prototype.chat = async function (text) {
490
- // 先尝试能否有输出
491
- let res = await this.process(text);
492
- // 如果没有尝试正则匹配
493
- if (!res.intent) {
494
- let matches = this._tryMatches(text);
495
- }
496
- return res;
497
- };
498
-
499
- /**
500
- * 尝试匹配正则表达式
501
- * @param {string} text - 文本
502
- * @returns {array} 符合的正则表达式数组
503
- */
504
- NLP.prototype._tryMatches = function (text) {
505
- let dict = this.regex;
506
- let intent = null;
507
- let words = [];
508
- for (const key of dict) {
509
- let regexs = dict[key];
510
- for (let i = 0; i < regexs.length; i++) {
511
- let matches = this._extractKeywords(regexs[i], text);
512
- if (matches) {
513
- intent = key;
514
- words.push(...matches);
515
- break;
516
- }
517
- }
518
- }
519
- return {
520
- intent,
521
- words
522
- };
523
- };
524
-
525
- module.exports = { NLP };