first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

593
ui/lib/types/config.ts Normal file
View File

@@ -0,0 +1,593 @@
// Configuration types that match the Go backend structures
import { KnownProvidersNames } from "@/lib/constants/logs";
import { EnvVar } from "./schemas";
// Known provider names - all supported standard providers
export type KnownProvider = (typeof KnownProvidersNames)[number];
// Base provider names - all supported base providers
export type BaseProvider = "openai" | "anthropic" | "cohere" | "gemini" | "bedrock" | "replicate" | "fireworks";
// Branded type for custom provider names to prevent collision with known providers
export type CustomProviderName = string & { readonly __brand: "CustomProviderName" };
// ModelProvider union - either known providers or branded custom providers
export type ModelProviderName = KnownProvider | CustomProviderName;
// Helper function to check if a provider name is a known provider
export const isKnownProvider = (provider: string): provider is KnownProvider => {
return KnownProvidersNames.includes(provider.toLowerCase() as KnownProvider);
};
// AzureKeyConfig matching Go's schemas.AzureKeyConfig
export interface AzureKeyConfig {
endpoint: EnvVar;
api_version?: EnvVar;
client_id?: EnvVar;
client_secret?: EnvVar;
tenant_id?: EnvVar;
scopes?: string[];
}
export const DefaultAzureKeyConfig: AzureKeyConfig = {
endpoint: { value: "", env_var: "", from_env: false },
api_version: { value: "2024-02-01", env_var: "", from_env: false },
client_id: { value: "", env_var: "", from_env: false },
client_secret: { value: "", env_var: "", from_env: false },
tenant_id: { value: "", env_var: "", from_env: false },
scopes: [],
} as const satisfies Required<AzureKeyConfig>;
// VertexKeyConfig matching Go's schemas.VertexKeyConfig
export interface VertexKeyConfig {
project_id: EnvVar;
project_number?: EnvVar;
region: EnvVar;
auth_credentials?: EnvVar;
}
export const DefaultVertexKeyConfig: VertexKeyConfig = {
project_id: { value: "", env_var: "", from_env: false },
project_number: { value: "", env_var: "", from_env: false },
region: { value: "", env_var: "", from_env: false },
auth_credentials: { value: "", env_var: "", from_env: false },
} as const satisfies Required<VertexKeyConfig>;
export interface S3BucketConfig {
bucket_name: string;
prefix?: string;
is_default?: boolean;
}
export interface BatchS3Config {
buckets?: S3BucketConfig[];
}
// BedrockKeyConfig matching Go's schemas.BedrockKeyConfig
export interface BedrockKeyConfig {
access_key?: EnvVar;
secret_key?: EnvVar;
session_token?: EnvVar;
region?: EnvVar;
arn?: EnvVar;
batch_s3_config?: BatchS3Config;
}
// Default BedrockKeyConfig
export const DefaultBedrockKeyConfig: BedrockKeyConfig = {
access_key: { value: "", env_var: "", from_env: false },
secret_key: { value: "", env_var: "", from_env: false },
session_token: undefined as unknown as EnvVar,
region: { value: "us-east-1", env_var: "", from_env: false },
arn: { value: "", env_var: "", from_env: false },
batch_s3_config: undefined as unknown as BatchS3Config,
} as const satisfies Required<BedrockKeyConfig>;
// VLLMKeyConfig matching Go's schemas.VLLMKeyConfig
export interface VLLMKeyConfig {
url: EnvVar;
model_name: string;
}
// Default VLLMKeyConfig
export const DefaultVLLMKeyConfig: VLLMKeyConfig = {
url: { value: "", env_var: "", from_env: false },
model_name: "",
} as const satisfies Required<VLLMKeyConfig>;
// ReplicateKeyConfig matching Go's schemas.ReplicateKeyConfig
export interface ReplicateKeyConfig {
use_deployments_endpoint: boolean;
}
// Default ReplicateKeyConfig
export const DefaultReplicateKeyConfig: ReplicateKeyConfig = {
use_deployments_endpoint: false,
} as const satisfies Required<ReplicateKeyConfig>;
// OllamaKeyConfig matching Go's schemas.OllamaKeyConfig
export interface OllamaKeyConfig {
url: EnvVar;
}
// Default OllamaKeyConfig
export const DefaultOllamaKeyConfig: OllamaKeyConfig = {
url: { value: "", env_var: "", from_env: false },
} as const satisfies Required<OllamaKeyConfig>;
// SGLKeyConfig matching Go's schemas.SGLKeyConfig
export interface SGLKeyConfig {
url: EnvVar;
}
// Default SGLKeyConfig
export const DefaultSGLKeyConfig: SGLKeyConfig = {
url: { value: "", env_var: "", from_env: false },
} as const satisfies Required<SGLKeyConfig>;
// Key structure matching Go's schemas.Key
export interface ModelProviderKey {
id: string;
name: string;
value?: EnvVar;
models?: string[];
blacklisted_models?: string[];
weight: number;
enabled?: boolean;
use_for_batch_api?: boolean;
aliases?: Record<string, string>;
azure_key_config?: AzureKeyConfig;
vertex_key_config?: VertexKeyConfig;
bedrock_key_config?: BedrockKeyConfig;
vllm_key_config?: VLLMKeyConfig;
replicate_key_config?: ReplicateKeyConfig;
ollama_key_config?: OllamaKeyConfig;
sgl_key_config?: SGLKeyConfig;
config_hash?: string; // Present when config is synced from config.json
status?: "unknown" | "success" | "list_models_failed";
description?: string;
}
// Default ModelProviderKey
export const DefaultModelProviderKey: ModelProviderKey = {
id: "",
name: "",
value: {
value: "",
env_var: "",
from_env: false,
},
models: [],
blacklisted_models: [],
weight: 1.0,
enabled: true,
};
// NetworkConfig matching Go's schemas.NetworkConfig
export interface NetworkConfig {
base_url?: string;
is_key_less?: boolean;
extra_headers?: Record<string, string>;
default_request_timeout_in_seconds: number;
max_retries: number;
retry_backoff_initial: number; // Duration in milliseconds
retry_backoff_max: number; // Duration in milliseconds
insecure_skip_verify?: boolean;
ca_cert_pem?: string;
stream_idle_timeout_in_seconds?: number;
max_conns_per_host?: number;
enforce_http2?: boolean;
beta_header_overrides?: Record<string, boolean>;
}
// ConcurrencyAndBufferSize matching Go's schemas.ConcurrencyAndBufferSize
export interface ConcurrencyAndBufferSize {
concurrency: number;
buffer_size: number;
}
// Proxy types matching Go's schemas.ProxyType
export type ProxyType = "none" | "http" | "socks5" | "environment";
// ProxyConfig matching Go's schemas.ProxyConfig
export interface ProxyConfig {
type: ProxyType;
url?: string;
username?: string;
password?: string;
ca_cert_pem?: string;
}
// Request types matching Go's schemas.RequestType
export type RequestType =
| "list_models"
| "text_completion"
| "text_completion_stream"
| "chat_completion"
| "chat_completion_stream"
| "responses"
| "responses_stream"
| "embedding"
| "rerank"
| "speech"
| "speech_stream"
| "transcription"
| "transcription_stream"
| "image_generation"
| "image_generation_stream"
| "image_edit"
| "image_edit_stream"
| "image_variation"
| "ocr"
| "ocr_stream"
| "video_generation"
| "video_retrieve"
| "video_download"
| "video_delete"
| "video_list"
| "video_remix"
| "count_tokens"
| "batch_create"
| "batch_list"
| "batch_retrieve"
| "batch_cancel"
| "batch_results"
| "file_upload"
| "file_list"
| "file_retrieve"
| "file_delete"
| "file_content"
| "mcp_tool_execution"
| "container_create"
| "container_list"
| "container_retrieve"
| "container_delete"
| "container_file_create"
| "container_file_list"
| "container_file_retrieve"
| "container_file_content"
| "container_file_delete"
| "websocket_responses"
| "realtime";
// AllowedRequests matching Go's schemas.AllowedRequests
export interface AllowedRequests {
text_completion: boolean;
text_completion_stream: boolean;
chat_completion: boolean;
chat_completion_stream: boolean;
responses: boolean;
responses_stream: boolean;
embedding: boolean;
speech: boolean;
speech_stream: boolean;
transcription: boolean;
transcription_stream: boolean;
image_generation: boolean;
image_generation_stream: boolean;
image_edit: boolean;
image_edit_stream: boolean;
image_variation: boolean;
ocr: boolean;
ocr_stream: boolean;
count_tokens: boolean;
list_models: boolean;
rerank: boolean;
video_generation: boolean;
video_retrieve: boolean;
video_download: boolean;
video_delete: boolean;
video_list: boolean;
video_remix: boolean;
websocket_responses: boolean;
realtime: boolean;
}
// CustomProviderConfig matching Go's schemas.CustomProviderConfig
export interface CustomProviderConfig {
base_provider_type: KnownProvider;
is_key_less?: boolean;
allowed_requests?: AllowedRequests;
request_path_overrides?: Record<string, string>;
}
// OpenAIConfig holds OpenAI-specific provider configuration.
export interface OpenAIConfig {
disable_store?: boolean;
}
// ProviderConfig matching Go's lib.ProviderConfig
export interface ModelProviderConfig {
network_config?: NetworkConfig;
concurrency_and_buffer_size?: ConcurrencyAndBufferSize;
proxy_config?: ProxyConfig;
send_back_raw_request?: boolean;
send_back_raw_response?: boolean;
store_raw_request_response?: boolean;
custom_provider_config?: CustomProviderConfig;
openai_config?: OpenAIConfig;
status?: "unknown" | "success" | "list_models_failed";
description?: string;
}
// ProviderResponse matching Go's ProviderResponse
export interface ModelProvider extends ModelProviderConfig {
name: ModelProviderName;
provider_status: ProviderStatus;
config_hash?: string; // Present when config is synced from config.json
}
// ListProvidersResponse matching Go's ListProvidersResponse
export interface ListProvidersResponse {
providers?: ModelProvider[];
total: number;
}
// AddProviderRequest matching Go's AddProviderRequest
export interface AddProviderRequest {
provider: ModelProviderName;
network_config?: NetworkConfig;
concurrency_and_buffer_size?: ConcurrencyAndBufferSize;
proxy_config?: ProxyConfig;
send_back_raw_request?: boolean;
send_back_raw_response?: boolean;
store_raw_request_response?: boolean;
custom_provider_config?: CustomProviderConfig;
openai_config?: OpenAIConfig;
}
// UpdateProviderRequest matching Go's UpdateProviderRequest
export interface UpdateProviderRequest {
network_config: NetworkConfig;
concurrency_and_buffer_size: ConcurrencyAndBufferSize;
proxy_config?: ProxyConfig;
send_back_raw_request?: boolean;
send_back_raw_response?: boolean;
store_raw_request_response?: boolean;
custom_provider_config?: CustomProviderConfig;
openai_config?: OpenAIConfig;
}
export interface CreateProviderKeyRequest extends ModelProviderKey {}
export interface UpdateProviderKeyRequest extends ModelProviderKey {}
export interface ListProviderKeysResponse {
keys: ModelProviderKey[];
total: number;
}
// BifrostErrorResponse matching Go's schemas.BifrostError
export interface BifrostErrorResponse {
event_id?: string;
type?: string;
is_bifrost_error: boolean;
status_code?: number;
error: {
message: string;
type?: string;
code?: string;
param?: string;
};
}
// LatestReleaseResponse matching Go's LatestReleaseResponse
export interface LatestReleaseResponse {
name: string;
changelogUrl: string;
}
export interface FrameworkConfig {
id: number;
pricing_url: string;
pricing_sync_interval: number;
}
// Auth config
export interface AuthConfig {
admin_username: EnvVar;
admin_password: EnvVar;
is_enabled: boolean;
disable_auth_on_inference?: boolean;
}
// Global proxy type (for global proxy configuration, not per-provider)
export type GlobalProxyType = "http" | "socks5" | "tcp";
// Global proxy configuration matching Go's tables.GlobalProxyConfig
export interface GlobalProxyConfig {
enabled: boolean;
type: GlobalProxyType;
url: string;
username?: string;
password?: string;
ca_cert_pem?: string;
no_proxy?: string;
timeout?: number;
skip_tls_verify?: boolean;
enable_for_scim: boolean;
enable_for_inference: boolean;
enable_for_api: boolean;
}
// Default GlobalProxyConfig
export const DefaultGlobalProxyConfig: GlobalProxyConfig = {
enabled: false,
type: "http",
url: "",
username: "",
password: "",
no_proxy: "",
timeout: 30,
skip_tls_verify: false,
enable_for_scim: false,
enable_for_inference: false,
enable_for_api: false,
};
// Global header filter configuration matching Go's tables.GlobalHeaderFilterConfig
// Controls which headers with the x-bf-eh-* prefix are forwarded to LLM providers
export interface GlobalHeaderFilterConfig {
allowlist?: string[]; // If non-empty, only these headers are allowed
denylist?: string[]; // Headers to always block
}
// Default GlobalHeaderFilterConfig
export const DefaultGlobalHeaderFilterConfig: GlobalHeaderFilterConfig = {
allowlist: [],
denylist: [],
};
// Restart required configuration
export interface RestartRequiredConfig {
required: boolean;
reason?: string;
}
// Bifrost Config
export interface BifrostConfig {
client_config: CoreConfig;
framework_config: FrameworkConfig;
auth_config?: AuthConfig;
proxy_config?: GlobalProxyConfig;
restart_required?: RestartRequiredConfig;
is_db_connected: boolean;
is_cache_connected: boolean;
is_logs_connected: boolean;
auth_token?: string;
}
export interface CompatConfig {
convert_text_to_chat: boolean;
convert_chat_to_responses: boolean;
should_drop_params: boolean;
should_convert_params: boolean;
}
// Core Bifrost configuration types
export interface CoreConfig {
drop_excess_requests: boolean;
initial_pool_size: number;
prometheus_labels: string[];
enable_logging: boolean;
disable_content_logging: boolean;
disable_db_pings_in_health: boolean;
log_retention_days: number;
enforce_auth_on_inference: boolean;
allow_direct_keys: boolean;
allowed_origins: string[];
allowed_headers: string[];
max_request_body_size_mb: number;
compat: CompatConfig;
mcp_agent_depth: number;
mcp_tool_execution_timeout: number;
mcp_code_mode_binding_level?: string;
mcp_tool_sync_interval: number;
mcp_disable_auto_tool_inject: boolean;
async_job_result_ttl: number;
required_headers: string[];
logging_headers: string[];
whitelisted_routes: string[];
hide_deleted_virtual_keys_in_filters: boolean;
routing_chain_max_depth: number;
header_filter_config?: GlobalHeaderFilterConfig;
}
export const DefaultCoreConfig: CoreConfig = {
drop_excess_requests: false,
initial_pool_size: 1000,
prometheus_labels: [],
enable_logging: true,
disable_content_logging: false,
disable_db_pings_in_health: false,
log_retention_days: 365,
enforce_auth_on_inference: false,
allow_direct_keys: false,
allowed_origins: [],
max_request_body_size_mb: 100,
compat: { convert_text_to_chat: false, convert_chat_to_responses: false, should_drop_params: false, should_convert_params: false },
mcp_agent_depth: 10,
mcp_tool_execution_timeout: 30,
mcp_code_mode_binding_level: "server",
mcp_tool_sync_interval: 10,
mcp_disable_auto_tool_inject: false,
async_job_result_ttl: 3600,
allowed_headers: [],
required_headers: [],
logging_headers: [],
whitelisted_routes: [],
hide_deleted_virtual_keys_in_filters: false,
routing_chain_max_depth: 10,
};
// Semantic cache configuration types
interface BaseCacheConfig {
ttl_seconds: number;
threshold: number;
conversation_history_threshold?: number;
exclude_system_prompt?: boolean;
cache_by_model: boolean;
cache_by_provider: boolean;
created_at?: string;
updated_at?: string;
}
export interface DirectCacheConfig extends BaseCacheConfig {
dimension: 1;
provider?: undefined;
keys?: ModelProviderKey[];
embedding_model?: undefined;
}
export interface ProviderBackedCacheConfig extends BaseCacheConfig {
provider: ModelProviderName;
keys?: ModelProviderKey[];
embedding_model: string;
dimension: number;
}
export type CacheConfig = DirectCacheConfig | ProviderBackedCacheConfig;
export interface EditorCacheConfig extends BaseCacheConfig {
provider?: ModelProviderName;
keys?: ModelProviderKey[];
embedding_model?: string;
dimension?: number;
}
// Maxim configuration types
export interface MaximConfig {
api_key: string;
log_repo_id: string;
}
// Form-specific custom provider config that allows any string for base_provider_type
export interface FormCustomProviderConfig extends Omit<CustomProviderConfig, "base_provider_type"> {
base_provider_type: string;
}
// Form-specific provider type that allows any string for name
export interface FormModelProvider extends Omit<ModelProvider, "name" | "custom_provider_config"> {
name: string;
custom_provider_config?: FormCustomProviderConfig;
}
// Utility types for form handling
export interface ProviderFormData {
provider: FormModelProvider;
keys: ModelProviderKey[];
network_config?: {
baseURL?: string;
defaultRequestTimeoutInSeconds: number;
maxRetries: number;
};
concurrency_and_buffer_size?: {
concurrency: number;
bufferSize: number;
};
custom_provider_config?: FormCustomProviderConfig;
}
// Status types
export type ProviderStatus = "active" | "error" | "deleted";

529
ui/lib/types/governance.ts Normal file
View File

@@ -0,0 +1,529 @@
// Governance types that match the Go backend structures
import { ModelProviderName, RequestType } from "./config";
export interface Budget {
id: string;
max_limit: number; // In dollars
reset_duration: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
current_usage: number; // In dollars
last_reset: string; // ISO timestamp
calendar_aligned?: boolean; // When true, resets at clean calendar boundaries (day/week/month/year start)
}
export interface RateLimit {
id: string;
// Flexible token limits
token_max_limit?: number; // Maximum tokens allowed
token_reset_duration?: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
token_current_usage: number; // Current token usage
token_last_reset: string; // ISO timestamp
// Flexible request limits
request_max_limit?: number; // Maximum requests allowed
request_reset_duration?: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
request_current_usage: number; // Current request usage
request_last_reset: string; // ISO timestamp
}
export interface Team {
id: string;
name: string;
customer_id?: string;
rate_limit_id?: string;
// Populated relationships
customer?: Customer;
budgets?: Budget[]; // Multi-budget: each with a distinct reset_duration
rate_limit?: RateLimit;
}
export interface Customer {
id: string;
name: string;
budget_id?: string;
rate_limit_id?: string;
// Populated relationships
teams?: Team[];
budget?: Budget;
rate_limit?: RateLimit;
}
export interface DBKey {
key_id: string; // UUID identifier for the key
name: string; // Name of the key
provider_id: string; // identifier for the provider
models: string[]; // List of models this key can access
provider: ModelProviderName; // Provider name
}
export interface RedactedDBKey {
id: string;
name: string;
models: string[];
weight: number;
}
export interface VirtualKey {
id: string;
name: string;
value: string; // The actual key value
description?: string;
provider_configs?: VirtualKeyProviderConfig[];
mcp_configs?: VirtualKeyMCPConfig[];
team_id?: string;
customer_id?: string;
rate_limit_id?: string;
is_active: boolean;
calendar_aligned?: boolean;
created_at: string;
updated_at: string;
// Populated relationships
team?: Team;
customer?: Customer;
budgets?: Budget[];
rate_limit?: RateLimit;
config_hash?: string; // Present when config is synced from config.json
}
// Provider config budgets don't have calendar_aligned (it's a VK-level field)
export type ProviderConfigBudget = Omit<Budget, "calendar_aligned">;
export interface VirtualKeyProviderConfig {
id?: number;
provider: string;
weight: number | null;
allowed_models: string[];
allow_all_keys: boolean; // True means all keys allowed; false with empty keys means no keys allowed
budgets?: ProviderConfigBudget[];
rate_limit?: RateLimit;
keys?: DBKey[]; // Associated database keys for this provider (only used when allow_all_keys is false)
}
export interface VirtualKeyMCPConfig {
id?: number;
virtual_key_id?: string;
mcp_client_id?: number;
mcp_client?: {
id: number;
name: string;
connection_type: string;
connection_string?: string;
tools_to_execute: string[];
created_at: string;
updated_at: string;
};
tools_to_execute?: string[];
}
// Request interfaces for create/update operations (still use mcp_client_name)
export interface VirtualKeyMCPConfigRequest {
id?: number;
mcp_client_name: string;
tools_to_execute?: string[];
}
export interface UsageStats {
virtual_key_id: string;
provider?: string;
model?: string;
tokens_current_usage: number;
requests_current_usage: number;
tokens_last_reset: string;
requests_last_reset: string;
}
// Request interfaces for provider config operations
export interface VirtualKeyProviderConfigRequest {
provider: string;
weight?: number | null;
allowed_models?: string[];
budgets?: ProviderConfigBudgetRequest[];
rate_limit?: CreateRateLimitRequest;
key_ids?: string[]; // List of DBKey UUIDs to associate with this provider config
}
export interface VirtualKeyProviderConfigUpdateRequest {
id?: number;
provider: string;
weight?: number | null;
allowed_models?: string[];
budgets?: ProviderConfigBudgetRequest[];
rate_limit?: UpdateRateLimitRequest;
key_ids?: string[]; // List of DBKey UUIDs to associate with this provider config
}
// VK-level budgets don't include calendar_aligned (it's a VK-level field, not per-budget)
export type VirtualKeyBudgetRequest = Omit<CreateBudgetRequest, "calendar_aligned">;
// Request types for API calls
export interface CreateVirtualKeyRequest {
name: string;
description?: string;
provider_configs?: VirtualKeyProviderConfigRequest[];
mcp_configs?: VirtualKeyMCPConfigRequest[];
team_id?: string;
customer_id?: string;
budgets?: VirtualKeyBudgetRequest[];
rate_limit?: CreateRateLimitRequest;
is_active?: boolean;
calendar_aligned?: boolean;
}
export interface UpdateVirtualKeyRequest {
name?: string;
description?: string;
provider_configs?: VirtualKeyProviderConfigUpdateRequest[];
mcp_configs?: VirtualKeyMCPConfigRequest[];
team_id?: string;
customer_id?: string;
budgets?: VirtualKeyBudgetRequest[];
rate_limit?: UpdateRateLimitRequest;
is_active?: boolean;
calendar_aligned?: boolean;
}
export interface CreateTeamRequest {
name: string;
customer_id?: string;
budgets?: CreateBudgetRequest[]; // Multi-budget: each must have a unique reset_duration
rate_limit?: CreateRateLimitRequest;
}
export interface UpdateTeamRequest {
name?: string;
customer_id?: string;
budgets?: CreateBudgetRequest[]; // Replaces all team budgets; empty array clears
rate_limit?: UpdateRateLimitRequest;
}
export interface CreateCustomerRequest {
name: string;
budget?: CreateBudgetRequest;
rate_limit?: CreateRateLimitRequest;
}
export interface UpdateCustomerRequest {
name?: string;
budget?: UpdateBudgetRequest;
rate_limit?: UpdateRateLimitRequest;
}
export interface CreateBudgetRequest {
max_limit: number; // In dollars
reset_duration: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
calendar_aligned?: boolean; // Snap resets to calendar boundaries (day/week/month/year)
}
// Provider config budget requests don't include calendar_aligned (it's a VK-level field)
export type ProviderConfigBudgetRequest = Omit<CreateBudgetRequest, "calendar_aligned">;
export interface UpdateBudgetRequest {
max_limit?: number;
reset_duration?: string;
calendar_aligned?: boolean; // When switching to true, current usage is reset to 0
}
export interface CreateRateLimitRequest {
token_max_limit?: number; // Maximum tokens allowed
token_reset_duration?: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
request_max_limit?: number; // Maximum requests allowed
request_reset_duration?: string; // e.g., "30s", "5m", "1h", "1d", "1w", "1M"
}
export interface UpdateRateLimitRequest {
token_max_limit?: number | null; // Maximum tokens allowed (null to clear)
token_reset_duration?: string | null; // e.g., "30s", "5m", "1h", "1d", "1w", "1M" (null to clear)
request_max_limit?: number | null; // Maximum requests allowed (null to clear)
request_reset_duration?: string | null; // e.g., "30s", "5m", "1h", "1d", "1w", "1M" (null to clear)
}
export interface ResetUsageRequest {
virtual_key_id: string;
provider?: string;
model?: string;
}
// Query params
export interface GetVirtualKeysParams {
limit?: number;
offset?: number;
search?: string;
customer_id?: string;
team_id?: string;
exclude_access_profile_managed_virtual?: boolean;
sort_by?: "name" | "budget_spent" | "created_at" | "status";
order?: "asc" | "desc";
export?: boolean;
}
// Response types
export interface GetVirtualKeysResponse {
virtual_keys: VirtualKey[];
count: number;
total_count: number;
limit: number;
offset: number;
}
export interface GetTeamsParams {
limit?: number;
offset?: number;
search?: string;
customer_id?: string;
}
export interface GetTeamsResponse {
teams: Team[];
count: number;
total_count: number;
limit: number;
offset: number;
}
export interface GetCustomersParams {
limit?: number;
offset?: number;
search?: string;
}
export interface GetCustomersResponse {
customers: Customer[];
count: number;
total_count: number;
limit: number;
offset: number;
}
export interface GetBudgetsResponse {
budgets: Budget[];
count: number;
}
export interface GetRateLimitsResponse {
rate_limits: RateLimit[];
count: number;
}
export interface GetUsageStatsResponse {
virtual_key_id?: string;
usage_stats: UsageStats | UsageStats[];
}
export interface DebugStatsResponse {
plugin_stats: Record<string, any>;
database_stats: {
virtual_keys_count: number;
teams_count: number;
customers_count: number;
budgets_count: number;
rate_limits_count: number;
usage_tracking_count: number;
audit_logs_count: number;
};
timestamp: string;
}
export interface HealthCheckResponse {
status: "healthy" | "unhealthy" | "warning";
timestamp: string;
checks: Record<
string,
{
status: "healthy" | "unhealthy" | "warning";
error?: string;
message?: string;
}
>;
}
// Model Config for per-model budgeting and rate limiting
export interface ModelConfig {
id: string;
model_name: string;
provider?: string; // Optional provider - if empty/null, applies to all providers
budget_id?: string;
rate_limit_id?: string;
// Populated relationships
budget?: Budget;
rate_limit?: RateLimit;
created_at: string;
updated_at: string;
}
// Request types for model config operations
export interface CreateModelConfigRequest {
model_name: string;
provider?: string; // Optional provider - if empty/null, applies to all providers
budget?: CreateBudgetRequest;
rate_limit?: CreateRateLimitRequest;
}
export interface UpdateModelConfigRequest {
model_name?: string;
provider?: string; // Optional provider - if empty/null, applies to all providers
budget?: UpdateBudgetRequest;
rate_limit?: UpdateRateLimitRequest;
}
export interface GetModelConfigsParams {
limit?: number;
offset?: number;
search?: string;
}
// Response types for model configs
export interface GetModelConfigsResponse {
model_configs: ModelConfig[];
count: number;
total_count: number;
limit: number;
offset: number;
}
export type PricingOverrideScopeKind =
| "global"
| "provider"
| "provider_key"
| "virtual_key"
| "virtual_key_provider"
| "virtual_key_provider_key";
export type PricingOverrideMatchType = "exact" | "wildcard";
export interface PricingOverridePatch {
// Token
input_cost_per_token?: number;
output_cost_per_token?: number;
input_cost_per_token_batches?: number;
output_cost_per_token_batches?: number;
input_cost_per_token_priority?: number;
output_cost_per_token_priority?: number;
input_cost_per_token_flex?: number;
output_cost_per_token_flex?: number;
input_cost_per_character?: number;
// 128k tier
input_cost_per_token_above_128k_tokens?: number;
output_cost_per_token_above_128k_tokens?: number;
input_cost_per_image_above_128k_tokens?: number;
input_cost_per_video_per_second_above_128k_tokens?: number;
input_cost_per_audio_per_second_above_128k_tokens?: number;
// 200k tier
input_cost_per_token_above_200k_tokens?: number;
input_cost_per_token_above_200k_tokens_priority?: number;
output_cost_per_token_above_200k_tokens?: number;
output_cost_per_token_above_200k_tokens_priority?: number;
// 272k tier
input_cost_per_token_above_272k_tokens?: number;
input_cost_per_token_above_272k_tokens_priority?: number;
output_cost_per_token_above_272k_tokens?: number;
output_cost_per_token_above_272k_tokens_priority?: number;
// Cache
cache_creation_input_token_cost?: number;
cache_read_input_token_cost?: number;
cache_creation_input_token_cost_above_200k_tokens?: number;
cache_read_input_token_cost_above_200k_tokens?: number;
cache_read_input_token_cost_above_200k_tokens_priority?: number;
cache_creation_input_token_cost_above_1hr?: number;
cache_creation_input_token_cost_above_1hr_above_200k_tokens?: number;
cache_creation_input_audio_token_cost?: number;
cache_read_input_token_cost_priority?: number;
cache_read_input_token_cost_flex?: number;
cache_read_input_image_token_cost?: number;
cache_read_input_token_cost_above_272k_tokens?: number;
cache_read_input_token_cost_above_272k_tokens_priority?: number;
// Image
input_cost_per_image_token?: number;
output_cost_per_image_token?: number;
input_cost_per_image?: number;
input_cost_per_pixel?: number;
output_cost_per_image?: number;
output_cost_per_pixel?: number;
output_cost_per_image_premium_image?: number;
output_cost_per_image_above_512_and_512_pixels?: number;
output_cost_per_image_above_512_and_512_pixels_and_premium_image?: number;
output_cost_per_image_above_1024_and_1024_pixels?: number;
output_cost_per_image_above_1024_and_1024_pixels_and_premium_image?: number;
output_cost_per_image_low_quality?: number;
output_cost_per_image_medium_quality?: number;
output_cost_per_image_high_quality?: number;
output_cost_per_image_auto_quality?: number;
// Audio/Video
input_cost_per_audio_token?: number;
input_cost_per_audio_per_second?: number;
input_cost_per_second?: number;
input_cost_per_video_per_second?: number;
output_cost_per_audio_token?: number;
output_cost_per_video_per_second?: number;
output_cost_per_second?: number;
// Other
search_context_cost_per_query?: number;
code_interpreter_cost_per_session?: number;
// OCR
ocr_cost_per_page?: number;
annotation_cost_per_page?: number;
}
export interface PricingOverride {
id: string;
name: string;
scope_kind: PricingOverrideScopeKind;
virtual_key_id?: string;
provider_id?: string;
provider_key_id?: string;
match_type: PricingOverrideMatchType;
pattern: string;
request_types?: RequestType[];
pricing_patch: string;
config_hash?: string;
created_at: string;
updated_at: string;
}
export interface CreatePricingOverrideRequest {
name: string;
scope_kind: PricingOverrideScopeKind;
virtual_key_id?: string;
provider_id?: string;
provider_key_id?: string;
match_type: PricingOverrideMatchType;
pattern: string;
request_types: RequestType[];
patch?: PricingOverridePatch;
}
export interface UpdatePricingOverrideRequest {
name?: string;
scope_kind?: PricingOverrideScopeKind;
virtual_key_id?: string;
provider_id?: string;
provider_key_id?: string;
match_type?: PricingOverrideMatchType;
pattern?: string;
request_types?: string[];
patch?: PricingOverridePatch;
}
export interface GetPricingOverridesResponse {
pricing_overrides: PricingOverride[];
count: number;
total_count: number;
limit: number;
offset: number;
}
// Provider governance - for extending provider with budget/rate limit
export interface ProviderGovernance {
provider: string;
budget_id?: string;
rate_limit_id?: string;
budget?: Budget;
rate_limit?: RateLimit;
}
export interface UpdateProviderGovernanceRequest {
budget?: UpdateBudgetRequest;
rate_limit?: UpdateRateLimitRequest;
}
export interface GetProviderGovernanceResponse {
providers: ProviderGovernance[];
count: number;
}

1221
ui/lib/types/logs.ts Normal file

File diff suppressed because it is too large Load Diff

138
ui/lib/types/mcp.ts Normal file
View File

@@ -0,0 +1,138 @@
import { Function as ToolFunction } from "./logs";
import { EnvVar } from "./schemas";
export type MCPConnectionType = "http" | "stdio" | "sse";
export type MCPConnectionState = "connected" | "disconnected" | "error";
export type MCPAuthType = "none" | "headers" | "oauth" | "per_user_oauth";
export type { EnvVar };
export interface MCPStdioConfig {
command: string;
args: string[];
envs: string[];
}
export interface OAuthConfig {
client_id: string;
client_secret?: string; // Optional for public clients using PKCE
authorize_url?: string; // Optional, will be discovered from server_url if not provided
token_url?: string; // Optional, will be discovered from server_url if not provided
registration_url?: string; // Optional, for dynamic client registration
scopes?: string[]; // Optional, can be discovered
server_url?: string; // MCP server URL for OAuth discovery (automatically set from connection_string)
}
export interface MCPClientConfig {
client_id: string; // Maps to ClientID in TableMCPClient
name: string;
is_code_mode_client?: boolean;
connection_type: MCPConnectionType;
connection_string?: EnvVar;
stdio_config?: MCPStdioConfig;
auth_type?: MCPAuthType;
oauth_config_id?: string;
tools_to_execute?: string[];
tools_to_auto_execute?: string[];
headers?: Record<string, EnvVar>;
is_ping_available?: boolean;
tool_pricing?: Record<string, number>;
tool_sync_interval?: number; // Per-client override in minutes (0 = use global, -1 = disabled)
allowed_extra_headers?: string[]; // Allowlist of x-bf-eh-* headers forwarded to this MCP server. ["*"] = allow all.
allow_on_all_virtual_keys?: boolean; // When true, available to all VKs with all tools allowed by default; explicit VK config overrides this
}
export interface MCPVKConfigResponse {
virtual_key_id: string;
virtual_key_name: string;
tools_to_execute: string[];
}
export interface MCPClient {
config: MCPClientConfig;
tools: ToolFunction[];
state: MCPConnectionState;
vk_configs: MCPVKConfigResponse[];
}
export interface CreateMCPClientRequest {
name: string;
is_code_mode_client?: boolean;
connection_type: MCPConnectionType;
connection_string?: EnvVar;
stdio_config?: MCPStdioConfig;
auth_type?: MCPAuthType;
oauth_config?: OAuthConfig;
tools_to_execute?: string[];
tools_to_auto_execute?: string[];
headers?: Record<string, EnvVar>;
is_ping_available?: boolean;
}
export interface OAuthFlowResponse {
status: "pending_oauth";
message: string;
oauth_config_id: string;
authorize_url: string;
expires_at: string;
mcp_client_id: string;
}
export interface OAuthStatusResponse {
id: string;
status: "pending" | "authorized" | "failed" | "expired" | "revoked";
created_at: string;
expires_at: string;
token_id?: string;
token_expires_at?: string;
token_scopes?: string;
}
export interface MCPVKConfig {
virtual_key_id: string;
tools_to_execute: string[];
}
export interface UpdateMCPClientRequest {
name?: string;
is_code_mode_client?: boolean;
headers?: Record<string, EnvVar>;
tools_to_execute?: string[];
tools_to_auto_execute?: string[];
is_ping_available?: boolean;
tool_pricing?: Record<string, number>;
tool_sync_interval?: number; // Per-client override in minutes (0 = use global, -1 = disabled)
allowed_extra_headers?: string[]; // Allowlist of x-bf-eh-* headers forwarded to this MCP server. ["*"] = allow all.
allow_on_all_virtual_keys?: boolean; // When true, available to all VKs with all tools allowed by default; explicit VK config overrides this
vk_configs?: MCPVKConfig[]; // When provided, replaces all VK assignments for this MCP client
}
// Pagination params for MCP clients list
export interface GetMCPClientsParams {
limit?: number;
offset?: number;
search?: string;
}
// Paginated response for MCP clients list
export interface GetMCPClientsResponse {
clients: MCPClient[];
count: number;
total_count: number;
limit: number;
offset: number;
}
// Types for MCP Tool Selector component
export interface SelectedTool {
mcpClientId: string;
toolName: string;
}
// MCP Tool Spec for tool groups (matches backend schema)
export interface MCPToolSpec {
mcp_client_id: string;
tool_names: string[];
}

47
ui/lib/types/plugins.ts Normal file
View File

@@ -0,0 +1,47 @@
// Plugins types that match the Go backend structures
export const SEMANTIC_CACHE_PLUGIN = "semantic_cache";
export const MAXIM_PLUGIN = "maxim";
export type PluginType = "llm" | "mcp" | "http";
export interface PluginStatus {
name: string;
status: string;
logs: string[];
types: PluginType[];
}
export interface Plugin {
name: string;
actualName?: string;
enabled: boolean;
config: any;
isCustom: boolean;
path?: string;
status?: PluginStatus;
placement?: string;
order?: number;
}
export interface PluginsResponse {
plugins: Plugin[];
count: number;
}
export interface CreatePluginRequest {
name: string;
path: string;
enabled: boolean;
config: any;
placement?: string;
order?: number;
}
export interface UpdatePluginRequest {
enabled: boolean;
path?: string;
config?: any;
placement?: string;
order?: number;
}

255
ui/lib/types/prompts.ts Normal file
View File

@@ -0,0 +1,255 @@
// Prompt Repository types for frontend
import type { SerializedMessage } from "@/lib/message";
export interface PromptUser {
id: string;
name: string;
email: string;
}
export type { MessageContent, MessageFile, MessageImageURL, MessageInputAudio, SerializedMessage } from "@/lib/message";
export interface Folder {
id: string;
name: string;
description?: string;
created_by_id?: number;
created_by?: PromptUser;
created_at: string;
updated_at: string;
prompts_count?: number;
}
export interface Prompt {
id: string;
name: string;
folder_id?: string;
folder?: Folder;
created_by_id?: number;
created_by?: PromptUser;
created_at: string;
updated_at: string;
latest_version?: PromptVersion;
}
export interface ModelParams {
temperature?: number;
max_tokens?: number;
top_p?: number;
frequency_penalty?: number;
presence_penalty?: number;
stop?: string[];
[key: string]: any;
}
export interface PromptVersion {
id: number;
prompt_id: string;
version_number: number;
commit_message: string;
messages: PromptVersionMessage[];
model_params: ModelParams;
provider: string;
model: string;
variables?: Record<string, string>;
is_latest: boolean;
created_by_id?: number;
created_by?: PromptUser;
created_at: string; // No updated_at - versions are immutable
}
export interface PromptVersionMessage {
id: number;
prompt_id: string;
version_id: number;
order_index: number;
message: PromptMessage;
}
export interface PromptSession {
id: number;
prompt_id: string;
prompt?: Prompt;
version_id?: number;
version?: PromptVersion;
name: string;
messages: PromptSessionMessage[];
model_params: ModelParams;
provider: string;
model: string;
variables?: Record<string, string>;
created_by_id?: number;
created_by?: PromptUser;
created_at: string;
updated_at: string;
}
export interface PromptSessionMessage {
id: number;
prompt_id: string;
session_id: number;
order_index: number;
message: PromptMessage;
}
// ============================================================================
// Message Types (OpenAI-compatible format)
// ============================================================================
export type PromptMessage = SerializedMessage;
// ============================================================================
// API Request/Response Types - Folders
// ============================================================================
export interface GetFoldersResponse {
folders: Folder[];
}
export interface GetFolderResponse {
folder: Folder;
}
export interface CreateFolderRequest {
name: string;
description?: string;
}
export interface CreateFolderResponse {
folder: Folder;
}
export interface UpdateFolderRequest {
name?: string;
description?: string;
}
export interface UpdateFolderResponse {
folder: Folder;
}
export interface DeleteFolderResponse {
message: string;
}
// ============================================================================
// API Request/Response Types - Prompts
// ============================================================================
export interface GetPromptsResponse {
prompts: Prompt[];
}
export interface GetPromptResponse {
prompt: Prompt;
}
export interface CreatePromptRequest {
name: string;
folder_id?: string;
}
export interface CreatePromptResponse {
prompt: Prompt;
}
export interface UpdatePromptRequest {
name?: string;
folder_id?: string | null;
}
export interface UpdatePromptResponse {
prompt: Prompt;
}
export interface DeletePromptResponse {
message: string;
}
// ============================================================================
// API Request/Response Types - Versions
// ============================================================================
export interface GetVersionsResponse {
versions: PromptVersion[];
}
export interface GetVersionResponse {
version: PromptVersion;
}
export interface CreateVersionRequest {
commit_message: string;
messages: PromptMessage[];
model_params: ModelParams;
provider: string;
model: string;
}
export interface CreateVersionResponse {
version: PromptVersion;
}
export interface DeleteVersionResponse {
message: string;
}
// ============================================================================
// API Request/Response Types - Sessions
// ============================================================================
export interface GetSessionsResponse {
sessions: PromptSession[];
}
export interface GetSessionResponse {
session: PromptSession;
}
export interface CreateSessionRequest {
name?: string;
version_id?: number;
messages?: PromptMessage[];
model_params: ModelParams;
provider: string;
model: string;
variables?: Record<string, string>;
}
export interface CreateSessionResponse {
session: PromptSession;
}
export interface UpdateSessionRequest {
name?: string;
messages: PromptMessage[];
model_params: ModelParams;
provider: string;
model: string;
variables?: Record<string, string>;
}
export interface UpdateSessionResponse {
session: PromptSession;
}
export interface RenameSessionRequest {
name: string;
}
export interface RenameSessionResponse {
session: PromptSession;
}
export interface DeleteSessionResponse {
message: string;
}
export interface CommitSessionRequest {
commit_message: string;
message_indices?: number[];
}
export interface CommitSessionResponse {
version: PromptVersion;
}

View File

@@ -0,0 +1,123 @@
/**
* Routing Rules Type Definitions
* Defines all TypeScript interfaces for routing rules feature
*/
import { RuleGroupType } from "react-querybuilder";
export interface RoutingTarget {
provider?: string;
model?: string;
key_id?: string;
weight: number;
}
export interface RoutingRule {
id: string;
name: string;
description: string;
cel_expression: string;
targets: RoutingTarget[];
fallbacks?: string[];
scope: "global" | "team" | "customer" | "virtual_key";
scope_id?: string;
priority: number;
enabled: boolean;
chain_rule: boolean;
query?: RuleGroupType;
created_at: string;
updated_at: string;
}
export interface CreateRoutingRuleRequest {
name: string;
description?: string;
cel_expression?: string;
targets: RoutingTarget[];
fallbacks?: string[];
scope: string;
scope_id?: string;
priority: number;
enabled?: boolean;
chain_rule?: boolean;
query?: RuleGroupType;
}
/** Partial update: only sent fields are applied; allows clearing fields by sending "" or []. */
export type UpdateRoutingRuleRequest = Partial<CreateRoutingRuleRequest>;
export interface GetRoutingRulesParams {
limit?: number;
offset?: number;
search?: string;
}
export interface GetRoutingRulesResponse {
rules: RoutingRule[];
count: number;
total_count: number;
limit: number;
offset: number;
}
export interface GetRoutingRuleResponse {
rule: RoutingRule;
}
export interface RoutingTargetFormData {
provider: string;
model: string;
key_id: string;
weight: number;
}
export interface RoutingRuleFormData {
id?: string;
name: string;
description: string;
cel_expression: string;
targets: RoutingTargetFormData[];
fallbacks: string[];
scope: string;
scope_id: string;
priority: number;
enabled: boolean;
chain_rule: boolean;
query?: RuleGroupType;
isDirty?: boolean;
}
export enum RoutingRuleScope {
Global = "global",
Team = "team",
Customer = "customer",
VirtualKey = "virtual_key",
}
export const ROUTING_RULE_SCOPES = [
{ value: RoutingRuleScope.Global, label: "Global" },
{ value: RoutingRuleScope.Team, label: "Team" },
{ value: RoutingRuleScope.Customer, label: "Customer" },
{ value: RoutingRuleScope.VirtualKey, label: "Virtual Key" },
];
export const DEFAULT_ROUTING_TARGET: RoutingTargetFormData = {
provider: "",
model: "",
key_id: "",
weight: 1,
};
export const DEFAULT_ROUTING_RULE_FORM_DATA: RoutingRuleFormData = {
name: "",
description: "",
cel_expression: "",
targets: [DEFAULT_ROUTING_TARGET],
fallbacks: [],
scope: RoutingRuleScope.Global,
scope_id: "",
priority: 0,
enabled: true,
chain_rule: false,
isDirty: false,
};

1108
ui/lib/types/schemas.ts Normal file

File diff suppressed because it is too large Load Diff