@link-assistant/hive-mind 1.0.1 → 1.0.3
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 +27 -0
- package/package.json +1 -1
- package/src/claude.lib.mjs +7 -14
- package/src/config.lib.mjs +29 -0
- package/src/limits.lib.mjs +37 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 26b69f2: Fix Claude Code output token limit by setting CLAUDE_CODE_MAX_OUTPUT_TOKENS to 64000
|
|
8
|
+
- Claude Code CLI defaults to 32K output token limit, but Claude Sonnet/Opus/Haiku 4.5 models support 64K
|
|
9
|
+
- Added `claudeCode.maxOutputTokens` configuration in `config.lib.mjs` (default: 64000)
|
|
10
|
+
- Pass `CLAUDE_CODE_MAX_OUTPUT_TOKENS` environment variable when executing Claude CLI
|
|
11
|
+
- Configuration can be overridden via `CLAUDE_CODE_MAX_OUTPUT_TOKENS` or `HIVE_MIND_CLAUDE_CODE_MAX_OUTPUT_TOKENS` environment variables
|
|
12
|
+
- Added comprehensive case study analysis in `docs/case-studies/issue-1076/`
|
|
13
|
+
|
|
14
|
+
See: https://github.com/link-assistant/hive-mind/issues/1076
|
|
15
|
+
|
|
16
|
+
## 1.0.2
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 1a96d9f: Fix Claude Usage API rate limiting by increasing cache TTL to 20 minutes
|
|
21
|
+
- The Claude Usage API (`/api/oauth/usage`) was returning null values due to rate limiting when called too frequently
|
|
22
|
+
- Increased default cache TTL from 3 minutes to 20 minutes for Claude Usage API
|
|
23
|
+
- Added configurable environment variable `HIVE_MIND_USAGE_API_CACHE_TTL_MS` (default: 1200000ms = 20 minutes)
|
|
24
|
+
- Added HTTP response status logging for easier debugging
|
|
25
|
+
- Added explicit 429 rate limit error handling
|
|
26
|
+
- Updated documentation in `docs/CONFIGURATION.md`
|
|
27
|
+
|
|
28
|
+
See: https://github.com/link-assistant/hive-mind/issues/1074
|
|
29
|
+
|
|
3
30
|
## 1.0.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/package.json
CHANGED
package/src/claude.lib.mjs
CHANGED
|
@@ -10,7 +10,7 @@ const path = (await use('path')).default;
|
|
|
10
10
|
// Import log from general lib
|
|
11
11
|
import { log, cleanErrorMessage } from './lib.mjs';
|
|
12
12
|
import { reportError } from './sentry.lib.mjs';
|
|
13
|
-
import { timeouts, retryLimits } from './config.lib.mjs';
|
|
13
|
+
import { timeouts, retryLimits, claudeCode, getClaudeEnv } from './config.lib.mjs';
|
|
14
14
|
import { detectUsageLimit, formatUsageLimitMessage } from './usage-limit.lib.mjs';
|
|
15
15
|
import { createInteractiveHandler } from './interactive-mode.lib.mjs';
|
|
16
16
|
import { displayBudgetStats } from './claude.budget-stats.lib.mjs';
|
|
@@ -931,24 +931,17 @@ export const executeClaudeCommand = async params => {
|
|
|
931
931
|
await log('', { verbose: true });
|
|
932
932
|
}
|
|
933
933
|
try {
|
|
934
|
+
const claudeEnv = getClaudeEnv(); // Set CLAUDE_CODE_MAX_OUTPUT_TOKENS (see issue #1076)
|
|
935
|
+
if (argv.verbose) await log(`📊 CLAUDE_CODE_MAX_OUTPUT_TOKENS: ${claudeCode.maxOutputTokens}`, { verbose: true });
|
|
934
936
|
if (argv.resume) {
|
|
935
|
-
// When resuming, pass prompt directly with -p flag
|
|
936
|
-
// Use simpler escaping - just escape double quotes
|
|
937
|
+
// When resuming, pass prompt directly with -p flag. Escape double quotes for shell.
|
|
937
938
|
const simpleEscapedPrompt = prompt.replace(/"/g, '\\"');
|
|
938
939
|
const simpleEscapedSystem = systemPrompt.replace(/"/g, '\\"');
|
|
939
|
-
execCommand = $({
|
|
940
|
-
cwd: tempDir,
|
|
941
|
-
mirror: false,
|
|
942
|
-
})`${claudePath} --resume ${argv.resume} --output-format stream-json --verbose --dangerously-skip-permissions --model ${mappedModel} -p "${simpleEscapedPrompt}" --append-system-prompt "${simpleEscapedSystem}"`;
|
|
940
|
+
execCommand = $({ cwd: tempDir, mirror: false, env: claudeEnv })`${claudePath} --resume ${argv.resume} --output-format stream-json --verbose --dangerously-skip-permissions --model ${mappedModel} -p "${simpleEscapedPrompt}" --append-system-prompt "${simpleEscapedSystem}"`;
|
|
943
941
|
} else {
|
|
944
|
-
// When not resuming, pass prompt via stdin
|
|
945
|
-
// For system prompt, escape it properly for shell - just escape double quotes
|
|
942
|
+
// When not resuming, pass prompt via stdin. Escape double quotes for shell.
|
|
946
943
|
const simpleEscapedSystem = systemPrompt.replace(/"/g, '\\"');
|
|
947
|
-
execCommand = $({
|
|
948
|
-
cwd: tempDir,
|
|
949
|
-
stdin: prompt,
|
|
950
|
-
mirror: false,
|
|
951
|
-
})`${claudePath} --output-format stream-json --verbose --dangerously-skip-permissions --model ${mappedModel} --append-system-prompt "${simpleEscapedSystem}"`;
|
|
944
|
+
execCommand = $({ cwd: tempDir, stdin: prompt, mirror: false, env: claudeEnv })`${claudePath} --output-format stream-json --verbose --dangerously-skip-permissions --model ${mappedModel} --append-system-prompt "${simpleEscapedSystem}"`;
|
|
952
945
|
}
|
|
953
946
|
await log(`${formatAligned('📋', 'Command details:', '')}`);
|
|
954
947
|
await log(formatAligned('📂', 'Working directory:', tempDir, 2));
|
package/src/config.lib.mjs
CHANGED
|
@@ -78,6 +78,33 @@ export const retryLimits = {
|
|
|
78
78
|
initial503RetryDelayMs: parseIntWithDefault('HIVE_MIND_INITIAL_503_RETRY_DELAY_MS', 5 * 60 * 1000), // 5 minutes
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
+
// Claude Code CLI configurations
|
|
82
|
+
// See: https://github.com/link-assistant/hive-mind/issues/1076
|
|
83
|
+
// Claude models support up to 64K output tokens, but Claude Code CLI defaults to 32K
|
|
84
|
+
// Setting a higher limit allows Claude to generate longer responses without hitting the limit
|
|
85
|
+
export const claudeCode = {
|
|
86
|
+
// Maximum output tokens for Claude Code CLI responses
|
|
87
|
+
// Default: 64000 (matches Claude Sonnet/Opus/Haiku 4.5 model capabilities)
|
|
88
|
+
// Set via CLAUDE_CODE_MAX_OUTPUT_TOKENS or HIVE_MIND_CLAUDE_CODE_MAX_OUTPUT_TOKENS
|
|
89
|
+
maxOutputTokens: parseIntWithDefault('CLAUDE_CODE_MAX_OUTPUT_TOKENS', parseIntWithDefault('HIVE_MIND_CLAUDE_CODE_MAX_OUTPUT_TOKENS', 64000)),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Helper function to get Claude CLI environment with CLAUDE_CODE_MAX_OUTPUT_TOKENS set
|
|
93
|
+
export const getClaudeEnv = () => ({ ...process.env, CLAUDE_CODE_MAX_OUTPUT_TOKENS: String(claudeCode.maxOutputTokens) });
|
|
94
|
+
|
|
95
|
+
// Cache TTL configurations (in milliseconds)
|
|
96
|
+
// The Usage API (Claude limits) has stricter rate limiting than regular APIs
|
|
97
|
+
// See: https://github.com/link-assistant/hive-mind/issues/1074
|
|
98
|
+
export const cacheTtl = {
|
|
99
|
+
// General API cache TTL (GitHub API, etc.)
|
|
100
|
+
api: parseIntWithDefault('HIVE_MIND_API_CACHE_TTL_MS', 3 * 60 * 1000), // 3 minutes
|
|
101
|
+
// Claude Usage API cache TTL - must be at least 20 minutes to avoid rate limiting
|
|
102
|
+
// The API returns null values when called too frequently
|
|
103
|
+
usageApi: parseIntWithDefault('HIVE_MIND_USAGE_API_CACHE_TTL_MS', 20 * 60 * 1000), // 20 minutes
|
|
104
|
+
// System metrics cache TTL (RAM, CPU, disk)
|
|
105
|
+
system: parseIntWithDefault('HIVE_MIND_SYSTEM_CACHE_TTL_MS', 2 * 60 * 1000), // 2 minutes
|
|
106
|
+
};
|
|
107
|
+
|
|
81
108
|
// File and path configurations
|
|
82
109
|
export const filePaths = {
|
|
83
110
|
tempDir: getenv('HIVE_MIND_TEMP_DIR', '/tmp'),
|
|
@@ -177,6 +204,8 @@ export function getAllConfigurations() {
|
|
|
177
204
|
githubLimits,
|
|
178
205
|
systemLimits,
|
|
179
206
|
retryLimits,
|
|
207
|
+
claudeCode,
|
|
208
|
+
cacheTtl,
|
|
180
209
|
filePaths,
|
|
181
210
|
textProcessing,
|
|
182
211
|
display,
|
package/src/limits.lib.mjs
CHANGED
|
@@ -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:
|
|
792
|
-
|
|
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
|
-
|
|
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.
|
|
893
|
+
if (result.success) cache.set('claude', result, CACHE_TTL.USAGE_API);
|
|
862
894
|
return result;
|
|
863
895
|
}
|
|
864
896
|
|