Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ What else did you try or consider? Why is the proposal preferable?

## Scope notes

- Is this a new role/component in the chain (RequestProcessor / LLMBackend / ResponseProcessor / ResponseTranslator), or an extension of an existing one?
- Does it touch a public API listed in `switchyard/__init__.py.__all__`?
- Which surface owns the change: server API or configuration, routing algorithm,
protocol type, translation codec, upstream client, Python binding, or launcher?
- Does it change a public Rust, PyO3, Python, CLI, or deployment-TOML interface?
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- Backward-compatibility concerns?

## Additional context
Expand Down
39 changes: 29 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ uv run mypy switchyard

# Tests — no failures
uv run pytest tests/ -v

# Rust formatting, linting, and tests
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

These commands run in CI on every push. **Fix linting errors locally before pushing:**
Expand Down Expand Up @@ -130,6 +135,9 @@ feat(api)!: remove legacy route option
uv run ruff check .
uv run mypy switchyard
uv run pytest tests/ -v
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

4. **Push and open a PR** on GitHub. Include:
Expand All @@ -152,6 +160,7 @@ workflows (commitlint, PR title) run on every PR but are advisory.

```bash
uv run pytest tests/ -v
cargo test --workspace
```

### Integration tests (requires API keys)
Expand All @@ -167,19 +176,29 @@ The default unit test suite runs with no network access and no API keys. Live, e

## Architecture

See [Agents](AGENTS.md) for the full architecture guide. Key points:
See [Architecture](docs/architecture.md) for the request lifecycle and
[Agents](AGENTS.md) for crate boundaries and repository conventions. The
supported serving path is native Rust:

```text
HTTP request → switchyard-server → libsy → libsy-llm-client
→ switchyard-translation → upstream model
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- **Typed requests/responses** — use `ChatRequest` and `ChatResponse` subtypes
- **Composable chain** — `RequestProcessor` → `LLMBackend` → `ResponseProcessor` → `TranslationEngine`
- **Profiles** — pre-built chains in `switchyard/lib/profiles/`
Before making a change, identify the surface that owns it:

When adding a new component:
- Put routing algorithms and driver behavior in `crates/libsy`.
- Put provider-neutral request and response types in `crates/protocol`.
- Put translated HTTP calls in `crates/libsy-llm-client`.
- Put wire-format conversion in `crates/switchyard-translation`.
- Put HTTP serving and deployment configuration in `crates/switchyard-server`.
- Put native Python bindings in `crates/switchyard-py`; keep Python wrappers in
`switchyard/libsy` or `switchyard_rust`.
- Put launcher behavior in `switchyard/cli`.

1. Decide the role: `RequestProcessor`, `LLMBackend`, `ResponseProcessor`, or translation engine work.
2. Subclass the ABC from `switchyard/lib/roles.py`.
3. Put Python middleware in the matching subpackage (`switchyard/lib/processors/`, `switchyard/lib/backends/`) and provider translation logic in `crates/switchyard-translation`.
4. Add tests in `tests/`.
5. Export from the relevant `__init__.py` and from `switchyard/__init__.py`'s `__all__`.
Add Rust tests in the owning crate and Python tests in `tests/`. Export new
public symbols from the owning crate or package rather than the top-level
`switchyard` package unless that package owns the API.

## Documentation

Expand Down
46 changes: 21 additions & 25 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Switchyard itself. If you only want to **use** the package, see
[README](README.md).

For deeper architectural docs, see [Agents](AGENTS.md) and
[Architecture](docs/ARCHITECTURE.md).
[Architecture](docs/architecture.md).

## Setup

Expand Down Expand Up @@ -40,30 +40,21 @@ uv sync --all-extras # everything (dev group is still included by default)
## Project Structure

```
switchyard/
├── switchyard/ # The package itself
│ ├── __init__.py # Public API exports (single source of truth)
│ ├── lib/ # Core library
│ │ ├── roles.py # RequestProcessor, LLMBackend, ResponseProcessor ABCs
│ │ ├── switchyard.py # Switchyard chain executor
│ │ ├── profiles/ # Profile configs/runtimes (passthrough, random_routing, …)
│ │ ├── proxy_context.py # ProxyContext — per-request state
│ │ ├── chat_request/ # Typed request hierarchy
│ │ ├── chat_response/ # Typed response hierarchy
│ │ ├── backends/ # LLMBackend implementations
│ │ ├── processors/ # RequestProcessor / ResponseProcessor implementations
│ │ ├── factories/ # MiddlewareFactory implementations + configs
│ │ └── endpoints/ # FastAPI endpoint wrappers (require [server])
│ ├── cli/ # CLI entry point (requires [cli])
│ └── server/ # FastAPI app factory + verify helpers (requires [server])
├── crates/
│ ├── switchyard-translation/ # Rust request/response/stream translation engine
│ └── switchyard-py/ # Thin PyO3 bindings plus Python convenience wrapper
├── tests/ # Pytest unit tests (no API keys required)
├── examples/ # Minimal usage examples
├── docs/ # Architecture, getting started, publication
├── secrets/ # Local credential template (git-ignored)
└── pyproject.toml
switchyard/ # Python package
├── cli/ # CLI and coding-agent launchers
└── libsy/ # Typed wrappers for libsy algorithms
switchyard_rust/ # Python facades over the PyO3 extension
crates/
├── libsy/ # Routing algorithms and driver
├── libsy-llm-client/ # Translated HTTP model calls
├── protocol/ # Provider-neutral protocol types
├── switchyard-py/ # PyO3 bindings for libsy and the server
├── switchyard-server/ # Native HTTP server and TOML configuration
├── switchyard-skill-distillation/ # Skill-distillation contracts
└── switchyard-translation/ # Request, response, and stream translation
tests/ # Python tests (no API keys required)
docs/ # User and architecture documentation
pyproject.toml # Python package and development tooling
```

## Development Workflow
Expand All @@ -78,6 +69,11 @@ uv run pytest tests/ -v
# Lint and type check
uv run ruff check .
uv run mypy switchyard

# Rust formatting, linting, and tests
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

> **Local Git hooks:** install both `pre-commit` and `commit-msg` hooks with
Expand Down