ask

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 6 Imported by: 0

README

ask

Extension. Ejectable — the loop never names it. Without it the agent can only guess when it needs a human decision; with it the agent asks a structured question and the run parks until the answer arrives.

Model Experience

The legacy Go driver uses the dangling-call workflow below. The native engine uses the Go argument preparer, which trims and bounds fields while retaining valid UTF-8 at byte limits. The native engine emits an immutable waiting tool result; the host parks the run using the settled effect receipt. A human answer is a new native user message on resume, rather than a replacement of that result. The physical effect ID keeps questions distinct even when a provider reuses a tool-call ID. An unanswered resume makes no model request; durable native message events prevent a recorded answer from being delivered twice.

A question parks the run

The model calls ask with a prompt, optional labeled options, and a multi flag. The tool never returns a result: a valid call ends the run parked (ErrParked), the call stays dangling in the durable log behind an EntryQuestion, and the run row settles as waiting.

Token effect

Zero while parked — no model call runs until the human answers.

KV cache effect

Append-only. The answer lands as the call's tool result on resume.

The answer is the tool result

The human's reply is recorded as an EntryAnswer keyed on the call id; a resumed run closes the dangling call with that text — the model sees the answer exactly as if ask had returned it. A resume that finds the question still unanswered re-issues the call (the tool is retry-safe), which re-parks the run on the same question.

What it cannot do

  • Ask on unattended runs. The host advertises it only on chat-triggered runs; a scheduled, webhook, delegate, or manual run never sees the tool.
  • Ask twice in one call. One question per call; a second question is a second call.
  • Block the process. Parking ends the run — nothing waits in memory, so a restart while parked loses nothing: the question is durable and the resume re-asks or delivers the stored answer.

Documentation

Overview

Package ask contributes the `ask` tool: the agent poses a structured question to the human — a prompt plus labeled options, optionally multi-select — and the run parks until the answer arrives.

Parking is a loop mechanism, not a block: Run returns agentcore.ErrParked, the loop records an EntryQuestion for the call and ends the run WITHOUT a tool result, leaving the call dangling in the durable log. The answer arrives out-of-band as an EntryAnswer keyed on the same call id; a resumed run closes the dangling call with that answer as its tool result — the model sees the human's reply exactly as if the tool had returned it. A resume that finds the question still unanswered re-issues the call (the tool is retry-safe), which parks the run again on the same question.

The tool is advertised only where a human can answer — the host wires it on chat-triggered runs and leaves it off scheduled/webhook/delegate/manual runs. It is self-gated: it returns nothing but what the user typed, so it cannot reach anything the run does not already have.

Index

Constants

View Source
const ToolName = "ask"

ToolName is the model-visible identifier.

Variables

This section is empty.

Functions

func QuestionText

func QuestionText(raw json.RawMessage) string

QuestionText renders the bounded question for hosts with a plain-text human channel. Structured clients may render the original payload directly.

Types

type Option

type Option struct {
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
}

Option is one labeled choice the human can pick.

type Plugin

type Plugin struct{}

Plugin offers questions on an interactive top-level run. Delegated children report missing information to their parent, which owns the human channel.

func (Plugin) BeginRun

func (Plugin) Name

func (Plugin) Name() string

func (Plugin) Register

func (p Plugin) Register(r *agentcore.Registry) error

func (Plugin) SelfGated

func (Plugin) SelfGated() bool

func (Plugin) Tools

func (Plugin) Tools() []agentcore.Tool

type Tool

type Tool struct{}

Tool is the ask capability. It carries no state: everything durable lives in the session log the loop writes, so the same value serves every run.

func (Tool) Name

func (Tool) Name() string

Name identifies the tool.

func (Tool) PiArgumentPreparation

func (Tool) PiArgumentPreparation() string

PiArgumentPreparation selects this plugin's bundled synchronous Pi hook.

func (Tool) PrepareArguments

func (Tool) PrepareArguments(raw string) string

PrepareArguments normalizes the raw call before validation: clamps bound the question and options so the durable EntryQuestion records the form the human actually sees.

func (Tool) RetrySafe

func (Tool) RetrySafe() bool

RetrySafe makes a dangling ask re-issue on resume: re-parking on the same question is the correct recovery when the answer never arrived.

func (Tool) Run

func (Tool) Run(_ context.Context, raw string) (string, error)

Run never produces a result: a valid call parks the run. The answer reaches the model through the durable log (EntryAnswer), not through this return.

func (Tool) Schema

func (Tool) Schema() agentcore.ToolSchema

Schema advertises the tool to the model.

func (Tool) SelfGated

func (Tool) SelfGated() bool

SelfGated exempts the tool from the permission policy: it returns only what the user typed, so it reaches nothing the run does not already have.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL