Skip to content

Getting Started

This guide will walk you through creating your first AI agent with @arcaelas/agent, from installation to deployment.

Prerequisites

Before you begin, ensure you have:

  • Node.js ≥ 16.0.0 installed
  • An OpenAI API key (get one at platform.openai.com)
  • Basic knowledge of TypeScript or JavaScript

Step 1: Installation

Install @arcaelas/agent and required dependencies:

npm install @arcaelas/agent dotenv

Step 2: Environment Setup

Create a .env file in your project root:

OPENAI_API_KEY=sk-your-actual-api-key-here

Step 3: Your First Agent

Create a file my-first-agent.ts:

import 'dotenv/config';
import { Agent, Rule, OpenAI } from '@arcaelas/agent';

// Create the provider — no external SDK needed
const provider = new OpenAI({
  api_key: process.env.OPENAI_API_KEY!,
  model: "gpt-4o-mini",
});

// Create the agent
const assistant = new Agent({
  rules: [new Rule("A helpful assistant that answers questions and provides information.")],
  providers: [provider],
});

// Start conversation
async function main() {
  const [messages, success] = await assistant.call("Hello! Can you introduce yourself?");

  if (success) {
    console.log("Assistant:", messages[messages.length - 1].content);
  } else {
    console.log("Failed to get response");
  }
}

main();

Run your agent:

npx tsx my-first-agent.ts

Expected Output:

Assistant: Hello! I'm your Personal Assistant, here to help answer questions and provide information. How can I assist you today?

Step 4: Adding Tools

Tools allow your agent to perform actions. Let's add a time tool:

import { Agent, Tool, OpenAI } from '@arcaelas/agent';

// Create a simple time tool
const time_tool = new Tool("get_current_time", async (agent) => {
  return new Date().toLocaleString();
});

// Create agent with the tool
const assistant = new Agent({
  rules: [new Rule("Assistant that can tell the current time.")],
  tools: [time_tool],
  providers: [
    new OpenAI({
      api_key: process.env.OPENAI_API_KEY!,
      model: "gpt-4o-mini",
    }),
  ],
});

// Ask for the time
const [messages, success] = await assistant.call("What time is it?");

The agent will: 1. Receive your question 2. Decide to use the get_current_time tool 3. Execute the tool automatically 4. Respond with the current time

Step 5: Adding Rules

Rules define how your agent should behave:

import { Agent, Rule, OpenAI } from '@arcaelas/agent';

const assistant = new Agent({
  rules: [
    new Rule("Professional customer support agent."),
    new Rule("Always maintain a professional and courteous tone"),
    new Rule("Never share confidential information"),
    new Rule("If unsure, admit it rather than making up information")
  ],
  providers: [
    new OpenAI({ api_key: process.env.OPENAI_API_KEY!, model: "gpt-4o-mini" }),
  ],
});

Step 6: Multi-Provider Setup

Add automatic failover between providers. All providers are built-in — no external SDKs needed:

import { Agent, Rule, OpenAI, Claude, Groq } from '@arcaelas/agent';

const resilient_agent = new Agent({
  rules: [new Rule("High-availability assistant.")],
  providers: [
    // Primary: OpenAI
    new OpenAI({
      api_key: process.env.OPENAI_API_KEY!,
      model: "gpt-4o-mini",
    }),
    // Backup: Anthropic Claude
    new Claude({
      api_key: process.env.ANTHROPIC_API_KEY!,
      model: "claude-haiku-3-5",
    }),
    // Fallback: Groq (ultra-fast)
    new Groq({
      api_key: process.env.GROQ_API_KEY!,
      model: "llama-3.1-8b-instant",
    }),
  ],
});

If OpenAI fails, the agent automatically tries Claude, then Groq. Other available providers: DeepSeek (reasoning/code) and Ollama (local models, no API key required). See the Providers guide for details.

Step 7: Context Inheritance

Create reusable contexts for organizational structure:

import { Agent, Context, Metadata, Rule, OpenAI } from '@arcaelas/agent';

// Company-wide base context
const company_context = new Context({
  metadata: new Metadata()
    .set("organization", "Acme Corp")
    .set("compliance", "enterprise"),
  rules: [
    new Rule("Maintain professional communication"),
    new Rule("Protect confidential information")
  ]
});

// Department-specific context
const support_context = new Context({
  context: company_context,  // Inherits from company
  metadata: new Metadata().set("department", "Support"),
  tools: [kb_search_tool, ticket_tool]
});

// Create agent with inherited context
const support_agent = new Agent({
  rules: [new Rule("Customer support specialist.")],
  contexts: support_context,  // Has access to everything
  providers: [
    new OpenAI({ api_key: process.env.OPENAI_API_KEY!, model: "gpt-4o-mini" }),
  ],
});

// Agent automatically has:
// - Company metadata ("organization", "compliance")
// - Department metadata ("department")
// - Company rules + department rules
// - Department tools

Complete Example

Here's a complete, production-ready example:

import 'dotenv/config';
import { Agent, Tool, Rule, Metadata, OpenAI } from '@arcaelas/agent';

// Create utility tools
const weather_tool = new Tool("get_weather", {
  description: "Get current weather for a city",
  parameters: {
    city: "City name (e.g., 'London', 'New York')"
  },
  func: async (agent, params) => {
    // In production, call a real weather API
    return `Weather in ${params.city}: Sunny, 22°C`;
  }
});

const time_tool = new Tool("get_time", async (agent) => {
  return new Date().toLocaleString();
});

// Create the agent
const assistant = new Agent({
  rules: [
    new Rule("Intelligent assistant with weather and time capabilities."),
    new Rule("Be concise and helpful"),
    new Rule("Use tools when appropriate"),
    new Rule("Admit when you don't know something")
  ],

  metadata: new Metadata()
    .set("version", "1.0")
    .set("environment", "production"),

  tools: [weather_tool, time_tool],

  providers: [
    new OpenAI({
      api_key: process.env.OPENAI_API_KEY!,
      model: "gpt-4o-mini",
    }),
  ],
});

// Interactive conversation loop
async function startChat() {
  const readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  });

  console.log("Chat started! Type 'exit' to quit.\n");

  const prompt = () => {
    readline.question('You: ', async (input: string) => {
      if (input.toLowerCase() === 'exit') {
        readline.close();
        return;
      }

      const [messages, success] = await assistant.call(input);

      if (success) {
        const response = messages[messages.length - 1].content;
        console.log(`Assistant: ${response}\n`);
      } else {
        console.log("Failed to get response. Try again.\n");
      }

      prompt();
    });
  };

  prompt();
}

startChat();

Streaming Responses

Use agent.stream() instead of agent.call() to receive tokens as they arrive. It returns an AsyncGenerator<StreamChunk> with four possible chunk roles:

import { Agent, OpenAI } from '@arcaelas/agent';

const agent = new Agent({
  providers: [new OpenAI({ api_key: process.env.OPENAI_API_KEY!, model: "gpt-4o-mini" })],
});

for await (const chunk of agent.stream("Tell me a short story")) {
  if (chunk.role === "assistant") process.stdout.write(chunk.content);  // text token
  if (chunk.role === "thinking")  process.stdout.write(`[think] ${chunk.content}`); // reasoning
  if (chunk.role === "tool_call") console.log(`\n→ calling ${chunk.name}(${chunk.arguments})`);
  if (chunk.role === "tool")      console.log(`← ${chunk.name}: ${chunk.content}`);
}

stream() handles the full agentic loop (tool calls, re-invocations) exactly like call(). See the Providers guide for provider-specific streaming capabilities (e.g. thinking chunks from DeepSeek or Claude).

Next Steps

Now that you've created your first agent, explore these topics:

Common Issues

Provider Errors

If you see connection errors:

  1. Check your API key is correct
  2. Verify internet connection
  3. Check API provider status

Tool Execution Failures

If tools aren't working:

  1. Ensure tools are passed to the provider
  2. Check tool function returns a string
  3. Verify parameters match expected format

TypeScript Errors

If TypeScript shows errors:

  1. Install types: npm install --save-dev @types/node
  2. Update tsconfig.json target to ES2020+
  3. Enable esModuleInterop in tsconfig

Support

Need help? Check these resources: