Holds the history lock for a turn, 600 s grace period, interim texts as core.notify. Tests with a fake LLM in the real core. The SDK tests of /proc, /self, /run, and detached notifications now run.
82 lines
2.9 KiB
Rust
82 lines
2.9 KiB
Rust
//! Use typed calls from discovered provider documents in `imports/`.
|
|
//! Generated modules own the wire types, so calls need no manual JSON.
|
|
//! The detached HTTP service survives this consumer. Its endpoint refers to that service's process-local state.
|
|
//! Copy fresh documents from `/proc/core/plugins/<provider>/discover.json` after an interface changes.
|
|
use sausage_plugin::{Result, rpc, schema};
|
|
sausage_plugin::import!("notes");
|
|
sausage_plugin::import!("www");
|
|
sausage_plugin::import!("secrets");
|
|
/// Demonstrate typed imports without manual JSON messages.
|
|
struct Consumer;
|
|
/// A note for the imported notes plugin.
|
|
#[schema]
|
|
struct NoteParams {
|
|
/// The text to append.
|
|
text: String,
|
|
}
|
|
/// The text and HTTP port for this demonstration.
|
|
#[schema]
|
|
struct DemoParams {
|
|
/// The note text to append.
|
|
text: String,
|
|
/// The port for the detached HTTP server.
|
|
port: u16,
|
|
}
|
|
#[rpc]
|
|
impl Consumer {
|
|
/// Add a note through the generated import and return its count.
|
|
async fn note(&self, p: NoteParams) -> Result<usize> {
|
|
Ok(notes::add(notes::AddParams { text: p.text }).await?.count as usize)
|
|
}
|
|
/// Add a note, start a server, and inspect its control endpoint.
|
|
async fn demo(&self, p: DemoParams) -> Result<u64> {
|
|
let added = notes::add(notes::AddParams { text: p.text }).await?;
|
|
eprintln!("{} notes", added.count);
|
|
let pid = www::start(www::StartParams { port: p.port })
|
|
.detach()
|
|
.await?;
|
|
let control = www::control::connect(format!("/proc/{pid}/control")).await?;
|
|
control.stats().await
|
|
}
|
|
/// Store and read a value through the boot service's fixed endpoint.
|
|
async fn vault(&self) -> Result<Option<String>> {
|
|
let vault = secrets::vault::connect("/run/secrets").await?;
|
|
vault
|
|
.put(secrets::PutParams {
|
|
name: "example".into(),
|
|
value: "hello".into(),
|
|
})
|
|
.on_notify(|name, params| eprintln!("{name}: {params}"))
|
|
.await?;
|
|
vault
|
|
.get(secrets::GetParams {
|
|
name: "example".into(),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
/// Start the SDK transport for this plugin.
|
|
fn main() {
|
|
sausage_plugin::run(Consumer)
|
|
}
|
|
/// Tests check generated wire types without other plugins in the test world.
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
/// Generated params retain their wire field names.
|
|
#[test]
|
|
fn generated_params_use_text() {
|
|
let value = sausage_plugin::serde_json::to_value(notes::AddParams {
|
|
text: "milk".into(),
|
|
})
|
|
.unwrap();
|
|
assert_eq!(value, sausage_plugin::serde_json::json!({"text":"milk"}));
|
|
}
|
|
/// A generated result decodes without another plugin in the test world.
|
|
#[test]
|
|
fn generated_result_decodes_count() {
|
|
let added: notes::Added = sausage_plugin::serde_json::from_str(r#"{"count":2}"#).unwrap();
|
|
assert_eq!(added.count, 2);
|
|
}
|
|
}
|