Перейти к основному содержимому

Openhands

Делегирование кода OpenHands CLI (модельно-агностический, LiteLLM).

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

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

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

к сведению

Ниже приведено полное определение навыка, которое VibeOS загружает при активации этого навыка. Это то, что агент видит в качестве инструкций, когда навык активен.

OpenHands CLI

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

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

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

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

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

Предварительные требования​

  1. Установите upstream (требуется 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       # или любой слаг LiteLLM
    export LLM_API_KEY=$OPENROUTER_API_KEY
    export LLM_BASE_URL=https://openrouter.ai/api/v1 # опустите для native OpenAI

    LLM_MODEL использует полный слаг LiteLLM. Когда провайдером является OpenRouter, слаг имеет двойной префикс: openrouter/<vendor>/<model> (например, openrouter/anthropic/claude-sonnet-4.5). Для native Anthropic: anthropic/claude-sonnet-4-5. Для native 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 'Добавить обработку ошибок во все вызовы API в src/'",
workdir="/path/to/project",
timeout=600
)

Фоновый режим для длительных задач​

terminal(command="<то же, что выше>", 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: &lt;32-hex> и строку Hint: openhands --resume &lt;dashed-uuid&gt; в конце каждого запуска. Используйте форму с дефисами для возобновления:

terminal(
command="OPENHANDS_SUPPRESS_BANNER=1 LLM_MODEL=... openhands --headless --json --override-with-envs --exit-without-confirmation --resume <dashed-uuid> -t 'Теперь исправь найденную ошибку'",
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 и игнорирует env.
--exit-without-confirmationНе показывать диалог «вы уверены» при выходе.
--always-approve / --yoloАвтоматически одобрять каждое действие (по умолчанию в --headless).
--llm-approveШлюз безопасности на основе LLM (только интерактивный — НЕ работает в безголовом режиме).
--version / -vВывести версию и выйти.

Нет флагов --model, --max-iterations, --workspace, --sandbox, --sandbox-type. Модель — LLM_MODEL. Рабочая область — workdir, который вы передаёте инструменту terminal. Песочница / среда выполнения — переменные окружения 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 выводит предупреждения bedrock-runtime и sagemaker-runtime в stderr, потому что 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 зависает в ожидании первоначальной настройки.
  • Слаг модели — LiteLLM, а не провайдера. openrouter/openai/gpt-4o-mini работает; openai/gpt-4o-mini при указании на OpenRouter — нет. anthropic/claude-sonnet-4-5 (дефис) — native 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 нет.
  • Формат ID возобновления капризен. CLI завершается строкой Conversation ID: f46573d9cfdb45e492ca189bde40019b (без дефисов), а затем Hint: openhands --resume f46573d9-cfdb-45e4-92ca-189bde40019b (с дефисами). Используйте форму с дефисами.
  • Безголовый режим игнорирует --llm-approve. Если передать его, вы получите ошибку argparse. Безголовый режим жёстко кодирует always-approve.
  • Нет поддержки Windows в upstream. Документация OpenHands требует WSL на Windows. Этот навык соответственно ограничен [linux, macos].
  • ~/.openhands/conversations/&lt;id&gt;/ накапливается. Каждый запуск сохраняет траекторию. Очищайте, если запускаете пакетно.
  • Тяжёлая установка (~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 'Выведи строку OPENHANDS_OK в stdout через инструмент terminal.'",
workdir="/tmp",
timeout=120
)

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

Связанное​