From eabaf540650a64c9d7528fd9be03807390a9210f Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Mon, 30 Mar 2026 15:29:21 -0700 Subject: [PATCH] feat(skills): add RPC schema and handler for remote procedure calls - Introduced a new RPC schema to facilitate sending arbitrary RPC methods to running skills. - Implemented the `handle_skills_rpc` function to process RPC requests, including skill ID, method name, and optional parameters. - Updated the controller schemas to include the new RPC functionality, enhancing the skills management system. --- src/openhuman/skills/schemas.rs | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/openhuman/skills/schemas.rs b/src/openhuman/skills/schemas.rs index db9be090c..15896cb34 100644 --- a/src/openhuman/skills/schemas.rs +++ b/src/openhuman/skills/schemas.rs @@ -31,6 +31,7 @@ pub fn all_controller_schemas() -> Vec { skills_schema("list_tools"), skills_schema("sync"), skills_schema("call_tool"), + skills_schema("rpc"), ] } @@ -107,6 +108,10 @@ pub fn all_registered_controllers() -> Vec { schema: skills_schema("call_tool"), handler: handle_skills_call_tool, }, + RegisteredController { + schema: skills_schema("rpc"), + handler: handle_skills_rpc, + }, ] } @@ -360,6 +365,32 @@ fn skills_schema(function: &str) -> ControllerSchema { required: true, }], }, + "rpc" => ControllerSchema { + namespace: "skills", + function: "rpc", + description: "Send an arbitrary RPC method to a running skill (e.g. oauth/complete, skill/sync).", + inputs: vec![ + skill_id_input("The target skill ID."), + FieldSchema { + name: "method", + ty: TypeSchema::String, + comment: "RPC method name (e.g. oauth/complete, skill/ping).", + required: true, + }, + FieldSchema { + name: "params", + ty: TypeSchema::Option(Box::new(TypeSchema::Json)), + comment: "JSON params to pass to the RPC handler.", + required: false, + }, + ], + outputs: vec![FieldSchema { + name: "result", + ty: TypeSchema::Json, + comment: "RPC handler result.", + required: true, + }], + }, _ => ControllerSchema { namespace: "skills", function: "unknown", @@ -478,6 +509,14 @@ struct CallToolParams { arguments: Option, } +#[derive(Deserialize)] +struct SkillRpcParams { + skill_id: String, + method: String, + #[serde(default)] + params: Option, +} + fn handle_skills_start(params: Map) -> ControllerFuture { Box::pin(async move { let p: SkillIdParams = @@ -562,6 +601,21 @@ fn handle_skills_call_tool(params: Map) -> ControllerFuture { }) } +fn handle_skills_rpc(params: Map) -> ControllerFuture { + Box::pin(async move { + let p: SkillRpcParams = + serde_json::from_value(Value::Object(params)).map_err(|e| e.to_string())?; + let engine = require_engine()?; + engine + .rpc( + &p.skill_id, + &p.method, + p.params.unwrap_or(serde_json::json!({})), + ) + .await + }) +} + #[cfg(test)] mod tests { use super::*;