Skip to content

Commit

Permalink
feat(chat): support function call api (sashabaranov#369)
Browse files Browse the repository at this point in the history
* feat(chat): support function call api

* rename struct & add const ChatMessageRoleFunction
  • Loading branch information
Ccheers authored Jun 15, 2023
1 parent 7e76a68 commit 2bd65aa
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
77 changes: 73 additions & 4 deletions chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ const (
ChatMessageRoleSystem = "system"
ChatMessageRoleUser = "user"
ChatMessageRoleAssistant = "assistant"
ChatMessageRoleFunction = "function"
)

const chatCompletionsSuffix = "/chat/completions"

var (
ErrChatCompletionInvalidModel = errors.New("this model is not supported with this method, please use CreateCompletion client method instead") //nolint:lll
ErrChatCompletionStreamNotSupported = errors.New("streaming is not supported with this method, please use CreateChatCompletionStream") //nolint:lll
Expand All @@ -27,6 +30,14 @@ type ChatCompletionMessage struct {
// - https://github.com/openai/openai-python/blob/main/chatml.md
// - https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
Name string `json:"name,omitempty"`

FunctionCall *FunctionCall `json:"function_call,omitempty"`
}

type FunctionCall struct {
Name string `json:"name,omitempty"`
// call function with arguments in JSON format
Arguments string `json:"arguments,omitempty"`
}

// ChatCompletionRequest represents a request structure for chat completion API.
Expand All @@ -43,12 +54,70 @@ type ChatCompletionRequest struct {
FrequencyPenalty float32 `json:"frequency_penalty,omitempty"`
LogitBias map[string]int `json:"logit_bias,omitempty"`
User string `json:"user,omitempty"`
Functions []*FunctionDefine `json:"functions,omitempty"`
FunctionCall string `json:"function_call,omitempty"`
}

type FunctionDefine struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
// it's required in function call
Parameters *FunctionParams `json:"parameters"`
}

type FunctionParams struct {
// the Type must be JSONSchemaTypeObject
Type JSONSchemaType `json:"type"`
Properties map[string]*JSONSchemaDefine `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}

type JSONSchemaType string

const (
JSONSchemaTypeObject JSONSchemaType = "object"
JSONSchemaTypeNumber JSONSchemaType = "number"
JSONSchemaTypeString JSONSchemaType = "string"
JSONSchemaTypeArray JSONSchemaType = "array"
JSONSchemaTypeNull JSONSchemaType = "null"
JSONSchemaTypeBoolean JSONSchemaType = "boolean"
)

// JSONSchemaDefine is a struct for JSON Schema.
type JSONSchemaDefine struct {
// Type is a type of JSON Schema.
Type JSONSchemaType `json:"type,omitempty"`
// Description is a description of JSON Schema.
Description string `json:"description,omitempty"`
// Enum is a enum of JSON Schema. It used if Type is JSONSchemaTypeString.
Enum []string `json:"enum,omitempty"`
// Properties is a properties of JSON Schema. It used if Type is JSONSchemaTypeObject.
Properties map[string]*JSONSchemaDefine `json:"properties,omitempty"`
// Required is a required of JSON Schema. It used if Type is JSONSchemaTypeObject.
Required []string `json:"required,omitempty"`
}

type FinishReason string

const (
FinishReasonStop FinishReason = "stop"
FinishReasonLength FinishReason = "length"
FinishReasonFunctionCall FinishReason = "function_call"
FinishReasonContentFilter FinishReason = "content_filter"
FinishReasonNull FinishReason = "null"
)

type ChatCompletionChoice struct {
Index int `json:"index"`
Message ChatCompletionMessage `json:"message"`
FinishReason string `json:"finish_reason"`
Index int `json:"index"`
Message ChatCompletionMessage `json:"message"`
// FinishReason
// stop: API returned complete message,
// or a message terminated by one of the stop sequences provided via the stop parameter
// length: Incomplete model output due to max_tokens parameter or token limit
// function_call: The model decided to call a function
// content_filter: Omitted content due to a flag from our content filters
// null: API response still in progress or incomplete
FinishReason FinishReason `json:"finish_reason"`
}

// ChatCompletionResponse represents a response structure for chat completion API.
Expand All @@ -71,7 +140,7 @@ func (c *Client) CreateChatCompletion(
return
}

urlSuffix := "/chat/completions"
urlSuffix := chatCompletionsSuffix
if !checkEndpointSupportsModel(urlSuffix, request.Model) {
err = ErrChatCompletionInvalidModel
return
Expand Down
2 changes: 1 addition & 1 deletion chat_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (c *Client) CreateChatCompletionStream(
ctx context.Context,
request ChatCompletionRequest,
) (stream *ChatCompletionStream, err error) {
urlSuffix := "/chat/completions"
urlSuffix := chatCompletionsSuffix
if !checkEndpointSupportsModel(urlSuffix, request.Model) {
err = ErrChatCompletionInvalidModel
return
Expand Down
2 changes: 1 addition & 1 deletion completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var disabledModelsForEndpoints = map[string]map[string]bool{
GPT432K0314: true,
GPT432K0613: true,
},
"/chat/completions": {
chatCompletionsSuffix: {
CodexCodeDavinci002: true,
CodexCodeCushman001: true,
CodexCodeDavinci001: true,
Expand Down

0 comments on commit 2bd65aa

Please sign in to comment.