-
Notifications
You must be signed in to change notification settings - Fork 262
Add an option to disable Stainless telemetry headers #962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,7 @@ class OpenAIOkHttpClient private constructor() { | |
| class Builder internal constructor() { | ||
|
|
||
| private var clientOptions: ClientOptions.Builder = ClientOptions.builder() | ||
| private var sendStainlessHeaders: Boolean = true | ||
| private var dispatcherExecutorService: ExecutorService? = null | ||
| private var followRedirects: Boolean = true | ||
| private var proxy: Proxy? = null | ||
|
|
@@ -370,6 +371,16 @@ class OpenAIOkHttpClient private constructor() { | |
| clientOptions.azureUrlPathMode(azureUrlPathMode) | ||
| } | ||
|
|
||
| /** | ||
| * Whether to send the SDK's default `X-Stainless-*` telemetry headers. | ||
| * | ||
| * Defaults to `true`. | ||
| */ | ||
| fun sendStainlessHeaders(sendStainlessHeaders: Boolean) = apply { | ||
| this.sendStainlessHeaders = sendStainlessHeaders | ||
| clientOptions.sendStainlessHeaders(sendStainlessHeaders) | ||
| } | ||
|
|
||
| fun organization(organization: String?) = apply { clientOptions.organization(organization) } | ||
|
|
||
| /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */ | ||
|
|
@@ -512,6 +523,7 @@ class OpenAIOkHttpClient private constructor() { | |
| .maxIdleConnections(maxIdleConnections) | ||
| .keepAliveDuration(keepAliveDuration) | ||
| .dispatcherExecutorService(dispatcherExecutorService) | ||
| .sendStainlessHeaders(sendStainlessHeaders) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When AGENTS.md reference: AGENTS.md:L41-L45 Useful? React with 👍 / 👎. |
||
| .sslSocketFactory(sslSocketFactory) | ||
| .trustManager(trustManager) | ||
| .hostnameVerifier(hostnameVerifier) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,6 +137,8 @@ private constructor( | |
| @get:JvmName("credential") val credential: Credential, | ||
| @get:JvmName("azureServiceVersion") val azureServiceVersion: AzureOpenAIServiceVersion?, | ||
| @get:JvmName("azureUrlPathMode") val azureUrlPathMode: AzureUrlPathMode, | ||
| /** Whether to send the SDK's default `X-Stainless-*` telemetry headers. */ | ||
| @get:JvmName("sendStainlessHeaders") val sendStainlessHeaders: Boolean, | ||
| private val organization: String?, | ||
| private val project: String?, | ||
| private val webhookSecret: String?, | ||
|
|
@@ -216,6 +218,7 @@ private constructor( | |
| private var credential: Credential? = null | ||
| private var azureServiceVersion: AzureOpenAIServiceVersion? = null | ||
| private var azureUrlPathMode: AzureUrlPathMode = AzureUrlPathMode.AUTO | ||
| private var sendStainlessHeaders: Boolean = true | ||
| private var adminApiKey: String? = null | ||
| private var organization: String? = null | ||
| private var project: String? = null | ||
|
|
@@ -251,6 +254,10 @@ private constructor( | |
| } | ||
| azureServiceVersion = clientOptions.azureServiceVersion | ||
| azureUrlPathMode = clientOptions.azureUrlPathMode | ||
| sendStainlessHeaders = clientOptions.sendStainlessHeaders | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
| if (!sendStainlessHeaders) { | ||
| headers.removeAll(STAINLESS_HEADER_NAMES) | ||
| } | ||
|
Comment on lines
+258
to
+260
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If options are built with AGENTS.md reference: AGENTS.md:L41-L45 Useful? React with 👍 / 👎. |
||
| organization = clientOptions.organization | ||
| project = clientOptions.project | ||
| webhookSecret = clientOptions.webhookSecret | ||
|
|
@@ -450,6 +457,19 @@ private constructor( | |
| this.azureUrlPathMode = azureUrlPathMode | ||
| } | ||
|
|
||
| /** | ||
| * Whether to send the SDK's default `X-Stainless-*` telemetry headers. | ||
| * | ||
| * Defaults to `true`. Set to `false` when a provider or gateway imposes a strict request | ||
| * header limit, such as Azure OpenAI returning HTTP 431 for the default telemetry headers. | ||
| */ | ||
| fun sendStainlessHeaders(sendStainlessHeaders: Boolean) = apply { | ||
| this.sendStainlessHeaders = sendStainlessHeaders | ||
| if (!sendStainlessHeaders) { | ||
| headers.removeAll(STAINLESS_HEADER_NAMES) | ||
| } | ||
| } | ||
|
Comment on lines
+466
to
+471
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Azure users normally construct clients with Useful? React with 👍 / 👎. |
||
|
|
||
| fun organization(organization: String?) = apply { this.organization = organization } | ||
|
|
||
| /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */ | ||
|
|
@@ -711,14 +731,16 @@ private constructor( | |
|
|
||
| val headers = Headers.builder() | ||
| val queryParams = QueryParams.builder() | ||
| headers.put("X-Stainless-Lang", "java") | ||
| headers.put("X-Stainless-Arch", getOsArch()) | ||
| headers.put("X-Stainless-OS", getOsName()) | ||
| headers.put("X-Stainless-OS-Version", getOsVersion()) | ||
| headers.put("X-Stainless-Package-Version", getPackageVersion()) | ||
| headers.put("X-Stainless-Runtime", "JRE") | ||
| headers.put("X-Stainless-Runtime-Version", getJavaVersion()) | ||
| headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString()) | ||
| if (sendStainlessHeaders) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When this option is false, only the static headers stored in Useful? React with 👍 / 👎. |
||
| headers.put("X-Stainless-Lang", "java") | ||
| headers.put("X-Stainless-Arch", getOsArch()) | ||
| headers.put("X-Stainless-OS", getOsName()) | ||
| headers.put("X-Stainless-OS-Version", getOsVersion()) | ||
| headers.put("X-Stainless-Package-Version", getPackageVersion()) | ||
| headers.put("X-Stainless-Runtime", "JRE") | ||
| headers.put("X-Stainless-Runtime-Version", getJavaVersion()) | ||
| headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString()) | ||
| } | ||
| // We replace after all the default headers to allow end-users to overwrite them. | ||
| headers.replaceAll(this.headers.build()) | ||
|
|
||
|
|
@@ -778,6 +800,7 @@ private constructor( | |
| .sleeper(sleeper) | ||
| .clock(clock) | ||
| .maxRetries(maxRetries) | ||
| .sendStainlessHeaders(sendStainlessHeaders) | ||
| .build() | ||
|
|
||
| return ClientOptions( | ||
|
|
@@ -802,6 +825,7 @@ private constructor( | |
| credential, | ||
| azureServiceVersion, | ||
| azureUrlPathMode, | ||
| sendStainlessHeaders, | ||
| organization, | ||
| project, | ||
| webhookSecret, | ||
|
|
@@ -880,3 +904,18 @@ private constructor( | |
| private object AdminApiKeyOnlyCredential : Credential | ||
|
|
||
| private object HttpRequestAuthenticatorCredential : Credential | ||
|
|
||
| private val STAINLESS_HEADER_NAMES = | ||
| setOf( | ||
| "X-Stainless-Lang", | ||
| "X-Stainless-Arch", | ||
| "X-Stainless-OS", | ||
| "X-Stainless-OS-Version", | ||
| "X-Stainless-Package-Version", | ||
| "X-Stainless-Runtime", | ||
| "X-Stainless-Runtime-Version", | ||
| "X-Stainless-Kotlin-Version", | ||
| "X-Stainless-Retry-Count", | ||
| "X-Stainless-Read-Timeout", | ||
| "X-Stainless-Timeout", | ||
| ) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a client initially uses the default and is later cloned with
client.withOptions(b -> b.sendStainlessHeaders(false)),ClientOptions.Builder.from()reuses the originalHttpClient, whose new transport-level flag was fixed totrueat construction. The clone omits static and retry headers, but this call still causes the reused OkHttp transport to addX-Stainless-Read-TimeoutandX-Stainless-Timeout; with the nonzero default timeouts, the Azure workaround remains incomplete. Fresh evidence in this revision is that the transport now captures the flag immutably whilewithOptionscontinues reusingoriginalHttpClient; propagate the updated policy to cloned transports or make request-time injection consult the current options, and cover the publicwithOptionsflow on the wire.AGENTS.md reference: AGENTS.md:L41-L45
Useful? React with 👍 / 👎.