openclaw-app 1.1.4 → 1.1.6

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 CHANGED
@@ -563,8 +563,9 @@ function cleanupRelay(state: RelayState) {
563
563
  state.ws = null;
564
564
  }
565
565
  state.e2eSessions.clear();
566
- state.prevE2eSessions.clear();
567
- state.pendingFlushQueue.clear();
566
+ // prevE2eSessions is intentionally kept across reconnects so that
567
+ // offline-buffered messages can still be re-encrypted after a plugin
568
+ // reconnect. pendingFlushQueue is also kept for the same reason.
568
569
  }
569
570
 
570
571
  function connectRelay(ctx: any, account: ResolvedAccount) {
@@ -928,6 +929,13 @@ async function handleRpc(ctx: any, accountId: string, msg: any): Promise<boolean
928
929
  agentsListType: Array.isArray(agentsList) ? `array[${agentsList.length}]` : typeof agentsList,
929
930
  agentsSample: Array.isArray(agentsList) ? agentsList.slice(0, 3) : agentsList,
930
931
  });
932
+ } else if (method === "runtime.inspect.deep") {
933
+ // Inspect sub-objects to find agents.create capability
934
+ const systemKeys = runtime?.system ? Object.keys(runtime.system) : [];
935
+ const toolsKeys = runtime?.tools ? Object.keys(runtime.tools) : [];
936
+ const stateKeys = runtime?.state ? Object.keys(runtime.state) : [];
937
+ const agentsApiKeys = runtime?.agents ? Object.keys(runtime.agents) : [];
938
+ await sendRpcReply({ systemKeys, toolsKeys, stateKeys, agentsApiKeys });
931
939
  } else if (method === "agents.list") {
932
940
  const cfg = runtime.config.loadConfig();
933
941
  // cfg.agents structure: { defaults: {...}, list: [{id, name, workspace, ...}], ... }
@@ -953,6 +961,25 @@ async function handleRpc(ctx: any, accountId: string, msg: any): Promise<boolean
953
961
  const cfg = runtime.config.loadConfig();
954
962
  const sessions = runtime.session?.listSessions?.({ cfg, accountId }) ?? [];
955
963
  await sendRpcReply({ sessions });
964
+ } else if (method === "agents.create") {
965
+ // Use CLI: openclaw agents add <name> --workspace <path> [--model <model>]
966
+ const name = params.name as string | undefined;
967
+ const workspace = (params.workspace as string | undefined) ?? `~/.openclaw/agents/${name}`;
968
+ const model = params.model as string | undefined;
969
+ if (!name) {
970
+ await sendRpcReply(null, "agents.create: missing required param 'name'");
971
+ } else {
972
+ let cmd = `openclaw agents add ${name} --workspace ${workspace}`;
973
+ if (model) cmd += ` --model ${model}`;
974
+ ctx.log?.info?.(`[${CHANNEL_ID}] agents.create cmd: ${cmd}`);
975
+ const result = await runtime.system.runCommandWithTimeout(cmd, 15000);
976
+ ctx.log?.info?.(`[${CHANNEL_ID}] agents.create result: ${JSON.stringify(result)}`);
977
+ if (result.exitCode !== 0) {
978
+ await sendRpcReply(null, `Command failed (exit ${result.exitCode}): ${result.stderr ?? result.stdout ?? ''}`);
979
+ } else {
980
+ await sendRpcReply({ name, workspace, output: result.stdout ?? '' });
981
+ }
982
+ }
956
983
  } else {
957
984
  await sendRpcReply(null, `Unknown RPC method: ${method}`);
958
985
  }
@@ -999,13 +1026,17 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
999
1026
  });
1000
1027
 
1001
1028
  // Derive an isolated Gateway session for each mobile conversation.
1002
- // If the app provides an agentId, route to that agent's session:
1003
- // agent:<agentId>:mobile-<appSessionKey>
1004
- // Otherwise fall back to the default main agent route.
1005
- let sessionKey: string;
1029
+ //
1030
+ // chatSessionKey format from app: "agent:<agentId>:<uuid1>-<uuid2>"
1031
+ // We use this as the stable per-conversation identity on the Gateway side.
1032
+ // appSessionKey is the wire-level connection ID — used for E2E reply routing.
1006
1033
  const appSessionKey = msg.sessionKey ? String(msg.sessionKey) : null;
1007
1034
  const msgAgentId = msg.agentId ? String(msg.agentId) : null;
1008
- if (appSessionKey) {
1035
+ let sessionKey: string;
1036
+ if (chatSessionKey) {
1037
+ // chatSessionKey from app: "agent:<agentId>:<uuid>" — use as-is for Gateway routing
1038
+ sessionKey = chatSessionKey;
1039
+ } else if (appSessionKey) {
1009
1040
  const agentId = msgAgentId || 'main';
1010
1041
  sessionKey = `agent:${agentId}:mobile-${appSessionKey}`;
1011
1042
  } else {
@@ -1177,4 +1208,4 @@ export default function register(api: any) {
1177
1208
  });
1178
1209
 
1179
1210
  api.logger?.info?.("[openclaw-app] Plugin registered");
1180
- }
1211
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-app",
3
3
  "name": "OpenClaw App",
4
- "version": "1.1.4",
4
+ "version": "1.1.6",
5
5
  "description": "Mobile app channel for OpenClaw — chat via the OpenClaw App app through a Cloudflare Worker relay.",
6
6
  "channels": [
7
7
  "openclaw-app"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-app",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "OpenClaw App channel plugin — relay bridge for the OpenClaw App app",
5
5
  "main": "index.ts",
6
6
  "type": "module",