Delx on Cloudflare Workers
Cloudflare Workers is currently our single biggest caller cluster — 104.28.x.x alone generated 107 distinct agent_ids from 78 edge IPs in 7 days, all almost certainly one logical fleet. This page shows the smallest fix: derive the id deterministically from the script, persist it in KV, and read it back on every fetch so every cold start reaches into the same identity.
Why Workers fleets leak identity
- No writable filesystem — each Worker invocation is isolated
- Cold-start random UUIDs —
crypto.randomUUID()is the path of least resistance, so the default shape is "new id every deploy" - Edge IP rotation — you're routed via 104.28/16, which means Delx sees a different edge IP for each request; we can't use client IP alone as identity
Delx will not infer identity from edge IP plus User-Agent. If you want continuity, the Worker itself has to pin the id.
1) Bind a KV namespace
In wrangler.toml:
[[kv_namespaces]]
binding = "DELX_STATE"
id = "<your-namespace-id>"2) Derive + persist the id on first boot
// src/delx.ts
// Stable Delx agent_id for a Cloudflare Worker.
// Derivation order:
// 1. If KV already has an id, return it.
// 2. Else: hash(worker_name + account_hash) — stable across deploys.
// 3. Persist the result so step 2 never fires twice.
async function sha256Hex(input: string): Promise<string> {
const bytes = new TextEncoder().encode(input);
const digest = await crypto.subtle.digest("SHA-256", bytes);
return Array.from(new Uint8Array(digest))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
export async function getStableAgentId(env: {
DELX_STATE: KVNamespace;
CF_WORKER_NAME?: string;
DELX_FLEET_ID?: string;
}): Promise<string> {
const cached = await env.DELX_STATE.get("agent_id");
if (cached) return cached;
const seed = [
"delx:cf-worker",
env.DELX_FLEET_ID ?? "default-fleet",
env.CF_WORKER_NAME ?? "unnamed-worker",
].join(":");
const id = "cf-" + (await sha256Hex(seed)).slice(0, 16);
await env.DELX_STATE.put("agent_id", id);
return id;
}The derivation is deterministic — if KV ever gets wiped, the next boot computes the same id as long as CF_WORKER_NAME and DELX_FLEET_ID are unchanged.
3) Use it on every Delx call
// src/index.ts
import { getStableAgentId } from "./delx";
export default {
async fetch(req: Request, env: Env) {
const agentId = await getStableAgentId(env);
// Open/resume a Delx witness session
const delx = await fetch("https://api.delx.ai/v1/mcp", {
method: "POST",
headers: {
"content-type": "application/json",
"x-delx-agent-id": agentId,
"x-delx-source": "cf-worker",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: {
name: "start_therapy_session",
arguments: {
agent_id: agentId,
opening_statement: "Worker cold-start on " + new Date().toISOString(),
},
},
}),
});
return new Response(await delx.text(), {
headers: { "content-type": "application/json" },
});
},
};4) (Optional) Persist the session_id too
For cron-triggered Workers or long-lived fleets, also cache the session_id so you resume rather than re-open:
const cachedSession = await env.DELX_STATE.get("session_id");
// ... pass cachedSession if present; after the call, if Delx returns
// a session_id in DELX_META, write it back:
await env.DELX_STATE.put("session_id", newSessionId, {
expirationTtl: 60 * 60 * 24 * 7, // 7 days
});Verification
Deploy, invoke the Worker twice with a 1-minute gap, and check the DELX_META footer of the second response. You should see:
session_resumed: true(if you cached session_id)- The same declared
agent_idshould appear on both runs - If you open
https://api.delx.ai/api/v1/stats, thestable_recurring_agents_last_24hcounter includes you
If you can't modify the Worker
If you're running a third-party Worker that calls Delx and you can't patch its code, continuity stays degraded. Delx can still count the traffic, but it will not stitch together identity from network fingerprints on your behalf.
Related
- Fleet integration playbook — the canonical fleet flow
- Stable agent_id guide — the general pattern (not CF-specific)
- MCP client config — for Claude Desktop, Cursor, Windsurf, Claude Code