109 lines
3.8 KiB
Go
109 lines
3.8 KiB
Go
package clients
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"sort"
|
|
)
|
|
|
|
// Keep these lists aligned with openai-node 6.47.0 and the public OpenAI API
|
|
// reference. The Gateway accepts a small, explicit set of routing extensions at
|
|
// ingress, but only protocol fields (plus controlled provider adaptations) are
|
|
// allowed across the upstream boundary.
|
|
var openAIChatRequestParameters = stringSet(
|
|
"messages", "model", "audio", "frequency_penalty", "function_call", "functions",
|
|
"logit_bias", "logprobs", "max_completion_tokens", "max_tokens", "metadata",
|
|
"modalities", "moderation", "n", "parallel_tool_calls", "prediction",
|
|
"presence_penalty", "prompt_cache_key", "prompt_cache_options", "prompt_cache_retention",
|
|
"reasoning_effort", "response_format", "safety_identifier", "seed", "service_tier",
|
|
"stop", "store", "stream", "stream_options", "temperature", "tool_choice", "tools",
|
|
"top_logprobs", "top_p", "user", "verbosity", "web_search_options",
|
|
)
|
|
|
|
var openAIResponsesRequestParameters = stringSet(
|
|
"background", "context_management", "conversation", "include", "input", "instructions",
|
|
"max_output_tokens", "max_tool_calls", "metadata", "model", "moderation",
|
|
"parallel_tool_calls", "previous_response_id", "prompt", "prompt_cache_key",
|
|
"prompt_cache_options", "prompt_cache_retention", "reasoning", "safety_identifier",
|
|
"service_tier", "store", "stream", "stream_options", "temperature", "text",
|
|
"tool_choice", "tools", "top_logprobs", "top_p", "truncation", "user",
|
|
)
|
|
|
|
var gatewayOpenAIRequestExtensions = stringSet(
|
|
"runMode", "run_mode", "conversationId", "conversation_id", "sessionId", "session_id",
|
|
"requestId", "request_id", "signal", "userMessage", "user_message", "platformId",
|
|
"platform_id", "options", "enable_thinking", "thinking_budget_tokens", "enable_web_search",
|
|
"modelType", "model_type", "capability", "capabilityType", "mode", "simulation", "testMode",
|
|
)
|
|
|
|
var gatewayResponsesRequestExtensions = stringSet("messages", "presence_penalty", "frequency_penalty")
|
|
|
|
var controlledOpenAIChatProviderParameters = stringSet(
|
|
"enable_thinking", "thinking_budget", "thinking", "enable_web_search",
|
|
)
|
|
|
|
var controlledOpenAIResponsesProviderParameters = stringSet("presence_penalty", "frequency_penalty")
|
|
|
|
func ValidateOpenAIRequestParameters(kind string, body map[string]any) error {
|
|
allowed := openAIChatRequestParameters
|
|
if kind == "responses" {
|
|
allowed = openAIResponsesRequestParameters
|
|
}
|
|
unknown := make([]string, 0)
|
|
for key := range body {
|
|
if _, ok := allowed[key]; ok {
|
|
continue
|
|
}
|
|
if _, ok := gatewayOpenAIRequestExtensions[key]; ok {
|
|
continue
|
|
}
|
|
if kind == "responses" {
|
|
if _, ok := gatewayResponsesRequestExtensions[key]; ok {
|
|
continue
|
|
}
|
|
}
|
|
unknown = append(unknown, key)
|
|
}
|
|
if len(unknown) == 0 {
|
|
return nil
|
|
}
|
|
sort.Strings(unknown)
|
|
return &ClientError{
|
|
Code: "invalid_parameter",
|
|
Message: fmt.Sprintf("Unknown parameter: %s", unknown[0]),
|
|
Param: unknown[0],
|
|
StatusCode: http.StatusBadRequest,
|
|
Retryable: false,
|
|
}
|
|
}
|
|
|
|
func FilterOpenAIChatRequestBody(body map[string]any) map[string]any {
|
|
return filterOpenAIRequestBody(body, openAIChatRequestParameters, controlledOpenAIChatProviderParameters)
|
|
}
|
|
|
|
func FilterOpenAIResponsesRequestBody(body map[string]any) map[string]any {
|
|
return filterOpenAIRequestBody(body, openAIResponsesRequestParameters, controlledOpenAIResponsesProviderParameters)
|
|
}
|
|
|
|
func filterOpenAIRequestBody(body map[string]any, allowed map[string]struct{}, extensions map[string]struct{}) map[string]any {
|
|
out := make(map[string]any, len(body))
|
|
for key, value := range body {
|
|
if _, ok := allowed[key]; ok {
|
|
out[key] = value
|
|
continue
|
|
}
|
|
if _, ok := extensions[key]; ok {
|
|
out[key] = value
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func stringSet(values ...string) map[string]struct{} {
|
|
out := make(map[string]struct{}, len(values))
|
|
for _, value := range values {
|
|
out[value] = struct{}{}
|
|
}
|
|
return out
|
|
}
|