mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-29 01:25:33 +08:00
feat: add Token Plan quota query for Kimi, Zhipu GLM, and MiniMax
Add a new "Token Plan" template type in the usage query panel that natively queries quota/usage from Chinese coding plan providers (Kimi For Coding, Zhipu GLM, MiniMax) without requiring custom scripts. - Rust backend: new coding_plan service with provider-specific API queries (Kimi /v1/usages, Zhipu /api/monitor/usage/quota/limit, MiniMax /coding_plan/remains) normalized into UsageResult - Frontend: Token Plan template in UsageScriptModal with auto-detection of provider based on ANTHROPIC_BASE_URL pattern matching - Follows the same pattern as GitHub Copilot template (dedicated API path in queryProviderUsage, no JS script needed)
This commit is contained in:
@@ -95,6 +95,9 @@ const generatePresetTemplates = (
|
||||
|
||||
// GitHub Copilot 模板不需要脚本,使用专用 API
|
||||
[TEMPLATE_TYPES.GITHUB_COPILOT]: "",
|
||||
|
||||
// Coding Plan 模板不需要脚本,使用专用 Rust 查询
|
||||
[TEMPLATE_TYPES.TOKEN_PLAN]: "",
|
||||
});
|
||||
|
||||
// 模板名称国际化键映射
|
||||
@@ -103,8 +106,33 @@ const TEMPLATE_NAME_KEYS: Record<string, string> = {
|
||||
[TEMPLATE_TYPES.GENERAL]: "usageScript.templateGeneral",
|
||||
[TEMPLATE_TYPES.NEW_API]: "usageScript.templateNewAPI",
|
||||
[TEMPLATE_TYPES.GITHUB_COPILOT]: "usageScript.templateCopilot",
|
||||
[TEMPLATE_TYPES.TOKEN_PLAN]: "usageScript.templateTokenPlan",
|
||||
};
|
||||
|
||||
/** Coding Plan 供应商选项 */
|
||||
const TOKEN_PLAN_PROVIDERS = [
|
||||
{ id: "kimi", label: "Kimi For Coding", pattern: /api\.kimi\.com\/coding/i },
|
||||
{
|
||||
id: "zhipu",
|
||||
label: "Zhipu GLM (智谱)",
|
||||
pattern: /bigmodel\.cn|api\.z\.ai/i,
|
||||
},
|
||||
{
|
||||
id: "minimax",
|
||||
label: "MiniMax",
|
||||
pattern: /api\.minimaxi?\.com|api\.minimax\.io/i,
|
||||
},
|
||||
] as const;
|
||||
|
||||
/** 根据 Base URL 自动检测 Coding Plan 供应商 */
|
||||
function detectTokenPlanProvider(baseUrl: string | undefined): string | null {
|
||||
if (!baseUrl) return null;
|
||||
for (const cp of TOKEN_PLAN_PROVIDERS) {
|
||||
if (cp.pattern.test(baseUrl)) return cp.id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
provider,
|
||||
appId,
|
||||
@@ -164,18 +192,39 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
|
||||
const [script, setScript] = useState<UsageScript>(() => {
|
||||
const savedScript = provider.meta?.usage_script;
|
||||
const defaultScript = {
|
||||
if (savedScript) {
|
||||
// 已有配置:如果是 coding_plan 但没有 codingPlanProvider,自动检测填充
|
||||
if (
|
||||
savedScript.templateType === TEMPLATE_TYPES.TOKEN_PLAN &&
|
||||
!savedScript.codingPlanProvider
|
||||
) {
|
||||
return {
|
||||
...savedScript,
|
||||
codingPlanProvider:
|
||||
detectTokenPlanProvider(providerCredentials.baseUrl) || "kimi",
|
||||
};
|
||||
}
|
||||
return savedScript;
|
||||
}
|
||||
|
||||
// 新配置:如果 URL 匹配 Coding Plan,自动初始化
|
||||
const autoDetected = detectTokenPlanProvider(providerCredentials.baseUrl);
|
||||
if (autoDetected) {
|
||||
return {
|
||||
enabled: false,
|
||||
language: "javascript" as const,
|
||||
code: "",
|
||||
timeout: 10,
|
||||
codingPlanProvider: autoDetected,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: false,
|
||||
language: "javascript" as const,
|
||||
code: PRESET_TEMPLATES[TEMPLATE_TYPES.GENERAL],
|
||||
timeout: 10,
|
||||
};
|
||||
|
||||
if (!savedScript) {
|
||||
return defaultScript;
|
||||
}
|
||||
|
||||
return savedScript;
|
||||
});
|
||||
|
||||
const [testing, setTesting] = useState(false);
|
||||
@@ -236,7 +285,7 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
}
|
||||
// 优先使用保存的 templateType
|
||||
if (existingScript?.templateType) {
|
||||
return existingScript.templateType;
|
||||
return existingScript.templateType as string;
|
||||
}
|
||||
// 向后兼容:根据字段推断模板类型
|
||||
// 检测 NEW_API 模板(有 accessToken 或 userId)
|
||||
@@ -247,7 +296,11 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
if (existingScript?.apiKey || existingScript?.baseUrl) {
|
||||
return TEMPLATE_TYPES.GENERAL;
|
||||
}
|
||||
// 新配置或无凭证:默认使用 GENERAL(与默认代码模板一致)
|
||||
// 新配置:如果 URL 匹配 Coding Plan 供应商,自动选择 Coding Plan 模板
|
||||
if (detectTokenPlanProvider(providerCredentials.baseUrl)) {
|
||||
return TEMPLATE_TYPES.TOKEN_PLAN;
|
||||
}
|
||||
// 默认使用 GENERAL(与默认代码模板一致)
|
||||
return TEMPLATE_TYPES.GENERAL;
|
||||
},
|
||||
);
|
||||
@@ -278,8 +331,11 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
// Copilot 模板不需要脚本验证
|
||||
if (selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT) {
|
||||
// Copilot 和 Coding Plan 模板不需要脚本验证
|
||||
if (
|
||||
selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT &&
|
||||
selectedTemplate !== TEMPLATE_TYPES.TOKEN_PLAN
|
||||
) {
|
||||
if (script.enabled && !script.code.trim()) {
|
||||
toast.error(t("usageScript.scriptEmpty"));
|
||||
return;
|
||||
@@ -297,6 +353,7 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
| "general"
|
||||
| "newapi"
|
||||
| "github_copilot"
|
||||
| "token_plan"
|
||||
| undefined,
|
||||
};
|
||||
onSave(scriptWithTemplate);
|
||||
@@ -306,6 +363,45 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
const handleTest = async () => {
|
||||
setTesting(true);
|
||||
try {
|
||||
// Coding Plan 模板使用专用 API
|
||||
if (selectedTemplate === TEMPLATE_TYPES.TOKEN_PLAN) {
|
||||
const config = provider.settingsConfig as Record<string, any>;
|
||||
const baseUrl: string = config?.env?.ANTHROPIC_BASE_URL ?? "";
|
||||
const apiKey: string =
|
||||
config?.env?.ANTHROPIC_AUTH_TOKEN ??
|
||||
config?.env?.ANTHROPIC_API_KEY ??
|
||||
"";
|
||||
const { subscriptionApi } = await import("@/lib/api/subscription");
|
||||
const quota = await subscriptionApi.getCodingPlanQuota(baseUrl, apiKey);
|
||||
if (quota.success && quota.tiers.length > 0) {
|
||||
const summary = quota.tiers
|
||||
.map((tier) => `${tier.name}: ${Math.round(tier.utilization)}%`)
|
||||
.join(", ");
|
||||
toast.success(`${t("usageScript.testSuccess")}${summary}`, {
|
||||
duration: 3000,
|
||||
closeButton: true,
|
||||
});
|
||||
// 将结果转换为 UsageResult 格式更新缓存
|
||||
const usageData = quota.tiers.map((tier) => ({
|
||||
planName: tier.name,
|
||||
remaining: 100 - tier.utilization,
|
||||
total: 100,
|
||||
used: tier.utilization,
|
||||
unit: "%",
|
||||
}));
|
||||
queryClient.setQueryData(["usage", provider.id, appId], {
|
||||
success: true,
|
||||
data: usageData,
|
||||
});
|
||||
} else {
|
||||
toast.error(
|
||||
`${t("usageScript.testFailed")}: ${quota.error || t("endpointTest.noResult")}`,
|
||||
{ duration: 5000 },
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Copilot 模板使用专用 API
|
||||
if (selectedTemplate === TEMPLATE_TYPES.GITHUB_COPILOT) {
|
||||
const accountId = resolveManagedAccountId(
|
||||
@@ -410,7 +506,7 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
|
||||
const handleUsePreset = (presetName: string) => {
|
||||
const preset = PRESET_TEMPLATES[presetName];
|
||||
if (preset) {
|
||||
if (preset !== undefined) {
|
||||
if (presetName === TEMPLATE_TYPES.CUSTOM) {
|
||||
// 🔧 自定义模式:用户应该在脚本中直接写完整 URL 和凭证,而不是依赖变量替换
|
||||
// 这样可以避免同源检查导致的问题
|
||||
@@ -447,6 +543,21 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
accessToken: undefined,
|
||||
userId: undefined,
|
||||
});
|
||||
} else if (presetName === TEMPLATE_TYPES.TOKEN_PLAN) {
|
||||
// Coding Plan 模板不需要脚本,使用 Rust 原生查询
|
||||
const autoDetected = detectTokenPlanProvider(
|
||||
providerCredentials.baseUrl,
|
||||
);
|
||||
setScript({
|
||||
...script,
|
||||
code: "",
|
||||
apiKey: undefined,
|
||||
baseUrl: undefined,
|
||||
accessToken: undefined,
|
||||
userId: undefined,
|
||||
codingPlanProvider:
|
||||
script.codingPlanProvider || autoDetected || "kimi",
|
||||
});
|
||||
}
|
||||
setSelectedTemplate(presetName);
|
||||
}
|
||||
@@ -529,10 +640,11 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
.filter((name) => {
|
||||
const isCopilotProvider =
|
||||
provider.meta?.providerType === "github_copilot";
|
||||
// Copilot 供应商只显示 copilot 模板,其他供应商不显示 copilot 模板
|
||||
// Copilot 供应商只显示 copilot 模板
|
||||
if (isCopilotProvider) {
|
||||
return name === TEMPLATE_TYPES.GITHUB_COPILOT;
|
||||
}
|
||||
// 非 Copilot 供应商不显示 copilot 模板
|
||||
return name !== TEMPLATE_TYPES.GITHUB_COPILOT;
|
||||
})
|
||||
.map((name) => {
|
||||
@@ -634,6 +746,43 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Coding Plan 模式:供应商选择 */}
|
||||
{selectedTemplate === TEMPLATE_TYPES.TOKEN_PLAN && (
|
||||
<div className="space-y-3 border-t border-white/10 pt-3">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t("usageScript.tokenPlanHint")}
|
||||
</p>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{TOKEN_PLAN_PROVIDERS.map((cp) => (
|
||||
<Button
|
||||
key={cp.id}
|
||||
type="button"
|
||||
variant={
|
||||
script.codingPlanProvider === cp.id
|
||||
? "default"
|
||||
: "outline"
|
||||
}
|
||||
size="sm"
|
||||
className={cn(
|
||||
"rounded-lg border",
|
||||
script.codingPlanProvider === cp.id
|
||||
? "shadow-sm"
|
||||
: "bg-background text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
||||
)}
|
||||
onClick={() =>
|
||||
setScript({
|
||||
...script,
|
||||
codingPlanProvider: cp.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
{cp.label}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 凭证配置 */}
|
||||
{shouldShowCredentialsConfig && (
|
||||
<div className="space-y-4">
|
||||
@@ -860,40 +1009,42 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
</div>
|
||||
|
||||
{/* 提取器代码 - Copilot 模板不需要 */}
|
||||
{selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT && (
|
||||
<div className="space-y-4 glass rounded-xl border border-white/10 p-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-base font-medium">
|
||||
{t("usageScript.extractorCode")}
|
||||
</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{t("usageScript.extractorHint")}
|
||||
{selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT &&
|
||||
selectedTemplate !== TEMPLATE_TYPES.TOKEN_PLAN && (
|
||||
<div className="space-y-4 glass rounded-xl border border-white/10 p-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-base font-medium">
|
||||
{t("usageScript.extractorCode")}
|
||||
</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{t("usageScript.extractorHint")}
|
||||
</div>
|
||||
</div>
|
||||
<JsonEditor
|
||||
id="usage-code"
|
||||
value={script.code || ""}
|
||||
onChange={(value) =>
|
||||
setScript((prev) => ({ ...prev, code: value }))
|
||||
}
|
||||
height={480}
|
||||
language="javascript"
|
||||
showMinimap={false}
|
||||
/>
|
||||
</div>
|
||||
<JsonEditor
|
||||
id="usage-code"
|
||||
value={script.code || ""}
|
||||
onChange={(value) =>
|
||||
setScript((prev) => ({ ...prev, code: value }))
|
||||
}
|
||||
height={480}
|
||||
language="javascript"
|
||||
showMinimap={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
{/* 帮助信息 - Copilot 模板不需要 */}
|
||||
{selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT && (
|
||||
<div className="glass rounded-xl border border-white/10 p-6 text-sm text-foreground/90">
|
||||
<h4 className="font-medium mb-2">
|
||||
{t("usageScript.scriptHelp")}
|
||||
</h4>
|
||||
<div className="space-y-3 text-xs">
|
||||
<div>
|
||||
<strong>{t("usageScript.configFormat")}</strong>
|
||||
<pre className="mt-1 p-2 bg-black/20 text-foreground rounded border border-white/10 text-[10px] overflow-x-auto">
|
||||
{`({
|
||||
{selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT &&
|
||||
selectedTemplate !== TEMPLATE_TYPES.TOKEN_PLAN && (
|
||||
<div className="glass rounded-xl border border-white/10 p-6 text-sm text-foreground/90">
|
||||
<h4 className="font-medium mb-2">
|
||||
{t("usageScript.scriptHelp")}
|
||||
</h4>
|
||||
<div className="space-y-3 text-xs">
|
||||
<div>
|
||||
<strong>{t("usageScript.configFormat")}</strong>
|
||||
<pre className="mt-1 p-2 bg-black/20 text-foreground rounded border border-white/10 text-[10px] overflow-x-auto">
|
||||
{`({
|
||||
request: {
|
||||
url: "{{baseUrl}}/api/usage",
|
||||
method: "POST",
|
||||
@@ -910,39 +1061,39 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
||||
};
|
||||
}
|
||||
})`}
|
||||
</pre>
|
||||
</div>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>{t("usageScript.extractorFormat")}</strong>
|
||||
<ul className="mt-1 space-y-0.5 ml-2">
|
||||
<li>{t("usageScript.fieldIsValid")}</li>
|
||||
<li>{t("usageScript.fieldInvalidMessage")}</li>
|
||||
<li>{t("usageScript.fieldRemaining")}</li>
|
||||
<li>{t("usageScript.fieldUnit")}</li>
|
||||
<li>{t("usageScript.fieldPlanName")}</li>
|
||||
<li>{t("usageScript.fieldTotal")}</li>
|
||||
<li>{t("usageScript.fieldUsed")}</li>
|
||||
<li>{t("usageScript.fieldExtra")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<strong>{t("usageScript.extractorFormat")}</strong>
|
||||
<ul className="mt-1 space-y-0.5 ml-2">
|
||||
<li>{t("usageScript.fieldIsValid")}</li>
|
||||
<li>{t("usageScript.fieldInvalidMessage")}</li>
|
||||
<li>{t("usageScript.fieldRemaining")}</li>
|
||||
<li>{t("usageScript.fieldUnit")}</li>
|
||||
<li>{t("usageScript.fieldPlanName")}</li>
|
||||
<li>{t("usageScript.fieldTotal")}</li>
|
||||
<li>{t("usageScript.fieldUsed")}</li>
|
||||
<li>{t("usageScript.fieldExtra")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="text-muted-foreground">
|
||||
<strong>{t("usageScript.tips")}</strong>
|
||||
<ul className="mt-1 space-y-0.5 ml-2">
|
||||
<li>
|
||||
{t("usageScript.tip1", {
|
||||
apiKey: "{{apiKey}}",
|
||||
baseUrl: "{{baseUrl}}",
|
||||
})}
|
||||
</li>
|
||||
<li>{t("usageScript.tip2")}</li>
|
||||
<li>{t("usageScript.tip3")}</li>
|
||||
</ul>
|
||||
<div className="text-muted-foreground">
|
||||
<strong>{t("usageScript.tips")}</strong>
|
||||
<ul className="mt-1 space-y-0.5 ml-2">
|
||||
<li>
|
||||
{t("usageScript.tip1", {
|
||||
apiKey: "{{apiKey}}",
|
||||
baseUrl: "{{baseUrl}}",
|
||||
})}
|
||||
</li>
|
||||
<li>{t("usageScript.tip2")}</li>
|
||||
<li>{t("usageScript.tip3")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -343,9 +343,7 @@ export function ProviderCard({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex items-center ml-auto min-w-0 gap-3"
|
||||
>
|
||||
<div className="flex items-center ml-auto min-w-0 gap-3">
|
||||
<div className="ml-auto">
|
||||
<div className="flex items-center gap-1">
|
||||
{isOfficial ? (
|
||||
@@ -393,9 +391,7 @@ export function ProviderCard({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex items-center gap-1.5 flex-shrink-0 opacity-0 pointer-events-none group-hover:opacity-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-focus-within:pointer-events-auto transition-opacity duration-200"
|
||||
>
|
||||
<div className="flex items-center gap-1.5 flex-shrink-0 opacity-0 pointer-events-none group-hover:opacity-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-focus-within:pointer-events-auto transition-opacity duration-200">
|
||||
<ProviderActions
|
||||
appId={appId}
|
||||
isCurrent={isCurrent}
|
||||
@@ -406,7 +402,9 @@ export function ProviderCard({
|
||||
onSwitch={() => onSwitch(provider)}
|
||||
onEdit={() => onEdit(provider)}
|
||||
onDuplicate={() => onDuplicate(provider)}
|
||||
onTest={onTest && !isOfficial ? () => onTest(provider) : undefined}
|
||||
onTest={
|
||||
onTest && !isOfficial ? () => onTest(provider) : undefined
|
||||
}
|
||||
onConfigureUsage={
|
||||
isOfficial ? undefined : () => onConfigureUsage(provider)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export const TEMPLATE_TYPES = {
|
||||
GENERAL: "general",
|
||||
NEW_API: "newapi",
|
||||
GITHUB_COPILOT: "github_copilot",
|
||||
TOKEN_PLAN: "token_plan",
|
||||
} as const;
|
||||
|
||||
export type TemplateType = (typeof TEMPLATE_TYPES)[keyof typeof TEMPLATE_TYPES];
|
||||
|
||||
@@ -1090,7 +1090,9 @@
|
||||
"templateGeneral": "General",
|
||||
"templateNewAPI": "NewAPI",
|
||||
"templateCopilot": "GitHub Copilot",
|
||||
"templateTokenPlan": "Token Plan",
|
||||
"copilotAutoAuth": "Auto OAuth authentication, no manual credentials needed",
|
||||
"tokenPlanHint": "Automatically uses the provider's API Key and Base URL to query Token Plan quota",
|
||||
"resetDate": "Reset date",
|
||||
"premiumRequests": "Premium Requests",
|
||||
"credentialsConfig": "Credentials",
|
||||
|
||||
@@ -1090,7 +1090,9 @@
|
||||
"templateGeneral": "General",
|
||||
"templateNewAPI": "NewAPI",
|
||||
"templateCopilot": "GitHub Copilot",
|
||||
"templateTokenPlan": "Token Plan",
|
||||
"copilotAutoAuth": "OAuth 認証を自動使用、手動設定不要",
|
||||
"tokenPlanHint": "プロバイダーのAPI KeyとBase URLを使用してToken Planクォータを自動クエリ",
|
||||
"resetDate": "リセット日",
|
||||
"premiumRequests": "Premium リクエスト",
|
||||
"credentialsConfig": "認証情報",
|
||||
|
||||
@@ -1090,7 +1090,9 @@
|
||||
"templateGeneral": "通用模板",
|
||||
"templateNewAPI": "NewAPI",
|
||||
"templateCopilot": "GitHub Copilot",
|
||||
"templateTokenPlan": "Token Plan",
|
||||
"copilotAutoAuth": "自动使用 OAuth 认证,无需手动配置凭证",
|
||||
"tokenPlanHint": "自动使用供应商的 API Key 和 Base URL 查询 Token Plan 额度",
|
||||
"resetDate": "重置日期",
|
||||
"premiumRequests": "Premium 请求",
|
||||
"credentialsConfig": "凭证配置",
|
||||
|
||||
@@ -4,4 +4,9 @@ import type { SubscriptionQuota } from "@/types/subscription";
|
||||
export const subscriptionApi = {
|
||||
getQuota: (tool: string): Promise<SubscriptionQuota> =>
|
||||
invoke("get_subscription_quota", { tool }),
|
||||
getCodingPlanQuota: (
|
||||
baseUrl: string,
|
||||
apiKey: string,
|
||||
): Promise<SubscriptionQuota> =>
|
||||
invoke("get_coding_plan_quota", { baseUrl, apiKey }),
|
||||
};
|
||||
|
||||
@@ -62,6 +62,7 @@ export interface UsageScript {
|
||||
baseUrl?: string; // 用量查询专用的 Base URL(通用和 NewAPI 模板使用)
|
||||
accessToken?: string; // 访问令牌(NewAPI 模板使用)
|
||||
userId?: string; // 用户ID(NewAPI 模板使用)
|
||||
codingPlanProvider?: string; // Coding Plan 供应商标识(如 "kimi", "zhipu", "minimax")
|
||||
autoQueryInterval?: number; // 自动查询间隔(单位:分钟,0 表示禁用)
|
||||
autoIntervalMinutes?: number; // 自动查询间隔(分钟)- 别名字段
|
||||
request?: {
|
||||
|
||||
Reference in New Issue
Block a user