Agents & Tools
Build structured, deterministic AI agents with tools, policies, and safety guardrails.
Why Agents?
Agents are LLMs that can take actions. Instead of just generating text, they can call tools (functions) to interact with external systems, databases, APIs, and more. Orka agents follow a structured reasoning loop: they think about what to do, take an action, observe the result, and repeat until they have a final answer.
import { createOrka, OpenAIAdapter } from 'orkajs';import type { Tool } from 'orkajs'; const orka = createOrka({ llm: new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! }), vectorDB: myVectorDB,}); const agent = orka.agent({ goal: 'Help customers with their orders', tools: [getOrder, cancelOrder, refundOrder], policy: { maxSteps: 5, noHallucination: true, rules: ['Always verify order exists before any action'], },}); const result = await agent.run('What is the status of order ORD-123?'); console.log(result.output); // "Order ORD-123 is currently being shipped..."console.log(result.toolsUsed); // ['get_order']console.log(result.steps); // Detailed reasoning traceconsole.log(result.totalTokens); // Token usage# Defining Tools
Tools are functions that agents can call. Each tool has a name, description, parameters, and an execute function. The description is crucial — it tells the LLM when and how to use the tool.
import type { Tool } from 'orkajs'; const getOrder: Tool = { name: 'get_order', description: 'Retrieve an order by its ID. Returns order status, items, and shipping info.', parameters: [ { name: 'orderId', type: 'string', description: 'The order ID (e.g., ORD-123)', required: true, }, ], async execute(input) { const order = await db.orders.findById(input.orderId as string); if (!order) { return { output: '', error: `Order ${input.orderId} not found` }; } return { output: `Order ${order.id}: ${order.status}, shipped via ${order.carrier}`, metadata: { orderId: order.id, status: order.status }, }; },}; const cancelOrder: Tool = { name: 'cancel_order', description: 'Cancel an order. Only works for orders not yet shipped.', parameters: [ { name: 'orderId', type: 'string', description: 'Order ID to cancel', required: true }, { name: 'reason', type: 'string', description: 'Cancellation reason', required: false }, ], async execute(input) { const result = await db.orders.cancel(input.orderId as string, input.reason as string); if (!result.success) { return { output: '', error: result.error }; } return { output: `Order ${input.orderId} has been cancelled.` }; },};Tool Interface
name: stringUnique identifier for the tool. Use snake_case (e.g., get_order, send_email).
description: stringClear description of what the tool does. The LLM uses this to decide when to call it.
parameters: ToolParameter[]Array of { name, type, description, required }. Types: string, number, boolean, array, object.
execute(input): Promise<ToolResult>Async function that runs the tool. Returns { output: string, error?: string, metadata?: object }.
# Agent Policies
Policies control agent behavior and add safety guardrails. Use them to limit steps, restrict tools, and enforce rules.
| Property | Type | Description |
|---|---|---|
| maxSteps | number | Maximum reasoning steps |
| noHallucination | boolean | Instruct agent not to hallucinate |
| rules | string[] | Custom rules in natural language |
| allowedTools | string[] | Whitelist of allowed tools |
| blockedTools | string[] | Blacklist of forbidden tools |
💡 ReAct Loop
Orka AI agents follow a structured ReAct (Reasoning + Action) loop:
- Think: "I need to find the order status first"
- Act: Call get_order({orderId: 'ORD-123'})
- Observe: "Order ORD-123: shipped via FedEx"
- Think: "I have the answer, I can respond"
- Finish: Return final answer to user
# Agent Result
| Property | Type | Description |
|---|---|---|
| output | string | Final answer from the agent |
| toolsUsed | string[] | Names of tools that were called |
| steps | AgentStep[] | Detailed trace of each reasoning step |
| totalTokens | number | Total tokens consumed |
| metadata | object | Combined metadata from all tool calls |
Complete Example
import { createOrka, OpenAIAdapter } from 'orkajs';import type { Tool } from 'orkajs'; const orka = createOrka({ llm: new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! }), vectorDB: myVectorDB,}); // Define toolsconst getWeather: Tool = { name: 'get_weather', description: 'Get current weather for a city', parameters: [ { name: 'city', type: 'string', description: 'City name', required: true }, ], execute: async (input) => { const weather = await weatherAPI.get(input.city as string); return { output: `${weather.temp}°C, ${weather.condition}` }; },}; const sendEmail: Tool = { name: 'send_email', description: 'Send an email to a recipient', parameters: [ { name: 'to', type: 'string', description: 'Email address', required: true }, { name: 'subject', type: 'string', description: 'Email subject', required: true }, { name: 'body', type: 'string', description: 'Email body', required: true }, ], execute: async (input) => { await emailService.send(input.to, input.subject, input.body); return { output: `Email sent to ${input.to}` }; },}; // Create agent with policiesconst agent = orka.agent({ goal: 'Help users with weather info and email tasks', tools: [getWeather, sendEmail], policy: { maxSteps: 5, noHallucination: true, rules: [ 'Always confirm before sending emails', 'Provide temperature in both Celsius and Fahrenheit', ], blockedTools: [], // Could block 'send_email' for read-only mode },}); // Run the agentconst result = await agent.run('What is the weather in Paris?');console.log(result.output);// "The current weather in Paris is 18°C (64°F), partly cloudy."🚀 Advanced Agents
For more sophisticated agent patterns (ReAct, Plan-and-Execute, OpenAI Functions, Structured Chat) and pre-built toolkits (SQL, CSV), see the Advanced Agents documentation.
Tree-shaking Imports
// ✅ Import typesimport type { Tool, ToolParameter, ToolResult } from 'orkajs'; // ✅ Import agent types for advanced usageimport { ReActAgent } from 'orkajs/agent/react';import { PlanAndExecuteAgent } from 'orkajs/agent/plan-and-execute';