Files
openworker/coworker/tools/ask.py
T
Rohit C PrasadandDevika 2b45018ffa OpenWorker: initial import
Imported from andrewyng/aisuite@1b4bbf303e
(contents of its platform/ directory, hoisted to the repo root).
Development history prior to this commit lives in that repository.

Co-authored-by: Devika <devikaverma11@gmail.com>
2026-07-21 11:09:41 -07:00

59 lines
2.7 KiB
Python

"""The `ask_user` tool — the agent asks the user a question and waits for the answer.
The general human-in-the-loop Q&A primitive, modelled on Claude Code's own AskUserQuestion: a
question, optional quick-reply `options`, and (by default) an always-available free-text escape —
plus `multi` for choose-several. Like `request_directory`, it's intercepted by the TurnEngine: the
question becomes an Inbox item (answerable inline in the live session, or from the Inbox when the
session runs unattended), the agent suspends until it's resolved, and the answer comes back as the
tool result. The callable here is only a schema carrier + a safe fallback.
"""
from __future__ import annotations
from aisuite.agents import ToolMetadata, tool
def ask_user_tool() -> object:
def ask_user(
question: str,
options: list[str] | None = None,
allow_text: bool = True,
multi: bool = False,
header: str = "",
) -> dict:
"""Ask the user a question and wait for their answer — use when you genuinely need a human
decision or information you can't infer (a preference, a missing fact, a choice between real
alternatives). Prefer this over guessing or stalling.
- `question`: the full question, in plain language.
- `options`: optional quick-reply choices. Offer them when the answer is one of a few
discrete alternatives; leave empty for an open-ended question.
- `allow_text`: keep a free-text answer available even when you give options (the default;
this is the "Other / type your own" escape). Set False only when the options are
exhaustive and a typed answer would be meaningless.
- `multi`: allow the user to pick more than one option.
- `header`: a short (≤ ~12 char) label for the Inbox card chip, e.g. "Region".
Returns `{"answer": "..."}` — the chosen option(s) or the typed text. Don't ask what you can
reasonably decide yourself; reserve this for choices that are actually the user's to make.
"""
# Real handling lives in the engine (it needs the out-of-band Inbox round-trip). This body
# only runs if no question_asker is wired (e.g. a headless surface).
return {
"answer": "",
"error": "asking the user isn't available in this surface",
}
return tool(
ask_user,
metadata=ToolMetadata(
category="interaction",
risk_level="low",
capabilities=["ask_user"],
description=(
"Ask the user a question (free-text or multiple-choice) and wait for their answer. "
"Use for decisions or information only the user can provide."
),
),
)