Build intelligent agentic services from hierarchical knowledge trees.
Agentize is a Go library for building agentic services. You give it a filesystem-based knowledge tree and an LLM, and it manages users, sessions, message processing, tool calls, multi-agent routing, summarization, persistence, and an operational dashboard. It is embedded into a host application (it is not a standalone CLI/server).
- π³ Knowledge-tree navigation β hierarchical nodes with automatic discovery and tool accumulation
- π Node RBAC β role/group/user permissions with inheritance (see docs/AUTH_EXAMPLES.md)
- π€ LLM message processing β single-agent or multi-agent (Core router + worker agents)
- π¬ Sessions & summarization β persistent sessions with a background rolling-window summarizer
- ποΈ Pluggable storage β SQLite (default) or MongoDB behind one
store.Storeinterface - π User files & image editing β record uploads,
manage_filestool, optional OpenRouter image edits - π§ Planning DAG β optional plan execution with status/cancel tools
- π Observability β ~30 Prometheus metrics + two Grafana dashboards (see docs/METRICS.md)
- π οΈ Debug dashboard β users, sessions, messages, files, tool calls, routing DAGs, summarization logs β behind admin auth
go get github.com/ghiac/agentizepackage main
import (
"context"
"fmt"
"github.com/ghiac/agentize"
"github.com/ghiac/agentize/engine"
)
func main() {
// Loads every node under ./knowledge (SQLite store + local file store by default).
ag, err := agentize.New("./knowledge")
if err != nil {
panic(err)
}
// Configure the LLM. This also starts the summarization scheduler.
if err := ag.UseLLMConfig(engine.LLMConfig{
APIKey: "sk-...", // or your OpenRouter/compatible key
Model: "openai/gpt-4o",
// BaseURL: "https://openrouter.ai/api/v1", // optional
}); err != nil {
panic(err)
}
// One session per user, then process messages against it.
session, err := ag.CreateSession("user-123")
if err != nil {
panic(err)
}
resp, tokens, err := ag.ProcessMessage(context.Background(), session.SessionID, "Hello!")
if err != nil {
panic(err)
}
fmt.Printf("reply=%q tokens=%d\n", resp, tokens)
}Open a store explicitly and pass it in. Switching backends is a one-line config change.
import (
"github.com/ghiac/agentize"
"github.com/ghiac/agentize/engine"
"github.com/ghiac/agentize/store"
)
// SQLite (default backend)
s, err := store.Open(store.Config{
Backend: "sqlite",
SQLitePath: "./data/sessions.db", // ":memory:" for ephemeral
})
// β¦or MongoDB
// s, err := store.Open(store.Config{Backend: "mongodb", MongoURI: "mongodb://localhost:27017"})
if err != nil {
panic(err)
}
defer s.Close()
ag, err := agentize.NewWithOptions("./knowledge", &agentize.Options{
SessionStore: s,
FileStoreDir: "./data/files",
})
if err != nil {
panic(err)
}
_ = ag.UseLLMConfig(engine.LLMConfig{APIKey: "sk-...", Model: "openai/gpt-4o"})
// The background summarizer is now running; stop it on shutdown:
defer ag.StopScheduler()The scheduler is tuned via env vars (all optional):
| Variable | Default | Meaning |
|---|---|---|
AGENTIZE_SCHEDULER_ENABLED |
true |
Master switch |
AGENTIZE_SCHEDULER_CHECK_INTERVAL_MINUTES |
5 |
How often to scan sessions |
AGENTIZE_SCHEDULER_FIRST_THRESHOLD |
5 |
Messages before the first summarization |
AGENTIZE_SCHEDULER_SUBSEQUENT_MESSAGE_THRESHOLD |
25 |
Messages before re-summarizing |
AGENTIZE_SCHEDULER_SUMMARY_MODEL |
openai/gpt-5-nano |
Model used for summaries |
Implement engine.Callback to meter usage and gate actions, mount the
/agentize routes on your Gin router, and protect them with admin credentials.
import (
"context"
"fmt"
"github.com/ghiac/agentize"
"github.com/ghiac/agentize/engine"
"github.com/gin-gonic/gin"
)
type billing struct{ /* your credit store */ }
// BeforeAction may return an error to BLOCK the call (e.g. quota exceeded).
func (b *billing) BeforeAction(ctx context.Context, e *engine.UsageEvent) error {
return nil
}
// AfterAction records actual usage (tokens, model, duration).
func (b *billing) AfterAction(ctx context.Context, e *engine.UsageEvent) {
fmt.Printf("usage user=%s model=%s in=%d out=%d\n",
e.UserID, e.Model, e.InputTokens, e.OutputTokens)
}
func main() {
ag, _ := agentize.New("./knowledge")
_ = ag.UseLLMConfig(engine.LLMConfig{APIKey: "sk-...", Model: "openai/gpt-4o"})
// Meter/gate every LLM, tool and agent-routing call.
ag.GetEngine().Callback = &billing{}
// Protect the dashboard + metrics. Without credentials a warning is logged
// and the pages are open β never do that on an untrusted network.
ag.SetAdminCredentials("admin", "change-me") // or AGENTIZE_ADMIN_USERNAME/PASSWORD
router := gin.New()
ag.RegisterRoutes(router) // mounts /agentize, /agentize/metrics, /agentize/debug/*, /agentize/health
_ = router.Run(":8080")
}Routes mounted by RegisterRoutes (all but /agentize/health and the login
endpoints require a signed-in admin once credentials are set):
| Route | Purpose |
|---|---|
GET /agentize/health |
Liveness (always open) |
GET /agentize/metrics |
Prometheus metrics (dedicated registry) |
GET /agentize |
Index |
GET /agentize/debug/* |
Users, sessions, messages, files, tool calls, routing DAGs, summarization logs |
GET /agentize/docs, /agentize/graph |
Generated docs + knowledge-graph visualization |
See docs/SECURITY.md for the threat model and docs/OPERATIONS.md for running it in production.
For routing between specialized worker agents (e.g. a cheap "low" agent and a
capable "high" agent), compose an AgentManager and a CoreHandler. Each worker
is an *engine.Engine; the Core LLM decides which to delegate to.
import (
"github.com/ghiac/agentize/agentmanager"
"github.com/ghiac/agentize/core"
"github.com/ghiac/agentize/engine"
"github.com/ghiac/agentize/model"
)
sessionHandler := model.NewSessionHandler(store, model.DefaultSessionHandlerConfig())
agents := agentmanager.New(sessionHandler)
// Register each worker agent (engine construction is detailed in CORE_AGENT.md).
_ = agents.Register(agentmanager.AgentConfig{
Name: "high",
Model: "openai/gpt-4o",
AgentType: model.AgentTypeHigh,
CostTier: agentmanager.CostTierHigh,
}, highEngine)
cfg := core.DefaultCoreHandlerConfig()
cfg.CoreLLMConfig = engine.LLMConfig{APIKey: "sk-...", Model: "openai/gpt-5-nano"}
ch := core.NewCoreHandler(sessionHandler, agents, cfg)
_ = ch.UseLLMConfig(cfg.CoreLLMConfig)
ch.SetCallback(myBillingCallback) // propagates to every worker engine
reply, err := ch.ProcessMessage(context.Background(), "user-123", "Help me research X")The full multi-agent wiring (engine fields, knowledge sets, web search, planning) is documented in docs/CORE_AGENT.md and docs/ARCHITECTURE.md.
knowledge/
root/
node.md # Markdown content / instructions
node.yaml # Node metadata, routing, and auth
tools.json # Tools available at this level
next/ # Child nodes
node.md
node.yaml
tools.json
id: "root"
title: "Root Node"
description: "Entry point for the knowledge tree"
# RBAC β see docs/AUTH_EXAMPLES.md
auth:
inherit: true
default: { perms: "r" }
roles:
admin: { perms: "rwx" }
routing:
mode: "sequential" # or "parallel" / "conditional"
memory:
persist: ["summary", "facts"]{
"tools": [
{
"name": "search_docs",
"description": "Search in documentation",
"input_schema": {
"type": "object",
"properties": { "q": { "type": "string" } },
"required": ["q"]
}
}
]
}| Variable | Effect |
|---|---|
AGENTIZE_ADMIN_USERNAME / AGENTIZE_ADMIN_PASSWORD |
Protect the /agentize dashboard + metrics |
AGENTIZE_LOG_LEVEL |
debug|info|warn|error (default info) |
AGENTIZE_LOG_FORMAT |
text (default) or json |
AGENTIZE_METRICS_DEFAULT_REGISTRY |
1 exposes the full global Prometheus registry |
AGENTIZE_SCHEDULER_* |
Summarization scheduler tuning (see above) |
make test # go test ./...
make test-race # go test -race ./... (matches CI)
make test-full # format + vet + build + tests + coverage (scripts/test.sh)CI (.github/workflows/ci.yml) runs gofmt,
go vet, go build, and go test -race -coverprofile on every push and PR.
The MongoDB store conformance suite runs against a real MongoDB via
testcontainers and self-skips when Docker is unavailable.
| Doc | Topic |
|---|---|
| docs/ARCHITECTURE.md | System architecture |
| docs/CORE_AGENT.md | Core router + system-prompt assembly |
| docs/PLANNING.md | Planning DAG |
| docs/ROUTING_DAG.md | Routing-decision traces |
| docs/METRICS.md | Prometheus metrics + Grafana dashboards |
| docs/SECURITY.md | Threat model, debug-route exposure, PII |
| docs/OPERATIONS.md | Backup, scaling, alerts, graceful shutdown |
| docs/AUTH_EXAMPLES.md | Node RBAC examples (EN / FA) |
| CHANGELOG.md | Changes & deprecations |
agentize/
βββ model/ # Core data structures (Node, Session, Tool, Auth, User, Message)
βββ fsrepo/ # Filesystem repository for loading nodes
βββ core/ # Core router (multi-agent orchestration)
βββ agentmanager/ # Worker-agent registry
βββ engine/ # Per-agent engine (LLM loop, tools, scheduler)
βββ planning/ # Plan execution DAG
βββ store/ # Persistence (SQLite / MongoDB) behind one interface
βββ filestore/ # Pluggable byte storage for user files
βββ metrics/ # Prometheus instrumentation
βββ debuger/ # Debug dashboard pages
βββ documents/ # Documentation generation
βββ visualize/ # ECharts knowledge-graph visualization