diff --git a/dist/vision-subagent.skill b/dist/vision-subagent.skill index b078deb..c7abfdb 100644 Binary files a/dist/vision-subagent.skill and b/dist/vision-subagent.skill differ diff --git a/dist/web-search.skill b/dist/web-search.skill new file mode 100644 index 0000000..62d443c Binary files /dev/null and b/dist/web-search.skill differ diff --git a/skills/vision-subagent/SKILL.md b/skills/vision-subagent/SKILL.md index d2a4f70..8822178 100644 --- a/skills/vision-subagent/SKILL.md +++ b/skills/vision-subagent/SKILL.md @@ -1,20 +1,20 @@ --- name: vision-subagent author: ours -version: 0.1.0 +version: 0.2.0 description: > Use when you need to SEE an image (photo, screenshot, PCB render, diagram, picture file) but your model does not support images — e.g. a read tool result was omitted with "tool image omitted: model does not support images", or the user asks what is shown in a picture / asks you to look at a screenshot / render. Delegate the vision work to a vision-capable subagent - via the describe_image tool instead of guessing or saying you can't. + instead of guessing or saying you can't. --- # Vision Subagent Твоя модель не видит изображения — картинки выбрасываются из контекста. -Не угадывай содержимое и не отказывайся: делегируй зрение сабу с видящей моделью. +Не угадывай содержимое и не отказывайся: делегируй зрение видущему субагенту. ## Когда вызывать @@ -27,7 +27,9 @@ description: > ## Как вызывать -Вызови тул `describe_image`: +### Через тул `describe_image` (pi) + +Если у тебя доступен тул `describe_image`: ``` describe_image: @@ -35,8 +37,19 @@ describe_image: question: "точечный вопрос" # опционально ``` +### Через скрипт describe-image (Claude Code на deepseek и любой агент) + +Если тула нет — запусти субагента-скрипт через Bash: + +``` +node ~/projects/.common/lib/describe-image/describe-image.mjs --path "<абсолютный путь|URL>" [--question "точечный вопрос"] +``` + +Скрипт печатает в stdout описание от видящей модели — этот текст и есть +результат «зрения», верни его пользователю/в свой ответ. + Пример точечного вопроса: -`path: "C:\Users\vitya\Downloads\screen.png"`, `question: "Какое сообщение об ошибке в красной рамке сверху?"` +`node ~/projects/.common/lib/describe-image/describe-image.mjs --path "C:\Users\vitya\Downloads\screen.png" --question "Какое сообщение об ошибке в красной рамке сверху?"` ## Правила @@ -44,23 +57,29 @@ describe_image: если ты её не видел — это галлюцинация. 2. **Задавай точечные вопросы.** Не соглашайся на generic-описание, если тебе нужны конкретные детали (текст, координаты, цвета, что на заднем плане). - Если ответа не хватило — вызови `describe_image` ещё раз с уточнением. -3. **Если `describe_image` упал** (нет vision-модели, ошибка сети) — честно скажи - пользователю, что зрение сейчас недоступно, и предложи путь дальше - (например, переключить модель на видящую через `/model`). + Если ответа не хватило — вызови ещё раз с уточнением. +3. **Если зрение недоступно** (упал тул/скрипт: нет vision-модели, ошибка сети) — + честно скажи пользователю, что зрение сейчас недоступно, и предложи путь дальше. ## Настройка vision-модели Модель задаётся ЯВНО (по приоритету): -1. env `PI_VISION_MODEL` — например `routerai/minimax-m3` -2. файл `~/.pi/vision-model.json` — `{ "model": "routerai/minimax-m3" }` +1. env `PI_VISION_MODEL` — например `routerai/meta/muse-glimmer-30b` +2. файл `~/.pi/vision-model.json` — `{ "model": "routerai/meta/muse-glimmer-30b" }` -Авто-выбора нет — если модель не задана, `describe_image` вернёт ошибку с подсказкой. +Авто-выбора нет — если модель не задана, зрение вернёт ошибку с подсказкой. +Конфиг общий для pi и Claude Code (единый источник правды). -## Реализация тула +## Реализация -Тул `describe_image` — pi-расширение: -`~/projects/pi-extensions/extensions/vision-subagent.ts` (репо -`OpeItcLoc03/pi-extensions`, дом pi-расширений). Правки — в клоне репо → -`commit + push` → `just install` (затирает home-копию). Конфиг-example: -`~/projects/pi-extensions/config/vision-model.json.example`. +- **Скрипт (Claude Code / любой агент):** `~/projects/.common/lib/describe-image/describe-image.mjs` + — субагент на клиенте OpenAI API (пакет `openai`), зовёт routerai + (`https://routerai.ru/api/v1`). Модель — из `PI_VISION_MODEL`/`~/.pi/vision-model.json`, + ключ — `~/.pi/agent/auth.json` (провайдер и base URL — из префикса модели, напр. `routerai/…`). + **Формат картинки — стандартный OpenAI `image_url`** (`data:;base64,…`). + pi-legacy `{type:"image",data,mimeType}` routerai НЕ принимает (модель отвечает + «no image data») — не «чинить» обратно по комментарию в pi-расширении. +- **pi-расширение (тул `describe_image`):** `~/projects/pi-extensions/extensions/vision-subagent.ts` + (репо `OpeItcLoc03/pi-extensions`, дом pi-расширений). Правки — в клоне репо → + `commit + push` → `just install` (затирает home-копию). Конфиг-example: + `~/projects/pi-extensions/config/vision-model.json.example`. diff --git a/skills/web-search/SKILL.md b/skills/web-search/SKILL.md index 6d118ee..94034b3 100644 --- a/skills/web-search/SKILL.md +++ b/skills/web-search/SKILL.md @@ -1,25 +1,25 @@ --- name: web-search author: ours -version: 0.1.0 +version: 0.2.0 description: > Use when the user asks for fresh or external information — news, prices, versions, dates, current facts — or says «поищи», «найди актуальное», - "search for", "look up". Search the web via the `search_web` tool (a - search-capable model from llm-web-proxy with live citations) instead of - guessing from training data, refusing, or scraping by hand. Search is ON by - default — the agent decides when to call it; the user can turn it OFF for - the rest of the session by saying «без поиска» / "no search". + "search for", "look up". Search the web via a search-capable model from + llm-web-proxy with live citations (`search_web` tool or the `search-web` + script) instead of guessing from training data, refusing, or scraping by + hand. Search is ON by default — the agent decides when to call it; the user + can turn it OFF for the rest of the session by saying «без поиска» / "no search". --- # Web Search -Твоя основная модель не имеет веб-поиска. `search_web` — тул, который -отправляет запрос search-модели (веб-поиск DeepSeek с цитатами) на чистом -контексте и возвращает ответ с [1][2]-источниками. **Поиск включён по -умолчанию** — не отказывайся и не выдумывай, когда нужны свежие данные. +Твоя основная модель не имеет веб-поиска. Поиск идёт через search-модель +(веб-поиск DeepSeek с цитатами) на чистом контексте и возвращает ответ с +[1][2]-источниками. **Поиск включён по умолчанию** — не отказывайся и не +выдумывай, когда нужны свежие данные. -## Когда вызывать search_web +## Когда вызывать поиск - Юзер просит «поищи X», «найди актуальное про Y», "search for", "look up". - Вопрос про свежие/внешние данные: новости, цены, версии, даты релизов, @@ -30,17 +30,30 @@ description: > - Вопросы по коду/проекту, дизайн, рефакторинг — ответ в репо и контексте. - Уже загруженные доки/файлы сессии — не ищи то, что уже прочитано. -- **Юзер сказал «без поиска» в этой сессии** — тул не вызывать до конца сессии. +- **Юзер сказал «без поиска» в этой сессии** — поиск не вызывать до конца сессии. ## Как вызывать +### Через тул `search_web` (pi) + ``` search_web: query: "последняя версия Rust — что нового в релизе" ``` -Один запрос = **один вызов** тула. Не спамить серией поисков — если ответа -не хватило, уточни запрос один раз. +### Через скрипт search-web (Claude Code и любой агент) + +Если тула нет — запусти субагента-скрипт через Bash: + +``` +node ~/projects/.common/lib/search-web/search-web.mjs --query "последняя версия Rust — что нового в релизе" +``` + +Скрипт печатает в stdout ответ search-модели (с [1][2]-цитатами и списком +источников) — это и есть результат поиска. + +Один запрос = **один** вызов (тула/скрипта). Не спамить серией поисков — +если ответа не хватило, уточни запрос один раз. ## Правила ответа @@ -52,29 +65,40 @@ search_web: ## Механизм «без поиска» - **Default**: поиск включён — сам решаешь, когда нужны свежие данные. -- Юзер: «без поиска» / "no search" → **перестань вызывать search_web до конца +- Юзер: «без поиска» / "no search" → **перестань вызывать поиск до конца сессии**. Подтверди одной строкой. Не искать даже если запрос «поисковый». - Юзер снова: «поищи» → верни поиск (повторный грант, до конца сессии). - Следующая сессия — снова поиск включён (грант не переживает сессии). -## Ошибки тула +## Ошибки -`search_web failed: ...` — честно скажи юзеру, что поиск недоступен -(модель не настроена: `/search-status`, или сервер llm-web-proxy не запущен: -`lwp serve`), и предложи путь дальше. +`search_web failed: ...` (или ненулевой exit скрипта) — честно скажи юзеру, +что поиск недоступен (модель не настроена, или сервер llm-web-proxy не +запущен: `lwp serve`), и предложи путь дальше. ## Настройка -Search-модель (default `lwp/deepseek-pro-search-web`, pro-search): +Search-модель (default `lwp/deepseek-flash-search-web`): 1. env `PI_SEARCH_MODEL` — например `lwp/deepseek-flash-search-web` 2. файл `~/.pi/search-model.json` — `{ "model": "..." }` -Тул `search_web` — pi-расширение `~/projects/pi-extensions/extensions/search-web.ts` -(репо `OpeItcLoc03/pi-extensions`). Правки — commit + push → `just install` → `/reload`. +⚠️ `lwp/deepseek-pro-search-web` (pro-search, Expert Mode) живой поиск НЕ +выполняет — отвечает из обучения («unavailable in Expert Mode»). Рабочая — +flash-search (Instant Mode). Не «чинить» дефолт обратно на pro. + +## Реализация + +- **Скрипт (Claude Code / любой агент):** `~/projects/.common/lib/search-web/search-web.mjs` + — субагент на клиенте OpenAI API (пакет `openai`), зовёт локальный + llm-web-proxy (`http://127.0.0.1:8788/v1`, `stream:false`). Модель — из + `PI_SEARCH_MODEL`/`~/.pi/search-model.json`, ключ+baseUrl — из + `~/.pi/agent/models.json` → `providers["llm-web"]` (общий конфиг с pi). +- **pi-расширение (тул `search_web`):** `~/projects/pi-extensions/extensions/search-web.ts` + (репо `OpeItcLoc03/pi-extensions`). Правки — commit + push → `just install` → `/reload`. ## Out of scope -- НЕ автоматический поиск в каждом сообщении — тул зовётся, когда запрос +- НЕ автоматический поиск в каждом сообщении — поиск зовётся, когда запрос реально требует внешних данных. -- НЕ скрейпинг страниц (это browser-cdp): search_web ищет и отвечает с цитатами, +- НЕ скрейпинг страниц (это browser-cdp): поиск ищет и отвечает с цитатами, а не открывает конкретные URL.