fix(rpc): normalize legacy un-namespaced method names in dispatcher (OPENHUMAN-TAURI-9Q) (#1541)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
This commit is contained in:
oxoxDev
2026-05-12 19:56:51 -07:00
committed by GitHub
co-authored by google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Steven Enamakel
parent d762660ea3
commit 2f2f98516a
+154
View File
@@ -30,6 +30,17 @@ pub async fn dispatch(
method: &str,
params: serde_json::Value,
) -> Result<serde_json::Value, String> {
let method = if let Some(canonical) = normalize_legacy_method(method) {
log::debug!(
"[rpc] legacy method '{}' rewritten to '{}'",
method,
canonical
);
canonical
} else {
method
};
log::trace!(
"[rpc:dispatch] enter method={} params={}",
method,
@@ -66,6 +77,44 @@ pub async fn dispatch(
Err(format!("unknown method: {method}"))
}
/// Normalizes legacy un-namespaced method names to their canonical equivalents.
///
/// This provides defense-in-depth against stale or unbalanced callers that may
/// still be using old method names.
///
/// Source of truth: `app/src/services/rpcMethods.ts` (`LEGACY_METHOD_ALIASES`)
fn normalize_legacy_method(method: &str) -> Option<&'static str> {
match method {
"openhuman.get_analytics_settings" => Some("openhuman.config_get_analytics_settings"),
"openhuman.get_composio_trigger_settings" => {
Some("openhuman.config_get_composio_trigger_settings")
}
"openhuman.get_config" => Some("openhuman.config_get"),
"openhuman.get_runtime_flags" => Some("openhuman.config_get_runtime_flags"),
"openhuman.ping" => Some("core.ping"),
"openhuman.set_browser_allow_all" => Some("openhuman.config_set_browser_allow_all"),
"openhuman.update_analytics_settings" => Some("openhuman.config_update_analytics_settings"),
"openhuman.update_browser_settings" => Some("openhuman.config_update_browser_settings"),
"openhuman.update_composio_trigger_settings" => {
Some("openhuman.config_update_composio_trigger_settings")
}
"openhuman.update_local_ai_settings" => Some("openhuman.config_update_local_ai_settings"),
"openhuman.update_memory_settings" => Some("openhuman.config_update_memory_settings"),
"openhuman.update_model_settings" => Some("openhuman.config_update_model_settings"),
"openhuman.update_runtime_settings" => Some("openhuman.config_update_runtime_settings"),
"openhuman.update_screen_intelligence_settings" => {
Some("openhuman.config_update_screen_intelligence_settings")
}
"openhuman.workspace_onboarding_flag_exists" => {
Some("openhuman.config_workspace_onboarding_flag_exists")
}
"openhuman.workspace_onboarding_flag_set" => {
Some("openhuman.config_workspace_onboarding_flag_set")
}
_ => None,
}
}
/// Handles internal core-level RPC methods.
///
/// These methods provide basic information about the server and its version.
@@ -216,4 +265,109 @@ mod tests {
assert_eq!(result.value, json!({ "version": "0.0.0-abc" }));
assert!(result.logs.is_empty());
}
#[test]
fn test_normalize_legacy_method_all_aliases() {
let cases = vec![
(
"openhuman.get_analytics_settings",
"openhuman.config_get_analytics_settings",
),
(
"openhuman.get_composio_trigger_settings",
"openhuman.config_get_composio_trigger_settings",
),
("openhuman.get_config", "openhuman.config_get"),
(
"openhuman.get_runtime_flags",
"openhuman.config_get_runtime_flags",
),
("openhuman.ping", "core.ping"),
(
"openhuman.set_browser_allow_all",
"openhuman.config_set_browser_allow_all",
),
(
"openhuman.update_analytics_settings",
"openhuman.config_update_analytics_settings",
),
(
"openhuman.update_browser_settings",
"openhuman.config_update_browser_settings",
),
(
"openhuman.update_composio_trigger_settings",
"openhuman.config_update_composio_trigger_settings",
),
(
"openhuman.update_local_ai_settings",
"openhuman.config_update_local_ai_settings",
),
(
"openhuman.update_memory_settings",
"openhuman.config_update_memory_settings",
),
(
"openhuman.update_model_settings",
"openhuman.config_update_model_settings",
),
(
"openhuman.update_runtime_settings",
"openhuman.config_update_runtime_settings",
),
(
"openhuman.update_screen_intelligence_settings",
"openhuman.config_update_screen_intelligence_settings",
),
(
"openhuman.workspace_onboarding_flag_exists",
"openhuman.config_workspace_onboarding_flag_exists",
),
(
"openhuman.workspace_onboarding_flag_set",
"openhuman.config_workspace_onboarding_flag_set",
),
];
for (legacy, canonical) in cases {
assert_eq!(
normalize_legacy_method(legacy),
Some(canonical),
"Legacy method {} should normalize to {}",
legacy,
canonical
);
}
}
#[test]
fn test_normalize_legacy_method_none_for_unknown_or_canonical() {
assert!(normalize_legacy_method("core.ping").is_none());
assert!(normalize_legacy_method("openhuman.config_get").is_none());
assert!(normalize_legacy_method("unknown.method").is_none());
}
#[tokio::test]
async fn dispatch_legacy_ping_rewrites_and_succeeds() {
let out = dispatch(test_state(), "openhuman.ping", json!({}))
.await
.expect("openhuman.ping should be rewritten to core.ping and succeed");
assert_eq!(out, json!({ "ok": true }));
}
#[tokio::test]
async fn dispatch_legacy_alias_routes_to_registry() {
// openhuman.get_analytics_settings should rewrite to openhuman.config_get_analytics_settings.
// This is a read-only call and should succeed if the registry is wired up.
let out = dispatch(test_state(), "openhuman.get_analytics_settings", json!({}))
.await
.expect("openhuman.get_analytics_settings should be rewritten and succeed");
// The registry-wrapped payload has a "result" field.
assert!(
out.get("enabled").is_some() || out.get("result").is_some(),
"Payload should have 'enabled' or 'result', got: {}",
out
);
}
}