Skip to main content

ClientToolDecl

Struct ClientToolDecl 

Source
pub struct ClientToolDecl {
    pub name: String,
    pub effect: Effect,
    pub input_schema: Value,
    pub output_schema: Option<Value>,
    pub trust_completion: bool,
    pub require_equal: Vec<String>,
    pub idempotency_key: Vec<String>,
}
Expand description

One operator-written declaration of a tool the CLIENT performs.

There is no handler behind it. It exists so this server can do the things it CAN honestly do about a call it never witnessed: fix the effect class, check the input before an intent is recorded, check the reported output against a shape the operator declared, pin named fields so a report cannot alter what was authorized, and decide whether the client’s report is allowed to close the call at all.

Unknown keys are rejected rather than ignored. A misspelled key like require_equal would otherwise be dropped silently, leaving a guard the operator meant to set quietly absent, and the mistake would not surface until a client had already altered a field the operator meant to pin. Refusing early, precisely, is the rule.

The declaration deserializes through [RawClientToolDecl] so a cross-field rule the field-by-field format cannot express is enforced at load: every require_equal name must be required on both sides. A file that breaks it fails to parse, naming the field and the missing side.

Fields§

§name: String

The tool’s name, the one a client names when it opens an intent.

§effect: Effect

The operator-declared effect class, recorded on every intent for this tool. Never taken from the client, for the reason in the module docs.

§input_schema: Value

The schema an intent’s input must satisfy, checked with salvor_runtime::validate_against_schema before anything is written.

§output_schema: Option<Value>

The schema a client-reported completion must satisfy. Optional in the format, because a declaration is still useful without one (the effect and the input check both still apply), but a tool declared without it cannot be self-completed by a client: an unfalsifiable completion is precisely what the schema exists to prevent.

§trust_completion: bool

Whether the client may record its own completion for this tool. false by default: silence gets the safe direction, and self-completing a write on the client’s word alone is the convenient direction, so it is an explicit opt-in. false means every call for this tool is settled by hand through the resolve endpoint after someone has verified it externally.

§require_equal: Vec<String>

Top-level field names whose client-reported value must equal the intent’s recorded value. Empty by default. Every named field must appear in both input_schema.required and output_schema.required, checked at load, so the two values always exist to compare; at the completion boundary a reported value that differs from the authorized one refuses the completion. The output schema is a shape check and cannot know what was authorized; this is the field-level equality the shape check cannot do.

§idempotency_key: Vec<String>

Top-level input field names that, together, say what one call for this tool IS. Empty by default, and empty means the key stays positional.

A client-performed call always gets a server-derived idempotency key (see client_tool_idempotency_key), because the client must not be the one choosing it. What the operator chooses here is what the derivation is over. With no fields named, the key is derived from the call’s POSITION in the run, which is an attempt identifier: the same position retried presents the same key, and that is all it promises. Naming fields makes it a content identity instead: ["order_id", "amount_cents"] says that a refund of that amount against that order is one refund, wherever in the run it is asked for, so a loop that asks for it twice gets the first call’s answer back rather than a second refund.

Each name is a top-level field of the intent’s input. A field the input does not carry is refused at the intent boundary, naming it, rather than silently deriving a key over a missing value: two different calls would otherwise collapse onto one identity.

Trait Implementations§

Source§

impl Clone for ClientToolDecl

Source§

fn clone(&self) -> ClientToolDecl

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClientToolDecl

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ClientToolDecl

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more