Skip to content

feat: stream chat events in AG-UI protocol - #2

Merged
sinabs merged 4 commits into
mainfrom
feat/011-sse-ag-ui
Nov 4, 2026
Merged

sinabs merged 4 commits into
mainfrom
feat/011-sse-ag-ui

Conversation

@sinabs

@sinabs sinabs commented Nov 4, 2026

Copy link
Copy Markdown
Owner

概要

01 番外:流式接口 POST /api/chat/stream 从自研 SSE 事件格式改为 AG-UI 标准协议。SSE 只是通道,事件契约交给官方 agentscope-extensions-agui(只引库,不引 starter)。

主要变更

  • 请求体改为标准 RunAgentInput(threadId 即会话 ID,runId 必填),由 AguiStreamCodec 解析校验,只采用最后一条 user 消息,丢弃客户端的 tools 等字段;适配器上设 AGENT_ONLY 再兜一层。
  • 事件由官方 AguiAgentAdapter 产生;HintEventConverter 把框架提示转成 CUSTOM name=hint,用量走 CUSTOM token_usage;没有 done 事件,全文由客户端拼接。
  • threadId 与同步接口的 sessionId 共用同一份 SafeId 规则。
  • 删除旧的 ChatEvent、EventCodec;ArchUnit 规则放行 codec/config 中的 AG-UI 类型。
  • README 中英文、.http 示例同步。
  • 版本号 1.0.0 → 1.0.1。

注意

这是对外协议的不兼容变更:旧私有事件被直接替换,没有并存。同步接口 /api/chat 的格式不变。

测试

./gradlew build 全部通过(70 个测试,0 失败)。

流式接口 POST /api/chat/stream 改用 AG-UI 标准事件,不再自定义事件格式。

- 引入 agentscope-extensions-agui 协议库(不引 agui starter:入口无认证、不关闭 Agent、绕开 threadId 校验)
- 请求体改为标准 RunAgentInput,由 AguiStreamCodec 解析校验:threadId 遵守 SafeId 规则,只采用最后一条 user 消息,丢弃 tools/context/state/forwardedProps/resume,校验失败在建流之前返回 400
- 事件由官方 AguiAgentAdapter 产生,HintEventConverter 把框架提示转成 CUSTOM hint,用量走 CUSTOM token_usage,出错只发 RUN_ERROR
- 删除自研的 ChatEvent 和 EventCodec;同步接口 /api/chat 不变
- ArchitectureTests 新增规则:AG-UI 类型只能出现在 codec 和 config
- README 中英文同步,.http 示例改为 AG-UI 请求体

这是对外协议的不兼容变更:旧的 textDelta/toolCall/done/error 事件不再存在。
- 请求体直接解析成 RunAgentInput,runId 改为必填,缺失或空白返回 400,
  去掉先转 Map 再补 runId 的字符串操作
- hint 事件的 value 改用 HintPayload record,字段名由编译器检查
- RUN_ERROR 的错误码提成 INTERNAL_ERROR_CODE 常量
- AguiStreamCodec 与 StreamRequest 用 Lombok 生成构造器
- 补充重建 RunAgentInput 的原因注释
- README、ChatApi、.http 示例和相关测试同步 runId 必填
- 最后一条 user 消息只取文本重建,消息 ID 由服务端生成:原样转交时,客户端伪造的
  toolCalls/toolCallId 会被适配器转成 ToolUseBlock 存进历史,让后续每轮模型调用失败
- messages 里有 null 元素时返回 400,不再空指针报 500
- 流式接口加 consumes=application/json:String 参数原本什么类型都收,text/plain
  不触发 CORS 预检,跨站页面可以直接发起对话;其他类型现在返回 415
- 适配器设为 ToolMergeMode.AGENT_ONLY,客户端工具即使被透传也盖不掉服务端工具
- 新增 model/SafeId,同步接口的 sessionId 与流式接口的 threadId 共用一份规则;
  空白 sessionId 仍新建会话,user:42 这类值现在返回 400
- 适配器之外的失败(创建 Agent 失败、编码失败)先补 RUN_STARTED 再发 RUN_ERROR,
  code 固定为 INTERNAL_ERROR;started 标记放进 Flux.defer,每次订阅一份
- README 中英文同步:请求规则、错误码说明、不兼容变更里补上 415 与 sessionId 校验
版本号从 1.0.0 改为 1.0.1。
@sinabs
sinabs merged commit 9af73c2 into main Nov 4, 2026
3 checks passed
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.

1 participant