# Agent

Agents in AXAR AI are the primary building blocks. They represent a tightly coupled set of tasks. Agents can work independently in a developer-defined workflow or collaborate to build more complex autonomous workflows.

<figure><img src="/files/RklOp57KlYBOEN1OmeIE" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
Conceptually, an agent in AXAR AI is a container for:

* **LLM model:** The LLM the agent uses.
* **System prompts:** Instructions to guide the LLM.
* **Structured I/O:** Data structures defining the expected input and output of the agent.
* **Dependencies:** External objects passed to the agent, available across prompts, tools, and validators within the agent.
* **Tools:** Methods the agent can call to gather information or perform actions as needed.
  {% endhint %}

### **Creating an agent**

Here’s a simple example of creating an agent in AXAR AI. This agent greets the user by their name.

```typescript
import { model, systemPrompt, Agent } from "@axarai/axar";

// Specify the AI model used by the agent
@model('openai:gpt-4o-mini')
// Provide a system-level prompt to guide the agent's behavior
@systemPrompt(`Greet the user by their name in a friendly tone.`)
export class GreetingAgent extends Agent<string, string> {
  
}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent().run("My name is Alice.");
  console.log(response); // Output: "Hello, Alice! It's great to meet you! How are you doing today?"
})();
```

#### What just happened?

{% stepper %}
{% step %}
**Model**

The `@model` decorator sets the AI model to use. Here, it’s using `openai:gpt-4o-mini`.
{% endstep %}

{% step %}
**Prompt**

The `@systemPrompt` decorator defines the agent’s behavior. In this case, the agent greets users by their name in a friendly way.
{% endstep %}

{% step %}
**Agent**

The `GreetingAgent` class extends `Agent`, taking a `string` as input and returning a `string` as output.
{% endstep %}

{% step %}
**Run**

The agent runs with the input `"My name is Alice."` and generates a friendly greeting based on the system prompt.
{% endstep %}
{% endstepper %}

### Dynamic system prompts <a href="#runs-vs-conversations" id="runs-vs-conversations"></a>

In the previous example, the `run()` method assumes the user's name is included in the input. But what if the input doesn’t contain the name?

We can handle this by modifying the agent to accept the user's name as a parameter in its `constructor()`. We can then generate a dynamic system prompt using the provided name. This is done by combining the `@systemPrompt` annotation with an instance method inside the agent class.

With this setup, the username is passed during instantiation every time and also doesn't need to be included in every `run()` call.

{% hint style="success" %}
Dynamic system prompts let us change an agent's behavior in runtime based on external context. We can pass that context to the agent through its `constructor()` as a dependency, or the method defining the dynamic prompt can fetch the external context directly.
{% endhint %}

Here’s how it works:

```typescript
import { model, systemPrompt, Agent } from "@axarai/axar";

@model('openai:gpt-4o-mini')
@systemPrompt(`
  Greet the user by their name in a friendly tone.
`)
export class GreetingAgent extends Agent<string, string> {
  constructor(private userName: string) {
    super();
  }

  // A dynamic system prompt generated in runtime
  @systemPrompt()
  getUserName(): string {
    return `User's name is: ${this.userName}!`;
  }
}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent('Alice').run('Greet me.');
  console.log(response); // Output: "Hello, Alice! 😊 It's great to see you! How are you doing today?"
})();
```

{% hint style="info" %}
The above example also shows how to inject external dependencies to an agent. Anything passed into the agent's `constructor()` can be accessed within the agent throughout its lifetime.
{% endhint %}

### Structured I/O

So far, we’ve seen how to pass a string to an agent and get a string response. However, in many cases, we might want our agent to handle structured input and output for better control, validation, and clarity. AXAR makes this possible with schemas, allowing us to define structured data formats for both input and output.

{% hint style="success" %}
With structured I/O, we can:

* Validate input data before passing it to the agent.
* Ensure the output conforms to a predefined structure and validation rules.
* Handle complex use cases with multiple fields and specific data types.
  {% endhint %}

The following example demonstrates a `GreetingAgent` that takes structured input, including the user's name, mood, day of the week, and language preference. The agent then generates structured output with a greeting, a response to the user's mood, and an optional weekend message.

```typescript
import {
  model,
  systemPrompt,
  Agent,
  schema,
  property,
  output,
  input,
  optional,
} from '@axarai/axar';

@schema()
class GreetingAgentRequest {
  @property("User's full name")
  userName!: string;

  @property("User's current mood")
  userMood!: 'happy' | 'neutral' | 'sad';

  @property('Day of the week')
  dayOfWeek!: string;

  @property("User's language preference")
  language!: string;
}

@schema()
class GreetingAgentResponse {
  @property("A greeting message to cater to the user's mood")
  greeting!: string;

  @property("A line acknowledging the user's mood")
  moodResponse!: string;

  @property("A personalized message only if it's the weekend")
  @optional()
  weekendMessage?: string;
}


@model('openai:gpt-4o-mini')
@systemPrompt(`Greet the user by their name in a friendly tone in their preferred language.`)
@input(GreetingAgentRequest)
@output(GreetingAgentResponse)
export class GreetingAgent extends Agent<
  GreetingAgentRequest,
  GreetingAgentResponse
> {}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent().run({
    userName: 'Alice',
    userMood: 'happy',
    dayOfWeek: 'Saturday',
    language: 'English',
  });
  console.log(response);
})();

```

### **Running agents**

AXAR AI provides two methods for running agents:

#### agent.run()

The `run()` method is an asynchronous function that processes the input and returns the complete output in a single response.

```typescript
const greetingAgent = new GreetingAgent();
const response = await greetingAgent.run(input);
console.log(response);
```

#### agent.stream()

The `stream()` method provides a streaming interface that yields partial results as they become available, useful for real-time UI updates or processing long responses.

```typescript
const greetingAgent = new GreetingAgent();
const { stream } = await agent.stream(input);
for await (const chunk of stream) {
    // Process each chunk as it arrives
    console.log(chunk);
}
```

Both methods support the full range of AXAR AI features including:

* Input/output schema validation
* Tool execution
* Telemetry and monitoring
* Error handling
* Model configuration


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://axar-ai.gitbook.io/axar/basics/agent.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
