diff --git a/docs/plan.md b/docs/plan.md index 00a7269..0f5d408 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -145,7 +145,18 @@ class BackendConfig(BaseModel, frozen=True): - Body validation via the same pydantic v2 models used elsewhere. - WebSocket remains deferred unless SSE fails under transcript volume. -## 2. Directory Layout +### 1.7 Workflow Orchestration + +- **NOT USED in v0.x. Deferred to v1.0 multi-tenant ADR (DR-3).** +- v3 / earlier v4 r1 drafts named `temporalio` here. After v0.1.0 shipped + and the OpenRouter E2E path was proven, single-user single-machine durable + resume turned out to be reachable with **LangGraph `AsyncPostgresSaver` + checkpoint + DB phase-state machine + `sweep_orphan_runs`** — all of + which already exist in the v0.2 codebase. The Temporal server + worker + + determinism rules are weight that v1.0's multi-tenant decision can + re-evaluate; in the meantime, `temporalio` is **not** in + `my-deepagent/pyproject.toml`, no worker process, no `apps/worker/`. +- See DR-3 below + §23 v0.2 row matrix for the migration replacement. v4 r1 collapses the v3 multi-package monorepo into a single `my-deepagent/` project. The TS `apps/`, `packages/`, `tests/`, `scripts/` trees were deleted @@ -1924,6 +1935,7 @@ M5+: |----|----------|-----------|--------| | DR-1 | **v3 → v4 major bump: delete TS monorepo, rewrite in Python on LangChain `deepagents`.** | (1) Claude/Anthropic direct API cost is prohibitive for a single-user toolchain. (2) OpenRouter cost-tuned models (DeepSeek, etc.) require a multi-turn, tool-using agent harness; `deepagents` is Python-only with no 1:1 TS port. (3) Switching languages is shorter than reimplementing the harness. | Step 0 (commit `0e61b2d`) deleted `apps/`, `packages/`, `tests/`, `scripts/`, pnpm/tsconfig metadata. The Python rewrite lives at `my-deepagent/` and reached Step 15 (real OpenRouter E2E PASS, ~$0.05/run) before the v3 codebase was removed. CC-39's separate `OpenRouterAdapter` is replaced by `my_deepagent.session.build_agent` (deepagents 0.6.1 with LocalShellBackend + SafetyShellMiddleware). v3 CC counters frozen; v4 begins its own series. Recovery: `git checkout pre-python-rewrite -- `. | | DR-2 | **SQLite for v0.1.0; Postgres migration scheduled as v0.2 PR #1, ahead of M8-Py FastAPI.** | The v4 r1 first draft suggested Postgres should re-enter "with Temporal." That was wrong: Temporal (M5-Py) does not write to the `my-deepagent` ORM tables — it has its own backing store. The real trigger for Postgres is *a second writer on `runs` / `run_phases` / `llm_calls`*, which first appears with FastAPI (M8-Py) and the eventual web GUI. Until then, SQLite WAL handles single-process concurrent reads fine and saves new users a Docker prerequisite at install time. | Migration sequencing: v0.2 PR #1 = "stop writers → `alembic downgrade base` against SQLite → regenerate baseline against Postgres → adjust JSON column types / partial-unique-index syntax / UPSERT for the Postgres dialect → add `pg_isready` doctor check." M5-Py (Temporal) can be implemented on either SQLite or Postgres my-deepagent DB; the order (v0.2-PR-1 → M5-Py → M8-Py) is chosen for stack consistency, not necessity. Supersedes the "Postgres parked indefinitely" wording from earlier v4 r1 drafts. | +| DR-3 | **Temporal deferred to v1.0 multi-tenant ADR. v0.x ships zero Temporal code.** | v3 and early v4 r1 drafts had Temporal as the canonical durable-workflow layer (M5-Py). For 1-user 1-machine CLI/REPL/web-GUI workloads, the same durability guarantee is reachable with (1) LangGraph `AsyncPostgresSaver` (already in deps, v0.2 PR #1) + (2) `RunPhaseRow` / `LlmCallRow` state machine per-commit (already in models) + (3) `sweep_orphan_runs` at startup (already in `recovery.py`). Temporal server + worker + deterministic-workflow rules + `apps/worker/` are weight without proportional payoff at this scale. The decision to add Temporal becomes meaningful only when v1.0 introduces multi-tenant / multi-machine fanout. | M5-Py row in §23 marked **DEFERRED v1.0+**. `temporalio` is NOT added to `my-deepagent/pyproject.toml`. No `apps/worker/`. v0.2 PR #2 implements `runs resume` via the LangGraph + DB state machine path (see §23 row). Supersedes "M5-Py: Temporal worker NEXT" in earlier v4 r1 drafts. Open question for v1.0 ADR: Temporal vs Hatchet vs in-house Postgres-based workflow runner. | ### Future Open Questions @@ -1970,6 +1982,9 @@ v4 r1 order (Python, status as of v0.1.0): | Step 14 | TUI recovery (M7-Py) | DEFERRED — not in v0.1.0 | | Step 15 | End-to-end real OpenRouter integration test | DONE (`733c9be`) | | Step 0-purge | Delete v3 TS monorepo per DR-1 | DONE (`0e61b2d`) | -| v0.2 PR #1 | **Postgres migration** — Alembic baseline regen against Postgres 16; SQLite removed. Triggered by upcoming M8-Py multi-process writes, sequenced *before* M8-Py for a clean cut. Adds `pg_isready` doctor check; `mydeepagent doctor` no longer offers SQLite fast-path. | PLANNED (next) | -| M5-Py | Temporal worker (`apps/worker`). Temporal server uses its own backing DB (separate Postgres `temporal` namespace) and does not touch `my-deepagent`'s ORM tables, so M5-Py works on either SQLite or Postgres my-deepagent DB. Targeted post-v0.2-PR-1 for stack consistency. | PLANNED | -| M8-Py | FastAPI + SSE (`apps/api`). Requires Postgres (see §1.3 trigger table). | PLANNED | +| v0.2 PR #1 | **Postgres migration** — Alembic baseline regen against Postgres 16; SQLite moved to dev-only (test). `psycopg`/`asyncpg`/`langgraph-checkpoint-postgres` in prod, `aiosqlite` in dev. Dialect-aware `insert_for` upsert helper. Live E2E PASS on Postgres. | DONE (`e21a524`) | +| v0.2 PR #2a | **LangGraph `AsyncPostgresSaver` engine wiring**. `WorkflowEngine.run()` opens a saver context once; `_run_phase` forwards `checkpointer=saver` to `build_agent` and passes `config={"configurable": {"thread_id": f"run:{run_id}:phase:{phase_id}"}}` to `agent.ainvoke`. Foundation for v0.2 PR #2b. | PLANNED | +| v0.2 PR #2b | **`mydeepagent runs resume ` real implementation**. `existing_run_id` branch in `WorkflowEngine.run`, RunBindingRow + workflow_templates.definition reload, first-non-completed-phase resume via LangGraph thread replay. 5 integration scenarios. Closes v0.1.0 KNOWN LIMIT. | PLANNED | +| v0.2 PR #3 | **FastAPI + SSE + minimal Web GUI** (`mydeepagent serve`). vanilla HTML/JS/CSS, no build system. read+write run routes, SSE stream (0.5s polling, v0.3 NOTIFY upgrade ADR), Korean-only UI, `--host 127.0.0.1` enforced. Manual browser verification end-to-end. | PLANNED | +| M5-Py | Temporal worker (`apps/worker`). | **DEFERRED to v1.0+ per DR-3.** Single-user durable resume is reachable with the LangGraph + DB + sweep_orphan_runs stack now landing in v0.2 PR #2. Re-evaluate when multi-tenant / multi-machine ADR opens at v1.0. | +| M8-Py | Standalone `apps/api` package. | **Absorbed into v0.2 PR #3.** No separate apps/api directory; FastAPI lives inside `my-deepagent/src/my_deepagent/api/`. M8-Py row retained as historical marker. |