Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
0ea9858
refactor: explicit ChatResult id generation
Lancetnik Aug 20, 2025
765e12e
refactor: add Chat class
Lancetnik Aug 20, 2025
cfaf654
Merge branch 'main' into feat/remote-agents
priyansh4320 Aug 20, 2025
fe0b8d2
refactor: polish Conversible Agent
Lancetnik Aug 21, 2025
d1a1f8f
Merge branch 'main' into feat/remote-agents
Lancetnik Aug 21, 2025
422f592
chore: revert branch changes
Lancetnik Aug 21, 2025
dede993
feat: init RemoteAgent
Lancetnik Aug 25, 2025
b70dc36
Merge branch 'main' into feat/remote-agents
Lancetnik Aug 25, 2025
6d2888a
Merge branch 'feat/remote-agents' of github.com:ag2ai/ag2 into feat/r…
Lancetnik Aug 25, 2025
ded5dea
refactor: pass chat_id to _prepare_chat
Lancetnik Aug 25, 2025
d8309ca
feat: ConversableAgent compatibility
Lancetnik Aug 26, 2025
224dbc4
tests: fix _append_oai_message usage
Lancetnik Aug 27, 2025
ea71287
refactor: stateless implementation
Lancetnik Aug 27, 2025
fae9c78
refactor: revert useless changes
Lancetnik Aug 27, 2025
f5f51ad
chore: update files to main
Lancetnik Aug 27, 2025
7a964e8
feat: add async RemoteAgent execution
Lancetnik Aug 27, 2025
d77d4ae
feat: impl long-polling tasks & tools execution
Lancetnik Aug 28, 2025
f77d569
lint: fix remote agents mypy
Lancetnik Aug 29, 2025
988573d
feat: pass ContextVariables to remote tool executor
Lancetnik Aug 29, 2025
7a53f3d
feat: pass ContextVariables to remote tool executor
Lancetnik Aug 29, 2025
31fe128
lint: fix remote agents mypy
Lancetnik Aug 29, 2025
7ef6224
feat: support ReplyResult in remote tools
Lancetnik Sep 2, 2025
ac45596
chore: revert _prepare_chat method changes
Lancetnik Sep 4, 2025
c6841cb
Merge branch 'main' of github.com:ag2ai/ag2 into feat/remote-agents
Lancetnik Sep 4, 2025
670e8e3
feat: support guardrails
Lancetnik Sep 4, 2025
9be800e
lint: correct mypy types
Lancetnik Sep 4, 2025
933be7f
Merge branch 'main' into feat/remote-agents
Lancetnik Sep 4, 2025
34bd23c
feat: add silent mode for RemoteAgent
Lancetnik Sep 5, 2025
127df28
tests: add tests for remote client
Lancetnik Sep 5, 2025
23956b6
docs: add default pattern example to play
Lancetnik Sep 9, 2025
5325452
feat: support DefaultPattern
Lancetnik Sep 10, 2025
706fd79
refactor: polish remote package structure
Lancetnik Sep 10, 2025
4f33c7f
feat: add RetryPolicy to process RemoteAgent inaccessibility
Lancetnik Sep 10, 2025
e69b889
chore: merge main
Lancetnik Sep 29, 2025
23b879e
feat: add A2ARemoteAgent
Lancetnik Sep 30, 2025
2ca8f1b
feat: support PydanticAI targets
Lancetnik Oct 1, 2025
3c38a52
feat: add A2aAgentServer
Lancetnik Oct 4, 2025
a9db3d9
docs: add a2a server examples
Lancetnik Oct 4, 2025
305ff4e
feat: process A2A connection errors
Lancetnik Oct 5, 2025
92cb1cb
docs: add generated examples
Lancetnik Oct 6, 2025
f7c7dda
docs: polish a2a index page
Lancetnik Oct 7, 2025
5be163c
docs: add A2A server documentation
Lancetnik Oct 9, 2025
3e59728
docs: complete A2aServer documentation
Lancetnik Oct 11, 2025
f28648a
docs: complete A2A client
Lancetnik Oct 13, 2025
5b109b0
Merge branch 'main' into feat/remote-agents
Lancetnik Oct 13, 2025
4cf5686
lint: install a2a to check types
Lancetnik Oct 13, 2025
3aef70d
chore: add Nikita as A2A Codeowner and maintainer
Lancetnik Oct 13, 2025
36ca0fd
test: add checks for A2A parsing
Lancetnik Oct 13, 2025
dbc87de
ci: correct testing with a2a
Lancetnik Oct 13, 2025
60a211b
chore: remove remote-examples
Lancetnik Oct 13, 2025
6beeba1
Documentation updates
marklysze Oct 15, 2025
855605a
feat: add TestAgent and write some tests
Lancetnik Oct 15, 2025
cd5e78a
Merge branch 'main' into feat/remote-agents
Lancetnik Oct 15, 2025
8ea14d6
chore: polish .gitignore style
Lancetnik Oct 15, 2025
02e2a08
test: add tests for RemoteService
Lancetnik Oct 16, 2025
9cce978
test: add A2A chat tests
Lancetnik Oct 17, 2025
ac3317f
chore: merge main
Lancetnik Oct 17, 2025
78c98ac
ci: trigger claude at ready to review PR state
Lancetnik Oct 17, 2025
584d09e
chore: add fasta2a to pydantic-ai interop dep
Lancetnik Oct 17, 2025
a2db8fc
test: bump pydantic-ai interop version to let tests pass
Lancetnik Oct 17, 2025
12a2c7d
test: fix red tests
Lancetnik Oct 20, 2025
ac207d9
docs: add Remote Tool call diagram
Lancetnik Oct 20, 2025
558455a
test: fix red tests
Lancetnik Oct 20, 2025
bab39f9
docs: rephrase
Lancetnik Oct 20, 2025
120d66b
chore: remove 0.10 deprecations
Lancetnik Oct 20, 2025
ed61cf1
test: fix red tests
Lancetnik Oct 20, 2025
5822c12
docs: polish LLMConfig usage
Lancetnik Oct 21, 2025
3019c31
Remote Agent documentation tweaks
marklysze Oct 21, 2025
3758589
Merge branch 'main' into feat/remote-agents
marklysze Oct 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# AG2 code owners
# About code owners https://docs.github.com/ru/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

# A2A and Remote
/autogen/a2a/ @Lancetnik
/autogen/remote/ @Lancetnik
/test/a2a/ @Lancetnik
/test/remote/ @Lancetnik
/website/docs/user-guide/a2a/ @Lancetnik
16 changes: 14 additions & 2 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ name: Claude Code Review
on:
# For PRs from the same repository (fast path)
pull_request:
types: [opened, synchronize]
types:
- opened
- synchronize
- ready_for_review
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"
# For PRs from forked repositories (secure path with secrets)
pull_request_target:
types: [opened, synchronize]
types:
- opened
- synchronize
- ready_for_review

jobs:
claude-review:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/core-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
shell: bash
- name: Install packages and dependencies
run: |
uv pip install --system -e .[test,cosmosdb,interop,redis,websockets,openai,docs]
uv pip install --system -e .[test,cosmosdb,interop,redis,websockets,openai,docs,a2a]
- name: Install optional dependencies for code executors
run: |
uv pip install --system -e ".[jupyter-executor]"
Expand Down
40 changes: 20 additions & 20 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
.docusaurus/
node_modules/

# Project
/.vs
.vscode
.vs/
.vscode/
.idea/
.DS_Store

# Log files
*.log

# Python virtualenv
.venv*
.env*

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -76,7 +75,7 @@ db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache
.webassets-cache/

# Scrapy stuff:
.scrapy
Expand Down Expand Up @@ -125,6 +124,8 @@ venv/
ENV/
env.bak/
venv.bak/
.venv*
.env*

# Spyder project settings
.spyderproject
Expand All @@ -141,6 +142,9 @@ venv.bak/
.dmypy.json
dmypy.json

# ruff
.ruff_cache/

# Pyre type checker
.pyre/

Expand All @@ -150,10 +154,7 @@ dmypy.json
# Cython debug symbols
cython_debug/

logs

.idea/*
.DS_Store
logs/

output/
*.pkl
Expand All @@ -168,7 +169,7 @@ wolfram.txt

# DB on disk for Teachability
tmp/
test/my_tmp/*
test/my_tmp/

# Storage for the AgentEval output
test/test_files/agenteval-in-out/out/
Expand All @@ -179,28 +180,27 @@ local_cache/

# Files created by tests
*tmp_code_*
test/agentchat/test_agent_scripts/*
test/agentchat/test_agent_scripts/

# test cache
.cache_test
.db
local_cache


notebook/result.png

notebook/coding

chroma
notebook/reasoning_tree.json
client_secret*.json
*token*.json
*credentials.json
notebook/*_server.py

notebook/result.png
notebook/coding/

notebook/mcp/wikipedia_articles
notebook/mcp/arxiv_papers
notebook/mcp/wikipedia_articles/
notebook/mcp/arxiv_papers/

remote-examples

*CLAUDE.md:
.cursor/
46 changes: 24 additions & 22 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@

## Here is a list of maintainers for the AG2 project.

| Name | GitHub Handle | Organization | Features |
|-----------------|------------------------------------------------------------|------------------------|-----------------------------------------|
| Qingyun Wu | [qingyun-wu](https://github.com/qingyun-wu) | Penn State University | all, alt-models, autobuilder |
| Chi Wang | [sonichi](https://github.com/sonichi) | - | all |
| Mark Sze | [marklysze](https://github.com/marklysze) | - | alt-models, group chat |
| Hrushikesh Dokala | [Hk669](https://github.com/Hk669) | - | alt-models, swebench, logging, rag |
| Jiale Liu | [LeoLjl](https://github.com/LeoLjl) | Penn State University | autobuild, group chat |
| Shaokun Zhang | [skzhang1](https://github.com/skzhang1) | Penn State University | AgentOptimizer, Teachability |
| Yixuan Zhai | [randombet](https://github.com/randombet) | Meta | group chat, sequential_chats, rag |
| Yiran Wu | [yiranwu0](https://github.com/yiranwu0) | Penn State University | alt-models, group chat, logging, infra |
| Jieyu Zhang | [JieyuZ2](https://jieyuz2.github.io/) | University of Washington | autobuild, group chat |
| Davor Runje | [davorrunje](https://github.com/davorrunje) | airt.ai | Tool calling, I/O |
| Rudy Wu | [rudyalways](https://github.com/rudyalways) | Google | all, group chats, sequential chats |
| Haiyang Li | [ohdearquant](https://github.com/ohdearquant) | - | all, sequential chats, structured output, low-level|
| Eric Moore | [emooreatx](https://github.com/emooreatx) | IBM | all|
| Evan David | [evandavid1](https://github.com/evandavid1) | - | all |
| Tvrtko Sternak | [sternakt](https://github.com/sternakt) | airt.ai | structured output |
| Jiacheng Shang | [Eric-Shang](https://github.com/Eric-Shang) | Toast | RAG |
| Alec Solder | [alecsolder](https://github.com/alecsolder) | - | swarms, reasoning, function calling |
| Marc Willhaus | [willhama](https://github.com/willhama) | - | - |
| George Sideris | [giorgossideris](https://github.com/giorgossideris) | - | reasoning, RAG |
| Beibin Li | [BeibinLi](https://github.com/BeibinLi) | GenAI, Meta | multimodal, reasoning, optiguide |
| Name | GitHub Handle | Organization | Features |
|-------------------|------------------------------------------------------------|--------------------------|-----------------------------------------|
| Qingyun Wu | [qingyun-wu](https://github.com/qingyun-wu) | Penn State University | all, alt-models, autobuilder |
| Chi Wang | [sonichi](https://github.com/sonichi) | - | all |
| Mark Sze | [marklysze](https://github.com/marklysze) | - | alt-models, group chat |
| Hrushikesh Dokala | [Hk669](https://github.com/Hk669) | - | alt-models, swebench, logging, rag |
| Jiale Liu | [LeoLjl](https://github.com/LeoLjl) | Penn State University | autobuild, group chat |
| Shaokun Zhang | [skzhang1](https://github.com/skzhang1) | Penn State University | AgentOptimizer, Teachability |
| Yixuan Zhai | [randombet](https://github.com/randombet) | Meta | group chat, sequential_chats, rag |
| Yiran Wu | [yiranwu0](https://github.com/yiranwu0) | Penn State University | alt-models, group chat, logging, infra |
| Jieyu Zhang | [JieyuZ2](https://jieyuz2.github.io/) | University of Washington | autobuild, group chat |
| Davor Runje | [davorrunje](https://github.com/davorrunje) | airt.ai | Tool calling, I/O |
| Rudy Wu | [rudyalways](https://github.com/rudyalways) | Google | all, group chats, sequential chats |
| Haiyang Li | [ohdearquant](https://github.com/ohdearquant) | - | all, sequential chats, structured output, low-level|
| Eric Moore | [emooreatx](https://github.com/emooreatx) | IBM | all |
| Evan David | [evandavid1](https://github.com/evandavid1) | - | all |
| Tvrtko Sternak | [sternakt](https://github.com/sternakt) | airt.ai | structured output |
| Jiacheng Shang | [Eric-Shang](https://github.com/Eric-Shang) | Toast | RAG |
| Alec Solder | [alecsolder](https://github.com/alecsolder) | - | swarms, reasoning, function calling |
| Marc Willhaus | [willhama](https://github.com/willhama) | - | - |
| George Sideris | [giorgossideris](https://github.com/giorgossideris) | - | reasoning, RAG |
| Beibin Li | [BeibinLi](https://github.com/BeibinLi) | GenAI, Meta | multimodal, reasoning, optiguide |
| Nikita Pastukhov | [Lancetnik](https://github.com/lancetnik) | - | A2A |


**Pending Maintainers list (Marked with \*, Waiting for explicit approval from the maintainers)**
| Name | GitHub Handle | Organization | Features |
Expand Down
36 changes: 36 additions & 0 deletions autogen/a2a/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
#
# SPDX-License-Identifier: Apache-2.0
try:
from a2a.types import AgentCard
except ImportError as e:
raise ImportError("a2a-sdk is not installed. Please install it with:\npip install ag2[a2a]") from e

import warnings

warnings.warn(
(
"AG2 Implementation for A2A support is in experimental mode "
"and is subjected to breaking changes. Once it's stable enough the "
"experimental mode will be removed. Your feedback is welcome."
),
ImportWarning,
stacklevel=2,
)

from autogen.remote.httpx_client_factory import HttpxClientFactory

from .agent_executor import AutogenAgentExecutor
from .client import A2aRemoteAgent
from .httpx_client_factory import MockClient
from .server import A2aAgentServer, CardSettings

__all__ = (
"A2aAgentServer",
"A2aRemoteAgent",
"AgentCard",
"AutogenAgentExecutor",
"CardSettings",
"HttpxClientFactory",
"MockClient",
)
105 changes: 105 additions & 0 deletions autogen/a2a/agent_executor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
#
# SPDX-License-Identifier: Apache-2.0

from datetime import datetime, timezone

from a2a.server.agent_execution import AgentExecutor, RequestContext
from a2a.server.events import EventQueue
from a2a.types import TaskArtifactUpdateEvent, TaskState, TaskStatus, TaskStatusUpdateEvent
from a2a.utils import new_task
from a2a.utils.message import new_agent_text_message

from autogen import ConversableAgent
from autogen.doc_utils import export_module
from autogen.remote.agent_service import AgentService

from .utils import request_message_from_a2a, response_message_to_a2a


@export_module("autogen.a2a")
class AutogenAgentExecutor(AgentExecutor):
"""An agent executor that bridges Autogen ConversableAgents with A2A protocols.

This class wraps an Autogen ConversableAgent to enable it to be executed within
the A2A framework, handling message processing, task management, and event publishing.
"""

def __init__(self, agent: ConversableAgent) -> None:
self.agent = AgentService(agent)

async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
assert context.message

task = context.current_task
if not task:
task = new_task(context.message)
task.status.timestamp = datetime.now(timezone.utc).isoformat()
# publish the task status submitted event
await event_queue.enqueue_event(task)

try:
result = await self.agent(request_message_from_a2a(context.message))

except Exception as e:
# publish the task status failed event
await event_queue.enqueue_event(
TaskStatusUpdateEvent(
task_id=task.id,
status=TaskStatus(
state=TaskState.failed,
message=new_agent_text_message(
str(e),
task_id=task.id,
context_id=context.context_id,
),
timestamp=datetime.now(timezone.utc).isoformat(),
),
context_id=context.context_id,
final=True,
)
)
return

artifact, messages = response_message_to_a2a(result, context.context_id, task.id)

# publish local chat history events
for message in messages:
await event_queue.enqueue_event(
TaskStatusUpdateEvent(
task_id=task.id,
status=TaskStatus(
state=TaskState.working,
message=message,
timestamp=datetime.now(timezone.utc).isoformat(),
),
context_id=context.context_id,
final=False,
)
)

# publish the task result event
await event_queue.enqueue_event(
TaskArtifactUpdateEvent(
task_id=task.id,
last_chunk=True,
context_id=context.context_id,
artifact=artifact,
)
)

# publish the task status completed event
await event_queue.enqueue_event(
TaskStatusUpdateEvent(
task_id=task.id,
status=TaskStatus(
state=TaskState.completed,
timestamp=datetime.now(timezone.utc).isoformat(),
),
context_id=context.context_id,
final=True,
)
)

async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
pass
Loading
Loading