mm_os 4.2.8 → 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.
- package/ai.js +130 -0
- package/core/plugin/index.js +297 -328
- 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/core/plugin/index.js
CHANGED
|
@@ -1,328 +1,297 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
*
|
|
52
|
-
* @
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
case '
|
|
183
|
-
return this.
|
|
184
|
-
case '
|
|
185
|
-
return this.
|
|
186
|
-
case '
|
|
187
|
-
return this.
|
|
188
|
-
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
*
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* 安装插件
|
|
300
|
-
* @private
|
|
301
|
-
*/
|
|
302
|
-
Plugin.prototype._install = async function () {
|
|
303
|
-
return this;
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* 安装插件
|
|
308
|
-
*/
|
|
309
|
-
Plugin.prototype.install = async function () {
|
|
310
|
-
return this._install();
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* 卸载插件
|
|
315
|
-
* @private
|
|
316
|
-
*/
|
|
317
|
-
Plugin.prototype._uninstall = async function () {
|
|
318
|
-
return this;
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* 卸载插件
|
|
323
|
-
*/
|
|
324
|
-
Plugin.prototype.uninstall = async function () {
|
|
325
|
-
return this._uninstall();
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
exports.Plugin = Plugin;
|
|
1
|
+
const { Drive } = require('mm_machine');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 插件基类
|
|
5
|
+
* 负责管理插件的生命周期、资源加载和依赖管理
|
|
6
|
+
*/
|
|
7
|
+
class Plugin extends Drive {
|
|
8
|
+
static config = {
|
|
9
|
+
// 插件名称
|
|
10
|
+
name: '',
|
|
11
|
+
// 插件标题
|
|
12
|
+
title: '插件',
|
|
13
|
+
// 插件描述
|
|
14
|
+
description: '介绍插件的作用',
|
|
15
|
+
// 插件版本
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
// 用于什么应用
|
|
18
|
+
app: 'tool',
|
|
19
|
+
// 作者
|
|
20
|
+
author: 'qww',
|
|
21
|
+
// 主文件
|
|
22
|
+
main: './index.js',
|
|
23
|
+
// git仓库地址
|
|
24
|
+
git: '',
|
|
25
|
+
// 依赖的npm模块
|
|
26
|
+
dependencies: [],
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* 构造函数
|
|
30
|
+
* @param {object} config 配置参数
|
|
31
|
+
* @param {object} parent 父对象
|
|
32
|
+
*/
|
|
33
|
+
constructor(config, parent) {
|
|
34
|
+
super({ ...Plugin.config, ...(config || {}) }, parent);
|
|
35
|
+
this.options = {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 获取模板目录
|
|
41
|
+
* @returns {string} 模板目录
|
|
42
|
+
*/
|
|
43
|
+
Plugin.prototype.getTplDir = function () {
|
|
44
|
+
return __dirname;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 初始化核心
|
|
49
|
+
* @param {object} app 应用实例
|
|
50
|
+
* @param {object} eventer 事件管理器
|
|
51
|
+
* @param {object} logger 日志管理器
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
Plugin.prototype._initCore = async function (app, eventer, logger) {
|
|
55
|
+
// 初始化依赖项
|
|
56
|
+
if (logger) {
|
|
57
|
+
this.setLogger(logger);
|
|
58
|
+
}
|
|
59
|
+
if (eventer) {
|
|
60
|
+
this.getEventer = function () {
|
|
61
|
+
return eventer;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (app) {
|
|
65
|
+
this.getApp = function () {
|
|
66
|
+
return app;
|
|
67
|
+
};
|
|
68
|
+
this._db = app.db;
|
|
69
|
+
this._cache = app.cache;
|
|
70
|
+
this._filer = app.filer;
|
|
71
|
+
}
|
|
72
|
+
// // 初始化管理
|
|
73
|
+
// await this._initManager();
|
|
74
|
+
// // 加载资源
|
|
75
|
+
// await this._loadSources();
|
|
76
|
+
// // 初始化资源
|
|
77
|
+
// await this._initSources();
|
|
78
|
+
// 初始化配置
|
|
79
|
+
this._initOptions();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 获取应用实例
|
|
84
|
+
* @returns {object} 应用实例
|
|
85
|
+
*/
|
|
86
|
+
Plugin.prototype.getApp = function () {
|
|
87
|
+
// 初始化资源
|
|
88
|
+
return this.getParent();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 获取插件配置
|
|
93
|
+
* @returns {object} 插件配置
|
|
94
|
+
*/
|
|
95
|
+
Plugin.prototype.getOptions = function () {
|
|
96
|
+
return this.options;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 初始化插件选项
|
|
101
|
+
* 从config.options中提取默认值,mm_machine的save/load机制负责持久化
|
|
102
|
+
*/
|
|
103
|
+
Plugin.prototype._initOptions = function () {
|
|
104
|
+
this.options = this.getConfigOptions();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 转换数字类型值
|
|
109
|
+
* @param {*} value 原始值
|
|
110
|
+
* @returns {number} 转换后的值
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
Plugin.prototype._convertNumber = function (value) {
|
|
114
|
+
if (value === 'null') return 0;
|
|
115
|
+
return Number(value || '0');
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 转换布尔类型值
|
|
120
|
+
* @param {*} value 原始值
|
|
121
|
+
* @returns {boolean} 转换后的值
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
Plugin.prototype._convertBoolean = function (value) {
|
|
125
|
+
if (!value) return false;
|
|
126
|
+
if (typeof value === 'boolean') return value;
|
|
127
|
+
if (typeof value === 'string') {
|
|
128
|
+
return value === '1' || value === 'true';
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 转换对象类型值
|
|
135
|
+
* @param {*} value 原始值
|
|
136
|
+
* @returns {object} 转换后的值
|
|
137
|
+
* @private
|
|
138
|
+
*/
|
|
139
|
+
Plugin.prototype._convertObject = function (value) {
|
|
140
|
+
if (value === 'null') return {};
|
|
141
|
+
return value.toJSON ? value.toJSON() : {};
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 转换数组类型值
|
|
146
|
+
* @param {*} value 原始值
|
|
147
|
+
* @returns {Array} 转换后的值
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
Plugin.prototype._convertArray = function (value) {
|
|
151
|
+
if (value === 'null') return [];
|
|
152
|
+
return value.toJSON ? value.toJSON() : [];
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* 转换字符串类型值
|
|
157
|
+
* @param {*} value 原始值
|
|
158
|
+
* @returns {string} 转换后的值
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
Plugin.prototype._convertString = function (value) {
|
|
162
|
+
if (value === 'null') return null;
|
|
163
|
+
return value || '';
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 转换单个配置项的值
|
|
168
|
+
* @param {object} option 配置项
|
|
169
|
+
* @returns {*} 转换后的值
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
Plugin.prototype._convertOptionValue = function (option) {
|
|
173
|
+
var val = option.value;
|
|
174
|
+
if (val === 'null') return null;
|
|
175
|
+
|
|
176
|
+
var type = option.type;
|
|
177
|
+
switch (type) {
|
|
178
|
+
case 'number':
|
|
179
|
+
return this._convertNumber(val);
|
|
180
|
+
case 'boolean':
|
|
181
|
+
return this._convertBoolean(val);
|
|
182
|
+
case 'object':
|
|
183
|
+
return this._convertObject(val);
|
|
184
|
+
case 'array':
|
|
185
|
+
return this._convertArray(val);
|
|
186
|
+
case 'string':
|
|
187
|
+
return this._convertString(val);
|
|
188
|
+
default:
|
|
189
|
+
return val;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 获取配置参数
|
|
195
|
+
* @returns {object} 返回配置参数
|
|
196
|
+
*/
|
|
197
|
+
Plugin.prototype.getConfigOptions = function () {
|
|
198
|
+
var op = this.config.options || [];
|
|
199
|
+
var dict = {};
|
|
200
|
+
for (var i = 0; i < op.length; i++) {
|
|
201
|
+
var o = op[i];
|
|
202
|
+
dict[o.name] = this._convertOptionValue(o);
|
|
203
|
+
}
|
|
204
|
+
return dict;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 设计配置
|
|
209
|
+
* @param {object} body 配置参数
|
|
210
|
+
*/
|
|
211
|
+
Plugin.prototype.designOptions = function (body) {
|
|
212
|
+
var cg = this.config;
|
|
213
|
+
if (Array.isArray(body)) {
|
|
214
|
+
cg.options = body;
|
|
215
|
+
} else {
|
|
216
|
+
var options = cg.options || [];
|
|
217
|
+
var option = options.getObj({
|
|
218
|
+
name: body.name,
|
|
219
|
+
});
|
|
220
|
+
if (option) {
|
|
221
|
+
Object.assign(option, body);
|
|
222
|
+
} else {
|
|
223
|
+
options.push(body);
|
|
224
|
+
}
|
|
225
|
+
cg.options = options;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 保存配置
|
|
231
|
+
* 更新options字典和config.options数组中的值,并通过mm_machine的save()持久化
|
|
232
|
+
* @param {object} options 配置参数
|
|
233
|
+
*/
|
|
234
|
+
Plugin.prototype.saveOptions = function (options) {
|
|
235
|
+
this.options = options;
|
|
236
|
+
var config_options = this.config.options;
|
|
237
|
+
if (config_options) {
|
|
238
|
+
for (var i = 0; i < config_options.length; i++) {
|
|
239
|
+
var o = config_options[i];
|
|
240
|
+
if (o.name in options) {
|
|
241
|
+
o.value = options[o.name];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
this.save();
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* 获取模型
|
|
250
|
+
* @param {string} type 模型类型
|
|
251
|
+
* @returns {object} 返回获取到的模型
|
|
252
|
+
*/
|
|
253
|
+
Drive.prototype.getModel = function (type) {
|
|
254
|
+
let model = { ...this.config };
|
|
255
|
+
let dir = this.getDir();
|
|
256
|
+
let l = $.slash;
|
|
257
|
+
let app_name = dir.between('app' + l, l);
|
|
258
|
+
let plugin_name = dir.between('plugin' + l, l);
|
|
259
|
+
let name = dir.basename();
|
|
260
|
+
model.app = app_name;
|
|
261
|
+
model.plugin = plugin_name;
|
|
262
|
+
model.name = model.name || name;
|
|
263
|
+
model.path = '/' + app_name + '/' + name;
|
|
264
|
+
return model;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 安装插件
|
|
269
|
+
* @private
|
|
270
|
+
*/
|
|
271
|
+
Plugin.prototype._install = async function () {
|
|
272
|
+
return this;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* 安装插件
|
|
277
|
+
*/
|
|
278
|
+
Plugin.prototype.install = async function () {
|
|
279
|
+
return this._install();
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* 卸载插件
|
|
284
|
+
* @private
|
|
285
|
+
*/
|
|
286
|
+
Plugin.prototype._uninstall = async function () {
|
|
287
|
+
return this;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* 卸载插件
|
|
292
|
+
*/
|
|
293
|
+
Plugin.prototype.uninstall = async function () {
|
|
294
|
+
return this._uninstall();
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
exports.Plugin = Plugin;
|
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.
|
|
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
|
}
|