twitter-tools-public/server/vendor/github.com/sashabaranov/go-openai/assistant.go

326 lines
9.2 KiB
Go

package openai
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
)
const (
assistantsSuffix = "/assistants"
assistantsFilesSuffix = "/files"
)
type Assistant struct {
ID string `json:"id"`
Object string `json:"object"`
CreatedAt int64 `json:"created_at"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Model string `json:"model"`
Instructions *string `json:"instructions,omitempty"`
Tools []AssistantTool `json:"tools"`
ToolResources *AssistantToolResource `json:"tool_resources,omitempty"`
FileIDs []string `json:"file_ids,omitempty"` // Deprecated in v2
Metadata map[string]any `json:"metadata,omitempty"`
Temperature *float32 `json:"temperature,omitempty"`
TopP *float32 `json:"top_p,omitempty"`
ResponseFormat any `json:"response_format,omitempty"`
httpHeader
}
type AssistantToolType string
const (
AssistantToolTypeCodeInterpreter AssistantToolType = "code_interpreter"
AssistantToolTypeRetrieval AssistantToolType = "retrieval"
AssistantToolTypeFunction AssistantToolType = "function"
AssistantToolTypeFileSearch AssistantToolType = "file_search"
)
type AssistantTool struct {
Type AssistantToolType `json:"type"`
Function *FunctionDefinition `json:"function,omitempty"`
}
type AssistantToolFileSearch struct {
VectorStoreIDs []string `json:"vector_store_ids"`
}
type AssistantToolCodeInterpreter struct {
FileIDs []string `json:"file_ids"`
}
type AssistantToolResource struct {
FileSearch *AssistantToolFileSearch `json:"file_search,omitempty"`
CodeInterpreter *AssistantToolCodeInterpreter `json:"code_interpreter,omitempty"`
}
// AssistantRequest provides the assistant request parameters.
// When modifying the tools the API functions as the following:
// If Tools is undefined, no changes are made to the Assistant's tools.
// If Tools is empty slice it will effectively delete all of the Assistant's tools.
// If Tools is populated, it will replace all of the existing Assistant's tools with the provided tools.
type AssistantRequest struct {
Model string `json:"model"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Instructions *string `json:"instructions,omitempty"`
Tools []AssistantTool `json:"-"`
FileIDs []string `json:"file_ids,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
ToolResources *AssistantToolResource `json:"tool_resources,omitempty"`
ResponseFormat any `json:"response_format,omitempty"`
Temperature *float32 `json:"temperature,omitempty"`
TopP *float32 `json:"top_p,omitempty"`
}
// MarshalJSON provides a custom marshaller for the assistant request to handle the API use cases
// If Tools is nil, the field is omitted from the JSON.
// If Tools is an empty slice, it's included in the JSON as an empty array ([]).
// If Tools is populated, it's included in the JSON with the elements.
func (a AssistantRequest) MarshalJSON() ([]byte, error) {
type Alias AssistantRequest
assistantAlias := &struct {
Tools *[]AssistantTool `json:"tools,omitempty"`
*Alias
}{
Alias: (*Alias)(&a),
}
if a.Tools != nil {
assistantAlias.Tools = &a.Tools
}
return json.Marshal(assistantAlias)
}
// AssistantsList is a list of assistants.
type AssistantsList struct {
Assistants []Assistant `json:"data"`
LastID *string `json:"last_id"`
FirstID *string `json:"first_id"`
HasMore bool `json:"has_more"`
httpHeader
}
type AssistantDeleteResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Deleted bool `json:"deleted"`
httpHeader
}
type AssistantFile struct {
ID string `json:"id"`
Object string `json:"object"`
CreatedAt int64 `json:"created_at"`
AssistantID string `json:"assistant_id"`
httpHeader
}
type AssistantFileRequest struct {
FileID string `json:"file_id"`
}
type AssistantFilesList struct {
AssistantFiles []AssistantFile `json:"data"`
httpHeader
}
// CreateAssistant creates a new assistant.
func (c *Client) CreateAssistant(ctx context.Context, request AssistantRequest) (response Assistant, err error) {
req, err := c.newRequest(ctx, http.MethodPost, c.fullURL(assistantsSuffix), withBody(request),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// RetrieveAssistant retrieves an assistant.
func (c *Client) RetrieveAssistant(
ctx context.Context,
assistantID string,
) (response Assistant, err error) {
urlSuffix := fmt.Sprintf("%s/%s", assistantsSuffix, assistantID)
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// ModifyAssistant modifies an assistant.
func (c *Client) ModifyAssistant(
ctx context.Context,
assistantID string,
request AssistantRequest,
) (response Assistant, err error) {
urlSuffix := fmt.Sprintf("%s/%s", assistantsSuffix, assistantID)
req, err := c.newRequest(ctx, http.MethodPost, c.fullURL(urlSuffix), withBody(request),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// DeleteAssistant deletes an assistant.
func (c *Client) DeleteAssistant(
ctx context.Context,
assistantID string,
) (response AssistantDeleteResponse, err error) {
urlSuffix := fmt.Sprintf("%s/%s", assistantsSuffix, assistantID)
req, err := c.newRequest(ctx, http.MethodDelete, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// ListAssistants Lists the currently available assistants.
func (c *Client) ListAssistants(
ctx context.Context,
limit *int,
order *string,
after *string,
before *string,
) (response AssistantsList, err error) {
urlValues := url.Values{}
if limit != nil {
urlValues.Add("limit", fmt.Sprintf("%d", *limit))
}
if order != nil {
urlValues.Add("order", *order)
}
if after != nil {
urlValues.Add("after", *after)
}
if before != nil {
urlValues.Add("before", *before)
}
encodedValues := ""
if len(urlValues) > 0 {
encodedValues = "?" + urlValues.Encode()
}
urlSuffix := fmt.Sprintf("%s%s", assistantsSuffix, encodedValues)
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// CreateAssistantFile creates a new assistant file.
func (c *Client) CreateAssistantFile(
ctx context.Context,
assistantID string,
request AssistantFileRequest,
) (response AssistantFile, err error) {
urlSuffix := fmt.Sprintf("%s/%s%s", assistantsSuffix, assistantID, assistantsFilesSuffix)
req, err := c.newRequest(ctx, http.MethodPost, c.fullURL(urlSuffix),
withBody(request),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// RetrieveAssistantFile retrieves an assistant file.
func (c *Client) RetrieveAssistantFile(
ctx context.Context,
assistantID string,
fileID string,
) (response AssistantFile, err error) {
urlSuffix := fmt.Sprintf("%s/%s%s/%s", assistantsSuffix, assistantID, assistantsFilesSuffix, fileID)
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}
// DeleteAssistantFile deletes an existing file.
func (c *Client) DeleteAssistantFile(
ctx context.Context,
assistantID string,
fileID string,
) (err error) {
urlSuffix := fmt.Sprintf("%s/%s%s/%s", assistantsSuffix, assistantID, assistantsFilesSuffix, fileID)
req, err := c.newRequest(ctx, http.MethodDelete, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, nil)
return
}
// ListAssistantFiles Lists the currently available files for an assistant.
func (c *Client) ListAssistantFiles(
ctx context.Context,
assistantID string,
limit *int,
order *string,
after *string,
before *string,
) (response AssistantFilesList, err error) {
urlValues := url.Values{}
if limit != nil {
urlValues.Add("limit", fmt.Sprintf("%d", *limit))
}
if order != nil {
urlValues.Add("order", *order)
}
if after != nil {
urlValues.Add("after", *after)
}
if before != nil {
urlValues.Add("before", *before)
}
encodedValues := ""
if len(urlValues) > 0 {
encodedValues = "?" + urlValues.Encode()
}
urlSuffix := fmt.Sprintf("%s/%s%s%s", assistantsSuffix, assistantID, assistantsFilesSuffix, encodedValues)
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix),
withBetaAssistantVersion(c.config.AssistantVersion))
if err != nil {
return
}
err = c.sendRequest(req, &response)
return
}