Skip to content

agheieff/ai-chat

Repository files navigation

AI Chat

Async, streaming AI chat with OpenRouter backend, CLI and Telegram interfaces, prompt assembly, and simple command system.

Features

  • Streaming responses with optional reasoning blocks
  • Per-session history and automatic context trimming
  • Slash commands for chat control (/model, /save, /system, ...)
  • Token usage and cost display
  • Prompt parts assembled from prompts/
  • Auto-saves each conversation as JSON (per message)
    • Files are organized by month (./saves/conversations/YYYY-MM/)
    • New conversations are named from the first user message (slug + timestamp)

Requirements

  • Python 3.9+
  • OpenRouter API key (OPENROUTER_API_KEY)
  • Optional: Telegram bot token (TG_BOT_TOKEN) for Telegram interface
  • Optional: OpenAI API key (OPENAI_API_KEY) for voice transcription

Install

From the ai-chat directory:

pip install -r requirements.txt

This installs local libs via editable paths: libs/openrouter, libs/cli_loop, libs/telegram_mini.

Configure

Create .env (see .env.example):

OPENROUTER_API_KEY=sk-or-...
# TG_BOT_TOKEN=123456:abcdef...
# OPENAI_API_KEY=sk-openai-...

# Optional overrides
# AI_CHAT_MODELS_FILE=models.txt
# AI_CHAT_SAVE_DIR=./saves
# AI_CHAT_CONVERSATIONS_DIR=./saves/conversations
# AI_CHAT_DEFAULT_MODEL=0
# AI_CHAT_MAX_CONTEXT=128000
# AI_CHAT_MAX_NEW=32768

Models are read from models.txt (one per line). Example entries:

qwen/qwen3-max
anthropic/claude-sonnet-4.5
openai/gpt-5

Prompts

Assemble your system prompt from parts listed in prompts/index.yaml:

parts:
  - parts/meta.md
  - parts/coding/style.md

Place the files under prompts/parts/. If index.yaml is missing or empty, no system prompt is used.

Run

CLI:

python run_cli.py

On startup, the CLI shows either the current autosave file (if one is active) or the autosave directory for the current month, so you always know where conversations are being written.

Telegram bot (requires TG_BOT_TOKEN):

python run_telegram.py

Unified runner (Web + Telegram):

python run_app.py           # runs web + bot (bot only if TG_BOT_TOKEN set)
python run_app.py --web     # only web
python run_app.py --bot     # only telegram

Web (with reload, dev):

python run_web.py           # uvicorn with reload, binds 0.0.0.0:8080

LAN access: the server binds 0.0.0.0 so it’s reachable via your local IP, e.g. http://192.168.x.x:8080.

Web API (experimental):

uvicorn web.server:app --reload --port 8080

Web UI (htmx):

  • Visit http://localhost:8080/ui (or just /). Minimal file browser + chat panel using htmx.
  • Set the working directory from the Files panel (“Use This Directory”).
  • Send messages from the Chat panel; conversations autosave to your workspace.

E2E Test Script:

python scripts/test_web_api.py
  • Runs the API + UI end-to-end in-process (no Uvicorn needed).
  • Uses a temporary save dir under .e2e_tmp.
  • Covers signup/login, profiles, file ops, set working dir, chat send, and autosave JSON checks.

Endpoints (cookie sessions):

  • POST /auth/signup – { email, password, username? } → sets session cookie, returns { account, csrf }
  • POST /auth/login – { email, password } → sets session cookie, returns { account, csrf }
  • POST /auth/logout – clears session cookie
  • GET /auth/me – returns account, profiles, active profile
  • GET /profiles – list profiles
  • POST /profiles – create profile { name } (requires X-CSRF-Token)
  • POST /profiles/select – activate a profile { slug } (requires X-CSRF-Token)
  • GET /files/list?path=… – list files within the current workspace (account root or active profile root)
  • POST /files/mkdir – create a directory { path } (requires X-CSRF-Token)

Notes

  • Account directories are created under AI_CHAT_ACCOUNTS_DIR with conversations/, prompts/, attachments/.
  • Profiles (optional) are created under accounts/<account>/profiles/<profile>/... with the same subfolders.
  • Use /auth/me to retrieve the CSRF token after login/signup and pass it via X-CSRF-Token on mutating requests.

Telegram Linking

  • Open the web UI → Profile → “Generate Link Code”.
  • In Telegram, send /link <code> to the bot (or tap the deep link).
  • The bot links your Telegram account (user_id + username) to that profile.
  • Only linked users can chat; others receive instructions to link.

Optionally set TG_BOT_USERNAME to render the deep-link URL.

Reset Local Data

To wipe local DB and user data, run:

scripts/clear_data.sh --yes

Accounts (User Directories)

Create simple per-user directories where users can keep files (auth and schemas will come later):

  • /account create <name> — Creates a new account directory under AI_CHAT_ACCOUNTS_DIR (defaults to ./saves/accounts). Names are slugged for safety.
  • /account list — Lists existing account directories.

Environment override:

# Where to store user account directories
# AI_CHAT_ACCOUNTS_DIR=./saves/accounts

Notes

  • Telegram: conversations are automatically autosaved under the sender’s account dir (slug from username or user-<id>), in the conversations/YYYY-MM/ subfolder.
  • This is just a directory structure; no auth or schema enforcement yet.
  • You can manage files under these directories however you like; future tooling may build on top of this.

Commands

  • /new — Start a fresh chat
  • /save [name] — Save conversation
  • /model — Show active model
  • /model list — List models
  • /model <num|id> — Switch model
  • /system — Reload system prompt
  • /thinking — Toggle reasoning generation
  • /show_thinking — Toggle display of reasoning
  • /stream — Toggle streaming
  • /config — Show effective config and session state
  • /help — Show help
  • /quit — Exit CLI

SSH Gateway (optional)

Expose an SSH shell that attaches to each account’s containerized workspace (Phase 3). Recommended setup uses a single gateway OS user and per‑account public keys.

Prerequisites

  • Container runtime available (docker or podman)
  • Workspace feature enabled for the account(s)

App env

AI_CHAT_SSH_ENABLED=1
AI_CHAT_SSH_GATEWAY_USER=aiacct            # gateway OS user
AI_CHAT_VM_RUNTIME=docker                  # or podman
AI_CHAT_VM_IMAGE=ubuntu:22.04              # any image with bash

Install scripts (as root)

install -m0755 -o root -g root scripts/ssh_authorized_keys.py /usr/local/bin/ssh_authorized_keys
install -m0755 -o root -g root scripts/ssh_bridge.py          /usr/local/bin/ssh_bridge
useradd -r -m -s /usr/bin/nologin aiacct || true
ssh-keygen -A   # ensure host keys exist

sshd_config (single gateway user — recommended)

AuthorizedKeysCommand /usr/local/bin/ssh_authorized_keys
AuthorizedKeysCommandUser root
PermitUserEnvironment yes

Match User aiacct
  ForceCommand /usr/local/bin/ssh_bridge
  PermitTTY yes
  AllowTcpForwarding no
  X11Forwarding no
  PermitTunnel no

Provide env to sshd via systemd drop‑in

mkdir -p /etc/systemd/system/sshd.service.d
cat >/etc/systemd/system/sshd.service.d/override.conf <<'EOF'
[Service]
Environment=AI_CHAT_SSH_ENABLED=1
Environment=AI_CHAT_SSH_GATEWAY_USER=aiacct
EOF
systemctl daemon-reload
sshd -t && systemctl restart sshd

Add a key and connect

python -m ai-chat.scripts.ssh_keys add --account-id 1 --name laptop --file ~/.ssh/id_ed25519.pub
ssh aiacct@<host>

Local test without touching your main sshd

# Write a minimal test config (port 2222, loopback only)
cat >~/sshd_test_config <<'EOF'
Port 2222
ListenAddress 127.0.0.1
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
AuthorizedKeysCommand /usr/local/bin/ssh_authorized_keys
AuthorizedKeysCommandUser root
PermitUserEnvironment yes
PidFile /tmp/sshd_test.pid
Match User aiacct
  ForceCommand /usr/local/bin/ssh_bridge
  PermitTTY yes
  AllowTcpForwarding no
  X11Forwarding no
  PermitTunnel no
EOF
sudo sshd -f ~/sshd_test_config -D -e   # or run in another terminal without -D
# then from a new terminal:
ssh -p 2222 aiacct@127.0.0.1

Notes

  • If you see “no hostkeys available”, run sudo ssh-keygen -A.
  • Ensure the script paths are absolute and executable by root (0755).
  • For per‑account OS users instead of a single gateway user, use Match User aiacct_* and omit AI_CHAT_SSH_GATEWAY_USER.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors