Розв'язання проблем
Часті збої та як їх виправити. Якщо сумніваєшся, запусти:
aipager doctor
Він по черзі виконує всі перевірки нижче і для кожного збою виводить рекомендоване рішення. Вихідний код: aipager/doctor.py.
«Another aipager daemon already owns the socket»#
Два aipager не можуть ділити один керувальний сокет. Ця помилка означає, що aipager усе ще працює і відповідає на ньому (сокет - це $XDG_RUNTIME_DIR/aipager.sock або /tmp/aipager.sock, якщо $XDG_RUNTIME_DIR не задано). Файл сокета, що лишився від aipager, який упав, - не проблема: наступний запуск видаляє його і створює новий. Спершу зупини aipager, що працює:
aipager service stop # якщо він працює як служба
pkill -f 'aipager start' # інакше
Якщо перевірка сокета його не помітить, aipager start однаково відмовиться з aipager is already running (pid=N) і назве свій файл блокування (~/.local/share/aipager/daemon.lock): зупини цей процес так само.
Бот у Telegram не відповідає#
aipager status: якщо в рядку aipager написаноnot running, запусти його.aipager doctor: перевіркиtoken_validіchat_reachableзвертаються до API Telegram від початку до кінця і показують точну помилку.- Не той чат: запусти
aipager configі вибери Test bot reachability. Щоб виправити неправильний особистий чат, додай правильний через Add a DM scope (див. як знайти ID), потім прибери неправильний в Edit a scope. - Ботові жодного разу не надсилали
/start: відкрий бота в Telegram і один раз натисни Start.
Робочі картки стали повільнішими#
Telegram дозволяє приблизно одне повідомлення на секунду в один чат (і 20 на хвилину в групу). Рахується кожне повідомлення і кожна правка. aipager дає кожному чату свій бюджет приблизно в 1 виклик на секунду з невеликим запасом на сплески, і робочі картки цього чату його ділять. Індикатор «друкує…» теж входить у цей бюджет, як найменш важливе, що надсилає чат (див. «Бульбашка набору» нижче).
Частка бульбашки відкладається першою (один виклик кожні 4,5 секунди, поки найстарішому завданню чату, що триває, менше десяти хвилин, рідше, коли воно старіє, див. «Бульбашка набору»), а картки ділять решту. Тому одна картка в особистому чаті оновлюється приблизно кожні 4,8 секунди; за двох сесій, що працюють в одному чаті, кожна картка - приблизно кожні 9,7 секунди; за трьох - приблизно кожні 14,5. Повільна картка - це бюджет за роботою, а не баг. Відповіді, повідомлення у відповідь і реакції на кнопки ніколи не сповільнюються заради картки: вони мають зарезервований жетон, а правка картки, якій не вистачає на виклик, просто пропускається і повторюється на наступному проході, а не стає в чергу перед твоєю відповіддю.
У групі ліміт 20 викликів на хвилину, хоч скільки там сесій, і одна бульбашка з'їла б дві третини цього. Картки групи разом зберігають одне оновлення кожні 10 секунд (11 с для однієї картки), а бульбашка бере решту: тому в групі вона може час від часу зникати на секунду-дві.
Щоб пришвидшити картки: тримай менше одночасних сесій в одному чаті або дай найактивнішим власний чат (aipager config). Можна також налаштувати STREAM_EDIT_INTERVAL (за замовчуванням 1.2, темп, поки картка виводить текст) і BUSY_EDIT_INTERVAL (за замовчуванням 3.0, коли вона затихла) як змінні оточення aipager (див. налаштування з оточення). Поставити будь-яку з них нижче нижньої межі для чату безпечно і нічого не змінює: перемагає межа, і саме це тримає чат під лімітом Telegram, хоч яке значення стоїть у налаштуваннях.
Картка довгого завдання оновлюється рідше#
Темп вище діє перші дві хвилини завдання. Потім картка сповільнюється в міру того, як завдання старіє, а з 10 хвилин її годинник іде кроками по 30 с, у такт оновленням, щоб вона ніколи не виглядала завислою:
| вік завдання | картка оновлюється не частіше, ніж раз на | годинник показує |
|---|---|---|
| 0–2 хв | як вище (близько 4,8 с для однієї картки в особистому чаті) | 0:45 |
| 2–10 хв | 10 с | 4:10 |
| 10–60 хв | 30 с | 23:00, 23:30 |
| понад 60 хв | 30 с | 1:23:00, 1:23:30 |
Годинник округлюється вниз до свого кроку в 30 с, а оновлення йдуть не частіше, ніж через 30 с, іноді трохи рідше. Тому картка час від часу пропускає крок: оновлення на 23 хв 29 с показує 23:00, а якщо наступне прийде на 24 хв 1 с, воно покаже 24:00, і 23:30 буде пропущено.
Новий рядок інструмента або нове речення чекають на наступне оновлення; зміна стану (сесія переходить від роботи до очікування фонового агента і назад) показується одразу, не частіше разу на 10 секунд. Живі рядки агентів і рядок очікування йдуть тими самими кроками. Завершена картка показує тривалість завдання в справжніх секундах (23:17).
Саме це не дає чотиригодинному завданню правити одне повідомлення тисячі разів: 2026-09-23 одна картка так і зробила, і чат заблокували на сім годин. Щоб зберегти швидкий темп на все завдання, вимкни /settings → ⏱ Оновлення картки в довгих завданнях (для чату або для однієї сесії з Mini App чи з 👤 Налаштування кожної сесії).
Бульбашка набору#
Бульбашка «друкує…» надсилає один цикл на чат, хоч скільки сесій там працює (в усіх клієнтах Telegram бульбашка одна на чат), кожні TYPING_INDICATOR_INTERVAL секунд (за замовчуванням 4,5: Telegram прибирає статус набору через 5; 0 вимикає бульбашку). У бюджеті чату вона вважається найменш важливим, що надсилає чат:
- вона сповільнюється в міру того, як завдання старіє, за віком найстарішого завдання чату, що триває: кожні 4,5 с у перші десять хвилин (бульбашка горить постійно), потім кожні 15 с; Telegram показує її 5 с, тому бульбашка старого завдання блимає, а не горить. На 4,5 с вона одна давала б 800 викликів на годину, і годинний ліміт (нижче) вимикав би її надовго; вимкнення ⏱ Оновлення картки в довгих завданнях тримає її на 4,5 с;
- вона з'являється з самого початку кожного завдання; молода картка оновлюється трохи повільніше, щоб звільнити їй місце: частка бульбашки відкладається до того, як картки ділять решту (вище), тому разом вони ніколи не перевищують лімітів чату;
- вона ніколи не бере жетон, потрібний правці картки: бульбашка, яка мала б піти одразу після правки картки, чекає пів секунди (
TYPING_RETRY_WAKE) і пробує знову, тож вона запізнюється щонайбільше на секунду-дві, але ніколи не зникає; - її першою викидають, коли годинний обсяг чату стає великим (нижче);
- 429 на саму бульбашку блокує лише бульбашку, на стільки, скільки попросив Telegram (картки працюють далі), але запускає шестигодинний режим попередження чату (темп обмежено 0,5 виклику/с, тому картки теж сповільнюються);
- блокування на бульбашку (
retry_afterвище межі нижче) вимикає надсилання в чат так само, як блокування на будь-який інший виклик: у нього більше нічого не йде, а відповідь завдання притримується і доставляється, коли блокування знімуть.
Раніше вона була безкоштовною (один цикл на кожну сесію, що працює, поза будь-яким бюджетом), поки 2026-09-23 дві сесії в одному особистому чаті не надіслали її близько 5 400 разів за три години і Telegram не обмежив саму бульбашку.
Бот сповільнився: ліміт запитів (429)#
Якщо Telegram усе ж обмежує чат, він відповідає на один виклик 429 і retry_after у кілька секунд. aipager перестає звертатися до цього чату рівно на цей час, потім повторює одне відкладене надсилання і подвоює інтервал карток цього чату (до ×8). Кожна спокійна хвилина зменшує його вдвічі назад до норми.
Що ти бачиш:
aipager status(і рядокaipager daemonвaipager doctor) показуєTelegram flood backoff ×4 (chat …), last 429 12 s ago.- Рівно один рядок в
aipager logs, без трасування:flood: chat … 429 retry_after=5s → cadence ×2. - Нічого не вимкнено, і жодна відповідь не губиться: її відкладено, а не викинуто.
- Зароблена швидкість надсилання чату падає вдвічі, і чат входить у шестигодинний режим попередження (
FLOOD_WARNING_HOURS): його швидкість не може піднятися вище 0,5 виклику/с (FLOOD_WARNED_CEILING) і росте назад повільно.aipager statusце показує:Telegram chat 123: rate 0.25/s (ceiling 0.50/s), 212/1200 calls in the last hour (as of 18s ago), 7/30 in the last minute - warning regime, 5h 52m left.
Нічого робити не потрібно. Це минає само. Рядок про пригальмовування зникає, коли чат хвилину-дві спокійний; швидкість росте на 0,1 виклику/с за кожне спокійне вікно (зазвичай хвилина, у режимі попередження - 36 хвилин), а повна стеля повертається, коли режим закінчується. aipager doctor весь цей час тримає рядок aipager зеленим: чат, що пригальмовує, - це нормальна робота. (Раніше 429 забувався приблизно через п'ять хвилин. Єдине попередження Telegram перед блокуванням 2026-09-23 прийшло за 3 год 23 хв до нього, а чат повернувся на повну швидкість за кілька хвилин після нього.)
Годинний бюджет#
Кожен чат має ще ковзну годину: не більше FLOOD_HOURLY_MAX (1200) викликів за будь-які 60 хвилин, бульбашки набору, правки карток і відповіді разом; виключено лише реакції. Останні 120 (FLOOD_HOURLY_ESSENTIAL_RESERVE) залишено для відповідей, повідомлень у відповідь і запитів:
- на 810 викликах на годину бульбашку набору ставлять на паузу (вона повертається нижче 648);
- на 1080 чат входить у мінімальний режим (нижче), поки година не опуститься до 864;
- відповідей годинний бюджет ніколи не відхиляє; якщо вони колись перейдуть 1200, лог скаже про це раз на годину.
aipager status показує виклики чату за останню годину відносно його бюджету. Число береться з файлу стану, який aipager перезаписує не частіше разу на хвилину, поки йдуть виклики, тому поруч із ним вказано його вік. Дві активні сесії, які годинами пишуть в один особистий чат, лишаються помітно нижче бюджету (інцидент 2026-09-23, відтворений заново: близько 900 викликів у найзавантаженішу годину проти приблизно 3 400 за моделлю для тієї самої роботи без бюджету).
Зароблена швидкість і чому твої картки можуть бути повільнішими, ніж раніше#
З версії 0.7.13 стала швидкість надсилання кожного чату визначається з досвіду, а не припускається. Telegram не публікує ліміту, який насправді діє для твого бота (він залежить від недавньої історії твого акаунта), тому aipager починає кожен чат з 0,5 виклику/с, додає 0,1 за кожну спокійну хвилину до стелі 1/с, зменшує вдвічі під час 429 і опускає до 0,05 після блокування. Бот, якого щойно блокували, іде набагато обережніше, ніж той, якого не блокували, і заробляє швидкість назад протягом наступних годин.
Якщо швидкість чату падає нижче 0,2 виклику/с або частку його годинного бюджету на картки й бульбашки вичерпано, він входить у мінімальний режим: робочі картки перестають анімуватися і показують один нерухомий рядок ⏳ x1 · працює (картка поки не оновлюється), бульбашка набору зупиняється, а закріплений рядок стану показує ⏸ картки поки не оновлюються (годинний ліміт Telegram) (або (ліміт Telegram), коли туди чат привела швидкість) і в іншому не змінюється, доки це не мине. Відповіді, повідомлення у відповідь і запити на дозвіл ідуть далі: у цьому весь сенс. Картка - це близько 95 % того, що надсилає цей бот, а відповідь - близько 5 %, тому під тиском він жертвує пікселями, а не роботою. aipager doctor показує мінімальний режим як попередження, щоб картку на паузі ніколи не прийняли за зламану; він знімається сам, коли швидкість відновлюється.
Бот замовк: блокування Telegram (flood control)#
retry_after більший за TELEGRAM_MAX_RETRY_AFTER (за замовчуванням 90 с) - це не ліміт запитів, а блокування, і воно може тривати годинами. З чату це виглядає так, ніби бот помер: повідомлення й далі доходять до Claude, сесії працюють далі, але відповіді не приходять.
Що ти бачиш:
aipager status(і рядокaipager daemonвaipager doctor) показуєTelegram flood-muted until HH:MM (chat …).- Один рядок в
aipager logs:Telegram flood control — chat … muted for Ns (until HH:MM) …, потім тиша щодо цього чату. Пізніше один рядокflood mute on chat … lifted. aipager statusще й показує повний стан чату:Telegram chat 123: rate 0.05/s (ceiling 0.50/s), 431/600 calls in the last hour (as of 12s ago) - MINIMAL MODE, card updates paused - flood-muted until 09:41 - warning regime, 5h 59m left (1 ban(s) in the last 7 days).
aipager вимикає надсилання в чат рівно на той час, який попросив Telegram, і не робить до нього жодного виклику будь-якого виду: ні відповідей, ні правок робочої картки, ні вкладень, ні реакцій, ні індикаторів набору, ні коротких сповіщень після натискання кнопок, ні відповідей, які дали б твої команди. Кожен із них став би новим порушенням, яке подовжує блокування; саме запит посеред активного блокування 2026-09-15 перетворив блокування на 21 хвилину на блокування на 9,5 години. Тому команда, набрана під час вимкнення, не отримує взагалі жодної відповіді, і натискання кнопки теж не підтверджується: до 0.7.12 коротке сповіщення все одно йшло, з розрахунком на те, що Telegram рахує його окремо. Для темпу це так; для блокувань - ні. Інших чатів це не зачіпає.
Писати ботові під час блокування безпечно, і нічого не губиться. Ніщо з того, що ти робиш у чаті, не змушує бота звертатися до Telegram, поки надсилання в чат вимкнено, тому подовжити блокування це не може:
- Повідомлення, яке ти надсилаєш (текст, голосове, файл, швидкий шаблон), однаково доходить до Claude, і сесія над ним працює. Його робоча картка притримується, а не викидається: якщо завдання ще триває, коли блокування знімуть, картка з'явиться тоді. Після блокування чат ще якийсь час лишається в мінімальному режимі, тому картка може з'явитися на кілька хвилин пізніше кінця блокування. Якщо завдання закінчилося під час блокування, ти отримаєш його відповідь і жодної картки.
- 🔄 Повторити під час блокування нічого не робить. Повідомлення не надсилається знову, а кнопка лишається, тож її можна натиснути ще раз після блокування. До 0.7.14 включно повідомлення йшло до Claude, а повідомлення про помилку з кнопкою лишалося, тож друге натискання надсилало його ще раз.
- Основна клавіатура теж притримується, зокрема та, яку надсилає перезапуск (до 0.7.14 включно вона губилася, поки щось інше її не оновлювало). Вона надсилається після блокування.
Після зняття блокування все приходить у такому порядку: притримані відповіді, потім картки завдань, які ще тривають, потім клавіатура. Картка, якій доводиться чекати кінця мінімального режиму, приходить після клавіатури.
Відповіді не губляться. Відповідь, що вийшла, поки надсилання в чат вимкнено, притримується і доставляється після зняття блокування за пару секунд, з першим рядком ⏳ прийшло із запізненням: затримано на 42 хвилини через ліміт Telegram. Питати знову не потрібно, а якщо спитаєш, прийдуть обидві відповіді, спершу стара: блокування на кілька годин охоплює кілька завдань, і відповідь кожного тобі потрібна. (Притримані відповіді живуть у пам'яті: якщо перезапустити aipager, поки якісь чекають, вони губляться; лог вимкнення каже, скільки. Чат притримує не більше 20 і нічого старшого за 24 години; усе, що викинуто з будь-якої з цих причин, позначається в лозі попередженням із зазначенням, що це було.)
Блокування робить чат потім повільнішим, а не швидшим. Щойно блокування настає, вивчена швидкість чату падає до мінімуму, а блокування зараховується; години вимкнення нічого не повертають, ріст починається заново з моменту зняття блокування, і сім днів (FLOOD_BAN_MEMORY_DAYS) стеля швидкості чату і його годинний бюджет діляться на одиницю плюс кількість блокувань за цей тиждень: одне блокування ділить обидва вдвічі, два - на три. aipager status показує все це. (Раніше ця пам'ять тривала 24 години і ділила лише стелю; чат, заблокований 2026-09-19, повернувся на повну швидкість і був заблокований на сім годин 2026-09-23.) П'ять і більше блокувань за тиждень тримають чат у мінімальному режимі, доки вони не застаріють: відповіді йдуть, картки лишаються на паузі.
Чого НЕ робити:
- Не перезапускай aipager, щоб «полагодити». Вимкнення зніметься саме в показаний час. З версії 0.7.13 перезапуск більше не забуває блокування (строк, зароблена швидкість чату та історія його блокувань зберігаються в
~/.claude/aipager-flood-state.jsonі відновлюються під час запуску, як і остання година викликів чату та його режим попередження), тому перезапуск його більше й не подовжує. Але він викине всі ще притримані відповіді й нічого не полагодить. - Не опускай
TELEGRAM_MAX_RETRY_AFTERнижче стандартних 90 с у надії повторити раніше: усе вище цього порогу - це блокування, а не ліміт запитів.
Як цього уникнути: тримай менше одночасних сесій в одному чаті або дай найактивнішим власний чат (aipager config).
Сесія зникла із закріпленого рядка стану (вона GONE)#
Процес dtach цієї сесії завершився (перезавантаження комп'ютера, pkill claude, хтось набрав exit у під'єднаній сесії dtach). Створи її заново: у її папці ~/.claude/projects/... розмова лишилася.
Найпростіше - /resume <label> у Telegram (або просто /resume для списку): це перезапускає сесію і продовжує розмову. З командного рядка:
aipager resume <label> # те саме з термінала
aipager session <label> # або нова сесія, без історії
aipager session <label> --continue # новий dtach, остання розмова цієї папки
Запит на дозвіл без новин 5 хвилин#
Якщо сесія чекає на запит на дозвіл або питання, а Claude Code 5 хвилин нічого не повідомляє, aipager читає збережену розмову сесії. Зважають лише на новини від самого Claude і від агента, який запитав: фоновий агент, що далі працює, не заважає цій перевірці. Лише якщо вона показує, що запит закінчено (на нього відповіли в терміналі, а звістка про це загубилася), aipager перестає на нього чекати і знову вважає, що сесія працює. Інакше запит лишається відкритим скільки завгодно: картка й закріплений рядок і далі кажуть, що сесії потрібна твоя відповідь, примітка «ще працює» не приходить, а твої повідомлення затримуються, доки ти не відповіси (див. текст). Claude Code, що закрився з відкритим запитом, завершує сесію. Кнопки запиту й далі відповідають у діалозі, якщо він ще відкритий (див. відповіді).
Змінити очікування:
AIPAGER_INTERACTIVE_TIMEOUT=300 aipager start # у секундах
Підтримка голосових не встановлюється через Telegram#
Кнопка [📦 Установити голосові] запускає інсталятор і править своє повідомлення кожні кілька секунд, поки він працює (усе ще триває… (25 с)). Якщо встановлення не вдалося, повідомлення показує код виходу і останні 500 символів виводу інсталятора. Часті причини:
- Мережа: pip не може достукатися до PyPI. Перевір з'єднання з комп'ютера, де працює aipager.
- Диск:
~/.cache/huggingface/потрібно близько 74 МБ на модель і кешу wheels від pip ще близько 250 МБ. Спершу звільни місце. - Permission denied: venv лише для читання. Перейди на
uv tool install, який завжди використовує venv, що належить твоєму користувачеві.
Якщо бот утратив зв'язок посеред встановлення, саме встановлення на комп'ютері зазвичай завершилося: перезапусти aipager і спробуй голосове ще раз.
Під час відкриття застосунку видно «Відкрий цю сторінку з застосунку Telegram, щоб увійти.»#
Сторінка завантажилася, а скрипт Mini App SDK від Telegram (той, що дає initData) - ні, тому сторінці нема з чим входити, і вона не робить жодного виклику API. Повідомлення звучить так, ніби винен ти; насправді причина в мережі.
Нові версії aipager самі завантажують цей скрипт і віддають його зі свого джерела сторінки (/telegram-web-app.js), тож телефону треба достукатися лише до хоста, який віддав сторінку, а не ще й до telegram.org. Якщо бачиш це на старій версії, оновися.
Далі по черзі:
- Подивися вихідний код сторінки. Якщо її тег
<script>вказує наhttps://telegram.org/js/telegram-web-app.js, aipager ще не зміг завантажити скрипт, і сторінка вантажить його з Telegram, а саме це й не працює на телефоні, який не може достукатися доtelegram.org. aipager завантажує його під час запуску сервера Mini App і повторює не частіше разу на день, тому перезапуск aipager повторює спробу одразу;journalctl --user -u aipager | grep "webapp sdk"каже, що пішло не так (зазвичай заблокований або фільтрованийtelegram.org). - Якщо тег вказує на
/telegram-web-app.js, перевір, що aipager його віддає:curl -sI http://127.0.0.1:8765/telegram-web-app.jsна комп'ютері aipager (виправ порт, якщо він змінювався) має відповісти200зContent-Type: application/javascript. Копія лежить у~/.local/share/aipager/webapp-sdk/. - URL відкрито у звичайному браузері, а не через кнопку
/appабо кнопку меню бота: тоді це очікуване повідомлення. SDK даєinitDataлише всередині Telegram. - Сторінку було відкрито понад п'ять хвилин:
initDataспливає, і сторінка просить відкрити її заново. Натисни/appще раз. - Mini App відкрито кнопкою
📱 Appна клавіатурі від старішої версії aipager. Telegram не даєinitDataMini App, відкритій кнопкою клавіатури, тому на клавіатурі aipager цієї кнопки більше немає. Надішли/start, щоб отримати поточну клавіатуру, і відкривай застосунок кнопкою меню або командою/app.
pyexpat _XML_SetAllocTrackerActivationThreshold під час встановлення через brew#
Пакет python@3.12 з Homebrew зібрано з новішою libexpat, ніж є у твоїй системі, майже завжди тому, що Xcode і Command Line Tools застаріли на macOS Tahoe (26.x). Вивід brew зазвичай сам про це каже. Два рішення:
- Використай натомість
uv tool install aipager. uv приносить власний python і повністю оминає проблему. Це рекомендований шлях на macOS; див. README. - Онови Xcode і Command Line Tools:
Або відкрий Xcode в App Store і онови до останньої версії.
sudo rm -rf /Library/Developer/CommandLineTools sudo xcode-select --install
«ModuleNotFoundError: aipager»#
Програма aipager посилається на Python, у якому aipager більше не встановлено (часто після видалення venv). Перевстанови:
uv tool install --reinstall aipager
# або тим інсталятором, з якого починали: pipx, brew, pip
Список сесій утрачено або пошкоджено#
aipager зберігає свої сесії в ~/.claude/aipager-sessions.json і перезаписує його атомарно (новий файл, потім перейменування), тож перерваний запис лишає старий файл цілим. Якщо файлу все ж немає, він не читається або це не валідний JSON, aipager пише в лог, що починає заново (попередження, якщо файл був, але не прочитався), і починає з порожнім списком; він не зупиняється. Резервних копій цього файлу немає. Нічого важливого не губиться:
- сесії, що працюють, знаходяться знову на першому проході монітора, за їхніми сокетами dtach (
/tmp/claude-dtach-*.sock); - кожна розмова й далі лежить у власній папці Claude Code
~/.claude/projects/..., тожaipager session <name> --continueу папці цієї сесії її продовжить (--resumeдає вибрати); - губиться список завершених сесій (
/resume), картки, які були відкриті, і решта того, що aipager пам'ятав про кожну сесію.
Якщо aipager і далі падає під час запуску, aipager logs (або journalctl --user -u aipager) скаже чому; відсунь файл убік (mv ~/.claude/aipager-sessions.json ~/aipager-sessions.json.old), щоб виключити його.
Сесія не запускається#
Запуск, від якого відмовився dtach, показує в чаті причину одним рядком (сокет уже існує, shell не виконуваний, немає псевдотермінала, назва задовга, доступ заборонено, немає папки); власне повідомлення dtach, зі шляхами, є в aipager logs.
Список перевірок aipager doctor#
Порядок важливий: кожна наступна перевірка припускає, що попередні пройшли. Перевірка, яка падає в неочікуваному оточенні, показується одним рядком ⚠ з назвою перевірки та помилкою; решта перевірок однаково виконується.
Перевірка (ключ --json) | Що перевіряє | Як виправити |
|---|---|---|
config_parses | aipager.yaml і policy.yaml читаються; іде першою, бо всі наступні перевірки читають конфігурацію | помилка називає файл і рядок |
config | ~/.config/aipager/aipager.yaml існує, і в ньому є токен і чат | aipager config |
token_valid | Токен працює з getMe у Telegram | знову запустити aipager config |
chat_reachable | Telegram знає налаштований чат (getChat; нічого не надсилається) | відкрити бота, натиснути Start |
team | Чати й учасники (або старий team.yaml): каже, особистий це режим чи командний, і позначає пошкоджений або невідповідний старий team.yaml | aipager config |
role_shell_access | Один раз попереджає про кожну роль учасника, яка може запускати Bash (її правила безпеки працюють лише наскільки можливо і не є межею; див. групи) | не давати цій ролі Bash у policy.yaml або змиритися |
peer_messages | Повідомлення між сесіями Claude: де зберігаються їхні квитанції та чи закрита ця папка, чи може ця система перевірити час запуску відправника, і попередження про кожну роль, якій правило дозволяє SendMessage (див. безпека) | прибрати спільну папку квитанцій (aipager створить її заново) або не давати цій ролі SendMessage |
claude | Знаходить програму claude так само, як кожен запуск (claude_path в aipager.yaml або $AIPAGER_CLAUDE_BIN перемагають одразу; інакше найновіша з ~/.local/bin, PATH і Homebrew), і перелічує кожне ІНШЕ знайдене встановлення | встановити Claude Code або задати claude_path / AIPAGER_CLAUDE_BIN |
claude_auth | Пробує claude auth status у тому самому оточенні, яке отримує справжня сесія. Ніколи не провалюється: «вхід не виконано» і «сама проба не вдалася» показуються по-різному, і ні те, ні те не заважає запуску сесії | claude auth login або задати ключ API / CLAUDE_CODE_OAUTH_TOKEN |
dtach | Програму dtach знайдено (власний dtach-bin aipager або та, що в PATH) | uv tool install --reinstall aipager |
hook_scripts | aipager-hook і aipager-statusline є в PATH | uv tool install --reinstall aipager |
settings_json | У ~/.claude/settings.json підключено hooks aipager | aipager config |
daemon | aipager працює і його сокет відповідає; показує й стан лімітів Telegram (див. вище) | aipager start |
service_installed | За бажанням: файл служби на місці | aipager service install |
service_unit_path | Лише Linux: Environment=PATH= встановленої служби справді містить папку знайденої програми claude, прочитаний як текст, бо doctor не бачить PATH systemd з інтерактивного shell оператора | aipager service install --yes |
miniapp | Чи може запуститися Mini App, коли її ввімкнено. Ніколи не провалюється: Mini App необов'язкова | виправлення, яке вона називає |
aipager doctor --json виводить ті самі перевірки в цьому порядку з цими ключами (див. команди).
Запусти aipager doctor --fix, щоб інтерактивно знайти облікові дані Claude і скопіювати їх у daemon.env (і тоді, коли файл є, але їх у ньому немає) або закріпити claude_path, коли знайдено більше одного встановлення. Він діє лише після запитання. Для служби, у PATH якої немає папки claude, запусти aipager service install --yes.
aipager не знаходить claude або вибирає не те встановлення#
Раніше шість місць шукали claude кожне по-своєму і могли не збігатися. Тепер усі йдуть через одну функцію пошуку (aipager/claude_resolve.py). claude_path в aipager.yaml, потім $AIPAGER_CLAUDE_BIN, перемагають одразу, якщо працюють. Інакше перевіряється кожен claude, знайдений у ~/.local/bin, у $PATH і в префіксах Homebrew, і перемагає найновіша версія (тож зміна порядку в $PATH не змінює вибору, якщо інше встановлення новіше). Запусти aipager doctor, щоб побачити, яке саме він вибрав і що ще знайшов; якщо перемагає не те, закріпи потрібне:
aipager doctor --fix # інтерактивний вибір серед знайдених встановлень
# або вручну:
echo 'claude_path: /home/you/.local/bin/claude' >> ~/.config/aipager/aipager.yaml
Сесії не можуть увійти під службою systemd, хоча claude у терміналі працює#
Служби systemctl --user ніколи не читають ~/.bashrc або ~/.profile, тому рядок export CLAUDE_CODE_OAUTH_TOKEN=… звідти ніколи не доходить до aipager. Натомість служба використовує LoadCredential= із systemd і читає ~/.config/aipager/daemon.env: простий файл KEY=VALUE з правами 0600, який створюється автоматично під час першого запуску aipager service install (переноситься зі старого config.env, якщо там був токен, інакше один раз знаходиться у твоєму shell входу, інакше лишається порожнім з попередженням). Якщо він досі порожній, aipager doctor --fix знову шукає в тих самих місцях, якщо відповісти так, і додає знайдений рядок, зберігаючи решту рядків файлу; токен він ніколи не виводить. Або додай рядок вручну:
cat ~/.config/aipager/daemon.env # подивитися, що там є (чи немає)
echo 'CLAUDE_CODE_OAUTH_TOKEN=sk-...' >> ~/.config/aipager/daemon.env
chmod 600 ~/.config/aipager/daemon.env
aipager service stop && aipager service start
Див. Модель безпеки: облікові дані Claude про те, від чого цей файл захищає, а від чого ні.
Керувальний сокет aipager переїхав#
aipager doctor / aipager status раніше завжди дивилися в /tmp/aipager.sock. Під службою systemd керувальний сокет тепер лежить у $XDG_RUNTIME_DIR/aipager.sock (із запасним /tmp, лише коли $XDG_RUNTIME_DIR не задано: контейнери, WSL1, мінімальні дистрибутиви). Переїхав лише цей один сокет; сокетів dtach кожної сесії (/tmp/claude-dtach-*.sock) це не зачепило. Задай AIPAGER_SOCKET_PATH, якщо потрібне конкретне місце.
/update каже, що перезапуск завершить сесії (KillMode)#
У файлах служб, записаних до цієї версії, немає рядка KillMode=, тому systemd використовує control-group: зупинка чи перезапуск aipager.service завершує кожну сесію Claude, яку запустив aipager. Тому /update встановлює нову версію, але aipager не перезапускає і перелічує сесії, які обірвав би перезапуск. Виправ це один раз:
aipager service install
Це перезаписує службу з KillMode=process, перезавантажує systemd і перезапускає aipager, і цей перезапуск уже йде з новим налаштуванням. Перевір через systemctl --user show -p KillMode aipager.service (KillMode=process). З цим налаштуванням systemd під час кожного перезапуску пише для твоїх сесій рядки «left-over process»; це нормально.
aipager update не знаходить uv або pipx#
aipager update шукає інсталятор за абсолютним шляхом у твоєму PATH, а також у ~/.local/bin, ~/.cargo/bin, префіксах Homebrew, /usr/bin і /bin. Якщо він однаково каже, що не знайшов pipx, інсталятора, який створив цей aipager, більше немає або він лежить в іншому місці; перевстанови тим інструментом, який є (pipx install --force aipager, uv tool install --reinstall aipager).
Оновлення відхилено: editable або чуже встановлення#
/update і aipager update оновлюють лише встановлення, яке належить твоєму користувачеві й доступне йому на запис, через інсталятор, який його створив. Вони відмовляють і називають причину для:
- робочої копії в режимі editable (для розробки): онови її через
git pull; - встановлення через Nix, Snap, Docker або системний пакет: використай оновлення цієї системи;
- встановлення, яке належить іншому користувачеві (наприклад, venv root в
/opt): онови його від імені цього користувача; - встановлення з локальної папки (
pipx install /path/to/aipager):звідси не оновити: it was installed from a local folder; update it from that folder. Отримай нову версію в цю папку і перевстанови з неї або перейди на PyPI черезpipx install --force aipager; - встановлення, для якого незрозуміло, який інсталятор його зробив (
could not tell which installer owns this aipager): перевстанови його черезuv tool install aipagerабоpipx install aipager.
Оновлення не вдалося: unexpected argument '--refresh'#
aipager 1.0.0 і старіші запускали uv tool upgrade aipager --refresh, а цього прапорця не приймає жодна версія uv, тому кожне оновлення встановлення через uv зупинялося з error: unexpected argument '--refresh' found і нічого не перезапускало. Нові версії запускають uv tool upgrade aipager. Щоб один раз пройти це місце, онови з термінала на цьому комп'ютері (aipager update на цих версіях має ту саму ваду):
uv tool upgrade aipager
systemctl --user restart aipager.service
Без служби (або на macOS) перезапусти aipager тим способом, яким його було запущено.
Оновлення Claude Code: встановлено через npm у папку, куди не можна писати#
Claude Code, встановлений через sudo npm install -g, лежить у папці, яку може змінювати лише root (на кшталт /usr/lib/node_modules), тому claude update від твого користувача падає з global folder isn't writable. /update і Mini App показують новішу версію з звідси не оновити: installed with npm into a folder your user can't write to і без кнопки для неї. Один раз запусти claude install від того користувача, під яким працює aipager: це переводить на власний інсталятор Claude Code у твоїй домашній папці, який оновлюється без sudo. Потім перезапусти aipager (systemctl --user restart aipager.service або тим способом, яким його було запущено): aipager, що працює, тримає той Claude Code, який знайшов під час запуску, а після перезапуску бере найновіший зі знайдених. Якщо claude_path в aipager.yaml (aipager doctor --fix може його задати) або AIPAGER_CLAUDE_BIN вказує на версію з npm, спрямуй його на ~/.local/bin/claude або спершу прибери, бо вони завжди перемагають.
Оновилося, але версія не змінилася#
Встановлення pipx з git URL оновлюється з цього джерела git, а не з PyPI. Коли в джерелі немає нічого новішого, /update пише ✅ У aipager уже версія A: це встановлення через pipx оновлюється зі свого git-репозиторію, а там нічого новішого немає.. Надішли або вибери нову версію там або перейди на PyPI через pipx install --force aipager.
Без служби aipager, який не перезапускає жоден менеджер служб (aipager start у терміналі чи tmux, Docker, launchd), встановлює оновлення, але далі працює на старому коді, доки не перезапуститься. Тоді /update пише aipager B встановлено, він чекає на перезапуск (зараз працює A)., а hooks Claude Code, які запускаються заново на кожну подію, можливо, вже працюють на B: власник отримує одне сповіщення, що оновлення зроблено лише наполовину (через дві хвилини після того, як hooks уперше запустили B, тож перезапуск одразу після встановлення його ніколи не показує, і коли в особистому чаті власника не триває жодне завдання). Коли aipager уже працює на B, це сповіщення перетворюється на ✅ Оновлення aipager завершено: aipager тепер працює на B., без кнопки. Натисни 🔄 Перезапустити зараз (у повідомленні про оновлення, у сповіщенні чи в Налаштування → Оновлення в Mini App). aipager чекає, доки не залишиться жодного завдання, акуратно зупиняється й запускає нову версію на місці: той самий процес у тому самому терміналі, вікні tmux чи контейнері, з тією самою командою й тим самим оточенням.
Якщо запуск на місці не вдався, окрема копія запускає aipager, коли старий процес уже завершився. Її вивід тоді йде в лог самоперезапуску (aipager.log у папці екземпляра або /tmp/aipager.log), а не у твій термінал, а лог aipager називає команду, яку треба виконати, якщо ця копія не повернеться. Якщо зник сам інтерпретатор (його оточення видалили) або нічого не вдалося запустити, aipager завершується з кодом 1, лог aipager закінчується рядком restart.failed: з командою, яку треба виконати, а наступний запуск повідомляє про оновлення.
Коли кнопки Перезапустити зараз немає, повідомлення дає кроки для твого встановлення: у терміналі чи tmux натисни Ctrl+C і виконай aipager start; на macOS: launchctl kickstart -k gui/<uid>/com.aipager.daemon; у Docker: docker restart <container> на хості. Перестворення контейнера Docker (docker compose up після down або знову docker run) запускає його з образу, а це повертає версію aipager з цього образу: щоб залишити новіший aipager, використовуй новіший образ.
aipager не повернувся після оновлення#
Оновлення перевіряє, що нова версія завантажується, перш ніж щось перезапускати, але якщо новий aipager однаково не запускається, systemd повторює спробу кожні 5 с. Подивися чому:
journalctl --user -u aipager.service -n 50
Перевстанови попередню версію тим самим інсталятором, потім перезапусти:
pipx install --force aipager==<previous> # або:
uv tool install --force aipager==<previous> # або:
<venv>/bin/python -m pip install aipager==<previous>
systemctl --user restart aipager.service
Встановлення pipx з локального шляху: pipx install --force /path/to/aipager на старому коміті. Якщо чекає застаріле оголошення, прибери його через rm -f ~/.local/share/aipager/update-restart.json (через 24 год його однаково ігнорують); ~/.local/share/aipager/update.lock - це лише файл блокування, і його безпечно видалити, коли жодне оновлення не триває.
«Оновлення перервалося, коли aipager вимикався»#
aipager зупинився (або його перезапустили), поки /update встановлював, і інсталятор зупинився разом із ним, тож встановлення може бути записане наполовину. Якщо aipager або Claude Code поводяться дивно, полагодь: для aipager запусти команду перевстановлення з повідомлення (наприклад, pipx install --force aipager) і потім systemctl --user restart aipager.service; для Claude Code знову запусти claude update.
Якщо «Перезапустити зараз» не зміг знову запустити aipager (без служби), у лозі aipager лишається restart.failed: з командою, яку треба виконати; виконай її, і новий aipager повідомить про оновлення.
Чат не тією мовою#
Мова aipager береться з того, що вибрано для чату, а не з повідомлень у ньому. Відкрий /language у цьому чаті й вибери потрібну мову: цей вибір важливіший за все інше. В особистому чаті Автоматично йде за мовою твого застосунку Telegram (Налаштування → Мова в Telegram); мова, якої aipager не має, показується англійською. Особистий чат, який існував до появи мов, лишається англійським, доки ти не вибереш мову. Група лишається англійською, доки адмін не вибере їй мову. Мова змінює лише тексти самого aipager: Claude відповідає тією мовою, якою ти йому пишеш, хоч би що показував aipager. Див. Мови.
Опис бота не той, що написано в BotFather#
aipager ставить опис і короткий опис бота кожною мовою, якою він говорить, для людей, у яких застосунок Telegram цією мовою, і Telegram показує їм цей текст замість того, що написано в BotFather. aipager робить так, лише поки в тебе немає свого опису, тому опис, написаний до встановлення цієї версії, бачать усі. Якщо його написано після того, як aipager поставив свій, люди цими мовами й далі бачать опис aipager. Щоб показати їм твій, зітри текст aipager для кожної мови через Bot API (setMyDescription і setMyShortDescription з порожнім текстом і цим language_code); aipager ніколи не поставить його знову, поки є твій.
aipager пише, що languages.json не вдалося використати#
aipager зберігає те, що дізнався про мови (хто був тут до появи мов, остання мова Telegram, яку він бачив у кожної людини, і чи пішли разова пропозиція та рядок першого контакту), у ~/.local/state/aipager/languages.json. Якщо цей файл не читається, aipager відсуває його вбік як languages.json.bad-<time> у тій самій папці, пише в лог попередження (знову під час кожного запуску, доки не ухвалено рішення) і тримає всі чати англійською без пропозиції мови, доки не ухвалено рішення: поверни старий файл, якщо можеш його полагодити, або видали languages.json і перезапусти, і aipager знову вважатиме кожну відому йому людину такою, що вже була тут (англійська, доки людина не вибере). Мова, яку хтось вибрав, у цьому файлі не зберігається і ніколи не губиться.
Текст справа наліво виглядає неправильно#
Перською та арабською aipager ставить у свої тексти невидимі позначки напрямку, щоб кожен рядок читався справа наліво, а назви сесій, команди й код лишалися зліва направо. Якщо рядок однаково виглядає перемішаним, найчастіше справа в клієнті Telegram, який по-своєму малює текст зі змішаним напрямком: перевір в іншому клієнті (телефон проти Desktop або Web), перш ніж повідомляти. Власні відповіді Claude показуються так, як Claude їх написав, без доданих позначок.
Перекладене слово клавіатури нічого не робить в іншому чаті#
Клавіатура кожного чату - мовою цього чату. Слова основної клавіатури (status, stop, new, kill та інші) розуміються в кожному чаті будь-якою мовою, а англійські слова працюють завжди. Слово кнопки шаблону чи команди - інша справа: набране в чаті з іншою мовою, це повідомлення для Claude, а не кнопка, тому українське «Очистити розмову» ніколи не запустить /clear у перському чи англійському чаті. Використовуй саму кнопку або англійську команду (/clear). Якщо клавіатура виглядає застарілою після зміни мови чату, надішли /start, щоб отримати поточну. Слово, яке водночас є назвою однієї з твоїх сесій, звертається до цієї сесії. /mode завжди читає ask, auto і full як режим, а перекладене слово режиму - як сесію лише тоді, коли сесія, що працює, має саме таку назву.
Не вдається?#
Надішли звіт про проблему: натисни Повідомити про проблему під /help у своєму особистому чаті з ботом або запусти aipager report у терміналі. Ти бачиш увесь звіт до того, як щось буде надіслано, і в ньому немає чатів, повідомлень, імен, шляхів чи токенів (див. Звіти про проблеми). Після надсилання ти отримаєш номер на кшталт ap1-7c41d09e2b3a.
Потім, якщо хочеш це обговорити, відкрий issue на github.com/dev-aly3n/aipager/issues і вкажи цей номер. Будь ласка, не вставляй в issue вивід aipager doctor або aipager logs: у них є ID твого чату, шляхи твоєї домашньої папки, назви сесій і початок твоїх повідомлень. Якщо потрібен рядок логу, той, хто підтримує aipager, попросить саме цей один рядок, і ти зможеш спершу прибрати з нього все особисте.
Див. також#
- Архітектура: що робить кожна частина.
- Модель безпеки: чого aipager торкається, а чого ні.