@workclaw/openclaw-workclaw 1.0.335 → 1.0.337
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/packages/plugin/src/api/accounts-api.js +22 -0
- package/dist/packages/plugin/src/gateway/config-writer.js +117 -19
- package/dist/src/api/accounts-api.d.ts.map +1 -1
- package/dist/src/gateway/config-writer.d.ts +7 -8
- package/dist/src/gateway/config-writer.d.ts.map +1 -1
- package/openclaw.plugin.json +175 -1
- package/package.json +1 -1
|
@@ -18,6 +18,9 @@ async function readRequestBody(req) {
|
|
|
18
18
|
}
|
|
19
19
|
async function loadRuntimeConfig(api) {
|
|
20
20
|
const runtimeConfig = api.runtime?.config;
|
|
21
|
+
if (runtimeConfig?.current) {
|
|
22
|
+
return runtimeConfig.current();
|
|
23
|
+
}
|
|
21
24
|
if (runtimeConfig?.loadConfig) {
|
|
22
25
|
return runtimeConfig.loadConfig();
|
|
23
26
|
}
|
|
@@ -25,6 +28,25 @@ async function loadRuntimeConfig(api) {
|
|
|
25
28
|
}
|
|
26
29
|
async function writeRuntimeConfig(api, config) {
|
|
27
30
|
const runtimeConfig = api.runtime?.config;
|
|
31
|
+
const afterWrite = { mode: "none", reason: "workclaw-accounts-api" };
|
|
32
|
+
if (runtimeConfig?.mutateConfigFile) {
|
|
33
|
+
await runtimeConfig.mutateConfigFile({
|
|
34
|
+
afterWrite,
|
|
35
|
+
mutate(draft) {
|
|
36
|
+
for (const key of Object.keys(draft)) {
|
|
37
|
+
if (!(key in config)) {
|
|
38
|
+
delete draft[key];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
Object.assign(draft, JSON.parse(JSON.stringify(config)));
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (runtimeConfig?.replaceConfigFile) {
|
|
47
|
+
await runtimeConfig.replaceConfigFile(config, afterWrite);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
28
50
|
if (runtimeConfig?.writeConfigFile) {
|
|
29
51
|
await runtimeConfig.writeConfigFile(config);
|
|
30
52
|
return;
|
|
@@ -27,16 +27,94 @@ async function writeConfigFile(newConfig, cfg, log) {
|
|
|
27
27
|
try {
|
|
28
28
|
const runtime = getWorkclawRuntime();
|
|
29
29
|
const configApi = runtime.config;
|
|
30
|
+
const afterWrite = {
|
|
31
|
+
mode: "auto",
|
|
32
|
+
reason: "workclaw-full-config-write"
|
|
33
|
+
};
|
|
30
34
|
logger.info(`[智小途-配置] 准备写入配置 (channels/openclaw-workclaw/accounts): ${JSON.stringify(newConfig?.channels?.["openclaw-workclaw"]?.accounts, null, 2)}`);
|
|
31
35
|
logger.info(`[智小途-配置] 准备写入配置 (models): ${JSON.stringify(newConfig?.models, null, 2)}`);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
if (configApi.mutateConfigFile) {
|
|
37
|
+
const result = await configApi.mutateConfigFile({
|
|
38
|
+
mutate: (draft) => {
|
|
39
|
+
replaceObjectContents(draft, newConfig);
|
|
40
|
+
},
|
|
41
|
+
afterWrite
|
|
42
|
+
});
|
|
43
|
+
logger.info("[智小途-配置] 配置写入成功(使用 mutateConfigFile)");
|
|
44
|
+
logConfigWriteResult(result, log);
|
|
45
|
+
} else if (configApi.replaceConfigFile) {
|
|
46
|
+
const result = await configApi.replaceConfigFile(newConfig, afterWrite);
|
|
47
|
+
logger.info("[智小途-配置] 配置写入成功(使用 replaceConfigFile)");
|
|
48
|
+
logConfigWriteResult(result, log);
|
|
49
|
+
} else if (configApi.writeConfigFile) {
|
|
50
|
+
await configApi.writeConfigFile(newConfig);
|
|
51
|
+
logger.info("[智小途-配置] 配置写入成功(使用 writeConfigFile - 兼容模式)");
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error("No config write API available");
|
|
54
|
+
}
|
|
55
|
+
replaceObjectContents(cfg, newConfig);
|
|
35
56
|
} catch (err) {
|
|
36
57
|
logger.error(`[智小途-配置] 写入配置失败: ${String(err)}`);
|
|
37
58
|
throw err;
|
|
38
59
|
}
|
|
39
60
|
}
|
|
61
|
+
async function mutateConfigPatch(cfg, mutate, log, reason = "workclaw-config-patch") {
|
|
62
|
+
const runtime = getWorkclawRuntime();
|
|
63
|
+
const configApi = runtime.config;
|
|
64
|
+
const afterWrite = {
|
|
65
|
+
mode: "none",
|
|
66
|
+
reason
|
|
67
|
+
};
|
|
68
|
+
if (configApi.mutateConfigFile) {
|
|
69
|
+
const result = await configApi.mutateConfigFile({
|
|
70
|
+
mutate,
|
|
71
|
+
afterWrite
|
|
72
|
+
});
|
|
73
|
+
logConfigWriteResult(result, log);
|
|
74
|
+
} else {
|
|
75
|
+
const nextConfig = cloneConfig(cfg);
|
|
76
|
+
mutate(nextConfig);
|
|
77
|
+
if (configApi.replaceConfigFile) {
|
|
78
|
+
const result = await configApi.replaceConfigFile(nextConfig, afterWrite);
|
|
79
|
+
logConfigWriteResult(result, log);
|
|
80
|
+
} else if (configApi.writeConfigFile) {
|
|
81
|
+
await configApi.writeConfigFile(nextConfig);
|
|
82
|
+
} else {
|
|
83
|
+
throw new Error("No config write API available");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
mutate(cfg);
|
|
87
|
+
}
|
|
88
|
+
function replaceObjectContents(target, source) {
|
|
89
|
+
if (target == null || typeof target !== "object")
|
|
90
|
+
return;
|
|
91
|
+
if (source == null || typeof source !== "object")
|
|
92
|
+
return;
|
|
93
|
+
for (const key of Object.keys(target)) {
|
|
94
|
+
if (!(key in source)) {
|
|
95
|
+
delete target[key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const clonedSource = cloneConfig(source);
|
|
99
|
+
Object.assign(target, clonedSource);
|
|
100
|
+
}
|
|
101
|
+
function cloneConfig(value) {
|
|
102
|
+
return JSON.parse(JSON.stringify(value));
|
|
103
|
+
}
|
|
104
|
+
function logConfigWriteResult(result, log) {
|
|
105
|
+
if (!result)
|
|
106
|
+
return;
|
|
107
|
+
const serialized = JSON.stringify(result);
|
|
108
|
+
log?.info?.(`[智小途-配置] 写入结果: ${serialized}`);
|
|
109
|
+
const mode = result.followUp?.mode ?? result.afterWrite?.mode;
|
|
110
|
+
if (mode === "restart") {
|
|
111
|
+
log?.info?.("[智小途-配置] 框架要求重启后生效");
|
|
112
|
+
} else if (mode === "auto") {
|
|
113
|
+
log?.info?.("[智小途-配置] 框架将按自动策略评估 reload/restart");
|
|
114
|
+
} else if (mode === "none") {
|
|
115
|
+
log?.info?.("[智小途-配置] 配置按 none 策略写入,不请求自动重启");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
40
118
|
function loadOpenConversationId(accountId, userId) {
|
|
41
119
|
const statePath = getStateFilePath();
|
|
42
120
|
const key = `${accountId}:${userId}`;
|
|
@@ -109,35 +187,55 @@ async function initWorkclawAgent(params, cfg, log) {
|
|
|
109
187
|
const workclawCfg = cfg?.channels?.[PLUGIN_ID];
|
|
110
188
|
if (!workclawCfg)
|
|
111
189
|
return;
|
|
190
|
+
const accountId = params.accountId || "default";
|
|
191
|
+
const existingApiKey = cfg.models?.providers?.[DEFAULT_PROVIDER]?.apiKey;
|
|
192
|
+
const shouldWriteApiKey = Boolean(
|
|
193
|
+
params.apiKey && !(existingApiKey && typeof existingApiKey === "object" && existingApiKey.type)
|
|
194
|
+
);
|
|
112
195
|
if (params.apiKey) {
|
|
113
|
-
const existingApiKey = cfg.models?.providers?.[DEFAULT_PROVIDER]?.apiKey;
|
|
114
196
|
if (existingApiKey && typeof existingApiKey === "object" && existingApiKey.type) {
|
|
115
197
|
logger.info(`[智小途-智能体] apiKey 是 SecretRef (type=${existingApiKey.type}),跳过覆盖`);
|
|
116
198
|
} else {
|
|
117
|
-
if (!cfg.models)
|
|
118
|
-
cfg.models = {};
|
|
119
|
-
if (!cfg.models.providers)
|
|
120
|
-
cfg.models.providers = {};
|
|
121
|
-
if (!cfg.models.providers[DEFAULT_PROVIDER])
|
|
122
|
-
cfg.models.providers[DEFAULT_PROVIDER] = {};
|
|
123
|
-
cfg.models.providers[DEFAULT_PROVIDER].apiKey = params.apiKey;
|
|
124
199
|
logger.info(`[智小途-智能体] apiKey 已设置(明文值)`);
|
|
125
200
|
}
|
|
126
201
|
}
|
|
127
202
|
if (params.agentId) {
|
|
128
|
-
const accountId = params.accountId || "default";
|
|
129
|
-
const accounts = workclawCfg.accounts ?? {};
|
|
130
|
-
workclawCfg.accounts = accounts;
|
|
131
|
-
if (!accounts[accountId])
|
|
132
|
-
accounts[accountId] = {};
|
|
133
|
-
accounts[accountId].agentId = params.agentId;
|
|
134
203
|
logger.info(`[智小途-智能体] agentId=${params.agentId} 已设置 accountId=${accountId}`);
|
|
135
204
|
}
|
|
136
205
|
if (params.userId) {
|
|
137
|
-
workclawCfg.userId = params.userId;
|
|
138
206
|
logger.info(`[智小途-智能体] userId=${params.userId} 已设置`);
|
|
139
207
|
}
|
|
140
|
-
await
|
|
208
|
+
await mutateConfigPatch(
|
|
209
|
+
cfg,
|
|
210
|
+
(draft) => {
|
|
211
|
+
if (!draft.channels)
|
|
212
|
+
draft.channels = {};
|
|
213
|
+
if (!draft.channels[PLUGIN_ID])
|
|
214
|
+
draft.channels[PLUGIN_ID] = {};
|
|
215
|
+
const draftWorkclawCfg = draft.channels[PLUGIN_ID];
|
|
216
|
+
if (shouldWriteApiKey) {
|
|
217
|
+
if (!draft.models)
|
|
218
|
+
draft.models = {};
|
|
219
|
+
if (!draft.models.providers)
|
|
220
|
+
draft.models.providers = {};
|
|
221
|
+
if (!draft.models.providers[DEFAULT_PROVIDER])
|
|
222
|
+
draft.models.providers[DEFAULT_PROVIDER] = {};
|
|
223
|
+
draft.models.providers[DEFAULT_PROVIDER].apiKey = params.apiKey;
|
|
224
|
+
}
|
|
225
|
+
if (params.agentId) {
|
|
226
|
+
const accounts = draftWorkclawCfg.accounts ?? {};
|
|
227
|
+
draftWorkclawCfg.accounts = accounts;
|
|
228
|
+
if (!accounts[accountId])
|
|
229
|
+
accounts[accountId] = {};
|
|
230
|
+
accounts[accountId].agentId = params.agentId;
|
|
231
|
+
}
|
|
232
|
+
if (params.userId) {
|
|
233
|
+
draftWorkclawCfg.userId = params.userId;
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
log,
|
|
237
|
+
"workclaw-init-agent"
|
|
238
|
+
);
|
|
141
239
|
logger.info(`[智小途-智能体] 所有配置已持久化`);
|
|
142
240
|
} catch (err) {
|
|
143
241
|
logger.error(`[智小途-智能体] 初始化失败: ${String(err)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts-api.d.ts","sourceRoot":"","sources":["../../../src/api/accounts-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"accounts-api.d.ts","sourceRoot":"","sources":["../../../src/api/accounts-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AA0F5D,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,iBAAiB,IAC/C,KAAK,GAAG,EAAE,KAAK,GAAG,mBA2FjC"}
|
|
@@ -13,10 +13,11 @@ interface ConfigLogger {
|
|
|
13
13
|
/**
|
|
14
14
|
* 将新配置写入 openclaw.json 文件。
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
* 1.
|
|
18
|
-
* 2.
|
|
19
|
-
* 3.
|
|
16
|
+
* 正确的实现方式:
|
|
17
|
+
* 1. 优先使用 mutateConfigFile(官方推荐)
|
|
18
|
+
* 2. 必须指定 afterWrite 策略
|
|
19
|
+
* 3. 处理返回值中的 followUp 意图
|
|
20
|
+
* 4. 使用深合并策略处理嵌套属性
|
|
20
21
|
*/
|
|
21
22
|
export declare function writeConfigFile(newConfig: any, cfg: any, log?: ConfigLogger): Promise<void>;
|
|
22
23
|
/**
|
|
@@ -67,11 +68,9 @@ export declare function saveWorkClawUserId(accountId: string, userId: string | n
|
|
|
67
68
|
*/
|
|
68
69
|
export declare function saveWorkClawAgentId(accountId: string, agentId: string | number, cfg: any, log?: ConfigLogger): Promise<void>;
|
|
69
70
|
/**
|
|
70
|
-
*
|
|
71
|
+
* 将 apiKey 保存到模型配置并持久化到 openclaw.json。
|
|
71
72
|
*
|
|
72
|
-
*
|
|
73
|
-
* 否则会重新解析环境变量(如 ${MODEL_API_KEY})
|
|
74
|
-
* 并可能覆盖运行时配置中已解析的值。
|
|
73
|
+
* 使用局部 mutate,避免把整份运行时快照回写到配置文件。
|
|
75
74
|
*/
|
|
76
75
|
export declare function saveWorkClawApiKey(apiKey: string, cfg: any, log?: ConfigLogger): Promise<void>;
|
|
77
76
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../../src/gateway/config-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;
|
|
1
|
+
{"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../../src/gateway/config-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AA2ED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,GAAG,EACd,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAyCf;AAoHD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAavF;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAmBf;AA4DD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE;IACN,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,EACD,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
package/openclaw.plugin.json
CHANGED
|
@@ -35,9 +35,21 @@
|
|
|
35
35
|
"description": "智小途企业通讯平台",
|
|
36
36
|
"schema": {
|
|
37
37
|
"type": "object",
|
|
38
|
-
"additionalProperties":
|
|
38
|
+
"additionalProperties": false,
|
|
39
39
|
"required": ["appKey", "appSecret"],
|
|
40
40
|
"properties": {
|
|
41
|
+
"enabled": {
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"title": "是否启用"
|
|
44
|
+
},
|
|
45
|
+
"baseUrl": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"title": "接口地址"
|
|
48
|
+
},
|
|
49
|
+
"websocketUrl": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"title": "WebSocket 地址"
|
|
52
|
+
},
|
|
41
53
|
"appKey": {
|
|
42
54
|
"type": "string",
|
|
43
55
|
"description": "智小途应用 Key",
|
|
@@ -47,6 +59,168 @@
|
|
|
47
59
|
"type": "string",
|
|
48
60
|
"description": "智小途应用 Secret",
|
|
49
61
|
"title": "应用 Secret"
|
|
62
|
+
},
|
|
63
|
+
"agentId": {
|
|
64
|
+
"title": "默认智能体 ID",
|
|
65
|
+
"anyOf": [
|
|
66
|
+
{
|
|
67
|
+
"type": "string"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"type": "number"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"userId": {
|
|
75
|
+
"title": "默认用户 ID",
|
|
76
|
+
"anyOf": [
|
|
77
|
+
{
|
|
78
|
+
"type": "string"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "number"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"localIp": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"title": "本地 IP"
|
|
88
|
+
},
|
|
89
|
+
"requestTimeout": {
|
|
90
|
+
"type": "integer",
|
|
91
|
+
"minimum": 1,
|
|
92
|
+
"title": "请求超时毫秒"
|
|
93
|
+
},
|
|
94
|
+
"allowInsecureTls": {
|
|
95
|
+
"type": "boolean",
|
|
96
|
+
"title": "允许不安全 TLS"
|
|
97
|
+
},
|
|
98
|
+
"allowRawJsonPayload": {
|
|
99
|
+
"type": "boolean",
|
|
100
|
+
"title": "允许原始 JSON 负载"
|
|
101
|
+
},
|
|
102
|
+
"uploadUrl": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"title": "上传地址"
|
|
105
|
+
},
|
|
106
|
+
"uploadFieldName": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"title": "上传字段名"
|
|
109
|
+
},
|
|
110
|
+
"uploadHeaders": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"additionalProperties": {
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
"title": "上传请求头"
|
|
116
|
+
},
|
|
117
|
+
"uploadFormFields": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"additionalProperties": {
|
|
120
|
+
"anyOf": [
|
|
121
|
+
{
|
|
122
|
+
"type": "string"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"type": "number"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"type": "boolean"
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"title": "上传表单字段"
|
|
133
|
+
},
|
|
134
|
+
"uploadResponseUrlPath": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"title": "上传响应 URL 路径"
|
|
137
|
+
},
|
|
138
|
+
"dmPolicy": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"enum": ["open"],
|
|
141
|
+
"title": "私聊策略"
|
|
142
|
+
},
|
|
143
|
+
"allowFrom": {
|
|
144
|
+
"type": "array",
|
|
145
|
+
"title": "允许发送者",
|
|
146
|
+
"items": {
|
|
147
|
+
"anyOf": [
|
|
148
|
+
{
|
|
149
|
+
"type": "string"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"type": "number"
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"mediaMaxMb": {
|
|
158
|
+
"type": "number",
|
|
159
|
+
"exclusiveMinimum": 0,
|
|
160
|
+
"title": "媒体大小上限"
|
|
161
|
+
},
|
|
162
|
+
"accounts": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"title": "账户配置",
|
|
165
|
+
"additionalProperties": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"properties": {
|
|
169
|
+
"enabled": {
|
|
170
|
+
"type": "boolean"
|
|
171
|
+
},
|
|
172
|
+
"name": {
|
|
173
|
+
"type": "string"
|
|
174
|
+
},
|
|
175
|
+
"agentId": {
|
|
176
|
+
"anyOf": [
|
|
177
|
+
{
|
|
178
|
+
"type": "string"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"type": "number"
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
"userId": {
|
|
186
|
+
"anyOf": [
|
|
187
|
+
{
|
|
188
|
+
"type": "string"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"type": "number"
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
"openConversationId": {
|
|
196
|
+
"type": "string"
|
|
197
|
+
},
|
|
198
|
+
"dmPolicy": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"enum": ["open"]
|
|
201
|
+
},
|
|
202
|
+
"allowFrom": {
|
|
203
|
+
"type": "array",
|
|
204
|
+
"items": {
|
|
205
|
+
"anyOf": [
|
|
206
|
+
{
|
|
207
|
+
"type": "string"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"type": "number"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"mediaMaxMb": {
|
|
216
|
+
"type": "number",
|
|
217
|
+
"exclusiveMinimum": 0
|
|
218
|
+
},
|
|
219
|
+
"allowInsecureTls": {
|
|
220
|
+
"type": "boolean"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
50
224
|
}
|
|
51
225
|
}
|
|
52
226
|
},
|