@abhishek944/pi-ask0.4.3
A lightweight one-shot ask command for Pi with a limited tool set.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-ask
A small Pi extension for simple, one-shot questions.
/ask temporarily narrows Pi's active tools for one answer and restores the exact previous tool set when it finishes or is cancelled. It adds no Ask Mode instructions to the conversation and needs no reset or clear command. Later prompts use the previous tools normally.
Install
From npm:
pi install npm:@abhishek944/pi-ask
Or directly from GitHub:
pi install git:github.com/abhishek944/pi-ask@v0.4.3
Restart Pi after installing, or run /reload in an existing session.
Use
/ask What does this function return?
The question runs with only the approved tools that were already active:
readgrepfindlsweb_enableweb_searchsource_checkfetch_contentget_search_contentimage_generatesprite_generateMonitorListLoopListWorkListTodoList
web_enable can activate the configured web lookup tools during the answer. Sprite generation requires pi-image-gen.spriteGeneration.enabled to be true. Allowlisting a tool does not install or enable a disabled extension.
Shell access and file-changing tools such as bash, edit, and write are unavailable. Other unapproved extension tools are unavailable too.
Image and sprite generation are intentionally allowed and may create output files. Work, todo, loop, and monitor mutations remain unavailable. All other project-file changes are blocked by removing those tools and by a second check immediately before any tool call.
When the answer settles, Pi restores the exact tool list that was active before /ask. If startup fails before an answer begins, the next idle prompt automatically restores that list before it is processed.
Run /ask tools for a local capability report. It starts no model turn and changes no tools. The report labels itself a preview when Ask is not active, and lists the actual effective tools while an Ask answer is running. It separates allowlisted tools that are active, allowlisted tools that are registered in Pi but inactive, and allowlisted names that are not registered at all; a missing name does not tell Pi Ask why it is missing. If another extension owns the current restricted run, the report says so instead of presenting that run's tools as Ask's policy.
The report repeats the fixed boundaries: shell and file-changing tools and work, todo, loop, and monitor mutations stay blocked, while image_generate and sprite_generate may create image files. Registration or active status is not a health check; a tool or provider can still fail at runtime. /ask tools must be typed exactly; other text after /ask remains a question.
Reusable guard
Other Pi extensions can request the same guard through Pi's shared event bus. The guard narrows the current tool set, checks every tool call again immediately before execution, supports exact top-level input constraints, and restores the previous tools after agent_settled or session shutdown.
import type { PiAskGuardAcquireRequest } from "@abhishek944/pi-ask/guard";
const request: PiAskGuardAcquireRequest = {
ownerId: "my-extension:restricted-run",
allowedTools: [
"read",
"grep",
{ name: "my_status_tool", equals: { id: "expected-id" } },
],
context: "This run is read-only.",
startsRun: true,
};
pi.events.emit("pi-ask:guard:acquire", request);
if (request.response?.status !== "active" || !request.response.acquisitionToken) {
// Fail closed: do not start the unrestricted agent run.
}
// If startup fails before the run begins, release with the exact returned token:
function cancelBeforeStart() {
pi.events.emit("pi-ask:guard:release", {
ownerId: request.ownerId,
acquisitionToken: request.response!.acquisitionToken!,
});
}
Built-in tool names are accepted only when pi.getAllTools() reports Pi's matching built-in provenance, so an extension cannot replace read and inherit permission by name. Rules for extension tools can add sourceInfo: { source, path } when the caller depends on one exact implementation; Pi Ask verifies that metadata before activation.
Only one restricted run can own the guard at a time. Callers must require the synchronous active response before starting work. Pi must be idle before a caller acquires with startsRun: true and immediately invokes pi.sendMessage(..., { triggerTurn: true }); this lets Pi Ask associate restoration with that complete run rather than with retry-level starts. Programmatic custom-message runs do not emit before_agent_start, so callers must also include any required guard context in the message itself.
Extensions that start unguarded custom-message runs during another run's settlement should emit pi-ask:guard:run-start immediately before pi.sendMessage. This keeps complete-run ordering intact for a later guarded wake. The event is only a lifecycle marker and does not activate restrictions. In ordinary agent runs, restoration is automatic; pi-ask:guard:release is available for a caller that must cancel before the agent starts. Pi Ask emits pi-ask:guard:released after restoration so waiting clients can resume without polling.
The guard module is exported as @abhishek944/pi-ask/guard. The pi-ask extension must also be loaded so its shared-event listeners are registered.
Notes
/askneeds a question. Running it without text shows a short usage message.- Lookup, status, image, and sprite tools are optional. Pi uses them only when helpful.
- Wait for the
/askanswer to finish before sending another agent prompt. Anything queued into the same agent run keeps the limited tool set until Pi settles. - Built-in slash commands and shell commands typed directly by the user are outside this model-tool guardrail.
- This is an extension-level guardrail, not an operating-system sandbox.
License
Apache-2.0