File size: 2,929 Bytes
5d0a52f
 
 
 
 
 
 
 
 
ba262d0
 
5d0a52f
 
 
 
 
b3dfc6c
5d0a52f
 
347f81b
 
4f2220c
 
 
 
 
 
 
 
 
 
5d0a52f
 
 
 
 
5dd5107
5d0a52f
 
7e5ecc4
 
5d0a52f
 
 
 
 
4f2665c
 
 
 
5d0a52f
 
 
 
 
 
 
7e5ecc4
5d0a52f
 
 
 
 
 
4f2665c
5d0a52f
 
2996fd8
 
 
 
 
 
 
5d0a52f
 
 
2996fd8
5d0a52f
 
 
2996fd8
 
 
 
5d0a52f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
 * Data models for multi-account management.
 */

export type AccountStatus =
  | "active"
  | "expired"
  | "rate_limited"
  | "refreshing"
  | "disabled"
  | "banned";

export interface AccountUsage {
  request_count: number;
  input_tokens: number;
  output_tokens: number;
  empty_response_count: number;
  last_used: string | null;
  rate_limit_until: string | null;
  /** Tracks the current rate limit window end (Unix seconds). When window rolls over, counters reset. */
  window_reset_at?: number | null;
  /** Per-window request count (resets when window expires). */
  window_request_count?: number;
  /** Per-window input tokens (resets when window expires). */
  window_input_tokens?: number;
  /** Per-window output tokens (resets when window expires). */
  window_output_tokens?: number;
  /** ISO timestamp of when window counters were last reset. */
  window_counters_reset_at?: string | null;
  /** Window duration in seconds, synced from backend, used for local window estimation. */
  limit_window_seconds?: number | null;
}

export interface AccountEntry {
  id: string;
  token: string;
  refreshToken: string | null;
  email: string | null;
  accountId: string | null;
  /** Per-user unique ID (chatgpt_user_id). Team members share accountId but have distinct userId. */
  userId: string | null;
  planType: string | null;
  proxyApiKey: string;
  status: AccountStatus;
  usage: AccountUsage;
  addedAt: string;
  /** Cached official quota from background refresh. Null until first fetch. */
  cachedQuota: CodexQuota | null;
  /** ISO timestamp of when cachedQuota was last updated. */
  quotaFetchedAt: string | null;
}

/** Public info (no token) */
export interface AccountInfo {
  id: string;
  email: string | null;
  accountId: string | null;
  userId: string | null;
  planType: string | null;
  status: AccountStatus;
  usage: AccountUsage;
  addedAt: string;
  expiresAt: string | null;
  quota?: CodexQuota;
  quotaFetchedAt?: string | null;
}

/** A single rate limit window (primary or secondary). */
export interface CodexQuotaWindow {
  used_percent: number | null;
  reset_at: number | null;
  limit_window_seconds: number | null;
}

/** Official Codex quota from /backend-api/codex/usage */
export interface CodexQuota {
  plan_type: string;
  rate_limit: CodexQuotaWindow & {
    allowed: boolean;
    limit_reached: boolean;
  };
  /** Secondary rate limit window (e.g. weekly cap). Null when backend doesn't report one. */
  secondary_rate_limit: CodexQuotaWindow & {
    limit_reached: boolean;
  } | null;
  code_review_rate_limit: {
    allowed: boolean;
    limit_reached: boolean;
    used_percent: number | null;
    reset_at: number | null;
  } | null;
}

/** Returned by acquire() */
export interface AcquiredAccount {
  entryId: string;
  token: string;
  accountId: string | null;
}

/** Persistence format */
export interface AccountsFile {
  accounts: AccountEntry[];
}