fix(my-deepagent): v0.3 plan-conformance — 18-item gap fix across PR #2-#9

1차 v0.3 구현 후 plan-v0.3 와 대조해 발견된 18건 누락/명세 위반을 보강.
자기 리뷰 3 라운드 (누락·미완 / 오류·엣지케이스 / 과최적화) 모두 PASS.

PR #5 plan-mode (3건):
- BLOCKED_TOOLS_IN_PLAN_MODE 에 write_todos 추가
- /plan 시 system message inject (_PLAN_MODE_SYSTEM_PROMPT)
- /approve 시 마지막 assistant 메시지를 "approved plan" system 으로 inject
- InteractiveSession._pending_system_messages 인프라 신설

PR #2 compaction (1건):
- CompactionResult.summary_text 추가, 다음 thread 첫 ainvoke 에 inject

PR #3 auto-memory (6건):
- global memory dir + bootstrap
- frontmatter name/description/type 정식 도입 + MemoryEntry/MemoryType
- _infer_memory_type (keyword heuristic, no LLM)
- _scrub_secrets (OpenRouter/Anthropic/OpenAI/AWS/Bearer redaction)
- /memory show <name> 서브명령
- /remember [--global] / /forget [--global] 스코프 토글

PR #4 skills (3건):
- project_skills_dir + 두 스코프 (global / project) merge with last-wins
- /skill <name> 본문 inject (queue_system_message) — 이전엔 REPL 출력만
- /skills show <name> 별도 서브명령

PR #6 sub-agent (4건):
- budget.py `session:<uuid>` scope + CostMiddleware 자동 전달
- resolve_root_session_id walk-up (cycle guard) + sub-agent root 에 charge
- run_subagent_to_completion 실제 ainvoke + 결과 push to parent
- /agents 서브명령 구조 (list / spawn / show) + spawn 시 parent system msg

PR #7 governance (1건):
- bootstrap_user_dirs — instructions + global/memory + skills + projects 한
  호출로 idempotent 부트스트랩

PR #8 Web GUI (1건):
- index.html → 세션 목록, runs.html (신설) → workflow archive
- conversation.html ?session=<id> deep-link

PR #9 workflow integration (2건):
- /workflow 백그라운드 WorkflowEngine.run + 진행 메시지 stream 누적
- /binding show <workflow-name[@version]> 인자 지원

테스트 (+17, 685 → 702 passed):
- test_plan_mode: write_todos 차단 + blocklist sanity
- test_memory: scrub + type 추론 + override
- test_skills: project override + find_skill + resolve_skill_sources(pk)
- test_subagents: resolve_root_session_id chain + missing fallback
- test_budget: session: scope accumulation
- test_instructions: governance bootstrap + idempotency
- test_api_static: runs.html 신설 + index.html 재구성

게이트:
- ruff check / format --check / mypy: PASS (141 source files)
- pytest -q --ignore=tests/integration/test_e2e_workflow.py
  --ignore=tests/integration/test_openrouter_smoke.py: 702 passed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
chungyeong
2026-05-18 00:03:08 +09:00
parent 361d6d7636
commit 96c8849e2c
24 changed files with 1687 additions and 304 deletions

View File

@@ -2,6 +2,106 @@
## [Unreleased]
### Changed
- **v0.3 plan-conformance fixes** — 1차 구현 후 plan-v0.3 와 대조해 발견된 18건
누락/명세 위반을 보강. 자기 리뷰 3 라운드 (누락·미완 / 오류·엣지케이스 /
과최적화) 모두 PASS.
- **PR #5 (plan mode) 3건**:
- `PlanModeMiddleware.BLOCKED_TOOLS_IN_PLAN_MODE``write_todos` 추가
(plan 명세대로: todos 는 plan markdown 의 일부, /approve 까지 차단).
- `/plan` 진입 시 system message inject (`_PLAN_MODE_SYSTEM_PROMPT`
"당신은 plan mode입니다 …"). 새 `InteractiveSession.enter_plan_mode()`
flag 토글 + pending system message 큐 + thread bump 를 한 번에 처리.
- `/approve` 시 마지막 assistant 메시지(=plan markdown) 추출 후
"approved plan" system message 로 다음 turn 에 inject. 새
`InteractiveSession.approve_plan() / reject_plan()`.
- 신규 인프라: `InteractiveSession._pending_system_messages: list[str]` +
`queue_system_message()` / `consume_pending_system_messages()`
`_invoke_and_stream` 이 매 turn 시작 시 prepend (MessageRow 영속 포함).
- **PR #2 (compaction) 1건**:
- `CompactionResult.summary_text` 필드 추가. 자동/수동 compaction 결과
summary 가 `sess.queue_system_message()` 로 다음 thread 의 첫 ainvoke 에
inject — plan 명세 ("새 thread 에는 system + 1 summary + 최근 K 메시지")
충족.
- **PR #3 (auto-memory) 6건**:
- `global_memory_dir(config)` + `<data_dir>/global/memory/` 부트스트랩.
`list_memory_paths` 가 global + project 둘 다 deepagents memory= 에 전달.
- Frontmatter `name / description / type` 정식 도입 (`type` ∈ user /
feedback / project / reference). `MemoryType` Literal + `MemoryEntry`
dataclass + `read_entry` / `read_index_entries`.
- `_infer_memory_type` — 키워드 기반 deterministic classifier (no LLM).
`/remember --type=feedback <text>` 로 override 가능.
- `_scrub_secrets` — OpenRouter/Anthropic/OpenAI/AWS/Bearer 토큰 정규식
매칭 후 `<redacted:...>` 치환. `WriteResult.scrubbed` 플래그 + REPL
경고.
- `/memory show <name>` 슬래시 서브명령 — 본문 + (type, scope) 출력.
- `/remember [--global]` / `/forget [--global]` — 두 스코프 명시적 토글.
- **PR #4 (skills) 3건**:
- `project_skills_dir(config, project_key)` — `<data_dir>/projects/<key>/
skills/`. `resolve_skill_sources(config, project_key)` 가 global +
project 두 경로 반환 → project 가 global 을 덮음 (deepagents
"later-wins").
- `list_all_skills(config, project_key)` + `find_skill(config,
project_key, name)` — 두 스코프 merge + scope 라벨 표시.
- `/skill <name>` 동작 정정 — 본문을 REPL 출력만 하던 것을 system
message 로 inject (queue) 하도록 변경. plan 명세 "본문 inject (이번
turn 전체)" 충족. `/skills show <name>` 별도 서브명령 신설 (inject 안
함, 인스펙션만).
- **PR #6 (sub-agent) 4건**:
- `budget.py`: `session:<uuid>` scope 추가. `_scopes_for` 가
`session_id` 받아 ledger 누적. `CostMiddleware` 가 `interactive_session_id`
를 자동 전달. Plan 명세 "sub-agent 는 root session 의 한도에 합산"
충족.
- `subagents.resolve_root_session_id` — `parent_session_id` 체인 walk-up
(cycle guard). Sub-agent CostMiddleware 가 ROOT session 으로 charge.
- `subagents.run_subagent_to_completion` — 실제 ainvoke + 결과 summary 를
부모 세션에 `[sub-agent <id> result]` system message 로 push + sub-
session 자동 `ended` 마킹.
- `/agents` 슬래시 서브명령 구조 (list / spawn / show) — 기존 단순 list
+ 별도 /spawn 을 plan 명세대로 재구성. spawn 시 부모 세션에
`[sub-agent <id> spawned]` system message 자동 insert.
- **PR #7 (governance) 1건**:
- `governance.bootstrap_user_dirs(config)` — 글로벌 MYDEEPAGENT.md +
`global/memory/MEMORY.md` + `skills/` + `projects/` 를 한 호출로
idempotent 부트스트랩. `InteractiveSession.__init__` 에서 호출 (이전엔
`ensure_global_instructions_initialized` 만 호출했음 — memory 글로벌
미준비).
- **PR #8 (Web GUI) 1건**:
- `static/index.html` 을 워크플로우 runs 페이지에서 **세션 목록 페이지**
로 재구성. `static/runs.html` 신설 (기존 runs 목록 archive 위치).
Nav 링크: 대화 → / / Runs (archive) → /runs.html / 새 Workflow Run →
/new.html. `app.js` 에 `renderSessionsList` 핸들러 + `data-page="runs"`
라우팅 추가. Conversation 페이지 `?session=<id>` 쿼리 deep-link 지원.
- **PR #9 (workflow) 2건**:
- `/workflow <name> [--repo=<path>] [--base=<branch>]` 가 실제 백그라운드
`WorkflowEngine.run` 발사하도록 구현 (`_run_workflow_background`).
진행 상태 (started / ended / failed + final_report_path) 가 메인 세션
`MessageRow(role="system")` 로 누적 → SSE 로 GUI 에도 자동 push.
- `/binding show <workflow-name[@version]>` 인자 지원 — 특정 워크플로우의
role → eligible 페르소나 매칭 미리보기 (실행 X).
- **신규/갱신 테스트** (+17 케이스, 685 → **702 passed**):
- test_plan_mode: write_todos 차단 + blocklist sanity 보강
- test_memory: scrub redaction + frontmatter `type` 추론 + explicit
override 3 케이스
- test_skills: project-scope override + find_skill resolution +
resolve_skill_sources(project_key) 4 케이스
- test_subagents: resolve_root_session_id chain walk + missing fallback 2
케이스
- test_budget: session: scope accumulation + session_id 미전달 시 빈
ledger 2 케이스
- test_instructions: governance bootstrap full-skeleton + idempotency 2
케이스
- test_api_static: runs.html 신설 + index.html 재구성 2 케이스
### Added
- **v0.3 PR #9 — Workflow 옵션화 + user 디렉터리 wiring**. Workflow engine 은
주력이 아니라 "옵션" 으로 격하 (사용자가 명시적 `/workflow <name>` 호출 시만