Skip to content

Commit 79cd3b3

Browse files
committed
Add devcontainer setup for AI coding agents
- Dockerfile with Python 3.12, uv, pre-commit, deno - docker-compose with optional services (Ollama, PostgreSQL, pgvector) - docs with setup instructions - platform compatibility (x86_64) to support all dependencies (tested on an M4 chip)
1 parent 359c6d2 commit 79cd3b3

File tree

9 files changed

+1503
-0
lines changed

9 files changed

+1503
-0
lines changed

.devcontainer/.env.example

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Pydantic AI DevContainer Environment Variables
2+
# Copy this file to .env and fill in your actual values
3+
4+
# ============================================================================
5+
# MODEL PROVIDER API KEYS
6+
# ============================================================================
7+
8+
# OpenAI (Required for: OpenAI models, OpenAI-compatible providers)
9+
# Get your key at: https://platform.openai.com/api-keys
10+
OPENAI_API_KEY=
11+
12+
# Anthropic (Required for: Claude models)
13+
# Get your key at: https://console.anthropic.com/settings/keys
14+
ANTHROPIC_API_KEY=
15+
16+
# Google Generative AI (Required for: Gemini models via Google AI Studio)
17+
# Get your key at: https://aistudio.google.com/apikey
18+
GEMINI_API_KEY=
19+
20+
# Google Cloud (Required for: Gemini models via Vertex AI)
21+
# Service account JSON content (not a file path)
22+
# Get it from: https://console.cloud.google.com/iam-admin/serviceaccounts
23+
GOOGLE_SERVICE_ACCOUNT_CONTENT=
24+
25+
# Groq (Required for: Groq models)
26+
# Get your key at: https://console.groq.com/keys
27+
GROQ_API_KEY=
28+
29+
# Mistral AI (Required for: Mistral models)
30+
# Get your key at: https://console.mistral.ai/api-keys
31+
MISTRAL_API_KEY=
32+
33+
# Cohere (Required for: Cohere models)
34+
# Get your key at: https://dashboard.cohere.com/api-keys
35+
CO_API_KEY=
36+
37+
# AWS Bedrock (Required for: AWS Bedrock models)
38+
# Configure via AWS CLI or set these:
39+
# AWS_ACCESS_KEY_ID=
40+
# AWS_SECRET_ACCESS_KEY=
41+
# AWS_REGION=us-east-1
42+
43+
# ============================================================================
44+
# ADDITIONAL MODEL PROVIDERS (OpenAI-compatible)
45+
# ============================================================================
46+
47+
# DeepSeek (OpenAI-compatible)
48+
# Get your key at: https://platform.deepseek.com/api_keys
49+
DEEPSEEK_API_KEY=
50+
51+
# xAI Grok (OpenAI-compatible)
52+
# Get your key at: https://console.x.ai/
53+
GROK_API_KEY=
54+
55+
# OpenRouter (Aggregates multiple providers)
56+
# Get your key at: https://openrouter.ai/settings/keys
57+
OPENROUTER_API_KEY=
58+
59+
# Vercel AI Gateway
60+
# Configure at: https://vercel.com/docs/ai-gateway
61+
VERCEL_AI_GATEWAY_API_KEY=
62+
63+
# Fireworks AI (OpenAI-compatible)
64+
# Get your key at: https://fireworks.ai/api-keys
65+
FIREWORKS_API_KEY=
66+
67+
# Together AI (OpenAI-compatible)
68+
# Get your key at: https://api.together.ai/settings/api-keys
69+
TOGETHER_API_KEY=
70+
71+
# Cerebras (OpenAI-compatible)
72+
# Get your key at: https://cloud.cerebras.ai/
73+
CEREBRAS_API_KEY=
74+
75+
# Nebius AI (OpenAI-compatible)
76+
# Get your key at: https://studio.nebius.ai/
77+
NEBIUS_API_KEY=
78+
79+
# OVHcloud AI Endpoints (OpenAI-compatible)
80+
# Get your key at: https://endpoints.ai.cloud.ovh.net/
81+
OVHCLOUD_API_KEY=
82+
83+
# MoonshotAI (OpenAI-compatible)
84+
# Get your key at: https://platform.moonshot.cn/
85+
MOONSHOTAI_API_KEY=
86+
87+
# Heroku Inference (OpenAI-compatible)
88+
# Get your key at: https://www.heroku.com/ai
89+
HEROKU_INFERENCE_KEY=
90+
91+
# ============================================================================
92+
# LOCAL MODEL PROVIDERS
93+
# ============================================================================
94+
95+
# Ollama (Optional - for local models)
96+
# If running Ollama locally or via docker-compose, set the base URL
97+
# Default when using docker-compose ollama service:
98+
# OLLAMA_BASE_URL=http://localhost:11434/v1/
99+
# OLLAMA_API_KEY=placeholder # Not needed for local, but some tools require it
100+
101+
# ============================================================================
102+
# OBSERVABILITY & MONITORING
103+
# ============================================================================
104+
105+
# Logfire (Optional - for structured logging and tracing)
106+
# Get your token at: https://logfire.pydantic.dev/
107+
# LOGFIRE_TOKEN=
108+
# LOGFIRE_SERVICE_NAME=pydantic-ai-dev
109+
110+
# ============================================================================
111+
# SEARCH PROVIDERS (for tool integrations)
112+
# ============================================================================
113+
114+
# Brave Search (Optional - for web search tools)
115+
# Get your key at: https://brave.com/search/api/
116+
# BRAVE_API_KEY=
117+
118+
# Tavily Search (Optional - for web search tools)
119+
# Get your key at: https://tavily.com/
120+
# TAVILY_API_KEY=
121+
122+
# ============================================================================
123+
# MODEL CONTEXT PROTOCOL (MCP)
124+
# ============================================================================
125+
126+
# GitHub Personal Access Token (Optional - for MCP GitHub server)
127+
# Create at: https://github.com/settings/tokens
128+
# Needs: repo, read:org scopes
129+
# GITHUB_PERSONAL_ACCESS_TOKEN=
130+
131+
# ============================================================================
132+
# DATABASE CONNECTIONS (for examples)
133+
# ============================================================================
134+
135+
# PostgreSQL (Optional - for SQL/RAG examples)
136+
# Default when using docker-compose postgres service:
137+
# DATABASE_URL=postgresql://postgres:postgres@localhost:54320/postgres
138+
139+
# PostgreSQL with pgvector (Optional - for RAG examples)
140+
# Default when using docker-compose pgvector service:
141+
# PGVECTOR_DATABASE_URL=postgresql://postgres:postgres@localhost:54321/postgres
142+
143+
# ============================================================================
144+
# TESTING FLAGS
145+
# ============================================================================
146+
147+
# Enable live API testing (Optional - USE WITH CAUTION - incurs API costs!)
148+
# Set to exact value below to enable live tests that hit real APIs
149+
# PYDANTIC_AI_LIVE_TEST_DANGEROUS=CHARGE-ME!
150+
151+
# ============================================================================
152+
# NOTES
153+
# ============================================================================
154+
#
155+
# - Most API keys are OPTIONAL - only set the ones you plan to use
156+
# - For testing, use test models or Ollama to avoid API costs
157+
# - Never commit this file with real API keys
158+
# - Add .env to .gitignore (already done in this project)
159+
# - See README.md for detailed setup instructions per provider

.devcontainer/AGENTS.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# DevContainer Maintenance Guide
2+
3+
## About This Codebase
4+
5+
- **Pydantic AI**: Agent framework for building LLM-powered applications with Pydantic
6+
- **Workspace structure**: uv monorepo with multiple packages
7+
- `pydantic-ai-slim`: Core framework (minimal dependencies)
8+
- `pydantic-evals`: Evaluation framework
9+
- `pydantic-graph`: Graph execution engine
10+
- `examples/`: Example applications
11+
- `clai/`: CLI tool
12+
- **Primary users**: Contributors, AI coding agents (Claude Code, Cursor), PR reviewers
13+
14+
## DevContainer Purpose
15+
16+
- Provides isolated, reproducible development environment
17+
- Matches exact dependencies and tools across all developers and AI agents
18+
- Prevents "works on my machine" issues
19+
- Ensures AI agents have proper access to testing/building tools
20+
- Security isolation for AI agents
21+
22+
## Platform Configuration
23+
24+
- **Default platform**: `linux/amd64` (x86_64)
25+
- **Why not ARM64**: Some Python packages (e.g., mlx) lack Linux ARM64 wheels
26+
- **Apple Silicon**: Uses Rosetta/QEMU emulation automatically (slightly slower but compatible)
27+
- **Change if needed**: Edit `docker-compose.yml` platform setting
28+
29+
## Installation Modes
30+
31+
### Standard Mode (Default)
32+
- Installs: Cloud API providers + dev tools
33+
- Excludes: PyTorch, transformers, vLLM, outlines ML extras
34+
- Use case: 95% of development (PR testing, features, bug fixes)
35+
- Why: Saves significant install time and disk space
36+
- Command: Uses explicit `--extra` flags in `install.sh`
37+
38+
### Full Mode
39+
- Installs: Everything including ML frameworks
40+
- Use case: Working on outlines integration, local model features
41+
- Command: `--all-extras --all-packages`
42+
43+
### Mode Selection
44+
- Interactive (VSCode): User prompted to choose
45+
- Non-interactive (agents/CI): Defaults to Standard
46+
- Override: Set `INSTALL_MODE=standard|full` environment variable
47+
48+
## Key Files
49+
50+
### `.devcontainer/devcontainer.json`
51+
- VSCode configuration for the devcontainer
52+
- Editor settings, extensions, port forwarding
53+
- Lifecycle commands (`postCreateCommand`, `postStartCommand`)
54+
- Environment variables (`UV_LINK_MODE`, `UV_PROJECT_ENVIRONMENT`, etc.)
55+
- Git identity for AI commits
56+
57+
### `.devcontainer/Dockerfile`
58+
- Base image: `mcr.microsoft.com/devcontainers/base:debian-12`
59+
- System dependencies for Python builds
60+
- Installs: uv, deno, pre-commit, Python 3.12
61+
- Runs as non-root user `vscode`
62+
63+
### `.devcontainer/docker-compose.yml`
64+
- Service orchestration
65+
- Platform specification (`linux/amd64`)
66+
- Optional services (commented out): Ollama, PostgreSQL, pgvector, MCP proxy
67+
- Volume management for persistence
68+
69+
### `.devcontainer/install.sh`
70+
- Interactive installation script
71+
- Detects interactive vs non-interactive mode
72+
- Implements Standard vs Full installation logic
73+
- Installs pre-commit hooks
74+
- Called by `postCreateCommand` in devcontainer.json
75+
76+
## Environment Variables
77+
78+
### Critical Variables (devcontainer.json)
79+
- `UV_PROJECT_ENVIRONMENT=/workspace/.venv`: Virtual environment location
80+
- `UV_LINK_MODE=copy`: Suppress hardlink warnings in Docker volumes
81+
- `PYTHONUNBUFFERED=1`: Ensure Python output appears immediately
82+
- `COLUMNS=150`: Terminal width for better output formatting
83+
- `GIT_AUTHOR_*`, `GIT_COMMITTER_*`: Git identity for AI commits
84+
85+
### Optional Variables
86+
- `INSTALL_MODE=standard|full`: Override installation mode
87+
- API keys: Should be set in `.devcontainer/.env` (not committed)
88+
89+
## Dependencies and Extras
90+
91+
### Always Installed (Both Modes)
92+
- Core: pydantic, httpx, opentelemetry-api
93+
- Cloud APIs: openai, anthropic, google, groq, mistral, cohere, bedrock, huggingface
94+
- Dev tools: cli, mcp, fastmcp, logfire, retries, temporal, ui, ag-ui, evals
95+
- Build tools: lint group, docs group (ruff, mypy, pyright, mkdocs)
96+
97+
### Only in Full Mode
98+
- `outlines-transformers`: PyTorch + Transformers library
99+
- `outlines-vllm-offline`: vLLM inference engine
100+
- `outlines-sglang`: SGLang framework
101+
- `outlines-mlxlm`: Apple MLX framework
102+
- `outlines-llamacpp`: LlamaCPP bindings
103+
104+
## Common Maintenance Tasks
105+
106+
### Adding New System Dependencies
107+
- Edit `Dockerfile`: Add to `apt-get install` command
108+
- Rebuild container required
109+
110+
### Adding Python Packages
111+
- Use `uv add package-name` (not manual pyproject.toml edits)
112+
- For new extras: Add to `pydantic_ai_slim/pyproject.toml` optional-dependencies
113+
- Update `install.sh` if extra should be in Standard mode
114+
115+
### Adding VSCode Extensions
116+
- Edit `devcontainer.json`: Add to `customizations.vscode.extensions` array
117+
- Rebuild container required
118+
119+
### Updating Base Image/Tools
120+
- `Dockerfile`: Change base image tag
121+
- Update uv/deno install commands if needed
122+
- Test with both Standard and Full modes
123+
124+
### Adding Optional Services
125+
- Uncomment service in `docker-compose.yml`
126+
- Uncomment corresponding volume if needed
127+
- Document in README.md optional services section
128+
129+
## Troubleshooting
130+
131+
### Container Build Fails
132+
- Check Docker daemon is running
133+
- Check internet connectivity
134+
- Try: `docker system prune -a` to clean cache
135+
- Check Dockerfile for syntax errors: `docker build -f .devcontainer/Dockerfile .`
136+
137+
### Installation Script Fails
138+
- Check `install.sh` syntax: `bash -n .devcontainer/install.sh`
139+
- Run manually in container to see detailed errors
140+
- Check uv lockfile is up to date: `uv lock`
141+
142+
### Performance Issues
143+
- Verify Docker resources (4+ GB RAM recommended)
144+
- Check platform setting (amd64 vs arm64)
145+
- Volume cache consistency setting in docker-compose.yml
146+
147+
### UV Warnings
148+
- Hardlink warning: Ensure `UV_LINK_MODE=copy` is set
149+
- Lockfile conflicts: Run `uv lock` to regenerate
150+
151+
## Best Practices
152+
153+
### When Changing install.sh
154+
- Test both Standard and Full modes
155+
- Test interactive and non-interactive flows
156+
- Verify syntax with `bash -n install.sh`
157+
- Update README.md to match
158+
159+
### When Changing Dependencies
160+
- Keep Standard mode lean (exclude heavy ML frameworks)
161+
- Update install.sh if adding new extras
162+
- Document in README.md what's included/excluded
163+
- Test install time impact
164+
165+
### When Updating Documentation
166+
- Keep README.md user-facing and comprehensive
167+
- Keep CLAUDE.md maintainer-focused and concise
168+
- No time estimates (machine-dependent)
169+
- Link to official docs where applicable
170+
171+
## Git Configuration
172+
173+
- Credentials forwarded automatically by VSCode (no manual setup needed)
174+
- Git identity set via environment variables (not .gitconfig file)
175+
- Safe directory configured in `postStartCommand`
176+
- AI commits use identity from `GIT_AUTHOR_*` variables
177+
178+
## Testing the Setup
179+
180+
### Manual Test
181+
1. Make changes to devcontainer files
182+
2. Rebuild container: "Dev Containers: Rebuild Container"
183+
3. Test Standard mode installation
184+
4. Test Full mode: `INSTALL_MODE=full` or run `make install`
185+
5. Verify: `uv run pytest tests/test_agent.py::test_simple_sync`
186+
187+
### CI Considerations
188+
- Container should work in non-interactive mode
189+
- Default Standard mode should cover 95% of test suite
190+
- Full mode needed only for outlines/ML framework tests

0 commit comments

Comments
 (0)