Skip to content

Model Picker — C source

Filter every major model by context window, price, modality, and tier — sort by cost, context, or tokens-per-dollar to find the right model for the task.

This is the C implementation — the same logic the interactive tool runs, in a shareable, citable form.

/* model-picker — C port: filter + rank the AI model catalog. */
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

/* Pricing projection of the TS AiModel record; priced == false means the TS
 * null rates. Filter sentinels: NULL tier / 0 min_context / negative
 * max_input_per_m mean "do not apply this constraint". */
typedef struct {
    const char *id, *tier;
    long long context_window;
    bool priced;
    double input_per_m, output_per_m; /* USD per 1M in/out tokens. */
} Model;

typedef struct { const char *tier; long long min_context; double max_input_per_m; } ModelFilter;

/* Sort keys: the TS SortKey union. tokensPerDollar and released follow the
 * same pattern (rank 1e6 / output_per_m, or the date, descending). */
typedef enum { PRICE, CONTEXT } SortKey;

/* Rank core: value order (desc when asked), missing values last. */
static int cmp_opt(bool ha, double va, bool hb, double vb, int desc)
{
    if (!ha || !hb) return hb - ha;
    return va == vb ? 0 : (va < vb ? -1 : 1) * (desc ? -1 : 1);
}

/* Strict "a before b" per key: value order first, missing last, id ascending
 * on ties — the TS COMPARATORS contract. */
static bool less(SortKey key, const Model *a, const Model *b)
{
    int c = key == PRICE
        ? cmp_opt(a->priced, a->input_per_m, b->priced, b->input_per_m, 0)
        : cmp_opt(true, (double)a->context_window, true, (double)b->context_window, 1);
    return c != 0 ? c < 0 : strcmp(a->id, b->id) < 0;
}

/* listModels (src/lib/ai/models.ts, inlined: unpriced rows never satisfy
 * max_input_per_m) followed by the sort — the TS pickModels pipeline. */
static size_t pick_models(const Model *models, size_t n, ModelFilter f, SortKey key, const Model **out)
{
    size_t k = 0;
    for (size_t i = 0; i < n; i++) {
        const Model *m = &models[i];
        if ((f.tier && strcmp(m->tier, f.tier)) ||
            (f.min_context > 0 && m->context_window < f.min_context) ||
            (f.max_input_per_m >= 0 && (!m->priced || m->input_per_m > f.max_input_per_m)))
            continue;
        out[k++] = m;
    }
    for (size_t i = 1; i < k; i++) /* insertion sort; full order via id ties */
        for (size_t j = i; j > 0 && less(key, out[j], out[j - 1]); j--) {
            const Model *t = out[j];
            out[j] = out[j - 1];
            out[j - 1] = t;
        }
    return k;
}

int main(void)
{
    const Model models[] = { /* snapshot rows in the TS lib; one unpriced */
        { "atlas-flagship", "flagship", 1000000, true, 3.0, 15.0 },
        { "atlas-mini", "fast", 200000, true, 0.5, 2.0 },
        { "nova-open", "balanced", 1000000, false, 0.0, 0.0 },
        { "zeta-budget", "budget", 128000, true, 0.5, 1.0 },
    };
    enum { N = sizeof models / sizeof models[0] };
    const Model *rows[N];
    puts("long-context (minContext >= 500000, sort context):");
    size_t k = pick_models(models, N, (ModelFilter){ NULL, 500000, -1.0 }, CONTEXT, rows);
    for (size_t i = 0; i < k; i++)
        printf("  %-14s ctx %lld\n", rows[i]->id, rows[i]->context_window);
    puts("price sort (all models, unpriced last, ties by id):");
    k = pick_models(models, N, (ModelFilter){ NULL, 0, -1.0 }, PRICE, rows);
    for (size_t i = 0; i < k; i++)
        printf(rows[i]->priced ? "  %-14s $%.2f/M in\n" : "  %-14s unpriced\n", rows[i]->id, rows[i]->input_per_m);
    return 0;
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →