Skip to main content

Module 31: Elicitation

An agent asks the user for structured input in the middle of a prompt, or sends them to a URL for an out-of-band interaction such as signing in.

What You’ll Learn

  • Sending an elicitation request from an agent through context.client().createElicitation
  • Building a form schema: text, single-select, multi-select, boolean, and integer fields
  • Handling accept, decline, and cancel responses in the agent
  • URL mode: no schema, no content in the answer, and a separate elicitation/complete notification when the out-of-band interaction finishes
  • Advertising elicitation support (.elicitationForm()/.elicitationUrl()) and answering requests on the client

The Code

Agent: ask for a form mid-prompt

Elicitation is an agent-to-client request. As of 0.80.0 the prompt handler reaches it through context.client(), the raw ACP requests of the prompt’s own session, so the agent needs no reference to itself. The async API makes the request-then-continue flow a flatMap:

URL mode: sign-in pages and other out-of-band flows

A form isn’t the only kind of elicitation. In URL mode, the agent sends a link (a sign-in page, a payment page) that the client opens out of band with the user’s consent: no schema, and the accept answer carries no content. When the external interaction finishes (an OAuth callback, for example), the agent tells the client with a separate elicitation/complete notification carrying the same elicitation id:

Client: advertise support and answer

The client declares elicitation support in its capabilities and registers a handler. A real client shows the form to the user; the demo fills it in automatically:
As of 0.80.0, initialize(InitializeRequest) is removed: capabilities are set only on the client builder, and initialize() sends them. See the 0.80.0 migration guide.

Form Field Types

Responses

The agent must handle all three. A prompt that depends on the form still has to end its turn when the user declines or cancels.
Elicitation was added in SDK 0.12.0 as an unstable protocol element, marked @UnstableAcpApi. It is stable as of 0.80.0 (promoted in protocol v1.7.0), and its API is no longer @UnstableAcpApi. The elicitation capability’s modes are now typed (ElicitationFormCapabilities, ElicitationUrlCapabilities), the no-argument ElicitationCapabilities() constructor is removed in favor of formOnly()/urlOnly()/formAndUrl(), and ElicitationAction is an open value type, not an enum: compare with equals, not ==. The agent may only request a mode the client advertised.

Source Code

View on GitHub

Running the Example

The demo runs five exchanges against the agent: a simple single-select that the user accepts, the full project form accepted with every field type, a form the user declines, one the user cancels, and a URL-mode sign-in the user agrees to open, followed by the agent’s elicitation/complete. No API key required.

Next Module

Module 32: Agent-Client Agent — from chatbot to agent: an ACP agent whose prompt handler runs a tool-using agent loop.