Skip to content

feat(sdk): set-once integration attribution via ConnectionConfig.setIntegration#1524

Open
mishushakov wants to merge 5 commits into
mainfrom
streamline-sdk-attribution
Open

feat(sdk): set-once integration attribution via ConnectionConfig.setIntegration#1524
mishushakov wants to merge 5 commits into
mainfrom
streamline-sdk-attribution

Conversation

@mishushakov

@mishushakov mishushakov commented Jul 3, 2026

Copy link
Copy Markdown
Member

Replaces the per-call integration connection option with a set-once, process-wide setter — ConnectionConfig.setIntegration() in JS and ConnectionConfig.set_integration() in Python — so integrations wrapping the SDK tag themselves once at startup and every request carries the identifier in the User-Agent header, with no threading through individual SDK calls. The setter is internal and hidden from generated docs; the integration option is removed from ConnectionConfigOpts (kept as a deprecated alias of ConnectionOpts) and from the Python constructor, and the round-trip machinery from #1459 is no longer needed since rebuilt configs read the process-wide value. User-Agent handling now follows a single rule via one shared helper: an explicitly provided User-Agent always wins (Python), otherwise the SDK sends its own tagged with the current integration — including recomputing after the integration is cleared. Tests cover attribution, clearing, config rebuilds, and custom User-Agent precedence in both SDKs, with changesets for e2b and @e2b/python-sdk (minor). CLI attribution using this setter will follow in a separate PR.

Usage (internal integrations only):

import { ConnectionConfig } from 'e2b'
ConnectionConfig.setIntegration('e2b-code-interpreter/0.1.0') // once at startup
from e2b import ConnectionConfig
ConnectionConfig.set_integration("e2b-code-interpreter/0.1.0")  # once at startup

🤖 Generated with Claude Code

…ntegration

Replace the per-call `integration` connection option with a process-wide,
set-once setter: `ConnectionConfig.setIntegration()` (JS) and
`ConnectionConfig.set_integration()` (Python). Integrations wrapping the
SDK tag themselves once at startup and every request carries the identifier
in the User-Agent header — no more threading the option through individual
SDK calls, and the knob is kept out of the public, documented API surface.

The `integration` option is removed from `ConnectionConfigOpts` (now a
deprecated alias of `ConnectionOpts`) and from the Python constructor.
The CLI uses the new setter to tag all its traffic as `e2b-cli/<version>`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8e34321

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
e2b Minor
@e2b/python-sdk Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor

cursor Bot commented Jul 3, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Minor semver bump removes a public constructor/options field and changes attribution timing; JS/Python User-Agent precedence diverges, which can break callers relying on custom agents or the old per-config integration option.

Overview
The per-call integration option is removed from JS ConnectionConfigOpts / Python ConnectionConfig.__init__; attribution moves to process-wide ConnectionConfig.setIntegration() / set_integration(), read when each config is constructed and appended to User-Agent.

The changeset says an explicit User-Agent wins in Python, but JS still always assigns this.headers['User-Agent'] = ConnectionConfig.buildUserAgent() after merging headers / apiHeaders, so a caller-supplied User-Agent in JS is overwritten and behavior does not match Python.

Callers that still pass integration on config construction will fail at compile time in TS or with an unexpected keyword argument in Python; they must switch to the internal set-once API before creating configs. Configs created before setIntegration are not retro-tagged, and later changes to the static integration value do not refresh headers on existing instances.

Reviewed by Cursor Bugbot for commit 8e34321. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from 37ddf3b. Download artifacts from this workflow run.

JS SDK (e2b@2.31.1-streamline-sdk-attribution.0):

npm install ./e2b-2.31.1-streamline-sdk-attribution.0.tgz

CLI (@e2b/cli@2.13.1-streamline-sdk-attribution.0):

npm install ./e2b-cli-2.13.1-streamline-sdk-attribution.0.tgz

Python SDK (e2b==2.30.0+streamline-sdk-attribution):

pip install ./e2b-2.30.0+streamline.sdk.attribution-py3-none-any.whl

… rpc headers test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread packages/python-sdk/e2b/connection_config.py Outdated
mishushakov and others added 2 commits July 3, 2026 15:51
Cover the two behaviors the setter contract implies but nothing asserted:
custom User-Agent headers are preserved (Python) or overridden by an
integration, and setIntegration does not retro-tag configs constructed
before it was called (JS).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ration

After ConnectionConfig.set_integration(None), configs built while an
integration was set kept the stale tagged User-Agent through
get_api_params rebuilds: the header was only recomputed when the classvar
was non-None, and __init__ preserves an existing User-Agent. Track whether
the User-Agent was SDK-built and recompute it from the current integration
on every get_api_params call, while still preserving user-supplied
User-Agents (construction-time and per-call).

Reported by Cursor BugBot on #1524.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c6697b1. Configure here.

Comment thread packages/python-sdk/e2b/connection_config.py Outdated
Unify the two precedence rules ConnectionConfig grew (construction-time
custom User-Agent lost to the integration, per-call won over it) into a
single one — an explicitly provided User-Agent always wins, otherwise the
SDK-built one tagged with the current integration — and extract it into
_apply_user_agent, shared by __init__ and get_api_params. _build_user_agent
and the JS buildUserAgent now read the integration themselves instead of
taking it as a parameter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant