feat: update plugin service authoring templates

This commit is contained in:
2026-06-25 16:37:37 +09:00
parent cd2006305e
commit 7a4fd97526
11 changed files with 530 additions and 80 deletions
@@ -1,6 +1,10 @@
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use yoi_plugin_pdk::wit_bindgen;
use yoi_plugin_pdk::{export_plugin_instance, Plugin, PluginIngressEvent, PluginStatus, ToolOutput};
use yoi_plugin_pdk::{
export_plugin_instance, Plugin, PluginIngressEvent, PluginStatus, ServiceOutput, ToolError,
ToolOutput,
};
wit_bindgen::generate!({
world: "instance",
@@ -9,24 +13,42 @@ wit_bindgen::generate!({
runtime_path: "yoi_plugin_pdk::wit_bindgen::rt",
});
#[derive(Default)]
struct ExamplePlugin {
calls: u64,
count: u64,
}
#[derive(Deserialize)]
struct EchoInput {
text: String,
}
#[derive(Serialize)]
struct EchoOutput {
text: String,
count: u64,
}
impl Plugin for ExamplePlugin {
fn start(_config: Value) -> yoi_plugin_pdk::Result<Self> {
Ok(Self { calls: 0 })
fn start(config: Value) -> Result<Self, ToolError> {
Ok(Self {
count: config.get("start_count").and_then(Value::as_u64).unwrap_or(0),
})
}
fn handle_tool(&mut self, name: &str, input: Value) -> yoi_plugin_pdk::Result<ToolOutput> {
self.calls += 1;
fn handle_tool(&mut self, name: &str, input: Value) -> Result<ToolOutput, ToolError> {
if name != "example_echo" {
return Err(ToolError::invalid_input(format!("unknown tool: {name}")));
}
let input: EchoInput =
serde_json::from_value(input).map_err(|err| ToolError::invalid_input(err.to_string()))?;
self.count += 1;
ToolOutput::json(
format!("{name} handled by shared instance"),
json!({
"tool": name,
"calls": self.calls,
"input": input
}),
format!("echoed {} bytes", input.text.len()),
EchoOutput {
text: input.text,
count: self.count,
},
)
}
@@ -34,18 +56,29 @@ impl Plugin for ExamplePlugin {
&mut self,
name: &str,
event: PluginIngressEvent,
) -> yoi_plugin_pdk::Result<Value> {
Ok(json!({
"ingress": name,
"kind": event.kind,
"source": event.source,
"calls": self.calls,
"accepted": true
}))
) -> Result<ServiceOutput, ToolError> {
if name != "example_ws" {
return Ok(ServiceOutput::accepted(json!({ "ignored": name }))?);
}
let Some(text) = event.websocket_text() else {
return Ok(ServiceOutput::accepted(json!({
"accepted": true,
"kind": event.kind,
}))?);
};
self.count += 1;
ServiceOutput::websocket_send(
&event,
format!("example-reply-{}", self.count),
event.source.strip_prefix("websocket:").unwrap_or(&event.source),
format!("echo({}): {text}", self.count),
)
}
fn status(&self) -> yoi_plugin_pdk::Result<PluginStatus> {
Ok(PluginStatus::ready(json!({ "calls": self.calls })))
fn status(&self) -> Result<PluginStatus, ToolError> {
Ok(PluginStatus::ready(json!({ "count": self.count })))
}
}