Skip to content

feat: add conformance workflow and compatibility fixes#387

Merged
liujuanjuan1984 merged 4 commits intomainfrom
chore/370-a2a-conformance-evaluation
Apr 3, 2026
Merged

feat: add conformance workflow and compatibility fixes#387
liujuanjuan1984 merged 4 commits intomainfrom
chore/370-a2a-conformance-evaluation

Conversation

@liujuanjuan1984
Copy link
Copy Markdown
Collaborator

概述

  • 增加独立的 A2A conformance 实验入口,与 ./scripts/doctor.sh 主回归流程分离
  • 补充首轮 conformance triage 文档,并将诊断结论沉淀到仓库
  • 修复评估过程中识别出的两个仓库侧 gap:A2A-Version: 1.0 下的 PascalCase JSON-RPC alias 兼容,以及 GET /v1/tasks 返回 500 NotImplementedError

模块变更

1. Conformance 实验入口与文档

  • 新增 scripts/conformance.sh,用于本地/手动运行官方 a2aproject/a2a-tck
  • 新增 docs/conformance.md,说明实验入口、环境变量、产物与解释方式
  • 新增 docs/conformance-triage.md,沉淀首轮 failed/error 的逐条归因
  • 更新 CONTRIBUTING.mdscripts/README.md,明确 conformance 入口与 doctor.sh 的职责边界

2. JSON-RPC 兼容补丁

  • A2A-Version: 1.0 下,对 PascalCase JSON-RPC 方法名做归一化处理
  • 当前覆盖 SendMessageSendStreamingMessageGetTaskCancelTaskGetExtendedAgentCard 以及 push notification config 相关 alias
  • 保持 0.3 基线行为不变,未声明 1.0 时不放宽这些 alias

3. REST /v1/tasks 修复

  • 接管 /v1/tasks REST 路由,避免落到 SDK 默认 RESTHandler.list_tasks()NotImplementedError
  • 新增本地 task listing 实现,从当前 task store(memory / database)读取任务
  • 支持基本分页与过滤:contextIdstatusstatusTimestampAfterpageSizepageToken
  • 支持 historyLengthincludeArtifacts 控制返回载荷

4. 测试

  • 增补 JSON-RPC alias 兼容相关测试
  • 增补 /v1/tasks 分页、过滤、history/artifacts 控制、参数校验测试
  • 更新脚本健康检查测试,覆盖新增 conformance 入口

验证

  • ./scripts/doctor.sh
  • bash ./scripts/conformance.sh mandatory

结果说明

  • 本 PR 修复了两个在评估中确认的仓库侧 gap,但它们不是当前 mandatory TCK 失败面的直接主因
  • 复跑 conformance 后,失败集合与修复前一致,进一步说明当前 TCK 仍存在 0.3 / 1.0 口径混用问题
  • 仓库当前仍保持 1.0 为 partial compatibility,而不是完整 1.0 迁移

Issue 关联

Closes #370
Closes #385
Closes #386

@liujuanjuan1984
Copy link
Copy Markdown
Collaborator Author

本次独立审查结果如下。

发现

  1. 中风险:src/opencode_a2a/server/rest_tasks.py:76src/opencode_a2a/server/rest_tasks.py:101src/opencode_a2a/server/rest_tasks.py:244
    /v1/tasks 路由只在 query 解析和 task store 读取阶段捕获 _ListTasksValidationError,但对已持久化任务 status.timestamp 的解析发生在 _filter_tasks() 里,已经离开了 try 范围。也就是说,只要库里存在历史坏数据、手工修复数据或旧格式 timestamp,这条刚修好的路由仍然会因为未捕获异常退化成 500。建议把排序/过滤阶段的 timestamp 解析改成容错处理,至少把坏 timestamp 降级为最小值或忽略异常,而不是让整个列表请求失败。
  2. 中风险:src/opencode_a2a/server/rest_tasks.py:78src/opencode_a2a/server/rest_tasks.py:251
    新的 pageToken 实际上只是 base64 包装后的 offset,不是真正稳定的 cursor。两次分页请求之间如果任务列表发生插入/删除,当前实现会出现重复或遗漏,这和 1.0 ListTasks 想要的 cursor-based pagination 语义并不一致。考虑到这次目标是先修 GET /v1/tasks500,我认为“先做最小实现”是合理的,但建议在后续说明里继续强调这是 basic pagination,而不是稳定游标契约。

开放问题

  1. src/opencode_a2a/server/middleware.py:385src/opencode_a2a/server/request_parsing.py:18 已经扩展了 A2A-Version: 1.0 下的 PascalCase JSON-RPC alias 行为;但仓库文档和兼容矩阵仍把 1.0 标为 partial(src/opencode_a2a/contracts/extensions.py:1425)。如果当前产品策略是“等官方 a2a-sdk 真正支持 1.0 后再迁移”,那这一笔行为扩展是否保留,建议单独再确认一次。

PR 标题与描述

  1. 标题 feat: add conformance workflow and compatibility fixes 基本准确,覆盖了本 PR 的主线:实验入口 + 兼容性修补。
  2. 描述按模块拆分是清晰的,代码、文档、验证、结果说明都齐了,可读性没问题。
  3. Closes #370Closes #385Closes #386 目前看是准确的:本 PR 确实落了 conformance 实验入口,也修了两个在评估过程中拆出来的仓库侧 gap。

除上述两点风险与一个策略问题外,其余改动方向是合理的;尤其是把 conformance 从 doctor.sh 主回归链路中独立出来,这个边界划分是对的。

@liujuanjuan1984
Copy link
Copy Markdown
Collaborator Author

本轮已收尾此前审查中提出的两项风险:

  1. /v1/tasks 对已落库的异常 status.timestamp 不再返回 500

    • 解析存储任务时间戳时增加了容错处理
    • 遇到坏数据时记录 warning,并回退到最小时间戳参与排序
    • 保持接口可用,避免单条脏数据拖垮整个列表查询
  2. pageToken 不再是简单 offset 包装,已改为稳定 cursor

    • token 现在携带上一页最后一条任务的 id + timestamp
    • 翻页时按排序键继续向后读取,降低并发插入新任务时的重复/遗漏风险
    • 同时补了插入新任务后的分页稳定性测试

验证:

  • ./scripts/doctor.sh 通过
  • 521 passed
  • total coverage 91.09%

对应提交:6dc5515 fix: harden task listing pagination (#387)

@liujuanjuan1984 liujuanjuan1984 merged commit df55502 into main Apr 3, 2026
3 checks passed
@liujuanjuan1984 liujuanjuan1984 deleted the chore/370-a2a-conformance-evaluation branch April 3, 2026 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant