Skip to content

fix: derive agent-scoped session identity when host omits sessionId - #20

Merged
rjcloudsigma merged 1 commit into
mainfrom
fix/agent-scoped-session-identity
Jul 28, 2026
Merged

fix: derive agent-scoped session identity when host omits sessionId#20
rjcloudsigma merged 1 commit into
mainfrom
fix/agent-scoped-session-identity

Conversation

@rjcloudsigma

Copy link
Copy Markdown
Collaborator

Problem

v0.7.0 injected nothing at all on the transport that carries all agent traffic. Measured in production:

OpenAI session records: 2248  ->  2247 TaaS-minted, 1 caller-supplied
272 requests            ->  272 distinct session ids
continuity              ->  0.0% (anthropic, claude-code and codex)

Consecutive requests scattered across 8 different nodes (jhb-02, fra-03, dub-02, dub-01, zrh-03, zrh-02, mty-04, wdc-04), so session affinity was genuinely not engaging — not merely mis-measured.

Root cause

OpenClaw builds the wrapStreamFn context in extra-params-cce1g0up.js as:

context: {
  config, agentDir, workspaceDir, agentId,
  nativeWebSearchAllowedByToolPolicy,
  provider, modelId, extraParams, thinkingLevel, model, streamFn
}

There is no sessionId. resolveSessionIdentity requires either ctx.sessionId or OPENCLAW_SESSION_ID (absent from the gateway environment), so it returned null and the plugin skipped injection entirely.

The header path cannot compensate: X-Session-Id is emitted from resolveTransportTurnState, which OpenClaw only invokes from the Responses transports. CloudSigma is configured api: "openai-completions", and createOpenAICompletionsTransportStreamFn contains zero turnState references.

Verified directly against the installed build:

WITH ctx.sessionId    -> metadata injected
WITHOUT ctx.sessionId -> metadata: null

Fix

agentId is supplied and is stable for the life of an agent conversation — exactly the granularity affinity needs. When no native session id exists, derive a deterministic identity from it, scoped by workspace, under a distinct agent_scoped mode so it can never be mistaken for a native session id.

Precedence is unchanged: native ctx.sessionIdOPENCLAW_SESSION_ID → agent-scoped fallback → null.

Verification

Against the real production context shape:

PRODUCTION ctx (agentId, NO sessionId):
  session_id : oc:8aeb5e398b8908bd
  sticky_key : oc:8aeb5e398b8908bd
  correlation: {"session_id":"oc:8aeb5e398b8908bd","agent_id":"main",
                "source":"openclaw-taas-affinity","plugin_version":"0.8.0"}

Invariants confirmed:

stable across calls : true
different agent     : true
workspace-scoped    : true
native still wins   : native
no identity -> null : true
  • 16/16 tests pass (11 existing + 5 new in test/agent-scoped-session.test.ts)
  • Typecheck clean; version 0.7.0 → 0.8.0, smoke assertions updated

Companion change

Paired with cloudsigma/taas PR for dual-format identity resolution, so the injected openclaw_correlation envelope is honoured on the OpenAI-compatible endpoint as well as the Anthropic one.

@rjcloudsigma
rjcloudsigma merged commit a5f4246 into main Jul 28, 2026
1 check passed
@rjcloudsigma
rjcloudsigma deleted the fix/agent-scoped-session-identity branch July 28, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant