Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 0 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ A2AT_PROMPT_RESOURCE_LOCAL_ROOT_DIR=

# Prompt compliance
A2AT_PROMPT_COMPLIANCE_ENABLED=false
A2AT_PROMPT_COMPLIANCE_GUARDRAIL_PROVIDER=noop

# LLM runtime
# Supported providers: openai (OpenAI-compatible APIs like DeepSeek, Azure OpenAI, etc.)
Expand All @@ -55,12 +54,3 @@ A2AT_NEGOTIATION_STATE_STORE_TYPE=in_memory
A2AT_CRED_KEY=your-32-byte-hex-key-here

# Keep true for production HTTPS. Set false only for local/self-signed integration testing.
# For LoadPsop HTTPS, false skips both server trust and hostname checks; no local CA file is needed.
# The server still needs a TLS certificate. This does not bypass mTLS or change forwarding-platform TLS.
A2A_SSL_VERIFY=false
# Comma-separated classpath:, file: URI, or absolute file locations. Leave empty for bundled cards.
# For a live OMC, point the city AgentCards at files exported by the registry center.
A2A_AGENT_CARD_LOCATIONS=
# Embedded startup validates both effective AgentCards against local network interfaces.
# Set false for an external OMC, including one running on the same host. Empty defaults to true.
A2A_EMBEDDED_OMC_ENABLED=
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
- Separate authorization/notification lifecycle from workflow outcomes; never synthesize a subscription ACK.
- Observe serialized HTTP/JSON-RPC, real gRPC metadata/protobuf and dev vendor SDK traffic with mandatory redaction and
bounded SSE.
- Add local missing-port SpringSpnDemo negotiation tests for direct and dev Order; real LLM/platform/OMC validation
remains separate.
- Add missing-input negotiation and independent transport-path regression tests; live model and production endpoint
validation remains separate.
- Refresh bilingual callback, architecture and integration contracts. No older SDK compatibility layer.

### Release hardening
Expand Down
9 changes: 5 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mvn -B clean verify
workflow-engine-sdk-java/
|-- workflow-engine/ SDK engine module
| +-- src/main/java/dev/openan/workflow/engine/
| |-- client/ A2A transport, auth, extensions (package-private internals)
| |-- client/ A2A transport, authentication, extensions, runtime APIs
| |-- control/ User-facing: ControlPoint, EventCallback, EventType
| |-- core/ Internal: WorkflowExecutor, ContextBuilder (package-private)
| |-- model/ Data models
Expand Down Expand Up @@ -137,8 +137,9 @@ Every Java file must start with the Apache 2.0 license header:

- Run the complete `mvn -B clean verify` reactor; sample failures block release.
- Documentation code snippets are compiled by DocumentedCallbackExampleTest; HostQuickStartTest executes the minimal host flow.
- Check default single-city negotiation, final serialized protocol logs, independent extension lifecycle, cancellation and secret anonymization.
- Check required-input negotiation, final serialized protocol logs, independent extension lifecycle, cancellation and secret anonymization.
- Verify published POM coordinates, sources/Javadoc artifacts and the absence of private configuration/reference documents.
- Record the tested commit and Surefire reports. Offline providers and local OMC simulators are not live acceptance.
- Live model/OMC validation requires authorized endpoints and a separate acceptance record. Never commit customer integration notes.
- Record the tested commit and Surefire reports. Offline providers and local protocol simulators are not live acceptance.
- Live model and dispatched-agent validation requires authorized endpoints and a separate acceptance record. Never
commit customer integration notes.
- Do not publish, tag, or push as a side effect of running tests.
56 changes: 22 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Java](https://img.shields.io/badge/Java-17+-orange.svg)](https://adoptium.net/)
[![Maven](https://img.shields.io/badge/Maven-3.6+-red.svg)](https://maven.apache.org/)

A standalone SDK for executing multi-agent workflows over the [A2A protocol](https://a2aproject.github.io/a2a-java/)
A Java SDK embedded in a host agent for executing multi-agent workflows over the [A2A protocol](https://a2aproject.github.io/a2a-java/)
with [A2A-T](https://projects.tmforum.org/a2aproject/telecommunication/extensions/) telecom extensions.

The engine handles workflow scheduling, A2A envelopes, transport, task waiting, authentication and TLS. Host callbacks
Expand All @@ -13,7 +13,7 @@ return final message content and own any A2A-T generation, schema, validation or
## Features

- **A2A-T Extension Support**: Task-T (structured task prompts), Negotiation-T (stateless auto negotiation loop),
Authorization-T (independent whitelist operation), Notification-T (independent long-lived SSE subscription)
Authorization-T (independent authorization operation), Notification-T (independent long-lived SSE subscription)
- **Content-neutral callbacks**: final MessageContent, complete ReceivedMessage, local multi-output TaskResult and
explicit NegotiationReply.Send/Stop
- **Minimal A2A-T dependency**: a2a-t-core only in the engine; content generation and template queries use the host's
Expand All @@ -25,25 +25,25 @@ return final message content and own any A2A-T generation, schema, validation or
- **Protocol Logging**: actual HTTP/JSON-RPC boundaries and gRPC metadata/protobuf views;
bodies default on at DEBUG with mandatory secret-field redaction

The SPN sample treats the protocol document as an input, not as executable truth. The pinned A2A-T SDK templates, slot
schemas, canonical URIs, and validation results are authoritative. Protocol generation and validation fail closed; raw
text is never sent under an A2A-T URI as a fallback.
Protocol documents are integration inputs, not executable truth. The pinned A2A-T SDK templates, slot schemas,
canonical URIs, and validation results are authoritative. Protocol generation and validation fail closed; raw text is
never sent under an A2A-T URI as a fallback.

In `SpringSpnDemo`, WAIMO sends a Task-T complaint to the integrator. The integrator loads the PSOP, dispatches two
city-specific OMC diagnoses in parallel, joins both branches exactly once, and returns the real merged result over
direct HTTP+JSON transport. Task-T, Authorization-T, and Notification-T each use an independent
transport/runtime/context. Authorization and Notification are independently triggered integrator operations rather than
DAG nodes; Notification keeps an explicit long-lived subscription until the recovery result, cancellation, or shutdown.
The SDK is embedded in a host agent. It schedules workflow tasks to dispatched agents and returns complete results to
the host callbacks. Task-T, Authorization-T, and Notification-T use independent transport/runtime/context instances.
Authorization and Notification are independently triggered host-agent operations rather than DAG nodes; a notification
subscription remains open until the host-defined terminal event, explicit cancellation, or shutdown.

## Quick Start

### 1. Add Maven dependency

A2A-T SDK `1.1.0` is published to Maven Central. Maven resolves it automatically; no SDK source checkout or local SDK
build is required. The engine depends only on
`a2a-t-core`; hosts using content generation explicitly add `a2a-t-client:1.1.0`
(and `a2a-t-server:1.1.0` for receiving-side validation). See
the [A2A-T SDK dependency guide](docs/zh/A2AT-SDK-DEPENDENCY.md) for IDEA setup and upgrade checks.
`a2a-t-core`; host agents using content generation explicitly add `a2a-t-client:1.1.0`. A dispatched-agent service that
validates received extension content adds `a2a-t-server:1.1.0`. See the bilingual
[Developer Guide](docs/en/DEVELOPER_GUIDE.md) / [开发者指南](docs/zh/DEVELOPER_GUIDE.md) for dependency and
upgrade guidance.

```xml
<dependency>
Expand Down Expand Up @@ -80,7 +80,7 @@ HostQuickStart.main(new String[] {
```

This minimal example sends plain A2A content. For Task-T, Negotiation-T, Authorization-T and Notification-T content
generation/validation in host business callbacks, follow SpringSpnDemo and the business callback guide.
generation/validation in host-agent business callbacks, follow the business callback guide.

Final content callbacks, complete dependency inputs and negotiation
Send/Stop: [English](docs/en/BUSINESS_CALLBACKS.md) / [中文](docs/zh/BUSINESS_CALLBACKS.md).
Expand Down Expand Up @@ -127,7 +127,7 @@ graph TD

| Package | Key Classes | Description |
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
| `client` | `WorkflowEngineClient`, `DefaultWorkflowEngineClient`, `ExtensionSender`, `A2ATransport`, `AuthProvider`, `AgentAuthManager`, `WorkflowEngineClientConfig`, `CredentialCrypto`, `AgentCardJacksonModule` | A2A transport, auth, extensions (package-private internals) |
| `client` | `WorkflowEngineClient`, `DefaultWorkflowEngineClient`, `ExtensionSender`, `A2ATransport`, `AuthProvider`, `WorkflowEngineClientConfig`, `CredentialCrypto`, `AgentCardJacksonModule` | Public transport, authentication, extension, and runtime APIs |
| `control` | `ControlPoint`, `DefaultControlPoint`, `EventCallback`, `EventType`, `NegotiationStrategy` | User-facing decision interfaces |
| `core` | `WorkflowExecutor`, `ContextBuilder` | DAG traversal, context assembly |
| `model` | `Workflow`, `WorkflowStep`, `Task`, `TaskRequest`, `MessageContent`, `TaskResult`, `NegotiationRequest`, `NegotiationReply`, `ExecutionResult` | Data models |
Expand All @@ -143,16 +143,17 @@ graph TD

- [Integration Guide](docs/en/INTEGRATION_GUIDE.md) - Setup, configuration, secondary development
- [API Reference](docs/en/API_REFERENCE.md) - Public interface and class documentation
- [Business Callback Contract](docs/en/BUSINESS_CALLBACKS.md) - Host-agent callback inputs, outputs, and ownership
- [Design Document](docs/en/DESIGN.md) - Architecture, module structure, design decisions
- [Developer Guide](docs/en/DEVELOPER_GUIDE.md) - Internal architecture, contribution, debugging

### 中文

- [集成指南](docs/zh/INTEGRATION_GUIDE.md) - 安装、配置、二次开发
- [API 参考](docs/zh/API_REFERENCE.md) - 公共接口和类文档
- [业务回调集成契约](docs/zh/BUSINESS_CALLBACKS.md) - 宿主智能体回调的输入、输出与职责边界
- [架构设计](docs/zh/DESIGN.md) - 架构、模块结构、设计决策
- [开发者指南](docs/zh/DEVELOPER_GUIDE.md) - 内部架构、贡献、调试
- [集成方集成指南](docs/zh/集成方场景接入指南.md) - 集成方 Spring Boot 集成完整指南

## Modules

Expand All @@ -166,22 +167,9 @@ graph TD

[Apache License 2.0](LICENSE)

### Inspect negotiation in the local Demo
## Verification

Running the local SpringSpnDemo without VM options now negotiates missing City1 input; City2 diagnoses directly. This is
a local sample scenario, not an engine default. To use complete inputs in both cities, add this IDEA **VM option**:

```text
-Da2at.samples.negotiation=false
```

By default only City1 loses its Task-T task object. Add `-Da2at.samples.negotiation.city=city2` or `both`
to exercise City2 or both cities. The host retains city-scoped authoritative input and the complaint context is
preserved. Expect DEMO_NEGOTIATION → INPUT_REQUIRED/PROPOSE → onNegotiation → ACCEPT → both diagnoses → one aggregate.
External-OMC mode defaults to no injection and rejects an explicit true switch. The Demo passes its setting into the
current Spring application context without modifying JVM-wide properties. Protocol observations are in the console and
`logs/spn-demo.log` relative to the run directory.

Run `SpringSpnDemoE2ETest` for direct transport. It tests the no-VM-option
single-city default, explicit disable/enable and both-city negotiation with current SDK resources and an offline LLM
provider. This is local protocol E2E evidence, not real model/platform/OMC validation.
Run `mvn -B clean verify` before release. The reactor verifies the engine, Spring Boot starter, callback examples,
protocol transport, negotiation, independent extension lifecycles, cancellation, error propagation, and credential
redaction. These automated tests use controlled fixtures; production endpoints, identity services, and live model
providers require a separate acceptance record.
62 changes: 31 additions & 31 deletions docs/diagrams/workflow-engine-surrounding-systems.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,50 @@ flowchart TB
classDef local fill: #F8FAFC, stroke: #64748B, color: #0F172A, stroke-dasharray: 5 3
classDef agent fill: #F5F3FF, stroke: #7C3AED, color: #2E1065, stroke-width: 1.5px

subgraph CONTROL["周边控制面与上游系统"]
subgraph CONTROL["External systems"]
direction LR
WAIMO["WAIMO<br/>上游任务发起方"]:::external
REG["注册中心 / Registry Center<br/>AgentCard 发布与查询"]:::external
ORCH["编排中心 / Orchestration Center<br/>工作流检索与 PSOP 加载"]:::external
CALLER["External A2A requester<br/>Task request and final response"]:::external
REG["Registry center<br/>AgentCard publication and discovery"]:::external
ORCH["Orchestration center<br/>Workflow search and loading"]:::external
end

subgraph HOST["宿主智能体:集成方 / Integrator Agent"]
subgraph HOST["Host agent"]
direction TB
ENTRY["A2A 服务端入口<br/>接收 Task-T,解析诊断意图"]:::host
ADAPTER["宿主集成层<br/>准备 AgentCard、Workflow、配置和业务上下文"]:::host
ENTRY["A2A server entry<br/>Receive and validate inbound tasks"]:::host
ADAPTER["Host integration layer<br/>Prepare AgentCards, Workflow, configuration and context"]:::host

subgraph ENGINE["嵌入式 Workflow Execution Engine SDK"]
subgraph ENGINE["Embedded Workflow Execution Engine SDK"]
direction TB
LOAD["发现辅助 API<br/>RegistryClient / LoadPsop"]:::sdk
RUN["工作流协议调度<br/>ExecutePsop → WorkflowExecutor<br/>Task-T + Negotiation-T"]:::sdk
CALLBACK["宿主回调接口<br/>ControlPoint / EventCallback / onFinish"]:::sdk
EXT["流程外协议操作<br/>ExtensionSender<br/>Authorization-T / Notification-T"]:::sdk
LOAD["Discovery helpers<br/>RegistryClient / LoadPsop"]:::sdk
RUN["Workflow protocol scheduling<br/>ExecutePsop → WorkflowExecutor<br/>Task-T + Negotiation-T"]:::sdk
CALLBACK["Host callbacks<br/>ControlPoint / EventCallback / onFinish"]:::sdk
EXT["Independent protocol operations<br/>ExtensionSender<br/>Authorization-T / Notification-T"]:::sdk
end

BIZ["集成方业务实现<br/>业务接管、路由、汇总、持久化、通知处理"]:::host
BIZ["Host business implementation<br/>Content, routing, aggregation, persistence and notification handling"]:::host
end

subgraph SAMPLE["Demo 本地替代路径(非生产数据源)"]
subgraph SAMPLE["Optional local fixtures (non-production)"]
direction LR
LOCALCARD["本地 AgentCard JSON<br/>WorkbenchAgentCatalog"]:::local
LOCALPSOP["本地 PSOP fallback<br/>仅用于离线演示"]:::local
LOCALCARD["Local AgentCard JSON"]:::local
LOCALPSOP["Local Workflow fixture"]:::local
end

subgraph DOWNSTREAM["下游业务智能体"]
OMCS["地市 OMC 智能体群<br/>地市 1 OMC | 地市 2 OMC"]:::agent
subgraph DOWNSTREAM["Dispatched agents"]
AGENTS["One or more dispatched agents"]:::agent
end

WAIMO <-->|" Task-T 诊断任务 / 汇总 artifact "| ENTRY
ENTRY -->|" 运行意图 "| ADAPTER
REG -->|" 生产:查询 AgentCard "| LOAD
ORCH -->|" search / load PSOP "| LOAD
LOCALCARD -.->|" Demo 替代注册中心 "| ADAPTER
LOCALPSOP -.->|" Demo 检索失败时 "| ADAPTER
LOAD -->|" 发现结果交给宿主 "| ADAPTER
CALLER <-->|"A2A request / final result"| ENTRY
ENTRY -->|"Validated intent and input"| ADAPTER
REG -->|"Discover AgentCards"| LOAD
ORCH -->|"Search / load Workflow"| LOAD
LOCALCARD -.->|"Development fixture"| ADAPTER
LOCALPSOP -.->|"Development fixture"| ADAPTER
LOAD -->|"Discovery results"| ADAPTER
ADAPTER -->|" Workflow + AgentCards "| RUN
RUN <-->|" 业务决策与执行结果 "| CALLBACK
CALLBACK <-->|" 回调 "| BIZ
ADAPTER -->|" 独立业务时机 "| EXT
RUN <-->|" 向两地市并行 Task-T<br/>必要时 Negotiation-T / 返回诊断结果 "| OMCS
EXT <-->|" Authorization-T 一次性授权<br/>Notification-T 长连接订阅与结果 SSE "| OMCS
BIZ -->|" 汇总结果 "| ENTRY
RUN <-->|"Business decisions and results"| CALLBACK
CALLBACK <-->|"Callbacks"| BIZ
ADAPTER -->|"Independent business timing"| EXT
RUN <-->|"Task-T; Negotiation-T when required"| AGENTS
EXT <-->|"Authorization-T / Notification-T"| AGENTS
BIZ -->|"Final business result"| ENTRY
Loading
Loading