| name | python-package-management |
| description | Guide for managing packages in the Agent Framework Python monorepo, including creating new connector packages, versioning, and the lazy-loading pattern. Use this when adding, modifying, or releasing packages.
|
Python Package Management
Monorepo Structure
python/
├── pyproject.toml # Root package (agent-framework)
├── packages/
│ ├── core/ # agent-framework-core (main package)
│ ├── azure-ai/ # agent-framework-azure-ai
│ ├── anthropic/ # agent-framework-anthropic
│ └── ... # Other connector packages
agent-framework-core contains core abstractions and OpenAI/Azure OpenAI built-in
- Provider packages extend core with specific integrations
- Root
agent-framework depends on agent-framework-core[all]
Dependency Management
Uses uv for dependency management and
poethepoet for task automation.
uv run poe setup
uv run poe install
uv run poe venv --python 3.12
uv lock --upgrade-package <dependency-name> && uv run poe install
uv run poe upgrade-dev-dependencies
uv run poe validate-dependency-bounds-test
uv run poe validate-dependency-bounds-test --project <workspace-package-name>
uv run poe validate-dependency-bounds-project --mode both --project <workspace-package-name> --dependency "<dependency-name>"
uv run poe validate-dependency-bounds-project --mode upper --project "*"
uv run poe add-dependency-and-validate-bounds --project <workspace-package-name> --dependency "<dependency-spec>"
Dependency Bound Notes
- Stable dependencies (
>=1.0) should typically be bounded as >=<known-good>,<next-major>.
- Prerelease (
dev/a/b/rc) and <1.0 dependencies should use hard bounds with an explicit upper cap (avoid open-ended ranges).
- For
<1.0 dependencies, prefer the broadest validated range the package can really support. That may be a patch line, a minor line, or multiple minor lines when checks/tests show the broader lane is compatible.
- Prefer supporting multiple majors when practical; if APIs diverge across supported majors, use version-conditional imports/paths.
- For dependency changes, run workspace-wide bound gates first, then
validate-dependency-bounds-project --mode both for the target package/dependency to keep minimum and maximum constraints current. The same task can also drive repo-wide upper-bound automation by using --project "*" and omitting --dependency.
- Prefer targeted lock updates with
uv lock --upgrade-package <dependency-name> to reduce uv.lock merge conflicts.
- Use
add-dependency-and-validate-bounds for package-scoped dependency additions plus bound validation in one command.
- Use
upgrade-dev-dependencies for repo-wide dev tooling refreshes; it repins dev dependencies, refreshes uv.lock, and reruns check, typing, and test.
Lazy Loading Pattern
Provider folders in core use __getattr__ to lazy load from connector packages:
_IMPORTS: dict[str, tuple[str, str]] = {
"AzureAIAgentClient": ("agent_framework_azure_ai", "agent-framework-azure-ai"),
}
def __getattr__(name: str) -> Any:
if name in _IMPORTS:
import_path, package_name = _IMPORTS[name]
try:
return getattr(importlib.import_module(import_path), name)
except ModuleNotFoundError as exc:
raise ModuleNotFoundError(
f"The package {package_name} is required to use `{name}`. "
f"Install it with: pip install {package_name}"
) from exc
Adding a New Connector Package
Important: Do not create a new package unless approved by the core team.
Initial Release (Preview)
- Create directory under
packages/ (e.g., packages/my-connector/)
- Add the package to
tool.uv.sources in root pyproject.toml
- Include samples inside the package (e.g.,
packages/my-connector/samples/)
- Do NOT add to
[all] extra in packages/core/pyproject.toml
- Do NOT create lazy loading in core yet
Recommended dependency workflow during connector implementation:
- Add the dependency to the target package:
uv run poe add-dependency-to-project --project <workspace-package-name> --dependency "<dependency-spec>"
- Implement connector code and tests.
- Validate dependency bounds for that package/dependency:
uv run poe validate-dependency-bounds-project --mode both --project <workspace-package-name> --dependency "<dependency-name>"
- If the package has meaningful tests/checks that validate dependency compatibility, you can use the add + validation flow in one command:
uv run poe add-dependency-and-validate-bounds --project <workspace-package-name> --dependency "<dependency-spec>"
If compatibility checks are not in place yet, add the dependency first, then implement tests before running bound validation.
Promotion to Stable
- Move samples to root
samples/ folder
- Add to
[all] extra in packages/core/pyproject.toml
- Create provider folder in
agent_framework/ with lazy loading __init__.py
Versioning
- All non-core packages declare a lower bound on
agent-framework-core
- When core version bumps with breaking changes, update the lower bound in all packages
- Non-core packages version independently; only raise core bound when using new core APIs
Installation Options
pip install agent-framework-core
pip install agent-framework-core[all]
pip install agent-framework
pip install agent-framework-azure-ai
Maintaining Documentation
When changing a package, check if its AGENTS.md needs updates:
- Adding/removing/renaming public classes or functions
- Changing the package's purpose or architecture
- Modifying import paths or usage patterns