rpc-call.js
2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* RPC Call Utility
*
* 用于在 Hook 脚本中向 AgentBridge 发送控制指令。
* Usage: node scripts/rpc-call.js --agent AgentName --command git/checkout --args feat/task-123
*/
const { WebSocket } = require('ws');
const path = require('path');
const fs = require('fs');
// 解析参数
const args = process.argv.slice(2);
const params = {};
let currentKey = null;
for (const arg of args) {
if (arg.startsWith('--')) {
currentKey = arg.substring(2);
params[currentKey] = true;
} else if (currentKey) {
params[currentKey] = arg;
currentKey = null;
}
}
if (!params.agent || !params.command) {
console.error('Usage: node scripts/rpc-call.js --config <path> --agent <name> --command <cmd> [--args <args>]');
process.exit(1);
}
async function main() {
const configPath = params.config || path.join(__dirname, '../server/config/agents.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
const agentConfig = config.agents[params.agent];
const launcherConfig = config.launchers[agentConfig.launcher];
let wsUrl;
if (launcherConfig.type === 'none' && launcherConfig.url) {
wsUrl = launcherConfig.url;
} else {
console.error(`Unsupported launcher type for RPC: ${launcherConfig.type} (only 'none' with url is supported)`);
process.exit(1);
}
console.log(`Testing RPC connection to ${wsUrl}...`);
const ws = new WebSocket(wsUrl);
await new Promise((resolve, reject) => {
ws.on('open', resolve);
ws.on('error', reject);
});
console.log('Connected. Sending command...');
let requestParams = {};
if (params.args) {
if (params.args.startsWith('{')) {
try {
requestParams = JSON.parse(params.args);
} catch (e) {
console.warn("Failed to parse args as JSON, treating as raw string", e);
requestParams = { args: params.args };
}
} else if (params.args.includes('=')) {
// Simple key=value parser
params.args.split(' ').forEach(kv => {
const [k, v] = kv.split('=');
if (k && v) requestParams[k] = v;
});
} else {
requestParams = { args: params.args };
}
}
const request = {
type: 'control',
id: Date.now(),
command: params.command,
params: requestParams
};
ws.send(JSON.stringify(request));
// 等待响应
ws.on('message', (data) => {
const response = JSON.parse(data);
if (response.id === request.id) {
console.log('Response:', JSON.stringify(response, null, 2));
if (response.status === 'ok' || !response.error) {
process.exit(0);
} else {
console.error('RPC Error:', response.error);
process.exit(1);
}
}
});
// 超时
setTimeout(() => {
console.error('Timeout waiting for RPC response');
process.exit(1);
}, 5000);
}
main().catch(err => {
console.error(err);
process.exit(1);
});