# Swift functions that answer questions about text

A SwiftPM package over the C library, for Swift 6. Each call returns its answer and its run facts.

## Install

| Channel | Note |
| --- | --- |
| `thinkthen-swift-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

*Package.swift, a project file beside the sample*

```
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "FirstCall",
    dependencies: [.package(path: "thinkthen-swift")],
    targets: [
        .executableTarget(
            name: "FirstCall",
            dependencies: [
                .product(
                    name: "ThinkThen",
                    package: "thinkthen-swift"
                ),
            ],
            path: ".",
            sources: ["main.swift"]
        ),
    ]
)
```

```
import ThinkThen

let tt = try Engine()
let question = "Does the customer ask for a refund?"
var isRefund = try tt.decide(
    question,
    "Please refund my order. It arrived broken."
)
precondition(isRefund.value.outcome == .yes)

let refund = """
    {"decide": "\(question)", "threshold": "0.2:0.8"}
    """
isRefund = try tt.decide(
    refund,
    "I want to send this back."
)
precondition(isRefund.value.outcome == .unsure)
tt.close()
```

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

```
swift build \
    -Xlinker -L -Xlinker "$PWD/thinkthen-c/lib" \
    -Xlinker -rpath -Xlinker "$PWD/thinkthen-c/lib"
.build/debug/FirstCall
```

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

## Run facts

`decide` returns a `CallResult`. `.value` holds the answer, and `.facts` holds this call's run facts as JSON text.

## Errors

A failed call throws a `DoorFailure`. Its `kind` names usage, backend, deadline, local, cancelled or defect.

## Settings and recording

`Engine(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 Swift

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

The Swift project file names its sample, so this sample has its own.

*Package.swift, a project file beside the sample*

```
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "Backends",
    dependencies: [.package(path: "thinkthen-swift")],
    targets: [
        .executableTarget(
            name: "Backends",
            dependencies: [
                .product(
                    name: "ThinkThen",
                    package: "thinkthen-swift"
                ),
            ],
            path: ".",
            sources: ["backends.swift"]
        ),
    ]
)
```

```
import ThinkThen

@main
struct Backends {
    static func main() throws {
        let tt = try Engine()
        let question = "Does the customer ask for a refund?"
        let brokenIsRefund = try tt.decide(
            question,
            "Please refund my order. It arrived broken."
        )
        let thanksIsRefund = try tt.decide(
            question,
            "Thanks for the quick help yesterday!"
        )
        precondition(brokenIsRefund.value.outcome == .yes)
        precondition(thanksIsRefund.value.outcome == .no)
        tt.close()
    }
}
```

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

```
swift build \
    -Xlinker -L -Xlinker "$PWD/thinkthen-c/lib" \
    -Xlinker -rpath -Xlinker "$PWD/thinkthen-c/lib"
.build/debug/Backends
```

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 Swift

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 Swift

- Add the package with `.package(path:)`. Its product is `ThinkThen`.
- The linker needs the C library's folder, through `-Xlinker -L` and `-Xlinker -rpath`.
- Call `close()` once, after every call on the engine ends.

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