nexus_sdk/types/
tool_meta.rs1use {
2 crate::{move_bindings::interface::meta_schema::MetaSchema, ToolFqn},
3 std::time::Duration,
4};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct ToolMeta {
9 pub fqn: ToolFqn,
10 pub url: String,
11 pub description: String,
12 pub timeout: Duration,
13 pub input_schema: Vec<u8>,
14 pub output_schema: Vec<u8>,
15}
16
17impl ToolMeta {
18 pub fn validate_registration(&self) -> anyhow::Result<()> {
24 anyhow::ensure!(
25 !self.description.trim().is_empty(),
26 "Tool description must not be empty"
27 );
28 Ok(())
29 }
30
31 pub fn meta_schema(&self) -> anyhow::Result<MetaSchema> {
33 MetaSchema::from_offchain_json_schemas(&self.input_schema, &self.output_schema)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 fn metadata(description: &str) -> ToolMeta {
42 ToolMeta {
43 fqn: "xyz.taluslabs.example@1".parse().unwrap(),
44 url: "https://example.invalid/tool".to_owned(),
45 description: description.to_owned(),
46 timeout: Duration::from_secs(10),
47 input_schema: br#"{"type":"object","properties":{}}"#.to_vec(),
48 output_schema: br#"{"oneOf":[{"type":"object","properties":{}}]}"#.to_vec(),
49 }
50 }
51
52 #[test]
53 fn registration_rejects_an_empty_description() {
54 let error = metadata(" \n\t")
55 .validate_registration()
56 .expect_err("blank Tool descriptions must be rejected");
57
58 assert_eq!(error.to_string(), "Tool description must not be empty");
59 }
60
61 #[test]
62 fn registration_accepts_a_meaningful_description() {
63 metadata("Returns an example result.")
64 .validate_registration()
65 .expect("meaningful Tool metadata must be accepted");
66 }
67}