diff --git a/libs/acp/Makefile b/libs/acp/Makefile new file mode 100644 index 00000000..93ad4394 --- /dev/null +++ b/libs/acp/Makefile @@ -0,0 +1,53 @@ +.PHONY: all lint format test help + +# Default target executed when no arguments are given to make. +all: help + +###################### +# TESTING AND COVERAGE +###################### + +# Define a variable for the test file path. +TEST_FILE ?= tests/ + +test: + uv run pytest --disable-socket --allow-unix-socket $(TEST_FILE) --timeout 10 + +test_watch: + uv run ptw . -- $(TEST_FILE) + + +###################### +# LINTING AND FORMATTING +###################### + +# Define a variable for Python and notebook files. +lint format: PYTHON_FILES=deepagents_cli/ tests/ +lint_diff format_diff: PYTHON_FILES=$(shell git diff --relative=. --name-only --diff-filter=d master | grep -E '\.py$$|\.ipynb$$') + +lint lint_diff: + [ "$(PYTHON_FILES)" = "" ] || uv run ruff format $(PYTHON_FILES) --diff + [ "$(PYTHON_FILES)" = "" ] || uv run ruff check $(PYTHON_FILES) --diff + # [ "$(PYTHON_FILES)" = "" ] || uv run mypy $(PYTHON_FILES) + +format format_diff: + [ "$(PYTHON_FILES)" = "" ] || uv run ruff format $(PYTHON_FILES) + [ "$(PYTHON_FILES)" = "" ] || uv run ruff check --fix $(PYTHON_FILES) + + + +###################### +# HELP +###################### + +help: + @echo '====================' + @echo '-- LINTING --' + @echo 'format - run code formatters' + @echo 'lint - run linters' + @echo '-- TESTS --' + @echo 'test - run unit tests' + @echo 'test TEST_FILE= - run all tests in file' + @echo '-- DOCUMENTATION tasks are from the top-level Makefile --' + + diff --git a/libs/acp/README.md b/libs/acp/README.md new file mode 100644 index 00000000..3627ee62 --- /dev/null +++ b/libs/acp/README.md @@ -0,0 +1 @@ +# ACP diff --git a/libs/acp/deepagents_acp/__init__.py b/libs/acp/deepagents_acp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/libs/acp/deepagents_acp/client.py b/libs/acp/deepagents_acp/client.py new file mode 100644 index 00000000..ec55b133 --- /dev/null +++ b/libs/acp/deepagents_acp/client.py @@ -0,0 +1,176 @@ +import asyncio +import asyncio.subprocess as aio_subprocess +import contextlib +import logging +import os +import sys + +from acp import ( + Client, + ClientSideConnection, + InitializeRequest, + NewSessionRequest, + PromptRequest, + RequestError, + SessionNotification, + text_block, + PROTOCOL_VERSION, +) +from acp.schema import ( + AgentMessageChunk, + AudioContentBlock, + ClientCapabilities, + EmbeddedResourceContentBlock, + ImageContentBlock, + Implementation, + ResourceContentBlock, + TextContentBlock, +) + + +class ExampleClient(Client): + async def requestPermission(self, params): # type: ignore[override] + raise RequestError.method_not_found("session/request_permission") + + async def writeTextFile(self, params): # type: ignore[override] + raise RequestError.method_not_found("fs/write_text_file") + + async def readTextFile(self, params): # type: ignore[override] + raise RequestError.method_not_found("fs/read_text_file") + + async def createTerminal(self, params): # type: ignore[override] + raise RequestError.method_not_found("terminal/create") + + async def terminalOutput(self, params): # type: ignore[override] + raise RequestError.method_not_found("terminal/output") + + async def releaseTerminal(self, params): # type: ignore[override] + raise RequestError.method_not_found("terminal/release") + + async def waitForTerminalExit(self, params): # type: ignore[override] + raise RequestError.method_not_found("terminal/wait_for_exit") + + async def killTerminal(self, params): # type: ignore[override] + raise RequestError.method_not_found("terminal/kill") + + async def sessionUpdate(self, params: SessionNotification) -> None: + update = params.update + if not isinstance(update, AgentMessageChunk): + return + + content = update.content + text: str + if isinstance(content, TextContentBlock): + text = content.text + elif isinstance(content, ImageContentBlock): + text = "" + elif isinstance(content, AudioContentBlock): + text = "