mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-03 15:53:56 +00:00
clawhubadapter: agent 全量管理 OpenClaw 插件与通道(管理接口补齐)
新工具(agent 可直接调用): - plugin_info:插件详情(OC/sidecar/SKILL 类型、工具列表、关联通道及状态) - plugin_reload:重新加载插件(reloadPlugin) - channel_list:全部注册通道 + 实时运行状态 - channel_send:向通道注入消息(SendToChannel → channel/send → pollQueues) - channel_start / channel_stop:通道账号启停 manager 新 RPC: - plugins/channels:registeredChannels 摘要(type/status/accounts) - channel/start:fire-and-forget startChannels 恢复账号(startAccount 永久挂起语义) - channel/stop:stopAccount 停止心跳/轮询,支持按 channel 全停或按 accountId 单停 Go 侧 channelSummary 合并 manager 注册信息与 channel_status 实时缓存(缓存优先)。 验证:微信端到端(本地 mock LLM 源)channel_list 返回 wechat running=true connected=true、 channel_send 投递成功;standalone manager 验证 channel/start 心跳恢复与 channel/stop。
This commit is contained in:
@ -758,6 +758,42 @@ rl.on('line', async (line) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// 停止通道账号(stopAccount:停止心跳/轮询)。channel 可省略(停该插件全部通道)
|
||||
if (method === 'channel/stop') {
|
||||
const chName = req.params?.channel;
|
||||
const accountId = req.params?.accountId;
|
||||
if (chName) {
|
||||
const ch = registeredChannels[chName];
|
||||
if (!ch) { sendError(id, -32601, `channel not found: ${chName}`); return; }
|
||||
if (accountId) {
|
||||
const gateway = ch.channelPlugin && ch.channelPlugin.gateway;
|
||||
if (gateway && typeof gateway.stopAccount === 'function') {
|
||||
gateway.stopAccount({ account: { accountId }, channelRuntime: ch.runtime, cfg: ch.pluginConfig || {} }).catch((e) =>
|
||||
process.stderr.write(`[manager] ${chName}: stopAccount(${accountId}) failed: ${e.message}\n`));
|
||||
}
|
||||
if (ch.accounts) delete ch.accounts[accountId];
|
||||
} else {
|
||||
stopChannels(chName);
|
||||
}
|
||||
writeJSON({ jsonrpc: '2.0', id, result: { status: 'stopped', channel: chName, accountId: accountId || 'all' } });
|
||||
} else {
|
||||
for (const name of Object.keys(registeredChannels)) stopChannels(name);
|
||||
writeJSON({ jsonrpc: '2.0', id, result: { status: 'stopped', channel: 'all' } });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 启动通道账号(gateway.startAccount fire-and-forget)
|
||||
if (method === 'channel/start') {
|
||||
const chName = req.params?.channel;
|
||||
const ch = registeredChannels[chName];
|
||||
if (!ch) { sendError(id, -32601, `channel not found: ${chName}`); return; }
|
||||
ch.accounts = {};
|
||||
startChannels(chName).catch((e) => process.stderr.write(`[manager] ${chName}: startChannels failed: ${e.message}\n`));
|
||||
writeJSON({ jsonrpc: '2.0', id, result: { status: 'started', channel: chName } });
|
||||
return;
|
||||
}
|
||||
|
||||
if (method === 'plugins/list') {
|
||||
const list = Object.entries(loadedPlugins).map(([name, p]) => ({
|
||||
name,
|
||||
@ -767,6 +803,18 @@ rl.on('line', async (line) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (method === 'plugins/channels') {
|
||||
const list = Object.entries(registeredChannels).map(([name, ch]) => ({
|
||||
name,
|
||||
plugin: ch.pluginName,
|
||||
type: ch.type || 'text',
|
||||
status: ch.status || {},
|
||||
accounts: ch.accounts ? Object.keys(ch.accounts) : [],
|
||||
}));
|
||||
writeJSON({ jsonrpc: '2.0', id, result: { channels: list } });
|
||||
return;
|
||||
}
|
||||
|
||||
if (method === 'plugins/install') {
|
||||
const pkg = req.params?.package;
|
||||
if (!pkg) { sendError(id, -32602, 'package required'); return; }
|
||||
@ -794,6 +842,13 @@ rl.on('line', async (line) => {
|
||||
|
||||
if (!loadedPlugins[name]) { sendError(id, -32601, `plugin not found: ${name}`); return; }
|
||||
|
||||
// 先优雅停靠通道账号(stopAccount 停止心跳/轮询),再卸载
|
||||
for (const chName of Object.keys(registeredChannels)) {
|
||||
if (registeredChannels[chName].pluginName === name) {
|
||||
stopChannels(chName);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove tools
|
||||
const idxs = [];
|
||||
for (let i = allTools.length - 1; i >= 0; i--) {
|
||||
|
||||
Reference in New Issue
Block a user