合并:把 origin/master 并入回合错误重构分支并保留双方行为

- 解决 direct_runtime/mod.rs 冲突:保留本分支 typed 回合错误重构(TurnError/EnqueueError 与 record_direct_codex_failure_facts 拆分),接入 master 的诊断 v3 口径(persist_agent_runtime_error 新签名 + typed error 字段)、prompt 反馈改截断不脱敏、项目写锁改名
- 解决 thread_manager/dispatch.rs 冲突:保留本分支 TurnError/TurnCompletion 换代与 finish_turn_failure 分类层,接住 master 的 tt= 日志改名与 cc 执行器整轮成功后补写 completed 终态
- 解决 direct_tools_mcp.rs 冲突:采用 master 版(本分支唯一改动是 external MCP 容量测试读 body,master 已有等价实现)
- 处理 direct_turn_failure.rs 删除/修改冲突:维持本分支删除,把 completed() 语义迁进 TurnCompletion::Completed 并补回对应测试
- 处理 runtime_driver/entrypoints.rs 修改/删除冲突:接受 master 退役自建 Agent Runtime 的删除(本分支只在该文件做 direct_now_ms 改名)
- 合并 decision-log.md:双方条目都保留
- 修复 auto-merge 漏掉的语义冲突:claude_code_cli.rs 的 direct_now_ms() 改名 now_ms();诊断测试改为断言 AGENT_RUNTIME_ERROR_SCHEMA_VERSION、detail 字段改 message;record_direct_codex_failure_facts 新增 typed_error 入参(TurnError 不序列化,落盘用 classify 投影出的 TurnFailure)
This commit is contained in:
2026-10-03 13:12:10 +08:00
372 changed files with 13835 additions and 241829 deletions
-6
View File
@@ -120,12 +120,6 @@ echo '[rust-cache] warming AGC Rust lanes'
cargo test --locked --manifest-path Cargo.toml \
--bin genarrative-ai-game-creator-shell --no-run
)
cargo clean --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml
echo '[rust-cache] warming AGC agent-run smoke executable'
(
cd apps/ai-game-creator-shell
cargo build --manifest-path src-tauri/Cargo.toml
)
du -sh /opt/genarrative-ci/rust-cache/objects
WARM
docker cp "${container_id}:/opt/genarrative-ci/rust-cache/." "${work_dir}/snapshot/"
-11
View File
@@ -78,8 +78,6 @@ const aiGameCreatorViteConfigSource = fs.readFileSync(
// - agc-rust-shard-1..4:AGC 壳自身的 Rust bin target 单测,按名单切成 4 片,片内仍保持
// `--test-threads=1`;CI 由两条 lane job 各顺序运行两片,每个分片分组都会做一次
// 「片并集等于全集且互斥」的自校验。
// - agc-rust-smoke:会用 `src-tauri/Cargo.toml` spawn `cargo run` 的 agent-run smoke。
// 与分片分开,免得把已经压到 4 分钟级的片 job 拖长。
// - release:发布构建 smoke 和依赖发布产物的落盘断言。
const nativeShellGateGroups = [
'contract',
@@ -90,7 +88,6 @@ const nativeShellGateGroups = [
'agc-rust-shard-2',
'agc-rust-shard-3',
'agc-rust-shard-4',
'agc-rust-smoke',
'release',
];
const requestedNativeShellGroups = readRequestedNativeShellGroups(
@@ -2396,14 +2393,6 @@ const steps = [
'--shard-index=4',
],
},
// agent-run smoke 会用 `src-tauri/Cargo.toml` spawn `cargo run`,因此单独一个分组,
// 落在同样预热了 AGC 壳 Cargo 依赖的 job 里。
{
group: 'agc-rust-smoke',
label: 'ai-game-creator-shell-agent-run-smoke',
command: npmCommand,
args: ['run', 'ai-game-creator-shell:agent-run:smoke'],
},
{
group: 'release',
label: 'ai-game-creator-shell-release-build-smoke',
-1
View File
@@ -26,7 +26,6 @@ CHUNK_BYTES = 8 * 1024**2
JOBS = {
"ai-game-creator-shell-rust-lane-1",
"ai-game-creator-shell-rust-lane-2",
"ai-game-creator-shell-rust-smoke",
"ai-game-creator-shell-rust-crates",
"backend-tests",
"native-shell-tests",
-1
View File
@@ -11,7 +11,6 @@ import stat
JOBS = {
"ai-game-creator-shell-rust-lane-1",
"ai-game-creator-shell-rust-lane-2",
"ai-game-creator-shell-rust-smoke",
"ai-game-creator-shell-rust-crates",
"backend-tests",
"native-shell-tests",
-2
View File
@@ -33,7 +33,6 @@ LABEL = re.compile(r'(?m)^(\s*-\s*[\"\x27]?)genarrative-ci:docker://(sha256:[0-9
JOBS = {
"AI game creator shell Rust lane 1/2",
"AI game creator shell Rust lane 2/2",
"AI game creator shell Rust smoke",
"AI game creator shell Rust crates",
"Backend tests", "Native shell tests", "Frontend tests",
"Repository checks", "AI game creator shell web tests",
@@ -41,7 +40,6 @@ JOBS = {
RUST_JOB_IDS = {
"AI game creator shell Rust lane 1/2": "ai-game-creator-shell-rust-lane-1",
"AI game creator shell Rust lane 2/2": "ai-game-creator-shell-rust-lane-2",
"AI game creator shell Rust smoke": "ai-game-creator-shell-rust-smoke",
"AI game creator shell Rust crates": "ai-game-creator-shell-rust-crates",
"Backend tests": "backend-tests",
"Native shell tests": "native-shell-tests",
+2 -17
View File
@@ -63,12 +63,11 @@ const jobNames = [
'ai-game-creator-shell-web-tests',
'ai-game-creator-shell-rust-lane-1',
'ai-game-creator-shell-rust-lane-2',
'ai-game-creator-shell-rust-smoke',
'ai-game-creator-shell-rust-crates',
] as const;
// crate 级测试只跑共享 / 平台 / 编辑器插件的 Cargo manifest,不构建 AGC 壳。
// 壳的 Rust 分片与 agent-run smoke 会执行 build.rs,需要 npm 安装的 Claude Agent SDK。
// 壳的 Rust 分片会执行 build.rs,需要 npm 安装的 Claude Agent SDK。
const jobsWithoutNpmInstall: readonly string[] = [
'ai-game-creator-shell-rust-crates',
];
@@ -92,7 +91,6 @@ const nativeShellGateGroupScripts = {
'agc-rust-shard-2': 'npm run check:native-shells:agc-rust-shard-2',
'agc-rust-shard-3': 'npm run check:native-shells:agc-rust-shard-3',
'agc-rust-shard-4': 'npm run check:native-shells:agc-rust-shard-4',
'agc-rust-smoke': 'npm run check:native-shells:agc-rust-smoke',
release: 'npm run check:native-shells:release',
} as const;
@@ -141,7 +139,6 @@ describe('project CI workflow', () => {
const producers = [
'ai-game-creator-shell-rust-lane-1',
'ai-game-creator-shell-rust-lane-2',
'ai-game-creator-shell-rust-smoke',
'ai-game-creator-shell-rust-crates',
'backend-tests',
'native-shell-tests',
@@ -175,8 +172,6 @@ describe('project CI workflow', () => {
'Run AI game creator shell Rust shard 1/4',
'ai-game-creator-shell-rust-lane-2':
'Run AI game creator shell Rust shard 3/4',
'ai-game-creator-shell-rust-smoke':
'Run AI game creator shell agent-run smoke',
'ai-game-creator-shell-rust-crates':
'Run AI game creator shell shared crate gates',
'backend-tests': 'Run server-rs workspace tests',
@@ -242,9 +237,6 @@ describe('project CI workflow', () => {
'cargo test --locked -p spacetime-module --no-fail-fast --manifest-path server-rs/Cargo.toml --no-run',
);
expect(warmCommands).toContain('cd apps/ai-game-creator-shell/src-tauri');
expect(warmCommands).toContain(
'cd apps/ai-game-creator-shell cargo build --manifest-path src-tauri/Cargo.toml',
);
expect(warmCommands).toContain(
'cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml --no-run',
);
@@ -678,13 +670,6 @@ describe('project CI workflow', () => {
nativeShellGateScript.match(/ai-game-creator-shell:check:rust:shell/gu),
).toHaveLength(4);
const smokeJob = jobSection('ai-game-creator-shell-rust-smoke');
expect(smokeJob).toContain(
'run: npm run check:native-shells:agc-rust-smoke',
);
expect(smokeJob).toContain('cargo fetch --locked');
expect(smokeJob).not.toContain('server-rs/Cargo.toml');
const cratesJob = jobSection('ai-game-creator-shell-rust-crates');
expect(cratesJob).toContain(
'run: npm run check:native-shells:agc-rust-crates',
@@ -704,7 +689,7 @@ describe('project CI workflow', () => {
// 拆开的 web / rust 两段必须还是原 `ai-game-creator-shell:check` 的同一条命令序列,
// rust 段再拆成 crate 级与壳分片两段后在聚合脚本里保持同序。
expect(rootPackageJson.scripts?.['ai-game-creator-shell:check']).toBe(
'npm run ai-game-creator-shell:check:web && npm run ai-game-creator-shell:check:rust && npm run ai-game-creator-shell:agent-run:smoke',
'npm run ai-game-creator-shell:check:web && npm run ai-game-creator-shell:check:rust',
);
expect(rootPackageJson.scripts?.['ai-game-creator-shell:check:web']).toBe(
'npm run ai-game-creator-shell:typecheck && npm --prefix apps/ai-game-creator-shell run bundled-resources:test && npm run test -- apps/ai-game-creator-shell/tests',
+2 -2
View File
@@ -340,7 +340,7 @@ class GiteaCacheMaintenanceTest(unittest.TestCase):
instance, run, jobs, artifacts = self.source_fixture()
result = self.select_source(instance)
self.assertEqual(result["run_id"], 44)
self.assertEqual(len(result["exports"]), 6)
self.assertEqual(len(result["exports"]), len(maintenance_module.RUST_JOB_IDS))
self.assertEqual({item["size_in_bytes"] for item in result["exports"]}, {10})
run["event"] = "pull_request"
self.assertIsNone(self.select_source(instance))
@@ -421,7 +421,7 @@ class GiteaCacheMaintenanceTest(unittest.TestCase):
instance.docker = docker
instance.api.download = lambda path, destination, expected_size: destination.write_bytes(b"download")
def merge(inputs, output, **kwargs):
self.assertEqual(len(inputs), 6)
self.assertEqual(len(inputs), len(maintenance_module.RUST_JOB_IDS))
self.assertEqual(kwargs["expected_inherited_source_sha"], "b" * 40)
output.mkdir()
(output / "objects").mkdir()