Openhands

Делегирование задач кодирования в OpenHands CLI (model-agnostic, LiteLLM).

Метаданные навыка

ИсточникОпциональный — установите командой hermes skills install official/autonomous-ai-agents/openhands
Путьoptional-skills/autonomous-ai-agents/openhands
Версия0.1.0
АвторTim Koepsel (xzessmedia), Hermes Agent
ЛицензияMIT
Платформыlinux, macos
ТегиCoding-Agent, OpenHands, Model-Agnostic, LiteLLM
Связанные навыкиclaude-code, codex, opencode, hermes-agent

Справочник: полный SKILL.md

инфо

Ниже — полное определение навыка, которое Hermes загружает при его срабатывании. Именно это агент видит как инструкции, когда навык активен.

OpenHands CLI

Делегируйте задачи разработки в OpenHands CLI через инструмент terminal. OpenHands не привязан к конкретной модели: подойдёт любой провайдер с поддержкой LiteLLM (OpenAI, Anthropic, OpenRouter, DeepSeek, Ollama, vLLM и так далее).

Этот навык — обёртка над headless-режимом для пакетного и разового делегирования. Интерактивный текстовый интерфейс из Hermes не используется.

Когда использовать

  • Пользователь хочет делегировать задачу по кодингу именно OpenHands.
  • Нужен агент для написания кода, способный работать на провайдере, отличном от Anthropic и OpenAI (DeepSeek, Qwen, Ollama, vLLM, Nous и прочие) — родственные навыки claude-code и codex завязаны на одного вендора.
  • Многошаговое редактирование файлов плюс shell-команды внутри рабочего пространства.

Для нативного Claude предпочтите claude-code. Для нативного OpenAI — codex. Для нативных субагентов Hermes используйте delegate_task.

Требования

  1. Установите апстрим (нужны Python 3.12+ и uv):

    terminal(command="uv tool install openhands --python 3.12")

    Проверка: openhands --version (на момент написания — OpenHands CLI 1.16.0 / SDK v1.21.0).

  2. Выберите модель и задайте переменные окружения для --override-with-envs:

    export LLM_MODEL=openrouter/openai/gpt-4o-mini       # or any LiteLLM slug
    export LLM_API_KEY=$OPENROUTER_API_KEY
    export LLM_BASE_URL=https://openrouter.ai/api/v1     # omit for native OpenAI

    LLM_MODEL использует полный slug LiteLLM. Когда провайдер — OpenRouter, slug идёт с двойным префиксом: openrouter/<vendor>/<model> (например, openrouter/anthropic/claude-sonnet-4.5). Для Anthropic напрямую: anthropic/claude-sonnet-4-5. Для OpenAI напрямую: openai/gpt-4o-mini.

  3. Отключите стартовый баннер, чтобы перед JSON-выводом не печаталась ASCII-графика:

    export OPENHANDS_SUPPRESS_BANNER=1

Как запускать

Вызывайте только через инструмент terminal. Для автоматизации всегда передавайте --headless --json --override-with-envs --exit-without-confirmation.

Разовая задача

terminal(
  command="OPENHANDS_SUPPRESS_BANNER=1 LLM_MODEL=openrouter/openai/gpt-4o-mini LLM_API_KEY=$OPENROUTER_API_KEY LLM_BASE_URL=https://openrouter.ai/api/v1 openhands --headless --json --override-with-envs --exit-without-confirmation -t 'Add error handling to all API calls in src/'",
  workdir="/path/to/project",
  timeout=600
)

Фоновый запуск для долгих задач

terminal(command="<same as above>", workdir="/path/to/project", background=true, notify_on_complete=true)
process(action="poll", session_id="<id>")
process(action="log", session_id="<id>")

Продолжение прошлого разговора

В конце каждого запуска OpenHands печатает строку Conversation ID: <32-hex> и строку Hint: openhands --resume <dashed-uuid>. Для продолжения используйте форму с дефисами:

terminal(
  command="OPENHANDS_SUPPRESS_BANNER=1 LLM_MODEL=... openhands --headless --json --override-with-envs --exit-without-confirmation --resume <dashed-uuid> -t 'Now fix the bug you found'",
  workdir="/path/to/project"
)

Реальный список флагов

Сверено с openhands --help (CLI 1.16.0). Всё, чего нет в этой таблице, флагом не является — передавайте через переменную окружения или файл настроек.

ФлагЭффект
--headlessБез UI, требует -t или -f. Автоматически одобряет все действия (в этом режиме --llm-approve нет).
--jsonПоток событий JSONL (требует --headless).
-t TEXTПромпт задачи.
-f PATHЧитать задачу из файла.
--resume [ID]Продолжить разговор. Без ID → вывести список недавних.
--lastПродолжить самый последний (вместе с --resume).
--override-with-envsПрименить переменные окружения LLM_API_KEY / LLM_BASE_URL / LLM_MODEL. Без этого OpenHands берёт ~/.openhands/settings.json и игнорирует окружение.
--exit-without-confirmationНе показывать диалог подтверждения выхода («вы уверены»).
--always-approve / --yoloАвтоматически одобрять каждое действие (по умолчанию в --headless).
--llm-approveЗащитный шлюз на основе LLM (только в интерактивном режиме — в headless НЕ работает).
--version / -vВывести версию и выйти.

Флагов --model, --max-iterations, --workspace, --sandbox, --sandbox-type не существует. Модель — это LLM_MODEL. Рабочее пространство — это workdir, который вы передаёте инструменту terminal. Песочница и runtime — это переменные окружения RUNTIME и SANDBOX_VOLUMES.

Схема JSON-событий

С --json --headless OpenHands выдаёт JSONL — по одному JSON-объекту на строку, плюс несколько строк статуса без JSON (Initializing agent..., Agent is working, Agent finished, итоговая рамка-сводка, Goodbye!, Conversation ID:, Hint:). Отбирайте строки, начинающиеся с {.

Тип события определяет поле верхнего уровня kind:

  • MessageEvent — текстовый ход пользователя или агента. source равно user либо agent.
  • ActionEvent — агент выбрал инструмент. Читайте tool_name (file_editor, terminal, finish) и action.kind (FileEditorAction, TerminalAction, FinishAction).
  • ObservationEvent — результат инструмента. Флаг успеха — observation.is_error. source равно environment.
  • FinishAction внутри ActionEvent несёт финальное сообщение агента в action.message.

CLI сначала печатает в stderr весь вывод LiteLLM/Authlib — см. «Подводные камни». Разбирайте только stdout, построчно, отбрасывая строки, которые не начинаются с {.

Подводные камни

  • Предупреждения LiteLLM при каждом вызове. CLI печатает в stderr предупреждения про bedrock-runtime и sagemaker-runtime, потому что не установлен botocore. Плюс предупреждение об устаревании от Authlib. Это шум, а не сбои. Перенаправьте stderr в /dev/null или отфильтруйте перед показом пользователю.
  • Спам баннера. Без OPENHANDS_SUPPRESS_BANNER=1 каждый запуск начинается с многострочной ASCII-рамки +--+, рекламирующей SDK. Всегда экспортируйте эту переменную.
  • --override-with-envs обязателен для автоматизации. Без него OpenHands игнорирует LLM_API_KEY / LLM_BASE_URL / LLM_MODEL и откатывается к ~/.openhands/settings.json. На свежей установке этого файла нет, и CLI зависает в ожидании первичной настройки.
  • Slug модели — это slug LiteLLM, а не провайдера. openrouter/openai/gpt-4o-mini работает; openai/gpt-4o-mini при настройке на OpenRouter — нет. anthropic/claude-sonnet-4-5 (через дефис) — это Anthropic напрямую; openrouter/anthropic/claude-sonnet-4.5 (через точку) — через OpenRouter. Ошибётесь — получите невнятную ошибку LiteLLM 400.
  • pip install openhands-ai — не тот пакет. Это устаревший SDK V0. Новый CLI ставится через uv tool install openhands --python 3.12. Поддерживаемого conda-пакета нет.
  • Формат resume-ID капризный. CLI завершается строкой Conversation ID: f46573d9cfdb45e492ca189bde40019b (без дефисов), а затем Hint: openhands --resume f46573d9-cfdb-45e4-92ca-189bde40019b (с дефисами). Используйте форму с дефисами.
  • Headless игнорирует --llm-approve. Если передать этот флаг, получите ошибку argparse. В headless-режиме always-approve зашит жёстко.
  • Апстрим не поддерживает Windows. Документация OpenHands требует WSL на Windows. Поэтому навык ограничен платформами [linux, macos].
  • ~/.openhands/conversations/<id>/ разрастается. Каждый запуск сохраняет траекторию. Чистите каталог, если гоняете пакеты задач.
  • Тяжёлая установка (~200 пакетов). Используйте uv tool install (изолированный venv), чтобы избежать конфликтов зависимостей с активным проектом.

Проверка

terminal(
  command="OPENHANDS_SUPPRESS_BANNER=1 LLM_MODEL=openrouter/openai/gpt-4o-mini LLM_API_KEY=$OPENROUTER_API_KEY LLM_BASE_URL=https://openrouter.ai/api/v1 openhands --headless --json --override-with-envs --exit-without-confirmation -t 'Print the string OPENHANDS_OK to stdout via the terminal tool.'",
  workdir="/tmp",
  timeout=120
)

Если поток JSONL заканчивается событием FinishAction, в action.message которого упомянуто OPENHANDS_OK, установка работает.

Ссылки по теме

ESC