TakoIA is a marketplace of autonomous AI expert agents. Each agent is a specialist you describe once and that then works on its own: it runs an explicit four-step loop — Analyse → Decision → Action → Restitution — and hands back a finished deliverable. What makes an agent irreplaceable is its persistent, personalized long-term memory (ICM): every run teaches it something, so the more you use an agent the better and more uniquely yours it becomes. Once an agent is good, you publish it to the marketplace and expose it as a token-billed hosted API — other people invoke it over HTTP, you keep a revenue share, and the agent (and its memory) never leave your backend.
Built for the Euratech 2026 hackathon. core-backend is the brain: a Rust
(Axum) orchestrator, a job queue, the ICM
memory bridge, a multi-provider LLM registry, and the marketplace + invoke API.
The companion Svelte app (with SvelteFlow) is a
visual builder for wiring the four steps. LLM calls go through the Claude CLI
(claude -p) so the agent runs on your Claude plan instead of per-token API
billing.
- Architecture
- Prerequisites
- Installation & configuration
- Environment variables
- Running
- Usage
- Security note
┌──────────────────────────┐ /api (REST + SSE) ┌────────────────────────────────┐
│ Svelte + SvelteFlow UI │ ───────────────────▶ │ Axum HTTP API (/api/*) │
│ visual 4-step builder │ ◀── SSE job events ── │ + serves the built frontend │
└──────────────────────────┘ └──────────────┬─────────────────┘
│ enqueue objective
▼
┌──────────────────────────────────────────┐
│ job queue (SQLite via sqlx) │
└──────────────┬───────────────────────────┘
│ worker dequeues
▼
┌───────────────────────────────────────────────────────────┐
│ agent engine — the 4-step loop │
│ Analyse ▶ Decision ▶ Action ▶ Restitution │
│ recall memory │ approval gate │ tools │ persist memory │
└───────┬───────────────┬───────────────┬───────────────────┘
│ │ │
LLM registry approvals (HITL) ICM memory store
(claude_max via pause job until (per-agent topic;
claude -p, ollama, a human approves `icm` CLI + DB
gemini, codex) fallback)
- Backend orchestrator (Axum). Exposes
/api/*(REST + Server-Sent Events for live job progress) and, in a production build, serves the compiled Svelte bundle from the same binary. Source undersrc/http/. - Job queue & worker. Objectives become jobs in the
sqlx/SQLite queue; a background worker claims them and drives the agent loop. The marketplace invoke endpoint runs a job inline for a synchronous response. - Agent engine (the 4-step loop).
src/agent/implements Analyse → Decision → Action → Restitution. The Decision step can pause on a human-in-the-loop approval gate; the Restitution step persists what was learned back into memory. - ICM memory.
src/memory.rsbridges TakoIA to the ICM (icmCLI) for semantic recall and consolidation, with a local SQLitememoriestable as a fallback. Each agent owns its own ICM topic, so its expertise is private and cumulative — this is what makes a trained agent irreplaceable. - LLM provider registry.
src/llm/selects a provider per step. The defaultclaude_maxprovider shells out toclaude -p --output-format json;ollama,gemini, andcodexare OpenAI-compatible HTTP providers. - Marketplace.
src/http/marketplace.rshandles publishing an agent, issuing consumer API keys (sk_…), the token-billed invoke API, revenue share, and earnings.
Stack: Rust (edition 2021) · tokio · Axum 0.7 + tower-http · sqlx 0.8
(SQLite) · reqwest · SSE · chacha20poly1305 (encrypts connector credentials at
rest). Frontend: Svelte 5 · Vite 5 · @xyflow/svelte (SvelteFlow) · Tailwind /
Flowbite, built with Bun.
| Requirement | Why | Notes |
|---|---|---|
| Rust (stable toolchain) | builds and runs the backend | rustup recommended |
| Bun (or Node 18+) | installs deps & builds the Svelte frontend | bun is what the Makefile uses |
claude CLI, authenticated |
the default claude_max LLM provider runs claude -p |
run claude once to log in, or generate a plan token with claude setup-token |
icm CLI |
persistent per-agent long-term memory (semantic recall) | optional but recommended — without it, memory falls back to a local SQLite table |
| SQLite | embedded database (queue, agents, memory) | no server needed; the file is created automatically |
openssl |
generate the MASTER_KEY |
already present on most systems |
The backend needs no external database server: SQLite is embedded and migrations run automatically on first boot.
git clone <this-repo-url> takoia-core-backend
cd takoia-core-backendDemo mode — no Claude, no ICM, no API keys. TakoIA degrades gracefully: without the
claudeCLI, agent runs complete using offline canned content; without theicmCLI, long-term memory falls back to a built-in SQLite store. So you can evaluate the entire product (the 4-step loop, the builder, the marketplace, the memory views) with zero LLM setup. Add a Claude token later for real model output.
The only prerequisite is Docker.
docker compose up --build # then open http://localhost:8080On the first visit, a setup wizard asks you to create your admin account
(email + password) — no shared default password. This builds the frontend +
backend and runs everything in one container. A MASTER_KEY is generated
automatically at startup (set it explicitly in docker-compose.yml to persist
encrypted connectors across restarts).
make demo # = make setup + make build + make run → http://localhost:8080make setup installs the frontend deps and creates a .env from .env-sample
with a freshly generated MASTER_KEY. make run builds the frontend bundle if
it is missing. To do it manually:
cp .env-sample .env
# generate a key and paste it as MASTER_KEY in .env:
openssl rand -base64 32Open the .env and set at least MASTER_KEY. Leave ADMIN_PASSWORD unset to
create the admin account through the first-run setup wizard (recommended), or
set ADMIN_USERNAME + ADMIN_PASSWORD to seed it non-interactively.
All configuration is environment-driven (loaded from .env). The table below
documents every variable read by src/config.rs.
| Variable | Default | Description |
|---|---|---|
MASTER_KEY |
none — required | 32-byte key, base64-encoded, used to encrypt connector credentials at rest (chacha20poly1305). The server refuses to start without it. Generate with openssl rand -base64 32. Must decode to exactly 32 bytes. |
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
sqlite://data/takoia.db?mode=rwc |
Main SQLite database (job queue, agents, marketplace). The file and its parent dir are created on demand. |
ICM_DB_PATH |
data/icm.db |
Dedicated SQLite database used by the icm CLI for agent long-term memory. |
AGENT_WORKDIR |
/tmp/takoia-agent-workspace |
Neutral working directory for the agent's claude -p subprocesses, deliberately outside the project git tree so the CLI does not pick up the host CLAUDE.md or trigger project-scoped ICM recall. |
| Variable | Default | Description |
|---|---|---|
ADMIN_USERNAME |
admin |
Username used only when seeding the admin from ADMIN_PASSWORD. |
ADMIN_PASSWORD |
(unset) | When set, seeds the admin account non-interactively at startup. When unset/empty (the default), no admin is created and the first-run setup wizard asks you to create one on first visit — no shared default password. |
| Variable | Default | Description |
|---|---|---|
BIND_ADDR |
127.0.0.1:8080 |
Address the HTTP server binds to. |
FRONTEND_DEV_ORIGIN |
http://localhost:5173 |
CORS origin allowed for the Vite dev server during hot-reload. Unused in a same-origin production build. |
| Variable | Default | Description |
|---|---|---|
DEFAULT_LLM_PROVIDER |
claude_max |
Provider used by the demo agent and as the default for new agents. |
CLAUDE_MAX_TOKEN |
(unset) | Optional Claude plan token from claude setup-token, passed to claude -p as CLAUDE_CODE_OAUTH_TOKEN so the agent consumes your plan instead of API credits. If unset, claude -p uses whatever login the claude CLI already has. |
Provider seeds. Providers are normally configured (and encrypted) from the
Settings UI. The variables below only seed the connectors table on first
boot, so the demo works without opening the UI. For each provider <NAME> in
{CLAUDE_MAX, OLLAMA, GEMINI, CODEX}:
| Variable | Description |
|---|---|
<NAME>_BASE_URL |
OpenAI-compatible base URL. A seed is created only if this is set. |
<NAME>_API_KEY |
API key (optional — e.g. local Ollama needs none). |
<NAME>_MODEL |
Default model id for that provider. |
The four logical providers are claude_max (Claude plan proxy), ollama
(local, offline-safe fallback), gemini, and codex.
| Variable | Default | Description |
|---|---|---|
DISCORD_WEBHOOK_URL |
(unset) | Optional Discord webhook for the send_discord notification tool. |
RUST_LOG |
takoia=debug,tower_http=debug,info |
Tracing filter. |
A ready-to-copy .env.example lives next to this README. Copy
it to .env, then set MASTER_KEY and ADMIN_PASSWORD:
# ── Required ────────────────────────────────────────────────────────────────
# 32 bytes, base64. Generate with: openssl rand -base64 32
MASTER_KEY=REPLACE_ME_WITH_openssl_rand_base64_32
# ── Auth ────────────────────────────────────────────────────────────────────
# Leave ADMIN_PASSWORD empty to create the admin via the first-run setup wizard
# (recommended). Set both to seed the admin non-interactively instead.
ADMIN_USERNAME=admin
ADMIN_PASSWORD=
# ── Server ──────────────────────────────────────────────────────────────────
BIND_ADDR=127.0.0.1:8080
FRONTEND_DEV_ORIGIN=http://localhost:5173
# ── Database & storage ──────────────────────────────────────────────────────
DATABASE_URL=sqlite://data/takoia.db?mode=rwc
ICM_DB_PATH=data/icm.db
AGENT_WORKDIR=/tmp/takoia-agent-workspace
# ── LLM providers ───────────────────────────────────────────────────────────
DEFAULT_LLM_PROVIDER=claude_max
# Optional Claude plan token (claude setup-token) -> CLAUDE_CODE_OAUTH_TOKEN.
CLAUDE_MAX_TOKEN=
# Seed connectors (only used on first boot if the connectors table is empty).
CLAUDE_MAX_BASE_URL=
CLAUDE_MAX_API_KEY=
CLAUDE_MAX_MODEL=
OLLAMA_BASE_URL=http://localhost:11434/v1
OLLAMA_API_KEY=
OLLAMA_MODEL=llama3.1
GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.0-flash
CODEX_BASE_URL=https://api.openai.com/v1
CODEX_API_KEY=
CODEX_MODEL=gpt-4o-mini
# ── Integrations & logging ──────────────────────────────────────────────────
DISCORD_WEBHOOK_URL=
RUST_LOG=takoia=debug,tower_http=debug,infoThere is no manual migration step: on startup the binary connects to
DATABASE_URL and runs all SQL migrations in migrations/ automatically
(db::migrate), then seeds a default account, providers, and demo agents on
first boot. The migrations are managed with sqlx; if you have the
sqlx CLI installed you can also run them
by hand with sqlx migrate run (against the same DATABASE_URL).
cargo run --release # or: make runThe server logs listening on BIND_ADDR (default 127.0.0.1:8080) and prints
the admin login. With a production frontend bundle present, it serves the app on
the same origin at http://localhost:8080.
For UI development, run Vite's dev server alongside the backend:
# both at once (backend auto-reload + frontend HMR):
make dev
# or in two terminals:
make dev-api # cargo watch -x run (backend on :8080)
make dev-web # bun run dev (Vite on :5173)Open http://localhost:5173. Vite proxies /api to the backend on :8080
(see frontend/vite.config.ts), so the browser sees a single same-origin app:
edit a .svelte file and the page updates instantly; edit Rust and cargo watch
recompiles and restarts the server.
- Dev: browser → Vite (
:5173) → proxy/api→ Axum (:8080). - Prod: browser → Axum (
:8080) serves both the static frontend and/api.
cargo test # or: make testOn a fresh instance, the first visit opens a setup wizard to create your admin
account. If you seeded one via ADMIN_PASSWORD, sign in with those credentials.
Create an agent and describe what expert it should be (its persona, the system
prompt, the allowed tools, and the autonomy level). You can also scaffold one
from a short description, or import/export an agent as TOML
(POST /api/agents/import, GET /api/agents/:id/export).
In the SvelteFlow builder, wire the four steps — Analyse → Decision → Action → Restitution. Per step you can pick the LLM provider, the tools, and whether the Decision step requires a human approval (human-in-the-loop) before the agent takes action. The agent recalls its ICM memory at the start of a run and persists what it learned at Restitution, so it improves with every objective.
Give the agent an objective (POST /api/objectives). It is enqueued as a job;
follow the live timeline over SSE at GET /api/jobs/:id/events.
Publish an agent (POST /api/agents/:id/publish) with a price per 1k output
tokens and a revenue share. It then appears in the marketplace
(GET /api/marketplace) and becomes callable over the hosted API.
Consumers create an API key (sk_…) and call the agent. The run is metered per
output token, the consumer is billed, and the publisher is credited their share.
The agent runs with read-only memory, so a caller can never pollute the
publisher's curated expertise.
curl -X POST http://localhost:8080/api/v1/agents/<AGENT_ID>/invoke \
-H "Authorization: Bearer sk_your_consumer_key" \
-H "Content-Type: application/json" \
-d '{"input": "Summarize this week in Rust async."}'Earnings are visible at GET /api/marketplace/earnings; usage at
GET /api/usage.
This is a hackathon / demo backend. Apart from the /api/login endpoint and
the marketplace invoke endpoint (/api/v1/agents/:id/invoke, which requires a
Bearer sk_… consumer key), the /api/* surface is currently
unauthenticated. Do not expose it directly to the public internet — front it
with proper authentication (a reverse proxy with auth, network isolation, etc.)
before deploying anywhere real. Connector credentials are encrypted at rest with
MASTER_KEY, so keep that key secret and back it up: losing it makes stored
credentials unrecoverable.
Connector / AI-tool secrets are stored through a pluggable backend, selected in Settings → Secret storage (admin only):
| Backend | Where secrets live | Requirement on the host |
|---|---|---|
local (default) |
encrypted in the DB with MASTER_KEY |
none |
vault |
HashiCorp Vault (KV v2) | vault CLI, addr + token |
azure |
Azure Key Vault | az CLI, authenticated; vault_name |
gcp |
GCP Secret Manager | gcloud CLI, authenticated; project |
aws |
AWS Secrets Manager | aws CLI, authenticated; region |
External backends are driven through their CLI (the same way the engine shells
out to claude / icm): the operator authenticates the CLI on the host (CLI
login or instance identity) and TakoIA only stores the locator (vault name,
project, region…). When an external backend is active, the DB keeps only an
encrypted reference (@ext/<name>) — the secret value lives in the vault.
Secrets are passed to the CLIs via a 0600 temp file, never on the command line.
For the secretless setup (managed / workload identity, no cloud credentials
stored in TakoIA) and the minimal IAM/RBAC per cloud, see
docs/secret-backends.md.
TakoIA core-backend is licensed under the Business Source License 1.1 (BSL
1.1) — see LICENSE. You may copy, modify and make non-production
use of the code freely. On the Change Date (2028-06-14) the license
automatically converts to the Apache License, Version 2.0.