Skip to content

feat: cross-gateway sessions_send and sessions_spawn via gateway.peers#43656

Closed
SPFAdvisors wants to merge 2 commits into
openclaw:mainfrom
SPFAdvisors:feat/43605-cross-gateway-sessions
Closed

feat: cross-gateway sessions_send and sessions_spawn via gateway.peers#43656
SPFAdvisors wants to merge 2 commits into
openclaw:mainfrom
SPFAdvisors:feat/43605-cross-gateway-sessions

Conversation

@SPFAdvisors

Copy link
Copy Markdown

Problem

sessions_send and sessions_spawn only work within a single gateway. In multi-machine setups (agents split across MacBook, iMac, Mac Studio — each running their own OpenClaw gateway), there's no native way for agents to communicate cross-gateway. The current workaround is SSH scripts (msg-jarvis), which are fragile and bypass all gateway auth/routing.

Solution

Add cross-gateway routing to session tools via three complementary mechanisms:

1. gateway.peers config map (new)

Named peer gateways so agents can target remote gateways by name instead of raw URLs:

gateway:
  peers:
    imac:
      url: wss://imac.local:18789
      token: \${env:IMAC_GATEWAY_TOKEN}
    studio:
      url: wss://studio.local:18789

Peer tokens support SecretInput (env refs, secret stores, plaintext).

2. sessions_send: gateway / gatewayUrl / gatewayToken params

sessions_send(sessionKey="agent:jarvis:main", message="hello", gateway="imac")
sessions_send(sessionKey="agent:pepper:main", message="hi", gatewayUrl="wss://custom:18789", gatewayToken="tok")

When cross-gateway params are present:

  • Label resolution happens on the remote gateway
  • Message is sent via remote agent method
  • Wait + history fetch all route to remote
  • Response includes remote: true flag
  • Local session resolution, visibility checks, and A2A flow are bypassed (the remote gateway owns those)

3. sessions_spawn: same params

sessions_spawn(task="run tests", agentId="pepper", gateway="studio")

Forwards spawn as an agent message to the remote gateway.

Shared helper: gateway-peer.ts

Resolves cross-gateway targeting from tool params:

  1. gateway: "peerName" → looks up gateway.peers[peerName]
  2. gatewayUrl + optional gatewayToken → explicit URL override
  3. Neither → local gateway (returns undefined, no behavior change)

Peer names take precedence when both gateway and gatewayUrl are provided.

Design notes

  • Zero breaking changes — local path is completely unchanged
  • Pattern already existsmessage, cron, gateway, nodes, canvas tools already accept gatewayUrl/gatewayToken; this extends the pattern to session tools
  • Security — peer URLs are validated through existing resolveGatewayOptions() which enforces URL format and token resolution rules

Changes

File Change
config/zod-schema.ts gateway.peers record schema
config/types.gateway.ts GatewayPeerConfig type
config/schema.labels.ts Label for gateway.peers
config/schema.help.ts Help text for gateway.peers
agents/tools/gateway-peer.ts New — shared peer resolution helper
agents/tools/sessions-send-tool.ts Cross-gateway fast path + 3 new schema params
agents/tools/sessions-spawn-tool.ts Cross-gateway fast path + 3 new schema params
agents/tools/gateway-peer.test.ts New — 9 tests for peer resolution

Tests

  • 9 new peer resolution tests (named peer, missing peer, explicit URL, precedence, error messages)
  • 17 existing sessions tests pass
  • 32 existing config schema tests pass

Closes #43605

Add cross-gateway messaging support so agents on different machines
(each running their own OpenClaw gateway) can communicate natively
without SSH script workarounds.

Changes:

1. gateway.peers config map (name -> {url, token})
   - Zod schema, TypeScript type, schema label + help
   - Peer tokens support SecretInput (env refs, secret stores)

2. sessions_send: gateway/gatewayUrl/gatewayToken params
   - Named peer: gateway="imac" resolves from config
   - Explicit: gatewayUrl + gatewayToken for ad-hoc targets
   - Cross-gateway path: resolve label, send message, wait for
     reply, fetch history — all via remote callGateway()
   - Local path unchanged (zero breaking changes)

3. sessions_spawn: same gateway/gatewayUrl/gatewayToken params
   - Forwards spawn as agent message to remote gateway
   - Returns {status, runId, remote: true}

4. gateway-peer.ts: shared peer resolution helper
   - Resolves named peers from config with token resolution
   - Falls back to explicit gatewayUrl
   - Clear error messages with available peer names

5. Tests: 9 new tests for peer resolution (all passing)
   - Named peer with/without token
   - Missing peer, no peers configured
   - Explicit URL override, precedence rules
   - Existing 17 sessions tests + 32 config tests still pass

Config example:
  gateway:
    peers:
      imac:
        url: wss://imac.local:18789
        token: ${env:IMAC_GATEWAY_TOKEN}
      studio:
        url: wss://studio.local:18789
        token: ${env:STUDIO_GATEWAY_TOKEN}

Usage:
  sessions_send(sessionKey="agent:jarvis:main", message="hello", gateway="imac")
  sessions_spawn(task="run tests", agentId="pepper", gateway="studio")

Closes openclaw#43605
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M labels Mar 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb76211b4c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/tools/sessions-send-tool.ts Outdated
? Math.max(0, Math.floor(params.timeoutSeconds))
: 30;
const timeoutMs = timeoutSeconds * 1000;
const gateway = resolveGatewayOptions(peerOpts);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept configured peer URLs in cross-gateway session routing

This path resolves gateway.peers and then immediately calls resolveGatewayOptions(peerOpts), but resolveGatewayOptions still enforces gatewayUrl to be loopback or gateway.remote.url via validateGatewayUrlOverrideForAgentTools (src/agents/tools/gateway.ts). In practice, a peer like wss://imac.local:18789 is rejected with gatewayUrl override rejected, so the new gateway parameter cannot reach most configured peers (same failure pattern also applies to sessions_spawn).

Useful? React with 👍 / 👎.

Comment on lines +132 to +134
params: {
message: task,
...(sessionKey ? { sessionKey } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include idempotencyKey when forwarding remote sessions_spawn

The remote sessions_spawn fast path forwards to the gateway agent method, but this request body omits idempotencyKey. The gateway protocol requires idempotencyKey for agent requests (AgentParamsSchema), so any sessions_spawn call with gateway/gatewayUrl will be rejected as invalid params before the remote agent run starts.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds cross-gateway routing to sessions_send and sessions_spawn via a new gateway.peers config map and a shared gateway-peer.ts resolution helper. The design — named peers, explicit URL override, and a local-gateway fallback — fits cleanly into the existing pattern used by other tools (message, cron, canvas).

However, there is a critical runtime bug that makes the core feature non-functional:

  • resolveGatewayOptions rejects all peer URLs (src/agents/tools/sessions-send-tool.ts:88, src/agents/tools/sessions-spawn-tool.ts:121): The function internally calls validateGatewayUrlOverrideForAgentTools, which only permits loopback addresses or the single gateway.remote.url. Any peer URL like wss://imac.local:18789 will throw "gatewayUrl override rejected" as an uncaught exception, breaking every cross-gateway call.
  • Silent token resolution failure (src/agents/tools/gateway-peer.ts:48-51): When a ${env:...} token reference can't be resolved, the error is swallowed and the call proceeds without auth, producing a confusing downstream rejection instead of a clear config error.
  • Silently dropped spawn parameters (src/agents/tools/sessions-spawn-tool.ts:127-146): runtime, model, cwd, mode, attachments, and other spawn-specific params are silently discarded when routing cross-gateway. Callers receive no indication these params were ignored.
  • No URL format validation in Zod schema (src/config/zod-schema.ts:813): url accepts any string; invalid protocols or malformed URLs only surface at runtime.

Confidence Score: 1/5

  • Not safe to merge — the cross-gateway routing will fail at runtime for all peer URLs due to an incompatible URL validation check in resolveGatewayOptions.
  • The primary feature (cross-gateway sessions routing) is broken by a logic conflict with existing URL validation: resolveGatewayOptions enforces a strict allowlist (loopback + configured remote only) that categorically rejects the arbitrary peer URLs this feature depends on. The call is also uncaught, so it surfaces as an unhandled exception rather than a graceful error. Additionally, sessions_spawn silently drops caller-provided parameters when routing cross-gateway, which is a subtle but significant behavior gap. The config and type changes are clean, and the helper unit tests are well-written, but they don't cover the end-to-end routing path where the bug lives.
  • src/agents/tools/sessions-send-tool.ts and src/agents/tools/sessions-spawn-tool.ts — both call resolveGatewayOptions(peerOpts) without catching the URL-rejection error it will throw for any real peer URL.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/tools/sessions-send-tool.ts
Line: 88

Comment:
**`resolveGatewayOptions` rejects all peer URLs — cross-gateway routing will always fail**

`resolveGatewayOptions` calls `validateGatewayUrlOverrideForAgentTools` internally, which only permits two categories of URL:
1. Loopback addresses (`127.0.0.1`, `localhost`, `[::1]`) on the configured local port
2. Exactly the URL in `gateway.remote.url`

Any peer URL like `wss://imac.local:18789` will cause `validateGatewayUrlOverrideForAgentTools` to throw:
```
"gatewayUrl override rejected. Allowed: ws(s) loopback on port X ..."
```

This error is **not caught** here — it will propagate as an unhandled exception and break the tool call. The same problem exists in `sessions-spawn-tool.ts` at the equivalent `resolveGatewayOptions(peerOpts)` call.

The PR description states "peer URLs are validated through existing `resolveGatewayOptions()`", but that function's allowlist was designed for a single remote gateway, not for arbitrary peer URLs. The cross-gateway feature will be entirely broken for any peer that is not also the configured `gateway.remote.url`.

The fix is to bypass `resolveGatewayOptions` for peer URLs that have already been validated by the config schema, and call `callGateway` directly with the resolved URL and token from `peerOpts`, similar to what the local path does but without the URL re-validation step.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/tools/gateway-peer.ts
Line: 48-51

Comment:
**Silent token resolution failure produces misleading auth errors**

When `resolveSecretInputString` fails (e.g., because `${env:IMAC_GATEWAY_TOKEN}` references an env var that isn't set), the error is silently swallowed. `resolvedToken` remains `undefined`, and the peer call proceeds without auth. The remote gateway will then reject the request with an authentication error that gives the user no indication that their token config is broken.

While the comment says "non-fatal if the peer gateway doesn't require auth", this hides a clear configuration error (a missing env var) behind a confusing downstream failure. At a minimum, the resolution failure should be surfaced as a warning in the thrown error message or re-thrown when the result is `undefined` and a token was explicitly configured.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/tools/sessions-spawn-tool.ts
Line: 127-146

Comment:
**Cross-gateway spawn silently drops all spawn-specific parameters**

When `peerOpts` is set, only `message`, `sessionKey`, `label`, `deliver`, `channel`, and `inputProvenance` are forwarded to the remote gateway. All of the following caller-provided parameters are silently ignored:

- `runtime` (subagent vs acp)
- `model`
- `thinking`
- `cwd`
- `runTimeoutSeconds` / `timeoutSeconds`
- `mode` (run vs session)
- `cleanup`
- `sandbox`
- `streamTo`
- `attachments` / `attachAs`
- `resumeSessionId`

A caller doing `sessions_spawn(task="...", agentId="pepper", gateway="studio", runtime="acp", model="gpt-4o")` will silently get whatever defaults the remote gateway applies, not the requested `runtime` or `model`. If these parameters are intentionally not supported for cross-gateway spawning, the tool should validate and reject their presence explicitly (like `UNSUPPORTED_SESSIONS_SPAWN_PARAM_KEYS` does for channel params) rather than silently dropping them.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/config/zod-schema.ts
Line: 813

Comment:
**No URL format validation on `gateway.peers[*].url`**

The `url` field is accepted as any non-empty string. A misconfigured value like `"http://imac.local:18789"` (wrong protocol) or `"imac.local:18789"` (missing scheme) will only fail at runtime when the connection is attempted, producing a confusing error rather than a clear config validation message.

Consider adding a `.url()` or a `refine` check for `ws://` / `wss://` prefix to catch misconfigurations at startup:
```suggestion
                url: z.string().refine(
                  (v) => v.startsWith("ws://") || v.startsWith("wss://"),
                  { message: "gateway peer url must start with ws:// or wss://" },
                ),
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: fb76211

Comment thread src/agents/tools/sessions-send-tool.ts Outdated
? Math.max(0, Math.floor(params.timeoutSeconds))
: 30;
const timeoutMs = timeoutSeconds * 1000;
const gateway = resolveGatewayOptions(peerOpts);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveGatewayOptions rejects all peer URLs — cross-gateway routing will always fail

resolveGatewayOptions calls validateGatewayUrlOverrideForAgentTools internally, which only permits two categories of URL:

  1. Loopback addresses (127.0.0.1, localhost, [::1]) on the configured local port
  2. Exactly the URL in gateway.remote.url

Any peer URL like wss://imac.local:18789 will cause validateGatewayUrlOverrideForAgentTools to throw:

"gatewayUrl override rejected. Allowed: ws(s) loopback on port X ..."

This error is not caught here — it will propagate as an unhandled exception and break the tool call. The same problem exists in sessions-spawn-tool.ts at the equivalent resolveGatewayOptions(peerOpts) call.

The PR description states "peer URLs are validated through existing resolveGatewayOptions()", but that function's allowlist was designed for a single remote gateway, not for arbitrary peer URLs. The cross-gateway feature will be entirely broken for any peer that is not also the configured gateway.remote.url.

The fix is to bypass resolveGatewayOptions for peer URLs that have already been validated by the config schema, and call callGateway directly with the resolved URL and token from peerOpts, similar to what the local path does but without the URL re-validation step.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tools/sessions-send-tool.ts
Line: 88

Comment:
**`resolveGatewayOptions` rejects all peer URLs — cross-gateway routing will always fail**

`resolveGatewayOptions` calls `validateGatewayUrlOverrideForAgentTools` internally, which only permits two categories of URL:
1. Loopback addresses (`127.0.0.1`, `localhost`, `[::1]`) on the configured local port
2. Exactly the URL in `gateway.remote.url`

Any peer URL like `wss://imac.local:18789` will cause `validateGatewayUrlOverrideForAgentTools` to throw:
```
"gatewayUrl override rejected. Allowed: ws(s) loopback on port X ..."
```

This error is **not caught** here — it will propagate as an unhandled exception and break the tool call. The same problem exists in `sessions-spawn-tool.ts` at the equivalent `resolveGatewayOptions(peerOpts)` call.

The PR description states "peer URLs are validated through existing `resolveGatewayOptions()`", but that function's allowlist was designed for a single remote gateway, not for arbitrary peer URLs. The cross-gateway feature will be entirely broken for any peer that is not also the configured `gateway.remote.url`.

The fix is to bypass `resolveGatewayOptions` for peer URLs that have already been validated by the config schema, and call `callGateway` directly with the resolved URL and token from `peerOpts`, similar to what the local path does but without the URL re-validation step.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread src/agents/tools/gateway-peer.ts Outdated
Comment on lines +48 to +51
} catch {
// Fall through — token resolution failure is non-fatal if the peer
// gateway doesn't require auth.
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent token resolution failure produces misleading auth errors

When resolveSecretInputString fails (e.g., because ${env:IMAC_GATEWAY_TOKEN} references an env var that isn't set), the error is silently swallowed. resolvedToken remains undefined, and the peer call proceeds without auth. The remote gateway will then reject the request with an authentication error that gives the user no indication that their token config is broken.

While the comment says "non-fatal if the peer gateway doesn't require auth", this hides a clear configuration error (a missing env var) behind a confusing downstream failure. At a minimum, the resolution failure should be surfaced as a warning in the thrown error message or re-thrown when the result is undefined and a token was explicitly configured.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tools/gateway-peer.ts
Line: 48-51

Comment:
**Silent token resolution failure produces misleading auth errors**

When `resolveSecretInputString` fails (e.g., because `${env:IMAC_GATEWAY_TOKEN}` references an env var that isn't set), the error is silently swallowed. `resolvedToken` remains `undefined`, and the peer call proceeds without auth. The remote gateway will then reject the request with an authentication error that gives the user no indication that their token config is broken.

While the comment says "non-fatal if the peer gateway doesn't require auth", this hides a clear configuration error (a missing env var) behind a confusing downstream failure. At a minimum, the resolution failure should be surfaced as a warning in the thrown error message or re-thrown when the result is `undefined` and a token was explicitly configured.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +127 to +146
try {
const response = await callGateway<{ runId?: string }>({
url: gateway.url,
token: gateway.token,
method: "agent",
params: {
message: task,
...(sessionKey ? { sessionKey } : {}),
...(label ? { label } : {}),
deliver: false,
channel: "internal",
inputProvenance: {
kind: "inter_session",
sourceSessionKey: opts?.agentSessionKey,
sourceChannel: opts?.agentChannel,
sourceTool: "sessions_spawn",
},
},
timeoutMs: 15_000,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cross-gateway spawn silently drops all spawn-specific parameters

When peerOpts is set, only message, sessionKey, label, deliver, channel, and inputProvenance are forwarded to the remote gateway. All of the following caller-provided parameters are silently ignored:

  • runtime (subagent vs acp)
  • model
  • thinking
  • cwd
  • runTimeoutSeconds / timeoutSeconds
  • mode (run vs session)
  • cleanup
  • sandbox
  • streamTo
  • attachments / attachAs
  • resumeSessionId

A caller doing sessions_spawn(task="...", agentId="pepper", gateway="studio", runtime="acp", model="gpt-4o") will silently get whatever defaults the remote gateway applies, not the requested runtime or model. If these parameters are intentionally not supported for cross-gateway spawning, the tool should validate and reject their presence explicitly (like UNSUPPORTED_SESSIONS_SPAWN_PARAM_KEYS does for channel params) rather than silently dropping them.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tools/sessions-spawn-tool.ts
Line: 127-146

Comment:
**Cross-gateway spawn silently drops all spawn-specific parameters**

When `peerOpts` is set, only `message`, `sessionKey`, `label`, `deliver`, `channel`, and `inputProvenance` are forwarded to the remote gateway. All of the following caller-provided parameters are silently ignored:

- `runtime` (subagent vs acp)
- `model`
- `thinking`
- `cwd`
- `runTimeoutSeconds` / `timeoutSeconds`
- `mode` (run vs session)
- `cleanup`
- `sandbox`
- `streamTo`
- `attachments` / `attachAs`
- `resumeSessionId`

A caller doing `sessions_spawn(task="...", agentId="pepper", gateway="studio", runtime="acp", model="gpt-4o")` will silently get whatever defaults the remote gateway applies, not the requested `runtime` or `model`. If these parameters are intentionally not supported for cross-gateway spawning, the tool should validate and reject their presence explicitly (like `UNSUPPORTED_SESSIONS_SPAWN_PARAM_KEYS` does for channel params) rather than silently dropping them.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread src/config/zod-schema.ts Outdated
z.string().min(1),
z
.object({
url: z.string(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No URL format validation on gateway.peers[*].url

The url field is accepted as any non-empty string. A misconfigured value like "http://imac.local:18789" (wrong protocol) or "imac.local:18789" (missing scheme) will only fail at runtime when the connection is attempted, producing a confusing error rather than a clear config validation message.

Consider adding a .url() or a refine check for ws:// / wss:// prefix to catch misconfigurations at startup:

Suggested change
url: z.string(),
url: z.string().refine(
(v) => v.startsWith("ws://") || v.startsWith("wss://"),
{ message: "gateway peer url must start with ws:// or wss://" },
),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/zod-schema.ts
Line: 813

Comment:
**No URL format validation on `gateway.peers[*].url`**

The `url` field is accepted as any non-empty string. A misconfigured value like `"http://imac.local:18789"` (wrong protocol) or `"imac.local:18789"` (missing scheme) will only fail at runtime when the connection is attempted, producing a confusing error rather than a clear config validation message.

Consider adding a `.url()` or a `refine` check for `ws://` / `wss://` prefix to catch misconfigurations at startup:
```suggestion
                url: z.string().refine(
                  (v) => v.startsWith("ws://") || v.startsWith("wss://"),
                  { message: "gateway peer url must start with ws:// or wss://" },
                ),
```

How can I resolve this? If you propose a fix, please make it concise.

1. Bypass resolveGatewayOptions for peer URLs — it only allows
   loopback/remote URLs, rejecting valid peer addresses like
   wss://imac.local:18789. Both sessions-send-tool and
   sessions-spawn-tool now pass peer URL/token directly to callGateway.

2. Throw on token resolution failure in gateway-peer.ts — previously
   silently swallowed, which would cause auth failures on the remote
   gateway with no indication of misconfiguration.

3. Reject unsupported spawn parameters for cross-gateway spawns —
   runtime, model, thinking, cwd, timeouts, mode, cleanup, sandbox,
   streamTo, thread, attachments, resumeSessionId are local-only and
   were silently dropped. Now returns explicit error listing which
   params are unsupported.

4. Add ws:///wss:// URL format validation on gateway.peers URL in
   zod-schema via .refine() check.

Addresses greptile review on PR openclaw#43656.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85c5b02419

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


return {
gatewayUrl: peer.url.trim(),
gatewayToken: gatewayToken || resolvedToken,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject tokenless peers before routing to overridden gateway

This helper returns peer overrides even when no token is available (gatewayToken resolves to undefined), and both new cross-gateway paths pass that straight into callGateway. callGateway treats any explicit url as an override and requires explicit credentials (ensureExplicitGatewayAuth), so peer entries without a token will fail with "gateway url override requires explicit credentials" before the remote request is attempted. That makes the new optional gateway.peers.<name>.token behavior non-functional for tokenless peers.

Useful? React with 👍 / 👎.

const sessionKeyParam = readStringParam(params, "sessionKey");
const labelParam = readStringParam(params, "label")?.trim() || undefined;
const labelAgentIdParam = readStringParam(params, "agentId")?.trim() || undefined;
if (!sessionKeyParam && !labelParam) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve sessionKey/label exclusivity in remote sessions_send

The remote branch only checks for the "neither provided" case, so when both sessionKey and label are sent it silently prefers sessionKey and skips label resolution. The local branch still rejects this combination, so cross-gateway behavior becomes inconsistent and can route messages to an unintended session instead of surfacing an input error.

Useful? React with 👍 / 👎.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 27, 2026
@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed July 8, 2026, 11:23 AM ET / 15:23 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

PR surface: Source +397, Tests +97. Total +494 across 8 files.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: serialized state: src/agents/tools/sessions-send-tool.ts, serialized state: src/agents/tools/sessions-spawn-tool.ts, unknown-data-model-change: src/agents/tools/sessions-send-tool.ts, unknown-data-model-change: src/agents/tools/sessions-spawn-tool.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Not assessed.
Failure reason: timeout.

This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict.
Keep any merge decision on the normal maintainer review path until ClawSweeper can complete a fresh review.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • Review did not complete, so no work-lane recommendation was made.
Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against fc05a8103b72.

Label changes

Label changes:

  • remove P1: Current review triage priority is none.
  • remove rating: 🧂 unranked krab: Current review failed before PR readiness was assessed, so no rating label should remain.
  • remove merge-risk: 🚨 session-state: Current PR review selected no merge-risk labels.
  • remove merge-risk: 🚨 message-delivery: Current PR review selected no merge-risk labels.
  • remove merge-risk: 🚨 security-boundary: Current PR review selected no merge-risk labels.
  • remove status: 📣 needs proof: Current PR status no longer selects a status label.
Evidence reviewed

PR surface:

Source +397, Tests +97. Total +494 across 8 files.

View PR surface stats
Area Files Added Removed Net
Source 7 397 0 +397
Tests 1 97 0 +97
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 8 494 0 +494

What I checked:

  • failure reason: timeout.
  • codex failure detail: Codex review failed for this PR: Codex process timed out after 1200000ms.
  • codex stderr: No stderr captured.
  • codex stdout: \n- Maintainers can also comment @clawsweeper review to request a fresh review only.\n- Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.\n- Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.\n- Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.\n\n\u003c/details\u003e\n\n\u003c!-- clawsweeper-verdict:needs-human item=43656 sha=85c5b02419c2a2390465f74d2daa45a047d7e746 confidence=low --\u003e\n\n\u003c!-- clawsweeper-review item=43656 --\u003e","createdAt":"2026-04-27T05:20:44Z"},{"author":"clawsweeper","body":"ClawSweeper PR egg\n\n🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.\n\n\u003cdetails\u003e\n\u003csummary\u003eWhere did th.
  • process error code: ETIMEDOUT.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 28, 2026
@clawsweeper clawsweeper Bot added the P1 High-priority user-facing bug, regression, or broken workflow. label May 16, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 16, 2026
@clawsweeper clawsweeper Bot added impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. impact:message-loss Channel message delivery can be lost, duplicated, or misrouted. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. and removed impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. impact:message-loss Channel message delivery can be lost, duplicated, or misrouted. labels May 17, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 18, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 20, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 5, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 16, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 16, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 16, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 1, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closing this implementation while keeping #43605 open as the canonical issue.

The March 13 head is conflicting, has no current multi-gateway proof, and still omits the required spawn idempotency key. The raw gatewayUrl path also bypasses the existing agent-tool URL allowlist, so this needs a fresh product and security design rather than repair of the stale branch.

Thanks @SPFAdvisors for exploring the feature.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Cross-gateway messaging (sessions_send between machines)

2 participants