Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { CONCRETE_PLATFORM_OPTIONS, GROUP_PLATFORM_OPTIONS } from '@/constants/platforms'
|
||||
|
||||
const concretePlatforms = [
|
||||
'anthropic',
|
||||
'openai',
|
||||
'gemini',
|
||||
'antigravity',
|
||||
'grok',
|
||||
'kimi',
|
||||
'zhipu',
|
||||
'deepseek'
|
||||
]
|
||||
|
||||
describe('platform option catalogs', () => {
|
||||
it('exposes every concrete account platform', () => {
|
||||
expect(CONCRETE_PLATFORM_OPTIONS.map((option) => option.value)).toEqual(concretePlatforms)
|
||||
})
|
||||
|
||||
it('adds composite for group-backed filters', () => {
|
||||
expect(GROUP_PLATFORM_OPTIONS.map((option) => option.value)).toEqual([
|
||||
...concretePlatforms,
|
||||
'composite'
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,63 @@
|
||||
/** WebSearch emulation mode values (must match backend WebSearchMode* constants in account.go) */
|
||||
export const WEB_SEARCH_MODE_DEFAULT = 'default' as const
|
||||
export const WEB_SEARCH_MODE_ENABLED = 'enabled' as const
|
||||
export const WEB_SEARCH_MODE_DISABLED = 'disabled' as const
|
||||
export type WebSearchMode = typeof WEB_SEARCH_MODE_DEFAULT | typeof WEB_SEARCH_MODE_ENABLED | typeof WEB_SEARCH_MODE_DISABLED
|
||||
|
||||
/** Quota notification threshold type values (must match thresholdType* constants in balance_notify_service.go) */
|
||||
export const QUOTA_THRESHOLD_TYPE_FIXED = 'fixed' as const
|
||||
export const QUOTA_THRESHOLD_TYPE_PERCENTAGE = 'percentage' as const
|
||||
export type QuotaThresholdType = typeof QUOTA_THRESHOLD_TYPE_FIXED | typeof QUOTA_THRESHOLD_TYPE_PERCENTAGE
|
||||
|
||||
/** Quota reset mode values */
|
||||
export const QUOTA_RESET_MODE_ROLLING = 'rolling' as const
|
||||
export const QUOTA_RESET_MODE_FIXED = 'fixed' as const
|
||||
export type QuotaResetMode = typeof QUOTA_RESET_MODE_ROLLING | typeof QUOTA_RESET_MODE_FIXED
|
||||
|
||||
/** Vertex AI location options for Service Account accounts */
|
||||
export const VERTEX_LOCATION_OPTIONS = [
|
||||
{
|
||||
label: 'Common',
|
||||
options: [
|
||||
{ value: 'us-central1', label: 'us-central1 (Iowa)' },
|
||||
{ value: 'global', label: 'global' },
|
||||
{ value: 'us', label: 'us' },
|
||||
{ value: 'eu', label: 'eu' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'United States',
|
||||
options: [
|
||||
{ value: 'us-east1', label: 'us-east1 (South Carolina)' },
|
||||
{ value: 'us-east4', label: 'us-east4 (Northern Virginia)' },
|
||||
{ value: 'us-east5', label: 'us-east5 (Columbus)' },
|
||||
{ value: 'us-south1', label: 'us-south1 (Dallas)' },
|
||||
{ value: 'us-west1', label: 'us-west1 (Oregon)' },
|
||||
{ value: 'us-west4', label: 'us-west4 (Las Vegas)' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Europe',
|
||||
options: [
|
||||
{ value: 'europe-west1', label: 'europe-west1 (Belgium)' },
|
||||
{ value: 'europe-west2', label: 'europe-west2 (London)' },
|
||||
{ value: 'europe-west3', label: 'europe-west3 (Frankfurt)' },
|
||||
{ value: 'europe-west4', label: 'europe-west4 (Netherlands)' },
|
||||
{ value: 'europe-west6', label: 'europe-west6 (Zurich)' },
|
||||
{ value: 'europe-west8', label: 'europe-west8 (Milan)' },
|
||||
{ value: 'europe-west9', label: 'europe-west9 (Paris)' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Asia Pacific',
|
||||
options: [
|
||||
{ value: 'asia-east1', label: 'asia-east1 (Taiwan)' },
|
||||
{ value: 'asia-east2', label: 'asia-east2 (Hong Kong)' },
|
||||
{ value: 'asia-northeast1', label: 'asia-northeast1 (Tokyo)' },
|
||||
{ value: 'asia-northeast3', label: 'asia-northeast3 (Seoul)' },
|
||||
{ value: 'asia-south1', label: 'asia-south1 (Mumbai)' },
|
||||
{ value: 'asia-southeast1', label: 'asia-southeast1 (Singapore)' },
|
||||
{ value: 'australia-southeast1', label: 'australia-southeast1 (Sydney)' }
|
||||
]
|
||||
}
|
||||
] as const
|
||||
@@ -0,0 +1,26 @@
|
||||
/** Channel status values (must match service.Status* constants in Go). */
|
||||
export const CHANNEL_STATUS_ACTIVE = 'active' as const
|
||||
export const CHANNEL_STATUS_DISABLED = 'disabled' as const
|
||||
export type ChannelStatus = typeof CHANNEL_STATUS_ACTIVE | typeof CHANNEL_STATUS_DISABLED
|
||||
|
||||
/** Billing mode values (must match service.BillingMode* constants in Go). */
|
||||
export const BILLING_MODE_TOKEN = 'token' as const
|
||||
export const BILLING_MODE_PER_REQUEST = 'per_request' as const
|
||||
export const BILLING_MODE_IMAGE = 'image' as const
|
||||
export const BILLING_MODE_VIDEO = 'video' as const
|
||||
export type BillingMode =
|
||||
| typeof BILLING_MODE_TOKEN
|
||||
| typeof BILLING_MODE_PER_REQUEST
|
||||
| typeof BILLING_MODE_IMAGE
|
||||
| typeof BILLING_MODE_VIDEO
|
||||
|
||||
/** Billing-model-source values (must match service.BillingModelSource* constants in Go). */
|
||||
export const BILLING_MODEL_SOURCE_REQUESTED = 'requested' as const
|
||||
export const BILLING_MODEL_SOURCE_UPSTREAM = 'upstream' as const
|
||||
export const BILLING_MODEL_SOURCE_CHANNEL_MAPPED = 'channel_mapped' as const
|
||||
export const BILLING_MODEL_SOURCE_RESPONSE = 'response_model' as const
|
||||
export type BillingModelSource =
|
||||
| typeof BILLING_MODEL_SOURCE_REQUESTED
|
||||
| typeof BILLING_MODEL_SOURCE_UPSTREAM
|
||||
| typeof BILLING_MODEL_SOURCE_CHANNEL_MAPPED
|
||||
| typeof BILLING_MODEL_SOURCE_RESPONSE
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Channel monitor shared constants.
|
||||
*
|
||||
* Single source of truth for provider/status string values used by both the
|
||||
* admin (`views/admin/ChannelMonitorView.vue`) and user-facing
|
||||
* (`views/user/ChannelStatusView.vue`) screens, plus the shared composable
|
||||
* `useChannelMonitorFormat`.
|
||||
*/
|
||||
|
||||
import type { APIMode, CheckMode, Provider, MonitorStatus } from '@/api/admin/channelMonitor'
|
||||
|
||||
export const PROVIDER_OPENAI: Provider = 'openai'
|
||||
export const PROVIDER_ANTHROPIC: Provider = 'anthropic'
|
||||
export const PROVIDER_GEMINI: Provider = 'gemini'
|
||||
export const PROVIDER_GROK: Provider = 'grok'
|
||||
export const PROVIDER_ANTIGRAVITY: Provider = 'antigravity'
|
||||
export const PROVIDER_KIMI: Provider = 'kimi'
|
||||
export const PROVIDER_ZHIPU: Provider = 'zhipu'
|
||||
export const PROVIDER_DEEPSEEK: Provider = 'deepseek'
|
||||
|
||||
export const DEFAULT_GROK_ENDPOINT = 'https://api.x.ai'
|
||||
export const DEFAULT_GROK_MODEL = 'grok-4.5'
|
||||
|
||||
/** 国产 provider 的官方 endpoint(探活模式预填;配额模式可留空)。 */
|
||||
export const DEFAULT_KIMI_ENDPOINT = 'https://api.moonshot.cn'
|
||||
export const DEFAULT_ZHIPU_ENDPOINT = 'https://open.bigmodel.cn'
|
||||
export const DEFAULT_DEEPSEEK_ENDPOINT = 'https://api.deepseek.com'
|
||||
|
||||
export const CHECK_MODE_PROBE: CheckMode = 'probe'
|
||||
export const CHECK_MODE_QUOTA: CheckMode = 'quota'
|
||||
export const CHECK_MODE_QUOTA_PROBE: CheckMode = 'quota_probe'
|
||||
|
||||
export const API_MODE_CHAT_COMPLETIONS: APIMode = 'chat_completions'
|
||||
export const API_MODE_RESPONSES: APIMode = 'responses'
|
||||
|
||||
export const PROVIDERS: readonly Provider[] = [
|
||||
PROVIDER_OPENAI,
|
||||
PROVIDER_ANTHROPIC,
|
||||
PROVIDER_GEMINI,
|
||||
PROVIDER_GROK,
|
||||
PROVIDER_ANTIGRAVITY,
|
||||
PROVIDER_KIMI,
|
||||
PROVIDER_ZHIPU,
|
||||
PROVIDER_DEEPSEEK,
|
||||
]
|
||||
|
||||
/** 仅支持配额模式(无探活 adapter)的 provider。 */
|
||||
export const QUOTA_ONLY_PROVIDERS: readonly Provider[] = [PROVIDER_ANTIGRAVITY]
|
||||
|
||||
export const CHECK_MODES: readonly CheckMode[] = [
|
||||
CHECK_MODE_PROBE,
|
||||
CHECK_MODE_QUOTA,
|
||||
CHECK_MODE_QUOTA_PROBE,
|
||||
]
|
||||
|
||||
export const API_MODES: readonly APIMode[] = [
|
||||
API_MODE_CHAT_COMPLETIONS,
|
||||
API_MODE_RESPONSES,
|
||||
]
|
||||
|
||||
export const STATUS_OPERATIONAL: MonitorStatus = 'operational'
|
||||
export const STATUS_DEGRADED: MonitorStatus = 'degraded'
|
||||
export const STATUS_FAILED: MonitorStatus = 'failed'
|
||||
export const STATUS_ERROR: MonitorStatus = 'error'
|
||||
|
||||
export const MONITOR_STATUSES: readonly MonitorStatus[] = [
|
||||
STATUS_OPERATIONAL,
|
||||
STATUS_DEGRADED,
|
||||
STATUS_FAILED,
|
||||
STATUS_ERROR,
|
||||
]
|
||||
|
||||
/** Default polling interval (seconds) for new monitors. */
|
||||
export const DEFAULT_INTERVAL_SECONDS = 60
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { AccountPlatform, GroupPlatform } from '@/types'
|
||||
|
||||
export interface PlatformOption<T extends string = string> {
|
||||
value: T
|
||||
label: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete upstream platforms supported by accounts and request routing.
|
||||
* Keep platform selectors derived from this catalog so newly added providers
|
||||
* do not silently disappear from list filters.
|
||||
*/
|
||||
export const CONCRETE_PLATFORM_OPTIONS = [
|
||||
{ value: 'anthropic', label: 'Anthropic' },
|
||||
{ value: 'openai', label: 'OpenAI' },
|
||||
{ value: 'gemini', label: 'Gemini' },
|
||||
{ value: 'antigravity', label: 'Antigravity' },
|
||||
{ value: 'grok', label: 'Grok' },
|
||||
{ value: 'kimi', label: 'Kimi' },
|
||||
{ value: 'zhipu', label: 'Zhipu GLM' },
|
||||
{ value: 'deepseek', label: 'DeepSeek' }
|
||||
] as const satisfies readonly PlatformOption<AccountPlatform>[]
|
||||
|
||||
/** Platforms that can own a group. */
|
||||
export const GROUP_PLATFORM_OPTIONS = [
|
||||
...CONCRETE_PLATFORM_OPTIONS,
|
||||
{ value: 'composite', label: 'Composite' }
|
||||
] as const satisfies readonly PlatformOption<GroupPlatform>[]
|
||||
Reference in New Issue
Block a user