Skip to content

feat(weave): send client-capability header on ingest (Python + Node)#7342

Closed
ro31337 wants to merge 1 commit into
masterfrom
roman/WB-35951-client-capabilities-header
Closed

feat(weave): send client-capability header on ingest (Python + Node)#7342
ro31337 wants to merge 1 commit into
masterfrom
roman/WB-35951-client-capabilities-header

Conversation

@ro31337

@ro31337 ro31337 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

JIRA Issue(s)

https://coreweave.atlassian.net/browse/WB-35951

Description

Both the Python and Node SDKs now send an X-Weave-Client-Capabilities header on every request they make to the Weave trace server. The value is a small comma-separated list of the sampling-relevant capabilities this SDK build guarantees — today trace_id_on_end,eval_child_meta, matching the two recent changes that put trace_id on every call message and tag evaluation child calls with eval metadata.

The header is groundwork for a future server-side ingest sampler. To sample the calls model safely the server has to drop whole traces consistently and never shred evaluations, which is only true once a client sends trace_id everywhere and marks its eval calls. The server cannot infer that from the data alone — an unmarked call is ambiguous (a normal call, or an eval child from an older client) — so the client states it directly, and the sampler leaves traffic without the header unsampled. Nothing reads the header yet; this mirrors the X-Weave-Trace-Id header added recently for the same future sampler.

Why this approach

A capability list rather than an SDK version keeps the server out of mapping versions to behavior: the Python and Node SDKs version independently, and the relevant behavior landed across several releases. It is advisory, not a gate — a missing or unknown capability just means "don't sample," never a rejected request. It is set once in the shared request-header builder, so it rides every request (it describes the client, not one trace); a future sampler simply reads it on the ingest paths.

Testing

Python: new tests assert the header is present on single-call and on batch upsert requests; the full trace_server_bindings suite passes (64). Node: a new clientApi test asserts init() wires the header onto the trace-server client; the full suite passes (313). The VCR cassette matcher now ignores this header the same way it already ignores the volatile client_version body field, so the recorded live/ cassettes still match. Lint, format and typecheck (cjs + esm) are clean.

Backward compatibility

Additive and safe both ways: an older server ignores the unknown header, and an older client simply doesn't send it. The Stainless transport and the one-shot login health check are out of scope, matching the X-Weave-Trace-Id change. One follow-up to track: if the Stainless transport later becomes the default, this header and X-Weave-Trace-Id must be ported to it together, otherwise the sampler would see header-less traffic from the new default client.

Both SDKs now send an X-Weave-Client-Capabilities header on every trace-ingest request, declaring the sampling-relevant capabilities this build guarantees (trace_id on call-end, eval metadata on eval child calls). A future server-side ingest sampler reads it to tell a sampling-safe client from an older one and leave unsupported traffic unsampled.

WB-35951
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@ro31337 ro31337 marked this pull request as ready for review June 22, 2026 18:12
@ro31337 ro31337 requested review from a team as code owners June 22, 2026 18:12
# sampling-safe client even on the batch path, which cannot carry a per-trace
# trace_id header.
# =============================================================================

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ is it too wordy?

@ro31337

ro31337 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Splitting the TS and Python changes into separate PRs per review feedback (keeps reverts simple): Python #7350, Node #7351. Both are drafts with green CI. Closing this combined PR in favor of those.

@ro31337 ro31337 closed this Jun 23, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant