Pulse/internal/ai/chat/tools.go
rcourtman 900e05025a Fix OpenAI-compatible endpoint support for chat
Two issues fixed:

1. Custom base URL wasn't being passed to the OpenAI client in
   createProviderForModel() - requests went to api.openai.com instead
   of the configured endpoint (e.g., LM Studio, llama.cpp)

2. Tool schemas were missing the "properties" field when tools had no
   parameters. OpenAI API requires "properties" to always be present
   as an object, even if empty.

Fixes #1154
2026-02-03 12:03:06 +00:00

78 lines
1.9 KiB
Go

package chat
import (
"github.com/rcourtman/pulse-go-rewrite/internal/ai/providers"
"github.com/rcourtman/pulse-go-rewrite/internal/ai/tools"
)
// ConvertMCPToolsToProvider converts MCP tool definitions to provider tool format
func ConvertMCPToolsToProvider(mcpTools []tools.Tool) []providers.Tool {
result := make([]providers.Tool, 0, len(mcpTools))
for _, t := range mcpTools {
// Build the input schema in the format expected by providers
inputSchema := make(map[string]interface{})
inputSchema["type"] = "object"
// Convert properties - always include "properties" even if empty
// OpenAI API requires "properties" to be present as an object
props := make(map[string]interface{})
for name, prop := range t.InputSchema.Properties {
propDef := map[string]interface{}{
"type": prop.Type,
}
if prop.Description != "" {
propDef["description"] = prop.Description
}
if len(prop.Enum) > 0 {
propDef["enum"] = prop.Enum
}
if prop.Default != nil {
propDef["default"] = prop.Default
}
props[name] = propDef
}
inputSchema["properties"] = props
// Add required fields
if len(t.InputSchema.Required) > 0 {
inputSchema["required"] = t.InputSchema.Required
}
result = append(result, providers.Tool{
Name: t.Name,
Description: t.Description,
InputSchema: inputSchema,
})
}
return result
}
// ConvertProviderToolCallToMCP converts a provider tool call to MCP format
func ConvertProviderToolCallToMCP(tc providers.ToolCall) tools.CallToolParams {
return tools.CallToolParams{
Name: tc.Name,
Arguments: tc.Input,
}
}
// FormatToolResult formats a tool result for display
func FormatToolResult(result tools.CallToolResult) string {
if len(result.Content) == 0 {
return ""
}
// Combine all text content
var text string
for _, c := range result.Content {
if c.Type == "text" && c.Text != "" {
if text != "" {
text += "\n"
}
text += c.Text
}
}
return text
}