mm_os 4.2.9 → 4.3.0

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 (2) hide show
  1. package/ai.js +130 -0
  2. package/package.json +3 -2
package/ai.js ADDED
@@ -0,0 +1,130 @@
1
+ /**
2
+ * ai.js
3
+ * AI模块管理类
4
+ * 负责加载并初始化mm_ai模块,桥接前后端AI对话
5
+ */
6
+
7
+ const path = require('path');
8
+ const fs = require('fs');
9
+
10
+ async function tryRequire() {
11
+ try {
12
+ return require('mm_ai');
13
+ } catch (error) {
14
+ console.log('mm_ai模块未安装,尝试安装...');
15
+ await require('npm').exec('npm i mm_ai');
16
+ return require('mm_ai');
17
+ }
18
+ }
19
+
20
+ /**
21
+ * 覆写 Agent.prototype.filterMessages,将消息中的 /file/ 路径转为 LLM 可读格式
22
+ * @param {Array} messages - 消息记录
23
+ * @returns {Array} 转换后的消息记录
24
+ */
25
+ function overrideFilterMessages(messages) {
26
+ if (!messages || !messages.length) {
27
+ return messages;
28
+ }
29
+ var result = [];
30
+ for (var i = 0; i < messages.length; i++) {
31
+ var msg = messages[i];
32
+ if (msg.role !== 'user' || typeof msg.content !== 'string') {
33
+ result.push(msg);
34
+ continue;
35
+ }
36
+ var content = msg.content;
37
+ var parts = [];
38
+ var last_idx = 0;
39
+ var file_re = /!?\[([^\]]*)\]\((\/file\/[^)]+)\)/g;
40
+ var match;
41
+ while ((match = file_re.exec(content)) !== null) {
42
+ if (match.index > last_idx) {
43
+ parts.push({ type: 'text', text: content.substring(last_idx, match.index) });
44
+ }
45
+ var alt = match[1] || '文件';
46
+ var file_url = match[2];
47
+ var rel_path = '.' + file_url;
48
+ var full_path = rel_path.fullname($.run_path);
49
+ if (fs.existsSync(full_path)) {
50
+ var ext = path.extname(full_path).toLowerCase();
51
+ var img_exts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg'];
52
+ var text_exts = ['.txt', '.js', '.ts', '.py', '.json', '.md', '.css', '.html', '.xml',
53
+ '.yaml', '.yml', '.ini', '.cfg', '.conf', '.sh', '.bat', '.ps1', '.sql',
54
+ '.java', '.go', '.rs', '.rb', '.php', '.c', '.cpp', '.h', '.hpp',
55
+ '.log', '.csv', '.env', '.toml'];
56
+ if (img_exts.indexOf(ext) !== -1) {
57
+ try {
58
+ var img_data = fs.readFileSync(full_path);
59
+ var base64 = img_data.toString('base64');
60
+ var mime = 'image/' + (ext === '.jpg' ? 'jpeg' : ext.replace('.', ''));
61
+ parts.push({ type: 'image_url', image_url: { url: 'data:' + mime + ';base64,' + base64 } });
62
+ } catch (e) {
63
+ parts.push({ type: 'text', text: '[图片加载失败: ' + alt + ']' });
64
+ }
65
+ } else if (text_exts.indexOf(ext) !== -1) {
66
+ try {
67
+ var file_content = fs.readFileSync(full_path, 'utf-8');
68
+ parts.push({ type: 'text', text: '--- ' + alt + ' ---\n' + file_content + '\n---' });
69
+ } catch (e) {
70
+ parts.push({ type: 'text', text: '[文件读取失败: ' + alt + ']' });
71
+ }
72
+ } else {
73
+ parts.push({ type: 'text', text: '[文件: ' + alt + ']' });
74
+ }
75
+ } else {
76
+ parts.push({ type: 'text', text: match[0] });
77
+ }
78
+ last_idx = match.index + match[0].length;
79
+ }
80
+ if (last_idx < content.length) {
81
+ parts.push({ type: 'text', text: content.substring(last_idx) });
82
+ }
83
+ var user_content;
84
+ if (parts.length === 0) {
85
+ user_content = content;
86
+ } else if (parts.length === 1 && parts[0].type === 'text') {
87
+ user_content = parts[0].text;
88
+ } else {
89
+ user_content = parts;
90
+ }
91
+ result.push({ ...msg, content: user_content });
92
+ }
93
+ return result;
94
+ }
95
+
96
+ /**
97
+ * 初始化AI模块
98
+ * 创建MM_ai实例(mm_ai内部已注册chat:in事件处理)
99
+ * @param {object} server 服务器实例
100
+ */
101
+ async function initAI(server) {
102
+ // 检查AI开关
103
+ if (!server.config.sys || !server.config.sys.ai) {
104
+ return null;
105
+ }
106
+
107
+ try {
108
+ var mod = await tryRequire();
109
+ if (!mod || !mod.MM_ai) {
110
+ server.log('warn', 'mm_ai模块加载失败');
111
+ return null;
112
+ }
113
+
114
+ // 覆写 Agent.prototype.filterMessages 处理文件路径
115
+ var { Agent } = require('mm_ai/core/agent/index.js');
116
+ Agent.prototype.filterMessages = overrideFilterMessages;
117
+
118
+ var ai = new mod.MM_ai(server.config, server);
119
+ server.ai = ai;
120
+ await ai.run();
121
+ return ai;
122
+ } catch (error) {
123
+ server.log('error', 'AI模块加载失败', error);
124
+ return null;
125
+ }
126
+ }
127
+
128
+ module.exports = {
129
+ initAI
130
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mm_os",
3
3
  "description": "MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。",
4
- "version": "4.2.9",
4
+ "version": "4.3.0",
5
5
  "main": "index.js",
6
6
  "keywords": [
7
7
  "AI",
@@ -79,6 +79,7 @@
79
79
  "core/",
80
80
  "ulits/",
81
81
  "tcp.js",
82
- "software.js"
82
+ "software.js",
83
+ "ai.js"
83
84
  ]
84
85
  }