AGENTS.md · dapr/dapr-agents
AGENTS.md from dapr/dapr-agents: 117 lines covering Project Context, Quick Commands, Code Standards, Testing and more.
Template by dapr
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/dapr/dapr-agents/main/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documentation
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 117 lines
- File
AGENTS.md
Sections
- Project Context
- Quick Commands
- Code Standards
- Testing
- Pull Request Rules
First lines (shown under the repo's Apache-2.0 license)
<!--
Copyright 2026 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
# Dapr Agents - Developer Guide
## Project Context
**Full Setup**: See [./docs/development/README.md](./docs/development/README.md)
## Quick Commands
- **Setup**: `uv venv && source .venv/bin/activate && uv sync --group test --extra drasi`
- **Before commit (REQUIRED)**: `uv run ruff format && uv run flake8 dapr_agents tests ext --ignore=E501,F401,W503,E203,E704 && uv run mypy --config-file mypy.ini && uv run pytest tests -m "not integration" && DAPR_AGENTS_REQUIRE_DRASI=1 uv run pytest ext -m "not integration"`
- **Individual checks**:
- Auto-format: `uv run ruff format` (rewrites files). CI fails if formatting would change anything; the read-only equivalent is `uv run ruff format --check`
- Lint: `uv run flake8 dapr_agents tests ext --ignore=E501,F401,W503,E203,E704`
- Type check: `uv run mypy --config-file mypy.ini`
- Unit tests: `uv run pytest tests -m "not integration"`
- Drasi extension tests (own pytest session, needs `--extra drasi`): `DAPR_AGENTS_REQUIRE_DRASI=1 uv run pytest ext -m "not integration"`
- **Testing**:
- Integration tests (requires API keys): `uv run pytest tests -m integration`
## Code Standards
**Branch Names**: `feat/*`, `fix/*`, `bugfix/*`, `hotfix/*`
**Commit Format**: `<type>[scope]: <description>`
- Types: `feat`, `fix`, `docs`, `chore`, `test`, `refactor`, `perf`, `ci`, `style`, `build`
- Example: `feat(agents): add new orchestrator` or `fix(llm): handle timeout errors`
**Sign-off (REQUIRED)**: Every commit must carry a DCO `Signed-off-by` line — add it automatically with `git commit -s`. The DCO bot blocks the PR if any commit is unsigned. See [CONTRIBUTING.md](./CONTRIBUTING.md#developer-certificate-of-origin-signing-your-work).
**Versioning**:
Dapr Agents use semantic versioning for releasing. Prefer making changes that allow backward compatability.
**Workflow changes**: Workflow bodies are replayed, and runs can span upgrades. Put a change that alters which activities, timers or child workflows run, or their order, behind `ctx.is_patched(...)` or into a new workflow version, and change activity inputs only additively. See [Changing workflow code](./docs/development/README.md#changing-workflow-code).
**License Header**: Every new `.py` file (source and test) must start with the Apache 2.0 header below — copied verbatim, `#`-comment style, with the year `2026`, followed by a blank line before the first import or docstring:
```python
#
# Copyright 2026 The Dapr Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
```
**Code Quality** (enforced by CI):
- **Python version**: `>=3.11,<3.15` (the optional `vectorstore` group is still `<3.14`); the root `pyproject.toml` `requires-python` is the source of truth, so update this line too when it changes. When changing the supported range, update `requires-python` in every workspace member at once (root, `ext/*`, `quickstarts/`, `examples/*`) and run `uv lock`
- **Formatting**: ruff (auto-format, no exceptions)
- **Linting**: flake8 (ignores: E501, F401, W503, E203, E704)
- **Type Checking**: mypy (config: `./mypy.ini`)
- **All checks MUST pass** before merge
- **General**:
- **Typing**: Enforce strong typing (e.g., `variable: Dict[str, List[str]] = ..`)
- **Pydantic Models**: For validated/serialized data (APIs, configs, external input)
- **Dataclasses**: For internal data structures without validation
- **Logging**:
- Use module-level logger: `logger = logging.getLogger(__name__)`
- For new log messages, prefer f-strings (e.g. logger.debug(f"{variable}")) over format strings (e.g. logger.debug("%s", variable))
- **ConfigDict**: Add `model_config = ConfigDict(arbitrary_types_allowed=True)` when Pydantic models contain non-serializable types
- **Custom Exceptions**: Define domain-specific exceptions (inherit from `Exception`); use descriptive names ending in `Error`
- **Async Execution**:
- Check for running loop with `asyncio.get_running_loop()` before creating new loops
- Use `asyncio.run_coroutine_threadsafe()` when submitting coroutines to a running loop from another thread
- Create fresh event loops only when no loop is running
- **Error Handling**:
- Always catch specific exceptions before general ones
- Log errors with context before raising: `logger.error("Operation failed: %s", error, exc_info=True)`
- Use `span.record_exception(e)` for observability when available
- **Function Signatures**: Return `None` explicitly for functions with no return value (e.g., `def setup() -> None:`)
- **Module Exports**: Define `__all__` in `__init__.py` to explicitly control public API
- **Dependencies**: Anything imported from `dapr_agents/` at runtime must be declared in `[project] dependencies` (or an optional extra that guards the import), not only in a dependency group. The gate installs the `test` group, so a package that only arrives transitively or through the group still passes CI
- **Examples**: Nothing in CI imports `examples/` or `quickstarts/`. When you rename or move a public symbol, update its users there too: `git grep -n "<OldName>" -- examples quickstarts`
## Testing
**Test Structure**: `./tests/` mirrors `./dapr_agents/` structure
- `agents/`, `llm/`, `workflow/` - Unit tests
- `quickstarts/` - E2E integration tests (requires API keys: `OPENAI_API_KEY`, etc.)
- `ext/dapr-agents-ext-drasi/tests/` - Drasi extension tests, run as their own pytest session (see Quick Commands)
- Tests that need a real MCP server can start a small FastMCP script from `tests/` over stdio (or as a subprocess on a free port for streamable HTTP), as `tests/tool/mcp_echo_server.py` does. No API keys are needed, so these run with `-m "not integration"`
**CI** (`./.github/workflows/build.yaml`): ruff → flake8 → mypy → pytest → Drasi extension tests
- Matrix: Python 3.11, 3.12, 3.13, 3.14. Each `build` job pins uv to its matrix interpreter (`UV_PYTHON`) and fails if the interpreter doesn't match
- Failures block merge
## Pull Request Rules
**REQUIRED Before PR**:
1. Run `uv run ruff format && uv run flake8 dapr_agents tests ext --ignore=E501,F401,W503,E203,E704 && uv run mypy --config-file mypy.ini && uv run pytest tests -m "not integration" && DAPR_AGENTS_REQUIRE_DRASI=1 uv run pytest ext -m "not integration"` locally - all checks must pass
2. Use conventional commit format for PR title
3. Update docs in `dapr/docs` repo for: API changes, new features, breaking changes, config options
- **Not required** for internal-only changes (bug fixes, refactors, performance, tests) that don't change the public API, features, config options, or documented/observable behavior
4. Include "AGENTS.md Notes" in the PR with suggestions to make this prompt better
**PR Will Fail If**:
- Commits are not signed (missing DCO `Signed-off-by`; use `git commit -s`)
- Not formatted with ruff
- Flake8 errors exist
- Mypy type errors present
- Any tests fail
- No corresponding docs PR (when required)Signals
- Stars
- 764
- Forks
- 157
- Open issues
- 30
- Last commit (this folder)
- Oct 14, 2026 (15 days ago)
- Last release
- Oct 9, 2026 (20 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- Apache-2.0
- Repository
- github.com/dapr/dapr-agents
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from dapr
Cite this page
AGENTS.md · dapr/dapr-agents. Agent Mart. https://agentmart.dev/templates/dapr-dapr-agents-agents-md (last updated 2026-10-24)