Skip to main content

Module command_support

Module command_support 

Source
Expand description

Generic adoption helpers for the client command channel.

A client protocol opts into injected commands (the dashboard’s [send] button, and any future programmatic control) with a ~10-line diff to its connection loop:

ⓘ
let mut command_rx = command_support::register_command_channel(&app_state, client_id).await;
// ... inside the read loop:
tokio::select! {
    read = read_half.read(&mut buffer) => { /* existing arms unchanged */ }
    Some(cmd) = command_rx.recv() => {
        if command_support::handle_stream_client_command(
            &MyClientProtocol, &write_half_arc, cmd, client_id, &app_state, &status_tx,
        ).await { break; }
    }
}

handle_stream_client_command is fully generic for split-stream clients: it executes the action through the protocol’s own execute_action (the same machinery LLM-produced actions use), writes SendData results to the write half, and replies with a ClientSendOutcome. A protocol whose vocabulary produces Custom results (IRC’s send_privmsg, for instance) writes its own arm body and uses reply directly.

Concurrency note: the command arm runs in the same single task as the read loop, so a command never races the loop’s own writes. A command arriving while the loop is mid-LLM-call simply waits its turn in the bounded channel; user injection is deliberately independent of the protocol’s Idle/Processing state machine.

Cancellation-safety note for adopters: AsyncReadExt::read is cancellation-safe, so wrapping it in tokio::select! with the command arm does not lose data.

Functions§

handle_stream_client_command
Generic command-arm body for split-stream clients. Executes the action, maps the result to wire writes, records a client access-log entry, and replies on the command’s oneshot.
register_command_channel
Create and register the command channel for a running client. Call once the connection is established; move the returned receiver into the loop task.
reply
Reply on a command’s oneshot, tolerating a caller that stopped listening.