Metadata-Version: 2.5
Name: urok
Version: 0.1.0
Summary: Консольный помощник для учёбы: объясняет темы, проверяет домашку, помогает разобраться
License: MIT
Keywords: chat,cli,homework,ollama,study
Classifier: Environment :: Console
Classifier: Intended Audience :: Education
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# urok

Консольный помощник для учёбы. Объясняет темы, проверяет домашку, помогает
разобраться в том, что не понял.

Работает сразу после установки: бэкенд — OpenCode Zen, модель
`space-bunny-free`, ключ `public`. Ничего настраивать не нужно, ключ не нужен.

Ноль зависимостей — только стандартная библиотека Python.

## Установка

```bash
pip install .
```

После установки в любой папке работает команда `urok`.

## Запуск под конкретный урок

```bash
urok --grade 9 --subject физика
```

Модель сразу настроится на девятый класс и физику. Можно менять на лету: `/system`.

## Команды

| Команда | Что делает |
| --- | --- |
| `/help` | список команд |
| `/exit` | выйти, Ctrl+D тоже |
| `/clear` | забыть текущий диалог |
| `/model` | какая модель сейчас |
| `/model имя` | переключить модель прямо сейчас |
| `/models` | список моделей на сервере |
| `/base` | адрес сервера |
| `/base адрес` | сменить сервер |
| `/system` | показать или сменить системный промпт |
| `/wipe` | удалить всю сохранённую историю |
| `/load` | продолжить прошлую сессию (нужен `--keep-history`) |
| `/sessions` | список сохранённых сессий |
| `/copy` | скопировать последний ответ в буфер (Windows) |

Ctrl+C во время ответа прерывает только этот ответ — диалог остаётся.

## История по умолчанию не пишется

Закрыл консоль — на диске ничего не осталось. Проверено: папка `~/.urok` не
создаётся вообще, даже `mkdir` не вызывается. При выходе печатается проверка:

```
на диск ничего не записано, следов нет
```

Если папка всё же есть от прошлых запусков с `--keep-history` — выход скажет
об этом прямо и предложит `/wipe`.

Запомнить диалог между запусками:

```bash
urok --keep-history
```

Тогда история пишется в `~/.urok/session-ГГГГММДД-ЧЧММСС.json`, продолжить —
`urok --keep-history --load 1`.

## Что остаётся на диске помимо истории

Честно, чтобы не было сюрпризов. Пакет убирает за собой только историю диалога.
Это остаётся и находится вне его досягаемости:

| След | Где | Как убрать |
| --- | --- | --- |
| сам пакет | `site-packages/urok` | `pip uninstall urok` |
| байт-код | `site-packages/urok/__pycache__` | `pip uninstall urok` |
| история команд PowerShell | `ConsoleHost_history.txt` | Clear-History и удаление файла |
| сетевой лог | DNS/прокси школной сети | вне твоего контроля |

Запросы к `opencode.ai` видны сетевому логу в любом случае — это происходит
независимо от того, что лежит на диске. Эфемерный режим чистит локальные следы,
а не сетевые.

## Другие бесплатные модели

На Zen их несколько, все с суффиксом `-free`:

```
space-bunny-free          по умолчанию
deepseek-v4-flash-free
muse-spark-1.3-contributor-free
muse-spark-1.2-contributor-free
mimo-v2.5-free
nemotron-3-ultra-free
longcat-2.5-preview-free
```

Полный список: `/models`. Переключить: `/model muse-spark-1.3-contributor-free`
или флагом `urok --model deepseek-v4-flash-free`.

## Другой провайдер

Через флаги:

```bash
urok --base https://api.groq.com/openai/v1 --key gsk_... --model llama-3.3-70b-versatile
```

Или через переменные окружения, чтобы не светить ключ в истории:

```bash
set UROK_BASE_URL=https://api.groq.com/openai/v1
set UROK_API_KEY=gsk_...
set UROK_MODEL=llama-3.3-70b-versatile
urok
```

Подходит любой OpenAI-совместимый адрес: Groq, OpenAI, LM Studio, Ollama,
llama.cpp на `http://127.0.0.1:8080/v1`.

## Где лежат данные

История по умолчанию не пишется. С флагом `--keep-history` диалог сохраняется
в `~/.urok/session-ГГГГММДД-ЧЧММСС.json`, по строке на сообщение.
Сменить папку: переменная `UROK_HOME`.

## Настройка своего промпта

```bash
urok --system "Объясняй как пятикласснику, только формулы и короткие примеры."
```

## Тесты

```bash
python tests/smoke.py
```

Поднимает фейковый API в потоке и прогоняет через него весь диалог.
