# 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

| Channel | Note |
| --- | --- |
| `dotnet add package Botassembly.ThinkThen` | The NuGet package. |
| `thinkthen-csharp-VERSION-TARGET.tar.gz` | The package file, from each release. Its folder serves as a local feed. |
| `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

*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](/install/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.

| 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
```

```
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](/install/configuration/#configuration-file) page shows the file.

### OpenAI Decisions API from C#

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

- The package finds the C library by name. `LD_LIBRARY_PATH` names its folder.
- `Trace.Assert` runs in a Release build. `Debug.Assert` does not.

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