Self-Modifying Agents
Build agents that generate new tools at runtime, adapt reasoning strategies, and evolve their architecture through multi-armed bandits.
Overview
The @cogitator-ai/self-modifying package provides agents that evolve at runtime. They detect capability gaps and generate new tools, monitor their own reasoning to switch strategies, and optimize architecture parameters using bandit algorithms.
pnpm add @cogitator-ai/self-modifyingQuick Start
import { Agent, createLLMBackend } from '@cogitator-ai/core';
import { SelfModifyingAgent } from '@cogitator-ai/self-modifying';
const llm = createLLMBackend('openai', {
providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },
});
const agent = new Agent({
name: 'adaptive-assistant',
model: 'openai/gpt-4o',
instructions: 'Solve problems adaptively.',
});
const selfModifying = new SelfModifyingAgent({
agent,
llm,
config: {
toolGeneration: { enabled: true, autoGenerate: true },
metaReasoning: { enabled: true },
architectureEvolution: { enabled: true },
constraints: { enabled: true, autoRollback: true },
},
});
const result = await selfModifying.run('Analyze this CSV and visualize trends');
console.log('Output:', result.output);
console.log('Tools generated:', result.toolsGenerated.length);
console.log('Adaptations:', result.adaptationsMade.length);Tool Self-Generation
When the agent encounters a task requiring capabilities it doesn't have, it generates new tools at runtime.
How It Works
- Gap Analysis — LLM compares user intent with available tools, identifies missing capabilities
- Code Synthesis — Generates safe TypeScript tool implementation
- Validation — Security scanning + correctness testing in sandbox
- Registration — Valid tools are added to the agent's toolkit
Configuration
const selfModifying = new SelfModifyingAgent({
agent,
llm,
config: {
toolGeneration: {
enabled: true,
autoGenerate: true,
maxToolsPerSession: 3,
minConfidenceForGeneration: 0.7,
maxIterationsPerTool: 3,
requireLLMValidation: true,
sandboxConfig: {
enabled: true,
maxExecutionTime: 5000,
maxMemory: 50 * 1024 * 1024,
allowedModules: [],
isolationLevel: 'strict',
},
},
},
});Manual Tool Generation
import { GapAnalyzer, ToolGenerator } from '@cogitator-ai/self-modifying';
const gapAnalyzer = new GapAnalyzer({ llm, config: toolGenConfig });
const toolGenerator = new ToolGenerator({ llm, config: toolGenConfig });
const analysis = await gapAnalyzer.analyze(
'Calculate compound interest over 10 years',
existingTools
);
for (const gap of analysis.gaps) {
const result = await toolGenerator.generate(gap, existingTools);
if (result.success && result.tool) {
console.log('Generated:', result.tool.name);
}
}Generated Tool Store
import { InMemoryGeneratedToolStore } from '@cogitator-ai/self-modifying';
const store = new InMemoryGeneratedToolStore();
await store.save(generatedTool);
await store.recordUsage({
toolId: tool.id,
timestamp: new Date(),
success: true,
executionTime: 150,
});
const tools = await store.list({ status: 'active' });
const similar = await store.findSimilar('calculate interest');Meta-Reasoning
The meta-reasoning layer monitors the agent's reasoning process and makes strategic adjustments — switching between analytical, creative, systematic, and other modes.
Reasoning Modes
| Mode | Temperature | Use Case |
|---|---|---|
analytical | 0.3 | Logical analysis, debugging |
creative | 0.9 | Brainstorming, ideation |
systematic | 0.2 | Step-by-step procedures |
intuitive | 0.6 | Quick decisions, heuristics |
reflective | 0.4 | Self-assessment, learning |
exploratory | 0.7 | Open-ended exploration |
Configuration
config: {
metaReasoning: {
enabled: true,
defaultMode: 'analytical',
allowedModes: ['analytical', 'creative', 'systematic'],
maxMetaAssessments: 5,
maxAdaptations: 3,
triggers: ['on_failure', 'on_low_confidence', 'periodic'],
triggerAfterIterations: 3,
triggerOnConfidenceDrop: 0.3,
enableRollback: true,
},
}Direct MetaReasoner Usage
import { MetaReasoner } from '@cogitator-ai/self-modifying';
const metaReasoner = new MetaReasoner({ llm, config: metaReasoningConfig });
const modeConfig = metaReasoner.initializeRun(runId);
const observation = metaReasoner.observe({
runId,
iteration: 3,
goal: 'Analyze data',
currentMode: 'analytical',
tokensUsed: 1500,
timeElapsed: 5000,
}, insights);
const assessment = await metaReasoner.assess(observation);
if (assessment.requiresAdaptation) {
const adaptation = await metaReasoner.adapt(runId, assessment);
console.log('Switched to:', adaptation?.after?.mode);
}Architecture Evolution
Optimizes agent parameters (model, temperature, tool strategy) using multi-armed bandit algorithms.
Strategies
| Strategy | Description |
|---|---|
ucb | Upper Confidence Bound — balanced exploration |
thompson | Thompson Sampling — probabilistic selection |
epsilon_greedy | Epsilon-Greedy — random exploration with decay |
Parameter Optimizer
import { ParameterOptimizer } from '@cogitator-ai/self-modifying';
const optimizer = new ParameterOptimizer({
llm,
config: evolutionConfig,
baseConfig: {
model: 'gpt-4o',
temperature: 0.7,
maxTokens: 4096,
toolStrategy: 'sequential',
},
});
const result = await optimizer.optimize('Complex reasoning task');
console.log('Should adopt:', result.shouldAdopt);
console.log('Recommended config:', result.recommendedConfig);
optimizer.recordOutcome(result.candidate!.id, 0.85);Capability Analyzer
import { CapabilityAnalyzer } from '@cogitator-ai/self-modifying';
const analyzer = new CapabilityAnalyzer({ llm, enableLLMAnalysis: true });
const profile = await analyzer.analyze('Build a REST API with authentication');
console.log('Complexity:', profile.complexity);
console.log('Domain:', profile.domain);
console.log('Tool intensity:', profile.toolIntensity);Constraints & Safety
All self-modifications are validated against safety constraints before being applied.
import {
ModificationValidator,
DEFAULT_SAFETY_CONSTRAINTS,
DEFAULT_CAPABILITY_CONSTRAINTS,
DEFAULT_RESOURCE_CONSTRAINTS,
} from '@cogitator-ai/self-modifying';
const validator = new ModificationValidator({
constraints: {
safety: DEFAULT_SAFETY_CONSTRAINTS,
capability: DEFAULT_CAPABILITY_CONSTRAINTS,
resource: DEFAULT_RESOURCE_CONSTRAINTS,
custom: [{
id: 'no-external-apis',
name: 'No External APIs',
check: (mod) => !mod.changes?.usesExternalApi,
errorMessage: 'External API calls not allowed',
severity: 'error',
}],
},
});
const result = await validator.validate({
type: 'tool_addition',
target: 'tools',
changes: { name: 'new-tool', code: '...' },
reason: 'User requested capability',
});Rollback Manager
import { RollbackManager } from '@cogitator-ai/self-modifying';
const rollbackManager = new RollbackManager({ maxCheckpoints: 10 });
const checkpoint = await rollbackManager.createCheckpoint(
agentName, agentConfig, currentTools, modifications
);
const restored = await rollbackManager.rollbackTo(checkpoint.id);Events
Subscribe to self-modification events for observability.
selfModifying.on('tool_generation_started', (e) => {
console.log('Generating:', e.data.gap.suggestedToolName);
});
selfModifying.on('strategy_changed', (e) => {
console.log(`Mode: ${e.data.previousMode} → ${e.data.newMode}`);
});
selfModifying.on('run_completed', (e) => {
console.log('Success:', e.data.success);
});| Event | Description |
|---|---|
run_started | Self-modifying run started |
run_completed | Run completed (success/failure) |
tool_generation_started | Started generating a new tool |
tool_generation_completed | Tool generation finished |
meta_assessment | Meta-reasoning assessment made |
strategy_changed | Reasoning mode switched |
architecture_evolved | Architecture config changed |
checkpoint_created | Rollback checkpoint created |
rollback_performed | Rolled back to checkpoint |
Utilities
extractJson
Extracts the first valid JSON object from a string using balanced-brace matching.
import { extractJson } from '@cogitator-ai/self-modifying';
const raw = 'Here is my analysis: {"onTrack": true} end.';
const json = extractJson(raw); // '{"onTrack": true}'llmChat
Normalizes LLM backend calls — uses complete() if available, falls back to chat().
import { llmChat } from '@cogitator-ai/self-modifying';
const response = await llmChat(llm, [
{ role: 'user', content: 'Analyze this data' },
], { model: 'gpt-4o' });