Files
NianToB/tests/unit/model-diagnostics.test.ts
inman 0abc48189c
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled
feat: prepare Zhinian desktop pilot
2026-05-07 21:49:20 +08:00

130 lines
4.3 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
const modelDiagnosticsMocks = vi.hoisted(() => ({
config: {} as Record<string, unknown>,
writeOpenClawConfig: vi.fn(),
testOpenClawDir: '/tmp/clawx-tests/model-diagnostics-openclaw',
}));
vi.mock('@electron/utils/channel-config', () => ({
readOpenClawConfig: vi.fn(async () => modelDiagnosticsMocks.config),
writeOpenClawConfig: vi.fn(async (config: Record<string, unknown>) => {
modelDiagnosticsMocks.config = config;
modelDiagnosticsMocks.writeOpenClawConfig(config);
}),
}));
vi.mock('@electron/utils/paths', () => ({
getOpenClawConfigDir: () => modelDiagnosticsMocks.testOpenClawDir,
}));
vi.mock('@electron/utils/logger', () => ({
logger: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
},
}));
function authProfilesPath(homeDir: string): string {
return join(homeDir, '.openclaw', 'agents', 'main', 'agent', 'auth-profiles.json');
}
describe('Yinian model diagnostics', () => {
const originalHome = process.env.HOME;
const testHome = join(tmpdir(), 'clawx-tests', 'model-diagnostics-home');
beforeEach(() => {
vi.resetModules();
vi.clearAllMocks();
process.env.HOME = testHome;
rmSync(testHome, { recursive: true, force: true });
rmSync(modelDiagnosticsMocks.testOpenClawDir, { recursive: true, force: true });
mkdirSync(join(testHome, '.openclaw', 'agents', 'main', 'agent'), { recursive: true });
mkdirSync(modelDiagnosticsMocks.testOpenClawDir, { recursive: true });
modelDiagnosticsMocks.config = {
models: {
providers: {
minimax: {
baseUrl: 'https://api.minimaxi.com/anthropic',
api: 'anthropic-messages',
timeoutSeconds: 30,
models: [{ id: 'MiniMax-M2.7' }],
},
},
pricing: {
enabled: true,
},
},
agents: {
defaults: {
model: {
primary: 'minimax/MiniMax-M2.7',
fallbacks: ['minimax/MiniMax-M2.5'],
},
},
},
};
writeFileSync(authProfilesPath(testHome), JSON.stringify({
version: 1,
profiles: {
'minimax-cn:default': {
type: 'api_key',
provider: 'minimax-cn',
key: 'secret',
},
},
}, null, 2));
});
afterEach(() => {
process.env.HOME = originalHome;
rmSync(testHome, { recursive: true, force: true });
rmSync(modelDiagnosticsMocks.testOpenClawDir, { recursive: true, force: true });
});
it('repairs runtime model defaults and normalizes MiniMax auth profile aliases', async () => {
const {
buildYinianModelConfigDiagnostics,
ensureYinianModelRuntimeConfigured,
} = await import('@electron/utils/model-diagnostics');
await ensureYinianModelRuntimeConfigured();
expect(modelDiagnosticsMocks.writeOpenClawConfig).toHaveBeenCalledWith(expect.objectContaining({
models: expect.objectContaining({
pricing: expect.objectContaining({ enabled: false }),
providers: expect.objectContaining({
minimax: expect.objectContaining({ timeoutSeconds: 300 }),
}),
}),
agents: expect.objectContaining({
defaults: expect.objectContaining({
heartbeat: expect.objectContaining({ every: '0m' }),
}),
}),
}));
const authStore = JSON.parse(readFileSync(authProfilesPath(testHome), 'utf8')) as {
profiles: Record<string, { provider?: string; key?: string }>;
order?: Record<string, string[]>;
lastGood?: Record<string, string>;
};
expect(authStore.profiles['minimax:default']).toMatchObject({
provider: 'minimax',
key: 'secret',
});
expect(authStore.order?.minimax).toContain('minimax:default');
expect(authStore.lastGood?.minimax).toBe('minimax:default');
const diagnostics = await buildYinianModelConfigDiagnostics();
expect(diagnostics.ok).toBe(true);
expect(diagnostics.model.primary).toBe('minimax/MiniMax-M2.7');
expect(diagnostics.runtime.pricingCatalogFetchDisabled).toBe(true);
expect(diagnostics.checks.find((check) => check.id === 'auth-profile')?.status).toBe('ok');
});
});