mm_os 4.2.4 → 4.2.7

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 (77) 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/api/script.tpl.js +24 -24
  12. package/com/cmd/config.tpl.json +48 -122
  13. package/com/cmd/drive.js +176 -1548
  14. package/com/cmd/index.js +287 -1066
  15. package/com/cmd/job/config.json +66 -0
  16. package/com/cmd/job/index.js +241 -0
  17. package/com/cmd/job/test.js +188 -0
  18. package/com/cmd/script.tpl.js +12 -33
  19. package/com/db/drive.js +2206 -2019
  20. package/com/db/index.js +241 -242
  21. package/com/event/config.tpl.json +3 -1
  22. package/com/event/drive.js +3 -1
  23. package/com/event/index.js +73 -46
  24. package/com/event/script.tpl.js +22 -22
  25. package/com/mqtt/config.tpl.json +16 -8
  26. package/com/mqtt/drive.js +696 -676
  27. package/com/mqtt/index.js +1012 -822
  28. package/com/mqtt/index.test.js +503 -0
  29. package/com/mqtt/mm_mqtt.js +446 -420
  30. package/com/mqtt/script.tpl.js +3 -7
  31. package/com/nav/drive.js +7 -7
  32. package/com/nav/index.js +228 -231
  33. package/com/param/index.js +19 -17
  34. package/com/pendant/index.js +467 -441
  35. package/com/socket/drive.js +679 -651
  36. package/com/socket/index.js +94 -48
  37. package/com/sql/drive.js +1283 -1259
  38. package/com/sql/index.js +152 -150
  39. package/com/static/drive.js +1 -1
  40. package/com/static/index.js +232 -226
  41. package/com/static/script.tpl.js +25 -25
  42. package/com/task/drive.js +428 -405
  43. package/com/task/index.js +154 -148
  44. package/com/task/script.tpl.js +37 -34
  45. package/com/template/drive.js +1 -1
  46. package/com/template/index.js +141 -138
  47. package/com.js +87 -6
  48. package/common/middleware/web_after/index.js +5 -11
  49. package/common/middleware/web_base/index.js +1 -1
  50. package/common/middleware/web_cors/index.js +1 -1
  51. package/common/middleware/web_error/index.js +131 -119
  52. package/common/middleware/web_error/middleware.json +2 -1
  53. package/common/middleware/web_logger/index.js +1 -1
  54. package/common/middleware/web_main/index.js +2 -0
  55. package/common/middleware/web_static/index.js +2 -2
  56. package/common/middleware/web_waf/index.js +1 -1
  57. package/core/app/config.tpl.json +4 -4
  58. package/core/app/index.js +710 -534
  59. package/core/middleware/index.js +1 -9
  60. package/core/mod/config.tpl.json +1 -1
  61. package/core/model/config.tpl.json +1 -1
  62. package/core/plugin/config.tpl.json +15 -3
  63. package/core/plugin/index.js +31 -0
  64. package/core/pusher/index.js +158 -161
  65. package/core/scene/loop.js +1306 -1255
  66. package/core/store/index.js +1794 -1755
  67. package/core/store/sql.js +1488 -1464
  68. package/core/zone/bat/index.js +744 -728
  69. package/core/zone/config.tpl.json +3 -3
  70. package/core/zone/index.js +655 -616
  71. package/os.js +0 -4
  72. package/package.json +16 -16
  73. package/server.js +583 -427
  74. package/com/cmd/nlp.js +0 -525
  75. package/core/app/index copy.js +0 -611
  76. package/software.js +0 -194
  77. package/tcp.js +0 -279
package/com/api/index.js CHANGED
@@ -1,198 +1,196 @@
1
- const Manager = require('mm_machine').Manager;
2
- const Drive = require('./drive');
3
-
4
- /**
5
- * Api接口类
6
- * @class
7
- * @augments {Manager}
8
- */
9
- class Api extends Manager {
10
- /**
11
- * 配置参数
12
- * @type {object}
13
- */
14
- static config = {
15
- /**
16
- * 名称
17
- * @type {string}
18
- */
19
- name: '',
20
- /**
21
- * 标题
22
- * @type {string}
23
- */
24
- title: 'API接口',
25
- /**
26
- * 描述
27
- * @type {string}
28
- */
29
- description: '这是API接口管理器',
30
- /**
31
- * 检索文件名
32
- * @type {string}
33
- */
34
- filename: 'api.json',
35
- /**
36
- * 模板目录
37
- * @type {string}
38
- */
39
- tpl_dir: __dirname,
40
- /**
41
- * 基础目录
42
- * @type {string}
43
- */
44
- base_dir: '../common/api'.fullname(__dirname),
45
- /**
46
- * 自定义目录,加载项目自定义资源
47
- * @type {string}
48
- */
49
- dir: './app'.fullname(),
50
- /**
51
- * 搜索模式 dir按目录搜索 | file按文件名搜索
52
- * @type {string}
53
- */
54
- search_way: 'dir',
55
- /**
56
- * 是否懒加载
57
- * @type {boolean}
58
- */
59
- lazy_load: true,
60
- /**
61
- * 模式
62
- * 1.生产模式,改变文件不会重新加载
63
- * 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
64
- * 3.热重载模式,改变配置文件都会加载配置和脚本
65
- * 4.重载模式,执行完后重新加载脚本,避免变量污染
66
- * 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
67
- * @type {number}
68
- */
69
- mode: 3
70
- };
71
-
72
- /**
73
- * 构造函数
74
- * @param {object} config 配置参数
75
- * @param {object} parent 父级模块
76
- */
77
- constructor(config, parent) {
78
- super({ ...Api.config, ...config }, parent);
79
- }
80
- }
81
-
82
- /**
83
- * Api驱动类
84
- */
85
- Api.prototype.Drive = Drive;
86
-
87
- /**
88
- * 接口排序
89
- */
90
- Api.prototype._sort = function () {
91
- let sort_key = this.config.sort_key || 'sort';
92
- let infos = this.getInfos();
93
- infos.sort((o1, o2) => {
94
- let m1 = this.getMod(o1.name);
95
- let m2 = this.getMod(o2.name);
96
- var p1 = m1.config.path;
97
- var p2 = m2.config.path;
98
- var n = p2.length - p1.length;
99
- if (n) {
100
- return n;
101
- } else {
102
- return m1.config[sort_key] - m2.config[sort_key];
103
- }
104
- });
105
- };
106
-
107
- /**
108
- * 匹配目标
109
- * @param {string} str 目标
110
- * @param {string} pattern 模式
111
- * @returns {boolean} 是否匹配
112
- */
113
- Api.prototype.isMatch = function (str, pattern) {
114
- if (str === pattern) {
115
- return true;
116
- } else if (pattern.startsWith('*')) {
117
- let clean = pattern.replaceAll('*', '');
118
- if (pattern.endsWith('*')) {
119
- return str.indexOf(clean) !== -1;
120
- } else {
121
- return str.endsWith(clean);
122
- }
123
- } else if (pattern.endsWith('*')) {
124
- let clean = pattern.replaceAll('*', '');
125
- return str.startsWith(clean);
126
- }
127
- else {
128
- return false;
129
- }
130
- };
131
-
132
- /**
133
- * 执行Api
134
- * @param {object} ctx 请求上下文
135
- * @param {object} db 数据管理器
136
- * @returns {object | string} 返回一个对象或字符串
137
- */
138
- Api.prototype.run = async function (ctx, db = {}) {
139
- let path = ctx.request.path;
140
- let infos = this.getInfos();
141
-
142
- for (var i = 0, info; info = infos[i++];) {
143
- if (info.state === 1) {
144
- let mod = this.getMod(info.name);
145
- if (mod && this.isMatch(path, mod.config.path)) {
146
- if (!mod.isLoaded()) {
147
- await mod.call('loadScript');
148
- }
149
- var ret = await mod.run(ctx, db);
150
- if (this.config.mode > 4) {
151
- mod.do('reload');
152
- }
153
- if (ret) {
154
- db.ret = ret;
155
- break;
156
- }
157
- }
158
- }
159
- }
160
- return db.ret;
161
- };
162
-
163
- /**
164
- * @module 导出API类
165
- */
166
- exports.Api = Api;
167
-
168
-
169
- /**
170
- * 创建全局管理器
171
- */
172
- if (!$.pool.api) {
173
- $.pool.api = {};
174
- }
175
-
176
- /**
177
- * API管理器,用于创建缓存
178
- * @param {string} scope 作用域
179
- * @param {string} title 标题
180
- * @returns {object} 返回一个缓存类
181
- */
182
- function apiAdmin(scope, title) {
183
- var sc = scope || $.val.scope + '';
184
- var obj = $.pool.api[sc];
185
- if (!obj) {
186
- $.pool.api[sc] = new Api({
187
- name: sc,
188
- title: title
189
- });
190
- obj = $.pool.api[sc];
191
- }
192
- return obj;
193
- }
194
-
195
- /**
196
- * @module 导出API管理器
197
- */
198
- $.admin.api = apiAdmin;
1
+ const Manager = require("mm_machine").Manager;
2
+ const Drive = require("./drive");
3
+
4
+ /**
5
+ * Api接口类
6
+ * @class
7
+ * @augments {Manager}
8
+ */
9
+ class Api extends Manager {
10
+ /**
11
+ * 配置参数
12
+ * @type {object}
13
+ */
14
+ static config = {
15
+ /**
16
+ * 名称
17
+ * @type {string}
18
+ */
19
+ name: "",
20
+ /**
21
+ * 标题
22
+ * @type {string}
23
+ */
24
+ title: "API接口",
25
+ /**
26
+ * 描述
27
+ * @type {string}
28
+ */
29
+ description: "这是API接口管理器",
30
+ /**
31
+ * 检索文件名
32
+ * @type {string}
33
+ */
34
+ filename: "api.json",
35
+ /**
36
+ * 模板目录
37
+ * @type {string}
38
+ */
39
+ tpl_dir: __dirname,
40
+ /**
41
+ * 基础目录
42
+ * @type {string}
43
+ */
44
+ base_dir: "../common/api".fullname(__dirname),
45
+ /**
46
+ * 自定义目录,加载项目自定义资源
47
+ * @type {string}
48
+ */
49
+ dir: "./app".fullname(),
50
+ /**
51
+ * 搜索模式 dir按目录搜索 | file按文件名搜索
52
+ * @type {string}
53
+ */
54
+ search_way: "dir",
55
+ /**
56
+ * 是否懒加载
57
+ * @type {boolean}
58
+ */
59
+ lazy_load: true,
60
+ /**
61
+ * 模式
62
+ * 1.生产模式,改变文件不会重新加载
63
+ * 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
64
+ * 3.热重载模式,改变配置文件都会加载配置和脚本
65
+ * 4.重载模式,执行完后重新加载脚本,避免变量污染
66
+ * 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
67
+ * @type {number}
68
+ */
69
+ mode: process.env.NODE_ENV === "production" ? 1 : 3,
70
+ };
71
+
72
+ /**
73
+ * 构造函数
74
+ * @param {object} config 配置参数
75
+ * @param {object} parent 父级模块
76
+ */
77
+ constructor(config, parent) {
78
+ super({ ...Api.config, ...config }, parent);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Api驱动类
84
+ */
85
+ Api.prototype.Drive = Drive;
86
+
87
+ /**
88
+ * 接口排序
89
+ */
90
+ Api.prototype._sort = function () {
91
+ let sort_key = this.config.sort_key || "sort";
92
+ let infos = this.getInfos();
93
+ infos.sort((o1, o2) => {
94
+ let m1 = this.getMod(o1.name);
95
+ let m2 = this.getMod(o2.name);
96
+ var p1 = m1.config.path;
97
+ var p2 = m2.config.path;
98
+ var n = p2.length - p1.length;
99
+ if (n) {
100
+ return n;
101
+ } else {
102
+ return m1.config[sort_key] - m2.config[sort_key];
103
+ }
104
+ });
105
+ };
106
+
107
+ /**
108
+ * 匹配目标
109
+ * @param {string} str 目标
110
+ * @param {string} pattern 模式
111
+ * @returns {boolean} 是否匹配
112
+ */
113
+ Api.prototype.isMatch = function (str, pattern) {
114
+ if (str === pattern) {
115
+ return true;
116
+ } else if (pattern.startsWith("*")) {
117
+ let clean = pattern.replaceAll("*", "");
118
+ if (pattern.endsWith("*")) {
119
+ return str.indexOf(clean) !== -1;
120
+ } else {
121
+ return str.endsWith(clean);
122
+ }
123
+ } else if (pattern.endsWith("*")) {
124
+ let clean = pattern.replaceAll("*", "");
125
+ return str.startsWith(clean);
126
+ } else {
127
+ return false;
128
+ }
129
+ };
130
+
131
+ /**
132
+ * 执行Api
133
+ * @param {object} ctx 请求上下文
134
+ * @param {object} db 数据管理器
135
+ * @returns {object | string} 返回一个对象或字符串
136
+ */
137
+ Api.prototype.run = async function (ctx, db = {}) {
138
+ let path = ctx.request.path;
139
+ let infos = this.getInfos();
140
+
141
+ for (var i = 0, info; (info = infos[i++]);) {
142
+ if (info.state === 1) {
143
+ let mod = this.getMod(info.name);
144
+ if (mod && this.isMatch(path, mod.config.path)) {
145
+ if (!mod.isLoaded()) {
146
+ await mod.do("load");
147
+ }
148
+ var ret = await mod.run(ctx, db);
149
+ if (this.config.mode > 4) {
150
+ mod.do("reload");
151
+ }
152
+ if (ret) {
153
+ db.ret = ret;
154
+ break;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ return db.ret;
160
+ };
161
+
162
+ /**
163
+ * @module 导出API类
164
+ */
165
+ exports.Api = Api;
166
+
167
+ /**
168
+ * 创建全局管理器
169
+ */
170
+ if (!$.pool.api) {
171
+ $.pool.api = {};
172
+ }
173
+
174
+ /**
175
+ * API管理器,用于创建缓存
176
+ * @param {string} scope 作用域
177
+ * @param {string} title 标题
178
+ * @returns {object} 返回一个缓存类
179
+ */
180
+ function apiAdmin(scope, title) {
181
+ var sc = scope || $.val.scope + "";
182
+ var obj = $.pool.api[sc];
183
+ if (!obj) {
184
+ $.pool.api[sc] = new Api({
185
+ name: sc,
186
+ title: title,
187
+ });
188
+ obj = $.pool.api[sc];
189
+ }
190
+ return obj;
191
+ }
192
+
193
+ /**
194
+ * @module 导出API管理器
195
+ */
196
+ $.admin.api = apiAdmin;
@@ -1,32 +1,32 @@
1
1
 
2
- /**
3
- * 接口主函数
4
- * @param {object} ctx HTTP上下文
5
- * @param {object} db 数据管理器,如: { next: async function{}, ret: {} }
6
- * @returns {object} 执行结果
7
- */
8
- async function main(ctx, db) {
9
- // 获取请求参数
10
- var req = ctx.request;
11
- var {
12
- query,
13
- body
14
- } = req;
15
- // return "hello world" + JSON.stringify(body);
2
+ module.exports = {
3
+ /**
4
+ * 接口主函数
5
+ * @param {object} ctx HTTP上下文
6
+ * @param {object} db 数据管理器,如: { next: async function{}, ret: {} }
7
+ * @returns {object} 执行结果
8
+ */
9
+ async main(ctx, db) {
10
+ // 获取请求参数
11
+ var req = ctx.request;
12
+ var {
13
+ query,
14
+ body
15
+ } = req;
16
+ // return "hello world" + JSON.stringify(body);
16
17
 
17
- // 操作sql模板
18
- var m = query.method;
19
- if (m === 'add') {
18
+ // 操作sql模板
19
+ var m = query.method;
20
+ if (m === 'add') {
20
21
 
21
- } else if (m === 'del') {
22
+ } else if (m === 'del') {
22
23
 
23
- } else if (m === 'set') {
24
+ } else if (m === 'set') {
24
25
 
25
- } else {
26
+ } else {
26
27
 
28
+ }
29
+ var ret = await this.sql.run(query, body, db);
30
+ return ret;
27
31
  }
28
- var ret = await this.sql.run(query, body, db);
29
- return ret;
30
32
  };
31
-
32
- exports.main = main;
@@ -1,122 +1,48 @@
1
- {
2
- // 指令(意图)名称, 用于动态增删改配置
3
- "name": "{name || 'demo'}",
4
- // 标题, 用于查询指令时
5
- "title": "{title || '指令标题'}",
6
- // 描述, 用于介绍该指令的作用
7
- "description": "{description || '暂无描述'}",
8
- // 示例(训练样本), 用于提示AI该指令的格式,多个样本用分号隔开
9
- "example": "{example || '播放一首周杰伦的歌;听音乐,邓紫棋的喜欢你;听歌邓紫棋的《喜欢你》;我想听邓紫棋的《光年之外》'}",
10
- // 指令分组, 可以将特有的指令分一个组, 方便用户查询
11
- "group": "{group || 'default'}",
12
- // 指令分类, 例如: 查询服务类query、执行类execute、管理类admin、控制类control、播放类play、游戏类game
13
- "type": "{type || 'control'}",
14
- // 时态, 分before之前、check验证、main主要、render渲染、after之后五个时态
15
- "tense": "{tense || 'main'}",
16
- // 文件名, 用于驱动脚本, 实现业务
17
- "main": "{main || './index.js'}",
18
- // 指令状态, 1为启用, 0为禁用
19
- "state": 1,
20
- // 执行顺序, 数值越小的指令越优先执行
21
- "sort": 100,
22
- // 匹配关键词组, 当聊天中出现其中一个关键词则会执行该指令
23
- "match": ["播放", "听", "听歌"],
24
- // 结束会话 当值为1时,指令触发并返回了内容后不再执行其他指令。为0时,指令触发仍继续执行其他指令
25
- "end": 1,
26
- // 不包含关键词, 如果匹配后, 出现不应该包含的关键词, 则不会执行指令
27
- "not": [],
28
- // 移除关键词, 如果聊天中含这些词, 将会被剔除在执行指令
29
- "remove": [],
30
- // 提取特定词, 如果聊天中含有特定词, 会被提取出来再执行指令
31
- "extract": [],
32
- // 阶段(1-9),可用于补全参数fill、过滤参数filter、校验参数check、更新参数update
33
- "stage": [
34
- // 第一阶段
35
- {
36
- // 方式 fill为补全,会将本次消息加入到msg.form[name]中
37
- "mode": "fill",
38
- /* 参数, 用于执行指令行为前抽取关键词进行验证, 然后再执行指令 */
39
- "param": [
40
- {
41
- // 参数名称, 用于提交数据时
42
- "name": "music_name",
43
- // 参数标题, 用于提示用户什么参数错误
44
- "title": "音乐名称",
45
- // 是否必填, 1为必填, 0为选填
46
- "required": 1,
47
- // 参数描述, 用于提示AI该参数的作用
48
- "desc": "要播放的音乐名称",
49
- // 示例, 用于提示该参数的格式,多个示例用分号隔开,别名用竖线隔开
50
- "example": "画;喜欢你;告白气球;来自天堂的魔鬼;",
51
- // 抽验顺序, 越小的越优先验证, 并且抽取后排列在前
52
- "sort": 10,
53
- // 抽取/校验格式, 如果格式不符合, 则表示验证未通过,提示用户
54
- "format": "/[a-zA-Z0-9_\u4e00-\u9fa5]+/g",
55
- // 缺少参数提示, 如果不包含该参数, 则做出的提示
56
- "not_tip": "音乐名称是?",
57
- // 错误提示, 提示用户补充参数时, 补充参数错误时做出的提示
58
- "error_tip": "音乐名称不正确",
59
- // 校验/抽取的函数名, 通过函数的方式抽取/校验参数
60
- "func_name": "",
61
- // 同义词, 用于训练NLP, 多个同义词用分号隔开
62
- "aliases": "音乐;歌曲"
63
- },
64
- {
65
- // 参数名称, 用于提交数据时
66
- "name": "author",
67
- // 参数标题, 用于提示用户什么参数错误
68
- "title": "音乐作者",
69
- // 是否必填, 1为必填, 0为选填
70
- "required": 0,
71
- // 参数描述, 用于提示AI该参数的作用
72
- "desc": "写这首歌的人",
73
- // 示例, 用于提示该参数的格式,多个示例用分号隔开,别名用竖线隔开
74
- "example": "周杰伦|杰伦;邓紫棋|GEM",
75
- // 抽验顺序, 越小的越优先验证, 并且抽取后排列在前
76
- "sort": 10,
77
- // 抽取/校验格式, 如果格式不符合, 则表示验证未通过,提示用户
78
- "format": "/[a-zA-Z0-9_\u4e00-\u9fa5]+/g",
79
- // 缺少参数提示, 如果不包含该参数, 则做出的提示
80
- "not_tip": "音乐作者是?",
81
- // 错误提示, 提示用户补充参数时, 补充参数错误时做出的提示
82
- "error_tip": "音乐作者不正确",
83
- // 校验/抽取的函数名, 通过函数的方式抽取/校验参数
84
- "func_name": "",
85
- // 同义词, 用于训练NLP, 多个同义词用分号隔开
86
- "aliases": "作者;作词人"
87
- },
88
- {
89
- // 参数名称, 用于提交数据时
90
- "name": "singer",
91
- // 参数标题, 用于提示用户什么参数错误
92
- "title": "歌手",
93
- // 是否必填, 1为必填, 0为选填
94
- "required": 1,
95
- // 参数描述, 用于提示AI该参数的作用
96
- "desc": "唱歌的人",
97
- // 示例, 用于提示该参数的格式,多个示例用分号隔开,别名用竖线隔开
98
- "example": "周杰伦|杰伦;邓紫棋|GEM|G.E.M.",
99
- // 抽验顺序, 越小的越优先验证, 并且抽取后排列在前
100
- "sort": 10,
101
- // 抽取/校验格式, 如果格式不符合, 则表示验证未通过,提示用户
102
- "format": "/[a-zA-Z0-9_\u4e00-\u9fa5]+/g",
103
- // 缺少参数提示, 如果不包含该参数, 则做出的提示
104
- "not_tip": "歌手是?",
105
- // 错误提示, 提示用户补充参数时, 补充参数错误时做出的提示
106
- "error_tip": "歌手不正确",
107
- // 校验/抽取的函数名, 通过函数的方式抽取/校验参数
108
- "func_name": "",
109
- // 同义词, 用于训练NLP, 多个同义词用分号隔开
110
- "aliases": "歌手;唱作者"
111
- }
112
- ]
113
- },
114
- // 第二阶段
115
- {
116
- // 方式 update为更新,会将本次消息替换掉msg.form[name]的值
117
- "mode": "update",
118
- // 验证参数集
119
- "param": []
120
- }
121
- ]
122
- }
1
+ {
2
+ // 指令名称, 用于动态增删改配置
3
+ "name": "{name || 'demo'}",
4
+ // 标题, 用于查询指令时
5
+ "title": "{title || '指令标题'}",
6
+ // 描述, 用于介绍该指令的作用
7
+ "description": "{description || '暂无描述'}",
8
+ // 文件名, 用于驱动脚本, 实现业务
9
+ "main": "{main || './index.js'}",
10
+ // 指令状态, 1为启用, 0为禁用
11
+ "state": 1,
12
+ // 时态, before之前、main主要、after之后
13
+ "tense": "{tense || 'main'}",
14
+ // 匹配关键词组, 消息内容包含任一关键词则触发指令
15
+ "match": ["触发词1", "触发词2"],
16
+ // 排除关键词组, 包含任一排除词则不触发指令
17
+ "not": [],
18
+ // 执行顺序, 数值越小越优先执行
19
+ "sort": 100,
20
+ // 结束标志: 1为匹配后不再执行后续指令, 0为继续执行
21
+ "end": 1,
22
+ // 指令参数, 类似于驱动脚本中使用 openAI 工具时传递参数
23
+ "params": {
24
+ "properties": {
25
+ "tracking_no": {
26
+ "type": "string",
27
+ "description": "快递单号",
28
+ "example": "1234567890",
29
+ "question": "快递单号多少?",
30
+ "error": "请输入正确的快递单号",
31
+ "match": "{数字}{英文}",
32
+ "default": null
33
+ },
34
+ "company": {
35
+ "type": "string",
36
+ "description": "快递公司",
37
+ "example": "顺丰",
38
+ "question": "快递公司多少?",
39
+ "error": "请输入正确的快递公司",
40
+ "match": "{中文}快递",
41
+ "enum": ["顺丰", "圆通", "中通", "韵达", "申通"],
42
+ "remove": ["快递"],
43
+ "default": null
44
+ }
45
+ },
46
+ "required": []
47
+ }
48
+ }