P2: tool adapter layer, mock host, frame pipeline, and local web UI

- MockHostAdapter (tests/mock_host): in-memory editing model with opaque
  entity ids, id invalidation, token-bucket rate limiting, snapshot/restore
  with cap, event subscription, and a stdlib-zlib PNG encoder producing
  time-varying non-black frames
- HostToolExecutor: all 26 tool handlers mapped to HostAdapter calls,
  snapshot orchestration for mutating batches, concurrent scan_timeline
  frame pipeline with token bucket and RateLimited backoff, undo_session()
  restoring per-batch snapshots in reverse, get_params min/max/choices
  reflection
- Web UI (core[webui] extra): FastAPI + single-page vanilla JS, chat log,
  pending-confirmation list with approve/reject endpoints (timeout defaults
  to reject), progress, undo-session, snapshot management; SSE push + POST,
  bound to 127.0.0.1
- Host error types (HostError/EntityNotFound/RateLimited) and shared
  TokenBucket
- P2 acceptance chain: import -> place -> split -> ripple delete ->
  effect + param -> frame verification (non-black, pixel changes at cut
  and after effect) -> undo_session restores original state

Tests: 129 passed via uv run pytest (no network)
This commit is contained in:
2026-08-25 02:40:43 +08:00
parent e0db5ab2cf
commit 1b66a70859
25 changed files with 3807 additions and 4 deletions
+5
View File
@@ -10,12 +10,17 @@ dependencies = [
[dependency-groups]
dev = [
"pytest>=8.0",
"quercus-core[webui]",
]
[tool.uv]
# 根目录不是可安装包,仅作 workspace 锚点
package = false
[[tool.uv.index]]
url = "https://pypi.org/simple"
default = true
[tool.uv.sources]
quercus-core = { workspace = true }