{"_id":"@coco-box/ai-ag-ui-adapter","_rev":"4-8f722c3706492e0fb68a03fde0b43919","name":"@coco-box/ai-ag-ui-adapter","dist-tags":{"latest":"0.0.4"},"versions":{"0.0.1":{"name":"@coco-box/ai-ag-ui-adapter","version":"0.0.1","_id":"@coco-box/ai-ag-ui-adapter@0.0.1","maintainers":[{"name":"evelance","email":"evelancey@gmail.com"}],"dist":{"shasum":"aa1ccae78766eba9394ed075661c3b9bb80a6876","tarball":"https://registry.npmjs.org/@coco-box/ai-ag-ui-adapter/-/ai-ag-ui-adapter-0.0.1.tgz","fileCount":6,"integrity":"sha512-9by5eQ95SrVUKAbuDbnXxVxkj/HMmV8z2GkvnyyXm8SGAJVLmrmFBC63cZJle7fzO+nHv8qvDKPx3lItc6YQxA==","signatures":[{"sig":"MEUCIGcrnpzuG/9Tj/i+5lyprT1Bq+oNobXAnCvYlKLr3twzAiEA00asz9fXeTe6fYIl5CQF7YsiTII+NSekmTk5816NXnY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76764},"main":"dist/index.js","type":"module","_from":"file:coco-box-ai-ag-ui-adapter-0.0.1.tgz","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint . --ext .js,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore","test":"vitest","build":"vite build","clean":"rimraf dist","type-check":"tsc --noEmit"},"_npmUser":{"name":"evelance","email":"evelancey@gmail.com"},"_resolved":"/private/var/folders/p_/77g0gmx14x9b1kw2y8yr_lpw0000gn/T/198bf961562d27fd241b7ccc6e21e538/coco-box-ai-ag-ui-adapter-0.0.1.tgz","_integrity":"sha512-9by5eQ95SrVUKAbuDbnXxVxkj/HMmV8z2GkvnyyXm8SGAJVLmrmFBC63cZJle7fzO+nHv8qvDKPx3lItc6YQxA==","_npmVersion":"10.8.2","description":"Ag-UI 适配器：将 Ag-UI 事件与 @coco-box/ai UI 消息流对接","directories":{},"_nodeVersion":"20.19.3","dependencies":{"@ag-ui/core":"^0.0.35","@coco-box/ai":"0.0.1","@ag-ui/client":"^0.0.35"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.12","rimraf":"^5.0.5","vitest":"^1.2.2","typescript":"^5.7.3","@types/node":"^20.11.5","vite-plugin-dts":"^4.0.0"},"peerDependencies":{"@coco-box/ai":"0.0.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-ag-ui-adapter_0.0.1_1780164591116_0.12135946971354672","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@coco-box/ai-ag-ui-adapter","version":"0.0.2","_id":"@coco-box/ai-ag-ui-adapter@0.0.2","maintainers":[{"name":"evelance","email":"evelancey@gmail.com"}],"dist":{"shasum":"6b1db3833de0bf78db9a958e2fd3f7251e02f938","tarball":"https://registry.npmjs.org/@coco-box/ai-ag-ui-adapter/-/ai-ag-ui-adapter-0.0.2.tgz","fileCount":6,"integrity":"sha512-qIwcWmu8voZWYF7euB49UD3/IE5+HPEaU6xvDpPKNL82liaRq3I6OGzTyXLcflfn1UkCcgklWco194SvZRvY1w==","signatures":[{"sig":"MEQCIDhR6ijk0744i9a+iunv53sy+ROtJrIYinnRNgxsAPEYAiBVhAPhBC/pfceSMyDjeBLOGwCFFRjQ6OoObxc56Xb25w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79998},"main":"dist/index.js","type":"module","_from":"file:coco-box-ai-ag-ui-adapter-0.0.2.tgz","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint . --ext .js,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore","test":"vitest","build":"vite build","clean":"rimraf dist","type-check":"tsc --noEmit"},"_npmUser":{"name":"evelance","email":"evelancey@gmail.com"},"_resolved":"/private/var/folders/p_/77g0gmx14x9b1kw2y8yr_lpw0000gn/T/8c8e01b20176cf801e77da29d3763901/coco-box-ai-ag-ui-adapter-0.0.2.tgz","_integrity":"sha512-qIwcWmu8voZWYF7euB49UD3/IE5+HPEaU6xvDpPKNL82liaRq3I6OGzTyXLcflfn1UkCcgklWco194SvZRvY1w==","_npmVersion":"10.8.2","description":"Ag-UI 适配器：将 Ag-UI 事件与 @coco-box/ai UI 消息流对接","directories":{},"_nodeVersion":"20.19.3","dependencies":{"@ag-ui/core":"^0.0.35","@coco-box/ai":"0.0.1","@ag-ui/client":"^0.0.35"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.12","rimraf":"^5.0.5","vitest":"^1.2.2","typescript":"^5.7.3","@types/node":"^20.11.5","vite-plugin-dts":"^4.0.0"},"peerDependencies":{"@coco-box/ai":"0.0.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-ag-ui-adapter_0.0.2_1782279790356_0.3515367695287701","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@coco-box/ai-ag-ui-adapter","version":"0.0.3","_id":"@coco-box/ai-ag-ui-adapter@0.0.3","maintainers":[{"name":"evelance","email":"evelancey@gmail.com"}],"dist":{"shasum":"9cdd3181f5a5840d9be8bf371f06320168fa29f3","tarball":"https://registry.npmjs.org/@coco-box/ai-ag-ui-adapter/-/ai-ag-ui-adapter-0.0.3.tgz","fileCount":6,"integrity":"sha512-haOxGpCyr8+apPbsxy0c6grV5qjHUYAGWQ5mDrkM5q9C4kJgnPRws29ejuH/8huw7jpNmMAg2JlrCOEoK/Fzrw==","signatures":[{"sig":"MEQCIG8BsOWKLRgEevC3J2jkBWv8scLA8rl1pNFxr9FJ5w8nAiA6OR83ePQbA+/ystCx5G1w6SAUPzj+S2twKunnVSgllw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83422},"main":"dist/index.js","type":"module","_from":"file:coco-box-ai-ag-ui-adapter-0.0.3.tgz","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint . --ext .js,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore","test":"vitest","build":"vite build","clean":"rimraf dist","type-check":"tsc --noEmit"},"_npmUser":{"name":"evelance","email":"evelancey@gmail.com"},"_resolved":"/private/var/folders/p_/77g0gmx14x9b1kw2y8yr_lpw0000gn/T/1b8649c947bb927d828a6e0f821b7e6b/coco-box-ai-ag-ui-adapter-0.0.3.tgz","_integrity":"sha512-haOxGpCyr8+apPbsxy0c6grV5qjHUYAGWQ5mDrkM5q9C4kJgnPRws29ejuH/8huw7jpNmMAg2JlrCOEoK/Fzrw==","_npmVersion":"10.8.2","description":"Ag-UI 适配器：将 Ag-UI 事件与 @coco-box/ai UI 消息流对接","directories":{},"_nodeVersion":"20.19.3","dependencies":{"@ag-ui/core":"^0.0.35","@coco-box/ai":"0.0.1","@ag-ui/client":"^0.0.35"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.12","rimraf":"^5.0.5","vitest":"^1.2.2","typescript":"^5.7.3","@types/node":"^20.11.5","vite-plugin-dts":"^4.0.0"},"peerDependencies":{"@coco-box/ai":"0.0.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-ag-ui-adapter_0.0.3_1782463709133_0.24893392261728753","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"_id":"@coco-box/ai-ag-ui-adapter@0.0.4","dist":{"shasum":"ed248dafb8f21bff2761d99224609ea93072f177","tarball":"https://registry.npmjs.org/@coco-box/ai-ag-ui-adapter/-/ai-ag-ui-adapter-0.0.4.tgz","fileCount":6,"integrity":"sha512-/E+eCmMPBvKjkU7yCtMqH+gwZz0LBkZWeIb9tSrVCUCepwtzaNSzcx77/N/VqWvhBB6vkX56fnaj+EA7rYT9Bg==","signatures":[{"sig":"MEYCIQCBGqLopKOD4RDQB7+1DRXu1CaHnef1JxdzGl9eSaKLegIhAMKX2Dvz3hwO/sOCiiHnbRziBY2Y65tBBz9ctwDBD/1B","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC+WOs5JjnU1lusEILIp2/HE8XrtmrMaaGdhTRPy6EQQgIhANA3aaJkd5W1ASM+Ro8LuWle/GjDMoqvlDAkj17q+SYg"}],"unpackedSize":116246},"main":"dist/index.js","name":"@coco-box/ai-ag-ui-adapter","type":"module","_from":"file:coco-box-ai-ag-ui-adapter-0.0.4.tgz","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint . --ext .js,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore","test":"vitest","build":"vite build","clean":"rimraf dist","type-check":"tsc --noEmit"},"version":"0.0.4","_npmUser":{"name":"evelance","email":"evelancey@gmail.com"},"_resolved":"/private/var/folders/p_/77g0gmx14x9b1kw2y8yr_lpw0000gn/T/73859a521ebcb38ec23a516abeff9a4a/coco-box-ai-ag-ui-adapter-0.0.4.tgz","_integrity":"sha512-/E+eCmMPBvKjkU7yCtMqH+gwZz0LBkZWeIb9tSrVCUCepwtzaNSzcx77/N/VqWvhBB6vkX56fnaj+EA7rYT9Bg==","_npmVersion":"10.8.2","description":"Ag-UI 适配器：将 Ag-UI 事件与 @coco-box/ai UI 消息流对接","directories":{},"maintainers":[{"name":"evelance","email":"evelancey@gmail.com"}],"_nodeVersion":"20.19.3","dependencies":{"@ag-ui/core":"^0.0.35","@coco-box/ai":"0.0.1","@ag-ui/client":"^0.0.35","eventsource-parser":"^3.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.12","rimraf":"^5.0.5","vitest":"^1.2.2","typescript":"^5.7.3","@types/node":"^20.11.5","vite-plugin-dts":"^4.0.0"},"peerDependencies":{"@coco-box/ai":"0.0.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ai-ag-ui-adapter_0.0.4_1790213865727_0.861666771658611"}}},"time":{"created":"2026-05-30T18:09:50.973Z","modified":"2026-09-24T01:37:46.018Z","0.0.1":"2026-05-30T18:09:51.261Z","0.0.2":"2026-06-24T05:43:10.493Z","0.0.3":"2026-06-26T08:48:29.278Z","0.0.4":"2026-09-24T01:37:45.827Z"},"description":"Ag-UI 适配器：将 Ag-UI 事件与 @coco-box/ai UI 消息流对接","maintainers":[{"name":"evelance","email":"evelancey@gmail.com"}],"readme":"# @coco-box/ai-ag-ui-adapter\n\n将 [AG-UI](https://github.com/ag-ui-protocol/ag-ui) 协议事件适配为 `AI SDK` 的 [UI 消息流](https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message#uimessage)，便于直接接入前端 Chat 组件或自定义界面。\n\n## 特性\n\n- 支持多协议输入：标准 SSE、JSONL、WebSocket 对象事件。\n- SSE 支持 `id`、`event`、`retry`、注释、多行 `data`、CR/LF/CRLF、任意网络分片与 UTF-8 跨分片解码。\n- 可选 `transformChunk`：在消息状态机消费前替换 chunk，或返回 `null` 丢弃业务上不需要的 chunk。\n- 可选 `onUpdate`：监听经过 `transformChunk` 后保留下来的每个 `UIMessageChunk`。\n\n## 安装\n\n### 工作区（monorepo）使用\n\n```json\n\"dependencies\": {\n  \"@coco-box/ai-ag-ui-adapter\": \"workspace:*\",\n}\n```\n\n### 独立项目使用\n\n前置依赖：\n\n- `@coco-box/ai`：核心库，提供 `AbstractChat`、`Transport` 等基础功能。\n- `@coco-box/ai-vue`：Vue 组件库，提供 `Chat` 类。\n- `@coco-box/ai-vue-2`：Vue 2 组件库，提供 `Chat` 类。\n\n> 说明：`@cocobox-/ai-vue` 与 `@coco-box/ai-vue-2` 是可选依赖（二选一），根据项目使用的 Vue 版本选择安装。\n\n```bash\nnpm i @coco-box/ai @coco-box/ai-vue\n# or\nnpm i @coco-box/ai @coco-box/ai-vue-2\n```\n\n安装依赖：\n\n```bash\nnpm i @coco-box/ai-ag-ui-adapter\n```\n\n## 快速开始\n\n> 下方 `AgUiHttpTransport` 或 `AgUiWsTransport` 使用参考见文档： [AI SDK UI - Transport](https://ai-sdk.dev/docs/ai-sdk-ui/transport#transport)\n\n```ts\nimport { Chat } from '@coco-box/ai-vue-2';\nimport { AgUiHttpTransport } from '@coco-box/ai-ag-ui-adapter';\n\n// HTTP 版（SSE/HTTP 流式）\nconst chatHttp = new Chat({\n  transport: new AgUiHttpTransport({\n    api: '/api/chat',\n    transformChunk: (chunk) => {\n      // 业务层可在这里过滤服务端回显等事件；默认不做任何过滤\n      return chunk;\n    },\n    onUpdate: (chunk) => {\n      // 监听保留下来的 UI 增量\n    },\n  }),\n});\n\n// WebSocket 版（WS 文本/二进制消息）\nconst chatWs = new Chat({\n  transport: new AgUiWsTransport({\n    api: '/api/chat',\n    onUpdate: (chunk) => {\n      // UI 增量渲染或日志\n    },\n  }),\n});\n```\n\n## API 参考\n\n### 函数\n\n- `mapAgUiEventToUiChunk(event)`\n  - 作用：将单个 AG-UI 原始事件映射为 `UIMessageChunk` 或 `TextStreamPart`。\n  - 入参：`AgUIRawEvent`（见 `src/types.ts`）。\n  - 返回：`UIMessageChunk | TextStreamPart<any> | null`。\n  - 说明：处理文本、思考、工具调用与自定义 `CUSTOM` 事件（转为 `data-*`）。\n\n- `createUiChunkStreamFromAgUi(stream, options?)`\n  - 作用：将 AG-UI 原始事件流（字符串、`Uint8Array` 或对象）转换为 `ReadableStream<UIMessageChunk>`。\n  - 入参：`ReadableStream<string | Uint8Array | AgUIRawEvent>`；可选 `transformChunk`、`onUpdate`、`onStreamError`。\n  - 返回：`ReadableStream<UIMessageChunk>`。\n  - 说明：自动识别 SSE 与 JSONL 格式，逐个事件映射并输出 UI 协议分片；旧的 `(stream, onUpdate?, onStreamError?)` 调用方式继续兼容。\n\n### 类\n\n- `AgUiHttpTransport`\n  - 继承：`HttpChatTransport<UIMessage>`（来自 `@coco-box/ai`）。\n  - 初始化：在原 transport 参数上增加 `transformChunk`、`onUpdate` 和 `onResponse`。\n  - 特性：覆写 `processResponseStream`，将后端返回的原始流适配为 `UIMessageChunk` 流。\n\n- `AgUiWsTransport`\n  - 继承：`WSChatTransport<UIMessage>`（来自 `@coco-box/ai`）。\n  - 初始化：在原 transport 参数上增加 `transformChunk` 和 `onUpdate`。\n  - 特性：同上，适配 WS 原始消息到 `UIMessageChunk` 流。\n\n`transformChunk` 的执行顺序为：AG-UI 事件映射 → `transformChunk` → `onUpdate` → 消息状态机。返回 `null` 的 chunk 不会触发 `onUpdate`，也不会进入消息状态机。业务事件是否应过滤由使用方决定；适配器不会硬编码丢弃 `USER_QUERY` 等合法 AG-UI 自定义事件。\n\n## 事件映射一览\n\n- 文本：`TEXT_MESSAGE_START` → `text-start`，`TEXT_MESSAGE_CONTENT` → `text-delta`，`TEXT_MESSAGE_END` → `text-end`\n- 思考：`THINKING_TEXT_MESSAGE_START` → `reasoning-start`，`THINKING_TEXT_MESSAGE_CONTENT` → `reasoning-delta`，`THINKING_TEXT_MESSAGE_END` → `reasoning-end`\n- 工具（输入）：`TOOL_CALL_START` → `tool-input-start`，`TOOL_CALL_ARGS` → `tool-input-delta`\n- 工具（可用/结果/错误）：`TOOL_CALL_END` → `tool-input-available`，`TOOL_CALL_RESULT` → `tool-output-available` 或 `tool-output-error`\n- 自定义数据：`CUSTOM(name,value)` → `data-<name>`（小写，放入 `data` 字段）\n- 运行状态：`RUN_STARTED` → `start`，`RUN_FINISHED` → `finish`，`RUN_ERROR` → `error`\n- 快照/状态：`MESSAGES_SNAPSHOT` → `data-messages-snapshot`，`STATE_SNAPSHOT` → `data-state-snapshot`，`STATE_DELTA` → `data-state-delta`\n\n## 异常事件流处理约定\n\nAG-UI 事件流应满足协议定义的事件顺序；公司内部可以基于 AG-UI 扩展自定义事件，适配器不通过硬编码事件类型列表来穷举所有合法事件。\n\n当后端推送的数据导致 JSON 解析、事件映射、`onUpdate` 回调或 `ReadableStream` 写入失败时，适配器将按流错误处理：\n\n- SSE 注释/心跳行（例如 `: heartbeat`）以及 `event:`、`id:`、`retry:` 等控制字段按 SSE 语义解析，不会被当成 JSON 业务事件。\n- 立即让当前 `ReadableStream<UIMessageChunk>` 进入 `error` 状态，使上层 `Chat` 的 `onError` 能收到明确错误。\n- 取消上游 reader；HTTP/SSE 传输还会 abort 底层 fetch 请求，避免后端持续推送时浏览器仍继续接收数据。\n- 不对同一条异常流进行高频逐行 `console.error`，避免大量日志和堆栈输出阻塞浏览器主线程。\n- JSON 解析失败时，错误信息会携带当前异常行的截断内容，便于开发者定位后端输出问题。\n\n该兜底逻辑只保证前端不会因异常事件流进入日志风暴或半关闭状态；正确的协议顺序仍应由后端和下游 UI 消息状态机共同保证。\n","readmeFilename":"README.md"}