Files
Genarrative/apps/ai-game-creator-shell/src/services/pluginHost.ts
T
kdletters 8701f43f75 AGC 渲染层网络与状态下沉 Rust,并修复画布交互与失败文案
- 删除渲染层传输层:services/clientApi.ts、clientHttp 的 fetchClientHttp 与超时封装整体退场,账户、认证、素材直传、错误上报与游戏分发发布改走 Rust typed command。
- 新增宿主封装:accountHost、editorAssetHost、platformSessionRetry、agentRuntimeErrorDetail 与 features/app-shell/workspacePreferences;渲染层不再读写 access token / refresh cookie,localStorage 只剩测试态旧键迁移 shim。
- 修复 DirectProject 失败文案 v2 映射与「查看详情」按需读取,画布标签面板高度夹紧、框选每帧重算、文档预览入口与场景标题栏 key、资源筛选面板样式。
- 补齐与调整回归:accountHost、agentRuntimeErrorDetail、clientAuthHost、clientHttp、platformSession、platformSessionRetry、resourceFilterPanelStyle、directThreadChatSubscription 等定向用例,并清理测试 harness 中无调用方的残留。
2026-09-28 14:15:02 +08:00

128 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { resolveTauriInvoke } from '../app/tauri';
import type {
AgcExtensionSummary,
AgcPluginPanel,
AgcPluginSummary,
} from '../app/types';
export const AGC_PLUGIN_STATE_CHANGED_EVENT =
'game-creator-plugin-state-changed';
export type PluginRpcParams = Record<string, unknown> | unknown[] | null;
function invokeOrThrow() {
const invoke = resolveTauriInvoke();
if (!invoke) throw new Error('需要在 Tauri App 内运行');
return invoke;
}
export async function listAgcPlugins() {
return invokeOrThrow()('list_agc_plugins') as Promise<AgcPluginSummary[]>;
}
export async function listAgcExtensions() {
return invokeOrThrow()('list_agc_extensions') as Promise<
AgcExtensionSummary[]
>;
}
export async function refreshAgcPlugins() {
return invokeOrThrow()('refresh_agc_plugins') as Promise<AgcPluginSummary[]>;
}
export async function startAgcPlugin(id: string) {
return invokeOrThrow()('start_agc_plugin', {
id,
}) as Promise<AgcPluginSummary>;
}
/** 只消费宿主的能力投影;项目类型与平台支持均不在前端再次判断。 */
export async function startAvailableAgcEditorPlugins(
isActive: () => boolean = () => true,
) {
const plugins = await listAgcPlugins();
const available = plugins.filter(
(plugin) =>
plugin.builtin &&
(plugin.id === 'agc-cocos-editor' ||
plugin.id === 'agc-unity-editor' ||
plugin.id === 'agc-godot-editor') &&
plugin.enabled &&
plugin.hasRuntime &&
(plugin.status === 'stopped' || plugin.status === 'discovered'),
);
const results = await Promise.allSettled(
available.map((plugin) =>
isActive() ? startAgcPlugin(plugin.id) : Promise.resolve(),
),
);
const errors = results.flatMap((result, index) =>
result.status === 'rejected'
? [
`${available[index]!.name}:${
result.reason instanceof Error
? result.reason.message
: String(result.reason)
}`,
]
: [],
);
if (errors.length) {
throw new Error(errors.join(';'));
}
}
export async function stopAgcPlugin(id: string) {
return invokeOrThrow()('stop_agc_plugin', {
id,
}) as Promise<AgcPluginSummary>;
}
export async function reloadAgcPlugin(id: string) {
return invokeOrThrow()('reload_agc_plugin', {
id,
}) as Promise<AgcPluginSummary>;
}
/** 内置插件的可用开关;禁用后不能启动,对应 Agent 工具也不再出现。 */
export async function setAgcPluginEnabled(id: string, enabled: boolean) {
return invokeOrThrow()('set_agc_plugin_enabled', {
id,
enabled,
}) as Promise<AgcPluginSummary[]>;
}
export async function callAgcPlugin<T = unknown>(
id: string,
method: string,
params: PluginRpcParams = null,
) {
return invokeOrThrow()('call_agc_plugin', {
id,
method,
params,
}) as Promise<T>;
}
export async function readAgcPluginPanel(id: string, panelId: string) {
return invokeOrThrow()('read_agc_plugin_panel', { id, panelId }) as Promise<{
panel: AgcPluginPanel;
html: string;
}>;
}
export async function setAgcPluginProjectPath(projectPath: string | null) {
const invoke = invokeOrThrow();
// 项目 effect 的 cleanup(null) 与下个项目的设置必须按提交顺序抵达宿主。
const next = pluginProjectUpdate
.catch(() => undefined)
.then(
() =>
invoke('set_agc_plugin_project_path', { projectPath }) as Promise<void>,
);
pluginProjectUpdate = next;
return next;
}
let pluginProjectUpdate: Promise<void> = Promise.resolve();