# Dart functions that answer questions about text

One `Door` class over the C library, through Dart FFI. Each call returns its answer and its run facts.

## Install

| Channel | Note |
| --- | --- |
| `dart pub add thinkthen_dart` |  |
| `thinkthen-dart-VERSION-TARGET.tar.gz` | The package source, from each release. |
| `thinkthen-c-VERSION-TARGET.tar.gz` | The C library it calls, from the same release. |

Set `THINKTHEN_API_KEY` in the environment.

## A first call

*pubspec.yaml, a project file beside the sample*

```
name: first_call
environment:
  sdk: ^3.3.0
dependencies:
  thinkthen_dart:
    path: thinkthen-dart
```

```
import 'dart:io';

import 'package:thinkthen_dart/thinkthen_dart.dart';

void main() {
  final library = File('thinkthen-c/lib/libthinkthen.so');
  final tt = Door(library.absolute.path);
  final engine = tt.create();
  try {
    const question = 'Does the customer ask for a refund?';
    final isRefund = tt.decide(
      engine,
      question,
      'Please refund my order. It arrived broken.',
    );
    assert(isRefund.value.outcome == Outcome.yes);

    const refund = '{"decide": "$question", '
        '"threshold": "0.2:0.8"}';
    final backIsRefund = tt.decide(
      engine,
      refund,
      'I want to send this back.',
    );
    final outcome = backIsRefund.value.outcome;
    assert(outcome == Outcome.notSure);
  } finally {
    tt.engineFree(engine);
  }
}
```

*Build and run it beside the unpacked archives, thinkthen-c/ and thinkthen-dart/*

```
dart pub get
dart run --enable-asserts \
    first_call.dart
```

Not sure comes back as `Outcome.notSure`. Branch on it and send those cases to a person.

## Run facts

`decide` returns a record. `.value` holds the answer, and `.facts` holds this call's run facts as a `Map`.

## Errors

A failed call throws a `DoorFailure`. Its `kind` names one of six `ErrorKind` values. It also carries the message and `retryable`.

## Settings and recording

`create(settingsJson)` takes the settings as JSON. `"record"` writes a recording to a folder. `"replay"` answers from that recording with no connection. The [Settings](/install/settings/) page lists every setting.

## Jev, Liquid d1 and Ollama from Dart

Dart 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](/install/backends/typesafe/) | `typesafe` | `TYPESAFE_API_KEY` |
| [Liquid d1](/install/backends/liquid/) | `liquid` | `LIQUIDAI_API_KEY`, then `LIQUID_API_KEY` |
| [Ollama](/install/backends/ollama/) | `ollama` | `OLLAMA_API_KEY`. A local address needs no key. |

*Ask TypeSafe Jev.*

```
export THINKTHEN_BACKEND=typesafe
export TYPESAFE_API_KEY=...
```

*Ask Liquid d1.*

```
export THINKTHEN_BACKEND=liquid
export LIQUIDAI_API_KEY=...
```

*Ask Ollama. This block names a second port, 11535, as the site's runs do. On the default port, leave THINKTHEN_BASE_URL out.*

```
export THINKTHEN_BACKEND=ollama
export THINKTHEN_BASE_URL=http://localhost:11535/v1
```

```
import 'dart:io';

import 'package:thinkthen_dart/thinkthen_dart.dart';

void main() {
  final library = File('thinkthen-c/lib/libthinkthen.so');
  final tt = Door(library.absolute.path);
  final engine = tt.create();
  try {
    const question = 'Does the customer ask for a refund?';
    final brokenIsRefund = tt.decide(
      engine,
      question,
      'Please refund my order. It arrived broken.',
    );
    final thanksIsRefund = tt.decide(
      engine,
      question,
      'Thanks for the quick help yesterday!',
    );
    final broken = brokenIsRefund.value.outcome;
    final thanks = thanksIsRefund.value.outcome;
    assert(broken == Outcome.yes);
    assert(thanks == Outcome.no);
  } finally {
    tt.engineFree(engine);
  }
}
```

*Build and run it beside the unpacked archives, thinkthen-c/ and thinkthen-dart/*

```
dart pub get
dart run --enable-asserts \
    backends.dart
```

The configuration file's `backend` names a default backend for every run. The [Configuration](/install/configuration/#configuration-file) page shows the file.

### OpenAI Decisions API from Dart

OpenAI announced its Decisions API on 2026-09-29 in its [DevDay 2026 recap](https://openai.com/index/devday-2026-recap/). OpenAI has published no address, schema or price, so ThinkThen cannot call it. The [OpenAI Decisions API](/install/backends/openai/) page says what ThinkThen knows.

## What is different in Dart

- `Door` takes the C library's path. `create` makes an engine, and each call takes that engine first. `engineFree` closes it.
- `assert` runs only under `dart run --enable-asserts`.
- A Flutter app on Linux adds `thinkthen_dart` and passes the library path to `Door`.

On GitHub: [github.com/botassembly/thinkthen](https://github.com/botassembly/thinkthen)
