niceeval 0.14.2 → 0.14.3-canary.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/INDEX.md +13 -6
  2. package/dist/agents/sdk-streams.cjs +6 -1
  3. package/dist/agents/sdk-streams.cjs.map +1 -1
  4. package/dist/agents/sdk-streams.d.cts +3 -2
  5. package/dist/agents/sdk-streams.d.mts +3 -2
  6. package/dist/agents/sdk-streams.d.ts +3 -2
  7. package/dist/agents/ui-message-stream.cjs +3 -1
  8. package/dist/agents/ui-message-stream.cjs.map +1 -1
  9. package/dist/experiment/host/cli/debug-protocol.cjs +257 -0
  10. package/dist/experiment/host/cli/debug-protocol.cjs.map +1 -0
  11. package/dist/experiment/host/cli/debug-protocol.d.cts +13 -0
  12. package/dist/experiment/host/cli/debug-protocol.d.mts +13 -0
  13. package/dist/experiment/host/cli/debug-protocol.d.ts +13 -0
  14. package/dist/experiment/host/cli/debug-protocol.js +8 -0
  15. package/dist/experiment/host/cli/debug-protocol.js.map +1 -0
  16. package/dist/experiment/host/cli/session-protocol.cjs +78 -0
  17. package/dist/experiment/host/cli/session-protocol.cjs.map +1 -0
  18. package/dist/experiment/host/cli/session-protocol.d.cts +10 -0
  19. package/dist/experiment/host/cli/session-protocol.d.mts +10 -0
  20. package/dist/experiment/host/cli/session-protocol.d.ts +10 -0
  21. package/dist/experiment/host/cli/session-protocol.js +12 -0
  22. package/dist/experiment/host/cli/session-protocol.js.map +1 -0
  23. package/dist/experiment/host/index.cjs +9 -1
  24. package/dist/experiment/host/index.cjs.map +1 -1
  25. package/dist/experiment/host/index.d.cts +2 -0
  26. package/dist/experiment/host/index.d.mts +2 -0
  27. package/dist/experiment/host/index.d.ts +2 -0
  28. package/dist/experiment/host/index.js +28 -16
  29. package/dist/experiment/host/index.mjs +28 -16
  30. package/dist/run/cli/contribution.cjs +5 -5
  31. package/dist/run/cli/contribution.cjs.map +1 -1
  32. package/dist/run/host/index.cjs +14 -3
  33. package/dist/run/host/index.cjs.map +1 -1
  34. package/dist/run/host/index.d.cts +2 -2
  35. package/dist/run/host/index.d.mts +2 -2
  36. package/dist/run/host/index.d.ts +2 -2
  37. package/dist/run/host/lifecycle-adapter.cjs +12 -12
  38. package/dist/run/host/lifecycle-adapter.cjs.map +1 -1
  39. package/dist/run/host/runtime.cjs +22 -22
  40. package/dist/run/host/runtime.cjs.map +1 -1
  41. package/dist/run/host/runtime.d.cts +11 -2
  42. package/dist/run/host/runtime.d.mts +11 -2
  43. package/dist/run/host/runtime.d.ts +11 -2
  44. package/dist/run/host/runtime.js +2 -2
  45. package/dist/run/host/types.cjs.map +1 -1
  46. package/dist/run/host/types.d.cts +4 -5
  47. package/dist/run/host/types.d.mts +4 -5
  48. package/dist/run/host/types.d.ts +4 -5
  49. package/dist/runner/assert-first-bridge.cjs +78 -3
  50. package/dist/runner/assert-first-bridge.cjs.map +1 -1
  51. package/dist/runner/assert-first-bridge.d.cts +11 -1
  52. package/dist/runner/assert-first-bridge.d.mts +11 -1
  53. package/dist/runner/assert-first-bridge.d.ts +11 -1
  54. package/dist/runner/attempt.cjs +77 -67
  55. package/dist/runner/attempt.cjs.map +1 -1
  56. package/dist/sandbox/backend.cjs.map +1 -1
  57. package/dist/sandbox/backend.d.cts +2 -2
  58. package/dist/sandbox/backend.d.mts +2 -2
  59. package/dist/sandbox/backend.d.ts +2 -2
  60. package/dist/sandbox/index.cjs.map +1 -1
  61. package/dist/sandbox/index.d.cts +1 -0
  62. package/dist/sandbox/index.d.mts +1 -0
  63. package/dist/sandbox/index.d.ts +1 -0
  64. package/dist/sandbox/layer.cjs.map +1 -1
  65. package/dist/sandbox/layer.d.cts +3 -3
  66. package/dist/sandbox/layer.d.mts +3 -3
  67. package/dist/sandbox/layer.d.ts +3 -3
  68. package/dist/sandbox/runtime.cjs.map +1 -1
  69. package/dist/sandbox/types.cjs.map +1 -1
  70. package/dist/sandbox/types.d.cts +2 -0
  71. package/dist/sandbox/types.d.mts +2 -0
  72. package/dist/sandbox/types.d.ts +2 -0
  73. package/dist/show/render.cjs +1 -0
  74. package/dist/show/render.cjs.map +1 -1
  75. package/dist/terminal/blocks.cjs +3 -5
  76. package/dist/terminal/blocks.cjs.map +1 -1
  77. package/dist/view/app-dist/.vite/manifest.json +3 -76
  78. package/dist/view/app-dist/assets/index-C6GQwHEF.js +63 -0
  79. package/dist/view/app-dist/assets/{quality-cost-scatter-B5wDa_F1.js → quality-cost-scatter-CSiMLelf.js} +5 -5
  80. package/dist/view/app-dist/index.html +1 -2
  81. package/dist/view/server.cjs +4 -3
  82. package/dist/view/server.cjs.map +1 -1
  83. package/docs-site/zh/README.md +2 -2
  84. package/docs-site/zh/tutorials/agent-feedback-loop.mdx +8 -5
  85. package/docs-site/zh/tutorials/agent-onboarding.mdx +5 -3
  86. package/package.json +1 -1
  87. package/dist/view/app-dist/assets/AttemptDialog-76dX1VQq.js +0 -41
  88. package/dist/view/app-dist/assets/AttemptRoute-DRHVh2JA.js +0 -4
  89. package/dist/view/app-dist/assets/ResultsPage-9CSI8dvZ.js +0 -2
  90. package/dist/view/app-dist/assets/RunPage-BUF0REv7.js +0 -1
  91. package/dist/view/app-dist/assets/TableContentView-_Sbg5wDr.js +0 -3
  92. package/dist/view/app-dist/assets/index-BGr_6pGY.js +0 -19
  93. package/dist/view/app-dist/assets/jsx-runtime-BnHLaUks.js +0 -1
  94. package/dist/view/app-dist/assets/useSuspenseQuery-D3W8Uy33.js +0 -1
package/INDEX.md CHANGED
@@ -10,19 +10,26 @@
10
10
 
11
11
  随包文档目前只有中文。不要为了找英文版而去抓官网或 GitHub——那里的页面可能对应另一个版本,「另一个版本的英文页」比「当前版本的中文页」更危险。中文页读起来没有障碍就直接读;与用户交流仍用用户的语言。
12
12
 
13
+ ## 按任务路由
14
+
15
+ - **已有项目要运行或复验。** 先读 `docs-site/zh/tutorials/agent-feedback-loop.mdx`,再按任务从索引树补读 Authoring、接入或 Reference 页面。保留用户已经给出的范围、授权和预算;只有缺少会改变被测目标、运行边界、凭证边界或费用的决定时才提问。
16
+ - **只读诊断。** 先读 `docs-site/zh/tutorials/agent-feedback-loop.mdx`,再从索引树选择相关 Troubleshooting 或 Reference 页面。只从 `show`、`query` 或 `view` 收集公开证据;不要修改项目、重跑 Experiment、采用结果或写入 `.niceeval/`。
17
+ - **编写或修正评估。** 先读 `docs-site/zh/tutorials/authoring.mdx` 和 `docs-site/zh/tutorials/evaluation-kinds.mdx`;要连接被测对象时再读对应接入教程。评估输入必须覆盖真实业务能力,并能区分被测系统是否完成任务。
18
+ - **首次接入。** 读 `docs-site/zh/tutorials/agent-onboarding.mdx`,它拥有探索、必要决策、事件映射和生命周期的完整步骤。
19
+
13
20
  ## 帮用户跑通实验
14
21
 
15
- 1. **先确认目标和边界。** 读用户项目的 README、依赖、被测入口和现有 NiceEval 文件,确认要评什么真实用例、被测应用怎样启动、使用哪个 Agent / Sandbox / Judge,以及允许的时间和费用。不要用「你好」式占位题代替真实用例;付费模型、全量 benchmark 或批量重跑先征得用户同意。
16
- 2. **只读完成当前步骤需要的文档。** 从下面的树进入 `agent-onboarding` 或 `quickstart`,再按被测对象选择一页接入教程;需要精确字段或命令时补读一页 Reference。不要一次加载整站,也不要凭记忆发明 API。
22
+ 1. **先确认目标和边界。** 读用户项目的 README、依赖、被测入口和现有 NiceEval 文件,确认要评什么真实用例、被测应用怎样启动、使用哪个 Agent / Sandbox / Judge,以及允许的时间和费用。尊重已有授权;只有这些决定仍缺失且会影响正确性、范围或费用时才问。不要用「你好」式占位题代替真实用例;付费模型、全量 benchmark 或批量重跑先征得用户同意。
23
+ 2. **只读完成当前步骤需要的文档。** 按上方路由和下面的树选择页面;需要精确字段或命令时补读一页 Reference。不要一次加载整站,也不要凭记忆发明 API。
17
24
  3. **先建立最小闭环。** Adapter 连接真实被测入口,Experiment 明确选择评估用例与运行条件,评估用例覆盖目标产品有区分度的核心任务,不能退化成普通聊天或算术。写代码前确认四条链都能闭合:协议链从 Experiment 到目标响应,核心能力链从真实输入到业务断言,配置链从声明值到 runtime 消费方,生命周期链从启动、进程级凭证和 readiness 到失败清理。先运行 `niceeval exp list`,再用 `niceeval exp <experiment> <eval> --dry` 核对选择、模型、Attempt 数和结果沿用;生命周期或 Sandbox 不明确时用 `niceeval debug <experiment> <eval>` 查看静态计划。
18
- 4. **小范围真实运行。** 先跑一条评估用例、一个 Experiment 和足够证明链路的最小 Attempt 数;需要时给预算与并发加保护。保留完成反馈中的 `createdRunIds` `publicationCutoff`。先用 `niceeval show --run <run-id>` 在终端快速审阅;需要稳定 JSON 时,运行 `niceeval query discover`,再以 versioned request 调用 `niceeval query explain` 或 `niceeval query run`。需要浏览器连续深读时使用 `niceeval view --run <run-id>`。不要只看进程退出码。
19
- 5. **交付可复现结果。** 告诉用户新增或修改了哪些文件、实际运行了什么命令、Run ID、通过/失败/不可用状态和下一步。没有真实运行就明确说明,不把 `--dry`、typecheck 或配置发现说成实验已经跑通。
25
+ 4. **小范围真实运行。** 先跑一条评估用例、一个 Experiment 和足够证明链路的最小 Attempt 数;需要时给预算与并发加保护。保留最后 receipt 的 `createdRunIds` opaque `publicationCutoff`,并查看 `completion`。`createdRunIds` 只列出已创建的 Run;receipt 只交接这次调用,不能单独证明用户任务完成。先用 `niceeval show --run <run-id>` 在终端快速审阅;需要稳定 JSON 时,运行 `niceeval query discover`,再以 versioned request 调用 `niceeval query explain` 或 `niceeval query run`。需要浏览器连续深读时使用 `niceeval view --run <run-id>`。不要只看进程退出码。
26
+ 5. **交付可复现结果。** 在已获授权和预算内,主动修复执行链的错误并复验受影响范围。合法业务失败要保留并如实报告,不要为全绿改写应用或断言。缺少真实外部条件时,说清缺的是端口、凭证、数据库或模型服务等,并报告阻塞。告诉用户新增或修改了哪些文件、实际运行了什么命令、Run ID、通过/失败/不可用状态和下一步。没有真实运行就明确说明,不把 `--dry`、typecheck 或配置发现说成实验已经跑通。
20
27
 
21
28
  ## 发现并解决问题
22
29
 
23
30
  1. **从公开入口收集证据。** 选择问题对应的固定 Run;先用 `niceeval show --run <run-id>` 快速找到异常 Attempt,再用 `niceeval show @<locator>` 查看概览,并按提示进入 `--source`、`--execution`、`--timing`、`--usage` 或 `--diff`。需要稳定 JSON 时运行 `niceeval query discover`,再用完整 request 的 `query explain` / `query run` 读取覆盖、Verdict 和 diagnostics。需要浏览器连续深读时用 `niceeval view --run <run-id>`,再从页面导航进入详情。Attempt locator 仍是数据 identity,不是 `view` 的位置参数。不要直接读取或修改 `.niceeval/` 私有文件。
24
31
  2. **先分类,再修改。** 选择或发现错误查 `exp list` 与 `--dry`;Plugin、Sandbox、Agent、Fixture 顺序查 `debug`;基础设施和保留现场查 Troubleshooting;Judge 不可用先验证模型、密钥和端点;`failed` 只表示影响 Verdict 的断言未满足,不自动证明被测结果违背任务。`errored`、`skipped`、`not-dispatched` 与 `unavailable` 不能当成零分或普通失败。
25
- 3. **修产生错误的那一层。** 处理 `failed` 时,先比较任务允许的结果、实际产物及证据和断言条件。被测应用行为错就修应用;事件或用量映射错就修 Adapter;产物满足任务而断言拒绝了任务允许的结果,就修评估用例;Provider、凭据或生命周期错就修运行配置。不要通过任意放宽断言、伪造事件或改历史 Record 让结果变绿。
32
+ 3. **修产生错误的那一层。** 处理 `failed` 时,先比较任务允许的结果、实际产物及证据和断言条件。被测应用行为错就修应用;事件或用量映射错就修 Adapter;产物满足任务而断言拒绝了任务允许的结果,就修评估用例;Provider、凭据或生命周期错就修运行配置。已有授权和预算内主动修复执行错误并复验;只读请求不修改。不要通过任意放宽断言、伪造事件或改历史 Record 让结果变绿。
26
33
  4. **只复验受影响范围。** 修改后重复同一条精确选择命令。默认结果沿用会跳过身份仍匹配的结果;需要重验失败项用 `--rerun`,需要重验全部选中位置才用 `--rerun all`。只有在身份变化但历史证据经人工核对仍然有效时,才用 `niceeval accept` 明确发布新的采用 Run。
27
34
  5. **闭环验证。** 用新 Run ID 再次运行同一固定 Inspection request,确认分母不变、原 diagnostic 消失且没有新增错误;需要比较修复前后时,以两个明确 Run ID 构造 `runs.compare` request,或在人类审阅时交给 `view`,不要用「最新」代替实验边界。
28
35
 
@@ -33,7 +40,7 @@
33
40
  ## `docs-site/zh/tutorials/`
34
41
 
35
42
  - `docs-site/zh/tutorials/accept-results.mdx` — 审阅并采用历史 Attempt:从 --dry 取得候选 locator,核对不可变 Attempt,再用 niceeval accept 原子采用明确结果,并用新 Run ID 验证分母与来源。
36
- - `docs-site/zh/tutorials/agent-feedback-loop.mdx` — 让 Coding Agent 根据结果迭代:让 Coding Agent 读取 receipt 的 runIds,查看结果,再区分被测失败、证据错误与评估用例误判。
43
+ - `docs-site/zh/tutorials/agent-feedback-loop.mdx` — 让 Coding Agent 根据结果迭代:让 Coding Agent 读取 receipt 的 createdRunIds,查看结果,再区分被测失败、证据错误与评估用例误判。
37
44
  - `docs-site/zh/tutorials/agent-onboarding.mdx` — Coding Agent 从零接入项目:给 Coding Agent 的完整接入流程:探索项目、与用户确认路径、配置 Judge、写出 Adapter、Experiment 与评估用例,并跑通第一个实验。
38
45
  - `docs-site/zh/tutorials/authoring.mdx` — 编写评估用例: 单轮、多轮和测试集模式:用 defineEval 编写评估用例,包括单轮对话、多轮对话、数据驱动测试、Sandbox Workspace 和评估的生命周期与 Fixture。
39
46
  - `docs-site/zh/tutorials/ci-integration.mdx` — 在 CI 中运行 NiceEval:让 CI 使用退出状态判定门禁,保留最后的 receipt,并向平台提供 JUnit 文件。
@@ -410,7 +410,6 @@ function createCodexThreadEventStream() {
410
410
  events.push({ type: "thinking", text: item.text });
411
411
  }
412
412
  else if (item.type === "error" && typeof item.message === "string") {
413
- failed = true;
414
413
  events.push({ type: "error", message: item.message });
415
414
  }
416
415
  else {
@@ -438,6 +437,12 @@ function createCodexThreadEventStream() {
438
437
  }
439
438
  break;
440
439
  }
440
+ case "error": {
441
+ failed = true;
442
+ if (typeof event.message === "string")
443
+ events.push({ type: "error", message: event.message });
444
+ break;
445
+ }
441
446
  case "turn.failed": {
442
447
  failed = true;
443
448
  if (event.error?.message)
@@ -1 +1 @@
1
- {"version":3,"file":"sdk-streams.js","sourceRoot":"","sources":["sdk-streams.ts"],"names":[],"mappings":"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","sourcesContent":["// SDK 原生事件流 → 标准 StreamEvent 的官方转换器(+ 通用 SSE 读帧器)。\n//\n// 定位:各 agent SDK 的流式协议(Claude Agent SDK 的 `SDKMessage`、pi-agent-core 的\n// `AgentEvent`、Codex SDK 的 `ThreadEvent`)是 SDK 定义的通用协议,不是某个应用的私有格式——\n// 这层映射知识属于 niceeval 官方包,adapter 里只该剩传输粘合(应用把流放在哪个端点、\n// 审批走什么端点)。类型全部用结构化的 *Like 声明(同 turnFromAiSdk 的先例),不依赖任何 SDK 包。\n//\n// 用法(以 Claude Agent SDK 为例):\n//\n// ```typescript\n// import { sseJsonFrames, createClaudeSdkEventStream } from \"niceeval/adapter\";\n//\n// const frames = sseJsonFrames<SDKMessage>(res.body);\n// const stream = createClaudeSdkEventStream();\n// for (;;) {\n// const frame = await frames.next();\n// if (frame === null) break;\n// events.push(...stream.add(frame)); // 逐帧翻译;认不出的帧返回 []\n// }\n// return { status: stream.failed ? \"failed\" : \"completed\", events, usage: stream.usage };\n// ```\nimport type { CommandProjection, JsonValue, StreamEvent, ToolName, Usage } from \"../types.ts\";\nimport { normalizeToolName } from \"../o11y/tool-names.ts\";\nimport { CODEX_TOOL_ALIASES } from \"../o11y/parsers/codex.ts\";\nimport { CLAUDE_TOOL_ALIASES } from \"../o11y/parsers/claude-code.ts\";\nimport { notCommandProjection, opaqueCommandProjection } from \"../o11y/command-projection.ts\";\n// ───────────────────────── 通用 SSE 读帧器 ─────────────────────────\nexport interface SseFrameCursor<T> {\n /** 下一个 `data:` JSON 帧;流结束返回 null。`data: [DONE]` 哨兵帧自动跳过。 */\n next(): Promise<T | null>;\n}\n/** 标准 SSE(`data: {...}\\n\\n`)→ 逐帧 JSON。各 adapter 不用再手写 buffer 状态机。 */\nexport function sseJsonFrames<T>(body: ReadableStream<Uint8Array>): SseFrameCursor<T> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n async function next(): Promise<T | null> {\n for (;;) {\n const sepIndex = buffer.indexOf(\"\\n\\n\");\n if (sepIndex !== -1) {\n const rawEvent = buffer.slice(0, sepIndex);\n buffer = buffer.slice(sepIndex + 2);\n const line = rawEvent.split(\"\\n\").find((l) => l.startsWith(\"data: \"));\n if (!line)\n continue;\n const payload = line.slice(\"data: \".length);\n if (payload === \"[DONE]\")\n continue;\n return JSON.parse(payload) as T;\n }\n const { value, done } = await reader.read();\n if (done)\n return null;\n buffer += decoder.decode(value, { stream: true });\n }\n }\n return { next };\n}\nfunction isRecord(v: unknown): v is globalThis.Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n/** Claude Agent SDK 的原生 Bash tool 只交付 shell source,不交付 argv。 */\nfunction commandProjectionForClaudeSdkTool(name: string): CommandProjection | undefined {\n return name === \"Bash\" ? opaqueCommandProjection(\"unsupported-protocol\") : undefined;\n}\n// ───────────────────────── Claude Agent SDK:SDKMessage ─────────────────────────\n/** 只声明转换器要读的字段;真实的 SDKMessage 直接喂进来即可。 */\nexport interface ClaudeSdkMessageLike {\n type: string;\n subtype?: string;\n session_id?: string;\n tool_use_id?: string;\n is_error?: boolean;\n num_turns?: number;\n total_cost_usd?: number;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n cache_read_input_tokens?: number | null;\n cache_creation_input_tokens?: number | null;\n };\n message?: {\n content?: unknown;\n };\n [key: string]: unknown;\n}\nexport interface ClaudeSdkStream {\n /** 逐帧喂 `SDKMessage`,返回这一帧派生的标准事件;认不出的帧(stream_event 等)返回 []。 */\n add(message: ClaudeSdkMessageLike): StreamEvent[];\n /** `system`/`init` 帧带回的 session_id(首帧之后可读),回写 `ctx.session.id` 用。 */\n readonly sessionId: string | undefined;\n /** `result` 帧的聚合用量。 */\n readonly usage: Usage | undefined;\n /** `result` 帧报了 is_error。 */\n readonly failed: boolean;\n /**\n * 拒绝审批后续读前登记:该 tool_use 的 `tool_result` / `permission_denied` 落成\n * `status: \"rejected\"`(而不是 failed),且两种帧只产一条 operation.finished。\n */\n markRejected(toolUseId: string): void;\n}\n/**\n * Claude Agent SDK 消息流(`system` / `assistant` / `user` / `result`)→ 标准事件。\n * `assistant` 的 text/thinking/tool_use 块 → message / thinking / operation.started;`user` 的\n * tool_result 块 → operation.finished;`system`/`permission_denied` → rejected;`stream_event`\n * (逐 token 渲染)整个忽略。HITL 的停轮判定(哪个工具被门控)是应用侧的知识,不在这里——\n * 扫描 add() 返回的 operation.started 自行决定。\n */\nexport function createClaudeSdkEventStream(): ClaudeSdkStream {\n let sessionId: string | undefined;\n let usage: Usage | undefined;\n let failed = false;\n const resolvedCallIds = new Set<string>();\n const rejected = new Set<string>();\n const toolResultText = (content: unknown): string | undefined => {\n if (typeof content === \"string\")\n return content;\n if (Array.isArray(content)) {\n return content\n .filter((b): b is {\n type: \"text\";\n text: string;\n } => isRecord(b) && b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n }\n return undefined;\n };\n return {\n get sessionId() {\n return sessionId;\n },\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n markRejected(toolUseId) {\n rejected.add(toolUseId);\n },\n add(frame) {\n const events: StreamEvent[] = [];\n switch (frame.type) {\n case \"system\": {\n if (frame.subtype === \"init\" && typeof frame.session_id === \"string\") {\n sessionId ??= frame.session_id;\n }\n else if (frame.subtype === \"permission_denied\" && typeof frame.tool_use_id === \"string\") {\n if (!resolvedCallIds.has(frame.tool_use_id)) {\n resolvedCallIds.add(frame.tool_use_id);\n events.push({ type: \"operation.finished\", operationId: frame.tool_use_id, kind: \"tool\", status: \"rejected\" });\n }\n }\n break;\n }\n case \"assistant\": {\n const content: unknown[] = Array.isArray(frame.message?.content) ? frame.message.content : [];\n for (const block of content) {\n if (!isRecord(block))\n continue;\n if (block.type === \"text\" && typeof block.text === \"string\" && block.text) {\n events.push({ type: \"message\", role: \"assistant\", text: block.text });\n }\n else if (block.type === \"thinking\" && typeof block.thinking === \"string\" && block.thinking) {\n events.push({ type: \"thinking\", text: block.thinking });\n }\n else if (block.type === \"tool_use\" && typeof block.id === \"string\" && typeof block.name === \"string\") {\n const command = commandProjectionForClaudeSdkTool(block.name);\n events.push({\n type: \"operation.started\",\n operationId: block.id,\n operation: {\n kind: \"tool\",\n name: block.name,\n input: block.input as JsonValue,\n tool: normalizeToolName(block.name, CLAUDE_TOOL_ALIASES),\n ...(command === undefined ? {} : { command }),\n },\n });\n }\n }\n break;\n }\n case \"user\": {\n const content: unknown[] = Array.isArray(frame.message?.content) ? frame.message.content : [];\n for (const block of content) {\n if (!isRecord(block) || block.type !== \"tool_result\" || typeof block.tool_use_id !== \"string\")\n continue;\n if (resolvedCallIds.has(block.tool_use_id))\n continue;\n resolvedCallIds.add(block.tool_use_id);\n events.push({\n type: \"operation.finished\",\n operationId: block.tool_use_id,\n kind: \"tool\",\n output: toolResultText(block.content) as JsonValue,\n status: rejected.has(block.tool_use_id) ? \"rejected\" : block.is_error ? \"failed\" : \"completed\",\n });\n }\n break;\n }\n case \"result\": {\n failed = frame.is_error === true;\n if (frame.usage) {\n usage = {\n inputTokens: frame.usage.input_tokens,\n outputTokens: frame.usage.output_tokens,\n cacheReadTokens: frame.usage.cache_read_input_tokens ?? undefined,\n cacheCreationTokens: frame.usage.cache_creation_input_tokens ?? undefined,\n requests: frame.num_turns,\n costUSD: frame.total_cost_usd,\n };\n }\n break;\n }\n // stream_event(逐 token 渲染)与其它系统/生命周期消息:无对应 StreamEvent。\n default:\n break;\n }\n return events;\n },\n };\n}\n// ───────────────────────── pi-agent-core:AgentEvent ─────────────────────────\nexport interface PiAgentEventLike {\n type: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n result?: unknown;\n isError?: boolean;\n /** content 在 user 消息上是 string、assistant 消息上是 parts 数组——按 unknown 收,防御式解析。 */\n message?: {\n role?: string;\n content?: unknown;\n /** assistant 消息的收尾原因;\"error\" / \"aborted\" 表示这条消息以失败告终。 */\n stopReason?: string;\n /** stopReason 为 \"error\" 时的错误说明。 */\n errorMessage?: string;\n usage?: {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: {\n total: number;\n };\n };\n };\n /** `message_update` 帧携带的增量事件(text_delta / thinking_delta 等)——只读 type/delta,防御式解析。 */\n assistantMessageEvent?: {\n type?: string;\n delta?: unknown;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\nexport interface PiAgentStream {\n /** 逐帧喂 `AgentEvent`,返回这一帧派生的标准事件;生命周期帧(turn_start 等)返回 []。 */\n add(event: PiAgentEventLike): StreamEvent[];\n /** assistant `message_end` 逐条累加的用量。 */\n readonly usage: Usage | undefined;\n /** assistant 消息以 stopReason \"error\" / \"aborted\" 收尾过。 */\n readonly failed: boolean;\n /** 拒绝审批后续读前登记:该调用 `tool_execution_end` 的 isError 判成 \"rejected\" 而非 \"failed\"。 */\n markRejected(toolCallId: string): void;\n}\n/**\n * pi-agent-core 事件流(`message_start` / `message_update` / `message_end` /\n * `tool_execution_start` / `tool_execution_end`)→ 标准事件。消息三段式聚合成一条:\n * message_start 清空增量缓冲、message_update 的 text_delta / thinking_delta 逐段累加、\n * message_end 落地成 message / thinking(优先取 end 帧的完整 content,缺了用累加的增量兜底);\n * 只有 start/delta 的截断流不产出半条消息。message_end 同时累加 usage;assistant 消息以\n * stopReason \"error\" / \"aborted\" 收尾时记失败(`failed`)并发一条 error 事件。\n * tool_execution_start/end → operation.started / operation.finished。\n */\nexport function createPiAgentEventStream(): PiAgentStream {\n let usage: Usage | undefined;\n let failed = false;\n // message_start/update 累加的增量缓冲;message_end 落地后清空,截断流(无 end)不落地。\n let deltaText = \"\";\n let deltaThinking = \"\";\n const rejected = new Set<string>();\n const partText = (event: PiAgentEventLike, type: \"text\" | \"thinking\"): string => {\n if (event.message?.role !== \"assistant\" || !Array.isArray(event.message.content))\n return \"\";\n return event.message.content\n .filter((part): part is globalThis.Record<string, unknown> => isRecord(part) && part.type === type)\n .map((part) => {\n const v = type === \"text\" ? part.text : part.thinking;\n return typeof v === \"string\" ? v : \"\";\n })\n .join(\"\");\n };\n return {\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n markRejected(toolCallId) {\n rejected.add(toolCallId);\n },\n add(event) {\n const events: StreamEvent[] = [];\n switch (event.type) {\n case \"message_start\": {\n // 新消息开始:上一条没等到 message_end 的增量作废(不落地半条消息)。\n deltaText = \"\";\n deltaThinking = \"\";\n break;\n }\n case \"message_update\": {\n const e = event.assistantMessageEvent;\n if (isRecord(e) && typeof e.delta === \"string\") {\n if (e.type === \"text_delta\")\n deltaText += e.delta;\n else if (e.type === \"thinking_delta\")\n deltaThinking += e.delta;\n }\n break;\n }\n case \"message_end\": {\n // 优先取 end 帧的完整 content;缺了(部分传输只带增量)用累加的 delta 兜底。\n const text = partText(event, \"text\") || (event.message?.role === \"assistant\" ? deltaText : \"\");\n if (text)\n events.push({ type: \"message\", role: \"assistant\", text });\n const thinking = partText(event, \"thinking\") || (event.message?.role === \"assistant\" ? deltaThinking : \"\");\n if (thinking)\n events.push({ type: \"thinking\", text: thinking });\n deltaText = \"\";\n deltaThinking = \"\";\n if (event.message?.role === \"assistant\") {\n const stopReason = event.message.stopReason;\n if (stopReason === \"error\" || stopReason === \"aborted\") {\n failed = true;\n events.push({ type: \"error\", message: event.message.errorMessage ?? `pi agent stopReason=${stopReason}` });\n }\n }\n const u = event.message?.role === \"assistant\" ? event.message.usage : undefined;\n if (u) {\n // pi computes u.cost from its own model price table. That estimate\n // is not provider-observed billing and must not enter Usage.costUSD.\n usage = {\n inputTokens: (usage?.inputTokens ?? 0) + u.input,\n outputTokens: (usage?.outputTokens ?? 0) + u.output,\n cacheReadTokens: (usage?.cacheReadTokens ?? 0) + u.cacheRead,\n cacheCreationTokens: (usage?.cacheCreationTokens ?? 0) + u.cacheWrite,\n requests: (usage?.requests ?? 0) + 1,\n };\n }\n break;\n }\n case \"tool_execution_start\": {\n if (typeof event.toolCallId === \"string\" && typeof event.toolName === \"string\") {\n events.push({\n type: \"operation.started\",\n operationId: event.toolCallId,\n operation: { kind: \"tool\", name: event.toolName, input: event.args as JsonValue },\n });\n }\n break;\n }\n case \"tool_execution_end\": {\n if (typeof event.toolCallId === \"string\") {\n const status = event.isError ? (rejected.has(event.toolCallId) ? \"rejected\" : \"failed\") : \"completed\";\n events.push({ type: \"operation.finished\", operationId: event.toolCallId, kind: \"tool\", output: event.result as JsonValue, status });\n }\n break;\n }\n // agent_start / turn_start / turn_end / tool_execution_update / agent_end:\n // 无对应 StreamEvent(消息文本统一在 message_end 落地)。\n default:\n break;\n }\n return events;\n },\n };\n}\n// ───────────────────────── Codex SDK:ThreadEvent ─────────────────────────\nexport interface CodexThreadEventLike {\n type: string;\n thread_id?: string;\n item?: {\n type?: string;\n text?: string;\n message?: string;\n [key: string]: unknown;\n };\n error?: {\n message: string;\n };\n [key: string]: unknown;\n}\nexport interface CodexThreadStream {\n /**\n * 逐帧喂 `ThreadEvent`,返回标准事件:消息类(agent_message → message、reasoning → thinking、\n * error item / turn.failed → error)+ 工具项(command_execution / mcp_tool_call / web_search /\n * file_change → operation.started + operation.finished,附规范工具名 `tool`,如 command_execution →\n * `\"shell\"`,供 `calledTool(\"shell\")` 这类跨 agent 断言命中)。usage 从 `turn.completed` 聚合,经 `usage` 读。\n * 断言依据全部来自这条流;codex CLI 的原生 OTLP span 只用于瀑布图(spanMapper: mapCodexSpans)。\n */\n add(event: CodexThreadEventLike): StreamEvent[];\n /** `thread.started` 带回的 thread_id,回写 `ctx.session.id` 用。 */\n readonly threadId: string | undefined;\n /** `turn.completed` 聚合的用量(input/cached/output tokens)。 */\n readonly usage: Usage | undefined;\n /** turn.failed / error item 出现过。 */\n readonly failed: boolean;\n}\n/** Codex SDK 线程事件流(`thread.started` / `item.*` / `turn.completed` / `turn.failed`)→ 标准事件。 */\nexport function createCodexThreadEventStream(): CodexThreadStream {\n let threadId: string | undefined;\n let usage: Usage | undefined;\n let failed = false;\n // item.started 已发 operation.started 的 id;item.completed 时不重发,只补 result。\n const startedCallIds = new Set<string>();\n let synth = 0;\n const callIdOf = (item: globalThis.Record<string, unknown>, prefix: string): string => {\n const id = item.id;\n return typeof id === \"string\" || typeof id === \"number\" ? String(id) : `${prefix}_${++synth}`;\n };\n // 工具项 → operation.started(+completed 时的 operation.finished)。与 o11y/parsers/codex.ts 的\n // transcript 映射保持同一套语义(字段名以 codex exec --json 的 ThreadItem 为准),\n // 包括规范工具名 tool:少了它 derive 只能落 name=\"unknown\",calledTool(\"shell\") 这类\n // 跨 agent 规范名断言在 SDK 流路径上会静默失配(2026-07-09 CI 实红)。\n const handleToolItem = (item: globalThis.Record<string, unknown>, isCompleted: boolean): StreamEvent[] => {\n const events: StreamEvent[] = [];\n const emitCall = (callId: string, name: string, input: JsonValue, tool: ToolName, command: CommandProjection): void => {\n if (startedCallIds.has(callId))\n return;\n startedCallIds.add(callId);\n events.push({ type: \"operation.started\", operationId: callId, operation: { kind: \"tool\", name, input, tool, command } });\n };\n switch (item.type) {\n case \"command_execution\": {\n const callId = callIdOf(item, \"cmd\");\n emitCall(callId, \"command_execution\", { command: item.command ?? null } as JsonValue, \"shell\", opaqueCommandProjection(\"unsupported-protocol\"));\n if (isCompleted) {\n const exit = item.exit_code ?? item.exitCode;\n const output = item.aggregated_output ?? item.aggregatedOutput ?? item.output;\n const status = item.status === \"declined\" || item.status === \"rejected\"\n ? \"rejected\" as const\n : exit === 0 || (exit == null && item.status !== \"failed\" && item.status !== \"error\")\n ? \"completed\" as const\n : \"failed\" as const;\n events.push({\n type: \"operation.finished\",\n operationId: callId,\n kind: \"tool\",\n ...(output === undefined && exit === undefined\n ? {}\n : { output: { output: (output ?? null) as JsonValue, exit_code: (exit ?? null) as JsonValue } }),\n status,\n });\n }\n return events;\n }\n case \"mcp_tool_call\": {\n const callId = callIdOf(item, \"mcp\");\n const tool = String(item.tool ?? \"unknown\");\n const name = typeof item.server === \"string\" ? `${item.server}.${tool}` : tool;\n emitCall(callId, name, (item.arguments ?? null) as JsonValue, normalizeToolName(tool, CODEX_TOOL_ALIASES), notCommandProjection());\n if (isCompleted) {\n const success = !item.error && item.status !== \"failed\";\n events.push({\n type: \"operation.finished\",\n operationId: callId,\n kind: \"tool\",\n output: (item.result ?? null) as JsonValue,\n status: success ? \"completed\" : \"failed\",\n });\n }\n return events;\n }\n case \"web_search\": {\n const callId = callIdOf(item, \"web\");\n emitCall(callId, \"web_search\", { query: item.query ?? null } as JsonValue, \"web_search\", notCommandProjection());\n if (isCompleted) {\n events.push({ type: \"operation.finished\", operationId: callId, kind: \"tool\", output: null, status: \"completed\" });\n }\n return events;\n }\n case \"file_change\": {\n // 补丁类只在 completed 落一次:changes 里每个文件一对 called/result。\n if (!isCompleted)\n return events;\n const baseId = callIdOf(item, \"patch\");\n const changes = Array.isArray(item.changes) ? item.changes : [];\n changes.forEach((ch, i) => {\n const callId = `${baseId}#${i}`;\n const change = isRecord(ch) ? { path: ch.path ?? null, kind: ch.kind ?? null } : {};\n events.push({\n type: \"operation.started\",\n operationId: callId,\n operation: {\n kind: \"tool\",\n name: \"file_change\",\n input: change as JsonValue,\n tool: \"file_edit\",\n command: notCommandProjection(),\n },\n });\n events.push({ type: \"operation.finished\", operationId: callId, kind: \"tool\", output: change as JsonValue, status: \"completed\" });\n });\n return events;\n }\n default:\n return events;\n }\n };\n return {\n get threadId() {\n return threadId;\n },\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n add(event) {\n const events: StreamEvent[] = [];\n switch (event.type) {\n case \"thread.started\": {\n if (typeof event.thread_id === \"string\")\n threadId ??= event.thread_id;\n break;\n }\n case \"item.started\": {\n if (event.item)\n events.push(...handleToolItem(event.item, false));\n break;\n }\n case \"item.completed\": {\n const item = event.item;\n if (!item)\n break;\n if (item.type === \"agent_message\" && typeof item.text === \"string\" && item.text) {\n events.push({ type: \"message\", role: \"assistant\", text: item.text });\n }\n else if (item.type === \"reasoning\" && typeof item.text === \"string\" && item.text) {\n events.push({ type: \"thinking\", text: item.text });\n }\n else if (item.type === \"error\" && typeof item.message === \"string\") {\n failed = true;\n events.push({ type: \"error\", message: item.message });\n }\n else {\n events.push(...handleToolItem(item, true));\n }\n break;\n }\n case \"turn.completed\": {\n const u = event.usage;\n if (isRecord(u)) {\n const num = (v: unknown): number => (typeof v === \"number\" ? v : 0);\n usage = {\n // codex-rs TokenUsage 的 cached_input_tokens 是 input_tokens 的子集,\n // 落互斥桶前扣掉(docs/feature/adapters/sdk/codex-sdk/cost.md)\n inputTokens: (usage?.inputTokens ?? 0) + Math.max(0, num(u.input_tokens) - num(u.cached_input_tokens)),\n outputTokens: (usage?.outputTokens ?? 0) + num(u.output_tokens),\n cacheReadTokens: (usage?.cacheReadTokens ?? 0) + num(u.cached_input_tokens),\n // codex-rs TokenUsage 结构体同一份字段(与 o11y/parsers/codex.ts 的\n // transcript 解析同源),只在这次 turn 真的带回时累加。\n ...(typeof u.reasoning_output_tokens === \"number\" || usage?.reasoningTokens !== undefined\n ? { reasoningTokens: (usage?.reasoningTokens ?? 0) + num(u.reasoning_output_tokens) }\n : {}),\n requests: (usage?.requests ?? 0) + 1,\n };\n }\n break;\n }\n case \"turn.failed\": {\n failed = true;\n if (event.error?.message)\n events.push({ type: \"error\", message: event.error.message });\n break;\n }\n // item.updated(中间态)/ turn.started:忽略,等 completed。\n default:\n break;\n }\n return events;\n },\n };\n}\n"]}
1
+ {"version":3,"file":"sdk-streams.js","sourceRoot":"","sources":["sdk-streams.ts"],"names":[],"mappings":"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","sourcesContent":["// SDK 原生事件流 → 标准 StreamEvent 的官方转换器(+ 通用 SSE 读帧器)。\n//\n// 定位:各 agent SDK 的流式协议(Claude Agent SDK 的 `SDKMessage`、pi-agent-core 的\n// `AgentEvent`、Codex SDK 的 `ThreadEvent`)是 SDK 定义的通用协议,不是某个应用的私有格式——\n// 这层映射知识属于 niceeval 官方包,adapter 里只该剩传输粘合(应用把流放在哪个端点、\n// 审批走什么端点)。类型全部用结构化的 *Like 声明(同 turnFromAiSdk 的先例),不依赖任何 SDK 包。\n//\n// 用法(以 Claude Agent SDK 为例):\n//\n// ```typescript\n// import { sseJsonFrames, createClaudeSdkEventStream } from \"niceeval/adapter\";\n//\n// const frames = sseJsonFrames<SDKMessage>(res.body);\n// const stream = createClaudeSdkEventStream();\n// for (;;) {\n// const frame = await frames.next();\n// if (frame === null) break;\n// events.push(...stream.add(frame)); // 逐帧翻译;认不出的帧返回 []\n// }\n// return { status: stream.failed ? \"failed\" : \"completed\", events, usage: stream.usage };\n// ```\nimport type { CommandProjection, JsonValue, StreamEvent, ToolName, Usage } from \"../types.ts\";\nimport { normalizeToolName } from \"../o11y/tool-names.ts\";\nimport { CODEX_TOOL_ALIASES } from \"../o11y/parsers/codex.ts\";\nimport { CLAUDE_TOOL_ALIASES } from \"../o11y/parsers/claude-code.ts\";\nimport { notCommandProjection, opaqueCommandProjection } from \"../o11y/command-projection.ts\";\n// ───────────────────────── 通用 SSE 读帧器 ─────────────────────────\nexport interface SseFrameCursor<T> {\n /** 下一个 `data:` JSON 帧;流结束返回 null。`data: [DONE]` 哨兵帧自动跳过。 */\n next(): Promise<T | null>;\n}\n/** 标准 SSE(`data: {...}\\n\\n`)→ 逐帧 JSON。各 adapter 不用再手写 buffer 状态机。 */\nexport function sseJsonFrames<T>(body: ReadableStream<Uint8Array>): SseFrameCursor<T> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n async function next(): Promise<T | null> {\n for (;;) {\n const sepIndex = buffer.indexOf(\"\\n\\n\");\n if (sepIndex !== -1) {\n const rawEvent = buffer.slice(0, sepIndex);\n buffer = buffer.slice(sepIndex + 2);\n const line = rawEvent.split(\"\\n\").find((l) => l.startsWith(\"data: \"));\n if (!line)\n continue;\n const payload = line.slice(\"data: \".length);\n if (payload === \"[DONE]\")\n continue;\n return JSON.parse(payload) as T;\n }\n const { value, done } = await reader.read();\n if (done)\n return null;\n buffer += decoder.decode(value, { stream: true });\n }\n }\n return { next };\n}\nfunction isRecord(v: unknown): v is globalThis.Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n/** Claude Agent SDK 的原生 Bash tool 只交付 shell source,不交付 argv。 */\nfunction commandProjectionForClaudeSdkTool(name: string): CommandProjection | undefined {\n return name === \"Bash\" ? opaqueCommandProjection(\"unsupported-protocol\") : undefined;\n}\n// ───────────────────────── Claude Agent SDK:SDKMessage ─────────────────────────\n/** 只声明转换器要读的字段;真实的 SDKMessage 直接喂进来即可。 */\nexport interface ClaudeSdkMessageLike {\n type: string;\n subtype?: string;\n session_id?: string;\n tool_use_id?: string;\n is_error?: boolean;\n num_turns?: number;\n total_cost_usd?: number;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n cache_read_input_tokens?: number | null;\n cache_creation_input_tokens?: number | null;\n };\n message?: {\n content?: unknown;\n };\n [key: string]: unknown;\n}\nexport interface ClaudeSdkStream {\n /** 逐帧喂 `SDKMessage`,返回这一帧派生的标准事件;认不出的帧(stream_event 等)返回 []。 */\n add(message: ClaudeSdkMessageLike): StreamEvent[];\n /** `system`/`init` 帧带回的 session_id(首帧之后可读),回写 `ctx.session.id` 用。 */\n readonly sessionId: string | undefined;\n /** `result` 帧的聚合用量。 */\n readonly usage: Usage | undefined;\n /** `result` 帧报了 is_error。 */\n readonly failed: boolean;\n /**\n * 拒绝审批后续读前登记:该 tool_use 的 `tool_result` / `permission_denied` 落成\n * `status: \"rejected\"`(而不是 failed),且两种帧只产一条 operation.finished。\n */\n markRejected(toolUseId: string): void;\n}\n/**\n * Claude Agent SDK 消息流(`system` / `assistant` / `user` / `result`)→ 标准事件。\n * `assistant` 的 text/thinking/tool_use 块 → message / thinking / operation.started;`user` 的\n * tool_result 块 → operation.finished;`system`/`permission_denied` → rejected;`stream_event`\n * (逐 token 渲染)整个忽略。HITL 的停轮判定(哪个工具被门控)是应用侧的知识,不在这里——\n * 扫描 add() 返回的 operation.started 自行决定。\n */\nexport function createClaudeSdkEventStream(): ClaudeSdkStream {\n let sessionId: string | undefined;\n let usage: Usage | undefined;\n let failed = false;\n const resolvedCallIds = new Set<string>();\n const rejected = new Set<string>();\n const toolResultText = (content: unknown): string | undefined => {\n if (typeof content === \"string\")\n return content;\n if (Array.isArray(content)) {\n return content\n .filter((b): b is {\n type: \"text\";\n text: string;\n } => isRecord(b) && b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n }\n return undefined;\n };\n return {\n get sessionId() {\n return sessionId;\n },\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n markRejected(toolUseId) {\n rejected.add(toolUseId);\n },\n add(frame) {\n const events: StreamEvent[] = [];\n switch (frame.type) {\n case \"system\": {\n if (frame.subtype === \"init\" && typeof frame.session_id === \"string\") {\n sessionId ??= frame.session_id;\n }\n else if (frame.subtype === \"permission_denied\" && typeof frame.tool_use_id === \"string\") {\n if (!resolvedCallIds.has(frame.tool_use_id)) {\n resolvedCallIds.add(frame.tool_use_id);\n events.push({ type: \"operation.finished\", operationId: frame.tool_use_id, kind: \"tool\", status: \"rejected\" });\n }\n }\n break;\n }\n case \"assistant\": {\n const content: unknown[] = Array.isArray(frame.message?.content) ? frame.message.content : [];\n for (const block of content) {\n if (!isRecord(block))\n continue;\n if (block.type === \"text\" && typeof block.text === \"string\" && block.text) {\n events.push({ type: \"message\", role: \"assistant\", text: block.text });\n }\n else if (block.type === \"thinking\" && typeof block.thinking === \"string\" && block.thinking) {\n events.push({ type: \"thinking\", text: block.thinking });\n }\n else if (block.type === \"tool_use\" && typeof block.id === \"string\" && typeof block.name === \"string\") {\n const command = commandProjectionForClaudeSdkTool(block.name);\n events.push({\n type: \"operation.started\",\n operationId: block.id,\n operation: {\n kind: \"tool\",\n name: block.name,\n input: block.input as JsonValue,\n tool: normalizeToolName(block.name, CLAUDE_TOOL_ALIASES),\n ...(command === undefined ? {} : { command }),\n },\n });\n }\n }\n break;\n }\n case \"user\": {\n const content: unknown[] = Array.isArray(frame.message?.content) ? frame.message.content : [];\n for (const block of content) {\n if (!isRecord(block) || block.type !== \"tool_result\" || typeof block.tool_use_id !== \"string\")\n continue;\n if (resolvedCallIds.has(block.tool_use_id))\n continue;\n resolvedCallIds.add(block.tool_use_id);\n events.push({\n type: \"operation.finished\",\n operationId: block.tool_use_id,\n kind: \"tool\",\n output: toolResultText(block.content) as JsonValue,\n status: rejected.has(block.tool_use_id) ? \"rejected\" : block.is_error ? \"failed\" : \"completed\",\n });\n }\n break;\n }\n case \"result\": {\n failed = frame.is_error === true;\n if (frame.usage) {\n usage = {\n inputTokens: frame.usage.input_tokens,\n outputTokens: frame.usage.output_tokens,\n cacheReadTokens: frame.usage.cache_read_input_tokens ?? undefined,\n cacheCreationTokens: frame.usage.cache_creation_input_tokens ?? undefined,\n requests: frame.num_turns,\n costUSD: frame.total_cost_usd,\n };\n }\n break;\n }\n // stream_event(逐 token 渲染)与其它系统/生命周期消息:无对应 StreamEvent。\n default:\n break;\n }\n return events;\n },\n };\n}\n// ───────────────────────── pi-agent-core:AgentEvent ─────────────────────────\nexport interface PiAgentEventLike {\n type: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n result?: unknown;\n isError?: boolean;\n /** content 在 user 消息上是 string、assistant 消息上是 parts 数组——按 unknown 收,防御式解析。 */\n message?: {\n role?: string;\n content?: unknown;\n /** assistant 消息的收尾原因;\"error\" / \"aborted\" 表示这条消息以失败告终。 */\n stopReason?: string;\n /** stopReason 为 \"error\" 时的错误说明。 */\n errorMessage?: string;\n usage?: {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: {\n total: number;\n };\n };\n };\n /** `message_update` 帧携带的增量事件(text_delta / thinking_delta 等)——只读 type/delta,防御式解析。 */\n assistantMessageEvent?: {\n type?: string;\n delta?: unknown;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\nexport interface PiAgentStream {\n /** 逐帧喂 `AgentEvent`,返回这一帧派生的标准事件;生命周期帧(turn_start 等)返回 []。 */\n add(event: PiAgentEventLike): StreamEvent[];\n /** assistant `message_end` 逐条累加的用量。 */\n readonly usage: Usage | undefined;\n /** assistant 消息以 stopReason \"error\" / \"aborted\" 收尾过。 */\n readonly failed: boolean;\n /** 拒绝审批后续读前登记:该调用 `tool_execution_end` 的 isError 判成 \"rejected\" 而非 \"failed\"。 */\n markRejected(toolCallId: string): void;\n}\n/**\n * pi-agent-core 事件流(`message_start` / `message_update` / `message_end` /\n * `tool_execution_start` / `tool_execution_end`)→ 标准事件。消息三段式聚合成一条:\n * message_start 清空增量缓冲、message_update 的 text_delta / thinking_delta 逐段累加、\n * message_end 落地成 message / thinking(优先取 end 帧的完整 content,缺了用累加的增量兜底);\n * 只有 start/delta 的截断流不产出半条消息。message_end 同时累加 usage;assistant 消息以\n * stopReason \"error\" / \"aborted\" 收尾时记失败(`failed`)并发一条 error 事件。\n * tool_execution_start/end → operation.started / operation.finished。\n */\nexport function createPiAgentEventStream(): PiAgentStream {\n let usage: Usage | undefined;\n let failed = false;\n // message_start/update 累加的增量缓冲;message_end 落地后清空,截断流(无 end)不落地。\n let deltaText = \"\";\n let deltaThinking = \"\";\n const rejected = new Set<string>();\n const partText = (event: PiAgentEventLike, type: \"text\" | \"thinking\"): string => {\n if (event.message?.role !== \"assistant\" || !Array.isArray(event.message.content))\n return \"\";\n return event.message.content\n .filter((part): part is globalThis.Record<string, unknown> => isRecord(part) && part.type === type)\n .map((part) => {\n const v = type === \"text\" ? part.text : part.thinking;\n return typeof v === \"string\" ? v : \"\";\n })\n .join(\"\");\n };\n return {\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n markRejected(toolCallId) {\n rejected.add(toolCallId);\n },\n add(event) {\n const events: StreamEvent[] = [];\n switch (event.type) {\n case \"message_start\": {\n // 新消息开始:上一条没等到 message_end 的增量作废(不落地半条消息)。\n deltaText = \"\";\n deltaThinking = \"\";\n break;\n }\n case \"message_update\": {\n const e = event.assistantMessageEvent;\n if (isRecord(e) && typeof e.delta === \"string\") {\n if (e.type === \"text_delta\")\n deltaText += e.delta;\n else if (e.type === \"thinking_delta\")\n deltaThinking += e.delta;\n }\n break;\n }\n case \"message_end\": {\n // 优先取 end 帧的完整 content;缺了(部分传输只带增量)用累加的 delta 兜底。\n const text = partText(event, \"text\") || (event.message?.role === \"assistant\" ? deltaText : \"\");\n if (text)\n events.push({ type: \"message\", role: \"assistant\", text });\n const thinking = partText(event, \"thinking\") || (event.message?.role === \"assistant\" ? deltaThinking : \"\");\n if (thinking)\n events.push({ type: \"thinking\", text: thinking });\n deltaText = \"\";\n deltaThinking = \"\";\n if (event.message?.role === \"assistant\") {\n const stopReason = event.message.stopReason;\n if (stopReason === \"error\" || stopReason === \"aborted\") {\n failed = true;\n events.push({ type: \"error\", message: event.message.errorMessage ?? `pi agent stopReason=${stopReason}` });\n }\n }\n const u = event.message?.role === \"assistant\" ? event.message.usage : undefined;\n if (u) {\n // pi computes u.cost from its own model price table. That estimate\n // is not provider-observed billing and must not enter Usage.costUSD.\n usage = {\n inputTokens: (usage?.inputTokens ?? 0) + u.input,\n outputTokens: (usage?.outputTokens ?? 0) + u.output,\n cacheReadTokens: (usage?.cacheReadTokens ?? 0) + u.cacheRead,\n cacheCreationTokens: (usage?.cacheCreationTokens ?? 0) + u.cacheWrite,\n requests: (usage?.requests ?? 0) + 1,\n };\n }\n break;\n }\n case \"tool_execution_start\": {\n if (typeof event.toolCallId === \"string\" && typeof event.toolName === \"string\") {\n events.push({\n type: \"operation.started\",\n operationId: event.toolCallId,\n operation: { kind: \"tool\", name: event.toolName, input: event.args as JsonValue },\n });\n }\n break;\n }\n case \"tool_execution_end\": {\n if (typeof event.toolCallId === \"string\") {\n const status = event.isError ? (rejected.has(event.toolCallId) ? \"rejected\" : \"failed\") : \"completed\";\n events.push({ type: \"operation.finished\", operationId: event.toolCallId, kind: \"tool\", output: event.result as JsonValue, status });\n }\n break;\n }\n // agent_start / turn_start / turn_end / tool_execution_update / agent_end:\n // 无对应 StreamEvent(消息文本统一在 message_end 落地)。\n default:\n break;\n }\n return events;\n },\n };\n}\n// ───────────────────────── Codex SDK:ThreadEvent ─────────────────────────\nexport interface CodexThreadEventLike {\n type: string;\n message?: string;\n thread_id?: string;\n item?: {\n type?: string;\n text?: string;\n message?: string;\n [key: string]: unknown;\n };\n error?: {\n message: string;\n };\n [key: string]: unknown;\n}\nexport interface CodexThreadStream {\n /**\n * 逐帧喂 `ThreadEvent`,返回标准事件:消息类(agent_message → message、reasoning → thinking、\n * error item / turn.failed / 顶层 error → error)+ 工具项(command_execution / mcp_tool_call / web_search /\n * file_change → operation.started + operation.finished,附规范工具名 `tool`,如 command_execution →\n * `\"shell\"`,供 `calledTool(\"shell\")` 这类跨 agent 断言命中)。usage 从 `turn.completed` 聚合,经 `usage` 读。\n * 断言依据全部来自这条流;codex CLI 的原生 OTLP span 只用于瀑布图(spanMapper: mapCodexSpans)。\n */\n add(event: CodexThreadEventLike): StreamEvent[];\n /** `thread.started` 带回的 thread_id,回写 `ctx.session.id` 用。 */\n readonly threadId: string | undefined;\n /** `turn.completed` 聚合的用量(input/cached/output tokens)。 */\n readonly usage: Usage | undefined;\n /** turn.failed 或顶层不可恢复 error 出现过;非致命 error item 只保留诊断。 */\n readonly failed: boolean;\n}\n/** Codex SDK 线程事件流(`thread.started` / `item.*` / `turn.completed` / `turn.failed`)→ 标准事件。 */\nexport function createCodexThreadEventStream(): CodexThreadStream {\n let threadId: string | undefined;\n let usage: Usage | undefined;\n let failed = false;\n // item.started 已发 operation.started 的 id;item.completed 时不重发,只补 result。\n const startedCallIds = new Set<string>();\n let synth = 0;\n const callIdOf = (item: globalThis.Record<string, unknown>, prefix: string): string => {\n const id = item.id;\n return typeof id === \"string\" || typeof id === \"number\" ? String(id) : `${prefix}_${++synth}`;\n };\n // 工具项 → operation.started(+completed 时的 operation.finished)。与 o11y/parsers/codex.ts 的\n // transcript 映射保持同一套语义(字段名以 codex exec --json 的 ThreadItem 为准),\n // 包括规范工具名 tool:少了它 derive 只能落 name=\"unknown\",calledTool(\"shell\") 这类\n // 跨 agent 规范名断言在 SDK 流路径上会静默失配(2026-07-09 CI 实红)。\n const handleToolItem = (item: globalThis.Record<string, unknown>, isCompleted: boolean): StreamEvent[] => {\n const events: StreamEvent[] = [];\n const emitCall = (callId: string, name: string, input: JsonValue, tool: ToolName, command: CommandProjection): void => {\n if (startedCallIds.has(callId))\n return;\n startedCallIds.add(callId);\n events.push({ type: \"operation.started\", operationId: callId, operation: { kind: \"tool\", name, input, tool, command } });\n };\n switch (item.type) {\n case \"command_execution\": {\n const callId = callIdOf(item, \"cmd\");\n emitCall(callId, \"command_execution\", { command: item.command ?? null } as JsonValue, \"shell\", opaqueCommandProjection(\"unsupported-protocol\"));\n if (isCompleted) {\n const exit = item.exit_code ?? item.exitCode;\n const output = item.aggregated_output ?? item.aggregatedOutput ?? item.output;\n const status = item.status === \"declined\" || item.status === \"rejected\"\n ? \"rejected\" as const\n : exit === 0 || (exit == null && item.status !== \"failed\" && item.status !== \"error\")\n ? \"completed\" as const\n : \"failed\" as const;\n events.push({\n type: \"operation.finished\",\n operationId: callId,\n kind: \"tool\",\n ...(output === undefined && exit === undefined\n ? {}\n : { output: { output: (output ?? null) as JsonValue, exit_code: (exit ?? null) as JsonValue } }),\n status,\n });\n }\n return events;\n }\n case \"mcp_tool_call\": {\n const callId = callIdOf(item, \"mcp\");\n const tool = String(item.tool ?? \"unknown\");\n const name = typeof item.server === \"string\" ? `${item.server}.${tool}` : tool;\n emitCall(callId, name, (item.arguments ?? null) as JsonValue, normalizeToolName(tool, CODEX_TOOL_ALIASES), notCommandProjection());\n if (isCompleted) {\n const success = !item.error && item.status !== \"failed\";\n events.push({\n type: \"operation.finished\",\n operationId: callId,\n kind: \"tool\",\n output: (item.result ?? null) as JsonValue,\n status: success ? \"completed\" : \"failed\",\n });\n }\n return events;\n }\n case \"web_search\": {\n const callId = callIdOf(item, \"web\");\n emitCall(callId, \"web_search\", { query: item.query ?? null } as JsonValue, \"web_search\", notCommandProjection());\n if (isCompleted) {\n events.push({ type: \"operation.finished\", operationId: callId, kind: \"tool\", output: null, status: \"completed\" });\n }\n return events;\n }\n case \"file_change\": {\n // 补丁类只在 completed 落一次:changes 里每个文件一对 called/result。\n if (!isCompleted)\n return events;\n const baseId = callIdOf(item, \"patch\");\n const changes = Array.isArray(item.changes) ? item.changes : [];\n changes.forEach((ch, i) => {\n const callId = `${baseId}#${i}`;\n const change = isRecord(ch) ? { path: ch.path ?? null, kind: ch.kind ?? null } : {};\n events.push({\n type: \"operation.started\",\n operationId: callId,\n operation: {\n kind: \"tool\",\n name: \"file_change\",\n input: change as JsonValue,\n tool: \"file_edit\",\n command: notCommandProjection(),\n },\n });\n events.push({ type: \"operation.finished\", operationId: callId, kind: \"tool\", output: change as JsonValue, status: \"completed\" });\n });\n return events;\n }\n default:\n return events;\n }\n };\n return {\n get threadId() {\n return threadId;\n },\n get usage() {\n return usage;\n },\n get failed() {\n return failed;\n },\n add(event) {\n const events: StreamEvent[] = [];\n switch (event.type) {\n case \"thread.started\": {\n if (typeof event.thread_id === \"string\")\n threadId ??= event.thread_id;\n break;\n }\n case \"item.started\": {\n if (event.item)\n events.push(...handleToolItem(event.item, false));\n break;\n }\n case \"item.completed\": {\n const item = event.item;\n if (!item)\n break;\n if (item.type === \"agent_message\" && typeof item.text === \"string\" && item.text) {\n events.push({ type: \"message\", role: \"assistant\", text: item.text });\n }\n else if (item.type === \"reasoning\" && typeof item.text === \"string\" && item.text) {\n events.push({ type: \"thinking\", text: item.text });\n }\n else if (item.type === \"error\" && typeof item.message === \"string\") {\n events.push({ type: \"error\", message: item.message });\n }\n else {\n events.push(...handleToolItem(item, true));\n }\n break;\n }\n case \"turn.completed\": {\n const u = event.usage;\n if (isRecord(u)) {\n const num = (v: unknown): number => (typeof v === \"number\" ? v : 0);\n usage = {\n // codex-rs TokenUsage 的 cached_input_tokens 是 input_tokens 的子集,\n // 落互斥桶前扣掉(docs/feature/adapters/sdk/codex-sdk/cost.md)\n inputTokens: (usage?.inputTokens ?? 0) + Math.max(0, num(u.input_tokens) - num(u.cached_input_tokens)),\n outputTokens: (usage?.outputTokens ?? 0) + num(u.output_tokens),\n cacheReadTokens: (usage?.cacheReadTokens ?? 0) + num(u.cached_input_tokens),\n // codex-rs TokenUsage 结构体同一份字段(与 o11y/parsers/codex.ts 的\n // transcript 解析同源),只在这次 turn 真的带回时累加。\n ...(typeof u.reasoning_output_tokens === \"number\" || usage?.reasoningTokens !== undefined\n ? { reasoningTokens: (usage?.reasoningTokens ?? 0) + num(u.reasoning_output_tokens) }\n : {}),\n requests: (usage?.requests ?? 0) + 1,\n };\n }\n break;\n }\n case \"error\": {\n failed = true;\n if (typeof event.message === \"string\")\n events.push({ type: \"error\", message: event.message });\n break;\n }\n case \"turn.failed\": {\n failed = true;\n if (event.error?.message)\n events.push({ type: \"error\", message: event.error.message });\n break;\n }\n // item.updated(中间态)/ turn.started:忽略,等 completed。\n default:\n break;\n }\n return events;\n },\n };\n}\n"]}
@@ -103,6 +103,7 @@ export interface PiAgentStream {
103
103
  export declare function createPiAgentEventStream(): PiAgentStream;
104
104
  export interface CodexThreadEventLike {
105
105
  type: string;
106
+ message?: string;
106
107
  thread_id?: string;
107
108
  item?: {
108
109
  type?: string;
@@ -118,7 +119,7 @@ export interface CodexThreadEventLike {
118
119
  export interface CodexThreadStream {
119
120
  /**
120
121
  * 逐帧喂 `ThreadEvent`,返回标准事件:消息类(agent_message → message、reasoning → thinking、
121
- * error item / turn.failed → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
+ * error item / turn.failed / 顶层 error → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
123
  * file_change → operation.started + operation.finished,附规范工具名 `tool`,如 command_execution →
123
124
  * `"shell"`,供 `calledTool("shell")` 这类跨 agent 断言命中)。usage 从 `turn.completed` 聚合,经 `usage` 读。
124
125
  * 断言依据全部来自这条流;codex CLI 的原生 OTLP span 只用于瀑布图(spanMapper: mapCodexSpans)。
@@ -128,7 +129,7 @@ export interface CodexThreadStream {
128
129
  readonly threadId: string | undefined;
129
130
  /** `turn.completed` 聚合的用量(input/cached/output tokens)。 */
130
131
  readonly usage: Usage | undefined;
131
- /** turn.failed / error item 出现过。 */
132
+ /** turn.failed 或顶层不可恢复 error 出现过;非致命 error item 只保留诊断。 */
132
133
  readonly failed: boolean;
133
134
  }
134
135
  /** Codex SDK 线程事件流(`thread.started` / `item.*` / `turn.completed` / `turn.failed`)→ 标准事件。 */
@@ -103,6 +103,7 @@ export interface PiAgentStream {
103
103
  export declare function createPiAgentEventStream(): PiAgentStream;
104
104
  export interface CodexThreadEventLike {
105
105
  type: string;
106
+ message?: string;
106
107
  thread_id?: string;
107
108
  item?: {
108
109
  type?: string;
@@ -118,7 +119,7 @@ export interface CodexThreadEventLike {
118
119
  export interface CodexThreadStream {
119
120
  /**
120
121
  * 逐帧喂 `ThreadEvent`,返回标准事件:消息类(agent_message → message、reasoning → thinking、
121
- * error item / turn.failed → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
+ * error item / turn.failed / 顶层 error → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
123
  * file_change → operation.started + operation.finished,附规范工具名 `tool`,如 command_execution →
123
124
  * `"shell"`,供 `calledTool("shell")` 这类跨 agent 断言命中)。usage 从 `turn.completed` 聚合,经 `usage` 读。
124
125
  * 断言依据全部来自这条流;codex CLI 的原生 OTLP span 只用于瀑布图(spanMapper: mapCodexSpans)。
@@ -128,7 +129,7 @@ export interface CodexThreadStream {
128
129
  readonly threadId: string | undefined;
129
130
  /** `turn.completed` 聚合的用量(input/cached/output tokens)。 */
130
131
  readonly usage: Usage | undefined;
131
- /** turn.failed / error item 出现过。 */
132
+ /** turn.failed 或顶层不可恢复 error 出现过;非致命 error item 只保留诊断。 */
132
133
  readonly failed: boolean;
133
134
  }
134
135
  /** Codex SDK 线程事件流(`thread.started` / `item.*` / `turn.completed` / `turn.failed`)→ 标准事件。 */
@@ -103,6 +103,7 @@ export interface PiAgentStream {
103
103
  export declare function createPiAgentEventStream(): PiAgentStream;
104
104
  export interface CodexThreadEventLike {
105
105
  type: string;
106
+ message?: string;
106
107
  thread_id?: string;
107
108
  item?: {
108
109
  type?: string;
@@ -118,7 +119,7 @@ export interface CodexThreadEventLike {
118
119
  export interface CodexThreadStream {
119
120
  /**
120
121
  * 逐帧喂 `ThreadEvent`,返回标准事件:消息类(agent_message → message、reasoning → thinking、
121
- * error item / turn.failed → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
+ * error item / turn.failed / 顶层 error → error)+ 工具项(command_execution / mcp_tool_call / web_search /
122
123
  * file_change → operation.started + operation.finished,附规范工具名 `tool`,如 command_execution →
123
124
  * `"shell"`,供 `calledTool("shell")` 这类跨 agent 断言命中)。usage 从 `turn.completed` 聚合,经 `usage` 读。
124
125
  * 断言依据全部来自这条流;codex CLI 的原生 OTLP span 只用于瀑布图(spanMapper: mapCodexSpans)。
@@ -128,7 +129,7 @@ export interface CodexThreadStream {
128
129
  readonly threadId: string | undefined;
129
130
  /** `turn.completed` 聚合的用量(input/cached/output tokens)。 */
130
131
  readonly usage: Usage | undefined;
131
- /** turn.failed / error item 出现过。 */
132
+ /** turn.failed 或顶层不可恢复 error 出现过;非致命 error item 只保留诊断。 */
132
133
  readonly failed: boolean;
133
134
  }
134
135
  /** Codex SDK 线程事件流(`thread.started` / `item.*` / `turn.completed` / `turn.failed`)→ 标准事件。 */
@@ -390,7 +390,9 @@ function uiMessageStreamSendEffect(options, input, ctx) {
390
390
  if (!finalMessage) {
391
391
  return yield* effect_1.Effect.fail((0, send_failures_ts_1.makeSendFailure)({
392
392
  acceptance: "unknown",
393
- message: `POST ${url} 的流结束了但一条 assistant 消息都没归约出来 —— 端点吐的不是 UI Message Stream 帧?`,
393
+ message: streamState.sawError !== undefined && streamState.sawError.trim() !== ""
394
+ ? streamState.sawError
395
+ : `POST ${url} ended without producing an assistant message. Confirm the endpoint speaks the complete UI Message Stream protocol.`,
394
396
  }));
395
397
  }
396
398
  const derived = yield* effect_1.Effect.try({