Refactor codebase

This commit is contained in:
Luis Pater
2025-08-22 01:31:12 +08:00
parent 2b1762be16
commit 8c555c4e69
109 changed files with 7319 additions and 5735 deletions

View File

@@ -0,0 +1,17 @@
// Package interfaces defines the core interfaces and shared structures for the CLI Proxy API server.
// These interfaces provide a common contract for different components of the application,
// such as AI service clients, API handlers, and data models.
package interfaces
// APIHandler defines the interface that all API handlers must implement.
// This interface provides methods for identifying handler types and retrieving
// supported models for different AI service endpoints.
type APIHandler interface {
// HandlerType returns the type identifier for this API handler.
// This is used to determine which request/response translators to use.
HandlerType() string
// Models returns a list of supported models for this API handler.
// Each model is represented as a map containing model metadata.
Models() []map[string]any
}

View File

@@ -0,0 +1,54 @@
// Package interfaces defines the core interfaces and shared structures for the CLI Proxy API server.
// These interfaces provide a common contract for different components of the application,
// such as AI service clients, API handlers, and data models.
package interfaces
import (
"context"
"sync"
)
// Client defines the interface that all AI API clients must implement.
// This interface provides methods for interacting with various AI services
// including sending messages, streaming responses, and managing authentication.
type Client interface {
// Type returns the client type identifier (e.g., "gemini", "claude").
Type() string
// GetRequestMutex returns the mutex used to synchronize requests for this client.
// This ensures that only one request is processed at a time for quota management.
GetRequestMutex() *sync.Mutex
// GetUserAgent returns the User-Agent string used for HTTP requests.
GetUserAgent() string
// SendRawMessage sends a raw JSON message to the AI service without translation.
// This method is used when the request is already in the service's native format.
SendRawMessage(ctx context.Context, modelName string, rawJSON []byte, alt string) ([]byte, *ErrorMessage)
// SendRawMessageStream sends a raw JSON message and returns streaming responses.
// Similar to SendRawMessage but for streaming responses.
SendRawMessageStream(ctx context.Context, modelName string, rawJSON []byte, alt string) (<-chan []byte, <-chan *ErrorMessage)
// SendRawTokenCount sends a token count request to the AI service.
// This method is used to estimate the number of tokens in a given text.
SendRawTokenCount(ctx context.Context, modelName string, rawJSON []byte, alt string) ([]byte, *ErrorMessage)
// SaveTokenToFile saves the client's authentication token to a file.
// This is used for persisting authentication state between sessions.
SaveTokenToFile() error
// IsModelQuotaExceeded checks if the specified model has exceeded its quota.
// This helps with load balancing and automatic failover to alternative models.
IsModelQuotaExceeded(model string) bool
// GetEmail returns the email associated with the client's authentication.
// This is used for logging and identification purposes.
GetEmail() string
// CanProvideModel checks if the client can provide the specified model.
CanProvideModel(modelName string) bool
// Provider returns the name of the AI service provider (e.g., "gemini", "claude").
Provider() string
}

View File

@@ -0,0 +1,150 @@
// Package interfaces defines the core interfaces and shared structures for the CLI Proxy API server.
// These interfaces provide a common contract for different components of the application,
// such as AI service clients, API handlers, and data models.
package interfaces
import (
"time"
)
// GCPProject represents the response structure for a Google Cloud project list request.
// This structure is used when fetching available projects for a Google Cloud account.
type GCPProject struct {
// Projects is a list of Google Cloud projects accessible by the user.
Projects []GCPProjectProjects `json:"projects"`
}
// GCPProjectLabels defines the labels associated with a GCP project.
// These labels can contain metadata about the project's purpose or configuration.
type GCPProjectLabels struct {
// GenerativeLanguage indicates if the project has generative language APIs enabled.
GenerativeLanguage string `json:"generative-language"`
}
// GCPProjectProjects contains details about a single Google Cloud project.
// This includes identifying information, metadata, and configuration details.
type GCPProjectProjects struct {
// ProjectNumber is the unique numeric identifier for the project.
ProjectNumber string `json:"projectNumber"`
// ProjectID is the unique string identifier for the project.
ProjectID string `json:"projectId"`
// LifecycleState indicates the current state of the project (e.g., "ACTIVE").
LifecycleState string `json:"lifecycleState"`
// Name is the human-readable name of the project.
Name string `json:"name"`
// Labels contains metadata labels associated with the project.
Labels GCPProjectLabels `json:"labels"`
// CreateTime is the timestamp when the project was created.
CreateTime time.Time `json:"createTime"`
}
// Content represents a single message in a conversation, with a role and parts.
// This structure models a message exchange between a user and an AI model.
type Content struct {
// Role indicates who sent the message ("user", "model", or "tool").
Role string `json:"role"`
// Parts is a collection of content parts that make up the message.
Parts []Part `json:"parts"`
}
// Part represents a distinct piece of content within a message.
// A part can be text, inline data (like an image), a function call, or a function response.
type Part struct {
// Text contains plain text content.
Text string `json:"text,omitempty"`
// InlineData contains base64-encoded data with its MIME type (e.g., images).
InlineData *InlineData `json:"inlineData,omitempty"`
// FunctionCall represents a tool call requested by the model.
FunctionCall *FunctionCall `json:"functionCall,omitempty"`
// FunctionResponse represents the result of a tool execution.
FunctionResponse *FunctionResponse `json:"functionResponse,omitempty"`
}
// InlineData represents base64-encoded data with its MIME type.
// This is typically used for embedding images or other binary data in requests.
type InlineData struct {
// MimeType specifies the media type of the embedded data (e.g., "image/png").
MimeType string `json:"mime_type,omitempty"`
// Data contains the base64-encoded binary data.
Data string `json:"data,omitempty"`
}
// FunctionCall represents a tool call requested by the model.
// It includes the function name and its arguments that the model wants to execute.
type FunctionCall struct {
// Name is the identifier of the function to be called.
Name string `json:"name"`
// Args contains the arguments to pass to the function.
Args map[string]interface{} `json:"args"`
}
// FunctionResponse represents the result of a tool execution.
// This is sent back to the model after a tool call has been processed.
type FunctionResponse struct {
// Name is the identifier of the function that was called.
Name string `json:"name"`
// Response contains the result data from the function execution.
Response map[string]interface{} `json:"response"`
}
// GenerateContentRequest is the top-level request structure for the streamGenerateContent endpoint.
// This structure defines all the parameters needed for generating content from an AI model.
type GenerateContentRequest struct {
// SystemInstruction provides system-level instructions that guide the model's behavior.
SystemInstruction *Content `json:"systemInstruction,omitempty"`
// Contents is the conversation history between the user and the model.
Contents []Content `json:"contents"`
// Tools defines the available tools/functions that the model can call.
Tools []ToolDeclaration `json:"tools,omitempty"`
// GenerationConfig contains parameters that control the model's generation behavior.
GenerationConfig `json:"generationConfig"`
}
// GenerationConfig defines parameters that control the model's generation behavior.
// These parameters affect the creativity, randomness, and reasoning of the model's responses.
type GenerationConfig struct {
// ThinkingConfig specifies configuration for the model's "thinking" process.
ThinkingConfig GenerationConfigThinkingConfig `json:"thinkingConfig,omitempty"`
// Temperature controls the randomness of the model's responses.
// Values closer to 0 make responses more deterministic, while values closer to 1 increase randomness.
Temperature float64 `json:"temperature,omitempty"`
// TopP controls nucleus sampling, which affects the diversity of responses.
// It limits the model to consider only the top P% of probability mass.
TopP float64 `json:"topP,omitempty"`
// TopK limits the model to consider only the top K most likely tokens.
// This can help control the quality and diversity of generated text.
TopK float64 `json:"topK,omitempty"`
}
// GenerationConfigThinkingConfig specifies configuration for the model's "thinking" process.
// This controls whether the model should output its reasoning process along with the final answer.
type GenerationConfigThinkingConfig struct {
// IncludeThoughts determines whether the model should output its reasoning process.
// When enabled, the model will include its step-by-step thinking in the response.
IncludeThoughts bool `json:"include_thoughts,omitempty"`
}
// ToolDeclaration defines the structure for declaring tools (like functions)
// that the model can call during content generation.
type ToolDeclaration struct {
// FunctionDeclarations is a list of available functions that the model can call.
FunctionDeclarations []interface{} `json:"functionDeclarations"`
}

View File

@@ -0,0 +1,20 @@
// Package interfaces defines the core interfaces and shared structures for the CLI Proxy API server.
// These interfaces provide a common contract for different components of the application,
// such as AI service clients, API handlers, and data models.
package interfaces
import "net/http"
// ErrorMessage encapsulates an error with an associated HTTP status code.
// This structure is used to provide detailed error information including
// both the HTTP status and the underlying error.
type ErrorMessage struct {
// StatusCode is the HTTP status code returned by the API.
StatusCode int
// Error is the underlying error that occurred.
Error error
// Addon contains additional headers to be added to the response.
Addon http.Header
}

View File

@@ -0,0 +1,54 @@
// Package interfaces defines the core interfaces and shared structures for the CLI Proxy API server.
// These interfaces provide a common contract for different components of the application,
// such as AI service clients, API handlers, and data models.
package interfaces
import "context"
// TranslateRequestFunc defines a function type for translating API requests between different formats.
// It takes a model name, raw JSON request data, and a streaming flag, returning the translated request.
//
// Parameters:
// - string: The model name
// - []byte: The raw JSON request data
// - bool: A flag indicating whether the request is for streaming
//
// Returns:
// - []byte: The translated request data
type TranslateRequestFunc func(string, []byte, bool) []byte
// TranslateResponseFunc defines a function type for translating streaming API responses.
// It processes response data and returns an array of translated response strings.
//
// Parameters:
// - ctx: The context for the request
// - modelName: The model name
// - rawJSON: The raw JSON response data
// - param: Additional parameters for translation
//
// Returns:
// - []string: An array of translated response strings
type TranslateResponseFunc func(ctx context.Context, modelName string, rawJSON []byte, param *any) []string
// TranslateResponseNonStreamFunc defines a function type for translating non-streaming API responses.
// It processes response data and returns a single translated response string.
//
// Parameters:
// - ctx: The context for the request
// - modelName: The model name
// - rawJSON: The raw JSON response data
// - param: Additional parameters for translation
//
// Returns:
// - string: A single translated response string
type TranslateResponseNonStreamFunc func(ctx context.Context, modelName string, rawJSON []byte, param *any) string
// TranslateResponse contains both streaming and non-streaming response translation functions.
// This structure allows clients to handle both types of API responses appropriately.
type TranslateResponse struct {
// Stream handles streaming response translation.
Stream TranslateResponseFunc
// NonStream handles non-streaming response translation.
NonStream TranslateResponseNonStreamFunc
}