개요

OpenArms를 받아 개발·테스트 환경을 세우고 첫 연결까지 가는 과정입니다. 의존성의 권위는 코드 메타데이터(pyproject.toml·requirements-dev.txt)이고, 이 장은 그 위의 사람용 안내입니다.

요구 사항은 Python 3.9 이상입니다(requires-python = ">=3.9"). 라이브 전경 실행석은 현재 tmux를 backend로 쓰므로, tmux가 자연히 도는 macOS·Linux·WSL2를 권합니다(Windows 네이티브는 비주력입니다).

이 장 뒤로 메시징 플랫폼(텔레그램 연결), 연동(프로바이더 CLI), OpenArms 사용(PM 운용 루프)으로 이어집니다.

환경별 설치

macOS · Linux

python3 -m [venv](https://docs.python.org/3/library/venv.html) .venv && source .venv/bin/activate
pip install -e ".[dev]"
python3 scripts/dev_preflight.py               # 의존성 점검(설치·네트워크 없이 import만)
PYTHONIOENCODING=utf-8 python3 -m pytest -q

라이브 전경 실행석으로는 tmux를 씁니다.

Windows (WSL2 권장)

Windows에서는 WSL2 안에서 위 macOS·Linux 단계를 그대로 따릅니다. 프로젝트 파일은 Windows 드라이브 마운트 가 아니라 WSL2 네이티브 홈(~/)에 두는 편이 파일 입출력에 유리합니다. Windows 네이티브의 hermes venv는 지원 테스트 러너가 아닙니다 — pytest·[telethon](https://docs.telethon.dev/)이 없어 수집 자체가 되지 않습니다.

서버 (헤드리스 Linux)

서버에서도 같은 venv·pip 단계를 따릅니다. tmux가 전경 실행석이 되고, 메신저 연결은 환경 변수로 둡니다. 다만 현재 라이브 운영의 실증 권위 경로는 GUI 확인(Windows GUI + Mac VM 전경) 조합이라, 완전 헤드리스 운영은 사용자가 명명할 분화 버전 목표입니다.


이 장이 다루는 도구·서비스 — 선택 근거·구성·훅

아래는 빠른 시작에서 이름이 나오는 모든 도구/서비스에 대해, 왜 골랐는지 · 어떻게 붙이는지 · 배포판에서 훅을 어떻게 쓰는지를 한 항목씩 적은 것입니다. 이름만 흘리지 않고 실제 구성까지 내려갑니다.

venv (Python 가상환경)

왜 이걸 골랐나. OpenArms 코어는 의존성이 얇습니다 — 런타임은 telethon·[jsonschema](https://json-schema.org/) 둘, 개발은 거기에 pytest·build 정도입니다. 이 정도 표면에서는 표준 라이브러리에 들어 있는 venv로 충분하고, 추가 도구를 강제하지 않는 게 기여자 진입 장벽을 가장 낮춥니다. pip install -e ".[dev]"editable 설치가 핵심 근거입니다 — 소스 트리를 그대로 import 경로로 노출하므로, 라이브 VM 런타임이 쓰는 PYTHONPATH=<repo root> 실행 모델과 dev 환경이 동일해집니다. scripts.<module>이 PEP 420 namespace 패키지로 같은 방식으로 풀리는 것도 이 editable 설치 덕입니다.

대안 대비. [uv](https://docs.astral.sh/uv/)는 venv 생성이 venv보다 대략 200배 빠르고 uv.lock으로 재현성을 잠가 줍니다. 빠른 반복이 필요하면 uv venv && uv pip install -e ".[dev]"로 그대로 드롭인됩니다 — 코어가 pip 호환 인터페이스만 요구하므로 구조 변경 없이 속도만 얻습니다. 다만 OpenArms는 권위를 pyproject.toml/requirements-dev.txt에 두지, lock 파일을 강제하지 않습니다. conda는 이 의존성 폭에 과합니다.

어떻게 구성하나. 위 명령 그대로입니다. 단, 인터프리터 일관성이 함정입니다 — 테스트는 **WSL/Linux/macOS의 python3**로 레포 루트에서 돌립니다. Windows hermes-agent venv (...\hermes\hermes-agent\venv\Scripts\python.exe)는 pytest/telethon이 없어 지원 러너가 아닙니다. 그래서 설치 직후 scripts/dev_preflight.py그 인터프리터로 한 번 돌려 PASS/MISSING을 확인합니다(import-only 검사, 설치·네트워크 없음, 필수 누락 시 비-0 종료).

배포판 훅 연동. venv 자체엔 훅이 없지만, 프로바이더 플러그인은 레포 에 설치됩니다 (예: ~/.hermes/hermes-agent/plugins/openarms_contract_bridge). 그 위치에서 import openarms가 풀리도록 부트스트랩이 OPENARMS_ROOT 환경변수 → ~/openarms → 체크아웃 부모 순서로 레포 루트를 sys.path에 넣습니다. 배포 시 venv를 만들었으면 OPENARMS_ROOT를 그 체크아웃으로 가리키게 두는 것이 가장 안전한 한 줄입니다.

export OPENARMS_ROOT="$HOME/openarms"   # 플러그인이 레포 밖에서도 openarms를 import

tmux (전경 실행석 backend)

왜 이걸 골랐나. tmux는 OpenArms의 공식 base 의존성이자 통합 실행석(seat) substrate 입니다. 프로바이더 CLI(Hermes/AGY/Claude)는 사람처럼 대화형으로 살아 있어야 하는데, tmux의 detached 세션은 터미널이 안 붙어 있어도 프로세스가 계속 돌고, send-keys로 보이지 않는 pane에도 입력을 넣고, capture-pane으로 출력을 읽어옵니다. HTTP 데몬을 새로 띄우는 대신 잘 검증된 안정 API 위에 좌석을 올리는 선택입니다. @fg/@bg 토글과 좌석 매니저가 모두 tmux 바이너리를 전제합니다.

대안 대비. 세션 영속성과 프로그램 제어, 출력 캡처를 한 번에 주는 도구로 tmux는 사실상 표준이고 문서·이식성이 가장 좋습니다. 신생 cmux 류는 macOS 네이티브 앱이라 이식성이 약하고, 원시 pty/ssh 직접 제어는 재연결·버퍼·diff를 직접 구현해야 합니다. 그래서 0.0.2.x는 tmux를 backend로 굳혔습니다 — 단, 제품 정체성이 아니라 현재 구현의 backend라서, 이후 execution_seat를 tmux/pty/ssh/windows-terminal/provider-native로 추상화할 방향입니다.

어떻게 구성하나. tmux 바이너리 해석은 한 곳(openarms.runtime_config.tmux_bin)에서 일어나며 우선순위가 OPENARMS_TMUX_BIN(명시) > which tmux(PATH) > Homebrew 폴백 > 맨 tmux입니다. 설치 점검은 openarms.tmux_runtime.require_tmuxtmux -V로 하되 절대 예외를 던지지 않습니다(tmux 없는 CI 박스에서도 리스너는 import·실행돼야 함). 없으면 안내가 나옵니다: “tmux를 설치하거나 OPENARMS_TMUX_BIN 환경변수를 설정하세요.”

export OPENARMS_TMUX_BIN="$(which tmux)"   # 비표준 경로일 때만 명시
tmux new-session -d -s pm-hermes           # detached 좌석(예시)

배포판 훅 연동. Hermes 플러그인 매니페스트(plugin.yaml)는 requires_envOPENARMS_TMUX_BIN을 선언합니다. 라우트 실행기를 켜면(OPENARMS_HERMES_ROUTE_EXECUTOR=tmux) pre_gateway_dispatch 훅이 선언된 전경 tmux pane으로 그 턴을 제출합니다. 즉 배포판에서 tmux는 “있으면 좋은 것”이 아니라 훅이 실제로 의존하는 좌석입니다.

telethon (Telegram MTProto 클라이언트)

왜 이걸 골랐나. 텔레그램이 현재 1차 메신저 어댑터이고, OpenArms는 답변만이 아니라 사용자 계정 컨텍스트(방 기억 캡처, 사용자 말풍선 미러)가 필요합니다. 사용자 계정은 반드시 MTProto로만 접근할 수 있고, telethon이 그 순수 Python MTProto 구현입니다. MTProto는 텔레그램 서버에 TCP로 직접 붙어 HTTP 폴링·웹훅이 없어 오버헤드가 작고, Bot API의 다운로드 20MiB / 업로드 50MiB 한도 대신 최대 2GiB까지 다룹니다. 봇과 사용자 두 경로를 한 라이브러리로 처리할 수 있는 것도 채택 이유입니다.

대안 대비. 순수 봇 워크플로면 Bot API 래퍼로 족하지만, OpenArms가 요구하는 사용자측 말풍선·방 히스토리·미러링은 Bot API로는 불가능합니다. 그래서 telethon으로 통일합니다. 버전은 Python 3.9를 지원하는 보수적 하한 telethon>=1.24,<2로 고정합니다(플러그인 측은 >=1.36).

어떻게 구성하나. 네 값이 함께 있어야 MTProto 미러가 켜집니다 — TELEGRAM_API_ID·TELEGRAM_API_HASH(https://my.telegram.org 에서 발급), 그리고 미러링 계정의 StringSession(OPENARMS_TELEGRAM_USER_SESSION)입니다. StringSession은 세션 데이터를 Base64로 직렬화한 이식 가능한 인증 토큰이라 서버·컨테이너로 그대로 옮길 수 있습니다. 봇만 쓸 거면 이 네 값은 비워 두고 봇 토큰·대상 채팅 id만 채웁니다. 이 값들은 소유자 로컬 비밀이라 레포에 커밋하지 않고 .env(또는 ~/.config/openarms/hermes.env)에 둡니다 — .env.example이 모든 키의 플레이스홀더를 담고 있습니다.

cp .env.example .env
# OPENARMS_TELEGRAM_BOT_TOKEN, OPENARMS_TELEGRAM_SLOT_CHAT_ID 채우기(필수)
# 미러까지 쓰면 TELEGRAM_API_ID/HASH + OPENARMS_TELEGRAM_USER_SESSION
python -m openarms doctor    # 어떤 필수 값이 비었는지 점검

배포판 훅 연동. Hermes 플러그인은 telethon을 pip_dependencies로 선언하고, 사용자측 말풍선 전송은 cli_input_before_submit 훅에서 일어납니다 — 입력 전달 모드가 user-mtproto일 때 telethon 사용자 클라이언트로 말풍선을 보내고, 그 메시지 id로 suppress 키를 만들어 미러된 풍선이 두 번째 턴으로 다시 들어오는 것을 막습니다.

Hermes (PM 역할 프로바이더 CLI)

왜 이걸 골랐나. OpenArms는 프로바이더-중립 엔진 + 교체 가능한 어댑터 구조입니다. 역할(PM/worker)이 안정 개념이고 프로바이더는 그 역할을 채우는 교체 가능한 구현입니다. 현재 라이브 테스트베드는 Hermes를 PM(조율자) 역할에 바인딩합니다 — 이는 라이브 배치의 한 인스턴스이지 제품 기본값이 아닙니다. Hermes를 PM에 둔 이유는 그 공식 플러그인 hook 레이어가 스레드 라우팅·게이트웨이 디스패치를 깔끔히 가로챌 수 있어, Hermes 코어를 패치하지 않고 OpenArms로 흘려보낼 수 있기 때문입니다.

어떻게 구성하나. OpenArms는 Hermes를 설치·패치하지 않고 어댑터로 붙입니다. 연결 표면은 전부 환경변수입니다(OPENARMS_HERMES_*): 프로세스(OPENARMS_HERMES_BIN), tmux 좌석(OPENARMS_HERMES_CLI_PANE·OPENARMS_HERMES_CLI_SESSION), 라우팅 계약 (OPENARMS_HERMES_ROUTE_TARGET·OPENARMS_HERMES_ROUTE_EXECUTOR). 라이브가 드라이브하는 리스너는 중립 코어인 scripts/telegram_thread_router_listener.py입니다 — Hermes가 PM으로 이 리스너를 몰지만 리스너 자체는 프로바이더-중립으로 남습니다.

배포판 훅 연동. 공식 Hermes 플러그인 브리지(integrations/hermes/openarms_contract_bridge/) 는 레포 밖 플러그인 디렉터리에 설치되어 Hermes의 실제 플러그인 로더가 적재합니다. 매니페스트 plugin.yaml이 네 훅을 선언합니다:

# integrations/hermes/openarms_contract_bridge/plugin.yaml
name: openarms-contract-bridge
hooks:
  - pre_gateway_dispatch       # 에이전트 이전 라우트 결정(skip/rewrite/allow/route)
  - transform_llm_output       # 출력 변환
  - cli_input_before_submit    # 사용자 입력 관측 + 미러
  - cli_response_after_render  # 렌더된 응답 미러
requires_env:
  - OPENARMS_ROOT
  - OPENARMS_HERMES_ROUTE_TARGET
  - OPENARMS_HERMES_ROUTE_EXECUTOR
  - OPENARMS_TMUX_BIN

핵심 동작: pre_gateway_dispatch는 OpenArms의 “에이전트 이전” 결정으로 매핑되고, OPENARMS_HERMES_ROUTE_EXECUTOR=tmux로 라우트 실행이 명시적으로 켜졌을 때만 턴을 전경 tmux pane으로 제출합니다. 응답 미러가 켜져 있으면 게이트웨이는 skip을 돌려 Hermes 답변이 두 번 나가지 않게 하고, 미러가 꺼져 있으면 allow로 사용자가 답을 받게 합니다. 즉 훅은 Hermes 코어를 건드리지 않고 OpenArms 라우팅을 끼워 넣는 단 하나의 접점입니다.

AGY / Antigravity (worker 역할 프로바이더 CLI)

왜 이걸 골랐나. 같은 역할≠프로바이더 원칙에서, 라이브 테스트베드는 Antigravity CLI(짧게 agy)를 worker 역할에 바인딩합니다. 이것도 라이브 인스턴스이지 제품 기본값이 아닙니다 (제품 기본은 단일 PM). AGY를 worker로 둔 이유는 그 네이티브 첨부/파일 표면이 강해, 이미지· 파일이 섞인 작업 턴을 폴백 없이 프로바이더 고유 표면으로 처리할 수 있기 때문입니다.

어떻게 구성하나. 연결은 OPENARMS_AGY_* 환경변수입니다 — 텔레그램/표면 바인딩 (OPENARMS_AGY_TELEGRAM_BOT_TOKEN·OPENARMS_AGY_TELEGRAM_CHAT_ID), 전경 tmux 좌석 (OPENARMS_AGY_FOREGROUND_SESSION·OPENARMS_AGY_PANE), 턴 동작 (OPENARMS_AGY_INBOUND·OPENARMS_AGY_RESULT). OPENARMS_AGY_TELEGRAM_CHAT_ID는 AGY를 복구하는 fail-closed 게이트 키라 비면 worker가 살아나지 않습니다. 엔진이 역할-우선 네이밍으로 옮겨가면 이 키들은 중립 OPENARMS_WORKER_*(예: OPENARMS_WORKER_BOT_TOKEN)로 승계됩니다 — 마이그레이션 목표일 뿐 오늘의 라이브 키는 OPENARMS_AGY_*입니다.

배포판 훅 연동. AGY는 Antigravity-네이티브 플러그인 번들(integrations/antigravity/ openarms_provider/)로 붙고, 훅 매니페스트가 역할·프로바이더·권위·첨부 정책을 선언합니다:

// integrations/antigravity/openarms_provider/hooks/openarms.json
{
  "openarms_provider_bridge": {
    "role": "worker",
    "provider": "antigravity",
    "authority": "official_antigravity_cli_surface",
    "attachment_policy": "use_native_attachment_surface_before_fallback"
  }
}

worker 페르소나는 agy-global-AGENTS.md가 세션 시작 시 작업 디렉터리에서 자동 적재해 강제합니다(대화 우선, 하드 tool 게이트, 한국어 사용자 응답, 내부 표면 비노출). 첨부가 있는 턴은 attachment_policy대로 네이티브 첨부 표면을 먼저 거칩니다.

Claude · 기타 프로바이더 CLI

왜·어떻게. Claude를 비롯한 다른 CLI도 같은 어댑터 규약으로 붙일 수 있습니다 — OpenArms는 이들을 설치·패치하지 않고, 중립 역할 계약(PM/worker, 라우팅, 레지스트리, 표면)을 그 CLI의 고유 affordance로 매핑하는 얇은 어댑터만 둡니다. 표준 규칙: 프로바이더 라벨이 제품 역할을 대체(supersede)하지 않게 하고, 한 프로바이더의 기계적 idiom이나 깨지기 쉬운 키워드 휴리스틱을 중립 코어에 하드코딩하지 않습니다. 그래서 매니페스트/문서는 “PM 프로바이더”, “worker 프로바이더” 처럼 역할-우선으로 적고 hermes/antigravity는 현재 바인딩으로만 다룹니다.

doctor / preflight (설치 점검 도구)

왜·어떻게. 두 점검 도구는 “설치가 됐다”와 “라이브가 뜬다” 사이의 흔한 함정을 잡습니다. scripts/dev_preflight.py는 import-only로 필수 의존성(pytest·telethon·jsonschema) 존재만 보고(설치·네트워크 없음), 누락 시 비-0으로 끝납니다. python -m openarms doctor (= scripts/openarms_setup_doctor.py)는 메신저 연결 쪽을 봅니다 — 봇 토큰과 대상 채팅 id가 필수 finding이고, 포럼 토픽/비즈니스/MTProto 미러는 선택 finding입니다. 비밀 값은 redact_value로 마스킹해 stdout에 원문이 새지 않게 합니다.

python3 scripts/dev_preflight.py     # 인터프리터 의존성 점검(필수 누락 시 비-0)
python -m openarms doctor            # 메신저 연결 필수/선택 점검

첫 연결 설정

  • 홈 골격: OpenArms는 ~/.openarms(또는 OPENARMS_HOME)에 설정·자격·기억 골격을 둡니다.
  • 메신저: 현재 1차 어댑터는 텔레그램입니다. 봇 토큰과 대상 채널소유자 로컬 비밀이라 레포에 커밋하지 않고 .env로 둡니다(.env.example 참조).
  • 프로바이더 CLI: Hermes·AGY·Claude 등은 외부 CLI입니다. OpenArms는 이들을 설치·패치하지 않고 어댑터로 붙입니다.

OS 지원 현황 (0.0.2.x)

OS패키지·CLI·테스트라이브 운영
macOS · Mac VM가능현재 전경·tmux 기준석
Linux근거 있음(CI)tmux 구조에 적합
Windows가능(CI)비주력(GUI 확인 쪽)

멀티 OS 동일 완전 사용은 사용자가 명명할 분화 버전 목표이지 현재 상태가 아닙니다.

출처: WSL2 Setup Guide 2026 · Modern Python on WSL2 · Scripting tmux (tao-of-tmux) · HTTP Bot API vs MTProto (Telethon docs) · uv vs pip (Real Python)

0건의 항목