refactor: multi-provider memory adapters with scan-based builtin (#227)

* refactor: restructure memory into multi-provider adapters, remove manifest.json dependency

- Rename internal/memory/provider to internal/memory/adapters with per-provider subdirectories (builtin, mem0, openviking)
- Replace manifest.json-based delete/update with scan-based index from daily files
- Add mem0 and openviking provider adapters with HTTP client, chat hooks, MCP tools, and CRUD
- Wire provider lifecycle into registry (auto-instantiate on create, evict on update/delete)
- Split docker-compose into base stack + optional overlays (qdrant, browser, mem0, openviking)
- Update admin UI to support dynamic provider config schema rendering

* chore(lint): fix all golangci-lint issues for clean CI

* refactor(docker): replace compose overlay files with profiles

* feat(memory): add built-in memory multi modes

* fix(ci): golangci lint

* feat(memory): edit built-in memory sparse design
This commit is contained in:
晨苒
2026-03-14 06:04:13 +08:00
committed by GitHub
parent 27607d582d
commit 627b673a5c
75 changed files with 8253 additions and 2107 deletions
+21 -5
View File
@@ -72,7 +72,11 @@ import (
mcpwebfetch "github.com/memohai/memoh/internal/mcp/providers/webfetch"
mcpfederation "github.com/memohai/memoh/internal/mcp/sources/federation"
"github.com/memohai/memoh/internal/media"
memprovider "github.com/memohai/memoh/internal/memory/provider"
memprovider "github.com/memohai/memoh/internal/memory/adapters"
membuiltin "github.com/memohai/memoh/internal/memory/adapters/builtin"
memmem0 "github.com/memohai/memoh/internal/memory/adapters/mem0"
memopenviking "github.com/memohai/memoh/internal/memory/adapters/openviking"
storefs "github.com/memohai/memoh/internal/memory/storefs"
"github.com/memohai/memoh/internal/message"
"github.com/memohai/memoh/internal/message/event"
"github.com/memohai/memoh/internal/models"
@@ -253,17 +257,29 @@ func provideMemoryLLM(modelsService *models.Service, queries *dbsqlc.Queries, lo
return &lazyLLMClient{modelsService: modelsService, queries: queries, timeout: 30 * time.Second, logger: log}
}
func provideMemoryProviderRegistry(log *slog.Logger, chatService *conversation.Service, accountService *accounts.Service, manager *mcp.Manager) *memprovider.Registry {
func provideMemoryProviderRegistry(log *slog.Logger, chatService *conversation.Service, accountService *accounts.Service, manager *mcp.Manager, queries *dbsqlc.Queries, cfg config.Config) *memprovider.Registry {
registry := memprovider.NewRegistry(log)
builtinRuntime := handlers.NewBuiltinMemoryRuntime(manager)
registry.RegisterFactory(memprovider.BuiltinType, func(_ string, _ map[string]any) (memprovider.Provider, error) {
return memprovider.NewBuiltinProvider(log, builtinRuntime, chatService, accountService), nil
fileStore := storefs.New(log, manager)
registry.RegisterFactory(string(memprovider.ProviderBuiltin), func(_ string, providerConfig map[string]any) (memprovider.Provider, error) {
runtime, err := membuiltin.NewBuiltinRuntimeFromConfig(log, providerConfig, builtinRuntime, fileStore, queries, cfg)
if err != nil {
return nil, err
}
return membuiltin.NewBuiltinProvider(log, runtime, chatService, accountService), nil
})
registry.Register("__builtin_default__", memprovider.NewBuiltinProvider(log, builtinRuntime, chatService, accountService))
registry.RegisterFactory(string(memprovider.ProviderMem0), func(_ string, config map[string]any) (memprovider.Provider, error) {
return memmem0.NewMem0Provider(log, config, fileStore)
})
registry.RegisterFactory(string(memprovider.ProviderOpenViking), func(_ string, config map[string]any) (memprovider.Provider, error) {
return memopenviking.NewOpenVikingProvider(log, config)
})
registry.Register("__builtin_default__", membuiltin.NewBuiltinProvider(log, builtinRuntime, chatService, accountService))
return registry
}
func startMemoryProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, mpService *memprovider.Service, registry *memprovider.Registry) {
mpService.SetRegistry(registry)
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
resp, err := mpService.EnsureDefault(ctx)