mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
199 lines
8.1 KiB
TypeScript
199 lines
8.1 KiB
TypeScript
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import { describe, expect, test } from 'vitest';
|
|
|
|
import { CORE_RPC_METHODS, LEGACY_METHOD_ALIASES, normalizeRpcMethod } from '../rpcMethods';
|
|
|
|
describe('rpcMethods catalog', () => {
|
|
describe('normalizeRpcMethod', () => {
|
|
test('resolves all legacy aliases to their canonical core method', () => {
|
|
for (const [legacyMethod, coreMethod] of Object.entries(LEGACY_METHOD_ALIASES)) {
|
|
expect(normalizeRpcMethod(legacyMethod)).toBe(coreMethod);
|
|
}
|
|
});
|
|
|
|
test('transforms auth methods by replacing dots with underscores', () => {
|
|
expect(normalizeRpcMethod('openhuman.auth.login')).toBe('openhuman.auth_login');
|
|
expect(normalizeRpcMethod('openhuman.auth.get.state')).toBe('openhuman.auth_get_state');
|
|
expect(normalizeRpcMethod('openhuman.auth.a.b.c')).toBe('openhuman.auth_a_b_c');
|
|
});
|
|
|
|
test('returns unmapped or unrecognized methods unchanged', () => {
|
|
expect(normalizeRpcMethod('openhuman.threads_list')).toBe('openhuman.threads_list');
|
|
expect(normalizeRpcMethod('openhuman.unknown_method')).toBe('openhuman.unknown_method');
|
|
expect(normalizeRpcMethod('')).toBe('');
|
|
expect(normalizeRpcMethod('random_string')).toBe('random_string');
|
|
});
|
|
|
|
test('trims whitespace and converts to lower case', () => {
|
|
expect(normalizeRpcMethod(' OpenHuman.Auth.Login ')).toBe('openhuman.auth_login');
|
|
expect(normalizeRpcMethod(' OPENHUMAN.GET_CONFIG ')).toBe(CORE_RPC_METHODS.configGet);
|
|
expect(normalizeRpcMethod('OpenHuman.Unrecognized_Status ')).toBe(
|
|
'openhuman.unrecognized_status'
|
|
);
|
|
expect(normalizeRpcMethod(' some_RANDOM_method ')).toBe('some_random_method');
|
|
});
|
|
});
|
|
|
|
test('legacy aliases point at canonical method values', () => {
|
|
expect(LEGACY_METHOD_ALIASES['openhuman.update_model_settings']).toBe(
|
|
CORE_RPC_METHODS.inferenceUpdateModelSettings
|
|
);
|
|
expect(LEGACY_METHOD_ALIASES['openhuman.workspace_onboarding_flag_set']).toBe(
|
|
CORE_RPC_METHODS.configWorkspaceOnboardingFlagSet
|
|
);
|
|
});
|
|
|
|
describe('MCP client legacy alias resolution (Sentry CORE-RUST-DW/DV/DT/DS/DR)', () => {
|
|
test('mcp_clients.list resolves to mcp_clients_installed_list', () => {
|
|
expect(normalizeRpcMethod('mcp_clients.list')).toBe(CORE_RPC_METHODS.mcpClientsInstalledList);
|
|
});
|
|
|
|
test('openhuman.mcp_clients_list resolves to mcp_clients_installed_list', () => {
|
|
expect(normalizeRpcMethod('openhuman.mcp_clients_list')).toBe(
|
|
CORE_RPC_METHODS.mcpClientsInstalledList
|
|
);
|
|
});
|
|
|
|
test('openhuman.mcp_list resolves to mcp_clients_installed_list', () => {
|
|
expect(normalizeRpcMethod('openhuman.mcp_list')).toBe(
|
|
CORE_RPC_METHODS.mcpClientsInstalledList
|
|
);
|
|
});
|
|
|
|
test('openhuman.mcp_servers_list resolves to mcp_clients_installed_list', () => {
|
|
expect(normalizeRpcMethod('openhuman.mcp_servers_list')).toBe(
|
|
CORE_RPC_METHODS.mcpClientsInstalledList
|
|
);
|
|
});
|
|
|
|
test('openhuman.tool_registry_call resolves to mcp_clients_tool_call', () => {
|
|
expect(normalizeRpcMethod('openhuman.tool_registry_call')).toBe(
|
|
CORE_RPC_METHODS.mcpClientsToolCall
|
|
);
|
|
});
|
|
|
|
test('dotted tool_registry.diagnostics resolves to the canonical method (#3294)', () => {
|
|
expect(normalizeRpcMethod('tool_registry.diagnostics')).toBe(
|
|
CORE_RPC_METHODS.toolRegistryDiagnostics
|
|
);
|
|
expect(CORE_RPC_METHODS.toolRegistryDiagnostics).toBe('openhuman.tool_registry_diagnostics');
|
|
});
|
|
|
|
test('canonical mcp_clients_installed_list passes through unchanged', () => {
|
|
expect(normalizeRpcMethod('openhuman.mcp_clients_installed_list')).toBe(
|
|
'openhuman.mcp_clients_installed_list'
|
|
);
|
|
});
|
|
|
|
test('canonical mcp_clients_tool_call passes through unchanged', () => {
|
|
expect(normalizeRpcMethod('openhuman.mcp_clients_tool_call')).toBe(
|
|
'openhuman.mcp_clients_tool_call'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('health legacy alias resolution (Sentry CORE-RUST-FG / CORE-RUST-G0)', () => {
|
|
test('health_snapshot resolves to openhuman.health_snapshot', () => {
|
|
expect(normalizeRpcMethod('health_snapshot')).toBe(CORE_RPC_METHODS.healthSnapshot);
|
|
});
|
|
|
|
test('openhuman.system_info resolves to openhuman.health_system_info (Sentry CORE-RUST-G0)', () => {
|
|
// Older clients called openhuman.system_info before the method was
|
|
// namespaced under health as openhuman.health_system_info.
|
|
expect(normalizeRpcMethod('openhuman.system_info')).toBe(CORE_RPC_METHODS.healthSystemInfo);
|
|
});
|
|
|
|
test('canonical health_system_info passes through unchanged', () => {
|
|
expect(normalizeRpcMethod('openhuman.health_system_info')).toBe(
|
|
'openhuman.health_system_info'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('channels legacy alias resolution (Sentry OPENHUMAN-CORE-1Y / OPENHUMAN-CORE-1Z)', () => {
|
|
test('dotted channel list aliases resolve to channels_list', () => {
|
|
expect(normalizeRpcMethod('channels.list')).toBe(CORE_RPC_METHODS.channelsList);
|
|
expect(normalizeRpcMethod('openhuman.channels.list')).toBe(CORE_RPC_METHODS.channelsList);
|
|
});
|
|
|
|
test('canonical channels_list passes through unchanged', () => {
|
|
expect(normalizeRpcMethod('openhuman.channels_list')).toBe('openhuman.channels_list');
|
|
});
|
|
});
|
|
|
|
test('catalog canonical methods exist in core schema registry (drift guard)', () => {
|
|
const schemaSources = [
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/config/schemas/schema_defs.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/inference/provider/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/inference/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/inference/local/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/embeddings/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/mcp_registry/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/tool_registry/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/health/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../src/openhuman/channels/controllers/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
// The channels_* namespace/function literals now live in the vendored
|
|
// tinychannels crate (`ChannelControllerSchema`), not in the thin
|
|
// `src/openhuman/channels/controllers/schemas.rs` adapter above, which
|
|
// only converts from it (#4557 "Use tinychannels provider
|
|
// implementations") — read both so this drift guard still sees them.
|
|
fs.readFileSync(
|
|
path.resolve(__dirname, '../../../../vendor/tinychannels/src/controllers/schemas.rs'),
|
|
'utf8'
|
|
),
|
|
].join('\n');
|
|
|
|
for (const method of Object.values(CORE_RPC_METHODS)) {
|
|
// core.* methods (e.g. core.ping) are special dispatch methods, not in the schema catalog.
|
|
if (!method.startsWith('openhuman.')) continue;
|
|
const methodRoot = method.slice('openhuman.'.length);
|
|
const namespace = methodRoot.startsWith('inference_')
|
|
? 'inference'
|
|
: methodRoot.startsWith('embeddings_')
|
|
? 'embeddings'
|
|
: methodRoot.startsWith('providers_')
|
|
? 'providers'
|
|
: methodRoot.startsWith('mcp_clients_')
|
|
? 'mcp_clients'
|
|
: methodRoot.startsWith('health_')
|
|
? 'health'
|
|
: methodRoot.startsWith('channels_')
|
|
? 'channels'
|
|
: methodRoot.startsWith('tool_registry_')
|
|
? 'tool_registry'
|
|
: 'config';
|
|
const fnName = methodRoot.slice(`${namespace}_`.length);
|
|
expect(schemaSources).toContain(`namespace: "${namespace}"`);
|
|
expect(schemaSources).toContain(`function: "${fnName}"`);
|
|
}
|
|
});
|
|
});
|