Use user info proxy (#1963)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Switches budget fetch to `https://api.dyad.sh/v1/user/info` and validates/consumes `usedCredits`, `totalCredits`, and `budgetResetDate` directly via Zod. > > - **IPC/Pro handlers (`src/ipc/handlers/pro_handlers.ts`)**: > - **Endpoint**: Update user info URL to `https://api.dyad.sh/v1/user/info`. > - **Validation**: Add `zod` schema `UserInfoResponseSchema` to validate API response. > - **Data mapping**: Use `usedCredits`, `totalCredits`, `budgetResetDate`, and `userId` from response directly; remove conversion logic and old nested `user_info` parsing. > - **Redaction**: Compute `redactedUserId` from `userId` and return parsed `UserBudgetInfo`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit da1f192c2cabb2154bd10b69555c27d62fbb6368. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> ## Summary by cubic Switched user budget fetch to the new user info proxy and added schema validation. Uses API-provided credits directly and removes the old conversion logic. - **Refactors** - Use https://api.dyad.sh/v1/user/info instead of llm-gateway. - Validate response with a Zod schema (usedCredits, totalCredits, budgetResetDate, userId). - Map fields directly to UserBudgetInfo and remove CONVERSION_RATIO. - Keep redacted user ID format (****1234). - **Dependencies** - Removed unused html-dom-parser, html-react-parser, and react-property from the lockfile. <sup>Written for commit da1f192c2cabb2154bd10b69555c27d62fbb6368. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -4,12 +4,19 @@ import { createLoggedHandler } from "./safe_handle";
|
||||
import { readSettings } from "../../main/settings"; // Assuming settings are read this way
|
||||
import { UserBudgetInfo, UserBudgetInfoSchema } from "../ipc_types";
|
||||
import { IS_TEST_BUILD } from "../utils/test_utils";
|
||||
import { z } from "zod";
|
||||
|
||||
export const UserInfoResponseSchema = z.object({
|
||||
usedCredits: z.number(),
|
||||
totalCredits: z.number(),
|
||||
budgetResetDate: z.string(), // ISO date string from API
|
||||
userId: z.string(),
|
||||
});
|
||||
export type UserInfoResponse = z.infer<typeof UserInfoResponseSchema>;
|
||||
|
||||
const logger = log.scope("pro_handlers");
|
||||
const handle = createLoggedHandler(logger);
|
||||
|
||||
const CONVERSION_RATIO = (10 * 3) / 2;
|
||||
|
||||
export function registerProHandlers() {
|
||||
// This method should try to avoid throwing errors because this is auxiliary
|
||||
// information and isn't critical to using the app
|
||||
@@ -36,7 +43,7 @@ export function registerProHandlers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = "https://llm-gateway.dyad.sh/user/info";
|
||||
const url = "https://api.dyad.sh/v1/user/info";
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
@@ -57,21 +64,28 @@ export function registerProHandlers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const userInfoData = data["user_info"];
|
||||
const userId = userInfoData["user_id"];
|
||||
const rawData = await response.json();
|
||||
|
||||
// Validate the API response structure
|
||||
const data = UserInfoResponseSchema.parse(rawData);
|
||||
|
||||
// Turn user_abc1234 => "****1234"
|
||||
// Preserve the last 4 characters so we can correlate bug reports
|
||||
// with the user.
|
||||
const redactedUserId =
|
||||
userId.length > 8 ? "****" + userId.slice(-4) : "<redacted>";
|
||||
data.userId.length > 8 ? "****" + data.userId.slice(-4) : "<redacted>";
|
||||
|
||||
logger.info("Successfully fetched user budget information.");
|
||||
return UserBudgetInfoSchema.parse({
|
||||
usedCredits: userInfoData["spend"] * CONVERSION_RATIO,
|
||||
totalCredits: userInfoData["max_budget"] * CONVERSION_RATIO,
|
||||
budgetResetDate: new Date(userInfoData["budget_reset_at"]),
|
||||
|
||||
// Transform to UserBudgetInfo format
|
||||
const userBudgetInfo = UserBudgetInfoSchema.parse({
|
||||
usedCredits: data.usedCredits,
|
||||
totalCredits: data.totalCredits,
|
||||
budgetResetDate: new Date(data.budgetResetDate),
|
||||
redactedUserId: redactedUserId,
|
||||
});
|
||||
|
||||
return userBudgetInfo;
|
||||
} catch (error: any) {
|
||||
logger.error(`Error fetching user budget: ${error.message}`, error);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user