Assumptions

What an answer is based on (assumptions, unknowns and limits), with a way for the user to correct them so the agent can redo the work.

Pattern

≈ 1,282 tokens per use (tool 698 · guidance 293 · typical payload 291)How token costs are estimated

Example: Assumptions

How much will a week in Lisbon cost us?

What this is based on

For: Budget for a week in Lisbon

Assumed

  • Assumption: Two adults are travelling. Based on: You said “us” and didn't mention kids. Medium confidence · High impact.

  • Assumption: A mid-range hotel at about €140 a night. Based on: Typical 3-star rate in the centre for October. Medium confidence · High impact.

  • Assumption: You eat out twice a day. Based on: Common for a city break. Low confidence · Medium impact.

Not known

  • Not known: Where you're flying from. Based on: Flights aren't in the estimate yet. High impact.

Limits

  • Data limit: Prices are as of today and may change. Low impact.

When to use

  • The answer rests on guesses the user could easily correct: party size, budget, dates, rates, jurisdiction.
  • Something the agent needed was missing or cut off, and the user should know before relying on the answer.
  • A wrong assumption would change the answer a lot, such as an estimate, a forecast or a recommendation.

When not to use

  • Nothing was assumed. Don't invent assumptions to look careful.
  • The agent needs an answer before it can start at all. Ask the question instead.
  • The point is where the answer came from or what the agent did. Use Citations for sources and the Activity Trail for steps.

How the agent should use it

  • Show it right after the answer it explains, once per answer.
  • One plain sentence per item. Put the reason in basis: "From your message on Monday", "Industry average". It's shown while the user corrects that item and read to screen readers, not on every row.
  • Set impact honestly. High-impact items are listed first in their group and flagged "High impact", so reserve high for things that change the answer materially. Low-confidence items are flagged "Low confidence"; other ratings are read to screen readers only.
  • Add a correction whenever the user could give the real value, and set its value to what was assumed. Without one, the item can only be acknowledged.
  • On redo, redo the work with the corrected values and show a new set of assumptions. On confirm-all, keep the answer.
  • Lifecycle: when the agent redoes the work, mark this call superseded by the new one (supersededBy). It doesn't need expiresAt; if the data has a cutoff, say so in a data-limit item rather than relying on fetchedAt.

How the user corrects it

Items are grouped into Assumed, Not known and Limits (constraints and data limits). The appliesTo line is read to screen readers; the answer above already names it. Within a group, items are sorted by impact (high first), then by confidence (least certain first).

ControlShown forEffect
CorrectItems with a correctionOpens the typed input inline (text, number with unit, select, or yes/no) with Save and Cancel. The item then shows the new value under the struck-through statement
I can tell youUnknowns with a correctionSame as Correct
Looks rightAssumptionsMarks the item confirmed. Unknowns say "Fine without it" and limits say "Understood"

Saving the value that was already assumed counts as a confirmation, not a correction. Redo with corrections is enabled once there's at least one correction; Everything looks right is enabled while there are none.

Installation

npx shadcn@latest add https://your-site.com/r/assumptions.json

Usage

app/api/chat/route.ts
import { tool } from "ai"
import { assumptionsTool } from "@/components/genui/assumptions.schema"

const tools = {
  // No execute(): the call is completed by the user's corrections in the UI.
  [assumptionsTool.name]: tool({
    description: assumptionsTool.description,
    inputSchema: assumptionsTool.inputSchema,
  }),
}

The agent receives one of:

{ action: "redo", corrections: [{ id: "travellers", value: 3 }], confirmed: ["meals"] }
{ action: "confirm-all" }

Correction values are typed: a number for number, one of the options for select, true/false for boolean, and trimmed text for text.

With LangGraph

Push it from a graph node with ui.push({ name: "show_assumptions", props: { toolCallId, ...args } }, { message }), and render the thread's UI messages with the Renderer.

Restoring from history

Pass the stored result back as result. The component shows the read-only record (corrected values, confirmations and "Sent 2 corrections") and never calls onResult again.

<Assumptions
  {...part.input}
  result={part.state === "output-available" ? part.output : undefined}
/>

Schema

PropTypeNotes
titlestring?Default "What this is based on"
appliesTostring?The answer these sit behind, e.g. "Budget for a week in Lisbon". Screen readers only
itemsAssumptionItem[]1–12

AssumptionItem

FieldTypeNotes
idstringReturned in the result
kindassumption | unknown | constraint | data-limitSets the group
statementstringOne plain sentence
basisstring?Why it was assumed
confidencelow | medium | highHow sure the agent is
impactlow | medium | highHow much the answer changes if it's wrong
correction{ type, options?, unit?, value? }type is text, number, select or boolean. options is required for select. A unit starting with a currency symbol goes before the number ("€/night" → "€140/night")
sourceUrlstring?Data-bound. http(s) link to where the basis came from

Host props: status (streaming, ready, corrected, confirmed), onResult, result and className.

Source

On this page