openclaw-app 1.1.2 → 1.1.4
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/index.ts +85 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -881,9 +881,94 @@ async function handleRelayMessage(ctx: any, accountId: string, state: RelayState
|
|
|
881
881
|
await handleInbound(ctx, accountId, msg);
|
|
882
882
|
}
|
|
883
883
|
|
|
884
|
+
async function handleRpc(ctx: any, accountId: string, msg: any): Promise<boolean> {
|
|
885
|
+
if (msg.type !== "rpc") return false;
|
|
886
|
+
const reqId = msg.id as string | undefined;
|
|
887
|
+
const method = msg.method as string | undefined;
|
|
888
|
+
const params = msg.params ?? {};
|
|
889
|
+
const replySessionKey = msg.sessionKey as string | undefined;
|
|
890
|
+
|
|
891
|
+
ctx.log?.info?.(`[${CHANNEL_ID}] [${accountId}] handleRpc: method=${method} id=${reqId}`);
|
|
892
|
+
|
|
893
|
+
const runtime = pluginRuntime;
|
|
894
|
+
if (!runtime) {
|
|
895
|
+
ctx.log?.error?.(`[${CHANNEL_ID}] [${accountId}] RPC: no runtime`);
|
|
896
|
+
return true;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const relayState = getRelayState(accountId);
|
|
900
|
+
|
|
901
|
+
const sendRpcReply = async (data: unknown, error?: string) => {
|
|
902
|
+
if (!relayState.ws || relayState.ws.readyState !== WebSocket.OPEN) return;
|
|
903
|
+
if (!replySessionKey) return;
|
|
904
|
+
const sessionE2E = relayState.e2eSessions.get(replySessionKey);
|
|
905
|
+
if (!sessionE2E?.ready) return;
|
|
906
|
+
const inner = JSON.stringify({ type: "rpc-response", id: reqId, data, error: error ?? null, sessionKey: replySessionKey });
|
|
907
|
+
const encrypted = JSON.parse(await e2eEncrypt(sessionE2E, inner));
|
|
908
|
+
encrypted.sessionKey = replySessionKey;
|
|
909
|
+
relayState.ws.send(JSON.stringify(encrypted));
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
try {
|
|
913
|
+
if (method === "runtime.inspect") {
|
|
914
|
+
// Debug: return top-level keys of runtime object
|
|
915
|
+
const keys = Object.keys(runtime ?? {});
|
|
916
|
+
const cfgKeys = runtime?.config ? Object.keys(runtime.config) : [];
|
|
917
|
+
const cfg = runtime?.config?.loadConfig?.() ?? {};
|
|
918
|
+
const cfgTopKeys = Object.keys(cfg);
|
|
919
|
+
// Try to find agents in config
|
|
920
|
+
const agentsCfg = cfg.agents ?? cfg.agent ?? {};
|
|
921
|
+
const agentsListKeys = Object.keys(agentsCfg);
|
|
922
|
+
const agentsList = agentsCfg.list ?? agentsCfg.agents ?? agentsCfg ?? [];
|
|
923
|
+
await sendRpcReply({
|
|
924
|
+
runtimeKeys: keys,
|
|
925
|
+
configKeys: cfgKeys,
|
|
926
|
+
cfgTopKeys,
|
|
927
|
+
agentsCfgKeys: agentsListKeys,
|
|
928
|
+
agentsListType: Array.isArray(agentsList) ? `array[${agentsList.length}]` : typeof agentsList,
|
|
929
|
+
agentsSample: Array.isArray(agentsList) ? agentsList.slice(0, 3) : agentsList,
|
|
930
|
+
});
|
|
931
|
+
} else if (method === "agents.list") {
|
|
932
|
+
const cfg = runtime.config.loadConfig();
|
|
933
|
+
// cfg.agents structure: { defaults: {...}, list: [{id, name, workspace, ...}], ... }
|
|
934
|
+
const agentsCfg = cfg.agents ?? {};
|
|
935
|
+
let raw: any[] = [];
|
|
936
|
+
if (Array.isArray(agentsCfg.list)) {
|
|
937
|
+
raw = agentsCfg.list;
|
|
938
|
+
} else if (Array.isArray(agentsCfg.agents)) {
|
|
939
|
+
raw = agentsCfg.agents;
|
|
940
|
+
} else if (Array.isArray(agentsCfg)) {
|
|
941
|
+
raw = agentsCfg;
|
|
942
|
+
}
|
|
943
|
+
ctx.log?.info?.(`[${CHANNEL_ID}] agents raw count: ${raw.length}`);
|
|
944
|
+
const list = raw.map((a: any) => ({
|
|
945
|
+
id: a.id ?? a.agentId ?? '',
|
|
946
|
+
name: a.name ?? a.id ?? '',
|
|
947
|
+
emoji: a.emoji ?? null,
|
|
948
|
+
workspace: a.workspace ?? null,
|
|
949
|
+
createdAt: a.createdAt ?? null,
|
|
950
|
+
})).filter((a: any) => a.id);
|
|
951
|
+
await sendRpcReply({ agents: list });
|
|
952
|
+
} else if (method === "sessions.list") {
|
|
953
|
+
const cfg = runtime.config.loadConfig();
|
|
954
|
+
const sessions = runtime.session?.listSessions?.({ cfg, accountId }) ?? [];
|
|
955
|
+
await sendRpcReply({ sessions });
|
|
956
|
+
} else {
|
|
957
|
+
await sendRpcReply(null, `Unknown RPC method: ${method}`);
|
|
958
|
+
}
|
|
959
|
+
} catch (e: any) {
|
|
960
|
+
ctx.log?.error?.(`[${CHANNEL_ID}] [${accountId}] RPC error: ${e}`);
|
|
961
|
+
await sendRpcReply(null, String(e));
|
|
962
|
+
}
|
|
963
|
+
return true;
|
|
964
|
+
}
|
|
965
|
+
|
|
884
966
|
async function handleInbound(ctx: any, accountId: string, msg: any) {
|
|
885
967
|
ctx.log?.info?.(`[${CHANNEL_ID}] [${accountId}] handleInbound: type=${msg.type} content=${String(msg.content ?? "").slice(0, 100)}`);
|
|
886
968
|
|
|
969
|
+
// Handle RPC requests (agents.list, sessions.list, etc.) without AI involvement
|
|
970
|
+
if (await handleRpc(ctx, accountId, msg)) return;
|
|
971
|
+
|
|
887
972
|
if (msg.type !== "message" || !msg.content) {
|
|
888
973
|
ctx.log?.warn?.(`[${CHANNEL_ID}] [${accountId}] Skipping non-message: type=${msg.type}`);
|
|
889
974
|
return;
|
package/openclaw.plugin.json
CHANGED