Skip to content

Commit 8d1d7be

Browse files
extproc: implement image generation processor and tests
Signed-off-by: Hrushikesh Patil <[email protected]>
1 parent ec5b634 commit 8d1d7be

File tree

2 files changed

+13
-15
lines changed

2 files changed

+13
-15
lines changed

internal/extproc/imagegeneration_processor.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ func (i *imageGenerationProcessorRouterFilter) ProcessRequestBody(ctx context.Co
112112
// OpenAI SDK doesn't expose a generic Stream flag for image generation; keep false for now.
113113
isStreamingRequest := false
114114

115-
i.requestHeaders[i.config.modelNameHeaderKey] = model
115+
i.requestHeaders[internalapi.ModelNameHeaderKeyDefault] = model
116116

117117
var additionalHeaders []*corev3.HeaderValueOption
118118
additionalHeaders = append(additionalHeaders, &corev3.HeaderValueOption{
119119
// Set the model name to the request header with the key `x-ai-eg-model`.
120-
Header: &corev3.HeaderValue{Key: i.config.modelNameHeaderKey, RawValue: []byte(model)},
120+
Header: &corev3.HeaderValue{Key: internalapi.ModelNameHeaderKeyDefault, RawValue: []byte(model)},
121121
}, &corev3.HeaderValueOption{
122122
Header: &corev3.HeaderValue{Key: originalPathHeader, RawValue: []byte(i.requestHeaders[":path"])},
123123
})
@@ -217,7 +217,7 @@ func (i *imageGenerationProcessorUpstreamFilter) ProcessRequestHeaders(ctx conte
217217
// Set the original model from the request body before any overrides
218218
i.metrics.SetOriginalModel(i.originalRequestBody.Model)
219219
// Set the request model for metrics from the original model or override if applied.
220-
reqModel := cmp.Or(i.requestHeaders[i.config.modelNameHeaderKey], i.originalRequestBody.Model)
220+
reqModel := cmp.Or(i.requestHeaders[internalapi.ModelNameHeaderKeyDefault], i.originalRequestBody.Model)
221221
i.metrics.SetRequestModel(reqModel)
222222
i.metrics.SetResponseModel(reqModel)
223223

@@ -252,7 +252,7 @@ func (i *imageGenerationProcessorUpstreamFilter) ProcessRequestHeaders(ctx conte
252252

253253
var dm *structpb.Struct
254254
if bm := bodyMutation.GetBody(); bm != nil {
255-
dm = buildContentLengthDynamicMetadataOnRequest(i.config, len(bm))
255+
dm = buildContentLengthDynamicMetadataOnRequest(len(bm))
256256
}
257257
return &extprocv3.ProcessingResponse{
258258
Response: &extprocv3.ProcessingResponse_RequestHeaders{
@@ -471,7 +471,7 @@ func (i *imageGenerationProcessorUpstreamFilter) SetBackend(ctx context.Context,
471471
i.headerMutator = headermutator.NewHeaderMutator(b.HeaderMutation, rp.requestHeaders)
472472
// Sync header with backend model so header-derived labels/CEL use the actual model.
473473
if i.modelNameOverride != "" {
474-
i.requestHeaders[i.config.modelNameHeaderKey] = i.modelNameOverride
474+
i.requestHeaders[internalapi.ModelNameHeaderKeyDefault] = i.modelNameOverride
475475
// Update metrics with the overridden model
476476
i.metrics.SetRequestModel(i.modelNameOverride)
477477
}

internal/extproc/imagegeneration_processor_test.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/envoyproxy/ai-gateway/internal/extproc/translator"
2222
"github.com/envoyproxy/ai-gateway/internal/filterapi"
23+
"github.com/envoyproxy/ai-gateway/internal/internalapi"
2324
"github.com/envoyproxy/ai-gateway/internal/llmcostcel"
2425
tracing "github.com/envoyproxy/ai-gateway/internal/tracing/api"
2526
)
@@ -110,7 +111,7 @@ func Test_imageGenerationProcessorRouterFilter_ProcessRequestBody(t *testing.T)
110111
headers := map[string]string{":path": "/v1/images/generations"}
111112
const modelKey = "x-ai-gateway-model-key"
112113
p := &imageGenerationProcessorRouterFilter{
113-
config: &processorConfig{modelNameHeaderKey: modelKey},
114+
config: &processorConfig{},
114115
requestHeaders: headers,
115116
logger: slog.Default(),
116117
tracer: tracing.NoopTracing{}.ImageGenerationTracer(),
@@ -133,12 +134,11 @@ func Test_imageGenerationProcessorRouterFilter_ProcessRequestBody(t *testing.T)
133134

134135
t.Run("span creation", func(t *testing.T) {
135136
headers := map[string]string{":path": "/v1/images/generations"}
136-
const modelKey = "x-ai-gateway-model-key"
137137
span := &mockImageGenerationSpan{}
138138
mockTracerInstance := &mockImageGenerationTracer{returnedSpan: span}
139139

140140
p := &imageGenerationProcessorRouterFilter{
141-
config: &processorConfig{modelNameHeaderKey: modelKey},
141+
config: &processorConfig{},
142142
requestHeaders: headers,
143143
logger: slog.Default(),
144144
tracer: mockTracerInstance,
@@ -233,8 +233,6 @@ func Test_imageGenerationProcessorUpstreamFilter_ProcessResponseBody(t *testing.
233233
logger: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})),
234234
metrics: mm,
235235
config: &processorConfig{
236-
metadataNamespace: "ai_gateway_llm_ns",
237-
modelNameHeaderKey: "x-aigw-model",
238236
requestCosts: []processorConfigRequestCost{
239237
{LLMRequestCost: &filterapi.LLMRequestCost{Type: filterapi.LLMRequestCostTypeOutputToken, MetadataKey: "output_token_usage"}},
240238
{LLMRequestCost: &filterapi.LLMRequestCost{Type: filterapi.LLMRequestCostTypeInputToken, MetadataKey: "input_token_usage"}},
@@ -299,12 +297,12 @@ func Test_imageGenerationProcessorUpstreamFilter_ProcessResponseBody(t *testing.
299297

300298
func Test_imageGenerationProcessorUpstreamFilter_ProcessRequestHeaders(t *testing.T) {
301299
t.Run("ok with auth handler and header mutator", func(t *testing.T) {
302-
headers := map[string]string{":path": "/v1/images/generations", "x-model": "dall-e-3"}
300+
headers := map[string]string{":path": "/v1/images/generations", internalapi.ModelNameHeaderKeyDefault: "dall-e-3"}
303301
mm := &mockImageGenerationMetrics{}
304302
body := &openaisdk.ImageGenerateParams{Model: openaisdk.ImageModel("dall-e-3"), Prompt: "a cat"}
305303
mt := &mockImageGenerationTranslator{t: t, expRequestBody: body}
306304
p := &imageGenerationProcessorUpstreamFilter{
307-
config: &processorConfig{modelNameHeaderKey: "x-model"},
305+
config: &processorConfig{},
308306
requestHeaders: headers,
309307
logger: slog.Default(),
310308
metrics: mm,
@@ -344,8 +342,8 @@ func Test_imageGenerationProcessorUpstreamFilter_SetBackend(t *testing.T) {
344342
// Supported OpenAI schema.
345343
rp := &imageGenerationProcessorRouterFilter{originalRequestBody: &openaisdk.ImageGenerateParams{}}
346344
p2 := &imageGenerationProcessorUpstreamFilter{
347-
config: &processorConfig{modelNameHeaderKey: "x-model-name"},
348-
requestHeaders: map[string]string{"x-model-name": "dall-e-2"},
345+
config: &processorConfig{},
346+
requestHeaders: map[string]string{internalapi.ModelNameHeaderKeyDefault: "dall-e-2"},
349347
logger: slog.Default(),
350348
metrics: &mockImageGenerationMetrics{},
351349
}
@@ -355,7 +353,7 @@ func Test_imageGenerationProcessorUpstreamFilter_SetBackend(t *testing.T) {
355353
ModelNameOverride: "gpt-image-1",
356354
}, nil, rp)
357355
require.NoError(t, err)
358-
require.Equal(t, "gpt-image-1", p2.requestHeaders["x-model-name"])
356+
require.Equal(t, "gpt-image-1", p2.requestHeaders[internalapi.ModelNameHeaderKeyDefault])
359357
}
360358

361359
func TestImageGeneration_ParseBody(t *testing.T) {

0 commit comments

Comments
 (0)