🤖 Your AI Agent is just a while loop with an API call

Let me prove it

Michał Michalczuk

Senior Fullstack Engineer @ Tektit consulting

tektitconsulting.com

michalczukm.xyz

import { ToolLoopAgent, stepCountIs, tool } from 'ai';
import { mistral } from "@ai-sdk/mistral";
import { z } from 'zod';

const weatherAgent = new ToolLoopAgent({
  model: mistral("mistral-large-3"),
  tools: {
    weather: tool({
      description: 'Get the weather in a location (in Fahrenheit)',
      inputSchema: z.object({
        location: z.string().describe('The location to get the weather for'),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72 + Math.floor(Math.random() * 21) - 10,
      }),
    }),
    convertFahrenheitToCelsius: tool({
      description: 'Convert temperature from Fahrenheit to Celsius',
      inputSchema: z.object({
        temperature: z.number().describe('Temperature in Fahrenheit'),
      }),
      execute: async ({ temperature }) => {
        const celsius = Math.round((temperature - 32) * (5 / 9));
        return { celsius };
      },
    }),
  },
});

const result = await weatherAgent.generate({
  prompt: 'What is the weather in San Francisco in celsius?',
});
  • LLM provider bill for tokens
  • Tools/MCPs/Skills are not called
  • Provider's rate limiting

*Not to mention security, legal, data governance, comliance etc

💵 💶

Michał Michalczuk

michalczukm.xyz

Senior Software Engineer & Consultant
@ Tektit consulting

Talking head @various video formats

Let's create powerful agent from the scratch

*powerful != good or helpful
import readline from 'node:readline';

const SYSTEM_PROMPT = `You are a coding assistant.`;
const messages = [];

const chat = async () => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model: 'mistral-large-2512',
      messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
    }),
  });

  return (await await res.json()).choices[0].message;
};

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

for await (const line of rl) {
  messages.push({ role: 'user', content: line });
  
  const content = await chat();
  messages.push(content);

  process.stdout.write('🤖 ' + content.content + '\n> ');
}
node --env-file=.env src/agent.js
const SYSTEM_PROMPT = `You are a coding assistant with access to bash commands...`;

const messages = [];

const chat = async () => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
	method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model: 'mistral-large-2512',
      messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
      tools: [
        {
          type: 'function',
          function: {
            name: 'sh',
            parameters: {
              type: 'object',
              properties: { command: { type: 'string' } },
            },
          },
        },
      ],
    }),
  });

  return (await await res.json()).choices[0].message;
};

const runTool = (input) => {
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const content = await chat();
    messages.push(content);

    if (!content.tool_calls?.length) {
      process.stdout.write('🤖 ' + content.content + '\n> ');
      break;
    }

    for (const { id, function: { arguments: args } } of content.tool_calls) {
      const { command } = JSON.parse(args);
      messages.push({ role: 'tool', tool_call_id: id, content: runTool(command) });
    }
  }
}
const SYSTEM_PROMPT = `You are a coding assistant with access to bash commands...`;

const messages = [];

const chat = async () => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
	method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model: 'mistral-large-2512',
      messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
      tools: [
        {
          type: 'function',
          function: {
            name: 'sh',
            parameters: {
              type: 'object',
              properties: { command: { type: 'string' } },
            },
          },
        },
      ],
    }),
  });

  return (await await res.json()).choices[0].message;
};

const runTool = (input) => {
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const content = await chat();
    messages.push(content);

    if (!content.tool_calls?.length) {
      process.stdout.write('🤖 ' + content.content + '\n> ');
      break;
    }

    for (const { id, function: { arguments: args } } of content.tool_calls) {
      const { command } = JSON.parse(args);
      messages.push({ role: 'tool', tool_call_id: id, content: runTool(command) });
    }
  }
}
node --env-file=.env src/agent.js
docker sandbox run shell .
node --env-file=.env src/agent.js
[inside sandbox]
Add new tool in ./src/agent.js that will store memories in "memory.md" file in ./dist directory everytime user mentions that some information has to be memoized or stored or saved as memory.
[prompt]
const SYSTEM_PROMPT = `You are a coding assistant with access to bash commands...`;

const messages = [];

const chat = async () => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
	method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model: 'mistral-large-2512',
      messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
      tools: [
        {
          type: 'function',
          function: {
            name: 'sh',
            parameters: {
              type: 'object',
              properties: { command: { type: 'string' } },
            },
          },
        },
        {
          type: 'function',
          function: {
            name: 'memorize',
            description: 'Store information in memory for later retrieval.',
            parameters: {
              type: 'object',
              properties: {
                content: {
                  type: 'string',
                  description: 'The information to be stored in memory.',
                },
              },
              required: ['content'],
            },
          },
        },
      ],
    }),
  });

  return (await await res.json()).choices[0].message;
};

const runShell = (input) => {
  // ';:' forces a zero exit status so execSync never throws on bad commands.
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const runMemorize = (content) => {
  try {
    const distDir = path.join(process.cwd(), 'dist');
    if (!fs.existsSync(distDir)) {
      fs.mkdirSync(distDir, { recursive: true });
    }
    const memoryFile = path.join(distDir, 'memory.md');
    fs.appendFileSync(memoryFile, content + '\n');
    return `Memory saved to ${memoryFile}`;
  } catch (error) {
    return `Failed to save memory: ${error.message}`;
  }
};

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const content = await chat();
    messages.push(content);

    if (!content.tool_calls?.length) {
      process.stdout.write('🤖 ' + content.content + '\n> ');
      break;
    }

    for (const { id, function: { name, arguments: args } } of content.tool_calls) {
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        output = runMemorize(parsedArgs.content);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({ role: 'tool', tool_call_id: id, content: output });
    }
  }
}
const SYSTEM_PROMPT = `You are a coding assistant with access to bash commands...`;

const messages = [];

const chat = async () => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
	method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model: 'mistral-large-2512',
      messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
      tools: [
        {
          type: 'function',
          function: {
            name: 'sh',
            parameters: {
              type: 'object',
              properties: { command: { type: 'string' } },
            },
          },
        },
        {
          type: 'function',
          function: {
            name: 'memorize',
            description: 'Store information in memory for later retrieval.',
            parameters: {
              type: 'object',
              properties: {
                content: {
                  type: 'string',
                  description: 'The information to be stored in memory.',
                },
              },
              required: ['content'],
            },
          },
        },
      ],
    }),
  });

  return (await await res.json()).choices[0].message;
};

const runShell = (input) => {
  // ';:' forces a zero exit status so execSync never throws on bad commands.
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const runMemorize = (content) => {
  try {
    const distDir = path.join(process.cwd(), 'dist');
    if (!fs.existsSync(distDir)) {
      fs.mkdirSync(distDir, { recursive: true });
    }
    fs.appendFileSync(path.join(distDir, 'memory.md'), content + '\n');
    return `Memory saved to ${memoryFile}`;
  } catch (error) {
    return `Failed to save memory: ${error.message}`;
  }
};

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const content = await chat();
    messages.push(content);

    //.....

    for (const { id, function: { name, arguments: args } } of content.tool_calls) {
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        output = runMemorize(parsedArgs.content);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({ role: 'tool', tool_call_id: id, content: output });
    }
  }
}

What about multi-agent system?

Let's add it!

🤖

🤖

🤖

const MAIN_SYSTEM_PROMPT = `You are a helpful assistant with access to a coding specialist.
- You can help with general tasks and have access to bash commands.
- For ANY coding, programming, or software development task, you MUST delegate it to the coding agent using the "delegate_coding_task" tool.
- Do not try to write complex code yourself if it's better suited for the specialist.
- You can also save memories using "memorize".
- Be concise and practical.`;

const CODING_SYSTEM_PROMPT = `You are a specialized coding agent using the devstral-latest model.
- You are an expert in software development.
- You can execute bash commands using the "sh" tool to run tests, list files, or manage the project.
- You should focus purely on the coding task provided.
- When you are done, return a final response describing what you did.`;

// --- Tools ---

// --- Helper Functions ---

const runShell = (input) => {
  // ';:' forces a zero exit status so execSync never throws on bad commands.
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const runMemorize = (content) => {
  try {
    const distDir = path.join(process.cwd(), 'dist');
    if (!fs.existsSync(distDir)) {
      fs.mkdirSync(distDir, { recursive: true });
    }
    const memoryFile = path.join(distDir, 'memory.md');
    fs.appendFileSync(memoryFile, content + '\n');
    return `Memory saved to ${memoryFile}`;
  } catch (error) {
    return `Failed to save memory: ${error.message}`;
  }
};

const chat = async (model, messages, tools) => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
    method: 'POST',
    dispatcher,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model,
      messages,
      tools: tools.length > 0 ? tools : undefined,
    }),
  });

  if (!res.ok) {
    const txt = await res.text();
    throw new Error(`API Error: ${res.status} ${res.statusText} - ${txt}`);
  }

  const data = await res.json();
  return data.choices[0].message;
};

// --- Agents ---

const runMainAgent = async (messages) => {
  const response = await chat('mistral-large-2512', messages, [
    {
      type: 'function',
      function: {
        name: 'sh',
        description: 'Execute a shell command',
        parameters: {
          type: 'object',
          properties: { command: { type: 'string' } },
          required: ['command'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'delegate_coding_task',
        description: 'Delegate a coding task to the specialist coding agent.',
        parameters: {
          type: 'object',
          properties: {
            task: {
              type: 'string',
              description: 'The detailed coding task description.',
            },
          },
          required: ['task'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'memorize',
        description: 'Store information in memory for later retrieval.',
        parameters: {
          type: 'object',
          properties: {
            content: {
              type: 'string',
              description: 'The information to be stored in memory.',
            },
          },
          required: ['content'],
        },
      },
    },
  ]);
  return response;
};

// The Coding Agent Loop
const runCodingAgent = async (task) => {
  console.log(`\n👷 [Coding Agent] Starting task: "${task}"`);

  const messages = [
    { role: 'system', content: CODING_SYSTEM_PROMPT },
    { role: 'user', content: task },
  ];

  // Limit turns to prevent infinite loops in demo
  const MAX_TURNS = 20;

  for (let i = 0; i < MAX_TURNS; i++) {
    console.log(`👷 [Coding Agent] Turn ${i + 1}`);
    const response = await chat('devstral-latest', messages, [
      {
        type: 'function',
        function: {
          name: 'sh',
          description: 'Execute a shell command',
          parameters: {
            type: 'object',
            properties: { command: { type: 'string' } },
            required: ['command'],
          },
        },
      },
    ]);
    messages.push(response);

    if (response.content) {
      console.log(`👷 [Coding Agent] says: ${response.content}`);
    }

    if (!response.tool_calls || response.tool_calls.length === 0) {
      // Agent is done
      console.log(`👷 [Coding Agent] Finished.`);
      return response.content;
    }

    // Handle tool calls
    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      console.log(`👷 [Coding Agent] calling tool: ${name}`);

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }

  return 'Coding agent reached maximum turns without completing.';
};

// --- Main Loop ---

const messages = [{ role: 'system', content: MAIN_SYSTEM_PROMPT }];

const rl = readline.createInterface({
  input: process.stdin,
  crlfDelay: Infinity,
});

console.log('🤖 Multi-Agent System Initialized');
process.stdout.write('> ');

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const response = await runMainAgent(messages);
    messages.push(response);

    if (!response.tool_calls || response.tool_calls.length === 0) {
      process.stdout.write('🤖 ' + response.content + '\n> ');
      break;
    }

    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        console.log(`🛠️  [Main Agent] Executing shell: ${parsedArgs.command}`);
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        console.log(`🧠 [Main Agent] Memorizing...`);
        output = runMemorize(parsedArgs.content);
      } else if (name === 'delegate_coding_task') {
        console.log(`👉 [Main Agent] Delegating to Coding Agent...`);
        output = await runCodingAgent(parsedArgs.task);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }
}
const MAIN_SYSTEM_PROMPT = `You are a helpful assistant with access to a coding specialist.
- You can help with general tasks and have access to bash commands.
- For ANY coding, programming, or software development task, you MUST delegate it to the coding agent using the "delegate_coding_task" tool.
- Do not try to write complex code yourself if it's better suited for the specialist.
- You can also save memories using "memorize".
- Be concise and practical.`;

const CODING_SYSTEM_PROMPT = `You are a specialized coding agent using the devstral-latest model.
- You are an expert in software development.
- You can execute bash commands using the "sh" tool to run tests, list files, or manage the project.
- You should focus purely on the coding task provided.
- When you are done, return a final response describing what you did.`;

// --- Tools ---

// --- Helper Functions ---

const runShell = (input) => {
  // ';:' forces a zero exit status so execSync never throws on bad commands.
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const runMemorize = (content) => {
  try {
    const distDir = path.join(process.cwd(), 'dist');
    if (!fs.existsSync(distDir)) {
      fs.mkdirSync(distDir, { recursive: true });
    }
    const memoryFile = path.join(distDir, 'memory.md');
    fs.appendFileSync(memoryFile, content + '\n');
    return `Memory saved to ${memoryFile}`;
  } catch (error) {
    return `Failed to save memory: ${error.message}`;
  }
};

const chat = async (model, messages, tools) => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
    method: 'POST',
    dispatcher,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model,
      messages,
      tools: tools.length > 0 ? tools : undefined,
    }),
  });

  if (!res.ok) {
    const txt = await res.text();
    throw new Error(`API Error: ${res.status} ${res.statusText} - ${txt}`);
  }

  const data = await res.json();
  return data.choices[0].message;
};

// --- Agents ---

const runMainAgent = async (messages) => {
  const response = await chat('mistral-large-2512', messages, [
    {
      type: 'function',
      function: {
        name: 'sh',
        description: 'Execute a shell command',
        parameters: {
          type: 'object',
          properties: { command: { type: 'string' } },
          required: ['command'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'delegate_coding_task',
        description: 'Delegate a coding task to the specialist coding agent.',
        parameters: {
          type: 'object',
          properties: {
            task: {
              type: 'string',
              description: 'The detailed coding task description.',
            },
          },
          required: ['task'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'memorize',
        description: 'Store information in memory for later retrieval.',
        parameters: {
          type: 'object',
          properties: {
            content: {
              type: 'string',
              description: 'The information to be stored in memory.',
            },
          },
          required: ['content'],
        },
      },
    },
  ]);
  return response;
};

// The Coding Agent Loop
const runCodingAgent = async (task) => {
  console.log(`\n👷 [Coding Agent] Starting task: "${task}"`);

  const messages = [
    { role: 'system', content: CODING_SYSTEM_PROMPT },
    { role: 'user', content: task },
  ];

  // Limit turns to prevent infinite loops in demo
  const MAX_TURNS = 20;

  for (let i = 0; i < MAX_TURNS; i++) {
    console.log(`👷 [Coding Agent] Turn ${i + 1}`);
    const response = await chat('devstral-latest', messages, [
      {
        type: 'function',
        function: {
          name: 'sh',
          description: 'Execute a shell command',
          parameters: {
            type: 'object',
            properties: { command: { type: 'string' } },
            required: ['command'],
          },
        },
      },
    ]);
    messages.push(response);

    if (response.content) {
      console.log(`👷 [Coding Agent] says: ${response.content}`);
    }

    if (!response.tool_calls || response.tool_calls.length === 0) {
      // Agent is done
      console.log(`👷 [Coding Agent] Finished.`);
      return response.content;
    }

    // Handle tool calls
    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      console.log(`👷 [Coding Agent] calling tool: ${name}`);

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }

  return 'Coding agent reached maximum turns without completing.';
};

// --- Main Loop ---

const messages = [{ role: 'system', content: MAIN_SYSTEM_PROMPT }];

const rl = readline.createInterface({
  input: process.stdin,
  crlfDelay: Infinity,
});

console.log('🤖 Multi-Agent System Initialized');
process.stdout.write('> ');

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const response = await runMainAgent(messages);
    messages.push(response);

    if (!response.tool_calls || response.tool_calls.length === 0) {
      process.stdout.write('🤖 ' + response.content + '\n> ');
      break;
    }

    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        console.log(`🛠️  [Main Agent] Executing shell: ${parsedArgs.command}`);
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        console.log(`🧠 [Main Agent] Memorizing...`);
        output = runMemorize(parsedArgs.content);
      } else if (name === 'delegate_coding_task') {
        console.log(`👉 [Main Agent] Delegating to Coding Agent...`);
        output = await runCodingAgent(parsedArgs.task);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }
}
const MAIN_SYSTEM_PROMPT = `You are a helpful assistant with access to a coding specialist.
- You can help with general tasks and have access to bash commands.
- For ANY coding, programming, or software development task, you MUST delegate it to the coding agent using the "delegate_coding_task" tool.
- Do not try to write complex code yourself if it's better suited for the specialist.
- You can also save memories using "memorize".
- Be concise and practical.`;

const CODING_SYSTEM_PROMPT = `You are a specialized coding agent using the devstral-latest model.
- You are an expert in software development.
- You can execute bash commands using the "sh" tool to run tests, list files, or manage the project.
- You should focus purely on the coding task provided.
- When you are done, return a final response describing what you did.`;

// --- Tools ---

// --- Helper Functions ---

const runShell = (input) => {
  // ';:' forces a zero exit status so execSync never throws on bad commands.
  try {
    return execSync(input + ';:') + '';
  } catch (error) {
    return error.message;
  }
};

const runMemorize = (content) => {
  try {
    const distDir = path.join(process.cwd(), 'dist');
    if (!fs.existsSync(distDir)) {
      fs.mkdirSync(distDir, { recursive: true });
    }
    const memoryFile = path.join(distDir, 'memory.md');
    fs.appendFileSync(memoryFile, content + '\n');
    return `Memory saved to ${memoryFile}`;
  } catch (error) {
    return `Failed to save memory: ${error.message}`;
  }
};

const chat = async (model, messages, tools) => {
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
    method: 'POST',
    dispatcher,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
    },
    body: JSON.stringify({
      model,
      messages,
      tools: tools.length > 0 ? tools : undefined,
    }),
  });

  if (!res.ok) {
    const txt = await res.text();
    throw new Error(`API Error: ${res.status} ${res.statusText} - ${txt}`);
  }

  const data = await res.json();
  return data.choices[0].message;
};

// --- Agents ---

const runMainAgent = async (messages) => {
  const response = await chat('mistral-large-2512', messages, [
    {
      type: 'function',
      function: {
        name: 'sh',
        description: 'Execute a shell command',
        parameters: {
          type: 'object',
          properties: { command: { type: 'string' } },
          required: ['command'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'delegate_coding_task',
        description: 'Delegate a coding task to the specialist coding agent.',
        parameters: {
          type: 'object',
          properties: {
            task: {
              type: 'string',
              description: 'The detailed coding task description.',
            },
          },
          required: ['task'],
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'memorize',
        description: 'Store information in memory for later retrieval.',
        parameters: {
          type: 'object',
          properties: {
            content: {
              type: 'string',
              description: 'The information to be stored in memory.',
            },
          },
          required: ['content'],
        },
      },
    },
  ]);
  return response;
};

// The Coding Agent Loop
const runCodingAgent = async (task) => {
  console.log(`\n👷 [Coding Agent] Starting task: "${task}"`);

  const messages = [
    { role: 'system', content: CODING_SYSTEM_PROMPT },
    { role: 'user', content: task },
  ];

  // Limit turns to prevent infinite loops in demo
  const MAX_TURNS = 20;

  for (let i = 0; i < MAX_TURNS; i++) {
    console.log(`👷 [Coding Agent] Turn ${i + 1}`);
    const response = await chat('devstral-latest', messages, [
      {
        type: 'function',
        function: {
          name: 'sh',
          description: 'Execute a shell command',
          parameters: {
            type: 'object',
            properties: { command: { type: 'string' } },
            required: ['command'],
          },
        },
      },
    ]);
    messages.push(response);

    if (response.content) {
      console.log(`👷 [Coding Agent] says: ${response.content}`);
    }

    if (!response.tool_calls || response.tool_calls.length === 0) {
      // Agent is done
      console.log(`👷 [Coding Agent] Finished.`);
      return response.content;
    }

    // Handle tool calls
    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      console.log(`👷 [Coding Agent] calling tool: ${name}`);

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }

  return 'Coding agent reached maximum turns without completing.';
};

// --- Main Loop ---

const messages = [{ role: 'system', content: MAIN_SYSTEM_PROMPT }];

const rl = readline.createInterface({
  input: process.stdin,
  crlfDelay: Infinity,
});

console.log('🤖 Multi-Agent System Initialized');
process.stdout.write('> ');

for await (const line of rl) {
  messages.push({ role: 'user', content: line });

  while (true) {
    const response = await runMainAgent(messages);
    messages.push(response);

    if (!response.tool_calls || response.tool_calls.length === 0) {
      process.stdout.write('🤖 ' + response.content + '\n> ');
      break;
    }

    for (const toolCall of response.tool_calls) {
      const { name, arguments: args } = toolCall.function;
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        console.log(`🛠️  [Main Agent] Executing shell: ${parsedArgs.command}`);
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        console.log(`🧠 [Main Agent] Memorizing...`);
        output = runMemorize(parsedArgs.content);
      } else if (name === 'delegate_coding_task') {
        console.log(`👉 [Main Agent] Delegating to Coding Agent...`);
        output = await runCodingAgent(parsedArgs.task);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: output,
      });
    }
  }
}

What about other things?

- Tools

- MCP

- Skills

🤔

as the interface to inform LLM what is available in the agent

Think about tools

Where the tokens goes?

💵 💶

🤔

for await (const line of rl) {
  messages.push({ role: 'user', content: line });
  
  while (true) {
    // here goes HTTP call to Mistral API
    const content = await chat();
    messages.push(content);

    if (!content.tool_calls?.length) {
      process.stdout.write('🤖 ' + content.content + '\n> ');
      break;
    }

    for (const { id, function: { name, arguments: args } } of content.tool_calls) {
      const parsedArgs = JSON.parse(args);
      let output;

      if (name === 'sh') {
        output = runShell(parsedArgs.command);
      } else if (name === 'memorize') {
        output = runMemorize(parsedArgs.content);
      } else {
        output = `Error: Unknown tool ${name}`;
      }

      messages.push({
        role: 'tool',
        tool_call_id: id,
        content: output,
      });
    }
  }
}
// in chat(...)
const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
  method: 'POST',
  dispatcher,
  headers: {...}
  body: JSON.stringify({
    model: 'mistral-large-2512', //'devstral-latest',
    messages: [{ role: 'system', content: SYSTEM_PROMPT }, ...messages],
    tools: [
      {
        type: 'function',
        function: {
          name: 'sh',
          parameters: {
            type: 'object',
            properties: { command: { type: 'string' } },
          },
        },
      },
      {
        type: 'function',
        function: {
          name: 'memorize',
          description: 'Store information in memory for later retrieval.',
          parameters: {
            type: 'object',
            properties: {
              content: {
                type: 'string',
                description: 'The information to be stored in memory.',
              },
            },
            required: ['content'],
          },
        },
      },
    ],
  }),
 });

What about

provider-level caching?

What About

context compression?

What About

<paste here>?

It is exceptionally hard to make it helpful and smart

It is easy to create powerful agent

  • Prompts
  • Security
  • Guardrails
  • Cost control
  • Agent(s) constelation
  • Workflow(s)
  • LLMs are stateless, each request contains full conversation

  • We are sending only definitions of skills, and definitions and schemas for MCPs tools and tools

    • LLM simply "tells" agent which should be used

  • Less agent loops is better

    • Each agent loop is extra input tokens (all previous steps including tools results) + new step

  • Agent can run on your local machine or on someone else's machine aka cloud

    • Tools are executed on that machine, not on LLM

    • Alternative - on microVMs

  • System prompts/Agent.md/Claude.md/Gemini.md etc are send basically in every request, thats why you should keep them lightweight

  • There is a lot to play with cache on provider side - if you have large system prompts - use it!

Takeaways

🗒️

Selected sources

FEEDBACK

❤️

Thank you!

Michał Michalczuk

michalczukm.xyz