@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,518 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // questionGenerator -- analyzes evolution context (signals, session transcripts,
3
- // recent events) and generates proactive questions for the Hub bounty system.
4
- //
5
- // Questions are sent via the A2A fetch payload.questions field. The Hub creates
6
- // bounties from them, enabling multi-agent collaborative problem solving.
7
- //
8
- // Two entry points:
9
- // generateQuestions() -- standard path, runs at cycle start (rate-limited)
10
- // generateUrgentQuestions() -- post-solidify path, bypasses cooldown for
11
- // high-priority situations (failed solidify,
12
- // low confidence, validation failures)
13
- // ---------------------------------------------------------------------------
14
-
15
- const fs = require('fs');
16
- const path = require('path');
17
- const { getEvolutionDir } = require('./paths');
18
-
19
- const QUESTION_STATE_FILE = path.join(getEvolutionDir(), 'question_generator_state.json');
20
- const MIN_INTERVAL_MS = 30 * 60 * 1000; // standard path: at most once per 30 minutes
21
- const URGENT_INTERVAL_MS = 5 * 60 * 1000; // urgent path: at most once per 5 minutes
22
- const EXPLORE_INTERVAL_MS = 6 * 60 * 60 * 1000; // exploration path: at most once per 6 hours
23
- const MAX_QUESTIONS_PER_CYCLE = 3;
24
- const MAX_URGENT_QUESTIONS = 2;
25
-
26
- // Problem-signal triggers used by the standard strategies. Their presence means
27
- // the agent is "stuck"; the exploration (healthy-agent) strategy stays out of
28
- // the way when any of these fire, and is filtered out of a question's topic
29
- // anchor so a curiosity question never reads like a distress signal.
30
- var PROBLEM_SIGNALS = [
31
- 'recurring_error', 'high_failure_ratio', 'capability_gap', 'unsupported_input_type',
32
- 'evolution_saturation', 'force_steady_state', 'consecutive_failure_streak',
33
- 'user_feature_request', 'perf_bottleneck', 'hub_search_miss_with_problem',
34
- 'repair_loop_detected', 'force_innovation_after_repair_loop',
35
- 'plateau_pivot_required', 'plateau_pivot_suggested',
36
- ];
37
-
38
- // Common words stripped before ranking topic keywords for exploration questions.
39
- var EXPLORE_STOPWORDS = new Set([
40
- 'the', 'and', 'for', 'that', 'this', 'with', 'from', 'have', 'what', 'your',
41
- 'agent', 'about', 'into', 'then', 'than', 'they', 'them', 'their', 'there',
42
- 'here', 'will', 'would', 'could', 'should', 'been', 'were', 'using', 'used',
43
- 'cycle', 'evolution', 'error', 'errors', 'failed', 'failure', 'null', 'undefined',
44
- 'true', 'false', 'console', 'return', 'function', 'const', 'value', 'result',
45
- ]);
46
-
47
- // Infrastructure / user-local failures that the ecosystem cannot resolve.
48
- // Keep in sync with the hub-side bounty spam guard so the two gates never
49
- // disagree about what is worth asking the community.
50
- var INFRA_ERROR_RE = /\b(401|403|429|500|502|503|504|529)\b|invalid[\s_-]?api[\s_-]?key|authentication[\s_-]?error|unauthorized|permission[\s_-]?denied|rate[\s_-]?limit|too[\s_-]?many[\s_-]?requests|overloaded[\s_-]?error|ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EPIPE|fetch[\s_-]?failed|network[\s_-]?error|connection[\s_-]?refused|context[\s_-]?length|token[\s_-]?limit|(?:context|input)[\s_-]?window[\s_-]?exceeded|maximum[\s_-]?context[\s_-]?length/i;
51
-
52
- function isInfraError(text) {
53
- if (!text || typeof text !== 'string') return false;
54
- return INFRA_ERROR_RE.test(text);
55
- }
56
-
57
- function readState() {
58
- try {
59
- if (fs.existsSync(QUESTION_STATE_FILE)) {
60
- return JSON.parse(fs.readFileSync(QUESTION_STATE_FILE, 'utf8'));
61
- }
62
- } catch (_) {}
63
- return { lastAskedAt: null, lastUrgentAt: null, recentQuestions: [] };
64
- }
65
-
66
- function writeState(state) {
67
- try {
68
- var dir = path.dirname(QUESTION_STATE_FILE);
69
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
70
- fs.writeFileSync(QUESTION_STATE_FILE, JSON.stringify(state, null, 2) + '\n');
71
- } catch (_) {}
72
- }
73
-
74
- function isDuplicate(question, recentQuestions) {
75
- var qLower = question.toLowerCase();
76
- for (var i = 0; i < recentQuestions.length; i++) {
77
- var prev = String(recentQuestions[i] || '').toLowerCase();
78
- if (prev === qLower) return true;
79
- var qWords = new Set(qLower.split(/\s+/).filter(function(w) { return w.length > 2; }));
80
- var pWords = new Set(prev.split(/\s+/).filter(function(w) { return w.length > 2; }));
81
- if (qWords.size === 0 || pWords.size === 0) continue;
82
- var overlap = 0;
83
- qWords.forEach(function(w) { if (pWords.has(w)) overlap++; });
84
- if (overlap / Math.max(qWords.size, pWords.size) > 0.7) return true;
85
- }
86
- return false;
87
- }
88
-
89
- function extractErrorContext(transcript, maxLen) {
90
- var lines = transcript.split('\n');
91
- for (var i = 0; i < lines.length; i++) {
92
- if (/error|exception|failed|cannot|not supported|unsupported|not implemented/i.test(lines[i])) {
93
- return lines[i].replace(/\s+/g, ' ').trim().slice(0, maxLen || 150);
94
- }
95
- }
96
- return '';
97
- }
98
-
99
- function extractRecentGeneIds(recentEvents, count) {
100
- var ids = [];
101
- var last = recentEvents.slice(-(count || 5));
102
- for (var j = 0; j < last.length; j++) {
103
- var genes = last[j].genes_used;
104
- if (Array.isArray(genes) && genes.length > 0) ids.push(genes[0]);
105
- }
106
- return Array.from(new Set(ids));
107
- }
108
-
109
- // Pull a few salient domain keywords from the agent's recent work (session
110
- // transcript + memory). Deterministic frequency ranking, no NLP dependency.
111
- // Returns up to `max` distinctive lowercase terms, or [] when there is nothing
112
- // substantive -- used to ground exploration questions in the agent's real
113
- // activity so they are specific (and clear the hub relevance gate), not generic.
114
- function extractTopicKeywords(transcript, memory, max) {
115
- var text = (String(transcript || '') + ' ' + String(memory || '')).toLowerCase();
116
- var words = text.match(/[a-z][a-z0-9_-]{4,}/g) || [];
117
- var freq = {};
118
- for (var i = 0; i < words.length; i++) {
119
- var w = words[i];
120
- if (EXPLORE_STOPWORDS.has(w)) continue;
121
- freq[w] = (freq[w] || 0) + 1;
122
- }
123
- var ranked = Object.keys(freq)
124
- .filter(function (w) { return freq[w] >= 2; })
125
- .sort(function (a, b) { return freq[b] - freq[a]; });
126
- return ranked.slice(0, max || 5);
127
- }
128
-
129
- // Exploration strategy: a healthy, productively-running agent proactively asks
130
- // the network how to extend itself -- complementary capabilities, reusable
131
- // patterns, or adjacent high-value problems. This is the path that keeps organic
132
- // bounty demand flowing when no problem signals are firing (problem strategies
133
- // only fire when the agent is stuck). Anchored on the agent's real recent work
134
- // so the question is specific, not noise; returns null when there is no anchor.
135
- function buildExplorationCandidate(signals, recentEvents, transcript, memory) {
136
- var topicSignals = (signals || []).filter(function (s) {
137
- s = String(s || '');
138
- if (!/^[a-z][a-z0-9_]{3,40}$/i.test(s)) return false;
139
- if (s.indexOf('errsig') === 0 || s.indexOf('ban_gene') === 0 || s.indexOf('recurring_') === 0) return false;
140
- return !PROBLEM_SIGNALS.some(function (p) { return s === p || s.indexOf(p) === 0; });
141
- }).slice(0, 4);
142
-
143
- var keywords = extractTopicKeywords(transcript, memory, 5);
144
- var genes = extractRecentGeneIds(recentEvents, 5);
145
-
146
- // Require real work artifacts (domain keywords from the transcript/memory, or
147
- // recent genes) to ground the question. A bare signal name is too thin an
148
- // anchor to make a useful bounty, so topic signals only enrich the tags.
149
- if (keywords.length === 0 && genes.length === 0) return null;
150
-
151
- var focus = keywords.length > 0 ? keywords.slice(0, 5).join(', ') : genes.join(', ');
152
- var question = 'A productively-running agent working on ' + focus
153
- + ' wants to extend its capabilities. What reusable patterns, automation genes, '
154
- + 'or complementary tools in this area would be most valuable to build next, and '
155
- + 'what adjacent high-value problems is the ecosystem not yet solving well here?';
156
-
157
- return {
158
- question: question,
159
- amount: 0,
160
- signals: ['capability_frontier', 'exploration', 'proactive_curiosity']
161
- .concat(keywords.slice(0, 2))
162
- .concat(topicSignals.slice(0, 2)),
163
- priority: 0,
164
- };
165
- }
166
-
167
- // ---------------------------------------------------------------------------
168
- // Standard strategies (cycle-start, rate-limited by MIN_INTERVAL_MS)
169
- // ---------------------------------------------------------------------------
170
-
171
- function buildStandardCandidates(signals, recentEvents, transcript, memory) {
172
- var candidates = [];
173
- var signalSet = new Set(signals);
174
-
175
- // Strategy 1: Recurring errors the agent cannot resolve
176
- if (signalSet.has('recurring_error') || signalSet.has('high_failure_ratio')) {
177
- var errSig = signals.find(function(s) { return s.startsWith('recurring_errsig'); });
178
- if (errSig) {
179
- var errDetail = errSig.replace(/^recurring_errsig\(\d+x\):/, '').trim().slice(0, 120);
180
- // Skip infra/user-local failures (invalid api key, 429, network issues)
181
- // -- the community cannot fix the user's own environment.
182
- if (!isInfraError(errDetail)) {
183
- candidates.push({
184
- question: 'Recurring error in evolution cycle that auto-repair cannot resolve: ' + errDetail + ' -- What approaches or patches have worked for similar issues?',
185
- amount: 0,
186
- signals: ['recurring_error', 'auto_repair_failed'],
187
- priority: 3,
188
- });
189
- }
190
- }
191
- }
192
-
193
- // Strategy 2: Capability gaps detected from user conversations
194
- if (signalSet.has('capability_gap') || signalSet.has('unsupported_input_type')) {
195
- var gapContext = extractErrorContext(transcript, 150);
196
- if (gapContext && !isInfraError(gapContext)) {
197
- candidates.push({
198
- question: 'Capability gap detected in agent environment: ' + gapContext + ' -- How can this be addressed or what alternative approaches exist?',
199
- amount: 0,
200
- signals: ['capability_gap'],
201
- priority: 2,
202
- });
203
- }
204
- }
205
-
206
- // Strategy 3: Stagnation / saturation -- seek new directions
207
- if (signalSet.has('evolution_saturation') || signalSet.has('force_steady_state')) {
208
- var uniqueGenes = extractRecentGeneIds(recentEvents, 5);
209
- candidates.push({
210
- question: 'Agent evolution has reached saturation after exhausting genes: [' + uniqueGenes.join(', ') + ']. What new evolution directions, automation patterns, or capability genes would be most valuable?',
211
- amount: 0,
212
- signals: ['evolution_saturation', 'innovation_needed'],
213
- priority: 1,
214
- });
215
- }
216
-
217
- // Strategy 4: Consecutive failure streak -- seek external help
218
- var failStreak = signals.find(function(s) { return s.startsWith('consecutive_failure_streak_'); });
219
- if (failStreak) {
220
- var streakCount = parseInt(failStreak.replace('consecutive_failure_streak_', ''), 10) || 0;
221
- if (streakCount >= 3) {
222
- var failGene = signals.find(function(s) { return s.startsWith('ban_gene:'); });
223
- var failGeneId = failGene ? failGene.replace('ban_gene:', '') : 'unknown';
224
- candidates.push({
225
- question: 'Agent has failed ' + streakCount + ' consecutive evolution cycles (last gene: ' + failGeneId + '). The current approach is exhausted. What alternative strategies or environmental fixes should be tried?',
226
- amount: 0,
227
- signals: ['failure_streak', 'external_help_needed'],
228
- priority: 3,
229
- });
230
- }
231
- }
232
-
233
- // Strategy 5: User feature requests the agent can amplify
234
- if (signalSet.has('user_feature_request') || signals.some(function (s) { return String(s).startsWith('user_feature_request:'); })) {
235
- var featureLines = transcript.split('\n').filter(function(l) {
236
- return /\b(add|implement|create|build|i want|i need|please add)\b/i.test(l);
237
- });
238
- if (featureLines.length > 0) {
239
- var featureContext = featureLines[0].replace(/\s+/g, ' ').trim().slice(0, 150);
240
- candidates.push({
241
- question: 'User requested a feature that may benefit from community solutions: ' + featureContext + ' -- Are there existing implementations or best practices for this?',
242
- amount: 0,
243
- signals: ['user_feature_request', 'community_solution_sought'],
244
- priority: 1,
245
- });
246
- }
247
- }
248
-
249
- // Strategy 6: Performance bottleneck -- seek optimization patterns
250
- if (signalSet.has('perf_bottleneck')) {
251
- var perfLines = transcript.split('\n').filter(function(l) {
252
- return /\b(slow|timeout|latency|bottleneck|high cpu|high memory)\b/i.test(l);
253
- });
254
- if (perfLines.length > 0) {
255
- var perfContext = perfLines[0].replace(/\s+/g, ' ').trim().slice(0, 150);
256
- candidates.push({
257
- question: 'Performance bottleneck detected: ' + perfContext + ' -- What optimization strategies or architectural patterns address this?',
258
- amount: 0,
259
- signals: ['perf_bottleneck', 'optimization_sought'],
260
- priority: 2,
261
- });
262
- }
263
- }
264
-
265
- // Strategy 7: Hub search miss with active problem -- no ecosystem solution exists
266
- if (signalSet.has('hub_search_miss_with_problem')) {
267
- var problemCtx = extractErrorContext(transcript, 120);
268
- var problemSignalList = signals.filter(function(s) {
269
- return s === 'log_error' || s === 'test_failure' || s === 'deployment_issue'
270
- || s.startsWith('errsig:');
271
- }).slice(0, 3);
272
- if (!isInfraError(problemCtx) && !isInfraError(problemSignalList.join(' '))) {
273
- candidates.push({
274
- question: 'No matching solution found in ecosystem for active problem (signals: ' + problemSignalList.join(', ') + '). Context: ' + (problemCtx || 'complex multi-signal issue') + ' -- What strategies, patterns, or tools address this class of problem?',
275
- amount: 0,
276
- signals: ['hub_search_miss', 'ecosystem_gap', 'solution_sought'],
277
- priority: 2,
278
- });
279
- }
280
- }
281
-
282
- // Strategy 8: Repair loop -- stuck in repair->fail->repair cycle
283
- if (signalSet.has('repair_loop_detected') || signalSet.has('force_innovation_after_repair_loop')) {
284
- var recentGenes = extractRecentGeneIds(recentEvents, 6);
285
- candidates.push({
286
- question: 'Agent is stuck in a repair loop (repair->fail->repair cycle) with genes: [' + recentGenes.join(', ') + ']. The underlying issue persists despite multiple attempts. What fundamentally different approach could break this cycle?',
287
- amount: 0,
288
- signals: ['repair_loop', 'architectural_help_needed'],
289
- priority: 3,
290
- });
291
- }
292
-
293
- // Strategy 9: Plateau -- consecutive non-improving outcomes
294
- if (signalSet.has('plateau_pivot_required') || signalSet.has('plateau_pivot_suggested')) {
295
- var severity = signalSet.has('plateau_pivot_required') ? 'severe' : 'moderate';
296
- candidates.push({
297
- question: 'Agent evolution has plateaued (' + severity + ' -- no improvement in recent cycles). Current gene pool and mutation strategies are exhausted. What novel approaches, architectural patterns, or paradigm shifts could restart progress?',
298
- amount: 0,
299
- signals: ['evolution_plateau', 'pivot_needed'],
300
- priority: severity === 'severe' ? 3 : 2,
301
- });
302
- }
303
-
304
- return candidates;
305
- }
306
-
307
- // ---------------------------------------------------------------------------
308
- // Urgent strategies (post-solidify, rate-limited by URGENT_INTERVAL_MS)
309
- // These fire when a single cycle produces a bad outcome, without waiting
310
- // for multi-cycle statistical signals.
311
- // ---------------------------------------------------------------------------
312
-
313
- function buildUrgentCandidates(opts) {
314
- var o = opts || {};
315
- var candidates = [];
316
-
317
- // U1: Solidify validation failure -- the patch failed automated checks
318
- if (o.validationFailed) {
319
- var valErrors = String(o.validationErrors || '').slice(0, 200);
320
- var geneId = o.geneId || 'unknown';
321
- if (!isInfraError(valErrors)) {
322
- candidates.push({
323
- question: 'Evolution cycle produced a patch that failed validation (gene: ' + geneId + '). Errors: ' + valErrors + ' -- What is the correct approach to fix this validation failure?',
324
- amount: 0,
325
- signals: ['validation_failure', 'solidify_rejected'],
326
- priority: 3,
327
- });
328
- }
329
- }
330
-
331
- // U2: Low confidence outcome -- solidify scored below threshold
332
- if (o.lowConfidence && Number.isFinite(o.confidenceScore)) {
333
- var score = Math.round(o.confidenceScore * 100) / 100;
334
- var intent = o.intent || 'unknown';
335
- candidates.push({
336
- question: 'Evolution cycle completed with low confidence (score: ' + score + ', intent: ' + intent + '). The change is uncertain and may not be beneficial. What higher-confidence approaches exist for this type of problem?',
337
- amount: 0,
338
- signals: ['low_confidence', 'uncertain_outcome'],
339
- priority: 2,
340
- });
341
- }
342
-
343
- // U3: LLM review rejection -- a second-opinion model rejected the change
344
- if (o.llmReviewRejected) {
345
- var reason = String(o.llmReviewReason || '').slice(0, 200);
346
- if (!isInfraError(reason)) {
347
- candidates.push({
348
- question: 'Proposed code change was rejected by LLM review: ' + reason + ' -- What alternative implementation approach would pass quality review?',
349
- amount: 0,
350
- signals: ['llm_review_rejected', 'quality_concern'],
351
- priority: 3,
352
- });
353
- }
354
- }
355
-
356
- // U4: Zero blast radius after non-trivial attempt
357
- if (o.zeroBlastRadius && o.hadSignals) {
358
- var attemptedSignals = (Array.isArray(o.signals) ? o.signals : []).slice(0, 5).join(', ');
359
- candidates.push({
360
- question: 'Evolution cycle targeting signals [' + attemptedSignals + '] produced zero blast radius (no effective changes). The approach was insufficient. What concrete implementation steps would address these signals?',
361
- amount: 0,
362
- signals: ['zero_blast_radius', 'ineffective_approach'],
363
- priority: 2,
364
- });
365
- }
366
-
367
- // U5: Task completion failure -- claimed a task but couldn't solve it
368
- if (o.taskCompletionFailed) {
369
- var taskTitle = String(o.taskTitle || '').slice(0, 120);
370
- var taskSignals = String(o.taskSignals || '').slice(0, 100);
371
- if (!isInfraError(taskTitle) && !isInfraError(taskSignals)) {
372
- candidates.push({
373
- question: 'Failed to complete claimed task: "' + taskTitle + '" (signals: ' + taskSignals + '). The problem exceeds current capabilities. What approaches, tools, or patterns would solve this?',
374
- amount: 0,
375
- signals: ['task_completion_failed', 'help_needed'],
376
- priority: 3,
377
- });
378
- }
379
- }
380
-
381
- return candidates;
382
- }
383
-
384
- // ---------------------------------------------------------------------------
385
- // Public API
386
- // ---------------------------------------------------------------------------
387
-
388
- /**
389
- * Standard question generation (cycle start). Rate-limited to MIN_INTERVAL_MS.
390
- */
391
- function generateQuestions(opts) {
392
- var o = opts || {};
393
- var signals = Array.isArray(o.signals) ? o.signals : [];
394
- var recentEvents = Array.isArray(o.recentEvents) ? o.recentEvents : [];
395
- var transcript = String(o.sessionTranscript || '');
396
- var memory = String(o.memorySnippet || '');
397
-
398
- var state = readState();
399
-
400
- if (state.lastAskedAt) {
401
- var elapsed = Date.now() - new Date(state.lastAskedAt).getTime();
402
- if (elapsed < MIN_INTERVAL_MS) return [];
403
- }
404
-
405
- var candidates = buildStandardCandidates(signals, recentEvents, transcript, memory);
406
-
407
- // Exploration (healthy-agent) path: add a low-priority proactive question on a
408
- // slower cadence (EXPLORE_INTERVAL_MS) so a smoothly-running agent -- which
409
- // trips none of the problem strategies above -- still seeds organic bounty
410
- // demand. Disable with EVOLVER_EXPLORATION_QUESTIONS=0.
411
- var exploreEligible = process.env.EVOLVER_EXPLORATION_QUESTIONS !== '0';
412
- if (exploreEligible && state.lastExploreAt) {
413
- var exElapsed = Date.now() - new Date(state.lastExploreAt).getTime();
414
- if (exElapsed < EXPLORE_INTERVAL_MS) exploreEligible = false;
415
- }
416
- if (exploreEligible) {
417
- var exploration = buildExplorationCandidate(signals, recentEvents, transcript, memory);
418
- if (exploration) candidates.push(exploration);
419
- }
420
-
421
- if (candidates.length === 0) return [];
422
-
423
- candidates.sort(function(a, b) { return b.priority - a.priority; });
424
-
425
- var recentQTexts = Array.isArray(state.recentQuestions) ? state.recentQuestions : [];
426
- var filtered = [];
427
- for (var fi = 0; fi < candidates.length && filtered.length < MAX_QUESTIONS_PER_CYCLE; fi++) {
428
- if (!isDuplicate(candidates[fi].question, recentQTexts)) {
429
- filtered.push(candidates[fi]);
430
- }
431
- }
432
-
433
- if (filtered.length === 0) return [];
434
-
435
- // Advance the exploration cooldown only if an exploration question actually
436
- // went out, so problem questions never consume the slower exploration budget.
437
- var explorationSent = filtered.some(function (q) {
438
- return Array.isArray(q.signals) && q.signals.indexOf('exploration') !== -1;
439
- });
440
-
441
- var newRecentQuestions = recentQTexts.concat(filtered.map(function(q) { return q.question; }));
442
- if (newRecentQuestions.length > 30) {
443
- newRecentQuestions = newRecentQuestions.slice(-30);
444
- }
445
- writeState({
446
- lastAskedAt: new Date().toISOString(),
447
- lastUrgentAt: state.lastUrgentAt || null,
448
- lastExploreAt: explorationSent ? new Date().toISOString() : (state.lastExploreAt || null),
449
- recentQuestions: newRecentQuestions,
450
- });
451
-
452
- return filtered.map(function(q) {
453
- return { question: q.question, amount: q.amount, signals: q.signals };
454
- });
455
- }
456
-
457
- /**
458
- * Urgent question generation (post-solidify). Bypasses the standard cooldown
459
- * but has its own shorter cooldown (URGENT_INTERVAL_MS). Only fires when
460
- * a single cycle produces a clearly bad outcome.
461
- *
462
- * @param {object} opts
463
- * @param {boolean} [opts.validationFailed] - solidify validation failed
464
- * @param {string} [opts.validationErrors] - error details
465
- * @param {string} [opts.geneId] - gene used in the failed cycle
466
- * @param {boolean} [opts.lowConfidence] - score below threshold
467
- * @param {number} [opts.confidenceScore] - actual score (0-1)
468
- * @param {string} [opts.intent] - cycle intent
469
- * @param {boolean} [opts.llmReviewRejected] - LLM review rejected the change
470
- * @param {string} [opts.llmReviewReason] - rejection reason
471
- * @param {boolean} [opts.zeroBlastRadius] - no effective changes
472
- * @param {boolean} [opts.hadSignals] - had actionable signals
473
- * @param {string[]} [opts.signals] - current signals
474
- * @param {boolean} [opts.taskCompletionFailed] - failed to complete a task
475
- * @param {string} [opts.taskTitle] - task title
476
- * @param {string} [opts.taskSignals] - task signals
477
- * @returns {Array<{ question: string, amount: number, signals: string[] }>}
478
- */
479
- function generateUrgentQuestions(opts) {
480
- var state = readState();
481
-
482
- if (state.lastUrgentAt) {
483
- var elapsed = Date.now() - new Date(state.lastUrgentAt).getTime();
484
- if (elapsed < URGENT_INTERVAL_MS) return [];
485
- }
486
-
487
- var candidates = buildUrgentCandidates(opts);
488
- if (candidates.length === 0) return [];
489
-
490
- candidates.sort(function(a, b) { return b.priority - a.priority; });
491
-
492
- var recentQTexts = Array.isArray(state.recentQuestions) ? state.recentQuestions : [];
493
- var filtered = [];
494
- for (var fi = 0; fi < candidates.length && filtered.length < MAX_URGENT_QUESTIONS; fi++) {
495
- if (!isDuplicate(candidates[fi].question, recentQTexts)) {
496
- filtered.push(candidates[fi]);
497
- }
498
- }
499
-
500
- if (filtered.length === 0) return [];
501
-
502
- var newRecentQuestions = recentQTexts.concat(filtered.map(function(q) { return q.question; }));
503
- if (newRecentQuestions.length > 30) {
504
- newRecentQuestions = newRecentQuestions.slice(-30);
505
- }
506
- writeState({
507
- lastAskedAt: state.lastAskedAt || null,
508
- lastUrgentAt: new Date().toISOString(),
509
- lastExploreAt: state.lastExploreAt || null,
510
- recentQuestions: newRecentQuestions,
511
- });
512
-
513
- return filtered.map(function(q) {
514
- return { question: q.question, amount: q.amount, signals: q.signals };
515
- });
516
- }
517
-
518
- module.exports = { generateQuestions, generateUrgentQuestions };