@qwen-code/arena-agent 0.0.10-dev.5 → 0.0.10-dev.7

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 (101) hide show
  1. package/.env.example +19 -10
  2. package/CHANGELOG.md +160 -0
  3. package/README.md +50 -37
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +62 -96
  6. package/dist/agent.js.map +1 -1
  7. package/dist/anthropic.js +2 -0
  8. package/dist/anthropic.js.map +1 -1
  9. package/dist/ask-user.js +2 -0
  10. package/dist/ask-user.js.map +1 -1
  11. package/dist/attachments.js +4 -3
  12. package/dist/attachments.js.map +1 -1
  13. package/dist/cli.js +9 -8
  14. package/dist/cli.js.map +1 -1
  15. package/dist/code-tools.js +122 -30
  16. package/dist/code-tools.js.map +1 -1
  17. package/dist/compaction.d.ts +4 -2
  18. package/dist/compaction.js +37 -5
  19. package/dist/compaction.js.map +1 -1
  20. package/dist/config.d.ts +0 -2
  21. package/dist/config.js +2 -3
  22. package/dist/config.js.map +1 -1
  23. package/dist/file-edit.d.ts +2 -0
  24. package/dist/file-edit.js +9 -4
  25. package/dist/file-edit.js.map +1 -1
  26. package/dist/history.d.ts +7 -6
  27. package/dist/history.js +41 -46
  28. package/dist/history.js.map +1 -1
  29. package/dist/mode.js +3 -1
  30. package/dist/mode.js.map +1 -1
  31. package/dist/model-router-media.d.ts +1 -0
  32. package/dist/model-router-media.js +71 -1
  33. package/dist/model-router-media.js.map +1 -1
  34. package/dist/openai-responses.js +2 -0
  35. package/dist/openai-responses.js.map +1 -1
  36. package/dist/provider.d.ts +0 -1
  37. package/dist/provider.js +12 -41
  38. package/dist/provider.js.map +1 -1
  39. package/dist/replay-responses.d.ts +17 -0
  40. package/dist/replay-responses.js +100 -0
  41. package/dist/replay-responses.js.map +1 -0
  42. package/dist/routify-web-fetch.js +18 -4
  43. package/dist/routify-web-fetch.js.map +1 -1
  44. package/dist/server.js +7 -7
  45. package/dist/server.js.map +1 -1
  46. package/dist/spec.js +2 -0
  47. package/dist/spec.js.map +1 -1
  48. package/dist/speech-audio.d.ts +9 -0
  49. package/dist/speech-audio.js +130 -0
  50. package/dist/speech-audio.js.map +1 -0
  51. package/dist/speech-model.d.ts +3 -0
  52. package/dist/speech-model.js +8 -0
  53. package/dist/speech-model.js.map +1 -0
  54. package/dist/tools.js +81 -11
  55. package/dist/tools.js.map +1 -1
  56. package/dist/tui.js +6 -9
  57. package/dist/tui.js.map +1 -1
  58. package/dist/types.d.ts +16 -2
  59. package/dist/voice-registry.d.ts +2 -0
  60. package/dist/voice-registry.js +10 -2
  61. package/dist/voice-registry.js.map +1 -1
  62. package/dist/web-fetch-output.d.ts +9 -0
  63. package/dist/web-fetch-output.js +38 -0
  64. package/dist/web-fetch-output.js.map +1 -0
  65. package/docs/BINARY_DISTRIBUTION.md +25 -16
  66. package/docs/MODES_AND_RELEASES.md +28 -5
  67. package/docs/SDK.md +4 -0
  68. package/package.json +9 -3
  69. package/scripts/README.md +62 -0
  70. package/scripts/check-changelog.mjs +66 -0
  71. package/vendor/audio/darwin-arm64/FFmpeg.LICENSE +502 -0
  72. package/vendor/audio/darwin-arm64/LAME.LICENSE +481 -0
  73. package/vendor/audio/darwin-arm64/Opus.LICENSE +44 -0
  74. package/vendor/audio/darwin-arm64/ffmpeg.gz +0 -0
  75. package/vendor/audio/darwin-arm64/manifest.json +39 -0
  76. package/vendor/audio/darwin-x64/FFmpeg.LICENSE +502 -0
  77. package/vendor/audio/darwin-x64/LAME.LICENSE +481 -0
  78. package/vendor/audio/darwin-x64/Opus.LICENSE +44 -0
  79. package/vendor/audio/darwin-x64/ffmpeg.gz +0 -0
  80. package/vendor/audio/darwin-x64/manifest.json +39 -0
  81. package/vendor/audio/linux-arm64/FFmpeg.LICENSE +502 -0
  82. package/vendor/audio/linux-arm64/LAME.LICENSE +481 -0
  83. package/vendor/audio/linux-arm64/Opus.LICENSE +44 -0
  84. package/vendor/audio/linux-arm64/ffmpeg.gz +0 -0
  85. package/vendor/audio/linux-arm64/manifest.json +39 -0
  86. package/vendor/audio/linux-x64/FFmpeg.LICENSE +502 -0
  87. package/vendor/audio/linux-x64/LAME.LICENSE +481 -0
  88. package/vendor/audio/linux-x64/Opus.LICENSE +44 -0
  89. package/vendor/audio/linux-x64/ffmpeg.gz +0 -0
  90. package/vendor/audio/linux-x64/manifest.json +39 -0
  91. package/vendor/audio/sources/build-audio-encoder.sh +76 -0
  92. package/vendor/audio/sources/ffmpeg-7.0.2.tar.xz +0 -0
  93. package/vendor/audio/sources/lame-3.100.tar.gz +0 -0
  94. package/vendor/audio/sources/opus-1.5.2.tar.gz +0 -0
  95. package/vendor/audio/sources/pkgconf-2.3.0.tar.xz +0 -0
  96. package/vendor/audio/sources/sources.lock.json +30 -0
  97. package/vendor/audio/win32-x64/FFmpeg.LICENSE +502 -0
  98. package/vendor/audio/win32-x64/LAME.LICENSE +481 -0
  99. package/vendor/audio/win32-x64/Opus.LICENSE +44 -0
  100. package/vendor/audio/win32-x64/ffmpeg.gz +0 -0
  101. package/vendor/audio/win32-x64/manifest.json +39 -0
package/.env.example CHANGED
@@ -1,5 +1,4 @@
1
- # Model name. Provider prefixes are stripped for direct connections and kept
2
- # when LITELLM_PROXY_URL is configured.
1
+ # Model name. Provider prefixes select the protocol and are stripped before sending.
3
2
  OPENAI_MODEL=openai/qwen-latest-series-invite-beta-v92
4
3
  # OPENAI_MODEL=anthropic/claude-sonnet-4-20250514
5
4
  # OPENAI_MODEL=gemini/gemini-2.5-pro
@@ -27,10 +26,6 @@ ARENA_HARNESS_MODE=arena
27
26
  # ANTHROPIC_API_KEY=
28
27
  # GEMINI_API_KEY=
29
28
 
30
- # LiteLLM Proxy (takes precedence over OPENAI_BASE_URL).
31
- # LITELLM_PROXY_URL=http://127.0.0.1:4000/v1
32
- # LITELLM_API_KEY=
33
-
34
29
  # Direct OpenAI-compatible DashScope endpoint:
35
30
  # OPENAI_MODEL=qwen3.7-max
36
31
  # Default model used by the reproduction scripts:
@@ -51,6 +46,7 @@ ARENA_HARNESS_MODE=arena
51
46
  # ARENA_MAX_TOKENS=131072
52
47
  # ARENA_TEMPERATURE=1
53
48
  # OpenAI-compatible: reasoning_effort; native Anthropic: output_config.effort.
49
+ # Allowed: low, medium, high, xhigh, max, ultra.
54
50
  # ARENA_REASONING_EFFORT=max
55
51
  # ARENA_TOOL_CHOICE=auto
56
52
  # JSON array of exact tool names hidden from the model and rejected if called.
@@ -136,12 +132,15 @@ ROUTIFY_API_KEY=
136
132
  # CODE_HARNESS_WEB_SEARCH_MODEL=brave.llm-context
137
133
  # Optional fetch_page/web_fetch path: Firecrawl first, then Jina Reader.
138
134
  # CODE_HARNESS_ROUTIFY_WEB_FETCH_ENABLED=false
139
- # ARENA_IMAGE_MODEL=gemini-2.5-flash-image
135
+ # Code Arena web_fetch content cap (UTF-8 bytes, including truncation notice).
136
+ # Applies to local and Routify readers in all formats; must be a positive integer.
137
+ # CODE_HARNESS_WEB_FETCH_MAX_BYTES=40000
138
+ # ARENA_IMAGE_MODEL=gemini-3.1-flash-image
140
139
  # ARENA_IMAGE_SIZE=1024*1024
141
- # CODE_HARNESS_IMAGE_MODEL=gemini-2.5-flash-image
140
+ # CODE_HARNESS_IMAGE_MODEL=gemini-3.1-flash-image
142
141
  # CODE_HARNESS_IMAGE_SIZE=1024*1024
143
- # ARENA_SPEECH_MODEL=doubao-tts
144
- # ARENA_SPEECH_VOICE=zh_female_vv_uranus_bigtts
142
+ # ARENA_SPEECH_MODEL=gemini-3.1-flash-tts-preview
143
+ # ARENA_SPEECH_VOICE=Kore
145
144
 
146
145
  # start_process automatically checks E2B preview hosts when E2B_SANDBOX_ID is
147
146
  # present. For another preview proxy, use {port} and optionally {sandboxId}:
@@ -157,6 +156,16 @@ ROUTIFY_API_KEY=
157
156
  # the tool list but the executor still accepts calls to it.
158
157
  # CODE_HARNESS_APPLY_PATCH_TOOL=false
159
158
 
159
+ # Replay-time canned tool responses: a JSON file of
160
+ # {"entries": [{tool, arguments, output}, ...]}; matching calls return the
161
+ # recorded output verbatim, others fall through to real execution.
162
+ # Only nondeterministic network/media tools are replayable (web_search,
163
+ # web_fetch, fetch_page, fetch_media, image_search, generate_image,
164
+ # generate_speech); recorded entries for other tools are ignored with a
165
+ # diagnostic, and every miss is logged on stderr with an exit-time hit-rate
166
+ # summary.
167
+ # CODE_HARNESS_REPLAY_RESPONSES=
168
+
160
169
  # Full Stack build_and_start runtime. PostgreSQL and psql are environment
161
170
  # prerequisites, matching the captured sandbox baseline.
162
171
  # CODE_HARNESS_PREVIEW_PORT=3000
package/CHANGELOG.md ADDED
@@ -0,0 +1,160 @@
1
+ # Changelog
2
+
3
+ 记录影响 CLI 使用的功能、修复、配置和兼容性变化,四种运行模式和各分发包共用版本号。
4
+ 每个版本按影响范围分为 **Agent Arena**、**Code Arena**(React、HTML、Full Stack)
5
+ 和**通用**;共同的模型连接、CLI 和历史记录变化只记在通用部分,无变更的分类省略。
6
+ 从 `0.0.10-dev.0` 开始补录,历史条目按相邻 Git 标签之间的提交整理;日期采用
7
+ 标签对应发布提交的日期。最新标签之后的变更放在 `Unreleased`,不计入已发布版本。
8
+
9
+ 每次发布(包括 dev 预发布)前,将本次变更整理到与 `package.json` 版本一致的
10
+ `## [版本号] - YYYY-MM-DD` 条目,并保留顶部 `Unreleased` 供后续记录。
11
+ 发布步骤见[发版流程](docs/MODES_AND_RELEASES.md#发布节奏)。
12
+
13
+ ## [Unreleased]
14
+
15
+ ## [0.0.10-dev.7] - 2026-09-12
16
+
17
+ ### Code Arena
18
+
19
+ - `fetch_media` 修正 Pexels 图片推荐尺寸与缩略图选择;视频优先选择高分辨率 MP4,
20
+ 补齐 `videoFile` 元数据及视频封面,运行错误保留历史错误前缀。
21
+ - 默认 Agent、命令行和交互终端直接发送对应模式的历史提示词,不再自动追加本地
22
+ 工作区说明;SDK 显式传入 `workspaceContext` 时仍可附加说明。
23
+ - React 文件编辑保留原换行,重复匹配时替换首处;找不到原文时返回错误。
24
+ `apply_patch` 在写入前拒绝同一补丁内重复操作同一路径。
25
+ - React 修正文件列表的根目录别名及 500 条上限、子目录 glob 匹配和 grep 上下文
26
+ 分组;大文本读取采用约 40 KB 的头尾截断。
27
+ - React 安装依赖时拒绝版本范围,保留依赖锁文件,并修正非法包名和生图额度
28
+ 耗尽时的错误返回。
29
+ - 三种 Code Arena 模式的 `web_fetch` 正文默认限制为 40,000 UTF-8 字节,支持
30
+ `CODE_HARNESS_WEB_FETCH_MAX_BYTES` 配置;修复 Routify 的 text/html 格式读取。
31
+ - Full Stack 的 `bash` 省略 `workdir` 时默认在项目根目录执行;非法工作目录
32
+ 返回历史对应的详细错误,公开工具 schema 保持不变。
33
+
34
+ ### 通用
35
+
36
+ - 支持 `CODE_HARNESS_REPLAY_RESPONSES` 按工具名和参数回放已录制的网络/媒体返回,
37
+ 未命中时执行真实工具;本地文件和进程工具始终真实执行。
38
+ - 移除 LiteLLM 专用路由及 `LITELLM_PROXY_URL`、`LITELLM_API_KEY` 配置。
39
+ 模型连接统一使用 `OPENAI_BASE_URL` / `OPENAI_API_KEY`(兼容
40
+ `ARENA_API_BASE` / `ARENA_API_KEY`),通过 Chat Completions、Responses 或
41
+ Anthropic Messages 协议调用。使用旧 LiteLLM 环境变量的部署需迁移连接配置。
42
+ - Chat Completions 按配置传递 thinking 参数,不再因端点 URL 过滤这些参数,
43
+ 保留 reasoning effort 与 thinking budget 的优先级。
44
+
45
+ ## [0.0.10-dev.6] - 2026-09-10
46
+
47
+ ### Agent Arena
48
+
49
+ - 新增 Gemini TTS,默认语音模型改为 `gemini-3.1-flash-tts-preview`;支持 WAV、
50
+ MP3 和 Ogg Opus。npm 包携带音频编码器,SEA 二进制内嵌编码器,运行时无需下载
51
+ 或安装系统 ffmpeg;设置 `ARENA_SPEECH_MODEL=doubao-tts` 可继续使用豆包。
52
+ - 上下文压缩采用官方 dump 形式的 `role: "compaction"` 历史记录,保留全部原始
53
+ 消息;续跑从最后一条有效压缩记录恢复上下文。后台记忆更新只保存在内存中,
54
+ 不再单独持久化 `session_memory`。
55
+ - 限制 bash 输出缓冲区,避免长输出触发字符串大小溢出。
56
+
57
+ ### Code Arena
58
+
59
+ - Full Stack 默认模型 step 上限提高到 75。
60
+
61
+ ### 通用
62
+
63
+ - 支持 `ARENA_REASONING_EFFORT=ultra`,通过所选模型协议传递该推理档位。
64
+ - 默认图片生成模型由 `gemini-2.5-flash-image` 改为 `gemini-3.1-flash-image`。
65
+ - 本地图片附件和 Web 上传图片只加入附件清单,由模型按需调用 `read_file` 查看;
66
+ 网络图片仍可直接作为多模态输入。
67
+ - 运行时生成的开头 system prompt 不再写入历史、增量日志或返回的 messages。
68
+ 新会话及续跑均根据当前工作区和 Git 状态重新生成;兼容读取旧版带 system 前缀
69
+ 的历史,也支持直接续跑以 user 消息开头的官方历史。
70
+
71
+ ## [0.0.10-dev.5] - 2026-09-09
72
+
73
+ ### Agent Arena
74
+
75
+ - Agent Arena 引入按章节增量更新的 session memory,在后台更新记忆,达到上下文
76
+ 阈值时才回注;失败保留原上下文。默认新增对话更新阈值为 24,000 tokens,记忆
77
+ 输出上限为 131,072 tokens;Code Arena 继续使用原有完整摘要流程。
78
+ - 对齐 Agent Arena 文件分页的偏移、空白和 CRLF、沙箱文件创建行为,以及进程
79
+ 日志尾部的空行。bash 和进程工具使用历史对应的 C locale。
80
+ - 修复图片搜索结果的来源页面 URL、下载回退和历史选择结果;媒体工具保留工作区
81
+ 绝对路径。
82
+ - 网页搜索按深度返回 3 / 5 / 10 条结果,修复最高深度只返回 8 条的限制。
83
+ - 对齐仓库提示词变量、工作区快照和已关闭仓库会话的续跑处理。
84
+
85
+ ### Code Arena
86
+
87
+ - Code Arena 支持执行 `apply_patch`,包含新增、修改及删除文件;默认不向模型
88
+ 展示,设置 `CODE_HARNESS_APPLY_PATCH_TOOL=true` 后加入工具列表。
89
+ - Code Arena 文件编辑原样保留替换文本,容忍缩进差异;重复提交且替换
90
+ 内容已存在的编辑返回成功。`glob_files` 未传路径时使用工作区根目录;
91
+ `apply_patch` 的 Add File 内容不额外追加换行。
92
+
93
+ ## [0.0.10-dev.4] - 2026-09-03
94
+
95
+ ### Agent Arena
96
+
97
+ - 对齐 Agent Arena 大文本读取的整行首尾截断,以及 bash 与文件工具对真实路径、
98
+ `/tmp`、`/var/tmp` 的处理。
99
+
100
+ ### Code Arena
101
+
102
+ - 对齐 Code Arena 文件编辑匹配、文件读取与列表默认值、glob/grep 的返回及错误
103
+ 行为,并修复 Full Stack grep 的上下文分组。
104
+
105
+ ## [0.0.10-dev.3] - 2026-09-02
106
+
107
+ ### Code Arena
108
+
109
+ - React 初始模板更新 React、Vite 和 Node 类型依赖。
110
+
111
+ ### 通用
112
+
113
+ - CLI 支持 `--file <path>` 读取 UTF-8 提示词文件,与 `-p` / `--prompt` 互斥,
114
+ 方便传入超过命令行参数长度限制的提示词;两个命令入口和单文件二进制均可使用。
115
+
116
+ ## [0.0.10-dev.2] - 2026-08-31
117
+
118
+ ### Agent Arena
119
+
120
+ - 图片理解 fallback 可独立配置 base URL、API key 和协议,支持 Chat Completions、
121
+ Responses 及 Anthropic Messages;仅配置 fallback model 时仍继承主模型连接。
122
+
123
+ ### 通用
124
+
125
+ - Anthropic 流式工具调用收到空 delta 时保留已有 input,避免参数被清空。
126
+
127
+ ## [0.0.10-dev.1] - 2026-08-28
128
+
129
+ ### Agent Arena
130
+
131
+ - 对齐 Arena v2 工具参数校验、运行时错误和进程工具返回格式。
132
+
133
+ ### 通用
134
+
135
+ - headless 和 daemon 改为逐步追加 `history.json.journal.jsonl`,回合结束后再生成
136
+ `history.json`;异常退出可恢复已完成步骤。TUI 快照按消息流式序列化,避免长
137
+ 历史构造超大 JSON 字符串;SSE 缓存同时限制条数和字节量。
138
+
139
+ ## [0.0.10-dev.0] - 2026-08-28
140
+
141
+ ### Agent Arena
142
+
143
+ - 更新 Agent Arena v2 提示词和工具定义,工具从 11 个扩展为 15 个。
144
+ 新增 `start_process`、`get_process_output`、`stop_process` 管理跨调用后台
145
+ 进程,支持等待日志、端口或退出状态,并将进程日志写入 `.arena/processes/`。
146
+ - 新增 `add_voice` 音色注册及试听选择,`generate_speech` 使用稳定的 `voice_id`;
147
+ 无交互的 headless 模式可注册默认虚拟音色。
148
+ - headless 和 TUI 开放 `present_file` 工具,校验生成文件并返回工具结果。
149
+ - `bash` 用于一次性命令,区分超时与信号终止,并清理遗留后台进程;需要持续运行
150
+ 的任务改用进程工具。预览端口支持 E2B Host 探测及按需返回告警。
151
+
152
+ [Unreleased]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.7...master
153
+ [0.0.10-dev.7]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.6...v0.0.10-dev.7
154
+ [0.0.10-dev.6]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.5...v0.0.10-dev.6
155
+ [0.0.10-dev.5]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.4...v0.0.10-dev.5
156
+ [0.0.10-dev.4]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.3...v0.0.10-dev.4
157
+ [0.0.10-dev.3]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.2...v0.0.10-dev.3
158
+ [0.0.10-dev.2]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.1...v0.0.10-dev.2
159
+ [0.0.10-dev.1]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.10-dev.0...v0.0.10-dev.1
160
+ [0.0.10-dev.0]: https://gitlab.alibaba-inc.com/know-how/arena-harness/-/compare/v0.0.9-dev.34...v0.0.10-dev.0
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Arena CodeAgent Harness
2
2
 
3
+ 版本变化见 [Changelog](CHANGELOG.md),发布前请按[发版流程](docs/MODES_AND_RELEASES.md#发布节奏)
4
+ 更新变更记录并运行 `npm run check:changelog`。
5
+
3
6
  这是一个基于 `message.json` 与 `tools.json` 所定义消息和工具契约的 TypeScript
4
7
  CodeAgent harness。运行时只依赖 Node.js,不再依赖 Python:
5
8
 
@@ -111,9 +114,15 @@ arena serve --system-prompt '只使用中文回复。'
111
114
  ```
112
115
 
113
116
  该参数只在运行时覆盖第一条 system message,不会修改 canonical prompt fixture;
114
- 续跑已有 session 时,当前传入的值会替换历史中的 system message。未传参数时,
117
+ 续跑已有 session 时,使用当前参数重新生成运行时 system message。未传参数时,
115
118
  日期、workspace 和 mode 对应的现有 prompt 生成逻辑保持不变。
116
119
 
120
+ history.json、增量日志和返回的 messages 只保存对话历史(含 compaction),不保存运行时生成的开头 system;中途出现的 system 消息会保留。
121
+ 新会话和续跑均在构建模型请求时前置运行时 system;官方以 user 开头的历史可直接续跑。
122
+ 旧版带开头 system 的本地历史仍可读取,该旧前缀不作为本次指令,后续写入会移除它。
123
+ 每次运行(包括 resume)都会重新探测当前工作区和 Git 状态来填充仓库提示词,
124
+ 不从旧 system 或会话 metadata 恢复仓库信息;因此不同轮次的 system 可以变化。
125
+
117
126
  如需保留当前 mode 生成的 system prompt,只在末尾追加任务或部署指令,可传入
118
127
  `--append-system-prompt <text>`:
119
128
 
@@ -155,19 +164,13 @@ Messages,`gemini/` 使用 Google 的 OpenAI-compatible 接口;`openai/` 或
155
164
  无前缀模型使用 OpenAI 传输,其中模型名包含 `gpt`(大小写不敏感)时默认
156
165
  使用 Responses,其余使用 Chat Completions。无前缀且名称包含 `claude` 时
157
166
  使用 Anthropic Messages。显式 provider 前缀与 `ARENA_OPENAI_API` 始终优先。
158
- LiteLLM 官方提供 Python SDK 或独立 Proxy,因此
159
- 纯 TypeScript 版本使用
160
- [LiteLLM Proxy](https://docs.litellm.ai/) 作为多 provider 网关:
161
-
162
- ```bash
163
- export LITELLM_PROXY_URL=http://127.0.0.1:4000/v1
164
- export LITELLM_API_KEY=sk-litellm
165
- export OPENAI_MODEL=anthropic/claude-sonnet-4-20250514
166
- ```
167
+ 模型出口只有 Chat Completions、Responses API 和 Anthropic Messages 三种协议。
168
+ 端点和密钥统一使用 `OPENAI_BASE_URL` / `OPENAI_API_KEY`,兼容旧的
169
+ `ARENA_API_BASE` / `ARENA_API_KEY`。`LITELLM_PROXY_URL` 和 `LITELLM_API_KEY`
170
+ 已不再读取,即使仍在环境中也不会影响地址、认证、协议选择或参数格式。
171
+ provider 前缀用于选择协议,发送给服务端时会剥离。
167
172
 
168
- 设置 `LITELLM_PROXY_URL` 时,模型名会原样发送给 LiteLLM。没有 Proxy 时,
169
- 也支持直连:`openai/` 与 `gemini/` 前缀走各自的 OpenAI-compatibility 接口,
170
- `anthropic/` 前缀直接使用原生 Anthropic Messages 协议(`/v1/messages`):
173
+ 配置示例:
171
174
 
172
175
  ```bash
173
176
  # OpenAI
@@ -202,7 +205,7 @@ Anthropic Messages payload 并使用 `x-api-key`;OpenAI 路由根据上述规
202
205
  从而在不依赖 provider 端存储的情况下保留隐藏 reasoning。请求显式包含
203
206
  `reasoning.encrypted_content`;GPT-5.6 还会使用 `reasoning.context=all_turns`。
204
207
  设置 `ARENA_OPENAI_API=chat` 或 `responses` 可覆盖 GPT 的自动选择。
205
- 该开关不作用于 LiteLLM、Gemini 或 Anthropic 路由。如未设置统一入口,
208
+ 该开关不作用于 Gemini 或 Anthropic 路由。如未设置统一入口,
206
209
  Anthropic 可回退到 `ANTHROPIC_BASE_URL` /
207
210
  `ANTHROPIC_API_KEY`。
208
211
 
@@ -251,7 +254,7 @@ ARENA_COMPACTION_SUMMARY_MAX_TOKENS=131072
251
254
  ```
252
255
 
253
256
  可选的 `ARENA_REASONING_EFFORT` 支持 `low`、`medium`、`high`、`xhigh`
254
- 和 `max` 五档;Chat Completions 请求使用 `reasoning_effort`,Responses
257
+ 、`max` 和 `ultra` 六档;Chat Completions 请求使用 `reasoning_effort`,Responses
255
258
  请求使用 `reasoning.effort`,原生 Anthropic Messages 请求映射为
256
259
  `output_config.effort`。不会按模型静默
257
260
  降档;目标模型或兼容网关不支持所选档位时,由服务端返回明确错误。
@@ -290,11 +293,17 @@ Agent Arena 使用捕获的 session-memory 协议:只输出变化章节并合
290
293
  1500 tokens 时,下一次更新提示模型精简,不直接截断内容。
291
294
 
292
295
  主模型上下文通过新的 leading `<arena-system-message>` 回注记忆,最近完整的
293
- 模型/工具步骤保持原样。后台最新记忆暂存在内存;保存时将已回注的快照、覆盖位置和历史前缀摘要
294
- 写入现有 history 数据的 `session_memory` 字段;不创建独立 `.memory.json` 文件。
295
- 重启恢复时直接加载快照并接上未覆盖消息,不重新调用模型总结已有记忆。旧历史没有
296
- 快照或历史分支校验失败时,继续使用完整原始历史。`history.json.messages` 保持完整;
297
- 运行中的记忆更新使用现有增量 journal 记录,回合结束后合入 history.json。Agent Arena 记忆更新使用主模型、temperature=1、thinking
296
+ 模型/工具步骤保持原样。后台记忆只存在内存中,退出后丢弃。实际触发压缩时,
297
+ 在 `history.json.messages` 中插入官方 dump 形式的 `role: "compaction"` 记录:
298
+ 正文为 `content: [{type: "text", text: "摘要正文"}]`,`compaction` 包含 `ratio`、
299
+ `tokens_at_compaction` 和 `source`。普通消息格式不变,原始历史不删除。
300
+ 记录插在已覆盖前缀与保留步骤之间,其位置就是恢复边界,不另存覆盖索引或
301
+ `session_memory`。请求与 resume 使用系统提示词、最后一条未撤销压缩记录的摘要、
302
+ 以及其后的消息;`compaction` 角色只用于历史,不发送给模型。后台更新仍不会提前
303
+ 改变上下文。`undone: true` 的压缩记录不生效。
304
+ 这些字段及 `outer`/`inner` 值来自下载的官方 dump;本地将回合开始/工具循环内的
305
+ 压缩分别标为 `outer`/`inner`。token 数和比例使用本地估算,不代表已复刻官方计数。
306
+ Agent Arena 记忆更新使用主模型、temperature=1、thinking
298
307
  开启、thinking budget=81920,输出上限由 `ARENA_COMPACTION_SUMMARY_MAX_TOKENS`
299
308
  控制(默认 131072)。Code Arena 保留原有完整摘要实现,默认上限仍为 8192。
300
309
 
@@ -307,7 +316,7 @@ Responses 与其他协议一样,会在每个工具 step 前检查是否需要
307
316
  reasoning/function-call 状态都由本地 history 携带,压缩不再需要切断或重建 provider
308
317
  端 response 链。Agent Arena 压缩已归档的前缀,同时保留最新完整步骤里的
309
318
  加密 reasoning、function call 和 function output;下一次 Responses 请求直接回放这份
310
- 压缩后的本地上下文。持久化的原始 `history.json` 仍保持 append-only。
319
+ 压缩后的本地上下文;完整历史及压缩记录保存在 `history.json.messages`。
311
320
 
312
321
  每次模型请求都会通过 OpenAI-compatible 的 `stream_options.include_usage`
313
322
  请求 token 用量,并把服务端在最终 chunk 上报的 `usage` 对象原样记录到该轮
@@ -412,7 +421,7 @@ Arena 还维护一份有顺序的模型输入模态表,在第一次 HTTP 调
412
421
  为 fallback 设置完全独立的连接;协议支持 `openai-chat-completions`、
413
422
  `openai-responses` 和 `anthropic-messages`。例如 Anthropic 主模型可以把图片交给
414
423
  使用 OpenAI 兼容端点的 Gemini。任一独立连接参数出现后,fallback 不再继承主模型
415
- 的 base URL、认证、LiteLLM 路由或协议;未填写的连接项改用所选 provider 的标准
424
+ 的 base URL、认证或协议;未填写的连接项改用所选 provider 的标准
416
425
  环境变量与默认端点。仅配置 fallback model 时仍保持原有的主连接继承行为。
417
426
  fallback 不继承 `ARENA_EXTRA_BODY` 或主模型生成参数;原生 Anthropic Messages
418
427
  因协议要求会单独使用 `max_tokens: 16384`。
@@ -460,7 +469,8 @@ arena -p 'redraw this photo with the reference face' \
460
469
  每个附件会被保存到工作区 `uploads/`(模型内可通过
461
470
  `/home/user/uploads/<name>` 访问;重名自动加 `-2`、`-3` 后缀,URL 无扩展名
462
471
  时按图片字节特征补全扩展名)。本轮 user message 与 daemon 附件上传共用同
463
- 一构造逻辑,并使用统一的会话部件格式:图片部件
472
+ 一构造逻辑。本地图片只列入附件清单,由模型按需调用 `read_file` 查看;
473
+ 网络图片使用统一的会话部件格式:图片部件
464
474
  `{"image": ...}` 在前,随后是 prompt 文本 `{"text": ...}`,最后追加一条
465
475
  `<arena-system-message>`,列出保存到 `/home/user/uploads/` 的文件名。单条
466
476
  消息最多 10 个附件,单个附件上限 20 MB、总量上限 50 MB,与 daemon 一致。
@@ -469,9 +479,9 @@ arena -p 'redraw this photo with the reference face' \
469
479
  一律使用 `{"image": ...}` / `{"text": ...}` 原生部件并保持字段格式一致;仅在
470
480
  向模型发起 chat-completions 请求的边界处转换为
471
481
  OpenAI 风格的 `image_url` 部件。`--attach` 传 URL 时 `image` 直接记录该
472
- URL(模型服务端会自行下载;恢复历史上下文时要求该 URL 仍可访问);本地文件
473
- 没有可引用的 URL,`image` 存自包含的 base64
474
- data-URI。
482
+ URL(模型服务端会自行下载;恢复历史上下文时要求该 URL 仍可访问);若网络图片
483
+ 需要缩放或转码,则记录处理后的 Base64 data-URI。本地图片在 attach 时不生成
484
+ `image` 部件;后续 `read_file` 返回图片时仍可使用 Base64 data-URI。
475
485
 
476
486
  `stream-json` 每行一个 JSON 对象。`start`、`message`、`result` 事件中的
477
487
  `messages` 与输入样例保持相同契约:
@@ -716,9 +726,9 @@ message。未提供位置时,prompt 会明确标记位置不可用,不会使
716
726
  接口,并通过 URI 编码的 `x-file-name` header 传递文件名;再把返回的
717
727
  `attachment.path` 作为 `{ "type": "file", "path": "uploads/..." }`
718
728
  part 放入实时消息。每个文件最大 20 MB,每条消息最多 10 个文件、合计
719
- 50 MB。服务端会把文件写入该 session 的 `/home/user/uploads/` 映射目录,
720
- 图片作为 multimodal content 注入,并在 user message 最后追加
721
- `arena-system-message` 附件清单。附件引用只能指向本 session 的
729
+ 50 MB。服务端会把文件写入该 session 工作区的 `uploads/` 目录,
730
+ 并在 user message 最后追加 `arena-system-message` 附件清单。
731
+ 上传的图片由模型按需调用 `read_file` 查看。附件引用只能指向本 session 的
722
732
  `uploads/`,不能读取其他 workspace 路径或其他 session 的文件。
723
733
 
724
734
  SSE 支持 `Last-Event-ID` 断线续传,事件环同时受条数和字节预算约束,不缓存完整
@@ -746,7 +756,7 @@ retry 文件会删除。
746
756
  看到 WebUI 的 Retry 按钮:
747
757
 
748
758
  ```bash
749
- # 初始模型节点失败:失败后 history 只有 system/user;点一次 Retry 后成功
759
+ # 初始模型节点失败:失败后 history 只有 user;点一次 Retry 后成功
750
760
  ARENA_MODEL=mock/manual-retry-initial \
751
761
  ARENA_MODEL_RETRY_BASE_MS=0 ARENA_MODEL_RETRY_MAX_MS=0 npm run dev
752
762
 
@@ -841,8 +851,8 @@ Arena 的 `fetch_page` 和 Code Arena 的 `web_fetch` 默认仍使用本地抓
841
851
 
842
852
  `generate_image`、`generate_speech` 使用 ModelRouter/Routify,并从工作区
843
853
  `.env` 读取同一个 `ROUTIFY_API_KEY`。图片使用 Google 兼容协议调用;可用
844
- `ROUTIFY_VERTEX_BASE_URL` 覆盖默认根地址。语音使用 ModelRouter 的火山引擎
845
- `/protocol/volcengine/api/v1/tts` 路由,不需要新增服务密钥。
854
+ `ROUTIFY_VERTEX_BASE_URL` 覆盖默认根地址。语音默认也通过该 Google 协议
855
+ 调用 Gemini TTS,不需要新增服务密钥。
846
856
 
847
857
  `fetch_page` 使用 Defuddle 将 HTML 正文转换为 Markdown,并使用
848
858
  `pdf-parse` 提取 PDF 的前 30 页。响应按 Markdown 边界稳定分块,同一轮内
@@ -857,8 +867,8 @@ XLSX 仍可提取文字和表格内容,旧版 DOC、PPT、XLS 会先通过 Lib
857
867
  内容继续发送给模型。所有工具结果另有 1,000,000 字符的最终兜底。当前不做
858
868
  OCR,扫描版 PDF 只会返回无可提取文字的提示。
859
869
 
860
- 图片和语音的默认 ModelRouter 路由分别为 `gemini-2.5-flash-image` 和
861
- `doubao-tts`,可用 `ARENA_IMAGE_MODEL`、`ARENA_SPEECH_MODEL` 覆盖。图片生成结果和
870
+ 图片和语音的默认 ModelRouter 路由分别为 `gemini-3.1-flash-image` 和
871
+ `gemini-3.1-flash-tts-preview`,可用 `ARENA_IMAGE_MODEL`、`ARENA_SPEECH_MODEL` 覆盖。图片生成结果和
862
872
  搜索到的图片会立即下载到工作区;每次图片搜索的结果按生产命名保存为
863
873
  `image-search/<query slug>-<序号>.<扩展名>`,并作为可预览文件显示在 Web UI。
864
874
  语音生成先由 `add_voice` 生成两个试听候选并让用户选择,选择结果注册为稳定的
@@ -867,9 +877,12 @@ OCR,扫描版 PDF 只会返回无可提取文字的提示。
867
877
  它会按语言和 `voice_identity` 确定性注册一个默认音色,并在结果中以
868
878
  `virtual: true` 标记。返回的 `voice_id` 可直接用于后续 `generate_speech`。
869
879
  也可用
870
- `ARENA_SPEECH_VOICE` 强制覆盖底层音色。豆包响应中的 Base64 数据已经是 MP3、RIFF/WAV
871
- 或 Ogg Opus;`.ogg` 与 `.opus` 都保存 Ogg Opus 数据,所有支持的输出均不依赖
872
- 本地 `ffmpeg` 或 `lame`。
880
+ `ARENA_SPEECH_VOICE` 强制覆盖底层音色(例如 `Kore`)。Gemini 返回的 PCM 在内存中
881
+ 封装为 WAV;MP3 和 Ogg Opus 使用随包携带的精简静态 ffmpeg 转换。`.ogg` 与
882
+ `.opus` 都保存 Ogg Opus 数据。单文件发行版内嵌压缩转码器,npm 包携带平台资产;
883
+ 转换时释放到操作系统私有临时目录并在结束后清理,不搜索系统 ffmpeg、不运行时下载。
884
+ 显式设置 `ARENA_SPEECH_MODEL=doubao-tts` 可继续使用原火山引擎路由及豆包音色。
885
+ 从源码运行压缩语音前执行 `npm run prepare:audio`;发布打包会自动准备全部资产。
873
886
 
874
887
  所有路径工具都限制在 `--workspace` 内并检查符号链接逃逸。`bash` 是本机
875
888
  子进程,不是操作系统安全沙箱;多租户或不可信模型部署应使用容器或 VM。
package/dist/agent.d.ts CHANGED
@@ -15,7 +15,7 @@ interface AgentOptions {
15
15
  clientContext?: ClientContext;
16
16
  workspaceContext?: WorkspaceContext;
17
17
  onCheckpoint?: (messages: readonly Message[], tools: readonly ToolDefinition[]) => Promise<void>;
18
- /** Share across turns of one live session; history checkpoints may save its state. */
18
+ /** Share ephemeral background updates across turns of one live session. */
19
19
  sessionMemory?: SessionMemoryCache;
20
20
  onModelFailure?: (messages: readonly Message[], error: unknown) => void;
21
21
  /** Reuse immutable loaded history messages instead of cloning the full prefix. */
@@ -26,7 +26,7 @@ interface AgentRunOptions {
26
26
  userMessage?: UserTurnMessage;
27
27
  resumeFromHistory?: boolean;
28
28
  }
29
- export declare function resolveRepoContext(workspace: string, history?: Message[], mode?: HarnessMode): RepoContext | undefined;
29
+ export declare function resolveRepoContext(workspace: string, _history?: Message[], mode?: HarnessMode): RepoContext | undefined;
30
30
  export declare class Agent {
31
31
  private readonly config;
32
32
  private readonly sink;