默认模型目录补上 claude-opus-5-5 的 Claude Code CLI 绑定
Project CI / AI game creator shell Rust crates (push) Successful in 5m5s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m28s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m34s
Project CI / Frontend tests (push) Successful in 3m26s
Project CI / Backend tests (push) Successful in 8m3s
Project CI / AI game creator shell web tests (push) Failing after 3m38s
Project CI / Repository checks (push) Successful in 7m30s
Project CI / Native shell tests (push) Successful in 9m17s

module-runtime:from_upstream_models 为上游模型 claude-opus-5-5 额外生成一条 agentMode=cc + protocol=anthropic 的目录项,保留原 Codex 条目与默认项,超出目录项数上限时不再追加
module-runtime:新增 claude_code_default_binding 与单测,覆盖 cc 条目生成、协议配对与非该模型不额外生成
docs/project-memory/shared-memory/pitfalls:记录本地目录全是 codex 的现象、默认绑定口径,以及本地 8082 跑的是另一个 worktree(harness 分支)这个环境陷阱
This commit is contained in:
kdletters
2026-10-07 20:24:26 +08:00
parent 47655d880c
commit b1c89fbbae
2 changed files with 88 additions and 1 deletions
@@ -6595,6 +6595,15 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- **验证**:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --features=cocos-editor-execute,unity-editor-execute,godot-editor-execute --bin genarrative-ai-game-creator-shell claude_` 34 passed(新增 `claude_code_session_lookup_uses_the_project_directory_and_newest_trace`、`claude_direct_resume_falls_back_to_disk_and_prefers_the_process_map`)。真实环境用随包 `claude.exe`(2.1.285)复验:把项目隔离 home 的 `projects/` 拷进临时 `CLAUDE_CONFIG_DIR`、cwd 设为项目根,`--resume 00000000-…` 立刻回 `No conversation found with session ID`;`--resume f79dae28-…`(磁盘上最新那份)不报找不到,直接进入模型请求,落在本地抓包桩上的请求体里带着完整历史(`messages` 13 条,首条就是 14:23 的「做个废土风的扫雷…」原文)。
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs`。
## 2026-10-07 默认模型目录里没有 cc 模型,本地开发栈根本选不到 Claude Code CLI
- **现象**:本地 `/api/llm/models` 的 14 条模型全部是 `agentMode: "codex"`(`claude-opus-5-5` 也是 `protocol: openai_responses`),cc 模式在本地开发栈里没有可选项,只能靠后台手工加模型;而安装版走 dev 目录时 `claude-opus-5-5` 是 cc 模型。
- **根因**:默认目录由 `AgcModelCatalog::from_upstream_models` 按上游模型列表生成,所有条目一律落在 `AgcAgentMode::default()`(Codex),"上游模型名 → 执行器"没有任何默认绑定,所以任何全新环境都不会自带 cc 条目。
- **顺带查到的环境陷阱**:本地 8082 上的 `api-server.exe`(PID 15748)是从**另一个 worktree** 起的 —— `C:\Users\kdletters\.codex\worktrees\5cd1\Genarrative`(分支 `codex/agc-harness-cloud-config`,模型 DTO 多一个 `harnessProfileId`),不是 `F:\Projects\Genarrative` 的 master。所以"本地开发栈"看到的模型目录、字段和 master 不一致,用 master 的现象去对本地结果会得出错误结论;判断本地行为前先看 `Get-CimInstance Win32_Process` 的 `ExecutablePath`。
- **现行口径**:`from_upstream_models` 为上游的 `claude-opus-5-5` 额外生成一条 `id=claude-opus-5-5-cc`、`alias=claude-opus-5-5 (Claude Code)`、`agentMode=cc`、`protocol=anthropic` 的条目(原 Codex 条目与默认项保留;超过目录项数上限时不再追加)。后台手工保存过的目录不受影响:启动期只在目录缺失或校验不通过时重建,已有合法目录不会因为这行默认值被覆盖。
- **验证**:`cargo test -p module-runtime --lib agc_models::tests`(新增 `catalog_default_binding_adds_claude_code_cli_for_the_official_cc_model`,断言 cc 条目、`protocol=anthropic`、默认项仍是 Codex 条目,以及非该模型不额外生成)。
- **关联**:`server-rs/crates/module-runtime/src/agc_models.rs`、`server-rs/crates/api-server/src/agc_models.rs`。
## 2026-10-07 cc 模型说"我没有任何可调用的工具":先分清没连上还是模型说错
- **现象**:安装版 0.1.230,新建项目 `gameagent-63d3fda7` 的第一个回合(19:25),模型回答"在当前对话里,我**没有任何可调用的工具**…我能看到的上下文只有工作目录/平台/不是 git 仓库";同一版本 19:22 在 `gameagent-0514673b` 的回合里却真实调用了 `mcp__agc__client_session_info` 与 `mcp__agc__conversation_list` 并拿到回执。**同一个构建既能用工具、又会被模型说成没有工具**,所以"模型自述"不能当证据。
@@ -80,12 +80,29 @@ impl AgcModelCatalog {
entries.push(AgcModel {
id,
alias: model_id.clone(),
model_id,
model_id: model_id.clone(),
enabled: true,
agent_mode: AgcAgentMode::default(),
protocol: None,
access: AgcModelAccess::default(),
});
// 默认目录必须带上平台官方 cc(Claude Code CLI)绑定:上游只给模型名,如果不额外
// 生成这一条,全新环境(含本地开发栈)的模型列表里一个 cc 模型都没有,cc 模式
// 根本没有可选项。
if entries.len() < AGC_MODEL_CATALOG_MAX_MODELS {
if let Some((cc_id, cc_alias)) = claude_code_default_binding(&model_id) {
let cc_id = unique_model_id(&cc_id, &mut used_ids);
entries.push(AgcModel {
id: cc_id,
alias: cc_alias,
model_id: model_id.clone(),
enabled: true,
agent_mode: AgcAgentMode::Cc,
protocol: Some(AgcModelProtocol::Anthropic),
access: AgcModelAccess::default(),
});
}
}
}
let default_model_id = entries
.first()
@@ -175,6 +192,21 @@ fn agc_model_id_from_name(model_name: &str) -> String {
id
}
/// 上游模型名 → 默认目录里额外生成的 Claude Code CLI 绑定:`(目录标识, 显示别名)`。
///
/// 平台官方 cc 模型是 `claude-opus-5-5`。默认目录保留它原有的 Codex 绑定(历史目录的默认
/// 项),同时额外生成一条 `agentMode=cc` + `protocol=anthropic` 的条目,让 cc 模式在全新
/// 环境和本地开发栈里直接可选:现场证据是本地 `/api/llm/models` 的 14 条全是
/// `agentMode=codex`,cc 模式在本地没有可选项,只能靠后台手工加模型。
fn claude_code_default_binding(model_name: &str) -> Option<(String, String)> {
(model_name == "claude-opus-5-5").then(|| {
(
format!("{model_name}-cc"),
format!("{model_name} (Claude Code)"),
)
})
}
/// 生成在本次目录内唯一的标识:同名 slug 追加 `-2`/`-3`,并保证不超过长度上限。
fn unique_model_id(model_name: &str, used_ids: &mut HashSet<String>) -> String {
let slug = agc_model_id_from_name(model_name);
@@ -225,6 +257,52 @@ mod tests {
}
}
#[test]
fn catalog_default_binding_adds_claude_code_cli_for_the_official_cc_model() {
let catalog =
AgcModelCatalog::from_upstream_models(upstream(&["claude-opus-5-5", "gpt-5.6-sol"]), 0)
.unwrap();
// Codex 绑定保留,默认项不变(排序后第一项还是 claude-opus-5-5 的 Codex 条目)。
assert_eq!(catalog.default_model_id, "claude-opus-5-5");
assert_eq!(
catalog
.models
.iter()
.map(|entry| (
entry.id.as_str(),
entry.alias.as_str(),
entry.agent_mode,
entry.resolved_protocol()
))
.collect::<Vec<_>>(),
vec![
(
"claude-opus-5-5",
"claude-opus-5-5",
AgcAgentMode::Codex,
AgcModelProtocol::OpenAiResponses
),
(
"claude-opus-5-5-cc",
"claude-opus-5-5 (Claude Code)",
AgcAgentMode::Cc,
AgcModelProtocol::Anthropic
),
(
"gpt-5-6-sol",
"gpt-5.6-sol",
AgcAgentMode::Codex,
AgcModelProtocol::OpenAiResponses
),
]
);
assert!(catalog.validate().is_ok());
// 非 cc 模型不额外生成条目。
let only_codex =
AgcModelCatalog::from_upstream_models(upstream(&["gpt-5.6-sol"]), 0).unwrap();
assert_eq!(only_codex.models.len(), 1);
}
#[test]
fn catalog_builds_from_upstream_models_with_stable_ids() {
let catalog = AgcModelCatalog::from_upstream_models(