userinteract

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package userinteract provides an Eino-compatible tool for asking the user a question and collecting their typed answer.

The tool operates in two surfaces:

  • SurfaceCLI: prints the question to stderr and blocks reading a multi-line answer from stdin (terminated by a blank line or EOF). Safe for interactive terminal sessions.

  • SurfaceMCP: returns immediately with OutcomePending and never reads from stdin. The caller (MCP host) is responsible for displaying the question, collecting the user's answer out of band, and supplying it in a follow-up call with Args.Answer populated.

The Surface is set at construction and does not change per call. This matches the shell.Tool pattern (workspace path set at New) and structurally prevents an MCP-surface instance from ever holding or reading a stdin Reader.

Outcome type

userinteract defines its own Outcome type (succeeded, pending, failed) rather than using result.Outcome. The "pending" state is specific to this tool's MCP surface contract; it is not a generic concept and does not belong in the shared result package (see ADR 0006).

IsRetryable

IsRetryable returns false for all outcomes, including unknown. This diverges from shell and urlfetch (which return true for unknown). The divergence is intentional: stdin I/O errors and validation errors on a human-interaction tool are not transient failures that benefit from automated retry.

Single-outstanding-question assumption

In MCP mode the tool performs no pairing validation between a pending question and a subsequent answer. If the agent loop ever has more than one question in flight simultaneously, it is the loop's responsibility to route answers correctly. The tool cannot help with correlation.

stdin line cap

In CLI mode the scanner buffer is sized to 1 MiB per line. Pasted input with a line longer than 1 MiB is returned as an io error.

Index

Constants

View Source
const (
	ErrCategoryValidation = "validation"
	ErrCategoryIO         = "io"
	ErrCategoryUnknown    = "unknown"
)
View Source
const Name = "user_interact"

Name is the model-facing tool name.

Variables

This section is empty.

Functions

func Schema

func Schema() json.RawMessage

Schema returns a fresh JSON Schema copy for userinteract arguments.

Types

type Args

type Args struct {
	Question string `json:"question"`
	// Answer is reserved for the agent loop. Do not populate this field — it
	// will be set by the loop after the user responds. When non-empty, the
	// tool returns this value as the answer immediately.
	Answer string `json:"answer,omitempty"`
}

Args is the parsed input shape for the tool.

type Options

type Options struct {
	// Stdin overrides the reader used for CLI input. Default: os.Stdin.
	Stdin io.Reader
	// Stderr overrides the writer used to print the question prompt. Default:
	// os.Stderr.
	Stderr io.Writer
}

Options configures userinteract tool behavior that is intentionally owned by the caller rather than hidden inside the tool.

type Outcome

type Outcome string

Outcome is userinteract's own discriminator. It is not result.Outcome. The "pending" outcome only exists in this tool; adding it to the shared result package would violate ADR 0001's closed-enum rule (see ADR 0006).

const (
	// OutcomeSucceeded indicates the answer is available in Result.Answer.
	OutcomeSucceeded Outcome = "succeeded"
	// OutcomePending indicates MCP mode is awaiting the user's answer via a
	// follow-up call with Args.Answer populated.
	OutcomePending Outcome = "pending"
	// OutcomeFailed indicates the tool encountered an error.
	OutcomeFailed Outcome = "failed"
)

type Result

type Result struct {
	Outcome Outcome `json:"outcome"`
	Answer  string  `json:"answer,omitempty"`
	// Question is set only when Outcome == OutcomePending. It echoes
	// Args.Question so the MCP host can display it without tracking it
	// separately.
	Question string          `json:"question,omitempty"`
	Error    *ResultError    `json:"error,omitempty"`
	RawJSON  json.RawMessage `json:"-"`
}

Result is the structured envelope returned to the model.

func (Result) IsRetryable

func (r Result) IsRetryable() bool

IsRetryable reports whether the agent loop should retry the same call. Returns false for all outcomes — see doc.go for rationale.

func (*Result) UnmarshalJSON

func (r *Result) UnmarshalJSON(raw []byte) error

UnmarshalJSON decodes Result and preserves the original object in RawJSON.

type ResultError

type ResultError struct {
	Category string `json:"category"`
	Message  string `json:"message"`
}

ResultError is the structured failure envelope nested inside Result.

type Surface

type Surface string

Surface identifies the runtime context in which the tool is operating.

const (
	// SurfaceCLI is for interactive terminal sessions where blocking on stdin
	// is safe.
	SurfaceCLI Surface = "cli"
	// SurfaceMCP is for MCP server contexts where blocking is fatal.
	SurfaceMCP Surface = "mcp"
)

type Tool

type Tool struct {
	// contains filtered or unexported fields
}

Tool asks the user a question and returns their answer.

func New

func New(surface Surface, opts ...Options) (*Tool, error)

New constructs a Tool for the given surface.

func (*Tool) Info

func (t *Tool) Info(_ context.Context) (*schema.ToolInfo, error)

Info returns the Eino ToolInfo for userinteract.

func (*Tool) InvokableRun

func (t *Tool) InvokableRun(ctx context.Context, argsJSON string, _ ...tool.Option) (string, error)

InvokableRun is the Eino tool entry point.

func (*Tool) Run

func (t *Tool) Run(_ context.Context, args Args) Result

Run executes the tool with parsed args.

Jump to

Keyboard shortcuts

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