aisha 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ *.py linguist-language=Pyhton
aisha-0.2.2/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .eggs/
5
+ build/
6
+ dist/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .venv/
10
+ venv/
11
+ *.log
@@ -0,0 +1 @@
1
+ *
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: ''
3
+ label: project
4
+ limit: 5000
5
+ read_only: false
6
+ ---
7
+
aisha-0.2.2/INSTALL.md ADDED
@@ -0,0 +1,246 @@
1
+ # Установка агента aisha
2
+
3
+ `aisha` — локальный консольный AI-агент на Python 3.11+. Он работает с внешним `llama-server` (llama.cpp) через OpenAI-совместимый API и не требует облачных LLM или API-ключей.
4
+
5
+ ## 1. Требования
6
+
7
+ - **OS:** Windows 11 (основная), также работает на других ОС, поддерживающих Python 3.11+
8
+ - **Python 3.11+** (включая `pip` и `venv`)
9
+ - **Запущенный `llama-server`** из llama.cpp с поддержкой OpenAI-compatible API
10
+ - **GGUF-модель** и, при необходимости, chat-template (jinja)
11
+
12
+ ## 2. Установка Python (если ещё нет)
13
+
14
+ Проверьте версию:
15
+
16
+ ```powershell
17
+ python --version
18
+ ```
19
+
20
+ Нужен `Python 3.11` или новее. Если Python отсутствует — установите его с https://www.python.org/downloads/ (обязательно отметьте «Add python.exe to PATH»).
21
+
22
+ ## 3. Установка aisha
23
+
24
+ Склонируйте или скопируйте репозиторий в рабочую директорию, затем из корня проекта:
25
+
26
+ ### Вариант 1: в текущее окружение Python
27
+
28
+ ```bash
29
+ pip install -e ".[dev]"
30
+ ```
31
+
32
+ `-e` (editable) устанавливает агент в режиме разработки: изменения в `src/` сразу подхватываются, а команда `aisha` доступна глобально. Dev-зависимости (pytest, ruff) ставятся вместе.
33
+
34
+ ### Вариант 2: изолированно через pipx
35
+
36
+ ```bash
37
+ pipx install .
38
+ ```
39
+
40
+ Изолирует агент и его зависимости от остального окружения. Команда `aisha` также доступна глобально.
41
+
42
+ > Примечание: зависимости проекта — `httpx`, `rich`, `prompt-toolkit`, `ddgs`, `beautifulsoup4`, `PyYAML`. Они ставятся автоматически.
43
+
44
+ ### Проверка установки
45
+
46
+ ```bash
47
+ aisha --help
48
+ ```
49
+
50
+ Должна отобразиться справка по команде.
51
+
52
+ ## 4. Установка и настройка llama-server
53
+
54
+ `aisha` не загружает модель сам — за него это делает внешний `llama-server`.
55
+
56
+ 1. Скачайте сборку llama.cpp (CUDA или CPU) с https://github.com/ggml-org/llama.cpp/releases.
57
+ 2. Скачайте GGUF-модель, например Qwen:
58
+ `d:\models\llama\qwen\Qwen3.5-9B-UD-Q4_K_XL.gguf`
59
+ 3. При необходимости подготовьте jinja chat-template:
60
+ `d:\models\llama\qwen\chat_template.jinja`
61
+
62
+ ### Запуск сервера
63
+
64
+ ```powershell
65
+ z:\llamacpp\cuda\llama-server.exe `
66
+ -m d:\models\llama\qwen\Qwen3.5-9B-UD-Q4_K_XL.gguf `
67
+ --no-mmproj `
68
+ --jinja `
69
+ --chat-template-file "d:\models\llama\qwen\chat_template.jinja" `
70
+ --tools all `
71
+ -c 65536 `
72
+ -fa on `
73
+ --fit off `
74
+ --load-mode mlock `
75
+ --host localhost `
76
+ --port 8088 `
77
+ -a Qwen3.5-9B-Q4_K_XL `
78
+ -ngl 99 `
79
+ -np 1 `
80
+ -t 8 `
81
+ -ctk q8_0 `
82
+ -ctv q8_0 `
83
+ -ub 1024 `
84
+ -lv 4
85
+ ```
86
+
87
+ Ключевые параметры для работы с `aisha`:
88
+
89
+ | Параметр | Значение | Назначение |
90
+ | --- | --- | --- |
91
+ | `--host localhost` | локальный доступ | безопаснее, чем `0.0.0.0` |
92
+ | `--port 8088` | порт агента по умолчанию | совпадает с дефолтом в конфиге |
93
+ | `--tools all` | tool calling | нативный OpenAI-style tool calling |
94
+ | `-a Qwen3.5-9B-Q4_K_XL` | alias модели | только подсказка для агента |
95
+ | `-c 65536` | контекст | должен совпадать с `context_window` в конфиге |
96
+
97
+ > Безопасность: не публикуйте `llama-server` в интернет. Без reverse proxy, аутентификации и ограничения доступа он должен слушать только `localhost`.
98
+
99
+ ### Проверка сервера
100
+
101
+ ```powershell
102
+ Invoke-RestMethod http://localhost:8088/health
103
+ ```
104
+
105
+ Ожидаемый ответ:
106
+
107
+ ```text
108
+ {"status":"ok"}
109
+ ```
110
+
111
+ ## 5. Конфигурация aisha
112
+
113
+ Агент работает с настройками по умолчанию сразу после установки, но для удобства можно создать глобальный конфиг.
114
+
115
+ ### Глобальная конфигурация
116
+
117
+ Файл: `%USERPROFILE%\.aisha\config.toml`
118
+
119
+ ```toml
120
+ [server]
121
+ base_url = "http://localhost:8088"
122
+ model = "Qwen3.5-9B-Q4_K_XL"
123
+ connect_timeout = 5
124
+ request_timeout = 600
125
+
126
+ [llm]
127
+ temperature = 0.6
128
+ max_output_tokens = 65536
129
+ context_window = 65536
130
+ context_soft_limit = 0.85
131
+ max_tool_iterations = 25
132
+
133
+ [tools]
134
+ shell = true
135
+ web_search = true
136
+ permission = "ask"
137
+ shell_type = "powershell"
138
+ shell_timeout = 120
139
+ max_output_chars = 65536
140
+ allow_read_outside_workspace = false
141
+ allow_write_outside_workspace = false
142
+
143
+ [web]
144
+ timeout = 20
145
+ max_results = 8
146
+ max_page_bytes = 2097152
147
+ max_content_chars = 50000
148
+ allow_private_hosts = false
149
+
150
+ [memory]
151
+ enabled = true
152
+ max_block_chars = 30000
153
+
154
+ [ui]
155
+ theme = "dark"
156
+ stream = true
157
+ show_reasoning = false
158
+ debug = false
159
+ ```
160
+
161
+ > Имя модели в конфиге — только подсказка. Если объявленное имя не совпадает с `-a` на сервере, `aisha` автоматически подключается к первой доступной модели и не падает.
162
+
163
+ ### Проектная конфигурация
164
+
165
+ Файл `<workspace>/aisha.toml` переопределяет глобальные настройки для конкретного проекта. Он **не может ослабить безопасность**: `permission = "auto"`, чтение/запись за пределами workspace и т.п. приводят к ошибке конфигурации.
166
+
167
+ ### Приоритет настроек
168
+
169
+ 1. Аргументы командной строки
170
+ 2. Переменные окружения (`AISHA_SERVER_URL`, `AISHA_MODEL`, `AISHA_PERMISSION`, `AISHA_SHELL`, `AISHA_CONTEXT_WINDOW`, `AISHA_MAX_OUTPUT_TOKENS`)
171
+ 3. Проектный `aisha.toml`
172
+ 4. Глобальный `~/.aisha/config.toml`
173
+ 5. Значения по умолчанию
174
+
175
+ ## 6. Диагностика
176
+
177
+ Проверка соединения с сервером и доступности модели:
178
+
179
+ ```bash
180
+ aisha --doctor
181
+ ```
182
+
183
+ Расширенная проверка tool calling (отправляет безопасный тестовый запрос без shell-команд и записи файлов):
184
+
185
+ ```bash
186
+ aisha --doctor --tool-call-test
187
+ ```
188
+
189
+ ## 7. Первый запуск
190
+
191
+ Из любой рабочей директории:
192
+
193
+ ```bash
194
+ aisha
195
+ ```
196
+
197
+ Откроется интерактивный REPL. Полезные команды: `/status` — сервер, модель, workspace, токены; `/help` — справка.
198
+
199
+ Одноразовый запрос:
200
+
201
+ ```bash
202
+ aisha "Объясни структуру этого проекта"
203
+ ```
204
+
205
+ Другие полезные флаги:
206
+
207
+ ```bash
208
+ aisha --server http://localhost:8088 # другой llama-server
209
+ aisha --model Qwen3.5-9B-Q4_K_XL # переопределение модели
210
+ aisha -r # режим только для чтения
211
+ aisha --permission deny # запрет shell-команд
212
+ aisha --permission auto # выполнять разрешённые команды без подтверждения
213
+ aisha --shell cmd # cmd вместо PowerShell
214
+ aisha --tools-only # список доступных инструментов
215
+ ```
216
+
217
+ ## 8. Обновление
218
+
219
+ Обновите код из репозитория и переустановите пакет:
220
+
221
+ ```bash
222
+ pip install -e ".[dev]" --upgrade
223
+ ```
224
+
225
+ Для pipx:
226
+
227
+ ```bash
228
+ pipx upgrade aisha
229
+ ```
230
+
231
+ ## 9. Устранение неполадок
232
+
233
+ | Симптом | Решение |
234
+ | --- | --- |
235
+ | `ServerUnavailableError` при старте REPL | `llama-server` не запущен или недоступен. Проверьте `http://localhost:8088/health`. |
236
+ | Модель ещё загружается | Подождите, пока `llama-server` не загрузит GGUF, затем повторите `aisha --doctor`. |
237
+ | Ошибка конфигурации из `aisha.toml` | Проектный конфиг не может ослаблять безопасность — переместите такие настройки в глобальный `config.toml` или передайте флагом CLI. |
238
+ | Команда `aisha` не найдена | Переустановите пакет (`pip install -e .`) или проверьте, что каталог Scripts Python в PATH. |
239
+ | `permission = "ask"` мешает | Запустите с `--permission auto` или задайте `AISHA_PERMISSION=auto`. |
240
+
241
+ ## 10. Тестирование и проверка кода (разработка)
242
+
243
+ ```bash
244
+ python -m pytest tests/ -q # тесты (не требуют llama-server)
245
+ ruff check src/ tests/ # линт
246
+ ```
aisha-0.2.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alex Tisch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
aisha-0.2.2/PKG-INFO ADDED
@@ -0,0 +1,294 @@
1
+ Metadata-Version: 2.5
2
+ Name: aisha
3
+ Version: 0.2.2
4
+ Summary: Local console AI agent for working with source code, files, CLI and internet
5
+ Project-URL: Homepage, https://github.com/cruide/aisha
6
+ Project-URL: Website, https://alex-tisch.ru
7
+ Author-email: Tischenko Alexander <info@alex-tisch.ru>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Natural Language :: Russian
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development
21
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: beautifulsoup4>=4.12
24
+ Requires-Dist: ddgs>=9.0
25
+ Requires-Dist: httpx>=0.27
26
+ Requires-Dist: prompt-toolkit>=3.0
27
+ Requires-Dist: pyyaml>=6.0
28
+ Requires-Dist: rich>=13.7
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.6; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # aisha
36
+
37
+ Локальный консольный AI-агент на Python 3.11+. Работает с внешним
38
+ [llama-server](https://github.com/ggml-org/llama.cpp) (llama.cpp) по
39
+ OpenAI-совместимому REST API. Это **не веб-приложение**: вся логика — цикл
40
+ «запрос модели → вызовы инструментов → результаты → снова модель» в одном процессе.
41
+
42
+ Версия: `0.2.2`.
43
+
44
+ ## Возможности
45
+
46
+ - **Файлы** — чтение, запись, точечное редактирование, листинг, `glob`-поиск и `grep`;
47
+ - **Shell** — запуск команд (`powershell`/`cmd`/`sh`), таймауты, обрезка вывода, подтверждение опасных команд;
48
+ - **Веб** — поиск DuckDuckGo и загрузка страниц с SSRF-защитой;
49
+ - **Память** — постоянные блоки (глобальные и проектные) с приоритетом проекта;
50
+ - **Скиллы** — переиспользуемые инструкции в `SKILL.md`;
51
+ - **Многошаговые задачи** — todo-список и уточняющие вопросы к пользователю;
52
+ - **Нативный tool calling** — модель сама вызывает инструменты через API;
53
+ - **Авто-сжатие истории** при приближении к лимиту контекста;
54
+ - **Два режима** — one-shot (передан промпт) и интерактивный REPL.
55
+
56
+ ## Требования
57
+
58
+ - Python **3.11+**;
59
+ - запущенный **llama-server** (llama.cpp) с поддержкой OpenAI-совместимого API и tool calling.
60
+
61
+ ## Установка
62
+
63
+ ```bash
64
+ pip install -e ".[dev]" # src-layout: без этого пакет `aisha` не импортируется
65
+ ```
66
+
67
+ Точка входа — `aisha = "aisha.cli:main"` (см. `pyproject.toml`).
68
+
69
+ ## Запуск llama-server
70
+
71
+ Перед использованием нужно поднять сервер, например:
72
+
73
+ ```bash
74
+ llama-server \
75
+ --model ./models/Qwen3.5-9B-Q4_K_XL.gguf \
76
+ --port 8088 \
77
+ --n-gpu-layers 99
78
+ ```
79
+
80
+ По умолчанию aisha ждёт сервер на `http://localhost:8088`. Проверить подключение:
81
+
82
+ ```bash
83
+ aisha --doctor
84
+ ```
85
+
86
+ ## Быстрый старт
87
+
88
+ ```bash
89
+ aisha "объясни, что делает этот проект" # one-shot: один запрос и выход
90
+ aisha # без аргументов — интерактивный REPL
91
+ python -m aisha ... # эквивалентный вызов
92
+ ```
93
+
94
+ ## CLI
95
+
96
+ ```
97
+ aisha [промпт...] [флаги]
98
+ ```
99
+
100
+ | Флаг | Описание |
101
+ |---|---|
102
+ | `prompt` (позиционный) | запрос; без него запускается REPL |
103
+ | `--server URL` | адрес llama-server (по умолч. `http://localhost:8088`) |
104
+ | `--model NAME` | имя модели на сервере |
105
+ | `--api-key KEY` | API-ключ для сервера (если требуется авторизация) |
106
+ | `-r`, `--read-only` | режим только для чтения (только безопасные инструменты) |
107
+ | `--permission auto\|ask\|deny` | режим запуска shell-команд |
108
+ | `--shell powershell\|cmd` | оболочка по умолчанию |
109
+ | `--tools-only` | показать список инструментов и выйти |
110
+ | `--doctor` | диагностика подключения к серверу |
111
+ | `--tool-call-test` | вместе с `--doctor`: проверить tool calling |
112
+ | `--no-color` | отключить цвета |
113
+ | `--debug` | режим отладки: reasoning модели, дампы запросов/ответов, traceback |
114
+ | `--version` | показать версию |
115
+
116
+ ## Конфигурация
117
+
118
+ Приоритет (каждый слой глубоко сливается с предыдущим):
119
+
120
+ ```
121
+ DEFAULTS ← ~/.aisha/config.toml ← <workspace>/aisha.toml ← env AISHA_* ← CLI-флаги
122
+ ```
123
+
124
+ Полный пример `~/.aisha/config.toml`:
125
+
126
+ ```toml
127
+ [server]
128
+ base_url = "http://localhost:8088"
129
+ model = "Qwen3.5-9B-Q4_K_XL"
130
+ api_key = "" # необязательно; если сервер требует авторизацию (Bearer)
131
+ connect_timeout = 5.0
132
+ request_timeout = 600.0
133
+
134
+ [llm]
135
+ temperature = 0.6
136
+ top_p = 0.9 # необязательно; None = не передавать (используется серверный умолчание)
137
+ top_k = 40 # необязательно; целое > 0
138
+ repeat_penalty = 1.1 # необязательно; > 0
139
+ frequency_penalty = 0.0 # необязательно; -2.0 .. 2.0
140
+ max_output_tokens = 32768
141
+ context_window = 32768
142
+ context_soft_limit = 0.85
143
+ max_tool_iterations = 25
144
+ tool_guide = false # true — добавить «Справочник инструментов» в системный промпт (для слабых моделей)
145
+
146
+ [tools]
147
+ shell = true
148
+ web_search = true
149
+ permission = "ask" # auto | ask | deny
150
+ shell_type = "powershell"
151
+ shell_timeout = 120
152
+ max_output_chars = 65536
153
+ allow_read_outside_workspace = false
154
+ allow_write_outside_workspace = false
155
+
156
+ [web]
157
+ timeout = 20
158
+ max_results = 8
159
+ max_page_bytes = 2097152
160
+ max_content_chars = 50000
161
+ allow_private_hosts = false
162
+
163
+ [memory]
164
+ enabled = true
165
+ max_block_chars = 30000
166
+
167
+ [ui]
168
+ theme = "dark"
169
+ stream = true
170
+ show_reasoning = false
171
+ debug = false # true — то же, что --debug: reasoning + дампы запросов/ответов
172
+ input_history = "~/.aisha/input_history.txt"
173
+ ```
174
+
175
+ Переменные окружения:
176
+
177
+ | Переменная | Куда |
178
+ |---|---|
179
+ | `AISHA_SERVER_URL` | `server.base_url` |
180
+ | `AISHA_MODEL` | `server.model` |
181
+ | `AISHA_API_KEY` | `server.api_key` |
182
+ | `AISHA_PERMISSION` | `tools.permission` |
183
+ | `AISHA_SHELL` | `tools.shell_type` |
184
+ | `AISHA_CONTEXT_WINDOW` | `llm.context_window` |
185
+ | `AISHA_MAX_OUTPUT_TOKENS` | `llm.max_output_tokens` |
186
+
187
+ Конфиг строго валидируется: неизвестная секция или ключ вызывает ошибку.
188
+ **Проектный `aisha.toml` ограничен в правах безопасности** — он не может ставить
189
+ `permission = "auto"`, включать доступ за пределы workspace или включать `shell`,
190
+ если тот отключён глобально. Это защита от «троянского» конфига в склонированном репозитории.
191
+
192
+ ## Инструменты
193
+
194
+ | Инструмент | Read-only | Назначение |
195
+ |---|---|---|
196
+ | `read_file` | да | чтение файла UTF-8 с offset/limit |
197
+ | `write_file` | нет | создание/перезапись (атомарно) |
198
+ | `edit_file` | нет | точная замена фрагмента текста |
199
+ | `list_dir` | да | содержимое каталога |
200
+ | `glob` | да | поиск файлов по маске |
201
+ | `grep` | да | regex-поиск по содержимому |
202
+ | `run_command` | нет | запуск shell-команды |
203
+ | `web_search` | да | поиск DuckDuckGo |
204
+ | `web_fetch` | да | загрузка веб-страницы |
205
+ | `todowrite` | да | полная замена todo-списка сессии |
206
+ | `ask_user` | да | уточняющий вопрос (только в REPL) |
207
+ | `memory_list` / `memory_get` | да | список/чтение блоков памяти |
208
+ | `memory_set` / `memory_replace` | нет | запись/правка блоков памяти |
209
+ | `skill` | да | загрузить текст скилла по имени |
210
+
211
+ Файловые инструменты не выходят за пределы workspace (path-traversal блокируется),
212
+ если не включён соответствующий `allow_*_outside_workspace`.
213
+
214
+ ## Память и скиллы
215
+
216
+ - **Память** — JSON-блоки в `~/.aisha/memory/` (глобально) и `<workspace>/.aisha/memory/`
217
+ (проектно). Проектный блок перекрывает глобальный с тем же `label`.
218
+ Вызов `memory_get` не выводится в консоль (это фоновое чтение собственной памяти агента).
219
+ - **Скиллы** — каталоги `~/.aisha/skills/<name>/SKILL.md` и
220
+ `<workspace>/.aisha/skills/<name>/SKILL.md` с обязательным YAML-frontmatter
221
+ (`name`, `description`).
222
+
223
+ ## Кастомный системный промпт (SYSTEM.md)
224
+
225
+ Если в корне проекта есть файл `<workspace>/.aisha/SYSTEM.md`, его содержимое
226
+ **полностью заменяет** встроенный системный промпт aisha (persona, окружение, правила,
227
+ секции памяти и скиллов). При этом «Справочник инструментов» (`tool_guide = true`),
228
+ `AGENTS.md` и текущий todo-список по-прежнему добавляются после него. Файл обрезается
229
+ до 64 КБ, как и `AGENTS.md`.
230
+
231
+ ## REPL
232
+
233
+ Команды внутри интерактивного режима:
234
+
235
+ | Команда | Действие |
236
+ |---|---|
237
+ | `/help` | справка |
238
+ | `/new` | новая сессия (сброс истории) |
239
+ | `/status` | сервер, модель, workspace, режим, токены |
240
+ | `/tools` | список инструментов |
241
+ | `/skills` | индекс скиллов |
242
+ | `/memory` | блоки памяти |
243
+ | `/compact` | принудительное сжатие истории |
244
+ | `/doctor` | проверка соединения |
245
+ | `/init` | изучить проект и создать `AGENTS.md` |
246
+ | `/clear` | очистка экрана |
247
+ | `/quit`, `/exit`, `Ctrl+D` | выход |
248
+
249
+ Дополнительно: `Ctrl+C` отменяет текущий запрос (REPL не завершается),
250
+ `Ctrl+↑/↓` — история запросов, `Tab` — автодополнение команд и путей.
251
+
252
+ ## Безопасность
253
+
254
+ - Запуск shell-команд в режиме `permission = "ask"` требует подтверждения;
255
+ опасные команды (`rm -rf`, `Remove-Item -Recurse`, `git reset --hard` и т.п.)
256
+ подтверждаются всегда.
257
+ - `web_fetch` блокирует private/localhost/loopback-адреса (SSRF-защита), если не
258
+ включён `web.allow_private_hosts`.
259
+ - `find_danger` в `shell.py` — **эвристика по regex, а не песочница**: обойти её можно.
260
+ Не запускайте aisha от имени пользователя с повышенными правами в недоверенном окружении.
261
+
262
+ ## Разработка
263
+
264
+ ```bash
265
+ pip install -e ".[dev]"
266
+
267
+ pytest # весь набор; реальный сервер не нужен
268
+ pytest tests/test_config.py # один тест
269
+
270
+ ruff check . # линт (E, F, I, W; line-length 100)
271
+ ```
272
+
273
+ Тесты не ходят в реальный сервер: `test_client.py` подменяет транспорт
274
+ `httpx.MockTransport`, конфиг-тесты подменяют `Path.home`.
275
+
276
+ ## Структура проекта
277
+
278
+ ```
279
+ src/aisha/
280
+ ├── cli.py # entry point: args → config → registry → client → AgentLoop → UI
281
+ ├── client.py # async SSE-клиент к llama-server, ретраи, tool-call сборка
282
+ ├── agent.py # AgentLoop: цикл модель↔инструменты, компакция
283
+ ├── context.py # системный промпт, история, оценка токенов
284
+ ├── config.py # конфигурация, валидация, безопасность
285
+ ├── memory.py # постоянная память (блоки)
286
+ ├── skills.py # скиллы (SKILL.md)
287
+ ├── ui.py # ConsoleUI: rich + prompt_toolkit, REPL
288
+ ├── fsutil.py # атомарная запись, проверка путей, human_size
289
+ ├── errors.py # иерархия исключений
290
+ └── tools/ # реализации инструментов (base, files, shell, web, extras)
291
+ ```
292
+
293
+ Подробную картину по модулям, неочевидным решениям и «граблям» см. в
294
+ [`PROJECT.md`](PROJECT.md).