Signed-off-by: 未知时光 <732857315@qq.com>
This commit is contained in:
18
plugins/hermes/Cargo.toml
Normal file
18
plugins/hermes/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "agentsd-plugin-hermes"
|
||||
version = "0.16.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "agentsd-plugin-hermes"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
agentsd-plugin-sdk = { path = "../plugin-sdk" }
|
||||
agentsd-proto = { path = "../../core/proto" }
|
||||
anyhow = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true, features = ["net"] }
|
||||
tonic = { workspace = true }
|
||||
117
plugins/hermes/src/main.rs
Normal file
117
plugins/hermes/src/main.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use agentsd_plugin_sdk::{
|
||||
decode_json, err_json, export, listen_addr_from_env, ok_json, plugin_endpoint_from_env,
|
||||
plugin_info_with_endpoint, register,
|
||||
};
|
||||
use agentsd_proto::agentsd::{
|
||||
plugin_bridge_server::{PluginBridge, PluginBridgeServer},
|
||||
CallRequest, CallResponse, HeartbeatRequest, HeartbeatResponse, PluginInfo, RegisterResponse,
|
||||
};
|
||||
use anyhow::{ensure, Result};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_stream::wrappers::TcpListenerStream;
|
||||
use tonic::{transport::Server, Request, Response, Status};
|
||||
|
||||
const PLUGIN_ID: &str = "hermes";
|
||||
const PLUGIN_NAME: &str = "Hermes Agent Tools";
|
||||
const PLUGIN_VERSION: &str = "0.16.0";
|
||||
const PLUGIN_TYPE: &str = "basic";
|
||||
const PLUGIN_PORT: u16 = 50052;
|
||||
const SYSCALLS: &[&str] = &[
|
||||
"network.request",
|
||||
"fs.read",
|
||||
"fs.write",
|
||||
"process.spawn",
|
||||
"memory.read",
|
||||
"memory.write",
|
||||
"display.text",
|
||||
"timer.once",
|
||||
];
|
||||
|
||||
#[derive(Default)]
|
||||
struct HermesPlugin;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct EchoArgs {
|
||||
#[serde(default)]
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl PluginBridge for HermesPlugin {
|
||||
async fn register(
|
||||
&self,
|
||||
_req: Request<PluginInfo>,
|
||||
) -> std::result::Result<Response<RegisterResponse>, Status> {
|
||||
Err(Status::unimplemented("hermes plugin is not an agentsd bridge"))
|
||||
}
|
||||
|
||||
async fn call(
|
||||
&self,
|
||||
req: Request<CallRequest>,
|
||||
) -> std::result::Result<Response<CallResponse>, Status> {
|
||||
let req = req.into_inner();
|
||||
let response = match req.r#fn.as_str() {
|
||||
"echo" => match decode_json::<EchoArgs>(&req.args) {
|
||||
Ok(args) => ok_json(&json!({ "result": format!("hermes: {}", args.text) })),
|
||||
Err(err) => err_json(format!("invalid echo args: {err}")),
|
||||
},
|
||||
other => err_json(format!("unknown export: {other}")),
|
||||
};
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
type StreamCallStream = tokio_stream::wrappers::ReceiverStream<std::result::Result<CallResponse, Status>>;
|
||||
|
||||
async fn stream_call(
|
||||
&self,
|
||||
_req: Request<CallRequest>,
|
||||
) -> std::result::Result<Response<Self::StreamCallStream>, Status> {
|
||||
Err(Status::unimplemented("stream_call is not implemented for hermes"))
|
||||
}
|
||||
|
||||
async fn heartbeat(
|
||||
&self,
|
||||
_req: Request<HeartbeatRequest>,
|
||||
) -> std::result::Result<Response<HeartbeatResponse>, Status> {
|
||||
Ok(Response::new(HeartbeatResponse { ok: true }))
|
||||
}
|
||||
}
|
||||
|
||||
fn plugin_info(endpoint: &str) -> PluginInfo {
|
||||
plugin_info_with_endpoint(
|
||||
PLUGIN_ID,
|
||||
PLUGIN_NAME,
|
||||
PLUGIN_VERSION,
|
||||
PLUGIN_TYPE,
|
||||
SYSCALLS,
|
||||
&[],
|
||||
vec![export("echo", "Echo test route for Hermes plugin")],
|
||||
endpoint,
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let endpoint = plugin_endpoint_from_env(PLUGIN_PORT);
|
||||
let listen_addr: std::net::SocketAddr = listen_addr_from_env(PLUGIN_PORT).parse()?;
|
||||
let listener = TcpListener::bind(listen_addr).await?;
|
||||
let incoming = TcpListenerStream::new(listener);
|
||||
|
||||
let channel = agentsd_plugin_sdk::connect().await?;
|
||||
let resp = register(channel, plugin_info(&endpoint)).await?;
|
||||
ensure!(resp.ok, "register failed: {}", resp.error);
|
||||
|
||||
println!(
|
||||
"Hermes plugin registered: id={} type={} endpoint={} session={}",
|
||||
PLUGIN_ID, PLUGIN_TYPE, endpoint, resp.session_id
|
||||
);
|
||||
println!("Hermes PluginBridge server listening on {}", listen_addr);
|
||||
|
||||
Server::builder()
|
||||
.add_service(PluginBridgeServer::new(HermesPlugin::default()))
|
||||
.serve_with_incoming(incoming)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user