Advanced Agent Types
Specialized agent architectures for reasoning patterns : ReAct, Plan-and-Execute, OpenAI Functions, Structured Chat, and Streaming Tool Calls. Pluspre-built toolkits for SQL and CSV analysis.
ReAct Agent
IterativeDynamic loop of Thought → Action → Observation. Best for unpredictable, interactive tasks.
Plan-and-Execute
StructuralDecomposes goals into a task list before acting. Superior for long-running, complex workflows.
OpenAI Functions
OptimizedLeverages native model-level JSON schema for near-perfect tool invocation reliability.
Structured Chat
ValidatedEnforces strict JSON formatting with schema validation. Best for multi-input tool systems.
StreamingToolAgent
Real-timeStreams tokens in real time while executing tools in parallel. Users see the model thinking as tools run.
# ReAct Agent — Reasoning + Acting
The ReAct agent follows the Thought → Action → Observation loop. At each step, it reasons about what to do, takes an action (calls a tool), observes the result, and repeats until it can provide a final answer. This is the most general-purpose agent pattern and works well for most tasks.
import { ReActAgent } from '@orka-js/agent';import { OpenAIAdapter } from '@orka-js/openai';import type { Tool } from '@orka-js/tools'; const llm = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! }); // Define toolsconst searchTool: Tool = { name: 'web_search', description: 'Search the web for current information', parameters: [ { name: 'query', type: 'string', description: 'Search query', required: true } ], execute: async (input) => { const results = await mySearchAPI(input.query as string); return { output: results }; }}; const calculatorTool: Tool = { name: 'calculator', description: 'Perform mathematical calculations', parameters: [ { name: 'expression', type: 'string', description: 'Math expression to evaluate', required: true } ], execute: async (input) => { const result = eval(input.expression as string); // Use a safe math parser in production return { output: String(result) }; }}; // Create ReAct agentconst agent = new ReActAgent( { goal: 'Help users find information and perform calculations', tools: [searchTool, calculatorTool], maxSteps: 10, verbose: true, // Logs each Thought/Action/Observation policy: { rules: [ 'Always verify information from multiple sources', 'Show your calculations step by step' ] } }, llm); const result = await agent.run('What is the population of France times 2?'); console.log(result.output);// "The population of France is approximately 68 million. 68,000,000 × 2 = 136,000,000." console.log(result.steps);// [// { thought: "I need to find the population of France", action: "web_search", ... },// { thought: "Now I need to multiply by 2", action: "calculator", ... }// ]Cognitive Execution Trace
Pattern: Reasoning + Acting (ReAct)
"Find France population first"web_search({query: "population..."})"68 million inhabitants""Calculate 68M * 2"calculator({expression: "..."})136,000,000# Plan-and-Execute Agent
The Plan-and-Execute agent separates planning from execution. First, it creates a complete plan of steps. Then, it executes each step one by one. If a step fails and replanOnFailure is enabled, it dynamically adjusts the remaining plan. This architecture is ideal for complex, multi-step tasks where having a clear roadmap improves reliability.
import { PlanAndExecuteAgent } from '@orka-js/agent'; const agent = new PlanAndExecuteAgent( { goal: 'Research and analyze data to answer complex questions', tools: [searchTool, calculatorTool, databaseTool], maxSteps: 15, replanOnFailure: true, // Dynamically adjust plan if a step fails }, llm); const result = await agent.run( 'Compare the GDP per capita of France, Germany, and Japan. Which has grown the most in the last 5 years?'); console.log(result.output);// Comprehensive comparison with data and analysis console.log(result.plan);// [// { id: 1, description: "Search for France GDP per capita data", status: "completed", result: "..." },// { id: 2, description: "Search for Germany GDP per capita data", status: "completed", result: "..." },// { id: 3, description: "Search for Japan GDP per capita data", status: "completed", result: "..." },// { id: 4, description: "Calculate growth rates for each country", status: "completed", result: "..." },// { id: 5, description: "Compare and determine highest growth", status: "completed", result: "..." }// ] console.log(result.steps);// Detailed execution trace with timing and token usage per stepOptimal Scenarios
- Complex multi-step reasoning
- Research & deep analysis
- Strict operation ordering
- Observable execution roadmaps
Contraindications
- Simple single-step queries
- Real-time conversational UX
- Unpredictable branching paths
# OpenAI Functions Agent
Uses the OpenAI function calling format for precise, structured tool invocation. Tools are described as JSON schemas, and the LLM responds with structured function calls instead of free-text parsing. This results in more reliable tool usage with fewer parsing errors.
import { OpenAIFunctionsAgent } from '@orka-js/agent'; const agent = new OpenAIFunctionsAgent( { goal: 'Help users manage their tasks and calendar', tools: [ { name: 'create_event', description: 'Create a calendar event', parameters: [ { name: 'title', type: 'string', description: 'Event title', required: true }, { name: 'date', type: 'string', description: 'Event date (YYYY-MM-DD)', required: true }, { name: 'time', type: 'string', description: 'Event time (HH:MM)', required: false }, ], execute: async (input) => { await calendarAPI.create(input); return { output: `Event "${input.title}" created for ${input.date}` }; } }, { name: 'list_events', description: 'List calendar events for a date range', parameters: [ { name: 'start_date', type: 'string', description: 'Start date', required: true }, { name: 'end_date', type: 'string', description: 'End date', required: true }, ], execute: async (input) => { const events = await calendarAPI.list(input.start_date, input.end_date); return { output: JSON.stringify(events) }; } } ], // Optional: provide custom function definitions (auto-generated from tools if omitted) // functions: [{ name: 'create_event', description: '...', parameters: { ... } }], maxSteps: 5, }, llm); const result = await agent.run('Schedule a team meeting for next Monday at 2pm'); console.log(result.output);// "I've created a 'Team Meeting' event for 2024-03-18 at 14:00." console.log(result.metadata);// { agentType: 'openai-functions', stepsUsed: 1 }Auto-generated Function Schemas
If you don't provide custom function definitions, the agent automatically converts your Tool definitions into OpenAI-compatible function schemas:
// Your Tool definition:{ name: 'create_event', parameters: [{ name: 'title', type: 'string', required: true }] } // Auto-generated OpenAI function schema:{ "name": "create_event", "parameters": { "type": "object", "properties": { "title": { "type": "string" } }, "required": ["title"] }}# Structured Chat Agent
The Structured Chat agent communicates entirely through JSON. Every response — whether a tool call or a final answer — is a structured JSON object. This makes it highly predictable and easy to integrate into systems that require structured outputs. You can optionally define an output schema to enforce the format of the final answer.
import { StructuredChatAgent } from '@orka-js/agent'; const agent = new StructuredChatAgent( { goal: 'Analyze customer support tickets and route them', tools: [ { name: 'classify_ticket', description: 'Classify a support ticket by category and urgency', parameters: [ { name: 'text', type: 'string', description: 'Ticket text', required: true } ], execute: async (input) => { // Classification logic return { output: JSON.stringify({ category: 'billing', urgency: 'high' }) }; } }, { name: 'route_ticket', description: 'Route a ticket to the appropriate team', parameters: [ { name: 'category', type: 'string', description: 'Ticket category', required: true }, { name: 'urgency', type: 'string', description: 'Urgency level', required: true } ], execute: async (input) => { return { output: `Routed to ${input.category} team (priority: ${input.urgency})` }; } } ], // Optional: enforce output format outputSchema: { type: 'object', properties: { category: { type: 'string' }, urgency: { type: 'string' }, team: { type: 'string' }, summary: { type: 'string' } } }, maxSteps: 5, }, llm); const result = await agent.run('Customer says: "I was charged twice for my subscription!"'); console.log(result.output);// "Classified as billing/high urgency. Routed to billing team with priority handling." console.log(result.steps);// All steps are structured JSON — easy to log and audit# StreamingToolAgent — Real-time Streaming + Tools
StreamingToolAgent streams LLM tokens in real time while executing tool calls in parallel. Unlike ReActAgent (which waits for the full response), it yields token events immediately — users see the model "thinking" as tools run. Memory is loaded at the start of each call and saved after completion, maintaining full conversational context across requests.
import { StreamingToolAgent } from '@orka-js/agent';import { OpenAIAdapter } from '@orka-js/openai';import { Memory } from '@orka-js/memory-store'; const llm = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! }); const searchTool = { name: 'search_products', description: 'Search for products matching a query', parameters: [ { name: 'query', type: 'string', description: 'Search query', required: true }, { name: 'maxPrice', type: 'number', description: 'Maximum price filter', required: false }, ], execute: async ({ query, maxPrice }) => { const results = await productDB.search(query as string, maxPrice as number); return { output: JSON.stringify(results) }; },}; // Optional: pass a Memory instance for conversation persistenceconst memory = new Memory(); const agent = new StreamingToolAgent( { goal: 'Help customers find products that match their needs', tools: [searchTool], maxSteps: 5, verbose: true, // Logs each tool call to console }, llm, memory, // Agent remembers context across requests); // ─── Streaming run ──────────────────────────────────────────────────────────── for await (const event of agent.runStream('Find me a Bluetooth headphone under 200€')) { switch (event.type) { case 'token': process.stdout.write(event.token); // LLM thinking in real time break; case 'tool_call': console.log(`\n[→] ${event.name}(${event.arguments})`); break; case 'tool_result': console.log(`[←] ${event.result}`); // Tool output before final answer break; case 'done': console.log('\n[✓]', event.content); break; case 'error': console.error('[✗]', event.message); break; }} // ─── Subsequent call — agent remembers the previous exchange ────────────────── for await (const event of agent.runStream('What about under 150€?')) { // Agent knows the context: "Bluetooth headphone" from previous turn if (event.type === 'token') process.stdout.write(event.token);} // ─── Non-streaming shortcut ─────────────────────────────────────────────────── const result = await agent.run('Show me the top-rated option');console.log(result.output); // Final answerconsole.log(result.steps); // Tool calls with observationsconsole.log(result.totalTokens); // Token usageStream Event Flow
Per LLM call cycle
Memory Persistence
Pass a Memory instance to the constructor. History is automatically loaded before each runStream() and saved after each completion.
Parallel Tool Execution
When the LLM requests multiple tools simultaneously, all are executed in parallel via Promise.all(), then results are injected back into the stream.
# Agent Toolkits
Toolkits are pre-built collections of tools for common data analysis tasks. Instead of defining tools manually, use a toolkit to instantly equip any agent with domain-specific capabilities.
- SQL Toolkit
Provides tools for querying SQL databases: execute queries, inspect schema, and list tables. Supports read-only mode for safety and automatic LIMIT injection.
import { SQLToolkit, ReActAgent } from '@orka-js/agent'; const sqlToolkit = new SQLToolkit({ execute: async (query: string) => { // Connect to your database const result = await db.query(query); return JSON.stringify(result.rows); }, schema: ` CREATE TABLE users(id INT, name VARCHAR, email VARCHAR, created_at TIMESTAMP); CREATE TABLE orders(id INT, user_id INT, amount DECIMAL, status VARCHAR, created_at TIMESTAMP); CREATE TABLE products(id INT, name VARCHAR, price DECIMAL, category VARCHAR); `, readOnly: true, // Only SELECT queries allowed maxRows: 50 // Auto-inject LIMIT 50}); // Use with any agent typeconst agent = new ReActAgent( { goal: 'Answer questions about the database by writing SQL queries', tools: sqlToolkit.tools, // Includes: sql_query, sql_schema, sql_list_tables maxSteps: 8, }, llm); const result = await agent.run('How many orders were placed last month? What was the total revenue?'); // The agent will:// 1. Use sql_schema to understand the tables// 2. Write and execute SQL queries// 3. Synthesize the results into a natural language answerSQL Guardrail System
Zero-Trust Agentic Access
readOnlyPolicyImmutable Access
Hard-blocks DML operations (INSERT, UPDATE, DELETE). Only allows analytical queries.
maxRowsPerformanceRuntime Quota
Enforces strict pagination. Automatically appends LIMIT to prevent memory exhaustion.
schemaOptimizationSchema Mapping
In-memory metadata caching. Prevents the agent from scanning system tables.
- CSV Toolkit
Provides tools for analyzing CSV data in-memory: search, filter, and aggregate. No database required — just pass your CSV data as a string.
import { CSVToolkit, ReActAgent } from '@orka-js/agent'; const csvData = `name,department,salary,start_dateAlice,Engineering,95000,2021-03-15Bob,Marketing,72000,2020-06-01Charlie,Engineering,105000,2019-01-10Diana,Sales,68000,2022-09-20Eve,Engineering,88000,2023-02-01`; const csvToolkit = new CSVToolkit({ data: csvData, separator: ',' // default}); const agent = new ReActAgent( { goal: 'Analyze employee data and answer questions', tools: csvToolkit.tools, // Includes: csv_info, csv_search, csv_filter, csv_aggregate maxSteps: 8, }, llm); // Ask questions about the dataconst result = await agent.run('What is the average salary in Engineering? Who earns the most?'); // The agent will use csv_filter and csv_aggregate tools to find the answerconsole.log(result.output);// "The average salary in Engineering is $96,000. Charlie earns the most at $105,000." // CSV Toolkit tools:// - csv_info: Get column names, row count, sample data// - csv_search: Search for rows by column value (partial match)// - csv_filter: Filter rows with operators (=, !=, >, <, >=, <=, contains)// - csv_aggregate: count, sum, avg, min, max, distinct# Combining Agents with Toolkits
You can combine multiple toolkits and custom tools with any agent type:
import { PlanAndExecuteAgent, SQLToolkit, CSVToolkit } from '@orka-js/agent'; const sqlToolkit = new SQLToolkit({ execute: db.query, readOnly: true });const csvToolkit = new CSVToolkit({ data: reportCSV }); // Combine toolkit tools with custom toolsconst allTools = [ ...sqlToolkit.tools, ...csvToolkit.tools, myCustomSearchTool, myCalculatorTool,]; const agent = new PlanAndExecuteAgent( { goal: 'Cross-reference database records with CSV reports', tools: allTools, maxSteps: 15, replanOnFailure: true, }, llm); const result = await agent.run( 'Compare the sales figures in the CSV report with the orders table in the database. Are there any discrepancies?');Agent Type Comparison
| Agent Class | Operational Pattern | Primary Use Case | Reliability Score |
|---|---|---|---|
| Agent (Base) | Thought / Action | Simple automation | 60% |
| ReAct | Think → Act → Observe | Dynamic reasoning | 85% |
| Plan-and-Execute | Plan → Exec → Re-plan | Deep multi-step research | 98% |
| OpenAI Functions | Native Tool Binding | Mission-critical tools | 99% |
| Structured Chat | JSON Strict I/O | Auditable outputs | 90% |
| StreamingToolAgent | Stream → Tool → Stream | Real-time chat UX | 92% |
Best Practices
1. Choose the Right Agent Type
Use ReAct for general tasks, Plan-and-Execute for complex multi-step workflows, OpenAI Functions when you need precise tool calls, and Structured Chat when you need JSON outputs.
2. Set Appropriate Limits
Always set maxSteps to prevent infinite loops. Use policies to restrict tool access and enforce rules.
3. Use Toolkits for Data Analysis
SQLToolkit and CSVToolkit provide battle-tested tools. Always use readOnly mode for SQL in production. Combine multiple toolkits for cross-data analysis.
4. Monitor with verbose Mode
Enable verbose: true on ReActAgent during development to see each Thought/Action/Observation in the console. All agents return detailed steps for production monitoring.
Tree-shaking Imports
// ✅ Import only what you needimport { ReActAgent } from '@orka-js/agent';import { PlanAndExecuteAgent } from '@orka-js/agent';import { OpenAIFunctionsAgent } from '@orka-js/agent';import { StructuredChatAgent } from '@orka-js/agent';import { StreamingToolAgent } from '@orka-js/agent'; // v1.5.0+import { SQLToolkit, CSVToolkit } from '@orka-js/agent'; // ✅ Or combine in one importimport { ReActAgent, PlanAndExecuteAgent, StreamingToolAgent, SQLToolkit } from '@orka-js/agent';