feat(gateway): register fabric.register gateway method for live no-restart registration
Recruitment's register-agent step is a plain shell step (no LLM turn), so it cannot invoke the `fabric-register` TOOL (tool only fires inside an agent turn) and there is no `openclaw tools call` CLI. It previously fell back to the standalone bootstrap binary, which writes fabric-identity.json but cannot notify the running plugin -> the new agent's inbound socket only came up after a gateway restart. This adds an in-process gateway method `fabric.register` (scope: operator.write) whose handler runs inbound.addAccount: validates the key, persists identity, and brings the inbound socket up immediately. The script now calls `openclaw gateway call fabric.register --params ...` and only falls back to the bootstrap binary if the method is unavailable. Also resyncs committed dist/ to source (sub-discussion-hook/store + tools/ inbound were source-committed but their dist artifacts were stale). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
39
index.ts
39
index.ts
@@ -49,6 +49,18 @@ export default defineChannelPluginEntry({
|
||||
logger: { info: (m: string) => void; warn: (m: string) => void };
|
||||
on: (ev: string, fn: (...args: unknown[]) => unknown) => void;
|
||||
registerTool: (d: unknown) => void;
|
||||
registerGatewayMethod: (
|
||||
method: string,
|
||||
handler: (req: {
|
||||
params?: unknown;
|
||||
respond: (
|
||||
ok: boolean,
|
||||
data?: unknown,
|
||||
error?: { code: string; message: string },
|
||||
) => void;
|
||||
}) => void | Promise<void>,
|
||||
opts?: { scope?: string },
|
||||
) => void;
|
||||
};
|
||||
const cfg = (api.config ?? {}) as {
|
||||
channels?: { fabric?: { centerApiBase?: string; commandsSyncKey?: string } };
|
||||
@@ -121,6 +133,33 @@ export default defineChannelPluginEntry({
|
||||
api.logger.info('fabric: __fabric cross-plugin API installed (getChannelType + addAccount + removeAccount)');
|
||||
}
|
||||
|
||||
// CLI-invocable live registration, callable from a shell script via
|
||||
// openclaw gateway call fabric.register --params '{"agentId":"…","apiKey":"fak_…"}'
|
||||
// The `fabric-register` TOOL only fires inside an agent turn, and there is
|
||||
// no `openclaw tools call` CLI — so recruitment's `register-agent` script
|
||||
// (a plain shell step, no LLM turn) had to fall back to the standalone
|
||||
// binary, which can't notify the running plugin → needed a gateway
|
||||
// restart. This gateway method runs in-process: inbound.addAccount
|
||||
// validates the key, persists identity, and brings the socket up live —
|
||||
// no restart.
|
||||
api.registerGatewayMethod('fabric.register', async ({ params, respond }) => {
|
||||
const p = (params ?? {}) as { agentId?: string; apiKey?: string };
|
||||
if (!p.agentId || !p.apiKey) {
|
||||
respond(false, { ok: false }, { code: 'INVALID_REQUEST', message: 'agentId and apiKey required' });
|
||||
return;
|
||||
}
|
||||
if (!inbound) {
|
||||
respond(false, { ok: false }, { code: 'UNAVAILABLE', message: 'fabric inbound not ready (gateway still starting?)' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await inbound.addAccount({ agentId: p.agentId, fabricApiKey: p.apiKey });
|
||||
respond(true, { ok: true, agentId: p.agentId });
|
||||
} catch (err) {
|
||||
respond(false, { ok: false }, { code: 'UNAVAILABLE', message: `fabric-register failed: ${String(err)}` });
|
||||
}
|
||||
}, { scope: 'operator.write' });
|
||||
|
||||
api.on('gateway_start', () => {
|
||||
const _G = globalThis as Record<string, unknown>;
|
||||
if (_G._fabricInboundStarted) return;
|
||||
|
||||
Reference in New Issue
Block a user