Self-Modifying Agent

advanced20 minself-modifying.ts

The agent is asked for something none of its tools can do. It should notice the gap and generate a sandboxed tool, within safety limits.

What it shows

  • Find missing capabilities with GapAnalyzer
  • Check changes against constraints with ModificationValidator
  • Run SelfModifyingAgent with tool generation and meta-reasoning

The code

self-modifying.ts
import { Agent, createLLMBackend, tool } from '@cogitator-ai/core';
import {
  DEFAULT_CAPABILITY_CONSTRAINTS,
  DEFAULT_RESOURCE_CONSTRAINTS,
  DEFAULT_SAFETY_CONSTRAINTS,
  GapAnalyzer,
  ModificationValidator,
  SelfModifyingAgent,
} from '@cogitator-ai/self-modifying';
import { z } from 'zod';

const apiKey = process.env.GOOGLE_API_KEY;
if (!apiKey) throw new Error('Set GOOGLE_API_KEY');

const llm = createLLMBackend('google', { providers: { google: { apiKey } } });

const fetchWeather = tool({
  name: 'fetch_weather',
  description: 'Fetch current weather for a city',
  parameters: z.object({ city: z.string() }),
  execute: async ({ city }) => ({ city, temperature: 22, condition: 'partly cloudy', windKph: 18 }),
});

const agent = new Agent({
  name: 'adaptive-assistant',
  model: 'google/gemini-3.5-flash-lite',
  instructions: 'You fetch weather data. When you lack a tool for a task, say what is missing.',
  tools: [fetchWeather],
  temperature: 0.3,
  maxIterations: 5,
});

const toolGeneration = {
  enabled: true,
  autoGenerate: true,
  maxToolsPerSession: 2,
  minConfidenceForGeneration: 0.6,
  maxIterationsPerTool: 2,
  requireLLMValidation: false,
  sandboxConfig: {
    enabled: true,
    maxExecutionTime: 5000,
    maxMemory: 50 * 1024 * 1024,
    allowedModules: [],
    isolationLevel: 'strict' as const,
  },
};

const gaps = await new GapAnalyzer({ llm, model: 'gemini-3.5-flash-lite', config: toolGeneration }).analyze(
  'Calculate the wind chill for Tokyo and convert it to Fahrenheit',
  [fetchWeather]
);
for (const gap of gaps.gaps) {
  console.log(`missing: ${gap.suggestedToolName} — ${gap.description} (${(gap.confidence * 100).toFixed(0)}%)`);
}

const validator = new ModificationValidator({
  constraints: {
    safety: DEFAULT_SAFETY_CONSTRAINTS,
    capability: DEFAULT_CAPABILITY_CONSTRAINTS,
    resource: DEFAULT_RESOURCE_CONSTRAINTS,
  },
});
const check = await validator.validate({
  type: 'config_change',
  target: 'architecture',
  changes: { temperature: 0.5 },
  reason: 'More creative answers',
});
console.log('modification allowed:', check.valid);

const selfModifying = new SelfModifyingAgent({
  agent,
  llm,
  config: {
    toolGeneration,
    metaReasoning: { enabled: true },
    architectureEvolution: { enabled: false },
    constraints: { enabled: true, autoRollback: true },
  },
});

selfModifying.on('tool_generation_completed', (event) => {
  console.log(`generated ${event.data.name}: ${event.data.success ? 'ok' : 'failed'}`);
});

const result = await selfModifying.run('What is the wind chill in Tokyo, in Fahrenheit?');
console.log(result.output);
console.log('tools generated:', result.toolsGenerated.length, 'adaptations:', result.adaptationsMade.length);

Run it

install · bash
pnpm add @cogitator-ai/core @cogitator-ai/self-modifying zod
EnvironmentGOOGLE_API_KEY
run · bash
GOOGLE_API_KEY=your-key npx tsx self-modifying.ts

Or run the full example from a clone of the repository (keys in .env):

repository · bash
npx tsx examples/advanced/01-self-modifying.ts

Learn more