R functions that answer questions about text
The ten functions work inside dplyr pipelines. Read the answer from $value.
Install
| Channel |
|---|
install.packages("thinkthen") |
Set THINKTHEN_API_KEY in the environment.
A first call
library(thinkthen)
question <- "Does the customer ask for a refund?"
broken <- "Please refund my order. It arrived broken."
is_refund <- tt_decide(question, broken)$value
stopifnot(identical(is_refund, TRUE))
send_back <- "I want to send this back."
is_refund <- tt_decide(
question,
send_back,
threshold = "0.2:0.8"
)$value
stopifnot(identical(is_refund, NA))Not sure comes back as NA. Branch on it and send those cases to a person. Each function page shows its R call.
To apply one question to a list or a stream, read Functional patterns.
Data frames
A verb inside mutate() answers a whole column in one call. dplyr's filter() drops NA rows, so a not-sure answer leaves the pipeline on its own.
library(dplyr)
library(thinkthen)
question <- "Does the customer ask for a refund?"
messages <- tibble(
body = c(
"Please refund my order. It arrived broken.",
"I want to send this back."
)
)
answered <- messages |>
mutate(
is_refund = tt_decide(
question,
body,
threshold = "0.2:0.8"
)$value
)
stopifnot(identical(answered$is_refund, c(TRUE, NA)))
refunds <- answered |> filter(is_refund)
stopifnot(identical(refunds$body, messages$body[1]))Run facts
$facts counts this call.
Errors
Each failure arrives as an R condition named for its kind, such as thinkthen_usage. Each condition carries retryable.
Settings and recording
tt_engine() takes each setting as an argument and reads the environment for the rest. record = writes a recording to a folder. replay = answers from that recording with no connection. The Settings page lists every setting.
Jev, Liquid d1 and Ollama from R
R reads its backend from the environment. Set THINKTHEN_BACKEND to the name below. Set the backend's key variable in the shell, and the same sample asks that backend.
| Backend | Name | Key variable |
|---|---|---|
| TypeSafe Jev | typesafe | TYPESAFE_API_KEY |
| Liquid d1 | liquid | LIQUIDAI_API_KEY, then LIQUID_API_KEY |
| Ollama | ollama | OLLAMA_API_KEY. A local address needs no key. |
export THINKTHEN_BACKEND=typesafe
export TYPESAFE_API_KEY=...export THINKTHEN_BACKEND=liquid
export LIQUIDAI_API_KEY=...export THINKTHEN_BACKEND=ollama
export THINKTHEN_BASE_URL=http://localhost:11535/v1library(thinkthen)
question <- "Does the customer ask for a refund?"
texts <- c(
"Please refund my order. It arrived broken.",
"Thanks for the quick help yesterday!"
)
is_refund <- tt_decide(question, texts)$value
stopifnot(identical(is_refund, c(TRUE, FALSE)))The configuration file's backend names a default backend for every run. The Configuration page shows the file.
OpenAI Decisions API from R
OpenAI announced its Decisions API on 2026-09-29 in its DevDay 2026 recap. OpenAI has published no address, schema or price, so ThinkThen cannot call it. The OpenAI Decisions API page says what ThinkThen knows.
What is different in R
- A column goes in and the answered column is in
$value.
On GitHub: github.com/botassembly/thinkthen