Skip to content

feat(memory): generic ABC-driven Desktop config surface for memory providers - #38340

Closed
erosika wants to merge 5 commits into
NousResearch:mainfrom
erosika:feat/desktop-memory-provider-config
Closed

feat(memory): generic ABC-driven Desktop config surface for memory providers#38340
erosika wants to merge 5 commits into
NousResearch:mainfrom
erosika:feat/desktop-memory-provider-config

Conversation

@erosika

@erosika erosika commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What this is

A generic, ABC-driven config surface for Desktop memory providers. Alternative direction to #37546 (Hindsight Desktop panel), addressing the per-provider-by-name concern raised in that PR's review.

The problem

Desktop has no per-provider memory config UI. #37546 added one for Hindsight, but the way it did it was per-plugin: a hardcoded memory_providers.py registry, a memory.provider === 'hindsight' conditional, and a dedicated endpoint pair. Adding mem0 next means copy-pasting another panel, another conditional, another endpoint — hand-maintaining N plugin pages.

The config abstraction already exists. Every MemoryProvider declares get_config_schema() + save_config() (used by hermes memory setup). The registry in #37546 re-declared config the providers already own — two sources of truth that drift.

What this does instead

Pushes the Desktop config surface onto the existing MemoryProvider ABC:

  • Derive renderer metadata (label/kind/tier/options) from the schema providers already declare. Legacy schemas work untouched.
  • read_config() default for the conventional layout; providers with non-conventional storage override it (Honcho routes through its own host-block resolution).
  • One generic GET/PUT /api/memory/providers/{name}/config pair that delegates to the ABC. No per-provider branching, no registry.
  • when conditional fields carried through generically — Hindsight's mode-gated fields are the worked example.

All 9 providers are supported via auto-derivation; no bespoke per-provider code.

Notable behavior

  • Secrets are write-only: the value is never returned, only an is_set flag. A blank secret on save preserves the existing value.
  • Saving a provider's settings does NOT change memory.provider. Activation stays a separate action.
  • tier (safe/advanced) groups behavior-changing fields under a disclosure — editable, not locked (Desktop users may not use the CLI wizard).

Status

Backend + logic only. 375 tests green, 0 regressions. The React panel (generic renderer, dirty tracking, inline validation, when-aware rendering) and a cross-provider conformance test are still to come — opening as draft so the shared surface is reviewable first.

Test plan

pytest tests/agent/test_memory_config_surface.py \
       tests/hermes_cli/test_memory_provider_config_endpoints.py \
       tests/plugins/memory/test_hindsight_config_surface.py \
       tests/plugins/memory/honcho/test_honcho_config_surface.py

Refs #37546

Derive renderer metadata (label/kind/tier/placeholder/options) from the
existing get_config_schema() fields, add a default read_config() for the
conventional <home>/<name>/config.json + env-secret layout, and a generic
desktop_config_surface() assembler. Secrets are write-only (value never
returned). All additive and back-compatible; the CLI wizard is untouched.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers comp/plugins Plugin system and bundled plugins labels Jun 3, 2026
erosika added 3 commits June 3, 2026 16:20
Add GET/PUT /api/memory/providers/{name}/config that delegate entirely to
the provider ABC (desktop_config_surface / save_config). No per-provider
branching, no parallel registry, no stranded persistence logic. Saving a
provider's settings does NOT change memory.provider — activation stays a
separate action. Secrets write-only; blank secret preserves the existing
value; invalid select values return a field-scoped 400.
Expand Honcho's get_config_schema with label/kind/tier metadata (safe-tier
credentials + advanced-tier behavior knobs) and override read_config to
route through HonchoClientConfig.from_global_config(), honoring host-keyed
blocks, camelCase keys, multi-file resolution, and the HONCHO_API_KEY env
fallback — none of which the generic conventional reader understands. The
api_key value is never returned, only its set-state. save_config already
writes honcho.json, reused as-is.
Carry through the schema's when clause and add field_visible() so the
generic layer expresses the conditional/enum-gated fields the unified
schema must support (e.g. Hindsight's mode-gated api_url/api_key). The
write path skips fields whose when doesn't match submitted values,
mirroring the CLI wizard so a mode=cloud save doesn't persist the
local_external row. Hindsight is the worked example — its real 32-field
schema is verified end-to-end.
@erosika
erosika force-pushed the feat/desktop-memory-provider-config branch from 8802788 to 519b9b5 Compare June 3, 2026 16:41
Memory providers already declare config (get_config_schema), persist it
(save_config), and read it (read_config). Desktop only needed a presentation
layer on top. Keep it to ONE module:

- hermes_cli/memory_provider_surface.py owns the whole Desktop surface:
  field kinds, tiers, label derivation, when-gating (field_visible),
  enrich_schema, and build_surface().
- The default read_config() is inlined on the MemoryProvider ABC (~20 lines,
  conventional <home>/<name>/config.json + env secrets), so agent/ stays
  self-contained and never imports the presentation layer.
- Honcho overrides read_config() for its host-keyed honcho.json.

No parallel registry, no per-provider UI code; all providers covered
generically. Presentation vocabulary stays out of the core runtime.
@erosika
erosika force-pushed the feat/desktop-memory-provider-config branch from 519b9b5 to 96904a7 Compare June 3, 2026 17:40
@erosika

erosika commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Closing this. It solves the wrong layer.

The actual issue is that the desktop memory.provider dropdown is a hardcoded enum in constants.ts (['', 'builtin', 'honcho']), disconnected from discover_memory_providers() which the backend already runs. This PR built a generic config-panel/persistence framework on top of that dropdown without addressing the hardcoding — and #37546 just adds one more hardcoded entry plus a hand-built panel.

Replacing with a smaller change: wire the dropdown to discovery, drop the hardcoded enum. A config panel, if needed, is a separate follow-up scoped to providers that actually have UI-configurable settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants