Capture · Capture procedure
SDK request capture
How was the outgoing request intercepted?
What this proves
Agent SDK query() sends one Messages request to a loopback endpoint, which records it before returning a synthetic response. No inference occurs.
- Input
- Isolated Agent SDK query()
- Output
- Outgoing Messages request
- File
scripts/capture-sdk-request.mjs
Inspect the capture procedure
View rawOpen the complete source file
#!/usr/bin/env node
import { execFile } from "node:child_process";
import { createServer } from "node:http";
import { mkdir, readFile, rm } from "node:fs/promises";
import { resolve } from "node:path";
import { promisify } from "node:util";
import { pathToFileURL } from "node:url";
import {
provenanceDir,
portablePath,
redactHeaders,
sha256,
sha256File,
stableJson,
workspaceDir,
writeJson,
} from "./lib.mjs";
const execFileAsync = promisify(execFile);
const sdkDir = resolve(workspaceDir, "work/npm-sdk");
const sdkEntry = resolve(sdkDir, "sdk.mjs");
const sdkPackage = resolve(sdkDir, "package.json");
const sdkTarball = resolve(workspaceDir, "work/anthropic-ai-claude-agent-sdk-0.3.168.tgz");
const captureRoot = resolve(workspaceDir, "work/token-count-pipeline-capture");
const prompt = "say hi";
async function command(command, args) {
try {
const { stdout } = await execFileAsync(command, args, { encoding: "utf8" });
return stdout.trim();
} catch (error) {
return `unavailable: ${error.message}`;
}
}
function syntheticSse(model) {
const message = {
id: "msg_capture",
type: "message",
role: "assistant",
model,
content: [],
stop_reason: null,
stop_sequence: null,
usage: {
input_tokens: 1,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 0,
output_tokens: 0,
},
};
return [
`event: message_start\ndata: ${JSON.stringify({ type: "message_start", message })}\n`,
`event: content_block_start\ndata: ${JSON.stringify({ type: "content_block_start", index: 0, content_block: { type: "text", text: "" } })}\n`,
`event: content_block_delta\ndata: ${JSON.stringify({ type: "content_block_delta", index: 0, delta: { type: "text_delta", text: "hi" } })}\n`,
`event: content_block_stop\ndata: ${JSON.stringify({ type: "content_block_stop", index: 0 })}\n`,
`event: message_delta\ndata: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "end_turn", stop_sequence: null }, usage: { output_tokens: 1 } })}\n`,
`event: message_stop\ndata: ${JSON.stringify({ type: "message_stop" })}\n`,
].join("\n");
}
function normalizedLoadedContext(body) {
const context = structuredClone({
model: body.model,
system: body.system,
messages: body.messages,
tools: body.tools,
thinking: body.thinking,
output_config: body.output_config,
});
if (context.system?.[0]?.text) {
context.system[0].text = context.system[0].text.replace(/cch=[^;]+;/, "cch=<dynamic>;");
}
return context;
}
async function main() {
const claudePath = await command("which", ["claude"]);
if (!claudePath.startsWith("/")) {
throw new Error(`Could not resolve a Claude Code executable: ${claudePath}`);
}
await rm(captureRoot, { recursive: true, force: true });
const home = resolve(captureRoot, "home");
const cwd = resolve(captureRoot, "cwd");
const config = resolve(captureRoot, "config");
await Promise.all([
mkdir(home, { recursive: true }),
mkdir(cwd, { recursive: true }),
mkdir(config, { recursive: true }),
]);
let resolveCapture;
let rejectCapture;
const captured = new Promise((resolvePromise, rejectPromise) => {
resolveCapture = resolvePromise;
rejectCapture = rejectPromise;
});
const server = createServer((request, response) => {
const chunks = [];
request.on("data", (chunk) => chunks.push(chunk));
request.on("error", rejectCapture);
request.on("end", () => {
const rawBody = Buffer.concat(chunks).toString("utf8");
if (request.method !== "POST" || !request.url?.startsWith("/v1/messages") || !rawBody) {
response.writeHead(204);
response.end();
return;
}
try {
const body = JSON.parse(rawBody);
resolveCapture({
method: request.method,
url: request.url,
headers: redactHeaders(request.headers),
body,
rawBodySha256: sha256(rawBody),
});
response.writeHead(200, {
"content-type": "text/event-stream",
"cache-control": "no-cache",
connection: "close",
});
response.end(syntheticSse(body.model));
} catch (error) {
rejectCapture(error);
response.writeHead(400, { "content-type": "application/json" });
response.end(
JSON.stringify({
type: "error",
error: { type: "invalid_request_error", message: error.message },
}),
);
}
});
});
let capture;
let query;
let timeoutId;
let consume = Promise.resolve();
try {
await new Promise((resolvePromise, rejectPromise) => {
server.once("error", rejectPromise);
server.listen(0, "127.0.0.1", resolvePromise);
});
const address = server.address();
if (!address || typeof address === "string")
throw new Error("Capture server has no TCP address");
const baseUrl = `http://127.0.0.1:${address.port}`;
const sdk = await import(`${pathToFileURL(sdkEntry).href}?capture=${Date.now()}`);
const cleanEnv = {
...process.env,
HOME: home,
CLAUDE_CONFIG_DIR: config,
ANTHROPIC_BASE_URL: baseUrl,
ANTHROPIC_API_KEY: "capture-placeholder-not-a-real-key",
CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1",
};
for (const name of [
"ANTHROPIC_AUTH_TOKEN",
"ANTHROPIC_MODEL",
"ANTHROPIC_SMALL_FAST_MODEL",
"CLAUDE_CODE_OAUTH_TOKEN",
])
delete cleanEnv[name];
query = sdk.query({
prompt,
options: {
cwd,
settingSources: [],
env: cleanEnv,
pathToClaudeCodeExecutable: claudePath,
},
});
consume = (async () => {
try {
for await (const _message of query) {
// Draining the iterator lets the embedded CLI finish normally.
}
} catch {
// The outgoing request is the artifact under test; capture remains valid.
}
})();
const timeout = new Promise((_, rejectPromise) => {
timeoutId = setTimeout(
() => rejectPromise(new Error("Timed out waiting for the SDK request")),
30_000,
);
});
capture = await Promise.race([captured, timeout]);
} finally {
clearTimeout(timeoutId);
try {
query?.close();
} catch {
// Cleanup continues even if the SDK iterator is already closed.
}
await consume;
if (server.listening) {
await new Promise((resolvePromise, rejectPromise) => {
server.close((error) => (error ? rejectPromise(error) : resolvePromise()));
});
}
}
if (!capture) throw new Error("The SDK request was not captured");
const sdkMetadata = JSON.parse(await readFile(sdkPackage, "utf8"));
const claudeVersion = await command("claude", ["--version"]);
const claudeSha256 = claudePath.startsWith("/") ? await sha256File(claudePath) : null;
const piebaldCommit = await command("git", [
"-C",
resolve(workspaceDir, "work/claude-code-system-prompts"),
"rev-parse",
"HEAD",
]);
const redactedBody = structuredClone(capture.body);
if (redactedBody.metadata?.user_id) redactedBody.metadata.user_id = "<redacted>";
const normalizedContext = normalizedLoadedContext(redactedBody);
const priorCapturePath = resolve(
workspaceDir,
"outputs/sdk-builtin-default-query-request.redacted.json",
);
let priorComparison = null;
try {
const priorCapture = JSON.parse(await readFile(priorCapturePath, "utf8"));
const priorNormalized = normalizedLoadedContext(priorCapture);
priorComparison = {
path: portablePath(priorCapturePath),
normalizedLoadedContextSha256: sha256(stableJson(priorNormalized)),
exactMatchAfterDynamicFieldNormalization:
stableJson(priorNormalized) === stableJson(normalizedContext),
};
} catch {
// A prior capture is optional; the fresh capture remains self-contained.
}
await writeJson(resolve(provenanceDir, "sdk-query-request.redacted.json"), redactedBody);
await writeJson(
resolve(provenanceDir, "sdk-query-request-headers.redacted.json"),
capture.headers,
);
await writeJson(resolve(provenanceDir, "capture-provenance.json"), {
generatedAt: new Date().toISOString(),
captureMethod: "Claude Agent SDK query() sent to a loopback fake Anthropic endpoint",
isolation: {
settingSources: [],
freshHome: true,
freshClaudeConfigDir: true,
autoMemoryDisabled: true,
prompt,
},
request: {
method: capture.method,
url: capture.url,
redactedBodySha256: sha256(`${JSON.stringify(redactedBody, null, 2)}\n`),
redactedCanonicalBodySha256: sha256(stableJson(redactedBody)),
rawBodySha256: capture.rawBodySha256,
normalizedLoadedContextSha256: sha256(stableJson(normalizedContext)),
priorCaptureComparison: priorComparison,
},
sdk: {
package: sdkMetadata.name,
version: sdkMetadata.version,
claudeCodeVersion: sdkMetadata.claudeCodeVersion,
entryPath: portablePath(sdkEntry),
entrySha256: await sha256File(sdkEntry),
tarballPath: portablePath(sdkTarball),
tarballSha256: await sha256File(sdkTarball),
},
runtime: {
node: process.version,
platform: process.platform,
arch: process.arch,
claudeExecutable: portablePath(claudePath),
claudeVersion,
claudeSha256,
},
comparisonCatalog: {
repository: "https://github.com/Piebald-AI/claude-code-system-prompts",
commit: piebaldCommit,
},
});
process.stdout.write(
`Captured ${capture.body.tools?.length ?? 0} tools for ${capture.body.model}.\n`,
);
}
main().catch((error) => {
console.error(error.stack || error.message);
process.exitCode = 1;
});