@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.
- package/.env.example +19 -10
- package/CHANGELOG.md +160 -0
- package/README.md +50 -37
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +62 -96
- package/dist/agent.js.map +1 -1
- package/dist/anthropic.js +2 -0
- package/dist/anthropic.js.map +1 -1
- package/dist/ask-user.js +2 -0
- package/dist/ask-user.js.map +1 -1
- package/dist/attachments.js +4 -3
- package/dist/attachments.js.map +1 -1
- package/dist/cli.js +9 -8
- package/dist/cli.js.map +1 -1
- package/dist/code-tools.js +122 -30
- package/dist/code-tools.js.map +1 -1
- package/dist/compaction.d.ts +4 -2
- package/dist/compaction.js +37 -5
- package/dist/compaction.js.map +1 -1
- package/dist/config.d.ts +0 -2
- package/dist/config.js +2 -3
- package/dist/config.js.map +1 -1
- package/dist/file-edit.d.ts +2 -0
- package/dist/file-edit.js +9 -4
- package/dist/file-edit.js.map +1 -1
- package/dist/history.d.ts +7 -6
- package/dist/history.js +41 -46
- package/dist/history.js.map +1 -1
- package/dist/mode.js +3 -1
- package/dist/mode.js.map +1 -1
- package/dist/model-router-media.d.ts +1 -0
- package/dist/model-router-media.js +71 -1
- package/dist/model-router-media.js.map +1 -1
- package/dist/openai-responses.js +2 -0
- package/dist/openai-responses.js.map +1 -1
- package/dist/provider.d.ts +0 -1
- package/dist/provider.js +12 -41
- package/dist/provider.js.map +1 -1
- package/dist/replay-responses.d.ts +17 -0
- package/dist/replay-responses.js +100 -0
- package/dist/replay-responses.js.map +1 -0
- package/dist/routify-web-fetch.js +18 -4
- package/dist/routify-web-fetch.js.map +1 -1
- package/dist/server.js +7 -7
- package/dist/server.js.map +1 -1
- package/dist/spec.js +2 -0
- package/dist/spec.js.map +1 -1
- package/dist/speech-audio.d.ts +9 -0
- package/dist/speech-audio.js +130 -0
- package/dist/speech-audio.js.map +1 -0
- package/dist/speech-model.d.ts +3 -0
- package/dist/speech-model.js +8 -0
- package/dist/speech-model.js.map +1 -0
- package/dist/tools.js +81 -11
- package/dist/tools.js.map +1 -1
- package/dist/tui.js +6 -9
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +16 -2
- package/dist/voice-registry.d.ts +2 -0
- package/dist/voice-registry.js +10 -2
- package/dist/voice-registry.js.map +1 -1
- package/dist/web-fetch-output.d.ts +9 -0
- package/dist/web-fetch-output.js +38 -0
- package/dist/web-fetch-output.js.map +1 -0
- package/docs/BINARY_DISTRIBUTION.md +25 -16
- package/docs/MODES_AND_RELEASES.md +28 -5
- package/docs/SDK.md +4 -0
- package/package.json +9 -3
- package/scripts/README.md +62 -0
- package/scripts/check-changelog.mjs +66 -0
- package/vendor/audio/darwin-arm64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/darwin-arm64/LAME.LICENSE +481 -0
- package/vendor/audio/darwin-arm64/Opus.LICENSE +44 -0
- package/vendor/audio/darwin-arm64/ffmpeg.gz +0 -0
- package/vendor/audio/darwin-arm64/manifest.json +39 -0
- package/vendor/audio/darwin-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/darwin-x64/LAME.LICENSE +481 -0
- package/vendor/audio/darwin-x64/Opus.LICENSE +44 -0
- package/vendor/audio/darwin-x64/ffmpeg.gz +0 -0
- package/vendor/audio/darwin-x64/manifest.json +39 -0
- package/vendor/audio/linux-arm64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/linux-arm64/LAME.LICENSE +481 -0
- package/vendor/audio/linux-arm64/Opus.LICENSE +44 -0
- package/vendor/audio/linux-arm64/ffmpeg.gz +0 -0
- package/vendor/audio/linux-arm64/manifest.json +39 -0
- package/vendor/audio/linux-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/linux-x64/LAME.LICENSE +481 -0
- package/vendor/audio/linux-x64/Opus.LICENSE +44 -0
- package/vendor/audio/linux-x64/ffmpeg.gz +0 -0
- package/vendor/audio/linux-x64/manifest.json +39 -0
- package/vendor/audio/sources/build-audio-encoder.sh +76 -0
- package/vendor/audio/sources/ffmpeg-7.0.2.tar.xz +0 -0
- package/vendor/audio/sources/lame-3.100.tar.gz +0 -0
- package/vendor/audio/sources/opus-1.5.2.tar.gz +0 -0
- package/vendor/audio/sources/pkgconf-2.3.0.tar.xz +0 -0
- package/vendor/audio/sources/sources.lock.json +30 -0
- package/vendor/audio/win32-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/win32-x64/LAME.LICENSE +481 -0
- package/vendor/audio/win32-x64/Opus.LICENSE +44 -0
- package/vendor/audio/win32-x64/ffmpeg.gz +0 -0
- package/vendor/audio/win32-x64/manifest.json +39 -0
package/dist/voice-registry.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface VoiceAuditionCandidate {
|
|
|
7
7
|
export interface VoiceBattle {
|
|
8
8
|
battleId: string;
|
|
9
9
|
candidates: VoiceAuditionCandidate[];
|
|
10
|
+
model?: string;
|
|
10
11
|
language: string;
|
|
11
12
|
}
|
|
12
13
|
export interface RegisteredVoiceSelection {
|
|
@@ -16,6 +17,7 @@ export interface RegisteredVoiceSelection {
|
|
|
16
17
|
interface RegisteredVoice {
|
|
17
18
|
language: string;
|
|
18
19
|
providerVoice: string;
|
|
20
|
+
model: string;
|
|
19
21
|
}
|
|
20
22
|
export declare class VoiceRegistry {
|
|
21
23
|
private battleSequence;
|
package/dist/voice-registry.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { generateSpeechWithModelRouter } from "./model-router-media.js";
|
|
2
|
+
import { isGeminiSpeechModel, speechModel } from "./speech-model.js";
|
|
2
3
|
const registries = new Map();
|
|
3
4
|
function primaryLanguage(language) {
|
|
4
5
|
return language.toLowerCase().split(/[-_]/)[0] || "";
|
|
5
6
|
}
|
|
6
7
|
function voiceCatalog(language, gender) {
|
|
7
8
|
const masculine = gender === "masculine";
|
|
9
|
+
if (isGeminiSpeechModel(speechModel())) {
|
|
10
|
+
return masculine ? ["Puck", "Charon"] : ["Kore", "Aoede"];
|
|
11
|
+
}
|
|
8
12
|
if (primaryLanguage(language) === "en") {
|
|
9
13
|
return masculine
|
|
10
14
|
? ["en_male_tim_uranus_bigtts", "zh_male_m191_uranus_bigtts"]
|
|
@@ -31,9 +35,11 @@ export class VoiceRegistry {
|
|
|
31
35
|
async audition(text, language, voiceIdentity = {}, signal) {
|
|
32
36
|
const battleId = this.nextBattleId();
|
|
33
37
|
const voices = selectedVoices(language, voiceIdentity);
|
|
38
|
+
const model = speechModel();
|
|
34
39
|
const audio = await Promise.all(voices.map((voice) => generateSpeechWithModelRouter({
|
|
35
40
|
format: "mp3",
|
|
36
|
-
model
|
|
41
|
+
model,
|
|
42
|
+
language,
|
|
37
43
|
signal,
|
|
38
44
|
text,
|
|
39
45
|
voice,
|
|
@@ -41,6 +47,7 @@ export class VoiceRegistry {
|
|
|
41
47
|
return {
|
|
42
48
|
battleId,
|
|
43
49
|
language,
|
|
50
|
+
model,
|
|
44
51
|
candidates: voices.map((providerVoice, index) => ({
|
|
45
52
|
id: `candidate-${index + 1}`,
|
|
46
53
|
label: `Voice ${index + 1}`,
|
|
@@ -57,6 +64,7 @@ export class VoiceRegistry {
|
|
|
57
64
|
this.voices.set(voiceId, {
|
|
58
65
|
language: battle.language,
|
|
59
66
|
providerVoice: candidate.providerVoice,
|
|
67
|
+
model: battle.model || speechModel(),
|
|
60
68
|
});
|
|
61
69
|
return voiceId;
|
|
62
70
|
}
|
|
@@ -64,7 +72,7 @@ export class VoiceRegistry {
|
|
|
64
72
|
const battleId = this.nextBattleId();
|
|
65
73
|
const voiceId = `voice-${battleId}`;
|
|
66
74
|
const providerVoice = selectedVoices(language, voiceIdentity)[0];
|
|
67
|
-
this.voices.set(voiceId, { language, providerVoice });
|
|
75
|
+
this.voices.set(voiceId, { language, providerVoice, model: speechModel() });
|
|
68
76
|
return { battleId, voiceId };
|
|
69
77
|
}
|
|
70
78
|
resolve(voiceId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-registry.js","sourceRoot":"","sources":["../src/voice-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"voice-registry.js","sourceRoot":"","sources":["../src/voice-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const defaultMaxBytes = 40_000;
|
|
2
|
+
const maxTitleBytes = 512;
|
|
3
|
+
function configuredMaxBytes() {
|
|
4
|
+
const value = process.env.CODE_HARNESS_WEB_FETCH_MAX_BYTES?.trim() || "";
|
|
5
|
+
const parsed = /^\d+$/.test(value) ? Number(value) : NaN;
|
|
6
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : defaultMaxBytes;
|
|
7
|
+
}
|
|
8
|
+
export function truncateCodeArenaText(value, maxBytes = defaultMaxBytes) {
|
|
9
|
+
const bytes = Buffer.from(value, "utf8");
|
|
10
|
+
if (bytes.length <= maxBytes)
|
|
11
|
+
return value;
|
|
12
|
+
// Captures retain ~40 KB with symmetric head/tail and this marker. The
|
|
13
|
+
// omitted-token count is an estimate (UTF-8 bytes / 4), not model tokenization.
|
|
14
|
+
const omittedTokens = Math.ceil((bytes.length - maxBytes) / 4);
|
|
15
|
+
let notice = `\n…${omittedTokens} tokens truncated…\n`;
|
|
16
|
+
if (Buffer.byteLength(notice) > maxBytes)
|
|
17
|
+
notice = maxBytes >= 3 ? "…" : ".";
|
|
18
|
+
const half = Math.floor((maxBytes - Buffer.byteLength(notice)) / 2);
|
|
19
|
+
let headEnd = half;
|
|
20
|
+
let tailStart = bytes.length - half;
|
|
21
|
+
// Move cut points inward to preserve complete UTF-8 characters and the bound.
|
|
22
|
+
while (headEnd > 0 && (bytes[headEnd] & 0xc0) === 0x80)
|
|
23
|
+
headEnd -= 1;
|
|
24
|
+
while (tailStart < bytes.length && (bytes[tailStart] & 0xc0) === 0x80)
|
|
25
|
+
tailStart += 1;
|
|
26
|
+
return bytes.subarray(0, headEnd).toString("utf8") + notice +
|
|
27
|
+
bytes.subarray(tailStart).toString("utf8");
|
|
28
|
+
}
|
|
29
|
+
// Apply at the Code Arena tool boundary so local and Routify readers share the
|
|
30
|
+
// same bound. Agent Arena fetch_page retains its full, separately paged cache.
|
|
31
|
+
export function boundedWebFetchResult(result) {
|
|
32
|
+
return {
|
|
33
|
+
status: "success",
|
|
34
|
+
title: truncateCodeArenaText(String(result.title || "No Title Found"), maxTitleBytes),
|
|
35
|
+
content: truncateCodeArenaText(String(result.content || ""), configuredMaxBytes()),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=web-fetch-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-fetch-output.js","sourceRoot":"","sources":["../src/web-fetch-output.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,SAAS,kBAAkB;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzD,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,QAAQ,GAAG,eAAe;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3C,uEAAuE;IACvE,gFAAgF;IAChF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,MAAM,GAAG,MAAM,aAAa,sBAAsB,CAAC;IACvD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,QAAQ;QAAE,MAAM,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IACpC,8EAA8E;IAC9E,OAAO,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAE,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC;IACtE,OAAO,SAAS,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAE,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,SAAS,IAAI,CAAC,CAAC;IACvF,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM;QACzD,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,+EAA+E;AAC/E,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB,CAAC,MAGrC;IACC,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,gBAAgB,CAAC,EAAE,aAAa,CAAC;QACrF,OAAO,EAAE,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC;KACnF,CAAC;AACJ,CAAC"}
|
|
@@ -102,9 +102,9 @@ npm run package:binary
|
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
默认命令构建当前 runner 的系统、CPU 和 libc。CI 还支持在 Linux x64 上按 Node
|
|
105
|
-
SEA
|
|
105
|
+
SEA 跨平台流程生成四个发布目标:`linux-x64` 固定下载完全相同版本的 Node.js
|
|
106
106
|
unofficial-builds glibc 2.17 Runtime,`linux-x64-musl` 下载 unofficial-builds
|
|
107
|
-
musl Runtime,`darwin-x64`
|
|
107
|
+
musl Runtime,`darwin-arm64` 和 `darwin-x64` 下载对应架构的官方 macOS Runtime。四者都通过 Aone 可访问的
|
|
108
108
|
npmmirror 二进制镜像下载,并校验对应的
|
|
109
109
|
`SHASUMS256.txt`,关闭 code cache/snapshot 后注入 SEA blob。
|
|
110
110
|
macOS 产物再使用固定版本和 checksum 的 `rcodesign` 做 ad-hoc 签名。Aone 从仓库的
|
|
@@ -134,29 +134,33 @@ node scripts/package-binaries.mjs \
|
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
CI 应构建并汇总 `build/npm/packages/<target>`。原生 Runtime 通常应在对应环境中
|
|
137
|
-
构建;禁用 SEA snapshot/code cache 后,`linux-x64`、`linux-x64-musl
|
|
138
|
-
`darwin-x64` 都可以在 Linux x64 Runner 上使用经过校验的目标 Node Runtime
|
|
137
|
+
构建;禁用 SEA snapshot/code cache 后,`linux-x64`、`linux-x64-musl`、
|
|
138
|
+
`darwin-arm64` 和 `darwin-x64` 都可以在 Linux x64 Runner 上使用经过校验的目标 Node Runtime
|
|
139
139
|
组装。
|
|
140
140
|
|
|
141
141
|
本仓库使用 Aone CI,流水线定义在
|
|
142
142
|
[`/.aoneci/arena-binaries.yaml`](../.aoneci/arena-binaries.yaml)。当前项目没有关联
|
|
143
143
|
自托管 Runner 组,因此流水线优先使用 Aone 托管的 Linux amd64 资源构建
|
|
144
|
-
`linux-x64`,并交叉构建 `linux-x64-musl` 和 `darwin-x64`。推送与根
|
|
144
|
+
`linux-x64`,并交叉构建 `linux-x64-musl`、`darwin-arm64` 和 `darwin-x64`。推送与根
|
|
145
145
|
`package.json` 版本完全一致的 `v<semver>` Tag 时会自动运行,并在同一批次
|
|
146
|
-
|
|
146
|
+
发布这四个平台包、`@qwen-code/arena-agent` 和
|
|
147
147
|
`@qwen-code/arena-cli`;后两个包都包含四种模式和两个命令入口。普通分支 push
|
|
148
148
|
不触发,手动运行只构建、不发布。发布前
|
|
149
149
|
需要在“设置 → 持续集成 → 变量管理”中添加名为 `NPM_TOKEN` 的 Secret。
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
每次发布前先按[发版流程](MODES_AND_RELEASES.md#发布节奏)更新
|
|
152
|
+
[`CHANGELOG.md`](../CHANGELOG.md)。以下以新的预发布版 `0.0.10-dev.7` 为例,
|
|
153
|
+
发布脚本自动使用 npm `dev` tag:
|
|
152
154
|
|
|
153
155
|
```bash
|
|
154
|
-
npm version 0.0.10-dev.
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
npm version 0.0.10-dev.7 --no-git-tag-version
|
|
157
|
+
# 将本次变更整理到 CHANGELOG.md 的 0.0.10-dev.7 条目,填写日期并更新比较链接
|
|
158
|
+
npm run check:changelog
|
|
159
|
+
git add package.json package-lock.json CHANGELOG.md
|
|
160
|
+
git commit -m "chore: release 0.0.10-dev.7"
|
|
157
161
|
git push origin master
|
|
158
|
-
git tag v0.0.10-dev.
|
|
159
|
-
git push origin v0.0.10-dev.
|
|
162
|
+
git tag v0.0.10-dev.7
|
|
163
|
+
git push origin v0.0.10-dev.7
|
|
160
164
|
```
|
|
161
165
|
|
|
162
166
|
正式版同理,例如 `package.json` 为 `0.0.10` 时推送 `v0.0.10`,发布脚本会自动
|
|
@@ -164,16 +168,21 @@ git push origin v0.0.10-dev.1
|
|
|
164
168
|
发布到 npm。首次稳定版发布前请显式使用 `@dev` 或完整版本号;首个正式版本发布后
|
|
165
169
|
才把无版本安装渠道作为稳定入口。
|
|
166
170
|
|
|
167
|
-
Aone 官方不提供 Windows/macOS
|
|
171
|
+
Aone 官方不提供 Windows/macOS 托管资源;macOS 两个架构通过上述交叉构建覆盖。
|
|
168
172
|
Linux arm64 的两个平台包暂不参与自动发布,以免非关键 ARM64 Job 阻塞 x64
|
|
169
|
-
|
|
170
|
-
组。
|
|
173
|
+
发布。Windows 包仍需要关联对应的 self-hosted Runner 组。
|
|
171
174
|
|
|
172
175
|
## 发布
|
|
173
176
|
|
|
177
|
+
发布前必须有与根 `package.json` 版本一致、带有效日期及实际变更条目的 changelog,
|
|
178
|
+
并按 Agent Arena、Code Arena、通用分别记录变更。
|
|
179
|
+
`npm publish` 和多平台发布脚本均执行此检查,缺失时立即失败;多平台脚本在发布
|
|
180
|
+
第一个平台包前检查,避免只发布部分包后才发现变更记录缺失。
|
|
181
|
+
|
|
174
182
|
汇总全部 7 个平台包目录后,重新生成一次入口包并进行发布前检查:
|
|
175
183
|
|
|
176
184
|
```bash
|
|
185
|
+
npm run check:changelog
|
|
177
186
|
npm run package:binary:cli
|
|
178
187
|
npm run publish:binaries -- --dry-run --tag dev
|
|
179
188
|
```
|
|
@@ -201,7 +210,7 @@ SEA 产物内含目标平台的 Node.js 可执行文件,因此需要为每种
|
|
|
201
210
|
- Linux arm64/x64 的 glibc 与 musl
|
|
202
211
|
- Windows x64
|
|
203
212
|
|
|
204
|
-
|
|
213
|
+
除流水线已覆盖的四个发布目标外,其他目标应在对应操作系统和 CPU 架构的
|
|
205
214
|
构建机或 CI runner 上执行。
|
|
206
215
|
|
|
207
216
|
“业务机不需要 Node.js 20+”不等于“二进制不受 Node.js 20 的系统要求影响”。
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
agent loop、compaction、history、metrics、CLI/TUI/server 和 SDK。
|
|
9
9
|
- 模式边界只包含 system prompt、工具 schema/实现以及可选 scaffold。
|
|
10
10
|
- 四种模式使用同一个版本号一起演进,避免两份 agent loop 再次漂移。
|
|
11
|
-
- JavaScript/SDK 包与 SEA
|
|
11
|
+
- JavaScript/SDK 包与 SEA 二进制包是两种分发形式,共用发布版本;
|
|
12
12
|
它们不是两套产品源码,也不要求 npm workspaces。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
@@ -89,10 +89,30 @@ arena --mode full-stack -p '...'
|
|
|
89
89
|
|
|
90
90
|
## 发布节奏
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
每次发布(包括 dev 预发布)都必须先更新根目录的
|
|
93
|
+
[`CHANGELOG.md`](../CHANGELOG.md),并与版本号修改一起提交:
|
|
94
|
+
|
|
95
|
+
1. 将 `Unreleased` 中本次要发布的变更整理为 `## [版本号] - YYYY-MM-DD`,
|
|
96
|
+
版本号与 `package.json` 完全一致,并说明配置迁移。每个版本及 `Unreleased`
|
|
97
|
+
内按 `### Agent Arena`、`### Code Arena`、`### 通用` 分组;两类 Arena 的专属
|
|
98
|
+
变更分别记录,共用运行时、模型连接和 CLI 变化只写在通用部分。无变更的
|
|
99
|
+
分类省略,分类内可按需用四级标题区分新增、变更、修复。
|
|
100
|
+
2. 保留顶部 `## [Unreleased]` 供后续记录,更新新版本及 `Unreleased` 的比较链接。
|
|
101
|
+
3. 完成下面的发布检查,再提交版本变更和 changelog、推送匹配的 `v<version>` 标签。
|
|
102
|
+
|
|
103
|
+
Changelog 只记录用户使用 CLI 时能感知的功能、行为、修复、配置、安装兼容性和
|
|
104
|
+
迁移要求。内部技能、回放与审计工具、报告、测试、发布流程维护、源码归档及
|
|
105
|
+
构建下载诊断不写入 changelog。
|
|
106
|
+
|
|
107
|
+
`npm run check:changelog` 校验最新版本条目、有效日期和非空变更内容。
|
|
108
|
+
直接 `npm publish` 会通过 `prepublishOnly` 执行检查;多平台发布脚本(含 dry-run)
|
|
109
|
+
也会在任何包发布前执行检查,Aone 标签发布走同一入口。
|
|
110
|
+
|
|
111
|
+
四种模式一起发布。Agent、CLI 和所支持的平台包必须使用同一版本;只发布
|
|
112
|
+
JavaScript/SDK 包不算发版完成。检查及打包顺序:
|
|
94
113
|
|
|
95
114
|
```bash
|
|
115
|
+
npm run check:changelog
|
|
96
116
|
npm run typecheck
|
|
97
117
|
npm test
|
|
98
118
|
npm pack --dry-run
|
|
@@ -105,8 +125,11 @@ npm run package:binary:cli
|
|
|
105
125
|
npm run publish:binaries -- --dry-run
|
|
106
126
|
```
|
|
107
127
|
|
|
108
|
-
平台包必须先于 `@qwen-code/arena-cli`
|
|
109
|
-
|
|
128
|
+
平台包必须先于 `@qwen-code/arena-cli` 发布。推送标签后,核验 Agent、CLI 和所有
|
|
129
|
+
受支持平台包的 exact-version npm 查询,至少覆盖 `darwin-arm64`、`darwin-x64`、
|
|
130
|
+
`linux-x64`、`linux-x64-musl`,并用该完整版本号的 `install.sh` 做端到端烟测。
|
|
131
|
+
预发布还需确认相关包的 `dev` dist-tag 均指向最新预发布版本。
|
|
132
|
+
完整矩阵及发布命令见 [`BINARY_DISTRIBUTION.md`](BINARY_DISTRIBUTION.md)。
|
|
110
133
|
|
|
111
134
|
## 原 Code Harness 的迁移边界
|
|
112
135
|
|
package/docs/SDK.md
CHANGED
|
@@ -173,6 +173,10 @@ console.log(history.activePrompt);
|
|
|
173
173
|
`getHistory()` 同时会设置 SSE 续传需要的 `lastEventId`。恢复后再调用
|
|
174
174
|
`run()`、`stream()` 或 `connect()` 即可继续。
|
|
175
175
|
|
|
176
|
+
`history.messages` 与运行结果的 `messages` 只包含对话历史(含 compaction),
|
|
177
|
+
不包含运行时生成的开头 system;中途的 system 消息仍会保留。服务端在每次运行时
|
|
178
|
+
按当前配置生成开头 system,并只将它加入模型请求。
|
|
179
|
+
|
|
176
180
|
当前服务端还没有用户账号维度的 `sessions.list()`/`sessions.open()`。
|
|
177
181
|
跨设备登录应由服务端把 session 绑定到可信的 `userId`,并在用户登录后重新
|
|
178
182
|
签发短期 session token,而不是在设备之间同步旧 token。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qwen-code/arena-agent",
|
|
3
|
-
"version": "0.0.10-dev.
|
|
3
|
+
"version": "0.0.10-dev.7",
|
|
4
4
|
"description": "A four-mode TypeScript agent harness for Arena and Code Arena traces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/sdk.d.ts",
|
|
@@ -29,7 +29,10 @@
|
|
|
29
29
|
"docs/BINARY_DISTRIBUTION.md",
|
|
30
30
|
"modes",
|
|
31
31
|
"web",
|
|
32
|
+
"vendor/audio",
|
|
32
33
|
"README.md",
|
|
34
|
+
"CHANGELOG.md",
|
|
35
|
+
"scripts/check-changelog.mjs",
|
|
33
36
|
".env.example"
|
|
34
37
|
],
|
|
35
38
|
"engines": {
|
|
@@ -46,11 +49,14 @@
|
|
|
46
49
|
"package:binary:platform": "npm run build:binary && node scripts/package-binaries.mjs --skip-cli",
|
|
47
50
|
"package:binary:cli": "node scripts/package-binaries.mjs --cli-only",
|
|
48
51
|
"publish:binaries": "node scripts/publish-binaries.mjs",
|
|
52
|
+
"check:changelog": "node scripts/check-changelog.mjs",
|
|
53
|
+
"prepublishOnly": "npm run check:changelog",
|
|
49
54
|
"dev": "tsx src/cli.ts serve",
|
|
50
55
|
"tui": "tsx src/cli.ts tui",
|
|
51
|
-
"
|
|
56
|
+
"prepare:audio": "node scripts/prepare-audio.mjs",
|
|
57
|
+
"prepack": "npm run build && node scripts/prepare-audio.mjs --all",
|
|
52
58
|
"start": "node dist/cli.js serve",
|
|
53
|
-
"pretest": "npm run build",
|
|
59
|
+
"pretest": "npm run build && npm run prepare:audio",
|
|
54
60
|
"test": "tsx --test test/*.test.ts",
|
|
55
61
|
"test:tool-replay": "ARENA_TOOL_REPLAY_TESTS=1 tsx --test test/tool-replay.test.ts",
|
|
56
62
|
"scaffolds:validate-inputs": "tsx scripts/validate-scaffold-inputs.ts",
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# 轨迹复刻脚本
|
|
2
|
+
|
|
3
|
+
本目录保存 DataWorks SQL Arena 轨迹数据的复刻与环境准备脚本。数据集位于
|
|
4
|
+
`tasks/`,运行产物位于 `tasks/reproductions/`。
|
|
5
|
+
|
|
6
|
+
## 通用脚本
|
|
7
|
+
|
|
8
|
+
`reproduce_case.mjs` 运行单个 case,`reproduce_all.mjs`
|
|
9
|
+
批量运行数据集中标记为可复刻的 case。
|
|
10
|
+
|
|
11
|
+
每个 case 可以通过可选的 `prepare.json` 声明运行前环境准备。没有配置时
|
|
12
|
+
prepare phase 是 no-op;存在配置时,单任务和批量入口都会在调用模型前自动
|
|
13
|
+
执行并校验。当前支持固定 Git commit、从原始 history 恢复附件和文件断言。
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# 单个 case;默认数据集可省略 --dataset
|
|
17
|
+
node scripts/reproduce_case.mjs --case 010
|
|
18
|
+
|
|
19
|
+
# 指定其他数据集
|
|
20
|
+
node scripts/reproduce_case.mjs \
|
|
21
|
+
--dataset /path/to/dataset \
|
|
22
|
+
--case 010
|
|
23
|
+
|
|
24
|
+
# 以 5 个并发运行全部可复刻 case
|
|
25
|
+
node scripts/reproduce_all.mjs \
|
|
26
|
+
--dataset /path/to/dataset \
|
|
27
|
+
--concurrency 5
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
单独验证某个 prepare 配置,不调用模型:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
node scripts/prepare_workspace.mjs \
|
|
34
|
+
--case-dir /path/to/dataset/cases/case-xxx \
|
|
35
|
+
--workspace /path/to/empty/workspace
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
脚本读取项目根目录 `.env` 中的 `ARENA_API_MODEL`、`OPENAI_BASE_URL` 和
|
|
39
|
+
`OPENAI_API_KEY`。固定生成参数由数据集自身的 `reproduction.config.json`
|
|
40
|
+
提供。
|
|
41
|
+
|
|
42
|
+
批量入口具有以下行为:
|
|
43
|
+
|
|
44
|
+
- 每个失败 case 自动重试一次。
|
|
45
|
+
- 第一次失败后删除该次失败目录。
|
|
46
|
+
- 成功或最终失败后,只保留该 case 最新的最终运行目录。
|
|
47
|
+
- prepare 失败时不会调用模型,错误会写入该次 `result.json`。
|
|
48
|
+
- 单次运行默认 60 分钟超时,可通过 `--timeout-minutes` 或
|
|
49
|
+
`ARENA_REPRO_TIMEOUT_MINUTES` 调整。
|
|
50
|
+
- `--case` 的退出码只反映本次指定 case,不受历史失败记录影响。
|
|
51
|
+
- `--clean` 仅在数据集清单和可复刻性审计验证通过后清理
|
|
52
|
+
`reproductions/`。
|
|
53
|
+
|
|
54
|
+
完整清理后重新运行:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
node scripts/reproduce_all.mjs \
|
|
58
|
+
--dataset /path/to/dataset \
|
|
59
|
+
--concurrency 5 \
|
|
60
|
+
--timeout-minutes 60 \
|
|
61
|
+
--clean
|
|
62
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
6
|
+
|
|
7
|
+
export function checkChangelog(directory = root) {
|
|
8
|
+
const { version } = JSON.parse(
|
|
9
|
+
readFileSync(path.join(directory, "package.json"), "utf8"),
|
|
10
|
+
);
|
|
11
|
+
const fail = (message) => {
|
|
12
|
+
throw new Error(`CHANGELOG.md: ${message}. Update the changelog before releasing ${version}.`);
|
|
13
|
+
};
|
|
14
|
+
let changelog;
|
|
15
|
+
try {
|
|
16
|
+
changelog = readFileSync(path.join(directory, "CHANGELOG.md"), "utf8");
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error.code === "ENOENT") fail("file is missing");
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
// Examples and comments are not release notes.
|
|
22
|
+
const content = changelog
|
|
23
|
+
.replace(/<!--[^]*?-->/g, "")
|
|
24
|
+
.replace(/^(`{3,}|~{3,})[^\n]*\n[^]*?^\1[^\S\r\n]*$/gm, "");
|
|
25
|
+
const sections = [...content.matchAll(/^##[ \t]+(.+?)[ \t]*\r?$/gm)];
|
|
26
|
+
if (sections[0]?.[1] !== "[Unreleased]") {
|
|
27
|
+
fail("the first section must be ## [Unreleased]");
|
|
28
|
+
}
|
|
29
|
+
if (sections.filter((section) => section[1] === "[Unreleased]").length !== 1) {
|
|
30
|
+
fail("Unreleased must appear exactly once");
|
|
31
|
+
}
|
|
32
|
+
const currentSections = sections.filter((section) =>
|
|
33
|
+
section[1].startsWith(`[${version}]`),
|
|
34
|
+
);
|
|
35
|
+
if (currentSections.length !== 1 || currentSections[0] !== sections[1]) {
|
|
36
|
+
fail(`the newest release section must be a single ## [${version}] - YYYY-MM-DD`);
|
|
37
|
+
}
|
|
38
|
+
const current = currentSections[0];
|
|
39
|
+
const date = current[1].slice(`[${version}] - `.length);
|
|
40
|
+
if (
|
|
41
|
+
current[1] !== `[${version}] - ${date}` ||
|
|
42
|
+
!/^\d{4}-\d{2}-\d{2}$/.test(date) ||
|
|
43
|
+
!Number.isFinite(Date.parse(`${date}T00:00:00Z`)) ||
|
|
44
|
+
new Date(`${date}T00:00:00Z`).toISOString().slice(0, 10) !== date
|
|
45
|
+
) {
|
|
46
|
+
fail(`release ${version} needs a valid date in YYYY-MM-DD format`);
|
|
47
|
+
}
|
|
48
|
+
const body = content.slice(current.index + current[0].length, sections[2]?.index);
|
|
49
|
+
const entries = [...body.matchAll(/^[-*][ \t]+(.+?)\r?$/gm)];
|
|
50
|
+
if (!entries.some((entry) =>
|
|
51
|
+
/[\p{L}\p{N}]/u.test(entry[1]) &&
|
|
52
|
+
!/^(?:TODO|TBD|待补充|待填写|暂无)(?:[\s::.!!。…-]|$)/i.test(entry[1]),
|
|
53
|
+
)) {
|
|
54
|
+
fail(`release ${version} needs at least one non-placeholder change entry`);
|
|
55
|
+
}
|
|
56
|
+
return version;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
60
|
+
try {
|
|
61
|
+
console.log(`Changelog ready for ${checkChangelog()}`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(error.message);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
}
|