use serde_json::{Map, Value, json};
use super::fields::str_of;
use crate::boundary::Action;
use crate::registry::{mailbox, tools};
pub(super) const ADVERTISE: &str = "advertise";
pub(super) const INVOKE: &str = "invoke";
pub(super) const COMPLETE: &str = "complete";
pub(super) fn encode(set: &[tools::Tool]) -> Value {
json!({ "op": ADVERTISE, "tools": tools::encode(set) })
}
pub(super) fn encode_route(verb: &mailbox::Verb) -> Value {
match verb {
mailbox::Verb::Invoke(call) => json!({ "op": INVOKE, "client": call.client,
"tool": call.tool, "input": call.input }),
mailbox::Verb::Complete(done) => {
json!({ "op": COMPLETE, "invocation": done.invocation,
"capture": mailbox::capture_value(&done.capture) })
}
}
}
pub(super) fn decode(op: &str, o: &Map<String, Value>) -> Result<Action, String> {
match op {
INVOKE => Ok(Action::Route(mailbox::Verb::Invoke(mailbox::Call {
client: str_of(o, "client")?,
tool: str_of(o, "tool")?,
input: o.get("input").cloned().ok_or("invoke: missing input")?,
}))),
COMPLETE => Ok(Action::Route(mailbox::Verb::Complete(
mailbox::Completion {
invocation: str_of(o, "invocation")?,
capture: mailbox::capture_of(o.get("capture").ok_or("complete: missing capture")?)?,
},
))),
_ => Ok(Action::Advertise {
tools: tools::decode(o.get("tools").ok_or("advertise: missing tools")?)?,
}),
}
}