Files
sausage/sdk/src/imports.rs
T
surma c728429d04 sdk, agent: review fixes (T18R)
- The serve loop ends the process after EOF or exit_after_response,
  also with background tasks or listeners.
- One schema generator per direction for the whole document, so types
  with the same name get distinct names.
- The agent gives the complete error (code, message, data) to the
  model, writes SKIP only after a successful request, caps tool output
  at 64 KiB, writes each history line in one write, and skips a damaged
  line.
- Endpoints skip blank and non-RPC lines. client_rs does not panic.
- #[must_use] on builders and the lock guard; #[schemars] attributes
  and duplicate hooks are compile errors; raw identifiers; -32000 for
  local SDK errors; x-sausage-params only for methods with params.
2026-10-23 02:38:35 +01:00

48 lines
1.4 KiB
Rust

//! Typed outgoing calls and statically registered imported interfaces.
use crate::{Call, Result};
use serde_json::Value;
use std::{future::IntoFuture, marker::PhantomData};
/// An imported provider document registered by `import!`.
#[doc(hidden)]
pub struct Import {
/// The provider name.
pub name: &'static str,
/// Its complete OpenRPC document.
pub document: &'static str,
}
inventory::collect!(Import);
/// An outgoing call whose result decodes to a generated Rust type.
#[must_use = "await the call to send it"]
pub struct TypedCall<T> {
call: Call,
result: PhantomData<T>,
}
impl<T> TypedCall<T> {
/// Wrap an untyped call without sending it yet.
pub fn new(call: Call) -> Self {
Self {
call,
result: PhantomData,
}
}
/// Detach the child process from its caller.
pub fn detach(mut self) -> Self {
self.call = self.call.detach();
self
}
/// Receive progress notifications while the call runs.
pub fn on_notify(mut self, f: impl FnMut(&str, Value) + 'static) -> Self {
self.call = self.call.on_notify(f);
self
}
}
impl<T: serde::de::DeserializeOwned + 'static> IntoFuture for TypedCall<T> {
type Output = Result<T>;
type IntoFuture = futures::future::LocalBoxFuture<'static, Result<T>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { Ok(serde_json::from_value(self.call.await?)?) })
}
}