Skip to main content

Context

Struct Context 

Source
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: bool

Implementations§

Source§

impl Context<'_>

Source

pub fn notify(&mut self, level: &str, message: &str)

Pushes a toast to the host (level: info | warning | error).

Examples found in repository?
examples/full.rs (line 28)
5fn main() -> Result<(), phi::Error> {
6    let mut m = phi::Extension::new("full", "0.1.0");
7
8    m.register_tool(phi::Tool::new(
9        "echo",
10        "Echo the input back",
11        phi::Schema::object()
12            .property("text", phi::Schema::string())
13            .required(["text"]),
14        |args| {
15            let text = String::from_utf8_lossy(args);
16            Ok(phi::ToolResult {
17                content: format!("echo: {text}"),
18                ..Default::default()
19            })
20        },
21    ));
22
23    m.register_command(
24        "ask",
25        phi::Command::new("Ask a yes/no question", |_args, ctx| {
26            let reply = ctx.confirm("Confirm?", "Proceed with /tmp/x?");
27            if reply.ok {
28                ctx.notify("info", "Confirmed!");
29            } else {
30                ctx.notify("warning", "Declined.");
31            }
32            ctx.submit("follow-up from ask");
33            Ok(())
34        }),
35    );
36
37    m.run()
38}
More examples
Hide additional examples
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}
Source

pub fn set_status(&mut self, text: &str)

Updates the host footer extension status (empty text clears).

Source

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 32)
5fn main() -> Result<(), phi::Error> {
6    let mut m = phi::Extension::new("full", "0.1.0");
7
8    m.register_tool(phi::Tool::new(
9        "echo",
10        "Echo the input back",
11        phi::Schema::object()
12            .property("text", phi::Schema::string())
13            .required(["text"]),
14        |args| {
15            let text = String::from_utf8_lossy(args);
16            Ok(phi::ToolResult {
17                content: format!("echo: {text}"),
18                ..Default::default()
19            })
20        },
21    ));
22
23    m.register_command(
24        "ask",
25        phi::Command::new("Ask a yes/no question", |_args, ctx| {
26            let reply = ctx.confirm("Confirm?", "Proceed with /tmp/x?");
27            if reply.ok {
28                ctx.notify("info", "Confirmed!");
29            } else {
30                ctx.notify("warning", "Declined.");
31            }
32            ctx.submit("follow-up from ask");
33            Ok(())
34        }),
35    );
36
37    m.run()
38}
Source

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.

Source

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 26)
5fn main() -> Result<(), phi::Error> {
6    let mut m = phi::Extension::new("full", "0.1.0");
7
8    m.register_tool(phi::Tool::new(
9        "echo",
10        "Echo the input back",
11        phi::Schema::object()
12            .property("text", phi::Schema::string())
13            .required(["text"]),
14        |args| {
15            let text = String::from_utf8_lossy(args);
16            Ok(phi::ToolResult {
17                content: format!("echo: {text}"),
18                ..Default::default()
19            })
20        },
21    ));
22
23    m.register_command(
24        "ask",
25        phi::Command::new("Ask a yes/no question", |_args, ctx| {
26            let reply = ctx.confirm("Confirm?", "Proceed with /tmp/x?");
27            if reply.ok {
28                ctx.notify("info", "Confirmed!");
29            } else {
30                ctx.notify("warning", "Declined.");
31            }
32            ctx.submit("follow-up from ask");
33            Ok(())
34        }),
35    );
36
37    m.run()
38}
Source

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> 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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, !>

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.