Agent Runner
Run LLM tool-use loops with Anthropic or OpenAI, routed through Nella's validation pipeline with full cost tracking.
The Agent Runner lets you run complete LLM tool-use loops where every tool call is routed through Nella’s validation pipeline. It supports Anthropic and OpenAI models with built-in token tracking and cost estimation.
How It Works
- You provide a prompt and model configuration
- The runner sends the prompt to the LLM along with Nella’s MCP tool definitions
- When the LLM requests a tool call, the runner executes it through
McpToolHandler - Tool results are fed back to the LLM as messages
- The loop continues until the LLM finishes, hits the turn limit, or is stopped
Every tool call goes through Nella’s full validation pipeline — constraints, risk scanning, refusal checks — ensuring safe execution even in autonomous loops.
Quick Start
import { AgentRunner, McpToolHandler } from '@getnella/mcp';
const handler = new McpToolHandler({ workspacePath: '.' });
const runner = new AgentRunner(handler);
const result = await runner.run({
provider: 'anthropic',
model: 'claude-sonnet-4-20250514',
apiKey: process.env.ANTHROPIC_API_KEY,
prompt: 'Add input validation to the login form',
maxTurns: 10,
maxTokens: 4096,
});
console.log(`Status: ${result.status}`);
console.log(`Turns: ${result.turns.length}`);
console.log(`Cost: $${result.totalCost.toFixed(4)}`);
Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | "anthropic" or "openai" |
model | string | Yes | Model ID (e.g., claude-sonnet-4-20250514, gpt-4o) |
apiKey | string | Yes | Provider API key |
prompt | string | Yes | The task prompt |
maxTurns | number | No | Maximum loop iterations (default: 10) |
maxTokens | number | No | Max tokens per LLM call |
Supported Models & Pricing
| Model | Input (per 1M tokens) | Output (per 1M tokens) |
|---|---|---|
claude-opus-4-20250514 | $15.00 | $75.00 |
claude-sonnet-4-20250514 | $3.00 | $15.00 |
claude-3-5-sonnet-20241022 | $3.00 | $15.00 |
gpt-4-turbo | $10.00 | $30.00 |
gpt-4o | $2.50 | $10.00 |
gpt-4o-mini | $0.15 | $0.60 |
Result Structure
{
turns: AgentTurn[]; // Each turn contains:
// {
// assistantContent: string;
// toolCalls: ToolCallInfo[];
// toolResults: ToolResultInfo[];
// tokenUsage: { inputTokens, outputTokens, totalTokens };
// cost: number;
// durationMs: number;
// }
totalTokenUsage: {
inputTokens: number;
outputTokens: number;
totalTokens: number;
};
totalCost: number;
totalDurationMs: number;
status: "completed" | "max_turns" | "stopped" | "error";
error?: string;
}
Events
Subscribe to runner events for real-time monitoring:
runner.onEvent((event) => {
switch (event.type) {
case 'turn:start':
console.log(`Turn ${event.turn} starting...`);
break;
case 'turn:tool_call':
console.log(`Calling ${event.toolName}...`);
break;
case 'turn:end':
console.log(`Turn complete. Cost: $${event.cost}`);
break;
case 'done':
console.log(`Finished: ${event.status}`);
break;
}
});
| Event | Description |
|---|---|
status | Runner status change |
turn:start | New turn beginning |
turn:thinking | LLM is generating |
turn:tool_call | Tool call requested |
turn:tool_result | Tool call completed |
turn:end | Turn finished |
done | All turns complete |
error | Error occurred |
Stopping a Run
You can stop a running agent at any time:
const runner = new AgentRunner(handler);
// Start the run
const resultPromise = runner.run(config);
// Stop after 30 seconds
setTimeout(() => runner.stop(), 30000);
const result = await resultPromise;
// result.status === "stopped"
Provider Adapters
Anthropic
Calls https://api.anthropic.com/v1/messages with anthropic-version: 2023-06-01. Automatically converts between Nella’s tool format and Anthropic’s content block format (text + tool_use + tool_result).
OpenAI
Calls https://api.openai.com/v1/chat/completions. Converts tool calls from OpenAI’s function calling format with JSON-stringified arguments. Maps finish reasons (stop → end_turn, tool_calls → tool_use).