LocalChat
Однопользовательский Chainlit UI и ReAct-агент на LangChain с поддержкой OpenAI-compatible API и нативных моделей GigaChat: модель вызывает инструменты чтения загруженных файлов и формирует ответ. История диалога, сводка контекста и файлы сохраняются локально.
Агент предоставляет ровно четыре инструмента: ls, read_file, glob, grep. Их виртуальный / — файлы текущего чата. Выход в файловую систему хоста, другие чаты, запись файлов, shell и выполнение кода недоступны. Субагентов, планировщика, файловой выгрузки контекста и общей долговременной памяти нет.
Редактирование исторического запроса удаляет его прежний ответ и последующее продолжение. Контекст вместе со сводкой и файлами восстанавливается перед изменяемым запросом, после чего агент отвечает заново. Ошибка или Stop восстанавливают прежнее состояние. Одинаковый текст правки сохраняет весь диалог.
Установка и первый запуск
Требуются Python 3.12–3.13, Linux (или WSL2) и модель с tool calling: OpenAI-compatible API или GigaChat. Пакет содержит UI, переводы и все ресурсы приложения; клонировать репозиторий для запуска не нужно. Windows без WSL не поддерживается из-за требований файловой песочницы. macOS пока не входит в проверяемые платформы.
Установите приложение из PyPI через pipx:
pipx install --python python3.12 local-agent-chat
localchat init
localchat run
init запросит модель, адрес API и ключ или готовый access token. Запускайте команды в папке, где хотите хранить настройки и историю. Для OpenAI-compatible endpoint имя модели имеет вид openai:<model-id>, например openai:deepseek/deepseek-v4-flash-0731 для OpenRouter. Для GigaChat используйте gigachat:GigaChat-2 и base URL его API. Ключ вводится без отображения в терминале; секрет сессии создаётся автоматически. run покажет адрес UI, по умолчанию http://127.0.0.1:8765/. Остановка — Ctrl+C; --open-browser открывает браузер автоматически.
Можно также установить собранный wheel: pipx install --python python3.12 ./dist/local_agent_chat-0.2.0-py3-none-any.whl. Альтернатива pipx — python3.12 -m venv .venv, активация окружения и python -m pip install local-agent-chat.
Для локального API без ключа:
localchat init --no-input --model openai:your-model \
--base-url http://127.0.0.1:8000/v1 --no-api-key
Для автоматической настройки с ключом передайте его в OPENAI_API_KEY и используйте те же аргументы без --no-api-key. --api-key-env MY_PROVIDER_KEY выбирает другое имя переменной. Новые профили создаются с streaming: false и max_tokens: 128000: по умолчанию ответ приходит целиком. --streaming включает потоковый ответ; --no-streaming явно отключает его. --max-tokens 4096 задаёт другой лимит ответа. Полная справка с описанием обоих провайдеров: localchat --help, localchat init --help, localchat run --help.
Для GigaChat можно выполнить интерактивную настройку:
localchat init --model gigachat:GigaChat-2 --base-url https://api.giga.chat/v1
localchat run
Введите готовый access token, а не OAuth-ключ credentials. Для --no-input заранее задайте GIGACHAT_ACCESS_TOKEN; --api-key-env COMPANY_TOKEN выбирает другое имя переменной. OAuth и автоматическое обновление токена не выполняются. Если токен истёк, обновите его в .env (или в окружении, если оно переопределяет файл) и перезапустите приложение. --no-api-key доступен только для локального OpenAI-compatible API. Проверка TLS остаётся включённой; для собственного центра сертификации SDK поддерживает GIGACHAT_CA_BUNDLE_FILE с абсолютным путём к сертификатам.
Настройки, данные и обновление
В текущей рабочей папке создаются:
.env— параметры запуска и токены, права нового файла0600.models.yaml— профили моделей: идентификатор, base URL, streaming и имя переменной токена; секреты здесь не хранятся..local-agent-chat/— SQLite, история, память агента и вложения. Технические логи выводятся в консоль.
APP_DATA_DIR=.local-agent-chat и MODEL_PROFILES_FILE=models.yaml сохраняются относительными путями. --config-dir PATH или LOCALCHAT_CONFIG_DIR выбирает другой каталог конфигурации; его каталог данных по умолчанию также находится рядом с .env. --data-dir PATH или APP_DATA_DIR переопределяет каталог данных. Относительные пути разрешаются относительно каталога конфигурации. Приоритет: аргументы запуска, затем переменные окружения, затем .env, затем значения по умолчанию. XDG_CONFIG_HOME и XDG_DATA_HOME больше не выбирают расположение данных LocalChat.
Повторный init не перезаписывает настройки. Для смены модели или ключа отредактируйте конфигурацию и перезапустите приложение. Для нескольких моделей добавьте профили в models.yaml с уникальными id, например:
models:
- id: openrouter
label: DeepSeek
model: openai:deepseek/deepseek-v4-flash-0731
base_url: https://openrouter.ai/api/v1
api_key_env: OPENAI_API_KEY
streaming: false
max_tokens: 128000
- id: giga
label: GigaChat 2
model: gigachat:GigaChat-2
base_url: https://api.giga.chat/v1
api_key_env: GIGACHAT_ACCESS_TOKEN
streaming: false
max_tokens: 128000
Токены обоих профилей задаются в .env. Модели используются для ответа, инструментов, суммаризации и названий чатов.
В одном запущенном экземпляре одновременно выполняется только один пользовательский запрос. Пока запрос или служебное обращение к модели выполняется, новый запрос или правка из любого чата или вкладки отклоняется с сообщением «Модель занята». Очереди пользовательских запросов нет: отправьте запрос повторно после завершения текущего. Основная модель, суммаризация и названия чатов обращаются к провайдерам последовательно; во время паузы перед повтором блокировка сохраняется. Stop отменяет выполнение и ожидание повтора.
Обновление: pipx upgrade local-agent-chat или python -m pip install --upgrade local-agent-chat. Перед обновлением или переносом папки остановите процесс. Папку с .env, models.yaml и .local-agent-chat/ можно скопировать целиком и запустить в новом месте; относительные пути продолжат работать. Абсолютные пути нужно изменить отдельно. Два процесса не могут одновременно открыть один каталог данных, даже на разных портах.
Если запуск сообщает об отсутствующей конфигурации, выполните localchat init. По умолчанию сервер начинает с порта 8765; если он занят, пробует следующие до 65535. localchat run --port 9000 меняет начальный порт. Фактический порт показывается при запуске. Ошибки модели отображаются в UI и терминале; используйте endpoint с поддержкой tool calling и подходящим бюджетом контекста.
JupyterHub и VS Code proxy
В новом .env записывается APP_ROOT_PATH=auto. При наличии JUPYTERHUB_SERVICE_PREFIX сервер автоматически использует <prefix>/vscode/proxy/<фактический порт>. Вне JupyterHub префикс пустой, приложение открывается напрямую.
Также поддерживается точная запись:
APP_ROOT_PATH="${JUPYTERHUB_SERVICE_PREFIX%/}/vscode/proxy/$APP_PORT"
Этот шаблон раскрывается самим CLI после выбора свободного порта; без JupyterHub он даёт /vscode/proxy/<порт>. Остальные значения .env читаются буквально, shell-команды не выполняются. Явный --root-path /custom/path или статический путь в .env используется без замены порта. --root-path '' либо APP_ROOT_PATH='' отключает префикс даже в JupyterHub.
Открывайте UI по публичному адресу прокси. Прямой порт рассчитан на локальное использование; внешний доступ требует аутентификации прокси, см. Security.
Прежние системные каталоги автоматически не переносятся. Для старой установки используйте localchat run --config-dir ~/.config/localchat, сохранив прежний APP_DATA_DIR в её .env. Для перехода на локальную папку остановите сервис, скопируйте .env, models.yaml и содержимое прежнего каталога данных в .local-agent-chat/, затем задайте относительный APP_DATA_DIR. Пустой старый APP_ROOT_PATH сохраняет прямой запуск; замените его на auto для автоматического прокси.
./scripts/run.sh делегирует запуск Python CLI из текущей рабочей папки и больше не выполняет .env как shell-скрипт. Для совместимости можно задать ENV_FILE=/path/to/.env; для другого расположения используйте --config-dir. Запуск из исходников и проверки описаны в Contributing, выпуск — в инструкции публикации.
Контекст и лимиты
Параметры находятся в AgentConfig и могут задаваться через .env:
| Переменная | По умолчанию | Назначение |
|---|---|---|
AGENT_CONTEXT_TOKENS |
160000 | Бюджет окна с резервом под ответ и инструменты |
AGENT_SUMMARY_TRIGGER_TOKENS |
10000 | Порог суммаризации сообщений |
AGENT_KEEP_TOKENS |
3000 | Бюджет последних сообщений, сохраняемых дословно |
AGENT_SUMMARY_TOKENS |
1000 | Максимальный ответ модели суммаризации |
AGENT_MAX_OUTPUT_TOKENS |
128000 | Общий верхний предел ответа основной модели |
AGENT_MAX_MODEL_CALLS |
12 | Максимум обращений основной модели за один запрос |
Профиль модели задаёт max_tokens (по умолчанию 128000); фактический лимит ответа — меньшее из него и AGENT_MAX_OUTPUT_TOKENS. Суммаризация и названия чатов сохраняют отдельные небольшие лимиты: 1000 и 32 токена. max_tokens ограничивает ответ, а AGENT_CONTEXT_TOKENS — суммарное окно входа и ответа. Значения по умолчанию не описывают возможности конкретной модели: укажите пределы, поддерживаемые вашим endpoint, при необходимости уменьшив оба значения. Счётчик использует консервативную оценку для текста и tool calls. Конфигурация проверяет запас для ответа, сводки и схем инструментов.
Обновление пакета не перезаписывает существующие .env и models.yaml. Явно сохранённые старые значения продолжают действовать. Чтобы перейти на новые настройки, остановите приложение и задайте в профилях streaming: false, max_tokens: 128000, а в .env — AGENT_CONTEXT_TOKENS=160000, AGENT_MAX_OUTPUT_TOKENS=128000, LLM_MAX_RETRIES=10. Для профилей без streaming или max_tokens действуют новые значения по умолчанию.
Перед обращением к основной модели штатный SummarizationMiddleware заменяет старую часть контекста сводкой и сохраняет недавние сообщения, не разрывая tool-call/result пары. Предыдущая сводка включается в следующую. Длинный импортированный контекст суммируется порциями: старые сообщения не отбрасываются из-за стандартного лимита summarizer в 4000 токенов. Сводка не показывается как ответ пользователю и не заменяет полную историю UI.
В summary_options профиля можно передать параметры модели только для суммаризации. В примере OpenRouter reasoning выключен через extra_body.reasoning.enabled: false: иначе небольшой лимит ответа может целиком уйти на reasoning и оставить пустую сводку. См. параметры reasoning OpenRouter. Для другого провайдера задайте поддерживаемые им параметры. Лимиты ответа и streaming управляются агентом.
Пустая или обрезанная сводка, пустой ответ, ошибка модели и превышение бюджета последнего запроса завершают операцию с откатом. Слишком большой запрос следует разделить на части. Вывод одного файлового инструмента ограничен примерно 6000 символами; read_file поддерживает постраничное чтение, grep ищет буквальную строку.
Надёжность и хранение
Адаптеры OpenAI и GigaChat повторяют только отдельные запросы при временных сетевых ошибках, таймаутах и HTTP 408, 409, 429, 5xx. По умолчанию допускаются 10 повторов после первой попытки, всего до 11 обращений. Паузы: 1, 2, 4, 8, 16, 32, 64, 128, 256, 300 секунд. Пять минут — максимум одной паузы, а не общее время ожидания. Retry-After может увеличить паузу, но не выше 300 секунд. Ошибки авторизации, неверные параметры и другие постоянные ошибки завершают запрос сразу.
Настройки: LLM_MAX_RETRIES=10 (0 отключает HTTP-повторы), LLM_REQUEST_TIMEOUT_SECONDS=60, LLM_STREAM_CHUNK_TIMEOUT_SECONDS=120, LLM_STREAM_RETRIES=1, LLM_AUXILIARY_TIMEOUT_SECONDS=30. После первого фрагмента потоковый ответ не повторяется. Для потока, не выдавшего ни одного фрагмента до таймаута, действует отдельный бюджет LLM_STREAM_RETRIES с такой же экспоненциальной задержкой. Название чата ограничено общим таймаутом 30 секунд после получения доступа к модели, включая повторы. SDK-повторы отключены, поэтому скрытых вложенных повторов нет. Полный ход агента и выполненные инструменты не переигрываются; суммаризация использует ту же политику.
В APP_DATA_DIR находятся:
chainlit.sqlite3: сообщения, шаги инструментов, вложения, названия; постоянныйstepOrderсохраняет порядок даже при одинаковых временных метках.runtime-history.sqlite3: только актуальные завершённые запросы/ответы и ссылки на предшествующее состояние.checkpoints.sqlite3: выбор модели, текущий контекст и снимки контекста перед запросами. Граф ReAct между вызовами не хранит внутреннее состояние.sandboxes/: файлы и снимки файлов;blobs/: сохранённые вложения Chainlit.
Прежние чаты импортируются из актуальных запросов и ответов. Старые вызовы инструментов и внутренние графы не выполняются. Редактирование старого запроса восстанавливает предшествующую часть видимой истории. Старые режимы доступа исчезают; все чаты получают только чтение своей песочницы. Прежний индекс межчатового поиска удаляется, сохранённый memory/MEMORY.md больше не читается агентом. Внутренние старые LangGraph-таблицы могут оставаться в существующей базе как неиспользуемые данные.
UI принимает до 20 файлов по 100 MiB; объём активных файлов чата ограничен 1 GiB. Коллизии имён получают суффикс. Удаление чата удаляет его активные данные и снимки нового контекста.
Где менять код
| Задача | Файл |
|---|---|
| Сборка агента и цикл выполнения | local_agent_chat/agent_execution.py |
| Суммаризация и бюджет контекста | local_agent_chat/agent_context.py |
| Хранение контекста и откат | local_agent_chat/agent_memory.py |
| Четыре инструмента чтения | local_agent_chat/sandbox_tools.py |
| System prompt и заголовки | local_agent_chat/prompts.py |
| Настройки и provider retry | local_agent_chat/settings.py, local_agent_chat/llm_retry.py, local_agent_chat/providers.py |
| Координация истории и UI | local_agent_chat/runtime.py, local_agent_chat/chainlit_data.py, local_agent_chat/app.py |
Архитектура, термины, ограничения доступа, разработка, результаты проверок.
Metadata
Release files for local-agent-chat 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| local_agent_chat-0.2.0.tar.gz | 4.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| local_agent_chat-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.4 MB
Release files / local_agent_chat-0.2.0.tar.gz
| Download URL | local_agent_chat-0.2.0.tar.gz |
|---|---|
| Size | 4.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e78f192a7aa82e8f97553585c2744c81539a82c58204a8891b1914fa03b27fc7
|
|
BLAKE2b-256 checksum How to use checksums |
8c12f8ec5de84c5e09b39bc49d452f8c50d1c396d6df1c37cc3581352d02aa53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / local_agent_chat-0.2.0-py3-none-any.whl
| Download URL | local_agent_chat-0.2.0-py3-none-any.whl |
|---|---|
| Size | 4.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18f02f8a3fbeb8a59ae0e6c2dccfaafabb6ada771270dc83816688c03a421976
|
|
BLAKE2b-256 checksum How to use checksums |
d7d16bf30199300f626afd12ac862eeca0505ede5655c01c2eddc818948bbce6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log