Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
cpp/tests/fixtures/*.png binary
cpp/tests/fixtures/*.jpg binary

# Vendored third-party sources — never ours to reformat, lint, or review.
# linguist-vendored keeps them out of language stats; -diff keeps a 9 MB
# amalgamation out of every diff that touches the directory.
cpp/third_party/** linguist-vendored
cpp/third_party/sqlite/sqlite3.c -diff
cpp/third_party/sqlite/sqlite3.h -diff

# Every email-agent PR appends an [Unreleased] bullet to this changelog;
# without a union merge, sibling PRs merged close together conflict on the
# same insertion point.
Expand Down
76 changes: 75 additions & 1 deletion cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ endif()
# Must be included before project() so the toolchain is set in time.
include(${CMAKE_CURRENT_LIST_DIR}/cmake/vcpkg-auto-setup.cmake)

project(gaia-cpp VERSION 0.1.0 LANGUAGES CXX)
# C is required for the vendored SQLite amalgamation (third_party/sqlite).
project(gaia-cpp VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -112,6 +113,66 @@ if(GAIA_BUILD_TUI)
endif()
endif()

# ---------------------------------------------------------------------------
# SQLite — vendored amalgamation (third_party/sqlite), NOT find_package
# ---------------------------------------------------------------------------
# Deliberately no system-SQLite fallback: a distro build may lack FTS5 or use
# different compile-time defaults, and that only surfaces at query time on one
# platform. Compiling the amalgamation gives all three platforms identical
# semantics. See cpp/third_party/sqlite/README.md.
#
# An OBJECT library keeps SQLite's own warnings out of gaia_core's -Wall/-W4
# without loosening them for our code, and its objects are baked straight into
# gaia_core, so nothing extra ends up in the install export set.
add_library(gaia_sqlite3 OBJECT third_party/sqlite/sqlite3.c)

set(GAIA_SQLITE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sqlite)

target_include_directories(gaia_sqlite3 PRIVATE ${GAIA_SQLITE_INCLUDE_DIR})

set_target_properties(gaia_sqlite3 PROPERTIES
POSITION_INDEPENDENT_CODE ON
C_STANDARD 99
)

# Applied to both the amalgamation and to src/database.cpp, which includes
# sqlite3.h — the two must agree or the header describes a different build than
# the one linked in.
set(GAIA_SQLITE_DEFINITIONS
# Full-text search. A missing flag fails at *query* time, not build time —
# tests/test_database.cpp has an FTS5 smoke test that catches a silent drop.
SQLITE_ENABLE_FTS5
# Serialized mode: a gaia::Database may be shared across threads.
SQLITE_THREADSAFE=1
# Reject double-quoted string literals, so a typo'd column name is an error
# instead of silently becoming a string constant.
SQLITE_DQS=0
# Foreign-key constraints enforced unless a caller opts out.
SQLITE_DEFAULT_FOREIGN_KEYS=1
# Reject LIKE against BLOBs rather than coercing.
SQLITE_LIKE_DOESNT_MATCH_BLOBS
# WAL commits sync the WAL, not the whole database — the standard WAL default.
SQLITE_DEFAULT_WAL_SYNCHRONOUS=1
# Views/triggers/indexes can't invoke non-SQLITE_INNOCUOUS functions.
SQLITE_TRUSTED_SCHEMA=0
# Drop the global allocation counters we never read.
SQLITE_DEFAULT_MEMSTATUS=0
# Depth of the expression tree is bounded by SQLITE_MAX_SQL_LENGTH instead
# of a separate, lower limit that rejects legitimate generated SQL.
SQLITE_MAX_EXPR_DEPTH=0
)
# Note: no SQLITE_OMIT_* flags — upstream documents those as unsupported with
# the amalgamation. Loadable extensions are instead disabled per-connection via
# sqlite3_db_config() in src/database.cpp, which is a runtime guarantee.

target_compile_definitions(gaia_sqlite3 PRIVATE ${GAIA_SQLITE_DEFINITIONS})

# Third-party source: never our warnings to fix.
target_compile_options(gaia_sqlite3 PRIVATE
$<$<C_COMPILER_ID:MSVC>:/W0>
$<$<NOT:$<C_COMPILER_ID:MSVC>>:-w>
)

# Google Test (unit tests and/or integration tests)
if(GAIA_BUILD_TESTS OR GAIA_BUILD_INTEGRATION_TESTS)
find_package(GTest QUIET)
Expand Down Expand Up @@ -148,8 +209,17 @@ add_library(gaia_core
src/session.cpp
src/repl.cpp
src/json_event_handler.cpp
src/database.cpp
)

# SQLite is compiled straight into gaia_core. Consuming the OBJECT library via
# $<TARGET_OBJECTS:> rather than target_link_libraries keeps gaia_sqlite3 out of
# gaia_core's link interface, so install(EXPORT) has nothing extra to resolve —
# the same approach this file already takes for the fetched httplib/json.
target_sources(gaia_core PRIVATE $<TARGET_OBJECTS:gaia_sqlite3>)
target_include_directories(gaia_core PRIVATE ${GAIA_SQLITE_INCLUDE_DIR})
target_compile_definitions(gaia_core PRIVATE ${GAIA_SQLITE_DEFINITIONS})

# TUI sources (conditional on FTXUI availability)
if(GAIA_BUILD_TUI)
target_sources(gaia_core PRIVATE
Expand Down Expand Up @@ -212,6 +282,9 @@ endif()
# Platform-specific libraries
if(UNIX)
target_link_libraries(gaia_core PUBLIC pthread)
# SQLite references dlopen/dlsym on Unix even with extension loading
# disabled at runtime; the symbols must resolve at link time.
target_link_libraries(gaia_core PRIVATE ${CMAKE_DL_LIBS})
endif()
if(WIN32)
target_link_libraries(gaia_core PRIVATE ws2_32)
Expand Down Expand Up @@ -318,6 +391,7 @@ if(GAIA_BUILD_TESTS)
tests/test_session.cpp
tests/test_repl.cpp
tests/test_json_event_handler.cpp
tests/test_database.cpp
)

target_link_libraries(tests_mock PRIVATE
Expand Down
23 changes: 20 additions & 3 deletions cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,10 @@ gaia/ # repo root
│ ├── lemonade_client.h # HTTP client for the Lemonade inference server
│ ├── sse_parser.h # SSE parser for streaming chat completions
│ ├── console.h # TerminalConsole / SilentConsole output handlers
│ └── clean_console.h # CleanConsole — polished TUI with colors and word-wrap
│ ├── clean_console.h # CleanConsole — polished TUI with colors and word-wrap
│ └── database.h # SQLite: Database, Statement, Transaction, Migration
├── third_party/
│ └── sqlite/ # Vendored SQLite amalgamation (see its README)
├── src/
│ ├── agent.cpp # Agent loop state machine
│ ├── tool_registry.cpp
Expand All @@ -245,7 +248,8 @@ gaia/ # repo root
│ ├── mcp_client.cpp # Cross-platform subprocess + pipes (Win32 / POSIX)
│ ├── json_utils.cpp
│ ├── console.cpp
│ └── clean_console.cpp
│ ├── clean_console.cpp
│ └── database.cpp
├── examples/
│ ├── health_agent.cpp # Windows System Health Agent (MCP/CUA demo)
│ └── wifi_agent.cpp # Wi-Fi Troubleshooter (registered-tool demo)
Expand All @@ -260,6 +264,7 @@ gaia/ # repo root
│ ├── test_clean_console.cpp
│ ├── test_tool_integration.cpp
│ ├── test_types.cpp
│ ├── test_database.cpp
│ └── integration/
│ ├── test_main.cpp
│ ├── test_integration_llm.cpp
Expand Down Expand Up @@ -404,14 +409,26 @@ All tools exposed by the MCP server are automatically registered under the namin

## Dependencies

All fetched automatically by CMake — no manual installation needed.
No manual installation needed — CMake fetches these at configure time.

| Library | Version | License | Purpose |
|---------|---------|---------|---------|
| [nlohmann/json](https://github.com/nlohmann/json) | 3.11.3 | MIT | JSON parsing |
| [cpp-httplib](https://github.com/yhirose/cpp-httplib) | 0.15.3 | MIT | HTTP client (LLM API calls) |
| [FTXUI](https://github.com/ArthurSonzogni/FTXUI) | 6.1.9 | MIT | TUI console (optional, `GAIA_BUILD_TUI`) |
| [Google Test](https://github.com/google/googletest) | 1.14.0 | BSD-3 | Unit testing |

**Vendored in-tree** — checked in rather than fetched, so all three platform
builds compile byte-identical sources with the same feature flags:

| Library | Version | License | Purpose |
|---------|---------|---------|---------|
| [SQLite](https://sqlite.org) | 3.53.4 | public domain | Structured persistence (`gaia::Database`), FTS5 full-text search |

SQLite lives in [`third_party/sqlite/`](third_party/sqlite/) and is compiled
directly into `gaia_core`; there is deliberately no `find_package` fallback. See
that directory's README for the compile flags, the upgrade procedure, and why.

---

## Relationship to Python GAIA
Expand Down
Loading
Loading