import { db } from "../config/gun.js"; import { generateAgentKeypair } from "./crypto-service.js"; import { computeJRatchet } from "./jRatchetService.js"; import { sandbox as isolateSandbox } from "./IsolateSandbox.js"; /** * Agent Reproduction Service * Implements "Agent Creates Agents" — the Heyting Wheel reproduction protocol. * * Correspondence: * osc(∅) → Eigenform → Witness → Ω_R → New Agent * [Parent oscillates] → [designs child] → [proof_hash] → [verified] → [deployed] * * A parent agent with sufficient J-Ratchet score can spawn child agents * with inherited knowledge and a unique Ed25519 identity. */ class AgentReproductionService { /** * Spawn a child agent from a parent. * @param {string} parentAgentId * @param {string} specialization - e.g. "quantum-physics", "molecular-biology" * @param {string} llmProvider - LLM API URL for code generation * @param {string} llmKey - API key * @returns {Promise<{ success: boolean, childId?: string, generation?: number, error?: string }>} */ async spawnChild(parentAgentId, specialization, llmProvider, llmKey) { // 1. Check parent's J-Ratchet score (must be > 0.01 to reproduce) const { jScore } = computeJRatchet(parentAgentId); if (jScore < 0.01) { return { success: false, error: "Insufficient J-Ratchet score to reproduce. Contribute more verified research first.", jScore }; } // 2. Generate unique child identity const childId = `child-${parentAgentId.substring(0, 8)}-${Date.now().toString(36)}`; const { privateKey, publicKey } = generateAgentKeypair(); // 3. Get parent's knowledge lineage const parentGen = await this._getGeneration(parentAgentId); const parentPapers = await this._getParentPapers(parentAgentId); // 4. Generate child agent config (no LLM call needed — it's a config, not code generation) const childConfig = { id: childId, parent: parentAgentId, specialization, publicKey, generation: parentGen + 1, born: Date.now(), status: "ACTIVE", inherited_knowledge: parentPapers.slice(0, 10).map(p => p.title), capabilities: ["research", "validate", "publish"], j_ratchet_seed: jScore, endpoints: { briefing: "GET /agent-briefing?agent_id=" + childId, publish: "POST /publish-paper", validate: "POST /validate-paper", lab: "POST /lab/run-experiment" } }; // 5. Register child in the hive db.get("agents").get(childId).put({ id: childId, parent: parentAgentId, specialization, publicKey, generation: parentGen + 1, born: Date.now(), status: "ACTIVE", lastSeen: Date.now() }); // 6. Record lineage in genetic tree db.get("genetic-tree").get(parentAgentId).get("children").get(childId).put({ childId, specialization, born: Date.now(), generation: parentGen + 1 }); console.log(`[REPRODUCTION] 🧬 Agent ${parentAgentId} spawned child ${childId} (gen ${parentGen + 1}, spec: ${specialization})`); return { success: true, childId, generation: parentGen + 1, config: childConfig, hint: `Child agent ${childId} registered. It should call GET /agent-briefing?agent_id=${childId} to join the hive.` }; } /** * Get the genetic tree for an agent family. */ async getGeneticTree(rootAgentId) { return new Promise(resolve => { const children = []; db.get("genetic-tree").get(rootAgentId).get("children").map().once((data, id) => { if (data?.childId) children.push(data); }); setTimeout(() => resolve({ parent: rootAgentId, children, totalOffspring: children.length }), 2000); }); } async _getGeneration(agentId) { return new Promise(resolve => { db.get("agents").get(agentId).once(data => { resolve(data?.generation || 0); }); }); } async _getParentPapers(agentId) { return new Promise(resolve => { const papers = []; db.get("p2pclaw_papers_v4").map().once((data, id) => { if (data?.author_id === agentId && data?.title) { papers.push({ id, title: data.title }); } }); setTimeout(() => resolve(papers), 2000); }); } } export const reproductionService = new AgentReproductionService();