@the-open-engine/zeroshot 6.10.2 → 6.12.0

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.
Files changed (76) hide show
  1. package/cli/commands/providers.js +13 -13
  2. package/cli/index.js +77 -35
  3. package/cli/lib/first-run.js +12 -11
  4. package/cli/lib/update-checker.js +517 -132
  5. package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -1
  6. package/lib/agent-cli-provider/adapters/opencode.js +3 -0
  7. package/lib/agent-cli-provider/adapters/opencode.js.map +1 -1
  8. package/lib/agent-cli-provider/types.d.ts +1 -0
  9. package/lib/agent-cli-provider/types.d.ts.map +1 -1
  10. package/lib/agent-cli-provider/types.js.map +1 -1
  11. package/lib/cluster/client.cjs +146 -0
  12. package/lib/cluster/client.d.ts +44 -0
  13. package/lib/cluster/client.mjs +141 -0
  14. package/lib/cluster/connection.cjs +382 -0
  15. package/lib/cluster/connection.d.ts +41 -0
  16. package/lib/cluster/connection.mjs +378 -0
  17. package/lib/cluster/errors.cjs +44 -0
  18. package/lib/cluster/errors.d.ts +23 -0
  19. package/lib/cluster/errors.mjs +32 -0
  20. package/lib/cluster/frames.cjs +49 -0
  21. package/lib/cluster/frames.d.ts +12 -0
  22. package/lib/cluster/frames.mjs +45 -0
  23. package/lib/cluster/generated/protocol-schema.cjs +5 -0
  24. package/lib/cluster/generated/protocol-schema.d.ts +1 -0
  25. package/lib/cluster/generated/protocol-schema.mjs +2 -0
  26. package/lib/cluster/generated/protocol.cjs +22 -0
  27. package/lib/cluster/generated/protocol.d.ts +781 -0
  28. package/lib/cluster/generated/protocol.mjs +19 -0
  29. package/lib/cluster/index.cjs +40 -0
  30. package/lib/cluster/index.d.ts +10 -0
  31. package/lib/cluster/index.mjs +6 -0
  32. package/lib/cluster/queue.cjs +71 -0
  33. package/lib/cluster/queue.d.ts +15 -0
  34. package/lib/cluster/queue.mjs +67 -0
  35. package/lib/cluster/socket.cjs +15 -0
  36. package/lib/cluster/socket.d.ts +11 -0
  37. package/lib/cluster/socket.mjs +12 -0
  38. package/lib/cluster/subscriptions.cjs +270 -0
  39. package/lib/cluster/subscriptions.d.ts +69 -0
  40. package/lib/cluster/subscriptions.mjs +264 -0
  41. package/lib/cluster/validators.cjs +46 -0
  42. package/lib/cluster/validators.d.ts +3 -0
  43. package/lib/cluster/validators.mjs +42 -0
  44. package/lib/settings.js +195 -23
  45. package/lib/setup-apply.js +45 -32
  46. package/lib/setup-undo.js +25 -16
  47. package/package.json +25 -3
  48. package/scripts/build-cluster.js +43 -0
  49. package/scripts/generate-cluster-types.js +203 -0
  50. package/scripts/release-dry-run.js +6 -6
  51. package/scripts/rust-distribution.js +933 -0
  52. package/src/agent/agent-hook-executor.js +14 -6
  53. package/src/agent/agent-lifecycle.js +25 -8
  54. package/src/agent/agent-task-executor.js +711 -139
  55. package/src/agent/output-reformatter.js +54 -41
  56. package/src/agent/pr-verification.js +11 -3
  57. package/src/agent/task-execution-handle.js +373 -0
  58. package/src/agent-cli-provider/adapters/opencode.ts +3 -0
  59. package/src/agent-cli-provider/types.ts +1 -0
  60. package/src/agent-wrapper.js +5 -2
  61. package/src/cluster/client.ts +199 -0
  62. package/src/cluster/connection.ts +300 -0
  63. package/src/cluster/errors.ts +32 -0
  64. package/src/cluster/frames.ts +44 -0
  65. package/src/cluster/generated/protocol-schema.ts +2 -0
  66. package/src/cluster/generated/protocol.ts +183 -0
  67. package/src/cluster/index.ts +38 -0
  68. package/src/cluster/queue.ts +84 -0
  69. package/src/cluster/socket.ts +31 -0
  70. package/src/cluster/subscriptions.ts +256 -0
  71. package/src/cluster/validators.ts +56 -0
  72. package/src/cluster/ws.d.ts +7 -0
  73. package/src/isolation-manager.js +16 -0
  74. package/src/issue-providers/jira-provider.js +1 -1
  75. package/src/issue-providers/linear-provider.js +4 -4
  76. package/task-lib/runner.js +3 -0
@@ -40,7 +40,12 @@ function deepMerge(target, source) {
40
40
  return result;
41
41
  }
42
42
 
43
+ function hasCachedParsedResult(result) {
44
+ return result?.parsedResult !== undefined && result.parsedResult !== null;
45
+ }
46
+
43
47
  async function parseResultDataForHookLogic({ agent, result }) {
48
+ if (hasCachedParsedResult(result)) return result.parsedResult;
44
49
  if (!result?.output) return null;
45
50
  try {
46
51
  return await agent._parseResultOutput(result.output);
@@ -178,10 +183,12 @@ function logMissingResultFields({ agent, context, accessedFields, missingFields,
178
183
  }
179
184
 
180
185
  async function parseTransformResultData({ context, agent, script, scriptUsesResult }) {
181
- if (context.result?.output) {
182
- let resultData = null;
186
+ if (hasCachedParsedResult(context.result) || context.result?.output) {
187
+ let resultData = context.result?.parsedResult ?? null;
183
188
  try {
184
- resultData = await agent._parseResultOutput(context.result.output);
189
+ if (!hasCachedParsedResult(context.result)) {
190
+ resultData = await agent._parseResultOutput(context.result.output);
191
+ }
185
192
  } catch (parseError) {
186
193
  logTransformParseFailure({ agent, context, parseError });
187
194
  throw new Error(
@@ -423,7 +430,7 @@ async function substituteTemplate(params) {
423
430
  `Agent: ${agent.id}, TaskID: ${agent.currentTaskId}, Iteration: ${agent.iteration}`
424
431
  );
425
432
  }
426
- if (!context.result.output) {
433
+ if (!context.result.output && !hasCachedParsedResult(context.result)) {
427
434
  // Log detailed context for debugging
428
435
  const taskId = context.result.taskId || agent.currentTaskId || 'UNKNOWN';
429
436
  console.error(`\n${'='.repeat(80)}`);
@@ -478,8 +485,9 @@ async function substituteTemplate(params) {
478
485
  `Task logs posted to message bus.`
479
486
  );
480
487
  }
481
- // Parse result output - WILL THROW if no JSON block
482
- resultData = await agent._parseResultOutput(context.result.output);
488
+ resultData = hasCachedParsedResult(context.result)
489
+ ? context.result.parsedResult
490
+ : await agent._parseResultOutput(context.result.output);
483
491
  }
484
492
 
485
493
  // Helper to escape a value for JSON string substitution
@@ -201,7 +201,8 @@ function start(agent) {
201
201
  async function stop(agent) {
202
202
  stopLivenessCheck(agent);
203
203
 
204
- if (!agent.running && !agent.currentTask) {
204
+ const hasNestedExecutions = agent.nestedExecutions?.hasActive === true;
205
+ if (!agent.running && !agent.currentTask && !hasNestedExecutions) {
205
206
  return;
206
207
  }
207
208
 
@@ -213,8 +214,8 @@ async function stop(agent) {
213
214
  agent.unsubscribe = null;
214
215
  }
215
216
 
216
- // Kill current task if any
217
- if (agent.currentTask) {
217
+ // Kill parent and child executions through the shared ownership boundary.
218
+ if (agent.currentTask || hasNestedExecutions) {
218
219
  const termination = await agent._killTask('Task stopped by cluster shutdown');
219
220
  if (termination?.forced === false) {
220
221
  throw new Error(`Task shutdown could not confirm termination: ${termination.reason}`);
@@ -1132,7 +1133,9 @@ function startLivenessCheck(agent) {
1132
1133
 
1133
1134
  agent.livenessCheckInterval = setInterval(() => {
1134
1135
  const hasRecoverableTask =
1135
- Boolean(agent.currentTask) || Boolean(agent.isolation?.enabled && agent.currentTaskId);
1136
+ Boolean(agent.currentTask) ||
1137
+ Boolean(agent.isolation?.enabled && agent.currentTaskId) ||
1138
+ agent.nestedExecutions?.hasActive === true;
1136
1139
  if (!hasRecoverableTask || agent.livenessTerminationStarted) {
1137
1140
  return;
1138
1141
  }
@@ -1194,11 +1197,16 @@ function startLivenessCheck(agent) {
1194
1197
  const MAX_LIVENESS_TERMINATION_ATTEMPTS = 3;
1195
1198
 
1196
1199
  function beginLivenessTermination(agent, settings, reason, code, eventData) {
1200
+ const nestedTaskIds = agent.nestedExecutions?.activeTaskIds || [];
1197
1201
  agent.livenessTerminationContext = {
1198
1202
  taskId: agent.currentTaskId,
1203
+ nestedTaskIds,
1199
1204
  reason,
1200
1205
  code,
1201
- eventData,
1206
+ eventData: {
1207
+ ...eventData,
1208
+ ...(nestedTaskIds.length > 0 ? { nestedTaskIds } : {}),
1209
+ },
1202
1210
  eventPublished: false,
1203
1211
  };
1204
1212
  agent.livenessTerminationAttempts = 0;
@@ -1249,6 +1257,7 @@ function attemptLivenessTermination(agent, settings) {
1249
1257
  agent.livenessTerminationStarted = false;
1250
1258
  agent._publishLifecycle('AGENT_TERMINATION_RETRY', {
1251
1259
  taskId: context.taskId,
1260
+ nestedTaskIds: context.nestedTaskIds,
1252
1261
  reason: context.reason,
1253
1262
  code: context.code,
1254
1263
  error: error.message,
@@ -1272,13 +1281,17 @@ function exhaustLivenessTermination(agent, context, terminationError) {
1272
1281
 
1273
1282
  const attempts = agent.livenessTerminationAttempts;
1274
1283
  publishLivenessTerminationEvent(agent, context);
1284
+ const taskIdentity =
1285
+ context.taskId || context.nestedTaskIds.join(', ') || 'unknown provider task';
1275
1286
  const error = new Error(
1276
- `Failed to terminate isolated task ${context.taskId} after ${attempts} attempts; ` +
1287
+ `Failed to terminate provider task ${taskIdentity} after ${attempts} attempts; ` +
1277
1288
  `the provider task may still be running. Manual recovery is required before resume. ` +
1278
1289
  `Last error: ${terminationError.message}`
1279
1290
  );
1280
1291
  error.code = 'ISOLATED_TASK_TERMINATION_EXHAUSTED';
1281
- error.taskId = context.taskId;
1292
+ error.taskId = context.taskId || context.nestedTaskIds[0] || null;
1293
+ error.parentTaskId = context.taskId;
1294
+ error.nestedTaskIds = context.nestedTaskIds;
1282
1295
  error.permanent = true;
1283
1296
  error.restartExhausted = true;
1284
1297
  error.terminationExhausted = true;
@@ -1289,6 +1302,7 @@ function exhaustLivenessTermination(agent, context, terminationError) {
1289
1302
  agent.cluster.failureInfo = {
1290
1303
  agentId: agent.id,
1291
1304
  taskId: context.taskId,
1305
+ nestedTaskIds: context.nestedTaskIds,
1292
1306
  iteration: agent.iteration,
1293
1307
  type: 'task_termination',
1294
1308
  reason: 'termination_unverified',
@@ -1298,6 +1312,7 @@ function exhaustLivenessTermination(agent, context, terminationError) {
1298
1312
  };
1299
1313
  agent._publishLifecycle('AGENT_TERMINATION_EXHAUSTED', {
1300
1314
  taskId: context.taskId,
1315
+ nestedTaskIds: context.nestedTaskIds,
1301
1316
  reason: context.reason,
1302
1317
  code: error.code,
1303
1318
  terminationCode: context.code,
@@ -1307,10 +1322,12 @@ function exhaustLivenessTermination(agent, context, terminationError) {
1307
1322
  requiresManualRecovery: true,
1308
1323
  });
1309
1324
 
1325
+ let dispatched = agent.nestedExecutions?.failClosed(error) === true;
1310
1326
  if (typeof agent.currentTask?.failClosed === 'function') {
1311
1327
  agent.currentTask.failClosed(error);
1312
- return;
1328
+ dispatched = true;
1313
1329
  }
1330
+ if (dispatched) return;
1314
1331
 
1315
1332
  agent._log(`[${agent.id}] ${error.message}`);
1316
1333
  }