Skip to content

Commit

Permalink
Merge pull request #698 from ATheorell/agentP
Browse files Browse the repository at this point in the history
Adding official agent protocol test to ci + github badge
  • Loading branch information
pbharrin authored Sep 26, 2023
2 parents 94e67c4 + f833c08 commit d854f2a
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 32 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
name: Pip install and pytest
on:
pull_request:
branches: [main]
branches: [ main ]
paths:
- "**.py"
- "**.yaml"
- "**.yml"
push:
branches: [main]
branches: [ main ]
paths:
- "**.py"
- "**.yaml"
- "**.yml"

jobs:
test:
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/validate_agent_protocol.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Validate agent protocol compliance
on:
pull_request:
branches: [ main ]
paths:
- "**.py"
- "**.yaml"
- "**.yml"
push:
branches: [ main ]
paths:
- "**.py"
- "**.yaml"
- "**.yml"

jobs:
publish:
name: Validate agent protocol compliance
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install agent requirements
run: pip install .

- name: Check existence of OPENAI_API_KEY
run: |
if [[ -z "${OPENAI_API_KEY}" ]]; then
echo "OPENAI_API_KEY is empty"
else
echo "OPENAI_API_KEY has a length of ${#OPENAI_API_KEY}"
fi
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

- name: Run agent and validate compliance
run: |
python gpt_engineer/api.py & # Make sure to use the ampersand to detach your agent
URL=http://127.0.0.1:8000 bash -c "$(curl -fsSL https://agentprotocol.ai/test.sh)"
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
[![Discord Follow](https://dcbadge.vercel.app/api/server/8tcDQ89Ej2?style=flat)](https://discord.gg/8tcDQ89Ej2)
[![GitHub Repo stars](https://img.shields.io/github/stars/AntonOsika/gpt-engineer?style=social)](https://github.com/AntonOsika/gpt-engineer)
[![Twitter Follow](https://img.shields.io/twitter/follow/antonosika?style=social)](https://twitter.com/AntonOsika)
![Agent protocol](https://github.com/AntonOsika/gpt-engineer/actions/workflows/validate_agent_protocol.yaml/badge.svg)


**Specify what you want it to build, the AI asks for clarification, and then builds it.**

Expand Down
100 changes: 70 additions & 30 deletions gpt_engineer/api.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,109 @@
import os

from pathlib import Path

from agent_protocol import Agent, Step, Task

from agent_protocol import Agent, Step, Task, models
from gpt_engineer.db import DB
from gpt_engineer.main import main
from openai.error import AuthenticationError
import tempfile


async def task_handler(task: Task) -> None:
"""task_handler should create initial steps based on the input.
"""
Process the given task to set up the initial steps based on the task input.
Parameters:
- task (Task): An object containing task details, including the input prompt.
Behavior:
- Checks if the task has valid input.
- Reads additional input properties and sets up a workspace directory.
- Writes the prompt to a file.
- Registers the workspace directory as an artifact.
- Creates an initial step named "create_code".
The project is set up here.
Exceptions:
- Raises an exception if no input prompt is provided in the 'input' field of the task.
The prompt will be sent as task.input.
We will create a working directory in projects/<task_id>.
Returns:
- None
"""

# make sure we have a prompt or bail.
# Validate that we have a prompt or terminate.
if task.input is None:
raise Exception("No input prompt in the 'input' field.")

workspace = DB(f"projects/{task.task_id}")
# Extract additional properties from the task if available.
additional_input = dict()
if hasattr(task, "additional_input"):
if hasattr(task.additional_input, "__root__"):
additional_input = task.additional_input.__root__

# write prompt to a file
# Set up the root directory for the agent, defaulting to a temporary directory.
root_dir = additional_input.get("root_dir", tempfile.gettempdir())
additional_input["root_dir"] = root_dir

workspace = DB(os.path.join(root_dir, task.task_id))

# Write prompt to a file in the workspace.
workspace["prompt"] = f"{task.input}\n"

# write to consent file so we avoid hanging for a prompt
# Ensure no prompt hang by writing to the consent file.
consent_file = Path(os.getcwd()) / ".gpte_consent"
consent_file.write_text("false")

await Agent.db.create_artifact(
task_id=task.task_id,
relative_path="projects/",
file_name=f"projects/{task.task_id}",
relative_path=root_dir,
file_name=os.path.join(root_dir, task.task_id),
)

# pass options onto additional_properties
await Agent.db.create_step(
task_id=task.task_id,
name="create_code",
is_last=True,
additional_properties=task.additional_input.__root__
if task.additional_input is not None
else {},
additional_properties=additional_input,
)


async def step_handler(step: Step) -> Step:
"""
The code generation is run here. Any options are passed via task.additional_input.
Handle the provided step by triggering code generation or other operations.
Parameters:
- step (Step): An object containing step details and properties.
Improve code mode is not yet supported, but it would not be much work to support it.
A list of 'focus' files would need to be submitted in: task.additional_input.
Behavior:
- If not a dummy step, triggers the main code generation process.
- Handles potential authentication errors during code generation.
- Creates a dummy step if it's the last step to ensure continuity.
Returns:
- step (Step): Returns the processed step, potentially with modifications.
"""

main(
f"projects/{step.task_id}", # we could also make this an option
step.additional_properties.get("model", "gpt-4"),
step.additional_properties.get("temperature", 0.1),
"benchmark", # this needs to be headless mode
False,
step.additional_properties.get("azure_endpoint", ""),
step.additional_properties.get("verbose", False),
)
if not step.name == "Dummy step":
try:
main(
os.path.join(step.additional_properties["root_dir"], step.task_id),
step.additional_properties.get("model", "gpt-4"),
step.additional_properties.get("temperature", 0.1),
"benchmark",
False,
step.additional_properties.get("azure_endpoint", ""),
step.additional_properties.get("verbose", False),
)
except AuthenticationError:
print("The agent lacks a valid OPENAI_API_KEY to execute the requested step.")

if step.is_last:
await Agent.db.create_step(
step.task_id,
name=f"Dummy step",
input=f"Creating dummy step to not run out of steps after {step.name}",
is_last=True,
additional_properties={},
)
step.is_last = False

return step

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies = [
'tabulate == 0.9.0',
'python-dotenv >= 0.21.0',
'langchain >=0.0.240',
'agent-protocol==1.0.1',
]

classifiers = [
Expand Down

0 comments on commit d854f2a

Please sign in to comment.