# Agentic
[](https://elixir-lang.org/)
[](LICENSE)
[](https://hex.pm/packages/agentic)
A composable AI agent runtime for Elixir. Provides a complete agent loop with skills, working memory, knowledge persistence, and tool use. Drop it into any Elixir project to get a fully functional AI agent.
## Features
- **Composable Pipeline** — Middleware-style stage pipeline lets you mix and match agent behaviors
- **Multiple Profiles** — Four built-in profiles: `agentic`, `agentic_planned`, `turn_by_turn`, `conversational`
- **Tool Execution** — Built-in file operations, glob, grep, and extensibility for custom tools
- **Skills System** — YAML-defined skills that extend agent capabilities at runtime
- **Working Memory** — Context keeper with fact extraction and commitment detection
- **Persistence** — Transcript, plan, and knowledge persistence with pluggable backends
- **Cost Controls** — Per-session cost limits and token usage tracking
- **Telemetry** — Full event instrumentation via Telemetry
## Installation
Add Agentic to your dependencies in `mix.exs`:
```elixir
def deps do
[
{:agentic, "~> 0.1.0"}
]
end
```
### Database Backend
Agentic uses Recollect for knowledge persistence. Recollect supports two database backends:
**Option A: libSQL (Recommended for new projects)**
Single-file SQLite with native vector support. Zero configuration.
```elixir
def deps do
[
{:agentic, "~> 0.1.0"},
{:ecto_libsql, "~> 0.9"}
]
end
```
Configure Recollect:
```elixir
config :recollect,
database_adapter: Recollect.DatabaseAdapter.LibSQL,
repo: MyApp.Repo,
embedding: [
provider: Recollect.Embedding.OpenRouter,
dimensions: 768
]
```
**Option B: PostgreSQL (For existing installations)**
Traditional server-based database with pgvector extension.
```elixir
def deps do
[
{:agentic, "~> 0.1.0"},
{:postgrex, "~> 0.19"},
{:pgvector, "~> 0.3"}
]
end
```
Configure Recollect:
```elixir
config :recollect,
database_adapter: Recollect.DatabaseAdapter.Postgres,
repo: MyApp.Repo,
embedding: [
provider: Recollect.Embedding.OpenRouter,
dimensions: 1536
]
```
## Quick Start
```elixir
result = Agentic.run(
prompt: "Create a README.md file for my project",
workspace: "/path/to/your/project",
callbacks: %{
llm_chat: fn params -> MyLLM.chat(params) end
}
)
{:ok, %{text: response, cost: 0.05, tokens: 150, steps: 3}}
```
## Architecture
Agentic uses a **stage pipeline** architecture. Each stage wraps the next, receiving the context and a `next` function to call downstream:
```
ContextGuard → ProgressInjector → LLMCall → ModeRouter → ToolExecutor → CommitmentGate
```
- **Engine** builds the pipeline from stage modules
- **Profile** maps named profiles to stage lists and configuration
- **Phase** is a pure-function state machine with validated transitions
- **Context** is the loop state passed through every stage
### Profiles
| Profile | Behavior |
|---------|----------|
| `:agentic` | Full pipeline with tool use, progress tracking, context management (default) |
| `:agentic_planned` | Two-phase: plan → execute with tracking and verification |
| `:turn_by_turn` | LLM proposes changes, human approves before execution |
| `:conversational` | Simple call-respond, no tools |
## Callbacks API
The `callbacks` map connects Agentic to your LLM provider and external systems:
### Required
- `:llm_chat` — `(params) -> {:ok, response} | {:error, term}`
### Optional
- `:execute_tool` — custom tool handler (defaults to built-in tools)
- `:on_event` — `(event, ctx) -> :ok` for UI streaming
- `:on_response_facts` — `(ctx, text) -> :ok` for custom fact processing
- `:on_tool_facts` — `(ws_id, name, result, turn) -> :ok`
- `:on_persist_turn` — `(ctx, text) -> :ok`
- `:get_tool_schema` — `(name) -> {:ok, schema} | {:error, reason}`
- `:get_secret` — `(service, key) -> {:ok, value} | {:error, reason}`
- `:knowledge_search` — `(query, opts) -> {:ok, entries} | {:error, term}`
- `:knowledge_create` — `(params) -> {:ok, entry} | {:error, term}`
- `:knowledge_recent` — `(scope_id) -> {:ok, entries} | {:error, term}`
- `:search_tools` — `(query, opts) -> [result]`
- `:execute_external_tool` — `(name, args, ctx) -> {:ok, result} | {:error, reason}`
## Core Tools
Agentic ships with built-in tools for file operations:
- `file_read` — Read file contents
- `file_write` — Write or overwrite files
- `file_edit` — Apply targeted edits using line ranges
- `glob` — Find files by pattern
- `grep` — Search file contents
- `bash` — Execute shell commands
- `task` — Delegate to sub-agents
- `memory` — Store and retrieve facts
- `skills_list` — List available skills
- `skills_apply` — Apply a skill to the workspace
- `gateway` — Query external services
Extend via the skills system or custom callbacks.
## Storage Backends
- **Transcript** — Session history with event streaming
- **Plan** — Structured task plans (for `:agentic_planned` mode)
- **Knowledge** — Persistent fact storage with search
- **Context** — Workspace context with pluggable backends
All backends have a `:local` file-based implementation.
## Configuration
```elixir
Agentic.run(
prompt: "...",
workspace: "/path",
callbacks: %{llm_chat: &my_llm/1},
profile: :agentic, # which profile to use
mode: :agentic, # shorthand for profile
system_prompt: "...", # custom system prompt
history: [...], # prior messages
model_tier: :primary, # which model tier to use
cost_limit: 5.0, # per-session cost limit in USD
session_id: "agx-...", # custom session ID
user_id: "user-123", # for API key resolution
plan: %{...} # pre-built plan (for agentic_planned)
)
```
## Development
```bash
mix deps.get # Install dependencies
mix setup # Setup database
mix test # Run tests
mix format # Format code
mix dialyzer # Type check
```
## License
BSD-3-Clause — See [LICENSE](LICENSE) for details.
## Contributing
Contributions welcome. Please ensure tests pass and dialyzer is clean before submitting PRs.