-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
Is your feature request related to a problem? Please describe.
Yes. I got LocalAI running, both with Docker and building on my Mac. I tested with the Mistral model, but noticed that it didn't use functions. The reason is that 'functions' is actually already deprecated and there is now a 'tools' array instead. And my client is already using that.
Describe the solution you'd like
The tools array is a layer above functions. Each tool has a 'type', and the only supported type is 'function'. So if the type is function, there is a second field named function, which is then the Function object that used to be directly contained in the old functions array. So I imaging a simple conversion can be done, and I've actually tried to implement that:
diff --git a/api/schema/openai.go b/api/schema/openai.go
index 6355ff6..abf5dff 100644
--- a/api/schema/openai.go
+++ b/api/schema/openai.go
@@ -2,6 +2,7 @@ package schema
import (
"context"
+ "encoding/json"
config "github.com/go-skynet/LocalAI/api/config"
@@ -114,8 +115,8 @@ type OpenAIRequest struct {
Messages []Message `json:"messages" yaml:"messages"`
// A list of available functions to call
- Functions []grammar.Function `json:"functions" yaml:"functions"`
- FunctionCall interface{} `json:"function_call" yaml:"function_call"` // might be a string or an object
+ Functions []grammar.Function `json:"functions,omitempty" yaml:"functions"`
+ FunctionCall interface{} `json:"function_call,omitempty" yaml:"function_call"` // might be a string or an object
Stream bool `json:"stream"`
@@ -133,3 +134,34 @@ type OpenAIRequest struct {
// AutoGPTQ
ModelBaseName string `json:"model_base_name" yaml:"model_base_name"`
}
+
+// UnmarshalJSON implements the json.Unmarshaler interface and maps "tools" and "tool_call" to "functions" and "function_call".
+func (r *OpenAIRequest) UnmarshalJSON(data []byte) error {
+ type Alias OpenAIRequest
+
+ // Define an auxiliary struct with additional fields to avoid infinite recursion when using the standard JSON unmarshalling.
+ var aux struct {
+ Alias
+ Tools []grammar.Tool `json:"tools,omitempty" yaml:"tools"`
+ ToolCall interface{} `json:"tool_call,omitempty" yaml:"tool_call"`
+ }
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ // Copy the deserialized data back into the original request.
+ *r = OpenAIRequest(aux.Alias)
+
+ // Map "tools" and "tool_call".
+ if len(aux.Tools) > 0 {
+ for _, tool := range aux.Tools {
+ r.Functions = append(r.Functions, tool.Function)
+ }
+ }
+ if aux.ToolCall != nil {
+ r.FunctionCall = aux.ToolCall
+ }
+
+ return nil
+}
diff --git a/pkg/grammar/tools.go b/pkg/grammar/tools.go
index ef56662..5b3e497 100644
--- a/pkg/grammar/tools.go
+++ b/pkg/grammar/tools.go
+ package grammar
+
+type Tool struct {
+ Type string `json:"type"`
+ Function Function `json:"function,omitempty"`
}
+type Tools []Tool... but it crashes. Unfortunately, I only get a 500 and a nil panic in the log, but not actually where it happens. With some guidance, maybe I can provide a PR.