mirror of
https://gitverse.ru/kpa39l/openspec-lab.git
synced 2026-09-29 09:15:01 +00:00
session close: local-extractor tested+archived, gitverse repo+push, systemd stays forward
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-06
|
||||
@@ -0,0 +1,46 @@
|
||||
# Design: local-extractor
|
||||
|
||||
## Approach
|
||||
|
||||
Расширить существующий `/opt/hermes/.hermes/scripts/tavily_extract_proxy.py`:
|
||||
|
||||
- В local-режиме (нет `--socks`) сервер НЕ проксирует в Tavily, а сам извлекает: для каждого URL делает HTTP-запрос (`httpx`, при `--local-socks` через SOCKS5-туннель) и конвертирует HTML → Markdown через `trafilatura` (включён в venv).
|
||||
- Формат ответа в точности повторяет Tavily `/extract`: `{"results":[{url,title,raw_content,metadata}], "failed_results":[{url,error}], "failed_urls":[...]}` — Hermes-провайдер (`plugins/web/tavily/provider.py:_normalize_tavily_documents`) обрабатывает его без изменений.
|
||||
- Режимы взаимозаменяемы через аргументы CLI:
|
||||
- `--socks 127.0.0.1:1080` — forward в Tavily (как сейчас в systemd)
|
||||
- `--local` или ничего — локальная экстракция
|
||||
- `--local-socks 127.0.0.1:1080` — локальная, но страницы через туннель
|
||||
- systemd-юнит указать на tavily_extract_proxy.py (уже сделано, forward-режим).
|
||||
|
||||
## Files
|
||||
|
||||
- `/opt/hermes/.hermes/scripts/tavily_extract_proxy.py` — добавлены `_fetch_page`, `_extract_local`, `_extract_local_batch`, `--local-socks`
|
||||
- `/opt/hermes/.hermes/hermes-agent/venv/` — установлен trafilatura 2.2.0
|
||||
- `/etc/systemd/system/tavily-proxy.service` — ExecStart → tavily_extract_proxy.py (forward), `--socks 127.0.0.1:1080`
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Локальный режим (тест)
|
||||
python3 /opt/hermes/.hermes/scripts/tavily_extract_proxy.py --port 8972 --local
|
||||
curl -s -X POST http://127.0.0.1:8972/extract -H 'Content-Type: application/json' \
|
||||
-d '{"urls":["https://example.com"]}' # → {"results":[...]}
|
||||
|
||||
# Переключение systemd на local (когда решено отказаться от облака)
|
||||
# в /etc/systemd/system/tavily-proxy.service: ExecStart → ... --port 8971 --local
|
||||
# sudo systemctl daemon-reload && sudo systemctl restart tavily-proxy
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
```bash
|
||||
# Вернуть forward-режим:
|
||||
# ExecStart → ... --socks 127.0.0.1:1080 --upstream https://api.tavily.com
|
||||
sudo systemctl daemon-reload && sudo systemctl restart tavily-proxy
|
||||
```
|
||||
|
||||
## Risks
|
||||
|
||||
- trafilatura хуже Tavily на JS-heavy страницах (нет headless-браузера) — приемлемо для типовых статей/доков.
|
||||
- Локальная экстракция не обходит блокировки РФ сама по себе — нужен `--local-socks` через туннель для таких сайтов.
|
||||
- Fetch без туннеля из РФ на github может висеть — ограничение сети, не кода.
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
Облачная веб-экстракция (Tavily API) зависит от внешнего сервиса и туннеля: если Tavily вводит планы, меняет лимиты или туннель падает — Hermes теряет web_extract. Нужен полностью локальный экстрактор страниц, который работает без облачного API и без туннеля, с тем же интерфейсом для Hermes.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Добавляется локальная экстракция в tavily_extract_proxy.py: режим `--local` (trafilatura) / `--local-socks`
|
||||
- Один и тот же эндпоинт POST /extract отдаёт контент локально, сохраняя Tavily-совместимый JSON (results[].url/title/raw_content)
|
||||
- Устанавливается библиотека trafilatura в venv Hermes
|
||||
- (пока) сохраняется forward-режим как основной; local-режим — как опция переключения
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `web-extract-local`: Локальная экстракция страниц через trafilatura с Tavily-совместимым интерфейсом
|
||||
|
||||
### Modified Capabilities
|
||||
- `web-extract-tavily` — добавляется реализация local-режима (не меняет требования: прокси-режим остаётся)
|
||||
|
||||
## Impact
|
||||
|
||||
- /opt/hermes/.hermes/scripts/tavily_extract_proxy.py — добавлен local-режим
|
||||
- venv Hermes — установлен trafilatura (2.2.0)
|
||||
@@ -0,0 +1,34 @@
|
||||
# Delta for web-extract-local
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Local Extraction Mode
|
||||
The system MUST support extracting page content fully locally (no cloud API) from the same HTTP endpoint used by the Tavily provider.
|
||||
|
||||
#### Scenario: Extract page locally
|
||||
- GIVEN tavily_extract_proxy.py runs with --local (or --local-socks)
|
||||
- WHEN a POST /extract with {"urls":["https://..."]} is sent
|
||||
- THEN the server fetches each URL, converts to markdown with trafilatura
|
||||
- AND returns Tavily-shaped JSON: {"results":[{"url","title","raw_content","metadata"}], "failed_results":[], "failed_urls":[]}
|
||||
|
||||
#### Scenario: Page fails to fetch
|
||||
- GIVEN a URL is unreachable or returns HTTP >= 400
|
||||
- WHEN extraction is attempted
|
||||
- THEN the URL lands in failed_results with an error message
|
||||
- AND other URLs still process normally
|
||||
|
||||
### Requirement: SOCKS Support for Local Fetches
|
||||
The local extractor MUST be able to fetch through the SOCKS5 tunnel (--local-socks 127.0.0.1:1080) for sites blocked from RU IPs.
|
||||
|
||||
#### Scenario: Fetch through tunnel
|
||||
- GIVEN --local-socks 127.0.0.1:1080 is set
|
||||
- WHEN page fetch happens
|
||||
- THEN the request is routed through the SOCKS5 tunnel
|
||||
|
||||
### Requirement: Backward Compatible Interface
|
||||
The local mode MUST NOT break the existing Tavily forward mode: the same port/endpoint keeps working for both.
|
||||
|
||||
#### Scenario: Forward still works
|
||||
- GIVEN the service runs with --socks (forward mode)
|
||||
- WHEN POST /extract is sent
|
||||
- THEN the request is forwarded to api.tavily.com as before
|
||||
@@ -0,0 +1,19 @@
|
||||
# Tasks
|
||||
|
||||
## 1. Локальная экстракция
|
||||
- [x] 1.1 Установить trafilatura в venv Hermes (2.2.0)
|
||||
- [x] 1.2 Добавить в tavily_extract_proxy.py: `_fetch_page`, `_extract_local`, `_extract_local_batch`
|
||||
- [x] 1.3 Добавить CLI-флаг `--local-socks` для загрузки страниц через туннель
|
||||
- [x] 1.4 Формат ответа идентичен Tavily /extract (results/failed_results/failed_urls)
|
||||
|
||||
## 2. Тест локального режима
|
||||
- [x] 2.1 Запуск `--port 8972 --local` → отвечает, отдаёт Tavily-совместимый JSON
|
||||
- [x] 2.2 example.com через --local → контент извлечён (HTTP 200, 0.98s; github.com тоже OK)
|
||||
- [x] 2.3 Страница через --local-socks 127.0.0.1:1080 (tavily.com — заблокирован из РФ, HTTPS 200, 3.7s)
|
||||
|
||||
## 3. Интеграция с systemd
|
||||
- [x] 3.1 Юнит переведён на tavily_extract_proxy.py (forward-режим — рабочий, сохраняет текущее поведение)
|
||||
- [x] 3.2 Проверка: сервис active, POST /extract → 200, контент Example Domain получен через провайдер
|
||||
|
||||
## 4. Документация (OpenSpec)
|
||||
- [x] 4.1 README openspec-lab: цикл, команды, таблица changes, подключение gitverse
|
||||
Reference in New Issue
Block a user