@link-assistant/hive-mind 1.0.1 → 1.0.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 1a96d9f: Fix Claude Usage API rate limiting by increasing cache TTL to 20 minutes
8
+ - The Claude Usage API (`/api/oauth/usage`) was returning null values due to rate limiting when called too frequently
9
+ - Increased default cache TTL from 3 minutes to 20 minutes for Claude Usage API
10
+ - Added configurable environment variable `HIVE_MIND_USAGE_API_CACHE_TTL_MS` (default: 1200000ms = 20 minutes)
11
+ - Added HTTP response status logging for easier debugging
12
+ - Added explicit 429 rate limit error handling
13
+ - Updated documentation in `docs/CONFIGURATION.md`
14
+
15
+ See: https://github.com/link-assistant/hive-mind/issues/1074
16
+
3
17
  ## 1.0.1
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -78,6 +78,19 @@ export const retryLimits = {
78
78
  initial503RetryDelayMs: parseIntWithDefault('HIVE_MIND_INITIAL_503_RETRY_DELAY_MS', 5 * 60 * 1000), // 5 minutes
79
79
  };
80
80
 
81
+ // Cache TTL configurations (in milliseconds)
82
+ // The Usage API (Claude limits) has stricter rate limiting than regular APIs
83
+ // See: https://github.com/link-assistant/hive-mind/issues/1074
84
+ export const cacheTtl = {
85
+ // General API cache TTL (GitHub API, etc.)
86
+ api: parseIntWithDefault('HIVE_MIND_API_CACHE_TTL_MS', 3 * 60 * 1000), // 3 minutes
87
+ // Claude Usage API cache TTL - must be at least 20 minutes to avoid rate limiting
88
+ // The API returns null values when called too frequently
89
+ usageApi: parseIntWithDefault('HIVE_MIND_USAGE_API_CACHE_TTL_MS', 20 * 60 * 1000), // 20 minutes
90
+ // System metrics cache TTL (RAM, CPU, disk)
91
+ system: parseIntWithDefault('HIVE_MIND_SYSTEM_CACHE_TTL_MS', 2 * 60 * 1000), // 2 minutes
92
+ };
93
+
81
94
  // File and path configurations
82
95
  export const filePaths = {
83
96
  tempDir: getenv('HIVE_MIND_TEMP_DIR', '/tmp'),
@@ -177,6 +190,7 @@ export function getAllConfigurations() {
177
190
  githubLimits,
178
191
  systemLimits,
179
192
  retryLimits,
193
+ cacheTtl,
180
194
  filePaths,
181
195
  textProcessing,
182
196
  display,
@@ -10,6 +10,9 @@ import { homedir } from 'node:os';
10
10
  import { join } from 'node:path';
11
11
  import { promisify } from 'node:util';
12
12
 
13
+ // Import cache TTL configuration
14
+ import { cacheTtl } from './config.lib.mjs';
15
+
13
16
  const execAsync = promisify(exec);
14
17
 
15
18
  /**
@@ -532,6 +535,11 @@ export async function getClaudeUsageLimits(verbose = false, credentialsPath = DE
532
535
  },
533
536
  });
534
537
 
538
+ // Log HTTP response status for debugging (always, not just on error)
539
+ if (verbose) {
540
+ console.log(`[VERBOSE] /limits API HTTP status: ${response.status} ${response.statusText}`);
541
+ }
542
+
535
543
  if (!response.ok) {
536
544
  const errorText = await response.text();
537
545
  if (verbose) {
@@ -546,6 +554,15 @@ export async function getClaudeUsageLimits(verbose = false, credentialsPath = DE
546
554
  };
547
555
  }
548
556
 
557
+ // Check for rate limiting (429 Too Many Requests)
558
+ if (response.status === 429) {
559
+ const retryAfter = response.headers.get('retry-after');
560
+ return {
561
+ success: false,
562
+ error: `Rate limited by Claude Usage API. ${retryAfter ? `Retry after: ${retryAfter}s` : 'Try again later.'}`,
563
+ };
564
+ }
565
+
549
566
  return {
550
567
  success: false,
551
568
  error: `Failed to fetch usage from API: ${response.status} ${response.statusText}`,
@@ -786,10 +803,21 @@ export function formatUsageMessage(usage, diskSpace = null, githubRateLimit = nu
786
803
 
787
804
  /**
788
805
  * Cache TTL constants (in milliseconds)
806
+ * Values are loaded from config.lib.mjs which supports environment variable overrides.
807
+ *
808
+ * IMPORTANT: The Claude Usage API has stricter rate limiting than regular APIs.
809
+ * Calling it more frequently than every 20 minutes may result in null values being returned.
810
+ * See: https://github.com/link-assistant/hive-mind/issues/1074
811
+ *
812
+ * Configurable via environment variables:
813
+ * - HIVE_MIND_API_CACHE_TTL_MS: General API cache TTL (default: 180000 = 3 minutes)
814
+ * - HIVE_MIND_USAGE_API_CACHE_TTL_MS: Claude Usage API cache TTL (default: 1200000 = 20 minutes)
815
+ * - HIVE_MIND_SYSTEM_CACHE_TTL_MS: System metrics cache TTL (default: 120000 = 2 minutes)
789
816
  */
790
817
  export const CACHE_TTL = {
791
- API: 180000, // 3 minutes for API calls (Claude, GitHub)
792
- SYSTEM: 120000, // 2 minutes for system metrics (RAM, CPU, disk)
818
+ API: cacheTtl.api, // 3 minutes for regular API calls (GitHub)
819
+ USAGE_API: cacheTtl.usageApi, // 20 minutes for Claude Usage API (rate limited)
820
+ SYSTEM: cacheTtl.system, // 2 minutes for system metrics (RAM, CPU, disk)
793
821
  };
794
822
 
795
823
  /**
@@ -852,13 +880,17 @@ export function resetLimitCache() {
852
880
 
853
881
  export async function getCachedClaudeLimits(verbose = false) {
854
882
  const cache = getLimitCache();
855
- const cached = cache.get('claude', CACHE_TTL.API);
883
+ // Use USAGE_API TTL (20 minutes) for Claude limits to avoid rate limiting
884
+ // The Claude Usage API returns null values when called too frequently
885
+ // See: https://github.com/link-assistant/hive-mind/issues/1074
886
+ const cached = cache.get('claude', CACHE_TTL.USAGE_API);
856
887
  if (cached) {
857
- if (verbose) console.log('[VERBOSE] /limits-cache: Using cached Claude limits');
888
+ if (verbose) console.log('[VERBOSE] /limits-cache: Using cached Claude limits (TTL: ' + Math.round(CACHE_TTL.USAGE_API / 60000) + ' minutes)');
858
889
  return cached;
859
890
  }
891
+ if (verbose) console.log('[VERBOSE] /limits-cache: Cache miss for Claude limits, fetching from API...');
860
892
  const result = await getClaudeUsageLimits(verbose);
861
- if (result.success) cache.set('claude', result, CACHE_TTL.API);
893
+ if (result.success) cache.set('claude', result, CACHE_TTL.USAGE_API);
862
894
  return result;
863
895
  }
864
896