Skip to content

Commit d33eec2

Browse files
authored
refactor: drops SDK schema use in image generation (#1628)
1 parent dda2995 commit d33eec2

File tree

13 files changed

+164
-66
lines changed

13 files changed

+164
-66
lines changed

internal/apischema/openai/openai.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,3 +1900,99 @@ type Usage struct {
19001900
// Only populated for /v1/chat/completions endpoint, not for /v1/completions.
19011901
PromptTokensDetails *PromptTokensDetails `json:"prompt_tokens_details,omitempty"` //nolint:tagliatelle //follow openai api
19021902
}
1903+
1904+
// ImageGenerationRequest represents the request body for /v1/images/generations.
1905+
// https://platform.openai.com/docs/api-reference/images/create
1906+
type ImageGenerationRequest struct {
1907+
// A text description of the desired image(s). The maximum length is 1000 characters for DALL-E 2,
1908+
// 4000 characters for DALL-E 3, and 32000 characters for gpt-image-1.
1909+
Prompt string `json:"prompt"`
1910+
// The model to use for image generation. Defaults to dall-e-2.
1911+
Model string `json:"model,omitempty"`
1912+
// The number of images to generate. Must be between 1 and 10. For DALL-E 3, only n=1 is supported.
1913+
// Defaults to 1.
1914+
N int `json:"n,omitempty"`
1915+
// The quality of the image that will be generated.
1916+
// - hd or standard for DALL-E 3.
1917+
// - high, medium, or low for gpt-image-1.
1918+
// Defaults to standard for DALL-E 3, auto for gpt-image-1.
1919+
Quality string `json:"quality,omitempty"`
1920+
// The format in which the generated images are returned. Must be one of url or b64_json.
1921+
// URLs are only valid for 60 minutes after the image has been generated.
1922+
// This parameter isn't supported for gpt-image-1 which will always return base64-encoded images.
1923+
// Defaults to url.
1924+
ResponseFormat string `json:"response_format,omitempty"`
1925+
// The size of the generated images.
1926+
// - DALL-E 2: 256x256, 512x512, or 1024x1024.
1927+
// - DALL-E 3: 1024x1024, 1792x1024, or 1024x1792.
1928+
// - gpt-image-1: 1024x1024, 1536x1024, 1024x1536, or auto.
1929+
// Defaults to 1024x1024 (DALL-E 2/3) or auto (gpt-image-1).
1930+
Size string `json:"size,omitempty"`
1931+
// The style of the generated images. vivid or natural. DALL-E 3 only.
1932+
// Defaults to vivid.
1933+
Style string `json:"style,omitempty"`
1934+
// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
1935+
User string `json:"user,omitempty"`
1936+
// The output format of the image generation. Either png, webp, or jpeg.
1937+
// This parameter is only supported for gpt-image-1.
1938+
// Defaults to png.
1939+
OutputFormat string `json:"output_format,omitempty"`
1940+
// The background parameter used for the image generation. Either transparent, opaque, or auto.
1941+
// This parameter is only supported for gpt-image-1.
1942+
// Defaults to auto.
1943+
Background string `json:"background,omitempty"`
1944+
// Control the content-moderation level for images generated by gpt-image-1. Must be either low or auto.
1945+
// Defaults to auto.
1946+
Moderation string `json:"moderation,omitempty"`
1947+
// The compression level (0-100%) for the generated images.
1948+
// This parameter is only supported for gpt-image-1 with the webp or jpeg output formats.
1949+
// Defaults to 100.
1950+
OutputCompression *int `json:"output_compression,omitempty"`
1951+
// The number of partial images to generate.
1952+
// This parameter is used for streaming responses that return partial images. Value must be between 0 and 3.
1953+
// Defaults to 0.
1954+
PartialImages int `json:"partial_images,omitempty"`
1955+
// Generate the image in streaming mode.
1956+
// This parameter is only supported for gpt-image-1.
1957+
// Defaults to false.
1958+
Stream bool `json:"stream,omitempty"`
1959+
}
1960+
1961+
// ImageGenerationInputTokensDetails breakdown of tokens used in the prompt for image generation.
1962+
type ImageGenerationInputTokensDetails struct {
1963+
TextTokens int `json:"text_tokens,omitempty"`
1964+
ImageTokens int `json:"image_tokens,omitempty"`
1965+
}
1966+
1967+
// ImageGenerationUsage represents the usage information for image generation requests.
1968+
type ImageGenerationUsage struct {
1969+
TotalTokens int `json:"total_tokens"`
1970+
InputTokens int `json:"input_tokens"`
1971+
OutputTokens int `json:"output_tokens"`
1972+
InputTokensDetails *ImageGenerationInputTokensDetails `json:"input_tokens_details,omitempty"`
1973+
}
1974+
1975+
// ImageGenerationResponse represents the response body for /v1/images/generations.
1976+
// https://platform.openai.com/docs/api-reference/images/object
1977+
type ImageGenerationResponse struct {
1978+
// The Unix timestamp (in seconds) of when the image was created.
1979+
Created int64 `json:"created"`
1980+
// The list of generated images.
1981+
Data []ImageGenerationResponseData `json:"data"`
1982+
// For gpt-image-1 only, the token usage information for the image generation.
1983+
Usage *ImageGenerationUsage `json:"usage,omitempty"`
1984+
// The output format of the image generation. Either png, webp, or jpeg.
1985+
OutputFormat string `json:"output_format,omitempty"`
1986+
// The quality of the image generated. Either low, medium, or high.
1987+
Quality string `json:"quality,omitempty"`
1988+
// The size of the image generated. Either 1024x1024, 1024x1536, or 1536x1024.
1989+
Size string `json:"size,omitempty"`
1990+
// The background parameter used for the image generation. Either transparent or opaque.
1991+
Background string `json:"background,omitempty"`
1992+
}
1993+
1994+
type ImageGenerationResponseData struct {
1995+
B64JSON string `json:"b64_json,omitempty"`
1996+
URL string `json:"url,omitempty"`
1997+
RevisedPrompt string `json:"revised_prompt,omitempty"`
1998+
}

internal/endpointspec/endpointspec.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"encoding/json"
1212
"fmt"
1313

14-
openaisdk "github.com/openai/openai-go/v2"
1514
"github.com/tidwall/sjson"
1615

1716
"github.com/envoyproxy/ai-gateway/internal/apischema/anthropic"
@@ -173,8 +172,8 @@ func (EmbeddingsEndpointSpec) GetTranslator(schema filterapi.VersionedAPISchema,
173172
func (ImageGenerationEndpointSpec) ParseBody(
174173
body []byte,
175174
_ bool,
176-
) (internalapi.OriginalModel, *openaisdk.ImageGenerateParams, bool, []byte, error) {
177-
var openAIReq openaisdk.ImageGenerateParams
175+
) (internalapi.OriginalModel, *openai.ImageGenerationRequest, bool, []byte, error) {
176+
var openAIReq openai.ImageGenerationRequest
178177
if err := json.Unmarshal(body, &openAIReq); err != nil {
179178
return "", nil, false, nil, fmt.Errorf("failed to unmarshal image generation request: %w", err)
180179
}

internal/tracing/api/api.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ package api
1010
import (
1111
"context"
1212

13-
openaisdk "github.com/openai/openai-go/v2"
1413
"go.opentelemetry.io/otel/propagation"
1514
"go.opentelemetry.io/otel/trace"
1615

@@ -61,7 +60,7 @@ type (
6160
// EmbeddingsTracer creates spans for OpenAI embeddings requests.
6261
EmbeddingsTracer = RequestTracer[openai.EmbeddingRequest, openai.EmbeddingResponse, struct{}]
6362
// ImageGenerationTracer creates spans for OpenAI image generation requests.
64-
ImageGenerationTracer = RequestTracer[openaisdk.ImageGenerateParams, openaisdk.ImagesResponse, struct{}]
63+
ImageGenerationTracer = RequestTracer[openai.ImageGenerationRequest, openai.ImageGenerationResponse, struct{}]
6564
// RerankTracer creates spans for rerank requests.
6665
RerankTracer = RequestTracer[cohere.RerankV2Request, cohere.RerankV2Response, struct{}]
6766
// MessageTracer creates spans for Anthropic messages requests.
@@ -88,7 +87,7 @@ type (
8887
// EmbeddingsSpan represents an OpenAI embeddings request. The chunk type is unused and therefore set to struct{}.
8988
EmbeddingsSpan = Span[openai.EmbeddingResponse, struct{}]
9089
// ImageGenerationSpan represents an OpenAI image generation.
91-
ImageGenerationSpan = Span[openaisdk.ImagesResponse, struct{}]
90+
ImageGenerationSpan = Span[openai.ImageGenerationResponse, struct{}]
9291
// RerankSpan represents a rerank request span.
9392
RerankSpan = Span[cohere.RerankV2Response, struct{}]
9493
// MessageSpan represents an Anthropic messages request span.
@@ -127,7 +126,7 @@ type (
127126
// Note: Completion streaming chunks are full CompletionResponse objects, not deltas like chat completions.
128127
CompletionRecorder = SpanRecorder[openai.CompletionRequest, openai.CompletionResponse, openai.CompletionResponse]
129128
// ImageGenerationRecorder records attributes to a span according to a semantic convention.
130-
ImageGenerationRecorder = SpanRecorder[openaisdk.ImageGenerateParams, openaisdk.ImagesResponse, struct{}]
129+
ImageGenerationRecorder = SpanRecorder[openai.ImageGenerationRequest, openai.ImageGenerationResponse, struct{}]
131130
// EmbeddingsRecorder records attributes to a span according to a semantic convention.
132131
EmbeddingsRecorder = SpanRecorder[openai.EmbeddingRequest, openai.EmbeddingResponse, struct{}]
133132
// RerankRecorder records attributes to a span according to a semantic convention.
@@ -193,7 +192,7 @@ type (
193192
// NoopEmbeddingsTracer implements EmbeddingsTracer.
194193
NoopEmbeddingsTracer = NoopTracer[openai.EmbeddingRequest, openai.EmbeddingResponse, struct{}]
195194
// NoopImageGenerationTracer implements ImageGenerationTracer.
196-
NoopImageGenerationTracer = NoopTracer[openaisdk.ImageGenerateParams, openaisdk.ImagesResponse, struct{}]
195+
NoopImageGenerationTracer = NoopTracer[openai.ImageGenerationRequest, openai.ImageGenerationResponse, struct{}]
197196
// NoopRerankTracer implements RerankTracer.
198197
NoopRerankTracer = NoopTracer[cohere.RerankV2Request, cohere.RerankV2Response, struct{}]
199198
// NoopMessageTracer implements MessageTracer.

internal/tracing/openinference/openai/image_generation.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ package openai
1010
import (
1111
"encoding/json"
1212

13-
openaisdk "github.com/openai/openai-go/v2"
1413
"go.opentelemetry.io/otel/attribute"
1514
"go.opentelemetry.io/otel/codes"
1615
"go.opentelemetry.io/otel/trace"
1716

17+
"github.com/envoyproxy/ai-gateway/internal/apischema/openai"
1818
tracing "github.com/envoyproxy/ai-gateway/internal/tracing/api"
1919
"github.com/envoyproxy/ai-gateway/internal/tracing/openinference"
2020
)
@@ -52,17 +52,17 @@ func NewImageGenerationRecorder(config *openinference.TraceConfig) tracing.Image
5252
var imageGenStartOpts = []trace.SpanStartOption{trace.WithSpanKind(trace.SpanKindInternal)}
5353

5454
// StartParams implements the same method as defined in tracing.ImageGenerationRecorder.
55-
func (r *ImageGenerationRecorder) StartParams(*openaisdk.ImageGenerateParams, []byte) (spanName string, opts []trace.SpanStartOption) {
55+
func (r *ImageGenerationRecorder) StartParams(*openai.ImageGenerationRequest, []byte) (spanName string, opts []trace.SpanStartOption) {
5656
return "ImagesResponse", imageGenStartOpts
5757
}
5858

5959
// RecordRequest implements the same method as defined in tracing.ImageGenerationRecorder.
60-
func (r *ImageGenerationRecorder) RecordRequest(span trace.Span, req *openaisdk.ImageGenerateParams, body []byte) {
60+
func (r *ImageGenerationRecorder) RecordRequest(span trace.Span, req *openai.ImageGenerationRequest, body []byte) {
6161
span.SetAttributes(buildImageGenerationRequestAttributes(req, string(body), r.traceConfig)...)
6262
}
6363

6464
// RecordResponse implements the same method as defined in tracing.ImageGenerationRecorder.
65-
func (r *ImageGenerationRecorder) RecordResponse(span trace.Span, resp *openaisdk.ImagesResponse) {
65+
func (r *ImageGenerationRecorder) RecordResponse(span trace.Span, resp *openai.ImageGenerationResponse) {
6666
// Set output attributes.
6767
var attrs []attribute.KeyValue
6868
bodyString := openinference.RedactedValue
@@ -85,7 +85,7 @@ func (r *ImageGenerationRecorder) RecordResponseOnError(span trace.Span, statusC
8585
}
8686

8787
// buildImageGenerationRequestAttributes builds OpenInference attributes from the image generation request.
88-
func buildImageGenerationRequestAttributes(_ *openaisdk.ImageGenerateParams, body string, config *openinference.TraceConfig) []attribute.KeyValue {
88+
func buildImageGenerationRequestAttributes(_ *openai.ImageGenerationRequest, body string, config *openinference.TraceConfig) []attribute.KeyValue {
8989
attrs := []attribute.KeyValue{
9090
attribute.String(openinference.SpanKind, openinference.SpanKindLLM),
9191
attribute.String(openinference.LLMSystem, openinference.LLMSystemOpenAI),

internal/tracing/openinference/openai/image_generation_config_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ package openai
88
import (
99
"testing"
1010

11-
openaisdk "github.com/openai/openai-go/v2"
1211
"github.com/stretchr/testify/require"
1312
"go.opentelemetry.io/otel/attribute"
1413
"go.opentelemetry.io/otel/codes"
1514
"go.opentelemetry.io/otel/sdk/trace"
1615
oteltrace "go.opentelemetry.io/otel/trace"
1716

17+
"github.com/envoyproxy/ai-gateway/internal/apischema/openai"
1818
"github.com/envoyproxy/ai-gateway/internal/testing/testotel"
1919
"github.com/envoyproxy/ai-gateway/internal/tracing/openinference"
2020
)
@@ -23,7 +23,7 @@ func TestImageGenerationRecorder_WithConfig_HideInputs(t *testing.T) {
2323
tests := []struct {
2424
name string
2525
config *openinference.TraceConfig
26-
req *openaisdk.ImageGenerateParams
26+
req *openai.ImageGenerationRequest
2727
reqBody []byte
2828
expectedAttrs []attribute.KeyValue
2929
}{

internal/tracing/openinference/openai/image_generation_test.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,32 @@ package openai
88
import (
99
"testing"
1010

11-
openaisdk "github.com/openai/openai-go/v2"
12-
openaiparam "github.com/openai/openai-go/v2/packages/param"
1311
"github.com/stretchr/testify/require"
1412
"go.opentelemetry.io/otel/attribute"
1513
"go.opentelemetry.io/otel/codes"
1614
"go.opentelemetry.io/otel/sdk/trace"
1715
oteltrace "go.opentelemetry.io/otel/trace"
1816

17+
"github.com/envoyproxy/ai-gateway/internal/apischema/openai"
1918
"github.com/envoyproxy/ai-gateway/internal/testing/testotel"
2019
tracing "github.com/envoyproxy/ai-gateway/internal/tracing/api"
2120
"github.com/envoyproxy/ai-gateway/internal/tracing/openinference"
2221
)
2322

2423
var (
25-
basicImageReq = &openaisdk.ImageGenerateParams{
26-
Model: openaisdk.ImageModelGPTImage1,
24+
basicImageReq = &openai.ImageGenerationRequest{
25+
Model: "gpt-image-1",
2726
Prompt: "a hummingbird",
28-
Size: openaisdk.ImageGenerateParamsSize1024x1024,
29-
Quality: openaisdk.ImageGenerateParamsQualityHigh,
30-
ResponseFormat: openaisdk.ImageGenerateParamsResponseFormatB64JSON,
31-
N: openaiparam.NewOpt[int64](1),
27+
Size: "1024x1024",
28+
Quality: "hd",
29+
ResponseFormat: "b64_json",
30+
N: 1,
3231
}
3332
basicImageReqBody = mustJSON(basicImageReq)
3433

35-
basicImageResp = &openaisdk.ImagesResponse{
36-
Data: []openaisdk.Image{{URL: "https://example.com/img.png"}},
37-
Size: openaisdk.ImagesResponseSize1024x1024,
38-
Usage: openaisdk.ImagesResponseUsage{
34+
basicImageResp = &openai.ImageGenerationResponse{
35+
Data: []openai.ImageGenerationResponseData{{URL: "https://example.com/img.png"}},
36+
Usage: &openai.ImageGenerationUsage{
3937
InputTokens: 8,
4038
OutputTokens: 1056,
4139
TotalTokens: 1064,
@@ -47,7 +45,7 @@ var (
4745
func TestImageGenerationRecorder_StartParams(t *testing.T) {
4846
tests := []struct {
4947
name string
50-
req *openaisdk.ImageGenerateParams
48+
req *openai.ImageGenerationRequest
5149
reqBody []byte
5250
expectedSpanName string
5351
}{
@@ -75,7 +73,7 @@ func TestImageGenerationRecorder_StartParams(t *testing.T) {
7573
func TestImageGenerationRecorder_RecordRequest(t *testing.T) {
7674
tests := []struct {
7775
name string
78-
req *openaisdk.ImageGenerateParams
76+
req *openai.ImageGenerationRequest
7977
reqBody []byte
8078
config *openinference.TraceConfig
8179
expectedAttrs []attribute.KeyValue
@@ -138,7 +136,7 @@ func TestImageGenerationRecorder_RecordRequest(t *testing.T) {
138136
func TestImageGenerationRecorder_RecordResponse(t *testing.T) {
139137
tests := []struct {
140138
name string
141-
resp *openaisdk.ImagesResponse
139+
resp *openai.ImageGenerationResponse
142140
config *openinference.TraceConfig
143141
expectedAttrs []attribute.KeyValue
144142
expectedEvents []trace.Event

internal/tracing/span.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
package tracing
77

88
import (
9-
openaisdk "github.com/openai/openai-go/v2"
109
"go.opentelemetry.io/otel/trace"
1110

1211
anthropicschema "github.com/envoyproxy/ai-gateway/internal/apischema/anthropic"
@@ -50,7 +49,7 @@ type (
5049
chatCompletionSpan = span[openai.ChatCompletionResponse, openai.ChatCompletionResponseChunk]
5150
completionSpan = span[openai.CompletionResponse, openai.CompletionResponse]
5251
embeddingsSpan = span[openai.EmbeddingResponse, struct{}]
53-
imageGenerationSpan = span[openaisdk.ImagesResponse, struct{}]
52+
imageGenerationSpan = span[openai.ImageGenerationResponse, struct{}]
5453
rerankSpan = span[cohereschema.RerankV2Response, struct{}]
5554
messageSpan = span[anthropicschema.MessagesResponse, anthropicschema.MessagesStreamChunk]
5655
)

internal/tracing/tracer.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package tracing
88
import (
99
"context"
1010

11-
openaisdk "github.com/openai/openai-go/v2"
1211
"go.opentelemetry.io/otel/attribute"
1312
"go.opentelemetry.io/otel/propagation"
1413
"go.opentelemetry.io/otel/trace"
@@ -43,7 +42,7 @@ type (
4342
chatCompletionTracer = requestTracerImpl[openai.ChatCompletionRequest, openai.ChatCompletionResponse, openai.ChatCompletionResponseChunk]
4443
embeddingsTracer = requestTracerImpl[openai.EmbeddingRequest, openai.EmbeddingResponse, struct{}]
4544
completionTracer = requestTracerImpl[openai.CompletionRequest, openai.CompletionResponse, openai.CompletionResponse]
46-
imageGenerationTracer = requestTracerImpl[openaisdk.ImageGenerateParams, openaisdk.ImagesResponse, struct{}]
45+
imageGenerationTracer = requestTracerImpl[openai.ImageGenerationRequest, openai.ImageGenerationResponse, struct{}]
4746
rerankTracer = requestTracerImpl[cohereschema.RerankV2Request, cohereschema.RerankV2Response, struct{}]
4847
)
4948

internal/tracing/tracer_test.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"fmt"
1212
"testing"
1313

14-
openaisdk "github.com/openai/openai-go/v2"
1514
"github.com/stretchr/testify/require"
1615
"go.opentelemetry.io/contrib/propagators/autoprop"
1716
"go.opentelemetry.io/otel/attribute"
@@ -339,14 +338,14 @@ func TestNewImageGenerationTracer_BuildsGenericRequestTracer(t *testing.T) {
339338

340339
tracer := newImageGenerationTracer(tp.Tracer("test"), autoprop.NewTextMapPropagator(), testImageGenerationRecorder{})
341340
impl, ok := tracer.(*requestTracerImpl[
342-
openaisdk.ImageGenerateParams,
343-
openaisdk.ImagesResponse,
341+
openai.ImageGenerationRequest,
342+
openai.ImageGenerationResponse,
344343
struct{},
345344
])
346345
require.True(t, ok)
347346
require.Nil(t, impl.headerAttributes)
348347
require.NotNil(t, impl.newSpan)
349-
s := tracer.StartSpanAndInjectHeaders(context.Background(), nil, propagation.MapCarrier{}, &openaisdk.ImageGenerateParams{}, []byte("{}"))
348+
s := tracer.StartSpanAndInjectHeaders(context.Background(), nil, propagation.MapCarrier{}, &openai.ImageGenerationRequest{}, []byte("{}"))
350349
require.IsType(t, (*imageGenerationSpan)(nil), s)
351350
}
352351

@@ -448,19 +447,19 @@ type testImageGenerationRecorder struct {
448447
tracing.NoopChunkRecorder[struct{}]
449448
}
450449

451-
func (r testImageGenerationRecorder) StartParams(_ *openaisdk.ImageGenerateParams, _ []byte) (string, []oteltrace.SpanStartOption) {
450+
func (r testImageGenerationRecorder) StartParams(_ *openai.ImageGenerationRequest, _ []byte) (string, []oteltrace.SpanStartOption) {
452451
return "ImagesResponse", nil
453452
}
454453

455-
func (r testImageGenerationRecorder) RecordRequest(span oteltrace.Span, req *openaisdk.ImageGenerateParams, _ []byte) {
454+
func (r testImageGenerationRecorder) RecordRequest(span oteltrace.Span, req *openai.ImageGenerationRequest, _ []byte) {
456455
span.SetAttributes(
457456
attribute.String("model", req.Model),
458457
attribute.String("prompt", req.Prompt),
459-
attribute.String("size", string(req.Size)),
458+
attribute.String("size", req.Size),
460459
)
461460
}
462461

463-
func (r testImageGenerationRecorder) RecordResponse(span oteltrace.Span, resp *openaisdk.ImagesResponse) {
462+
func (r testImageGenerationRecorder) RecordResponse(span oteltrace.Span, resp *openai.ImageGenerationResponse) {
464463
respBytes, _ := json.Marshal(resp)
465464
span.SetAttributes(
466465
attribute.Int("statusCode", 200),

0 commit comments

Comments
 (0)