mirror of
https://github.com/langchain-ai/langsmith-java.git
synced 2026-08-26 18:17:05 -04:00
feat(runs): add GET /v2/runs/{run_id}/url endpoint and SDK runs.get_url method
Stainless-Generated-From: 12ef224c44ef834db59a6216eb1010f87947b165
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
configured_endpoints: 148
|
||||
configured_endpoints: 149
|
||||
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
// File generated from our OpenAPI spec by Stainless.
|
||||
|
||||
package com.langchain.smith.models.runs
|
||||
|
||||
import com.langchain.smith.core.Params
|
||||
import com.langchain.smith.core.checkRequired
|
||||
import com.langchain.smith.core.http.Headers
|
||||
import com.langchain.smith.core.http.QueryParams
|
||||
import java.util.Objects
|
||||
import java.util.Optional
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
/**
|
||||
* Returns the URL to view a specific run in the LangSmith UI. The caller must supply the run's
|
||||
* project_id and trace_id as query parameters; start_time is optional.
|
||||
*/
|
||||
class RunGetUrlParams
|
||||
private constructor(
|
||||
private val runId: String?,
|
||||
private val projectId: String,
|
||||
private val traceId: String,
|
||||
private val startTime: String?,
|
||||
private val additionalHeaders: Headers,
|
||||
private val additionalQueryParams: QueryParams,
|
||||
) : Params {
|
||||
|
||||
fun runId(): Optional<String> = Optional.ofNullable(runId)
|
||||
|
||||
/** Project (session) UUID */
|
||||
fun projectId(): String = projectId
|
||||
|
||||
/** Trace UUID */
|
||||
fun traceId(): String = traceId
|
||||
|
||||
/** Run start time in RFC3339 format; omit if unknown */
|
||||
fun startTime(): Optional<String> = Optional.ofNullable(startTime)
|
||||
|
||||
/** Additional headers to send with the request. */
|
||||
fun _additionalHeaders(): Headers = additionalHeaders
|
||||
|
||||
/** Additional query param to send with the request. */
|
||||
fun _additionalQueryParams(): QueryParams = additionalQueryParams
|
||||
|
||||
fun toBuilder() = Builder().from(this)
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Returns a mutable builder for constructing an instance of [RunGetUrlParams].
|
||||
*
|
||||
* The following fields are required:
|
||||
* ```java
|
||||
* .projectId()
|
||||
* .traceId()
|
||||
* ```
|
||||
*/
|
||||
@JvmStatic fun builder() = Builder()
|
||||
}
|
||||
|
||||
/** A builder for [RunGetUrlParams]. */
|
||||
class Builder internal constructor() {
|
||||
|
||||
private var runId: String? = null
|
||||
private var projectId: String? = null
|
||||
private var traceId: String? = null
|
||||
private var startTime: String? = null
|
||||
private var additionalHeaders: Headers.Builder = Headers.builder()
|
||||
private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
|
||||
|
||||
@JvmSynthetic
|
||||
internal fun from(runGetUrlParams: RunGetUrlParams) = apply {
|
||||
runId = runGetUrlParams.runId
|
||||
projectId = runGetUrlParams.projectId
|
||||
traceId = runGetUrlParams.traceId
|
||||
startTime = runGetUrlParams.startTime
|
||||
additionalHeaders = runGetUrlParams.additionalHeaders.toBuilder()
|
||||
additionalQueryParams = runGetUrlParams.additionalQueryParams.toBuilder()
|
||||
}
|
||||
|
||||
fun runId(runId: String?) = apply { this.runId = runId }
|
||||
|
||||
/** Alias for calling [Builder.runId] with `runId.orElse(null)`. */
|
||||
fun runId(runId: Optional<String>) = runId(runId.getOrNull())
|
||||
|
||||
/** Project (session) UUID */
|
||||
fun projectId(projectId: String) = apply { this.projectId = projectId }
|
||||
|
||||
/** Trace UUID */
|
||||
fun traceId(traceId: String) = apply { this.traceId = traceId }
|
||||
|
||||
/** Run start time in RFC3339 format; omit if unknown */
|
||||
fun startTime(startTime: String?) = apply { this.startTime = startTime }
|
||||
|
||||
/** Alias for calling [Builder.startTime] with `startTime.orElse(null)`. */
|
||||
fun startTime(startTime: Optional<String>) = startTime(startTime.getOrNull())
|
||||
|
||||
fun additionalHeaders(additionalHeaders: Headers) = apply {
|
||||
this.additionalHeaders.clear()
|
||||
putAllAdditionalHeaders(additionalHeaders)
|
||||
}
|
||||
|
||||
fun additionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
|
||||
this.additionalHeaders.clear()
|
||||
putAllAdditionalHeaders(additionalHeaders)
|
||||
}
|
||||
|
||||
fun putAdditionalHeader(name: String, value: String) = apply {
|
||||
additionalHeaders.put(name, value)
|
||||
}
|
||||
|
||||
fun putAdditionalHeaders(name: String, values: Iterable<String>) = apply {
|
||||
additionalHeaders.put(name, values)
|
||||
}
|
||||
|
||||
fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
|
||||
this.additionalHeaders.putAll(additionalHeaders)
|
||||
}
|
||||
|
||||
fun putAllAdditionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
|
||||
this.additionalHeaders.putAll(additionalHeaders)
|
||||
}
|
||||
|
||||
fun replaceAdditionalHeaders(name: String, value: String) = apply {
|
||||
additionalHeaders.replace(name, value)
|
||||
}
|
||||
|
||||
fun replaceAdditionalHeaders(name: String, values: Iterable<String>) = apply {
|
||||
additionalHeaders.replace(name, values)
|
||||
}
|
||||
|
||||
fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
|
||||
this.additionalHeaders.replaceAll(additionalHeaders)
|
||||
}
|
||||
|
||||
fun replaceAllAdditionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
|
||||
this.additionalHeaders.replaceAll(additionalHeaders)
|
||||
}
|
||||
|
||||
fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
|
||||
|
||||
fun removeAllAdditionalHeaders(names: Set<String>) = apply {
|
||||
additionalHeaders.removeAll(names)
|
||||
}
|
||||
|
||||
fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
|
||||
this.additionalQueryParams.clear()
|
||||
putAllAdditionalQueryParams(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun additionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) = apply {
|
||||
this.additionalQueryParams.clear()
|
||||
putAllAdditionalQueryParams(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun putAdditionalQueryParam(key: String, value: String) = apply {
|
||||
additionalQueryParams.put(key, value)
|
||||
}
|
||||
|
||||
fun putAdditionalQueryParams(key: String, values: Iterable<String>) = apply {
|
||||
additionalQueryParams.put(key, values)
|
||||
}
|
||||
|
||||
fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
|
||||
this.additionalQueryParams.putAll(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun putAllAdditionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) =
|
||||
apply {
|
||||
this.additionalQueryParams.putAll(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun replaceAdditionalQueryParams(key: String, value: String) = apply {
|
||||
additionalQueryParams.replace(key, value)
|
||||
}
|
||||
|
||||
fun replaceAdditionalQueryParams(key: String, values: Iterable<String>) = apply {
|
||||
additionalQueryParams.replace(key, values)
|
||||
}
|
||||
|
||||
fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
|
||||
this.additionalQueryParams.replaceAll(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun replaceAllAdditionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) =
|
||||
apply {
|
||||
this.additionalQueryParams.replaceAll(additionalQueryParams)
|
||||
}
|
||||
|
||||
fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
|
||||
|
||||
fun removeAllAdditionalQueryParams(keys: Set<String>) = apply {
|
||||
additionalQueryParams.removeAll(keys)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable instance of [RunGetUrlParams].
|
||||
*
|
||||
* Further updates to this [Builder] will not mutate the returned instance.
|
||||
*
|
||||
* The following fields are required:
|
||||
* ```java
|
||||
* .projectId()
|
||||
* .traceId()
|
||||
* ```
|
||||
*
|
||||
* @throws IllegalStateException if any required field is unset.
|
||||
*/
|
||||
fun build(): RunGetUrlParams =
|
||||
RunGetUrlParams(
|
||||
runId,
|
||||
checkRequired("projectId", projectId),
|
||||
checkRequired("traceId", traceId),
|
||||
startTime,
|
||||
additionalHeaders.build(),
|
||||
additionalQueryParams.build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun _pathParam(index: Int): String =
|
||||
when (index) {
|
||||
0 -> runId ?: ""
|
||||
else -> ""
|
||||
}
|
||||
|
||||
override fun _headers(): Headers = additionalHeaders
|
||||
|
||||
override fun _queryParams(): QueryParams =
|
||||
QueryParams.builder()
|
||||
.apply {
|
||||
put("project_id", projectId)
|
||||
put("trace_id", traceId)
|
||||
startTime?.let { put("start_time", it) }
|
||||
putAll(additionalQueryParams)
|
||||
}
|
||||
.build()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
|
||||
return other is RunGetUrlParams &&
|
||||
runId == other.runId &&
|
||||
projectId == other.projectId &&
|
||||
traceId == other.traceId &&
|
||||
startTime == other.startTime &&
|
||||
additionalHeaders == other.additionalHeaders &&
|
||||
additionalQueryParams == other.additionalQueryParams
|
||||
}
|
||||
|
||||
override fun hashCode(): Int =
|
||||
Objects.hash(runId, projectId, traceId, startTime, additionalHeaders, additionalQueryParams)
|
||||
|
||||
override fun toString() =
|
||||
"RunGetUrlParams{runId=$runId, projectId=$projectId, traceId=$traceId, startTime=$startTime, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
// File generated from our OpenAPI spec by Stainless.
|
||||
|
||||
package com.langchain.smith.models.runs
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.langchain.smith.core.ExcludeMissing
|
||||
import com.langchain.smith.core.JsonField
|
||||
import com.langchain.smith.core.JsonMissing
|
||||
import com.langchain.smith.core.JsonValue
|
||||
import com.langchain.smith.errors.LangChainInvalidDataException
|
||||
import java.util.Collections
|
||||
import java.util.Objects
|
||||
import java.util.Optional
|
||||
|
||||
class RunGetUrlResponse
|
||||
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
|
||||
private constructor(
|
||||
private val url: JsonField<String>,
|
||||
private val additionalProperties: MutableMap<String, JsonValue>,
|
||||
) {
|
||||
|
||||
@JsonCreator
|
||||
private constructor(
|
||||
@JsonProperty("url") @ExcludeMissing url: JsonField<String> = JsonMissing.of()
|
||||
) : this(url, mutableMapOf())
|
||||
|
||||
/**
|
||||
* @throws LangChainInvalidDataException if the JSON field has an unexpected type (e.g. if the
|
||||
* server responded with an unexpected value).
|
||||
*/
|
||||
fun url(): Optional<String> = url.getOptional("url")
|
||||
|
||||
/**
|
||||
* Returns the raw JSON value of [url].
|
||||
*
|
||||
* Unlike [url], this method doesn't throw if the JSON field has an unexpected type.
|
||||
*/
|
||||
@JsonProperty("url") @ExcludeMissing fun _url(): JsonField<String> = url
|
||||
|
||||
@JsonAnySetter
|
||||
private fun putAdditionalProperty(key: String, value: JsonValue) {
|
||||
additionalProperties.put(key, value)
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
@ExcludeMissing
|
||||
fun _additionalProperties(): Map<String, JsonValue> =
|
||||
Collections.unmodifiableMap(additionalProperties)
|
||||
|
||||
fun toBuilder() = Builder().from(this)
|
||||
|
||||
companion object {
|
||||
|
||||
/** Returns a mutable builder for constructing an instance of [RunGetUrlResponse]. */
|
||||
@JvmStatic fun builder() = Builder()
|
||||
}
|
||||
|
||||
/** A builder for [RunGetUrlResponse]. */
|
||||
class Builder internal constructor() {
|
||||
|
||||
private var url: JsonField<String> = JsonMissing.of()
|
||||
private var additionalProperties: MutableMap<String, JsonValue> = mutableMapOf()
|
||||
|
||||
@JvmSynthetic
|
||||
internal fun from(runGetUrlResponse: RunGetUrlResponse) = apply {
|
||||
url = runGetUrlResponse.url
|
||||
additionalProperties = runGetUrlResponse.additionalProperties.toMutableMap()
|
||||
}
|
||||
|
||||
fun url(url: String) = url(JsonField.of(url))
|
||||
|
||||
/**
|
||||
* Sets [Builder.url] to an arbitrary JSON value.
|
||||
*
|
||||
* You should usually call [Builder.url] with a well-typed [String] value instead. This
|
||||
* method is primarily for setting the field to an undocumented or not yet supported value.
|
||||
*/
|
||||
fun url(url: JsonField<String>) = apply { this.url = url }
|
||||
|
||||
fun additionalProperties(additionalProperties: Map<String, JsonValue>) = apply {
|
||||
this.additionalProperties.clear()
|
||||
putAllAdditionalProperties(additionalProperties)
|
||||
}
|
||||
|
||||
fun putAdditionalProperty(key: String, value: JsonValue) = apply {
|
||||
additionalProperties.put(key, value)
|
||||
}
|
||||
|
||||
fun putAllAdditionalProperties(additionalProperties: Map<String, JsonValue>) = apply {
|
||||
this.additionalProperties.putAll(additionalProperties)
|
||||
}
|
||||
|
||||
fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
|
||||
|
||||
fun removeAllAdditionalProperties(keys: Set<String>) = apply {
|
||||
keys.forEach(::removeAdditionalProperty)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable instance of [RunGetUrlResponse].
|
||||
*
|
||||
* Further updates to this [Builder] will not mutate the returned instance.
|
||||
*/
|
||||
fun build(): RunGetUrlResponse = RunGetUrlResponse(url, additionalProperties.toMutableMap())
|
||||
}
|
||||
|
||||
private var validated: Boolean = false
|
||||
|
||||
/**
|
||||
* Validates that the types of all values in this object match their expected types recursively.
|
||||
*
|
||||
* This method is _not_ forwards compatible with new types from the API for existing fields.
|
||||
*
|
||||
* @throws LangChainInvalidDataException if any value type in this object doesn't match its
|
||||
* expected type.
|
||||
*/
|
||||
fun validate(): RunGetUrlResponse = apply {
|
||||
if (validated) {
|
||||
return@apply
|
||||
}
|
||||
|
||||
url()
|
||||
validated = true
|
||||
}
|
||||
|
||||
fun isValid(): Boolean =
|
||||
try {
|
||||
validate()
|
||||
true
|
||||
} catch (e: LangChainInvalidDataException) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a score indicating how many valid values are contained in this object recursively.
|
||||
*
|
||||
* Used for best match union deserialization.
|
||||
*/
|
||||
@JvmSynthetic internal fun validity(): Int = (if (url.asKnown().isPresent) 1 else 0)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
|
||||
return other is RunGetUrlResponse &&
|
||||
url == other.url &&
|
||||
additionalProperties == other.additionalProperties
|
||||
}
|
||||
|
||||
private val hashCode: Int by lazy { Objects.hash(url, additionalProperties) }
|
||||
|
||||
override fun hashCode(): Int = hashCode
|
||||
|
||||
override fun toString() =
|
||||
"RunGetUrlResponse{url=$url, additionalProperties=$additionalProperties}"
|
||||
}
|
||||
+55
@@ -8,6 +8,8 @@ import com.langchain.smith.core.http.HttpResponseFor
|
||||
import com.langchain.smith.models.runs.Run
|
||||
import com.langchain.smith.models.runs.RunCreateParams
|
||||
import com.langchain.smith.models.runs.RunCreateResponse
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunGetUrlResponse
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunIngestBatchResponse
|
||||
@@ -102,6 +104,31 @@ interface RunServiceAsync {
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<Void?>
|
||||
|
||||
/**
|
||||
* Returns the URL to view a specific run in the LangSmith UI. The caller must supply the run's
|
||||
* project_id and trace_id as query parameters; start_time is optional.
|
||||
*/
|
||||
fun getUrl(runId: String, params: RunGetUrlParams): CompletableFuture<RunGetUrlResponse> =
|
||||
getUrl(runId, params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
runId: String,
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<RunGetUrlResponse> =
|
||||
getUrl(params.toBuilder().runId(runId).build(), requestOptions)
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(params: RunGetUrlParams): CompletableFuture<RunGetUrlResponse> =
|
||||
getUrl(params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<RunGetUrlResponse>
|
||||
|
||||
/**
|
||||
* Ingests a batch of runs in a single JSON payload. The payload must have `post` and/or `patch`
|
||||
* arrays containing run objects. Prefer this endpoint over single‑run ingestion when submitting
|
||||
@@ -430,6 +457,34 @@ interface RunServiceAsync {
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<HttpResponseFor<RunUpdateResponse>>
|
||||
|
||||
/**
|
||||
* Returns a raw HTTP response for `get /v2/runs/{run_id}/url`, but is otherwise the same as
|
||||
* [RunServiceAsync.getUrl].
|
||||
*/
|
||||
fun getUrl(
|
||||
runId: String,
|
||||
params: RunGetUrlParams,
|
||||
): CompletableFuture<HttpResponseFor<RunGetUrlResponse>> =
|
||||
getUrl(runId, params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
runId: String,
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<HttpResponseFor<RunGetUrlResponse>> =
|
||||
getUrl(params.toBuilder().runId(runId).build(), requestOptions)
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(params: RunGetUrlParams): CompletableFuture<HttpResponseFor<RunGetUrlResponse>> =
|
||||
getUrl(params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): CompletableFuture<HttpResponseFor<RunGetUrlResponse>>
|
||||
|
||||
/**
|
||||
* Returns a raw HTTP response for `post /runs/batch`, but is otherwise the same as
|
||||
* [RunServiceAsync.ingestBatch].
|
||||
|
||||
+42
@@ -26,6 +26,8 @@ import com.langchain.smith.models.info.InfoListResponse
|
||||
import com.langchain.smith.models.runs.Run
|
||||
import com.langchain.smith.models.runs.RunCreateParams
|
||||
import com.langchain.smith.models.runs.RunCreateResponse
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunGetUrlResponse
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunIngestBatchResponse
|
||||
@@ -210,6 +212,13 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client
|
||||
return CompletableFuture.completedFuture(null)
|
||||
}
|
||||
|
||||
override fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions,
|
||||
): CompletableFuture<RunGetUrlResponse> =
|
||||
// get /v2/runs/{run_id}/url
|
||||
withRawResponse().getUrl(params, requestOptions).thenApply { it.parse() }
|
||||
|
||||
override fun ingestBatch(
|
||||
params: RunIngestBatchParams,
|
||||
requestOptions: RequestOptions,
|
||||
@@ -419,6 +428,39 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client
|
||||
}
|
||||
}
|
||||
|
||||
private val getUrlHandler: Handler<RunGetUrlResponse> =
|
||||
jsonHandler<RunGetUrlResponse>(clientOptions.jsonMapper)
|
||||
|
||||
override fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions,
|
||||
): CompletableFuture<HttpResponseFor<RunGetUrlResponse>> {
|
||||
// We check here instead of in the params builder because this can be specified
|
||||
// positionally or in the params class.
|
||||
checkRequired("runId", params.runId().getOrNull())
|
||||
val request =
|
||||
HttpRequest.builder()
|
||||
.method(HttpMethod.GET)
|
||||
.baseUrl(clientOptions.baseUrl())
|
||||
.addPathSegments("v2", "runs", params._pathParam(0), "url")
|
||||
.build()
|
||||
.prepareAsync(clientOptions, params)
|
||||
val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions))
|
||||
return request
|
||||
.thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) }
|
||||
.thenApply { response ->
|
||||
errorHandler.handle(response).parseable {
|
||||
response
|
||||
.use { getUrlHandler.handle(it) }
|
||||
.also {
|
||||
if (requestOptions.responseValidation!!) {
|
||||
it.validate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val ingestBatchHandler: Handler<RunIngestBatchResponse> =
|
||||
jsonHandler<RunIngestBatchResponse>(clientOptions.jsonMapper)
|
||||
|
||||
|
||||
+54
@@ -9,6 +9,8 @@ import com.langchain.smith.core.http.HttpResponseFor
|
||||
import com.langchain.smith.models.runs.Run
|
||||
import com.langchain.smith.models.runs.RunCreateParams
|
||||
import com.langchain.smith.models.runs.RunCreateResponse
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunGetUrlResponse
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunIngestBatchResponse
|
||||
@@ -96,6 +98,29 @@ interface RunService {
|
||||
/** @see update */
|
||||
fun update(params: RunUpdateParams, requestOptions: RequestOptions = RequestOptions.none())
|
||||
|
||||
/**
|
||||
* Returns the URL to view a specific run in the LangSmith UI. The caller must supply the run's
|
||||
* project_id and trace_id as query parameters; start_time is optional.
|
||||
*/
|
||||
fun getUrl(runId: String, params: RunGetUrlParams): RunGetUrlResponse =
|
||||
getUrl(runId, params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
runId: String,
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): RunGetUrlResponse = getUrl(params.toBuilder().runId(runId).build(), requestOptions)
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(params: RunGetUrlParams): RunGetUrlResponse = getUrl(params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): RunGetUrlResponse
|
||||
|
||||
/**
|
||||
* Ingests a batch of runs in a single JSON payload. The payload must have `post` and/or `patch`
|
||||
* arrays containing run objects. Prefer this endpoint over single‑run ingestion when submitting
|
||||
@@ -416,6 +441,35 @@ interface RunService {
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): HttpResponseFor<RunUpdateResponse>
|
||||
|
||||
/**
|
||||
* Returns a raw HTTP response for `get /v2/runs/{run_id}/url`, but is otherwise the same as
|
||||
* [RunService.getUrl].
|
||||
*/
|
||||
@MustBeClosed
|
||||
fun getUrl(runId: String, params: RunGetUrlParams): HttpResponseFor<RunGetUrlResponse> =
|
||||
getUrl(runId, params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
@MustBeClosed
|
||||
fun getUrl(
|
||||
runId: String,
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): HttpResponseFor<RunGetUrlResponse> =
|
||||
getUrl(params.toBuilder().runId(runId).build(), requestOptions)
|
||||
|
||||
/** @see getUrl */
|
||||
@MustBeClosed
|
||||
fun getUrl(params: RunGetUrlParams): HttpResponseFor<RunGetUrlResponse> =
|
||||
getUrl(params, RequestOptions.none())
|
||||
|
||||
/** @see getUrl */
|
||||
@MustBeClosed
|
||||
fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions = RequestOptions.none(),
|
||||
): HttpResponseFor<RunGetUrlResponse>
|
||||
|
||||
/**
|
||||
* Returns a raw HTTP response for `post /runs/batch`, but is otherwise the same as
|
||||
* [RunService.ingestBatch].
|
||||
|
||||
+39
@@ -26,6 +26,8 @@ import com.langchain.smith.models.info.InfoListResponse
|
||||
import com.langchain.smith.models.runs.Run
|
||||
import com.langchain.smith.models.runs.RunCreateParams
|
||||
import com.langchain.smith.models.runs.RunCreateResponse
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunGetUrlResponse
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunIngestBatchResponse
|
||||
@@ -188,6 +190,13 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio
|
||||
private val logger = LoggerFactory.getLogger(RunServiceImpl::class.java)
|
||||
}
|
||||
|
||||
override fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions,
|
||||
): RunGetUrlResponse =
|
||||
// get /v2/runs/{run_id}/url
|
||||
withRawResponse().getUrl(params, requestOptions).parse()
|
||||
|
||||
override fun ingestBatch(
|
||||
params: RunIngestBatchParams,
|
||||
requestOptions: RequestOptions,
|
||||
@@ -336,6 +345,36 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio
|
||||
}
|
||||
}
|
||||
|
||||
private val getUrlHandler: Handler<RunGetUrlResponse> =
|
||||
jsonHandler<RunGetUrlResponse>(clientOptions.jsonMapper)
|
||||
|
||||
override fun getUrl(
|
||||
params: RunGetUrlParams,
|
||||
requestOptions: RequestOptions,
|
||||
): HttpResponseFor<RunGetUrlResponse> {
|
||||
// We check here instead of in the params builder because this can be specified
|
||||
// positionally or in the params class.
|
||||
checkRequired("runId", params.runId().getOrNull())
|
||||
val request =
|
||||
HttpRequest.builder()
|
||||
.method(HttpMethod.GET)
|
||||
.baseUrl(clientOptions.baseUrl())
|
||||
.addPathSegments("v2", "runs", params._pathParam(0), "url")
|
||||
.build()
|
||||
.prepare(clientOptions, params)
|
||||
val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions))
|
||||
val response = clientOptions.httpClient.execute(request, requestOptions)
|
||||
return errorHandler.handle(response).parseable {
|
||||
response
|
||||
.use { getUrlHandler.handle(it) }
|
||||
.also {
|
||||
if (requestOptions.responseValidation!!) {
|
||||
it.validate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val ingestBatchHandler: Handler<RunIngestBatchResponse> =
|
||||
jsonHandler<RunIngestBatchResponse>(clientOptions.jsonMapper)
|
||||
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
// File generated from our OpenAPI spec by Stainless.
|
||||
|
||||
package com.langchain.smith.models.runs
|
||||
|
||||
import com.langchain.smith.core.http.QueryParams
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class RunGetUrlParamsTest {
|
||||
|
||||
@Test
|
||||
fun create() {
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.startTime("start_time")
|
||||
.build()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pathParams() {
|
||||
val params =
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.build()
|
||||
|
||||
assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
// out-of-bound path param
|
||||
assertThat(params._pathParam(1)).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun queryParams() {
|
||||
val params =
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.startTime("start_time")
|
||||
.build()
|
||||
|
||||
val queryParams = params._queryParams()
|
||||
|
||||
assertThat(queryParams)
|
||||
.isEqualTo(
|
||||
QueryParams.builder()
|
||||
.put("project_id", "project_id")
|
||||
.put("trace_id", "trace_id")
|
||||
.put("start_time", "start_time")
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun queryParamsWithoutOptionalFields() {
|
||||
val params =
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.build()
|
||||
|
||||
val queryParams = params._queryParams()
|
||||
|
||||
assertThat(queryParams)
|
||||
.isEqualTo(
|
||||
QueryParams.builder()
|
||||
.put("project_id", "project_id")
|
||||
.put("trace_id", "trace_id")
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// File generated from our OpenAPI spec by Stainless.
|
||||
|
||||
package com.langchain.smith.models.runs
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
|
||||
import com.langchain.smith.core.jsonMapper
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class RunGetUrlResponseTest {
|
||||
|
||||
@Test
|
||||
fun create() {
|
||||
val runGetUrlResponse = RunGetUrlResponse.builder().url("url").build()
|
||||
|
||||
assertThat(runGetUrlResponse.url()).contains("url")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun roundtrip() {
|
||||
val jsonMapper = jsonMapper()
|
||||
val runGetUrlResponse = RunGetUrlResponse.builder().url("url").build()
|
||||
|
||||
val roundtrippedRunGetUrlResponse =
|
||||
jsonMapper.readValue(
|
||||
jsonMapper.writeValueAsString(runGetUrlResponse),
|
||||
jacksonTypeRef<RunGetUrlResponse>(),
|
||||
)
|
||||
|
||||
assertThat(roundtrippedRunGetUrlResponse).isEqualTo(runGetUrlResponse)
|
||||
}
|
||||
}
|
||||
+25
@@ -11,6 +11,7 @@ import com.langchain.smith.core.http.Headers
|
||||
import com.langchain.smith.core.http.HttpClient
|
||||
import com.langchain.smith.core.http.HttpRequest
|
||||
import com.langchain.smith.core.http.HttpResponse
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunRetrieveParams
|
||||
@@ -312,6 +313,30 @@ internal class RunServiceAsyncTest {
|
||||
runFuture.get()
|
||||
}
|
||||
|
||||
@Disabled("Mock server tests are disabled")
|
||||
@Test
|
||||
fun getUrl() {
|
||||
val client =
|
||||
LangsmithOkHttpClientAsync.builder()
|
||||
.apiKey("My API Key")
|
||||
.tenantId("My Tenant ID")
|
||||
.build()
|
||||
val runServiceAsync = client.runs()
|
||||
|
||||
val responseFuture =
|
||||
runServiceAsync.getUrl(
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.startTime("start_time")
|
||||
.build()
|
||||
)
|
||||
|
||||
val response = responseFuture.get()
|
||||
response.validate()
|
||||
}
|
||||
|
||||
@Disabled("Mock server tests are disabled")
|
||||
@Test
|
||||
fun ingestBatch() {
|
||||
|
||||
+21
@@ -25,6 +25,7 @@ import com.langchain.smith.core.http.HttpRequest
|
||||
import com.langchain.smith.core.http.HttpResponse
|
||||
import com.langchain.smith.models.runs.RunAttachment
|
||||
import com.langchain.smith.models.runs.RunCreateParams
|
||||
import com.langchain.smith.models.runs.RunGetUrlParams
|
||||
import com.langchain.smith.models.runs.RunIngest
|
||||
import com.langchain.smith.models.runs.RunIngestBatchParams
|
||||
import com.langchain.smith.models.runs.RunRetrieveParams
|
||||
@@ -605,6 +606,26 @@ internal class RunServiceTest {
|
||||
private fun testRun(id: String): RunIngest =
|
||||
RunIngest.builder().id(id).traceId(id).dottedOrder("order").name("test").build()
|
||||
|
||||
@Disabled("Mock server tests are disabled")
|
||||
@Test
|
||||
fun getUrl() {
|
||||
val client =
|
||||
LangsmithOkHttpClient.builder().apiKey("My API Key").tenantId("My Tenant ID").build()
|
||||
val runService = client.runs()
|
||||
|
||||
val response =
|
||||
runService.getUrl(
|
||||
RunGetUrlParams.builder()
|
||||
.runId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")
|
||||
.projectId("project_id")
|
||||
.traceId("trace_id")
|
||||
.startTime("start_time")
|
||||
.build()
|
||||
)
|
||||
|
||||
response.validate()
|
||||
}
|
||||
|
||||
@Disabled("Mock server tests are disabled")
|
||||
@Test
|
||||
fun ingestBatch() {
|
||||
|
||||
Reference in New Issue
Block a user