diff --git a/instrumentation/openai/openai-java-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/openai/v1_1/EmbeddingsTest.java b/instrumentation/openai/openai-java-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/openai/v1_1/EmbeddingsTest.java new file mode 100644 index 000000000000..c31bffa92357 --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/openai/v1_1/EmbeddingsTest.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.openai.v1_1; + +import com.openai.client.OpenAIClient; +import com.openai.client.OpenAIClientAsync; +import io.opentelemetry.instrumentation.openai.v1_1.AbstractEmbeddingsTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import org.junit.jupiter.api.extension.RegisterExtension; + +class EmbeddingsTest extends AbstractEmbeddingsTest { + + @RegisterExtension + private static final AgentInstrumentationExtension testing = + AgentInstrumentationExtension.create(); + + @Override + protected InstrumentationExtension getTesting() { + return testing; + } + + @Override + protected OpenAIClient wrap(OpenAIClient client) { + return client; + } + + @Override + protected OpenAIClientAsync wrap(OpenAIClientAsync client) { + return client; + } + + @Override + protected final List> maybeWithTransportSpan( + Consumer span) { + List> result = new ArrayList<>(); + result.add(span); + // Do a very simple assertion since the telemetry is not part of this library. + result.add(s -> s.hasName("POST")); + return result; + } +} diff --git a/instrumentation/openai/openai-java-1.1/library/README.md b/instrumentation/openai/openai-java-1.1/library/README.md index 4451ec510262..1a90fba0fd3e 100644 --- a/instrumentation/openai/openai-java-1.1/library/README.md +++ b/instrumentation/openai/openai-java-1.1/library/README.md @@ -1,6 +1,7 @@ # Library Instrumentation for OpenAI Java SDK version 1.1.0 and higher Provides OpenTelemetry instrumentation for [openai-java](https://github.com/openai/openai-java/). +Versions 1.1 through 2.x are supported. ## Quickstart diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingAttributesGetter.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingAttributesGetter.java new file mode 100644 index 000000000000..3503ff4da4c1 --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingAttributesGetter.java @@ -0,0 +1,129 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import static java.util.Collections.singletonList; + +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; +import io.opentelemetry.instrumentation.api.incubator.semconv.genai.GenAiAttributesGetter; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +enum EmbeddingAttributesGetter + implements GenAiAttributesGetter { + INSTANCE; + + @Override + public String getOperationName(EmbeddingCreateParams request) { + return GenAiAttributes.GenAiOperationNameIncubatingValues.EMBEDDINGS; + } + + @Override + public String getSystem(EmbeddingCreateParams request) { + return GenAiAttributes.GenAiSystemIncubatingValues.OPENAI; + } + + @Override + public String getRequestModel(EmbeddingCreateParams request) { + return request.model().asString(); + } + + @Nullable + @Override + public Long getRequestSeed(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public List getRequestEncodingFormats(EmbeddingCreateParams request) { + return request.encodingFormat().map(f -> singletonList(f.asString())).orElse(null); + } + + @Nullable + @Override + public Double getRequestFrequencyPenalty(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public Long getRequestMaxTokens(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public Double getRequestPresencePenalty(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public List getRequestStopSequences(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public Double getRequestTemperature(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public Double getRequestTopK(EmbeddingCreateParams request) { + return null; + } + + @Nullable + @Override + public Double getRequestTopP(EmbeddingCreateParams request) { + return null; + } + + @Override + public List getResponseFinishReasons( + EmbeddingCreateParams request, @Nullable CreateEmbeddingResponse response) { + return Collections.emptyList(); + } + + @Nullable + @Override + public String getResponseId( + EmbeddingCreateParams request, @Nullable CreateEmbeddingResponse response) { + return null; + } + + @Nullable + @Override + public String getResponseModel( + EmbeddingCreateParams request, @Nullable CreateEmbeddingResponse response) { + if (response == null) { + return null; + } + return response.model(); + } + + @Nullable + @Override + public Long getUsageInputTokens( + EmbeddingCreateParams request, @Nullable CreateEmbeddingResponse response) { + if (response == null) { + return null; + } + return response.usage().promptTokens(); + } + + @Nullable + @Override + public Long getUsageOutputTokens( + EmbeddingCreateParams request, @Nullable CreateEmbeddingResponse response) { + return null; + } +} diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/GenAiAttributes.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/GenAiAttributes.java index b34e4d3c7cab..c6209d44acdb 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/GenAiAttributes.java +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/GenAiAttributes.java @@ -15,6 +15,7 @@ final class GenAiAttributes { static final class GenAiOperationNameIncubatingValues { static final String CHAT = "chat"; + static final String EMBEDDINGS = "embeddings"; private GenAiOperationNameIncubatingValues() {} } diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingService.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingService.java new file mode 100644 index 000000000000..a40c512267cb --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingService.java @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import com.openai.core.RequestOptions; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; +import com.openai.services.blocking.EmbeddingService; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import java.lang.reflect.Method; + +final class InstrumentedEmbeddingService + extends DelegatingInvocationHandler { + + private final Instrumenter instrumenter; + + public InstrumentedEmbeddingService( + EmbeddingService delegate, + Instrumenter instrumenter) { + super(delegate); + this.instrumenter = instrumenter; + } + + @Override + protected Class getProxyType() { + return EmbeddingService.class; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String methodName = method.getName(); + Class[] parameterTypes = method.getParameterTypes(); + + if (methodName.equals("create") + && parameterTypes.length >= 1 + && parameterTypes[0] == EmbeddingCreateParams.class) { + if (parameterTypes.length == 1) { + return create((EmbeddingCreateParams) args[0], RequestOptions.none()); + } else if (parameterTypes.length == 2 && parameterTypes[1] == RequestOptions.class) { + return create((EmbeddingCreateParams) args[0], (RequestOptions) args[1]); + } + } + + return super.invoke(proxy, method, args); + } + + private CreateEmbeddingResponse create( + EmbeddingCreateParams request, RequestOptions requestOptions) { + Context parentContext = Context.current(); + if (!instrumenter.shouldStart(parentContext, request)) { + return delegate.create(request, requestOptions); + } + + Context context = instrumenter.start(parentContext, request); + CreateEmbeddingResponse response; + try (Scope ignored = context.makeCurrent()) { + response = delegate.create(request, requestOptions); + } catch (Throwable t) { + instrumenter.end(context, request, null, t); + throw t; + } + + instrumenter.end(context, request, response, null); + return response; + } +} diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingServiceAsync.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingServiceAsync.java new file mode 100644 index 000000000000..a0195d257186 --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedEmbeddingServiceAsync.java @@ -0,0 +1,72 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import com.openai.core.RequestOptions; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; +import com.openai.services.async.EmbeddingServiceAsync; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; + +final class InstrumentedEmbeddingServiceAsync + extends DelegatingInvocationHandler { + + private final Instrumenter instrumenter; + + public InstrumentedEmbeddingServiceAsync( + EmbeddingServiceAsync delegate, + Instrumenter instrumenter) { + super(delegate); + this.instrumenter = instrumenter; + } + + @Override + protected Class getProxyType() { + return EmbeddingServiceAsync.class; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String methodName = method.getName(); + Class[] parameterTypes = method.getParameterTypes(); + + if (methodName.equals("create") + && parameterTypes.length >= 1 + && parameterTypes[0] == EmbeddingCreateParams.class) { + if (parameterTypes.length == 1) { + return create((EmbeddingCreateParams) args[0], RequestOptions.none()); + } else if (parameterTypes.length == 2 && parameterTypes[1] == RequestOptions.class) { + return create((EmbeddingCreateParams) args[0], (RequestOptions) args[1]); + } + } + + return super.invoke(proxy, method, args); + } + + private CompletableFuture create( + EmbeddingCreateParams request, RequestOptions requestOptions) { + Context parentContext = Context.current(); + if (!instrumenter.shouldStart(parentContext, request)) { + return delegate.create(request, requestOptions); + } + + Context context = instrumenter.start(parentContext, request); + CompletableFuture future; + try (Scope ignored = context.makeCurrent()) { + future = delegate.create(request, requestOptions); + } catch (Throwable t) { + instrumenter.end(context, request, null, t); + throw t; + } + + future = future.whenComplete((res, t) -> instrumenter.end(context, request, res, t)); + return CompletableFutureWrapper.wrap(future, parentContext); + } +} diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClient.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClient.java index 754c5e8ba7f2..4fd816b5b7cb 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClient.java +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClient.java @@ -8,6 +8,8 @@ import com.openai.client.OpenAIClient; import com.openai.models.chat.completions.ChatCompletion; import com.openai.models.chat.completions.ChatCompletionCreateParams; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.lang.reflect.Method; @@ -16,16 +18,19 @@ final class InstrumentedOpenAiClient extends DelegatingInvocationHandler { private final Instrumenter chatInstrumenter; + private final Instrumenter embeddingInstrumenter; private final Logger eventLogger; private final boolean captureMessageContent; InstrumentedOpenAiClient( OpenAIClient delegate, Instrumenter chatInstrumenter, + Instrumenter embeddingInstrumenter, Logger eventLogger, boolean captureMessageContent) { super(delegate); this.chatInstrumenter = chatInstrumenter; + this.embeddingInstrumenter = embeddingInstrumenter; this.eventLogger = eventLogger; this.captureMessageContent = captureMessageContent; } @@ -44,9 +49,17 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl delegate.chat(), chatInstrumenter, eventLogger, captureMessageContent) .createProxy(); } + if (methodName.equals("embeddings") && parameterTypes.length == 0) { + return new InstrumentedEmbeddingService(delegate.embeddings(), embeddingInstrumenter) + .createProxy(); + } if (methodName.equals("async") && parameterTypes.length == 0) { return new InstrumentedOpenAiClientAsync( - delegate.async(), chatInstrumenter, eventLogger, captureMessageContent) + delegate.async(), + chatInstrumenter, + embeddingInstrumenter, + eventLogger, + captureMessageContent) .createProxy(); } return super.invoke(proxy, method, args); diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClientAsync.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClientAsync.java index bc7635590c79..bace0b179a1d 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClientAsync.java +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/InstrumentedOpenAiClientAsync.java @@ -8,6 +8,8 @@ import com.openai.client.OpenAIClientAsync; import com.openai.models.chat.completions.ChatCompletion; import com.openai.models.chat.completions.ChatCompletionCreateParams; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.lang.reflect.Method; @@ -16,16 +18,19 @@ final class InstrumentedOpenAiClientAsync extends DelegatingInvocationHandler { private final Instrumenter chatInstrumenter; + private final Instrumenter embeddingInstrumenter; private final Logger eventLogger; private final boolean captureMessageContent; InstrumentedOpenAiClientAsync( OpenAIClientAsync delegate, Instrumenter chatInstrumenter, + Instrumenter embeddingInstrumenter, Logger eventLogger, boolean captureMessageContent) { super(delegate); this.chatInstrumenter = chatInstrumenter; + this.embeddingInstrumenter = embeddingInstrumenter; this.eventLogger = eventLogger; this.captureMessageContent = captureMessageContent; } @@ -44,9 +49,17 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl delegate.chat(), chatInstrumenter, eventLogger, captureMessageContent) .createProxy(); } + if (methodName.equals("embeddings") && parameterTypes.length == 0) { + return new InstrumentedEmbeddingServiceAsync(delegate.embeddings(), embeddingInstrumenter) + .createProxy(); + } if (methodName.equals("sync") && parameterTypes.length == 0) { return new InstrumentedOpenAiClient( - delegate.sync(), chatInstrumenter, eventLogger, captureMessageContent) + delegate.sync(), + chatInstrumenter, + embeddingInstrumenter, + eventLogger, + captureMessageContent) .createProxy(); } return super.invoke(proxy, method, args); diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetry.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetry.java index 7a44eec4a581..f6528eec741f 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetry.java +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetry.java @@ -9,6 +9,8 @@ import com.openai.client.OpenAIClientAsync; import com.openai.models.chat.completions.ChatCompletion; import com.openai.models.chat.completions.ChatCompletionCreateParams; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; @@ -29,6 +31,7 @@ public static OpenAITelemetryBuilder builder(OpenTelemetry openTelemetry) { } private final Instrumenter chatInstrumenter; + private final Instrumenter embeddingsInstrumenter; private final Logger eventLogger; @@ -36,9 +39,11 @@ public static OpenAITelemetryBuilder builder(OpenTelemetry openTelemetry) { OpenAITelemetry( Instrumenter chatInstrumenter, + Instrumenter embeddingsInstrumenter, Logger eventLogger, boolean captureMessageContent) { this.chatInstrumenter = chatInstrumenter; + this.embeddingsInstrumenter = embeddingsInstrumenter; this.eventLogger = eventLogger; this.captureMessageContent = captureMessageContent; } @@ -46,14 +51,14 @@ public static OpenAITelemetryBuilder builder(OpenTelemetry openTelemetry) { /** Wraps the provided OpenAIClient, enabling telemetry for it. */ public OpenAIClient wrap(OpenAIClient client) { return new InstrumentedOpenAiClient( - client, chatInstrumenter, eventLogger, captureMessageContent) + client, chatInstrumenter, embeddingsInstrumenter, eventLogger, captureMessageContent) .createProxy(); } /** Wraps the provided OpenAIClientAsync, enabling telemetry for it. */ public OpenAIClientAsync wrap(OpenAIClientAsync client) { return new InstrumentedOpenAiClientAsync( - client, chatInstrumenter, eventLogger, captureMessageContent) + client, chatInstrumenter, embeddingsInstrumenter, eventLogger, captureMessageContent) .createProxy(); } } diff --git a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetryBuilder.java b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetryBuilder.java index 8d0574b541a7..5f36c76a5798 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetryBuilder.java +++ b/instrumentation/openai/openai-java-1.1/library/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/OpenAITelemetryBuilder.java @@ -8,12 +8,15 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.openai.models.chat.completions.ChatCompletion; import com.openai.models.chat.completions.ChatCompletionCreateParams; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.instrumentation.api.incubator.semconv.genai.GenAiAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.genai.GenAiClientMetrics; import io.opentelemetry.instrumentation.api.incubator.semconv.genai.GenAiSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; /** A builder of {@link OpenAITelemetry}. */ @SuppressWarnings("IdentifierName") // Want to match library's convention @@ -53,7 +56,18 @@ public OpenAITelemetry build() { .addOperationMetrics(GenAiClientMetrics.get()) .buildInstrumenter(); + Instrumenter embeddingsInstrumenter = + Instrumenter.builder( + openTelemetry, + INSTRUMENTATION_NAME, + GenAiSpanNameExtractor.create(EmbeddingAttributesGetter.INSTANCE)) + .addAttributesExtractor( + GenAiAttributesExtractor.create(EmbeddingAttributesGetter.INSTANCE)) + .addOperationMetrics(GenAiClientMetrics.get()) + .buildInstrumenter(SpanKindExtractor.alwaysClient()); + Logger eventLogger = openTelemetry.getLogsBridge().get(INSTRUMENTATION_NAME); - return new OpenAITelemetry(chatInstrumenter, eventLogger, captureMessageContent); + return new OpenAITelemetry( + chatInstrumenter, embeddingsInstrumenter, eventLogger, captureMessageContent); } } diff --git a/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingsTest.java b/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingsTest.java new file mode 100644 index 000000000000..0e7870933fbf --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/EmbeddingsTest.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import static java.util.Collections.singletonList; + +import com.openai.client.OpenAIClient; +import com.openai.client.OpenAIClientAsync; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; +import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; +import java.util.List; +import java.util.function.Consumer; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.RegisterExtension; + +class EmbeddingsTest extends AbstractEmbeddingsTest { + + @RegisterExtension + private static final LibraryInstrumentationExtension testing = + LibraryInstrumentationExtension.create(); + + private static OpenAITelemetry telemetry; + + @BeforeAll + static void setup() { + telemetry = + OpenAITelemetry.builder(testing.getOpenTelemetry()).setCaptureMessageContent(true).build(); + } + + @Override + protected InstrumentationExtension getTesting() { + return testing; + } + + @Override + protected OpenAIClient wrap(OpenAIClient client) { + return telemetry.wrap(client); + } + + @Override + protected OpenAIClientAsync wrap(OpenAIClientAsync client) { + return telemetry.wrap(client); + } + + @Override + protected List> maybeWithTransportSpan(Consumer span) { + return singletonList(span); + } +} diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java index e1f11a464405..a3e8dc56ff9b 100644 --- a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java @@ -62,9 +62,6 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.opentelemetry.instrumentation.testing.recording.RecordingExtension; -import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -73,28 +70,10 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletionException; -import java.util.function.Consumer; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.Parameter; -import org.junit.jupiter.params.ParameterizedClass; -import org.junit.jupiter.params.provider.EnumSource; - -@ParameterizedClass -@EnumSource(AbstractChatTest.TestType.class) -public abstract class AbstractChatTest { - enum TestType { - SYNC, - SYNC_FROM_ASYNC, - ASYNC, - ASYNC_FROM_SYNC, - } - - protected static final String INSTRUMENTATION_NAME = "io.opentelemetry.openai-java-1.1"; - - private static final String API_URL = "https://api.openai.com/v1"; +public abstract class AbstractChatTest extends AbstractOpenAiTest { protected static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); protected static final String TEST_CHAT_MODEL = "gpt-4o-mini"; @@ -102,49 +81,6 @@ enum TestType { protected static final String TEST_CHAT_INPUT = "Answer in up to 3 words: Which ocean contains Bouvet Island?"; - @RegisterExtension static final RecordingExtension recording = new RecordingExtension(API_URL); - - protected abstract InstrumentationExtension getTesting(); - - protected abstract OpenAIClient wrap(OpenAIClient client); - - protected abstract OpenAIClientAsync wrap(OpenAIClientAsync client); - - protected final OpenAIClient getRawClient() { - OpenAIOkHttpClient.Builder builder = - OpenAIOkHttpClient.builder().baseUrl("http://localhost:" + recording.getPort()); - if (recording.isRecording()) { - builder.apiKey(System.getenv("OPENAI_API_KEY")); - } else { - builder.apiKey("unused"); - } - return builder.build(); - } - - protected final OpenAIClientAsync getRawClientAsync() { - OpenAIOkHttpClientAsync.Builder builder = - OpenAIOkHttpClientAsync.builder().baseUrl("http://localhost:" + recording.getPort()); - if (recording.isRecording()) { - builder.apiKey(System.getenv("OPENAI_API_KEY")); - } else { - builder.apiKey("unused"); - } - return builder.build(); - } - - protected final OpenAIClient getClient() { - return wrap(getRawClient()); - } - - protected final OpenAIClientAsync getClientAsync() { - return wrap(getRawClientAsync()); - } - - protected abstract List> maybeWithTransportSpan( - Consumer span); - - @Parameter TestType testType; - protected final ChatCompletion doCompletions(ChatCompletionCreateParams params) { return doCompletions(params, getClient(), getClientAsync()); } diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java new file mode 100644 index 000000000000..a58a362501fe --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java @@ -0,0 +1,277 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_OPERATION_NAME; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_REQUEST_ENCODING_FORMATS; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_REQUEST_MODEL; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_RESPONSE_MODEL; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_SYSTEM; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_TOKEN_TYPE; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_USAGE_INPUT_TOKENS; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GenAiOperationNameIncubatingValues.EMBEDDINGS; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GenAiSystemIncubatingValues.OPENAI; +import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GenAiTokenTypeIncubatingValues.INPUT; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; + +import com.openai.client.OpenAIClient; +import com.openai.client.OpenAIClientAsync; +import com.openai.client.okhttp.OpenAIOkHttpClient; +import com.openai.client.okhttp.OpenAIOkHttpClientAsync; +import com.openai.errors.OpenAIIoException; +import com.openai.models.embeddings.CreateEmbeddingResponse; +import com.openai.models.embeddings.EmbeddingCreateParams; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import java.util.concurrent.CompletionException; +import org.junit.jupiter.api.Test; + +public abstract class AbstractEmbeddingsTest extends AbstractOpenAiTest { + private static final String MODEL = "text-embedding-3-small"; + + protected final CreateEmbeddingResponse doEmbeddings(EmbeddingCreateParams request) { + return doEmbeddings(request, getClient(), getClientAsync()); + } + + protected final CreateEmbeddingResponse doEmbeddings( + EmbeddingCreateParams request, OpenAIClient client, OpenAIClientAsync clientAsync) { + switch (testType) { + case SYNC: + return client.embeddings().create(request); + case SYNC_FROM_ASYNC: + return clientAsync.sync().embeddings().create(request); + case ASYNC: + case ASYNC_FROM_SYNC: + OpenAIClientAsync cl = testType == TestType.ASYNC ? clientAsync : client.async(); + try { + return cl.embeddings() + .create(request) + .thenApply( + res -> { + assertThat(Span.fromContextOrNull(Context.current())).isNull(); + return res; + }) + .join(); + } catch (CompletionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } + throw e; + } + } + throw new AssertionError(); + } + + @Test + void basic() { + String text = "South Atlantic Ocean."; + + EmbeddingCreateParams request = + EmbeddingCreateParams.builder() + .model(MODEL) + .inputOfArrayOfStrings(singletonList(text)) + .build(); + CreateEmbeddingResponse response = doEmbeddings(request); + + assertThat(response.data()).hasSize(1); + + getTesting() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + maybeWithTransportSpan( + span -> + span.hasName("embeddings text-embedding-3-small") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_USAGE_INPUT_TOKENS, 4), + // Newer versions of the library populate base64 when unset by + // the user. + satisfies( + GEN_AI_REQUEST_ENCODING_FORMATS, + val -> + val.satisfiesAnyOf( + v -> assertThat(v).isNull(), + v -> + assertThat(v) + .isEqualTo(singletonList("base64")))))))); + + getTesting() + .waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))), + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(4.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT))))); + } + + @Test + void allTheClientOptions() { + String text = "South Atlantic Ocean."; + + EmbeddingCreateParams request = + EmbeddingCreateParams.builder() + .model(MODEL) + .encodingFormat(EmbeddingCreateParams.EncodingFormat.BASE64) + .inputOfArrayOfStrings(singletonList(text)) + .build(); + CreateEmbeddingResponse response = doEmbeddings(request); + + assertThat(response.data()).hasSize(1); + + getTesting() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + maybeWithTransportSpan( + span -> + span.hasName("embeddings text-embedding-3-small") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo( + GEN_AI_REQUEST_ENCODING_FORMATS, singletonList("base64")), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_USAGE_INPUT_TOKENS, 4))))); + + getTesting() + .waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))), + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(4.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT))))); + } + + @Test + void connectionError() { + OpenAIClient client = + wrap( + OpenAIOkHttpClient.builder() + .baseUrl("http://localhost:9999/v5") + .apiKey("testing") + .maxRetries(0) + .build()); + OpenAIClientAsync clientAsync = + wrap( + OpenAIOkHttpClientAsync.builder() + .baseUrl("http://localhost:9999/v5") + .apiKey("testing") + .maxRetries(0) + .build()); + + EmbeddingCreateParams request = + EmbeddingCreateParams.builder() + .model(MODEL) + .inputOfArrayOfStrings(singletonList(INPUT)) + .build(); + + Throwable thrown = catchThrowable(() -> doEmbeddings(request, client, clientAsync)); + assertThat(thrown).isInstanceOf(OpenAIIoException.class); + + getTesting() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + maybeWithTransportSpan( + span -> + span.hasName("embeddings text-embedding-3-small") + .hasKind(SpanKind.CLIENT) + .hasException(thrown) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + // Newer versions of the library populate base64 when unset by + // the user. + satisfies( + GEN_AI_REQUEST_ENCODING_FORMATS, + val -> + val.satisfiesAnyOf( + v -> assertThat(v).isNull(), + v -> + assertThat(v) + .isEqualTo(singletonList("base64")))))))); + + getTesting() + .waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_SYSTEM, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL))))); + } +} diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractOpenAiTest.java b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractOpenAiTest.java new file mode 100644 index 000000000000..9fd4123971a2 --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractOpenAiTest.java @@ -0,0 +1,87 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.openai.v1_1; + +import com.openai.client.OpenAIClient; +import com.openai.client.OpenAIClientAsync; +import com.openai.client.okhttp.OpenAIOkHttpClient; +import com.openai.client.okhttp.OpenAIOkHttpClientAsync; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.recording.RecordingExtension; +import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; +import java.util.List; +import java.util.function.Consumer; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.EnumSource; + +@ParameterizedClass +@EnumSource(AbstractOpenAiTest.TestType.class) +abstract class AbstractOpenAiTest { + enum TestType { + SYNC, + SYNC_FROM_ASYNC, + ASYNC, + ASYNC_FROM_SYNC, + } + + protected static final String INSTRUMENTATION_NAME = "io.opentelemetry.openai-java-1.1"; + + private static final String API_URL = "https://api.openai.com/v1"; + + @RegisterExtension static final RecordingExtension recording = new RecordingExtension(API_URL); + + protected abstract InstrumentationExtension getTesting(); + + protected abstract OpenAIClient wrap(OpenAIClient client); + + protected abstract OpenAIClientAsync wrap(OpenAIClientAsync client); + + private OpenAIClient rawClient; + private OpenAIClientAsync rawClientAsync; + + protected final OpenAIClient getRawClient() { + if (rawClient == null) { + OpenAIOkHttpClient.Builder builder = + OpenAIOkHttpClient.builder().baseUrl("http://localhost:" + recording.getPort()); + if (recording.isRecording()) { + builder.apiKey(System.getenv("OPENAI_API_KEY")); + } else { + builder.apiKey("unused"); + } + rawClient = builder.build(); + } + return rawClient; + } + + protected final OpenAIClientAsync getRawClientAsync() { + if (rawClientAsync == null) { + OpenAIOkHttpClientAsync.Builder builder = + OpenAIOkHttpClientAsync.builder().baseUrl("http://localhost:" + recording.getPort()); + if (recording.isRecording()) { + builder.apiKey(System.getenv("OPENAI_API_KEY")); + } else { + builder.apiKey("unused"); + } + rawClientAsync = builder.build(); + } + return rawClientAsync; + } + + protected final OpenAIClient getClient() { + return wrap(getRawClient()); + } + + protected final OpenAIClientAsync getClientAsync() { + return wrap(getRawClientAsync()); + } + + protected abstract List> maybeWithTransportSpan( + Consumer span); + + @Parameter protected TestType testType; +} diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.alltheclientoptions.yaml b/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.alltheclientoptions.yaml new file mode 100644 index 000000000000..f5017d89df4d --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.alltheclientoptions.yaml @@ -0,0 +1,62 @@ +--- +id: 100ca9fa-bca3-4922-8287-4da475c9ce69 +name: embeddings +request: + url: /embeddings + method: POST + bodyPatterns: + - equalToJson: |- + { + "input" : [ "South Atlantic Ocean." ], + "model" : "text-embedding-3-small", + "encoding_format" : "base64" + } + ignoreArrayOrder: false + ignoreExtraElements: false +response: + status: 200 + body: | + { + "object": "list", + "data": [ + { + "object": "embedding", + "index": 0, + "embedding": "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" + } + ], + "model": "text-embedding-3-small", + "usage": { + "prompt_tokens": 4, + "total_tokens": 4 + } + } + headers: + Date: "Fri, 25 Jul 2025 06:40:50 GMT" + Content-Type: application/json + access-control-allow-origin: '*' + access-control-expose-headers: X-Request-ID + openai-model: text-embedding-3-small + openai-organization: test_organization + openai-processing-ms: "94" + openai-project: proj_Pf1eM5R55Z35wBy4rt8PxAGq + openai-version: 2020-10-01 + strict-transport-security: max-age=31536000; includeSubDomains; preload + via: envoy-router-7f8f4c5dfc-gfmqg + x-envoy-upstream-service-time: "103" + x-ratelimit-limit-requests: "5000" + x-ratelimit-limit-tokens: "5000000" + x-ratelimit-remaining-requests: "4999" + x-ratelimit-remaining-tokens: "4999994" + x-ratelimit-reset-requests: 12ms + x-ratelimit-reset-tokens: 0s + x-request-id: req_4960c59d7e3e1254fd4fa8f21808c6ae + cf-cache-status: DYNAMIC + Set-Cookie: test_set_cookie + X-Content-Type-Options: nosniff + Server: cloudflare + CF-RAY: 9649ab0aac86263c-NRT + alt-svc: h3=":443"; ma=86400 +uuid: 100ca9fa-bca3-4922-8287-4da475c9ce69 +persistent: true +insertionIndex: 38 diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.basic.yaml b/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.basic.yaml new file mode 100644 index 000000000000..5e36d3dff18c --- /dev/null +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/resources/mappings/io.opentelemetry.instrumentation.openai.v1_1.abstractembeddingstest.basic.yaml @@ -0,0 +1,1598 @@ +--- +id: 227a6023-72ed-4209-ab5d-a90c31f47de0 +name: embeddings +request: + url: /embeddings + method: POST + bodyPatterns: + - equalToJson: |- + { + "input" : [ "South Atlantic Ocean." ], + "model" : "text-embedding-3-small" + } + ignoreArrayOrder: false + ignoreExtraElements: false +response: + status: 200 + body: | + { + "object": "list", + "data": [ + { + "object": "embedding", + "index": 0, + "embedding": [ + -0.031545512, + -0.030183835, + 0.010292007, + 0.009111887, + -0.030864673, + 0.06481581, + 0.036016352, + -0.0019474814, + -0.0046864375, + -0.02102656, + 0.0026651986, + -0.010916109, + -0.018723056, + -0.012096229, + 0.014989791, + 0.024464794, + -0.024260541, + 0.018893266, + 0.01660111, + 0.023193894, + -0.028232098, + -0.035585154, + -0.06281869, + 0.061093897, + 0.020345721, + -0.014978444, + 0.008243818, + 0.018246468, + -0.06368108, + 0.025939943, + 0.10512145, + -0.0307512, + 0.00093686196, + 0.0657236, + 0.03930707, + 0.06862851, + -0.020425152, + -0.011733115, + -0.055874135, + 0.008209776, + 0.029003715, + -0.055556413, + 0.0033446185, + 0.0019744313, + 0.008476438, + 0.005350255, + -0.06871929, + -0.031704374, + 0.035040483, + 0.014308954, + -0.034132697, + 0.028459044, + -0.032407906, + -0.04309707, + 0.043165155, + -0.025758386, + -0.013560032, + 0.0026949854, + 0.06921857, + -0.0004801329, + -0.047023237, + 0.048838805, + -0.0015942965, + -0.005137493, + -0.046160843, + -0.002419813, + 0.014059313, + 0.061366234, + -0.056055695, + -0.019767009, + -0.048430305, + 0.022093205, + 0.024124373, + -0.03640216, + -0.053831622, + -0.014853625, + -0.014728804, + -0.03626599, + -0.001547489, + -0.034450423, + -0.029502997, + 0.06281869, + 0.021503145, + -0.012391259, + -0.01554581, + -0.04259779, + 0.016237995, + 0.008425375, + -0.018393984, + 0.026530003, + -0.032748327, + -0.020776918, + -0.020992517, + -0.010462217, + -0.010093429, + 0.039125513, + -0.009418264, + 0.012743025, + 0.024124373, + -0.0049814675, + -0.024169764, + -0.026121499, + 0.020799613, + -0.014025271, + -0.028322877, + -0.024805212, + 0.0018623767, + 0.01011045, + 0.012527427, + -0.011381349, + -0.009066498, + 0.029434914, + -0.0016184095, + 0.018927308, + -0.00461268, + -0.02110599, + 0.0029162578, + -0.06449809, + 0.055964917, + 0.0053162132, + 0.008124672, + -0.036583718, + 0.02132159, + -0.014047965, + -0.037082996, + -0.011613968, + -0.025168326, + -0.010252291, + 0.0067970366, + 0.0030580992, + 0.009531737, + -0.012527427, + -0.016067786, + -0.030978147, + 0.020062039, + 0.07107953, + -0.006428249, + -0.021673355, + 0.0012602602, + 0.011994103, + 0.022944253, + 0.027914373, + 0.039238986, + 0.0034751126, + 0.020118775, + -0.004414102, + -0.05564719, + 0.027120063, + 0.020130122, + -0.03846737, + 0.013253654, + -0.0049275677, + 0.003892126, + 0.025803775, + -0.0047375006, + -0.012924582, + -0.0036595063, + 0.0055176276, + 0.011744462, + -0.0017446483, + 0.0027687429, + -0.023023685, + 0.043074377, + 0.023783954, + -0.016816707, + -0.008493459, + 0.006689237, + 0.0155911995, + -0.052016053, + -0.0115004955, + -0.008187082, + -0.02068614, + -0.025599523, + -0.004955936, + -0.010501932, + -0.035744015, + 0.009429611, + -0.031772457, + -0.01815569, + 0.016782666, + -0.0212762, + 0.0022680429, + 0.035880182, + -0.007114761, + 0.0068480996, + 0.035902876, + 0.010331723, + -0.010445195, + -0.004204177, + -0.009480675, + 0.019188296, + -0.024918685, + 0.07067102, + 0.015750062, + -0.0069332044, + -0.04645587, + 0.014013924, + 0.044980723, + -0.008226797, + 0.033497248, + 0.028232098, + -0.023012338, + -0.033633415, + -0.060186114, + -0.021786828, + -0.033179525, + -0.053740844, + 0.021208115, + 0.055193298, + 0.0005897053, + 0.016317427, + -0.018654972, + 0.02607611, + 0.019880481, + -0.026575392, + -0.003236819, + -0.016657846, + 0.0096905995, + 0.023488924, + -0.012391259, + -0.036039047, + 0.013889103, + 0.01579545, + 0.026303057, + -0.0133103905, + 0.051380605, + 0.056418806, + -0.022467667, + 0.009571453, + -0.021798175, + 0.027029283, + 0.017474853, + -0.006496333, + -0.034813534, + -0.051698327, + -0.04039641, + -0.0058608837, + 0.011545884, + 0.021242158, + 0.009866483, + -0.028844854, + -0.014342995, + 0.05101749, + 0.029843416, + -0.013423864, + -0.020266289, + 0.046365093, + 0.039080124, + -0.016226647, + 0.050155096, + -0.008226797, + -0.01495575, + 0.025849164, + 0.010848025, + 0.010581363, + -0.009480675, + -0.050790545, + -0.05296923, + -0.03989713, + -0.01584084, + -0.045593478, + -0.022932906, + -0.048203357, + 0.010082082, + 0.024714433, + -0.0062069767, + 0.033111442, + 0.006167261, + -0.034178086, + -0.021559883, + 0.0032651874, + 0.037627667, + 0.006314776, + 0.0039999257, + 0.028073236, + 0.035063177, + 0.024691738, + 0.01933581, + 0.011545884, + -0.004453818, + 0.0278009, + -0.056101084, + -0.06685833, + 0.012674942, + -0.012561468, + -0.015647935, + 0.008589911, + -0.027437788, + 0.038989346, + 0.032997966, + 0.081428275, + 0.024805212, + -0.020652099, + -0.015999703, + -0.026030721, + 0.006314776, + 0.021332936, + -0.0018212427, + -0.027937068, + -0.0036708536, + 0.054194737, + -0.019959912, + 0.0136054205, + -0.016498983, + 0.008391333, + 0.03533551, + -0.0463424, + 0.016079133, + 0.023897428, + 0.011006887, + 0.020459194, + 0.0009141674, + 0.034836233, + -0.0174862, + 0.03699222, + -0.0119714085, + -0.054875575, + -0.0031517143, + 0.0035744016, + -0.027142758, + 0.012028145, + 0.024328625, + -0.024964074, + 0.012028145, + -0.0003819078, + -0.046183538, + -0.025304493, + -0.023670482, + 0.024396708, + -0.015182696, + 0.0018510293, + 0.0066041322, + 0.04368713, + -0.009934567, + 0.02216129, + -0.039624795, + -0.032748327, + 0.028345572, + -0.03533551, + 0.06059462, + -0.0092196865, + -0.018348595, + 0.02245632, + 0.02519102, + -0.010013998, + -0.009633863, + -0.018541498, + 0.014411079, + 0.07543689, + -0.015500421, + 0.008680689, + 0.0056509585, + -0.005843863, + -0.010189882, + -0.023647787, + 0.030546948, + 0.033088747, + -0.034768146, + -0.06876468, + 0.021242158, + -0.032589465, + 0.0036027697, + -0.03168168, + 0.00081700605, + 0.04511689, + -0.024124373, + -0.00514884, + 0.0021957038, + 0.00821545, + -0.011568579, + -0.03572132, + 0.047976412, + -0.052061442, + 0.0191656, + -0.0035942593, + 0.043414794, + -0.051743716, + 0.0015148654, + -0.032589465, + -0.0012815364, + -0.044549525, + 0.052469946, + -0.027460482, + 0.0049672835, + 0.029366829, + -0.052560724, + 0.0033247608, + -0.029979583, + -0.00431765, + -0.026098805, + -0.038490064, + -0.026802339, + 0.034700062, + 0.002731864, + -0.0032963925, + 0.008714732, + 0.042348146, + -0.018087607, + -0.038217727, + 0.048838805, + 0.034246173, + -0.027347008, + -0.0063091023, + -0.02283078, + 0.00916295, + 0.015125959, + -0.057235815, + 0.025667608, + 0.005594222, + -0.014569942, + -0.00093969883, + -0.05414935, + -0.0037673058, + 0.03383767, + 0.00007686027, + 0.040351022, + -0.015477726, + 0.05156216, + 0.0044282866, + 0.025667608, + -0.005012673, + 0.055374857, + -0.0075346115, + -0.0042495662, + 0.011937367, + 0.072895095, + 0.034677368, + -0.030342698, + 0.014184133, + 0.015772756, + 0.056010306, + -0.0103090275, + 0.007557306, + 0.030138446, + -0.016986918, + 0.024759823, + -0.0069956146, + 0.012856498, + -0.031068925, + 0.011245181, + 0.0037843266, + 0.020311678, + 0.0007595603, + 0.008709058, + -0.008039567, + -0.0019616657, + 0.03277102, + 0.021378325, + -0.054694016, + -0.017917397, + 0.053740844, + -0.0049956515, + -0.0059289676, + 0.012743025, + 0.028663296, + -0.019449282, + -0.008657995, + 0.027460482, + 0.012799761, + 0.045979287, + 0.008397006, + -0.016691888, + -0.054648627, + 0.011074971, + 0.029843416, + 0.02809593, + 0.000699987, + 0.0661321, + -0.0052112504, + -0.008703384, + -0.022115901, + -0.009214013, + 0.028844854, + 0.014762846, + -0.019676229, + 0.0036566695, + -0.007727516, + -0.020413805, + -0.043324016, + -0.0315909, + -0.002432579, + -0.006473638, + -0.028663296, + -0.0140025765, + -0.018393984, + -0.029071799, + -0.004746011, + 0.013718894, + -0.042824734, + -0.026121499, + 0.022740003, + 0.031704374, + -0.008113324, + -0.0083516175, + 0.034858927, + -0.04107725, + -0.04516228, + -0.021922996, + 0.05296923, + -0.0492927, + 0.042075813, + 0.0046240273, + -0.011778505, + 0.0057190424, + 0.07566384, + -0.04473108, + -0.016816707, + -0.053196173, + -0.025803775, + 0.015239432, + -0.0011248018, + 0.04028294, + -0.017542936, + -0.03556246, + -0.007194192, + -0.0044424706, + -0.0121189235, + 0.025576828, + -0.0015630914, + -0.0014680577, + -0.0076651056, + -0.021253506, + -0.019245032, + -0.0025815123, + -0.045888506, + -0.0011730278, + -0.028663296, + -0.0064566173, + -0.021151379, + 0.037173778, + 0.009429611, + 0.027029283, + -0.015352906, + -0.007960135, + -0.026734253, + -0.021491798, + -0.04039641, + 0.014581289, + -0.01152319, + 0.034064613, + 0.009355854, + 0.015602547, + -0.014751499, + 0.027324313, + -0.008941677, + 0.006808384, + -0.018393984, + -0.008266512, + 0.043868687, + 0.023239283, + -0.019222338, + 0.00060424407, + 0.0140025765, + -0.0074551804, + -0.0028155504, + -0.03551707, + 0.008028219, + -0.017463505, + -0.013911798, + 0.013446558, + 0.029366829, + -0.016533025, + -0.022354193, + -0.00945798, + 0.008714732, + 0.057780486, + 0.016703235, + -0.01879114, + -0.00087516103, + 0.030342698, + 0.02355701, + 0.032839105, + -0.012618205, + -0.006592785, + 0.0066551953, + 0.023783954, + 0.033292998, + -0.017622367, + -0.014354343, + 0.0143997315, + -0.0229556, + -0.022615181, + -0.015307517, + 0.044163715, + -0.0062523657, + 0.011982756, + -0.023284674, + -0.004073683, + 0.032158267, + 0.0064509436, + 0.054694016, + -0.02809593, + -0.0137075465, + -0.023307368, + -0.021196768, + -0.00857289, + 0.04275665, + -0.008385659, + 0.012164312, + 0.042620484, + 0.018212426, + -0.024805212, + -0.017077696, + -0.004972957, + -0.034518506, + 0.00059112377, + 0.014558595, + -0.02371587, + -0.015557157, + 0.020527277, + 0.011267875, + 0.043664437, + 0.017724494, + -0.051244438, + 0.010802636, + 0.0132082645, + -0.0568727, + 0.033678807, + 0.006955899, + -0.017474853, + -0.0070750457, + 0.024464794, + 0.029798027, + 0.007977157, + -0.020447847, + -0.0039204946, + -0.023398146, + 0.052333776, + 0.0062069767, + 0.002241093, + -0.018405331, + 0.028504433, + 0.019074822, + 0.007381423, + -0.0072906446, + 0.018348595, + -0.01866632, + 0.024873296, + 0.053150784, + 0.00857289, + -0.032907188, + 0.02253575, + 0.014592636, + 0.0026538514, + 0.014252217, + -0.012232397, + 0.012436648, + -0.014672067, + -0.029003715, + 0.011846588, + 0.034495812, + 0.018393984, + 0.011188444, + -0.019540062, + -0.02911719, + -0.03374689, + 0.01778123, + -0.039080124, + -0.029207967, + -0.0043630395, + -0.0087431, + 0.0379227, + 0.018950002, + -0.04629701, + -0.015477726, + -0.0057530846, + -0.008385659, + -0.0016524515, + 0.027868984, + -0.043119766, + 0.03969288, + -0.009968609, + 0.042280063, + 0.0072736233, + 0.039738268, + -0.004794237, + 0.025849164, + -0.010944477, + 0.012958624, + 0.0005116926, + -0.03383767, + 0.022490362, + -0.0068480996, + 0.029661858, + -0.011245181, + -0.0013616767, + -0.012084882, + -0.011239507, + -0.009537411, + 0.047613297, + -0.027074674, + 0.04554809, + 0.022649223, + 0.017803924, + 0.014252217, + 0.018654972, + -0.020742876, + -0.0019488999, + 0.020368416, + -0.017168475, + 0.04516228, + -0.005174372, + 0.012096229, + 0.0074268123, + -0.006269387, + -0.012504731, + -0.007892052, + 0.0008233889, + 0.02039111, + 0.043460183, + 0.016657846, + 0.014864972, + -0.047613297, + 0.0050495514, + 0.0015148654, + -0.009140255, + -0.010779941, + 0.020663446, + -0.042189285, + -0.007131782, + 0.03606174, + 0.01004804, + -0.022989644, + 0.012981319, + 0.03247599, + 0.008595585, + 0.02405629, + 0.001938971, + 0.0011439504, + -0.005103451, + -0.016294733, + 0.017974133, + 0.00022730073, + 0.009775705, + 0.012652246, + 0.036606412, + -0.006967246, + -0.021514494, + 0.02076557, + 0.0037928373, + 0.013106139, + 0.0015262127, + 0.020266289, + 0.011948714, + 0.025145631, + -0.0030666096, + -0.01407066, + -0.015954314, + 0.047613297, + -0.003418376, + -0.029639164, + 0.005367276, + 0.016033744, + 0.023670482, + -0.0320221, + -0.014683414, + 0.01276572, + 0.012277786, + -0.034450423, + -0.0029843417, + -0.0055204644, + 0.018847875, + 0.040577967, + 0.017066348, + 0.020470541, + -0.00031293742, + -0.017633714, + 0.0086012585, + 0.052061442, + 0.019596798, + 0.016952876, + -0.025712997, + -0.0024836417, + 0.033179525, + -0.0039034735, + 0.0049701203, + -0.0073700757, + 0.022898864, + -0.017111737, + -0.0067062583, + -0.0015162838, + -0.030546948, + 0.008033893, + -0.002625483, + 0.0012779904, + 0.0015942965, + 0.0240109, + -0.008198429, + 0.03079659, + 0.004615517, + 0.0059573357, + -0.0014950077, + -0.029457608, + -0.01992587, + 0.058506712, + 0.033588026, + 0.033519942, + -0.044050243, + -0.03168168, + 0.015874881, + 0.031568207, + -0.008845225, + -0.0025304493, + -0.04039641, + 0.0028439187, + 0.051153656, + -0.0048623206, + 0.047204796, + -0.0108536985, + -0.0069332044, + -0.009735989, + 0.0007084974, + -0.0324306, + 0.020708835, + 0.033134136, + -0.007869357, + 0.024578266, + 0.008255165, + -0.011699073, + 0.014388384, + 0.024737129, + 0.011857935, + 0.024464794, + 0.0019205316, + 0.052878447, + 0.007767231, + 0.045003418, + -0.020720182, + 0.014978444, + -0.023114463, + 0.061230067, + 0.0070807193, + -0.025281798, + -0.0143997315, + 0.014240869, + -0.03803617, + -0.029480303, + -0.026507309, + -0.024986768, + 0.029230662, + 0.059913777, + 0.0019829418, + -0.013276349, + 0.00052800437, + 0.018859223, + 0.019483326, + 0.012845151, + -0.002519102, + 0.010689163, + -0.0094693275, + 0.013560032, + -0.013299043, + -0.030705811, + -0.032453295, + 0.025667608, + -0.022808086, + -0.0074665276, + -0.005307703, + -0.029888805, + -0.013026708, + -0.0037531217, + 0.010172861, + 0.008527501, + -0.03336108, + -0.018416679, + 0.015364253, + -0.008771468, + 0.02355701, + 0.020924434, + -0.009293444, + -0.00941259, + 0.036175214, + -0.044708386, + -0.023284674, + -0.013684852, + 0.007301992, + 0.021627966, + 0.020708835, + -0.0058325157, + 0.025100242, + 0.03669719, + 0.015057876, + -0.050291263, + 0.03733264, + -0.044504136, + 0.010677815, + 0.02194569, + 0.010439522, + -0.016567068, + 0.027868984, + 0.02283078, + 0.020720182, + 0.00030815028, + -0.0061048507, + -0.009974282, + -0.050018925, + -0.028549824, + -0.021503145, + 0.017792577, + -0.0018141506, + -0.016317427, + 0.020606708, + 0.0019162764, + -0.04023755, + 0.005693511, + 0.028617907, + 0.011080645, + 0.0013269257, + 0.043868687, + 0.021673355, + -0.040078685, + 0.031727068, + 0.024215152, + 0.012663594, + 0.031908628, + 0.0034751126, + -0.0023971186, + -0.016794013, + 0.0046892744, + -0.00278009, + 0.024827907, + -0.009004088, + -0.021854913, + -0.025803775, + 0.013809672, + 0.0017489037, + -0.011960061, + 0.0050608986, + -0.029502997, + -0.01112036, + 0.010831004, + -0.0013552939, + 0.0164309, + 0.003997089, + 0.00021400311, + -0.025145631, + 0.0320221, + 0.002151733, + 0.011188444, + -0.008941677, + 0.049655814, + -0.005611243, + 0.028050542, + -0.030524254, + -0.011489148, + -0.023148505, + 0.013469253, + 0.032929882, + 0.007018309, + -0.037900005, + 0.026643476, + 0.028481739, + 0.03635677, + -0.0034637654, + -0.011914671, + 0.005741737, + 0.03184054, + 0.0054495437, + 0.002772998, + -0.058733657, + 0.0021886118, + 0.003449581, + 0.01638551, + -0.0057928, + 0.0015233759, + -0.0060651354, + -0.029775333, + 0.002021239, + 0.053786233, + -0.046750903, + -0.012130271, + -0.01828051, + 0.051380605, + 0.047658686, + -0.0036708536, + 0.02843635, + 0.007835316, + 0.0041360934, + -0.0366518, + -0.01778123, + -0.0051119616, + 0.027188146, + -0.024124373, + -0.03635677, + -0.003858084, + 0.005906273, + -0.009917546, + 0.025009463, + 0.0231712, + -0.027392399, + 0.0008198429, + -0.03415539, + 0.03383767, + 0.029185273, + 0.018178385, + -0.008828204, + 0.016181258, + -0.0036680168, + -0.02132159, + 0.0030382413, + -0.015523115, + -0.012379912, + -0.012334522, + -0.014059313, + -0.0073870965, + 0.022853475, + -0.017588325, + 0.006133219, + 0.014445121, + -0.019279074, + -0.035744015, + 0.03690144, + 0.024419403, + 0.025145631, + 0.024374014, + -0.054240126, + 0.02342084, + -0.003682201, + -0.059686832, + 0.022864822, + 0.053650066, + 0.006484986, + 0.044458747, + -0.009401243, + -0.031182399, + 0.00443396, + 0.0025985332, + 0.00544387, + 0.053604677, + -0.020323025, + -0.010831004, + -0.015886229, + 0.0009014017, + 0.017894702, + 0.010178534, + 0.027959764, + -0.010257965, + -0.0053559286, + 0.002872287, + 0.063544914, + 0.013423864, + -0.003469439, + -0.0056878375, + -0.0063601653, + -0.014354343, + 0.017872008, + -0.008465091, + 0.000423751, + -0.017645061, + -0.011665031, + 0.00068012916, + 0.011438085, + 0.030115752, + -0.011846588, + -0.05859749, + 0.013355779, + 0.017372726, + -0.025054853, + 0.0076026954, + 0.022127248, + -0.0023162689, + 0.012334522, + -0.00016976634, + -0.024510182, + -0.009435285, + 0.015897576, + 0.028776769, + 0.023375452, + -0.047794856, + 0.0064395964, + 0.025826469, + 0.04393677, + 0.008181408, + 0.015818145, + -0.040623356, + -0.021378325, + -0.019687576, + -0.006774342, + 0.016124522, + 0.06440731, + -0.028799463, + 0.04300629, + 0.0039034735, + -0.011755809, + -0.010121797, + 0.024759823, + -0.033928446, + -0.00703533, + -0.030615034, + -0.017179823, + -0.0104849115, + 0.024555571, + -0.0037559585, + 0.04355096, + 0.0017971296, + -0.01882518, + -0.005398481, + 0.016056439, + -0.00039928334, + -0.009276423, + 0.017837966, + -0.0041360934, + -0.006819731, + 0.031727068, + -0.019233685, + 0.008595585, + -0.011846588, + 0.04019216, + 0.003449581, + -0.019755661, + -0.02186626, + -0.040759526, + 0.0009155858, + -0.037786532, + -0.0022113062, + -0.02784629, + -0.029457608, + -0.003997089, + -0.027029283, + 0.020198205, + 0.01803087, + -0.025690302, + -0.003957373, + 0.002828316, + -0.010910436, + -0.0040169465, + 0.0043119765, + 0.017667755, + -0.027891679, + -0.018008176, + 0.0034070287, + -0.014762846, + 0.027573954, + -0.0045559434, + 0.01601105, + 0.007148803, + -0.007931767, + -0.016101828, + -0.031137008, + 0.043278627, + 0.03980635, + 0.03572132, + 0.018110301, + 0.0057956367, + 0.018167038, + 0.029139884, + 0.028890243, + 0.09368336, + 0.013741588, + -0.031137008, + -0.020947129, + 0.0307512, + -0.008953025, + -0.021968385, + 0.025168326, + 0.014274912, + 0.015216738, + 0.013843714, + 0.0053162132, + 0.019596798, + 0.0011389859, + -0.00067303714, + 0.033519942, + 0.042915512, + 0.0018467741, + 0.050745156, + -0.012277786, + 0.0032453297, + -0.025735691, + -0.02941222, + 0.03501779, + 0.0121189235, + 0.020879043, + 0.0005205577, + -0.019687576, + 0.017849313, + -0.011069298, + 0.00857289, + -0.02911719, + 0.004896363, + 0.02014147, + -0.04865725, + 0.03079659, + -0.015398295, + 0.0006397044, + -0.02578108, + 0.03556246, + 0.0010772849, + -0.01247069, + -0.02553144, + -0.011630989, + -0.009429611, + -0.0044424706, + -0.00031080982, + -0.003242493, + -0.015307517, + 0.002941789, + -0.012822457, + 0.045184974, + -0.0015120286, + 0.0143997315, + -0.040078685, + -0.020561319, + 0.0017829455, + -0.023375452, + 0.0149444025, + -0.023579704, + 0.012436648, + 0.007182845, + 0.026552698, + 0.06799306, + 0.002178683, + -0.023534313, + -0.023398146, + -0.008493459, + -0.011744462, + -0.015954314, + -0.004346018, + -0.012822457, + 0.020447847, + -0.014252217, + 0.006331797, + 0.005216924, + 0.037900005, + -0.032044794, + -0.041485753, + 0.042075813, + -0.018393984, + -0.014581289, + 0.038308505, + 0.0010808309, + 0.031159703, + -0.04448144, + -0.0042580767, + -0.00319143, + 0.010286333, + -0.033270303, + -0.012538774, + 0.007460854, + 0.006031093, + 0.0079544615, + 0.018098954, + 0.014842276, + 0.0007269368, + 0.05691809, + 0.0014581289, + 0.03883048, + 0.03129587, + 0.0061559137, + -0.028050542, + -0.014161439, + 0.015511768, + -0.044935334, + 0.025032159, + -0.020130122, + -0.011086319, + 0.016964223, + 0.0011709002, + 0.027074674, + -0.0043914076, + -0.016555721, + 0.003616954, + 0.007835316, + 0.011364328, + 0.016113175, + -0.018598236, + 0.015534462, + -0.00230634, + -0.027642038, + 0.04237084, + -0.02941222, + 0.0011957224, + 0.047023237, + 0.008062261, + 0.0421212, + -0.03576671, + 0.040668745, + 0.00257442, + -0.010660795, + -0.0032510033, + 0.00095459213, + 0.008374312, + 0.036379464, + 0.0067629945, + -0.0061275456, + -0.011994103, + -0.0021418042, + -0.003060936, + 0.005055225, + -0.021854913, + -0.03336108, + 0.018598236, + -0.04915653, + 0.022059163, + -0.005367276, + -0.0033020661, + -0.020357069, + -0.016612457, + 0.005236782, + -0.027392399, + 0.023216588, + 0.016464941, + -0.015352906, + -0.014933055, + -0.0078807045, + 0.008408354, + 0.020459194, + 0.027596649, + 0.011364328, + -0.032793716, + -0.024737129, + 0.034064613, + -0.0011340214, + 0.031341262, + 0.016294733, + -0.03508587, + 0.019869134, + -0.03256677, + -0.025054853, + -0.015273474, + 0.027596649, + 0.014013924, + 0.020334372, + 0.012674942, + 0.014308954, + -0.0002664844, + -0.004036804, + 0.0024382526, + 0.006042441, + -0.017089043, + -0.0030921411, + -0.012493384, + 0.0021772645, + 0.026847728, + -0.0044992073, + -0.016964223, + 0.012538774, + 0.014479163, + 0.03533551, + 0.035244733, + -0.0134579055, + -0.016101828, + 0.0132082645, + 0.039760962, + -0.016828056, + -0.007489222, + 0.030138446, + 0.010263639, + -0.011216813, + 0.006365839, + 0.067720726, + -0.018813834, + 0.025440661, + -0.010740225, + -0.027347008, + 0.007818294, + 0.04073683, + 0.01276572, + -0.010070735, + -0.0029786678, + -0.0007138165, + -0.029934194, + -0.0064055547, + -0.007296318, + 0.0048226053, + 0.023920123, + -0.0018935818, + -0.00009299472, + -0.024532877, + 0.019199643, + -0.006513354, + 0.0058608837, + 0.0012517497, + -0.03592557, + -0.03522204, + -0.0016184095, + -0.02873138, + -0.023443535, + 0.019869134, + 0.0005638193, + -0.019528715, + 0.04743174, + 0.0015829493, + 0.008816857, + -0.016533025, + -0.038444676, + 0.031999405, + 0.0089984145, + 0.027528565, + -0.009696273, + -0.012618205, + 0.01289054, + 0.029344134, + -0.015636588, + 0.0051828823, + 0.048248746, + 0.019233685, + 0.0051006144, + 0.017599672, + 0.008317576, + -0.03340647, + 0.018314553, + 0.02414707, + -0.018462067, + 0.016930182, + -0.014467816, + 0.018927308, + 0.027437788, + 0.007046677, + 0.0004783599, + 0.012777067, + -0.020674793, + 0.032589465, + -0.03753689, + 0.0033304344, + -0.018087607, + -0.03479084, + 0.0076821265, + -0.005923294, + -0.017452158, + -0.037604973, + -0.044390664, + 0.037809227, + -0.009770031, + 0.015398295, + 0.0020481888, + 0.0023091768, + 0.0060083987, + 0.013582726, + 0.0013021034, + -0.03560785, + -0.019528715, + 0.0031119988, + 0.0036623431, + -0.004692111, + 0.011579926, + 0.017894702, + 0.051652938, + -0.0042637503, + 0.02523641, + 0.02312581, + 0.015761409, + -0.021469103, + 0.010280659, + -0.026507309, + -0.012811109, + -0.026507309, + -0.011506169, + -0.016033744, + 0.00020176929, + -0.0030212204, + 0.0052906815, + -0.01786066, + 0.029888805, + -0.015114612, + 0.0060140723, + -0.023443535, + 0.031658985, + -0.005384297, + -0.009480675, + 0.03942054, + 0.028277488, + -0.010967172, + 0.0038665948, + 0.0027545586, + 0.0026822195, + -0.0060083987, + -0.044413358, + -0.014876319, + 0.029820722, + -0.012822457, + -0.020368416, + -0.006859447, + -0.008692036, + 0.034563895, + 0.010274986, + -0.020742876, + 0.0072679496, + -0.017213864, + 0.018098954, + 0.018121649, + 0.024419403, + 0.011551558, + -0.017361378, + 0.0005308412, + -0.059868388, + 0.018246468, + 0.007250929, + -0.012731678, + 0.016759971, + -0.039738268, + 0.001914858, + 0.003517665, + -0.0005804856, + 0.0038694316, + 0.03345186, + -0.012073535, + 0.01845072, + -0.043573655, + 0.004641048, + 0.0013482019, + -0.010621079, + -0.017338684, + 0.0025247757, + 0.019891828, + -0.018212426, + -0.035880182, + 0.012845151, + -0.012958624, + 0.006246692, + -0.010269312, + -0.009577126, + -0.01828051, + -0.017202517, + 0.029548386, + -0.036129825, + 0.00933316, + -0.0046070064, + -0.030251918, + -0.011937367, + 0.02553144, + 0.0049956515, + -0.030864673, + 0.0013673505, + 0.030546948, + -0.010462217, + 0.038535453, + -0.045207668, + 0.008652321, + 0.0027588138, + -0.008975719, + 0.039760962, + 0.025304493, + 0.0299115, + 0.020572666, + 0.045139585 + ] + } + ], + "model": "text-embedding-3-small", + "usage": { + "prompt_tokens": 4, + "total_tokens": 4 + } + } + headers: + Date: "Fri, 25 Jul 2025 06:33:50 GMT" + Content-Type: application/json + access-control-allow-origin: '*' + access-control-expose-headers: X-Request-ID + openai-model: text-embedding-3-small + openai-organization: test_organization + openai-processing-ms: "115" + openai-project: proj_Pf1eM5R55Z35wBy4rt8PxAGq + openai-version: 2020-10-01 + strict-transport-security: max-age=31536000; includeSubDomains; preload + via: envoy-router-84549dd555-dssv8 + x-envoy-upstream-service-time: "118" + x-ratelimit-limit-requests: "5000" + x-ratelimit-limit-tokens: "5000000" + x-ratelimit-remaining-requests: "4999" + x-ratelimit-remaining-tokens: "4999994" + x-ratelimit-reset-requests: 12ms + x-ratelimit-reset-tokens: 0s + x-request-id: req_23145c67d571cd4266c17f1985b90434 + cf-cache-status: DYNAMIC + Set-Cookie: test_set_cookie + X-Content-Type-Options: nosniff + Server: cloudflare + CF-RAY: 9649a0c7591f986e-NRT + alt-svc: h3=":443"; ma=86400 +uuid: 227a6023-72ed-4209-ab5d-a90c31f47de0 +persistent: true +insertionIndex: 36