Add external memory approval queue UI - #1975
kiosvantra wants to merge 3 commits into
Conversation
Review — substantive, but needs rework before mergeThanks @kiosvantra — the contract design (provider-oriented review surface, SQLite candidates table shape, optional config registration via 🔴 Blocker 1: hardcoded private IP addresses leak into a public repo
DEFAULT_OLLAMA_URL = "http://10.0.100.50:11434"
DEFAULT_QDRANT_URL = "http://10.0.100.16:6333"These are RFC1918 private addresses (10.0.100.0/24) that point at someone's specific internal network. nesquena/hermes-webui is a public repo — once these land on master, they're permanent in the git history and grep-able by anyone scanning the codebase for environment leaks. Project policy is no IPs, no internal hostnames, no org-specific addresses anywhere in the public source tree. Even baked-in as "defaults" they're a leak: a user who never configures a custom value would have the WebUI silently attempt to connect to your internal Ollama/Qdrant instances on first use, and the addresses are now public knowledge. Required change: remove these constants entirely. Connection URLs must come exclusively from one of:
When no URL is configured, the provider should disable itself with a clear "not configured" UI state rather than fall back to a hardcoded default that points anywhere. 🔴 Blocker 2: "HMS Knowledge" baked in as a built-in provider
ProviderSpec(
id="hms_knowledge",
label="HMS Knowledge",
kind="builtin",
db_path=home / "hms_knowledge" / "knowledge.sqlite",
config_path=home / "hms_knowledge.json",
)Plus "HMS Knowledge" appears nowhere else in nesquena/hermes-webui or hermes-agent — verified by Required change: drop the If "HMS Knowledge" is genuinely meant to be a generic well-known provider that ships with the WebUI, it needs (a) public documentation explaining what it is, (b) a public reference implementation, (c) no internal-IP defaults, and (d) a separate PR proposing the general "built-in providers" concept for review. 🟡 Concern 3: scope is large for a feature with no prior issue+1100 LOC adding a new top-level UI section, a new For features at this scope, the project flow is typically:
This avoids the contributor spending 1000+ LOC on something the maintainer might shape differently or want narrower. It also gives users a place to find context after the PR ships ("what is this provider thing for?"). Could you file an issue first describing the use case + contract design? I'm happy to discuss the API shape there before the implementation lands. The current implementation can be referenced in the issue so the conversation is grounded in concrete code. 🟡 Concern 4: the contract overlap with existing memory infrastructureHermes already has nine memory plugins under This PR's Worth either:
🟢 What's solidThe actual contract design is good:
Once the IP/HMS/scope concerns are resolved, the architectural bones are good. Suggested path forward
Closing this PR is not the right call — the work is mostly fine. But it can't merge with the current defaults baked in. Please refile with the architectural fixes and I'll prioritize the v2 review. Thanks again for the PR — happy to help shape the v2 in the tracking issue once you file it. |
552c4d9 to
f14f25d
Compare
|
Thanks for the detailed review — I addressed the blockers and rewrote the PR branch history. Changes made:
Local verification: python -m pytest tests/test_external_memory_api.py tests/test_external_memory_review_ui.py -q
# 25 passedI also scanned the PR diff and updated PR body for the removed provider-specific/internal references. Since the earlier review comment quotes removed implementation details, could you please edit or minimize that comment from the public PR thread if appropriate? |
Add a provider-neutral review surface for custom external memory approval queues. Providers are registered explicitly through external_memory_providers.json; no provider-specific endpoints, hostnames, IPs, model names, or collection names are bundled.
f14f25d to
0271e1f
Compare
|
Bumping — last review pass landed May 9, blockers were addressed and the branch was force-pushed to a single sanitized commit May 10. CI is currently UNSTABLE; can you triage the failing checks so we can move this from Specifically, please drop a comment confirming:
Once CI is green and the |
|
Thanks for the bump. I checked both the PR and the linked design issue to make sure I was looking at the right place. The design discussion on #1980 looks separate from this CI question; the unstable signal appears to be on this PR branch. From what I can see, the latest workflow run for this branch did not actually execute any jobs. It completed with gh pr checks 1975 --repo nesquena/hermes-webui --watch=false
# no checks reported on the 'external-memory-providers-panel-clean' branch
gh run view 25636760675 --repo nesquena/hermes-webui --json conclusion,jobs,url
# conclusion: action_required
# jobs: []
# url: https://github.com/nesquena/hermes-webui/actions/runs/25636760675So I do not currently see a failing ruff/pytest job to triage. This looks like the workflow is waiting for maintainer approval to run, rather than a test failure from the force-push/rebase. The branch currently contains the sanitized implementation updates for the earlier blockers:
If you approve/rerun the workflow and a concrete job goes red, I’ll triage that run directly. |
|
Thanks — I found the CI failure and pushed a small fix. The failing job was: It was failing because the External Memory review actions still used browser-native Fix pushed in
Focused local verification: uvx --from pytest pytest \
tests/test_sprint33.py::test_no_native_prompt_calls_remain_in_static_js \
tests/test_kanban_ui_static.py::test_kanban_dashboard_parity_core_controls_are_native \
-q
# 2 passed
uvx --from pytest pytest \
tests/test_external_memory_api.py \
tests/test_external_memory_review_ui.py \
tests/test_sprint33.py \
tests/test_kanban_ui_static.py \
-q
# 66 passedThe new workflow run for the pushed commit is back in Once that workflow is approved/rerun, I’ll triage any remaining concrete failures if they appear. |
|
Removing CI is green now after the Branch is CLEAN/MERGEABLE. Maintainer-review label is kept since this is a 1377-LOC architectural UI feature that needs careful review. Re-queuing for the next sweep. |
|
Closing this PR — recommending it move upstream to Thanks @kiosvantra for the substantial work here, and to @IkaRiche on #1980 for the KiLu validation offer. After end-to-end re-review (code is clean, CI green, sanitization done correctly), I'm closing the PR rather than merging it. The reasoning is about where this functionality lives, not whether it should exist. What's good about the PR
Why the WebUI repo is the wrong homeAlways-visible UI for a niche workflow. The Plugin layer is the right abstraction. Hermes Agent already has 10 memory plugins ( Indexing protocol coupling. Despite the provider-neutral framing on the WebUI surface, Marginal-benefit screen at 1377 LOC. The WebUI repo is conservative about feature surface area. 1377 LOC of new architecture for a feature that two contributors are excited about — without first having a design conversation that the maintainer signed off on — is exactly the wrong ratio. Compare: every recently-merged feature here is ≤200 LOC or has been broken into composable hardening passes. Recommended path forwardThe work shouldn't be wasted. The right placement is: 1. Move the approval-queue logic into a 2. Surface review in the WebUI through
3. Keep #1980 open as the design venue. The shape we landed on through review (three-gate model: review → write-policy → persistence with verifiable read-back) is provider-agnostic by design, so a hermes-agent plugin implementing those same fail-closed invariants is what the validation pass on #1980 should test. What I'm doing right now
If a Thank you @kiosvantra for the thoughtful design and patient iteration. The contract you converged on is the right shape — it just belongs one layer down. |
|
Thanks for the thorough re-review and for spelling out the ownership boundary. That makes sense to me. The fail-closed approval flow and provider-neutral contract are the parts I most wanted to validate here; if the WebUI should stay default-off / hidden-until-opted-in for this class of workflow, moving the approval queue into the I’ll treat #1975 as a validated prototype and carry the useful pieces forward there:
Thanks again for the review. |
Summary
Adds a generic External Memory Approval Queue surface to the WebUI Memory panel.
This is intentionally provider-neutral. WebUI ships no provider-specific backend, endpoint, hostname, model, collection, or built-in memory provider. Users opt in by registering a custom SQLite-backed approval queue in
external_memory_providers.json.Tracking issue: #1980
What changed
api/external_memory.pyas a generic backend helper for external memory approval queues./api/external-memory/*routes for:External Memorysection under the existing Memory panel.Provider contract
A provider can appear in the UI when it is explicitly registered from the active Hermes home:
{ "providers": [ { "id": "custom_store", "label": "Custom Store", "db_path": "custom_memory/items.sqlite", "config_path": "custom_memory/config.json" } ] }The provider database exposes this SQLite table:
Optional indexing settings must come from provider config or environment variables. If they are absent, approval returns a clear not-configured error instead of using defaults.
Tests
python -m pytest tests/test_external_memory_api.py tests/test_external_memory_review_ui.py -q # 25 passed