@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.
- package/README.md +27 -564
- package/bin/evolver-llm-proxy.js +3 -0
- package/bin/evolver-mcp.js +2 -0
- package/bin/evolver-proxy.js +3 -0
- package/bin/evolver.js +4 -0
- package/index.js +1 -3586
- package/package.json +32 -62
- package/CONTRIBUTING.md +0 -19
- package/LICENSE +0 -641
- package/README.ja-JP.md +0 -521
- package/README.ko-KR.md +0 -520
- package/README.zh-CN.md +0 -531
- package/SKILL.md +0 -365
- package/assets/cover.png +0 -0
- package/assets/gep/genes.seed.json +0 -496
- package/conformance/savings-core/constants.json +0 -30
- package/conformance/savings-core/golden-vectors.json +0 -333
- package/scripts/a2a_export.js +0 -63
- package/scripts/a2a_ingest.js +0 -79
- package/scripts/a2a_promote.js +0 -118
- package/scripts/analyze_by_skill.js +0 -121
- package/scripts/build_binaries.js +0 -479
- package/scripts/check-changelog.js +0 -166
- package/scripts/extract_log.js +0 -85
- package/scripts/generate_history.js +0 -75
- package/scripts/gep_append_event.js +0 -96
- package/scripts/gep_personality_report.js +0 -234
- package/scripts/human_report.js +0 -147
- package/scripts/recall-verify-report.js +0 -234
- package/scripts/recover_loop.js +0 -61
- package/scripts/refresh_stars_badge.js +0 -168
- package/scripts/seed-merchants.js +0 -91
- package/scripts/skill2recipes.js +0 -118
- package/scripts/suggest_version.js +0 -89
- package/scripts/validate-modules.js +0 -38
- package/scripts/validate-suite.js +0 -78
- package/skills/_meta/SKILL.md +0 -41
- package/skills/index.json +0 -14
- package/src/adapters/claudeCode.js +0 -194
- package/src/adapters/codex.js +0 -216
- package/src/adapters/cursor.js +0 -91
- package/src/adapters/hookAdapter.js +0 -469
- package/src/adapters/kiro.js +0 -195
- package/src/adapters/opencode.js +0 -326
- package/src/adapters/scripts/_lockPaths.js +0 -74
- package/src/adapters/scripts/_memoryFiltering.js +0 -35
- package/src/adapters/scripts/_runtimePaths.js +0 -440
- package/src/adapters/scripts/evolver-session-end.js +0 -321
- package/src/adapters/scripts/evolver-session-start.js +0 -587
- package/src/adapters/scripts/evolver-signal-detect.js +0 -98
- package/src/adapters/scripts/evolver-task-recall.js +0 -173
- package/src/atp/atpExecute.js +0 -283
- package/src/atp/atpTaskPickup.js +0 -233
- package/src/atp/autoBuyer.js +0 -382
- package/src/atp/autoDeliver.js +0 -215
- package/src/atp/cli.js +0 -354
- package/src/atp/cliAutobuyPrompt.js +0 -154
- package/src/atp/consumerAgent.js +0 -157
- package/src/atp/defaultHandler.js +0 -69
- package/src/atp/heartbeatSignalsHandler.js +0 -254
- package/src/atp/hubClient.js +0 -317
- package/src/atp/index.js +0 -38
- package/src/atp/merchantAgent.js +0 -118
- package/src/atp/protocol.js +0 -41
- package/src/atp/questionComposer.js +0 -133
- package/src/atp/serviceHelper.js +0 -92
- package/src/canary.js +0 -13
- package/src/config.js +0 -351
- package/src/evolve/guards.js +0 -1
- package/src/evolve/pipeline/collect.js +0 -1
- package/src/evolve/pipeline/dispatch.js +0 -1
- package/src/evolve/pipeline/enrich.js +0 -1
- package/src/evolve/pipeline/hub.js +0 -1
- package/src/evolve/pipeline/select.js +0 -1
- package/src/evolve/pipeline/signals.js +0 -1
- package/src/evolve/utils.js +0 -1
- package/src/evolve.js +0 -1
- package/src/experiment/agentRunner.js +0 -229
- package/src/experiment/cli.js +0 -159
- package/src/experiment/comparison.js +0 -233
- package/src/experiment/metrics.js +0 -75
- package/src/forceUpdate.js +0 -991
- package/src/gep/a2a.js +0 -173
- package/src/gep/a2aProtocol.js +0 -1
- package/src/gep/analyzer.js +0 -35
- package/src/gep/antiAbuseTelemetry.js +0 -1
- package/src/gep/assetCallLog.js +0 -197
- package/src/gep/assetStore.js +0 -723
- package/src/gep/assets.js +0 -36
- package/src/gep/autoDistillConv.js +0 -1
- package/src/gep/autoDistillLlm.js +0 -1
- package/src/gep/bridge.js +0 -138
- package/src/gep/candidateEval.js +0 -1
- package/src/gep/candidates.js +0 -1
- package/src/gep/claimNudge.js +0 -121
- package/src/gep/cliContracts.js +0 -1190
- package/src/gep/contentHash.js +0 -1
- package/src/gep/conversationDistiller.js +0 -1
- package/src/gep/conversationSniffer.js +0 -1
- package/src/gep/crypto.js +0 -1
- package/src/gep/curriculum.js +0 -1
- package/src/gep/deviceId.js +0 -1
- package/src/gep/directoryClient.js +0 -115
- package/src/gep/envFingerprint.js +0 -1
- package/src/gep/epigenetics.js +0 -1
- package/src/gep/execBridge.js +0 -1
- package/src/gep/executionTrace.js +0 -291
- package/src/gep/explore.js +0 -1
- package/src/gep/featureFlags.js +0 -121
- package/src/gep/gitOps.js +0 -265
- package/src/gep/hash.js +0 -1
- package/src/gep/hostErrorClassifier.js +0 -34
- package/src/gep/hubFetch.js +0 -1
- package/src/gep/hubReview.js +0 -1
- package/src/gep/hubSearch.js +0 -1
- package/src/gep/hubVerify.js +0 -1
- package/src/gep/idleScheduler.js +0 -400
- package/src/gep/issueReporter.js +0 -416
- package/src/gep/learningSignals.js +0 -1
- package/src/gep/llmReview.js +0 -92
- package/src/gep/localStateAwareness.js +0 -243
- package/src/gep/mailboxTransport.js +0 -119
- package/src/gep/memoryGraph.js +0 -1
- package/src/gep/memoryGraphAdapter.js +0 -1
- package/src/gep/mutation.js +0 -1
- package/src/gep/narrativeMemory.js +0 -1
- package/src/gep/oauthLogin.js +0 -181
- package/src/gep/openPRRegistry.js +0 -1
- package/src/gep/paths.js +0 -522
- package/src/gep/personality.js +0 -1
- package/src/gep/policyCheck.js +0 -1
- package/src/gep/portable.js +0 -103
- package/src/gep/privacyClient.js +0 -235
- package/src/gep/prompt.js +0 -1
- package/src/gep/questionGenerator.js +0 -518
- package/src/gep/recallInject.js +0 -1
- package/src/gep/recallVerifier.js +0 -1
- package/src/gep/reflection.js +0 -1
- package/src/gep/sanitize.js +0 -264
- package/src/gep/savingsCore.js +0 -1
- package/src/gep/schemas/capsule.js +0 -170
- package/src/gep/schemas/gene.js +0 -154
- package/src/gep/schemas/index.js +0 -8
- package/src/gep/schemas/protocol.js +0 -51
- package/src/gep/schemas/task.js +0 -74
- package/src/gep/selector.js +0 -1
- package/src/gep/selfPR.js +0 -469
- package/src/gep/signals.js +0 -776
- package/src/gep/skill2gep.js +0 -1056
- package/src/gep/skill2gepAudit.js +0 -303
- package/src/gep/skill2recipes.js +0 -511
- package/src/gep/skillDistiller.js +0 -1
- package/src/gep/skillPublisher.js +0 -358
- package/src/gep/solidify.js +0 -1
- package/src/gep/strategy.js +0 -1
- package/src/gep/taskReceiver.js +0 -575
- package/src/gep/tokenSavings.js +0 -1
- package/src/gep/trajectoryExport.js +0 -1
- package/src/gep/validationReport.js +0 -55
- package/src/gep/validator/index.js +0 -411
- package/src/gep/validator/reporter.js +0 -210
- package/src/gep/validator/sandboxExecutor.js +0 -480
- package/src/gep/validator/stakeBootstrap.js +0 -357
- package/src/gep/workspaceKeychain.js +0 -1
- package/src/ops/cleanup.js +0 -80
- package/src/ops/commentary.js +0 -60
- package/src/ops/health_check.js +0 -104
- package/src/ops/index.js +0 -11
- package/src/ops/innovation.js +0 -67
- package/src/ops/lifecycle.js +0 -798
- package/src/ops/self_repair.js +0 -76
- package/src/ops/skills_monitor.js +0 -147
- package/src/ops/trigger.js +0 -33
- package/src/proxy/clientSettings.js +0 -405
- package/src/proxy/envelope.js +0 -59
- package/src/proxy/extensions/dmHandler.js +0 -45
- package/src/proxy/extensions/sessionHandler.js +0 -141
- package/src/proxy/extensions/skillUpdater.js +0 -64
- package/src/proxy/extensions/traceControl.js +0 -1
- package/src/proxy/index.js +0 -1395
- package/src/proxy/inject.js +0 -1
- package/src/proxy/lifecycle/manager.js +0 -1568
- package/src/proxy/mailbox/state.js +0 -207
- package/src/proxy/mailbox/store.js +0 -590
- package/src/proxy/router/cache_passthrough.js +0 -26
- package/src/proxy/router/features.js +0 -84
- package/src/proxy/router/gemini_route.js +0 -154
- package/src/proxy/router/messages_route.js +0 -535
- package/src/proxy/router/model_router.js +0 -113
- package/src/proxy/router/models_route.js +0 -52
- package/src/proxy/router/ollama_route.js +0 -103
- package/src/proxy/router/responses_route.js +0 -170
- package/src/proxy/router/vertex_route.js +0 -110
- package/src/proxy/server/http.js +0 -363
- package/src/proxy/server/routes.js +0 -558
- package/src/proxy/server/settings.js +0 -115
- package/src/proxy/sync/engine.js +0 -179
- package/src/proxy/sync/inbound.js +0 -211
- package/src/proxy/sync/outbound.js +0 -320
- package/src/proxy/task/monitor.js +0 -131
- package/src/proxy/trace/extractor.js +0 -1
- package/src/proxy/trace/usage.js +0 -1
- package/src/webui/client/clientJs/assets.js +0 -111
- package/src/webui/client/clientJs/bootstrap.js +0 -92
- package/src/webui/client/clientJs/common.js +0 -77
- package/src/webui/client/clientJs/i18n.js +0 -366
- package/src/webui/client/clientJs/index.js +0 -35
- package/src/webui/client/clientJs/interactions.js +0 -351
- package/src/webui/client/clientJs/overview.js +0 -152
- package/src/webui/client/clientJs/personality.js +0 -285
- package/src/webui/client/clientJs/pipelines.js +0 -330
- package/src/webui/client/indexHtml.js +0 -221
- package/src/webui/client/static.js +0 -23
- package/src/webui/client/stylesCss.js +0 -639
- package/src/webui/client/vendor/README.md +0 -15
- package/src/webui/client/vendor/echarts.min.js +0 -45
- package/src/webui/index.js +0 -14
- package/src/webui/observer/assets.js +0 -146
- package/src/webui/observer/index.js +0 -37
- package/src/webui/observer/interactions.js +0 -127
- package/src/webui/observer/jsonl.js +0 -75
- package/src/webui/observer/paths.js +0 -46
- package/src/webui/observer/personality.js +0 -43
- package/src/webui/observer/pipelineEvents.js +0 -58
- package/src/webui/observer/redact.js +0 -63
- package/src/webui/observer/runs.js +0 -356
- package/src/webui/observer/safety.js +0 -57
- package/src/webui/observer/skills.js +0 -70
- package/src/webui/observer/status.js +0 -71
- package/src/webui/server/http.js +0 -138
- 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 };
|