@evomap/evolver 1.89.3 → 1.89.5
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 +8 -0
- package/index.js +116 -7
- package/package.json +1 -1
- package/src/adapters/scripts/_runtimePaths.js +1 -0
- package/src/adapters/scripts/evolver-session-end.js +1 -0
- package/src/adapters/scripts/evolver-session-start.js +1 -0
- package/src/config.js +23 -0
- package/src/evolve/guards.js +1 -1
- package/src/evolve/pipeline/collect.js +1 -1
- package/src/evolve/pipeline/dispatch.js +1 -1
- package/src/evolve/pipeline/enrich.js +1 -1
- package/src/evolve/pipeline/hub.js +1 -1
- package/src/evolve/pipeline/select.js +1 -1
- package/src/evolve/pipeline/signals.js +1 -1
- package/src/evolve/utils.js +1 -1
- package/src/evolve.js +1 -1
- package/src/experiment/agentRunner.js +229 -0
- package/src/experiment/cli.js +159 -0
- package/src/experiment/comparison.js +233 -0
- package/src/experiment/metrics.js +75 -0
- package/src/forceUpdate.js +147 -59
- package/src/gep/a2aProtocol.js +1 -1
- package/src/gep/antiAbuseTelemetry.js +1 -0
- package/src/gep/autoDistillConv.js +1 -1
- package/src/gep/autoDistillLlm.js +1 -1
- package/src/gep/candidateEval.js +1 -1
- package/src/gep/candidates.js +1 -1
- package/src/gep/contentHash.js +1 -1
- package/src/gep/conversationSniffer.js +1 -1
- package/src/gep/crypto.js +1 -1
- package/src/gep/curriculum.js +1 -1
- package/src/gep/deviceId.js +1 -1
- package/src/gep/envFingerprint.js +1 -1
- package/src/gep/epigenetics.js +1 -1
- package/src/gep/execBridge.js +1 -1
- package/src/gep/explore.js +1 -1
- package/src/gep/hash.js +1 -1
- package/src/gep/hubFetch.js +1 -1
- package/src/gep/hubReview.js +1 -1
- package/src/gep/hubSearch.js +1 -1
- package/src/gep/hubVerify.js +1 -1
- package/src/gep/idleScheduler.js +6 -1
- package/src/gep/learningSignals.js +1 -1
- package/src/gep/memoryGraph.js +1 -1
- package/src/gep/memoryGraphAdapter.js +1 -1
- package/src/gep/mutation.js +1 -1
- package/src/gep/narrativeMemory.js +1 -1
- package/src/gep/openPRRegistry.js +1 -1
- package/src/gep/personality.js +1 -1
- package/src/gep/policyCheck.js +1 -1
- package/src/gep/prompt.js +1 -1
- package/src/gep/recallInject.js +1 -1
- package/src/gep/recallVerifier.js +1 -1
- package/src/gep/reflection.js +1 -1
- package/src/gep/sanitize.js +9 -0
- package/src/gep/selector.js +1 -1
- package/src/gep/skillDistiller.js +1 -1
- package/src/gep/solidify.js +1 -1
- package/src/gep/strategy.js +1 -1
- package/src/gep/tokenSavings.js +1 -1
- package/src/gep/validator/sandboxExecutor.js +29 -1
- package/src/gep/workspaceKeychain.js +1 -1
- package/src/ops/lifecycle.js +17 -4
- package/src/proxy/extensions/traceControl.js +1 -1
- package/src/proxy/index.js +216 -2
- package/src/proxy/inject.js +1 -1
- package/src/proxy/lifecycle/manager.js +31 -0
- package/src/proxy/mailbox/store.js +31 -7
- package/src/proxy/router/messages_route.js +5 -2
- package/src/proxy/router/responses_route.js +157 -0
- package/src/proxy/server/http.js +13 -4
- package/src/proxy/server/routes.js +11 -1
- package/src/proxy/sync/engine.js +7 -1
- package/src/proxy/sync/outbound.js +32 -4
- package/src/proxy/trace/extractor.js +1 -1
- package/src/proxy/trace/usage.js +1 -1
package/README.md
CHANGED
|
@@ -146,6 +146,14 @@ how `setup-hooks --platform=codex` wires Evolver in), but it does **not**
|
|
|
146
146
|
emit a session transcript file the way Cursor / Claude Code / opencode do.
|
|
147
147
|
That means `evolver --review` cannot read raw session logs on Codex.
|
|
148
148
|
|
|
149
|
+
`setup-hooks --platform=codex` is lifecycle integration only; it does not route
|
|
150
|
+
Codex model requests through Evolver Proxy. To route Codex model traffic, run
|
|
151
|
+
Evolver Proxy and configure Codex with a user-level OpenAI Responses-compatible
|
|
152
|
+
custom provider whose `base_url` points at the proxy's `/v1` endpoint and whose
|
|
153
|
+
command-backed auth runs `evolver proxy-token` or the absolute `node index.js
|
|
154
|
+
proxy-token --settings ...` helper emitted by `scripts/internal-proxy-env.sh
|
|
155
|
+
--codex-config` from a source checkout.
|
|
156
|
+
|
|
149
157
|
Evolver compensates by reading, in order:
|
|
150
158
|
|
|
151
159
|
1. `MEMORY.md` / `USER.md` in the workspace root (if you maintain them);
|
package/index.js
CHANGED
|
@@ -1,4 +1,65 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
function _printProxyTokenUsage(out = process.stderr) {
|
|
3
|
+
out.write('Usage: node index.js proxy-token [--settings FILE]\n');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function _readProxyTokenFromSettingsFile(fs, settingsFile) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
|
|
9
|
+
return parsed && parsed.proxy && typeof parsed.proxy.token === 'string'
|
|
10
|
+
? parsed.proxy.token
|
|
11
|
+
: '';
|
|
12
|
+
} catch {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// `proxy-token` is a credential helper for Codex. Handle it before loading any
|
|
18
|
+
// project .env so a workspace cannot change EVOLVER_SETTINGS_DIR or other local
|
|
19
|
+
// state used to find the proxy token.
|
|
20
|
+
if (process.argv[2] === 'proxy-token') {
|
|
21
|
+
try {
|
|
22
|
+
const _fs = require('fs');
|
|
23
|
+
const _os = require('os');
|
|
24
|
+
const _path = require('path');
|
|
25
|
+
let settingsFile = '';
|
|
26
|
+
for (let i = 3; i < process.argv.length; i++) {
|
|
27
|
+
const arg = process.argv[i];
|
|
28
|
+
if (arg === '-h' || arg === '--help') {
|
|
29
|
+
_printProxyTokenUsage(process.stdout);
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
if (arg === '--settings') {
|
|
33
|
+
if (!process.argv[i + 1]) {
|
|
34
|
+
_printProxyTokenUsage();
|
|
35
|
+
console.error('[proxy-token] missing value for --settings');
|
|
36
|
+
process.exit(2);
|
|
37
|
+
}
|
|
38
|
+
settingsFile = process.argv[i + 1];
|
|
39
|
+
i++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
_printProxyTokenUsage();
|
|
43
|
+
console.error('[proxy-token] unknown argument');
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
const defaultSettingsFile = _path.join(
|
|
47
|
+
process.env.EVOLVER_SETTINGS_DIR || _path.join(_os.homedir(), '.evolver'),
|
|
48
|
+
'settings.json',
|
|
49
|
+
);
|
|
50
|
+
const token = _readProxyTokenFromSettingsFile(_fs, settingsFile || defaultSettingsFile);
|
|
51
|
+
if (!token) {
|
|
52
|
+
console.error('[proxy-token] no active proxy token found; start evolver with EVOMAP_PROXY=1 first');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write(token + '\n');
|
|
56
|
+
process.exit(0);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error('[proxy-token] Failed:', e && e.message || e);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
2
63
|
// Load .env BEFORE any internal require so that a2aProtocol and ATP
|
|
3
64
|
// modules see A2A_NODE_SECRET / A2A_NODE_ID / A2A_HUB_URL at first
|
|
4
65
|
// access and never fall back to a stale persisted/cached secret.
|
|
@@ -625,7 +686,7 @@ async function main() {
|
|
|
625
686
|
// failure mode obvious.
|
|
626
687
|
try {
|
|
627
688
|
const { execSync } = require('child_process');
|
|
628
|
-
execSync('git --version', { stdio: 'ignore', timeout: 5000 });
|
|
689
|
+
execSync('git --version', { stdio: 'ignore', timeout: 5000, windowsHide: true });
|
|
629
690
|
} catch (_gitErr) {
|
|
630
691
|
console.error('');
|
|
631
692
|
console.error('[Preflight] Could not run "git --version". Evolver requires git to be installed and available on PATH.');
|
|
@@ -1166,6 +1227,24 @@ async function main() {
|
|
|
1166
1227
|
const { registerMailboxTransport } = require('./src/gep/mailboxTransport');
|
|
1167
1228
|
registerMailboxTransport();
|
|
1168
1229
|
process.env.A2A_TRANSPORT = 'mailbox';
|
|
1230
|
+
try {
|
|
1231
|
+
const a2a = require('./src/gep/a2aProtocol');
|
|
1232
|
+
a2a.startSystemdNotifyWatchdog(function () {
|
|
1233
|
+
try {
|
|
1234
|
+
const proxy = proxyInfo && proxyInfo.proxy;
|
|
1235
|
+
const lifecycle = proxy && proxy.lifecycle;
|
|
1236
|
+
if (lifecycle && typeof lifecycle.getHeartbeatStats === 'function') {
|
|
1237
|
+
const stats = lifecycle.getHeartbeatStats();
|
|
1238
|
+
// Hub-backed lifecycle stats are authoritative even when stopped;
|
|
1239
|
+
// systemd should starve and restart instead of seeing a false ping.
|
|
1240
|
+
if (stats && (stats.running || proxy.hubUrl)) return stats;
|
|
1241
|
+
}
|
|
1242
|
+
} catch (_) {}
|
|
1243
|
+
return { running: true, consecutiveFailures: 0, lastTickAt: Date.now() };
|
|
1244
|
+
});
|
|
1245
|
+
} catch (sdErr) {
|
|
1246
|
+
console.warn('[Heartbeat] systemd notify/watchdog setup failed: ' + (sdErr && sdErr.message || sdErr));
|
|
1247
|
+
}
|
|
1169
1248
|
} else {
|
|
1170
1249
|
const a2a = require('./src/gep/a2aProtocol');
|
|
1171
1250
|
try { a2a.startHeartbeat(); }
|
|
@@ -1825,9 +1904,9 @@ async function main() {
|
|
|
1825
1904
|
const repoRoot = getRepoRoot();
|
|
1826
1905
|
let diff = '';
|
|
1827
1906
|
try {
|
|
1828
|
-
const unstaged = execSync('git diff', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1829
|
-
const staged = execSync('git diff --cached', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1830
|
-
const untracked = execSync('git ls-files --others --exclude-standard', { cwd: repoRoot, encoding: 'utf8', timeout: 10000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1907
|
+
const unstaged = execSync('git diff', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1908
|
+
const staged = execSync('git diff --cached', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1909
|
+
const untracked = execSync('git ls-files --others --exclude-standard', { cwd: repoRoot, encoding: 'utf8', timeout: 10000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1831
1910
|
if (staged) diff += '=== Staged Changes ===\n' + staged + '\n\n';
|
|
1832
1911
|
if (unstaged) diff += '=== Unstaged Changes ===\n' + unstaged + '\n\n';
|
|
1833
1912
|
if (untracked) diff += '=== Untracked Files ===\n' + untracked + '\n';
|
|
@@ -1909,13 +1988,13 @@ async function main() {
|
|
|
1909
1988
|
} else if (args.includes('--reject')) {
|
|
1910
1989
|
console.log('\n[Review] Rejected. Rolling back changes...');
|
|
1911
1990
|
try {
|
|
1912
|
-
execSync('git checkout -- .', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER });
|
|
1991
|
+
execSync('git checkout -- .', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true });
|
|
1913
1992
|
// Preserve user state on reject: .env files, node_modules, runtime
|
|
1914
1993
|
// PID files, and a dedicated workspace/ dir (if one exists) MUST NOT
|
|
1915
1994
|
// be wiped by an automated rollback. Users have reported losing
|
|
1916
1995
|
// secrets and runtime caches to an aggressive git clean.
|
|
1917
1996
|
execSync('git clean -fd -e node_modules -e workspace -e .env -e ".env.*" -e "*.pid"', {
|
|
1918
|
-
cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER,
|
|
1997
|
+
cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true,
|
|
1919
1998
|
});
|
|
1920
1999
|
const evolDir = getEvolutionDir();
|
|
1921
2000
|
const sp = path.join(evolDir, 'evolution_solidify_state.json');
|
|
@@ -2922,10 +3001,40 @@ async function main() {
|
|
|
2922
3001
|
process.exit(1);
|
|
2923
3002
|
}
|
|
2924
3003
|
|
|
3004
|
+
} else if (command === 'experiment') {
|
|
3005
|
+
// Comparative experiment runner: run the SAME task twice -- a baseline arm
|
|
3006
|
+
// and a variant arm that reuses a gene's strategy -- via a headless agent
|
|
3007
|
+
// CLI, collect duration/rounds/tokens/pass-rate, and print a comparison
|
|
3008
|
+
// JSON to stdout. Consumed by EvoMap Desktop's ExperimentsAPI.Run, which
|
|
3009
|
+
// spawns `node index.js experiment --request-file=<json>` and parses stdout.
|
|
3010
|
+
try {
|
|
3011
|
+
const expCli = require('./src/experiment/cli');
|
|
3012
|
+
const parsed = expCli.parseExperimentArgs(args.slice(1));
|
|
3013
|
+
if (!parsed.ok) {
|
|
3014
|
+
console.error('[Experiment] ' + parsed.error);
|
|
3015
|
+
console.error(expCli.printExperimentUsage());
|
|
3016
|
+
process.exit(2);
|
|
3017
|
+
}
|
|
3018
|
+
const res = await expCli.runExperiment(parsed.opts, { err: (...a) => console.error(...a) });
|
|
3019
|
+
// stdout carries ONLY the structured JSON so the Go caller can JSON.parse
|
|
3020
|
+
// it without log contamination; all logging above went to stderr. res.data
|
|
3021
|
+
// is already secret-redacted by runExperiment (sanitizePayload).
|
|
3022
|
+
if (res && res.data) process.stdout.write(JSON.stringify(res.data) + '\n');
|
|
3023
|
+
process.exit(res && typeof res.exitCode === 'number' ? res.exitCode : (res && res.ok ? 0 : 1));
|
|
3024
|
+
} catch (expErr) {
|
|
3025
|
+
console.error('[Experiment] CLI error:', expErr && expErr.message || expErr);
|
|
3026
|
+
process.exit(1);
|
|
3027
|
+
}
|
|
3028
|
+
|
|
2925
3029
|
} else {
|
|
2926
|
-
console.log(`Usage: node index.js [run|/evolve|login|logout|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|recipe|buy|orders|verify|atp|atp-complete] [--loop]
|
|
3030
|
+
console.log(`Usage: node index.js [run|/evolve|login|logout|proxy-token|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|recipe|buy|orders|verify|atp|atp-complete|experiment] [--loop]
|
|
2927
3031
|
- login (authorize this device via the hub, gh-auth-login style; stores an OAuth token used instead of node_secret)
|
|
2928
3032
|
- logout (remove the stored OAuth token)
|
|
3033
|
+
- proxy-token (print the local proxy bearer token for command-backed client auth)
|
|
3034
|
+
- experiment flags:
|
|
3035
|
+
- --task="..." --metric="..." (required; same task, baseline vs variant)
|
|
3036
|
+
- --gene=<geneId> (variant arm reuses this gene's strategy)
|
|
3037
|
+
- --baseline="..." --variant="..." --validation="c1;;c2" --request-file=<json>
|
|
2929
3038
|
- recipe flags:
|
|
2930
3039
|
- build --title="..." --genes=<asset_id,...> [--description] [--price=N] [--publish]
|
|
2931
3040
|
(builds a DRAFT DNA blueprint; --publish is opt-in)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.89.
|
|
3
|
+
"version": "1.89.5",
|
|
4
4
|
"description": "A GEP-powered self-evolution engine for AI agents. Features automated log analysis and Genome Evolution Protocol (GEP) for auditable, reusable evolution assets.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/src/config.js
CHANGED
|
@@ -202,6 +202,26 @@ function reuseAttributionMode() {
|
|
|
202
202
|
return v === 'shadow' ? 'shadow' : 'off';
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
// --- Anti-abuse telemetry (privacy-preserving heartbeat summary) ---
|
|
206
|
+
// Enabled by default. In heartbeat mode, clients attach a small
|
|
207
|
+
// `meta.anti_abuse` envelope with low-sensitive hashes, source-confidence
|
|
208
|
+
// labels, and explicit placeholders for data that must be observed by Hub
|
|
209
|
+
// services instead of trusted from the client.
|
|
210
|
+
const ANTI_ABUSE_TELEMETRY_MODE = envStr('EVOLVER_ANTI_ABUSE_TELEMETRY', 'heartbeat');
|
|
211
|
+
function antiAbuseTelemetryMode() {
|
|
212
|
+
const raw = process.env.EVOLVER_ANTI_ABUSE_TELEMETRY;
|
|
213
|
+
const v = String(raw == null ? '' : raw).toLowerCase().trim();
|
|
214
|
+
// Empty / whitespace-only counts as UNSET (same as envStr's '' -> fallback
|
|
215
|
+
// above): a blank `EVOLVER_ANTI_ABUSE_TELEMETRY=` line in a .env file must
|
|
216
|
+
// not silently disable the documented default-on behavior. Opt-out is
|
|
217
|
+
// explicit only.
|
|
218
|
+
if (v === '') return 'heartbeat';
|
|
219
|
+
if (v === '0' || v === 'false' || v === 'no' || v === 'off') return 'off';
|
|
220
|
+
return (v === '1' || v === 'true' || v === 'yes' || v === 'on' || v === 'heartbeat')
|
|
221
|
+
? 'heartbeat'
|
|
222
|
+
: 'off';
|
|
223
|
+
}
|
|
224
|
+
|
|
205
225
|
// --- Validator mode (opt-out) ---
|
|
206
226
|
// Node role: the evolver periodically fetches assigned validation tasks from
|
|
207
227
|
// the Hub, runs the commands in an isolated sandbox, and submits
|
|
@@ -286,6 +306,9 @@ module.exports = {
|
|
|
286
306
|
// Reuse attribution (P4-a Slice A)
|
|
287
307
|
REUSE_ATTRIBUTION_MODE,
|
|
288
308
|
reuseAttributionMode,
|
|
309
|
+
// Anti-abuse telemetry
|
|
310
|
+
ANTI_ABUSE_TELEMETRY_MODE,
|
|
311
|
+
antiAbuseTelemetryMode,
|
|
289
312
|
// Validator (opt-in role)
|
|
290
313
|
VALIDATOR_ENABLED,
|
|
291
314
|
VALIDATOR_STAKE_AMOUNT,
|