openclaw-app 1.1.1 → 1.1.3
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 +64 -9
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -881,9 +881,66 @@ 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 === "agents.list") {
|
|
914
|
+
const agents = runtime.agents?.list?.() ?? runtime.config?.loadConfig()?.agents?.agents ?? [];
|
|
915
|
+
// Normalize to [{id, name, emoji, workspace, createdAt}]
|
|
916
|
+
const list = Array.isArray(agents) ? agents.map((a: any) => ({
|
|
917
|
+
id: a.id ?? a.agentId ?? '',
|
|
918
|
+
name: a.name ?? a.id ?? '',
|
|
919
|
+
emoji: a.emoji ?? null,
|
|
920
|
+
workspace: a.workspace ?? null,
|
|
921
|
+
createdAt: a.createdAt ?? null,
|
|
922
|
+
})).filter((a: any) => a.id) : [];
|
|
923
|
+
await sendRpcReply({ agents: list });
|
|
924
|
+
} else if (method === "sessions.list") {
|
|
925
|
+
const cfg = runtime.config.loadConfig();
|
|
926
|
+
const sessions = runtime.session?.listSessions?.({ cfg, accountId }) ?? [];
|
|
927
|
+
await sendRpcReply({ sessions });
|
|
928
|
+
} else {
|
|
929
|
+
await sendRpcReply(null, `Unknown RPC method: ${method}`);
|
|
930
|
+
}
|
|
931
|
+
} catch (e: any) {
|
|
932
|
+
ctx.log?.error?.(`[${CHANNEL_ID}] [${accountId}] RPC error: ${e}`);
|
|
933
|
+
await sendRpcReply(null, String(e));
|
|
934
|
+
}
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
|
|
884
938
|
async function handleInbound(ctx: any, accountId: string, msg: any) {
|
|
885
939
|
ctx.log?.info?.(`[${CHANNEL_ID}] [${accountId}] handleInbound: type=${msg.type} content=${String(msg.content ?? "").slice(0, 100)}`);
|
|
886
940
|
|
|
941
|
+
// Handle RPC requests (agents.list, sessions.list, etc.) without AI involvement
|
|
942
|
+
if (await handleRpc(ctx, accountId, msg)) return;
|
|
943
|
+
|
|
887
944
|
if (msg.type !== "message" || !msg.content) {
|
|
888
945
|
ctx.log?.warn?.(`[${CHANNEL_ID}] [${accountId}] Skipping non-message: type=${msg.type}`);
|
|
889
946
|
return;
|
|
@@ -913,18 +970,16 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
|
|
|
913
970
|
peer: { kind: "direct", id: senderId },
|
|
914
971
|
});
|
|
915
972
|
|
|
916
|
-
//
|
|
917
|
-
//
|
|
918
|
-
//
|
|
919
|
-
//
|
|
973
|
+
// Derive an isolated Gateway session for each mobile conversation.
|
|
974
|
+
// If the app provides an agentId, route to that agent's session:
|
|
975
|
+
// agent:<agentId>:mobile-<appSessionKey>
|
|
976
|
+
// Otherwise fall back to the default main agent route.
|
|
920
977
|
let sessionKey: string;
|
|
921
978
|
const appSessionKey = msg.sessionKey ? String(msg.sessionKey) : null;
|
|
979
|
+
const msgAgentId = msg.agentId ? String(msg.agentId) : null;
|
|
922
980
|
if (appSessionKey) {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
const colonIdx = mainKey.lastIndexOf(':');
|
|
926
|
-
const agentPrefix = colonIdx > 0 ? mainKey.substring(0, colonIdx + 1) : '';
|
|
927
|
-
sessionKey = `${agentPrefix}mobile-${appSessionKey}`;
|
|
981
|
+
const agentId = msgAgentId || 'main';
|
|
982
|
+
sessionKey = `agent:${agentId}:mobile-${appSessionKey}`;
|
|
928
983
|
} else {
|
|
929
984
|
sessionKey = route.mainSessionKey;
|
|
930
985
|
}
|
package/openclaw.plugin.json
CHANGED