Просмотр исходного кода

Show requesty key balance on the settings screen (#1995)

Matt Rubens 9 месяцев назад
Родитель
Сommit
1fb34b81fa

+ 5 - 0
.changeset/lazy-ducks-hang.md

@@ -0,0 +1,5 @@
+---
+"roo-cline": patch
+---
+
+Show requesty key balance on the settings screen

+ 25 - 1
webview-ui/src/components/settings/ApiOptions.tsx

@@ -47,6 +47,7 @@ import {
 	OPENROUTER_DEFAULT_PROVIDER_NAME,
 } from "@/components/ui/hooks/useOpenRouterModelProviders"
 import { useOpenRouterKeyInfo } from "@/components/ui/hooks/useOpenRouterKeyInfo"
+import { useRequestyKeyInfo } from "@/components/ui/hooks/useRequestyKeyInfo"
 import { MODELS_BY_PROVIDER, PROVIDERS, AWS_REGIONS, VERTEX_REGIONS } from "./constants"
 import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
 import { ModelInfoView } from "./ModelInfoView"
@@ -74,6 +75,24 @@ const OpenRouterBalanceDisplay = ({ apiKey, baseUrl }: { apiKey: string; baseUrl
 	)
 }
 
+const RequestyBalanceDisplay = ({ apiKey }: { apiKey: string }) => {
+	const { data: keyInfo } = useRequestyKeyInfo(apiKey)
+
+	if (!keyInfo) {
+		return null
+	}
+
+	// Parse the balance to a number and format it to 2 decimal places
+	const balance = parseFloat(keyInfo.org_balance)
+	const formattedBalance = balance.toFixed(2)
+
+	return (
+		<VSCodeLink href="https://app.requesty.ai/settings" className="text-vscode-foreground hover:underline">
+			${formattedBalance}
+		</VSCodeLink>
+	)
+}
+
 interface ApiOptionsProps {
 	uriScheme: string | undefined
 	apiConfiguration: ApiConfiguration
@@ -427,7 +446,12 @@ const ApiOptions = ({
 						onInput={handleInputChange("requestyApiKey")}
 						placeholder={t("settings:providers.getRequestyApiKey")}
 						className="w-full">
-						<label className="block font-medium mb-1">{t("settings:providers.requestyApiKey")}</label>
+						<div className="flex justify-between items-center mb-1">
+							<label className="block font-medium">{t("settings:providers.requestyApiKey")}</label>
+							{apiConfiguration?.requestyApiKey && (
+								<RequestyBalanceDisplay apiKey={apiConfiguration.requestyApiKey} />
+							)}
+						</div>
 					</VSCodeTextField>
 					<div className="text-sm text-vscode-descriptionForeground -mt-2">
 						{t("settings:providers.apiKeyStorageNotice")}

+ 50 - 0
webview-ui/src/components/ui/hooks/useRequestyKeyInfo.ts

@@ -0,0 +1,50 @@
+import axios from "axios"
+import { z } from "zod"
+import { useQuery, UseQueryOptions } from "@tanstack/react-query"
+
+const requestyKeyInfoSchema = z.object({
+	name: z.string(),
+	monthly_limit: z.string(),
+	monthly_spend: z.string(),
+	org_balance: z.string(),
+	config: z.object({
+		aliases: z.record(z.string(), z.any()).optional(),
+	}),
+})
+
+export type RequestyKeyInfo = z.infer<typeof requestyKeyInfoSchema>
+
+async function getRequestyKeyInfo(apiKey?: string) {
+	if (!apiKey) return null
+
+	try {
+		const response = await axios.get("https://api.requesty.ai/x/apikey", {
+			headers: {
+				Authorization: `Bearer ${apiKey}`,
+				"Content-Type": "application/json",
+			},
+		})
+
+		const result = requestyKeyInfoSchema.safeParse(response.data)
+		if (!result.success) {
+			console.error("Requesty API key info validation failed:", result.error)
+			return null
+		}
+
+		return result.data
+	} catch (error) {
+		console.error("Error fetching Requesty key info:", error)
+		return null
+	}
+}
+
+type UseRequestyKeyInfoOptions = Omit<UseQueryOptions<RequestyKeyInfo | null>, "queryKey" | "queryFn">
+export const useRequestyKeyInfo = (apiKey?: string, options?: UseRequestyKeyInfoOptions) => {
+	return useQuery<RequestyKeyInfo | null>({
+		queryKey: ["requesty-key-info", apiKey],
+		queryFn: () => getRequestyKeyInfo(apiKey),
+		staleTime: 30 * 1000, // 30 seconds
+		enabled: !!apiKey,
+		...options,
+	})
+}