ThinkThen

C# functions that answer questions about text

An Engine over the C library, for .NET 8. Each call returns its answer and its run facts.

Install

ChannelNote
dotnet add package Botassembly.ThinkThenThe NuGet package.
thinkthen-csharp-VERSION-TARGET.tar.gzThe package file, from each release. Its folder serves as a local feed.
thinkthen-c-VERSION-TARGET.tar.gzThe C library it calls, from the same release.

Set THINKTHEN_API_KEY in the environment.

A first call

first-call.csproj, a project file beside the sample
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Botassembly.ThinkThen"
                      Version="*" />
  </ItemGroup>
</Project>
using System.Diagnostics;
using ThinkThen;

using var tt = Engine.Open();
const string question =
    "Does the customer ask for a refund?";
var isRefund = tt.Decide(
    question,
    "Please refund my order. It arrived broken.");
Trace.Assert(isRefund.Value.OutcomeKind == Outcome.Yes);

const string refund = """
    {"decide": "Does the customer ask for a refund?",
     "threshold": "0.2:0.8"}
    """;
isRefund = tt.Decide(refund, "I want to send this back.");
Trace.Assert(isRefund.Value.OutcomeKind == Outcome.NotSure);
Build and run it beside first-call.csproj and the unpacked archives, thinkthen-c/ and thinkthen-csharp/, in a folder with no other .cs file
dotnet build -o bin \
    --source "$PWD/thinkthen-csharp"
LD_LIBRARY_PATH="$PWD/thinkthen-c/lib" \
    dotnet bin/first-call.dll

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

Run facts

Decide returns a TypedResult. .Value holds the answer, and .Facts holds this call's run facts as a JsonElement.

Errors

A failed call throws a Failure. Its Kind names one of six FailureKind values, and Retryable says whether a retry may help.

Settings and recording

Engine.Open(settingsJson) takes the settings as JSON. "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 C#

C# 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.

BackendNameKey variable
TypeSafe JevtypesafeTYPESAFE_API_KEY
Liquid d1liquidLIQUIDAI_API_KEY, then LIQUID_API_KEY
OllamaollamaOLLAMA_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
using System.Diagnostics;
using ThinkThen;

using var tt = Engine.Open();
const string question =
    "Does the customer ask for a refund?";
var brokenIsRefund = tt.Decide(
    question,
    "Please refund my order. It arrived broken.");
var thanksIsRefund = tt.Decide(
    question,
    "Thanks for the quick help yesterday!");
var broken = brokenIsRefund.Value.OutcomeKind;
var thanks = thanksIsRefund.Value.OutcomeKind;
Trace.Assert(broken == Outcome.Yes);
Trace.Assert(thanks == Outcome.No);
Build and run it beside first-call.csproj and the unpacked archives, thinkthen-c/ and thinkthen-csharp/, in a folder with no other .cs file
dotnet build -o bin \
    --source "$PWD/thinkthen-csharp"
LD_LIBRARY_PATH="$PWD/thinkthen-c/lib" \
    dotnet bin/first-call.dll

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

OpenAI Decisions API from C#

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 C#