fix: normalize model name in TranslateRequest fallback to prevent prefix leak

When no request translator is registered for a format pair (e.g.
        openai-response → openai-response), TranslateRequest returned the raw
        payload unchanged. This caused client-side model prefixes (e.g.
        "copilot/gpt-5-mini") to leak into upstream requests, resulting in
        "The requested model is not supported" errors from providers.

        The fallback path now updates the "model" field in the payload to
        match the resolved model name before returning.
This commit is contained in:
Longwu Ou
2026-03-18 12:30:22 -04:00
parent db63f9b5d6
commit e1e9fc43c1

View File

@@ -3,6 +3,9 @@ package translator
import (
"context"
"sync"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
// Registry manages translation functions across schemas.
@@ -39,7 +42,9 @@ func (r *Registry) Register(from, to Format, request RequestTransform, response
}
// TranslateRequest converts a payload between schemas, returning the original payload
// if no translator is registered.
// if no translator is registered. When falling back to the original payload, the
// "model" field is still updated to match the resolved model name so that
// client-side prefixes (e.g. "copilot/gpt-5-mini") are not leaked upstream.
func (r *Registry) TranslateRequest(from, to Format, model string, rawJSON []byte, stream bool) []byte {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -49,6 +54,11 @@ func (r *Registry) TranslateRequest(from, to Format, model string, rawJSON []byt
return fn(model, rawJSON, stream)
}
}
if model != "" && gjson.GetBytes(rawJSON, "model").String() != model {
if updated, err := sjson.SetBytes(rawJSON, "model", model); err == nil {
return updated
}
}
return rawJSON
}