From 11c08fe62e273d4c0ccdaf998cdb15a53d3f00f5 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:34:41 +0800 Subject: [PATCH] fix(go): resolve tenant model IDs in memory create/update without hard failure (#17176) --- internal/service/memory.go | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/internal/service/memory.go b/internal/service/memory.go index 3e0129434e..9a5892e350 100644 --- a/internal/service/memory.go +++ b/internal/service/memory.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "log/slog" "ragflow/internal/common" "ragflow/internal/entity" models "ragflow/internal/entity/models" @@ -343,20 +344,25 @@ type ListMemoryResponse struct { // req := &CreateMemoryRequest{Name: "MyMemory", MemoryType: []string{"semantic"}, EmbdID: "embd1", LLMID: "llm1"} // resp, err := service.CreateMemory("tenant123", req) func (s *MemoryService) CreateMemory(tenantID string, req *CreateMemoryRequest) (*CreateMemoryResponse, error) { + // Resolve tenant model IDs, mirroring Python's ensure_tenant_model_ids_for_params. + // Resolution failure is non-fatal (e.g. Builtin models that have no + // tenant_model row) — we leave the tenant_*_id fields nil and proceed. modelProvider := NewModelProviderService() if req.LLMID != "" && req.TenantLLMID == nil { tenantLLMID, err := modelProvider.ResolveModelID(tenantID, entity.ModelTypeChat, req.LLMID) if err != nil { - return nil, err + slog.Warn("CreateMemory: failed to resolve tenant LLM id", "tenant_id", tenantID, "llm_id", req.LLMID, "err", err) + } else if tenantLLMID != "" { + req.TenantLLMID = &tenantLLMID } - req.TenantLLMID = &tenantLLMID } if req.EmbdID != "" && req.TenantEmbdID == nil { tenantEmbdID, err := modelProvider.ResolveModelID(tenantID, entity.ModelTypeEmbedding, req.EmbdID) if err != nil { - return nil, err + slog.Warn("CreateMemory: failed to resolve tenant embedding id", "tenant_id", tenantID, "embd_id", req.EmbdID, "err", err) + } else if tenantEmbdID != "" { + req.TenantEmbdID = &tenantEmbdID } - req.TenantEmbdID = &tenantEmbdID } if err := common.ValidateName(req.Name); err != nil { @@ -481,12 +487,35 @@ func (s *MemoryService) UpdateMemory(tenantID string, memoryID string, req *Upda updateDict["permissions"] = perm } + // Resolve tenant model IDs when llm_id / embd_id is provided, mirroring + // Python's ensure_tenant_model_ids_for_params. The frontend sends model + // names (or model_id UUIDs); the backend must resolve them to + // tenant_model row IDs so downstream code that depends on + // tenant_llm_id / tenant_embd_id stays consistent after an update. + // Resolution failure is non-fatal (e.g. Builtin models). + modelProvider := NewModelProviderService() if req.LLMID != nil { updateDict["llm_id"] = *req.LLMID + if req.TenantLLMID == nil && *req.LLMID != "" { + resolved, err := modelProvider.ResolveModelID(tenantID, entity.ModelTypeChat, *req.LLMID) + if err != nil { + slog.Warn("UpdateMemory: failed to resolve tenant LLM id", "tenant_id", tenantID, "llm_id", *req.LLMID, "err", err) + } else if resolved != "" { + updateDict["tenant_llm_id"] = resolved + } + } } if req.EmbdID != nil { updateDict["embd_id"] = *req.EmbdID + if req.TenantEmbdID == nil && *req.EmbdID != "" { + resolved, err := modelProvider.ResolveModelID(tenantID, entity.ModelTypeEmbedding, *req.EmbdID) + if err != nil { + slog.Warn("UpdateMemory: failed to resolve tenant embedding id", "tenant_id", tenantID, "embd_id", *req.EmbdID, "err", err) + } else if resolved != "" { + updateDict["tenant_embd_id"] = resolved + } + } } if req.TenantLLMID != nil {