Refine desktop setup and remove bundled app center apps
This commit is contained in:
@@ -27,6 +27,33 @@ const mocks = vi.hoisted(() => ({
|
||||
vi.mock('@electron/services/providers/provider-store', () => ({
|
||||
getProviderAccount: mocks.getProviderAccount,
|
||||
listProviderAccounts: mocks.listProviderAccounts,
|
||||
providerAccountToConfig: (account: {
|
||||
id: string;
|
||||
vendorId: ProviderConfig['type'];
|
||||
label: string;
|
||||
baseUrl?: string;
|
||||
apiProtocol?: ProviderConfig['apiProtocol'];
|
||||
headers?: Record<string, string>;
|
||||
model?: string;
|
||||
fallbackModels?: string[];
|
||||
fallbackAccountIds?: string[];
|
||||
enabled: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}): ProviderConfig => ({
|
||||
id: account.id,
|
||||
name: account.label,
|
||||
type: account.vendorId,
|
||||
baseUrl: account.baseUrl,
|
||||
apiProtocol: account.apiProtocol,
|
||||
headers: account.headers,
|
||||
model: account.model,
|
||||
fallbackModels: account.fallbackModels,
|
||||
fallbackProviderIds: account.fallbackAccountIds,
|
||||
enabled: account.enabled,
|
||||
createdAt: account.createdAt,
|
||||
updatedAt: account.updatedAt,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@electron/services/secrets/secret-store', () => ({
|
||||
@@ -126,12 +153,12 @@ describe('provider-runtime-sync refresh strategy', () => {
|
||||
mocks.listAgentsSnapshot.mockResolvedValue({ agents: [] });
|
||||
});
|
||||
|
||||
it('uses debouncedReload after saving provider config', async () => {
|
||||
it('uses debouncedRestart after saving provider config', async () => {
|
||||
const gateway = createGateway('running');
|
||||
await syncSavedProviderToRuntime(createProvider(), undefined, gateway as GatewayManager);
|
||||
|
||||
expect(gateway.debouncedReload).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedRestart).not.toHaveBeenCalled();
|
||||
expect(gateway.debouncedRestart).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedReload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('uses debouncedRestart after deleting provider config', async () => {
|
||||
@@ -170,12 +197,90 @@ describe('provider-runtime-sync refresh strategy', () => {
|
||||
expect(mocks.removeProviderFromOpenClaw).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('uses debouncedReload after switching default provider when gateway is running', async () => {
|
||||
it('uses debouncedRestart after switching default provider when gateway is running', async () => {
|
||||
const gateway = createGateway('running');
|
||||
await syncDefaultProviderToRuntime('moonshot', gateway as GatewayManager);
|
||||
|
||||
expect(gateway.debouncedReload).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedRestart).not.toHaveBeenCalled();
|
||||
expect(gateway.debouncedRestart).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedReload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('syncs DeepSeek account defaults to the runtime model provider', async () => {
|
||||
mocks.getProvider.mockResolvedValue(null);
|
||||
mocks.getProviderAccount.mockResolvedValue({
|
||||
id: 'deepseek-a1e23f39',
|
||||
vendorId: 'deepseek',
|
||||
label: 'DeepSeek',
|
||||
authMode: 'api_key',
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
model: 'deepseek-v4-pro',
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
createdAt: '2026-06-03T00:00:00.000Z',
|
||||
updatedAt: '2026-06-03T00:00:00.000Z',
|
||||
});
|
||||
mocks.getApiKey.mockResolvedValue('sk-deepseek');
|
||||
mocks.getProviderConfig.mockImplementation((type: string) => {
|
||||
if (type === 'deepseek') {
|
||||
return {
|
||||
api: 'openai-completions',
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
apiKeyEnv: 'DEEPSEEK_API_KEY',
|
||||
};
|
||||
}
|
||||
return {
|
||||
api: 'openai-completions',
|
||||
baseUrl: 'https://api.moonshot.cn/v1',
|
||||
apiKeyEnv: 'MOONSHOT_API_KEY',
|
||||
};
|
||||
});
|
||||
|
||||
const gateway = createGateway('running');
|
||||
await syncDefaultProviderToRuntime('deepseek-a1e23f39', gateway as GatewayManager);
|
||||
|
||||
expect(mocks.setOpenClawDefaultModelWithOverride).toHaveBeenCalledWith(
|
||||
'deepseek',
|
||||
'deepseek/deepseek-v4-pro',
|
||||
expect.objectContaining({
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
api: 'openai-completions',
|
||||
apiKeyEnv: 'DEEPSEEK_API_KEY',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
expect(mocks.saveProviderKeyToOpenClaw).toHaveBeenCalledWith('deepseek', 'sk-deepseek');
|
||||
expect(gateway.debouncedRestart).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('syncs default provider accounts even when no legacy provider entry exists', async () => {
|
||||
mocks.getProvider.mockResolvedValue(null);
|
||||
mocks.getProviderAccount.mockResolvedValue({
|
||||
id: 'tenant1234',
|
||||
vendorId: 'custom',
|
||||
label: 'Tenant Model',
|
||||
authMode: 'api_key',
|
||||
baseUrl: 'https://llm.example.test/v1',
|
||||
apiProtocol: 'openai-completions',
|
||||
model: 'tenant-model',
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
createdAt: '2026-06-03T00:00:00.000Z',
|
||||
updatedAt: '2026-06-03T00:00:00.000Z',
|
||||
});
|
||||
mocks.getApiKey.mockResolvedValue('sk-tenant');
|
||||
|
||||
await syncDefaultProviderToRuntime('tenant1234');
|
||||
|
||||
expect(mocks.setOpenClawDefaultModelWithOverride).toHaveBeenCalledWith(
|
||||
'custom-tenant12',
|
||||
'custom-tenant12/tenant-model',
|
||||
expect.objectContaining({
|
||||
baseUrl: 'https://llm.example.test/v1',
|
||||
api: 'openai-completions',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
expect(mocks.saveProviderKeyToOpenClaw).toHaveBeenCalledWith('custom-tenant12', 'sk-tenant');
|
||||
});
|
||||
|
||||
it('skips refresh after switching default provider when gateway is stopped', async () => {
|
||||
@@ -281,7 +386,8 @@ describe('provider-runtime-sync refresh strategy', () => {
|
||||
api: 'openai-completions',
|
||||
}),
|
||||
);
|
||||
expect(gateway.debouncedReload).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedRestart).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedReload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('syncs Ollama as default provider with correct baseUrl and api protocol', async () => {
|
||||
@@ -339,7 +445,8 @@ describe('provider-runtime-sync refresh strategy', () => {
|
||||
);
|
||||
// Should NOT call the non-override path
|
||||
expect(mocks.setOpenClawDefaultModel).not.toHaveBeenCalled();
|
||||
expect(gateway.debouncedReload).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedRestart).toHaveBeenCalledTimes(1);
|
||||
expect(gateway.debouncedReload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('removes Ollama provider from runtime on delete', async () => {
|
||||
|
||||
Reference in New Issue
Block a user