AGC 支持 Anthropic 独立网关路由与后台协议选项
新增平台 Anthropic 网关路由 /api/llm/anthropic/{*path},复用账号 Router 凭据边界
OpenAI 侧规范路径改为 /api/llm/v1/responses 与 /api/llm/v1/chat/completions,旧路径保留兼容
baseUrl 不再携带路由与版本段,统一由协议自己拼 v1/<op>
cc 执行器改走平台网关,ANTHROPIC_AUTH_TOKEN 复用平台会话,不再直连 Router
后台模型目录 agentMode 增加 anthropic,管理页与客户端契约同步
补齐三条路由埋点与静态段白名单,新增三条回归测试
同步后端架构文档、模型别名文档与排障记忆
This commit is contained in:
@@ -1075,7 +1075,7 @@ export interface AdminRechargeRefundActionResponse {
|
||||
export interface AdminWalletRestrictionResponse {
|
||||
wallet: AdminProfileWalletPayload;
|
||||
}
|
||||
export type AdminAgcAgentMode = 'codex' | 'cc';
|
||||
export type AdminAgcAgentMode = 'codex' | 'cc' | 'anthropic';
|
||||
|
||||
export interface AdminAgcModel {
|
||||
id: string;
|
||||
|
||||
@@ -226,6 +226,7 @@ export function AdminAgcModelsPage({
|
||||
>
|
||||
<option value="codex">Codex</option>
|
||||
<option value="cc">Claude Code</option>
|
||||
<option value="anthropic">Anthropic 协议</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -352,7 +352,21 @@ fn copy_env(command: &mut tokio::process::Command, name: &str) {
|
||||
fn claude_base_url(llm: Option<&GameCreatorLlmConfig>) -> Option<String> {
|
||||
std::env::var("ANTHROPIC_BASE_URL")
|
||||
.ok()
|
||||
.or_else(|| llm.map(|value| value.base_url.trim_end_matches('/').to_string()))
|
||||
.or_else(|| {
|
||||
let llm = llm?;
|
||||
// Official models never talk to the Router directly: the account
|
||||
// Router credential lives server-side, so the Claude sidecar goes
|
||||
// through the platform gateway and appends `/v1/messages` itself.
|
||||
if !llm.custom_enabled {
|
||||
if let Some(session) = crate::platform_session::current_platform_session() {
|
||||
return Some(format!(
|
||||
"{}/api/llm/anthropic",
|
||||
session.api_base_url.trim_end_matches('/')
|
||||
));
|
||||
}
|
||||
}
|
||||
Some(llm.base_url.trim_end_matches('/').to_string())
|
||||
})
|
||||
.map(|value| {
|
||||
value
|
||||
.trim_end_matches('/')
|
||||
|
||||
@@ -2351,7 +2351,7 @@ impl CodexAppServerConnection {
|
||||
)
|
||||
})?;
|
||||
effective_llm.base_url =
|
||||
format!("{}/api/llm", session.api_base_url.trim_end_matches('/'));
|
||||
format!("{}/api/llm/v1", session.api_base_url.trim_end_matches('/'));
|
||||
effective_llm.api_key.clear();
|
||||
// Only the platform catalog identifier reaches Codex. api-server
|
||||
// validates it and resolves the actual upstream model.
|
||||
@@ -2619,7 +2619,7 @@ impl CodexAppServerConnection {
|
||||
..
|
||||
} => (
|
||||
Some((
|
||||
format!("{}/api/llm", api_base_url.trim_end_matches('/')),
|
||||
format!("{}/api/llm/v1", api_base_url.trim_end_matches('/')),
|
||||
access_token.clone(),
|
||||
)),
|
||||
true,
|
||||
|
||||
@@ -1098,7 +1098,8 @@ fn select_game_creator_model_inner(
|
||||
if let Some(agent_mode) = catalog_agent_mode {
|
||||
config.agent_mode = match agent_mode.trim() {
|
||||
"codex" => GAME_CREATOR_AGENT_MODE_CODEX_APP_SERVER.to_string(),
|
||||
"cc" => GAME_CREATOR_AGENT_MODE_CLAUDE_CODE_CLI.to_string(),
|
||||
// `cc` 是 Claude 执行器的历史别名,`anthropic` 是同一执行器的显式协议值。
|
||||
"cc" | "anthropic" => GAME_CREATOR_AGENT_MODE_CLAUDE_CODE_CLI.to_string(),
|
||||
value => return Err(format!("模型 Agent 模式无效:{value}")),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -222,7 +222,8 @@ fn build_game_creator_official_platform_llm_config(
|
||||
if api_base_url.is_empty() {
|
||||
return Err("登录态缺少 API Server 地址".to_string());
|
||||
}
|
||||
let proxy_base_url = format!("{api_base_url}/api/llm");
|
||||
// baseUrl 不带路由与版本段,OpenAI 协议由 platform-llm 自己拼 `v1/<op>`。
|
||||
let proxy_base_url = format!("{api_base_url}/api/llm/v1");
|
||||
LlmConfig::new(
|
||||
LlmProvider::OpenAiCompatible,
|
||||
proxy_base_url,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { resolveTauriInvoke } from '../app/tauri';
|
||||
export type ClientLlmModel = {
|
||||
displayName: string;
|
||||
id: string;
|
||||
agentMode: 'codex' | 'cc';
|
||||
agentMode: 'codex' | 'cc' | 'anthropic';
|
||||
};
|
||||
|
||||
export type ClientLlmModelCatalog = {
|
||||
|
||||
Reference in New Issue
Block a user