@luan.sh/pi-conversation
Async user conversations and interruptible clock tools for Pi
Package details
Install @luan.sh/pi-conversation from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@luan.sh/pi-conversation- Package
@luan.sh/pi-conversation- Version
0.1.0- Published
- Oct 5, 2026
- Downloads
- not available
- Author
- cfcluan
- License
- MIT
- Types
- extension
- Size
- 26.3 MB
- Dependencies
- 4 dependencies · 5 peers
Pi manifest JSON
{
"extensions": [
"./src/extension.ts",
"./node_modules/@luan.sh/pi-libtui/src/extension.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-conversation
Asynchronous questions, user-facing messages, and interruptible clock tools for Pi. The model can ask a question while continuing independent work.
Install
pi install ./harnesses/pi/agent/packages/pi-conversation
Enable request_user_input_async, send_message_to_user_async, clock__sleep, and clock__curr_time
in Pi's tool selection. Keep these control tools direct. The managed harness
loads and selects them already. No Pi source changes are needed.
Questions and messages
request_user_input_async accepts {questions: [{title, options?}]} and returns
{"accepted":true} immediately. The tool call ID identifies the group.
Questions appear inline above the chat editor. Click a suggested answer, or click
the text field and type your own. Enter or Next/Send submits the typed answer.
Groups show one question at a time; Back revisits an earlier answer. Escape
returns focus to chat and preserves the draft. No modal or opening button is needed;
preselection never submits an answer.
The whole group is submitted after every question has an answer. Answers arrive through Pi's steering queue and wake a waiting model. The transcript shows the answer once; its tool correlation envelope stays hidden. Click Dismiss to dismiss the visible group; its response explicitly reports that dismissal is not approval. Questions and submitted answers persist across resume and rollover. If Pi stops before an answer leaves its steering queue, the next model request recovers it from the transcript.
send_message_to_user_async({message}) displays a durable user-facing message
without ending the turn and returns {"accepted":true}. Use it for an answer
or finding the user needs during ongoing work. Routine progress still belongs
in commentary.
Child agents use their parent's mailbox. These two tools reject root-user interaction from all child agents, including interactive side sessions.
Clock and persistence
clock__curr_time({}) returns the current UTC time. clock__sleep({duration_ms})
waits for 1 ms through 12 hours and reports elapsed wall time and whether new
input interrupted the wait. Its presentation details retain elapsed_ms and
reason (elapsed, input, or cancelled). New input, submitted answers, and shutdown wake the wait.
Pi must remain running; this is an active-session wait, not an OS scheduler.
Questions, messages, and clock tools work in ordinary mode. This extension does not select reasoning or own persistent mode. For Codex Persistent reasoning, use Codex Native settings' Reasoning mode (this session) setting. Its compiled default is Use Pi thinking level. The provider owns the Codex instructions, backend effort mapping, and current-time reminder defaults.
With Codex Native installed, Astra exposes async questions and clock tools from
its catalog. Async messages require Async messages to be enabled; the managed
harness enables it. Sleep also follows the feature, model, and time-reminder
settings. The provider exposes clock.curr_time and clock.sleep on the wire and
routes them to Pi's local clock__curr_time and clock__sleep tools. Execution
checks the same availability policy as request construction.
Actions and UI
Tool rows show readable actions and outcomes, including the checked time, requested wait, and whether input resumed it. Expand a question row to inspect its choices. Async messages appear once as formatted transcript text.
The visible controls are the normal workflow. The existing /questions command remains an optional keyboard alternative, not a setup step.
Notes, history, and context rollover are model tools; ask for normal work and
let the model use them when needed.
| Action ID | Behavior |
|---|---|
conversation.questions.open |
Focus the inline question card. |
Bind actions through keybindings.json; the extension owns no default keys.
The TUI uses pi-libtui's inline input, selectable rows, and semantic colors. RPC clients use Pi's
standard select/input requests automatically when a question is created. Headless sessions persist
questions but need a user-capable client to answer them.
Architecture
| Responsibility | Owner |
|---|---|
| Tool schemas and execution | src/tools/request-user-input, send-user-message, sleep, current-time |
| Persisted questions, answers, validation | src/core/state.ts |
| Delivery, restrictions, wake routing | src/runtime/conversation.ts |
| Interruptible timer | src/runtime/sleep.ts |
| Model instructions | src/contributions |
| Inline questions and widget | src/ui/questions.ts; pi-libtui |
| RPC question dialogs | src/ui/rpc-questions.ts |
| Tool presentation | src/tools/presentation.ts; shared ToolActivity rows and durable message/answer entries |
| Native boundary | None; Pi owns the run loop and transcript |
| Public library surface | src/index.ts exports validated state helpers |