Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const REQUESTER_RUNTIME_SCHEMA_VERSION = "2026-06-04"
const REQUESTER_RUNTIME_SOURCE = "openclaw-taas-affinity"
const GIT_PROBE_TIMEOUT_MS = 250
const LAST_ROUTE_LIMIT = 256
const PLUGIN_VERSION = "0.8.0"
const PLUGIN_VERSION = "0.9.0"

// OpenClaw stores active registry state (including workspaceDir) on globalThis
// under this well-known symbol key.
Expand Down Expand Up @@ -498,14 +498,22 @@ export default {
"pin sessions to the same upstream slot from turn 1, maximising prompt-cache hit rates.",

register(api: OpenClawPluginApi) {
// The runtime supports wrapSimpleCompletionStreamFn, but the installed
// plugin-sdk ProviderPlugin declaration lags that optional hook. Keep the
// compatibility cast scoped to this registration object.
api.registerProvider({
id: "taas-affinity-hook",
label: "CloudSigma TaaS Token Cache Optimizer",
hookAliases: ["cloudsigma", "cloudsigma-staging"],
auth: [],
// Full agent/tool runs use wrapStreamFn. Internal/background/simple
// completions use a separate OpenClaw hook; omitting it created a
// second identity-less population on the same Snowcrash API key.
// Both surfaces must inject identical session/sticky metadata.
wrapStreamFn: buildWrapper,
wrapSimpleCompletionStreamFn: buildWrapper,
resolveTransportTurnState: buildTransportTurnState,
})
} as any)

if (typeof api.registerGatewayMethod === "function") api.registerGatewayMethod(
"taas.completion.deliver",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openclaw-taas-affinity",
"version": "0.8.0",
"version": "0.9.0",
"description": "OpenClaw provider plugin \u2014 CloudSigma TaaS session affinity. Injects a stable X-Session-Id header per conversation so TaaS can pin the session to the same OAuth token / Bedrock region / Claude Code node, maximising prompt-cache hit rates.",
"type": "module",
"main": "dist/index.js",
Expand Down
21 changes: 21 additions & 0 deletions test/simple-completion-affinity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import assert from "node:assert/strict"
import test from "node:test"
import plugin from "../index.ts"

test("simple completion hook is registered and shares affinity injection", async () => {
let registered: any
;(plugin as any).register({ registerProvider: (cfg: any) => { registered = cfg }, registerGatewayMethod: () => {} })
assert.equal(registered.wrapSimpleCompletionStreamFn, registered.wrapStreamFn)
let innerOptions: any
const inner = async function* (_m: any, _c: any, options: any) { innerOptions = options; yield { type: "start" } }
const wrapped = registered.wrapSimpleCompletionStreamFn({
provider: "cloudsigma", modelId: "gpt-5.6-sol", agentId: "main",
workspaceDir: "/home/cloudsigma/.openclaw/workspace", streamFn: inner,
})
const gen = wrapped("gpt-5.6-sol", {}, { onPayload: async (p: any) => p })
await gen.next()
const patched = await innerOptions.onPayload({ model: "gpt-5.6-sol", messages: [{ role: "user", content: "hi" }] }, "gpt-5.6-sol")
assert.ok(patched.metadata?.session_id?.startsWith("oc:"))
assert.equal(patched.metadata?.sticky_key, patched.metadata?.session_id)
assert.equal(patched.metadata?.openclaw_correlation?.agent_id, "main")
})
4 changes: 2 additions & 2 deletions test/smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const transportState = provider.resolveTransportTurnState({ sessionId: "smoke-lo

assert.equal(transportState.headers["X-Session-Id"], "smoke-local-session")
assert.equal(transportState.headers["X-OpenClaw-Session-Id"], transportState.headers["X-Session-Id"])
assert.equal(transportState.headers["X-OpenClaw-Plugin-Version"], "0.8.0")
assert.equal(transportState.headers["X-OpenClaw-Plugin-Version"], "0.9.0")
assert.equal(transportState.headers["X-OpenClaw-Turn-Id"], "turn-smoke")
assert.equal(transportState.headers["X-OpenClaw-Attempt"], "1")

Expand All @@ -93,7 +93,7 @@ assert.equal(capturedPayload.metadata.requester_runtime.tool_execution, "directi
assert.equal("available_bridges" in capturedPayload.metadata.requester_runtime, false)
assert.equal(capturedPayload.metadata.openclaw_correlation.schema_version, "2026-06-05")
assert.equal(capturedPayload.metadata.openclaw_correlation.source, "openclaw-taas-affinity")
assert.equal(capturedPayload.metadata.openclaw_correlation.plugin_version, "0.8.0")
assert.equal(capturedPayload.metadata.openclaw_correlation.plugin_version, "0.9.0")
assert.equal(capturedPayload.metadata.openclaw_correlation.session_id, localSessionA)
assert.equal(capturedPayload.metadata.openclaw_correlation.sticky_key, localSessionA)
assert.equal(capturedPayload.metadata.openclaw_correlation.provider, "cloudsigma")
Expand Down
Loading