gateway: add local backend daemon controls to dashboard
This commit is contained in:
@@ -10,6 +10,7 @@ import { createHistoryHandlers } from './history.js';
|
||||
import { createCanvasHandlers } from './canvas.js';
|
||||
import { createConfigHandlers, redactConfig } from './config.js';
|
||||
import { createPairingHandlers } from './pairing.js';
|
||||
import type { LocalBackendStatus, LocalBackendControlResult } from './localBackends.js';
|
||||
import { PairingManager } from '../../channels/pairing.js';
|
||||
import { LaneQueue } from '../lane-queue.js';
|
||||
import { CanvasStore } from '../canvas-store.js';
|
||||
@@ -142,6 +143,107 @@ describe('system handlers', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('system.localBackends returns empty list when callback is not provided', async () => {
|
||||
const req: GatewayRequest = { id: 35, method: 'system.localBackends' };
|
||||
const result = await handlers['system.localBackends'](req) as GatewayResponse;
|
||||
expect(getPath(result.result, 'backends')).toEqual([]);
|
||||
});
|
||||
|
||||
it('system.localBackends returns backend statuses from callback', async () => {
|
||||
const localBackends: LocalBackendStatus[] = [
|
||||
{
|
||||
id: 'ollama',
|
||||
provider: 'ollama',
|
||||
name: 'Ollama',
|
||||
unit: 'ollama.service',
|
||||
configured: true,
|
||||
loadState: 'loaded',
|
||||
activeState: 'active',
|
||||
subState: 'running',
|
||||
unitFileState: 'enabled',
|
||||
description: 'Ollama Service',
|
||||
pid: 1234,
|
||||
result: 'success',
|
||||
statusText: 'active (running)',
|
||||
availableActions: ['restart', 'stop'],
|
||||
},
|
||||
];
|
||||
const getLocalBackends = vi.fn(async (): Promise<LocalBackendStatus[]> => localBackends);
|
||||
|
||||
const handlers = createSystemHandlers({
|
||||
...deps,
|
||||
getLocalBackends,
|
||||
});
|
||||
const req: GatewayRequest = { id: 36, method: 'system.localBackends' };
|
||||
const result = await handlers['system.localBackends'](req) as GatewayResponse;
|
||||
expect(getLocalBackends).toHaveBeenCalledTimes(1);
|
||||
expect(getPath(result.result, 'backends')).toHaveLength(1);
|
||||
expect(getPath(result.result, 'backends', '0', 'id')).toBe('ollama');
|
||||
});
|
||||
|
||||
it('system.localBackendControl validates required params', async () => {
|
||||
const handlers = createSystemHandlers({
|
||||
...deps,
|
||||
controlLocalBackend: vi.fn(),
|
||||
});
|
||||
const missingBackend = await handlers['system.localBackendControl']({
|
||||
id: 37,
|
||||
method: 'system.localBackendControl',
|
||||
params: { action: 'restart' },
|
||||
}) as GatewayError;
|
||||
expect(missingBackend.error.code).toBe(ErrorCode.InvalidRequest);
|
||||
|
||||
const missingAction = await handlers['system.localBackendControl']({
|
||||
id: 38,
|
||||
method: 'system.localBackendControl',
|
||||
params: { backend: 'ollama' },
|
||||
}) as GatewayError;
|
||||
expect(missingAction.error.code).toBe(ErrorCode.InvalidRequest);
|
||||
|
||||
const badAction = await handlers['system.localBackendControl']({
|
||||
id: 39,
|
||||
method: 'system.localBackendControl',
|
||||
params: { backend: 'ollama', action: 'reload' },
|
||||
}) as GatewayError;
|
||||
expect(badAction.error.code).toBe(ErrorCode.InvalidRequest);
|
||||
});
|
||||
|
||||
it('system.localBackendControl forwards action to callback', async () => {
|
||||
const controlResult: LocalBackendControlResult = {
|
||||
backend: 'ollama',
|
||||
action: 'restart',
|
||||
status: {
|
||||
id: 'ollama',
|
||||
provider: 'ollama',
|
||||
name: 'Ollama',
|
||||
unit: 'ollama.service',
|
||||
configured: true,
|
||||
loadState: 'loaded',
|
||||
activeState: 'active',
|
||||
subState: 'running',
|
||||
unitFileState: 'enabled',
|
||||
description: 'Ollama Service',
|
||||
pid: 321,
|
||||
result: 'success',
|
||||
statusText: 'active (running)',
|
||||
availableActions: ['restart', 'stop'],
|
||||
},
|
||||
};
|
||||
const controlLocalBackend = vi.fn(async (): Promise<LocalBackendControlResult> => controlResult);
|
||||
const handlers = createSystemHandlers({
|
||||
...deps,
|
||||
controlLocalBackend,
|
||||
});
|
||||
const req: GatewayRequest = {
|
||||
id: 40,
|
||||
method: 'system.localBackendControl',
|
||||
params: { backend: 'ollama', action: 'restart' },
|
||||
};
|
||||
const result = await handlers['system.localBackendControl'](req) as GatewayResponse;
|
||||
expect(controlLocalBackend).toHaveBeenCalledWith('ollama', 'restart');
|
||||
expect(getPath(result.result, 'status', 'activeState')).toBe('active');
|
||||
});
|
||||
|
||||
it('system.presence returns empty result when getPresence is not provided', async () => {
|
||||
const req: GatewayRequest = { id: 4, method: 'system.presence' };
|
||||
const result = await handlers['system.presence'](req) as GatewayResponse;
|
||||
|
||||
Reference in New Issue
Block a user