> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents Framework & API Guide

> Step-by-step guide to building agents with the Orq.ai Agents Framework and API. Covers tools, memory, knowledge bases, and multi-agent patterns.

## Overview

The Orq.ai Agents Framework provides a powerful API for creating, configuring, and executing intelligent AI agents. This guide covers the complete workflow for building agents programmatically and integrating them into your applications using the Agents API and SDKs.

## Core Concepts

### Agent Lifecycle

Agents follow a simple two-step lifecycle:

1. **Creation** - Define your agent configuration via `POST /v2/agents`
2. **Execution** - Send messages via `POST /v2/agents/{agent_key}/responses`

### A2A Protocol

All agent communication uses the **A2A Protocol** for standardized agent-to-agent messaging. Messages are structured with a role and parts array containing content blocks.

### Task IDs and Context

Each agent execution returns a `task_id` that maintains conversation context across multiple turns. Use the same `task_id` in subsequent requests to continue conversations without replaying the full history.

***

## Step 1: Creating Agents

### Agent Configuration

An agent requires the following configuration:

* **key** (required): Unique identifier within your workspace
* **role**: The agent's function or purpose
* **description**: Brief summary of capabilities
* **instructions**: Behavioral guidelines and system prompt
* **model**: Model to use (string or object format)
* **path**: Storage location in your project structure
* **settings**: Execution parameters (max\_iterations, max\_execution\_time, tools)

### Creating a Simple Agent

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.orq.ai/v2/agents \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "key": "support-agent",
    "role": "Customer Support Assistant",
    "description": "Handles customer inquiries and provides support",
    "instructions": "You are a helpful customer support assistant. Answer customer questions clearly and concisely. If you cannot help, escalate to a human agent.",
    "path": "Default/agents",
    "model": "openai/gpt-4o",
    "settings": {
      "max_iterations": 5,
      "max_execution_time": 300,
      "tools": []
    }
  }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from orq_ai_sdk import Orq
  import os

  client = Orq(
      api_key=os.getenv("ORQ_API_KEY", ""),
  )

  agent = client.agents.create(
      key="support-agent",
      role="Customer Support Assistant",
      description="Handles customer inquiries and provides support",
      instructions="You are a helpful customer support assistant. Answer customer questions clearly and concisely. If you cannot help, escalate to a human agent.",
      path="Default/agents",
      model="openai/gpt-4o",
      settings={
          "max_iterations": 5,
          "max_execution_time": 300,
          "tools": []
      }
  )

  print(f"Agent created: {agent.key}")
  ```

  ```typescript Typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import { Orq } from "@orq-ai/node";

  const client = new Orq({
    apiKey: process.env.ORQ_API_KEY ?? "",
  });

  async function createAgent() {
    const agent = await client.agents.create({
      key: "support-agent",
      role: "Customer Support Assistant",
      description: "Handles customer inquiries and provides support",
      instructions: "You are a helpful customer support assistant. Answer customer questions clearly and concisely. If you cannot help, escalate to a human agent.",
      path: "Default/agents",
      model: "openai/gpt-4o",
      settings: {
        maxIterations: 5,
        maxExecutionTime: 300,
        tools: []
      }
    });

    console.log(`Agent created: ${agent.key}`);
  }

  createAgent();
  ```
</CodeGroup>

### Model Parameter Formats

The `model` parameter supports two formats:

**String Format** (simple, recommended for basic use):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
"model": "anthropic/claude-3-sonnet"
```

Use this when you want default model behavior without custom parameters.

**Object Format** (for advanced configuration):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
"model": {
  "id": "openai/gpt-4o",
  "parameters": {
    "temperature": 0.7,
    "max_tokens": 1000
  }
}
```

Use this when you need to customize temperature, token limits, or other model-specific parameters.

### Agent Settings

Configure execution behavior with the `settings` object:

| Parameter                | Type   | Description                       | Default         |
| ------------------------ | ------ | --------------------------------- | --------------- |
| `max_iterations`         | number | Maximum agent processing loops    | 100             |
| `max_execution_time`     | number | Maximum execution time in seconds | 300             |
| `tools`                  | array  | Tools available to the agent      | \[]             |
| `tool_approval_required` | string | Tool approval mode                | "respect\_tool" |

**Tool Approval Modes:**

* `"respect_tool"` (default) - Use tool's individual approval settings. Each tool defines whether approval is required
* `"none"` - Never require approval, execute all tools automatically. Use for trusted tools and automated workflows
* `"always"` - Always require manual approval before any tool execution. Use for high-risk operations (coming soon)

| Mode           | Best For                 | Example                                                              |
| -------------- | ------------------------ | -------------------------------------------------------------------- |
| `respect_tool` | Mixed trust levels       | Some tools (web search) are safe, others (CRM inserts) need approval |
| `none`         | Automated, trusted tools | Retrieving current date, reading knowledge bases                     |
| `always`       | High-risk operations     | Financial transactions, account deletions, data modifications        |

<Info>
  To learn more about tools, see the [Tools Documentation](/docs/agents/build#add-tools).
</Info>

## Step 2: Executing Agents

### Basic Execution

Execute an agent using the Responses API:

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.orq.ai/v2/agents/support-agent/responses \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "I have a question about my account"
        }
      ]
    },
    "background": false
  }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from orq_ai_sdk import Orq
  import os

  client = Orq(
      api_key=os.getenv("ORQ_API_KEY", ""),
  )

  try:
      response = client.agents.responses.create(
          agent_key="support-agent",
          background=False,
          message={
              "role": "user",
              "parts": [
                  {
                      "kind": "text",
                      "text": "I have a question about my account"
                  }
              ]
          }
      )

      if response.output and len(response.output) > 0:
          parts = response.output[0].parts
          if parts and len(parts) > 0:
              print(parts[0].text)
  except Exception as e:
      print(f"Error: {e}")
  ```

  ```typescript Typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import { Orq } from "@orq-ai/node";

  const client = new Orq({
    apiKey: process.env.ORQ_API_KEY ?? "",
  });

  async function executeAgent() {
    try {
      const response = await client.agents.responses.create({
        agentKey: "support-agent",
        background: false,
        message: {
          role: "user",
          parts: [
            {
              kind: "text",
              text: "I have a question about my account"
            }
          ]
        }
      });

      if (response?.output && response.output.length > 0) {
        const parts = response.output[0].parts;
        if (parts && parts.length > 0) {
          console.log(parts[0].text);
        }
      }
    } catch (error) {
      console.error(`Error: ${error}`);
    }
  }

  executeAgent();
  ```
</CodeGroup>

### Response Structure

The response includes:

* **output**: Array of A2A protocol messages with the agent's responses
* **task\_id**: Identifier for continuing this conversation
* **usage**: Token consumption details
* **model**: Model used for execution

## Step 3: Multi-Turn Conversations

### Using Task IDs for Context

Continue conversations by providing the `task_id` from a previous response:

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.orq.ai/v2/agents/support-agent/responses \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "task_id": "01K6D8QESESZ6SAXQPJPFQXPFT",
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Can you help me reset my password?"
        }
      ]
    },
    "background": false
  }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from orq_ai_sdk import Orq
  import os

  client = Orq(
      api_key=os.getenv("ORQ_API_KEY", ""),
  )

  try:
      # Continue conversation with task_id
      response = client.agents.responses.create(
          agent_key="support-agent",
          task_id="01K6D8QESESZ6SAXQPJPFQXPFT",
          background=False,
          message={
              "role": "user",
              "parts": [
                  {
                      "kind": "text",
                      "text": "Can you help me reset my password?"
                  }
              ]
          }
      )

      if response.output and len(response.output) > 0:
          parts = response.output[0].parts
          if parts and len(parts) > 0:
              print(parts[0].text)
  except Exception as e:
      print(f"Error: {e}")
  ```

  ```typescript Typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import { Orq } from "@orq-ai/node";

  const client = new Orq({
    apiKey: process.env.ORQ_API_KEY ?? "",
  });

  async function continueConversation() {
    try {
      const response = await client.agents.responses.create({
        agentKey: "support-agent",
        taskId: "01K6D8QESESZ6SAXQPJPFQXPFT",
        background: false,
        message: {
          role: "user",
          parts: [
            {
              kind: "text",
              text: "Can you help me reset my password?"
            }
          ]
        }
      });

      if (response?.output && response.output.length > 0) {
        const parts = response.output[0].parts;
        if (parts && parts.length > 0) {
          console.log(parts[0].text);
        }
      }
    } catch (error) {
      console.error(`Error: ${error}`);
    }
  }

  continueConversation();
  ```
</CodeGroup>

<Tip>
  **Key Benefits:**

  * Full conversation context is maintained automatically
  * No need to replay previous messages
  * Efficient token usage
  * Natural multi-turn interactions
</Tip>

## Advanced Configuration

### Execution Modes

| Execution Mode       | Synchronous (`background: false`)                              | Asynchronous (`background: true`)                              |
| -------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| **Behavior**         | Agent processes request completely before returning            | Returns immediately with `task_id` and initial status          |
| **Response**         | Complete output, all tool results, token usage                 | Initial status only; agent continues in background             |
| **Timeout**          | Respects `max_execution_time` (default: 300s); fails on exceed | No immediate timeout concern                                   |
| **Result retrieval** | Immediate in response                                          | Must poll using `task_id`                                      |
| **Best for**         | Interactive apps, chatbots, APIs needing immediate responses   | Long-running operations, batch processing, high-load scenarios |
| **Trade-off**        | Client must wait for completion                                | Requires polling                                               |

## Agent State Management

Agents process tasks asynchronously. The `/responses` endpoint returns:

* `task_id`: Reference to continue multi-turn conversations
* `output`: Array of messages with agent's response
* `usage`: Token consumption details

Reuse `task_id` in subsequent requests to maintain conversation context.

## Best Practices

### Instructions Design

* Write clear, concise instructions
* Define expected outputs and formats
* Specify when to escalate or ask for clarification
* Include examples when helpful

### Performance Optimization

* Set appropriate `max_iterations` limits
* Use `max_execution_time` to prevent runaway processes
* Leverage `task_id` to avoid context replay
* Batch related requests when possible

## Complete Example: Conversational Loop

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from orq_ai_sdk import Orq
  import os

  client = Orq(api_key=os.getenv("ORQ_API_KEY", ""))

  # Create agent
  agent = client.agents.create(
      key="chatbot",
      role="Conversational Assistant",
      description="A friendly conversational assistant",
      instructions="You are a helpful assistant. Answer questions accurately and engage in natural conversation.",
      path="Default/agents",
      model="openai/gpt-4o",
      settings={
          "max_iterations": 5,
          "max_execution_time": 300,
          "tools": []
      }
  )

  print(f"Agent created: {agent.key}\n")

  # Start conversation
  task_id = None
  messages = [
      "Hello, how are you?",
      "What can you help me with?",
      "Tell me about machine learning"
  ]

  try:
      for user_message in messages:
          print(f"User: {user_message}")

          response = client.agents.responses.create(
              agent_key="chatbot",
              task_id=task_id,
              background=False,
              message={
                  "role": "user",
                  "parts": [{"kind": "text", "text": user_message}]
              }
          )

          # Extract response
          if response.output and len(response.output) > 0:
              parts = response.output[0].parts
              if parts and len(parts) > 0:
                  agent_response = parts[0].text
                  print(f"Agent: {agent_response}\n")

                  # Store task_id for next turn to maintain conversation context
                  # API guarantees task_id is always in response, even on first call
                  task_id = response.task_id
  except Exception as e:
      print(f"Error in conversation: {e}")
  ```

  ```typescript Typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import { Orq } from "@orq-ai/node";

  const client = new Orq({
    apiKey: process.env.ORQ_API_KEY ?? "",
  });

  async function conversationalLoop() {
    try {
      // Create agent
      const agent = await client.agents.create({
        key: "chatbot",
        role: "Conversational Assistant",
        description: "A friendly conversational assistant",
        instructions: "You are a helpful assistant. Answer questions accurately and engage in natural conversation.",
        path: "Default/agents",
        model: "openai/gpt-4o",
        settings: {
          maxIterations: 5,
          maxExecutionTime: 300,
          tools: []
        }
      });

      console.log(`Agent created: ${agent.key}\n`);

      // Start conversation
      let taskId = null;
      const messages = [
        "Hello, how are you?",
        "What can you help me with?",
        "Tell me about machine learning"
      ];

      for (const userMessage of messages) {
        console.log(`User: ${userMessage}`);

        const response = await client.agents.responses.create({
          agentKey: "chatbot",
          taskId: taskId,
          background: false,
          message: {
            role: "user",
            parts: [{ kind: "text", text: userMessage }]
          }
        });

        // Extract response
        if (response?.output && response.output.length > 0) {
          const parts = response.output[0].parts;
          if (parts && parts.length > 0) {
            const agentResponse = parts[0].text;
            console.log(`Agent: ${agentResponse}\n`);

            // Store task_id for next turn to maintain conversation context
            // API guarantees taskId is always in response, even on first call
            taskId = response.taskId;
          }
        }
      }
    } catch (error) {
      console.error(`Error in conversation: ${error}`);
    }
  }

  conversationalLoop();
  ```
</CodeGroup>

## Next Steps

* [**Tools with Agents**](/docs/agents/build#add-tools) - Add capabilities like web search and custom functions
* [**Multi-Agent Workflows**](/docs/agents/run#multi-agent-workflows) - Orchestrate multiple agents together
* [**API Reference**](/reference/agents/create-agent) - Detailed endpoint documentation
