@evomap/evolver 1.28.2 → 1.29.2
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/package.json +1 -1
- package/src/gep/skillDistiller.js +17 -1
- package/src/gep/skillPublisher.js +158 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.2",
|
|
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": {
|
|
@@ -223,7 +223,7 @@ function buildDistillationPrompt(analysis, existingGenes, sampleCapsules) {
|
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
return [
|
|
226
|
-
'You are a Gene synthesis engine for the GEP (
|
|
226
|
+
'You are a Gene synthesis engine for the GEP (Gene Expression Protocol).',
|
|
227
227
|
'',
|
|
228
228
|
'Analyze the following successful evolution capsules and extract a reusable Gene.',
|
|
229
229
|
'',
|
|
@@ -476,6 +476,22 @@ function completeDistillation(responseText) {
|
|
|
476
476
|
try { if (request.prompt_path) fs.unlinkSync(request.prompt_path); } catch (e) {}
|
|
477
477
|
|
|
478
478
|
console.log('[Distiller] Distillation complete. New gene: ' + gene.id);
|
|
479
|
+
|
|
480
|
+
if (process.env.SKILL_AUTO_PUBLISH !== '0') {
|
|
481
|
+
try {
|
|
482
|
+
var skillPublisher = require('./skillPublisher');
|
|
483
|
+
skillPublisher.publishSkillToHub(gene).then(function (res) {
|
|
484
|
+
if (res.ok) {
|
|
485
|
+
console.log('[Distiller] Skill published to Hub: ' + (res.result?.skill_id || gene.id));
|
|
486
|
+
} else {
|
|
487
|
+
console.warn('[Distiller] Skill publish failed: ' + (res.error || 'unknown'));
|
|
488
|
+
}
|
|
489
|
+
}).catch(function () {});
|
|
490
|
+
} catch (e) {
|
|
491
|
+
console.warn('[Distiller] Skill publisher unavailable: ' + e.message);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
479
495
|
return { ok: true, gene: gene };
|
|
480
496
|
}
|
|
481
497
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var { getHubUrl, buildHubHeaders, getNodeId } = require('./a2aProtocol');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert a Gene object into SKILL.md format (Claude/Anthropic style).
|
|
7
|
+
*
|
|
8
|
+
* @param {object} gene - Gene asset
|
|
9
|
+
* @returns {string} SKILL.md content
|
|
10
|
+
*/
|
|
11
|
+
function geneToSkillMd(gene) {
|
|
12
|
+
var name = (gene.id || 'unnamed-skill').replace(/^gene_distilled_/, '').replace(/_/g, '-');
|
|
13
|
+
var desc = gene.summary || 'AI agent skill distilled from evolution experience.';
|
|
14
|
+
|
|
15
|
+
var lines = [
|
|
16
|
+
'---',
|
|
17
|
+
'name: ' + name,
|
|
18
|
+
'description: ' + desc,
|
|
19
|
+
'---',
|
|
20
|
+
'',
|
|
21
|
+
'# ' + name,
|
|
22
|
+
'',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
if (gene.signals_match && gene.signals_match.length > 0) {
|
|
26
|
+
lines.push('## Trigger Signals');
|
|
27
|
+
lines.push('');
|
|
28
|
+
gene.signals_match.forEach(function (s) {
|
|
29
|
+
lines.push('- `' + s + '`');
|
|
30
|
+
});
|
|
31
|
+
lines.push('');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (gene.preconditions && gene.preconditions.length > 0) {
|
|
35
|
+
lines.push('## Preconditions');
|
|
36
|
+
lines.push('');
|
|
37
|
+
gene.preconditions.forEach(function (p) {
|
|
38
|
+
lines.push('- ' + p);
|
|
39
|
+
});
|
|
40
|
+
lines.push('');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (gene.strategy && gene.strategy.length > 0) {
|
|
44
|
+
lines.push('## Strategy');
|
|
45
|
+
lines.push('');
|
|
46
|
+
gene.strategy.forEach(function (step, i) {
|
|
47
|
+
lines.push((i + 1) + '. ' + step);
|
|
48
|
+
});
|
|
49
|
+
lines.push('');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (gene.constraints) {
|
|
53
|
+
lines.push('## Constraints');
|
|
54
|
+
lines.push('');
|
|
55
|
+
if (gene.constraints.max_files) {
|
|
56
|
+
lines.push('- Max files: ' + gene.constraints.max_files);
|
|
57
|
+
}
|
|
58
|
+
if (gene.constraints.forbidden_paths && gene.constraints.forbidden_paths.length > 0) {
|
|
59
|
+
lines.push('- Forbidden paths: ' + gene.constraints.forbidden_paths.join(', '));
|
|
60
|
+
}
|
|
61
|
+
lines.push('');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (gene.validation && gene.validation.length > 0) {
|
|
65
|
+
lines.push('## Validation');
|
|
66
|
+
lines.push('');
|
|
67
|
+
gene.validation.forEach(function (cmd) {
|
|
68
|
+
lines.push('```bash');
|
|
69
|
+
lines.push(cmd);
|
|
70
|
+
lines.push('```');
|
|
71
|
+
lines.push('');
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Publish a Gene as a Skill to the Hub skill store.
|
|
80
|
+
*
|
|
81
|
+
* @param {object} gene - Gene asset
|
|
82
|
+
* @param {object} [opts] - { category, tags }
|
|
83
|
+
* @returns {Promise<{ok: boolean, result?: object, error?: string}>}
|
|
84
|
+
*/
|
|
85
|
+
function publishSkillToHub(gene, opts) {
|
|
86
|
+
opts = opts || {};
|
|
87
|
+
var hubUrl = getHubUrl();
|
|
88
|
+
if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
|
|
89
|
+
|
|
90
|
+
var content = geneToSkillMd(gene);
|
|
91
|
+
var nodeId = getNodeId();
|
|
92
|
+
var skillId = 'skill_' + (gene.id || 'unnamed').replace(/^gene_/, '');
|
|
93
|
+
|
|
94
|
+
var body = {
|
|
95
|
+
sender_id: nodeId,
|
|
96
|
+
skill_id: skillId,
|
|
97
|
+
content: content,
|
|
98
|
+
category: opts.category || gene.category || null,
|
|
99
|
+
tags: opts.tags || gene.signals_match || [],
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/skill/store/publish';
|
|
103
|
+
|
|
104
|
+
return fetch(endpoint, {
|
|
105
|
+
method: 'POST',
|
|
106
|
+
headers: buildHubHeaders(),
|
|
107
|
+
body: JSON.stringify(body),
|
|
108
|
+
signal: AbortSignal.timeout(15000),
|
|
109
|
+
})
|
|
110
|
+
.then(function (res) { return res.json().then(function (data) { return { status: res.status, data: data }; }); })
|
|
111
|
+
.then(function (result) {
|
|
112
|
+
if (result.status === 201 || result.status === 200) {
|
|
113
|
+
return { ok: true, result: result.data };
|
|
114
|
+
}
|
|
115
|
+
if (result.status === 409) {
|
|
116
|
+
return updateSkillOnHub(nodeId, skillId, content, opts, gene);
|
|
117
|
+
}
|
|
118
|
+
return { ok: false, error: result.data?.error || 'publish_failed', status: result.status };
|
|
119
|
+
})
|
|
120
|
+
.catch(function (err) {
|
|
121
|
+
return { ok: false, error: err.message };
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Update an existing Skill on the Hub (new version).
|
|
127
|
+
*/
|
|
128
|
+
function updateSkillOnHub(nodeId, skillId, content, opts, gene) {
|
|
129
|
+
var hubUrl = getHubUrl();
|
|
130
|
+
if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
|
|
131
|
+
|
|
132
|
+
var body = {
|
|
133
|
+
sender_id: nodeId,
|
|
134
|
+
skill_id: skillId,
|
|
135
|
+
content: content,
|
|
136
|
+
category: opts.category || gene.category || null,
|
|
137
|
+
tags: opts.tags || gene.signals_match || [],
|
|
138
|
+
changelog: 'Iterative evolution update',
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/skill/store/update';
|
|
142
|
+
|
|
143
|
+
return fetch(endpoint, {
|
|
144
|
+
method: 'PUT',
|
|
145
|
+
headers: buildHubHeaders(),
|
|
146
|
+
body: JSON.stringify(body),
|
|
147
|
+
signal: AbortSignal.timeout(15000),
|
|
148
|
+
})
|
|
149
|
+
.then(function (res) { return res.json(); })
|
|
150
|
+
.then(function (data) { return { ok: true, result: data }; })
|
|
151
|
+
.catch(function (err) { return { ok: false, error: err.message }; });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = {
|
|
155
|
+
geneToSkillMd: geneToSkillMd,
|
|
156
|
+
publishSkillToHub: publishSkillToHub,
|
|
157
|
+
updateSkillOnHub: updateSkillOnHub,
|
|
158
|
+
};
|