Depends#
The Depends mechanism allows you to calculate and inject dependencies dynamically at execution time.
The key difference with Dependency Injection is their execution model. Inject is used to retrieve static objects or configurations that have already been created (like an existing database connection or API key). Depends, on the other hand, executes a callable function during the tool's invocation to resolve the dependency.
Under the hood, Depends uses the exact same mechanism and design philosophy as FastAPI's dependency injection system.
Side-execution#
You can use Depends to execute side-effects before your tool runs—even if your tool doesn't actually need the return value of the dependency. This is extremely useful for things like authentication, logging, or permission verification.
To do this, simply declare the dependency in your tool's signature. The framework will execute it, and you can safely ignore the injected value.
Sync/Async
Depends can be used with both synchronous and asynchronous functions.
Depends with yield#
Just like in FastAPI, you can create dependencies that use yield instead of return. This allows you to execute "teardown" or "cleanup" code after the tool has finished executing.
This is the recommended approach for managing resource lifecycles, such as opening and closing database sessions or file handlers.
Combining Depends and Inject#
A powerful pattern is to combine Depends with Inject. You can use Inject to retrieve a static configuration or persistent resource (like a database connection pool), and then use Depends to manage a short-lived resource (like a database session) based on that configuration.
Dependencies caching#
By default, if multiple parameters in your tool (or multiple sub-dependencies) depend on the exact same Depends function, the framework will only execute that function once per tool call. The result is cached and reused for any subsequent injections within that specific execution step.
If you explicitly want the dependency to be re-calculated every single time it is injected, you can disable the cache by passing use_cache=False:
Dependencies Overrides#
During testing, you often need to mock or override complex dependencies (like replacing a production database with a mock test database).
You can easily override any Depends function at the agent level using the dependency_provider. When the agent executes, it will automatically route all requests for the original dependency to your override function.
To override Inject dependencies, you can just set dependencies={...} in the ask call.