- 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.
48 lines
1.4 KiB
Rust
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?)?) })
|
|
}
|
|
}
|