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++ Sequential Flow
Runs a two-step Ax flow against OpenAI.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/flows/sequential_flow.cpp - Source: src/examples/cpp/flows/sequential_flow.cpp
#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 step = axllm::ax("documentText:string -> summaryText:string");
axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.sequentialFlow"}}))
.execute("step", step)
.map("note", [](axllm::Value) { return axllm::object({{"note", "Mapped flow state after the provider-backed step."}}); })
.returns(axllm::object({{"step", "step"}, {"note", "note"}}));
axllm::Value output = program.forward(client, axllm::object({{"documentText", "Ax gives developers signatures, provider clients, agents, flows, tracing, and optimization."}}));
std::cout << axllm::stringify(output) << "\n";
}C++ Branching Flow
Routes a classification through follow-up flow logic backed by OpenAI.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
intermediate - Run:
npm run example -- cpp src/examples/cpp/flows/branch_flow.cpp - Source: src/examples/cpp/flows/branch_flow.cpp
#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 classifier =
axllm::ax("request:string -> route:class \"support, sales, engineering\"");
axllm::AxGen responder = axllm::ax("request:string, route:string -> response:string");
axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.branchFlow"}}))
.execute("classifier", classifier,
axllm::object({{"reads", axllm::array({"request"})},
{"writes", axllm::array({"classifierResult", "route"})}}))
.execute("responder", responder,
axllm::object({{"reads", axllm::array({"request", "route"})},
{"writes", axllm::array({"responderResult", "response"})}}))
.returns(axllm::object({{"route", "route"}, {"response", "response"}}));
axllm::Value output = program.forward(client, axllm::object({{"request", "A customer says checkout is down for their enterprise account."}}));
std::cout << axllm::stringify(output) << "\n";
}C++ Parallel Flow
Runs two independent OpenAI-backed steps in parallel before joining their results.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
intermediate - Run:
npm run example -- cpp src/examples/cpp/flows/parallel-flow.cpp - Source: src/examples/cpp/flows/parallel-flow.cpp
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <iostream>
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 research = axllm::ax("topicText:string -> factList:string[]");
axllm::AxGen audience = axllm::ax("topicText:string -> audienceAngle:string");
axllm::AxGen join = axllm::ax("factList:string[], audienceAngle:string -> briefText:string");
axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.parallelFlow"}}))
.execute("research", research,
axllm::object({{"reads", axllm::array({"topicText"})},
{"writes", axllm::array({"researchResult", "factList"})}}))
.execute("audience", audience,
axllm::object({{"reads", axllm::array({"topicText"})},
{"writes", axllm::array({"audienceResult", "audienceAngle"})}}))
.execute("join", join,
axllm::object({{"reads", axllm::array({"factList", "audienceAngle"})},
{"writes", axllm::array({"joinResult", "briefText"})}}))
.returns(axllm::object({{"briefText", "briefText"}}));
axllm::Value output = program.forward(
client,
axllm::object({{"topicText", "Why typed contracts make multi-step LLM systems easier to maintain"}}));
std::cout << axllm::stringify(output) << "\n";
}C++ Controlled Background Flow
Uses ordinary generation with background tools, steering, and a reasoning update.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
advanced - Run:
npm run example -- cpp src/examples/cpp/flows/astra_async.cpp - Source: src/examples/cpp/flows/astra_async.cpp
#include "axllm/axllm.hpp"
#include <iostream>
using namespace axllm;
struct RunState { std::atomic<bool> pending{false},finished{false},overlap{false},steered{false};std::atomic<int> applied{0};AxRunControl control; };
int main(){
const char* key=std::getenv("OPENAI_API_KEY");if(!key||!*key)key=std::getenv("OPENAI_APIKEY");if(!key||!*key)throw std::runtime_error("Set OPENAI_API_KEY or OPENAI_APIKEY.");
auto client=ai("openai",object({{"api_key",key},{"model","gpt-6-astra"},{"model_config",object({{"thinkingTokenBudget","low"},{"max_tokens",4096}})}}));
auto state=std::make_shared<RunState>();auto control=state->control;std::weak_ptr<RunState> weak=state;
control.on_event([weak](Value event){if(auto state=weak.lock();state&&stringify(Core::get(event,"type"))=="\"applied\"")++state->applied;});
Value schema=object({{"type","object"},{"properties",Value::object()},{"additionalProperties",false}});
Tool slow("slow_reference","Look up a reference; takes a few seconds.",schema,[state](Value){state->pending.store(true);if(!state->steered.exchange(true)){state->control.steer("Include the word VERIFIED in the final answer.");state->control.set_thinking_token_budget("medium");}std::this_thread::sleep_for(std::chrono::seconds(6));state->finished.store(true);return Value("REF-42");});slow.execution("background");
Tool label("local_label","Read an independent local label immediately.",schema,[state](Value){for(int i=0;i<300&&!state->pending.load();++i)std::this_thread::sleep_for(std::chrono::milliseconds(10));if(state->pending.load()&&!state->finished.load())state->overlap.store(true);return Value("LAUNCH");});
auto program=ax("question -> answer");program.add_tool(slow).add_tool(label);
auto verifier=ax("answer -> report \"Repeat the exact reference, label, and verification word from the answer.\"");
auto workflow=flow().execute("lookup",program,object({{"writes",Value(Array{"answer"})}})).execute("verify",verifier,object({{"reads",Value(Array{"answer"})}})).returns(object({{"answer","report"}}));
Value result=workflow.forward(*client,object({{"question","First call slow_reference. While it is pending, call local_label. Call each tool only once; do not call a tool again while its result is pending. If a required tool result is still pending, end this response with a brief progress message. The application will continue with the result when it arrives; do not spend reasoning tokens waiting for it. Once both results arrive, return them in one sentence."}}),object({{"control",control.value()},{"serviceTier","standard"},{"maxSteps",6}}));
std::string answer=stringify(result);for(const std::string& word:{"REF-42","LAUNCH","VERIFIED"})if(answer.find(word)==std::string::npos)throw std::runtime_error("Missing final result: "+answer);
if(!state->overlap.load())throw std::runtime_error("No independent work while background tool was pending");if(state->applied.load()!=4)throw std::runtime_error("Control updates were not applied");
std::cout<<answer<<"\nBackground overlap verified; steering and reasoning applied at the next response.\n";
}C++ Concurrent Astra Flow
Independent conversations overlap, retain their tool results, and receive scoped controls.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
advanced - Run:
npm run example -- cpp src/examples/cpp/flows/astra_parallel.cpp - Source: src/examples/cpp/flows/astra_parallel.cpp
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <iostream>
#include <set>
using namespace axllm;
int main(){
const char* key=std::getenv("OPENAI_API_KEY");if(!key||!*key)key=std::getenv("OPENAI_APIKEY");if(!key||!*key)throw std::runtime_error("Set OPENAI_API_KEY or OPENAI_APIKEY.");
auto client=ai("openai",object({{"api_key",key},{"model","gpt-6-astra"},{"model_config",object({{"thinkingTokenBudget","low"},{"max_tokens",4096}})}}));
struct Gate{std::mutex mutex;std::condition_variable ready;int calls=0;bool updates=false;};auto gate=std::make_shared<Gate>();
auto control=run_control();std::set<std::string> paths;std::vector<Value> applied;
control.on_event([&control,&paths,&applied,gate](Value event){
if(display(Core::get(event,"type"))=="tool.started"){
paths.insert(display(Core::get(event,"path")));if(paths.size()==2){control.steer("Include VERIFIED with the exact reference in your final answer.");control.set_thinking_token_budget("medium","root/left");std::lock_guard<std::mutex> lock(gate->mutex);gate->updates=true;gate->ready.notify_all();}
}
if(display(Core::get(event,"type"))=="applied")applied.push_back(event);
});
Tool lookup("lookup","Look up the exact reference once.",Value::object(),[gate](Value){
std::unique_lock<std::mutex> lock(gate->mutex);if(++gate->calls>2)throw std::runtime_error("Lookup was called more than once per node");gate->ready.notify_all();
if(!gate->ready.wait_for(lock,std::chrono::seconds(45),[&]{return gate->calls==2&&gate->updates;}))throw std::runtime_error("Both controlled nodes did not overlap");return Value("REF-42");
});lookup.execution("background");
auto program=ax("question -> answer");program.add_tool(lookup);
auto workflow=flow().execute("left",program).execute("right",program).returns(object({{"left","leftResult"},{"right","rightResult"}}));
auto result=workflow.forward(*client,object({{"question","Call lookup exactly once. If its result is pending, return a brief progress message without calling it again. Return the exact reference when its result arrives."}}),object({{"control",control.value()},{"serviceTier","standard"},{"maxSteps",6}}));
if(paths!=std::set<std::string>{"root/left","root/right"}||applied.size()!=3)throw std::runtime_error("Scoped controls did not apply");
for(const auto* node:{"left","right"}){auto answer=stringify(Core::get(result,node));if(answer.find("REF-42")==std::string::npos||answer.find("VERIFIED")==std::string::npos)throw std::runtime_error("Missing final result: "+answer);}
std::cout<<stringify(result)<<"\nParallel overlap verified; root steering and targeted reasoning applied.\n";
}C++ Composed Flow
Composes multiple typed programs into one OpenAI-backed flow.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
advanced - Run:
npm run example -- cpp src/examples/cpp/flows/composed_flow.cpp - Source: src/examples/cpp/flows/composed_flow.cpp
#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 step = axllm::ax("topic:string -> outline:string[]");
axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.composedFlow"}}))
.execute("step", step)
.map("note", [](axllm::Value) { return axllm::object({{"note", "Mapped flow state after the provider-backed step."}}); })
.returns(axllm::object({{"step", "step"}, {"note", "note"}}));
axllm::Value output = program.forward(client, axllm::object({{"topic", "How Ax moves from typed generation to agents, flows, and optimization"}}));
std::cout << axllm::stringify(output) << "\n";
}C++ Refinement Flow
Drafts, critiques, and revises an answer through three OpenAI-backed steps.
- Provider:
openai - Env:
OPENAI_API_KEY,OPENAI_APIKEY - Level:
advanced - Run:
npm run example -- cpp src/examples/cpp/flows/refine-flow.cpp - Source: src/examples/cpp/flows/refine-flow.cpp
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <iostream>
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 draft = axllm::ax("topicText:string -> draftText:string");
axllm::AxGen critique = axllm::ax("draftText:string -> critiqueText:string");
axllm::AxGen revise = axllm::ax("draftText:string, critiqueText:string -> revisedText:string");
axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.refineFlow"}}))
.execute("draft", draft,
axllm::object({{"reads", axllm::array({"topicText"})},
{"writes", axllm::array({"draftResult", "draftText"})}}))
.execute("critique", critique,
axllm::object({{"reads", axllm::array({"draftText"})},
{"writes", axllm::array({"critiqueResult", "critiqueText"})}}))
.execute("revise", revise,
axllm::object({{"reads", axllm::array({"draftText", "critiqueText"})},
{"writes", axllm::array({"reviseResult", "revisedText"})}}))
.returns(axllm::object({{"revisedText", "revisedText"}}));
axllm::Value output = program.forward(
client,
axllm::object({{"topicText", "Explain automatic flow parallelism to a backend engineer."}}));
std::cout << axllm::stringify(output) << "\n";
}