@mndrk/agx 1.4.20 → 1.4.22

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 (104) hide show
  1. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/BUILD_ID +1 -1
  2. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-build-manifest.json +29 -29
  3. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-path-routes-manifest.json +4 -4
  4. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/build-manifest.json +2 -2
  5. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/prerender-manifest.json +22 -22
  6. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  7. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.html +1 -1
  8. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.rsc +2 -2
  9. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/audit/route_client-reference-manifest.js +1 -1
  10. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/[...nextauth]/route_client-reference-manifest.js +1 -1
  11. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/daemon-secret/route_client-reference-manifest.js +1 -1
  12. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/code/route_client-reference-manifest.js +1 -1
  13. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/token/route_client-reference-manifest.js +1 -1
  14. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +1 -1
  15. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  16. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/learnings/route_client-reference-manifest.js +1 -1
  17. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/logs/stream/route_client-reference-manifest.js +1 -1
  18. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  19. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/signal/route_client-reference-manifest.js +1 -1
  20. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/start/route_client-reference-manifest.js +1 -1
  21. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/status/route_client-reference-manifest.js +1 -1
  22. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -1
  23. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  24. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
  25. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/complete/route_client-reference-manifest.js +1 -1
  26. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/route_client-reference-manifest.js +1 -1
  27. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/stage-prompts/route_client-reference-manifest.js +1 -1
  28. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/[commentId]/route_client-reference-manifest.js +1 -1
  29. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
  30. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/heartbeat/route_client-reference-manifest.js +1 -1
  31. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/history/route_client-reference-manifest.js +1 -1
  32. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/logs/route_client-reference-manifest.js +1 -1
  33. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
  34. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
  35. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/stream/route_client-reference-manifest.js +1 -1
  36. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/user-settings/route_client-reference-manifest.js +1 -1
  37. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/nodes/route_client-reference-manifest.js +1 -1
  38. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/route_client-reference-manifest.js +1 -1
  39. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  40. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/callback/route_client-reference-manifest.js +1 -1
  41. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page.js +5 -5
  42. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page_client-reference-manifest.js +1 -1
  43. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.html +1 -1
  44. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.rsc +3 -3
  45. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page.js +8 -3
  46. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page_client-reference-manifest.js +1 -1
  47. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.html +1 -1
  48. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.rsc +3 -3
  49. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.html +1 -1
  50. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.rsc +2 -2
  51. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login/page_client-reference-manifest.js +1 -1
  52. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.html +1 -1
  53. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.rsc +2 -2
  54. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/page_client-reference-manifest.js +1 -1
  55. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page.js +4 -4
  56. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  57. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/tasks/page_client-reference-manifest.js +1 -1
  58. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/workflow/page_client-reference-manifest.js +1 -1
  59. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  60. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.html +1 -1
  61. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.rsc +3 -3
  62. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  63. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.html +1 -1
  64. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.rsc +2 -2
  65. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app-paths-manifest.json +4 -4
  66. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/3009.js +5 -6
  67. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/6125.js +1 -1
  68. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/middleware-manifest.json +5 -5
  69. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/404.html +1 -1
  70. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/500.html +1 -1
  71. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.js +1 -1
  72. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.json +1 -1
  73. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/{9337-5d3c6b1828da8ec3.js → 9337-09000d8a6c85f40c.js} +1 -1
  74. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/9719-0fda94fde411f574.js +1 -0
  75. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-e2c2560ec12b421d.js +1 -0
  76. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/dashboard/page-7437499eb05d5ce8.js +1 -0
  77. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-253ca8286e8f1d68.js +1 -0
  78. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/72371329e4c91108.css +1 -0
  79. package/index.js +212 -63
  80. package/lib/cli/cloud/aggregate.js +162 -0
  81. package/lib/cli/cloud/command.js +230 -0
  82. package/lib/cli/cloud/executeVerifySingle.js +293 -0
  83. package/lib/cli/cloud/executeVerifySwarm.js +302 -0
  84. package/lib/cli/cloud/index.js +68 -0
  85. package/lib/cli/cloud/iterations.js +155 -0
  86. package/lib/cli/cloud/persist.js +123 -0
  87. package/lib/cli/cloud/prompts.js +229 -0
  88. package/lib/cli/cloud/simpleLoops.js +203 -0
  89. package/lib/cli/cloud/taskLogger.js +159 -0
  90. package/lib/cli/cloudArtifacts.js +478 -0
  91. package/lib/cli/onboarding.js +23 -4
  92. package/lib/cli/runCli.js +205 -2200
  93. package/lib/cli/util.js +68 -1
  94. package/lib/cloud/client.js +3 -30
  95. package/lib/config/cloudConfig.js +110 -6
  96. package/lib/config/paths.js +1 -1
  97. package/package.json +1 -1
  98. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/9719-1d7bdd112db709cc.js +0 -1
  99. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-1191b5d80fb53701.js +0 -1
  100. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/dashboard/page-2403721dcf6fac4f.js +0 -1
  101. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-e5b42f6a38ee1959.js +0 -1
  102. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/97623b2fc4a523a7.css +0 -1
  103. /package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/{_UEH0bf2vZJdfFbGlB9rM → M4AQWpnhTFqFD3HFlSHd9}/_buildManifest.js +0 -0
  104. /package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/{_UEH0bf2vZJdfFbGlB9rM → M4AQWpnhTFqFD3HFlSHd9}/_ssgManifest.js +0 -0
@@ -0,0 +1,162 @@
1
+ /* eslint-disable no-console */
2
+ 'use strict';
3
+
4
+ function createCloudAggregateHelpers(env) {
5
+ const {
6
+ SWARM_TIMEOUT_MS,
7
+ SWARM_RETRIES,
8
+ pRetryFn,
9
+ logExecutionFlow,
10
+ runAgxCommand,
11
+ resolveStageObjective,
12
+ buildStageRequirementPrompt,
13
+ enforceStageRequirement,
14
+ ensureExplanation,
15
+ ensureNextPrompt,
16
+ extractFileRefsFromText,
17
+ extractJson,
18
+ signalTemporalTask,
19
+ buildAggregatorPrompt,
20
+ resolveAggregatorModel,
21
+ abortIfCancelled,
22
+ } = env || {};
23
+
24
+ async function runSingleAgentAggregate({ task, taskId, prompt, output, iteration, logger, provider, model, artifacts, cancellationWatcher }) {
25
+ logExecutionFlow('runSingleAgentAggregate', 'input', `taskId=${taskId}, iteration=${iteration}`);
26
+ logExecutionFlow('runSingleAgentAggregate', 'processing', 'running aggregator');
27
+ const stageKey = task?.stage || 'unknown';
28
+ const stagePrompt = resolveStageObjective(task, stageKey, '');
29
+ const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
30
+ const aggregatorProvider = String(provider || task?.provider || task?.engine || 'claude').toLowerCase();
31
+ const aggregatorModel = typeof model === 'string' && model.trim() ? model.trim() : null;
32
+ const fileRefs = extractFileRefsFromText(output, { max: 20 });
33
+
34
+ const aggregatePrompt = buildAggregatorPrompt({
35
+ role: 'single-agent',
36
+ taskId,
37
+ task,
38
+ stagePrompt,
39
+ stageRequirement,
40
+ runPath: artifacts?.runPath || null,
41
+ fileRefs,
42
+ });
43
+ artifacts?.recordPrompt(`Aggregator Prompt (${aggregatorProvider}${aggregatorModel ? `/${aggregatorModel}` : ''})`, aggregatePrompt);
44
+
45
+ const aggregateArgs = [aggregatorProvider, '--prompt', aggregatePrompt, '--print'];
46
+ if (aggregatorModel) {
47
+ aggregateArgs.push('--model', aggregatorModel);
48
+ }
49
+
50
+ await abortIfCancelled(cancellationWatcher);
51
+ const res = await pRetryFn(
52
+ () => runAgxCommand(aggregateArgs, SWARM_TIMEOUT_MS, `agx ${aggregatorProvider} aggregate`, {
53
+ onStdout: (data) => logger?.log('checkpoint', data),
54
+ onStderr: (data) => logger?.log('error', data),
55
+ onTrace: (event) => {
56
+ void artifacts?.recordEngineTrace?.({ provider: aggregatorProvider, model: aggregatorModel || null, role: 'single-aggregate' }, event);
57
+ },
58
+ cancellationWatcher,
59
+ }),
60
+ { retries: SWARM_RETRIES }
61
+ );
62
+
63
+ const decision = extractJson(res.stdout) || extractJson(res.stderr);
64
+ logExecutionFlow('runSingleAgentAggregate', 'output', `decision=${JSON.stringify(decision || {})}`);
65
+ if (!decision) {
66
+ logger?.log('error', '[single] Aggregator returned invalid JSON\n');
67
+ return { done: true, decision: 'failed', explanation: 'Aggregator response was not valid JSON.', final_result: 'Aggregator response was not valid JSON.', next_prompt: '', summary: 'Aggregator response was not valid JSON.' };
68
+ }
69
+
70
+ logger?.log('checkpoint', `[single] decision ${JSON.stringify(decision)}\n`);
71
+
72
+ return ensureExplanation(enforceStageRequirement({
73
+ done: Boolean(decision.done),
74
+ decision: typeof decision.decision === 'string' ? decision.decision : '',
75
+ explanation: typeof decision.explanation === 'string' ? decision.explanation : '',
76
+ final_result: typeof decision.final_result === 'string' ? decision.final_result : '',
77
+ next_prompt: typeof decision.next_prompt === 'string' ? decision.next_prompt : '',
78
+ summary: typeof decision.summary === 'string' ? decision.summary : ''
79
+ }, { stage: stageKey, stagePrompt }));
80
+ }
81
+
82
+ async function runSwarmAggregate({ task, taskId, prompt, results, iteration, logger, artifacts }) {
83
+ const providerList = results.map((r) => r.provider).join(',');
84
+ logExecutionFlow('runSwarmAggregate', 'input', `taskId=${taskId}, iteration=${iteration}, providers=${providerList}`);
85
+ const stageKey = task?.stage || 'unknown';
86
+ const stagePrompt = resolveStageObjective(task, stageKey, '');
87
+ const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
88
+ const aggregatorProvider = String(task?.engine || task?.provider || 'claude').toLowerCase();
89
+ const aggregatorModel = resolveAggregatorModel(task);
90
+ const fileRefs = extractFileRefsFromText(
91
+ results.map((r) => r?.output || '').filter(Boolean).join('\n\n'),
92
+ { max: 20 }
93
+ );
94
+
95
+ const aggregatePrompt = buildAggregatorPrompt({
96
+ role: 'swarm',
97
+ taskId,
98
+ task,
99
+ stagePrompt,
100
+ stageRequirement,
101
+ runPath: artifacts?.runPath || null,
102
+ fileRefs,
103
+ });
104
+ artifacts?.recordPrompt(`Swarm Aggregator Prompt (${aggregatorProvider}${aggregatorModel ? `/${aggregatorModel}` : ''})`, aggregatePrompt);
105
+
106
+ const aggregateArgs = [aggregatorProvider, '--prompt', aggregatePrompt, '--print'];
107
+ if (aggregatorModel) {
108
+ aggregateArgs.push('--model', aggregatorModel);
109
+ }
110
+
111
+ logExecutionFlow('runSwarmAggregate', 'processing', 'running aggregator');
112
+ const res = await pRetryFn(
113
+ () => runAgxCommand(aggregateArgs, SWARM_TIMEOUT_MS, `agx ${aggregatorProvider} aggregate`, {
114
+ onStdout: (data) => logger?.log('checkpoint', data),
115
+ onStderr: (data) => logger?.log('error', data),
116
+ onTrace: (event) => {
117
+ void artifacts?.recordEngineTrace?.({ provider: aggregatorProvider, model: aggregatorModel || null, role: 'swarm-aggregate' }, event);
118
+ void signalTemporalTask(taskId, 'daemonStep', {
119
+ kind: 'runAgxCommand',
120
+ task_id: taskId,
121
+ provider: aggregatorProvider,
122
+ model: aggregatorModel || null,
123
+ role: 'swarm-aggregate',
124
+ iteration,
125
+ providers: results.map((r) => r.provider),
126
+ ...event,
127
+ });
128
+ },
129
+ }),
130
+ { retries: SWARM_RETRIES }
131
+ );
132
+
133
+ const decision = extractJson(res.stdout) || extractJson(res.stderr);
134
+ logExecutionFlow('runSwarmAggregate', 'output', `decision=${JSON.stringify(decision || {})}`);
135
+ if (!decision) {
136
+ logger?.log('error', '[swarm] Aggregator returned invalid JSON\n');
137
+ return {
138
+ done: true,
139
+ decision: 'failed',
140
+ explanation: 'Aggregator response was not valid JSON.',
141
+ final_result: 'Aggregator response was not valid JSON.',
142
+ next_prompt: '',
143
+ summary: 'Aggregator response was not valid JSON.'
144
+ };
145
+ }
146
+
147
+ logger?.log('checkpoint', `[swarm] decision ${JSON.stringify(decision)}\n`);
148
+
149
+ return enforceStageRequirement({
150
+ done: Boolean(decision.done),
151
+ decision: typeof decision.decision === 'string' ? decision.decision : '',
152
+ explanation: typeof decision.explanation === 'string' ? decision.explanation : '',
153
+ final_result: typeof decision.final_result === 'string' ? decision.final_result : '',
154
+ next_prompt: typeof decision.next_prompt === 'string' ? decision.next_prompt : '',
155
+ summary: typeof decision.summary === 'string' ? decision.summary : ''
156
+ }, { stage: stageKey, stagePrompt });
157
+ }
158
+
159
+ return { runSingleAgentAggregate, runSwarmAggregate };
160
+ }
161
+
162
+ module.exports = { createCloudAggregateHelpers };
@@ -0,0 +1,230 @@
1
+ /* eslint-disable no-console */
2
+ 'use strict';
3
+
4
+ function createCloudCommandHelpers(env) {
5
+ const {
6
+ loadCloudConfigFile,
7
+ fetch,
8
+ sanitizeCliArgs,
9
+ logExecutionFlow,
10
+ spawnCloudTaskProcess,
11
+ randomId,
12
+ appendTail,
13
+ truncateForTemporalTrace,
14
+ extractCancellationReason,
15
+ CancellationRequestedError,
16
+ CANCELLED_ERROR_CODE,
17
+ } = env || {};
18
+
19
+ async function updateCloudTask(taskId, updates) {
20
+ const cloudConfig = loadCloudConfigFile();
21
+ if (!cloudConfig?.apiUrl) return;
22
+ if (!taskId) return;
23
+
24
+ try {
25
+ const headers = {
26
+ 'Content-Type': 'application/json',
27
+ 'x-user-id': cloudConfig.userId || '',
28
+ };
29
+ if (cloudConfig?.token) {
30
+ headers.Authorization = `Bearer ${cloudConfig.token}`;
31
+ }
32
+ // Assume standard API route is /api/tasks/:id
33
+ await fetch(`${cloudConfig.apiUrl}/api/tasks/${encodeURIComponent(taskId)}`, {
34
+ method: 'PATCH',
35
+ headers,
36
+ body: JSON.stringify(updates),
37
+ });
38
+ } catch (err) {
39
+ // Silent fail or log debug
40
+ // console.debug('Failed to update cloud task', err);
41
+ }
42
+ }
43
+
44
+ function runAgxCommand(args, timeoutMs, label, handlers = {}) {
45
+ return new Promise((resolve, reject) => {
46
+ let stdout = '';
47
+ let stderr = '';
48
+ let stdoutTail = '';
49
+ let stderrTail = '';
50
+ let settled = false;
51
+
52
+ const childArgs = sanitizeCliArgs([process.argv[1], ...args]);
53
+ logExecutionFlow('runAgxCommand', 'input', `label=${label}, args=${childArgs.join(' ')}, timeout=${timeoutMs}`);
54
+ const cancellationWatcher = handlers.cancellationWatcher || null;
55
+ const child = spawnCloudTaskProcess(childArgs);
56
+ logExecutionFlow('runAgxCommand', 'processing', `spawning child process (pid: ${child.pid})`);
57
+
58
+ const controller = new AbortController();
59
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
60
+ const traceId = randomId();
61
+ const startedAt = Date.now();
62
+ const startedAtIso = new Date(startedAt).toISOString();
63
+ const emitTrace = (event) => {
64
+ if (!handlers || typeof handlers.onTrace !== 'function') return;
65
+ try {
66
+ handlers.onTrace(event);
67
+ } catch { }
68
+ };
69
+
70
+ emitTrace({
71
+ id: traceId,
72
+ phase: 'start',
73
+ label,
74
+ args: childArgs,
75
+ pid: child?.pid || null,
76
+ timeout_ms: timeoutMs,
77
+ started_at: startedAtIso,
78
+ });
79
+
80
+ if (cancellationWatcher?.start) {
81
+ try {
82
+ cancellationWatcher.start();
83
+ } catch { }
84
+ }
85
+
86
+ let cancelUnsubscribe = null;
87
+ const cleanupCancellation = () => {
88
+ if (cancelUnsubscribe) {
89
+ cancelUnsubscribe();
90
+ cancelUnsubscribe = null;
91
+ }
92
+ };
93
+
94
+ const handleCancellation = (payload) => {
95
+ if (settled) return;
96
+ settled = true;
97
+ clearTimeout(timeout);
98
+ if (child && typeof child.kill === 'function') {
99
+ child.kill('SIGTERM');
100
+ setTimeout(() => {
101
+ child.kill('SIGKILL');
102
+ }, 500);
103
+ }
104
+ const reason = extractCancellationReason(payload) || 'Cancelled by operator';
105
+ const err = new CancellationRequestedError(reason);
106
+ err.code = CANCELLED_ERROR_CODE;
107
+ err.payload = payload;
108
+ err.stdout = stdout;
109
+ err.stderr = stderr;
110
+ emitTrace({
111
+ id: traceId,
112
+ phase: 'cancel',
113
+ label,
114
+ args: childArgs,
115
+ pid: child?.pid || null,
116
+ timeout_ms: timeoutMs,
117
+ started_at: startedAtIso,
118
+ finished_at: new Date().toISOString(),
119
+ duration_ms: Date.now() - startedAt,
120
+ stdout_tail: truncateForTemporalTrace(stdoutTail),
121
+ stderr_tail: truncateForTemporalTrace(stderrTail),
122
+ error: err.message,
123
+ });
124
+ cleanupCancellation();
125
+ reject(err);
126
+ };
127
+
128
+ if (cancellationWatcher?.onCancel) {
129
+ cancelUnsubscribe = cancellationWatcher.onCancel(handleCancellation);
130
+ }
131
+
132
+ controller.signal.addEventListener('abort', () => {
133
+ if (settled) return;
134
+ settled = true;
135
+ child.kill('SIGKILL');
136
+ const err = new Error(`${label || 'command'} timed out`);
137
+ err.code = 'ETIMEDOUT';
138
+ clearTimeout(timeout);
139
+ emitTrace({
140
+ id: traceId,
141
+ phase: 'timeout',
142
+ label,
143
+ args: childArgs,
144
+ pid: child?.pid || null,
145
+ timeout_ms: timeoutMs,
146
+ started_at: startedAtIso,
147
+ finished_at: new Date().toISOString(),
148
+ duration_ms: Date.now() - startedAt,
149
+ stdout_tail: truncateForTemporalTrace(stdoutTail),
150
+ stderr_tail: truncateForTemporalTrace(stderrTail),
151
+ error: err.message,
152
+ });
153
+ cleanupCancellation();
154
+ reject(err);
155
+ });
156
+
157
+ child.stdout.on('data', (data) => {
158
+ const chunk = data.toString();
159
+ stdout += chunk;
160
+ stdoutTail = appendTail(stdoutTail, chunk);
161
+ if (handlers.onStdout) handlers.onStdout(data);
162
+ });
163
+ child.stderr.on('data', (data) => {
164
+ const chunk = data.toString();
165
+ stderr += chunk;
166
+ stderrTail = appendTail(stderrTail, chunk);
167
+ if (handlers.onStderr) handlers.onStderr(data);
168
+ });
169
+
170
+ child.on('error', (err) => {
171
+ if (settled) return;
172
+ settled = true;
173
+ clearTimeout(timeout);
174
+ logExecutionFlow('runAgxCommand', 'output', `error ${err?.message || err}`);
175
+ emitTrace({
176
+ id: traceId,
177
+ phase: 'error',
178
+ label,
179
+ args: childArgs,
180
+ pid: child?.pid || null,
181
+ timeout_ms: timeoutMs,
182
+ started_at: startedAtIso,
183
+ finished_at: new Date().toISOString(),
184
+ duration_ms: Date.now() - startedAt,
185
+ stdout_tail: truncateForTemporalTrace(stdoutTail),
186
+ stderr_tail: truncateForTemporalTrace(stderrTail),
187
+ error: err?.message || String(err),
188
+ });
189
+ cleanupCancellation();
190
+ reject(err);
191
+ });
192
+
193
+ child.on('close', (code) => {
194
+ if (settled) return;
195
+ settled = true;
196
+ clearTimeout(timeout);
197
+ logExecutionFlow('runAgxCommand', 'output', `pid=${child.pid}, exit code=${code}`);
198
+ emitTrace({
199
+ id: traceId,
200
+ phase: 'exit',
201
+ label,
202
+ args: childArgs,
203
+ pid: child?.pid || null,
204
+ timeout_ms: timeoutMs,
205
+ started_at: startedAtIso,
206
+ finished_at: new Date().toISOString(),
207
+ duration_ms: Date.now() - startedAt,
208
+ exit_code: code,
209
+ stdout_tail: truncateForTemporalTrace(stdoutTail),
210
+ stderr_tail: truncateForTemporalTrace(stderrTail),
211
+ });
212
+ cleanupCancellation();
213
+ if (code === 0) {
214
+ resolve({ stdout, stderr, code });
215
+ } else {
216
+ const err = new Error(`${label || 'command'} exited with code ${code}`);
217
+ err.code = code;
218
+ err.stdout = stdout;
219
+ err.stderr = stderr;
220
+ reject(err);
221
+ }
222
+ });
223
+ });
224
+ }
225
+
226
+ return { updateCloudTask, runAgxCommand };
227
+ }
228
+
229
+ module.exports = { createCloudCommandHelpers };
230
+
@@ -0,0 +1,293 @@
1
+ /* eslint-disable no-console */
2
+ 'use strict';
3
+
4
+ function createCloudExecuteVerifySingle(env) {
5
+ const {
6
+ path,
7
+ fs,
8
+ SWARM_RETRIES,
9
+ SINGLE_MAX_ITERS,
10
+ VERIFY_TIMEOUT_MS,
11
+ pRetryFn,
12
+ logExecutionFlow,
13
+ resolveStageObjective,
14
+ buildStageRequirementPrompt,
15
+ enforceStageRequirement,
16
+ detectVerifyCommands,
17
+ runVerifyCommands,
18
+ getGitSummary,
19
+ createDaemonArtifactsRecorder,
20
+ runAgxCommand,
21
+ runSingleAgentIteration,
22
+ buildExecuteIterationPrompt,
23
+ buildVerifyPrompt,
24
+ persistIterationArtifacts,
25
+ finalizeRunSafe,
26
+ buildLocalRunIndexEntry,
27
+ postTaskComment,
28
+ extractJsonLast,
29
+ ensureExplanation,
30
+ ensureNextPrompt,
31
+ abortIfCancelled,
32
+ CancellationRequestedError,
33
+ buildNextPromptWithDecisionContext,
34
+ } = env || {};
35
+
36
+ async function runSingleAgentExecuteVerifyLoop({ taskId, task, provider, model, logger, storage, projectSlug, taskSlug, stageLocal, initialPromptContext, cancellationWatcher }) {
37
+ logExecutionFlow('runSingleAgentExecuteVerifyLoop', 'input', `taskId=${taskId}, provider=${provider}, model=${model}`);
38
+ const stageKey = task?.stage || 'unknown';
39
+ const stagePrompt = resolveStageObjective(task, stageKey, '');
40
+ const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
41
+
42
+ let iteration = 1;
43
+ let nextPrompt = '';
44
+ let lastDecision = null;
45
+ let lastRun = null;
46
+ let lastRunEntry = null;
47
+
48
+ while (iteration <= SINGLE_MAX_ITERS) {
49
+ logger?.log('system', `[single] execute/verify iteration ${iteration} start\n`);
50
+ logExecutionFlow('runSingleAgentExecuteVerifyLoop', 'processing', `iteration ${iteration} start`);
51
+ await abortIfCancelled(cancellationWatcher);
52
+
53
+ const executeRun = await storage.createRun({
54
+ projectSlug,
55
+ taskSlug,
56
+ stage: stageLocal,
57
+ engine: provider,
58
+ model: model || undefined,
59
+ });
60
+ lastRun = executeRun;
61
+ const runContainerPath = executeRun?.paths?.root ? path.dirname(executeRun.paths.root) : null;
62
+
63
+ const executeArtifacts = createDaemonArtifactsRecorder({ storage, run: executeRun, taskId });
64
+ if (iteration === 1 && initialPromptContext) {
65
+ executeArtifacts.recordPrompt('Initial Task Context', initialPromptContext);
66
+ }
67
+
68
+ // Tee spawned agx output into files under execute artifacts.
69
+ const execStdoutPath = executeRun?.paths?.artifacts ? path.join(executeRun.paths.artifacts, 'spawned.stdout.log') : null;
70
+ const execStderrPath = executeRun?.paths?.artifacts ? path.join(executeRun.paths.artifacts, 'spawned.stderr.log') : null;
71
+ const execStdoutStream = execStdoutPath ? fs.createWriteStream(execStdoutPath, { flags: 'a' }) : null;
72
+ const execStderrStream = execStderrPath ? fs.createWriteStream(execStderrPath, { flags: 'a' }) : null;
73
+
74
+ // EXECUTE
75
+ const executePrompt = buildExecuteIterationPrompt(nextPrompt, iteration);
76
+ let output = '';
77
+ try {
78
+ output = await runSingleAgentIteration({
79
+ taskId,
80
+ task,
81
+ provider,
82
+ model,
83
+ prompt: executePrompt,
84
+ logger,
85
+ onStdout: (chunk) => {
86
+ try { execStdoutStream?.write(chunk.toString()); } catch { }
87
+ },
88
+ onStderr: (chunk) => {
89
+ try { execStderrStream?.write(chunk.toString()); } catch { }
90
+ },
91
+ artifacts: executeArtifacts,
92
+ cancellationWatcher,
93
+ });
94
+ } catch (err) {
95
+ const message = err?.stdout || err?.stderr || err?.message || 'Single-agent execute phase failed.';
96
+ executeArtifacts.recordOutput('Execute Error', String(message));
97
+ await executeArtifacts.flush();
98
+ try { execStdoutStream?.end(); } catch { }
99
+ try { execStderrStream?.end(); } catch { }
100
+ await storage.failRun(executeRun, { error: err?.message || 'execute failed', code: 'EXECUTE_FAILED' });
101
+ lastDecision = {
102
+ done: false,
103
+ decision: 'failed',
104
+ explanation: err?.message || 'Single-agent execute phase failed.',
105
+ final_result: message,
106
+ next_prompt: '',
107
+ summary: err?.message || 'Single-agent execute phase failed.',
108
+ };
109
+ return { code: 1, decision: lastDecision, lastRun, runIndexEntry: lastRunEntry };
110
+ }
111
+ try { execStdoutStream?.end(); } catch { }
112
+ try { execStderrStream?.end(); } catch { }
113
+ executeArtifacts.recordOutput(`Agent Output (${provider}${model ? `/${model}` : ''}, iter ${iteration})`, output);
114
+ await executeArtifacts.flush();
115
+
116
+ // VERIFY (local commands)
117
+ const verifyCommands = detectVerifyCommands({ cwd: process.cwd() });
118
+ const gitSummary = getGitSummary({ cwd: process.cwd() });
119
+ const verifyResults = await runVerifyCommands(verifyCommands, { cwd: process.cwd(), max_output_chars: 20000 });
120
+
121
+ const verifyRun = await storage.createRun({
122
+ projectSlug,
123
+ taskSlug,
124
+ stage: 'verify',
125
+ runId: executeRun.run_id,
126
+ engine: provider,
127
+ model: model || undefined,
128
+ });
129
+ lastRun = verifyRun;
130
+
131
+ // Tee verifier stdout/stderr to files under verify artifacts.
132
+ const verifyStdoutPath = verifyRun?.paths?.artifacts ? path.join(verifyRun.paths.artifacts, 'spawned.stdout.log') : null;
133
+ const verifyStderrPath = verifyRun?.paths?.artifacts ? path.join(verifyRun.paths.artifacts, 'spawned.stderr.log') : null;
134
+ const verifyStdoutStream = verifyStdoutPath ? fs.createWriteStream(verifyStdoutPath, { flags: 'a' }) : null;
135
+ const verifyStderrStream = verifyStderrPath ? fs.createWriteStream(verifyStderrPath, { flags: 'a' }) : null;
136
+
137
+ // VERIFY (LLM)
138
+ const verifyPrompt = buildVerifyPrompt({
139
+ taskId,
140
+ task,
141
+ stagePrompt,
142
+ stageRequirement,
143
+ gitSummary,
144
+ verifyResults,
145
+ iteration,
146
+ lastRunPath: runContainerPath || verifyRun?.paths?.root || null,
147
+ });
148
+ const verifyArtifacts = createDaemonArtifactsRecorder({ storage, run: verifyRun, taskId });
149
+ verifyArtifacts.recordPrompt(`Verification Prompt (${provider}${model ? `/${model}` : ''}, iter ${iteration})`, verifyPrompt);
150
+
151
+ const verifyArgs = [provider, '--prompt', verifyPrompt, '--print'];
152
+ if (model) verifyArgs.push('--model', model);
153
+
154
+ await abortIfCancelled(cancellationWatcher);
155
+
156
+ let verifyRes;
157
+ try {
158
+ verifyRes = await pRetryFn(
159
+ () => runAgxCommand(verifyArgs, VERIFY_TIMEOUT_MS, `agx ${provider} verify`, {
160
+ onStdout: (data) => {
161
+ try { verifyStdoutStream?.write(data.toString()); } catch { }
162
+ logger?.log('checkpoint', data);
163
+ },
164
+ onStderr: (data) => {
165
+ try { verifyStderrStream?.write(data.toString()); } catch { }
166
+ logger?.log('error', data);
167
+ },
168
+ onTrace: (event) => {
169
+ void verifyArtifacts?.recordEngineTrace?.({ provider, model: model || null, role: 'single-verify' }, event);
170
+ },
171
+ cancellationWatcher,
172
+ }),
173
+ { retries: SWARM_RETRIES }
174
+ );
175
+ } catch (err) {
176
+ try { verifyStdoutStream?.end(); } catch { }
177
+ try { verifyStderrStream?.end(); } catch { }
178
+ if (err instanceof CancellationRequestedError) {
179
+ throw err;
180
+ }
181
+ verifyArtifacts.recordOutput('Verifier Error', String(err?.message || err));
182
+ await persistIterationArtifacts(storage, { runContainerPath, executeRun, verifyRun, decision: {}, verifyCommands, verifyResults, gitSummary });
183
+ await verifyArtifacts.flush();
184
+ await storage.failRun(verifyRun, { error: err?.message || 'verify failed', code: 'VERIFY_FAILED' });
185
+ await finalizeRunSafe(storage, executeRun, { status: 'failed', reason: `Verification failed: ${err?.message || 'verify failed'}` });
186
+ lastDecision = {
187
+ done: false,
188
+ decision: 'failed',
189
+ explanation: err?.message || 'Verifier failed.',
190
+ final_result: err?.message || 'Verifier failed.',
191
+ next_prompt: '',
192
+ summary: err?.message || 'Verifier failed.',
193
+ };
194
+ return { code: 1, decision: lastDecision, lastRun, runIndexEntry: lastRunEntry };
195
+ }
196
+ try { verifyStdoutStream?.end(); } catch { }
197
+ try { verifyStderrStream?.end(); } catch { }
198
+
199
+ const verifierText = verifyRes?.stdout || verifyRes?.stderr || '';
200
+ verifyArtifacts.recordOutput(`Verifier Output (${provider}${model ? `/${model}` : ''}, iter ${iteration})`, verifierText);
201
+
202
+ let decision = extractJsonLast(verifierText);
203
+ if (!decision) decision = extractJsonLast(verifyRes?.stderr || '');
204
+ if (!decision) {
205
+ decision = {
206
+ done: false,
207
+ decision: 'failed',
208
+ explanation: 'Verifier returned invalid JSON.',
209
+ final_result: 'Verifier returned invalid JSON.',
210
+ next_prompt: '',
211
+ summary: 'Verifier returned invalid JSON.',
212
+ };
213
+ }
214
+
215
+ decision = ensureExplanation(ensureNextPrompt(enforceStageRequirement({
216
+ done: Boolean(decision.done),
217
+ decision: typeof decision.decision === 'string' ? decision.decision : '',
218
+ explanation: typeof decision.explanation === 'string' ? decision.explanation : '',
219
+ final_result: typeof decision.final_result === 'string' ? decision.final_result : '',
220
+ next_prompt: typeof decision.next_prompt === 'string' ? decision.next_prompt : '',
221
+ summary: typeof decision.summary === 'string' ? decision.summary : '',
222
+ plan_md: typeof decision.plan_md === 'string' ? decision.plan_md : '',
223
+ implementation_summary_md: typeof decision.implementation_summary_md === 'string' ? decision.implementation_summary_md : '',
224
+ verification_md: typeof decision.verification_md === 'string' ? decision.verification_md : '',
225
+ }, { stage: stageKey, stagePrompt })));
226
+
227
+ lastDecision = decision;
228
+
229
+ await persistIterationArtifacts(storage, { runContainerPath, executeRun, verifyRun, decision, verifyCommands, verifyResults, gitSummary });
230
+
231
+ // Finalize this iteration (verify) run.
232
+ verifyArtifacts.recordOutput('Daemon Decision', JSON.stringify(decision || {}, null, 2));
233
+ await verifyArtifacts.flush();
234
+
235
+ const statusMap = {
236
+ done: 'done',
237
+ blocked: 'blocked',
238
+ not_done: 'continue',
239
+ failed: 'failed',
240
+ };
241
+ const localDecisionStatus = statusMap[String(decision?.decision || 'failed')] || 'failed';
242
+ await finalizeRunSafe(storage, executeRun, {
243
+ status: localDecisionStatus,
244
+ reason: 'Execute phase completed; see verify stage for decision.',
245
+ });
246
+ await storage.finalizeRun(verifyRun, {
247
+ status: localDecisionStatus,
248
+ reason: decision?.explanation || decision?.summary || '',
249
+ });
250
+
251
+ lastRunEntry = await buildLocalRunIndexEntry(storage, verifyRun, localDecisionStatus);
252
+
253
+ // Update local task status.
254
+ const localTaskStatusMap = {
255
+ done: 'done',
256
+ blocked: 'blocked',
257
+ not_done: 'running',
258
+ failed: 'failed',
259
+ };
260
+ const nextLocalStatus = localTaskStatusMap[String(decision?.decision || 'failed')] || 'failed';
261
+ await storage.updateTaskState(projectSlug, taskSlug, { status: nextLocalStatus });
262
+
263
+ await postTaskComment(taskId, decision.summary || decision.explanation || '');
264
+
265
+ if (['done', 'blocked', 'failed'].includes(String(decision?.decision || ''))) {
266
+ const code = decision?.decision === 'done' ? 0 : 1;
267
+ return { code, decision: lastDecision, lastRun, runIndexEntry: lastRunEntry };
268
+ }
269
+
270
+ nextPrompt = (typeof buildNextPromptWithDecisionContext === 'function'
271
+ ? buildNextPromptWithDecisionContext(decision)
272
+ : (decision?.next_prompt || ''));
273
+ iteration += 1;
274
+ }
275
+
276
+ if (!lastDecision) {
277
+ lastDecision = {
278
+ done: false,
279
+ decision: 'not_done',
280
+ explanation: `Single-agent run reached max iterations (${SINGLE_MAX_ITERS}).`,
281
+ final_result: `Single-agent run reached max iterations (${SINGLE_MAX_ITERS}).`,
282
+ next_prompt: '',
283
+ summary: `Single-agent run reached max iterations (${SINGLE_MAX_ITERS}).`,
284
+ };
285
+ }
286
+
287
+ return { code: 1, decision: lastDecision, lastRun, runIndexEntry: lastRunEntry };
288
+ }
289
+
290
+ return { runSingleAgentExecuteVerifyLoop };
291
+ }
292
+
293
+ module.exports = { createCloudExecuteVerifySingle };