Skip to main content
ask from tally-ai turns a question into a Tally query. The model answers in query text, the text is parsed against your schema, and only a query that parses is returned. The model never applies free text to a view. It works with any model the AI SDK can call: a provider package, a gateway model id or your own provider.

How it works

1

Prompt

describeSchema(schema, options) builds the system prompt: the query grammar, every visible column with its type, operators, enum values, aliases and limits, the examples you pass, and today’s date.
2

Answer

The model returns structured output with two fields: the query text and one short sentence explaining it.
3

Parse

The text is parsed with parseQuery against the schema. A query that parses is printed in its canonical form and returned.
4

Repair

Parse errors go back to the model with a request for a corrected query. After the last repair round, ask throws.

Usage

ask.ts
The result has three fields:

Options

Hidden columns are left out of the prompt. Columns with filterable, sortable or groupable set to false are described with those limits. A description on a column is passed to the model as is.

Errors

When no attempt parses, ask throws an AskError. Its message is the first parse error of the last attempt. question holds the question and attempts holds every answer with its parse errors.
errors.ts
Errors from the model call itself, such as a network failure or an abort, are not wrapped.

In the filter bar

createAskHandler returns the handler for the ai prop of <Tally>. It takes the same options without schema, which comes from the grid.
accounts.tsx
With a handler set, the placeholder of the filter bar changes to askPlaceholder. Text that does not parse as a query, or reads like a sentence, goes to the handler. The answer lands as filter chips. Rename the strings with the askPlaceholder and asking labels.

Keys in the browser

Model calls need an API key. Keep it on the server. Add a same-origin route that forwards model requests and adds the key, and point the provider’s base URL at it. ask, designColumn and withAiColumns then run in the browser. The playground does this in examples/playground/server, with a body size limit and a rate limit per client.

Your own agent loop

describeSchema(schema, { examples, context, now }) returns the same system prompt ask uses. Use it when you drive the model yourself, then validate the answer with parseQuery.