AGENTS.md
This file provides guidance to coding agents when working with code in this repository.
Loading actions...
Skill content
Main instructions and any bundled files for this skill.
AGENTS.md
This file provides guidance to coding agents when working with code in this repository.
Project Overview
Cog is a tool that packages machine learning models in production-ready containers.
It consists of:
- Cog CLI (
cmd/cog/) - Command-line interface for building, running, and deploying models, written in Go - Python SDK (
python/cog/) - Python library for defining model predictors and training in Python - Coglet (
crates/) - Rust-based prediction server that runs inside containers, with Python bindings via PyO3
Documentation for the CLI and SDK is available by reading ./docs/llms.txt.
Development Commands
Development tasks are managed with mise. Run mise tasks to see all available tasks.
Quick Reference
| Task | Description |
|---|---|
mise run fmt | Check formatting (all languages) |
mise run fmt:fix | Fix formatting (all languages) |
mise run lint | Run linters (all languages) |
mise run lint:fix | Fix lint issues (all languages) |
mise run test:go | Run Go tests |
mise run test:rust | Run Rust tests |
mise run test:python | Run Python tests |
mise run test:integration | Run integration tests |
mise run build:cog | Build cog CLI binary |
mise run build:coglet | Build coglet wheel (dev) |
mise run build:sdk | Build SDK wheel |
mise run install | Build and symlink cog to /usr/local/bin |
mise run docs:llm | IMPORTANT: Regenerate docs/llms.txt after editing docs |
mise run docs:cli | Generate CLI reference docs from Go source code |
mise run version | Show current version from VERSION.txt |
mise run version:bump <ver> | Bump version everywhere and commit |
Task Naming Convention
Tasks follow a consistent naming pattern:
- Language-based tasks for fmt/lint/test/typecheck:
task:go,task:rust,task:python - Component-based tasks for build:
build:cog,build:coglet,build:sdk - Check vs Fix:
fmtandlintdefault to check mode (non-destructive); use:fixsuffix to auto-fix
All Tasks by Category
Format:
mise run fmt/mise run fmt:check- Check all (alias)mise run fmt:fix- Fix allmise run fmt:go/mise run fmt:rust/mise run fmt:python- Per-language
Lint:
mise run lint/mise run lint:check- Check all (alias)mise run lint:fix- Fix allmise run lint:go/mise run lint:rust/mise run lint:python- Per-languagemise run lint:rust:deny- Check Rust licenses/advisories
Test:
mise run test:go- Go unit testsmise run test:rust- Rust unit testsmise run test:python- Python unit tests (via tox)mise run test:coglet:python- Coglet Python binding testsmise run test:integration- Integration tests
Build:
mise run build:cog- Build cog CLI (development)mise run build:cog:release- Build cog CLI (release)mise run build:coglet- Build coglet wheel (dev install)mise run build:coglet:wheel- Build coglet wheel (native platform)mise run build:coglet:wheel:linux-x64- Build for Linux x86_64mise run build:coglet:wheel:linux-arm64- Build for Linux ARM64mise run build:sdk- Build SDK wheel
Install:
mise run install- Symlink cog CLI to/usr/local/bin(requiresbuild:cogfirst)PREFIX=/custom/path mise run install- Symlink to custom location
Version:
mise run version- Show current version from VERSION.txtmise run version:bump <ver>- Bump version everywhere and commitmise run version:check- Verify VERSION.txt matches Cargo.toml
Other:
mise run typecheck- Type check all languagesmise run generate- Run code generationmise run clean- Clean all build artifactsmise run docs- Build documentationmise run docs:serve- Serve docs locally
Code Style Guidelines
Go
- Imports: Organize in three groups separated by blank lines: (1) Standard library, (2) Third-party packages, (3) Internal packages (
github.com/replicate/cog/pkg/...) - Formatting: Use
mise run fmt:go:fix - Linting: Must pass golangci-lint with: errcheck, gocritic, gosec, govet, ineffassign, misspell, revive, staticcheck, unused
- Error Handling: Return errors as values; use
pkg/errors.CodedErrorfor user-facing errors with error codes - Naming: CamelCase for exported, camelCase for unexported
- Testing: Use
testify/requirefor assertions; prefer table-driven tests
Example import block:
import (
"fmt"
"github.com/spf13/cobra"
"github.com/replicate/cog/pkg/config"
)
Python
- Imports: Automatically organized by ruff/isort (stdlib → third-party → local)
- Formatting: Use
mise run fmt:python:fix - Linting: Must pass ruff checks: E (pycodestyle), F (Pyflakes), I (isort), W (warnings), S (bandit), B (bugbear), ANN (annotations)
- Type Annotations: Required on all function signatures; use
typing_extensionsfor compatibility; avoidAnywhere possible - Error Handling: Raise exceptions with descriptive messages; avoid generic exception catching
- Naming: snake_case for functions/variables/modules, PascalCase for classes
- Testing: Use pytest with fixtures; async tests with pytest-asyncio
- Compatibility: Must support Python 3.10-3.13
Rust
- Formatting: Use
mise run fmt:rust:fix - Linting: Must pass
mise run lint:rust(clippy) - Dependencies: Audited with
cargo-deny(seecrates/deny.toml); runmise run lint:rust:deny - Error Handling: Use
thiserrorfor typed errors,anyhowfor application errors - Naming: snake_case for functions/variables, PascalCase for types
- Testing: Use
cargo test; snapshot tests useinsta - Async: tokio runtime; async/await patterns
Working on the CLI and support tooling
The CLI code is in the cmd/cog/ and pkg/ directories. Support tooling is in the tools/ directory.
The main commands for working on the CLI are:
go run ./cmd/cog- Runs the Cog CLI directly from source (requires wheel to be built first)mise run build:cog- Builds the Cog CLI binarymise run install- Symlinks the built binary to/usr/local/bin(runbuild:cogfirst), or to a custom path withPREFIX=/custom/path mise run installmise run test:go- Runs all Go unit testsgo test ./pkg/...- Runs tests directly withgo test
Working on the Python SDK
The Python SDK is developed in the python/cog/ directory. It uses uv for virtual environments and tox for testing across multiple Python versions.
The main commands for working on the SDK are:
mise run build:sdk- Builds the Python wheelmise run test:python- Runs Python tests across all supported versions
Working on Coglet (Rust)
Coglet is the Rust-based prediction server that runs inside Cog containers, handling HTTP requests, worker process management, and prediction execution.
The code is in the crates/ directory:
crates/coglet/- Core Rust library (HTTP server, worker orchestration, IPC)crates/coglet-python/- PyO3 bindings for Python predictor integration (requires Python 3.10+)
For detailed architecture documentation, see crates/README.md and crates/coglet/README.md.
The main commands for working on Coglet are:
mise run build:coglet- Build and install coglet wheel for development (macOS, for local Rust/Python tests)mise run build:coglet:wheel:linux-x64- Build Linux x86_64 wheel (required to test Rust changes in Docker containers viacog predict/cog train)mise run test:rust- Run Rust unit testsmise run lint:rust- Run clippy lintermise run fmt:rust:fix- Format code
Testing
Go code is tested using the built-in go test framework:
go test ./pkg/... -run <name>- Runs specific Go tests by namemise run test:go- Runs all Go unit tests
Python code is tested using tox, which allows testing across multiple Python versions and configurations:
mise run test:python- Runs all Python unit testsuv run tox -e py312-tests -- python/tests/server/test_http.py::test_openapi_specification_with_yield- Runs a specific Python test
The integration test suite in integration-tests/ tests the end-to-end functionality of the Cog CLI and Python SDK using Go's testscript framework:
mise run test:integration- Runs the integration testsmise run test:integration string_predictor- Runs a specific integration test
The integration tests require a built Cog binary, which defaults to the first cog in PATH. Run tests against a specific binary with the COG_BINARY environment variable:
mise run build:cog
COG_BINARY=dist/go/*/cog mise run test:integration
Development Workflow
- Run
mise installto set up the development environment - Run
mise run build:sdkafter making changes to the./pythondirectory - Run
mise run build:coglet:wheel:linux-x64after making changes to the./cratesdirectory (needed for Docker testing) - Run
mise run build:cogto build the CLI (wheels are picked up fromdist/at Docker build time, not embedded in the binary) - Run
mise run fmt:fixto format code - Run
mise run lintto check code quality - Run
mise run docs:llmto regeneratedocs/llms.txtafter changingREADME.mdor anydocs/*.mdfile - Read the
./docsdirectory and make sure the documentation is up to date
IMPORTANT: Always run mise run lint (or the language-specific variant, e.g. mise run lint:go) before committing to catch linter errors early. CI will reject PRs that fail lint checks.
Architecture
CLI Architecture (Go)
The CLI follows a command pattern with subcommands. The main components are:
pkg/cli/- Command definitions (build, exec, predict, serve, etc.)pkg/docker/- Docker client and container managementpkg/dockerfile/- Dockerfile generation and templatingpkg/config/- cog.yaml parsing and validationpkg/image/- Image building and pushing logic
Python SDK Architecture
python/cog/- Core SDKbase_predictor.py- Base class for model predictorstypes.py- Input/output type definitionsserver/- HTTP/queue server implementationcommand/- Runner implementations for predict/train
Coglet Architecture (Rust)
The prediction server that runs inside Cog containers. Uses a two-process architecture: a parent process (HTTP server + orchestrator) and a worker subprocess (Python predictor execution).
See crates/README.md for detailed architecture documentation.
crates/coglet/- Core Rust library (HTTP server, worker orchestration, IPC bridge)crates/coglet-python/- PyO3 bindings for Python predictor integration
Key Design Patterns
- Local Wheel Resolution: The CLI discovers SDK and coglet wheels from
dist/at Docker build time (not embedded in the binary) - Docker SDK Integration: Uses Docker Go SDK for container operations
- Type Safety: Dataclasses for Python type validation, strongly typed Go interfaces
- Compatibility Matrix: Automated CUDA/PyTorch/TensorFlow compatibility management
For comprehensive architecture documentation, see architecture/.
Common Tasks
Adding a new CLI command
- Create command file in
pkg/cli/ - Add command to
pkg/cli/root.go - Implement business logic in appropriate
pkg/subdirectory - Add tests
Modifying Python SDK behavior
- Edit files in
python/cog/ - Run
mise run build:sdkto rebuild wheel - Test with
mise run test:python - Integration test with
mise run test:integration
Updating ML framework compatibility
- See
tools/compatgen/for compatibility matrix generation - Update framework versions in relevant Dockerfile templates
- Test with various framework combinations
Updating the docs
- Documentation is in the
docs/directory, written in Markdown and generated into HTML usingmkdocs. - IMPORTANT: After editing any file in
docs/orREADME.md, you MUST runmise run docs:llmto regeneratedocs/llms.txt. This file is used by coding agents and should be kept in sync with the documentation. - IMPORTANT: CLI reference docs (
docs/cli.md) are auto-generated from Go source code. After modifying CLI commands incmd/orpkg/cli/, runmise run docs:clito regenerate, and ensuremise run docs:cli:checkpasses before committing.
CI Tool Dependencies
Development tools are managed in one place: mise.toml. CI workflows use
jdx/mise-action@v4 (with caching enabled) to install the same tool versions that
developers use locally. This eliminates version drift between local dev and CI.
Exceptions:
| Tool | CI method | Why |
|---|---|---|
| coglet wheel (maturin+zig) | PyO3/maturin-action | Builds inside a manylinux container with bundled maturin and zig |
| Rust target cache | Swatinem/rust-cache | Caches crates/target/ directory (separate from tool caching) |
check-stubs Python | actions/setup-python | Needs shared-library Python (libpython3.x.so) for PyO3 auto-initialize |
When updating a tool version, update mise.toml only. CI picks it up automatically.
Agent Skills
The .agents/skills/ directory contains shared skill definitions that provide specialized instructions and workflows for coding agents. Each skill is a subdirectory with a SKILL.md file that agents load on demand when the task matches.
Skills are invoked automatically by agents when a matching task is detected. See individual SKILL.md files for details on when and how each skill applies.
Important Files
VERSION.txt- Canonical version (single source of truth)cog.yaml- User-facing model configurationpkg/config/config.go- Go code for parsing and validatingcog.yamlpkg/config/data/config_schema_v1.0.json- JSON schema forcog.yamlpython/cog/base_predictor.py- Predictor interfacecrates/Cargo.toml- Rust workspace configuration (version must match VERSION.txt)crates/README.md- Coglet architecture overviewmise.toml- Task definitions for development workflow
Testing Philosophy
- Unit tests for individual components (Go and Python)
- Integration tests for end-to-end workflows
- Tests use real Docker operations (no mocking Docker API)
- Always run
mise run build:sdkafter making Python changes before testing Go code - Python 3.10-3.13 compatibility is required
Go Test Conventions
All Go tests must use testify for assertions. Do not use raw if checks with t.Fatal/t.Errorf — use require and assert instead.
require— for fatal assertions that should stop the test (setup failures, preconditions):require.NoError(t, err, "failed to create client") require.Equal(t, expected, actual) require.True(t, condition, "server should be ready")assert— for non-fatal checks where the test should continue (e.g. validating multiple fields in a loop):assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Contains(t, output, "expected substring") assert.NoError(t, err, "prediction %d failed", i)- Use
requirefor errors in setup/teardown andassertfor the actual test expectations - Prefer specific assertions (
Equal,Contains,NoError,Len,Less) over genericTrue/False— they produce better failure messages - Prefer table-driven tests for testing multiple similar cases
Related Skills
Frontend Typescript Linting.mdc
TypeScript and ESLint rules that MUST be followed when creating, modifying, or reviewing any file under apps/frontend/, including .ts, .tsx, .js, and .jsx files. Also apply when discussing frontend li...
2. Apply Deepthink Protocol (reason about dependencies
risks