Skip to content

Mock LLM Responder — C++ source

Generate deterministic mock LLM API responses - chat completion JSON, SSE event streams with chunk timing, and a replay curl - for testing clients without an API key.

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

// mock-llm-responder — C++ port: deterministic mock LLM responses (seeded PRNG + SSE chunks).
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>
static const std::vector<std::string> POEM_WORDS = {
    "cosmos", "nebula", "quantum", "signal", "photon", "drift", "orbit", "vector",
    "cipher", "lumen", "aurora", "echo", "helix", "nova", "pulse", "tide",
    "vertex", "zenith", "quasar", "ion", "halo", "flux", "prism", "comet",
};
// FNV-1a 32-bit hash — turns the spec into a deterministic seed / id.
static uint32_t hashString(const std::string &s) {
    uint32_t h = 0x811c9dc5u;
    for (char c : s) { h ^= static_cast<uint8_t>(c); h *= 0x01000193u; }
    return h;
}
// mulberry32 — tiny seeded PRNG; same seed, same sequence, forever.
struct Rng {
    uint32_t a = 0;
    double next() {
        a += 0x6d2b79f5u; // uint32 math wraps, mirroring Math.imul + >>> 0
        uint32_t t = (a ^ (a >> 15)) * (a | 1u);
        t = (t + ((t ^ (t >> 7)) * (t | 61u))) ^ t;
        return static_cast<double>(t ^ (t >> 14)) / 4294967296.0;
    }
};
// ~4 chars per token, floor of 1 — deterministic, no tokenizer needed.
static int tokenCount(const std::string &text) {
    return text.empty() ? 0 : static_cast<int>(std::max<size_t>(1, (text.size() + 3) / 4));
}
// Cut text so it fits in maxTokens tokens (4 chars each).
static std::string truncateToTokens(const std::string &text, int maxTokens) {
    if (tokenCount(text) <= maxTokens) return text;
    std::string cut{text.substr(0, static_cast<size_t>(maxTokens) * 4)};
    while (!cut.empty() && std::isspace(static_cast<unsigned char>(cut.back()))) cut.pop_back();
    return cut;
}
// One poem line of 5-7 vocabulary words.
static std::string makeLine(Rng &rng) {
    int n = 5 + static_cast<int>(rng.next() * 3);
    std::string line; // words joined below; (i ? " " : "") keeps separators exact
    for (int i = 0; i < n; i++)
        line += (i ? " " : "") + POEM_WORDS[static_cast<size_t>(rng.next() * POEM_WORDS.size())];
    return line;
}
// Poem-ish lorem, grown line by line until the token budget is full.
static std::string buildPoem(uint32_t seed, int maxTokens) {
    Rng rng{seed};
    std::string text;
    for (;;) {
        std::string candidate = text.empty() ? makeLine(rng) : text + '\n' + makeLine(rng);
        if (!text.empty() && tokenCount(candidate) > maxTokens) break;
        text = std::move(candidate);
    }
    return truncateToTokens(text, maxTokens);
}
// Split content into stream chunks (word tokens keep trailing whitespace).
static std::vector<std::string> chunkContent(const std::string &content, size_t perChunk) {
    std::vector<std::string> words, chunks;
    for (size_t i = 0; i < content.size();) {
        size_t j = i; while (j < content.size() && !std::isspace(static_cast<unsigned char>(content[j]))) j++;
        while (j < content.size() && std::isspace(static_cast<unsigned char>(content[j]))) j++;
        words.push_back(content.substr(i, j - i));
        i = j;
    }
    for (size_t k = 0; k < words.size(); k += perChunk) {
        std::string chunk;
        for (size_t m = k; m < std::min(k + perChunk, words.size()); m++) chunk += words[m];
        chunks.push_back(std::move(chunk));
    }
    return chunks;
}
int main() {
    const std::string spec = "streamed-lorem|mock-gpt-4o-mini|24"; // salted seeds: |id, |poem
    std::string poem = buildPoem(hashString(spec + "|poem"), 24);
    std::printf("id=chatcmpl-mock-%08x\n%s\n", hashString(spec + "|id"), poem.c_str());
    std::printf("tokens=%d chunks=%zu\n", tokenCount(poem), chunkContent(poem, 4).size());
}

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 →