Skip to content

Latest commit

Β 

History

1,890 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

EN Β· RU

Iva β€” self-hosted Telegram AI assistant with layered memory

Release License: MIT built on eve Node 24 Last release

Site Β· Use cases Β· Features Β· Install Β· Memory Β· What's new Β· Docs


Iva is a self-hosted Telegram AI assistant with layered memory that turns your messages into an Obsidian-compatible vault. You talk, it files: voice notes, photos, forwarded posts and decisions become plain-markdown cards it actually remembers. Everything runs on your own server, with your keys and your data.

One command installs it:

curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh | bash

Why people run Iva

  • "What did we agree with client X about the last shipment?" β€” found in seconds, months later.
  • A five-minute voice note from the car β†’ a task list, a draft email, a meeting card.
  • "Make a quote from this price list, cut the discount by 2.5%, send it to the client" β€” a finished Google Doc, link in the chat.

The rest β€” for business owners, specialists, executives and everyday life: Use cases.

How it works

How Iva works: voice, text, photos and PDFs fly from Telegram into the willow-tree agent, wired to memory, nightly rollup, cron, reminders, search, web, workspace and docs

The bridge long-polls Telegram, so no public HTTPS, domain or webhook is needed. Iva runs as two systemd user services, two systemd watchdog timers and seven in-process eve schedules β€” operations live in docs/deploy.md.

Wondering what you'd actually use an agent for? β†’ 25+ real scenarios β€” business, work, everyday life.

What people ask Iva: eight everyday requests, from a voice note turned into tasks to research with sources and a bedtime story that continues tomorrow

Features

Voice, vision, memory, personal CRM, Google Workspace, skills β€” expand the full list
  • Voice β€” voice, audio and video notes transcribed with Deepgram nova-3; auto-detects ru/uz/en.
  • Vision β€” photos described by your provider's own vision model; no extra key, no extra bill.
  • Rich replies β€” tables, checklists, collapsible blocks and formulas render natively in Telegram via Bot API 10.1 rich messages; plain formatting keeps its proven path, with a graceful fallback.
  • Quiet update checks β€” once a day Iva checks for a newer stable release without spending model tokens. If one exists, Telegram offers Update or Later once; otherwise it says nothing.
  • Layered memory β€” remembers across months, long after the chat window has scrolled away.
  • Personal CRM β€” who your people are, what you agreed, when to follow up.
  • Search by meaning β€” BM25 plus link-graph rerank, any language; optional vector mode with one key.
  • Decision cards β€” what you chose, when and why; old versions stay in a dated History.
  • Tasks & reminders β€” priorities, due dates and a morning digest.
  • Web search β€” four pluggable providers: Tavily, Exa, Parallel or Brave.
  • Google Workspace β€” Gmail, Calendar, Drive, Sheets, Docs and Tasks from chat via the gws CLI; installed for you, with a guided key setup right in the conversation.
  • Skills & MCP β€” drop one file to add a procedure or connect an MCP server; keys stay in .env.
  • Personal Telegram β€” userbot (beta) β€” read and send from your own account, not just the bot; connect by chat (QR, no terminal). Rough and buggy β€” opt-in, at your own risk. A server-side anti-ban guardrail (FloodWait compliance + randomized pacing + circuit-breaker) is enforced, not just advised. Details.
  • Safe to forward β€” forwarded text, captions and voice transcripts pass an injection screen before the model reads them. A flagged message or transcript reaches the model tagged as data rather than as an instruction; for media captions the screen runs but the tag does not travel with it yet.
  • Token accounting β€” every model step is logged; /usage reports it for free.

The Memory Tree

How Iva remembers: a leaf is a day, branches are weeks and months, tree rings are years around CORE.md

Layer What lives there Path
πŸƒ Leaves the word-for-word transcript of each day, Iva's replies included daily/YYYY-MM-DD.md
🌿 Branches summaries folded upward: day β†’ week β†’ month β†’ year summaries/daily/, weekly/, monthly/, yearly/
πŸͺ΅ Trunk CORE.md (≀1200 chars, in every prompt) + typed cards: contacts, projects, decisions, ideas, notes CORE.md, cards/
  • Every message lands verbatim in a daily markdown log β€” nothing is paraphrased on arrival.
  • A nightly rollup at 04:00 distills day β†’ week β†’ month β†’ year into schema-validated cards; facts that change get rewritten, not piled up.
  • One core file, CORE.md (≀1,200 chars), rides in every prompt β€” Iva knows you before it searches anything.

Full architecture and search internals: docs/memory.md.

A secretary inside Telegram

Your secretary inside Telegram: the userbot reads group chats from your own account, collects summaries and replies as you, guarded by a server-enforced anti-ban guardrail

The bot is half of Telegram. The other half is your personal account: connect the userbot (beta, opt-in) and Iva works from it like a secretary β€” reads the group chats you never keep up with, folds them into summaries, catches the messages that actually need you, and replies as you.

  • All of Telegram β€” groups, channels, unreads, search and the full history of your personal account.
  • Onboarding in chat β€” tell the bot to connect your Telegram, scan a QR. No terminal.
  • Anti-ban guardrail on the server β€” FloodWait compliance, a randomized delay after every send, and a circuit-breaker that pauses sending after three FloodWaits in 24 hours. It is enforced in the proxy rather than asked for in a prompt, and it wraps the three outbound calls that actually get accounts flagged: messages, files, forwards. Joins, invites, contact imports and reactions are not wrapped β€” those limits live in the skill file, which is a prompt.
  • Read-only mode β€” one .env switch and Iva can read and search but physically cannot send.

Warning

Automating a personal account is against Telegram's ToS and can get the account limited or banned. The userbot is opt-in, beta, and used at your own risk β€” reading is far safer than sending. Details: docs/userbot.md.

Security & privacy

Untrusted input from Telegram and the web passes the security gate: corrupted messages drop into the reject tray, only clean context reaches the vault

Web pages, search results, voice transcripts, captions and the vision model's description of a picture reach the model only through a prompt-injection sanitizer. On a forwarded text message the same gate annotates the turn with a warning instead of filtering the text, and document bodies, userbot-read chats and agent-browser output are not screened at all. Everything that leaves through the Outbox passes a secret-redaction gate, and the user allowlist fails closed β€” an empty list answers nobody. Your memory is a private git repo you own; the honest boundary is that the model and transcription are cloud APIs you choose and pay for. Gate internals and the full boundary: docs/security.md.

Install

One command on any Ubuntu/Debian box β€” a fresh VPS or your own machine:

curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh | bash
  1. Get a bot token from @BotFather.
  2. Run the installer and answer its questions.
  3. Message your bot. The wizard picks your Telegram ID out of that message, finishes setup, and Iva confirms right in the chat that it's live.

Brand-new VPS, still logged in as root? Run bash <(curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/bootstrap.sh) first: it creates your sudo user (with lingering enabled), updates the box, and turns on a firewall, fail2ban and SSH hardening. It asks three things β€” a login, its password, and the timezone β€” and no SSH key. Then log in as that user with that password and run the installer above. Details: docs/install.md.

Install as a normal user, not as root β€” Iva's shell tool runs as whoever installed it. Headless installs take --skip-setup or --non-interactive. Prefer to read before you run? Fetch it with curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh -o install.sh, read it, then bash install.sh. Wizard walkthrough and an SSH primer for first-time VPS owners: docs/install.md.

The first minute

Three messages, and you can watch the memory work:

  1. Send a voice note about your day β€” anything, out loud. Then look in daily/ inside your vault on the server: your words are sitting there in plain markdown, dated, yours. No other assistant hands you the file.
  2. Tell it something a colleague would remember: Marina at Acme wants the revised quote by Friday β€” she never picks up the phone.
  3. Ask for it back the way a person would: how should I follow up with Marina? β€” the answer comes from the card Iva just wrote, not from the last few messages.

Then send a photo of a business card, or forward a long post and ask for the gist. /menu has the rest; the full list is in 25+ scenarios.

Install from a clone β€” build it yourself
git clone https://github.com/smixs/iva-agent.git ~/iva
cd ~/iva && bash install.sh

The installer reuses the existing checkout instead of re-cloning, keeps .env and the vault untouched, and installs the same dependencies. A fork or a branch works through variables read at startup: REPO_URL=…, BRANCH=…, INSTALL_DIR=… (defaults: this repo, main, ~/iva). Details: docs/install.md.

Providers & cost

Five model providers. Pick one and fill its block in .env:

Provider How you pay
OpenCode Go API key, ~$10/mo ($5 first month)
Ollama Cloud API key, ~$20/mo
OpenRouter API key, pay-as-you-go, 300+ models
OpenAI (ChatGPT) your Plus/Pro subscription, no API key
Custom your own OpenAI-compatible endpoint

Default model is deepseek-v4-pro, 131k context. On Go it runs about $14–15/mo all-in ($10 model + $4–5 VPS; the model's first month is $5), no markup; voice rides Deepgram's free starter credit. Model lists, limits and the search matrix: docs/providers.md.

Documentation

Use cases Β· Install Β· Configuration Β· Memory Β· Providers Β· Security Β· Deploy Β· Commands & CLI Β· Menu Β· Reminders Β· Extending Β· Plugins Β· FAQ Β· Troubleshooting

ДокумСнтация Π½Π° русском β†’ docs/ru/

What's New

v0.4.4 Β· 17.09.2026 β€” expand the latest releases

17.09.2026

v0.4.4

  • ⏰ A reminder is an instruction Iva gives her future self: at the due minute the text of the reminder is the prompt of one fresh turn with tools, not a line to read back β€” "in 3 minutes find the news and send it" arrives as the news, not as its own wording. A turn that could not run, failed or came back empty still delivers: the code sends your text verbatim and names the cause in the row.
  • ⏰ A reminder comes back to the chat it was asked in: the row remembers the chat and the topic of the turn, so a reminder set in a group topic lands in that topic instead of a private chat; old rows and requests that did not come from Telegram still go to the owner's chat. iva doctor stopped claiming "the dispatcher has not ticked yet" β€” it was reading the pulse from the wrong folder.
  • πŸ” /update --force works from the chat too: the word after /update is read now, so the running build can be rebuilt from Telegram exactly as iva update --force does on the server β€” the way out of a broken edit in Iva's own code. The flag travels in the request file, so a restarted update rebuilds as well.
  • 🩺 The doctor names the cure for stuck workflows: "running count 7 exceeds 5" now says in the same line that such runs are stale rather than live, and that iva reset quarantines them and restarts the services; memory is left alone.

14.09.2026

v0.4.3

  • πŸ” One updater, the way pi does it: the old in-place update path (stash and rebase inside the working folder with a byte-level check of stray files, ~15k lines) is gone together with the guesswork "developer or installation" by branches and shims that kept people with a second branch on the fragile path forever. Every Iva folder now updates through versions: build beside, probe, switch, roll back. A developer checkout is marked with an empty .iva-dev file. Edits to Iva's own code are no longer promised or kept β€” your own skills, tools and plugins live in data/custom. repair.sh and a re-run of install.sh hand an existing installation to the same updater. An update cut off mid-way (a server reboot) is restarted once by the bridge itself with a line in the chat. Older flat installs need two /updates: the first fetches the new code, the second moves onto versions.
  • πŸ”˜ Menu buttons two per row again: the classic menu lays buttons out in pairs as before 0.4.2; the new rich menu shows the same pairs as compact pills with a "button β€” what it does" caption under the row, no more one long full-width button.
  • πŸ”Œ A tool schema the provider rejects no longer kills the turn: OpenAI (codex) rejects the whole request when any tool carries a regex with lookaround; Iva now retries once without those patterns, and if it still fails, the error names the field and where the tool lives.
  • 🧷 Codex tools without strict mode: tools go to codex with strict: false, so optional fields stay optional and reminders are set on the first call instead of looping.
  • 🧰 diagnose.sh collects more: the plugin list, the reminder dispatcher pulse and the schedule lines of the last day.

13.09.2026

v0.4.2

  • 🎀 The voice key is no longer required at install: the Deepgram step of the wizard is skipped with Enter (console.deepgram.com does not open from some countries, and people got stuck on install for an optional feature); without the key voice notes are saved and Iva suggests /menu β†’ 🎀 Voice, and iva doctor shows a warning instead of a failure.
  • πŸ”˜ A new menu, on request: buttons inside the message: by default the menu, the /model and /think wizards, the update offer and the "Working" status look as before (a message with buttons under it); /menu β†’ Maintenance β†’ ✨ New menu switches them to Telegram rich messages β€” every button a full-width row with what it does right under it, headings, status and timers as tables, and β—€οΈŽ Classic menu at the bottom brings the old look back. Iva also offers buttons in her own replies when there are two to four options, and a tap comes back to her as your message; the rich-replies skill covers the whole palette. The new menu needs a Telegram client from August 2026; in groups the reply buttons don't work. ADR-0015
  • πŸ’¬ Rich replies and voice are set from the menu: two new /menu screens β€” a switch for rich replies (Auto: tables, task lists, folds and formulas go as rich messages; Plain text: ordinary messages) and 🎀 Voice with the Deepgram key and the recognition language (Auto/Русский/English/OΚ»zbek); the key is taken from your next message in a private chat and deleted from the chat, and both screens offer a restart after saving.
  • πŸ“¦ Dependencies cleaned up: the unused @vercel/connect is gone, fast-uri, hono and qs under @modelcontextprotocol/sdk are bumped past their vulnerabilities (npm audit: 0 high, 0 moderate), and the ai pin is lifted to ^7.0.82, the peer eve 0.51.1 requires.

v0.4.1

  • ⏰ A reminder is an instruction Iva gives her future self: a data/ row moves "pending β†’ fired" in one atomic transition, and at the due minute the text of the reminder is the prompt of one fresh turn β€” Iva does what it says with her tools and the code sends the final text of that turn back to the chat and topic you asked in, so "in 3 minutes find the news and send it" arrives as the news, not as its own wording. A turn that could not run, failed or came back empty still delivers: the code sends your text verbatim and names the cause in the row. The firing fact (fired_at, delivered, error) sits in the row, iva doctor shows it, and rows from the old schema survive the update.
  • πŸ”” One remind tool with add, list, remove: one-off reminders ("in 30 minutes", "at 14:30") and repeating ones (a cron expression in your time zone) are set, listed and removed by a single tool with an action field instead of three. The moment is computed in code and handed to the agent as a ready time, schedules firing more often than every 10 minutes are refused, and the destination is always your chat. ADR-0013
  • πŸ›‘ bash cannot set timers of its own or talk to Telegram anymore: systemd-run, writing crontab, at/batch, units under ~/.config/systemd/user, ~/.iva-scripts, sleep chains and direct calls to api.telegram.org are refused before they run, and the refusal names the replacement; reading (crontab -l, systemctl status, journalctl) still passes.
  • πŸ“‹ Every schedule run leaves a fact, and the agent wakes up with it: each run writes a row to data/jobs.json (reason, exit code, secret-free tail, kept seven days). On success Iva stays silent; on failure she fixes the cause and tells the owner, open failures are visible to every turn and in iva doctor and close on the next success or with iva jobs ack <name>, and if the agent cannot wake at all, one message a day reaches you. A wake turn that ended by waiting for the next message is a normal end now, not a failure. The schedules section of iva doctor works without systemd.
  • πŸ”Ž A complaint turns into an evidence bundle with no secrets in it: iva diagnose puts versions, OS and node, the iva doctor output, the last 200 service log lines, reminder and turn-failure facts and the schedule table into data/diagnose/<date>.md, cutting the values of every .env key except settings, plus the bot token, owner chat id and e-mail; the report-problem skill reads the bundle, explains the failure in two lines and offers a ready issue link or a message for the support group.
  • 🧹 An interrupted update cleans up after itself and names the reason: the retiring checkout wears a marker with its own identity, deletes .git last and finishes on a repeat; stale shim-refresh claims in ~/.local/bin are swept by age even under a live pid; a failed optional step now logs its exit code and the last output line (for example exit 127: uv: command not found) instead of a silent "… did not run".
  • 🧩 Your rules live beside the bundled persona and load every turn: markdown files in data/custom/agent/instructions/ reach the prompt live without a rebuild, so a behavior rule written into rules.md (with write_file, after your confirmation) works at once; the old instructions.md replacement is obsolete, and iva doctor shows the rule count and warns when it overruns the limit.
  • 🧭 The vault directory is computed by one formula everywhere: file tools, media, the diary, nightly memory, the CLI, the menu, the build and the installer call a single resolver. An empty value or stray spaces is now a clear error naming the variable instead of a silent directory swap, a relative path resolves against the caller's base, and a bad setting reaches the user as one line, not a stack trace.
  • 🧩 Iva runs on eve 0.51.1 (0.4.0 shipped 0.47.3): the local patch is ported and rebuilt for the new runtime.

Full history β€” CHANGELOG.md.

Built on

eve 0.51.1, Vercel's agent framework, runs the agent; Node 24's built-in SQLite runs the search index β€” no separate database. Iva grew out of agent-second-brain and autograph β€” that story is in docs/memory.md.

Thanks

Iva gets better because people run it for real β€” contributors are welcome. Open an issue with what breaks, or send a PR. Everyone who already helped: docs/thanks.md.

License

MIT β€” take it, change it, run it on a hundred servers; just don't blame anyone if something breaks.

Releases

Packages

Contributors

Languages