> For the complete documentation index, see [llms.txt](https://docs.volaris.games/volsai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.volaris.games/volsai/linkolnos/documentation.md).

# Documentation

🔗 [\[GitHub Repository\]](https://github.com/VolarisGames/LinkolnOS)

> Open-source launchpad for deploying real-time, knowledge-aware AI agents on Telegram.

LinkolnOS lets you spin up a Telegram bot that fetches live content from websites you control, talks to an OpenAI model, and remembers the conversation. Admins manage the knowledge base from inside Telegram — no dashboard required.

[![CI](https://github.com/VolarisAI/LinkolnOS/actions/workflows/ci.yml/badge.svg)](https://github.com/VolarisAI/LinkolnOS/actions/workflows/ci.yml) [![License: MIT](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667) [![Node](https://camo.githubusercontent.com/8f0aa01709dafbe9f00aba61e321d4549bf3de348f23e14f1df46fd6edc2c69b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334431382d627269676874677265656e2e737667)](https://camo.githubusercontent.com/8f0aa01709dafbe9f00aba61e321d4549bf3de348f23e14f1df46fd6edc2c69b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334431382d627269676874677265656e2e737667) [![Status: beta](https://camo.githubusercontent.com/1651d68ef49a0de0fabf4e2f1059528b04e2a7f0bfdf09fd1ede41a56653fe08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374617475732d626574612d79656c6c6f772e737667)](https://camo.githubusercontent.com/1651d68ef49a0de0fabf4e2f1059528b04e2a7f0bfdf09fd1ede41a56653fe08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374617475732d626574612d79656c6c6f772e737667)

***

### Features

* **Telegram-native** — users chat directly in Telegram, no extra app
* **Live website crawling** — bot pulls fresh content per query (axios + cheerio)
* **Per-project knowledge bases** — admins add/remove source URLs via bot commands
* **OpenAI-backed responses** — configurable model, temperature, and token budget
* **Persisted state** — projects, admin passwords, websites, and conversation history all in Postgres (survives restarts)
* **Polling or webhook mode** — polling auto-enabled for local dev (no tunnel needed); webhook mode for production
* **Two access modes** — Admin mode (manage knowledge) and User mode (ask questions)
* **Customizable personality** — edit `personality.json` to change tone and capabilities

***

### Requirements

* **Node.js ≥ 18**
* **PostgreSQL** running locally or remotely (any recent version)
* **Telegram bot token** — get one from [@BotFather](https://t.me/BotFather)
* **OpenAI API key** — from [platform.openai.com](https://platform.openai.com/api-keys)
* **A public HTTPS URL** — *only required for webhook (production) mode*. Local dev runs in polling mode automatically.

***

### Quickstart (local dev, polling mode)

```
# 1. Clone & install
git clone https://github.com/VolarisAI/LinkolnOS.git
cd LinkolnOS
npm install

# 2. Configure
cp .env.example .env
# Edit .env: TELEGRAM_BOT_TOKEN, OPENAI_API_KEY, ADMIN_PASSWORD, DB_* values.
# Leave WEBHOOK_URL blank to run in polling mode (no tunnel needed).

# 3. Make sure Postgres is reachable with the credentials in .env.
#    LinkolnOS auto-creates its tables on first run.

# 4. Start
npm start
```

If anything is missing from `.env`, the app exits with a friendly list of what to fix.

Once running, open your bot in Telegram and send `/start` to create your first project.

#### Running tests

```
npm test
```

***

### Configuration

All configuration lives in `.env`. See [`.env.example`](https://github.com/VolarisAI/LinkolnOS/blob/master/.env.example) for the canonical list.

| Variable                                                      | Required | Default       | Purpose                                                                                                                     |
| ------------------------------------------------------------- | -------- | ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `TELEGRAM_BOT_TOKEN`                                          | ✅        | —             | From @BotFather                                                                                                             |
| `ADMIN_PASSWORD`                                              | ✅        | —             | Password admins type to unlock admin commands                                                                               |
| `OPENAI_API_KEY`                                              | ✅        | —             | Your OpenAI API key                                                                                                         |
| `OPENAI_MODEL`                                                | ⬜        | `gpt-4o-mini` | Any chat-completions model                                                                                                  |
| `OPENAI_MAX_TOKENS`                                           | ⬜        | `500`         | Max response length                                                                                                         |
| `OPENAI_TEMPERATURE`                                          | ⬜        | `0.9`         | 0.0 = deterministic, 2.0 = wild                                                                                             |
| `DB_USER` / `DB_HOST` / `DB_NAME` / `DB_PASSWORD` / `DB_PORT` | ✅        | —             | Postgres connection                                                                                                         |
| `DB_SSL`                                                      | ⬜        | `false`       | Set `true` for hosted Postgres that requires SSL (Render, Heroku, Supabase). Leave `false` for local Postgres.              |
| `WEBHOOK_URL`                                                 | ⬜        | —             | Public HTTPS URL (e.g. `https://yourapp.onrender.com`). **Leave blank for polling mode.** Set it to switch to webhook mode. |
| `PORT`                                                        | ⬜        | `3000`        | HTTP port for the webhook server (only used in webhook mode)                                                                |
| `MAX_WEBSITES`                                                | ⬜        | `50`          | Per-project URL limit (documented; not enforced yet)                                                                        |

***

### Architecture

```
                  ┌──────────────┐
   Telegram ──►   │   app.js     │  ──►  Polling (dev)  OR  Express webhook (prod)
                  │  (router)    │
                  └──┬───────────┘
                     │
       ┌─────────────┼─────────────────────────────┐
       ▼             ▼                             ▼
  commands/      crawler.js                     llm.js
  (admin +       (axios + cheerio,              (OpenAI client,
   user verbs)    pulls live page content)       personality.json)
       │             │                             │
       └─────────────┴───► stateManager.js
                            (in-memory cache, write-through to Postgres)
                                  │
                                  ▼
                              db.js (Postgres — projects + conversation history)
```

**Key files:**

* `app.js` — entry point, mode detection (polling vs webhook), top-level message routing
* `commands/` — admin + user command handlers
* `crawler.js` — website fetching and content extraction
* `llm.js` — OpenAI chat-completions integration and personality loading
* `stateManager.js` — read-through cache backed by Postgres; sync reads, async writes
* `db.js` — Postgres schema (projects + conversations) and pool
* `personality.json` — bot's name, bio, capabilities (editable)
* `test/` — unit tests run via Node's built-in `node:test`
* `.github/workflows/ci.yml` — runs lint + tests on Node 18, 20, 22 for every PR

***

### Deployment

**Local development** — polling mode is automatic when `WEBHOOK_URL` is unset. Just run `npm start`.

**Production** — set `WEBHOOK_URL` to a public HTTPS URL and the bot switches to webhook mode. Recommended hosts:

* **Render**, **Railway**, **Fly.io** — set `WEBHOOK_URL` to your service URL; the bot binds to `$PORT` (Render sets this automatically)
* **AWS / GCP / your own VPS** — terminate TLS in front of the Node process
* **Local "production-like" testing** — use [ngrok](https://ngrok.com/) or [cloudflared](https://github.com/cloudflare/cloudflared) to expose `http://localhost:3000` and put that URL in `WEBHOOK_URL`

Use a process manager (PM2, systemd, your platform's restart policy) so the bot recovers from crashes. The app handles `SIGTERM`/`SIGINT` gracefully — webhook is removed from Telegram and Postgres pool is closed before exit.

***

### Usage

Inside Telegram:

* `/start` — Creates a new project (first time) or resumes your existing one
* `/start <projectName>` — Deep-link into someone else's project as a user
* `/help` — Show command reference
* **For Admin** button → enter `ADMIN_PASSWORD` → manage websites, change password, delete the agent
* **Restart Conversation** button — clears your conversation history

***

### Known Limitations

Be honest with yourself before deploying this in production:

* **Shared admin password per project.** No per-user admin auth — anyone with the password is admin.
* **Every user message re-crawls every URL.** No caching. If a project has 5 sites × 3 subpages each, that's 20 HTTP fetches per Telegram message. Slow + bandwidth-heavy + may hit rate limits on the source sites. Caching is on the roadmap.
* **Keyword filtering before LLM is naive substring matching.** Works for simple queries; misses paraphrases. Vector search would be a real improvement.
* **No file-upload support.** Knowledge base is web pages only — no PDF, CSV, DOCX yet.

***

### Roadmap

* [x] &#x20;~~Persist `stateManager` to Postgres so projects survive restarts~~ ✅ (Phase 3)
* [x] &#x20;~~Optional polling mode for local development~~ ✅ (Phase 3)
* [x] &#x20;~~Smoke tests + CI on PRs~~ ✅ (Phase 3)
* [x] &#x20;~~Proper chat-completions messages array (instead of flattened string)~~ ✅ (Phase 3)
* [ ] &#x20;In-memory crawler cache (5-min TTL) to cut latency and OpenAI token cost
* [ ] &#x20;Per-user admin roles instead of shared password
* [ ] &#x20;File-upload support (PDF, CSV, DOCX) for the knowledge base
* [ ] &#x20;Vector embeddings + similarity search instead of keyword substring match
* [ ] &#x20;Structured logging (Winston / Pino)
* [ ] &#x20;Rate limiting per chat ID
* [ ] &#x20;ESLint + Prettier configuration

***

### Contributing

PRs welcome. See [CONTRIBUTING.md](https://github.com/VolarisAI/LinkolnOS/blob/master/CONTRIBUTING.md) for setup, branch naming, and review expectations.

Security issues: please follow [SECURITY.md](https://github.com/VolarisAI/LinkolnOS/blob/master/SECURITY.md) — don't open a public issue.

***

### License

[MIT](https://github.com/VolarisAI/LinkolnOS/blob/master/LICENSE) © 2026 Volaris Games

The MIT license requires attribution: if you ship code derived from LinkolnOS, please keep the copyright notice in the source. A mention in your README is appreciated but not legally required.

***

### Acknowledgements

* [OpenAI](https://openai.com/) for the LLM
* [`node-telegram-bot-api`](https://github.com/yagop/node-telegram-bot-api) for the Telegram integration
* [Cheerio](https://cheerio.js.org/) + [Axios](https://axios-http.com/) for the crawler
* [PostgreSQL](https://www.postgresql.org/) for persistence

#### Enjoy building with LinkolnOS!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.volaris.games/volsai/linkolnos/documentation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
