 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			455 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			455 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package openai
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| )
 | |
| 
 | |
| type Run struct {
 | |
| 	ID             string             `json:"id"`
 | |
| 	Object         string             `json:"object"`
 | |
| 	CreatedAt      int64              `json:"created_at"`
 | |
| 	ThreadID       string             `json:"thread_id"`
 | |
| 	AssistantID    string             `json:"assistant_id"`
 | |
| 	Status         RunStatus          `json:"status"`
 | |
| 	RequiredAction *RunRequiredAction `json:"required_action,omitempty"`
 | |
| 	LastError      *RunLastError      `json:"last_error,omitempty"`
 | |
| 	ExpiresAt      int64              `json:"expires_at"`
 | |
| 	StartedAt      *int64             `json:"started_at,omitempty"`
 | |
| 	CancelledAt    *int64             `json:"cancelled_at,omitempty"`
 | |
| 	FailedAt       *int64             `json:"failed_at,omitempty"`
 | |
| 	CompletedAt    *int64             `json:"completed_at,omitempty"`
 | |
| 	Model          string             `json:"model"`
 | |
| 	Instructions   string             `json:"instructions,omitempty"`
 | |
| 	Tools          []Tool             `json:"tools"`
 | |
| 	FileIDS        []string           `json:"file_ids"` //nolint:revive // backwards-compatibility
 | |
| 	Metadata       map[string]any     `json:"metadata"`
 | |
| 	Usage          Usage              `json:"usage,omitempty"`
 | |
| 
 | |
| 	Temperature *float32 `json:"temperature,omitempty"`
 | |
| 	// The maximum number of prompt tokens that may be used over the course of the run.
 | |
| 	// If the run exceeds the number of prompt tokens specified, the run will end with status 'incomplete'.
 | |
| 	MaxPromptTokens int `json:"max_prompt_tokens,omitempty"`
 | |
| 	// The maximum number of completion tokens that may be used over the course of the run.
 | |
| 	// If the run exceeds the number of completion tokens specified, the run will end with status 'incomplete'.
 | |
| 	MaxCompletionTokens int `json:"max_completion_tokens,omitempty"`
 | |
| 	// ThreadTruncationStrategy defines the truncation strategy to use for the thread.
 | |
| 	TruncationStrategy *ThreadTruncationStrategy `json:"truncation_strategy,omitempty"`
 | |
| 
 | |
| 	httpHeader
 | |
| }
 | |
| 
 | |
| type RunStatus string
 | |
| 
 | |
| const (
 | |
| 	RunStatusQueued         RunStatus = "queued"
 | |
| 	RunStatusInProgress     RunStatus = "in_progress"
 | |
| 	RunStatusRequiresAction RunStatus = "requires_action"
 | |
| 	RunStatusCancelling     RunStatus = "cancelling"
 | |
| 	RunStatusFailed         RunStatus = "failed"
 | |
| 	RunStatusCompleted      RunStatus = "completed"
 | |
| 	RunStatusIncomplete     RunStatus = "incomplete"
 | |
| 	RunStatusExpired        RunStatus = "expired"
 | |
| 	RunStatusCancelled      RunStatus = "cancelled"
 | |
| )
 | |
| 
 | |
| type RunRequiredAction struct {
 | |
| 	Type              RequiredActionType `json:"type"`
 | |
| 	SubmitToolOutputs *SubmitToolOutputs `json:"submit_tool_outputs,omitempty"`
 | |
| }
 | |
| 
 | |
| type RequiredActionType string
 | |
| 
 | |
| const (
 | |
| 	RequiredActionTypeSubmitToolOutputs RequiredActionType = "submit_tool_outputs"
 | |
| )
 | |
| 
 | |
| type SubmitToolOutputs struct {
 | |
| 	ToolCalls []ToolCall `json:"tool_calls"`
 | |
| }
 | |
| 
 | |
| type RunLastError struct {
 | |
| 	Code    RunError `json:"code"`
 | |
| 	Message string   `json:"message"`
 | |
| }
 | |
| 
 | |
| type RunError string
 | |
| 
 | |
| const (
 | |
| 	RunErrorServerError       RunError = "server_error"
 | |
| 	RunErrorRateLimitExceeded RunError = "rate_limit_exceeded"
 | |
| )
 | |
| 
 | |
| type RunRequest struct {
 | |
| 	AssistantID            string          `json:"assistant_id"`
 | |
| 	Model                  string          `json:"model,omitempty"`
 | |
| 	Instructions           string          `json:"instructions,omitempty"`
 | |
| 	AdditionalInstructions string          `json:"additional_instructions,omitempty"`
 | |
| 	AdditionalMessages     []ThreadMessage `json:"additional_messages,omitempty"`
 | |
| 	Tools                  []Tool          `json:"tools,omitempty"`
 | |
| 	Metadata               map[string]any  `json:"metadata,omitempty"`
 | |
| 
 | |
| 	// Sampling temperature between 0 and 2. Higher values like 0.8 are  more random.
 | |
| 	// lower values are more focused and deterministic.
 | |
| 	Temperature *float32 `json:"temperature,omitempty"`
 | |
| 	TopP        *float32 `json:"top_p,omitempty"`
 | |
| 
 | |
| 	// The maximum number of prompt tokens that may be used over the course of the run.
 | |
| 	// If the run exceeds the number of prompt tokens specified, the run will end with status 'incomplete'.
 | |
| 	MaxPromptTokens int `json:"max_prompt_tokens,omitempty"`
 | |
| 
 | |
| 	// The maximum number of completion tokens that may be used over the course of the run.
 | |
| 	// If the run exceeds the number of completion tokens specified, the run will end with status 'incomplete'.
 | |
| 	MaxCompletionTokens int `json:"max_completion_tokens,omitempty"`
 | |
| 
 | |
| 	// ThreadTruncationStrategy defines the truncation strategy to use for the thread.
 | |
| 	TruncationStrategy *ThreadTruncationStrategy `json:"truncation_strategy,omitempty"`
 | |
| 
 | |
| 	// This can be either a string or a ToolChoice object.
 | |
| 	ToolChoice any `json:"tool_choice,omitempty"`
 | |
| 	// This can be either a string or a ResponseFormat object.
 | |
| 	ResponseFormat any `json:"response_format,omitempty"`
 | |
| 	// Disable the default behavior of parallel tool calls by setting it: false.
 | |
| 	ParallelToolCalls any `json:"parallel_tool_calls,omitempty"`
 | |
| }
 | |
| 
 | |
| // ThreadTruncationStrategy defines the truncation strategy to use for the thread.
 | |
| // https://platform.openai.com/docs/assistants/how-it-works/truncation-strategy.
 | |
| type ThreadTruncationStrategy struct {
 | |
| 	// default 'auto'.
 | |
| 	Type TruncationStrategy `json:"type,omitempty"`
 | |
| 	// this field should be set if the truncation strategy is set to LastMessages.
 | |
| 	LastMessages *int `json:"last_messages,omitempty"`
 | |
| }
 | |
| 
 | |
| // TruncationStrategy defines the existing truncation strategies existing for thread management in an assistant.
 | |
| type TruncationStrategy string
 | |
| 
 | |
| const (
 | |
| 	// TruncationStrategyAuto messages in the middle of the thread will be dropped to fit the context length of the model.
 | |
| 	TruncationStrategyAuto = TruncationStrategy("auto")
 | |
| 	// TruncationStrategyLastMessages the thread will be truncated to the n most recent messages in the thread.
 | |
| 	TruncationStrategyLastMessages = TruncationStrategy("last_messages")
 | |
| )
 | |
| 
 | |
| // ReponseFormat specifies the format the model must output.
 | |
| // https://platform.openai.com/docs/api-reference/runs/createRun#runs-createrun-response_format.
 | |
| // Type can either be text or json_object.
 | |
| type ReponseFormat struct {
 | |
| 	Type string `json:"type"`
 | |
| }
 | |
| 
 | |
| type RunModifyRequest struct {
 | |
| 	Metadata map[string]any `json:"metadata,omitempty"`
 | |
| }
 | |
| 
 | |
| // RunList is a list of runs.
 | |
| type RunList struct {
 | |
| 	Runs []Run `json:"data"`
 | |
| 
 | |
| 	httpHeader
 | |
| }
 | |
| 
 | |
| type SubmitToolOutputsRequest struct {
 | |
| 	ToolOutputs []ToolOutput `json:"tool_outputs"`
 | |
| }
 | |
| 
 | |
| type ToolOutput struct {
 | |
| 	ToolCallID string `json:"tool_call_id"`
 | |
| 	Output     any    `json:"output"`
 | |
| }
 | |
| 
 | |
| type CreateThreadAndRunRequest struct {
 | |
| 	RunRequest
 | |
| 	Thread ThreadRequest `json:"thread"`
 | |
| }
 | |
| 
 | |
| type RunStep struct {
 | |
| 	ID          string         `json:"id"`
 | |
| 	Object      string         `json:"object"`
 | |
| 	CreatedAt   int64          `json:"created_at"`
 | |
| 	AssistantID string         `json:"assistant_id"`
 | |
| 	ThreadID    string         `json:"thread_id"`
 | |
| 	RunID       string         `json:"run_id"`
 | |
| 	Type        RunStepType    `json:"type"`
 | |
| 	Status      RunStepStatus  `json:"status"`
 | |
| 	StepDetails StepDetails    `json:"step_details"`
 | |
| 	LastError   *RunLastError  `json:"last_error,omitempty"`
 | |
| 	ExpiredAt   *int64         `json:"expired_at,omitempty"`
 | |
| 	CancelledAt *int64         `json:"cancelled_at,omitempty"`
 | |
| 	FailedAt    *int64         `json:"failed_at,omitempty"`
 | |
| 	CompletedAt *int64         `json:"completed_at,omitempty"`
 | |
| 	Metadata    map[string]any `json:"metadata"`
 | |
| 
 | |
| 	httpHeader
 | |
| }
 | |
| 
 | |
| type RunStepStatus string
 | |
| 
 | |
| const (
 | |
| 	RunStepStatusInProgress RunStepStatus = "in_progress"
 | |
| 	RunStepStatusCancelling RunStepStatus = "cancelled"
 | |
| 	RunStepStatusFailed     RunStepStatus = "failed"
 | |
| 	RunStepStatusCompleted  RunStepStatus = "completed"
 | |
| 	RunStepStatusExpired    RunStepStatus = "expired"
 | |
| )
 | |
| 
 | |
| type RunStepType string
 | |
| 
 | |
| const (
 | |
| 	RunStepTypeMessageCreation RunStepType = "message_creation"
 | |
| 	RunStepTypeToolCalls       RunStepType = "tool_calls"
 | |
| )
 | |
| 
 | |
| type StepDetails struct {
 | |
| 	Type            RunStepType                 `json:"type"`
 | |
| 	MessageCreation *StepDetailsMessageCreation `json:"message_creation,omitempty"`
 | |
| 	ToolCalls       []ToolCall                  `json:"tool_calls,omitempty"`
 | |
| }
 | |
| 
 | |
| type StepDetailsMessageCreation struct {
 | |
| 	MessageID string `json:"message_id"`
 | |
| }
 | |
| 
 | |
| // RunStepList is a list of steps.
 | |
| type RunStepList struct {
 | |
| 	RunSteps []RunStep `json:"data"`
 | |
| 
 | |
| 	FirstID string `json:"first_id"`
 | |
| 	LastID  string `json:"last_id"`
 | |
| 	HasMore bool   `json:"has_more"`
 | |
| 
 | |
| 	httpHeader
 | |
| }
 | |
| 
 | |
| type Pagination struct {
 | |
| 	Limit  *int
 | |
| 	Order  *string
 | |
| 	After  *string
 | |
| 	Before *string
 | |
| }
 | |
| 
 | |
| // CreateRun creates a new run.
 | |
| func (c *Client) CreateRun(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	request RunRequest,
 | |
| ) (response Run, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs", threadID)
 | |
| 	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
 | |
| }
 | |
| 
 | |
| // RetrieveRun retrieves a run.
 | |
| func (c *Client) RetrieveRun(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string,
 | |
| ) (response Run, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s", threadID, runID)
 | |
| 	req, err := c.newRequest(
 | |
| 		ctx,
 | |
| 		http.MethodGet,
 | |
| 		c.fullURL(urlSuffix),
 | |
| 		withBetaAssistantVersion(c.config.AssistantVersion))
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	err = c.sendRequest(req, &response)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // ModifyRun modifies a run.
 | |
| func (c *Client) ModifyRun(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string,
 | |
| 	request RunModifyRequest,
 | |
| ) (response Run, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s", threadID, runID)
 | |
| 	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
 | |
| }
 | |
| 
 | |
| // ListRuns lists runs.
 | |
| func (c *Client) ListRuns(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	pagination Pagination,
 | |
| ) (response RunList, err error) {
 | |
| 	urlValues := url.Values{}
 | |
| 	if pagination.Limit != nil {
 | |
| 		urlValues.Add("limit", fmt.Sprintf("%d", *pagination.Limit))
 | |
| 	}
 | |
| 	if pagination.Order != nil {
 | |
| 		urlValues.Add("order", *pagination.Order)
 | |
| 	}
 | |
| 	if pagination.After != nil {
 | |
| 		urlValues.Add("after", *pagination.After)
 | |
| 	}
 | |
| 	if pagination.Before != nil {
 | |
| 		urlValues.Add("before", *pagination.Before)
 | |
| 	}
 | |
| 
 | |
| 	encodedValues := ""
 | |
| 	if len(urlValues) > 0 {
 | |
| 		encodedValues = "?" + urlValues.Encode()
 | |
| 	}
 | |
| 
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs%s", threadID, 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
 | |
| }
 | |
| 
 | |
| // SubmitToolOutputs submits tool outputs.
 | |
| func (c *Client) SubmitToolOutputs(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string,
 | |
| 	request SubmitToolOutputsRequest) (response Run, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s/submit_tool_outputs", threadID, runID)
 | |
| 	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
 | |
| }
 | |
| 
 | |
| // CancelRun cancels a run.
 | |
| func (c *Client) CancelRun(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string) (response Run, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s/cancel", threadID, runID)
 | |
| 	req, err := c.newRequest(
 | |
| 		ctx,
 | |
| 		http.MethodPost,
 | |
| 		c.fullURL(urlSuffix),
 | |
| 		withBetaAssistantVersion(c.config.AssistantVersion))
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	err = c.sendRequest(req, &response)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // CreateThreadAndRun submits tool outputs.
 | |
| func (c *Client) CreateThreadAndRun(
 | |
| 	ctx context.Context,
 | |
| 	request CreateThreadAndRunRequest) (response Run, err error) {
 | |
| 	urlSuffix := "/threads/runs"
 | |
| 	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
 | |
| }
 | |
| 
 | |
| // RetrieveRunStep retrieves a run step.
 | |
| func (c *Client) RetrieveRunStep(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string,
 | |
| 	stepID string,
 | |
| ) (response RunStep, err error) {
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s/steps/%s", threadID, runID, stepID)
 | |
| 	req, err := c.newRequest(
 | |
| 		ctx,
 | |
| 		http.MethodGet,
 | |
| 		c.fullURL(urlSuffix),
 | |
| 		withBetaAssistantVersion(c.config.AssistantVersion))
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	err = c.sendRequest(req, &response)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // ListRunSteps lists run steps.
 | |
| func (c *Client) ListRunSteps(
 | |
| 	ctx context.Context,
 | |
| 	threadID string,
 | |
| 	runID string,
 | |
| 	pagination Pagination,
 | |
| ) (response RunStepList, err error) {
 | |
| 	urlValues := url.Values{}
 | |
| 	if pagination.Limit != nil {
 | |
| 		urlValues.Add("limit", fmt.Sprintf("%d", *pagination.Limit))
 | |
| 	}
 | |
| 	if pagination.Order != nil {
 | |
| 		urlValues.Add("order", *pagination.Order)
 | |
| 	}
 | |
| 	if pagination.After != nil {
 | |
| 		urlValues.Add("after", *pagination.After)
 | |
| 	}
 | |
| 	if pagination.Before != nil {
 | |
| 		urlValues.Add("before", *pagination.Before)
 | |
| 	}
 | |
| 
 | |
| 	encodedValues := ""
 | |
| 	if len(urlValues) > 0 {
 | |
| 		encodedValues = "?" + urlValues.Encode()
 | |
| 	}
 | |
| 
 | |
| 	urlSuffix := fmt.Sprintf("/threads/%s/runs/%s/steps%s", threadID, runID, 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
 | |
| }
 |