# NomadCode Core NomadCode Core는 사용자 요청을 작업 단위로 받고, 작업 상태를 저장하며, 비동기 Agent 작업 흐름을 관리하기 위한 서버입니다. 초기 목표는 작업 생성과 조회, PostgreSQL 기반 작업 상태 저장, River 기반 비동기 작업 실행, Plane/Mattermost Adapter stub 구성, 이후 IOP / Agent Integrator와 연결 가능한 구조 확보입니다. ## 현재 구현 범위 - Go HTTP Server - `GET /healthz`, `GET /readyz` - task 생성 / 조회 / 목록 / enqueue API - PostgreSQL 연결 - goose migration - sqlc 기반 DB query 생성 구조 - River task job - IOP Edge/OpenAI-compatible 모델 호출 경로(Ollama direct fallback 가능) - IOP Edge/A2A-compatible agent 호출 인터페이스 - Plane Adapter stub - Mattermost Adapter stub - 선택적 Docker Compose 실행 환경(PostgreSQL, Redis) ## 현재 구현하지 않은 범위 - 실제 Plane API 호출 - 실제 Mattermost 메시지 발송 - IOP native protocol 연동 - Agent Integrator 연동 - Outline / Forgejo / Nextcloud 연동 - MCP 서버 - Web Agent UI - Flutter 앱 - 복잡한 권한 정책 - 복잡한 workflow DSL ## 단계별 다음 작업 ### Phase 1. Server Skeleton 현재 스캐폴드 단계입니다. 목표: - 서버 실행 골격 구성 - task 저장 구조 구성 - 로컬 모델 호출 기반 비동기 job 실행 - Adapter stub 생성 ### Phase 2. Workflow Core 목표: - task 상태 전이 정리 - enqueue / running / completed / failed 흐름 안정화 - retry / timeout 기본 구조 추가 - notification event 구조 정리 ### Phase 3. External Integration 목표: - Plane issue 생성 / comment / status update 구현 - Mattermost 메시지 발송 구현 - Agent Integrator 호출 구조 추가 - IOP 호출 구조 추가 - IOP의 OpenAI-compatible API 경로는 단순 모델/chat completion 호환 호출에 사용 - IOP의 A2A JSON-RPC 경로는 Core가 Edge 실행 그룹이나 외부 agent에게 작업을 위임하고 task 상태/artifact/cancel 흐름을 공유할 때 사용 ## 실행 방법 로컬 실행은 현재 개발 호스트의 Go와 `code-server` compose에 붙은 PostgreSQL/Redis가 있다는 전제로 진행합니다. local 기본 `DATABASE_URL`은 `postgres://nomadcode:nomadcode@code-server-postgres:5432/nomadcode-core-local?sslmode=disable` 이고, local 기본 `REDIS_URL`은 `redis://code-server-redis:6379/3`, `REDIS_KEY_PREFIX`는 `nomadcode-core:local` 입니다. dev 배포는 Docker Compose로 실행하며, 같은 `code-server-postgres` Postgres와 `code-server-redis` Redis를 사용합니다. dev DB명은 `nomad-core-dev` 이고, dev 기본 `REDIS_URL`은 `redis://code-server-redis:6379/4`, `REDIS_KEY_PREFIX`는 `nomadcode-core:dev` 입니다. `AUTH_PASSWORD`를 설정하면 `/readyz`와 `/api/*`에 HTTP Basic Auth가 적용됩니다. 모델 호출의 장기 대상은 IOP Edge의 OpenAI-compatible input surface이며, 현재 core model client는 Responses API 형식을 사용합니다. fallback 기본값은 direct Ollama `MODEL_BASE_URL=http://192.168.0.91:11434`, `MODEL_NAME=qwen3.6:35b-a3b-bf16`, `MODEL_CONTEXT_SIZE=262144`, `MODEL_TIMEOUT_SEC=300` 입니다. A2A agent 호출 endpoint는 `A2A_EDGE_URL`로 설정하고, 기존 `A2A_AGENT_URL`도 fallback alias로 받습니다. bearer token은 `A2A_TOKEN`, timeout은 `A2A_TIMEOUT_SEC`로 설정합니다. `code-server` PostgreSQL 컨테이너에 DB를 생성하는 예시: ```bash docker exec code-server-postgres psql -U nomadcode -d postgres -c 'CREATE DATABASE "nomadcode-core-local" OWNER nomadcode;' docker exec code-server-postgres psql -U nomadcode -d postgres -c 'CREATE DATABASE "nomad-core-dev" OWNER nomadcode;' ``` Migration 실행: ```bash ./bin/migrate-up ``` 서버 실행: ```bash ./bin/run ``` 간단한 암호를 걸고 실행: ```bash AUTH_PASSWORD="change-me" ./bin/run curl -u nomadcode:change-me localhost:8080/api/tasks ``` 다른 DB 주소를 사용할 경우: ```bash DATABASE_URL="postgres://user:password@localhost:5432/dbname?sslmode=disable" ./bin/migrate-up DATABASE_URL="postgres://user:password@localhost:5432/dbname?sslmode=disable" ./bin/run ``` 다른 모델 endpoint를 사용할 경우: ```bash MODEL_BASE_URL="http://localhost:11434" \ MODEL_NAME="qwen3.6:35b-a3b-bf16" \ MODEL_CONTEXT_SIZE="262144" \ MODEL_TIMEOUT_SEC="300" \ ./bin/run ``` 모델 호출은 OpenAI-compatible Responses API의 non-streaming `POST /v1/responses` 형식을 사용합니다. IOP Edge OpenAI-compatible listener를 `MODEL_BASE_URL`로 쓰려면 해당 listener가 `/v1/responses`를 제공해야 합니다. direct Ollama fallback에서는 `MODEL_CONTEXT_SIZE`를 Ollama 전용 option인 `options.num_ctx`로 전달합니다. A2A agent 호출 인터페이스는 JSON-RPC 2.0 `message/send`, `tasks/get`, `tasks/cancel`을 우선 지원합니다. `A2A_EDGE_URL`을 설정하면 worker는 A2A `message/send`를 blocking 호출하고, 완료된 task/message 응답만 local task completion으로 반영합니다. 기존 `A2A_AGENT_URL`도 fallback alias로 받습니다. 설정하지 않으면 기존 OpenAI-compatible 모델 호출 경로를 사용합니다. 테스트 실행: ```bash ./bin/test ``` sqlc 실행: ```bash ./bin/sqlc ``` DB 접근 코드는 `migrations/`의 스키마와 `queries/`의 SQL을 기준으로 `internal/db/`에 생성합니다. `internal/db/db.go`, `internal/db/models.go`, `internal/db/tasks.sql.go`는 생성 파일이므로 직접 수정하지 않습니다. Docker Compose 실행은 dev 배포용입니다. compose는 외부 Docker 네트워크 `net_nginx`에 붙고, 같은 네트워크의 `code-server-postgres`에 `nomad-core-dev` DB로, `code-server-redis`의 Redis DB 4번과 `nomadcode-core:dev` key prefix로 접속합니다. dev Redis 주소나 prefix를 바꿀 때는 local 실행용 `REDIS_URL`, `REDIS_KEY_PREFIX`와 분리된 `DEV_REDIS_URL`, `DEV_REDIS_KEY_PREFIX`를 사용합니다. 외부 노출 테스트에서는 `AUTH_PASSWORD`를 함께 지정합니다. ```bash AUTH_PASSWORD="change-me" ./bin/docker-up ``` Makefile은 같은 명령을 감싸는 얇은 alias입니다. ```bash make migrate-up make run make test make sqlc ``` API 테스트: ```bash curl localhost:8080/healthz curl localhost:8080/readyz ``` ```bash curl -X POST localhost:8080/api/tasks \ -H 'Content-Type: application/json' \ -d '{"title":"README 수정 작업","source":"manual","payload":{"message":"README 초안을 정리해줘"}}' ``` ```bash curl localhost:8080/api/tasks curl localhost:8080/api/tasks/{id} curl -X POST localhost:8080/api/tasks/{id}/enqueue ```