proxy

package
v0.11.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Overview

Package proxy implements HTTP handlers that forward requests to GitHub Copilot's backend. It provides Anthropic-to-OpenAI translation for the /v1/messages endpoint and near zero-copy passthrough for OpenAI endpoints.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultCompactUpstreamChunkBytes added in v0.10.3

func DefaultCompactUpstreamChunkBytes() int

DefaultCompactUpstreamChunkBytes is the default target body size for chunked /v1/responses/compact retries. Exposed so callers can show the default value in flag/env help text.

func DefaultCompactUpstreamChunkConcurrency added in v0.11.0

func DefaultCompactUpstreamChunkConcurrency() int

DefaultCompactUpstreamChunkConcurrency returns the default max parallelism for sibling chunk compaction calls after the first chunk succeeds.

func DefaultCompactUpstreamMaxAttempts added in v0.10.3

func DefaultCompactUpstreamMaxAttempts() int

DefaultCompactUpstreamMaxAttempts returns the default upstream attempt cap for chunked /v1/responses/compact 413 fallback retries.

func DefaultStreamingUpstreamTimeout

func DefaultStreamingUpstreamTimeout() time.Duration

DefaultStreamingUpstreamTimeout returns the default timeout used for streaming upstream inference requests.

func MapStopReason

func MapStopReason(finishReason *string) string

MapStopReason maps an OpenAI finish reason to an Anthropic stop reason.

func NormalizeModelName

func NormalizeModelName(model string) string

NormalizeModelName converts Anthropic model names to Copilot-compatible names.

func ResolveFilterHint added in v0.11.0

func ResolveFilterHint(command string) string

func StreamOpenAIPassthrough

func StreamOpenAIPassthrough(w http.ResponseWriter, body io.ReadCloser)

StreamOpenAIPassthrough streams OpenAI SSE bytes directly to the client.

func StreamOpenAIPassthroughWithFinalResponse added in v0.11.0

func StreamOpenAIPassthroughWithFinalResponse(
	w http.ResponseWriter,
	body io.ReadCloser,
	onFinalResponse func(*models.OpenAIResponse),
)

StreamOpenAIPassthroughWithFinalResponse streams OpenAI SSE lines to the client and optionally invokes onFinalResponse with the complete aggregated OpenAI response after the upstream stream terminates successfully with [DONE].

func StreamOpenAIToAnthropic

func StreamOpenAIToAnthropic(w http.ResponseWriter, body io.ReadCloser, model string, requestID string)

StreamOpenAIToAnthropic translates an OpenAI SSE stream into Anthropic SSE format.

func StreamOpenAIToAnthropicWithFinalResponse added in v0.11.0

func StreamOpenAIToAnthropicWithFinalResponse(
	w http.ResponseWriter,
	body io.ReadCloser,
	model string,
	requestID string,
	onFinalResponse func(*models.OpenAIResponse),
)

StreamOpenAIToAnthropicWithFinalResponse translates an OpenAI SSE stream into Anthropic SSE format and optionally invokes onFinalResponse with the complete aggregated OpenAI response after the translated stream finishes successfully.

func StreamOpenAIToGemini

func StreamOpenAIToGemini(w http.ResponseWriter, body io.ReadCloser)

StreamOpenAIToGemini translates upstream OpenAI SSE into Gemini-style data-only SSE frames.

func StreamOpenAIToGeminiWithFinalResponse added in v0.11.0

func StreamOpenAIToGeminiWithFinalResponse(
	w http.ResponseWriter,
	body io.ReadCloser,
	onFinalResponse func(*models.OpenAIResponse),
)

StreamOpenAIToGeminiWithFinalResponse translates upstream OpenAI SSE into Gemini-style data-only SSE frames and optionally invokes onFinalResponse with the complete aggregated OpenAI response after the translated stream finishes successfully.

func TranslateAnthropicToOpenAI

func TranslateAnthropicToOpenAI(req *models.AnthropicRequest) (*models.OpenAIRequest, error)

TranslateAnthropicToOpenAI converts an Anthropic Messages API request to OpenAI Chat Completions format.

func TranslateGeminiCountTokens

func TranslateGeminiCountTokens(req *models.GeminiCountTokensRequest, pathModel string) (*models.OpenAIRequest, error)

func TranslateGeminiToOpenAI

func TranslateGeminiToOpenAI(req *models.GeminiGenerateContentRequest, pathModel string, stream bool) (*models.OpenAIRequest, error)

func TranslateOpenAIToAnthropic

func TranslateOpenAIToAnthropic(resp *models.OpenAIResponse, model string) *models.AnthropicResponse

TranslateOpenAIToAnthropic translates an OpenAI Chat Completions response to Anthropic Messages format.

Types

type CopilotHeaderConfig

type CopilotHeaderConfig struct {
	EditorVersion       string `json:"editor_version,omitempty" yaml:"editor_version,omitempty"`
	EditorPluginVersion string `json:"editor_plugin_version,omitempty" yaml:"editor_plugin_version,omitempty"`
	UserAgent           string `json:"user_agent,omitempty" yaml:"user_agent,omitempty"`
	IntegrationID       string `json:"copilot_integration_id,omitempty" yaml:"copilot_integration_id,omitempty"`
	GitHubAPIVersion    string `json:"github_api_version,omitempty" yaml:"github_api_version,omitempty"`
	OpenAIIntent        string `json:"openai_intent,omitempty" yaml:"openai_intent,omitempty"`
}

CopilotHeaderConfig controls the synthetic editor-identifying headers sent to the upstream Copilot backend. Empty fields fall back to project defaults.

func DefaultCopilotHeaderConfig

func DefaultCopilotHeaderConfig() CopilotHeaderConfig

type CopilotHeaderProfilesConfig added in v0.10.6

type CopilotHeaderProfilesConfig struct {
	Default         CopilotHeaderConfig `json:"default,omitempty" yaml:"default,omitempty"`
	ChatCompletions CopilotHeaderConfig `json:"chat_completions,omitempty" yaml:"chat_completions,omitempty"`
	Responses       CopilotHeaderConfig `json:"responses,omitempty" yaml:"responses,omitempty"`
}

CopilotHeaderProfilesConfig allows provider config to override Copilot header profiles globally for the provider or for a specific upstream endpoint. Empty fields inherit from the provider default profile and then the project defaults.

type Option

type Option func(*ProxyHandler)

Option customizes ProxyHandler behavior.

func WithCompactUpstreamChunkBytes added in v0.10.3

func WithCompactUpstreamChunkBytes(bytes int) Option

WithCompactUpstreamChunkBytes overrides the initial target body size used when retrying /v1/responses/compact requests after the upstream returns 413. Non-positive values fall back to the default. The chunker still halves the target down to compactUpstreamChunkBodyFloor on recursive 413s.

func WithCompactUpstreamChunkConcurrency added in v0.11.0

func WithCompactUpstreamChunkConcurrency(concurrency int) Option

WithCompactUpstreamChunkConcurrency overrides the maximum number of sibling compact chunks sent concurrently after the first chunk succeeds at the current target. Non-positive values fall back to the default.

func WithCompactUpstreamMaxAttempts added in v0.10.3

func WithCompactUpstreamMaxAttempts(max int) Option

WithCompactUpstreamMaxAttempts caps the total number of logical compaction calls the /v1/responses/compact 413 fallback may make for a single inbound request. Each logical call may produce extra real upstream POSTs through model fallback or the shared transport-retry policy. Non-positive values fall back to the default.

func WithCopilotBaseURL added in v0.10.8

func WithCopilotBaseURL(baseURL string) Option

WithCopilotBaseURL overrides the legacy single-upstream Copilot base URL. It is primarily useful for local contract tests and diagnostic harnesses.

func WithCopilotHeaderConfig

func WithCopilotHeaderConfig(cfg CopilotHeaderConfig) Option

WithCopilotHeaderConfig overrides the synthetic Copilot-identifying headers used for upstream requests. The raw override values are retained so endpoint- scoped header logic can distinguish an explicitly configured OpenAI intent from the built-in chat/responses default.

func WithProvidersConfig added in v0.9.0

func WithProvidersConfig(cfg ProvidersConfig) Option

WithProvidersConfig enables multi-provider model routing. When unset, the proxy keeps its legacy single-upstream Copilot behavior.

func WithResponsesWebSocketConfig

func WithResponsesWebSocketConfig(cfg ResponsesWebSocketConfig) Option

WithResponsesWebSocketConfig overrides websocket-session state behavior for GET /v1/responses Codex clients.

func WithStreamingUpstreamTimeout

func WithStreamingUpstreamTimeout(timeout time.Duration) Option

WithStreamingUpstreamTimeout overrides the timeout used for streaming upstream inference requests. Non-positive values fall back to the default.

type ProviderConfig added in v0.9.0

type ProviderConfig struct {
	ID            string                      `json:"id" yaml:"id"`
	Type          string                      `json:"type" yaml:"type"`
	Default       bool                        `json:"default,omitempty" yaml:"default,omitempty"`
	IncludeModels []string                    `json:"include_models,omitempty" yaml:"include_models,omitempty"`
	ExcludeModels []string                    `json:"exclude_models,omitempty" yaml:"exclude_models,omitempty"`
	BaseURL       string                      `json:"base_url,omitempty" yaml:"base_url,omitempty"`
	APIKey        string                      `json:"api_key,omitempty" yaml:"api_key,omitempty"`
	APIKeyEnv     string                      `json:"api_key_env,omitempty" yaml:"api_key_env,omitempty"`
	APIVersion    string                      `json:"api_version,omitempty" yaml:"api_version,omitempty"`
	Headers       CopilotHeaderProfilesConfig `json:"headers,omitempty" yaml:"headers,omitempty"`
	Models        []ProviderModelConfig       `json:"models,omitempty" yaml:"models,omitempty"`
}

ProviderConfig configures one upstream provider instance.

type ProviderModelConfig added in v0.9.0

type ProviderModelConfig struct {
	PublicID            string   `json:"public_id" yaml:"public_id"`
	Deployment          string   `json:"deployment,omitempty" yaml:"deployment,omitempty"`
	Name                string   `json:"name,omitempty" yaml:"name,omitempty"`
	Endpoints           []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
	ModelPickerEnabled  *bool    `json:"model_picker_enabled,omitempty" yaml:"model_picker_enabled,omitempty"`
	ModelPickerCategory string   `json:"model_picker_category,omitempty" yaml:"model_picker_category,omitempty"`
	ReasoningEffort     []string `json:"reasoning_effort,omitempty" yaml:"reasoning_effort,omitempty"`
	Vision              *bool    `json:"vision,omitempty" yaml:"vision,omitempty"`
	ParallelToolCalls   *bool    `json:"parallel_tool_calls,omitempty" yaml:"parallel_tool_calls,omitempty"`
	ContextWindow       *int64   `json:"context_window,omitempty" yaml:"context_window,omitempty"`
}

ProviderModelConfig maps a public model ID exposed by this proxy to the upstream model or deployment name used by the provider.

type ProvidersConfig added in v0.9.0

type ProvidersConfig struct {
	Providers      []ProviderConfig     `json:"providers" yaml:"providers"`
	ToolOptimizers ToolOptimizersConfig `json:"tool_optimizers,omitempty" yaml:"tool_optimizers,omitempty"`
}

ProvidersConfig configures optional non-Copilot upstream providers. When empty, the proxy keeps its legacy zero-config Copilot behavior.

func LoadProvidersConfigFile added in v0.9.0

func LoadProvidersConfigFile(path string) (ProvidersConfig, error)

func (ProvidersConfig) UsesCopilot added in v0.9.0

func (c ProvidersConfig) UsesCopilot() bool

type ProxyHandler

type ProxyHandler struct {
	// contains filtered or unexported fields
}

ProxyHandler holds dependencies for all HTTP handlers.

func NewProxyHandler

func NewProxyHandler(a *auth.Authenticator, log *logger.Logger, opts ...Option) (*ProxyHandler, error)

NewProxyHandler creates a ProxyHandler with connection pooling and HTTP/2.

func (*ProxyHandler) HandleAnthropicMessages

func (h *ProxyHandler) HandleAnthropicMessages(w http.ResponseWriter, r *http.Request)

HandleAnthropicMessages handles POST /v1/messages by translating the Anthropic request to OpenAI format, forwarding to Copilot, and translating the response back.

func (*ProxyHandler) HandleCompact

func (h *ProxyHandler) HandleCompact(w http.ResponseWriter, r *http.Request)

HandleCompact handles POST /v1/responses/compact by forwarding the request to the upstream /responses endpoint with a compaction system prompt injected. The upstream response is then transformed into the compact response format that Codex expects. The returned compaction item is a proxy-owned token that this proxy can later expand back into summarized context for /responses.

func (*ProxyHandler) HandleGeminiModels

func (h *ProxyHandler) HandleGeminiModels(w http.ResponseWriter, r *http.Request)

HandleGeminiModels routes Gemini-native model actions to the corresponding translation handler.

func (*ProxyHandler) HandleHealthz

func (h *ProxyHandler) HandleHealthz(w http.ResponseWriter, r *http.Request)

HandleHealthz handles GET /healthz and returns {"status":"ok"}.

func (*ProxyHandler) HandleMemorySummarize

func (h *ProxyHandler) HandleMemorySummarize(w http.ResponseWriter, r *http.Request)

HandleMemorySummarize handles POST /v1/memories/trace_summarize by sending the traces to the upstream /responses endpoint with a summarization prompt, then transforming the response into the format Codex expects.

func (*ProxyHandler) HandleModels

func (h *ProxyHandler) HandleModels(w http.ResponseWriter, r *http.Request)

HandleModels handles GET /v1/models by building a merged model catalog across the configured providers. Responses are cached for modelsCacheTTL to avoid repeated upstream calls.

func (*ProxyHandler) HandleOpenAIChatCompletions

func (h *ProxyHandler) HandleOpenAIChatCompletions(w http.ResponseWriter, r *http.Request)

HandleOpenAIChatCompletions handles POST /v1/chat/completions by forwarding the request to Copilot with only auth headers injected (near zero-copy passthrough).

func (*ProxyHandler) HandleReadyz

func (h *ProxyHandler) HandleReadyz(w http.ResponseWriter, r *http.Request)

HandleReadyz validates that the proxy can obtain an auth token and reach the configured upstream providers.

func (*ProxyHandler) HandleResponses

func (h *ProxyHandler) HandleResponses(w http.ResponseWriter, r *http.Request)

HandleResponses handles POST /v1/responses by forwarding the request to Copilot's responses endpoint with only auth headers injected.

func (*ProxyHandler) HandleResponsesWebSocket

func (h *ProxyHandler) HandleResponsesWebSocket(w http.ResponseWriter, r *http.Request)

HandleResponsesWebSocket handles GET /v1/responses websocket upgrades used by Codex. Each websocket request is translated into a normal upstream streaming /responses HTTP request and the SSE data payloads are forwarded back as websocket text frames.

func (*ProxyHandler) ServerWriteTimeout

func (h *ProxyHandler) ServerWriteTimeout() time.Duration

ServerWriteTimeout returns the HTTP server write timeout derived from the configured streaming upstream timeout plus the non-streaming request budget.

type ResponsesWebSocketConfig

type ResponsesWebSocketConfig struct {
	Enabled             bool
	TurnStateDelta      bool
	DisableAutoCompact  bool
	AutoCompactMaxItems int
	AutoCompactMaxBytes int
	AutoCompactKeepTail int
}

ResponsesWebSocketConfig controls websocket-session state management for Codex-style GET /v1/responses clients.

func DefaultResponsesWebSocketConfig

func DefaultResponsesWebSocketConfig() ResponsesWebSocketConfig

type ToolCommandRewriteRequest added in v0.11.0

type ToolCommandRewriteRequest struct {
	ToolName string
	CallID   string
	Command  string
	Metadata map[string]string
}

type ToolCommandRewriteResult added in v0.11.0

type ToolCommandRewriteResult struct {
	Changed  bool
	Command  string
	Provider string
	Reason   string
}

type ToolExecutionContext added in v0.11.0

type ToolExecutionContext struct {
	CallID           string
	ToolName         string
	OriginalCommand  string
	RewrittenCommand string
	RewriteProvider  string
	FilterHint       string
	CreatedAt        time.Time
}

type ToolExecutionContextStore added in v0.11.0

type ToolExecutionContextStore struct {
	// contains filtered or unexported fields
}

func NewToolExecutionContextStore added in v0.11.0

func NewToolExecutionContextStore() *ToolExecutionContextStore

func NewToolExecutionContextStoreWithLimits added in v0.11.0

func NewToolExecutionContextStoreWithLimits(ttl time.Duration, maxEntries int) *ToolExecutionContextStore

func (*ToolExecutionContextStore) Delete added in v0.11.0

func (s *ToolExecutionContextStore) Delete(scope, callID string)

func (*ToolExecutionContextStore) Get added in v0.11.0

func (s *ToolExecutionContextStore) Get(scope, callID string) (ToolExecutionContext, bool)

func (*ToolExecutionContextStore) Put added in v0.11.0

type ToolOptimizer added in v0.11.0

type ToolOptimizerManager added in v0.11.0

type ToolOptimizerManager struct {
	// contains filtered or unexported fields
}

func NewToolOptimizerManager added in v0.11.0

func NewToolOptimizerManager(cfg ToolOptimizersConfig, providers []stagedToolOptimizer) *ToolOptimizerManager

func (*ToolOptimizerManager) CommandRewriteEnabled added in v0.11.0

func (m *ToolOptimizerManager) CommandRewriteEnabled() bool

func (*ToolOptimizerManager) Enabled added in v0.11.0

func (m *ToolOptimizerManager) Enabled() bool

func (*ToolOptimizerManager) MatchShellToolName added in v0.11.0

func (m *ToolOptimizerManager) MatchShellToolName(name string) bool

func (*ToolOptimizerManager) OutputReduceEnabled added in v0.11.0

func (m *ToolOptimizerManager) OutputReduceEnabled() bool

func (*ToolOptimizerManager) ReduceOutput added in v0.11.0

func (*ToolOptimizerManager) RewriteCommand added in v0.11.0

func (*ToolOptimizerManager) ShellCommandArgPath added in v0.11.0

func (m *ToolOptimizerManager) ShellCommandArgPath() string

func (*ToolOptimizerManager) ShellFunctionCallsEnabled added in v0.11.0

func (m *ToolOptimizerManager) ShellFunctionCallsEnabled() bool

func (*ToolOptimizerManager) ShouldInspectNonStreamingResponses added in v0.11.0

func (m *ToolOptimizerManager) ShouldInspectNonStreamingResponses() bool

type ToolOptimizerOutputConfig added in v0.11.0

type ToolOptimizerOutputConfig struct {
	Enabled       bool `json:"enabled" yaml:"enabled"`
	TimeoutMS     int  `json:"timeout_ms,omitempty" yaml:"timeout_ms,omitempty"`
	MinInputBytes int  `json:"min_input_bytes,omitempty" yaml:"min_input_bytes,omitempty"`
	MaxInputBytes int  `json:"max_input_bytes,omitempty" yaml:"max_input_bytes,omitempty"`
	// contains filtered or unexported fields
}

func (*ToolOptimizerOutputConfig) UnmarshalJSON added in v0.11.0

func (c *ToolOptimizerOutputConfig) UnmarshalJSON(data []byte) error

func (*ToolOptimizerOutputConfig) UnmarshalYAML added in v0.11.0

func (c *ToolOptimizerOutputConfig) UnmarshalYAML(value *yaml.Node) error

type ToolOptimizerProviderConfig added in v0.11.0

type ToolOptimizerProviderConfig struct {
	ID             string   `json:"id" yaml:"id"`
	Type           string   `json:"type" yaml:"type"`
	Enabled        *bool    `json:"enabled,omitempty" yaml:"enabled,omitempty"`
	Path           string   `json:"path,omitempty" yaml:"path,omitempty"`
	Args           []string `json:"args,omitempty" yaml:"args,omitempty"`
	Stages         []string `json:"stages,omitempty" yaml:"stages,omitempty"`
	MaxStdoutBytes int      `json:"max_stdout_bytes,omitempty" yaml:"max_stdout_bytes,omitempty"`
	MaxStderrBytes int      `json:"max_stderr_bytes,omitempty" yaml:"max_stderr_bytes,omitempty"`
}

type ToolOptimizerRewriteConfig added in v0.11.0

type ToolOptimizerRewriteConfig struct {
	Enabled       bool   `json:"enabled" yaml:"enabled"`
	StreamingMode string `json:"streaming_mode,omitempty" yaml:"streaming_mode,omitempty"`
	TimeoutMS     int    `json:"timeout_ms,omitempty" yaml:"timeout_ms,omitempty"`
}

type ToolOptimizerShellFunctionCallsConfig added in v0.11.0

type ToolOptimizerShellFunctionCallsConfig struct {
	Enabled        *bool    `json:"enabled,omitempty" yaml:"enabled,omitempty"`
	Names          []string `json:"names,omitempty" yaml:"names,omitempty"`
	CommandArgPath string   `json:"command_arg_path,omitempty" yaml:"command_arg_path,omitempty"`
}

type ToolOptimizerToolsConfig added in v0.11.0

type ToolOptimizerToolsConfig struct {
	ShellFunctionCalls ToolOptimizerShellFunctionCallsConfig `json:"shell_function_calls,omitempty" yaml:"shell_function_calls,omitempty"`
}

type ToolOptimizersConfig added in v0.11.0

type ToolOptimizersConfig struct {
	Enabled        bool                          `json:"enabled" yaml:"enabled"`
	Tools          ToolOptimizerToolsConfig      `json:"tools,omitempty" yaml:"tools,omitempty"`
	CommandRewrite ToolOptimizerRewriteConfig    `json:"command_rewrite,omitempty" yaml:"command_rewrite,omitempty"`
	OutputReduce   ToolOptimizerOutputConfig     `json:"output_reduce,omitempty" yaml:"output_reduce,omitempty"`
	Providers      []ToolOptimizerProviderConfig `json:"providers,omitempty" yaml:"providers,omitempty"`
}

ToolOptimizersConfig configures optional command/output optimization for tool calls flowing through supported API surfaces. The feature is intentionally disabled by default; zero values preserve the legacy passthrough behavior.

type ToolOutputReduceRequest added in v0.11.0

type ToolOutputReduceRequest struct {
	ToolName   string
	CallID     string
	Command    string
	FilterHint string
	Output     string
	Metadata   map[string]string
}

type ToolOutputReduceResult added in v0.11.0

type ToolOutputReduceResult struct {
	Changed  bool
	Output   string
	Provider string
	Reason   string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL