Metadata-Version: 2.4
Name: philharmonica-adk
Version: 0.1.0
Summary: Philharmonica ADK — orchestrate a complex system of agents that performs real-world actions, provider-agnostic across 100+ LLMs
Author-email: Augments Labs <support@augmentslabs.com>
License: MIT
Project-URL: Homepage, https://github.com/augments-labs/philharmonica-adk-python
Project-URL: Repository, https://github.com/augments-labs/philharmonica-adk-python
Project-URL: Bug Tracker, https://github.com/augments-labs/philharmonica-adk-python/issues
Project-URL: Documentation, https://github.com/augments-labs/philharmonica-adk-python/tree/main/docs
Project-URL: Changelog, https://github.com/augments-labs/philharmonica-adk-python/releases
Keywords: agents,llm,multi-agent,agentic,litellm,openai,anthropic,gemini,mcp,opentelemetry,swarm,graph,handoff,tool-use,streaming
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: <3.14,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: litellm<2,>=1.80.9
Requires-Dist: pydantic<3,>=2.12.5
Requires-Dist: griffe>=1.15.0
Requires-Dist: aiosqlite>=0.21.0
Requires-Dist: typing-extensions<5,>=4.15.0
Requires-Dist: click<9,>=8.1.7
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.75.0; extra == "anthropic"
Provides-Extra: openai
Requires-Dist: openai>=2.0.0; extra == "openai"
Provides-Extra: voice
Requires-Dist: philharmonica-adk[openai]; extra == "voice"
Requires-Dist: websockets>=13.0; extra == "voice"
Requires-Dist: numpy>=1.26; extra == "voice"
Provides-Extra: gemini
Requires-Dist: google-genai>=1.0.0; extra == "gemini"
Provides-Extra: mcp
Requires-Dist: mcp<2,>=1.24.0; extra == "mcp"
Provides-Extra: a2a
Requires-Dist: a2a-sdk[http-server]>=1.0.0; extra == "a2a"
Provides-Extra: server
Requires-Dist: starlette>=0.37; extra == "server"
Requires-Dist: sse-starlette>=2.0; extra == "server"
Provides-Extra: serve
Requires-Dist: philharmonica-adk[a2a,server]; extra == "serve"
Requires-Dist: uvicorn>=0.30; extra == "serve"
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.39.1; extra == "otel"
Requires-Dist: opentelemetry-sdk>=1.39.1; extra == "otel"
Requires-Dist: opentelemetry-exporter-otlp>=1.39.1; extra == "otel"
Provides-Extra: viz
Requires-Dist: graphviz>=0.20.2; extra == "viz"
Provides-Extra: mermaid
Requires-Dist: mermaid-py>=0.5.0; extra == "mermaid"
Provides-Extra: verbose
Requires-Dist: rich>=14.2.0; extra == "verbose"
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == "yaml"
Provides-Extra: guardrails-lingua
Requires-Dist: lingua-language-detector>=2.0.0; extra == "guardrails-lingua"
Provides-Extra: guardrails
Requires-Dist: philharmonica-adk[guardrails-lingua]; extra == "guardrails"
Provides-Extra: rag-pdf
Requires-Dist: pymupdf>=1.24; extra == "rag-pdf"
Provides-Extra: rag-docx
Requires-Dist: python-docx>=1.1; extra == "rag-docx"
Provides-Extra: rag-web
Requires-Dist: requests>=2.31; extra == "rag-web"
Requires-Dist: beautifulsoup4>=4.12; extra == "rag-web"
Provides-Extra: rag-github
Requires-Dist: PyGithub>=2.1; extra == "rag-github"
Provides-Extra: rag-youtube
Requires-Dist: youtube-transcript-api>=1.0; extra == "rag-youtube"
Requires-Dist: pytube>=15.0; extra == "rag-youtube"
Provides-Extra: rag
Requires-Dist: philharmonica-adk[rag-docx,rag-github,rag-pdf,rag-web,rag-youtube]; extra == "rag"
Provides-Extra: sandbox
Provides-Extra: sandbox-docker
Requires-Dist: docker>=7.0.0; extra == "sandbox-docker"
Provides-Extra: sandbox-k8s
Requires-Dist: kubernetes>=30.0.0; extra == "sandbox-k8s"
Provides-Extra: sandbox-remote-vm
Requires-Dist: httpx>=0.27.0; extra == "sandbox-remote-vm"
Provides-Extra: sandbox-e2b
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-e2b"
Provides-Extra: sandbox-vercel
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-vercel"
Provides-Extra: sandbox-modal
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-modal"
Provides-Extra: sandbox-daytona
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-daytona"
Provides-Extra: sandbox-cloudflare
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-cloudflare"
Provides-Extra: sandbox-blaxel
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-blaxel"
Provides-Extra: sandbox-runloop
Requires-Dist: philharmonica-adk[sandbox-remote-vm]; extra == "sandbox-runloop"
Provides-Extra: sandbox-s3
Requires-Dist: boto3>=1.34.0; extra == "sandbox-s3"
Provides-Extra: sandbox-gcs
Requires-Dist: google-cloud-storage>=2.16.0; extra == "sandbox-gcs"
Provides-Extra: checkpointer-postgres
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "checkpointer-postgres"
Provides-Extra: cost-ledger-postgres
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "cost-ledger-postgres"
Provides-Extra: memory-pgvector
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "memory-pgvector"
Requires-Dist: pgvector>=0.3; extra == "memory-pgvector"
Provides-Extra: memory-chroma
Requires-Dist: chromadb>=0.5; extra == "memory-chroma"
Provides-Extra: memory-pinecone
Requires-Dist: pinecone>=8.0; extra == "memory-pinecone"
Provides-Extra: memory-qdrant
Requires-Dist: qdrant-client>=1.12; extra == "memory-qdrant"
Provides-Extra: cost-ledger-redis
Requires-Dist: redis>=5.0; extra == "cost-ledger-redis"
Provides-Extra: checkpointer-redis
Requires-Dist: redis>=5.0; extra == "checkpointer-redis"
Provides-Extra: checkpointer-s3
Requires-Dist: boto3>=1.34.0; extra == "checkpointer-s3"
Provides-Extra: audit-s3
Requires-Dist: boto3>=1.34.0; extra == "audit-s3"
Provides-Extra: audit-postgres
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "audit-postgres"
Provides-Extra: a2a-postgres
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "a2a-postgres"
Provides-Extra: session-postgres
Requires-Dist: psycopg[binary,pool]>=3.2; extra == "session-postgres"
Provides-Extra: temporal
Requires-Dist: temporalio>=1.24.0; extra == "temporal"
Provides-Extra: restate
Requires-Dist: restate-sdk>=0.18.0; extra == "restate"
Provides-Extra: all
Requires-Dist: philharmonica-adk[a2a-postgres,anthropic,checkpointer-postgres,checkpointer-redis,checkpointer-s3,cost-ledger-postgres,cost-ledger-redis,gemini,guardrails,mcp,memory-chroma,memory-pgvector,memory-pinecone,memory-qdrant,openai,otel,rag,serve,server,session-postgres,temporal,verbose,viz,voice]; extra == "all"
Provides-Extra: test
Requires-Dist: pytest<10,>=9.0.0; extra == "test"
Requires-Dist: pytest-asyncio>=1.0.0; extra == "test"
Requires-Dist: pytest-cov>=7.0.0; extra == "test"
Requires-Dist: pytest-mock>=3.14.0; extra == "test"
Requires-Dist: pytest-timeout>=2.4.0; extra == "test"
Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
Requires-Dist: pytest-rerunfailures>=14.0; extra == "test"
Requires-Dist: coverage[toml]>=7.6.0; extra == "test"
Requires-Dist: parameterized>=0.9.0; extra == "test"
Requires-Dist: inline-snapshot>=0.20.7; extra == "test"
Requires-Dist: fakeredis[lua]>=2.21; extra == "test"
Requires-Dist: moto>=5.0; extra == "test"
Requires-Dist: pytest-postgresql>=6.0; extra == "test"
Provides-Extra: dev
Requires-Dist: philharmonica-adk[all,test]; extra == "dev"
Requires-Dist: ruff==0.15.7; extra == "dev"
Requires-Dist: mypy>=1.15.0; extra == "dev"
Requires-Dist: pyright>=1.1.408; extra == "dev"
Requires-Dist: types-PyYAML>=6.0; extra == "dev"
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
Requires-Dist: bandit[toml]>=1.7; extra == "dev"
Requires-Dist: pip-audit>=2.7; extra == "dev"
Requires-Dist: python-dotenv>=1.2.2; extra == "dev"
Requires-Dist: commitizen>=4.4.0; extra == "dev"
Requires-Dist: build>=1.2.0; extra == "dev"
Dynamic: license-file

<div align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)"
            srcset="https://raw.githubusercontent.com/augments-labs/philharmonica-adk-python/main/docs/images/logo-dark.png">
    <img src="https://raw.githubusercontent.com/augments-labs/philharmonica-adk-python/main/docs/images/logo-light.png"
         alt="Philharmonica" width="132" height="132">
  </picture>
</div>

# Philharmonica Agent Development Kit (ADK)

A provider-agnostic Python framework to orchestrate complex
systems of agents that perform real-world actions, across 100+ LLMs via litellm.

## The concept

An agent is a model that stopped talking and started doing: it calls tools,
changes state, and leaves side effects in the world. One agent is useful. A
set of specialists that cannot coordinate is a liability.

A philharmonic is not a crowd of capable musicians. It is a score, sections
that know their part, and a conductor holding the tempo. This ADK gives you
the same three things for agents:

- **The score** — explicit orchestration. Graphs for state machines, flows
  for pipelines, swarms for open-ended exploration, handoffs for delegation.
  You write the structure; nothing is inferred behind your back.
- **The sections** — agents scoped to one job, each carrying its own tools,
  guardrails, and budget. An `Agent` is configuration, never a hidden runtime.
- **The conductor** — the `Runner`. Every run travels one execution path,
  where turns, retries, token budgets, and interrupts are *enforced* rather
  than suggested.

The framework never injects a prompt, a tool, or a token you did not ask for,
and every cost-bearing default starts bounded. Decisions, tool I/O, and token
spend come back as structured traces, so what the ensemble actually did is
readable after the fact.

## Design tenets

1. **Explicit over magical.** If you can't step through it in a debugger, it
   doesn't belong in the orchestration path.
2. **One obvious way.** Fewer knobs, sharper edges — the ADK has opinions.
3. **Everything is inspectable.** Decisions, tool I/O, and token costs are
   structured traces, not anecdotes.
4. **Benchmarks or it didn't happen.** Claims ship with eval evidence or not
   at all — including this framework's own.

## Status

- **Today (v0.1.0 groundwork):** agents, `Runner` (sync/async/streaming),
  swarms, graphs, flows, task pipelines, tools, handoffs, guardrails, memory
  and sessions, MCP, A2A, sandboxed code execution, durable execution
  (Temporal/Restate), OpenTelemetry tracing, deploy targets, and a strict
  JSON/YAML config layer — all in this repository, MIT licensed.
- **Next:** `philharmonica-evals-python` (benchmarks vs. other frameworks) and
  `philharmonica-cookbook-python` (production-grade examples) — build with the ADK,
  prove it with the evals, learn it from the cookbook.

## Installation

### Use it in your own project

```bash
uv add philharmonica-adk          # or: pip install philharmonica-adk
```

The core install is deliberately lean — `litellm`, `pydantic`, `griffe`, `aiosqlite`, `typing-extensions` — and every optional provider / exporter / UI enhancement is gated behind its own extra:

```bash
pip install 'philharmonica-adk[anthropic]'   # native Anthropic SDK path
pip install 'philharmonica-adk[otel]'        # OpenTelemetry tracing bridge
pip install 'philharmonica-adk[mcp]'         # Model Context Protocol client
pip install 'philharmonica-adk[viz]'         # Agent graph visualization (graphviz)
pip install 'philharmonica-adk[verbose]'     # Rich-backed panel/line verbose renderer (ANSI fallback without it)
pip install 'philharmonica-adk[all]'         # all of the above
```

### Work on the ADK itself

Prerequisites: Python 3.12+ and [uv](https://docs.astral.sh/uv/) (uv installs the interpreter itself if you don't have it).

```bash
# 1. Clone the repository
git clone https://github.com/augments-labs/philharmonica-adk-python.git
cd philharmonica-adk-python

# 2. Build .venv from the committed lockfile — everything + test + lint + typecheck
uv sync --extra dev

# 3. Run anything inside it
uv run philharmonica --help
uv run pytest
```

`uv sync` resolves from `uv.lock`, so every contributor and every CI job installs byte-identical versions. Activate the environment directly (`source .venv/bin/activate`) if you would rather not prefix commands with `uv run`, and swap `--extra dev` for any other extra (`--extra anthropic`, `--extra all`, or none at all) to work against a leaner surface.

Conda works too, if you prefer it:

```bash
conda env create -f environment.yaml   # also runs `pip install -e '.[dev]'`
conda activate philharmonica-adk-python
```

Either way the install is editable: `philharmonica.adk` is importable from the `src/` layout defined in `pyproject.toml`, and source changes take effect immediately without reinstalling.

### API Keys

Set the API keys for the LLM providers you want to use:

```bash
export ANTHROPIC_API_KEY="your-key"
export OPENAI_API_KEY="your-key"
export GEMINI_API_KEY="your-key"
```

### Verify Installation

```bash
python -c "from philharmonica.adk import Agent, Runner; print('OK')"
```

## Quick Start

```python
import asyncio
import logging

from philharmonica.adk import Agent, Runner

logger = logging.getLogger(__name__)

agent = Agent(
    name="Assistant",
    system_prompt="You are a helpful assistant.",
)

result = asyncio.run(Runner.arun(agent, "Hello!"))
logger.info(result.final_output)
```

## Command-Line Interface

The `philharmonica` console script drives agents from the terminal — scaffold a
project, validate its config without spending a token, then run or chat:

```bash
philharmonica new my_agent                       # scaffold config + tools + schema
philharmonica validate my_agent/agent.json       # strict schema check, no tokens
philharmonica run my_agent/agent.json "hello"    # one-shot run (config or --agent module:var)
philharmonica chat my_agent/agent.json           # interactive REPL, optional --session-db
philharmonica serve my_agent/agent.json                    # REST + health over HTTP ([serve] extra)
```

`run` auto-dispatches agents, swarms, graphs, and topologies; every
cost-affecting behavior (sessions, verbose rendering, tracing, env
files) stays off until you pass its flag. See `docs/cli/cli.md` for the
full command reference.

## Deployment

Serve an agent over HTTP, then ship the container to any cloud. The
framework imports no server runtime and no cloud SDK — every piece is
opt-in, and you keep control of the runtime.

```bash
pip install 'philharmonica-adk[serve]'

# Serve locally: REST (POST /run, POST /run_sse) + health (/healthz, /readyz).
philharmonica serve --agent my_agent.app:agent --host 0.0.0.0 --port 8000

# Generate the deployment artifacts you own (Dockerfile + manifests):
philharmonica deploy init --target k8s --agent my_agent.app:agent --image my-agent:latest

# Or build and ship to a target via your installed CLIs:
philharmonica deploy build      --agent my_agent.app:agent --image my-agent:latest --push
philharmonica deploy cloud-run  --agent my_agent.app:agent --image gcr.io/PROJECT/my-agent --project PROJECT --region REGION
philharmonica deploy gke        --agent my_agent.app:agent --image IMAGE --project P --region R --cluster C
philharmonica deploy ecs        --agent my_agent.app:agent --image ACCT.dkr.ecr.R.amazonaws.com/my-agent --region R --execution-role-arn ARN
```

`philharmonica deploy` targets `docker`, `k8s`, `gke`, `helm`, `cloudrun`,
`ecs`, `app-runner`, and `lambda`. The generated image satisfies the
universal container contract (binds `0.0.0.0:$PORT`, config from env,
non-root, `/healthz` + `/readyz` probes), so the same image runs
everywhere. The generated `requirements.txt` installs `philharmonica-adk`
from PyPI; edit it if you need a pin, a vendored wheel, or a VCS URL
instead.

A single replica works out of the box on the default per-pod SQLite
stores. For multi-replica (horizontally-scaled) deployments, back A2A
tasks and REST sessions with Postgres so state is shared across pods —
`philharmonica serve --task-dsn "$PG_DSN" --session-dsn "$PG_DSN"` (install
`philharmonica-adk[a2a-postgres,session-postgres]`). The AWS deploy commands
also accept `--push` to log in to ECR and build/push the image for you.
See [`docs/deploy/`](docs/deploy/) for the full guide.

## Running Examples

All examples are runnable from the project root:

```bash
python examples/agent_patterns/agents_as_tools.py
python examples/handoffs/llm_orchestrated.py
python examples/tools/tool_guardrails.py
```

## Core Concepts

- [**Agents**](docs/agents/) — Autonomous entities with tools, guardrails, and handoffs
- [**Tools**](docs/tools/) — Function wrappers with schema validation and guardrails
- [**Handoffs**](docs/handoffs/) — Agent-to-agent routing (LLM-orchestrated or code-orchestrated)
- [**Guardrails**](docs/guardrails/) — Pre/post execution validation at agent and tool level
- [**Memory**](docs/memory/) — Persistent knowledge across sessions
- [**Skills**](docs/skills/) — Reusable capability packages (instructions + tools + governance)
- [**Tracing**](docs/tracing/) — OpenTelemetry observability

## Project Structure

```
src/philharmonica/adk/       # Source code (namespace package)
tests/                 # Unit and integration tests
examples/              # Single-file runnable examples (one concept each)
docs/                  # Usage documentation
configs/               # Logging and other configs
```

## Key Dependencies

**Core**: `litellm` | `pydantic` | `griffe` | `aiosqlite` | `typing-extensions`
**Optional extras**: `anthropic` (`.[anthropic]`) | `mcp` (`.[mcp]`) | `opentelemetry-*` (`.[otel]`) | `graphviz` (`.[viz]`) | `rich` (`.[verbose]`)

## Acknowledgements

This ADK draws on prior art and ongoing work from across the
multi-agent ecosystem:

- [**LangGraph**](https://github.com/langchain-ai/langgraph) —
  state-machine multi-agent orchestration; influence on the
  `graphs/` subsystem.
- [**CrewAI**](https://github.com/crewAIInc/crewAI) — multi-agent
  collaboration patterns.
- [**OpenAI Swarm**](https://github.com/openai/swarm) — swarm cycle
  pattern (reference shape for `swarms/`).
- [**OpenAI Agents SDK**](https://github.com/openai/openai-agents-python) —
  Runner design and handoff mechanism reference.
- [**Anthropic Claude Agent SDK**](https://github.com/anthropics/anthropic-quickstarts) —
  Anthropic-native provider design.
- [**LiteLLM**](https://github.com/BerriAI/litellm) — provider-agnostic
  LLM abstraction over 100+ models.
- [**Model Context Protocol**](https://modelcontextprotocol.io/) —
  tool-integration substrate.
- [**Pydantic**](https://docs.pydantic.dev/) — typed validation.
- [**Temporal**](https://temporal.io/) — durable execution backbone.
- [**OpenTelemetry**](https://opentelemetry.io/) and
  [**OpenInference**](https://github.com/Arize-ai/openinference) —
  observability conventions.

Inclusion here records influence, not endorsement.
