OrkaJS
Orka.JS

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 trace
console.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: string

Unique identifier for the tool. Use snake_case (e.g., get_order, send_email).

description: string

Clear 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.

PropertyTypeDescription
maxStepsnumberMaximum reasoning steps
noHallucinationbooleanInstruct agent not to hallucinate
rulesstring[]Custom rules in natural language
allowedToolsstring[]Whitelist of allowed tools
blockedToolsstring[]Blacklist of forbidden tools

💡 ReAct Loop

Orka AI agents follow a structured ReAct (Reasoning + Action) loop:

  1. Think: "I need to find the order status first"
  2. Act: Call get_order({orderId: 'ORD-123'})
  3. Observe: "Order ORD-123: shipped via FedEx"
  4. Think: "I have the answer, I can respond"
  5. Finish: Return final answer to user

# Agent Result

PropertyTypeDescription
outputstringFinal answer from the agent
toolsUsedstring[]Names of tools that were called
stepsAgentStep[]Detailed trace of each reasoning step
totalTokensnumberTotal tokens consumed
metadataobjectCombined 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 tools
const 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 policies
const 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 agent
const 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 types
import type { Tool, ToolParameter, ToolResult } from 'orkajs';
 
// ✅ Import agent types for advanced usage
import { ReActAgent } from 'orkajs/agent/react';
import { PlanAndExecuteAgent } from 'orkajs/agent/plan-and-execute';