Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion connectors/mongo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def delete_records(


def parse_object_id_to_str(
data: Union[Dict[str, Any], List[Any], ObjectId]
data: Union[Dict[str, Any], List[Any], ObjectId],
) -> Union[Dict[str, Any], List[Any], str]:
"""Parses ObjectId to string recursively.

Expand Down
10 changes: 10 additions & 0 deletions docs/source/eval_framework/specs/conv_agent_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ paths:
annotations: []
metadata:
genre: "Action"
500:
description: Error in processing the utterance or generating the response.
schema:
type: object
properties:
message:
type: string
examples:
application/json:
message: "Error in response generation."

/configure:
post:
Expand Down
40 changes: 40 additions & 0 deletions docs/source/eval_framework/specs/user_simulator_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ paths:
dialogue_acts: []
annotations: []
metadata: {}
500:
description: Error in processing the utterance or generating the response.
schema:
type: object
properties:
message:
type: string
examples:
application/json:
message: "Error in response generation."

/configure:
post:
Expand Down Expand Up @@ -159,6 +169,26 @@ paths:
examples:
application/json:
message: "Information need set successfully"
400:
description: Error in the process
schema:
type: object
properties:
message:
type: string
examples:
application/json:
message: "Error in setting the information need."
500:
description: Internal server error
schema:
type: object
properties:
message:
type: string
examples:
application/json:
message: "Internal server error."

/get_information_need:
post:
Expand Down Expand Up @@ -194,6 +224,16 @@ paths:
- "director"
fulfilled_slots:
title: "Top Gun"
500:
description: Internal server error
schema:
type: object
properties:
message:
type: string
examples:
application/json:
message: "Internal server error."

definitions:
DialogueAct:
Expand Down
2 changes: 1 addition & 1 deletion simlab/utils/participant_api/utils_response_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


def parse_API_response(
api_response: Dict[str, Any]
api_response: Dict[str, Any],
) -> Tuple[str, List[DialogueAct], List[Annotation], Dict[str, Any]]:
"""Parses the response from the API.

Expand Down
6 changes: 6 additions & 0 deletions starterkits/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Starter Kits

This directory contains two starter kits to build conversational agents and user simulators for SimLab. Each starter kit provides a Dockerfile template and a template for the communication API.

* [Conversational Agent Starter Kit](agent/README.md)
* [User Simulator Starter Kit](simulator/README.md)
36 changes: 36 additions & 0 deletions starterkits/agent/Dockerfile.temp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Template Dockerfile to create a Docker image of a conversation agent.
# Placeholders are indicated by `<placeholder>` and TODO comments and should be replaced with actual values.
FROM <base_image>

# Labels for the image
LABEL type="agent"
LABEL name=<agent_name>
LABEL description=<agent_description>
LABEL author=<author_name>
LABEL version=<version_number>
LABEL tag=<tag>
LABEL port=5005

# Set the working directory
WORKDIR /

# TODO: Install any dependencies required for the agent.
# Example: python requirements
# COPY requirements.txt requirements.txt
# RUN pip install --no-cache-dir -r requirements.txt

# Copy the agent source code into the image
COPY src/ src/

# TODO: If the agent requires any additional files, copy them here.
# Example: data files
# COPY data/ data/

# Expose the port the agent will run on. This should match the LABEL port, defaults to 5005.
EXPOSE 5005

# Command to run the agent. This should be replaced with the actual command to start your agent.
# Example for a Flask app:
# CMD ["python", "-m", "src.api_template_flask"]

CMD [<start_command>]
78 changes: 78 additions & 0 deletions starterkits/agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Conversational Agent Starter Kit

This starter kit provides a template to create a compatible conversational agent and its associated image for SimLab.

## Structure

The starter kit is organized as follows:

* `Dockerfile.temp`: A template with placeholders to build the agent's Docker image.
* `src/`: Provides templates with placeholder implementation for the communication API. The different templates correspond to different languages and frameworks.
- `src/api_template_flask.py`: A template for a Flask-based API.
- `src/api_template_fastapi.py`: A template for a FastAPI-based API.

## Getting Started

**Prerequisites:**

* Familiarity with the communication API of SimLab. See the [specification](https://github.com/iai-group/simlab/blob/main/docs/source/eval_framework/specs/conv_agent_api.yaml) for details.
* Basic knowledge of Docker and how to build Docker images.

To create a new conversational agent, you need to:

1. **Create a new repository**.
2. **Copy the starter kit** into your new repository.

Then you can start the implementation of your agent by modifying the templates in the `src/` directory and the `Dockerfile.temp`. Explanations on how to proceed are provided in the following sections.

## Implementation

### Communication API

In `src/`, you will find templates for the communication API in different languages and frameworks. You can choose the one that best fits your needs and preferences. The templates include placeholders and comments to guide you through the implementation process.

Placeholders in the templates include:

* Implementation of the logic to handle the reception and response to incoming user messages in `receive_message()`. Note that the different elements of the response are set to `None` by default and should be replaced with the actual implementation.
* Implementation of the logic to validate the agent's configuration in `configure()`. That is, making sure that the `agent_id` and `parameters` are valid and that the agent can be configured with the provided parameters.
* Implementation of the logic to configure the agent based on the provided parameters in `configure()`.

### Dockerfile

Start by renaming the `Dockerfile.temp` to `Dockerfile`. Then, you can edit the file based on the different placeholders and comments provided in the file. Please note that additional modifications may be required to adapt the Dockerfile to your specific agent's requirements.

In its current state, the template provides the list of labels required by SimLab, as well as commands to copy the source code and expose the port used by the communication API.

Placeholders in the Dockerfile include:

* `<base_image>`: The base image to use for your agent. You can choose a base image that fits your needs, such as `python:3.9-slim` or `ubuntu:20.04`.
* Labels to provide metadata about your agent, such as:
- `<agent_name>`
- `<agent_description>`
- `<author_name>`
- `<version_number>`
- `<tag>`
* Commands to install the necessary dependencies for your agent, such as:
- `pip install -r requirements.txt` for Python-based agents.
- `apt-get install -y <package>` for system-level dependencies.
* Commands to copy files required to run your agent, such as:
- `COPY data/ data/` to copy data files.
- `COPY configuration.yaml configuration.yaml` to copy configuration files.
* Command to run your agent, such as:
- `CMD ["python", "src/api_template_flask.py"]` for a Flask-based agent.

## Docker Image

You can build the Docker image for your agent using the following command from the root of your repository:

```bash
docker build -t [username]/[name]:[tag] .
```

Then, you can create the archive for your agent using the following command:

```bash
docker save [username]/[name]:[tag] | gzip > [archive-name].tar.gz
```

Replace `[username]`, `[name]`, and `[tag]` with your SimLab username, the name of your agent, and the tag of the image, respectively.
87 changes: 87 additions & 0 deletions starterkits/agent/src/api_template_flask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""Conversational agent API template for Flask framework.

This file contains methods with placeholders for the API endpoints described in
the documentation. Placeholders are indicated by TODO comments."""

from flask import Flask, request, jsonify, Response
from typing import List, Dict

app = Flask(__name__)


@app.route("/receive_utterance", methods=["POST"])
def receive_utterance() -> Response:
"""Receives an utterance from the user and sends a response.

Returns:
Response to user.
"""
try:
context = request.json.get("context")
user_id = request.json.get("user_id")
agent_id = request.json.get("agent_id")
utterance = request.json.get("message")

# TODO: implement logic to process an utterance and generate a response.
# Check documentation for further details on the expected format of
# the different elements of the response.
response: str = None # Placeholder for response, defaults to None
dialogue_acts: List = (
None # Placeholder for dialogue acts, defaults to None. Optional.
)
annotations: List = (
None # Placeholder for annotations, defaults to None. Optional.
)
metadata: Dict = (
None # Placeholder for metadata, defaults to None. Optional.
)

return (
jsonify(
{
"message": response,
"dialogue_acts": dialogue_acts,
"annotations": annotations,
"metadata": metadata,
}
),
200,
)
except Exception as e:
return jsonify({"message": str(e)}), 500


@app.route("/configure", methods=["POST"])
def configure() -> Response:
"""Configures the agent with custom parameters.

Returns:
Whether the configuration was successful.
"""
try:
agent_id = request.json.get("id")
parameters = request.json.get("parameters")

# TODO: Validate agent_id and parameters
b_valid_configuration = (
False # Placeholder for validation, defaults to False
)

if not b_valid_configuration:
return jsonify({"message": "Invalid configuration"}), 400

# TODO: Implement configuration logic

b_success = False # Placeholder for success status, defaults to False

if b_success:
return jsonify({"message": "Configuration successful"}), 201

return (
jsonify(
{"message": "An issue occurred when configuring the agent"}
),
400,
)
except Exception as e:
return jsonify({"message": str(e)}), 500
1 change: 1 addition & 0 deletions tests/backend/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module level init for backend tests."""

from bson import ObjectId

from connectors.mongo.mongo_connector import MongoDBConnector
Expand Down
Loading