feat: 인벤토리 캐시 및 JSON 인코더 추가
- 인벤토리 캐시 기능을 추가하여, RCON으로 인벤토리를 읽지 못할 경우 이전에 성공적으로 읽은 데이터를 활용 - Lua에서 JSON 인코딩을 위한 간단한 함수 추가, 일부 Factorio 버전에서 `game.table_to_json`이 없을 경우 대체 - `README.md`에 인벤토리 캐시 및 JSON 인코더 사용에 대한 설명 추가 - `scan_resources()`와 `mine_resource`의 반경을 확장하여 자원 탐색 실패를 줄임
This commit is contained in:
90
docs/plan.md
90
docs/plan.md
@@ -22,3 +22,93 @@
|
||||
### README 업데이트 계획
|
||||
- 채굴 제외(exclude) 로직이 “정수 타일 키 기반으로 통일”되도록 README의 기술/동작 설명(또는 체크리스트)을 업데이트합니다.
|
||||
|
||||
---
|
||||
|
||||
## 자원 패치 중심 오차로 인한 채굴 실패 완화 계획
|
||||
|
||||
### 문제 관찰
|
||||
- `scan_resources()`가 패치의 평균 중심(`center_x/y`)을 추천 좌표로 사용하면서,
|
||||
플레이어가 해당 좌표로 이동한 직후 `mine_resource`의 엔티티 탐색 반경 안에서
|
||||
실제 자원 엔티티를 찾지 못해 실패하는 케이스가 발생할 수 있음.
|
||||
|
||||
### 근거(팩토리오 Lua API)
|
||||
- `LuaInventory.get_contents()`는 `dictionary[string -> uint]`를 반환하므로,
|
||||
인벤토리 판독은 `name -> count` 형태로 처리하는 것이 맞다.
|
||||
- 자원 엔티티의 `e.position`은 부동소수(MapPosition) 좌표이므로,
|
||||
타일 중심/평균 중심과 실제 엔티티 좌표 간 오차가 생길 수 있다.
|
||||
|
||||
### 변경 목표
|
||||
1. `scan_resources()` 결과에 패치 대표 좌표를 평균 중심뿐 아니라
|
||||
플레이어 기준 가장 가까운 실제 엔티티 좌표(앵커 `anchor_x/y` 및 `anchor_tile_x/y`)로 함께 제공
|
||||
2. `summarize_for_ai()`에서는 평균 중심 대신 앵커 좌표 기반으로 거리/추천을 계산
|
||||
3. `mine_resource` 후보 엔티티 탐색 반경을 더 크게 잡아(행동 레벨) 이동 직후 실패를 흡수
|
||||
|
||||
### 구현 범위
|
||||
- `state_reader.py`
|
||||
- `scan_resources()`에 `anchor_x/y` 및 `anchor_tile_x/y` 추가
|
||||
- `summarize_for_ai()` 거리 계산을 앵커 우선으로 변경
|
||||
- `action_executor.py`
|
||||
- `mine_resource`에서 후보 엔티티 탐색 반경을 `80` → `250`으로 확장
|
||||
|
||||
---
|
||||
|
||||
## GLM 응답 지연 원인 계측/완화 계획
|
||||
|
||||
### 문제 관찰
|
||||
- `ai_planner.py`에서 GLM 호출이 `[GLM] 생각 중...` 이후 30초~1분 이상 지연되는 현상 발생
|
||||
- JSON 파싱 실패로 인한 재시도는 가끔 발생(하지만 느림의 주 원인이 아닐 가능성도 있음)
|
||||
|
||||
### 1단계(증거 수집)
|
||||
- `ai_planner.py`의 `_call_glm()`에 타이밍 로그 추가
|
||||
- `total`: 요청 시작~콘텐츠 반환까지 전체 소요
|
||||
- `http_read`: HTTP 응답 본문 수신까지 소요
|
||||
- `json_parse`: 응답 JSON 파싱 시간
|
||||
- `prompt_chars/system_chars/max_tokens`: 입력 크기 동시 기록
|
||||
|
||||
### 2단계(완화: 로그 확인 후)
|
||||
- `json_parse`가 아니라 `http_read/total`이 큰 경우:
|
||||
- `max_tokens`를 우선 크게 줄여 생성 길이 상한 조정
|
||||
- `SYSTEM_PROMPT`/`state_summary` 길이를 더 강하게 제한
|
||||
- `json_parse`가 큰 경우:
|
||||
- JSON 파싱/복구 로직 비용 또는 응답 형식 편차 원인 재점검
|
||||
|
||||
### README 업데이트
|
||||
- `README.md`의 `주의사항`/`실행` 섹션에 GLM 지연 계측 로그 출력 방식 및 파라미터 조정 힌트를 반영
|
||||
|
||||
---
|
||||
## Cursor Hooks - Windows `sessionStart` 앱 선택창 원인/해결 계획
|
||||
### 문제 재현/관찰
|
||||
- Cursor `@cursor.hooks` 로그에서 `sessionStart` 훅 실행 중 `./hooks/session-start`가 stdout JSON을 내지 못하거나, Windows에서 앱 선택창이 뜨는 현상이 관찰됨
|
||||
|
||||
### 원인 후보
|
||||
- Windows에서 확장자 없는 `./hooks/session-start`를 실행할 때 `bash`로 해석되지 않아, OS가 실행 대신 “어떤 앱으로 열지”를 요청할 수 있음
|
||||
|
||||
### 변경 목표
|
||||
1. 프로젝트 훅은 `powershell`로 stdout에 JSON을 출력하도록 고정
|
||||
2. superpowers 플러그인의 Cursor 훅은 `bash`로 감싸 실행되도록 구성 변경
|
||||
|
||||
### 구현/검증 범위
|
||||
- `E:/develop/factorio-ai-agent/.cursor/hooks.json`
|
||||
- `E:/develop/factorio-ai-agent/.cursor/session-start-hook.ps1`
|
||||
- `.../superpowers/.../hooks/hooks-cursor.json`
|
||||
- 검증: Cursor 재시작 후 `View -> Output -> Hooks`에서 sessionStart 훅이 정상 파싱되어 `OUTPUT`에 JSON이 나타나는지 확인
|
||||
|
||||
---
|
||||
|
||||
## 인벤토리 캐시(메모리) 추가 계획
|
||||
|
||||
### 목표
|
||||
- 파이썬 에이전트만 종료/재실행할 때 `RCON`으로 인벤토리를 읽지 못하거나(`{}` 반환) 빈 값이 나오면,
|
||||
직전에 성공적으로 읽은 인벤토리를 기억해서 프롬프트에 반영한다.
|
||||
|
||||
### 정책(사용자 선택: 1번 fallback only)
|
||||
- `get_inventory()`가 성공적으로 읽어서 값이 비어있지 않으면 캐시를 갱신한다.
|
||||
- `get_inventory()` 결과가 빈 딕셔너리이면(실패/빈 값) 캐시 파일을 로드해서 대체한다.
|
||||
|
||||
### 구현 범위
|
||||
- `state_reader.py`
|
||||
- `inventory_memory.json` 로드/저장 유틸 추가
|
||||
- `get_inventory()` 반환값을 캐시 fallback으로 교체
|
||||
- `README.md`
|
||||
- 인벤토리 캐시 동작과 파일명(`inventory_memory.json`)을 설명
|
||||
|
||||
|
||||
Reference in New Issue
Block a user