ThinkThen

Rust functions that answer questions about text

Call the engine directly. The compiler makes you handle not sure.

Install

Channel
cargo add thinkthen

Set THINKTHEN_API_KEY in the environment.

A first call

Cargo.toml, a project file beside the sample
[package]
name = "first-call"
edition = "2024"

[dependencies]
thinkthen = "0.0.1"
use thinkthen::{Description, Engine, Question};

thinkthen::choices! {
    enum Team {
        Billing => "billing",
        Shipping => "shipping",
        Account => "account",
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let tt = Engine::from_env()?;
    let question = "Which team owns this?";
    let billing =
        Description::text("Invoices, fees, and refunds.")?;
    let shipping =
        Description::text("Parcels and delivery.")?;
    let account =
        Description::text("Logins and passwords.")?;
    let owner = Question::choose::<Team>(question)?
        .option(Team::Billing, Some(billing))?
        .option(Team::Shipping, Some(shipping))?
        .option(Team::Account, Some(account))?
        .build()?;

    let texts = [
        "Please refund the extra fee on my invoice.",
        "My parcel went to the wrong address.",
        "I cannot reset my password.",
    ];
    let teams = texts
        .iter()
        .map(|text| {
            tt.choose(&owner, text)
                .map(|call| call.into_value())
        })
        .collect::<Result<Vec<_>, _>>()?;
    let expected = [
        Some(Team::Billing),
        Some(Team::Shipping),
        Some(Team::Account),
    ];
    assert_eq!(teams, expected);
    Ok(())
}
Build and run it beside Cargo.toml
mkdir -p src/bin
cp first-call.rs src/bin/
cargo run --quiet --bin first-call

Not sure comes back as Answer::Unsure from decide, and None from choose. Branch on it and send those cases to a person. Each function page shows its Rust call.

Run facts

Call::facts() counts this call.

Errors

Every call returns a Result. Its Error names one of six kinds. A started call that fails keeps its facts in Error::facts().

Settings and recording

EngineBuilder sets each setting. record writes a recording to a folder. replay answers from that recording and sends nothing, even on a miss. The Settings page lists every setting.

Jev, Liquid d1 and Ollama from Rust

EngineBuilder::backend names the backend in code, and it outranks the environment. The sample builds one engine for each backend and asks each the same question.

BackendNameKey variable
TypeSafe JevtypesafeTYPESAFE_API_KEY
Liquid d1liquidLIQUIDAI_API_KEY, then LIQUID_API_KEY
OllamaollamaOLLAMA_API_KEY. A local address needs no key.
The Ollama engine names the second port, 11535. On the default port, leave base_url out.
use thinkthen::{Answer, EngineBuilder, Question};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let typesafe = EngineBuilder::from_env()?
        .backend("typesafe")?
        .build()?;
    let liquid = EngineBuilder::from_env()?
        .backend("liquid")?
        .build()?;
    let ollama = EngineBuilder::from_env()?
        .backend("ollama")?
        .base_url("http://localhost:11535/v1")?
        .build()?;

    let question = "Does the customer ask for a refund?";
    let refund = Question::decide(question)?.cut();
    let broken =
        "Please refund my order. It arrived broken.";
    let thanks = "Thanks for the quick help yesterday!";
    for tt in [typesafe, liquid, ollama] {
        let yes = tt.decide(&refund, broken)?.into_value();
        let no = tt.decide(&refund, thanks)?.into_value();
        assert_eq!(yes, Answer::Yes);
        assert_eq!(no, Answer::No);
    }
    Ok(())
}
Build and run it beside Cargo.toml
mkdir -p src/bin
cp backends.rs src/bin/
cargo run --quiet --bin backends

EngineBuilder::from_env also reads THINKTHEN_BACKEND and THINKTHEN_BASE_URL, so the shell settings the other language pages show work here too.

The configuration file's backend names a default backend for every run. The Configuration page shows the file.

OpenAI Decisions API from Rust

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 Rust