Skip to content

Conversation

Copy link

Copilot AI commented Dec 6, 2025

Implements Agent2Agent (A2A) protocol integration allowing BotSharp to invoke remote agents hosted on Microsoft Agent Framework. Remote agents are discovered via standardized agent cards and invoked through JSON-RPC 2.0.

Implementation

New plugin: BotSharp.Plugin.AgentFramework

  • A2A Protocol Models: JSON-RPC 2.0 message structures, agent card format, task lifecycle models
  • HTTP Client: Async task submission (sendTask) and polling (getTask) with configurable timeouts
  • Agent Discovery: Fetches and caches agent metadata from /.well-known/agent-card.json
  • Routing Integration:
    • AgentFrameworkHook loads remote agent descriptions for router matching
    • AgentFrameworkConversationHook intercepts messages and forwards to MAF service
    • Conversation history passed as context in A2A format

Core framework change:

  • Added AgentType.A2ARemote = "a2a-remote" to agent type constants

Configuration

{
  "AgentFramework": {
    "Enabled": true,
    "TimeoutSeconds": 30,
    "PollingIntervalMs": 2000,
    "MaxPollingAttempts": 60
  }
}

Agent configuration:

{
  "type": "a2a-remote",
  "templateDict": {
    "a2a_endpoint": "https://your-maf-service.azurewebsites.net"
  }
}

Message Flow

User message → Router (intent matching) → A2A Hook intercepts
  → Fetch agent card (cached) → POST /a2a/tasks (sendTask)
  → Poll status (getTask) if needed → Return response

Remote agent descriptions dynamically update from agent cards, enabling router to match intents without manual configuration sync.

Original prompt

BotSharp 与 Microsoft Agent Framework (MAF)集成
BotSharp 与 MAF 的集成属于.NET 生态内部的强强联合。最佳实践是采用微软主推的 Agent2Agent (A2A) 协议,该协议基于 JSON-RPC 2.0,专为 Agent 互操作性设计 。
4.1 通信协议规范:Agent2Agent (A2A)
A2A 协议不仅定义了消息格式,还定义了发现机制。BotSharp 作为 A2A 协议中的 Client(发起方),而 MAF 托管的服务作为 Server(接收方)。
4.1.1 发现机制 (Agent Discovery)
MAF Agent 会在标准路径 .well-known/agent-card.json 发布其元数据。BotSharp 的 MAF 插件在启动或刷新时,会请求此 URL。
Agent Card JSON 示例:
{
"name": "HR_Assistant",
"description": "Handles employee leave requests and policy inquiries.",
"version": "1.0.0",
"capabilities":
}

深度洞察:BotSharp 的 Router 可以直接利用 Agent Card 中的 description 字段作为路由依据。这意味着当远程 MAF Agent 更新其描述时,BotSharp 可以动态感知并调整路由策略,无需重新部署代码。
4.1.2 消息交互 (JSON-RPC)
A2A 使用 HTTP POST 发送 JSON-RPC 消息。
● 请求 (Request): sendTask 方法用于提交任务。
● 响应 (Response): 返回任务 ID 或直接结果。
● 流式与轮询: 对于长时任务,Client 使用 getTask 方法轮询状态,或使用 sendTaskSubscribe 建立 SSE 连接 18。
4.2 BotSharp 插件实现设计
我们需要开发 BotSharp.Plugin.AgentFramework。
依赖注入与服务注册:
参考 C# 代码示例 19,插件需要注册 A2ACardResolver 和 A2AClient。

// 伪代码展示 BotSharp 插件结构
public class AgentFrameworkPlugin : IBotSharpPlugin
{
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
// 注册 A2A 客户端工厂
services.AddSingleton<IA2AClientFactory, A2AClientFactory>();
// 注册 Agent Hook,用于将远程 MAF Agent 注入到路由表
services.AddScoped<IAgentHook, AgentFrameworkHook>();
}
}

public class AgentFrameworkHook : AgentHookBase
{
public override async Task OnAgentLoaded(Agent agent)
{
// 如果 Agent 类型标记为 A2A 远程代理
if(agent.Type == "a2a-remote") {
// 动态加载 Agent Card 更新本地描述
var card = await _resolver.GetCardAsync(agent.Endpoint);
agent.Description = card.Description;
agent.Instruction = "Forward user request to remote A2A service.";
}
}
}

4.3 序列图:BotSharp 路由至 MAF Agent

sequenceDiagram
participant User as 用户
participant Router as BotSharp Router
participant Plugin as MAF Plugin (A2A Client)
participant MAF as MAF Service (Azure App Service)

User->>Router: "我想预订下周的年假"
Router->>Router: 意图分析 -> 匹配 "HR_Assistant" (Profile: ma_framework)
Router->>Plugin: InvokeAgent(AgentId, Context)

Note over Plugin, MAF: 发现阶段 (通常缓存)
Plugin->>MAF: GET /.well-known/agent-card.json
MAF-->>Plugin: 返回 AgentCard (包含能力定义)

Note over Plugin, MAF: 执行阶段 (JSON-RPC)
Plugin->>Plugin: 将会话历史转换为 A2A Message
Plugin->>MAF: POST /a2a/tasks (JSON-RPC method: sendTask)
Note right of Plugin: Body: { "jsonrpc": "2.0", "method": "sendTask", "params": { "input": "..." } }

MAF-->>Plugin: 202 Accepted { "result": { "taskId": "task_123", "status": "queued" } }

loop 状态轮询 (Polling) 或 SSE
    Plugin->>MAF: POST /a2a/tasks (method: getTask, id: "task_123")
    MAF-->>Plugin: { "result": { "status": "running", "progress": "Checking policy..." } }
end

MAF-->>Plugin: { "result": { "status": "completed", "output": "年假预订成功" } }
Plugin-->>Router: 返回结构化响应
Router-->>User: "您的年假已成功预订。"

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits December 6, 2025 07:51
Co-authored-by: geffzhang <439390+geffzhang@users.noreply.github.com>
… improve documentation

Co-authored-by: geffzhang <439390+geffzhang@users.noreply.github.com>
Co-authored-by: geffzhang <439390+geffzhang@users.noreply.github.com>
Co-authored-by: geffzhang <439390+geffzhang@users.noreply.github.com>
Copilot AI changed the title [WIP] Integrate BotSharp with Microsoft Agent Framework Integrate BotSharp with Microsoft Agent Framework via A2A protocol Dec 6, 2025
Copilot AI requested a review from geffzhang December 6, 2025 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants