Documentation
¶
Index ¶
- func ConvertResponse(targetFormat string, resp *Response) ([]byte, error)
- type AnthropicFormatConverter
- func (c *AnthropicFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
- func (c *AnthropicFormatConverter) ConvertRequestToUniversal(anthropicReq *AnthropicMessagesRequest) (*Request, error)
- func (c *AnthropicFormatConverter) ConvertResponseToAnthropic(universalResp *Response, model string) (*AnthropicMessagesResponse, error)
- func (c *AnthropicFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
- func (c *AnthropicFormatConverter) GetEndpoint() string
- func (c *AnthropicFormatConverter) GetProviderName() string
- type AnthropicMessagesRequest
- type AnthropicMessagesResponse
- type AudioSource
- type AuthenticationError
- type Client
- type Config
- type ContentPart
- func NewAudioPartFromBase64(data, format string) ContentPart
- func NewAudioPartFromURL(url, format string) ContentPart
- func NewDocumentPartFromBase64(data, mimeType string) ContentPart
- func NewDocumentPartFromURL(url, mimeType string) ContentPart
- func NewImagePartFromBase64(data, format string) ContentPart
- func NewImagePartFromURL(url string) ContentPart
- func NewPDFPartFromBase64(data string) ContentPart
- func NewPDFPartFromURL(url string) ContentPart
- func NewTextPart(text string) ContentPart
- func NewVideoPartFromBase64(data, format string) ContentPart
- func NewVideoPartFromURL(url, format string) ContentPart
- type ContentType
- type DocumentSource
- type ErrorWithStatus
- type FormatConverter
- type FormatConverterFactory
- type FunctionDefinition
- type GeminiFormatConverter
- func (c *GeminiFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
- func (c *GeminiFormatConverter) ConvertRequestToUniversal(geminiReq *GeminiGenerateContentRequest) (*Request, error)
- func (c *GeminiFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
- func (c *GeminiFormatConverter) ConvertResponseToGemini(universalResp *Response) (*GeminiGenerateContentResponse, error)
- func (c *GeminiFormatConverter) GetEndpoint() string
- func (c *GeminiFormatConverter) GetProviderName() string
- type GeminiGenerateContentRequest
- type GeminiGenerateContentResponse
- type ImageSource
- type ImageSourceType
- type InvalidRequestError
- type MediaSourceType
- type Message
- type NetworkError
- type OpenAIChatCompletionRequest
- type OpenAIFormatConverter
- func (c *OpenAIFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
- func (c *OpenAIFormatConverter) ConvertRequestToUniversal(openaiReq *OpenAIChatCompletionRequest) (*Request, error)
- func (c *OpenAIFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
- func (c *OpenAIFormatConverter) ConvertResponseToOpenAI(universalResp *Response, model string, promptTokens, completionTokens int) (*openaiChatCompletionResponse, error)
- func (c *OpenAIFormatConverter) GetEndpoint() string
- func (c *OpenAIFormatConverter) GetProviderName() string
- type Option
- type Provider
- type RateLimitError
- type Request
- type Response
- type Role
- type ServerError
- type TimeoutError
- type Tool
- type ToolCall
- type ToolServerClient
- type ToolServerConfig
- type ToolServerDetails
- type ToolServerManager
- type UnknownError
- type VideoSource
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AnthropicFormatConverter ¶
type AnthropicFormatConverter struct{}
AnthropicFormatConverter provides conversion between Anthropic API format and Universal format. It implements the FormatConverter interface.
func NewAnthropicFormatConverter ¶
func NewAnthropicFormatConverter() *AnthropicFormatConverter
NewAnthropicFormatConverter creates a new Anthropic format converter.
func (*AnthropicFormatConverter) ConvertRequestFromFormat ¶
func (c *AnthropicFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
ConvertRequestFromFormat converts an Anthropic request to Universal format.
func (*AnthropicFormatConverter) ConvertRequestToUniversal ¶
func (c *AnthropicFormatConverter) ConvertRequestToUniversal(anthropicReq *AnthropicMessagesRequest) (*Request, error)
ConvertRequestToUniversal converts an Anthropic request to Universal format.
func (*AnthropicFormatConverter) ConvertResponseToAnthropic ¶
func (c *AnthropicFormatConverter) ConvertResponseToAnthropic(universalResp *Response, model string) (*AnthropicMessagesResponse, error)
ConvertResponseToAnthropic converts a Universal Response to Anthropic format.
func (*AnthropicFormatConverter) ConvertResponseToFormat ¶
func (c *AnthropicFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
ConvertResponseToFormat converts a Universal Response to Anthropic format.
func (*AnthropicFormatConverter) GetEndpoint ¶
func (c *AnthropicFormatConverter) GetEndpoint() string
GetEndpoint returns the Anthropic API endpoint path.
func (*AnthropicFormatConverter) GetProviderName ¶
func (c *AnthropicFormatConverter) GetProviderName() string
GetProviderName returns the provider name.
type AnthropicMessagesRequest ¶
type AnthropicMessagesRequest struct {
Model string `json:"model"`
System string `json:"system,omitempty"`
Messages []anthropicMessage `json:"messages"`
MaxTokens int `json:"max_tokens"`
Tools []anthropicTool `json:"tools,omitempty"`
}
AnthropicMessagesRequest represents an Anthropic messages request.
type AnthropicMessagesResponse ¶
type AnthropicMessagesResponse struct {
ID string `json:"id"`
Type string `json:"type"`
Role string `json:"role"`
Model string `json:"model"`
Content []anthropicContentBlock `json:"content"`
StopReason string `json:"stop_reason"`
Usage *anthropicUsage `json:"usage,omitempty"`
}
AnthropicMessagesResponse represents an Anthropic messages response.
type AudioSource ¶
type AudioSource struct {
Type MediaSourceType // "url" or "base64"
URL string // HTTP(S) URL to the audio file
Data string // Base64-encoded audio data
Format string // Audio format: "mp3", "wav", "aiff", "aac", "ogg", "flac"
}
AudioSource represents an audio input for audio-enabled models (primarily Gemini). Supported formats: MP3, WAV, AIFF, AAC, OGG, FLAC
type AuthenticationError ¶
type AuthenticationError struct {
// contains filtered or unexported fields
}
AuthenticationError represents authentication failures (401, 403).
func NewAuthenticationError ¶
func NewAuthenticationError(provider string, statusCode int, message string, err error) *AuthenticationError
NewAuthenticationError creates a new authentication error.
func (*AuthenticationError) StatusCode ¶
func (e *AuthenticationError) StatusCode() int
type Client ¶
Client is the unified interface for different AI providers.
func NewClientFromEnv ¶
NewClientFromEnv creates a new AI client by reading configuration from environment variables. It provides a convenient way to initialize the client without manual configuration.
It uses the following environment variables:
- AI_PROVIDER: "openai" or "gemini" (defaults to "openai").
- OPENAI_API_KEY, OPENAI_MODEL, OPENAI_BASE_URL
- GEMINI_API_KEY, GEMINI_MODEL, GEMINI_BASE_URL
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config holds all possible Configuration options for any client.
type ContentPart ¶
type ContentPart struct {
Type ContentType
Text string // For text parts
ImageSource *ImageSource // For image parts
AudioSource *AudioSource // For audio parts
VideoSource *VideoSource // For video parts
DocumentSource *DocumentSource // For document parts (PDF, etc.)
}
ContentPart represents a part of multimodal content (text, image, audio, video, document, etc.).
func NewAudioPartFromBase64 ¶
func NewAudioPartFromBase64(data, format string) ContentPart
NewAudioPartFromBase64 creates an audio content part from base64-encoded data. The format parameter specifies the audio format (e.g., "mp3", "wav", "ogg").
func NewAudioPartFromURL ¶
func NewAudioPartFromURL(url, format string) ContentPart
NewAudioPartFromURL creates an audio content part from a URL. Supported formats: mp3, wav, aiff, aac, ogg, flac Primarily supported by Gemini models.
func NewDocumentPartFromBase64 ¶
func NewDocumentPartFromBase64(data, mimeType string) ContentPart
NewDocumentPartFromBase64 creates a document content part from base64-encoded data. The mimeType parameter should be "application/pdf" for PDF documents.
func NewDocumentPartFromURL ¶
func NewDocumentPartFromURL(url, mimeType string) ContentPart
NewDocumentPartFromURL creates a document content part from a URL. Primarily used for PDF documents. Supported by Gemini and Anthropic models.
func NewImagePartFromBase64 ¶
func NewImagePartFromBase64(data, format string) ContentPart
NewImagePartFromBase64 creates an image content part from base64-encoded data. The data parameter should be the base64-encoded image data. The format parameter specifies the image format (e.g., "png", "jpeg", "gif", "webp"). If format is empty, it will be auto-detected from the data URI prefix if present.
func NewImagePartFromURL ¶
func NewImagePartFromURL(url string) ContentPart
NewImagePartFromURL creates an image content part from a URL.
func NewPDFPartFromBase64 ¶
func NewPDFPartFromBase64(data string) ContentPart
NewPDFPartFromBase64 is a convenience function for creating a PDF document part from base64 data.
func NewPDFPartFromURL ¶
func NewPDFPartFromURL(url string) ContentPart
NewPDFPartFromURL is a convenience function for creating a PDF document part from a URL.
func NewTextPart ¶
func NewTextPart(text string) ContentPart
NewTextPart creates a text content part.
func NewVideoPartFromBase64 ¶
func NewVideoPartFromBase64(data, format string) ContentPart
NewVideoPartFromBase64 creates a video content part from base64-encoded data. The format parameter specifies the video format (e.g., "mp4", "webm").
func NewVideoPartFromURL ¶
func NewVideoPartFromURL(url, format string) ContentPart
NewVideoPartFromURL creates a video content part from a URL. Supported formats: mp4, mpeg, mov, avi, flv, mpg, webm, wmv, 3gpp Primarily supported by Gemini models.
type ContentType ¶
type ContentType string
ContentType defines the type of content in a multimodal message.
const ( ContentTypeText ContentType = "text" ContentTypeImage ContentType = "image" ContentTypeAudio ContentType = "audio" ContentTypeVideo ContentType = "video" ContentTypeDocument ContentType = "document" )
type DocumentSource ¶
type DocumentSource struct {
Type MediaSourceType // "url" or "base64"
URL string // HTTP(S) URL to the document
Data string // Base64-encoded document data
MimeType string // MIME type: "application/pdf", etc.
}
DocumentSource represents a document input (primarily PDF). Supported by Gemini and Anthropic.
type ErrorWithStatus ¶
ErrorWithStatus is the base interface for all AI client errors. It provides access to the HTTP status code and allows for error type assertions.
type FormatConverter ¶
type FormatConverter interface {
// ConvertRequestFromFormat converts a provider-specific request format to Universal Request.
// The input should be the unmarshaled JSON request body from the provider's API.
ConvertRequestFromFormat(providerReq any) (*Request, error)
// ConvertResponseToFormat converts a Universal Response to provider-specific response format.
// Returns the response struct that can be marshaled to JSON for the provider's API.
ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
// GetEndpoint returns the API endpoint path for this format (e.g., "/v1/chat/completions", "/v1/messages").
GetEndpoint() string
// GetProviderName returns the provider name for this format (e.g., "openai", "gemini", "anthropic").
GetProviderName() string
}
FormatConverter defines the interface for converting between provider-specific API formats and the Universal format. This enables creating proxy servers that accept one provider's API format and route to any other provider.
type FormatConverterFactory ¶
type FormatConverterFactory struct{}
FormatConverterFactory creates format converters for different providers.
func NewFormatConverterFactory ¶
func NewFormatConverterFactory() *FormatConverterFactory
NewFormatConverterFactory creates a new format converter factory.
func (*FormatConverterFactory) GetConverter ¶
func (f *FormatConverterFactory) GetConverter(provider Provider) (FormatConverter, error)
GetConverter returns the appropriate format converter for the given provider.
type FunctionDefinition ¶
type FunctionDefinition struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Parameters json.RawMessage `json:"parameters"`
}
FunctionDefinition is a universal, provider-agnostic function definition.
type GeminiFormatConverter ¶
type GeminiFormatConverter struct{}
GeminiFormatConverter provides conversion between Google Gemini API format and Universal format. It implements the FormatConverter interface.
func NewGeminiFormatConverter ¶
func NewGeminiFormatConverter() *GeminiFormatConverter
NewGeminiFormatConverter creates a new Gemini format converter.
func (*GeminiFormatConverter) ConvertRequestFromFormat ¶
func (c *GeminiFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
ConvertRequestFromFormat converts a Gemini request to Universal format.
func (*GeminiFormatConverter) ConvertRequestToUniversal ¶
func (c *GeminiFormatConverter) ConvertRequestToUniversal(geminiReq *GeminiGenerateContentRequest) (*Request, error)
ConvertRequestToUniversal converts a Gemini request to Universal format.
func (*GeminiFormatConverter) ConvertResponseToFormat ¶
func (c *GeminiFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
ConvertResponseToFormat converts a Universal Response to Gemini format.
func (*GeminiFormatConverter) ConvertResponseToGemini ¶
func (c *GeminiFormatConverter) ConvertResponseToGemini(universalResp *Response) (*GeminiGenerateContentResponse, error)
ConvertResponseToGemini converts a Universal Response to Gemini format.
func (*GeminiFormatConverter) GetEndpoint ¶
func (c *GeminiFormatConverter) GetEndpoint() string
GetEndpoint returns the Gemini API endpoint path (note: model is typically part of the path).
func (*GeminiFormatConverter) GetProviderName ¶
func (c *GeminiFormatConverter) GetProviderName() string
GetProviderName returns the provider name.
type GeminiGenerateContentRequest ¶
type GeminiGenerateContentRequest struct {
Contents []geminiContent `json:"contents"`
Tools []geminiTool `json:"tools,omitempty"`
SystemInstruction *geminiContent `json:"systemInstruction,omitempty"`
}
GeminiGenerateContentRequest represents a Gemini generateContent request.
type GeminiGenerateContentResponse ¶
type GeminiGenerateContentResponse struct {
Candidates []geminiCandidate `json:"candidates"`
}
GeminiGenerateContentResponse represents a Gemini generateContent response.
type ImageSource ¶
type ImageSource struct {
Type ImageSourceType // "url" or "base64"
URL string // HTTP(S) URL to the image
Data string // Base64-encoded image data (with or without data URI prefix)
Format string // Image format: "png", "jpeg", "gif", "webp" (optional, can be auto-detected)
}
ImageSource represents an image input for vision-enabled models.
type ImageSourceType ¶
type ImageSourceType string
ImageSourceType defines how an image is provided.
const ( ImageSourceTypeURL ImageSourceType = "url" ImageSourceTypeBase64 ImageSourceType = "base64" )
type InvalidRequestError ¶
type InvalidRequestError struct {
Details string
// contains filtered or unexported fields
}
InvalidRequestError represents invalid request errors (400).
func NewInvalidRequestError ¶
func NewInvalidRequestError(provider string, message string, details string, err error) *InvalidRequestError
NewInvalidRequestError creates a new invalid request error.
func (*InvalidRequestError) StatusCode ¶
func (e *InvalidRequestError) StatusCode() int
type MediaSourceType ¶
type MediaSourceType string
MediaSourceType defines how media (audio/video/document) is provided.
const ( MediaSourceTypeURL MediaSourceType = "url" MediaSourceTypeBase64 MediaSourceType = "base64" )
type Message ¶
type Message struct {
Role Role
Content string // Simple text content (for backward compatibility)
ContentParts []ContentPart // Multimodal content (text + images, etc.)
ToolCalls []ToolCall
ToolCallID string
}
Message represents a universal message structure. Supports both simple text messages (Content) and multimodal messages (ContentParts).
func NewMultimodalMessage ¶
func NewMultimodalMessage(role Role, parts []ContentPart) Message
NewMultimodalMessage creates a message with multimodal content parts.
func NewTextMessage ¶
NewTextMessage creates a simple text message. This is a convenience function for backward compatibility.
type NetworkError ¶
type NetworkError struct {
// contains filtered or unexported fields
}
NetworkError represents network-level failures (connection refused, DNS, etc.).
func NewNetworkError ¶
func NewNetworkError(provider string, message string, err error) *NetworkError
NewNetworkError creates a new network error.
func (*NetworkError) StatusCode ¶
func (e *NetworkError) StatusCode() int
type OpenAIChatCompletionRequest ¶
type OpenAIChatCompletionRequest struct {
Model string `json:"model"`
Messages []openaiMessage `json:"messages"`
Tools []openaiTool `json:"tools,omitempty"`
}
OpenAIChatCompletionRequest represents an OpenAI chat completion request. This type is exported to enable format conversion in the proxy server.
type OpenAIFormatConverter ¶
type OpenAIFormatConverter struct{}
OpenAIFormatConverter provides conversion between OpenAI API format and Universal format. This enables creating an OpenAI-compatible proxy server that can route to any provider. It implements the FormatConverter interface.
func NewOpenAIFormatConverter ¶
func NewOpenAIFormatConverter() *OpenAIFormatConverter
NewOpenAIFormatConverter creates a new OpenAI format converter.
func (*OpenAIFormatConverter) ConvertRequestFromFormat ¶
func (c *OpenAIFormatConverter) ConvertRequestFromFormat(providerReq any) (*Request, error)
ConvertRequestFromFormat converts an OpenAI request to Universal format. Implements FormatConverter interface.
func (*OpenAIFormatConverter) ConvertRequestToUniversal ¶
func (c *OpenAIFormatConverter) ConvertRequestToUniversal(openaiReq *OpenAIChatCompletionRequest) (*Request, error)
ConvertRequestToUniversal converts an OpenAI chat completion request to Universal Request format.
func (*OpenAIFormatConverter) ConvertResponseToFormat ¶
func (c *OpenAIFormatConverter) ConvertResponseToFormat(universalResp *Response, originalModel string) (any, error)
ConvertResponseToFormat converts a Universal Response to OpenAI format. Implements FormatConverter interface.
func (*OpenAIFormatConverter) ConvertResponseToOpenAI ¶
func (c *OpenAIFormatConverter) ConvertResponseToOpenAI(universalResp *Response, model string, promptTokens, completionTokens int) (*openaiChatCompletionResponse, error)
ConvertResponseToOpenAI converts a Universal Response to OpenAI chat completion response format.
func (*OpenAIFormatConverter) GetEndpoint ¶
func (c *OpenAIFormatConverter) GetEndpoint() string
GetEndpoint returns the OpenAI API endpoint path.
func (*OpenAIFormatConverter) GetProviderName ¶
func (c *OpenAIFormatConverter) GetProviderName() string
GetProviderName returns the provider name.
type Option ¶
type Option func(*Config)
Option is the function signature for Configuration options.
func WithAPIKey ¶
WithAPIKey sets the API key for authentication.
func WithBaseURL ¶
WithBaseURL sets a custom base URL for the API endpoint.
func WithTimeout ¶
WithTimeout sets the HTTP client timeout.
type RateLimitError ¶
RateLimitError represents rate limiting errors (429).
func NewRateLimitError ¶
func NewRateLimitError(provider string, message string, retryAfter time.Duration, err error) *RateLimitError
NewRateLimitError creates a new rate limit error.
func (*RateLimitError) StatusCode ¶
func (e *RateLimitError) StatusCode() int
type Request ¶
Request is a universal request structure for content generation.
func ConvertRequest ¶
ConvertRequest converts a provider-specific request payload into the universal Request format.
type ServerError ¶
type ServerError struct {
// contains filtered or unexported fields
}
ServerError represents server-side errors (5xx).
func NewServerError ¶
func NewServerError(provider string, statusCode int, message string, err error) *ServerError
NewServerError creates a new server error.
func (*ServerError) StatusCode ¶
func (e *ServerError) StatusCode() int
type TimeoutError ¶
TimeoutError represents timeout errors (context deadline exceeded).
func NewTimeoutError ¶
func NewTimeoutError(provider string, duration time.Duration, err error) *TimeoutError
NewTimeoutError creates a new timeout error.
func (*TimeoutError) StatusCode ¶
func (e *TimeoutError) StatusCode() int
type Tool ¶
type Tool struct {
Type string `json:"type"`
Function FunctionDefinition `json:"function"`
}
Tool defines a tool the model can use.
type ToolServerClient ¶
type ToolServerClient struct {
// contains filtered or unexported fields
}
ToolServerClient handles the connection lifecycle for a single tool server. It should be created and managed by the ToolServerManager.
func (*ToolServerClient) Close ¶
func (c *ToolServerClient) Close() error
Close terminates the session with the tool server.
func (*ToolServerClient) Connect ¶
func (c *ToolServerClient) Connect(ctx context.Context) error
Connect establishes a session with the tool server. It is optional to call this manually; methods like FetchTools and ExecuteTool will call it automatically if a session is not already active.
func (*ToolServerClient) ExecuteTool ¶
ExecuteTool executes a tool call, automatically connecting if necessary.
func (*ToolServerClient) FetchTools ¶
func (c *ToolServerClient) FetchTools(ctx context.Context) ([]Tool, error)
FetchTools lists available tools, automatically connecting if necessary.
type ToolServerConfig ¶
type ToolServerConfig struct {
MCPServers map[string]ToolServerDetails `json:"mcpServers"`
}
ToolServerConfig defines the top-level structure of the mcp.json file.
type ToolServerDetails ¶
type ToolServerDetails struct {
Command string `json:"command"`
Args []string `json:"args"`
Env map[string]string `json:"env"`
}
ToolServerDetails defines the configuration for a command-based tool server as found in the mcp.json file.
type ToolServerManager ¶
type ToolServerManager struct {
// contains filtered or unexported fields
}
ToolServerManager discovers and manages tool server clients from various sources. It acts as a central registry for all known tool servers. All methods are safe for concurrent use.
func NewToolServerManager ¶
func NewToolServerManager() *ToolServerManager
NewToolServerManager creates a new, empty manager.
func (*ToolServerManager) AddRemoteServer ¶
func (m *ToolServerManager) AddRemoteServer(name, url string) error
AddRemoteServer programmatically registers a remote, HTTP-based tool server.
func (*ToolServerManager) GetClient ¶
func (m *ToolServerManager) GetClient(name string) (*ToolServerClient, bool)
GetClient retrieves a ready-to-use client for the server with the given name.
func (*ToolServerManager) ListServerNames ¶
func (m *ToolServerManager) ListServerNames() []string
ListServerNames returns a slice of the names of all registered servers.
func (*ToolServerManager) LoadFromFile ¶
func (m *ToolServerManager) LoadFromFile(configFile string) error
LoadFromFile parses a standard mcp.json file and registers all defined servers with the manager.
type UnknownError ¶
type UnknownError struct {
// contains filtered or unexported fields
}
UnknownError represents unexpected errors that don't fit other categories.
func NewUnknownError ¶
func NewUnknownError(provider string, statusCode int, message string, err error) *UnknownError
NewUnknownError creates a new unknown error.
func (*UnknownError) StatusCode ¶
func (e *UnknownError) StatusCode() int
type VideoSource ¶
type VideoSource struct {
Type MediaSourceType // "url" or "base64"
URL string // HTTP(S) URL to the video file
Data string // Base64-encoded video data
Format string // Video format: "mp4", "mpeg", "mov", "avi", "flv", "webm", etc.
}
VideoSource represents a video input for video-enabled models (primarily Gemini). Supported formats: MP4, MPEG, MOV, AVI, FLV, MPG, WEBM, WMV, 3GPP
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
api-proxy
command
|
|
|
examples
|
|
|
audio_chat
command
|
|
|
pdf_chat
command
|
|
|
simple_chat
command
|
|
|
tool_server_interaction
command
|
|
|
universal_proxy_demo
command
|
|
|
video_chat
command
|
|
|
vision_chat
command
|