@wu529778790/open-im 1.6.2 → 1.6.3-beta.2
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/adapters/registry.d.ts +1 -1
- package/dist/adapters/registry.js +23 -18
- package/dist/commands/handler.d.ts +1 -1
- package/dist/commands/handler.js +10 -8
- package/dist/config-web-page-i18n.d.ts +4 -0
- package/dist/config-web-page-i18n.js +4 -0
- package/dist/config-web-page-script.js +16 -5
- package/dist/config-web-page-template.js +5 -0
- package/dist/config-web.d.ts +7 -0
- package/dist/config-web.js +60 -2
- package/dist/config-web.test.js +9 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.js +29 -1
- package/dist/dingtalk/event-handler.d.ts +1 -1
- package/dist/dingtalk/event-handler.js +7 -5
- package/dist/feishu/event-handler.d.ts +1 -1
- package/dist/feishu/event-handler.js +8 -6
- package/dist/hook/permission-server.d.ts +1 -0
- package/dist/hook/permission-server.js +13 -7
- package/dist/hook/permission-server.test.d.ts +1 -0
- package/dist/hook/permission-server.test.js +12 -0
- package/dist/index.js +7 -10
- package/dist/manager.js +2 -1
- package/dist/qq/event-handler.d.ts +1 -1
- package/dist/qq/event-handler.js +6 -4
- package/dist/qq/event-handler.test.js +7 -0
- package/dist/service-control.d.ts +1 -0
- package/dist/service-control.js +26 -7
- package/dist/service-control.test.d.ts +1 -0
- package/dist/service-control.test.js +36 -0
- package/dist/shared/ai-task.js +128 -104
- package/dist/shared/ai-task.test.d.ts +1 -0
- package/dist/shared/ai-task.test.js +69 -0
- package/dist/telegram/event-handler.d.ts +1 -1
- package/dist/telegram/event-handler.js +8 -6
- package/dist/wechat/event-handler.d.ts +1 -1
- package/dist/wechat/event-handler.js +8 -6
- package/dist/wework/event-handler.d.ts +1 -1
- package/dist/wework/event-handler.js +8 -6
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Config } from '../config.js';
|
|
2
2
|
import type { ToolAdapter } from './tool-adapter.interface.js';
|
|
3
3
|
export declare function initAdapters(config: Config): void;
|
|
4
4
|
export declare function getAdapter(aiCommand: string): ToolAdapter | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getConfiguredAiCommands } from '../config.js';
|
|
1
2
|
import { ClaudeAdapter } from './claude-adapter.js';
|
|
2
3
|
import { ClaudeSDKAdapter } from './claude-sdk-adapter.js';
|
|
3
4
|
import { CursorAdapter } from './cursor-adapter.js';
|
|
@@ -5,26 +6,30 @@ import { CodexAdapter } from './codex-adapter.js';
|
|
|
5
6
|
const adapters = new Map();
|
|
6
7
|
export function initAdapters(config) {
|
|
7
8
|
adapters.clear();
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
for (const aiCommand of getConfiguredAiCommands(config)) {
|
|
10
|
+
if (aiCommand === 'claude') {
|
|
11
|
+
if (config.useSdkMode) {
|
|
12
|
+
console.log('⚡ 启用 Claude Agent SDK 模式 - 进程内执行,响应更快');
|
|
13
|
+
adapters.set('claude', new ClaudeSDKAdapter());
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.log('🚀 使用标准 Claude 适配器');
|
|
17
|
+
adapters.set('claude', new ClaudeAdapter(config.claudeCliPath, {
|
|
18
|
+
useProcessPool: true,
|
|
19
|
+
idleTimeoutMs: 2 * 60 * 1000,
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
continue;
|
|
12
23
|
}
|
|
13
|
-
|
|
14
|
-
console.log('
|
|
15
|
-
adapters.set('
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
if (aiCommand === 'cursor') {
|
|
25
|
+
console.log('🖱️ 使用 Cursor Agent CLI 适配器');
|
|
26
|
+
adapters.set('cursor', new CursorAdapter(config.cursorCliPath));
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (aiCommand === 'codex') {
|
|
30
|
+
console.log('📦 使用 Codex CLI 适配器');
|
|
31
|
+
adapters.set('codex', new CodexAdapter(config.codexCliPath));
|
|
19
32
|
}
|
|
20
|
-
}
|
|
21
|
-
else if (config.aiCommand === 'cursor') {
|
|
22
|
-
console.log('🖱️ 使用 Cursor Agent CLI 适配器');
|
|
23
|
-
adapters.set('cursor', new CursorAdapter(config.cursorCliPath));
|
|
24
|
-
}
|
|
25
|
-
else if (config.aiCommand === 'codex') {
|
|
26
|
-
console.log('📦 使用 Codex CLI 适配器');
|
|
27
|
-
adapters.set('codex', new CodexAdapter(config.codexCliPath));
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
export function getAdapter(aiCommand) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Config } from '../config.js';
|
|
2
2
|
import type { SessionManager } from '../session/session-manager.js';
|
|
3
3
|
import type { RequestQueue } from '../queue/request-queue.js';
|
|
4
4
|
import { type PermissionMode } from '../permission-mode/types.js';
|
package/dist/commands/handler.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePlatformAiCommand } from '../config.js';
|
|
1
2
|
import { resolveLatestPermission, getPendingCount } from '../hook/permission-server.js';
|
|
2
3
|
import { escapePathForMarkdown } from '../shared/utils.js';
|
|
3
4
|
import { getPermissionMode, setPermissionMode } from '../permission-mode/session-mode.js';
|
|
@@ -26,7 +27,7 @@ export class CommandHandler {
|
|
|
26
27
|
if (t === '/pwd')
|
|
27
28
|
return this.handlePwd(chatId, userId);
|
|
28
29
|
if (t === '/status')
|
|
29
|
-
return this.handleStatus(chatId, userId);
|
|
30
|
+
return this.handleStatus(chatId, userId, platform);
|
|
30
31
|
if (t === '/allow' || t === '/y')
|
|
31
32
|
return this.handleAllow(chatId);
|
|
32
33
|
if (t === '/deny' || t === '/n')
|
|
@@ -109,15 +110,16 @@ export class CommandHandler {
|
|
|
109
110
|
await this.deps.sender.sendTextReply(chatId, `当前工作目录: ${escapePathForMarkdown(workDir)}`);
|
|
110
111
|
return true;
|
|
111
112
|
}
|
|
112
|
-
async handleStatus(chatId, userId) {
|
|
113
|
-
const
|
|
113
|
+
async handleStatus(chatId, userId, platform) {
|
|
114
|
+
const aiCommand = resolvePlatformAiCommand(this.deps.config, platform);
|
|
115
|
+
const version = await this.getAiVersion(aiCommand);
|
|
114
116
|
const workDir = this.deps.sessionManager.getWorkDir(userId);
|
|
115
117
|
const convId = this.deps.sessionManager.getConvId(userId);
|
|
116
|
-
const sessionId = this.deps.sessionManager.getSessionIdForConv(userId, convId,
|
|
118
|
+
const sessionId = this.deps.sessionManager.getSessionIdForConv(userId, convId, aiCommand);
|
|
117
119
|
const lines = [
|
|
118
120
|
'📊 状态:',
|
|
119
121
|
'',
|
|
120
|
-
`AI 工具: ${
|
|
122
|
+
`AI 工具: ${aiCommand}`,
|
|
121
123
|
`版本: ${version}`,
|
|
122
124
|
`工作目录: ${escapePathForMarkdown(workDir)}`,
|
|
123
125
|
`会话: ${sessionId ?? '无'}`,
|
|
@@ -169,10 +171,10 @@ export class CommandHandler {
|
|
|
169
171
|
}
|
|
170
172
|
return true;
|
|
171
173
|
}
|
|
172
|
-
getAiVersion() {
|
|
173
|
-
const cmd =
|
|
174
|
+
getAiVersion(aiCommand) {
|
|
175
|
+
const cmd = aiCommand === 'cursor'
|
|
174
176
|
? this.deps.config.cursorCliPath
|
|
175
|
-
:
|
|
177
|
+
: aiCommand === 'codex'
|
|
176
178
|
? this.deps.config.codexCliPath
|
|
177
179
|
: this.deps.config.claudeCliPath;
|
|
178
180
|
return new Promise((resolve) => {
|
|
@@ -41,6 +41,8 @@ export declare const PAGE_TEXTS: {
|
|
|
41
41
|
readonly platformsTitle: "Platforms";
|
|
42
42
|
readonly platformsHint: "Disabled platforms keep their saved values.";
|
|
43
43
|
readonly enabled: "Enabled";
|
|
44
|
+
readonly platformAiTool: "AI tool override";
|
|
45
|
+
readonly inheritDefaultAi: "Use default AI tool";
|
|
44
46
|
readonly botToken: "Bot token";
|
|
45
47
|
readonly proxy: "Proxy";
|
|
46
48
|
readonly allowedUserIds: "Allowed user IDs";
|
|
@@ -137,6 +139,8 @@ export declare const PAGE_TEXTS: {
|
|
|
137
139
|
readonly platformsTitle: "平台配置";
|
|
138
140
|
readonly platformsHint: "禁用的平台会保留已保存的值。";
|
|
139
141
|
readonly enabled: "启用";
|
|
142
|
+
readonly platformAiTool: "平台 AI 工具覆盖";
|
|
143
|
+
readonly inheritDefaultAi: "使用默认 AI 工具";
|
|
140
144
|
readonly botToken: "Bot Token";
|
|
141
145
|
readonly proxy: "代理";
|
|
142
146
|
readonly allowedUserIds: "允许的用户 ID";
|
|
@@ -41,6 +41,8 @@ export const PAGE_TEXTS = {
|
|
|
41
41
|
platformsTitle: "Platforms",
|
|
42
42
|
platformsHint: "Disabled platforms keep their saved values.",
|
|
43
43
|
enabled: "Enabled",
|
|
44
|
+
platformAiTool: "AI tool override",
|
|
45
|
+
inheritDefaultAi: "Use default AI tool",
|
|
44
46
|
botToken: "Bot token",
|
|
45
47
|
proxy: "Proxy",
|
|
46
48
|
allowedUserIds: "Allowed user IDs",
|
|
@@ -137,6 +139,8 @@ export const PAGE_TEXTS = {
|
|
|
137
139
|
platformsTitle: "\u5e73\u53f0\u914d\u7f6e",
|
|
138
140
|
platformsHint: "\u7981\u7528\u7684\u5e73\u53f0\u4f1a\u4fdd\u7559\u5df2\u4fdd\u5b58\u7684\u503c\u3002",
|
|
139
141
|
enabled: "\u542f\u7528",
|
|
142
|
+
platformAiTool: "\u5e73\u53f0 AI \u5de5\u5177\u8986\u76d6",
|
|
143
|
+
inheritDefaultAi: "\u4f7f\u7528\u9ed8\u8ba4 AI \u5de5\u5177",
|
|
140
144
|
botToken: "Bot Token",
|
|
141
145
|
proxy: "\u4ee3\u7406",
|
|
142
146
|
allowedUserIds: "\u5141\u8bb8\u7684\u7528\u6237 ID",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
2
|
-
{ key: "telegram", label: "Telegram", fields: ["botToken", "proxy", "allowedUserIds"], testFields: ["botToken", "proxy"] },
|
|
3
|
-
{ key: "feishu", label: "Feishu", fields: ["appId", "appSecret", "allowedUserIds"], testFields: ["appId", "appSecret"] },
|
|
4
|
-
{ key: "qq", label: "QQ", fields: ["appId", "secret", "allowedUserIds"], testFields: ["appId", "secret"] },
|
|
5
|
-
{ key: "wework", label: "WeWork", fields: ["corpId", "secret", "allowedUserIds"], testFields: ["corpId", "secret"] },
|
|
6
|
-
{ key: "dingtalk", label: "DingTalk", fields: ["clientId", "clientSecret", "cardTemplateId", "allowedUserIds"], testFields: ["clientId", "clientSecret"] },
|
|
2
|
+
{ key: "telegram", label: "Telegram", fields: ["aiCommand", "botToken", "proxy", "allowedUserIds"], testFields: ["botToken", "proxy"] },
|
|
3
|
+
{ key: "feishu", label: "Feishu", fields: ["aiCommand", "appId", "appSecret", "allowedUserIds"], testFields: ["appId", "appSecret"] },
|
|
4
|
+
{ key: "qq", label: "QQ", fields: ["aiCommand", "appId", "secret", "allowedUserIds"], testFields: ["appId", "secret"] },
|
|
5
|
+
{ key: "wework", label: "WeWork", fields: ["aiCommand", "corpId", "secret", "allowedUserIds"], testFields: ["corpId", "secret"] },
|
|
6
|
+
{ key: "dingtalk", label: "DingTalk", fields: ["aiCommand", "clientId", "clientSecret", "cardTemplateId", "allowedUserIds"], testFields: ["clientId", "clientSecret"] },
|
|
7
7
|
];
|
|
8
8
|
const platformKeys = platformDefinitions.map((platform) => platform.key);
|
|
9
9
|
const ids = platformDefinitions.flatMap((platform) => ["enabled", ...platform.fields].map((field) => platform.key + "-" + field)).concat(["ai-aiCommand","ai-claudeCliPath","ai-claudeWorkDir","ai-claudeSkipPermissions","ai-claudeTimeoutMs","ai-codexTimeoutMs","ai-claudeModel","ai-cursorCliPath","ai-codexCliPath","ai-codexProxy","ai-hookPort","ai-logLevel","ai-useSdkMode"]);
|
|
@@ -59,6 +59,11 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
59
59
|
setText("qq-enabled-label", t("enabled"));
|
|
60
60
|
setText("wework-enabled-label", t("enabled"));
|
|
61
61
|
setText("dingtalk-enabled-label", t("enabled"));
|
|
62
|
+
setText("telegram-aiCommand-label", t("platformAiTool"));
|
|
63
|
+
setText("feishu-aiCommand-label", t("platformAiTool"));
|
|
64
|
+
setText("qq-aiCommand-label", t("platformAiTool"));
|
|
65
|
+
setText("wework-aiCommand-label", t("platformAiTool"));
|
|
66
|
+
setText("dingtalk-aiCommand-label", t("platformAiTool"));
|
|
62
67
|
setText("telegram-botToken-label", t("botToken"));
|
|
63
68
|
setText("telegram-proxy-label", t("proxy"));
|
|
64
69
|
setText("telegram-allowedUserIds-label", t("allowedUserIds"));
|
|
@@ -86,6 +91,12 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
86
91
|
el("wework-allowedUserIds").placeholder = t("commaSeparatedIds");
|
|
87
92
|
el("dingtalk-allowedUserIds").placeholder = t("commaSeparatedIds");
|
|
88
93
|
el("dingtalk-cardTemplateId").placeholder = t("optional");
|
|
94
|
+
["telegram","feishu","qq","wework","dingtalk"].forEach((platform) => {
|
|
95
|
+
const select = el(platform + "-aiCommand");
|
|
96
|
+
if (select?.options?.length) {
|
|
97
|
+
select.options[0].text = t("inheritDefaultAi");
|
|
98
|
+
}
|
|
99
|
+
});
|
|
89
100
|
setText("ai-aiCommand-label", t("aiTool"));
|
|
90
101
|
setText("ai-claudeWorkDir-label", t("workDir"));
|
|
91
102
|
setText("ai-claudeCliPath-label", t("claudeCli"));
|
|
@@ -159,6 +159,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
159
159
|
<article class="panel" id="telegram-panel">
|
|
160
160
|
<div class="panel-head"><h3>Telegram</h3><label class="toggle"><input id="telegram-enabled" type="checkbox" /> <span id="telegram-enabled-label">Enabled</span></label></div>
|
|
161
161
|
<div class="summary" id="telegram-help" style="margin-bottom:12px;color:var(--muted);font-size:0.9em;">Get credentials: visit <a href="https://t.me/BotFather" target="_blank" style="color:var(--green);text-decoration:underline;">@BotFather</a>, send /newbot, then copy the Bot Token</div>
|
|
162
|
+
<label><span id="telegram-aiCommand-label">AI tool override</span><select id="telegram-aiCommand"><option value="">Use default AI tool</option><option value="claude">claude</option><option value="codex">codex</option><option value="cursor">cursor</option></select></label>
|
|
162
163
|
<label><span id="telegram-botToken-label">Bot token</span><input id="telegram-botToken" type="password" autocomplete="off" placeholder="123456:ABC..." /></label>
|
|
163
164
|
<label><span id="telegram-proxy-label">Proxy</span><input id="telegram-proxy" placeholder="http://127.0.0.1:7890" /></label>
|
|
164
165
|
<label><span id="telegram-allowedUserIds-label">Allowed user IDs</span><textarea id="telegram-allowedUserIds" placeholder="Comma-separated IDs"></textarea></label>
|
|
@@ -167,6 +168,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
167
168
|
<article class="panel" id="feishu-panel">
|
|
168
169
|
<div class="panel-head"><h3>Feishu</h3><label class="toggle"><input id="feishu-enabled" type="checkbox" /> <span id="feishu-enabled-label">Enabled</span></label></div>
|
|
169
170
|
<div class="summary" id="feishu-help" style="margin-bottom:12px;color:var(--muted);font-size:0.9em;">Get credentials: visit <a href="https://open.feishu.cn/" target="_blank" style="color:var(--green);text-decoration:underline;">Feishu Open Platform</a>, create an app, enable the bot, and copy the App ID / App Secret</div>
|
|
171
|
+
<label><span id="feishu-aiCommand-label">AI tool override</span><select id="feishu-aiCommand"><option value="">Use default AI tool</option><option value="claude">claude</option><option value="codex">codex</option><option value="cursor">cursor</option></select></label>
|
|
170
172
|
<label><span id="feishu-appId-label">App ID</span><input id="feishu-appId" /></label>
|
|
171
173
|
<label><span id="feishu-appSecret-label">App Secret</span><input id="feishu-appSecret" type="password" autocomplete="off" /></label>
|
|
172
174
|
<label><span id="feishu-allowedUserIds-label">Allowed user IDs</span><textarea id="feishu-allowedUserIds" placeholder="Comma-separated IDs"></textarea></label>
|
|
@@ -175,6 +177,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
175
177
|
<article class="panel" id="qq-panel">
|
|
176
178
|
<div class="panel-head"><h3>QQ</h3><label class="toggle"><input id="qq-enabled" type="checkbox" /> <span id="qq-enabled-label">Enabled</span></label></div>
|
|
177
179
|
<div class="summary" id="qq-help" style="margin-bottom:12px;color:var(--muted);font-size:0.9em;">Get credentials: visit <a href="https://bot.q.qq.com" target="_blank" style="color:var(--green);text-decoration:underline;">QQ Open Platform</a>, create a bot, and copy the App ID / App Secret</div>
|
|
180
|
+
<label><span id="qq-aiCommand-label">AI tool override</span><select id="qq-aiCommand"><option value="">Use default AI tool</option><option value="claude">claude</option><option value="codex">codex</option><option value="cursor">cursor</option></select></label>
|
|
178
181
|
<label><span id="qq-appId-label">App ID</span><input id="qq-appId" /></label>
|
|
179
182
|
<label><span id="qq-secret-label">App Secret</span><input id="qq-secret" type="password" autocomplete="off" /></label>
|
|
180
183
|
<label><span id="qq-allowedUserIds-label">Allowed user IDs</span><textarea id="qq-allowedUserIds" placeholder="Comma-separated IDs"></textarea></label>
|
|
@@ -183,6 +186,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
183
186
|
<article class="panel" id="wework-panel">
|
|
184
187
|
<div class="panel-head"><h3>WeWork</h3><label class="toggle"><input id="wework-enabled" type="checkbox" /> <span id="wework-enabled-label">Enabled</span></label></div>
|
|
185
188
|
<div class="summary" id="wework-help" style="margin-bottom:12px;color:var(--muted);font-size:0.9em;">Get credentials: visit <a href="https://work.weixin.qq.com/" target="_blank" style="color:var(--green);text-decoration:underline;">WeWork Admin Console</a>, create an app, and copy the Bot ID (Corp ID) / Secret</div>
|
|
189
|
+
<label><span id="wework-aiCommand-label">AI tool override</span><select id="wework-aiCommand"><option value="">Use default AI tool</option><option value="claude">claude</option><option value="codex">codex</option><option value="cursor">cursor</option></select></label>
|
|
186
190
|
<label><span id="wework-corpId-label">Corp ID / Bot ID</span><input id="wework-corpId" /></label>
|
|
187
191
|
<label><span id="wework-secret-label">Secret</span><input id="wework-secret" type="password" autocomplete="off" /></label>
|
|
188
192
|
<label><span id="wework-allowedUserIds-label">Allowed user IDs</span><textarea id="wework-allowedUserIds" placeholder="Comma-separated IDs"></textarea></label>
|
|
@@ -191,6 +195,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
191
195
|
<article class="panel" id="dingtalk-panel">
|
|
192
196
|
<div class="panel-head"><h3>DingTalk</h3><label class="toggle"><input id="dingtalk-enabled" type="checkbox" /> <span id="dingtalk-enabled-label">Enabled</span></label></div>
|
|
193
197
|
<div class="summary" id="dingtalk-help" style="margin-bottom:12px;color:var(--muted);font-size:0.9em;">Get credentials: create an enterprise internal app on DingTalk Open Platform, enable Stream Mode, and copy the Client ID / Client Secret</div>
|
|
198
|
+
<label><span id="dingtalk-aiCommand-label">AI tool override</span><select id="dingtalk-aiCommand"><option value="">Use default AI tool</option><option value="claude">claude</option><option value="codex">codex</option><option value="cursor">cursor</option></select></label>
|
|
194
199
|
<label><span id="dingtalk-clientId-label">Client ID / AppKey</span><input id="dingtalk-clientId" /></label>
|
|
195
200
|
<label><span id="dingtalk-clientSecret-label">Client Secret / AppSecret</span><input id="dingtalk-clientSecret" type="password" autocomplete="off" /></label>
|
|
196
201
|
<label><span id="dingtalk-cardTemplateId-label">Card template ID</span><input id="dingtalk-cardTemplateId" placeholder="Optional" /></label>
|
package/dist/config-web.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FileConfig } from "./config.js";
|
|
1
2
|
type WebFlowMode = "init" | "start" | "dev";
|
|
2
3
|
type WebFlowResult = "saved" | "cancel";
|
|
3
4
|
export interface StartedWebConfigServer {
|
|
@@ -5,6 +6,12 @@ export interface StartedWebConfigServer {
|
|
|
5
6
|
url: string;
|
|
6
7
|
waitForResult: Promise<WebFlowResult>;
|
|
7
8
|
}
|
|
9
|
+
export declare function getHealthPlatformSnapshot(file: FileConfig, env?: NodeJS.ProcessEnv): Record<string, {
|
|
10
|
+
configured: boolean;
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
healthy: boolean;
|
|
13
|
+
message?: string;
|
|
14
|
+
}>;
|
|
8
15
|
export declare function testPlatformConfig(platform: string, config: Record<string, unknown>): Promise<string>;
|
|
9
16
|
export declare function getWebConfigPort(): number;
|
|
10
17
|
export declare function getWebConfigUrl(): string;
|
package/dist/config-web.js
CHANGED
|
@@ -8,6 +8,54 @@ import { PAGE_HTML } from "./config-web-page.js";
|
|
|
8
8
|
import { getServiceStatus, startBackgroundService, stopBackgroundService } from "./service-control.js";
|
|
9
9
|
import { initWeWork, stopWeWork } from "./wework/client.js";
|
|
10
10
|
const TEST_TIMEOUT_MS = 10000;
|
|
11
|
+
export function getHealthPlatformSnapshot(file, env = process.env) {
|
|
12
|
+
const fileTelegram = file.platforms?.telegram;
|
|
13
|
+
const fileFeishu = file.platforms?.feishu;
|
|
14
|
+
const fileQQ = file.platforms?.qq;
|
|
15
|
+
const fileWework = file.platforms?.wework;
|
|
16
|
+
const fileDingtalk = file.platforms?.dingtalk;
|
|
17
|
+
const telegramBotToken = env.TELEGRAM_BOT_TOKEN ?? fileTelegram?.botToken ?? file.telegramBotToken;
|
|
18
|
+
const feishuAppId = env.FEISHU_APP_ID ?? fileFeishu?.appId ?? file.feishuAppId;
|
|
19
|
+
const feishuAppSecret = env.FEISHU_APP_SECRET ?? fileFeishu?.appSecret ?? file.feishuAppSecret;
|
|
20
|
+
const qqAppId = env.QQ_BOT_APPID ?? env.QQ_APP_ID ?? fileQQ?.appId;
|
|
21
|
+
const qqSecret = env.QQ_BOT_SECRET ?? env.QQ_SECRET ?? fileQQ?.secret;
|
|
22
|
+
const weworkCorpId = env.WEWORK_CORP_ID ?? fileWework?.corpId;
|
|
23
|
+
const weworkSecret = env.WEWORK_SECRET ?? fileWework?.secret;
|
|
24
|
+
const dingtalkClientId = env.DINGTALK_CLIENT_ID ?? fileDingtalk?.clientId;
|
|
25
|
+
const dingtalkClientSecret = env.DINGTALK_CLIENT_SECRET ?? fileDingtalk?.clientSecret;
|
|
26
|
+
return {
|
|
27
|
+
telegram: {
|
|
28
|
+
configured: !!telegramBotToken,
|
|
29
|
+
enabled: !!telegramBotToken && fileTelegram?.enabled !== false,
|
|
30
|
+
healthy: !!telegramBotToken,
|
|
31
|
+
message: telegramBotToken ? "Token configured" : "Token not configured",
|
|
32
|
+
},
|
|
33
|
+
feishu: {
|
|
34
|
+
configured: !!(feishuAppId && feishuAppSecret),
|
|
35
|
+
enabled: !!(feishuAppId && feishuAppSecret) && fileFeishu?.enabled !== false,
|
|
36
|
+
healthy: !!(feishuAppId && feishuAppSecret),
|
|
37
|
+
message: feishuAppId && feishuAppSecret ? "App ID and Secret configured" : "Missing credentials",
|
|
38
|
+
},
|
|
39
|
+
qq: {
|
|
40
|
+
configured: !!(qqAppId && qqSecret),
|
|
41
|
+
enabled: !!(qqAppId && qqSecret) && fileQQ?.enabled !== false,
|
|
42
|
+
healthy: !!(qqAppId && qqSecret),
|
|
43
|
+
message: qqAppId && qqSecret ? "App ID and Secret configured" : "Missing credentials",
|
|
44
|
+
},
|
|
45
|
+
wework: {
|
|
46
|
+
configured: !!(weworkCorpId && weworkSecret),
|
|
47
|
+
enabled: !!(weworkCorpId && weworkSecret) && fileWework?.enabled !== false,
|
|
48
|
+
healthy: !!(weworkCorpId && weworkSecret),
|
|
49
|
+
message: weworkCorpId && weworkSecret ? "Corp ID and Secret configured" : "Missing credentials",
|
|
50
|
+
},
|
|
51
|
+
dingtalk: {
|
|
52
|
+
configured: !!(dingtalkClientId && dingtalkClientSecret),
|
|
53
|
+
enabled: !!(dingtalkClientId && dingtalkClientSecret) && fileDingtalk?.enabled !== false,
|
|
54
|
+
healthy: !!(dingtalkClientId && dingtalkClientSecret),
|
|
55
|
+
message: dingtalkClientId && dingtalkClientSecret ? "Client ID and Secret configured" : "Missing credentials",
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
11
59
|
function splitCsv(value) {
|
|
12
60
|
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
13
61
|
}
|
|
@@ -40,30 +88,35 @@ function buildInitialPayload(file) {
|
|
|
40
88
|
platforms: {
|
|
41
89
|
telegram: {
|
|
42
90
|
enabled: file.platforms?.telegram?.enabled ?? Boolean(file.platforms?.telegram?.botToken),
|
|
91
|
+
aiCommand: file.platforms?.telegram?.aiCommand ?? "",
|
|
43
92
|
botToken: file.platforms?.telegram?.botToken ?? "",
|
|
44
93
|
proxy: file.platforms?.telegram?.proxy ?? "",
|
|
45
94
|
allowedUserIds: (file.platforms?.telegram?.allowedUserIds ?? []).join(", "),
|
|
46
95
|
},
|
|
47
96
|
feishu: {
|
|
48
97
|
enabled: file.platforms?.feishu?.enabled ?? Boolean(file.platforms?.feishu?.appId && file.platforms?.feishu?.appSecret),
|
|
98
|
+
aiCommand: file.platforms?.feishu?.aiCommand ?? "",
|
|
49
99
|
appId: file.platforms?.feishu?.appId ?? "",
|
|
50
100
|
appSecret: file.platforms?.feishu?.appSecret ?? "",
|
|
51
101
|
allowedUserIds: (file.platforms?.feishu?.allowedUserIds ?? []).join(", "),
|
|
52
102
|
},
|
|
53
103
|
qq: {
|
|
54
104
|
enabled: file.platforms?.qq?.enabled ?? Boolean(file.platforms?.qq?.appId && file.platforms?.qq?.secret),
|
|
105
|
+
aiCommand: file.platforms?.qq?.aiCommand ?? "",
|
|
55
106
|
appId: file.platforms?.qq?.appId ?? "",
|
|
56
107
|
secret: file.platforms?.qq?.secret ?? "",
|
|
57
108
|
allowedUserIds: (file.platforms?.qq?.allowedUserIds ?? []).join(", "),
|
|
58
109
|
},
|
|
59
110
|
wework: {
|
|
60
111
|
enabled: file.platforms?.wework?.enabled ?? Boolean(file.platforms?.wework?.corpId && file.platforms?.wework?.secret),
|
|
112
|
+
aiCommand: file.platforms?.wework?.aiCommand ?? "",
|
|
61
113
|
corpId: file.platforms?.wework?.corpId ?? "",
|
|
62
114
|
secret: file.platforms?.wework?.secret ?? "",
|
|
63
115
|
allowedUserIds: (file.platforms?.wework?.allowedUserIds ?? []).join(", "),
|
|
64
116
|
},
|
|
65
117
|
dingtalk: {
|
|
66
118
|
enabled: file.platforms?.dingtalk?.enabled ?? Boolean(file.platforms?.dingtalk?.clientId && file.platforms?.dingtalk?.clientSecret),
|
|
119
|
+
aiCommand: file.platforms?.dingtalk?.aiCommand ?? "",
|
|
67
120
|
clientId: file.platforms?.dingtalk?.clientId ?? "",
|
|
68
121
|
clientSecret: file.platforms?.dingtalk?.clientSecret ?? "",
|
|
69
122
|
cardTemplateId: file.platforms?.dingtalk?.cardTemplateId ?? "",
|
|
@@ -351,6 +404,7 @@ function toFileConfig(payload, existing) {
|
|
|
351
404
|
telegram: {
|
|
352
405
|
...existing.platforms?.telegram,
|
|
353
406
|
enabled: payload.platforms.telegram.enabled,
|
|
407
|
+
aiCommand: clean(payload.platforms.telegram.aiCommand),
|
|
354
408
|
botToken: clean(payload.platforms.telegram.botToken),
|
|
355
409
|
proxy: clean(payload.platforms.telegram.proxy),
|
|
356
410
|
allowedUserIds: splitCsv(payload.platforms.telegram.allowedUserIds),
|
|
@@ -358,6 +412,7 @@ function toFileConfig(payload, existing) {
|
|
|
358
412
|
feishu: {
|
|
359
413
|
...existing.platforms?.feishu,
|
|
360
414
|
enabled: payload.platforms.feishu.enabled,
|
|
415
|
+
aiCommand: clean(payload.platforms.feishu.aiCommand),
|
|
361
416
|
appId: clean(payload.platforms.feishu.appId),
|
|
362
417
|
appSecret: clean(payload.platforms.feishu.appSecret),
|
|
363
418
|
allowedUserIds: splitCsv(payload.platforms.feishu.allowedUserIds),
|
|
@@ -365,6 +420,7 @@ function toFileConfig(payload, existing) {
|
|
|
365
420
|
qq: {
|
|
366
421
|
...existing.platforms?.qq,
|
|
367
422
|
enabled: payload.platforms.qq.enabled,
|
|
423
|
+
aiCommand: clean(payload.platforms.qq.aiCommand),
|
|
368
424
|
appId: clean(payload.platforms.qq.appId),
|
|
369
425
|
secret: clean(payload.platforms.qq.secret),
|
|
370
426
|
allowedUserIds: splitCsv(payload.platforms.qq.allowedUserIds),
|
|
@@ -372,6 +428,7 @@ function toFileConfig(payload, existing) {
|
|
|
372
428
|
wework: {
|
|
373
429
|
...existing.platforms?.wework,
|
|
374
430
|
enabled: payload.platforms.wework.enabled,
|
|
431
|
+
aiCommand: clean(payload.platforms.wework.aiCommand),
|
|
375
432
|
corpId: clean(payload.platforms.wework.corpId),
|
|
376
433
|
secret: clean(payload.platforms.wework.secret),
|
|
377
434
|
allowedUserIds: splitCsv(payload.platforms.wework.allowedUserIds),
|
|
@@ -379,6 +436,7 @@ function toFileConfig(payload, existing) {
|
|
|
379
436
|
dingtalk: {
|
|
380
437
|
...existing.platforms?.dingtalk,
|
|
381
438
|
enabled: payload.platforms.dingtalk.enabled,
|
|
439
|
+
aiCommand: clean(payload.platforms.dingtalk.aiCommand),
|
|
382
440
|
clientId: clean(payload.platforms.dingtalk.clientId),
|
|
383
441
|
clientSecret: clean(payload.platforms.dingtalk.clientSecret),
|
|
384
442
|
cardTemplateId: clean(payload.platforms.dingtalk.cardTemplateId),
|
|
@@ -492,8 +550,8 @@ export async function startWebConfigServer(options) {
|
|
|
492
550
|
const telegramBotToken = process.env.TELEGRAM_BOT_TOKEN ?? fileTelegram?.botToken ?? file.telegramBotToken;
|
|
493
551
|
const feishuAppId = process.env.FEISHU_APP_ID ?? fileFeishu?.appId ?? file.feishuAppId;
|
|
494
552
|
const feishuAppSecret = process.env.FEISHU_APP_SECRET ?? fileFeishu?.appSecret ?? file.feishuAppSecret;
|
|
495
|
-
const qqAppId = process.env.QQ_APP_ID ?? fileQQ?.appId;
|
|
496
|
-
const qqSecret = process.env.QQ_SECRET ?? fileQQ?.secret;
|
|
553
|
+
const qqAppId = process.env.QQ_BOT_APPID ?? process.env.QQ_APP_ID ?? fileQQ?.appId;
|
|
554
|
+
const qqSecret = process.env.QQ_BOT_SECRET ?? process.env.QQ_SECRET ?? fileQQ?.secret;
|
|
497
555
|
const weworkCorpId = process.env.WEWORK_CORP_ID ?? fileWework?.corpId;
|
|
498
556
|
const weworkSecret = process.env.WEWORK_SECRET ?? fileWework?.secret;
|
|
499
557
|
const dingtalkClientId = process.env.DINGTALK_CLIENT_ID ?? fileDingtalk?.clientId;
|
package/dist/config-web.test.js
CHANGED
|
@@ -15,7 +15,7 @@ vi.mock("./wework/client.js", () => ({
|
|
|
15
15
|
initWeWork: initWeWorkMock,
|
|
16
16
|
stopWeWork: stopWeWorkMock,
|
|
17
17
|
}));
|
|
18
|
-
import { testPlatformConfig } from "./config-web.js";
|
|
18
|
+
import { getHealthPlatformSnapshot, testPlatformConfig } from "./config-web.js";
|
|
19
19
|
describe("testPlatformConfig", () => {
|
|
20
20
|
beforeEach(() => {
|
|
21
21
|
vi.clearAllMocks();
|
|
@@ -47,3 +47,11 @@ describe("testPlatformConfig", () => {
|
|
|
47
47
|
expect(globalThis.fetch).not.toHaveBeenCalled();
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
|
+
describe("getHealthPlatformSnapshot", () => {
|
|
51
|
+
it("recognizes QQ credentials from runtime env names", () => {
|
|
52
|
+
const snapshot = getHealthPlatformSnapshot({ platforms: { qq: { enabled: true } } }, { QQ_BOT_APPID: "qq-app", QQ_BOT_SECRET: "qq-secret" });
|
|
53
|
+
expect(snapshot.qq.configured).toBe(true);
|
|
54
|
+
expect(snapshot.qq.enabled).toBe(true);
|
|
55
|
+
expect(snapshot.qq.message).toContain("configured");
|
|
56
|
+
});
|
|
57
|
+
});
|
package/dist/config.d.ts
CHANGED
|
@@ -49,19 +49,23 @@ export interface Config {
|
|
|
49
49
|
platforms: {
|
|
50
50
|
telegram?: {
|
|
51
51
|
enabled: boolean;
|
|
52
|
+
aiCommand?: AiCommand;
|
|
52
53
|
proxy?: string;
|
|
53
54
|
allowedUserIds: string[];
|
|
54
55
|
};
|
|
55
56
|
feishu?: {
|
|
56
57
|
enabled: boolean;
|
|
58
|
+
aiCommand?: AiCommand;
|
|
57
59
|
allowedUserIds: string[];
|
|
58
60
|
};
|
|
59
61
|
qq?: {
|
|
60
62
|
enabled: boolean;
|
|
63
|
+
aiCommand?: AiCommand;
|
|
61
64
|
allowedUserIds: string[];
|
|
62
65
|
};
|
|
63
66
|
wechat?: {
|
|
64
67
|
enabled: boolean;
|
|
68
|
+
aiCommand?: AiCommand;
|
|
65
69
|
wsUrl?: string;
|
|
66
70
|
token?: string;
|
|
67
71
|
jwtToken?: string;
|
|
@@ -72,10 +76,12 @@ export interface Config {
|
|
|
72
76
|
};
|
|
73
77
|
wework?: {
|
|
74
78
|
enabled: boolean;
|
|
79
|
+
aiCommand?: AiCommand;
|
|
75
80
|
allowedUserIds: string[];
|
|
76
81
|
};
|
|
77
82
|
dingtalk?: {
|
|
78
83
|
enabled: boolean;
|
|
84
|
+
aiCommand?: AiCommand;
|
|
79
85
|
allowedUserIds: string[];
|
|
80
86
|
cardTemplateId?: string;
|
|
81
87
|
};
|
|
@@ -84,6 +90,7 @@ export interface Config {
|
|
|
84
90
|
export interface FilePlatformTelegram {
|
|
85
91
|
enabled?: boolean;
|
|
86
92
|
botToken?: string;
|
|
93
|
+
aiCommand?: AiCommand;
|
|
87
94
|
allowedUserIds?: string[];
|
|
88
95
|
proxy?: string;
|
|
89
96
|
}
|
|
@@ -91,18 +98,21 @@ export interface FilePlatformFeishu {
|
|
|
91
98
|
enabled?: boolean;
|
|
92
99
|
appId?: string;
|
|
93
100
|
appSecret?: string;
|
|
101
|
+
aiCommand?: AiCommand;
|
|
94
102
|
allowedUserIds?: string[];
|
|
95
103
|
}
|
|
96
104
|
interface FilePlatformQQ {
|
|
97
105
|
enabled?: boolean;
|
|
98
106
|
appId?: string;
|
|
99
107
|
secret?: string;
|
|
108
|
+
aiCommand?: AiCommand;
|
|
100
109
|
allowedUserIds?: string[];
|
|
101
110
|
}
|
|
102
111
|
interface FilePlatformWechat {
|
|
103
112
|
enabled?: boolean;
|
|
104
113
|
appId?: string;
|
|
105
114
|
appSecret?: string;
|
|
115
|
+
aiCommand?: AiCommand;
|
|
106
116
|
token?: string;
|
|
107
117
|
jwtToken?: string;
|
|
108
118
|
loginKey?: string;
|
|
@@ -115,6 +125,7 @@ export interface FilePlatformWework {
|
|
|
115
125
|
enabled?: boolean;
|
|
116
126
|
corpId?: string;
|
|
117
127
|
secret?: string;
|
|
128
|
+
aiCommand?: AiCommand;
|
|
118
129
|
wsUrl?: string;
|
|
119
130
|
allowedUserIds?: string[];
|
|
120
131
|
}
|
|
@@ -122,6 +133,7 @@ export interface FilePlatformDingtalk {
|
|
|
122
133
|
enabled?: boolean;
|
|
123
134
|
clientId?: string;
|
|
124
135
|
clientSecret?: string;
|
|
136
|
+
aiCommand?: AiCommand;
|
|
125
137
|
allowedUserIds?: string[];
|
|
126
138
|
cardTemplateId?: string;
|
|
127
139
|
}
|
|
@@ -182,4 +194,6 @@ export declare function needsSetup(): boolean;
|
|
|
182
194
|
export declare function loadConfig(): Config;
|
|
183
195
|
/** 获取已配置凭证的平台列表(用于多通道启动时让用户选择),顺序:Telegram、飞书、企业微信、微信 */
|
|
184
196
|
export declare function getPlatformsWithCredentials(config: Config): Platform[];
|
|
197
|
+
export declare function resolvePlatformAiCommand(config: Config, platform: Platform): AiCommand;
|
|
198
|
+
export declare function getConfiguredAiCommands(config: Config): AiCommand[];
|
|
185
199
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -9,6 +9,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
9
9
|
import { join, dirname, isAbsolute } from 'node:path';
|
|
10
10
|
import { homedir } from 'node:os';
|
|
11
11
|
import { APP_HOME } from './constants.js';
|
|
12
|
+
const AI_COMMANDS = ['claude', 'codex', 'cursor'];
|
|
12
13
|
export const CONFIG_PATH = join(APP_HOME, 'config.json');
|
|
13
14
|
const CODEX_AUTH_PATHS = [
|
|
14
15
|
join(homedir(), '.codex', 'auth.json'),
|
|
@@ -24,6 +25,11 @@ function hasOldConfigFormat(raw) {
|
|
|
24
25
|
const hasNew = raw.tools && typeof raw.tools === 'object' && raw.tools.claude;
|
|
25
26
|
return !!hasOld && !hasNew;
|
|
26
27
|
}
|
|
28
|
+
function normalizeAiCommand(value, fallback) {
|
|
29
|
+
return typeof value === 'string' && AI_COMMANDS.includes(value)
|
|
30
|
+
? value
|
|
31
|
+
: fallback;
|
|
32
|
+
}
|
|
27
33
|
function hasCodexAuth() {
|
|
28
34
|
if (process.env.OPENAI_API_KEY)
|
|
29
35
|
return true;
|
|
@@ -323,7 +329,7 @@ export function loadConfig() {
|
|
|
323
329
|
? parseCommaSeparated(process.env.DINGTALK_ALLOWED_USER_IDS)
|
|
324
330
|
: fileDingtalk?.allowedUserIds ?? allowedUserIds;
|
|
325
331
|
// 5. AI / 工作目录 / 安全配置(从 tools 读取)
|
|
326
|
-
const aiCommand = (process.env.AI_COMMAND ?? file.aiCommand
|
|
332
|
+
const aiCommand = normalizeAiCommand(process.env.AI_COMMAND ?? file.aiCommand, 'claude');
|
|
327
333
|
const tc = file.tools?.claude ?? {};
|
|
328
334
|
const tcur = file.tools?.cursor ?? {};
|
|
329
335
|
const tcod = file.tools?.codex ?? {};
|
|
@@ -550,35 +556,42 @@ export function loadConfig() {
|
|
|
550
556
|
telegram: telegramEnabled
|
|
551
557
|
? {
|
|
552
558
|
enabled: true,
|
|
559
|
+
aiCommand: normalizeAiCommand(file.platforms?.telegram?.aiCommand, aiCommand),
|
|
553
560
|
proxy: process.env.TELEGRAM_PROXY ?? file.platforms?.telegram?.proxy,
|
|
554
561
|
allowedUserIds: telegramAllowedUserIds,
|
|
555
562
|
}
|
|
556
563
|
: {
|
|
557
564
|
enabled: false,
|
|
565
|
+
aiCommand: normalizeAiCommand(file.platforms?.telegram?.aiCommand, aiCommand),
|
|
558
566
|
proxy: process.env.TELEGRAM_PROXY ?? file.platforms?.telegram?.proxy,
|
|
559
567
|
allowedUserIds: telegramAllowedUserIds,
|
|
560
568
|
},
|
|
561
569
|
feishu: feishuEnabled
|
|
562
570
|
? {
|
|
563
571
|
enabled: true,
|
|
572
|
+
aiCommand: normalizeAiCommand(file.platforms?.feishu?.aiCommand, aiCommand),
|
|
564
573
|
allowedUserIds: feishuAllowedUserIds,
|
|
565
574
|
}
|
|
566
575
|
: {
|
|
567
576
|
enabled: false,
|
|
577
|
+
aiCommand: normalizeAiCommand(file.platforms?.feishu?.aiCommand, aiCommand),
|
|
568
578
|
allowedUserIds: feishuAllowedUserIds,
|
|
569
579
|
},
|
|
570
580
|
qq: qqEnabled
|
|
571
581
|
? {
|
|
572
582
|
enabled: true,
|
|
583
|
+
aiCommand: normalizeAiCommand(file.platforms?.qq?.aiCommand, aiCommand),
|
|
573
584
|
allowedUserIds: qqAllowedUserIds,
|
|
574
585
|
}
|
|
575
586
|
: {
|
|
576
587
|
enabled: false,
|
|
588
|
+
aiCommand: normalizeAiCommand(file.platforms?.qq?.aiCommand, aiCommand),
|
|
577
589
|
allowedUserIds: qqAllowedUserIds,
|
|
578
590
|
},
|
|
579
591
|
wechat: wechatEnabled
|
|
580
592
|
? {
|
|
581
593
|
enabled: true,
|
|
594
|
+
aiCommand: normalizeAiCommand(file.platforms?.wechat?.aiCommand, aiCommand),
|
|
582
595
|
wsUrl: wechatWsUrl,
|
|
583
596
|
token: wechatToken,
|
|
584
597
|
jwtToken: wechatJwtToken,
|
|
@@ -589,6 +602,7 @@ export function loadConfig() {
|
|
|
589
602
|
}
|
|
590
603
|
: {
|
|
591
604
|
enabled: false,
|
|
605
|
+
aiCommand: normalizeAiCommand(file.platforms?.wechat?.aiCommand, aiCommand),
|
|
592
606
|
wsUrl: wechatWsUrl,
|
|
593
607
|
token: wechatToken,
|
|
594
608
|
jwtToken: wechatJwtToken,
|
|
@@ -600,20 +614,24 @@ export function loadConfig() {
|
|
|
600
614
|
wework: weworkEnabled
|
|
601
615
|
? {
|
|
602
616
|
enabled: true,
|
|
617
|
+
aiCommand: normalizeAiCommand(file.platforms?.wework?.aiCommand, aiCommand),
|
|
603
618
|
allowedUserIds: weworkAllowedUserIds,
|
|
604
619
|
}
|
|
605
620
|
: {
|
|
606
621
|
enabled: false,
|
|
622
|
+
aiCommand: normalizeAiCommand(file.platforms?.wework?.aiCommand, aiCommand),
|
|
607
623
|
allowedUserIds: weworkAllowedUserIds,
|
|
608
624
|
},
|
|
609
625
|
dingtalk: dingtalkEnabled
|
|
610
626
|
? {
|
|
611
627
|
enabled: true,
|
|
628
|
+
aiCommand: normalizeAiCommand(file.platforms?.dingtalk?.aiCommand, aiCommand),
|
|
612
629
|
allowedUserIds: dingtalkAllowedUserIds,
|
|
613
630
|
cardTemplateId: dingtalkCardTemplateId,
|
|
614
631
|
}
|
|
615
632
|
: {
|
|
616
633
|
enabled: false,
|
|
634
|
+
aiCommand: normalizeAiCommand(file.platforms?.dingtalk?.aiCommand, aiCommand),
|
|
617
635
|
allowedUserIds: dingtalkAllowedUserIds,
|
|
618
636
|
cardTemplateId: dingtalkCardTemplateId,
|
|
619
637
|
},
|
|
@@ -683,3 +701,13 @@ export function getPlatformsWithCredentials(config) {
|
|
|
683
701
|
r.push('wechat');
|
|
684
702
|
return r;
|
|
685
703
|
}
|
|
704
|
+
export function resolvePlatformAiCommand(config, platform) {
|
|
705
|
+
return config.platforms[platform]?.aiCommand ?? config.aiCommand;
|
|
706
|
+
}
|
|
707
|
+
export function getConfiguredAiCommands(config) {
|
|
708
|
+
const commands = new Set([config.aiCommand]);
|
|
709
|
+
for (const platform of config.enabledPlatforms) {
|
|
710
|
+
commands.add(resolvePlatformAiCommand(config, platform));
|
|
711
|
+
}
|
|
712
|
+
return Array.from(commands);
|
|
713
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DWClientDownStream } from 'dingtalk-stream';
|
|
2
|
-
import type
|
|
2
|
+
import { type Config } from '../config.js';
|
|
3
3
|
import type { SessionManager } from '../session/session-manager.js';
|
|
4
4
|
export interface DingTalkEventHandlerHandle {
|
|
5
5
|
stop: () => void;
|