|
|
|
@ -34,10 +34,12 @@ type ErrorResponse struct { |
|
|
|
} |
|
|
|
|
|
|
|
type Message struct { |
|
|
|
Role string `json:"role"` |
|
|
|
Content any `json:"content"` |
|
|
|
Reasoning string `json:"reasoning,omitempty"` |
|
|
|
ToolCalls []ToolCall `json:"tool_calls,omitempty"` |
|
|
|
Role string `json:"role"` |
|
|
|
Content any `json:"content"` |
|
|
|
Reasoning string `json:"reasoning,omitempty"` |
|
|
|
ToolCalls []ToolCall `json:"tool_calls,omitempty"` |
|
|
|
Name string `json:"name,omitempty"` |
|
|
|
ToolCallID string `json:"tool_call_id,omitempty"` |
|
|
|
} |
|
|
|
|
|
|
|
type Choice struct { |
|
|
|
@ -401,13 +403,20 @@ func toModel(r api.ShowResponse, m string) Model { |
|
|
|
func fromChatRequest(r ChatCompletionRequest) (*api.ChatRequest, error) { |
|
|
|
var messages []api.Message |
|
|
|
for _, msg := range r.Messages { |
|
|
|
toolName := "" |
|
|
|
if strings.ToLower(msg.Role) == "tool" { |
|
|
|
toolName = msg.Name |
|
|
|
if toolName == "" && msg.ToolCallID != "" { |
|
|
|
toolName = nameFromToolCallID(r.Messages, msg.ToolCallID) |
|
|
|
} |
|
|
|
} |
|
|
|
switch content := msg.Content.(type) { |
|
|
|
case string: |
|
|
|
toolCalls, err := fromCompletionToolCall(msg.ToolCalls) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
messages = append(messages, api.Message{Role: msg.Role, Content: content, Thinking: msg.Reasoning, ToolCalls: toolCalls}) |
|
|
|
messages = append(messages, api.Message{Role: msg.Role, Content: content, Thinking: msg.Reasoning, ToolCalls: toolCalls, ToolName: toolName}) |
|
|
|
case []any: |
|
|
|
for _, c := range content { |
|
|
|
data, ok := c.(map[string]any) |
|
|
|
@ -466,6 +475,9 @@ func fromChatRequest(r ChatCompletionRequest) (*api.ChatRequest, error) { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
messages[len(messages)-1].ToolCalls = toolCalls |
|
|
|
if toolName != "" { |
|
|
|
messages[len(messages)-1].ToolName = toolName |
|
|
|
} |
|
|
|
} |
|
|
|
default: |
|
|
|
// content is only optional if tool calls are present
|
|
|
|
@ -563,6 +575,20 @@ func fromChatRequest(r ChatCompletionRequest) (*api.ChatRequest, error) { |
|
|
|
}, nil |
|
|
|
} |
|
|
|
|
|
|
|
func nameFromToolCallID(messages []Message, toolCallID string) string { |
|
|
|
// iterate backwards to be more resilient to duplicate tool call IDs (this
|
|
|
|
// follows "last one wins")
|
|
|
|
for i := len(messages) - 1; i >= 0; i-- { |
|
|
|
msg := messages[i] |
|
|
|
for _, tc := range msg.ToolCalls { |
|
|
|
if tc.ID == toolCallID { |
|
|
|
return tc.Function.Name |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return "" |
|
|
|
} |
|
|
|
|
|
|
|
func fromCompletionToolCall(toolCalls []ToolCall) ([]api.ToolCall, error) { |
|
|
|
apiToolCalls := make([]api.ToolCall, len(toolCalls)) |
|
|
|
for i, tc := range toolCalls { |
|
|
|
|