Metadata-Version: 2.4
Name: a2a-agent
Version: 0.2.19
Summary: MQTT 위에서 도는 커맨더-워커 A2A 오케스트레이션 에이전트
Author: Judvika
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: paho-mqtt
Requires-Dist: typer
Requires-Dist: pyyaml
Dynamic: license-file

# a2a-agent

`a2a-agent`는 MQTT 위에서 커맨더와 워커가 A2A 형식 메시지를 주고받기 위한 작은 명령줄 도구입니다.

현재 버전은 MQTT 브로커(기본값은 환경변수 `A2A_BROKER_HOST`, 미설정 시 `localhost:1883`), 기본 방 `team`, 6자리 페어링 코드, 역할별 `run` 루프, 커맨더 `send`, 워커 `echo`/`opencode`/`cursor` 실행기를 지원합니다.

0.1.7부터 워커 `run`은 실행 중에도 PyPI 최신 버전을 주기적으로 확인합니다. 배포 설치본에서 새 버전이 발견되면 업데이트 후 같은 명령으로 재시작합니다. 개발용 editable 설치는 자동 업데이트를 건너뜁니다.

## 설치

PyPI 배포 후에는 다음처럼 설치할 수 있습니다.

```bash
python -m pip install a2a-agent
```

개발 환경에서 소스 코드로 설치하려면 저장소 루트에서 실행합니다.

```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -e .
```

## 기본 사용

커맨더 설정을 만듭니다.

```bash
a2a-agent init --room team --device-name commander --broker-host <BROKER_HOST> --broker-port 1883 --no-tls
```

커맨더 실행 루프를 켭니다. 이 루프가 켜져 있어야 워커의 페어링 요청에 답할 수 있습니다.

```bash
a2a-agent run
```

다른 터미널에서 워커 6자리 페어링 코드를 발급합니다.

```bash
a2a-agent invite macbook-air
```

워커 기기에서는 코드만 입력해 참여합니다.

```bash
a2a-agent join ABC234
```

워커 실행 루프를 켭니다. 기본 실행기는 `echo`입니다.

```bash
A2A_EXECUTOR=echo a2a-agent run
```

자동 업데이트를 임시로 끄려면 `A2A_AUTO_UPDATE=0`을 붙입니다.

```bash
A2A_AUTO_UPDATE=0 A2A_EXECUTOR=echo a2a-agent run
```

워커의 실행 중 업데이트 확인 주기는 기본 3600초입니다. 필요하면 `A2A_UPDATE_INTERVAL_SECONDS`로 조정하고, `0`으로 두면 실행 중 감시만 끕니다.

```bash
A2A_UPDATE_INTERVAL_SECONDS=1800 A2A_EXECUTOR=echo a2a-agent run
```

커맨더에서 워커에게 작업을 보냅니다.

```bash
a2a-agent send macbook-air "ping-테스트"
```

커맨더는 사람용 별칭도 저장할 수 있습니다. 별칭은 커맨더 config에만 저장되고, 워커의 실제 기기명은 바꾸지 않습니다.

```bash
a2a-agent set-alias "회사 PC" windows-cursor
a2a-agent send "회사 PC" "ping-테스트"
```

## 원격 제어 태스크

0.2.6부터 커맨더는 워커의 AI 실행기를 거치지 않는 내장 제어 태스크를 보낼 수 있습니다. 기기 별칭도 그대로 사용할 수 있습니다.

```bash
a2a-agent control "데스크탑 PC" install-autostart
a2a-agent control "데스크탑 PC" uninstall-autostart
```

워커 코드는 위 두 이름만 고정 함수로 처리합니다. 다른 값은 `unsupported control` 실패 응답이 되며, 임의 셸 명령은 실행하지 않습니다. 등록 활성화나 제거가 끝나지 않아 수동 명령이 필요한 결과도 실패로 응답합니다. 응답 대기 시간은 일반 `send`와 같은 `A2A_SEND_TIMEOUT`을 사용합니다. 제어 명령을 보내기 전에 대상 워커도 0.2.6 이상인지 확인해야 합니다.

## 파일 첨부

0.2.19부터 파일 공유 기본 백엔드는 Dropbox입니다. 커맨더만
`DROPBOX_APP_KEY`, `DROPBOX_APP_SECRET`, `DROPBOX_REFRESH_TOKEN`을 가지며,
기본 실행 래퍼는 `/Users/macmini/.config/agent-secrets/dropbox.env`를 읽습니다.
워커에는 Dropbox 장기 자격을 전달하지 않습니다.

```bash
a2a-agent send macbook-air "이 이미지 분석해줘" --file chart.png
```

커맨더는 입력 파일을 `/a2a-workspace/<task-id>/in/`에 올린 뒤 4시간짜리
직접 다운로드 URL을 태스크에 넣습니다. 워커는 자격 없이 일반 HTTP GET으로
입력을 받습니다. 결과 파일은 태스크에 포함된 단명 access token으로
`/a2a-workspace/<task-id>/out/`에만 올릴 수 있고, 커맨더가 임시 URL로
자동 내려받습니다. 완료 응답 뒤 커맨더는 해당 태스크 폴더를 정리하며, 정리
실패는 경고만 남기고 작업 결과에는 영향을 주지 않습니다.

기존 `A2A_SHARE_*` FileStation 설정은 하위 호환 경로로 남아 있습니다. Dropbox
자격이 없고 기존 설정만 있으면 이전 방식으로 동작합니다. 어느 공유 설정도
없으면 파일 첨부만 비활성화되고 텍스트 통신은 그대로 동작합니다.

## 워커 실행기

- `echo`: 받은 텍스트를 그대로 회신합니다. 연결 확인용 기본값입니다.
- `opencode`: `opencode run -m opencode/big-pickle "<프롬프트>"`를 호출하고 표준출력을 회신합니다. 실패하거나 설치되어 있지 않으면 에러 메시지를 결과로 돌려보냅니다.
- `cursor`: `cursor-agent -p --yolo --trust "<프롬프트>"`를 호출하고 표준출력을 회신합니다. 느릴 수 있으므로 커맨더 송신 시 `A2A_SEND_TIMEOUT`을 늘릴 수 있습니다.
- `grok`: `grok --always-approve -p "<프롬프트>"`(일회용, `-c` 없음)를 호출하고 표준출력을 회신합니다.

실행기는 설정 파일의 `executor` 또는 환경변수 `A2A_EXECUTOR`로 선택합니다. 환경변수가 우선합니다.

## 토픽

페어링 토픽은 방과 무관한 전역 토픽입니다.

```text
a2a/_pairing/request
a2a/_pairing/reply/{code}
```

작업 토픽은 방과 워커 이름을 기준으로 나뉩니다.

```text
a2a/{room}/agents/{device}/card
a2a/{room}/agents/{device}/status
a2a/{room}/cmd/{device}/request
a2a/{room}/cmd/{device}/response
a2a/{room}/cmd/{device}/task-status
```

## 구조

```text
a2a-agent/
├── pyproject.toml
├── README.md
├── LICENSE
├── install/install.sh
├── scripts/live_broker_roundtrip.py
├── src/a2a_agent/
│   ├── cli.py
│   ├── client.py
│   ├── config.py
│   ├── executor.py
│   ├── invite.py
│   ├── pairing.py
│   ├── protocol.py
│   ├── runtime.py
│   ├── updater.py
│   └── topics.py
└── tests/
```

## 라이선스

MIT 라이선스를 따릅니다.
