awslabs / awslabs/cli-agent-orchestrator
[feat] Plugin/provider extension API — register providers without patching source
- Dominant language
- Python
- Stars
- 1.3k
- Forks
- 267
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 70
Description
## Problem
Adding a new provider (e.g. Devin CLI) requires modifying **7 hardcoded source files** inside the installed CAO package:
| File | What must be modified |
|------|----------------------|
| `models/provider.py` | Add enum member to `ProviderType` |
| `providers/manager.py` | Add import + `elif` branch in provider factory |
| `cli/commands/launch.py` | Add to `PROVIDERS_REQUIRING_WORKSPACE_ACCESS` set |
| `utils/tool_mapping.py` | Add tool name mapping entries to `TOOL_MAPPING` dict |
| `services/settings_service.py` | Add default agent directory config |
| `utils/agent_profiles.py` | Add to `provider_source_labels` |
| `api/main.py` | Add to `provider_binaries` dict |
There is no plugin or extension API to register providers dynamically. Anyone who wants to add a new provider must either fork the repo or build a source-patching tool (which is what we did — a 426-line Python patcher that generates replacement files from `plugin.yaml` manifests).
## Proposed Solution
A **provider registration mechanism** that lets external packages register themselves without modifying CAO internals. Possible approaches:
### Option A: Plugin manifest discovery
CAO discovers `plugin.yaml` files at startup from a configured plugins directory (e.g. `~/.aws/cli-agent-orchestrator/plugins/`):
```yaml
name: devin-cli
provider:
type: devin_cli
class: providers.devin:DevinCliProvider
binary: devin
label: Devin CLI
requires_workspace: true
tool_mapping:
fs_read: Read
fs_write: Write
execute_bash: Bash
agents:
- agents/developer.md
- agents/reviewer.md
```
### Option B: Python entry points
Providers register via `importlib.metadata` entry points in their `pyproject.toml`:
```toml
[project.entry-points."cao.providers"]
devin_cli = "cao_devin:DevinCliProvider"
```
### Option C: Runtime registration API
A `register_provider()` function that can be called from a startup hook:
```python
from cli_agent_orchestrator.providers import register_provider
register_provider("devin_cli", DevinCliProvider, binary="devin", ...)
```
## Proof of Concept
We have a working implementation using Option A in [cao-poc](https://github.com/ThePlenkov/cli-agent-orchestrator). The patcher reads `plugin.yaml` manifests and generates patched source files for all 7 locations. It successfully registers a Devin CLI provider with full functionality (status detection, response extraction, MCP config, agent profiles).
The core issue is that provider registration is scattered across 7 files with no centralized registry. Consolidating into a single extensible registry would make all three options feasible.
## Related
- #143 (provider-agnostic skills support) — complementary but different scope. Skills are about capabilities; this is about the provider type system itself.
Contributor guide
Research direction
Start by reading the seven integration points named in the issue, especially models/provider.py, providers/manager.py, and api/main.py, then compare them with the cao-poc plugin.yaml implementation. The work is done when an external provider can register its type, factory, binary, mappings, profiles, and workspace requirements without editing CAO source files.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100