diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f55865f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Test Suite + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11", "3.12", "3.13"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y libolm-dev build-essential + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install .[dev] + + - name: Run tests + run: python -m pytest tests/ -v diff --git a/nanobot/channels/matrix.py b/nanobot/channels/matrix.py index 0d7a908..3f3f132 100644 --- a/nanobot/channels/matrix.py +++ b/nanobot/channels/matrix.py @@ -149,13 +149,22 @@ class MatrixChannel(BaseChannel): name = "matrix" display_name = "Matrix" - def __init__(self, config: Any, bus: MessageBus): + def __init__( + self, + config: Any, + bus: MessageBus, + *, + restrict_to_workspace: bool = False, + workspace: str | Path | None = None, + ): super().__init__(config, bus) self.client: AsyncClient | None = None self._sync_task: asyncio.Task | None = None self._typing_tasks: dict[str, asyncio.Task] = {} - self._restrict_to_workspace = False - self._workspace: Path | None = None + self._restrict_to_workspace = bool(restrict_to_workspace) + self._workspace = ( + Path(workspace).expanduser().resolve(strict=False) if workspace is not None else None + ) self._server_upload_limit_bytes: int | None = None self._server_upload_limit_checked = False diff --git a/tests/test_commands.py b/tests/test_commands.py index 5848bd8..cb77bde 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -1,3 +1,4 @@ +import re import shutil from pathlib import Path from unittest.mock import AsyncMock, MagicMock, patch @@ -11,6 +12,12 @@ from nanobot.providers.litellm_provider import LiteLLMProvider from nanobot.providers.openai_codex_provider import _strip_model_prefix from nanobot.providers.registry import find_by_model + +def _strip_ansi(text): + """Remove ANSI escape codes from text.""" + ansi_escape = re.compile(r'\x1b\[[0-9;]*m') + return ansi_escape.sub('', text) + runner = CliRunner() @@ -228,10 +235,11 @@ def test_agent_help_shows_workspace_and_config_options(): result = runner.invoke(app, ["agent", "--help"]) assert result.exit_code == 0 - assert "--workspace" in result.stdout - assert "-w" in result.stdout - assert "--config" in result.stdout - assert "-c" in result.stdout + stripped_output = _strip_ansi(result.stdout) + assert "--workspace" in stripped_output + assert "-w" in stripped_output + assert "--config" in stripped_output + assert "-c" in stripped_output def test_agent_uses_default_config_when_no_workspace_or_config_flags(mock_agent_runtime):