Files
smartmate/backend/service/agentsvc/memory_rpc_reader.go
Losita e1819c5653 Version: 0.9.74.dev.260505
后端:
1.阶段 6 memory 服务化 CP1-CP3 落地
- 新增 cmd/memory 独立进程入口,落地 services/memory dao/rpc/sv 与 memory zrpc pb
- 将 memory.extract.requested outbox 消费与 memory worker 迁入 cmd/memory,单体 worker 不再消费 memory outbox
- 新增 gateway/client/memory、shared/contracts/memory 和 shared/ports memory port
- 将 /api/v1/memory/items* HTTP 管理面切到 memory zrpc,gateway 只保留鉴权、限流、幂等、参数绑定和响应透传
- 新增 memory Retrieve RPC,并将 agent 主链路 memory reader 切到 memory zrpc 读取
- 补充 agent memory RPC reader 适配器,保留注入侧 observer / metrics 观测能力
- 保留旧 backend/memory 核心实现作为迁移期复用与回退面,cmd/memory 内部继续复用既有 Module / ReadService 逻辑
- 补充 memory.rpc 示例配置,更新单体 outbox 发布边界与 memory handler 注释口径
2026-05-05 13:52:49 +08:00

122 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package agentsvc
import (
"context"
"errors"
memorymodel "github.com/LoveLosita/smartflow/backend/memory/model"
memoryobserve "github.com/LoveLosita/smartflow/backend/memory/observe"
memorycontracts "github.com/LoveLosita/smartflow/backend/shared/contracts/memory"
)
// MemoryRPCReaderClient 描述 agent 读取 memory zrpc 所需的最小能力。
//
// 职责边界:
// 1. 只读取候选记忆,不暴露管理写接口;
// 2. 不要求调用方知道 gateway/client/memory 的具体实现;
// 3. 错误原样返回给预取链路,由 agent 侧负责软降级和观测记录。
type MemoryRPCReaderClient interface {
Retrieve(ctx context.Context, req memorycontracts.RetrieveRequest) ([]memorycontracts.ItemDTO, error)
}
type memoryRPCReader struct {
client MemoryRPCReaderClient
observer memoryobserve.Observer
metrics memoryobserve.MetricsRecorder
}
// NewMemoryRPCReader 创建跨进程 memory reader 适配器。
//
// 职责边界:
// 1. 只把 agent 内部的 memorymodel.RetrieveRequest 转成共享契约;
// 2. 不持有 memory.Module避免 CP3 后 agent 主链路继续直连本进程记忆服务;
// 3. observer / metrics 只用于 agent 注入观测,不参与 retrieve 业务调用;
// 4. client 为空时返回 nil让 SetMemoryReader 保持既有“无 reader 则不注入”的降级语义。
func NewMemoryRPCReader(
client MemoryRPCReaderClient,
observer memoryobserve.Observer,
metrics memoryobserve.MetricsRecorder,
) MemoryReader {
if client == nil {
return nil
}
if observer == nil {
observer = memoryobserve.NewNopObserver()
}
if metrics == nil {
metrics = memoryobserve.NewNopMetrics()
}
return &memoryRPCReader{
client: client,
observer: observer,
metrics: metrics,
}
}
// Retrieve 通过 memory zrpc 读取候选记忆并转换回 agent 内部 DTO。
func (r *memoryRPCReader) Retrieve(ctx context.Context, req memorymodel.RetrieveRequest) ([]memorymodel.ItemDTO, error) {
if r == nil || r.client == nil {
return nil, errors.New("memory rpc reader client is nil")
}
items, err := r.client.Retrieve(ctx, memorycontracts.RetrieveRequest{
Query: req.Query,
UserID: req.UserID,
ConversationID: req.ConversationID,
AssistantID: req.AssistantID,
RunID: req.RunID,
MemoryTypes: append([]string(nil), req.MemoryTypes...),
Limit: req.Limit,
Now: req.Now,
})
if err != nil {
return nil, err
}
return toMemoryModelItems(items), nil
}
// MemoryObserver 暴露 agent 注入链路使用的 observer保持 CP3 切流前后的注入观测连续。
func (r *memoryRPCReader) MemoryObserver() memoryobserve.Observer {
if r == nil || r.observer == nil {
return memoryobserve.NewNopObserver()
}
return r.observer
}
// MemoryMetrics 暴露 agent 注入链路使用的 metrics避免 RPC reader 切流后指标静默丢失。
func (r *memoryRPCReader) MemoryMetrics() memoryobserve.MetricsRecorder {
if r == nil || r.metrics == nil {
return memoryobserve.NewNopMetrics()
}
return r.metrics
}
// toMemoryModelItems 只做跨层 DTO 字段搬运,不改变排序、过滤和记忆内容。
func toMemoryModelItems(items []memorycontracts.ItemDTO) []memorymodel.ItemDTO {
if len(items) == 0 {
return nil
}
result := make([]memorymodel.ItemDTO, 0, len(items))
for _, item := range items {
result = append(result, memorymodel.ItemDTO{
ID: item.ID,
UserID: item.UserID,
ConversationID: item.ConversationID,
AssistantID: item.AssistantID,
RunID: item.RunID,
MemoryType: item.MemoryType,
Title: item.Title,
Content: item.Content,
ContentHash: item.ContentHash,
Confidence: item.Confidence,
Importance: item.Importance,
SensitivityLevel: item.SensitivityLevel,
IsExplicit: item.IsExplicit,
Status: item.Status,
TTLAt: item.TTLAt,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
return result
}