@link-assistant/hive-mind 1.24.4 → 1.24.6
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 +26 -0
- package/README.md +0 -4
- package/package.json +1 -1
- package/src/agent.lib.mjs +12 -0
- package/src/claude.lib.mjs +52 -10
- package/src/hive.config.lib.mjs +1 -1
- package/src/solve.config.lib.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.24.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Make `--auto-resume-on-limit-reset` enabled by default to improve user experience when hitting API rate limits. Previously defaulted to `false`, now defaults to `true` for both `solve` and `hive` commands. Users can explicitly disable with `--no-auto-resume-on-limit-reset` if needed.
|
|
8
|
+
|
|
9
|
+
Fix false positive error detection for step_finish with reason stop
|
|
10
|
+
|
|
11
|
+
When an agent encounters a timeout error during execution but successfully recovers and completes (indicated by `step_finish` with `reason: "stop"`), the error detection was incorrectly flagging this as a failure due to fallback pattern matching.
|
|
12
|
+
|
|
13
|
+
The `agentCompletedSuccessfully` flag was only being set for `session.idle` and `"exiting loop"` log messages (Issue #1276), but not for the more common `step_finish` event with `reason: "stop"`. This meant the fallback pattern matching would still trigger and detect error patterns in the full output, even when the agent had clearly completed successfully.
|
|
14
|
+
|
|
15
|
+
Fix: Add `step_finish` with `reason: "stop"` as a success marker in both stdout and stderr processing loops in `src/agent.lib.mjs`.
|
|
16
|
+
|
|
17
|
+
## 1.24.5
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 17317bb: fix: prevent false positive error detection for JSON-structured stderr warnings (Issue #1337)
|
|
22
|
+
|
|
23
|
+
Claude Code SDK can emit structured JSON log messages to stderr with format `{"level":"warn","message":"..."}`. When these messages contained error-related keywords like "failed", the detection logic incorrectly flagged them as errors.
|
|
24
|
+
|
|
25
|
+
Added JSON parsing for stderr messages starting with `{`. If the parsed JSON has a `level` field that is not `"error"` or `"fatal"`, the message is treated as a warning (non-error), preserving existing emoji-prefix detection as a fallback.
|
|
26
|
+
|
|
27
|
+
Also enables `ANTHROPIC_LOG=debug` when running with `--verbose` flag, allowing users to see detailed API request information as suggested by the BashTool pre-flight warning.
|
|
28
|
+
|
|
3
29
|
## 1.24.4
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -268,12 +268,10 @@ See [docs/HELM.md](./docs/HELM.md) for detailed Helm configuration options.
|
|
|
268
268
|
--attach-logs
|
|
269
269
|
--verbose
|
|
270
270
|
--no-tool-check
|
|
271
|
-
--auto-resume-on-limit-reset
|
|
272
271
|
TELEGRAM_SOLVE_OVERRIDES:
|
|
273
272
|
--attach-logs
|
|
274
273
|
--verbose
|
|
275
274
|
--no-tool-check
|
|
276
|
-
--auto-resume-on-limit-reset
|
|
277
275
|
TELEGRAM_BOT_VERBOSE: true
|
|
278
276
|
"
|
|
279
277
|
|
|
@@ -295,12 +293,10 @@ See [docs/HELM.md](./docs/HELM.md) for detailed Helm configuration options.
|
|
|
295
293
|
--attach-logs
|
|
296
294
|
--verbose
|
|
297
295
|
--no-tool-check
|
|
298
|
-
--auto-resume-on-limit-reset
|
|
299
296
|
)" --solve-overrides "(
|
|
300
297
|
--attach-logs
|
|
301
298
|
--verbose
|
|
302
299
|
--no-tool-check
|
|
303
|
-
--auto-resume-on-limit-reset
|
|
304
300
|
)" --verbose
|
|
305
301
|
|
|
306
302
|
# Press CTRL + A + D for detach from screen
|
package/package.json
CHANGED
package/src/agent.lib.mjs
CHANGED
|
@@ -665,6 +665,13 @@ export const executeAgentCommand = async params => {
|
|
|
665
665
|
if (data.type === 'session.idle' || (data.type === 'log' && data.message === 'exiting loop')) {
|
|
666
666
|
agentCompletedSuccessfully = true;
|
|
667
667
|
}
|
|
668
|
+
// Issue #1296: Detect step_finish with reason "stop" as successful completion
|
|
669
|
+
// This is a clear marker of success - agent finished normally, not due to error or limit
|
|
670
|
+
// When this event appears, we should ignore any error events that appeared earlier in the stream
|
|
671
|
+
// (e.g., timeout errors that were recovered from via retry logic)
|
|
672
|
+
if (data.type === 'step_finish' && data.part?.reason === 'stop') {
|
|
673
|
+
agentCompletedSuccessfully = true;
|
|
674
|
+
}
|
|
668
675
|
} catch {
|
|
669
676
|
// Not JSON - log as plain text
|
|
670
677
|
await log(line);
|
|
@@ -727,6 +734,11 @@ export const executeAgentCommand = async params => {
|
|
|
727
734
|
if (stderrData.type === 'session.idle' || (stderrData.type === 'log' && stderrData.message === 'exiting loop')) {
|
|
728
735
|
agentCompletedSuccessfully = true;
|
|
729
736
|
}
|
|
737
|
+
// Issue #1296: Detect step_finish with reason "stop" as successful completion (stderr)
|
|
738
|
+
// This is a clear marker of success - agent finished normally, not due to error or limit
|
|
739
|
+
if (stderrData.type === 'step_finish' && stderrData.part?.reason === 'stop') {
|
|
740
|
+
agentCompletedSuccessfully = true;
|
|
741
|
+
}
|
|
730
742
|
} catch {
|
|
731
743
|
// Not JSON - log as plain text
|
|
732
744
|
await log(stderrLine);
|
package/src/claude.lib.mjs
CHANGED
|
@@ -724,6 +724,48 @@ export const calculateSessionTokens = async (sessionId, tempDir) => {
|
|
|
724
724
|
throw new Error(`Failed to read session file: ${readError.message}`);
|
|
725
725
|
}
|
|
726
726
|
};
|
|
727
|
+
/**
|
|
728
|
+
* Determines whether a stderr message line should be treated as an error.
|
|
729
|
+
*
|
|
730
|
+
* Excludes:
|
|
731
|
+
* - Emoji-prefixed warnings (Issue #477): lines starting with ⚠️ or ⚠
|
|
732
|
+
* - JSON-structured log messages with non-error level (Issue #1337):
|
|
733
|
+
* e.g. {"level":"warn","message":"...failed..."} — the word "failed" is in
|
|
734
|
+
* the message text but the level is "warn", so it is NOT an error.
|
|
735
|
+
* Only JSON lines with level "error" or "fatal" are treated as real errors.
|
|
736
|
+
*
|
|
737
|
+
* @param {string} message - A single trimmed stderr line
|
|
738
|
+
* @returns {boolean} true if the line should count as an error
|
|
739
|
+
*/
|
|
740
|
+
export const isStderrError = message => {
|
|
741
|
+
const trimmed = message.trim();
|
|
742
|
+
if (!trimmed) return false;
|
|
743
|
+
|
|
744
|
+
// Detection 1: Emoji-prefixed warnings (Issue #477)
|
|
745
|
+
let isWarning = trimmed.startsWith('⚠️') || trimmed.startsWith('⚠');
|
|
746
|
+
|
|
747
|
+
// Detection 2: JSON-structured log messages (Issue #1337)
|
|
748
|
+
if (!isWarning && trimmed.startsWith('{')) {
|
|
749
|
+
try {
|
|
750
|
+
const parsed = JSON.parse(trimmed);
|
|
751
|
+
if (parsed && typeof parsed.level === 'string') {
|
|
752
|
+
const level = parsed.level.toLowerCase();
|
|
753
|
+
// Only "error" and "fatal" levels are real errors.
|
|
754
|
+
if (level !== 'error' && level !== 'fatal') {
|
|
755
|
+
isWarning = true;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
} catch {
|
|
759
|
+
// Not valid JSON — fall through to keyword matching
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (!isWarning && (trimmed.includes('Error:') || trimmed.includes('error') || trimmed.includes('failed') || trimmed.includes('not found'))) {
|
|
764
|
+
return true;
|
|
765
|
+
}
|
|
766
|
+
return false;
|
|
767
|
+
};
|
|
768
|
+
|
|
727
769
|
export const executeClaudeCommand = async params => {
|
|
728
770
|
const {
|
|
729
771
|
tempDir,
|
|
@@ -847,10 +889,17 @@ export const executeClaudeCommand = async params => {
|
|
|
847
889
|
// Pass model for model-specific max output tokens (Issue #1221)
|
|
848
890
|
// Pass thinkLevel and maxBudget for Opus 4.6 effort level conversion (Issue #1238)
|
|
849
891
|
const claudeEnv = getClaudeEnv({ thinkingBudget: resolvedThinkingBudget, model: mappedModel, thinkLevel, maxBudget });
|
|
892
|
+
// Issue #1337: Enable ANTHROPIC_LOG=debug in --verbose mode to diagnose slow API requests.
|
|
893
|
+
// The BashTool pre-flight check suggests "Run with ANTHROPIC_LOG=debug to check for failed or slow API requests."
|
|
894
|
+
// When --verbose is enabled, we propagate ANTHROPIC_LOG=debug so users can see detailed API request info.
|
|
895
|
+
if (argv.verbose) {
|
|
896
|
+
claudeEnv.ANTHROPIC_LOG = 'debug';
|
|
897
|
+
}
|
|
850
898
|
const modelMaxOutputTokens = getMaxOutputTokensForModel(mappedModel);
|
|
851
899
|
if (argv.verbose) await log(`📊 CLAUDE_CODE_MAX_OUTPUT_TOKENS: ${modelMaxOutputTokens}`, { verbose: true });
|
|
852
900
|
if (argv.verbose) await log(`📊 MCP_TIMEOUT: ${claudeCode.mcpTimeout}ms (server startup)`, { verbose: true });
|
|
853
901
|
if (argv.verbose) await log(`📊 MCP_TOOL_TIMEOUT: ${claudeCode.mcpToolTimeout}ms (tool execution)`, { verbose: true });
|
|
902
|
+
if (argv.verbose) await log(`📊 ANTHROPIC_LOG: debug (verbose mode)`, { verbose: true });
|
|
854
903
|
if (resolvedThinkingBudget !== undefined) await log(`📊 MAX_THINKING_TOKENS: ${resolvedThinkingBudget}`, { verbose: true });
|
|
855
904
|
if (claudeEnv.CLAUDE_CODE_EFFORT_LEVEL) await log(`📊 CLAUDE_CODE_EFFORT_LEVEL: ${claudeEnv.CLAUDE_CODE_EFFORT_LEVEL}`, { verbose: true });
|
|
856
905
|
if (!isNewVersion && thinkLevel) await log(`📊 Thinking level (via keywords): ${thinkLevel}`, { verbose: true });
|
|
@@ -1065,16 +1114,9 @@ export const executeClaudeCommand = async params => {
|
|
|
1065
1114
|
// Log stderr immediately
|
|
1066
1115
|
if (errorOutput) {
|
|
1067
1116
|
await log(errorOutput, { stream: 'stderr' });
|
|
1068
|
-
// Track stderr errors for failure detection
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
// Example: "⚠️ [BashTool] Pre-flight check is taking longer than expected. Run with ANTHROPIC_LOG=debug to check for failed or slow API requests."
|
|
1072
|
-
// Even though this contains the word "failed", it's a warning, not an error
|
|
1073
|
-
const isWarning = trimmed.startsWith('⚠️') || trimmed.startsWith('⚠');
|
|
1074
|
-
// Issue #1165: Also detect "command not found" errors (e.g., "/bin/sh: 1: claude: not found")
|
|
1075
|
-
// These indicate the Claude CLI is not installed or not in PATH
|
|
1076
|
-
if (trimmed && !isWarning && (trimmed.includes('Error:') || trimmed.includes('error') || trimmed.includes('failed') || trimmed.includes('not found'))) {
|
|
1077
|
-
stderrErrors.push(trimmed);
|
|
1117
|
+
// Track stderr errors for failure detection using shared helper (Issue #477, #1165, #1337)
|
|
1118
|
+
if (isStderrError(errorOutput)) {
|
|
1119
|
+
stderrErrors.push(errorOutput.trim());
|
|
1078
1120
|
}
|
|
1079
1121
|
}
|
|
1080
1122
|
} else if (chunk.type === 'exit') {
|
package/src/hive.config.lib.mjs
CHANGED
|
@@ -36,7 +36,7 @@ const HIVE_CUSTOM_SOLVE_OPTIONS = {
|
|
|
36
36
|
'auto-resume-on-limit-reset': {
|
|
37
37
|
type: 'boolean',
|
|
38
38
|
description: 'Automatically resume when AI tool limit resets (calculates reset time and waits). Passed to solve command.',
|
|
39
|
-
default:
|
|
39
|
+
default: true,
|
|
40
40
|
},
|
|
41
41
|
'auto-cleanup': {
|
|
42
42
|
type: 'boolean',
|
package/src/solve.config.lib.mjs
CHANGED
|
@@ -132,7 +132,7 @@ export const SOLVE_OPTION_DEFINITIONS = {
|
|
|
132
132
|
'auto-resume-on-limit-reset': {
|
|
133
133
|
type: 'boolean',
|
|
134
134
|
description: 'Automatically resume when AI tool limit resets (maintains session context with --resume flag)',
|
|
135
|
-
default:
|
|
135
|
+
default: true,
|
|
136
136
|
},
|
|
137
137
|
'auto-restart-on-limit-reset': {
|
|
138
138
|
type: 'boolean',
|