diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4eb1c5cf..f5e162bf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: uses: ./.github/actions/setup-poetry-env - name: Run checks - run: cd arcade && make check + run: make check tox: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 8644224d..54632f88 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .DS_Store +arcade.toml +docker/arcade.toml *.lock diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..86b16d44 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ + + +.PHONY: install +install: ## Install the poetry environment and install the pre-commit hooks + @echo "šŸš€ Creating virtual environment using pyenv and poetry" + @cd arcade && poetry install + @cd arcade && poetry run pre-commit install + @cd arcade && poetry shell + +.PHONY: check +check: ## Run code quality tools. + @echo "šŸš€ Checking Poetry lock file consistency with 'pyproject.toml': Running poetry check --lock" + @cd arcade && poetry check --lock + @echo "šŸš€ Linting code: Running pre-commit" + @cd arcade && poetry run pre-commit run -a + @echo "šŸš€ Static type checking: Running mypy" + @cd arcade && poetry run mypy $(git ls-files '*.py') + +.PHONY: test +test: ## Test the code with pytest + @echo "šŸš€ Testing code: Running pytest" + @cd arcade && poetry run pytest -v --cov --cov-config=pyproject.toml --cov-report=xml + +.PHONY: build +build: clean-build ## Build wheel file using poetry + @echo "šŸš€ Creating wheel file" + @cd arcade && poetry build + +.PHONY: clean +clean: ## clean build artifacts + @cd arcade && rm -rf dist + +.PHONY: publish +publish: ## publish a release to pypi. + @echo "šŸš€ Publishing: Dry run." + @cd arcade && poetry config pypi-token.pypi $(PYPI_TOKEN) + @cd arcade && poetry publish --dry-run + @echo "šŸš€ Publishing." + @cd arcade && poetry publish + +.PHONY: build-and-publish +build-and-publish: build publish ## Build and publish. + +.PHONY: docs-test +docs-test: ## Test if documentation can be built without warnings or errors + @cd arcade && poetry run mkdocs build -s + +.PHONY: docs +docs: ## Build and serve the documentation + @cd arcade && poetry run mkdocs serve -a localhost:8777 + +.PHONY: docker +docker: ## Build and run the Docker container + @cd docker && make docker-build + @cd docker && make docker-run + +.PHONY: help +help: + @echo "šŸ› ļø Arcade AI Dev Commands:\n" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.DEFAULT_GOAL := help diff --git a/arcade/Makefile b/arcade/Makefile deleted file mode 100644 index e2381cdb..00000000 --- a/arcade/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -VENDOR ?= ArcadeAI -PROJECT ?= ArcadeAI -SOURCE ?= https://github.com/ArcadeAI/arcade-ai -LICENSE ?= MIT -DESCRIPTION ?= "Arcade AI for LLM Tool Serving" -REPOSITORY ?= arcadeai/arcade-ai - -VERSION ?= dev -COMMIT ?= $(shell git describe --dirty --always --abbrev=15) -BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") -IMAGE_NAME ?= actor -PORT ?= 8000 - -.PHONY: install -install: ## Install the poetry environment and install the pre-commit hooks - @echo "šŸš€ Creating virtual environment using pyenv and poetry" - @poetry install - @poetry run pre-commit install - @poetry shell - -.PHONY: check -check: ## Run code quality tools. - @echo "šŸš€ Checking Poetry lock file consistency with 'pyproject.toml': Running poetry check --lock" - @poetry check --lock - @echo "šŸš€ Linting code: Running pre-commit" - @poetry run pre-commit run -a - @echo "šŸš€ Static type checking: Running mypy" - @poetry run mypy $(git ls-files '*.py') - -.PHONY: test -test: ## Test the code with pytest - @echo "šŸš€ Testing code: Running pytest" - @poetry run pytest -v --cov --cov-config=pyproject.toml --cov-report=xml - -.PHONY: build -build: clean-build ## Build wheel file using poetry - @echo "šŸš€ Creating wheel file" - @poetry build - -.PHONY: clean -clean: ## clean build artifacts - @rm -rf dist - -.PHONY: publish -publish: ## publish a release to pypi. - @echo "šŸš€ Publishing: Dry run." - @poetry config pypi-token.pypi $(PYPI_TOKEN) - @poetry publish --dry-run - @echo "šŸš€ Publishing." - @poetry publish - -.PHONY: build-and-publish -build-and-publish: build publish ## Build and publish. - -.PHONY: docs-test -docs-test: ## Test if documentation can be built without warnings or errors - @poetry run mkdocs build -s - -.PHONY: docs -docs: ## Build and serve the documentation - @poetry run mkdocs serve -a localhost:8777 - -.PHONY: docker-build -docker-build: ## Build the Docker container - @echo "šŸ› ļø Building Docker image ($(VERSION)).." - @echo "- Commit: $(COMMIT)" - @echo "- Build Date: $(BUILD_DATE)" - @docker build -f ../docker/Dockerfile ../ -t $(REPOSITORY):$(VERSION) \ - --build-arg PORT=$(PORT) \ - --build-arg VERSION="$(VERSION)" \ - --build-arg COMMIT="$(COMMIT)" \ - --build-arg BUILD_DATE="$(BUILD_DATE)" \ - --label=org.opencontainers.image.vendor="$(VENDOR)" \ - --label=org.opencontainers.image.title="$(PROJECT)" \ - --label=org.opencontainers.image.revision="$(COMMIT)" \ - --label=org.opencontainers.image.version="$(VERSION)" \ - --label=org.opencontainers.image.created="$(BUILD_DATE)" \ - --label=org.opencontainers.image.source="$(SOURCE)" \ - --label=org.opencontainers.image.licenses="$(LICENSE)" \ - --label=org.opencontainers.image.description=$(DESCRIPTION) - -.PHONY: docker-run -docker-run: ## Run the Docker container - @echo "šŸš€ Running Docker container ($(VERSION)).." - @docker run -p $(PORT):$(PORT) \ - -e WORK_DIR=/app/docker/ \ - $(REPOSITORY):$(VERSION) - -.PHONY: help -help: - @echo "šŸ› ļø Arcade AI Dev Commands:\n" - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -.DEFAULT_GOAL := help diff --git a/docker/Dockerfile b/docker/Dockerfile index 9d0742d8..eb481a0f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,10 +1,14 @@ # Use a lightweight Python image FROM python:3.10-slim -# Set environment variables -ENV POETRY_VERSION=1.8.3 -ENV PORT=8001 -ENV HOST=0.0.0.0 +# Define build arguments with default values +ARG PORT=8001 +ARG HOST=0.0.0.0 + +# Set environment variables using the build arguments +ENV PORT=${PORT} +ENV HOST=${HOST} +ENV WORK_DIR=/app # Install system dependencies RUN apt-get update && apt-get install -y \ @@ -13,41 +17,28 @@ RUN apt-get update && apt-get install -y \ libssl-dev \ libffi-dev \ python3-dev \ + curl \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -# Install Poetry -RUN python -m pip install "poetry==$POETRY_VERSION" - -# Set the working directory WORKDIR /app # Copy the parent directory contents into the container COPY . . -WORKDIR /app/arcade - # Build the project and install the wheel with extras -RUN python -m poetry build && \ - pip install dist/arcade_ai-0.1.0-py3-none-any.whl[fastapi,dev] - -WORKDIR /app +RUN python -m pip install dist/arcade_ai-0.1.0-py3-none-any.whl[fastapi,dev] uvicorn # Install toolkits from the toolkits directory RUN set -e; \ - for toolkit in /app/toolkits/*; do \ - echo "Installing toolkit $(basename $toolkit) "; \ - cd $toolkit; \ - python -m poetry build; \ - pip install dist/*.whl; \ + for toolkit in dist/toolkits/*; do \ + echo "Installing toolkit $toolkit"; \ + pip install $toolkit; \ done + # Expose the port EXPOSE $PORT -WORKDIR /app/arcade - -RUN pip install uvicorn - # Run the arcade dev command CMD arcade dev --host $HOST --port $PORT diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 00000000..e859cf16 --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,44 @@ +VENDOR ?= ArcadeAI +PROJECT ?= ArcadeAI +SOURCE ?= https://github.com/ArcadeAI/arcade-ai +LICENSE ?= MIT +DESCRIPTION ?= "Arcade AI for LLM Tool Serving" +REPOSITORY ?= arcadeai/arcade-ai + +VERSION ?= dev +COMMIT ?= $(shell git describe --dirty --always --abbrev=15) +BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") +IMAGE_NAME ?= actor +PORT ?= 8002 + + +.PHONY: docker-build +docker-build: ## Build the Docker container + @echo "šŸ› ļø Building Docker image ($(VERSION)).." + @echo "- Commit: $(COMMIT)" + @echo "- Build Date: $(BUILD_DATE)" + @docker build --build-arg PORT=$(PORT) -t $(REPOSITORY):$(VERSION) . \ + --build-arg PORT=$(PORT) \ + --build-arg VERSION="$(VERSION)" \ + --build-arg COMMIT="$(COMMIT)" \ + --build-arg BUILD_DATE="$(BUILD_DATE)" \ + --label=org.opencontainers.image.vendor="$(VENDOR)" \ + --label=org.opencontainers.image.title="$(PROJECT)" \ + --label=org.opencontainers.image.revision="$(COMMIT)" \ + --label=org.opencontainers.image.version="$(VERSION)" \ + --label=org.opencontainers.image.created="$(BUILD_DATE)" \ + --label=org.opencontainers.image.source="$(SOURCE)" \ + --label=org.opencontainers.image.licenses="$(LICENSE)" \ + --label=org.opencontainers.image.description=$(DESCRIPTION) + +.PHONY: docker-run +docker-run: ## Run the Docker container + @echo "\nšŸš€ Run the container with the following ..." + @echo ">>> docker run -d -p $(PORT):$(PORT) $(REPOSITORY):$(VERSION)" + +.PHONY: help +help: + @echo "šŸ› ļø Actor Docker Commands:\n" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.DEFAULT_GOAL := help diff --git a/docker/arcade.toml b/docker/arcade.toml deleted file mode 100644 index e4965966..00000000 --- a/docker/arcade.toml +++ /dev/null @@ -1,8 +0,0 @@ -[api] -key = "123456789" -secret = "196a8a25-fde8-453a-9f58-ff646a6e034d" - -[engine] -host = "arcade-engine" -port = "9099" -tls = false diff --git a/docker/toolkits.txt b/docker/toolkits.txt index 732094f5..70572bc8 100644 --- a/docker/toolkits.txt +++ b/docker/toolkits.txt @@ -1,3 +1,4 @@ gmail +slack github websearch diff --git a/examples/langchain/gmail.py b/examples/langchain/gmail.py index 1b8e8822..538904f8 100644 --- a/examples/langchain/gmail.py +++ b/examples/langchain/gmail.py @@ -18,13 +18,16 @@ from langgraph.prebuilt import create_react_agent # Uncomment the following lines if you have the LangSmith API key # os.environ["LANGCHAIN_TRACING_V2"] = "true" # os.environ["LANGCHAIN_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ") -# Step 3: Authenticate with Gmail +# +# Step 3 (Option 1) Manually authenticate with Gmail by creating your own google app, credentials, and handling tokens and Oauth # credentials = get_gmail_credentials( # token_file="token.json", # scopes=["https://mail.google.com/"], # client_secrets_file="credentials.json", # ) -# alternative way to authenticate with arcade +# +# ----------------- OR ----------------- +# Step 3 (Option 2) Use the Arcade SDK to authenticate with Gmail from arcade.client import Arcade, AuthProvider client = Arcade(base_url="http://localhost:9099", api_key=os.environ["ARCADE_API_KEY"])