Skip to content

Commit

Permalink
Merge branch 'main' into rl_for_math
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexPiche authored Dec 2, 2024
2 parents b7f669e + 8e45ab7 commit a4e6204
Show file tree
Hide file tree
Showing 93 changed files with 4,325 additions and 1,709 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ jobs:
with:
python-version: "3.10"
cache: "pip"
- name: Install pypa/build
run: python3 -m pip install build --user
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.dev.txt -r requirements.txt -r requirements.finetune.txt
- name: Build core
run: |
pip install -e .
- name: Build a binary wheel and a source tarball
run: python3 -m build --outdir dist/
105 changes: 105 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Release package to PyPI and GitHub
# based on official doc
# https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/


on: push
jobs:
build:
name: Build distribution
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install pypa/build
run: python3 -m pip install build --user
- name: Build a binary wheel and a source tarball
run: python3 -m build --outdir dist/
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

publish-to-pypi:
name: >-
Publish Python distribution to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
needs:
- build
runs-on: ubuntu-22.04
environment:
name: pypi
url: https://pypi.org/p/TapeAgents
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

github-release:
name: >-
Sign the Python distribution with Sigstore and upload them to GitHub Release
needs:
- publish-to-pypi
runs-on: ubuntu-22.04

permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/

- name: Sign the dists with Sigstore
uses: sigstore/[email protected]
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--notes ""
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
- name: Set GitHub Release as pre-release
if: contains(github.ref, '.dev') # set releases with tags vA.B.C.devD as pre-release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release edit
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--prerelease
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,6 @@ cython_debug/
/wandb/
config_tree
outputs/
data/
package-lock.json
package.json
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: setup env install lint test test-slow test-all clean update-intro update-clean-intro clear-clean-intro
.PHONY: setup env install lint test test-slow test-all clean update-intro update-clean-intro clear-clean-intro build

ENV_NAME=tapeagents
PYTHON_VERSION=3.10
Expand Down Expand Up @@ -44,3 +44,8 @@ update-clean-intro:

clear-clean-intro:
@$(CONDA) run --no-capture-output --name ${ENV_NAME} jupyter nbconvert --inplace examples/intro_clean.ipynb --ClearOutputPreprocessor.enabled=True --ClearMetadataPreprocessor.enabled=True

build:
@mkdir -p dist
@rm dist/*
@python3 -m build --outdir dist/
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<div align="center">

# TapeAgents

[![GitHub Release](https://img.shields.io/github/v/release/ServiceNow/TapeAgents?logo=bookstack&logoColor=white)](https://github.com/ServiceNow/TapeAgents/releases)
[![PyPI - Version](https://img.shields.io/pypi/v/TapeAgents?logo=pypi&logoColor=white)](https://pypi.org/project/TapeAgents/)
[![Documentation](https://img.shields.io/badge/MkDocs-Documentation-blue?logo=materialformkdocs&logoColor=white)](https://servicenow.github.io/TapeAgents/)
![Build Status](https://github.com/ServiceNow/TapeAgents/actions/workflows/build.yml/badge.svg)
![Tests Status](https://github.com/ServiceNow/TapeAgents/actions/workflows/python-tests.yml/badge.svg)
![Supported Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)

</div>


**TapeAgents** is a framework that leverages a structured, replayable log (**Tape**) of the agent session to facilitate all stages of the LLM Agent development lifecycle. In TapeAgents, the agent reasons by processing the tape and the LLM output to produce new thoughts, actions, control flow steps and append them to the tape. The environment then reacts to the agent’s actions by likewise appending observation steps to the tape.

![image](/assets/overview.png)
![image](https://github.com/ServiceNow/TapeAgents/raw/main/assets/overview.png)


Key features:
Expand All @@ -27,28 +27,27 @@ The Tape-centric design of TapeAgents will help you at all stages of your projec

# Get Started

We highly recommend starting with the [introductory Jupyter notebook](/intro.ipynb). The notebook will introduce you to all the core concepts of framework.
We highly recommend starting with the [introductory Jupyter notebook](https://github.com/ServiceNow/TapeAgents/blob/main/intro.ipynb). The notebook will introduce you to all the core concepts of framework.

# Installation
Install the latest release:
```
pip install TapeAgents
```

If you want to install the version from the sources:
1. Clone the repository:
```
git clone https://github.com/ServiceNow/TapeAgents.git
cd TapeAgents
```

2. Create conda environment and install the package in editable mode:
2. Create conda environment `tapeagents` and install the package in editable mode inside the environment:
```
make setup
```

# Examples

To run the example, first activate the `tapeagents` environment that was created during the setup process:
```bash
conda activate tapeagents
```

The simplest agent just to show the basic structure of the agent:
```python
from tapeagents.agent import Agent, Node
Expand Down Expand Up @@ -76,16 +75,16 @@ final_tape = agent.run(start_tape).get_final_tape() # agent will start executin
print(f"Final tape: {final_tape.model_dump_json(indent=2)}")
```

The [examples/](examples/) directory contains examples of how to use the TapeAgents framework for building, debugging, serving and improving agents. Each example is a self-contained Python script (or module) that demonstrates how to use the framework to build an agent for a specific task.
The [examples/](https://github.com/ServiceNow/TapeAgents/tree/main/examples) directory contains examples of how to use the TapeAgents framework for building, debugging, serving and improving agents. Each example is a self-contained Python script (or module) that demonstrates how to use the framework to build an agent for a specific task.

- How to build a single agent that [does planning, searches the web and uses code interpreter](examples/gaia_agent) to answer knowledge-grounded questions, solving the tasks from the [GAIA benchmark](https://huggingface.co/spaces/gaia-benchmark/leaderboard).
- How to build [a team of TapeAgents](examples/data_science) with [AutoGen](https://github.com/microsoft/autogen)-style low-code programming paradigm
- How to [finetune a TapeAgent](examples/gsm8k_tuning) with a small LLM to be better at math problem solving on GSM-8k dataset.
- How to build a single agent that [does planning, searches the web and uses code interpreter](https://github.com/ServiceNow/TapeAgents/tree/main/examples/gaia_agent) to answer knowledge-grounded questions, solving the tasks from the [GAIA benchmark](https://huggingface.co/spaces/gaia-benchmark/leaderboard).
- How to build [a team of TapeAgents](https://github.com/ServiceNow/TapeAgents/tree/main/examples/data_science) with [AutoGen](https://github.com/microsoft/autogen)-style low-code programming paradigm
- How to [finetune a TapeAgent](https://github.com/ServiceNow/TapeAgents/tree/main/examples/gsm8k_tuning) with a small LLM to be better at math problem solving on GSM-8k dataset.


Other notable examples that demonstrate the main aspects of the framework:
- [workarena](examples/workarena) - custom agent that solves [WorkArena](https://github.com/ServiceNow/WorkArena) benchmark using [BrowserGym](https://github.com/ServiceNow/BrowserGym) environment.
- [tape_improver.py](examples/tape_improver.py) - the agent that revisit and improves the tapes produced by another agent.
- [workarena](https://github.com/ServiceNow/TapeAgents/tree/main/examples/workarena) - custom agent that solves [WorkArena](https://github.com/ServiceNow/WorkArena) benchmark using [BrowserGym](https://github.com/ServiceNow/BrowserGym) environment.
- [tape_improver.py](https://github.com/ServiceNow/TapeAgents/tree/main/examples/tape_improver) - the agent that revisit and improves the tapes produced by another agent.


# Learn more
Expand All @@ -98,6 +97,7 @@ Feel free to reach out to the team:
- Dzmitry Bahdanau, [email protected]
- Oleh Shliazhko, [email protected]
- Jordan Prince Tremblay, [email protected]
- Alexandre Piché, [email protected]

# Acknowledgements

Expand Down
6 changes: 3 additions & 3 deletions conf/gaia_llama.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defaults:
- _self_

exp_name: llama3_405b_1
exp_path: ../gaia/runs/${exp_name}
data_dir: ../gaia/dataset/validation/
exp_path: outputs/gaia/runs/${exp_name}
split: validation
n_attempts: 1
agent:
planning_mode: simple
Expand All @@ -17,4 +17,4 @@ env:

hydra:
run:
dir: ../gaia/runs/${exp_name}
dir: outputs/gaia/runs/${exp_name}
6 changes: 3 additions & 3 deletions conf/gaia_openai.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defaults:
- _self_

exp_name: gpt4o_mini_val_batch32_6
exp_path: ../gaia/runs/${exp_name}
data_dir: ../gaia/dataset/validation/
exp_path: outputs/gaia/runs/${exp_name}
split: validation
n_attempts: 1
batch: 32
agent:
Expand All @@ -18,4 +18,4 @@ env:

hydra:
run:
dir: ../gaia/runs/${exp_name}
dir: outputs/gaia/runs/${exp_name}
28 changes: 28 additions & 0 deletions docs/css/mkdocstrings.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
h5 {
font-size: 1.25em !important;
font-weight: 400 !important;
}

h3,
h4,
h5 {
margin: 1.6em 0 .64em !important;
}

.doc-object {
margin-top: 4em !important;
}

:root {
--md-primary-fg-color: #1f8476;
--md-primary-fg-color--light: #80b6a1;
--md-primary-fg-color--dark: #293e40;
}

code.doc-symbol-method::after {
content: "method" !important;
}

code.doc-symbol-module::after {
content: "module" !important;
}
52 changes: 52 additions & 0 deletions docs/gen_ref_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Generate the code reference pages."""

from pathlib import Path

import mkdocs_gen_files

project = "tapeagents"
nav = mkdocs_gen_files.Nav()
root = Path(__file__).parent.parent
src = root / project

for path in sorted(src.rglob("*.py")):
module_path = path.relative_to(src).with_suffix("")
doc_path = path.relative_to(src).with_suffix(".md")
full_doc_path = Path("reference", doc_path)

parts = (project,) + module_path.parts

if parts[-1] == "__init__":
parts = parts[:-1]
doc_path = doc_path.with_name("index.md")
full_doc_path = full_doc_path.with_name("index.md")
elif parts[-1] == "__main__":
continue
if not doc_path:
continue

nav_aliases = {
"io": "IO",
"rl": "RL",
"llms": "LLMs",
"llm_function": "LLM Function",
}
nav_key = list(parts[1:])
if nav_key:
for i in range(len(nav_key)):
if nav_key[i] in nav_aliases:
nav_key[i] = nav_aliases[nav_key[i]]
else:
nav_key[i] = nav_key[i].title().replace("_", " ").strip()
nav_key = tuple(nav_key)
nav[nav_key] = doc_path.as_posix()

with mkdocs_gen_files.open(full_doc_path, "w") as fd:
identifier = ".".join(parts)
if identifier:
print(f"::: {identifier}", file=fd)

mkdocs_gen_files.set_edit_path(full_doc_path, path.relative_to(root))

with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
nav_file.writelines(nav.build_literate_nav())
7 changes: 7 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# TapeAgents Documentation

**TapeAgents** is a framework that leverages a structured, replayable log (**Tape**) of the agent session to facilitate all stages of the LLM Agent development lifecycle. In TapeAgents, the agent reasons by processing the tape and the LLM output to produce new thoughts, actions, control flow steps and append them to the tape. The environment then reacts to the agent’s actions by likewise appending observation steps to the tape.

## Contents
- [Quick Start](quickstart.md) - Get started with TapeAgents.
- [Reference](reference/) - Detailed documentation of the TapeAgents framework.
1 change: 1 addition & 0 deletions docs/quickstart.md
5 changes: 3 additions & 2 deletions examples/annotator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
AnnotationAction,
AnnotatorFreeFormThought,
AssistantStep,
DialogTape,
DialogAnnotator,
DialogAnnotatorTape,
DialogContext,
DialogTape,
ToolCalls,
ToolResult,
ToolSpec,
UserStep,
)
from tapeagents.llms import LiteLLM, LLMStream
from tapeagents.rendering import render_dialog_plain_text
from tapeagents.renderers import render_dialog_plain_text

_ANNOTATOR_PROMPT: str = """Here is a dialog between a user and an assistant.
Expand All @@ -43,6 +43,7 @@ class GroundednessAnnotator(DialogAnnotator):
Annotates the steps of a given dialog tape based on the results of function calls in the tape.
Produces the binary correctness of the assistant's last message.
"""

def make_prompt(self, tape: DialogAnnotatorTape):
"""
Creates a prompt for the annotator based on the dialog tape.
Expand Down
Loading

0 comments on commit a4e6204

Please sign in to comment.