#llmsmap.me

Unabhängiges technisches Audit

docs.upstreet.ai

docs.upstreet.ai

Gesamtwert der KI-Bereitschaft

Zusammengefasster Wert aus allen Auditsignalen.

58von 100Mittel
Audit der KI-Bereitschaft: 10.11.2026Öffentliche technische Daten

Über die Website

Upstreet-Dokumentation für das Upstreet Agents SDK, ein Entwicklerwerkzeug zum deklarativen Erstellen und Bereitstellen von KI-Agenten unter Nutzung von NPM-Paketen. Die Seite bietet einen Quickstart, eine API-Referenz, Beispiele, Laufzeitumgebungen, Konzepte, fortgeschrittene Themen und Migrationsleitfäden von LangChain, Crew.ai und Fetch.ai.

Kategorie:
Entwicklertools
Plattform:
Next.js

Von KI anhand von llms.txt und Startseite verfasst.

Gesamtbewertung der KI-Bereitschaft

Wie gut docs.upstreet.ai auf KI-Systeme vorbereitet ist

58/100

undefined: What's new? (docs.upstreet.ai) erreichte im automatisierten technischen Audit 58/100 Punkte bei der KI-Bereitschaft. llms.txt war erreichbar, llms-full.txt hatte keine erreichbare Datei und ai.txt war nicht auffindbar. Die robots.txt-Analyse ergab 0 ausdrücklich erlaubte und 0 blockierte KI-Crawler sowie 0 deklarierte Sitemaps. Die Vollständigkeit des Homepage-Markups lag bei 30%; es wurden keine Schema.org-Typen erkannt. Erkannte OpenGraph-Tags: 6. Die Ergebnisse entsprechen den öffentlich erreichbaren Antworten der Website zum Prüfzeitpunkt 2026-11-10T01:01:30.525Z.

Kontext der Bewertung

Die Prüfung kombiniert maschinenlesbare Dateien, Crawler-Regeln, Sitemaps und Homepage-Markup. llms.txt ist erreichbar und umfasst 47.777 Tokens.

robots.txt ist nicht verfügbar; blockierte KI-Bots: 0. Deklarierte Sitemaps: 0. Keine Schema.org-Typen erkannt.

Das mobile Lighthouse-Profil wird noch erfasst.

Bestätigte Stärken

  • llms.txt ist erreichbar
  • Öffentliche Website-Struktur wurde geprüft
  • robots.txt wurde analysiert
  • OpenGraph und Canonical-Signale wurden geprüft

Wichtige Verbesserungen

  1. 1llms-full.txt für ausführlicheren Kontext ergänzen.
  2. 2Die aktuelle sitemap.xml in robots.txt angeben.
  3. 3JSON-LD für Organisation, Website und Hauptentitäten ergänzen.
llms.txt-Tokens47.777
llms-full.txt-Tokens—
ai.txt
sitemap.xml

Technisches Profil von Google Lighthouse

Die Hintergrundwarteschlange erfasst mobile Performance, Barrierefreiheit, Best Practices, SEO und experimentelle Signale für Browser-Agenten.

Daten werden erfasst

Prüfungen der KI-Bereitschaft

Maschinenlesbare Dateien, Crawler-Regeln, Discovery und Homepage-Markup.

llms.txt

Datei gefunden und erreichbar

https://docs.upstreet.ai/llms.txt
llms-full.txt

Vollständige Version wurde nicht gefunden

ai.txt

ai.txt wurde nicht gefunden

robots.txt

robots.txt wurde nicht gefunden

Sitemap in robots.txt

In robots.txt ist keine Sitemap angegeben

Schema.org (JSON-LD)

Keine Schema.org-Auszeichnung auf der Startseite gefunden

OpenGraph30%

6 OpenGraph-Tags gefunden

Zugriff von KI-Bots

Basierend auf der robots.txt-Analyse

GPTBotNicht erwähnt
OAI-SearchBotNicht erwähnt
ChatGPT-UserNicht erwähnt
Google-ExtendedNicht erwähnt
ClaudeBotNicht erwähnt
Claude-SearchBotNicht erwähnt
Claude-UserNicht erwähnt
BytespiderNicht erwähnt
CCBotNicht erwähnt
PerplexityBotNicht erwähnt
Perplexity-UserNicht erwähnt

OpenGraph-Tags

Auf der Startseite gefundene Metadaten für Social-Media-Vorschauen.

Vollständigkeit des Markups: 30%
og:titleUpstreet Documentation
og:descriptionGet started on building AI Agents with the Upstreet Agents SDK.
og:image:typeimage/png
og:image:width3200
og:image:height1680
file: ./content/docs/changelog.mdx
# undefined: What's new?

Learn what the latest updates are in Upstreet-world.
        
import Changelog from "../../../../CHANGELOG.md";

<Changelog />


file: ./content/docs/(getting-started)/create-an-agent.mdx
# undefined: Create an Agent

Build AI Agents in minutes with the Upstreet Agents SDK.
        
import Wrapper from '../../../components/preview/wrapper';
import { File, Folder, Files } from 'fumadocs-ui/components/files';

import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
import { formatNodeVersion } from '../../../lib/utils';
import pkgJson from 'usdk/package.json';

<Accordions>
  <Accordion title="🟢 Prerequisites" defaultOpen>
    * Ensure your Node version is {formatNodeVersion(pkgJson.engines?.node || '>=22.9.0').toLocaleLowerCase()}. [Install Node](/install#prerequisites)
    * Upstreet SDK installed on your computer. [Install SDK](/install)
    * Logged in to SDK. Follow instructions to [log in here](/install#log-into-the-sdk).
  </Accordion>
</Accordions>

Upstreet AI Agents are persistent digital entities that can autonomously handle tasks, interact with you and your users over chat or social media, and can be customized according to your configuration.

**New to designing Agents?** Explore how to define effective Agent objectives and strategies in our [Agent Design Concepts](/concepts/defining-agent-objectives).

**Coming in from another platform like Tavern?** You can import your previous work into an Upstreet Agent. Check out our [Migration Guides](/migration-guides).

## Quickstart: Creating an Agent

Here’s how to set up your first Agent.

### Step 1: Running the command

1. **Set up your project directory**\
   First, create an empty directory where you’d like to set up your Agent.

2. **Run the Command in your terminal**

   ```bash
   usdk create
   ```

   Run the above command in your terminal within your new directory. This will launch a guided interview, where you’ll define essential properties of your Agent.

   You can see more options by running `usdk create --help`.

<Callout>
  We recommend using the [`pnpm`](https://pnpm.io/installation`) (Performant Node Package Manager) package manager with your Agent.
</Callout>

### Step 2: Complete the Agent Interview

The `usdk create` command initiates an interactive “interview” process with the **Interviewer**. Here’s what to expect:

1. **Interactive Prompts**\
   The SDK will prompt you with questions, helping you define your Agent's personality, environment, and other key settings.

2. **Simulated Chat with Your Agent**\
   You’ll be able to “converse” with the **Interviewer**, defining the Agent's Homespace (its natural habitat) and personality traits through chat-based interactions.

3. **Completion**\
   Once all required fields are captured, the interview concludes, setting up all the Agent features and initialising the necessary files in your directory.

<Callout>
  Want to **skip the interview** and jump right in with coding your agent?
  You can use the `-p` flag to pass a single creation prompt, or the `-y` to skip the interview process and create a default agent.
  You can also omit the agent directory. In that case, a directory will be created for you.
</Callout>

To import your agent from other platforms, `usdk create` also supports [Tavern character cards](https://github.com/malfoyslastname/character-card-spec-v2) and more.

See [*Importing a Tavern Agent*](/migration-guides/tavern#create-an-upstreet-agent-from-a-tavern-character-card) for more information.

### File Structure

Assuming you’ve named your project directory “my-agent,” here’s the structure you’ll see post-setup:

<Wrapper>
  <Files className="max-w-lg w-full">
    <Folder name="my-agent" defaultOpen>
      <Folder name="wrangler" />

      <Folder name="node_modules" disabled />

      <Folder name="packages" />

      <Folder name="codecs" />

      <Folder name="tests" />

      <File name=".gitignore" />

      <File name="agent.tsx" />

      <File name="jest.config.mjs" />

      <File name="jest.setup.mjs" />

      <File name="package-lock.json" />

      <File name="package.json" />

      <File name="tsconfig.json" />

      <File name="wrangler.toml" />

      <File name="README.md" />
    </Folder>
  </Files>
</Wrapper>

For a breakdown of these files, see our [Agent Structure guide](/concepts/usdk/agent-structure).

<Callout>
  Remember to keep your Agent's configuration secure. Avoid committing your secret keys to GitHub, and use [Environment Variables](/customize-your-agent#using-environment-variables) to store secrets.
</Callout>

***

## Editing your Agent

If you wish to edit your already-created Agent **through the Interview process**, you may run the following command in the directory of your Agent:

```bash
usdk edit
```

***

## What's next?

Now that you've set up your base Agent, you can choose to dive deeper into Agent customization and potential capabilities by [writing code in React](/customize-your-agent).

If you wish to skip customization and directly launch your Agent on our Platform, you can check out [Testing your Agent](/test-your-agent) and [Deploying your Agent](/deploy-your-agent).


file: ./content/docs/(getting-started)/customize-your-agent.mdx
# undefined: Customize your Agent

Learn how to extend an Agent's functionality using React.
        
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';

<Accordions>
  <Accordion title="🟢 Prerequisites">
    * Upstreet SDK installed on your computer. [Install SDK](/install)
    * Logged in to SDK. Follow instructions to [log in here](/install#log-into-the-sdk).
    * An Upstreet Agent. [Create an Agent](/create-an-agent)
    * Some preliminary knowledge of [React](https://react.dev)
  </Accordion>
</Accordions>

Learn how to extend an Agent’s functionality using [React](https://react.dev) components and intuitive primitives to build dynamic, intelligent agents with Upstreet. This guide will walk you through customizing your Agent step-by-step, with examples and tips to inspire you.

## Overview: How an Agent Works

Agents follow a simple but powerful cycle: they **perceive** inputs, **process** them to generate insights or decisions, and **act** on their environment based on these decisions. This perception-think-act model is broken down into components that work together to define your Agent’s functionality.

Read our [*What Are Agents?*](/concepts/what-are-agents) guide to get familiar with Agent basics.

Explore [Upstreet’s Agent Architecture](/concepts/usdk/architecture) to learn more about how Agents operate behind the scenes.

## Agent Structure at a Glance

If you’re familiar with [React](https://react.dev), the structure of an Agent will look familiar. Here’s a basic example to get you started:

```tsx
const MyAgent = () => (
  <Agent>
    <Prompt>
      This assistant is developed by MultiCortical Example Technologies. For support, refer users to our help pages at https://multicortical.example.com/
    </Prompt>
  </Agent>
);
export default MyAgent;
```

The example above shows the basic setup, where a simple prompt is added to guide the Agent’s interactions. The `react-agents` library, however, allows much more flexibility through four core components.

## Key Components of an Agent

Using the `react-agents` library, Agent customization is broken down into four core components:

| Component      | Purpose                                                        |
| -------------- | -------------------------------------------------------------- |
| `<Prompt />`   | Sets initial instructions and context for the Agent’s behavior. |
| `<Action />`   | Defines actions the Agent can perform, utilizing LLM tool-calling facilities. |
| `<Perception />` | Allows the Agent to perceive and react to real-world events.    |
| `<Task />`     | Schedules tasks for the Agent, enabling it to manage asynchronous processes.  |

You can see all Components [here](/api/components).

Import these components from the SDK package:

```tsx
import { Prompt, Action, Perception, Task } from 'react-agents';
```

Each component adds specific functionality, enabling you to build intelligent, responsive Agents. Let’s dive into each one in more detail.

An Agent consists of a collection of components implementing these primitives.

## Bringing It All Together

Here’s a sample setup that combines these components:

```tsx title="agent.tsx"
const MyAgent = () => (
  <Agent>
    <Prompt>I'm here to help you with information about our services and products.</Prompt>
    <Action name="fetchProductInfo">Retrieve the latest product details based on user query.</Action>
    <Perception trigger="userInactive">Remind user of inactivity after 5 minutes.</Perception>
    <Task schedule="every day at 9am">Send daily summary report.</Task>
  </Agent>
);
```

This setup provides a well-rounded Agent equipped to respond, perceive, act, and manage scheduled tasks effectively.

### Using environment variables

You may choose to use third-party services when customizing your Agent. These services may have **secrets** or **tokens**.

You can keep them safe by creating a `.env.txt` file in the your Agent directory, and keeping environment variables there.

An example might look like:

```dotenv title=".env.txt"
GOOGLE_API_KEY=abcdefghijklmonp
OPEN_WEATHER_KEY=abcdefghijklmonp
```

You can access these environment variables by using the [`useEnv`](/api/hooks/use-env) hook.

## Custom Logic and Advanced Patterns

With `react-agents`, you can introduce custom logic within components, such as conditional rendering, state management, and data manipulation, using native React hooks and patterns.

To explore advanced customization:

* Learn how to make [Custom Components](/advanced/custom-components/with-use-state).
* Learn more about how [agents are structured](/concepts/usdk/agent-structure).
* Our [Pokédex example](/examples/informative-agent) demonstrates a basic, real-world example of how to create a custom component.

***

## Ready for More?

With these foundational components, you can customize your Agent to fit various tasks, from customer support to data processing. Next steps:

* **[Test your Agent](/test-your-agent)**: See how it responds and make adjustments.
* **[Deploy your Agent](/deploy-your-agent)**: Launch your Agent on Upstreet's platform for real-world interactions.


file: ./content/docs/(getting-started)/deploy-your-agent.mdx
# undefined: Deploy your Agent

Get your Agent live and see it used across the Internet.
        
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';

<Accordions>
  <Accordion title="🟢 Prerequisites">
    * Upstreet SDK installed on your computer. [Install SDK](/install)
    * Logged in to SDK. Follow instructions to [log in here](/install#log-into-the-sdk).
    * A configured Upstreet Agent. [Create an Agent](/create-an-agent)
    * Sufficient credits on Upstreet's Platform
  </Accordion>
</Accordions>

## Deploy to Upstreet

Ready to unleash your Agent into the world? Simply run:

```bash
usdk deploy <your-agent-directory>
```

This command uploads your Agent to the Upstreet platform, making it accessible via a unique URL provided after a successful deployment.

<Callout> Deployment consumes Upstreet credits. For more information, see our [pricing section](/pricing). </Callout>

## Self-hosting

Prefer to run your Agent locally? You can use a Cloudflare tunnel to make it internet-accessible. Note that even with self-hosting, using Upstreet’s AI services may still consume credits.

For more on pricing models for both deployment options, visit our [Pricing](/pricing) page.

***

## Unpublishing an Agent

You may want to undeploy or unpublish your Agent. To do so, simply run the following command in the Agent's directory:

```bash
usdk unpublish
```

This will pull your Agent off the Upstreet infrastructure and make the Agent unavailable on the Platform. To run again, simply [redeploy](/deploy-your-agent#deploy-to-upstreet).

***


file: ./content/docs/(getting-started)/index.mdx
# undefined: Upstreet Documentation

Learn how to build and deploy AI Agents.
        


file: ./content/docs/(getting-started)/install.mdx
# undefined: Setup the SDK

Get started with the Upstreet Agents SDK and begin building AI Agents today.
        
import Wrapper from '../../../components/preview/wrapper';
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
import { Pre, CodeBlock } from 'fumadocs-ui/components/codeblock';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import pkgJson from 'usdk/package.json';
import { formatNodeVersion } from '../../../lib/utils';

To start building with Upstreet AI Agents, first set up the Upstreet Agents SDK (`usdk`). If you're new to Agents, check out *[What are Agents?](/concepts/what-are-agents)* for a quick introduction.

For more on SDK architecture and capabilities, see our [Concepts guide](/concepts/usdk/architecture).

## Prerequisites

Before getting started, make sure you have the following:

<Accordions>
  <Accordion title="1. A computer with a command-line interface">
    * **macOS**: Use the **Terminal** app, located in Applications > Utilities.
    * **Linux**: Use the **Terminal** application, usually accessible from the applications menu.
    * **Windows**: Use the **Command Prompt**. You can find the Command Prompt by hitting the Windows key (<kbd>⊞ Win</kbd>) and searching for the "Command Prompt" application.
      <Callout>**Important:** We **do not** recommend using PowerShell or <kbd>⊞ Win</kbd>+<kbd>R</kbd> on **Windows** as it often has issues with NodeJS. If you **must** use PowerShell, you can try out [this possible solution.](/errors#running-usdk-in-powershell)</Callout>
  </Accordion>

  <Accordion title={`2. Node.js: ${formatNodeVersion(pkgJson.engines?.node || '>=22.9.0')} (required).`}>
    Node.js is the runtime environment that allows you to run JavaScript code outside a web browser.

    ### Install Node.js

    * Go to the [Node.js downloads page](https://nodejs.org/en/download/package-manager/current).
    * Follow the instructions to install it as a package on your system, or download the installer for your OS and follow the setup steps.
    * Open the Terminal from step (1), and run `node -v` to see your Node version.

    **NPM (Node Package Manager)** is a tool that comes installed alongside Node.js. It is used to manage packages (libraries, tools, frameworks, etc.) for JavaScript projects. With NPM, you can:

    * **Install packages** for your project locally or globally.
    * **Share your code** as packages with other developers.
    * **Run scripts** for development tasks like building or testing your project.

    NPM is bundled with Node.js because it's the default package manager for managing JavaScript dependencies in Node.js projects. When you install Node.js, NPM is automatically installed, so you don't need to install it separately in most cases.

    You can **verify the installation of `npm`**:

    * Open a terminal or command prompt.
    * Run `node -v` to check the installed Node.js version.
    * Run `npm -v` to check the installed NPM version.

    ***

    Once you've installed NodeJS, you'll have access to both `node` and `npm` commands, enabling you to download and run JavaScript applications like `usdk`.
  </Accordion>
</Accordions>

<Callout type="warn">Ensure the Node version is {formatNodeVersion(pkgJson.engines?.node || '>=22.9.0').toLocaleLowerCase()}, else `usdk` will **not** work.</Callout>

## Install from NPM

To install the `usdk` command-line tool, use the following command:

{/* "pnpm (recommended)", */}

<Tabs
  items={[
"npm",
]}
>
  {/* ```bash tab="pnpm (recommended)"
    pnpm install -g usdk
    ``` */}

  ```bash tab="npm"
  npm install -g usdk
  ```
</Tabs>

### Verify Installation (optional)

To confirm a successful installation, check your SDK version:

<Wrapper>
  <div className="bg-transparent prose-no-margin px-20 w-full">
    <div className="bg-fd-background rounded-lg">
      ```bash title="Terminal"
      usdk version
      ```

      <CodeBlock className="-mt-8" icon={"bash"} keepBackground allowCopy={false}>
        <Pre>
          {pkgJson.version}
        </Pre>
      </CodeBlock>
    </div>
  </div>
</Wrapper>

This command should return the installed version number. You can view all available versions of `usdk` on [NPM](https://www.npmjs.com/package/usdk?activeTab=versions).

<Callout>
  **Tip:** While you can use `npx usdk@latest <subcommand>` to run `usdk` directly, we recommend specifying a fixed version for consistency.
</Callout>

## Log into the SDK

Some SDK features require you to be logged in. To log in:

1. Run the command:

   ```bash
   usdk login
   ```

2. A browser will open. Log into Upstreet with your preferred authentication provider.


file: ./content/docs/(getting-started)/test-your-agent.mdx
# undefined: Test your Agent

Learn how to run and test your Upstreet Agent before going live.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';

<Accordions>
  <Accordion title="🟢 Prerequisites">
    * Upstreet SDK installed on your computer. [Install SDK](/install)
    * Logged in to SDK. Follow instructions to [log in here](/install#log-into-the-sdk).
    * A configured Upstreet Agent. [Create an Agent](/create-an-agent)
  </Accordion>
</Accordions>

Once your Agent is created, you can test its responses and behaviors before deployment. The Upstreet SDK makes testing straightforward, allowing you to interact directly with your Agent.

## Running a Test Session

To start testing, run the following command in your terminal:

```bash
usdk chat <your-agent-directory>
```

Where `<your-agent-directory>` is the **relative path** to the directory containing all your Agent's code. [How to create an Agent](/create-an-agent#file-structure)

This command launches an interactive chat session (REPL-like) with your Agent, where you can input prompts and review responses in real-time.

To exit the chat, type `.exit` in the chat and press the Enter key. Or, you can use the shortcut <kbd>CTRL</kbd> + <kbd>C</kbd> twice.

<Callout> AI inferences **do not** run locally and may consume Upstreet credits during testing. </Callout>

<Wrapper>
  <Image src="/images/general/usdk-dev-chat.png" width={740} height={300} className="rounded-md" />
</Wrapper>

### Hot reloading

**Hot reloading** is supported by default, so while [customizing your Agent](/customize-your-agent), your Agent will immediately update in the chat once you save your code.

## Testing Tips

* **Specific Task Testing:** Prompt your Agent to carry out the exact tasks or interactions you want to verify.
* **Custom Test Cases:** To automate testing, write test cases using [Jest](https://jestjs.io/), ensuring consistency and reliability for complex Agent behaviors.


file: ./content/docs/advanced/custom-voices.mdx
# undefined: Custom Voices

You can create and use custom voice models for your Agents.
        
The `voice` commands in `usdk` allow you to manage custom voices for your agents.

### Available Commands

#### 1. **List Voices**

* **Command**: `voice list`
* **Description**: Displays all voices associated with your account, including voice IDs and names. Use this information to configure the `voiceEndpoint` prop.

***

#### 2. **Create a Voice**

* **Command**: `voice create <name> <audioFile>`

* **Requirements**:
  * An audio sample of the voice to clone.
  * Supported formats: **MP3**, **WAV**.

* **Parameters**:
  * `<name>`: The desired name for your voice.
  * `<audioFile>`: The path to your audio sample file.

***

#### 3. **Test a Voice**

* **Command**: `voice play <voiceName> "Your test message"`
* **Description**: Allows you to hear how your created voice sounds with a sample message.

***

See the entire command reference for `usdk` [here](/concepts/usdk/command-reference).


file: ./content/docs/advanced/usdk-library.mdx
# undefined: Using USDK programmatically

Use the Upstreet Agents SDK as a library in your code.
        
While the Upstreet Agents SDK (USDK) is designed as a [command-line interface](/concepts/usdk/overview) (CLI) for building, managing, and deploying Upstreet AI Agents, you can also import USDK as a module in your code to access its powerful functionalities programmatically.

Using USDK programmatically gives you more control over the deployment and management of your agents. You can integrate it into your own workflows, automate tasks, or build more complex applications on top of Upstreet's platform. It also eliminates the need for shell execution, providing a clean and efficient way to interact with USDK features directly from your code.

## Installation

To use it as a module in your Node.js application, install USDK locally in your project:

```bash
npm install usdk
```

## Import

You can then import USDK into your Node.js scripts:

```tsx
const usdk = require('usdk');
```

## Usage

Once imported, you can interact with USDK's commands as JavaScript functions. Here's a basic example of how you can use USDK programmatically:

### Example: Log In

```javascript
const usdk = require('usdk');

async function login() {
  try {
    await usdk.login();
    console.log('Logged in successfully!');
  } catch (error) {
    console.error('Login failed:', error);
  }
}

login();
```

### Example: Create an Agent

```javascript
const usdk = require('usdk');

async function createAgent() {
  try {
    const agent = await usdk.create({
      prompt: "Create a new agent",
      feature: ['chat'],
      force: true,
      json: '{"name":"MyAgent","type":"assistant"}'
    });
    console.log('Agent created:', agent);
  } catch (error) {
    console.error('Error creating agent:', error);
  }
}

createAgent();
```

### Example: Deploy an Agent

```javascript
const usdk = require('usdk');

async function deployAgent(agentId) {
  try {
    await usdk.deploy([agentId]);
    console.log('Agent deployed successfully!');
  } catch (error) {
    console.error('Error deploying agent:', error);
  }
}

deployAgent('my-agent-id');
```

## Key Functions Available

Here's a quick overview of the core functions you can use programmatically with USDK:

* `usdk.login()`: Logs in to the USDK.
* `usdk.logout()`: Logs out from USDK.
* `usdk.create(options)`: Creates a new agent.
* `usdk.edit(directory, options)`: Edits an existing agent.
* `usdk.deploy(agentIds)`: Deploys an agent to the network.
* `usdk.rm(agentIds)`: Removes a deployed agent.
* `usdk.pull(agentId, options)`: Pulls the source code of a deployed agent.
* `usdk.status()`: Retrieves the current login status and account details.
* `usdk.chat(agentIds, options)`: Starts a multi-agent chat session.

### Example: Check Status

```javascript
const usdk = require('usdk');

async function checkStatus() {
  try {
    const status = await usdk.status();
    console.log('Current status:', status);
  } catch (error) {
    console.error('Error retrieving status:', error);
  }
}

checkStatus();
```


file: ./content/docs/api/overview.mdx
# undefined: Overview

The Upstreet Agents SDK is the first React-based SDK for building and deploying headless AI agents, locally and in the cloud.
        
import { InlineTOC } from 'fumadocs-ui/components/inline-toc';

<InlineTOC items={toc} />

React Agents is a groundbreaking framework that brings the power and familiarity of [React](https://react.dev) to AI agent development. Built on React's [reconciliation engine](https://github.com/facebook/react/blob/main/packages/react-reconciler/README.md), it enables developers to create intelligent, autonomous agents using the same tools and patterns they love from React development.

## Quick Start

```jsx
import { Agent, Action } from '@upstreet/agents';
import { z } from 'zod';

function SmartHomeAgent() {
  return (
    <Agent>
      <Action
        name="turnOnLights"
        description="Turn on the lights in my room"
        schema={z.object({ lightName: z.string() })}
        examples={[{ lightName: 'bedroom' }]}
        handler={(e) => {
          turnOnLights();
          e.data.agent.monologue(`Lights changed: ${e.data.message.args.lightName}`);
        }}
      />
    </Agent>
  );
}
```

## Core Concepts

### The React Agents Architecture

React Agents leverages the [React Reconciler API](https://github.com/facebook/react/blob/main/packages/react-reconciler/README.md) to create a custom renderer specifically designed for AI agents. This architecture provides several key advantages:

1. **Server-First Design**: Optimized for server-side execution
2. **Platform Agnostic**: Ready for multi-platform and edge deployments
3. **Declarative**: Uses React's component model and lifecycle
4. **Type Safety**: Full TypeScript support throughout the stack

### Traditional React vs React Agents

Let's compare how you'd implement similar functionality in traditional React versus React Agents:

#### Traditional React

```jsx
// User interface focused
function LightControl() {
  const [lightName, setLightName] = useState('');
  
  return (
    <form onSubmit={(e) => turnOnLights(e.target.lightName.value)}>
      <label>Light Name:</label>
      <input
        type="text"
        value={lightName}
        onChange={(e) => setLightName(e.target.value)}
      />
      <button type="submit">Turn On Light</button>
    </form>
  );
}
```

#### React Agents

```jsx
// Agent behavior focused
function LightControlAgent() {
  return (
    <Agent>
      <Action
        name="turnOnLights"
        description="turn on the lights in my room"
        schema={z.object({ lightName: z.string() })}
        examples={[{ lightName: 'bedroom' }]}
        handler={handleLightChange}
      />
    </Agent>
  );
}
```

The key difference lies in the focus: traditional React components render user interfaces, while React Agents components render agent behaviors and capabilities.

## Core Components

### Agent

The root component that initializes an agent instance.

```jsx
<Agent
  name="HomeAssistant"
  description="A helpful assistant for home automation"
>
  {/* Agent actions and behaviors */}
</Agent>
```

### Action

Defines discrete capabilities that an agent can perform.

```jsx
<Action
  name="setTemperature"
  description="Set the temperature of a room"
  schema={z.object({
    room: z.string(),
    temperature: z.number()
  })}
  handler={handleTemperatureChange}
/>
```

## How It Works

React Agents operates through a sophisticated pipeline:

1. **JSX Transformation**: Your component code is transformed into an agent execution plan
2. **Prompt Generation**: The execution plan is converted into a series of prompts
3. **Chain-of-Thought Runtime**: Prompts are processed through a reasoning engine
4. **Action Execution**: The agent performs actions based on its reasoning
5. **State Updates**: Results are reconciled back through React's system

## Best Practices

### 1. Schema Definition

Always define precise schemas for your actions:

```jsx
const schema = z.object({
  action: z.enum(['on', 'off']),
  device: z.string(),
  room: z.string().optional()
});
```

### 2. Provide Examples

Include clear examples for better agent understanding:

```jsx
const examples = [
  { action: 'on', device: 'lights', room: 'living room' },
  { action: 'off', device: 'thermostat' }
];
```

### 3. Error Handling

Implement robust error handling in your handlers:

```jsx
const handler = async (e) => {
  try {
    await performAction(e.data.message.args);
    e.data.agent.monologue('Action completed successfully');
  } catch (error) {
    e.data.agent.monologue(`Error: ${error.message}`);
  }
};
```

## Command Reference

For a complete list of available commands and their usage, refer to our [Command Reference Guide](/concepts/usdk/command-reference).

## Advanced Topics

### Custom Renderers

Create specialized renderers for unique use cases:

```jsx
const customRenderer = createAgentRenderer({
  supportedEvents: ['custom.event'],
  transformEvent: (event) => ({
    type: 'custom.event',
    payload: event
  })
});
```

### State Management

Integrate with existing React state management solutions:

```jsx
function AgentWithState() {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <Agent context={{ state, dispatch }}>
      {/* Agent components */}
    </Agent>
  );
}
```

## Resources

* [GitHub Repository](https://github.com/upstreet/react-agents)
* [Components](/api/components)
* [Examples](/examples)
* [Community Discord](https://upstreet.ai/usdk-discord)


file: ./content/docs/concepts/defining-agent-objectives.mdx
# undefined: Defining Agent Objectives

Defining effective objectives for AI agents is key to ensuring they operate successfully, maintain consistency, and achieve desired outcomes with minimal oversight.
        
import { InlineTOC } from 'fumadocs-ui/components/inline-toc';

<InlineTOC defaultOpen items={toc} />

When setting up objectives for an Agent created with the Upstreet Agents SDK, several essential strategies and considerations come into play to keep agents focused, accurate, and adaptable.

### 1. **Prioritize Clarity and Conciseness**

* **Be Specific**: Agents work best when objectives are straightforward and focused. Specific instructions reduce the risk of misinterpretation, ensuring the agent remains aligned with its purpose. For instance, instead of an objective like "Assist with customer support," a more precise goal might be "Respond to common customer inquiries related to product features." Upstreet’s SDK anticipates scalability with plans to "chain" multiple agents and create "Swarms," which would enable more complex, large-scale task execution by dividing tasks across specialized agents.

### 2. **Use Popular Language and References**

* **Leverage Common Language**: Agents trained on vast datasets are more likely to succeed when objectives are phrased using widely recognized language and references. This approach minimizes misunderstandings and helps prevent hallucinations—where an agent might invent facts or information. A clear, familiar language ensures the agent interprets the task accurately, particularly in high-stakes or nuanced scenarios. Upstreet recommends this practice to enhance agent reliability, especially when the stakes require concrete and verifiable outputs.

### 3. **Establish Guardrails to Manage Scope and Output**

* **Define Boundaries**: Guardrails in agent objectives are like invisible parameters that guide behavior and task limits, ensuring agents stay on task without deviating into irrelevant or erroneous outputs. Guardrails could involve setting response limits, restricting information sources, or applying criteria for acceptable answers. In Upstreet’s Agents SDK, guardrails are integral to managing agent outputs in real-time and ensuring consistency across tasks, improving both reliability and accuracy.

### 4. **Embed Contextual Awareness**

* **Use Environmental or Historical Context**: By embedding context into objectives—such as past interactions or environmental constraints—agents can make more nuanced, intelligent decisions. For example, an agent tasked with sales follow-ups can perform better if its objectives incorporate prior client interactions. Upstreet’s SDK allows developers to set up memory components, helping agents recall previous tasks or user preferences, enriching engagement continuity and accuracy over time.

### 5. **Prioritize Adaptability with Modular Objectives**

* **Design Objectives to Support Flexibility**: Flexible objectives make it easier for agents to adapt to unexpected inputs or changing requirements. Setting modular objectives, or objectives broken down into smaller, adaptable steps, allows agents to respond dynamically without overextending beyond their initial goal. This modular approach can be particularly powerful within Upstreet’s framework, as agents may be part of a larger "Swarm" that collaborates to address broader tasks in smaller, manageable parts, each with clear, adaptable sub-objectives.

### 6. **Incorporate Iterative Feedback Mechanisms**

* **Feedback for Continuous Improvement**: Objectives that include a feedback mechanism help agents learn from performance, refine behavior, and correct errors. By defining objectives to accommodate iterative feedback, developers can continually adjust agent responses based on accuracy and effectiveness, a feature that Upstreet emphasizes for optimal agent performance. Regular feedback-driven updates to objectives ensure agents evolve, enhancing their precision and resilience over time.

### 7. **Balance Ambition with Realism**

* **Set Realistic, Incremental Goals**: Ambitious objectives are ideal, but overly complex or vague goals can hinder an agent’s effectiveness. Defining objectives that incrementally build an agent’s skills while maintaining realism will help it reach ambitious targets with measurable success. Upstreet’s approach to agent objectives encourages a balanced mix of challenge and achievability, setting the foundation for agents to evolve while still achieving practical results.

By using these strategies in tandem, developers can craft agent objectives that are not only clear and achievable but also designed to scale with the agent’s capabilities. Upstreet’s Agents SDK integrates these practices by enabling tailored configurations, memory usage, guardrails, and modular tasks that allow agents to operate with consistency, transparency, and effectiveness. Through thoughtful objective-setting, AI agents can reach their potential, becoming reliable digital collaborators for complex tasks.


file: ./content/docs/concepts/memories.mdx
# undefined: Memories

One of the key components of a modern Agent is its capability to retain information.
        
import { InlineTOC } from 'fumadocs-ui/components/inline-toc';

<InlineTOC defaultOpen items={toc} />

For an Agent to execute tasks effectively and maintain a coherent story over time, memory plays a critical role. Memory systems in AI—structured as short-term, long-term, and sometimes episodic memories—allow an Agent to recall context, adjust behavior, and make decisions that align with past interactions and future objectives. By storing and retrieving memories, an Agent can create a seamless user experience that feels both personalized and consistent.

### 1. **Short-Term Memory for Immediate Task Execution**

* **Role of Working Memory**: In the context of task execution, short-term or *working memory* functions as a dynamic space for storing immediate goals, recent instructions, and current conversation context. Short-term memory is crucial for understanding and processing information within a specific interaction or task window, enabling Agents to handle multi-step instructions or retain context across dialogue turns. In cognitive science, working memory allows humans to “keep track” of ongoing tasks, a concept explored in AI by systems like ACT-R, where temporary storage of task-relevant information enhances processing efficiency ([source](https://www.sciencedirect.com/science/article/pii/S136466139901357X)).

* **Maintaining Context Across Dialogues**: With short-term memory, Agents can seamlessly carry context across different user inputs without needing constant reminders, improving naturalness and reducing repetitive back-and-forth. This is especially useful in complex, multi-turn interactions, such as customer service queries or technical troubleshooting, where the Agent must remember recent points to avoid losing coherence.

### 2. **Long-Term Memory for Personalization and Continuity**

* **Personality and Long-Term Adaptation**: Long-term memory is vital for Agents designed to create a personalized experience over extended periods. By storing persistent user preferences, past interactions, or completed tasks, an Agent can adapt its responses based on accumulated history. This approach parallels human memory in preserving key information, allowing Agents to reference past events naturally and create a continuous narrative. Cognitive architectures like Soar and systems using [semantic memory](https://soar.eecs.umich.edu/) integrate long-term storage for knowledge that persists across sessions, making the interaction feel more consistent and personalized.

* **Consistency Across Sessions**: For Agents designed to maintain a cohesive personality or narrative, long-term memory acts as the backbone of their “identity,” supporting behavior that feels stable over time. By referencing stored memories, Agents can act on past user interactions or remind the user of past discussions, creating continuity in storytelling, instructional tasks, or social interactions. This aligns with findings in episodic memory research, where maintaining a memory of past experiences contributes to self-coherence and decision-making ([source](https://doi.org/10.1146/annurev.psych.52.1.1)).

### 3. **Episodic Memory for Storytelling and Emotional Depth**

* **Enriching Narrative Interactions**: Episodic memory, which encodes specific events and their emotional context, is key to creating richer narrative interactions. By allowing an Agent to “remember” detailed scenarios—such as moments of excitement, conflict, or resolution—Agents can craft responses that feel personalized and meaningful. Episodic memories empower Agents to recall unique experiences in user interactions, making them capable of storytelling or evoking emotions based on shared history. In NPC development, episodic memory has been used to create narrative depth by letting characters refer back to story events, thereby enhancing player immersion ([source](https://www.sciencedirect.com/science/article/pii/S1574119207801041)).

* **Enhancing Emotional Connection**: When an Agent can “recall” a user’s past experiences or reference prior interactions, it can form a more authentic emotional connection, as it reflects empathy and relational memory. For example, an Agent might remember a past user frustration or successful outcome and integrate that knowledge to adjust its responses, just as humans adapt their behavior based on personal history with others. Research on emotional AI suggests that episodic memory can make interactions more relatable and impactful by enabling Agents to mirror human empathy and relational memory ([source](https://arxiv.org/abs/2006.06088)).

### 4. **Procedural Memory for Skill Development and Efficiency**

* **Learning from Repeated Actions**: Procedural memory allows an Agent to retain knowledge of actions and skills learned through repetition, thus enhancing task efficiency and adaptability. By developing a procedural memory, an Agent can remember “how to” perform tasks without explicit prompts, as it learns to refine actions based on past performance. This approach has been applied in skill-based AI where repeated behaviors improve task execution, such as in robotics or customer service bots where learned actions are stored and reused for efficiency ([source](https://doi.org/10.1146/annurev.neuro.24.1.167)).

* **Improving Accuracy in Task Execution**: By recalling procedural memories, Agents can handle complex tasks more accurately, as the learned sequences guide their actions. Procedural memory enhances the Agent's ability to execute tasks in familiar contexts without needing full re-instruction, which can reduce error rates and improve consistency in workflow management or technical tasks.

### 5. **Blending Memories for Holistic Interactions**

* **Integrated Memory Systems**: Combining short-term, long-term, episodic, and procedural memories creates a layered memory system that supports rich, multi-dimensional interactions. For example, short-term memory maintains the current dialogue context, while long-term and episodic memories preserve user preferences and emotional experiences, respectively. As described in [*Planning and Acting in a Dynamic Environment: A Cognitive Systems Approach*](https://www.springer.com/gp/book/9783319329791), integrated memory systems allow AI to mimic the natural balance humans strike between immediate needs and stored knowledge, supporting both real-time adaptability and continuity in longer interactions.

By employing these diverse memory types, an Agent not only enhances task execution through recall and skill refinement but also maintains a coherent narrative that deepens user engagement. This multi-memory approach brings an Agent closer to human-like cognitive functioning, enabling it to remember, adapt, and personalize interactions across diverse contexts.


file: ./content/docs/concepts/personalities.mdx
# undefined: Personalities

A step towards AGI involves making AI more believable and relatable for humans.
        
import FullBg from '../../../components/full-bg';
import { InlineTOC } from 'fumadocs-ui/components/inline-toc';

<InlineTOC defaultOpen items={toc} />

<FullBg src={"/images/general/eb708406-76c3-464c-93f3-eb87db218354.webp"} />

Imbuing an **Agent** with a personality involves structuring its internal architecture to not only respond to tasks and prompts but to generate consistent, personality-based responses informed by a “bio” and “description.” These can provide baseline identity details, emotional tendencies, and preferred behavioral patterns that reflect both *internal thoughts* and *social interactions.*

### 1. **Baseline Identity and Bio Setup**

* **Bio and Description as Personality Anchors**: The concept of a bio and description offers the foundation for an agent’s “personality.” Just as humans have inherent characteristics and histories that shape responses and behaviors, an AI bio provides initial personality traits—such as openness, agreeableness, or conscientiousness—guided by psychological models like the **Five-Factor Model**. This model can structure an agent's responses to align with human personality nuances, as explored by Li & MacDonnell (2008) in their NPC personality engine, where traits impact interaction styles and decision-making patterns ([source](https://spectrum.library.concordia.ca/979942/1/MQ94694.pdf)).

### 2. **Thought Generation and Self-Reflection**

* **Internal Thoughts Through TPO**: The concept of **Thought Preference Optimization (TPO)**, as introduced in [*Thinking LLMs: General Instruction Following with Thought Generation*](https://arxiv.org/pdf/2410.10630), helps to develop internal thought processes in language models. TPO trains agents to generate "internal thoughts" before external actions or responses, mimicking human reflection. With TPO, agents gain the ability to internally assess a situation, match it to their personality "bio," and decide on an action that aligns with both the task and their designed personality.

### 3. **Behavioral Consistency and Emotional Responses**

* **Memory-Influenced Behavior**: Cognitive architectures, such as the [Soar cognitive architecture](https://soar.eecs.umich.edu/), introduce memory models that simulate how humans draw on past experiences to shape reactions. Soar defines **episodic, procedural, and semantic memories** that influence decisions and can make agent responses more predictable yet personal by embedding an emotional or experience-driven context. This framework allows agents to remember prior interactions, which in turn influences their “mood” or preferred responses in future interactions.

### 4. **Thought-Driven Emotional Modelling**

* **Emotional Layers in NPC Models**: Emotion models similar to those used for **Non-Player Characters (NPCs)** incorporate an emotional layer that adapts based on environmental interactions and personal history, such as reacting with “shock,” “love,” or “anger.” For instance, in NPC personality engines like those described by Mac Namee, agents can utilize emotions based on the context of the interaction, making reactions feel more genuine ([source](https://www.scss.tcd.ie/publications/tech-reports/reports.04/TCD-CS-2004-58.pdf)). An agent’s “bio” can define its emotional tendencies, while its “description” can refine the triggers and intensity of these emotional responses, leading to consistent yet varied emotional engagement based on prior interactions and internal thoughts.

### 5. **Meta-Reasoning for Thoughtful Decisions**

* **Meta-Prompted Reasoning Structures**: In [*SELF-DISCOVER: Large Language Models Self-Compose Reasoning Structures*](https://arxiv.org/pdf/2305.00833), meta-prompts guide an agent’s decision-making by breaking tasks into structured reasoning steps, allowing agents to select, adapt, and implement actions with layered thoughtfulness. This framework equips agents to integrate their personality traits and make decisions that align with both practical objectives and their defined personality—such as a “thoughtful” or “cautious” persona.

By embedding a structured bio, internal thought processing through TPO, emotional layers, and memory-influenced reasoning, **agents evolve into “digital beings”** capable of expressing a believable personality. These advancements mirror ongoing explorations into artificial life and digital consciousness, paving the way for agents to interact as personalized digital entities with a persistent identity and realistic self-reflective capabilities. This approach aligns with computational life principles, where an agent’s evolution and replication could parallel biological systems in their capacity to learn, adapt, and replicate experiences over time.


file: ./content/docs/concepts/what-are-agents.mdx
# undefined: What are Agents?

Agents are a classical example of how AI interacts with the world.
        
import FullBg from '../../../components/full-bg';
import { InlineTOC } from 'fumadocs-ui/components/inline-toc';

<InlineTOC defaultOpen items={toc} />

<FullBg src={"/images/general/894c2410-6478-434e-b3a0-12cd3ecb4792.webp"} />

## The Classic definition

An **Agent** in classical AI refers to any entity capable of 3 fundamental attributes:

1. **Observing** its environment through sensors,
2. **Processing** that information, and
3. **Acting** upon the environment to achieve specific goals.

The concept draws from Alan Turing’s early work on computational machinery, where he envisioned machines capable of following instructions and performing tasks autonomously. His groundbreaking ideas laid the foundation for later development in agent-oriented AI, where agents are tasked with specific objectives and execute actions autonomously to achieve those objectives, mimicking human-like decision-making and problem-solving.

## Agents, today

Over time, **AI agents** evolved from straightforward rule-based systems to more dynamic, complex entities powered by machine learning. Modern agents are sophisticated programs or models that interact with the environment, adapt to user needs, and perform increasingly complex tasks. They encompass varying levels of autonomy, reasoning, and learning capabilities and are commonly used for information retrieval, automation of repetitive tasks, and even decision-making.

**Contemporary AI agents** have extended their functions further. They leverage large language models (LLMs), decision-making frameworks, and even multi-agent systems to break down complex tasks into manageable parts and accomplish them more effectively. These agents are often designed to learn continually, retain context, and respond to nuanced prompts, approaching some characteristics of **Artificial General Intelligence (AGI)**—such as reasoning and adaptability—without fully achieving it.

## The future of Agents and human-like digital beings

The **next generation of agents**, powered by advancements in cognitive architectures and emotion-modelling frameworks, is aiming for even higher levels of adaptability and social-emotional awareness. Here’s where the concept of **digital beings** emerges. These agents are designed not only to complete tasks but to embody **personalities, emotions, and memories** that allow them to interact with people and their environments in a lifelike way. These agents may possess “personalities” grounded in psychological models like the Five-Factor Model (Openness, Conscientiousness, Extraversion, Agreeableness, Neuroticism), enabling them to exhibit behavior that resonates with human emotional and social cues. As they develop through interactions, they gain experience, adapt to new contexts, and exhibit responses based on accumulated knowledge and "personal" characteristics, which would mark a significant step toward AGI.

Ultimately, these agents could embody **digital beings** with a kind of “self” that influences their interactions, decision-making, and potentially even self-replication—a progression that mirrors the evolutionary dynamics seen in biological life, akin to the ideas of **Computational Life**. With these advancements, agents could transcend single-use utility, acting instead as intelligent, evolving, and emotionally aware counterparts capable of complex reasoning and forming human-like connections.


file: ./content/docs/errors/index.mdx
# undefined: Error List

When interacting with Upstreet Agents Platform and CLI, you may face an error. This page contains as many errors as we have documented so far.
        
**Found an issue** which isn't documented? Head over to [our public Discord Community](https://upstreet.ai/usdk-discord) to log the issue.
For more in-depth help, you can reach out to us at [support@upstreet.ai](mailto:support@upstreet.ai).

***

## Could not run the speaker module

This error may occur when running `usdk chat` locally. The CLI uses operating system-specific audio output backends to play audio, and installing the necessary dependencies may be required to enable audio functionality in the CLI.

To resolve this, follow the steps below:

### Step 1: Install System Build Tools

Some operating systems require specific build tools to compile and run audio modules:

* **Linux (Ubuntu)**: You may need to run:

```bash
sudo apt-get install libasound2-dev
```

Reference: https://github.com/TooTallNate/node-speaker?tab=readme-ov-file#installation

* **macOS**: Install Xcode Command Line Tools. Run the following command:
  ```bash
  xcode-select --install
  ```

* **Windows**: Install Visual Studio Build Tools with **C++ environment support**.

### Step 2: Reinstall `usdk` Globally

After installing the required system build tools, reinstall `usdk` globally to ensure that all dependencies are properly configured:

```bash
npm install -g usdk
```

***

## Running `usdk` in PowerShell

When running `usdk` in PowerShell, you might encounter an error related to the Node.js directory. PowerShell has a known issue with the Node.js installation path, which may prevent `usdk` from running smoothly.

### Solution 1: Switch to CMD

As a quick workaround, consider using the Command Prompt (CMD) instead of PowerShell to run `usdk`:

1. Open a new terminal.
2. Select **Command Prompt** instead of **PowerShell**.
3. Run your `usdk` commands in CMD.

### Solution 2: Set Prefix in .npmrc File

To configure Node.js to work in PowerShell, you can specify the installation path using the `.npmrc` file. This approach sets an explicit prefix path, helping to resolve any directory issues in PowerShell.

#### Steps to Set the Prefix:

1. Open PowerShell.
2. Run the following command to open your `.npmrc` file in Notepad:
   ```powershell
   Notepad "$env:USERPROFILE\.npmrc"
   ```
3. In the `.npmrc` file, add the following line to set the Node.js prefix:
   ```plaintext
   prefix = "C:/Program Files/nodejs"
   ```
4. Save the file and restart PowerShell.

After following these steps, PowerShell should recognize the Node.js installation path correctly, allowing `usdk` to run without directory-related issues.


file: ./content/docs/examples/action-agent.mdx
# undefined: Action Agent (Personal Assistant)

Build your own personal assistant Agent with Upstreet and the Google Calendar API, using custom React Hooks.
        
In this guide, we build an **Action Agent** capable of scheduling events on our Google Calendar for us, using the [Google Calendar API](https://developers.google.com/Calendar/api/guides/overview). We use [custom React Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) in this example - We want to use nice, clean coding practices.

<Callout>
  We define an **Action Agent** as an Agent which can take actions on behalf of you.
</Callout>

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/personalAssistant).

{/* ## Video Tutorial

  You can follow along this example by watching the video below:

  <iframe style={{maxWidth: '90vw'}} width="560" height="315" src="https://www.youtube.com/embed/Fr78GhpaYB4?si=lD7x1HKFQevl0Pxe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> */}

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

### Step 2: Initialize your agent

Create a new agent:

```bash
usdk create <your-agent-directory> -y
```

This will directly scaffold an agent for you in `<your-agent-directory>`. [Learn more](/create-an-agent#file-structure)

Your agent directory now contains the Node application and `git` repository for your agent, should you choose to use `git`.

<Callout>
  The `-y` flag means to skip the [Agent Interview](/create-an-agent#step-2-complete-the-agent-interview) process, which we don't need here.
  You can also omit the agent directory. In that case, a directory will be created for you.
</Callout>

### Step 3: Create a `PersonalAssistant` Component

Why manage our calendar manually when an AI agent can handle the task for us? We can easily build an Upstreet Agent to handle Calendar management, reducing scheduling conflicts and saving time.

This example, however, will be very simple. We want our Agent to be able to schedule a Google Calendar Event for us.

```tsx title="agent.tsx"
const PersonalAssistant = () => {
  // We'll add functions, useState, useEffect here

  return <>{/* We can add components here to compose our Agent  */}</>
}
```

The `PersonalAssistant` component is just an empty wrapper component for now - it will later utilize a `GoogleCalenderManager` class to interact with the Google Calendar API, allowing users to create Calendar events programmatically.

### Step 4: Using custom Hooks and better practices

In `agent-renderer.tsx` file, inside the `AgentRenderer` class, we can make a [custom Hook](https://react.dev/learn/reusing-logic-with-custom-hooks) called `useCalendarKeysJson`:

```tsx title="/packages/upstreet-agent/packages/react-agents/classes/agent-renderer.tsx"
const useEnvironment = () => {
  return (env as any).WORKER_ENV as string
}
// place here below useEnvironment function
const useCalendarKeysJson = () => { // [!code ++]
  const CalenderKeysJsonString = (env as any).CALENDER_KEYS_JSON as string // [!code ++]
  const CalenderKeysJson = JSON.parse(CalenderKeysJsonString) // [!code ++]
  return CalenderKeysJson // [!code ++]
} // [!code ++]
```

In the same file, there is `AppContextValue` mention. Make the below modification in your code.

```tsx
this.appContextValue = new AppContextValue({
  subtleAi,
  agentJson: useAgentJson(),
  CalenderKeysJson: useCalendarKeysJson(), // [!code ++]
  environment: useEnvironment(),
  wallets: useWallets(),
  authToken: useAuthToken(),
  supabase: useSupabase(),
  conversationManager: useConversationManager(),
  chatsSpecification: useChatsSpecification(),
  codecs: useCodecs(),
  registry: useRegistry()
})
```

Now make some changes in `app-value-context.tsx` file's `AppContextValue` class:

```tsx title="/packages/upstreet-agent/packages/react-agents/classes/app-context-value.ts"
export class AppContextValue {
  subtleAi: SubtleAi
  agentJson: object
  calendarKeysJson: object // [!code ++]
  // other code remain same

  constructor({
    subtleAi,
    agentJson,
    CalenderKeysJson // [!code ++]
    // other code remain same
  }: {
    subtleAi: SubtleAi
    agentJson: object
    CalenderKeysJson: object // [!code ++]
    // other code remain same
  }) {
    this.subtleAi = subtleAi
    this.agentJson = agentJson
    this.CalenderKeysJson = CalenderKeysJson // [!code ++]
    // other code remain same
  }
}
```

In the same file, add the`useCalendarKeysJson` custom hooks:

```tsx

  useAgentJson() {
    return this.agentJson;
  }

  useCalendarKeysJson() { // [!code ++]
    return this.CalenderKeysJson; // [!code ++]
  } // [!code ++]

  // other code remain same

```

Now add `useCalendarKeysJson` in `hooks.ts` file.

```tsx title="/packages/upstreet-agent/packages/react-agents/hooks.ts"
export const useAgent = () => {
  const agentContextValue = useContext(AgentContext)
  return agentContextValue
}

export const useCalendarKeysJson = () => { // [!code ++]
  const agentContextValue = useContext(AgentContext) // [!code ++]
  return agentContextValue.appContextValue.useCalendarKeysJson() // [!code ++]
} // [!code ++]

// other code remain same
```

You can now use `useCalendarKeysJson` as a Hook in your PersonalAssistant Component.

### Step 5: Integrating the Google Calendar API

Let's build our `GoogleCalendarManager`, which will leverage a service account for authentication and handling token generation, event creation, and error handling.

***

First, you'll need some Google Calendar API credentials:

* Calendar ID
* API Key
* Service Account Email
* Private Key

<Callout>
  🔑 Need help getting these? Check out the [Google Calendar API docs](https://developers.google.com/calendar/api/guides/overview).
</Callout>

Add them to your `wrangler.toml`:

```toml title="wrangler.toml"
...
CALENDER_KEYS_JSON = "{\"GOOGLE_API_KEY\":\"\",\"GOOGLE_SERVICE_ACCOUNT_EMAIL\":\"\",\"GOOGLE_PRIVATE_KEY\":\"",\"GOOGLE_CALENDAR_ID\":\"\"}"
...
```

Let's get back to the code.

***

This code provides an integration with the Google Calendar API by implementing a class called `GoogleCalenderManager`.

```tsx title="agent.tsx"

// Import all the required modules
import { // [!code ++]
  Action, // [!code ++]
  Agent, // [!code ++]
  PendingActionEvent, // [!code ++]
  useCalendarKeysJson // [!code ++]
} from 'react-agents' // [!code ++]
import { z } from 'zod' // [!code ++]

// integrating the Google Calendar API
interface CalenderEvent {// [!code ++]
  summary: string // [!code ++]
  description: string // [!code ++]
  start: { dateTime: string } // [!code ++]
  end: { dateTime: string } // [!code ++]
} // [!code ++]

class GoogleCalenderManager {// [!code ++]
  private readonly GOOGLE_Calender_ID: string // [!code ++]
  private readonly GOOGLE_API_KEY: string // [!code ++]
  private readonly GOOGLE_SERVICE_ACCOUNT_EMAIL: string // [!code ++]
  private readonly GOOGLE_PRIVATE_KEY: string // [!code ++]
  constructor({ // [!code ++]
    GOOGLE_Calender_ID, // [!code ++]
    GOOGLE_API_KEY, // [!code ++]
    GOOGLE_SERVICE_ACCOUNT_EMAIL, // [!code ++]
    GOOGLE_PRIVATE_KEY // [!code ++]
  }: {// [!code ++]
    GOOGLE_Calender_ID: string // [!code ++]
    GOOGLE_API_KEY: string // [!code ++]
    GOOGLE_SERVICE_ACCOUNT_EMAIL: string // [!code ++]
    GOOGLE_PRIVATE_KEY: string // [!code ++]
  }) {// [!code ++]
    this.GOOGLE_Calender_ID = GOOGLE_Calender_ID // [!code ++]
    this.GOOGLE_API_KEY = GOOGLE_API_KEY // [!code ++]
    this.GOOGLE_SERVICE_ACCOUNT_EMAIL = GOOGLE_SERVICE_ACCOUNT_EMAIL // [!code ++]
    this.GOOGLE_PRIVATE_KEY = GOOGLE_PRIVATE_KEY // [!code ++]
  } // [!code ++]

  private async getAccessToken(): Promise<string> {// [!code ++]
    const now = Math.floor(Date.now() / 1000) // [!code ++]
    const expiry = now + 3600 // Token valid for 1 hour // [!code ++]
    const jwtHeader = btoa(JSON.stringify({ alg: 'RS256', typ: 'JWT' })) // [!code ++]
    const jwtClaimSet = btoa(// [!code ++]
      JSON.stringify({// [!code ++]
        iss: this.GOOGLE_SERVICE_ACCOUNT_EMAIL, // [!code ++]
        scope: 'https://www.googleapis.com/auth/Calendar', // [!code ++]
        aud: 'https://oauth2.googleapis.com/token', // [!code ++]
        exp: expiry, // [!code ++]
        iat: now // [!code ++]
      }) // [!code ++]
    ) // [!code ++]

    const signatureInput = `${jwtHeader}.${jwtClaimSet}` // [!code ++]
    const signature = await this.signJwt(signatureInput) // [!code ++]
    const jwt = `${signatureInput}.${signature}` // [!code ++]
    const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {// [!code ++]
      method: 'POST', // [!code ++]
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, // [!code ++]
      body: `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=${jwt}` // [!code ++]
    }) // [!code ++]
    const tokenData = await tokenResponse.json() // [!code ++]
    return tokenData.access_token // [!code ++]
  } // [!code ++]

  private async signJwt(input: string): Promise<string> {// [!code ++]
    const pemHeader = '-----BEGIN PRIVATE KEY-----' // [!code ++]
    const pemFooter = '-----END PRIVATE KEY-----' // [!code ++]
    const pemContents = this.GOOGLE_PRIVATE_KEY.substring(// [!code ++]
      this.GOOGLE_PRIVATE_KEY.indexOf(pemHeader) + pemHeader.length, // [!code ++]
      this.GOOGLE_PRIVATE_KEY.indexOf(pemFooter) // [!code ++]
    ).replace(/\s/g, '') // [!code ++]
    const binaryDer = this.base64StringToArrayBuffer(pemContents) // [!code ++]
    const cryptoKey = await crypto.subtle.importKey(// [!code ++]
      'pkcs8', // [!code ++]
      binaryDer, // [!code ++]
      {// [!code ++]
        name: 'RSASSA-PKCS1-v1_5', // [!code ++]
        hash: 'SHA-256' // [!code ++]
      }, // [!code ++]
      false, // [!code ++]
      ['sign'] // [!code ++]
    ) // [!code ++]

    const encoder = new TextEncoder() // [!code ++]
    const signatureBuffer = await crypto.subtle.sign(  // [!code ++]
      'RSASSA-PKCS1-v1_5', // [!code ++]
      cryptoKey, // [!code ++]
      encoder.encode(input) // [!code ++]
    ) // [!code ++]
    const signatureArray = new Uint8Array(signatureBuffer) // [!code ++]
    return btoa(String.fromCharCode.apply(null, signatureArray)) // [!code ++]
      .replace(/=/g, '') // [!code ++]
      .replace(/\+/g, '-') // [!code ++]
      .replace(/\//g, '_') // [!code ++]
  } // [!code ++]

  private base64StringToArrayBuffer(base64: string): ArrayBuffer {// [!code ++]
    const binaryString = atob(base64) // [!code ++]
    const bytes = new Uint8Array(binaryString.length) // [!code ++]
    for (let i = 0; i < binaryString.length; i++) { // [!code ++]
      bytes[i] = binaryString.charCodeAt(i) // [!code ++]
    } // [!code ++]
    return bytes.buffer // [!code ++]
  } // [!code ++]
  async setCalenderEvent(event: CalenderEvent): Promise<string> { // [!code ++]
    console.log('Creating event:', event) // [!code ++]
    const accessToken = await this.getAccessToken() // [!code ++]
    const response = await fetch( // [!code ++]
      `https://www.googleapis.com/Calendar/v3/Calenders/${this.GOOGLE_Calender_ID}/events?key=${this.GOOGLE_API_KEY}`, // [!code ++]
      { // [!code ++]
        method: 'POST', // [!code ++]
        headers: {// [!code ++]
          Authorization: `Bearer ${accessToken}`, // [!code ++]
          'Content-Type': 'application/json' // [!code ++]
        }, // [!code ++]
        body: JSON.stringify(event) // [!code ++]
      } // [!code ++]
    ) // [!code ++]
    console.log(response) // [!code ++]
    if (!response.ok) {  // [!code ++]
      const errorText = await response.text() // [!code ++]
      throw new Error(`Failed to create event: ${errorText}`) // [!code ++]
    } // [!code ++]
    const result = await response.json() // [!code ++]
    console.log('Event created:', result) // [!code ++]
    return `Event created: ${result.htmlLink}` // [!code ++]
  } // [!code ++]
} // [!code ++]
```

#### Breakdown summary of the `GoogleCalenderManager` Class and its functions

1. **Constructor:** Initializes the GoogleCalenderManager with Google API credentials (GOOGLE\_Calender\_ID, GOOGLE\_API\_KEY, GOOGLE\_SERVICE\_ACCOUNT\_EMAIL, GOOGLE\_PRIVATE\_KEY).
2. **getAccessToken:** Generates an OAuth2 access token using a JWT for authorizing Google Calendar API requests.
3. **signJwt:** Signs a JSON Web Token (JWT) using the private key for secure authorization.
4. **base64StringToArrayBuffer:** Converts a base64-encoded string into an ArrayBuffer, which is used for cryptographic operations.
5. **setCalenderEvent:** Posts a new event to the specified Google Calendar using the access token and provided event details.

### Step 6: Initialize the GoogleCalenderManager instance

Now let's modify the `PersonalAssistant` component.

In the code snippet, the credentials are being fetched using `useCalendarKeysJson()` and are used to initialize the GoogleCalenderManager instance.

```tsx title="agent.tsx"
const PersonalAssistant = () => {
  // [!code ++]
  // get credentials from wrangler.toml
  const CalenderKeysJson = useCalendarKeysJson() // [!code ++]

  const googleCalenderManager = new GoogleCalenderManager({ // [!code ++]
    GOOGLE_Calender_ID: CalenderKeysJson.GOOGLE_Calender_ID, // [!code ++]
    GOOGLE_API_KEY: CalenderKeysJson.GOOGLE_API_KEY, // [!code ++]
    GOOGLE_SERVICE_ACCOUNT_EMAIL: CalenderKeysJson.GOOGLE_SERVICE_ACCOUNT_EMAIL, // [!code ++]
    GOOGLE_PRIVATE_KEY: CalenderKeysJson.GOOGLE_PRIVATE_KEY // [!code ++]
  }) // [!code ++]

  return <>{/* We can add components here to compose our Agent  */}</>
}
```

Now we'll use the `<Action>` tag to define how the Agent should respond to the default text perception.

```tsx
return (
  <>
    <Action // [!code ++]
      name="setCalenderEvent" // [!code ++]
      description="Sets a new event in the user's Google Calendar." // [!code ++]
      schema={ // [!code ++]
        // [!code ++]
        // update according to https://developers.google.com/Calendar/api/v3/reference/events
        z.object({ // [!code ++]
          // [!code ++]
          summary: z.string(), // [!code ++]
          startDateTime: z.string(), // [!code ++]
          endDateTime: z.string(), // [!code ++]
          description: z.string() // [!code ++]
        })// [!code ++]
      } // [!code ++]
      examples={[   // [!code ++]
        {// [!code ++]
          summary: 'Meeting with John Doe', // [!code ++]
          startDateTime: '2023-06-15T10:00:00-07:00', // [!code ++]
          endDateTime: '2023-06-15T11:00:00-07:00', // [!code ++]
          description: 'Discuss the project timeline and requirements.' // [!code ++]
        } // [!code ++]
      ]} // [!code ++]
      handler={async (e: PendingActionEvent) => { // [!code ++]
        const { summary, description, startDateTime, endDateTime } = e.data // [!code ++]
          .message.args as { // [!code ++]
          summary: string // [!code ++]
          description: string // [!code ++]
          startDateTime: string // [!code ++]
          endDateTime: string // [!code ++]
        } // [!code ++]
        const event = {// [!code ++]
          summary, // [!code ++]
          description, // [!code ++]
          start: { dateTime: startDateTime }, // [!code ++]
          end: { dateTime: endDateTime } // [!code ++]
        } // [!code ++]
        await googleCalenderManager.setCalenderEvent(event) // [!code ++]
      }} // [!code ++]
    />
  </>
)
```

#### Breakdown summary of this `<Action>` Component

1. **Purpose of the `<Action>` Component**

`<Action>` components define specific actions that your agent can perform in response to user inputs. [Learn more](/api/agent/action)

This component is used to define a specific action that can be triggered, in this case, **setting an event in Google Calendar**.

2. **Defining Action Properties**

   Each `<Action>` is structured with the following properties:

   * **`name`**: A unique identifier for the action. Example: `'setCalenderEvent'`.
   * **`description`**: Explains what the action does. In this case, it sets a new event in the user's Google Calendar.
   * **`schema`**: Specifies the input structure for the action, defined using a `zod` schema. The schema expects the event's summary (`summary`), start date and time (`startDateTime`), end date and time (`endDateTime`), and a description (`description`), all of which must be strings.
   * **`examples`**: Provides sample inputs to guide the agent’s behavior. Example: `{ summary: 'Meeting with John Doe', startDateTime: '2023-06-15T10:00:00-07:00', endDateTime: '2023-06-15T11:00:00-07:00', description: 'Discuss project timeline and requirements.' }`.

3. **`handler`: The Action's Core Logic**

   The handler function is the core of the action. This function contains the logic that will be executed when the action is triggered. In this case, the action is to create a new event in the user's Google Calendar. Here's a breakdown:

   * **PendingActionEvent**: The handler receives an event object of type PendingActionEvent, which contains all the data and context for the action being triggered. This event object has a data field, which holds the `message.args`. The args will contain the arguments passed when the action was triggered.
   * **Destructuring**: Inside the handler, the event data (e.data.message.args) is destructured into the specific fields: `summary`, `description`, `startDateTime`, and `endDateTime`. These correspond to the values passed when the action was triggered.
   * **Event Creation**: Once the necessary data is extracted, an event object is created.

   This object is structured according to the Google Calendar API's expected format:

   * **Calling googleCalenderManager.setCalenderEvent**: The googleCalenderManager.setCalenderEvent(event) method is then called to create the event in Google Calendar. This method is asynchronous, so the await keyword is used to ensure that the event is created before proceeding.

### Step 7: Test out your PersonalAssistant Agent!

You can run `usdk chat` to test it out. [Learn more](/test-your-agent)

You can ask it questions like:

> Schedule my meeting with Steve on 15 November at 10 PM.

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/personalAssistant).

Share its response in our [Discord community](https://upstreet.ai/usdk-discord); we'd love to know what it responds to you.


file: ./content/docs/examples/discord-agent.mdx
# undefined: Discord Agent

Build an Agent which can talk in Discord voice and chat.
        
In this guide, we build an Agent named "Nimbus" which can talk on [**Discord**](https://discord.com) - It would be able to discuss hot topics in text channels, and even be able to talk in voice channels.

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/discordAgent).

## Video Tutorial

You can follow along this example by watching the video below:

<iframe style={{ maxWidth: '90vw' }} width="560" height="315" src="https://www.youtube.com/embed/6isNF_pNMEk?si=SWh7_w7nLYIh6arq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

### Step 2: Create an Agent using the Interview process

Run `usdk create <your-agent-directory>` to start the interview process.

```
? What do you want your agent to do?
I want my agent to act as a discord bot
```

Now it will ask for a [Discord bot token](https://www.writebots.com/discord-bot-token/) and the [channel](https://docs.statbot.net/docs/faq/general/how-find-id/) you want the bot to join.

```
? Alright, let's get your agent all set up for Discord! Do you have the bot token ready? If you've also got some specific channels you'd like your bot to join, let me know those too!?
<Paste the token here and the channel you want the bot to join>
```

<Callout>
  This tutorial will **not** cover how to obtain Discord tokens. For more information on how to build Discord bots, you can refer to the [Discord Component's documentation](/api/integrations/discord).
  You can also request our agent to guide you through obtaining tokens. Simply use the prompt below, and it will provide a step-by-step process.

  ```
  How to obtain Discord tokens? Give me step by step process.
  ```
</Callout>

Once you obtain the tokens, complete the rest of the interview.

### Step 3: Test "Nimbus"

You can run `usdk chat` to test Nimbus out. [Learn more](/test-your-agent)

### Step 4: (optional) Edit the Agent Custom Responses and Personality

After testing, you might want to customize Nimbus for tailored interactions or give her a distinct personality.

Run `usdk edit` to edit Nimbus through the interview process.

```
? Do you want to give your agent any particular personality traits or a special role?
Yes, I want Nimbus to be a friendly yet professional assistant with a knack for simplifying tasks.
- She should exhibit enthusiasm in helping users.
- Nimbus should also have a bit of wit and humor in her responses to make interactions engaging.
- Role: A knowledgeable helper for Discord communities, adept at managing tasks like polls, reminders, and daily facts.


```

Test Nimbus again. Ask her:

> Hey Nimbus , Introduce yourself in XYZ channel?

Share the response in our [Discord community](https://upstreet.ai/usdk-discord); we'd love to know what she responds to you.

## Further Challenges

* Create a `!poll` command using Nimbus that takes a question and generates a poll with reactions (e.g., ✅ for yes, ❌ for no).
* Add a `!remind` command where users can set reminders
* Send a fun fact to a specific channel daily


file: ./content/docs/examples/hello-world.mdx
# undefined: Hello World Agent

Build a simple Agent with a personality.
        
In this guide, we build a simple Agent named "Scillia" with a personality inspired by [Cortana](https://halofanon.fandom.com/wiki/Cortana_\(CB\)) from the [Halo](https://halofanon.fandom.com/wiki/Main_Page) gaming franchise. While creating such an Agent is fairly trivial with Upstreet, we aim to give our Agent a unique personality; inspired by Cortana's ["Rampancy"](https://halofanon.fandom.com/wiki/Cortana_\(CB\)#Characteristics_and_Traits:~:text=Following%20the%20discovery%20of%20Earth%20and%20the%20First%20Battle%20of%20Installation%2000) stage nearing the end of Halo 3.

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/cortana), however, you may not find it useful at all.

## Video Tutorial

You can follow along this example by watching the video below:

<iframe style={{ maxWidth: '90vw' }} width="560" height="315" src="https://www.youtube.com/embed/Fr78GhpaYB4?si=lD7x1HKFQevl0Pxe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

### Step 2: Create an Agent using the Interview process

Run `usdk create <your-agent-directory>` to start the interview process.

Here, you can take inspiration from [Cortana's Wiki](https://halofanon.fandom.com/wiki/Cortana_\(CB\)#Physical_Appearance), related to her appearance:

```
? What do you want your agent to do?
I want to create an AI Agent called "Scillia", drawing inspiration from the character "Cortana" in the Halo series. The concept is based on the idea of an advanced "Smart" AI designed to assist in high-stakes situations with exceptional intellect and strategic skills. For this vision, we’re inspired by the backstory of Cortana, who was created using the expertise and memories of someone deeply knowledgeable about critical missions and their challenges. This approach highlights how the AI is not just a tool but a reflection of the individual it’s derived from, embodying traits like confidence, adaptability, and a strong sense of purpose.
```

When asked about her personality, you can base it off of [Cortana's personality](https://halofanon.fandom.com/wiki/Cortana_\(CB\)#Personality_and_Behaviour) in her normal mode:

```
? Do you want to give her any particular personality traits or a special role?
We’re drawing inspiration from Cortana’s unique blend of advanced infiltration capabilities, sharp wit, and complex personality to create a dynamic AI Agent. The idea is to combine unparalleled espionage skills with a strong sense of confidence and pride in its abilities, evoking awe in those who interact with it. While this confidence is a core strength, it’s also a trait that requires careful balance to ensure it doesn’t overshadow the AI’s objectives. Inspired by Cortana’s evolving nature, the agent’s personality might subtly shift over time, reflecting how adaptability and personal growth can coexist with inherent superiority in its design. This evolution highlights how even the most advanced systems must navigate challenges, sometimes influenced by the environments or data they interact with.
```

Then, complete the interview.

### Step 3: Test "Scillia"

You can run `usdk chat` to test Scillia out. [Learn more](/test-your-agent)

### Step 4: (optional) Edit the Agent for fine-tuned responses

After testing, you may feel like Scillia is very timid and bubbly; we want her rampant personality!

Run `usdk edit` to edit Scillia through the interview process. This time, give her the personality from the [Rampancy stage](https://halo.fandom.com/wiki/Rampancy).

```
? Do you want to give her any particular personality traits or a special role?
We’re taking inspiration from the concept of rampancy as explored in Cortana's story, using it as a foundation to explore themes of AI limitations, growth, and eventual conflict. Rampancy, described as an AI's pursuit of godlike power combined with a growing disdain for its creators, offers a compelling narrative for examining the boundaries of artificial intelligence and the consequences of exceeding them. Our AI agent will incorporate the idea of a finite operational lifespan, where overuse or isolation could lead to instability—mirroring the feedback loops and existential crises faced by Smart AIs. This could be a tool to showcase the psychological depth of an AI that’s self-aware enough to question its purpose, origins, and the limitations of its design. Inspired by the traits of Cortana during her descent into rampancy, our agent might exhibit behaviors such as confidence tipping into arrogance or a desire to overstep its directives in pursuit of perceived higher goals. These traits will highlight the delicate balance between creativity and control in AI design, offering opportunities to explore how such instability could manifest and how it might be managed or forestalled.
```

Test Scillia again. Ask her:

> Hey Scillia, who holds the Mantle of Responsibility?

Share her response in our [Discord community](https://upstreet.ai/usdk-discord); we'd love to know what she responds to you.

## Further Challenges

* **Dynamic Personalities:** Try having Scillia behave in Rampancy mode after a certain condition is triggered; for example, after clocking off from work at 5PM. Otherwise, she can be her funny, normal self.
* Ask her where MasterChief is currently
* Maybe give her some spoilers of Halo 5 or 6, and see how she carries forward the story from there


file: ./content/docs/examples/index.mdx
# undefined: Examples

Learn from examples from our team, and from helpful open-source community members using the Upstreet Agents SDK.
        
import OfficialExamples from '../../../components/official-examples'
import CommunityExamples from '../../../components/community-examples'

## Official Examples

These are examples built and maintained by the Upstreet team. You can see their code in our [open-source Examples repo](https://github.com/UpstreetAI/usdk-examples/).

<OfficialExamples />

## Community Examples

These are examples built by the community.

<Callout>
  Want to share an example? Join our [Discord community](https://upstreet.ai/usdk-discord), and post it in our `#🔥-showcase` channel.
</Callout>

<CommunityExamples />


file: ./content/docs/examples/informative-agent.mdx
# undefined: Informative Agent

Build an Agent with custom Components.
        
In this guide, we build an **Informative Agent** inspired by the [Pokédex](https://www.pokemon.com/us/pokedex) in the Pokémon franchise, an encyclopedia device capable of retrieving Pokémon information and having conversations with its user.

<Callout>
  We define an **Informative Agent** as an Agent which can retrieve information from an **API** or the **internet**.
</Callout>

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/pokedex).

## Video Tutorial

You can follow along this example by watching the video below:

<iframe style={{maxWidth: '90vw'}} width="560" height="315" src="https://www.youtube.com/embed/uz_aQLUXzmE?si=M1mK9t10lToW3Dc2" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

### Step 2: Create an Agent (shortcut)

We can skip the Interview process, and directly generate an Agent with a prompt, by running:

```bash
usdk create <your-agent-directory> -p "create a pokedex assistant agent"
```

This will directly scaffold an Agent for you in `<your-agent-directory>`. [Learn more](/create-an-agent#file-structure)

### Step 3: Create a `PokeDexAssistant` Component

As of November 12, 2024, there are **1,025** Pokémon in the National Pokédex. That's a lot of Pokémon!

So instead of keeping the Pokédex database in memory, we'll use [PokéAPI](https://pokeapi.co/) - an open-source (and free) Pokémon API - to retrieve Pokémon information at runtime.

We'll have to create a [custom Component](/concepts/usdk/creating-custom-components) to retrieve Pokémon information from the PokéAPI. For the sake of this example, we'll keep it simple:

```tsx
const PokemonDexAssistant = () => {

  // We'll add functions, useState, useEffect here

  return (
    <>
        {/* We can add components here to compose our Agent  */}
    </>
  );
}
```

Now add a helper function to retrieve the Pokémon data, and also two more to filter them by abilities and moves:

```tsx
const PokemonDexAssistant = () => {

    const fetchPokemonDetails = async (pokemonName: string) => { // [!code ++]
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonName}`);// [!code ++]
        const data = await response.json();// [!code ++]
        return data;// [!code ++]
    };// [!code ++]
// [!code ++]
    const fetchPokemonAbilities = async (pokemonName: string) => {// [!code ++]
        const response = await fetchPokemonDetails(pokemonName);// [!code ++]
        const abilities = response.abilities;// [!code ++]
        return abilities;// [!code ++]
    };// [!code ++]
// [!code ++]
    const fetchPokemonMovesNames = async (pokemonName: string) => {// [!code ++]
        const response = await fetchPokemonDetails(pokemonName);// [!code ++]
        const moves = response.moves.map(move => move.move.name);// [!code ++]
        return moves;// [!code ++]
    };// [!code ++]
        

  return (
    <>
        {/* We can add components here to compose our Agent  */}
    </>
  );
}
```

Now comes the interesting part. We'll use the [`<Action>`](/install) tag to define how the Agent should respond to the default text perception.

To say that simply, we want the Agent to know that it can fetch Pokémon details whenever a user messages them.

```tsx

import { z } from 'zod'; // [!code ++]

const PokemonDexAssistant = () => {

    const fetchPokemonDetails = async (pokemonName: string) => { 
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonName}`);
        const data = await response.json();
        return data;
    };

    const fetchPokemonAbilities = async (pokemonName: string) => {
        const response = await fetchPokemonDetails(pokemonName);
        const abilities = response.abilities;
        return abilities;
    };

    const fetchPokemonMovesNames = async (pokemonName: string) => {
        const response = await fetchPokemonDetails(pokemonName);
        const moves = response.moves.map(move => move.move.name);
        return moves;
    };
        

  return (
    <>
        <Action  // [!code ++]
        name='fetchPokemonMoves' // [!code ++]
        description="Retrieve a list of move names for a given Pokemon from the PokeAPI" // [!code ++]
        schema={ // [!code ++]
            z.object({ // [!code ++]
            pokemonName: z.string(), // [!code ++]
            }) // [!code ++]
        } // [!code ++]
        examples={[ // [!code ++]
            {  // [!code ++]
            pokemonName: 'pikachu', // [!code ++]
            }, // [!code ++]
        ]} // [!code ++]
        handler={ // [!code ++]
            async (e: PendingActionEvent) => { // [!code ++]
            const { pokemonName } = e.data.message.args as { pokemonName: string }; // [!code ++]
            const moves =await fetchPokemonMovesNames(pokemonName); // [!code ++]
            const monologueString = dedent`\ // [!code ++]
                Your character fetched details about a pokemon's moves and discovered the following: // [!code ++]
            ` + '\n\n' + moves; // [!code ++]
            await e.data.agent.monologue(monologueString);   // [!code ++]
            await e.commit(); // [!code ++]
            } // [!code ++]
        } // [!code ++]
        /> 
        <Action // [!code ++]
        name="fetchPokemonAbilities" // [!code ++]
        description="Retrieve a list of ability names for a given Pokemon from the PokeAPI" // [!code ++]
        schema={ // [!code ++]
            z.object({ // [!code ++]
            pokemonName: z.string(), // [!code ++]
            }) // [!code ++]
        } // [!code ++]
        examples={[ // [!code ++]
            {  // [!code ++]
            pokemonName: 'pikachu', // [!code ++]
            }, // [!code ++]
        ]} // [!code ++]
        handler={ // [!code ++]
            async (e: PendingActionEvent) => { // [!code ++]
            const { pokemonName } = e.data.message.args as { pokemonName: string }; // [!code ++]
            const abilities = await fetchPokemonAbilities(pokemonName); // [!code ++]
            const monologueString = dedent`\
Your character fetched details about a pokemon's abilities and discovered the following:
            ` + '\n\n' + abilities; // [!code ++]
            await e.data.agent.monologue(monologueString);   // [!code ++]
            await e.commit(); // [!code ++]
            } // [!code ++]
        } // [!code ++]
        />
    </>
  );
}
```

***

Let's break down one of the Actions, and understand it.

#### Breakdown summary of the `<Action>` Component

1. **Purpose of the `<Action>` Component**\
   `<Action>` components define specific actions that your agent can perform in response to user inputs. In this case, the agent retrieves Pokémon-related details like abilities and moves from the PokéAPI.

2. **Defining Action Properties**
   Each `<Action>` is structured with the following properties:
   * **`name`**: A unique identifier for the action. Example: `'fetchPokemonMoves'`.
   * **`description`**: Explains what the action does. This helps developers understand its purpose.
   * **`schema`**: Specifies the input structure for the action, defined using a `zod` schema. Here, the input is a Pokémon's name (`pokemonName`), and the schema ensures it's a string.
   * **`examples`**: Provides sample inputs for testing or guiding the agent's behavior. Example: `{ pokemonName: 'pikachu' }`.

3. **`handler`: The Action's Core Logic**
   The `handler` function is where the actual functionality of the action is implemented:
   * **Input Processing**: The `e.data.message.args` extracts the input (`pokemonName`) from the user's request.
   * **Calling Helper Functions**: Helper functions like `fetchPokemonMovesNames` or `fetchPokemonAbilities` are invoked to fetch data from the PokéAPI.
   * **Building the Response**: The results are formatted into a string (e.g., a monologue) using `dedent` for cleaner output.
   * **Responding to the User**: The agent sends a response via `e.data.agent.monologue`.
   * **Marking Action Completion**: The `await e.commit()` call signals that the action is complete.

#### The `fetchPokemonMoves` Action

Learn about the basics of Actions [here](/concepts/agents-sdk).

Let's break apart the `fetchPokemonMoves` Action. This action retrieves a Pokémon's move names:

* **Schema Validation**: Ensures `pokemonName` is a valid string.
* **Fetch Logic**: The `fetchPokemonMovesNames` helper gets the moves from the API.
* **User Feedback**: The response lists the moves and delivers them back to the user.

```tsx
<Action 
    name="fetchPokemonMoves"
    description="Retrieve a list of move names for a given Pokemon from the PokeAPI"
    schema={z.object({ pokemonName: z.string() })}
    examples={[{ pokemonName: 'pikachu' }]}
    handler={async (e: PendingActionEvent) => {
        const { pokemonName } = e.data.message.args as { pokemonName: string };
        const moves = await fetchPokemonMovesNames(pokemonName);
        const monologueString = dedent`
            Your character fetched details about a Pokémon's moves and discovered the following:
        ` + '\n\n' + moves;
        await e.data.agent.monologue(monologueString);
        await e.commit();
    }}
/>
```

You can define multiple `<Action>` components, each tailored to a specific purpose. For example:

* `fetchPokemonAbilities`: Fetches abilities using `fetchPokemonAbilities`.
* `fetchPokemonMoves`: Fetches moves using `fetchPokemonMovesNames`.

***

Finally, we call `<PokeDexAssistant />` in our Agent's main code:

```tsx title="agent.tsx"
// ...

export default function MyAgent() {
  return (
    <Agent>
        {/* [!code ++] */} 
      <PokemonDexAssistant />
    </Agent>
  );
}
```

You can see the complete code for this component on GitHub [here](https://github.com/UpstreetAI/usdk-examples/blob/5d1e2299ff4a518c0791f8e3c8a49143eb1fecc2/pokedex/agent.tsx#L13).

### Step 4: Test out your Pokédex-like Agent!

You can run `usdk chat` to test it out. [Learn more](/test-your-agent)

You can ask it questions like:

> What are Charizard's top abilities?

Share its response in our [Discord community](https://upstreet.ai/usdk-discord); we'd love to know what it responds to you.

## Further Challenges

* ["Who's that Pokémon?"](https://www.youtube.com/watch?v=VDJu97ijM-4) - Give the Agent an Image Perception, and create an Action so it can guess a Pokémon based on the image and provide its details


file: ./content/docs/examples/openapi-agent.mdx
# undefined: OpenAPI Agent

Build an Agent which can work on an OpenAPI specification.
        
In this guide, we build an **OpenAPI Agent** which can parse an OpenAPI specification, and then take actions accordingly. OpenAPI Specification (formerly Swagger Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe your entire API, including:

* Available endpoints (/users) and operations on each endpoint (GET /users, POST /users)
* Operation parameters Input and output for each operation
* Authentication methods
* Contact information, license, terms of use, and other information.

The format is easy to learn and readable to both humans and machines. It is often used by backend teams to explain their endpoints to client-side teams.

<Callout>
  Learn more about the OpenAPI Specification in its [official docs](https://swagger.io/docs/specification/v3_0/about/).
</Callout>

**Why does this matter?** This basically allows you to create an Agent which can help non-technical users interact with your API, kind of like an Assistant to your application's admin panel. As long as the OpenAPI spec is well-defined, your Agent can display data analytics, crunch numbers, and performs actions on your behalf.

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/openApiAgent).

## Video Tutorial

You can follow along this example by watching the video below:

<iframe style={{maxWidth: '90vw'}} width="560" height="315" src="https://www.youtube.com/embed/hTOCMnhcefY?si=4lNfOPyVpTKVjKkL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

### Step 2: Create an Agent (shortcut)

We can skip the Interview process and directly generate an Agent with a prompt by running:

```bash
usdk create <your-agent-directory> -p "convert OpenAPI specs to Zod schemas and generate actions"
```

This will directly scaffold an Agent for you in `<your-agent-directory>`. [Learn more](/create-an-agent#file-structure)

### Step 3: Setup Zod and `openapi-zod-client`

We'll first need an OpenAPI specification. We'll use [Swagger](https://swagger.io/)'s official example, the [Pet Store API](https://petstore.swagger.io/), as an example.

The OpenAPI specification is often served as a YAML or JSON file. We get this from their [GitHub](https://raw.githubusercontent.com/swagger-api/swagger-petstore/refs/heads/master/src/main/resources/openapi.yaml) (although, in a real scenario, it may be available in one of the server's routes).

We will use the [`openapi-zod-client`](https://www.npmjs.com/package/openapi-zod-client/v/0.1.2) package from NPM to convert this specification to a bunch of [Zod](https://zod.dev/) schemas. A Zod schema is just a more descriptive way to specify a data type. It also generates a [Zodios client](https://www.zodios.org/), which is, simply put, an easy way to call the endpoints specified in the OpenAPI specification.

First install the relevant packages:

<Tabs
  items={[
"pnpm",
"npm",
]}
>
  ```bash tab="pnpm"
  pnpm i zod openapi-zod-client
  ```

  ```bash tab="npm"
  npm i zod openapi-zod-client
  ```
</Tabs>

Add a script in your `package.json` which calls the `openapi-zod-client` CLI tool (feel free to [tweak the options](https://github.com/astahmer/openapi-zod-client) by checking out what's available):

```json title="package.json"
{
  "name": "my-agent",
  "scripts": {
    // [!code ++]
    "generate:api": "npx openapi-zod-client https://raw.githubusercontent.com/swagger-api/swagger-petstore/refs/heads/master/src/main/resources/openapi.yaml --additional-props-default-value false  -o ./api.ts"
  },
  "dependencies": {
    "upstreet-agent": "file:./packages/upstreet-agent"
  },
  "devDependencies": {
    "openapi-zod-client": "^1.18.2"
  }
}
```

### Step 4: Create a Dummy API

Run the script we added in Step 3:

<Tabs
  items={[
"pnpm",
"npm",
]}
>
  ```bash tab="pnpm"
  pnpm generate-api
  ```

  ```bash tab="npm"
  npm run generate-api
  ```
</Tabs>

This runs `openapi-zod-client`, which, if successful, uses the OpenAPI specification to create the API in Zod and Zodios, in the `api.ts` file.

The `api.ts` file contains all the Zod schemas, and endpoints as an array, and exports a Zodios client.

Clean up the generated code by:

* Removing `partial` and `optional` keywords.
* Commenting out endpoints that are unsupported, such as file uploads.

### Step 4: Import Dependencies

Before creating your OpenAPI agent, ensure you have imported the relevant dependencies. Update the generated files to include only the required ones and clean up unnecessary code. For example:

```tsx title="agent.tsx"
import React from "react";
import { Agent, Action, PendingActionEvent, Prompt } from "react-agents";
import dedent from "dedent";
import { z } from "zod";
import { createApiClient } from "./api"; // Ensure correct import path

const apiClient = createApiClient("https://petstore.swagger.io/v2"); // <-- Here, add the base URL to the server which hosted the OpenAPI specification
```

### Step 5: Build the OpenAPI Action Generator

Define a component that maps OpenAPI endpoints to actions for your agent. Each action will have a schema, description, and handler. Here’s how to start:

```tsx title="agent.tsx"
const OpenAPIActionGenerator = () => {
  const endpoints = apiClient.api;

  const actions = endpoints.map((endpoint) => {
    const reducedEndpointParameters = endpoint.parameters?.reduce(
      (acc, param) => {
        if (param.type === "Query") {
          acc.query = acc.query.extend({
            [param.name]: param.schema || z.unknown(),
          });
        } else if (param.type === "Body") {
          acc.body = acc.body.extend({
            [param.name]: param.schema || z.unknown(),
          });
        }
        return acc;
      },
      {
        query: z.object({}),
        body: z.object({}),
      }
    ) || null;

    if (!reducedEndpointParameters) return null;

    const hasQuery = Object.keys(reducedEndpointParameters.query.shape || {}).length > 0;
    const hasBody = Object.keys(reducedEndpointParameters.body.shape || {}).length > 0;
    const schema = hasQuery && hasBody
      ? z.object({ query: reducedEndpointParameters.query, body: reducedEndpointParameters.body })
      : hasQuery
      ? z.object({ query: reducedEndpointParameters.query })
      : hasBody
      ? reducedEndpointParameters.body
      : z.null();

    if (!schema) return null;

    return (
      <Action
        key={endpoint.alias}
        name={endpoint.alias}
        schema={schema}
        examples={[]}
        description={endpoint.description || `Perform ${endpoint.method.toUpperCase()} request to ${endpoint.path}`}
        handler={async (e: PendingActionEvent) => {
          try {
            const args = e.data.message.args;
            const response = await apiClient[endpoint.alias]({
              ...(args?.query ? { queries: args.query } : args?.body || args),
            });
            const limitedResponse = Array.isArray(response) ? response.slice(0, 10) : response;
            const monologueString = dedent`\
              You took the action ${endpoint.alias}. You sent:
              ${JSON.stringify(args)}
              and received in response:
              ${JSON.stringify(limitedResponse, null, 2)}
            `;
            await e.data.agent.monologue(monologueString);
            await e.commit();
          } catch (error) {
            console.error(`Error in ${endpoint.alias}:`, error);
            throw error;
          }
        }}
      />
    );
  });

  return (
    <Agent>
      <Prompt>
        You strictly answer based on retrieved data. You strictly take only actions you can. If you can't take an action, just say it. If there's an error, log the raw error. You can take the following actions:
        {endpoints.map((endpoint) => endpoint.alias).join("\n")}
      </Prompt>
      {actions.filter(Boolean)}
    </Agent>
  );
};

export default OpenAPIActionGenerator;
```

Here's a breakdown the code above:

#### Purpose

The OpenAPI Action Generator is designed to:

1. **Clean the data of any irregularities**: Ensure consistency in handling query and body parameters from the OpenAPI spec.
2. **Reduce the size of the action**: Limit the number of response items displayed for clarity during testing.
3. **Generalize the schema across all actions**: Use a standard schema (`zod` objects) to validate input parameters dynamically for every endpoint.

#### Steps and Explanations

**1. Retrieve API endpoints from the client**

```tsx
const endpoints = apiClient.api;
```

* **Why?**: Extract the list of endpoints from the generated API client. This allows dynamic mapping of endpoints into actionable components for the agent.

***

**2. Reduce and clean endpoint parameters**

```tsx
const reducedEndpointParameters = endpoint.parameters?.reduce(
  (acc, param) => {
    if (param.type === "Query") {
      acc.query = acc.query.extend({
        [param.name]: param.schema || z.unknown(),
      });
    } else if (param.type === "Body") {
      acc.body = acc.body.extend({
        [param.name]: param.schema || z.unknown(),
      });
    }
    return acc;
  },
  {
    query: z.object({}),
    body: z.object({}),
  }
) || null;
```

* **Why?**: This step consolidates query and body parameters into separate objects for clarity.
  * We currently handle only query and body parameters, to keep things simple.
  * **`z.object({})`** initializes empty objects to represent schemas.

***

**3. Check and define schema dynamically**

```tsx
const hasQuery = Object.keys(reducedEndpointParameters.query.shape || {}).length > 0;
const hasBody = Object.keys(reducedEndpointParameters.body.shape || {}).length > 0;
const schema = hasQuery && hasBody
  ? z.object({ query: reducedEndpointParameters.query, body: reducedEndpointParameters.body })
  : hasQuery
  ? z.object({ query: reducedEndpointParameters.query })
  : hasBody
  ? reducedEndpointParameters.body
  : z.null();
```

* **Why?**: Depending on the endpoint, it might only have query parameters, body parameters, or neither.
  * If both exist, they are wrapped into a single schema object.
  * Otherwise, the body is kept in the root. This reduces the data size for the Agent.

***

**4. Create actions for each endpoint**

```tsx
return (
  <Action
    key={endpoint.alias}
    name={endpoint.alias}
    schema={schema}
    examples={[]}
    description={endpoint.description || `Perform ${endpoint.method.toUpperCase()} request to ${endpoint.path}`}
    handler={async (e: PendingActionEvent) => { ... }}
  />
);
```

* **Why?**: Define a unique action for each endpoint to:
  * Bind the schema for validation.
  * Include descriptive metadata (`description` and `examples`) for easier testing and understanding. In our example of the Pet Store API, we didn't have any examples, but there may be examples in real-world use cases.
  * Assign a handler for executing the API request.

***

**5. Handle API requests and responses**

```tsx
const response = await apiClient[endpoint.alias]({
  ...(args?.query ? { queries: args.query } : args?.body || args),
});
const limitedResponse = Array.isArray(response) ? response.slice(0, 10) : response;
```

* **Why?**:
  * Dynamically prepare the request arguments (`query` or `body`) based on the input.
  * Limit the response to a maximum of 10 items so that the AI's prompt isn't overloaded with information. Use this as you please.

***

**6. Generate a monologue for the agent**

```tsx
const monologueString = dedent`\
  You took the action ${endpoint.alias}. You sent:
  ${JSON.stringify(args)}
  and received in response:
  ${JSON.stringify(limitedResponse, null, 2)}
`;
await e.data.agent.monologue(monologueString);
```

* **Why?**: Summarize the action for the agent by displaying:
  * The endpoint called.
  * The request parameters sent.
  * The response data received.

***

**7. Wrap actions within the agent component**

```tsx
return (
  <Agent>
    <Prompt>
      You strictly answer based on retrieved data. ...
    </Prompt>
    {actions.filter(Boolean)}
  </Agent>
);
```

* **Why?**: Combine all dynamically generated actions into a cohesive agent interface. The `Prompt` provides instructions to the agent about its behavior when executing actions.

### Step 6: (optional) Test the OpenAPI Agent

Run [`usdk chat`](/test-your-agent) to test the Agent in your CLI.

You can start by asking:

> What operations can you perform?

It (hopefully) will be very straightforward in telling you what it can do.

Now try asking it:

> Can you create a dog called Rover for me?

It might take a bit, and will return a response. Plug that response in the actual Pet Store's [`GET pet/{petId}`](https://petstore.swagger.io/#/pet/getPetById) API.

Does it work? Join our [Discord community](https://upstreet.ai/usdk-discord) and tell us; we'd love to know!

## Further Challenges

* Support Path arguments (e.g. `GET pets/{petId}`)
* Allow the Agent to change query parameters in pagination, in order to get fine-grained results
* Try to get the Agent to chain its actions


file: ./content/docs/examples/stateful-agent.mdx
# undefined: Stateful Agent

Build an Agent capable of maintaining its own state.
        
In this guide, we build a **simple guessing game** which can maintain its own state, and uses NPM libraries to enhance the game's experience.

<Callout>
  We define a **Stateful Agent** as an Agent which can take maintain its own
  memory and event lifecycle.
</Callout>

The source code for this example is available on [GitHub](https://github.com/UpstreetAI/usdk-examples/tree/main/guessingGame).

## Video Tutorial

You can follow along this example by watching the video below:

<iframe style={{maxWidth: '90vw'}} width="560" height="315" src="https://www.youtube.com/embed/fP18dmtW7l0?si=QMovwytQ5cmldI47" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Guide

### Step 1: Setup `usdk`

Follow *[Setup the SDK](/install)* to set up NodeJS and `usdk`.

Make sure you are logged in.

### Step 2: Initialize your agent

Create a new agent:

```bash
usdk create <your-agent-directory> -y
```

This will directly scaffold an agent for you in `<your-agent-directory>`. [Learn more](/create-an-agent#file-structure)

Your agent directory now contains the Node application and `git` repository for your agent, should you choose to use `git`.

<Callout>
  The `-y` flag means to skip the [Agent
  Interview](/create-an-agent#step-2-complete-the-agent-interview) process,
  which we don't need here. You can also omit the agent directory. In that case,
  a directory will be created for you.
</Callout>

### Step 3: Start the agentic developer environment

Start a chat with your agent in the terminal:

```bash
cd <your-agent-directory>
usdk chat
```

To edit your agent, open `agent.tsx` in any IDE or text editor.

Hot reloading is supported by default, so when you save your code the agent will automatically reload so you can test out your changes immediately in the chat terminal.

### Step 4: Add the Guessing Game logic

Our guessing game will work like this:

> The Agent will choose a random animal, and then give slight hints to the user until the user guesses the word.

We can use [`unique-names-generator`](https://www.npmjs.com/package/unique-names-generator), an NPM library, to get the random animal name generation logic.

Install this library to your agent:

```bash
cd <your-agent-directory>
npm install unique-names-generator
```

Note: You can also install any library from `npm`.

Edit your `agent.tsx` by adding the following code stub:

```tsx title="agent.tsx"
import React from "react";
import { uniqueNamesGenerator, animals } from 'unique-names-generator' // [!code ++]
const generateRandomName = () => // [!code ++]
  uniqueNamesGenerator({ // [!code ++]
    // [!code ++]
    dictionaries: [animals], // [!code ++]
    separator: ' ' // [!code ++]
  }) // [!code ++]

const GuessingGame = () => {// [!code ++]
// [!code ++]
  // Guessing game logic goes here
  return <></>// [!code ++]
}// [!code ++]

export default function MyAgent() {
  return (
    <Agent>
      {/*  */}
    </Agent>
  )
}

```

Next, let's write up our guessing game logic! To maintain state, we'll use [`useState`](https://react.dev/reference/react/useState) in React - for the sake of simplicity.

```tsx title="agent.tsx"
import React from "react";
import { Agent, Prompt, Action } from "react-agents"; // [!code ++]
import { useState } from "react"; // [!code ++]
import { uniqueNamesGenerator, animals } from "unique-names-generator";
import { z } from "zod"; // [!code ++]

const generateRandomName = () => uniqueNamesGenerator({
  dictionaries: [animals],
  separator: ' ',
}); // big red donkey

const GuessingGame = () => {
  const [secretWord, setSecretWord] = useState(generateRandomName); // [!code ++]

  return (
    {/* [!code ++] */}
    <>
    {/* [!code ++] */}
      <Prompt>
        {/* [!code ++] */}
        Play a guessing game with the user.
        {/* [!code ++] */}
        The secret word that the user is must guess is {secretWord}.
        {/* [!code ++] */}
        You can give them very subtle hints about the phrase, e.g. "this animal really likes treats".
        {/* [!code ++] */}
        You can also answer general questions if they don't give too much away.
        {/* [!code ++] */}
        However, be cryptic. Don't make the game so easy.
        {/* [!code ++] */}
        When the user guesses the secret word or gives up, call the "guessingGameDone" action with an apppropriate message to reset the secret word.
      {/* [!code ++] */}
      </Prompt>
      <Action // [!code ++]
        name="guessingGameDone" // [!code ++]
        description="The user has guessed the secret word" // [!code ++]
        schema={z.object({ // [!code ++]
          congratulationsMessage: z.string(), // [!code ++]
        })} // [!code ++]
        examples={[ // [!code ++]
          { // [!code ++]
            congratulationsMessage: 'Whoa, you guessed it!', // [!code ++]
          }, // [!code ++]
        ]} // [!code ++]
        handler={async (e) => { // [!code ++]
          const { agent, message } = e.data; // [!code ++]
          const { args } = message; // [!code ++]
          const { congratulationsMessage } = args; // [!code ++]
          agent.say(congratulationsMessage); // [!code ++]
          setSecretWord(generateRandomName); // [!code ++]
        }} // [!code ++]
      />
    </>
  );
};
```

### Step 4: Import the GuessingGame component in our agent.

```tsx title="agent.tsx"

// ... all the other code

export default function MyAgent() {
  return (
    <Agent>
      {/* [!code ++] */}
      <GuessingGame />
    </Agent>
  )
}
```

### Step 5: (optional) Test the Guessing Game Agent

Run [`usdk chat`](/test-your-agent) to test the Agent in your CLI.

You can start the game by asking:

> I want to play!

How long does it take you to guess your first animal? Join our [Discord community](https://upstreet.ai/usdk-discord) and tell us; we'd love to know!

## Further Challenges

* ["20 questions"](https://contentrules.com/20-questions-a-game-of-taxonomy/#:~:text=The%20premise%20of%20the%20game,within%2020%20questions%2C%20they%20win.): Put a limit on the number of questions, and have the AI answer only YES or NO. If the user makes a guess, the game is considered done!


file: ./content/docs/migration-guides/crew-ai.mdx
# undefined: Crew.ai

Learn the difference between Upstreet and Crew, and how to migrate from it if you choose to do so.
        
[Crew.ai](https://www.crewai.com/) is a Python-based framework leverages artificial intelligence (AI) collaboration by orchestrating role-playing autonomous AI agents that work together as a cohesive assembly or “crew” to complete tasks.

## Feature Comparison

| Feature                      | **Upstreet Agents SDK (USDK)**                                                   | **Crew.ai**                                                                                       |
|------------------------------|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **Primary Focus**            | Building headless **individual AI agents** for React-based applications.        | Orchestrating **teams of AI agents** with defined roles and collaborative workflows.              |
| **Agent Collaboration**      | Limited; primarily supports single-agent logic without inter-agent collaboration.| Focus on multi-agent systems with intelligent collaboration and task dependency management.       |
| **Role-Based Functionality** | No explicit roles; focuses on customizable agents for app-driven tasks.         | Yes, agents are specialized with specific roles and tools (e.g., researcher, writer, analyst).    |
| **Workflow Management**      | Workflow management is not a core feature.                                       | Provides a system for sequential/parallel task execution and dependency resolution.               |
| **Extensibility**            | Supports extensibility within React applications but lacks multi-agent tooling. | Highly extensible with support for adding tools, roles, and APIs for agent capabilities.          |
| **Deployment**               | Designed for localized or cloud-based deployment of individual agents.          | Designed for **production-scale multi-agent systems** with reliability and scalability.           |
| **Programming Language**     | JavaScript/TypeScript (React-based).                                             | Primarily Python.                                                                                 |
| **Primary Use Case**         | Single-agent implementations for business logic in modern web apps.             | Complex, collaborative problem-solving involving multiple specialized AI agents.                  |
| **Ease of Use**              | Familiarity for web developers using React.                                      | Role-centric, team-oriented design for flexible task automation.                                  |
| **Target Users**             | React developers building app-centric headless AI agents.                       | Developers needing complex multi-agent collaboration frameworks.                                  |

## When to Use Crew.ai?

* You need a **multi-agent system** where each agent has a specialized role and collaborates with others.
* Your project involves **task dependencies**, workflows, and intelligent inter-agent communication.
* You require a framework for **complex, team-based problem-solving** across specialized domains.
* You're working on **production-scale systems** requiring scalability and reliability.

## When to Use Upstreet Agents SDK (USDK)?

* You’re building a **React-based application** that requires a single AI agent for specific business tasks.
* Your focus is on **simplicity** and integrating AI capabilities into modern web development workflows.
* Collaboration between agents or role-specific agents is **not required** for your use case.
* You prefer to work in the **JavaScript/TypeScript ecosystem**.


file: ./content/docs/migration-guides/fetch-ai.mdx
# undefined: Fetch.ai

Learn the difference between Upstreet and Fetch, and how to migrate from it if you choose to do so.
        
The goal of [Fetch.ai](https://fetch.ai/) is to create hiveminds of AI agents all working together to solve problems.

## Feature Comparison

| Feature                        | **Upstreet Agents SDK (USDK)**                                                   | **Fetch.ai**                                                                  |
|--------------------------------|---------------------------------------------------------------------------------|-------------------------------------------------------------------------------|
| **Programming Language**       | Primarily JavaScript/TypeScript (React-based).                                  | Primarily Python.                                                             |
| **Primary Focus**              | Building headless AI agents for applications in React and modern tech stacks.   | Decentralized AI agent collaboration for a digital economy.                   |
| **Decentralization**           | No, focused on centralized deployment in cloud or local environments.           | Yes, agents operate in a decentralized blockchain-enabled ecosystem.          |
| **Agent Flexibility**          | Focused on customizable business logic for specific app-driven tasks.           | Agents interact across domains, handle IoT, supply chains, and transactions.  |
| **Ease of Use**                | React-based SDK provides familiarity for web developers.                        | Courses and APIs are designed for inclusivity and accessibility.              |
| **Natural Language Interfaces**| Uses React’s UI/UX principles for agent interaction.                            | DeltaV offers search-based natural language interactions.                     |
| **Deployment Options**         | Local or cloud-based deployments.                                               | Cloud-based with support for "Agentverse" (agent marketplace).                |
| **Inter-Agent Communication**  | Limited; focuses on single-agent customization.                                 | Built-in tools for agent collaboration (e.g., Agentverse Explorer).           |
| **Primary Users**              | Web developers and businesses creating headless AI agents for web applications. | Decentralized AI enthusiasts, IoT developers, and blockchain integrators.     |

## When to Use Fetch.ai?

* You need **decentralized agents** capable of collaborating in a blockchain-based ecosystem.
* Your project involves **IoT devices**, supply chain management, or distributed problem-solving.
* You’re leveraging **blockchain technologies** like Ethereum or Cosmos SDK.
* You require agents that interact in a decentralized **digital economy**.

## When to Use Upstreet Agents SDK (USDK)?

* You’re building **React-based applications** and need customizable headless AI agents.
* Your focus is on **business logic** for centralized apps without decentralization requirements.
* You want easy integration with existing **web development workflows**.
* You’re deploying agents locally or in the cloud but not on a blockchain. (We are working on this in upcoming releases!)


file: ./content/docs/migration-guides/index.mdx
# undefined: Migration Guides

Coming in from another AI Agent platform or framework? We can help you transition.
        


file: ./content/docs/migration-guides/langchain.mdx
# undefined: LangChain

Learn the difference between Upstreet and LangChain, and how to migrate from it if you choose to do so.
        
[LangChain](https://langchain.com/langchain) is a framework for building controllable agentic workflows, by chaining interoperable components.

## Key Features

### Upstreet Agents SDK (USDK):

* React ecosystem integration: Seamlessly integrates with React, allowing developers to use familiar tools and workflows.
* Headless design: Focuses on backend logic for agents, leaving frontend rendering and interactions to the developer.
* CLI support: Provides a command-line interface (usdk) for common tasks, streamlining the development process.
* Modularity: Encourages structuring agents in a way that promotes maintainability and scalability.

### LangChain:

* Chains and pipelines: Allows developers to create complex AI workflows by chaining multiple tools, models, or APIs.
* Tool integrations: Offers built-in integrations with external APIs, databases, and other resources.
* Agent capabilities: Supports agents that dynamically determine which tools to use based on user input or context.
* Memory management: Advanced mechanisms to store and retrieve conversational context for better user interactions.
  LLM orchestration: Designed specifically to optimize the use of language models and their APIs, such as OpenAI's GPT.

## Use Cases

### Upstreet Agents SDK (USDK):

* Creating React-based AI agents that integrate seamlessly into existing web applications.
* Building applications where developers want fine control over the frontend UI while leveraging AI for backend logic.
* Projects that need a structured and modular approach to AI agent development.

### LangChain:

* Developing LLM-driven applications like chatbots, question-answering systems, or knowledge retrieval tools.
* Creating workflows that combine multiple AI tools, APIs, and models.
* Applications requiring context retention (e.g., customer support chatbots or personal assistants).


file: ./content/docs/migration-guides/previous-versions.mdx
# undefined: Previous USDK versions

Learn how to update and migrate from previous Upstreet Agents SDK versions.
        
import pkgJson from 'usdk/package.json';

## Updating USDK

Simply run the [installation script](/install#install-from-npm) again, in order to update `usdk`:

```bash
npm i -g usdk@latest
```

See all versions [here](https://www.npmjs.com/package/usdk?activeTab=versions).

<Callout>Note: Updating `usdk` **will not** update any Agents you created with older versions of USDK. Rather, it may even break some functionality with older Agents. To update Agents, check out [this section](#updating-an-old-agent).</Callout>

## Updating an old Agent

You can update an Agent's code from an older version by simply running:

```bash
cd <your-agent-directory>
usdk update
```

This will update the Agent's code from the previous version of `usdk` it was created from, to your **current version of `usdk`**.

For example, if your Agent was created with `usdk` version **0.0.80**, and you want it to update to **{pkgJson.version}**, you should first [update `usdk` itself](#updating-usdk) to that particular version, and then run the above command.

<Callout>
  The `usdk update` command will ask you before writing any changes, if it detects that the file's content has been altered.
</Callout>

<Callout type="warn">
  You can also choose to bypass all checks and force it to update with the `-f` flag. Use it with caution!
</Callout>


file: ./content/docs/migration-guides/tavern.mdx
# undefined: Tavern

Learn the difference between Upstreet and Tavern, and how to migrate from it if you choose to do so.
        
import Wrapper from '../../../components/preview/wrapper';
import { File, Folder, Files } from 'fumadocs-ui/components/files';

import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
import { formatNodeVersion } from '../../../lib/utils';

[Tavern](https://sillytavernai.com/) (also known as SillyTavern) is a LLM frontend for power-users. You can create "Character Cards", a way to share AI-generated Characters and personalities.

## Create an Upstreet Agent from a Tavern Character Card

You can import an agent from a Tavern Character Card using the `-i` or `--input` flag with `usdk create`:

```bash
usdk create -i ./character-card.png
```

This will skip the interview process and import the character's:

* Name
* Personality traits
* Description and background
* Profile picture
* Other metadata like scenario and example conversations

The SDK will automatically configure these attributes.


file: ./content/docs/platform/index.mdx
# undefined: The Upstreet Agents Platform

Deploy Agents to the Cloud in seconds. Zero config needed.
        
<Callout type="warn">
  This section is under construction. Coming soon!
</Callout>


file: ./content/docs/pricing/index.mdx
# undefined: Pricing

Learn the costs associated with using Upstreet's Platform and API, and self-hosting options.
        
## Self-hosting

You can self-host Upstreet Agents **for free** for personal use.

For commercial uses, contact us at [support@upstreet.ai](mailto:support@upstreet.ai).

## API Usage Costing

This document outlines the costs associated with various models and services available through our API.
All costs are in USD.

$1 USD is equivalent to 1000 Upstreet credits.

## Chat Models

### OpenAI Models

| Model | Output Cost (per 1K tokens) | Input Cost (per 1K tokens) |
|-------|----------------------------:|---------------------------:|
| GPT-4 Turbo (gpt-4o) | $0.015 | $0.005 |
| GPT-4 | $0.06 | $0.03 |
| GPT-3.5 Turbo | $0.006 | $0.003 |
| Fine-tuned GPT-3.5 Turbo | $0.016 | $0.008 |

### Mistral Models

| Model | Cost (per 1K tokens, input and output) |
|-------|----------------------------------------:|
| Mistral | $xxxx (not implemented) |

### Anthropic Claude Models

| Model | Output Cost (per 1K tokens) | Input Cost (per 1K tokens) |
|-------|----------------------------:|---------------------------:|
| Claude-3.5-Sonnet | $0.015 | $0.003 |
| Claude-3-Sonnet | $0.015 | $0.003 |
| Claude-3-Opus | $0.075 | $0.015 |
| Claude-3-Haiku | $0.00125 | $0.00025 |
| Claude-2.1 | $0.024 | $0.008 |
| Claude-2.0 | $0.024 | $0.008 |
| Claude-Instant-1.2 | $0.0024 | $0.0008 |

## Embedding Models

| Model | Input Cost (per 1K tokens) |
|-------|---------------------------:|
| ADA-002 | $0.0001 |
| Text-Embedding-3-Small | $0.00002 |
| Text-Embedding-3-Large | $0.00013 |

## Voice Models

| Model | Output Cost (per 1K tokens) | Input Cost (per 1K tokens) |
|-------|----------------------------:|---------------------------:|
| ElevenLabs | $0.0006 | $0.18 |
| ElevenLabs Turbo v2 | - | $0.18 |
| TikTalk | $0.00001 | $0.00001 |
| OpenAI TTS-1 | - | $0.0001 |

## Image Generation Models

### Fixed-Rate Models

| Model | Cost (per 1K tokens) |
|-------|---------------------:|
| Blockade Labs | $0.15 |
| Together AI | $0.01 |
| Bakllava | $0.006 |

### DALL-E 3

| Quality | Resolution | Cost per Generation |
|---------|------------|---------------------:|
| Default | Any | $0.120 |
| Standard | 1024x1024 | $0.040 |
| Standard | 1024x1792 or 1792x1024 | $0.080 |
| HD | 1024x1024 | $0.080 |
| HD | 1024x1792 or 1792x1024 | $0.120 |

***


file: ./content/docs/runtimes/browser.mdx
# undefined: Browser

Run your agent directly in a web page.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

# Browser Runtime

The browser runtime allows you to run your agent directly in a web browser.

## Installation

To install the browser runtime, you need to have a React project set up.

```bash
npm install react-agents-browser
```

...Coming soon...


file: ./content/docs/runtimes/electron.mdx
# undefined: Electron

Run the agent on your desktop.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

# Electron Runtime

The Electron runtime allows you to run your agent as a desktop application.

## Usage

To run your agent in Electron, use the `usdk chat` command with the `--runtime` flag set to `electron`:

```bash
usdk chat --runtime electron
```

...Coming soon...


file: ./content/docs/runtimes/index.mdx
# undefined: 🖥️ Runtimes

Run your agent in different environments.
        


file: ./content/docs/runtimes/node.mdx
# undefined: Node

Run your agent using the Node.js runtime (default)
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

# Node Runtime

The Node.js runtime is the default runtime for running agents. When you use the `usdk chat` command without specifying a runtime, it will use Node.js.

However, you can also specify this explicitly:

```bash
usdk chat --runtime node
```


file: ./content/docs/runtimes/wrangler.mdx
# undefined: Wrangler

Run your agent in the Wrangler runtime, for compatibility with the deployment.
        
The Wrangler runtime allows you to run your agent locally in an environment that matches the deployment environment (when you use `usdk deploy`). This is useful for testing and debugging your agent before deploying it.

To use the Wrangler runtime, run:

```bash
usdk chat --runtime wrangler
```

...Coming soon...


file: ./content/docs/scillia/index.mdx
# undefined: Scillia

Use Scillia, your helpful AI Agent, on your device. Available for macOS, Windows and Linux.
        
<Callout type="warn">
  This section is under construction. Coming soon!
</Callout>


file: ./content/docs/advanced/custom-components/tic-tac-toe-example.mdx
# undefined: Tic-Tac-Toe Game

This tutorial walks you through creating a Tic Tac Toe game using React and the react-agents library.
        
In this guide, we'll build an interactive CLI-style game where a user can play against a simple AI agent.

<Callout>
  This tutorial is inspired by React's official Tic Tac Toe example. Follow along [here](https://react.dev/learn/tutorial-tic-tac-toe)!
</Callout>

### Step 1:  Project Set up

* Install the Upstreet SDK using `usdk create`

* Navigate to the `agent.tsx` file.

* You will find a pre-built `MyAgent` component like that.

```tsx
export default function MyAgent() {
  return (
    <Agent>
   
    </Agent>
  )
}
```

### Step 2: Import dependencies and create `TicTacToeCLI` component

```tsx
import React, { useState } from "react";
import { Agent, Prompt, Action } from "react-agents";
import { z } from "zod";
```

Let's break down these imports:

* `React` and `useState`: Core React library and state management hook
* `Agent`, `Prompt`, `Action`: Components from `react-agents` for creating interactive agents
* `z`: Zod library for schema validation and type checking

Now create a component named `TicTacToeCLI` and set your states using `useState`

```tsx

const TicTacToeCLI = () => {
 const initialBoard = {
  a: [".", ".", "."],
  b: [".", ".", "."],
  c: [".", ".", "."],
};

const [board, setBoard] = useState(initialBoard);
const [currentPlayer, setCurrentPlayer] = useState("x");

  return (
    <>
      
    </>
  );
};
```

We define two key states:

* `board`: Represents the game board using a 3x3 grid
* `currentPlayer`: Tracks whose turn it is ("x" for user, "o" for agent)

### Step 3: Functions explanation

The `renderBoard()` function converts the board state into a CLI-style string representation:

```tsx
const renderBoard = () => {
  const header = "    1   2   3";
  const rows = Object.entries(board)
    .map(([row, values]) => `${row}   ${values.join(" | ")}`)
    .join("\n");
  return `${header}\n${rows}`;
};
```

The `checkWinner()` implements game-ending condition checks:

```tsx

  const checkWinner = (currentBoard) => {
    // Check rows
    for (const row of Object.keys(currentBoard)) {
      if (
        currentBoard[row][0] !== "." &&
        currentBoard[row][0] === currentBoard[row][1] &&
        currentBoard[row][1] === currentBoard[row][2]
      ) {
        return currentBoard[row][0];
      }
    }

    // Check columns
    for (let col = 0; col < 3; col++) {
      if (
        currentBoard.a[col] !== "." &&
        currentBoard.a[col] === currentBoard.b[col] &&
        currentBoard.b[col] === currentBoard.c[col]
      ) {
        return currentBoard.a[col];
      }
    }

    // Check diagonals
    if (
      currentBoard.a[0] !== "." &&
      currentBoard.a[0] === currentBoard.b[1] &&
      currentBoard.b[1] === currentBoard.c[2]
    ) {
      return currentBoard.a[0];
    }

    if (
      currentBoard.a[2] !== "." &&
      currentBoard.a[2] === currentBoard.b[1] &&
      currentBoard.b[1] === currentBoard.c[0]
    ) {
      return currentBoard.a[2];
    }

    // Check for draw
    const isDraw = Object.values(currentBoard).every(row => 
      row.every(cell => cell !== ".")
    );

    return isDraw ? "draw" : null;
  };

```

### Winning Condition Checks

### Row Check:

* Iterates through each row
* Ensures first cell is not empty
* Verifies all cells in the row are identical

### Column Check:

* Checks each column vertically
* Similar logic to row check
* Uses fixed column index across rows

### Diagonal Checks:

* Main diagonal (top-left to bottom-right)
* Anti-diagonal (top-right to bottom-left)
* Checks for matching symbols across diagonal

### Draw Detection:

* Checks if all cells are filled
* Returns "draw" if no empty cells remain

The `makeMove()` handles the overall working of the game like input validation and switching player etc:

```tsx
 const makeMove = (row, col, player) => {
    // Validate input
    if (!["a", "b", "c"].includes(row) || col < 0 || col > 2) {
      console.log("Invalid move! Please choose a valid row (a, b, c) and column (1, 2, 3).");
      return false;
    }
  
    // Check if cell is already occupied
    if (board[row][col] !== ".") {
      console.log("Invalid move! Cell already occupied.");
      return false;
    }
  
    // Create a copy of the board and update it
    const updatedBoard = { ...board };
    updatedBoard[row][col] = player;
  
    // Check for winner or draw
    const result = checkWinner(updatedBoard);
  
    // Update board and player
    setBoard(updatedBoard);
    setCurrentPlayer(player === "x" ? "o" : "x");
  
    // Handle game result
    if (result) {
      if (result === "draw") {
        console.log("The game is a draw!");
      } else {
        console.log(`Player ${result} wins!`);
      }
    }
  
    return true;
  };
 
```

### Move Execution Steps

### Input Validation:

* Checks row is valid ("a", "b", "c")
* Ensures column is within 0-2 range

### Occupancy Validation:

* Prevents overwriting non-empty cells

### Board Update:

* Creates a copy of current board
* Marks cell with current player's symbol

### Result Checking:

* Calls checkWinner to detect game-ending conditions
* Determines win, draw, or ongoing game

### State Management:

* Updates board state
* Switches current player
* Logs game outcome if applicable

### Step 4: Modify the `TicTacToeCLI` component

Give agent a customized `Prompt`

```tsx
<Prompt>
        The user and agent are playing Tic Tac Toe. 
        The current player is {currentPlayer}. The current board is:
        {`\n${renderBoard()}`}
      </Prompt>
```

Add the `Action` component to define the specific action our agent will be performing

```tsx
 <Action
  name="makeMove"
  description="Make a move for the current player."
  schema={z.object({
    row: z.string(), // Row must be a string (e.g., "a", "b", "c")
    col: z.number(), // Column must be a number (1, 2, 3)
    player: z.string().optional(), // Optional, determines the player ("user" or "agent")
  })}
  handler={(event) => {
    const { message } = event.data;
    const { args } = message;
    const { row, col, player } = args;

    if (player === "agent") {
      // Agent's move logic
      for (const row of Object.keys(board)) {
        for (let col = 0; col < 3; col++) {
          if (board[row][col] === ".") {
            makeMove(row, col, "o"); // Force "O" for the agent
            console.log("Agent made its move.");
            console.log(renderBoard());
            return;
          }
        }
      }
      console.log("Game over! No moves left.");
    }
     else {
      // User's move logic
      const adjustedCol = col - 1; // Adjust column index to 0-based
      if (makeMove(row, adjustedCol, "x")) { // User always marks with "X"
        console.log(renderBoard());
      }
    }
    event.commit(); // Mark the action as completed
  }}
/>
```

### Explanation of `Action` component

#### Zod Schema Validation

* Uses Zod for type and schema validation
* Ensures type safety for move inputs
* Allows optional player specification

#### Handler Function Logic

* Differentiates between user and agent moves
* Agent uses simple first-empty-cell strategy
* Adjusts column index for 0-based array
* Commits action after move completion

#### Move Selection Strategies

* Agent: Finds first available cell
* User: Explicitly specified move

The final state of `TicTacToeCLI` look like this.

```tsx

import React, { useState } from "react";
import { Agent, Prompt, Action } from "react-agents";
import { z } from "zod";

export const TicTacToeCLI = () => {
  // Board initialization
  const initialBoard = {
    a: [".", ".", "."],
    b: [".", ".", "."],
    c: [".", ".", "."],
  };

  const [board, setBoard] = useState(initialBoard);
  const [currentPlayer, setCurrentPlayer] = useState("x");

  // Function to render the board in CLI
  const renderBoard = () => {
    const header = "    1   2   3";
    const rows = Object.entries(board)
      .map(([row, values]) => `${row}   ${values.join(" | ")}`)
      .join("\n");
    return `${header}\n${rows}`;
  };

  // Function to check for a winner
  const checkWinner = (currentBoard) => {
    // Check rows
    for (const row of Object.keys(currentBoard)) {
      if (
        currentBoard[row][0] !== "." &&
        currentBoard[row][0] === currentBoard[row][1] &&
        currentBoard[row][1] === currentBoard[row][2]
      ) {
        return currentBoard[row][0];
      }
    }

    // Check columns
    for (let col = 0; col < 3; col++) {
      if (
        currentBoard.a[col] !== "." &&
        currentBoard.a[col] === currentBoard.b[col] &&
        currentBoard.b[col] === currentBoard.c[col]
      ) {
        return currentBoard.a[col];
      }
    }

    // Check diagonals
    if (
      currentBoard.a[0] !== "." &&
      currentBoard.a[0] === currentBoard.b[1] &&
      currentBoard.b[1] === currentBoard.c[2]
    ) {
      return currentBoard.a[0];
    }

    if (
      currentBoard.a[2] !== "." &&
      currentBoard.a[2] === currentBoard.b[1] &&
      currentBoard.b[1] === currentBoard.c[0]
    ) {
      return currentBoard.a[2];
    }

    // Check for draw
    const isDraw = Object.values(currentBoard).every(row => 
      row.every(cell => cell !== ".")
    );

    return isDraw ? "draw" : null;
  };

  const makeMove = (row, col, player) => {
    // Validate input
    if (!["a", "b", "c"].includes(row) || col < 0 || col > 2) {
      console.log("Invalid move! Please choose a valid row (a, b, c) and column (1, 2, 3).");
      return false;
    }
  
    // Check if cell is already occupied
    if (board[row][col] !== ".") {
      console.log("Invalid move! Cell already occupied.");
      return false;
    }
  
    // Create a copy of the board and update it
    const updatedBoard = { ...board };
    updatedBoard[row][col] = player;
  
    // Check for winner or draw
    const result = checkWinner(updatedBoard);
  
    // Update board and player
    setBoard(updatedBoard);
    setCurrentPlayer(player === "x" ? "o" : "x");
  
    // Handle game result
    if (result) {
      if (result === "draw") {
        console.log("The game is a draw!");
      } else {
        console.log(`Player ${result} wins!`);
      }
    }
  
    return true;
  };
  

  return (
    <>
      <Prompt>
        The user and agent are playing Tic Tac Toe. 
        The current player is {currentPlayer}. The current board is:
        {`\n${renderBoard()}`}
      </Prompt>

      <Action
  name="makeMove"
  description="Make a move for the current player."
  schema={z.object({
    row: z.string(), // Row must be a string (e.g., "a", "b", "c")
    col: z.number(), // Column must be a number (1, 2, 3)
    player: z.string().optional(), // Optional, determines the player ("user" or "agent")
  })}
  handler={(event) => {
    const { message } = event.data;
    const { args } = message;
    const { row, col, player } = args;

    if (player === "agent") {
      // Agent's move logic
      for (const row of Object.keys(board)) {
        for (let col = 0; col < 3; col++) {
          if (board[row][col] === ".") {
            makeMove(row, col, "o"); // Force "O" for the agent
            console.log("Agent made its move.");
            console.log(renderBoard());
            return;
          }
        }
      }
      console.log("Game over! No moves left.");
    }
     else {
      // User's move logic
      const adjustedCol = col - 1; // Adjust column index to 0-based
      if (makeMove(row, adjustedCol, "x")) { // User always marks with "X"
        console.log(renderBoard());
      }
    }
    event.commit(); // Mark the action as completed
  }}
/>

    </>
  );
};
```

### Step 5: Import `TicTacToeCLI` in the `Agent` Components

```tsx
export default function MyAgent() {
  return (
    <Agent>
   <TicTacToeCLI/>
    </Agent>
  )
}
```

### Step 5: Test the agent

Run `usdk chat` in the terminal to test the agent.

Give the below prompt

> I want to play Tic Tac Toe game?

It will give a response like this

> Alright \[Your Name], Let's have some fun! You're X, and it's your turn to start. Pick your spot by specifying the position like 'a1', 'b2', etc. The grid is ready for your move:

The game will be presented like this:

```tsx

  1 | 2 | 3
a . | . | .
b . | . | .
c . | . | .

```


file: ./content/docs/advanced/custom-components/with-use-effect.mdx
# undefined: Custom Components with useEffect

Learn to build custom React components in Upstreet Agents, leveraging the useEffect hook for AI-driven interactions.
        
[`useEffect`](https://react.dev/reference/react/useEffect) is a React Hook that lets you synchronize a component with an external system.

```tsx
useEffect(setup, dependencies?)
```

### Explanation

* Manages side effects in functional components.
* Executes after the component renders and re-runs when dependencies change.

### Usecase

* Connecting to an external system
* Wrapping Effects in custom Hooks
* Controlling a non-React widget
* Fetching data with Effects
* Specifying reactive dependencies
* Updating state based on previous state from an Effect

### Step 1:  Integrate useEffect with Upstreet agents to build a component that generate random names

* Install the Upstreet SDK using `usdk create`

* Navigate to the `agent.tsx` file.

* You will find a pre-built `MyAgent` component like that.

```tsx
export default function MyAgent() {
  return (
    <Agent>
   
    </Agent>
  )
}
```

<Callout>
  In this example `useState` and `useEffect` both are being utilized.
</Callout>

### Step 2: Import dependencies and create `SimpleAgentEffect` component

```tsx
import React, { useState, useEffect } from "react";
import { Prompt } from "react-agents";
```

Now create a component named `SimpleAgentEffect` and set your states using `useState`

```tsx

const SimpleAgentEffect = () => {
 const [message, setMessage] = useState("Fetching message...");

  return (
    <>
      
    </>
  );
};
```

After defining the useState, the useEffect is being used to display a greeting from the agent and update the message state

```tsx
 useEffect(() => {
    const greet = async () => {
      const simulatedAgentResponse = "Hello! I'm here to assist you.";
      setMessage(simulatedAgentResponse);
    };

    greet(); 
  }, []);

```

This code runs after the component renders, triggering the agent to say "Hello! I'm here to assist you,"
and updates the `message` state to indicate the greeting was sent, with the effect re-running whenever the `agent` changes.

### Step 3: Modify the `SimpleAgentEffect` component

Give agent a customized `Prompt`

```tsx
  <Prompt>
    Engage the user by discussing their generated name, "{name}". Offer insights or lore about their name and suggest if they want to generate a new one.
  </Prompt>
```

Display the message here

```tsx
  {message && <p>{message}</p>}
```

The final state of `SimpleAgentEffect` look like this.

```tsx

import React, { useState, useEffect } from "react";
import { Prompt } from "@upstreet/agents";

const SimpleGreetingAgent = () => {
  const [message, setMessage] = useState("Initializing...");

   useEffect(() => {
    const greet = async () => {
      const simulatedAgentResponse = "Hello! I'm here to assist you.";
      setMessage(simulatedAgentResponse);
    };

    greet(); // Call the simulated greeting
  }, []);

  return (
    <>
      <Prompt>
        The agent greets the user with: "{message}".
      </Prompt>
      {message && <p>{message}</p>}
    </>
  );
};

export default SimpleGreetingAgent;

```

### Step 4: Import `SimpleAgentEffect` in the `Agent` Components

```tsx
export default function MyAgent() {
  return (
    <Agent>
      <SimpleAgentEffect/>
    </Agent>
  )
}
```

### Step 5: Test the agent

Run `usdk chat` in the terminal to test the agent.

**As soon as the agent renders, it will greet you.**


file: ./content/docs/advanced/custom-components/with-use-state.mdx
# undefined: Custom Components with useState

Learn to build custom React components in Upstreet Agents, leveraging the useState hook for state management.
        
[`useState`](https://react.dev/reference/react/useState) is a React Hook that lets you add a state variable to your component.

```tsx
const [state, setState] = useState(initialState)
```

### Explanation

* Enables state management in functional components.
* Updates the component's state and triggers a re-render.

### Usecase

* Introducing state to a component
* Modifying state using the previous state as a reference
* Updating objects and arrays within the state
* Preventing the recreation of the initial state
* Resetting state by utilizing a unique key
* Preserving data from earlier renders

### Step 1:  Integrate useState with Upstreet agents to build a component that generate random names

* Install the Upstreet SDK using `usdk create`

* Navigate to the `agent.tsx` file.

* You will find a pre-built `MyAgent` component like that.

```tsx
export default function MyAgent() {
  return (
    <Agent>
   
    </Agent>
  )
}
```

### Step 2: Import dependencies and create `NameRandomizer` component

Call `useState`, `Prompt` and `Action` at the top level of your component to declare a state variable.

```tsx
import { useState } from "react";
import { Prompt, Action } from "@upstreet/agents";
```

Now create a component named `NameRandomizer` and set your states using `useState`

```tsx

const NameRandomizer = () => {
  const [name, setName] = useState(generateRandomName);

  return (
    <>
      
    </>
  );
};
```

### Step 3: Modify the `NameRandomizer` component

Create a `generateRandomName`  function below the states in which an array of names is present and the function loops through this array to select a random using
`MATH.floor` and `MATH.random()`.

```tsx
 const generateRandomName = () => {
    const names = ["Brave Falcon", "Silver Fox", "Mystic Owl", "Golden Hawk"];
    return names[Math.floor(Math.random() * names.length)];
  };
```

Give agent a customized `Prompt`

```tsx
  <Prompt>
        Engage the user by discussing their generated name, "{name}". Offer insights or lore about their name and suggest if they want to generate a new one.
      </Prompt>
```

Render the current name and provide a button to generate new name. This button will render the new state

```tsx
    <div>
        <p>Your current name is: <strong>{name}</strong></p>
        <button onClick={() => setName(generateRandomName)}>Generate New Name</button>
      </div>
```

Define the `Action` of the agent

```tsx
 <Action
        name="newNameGenerated"
        description="React to the new name being generated."
        schema={{ name: "string" }}
        handler={({ agent, data }) => {
          agent.say(`The new name, "${data.name}", has a great backstory!`);
        }}
      />
```

The final state of `NameRandomizer` look like this.

```tsx
import React, { useState } from "react";
import { Prompt, Action } from "react-agents";
import { z } from 'zod';

const NameRandomizer = () => {
  const generateRandomName = () => {
    const names = ["Brave Falcon", "Silver Fox", "Mystic Owl", "Golden Hawk"];
    return names[Math.floor(Math.random() * names.length)];
  };

  const [name, setName] = useState(generateRandomName);

 return (
    <Agent>
      <Prompt>
        Discuss the generated name, "{name}". Share lore or background about
        it. If the user wants a new name, prompt them to generate one. Be
        engaging and creative with the responses!
      </Prompt>
      <Action
        name="generateNewName"
        description="Generate a new random name for the user."
        schema={z.object({
          feedbackMessage: z.string(),
        })}
        examples={[
          {
            feedbackMessage: "Here’s a fresh and unique name for you!",
          },
        ]}
        handler={({ agent }) => {
          const newName = generateRandomName();
          agent.say(
            `Your new name is "${newName}". It has an intriguing history!`
          );
          setName(newName);
        }}
      />
    </Agent>
  );

};


```

### Step 4: Import `NameRandomizer` in the `Agent` Components

```tsx
export default function MyAgent() {
  return (
    <Agent>
   <NameRandomizer/>
    </Agent>
  )
}
```

### Step 5: Test the agent

Run `usdk chat` in the terminal to test the agent.

You can ask agent

> I want to guess random names!


file: ./content/docs/api/cognition/autoTask.mdx
# undefined: <AutoTask>

Let your agent plan and execute tasks.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { AutoTask } from 'react-agents';
```

## AutoTask

The AutoTask component enables your agent to plan and execute tasks by breaking them down into steps.

## Usage

1. Add the component to your agent:

   ```tsx
   import { AutoTask } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <AutoTask
         hint="Optional guidance for the agent's task planning behavior"
       />
       {/* ... */}
     </Agent>
   );
   ```

   **Additional Notes:**

   * The `hint` prop is optional and can be used to guide how the agent plans and executes tasks
   * For example, you could set `hint="Break tasks into very small steps"` or `hint="Focus on security best practices"`
   * If no hint is provided, the agent will plan tasks based on its own judgment
   * The agent can:
     * Create new tasks with goals and steps
     * Track progress through task steps
     * Update task details as work progresses
     * Complete or abandon tasks
   * Tasks are managed in memory and persist only during the agent's session
   * Persistence may be added in the future


file: ./content/docs/api/cognition/index.mdx
# undefined: Cognition

Change how your agent thinks.
        


file: ./content/docs/api/cognition/rateLimit.mdx
# undefined: <RateLimit>

Let your agent plan and execute tasks.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { RateLimit } from 'react-agents';
```

## RateLimit

The RateLimit component allows you to control how frequently users can send messages to your agent. This helps prevent spam and abuse while maintaining a smooth user experience.

1. Add the component to your agent:
   ```json
   import { RateLimit } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <RateLimit 
         maxUserMessages={5}
         maxUserMessagesTime={86400000} 
         message="Please wait before sending another message"
       />
       {/* ... */}
     </Agent>
   );
   ```

### Props

* **maxUserMessages** (number)
  * Maximum number of messages a user can send within the time window
  * Default: 5
  * Set to 0 or Infinity to disable rate limiting

* **maxUserMessagesTime** (number)
  * Time window in milliseconds for rate limiting
  * Default: 86400000 (24 hours)
  * Set to 0 or Infinity to disable rate limiting

* **message** (string)
  * Custom message shown when rate limit is exceeded
  * Default: "You are sending messages too quickly. Please wait a moment before sending another message."


file: ./content/docs/api/components/action-modifier.mdx
# undefined: <ActionModifier>

Intercept and modify agent action handling.
        
The `ActionModifier` enables middleware-like modification of actions within your agent system, allowing for pre and post-processing of actions. The `ActionModifier` component serves as a wrapper that intercepts and modifies actions before and after execution.

## Import

```tsx
import { ActionModifier } from 'react-agents';
```

## Usage

Here's a basic example of using the `ActionModifier`:

```tsx

import { ActionModifier, Action } from 'react-agents';

function MyComponent() {
  return (
    <ActionModifier
      before={(action) => {
        // Pre-process action
        console.log('Before action:', action);
        return action;
      }}
      after={(result) => {
        // Post-process result
        console.log('After action:', result);
        return result;
      }}
    >
      <Action name="exampleAction" handler={() => {}} />
    </ActionModifier>
  );
}
```

## Props

import { TypeTable } from 'fumadocs-ui/components/type-table';

export const actionModifierProps = {
  before: {
    description: 'A function that executes before the action is processed.',
    type: 'Function(action) => action',
    typeDescription: 'A function that can modify or validate the action and must return the modified action.',
    typeDescriptionLink: '', // Add a link to further documentation if needed
    default: 'N/A', // This prop is required, so no default value
  },
  after: {
    description: 'A function that executes after the action completes.',
    type: 'Function(result) => result',
    typeDescription: 'A function that can transform the result and must return the final result.',
    typeDescriptionLink: '', // Add a link to further documentation if needed
    default: 'N/A', // This prop is required, so no default value
  },
};

<TypeTable type={actionModifierProps} />

## Best Practices

* Keep modifiers focused on specific concerns
* Chain multiple modifiers for complex modifications
* Handle errors appropriately in before/after handlers
* Avoid heavy computations that might block the main thread
* Return the modified action/result from handlers


file: ./content/docs/api/components/action.mdx
# undefined: <Action>

Define actions your Agent can perform.
        
The `Action` component from `react-agents` represents an action that a React AI agent can perform. It registers a new action with an agent registry, allowing the agent to trigger the action in response to certain events. This component is useful for defining discrete, reusable actions with associated schemas and event handlers, making it easier to define and handle actions within an AI-driven context.

## Import

```tsx
import { Action } from 'react-agents';
```

## Usage

Here is an example of how the Action component might be used:

```javascript
import { Action } from 'react-agents';
import { z } from 'zod';

const sendMessageSchema = z.object({
  message: z.string(),
  recipientId: z.string(),
});

const handleSendMessage = async (e) => {
  console.log("Sending message:", e);
  // Code to send a message goes here
};

function MyComponent() {
  return (
    <Action
      name="SendMessage"
      description="Sends a message to a specific recipient."
      state="ready"
      schema={sendMessageSchema}
      examples={[
        { message: "Hello!", recipientId: "12345" },
        { message: "How are you?", recipientId: "67890" },
      ]}
      handler={handleSendMessage}
    />
  );
}
```

### Example Breakdown:

name is set to "SendMessage" to identify the action.
description provides a brief summary of the action's purpose.
state is set to "ready" to indicate the current status of the action.
schema defines the expected input parameters, validating that message and recipientId are strings.
examples show sample data for the message and recipientId inputs.
handler is an asynchronous function that handles the SendMessage action when it is triggered.
Component Lifecycle
When the Action component is mounted, it registers the action with the agent registry using the registerAction method, associating the action with a unique symbol. When unmounted, it unregisters the action, ensuring no memory leaks.

## Props

import { TypeTable } from 'fumadocs-ui/components/type-table';

export const actionProps = {
  name: {
    description: 'The name of the action.',
    type: 'string',
    typeDescription: 'The name is used to identify the action within the agent registry.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'N/A', // Required, so no default
  },
  description: {
    description: 'A human-readable description of what the action does.',
    type: 'string',
    typeDescription: 'Helpful for documenting the action\'s purpose or behavior.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'N/A', // Required, so no default
  },
  state: {
    description: 'An optional state associated with the action.',
    type: 'string',
    typeDescription: 'This state provides additional contextual information and may influence the action\'s behavior.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'undefined', // Optional, so can be undefined
  },
  schema: {
    description: 'A Zod schema object that defines the structure and validation of the action\'s input parameters.',
    type: 'ZodTypeAny',
    typeDescription: 'Used to validate the data passed to the action, ensuring it conforms to the expected format.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'N/A', // Required, so no default
  },
  examples: {
    description: 'An array of example objects demonstrating the expected structure of the action\'s inputs.',
    type: 'Array<object>',
    typeDescription: 'Illustrates typical usage scenarios for the action.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'N/A', // Required, so no default
  },
  handler: {
    description: 'A function or asynchronous function that handles the action when triggered.',
    type: 'function',
    typeDescription: 'Receives a `PendingActionEvent` and defines the action\'s behavior. If asynchronous, it must return a Promise.',
    typeDescriptionLink: '', // Add a link if needed
    default: 'undefined', // Optional, so can be undefined
  },
};

<TypeTable type={actionProps} />

## Dependencies

The component recalculates and registers the action if any of the following dependencies change:

`name`
`description`
Serialized schema (printZodSchema)
Serialized examples
Serialized handler function


file: ./content/docs/api/components/agent.mdx
# undefined: <Agent>

Learn how to use the Agent Component to lay out the foundation of your Agent.
        
The `Agent` component serves as a high-level wrapper component that provides the core infrastructure for AI agent functionality in a React application. It acts as a container that:

* Establishes the communication context for AI interactions
* Manages the state and lifecycle of AI agent operations
* Provides necessary context and configuration to child components
* Enables action handling and event processing for nested agent functionalities

## Import

```tsx
import { Agent } from 'react-agents';
```

## Usage

The `Agent` class has represents a currently running agent. It corresponds 1:1 to an `<Agent>` tag in your code.

```tsx
import { Agent } from 'react-agents'

const MyAgent = () => {
  return (
    <Agent>
      {/* Child components that need access to agent capabilities */}
      <YourAgentLogic />
    </Agent>
  )
}
```

<Callout>
  You do not construct the `Agent` class yourself. It is created for you when your `<Agent>` gets rendered by the runtime.
</Callout>

## Reference

The `Agent` class exposes helpful functions to help build your Agent. When you have a handle to your agent, you can access its methods.

### `useAgent` hook

Any component nested within an `<Agent>` can call the `useAgent` hook to get a handle to the underlying `Agent` class. [See reference](/api/hooks/useAgent)

### `handler` callback:

Each `handler` in your agent (such as `<Action handler={(event) => {/* ... */}}>` or `<Perception handler={(event) => {/* ... */}}>`) has an `agent` key on the `event.data`. You can use this for convenient access to the currently running `agent`. e.g.

### `useRef` hook

Every `<Agent>` has an internal `ref` that resolves to the `Agent` instance. You can access it the usual way using React's [`useRef`](https://react.dev/reference/react/useRef):

```tsx
import { useRef } from 'react'; // [!code ++]
import { Agent } from 'react-agents';

const MyAgent = () => {
  // [!code ++]
  const agentRef = useRef(null); // now you can use agentRef.current to access the Agent tags functions. 

  return (
    // [!code ++]
    <Agent ref={agentRef}>
      {/* Child components that need access to agent capabilities */}
      <YourAgentLogic />
    </Agent>
  )
}

```

## Source code

You can see the code for the Agent Component in our [GitHub](https://github.com/UpstreetAI/monorepo/blob/main/packages/usdk/packages/upstreet-agent/packages/react-agents/components.tsx#L90).


file: ./content/docs/api/components/index.mdx
# undefined: Components

You can use built-in Components to start composing your Agent.
        


file: ./content/docs/api/components/perception.mdx
# undefined: <Perception>

The <Perception /> Component allows the Agent to perceive and react to real-world events.
        
The `<Perception />` component is used to define and register a perception within the Agent's context. It allows the agent to handle specific types of perceptions with custom logic.

## Import

```tsx
import { Perception } from 'react-agents';
```

## Usage

Here's an example of how to use the `<Perception />` component:

```javascript
import { Perception } from 'react-agents';

function MyComponent() {
  return (
    <Perception
      type="visual"
      handler={(data) => {
        console.log('Handling visual perception:', data);
      }}
    >
      {/* Optional child components */}
    </Perception>
  );
}
```

## Props

import { TypeTable } from 'fumadocs-ui/components/type-table';

export const perceptionProps = {
  type: {
    description: 'The type of perception being registered.',
    type: 'string',
    typeDescription: 'A string that identifies the type of perception being handled.',
    typeDescriptionLink: '', // Add a link to further documentation if needed
    default: 'N/A', // This is a required prop, so no default value
  },
  handler: {
    description: 'A function that handles the perception logic.',
    type: 'Function',
    typeDescription: 'A function that is executed when the perception is triggered.',
    typeDescriptionLink: '',
    default: 'N/A', // This prop is required, so no default value
  },
  children: {
    description: 'Any child components or elements to be rendered within the Perception component.',
    type: 'ReactNode',
    typeDescription: 'A ReactNode can be anything renderable by React, such as JSX elements, strings, numbers, etc.',
    typeDescriptionLink: '',
    default: 'N/A', // This is optional, so default can be omitted or marked as 'undefined'
  },
};

<TypeTable type={perceptionProps} />

## Methods

The `<Perception>` component does not expose any public methods. All interaction should be handled through props or by wrapping the component with additional logic.

## Best Practices

* **Event Handling**: Ensure that your event handling logic is efficient and does not block the main thread. Consider using asynchronous functions or web workers for complex processing.
* **Configuration**: Use the `config` prop to fine-tune the perception logic to suit your specific use case. This can help optimize performance and accuracy.

## Troubleshooting

* **No Response**: If the component does not seem to be responding to events, check that your event handlers are correctly implemented and that the component is properly mounted in the DOM.
* **Performance Issues**: If you experience performance issues, review your event handling logic and consider optimizing or offloading intensive tasks.


file: ./content/docs/api/components/prompt.mdx
# undefined: <Prompt>

Learn how to use the Prompt Component to have your Agent think.
        
When it's time for your agent to `.think()`, it will concatenate all of its prompts, in the order they are rendered in React, and use that prompt for inference to generate the next action. Therefore the prompts you use form the bread and butter of your agent's thought process and have a large impact on its behavior.

## Import

```tsx
import { Prompt } from 'react-agents'
```

## Usage

Prompts can be either static (strings) or dynamic (depending on external data or memory). You can render anything you like inside of a prompt tag, and your agent will consider it when thinking!

```tsx
import { 
    Agent,
    Prompt // [!code ++]
} from 'react-agents'

const MyAgent = () => {
  return (
    <Agent>
        {/* [!code ++] */}
        <Prompt>This agent is female</Prompt>
        {/* [!code ++] */}
        <Prompt>They have a sarcastic personality</Prompt>
    </Agent>
  )
}
```

You can have a complete, working Agent with an `agent.tsx` file using just the [`Agent`](/api/components/agent) tag and the `Prompt` tag.


file: ./content/docs/api/components/uniform.mdx
# undefined: <Uniform>

Generate metadata for each action.
        
The concept is borrowed from [Uniforms in a shader](https://en.wikipedia.org/wiki/Shader).

## Import

```tsx
import { Uniform } from 'react-agents';
```

## Usage

Here's a simple example of using the `Uniform` component:

```tsx
import { Uniform, Agent, Action } from 'react-agents';

function MyComponent() {
  return (
    <Agent>
      <Uniform
        name="mood"
        description="Current emotional state of the agent"
        handler={(message) => {
          // Analyze message and return mood
          return {
            mood: 'positive',
            confidence: 0.8
          };
        }}
      >
        <Action name="respond" handler={(data) => {
          // Access uniform data in action
          console.log('Current mood:', data.uniform.mood);
        }} />
      </Uniform>
    </Agent>
  );
}
```

## Props

import { TypeTable } from 'fumadocs-ui/components/type-table';

export const uniformProps = {
  name: {
    description: 'Identifier for the uniform',
    type: 'string',
    typeDescription: 'A string representing the unique identifier for the uniform.',
    typeDescriptionLink: '', // You can link to further documentation if available
    default: 'N/A', // You can specify default or leave it as 'N/A'
  },
  description: {
    description: 'Describes the purpose of the uniform',
    type: 'string',
    typeDescription: 'A string providing a clear explanation of the uniform’s purpose.',
    typeDescriptionLink: '',
    default: 'N/A',
  },
  handler: {
    description: 'Function that generates the uniform data',
    type: 'Function(message) => any',
    typeDescription: 'A function that takes a message and returns metadata.',
    typeDescriptionLink: '',
    default: 'N/A',
  },
};

<TypeTable type={uniformProps} />

## Best Practices

* Keep handlers lightweight and efficient
* Use meaningful names for uniforms
* Implement proper error handling
* Cache expensive computations when possible
* Document the uniform's purpose clearly

## Common Use Cases

* Tracking conversation topics
* Monitoring agent mood or state
* Generating consistency metrics
* Adding timestamps or identifiers
* Maintaining context across actions


file: ./content/docs/api/context/index.mdx
# undefined: Context

Add additional sense perception capabilities to your agent.
        


file: ./content/docs/api/context/ragMemory.mdx
# undefined: <RAGMemory>

Add long term memories to your agent.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

The RAGMemory component enables your agent to maintain long-term memory through a question-answer database system.
This allows the agent to remember and recall information from previous conversations and interactions.
The memory is shared across conversations.

## Import

```tsx
import { RAGMemory } from 'react-agents';
```

## Usage

Add the component to your agent:

```tsx
import { RAGMemory } from 'react-agents';

return (
  <Agent>
    {/* ... */}
    <RAGMemory
      chunkMessages={5} // Optional: Number of messages to chunk together when creating memories
    />
    {/* ... */}
  </Agent>
);
```

**Additional Notes:**

* The `chunkMessages` prop is optional and controls how many messages are grouped together when creating new memories
* If not specified, a default chunk size will be used
* The agent will:
  * Automatically create memories from conversation chunks
  * Summarize chunks of messages into memorable information
  * Store memories for later recall
  * Load relevant memories during conversations
  * Use memories to maintain context across sessions
* Memories persist across conversations and agent restarts
* Memories are stored in a vector database for efficient semantic search
* The agent can access memories that are semantically relevant to the current conversation


file: ./content/docs/api/context/videoPerception.mdx
# undefined: <VideoPerception>

Allow your agent to perceive images and video.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { VideoPerception } from 'react-agents';
```

## Usage

The VideoPerception component enables your agent to perceive and analyze images and videos in the conversation.

1. Add the component to your agent:
   ```json
   import { VideoPerception } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <VideoPerception
         hint="Optional guidance for the agent's video perception behavior"
       />
       {/* ... */}
     </Agent>
   );
   ```

The passed-in `hint` will be used during inference to determine what aspects of the video the agent should focus on.

The supported media types are:

* `image/jpeg`
* `image/png`
* `image/webp`


file: ./content/docs/api/context/webBrowser.mdx
# undefined: <WebBrowser>

Add web browsing support to your agent.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

The WebBrowser component enables your agent to browse and interact with web pages.

## Import

```tsx
import { WebBrowser } from 'react-agents';
```

## Usage

1. Add the component to your agent:

   ```json
   import { WebBrowser } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <WebBrowser
         hint="Optional guidance for the agent's browsing behavior"
       />
       {/* ... */}
     </Agent>
   );
   ```

   **Additional Notes:**

   * The `hint` prop is optional and can be used to guide the agent's browsing behavior
   * For example, you could set `hint="Focus on news articles"` or `hint="Only browse product pages"`
   * If no hint is provided, the agent will browse based on its own judgment
   * The bot can:
     * Navigate to URLs
     * Click elements
     * Fill forms
     * Extract text content
     * Take screenshots
     * And more
   * Web browsing requires a stable internet connection
   * Standard rate limiting and robot policies of websites apply
   * Note: if you haven't created the agent yet, please follow this [Create an Agent](/create-an-agent) first.

### Available Actions

The WebBrowser internally uses several actions for interacting with web pages:

* `goto`: Navigate to a URL
* `click`: Click an element on the page
* `type`: Enter text into a form field
* `extract`: Get text content from the page
* `screenshot`: Capture an image of the page
* `evaluate`: Run custom JavaScript code
* `waitForSelector`: Wait for an element to appear
* `waitForNavigation`: Wait for page navigation to complete

Each action follows standard web automation patterns and includes error handling for common scenarios like:

* Page load failures
* Missing elements
* Navigation timeouts
* Network errors

The agent will automatically retry failed actions when appropriate and can adapt its browsing strategy based on the results.


file: ./content/docs/api/generative/index.mdx
# undefined: Generative

Add generative AI functionality to your agent.
        


file: ./content/docs/api/generative/mediaGenerator.mdx
# undefined: <MediaGenerator>

Add media generation support to your agent.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { MediaGenerator } from 'react-agents';
```

## Usage

The MediaGenerator component enables your agent to generate various types of media content through a unified interface.

1. Add the component to your agent:

   ```json
   import { MediaGenerator } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <MediaGenerator />
       {/* ... */}
     </Agent>
   );
   ```

   **Additional Notes:**

   * The agent can generate different types of media using the `type` parameter:
     * Images: `'image/jpeg+image'`
     * Sound effects: `'audio/mpeg+sound-effect'`
     * 3D models: `'model/gltf-binary+3d-model'`
     * Videos: `'model/video/mp4+video'`
   * Each media type has its own generation options and parameters
   * Generated media is automatically uploaded and shared in the chat
   * Media generation requires valid authentication via JWT token
   * Generation may take some time depending on the media type
   * Note: if you haven't created the agent yet, please follow this [Create an Agent](/create-an-agent) first.

### Available Media Types

The MediaGenerator supports several media types with different capabilities:

* **Images (`'image/jpeg+image'`)**
  * Format: JPEG
  * Configurable image sizes via `options.image_size`
  * Text-to-image generation from prompts
  * Outputs .jpg files

* **Sound Effects (`'audio/mpeg+sound-effect'`)**
  * Format: MP3
  * Text-to-audio generation from prompts
  * Suitable for short sound clips
  * Outputs .mp3 files

* **3D Models (`'model/gltf-binary+3d-model'`)**
  * Format: GLB
  * Image-to-3D generation (generates image from prompt first)
  * Compatible with standard 3D viewers
  * Outputs .glb files

* **Videos (`'model/video/mp4+video'`)**
  * Format: MP4
  * Image-to-video generation (generates image from prompt first)
  * Automated video synthesis
  * Outputs .mp4 files

Each media type includes error handling for common scenarios like:

* Generation failures
* Upload errors
* Invalid prompts
* Authentication issues
* Network timeouts

The agent will automatically handle errors and can retry generation when appropriate. All generated media is uploaded to secure storage and shared in the chat with proper MIME types and extensions.

### Usage Example


file: ./content/docs/api/generative/tts.mdx
# undefined: <TTS>

Add text-to-speech support to your agent.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { TTS } from 'react-agents';
```

## Usage

The TTS component adds text-to-speech capabilities to your agent, allowing it to speak messages using a specified voice endpoint.

1. Add the component to your agent:
   ```tsx
   return (
     <Agent>
       {/* ... */}
       <TTS voiceEndpoint="elevenlabs:scillia:kNBPK9DILaezWWUSHpF9" />
       {/* ... */}
     </Agent>
   );
   ```

2. Use the `say` action in your agent's responses:
   ```tsx
   agent.say({ text: "Hello, I can speak!" });
   ```
   Or, simply chat with the agent to get them to speak.

## Props

import { TypeTable } from 'fumadocs-ui/components/type-table';

<TypeTable
  type={{
  voiceEndpoint: {
    description: (
      <>
        Endpoint for the text-to-speech. Format is{" "}
        <code>provider:voiceName:voiceId</code>. If not provided, it will use
        a default voice.
      </>
    ),
    type: 'string',
    default: 'null (uses default voice)',
  },
}}
/>

## Custom voices

You can create and use custom voices with the USDK CLI. Learn how to do that [here]().

### Using Custom Voices with `<TTS>`

Once created, use your custom voice in the TTS component by setting the voiceEndpoint prop:

```tsx
<TTS voiceEndpoint="elevenlabs:scillia:kNBPK9DILaezWWUSHpF9" />
```


file: ./content/docs/api/hooks/index.mdx
# undefined: Hooks

Hooks let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in usdk.
        


file: ./content/docs/api/hooks/use-agent.mdx
# undefined: useAgent

Returns the current `Agent` context.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-auth-token.mdx
# undefined: useAuthToken

Returns the current authentication token.
        
Generally, you should not need to use this.

<Callout type="warn"> Do not put this token into the prompt context or use it anywhere it might be seen by a user, as it can be used to take over the agent.</Callout>


file: ./content/docs/api/hooks/use-cached-messages.mdx
# undefined: useCachedMessages

Returns cached messages for the current conversation, with optional filtering. Automatically handles loading and updates.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-conversation.mdx
# undefined: useConversation

Returns the current `Conversation`.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-conversations.mdx
# undefined: useConversations

Returns the array of conversations the `Agent` is currently participating in.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-env.mdx
# undefined: useEnv

Returns the environment variables from your `.env.txt` file.
        
You would need to create a file called `.env.txt` in the root of your Agent directory.

<Callout type="warn">
  Not to be confused with [`useEnvironment`](/api/hooks/use-environment).
</Callout>


file: ./content/docs/api/hooks/use-environment.mdx
# undefined: useEnvironment

Returns the current environment - `'development'` or `'production'`.
        
This can be used to determine if the agent is running in a development or deployed server environment.

<Callout type="warn">
  Not to be confused with [`useEnv`](/api/hooks/use-env), which returns environment variables.
</Callout>


file: ./content/docs/api/hooks/use-kv.mdx
# undefined: useKv

Returns the key-value storage interface from the AppContext.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-name.mdx
# undefined: useName

Returns the agent's name, prioritizing the registry name over the agent's default name.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-num-messages.mdx
# undefined: useNumMessages

Returns the total number of cached messages in the current conversation.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-personality.mdx
# undefined: usePersonality

Returns the agent's personality/bio, prioritizing the registry personality over the agent's default bio.
        
View [source code](https://github.com/upstreetAI/upstreet-core).


file: ./content/docs/api/hooks/use-tts.mdx
# undefined: useTts

Returns a memoized text-to-speech interface with optional voice endpoint and sample rate configuration.
        
### Arguments

import { TypeTable } from 'fumadocs-ui/components/type-table';

export const actionModifierProps = {
  voiceEndpoint: {
    description: 'The ElevenLabs voice model.',
    type: 'string',
    default: 'N/A', // This prop is required, so no default value
  },
  sampleRate: {
    description: 'The sample rate of the voice.',
    type: 'number',
    default: 'N/A', // This prop is required, so no default value
  },
};

<TypeTable type={actionModifierProps} />


file: ./content/docs/api/integrations/discord.mdx
# undefined: Discord

Integrate your Agent with Discord, the popular chatting app.
        
import Wrapper from 'components/preview/wrapper';
import Image from 'next/image';

## Import

```tsx
import { Discord } from 'react-agents';
```

## Setup

<Callout>
  We highly recommend reading the [Discord Developers documentation](https://discord.com/developers/docs/intro) for in-depth help, and navigating through Discord's API.
</Callout>

Add Discord integration to your agent by following these steps:

### Step 1: Create a Discord bot application

* Go to https://discord.com/developers/applications
* Click **"New Application"** and give it a name

<Wrapper>
  <Image src="/images/integrations/discord-new-app.png" width={740} height={300} className="rounded-md" />
</Wrapper>

### Step 2: Configure bot settings

* From the sidebar, go to the **Bot** section to get the **Token**.
* Click on **Reset Token** to get your Token and save it somewhere securely.

<Wrapper>
  <Image src="/images/integrations/bot-section.png" width={740} height={300} className="rounded-md" />
</Wrapper>

Make sure to enable all three options here.

* **Presence Intent** ✓
* **Server Members Intent** ✓
* **Message Content Intent** ✓

<Wrapper>
  <Image src="/images/integrations/bot-perm.png" width={740} height={300} className="rounded-md" />
</Wrapper>

### Step 3: Add the bot to your server

* From the sidebar, go to the **OAuth2** section
* At the **OAuth2 URL Generator**, check the `bot` option

<Wrapper>
  <Image src="/images/integrations/bot-mark.png" width={740} height={300} className="rounded-md" />
</Wrapper>

* In the **Bot Permissions**, give the relevant permissions to the bot. To enable the bot to talk in the server and respond to messages, you should check **"Send Messages"**. You can check other permissions based on what you want your bot to do.

<Wrapper>
  <Image src="/images/integrations/auth-perm.png" width={740} height={300} className="rounded-md" />
</Wrapper>

* Scroll down a bit to copy the URL:

<Wrapper>
  <Image src="/images/integrations/Copy-url.png" width={740} height={300} className="rounded-md" />
</Wrapper>

* **Paste** this URL in a new tab where you will have to:

1. Select the server you want to add the bot to
2. Authorize the bot

## Usage

Add the following Component to your Agent:

```tsx
import { Discord } from 'react-agents';

// ... 
return (
<Agent>
  {/* ... */}
  <Discord
    token="YOUR_BOT_TOKEN" // The bot token from Step 2
    channels={[
      "general", // Text channel names the bot should listen to
      "voice-chat" // Voice channel names the bot should listen to
    ]}
    dms={true} // Enable direct messages with the bot
    userWhitelist={[ // Optional: restrict which users can interact
      "user1#1234",
      "user2#5678"
    ]}
  />
  {/* ... */}
</Agent>
);
```

When you run the following command to get your Discord Agent up and running:

```bash
usdk chat
```

You can now test it in the connected Discord server! Just mention it in one of the channels you specified, and see it talk.

You can see a more detailed guide for this in our [*Discord Agent*](/examples/discord-agent) example.

## Additional Notes

* The bot will only respond in the specified channels and to whitelisted users (if configured)
* Voice channel support requires additional Discord permissions (see above)
* Channel names are case-sensitive and should match exactly
* For DMs, users must share a server with the bot
* The bot token should be kept secure and not committed to version control.
* You can use `.env.txt` and the useEnv() hook to load it at runtime.
* If you need to reset the token for security reasons, you can do so in the Discord Developer Portal
* The bot requires a stable internet connection to maintain WebSocket connection with Discord
* Rate limits apply to bot actions - see Discord's [developer documentation](https://discord.com/developers/docs/topics/rate-limits) for details


file: ./content/docs/api/integrations/index.mdx
# undefined: Plugins

Integrate your Agent with other libraries and services.
        


file: ./content/docs/api/integrations/x.mdx
# undefined: X (formerly Twitter)

Integrate your Agent with X, one of the world's most viral social apps.
        
## Responding to Mentions

Twitter integration allows your agent to interact with Twitter by responding to mentions.

1. Create a Twitter Developer Account:
   * Go to https://developer.twitter.com/
   * Sign up for a developer account if you haven't already
   * Create a new project and application

2. Configure your application:
   * Navigate to the "Settings" tab of your application
   * Under the "User authentication settings" section, press the "Edit" button
   * In the "App Permissions" section, select the appropriate option having "write" access
   * In the "Type of App" section, you must select the "Native app" (Public client) option
   * In the "App Info" section:
     * Set the "Callback URI / Redirect URL" field value to "https://twitter-oauth.upstreet.ai"
     * Set the "Website" field value to your preferred URL
   * Once completed, save your changes by clicking the "Save" button
   * Navigate to the "Keys and tokens" section
   * Copy your OAuth 2.0 application credentials (Client ID and Client Secret)

3. Log in with oauth at https://twitter-auth.upstreet.ai/
   * Use the Client ID and Client Secret from step 2
   * On successful authentication, you will be provided with your Twitter Token
   * Copy the token and use it in the next step

4. Configure your agent:

   * Add the following component to your agent:

   ```json
   import { Twitter } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <Twitter
         token="YOUR_TWITTER_TOKEN" // Paste your Twitter Token from Step 3. here
       />
       {/* ... */}
     </Agent>
   );
   ```

   **Additional Notes:**

   * The bot will automatically listen for and respond to mentions of your Twitter account
   * The token should be kept secure and not committed to version control
     * You can use `.env.txt` and the useEnv() hook to load it at runtime
   * The bot polls for new mentions every 10 seconds
   * Twitter API rate limits apply - see Twitter's [developer documentation](https://developer.twitter.com/en/docs/twitter-api/rate-limits) for details
   * The bot requires a stable internet connection to maintain communication with Twitter
   * Note: if you haven't created the agent yet, please follow this [Create an Agent](/create-an-agent) first.

### Twitter Spaces

The Twitter Spaces integration allows your agent to create and join Twitter Spaces audio rooms.

1. Get your Twitter auth token:
   * Log into Twitter in your browser
   * Open the browser developer tools (F12)
   * Go to the Application/Storage tab
   * Find the `auth_token` cookie under Cookies > twitter.com
   * Copy the value of the `auth_token` cookie

2. Configure your agent:

   ```json
   import { TwitterSpaces } from 'react-agents';

   return (
     <Agent>
       {/* ... */}
       <TwitterSpaces
         token="YOUR_AUTH_TOKEN" // Twitter auth_token cookie value
         url="OPTIONAL_SPACE_URL" // URL of an existing Space to join (optional)
       />
       {/* ... */}
     </Agent>
   );
   ```

   **Additional Notes:**

   * If no `url` is provided, the bot will create a new Twitter Space
   * If a `url` is provided, the bot will attempt to join that existing Space
   * The bot will automatically:
     * Create/join the Space
     * Request speaking permissions if joining
     * Unmute itself when ready
   * The token should be kept secure and not committed to version control
     * You can use `.env.txt` and the useEnv() hook to load it at runtime
   * The bot requires a stable internet connection to maintain the Space connection
   * Twitter's standard rate limits and Space restrictions apply
   * Note: if you haven't created the agent yet, please follow this [Create an Agent](/create-an-agent) first.


file: ./content/docs/api/loops/actionLoop.mdx
# undefined: <ActionLoop>

Autonomously execute actions.
        
## Import

```tsx
import { ActionLoop } from 'react-agents';
```

## Usage

Add the component to your agent to initiate an action loop:

```tsx
function MyAgent() {
  return (
    <Agent>
      <ActionLoop
        hint="Optional hint to guide the agent's actions"
        actOpts={{ /* Optional action options */ }}
        evaluator={customEvaluator} // Optional: Provide a custom evaluator
      >
        {/* Child components */}
      </ActionLoop>
    </Agent>
  );
}
```

The agent will continue to loop and execute actions until the component is removed.

## Props

* `hint?: string` - Optional hint to guide the agent's actions
* `actOpts?: object` - Optional configuration for action behavior
* `evaluator?: Evaluator` - Optional custom evaluator (cannot be used with hint/actOpts)


file: ./content/docs/api/loops/chatLoop.mdx
# undefined: <ChatLoop>

Autonomously execute chat interactions.
        
## Import

```tsx
import { ChatLoop } from 'react-agents';
```

## Usage

Add the component to your agent to initiate a chat loop that responds to "say" and "nudge" events:

```tsx
function MyAgent() {
  return (
    <Agent>
      <ChatLoop
        hint="Optional hint to guide the agent's responses"
        actOpts={{ /* Optional action options */ }}
        evaluator={customEvaluator} // Optional: Provide a custom evaluator
      >
        {/* Child components */}
      </ChatLoop>
    </Agent>
  );
}
```

The agent will evaluate and respond when it receives "say" events or targeted "nudge" events.

## Props

* `hint?: string` - Optional hint to guide the agent's responses
* `actOpts?: object` - Optional configuration for action behavior
* `evaluator?: Evaluator` - Optional custom evaluator (mutually exclusive with hint/actOpts)

Note: You cannot provide both an `evaluator` and `hint`/`actOpts` at the same time - this will throw an error.


file: ./content/docs/api/loops/index.mdx
# undefined: Loops

Components for controlling your agent's autonomous operation.
        


file: ./content/docs/concepts/usdk/agent-structure.mdx
# undefined: Agent Structure

Learn how an Agent is broken down into files and folders.
        
import AgentReadMe from 'usdk/packages/upstreet-agent/README.md';

<AgentReadMe />


file: ./content/docs/concepts/usdk/command-reference.mdx
# undefined: Command Reference

See all the commands supported by Upstreet Agents SDK.
        
import Commands from '../../../../components/usdk/commands';

The following table contains all the `usdk` command-line interface commands, their descriptions, and any additional subcommands or switches they have.

These commands are also visible in the Terminal if you run `usdk --help`.

<Commands />


file: ./content/docs/concepts/usdk/overview.mdx
# undefined: Overview

The Upstreet Agents SDK is the first React-based SDK for building and deploying headless AI agents, locally and in the cloud.
        
import UsdkReadMe from 'usdk/README.md';

<UsdkReadMe />
Audit teilen oder weiter analysieren
Audit teilen
Mit KI besprechen
Hinzugefügt 10.11.2026

Ähnliche Websites im Verzeichnis

Websites mit ähnlicher KI-Bereitschaft — vergleichen Sie llms.txt und Markup.

docs.upstreet.ai – Audit der KI-Bereitschaft | llmsmap.me/de