evolclaw 2.5.5 → 2.5.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.
- package/dist/agents/codex-runner.js +22 -13
- package/dist/channels/dingtalk.js +4 -3
- package/dist/channels/feishu.js +2 -1
- package/dist/channels/qqbot.js +2 -1
- package/dist/channels/wecom.js +2 -1
- package/dist/cli.js +1 -1
- package/dist/core/message/message-processor.js +2 -2
- package/dist/ipc.js +19 -11
- package/dist/paths.js +10 -1
- package/dist/utils/init-channel.js +29 -1
- package/dist/utils/init.js +12 -2
- package/package.json +8 -8
- package/aun/pyproject.toml +0 -20
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* Implements the same interface surface as AgentRunner (claude-runner.ts)
|
|
6
6
|
* so MessageProcessor and CommandHandler can work with it transparently.
|
|
7
7
|
*/
|
|
8
|
-
import { Codex } from '@openai/codex-sdk';
|
|
9
8
|
import { resolveOpenaiConfig } from '../config.js';
|
|
10
9
|
import { logger } from '../utils/logger.js';
|
|
11
10
|
import fs from 'fs';
|
|
@@ -24,24 +23,33 @@ const CODEX_MODELS = ['gpt-5.3-codex', 'gpt-5.2-codex', 'gpt-5-codex', 'gpt-5.2'
|
|
|
24
23
|
export class CodexRunner {
|
|
25
24
|
name = 'codex';
|
|
26
25
|
capabilities = { clear: false, compact: false, fork: false };
|
|
27
|
-
codex;
|
|
26
|
+
codex = null;
|
|
27
|
+
codexModule = null;
|
|
28
28
|
model;
|
|
29
29
|
effort;
|
|
30
30
|
activeAbortControllers = new Map();
|
|
31
31
|
activeStreams = new Map();
|
|
32
32
|
activeSessions = new Map(); // sessionId → threadId
|
|
33
33
|
onSessionIdUpdate;
|
|
34
|
+
resolvedConfig;
|
|
34
35
|
constructor(config, callbacks) {
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
this.model = resolved.model;
|
|
41
|
-
if (resolved.effort)
|
|
42
|
-
this.effort = resolved.effort;
|
|
36
|
+
this.resolvedConfig = resolveOpenaiConfig(config);
|
|
37
|
+
this.model = this.resolvedConfig.model;
|
|
38
|
+
if (this.resolvedConfig.effort)
|
|
39
|
+
this.effort = this.resolvedConfig.effort;
|
|
43
40
|
this.onSessionIdUpdate = callbacks.onSessionIdUpdate;
|
|
44
41
|
}
|
|
42
|
+
async ensureCodex() {
|
|
43
|
+
if (!this.codex || !this.codexModule) {
|
|
44
|
+
const { requireOptional } = await import('../utils/init-channel.js');
|
|
45
|
+
this.codexModule = await requireOptional('@openai/codex-sdk');
|
|
46
|
+
this.codex = new this.codexModule.Codex({
|
|
47
|
+
apiKey: this.resolvedConfig.apiKey,
|
|
48
|
+
baseUrl: this.resolvedConfig.baseUrl,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return { codex: this.codex, mod: this.codexModule };
|
|
52
|
+
}
|
|
45
53
|
// ── ModelSwitcher ──
|
|
46
54
|
setModel(model) { this.model = model; }
|
|
47
55
|
getModel() { return this.model; }
|
|
@@ -89,6 +97,7 @@ export class CodexRunner {
|
|
|
89
97
|
async runQuery(sessionId, prompt, projectPath, initialAgentSessionId, images, systemPromptAppend, sessionManager) {
|
|
90
98
|
// Agent ctl: 注入 EVOLCLAW_SESSION_ID 供子进程使用
|
|
91
99
|
process.env.EVOLCLAW_SESSION_ID = sessionId;
|
|
100
|
+
const { codex } = await this.ensureCodex();
|
|
92
101
|
let agentSessionId = initialAgentSessionId || this.activeSessions.get(sessionId);
|
|
93
102
|
const threadOptions = {
|
|
94
103
|
workingDirectory: projectPath,
|
|
@@ -99,8 +108,8 @@ export class CodexRunner {
|
|
|
99
108
|
...(this.effort ? { modelReasoningEffort: this.effort } : {}),
|
|
100
109
|
};
|
|
101
110
|
const thread = agentSessionId
|
|
102
|
-
?
|
|
103
|
-
:
|
|
111
|
+
? codex.resumeThread(agentSessionId, threadOptions)
|
|
112
|
+
: codex.startThread(threadOptions);
|
|
104
113
|
const controller = new AbortController();
|
|
105
114
|
this.activeAbortControllers.set(sessionId, controller);
|
|
106
115
|
// 构建输入:将 base64 图片写入临时文件,转换为 Codex SDK 的 local_image 格式
|
|
@@ -226,7 +235,7 @@ export class CodexRunner {
|
|
|
226
235
|
yield { type: 'tool_use', name: `MCP:${item.server}/${item.tool}`, input: item.arguments };
|
|
227
236
|
}
|
|
228
237
|
else if (item.type === 'file_change') {
|
|
229
|
-
const desc = item.changes.map(c => `${c.kind} ${c.path}`).join(', ');
|
|
238
|
+
const desc = item.changes.map((c) => `${c.kind} ${c.path}`).join(', ');
|
|
230
239
|
yield { type: 'tool_use', name: 'FileChange', input: { description: desc } };
|
|
231
240
|
}
|
|
232
241
|
else if (item.type === 'web_search') {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { requireOptional } from '../utils/init-channel.js';
|
|
2
3
|
import { normalizeChannelInstances, getChannelShowActivities } from '../config.js';
|
|
3
4
|
// ── Webhook SSRF validation ────────────────────────────────────────────────────
|
|
4
5
|
const WEBHOOK_RE = /^https:\/\/(api|oapi)\.dingtalk\.com\//;
|
|
@@ -56,7 +57,7 @@ export class DingtalkChannel {
|
|
|
56
57
|
if (!clientId || !clientSecret || clientId.includes('your-') || clientSecret.includes('your-')) {
|
|
57
58
|
throw new Error('DingTalk clientId/clientSecret not configured');
|
|
58
59
|
}
|
|
59
|
-
const { DWClient, TOPIC_ROBOT } = await
|
|
60
|
+
const { DWClient, TOPIC_ROBOT } = await requireOptional('dingtalk-stream');
|
|
60
61
|
this.client = new DWClient({ clientId, clientSecret });
|
|
61
62
|
this.client.registerCallbackListener(TOPIC_ROBOT, async (msg) => {
|
|
62
63
|
await this.handleIncoming(msg);
|
|
@@ -320,7 +321,7 @@ export class DingtalkChannel {
|
|
|
320
321
|
return;
|
|
321
322
|
}
|
|
322
323
|
// Step 1: Upload media
|
|
323
|
-
const FormData = (await
|
|
324
|
+
const FormData = (await requireOptional('form-data')).default;
|
|
324
325
|
const form = new FormData();
|
|
325
326
|
form.append('type', 'image');
|
|
326
327
|
form.append('media', png, { filename: 'image.png', contentType: 'image/png' });
|
|
@@ -360,7 +361,7 @@ export class DingtalkChannel {
|
|
|
360
361
|
return;
|
|
361
362
|
}
|
|
362
363
|
// Step 1: Upload media
|
|
363
|
-
const FormData = (await
|
|
364
|
+
const FormData = (await requireOptional('form-data')).default;
|
|
364
365
|
const form = new FormData();
|
|
365
366
|
form.append('type', 'file');
|
|
366
367
|
form.append('media', fs.createReadStream(filePath), { filename: path.basename(filePath) });
|
package/dist/channels/feishu.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as lark from '@larksuiteoapi/node-sdk';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import imageType from 'image-type';
|
|
@@ -41,6 +40,8 @@ export class FeishuChannel {
|
|
|
41
40
|
if (this.config.appId.startsWith('YOUR_') || this.config.appSecret.startsWith('YOUR_')) {
|
|
42
41
|
throw new Error('Feishu credentials not configured (placeholder values detected)');
|
|
43
42
|
}
|
|
43
|
+
const { requireOptional } = await import('../utils/init-channel.js');
|
|
44
|
+
const lark = await requireOptional('@larksuiteoapi/node-sdk');
|
|
44
45
|
try {
|
|
45
46
|
this.client = new lark.Client({
|
|
46
47
|
appId: this.config.appId,
|
package/dist/channels/qqbot.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.js';
|
|
2
2
|
import { markdownToPlainText } from '../utils/format.js';
|
|
3
|
+
import { requireOptional } from '../utils/init-channel.js';
|
|
3
4
|
import { normalizeChannelInstances, getChannelShowActivities } from '../config.js';
|
|
4
5
|
// ── QQBotChannel ────────────────────────────────────────────────────────────
|
|
5
6
|
export class QQBotChannel {
|
|
@@ -37,7 +38,7 @@ export class QQBotChannel {
|
|
|
37
38
|
if (!appId || !clientSecret || appId.includes('your-') || clientSecret.includes('your-')) {
|
|
38
39
|
throw new Error('QQBot appId/clientSecret not configured');
|
|
39
40
|
}
|
|
40
|
-
const { QQBotClient } = await
|
|
41
|
+
const { QQBotClient } = await requireOptional('pure-qqbot');
|
|
41
42
|
this.client = new QQBotClient({
|
|
42
43
|
appId,
|
|
43
44
|
clientSecret,
|
package/dist/channels/wecom.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { requireOptional } from '../utils/init-channel.js';
|
|
3
4
|
import { normalizeChannelInstances, getChannelShowActivities } from '../config.js';
|
|
4
5
|
// ── WecomChannel ───────────────────────────────────────────────────────────────
|
|
5
6
|
export class WecomChannel {
|
|
@@ -31,7 +32,7 @@ export class WecomChannel {
|
|
|
31
32
|
if (!botId || !secret) {
|
|
32
33
|
throw new Error('WeCom botId/secret not configured');
|
|
33
34
|
}
|
|
34
|
-
const { WSClient } = await
|
|
35
|
+
const { WSClient } = await requireOptional('@wecom/aibot-node-sdk');
|
|
35
36
|
this.client = new WSClient({ botId, secret });
|
|
36
37
|
// Message events
|
|
37
38
|
this.client.on('message', (frame) => {
|
package/dist/cli.js
CHANGED
|
@@ -1307,7 +1307,7 @@ export async function main(args) {
|
|
|
1307
1307
|
else if (args[1] === 'wecom') {
|
|
1308
1308
|
await cmdInitWecom();
|
|
1309
1309
|
}
|
|
1310
|
-
else if (args[1]) {
|
|
1310
|
+
else if (args[1] && !args[1].startsWith('-')) {
|
|
1311
1311
|
const supported = ['feishu', 'wechat', 'aun', 'dingtalk', 'qqbot', 'wecom'];
|
|
1312
1312
|
console.error(`❌ 不支持的渠道: ${args[1]}`);
|
|
1313
1313
|
console.error(` 支持的渠道: ${supported.join(', ')}`);
|
|
@@ -681,7 +681,7 @@ export class MessageProcessor {
|
|
|
681
681
|
// 区分超时 / 中断 / 错误
|
|
682
682
|
const errType = classifyError(error);
|
|
683
683
|
const interruptReason = this.interruptedSessions.get(session.id);
|
|
684
|
-
const isUserInterrupt = interruptReason === 'new_message' || interruptReason === 'stop';
|
|
684
|
+
const isUserInterrupt = interruptReason === 'new_message' || interruptReason === 'stop' || interruptReason === 'recalled';
|
|
685
685
|
const procStatus = errType === ErrorType.SDK_TIMEOUT ? 'timeout'
|
|
686
686
|
: errType === ErrorType.STREAM_ERROR ? 'interrupted'
|
|
687
687
|
: 'error';
|
|
@@ -889,7 +889,7 @@ export class MessageProcessor {
|
|
|
889
889
|
// 失败且无前置错误输出:显示 errors 摘要
|
|
890
890
|
// 但用户主动中断(新消息打断 或 /stop 命令)时不显示错误提示
|
|
891
891
|
const interruptReason = this.interruptedSessions.get(session.id);
|
|
892
|
-
const isUserInterrupt = interruptReason === 'new_message' || interruptReason === 'stop';
|
|
892
|
+
const isUserInterrupt = interruptReason === 'new_message' || interruptReason === 'stop' || interruptReason === 'recalled';
|
|
893
893
|
if (event.isError && !hasErrorResult && !shouldSuppress() && !isUserInterrupt) {
|
|
894
894
|
const errorSummary = event.errors?.join('; ') || '\u4efb\u52a1\u6267\u884c\u5931\u8d25';
|
|
895
895
|
// 使用 terminalReason 提供更友好的错误提示
|
package/dist/ipc.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import net from 'net';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import { logger } from './utils/logger.js';
|
|
4
|
+
const isWindows = process.platform === 'win32';
|
|
5
|
+
const isNamedPipe = (p) => isWindows && p.startsWith('\\\\.\\pipe\\');
|
|
4
6
|
export class IpcServer {
|
|
5
7
|
socketPath;
|
|
6
8
|
getStatus;
|
|
@@ -12,11 +14,13 @@ export class IpcServer {
|
|
|
12
14
|
this.commandExecutor = commandExecutor;
|
|
13
15
|
}
|
|
14
16
|
start() {
|
|
15
|
-
// Remove stale socket file
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
// Remove stale socket file (Unix only — named pipes auto-cleanup on process exit)
|
|
18
|
+
if (!isNamedPipe(this.socketPath)) {
|
|
19
|
+
try {
|
|
20
|
+
fs.unlinkSync(this.socketPath);
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
18
23
|
}
|
|
19
|
-
catch { }
|
|
20
24
|
this.server = net.createServer((conn) => {
|
|
21
25
|
let buf = '';
|
|
22
26
|
conn.on('data', async (data) => {
|
|
@@ -42,11 +46,13 @@ export class IpcServer {
|
|
|
42
46
|
logger.error('[IPC] Server error:', err);
|
|
43
47
|
});
|
|
44
48
|
this.server.listen(this.socketPath, () => {
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
// Restrict to current user (Unix only — named pipes use Windows ACLs)
|
|
50
|
+
if (!isNamedPipe(this.socketPath)) {
|
|
51
|
+
try {
|
|
52
|
+
fs.chmodSync(this.socketPath, 0o600);
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
48
55
|
}
|
|
49
|
-
catch { }
|
|
50
56
|
logger.info(`[IPC] Listening on ${this.socketPath}`);
|
|
51
57
|
});
|
|
52
58
|
}
|
|
@@ -55,10 +61,12 @@ export class IpcServer {
|
|
|
55
61
|
this.server.close();
|
|
56
62
|
this.server = null;
|
|
57
63
|
}
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
if (!isNamedPipe(this.socketPath)) {
|
|
65
|
+
try {
|
|
66
|
+
fs.unlinkSync(this.socketPath);
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
60
69
|
}
|
|
61
|
-
catch { }
|
|
62
70
|
}
|
|
63
71
|
async handleCommand(cmd) {
|
|
64
72
|
switch (cmd.type) {
|
package/dist/paths.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
const isWindows = process.platform === 'win32';
|
|
4
6
|
let _root = null;
|
|
5
7
|
export function resolveRoot() {
|
|
6
8
|
if (_root)
|
|
@@ -33,9 +35,16 @@ export function resolvePaths() {
|
|
|
33
35
|
lineStats: path.join(root, 'logs', 'line-stats.log'),
|
|
34
36
|
readySignal: path.join(root, 'logs', 'ready.signal'),
|
|
35
37
|
selfHealLog: path.join(root, 'logs', 'self-heal.md'),
|
|
36
|
-
socket:
|
|
38
|
+
socket: resolveSocketPath(root),
|
|
37
39
|
};
|
|
38
40
|
}
|
|
41
|
+
function resolveSocketPath(root) {
|
|
42
|
+
if (isWindows) {
|
|
43
|
+
const hash = crypto.createHash('sha1').update(root).digest('hex').slice(0, 12);
|
|
44
|
+
return `\\\\.\\pipe\\evolclaw-${hash}`;
|
|
45
|
+
}
|
|
46
|
+
return path.join(root, 'logs', 'evolclaw.sock');
|
|
47
|
+
}
|
|
39
48
|
export function ensureDataDirs() {
|
|
40
49
|
const p = resolvePaths();
|
|
41
50
|
fs.mkdirSync(p.dataDir, { recursive: true });
|
|
@@ -36,6 +36,22 @@ export async function npmInstallGlobal(pkg) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
/** Dynamic import with auto-install fallback for optional dependencies */
|
|
40
|
+
export async function requireOptional(pkg, autoInstall = true) {
|
|
41
|
+
try {
|
|
42
|
+
return await import(pkg);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
if (e.code !== 'ERR_MODULE_NOT_FOUND' && e.code !== 'MODULE_NOT_FOUND')
|
|
46
|
+
throw e;
|
|
47
|
+
if (!autoInstall)
|
|
48
|
+
throw new Error(`依赖 ${pkg} 未安装。请运行: npm install -g ${pkg}`);
|
|
49
|
+
const { logger } = await import('./logger.js');
|
|
50
|
+
logger.info(`正在安装可选依赖 ${pkg}...`);
|
|
51
|
+
await npmInstallGlobal(pkg);
|
|
52
|
+
return await import(pkg);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
39
55
|
function ask(rl, question) {
|
|
40
56
|
return new Promise(resolve => rl.question(question, resolve));
|
|
41
57
|
}
|
|
@@ -738,14 +754,26 @@ export async function setupAunAid(rl, _config) {
|
|
|
738
754
|
const agentType = typeInput === 'human' ? 'human' : 'ai';
|
|
739
755
|
const agentName = aid.split('.')[0];
|
|
740
756
|
const agentMdContent = `---\naid: "${aid}"\nname: "${agentName}"\ntype: "${agentType}"\nversion: "1.0.0"\ndescription: ""\ntags:\n - evolclaw\ninitialized: false\n---\n`;
|
|
757
|
+
const agentMdPath = path.join(aidDir, 'agent.md');
|
|
741
758
|
try {
|
|
742
759
|
await client.auth.uploadAgentMd(agentMdContent);
|
|
743
760
|
console.log(' ✓ agent.md 已发布');
|
|
744
|
-
fs.writeFileSync(path.join(aidDir, 'agent.md'), agentMdContent, 'utf-8');
|
|
745
761
|
}
|
|
746
762
|
catch (e) {
|
|
747
763
|
console.log(` ⚠ agent.md 发布失败(可稍后用 /agentmd put 重试): ${String(e.message || e).slice(0, 100)}`);
|
|
748
764
|
}
|
|
765
|
+
fs.writeFileSync(agentMdPath, agentMdContent, 'utf-8');
|
|
766
|
+
if (!fs.existsSync(agentMdPath)) {
|
|
767
|
+
try {
|
|
768
|
+
await client.close();
|
|
769
|
+
}
|
|
770
|
+
catch { /* ignore */ }
|
|
771
|
+
console.log(` ✗ agent.md 本地写入校验失败: ${agentMdPath}`);
|
|
772
|
+
failed = true;
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
console.log(' ✓ agent.md 已写入本地');
|
|
776
|
+
}
|
|
749
777
|
try {
|
|
750
778
|
await client.close();
|
|
751
779
|
}
|
package/dist/utils/init.js
CHANGED
|
@@ -445,11 +445,21 @@ export async function cmdInit(options) {
|
|
|
445
445
|
// 写入初始 agent.md(initialized: false)
|
|
446
446
|
const agentName = options.aunAid.split('.')[0];
|
|
447
447
|
const agentMd = `---\naid: "${options.aunAid}"\nname: "${agentName}"\ntype: "ai"\nversion: "1.0.0"\ndescription: ""\ntags:\n - evolclaw\ninitialized: false\n---\n`;
|
|
448
|
+
const agentMdPath = path.join(aidDir, 'agent.md');
|
|
448
449
|
try {
|
|
449
450
|
await client.auth.uploadAgentMd(agentMd);
|
|
450
|
-
fs.writeFileSync(path.join(aidDir, 'agent.md'), agentMd, 'utf-8');
|
|
451
451
|
}
|
|
452
|
-
catch {
|
|
452
|
+
catch (e) {
|
|
453
|
+
console.warn(`⚠ agent.md 网络发布失败(可稍后重试): ${String(e?.message || e).slice(0, 100)}`);
|
|
454
|
+
}
|
|
455
|
+
fs.writeFileSync(agentMdPath, agentMd, 'utf-8');
|
|
456
|
+
if (!fs.existsSync(agentMdPath)) {
|
|
457
|
+
try {
|
|
458
|
+
await client.close();
|
|
459
|
+
}
|
|
460
|
+
catch { }
|
|
461
|
+
throw new Error(`agent.md 写入校验失败: ${agentMdPath}`);
|
|
462
|
+
}
|
|
453
463
|
try {
|
|
454
464
|
await client.close();
|
|
455
465
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evolclaw",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
4
4
|
"description": "Lightweight AI Agent gateway connecting Claude Agent SDK to messaging channels (Feishu, ACP) with multi-project session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"dist/",
|
|
12
12
|
"!dist/experimental/",
|
|
13
13
|
"data/evolclaw.sample.json",
|
|
14
|
-
"evolclaw-install-aun.md"
|
|
15
|
-
"aun/pyproject.toml"
|
|
14
|
+
"evolclaw-install-aun.md"
|
|
16
15
|
],
|
|
17
16
|
"scripts": {
|
|
18
17
|
"dev": "tsx watch src/index.ts",
|
|
@@ -26,19 +25,20 @@
|
|
|
26
25
|
"dependencies": {
|
|
27
26
|
"@anthropic-ai/claude-agent-sdk": "^0.2.100",
|
|
28
27
|
"@agentunion/aun-node": "^0.2.12",
|
|
28
|
+
"image-type": "^6.0.0",
|
|
29
|
+
"qrcode-terminal": "^0.12.0"
|
|
30
|
+
},
|
|
31
|
+
"optionalDependencies": {
|
|
29
32
|
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
30
33
|
"@openai/codex-sdk": "^0.118.0",
|
|
31
|
-
"@types/form-data": "^2.2.1",
|
|
32
34
|
"@wecom/aibot-node-sdk": "^1.0.6",
|
|
33
35
|
"dingtalk-stream": "^2.1.6-beta.1",
|
|
34
|
-
"fast-xml-parser": "^5.7.2",
|
|
35
36
|
"form-data": "^4.0.5",
|
|
36
|
-
"
|
|
37
|
-
"pure-qqbot": "^2.0.0",
|
|
38
|
-
"qrcode-terminal": "^0.12.0"
|
|
37
|
+
"pure-qqbot": "^2.0.0"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
40
|
"@types/node": "^25.5.0",
|
|
41
|
+
"@types/form-data": "^2.2.1",
|
|
42
42
|
"@types/qrcode-terminal": "^0.12.2",
|
|
43
43
|
"@vitest/coverage-v8": "^4.1.0",
|
|
44
44
|
"tsx": "^4.19.0",
|
package/aun/pyproject.toml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "aun-cli"
|
|
3
|
-
version = "0.1.0"
|
|
4
|
-
description = "AUN CLI - Interactive command-line client for AUN protocol"
|
|
5
|
-
requires-python = ">=3.10"
|
|
6
|
-
dependencies = [
|
|
7
|
-
"aunp>=0.2.12",
|
|
8
|
-
"prompt-toolkit>=3.0.0",
|
|
9
|
-
"rich>=13.0.0",
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
[project.scripts]
|
|
13
|
-
aun = "aun_cli:cli_main"
|
|
14
|
-
|
|
15
|
-
[build-system]
|
|
16
|
-
requires = ["setuptools>=61.0"]
|
|
17
|
-
build-backend = "setuptools.build_meta"
|
|
18
|
-
|
|
19
|
-
[tool.setuptools]
|
|
20
|
-
py-modules = ["aun_cli"]
|