Compare commits

...

3 Commits

13 changed files with 49 additions and 49 deletions
@@ -936,6 +936,15 @@ export function VisualConfigEditor({
disabled={disabled}
onChange={(quotaSwitchPreviewModel) => onChange({ quotaSwitchPreviewModel })}
/>
<ToggleRow
title={t('config_management.visual.sections.quota.antigravity_credits')}
description={t(
'config_management.visual.sections.quota.antigravity_credits_desc'
)}
checked={values.quotaAntigravityCredits}
disabled={disabled}
onChange={(quotaAntigravityCredits) => onChange({ quotaAntigravityCredits })}
/>
</SectionGrid>
</ConfigSection>
+13 -1
View File
@@ -647,6 +647,12 @@ function getNextDirtyFields(
nextValues.quotaSwitchPreviewModel === baselineValues.quotaSwitchPreviewModel
);
}
if (Object.prototype.hasOwnProperty.call(patch, 'quotaAntigravityCredits')) {
updateDirty(
'quotaAntigravityCredits',
nextValues.quotaAntigravityCredits === baselineValues.quotaAntigravityCredits
);
}
if (Object.prototype.hasOwnProperty.call(patch, 'routingStrategy')) {
updateDirty('routingStrategy', nextValues.routingStrategy === baselineValues.routingStrategy);
}
@@ -827,6 +833,7 @@ export function useVisualConfig() {
quotaSwitchProject: Boolean(quotaExceeded?.['switch-project'] ?? true),
quotaSwitchPreviewModel: Boolean(quotaExceeded?.['switch-preview-model'] ?? true),
quotaAntigravityCredits: Boolean(quotaExceeded?.['antigravity-credits'] ?? true),
routingStrategy: routing?.strategy === 'fill-first' ? 'fill-first' : 'round-robin',
@@ -929,11 +936,16 @@ export function useVisualConfig() {
if (
docHas(doc, ['quota-exceeded']) ||
!values.quotaSwitchProject ||
!values.quotaSwitchPreviewModel
!values.quotaSwitchPreviewModel ||
!values.quotaAntigravityCredits
) {
ensureMapInDoc(doc, ['quota-exceeded']);
doc.setIn(['quota-exceeded', 'switch-project'], values.quotaSwitchProject);
doc.setIn(['quota-exceeded', 'switch-preview-model'], values.quotaSwitchPreviewModel);
doc.setIn(
['quota-exceeded', 'antigravity-credits'],
values.quotaAntigravityCredits
);
deleteIfMapEmpty(doc, ['quota-exceeded']);
}
+3 -12
View File
@@ -891,17 +891,6 @@
"kimi_oauth_status_error": "Authentication failed:",
"kimi_oauth_start_error": "Failed to start Kimi OAuth:",
"kimi_oauth_polling_error": "Failed to check authentication status:",
"qwen_oauth_title": "Qwen OAuth",
"qwen_oauth_button": "Start Qwen Login",
"qwen_oauth_hint": "Login to Qwen service through device authorization flow, automatically obtain and save authentication files.",
"qwen_oauth_url_label": "Authorization URL:",
"qwen_open_link": "Open Link",
"qwen_copy_link": "Copy Link",
"qwen_oauth_status_waiting": "Waiting for authentication...",
"qwen_oauth_status_success": "Authentication successful!",
"qwen_oauth_status_error": "Authentication failed:",
"qwen_oauth_start_error": "Failed to start Qwen OAuth:",
"qwen_oauth_polling_error": "Failed to check authentication status:",
"oauth_callback_label": "Callback URL",
"oauth_callback_placeholder": "http://localhost:1455/auth/callback?code=...&state=...",
"oauth_callback_hint": "Remote browser mode: after the provider redirects to http://localhost:..., copy the full URL and submit it here.",
@@ -1270,7 +1259,9 @@
"switch_project": "Switch Project",
"switch_project_desc": "Automatically switch to another project when quota is exceeded",
"switch_preview_model": "Switch to Preview Model",
"switch_preview_model_desc": "Switch to preview model version when quota is exceeded"
"switch_preview_model_desc": "Switch to preview model version when quota is exceeded",
"antigravity_credits": "Antigravity Credits Retry",
"antigravity_credits_desc": "Retry once with enabledCreditTypes=[\"GOOGLE_ONE_AI\"] when Antigravity returns quota_exhausted 429"
},
"streaming": {
"title": "Streaming Configuration",
+3 -12
View File
@@ -888,17 +888,6 @@
"kimi_oauth_status_error": "Ошибка аутентификации:",
"kimi_oauth_start_error": "Не удалось запустить Kimi OAuth:",
"kimi_oauth_polling_error": "Не удалось проверить статус аутентификации:",
"qwen_oauth_title": "Qwen OAuth",
"qwen_oauth_button": "Начать вход Qwen",
"qwen_oauth_hint": "Выполните вход в сервис Qwen через поток авторизации устройства и автоматически получите/сохраните файлы авторизации.",
"qwen_oauth_url_label": "URL авторизации:",
"qwen_open_link": "Открыть ссылку",
"qwen_copy_link": "Скопировать ссылку",
"qwen_oauth_status_waiting": "Ожидание аутентификации...",
"qwen_oauth_status_success": "Аутентификация успешна!",
"qwen_oauth_status_error": "Ошибка аутентификации:",
"qwen_oauth_start_error": "Не удалось запустить Qwen OAuth:",
"qwen_oauth_polling_error": "Не удалось проверить статус аутентификации:",
"oauth_callback_label": "Callback URL",
"oauth_callback_placeholder": "http://localhost:1455/auth/callback?code=...&state=...",
"oauth_callback_hint": "Режим удалённого браузера: после перенаправления провайдера на http://localhost:... скопируйте полный URL и отправьте его здесь.",
@@ -1269,7 +1258,9 @@
"switch_project": "Переключить проект",
"switch_project_desc": "Автоматически переходить на другой проект при превышении квоты",
"switch_preview_model": "Переключить на preview-модель",
"switch_preview_model_desc": "Переключаться на preview-версию модели при превышении квоты"
"switch_preview_model_desc": "Переключаться на preview-версию модели при превышении квоты",
"antigravity_credits": "Повтор Antigravity Credits",
"antigravity_credits_desc": "При ответе Antigravity quota_exhausted 429 повторять запрос один раз с enabledCreditTypes=[\"GOOGLE_ONE_AI\"]"
},
"streaming": {
"title": "Настройки стриминга",
+3 -12
View File
@@ -891,17 +891,6 @@
"kimi_oauth_status_error": "认证失败:",
"kimi_oauth_start_error": "启动 Kimi OAuth 失败:",
"kimi_oauth_polling_error": "检查认证状态失败:",
"qwen_oauth_title": "Qwen OAuth",
"qwen_oauth_button": "开始 Qwen 登录",
"qwen_oauth_hint": "通过设备授权流程登录 Qwen 服务,自动获取并保存认证文件。",
"qwen_oauth_url_label": "授权链接:",
"qwen_open_link": "打开链接",
"qwen_copy_link": "复制链接",
"qwen_oauth_status_waiting": "等待认证中...",
"qwen_oauth_status_success": "认证成功!",
"qwen_oauth_status_error": "认证失败:",
"qwen_oauth_start_error": "启动 Qwen OAuth 失败:",
"qwen_oauth_polling_error": "检查认证状态失败:",
"oauth_callback_label": "回调 URL",
"oauth_callback_placeholder": "http://localhost:1455/auth/callback?code=...&state=...",
"oauth_callback_hint": "远程浏览器模式:当授权跳转到 http://localhost:... 后,复制完整 URL 并提交到这里。",
@@ -1270,7 +1259,9 @@
"switch_project": "切换项目",
"switch_project_desc": "配额耗尽时自动切换到其他项目",
"switch_preview_model": "切换预览模型",
"switch_preview_model_desc": "配额耗尽时切换到预览版本模型"
"switch_preview_model_desc": "配额耗尽时切换到预览版本模型",
"antigravity_credits": "Antigravity Credits 重试",
"antigravity_credits_desc": "Antigravity 返回 quota_exhausted 429 时,使用 enabledCreditTypes=[\"GOOGLE_ONE_AI\"] 重试一次"
},
"streaming": {
"title": "流式传输配置",
+1 -3
View File
@@ -14,7 +14,6 @@ import iconAntigravity from '@/assets/icons/antigravity.svg';
import iconGemini from '@/assets/icons/gemini.svg';
import iconKimiLight from '@/assets/icons/kimi-light.svg';
import iconKimiDark from '@/assets/icons/kimi-dark.svg';
import iconQwen from '@/assets/icons/qwen.svg';
import iconIflow from '@/assets/icons/iflow.svg';
import iconVertex from '@/assets/icons/vertex.svg';
@@ -76,8 +75,7 @@ const PROVIDERS: { id: OAuthProvider; titleKey: string; hintKey: string; urlLabe
{ id: 'anthropic', titleKey: 'auth_login.anthropic_oauth_title', hintKey: 'auth_login.anthropic_oauth_hint', urlLabelKey: 'auth_login.anthropic_oauth_url_label', icon: iconClaude },
{ id: 'antigravity', titleKey: 'auth_login.antigravity_oauth_title', hintKey: 'auth_login.antigravity_oauth_hint', urlLabelKey: 'auth_login.antigravity_oauth_url_label', icon: iconAntigravity },
{ id: 'gemini-cli', titleKey: 'auth_login.gemini_cli_oauth_title', hintKey: 'auth_login.gemini_cli_oauth_hint', urlLabelKey: 'auth_login.gemini_cli_oauth_url_label', icon: iconGemini },
{ id: 'kimi', titleKey: 'auth_login.kimi_oauth_title', hintKey: 'auth_login.kimi_oauth_hint', urlLabelKey: 'auth_login.kimi_oauth_url_label', icon: { light: iconKimiLight, dark: iconKimiDark } },
{ id: 'qwen', titleKey: 'auth_login.qwen_oauth_title', hintKey: 'auth_login.qwen_oauth_hint', urlLabelKey: 'auth_login.qwen_oauth_url_label', icon: iconQwen }
{ id: 'kimi', titleKey: 'auth_login.kimi_oauth_title', hintKey: 'auth_login.kimi_oauth_hint', urlLabelKey: 'auth_login.kimi_oauth_url_label', icon: { light: iconKimiLight, dark: iconKimiDark } }
];
const CALLBACK_SUPPORTED: OAuthProvider[] = ['codex', 'anthropic', 'antigravity', 'gemini-cli'];
+1 -2
View File
@@ -9,8 +9,7 @@ export type OAuthProvider =
| 'anthropic'
| 'antigravity'
| 'gemini-cli'
| 'kimi'
| 'qwen';
| 'kimi';
export interface OAuthStartResponse {
url: string;
+6 -1
View File
@@ -366,7 +366,12 @@ export const normalizeConfigResponse = (raw: unknown): Config => {
if (isRecord(quota)) {
config.quotaExceeded = {
switchProject: normalizeBoolean(quota['switch-project'] ?? quota.switchProject),
switchPreviewModel: normalizeBoolean(quota['switch-preview-model'] ?? quota.switchPreviewModel)
switchPreviewModel: normalizeBoolean(
quota['switch-preview-model'] ?? quota.switchPreviewModel
),
antigravityCredits: normalizeBoolean(
quota['antigravity-credits'] ?? quota.antigravityCredits
)
};
}
+1
View File
@@ -9,6 +9,7 @@ import type { AmpcodeConfig } from './ampcode';
export interface QuotaExceededConfig {
switchProject?: boolean;
switchPreviewModel?: boolean;
antigravityCredits?: boolean;
}
export interface Config {
+1 -2
View File
@@ -9,8 +9,7 @@ export type OAuthProvider =
| 'anthropic'
| 'antigravity'
| 'gemini-cli'
| 'kimi'
| 'qwen';
| 'kimi';
// OAuth 流程状态
export interface OAuthFlow {
+2
View File
@@ -75,6 +75,7 @@ export type VisualConfigValues = {
maxRetryInterval: string;
quotaSwitchProject: boolean;
quotaSwitchPreviewModel: boolean;
quotaAntigravityCredits: boolean;
routingStrategy: 'round-robin' | 'fill-first';
wsAuth: boolean;
payloadDefaultRules: PayloadRule[];
@@ -114,6 +115,7 @@ export const DEFAULT_VISUAL_VALUES: VisualConfigValues = {
maxRetryInterval: '',
quotaSwitchProject: true,
quotaSwitchPreviewModel: true,
quotaAntigravityCredits: true,
routingStrategy: 'round-robin',
wsAuth: false,
payloadDefaultRules: [],
+2 -4
View File
@@ -57,16 +57,14 @@ export const OAUTH_CARD_IDS = [
'anthropic-oauth-card',
'antigravity-oauth-card',
'gemini-cli-oauth-card',
'kimi-oauth-card',
'qwen-oauth-card'
'kimi-oauth-card'
];
export const OAUTH_PROVIDERS = {
CODEX: 'codex',
ANTHROPIC: 'anthropic',
ANTIGRAVITY: 'antigravity',
GEMINI_CLI: 'gemini-cli',
KIMI: 'kimi',
QWEN: 'qwen'
KIMI: 'kimi'
} as const;
// API 端点
+4
View File
@@ -376,6 +376,10 @@ export function buildCandidateUsageSourceIds(input: {
const apiKey = input.apiKey?.trim();
if (apiKey) {
// Include the normalised form first so that "non-standard" keys (e.g. short tokens,
// keys containing '/' etc.) that are classified as text by normalizeUsageSourceId()
// can still match usage details.
result.push(normalizeUsageSourceId(apiKey));
result.push(`${USAGE_SOURCE_PREFIX_KEY}${fnv1a64Hex(apiKey)}`);
result.push(`${USAGE_SOURCE_PREFIX_MASKED}${maskApiKey(apiKey)}`);
}