From 5953b984fab17861c10d3ca1bb0de3e8183898b8 Mon Sep 17 00:00:00 2001 From: Zhoujie628 Date: Mon, 17 Aug 2026 17:33:08 +0800 Subject: [PATCH] docs+samples: remove customer-specific info from open-source repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove all customer instantiation details from documentation and sample code to keep the open-source repository vendor-neutral. Documents cleaned: - 工作台AgentScope结合方案.md: remove 凯通/中国移动/广东/阿里 references, replace com.kaitong.workbench with com.example.workbench, rename KaitongControlPoint -> AgentScopeControlPoint - 工作台集成指南.md: remove 广东移动/WAIMO/华为/iMaster/粤东粤西 references, replace with generic terms Source code cleaned: - SpnDomainAgentCity1Executor: 粤东OMC -> 城市1OMC in all strings/prompts - SpnDomainAgentCity2Executor: 粤西OMC -> 城市2OMC in all strings/prompts - WorkbenchControlPoint: rename hasYuedongFault/hasYuexiFault variables - NegotiationStrategy: 粤东-粤西 -> 城市1-城市2 in fallback text - SpnCrossCityDiagnosisDemo: 粤东-粤西 -> 城市1-城市2 in task text - AgentCard JSON: remove Yuedong/Yuexi, change provider to OpenAN - Test assertions: 粤东 -> 城市1 Verified: zero matches for 凯通/kaitong/WAIMO/粤东/粤西/广东移动/ 阿里开源/iMaster/Yuedong/Yuexi across all docs and samples. Copyright headers (Huawei Technologies) retained as copyright holder. Signed-off-by: Zhoujie628 --- ...23\345\220\210\346\226\271\346\241\210.md" | 38 +++++----- ...06\346\210\220\346\214\207\345\215\227.md" | 70 +++++++++---------- .../examples/agents/NegotiationStrategy.java | 6 +- .../agents/SpnDomainAgentCity1Executor.java | 20 +++--- .../agents/SpnDomainAgentCity2Executor.java | 18 ++--- .../agents/WorkbenchControlPoint.java | 26 +++---- .../embedded/SpnCrossCityDiagnosisDemo.java | 6 +- .../agentcard/spn_domain_agent_city1.json | 4 +- .../agentcard/spn_domain_agent_city2.json | 4 +- .../agentcard/transport_workbench_agent.json | 2 +- .../examples/EmbeddedA2AServerTest.java | 4 +- .../engine/examples/SpnCrossCityE2ETest.java | 9 ++- 12 files changed, 107 insertions(+), 100 deletions(-) diff --git "a/docs/zh/\345\267\245\344\275\234\345\217\260AgentScope\347\273\223\345\220\210\346\226\271\346\241\210.md" "b/docs/zh/\345\267\245\344\275\234\345\217\260AgentScope\347\273\223\345\220\210\346\226\271\346\241\210.md" index 2205313b..428462d1 100644 --- "a/docs/zh/\345\267\245\344\275\234\345\217\260AgentScope\347\273\223\345\220\210\346\226\271\346\241\210.md" +++ "b/docs/zh/\345\267\245\344\275\234\345\217\260AgentScope\347\273\223\345\220\210\346\226\271\346\241\210.md" @@ -1,6 +1,6 @@ # A2A-T 执行引擎 SDK 与 AgentScope 结合方案 -> 面向中国移动凯通工作台团队。说明 A2A-T 执行引擎 SDK(a2at-engine-java)与阿里开源 AgentScope 框架如何在凯通工作台 Agent 化改造中协同定位、划分职责、落地结合,发挥各自最大作用。本文档供双方对方案使用。 +> 面向工作台研发团队。说明 A2A-T 执行引擎 SDK(a2at-engine-java)与 AgentScope 框架如何在工作台 Agent 化改造中协同定位、划分职责、落地结合,发挥各自最大作用。本文档供双方对方案使用。 --- @@ -8,9 +8,9 @@ ### 1.1 现状 -凯通工作台当前为传统 Spring Java 微服务,承载广东传输工作台智能体的业务逻辑。业务复杂度高,当前 SDK demo 中的工作台智能体(`WorkbenchControlPoint`)为打桩实现。 +工作台当前为传统 Spring Java 微服务,承载传输工作台智能体的业务逻辑。业务复杂度高,当前 SDK demo 中的工作台智能体(`WorkbenchControlPoint`)为打桩实现。 -工作台团队计划从传统 Spring 微服务做 Agent 化改造,跟上行业趋势,拟采用阿里开源的 AgentScope 框架。 +工作台团队计划从传统 Spring 微服务做 Agent 化改造,跟上行业趋势,拟采用 AgentScope 框架。 ### 1.2 目标 @@ -180,16 +180,16 @@ CompletableFuture onNegotiation(String agentName, String negotiationText ```mermaid graph TD - WAIMO["WAIMO 故障中心
(上层业务系统)"] + UPPER["上层故障系统
(上层业务系统)"] ORCH["编排中心
(Python/FastAPI)
PSOP 存储 + 搜索 + 智能体注册"] - WB["凯通工作台智能体
(Spring Boot + spring-boot-starter)"] + WB["工作台智能体
(Spring Boot + spring-boot-starter)"] BRIDGE["ReasoningBridge
(Java 薄 HTTP 桥)"] AS["AgentScope 推理服务
(Python/FastAPI)
ReActAgent + tools + memory"] OMC1["城市 OMC 智能体
(下游)"] OMC2["城市 OMC 智能体
(下游)"] BIZ["工作台业务系统
(告警/拓扑/工单)"] - WAIMO -->|"A2A-T Task-T 原始诊断任务"| WB + UPPER -->|"A2A-T Task-T 原始诊断任务"| WB WB -->|"LoadPsop.search/load"| ORCH ORCH -->|"PSOP 工作流"| WB WB -->|"onTask/onSelfTask/onRoute/onNeg"| BRIDGE @@ -205,13 +205,13 @@ graph TD ```mermaid sequenceDiagram - participant WAIMO as WAIMO 故障中心 + participant UPPER as 上层故障系统 participant WB as 工作台智能体 (Spring+SDK) participant ORCH as 编排中心 participant AS as AgentScope 推理服务 participant OMC as 城市 OMC 智能体 - WAIMO->>WB: A2A-T Task-T 原始诊断任务 + UPPER->>WB: A2A-T Task-T 原始诊断任务 Note over WB: AgentExecutor 接收,委派给 Orchestrator WB->>ORCH: LoadPsop.search(intent) ORCH-->>WB: PSOP 工作流拓扑 @@ -248,7 +248,7 @@ sequenceDiagram end Note over WB: ExecutePsop 结束,产出汇总 - WB-->>WAIMO: 诊断结果 + Artifact + WB-->>UPPER: 诊断结果 + Artifact ``` ### 5.3 职责分配总表 @@ -282,7 +282,7 @@ sequenceDiagram ### 6.2 Java 侧接口定义 ```java -package com.kaitong.workbench.bridge; +package com.example.workbench.bridge; import java.util.List; import java.util.Map; @@ -336,7 +336,7 @@ public interface ReasoningBridge { ### 6.3 ControlPoint 实现(工作台侧) ```java -package com.kaitong.workbench.control; +package com.example.workbench.control; import dev.openan.workflow.engine.client.WorkflowEngineClient; import dev.openan.workflow.engine.control.DefaultControlPoint; @@ -344,7 +344,7 @@ import dev.openan.workflow.engine.model.JumpCondition; import dev.openan.workflow.engine.model.RouteDecision; import dev.openan.workflow.engine.model.TaskRequest; import dev.openan.workflow.engine.model.TaskResponse; -import com.kaitong.workbench.bridge.ReasoningBridge; +import com.example.workbench.bridge.ReasoningBridge; import java.util.List; import java.util.Map; @@ -354,11 +354,11 @@ import java.util.concurrent.CompletableFuture; * 工作台 ControlPoint:四个方法各一行调桥,业务逻辑全在 AgentScope 侧。 * SDK 承担 sendMessage 之后的全部协议机制(Task-T 提示词、协商循环、认证)。 */ -public class KaitongControlPoint extends DefaultControlPoint { +public class AgentScopeControlPoint extends DefaultControlPoint { private final ReasoningBridge bridge; - public KaitongControlPoint(ReasoningBridge bridge) { + public AgentScopeControlPoint(ReasoningBridge bridge) { this.bridge = bridge; } @@ -423,7 +423,7 @@ public class KaitongControlPoint extends DefaultControlPoint { ### 6.4 HTTP 桥实现(工作台侧) ```java -package com.kaitong.workbench.bridge; +package com.example.workbench.bridge; import com.fasterxml.jackson.databind.ObjectMapper; import java.net.URI; @@ -528,18 +528,18 @@ public class HttpReasoningBridge implements ReasoningBridge { ### 6.5 AgentScope 侧服务骨架(Python) ```python -# kaitong_reasoning_service.py +# reasoning_service.py # AgentScope 推理服务:四个端点对应 ControlPoint 四个回调。 # 每个端点用 ReActAgent 做推理,可调用工作台业务系统工具。 from fastapi import FastAPI from pydantic import BaseModel -app = FastAPI(title="Kaitong Workbench Reasoning Service") +app = FastAPI(title="Workbench Reasoning Service") # 初始化 LLM + Agent(按 AgentScope 最新文档配置) # agent = ReActAgent( -# name="kaitong_workbench", +# name="workbench_agent", # model=..., # tools=[ # Tool(query_alarm), # 对接工作台告警系统 @@ -674,7 +674,7 @@ graph LR | 1. 引入 starter | Maven 依赖 `spring-boot-starter`,写 `@Component AgentExecutor` | 提供 starter + autoconfig | | 2. 部署 AgentScope | 起 Python FastAPI 服务,四个端点骨架(可先返回固定文本) | 不涉及 | | 3. 实现桥 | 写 `HttpReasoningBridge`,配置 `a2a.reasoning-url` | 不涉及 | -| 4. 委派 ControlPoint | `KaitongControlPoint` 四方法委派给桥 | 提供 ControlPoint 接口 + DefaultControlPoint | +| 4. 委派 ControlPoint | `AgentScopeControlPoint` 四方法委派给桥 | 提供 ControlPoint 接口 + DefaultControlPoint | | 5. 接业务工具 | AgentScope 工具对接告警/拓扑/工单系统 | 不涉及 | | 6. 端到端联调 | 编排中心搜 PSOP -> 工作台执行 -> 下游 OMC 响应 | 提供 ExecutePsop + LoadPsop | diff --git "a/docs/zh/\345\267\245\344\275\234\345\217\260\351\233\206\346\210\220\346\214\207\345\215\227.md" "b/docs/zh/\345\267\245\344\275\234\345\217\260\351\233\206\346\210\220\346\214\207\345\215\227.md" index 10723ae6..1458434a 100644 --- "a/docs/zh/\345\267\245\344\275\234\345\217\260\351\233\206\346\210\220\346\214\207\345\215\227.md" +++ "b/docs/zh/\345\267\245\344\275\234\345\217\260\351\233\206\346\210\220\346\214\207\345\215\227.md" @@ -1,6 +1,6 @@ # 编排中心工作流执行引擎 SDK 工作台集成指南 -> 面向广东移动传输工作台智能体研发团队。本文档以 SPN 专线故障跨城协同诊断联创场景为例,从工作台视角说明接入Workflow执行引擎 SDK 的完整路径。 +> 面向传输工作台研发团队。本文档以 SPN 专线故障跨城协同诊断联创场景为例,从工作台视角说明接入Workflow执行引擎 SDK 的完整路径。 --- @@ -10,17 +10,17 @@ ```mermaid graph TD - WAIMO["WAIMO 故障中心
(上层业务系统)"] + UPPER["上层故障系统
(上层业务系统)"] WB["传输工作台智能体 (工作台)
接入 workflow-engine-java SDK
本文档的集成方"] - OMC1["SPN Domain Agent
(粤东 OMC, 华为)"] - OMC2["SPN Domain Agent
(粤西 OMC, 华为)"] + OMC1["SPN Domain Agent
(城市1 OMC)"] + OMC2["SPN Domain Agent
(城市2 OMC)"] - WAIMO -->|"A2A-T Task-T 下发原始诊断任务"| WB + UPPER -->|"A2A-T Task-T 下发原始诊断任务"| WB WB -->|"A2A-T 下发诊断"| OMC1 WB -->|"A2A-T 下发诊断"| OMC2 ``` -工作台是编排方。它接收 WAIMO 故障中心通过 A2A-T 下发的原始诊断任务,编排下游多地市 SPN Domain Agent (华为 OMC) 执行故障根因诊断,汇总结果并上报。 +工作台是编排方。它接收 上层故障系统通过 A2A-T 下发的原始诊断任务,编排下游多地市 SPN Domain Agent (OMC) 执行故障根因诊断,汇总结果并上报。 ### 1.2 四类 A2A-T 交互 @@ -70,7 +70,7 @@ graph LR | 组件 | 工作台实现 | SDK 提供 | 说明 | |------|-----------|---------|------| -| `AgentExecutor` | 是 | 否 | 工作台的 A2A 服务端入口,接收 WAIMO 下发的任务 | +| `AgentExecutor` | 是 | 否 | 工作台的 A2A 服务端入口,接收 上层系统 下发的任务 | | `ControlPoint` | 是 (4 个方法) | 接口 + 默认实现 | 工作流决策: 任务下发、自处理、路由、协商 | | `AuthProvider` | 是 (可选) | 接口 | 自定义认证头注入 (企业 SSO 等),与 credentials.json 二选一或组合 | | `WorkbenchOrchestrator` | 是 | 否 | 组装编排管线的业务类 | @@ -113,7 +113,7 @@ Spring Boot starter 会自动注册 `AgentCard`、`RequestHandler`、`RestHandle #### 2.1 AgentCard (工作台自身的) -工作台作为 A2A 服务端,需要声明自己的 AgentCard。该文件告知 WAIMO 故障中心如何调用工作台: +工作台作为 A2A 服务端,需要声明自己的 AgentCard。该文件告知 上层故障系统如何调用工作台: ```json { @@ -138,7 +138,7 @@ Spring Boot starter 会自动注册 `AgentCard`、`RequestHandler`、`RestHandle } ``` -下游 SPN Domain Agent 的 AgentCard 由华为提供或从注册中心获取。工作台只需加载它们用于 SDK 通信。关键信息是 `name` (SDK 中用此名称寻址) 和 `supportedInterfaces.url` (通信地址)。 +下游 SPN Domain Agent 的 AgentCard 由厂商提供或从注册中心获取。工作台只需加载它们用于 SDK 通信。关键信息是 `name` (SDK 中用此名称寻址) 和 `supportedInterfaces.url` (通信地址)。 #### 2.2 认证配置 @@ -153,7 +153,7 @@ SDK 提供两层认证机制,可单独使用或组合使用: ##### 方式一: Credentials 认证 (credentials.json) -SPN Domain Agent (华为 OMC) 使用 Bearer 认证。SDK 的 `AgentAuthManager` 自动调用登录接口获取令牌并缓存刷新,工作台只需提供凭证文件: +SPN Domain Agent (OMC) 使用 Bearer 认证。SDK 的 `AgentAuthManager` 自动调用登录接口获取令牌并缓存刷新,工作台只需提供凭证文件: ```json { @@ -281,7 +281,7 @@ WorkflowEngineClientConfig config = WorkflowEngineClientConfig.builder() - AgentCard 无 `securitySchemes` 但服务端仍要求认证 - 认证机制非 A2A 标准类型 (Bearer、API Key、OAuth2) -- 令牌来自企业统一身份认证平台 (如华为 iMaster SSO) +- 令牌来自企业统一身份认证平台 (如企业 SSO) - 需要注入非标准认证头 (如 `X-Custom-Token`、`X-Request-Signature`) ##### 两种方式组合使用 @@ -315,7 +315,7 @@ SDK 通过此配置调用 A2A-T SDK 生成 Task-T 结构化提示词。如果此 ### 步骤 3: 实现 AgentExecutor -工作台作为 A2A 服务端,需要实现 `AgentExecutor` 接口。这是 WAIMO 故障中心调用工作台的入口。SDK 不提供此实现 -- 它是工作台的业务代码。 +工作台作为 A2A 服务端,需要实现 `AgentExecutor` 接口。这是 上层故障系统调用工作台的入口。SDK 不提供此实现 -- 它是工作台的业务代码。 `AgentExecutor` 来自 A2A Java SDK (`org.a2aproject.sdk.server.agentexecution.AgentExecutor`)。工作台实现 `execute` 方法接收上层任务,实现 `cancel` 方法处理取消。 @@ -352,7 +352,7 @@ public class TransportWorkbenchExecutor implements AgentExecutor { String contextId = ctx.getContextId(); String input = extractText(ctx.getMessage()); - // 1. 向 WAIMO 回报任务已接收 (A2A 状态消息) + // 1. 向 上层系统 回报任务已接收 (A2A 状态消息) emitter.submit(buildStatusMessage(contextId, taskId, "任务已接收")); emitter.startWork(buildStatusMessage(contextId, taskId, "正在处理")); @@ -397,7 +397,7 @@ public class TransportWorkbenchExecutor implements AgentExecutor { } ``` -`AgentEmitter` 的调用时序: `submit` (已接收) -> `startWork` (处理中) -> `addArtifact` (结果) -> `complete` (完成)。这一时序是 A2A 协议的标准消息交互,WAIMO 故障中心据此感知任务进度。 +`AgentEmitter` 的调用时序: `submit` (已接收) -> `startWork` (处理中) -> `addArtifact` (结果) -> `complete` (完成)。这一时序是 A2A 协议的标准消息交互,上层故障系统据此感知任务进度。 如果使用 Spring Boot starter,只需将此类标注 `@Component`,starter 自动注册到 A2A 服务: @@ -459,7 +459,7 @@ public class WorkbenchControlPoint extends DefaultControlPoint { return switch (step) { case "diagnosis_city1" -> """ ## 任务 - SPN 专线故障诊断 - 粤东 OMC 侧 + SPN 专线故障诊断 - 城市1 OMC 侧 ## 故障参数 - 端口状态: port-7 = DOWN @@ -467,17 +467,17 @@ public class WorkbenchControlPoint extends DefaultControlPoint { - 所属单板: line-card-03 - 端口号: port-7 - 请针对粤东 OMC 侧端口故障进行诊断。"""; + 请针对城市1 OMC 侧端口故障进行诊断。"""; case "diagnosis_city2" -> """ ## 任务 - SPN 专线故障诊断 - 粤西 OMC 侧 + SPN 专线故障诊断 - 城市2 OMC 侧 ## 排查要求 - - 排查粤西 OMC 端口状态是否正常 + - 排查城市2 OMC 端口状态是否正常 - 确认光功率是否在正常范围 - 确认是否存在异常告警 - 请针对粤西 OMC 侧进行排查。"""; + 请针对城市2 OMC 侧进行排查。"""; default -> "请执行 SPN 专线故障诊断任务。"; }; } @@ -495,7 +495,7 @@ public class WorkbenchControlPoint extends DefaultControlPoint { public CompletableFuture onSelfTask(TaskRequest request) { String message = request.getMessage(); // 工作台本地汇总逻辑 (可调用 LLM 做故障定位结论) - String fallback = "汇总分析完成。故障定位: 粤东地市 OMC,端口 Down,光功率 -28dBm 低于阈值。"; + String fallback = "汇总分析完成。故障定位: 城市1 OMC,端口 Down,光功率 -28dBm 低于阈值。"; String sys = "你是 SPN 跨城故障协同诊断汇总专家。根据两地市 OMC 诊断结果,输出故障定位结论。"; String result = LlmHelper.text(a2atEnvPath, sys, message, fallback); return CompletableFuture.completedFuture( @@ -548,8 +548,8 @@ public CompletableFuture onNegotiation( // negotiationText: OMC 的协商请求内容 (明确指出缺失/错误的参数及修正建议) // 返回: 工作台补全或修正后的澄清文本 - String clarification = "客户 A 粤东-粤西间 SPN 专线中断," - + "粤东 OMC 告警端口 Down,光功率 -28dBm。" + String clarification = "城市1-城市2间 SPN 专线中断," + + "城市1 OMC 告警端口 Down,光功率 -28dBm。" + "请根据此上下文修正参数后重新执行诊断。"; return CompletableFuture.completedFuture(clarification); } @@ -743,7 +743,7 @@ private EventCallback createLogCallback() { ## 4. 完整调用时序 -以下是工作台收到 WAIMO 下发诊断任务后的完整端到端时序。 +以下是工作台收到 上层系统 下发诊断任务后的完整端到端时序。 ### 4.1 关键设计: 预定位与工作流执行分离 @@ -762,16 +762,16 @@ SDK 提供两个独立的门面 (facade),职责隔离: ```mermaid sequenceDiagram - participant WAIMO as WAIMO 故障中心 + participant UPPER as 上层故障系统 participant WB as 工作台 (WorkbenchOrchestrator) participant ES as ExtensionSender (SDK 预定位门面) participant EP as ExecutePsop (SDK 工作流运行器) participant EC as WorkflowEngineClient (SDK 工作流发送门面) - participant OMC as OMC (华为) + participant OMC as OMC - WAIMO->>WB: A2A-T Task-T (原始诊断任务) - WB-->>WAIMO: submit("任务已接收") - WB-->>WAIMO: startWork("处理中") + UPPER->>WB: A2A-T Task-T (原始诊断任务) + WB-->>UPPER: submit("任务已接收") + WB-->>UPPER: startWork("处理中") rect rgba(245, 245, 245, 1) Note over WB: 工作台编排: 初始化 @@ -831,8 +831,8 @@ sequenceDiagram EP-->>WB: ExecutionResult end - WB-->>WAIMO: addArtifact(诊断汇总结果) - WB-->>WAIMO: complete("完成") + WB-->>UPPER: addArtifact(诊断汇总结果) + WB-->>UPPER: complete("完成") rect rgba(240, 255, 240, 1) Note over ES,OMC: 后续: OMC 自动抢通并通过已建立的 SSE 通道上报 @@ -956,8 +956,8 @@ SDK 的 `WorkflowExecutor` 自动并行调度同一层的步骤 (无依赖关系 | 接口 | 方法 | 签名 (Java) | 何时调用 | |------|------|-------------|---------| -| `AgentExecutor` | `execute` | `void execute(RequestContext ctx, AgentEmitter emitter)` | WAIMO 下发任务时 | -| `AgentExecutor` | `cancel` | `void cancel(RequestContext ctx, AgentEmitter emitter)` | WAIMO 取消任务时 | +| `AgentExecutor` | `execute` | `void execute(RequestContext ctx, AgentEmitter emitter)` | 上层系统 下发任务时 | +| `AgentExecutor` | `cancel` | `void cancel(RequestContext ctx, AgentEmitter emitter)` | 上层系统 取消任务时 | | `ControlPoint` | `onTask` | `CompletableFuture onTask(TaskRequest, WorkflowEngineClient)` | 步骤需要向下游发任务 | | `ControlPoint` | `onSelfTask` | `CompletableFuture onSelfTask(TaskRequest)` | 自环节点本地处理 | | `ControlPoint` | `onRoute` | `CompletableFuture onRoute(String, Map, List)` | 条件分支选择 | @@ -985,9 +985,9 @@ SDK 的 `WorkflowExecutor` 自动并行调度同一层的步骤 (无依赖关系 | 维度 | Demo (samples) | 生产环境 | |------|----------------|---------| -| AgentExecutor | 模拟实现,返回固定文本 | 对接真实 WAIMO 故障中心,需完整 A2A 消息时序 | -| OMC Agent | 模拟 Agent,预置响应 | 华为真实 SPN Domain Agent,Bearer 认证、真实诊断逻辑 | -| AgentCard | 从 classpath 加载 JSON | 从注册中心获取或华为提供 | +| AgentExecutor | 模拟实现,返回固定文本 | 对接真实 上层故障系统,需完整 A2A 消息时序 | +| OMC Agent | 模拟 Agent,预置响应 | 真实 SPN Domain Agent,Bearer 认证、真实诊断逻辑 | +| AgentCard | 从 classpath 加载 JSON | 从注册中心获取或厂商提供 | | 认证 | credentials.json 明文密码 | 加密存储 (enc: 前缀) 或自定义 AuthProvider (企业 SSO) | | TLS | sslVerify=false | 生产证书校验 | | PSOP | fallback 固定 ID | 编排中心语义搜索 + 动态加载 | diff --git a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/NegotiationStrategy.java b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/NegotiationStrategy.java index e8adbf52..0cfa4f52 100644 --- a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/NegotiationStrategy.java +++ b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/NegotiationStrategy.java @@ -58,11 +58,11 @@ public NegotiationStrategy(String a2atEnvPath) { public CompletableFuture resolve( String agentName, String negotiationText, Map receiveResult) { log.info("[NegotiationStrategy] agent={}: {}", agentName, negotiationText); - String fallback = "根据工作台上下文,客户A粤东-粤西间SPN专线中断," + "粤东OMC告警端口Down,光功率-28dBm。"; + String fallback = "根据工作台上下文,客户A城市1-城市2间SPN专线中断," + "城市1OMC告警端口Down,光功率-28dBm。"; String sys = "你是SPN跨城专线故障工作台的协商澄清专家。根据协商请求," - + "补充客户A粤东-粤西间SPN专线中断的上下文" - + "(粤东OMC告警端口Down、光功率-28dBm)。中文。"; + + "补充客户A城市1-城市2间SPN专线中断的上下文" + + "(城市1OMC告警端口Down、光功率-28dBm)。中文。"; String clarification = LlmHelper.text(a2atEnvPath, sys, negotiationText, fallback); return CompletableFuture.completedFuture(clarification); } diff --git a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity1Executor.java b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity1Executor.java index 22dcd1de..cebb38ff 100644 --- a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity1Executor.java +++ b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity1Executor.java @@ -29,11 +29,11 @@ import java.util.Map; /** - * SPN Domain Agent for City1 (Eastern Guangdong / Yuedong OMC). + * SPN Domain Agent for City1 (City1 OMC). * *

Server-side negotiation-capable (extends {@link NegotiationBaseAgentExecutor}): on a new task * it replies INPUT_REQUIRED to start a Negotiation-T round, and on the follow-up it runs the - * diagnosis/recovery business. Yuedong side has a FAULT (port Down, optical power -28dBm). + * diagnosis/recovery business. City1 side has a FAULT (port Down, optical power -28dBm). * Diagnosis/recovery text is LLM-generated (deepseek) when the A2A-T .env is configured, else * deterministic. Authorization-T and Notification-T are pre-positioned before the workflow starts, * so this agent no longer injects them in response metadata. @@ -42,22 +42,22 @@ public class SpnDomainAgentCity1Executor extends NegotiationBaseAgentExecutor { private static final Logger log = LoggerFactory.getLogger(SpnDomainAgentCity1Executor.class); private static final String FAULT_DIAGNOSIS_RESULT = - "诊断结果:粤东城市OMC诊断结果 - 端口Down,光功率-28dBm(低于阈值),存在故障。\n" - + "修复方案:更换粤东OMC端口光模块,恢复端口Down状态。此修复方案需授权后执行(授权已预置)。\n" - + "故障根因:粤东OMC端口光模块故障。"; + "诊断结果:城市1城市OMC诊断结果 - 端口Down,光功率-28dBm(低于阈值),存在故障。\n" + + "修复方案:更换城市1OMC端口光模块,恢复端口Down状态。此修复方案需授权后执行(授权已预置)。\n" + + "故障根因:城市1OMC端口光模块故障。"; - private static final String RECOVERY_RESULT = "粤东OMC端口光模块已更换,端口恢复Up,专线业务恢复正常。"; + private static final String RECOVERY_RESULT = "城市1OMC端口光模块已更换,端口恢复Up,专线业务恢复正常。"; private static String llmDiagnosisResult(String input, String fallback) { String env = EnvResolver.resolveEnvPath(); - String sys = "你是SPN领域粤东OMC故障诊断专家。根据输入诊断信息,输出诊断结果、修复方案和故障根因,提及粤东。简洁专业,中文。"; - String user = "输入:\n" + input + "\n\n已知:粤东OMC端口port-7=DOWN,光功率-28dBm(阈值-20dBm)。请输出诊断结论。"; + String sys = "你是SPN领域城市1OMC故障诊断专家。根据输入诊断信息,输出诊断结果、修复方案和故障根因,提及城市1。简洁专业,中文。"; + String user = "输入:\n" + input + "\n\n已知:城市1OMC端口port-7=DOWN,光功率-28dBm(阈值-20dBm)。请输出诊断结论。"; return LlmHelper.text(env, sys, user, fallback); } private static String llmRecoveryResult(String input, String fallback) { String env = EnvResolver.resolveEnvPath(); - String sys = "你是SPN领域粤东OMC抢通执行专家。用一句话报告抢通成功结果,提及粤东OMC端口恢复Up、专线业务恢复。中文。"; + String sys = "你是SPN领域城市1OMC抢通执行专家。用一句话报告抢通成功结果,提及城市1OMC端口恢复Up、专线业务恢复。中文。"; String user = "输入:\n" + input + "\n\n已更换光模块,端口恢复Up。请输出抢通结果。"; return LlmHelper.text(env, sys, user, fallback); } @@ -117,7 +117,7 @@ private String selfTriggerRecovery(RequestContext ctx, String diagnosisResult) { @Override protected String defaultNegotiationText() { - return "粤东OMC诊断需要确认客户专线故障的详细端口信息后再执行,请补充。"; + return "城市1OMC诊断需要确认客户专线故障的详细端口信息后再执行,请补充。"; } @Override diff --git a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity2Executor.java b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity2Executor.java index c93b7d44..5eecf2c8 100644 --- a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity2Executor.java +++ b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/SpnDomainAgentCity2Executor.java @@ -29,9 +29,9 @@ import java.util.Map; /** - * SPN Domain Agent for City2 (Western Guangdong / Yuexi OMC). + * SPN Domain Agent for City2 (City2 OMC). * - *

Server-side negotiation-capable (extends {@link NegotiationBaseAgentExecutor}). Yuexi side is + *

Server-side negotiation-capable (extends {@link NegotiationBaseAgentExecutor}). City2 side is * NORMAL. Diagnosis/recovery text is LLM-generated when the A2A-T .env is configured, else * deterministic. Authorization-T and Notification-T are pre-positioned before the workflow starts. */ @@ -39,17 +39,17 @@ public class SpnDomainAgentCity2Executor extends NegotiationBaseAgentExecutor { private static final Logger log = LoggerFactory.getLogger(SpnDomainAgentCity2Executor.class); private static final String NORMAL_DIAGNOSIS_RESULT = - "诊断结果:粤西城市OMC诊断结果 - 端口状态正常,光功率-17dBm(正常范围),无异常告警。\n" - + "修复建议:粤西城市无需修复,故障不在此地市。\n" + "诊断结果:城市2城市OMC诊断结果 - 端口状态正常,光功率-17dBm(正常范围),无异常告警。\n" + + "修复建议:城市2城市无需修复,故障不在此地市。\n" + "故障根因:无根因(此地市正常)。"; - private static final String RECOVERY_RESULT = "粤西侧OMC抢通完成,业务恢复正常。"; + private static final String RECOVERY_RESULT = "城市2侧OMC抢通完成,业务恢复正常。"; private static String llmDiagnosisResult(String input, String fallback) { String env = EnvResolver.resolveEnvPath(); String sys = - "你是SPN领域粤西OMC故障诊断专家。根据输入诊断信息,粤西侧端口正常、光功率-17dBm(正常范围)、无异常告警。输出诊断结果:粤西无需修复、故障不在此地市。简洁专业,中文。"; - String user = "输入:\n" + input + "\n\n粤西OMC端口port-3=UP,光功率-17dBm,无告警。请输出诊断结论。"; + "你是SPN领域城市2OMC故障诊断专家。根据输入诊断信息,城市2侧端口正常、光功率-17dBm(正常范围)、无异常告警。输出诊断结果:城市2无需修复、故障不在此地市。简洁专业,中文。"; + String user = "输入:\n" + input + "\n\n城市2OMC端口port-3=UP,光功率-17dBm,无告警。请输出诊断结论。"; return LlmHelper.text(env, sys, user, fallback); } @@ -70,13 +70,13 @@ protected String resolveEnvPath() { protected String executeBusiness(RequestContext ctx, AgentEmitter emitter, String input) { String result = llmDiagnosisResult(input, NORMAL_DIAGNOSIS_RESULT); log.info( - "[SPN-Domain-Agent-City2] Diagnosis complete (Yuexi), no fault, no recovery needed"); + "[SPN-Domain-Agent-City2] Diagnosis complete (City2), no fault, no recovery needed"); return result; } @Override protected String defaultNegotiationText() { - return "粤西OMC诊断需要确认客户专线故障是否涉及粤西侧端口,请补充。"; + return "城市2OMC诊断需要确认客户专线故障是否涉及城市2侧端口,请补充。"; } @Override diff --git a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/WorkbenchControlPoint.java b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/WorkbenchControlPoint.java index 86f09875..49a5b5a4 100644 --- a/samples/src/main/java/dev/openan/workflow/engine/examples/agents/WorkbenchControlPoint.java +++ b/samples/src/main/java/dev/openan/workflow/engine/examples/agents/WorkbenchControlPoint.java @@ -67,17 +67,17 @@ public WorkbenchControlPoint(String a2atEnvPath, NegotiationStrategy negotiation } private static String analyzeFaultLocation(String messageText) { - boolean hasYuedongFault = - messageText.contains("粤东") + boolean hasCity1Fault = + messageText.contains("城市1") && (messageText.contains("故障") || messageText.contains("Down")); - boolean hasYuexiFault = - messageText.contains("粤西") + boolean hasCity2Fault = + messageText.contains("城市2") && (messageText.contains("故障") || messageText.contains("Down")); - if (hasYuedongFault) { - return "汇总分析完成。故障定位:粤东地市OMC,端口Down,光功率-28dBm低于阈值。"; + if (hasCity1Fault) { + return "汇总分析完成。故障定位:城市1地市OMC,端口Down,光功率-28dBm低于阈值。"; } - if (hasYuexiFault) { - return "汇总分析完成。故障定位:粤西地市OMC,需排查。"; + if (hasCity2Fault) { + return "汇总分析完成。故障定位:城市2地市OMC,需排查。"; } return "汇总分析完成。两地市均未见异常。"; } @@ -99,7 +99,7 @@ private static String buildCity1Task() { return """ ## 任务 -SPN专线故障诊断 - 粤东OMC侧 +SPN专线故障诊断 - 城市1OMC侧 ## 故障参数 - 端口状态:port-7 = DOWN @@ -107,7 +107,7 @@ private static String buildCity1Task() { - 所属单板:line-card-03 - 端口号:port-7 -请针对粤东OMC侧端口故障进行诊断。请用中文回复。""" +请针对城市1OMC侧端口故障进行诊断。请用中文回复。""" .stripIndent(); } @@ -115,14 +115,14 @@ private static String buildCity2Task() { return """ ## 任务 -SPN专线故障诊断 - 粤西OMC侧 +SPN专线故障诊断 - 城市2OMC侧 ## 排查要求 -- 排查粤西OMC端口状态是否正常 +- 排查城市2OMC端口状态是否正常 - 确认光功率是否在正常范围 - 确认是否存在异常告警 -请针对粤西OMC侧进行排查。请用中文回复。""" +请针对城市2OMC侧进行排查。请用中文回复。""" .stripIndent(); } diff --git a/samples/src/main/java/dev/openan/workflow/engine/examples/embedded/SpnCrossCityDiagnosisDemo.java b/samples/src/main/java/dev/openan/workflow/engine/examples/embedded/SpnCrossCityDiagnosisDemo.java index 840b1f15..5cdc8748 100644 --- a/samples/src/main/java/dev/openan/workflow/engine/examples/embedded/SpnCrossCityDiagnosisDemo.java +++ b/samples/src/main/java/dev/openan/workflow/engine/examples/embedded/SpnCrossCityDiagnosisDemo.java @@ -49,8 +49,8 @@ * *

    *
  • Transport Workbench Agent (port 26337) - orchestrator + merge - *
  • SPN Domain Agent City1 (port 26335) - Yuedong OMC, has fault - *
  • SPN Domain Agent City2 (port 26336) - Yuexi OMC, normal + *
  • SPN Domain Agent City1 (port 26335) - City1 OMC, has fault + *
  • SPN Domain Agent City2 (port 26336) - City2 OMC, normal *
*/ public class SpnCrossCityDiagnosisDemo { @@ -74,7 +74,7 @@ public static void main(String[] args) throws Exception { TimeUnit.SECONDS.sleep(AGENT_STARTUP_WAIT_SECONDS); log.info("=== Step 2: Send Task-T to Workbench Agent ==="); - String taskText = "SPN跨城专线故障诊断:" + "客户A粤东-粤西间SPN专线中断," + "请协同两地市OMC并行诊断," + "汇总分析确定故障在哪个地市"; + String taskText = "SPN跨城专线故障诊断:" + "客户A城市1-城市2间SPN专线中断," + "请协同两地市OMC并行诊断," + "汇总分析确定故障在哪个地市"; log.info("Sending task: {}", taskText); String response = sendTaskToWorkbench(taskText); log.info("=== Workbench Agent Response ==="); diff --git a/samples/src/main/resources/agentcard/spn_domain_agent_city1.json b/samples/src/main/resources/agentcard/spn_domain_agent_city1.json index 7547ad44..412a171f 100644 --- a/samples/src/main/resources/agentcard/spn_domain_agent_city1.json +++ b/samples/src/main/resources/agentcard/spn_domain_agent_city1.json @@ -1,8 +1,8 @@ { "name": "SPN Domain Agent City1", - "description": "SPN Domain Agent City1 - Yuedong OMC, private-line fault diagnosis with Bearer auth", + "description": "SPN Domain Agent City1 - OMC, private-line fault diagnosis with Bearer auth", "provider": { - "organization": "Huawei", + "organization": "OpenAN", "url": "https://www.huawei.com" }, "version": "1.0.0", diff --git a/samples/src/main/resources/agentcard/spn_domain_agent_city2.json b/samples/src/main/resources/agentcard/spn_domain_agent_city2.json index bd177f4a..b83dc3b9 100644 --- a/samples/src/main/resources/agentcard/spn_domain_agent_city2.json +++ b/samples/src/main/resources/agentcard/spn_domain_agent_city2.json @@ -1,8 +1,8 @@ { "name": "SPN Domain Agent City2", - "description": "SPN Domain Agent for City2 - Yuexi OMC, private-line fault diagnosis with Bearer auth", + "description": "SPN Domain Agent City2 - OMC, private-line fault diagnosis with Bearer auth", "provider": { - "organization": "Huawei", + "organization": "OpenAN", "url": "https://www.huawei.com" }, "version": "1.0.0", diff --git a/samples/src/main/resources/agentcard/transport_workbench_agent.json b/samples/src/main/resources/agentcard/transport_workbench_agent.json index 22e2fab5..6ca5b163 100644 --- a/samples/src/main/resources/agentcard/transport_workbench_agent.json +++ b/samples/src/main/resources/agentcard/transport_workbench_agent.json @@ -2,7 +2,7 @@ "name": "Transport Workbench Agent", "description": "负责向不同地市的SPN故障处理Agent下发专线故障诊断指令,并汇总分析诊断结果,生成报告。", "provider": { - "organization": "Huawei", + "organization": "OpenAN", "url": "" }, "version": "1.0.0", diff --git a/samples/src/test/java/dev/openan/workflow/engine/examples/EmbeddedA2AServerTest.java b/samples/src/test/java/dev/openan/workflow/engine/examples/EmbeddedA2AServerTest.java index 5f5ef5c7..e063af1b 100644 --- a/samples/src/test/java/dev/openan/workflow/engine/examples/EmbeddedA2AServerTest.java +++ b/samples/src/test/java/dev/openan/workflow/engine/examples/EmbeddedA2AServerTest.java @@ -176,7 +176,7 @@ void testSendMessage() throws Exception { String taskMeta = extractExtensionValue(result, "Task-T"); assertNotNull(taskMeta, "Task-T metadata should be present in response"); assertTrue( - taskMeta.contains("粤东"), - "Diagnosis metadata should mention Yuedong, got: " + taskMeta); + taskMeta.contains("城市1"), + "Diagnosis metadata should mention City1, got: " + taskMeta); } } diff --git a/samples/src/test/java/dev/openan/workflow/engine/examples/SpnCrossCityE2ETest.java b/samples/src/test/java/dev/openan/workflow/engine/examples/SpnCrossCityE2ETest.java index cb4a8a47..a2af84c5 100644 --- a/samples/src/test/java/dev/openan/workflow/engine/examples/SpnCrossCityE2ETest.java +++ b/samples/src/test/java/dev/openan/workflow/engine/examples/SpnCrossCityE2ETest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2026 Huawei Technologies Co., Ltd. + * All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + package dev.openan.workflow.engine.examples; import static org.junit.jupiter.api.Assertions.*; @@ -254,6 +261,6 @@ public void onEvent(String type, Map data) { Map mergeOut = result.getStepOutputs().get("merge_analysis"); assertNotNull(mergeOut, "merge_analysis output must exist"); String mergeText = String.valueOf(mergeOut.values().iterator().next()); - assertTrue(mergeText.contains("粤东"), "Merge must locate fault in Yuedong: " + mergeText); + assertTrue(mergeText.contains("城市1"), "Merge must locate fault in City1: " + mergeText); } }