fb130d1847
Project CI / AI game creator shell Rust lane 1/2 (push) Failing after 57s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
后台模型目录增加 codex/cc 执行模式绑定,旧目录缺省兼容 Codex AGC 客户端按模型绑定路由 Codex app-server 或 Claude Agent SDK sidecar 随包携带 Node runtime、Claude Agent SDK 与匹配平台 Claude runtime 补充模型配置、客户端选择、运行时适配、MCP 取消和定向测试 同步 AGC 模型配置规范、里程碑计划与共享决策记录
94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
import { resolveTauriInvoke } from '../app/tauri';
|
|
import type { GameCreatorAppConfigView } from '../app/types';
|
|
import { type ClientLlmModelCatalog, loadClientLlmModels } from './clientApi';
|
|
|
|
export type { ClientLlmModel, ClientLlmModelCatalog } from './clientApi';
|
|
|
|
let cached: ClientLlmModelCatalog | null = null;
|
|
let inFlight: Promise<ClientLlmModelCatalog> | null = null;
|
|
let source = '';
|
|
let generation = 0;
|
|
let localRevision = 0;
|
|
export const LLM_CONFIG_CHANGED_EVENT = 'agc-llm-config-changed';
|
|
export class LlmModelCatalogConfigError extends Error {}
|
|
|
|
export function notifyLlmConfigChanged() {
|
|
generation += 1;
|
|
cached = null;
|
|
inFlight = null;
|
|
source = '';
|
|
window.dispatchEvent(new Event(LLM_CONFIG_CHANGED_EVENT));
|
|
}
|
|
|
|
async function loadEffectiveCatalog(epoch: number) {
|
|
const invoke = resolveTauriInvoke();
|
|
if (!invoke) {
|
|
throw new LlmModelCatalogConfigError('本地模型服务不可用');
|
|
}
|
|
let config: GameCreatorAppConfigView | undefined;
|
|
try {
|
|
config = await invoke<GameCreatorAppConfigView>(
|
|
'read_game_creator_app_config',
|
|
);
|
|
} catch (error) {
|
|
if (epoch === generation) cached = null;
|
|
throw new LlmModelCatalogConfigError('读取客户端配置失败');
|
|
}
|
|
if (epoch !== generation) throw new Error('模型配置已更新');
|
|
const llm = config?.config.llm;
|
|
const nextSource = llm?.customEnabled
|
|
? JSON.stringify(['custom', llm.baseUrl, llm.visibleModels ?? []])
|
|
: 'official';
|
|
if (source !== nextSource) {
|
|
source = nextSource;
|
|
cached = null;
|
|
}
|
|
if (llm?.customEnabled) {
|
|
if (cached) return cached;
|
|
const ids = llm.visibleModels ?? [];
|
|
return {
|
|
defaultModelId: ids[0] ?? '',
|
|
models: ids.map((id) => ({
|
|
id,
|
|
displayName: id,
|
|
agentMode: 'codex' as const,
|
|
})),
|
|
revision: --localRevision,
|
|
};
|
|
}
|
|
// 官方模型目录的凭据、请求和响应解析归 Rust;渲染层只接收目录快照。
|
|
return loadClientLlmModels();
|
|
}
|
|
|
|
/** 最近一次成功读取的模型目录,用于首屏渲染与刷新失败时兜底。 */
|
|
export function cachedLlmModelCatalog() {
|
|
return cached;
|
|
}
|
|
|
|
/**
|
|
* 读取模型目录;同一时刻只保留一个在途请求,重复触发复用同一结果。
|
|
* 读取失败时保留上一次成功目录,不覆盖调用方已生效的选择。
|
|
*/
|
|
export function refreshLlmModelCatalog() {
|
|
if (inFlight) return inFlight;
|
|
const epoch = generation;
|
|
const request = loadEffectiveCatalog(epoch)
|
|
.then((catalog) => {
|
|
if (epoch !== generation) throw new Error('模型配置已更新');
|
|
cached = catalog;
|
|
return catalog;
|
|
})
|
|
.finally(() => {
|
|
if (inFlight === request) inFlight = null;
|
|
});
|
|
inFlight = request;
|
|
return request;
|
|
}
|
|
|
|
export function resetLlmModelCatalogCacheForTest() {
|
|
generation += 1;
|
|
source = '';
|
|
cached = null;
|
|
inFlight = null;
|
|
}
|