Questions
Learn how to implement questions in a BDK Book.
Overview
In your Book, you may need to ask the user for information. For example, if the Book needs to know when a project should begin, it can ask the user, “What is the project start date?” Or if it needs a username, it can prompt the user with, “What is the username?”
When this happens, Kognitos surfaces a question to pause the automation and ask the user for information. A question is an exception that signals that the automation cannot move forward without user input. The BDK provides an easy way to add and handle questions in your Book using the ask()
method.
How It Works
The ask()
function in the BDK is used to ask a question. Here’s how it works:
Kognitos Checks for an Answer
Each time ask()
is called, Kognitos checks internally whether it has already stored an answer for that specific question before.
If the answer to the question exists,
ask()
returns the answer value itself.If the answer to the question does not exist,
ask()
returns aQuestion
.
Question is Surfaced (if the answer is not present)
When a Question
object is returned from a procedure, Kognitos will:
Forward the question to the user
Pause the automation and wait for a response
Store the answer internally
Restart the procedure from the beginning automatically
The second time the procedure runs,
ask()
will be able to return the answer instead of a Question.
Usage
ask(concept_name: NounPhrasesStringLiteral, concept_type: Type[T], text: Optional[str] = None, choices: Optional[List[T]] = None) -> Union[T, Question[NounPhrasesStringLiteral, T]]
concept_name
Yes
The unique name of the concept being asked for.
concept_type
Yes
The return type of the answer.
text
No
(Optional) A message to show the user when the question is prompted in Kognitos.
choices
No
(Optional) A list of predefined options the user can choose from.
To use ask()
in your Book, follow these steps:
Call ask()
Call the ask()
function inside a method decorated with @procedure
.
Provide the concept_name
(the unique name of the concept being asked for) and the concept_type
(the return type of the answer).
result = ask("project start date", str)
(Optional) Specifying the Question Text
You can specify a text
to present to the user when the question is prompted in Kognitos. If the text is not specified, questions are presented as Please provide the <concept_name>
by default. For example:
result = ask("project start date", str, text="What is the start date of the project?")
(Optional) Specifying Choices
You can also guide users to select an answer from a predefined list by passing a choices
argument. When choices are set, Kognitos displays the question with a dropdown menu for the user to select from. For example:
result = ask("project start date", str, choices=["2025-07-22", "2025-07-25", "2025-07-28"])
Handle the Result of ask()
The ask()
function can return either the answer or a Question
object. To handle both cases, explicitly check the return type:
If
ask()
returns a value, that means the answer already exists internally.If
ask()
returns aQuestion
, that means the answer does not exist internally. What you do with theQuestion
is up to you — the Book can return it, hold onto it for later, or ignore it entirely. If you want Kognitos to surface the question to the user, return theQuestion
object from the procedure. For example:
if isinstance(result := ask("project start date", str), Question)
return result
Use the Answer
Once the ask()
function returns a value (and not a Question
), you can use the answer just like any other variable in Python — in calculations, conditions, etc. For example:
if isinstance(start_date := ask("project start date", str), Question):
return start_date
# Use the answer as a datetime object
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
project_due_date = date_obj + timedelta(days=30)
Declare Return Types
Always include return types in your procedure definitions. If your procedure may trigger a Question
, the return type must reflect that so the system understands which concept(s) you may be asking for. Make sure to include both the concept name (as a string Literal
in nounphrase form) and the concept type in the type hint. For example:
@procedure("to get a project due (date)")
def get_due_date(self) -> str | Question[Literal["project start date"], str]:
Examples
1. Asking a Question with Different Return Types
This example shows how to use ask()
with a set of mixed-type choices: a string, a datetime, and a float. The return type allows for any of those types, and also accounts for the case where a Question
is returned.
@procedure("to get a (value)")
def get_value(self) -> str | datetime | float | Question[Literal["value"], str | datetime | float]:
choices = ["Hello!", datetime(2023, 1, 1, tzinfo=timezone.utc), 123.456]
if isinstance(answer := ask("value", Union[str, datetime, float], choices=choices), Question):
return answer
return answer
2. Asking Multiple Questions
Sometimes your Book may need to collect more than one piece of information. You can call ask()
multiple times in the same procedure. Here’s an example:
from typing import Literal
from kognitos import procedure
from kognitos.bdk.api.questions import ask, Question
@procedure("to get a (text)")
def get_text(self) -> str | Question[Literal["color"], str] | Question[Literal["elephant's name"], str]:
"""
Get a text
"""
# First: Ask the user to pick a color
if isinstance(answer := ask("color", str, text="Pick a color", choices=["red", "blue", "green"]), Question):
return answer
color = answer
# Second: Ask for the elephant's name
if isinstance(answer := ask("elephant's name", str, text="What is the elephant's name?"), Question):
return answer
name = answer
# You can now use both answers
return f"The elephant named {name} is painted {color}."
How This Works
The first call to
ask()
checks whether the answer for color is present.If not, it returns a Question.
If answered, it stores the value and restarts the procedure.
Now that the answer for color is present, the procedure checks for the elephant’s name.
If not, it returns a Question.
If answered, it stores the value and restarts the procedure.
Once both values are available, the final result is returned.
Last updated
Was this helpful?