Skip to main content

Next-turn Suggestion

After the agent finishes replying, the backend may predict what the user is likely to ask next and push it over as an asgard.prompt_suggestion event. The SDK surfaces it in the composer's placeholder; Tab adopts it.

With the built-in <Chatbot> there is nothing to wire.

When It Shows Up

The suggestion only takes the stage on an empty, usable textarea:

  • The user has already typed something → hidden. It must never paint over what they wrote.
  • Preview mode, or a pending tool-call consent (the textarea is disabled) → hidden. Offering a Tab shortcut into a field nobody can use is a dead end.
  • A live run is deliberately not excluded. The textarea still accepts typing while the answer streams, and lining up the next question then is exactly when the suggestion earns its keep.

Adopting and Clearing

Tab puts the suggestion into the textarea — it does not send. Focus stays put, whether it goes out is still the user's call, and the box resizes itself.

Tab is intercepted only when there genuinely is a suggestion to adopt. Everywhere else it keeps moving focus — that is a keyboard user's only way out of the textarea, so swallowing it unconditionally would trap them — and Shift+Tab is never intercepted.

The suggestion is cleared in three cases: the user adopted it (the text is in the textarea now, and re-offering it would duplicate it), a send went out, or a new run made it stale. Losing focus is deliberately not one of them.

Headless Access

If you are wiring a custom shell, the channel carries the store:

channel.promptSuggestion$; // Observable<string | null>
channel.getPromptSuggestion(); // snapshot, for framework-agnostic getSnapshot() bridging
channel.clearPromptSuggestion(); // call it yourself on adopt / send / expiry

On the React side useChannel() hands you promptSuggestion and clearPromptSuggestion directly.

Live-only — it does not come back after a rejoin

asgard.prompt_suggestion arrives at most once per run, after the reply and before the run's terminal event, and it is never persisted — a rejoin replay does not carry it, so staying null after a reload is the normal case, not a dropped frame. There is no metadata source to seed it from either.

suggestion is always a non-empty string (the backend drops empty predictions rather than emitting them) and is written in the conversation's language, so the frontend neither needs nor should translate it.

See Also