diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..0f40e3aa --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +# Docker specific ignores: +.git + +# .gitignore ignores: +.env +.agents_workspace +.cache +__pycache__ +*.egg-info +logs +.mypy_cache +.pytest_cache diff --git a/.gitignore b/.gitignore index 43754f7a..55578600 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -requirements.txt -.venv .env .agents_workspace .cache diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e341e9b4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# Install Poetry and create venv in the builder step, +# then copy the venv to the runtime image, so that the runtime image is as small as possible. +FROM --platform=linux/amd64 python:3.10.14-slim-bookworm AS builder + +RUN pip install poetry==1.8.2 + +ENV POETRY_NO_INTERACTION=1 \ + POETRY_VIRTUALENVS_IN_PROJECT=1 \ + POETRY_VIRTUALENVS_CREATE=1 \ + POETRY_CACHE_DIR=/tmp/poetry_cache + +WORKDIR /app + +COPY pyproject.toml poetry.lock ./ + +RUN --mount=type=cache,target=$POETRY_CACHE_DIR poetry install --no-root --only main + +FROM --platform=linux/amd64 python:3.10.14-slim-bookworm AS runtime + +ENV VIRTUAL_ENV=/app/.venv \ + PATH="/app/.venv/bin:$PATH" + +WORKDIR /app + +COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} + +COPY prediction_market_agent ./prediction_market_agent + +ENV PYTHONPATH=/app + +CMD ["bash", "-c", "python prediction_market_agent/run_agent.py ${runnable_agent_name} ${market_type}"] diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..dfff0355 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# TODO: This should be automated as part of CI/CD pipeline, but for now, execute it locally on the main branch. +docker build . -t ghcr.io/gnosis/pma:latest && docker push ghcr.io/gnosis/pma:latest diff --git a/poetry.lock b/poetry.lock index f00b14ac..911be1d2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "aiohttp" diff --git a/prediction_market_agent/agents/coinflip_agent/deploy.py b/prediction_market_agent/agents/coinflip_agent/deploy.py new file mode 100644 index 00000000..22c5eede --- /dev/null +++ b/prediction_market_agent/agents/coinflip_agent/deploy.py @@ -0,0 +1,13 @@ +import random +import typing as t + +from prediction_market_agent_tooling.deploy.agent import DeployableAgent +from prediction_market_agent_tooling.markets.agent_market import AgentMarket + + +class DeployableCoinFlipAgent(DeployableAgent): + def pick_markets(self, markets: t.Sequence[AgentMarket]) -> t.Sequence[AgentMarket]: + return random.sample(markets, 1) + + def answer_binary_market(self, market: AgentMarket) -> bool | None: + return random.choice([True, False]) diff --git a/prediction_market_agent/run_agent.py b/prediction_market_agent/run_agent.py new file mode 100644 index 00000000..ff5eb4e8 --- /dev/null +++ b/prediction_market_agent/run_agent.py @@ -0,0 +1,31 @@ +""" +Entrypoint for running the agent in GKE. +If the agent adheres to PMAT standard (subclasses DeployableAgent), +simply add the agent to the `RunnableAgent` enum and then `RUNNABLE_AGENTS` dict. + +Can also be executed locally, simply by running `python prediction_market_agent/run_agent.py `. +""" + +from enum import Enum + +import typer +from prediction_market_agent_tooling.markets.markets import MarketType + +from prediction_market_agent.agents.coinflip_agent.deploy import DeployableCoinFlipAgent + + +class RunnableAgent(str, Enum): + coinflip = "coinflip" + + +RUNNABLE_AGENTS = { + RunnableAgent.coinflip: DeployableCoinFlipAgent, +} + + +def main(agent: RunnableAgent, market_type: MarketType) -> None: + RUNNABLE_AGENTS[agent]().run(market_type) + + +if __name__ == "__main__": + typer.run(main)