pub struct Context<'a> {
pub cwd: String,
pub session_id: String,
pub has_ui: bool,
/* private fields */
}Expand description
Interaction surface handed to command handlers. All host traffic goes
over the same PXB pipe the run loop owns — a handler may block the loop
(e.g. confirm reads nested frames).
Fields§
§cwd: String§session_id: String§has_ui: boolImplementations§
Source§impl Context<'_>
impl Context<'_>
Sourcepub fn notify(&mut self, level: &str, message: &str)
pub fn notify(&mut self, level: &str, message: &str)
Pushes a toast to the host (level: info | warning | error).
Examples found in repository?
examples/hello.rs (line 11)
5fn main() -> Result<(), phi::Error> {
6 let mut m = phi::Extension::new("hello", "0.1.0");
7
8 m.register_command(
9 "hello",
10 phi::Command::new("Say hi", |_args, ctx| {
11 ctx.notify("info", "Hello!");
12 // ctx.submit("follow-up"); // after /hello returns
13 // ctx.send_user_message("…"); // enqueue a turn anytime
14 Ok(())
15 }),
16 );
17
18 m.on_user_input(|_ev| {
19 // return Some(phi::UserInputResult { handled: true, ..Default::default() }) to swallow
20 // return Some(phi::UserInputResult { text: Some("rewritten".into()), ..Default::default() }) to transform
21 None
22 });
23
24 m.on_tool_call(|_ev| {
25 // return Some(phi::ToolCallResult { block: true, reason: "...".into(), ..Default::default() }) to deny
26 None
27 });
28
29 m.on_tool_result(|_ev| {
30 // return Some(phi::ToolResultResult { stop: true, ..Default::default() }) to end the agent loop
31 None
32 });
33
34 m.on_turn_stopping(|_ev| {
35 // return Some(phi::TurnStoppingResult { continue_: true, message: "check X".into(), ..Default::default() }) to steer
36 None
37 });
38
39 m.subscribe(pxb::Event::SessionStart, |ev| {
40 let _ = ev; // Reason, PreviousSessionID, …
41 });
42
43 m.run()
44}More examples
examples/full.rs (line 52)
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}Sourcepub fn set_status(&mut self, text: &str)
pub fn set_status(&mut self, text: &str)
Updates the host footer extension status (empty text clears).
Sourcepub fn submit(&mut self, text: &str)
pub fn submit(&mut self, text: &str)
Queues a prompt for the host to send after the current slash command returns.
Examples found in repository?
examples/full.rs (line 56)
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}Sourcepub fn send_user_message(&mut self, text: &str)
pub fn send_user_message(&mut self, text: &str)
Asks the host to enqueue a user turn (fire-and-forget). Safe to call from command handlers on the PXB read loop.
Sourcepub fn confirm(&mut self, title: &str, message: &str) -> ConfirmReply
pub fn confirm(&mut self, title: &str, message: &str) -> ConfirmReply
Shows a yes/no dialog on the host and waits for the answer.
Examples found in repository?
examples/full.rs (line 50)
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}Sourcepub fn confirm_opts(&mut self, req: ConfirmRequest) -> ConfirmReply
pub fn confirm_opts(&mut self, req: ConfirmRequest) -> ConfirmReply
confirm with labels / danger styling.
Auto Trait Implementations§
impl<'a> !RefUnwindSafe for Context<'a>
impl<'a> !Send for Context<'a>
impl<'a> !Sync for Context<'a>
impl<'a> !UnwindSafe for Context<'a>
impl<'a> Freeze for Context<'a>
impl<'a> Unpin for Context<'a>
impl<'a> UnsafeUnpin for Context<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more