5cf9ad131a56ec1f8f3ccdc9c7339d278a843f81
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6d371afadd |
feat(my-deepagent): v0.4 — workflow generator UI + hot-reload + UX polish
브라우저에서 YAML 안 쓰고도 새 워크플로우 템플릿 만들기 + 즉시 등록. + /new.html / index.html / new-workflow.html / runs.html / conversation.html 의 nav·copy·empty-state 정비. A. /new.html UX: - 제목 "새 Run" → "워크플로우 실행 (고급)" - 상단 info-box: "자유 대화는 여기가 아닙니다 → 메인 페이지" - 모든 필드에 한 줄 hint - Persona 오버라이드 <details> 접힘 B. Nav 재정렬 (5 페이지): - "대화" nav-primary, 나머지 nav-secondary (작고 dim) C. 메인 안내 + CSS: - 메인 / 에 "👋 my-deepagent" info-box 추가 - .info-box / .nav-primary / .nav-secondary / .wf-* 신규 스타일 D. Workflow hot-reload: - api/deps.py get_workflows 가 매 요청 mtime 튜플 검사 후 변경 시 reload - lifespan 도 user dir 포함하도록 _load_workflows_combined E. Workflow generator: - POST /api/workflows: CreateWorkflowRequest → WorkflowTemplate validate → <data_dir>/workflows/<name>@<version>.yaml 저장. 중복 409, validation 422. - static/new-workflow.html: 기본 정보 / Roles / Phases / YAML preview - app.js bootstrapWorkflowGenerator: capability chip 토글, role select 동적, 실시간 YAML preview, XSS 정책 유지 테스트 (test_workflow_generator.py, 7 신규): - 페이지 200 + 마크업 - POST happy / 422 (empty roles) / 422 (unknown role) / 409 (dup) - GET hot-reload after POST - GET hot-reload after external file drop 게이트: - ruff / format / mypy: PASS (142 source files) - pytest -q --ignore=tests/integration/test_e2e_workflow.py --ignore=tests/integration/test_openrouter_smoke.py: 709 passed (+7 신규) - 라이브 smoke: / / new.html / new-workflow.html 모두 200, screenshot OK Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f8335e4515 |
feat(my-deepagent): v0.3 PR #1 — interactive session persistence + LangGraph saver wiring
v0.3의 토대. REPL/GUI 둘 다 장기 대화를 영속해서 `mydeepagent --session <id>`
또는 `GET /api/sessions/{id}`로 어디서든 이어 진행 가능. Claude Code의
`claude --resume` 등가 능력.
Data model
- `persistence/models.py`:
- 신규 `MessageRow` 테이블 — (session_id, seq) UNIQUE, role/content/
tool_calls/token_count/is_summary/archived/ts. LangGraph checkpoint =
source of truth, 이 테이블은 GUI/CLI 빠른 조회 mirror. divergence
rebuild 매커니즘 없음 (단순성 우선).
- `InteractiveSessionRow` 컬럼 8개 추가:
total_input_tokens, total_output_tokens (PR #2 tiktoken으로 정밀화 예정),
model, project_key (sha256(realpath(repo_path))[:16]),
title (첫 user msg 50자), plan_mode (PR #5), parent_session_id (PR #6),
depth (PR #6 sub-agent depth ≤ 3).
- `alembic/versions/684e70f4536a_*.py` (신규):
- `op.batch_alter_table` 사용 — SQLite ALTER constraint 미지원 우회. Postgres는
native DDL.
- 자동생성이 제안한 LangGraph 테이블 (`checkpoints` 등) drop 라인은 의도적으로
제거 (langgraph-checkpoint-postgres가 자체 관리).
- server_default 박아서 기존 row 안전.
CLI
- `cli/interactive.py`:
- REPL 진입 시 `get_checkpointer_ctx(config.database_url)` 컨텍스트 열고
REPL 전체 동안 유지. `build_agent(..., checkpointer=saver)`로 deepagents에
LangGraph saver wire. v0.2 PR #10의 CostMiddleware / AuditToolMiddleware
보존.
- `_invoke_and_stream`이 ainvoke 전후 명시적 MessageRow insert
(user → ainvoke → assistant). last_message_at + total_*_tokens 누적 +
첫 user msg로 title 자동 setter.
- `InteractiveSession.thread_suffix` 도입. /model / /agent / /clear 호출
시 suffix bump → LangGraph thread_id = `{session_id}:{suffix}` 로 새
deepagents 컨텍스트 시작 (compaction과 같은 패턴, PR #2 재사용).
- 신규 `--session <id|prefix>` 옵션: 기존 row 로드 (ended이면 거부) 또는
신규 row insert (AgentPersonaRow upsert + project_key 박음).
- `/clear` 슬래시 갱신: messages.archived=True + 새 thread 시작. 세션 자체
는 살아있음 — `sessions show <id> --all`로 조회 가능.
- `cli/sessions.py` (신규): `mydeepagent sessions list/show/resume/end`.
show <id> [--all]이 archived 메시지까지. 6+ char prefix + 중복 시 명시
에러.
- `cli/main.py`: --session 옵션 + sessions 서브명령 + interactive_command
시그니처 확장.
HTTP API
- `api/models.py`: SessionSummary / MessageInfo / SessionDetail /
CreateSessionRequest / PostMessageRequest / SessionAck DTO 신규 (모두
extra="forbid").
- `api/routes/sessions.py` (신규):
GET /api/sessions?limit=&state=
GET /api/sessions/{id}?all=true (마지막 200 메시지)
POST /api/sessions (persona_name, model_override, repo_path)
POST /api/sessions/{id}/messages (사용자 메시지 append, 동기 persist;
PR #7 GUI에서 background ainvoke 추가)
GET /api/sessions/{id}/stream (SSE — 0.5s polling, last-event-id 헤더
+ ?last_seq 둘 다 지원)
POST /api/sessions/{id}/end
- `api/app.py`: sessions 라우터 마운트.
Tests
- `tests/integration/test_session_persist.py` (5 시나리오):
1. create + post → row + 메시지 + title + token 누적 영속
2. list가 신규 3 세션 모두 포함
3. prefix resolution + 404
4. end 후 메시지 거부 (409)
5. ?all=true가 archived 메시지 surfacing
Gates
- ruff check + ruff format + mypy --strict: PASS (124 source files)
- pytest non-E2E: 608 PASS (25.86 s) — v0.2 PR #3 후 603에서 +5 신규
- pytest E2E real OpenRouter on Postgres: PASS 82.07 s (베이스라인 60–122s
범위 내; DR-3 +20% 임계점 통과)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
0630142c34 |
feat(my-deepagent): v0.2 PR #3 — FastAPI + SSE + minimal Web GUI (mydeepagent serve)
Closes the "GUI 미존재" gap from the user's first-session requirements (REPL + workflow + GUI). v0.2 PR #1's Postgres migration made a second concurrent writer safe; v0.2 PR #2a/#2b wired durable resume; this commit ships the HTTP + browser surface that uses them. No auth, no multi-tenant, single uvicorn worker — per DR-3 boundaries. v0.3+ will add auth, multi-worker fanout, LISTEN/NOTIFY SSE upgrade. Backend - `src/my_deepagent/api/`: - `app.py` create_app() factory. lifespan stores db/config/personas/ workflows on app.state. CORS allow_origin_regex http://localhost(:port)?. /static mount + /, /{page}.html for the HTML frontend. - `models.py` — pydantic v2 DTOs (extra="forbid") for every route. Auto OpenAPI/Swagger via FastAPI's response_model. - `deps.py` — get_db / get_config / get_personas / get_workflows. - `runner.py` — start_new_run / start_resume. Pre-allocates run_id via new `WorkflowEngine.run(pre_allocated_run_id=...)` so the route returns the id immediately while the engine runs in asyncio.create_task. - `sse.py` — 0.5 s poll over run_events.seq. Emits ServerSentEvent rows; sends `event: done` and HTTP-200-closes when run hits terminal. - `routes/{runs,personas,workflows,budget}.py`: GET /api/runs (list, ?limit + ?state) GET /api/runs/{id} (detail + phases + artifacts + events) POST /api/runs (start; mock-able via runner.start_new_run) POST /api/runs/{id}/resume POST /api/runs/{id}/abort GET /api/runs/{id}/events (SSE; Last-Event-ID header + ?last_event_id) GET /api/personas GET /api/workflows GET /api/budget CLI - `cli/serve.py` mydeepagent serve [--host 127.0.0.1] [--port 8000]. Loud stderr warning if --host is not loopback (no auth = footgun). uvicorn.run(factory=True, workers=1). - `cli/main.py` serve command registered. Static frontend (vanilla HTML/JS/CSS, no build system) - index.html — runs list + budget summary - new.html — start-run form (workflow select, repo path, requirements, per-role persona override) - run.html — run detail + live SSE event log + Resume/Abort buttons - app.js — fetch + EventSource. XSS policy HARDCODED at file top: textContent only, innerHTML/insertAdjacentHTML/outerHTML forbidden. - style.css — dark theme, single file. Engine - WorkflowEngine.run(... pre_allocated_run_id: UUID|None = None). None → uuid4() (existing behavior). Set → use that UUID. Backward compatible. Tests - tests/integration/test_api_read.py (5): list empty, get 404, personas seed count (12), workflows seed (>=3), budget empty. - tests/integration/test_api_write.py (5): missing template 400, extra field 422, resume 404, abort 404, mock-runner happy path. - tests/integration/test_api_sse.py (1): seed terminal run + 3 events, drain stream, assert types present + stream closes within 3 s. - tests/integration/test_api_static.py (5): index/new/run HTML 200, app.js content-type + XSS-policy substring assertion, style.css content-type. - All fixtures use httpx ASGITransport + app.router.lifespan_context (httpx does NOT auto-trigger FastAPI lifespan) + sqlite tmp_path. Gates - ruff check + ruff format --check + mypy --strict: PASS (120 source files) - pytest non-E2E: 603 PASS (12.15 s) — +16 from new API tests - pytest E2E real OpenRouter on Postgres: PASS 60.44 s (baseline 71–122 s range; well within DR-3 acceptance threshold ≤+20%) Manual browser verification deferred to a follow-up (docker compose up, mydeepagent serve, open http://localhost:8000). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |