An OpenClaw plugin that maximises prompt-cache hit rates when using CloudSigma TaaS as your LLM provider.
It injects a stable, per-conversation session ID into every outbound request so TaaS can pin your conversation to the same upstream slot (OAuth token, Bedrock region, or Claude Code node) from the very first turn — giving you consistent prompt-cache reuse instead of cold starts on every message.
TaaS routes LLM requests across a pool of upstream slots. Without a session signal, it uses heuristics to guess which requests belong to the same conversation:
| Method | Confidence | Works when |
|---|---|---|
| Tool-use ID chain | 1.0 | Tool-result follow-up turns only |
| Structural inference | 0.85 | Mid-conversation, after a few turns |
| New session fallback | 0.30 | First turn — no prior context |
That 0.30 confidence on turn 1 means the first message in every conversation is likely routed to a random slot, breaking prompt-cache continuity right from the start.
This plugin passes a stable session_id derived from your OpenClaw workspace so TaaS short-circuits heuristic matching and achieves confidence 1.0 from turn 1.
OpenClaw's wrapStreamFn hook intercepts the outbound request payload before it is sent to TaaS. The plugin adds two fields:
{
"metadata": {
"session_id": "oc:edebc39a82a8a041",
"sticky_key": "oc:edebc39a82a8a041"
}
}session_id— read by TaaS's OpenAI and Codex affinity pathssticky_key— additionally read by the Anthropic substrate routing layer
Both fields point to the same value. Additionally, the plugin injects an X-Session-Id request header via the resolveTransportTurnState hook, for transport layers that support per-turn native headers.
The ID is a SHA-256 hash of the session source, truncated to 16 hex chars and prefixed oc:. The plugin walks through a tier list to find the best available source:
| Tier | Source | Notes |
|---|---|---|
| 1 | ctx.workspaceDir (explicit) |
Best signal — populated for main agent and many subagents |
| 2 | globalThis[pluginRegistryState].workspaceDir |
Parent agent workspace via plugin registry |
| 3 | process.env.OPENCLAW_SESSION_ID |
If OpenClaw sets this env var for sub-agents in future |
| 4 | process.env.OPENCLAW_AGENT_ID / OPENCLAW_RUN_ID |
Any stable per-agent env var |
| 5 | OPENCLAW_STATE_DIR hash |
Per-installation fallback — least specific |
| Property | Detail |
|---|---|
| Stable | Same value for every API turn within one conversation |
| Unique | Different workspaces / env vars → different IDs |
Resets on /new |
New conversation = new workspace = new ID |
| Namespaced | oc: prefix avoids collision with Claude Code and other TaaS clients |
Example IDs:
oc:edebc39a82a8a041 ← main agent session
oc:4ae2870a2e73027c ← subagent spawned from the above
oc:a1b2c3d4e5f60718 ← same agent, next conversation
OpenClaw sub-agents run in isolated processes and may not receive a workspaceDir in their wrapStreamFn context. Without this plugin, all sub-agent requests arrive at TaaS with session_id = 'none', breaking affinity.
The tier fallback system ensures sub-agents always get a deterministic session ID:
- If the sub-agent has a workspace (Tier 1) — derives a unique ID from it. Sub-agents get their own ID, separate from the parent.
- If the parent agent workspace is visible via globalThis (Tier 2) — reuses the parent's ID. This is correct behaviour: sub-agents from the same parent conversation share upstream slot affinity.
- If OpenClaw injects env vars (Tiers 3–4) — uses those for a stable per-agent ID.
- Last resort (Tier 5) — falls back to the state dir hash. All sub-agents on the same install share this ID, which still beats
session_id = 'none'for cache-hit purposes.
Set OPENCLAW_DEBUG=1 (or NODE_ENV=development) to emit the session ID source on each request:
[taas-affinity] wrapStreamFn sessionId=oc:edebc39a82a8a041 source=workspaceDir:/home/user/.openclaw/...
[taas-affinity] resolveTransportTurnState sessionId=oc:edebc39a82a8a041 source=workspaceDir:... turnId=abc attempt=1
- OpenClaw ≥ 1.0.0
- TaaS with session-affinity short-circuit support (commit
61a9960+, April 2026) - A CloudSigma account with TaaS access
openclaw plugins install openclaw-token-cache-optimizer
openclaw gateway restart# Clone into your OpenClaw extensions directory
git clone https://github.com/cloudsigma/openclaw-token-cache-optimizer \
~/.openclaw/extensions/openclaw-token-cache-optimizer
# Restart the gateway to load the plugin
openclaw gateway restartThat's it. No openclaw.json changes are required — the plugin auto-activates for all requests to the cloudsigma provider.
openclaw gateway statusYou should see the plugin listed in the startup log:
[plugins] openclaw-token-cache-optimizer: loaded
After installing, the first turn of every new conversation should show:
match_reason: "external_id_new" ← first turn (new session in Redis)
match_reason: "external_id" ← subsequent turns (known session)
Previously turn 1 would show match_reason: "new" with confidence: 0.30.
redis-cli -h redis.taas.svc.cluster.local get "anth:session:oc:edebc39a82a8a041"Replace the ID with your actual session ID. A non-null response confirms TaaS has bound the session to a slot.
| Session type | ID scope |
|---|---|
| Main agent | Own stable ID for the conversation lifetime |
| Spawned subagent | Own ID (separate workspaceDir) |
| Cron / isolated run | Own ID (isolated workspace per run) |
New conversation (/new, /reset) |
New workspace → new ID |
| Parallel conversations | Each gets a separate ID |
None required. The plugin works out of the box with zero configuration.
Issues and PRs welcome. The core logic lives in index.ts.
MIT — see LICENSE.