@@ -111,6 +111,7 @@ private constructor(
111111 @get:JvmName(" autoBatchTracing" ) val autoBatchTracing: Boolean ,
112112 private val apiKey: String? ,
113113 private val tenantId: String? ,
114+ private val oauthAccessToken: String? ,
114115) {
115116
116117 init {
@@ -172,6 +173,7 @@ private constructor(
172173 private var autoBatchTracing: Boolean = true
173174 private var apiKey: String? = null
174175 private var tenantId: String? = null
176+ private var oauthAccessToken: String? = null
175177
176178 @JvmSynthetic
177179 internal fun from (clientOptions : ClientOptions ) = apply {
@@ -190,6 +192,7 @@ private constructor(
190192 autoBatchTracing = clientOptions.autoBatchTracing
191193 apiKey = clientOptions.apiKey
192194 tenantId = clientOptions.tenantId
195+ oauthAccessToken = clientOptions.oauthAccessToken
193196 }
194197
195198 /* *
@@ -426,14 +429,9 @@ private constructor(
426429 * System properties take precedence over environment variables.
427430 */
428431 fun fromEnv () = apply {
429- (System .getProperty(" langchain.baseUrl" ) ? : System .getenv(" LANGSMITH_ENDPOINT" ))?.let {
430- baseUrl(it)
431- }
432- (System .getProperty(" langchain.langsmithApiKey" ) ? : System .getenv(" LANGSMITH_API_KEY" ))
433- ?.let { apiKey(it) }
434- (System .getProperty(" langchain.langsmithTenantId" )
435- ? : System .getenv(" LANGSMITH_TENANT_ID" ))
436- ?.let { tenantId(it) }
432+ langsmithEndpoint()?.let { baseUrl(it) }
433+ langsmithApiKey()?.let { apiKey(it) }
434+ langsmithTenantId()?.let { tenantId(it) }
437435 System .getenv(" LANGCHAIN_CUSTOM_HEADERS" )?.let { customHeadersEnv ->
438436 for (line in customHeadersEnv.split(" \n " )) {
439437 val colon = line.indexOf(' :' )
@@ -442,6 +440,8 @@ private constructor(
442440 }
443441 }
444442 }
443+ loadProfileClientConfig(jsonMapper, clock, baseUrl, profileNameOverride = profileName())
444+ ?.let { applyProfileConfig(it) }
445445 }
446446
447447 /* *
@@ -491,16 +491,26 @@ private constructor(
491491 // We replace after all the default headers to allow end-users to overwrite them.
492492 headers.replaceAll(this .headers.build())
493493 queryParams.replaceAll(this .queryParams.build())
494- apiKey?.let {
495- if (! it.isEmpty()) {
494+ apiKey
495+ ?.takeIf { it.isNotEmpty() }
496+ ?.let {
497+ headers.remove(" Authorization" )
496498 headers.replace(" X-API-Key" , it)
497499 }
500+ if (apiKey.isNullOrEmpty()) {
501+ oauthAccessToken
502+ ?.takeIf { it.isNotEmpty() }
503+ ?.let {
504+ val currentHeaders = headers.build()
505+ if (
506+ currentHeaders.values(" X-API-Key" ).all(String ::isBlank) &&
507+ currentHeaders.values(" Authorization" ).all(String ::isBlank)
508+ ) {
509+ headers.replace(" Authorization" , " Bearer $it " )
510+ }
511+ }
498512 }
499- tenantId?.let {
500- if (! it.isEmpty()) {
501- headers.replace(" X-Tenant-Id" , it)
502- }
503- }
513+ tenantId?.takeIf { it.isNotEmpty() }?.let { headers.replace(" X-Tenant-Id" , it) }
504514
505515 return ClientOptions (
506516 httpClient,
@@ -524,8 +534,48 @@ private constructor(
524534 autoBatchTracing,
525535 apiKey,
526536 tenantId,
537+ oauthAccessToken,
527538 )
528539 }
540+
541+ private fun applyProfileConfig (profile : ProfileClientConfig ) {
542+ if (baseUrl.isNullOrBlank()) {
543+ profile.baseUrl?.let { baseUrl(it) }
544+ }
545+ if (tenantId.isNullOrBlank()) {
546+ profile.tenantId?.let { tenantId(it) }
547+ }
548+ if (! apiKey.isNullOrBlank() || hasAuthHeader()) {
549+ return
550+ }
551+ if (! profile.oauthAccessToken.isNullOrBlank()) {
552+ oauthAccessToken = profile.oauthAccessToken
553+ } else if (! profile.apiKey.isNullOrBlank()) {
554+ apiKey(profile.apiKey)
555+ }
556+ }
557+
558+ private fun hasAuthHeader (): Boolean {
559+ val currentHeaders = headers.build()
560+ return currentHeaders.values(" X-API-Key" ).any { it.isNotBlank() } ||
561+ currentHeaders.values(" Authorization" ).any { it.isNotBlank() }
562+ }
563+
564+ private fun langsmithEndpoint (): String? =
565+ System .getProperty(" langchain.baseUrl" )
566+ ? : System .getenv(" LANGSMITH_ENDPOINT" )
567+ ? : System .getenv(" LANGCHAIN_ENDPOINT" )
568+
569+ private fun langsmithApiKey (): String? =
570+ System .getProperty(" langchain.langsmithApiKey" )
571+ ? : System .getenv(" LANGSMITH_API_KEY" )
572+ ? : System .getenv(" LANGCHAIN_API_KEY" )
573+
574+ private fun langsmithTenantId (): String? =
575+ System .getProperty(" langchain.langsmithTenantId" )
576+ ? : System .getenv(" LANGSMITH_TENANT_ID" )
577+ ? : System .getenv(" LANGSMITH_WORKSPACE_ID" )
578+ ? : System .getenv(" LANGCHAIN_WORKSPACE_ID" )
529579 }
530580
531581 /* *
0 commit comments