import Link from 'next/link'
import { Lumiflex } from 'uvcanvas'
import { Button } from "../components/ui/button"
import { MoveRight } from "lucide-react"
import { Accordion, AccordionItem, AccordionContent, AccordionTrigger } from "../components/ui/accordion"
import { Steps, Callout } from 'nextra/components'
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../components/ui/tabs"


<Callout>

<div className='space-x-3 flex flex-row items-center'>
<span className='font-bold'> Check out </span>
<Link target="_blank" href="https://colab.research.google.com/github/sotopia-lab/sotopia/blob/main/notebooks/tutorials/1.1-setup.ipynb">
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"/> </Link>
<span className='font-bold'> for a quick tutorial </span>
</div>

</Callout>

Train, deploy, and evaluate Social AI agents
with <Link href="https://sotopia.world/"><span className="font-display text-xl">Sotopia</span></Link>

## Features

{/* Use accordian for the following */}

<Accordion type="single" collapsible className="w-full">
  <AccordionItem value="item-1">
      <AccordionTrigger> Enables human-AI interaction </AccordionTrigger>
      <AccordionContent>
        <div>
          <ul>
            <li>Use `LLMAgent` to create LLM-based social agents, REST API-based interface for humans.</li>
            <li>RESTful API-based interface for humans.</li>
          </ul>
        </div>
      </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
      <AccordionTrigger> Preset social tasks, characters, and interactions </AccordionTrigger>
      <AccordionContent>
        <ul>
        <li>More than 200 social tasks, 40 characters, and 10k interaction episodes.</li>
        <li>Interactions between agents backed by both closed-source and open-source LLMs, and human participants.</li>
        <li>Evaluation of the performance based on multiple social dimensions.</li>
        </ul>
      </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-3">
      <AccordionTrigger> Realistic social interaction </AccordionTrigger>
      <AccordionContent>
        <ul>
          <li>Agents can talk, do non-verbal communication and performance physical actions.</li>
          <li>Characters have different personalities, backgrounds, and relationships.</li>
          <li>Agents can have different goals and motivations.</li>
        </ul>
      </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-4">
      <AccordionTrigger> Create your own </AccordionTrigger>
      <AccordionContent>
        <ul>
          <li>Modular design for easy extension.</li>
          <li>Subclass `BaseAgent`, `ParallelSotopiaEnv`, `Evaluator` to create your own agents, environments, and evaluators.</li>
          <li>Add your customized social tasks and characters.</li>
        </ul>
      </AccordionContent>
  </AccordionItem>
</Accordion>


## Why Sotopia?
Sotopia aims at pushing the boundary of artificial social intelligence through simulating realistic social interaction, supporting human-AI interaction, and evaluating the performance of social agents in a unified way.

**Unlike** other multi-agent frameworks ([CrewAI](https://www.crewai.com/), [CAMEL-AI](https://www.camel-ai.org/), [AutoGen](https://microsoft.github.io/autogen/dev/index.html), and [swarm](https://github.com/openai/swarm)), Sotopia provides a wide range of social tasks and characters with different backgrounds and personalities, and creates a asynchronous and information-imperfect social interaction environment.


## Installation
This package supports Python 3.10 and above. There are two ways to setup the package:
automatic installation with an interactive installer and manual installation from source.

### Interactive Installer
```bash
pip install sotopia
sotopia install
export REDIS_OM_URL="redis://localhost:6379"
```

<Accordion type="single" collapsible className="w-full">
      <AccordionItem value="item-1">
        <AccordionTrigger>Using uv? (recommended)</AccordionTrigger>
        <AccordionContent>
        We recommend using uv to install the package. You can install the package with the following command:
        ```bash
        uv pip install sotopia
        ```
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-2">
        <AccordionTrigger>Using Conda?</AccordionTrigger>
        <AccordionContent>
        Create a new environment with conda and install the package with pip:
        ```bash
        conda create -n sotopia python=3.11;
        conda activate sotopia;
        ```
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-3">
        <AccordionTrigger>Where to put my OpenAI/TogetherAI/Groq/Replicate API keys?</AccordionTrigger>
        <AccordionContent>
          <p>Although API keys are not required for all the experiments, you need to use these keys when you use LLMs from these providers.
          For example, set the environment variable `OPENAI_API_KEY` to your key.
          E.g., setting env variable in the `.env` file and use `uv run --env-file .env` to run the command.
          Or you could add the key to a conda environment: `conda env config vars set OPENAI_API_KEY=your_key`</p>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-4">
        <AccordionTrigger>What if I want to run examples and sotopia-chat?</AccordionTrigger>
        <AccordionContent>
          <p>Install the package with the following command:</p>
          ```bash
          pip install sotopia[examples, chat]
          ```
          if you are developing Sotopia using uv, you can sync your dependency with
          ```bash
          uv sync --extra examples --extra api
          ```
        </AccordionContent>
      </AccordionItem>
</Accordion>

### Or if you want to install from source

#### Clone the repo and install the package
```bash
git clone git@github.com:sotopia-lab/sotopia.git;
cd sotopia;
uv sync --all-extras
```

#### Set up Redis stack

Redis stack is a required dependency for using Sotopia. There are two ways to set up Redis stack:

```bash
sotopia install
```

or manual setup:
<Accordion type="single" collapsible className="w-full">
      <AccordionItem value="item-1">
        <AccordionTrigger>Docker is my thing.</AccordionTrigger>
        <AccordionContent>
        Please follow the [instruction](https://redis.io/docs/stack/get-started/install/docker/) to start a redis-stack server or use an existing server. If you want to use the existing data in Sotopia, you can download the `dump.rdb` file from [here](https://cmu.box.com/shared/static/xiivc5z8rnmi1zr6vmk1ohxslylvynur). Feel free to check more datasets related to Sotopia [here](https://huggingface.co/collections/cmu-lti/sotopia-65f312c1bd04a8c4a9225e5b).

        After downloading the `dump.rdb` file, make a `redis-data` folder in an desired `<your_path>` directory. And then you can start the server with the following command:
        ```bash
        docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 -v <your_path>/redis-data:/data/ redis/redis-stack:latest
        ```

        The `REDIS_OM_URL` need to be set before loading and saving agents:
        either set the env variable in the `.env` file and use `uv run --env-file .env` to run the command.
        or set the env variable in the conda environment:
        ```bash
        conda env config vars set REDIS_OM_URL="redis://user:password@host:port"
        ```
      </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-2">
        <AccordionTrigger>No, I don't want to use Docker. (Okay, we don't recommend this)</AccordionTrigger>
        <AccordionContent>
        <Tabs defaultValue="linux" className="w-full">
        <TabsList>
          <TabsTrigger value="linux">Linux</TabsTrigger>
          <TabsTrigger value="mac">MacOS</TabsTrigger>
          <TabsTrigger value="windows">Windows</TabsTrigger>
        </TabsList>
        <TabsContent value="linux">

        <Steps>
        ### Download the Redis stack
        ```bash
        # if you are using Ubunutu 20.04
        curl -fsSL https://packages.redis.io/redis-stack/redis-stack-server-7.2.0-v10.focal.x86_64.tar.gz -o redis-stack-server.tar.gz
        tar -xvzf redis-stack-server.tar.gz
        export PATH=$(pwd)/redis-stack-server-7.2.0-v10/bin:$PATH
        # if you are using Ubunutu 22.04, please do an extra step
        wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
        sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
        ```

        ### Start the server
        ```bash
        ./redis-stack-server-7.2.0-v10/bin/redis-stack-server --daemonize yes
        ```



        ### The `REDIS_OM_URL` need to be set before loading and saving agents:
        ```bash
        conda env config vars set REDIS_OM_URL="redis://user:password@host:port"
        ```
        If you are using the default settings, you can set the `REDIS_OM_URL` to `redis://localhost:6379`.
        </Steps>
        </TabsContent>
         <TabsContent value="mac">
         <Steps>
        ### Download the Redis stack
        ```bash
        brew tap redis-stack/redis-stack
        brew install redis-stack
        ```

        ### Start the server
        ```bash
        redis-stack-server --daemonize yes
        ```

        For other platforms, please check the [instruction](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/).

        ### Set the environment variable:
        The `REDIS_OM_URL` need to be set before loading and saving agents
        ```bash
        conda env config vars set REDIS_OM_URL="redis://user:password@host:port"
        ```
        If you are using the default settings, you can set the `REDIS_OM_URL` to `redis://localhost:6379`.
        </Steps>
         </TabsContent>
          <TabsContent value="windows">
          For Windows, unfortunately only docker is supported. Check the [official documentation](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/windows/).
          </TabsContent>
      </Tabs>
        </AccordionContent>
      </AccordionItem>
</Accordion>

## Quick Start

You can view an episode demo with default parameters with the following:
```python
import asyncio
from sotopia.samplers import UniformSampler
from sotopia.server import run_async_server

asyncio.run(
    run_async_server(
        model_dict={
            "env": "gpt-4",
            "agent1": "gpt-4o-mini",
            "agent2": "gpt-4o-mini",
        },
        sampler=UniformSampler(),
    )
)
```
or if you have cloned the repo, run
```bash
python examples/minimalist_demo.py
```
