Skip to main content

full/
full.rs

1//! Richer example: a tool, a confirm dialog, and a queued follow-up.
2
3use phi_ext::phi;
4
5fn main() -> Result<(), phi::Error> {
6    let mut m = phi::Extension::new("full", "0.1.0");
7
8    m.register_tool(
9        phi::Tool::new(
10            "echo",
11            "Echo the input back",
12            phi::Schema::object()
13                .property("text", phi::Schema::string())
14                .required(["text"]),
15            |args| {
16                let text = String::from_utf8_lossy(args);
17                Ok(phi::ToolResult {
18                    content: format!("echo: {text}"),
19                    ..Default::default()
20                })
21            },
22        )
23        .detail_from_args(|args| String::from_utf8_lossy(args).into_owned()),
24    );
25
26    m.register_tool(
27        phi::Tool::new_async(
28            "async-echo",
29            "Echo the input back (async handler)",
30            phi::Schema::object()
31                .property("text", phi::Schema::string())
32                .required(["text"]),
33            |args| async move {
34                // Yield once: proves the SDK's runtime drives the future
35                // rather than just polling a ready block.
36                tokio::task::yield_now().await;
37                let text = String::from_utf8_lossy(&args);
38                Ok(phi::ToolResult {
39                    content: format!("async echo: {text}"),
40                    ..Default::default()
41                })
42            },
43        )
44        .timeout_sec(10),
45    );
46
47    m.register_command(
48        "ask",
49        phi::Command::new("Ask a yes/no question", |_args, ctx| {
50            let reply = ctx.confirm("Confirm?", "Proceed with /tmp/x?");
51            if reply.ok {
52                ctx.notify("info", "Confirmed!");
53            } else {
54                ctx.notify("warning", "Declined.");
55            }
56            ctx.submit("follow-up from ask");
57            Ok(())
58        }),
59    );
60
61    m.run()
62}