@caseyharalson/orrery 0.13.0 → 0.13.1

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.
@@ -251,14 +251,28 @@ function createDefaultResult(stepId, exitCode, stderr) {
251
251
  }
252
252
 
253
253
  /**
254
- * Check if an error condition should trigger failover to another agent
254
+ * Check if agent stdout contains valid structured output (indicating a
255
+ * legitimate task-level result rather than an infrastructure failure).
256
+ * @param {string} stdout - Raw stdout from agent
257
+ * @returns {boolean}
258
+ */
259
+ function hasValidAgentOutput(stdout) {
260
+ if (!stdout) return false;
261
+ const results = parseAgentResults(stdout);
262
+ return results.length > 0;
263
+ }
264
+
265
+ /**
266
+ * Check if an error condition should trigger failover to another agent.
267
+ * Failover triggers on any non-zero exit unless the agent produced valid
268
+ * structured output (indicating a legitimate task-level failure, not an
269
+ * infrastructure issue).
255
270
  * @param {Object} result - Process result with exitCode, stdout, stderr
256
271
  * @param {Error} spawnError - Error from spawn (if any)
257
272
  * @param {boolean} timedOut - Whether the process timed out
258
- * @param {Object} errorPatterns - Regex patterns for error detection
259
273
  * @returns {{shouldFailover: boolean, reason: string}}
260
274
  */
261
- function shouldTriggerFailover(result, spawnError, timedOut, errorPatterns) {
275
+ function shouldTriggerFailover(result, spawnError, timedOut) {
262
276
  // 1. Spawn failures (command not found, ENOENT)
263
277
  if (spawnError) {
264
278
  if (spawnError.code === "ENOENT") {
@@ -272,23 +286,12 @@ function shouldTriggerFailover(result, spawnError, timedOut, errorPatterns) {
272
286
  return { shouldFailover: true, reason: "timeout" };
273
287
  }
274
288
 
275
- // 3. Non-zero exit with error patterns in stderr (but NOT legitimate blocked)
289
+ // 3. Non-zero exit failover unless agent produced valid structured output
276
290
  if (result && result.exitCode !== 0) {
277
- const stderr = result.stderr || "";
278
-
279
- // Check API error patterns
280
- for (const pattern of errorPatterns.apiError || []) {
281
- if (pattern.test(stderr)) {
282
- return { shouldFailover: true, reason: "api_error" };
283
- }
284
- }
285
-
286
- // Check token limit patterns
287
- for (const pattern of errorPatterns.tokenLimit || []) {
288
- if (pattern.test(stderr)) {
289
- return { shouldFailover: true, reason: "token_limit" };
290
- }
291
+ if (hasValidAgentOutput(result.stdout)) {
292
+ return { shouldFailover: false, reason: null };
291
293
  }
294
+ return { shouldFailover: true, reason: "agent_error" };
292
295
  }
293
296
 
294
297
  return { shouldFailover: false, reason: null };
@@ -513,8 +516,7 @@ function invokeAgentWithFailover(
513
516
  const { shouldFailover, reason } = shouldTriggerFailover(
514
517
  result,
515
518
  null,
516
- result.timedOut,
517
- failoverConfig.errorPatterns || {}
519
+ result.timedOut
518
520
  );
519
521
 
520
522
  if (shouldFailover && i < availableAgents.length - 1) {
@@ -535,8 +537,7 @@ function invokeAgentWithFailover(
535
537
  const { shouldFailover, reason } = shouldTriggerFailover(
536
538
  null,
537
539
  spawnError,
538
- false,
539
- failoverConfig.errorPatterns || {}
540
+ false
540
541
  );
541
542
 
542
543
  if (shouldFailover && i < availableAgents.length - 1) {
@@ -595,6 +596,7 @@ module.exports = {
595
596
  invokeAgentWithFailover,
596
597
  parseAgentResults,
597
598
  createDefaultResult,
599
+ shouldTriggerFailover,
598
600
  waitForAll,
599
601
  waitForAny
600
602
  };
@@ -146,30 +146,7 @@ module.exports = {
146
146
 
147
147
  // Timeout in milliseconds before trying next agent (15 minutes)
148
148
  // Can be overridden via ORRERY_AGENT_TIMEOUT environment variable
149
- timeoutMs: 900000,
150
-
151
- // Patterns to detect failover-triggering errors from stderr
152
- errorPatterns: {
153
- // API/connection errors
154
- apiError: [
155
- /API error/i,
156
- /connection refused/i,
157
- /ECONNRESET/i,
158
- /ETIMEDOUT/i,
159
- /network error/i,
160
- /rate limit/i,
161
- /429/,
162
- /502/,
163
- /503/
164
- ],
165
- // Token/context limit errors
166
- tokenLimit: [
167
- /token limit/i,
168
- /context.*(limit|length|exceeded)/i,
169
- /maximum.*tokens/i,
170
- /too long/i
171
- ]
172
- }
149
+ timeoutMs: 900000
173
150
  },
174
151
 
175
152
  // Concurrency control
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caseyharalson/orrery",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Workflow planning and orchestration CLI for AI agents",
5
5
  "license": "MIT",
6
6
  "author": "Casey Haralson",