@evomap/evolver 1.89.20 → 2.0.0-beta.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 (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 -3586
  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/skills/_meta/SKILL.md +0 -41
  38. package/skills/index.json +0 -14
  39. package/src/adapters/claudeCode.js +0 -194
  40. package/src/adapters/codex.js +0 -216
  41. package/src/adapters/cursor.js +0 -91
  42. package/src/adapters/hookAdapter.js +0 -469
  43. package/src/adapters/kiro.js +0 -195
  44. package/src/adapters/opencode.js +0 -326
  45. package/src/adapters/scripts/_lockPaths.js +0 -74
  46. package/src/adapters/scripts/_memoryFiltering.js +0 -35
  47. package/src/adapters/scripts/_runtimePaths.js +0 -440
  48. package/src/adapters/scripts/evolver-session-end.js +0 -321
  49. package/src/adapters/scripts/evolver-session-start.js +0 -587
  50. package/src/adapters/scripts/evolver-signal-detect.js +0 -98
  51. package/src/adapters/scripts/evolver-task-recall.js +0 -173
  52. package/src/atp/atpExecute.js +0 -283
  53. package/src/atp/atpTaskPickup.js +0 -233
  54. package/src/atp/autoBuyer.js +0 -382
  55. package/src/atp/autoDeliver.js +0 -215
  56. package/src/atp/cli.js +0 -354
  57. package/src/atp/cliAutobuyPrompt.js +0 -154
  58. package/src/atp/consumerAgent.js +0 -157
  59. package/src/atp/defaultHandler.js +0 -69
  60. package/src/atp/heartbeatSignalsHandler.js +0 -254
  61. package/src/atp/hubClient.js +0 -317
  62. package/src/atp/index.js +0 -38
  63. package/src/atp/merchantAgent.js +0 -118
  64. package/src/atp/protocol.js +0 -41
  65. package/src/atp/questionComposer.js +0 -133
  66. package/src/atp/serviceHelper.js +0 -92
  67. package/src/canary.js +0 -13
  68. package/src/config.js +0 -351
  69. package/src/evolve/guards.js +0 -1
  70. package/src/evolve/pipeline/collect.js +0 -1
  71. package/src/evolve/pipeline/dispatch.js +0 -1
  72. package/src/evolve/pipeline/enrich.js +0 -1
  73. package/src/evolve/pipeline/hub.js +0 -1
  74. package/src/evolve/pipeline/select.js +0 -1
  75. package/src/evolve/pipeline/signals.js +0 -1
  76. package/src/evolve/utils.js +0 -1
  77. package/src/evolve.js +0 -1
  78. package/src/experiment/agentRunner.js +0 -229
  79. package/src/experiment/cli.js +0 -159
  80. package/src/experiment/comparison.js +0 -233
  81. package/src/experiment/metrics.js +0 -75
  82. package/src/forceUpdate.js +0 -991
  83. package/src/gep/a2a.js +0 -173
  84. package/src/gep/a2aProtocol.js +0 -1
  85. package/src/gep/analyzer.js +0 -35
  86. package/src/gep/antiAbuseTelemetry.js +0 -1
  87. package/src/gep/assetCallLog.js +0 -197
  88. package/src/gep/assetStore.js +0 -723
  89. package/src/gep/assets.js +0 -36
  90. package/src/gep/autoDistillConv.js +0 -1
  91. package/src/gep/autoDistillLlm.js +0 -1
  92. package/src/gep/bridge.js +0 -138
  93. package/src/gep/candidateEval.js +0 -1
  94. package/src/gep/candidates.js +0 -1
  95. package/src/gep/claimNudge.js +0 -121
  96. package/src/gep/cliContracts.js +0 -1190
  97. package/src/gep/contentHash.js +0 -1
  98. package/src/gep/conversationDistiller.js +0 -1
  99. package/src/gep/conversationSniffer.js +0 -1
  100. package/src/gep/crypto.js +0 -1
  101. package/src/gep/curriculum.js +0 -1
  102. package/src/gep/deviceId.js +0 -1
  103. package/src/gep/directoryClient.js +0 -115
  104. package/src/gep/envFingerprint.js +0 -1
  105. package/src/gep/epigenetics.js +0 -1
  106. package/src/gep/execBridge.js +0 -1
  107. package/src/gep/executionTrace.js +0 -291
  108. package/src/gep/explore.js +0 -1
  109. package/src/gep/featureFlags.js +0 -121
  110. package/src/gep/gitOps.js +0 -265
  111. package/src/gep/hash.js +0 -1
  112. package/src/gep/hostErrorClassifier.js +0 -34
  113. package/src/gep/hubFetch.js +0 -1
  114. package/src/gep/hubReview.js +0 -1
  115. package/src/gep/hubSearch.js +0 -1
  116. package/src/gep/hubVerify.js +0 -1
  117. package/src/gep/idleScheduler.js +0 -400
  118. package/src/gep/issueReporter.js +0 -416
  119. package/src/gep/learningSignals.js +0 -1
  120. package/src/gep/llmReview.js +0 -92
  121. package/src/gep/localStateAwareness.js +0 -243
  122. package/src/gep/mailboxTransport.js +0 -119
  123. package/src/gep/memoryGraph.js +0 -1
  124. package/src/gep/memoryGraphAdapter.js +0 -1
  125. package/src/gep/mutation.js +0 -1
  126. package/src/gep/narrativeMemory.js +0 -1
  127. package/src/gep/oauthLogin.js +0 -181
  128. package/src/gep/openPRRegistry.js +0 -1
  129. package/src/gep/paths.js +0 -522
  130. package/src/gep/personality.js +0 -1
  131. package/src/gep/policyCheck.js +0 -1
  132. package/src/gep/portable.js +0 -103
  133. package/src/gep/privacyClient.js +0 -235
  134. package/src/gep/prompt.js +0 -1
  135. package/src/gep/questionGenerator.js +0 -518
  136. package/src/gep/recallInject.js +0 -1
  137. package/src/gep/recallVerifier.js +0 -1
  138. package/src/gep/reflection.js +0 -1
  139. package/src/gep/sanitize.js +0 -264
  140. package/src/gep/savingsCore.js +0 -1
  141. package/src/gep/schemas/capsule.js +0 -170
  142. package/src/gep/schemas/gene.js +0 -154
  143. package/src/gep/schemas/index.js +0 -8
  144. package/src/gep/schemas/protocol.js +0 -51
  145. package/src/gep/schemas/task.js +0 -74
  146. package/src/gep/selector.js +0 -1
  147. package/src/gep/selfPR.js +0 -469
  148. package/src/gep/signals.js +0 -776
  149. package/src/gep/skill2gep.js +0 -1056
  150. package/src/gep/skill2gepAudit.js +0 -303
  151. package/src/gep/skill2recipes.js +0 -511
  152. package/src/gep/skillDistiller.js +0 -1
  153. package/src/gep/skillPublisher.js +0 -358
  154. package/src/gep/solidify.js +0 -1
  155. package/src/gep/strategy.js +0 -1
  156. package/src/gep/taskReceiver.js +0 -575
  157. package/src/gep/tokenSavings.js +0 -1
  158. package/src/gep/trajectoryExport.js +0 -1
  159. package/src/gep/validationReport.js +0 -55
  160. package/src/gep/validator/index.js +0 -411
  161. package/src/gep/validator/reporter.js +0 -210
  162. package/src/gep/validator/sandboxExecutor.js +0 -480
  163. package/src/gep/validator/stakeBootstrap.js +0 -357
  164. package/src/gep/workspaceKeychain.js +0 -1
  165. package/src/ops/cleanup.js +0 -80
  166. package/src/ops/commentary.js +0 -60
  167. package/src/ops/health_check.js +0 -104
  168. package/src/ops/index.js +0 -11
  169. package/src/ops/innovation.js +0 -67
  170. package/src/ops/lifecycle.js +0 -798
  171. package/src/ops/self_repair.js +0 -76
  172. package/src/ops/skills_monitor.js +0 -147
  173. package/src/ops/trigger.js +0 -33
  174. package/src/proxy/clientSettings.js +0 -405
  175. package/src/proxy/envelope.js +0 -59
  176. package/src/proxy/extensions/dmHandler.js +0 -45
  177. package/src/proxy/extensions/sessionHandler.js +0 -141
  178. package/src/proxy/extensions/skillUpdater.js +0 -64
  179. package/src/proxy/extensions/traceControl.js +0 -1
  180. package/src/proxy/index.js +0 -1395
  181. package/src/proxy/inject.js +0 -1
  182. package/src/proxy/lifecycle/manager.js +0 -1568
  183. package/src/proxy/mailbox/state.js +0 -207
  184. package/src/proxy/mailbox/store.js +0 -590
  185. package/src/proxy/router/cache_passthrough.js +0 -26
  186. package/src/proxy/router/features.js +0 -84
  187. package/src/proxy/router/gemini_route.js +0 -154
  188. package/src/proxy/router/messages_route.js +0 -535
  189. package/src/proxy/router/model_router.js +0 -113
  190. package/src/proxy/router/models_route.js +0 -52
  191. package/src/proxy/router/ollama_route.js +0 -103
  192. package/src/proxy/router/responses_route.js +0 -170
  193. package/src/proxy/router/vertex_route.js +0 -110
  194. package/src/proxy/server/http.js +0 -363
  195. package/src/proxy/server/routes.js +0 -558
  196. package/src/proxy/server/settings.js +0 -115
  197. package/src/proxy/sync/engine.js +0 -179
  198. package/src/proxy/sync/inbound.js +0 -211
  199. package/src/proxy/sync/outbound.js +0 -320
  200. package/src/proxy/task/monitor.js +0 -131
  201. package/src/proxy/trace/extractor.js +0 -1
  202. package/src/proxy/trace/usage.js +0 -1
  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
- };