Add support for integers and tool configuration in schema handling
This update introduces support for `jsonschema.Integer` types and updates the logic to handle nested items in schemas. Added a new default error log for unknown types using `slog.Error`. Also, integrated tool configuration with a `FunctionCallingConfig` when `dontRequireTool` is false.
This commit is contained in:
150
llm.go
150
llm.go
@@ -3,8 +3,10 @@ package go_llm
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/sashabaranov/go-openai"
|
||||
"github.com/openai/openai-go"
|
||||
"github.com/openai/openai-go/packages/param"
|
||||
)
|
||||
|
||||
type Role string
|
||||
@@ -82,41 +84,111 @@ func (m *Message) fromRaw(raw map[string]any) Message {
|
||||
return res
|
||||
}
|
||||
|
||||
func (m Message) toChatCompletionMessages() []openai.ChatCompletionMessage {
|
||||
var res openai.ChatCompletionMessage
|
||||
func (m Message) toChatCompletionMessages(model string) []openai.ChatCompletionMessageParamUnion {
|
||||
var res openai.ChatCompletionMessageParamUnion
|
||||
|
||||
res.Role = string(m.Role)
|
||||
res.Name = m.Name
|
||||
res.Content = m.Text
|
||||
var arrayOfContentParts []openai.ChatCompletionContentPartUnionParam
|
||||
var textContent param.Opt[string]
|
||||
|
||||
for _, img := range m.Images {
|
||||
if img.Base64 != "" {
|
||||
res.MultiContent = append(res.MultiContent, openai.ChatMessagePart{
|
||||
Type: "image_url",
|
||||
ImageURL: &openai.ChatMessageImageURL{
|
||||
URL: "data:" + img.ContentType + ";base64," + img.Base64,
|
||||
arrayOfContentParts = append(arrayOfContentParts,
|
||||
openai.ChatCompletionContentPartUnionParam{
|
||||
OfImageURL: &openai.ChatCompletionContentPartImageParam{
|
||||
ImageURL: openai.ChatCompletionContentPartImageImageURLParam{
|
||||
URL: "data:" + img.ContentType + ";base64," + img.Base64,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
} else if img.Url != "" {
|
||||
res.MultiContent = append(res.MultiContent, openai.ChatMessagePart{
|
||||
Type: "image_url",
|
||||
ImageURL: &openai.ChatMessageImageURL{
|
||||
URL: img.Url,
|
||||
arrayOfContentParts = append(arrayOfContentParts,
|
||||
openai.ChatCompletionContentPartUnionParam{
|
||||
OfImageURL: &openai.ChatCompletionContentPartImageParam{
|
||||
ImageURL: openai.ChatCompletionContentPartImageImageURLParam{
|
||||
URL: img.Url,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// openai does not support messages with both content and multi-content
|
||||
if len(res.MultiContent) > 0 && res.Content != "" {
|
||||
res.MultiContent = append([]openai.ChatMessagePart{{
|
||||
Type: "text",
|
||||
Text: res.Content,
|
||||
}}, res.MultiContent...)
|
||||
res.Content = ""
|
||||
if m.Text != "" {
|
||||
if len(arrayOfContentParts) > 0 {
|
||||
arrayOfContentParts = append(arrayOfContentParts,
|
||||
openai.ChatCompletionContentPartUnionParam{
|
||||
OfText: &openai.ChatCompletionContentPartTextParam{
|
||||
Text: "\n",
|
||||
},
|
||||
},
|
||||
)
|
||||
} else {
|
||||
textContent = openai.String(m.Text)
|
||||
}
|
||||
}
|
||||
|
||||
return []openai.ChatCompletionMessage{res}
|
||||
a := strings.Split(model, "-")
|
||||
|
||||
useSystemInsteadOfDeveloper := true
|
||||
if len(a) > 1 && a[0][0] == 'o' {
|
||||
useSystemInsteadOfDeveloper = false
|
||||
}
|
||||
|
||||
switch m.Role {
|
||||
case RoleSystem:
|
||||
if useSystemInsteadOfDeveloper {
|
||||
res = openai.ChatCompletionMessageParamUnion{
|
||||
OfSystem: &openai.ChatCompletionSystemMessageParam{
|
||||
Content: openai.ChatCompletionSystemMessageParamContentUnion{
|
||||
OfString: textContent,
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
res = openai.ChatCompletionMessageParamUnion{
|
||||
OfDeveloper: &openai.ChatCompletionDeveloperMessageParam{
|
||||
Content: openai.ChatCompletionDeveloperMessageParamContentUnion{
|
||||
OfString: textContent,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
case RoleUser:
|
||||
var name param.Opt[string]
|
||||
if m.Name != "" {
|
||||
name = openai.String(m.Name)
|
||||
}
|
||||
|
||||
res = openai.ChatCompletionMessageParamUnion{
|
||||
OfUser: &openai.ChatCompletionUserMessageParam{
|
||||
Name: name,
|
||||
Content: openai.ChatCompletionUserMessageParamContentUnion{
|
||||
OfString: textContent,
|
||||
OfArrayOfContentParts: arrayOfContentParts,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
case RoleAssistant:
|
||||
var name param.Opt[string]
|
||||
if m.Name != "" {
|
||||
name = openai.String(m.Name)
|
||||
}
|
||||
|
||||
res = openai.ChatCompletionMessageParamUnion{
|
||||
OfAssistant: &openai.ChatCompletionAssistantMessageParam{
|
||||
Name: name,
|
||||
Content: openai.ChatCompletionAssistantMessageParamContentUnion{
|
||||
OfString: textContent,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return []openai.ChatCompletionMessageParamUnion{res}
|
||||
}
|
||||
|
||||
type ToolCall struct {
|
||||
@@ -134,10 +206,19 @@ func (t ToolCall) toRaw() map[string]any {
|
||||
return res
|
||||
}
|
||||
|
||||
func (t ToolCall) toChatCompletionMessages() []openai.ChatCompletionMessage {
|
||||
return []openai.ChatCompletionMessage{{
|
||||
Role: openai.ChatMessageRoleTool,
|
||||
ToolCallID: t.ID,
|
||||
func (t ToolCall) toChatCompletionMessages(_ string) []openai.ChatCompletionMessageParamUnion {
|
||||
return []openai.ChatCompletionMessageParamUnion{{
|
||||
OfAssistant: &openai.ChatCompletionAssistantMessageParam{
|
||||
ToolCalls: []openai.ChatCompletionMessageToolCallParam{
|
||||
{
|
||||
ID: t.ID,
|
||||
Function: openai.ChatCompletionMessageToolCallFunctionParam{
|
||||
Name: t.FunctionCall.Name,
|
||||
Arguments: t.FunctionCall.Arguments,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
@@ -160,7 +241,7 @@ func (t ToolCallResponse) toRaw() map[string]any {
|
||||
return res
|
||||
}
|
||||
|
||||
func (t ToolCallResponse) toChatCompletionMessages() []openai.ChatCompletionMessage {
|
||||
func (t ToolCallResponse) toChatCompletionMessages(_ string) []openai.ChatCompletionMessageParamUnion {
|
||||
var refusal string
|
||||
if t.Error != nil {
|
||||
refusal = t.Error.Error()
|
||||
@@ -174,10 +255,13 @@ func (t ToolCallResponse) toChatCompletionMessages() []openai.ChatCompletionMess
|
||||
}
|
||||
}
|
||||
|
||||
return []openai.ChatCompletionMessage{{
|
||||
Role: openai.ChatMessageRoleTool,
|
||||
Content: fmt.Sprint(t.Result),
|
||||
ToolCallID: t.ID,
|
||||
return []openai.ChatCompletionMessageParamUnion{{
|
||||
OfTool: &openai.ChatCompletionToolMessageParam{
|
||||
ToolCallID: t.ID,
|
||||
Content: openai.ChatCompletionToolMessageParamContentUnion{
|
||||
OfString: openai.String(fmt.Sprint(t.Result)),
|
||||
},
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user