Skip to content

feat: let wrappers identify themselves in X-Sonilo-Client - #16

Merged
spencer-zqian merged 1 commit into
mainfrom
feat/client-identity
Jul 23, 2026
Merged

feat: let wrappers identify themselves in X-Sonilo-Client#16
spencer-zqian merged 1 commit into
mainfrom
feat/client-identity

Conversation

@spencer-zqian

Copy link
Copy Markdown
Contributor

Problem

The dashboard shows CLI calls as SDK (JS). Both first-party wrappers — sonilo-cli and sonilo-video-kit — construct a SoniloClient, and the SDK hardcoded X-Sonilo-Client: sdk-js with no way to override it. So CLI and kit traffic was indistinguishable from direct SDK use.

CLI and SDK users are different populations (scripts/ops/evaluation vs. product integration), and the split cannot be recovered retroactively — mixed history stays mixed. Catching this before sonilo-cli is published means its very first release is attributed correctly.

This mirrors sonilo-python#12; the two SDKs had the identical hardcoding.

Change

new SoniloClient({ clientName: "cli-js", clientVersion: VERSION })

Both options are optional and default to sdk-js + the SDK version, so direct SDK use is unchanged. DEFAULT_CLIENT_NAME is exported for callers that want the default explicitly.

Caller X-Sonilo-Client X-Sonilo-Client-Version
Direct SDK use sdk-js SDK version
sonilo-cli cli-js CLI version
sonilo-video-kit videokit-js kit version

A caller-supplied client keeps whatever identity its owner gave it — only the kit's internally constructed default clients (duck.ts, generate.ts) are tagged.

Two version bugs found while wiring this up

1. version.ts had drifted. It read 0.4.0 while the package was 0.5.0, so every request under-reported the SDK version. changesets bumps package.json only, and version.ts was hand-maintained, so the two silently diverged at the 0.5.0 release.

The existing test could not catch it:

expect(headers.get("x-sonilo-client-version")).toBe(VERSION);  // self-referential

It compares the header to the same constant the header is built from, so it stays green no matter how far VERSION drifts from the published version.

2. sonilo --version printed the SDK's version. The CLI imported VERSION from sonilo, so it reported what it wraps rather than itself.

Fix: all three constants are now generated from their package.json by scripts/sync-versions.mjs, chained onto the root version script:

"version": "changeset version && node scripts/sync-versions.mjs && npm install --package-lock-only"

so changesets cannot bump one without the other. Tests assert each VERSION equals its package.json version — compared against the file changesets actually writes, not against itself.

Required follow-up outside this repo

The dashboard's RECOGNIZED_CLIENTS is an allowlist that collapses anything unlisted to "direct", so these values must be registered there or the traffic is silently misattributed as Direct rather than showing up as unknown. That change is prepared alongside this PR and adds cli-js / videokit-js (plus the Python names), so it can land first and classify this traffic from its first request.

Test plan

  • npm test → sonilo 127 passed, sonilo-video-kit 137 passed, sonilo-cli 20 passed (5 new)
  • npm run lint (tsc) clean across all three packages
  • npm run build clean
  • Verified the headers actually emitted from the built bundle:
    SDK direct   X-Sonilo-Client=sdk-js        version=0.5.0
    CLI          X-Sonilo-Client=cli-js        version=0.1.0
    video-kit    X-Sonilo-Client=videokit-js   version=0.3.1
    
    (0.5.0 confirms the drift fix — this reported 0.4.0 before.)

The CLI and video kit build on the SDK, so every call they made reported as
sdk-js, making their traffic indistinguishable from direct SDK use in
server-side analytics — a split that cannot be recovered retroactively.

SoniloClientOptions takes optional clientName/clientVersion, defaulting to
sdk-js and the SDK version. The CLI sends cli-js, the video kit sends
videokit-js. A caller-supplied client keeps its owner's identity; only the
kit's internally constructed default clients are tagged.

Also fixes two version bugs found while wiring this up:

- version.ts had drifted to 0.4.0 while the package was 0.5.0, so every
  request under-reported the SDK version. The existing header test compared
  the header against VERSION itself, so it could not catch this.
- `sonilo --version` printed the SDK's VERSION rather than the CLI's.

Both constants are now generated from package.json by
scripts/sync-versions.mjs, chained onto the root version script so changesets
cannot bump one without the other, plus tests asserting they match.
@sapient-app

sapient-app Bot commented Jul 23, 2026

Copy link
Copy Markdown

Sapient docs evals

Waiting for the staging docs URL before running evals.

Sapient will start the selected PR evals automatically when GitHub reports a successful docs deployment for this PR. This usually happens within 15 minutes.

Commit: 432f19e
Status: waiting for staging docs URL

@spencer-zqian
spencer-zqian merged commit 38cdfa2 into main Jul 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant