CloudSigma TaaS affinity provider hook for OpenClaw.
This plugin is intentionally narrow after the Claude Code Direction-2 lane update. It does not lease requester bridges, poll for bridge work, invoke requester-local tools, rewrite OpenAI tool payloads, or run OpenClaw maintenance sidecars.
For requests routed through the cloudsigma or cloudsigma-staging provider IDs, the plugin:
- resolves identity in strict order: invocation
options.sessionId, wrapperctx.sessionId, exact trace bridge, explicit legacy environment fallback - records authoritative
model_call_startedsession identity against the exact W3CtraceId+spanIdexposed through publicctx.trace - resolves generic/provider calls from the matching
StreamOptions.headers.traceparentwhen direct session identity is absent - keeps the trace bridge bounded (1,024 entries), short-lived (30-minute sliding TTL), and fail-closed for malformed or ambiguous correlation
- generates a stable
oc:<sha256-prefix>only as a deprecated compatibility fallback fromOPENCLAW_SESSION_ID - injects
metadata.session_idwhen absent - injects
metadata.sticky_keywhen absent - injects a sanitized
metadata.requester_runtimeenvelope when absent - injects transport header
X-Session-Id - injects correlation headers
X-OpenClaw-Session-Id,X-OpenClaw-Turn-Id,X-OpenClaw-Attempt, andX-OpenClaw-Agent-Id(when available) - injects
metadata.openclaw_correlationfor request/run tracing - captures TaaS autorouter + request/trace response headers
- exposes the latest route capture via gateway method
taas.autorouter.lastRoute - accepts a per-session request override via
taas.autorouter.setAlgorithm - exposes privacy-safe bridge outcome counters via
taas.affinity.stats(hits, misses, expiries, ambiguous traces, and direct invocation IDs); no trace or session values are returned
The manifest explicitly asks OpenClaw to import the plugin at gateway startup:
{
"activation": {
"onStartup": true,
"onProviders": ["cloudsigma", "cloudsigma-staging"]
}
}This is required because gateway RPC handlers must be attached during gateway startup. Provider/lazy activation is not enough for taas.autorouter.lastRoute to be present in the live gateway dispatch table.
On OpenClaw versions that expose the public model_call_started lifecycle hook, the plugin feature-detects api.on, records an authoritative non-empty ctx.sessionId (while checking event.sessionId for consistency), and requires an exact valid W3C trace/span match in the later provider invocation. It never uses timing, agent ID, workspace, session key, or a process-global "current session" for correlation. Exact successful matches refresh a 30-minute sliding bridge TTL so delayed retries remain safe; TaaS retains the resulting session affinity independently for seven days.
Older OpenClaw versions without this hook continue to work when options.sessionId, wrapper ctx.sessionId, or the explicit legacy OPENCLAW_SESSION_ID is available. Calls without one of those strong identities remain affinity-less.
Example injected metadata:
{
"metadata": {
"session_id": "oc:0123456789abcdef",
"sticky_key": "oc:0123456789abcdef",
"requester_runtime": {
"schema_version": "2026-06-04",
"source": "openclaw-taas-affinity",
"session_key": "oc:0123456789abcdef",
"openclaw_session_id": "oc:0123456789abcdef",
"requester_host_id": "host:1a2b3c4d5e6f7890",
"repo_name": "example-repo",
"git_branch_hint": "dev",
"git_dirty_hint": false,
"provider": "cloudsigma",
"model_id": "cloudsigma/auto",
"session_source_hint": "source:1a2b3c4d5e6f7890",
"tool_execution": "direction_2_gateway",
"metadata_classification": {
"identifiers": "hashed",
"repository": "name_branch_dirty_only",
"local_paths": "omitted_by_default"
},
"redaction_policy": "no_secrets;no_raw_local_paths;no_env_values;no_git_remotes;no_status_or_diffs;no_extra_params"
},
"openclaw_correlation": {
"schema_version": "2026-06-05",
"source": "openclaw-taas-affinity",
"plugin_version": "0.12.0",
"session_id": "oc:0123456789abcdef",
"sticky_key": "oc:0123456789abcdef",
"session_source_hint": "source:1a2b3c4d5e6f7890",
"agent_id": "new-agent-2",
"provider": "cloudsigma",
"model_id": "cloudsigma/auto"
}
}
}All metadata fields, including openclaw_correlation, are no-overwrite. If the caller already supplied metadata.session_id, metadata.sticky_key, metadata.requester_runtime, or metadata.openclaw_correlation, the plugin leaves them intact.
The plugin does not include raw local paths (workspace_dir, agent_dir, repo_root_hint), environment variables, tokens, git remotes, full git status output, diffs, or arbitrary provider extraParams.
Requester-side tool execution is handled outside this plugin by the Claude Code / TaaS / OpenClaw Direction-2 path.
The plugin intentionally leaves these payload structures untouched:
- OpenAI
tools tool_choice- assistant
tool_calls role: "tool"continuation messages
It also does not inject:
requester_runtime.available_bridgescapture_mode: "bridge_capable"- bridge operation names such as
requester.tool.invoke,openclaw.tool.invoke,bridge.ping, orbridge.echo
TaaS may return response headers such as:
X-TaaS-Autorouted: trueX-TaaS-Autorouter-ModelX-TaaS-Autorouter-ModeX-TaaS-Autorouter-Algorithm-SourceX-TaaS-Thinking-AppliedX-TaaS-Routed-Context-Window
The plugin stores the latest bounded capture per affinity session and per derived OpenClaw agent ID.
Query latest route by agent:
openclaw gateway call taas.autorouter.lastRoute \
--params '{"agentId":"new-agent-2"}' \
--jsonQuery by explicit affinity session ID:
openclaw gateway call taas.autorouter.lastRoute \
--params '{"sessionId":"oc:0123456789abcdef"}' \
--jsonQuery by native OpenClaw session ID:
openclaw gateway call taas.autorouter.lastRoute \
--params '{"localSessionId":"a5add102-d79b-4168-8a2a-6dd75135f73b"}' \
--jsoncd /home/cloudsigma/openclaw-taas-affinity
npm ci
npm test
npm run build
rsync -a --delete \
--exclude '.git' \
--exclude 'node_modules' \
--exclude 'package-lock.json' \
./ ~/.openclaw/extensions/openclaw-taas-affinity/
cd ~/.openclaw/extensions/openclaw-taas-affinity
npm ci --omit=dev --ignore-scriptsThen restart the managed gateway service during a controlled window:
systemctl --user restart openclaw-gateway.serviceVerify:
openclaw gateway status
openclaw plugins info openclaw-taas-affinity
openclaw gateway call taas.autorouter.lastRoute --params '{"agentId":"new-agent-2"}' --jsonnpm run typecheck
npm run smoke
npm run unit
npm test
npm run buildCurrent tests cover:
- direct GPT invocation identity and strict precedence
- Kimi and generic CloudSigma trace-bridge identity
- simple-completion trace bridging
- concurrent traces, same-trace retries, and subagent isolation
- malformed, absent, expired, oversized, or ambiguous trace state failing closed
- graceful operation when the lifecycle hook is unavailable
- manifest startup activation
- provider hook registration for
cloudsigmaandcloudsigma-staging - metadata/header injection
- no-overwrite behavior
- absence of requester bridge descriptors
- OpenAI tool payload pass-through
- autorouter capture and lookup by workspace/session/agent
| Variable | Default | Purpose |
|---|---|---|
OPENCLAW_DEBUG |
unset | Emit debug logs for session source and autorouter capture |
OPENCLAW_SESSION_ID |
unset | Deprecated compatibility fallback for runtimes that do not supply native ctx.sessionId |
OPENCLAW_AGENT_ID / OPENCLAW_RUN_ID |
unset | Agent label used only for autorouter capture lookup; never a session-identity source |
OPENCLAW_STATE_DIR |
~/.openclaw |
Used only to construct a hashed diagnostic source hint |
Requester bridge variables such as TAAS_REQUESTER_BRIDGE_PLUGIN_ENABLED, TAAS_REQUESTER_BRIDGE_LEASE_URL, and TAAS_REQUESTER_BRIDGE_POLL_INTERVAL_MS are obsolete and ignored by this plugin version.