Skip to content

Repository files navigation

Adam

Embeddable AI agent library in C.

Adam gives you a complete agent loop: tool calling, memory, sessions, voice, streaming, structured output, in one #include. Works with cloud APIs (Anthropic, OpenAI, Google Gemini, Groq, Together, xAI) and local models (llama.cpp) through the same interface. Compiles on macOS, Linux, Windows, iOS, Android, and WASM.

Quick Start

#include"adam.h"intmain(void) {
adam_init();
adam_settings_t*s=adam_create_settings();
adam_settings_set_provider(s, ADAM_API_ANTHROPIC,
getenv("ANTHROPIC_API_KEY"),
"claude-sonnet-4-20250514");
adam_history_t*h=adam_history_create();
adam_run_result_tr=adam_run(s, h, "What is the capital of France?");
printf("%s\n", r.final_response); // "The capital of France is Paris."adam_run_result_free(&r);
adam_history_destroy(h);
adam_settings_destroy(s);
adam_cleanup();
}
make deps # build llama.cpp + whisper.cpp
make all # build libadam.a
make test# run 161 tests (ASan + UBSan)

Features

FeatureDescription
Agent loopTool calling with automatic iteration until final response
Three providersAnthropic, OpenAI, Google Gemini + any compatible API + local GGUF via llama.cpp
Local visionMultimodal image understanding via llama.cpp + mmproj (Gemma 3, LLaVA, etc.)
Image generationNative image output via Gemini image models (gemini-3.1-flash-image-preview)
Database extensionsSQLite and PostgreSQL extensions — embed Adam as SQL functions that query the same database
13 built-in toolsFile I/O, shell, calculator, SQL, web fetch/search, HTTP POST, memory, research, multi-agent
Long-term memoryHybrid BM25 + vector search via SQLite (sqlite-memory + sqlite-vector)
Session persistenceSave/load conversations with UUIDv7 keys
Telegram botFull-featured Telegram integration with text, voice, images, tools, and memory
VoiceSTT (Whisper cloud/local) + TTS (cloud/system) + full audio pipeline
StreamingReal-time token delivery via callback
Structured outputadam_run_json() with validation and retry
Evolution loopSelf-improving agent: iterate, score, refine strategy
Research modeAutonomous multi-iteration information gathering with report synthesis
Multi-agentAgent A invokes Agent B as a tool, with independent settings/tools
GuardrailsPre-send and post-receive validation callbacks
Response cacheLRU hash table keyed on model + message history
History managementClone, summarize (LLM-based compression), token estimation
Thread poolConcurrent agent execution with job queue
Filesystem sandboxTools restricted to explicitly allowed directories
Cross-platformmacOS, Linux, Windows, iOS, Android, WASM (Emscripten)
Arena allocatorZero-leak per-iteration memory with automatic cleanup

Build

make deps # Build llama.cpp, whisper.cpp (+ mbedtls/curl on Linux)
make all # Build libadam.a
make test# Build & run unit tests (ASan + UBSan)
make chat # Interactive text chat (cloud API)
make chat GGUF=models/model.gguf # Interactive text chat (local)
make vision GGUF=models/model.gguf MMPROJ=models/mmproj.gguf # Local vision test
make talk # Voice agent (cloud)
make talk LOCAL=1 # Voice agent (fully local)
make memory # Memory system tests
make clean # Remove all build artifacts

API Reference

Full API documentation with every function, type, and callback: API.md

Examples

adam_settings_t*s=adam_create_settings();
adam_settings_set_provider(s, ADAM_API_ANTHROPIC, api_key, "claude-sonnet-4-20250514");
adam_history_t*h=adam_history_create();
adam_run_result_tr=adam_run(s, h, "Explain quantum entanglement simply.");
printf("%s\n", r.final_response);
adam_run_result_free(&r);
// Continue the conversation — history carries forwardr=adam_run(s, h, "Can you give an analogy?");
printf("%s\n", r.final_response);
adam_run_result_free(&r);
adam_history_destroy(h);
adam_settings_destroy(s);

More examples are available in the examples/ directory:

ExampleDescription
simple-conversationMulti-turn chat with a cloud API
tool-callingRegister a custom tool and let the agent call it
local-modelRun a local GGUF model via llama.cpp
local-visionImage understanding with a local vision model + mmproj
google-geminiUse Google Gemini models
image-generationGenerate images with Gemini
sqlite-queryNatural language queries on any SQLite database
structured-jsonGet validated JSON output with retry
memoryLong-term memory with hybrid BM25 + vector search
sessionsSave and restore conversations
streamingReal-time token streaming via callback
voiceSpeech-to-text + agent + text-to-speech pipeline
multi-agentAgent A delegates to Agent B as a tool
evolutionSelf-improving agent with scoring loop
researchAutonomous multi-iteration research with report
filesystem-sandboxFile and shell tools restricted to allowed directories
guardrailsPre-send and post-receive validation
response-cacheLRU cache for repeated queries
thread-poolConcurrent agent execution
telegramTelegram bot with text, images, tools, and memory
wasm-chatBrowser-based chat UI via WebAssembly
full-agentAll features combined

Database Extensions

Adam can be embedded directly inside SQLite and PostgreSQL as a SQL extension. The agent can query the same database it's loaded in — ask questions in natural language, get answers from your data.

-- SQLite
.load adam
-- PostgreSQL
CREATE EXTENSION adam;
-- Configure (both)SELECT adam_config('provider', 'anthropic');
SELECT adam_config('api_key', 'sk-ant-...');
-- Ask about your data — the agent reads the schema and runs SQLSELECT adam_ask('How many users signed up last month?');
-- → "47 users signed up last month."-- Generate SQL without executingSELECT adam_sql('top 5 products by revenue');
-- → "SELECT p.name, SUM(oi.quantity * oi.price) AS revenue FROM ..."
FunctionDescription
adam_config(key, val)Configure provider, API key, model (persisted)
adam(msg)Stateless one-shot chat
adam_ask(msg)SQL-aware agent — reads schema, queries data, multi-turn
adam_sql(question)Generate SQL from natural language
adam_create_session()Create session (auto-created on first adam_ask)
adam_get_session()Get current session UUID
adam_clear_session()Clear session and history

See extensions/sqlite/ and extensions/postgres/ for build instructions.

Architecture

adam_run() loop:
build system prompt (identity + instructions + bootstrap files + memory + datetime)
-> check guardrails (on_before_send)
-> check cache
-> dispatch LLM (mock | local/llama.cpp | remote/HTTP)
-> check guardrails (on_after_receive)
-> if tool_calls: execute tools -> append results -> loop
-> if text: return final response -> auto-save session -> extract memory

Platform abstraction: macOS uses NSURLSession, Linux uses libcurl+mbedtls, WASM uses embedder-provided http_fn callback.

Memory management: Arena allocators for per-iteration zero-copy work. malloc/free for long-lived structures. Arena-allocated strings are only valid within the current iteration.

Feature Gates

Define before #include "adam.h" to disable features:

GateEffect
ADAM_NO_CURLNo libcurl (must provide http_fn callback)
ADAM_NO_LOCALNo llama.cpp (no local inference)
ADAM_NO_PTHREADSNo thread pool, no voice thread
ADAM_NO_SQLITENo SQLite (no memory, sessions, or SQL tool)
ADAM_NO_VOICENo voice subsystem
ADAM_NO_FILESYSTEMNo file_read/file_write/list_directory tools
ADAM_NO_SHELLNo shell_exec tool

Dependencies

All vendored as git submodules in modules/:

ModulePurpose
llama.cppLocal LLM inference + GGML compute
whisper.cppLocal speech-to-text (shares ggml via symlink)
miniaudioCross-platform audio I/O
sqliteAmalgamation build
sqlite-memoryHybrid BM25 + vector knowledge store
sqlite-vectorVector similarity search
mbedtlsTLS (Linux only)
curlHTTP (Linux only)

macOS uses system frameworks (Foundation, Security, Metal, AVFoundation, Accelerate) instead of curl/mbedtls.

License

MIT

About

An embeddable cross-platform AI agent library written in C. Cloud and local LLMs, tool calling, long-term memory, voice, sessions, research mode, self-evolving loops. The SQLite of agent frameworks: small, portable, just works.

Resources

Stars

114 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages