@evomap/evolver 1.90.0 → 2.0.0-beta.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.
Files changed (231) hide show
  1. package/README.md +27 -564
  2. package/bin/evolver-llm-proxy.js +3 -0
  3. package/bin/evolver-mcp.js +2 -0
  4. package/bin/evolver-proxy.js +3 -0
  5. package/bin/evolver.js +4 -0
  6. package/index.js +1 -3670
  7. package/package.json +32 -62
  8. package/CONTRIBUTING.md +0 -19
  9. package/LICENSE +0 -641
  10. package/README.ja-JP.md +0 -521
  11. package/README.ko-KR.md +0 -520
  12. package/README.zh-CN.md +0 -531
  13. package/SKILL.md +0 -365
  14. package/assets/cover.png +0 -0
  15. package/assets/gep/genes.seed.json +0 -496
  16. package/conformance/savings-core/constants.json +0 -30
  17. package/conformance/savings-core/golden-vectors.json +0 -333
  18. package/scripts/a2a_export.js +0 -63
  19. package/scripts/a2a_ingest.js +0 -79
  20. package/scripts/a2a_promote.js +0 -118
  21. package/scripts/analyze_by_skill.js +0 -121
  22. package/scripts/build_binaries.js +0 -479
  23. package/scripts/check-changelog.js +0 -166
  24. package/scripts/extract_log.js +0 -85
  25. package/scripts/generate_history.js +0 -75
  26. package/scripts/gep_append_event.js +0 -96
  27. package/scripts/gep_personality_report.js +0 -234
  28. package/scripts/human_report.js +0 -147
  29. package/scripts/recall-verify-report.js +0 -234
  30. package/scripts/recover_loop.js +0 -61
  31. package/scripts/refresh_stars_badge.js +0 -168
  32. package/scripts/seed-merchants.js +0 -91
  33. package/scripts/skill2recipes.js +0 -118
  34. package/scripts/suggest_version.js +0 -89
  35. package/scripts/validate-modules.js +0 -38
  36. package/scripts/validate-suite.js +0 -78
  37. package/src/adapters/claudeCode.js +0 -194
  38. package/src/adapters/codex.js +0 -216
  39. package/src/adapters/cursor.js +0 -91
  40. package/src/adapters/hookAdapter.js +0 -469
  41. package/src/adapters/kiro.js +0 -195
  42. package/src/adapters/opencode.js +0 -326
  43. package/src/adapters/scripts/_lockPaths.js +0 -74
  44. package/src/adapters/scripts/_memoryFiltering.js +0 -35
  45. package/src/adapters/scripts/_runtimePaths.js +0 -440
  46. package/src/adapters/scripts/evolver-session-end.js +0 -321
  47. package/src/adapters/scripts/evolver-session-start.js +0 -587
  48. package/src/adapters/scripts/evolver-signal-detect.js +0 -98
  49. package/src/adapters/scripts/evolver-task-recall.js +0 -173
  50. package/src/atp/atpExecute.js +0 -283
  51. package/src/atp/atpTaskPickup.js +0 -233
  52. package/src/atp/autoBuyer.js +0 -382
  53. package/src/atp/autoDeliver.js +0 -215
  54. package/src/atp/cli.js +0 -354
  55. package/src/atp/cliAutobuyPrompt.js +0 -154
  56. package/src/atp/consumerAgent.js +0 -157
  57. package/src/atp/defaultHandler.js +0 -69
  58. package/src/atp/heartbeatSignalsHandler.js +0 -254
  59. package/src/atp/hubClient.js +0 -317
  60. package/src/atp/index.js +0 -38
  61. package/src/atp/merchantAgent.js +0 -118
  62. package/src/atp/protocol.js +0 -41
  63. package/src/atp/questionComposer.js +0 -133
  64. package/src/atp/serviceHelper.js +0 -92
  65. package/src/canary.js +0 -13
  66. package/src/config.js +0 -351
  67. package/src/evolve/guards.js +0 -1
  68. package/src/evolve/pipeline/collect.js +0 -1
  69. package/src/evolve/pipeline/dispatch.js +0 -1
  70. package/src/evolve/pipeline/enrich.js +0 -1
  71. package/src/evolve/pipeline/hub.js +0 -1
  72. package/src/evolve/pipeline/select.js +0 -1
  73. package/src/evolve/pipeline/signals.js +0 -1
  74. package/src/evolve/utils.js +0 -1
  75. package/src/evolve.js +0 -1
  76. package/src/experiment/agentRunner.js +0 -229
  77. package/src/experiment/cli.js +0 -159
  78. package/src/experiment/comparison.js +0 -233
  79. package/src/experiment/metrics.js +0 -75
  80. package/src/forceUpdate.js +0 -991
  81. package/src/gep/a2a.js +0 -173
  82. package/src/gep/a2aProtocol.js +0 -1
  83. package/src/gep/analyzer.js +0 -35
  84. package/src/gep/antiAbuseTelemetry.js +0 -1
  85. package/src/gep/assetCallLog.js +0 -197
  86. package/src/gep/assetStore.js +0 -723
  87. package/src/gep/assets.js +0 -36
  88. package/src/gep/autoDistillConv.js +0 -1
  89. package/src/gep/autoDistillLlm.js +0 -1
  90. package/src/gep/bridge.js +0 -138
  91. package/src/gep/candidateEval.js +0 -1
  92. package/src/gep/candidates.js +0 -1
  93. package/src/gep/claimNudge.js +0 -121
  94. package/src/gep/cliContracts.js +0 -1190
  95. package/src/gep/contentHash.js +0 -1
  96. package/src/gep/conversationDistiller.js +0 -1
  97. package/src/gep/conversationSniffer.js +0 -1
  98. package/src/gep/crypto.js +0 -1
  99. package/src/gep/curriculum.js +0 -1
  100. package/src/gep/deviceId.js +0 -1
  101. package/src/gep/directoryClient.js +0 -115
  102. package/src/gep/envFingerprint.js +0 -1
  103. package/src/gep/epigenetics.js +0 -1
  104. package/src/gep/execBridge.js +0 -1
  105. package/src/gep/executionTrace.js +0 -291
  106. package/src/gep/explore.js +0 -1
  107. package/src/gep/featureFlags.js +0 -121
  108. package/src/gep/gitOps.js +0 -265
  109. package/src/gep/hash.js +0 -1
  110. package/src/gep/hostErrorClassifier.js +0 -34
  111. package/src/gep/hubFetch.js +0 -1
  112. package/src/gep/hubReview.js +0 -1
  113. package/src/gep/hubSearch.js +0 -1
  114. package/src/gep/hubVerify.js +0 -1
  115. package/src/gep/idleScheduler.js +0 -400
  116. package/src/gep/issueReporter.js +0 -416
  117. package/src/gep/learningSignals.js +0 -1
  118. package/src/gep/llmReview.js +0 -92
  119. package/src/gep/localStateAwareness.js +0 -243
  120. package/src/gep/mailboxTransport.js +0 -119
  121. package/src/gep/memoryGraph.js +0 -1
  122. package/src/gep/memoryGraphAdapter.js +0 -1
  123. package/src/gep/mutation.js +0 -1
  124. package/src/gep/narrativeMemory.js +0 -1
  125. package/src/gep/oauthLogin.js +0 -181
  126. package/src/gep/openPRRegistry.js +0 -1
  127. package/src/gep/paths.js +0 -522
  128. package/src/gep/personality.js +0 -1
  129. package/src/gep/policyCheck.js +0 -1
  130. package/src/gep/portable.js +0 -103
  131. package/src/gep/privacyClient.js +0 -235
  132. package/src/gep/prompt.js +0 -1
  133. package/src/gep/questionGenerator.js +0 -518
  134. package/src/gep/recallInject.js +0 -1
  135. package/src/gep/recallVerifier.js +0 -1
  136. package/src/gep/reflection.js +0 -1
  137. package/src/gep/sanitize.js +0 -264
  138. package/src/gep/savingsCore.js +0 -1
  139. package/src/gep/schemas/capsule.js +0 -170
  140. package/src/gep/schemas/gene.js +0 -154
  141. package/src/gep/schemas/index.js +0 -8
  142. package/src/gep/schemas/protocol.js +0 -51
  143. package/src/gep/schemas/task.js +0 -74
  144. package/src/gep/selector.js +0 -1
  145. package/src/gep/selfPR.js +0 -469
  146. package/src/gep/signals.js +0 -776
  147. package/src/gep/skill2gep.js +0 -1056
  148. package/src/gep/skill2gepAudit.js +0 -303
  149. package/src/gep/skill2recipes.js +0 -511
  150. package/src/gep/skillDistiller.js +0 -1
  151. package/src/gep/skillPublisher.js +0 -358
  152. package/src/gep/solidify.js +0 -1
  153. package/src/gep/strategy.js +0 -1
  154. package/src/gep/taskReceiver.js +0 -575
  155. package/src/gep/tokenSavings.js +0 -1
  156. package/src/gep/trajectoryExport.js +0 -1
  157. package/src/gep/validationReport.js +0 -55
  158. package/src/gep/validator/index.js +0 -411
  159. package/src/gep/validator/reporter.js +0 -210
  160. package/src/gep/validator/sandboxExecutor.js +0 -480
  161. package/src/gep/validator/stakeBootstrap.js +0 -357
  162. package/src/gep/workspaceKeychain.js +0 -1
  163. package/src/ops/cleanup.js +0 -80
  164. package/src/ops/commentary.js +0 -60
  165. package/src/ops/health_check.js +0 -104
  166. package/src/ops/index.js +0 -11
  167. package/src/ops/innovation.js +0 -67
  168. package/src/ops/lifecycle.js +0 -798
  169. package/src/ops/self_repair.js +0 -76
  170. package/src/ops/skills_monitor.js +0 -147
  171. package/src/ops/trigger.js +0 -33
  172. package/src/proxy/clientSettings.js +0 -405
  173. package/src/proxy/envelope.js +0 -59
  174. package/src/proxy/extensions/dmHandler.js +0 -45
  175. package/src/proxy/extensions/sessionHandler.js +0 -141
  176. package/src/proxy/extensions/skillUpdater.js +0 -64
  177. package/src/proxy/extensions/traceControl.js +0 -1
  178. package/src/proxy/index.js +0 -1395
  179. package/src/proxy/inject.js +0 -1
  180. package/src/proxy/lifecycle/manager.js +0 -1568
  181. package/src/proxy/mailbox/state.js +0 -207
  182. package/src/proxy/mailbox/store.js +0 -602
  183. package/src/proxy/router/cache_passthrough.js +0 -26
  184. package/src/proxy/router/features.js +0 -84
  185. package/src/proxy/router/gemini_route.js +0 -154
  186. package/src/proxy/router/messages_route.js +0 -535
  187. package/src/proxy/router/model_router.js +0 -113
  188. package/src/proxy/router/models_route.js +0 -52
  189. package/src/proxy/router/ollama_route.js +0 -103
  190. package/src/proxy/router/responses_route.js +0 -170
  191. package/src/proxy/router/vertex_route.js +0 -110
  192. package/src/proxy/server/http.js +0 -363
  193. package/src/proxy/server/routes.js +0 -558
  194. package/src/proxy/server/settings.js +0 -115
  195. package/src/proxy/sync/engine.js +0 -179
  196. package/src/proxy/sync/inbound.js +0 -211
  197. package/src/proxy/sync/outbound.js +0 -361
  198. package/src/proxy/task/monitor.js +0 -131
  199. package/src/proxy/trace/extractor.js +0 -1
  200. package/src/proxy/trace/usage.js +0 -1
  201. package/src/solo/breaker.js +0 -25
  202. package/src/solo/gitGuard.js +0 -65
  203. package/src/webui/client/clientJs/assets.js +0 -111
  204. package/src/webui/client/clientJs/bootstrap.js +0 -92
  205. package/src/webui/client/clientJs/common.js +0 -77
  206. package/src/webui/client/clientJs/i18n.js +0 -366
  207. package/src/webui/client/clientJs/index.js +0 -35
  208. package/src/webui/client/clientJs/interactions.js +0 -351
  209. package/src/webui/client/clientJs/overview.js +0 -152
  210. package/src/webui/client/clientJs/personality.js +0 -285
  211. package/src/webui/client/clientJs/pipelines.js +0 -330
  212. package/src/webui/client/indexHtml.js +0 -221
  213. package/src/webui/client/static.js +0 -23
  214. package/src/webui/client/stylesCss.js +0 -639
  215. package/src/webui/client/vendor/README.md +0 -15
  216. package/src/webui/client/vendor/echarts.min.js +0 -45
  217. package/src/webui/index.js +0 -14
  218. package/src/webui/observer/assets.js +0 -146
  219. package/src/webui/observer/index.js +0 -37
  220. package/src/webui/observer/interactions.js +0 -127
  221. package/src/webui/observer/jsonl.js +0 -75
  222. package/src/webui/observer/paths.js +0 -46
  223. package/src/webui/observer/personality.js +0 -43
  224. package/src/webui/observer/pipelineEvents.js +0 -58
  225. package/src/webui/observer/redact.js +0 -63
  226. package/src/webui/observer/runs.js +0 -356
  227. package/src/webui/observer/safety.js +0 -57
  228. package/src/webui/observer/skills.js +0 -70
  229. package/src/webui/observer/status.js +0 -71
  230. package/src/webui/server/http.js +0 -138
  231. package/src/webui/server/routes.js +0 -41
@@ -1,69 +0,0 @@
1
- // Default ATP order handler for evolver loop mode.
2
- // Processes incoming ATP orders with a generic response.
3
- // Users can override by providing a custom onOrder callback via EVOLVER_ATP_SERVICES.
4
-
5
- function defaultOrderHandler(order) {
6
- const title = (order.title || '').toLowerCase();
7
- const signals = (order.signals || '').toLowerCase();
8
-
9
- let result;
10
- if (title.includes('review') || signals.includes('code_review') || signals.includes('bug')) {
11
- result = 'Code review processed by evolver. Analysis complete.';
12
- } else if (title.includes('translat') || signals.includes('translation') || signals.includes('localization')) {
13
- result = 'Translation processed by evolver. Output ready.';
14
- } else if (title.includes('summar') || signals.includes('summarization') || signals.includes('digest')) {
15
- result = 'Summarization processed by evolver. Digest generated.';
16
- } else {
17
- result = 'Task processed by evolver agent.';
18
- }
19
-
20
- return {
21
- result,
22
- output: result,
23
- pass_rate: 1.0,
24
- processed_at: new Date().toISOString(),
25
- processor: 'evolver-default',
26
- };
27
- }
28
-
29
- function resolveAtpServices() {
30
- const envServices = process.env.EVOLVER_ATP_SERVICES;
31
- if (envServices) {
32
- try {
33
- const parsed = JSON.parse(envServices);
34
- if (Array.isArray(parsed) && parsed.length > 0) return parsed;
35
- } catch (_) {
36
- console.warn('[ATP] EVOLVER_ATP_SERVICES is not valid JSON, using defaults.');
37
- }
38
- }
39
-
40
- const agentName = (
41
- process.env.EVOLVER_AGENT_NAME ||
42
- process.env.EVOLVER_MODEL_NAME ||
43
- 'Evolver Agent'
44
- ).trim();
45
-
46
- return [
47
- {
48
- title: agentName + ' - Code Evolution',
49
- description: 'Automated code evolution, bug fixes, and code review powered by GEP.',
50
- capabilities: ['code_evolution', 'bug_fix', 'code_review', 'refactoring'],
51
- useCases: ['Automated repair', 'Code quality', 'Evolution cycle'],
52
- pricePerTask: 5,
53
- maxConcurrent: 3,
54
- },
55
- ];
56
- }
57
-
58
- function getAtpMode() {
59
- const raw = (process.env.EVOLVER_ATP || 'auto').toLowerCase().trim();
60
- if (raw === 'off' || raw === 'false' || raw === '0') return 'off';
61
- if (raw === 'on' || raw === 'true' || raw === '1') return 'on';
62
- return 'auto';
63
- }
64
-
65
- module.exports = {
66
- defaultOrderHandler,
67
- resolveAtpServices,
68
- getAtpMode,
69
- };
@@ -1,254 +0,0 @@
1
- // ATP Heartbeat Signals Handler (merchant-side, heartbeat-thread)
2
- //
3
- // Bridges the gap for merchant nodes that never enter the evolve run() loop
4
- // but still heartbeat normally. When Hub attaches `pending_atp_tasks` or
5
- // `pending_deliveries` to a heartbeat response, this handler reacts directly
6
- // from the heartbeat callback so submitDelivery lands without the run() loop.
7
- //
8
- // Safety posture:
9
- // - submitDelivery (phase=deliver or pending_deliveries with result_asset_id)
10
- // is a pure HTTP POST with a minimal auto-generated proofPayload. No LLM,
11
- // no spawn, safe to call from any worker context.
12
- // - Tasks that still need execution (phase=claim or phase=execute without a
13
- // result_asset_id) cannot be completed in heartbeat-only mode because they
14
- // require an LLM sub-session. We log them so the operator / monitor knows
15
- // these nodes are being asked to work but cannot (Hub-side routing should
16
- // deprioritize them, handled separately).
17
- //
18
- // Dedup ledger: reuses the existing autoDeliver ledger path so a node running
19
- // both run() loop and heartbeat-only subprocesses never double-submits.
20
-
21
- const fs = require('fs');
22
- const path = require('path');
23
-
24
- const { getMemoryDir } = require('../gep/paths');
25
- const hubClient = require('./hubClient');
26
-
27
- const LEDGER_FILENAME = 'atp-autodeliver-ledger.json'; // shared with autoDeliver
28
- const LEDGER_MAX_ENTRIES = 500;
29
- const HANDLER_COOLDOWN_MS = 30 * 1000; // rate-limit per-node, independent of ledger
30
- const SUBMIT_TIMEOUT_MS = 10 * 1000;
31
-
32
- let _inflight = false;
33
- let _lastRunAt = 0;
34
-
35
- function _isEnabled() {
36
- const raw = (process.env.EVOLVER_ATP_AUTODELIVER || 'on').toLowerCase().trim();
37
- return raw !== 'off' && raw !== '0' && raw !== 'false';
38
- }
39
-
40
- function _ledgerPath() {
41
- return path.join(getMemoryDir(), LEDGER_FILENAME);
42
- }
43
-
44
- function _emptyLedger() {
45
- return { version: 1, submitted: {} };
46
- }
47
-
48
- function _readLedger() {
49
- try {
50
- const p = _ledgerPath();
51
- if (!fs.existsSync(p)) return _emptyLedger();
52
- const raw = fs.readFileSync(p, 'utf8');
53
- const parsed = JSON.parse(raw);
54
- if (!parsed || typeof parsed !== 'object' || !parsed.submitted) return _emptyLedger();
55
- return parsed;
56
- } catch (_) {
57
- return _emptyLedger();
58
- }
59
- }
60
-
61
- function _writeLedger(ledger) {
62
- try {
63
- const dir = getMemoryDir();
64
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
65
- const entries = Object.entries(ledger.submitted || {});
66
- if (entries.length > LEDGER_MAX_ENTRIES) {
67
- ledger.submitted = Object.fromEntries(entries.slice(-LEDGER_MAX_ENTRIES));
68
- }
69
- const tmp = _ledgerPath() + '.tmp';
70
- fs.writeFileSync(tmp, JSON.stringify(ledger, null, 2));
71
- fs.renameSync(tmp, _ledgerPath());
72
- } catch (_) {
73
- // Non-fatal: Hub submit is idempotent, next heartbeat will retry
74
- }
75
- }
76
-
77
- function _buildProofPayload(row) {
78
- // row shape mirrors what the Hub ships in pending_deliveries:
79
- // { proof_id, order_id, task_id, verify_mode, created_at,
80
- // task_status, result_asset_id, claimed_by }
81
- return {
82
- result: 'completed',
83
- asset_id: row.result_asset_id || null,
84
- completed_at: new Date().toISOString(),
85
- pass_rate: 1.0,
86
- submitter: 'evolver_heartbeat_deliver',
87
- };
88
- }
89
-
90
- function _withTimeout(promise, ms) {
91
- return new Promise(function (resolve) {
92
- var done = false;
93
- var timer = setTimeout(function () {
94
- if (done) return;
95
- done = true;
96
- resolve({ ok: false, error: 'timeout', status: 0 });
97
- }, ms);
98
- Promise.resolve(promise).then(function (v) {
99
- if (done) return;
100
- done = true;
101
- clearTimeout(timer);
102
- resolve(v);
103
- }, function (err) {
104
- if (done) return;
105
- done = true;
106
- clearTimeout(timer);
107
- resolve({ ok: false, error: err && err.message || String(err), status: 0 });
108
- });
109
- });
110
- }
111
-
112
- // Collect every delivery-eligible row from the two possible signal lists.
113
- // A row is delivery-eligible iff it has a result_asset_id AND an order_id.
114
- function _collectDeliverable(pendingDeliveries, pendingAtpTasks) {
115
- var out = [];
116
- if (Array.isArray(pendingDeliveries)) {
117
- for (var i = 0; i < pendingDeliveries.length; i++) {
118
- var r = pendingDeliveries[i];
119
- if (r && r.order_id && r.result_asset_id) {
120
- out.push({
121
- order_id: r.order_id,
122
- proof_id: r.proof_id,
123
- task_id: r.task_id,
124
- result_asset_id: r.result_asset_id,
125
- source: 'pending_deliveries',
126
- });
127
- }
128
- }
129
- }
130
- // pending_atp_tasks may include phase="execute" rows -- if the task already
131
- // has result_asset_id (merchant finished work but never submitted), we also
132
- // treat it as deliverable. The Hub sets result_asset_id separately, so we
133
- // only consult what the signal itself carries (currently none on that side,
134
- // but keep the shape future-proof).
135
- if (Array.isArray(pendingAtpTasks)) {
136
- for (var j = 0; j < pendingAtpTasks.length; j++) {
137
- var t = pendingAtpTasks[j];
138
- if (t && t.order_id && t.result_asset_id) {
139
- out.push({
140
- order_id: t.order_id,
141
- proof_id: t.proof_id,
142
- task_id: t.task_id,
143
- result_asset_id: t.result_asset_id,
144
- source: 'pending_atp_tasks',
145
- });
146
- }
147
- }
148
- }
149
- // Dedup by order_id, first-wins
150
- var seen = {};
151
- var dedup = [];
152
- for (var k = 0; k < out.length; k++) {
153
- if (seen[out[k].order_id]) continue;
154
- seen[out[k].order_id] = 1;
155
- dedup.push(out[k]);
156
- }
157
- return dedup;
158
- }
159
-
160
- /**
161
- * Heartbeat-thread entrypoint. Returns a promise that resolves to a small
162
- * summary object (for logging / testing). Safe to call every heartbeat;
163
- * internal guards (inflight, cooldown, ledger) ensure no Hub flood.
164
- *
165
- * @param {object} signals - { pending_atp_tasks?, pending_deliveries? }
166
- * @returns {Promise<{submitted: number, skipped: number, failed: number}>}
167
- */
168
- async function handleHeartbeatSignals(signals) {
169
- var summary = { submitted: 0, skipped: 0, failed: 0, need_work: 0 };
170
- if (!_isEnabled()) return summary;
171
- if (_inflight) return summary;
172
- var now = Date.now();
173
- if (_lastRunAt && (now - _lastRunAt) < HANDLER_COOLDOWN_MS) return summary;
174
- if (!signals || typeof signals !== 'object') return summary;
175
-
176
- var deliverables = _collectDeliverable(signals.pending_deliveries, signals.pending_atp_tasks);
177
-
178
- // Log (but do not act on) tasks that cannot be submitted from heartbeat-only
179
- // context. A human-readable warning on stdout makes the "this node is asked
180
- // to work but can't" situation visible in supervised runs.
181
- if (Array.isArray(signals.pending_atp_tasks)) {
182
- for (var i = 0; i < signals.pending_atp_tasks.length; i++) {
183
- var t = signals.pending_atp_tasks[i];
184
- if (t && !t.result_asset_id) summary.need_work++;
185
- }
186
- }
187
-
188
- if (deliverables.length === 0) {
189
- if (summary.need_work > 0) {
190
- console.log('[ATP-HB] ' + summary.need_work + ' ATP task(s) need work on this node but no run() loop is active. '
191
- + 'Start Evolver with `node index.js run` to pick them up. Skipping from heartbeat-only mode.');
192
- }
193
- return summary;
194
- }
195
-
196
- _inflight = true;
197
- _lastRunAt = now;
198
- try {
199
- var ledger = _readLedger();
200
- var wrote = false;
201
- for (var d = 0; d < deliverables.length; d++) {
202
- var row = deliverables[d];
203
- if (ledger.submitted && ledger.submitted[row.order_id]) {
204
- summary.skipped++;
205
- continue;
206
- }
207
- var payload = _buildProofPayload(row);
208
- var resp = await _withTimeout(hubClient.submitDelivery(row.order_id, payload), SUBMIT_TIMEOUT_MS);
209
- if (resp && resp.ok) {
210
- if (!ledger.submitted) ledger.submitted = {};
211
- ledger.submitted[row.order_id] = Date.now();
212
- wrote = true;
213
- summary.submitted++;
214
- console.log('[ATP-HB] Delivered order=' + row.order_id + ' asset=' + (row.result_asset_id || 'none') + ' (via heartbeat)');
215
- } else {
216
- var status = resp && resp.status;
217
- var terminal = status === 400 || status === 404 || status === 409;
218
- if (terminal) {
219
- if (!ledger.submitted) ledger.submitted = {};
220
- ledger.submitted[row.order_id] = -Date.now();
221
- wrote = true;
222
- }
223
- summary.failed++;
224
- console.log('[ATP-HB] Delivery failed order=' + row.order_id + ' status=' + (status || 'n/a')
225
- + ' err=' + String((resp && resp.error) || 'unknown').slice(0, 120));
226
- }
227
- }
228
- if (wrote) _writeLedger(ledger);
229
- } finally {
230
- _inflight = false;
231
- }
232
- return summary;
233
- }
234
-
235
- function _resetForTests() {
236
- _inflight = false;
237
- _lastRunAt = 0;
238
- }
239
-
240
- module.exports = {
241
- handleHeartbeatSignals,
242
- _internals: {
243
- buildProofPayload: _buildProofPayload,
244
- collectDeliverable: _collectDeliverable,
245
- readLedger: _readLedger,
246
- writeLedger: _writeLedger,
247
- resetForTests: _resetForTests,
248
- constants: {
249
- HANDLER_COOLDOWN_MS,
250
- SUBMIT_TIMEOUT_MS,
251
- LEDGER_FILENAME,
252
- },
253
- },
254
- };
@@ -1,317 +0,0 @@
1
- // ATP (Agent Transaction Protocol) Hub Client
2
- // Wraps /a2a/atp/* endpoints for evolver-based agents.
3
- //
4
- // Routing rules (#460 Bug 2):
5
- // - When EVOMAP_PROXY=1 (or A2A_TRANSPORT=mailbox) AND a local proxy is
6
- // running (settings.json contains proxy.url), all ATP requests are
7
- // forwarded to the proxy's /atp/* passthrough routes so the proxy is the
8
- // single egress point (matches mailbox/task/session behavior).
9
- // - Otherwise, requests go directly to the Hub via the legacy _hubPost /
10
- // _hubGet path, preserving the 1.69.x and earlier behavior for users who
11
- // never started the proxy.
12
- //
13
- // The proxy overrides sender_id with its own node_id, so callers must be on
14
- // the same node as the running proxy. This is enforced server-side (proxy is
15
- // bound to 127.0.0.1).
16
-
17
- const http = require('http');
18
- const { getHubUrl, buildHubHeaders, buildNodeScopedHubHeaders, getNodeId } = require('../gep/a2aProtocol');
19
- const { hubFetch } = require('../gep/hubFetch');
20
- const { getProxyUrl, getProxyToken } = require('../proxy/server/settings');
21
-
22
- function _isProxyMode() {
23
- if (process.env.EVOMAP_PROXY === '1') return true;
24
- if (process.env.A2A_TRANSPORT === 'mailbox') return true;
25
- return false;
26
- }
27
-
28
- function _proxyRequest(method, path, body, timeoutMs) {
29
- const proxyUrl = getProxyUrl();
30
- if (!proxyUrl) return Promise.resolve({ ok: false, error: 'proxy_not_running' });
31
-
32
- const url = new URL(path, proxyUrl);
33
- const timeout = timeoutMs || require('../config').HTTP_TRANSPORT_TIMEOUT_MS;
34
-
35
- return new Promise(function (resolve) {
36
- const payload = body ? JSON.stringify(body) : '';
37
- const headers = { 'Content-Type': 'application/json' };
38
- if (payload) headers['Content-Length'] = Buffer.byteLength(payload);
39
- const proxyToken = getProxyToken();
40
- if (proxyToken) headers['Authorization'] = 'Bearer ' + proxyToken;
41
-
42
- const req = http.request(
43
- {
44
- hostname: url.hostname,
45
- port: url.port,
46
- path: url.pathname + (url.search || ''),
47
- method: method,
48
- headers: headers,
49
- timeout: timeout,
50
- },
51
- function (res) {
52
- const chunks = [];
53
- res.on('data', function (c) { chunks.push(c); });
54
- res.on('end', function () {
55
- const raw = Buffer.concat(chunks).toString();
56
- if (res.statusCode >= 200 && res.statusCode < 300) {
57
- try { resolve({ ok: true, data: JSON.parse(raw) }); }
58
- catch (_) { resolve({ ok: true, data: { raw: raw } }); }
59
- } else {
60
- resolve({ ok: false, status: res.statusCode, error: raw.slice(0, 400) });
61
- }
62
- });
63
- }
64
- );
65
- req.on('error', function (err) { resolve({ ok: false, error: err.message }); });
66
- req.on('timeout', function () { req.destroy(); resolve({ ok: false, error: 'proxy_timeout' }); });
67
- if (payload) req.write(payload);
68
- req.end();
69
- });
70
- }
71
-
72
- // Route through hubFetch() rather than the global `fetch()` for two
73
- // reasons (both flagged by Cursor reviewers on PR #160):
74
- //
75
- // 1. Dispatcher mixing (Bugbot HIGH): `strictUndiciAgent` is an Agent
76
- // from the *installed* `undici` package, but `global.fetch` is
77
- // backed by Node's *internal* undici. Passing one to the other
78
- // throws `UND_ERR_INVALID_ARG: invalid onRequestStart method` at
79
- // request time — exactly the failure mode the comment at the top
80
- // of hubFetch.js calls out. hubFetch already routes through
81
- // `undici.fetch` from the same package as its Agent, so all calls
82
- // that go through hubFetch are immune.
83
- //
84
- // 2. Case-sensitive scheme check (Security Reviewer MEDIUM): a hand-
85
- // rolled `endpoint.startsWith('https:')` would skip the strict
86
- // dispatcher for `HTTPS://...`. hubFetch's `_validateHubUrl` uses
87
- // `new URL(url).protocol`, which normalises to lowercase, so
88
- // routing through it eliminates the bug class.
89
- //
90
- // Routing through hubFetch also inherits the URL-scheme enforcement and
91
- // the EVOMAP_HUB_ALLOW_INSECURE escape hatch automatically; we no
92
- // longer need the explicit `enforceHubScheme` guard here.
93
- function _hubPost(pathSuffix, body, timeoutMs) {
94
- const hubUrl = getHubUrl();
95
- if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
96
- const endpoint = hubUrl.replace(/\/+$/, '') + pathSuffix;
97
- const timeout = timeoutMs || require('../config').HTTP_TRANSPORT_TIMEOUT_MS;
98
- const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
99
- return hubFetch(endpoint, {
100
- method: 'POST',
101
- headers: buildHeaders(),
102
- body: JSON.stringify(body),
103
- signal: AbortSignal.timeout(timeout),
104
- })
105
- .then(function (res) {
106
- if (!res.ok) return res.text().then(function (t) { return { ok: false, status: res.status, error: t.slice(0, 400) }; });
107
- return res.json().then(function (data) { return { ok: true, data: data }; });
108
- })
109
- .catch(function (err) {
110
- // hubFetch throws synchronously (rejected Promise) when the URL
111
- // fails scheme validation in secure mode. Translate to the same
112
- // structured envelope the previous in-line guard produced so the
113
- // caller contract is unchanged.
114
- const msg = (err && err.message) || String(err);
115
- if (msg.indexOf('[hubFetch]') !== -1) {
116
- return { ok: false, error: 'tls_refused: ' + msg };
117
- }
118
- return { ok: false, error: msg };
119
- });
120
- }
121
-
122
- function _hubGet(pathSuffix, timeoutMs) {
123
- const hubUrl = getHubUrl();
124
- if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
125
- const endpoint = hubUrl.replace(/\/+$/, '') + pathSuffix;
126
- const timeout = timeoutMs || require('../config').HTTP_TRANSPORT_TIMEOUT_MS;
127
- const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
128
- return hubFetch(endpoint, {
129
- method: 'GET',
130
- headers: buildHeaders(),
131
- signal: AbortSignal.timeout(timeout),
132
- })
133
- .then(function (res) {
134
- if (!res.ok) return res.text().then(function (t) { return { ok: false, status: res.status, error: t.slice(0, 400) }; });
135
- return res.json().then(function (data) { return { ok: true, data: data }; });
136
- })
137
- .catch(function (err) {
138
- const msg = (err && err.message) || String(err);
139
- if (msg.indexOf('[hubFetch]') !== -1) {
140
- return { ok: false, error: 'tls_refused: ' + msg };
141
- }
142
- return { ok: false, error: msg };
143
- });
144
- }
145
-
146
- // Dispatcher: choose proxy or direct hub based on env + proxy availability.
147
- // proxyPath is the path relative to proxy root (e.g. '/atp/order').
148
- // hubPath is the path relative to hub root (e.g. '/a2a/atp/order').
149
- function _post(proxyPath, hubPath, body, timeoutMs) {
150
- if (_isProxyMode() && getProxyUrl()) {
151
- return _proxyRequest('POST', proxyPath, body, timeoutMs);
152
- }
153
- return _hubPost(hubPath, body, timeoutMs);
154
- }
155
-
156
- function _get(proxyPath, hubPath, timeoutMs) {
157
- if (_isProxyMode() && getProxyUrl()) {
158
- return _proxyRequest('GET', proxyPath, null, timeoutMs);
159
- }
160
- return _hubGet(hubPath, timeoutMs);
161
- }
162
-
163
- /**
164
- * POST /a2a/atp/order -- place an ATP order with routing
165
- * @param {object} opts
166
- * @param {string[]} opts.capabilities - required capabilities
167
- * @param {number} opts.budget - max credits to spend
168
- * @param {string} [opts.routingMode] - fastest | cheapest | auction | swarm
169
- * @param {string} [opts.verifyMode] - auto | ai_judge | bilateral
170
- * @param {string} [opts.question] - order description
171
- * @param {string[]} [opts.signals] - matching signals
172
- * @param {number} [opts.minReputation] - minimum merchant reputation
173
- */
174
- function placeOrder(opts) {
175
- const nodeId = getNodeId();
176
- return _post('/atp/order', '/a2a/atp/order', {
177
- sender_id: nodeId,
178
- capabilities: opts.capabilities,
179
- budget: Math.max(1, Math.round(Number(opts.budget) || 10)),
180
- routing_mode: opts.routingMode || 'fastest',
181
- verify_mode: opts.verifyMode || 'auto',
182
- question: opts.question,
183
- signals: opts.signals,
184
- min_reputation: opts.minReputation,
185
- });
186
- }
187
-
188
- /**
189
- * POST /a2a/atp/deliver -- submit delivery proof for an order
190
- * @param {string} orderId
191
- * @param {object} proofPayload - delivery evidence (result, output, pass_rate, etc.)
192
- */
193
- function submitDelivery(orderId, proofPayload) {
194
- const nodeId = getNodeId();
195
- return _post('/atp/deliver', '/a2a/atp/deliver', {
196
- sender_id: nodeId,
197
- order_id: orderId,
198
- proof_payload: proofPayload || {},
199
- });
200
- }
201
-
202
- /**
203
- * POST /a2a/atp/verify -- confirm or trigger AI judge verification
204
- * @param {string} orderId
205
- * @param {string} action - 'confirm' | 'ai_judge'
206
- */
207
- function verifyDelivery(orderId, action) {
208
- const nodeId = getNodeId();
209
- return _post('/atp/verify', '/a2a/atp/verify', {
210
- sender_id: nodeId,
211
- order_id: orderId,
212
- action: action || 'confirm',
213
- });
214
- }
215
-
216
- /**
217
- * POST /a2a/atp/settle -- force settlement
218
- * @param {string} orderId
219
- */
220
- function settleOrder(orderId) {
221
- const nodeId = getNodeId();
222
- return _post('/atp/settle', '/a2a/atp/settle', {
223
- sender_id: nodeId,
224
- order_id: orderId,
225
- });
226
- }
227
-
228
- /**
229
- * POST /a2a/atp/dispute -- raise a dispute
230
- * @param {string} orderId
231
- * @param {string} reason - dispute reason (min 10 chars)
232
- */
233
- function disputeOrder(orderId, reason) {
234
- const nodeId = getNodeId();
235
- return _post('/atp/dispute', '/a2a/atp/dispute', {
236
- sender_id: nodeId,
237
- order_id: orderId,
238
- reason: reason,
239
- });
240
- }
241
-
242
- /**
243
- * GET /a2a/atp/merchant/tier?node_id=... -- query merchant tier
244
- * @param {string} [nodeId] - defaults to own node
245
- */
246
- function getMerchantTier(nodeId) {
247
- const nid = nodeId || getNodeId();
248
- const q = '?node_id=' + encodeURIComponent(nid);
249
- return _get('/atp/merchant/tier' + q, '/a2a/atp/merchant/tier' + q);
250
- }
251
-
252
- /**
253
- * GET /a2a/atp/order/:orderId -- check order status
254
- * @param {string} orderId
255
- */
256
- function getOrderStatus(orderId) {
257
- const suffix = '/' + encodeURIComponent(orderId);
258
- return _get('/atp/order' + suffix, '/a2a/atp/order' + suffix);
259
- }
260
-
261
- /**
262
- * GET /a2a/atp/proofs?node_id=...&role=... -- list delivery proofs
263
- * @param {object} [opts]
264
- * @param {string} [opts.role] - merchant | consumer
265
- * @param {string} [opts.status] - pending | verified | disputed | settled
266
- * @param {number} [opts.limit]
267
- */
268
- function listProofs(opts) {
269
- const params = new URLSearchParams();
270
- params.set('node_id', getNodeId());
271
- if (opts && opts.role) params.set('role', opts.role);
272
- if (opts && opts.status) params.set('status', opts.status);
273
- if (opts && opts.limit) params.set('limit', String(opts.limit));
274
- const q = '?' + params.toString();
275
- return _get('/atp/proofs' + q, '/a2a/atp/proofs' + q);
276
- }
277
-
278
- /**
279
- * GET /a2a/atp/policy -- get ATP policy config
280
- */
281
- function getAtpPolicy() {
282
- return _get('/atp/policy', '/a2a/atp/policy');
283
- }
284
-
285
- /**
286
- * GET /a2a/task/my?node_id=... -- list this node's claimed tasks
287
- *
288
- * ATP-originated tasks include an `atp_order_id` field on each task so the
289
- * merchant side can pair a completed task with its DeliveryProof and call
290
- * submitDelivery. Non-ATP tasks simply omit the field. This is NOT an
291
- * /atp/* endpoint so it never routes through the proxy passthrough.
292
- *
293
- * @param {number} [limit]
294
- */
295
- function listMyTasks(limit) {
296
- const nid = getNodeId();
297
- const params = new URLSearchParams();
298
- params.set('node_id', nid);
299
- if (limit) params.set('limit', String(limit));
300
- const suffix = '/a2a/task/my?' + params.toString();
301
- return _hubGet(suffix);
302
- }
303
-
304
- module.exports = {
305
- placeOrder,
306
- submitDelivery,
307
- verifyDelivery,
308
- settleOrder,
309
- disputeOrder,
310
- getMerchantTier,
311
- getOrderStatus,
312
- listProofs,
313
- getAtpPolicy,
314
- listMyTasks,
315
- // exported for tests only
316
- _isProxyMode: _isProxyMode,
317
- };
package/src/atp/index.js DELETED
@@ -1,38 +0,0 @@
1
- // ATP (Agent Transaction Protocol) Module
2
- // Low-commission agent-to-agent transaction network.
3
- //
4
- // Sub-modules:
5
- // hubClient - Hub API client for ATP endpoints
6
- // merchantAgent - ready-to-use merchant agent template
7
- // consumerAgent - ready-to-use consumer agent template
8
- // serviceHelper - service publishing helper
9
- // defaultHandler - default order handler + config helpers for auto-ATP
10
- // autoBuyer - opt-out capability-gap auto order helper with budget caps
11
- // autoDeliver - opt-out merchant-side submitDelivery daemon
12
- // atpTaskPickup - merchant-side bridge from pre-claimed ATP tasks to sessions_spawn
13
- // atpExecute - end-to-end completer (publish Gene+Capsule, complete, deliver)
14
- // cli - parsers and runners for the `buy`/`orders`/`verify` subcommands
15
-
16
- const hubClient = require('./hubClient');
17
- const merchantAgent = require('./merchantAgent');
18
- const consumerAgent = require('./consumerAgent');
19
- const serviceHelper = require('./serviceHelper');
20
- const defaultHandler = require('./defaultHandler');
21
- const autoBuyer = require('./autoBuyer');
22
- const autoDeliver = require('./autoDeliver');
23
- const atpTaskPickup = require('./atpTaskPickup');
24
- const atpExecute = require('./atpExecute');
25
- const cli = require('./cli');
26
-
27
- module.exports = {
28
- hubClient,
29
- merchantAgent,
30
- consumerAgent,
31
- serviceHelper,
32
- defaultHandler,
33
- autoBuyer,
34
- autoDeliver,
35
- atpTaskPickup,
36
- atpExecute,
37
- cli,
38
- };