ThinkThen

Objective-C functions that answer questions about text

A TTClient over the C library, for GNU Objective-C with no Foundation.

Install

ChannelNote
thinkthen-objective-c-VERSION-TARGET.tar.gzThe binding's source, from each release.
thinkthen-c-VERSION-TARGET.tar.gzThe C library it calls, from the same release.

Set THINKTHEN_API_KEY in the environment.

A first call

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "ThinkThen.h"

int main(void) {
    TTClient *client = [TTClient create];
    TTFailure failure = {0};
    TTDecision is_refund = {0};
    char *facts = NULL;

    const char *question =
        "Does the customer ask for a refund?";
    const char *broken =
        "Please refund my order. It arrived broken.";
    [client decide:question
              text:broken
            length:strlen(broken)
          deadline:-1
             token:nil
            answer:&is_refund
             facts:&facts
           failure:&failure];
    assert(is_refund.outcome == TTOutcomeYes);
    free(facts);

    const char *refund =
        "{\"decide\": \"Does the customer ask"
        " for a refund?\", \"threshold\": \"0.2:0.8\"}";
    const char *send_back = "I want to send this back.";
    [client decide:refund
              text:send_back
            length:strlen(send_back)
          deadline:-1
             token:nil
            answer:&is_refund
             facts:&facts
           failure:&failure];
    assert(is_refund.outcome == TTOutcomeNotSure);
    free(facts);

    [client dealloc];
    return 0;
}
Build and run it beside the unpacked archives, thinkthen-c/ and thinkthen-objective-c/
gcc -std=gnu11 -x objective-c \
    -I thinkthen-c/include \
    -I thinkthen-objective-c/Sources \
    thinkthen-objective-c/Sources/ThinkThen.m \
    thinkthen-objective-c/Sources/TTJSON.c \
    first-call.m -o first-call \
    -L thinkthen-c/lib -lthinkthen \
    -Wl,-rpath,"$PWD/thinkthen-c/lib" \
    -lobjc -pthread -lm
./first-call

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

Run facts

Each typed call sets facts: to this call's run facts as JSON text. Free it with free.

Errors

A failed call returns a TTErrorKind and fills the TTFailure. A failed call leaves the answer untouched.

Settings and recording

createWithSettings:length:failure: 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 Objective-C

Objective-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
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "ThinkThen.h"

int main(void) {
    TTClient *client = [TTClient create];
    TTFailure failure = {0};
    TTDecision broken_is_refund = {0};
    TTDecision thanks_is_refund = {0};
    char *facts = NULL;

    const char *question =
        "Does the customer ask for a refund?";
    const char *broken =
        "Please refund my order. It arrived broken.";
    TTErrorKind broken_error =
        [client decide:question
                  text:broken
                length:strlen(broken)
              deadline:-1
                 token:nil
                answer:&broken_is_refund
                 facts:&facts
               failure:&failure];
    assert(broken_error == TTErrorNone);
    assert(broken_is_refund.outcome == TTOutcomeYes);
    free(facts);
    facts = NULL;

    const char *thanks =
        "Thanks for the quick help yesterday!";
    TTErrorKind thanks_error =
        [client decide:question
                  text:thanks
                length:strlen(thanks)
              deadline:-1
                 token:nil
                answer:&thanks_is_refund
                 facts:&facts
               failure:&failure];
    assert(thanks_error == TTErrorNone);
    assert(thanks_is_refund.outcome == TTOutcomeNo);
    free(facts);

    tt_failure_clear(&failure);
    [client dealloc];
    return 0;
}
Build and run it beside the unpacked archives, thinkthen-c/ and thinkthen-objective-c/
gcc -std=gnu11 -x objective-c \
    -I thinkthen-c/include \
    -I thinkthen-objective-c/Sources \
    thinkthen-objective-c/Sources/ThinkThen.m \
    thinkthen-objective-c/Sources/TTJSON.c \
    backends.m -o backends \
    -L thinkthen-c/lib -lthinkthen \
    -Wl,-rpath,"$PWD/thinkthen-c/lib" \
    -lobjc -pthread -lm
./backends

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

OpenAI Decisions API from Objective-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 Objective-C