Integration package for Dishka DI and AG2 Framework
Project description
AG2 integration for Dishka
Though it is not required, you can use dishka-ag2 integration. It features:
APP,SESSIONandREQUESTscope management using AG2 beta middleware and@injectAG2Providerfor working withBaseEvent,Context,ToolCallEventandHumanInputRequestin container- Automatic injection of dependencies via
@injectin supported AG2 hooks
Scope mapping
| Dishka scope | AG2 lifecycle | Description |
|---|---|---|
Scope.APP |
Root container | Lives for the application/container lifetime. |
Scope.SESSION |
on_turn |
Created once per agent.ask() turn and shared by all nested tool/LLM/HITL calls in that turn. |
Scope.REQUEST |
on_tool_execution, on_llm_call, on_human_input, injected prompt/schema validators |
Created for each tool execution, LLM call, HITL request, injected dynamic prompt, or injected response validator. |
Supported AG2 Features
| AG2 feature | Scope.APP |
Scope.SESSION |
Scope.REQUEST |
Notes |
|---|---|---|---|---|
@agent.tool |
yes | yes | yes | Main supported path for injected tools. |
standalone @tool in Agent(..., tools=[...]) |
yes | yes | yes | Same lifecycle as @agent.tool. |
Toolkit / custom Tool execution |
yes | yes | yes | Works for actual tool functions if the custom tool forwards middleware in register(). |
on_llm_call middleware path |
yes | yes | yes | REQUEST is opened for every model call. |
HITL hooks (hitl_hook= / @agent.hitl_hook) |
yes | yes | yes | HumanInputRequest is available in REQUEST scope. |
@agent.prompt |
yes | no | yes | Dynamic prompts run before middleware is constructed. Use dependencies={CONTAINER_NAME: container} so @inject can open REQUEST from the container. |
response_schema validators |
yes | no | yes | Injected validators can use REQUEST dependencies during reply.content() validation. |
See the examples directory for runnable examples:
examples/ag2_agent_tool.py-@agent.toolwith APP, SESSION and REQUEST.examples/ag2_standalone_tool.py- standalone@toolwithtools=[...].examples/ag2_standalone_tool_hitl.pyandexamples/ag2_standalone_tool_hitl_arg.py- HITL hook injection.examples/ag2_dynamic_prompt.py-@agent.promptwith injected APP/REQUEST dependencies.examples/ag2_response_schema.py-response_schemavalidators with injected APP/REQUEST dependencies.examples/ag2_toolkit.py- AG2Toolkitwith injected tool functions.examples/ag2_custom_toolset.py- custom AG2Tool/toolset with injectedschemas()and injected tool functions.
Installation
Install using pip
pip install dishka-ag2
Or with uv
uv add dishka-ag2
How to use
- Import
from dishka_ag2 import (
AG2Provider,
CONTAINER_NAME,
DishkaAsyncMiddleware,
DishkaSyncMiddleware,
FromDishka,
inject,
)
from dishka import make_async_container, Provider, Scope, provide
- Create provider. You can use
ToolCallEventorHumanInputRequestas factory parameters onREQUESTscope for tool/HITL requests, andBaseEvent/ContextonSESSIONscope.
For @agent.prompt and response_schema validators, REQUEST scope is also supported, but it is opened outside a tool/HITL event. Use request factories that do not require ToolCallEvent or HumanInputRequest in those paths.
from autogen.beta.events import HumanInputRequest, ToolCallEvent
class MyProvider(Provider):
@provide(scope=Scope.APP)
def app_counter(self) -> AppCounter:
return AppCounter()
@provide(scope=Scope.SESSION)
def conversation_state(self) -> ConversationState:
return ConversationState()
@provide(scope=Scope.REQUEST)
def tool_request_state(self, event: ToolCallEvent) -> ToolRequestState:
return ToolRequestState(tool_name=event.name)
@provide(scope=Scope.REQUEST)
def audit_log(self, event: HumanInputRequest) -> AuditLog:
return AuditLog(f"Human was asked: {event.content}")
@provide(scope=Scope.REQUEST)
def greeting_service(
self,
conversation: ConversationState,
request: ToolRequestState,
) -> GreetingService:
return GreetingService(conversation=conversation, request=request)
- Mark those of your tool parameters which are to be injected with
FromDishka[]
@agent.tool
@inject
async def greet_user(
name: str,
greeting: FromDishka[GreetingService],
counter: FromDishka[AppCounter],
) -> str:
count = counter.increment()
result = await greeting.greet(name)
return result
- Setup dishka integration: create container with
AG2Provider()and pass it toDishkaAsyncMiddlewareorDishkaSyncMiddlewareviaMiddleware
from autogen.beta import Agent
from autogen.beta.middleware import Middleware
container = make_async_container(MyProvider(), AG2Provider())
agent = Agent(
"assistant",
prompt="Use tools to greet users.",
middleware=[
Middleware(DishkaAsyncMiddleware, container=container),
],
)
- Run the agent and close the container when done
async def main() -> None:
try:
reply = await agent.ask("Greet Connor and Sara.")
print(reply.body)
finally:
await container.close()
AG2Provider context types
AG2Provider registers the following AG2 types as context dependencies, so you can use them as factory parameters:
| Type | Scope | Description |
|---|---|---|
BaseEvent |
SESSION | Initial event that started the turn |
Context |
SESSION | AG2 context for the current turn |
ToolCallEvent |
REQUEST | Event for the current tool invocation |
HumanInputRequest |
REQUEST | Event for the current HITL request |
Full example
import asyncio
from autogen.beta import Agent
from autogen.beta.events import ToolCallEvent
from autogen.beta.middleware import Middleware
from autogen.beta.testing import TestConfig
from dishka import Provider, Scope, make_async_container, provide
from dishka_ag2 import AG2Provider, DishkaAsyncMiddleware, FromDishka, inject
class AppCounter:
def __init__(self) -> None:
self._value = 0
def increment(self) -> int:
self._value += 1
return self._value
class MyProvider(Provider):
@provide(scope=Scope.APP)
def app_counter(self) -> AppCounter:
return AppCounter()
provider = MyProvider()
container = make_async_container(provider, AG2Provider())
agent = Agent(
"assistant",
prompt="Use tools to count.",
config=TestConfig(
ToolCallEvent(name="count", arguments="{}"),
ToolCallEvent(name="count", arguments="{}"),
"Done.",
),
middleware=[
Middleware(DishkaAsyncMiddleware, container=container),
],
)
@agent.tool
@inject
async def count(
counter: FromDishka[AppCounter],
) -> str:
value = counter.increment()
return f"count={value}"
async def main() -> None:
try:
reply = await agent.ask("Count twice.")
print(reply.body)
finally:
await container.close()
if __name__ == "__main__":
asyncio.run(main())
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dishka_ag2-0.1.tar.gz.
File metadata
- Download URL: dishka_ag2-0.1.tar.gz
- Upload date:
- Size: 131.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90de3f5938c45512828ce41d7bd6ad6c7987f934dc084b83914dc95a7db2a5a6
|
|
| MD5 |
27bd05ed486d54096970beba72cfe557
|
|
| BLAKE2b-256 |
3e0efe1af6ebd536fb6347eb05b4caf5f03f983b3324ee9c1719e4493bd49bec
|
File details
Details for the file dishka_ag2-0.1-py3-none-any.whl.
File metadata
- Download URL: dishka_ag2-0.1-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
252d2c7d59ee90dd25bb8af29d88daeb6309e871abc4a19c74808eb343aadd0d
|
|
| MD5 |
3c6a6e739f009b8668690ca52b7c4232
|
|
| BLAKE2b-256 |
649149b950b59ed3d8f5cd10ff1fd7d89d067e6fda1638aed1fc9a5fc9b70b7d
|