typescriptadvanced

AI Agent Loop with Tool Calling

Implement an autonomous agent loop that plans, selects tools, executes actions, and observes results.

typescript
import OpenAI from 'openai';

const openai = new OpenAI();

type Tool = {
  name: string;
  description: string;
  execute: (args: Record<string, string>) => Promise<string>;
};

const tools: Tool[] = [
  {
    name: 'search',
    description: 'Search the web for information',
    execute: async ({ query }) => `Results for: ${query}`,
  },
  {
    name: 'calculate',
    description: 'Evaluate a math expression',
    execute: async ({ expr }) => String(eval(expr)),
  },
];

export async function agentLoop(task: string, maxSteps = 5): Promise<string> {
  const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
    { role: 'system', content: `You are an agent. Available tools: ${tools.map((t) => `${t.name}: ${t.description}`).join(', ')}. Respond with JSON: {"tool": "name", "args": {}} or {"answer": "final answer"}` },
    { role: 'user', content: task },
  ];

  for (let step = 0; step < maxSteps; step++) {
    const res = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages,
      response_format: { type: 'json_object' },
    });

    const action = JSON.parse(res.choices[0].message.content ?? '{}');

    if (action.answer) return action.answer;

    const tool = tools.find((t) => t.name === action.tool);
    if (!tool) break;

    const result = await tool.execute(action.args ?? {});
    messages.push({ role: 'assistant', content: JSON.stringify(action) });
    messages.push({ role: 'user', content: `Tool result: ${result}` });
  }

  return 'Agent could not complete the task.';
}

Use Cases

  • Research assistants
  • Code generation agents
  • Data analysis bots

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.