pikiclaw 0.3.82 → 0.3.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2171,6 +2171,16 @@ const CLAUDE_MODELS = [
2171
2171
  // ---------------------------------------------------------------------------
2172
2172
  // Usage
2173
2173
  // ---------------------------------------------------------------------------
2174
+ // The account-usage query below hits api.anthropic.com/api/oauth/usage, which is
2175
+ // itself rate-limited. The dashboard rebuilds agent status ~every 30s (plus a
2176
+ // forced refresh on usage-ring hover), and querying that often trips the
2177
+ // endpoint's 429 — which (since we treat a query error as "unknown") blanks the
2178
+ // header usage ring entirely. Quota windows (5h/7d) move slowly, so we query at
2179
+ // most once per this interval and serve the last good result in between
2180
+ // (including across transient 429s), decoupling usage cadence from how often
2181
+ // agent status is rebuilt.
2182
+ const CLAUDE_USAGE_QUERY_TTL_MS = 5 * 60_000;
2183
+ const claudeUsageCache = { lastGood: null, lastAttemptAt: 0 };
2174
2184
  function getClaudeOAuthToken() {
2175
2185
  // `security` is macOS-only; other platforms store Claude creds differently
2176
2186
  // (DPAPI on Windows, libsecret on Linux) and Claude Code manages those itself.
@@ -2573,9 +2583,25 @@ class ClaudeDriver {
2573
2583
  const home = getHome();
2574
2584
  if (!home)
2575
2585
  return emptyUsage('claude', 'HOME is not set.');
2576
- return getClaudeUsageFromOAuth()
2577
- || getClaudeUsageFromTelemetry(home, opts.model)
2586
+ const telemetry = () => getClaudeUsageFromTelemetry(home, opts.model)
2578
2587
  || emptyUsage('claude', 'No recent Claude usage data found.');
2588
+ // Throttle the rate-limited OAuth usage query (see CLAUDE_USAGE_QUERY_TTL_MS).
2589
+ // Within the window we reuse the last good result rather than re-querying on
2590
+ // every agent-status rebuild, so a transient query-API 429 can't blank the
2591
+ // ring between successful polls.
2592
+ const now = Date.now();
2593
+ if (now - claudeUsageCache.lastAttemptAt < CLAUDE_USAGE_QUERY_TTL_MS) {
2594
+ return claudeUsageCache.lastGood ?? telemetry();
2595
+ }
2596
+ claudeUsageCache.lastAttemptAt = now;
2597
+ const oauth = getClaudeUsageFromOAuth();
2598
+ if (oauth) {
2599
+ claudeUsageCache.lastGood = oauth;
2600
+ return oauth;
2601
+ }
2602
+ // OAuth unavailable (non-mac, no token, or transient 429): keep showing the
2603
+ // last good windows if we have any; otherwise fall back to telemetry.
2604
+ return claudeUsageCache.lastGood ?? telemetry();
2579
2605
  }
2580
2606
  async deleteNativeSession(workdir, sessionId) {
2581
2607
  const file = claudeSessionTranscriptPath(workdir, sessionId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikiclaw",
3
- "version": "0.3.82",
3
+ "version": "0.3.83",
4
4
  "description": "Put the world's smartest AI agents in your pocket. Command local Claude & Gemini via IM. | 让最好用的 IM 变成你电脑上的顶级 Agent 控制台",
5
5
  "type": "module",
6
6
  "bin": {