MergeOpenResponsesConfig merges request parameters into the model configuration.
(config *config.ModelConfig, input *schema.OpenResponsesRequest)
| 693 | |
| 694 | // MergeOpenResponsesConfig merges request parameters into the model configuration. |
| 695 | func MergeOpenResponsesConfig(config *config.ModelConfig, input *schema.OpenResponsesRequest) error { |
| 696 | // Temperature |
| 697 | if input.Temperature != nil { |
| 698 | config.Temperature = input.Temperature |
| 699 | } |
| 700 | |
| 701 | // TopP |
| 702 | if input.TopP != nil { |
| 703 | config.TopP = input.TopP |
| 704 | } |
| 705 | |
| 706 | // MaxOutputTokens -> Maxtokens |
| 707 | if input.MaxOutputTokens != nil { |
| 708 | config.Maxtokens = input.MaxOutputTokens |
| 709 | } |
| 710 | |
| 711 | // Convert tools to functions - this will be handled in the endpoint handler |
| 712 | // We just validate that tools are present if needed |
| 713 | |
| 714 | // Handle tool_choice |
| 715 | if input.ToolChoice != nil { |
| 716 | switch tc := input.ToolChoice.(type) { |
| 717 | case string: |
| 718 | // "auto", "required", or "none" |
| 719 | if tc == "required" { |
| 720 | config.SetFunctionCallString("required") |
| 721 | } else if tc == "none" { |
| 722 | // Don't use tools - handled in endpoint |
| 723 | } |
| 724 | // "auto" is default - let model decide |
| 725 | case map[string]any: |
| 726 | // Specific tool. OpenAI spec nests the function name under "function": |
| 727 | // {"type":"function", "function":{"name":"..."}} |
| 728 | // Legacy/Anthropic-compat form puts it at the top level: |
| 729 | // {"type":"function", "name":"..."} |
| 730 | // The old code only handled the legacy shape AND used the wrong |
| 731 | // setter (SetFunctionCallString writes the mode field; the |
| 732 | // specific-function name lives in a separate field read by |
| 733 | // ShouldCallSpecificFunction / FunctionToCall). Net effect: a |
| 734 | // correctly-formed OpenAI tool_choice never engaged grammar-based |
| 735 | // forcing, the model got the tools but no selection hint, and |
| 736 | // streamed raw JSON as delta.content instead of delta.tool_calls. |
| 737 | if tcType, ok := tc["type"].(string); ok && tcType == "function" { |
| 738 | var name string |
| 739 | if fn, ok := tc["function"].(map[string]any); ok { |
| 740 | if n, ok := fn["name"].(string); ok { |
| 741 | name = n |
| 742 | } |
| 743 | } |
| 744 | if name == "" { |
| 745 | if n, ok := tc["name"].(string); ok { |
| 746 | name = n |
| 747 | } |
| 748 | } |
| 749 | if name != "" { |
| 750 | config.SetFunctionCallNameString(name) |
| 751 | } |
| 752 | } |
no test coverage detected