diff --git a/LICENSE b/LICENSE index cdffe03..5e94e89 100644 --- a/LICENSE +++ b/LICENSE @@ -5,12 +5,17 @@ Aether 非商业开源许可证 特此授予任何获得本软件及其相关文档文件(以下简称"软件")副本的人免费使用、 复制、修改、合并、发布和分发本软件的权限,但须遵守以下条件: -1. 仅限非商业用途 - 本软件不得用于商业目的。商业目的包括但不限于: +1. 仅限非盈利用途 + 本软件不得用于盈利目的。盈利目的包括但不限于: - 出售本软件或任何衍生作品 - 使用本软件提供付费服务 - - 将本软件用于商业产品或服务 - - 将本软件用于任何旨在获取商业利益或金钱报酬的活动 + - 将本软件用于以盈利为目的的商业产品或服务 + + 以下用途被明确允许: + - 个人学习和研究 + - 教育机构的教学和研究 + - 非盈利组织的内部使用 + - 企业内部非盈利性质的使用(如内部工具、测试环境等) 2. 署名要求 上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。 @@ -22,7 +27,7 @@ Aether 非商业开源许可证 您不得以不同的条款将本软件再许可给他人。 5. 商业许可 - 如需商业使用,请联系版权持有人以获取单独的商业许可。 + 如需将本软件用于盈利目的,请联系版权持有人以获取单独的商业许可。 本软件按"原样"提供,不提供任何明示或暗示的保证,包括但不限于对适销性、 特定用途适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何 diff --git a/README.md b/README.md index d222199..0ab3858 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ cd frontend && npm install && npm run dev - **模型级别**: 在模型管理中针对指定模型开启 1H缓存策略 - **密钥级别**: 在密钥管理中针对指定密钥使用 1H缓存策略 -> **注意**: 若对密钥设置强制 1H缓存, 则该密钥只能调用支持 1H缓存的模型 +> **注意**: 若对密钥设置强制 1H缓存, 则该密钥只能使用支持 1H缓存的模型, 匹配提供商Key, 将会导致这个Key无法同时用于Claude Code、Codex、GeminiCLI, 因为更推荐使用模型开启1H缓存. ### Q: 如何配置负载均衡? @@ -162,4 +162,16 @@ cd frontend && npm install && npm run dev ## 许可证 -本项目采用 [Aether 非商业开源许可证](LICENSE)。 +本项目采用 [Aether 非商业开源许可证](LICENSE)。允许个人学习、教育研究、非盈利组织及企业内部非盈利性质的使用;禁止用于盈利目的。商业使用请联系获取商业许可。 + +## 联系作者 + +

+ QQ二维码 +

+ +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=fawney19/Aether&type=Date)](https://star-history.com/#fawney19/Aether&Date) + + diff --git a/docs/author/qq_qrcode.jpg b/docs/author/qq_qrcode.jpg new file mode 100644 index 0000000..93ddc99 Binary files /dev/null and b/docs/author/qq_qrcode.jpg differ diff --git a/docs/author/wechat_payment.jpg b/docs/author/wechat_payment.jpg new file mode 100644 index 0000000..fc5b4f9 Binary files /dev/null and b/docs/author/wechat_payment.jpg differ diff --git a/frontend/src/mocks/data.ts b/frontend/src/mocks/data.ts index 6141b53..81702ad 100644 --- a/frontend/src/mocks/data.ts +++ b/frontend/src/mocks/data.ts @@ -5,7 +5,7 @@ import type { User, LoginResponse } from '@/api/auth' import type { DashboardStatsResponse, RecentRequest, ProviderStatus, DailyStatsResponse } from '@/api/dashboard' -import type { User as AdminUser, ApiKey } from '@/api/users' +import type { User as AdminUser } from '@/api/users' import type { AdminApiKeysResponse } from '@/api/admin' import type { Profile, UsageResponse } from '@/api/me' import type { ProviderWithEndpointsSummary, GlobalModelResponse } from '@/api/endpoints/types' @@ -185,18 +185,20 @@ export const MOCK_DASHBOARD_STATS: DashboardStatsResponse = { output: 700000, cache_creation: 50000, cache_read: 200000 - } + }, + // 普通用户专用字段 + monthly_cost: 45.67 } export const MOCK_RECENT_REQUESTS: RecentRequest[] = [ - { id: 'req-001', user: 'alice', model: 'claude-sonnet-4-20250514', tokens: 15234, time: '2 分钟前' }, - { id: 'req-002', user: 'bob', model: 'gpt-4o', tokens: 8765, time: '5 分钟前' }, - { id: 'req-003', user: 'charlie', model: 'claude-opus-4-20250514', tokens: 32100, time: '8 分钟前' }, - { id: 'req-004', user: 'diana', model: 'gemini-2.0-flash', tokens: 4521, time: '12 分钟前' }, - { id: 'req-005', user: 'eve', model: 'claude-sonnet-4-20250514', tokens: 9876, time: '15 分钟前' }, - { id: 'req-006', user: 'frank', model: 'gpt-4o-mini', tokens: 2345, time: '18 分钟前' }, - { id: 'req-007', user: 'grace', model: 'claude-haiku-3-5-20241022', tokens: 6789, time: '22 分钟前' }, - { id: 'req-008', user: 'henry', model: 'gemini-2.5-pro', tokens: 12345, time: '25 分钟前' } + { id: 'req-001', user: 'alice', model: 'claude-sonnet-4-5-20250929', tokens: 15234, time: '2 分钟前' }, + { id: 'req-002', user: 'bob', model: 'gpt-5.1', tokens: 8765, time: '5 分钟前' }, + { id: 'req-003', user: 'charlie', model: 'claude-opus-4-5-20251101', tokens: 32100, time: '8 分钟前' }, + { id: 'req-004', user: 'diana', model: 'gemini-3-pro-preview', tokens: 4521, time: '12 分钟前' }, + { id: 'req-005', user: 'eve', model: 'claude-sonnet-4-5-20250929', tokens: 9876, time: '15 分钟前' }, + { id: 'req-006', user: 'frank', model: 'gpt-5.1-codex-mini', tokens: 2345, time: '18 分钟前' }, + { id: 'req-007', user: 'grace', model: 'claude-haiku-4-5-20251001', tokens: 6789, time: '22 分钟前' }, + { id: 'req-008', user: 'henry', model: 'gemini-3-pro-preview', tokens: 12345, time: '25 分钟前' } ] export const MOCK_PROVIDER_STATUS: ProviderStatus[] = [ @@ -231,11 +233,11 @@ function generateDailyStats(): DailyStatsResponse { unique_models: 8 + Math.floor(Math.random() * 5), unique_providers: 4 + Math.floor(Math.random() * 3), model_breakdown: [ - { model: 'claude-sonnet-4-20250514', requests: Math.floor(baseRequests * 0.35), tokens: Math.floor(baseTokens * 0.35), cost: Number((baseCost * 0.35).toFixed(2)) }, - { model: 'gpt-4o', requests: Math.floor(baseRequests * 0.25), tokens: Math.floor(baseTokens * 0.25), cost: Number((baseCost * 0.25).toFixed(2)) }, - { model: 'claude-opus-4-20250514', requests: Math.floor(baseRequests * 0.15), tokens: Math.floor(baseTokens * 0.15), cost: Number((baseCost * 0.20).toFixed(2)) }, - { model: 'gemini-2.0-flash', requests: Math.floor(baseRequests * 0.15), tokens: Math.floor(baseTokens * 0.15), cost: Number((baseCost * 0.10).toFixed(2)) }, - { model: 'claude-haiku-3-5-20241022', requests: Math.floor(baseRequests * 0.10), tokens: Math.floor(baseTokens * 0.10), cost: Number((baseCost * 0.10).toFixed(2)) } + { model: 'claude-sonnet-4-5-20250929', requests: Math.floor(baseRequests * 0.35), tokens: Math.floor(baseTokens * 0.35), cost: Number((baseCost * 0.35).toFixed(2)) }, + { model: 'gpt-5.1', requests: Math.floor(baseRequests * 0.25), tokens: Math.floor(baseTokens * 0.25), cost: Number((baseCost * 0.25).toFixed(2)) }, + { model: 'claude-opus-4-5-20251101', requests: Math.floor(baseRequests * 0.15), tokens: Math.floor(baseTokens * 0.15), cost: Number((baseCost * 0.20).toFixed(2)) }, + { model: 'gemini-3-pro-preview', requests: Math.floor(baseRequests * 0.15), tokens: Math.floor(baseTokens * 0.15), cost: Number((baseCost * 0.10).toFixed(2)) }, + { model: 'claude-haiku-4-5-20251001', requests: Math.floor(baseRequests * 0.10), tokens: Math.floor(baseTokens * 0.10), cost: Number((baseCost * 0.10).toFixed(2)) } ] }) } @@ -243,11 +245,11 @@ function generateDailyStats(): DailyStatsResponse { return { daily_stats: dailyStats, model_summary: [ - { model: 'claude-sonnet-4-20250514', requests: 2456, tokens: 8500000, cost: 125.45, avg_response_time: 1.2, cost_per_request: 0.051, tokens_per_request: 3461 }, - { model: 'gpt-4o', requests: 1823, tokens: 6200000, cost: 98.32, avg_response_time: 0.9, cost_per_request: 0.054, tokens_per_request: 3401 }, - { model: 'claude-opus-4-20250514', requests: 987, tokens: 4100000, cost: 156.78, avg_response_time: 2.1, cost_per_request: 0.159, tokens_per_request: 4154 }, - { model: 'gemini-2.0-flash', requests: 1234, tokens: 3800000, cost: 28.56, avg_response_time: 0.6, cost_per_request: 0.023, tokens_per_request: 3079 }, - { model: 'claude-haiku-3-5-20241022', requests: 2100, tokens: 5200000, cost: 32.10, avg_response_time: 0.5, cost_per_request: 0.015, tokens_per_request: 2476 } + { model: 'claude-sonnet-4-5-20250929', requests: 2456, tokens: 8500000, cost: 125.45, avg_response_time: 1.2, cost_per_request: 0.051, tokens_per_request: 3461 }, + { model: 'gpt-5.1', requests: 1823, tokens: 6200000, cost: 98.32, avg_response_time: 0.9, cost_per_request: 0.054, tokens_per_request: 3401 }, + { model: 'claude-opus-4-5-20251101', requests: 987, tokens: 4100000, cost: 156.78, avg_response_time: 2.1, cost_per_request: 0.159, tokens_per_request: 4154 }, + { model: 'gemini-3-pro-preview', requests: 1234, tokens: 3800000, cost: 28.56, avg_response_time: 0.6, cost_per_request: 0.023, tokens_per_request: 3079 }, + { model: 'claude-haiku-4-5-20251001', requests: 2100, tokens: 5200000, cost: 32.10, avg_response_time: 0.5, cost_per_request: 0.015, tokens_per_request: 2476 } ], period: { start_date: dailyStats[0].date, @@ -336,7 +338,7 @@ export const MOCK_ALL_USERS: AdminUser[] = [ // ========== API Key 数据 ========== -export const MOCK_USER_API_KEYS: ApiKey[] = [ +export const MOCK_USER_API_KEYS = [ { id: 'key-uuid-001', key_display: 'sk-ae...x7f9', @@ -346,7 +348,8 @@ export const MOCK_USER_API_KEYS: ApiKey[] = [ is_active: true, is_standalone: false, total_requests: 1234, - total_cost_usd: 45.67 + total_cost_usd: 45.67, + force_capabilities: null }, { id: 'key-uuid-002', @@ -357,7 +360,8 @@ export const MOCK_USER_API_KEYS: ApiKey[] = [ is_active: true, is_standalone: false, total_requests: 5678, - total_cost_usd: 123.45 + total_cost_usd: 123.45, + force_capabilities: { cache_1h: true } }, { id: 'key-uuid-003', @@ -367,7 +371,8 @@ export const MOCK_USER_API_KEYS: ApiKey[] = [ is_active: false, is_standalone: false, total_requests: 100, - total_cost_usd: 2.34 + total_cost_usd: 2.34, + force_capabilities: null } ] @@ -813,16 +818,16 @@ export const MOCK_USAGE_RESPONSE: UsageResponse = { quota_usd: 100, used_usd: 45.32, summary_by_model: [ - { model: 'claude-sonnet-4-20250514', requests: 456, input_tokens: 650000, output_tokens: 250000, total_tokens: 900000, total_cost_usd: 18.50, actual_total_cost_usd: 13.50 }, - { model: 'gpt-4o', requests: 312, input_tokens: 480000, output_tokens: 180000, total_tokens: 660000, total_cost_usd: 12.30, actual_total_cost_usd: 9.20 }, - { model: 'claude-haiku-3-5-20241022', requests: 289, input_tokens: 420000, output_tokens: 170000, total_tokens: 590000, total_cost_usd: 8.50, actual_total_cost_usd: 6.30 }, - { model: 'gemini-2.0-flash', requests: 177, input_tokens: 250000, output_tokens: 100000, total_tokens: 350000, total_cost_usd: 6.37, actual_total_cost_usd: 4.33 } + { model: 'claude-sonnet-4-5-20250929', requests: 456, input_tokens: 650000, output_tokens: 250000, total_tokens: 900000, total_cost_usd: 18.50, actual_total_cost_usd: 13.50 }, + { model: 'gpt-5.1', requests: 312, input_tokens: 480000, output_tokens: 180000, total_tokens: 660000, total_cost_usd: 12.30, actual_total_cost_usd: 9.20 }, + { model: 'claude-haiku-4-5-20251001', requests: 289, input_tokens: 420000, output_tokens: 170000, total_tokens: 590000, total_cost_usd: 8.50, actual_total_cost_usd: 6.30 }, + { model: 'gemini-3-pro-preview', requests: 177, input_tokens: 250000, output_tokens: 100000, total_tokens: 350000, total_cost_usd: 6.37, actual_total_cost_usd: 4.33 } ], records: [ { id: 'usage-001', provider: 'anthropic', - model: 'claude-sonnet-4-20250514', + model: 'claude-sonnet-4-5-20250929', input_tokens: 1500, output_tokens: 800, total_tokens: 2300, @@ -837,7 +842,7 @@ export const MOCK_USAGE_RESPONSE: UsageResponse = { { id: 'usage-002', provider: 'openai', - model: 'gpt-4o', + model: 'gpt-5.1', input_tokens: 2000, output_tokens: 500, total_tokens: 2500, diff --git a/frontend/src/mocks/handler.ts b/frontend/src/mocks/handler.ts index 52ac2b4..cc412c3 100644 --- a/frontend/src/mocks/handler.ts +++ b/frontend/src/mocks/handler.ts @@ -405,10 +405,10 @@ function getUsageRecords() { // Mock 映射数据 const MOCK_ALIASES = [ - { id: 'alias-001', source_model: 'claude-4-sonnet', target_global_model_id: 'gm-001', target_global_model_name: 'claude-sonnet-4-20250514', target_global_model_display_name: 'Claude Sonnet 4', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, - { id: 'alias-002', source_model: 'claude-4-opus', target_global_model_id: 'gm-002', target_global_model_name: 'claude-opus-4-20250514', target_global_model_display_name: 'Claude Opus 4', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, - { id: 'alias-003', source_model: 'gpt4o', target_global_model_id: 'gm-004', target_global_model_name: 'gpt-4o', target_global_model_display_name: 'GPT-4o', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, - { id: 'alias-004', source_model: 'gemini-flash', target_global_model_id: 'gm-005', target_global_model_name: 'gemini-2.0-flash', target_global_model_display_name: 'Gemini 2.0 Flash', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' } + { id: 'alias-001', source_model: 'claude-4-sonnet', target_global_model_id: 'gm-003', target_global_model_name: 'claude-sonnet-4-5-20250929', target_global_model_display_name: 'Claude Sonnet 4.5', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, + { id: 'alias-002', source_model: 'claude-4-opus', target_global_model_id: 'gm-002', target_global_model_name: 'claude-opus-4-5-20251101', target_global_model_display_name: 'Claude Opus 4.5', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, + { id: 'alias-003', source_model: 'gpt5', target_global_model_id: 'gm-006', target_global_model_name: 'gpt-5.1', target_global_model_display_name: 'GPT-5.1', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' }, + { id: 'alias-004', source_model: 'gemini-pro', target_global_model_id: 'gm-005', target_global_model_name: 'gemini-3-pro-preview', target_global_model_display_name: 'Gemini 3 Pro Preview', provider_id: null, provider_name: null, scope: 'global', mapping_type: 'alias', is_active: true, created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z' } ] // Mock Endpoint Keys @@ -2172,10 +2172,10 @@ function generateIntervalTimelineData( // 模型列表(用于按模型区分颜色) const models = [ - 'claude-sonnet-4-20250514', - 'claude-3-5-sonnet-20241022', - 'claude-3-5-haiku-20241022', - 'claude-opus-4-20250514' + 'claude-sonnet-4-5-20250929', + 'claude-haiku-4-5-20251001', + 'claude-opus-4-5-20251101', + 'gpt-5.1' ] // 生成模拟的请求间隔数据 diff --git a/pyproject.toml b/pyproject.toml index 88b02ee..3746e20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ authors = [ classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", + "License :: Other/Proprietary License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9",