Generation Generation — C++ examples backed by real provider calls. cpp examples examples/generation src/examples/cpp/generation example Generation

These C++ examples are real runnable files. Edit the source file first; this page is rebuilt from the checked-in example and its metadata header.

C++ Prompt-Cached Generation

Runs GPT-5.6 structured generation with stable OpenAI prompt-cache affinity.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.6-luna" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen program = axllm::ax("question:string -> answer:string");
  axllm::Value output = program.forward(
      client,
      axllm::object({{"question", "In one sentence, explain Ax as a language-agnostic LLM programming library."}}),
      axllm::object({{"promptCacheKey", "ax-openai-example"}, {"contextCache", axllm::object({})}}));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Model Catalog

Lists static models and named OpenAI-compatible profiles with portable thinking levels and service tiers.

C++
#include "axllm/axllm.hpp"
#include <iostream>
#include <stdexcept>
#include <string>

axllm::Value provider(const axllm::Value& catalog, const std::string& name) {
  for (const auto& entry : axllm::Core::iter(catalog)) {
    if (axllm::display(axllm::Core::get(entry, "name")) == name) return entry;
  }
  throw std::runtime_error("missing provider " + name);
}

int main() {
  const auto catalog = axllm::get_supported_ai_models();
  const auto azure = provider(catalog, "azure-openai");
  const auto openrouter = provider(catalog, "openrouter");
  const auto azure_capabilities = axllm::Core::get(azure, "capabilities");
  const auto openrouter_capabilities = axllm::Core::get(openrouter, "capabilities");

  if (!axllm::equal(axllm::Core::get(azure, "isDynamic"), true)) return 2;
  if (!axllm::Core::iter(axllm::Core::get(azure, "models")).empty()) return 3;
  if (axllm::Core::iter(axllm::Core::get(azure_capabilities, "thinkingLevels")).empty()) return 4;
  if (axllm::Core::iter(axllm::Core::get(openrouter_capabilities, "serviceTiers")).size() != 3) return 5;

  std::cout << axllm::Core::iter(catalog).size()
            << " providers; Azure and OpenRouter named profiles are available\n";
}

C++ Structured Extraction

Extracts structured fields and labels from support text with OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen program = axllm::ax("ticket:string -> priority:class \"high, normal, low\", summary:string, labels:string[]");
  axllm::Value output = program.forward(client, axllm::object({{"ticket", "Checkout has failed for enterprise customers since 09:00. Support wants a concise summary and tags."}}));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Vertex Gemini Routing

Calls Gemini through Vertex with project and multi-region routing.

  • Provider: google-gemini
  • Env: GOOGLE_VERTEX_ACCESS_TOKEN, GOOGLE_PROJECT_ID, GOOGLE_REGION
  • Level: intermediate
  • Run: npm run example -- cpp src/examples/cpp/generation/vertex_gemini.cpp
  • Source: src/examples/cpp/generation/vertex_gemini.cpp
C++
#include "axllm/axllm.hpp"

#include <cstdlib>
#include <iostream>
#include <string>

const char* required(const char* name) {
  const char* value = std::getenv(name);
  if (value == nullptr || std::string(value).empty()) {
    std::cerr << "Set " << name << " to run this example.\n";
    std::exit(2);
  }
  return value;
}

int main() {
  const char* model = std::getenv("AX_VERTEX_MODEL");
  axllm::GoogleGeminiClient client(axllm::object({
      {"api_key", required("GOOGLE_VERTEX_ACCESS_TOKEN")},
      {"project_id", required("GOOGLE_PROJECT_ID")},
      {"region", required("GOOGLE_REGION")},
      {"model", model == nullptr || std::string(model).empty() ? "gemini-3.5-flash" : model},
  }));
  auto out = client.chat(axllm::object({
      {"chat_prompt", axllm::array({axllm::object({{"role", "user"}, {"content", "Reply with the word ready."}})})},
  }));
  std::cout << axllm::stringify(out) << "\n";
}

C++ Signature Constraints

Builds native constrained fields and runs the signature with OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <iostream>

axllm::Value field(const char* name, const char* title, axllm::Value type) {
  return axllm::Core::record_new(
      "Field", axllm::object({{"name", name}, {"title", title}, {"type", type}}));
}

int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));

  axllm::Value signature = axllm::Core::record_new(
      "AxSignature",
      axllm::object({
          {"description", "Extract a constrained restaurant booking"},
          {"inputs",
           axllm::array({
               field("requestText", "Request Text",
                     axllm::Core::record_new(
                         "FieldType",
                         axllm::object({{"name", "string"}, {"minLength", 10}, {"maxLength", 500}}))),
               field("contactEmail", "Contact Email",
                     axllm::Core::record_new(
                         "FieldType", axllm::object({{"name", "string"}, {"format", "email"}}))),
           })},
          {"outputs",
           axllm::array({
               field("partySize", "Party Size",
                     axllm::Core::record_new(
                         "FieldType",
                         axllm::object({{"name", "number"}, {"minimum", 1}, {"maximum", 12}}))),
               field("bookingCode", "Booking Code",
                     axllm::Core::record_new(
                         "FieldType",
                         axllm::object({
                             {"name", "string"},
                             {"pattern", "^[A-Z]{3}-\\d{4}$"},
                             {"patternDescription", "Must look like ABC-1234"},
                         }))),
           })},
      }));
  axllm::Core::validate_signature(signature);
  axllm::AxGen program = axllm::ax(signature);
  axllm::Value output = program.forward(
      client,
      axllm::object({
          {"requestText", "Book dinner for four people under the name Ada Lovelace."},
          {"contactEmail", "ada@example.com"},
      }));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Incremental Provider Stream

Handles OpenAI SSE chunks incrementally and can cancel by returning false.

C++
#include "axllm/axllm.hpp"
#include <chrono>
#include <cstdlib>
#include <iostream>

int main() {
  const char* api_key = std::getenv("OPENAI_API_KEY");
  if (api_key == nullptr || std::string(api_key).empty()) api_key = std::getenv("OPENAI_APIKEY");
  if (api_key == nullptr || std::string(api_key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* selected = std::getenv("AX_OPENAI_MODEL");
  std::string model = selected == nullptr || std::string(selected).empty() ? "gpt-5.6-luna" : selected;
  auto client = axllm::ai("openai", axllm::object({{"api_key", api_key}, {"model", model}}));
  const auto started = std::chrono::steady_clock::now();
  client->stream_each(
      axllm::object({{"chat_prompt", axllm::array({axllm::object({
          {"role", "user"}, {"content", "Reply with exactly: streaming works"}})})},
          {"model_config", axllm::object({{"temperature", 1}})}}),
      [&](const axllm::Value& event) {
        std::string content = axllm::display(axllm::Core::get(
            axllm::Core::get(axllm::Core::get(event, "results"), 0), "content", ""));
        if (!content.empty()) {
          auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
              std::chrono::steady_clock::now() - started).count();
          std::cout << "[" << elapsed << " ms] " << content << std::flush;
        }
        return true;
      });
  std::cout << "\n";
}

Centralized Usage Observer

Attributes every completed model call to a tenant, user, and request from one global observer.

C++
#include "axllm/axllm.hpp"

#include <chrono>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

int main() {
  const char* api_key = std::getenv("OPENAI_API_KEY");
  if (api_key == nullptr || std::string(api_key).empty()) api_key = std::getenv("OPENAI_APIKEY");
  if (api_key == nullptr || std::string(api_key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* configured_model = std::getenv("AX_OPENAI_MODEL");
  std::string model =
      configured_model == nullptr || std::string(configured_model).empty()
          ? "gpt-5.4-mini"
          : configured_model;

  std::vector<axllm::AxUsageEvent> events;
  axllm::set_usage_observer(
      [&events](axllm::AxUsageEvent event) { events.push_back(std::move(event)); });
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", api_key},
      {"model", model},
      {"usageContext",
       axllm::object({
           {"tenantId", "tenant-42"},
           {"feature", "support-chat"},
           {"attributes", axllm::object({{"environment", "example"}})},
       })},
  }));
  client.chat(
      axllm::object({
          {"chat_prompt",
           axllm::array({
               axllm::object({{"role", "user"}, {"content", "Reply with one short greeting."}}),
           })},
      }),
      axllm::object({
          {"usageContext",
           axllm::object({
               {"userId", "user-7"},
               {"requestId",
                "request-" +
                    std::to_string(
                        std::chrono::steady_clock::now().time_since_epoch().count())},
           })},
      }));
  axllm::set_usage_observer({});
  std::cout << axllm::stringify(axllm::Value(axllm::Array(events.begin(), events.end())))
            << "\n";
}

C++ Gemini Flex Inference

Sends latency-tolerant work through Gemini Flex and reports the applied tier.

C++
#include "axllm/axllm.hpp"

#include <cstdlib>
#include <iostream>
#include <string>

int main() {
  const char* key = std::getenv("GOOGLE_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("GOOGLE_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set GOOGLE_API_KEY or GOOGLE_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_GEMINI_MODEL");
  axllm::GoogleGeminiClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gemini-3.7-flash" : model},
  }));
  axllm::Value out = client.chat(axllm::object({
      {"chat_prompt", axllm::array({axllm::object({
          {"role", "user"},
          {"content", "Explain in one sentence why batch evaluations save time."},
      })})},
  }), axllm::object({{"service_tier", "flex"}}));
  std::cout << axllm::stringify(out) << "\n";
}

C++ Contextual Generation

Answers from supplied context and returns compact citations with OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen program = axllm::ax("context:string, question:string -> answer:string, citations:string[]");
  axllm::Value output = program.forward(client, axllm::object({{"context", "Ax uses signatures, ai(), ax(), agent(), flow(), and optimize()."}, {"question", "How should a new developer think about Ax?"}}));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Adaptive Provider Balancing

Routes equivalent chat traffic using shared reliability, latency, and cost statistics.

C++
#include "axllm/axllm.hpp"

#include <cstdlib>
#include <iostream>
#include <memory>
#include <vector>

int main() {
  const char* raw_key = std::getenv("OPENAI_API_KEY");
  if (raw_key == nullptr || std::string(raw_key).empty()) raw_key = std::getenv("OPENAI_APIKEY");
  if (raw_key == nullptr || std::string(raw_key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const std::string model = std::getenv("AX_OPENAI_MODEL") == nullptr ? "gpt-5.4-mini" : std::getenv("AX_OPENAI_MODEL");
  auto primary = std::make_shared<axllm::OpenAICompatibleClient>(axllm::object({{"api_key", raw_key}, {"model", model}}));
  auto backup = std::make_shared<axllm::OpenAICompatibleClient>(axllm::object({{"api_key", raw_key}, {"model", model}}));

  auto store = std::make_shared<axllm::AxInMemoryBalancerStatsStore>();
  std::vector<std::string> route_keys{"openai-primary", "openai-backup"};
  std::vector<std::string> events;
  auto strategy = std::make_shared<axllm::AxBalancerAdaptiveStrategy>();
  strategy->deadline_ms = 6'000;
  strategy->bad_outcome_cost = 0.02;
  strategy->expected_tokens = axllm::object({{"promptTokens", 1'200}, {"completionTokens", 300}});
  strategy->name_space = "support-summary-v1";
  strategy->route_key = [route_keys](const std::shared_ptr<axllm::AxAIService>&, std::size_t index) { return route_keys.at(index); };
  strategy->slice = [](axllm::Value context) { return axllm::Core::truthy(axllm::Core::get(axllm::Core::get(context, "options"), "stream")) ? "streaming" : "interactive"; };
  strategy->stats_store = store;
  strategy->on_routing_event = [&events](axllm::Value event) { events.push_back(axllm::display(axllm::Core::get(event, "type"))); };

  axllm::AxBalancerOptions options;
  options.strategy = strategy;
  axllm::AxBalancer balancer({primary, backup}, options);
  auto response = balancer.chat(axllm::object({{"model", model}, {"chat_prompt", axllm::array({axllm::object({{"role", "user"}, {"content", "Summarize why shared routing state matters."}})})}}));
  std::cout << axllm::stringify(response) << "\n" << events.size() << " routing events\n";
}

Portable Runtime Hooks

Applies global and forward-scoped rate limiting, tracing, and metrics to AxGen, AxAgent, and AxFlow.

C++
#include "axllm/axllm.hpp"
#include "axllm/runtime/quickjs/quickjs_runtime.hpp"

#include <cstdlib>
#include <iostream>
#include <memory>

class LogSpan final : public axllm::AxSpan {
 public:
  explicit LogSpan(std::string name) : name_(std::move(name)) { std::cout << "[span:start] " << name_ << "\n"; }
  void set_attributes(axllm::Value) override {}
  void add_event(std::string event, axllm::Value) override { std::cout << "[span:event] " << name_ << " " << event << "\n"; }
  void record_exception(std::string error) override { std::cout << "[span:error] " << name_ << " " << error << "\n"; }
  void set_status(std::string, std::string) override {}
  void end() override { std::cout << "[span:end] " << name_ << "\n"; }
 private:
  std::string name_;
};

class LogTracer final : public axllm::AxTracer {
 public:
  std::shared_ptr<axllm::AxSpan> start_span(const axllm::AxSpanStart& start) override { return std::make_shared<LogSpan>(start.name); }
};

class LogInstrument final : public axllm::AxCounter, public axllm::AxHistogram, public axllm::AxGauge {
 public:
  explicit LogInstrument(std::string name) : name_(std::move(name)) {}
  void add(double value, axllm::Value) override { std::cout << "[metric] " << name_ << " += " << value << "\n"; }
  void record(double value, axllm::Value) override { std::cout << "[metric] " << name_ << " = " << value << "\n"; }
 private:
  std::string name_;
};

class LogMeter final : public axllm::AxMeter {
 public:
  std::shared_ptr<axllm::AxCounter> create_counter(std::string name, axllm::AxMetricInstrumentOptions) override { return std::make_shared<LogInstrument>(std::move(name)); }
  std::shared_ptr<axllm::AxHistogram> create_histogram(std::string name, axllm::AxMetricInstrumentOptions) override { return std::make_shared<LogInstrument>(std::move(name)); }
  std::shared_ptr<axllm::AxGauge> create_gauge(std::string name, axllm::AxMetricInstrumentOptions) override { return std::make_shared<LogInstrument>(std::move(name)); }
};

axllm::AxRateLimiter limiter(std::string label) {
  return [label = std::move(label)](axllm::AxRequestExecutor next, const axllm::AxRateLimitInfo& info) {
    std::cout << "[limit:" << label << "] " << info.operation << " " << info.provider << "/" << info.model << " stream=" << info.streaming << "\n";
    return next();
  };
}

int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) { std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n"; return 2; }
  const char* configured_model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", configured_model == nullptr || std::string(configured_model).empty() ? "gpt-5.4-mini" : configured_model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  auto tracer = std::make_shared<LogTracer>();
  auto meter = std::make_shared<LogMeter>();
  axllm::AxRuntimeHooks override_hooks{limiter("forward"), tracer, meter};

  axllm::set_rate_limiter(limiter("global"));
  axllm::set_tracer(tracer);
  axllm::set_meter(meter);
  try {
    auto direct = axllm::ax("topic:string -> summary:string");
    std::cout << axllm::stringify(direct.forward(client, axllm::object({{"topic", "portable Ax runtime hooks"}}))) << "\n";

    auto helper = axllm::agent("question:string -> answer:string");
    axllm::runtime::quickjs::QuickJsCodeRuntime runtime;
    std::cout << axllm::stringify(helper.forward(
        client,
        axllm::object({{"question", "What does a rate limiter wrap?"}}),
        axllm::object({{"runtime", axllm::Core::code_runtime_ref(runtime)}, {"max_actor_steps", 12}}),
        override_hooks)) << "\n";

    auto outline = axllm::ax("topic:string -> outline:string");
    auto polish = axllm::ax("outline:string -> answer:string");
    auto workflow = axllm::flow(axllm::object({{"id", "examples.runtimeHooks"}}))
        .execute("outline", outline)
        .execute("polish", polish)
        .returns(axllm::object({{"answer", "polish"}}));
    std::cout << axllm::stringify(workflow.forward(client, axllm::object({{"topic", "Ax runtime hooks"}}), axllm::Value::object(), override_hooks)) << "\n";
  } catch (...) {
    axllm::set_rate_limiter({}); axllm::set_tracer({}); axllm::set_meter({});
    throw;
  }
  axllm::set_rate_limiter({}); axllm::set_tracer({}); axllm::set_meter({});
}
Docs