refactor(desktop): split kernel_commands/pipeline_commands into modules, add SaaS client libs and gateway modules

Split monolithic kernel_commands.rs (2185 lines) and pipeline_commands.rs (1391 lines)
into focused sub-modules under kernel_commands/ and pipeline_commands/ directories.
Add gateway module (commands, config, io, runtime), health_check, and 15 new
TypeScript client libraries for SaaS relay, auth, admin, telemetry, and kernel
sub-systems (a2a, agent, chat, hands, skills, triggers).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-31 11:12:47 +08:00
parent d0ae7d2770
commit f79560a911
71 changed files with 8521 additions and 5997 deletions

View File

@@ -463,8 +463,68 @@ export const useConnectionStore = create<ConnectionStore>((set, get) => {
}
if (!saasDegraded) {
set({ connectionState: 'connected', gatewayVersion: 'saas-relay' });
log.debug('Connected to SaaS relay');
// === SaaS Relay via Kernel ===
// Route LLM calls through SaaS relay (Key Pool) while keeping
// agent management local via KernelClient.
// baseUrl = saasUrl + /api/v1/relay → kernel appends /chat/completions
// apiKey = SaaS JWT token → sent as Authorization: Bearer <jwt>
if (isTauriRuntime()) {
if (!session.token) {
throw new Error('SaaS 中转模式需要认证令牌,请重新登录 SaaS 平台');
}
const kernelClient = getKernelClient();
// Fetch available models from SaaS relay
let models: Array<{ id: string }>;
try {
models = await saasClient.listModels();
} catch {
throw new Error('无法获取可用模型列表,请确认管理后台已配置 Provider 和模型');
}
if (models.length === 0) {
throw new Error('SaaS 平台没有可用模型,请先在管理后台配置 Provider 和模型');
}
// Use first available model (TODO: let user choose preferred model)
const relayModel = models[0];
kernelClient.setConfig({
provider: 'custom',
model: relayModel.id,
apiKey: session.token,
baseUrl: `${session.saasUrl}/api/v1/relay`,
apiProtocol: 'openai',
});
kernelClient.onStateChange = (state: ConnectionState) => {
set({ connectionState: state });
};
kernelClient.onLog = (level: string, message: string) => {
set((s) => ({
logs: [...s.logs.slice(-99), { timestamp: Date.now(), level, message }],
}));
};
set({ client: kernelClient });
const { initializeStores } = await import('./index');
initializeStores();
await kernelClient.connect();
set({ gatewayVersion: 'saas-relay', connectionState: 'connected' });
log.debug('Connected via SaaS relay (kernel backend):', {
model: relayModel.id,
baseUrl: `${session.saasUrl}/api/v1/relay`,
});
} else {
// Non-Tauri (browser) — simple connected state without kernel
set({ connectionState: 'connected', gatewayVersion: 'saas-relay' });
log.debug('Connected to SaaS relay (browser mode)');
}
return;
}
// Fall through to Tauri Kernel / Gateway mode