Skip to main content
Source Code: cpp/ in the GAIA repository.
Component: gaia::Agent base class and supporting libraries Language: C++17 Build system: CMake 3.14+ Dependencies: nlohmann/json, cpp-httplib, Google Test (all fetched automatically)

Overview

The GAIA C++17 framework is a native implementation of the core agent system. It compiles to a standalone binary with no interpreter overhead or runtime dependencies. What it provides:
  • Agent execution loop with state machine (planning, tool execution, error recovery, completion)
  • Tool registry with registerTool() for defining agent capabilities
  • MCP client with cross-platform stdio transport
  • JSON response parsing with multi-strategy fallback (code-block extraction, bracket matching, syntax fixing)
  • Console output with ANSI colors (TerminalConsole, CleanConsole) and silent mode (SilentConsole)
  • Vision-language model (VLM) supportgaia::Image + processQuery(..., images) overloads send images inline to OpenAI-compatible vision endpoints; see API Reference
The C++ framework focuses on the core agent loop and tool execution. Specialized agents (Code, Docker, Jira, Blender), the REST API server, RAG, and audio are available in the Python SDK.

Agent Execution Flow

  1. User query enters agent.processQuery()
  2. Agent composes a system prompt (tool descriptions + response format) and sends it to the LLM via HTTP
  3. LLM returns a JSON plan with tool calls
  4. Agent executes each tool — either a locally registered C++ callback or a remote MCP tool via JSON-RPC 2.0 over stdio
  5. Tool results feed back to the LLM for further reasoning
  6. Loop repeats until the LLM produces a final answer or the step limit is reached

Reactive Agent Loop

The agent is not a script. After every tool execution, the LLM is called again with the full conversation so far — including the tool’s output. This lets the model reason about results and change course. Each loop iteration: LLM reasons → agent executes → result fed back → LLM reasons again. The LLM can skip steps, add new ones, or pivot strategy at any point.

How It Works

The health_agent demo is a Windows System Health Agent. It subclasses gaia::Agent, connects to the Windows MCP server on startup, then enters the planning loop.

Wi-Fi Troubleshooter Demo

The wifi_agent demonstrates adaptive reasoning without MCP — all tools are registered directly in C++ as PowerShell commands. This showcases how an agent differs from a script: it reasons about each result, skips irrelevant steps, applies fixes, and verifies outcomes. Key features:
  • Structured reasoning — LLM outputs FINDING: and DECISION: prefixes, displayed with color-coded labels in the TUI
  • Adaptive behavior — skips downstream checks if adapter is disconnected, adds fix/verify steps when issues are found
  • Real tools — all diagnostics (netsh, ipconfig, Test-NetConnection) and fixes (flush DNS, toggle Wi-Fi radio, restart adapter) execute real PowerShell commands
  • GPU/NPU selection — choose between GGUF (GPU) and FLM (NPU) model backends at startup
  • Admin detection — warns on startup if fix tools won’t work without elevation
See the Wi-Fi Troubleshooter Agent guide for a full walkthrough.

How Tools Are Implemented

Tools are C++ lambdas registered with ToolRegistry. The Wi-Fi agent’s tools wrap PowerShell commands via a runShell() helper that uses _popen() to spawn a PowerShell subprocess:
The agent itself is pure C++. PowerShell is just the shell subprocess that executes system commands (netsh, ipconfig, Test-NetConnection). For complex operations like the WinRT Radio API, the tool writes a temporary .ps1 script and runs it via powershell -File.

Structured Reasoning Display

The system prompt instructs the LLM to prefix its reasoning with FINDING: and DECISION:. The custom CleanConsole output handler parses these and displays them with color-coded labels:
  • Finding (green) — what the diagnostic data shows
  • Decision (yellow) — what the agent will do next and why
This is what distinguishes an agent from a script: the decision points are visible. When the agent skips a step (“adapter is disconnected — IP checks would fail”), applies a fix, or re-runs a diagnostic to verify, you can see the reasoning that drove that choice.

Writing Your Own Agent

Subclass gaia::Agent, override getSystemPrompt() and optionally registerTools(), then call init() at the end of your constructor:
Why init() in the constructor? C++ virtual dispatch does not work from base-class constructors. Calling init() at the end of your subclass constructor ensures registerTools() and getSystemPrompt() resolve to your overrides.

Connecting MCP Servers

Register all tools exposed by an MCP server with a single call:

AgentConfig Reference

All fields have sensible defaults. Override only what you need:

Project Structure


Comparison with GAIA Python SDK


Next Steps

Setup

Install CMake, a C++17 compiler, Git, and Lemonade Server

Quickstart

Build steps and running your first demo agent

API Reference

Error handling, thread safety, security, deployment, and complete class API

Integration Guide

Consume gaia_core in your own CMake project via FetchContent, find_package, or shared library

Custom Agent

Custom prompts, typed tools, MCP servers, output capture, and AgentConfig tuning