- Added global uses configuration to the assistant, allowing for centralized management of vision, audio, search, and fetch settings. - Updated the Assistant struct and related methods to support the new Uses configuration, improving flexibility in assistant operations. - Refactored the Stream method to utilize the new CompletionResponse type, enhancing response handling. - Introduced new methods for building requests and managing capabilities, streamlining the assistant's interaction with various connectors.
354 lines
15 KiB
Go
354 lines
15 KiB
Go
package context
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/yaoapp/gou/plan"
|
|
"github.com/yaoapp/gou/store"
|
|
"github.com/yaoapp/yao/openapi/oauth/types"
|
|
)
|
|
|
|
// Accept the accept of the request, it will be used to identify the accept of the request.
|
|
type Accept string
|
|
|
|
// Referer the referer of the request, it will be used to identify the referer of the request.
|
|
type Referer string
|
|
|
|
// Client represents the client information from HTTP request
|
|
type Client struct {
|
|
Type string `json:"type,omitempty"` // Client type: web, android, ios, windows, macos, linux, agent, jssdk
|
|
UserAgent string `json:"user_agent,omitempty"` // Original User-Agent header
|
|
IP string `json:"ip,omitempty"` // Client IP address
|
|
}
|
|
|
|
const (
|
|
// AcceptStandard standard response format compatible with OpenAI API and general chat UIs (default)
|
|
AcceptStandard = "standard"
|
|
|
|
// AcceptWebCUI web-based CUI format with action request support for Yao Chat User Interface
|
|
AcceptWebCUI = "cui-web"
|
|
|
|
// AccepNativeCUI native mobile/tablet CUI format with action request support
|
|
AccepNativeCUI = "cui-native"
|
|
|
|
// AcceptDesktopCUI desktop CUI format with action request support
|
|
AcceptDesktopCUI = "cui-desktop"
|
|
)
|
|
|
|
// ValidAccepts is the map of valid accept types
|
|
var ValidAccepts = map[string]bool{
|
|
AcceptStandard: true,
|
|
AcceptWebCUI: true,
|
|
AccepNativeCUI: true,
|
|
AcceptDesktopCUI: true,
|
|
}
|
|
|
|
const (
|
|
// RefererAPI request from HTTP API endpoint
|
|
RefererAPI = "api"
|
|
|
|
// RefererProcess request from Yao Process call
|
|
RefererProcess = "process"
|
|
|
|
// RefererMCP request from MCP (Model Context Protocol) server
|
|
RefererMCP = "mcp"
|
|
|
|
// RefererJSSDK request from JavaScript SDK
|
|
RefererJSSDK = "jssdk"
|
|
|
|
// RefererAgent request from agent-to-agent recursive call (assistant calling another assistant)
|
|
RefererAgent = "agent"
|
|
|
|
// RefererTool request from tool/function execution
|
|
RefererTool = "tool"
|
|
|
|
// RefererHook request from hook trigger (on_message, on_error, etc.)
|
|
RefererHook = "hook"
|
|
|
|
// RefererSchedule request from scheduled task or cron job
|
|
RefererSchedule = "schedule"
|
|
|
|
// RefererScript request from custom script execution
|
|
RefererScript = "script"
|
|
|
|
// RefererInternal request from internal system call
|
|
RefererInternal = "internal"
|
|
)
|
|
|
|
// ValidReferers is the map of valid referer types
|
|
var ValidReferers = map[string]bool{
|
|
RefererAPI: true,
|
|
RefererProcess: true,
|
|
RefererMCP: true,
|
|
RefererJSSDK: true,
|
|
RefererAgent: true,
|
|
RefererTool: true,
|
|
RefererHook: true,
|
|
RefererSchedule: true,
|
|
RefererScript: true,
|
|
RefererInternal: true,
|
|
}
|
|
|
|
const (
|
|
// StackStatusPending stack is created but not started yet
|
|
StackStatusPending = "pending"
|
|
|
|
// StackStatusRunning stack is currently executing
|
|
StackStatusRunning = "running"
|
|
|
|
// StackStatusCompleted stack completed successfully
|
|
StackStatusCompleted = "completed"
|
|
|
|
// StackStatusFailed stack failed with error
|
|
StackStatusFailed = "failed"
|
|
|
|
// StackStatusTimeout stack execution timeout
|
|
StackStatusTimeout = "timeout"
|
|
)
|
|
|
|
// ValidStackStatus is the map of valid stack status types
|
|
var ValidStackStatus = map[string]bool{
|
|
StackStatusPending: true,
|
|
StackStatusRunning: true,
|
|
StackStatusCompleted: true,
|
|
StackStatusFailed: true,
|
|
StackStatusTimeout: true,
|
|
}
|
|
|
|
// Context the context
|
|
type Context struct {
|
|
|
|
// Context
|
|
context.Context
|
|
Space plan.Space `json:"-"` // Shared data space, it will be used to share data between the request and the call
|
|
Cache store.Store `json:"-"` // Cache store, it will be used to store the message cache, default is "__yao.agent.cache"
|
|
Stack *Stack `json:"-"` // Stack, current active stack of the request
|
|
Stacks map[string]*Stack `json:"-"` // Stacks, all stacks in this request (for trace logging)
|
|
Writer Writer `json:"-"` // Writer, it will be used to write response data to the client
|
|
|
|
// Authorized information
|
|
Authorized *types.AuthorizedInfo `json:"authorized,omitempty"` // Authorized information
|
|
ChatID string `json:"chat_id,omitempty"` // Chat ID, use to select chat
|
|
AssistantID string `json:"assistant_id,omitempty"` // Assistant ID, use to select assistant
|
|
Sid string `json:"sid" yaml:"-"` // Session ID (Deprecated, use Authorized instead)
|
|
Connector string `json:"connector,omitempty"` // Connector, use to select the connector of the LLM Model, Default is Assistant.Connector
|
|
Search *bool `json:"search,omitempty"` // Search mode, default is true
|
|
|
|
// Arguments for call
|
|
Args []interface{} `json:"args,omitempty"` // Arguments for call, it will be used to pass data to the call
|
|
Retry bool `json:"retry,omitempty"` // Retry mode
|
|
RetryTimes uint8 `json:"retry_times,omitempty"` // Retry times
|
|
|
|
// Locale information
|
|
Locale string `json:"locale,omitempty"` // Locale
|
|
Theme string `json:"theme,omitempty"` // Theme
|
|
|
|
// Request information
|
|
Client Client `json:"client,omitempty"` // Client information from HTTP request
|
|
Referer string `json:"referer,omitempty"` // Request source: api, process, mcp, jssdk, agent, tool, hook, schedule, script, internal
|
|
Accept Accept `json:"accept,omitempty"` // Response format: standard, cui-web, cui-native, cui-desktop
|
|
|
|
// CUI Context information
|
|
Route string `json:"route,omitempty"` // The route of the request, it will be used to identify the route of the request
|
|
Metadata map[string]interface{} `json:"metadata,omitempty"` // The metadata of the request, it will be used to pass data to the page
|
|
|
|
Silent bool `json:"silent,omitempty"` // Silent mode (Deprecated, use Referer instead)
|
|
}
|
|
|
|
// Stack represents the call stack node for tracing agent-to-agent calls
|
|
// Uses a flat structure to avoid circular references and memory overhead
|
|
type Stack struct {
|
|
// Identity
|
|
ID string `json:"id"` // Unique stack node ID, used to identify this specific call
|
|
TraceID string `json:"trace_id"` // Shared trace ID for entire call tree, inherited from root
|
|
|
|
// Call context
|
|
AssistantID string `json:"assistant_id"` // Assistant handling this call
|
|
Referer string `json:"referer,omitempty"` // Call source: api, agent, tool, process, etc.
|
|
Depth int `json:"depth"` // Call depth in the tree (0=root)
|
|
|
|
// Relationships
|
|
ParentID string `json:"parent_id,omitempty"` // Parent stack ID (empty for root call)
|
|
Path []string `json:"path"` // Full path from root: [root_id, parent_id, ..., this_id]
|
|
|
|
// Tracking
|
|
CreatedAt int64 `json:"created_at"` // Unix timestamp in milliseconds
|
|
CompletedAt *int64 `json:"completed_at,omitempty"` // Unix timestamp when completed (nil if ongoing)
|
|
Status string `json:"status"` // Status: pending, running, completed, failed, timeout
|
|
Error string `json:"error,omitempty"` // Error message if failed
|
|
|
|
// Metrics
|
|
DurationMs *int64 `json:"duration_ms,omitempty"` // Duration in milliseconds (calculated when completed)
|
|
}
|
|
|
|
// Response the response
|
|
// 100% compatible with the OpenAI API
|
|
type Response struct {
|
|
Create *HookCreateResponse `json:"create,omitempty"`
|
|
MCP *ResponseHookMCP `json:"mcp,omitempty"`
|
|
Done *ResponseHookDone `json:"done,omitempty"`
|
|
Failback *ResponseHookFailback `json:"failback,omitempty"`
|
|
Completion *CompletionResponse `json:"completion,omitempty"`
|
|
}
|
|
|
|
// HookCreateResponse the response of the create hook
|
|
type HookCreateResponse struct {
|
|
|
|
// Messages to be sent to the assistant
|
|
Messages []Message `json:"messages,omitempty"`
|
|
|
|
// Audio configuration (for models that support audio output)
|
|
Audio *AudioConfig `json:"audio,omitempty"`
|
|
|
|
// Generation parameters
|
|
Temperature *float64 `json:"temperature,omitempty"`
|
|
MaxTokens *int `json:"max_tokens,omitempty"`
|
|
MaxCompletionTokens *int `json:"max_completion_tokens,omitempty"`
|
|
|
|
// Context adjustments - allow hook to modify context fields
|
|
AssistantID string `json:"assistant_id,omitempty"` // Override assistant ID
|
|
Connector string `json:"connector,omitempty"` // Override connector
|
|
Locale string `json:"locale,omitempty"` // Override locale
|
|
Theme string `json:"theme,omitempty"` // Override theme
|
|
Route string `json:"route,omitempty"` // Override route
|
|
Metadata map[string]interface{} `json:"metadata,omitempty"` // Override or merge metadata
|
|
}
|
|
|
|
// ResponseHookDone the response of the done hook
|
|
type ResponseHookDone struct{}
|
|
|
|
// ResponseHookMCP the response of the mcp hook
|
|
type ResponseHookMCP struct{}
|
|
|
|
// ResponseHookFailback the response of the failback hook
|
|
type ResponseHookFailback struct{}
|
|
|
|
// Message Structure ( OpenAI Chat Completion Input Message Structure, https://platform.openai.com/docs/api-reference/chat/create#chat/create-messages )
|
|
// ===============================
|
|
|
|
// MessageRole represents the role of a message author
|
|
type MessageRole string
|
|
|
|
// Message role constants
|
|
const (
|
|
RoleDeveloper MessageRole = "developer" // Developer-provided instructions (o1 models and newer)
|
|
RoleSystem MessageRole = "system" // System instructions
|
|
RoleUser MessageRole = "user" // User messages
|
|
RoleAssistant MessageRole = "assistant" // Assistant responses
|
|
RoleTool MessageRole = "tool" // Tool responses
|
|
)
|
|
|
|
// Message represents a message in the conversation, compatible with OpenAI's chat completion API
|
|
// Supports message types: developer, system, user, assistant, and tool
|
|
type Message struct {
|
|
// Common fields for all message types
|
|
Role MessageRole `json:"role"` // Required: message author role
|
|
Content interface{} `json:"content,omitempty"` // string or array of ContentPart; Required for most types, optional for assistant with tool_calls
|
|
Name *string `json:"name,omitempty"` // Optional: participant name to differentiate between participants of the same role
|
|
|
|
// Tool message specific fields
|
|
ToolCallID *string `json:"tool_call_id,omitempty"` // Required for tool messages: tool call that this message is responding to
|
|
|
|
// Assistant message specific fields
|
|
ToolCalls []ToolCall `json:"tool_calls,omitempty"` // Optional for assistant: tool calls generated by the model
|
|
Refusal *string `json:"refusal,omitempty"` // Optional for assistant: refusal message (null when not refusing)
|
|
}
|
|
|
|
// ContentPartType represents the type of content part
|
|
type ContentPartType string
|
|
|
|
// Content part type constants
|
|
const (
|
|
ContentText ContentPartType = "text" // Text content
|
|
ContentImageURL ContentPartType = "image_url" // Image URL content (Vision)
|
|
ContentInputAudio ContentPartType = "input_audio" // Input audio content (Audio)
|
|
)
|
|
|
|
// ContentPart represents a part of the message content (for multimodal messages)
|
|
// Used when Content is an array instead of a simple string
|
|
type ContentPart struct {
|
|
Type ContentPartType `json:"type"` // Required: content part type
|
|
Text string `json:"text,omitempty"` // For type="text": the text content
|
|
ImageURL *ImageURL `json:"image_url,omitempty"` // For type="image_url": the image URL
|
|
InputAudio *InputAudio `json:"input_audio,omitempty"` // For type="input_audio": the input audio data
|
|
}
|
|
|
|
// ImageDetailLevel represents the detail level for image processing
|
|
type ImageDetailLevel string
|
|
|
|
// Image detail level constants
|
|
const (
|
|
DetailAuto ImageDetailLevel = "auto" // Let the model decide
|
|
DetailLow ImageDetailLevel = "low" // Low detail (faster, cheaper)
|
|
DetailHigh ImageDetailLevel = "high" // High detail (slower, more expensive)
|
|
)
|
|
|
|
// ImageURL represents an image URL in the message content
|
|
type ImageURL struct {
|
|
URL string `json:"url"` // Required: URL of the image or base64 encoded image data
|
|
Detail ImageDetailLevel `json:"detail,omitempty"` // Optional: how the model processes the image
|
|
}
|
|
|
|
// InputAudio represents input audio data in the message content
|
|
type InputAudio struct {
|
|
Data string `json:"data"` // Required: Base64 encoded audio data
|
|
Format string `json:"format"` // Required: Audio format (e.g., "wav", "mp3")
|
|
}
|
|
|
|
// ToolCallType represents the type of tool call
|
|
type ToolCallType string
|
|
|
|
// Tool call type constants
|
|
const (
|
|
ToolTypeFunction ToolCallType = "function" // Function call
|
|
)
|
|
|
|
// ToolCall represents a tool call generated by the model (for assistant messages)
|
|
type ToolCall struct {
|
|
ID string `json:"id"` // Required: unique identifier for the tool call
|
|
Type ToolCallType `json:"type"` // Required: type of tool call, currently only "function"
|
|
Function Function `json:"function"` // Required: function call details
|
|
}
|
|
|
|
// Function represents a function call with name and arguments
|
|
type Function struct {
|
|
Name string `json:"name"` // Required: name of the function to call
|
|
Arguments string `json:"arguments,omitempty"` // Optional: arguments to pass to the function, as a JSON string
|
|
}
|
|
|
|
// Completion Request Structure ( OpenAI Chat Completion Request, https://platform.openai.com/docs/api-reference/chat/create )
|
|
// ===============================
|
|
|
|
// CompletionRequest represents a chat completion request compatible with OpenAI's API
|
|
type CompletionRequest struct {
|
|
// Required fields
|
|
Model string `json:"model"` // Required: ID of the model to use
|
|
Messages []Message `json:"messages"` // Required: list of messages comprising the conversation so far
|
|
|
|
// Audio configuration (for models that support audio output)
|
|
Audio *AudioConfig `json:"audio,omitempty"` // Optional: audio output configuration
|
|
|
|
// Generation parameters
|
|
Temperature *float64 `json:"temperature,omitempty"` // Optional: sampling temperature (0-2), defaults to 1
|
|
MaxTokens *int `json:"max_tokens,omitempty"` // Optional: maximum number of tokens to generate (deprecated, use max_completion_tokens)
|
|
MaxCompletionTokens *int `json:"max_completion_tokens,omitempty"` // Optional: maximum number of tokens that can be generated in the completion
|
|
|
|
// Streaming configuration
|
|
Stream *bool `json:"stream,omitempty"` // Optional: if true, stream partial message deltas
|
|
StreamOptions *StreamOptions `json:"stream_options,omitempty"` // Optional: options for streaming response
|
|
|
|
// CUI Context information
|
|
Route string `json:"route,omitempty"` // Optional: route of the request for CUI context
|
|
Metadata map[string]interface{} `json:"metadata,omitempty"` // Optional: metadata to pass to the page for CUI context
|
|
}
|
|
|
|
// AudioConfig represents the audio output configuration for models that support audio
|
|
type AudioConfig struct {
|
|
Voice string `json:"voice"` // Required: voice to use for audio output (e.g., "alloy", "echo", "fable", "onyx", "nova", "shimmer")
|
|
Format string `json:"format"` // Required: audio output format (e.g., "wav", "mp3", "flac", "opus", "pcm16")
|
|
}
|
|
|
|
// StreamOptions represents options for streaming responses
|
|
type StreamOptions struct {
|
|
IncludeUsage bool `json:"include_usage,omitempty"` // If true, include usage statistics in the final chunk
|
|
}
|