126 lines
6.6 KiB
Markdown
126 lines
6.6 KiB
Markdown
|
|
# HANDOFF: galaxis-agent 자율 개발 에이전트
|
||
|
|
|
||
|
|
## Goal
|
||
|
|
|
||
|
|
galaxis-po (퇴직연금 퀀트 포트폴리오 관리) 코드베이스를 자율적으로 개발하는 SWE 에이전트(**galaxis-agent**)를 구축한다. open-swe를 포크하여 Gitea + Discord 환경에 맞게 커스터마이즈한다.
|
||
|
|
|
||
|
|
## Infrastructure
|
||
|
|
|
||
|
|
- **Agent Repo**: `ssh://git@152.69.231.161:7798/quant/galaxis-agent.git` (로컬: `~/workspace/quant/galaxis-agent/`)
|
||
|
|
- **Target Repo**: `ssh://git@152.69.231.161:7798/quant/galaxis-po.git`
|
||
|
|
- **Oracle VM**: A1 (4코어 ARM64, 24GB) - Gitea + Docker 운영 서버
|
||
|
|
- **LLM**: Claude API (Anthropic)
|
||
|
|
- **Discord**: 기존 봇 활용
|
||
|
|
|
||
|
|
## Key Documents
|
||
|
|
|
||
|
|
- **설계 스펙**: `docs/superpowers/specs/2026-03-20-galaxis-agent-design.md` (galaxis-po 리포, 2회 리뷰 완료)
|
||
|
|
- **Phase 1 플랜**: `docs/superpowers/plans/2026-03-20-galaxis-agent-phase1.md` (galaxis-po 리포)
|
||
|
|
- **Phase 2 플랜**: `docs/superpowers/plans/2026-03-20-galaxis-agent-phase2.md` (galaxis-po 리포)
|
||
|
|
- **open-swe 원본**: `/Users/moneypenny/workspace/etc/open-swe/`
|
||
|
|
- **메모리**: `/Users/moneypenny/.claude/projects/-Users-moneypenny-workspace-quant-galaxis-po/memory/MEMORY.md`
|
||
|
|
|
||
|
|
## Current Progress
|
||
|
|
|
||
|
|
### Phase 1: 프로젝트 기반 구축 — COMPLETE
|
||
|
|
|
||
|
|
galaxis-agent 리포에 16개 커밋, 40개 테스트 전부 통과, Gitea에 push 완료.
|
||
|
|
|
||
|
|
완료된 작업:
|
||
|
|
1. open-swe 코드 복사 → galaxis-agent 리포 생성
|
||
|
|
2. 불필요 코드 삭제 (Linear, Slack, GitHub API, 클라우드 샌드박스 - 21개 파일)
|
||
|
|
3. `github.py` → `git_utils.py` 분리 (순수 git CLI 유틸리티 보존)
|
||
|
|
4. 의존성 정리 (PyJWT/langsmith/langchain-openai 등 제거, docker/discord.py/pydantic-settings 추가)
|
||
|
|
5. `config.py` 환경변수 모듈 (pydantic-settings, TDD)
|
||
|
|
6. Phase 2 스텁 파일 (DockerSandbox, GiteaClient, DiscordClient, gitea_comment, discord_reply)
|
||
|
|
7. 핵심 파일 정리 (server.py, webapp.py, prompt.py, commit_and_open_pr.py, open_pr.py)
|
||
|
|
8. Dockerfile (서버 + 샌드박스), docker-compose.yml (docker-socket-proxy 포함)
|
||
|
|
9. ARM64 호환성 검증: deepagents 0.4.11, langgraph, docker 7.1.0, discord 2.7.1 모두 OK
|
||
|
|
|
||
|
|
### Phase 2: 핵심 기능 구현 — COMPLETE
|
||
|
|
|
||
|
|
**실행 방식**: Subagent-Driven Development (Task별 독립 subagent + spec 리뷰)
|
||
|
|
|
||
|
|
22개 커밋, **73개 테스트 통과** (40 Phase1 + 33 Phase2), Gitea에 push 완료.
|
||
|
|
|
||
|
|
| Task | 상태 | 커밋 | 설명 |
|
||
|
|
|------|------|------|------|
|
||
|
|
| Task 1: DockerSandbox | ✅ COMPLETE | `5d44c2e` | BaseSandbox 확장, docker-py 컨테이너 관리, 6 테스트 |
|
||
|
|
| Task 2: GiteaClient | ✅ COMPLETE | `b2ad726` | 6 async API 메서드, lazy singleton, 8 테스트 |
|
||
|
|
| Task 3: gitea_comment | ✅ COMPLETE | `e8983d8` | asyncio.run()으로 GiteaClient 호출, 3 테스트 |
|
||
|
|
| Task 4: commit_and_open_pr 완성 | ✅ COMPLETE | `816415d` | GiteaClient PR 생성, URL 변환, open_pr.py 안전망, 2 테스트 |
|
||
|
|
| Task 5: discord_reply | ✅ COMPLETE | `e8983d8` | DiscordClient + discord_reply 도구, 4 테스트 |
|
||
|
|
| Task 6: 프롬프트 로딩 | ✅ COMPLETE | `af7bd2c` | read_repo_instructions() AGENTS.md+CLAUDE.md, 3 테스트 |
|
||
|
|
| Task 7: 경로 검증 | ✅ COMPLETE | `af7bd2c` | path_validator.py, writable/blocked 경로 검증, 7 테스트 |
|
||
|
|
| Task 8: LangGraph 검증 | ✅ COMPLETE | `94edb45` | langchain/langgraph-api:3.11 ARM64 동작 확인, docker-compose 추가 |
|
||
|
|
| Task 9: 최종 테스트 | ✅ COMPLETE | - | 73 테스트 통과, 7 모듈 import 확인, Gitea push 완료 |
|
||
|
|
|
||
|
|
### Phase 3-4: 미작성
|
||
|
|
|
||
|
|
- Phase 3: Gitea webhook 완전 구현, Discord bot gateway, 메시지 큐잉
|
||
|
|
- Phase 4: CostGuard, 복구 메커니즘, 자동 머지 모드, 모니터링
|
||
|
|
|
||
|
|
## What Worked
|
||
|
|
|
||
|
|
- **Subagent-driven development**: Task별 독립 subagent 디스패치가 효율적. 컨텍스트 오염 없이 빠른 반복.
|
||
|
|
- **Task 묶기**: 유사한 Task를 하나의 subagent에 묶어 디스패치 (gitea_comment+discord_reply, prompt_loading+path_validator). 오버헤드 대폭 감소.
|
||
|
|
- **sonnet 모델**: Phase 2의 모든 구현 Task를 sonnet으로 처리. 스펙이 명확하면 sonnet이면 충분.
|
||
|
|
- **Phase 2 플랜 리뷰**: sync/async 인터페이스 불일치, 변수명 불일치, 잘못된 패턴 등을 플랜 리뷰에서 조기 발견하여 수정.
|
||
|
|
- **LangGraph Server**: `langchain/langgraph-api:3.11` 이미지가 ARM64에서 동작. SQLite 기본 모드 사용 가능. `DATABASE_URI` 환경변수 필요.
|
||
|
|
|
||
|
|
## What Didn't Work / Watch Out For
|
||
|
|
|
||
|
|
- **Task 번호 충돌**: 플랜 수정 시 Task 번호가 중복됨. 큰 변경은 전체 재작성이 나음.
|
||
|
|
- **Dockerfile 이름**: subagent가 `Dockerfile.agent`로 만들었는데 docker-compose는 `Dockerfile`을 참조. 수동 교체 필요.
|
||
|
|
- **기본 브랜치**: Gitea 리포 기본 브랜치 `main`, 로컬도 현재 `main` 브랜치.
|
||
|
|
- **LangGraph Server**: `latest` 태그 없음 → `3.11` 태그 사용. `DATABASE_URI` 없으면 시작 실패. SQLite로 설정 시 Go Core API 정상 시작.
|
||
|
|
- **module-level settings 인스턴스**: `settings = Settings()`를 모듈 레벨에 두면 env var 없을 때 import 실패. 지연 초기화나 클래스만 export하는 방식 필요.
|
||
|
|
- **BaseSandbox import 경로**: `deepagents.backends.sandbox.BaseSandbox` (플랜에 적힌 `deepagents.sandbox`가 아님)
|
||
|
|
- **ExecuteResponse import**: `deepagents.backends.protocol.ExecuteResponse`
|
||
|
|
- **싱글턴 AsyncClient + asyncio.run() 충돌 위험**: `asyncio.run()`이 이벤트 루프를 생성/종료하므로, 싱글턴 httpx.AsyncClient가 닫힌 루프에 바인딩될 수 있음. 도구마다 fresh client 생성 또는 sync httpx.Client 사용 고려.
|
||
|
|
|
||
|
|
## Key Code Patterns
|
||
|
|
|
||
|
|
### SandboxBackendProtocol.execute()는 동기
|
||
|
|
```python
|
||
|
|
# server.py가 호출하는 방식:
|
||
|
|
result = await loop.run_in_executor(None, sandbox_backend.execute, cmd)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 동기 도구에서 async GiteaClient 호출
|
||
|
|
```python
|
||
|
|
# commit_and_open_pr.py, gitea_comment.py, discord_reply.py에서:
|
||
|
|
import asyncio
|
||
|
|
result = asyncio.run(client.create_pull_request(...)) # executor thread에서 안전
|
||
|
|
```
|
||
|
|
|
||
|
|
### agents_md.py 패턴
|
||
|
|
```python
|
||
|
|
loop = asyncio.get_event_loop()
|
||
|
|
result = await loop.run_in_executor(None, sandbox_backend.execute, cmd)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
### Phase 3 플랜 작성 필요
|
||
|
|
|
||
|
|
Phase 2가 완료되었으므로, Phase 3 플랜을 작성해야 한다:
|
||
|
|
- Gitea webhook 완전 구현 (이벤트 파싱, rate limiting, 에이전트 디스패치)
|
||
|
|
- Discord bot gateway (메시지 수신, 스레드 관리)
|
||
|
|
- PersistentTaskQueue (SQLite 기반 영속 작업 큐)
|
||
|
|
- 메시지 큐잉 메커니즘 완성
|
||
|
|
|
||
|
|
### 실행 방법
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# galaxis-agent 리포로 이동
|
||
|
|
cd ~/workspace/quant/galaxis-agent
|
||
|
|
|
||
|
|
# 현재 상태 확인
|
||
|
|
git log --oneline
|
||
|
|
uv run pytest tests/ -v
|
||
|
|
|
||
|
|
# Phase 3 플랜 작성
|
||
|
|
# superpowers:writing-plans 스킬 사용
|
||
|
|
```
|