Documentation
¶
Overview ¶
Package virtualserver provides the HTTP handler for virtual model endpoints. It serves OpenAI Chat and Anthropic Messages API formats backed by separate per-provider virtual model registries.
This is the production HTTP surface for internal/virtualmodel: the parent server mounts it under /virtual/v1/* so end users can reach the synthetic provider for onboarding, demos, and dry-runs without configuring a real upstream provider. Test consumers do not depend on this package; they use the registry primitives in internal/virtualmodel directly.
Index ¶
- Constants
- type AnthropicContent
- type AnthropicDelta
- type AnthropicMessage
- type AnthropicMessageRequest
- type AnthropicMessageResponse
- type AnthropicModelsResponse
- type AnthropicStreamEvent
- type AnthropicTool
- type AnthropicUsage
- type ChatCompletionRequest
- type ChatCompletionResponse
- type ChatCompletionStreamResponse
- type Choice
- type Delta
- type FunctionCall
- type Handler
- type Message
- type OpenAIModelsResponse
- type ProviderSaver
- type ResponsesRequest
- type Service
- func (s *Service) BuildBuiltinProviders() []*typ.Provider
- func (s *Service) EnsureBuiltinProviders(store ProviderSaver) error
- func (s *Service) GetAnthropicRegistry() *anthropicvm.Registry
- func (s *Service) GetHandler() *Handler
- func (s *Service) GetOpenAIRegistry() *openaivm.Registry
- func (s *Service) SetupAnthropicRoutes(group *gin.RouterGroup)
- func (s *Service) SetupOpenAIRoutes(group *gin.RouterGroup)
- func (s *Service) SetupRoutes(group *gin.RouterGroup)deprecated
- type StreamChoice
- type ToolCall
- type Usage
Constants ¶
const ( BuiltinAnthropicUUID = "vmodel-builtin-anthropic" BuiltinOpenAIUUID = "vmodel-builtin-openai" BuiltinAnthropicName = "Virtual Models (Anthropic)" BuiltinOpenAIName = "Virtual Models (OpenAI)" )
Sentinel UUIDs and names for builtin virtual-model providers. Stable across restarts so seeding is idempotent.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AnthropicContent ¶
type AnthropicContent struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Input json.RawMessage `json:"input,omitempty"`
}
AnthropicContent is a content block in an Anthropic response.
type AnthropicDelta ¶
type AnthropicDelta struct {
Type string `json:"type,omitempty"`
Text string `json:"text,omitempty"`
Thinking string `json:"thinking,omitempty"`
StopReason string `json:"stop_reason,omitempty"`
}
AnthropicDelta is a delta in an Anthropic streaming response.
type AnthropicMessage ¶
type AnthropicMessage = anthropic.BetaMessageParam
Request types aliased from protocol / Anthropic SDK
type AnthropicMessageRequest ¶
type AnthropicMessageRequest = protocol.AnthropicBetaMessagesRequest
Request types aliased from protocol / Anthropic SDK
type AnthropicMessageResponse ¶
type AnthropicMessageResponse struct {
ID string `json:"id"`
Type string `json:"type"`
Role string `json:"role"`
Model string `json:"model"`
Content []AnthropicContent `json:"content"`
StopReason string `json:"stop_reason"`
Usage AnthropicUsage `json:"usage"`
}
AnthropicMessageResponse is an Anthropic-compatible message response.
type AnthropicModelsResponse ¶
type AnthropicModelsResponse struct {
Data []vmodel.Model `json:"data"`
FirstID string `json:"first_id"`
LastID string `json:"last_id"`
HasMore bool `json:"has_more"`
}
AnthropicModelsResponse is Anthropic's native /v1/models envelope. It differs from OpenAI's shape (no "object" field; cursor fields instead). We always emit has_more=false because vmodel returns the full registry in one shot.
type AnthropicStreamEvent ¶
type AnthropicStreamEvent struct {
Type string `json:"type"`
Message *AnthropicMessageResponse `json:"message,omitempty"`
Index int `json:"index,omitempty"`
Delta *AnthropicDelta `json:"delta,omitempty"`
Usage *AnthropicUsage `json:"usage,omitempty"`
}
AnthropicStreamEvent is a streaming event in Anthropic format.
type AnthropicTool ¶
type AnthropicTool = anthropic.BetaToolParam
Request types aliased from protocol / Anthropic SDK
type AnthropicUsage ¶
type AnthropicUsage struct {
InputTokens int64 `json:"input_tokens"`
OutputTokens int64 `json:"output_tokens"`
}
AnthropicUsage holds token usage in Anthropic format.
type ChatCompletionRequest ¶
type ChatCompletionRequest = protocol.OpenAIChatCompletionRequest
ChatCompletionRequest is an OpenAI-compatible chat completion request.
type ChatCompletionResponse ¶
type ChatCompletionResponse = openai.ChatCompletion
Response types aliased from OpenAI SDK
type ChatCompletionStreamResponse ¶
type ChatCompletionStreamResponse = openai.ChatCompletionChunk
Response types aliased from OpenAI SDK
type Delta ¶
type Delta = openai.ChatCompletionChunkChoiceDelta
Response types aliased from OpenAI SDK
type FunctionCall ¶
type FunctionCall = openai.ChatCompletionMessageFunctionToolCallFunction
Response types aliased from OpenAI SDK
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler handles HTTP requests for virtual model endpoints.
func NewHandler ¶
func NewHandler(anthropicReg *anthropicvm.Registry, openaiReg *openaivm.Registry) *Handler
NewHandler creates a new Handler backed by the given per-provider registries.
func (*Handler) ChatCompletions ¶
ChatCompletions handles POST /virtual/v1/chat/completions.
func (*Handler) ListAnthropicModels ¶
ListAnthropicModels handles GET /virtual/anthropic/v1/models — returns only the Anthropic-protocol registry in Anthropic's native envelope shape (data + first_id/last_id/has_more, no "object" field).
func (*Handler) ListModels
deprecated
ListModels handles GET /virtual/v1/models — returns the union of both registries.
Deprecated: prefer ListOpenAIModels / ListAnthropicModels for the protocol-split entrypoints. Retained for the legacy mixed-protocol route and for test fixtures that want both registries on one endpoint.
func (*Handler) ListOpenAIModels ¶
ListOpenAIModels handles GET /virtual/openai/v1/models — returns only the OpenAI-protocol registry so clients pointed at the OpenAI base URL don't see Anthropic-only model IDs they cannot dispatch.
func (*Handler) Messages ¶
Messages handles POST /virtual/v1/messages (Anthropic format).
Accepts both Anthropic v1 and beta wire formats. The query parameter "beta=true" mirrors the real Anthropic API gating used in internal/server/anthropic.go. Internally everything is canonicalized to the beta superset struct so vmodel implementations only deal with one request shape.
type OpenAIModelsResponse ¶
type OpenAIModelsResponse struct {
Object string `json:"object"`
Data []vmodel.Model `json:"data"`
}
OpenAIModelsResponse is the OpenAI models list response format.
type ProviderSaver ¶
type ProviderSaver interface {
GetByUUID(uuid string) (*typ.Provider, error)
Save(provider *typ.Provider) error
}
ProviderSaver is the minimal ProviderStore surface needed for seeding. Using an interface lets callers (server.go) pass the live *db.ProviderStore without virtualserver depending on the db package.
type ResponsesRequest ¶ added in v0.260716.1
type ResponsesRequest struct {
Model string `json:"model"`
Stream bool `json:"stream"`
Input json.RawMessage `json:"input"`
}
ResponsesRequest is the subset of the OpenAI Responses API request the virtual server needs: model routing, the stream flag, and the input text (echo models and token estimation read it; static mocks ignore it).
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service manages the virtual model service.
Each protocol has its own registry. A model registered in the Anthropic registry is callable only via /messages; a model in the OpenAI registry is callable only via /chat/completions. ID collisions across the two registries are intentional and legal — the registry IS the protocol context.
func NewService ¶
func NewService() *Service
NewService creates a fully initialized Service with default models registered in both protocol registries.
func (*Service) BuildBuiltinProviders ¶
BuildBuiltinProviders returns the list of builtin virtual-model providers that should be present in the ProviderStore. The list is built from the service's currently registered models so the seed always reflects the in-process registries.
func (*Service) EnsureBuiltinProviders ¶
func (s *Service) EnsureBuiltinProviders(store ProviderSaver) error
EnsureBuiltinProviders inserts or refreshes the builtin virtual-model providers in the given store. It is idempotent and safe to call on every startup:
- If a builtin provider is missing it is created (Enabled=true).
- If a builtin provider already exists its Enabled flag is preserved (users may have disabled it) while the model list is refreshed to match what is currently registered.
func (*Service) GetAnthropicRegistry ¶
func (s *Service) GetAnthropicRegistry() *anthropicvm.Registry
GetAnthropicRegistry returns the Anthropic-protocol model registry.
func (*Service) GetHandler ¶
GetHandler returns the HTTP handler.
func (*Service) GetOpenAIRegistry ¶
GetOpenAIRegistry returns the OpenAI Chat-protocol model registry.
func (*Service) SetupAnthropicRoutes ¶
func (s *Service) SetupAnthropicRoutes(group *gin.RouterGroup)
SetupAnthropicRoutes mounts the Anthropic-only entrypoints on the given group. Typical wiring:
anthropic := engine.Group("/virtual/anthropic")
svc.SetupAnthropicRoutes(anthropic)
This produces /virtual/anthropic/v1/models and /virtual/anthropic/v1/messages — drop-in compatible with the Anthropic SDK base URL convention.
func (*Service) SetupOpenAIRoutes ¶
func (s *Service) SetupOpenAIRoutes(group *gin.RouterGroup)
SetupOpenAIRoutes mounts the OpenAI-only entrypoints on the given group. Typical wiring:
openai := engine.Group("/virtual/openai")
svc.SetupOpenAIRoutes(openai)
This produces /virtual/openai/v1/models and /virtual/openai/v1/chat/completions — drop-in compatible with the OpenAI SDK base URL convention.
func (*Service) SetupRoutes
deprecated
func (s *Service) SetupRoutes(group *gin.RouterGroup)
SetupRoutes mounts virtual-model endpoints on a single mixed-protocol group at <group>/{models,chat/completions,messages}.
Deprecated: prefer SetupOpenAIRoutes + SetupAnthropicRoutes so OpenAI and Anthropic clients each see only their own model IDs. Retained for test fixtures.
type StreamChoice ¶
type StreamChoice = openai.ChatCompletionChunkChoice
Response types aliased from OpenAI SDK
type ToolCall ¶
type ToolCall = openai.ChatCompletionMessageFunctionToolCall
Response types aliased from OpenAI SDK