chore(release): v2.6.0 — RFC-014, RFC-015, recall timeout#130
Conversation
…endpoints Merges and reconciles the two RFC-015 implementations: Local (Jinja2 SPA): - web/templates/ (base.html, index.html, config_editor.html, 5 components) - web/static/css/design_tokens.css (full ZettelForge design system) - Jinja2Templates wiring with StaticFiles mount - GET / -> templates.TemplateResponse - GET /config -> config editor page - GET /api/version -> version + stats endpoint - SPA uses POST with JSON body for search - HTML_PAGE inline string removed Remote (flat JS SPA): - web/ui/ (index.html, 6 JS components, 7 JS views, assets, fonts) - web/ui/index.html read from disk verbatim via Path.read_text() - 13 new API endpoints (health, config R/W, graph, entities, history, ingest, telemetry, storage, logs, SSE streams) - docs: RFC-015, web-api.md, module-inventory.md, use-web-interface.md - tests/test_web_api.py Also includes: - Configurable content size limits (RFC-014) - Config-driven per-call-site LLM token budgets - Recall timeout support (PR #129)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62f6583276
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Prepares the v2.6.0 release by adding a Jinja2-based Web UI (templates + design tokens), expanding/adjusting the FastAPI web backend endpoints, and updating release/docs metadata.
Changes:
- Add Jinja2 template-based SPA pages (
/and/config) with componentized HTML/CSS. - Update
web/app.pyto serve templates/static assets and expose multiple management/system endpoints. - Bump docs + changelog to v2.6.0 and update guidance around config-driven LLM token budgets/content limits.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 23 comments.
Show a summary per file
| File | Description |
|---|---|
| web/templates/index.html | New Jinja2 SPA search/recall UI with inline JS rendering |
| web/templates/config_editor.html | New configuration editor UI (form + YAML textarea) |
| web/templates/components/tab_bar.html | Tab navigation component styling/markup |
| web/templates/components/synthesis_block.html | Synthesis rendering component styling/markup |
| web/templates/components/search_bar.html | Search input + button component |
| web/templates/components/result_card.html | Result card component styling/markup |
| web/templates/components/remember_panel.html | “Remember”/ingest panel component styling/markup |
| web/templates/base.html | Base layout, header/nav/footer, and global styling |
| web/static/css/design_tokens.css | Shared design tokens for the Jinja2 UI |
| web/app.py | Backend updates: templates/static mounting + multiple API endpoints |
| docs/reference/configuration.md | Version bump + token budget section updates |
| docs/index.md | Documentation index version bump |
| docs/how-to/upgrade.md | Upgrade guide updated for 2.6.0 |
| docs/how-to/troubleshoot.md | Troubleshooting guide version bump + wording updates |
| docs/explanation/llm-budgets-and-timeouts.md | Version bump + wording tweak for config-driven budgets |
| CHANGELOG.md | Add v2.6.0 release entry |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…x TemplateResponse signature - Add jinja2>=3.0.0 to pyproject.toml web and dev extras (CI was failing with ImportError on all 22 web API tests) - Set ZETTELFORGE_LLM_PROVIDER=mock in test_web_api.py conftest to prevent ingest tests from timing out against real Ollama - Rewrite /api/history to match the remote RFC-015 implementation: returns a flat JSON array with limit/days query params instead of the wrapper dict with pre-mapped fields - Fix TemplateResponse signature (request object first) to silence Starlette deprecation warning
- Add escHtml() and cssToken() helper functions to index.html SPA (caused JS errors in browser when rendering search results) - Add shared apiHeaders() helper to base.html (available on all pages) - Fix /config route to pass config_yaml and config_path to template (config_editor.html rendered blank without these variables) - Rewrite config_editor.js: uses /api/config (not /api/v1/config), sends JSON via PUT (not form-encoded POST), works with real backend - Fix stale doc anchors pointing to #per-call-site-max_tokens-budgets- hardcoded-v252 (renamed in v2.6.0 to config-driven) - Fix llm-budgets-and-timeouts.md wording — no longer says 'today the values are hardcoded' since v2.6.0 moved them to LLMConfig
Three blockers found in code review of the RFC-015 web GUI:
1. config_page (/config HTML route) called _to_dict, which was defined as
a nested function inside get_config_endpoint. Every render hit a
NameError that was silently swallowed by a bare except, leaving
config_yaml = "" and forcing the SPA to fall back to /api/config.
Promoted _to_dict to a module-level _config_to_dict helper used by
both routes.
2. update_config compared top-level payload keys against a set of
dotted-path restart-required fields, so {"embedding": {"provider": "x"}}
was reported as applied: ["embedding"], pending_restart: [], silently
telling operators a restart-required change had taken effect.
Added _flatten_keys to walk the nested payload to dotted leaf paths
and lifted the restart set to module scope as _RESTART_REQUIRED_FIELDS.
3. /config HTML route had no auth guard. /api/config was protected, but
the page shell (and once #1 was fixed, the server-rendered YAML body)
was reachable without an API key. Added Depends(require_api_guard)
to the route and made the YAML body redact secrets before serializing.
Tests:
Added four regression tests in tests/test_web_api.py covering nested
restart-required flags, nested non-restart application, /config auth
gate (via monkeypatch of API_KEY because it is captured at module import
time), and /config server-side YAML render. 24 passed, 2 skipped.
Note on the original review's blocker #2 (multi-tenancy regression on
graph and entity endpoints): not a regression. There is no per-tenant
MemoryManager._knowledge_graph anywhere in community or enterprise.
get_knowledge_graph() is a process-wide singleton; get_mm_for_request
is a stub returning the default MemoryManager. The old code's
getattr(tenant_mm, "_knowledge_graph", None) always returned None,
so the new singleton call is a functional improvement, not a regression.
No code change needed.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v2.6.0 Release
Features
New API endpoints (web/app.py)
New web UIs
Docs
Internal