From b22f4195bf119566a173dae8704b3cad3b27b7b4 Mon Sep 17 00:00:00 2001 From: galuszkm Date: Tue, 24 Mar 2026 01:25:24 +0100 Subject: [PATCH] feat: Add CLI and enhance documentation - Updated `config.yaml` in the streaming example to use `wire_event_queue()` instead of `make_event_queue()`. - Simplified installation instructions in the README for the agent factory example. - Improved the main README to clarify the purpose of hooks in the hooks example. - Added license, authors, and keywords to `pyproject.toml` for better package metadata. - Introduced a command-line interface (CLI) in `cli.py` for validating and loading YAML configurations. - Added type hints and documentation for agent and orchestration resolvers. - Enhanced error handling and logging in the `ToolNameSanitizer` hook. - Updated unit tests for the new CLI functionality, ensuring comprehensive coverage for both success and failure paths. - Added support for multi-file configuration in the CLI. - Included versioning and additional metadata in JSON outputs for CLI commands. --- .github/copilot-instructions.md | 4 +- AGENTS.md | 4 +- LICENSE | 1 - README.md | 40 +- SUPPORT.md | 3 + docs/index.html | 2 +- examples/10_nested/README.md | 26 +- examples/12_streaming/config.yaml | 2 +- examples/14_agent_factory/README.md | 2 +- examples/README.md | 4 +- pyproject.toml | 27 +- src/strands_compose/cli.py | 427 +++++++++++++++ .../config/resolvers/agents.py | 8 + .../resolvers/orchestrations/__init__.py | 8 + .../resolvers/orchestrations/builders.py | 2 + .../hooks/tool_name_sanitizer.py | 9 +- src/strands_compose/py.typed | 0 tests/unit/test_cli.py | 501 ++++++++++++++++++ tests/unit/test_event_queue.py | 15 +- uv.lock | 2 - 20 files changed, 1045 insertions(+), 42 deletions(-) create mode 100644 src/strands_compose/cli.py create mode 100644 src/strands_compose/py.typed create mode 100644 tests/unit/test_cli.py diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6e1b9ee..decb91f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -68,12 +68,12 @@ uv run just format # auto-format with ruff ``` src/strands_compose/ -├── __init__.py # Public API — load(), ComposeResult +├── __init__.py # Public API — load(), ResolvedConfig ├── models.py # Pydantic config models (AgentConfig, ModelConfig, …) ├── types.py # Shared type aliases ├── utils.py # Miscellaneous helpers ├── exceptions.py # Custom exception hierarchy -├── wire.py # Final assembly — wires all resolved objects into ComposeResult +├── wire.py # Final assembly — wires all resolved objects into ResolvedConfig ├── config/ # YAML loading, validation, interpolation │ ├── schema.py # JSON-schema for config validation │ ├── interpolation.py # ${VAR:-default} interpolation diff --git a/AGENTS.md b/AGENTS.md index 2b2acef..5cd587c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,12 +68,12 @@ uv run just format # auto-format with ruff ``` src/strands_compose/ -├── __init__.py # Public API — load(), ComposeResult +├── __init__.py # Public API — load(), ResolvedConfig ├── models.py # Pydantic config models (AgentConfig, ModelConfig, …) ├── types.py # Shared type aliases ├── utils.py # Miscellaneous helpers ├── exceptions.py # Custom exception hierarchy -├── wire.py # Final assembly — wires all resolved objects into ComposeResult +├── wire.py # Final assembly — wires all resolved objects into ResolvedConfig ├── config/ # YAML loading, validation, interpolation │ ├── schema.py # JSON-schema for config validation │ ├── interpolation.py # ${VAR:-default} interpolation diff --git a/LICENSE b/LICENSE index 67db858..dd5b3a5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/README.md b/README.md index e3f5e74..5dc0741 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ Python 3.11+ PyPI version Strands Agents - License + License

> [!IMPORTANT] -> Community project — not affiliated with AWS or the strands-agents team. Bugs here? [Open an issue](https://github.com/galuszkm/strands-compose/issues). Bugs in the underlying SDK? Head to [strands-agents](https://github.com/strands-agents/sdk-python). +> Community project — not affiliated with AWS or the strands-agents team. Bugs here? [Open an issue](https://github.com/strands-compose/sdk-python/issues). Bugs in the underlying SDK? Head to [strands-agents](https://github.com/strands-agents/sdk-python). ## What is this? @@ -180,13 +180,16 @@ Split large configs across files — models in one, agents in another, MCP in a ## Getting started +Install with [uv](https://docs.astral.sh/uv/): + ```bash -git clone https://github.com/strands-compose/sdk-python -cd sdk-python -uv sync --all-groups --all-extras +uv add strands-compose # Bedrock (default) +uv add strands-compose[ollama] # + Ollama +uv add strands-compose[openai] # + OpenAI +uv add strands-compose[gemini] # + Gemini ``` -Install from PyPI: +Or with pip: ```bash pip install strands-compose # Bedrock (default) @@ -223,6 +226,27 @@ with resolved.mcp_lifecycle: print(result) ``` +### CLI + +strands-compose ships a CLI to validate and debug configs without writing Python. + +**`check`** — fast, static validation (YAML syntax, schema, variable interpolation, cross-references). No side-effects, safe for CI. Will **not** catch runtime issues like bad credentials, unreachable MCP servers, or missing Python modules. + +```bash +strands-compose check config.yaml +strands-compose check base.yaml agents.yaml # merge multiple files +strands-compose check config.yaml --json # JSON output for scripts +strands-compose check config.yaml --quiet # exit code only +``` + +**`load`** *(recommended)* — full end-to-end validation. Builds real Python objects, starts MCP servers, and probes connectivity. Catches everything `check` catches plus import errors, auth failures, and MCP health issues. + +```bash +strands-compose load config.yaml +strands-compose load config.yaml --json +strands-compose load config.yaml --quiet +``` + --- ## Examples @@ -323,7 +347,7 @@ orchestrations: connections: - agent: content_team # Nested swarm as a delegate tool description: "Content creation team." - - agent: qa_bot # Neasted agent as a delegate tool + - agent: qa_bot # Nested agent as a delegate tool description: "Quality assurance." entry: team_leader @@ -363,7 +387,7 @@ async def main(): asyncio.run(main()) ``` -Event types: `TOKEN`, `REASONING`, `TOOL_START`, `TOOL_END`, `NODE_START`, `NODE_STOP`, `HANDOFF`, `COMPLETE` — each carrying `{type, agent_name, timestamp, data}`. Enough for a real-time frontend, a log aggregator, or a debugging dashboard. The `AnsiRenderer` gives you coloured terminal output out of the box — agent names, tool calls, reasoning traces, all streaming live. +Event types: `AGENT_START`, `TOKEN`, `REASONING`, `TOOL_START`, `TOOL_END`, `NODE_START`, `NODE_STOP`, `HANDOFF`, `COMPLETE`, `MULTIAGENT_START`, `MULTIAGENT_COMPLETE`, `ERROR` — each carrying `{type, agent_name, timestamp, data}`. Enough for a real-time frontend, a log aggregator, or a debugging dashboard. The `AnsiRenderer` gives you coloured terminal output out of the box — agent names, tool calls, reasoning traces, all streaming live. --- diff --git a/SUPPORT.md b/SUPPORT.md index 42007a0..da902f1 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -20,6 +20,9 @@ If you encounter a bug or have a feature request: ## Security If you discover a potential security issue, please see [SECURITY.md](SECURITY.md). + +## Troubleshooting + - If you see tool name errors, ensure the sanitizer is included in your hooks list **Import errors:** diff --git a/docs/index.html b/docs/index.html index 7cd3dd1..6d74499 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,7 +3,7 @@ - strands Compose + Strands Compose