后端: 1. 记忆系统移除 todo_hint 类型——随口记已由 Task 系统承接,todo_hint 语义重叠且无完成追踪 - 全链路清理:常量、校验、默认重要度、30 天 TTL、读取预算、LLM 抽取提示词枚举 - 总预算从四类收缩为三类(preference / constraint / fact) 2. 记忆抽取触发点从 chat-persist 移至 graph-completion——避免随口记消息被误提取为 constraint/preference - chat-persist consumer 不再自动入队 memory.extract.requested,仅负责聊天历史落库 - graph 完成后新增条件发布:检测 UsedQuickNote 标记,调用过 quick_note_create 则跳过记忆抽取 - ResetForNextRun 重置 UsedQuickNote,防止跨轮残留导致后续正常消息记忆抽取被误跳过 3. 任务类查询接口返回 items 补充数据库主键 ID(前端拖拽编排依赖此字段) 前端: 4. 排程视图新增手动编排模式——侧边栏任务块拖拽入周课表 + 悬浮删除热区 + 建议块虚线标识 - TaskClassSidebar 拖拽发起 + 预览态嵌入时间格式化(含周次/星期) - WeekPlanningBoard 外部拖入 / 内部移动 / 悬浮删除区交互 - ScheduleView 手动编排状态机(进入/退出/取消/覆盖确认)+ apply 时同步处理新增与删除
166 lines
8.8 KiB
Go
166 lines
8.8 KiB
Go
package model
|
||
|
||
import "time"
|
||
|
||
const (
|
||
// MemoryItemStatusActive 表示记忆条目可参与检索与注入。
|
||
MemoryItemStatusActive = "active"
|
||
// MemoryItemStatusArchived 表示记忆条目被归档,不再默认参与注入。
|
||
MemoryItemStatusArchived = "archived"
|
||
// MemoryItemStatusDeleted 表示记忆条目已软删除。
|
||
MemoryItemStatusDeleted = "deleted"
|
||
)
|
||
|
||
const (
|
||
// MemoryJobTypeExtract 表示“候选事实抽取”任务。
|
||
MemoryJobTypeExtract = "extract"
|
||
// MemoryJobTypeEmbed 表示“向量化同步”任务(Day1 仅预留)。
|
||
MemoryJobTypeEmbed = "embed"
|
||
// MemoryJobTypeReconcile 表示“冲突消解”任务(Day1 仅预留)。
|
||
MemoryJobTypeReconcile = "reconcile"
|
||
)
|
||
|
||
const (
|
||
// MemoryJobStatusPending 表示任务待执行。
|
||
MemoryJobStatusPending = "pending"
|
||
// MemoryJobStatusProcessing 表示任务执行中。
|
||
MemoryJobStatusProcessing = "processing"
|
||
// MemoryJobStatusSuccess 表示任务执行成功(最终态)。
|
||
MemoryJobStatusSuccess = "success"
|
||
// MemoryJobStatusFailed 表示任务执行失败但可重试。
|
||
MemoryJobStatusFailed = "failed"
|
||
// MemoryJobStatusDead 表示任务不可恢复失败(最终态)。
|
||
MemoryJobStatusDead = "dead"
|
||
)
|
||
|
||
// MemoryItem 对应 memory_items 表,用于保存长期可注入记忆。
|
||
//
|
||
// 职责边界:
|
||
// 1. 该模型只定义存储结构,不承载抽取/决策业务逻辑;
|
||
// 2. Day1 先建表与基础字段,Day2 再补读取注入链路;
|
||
// 3. 向量字段(vector_status/vector_id)仅做状态桥接,不等于向量库真值。
|
||
type MemoryItem struct {
|
||
ID int64 `gorm:"column:id;primaryKey;autoIncrement"`
|
||
|
||
UserID int `gorm:"column:user_id;not null;index:idx_memory_items_user_status_type,priority:1;index:idx_memory_items_user_conv_status,priority:1;index:idx_memory_items_user_asst_run_status,priority:1;index:idx_memory_items_user_type_hash,priority:1;comment:用户ID"`
|
||
ConversationID *string `gorm:"column:conversation_id;type:varchar(64);index:idx_memory_items_user_conv_status,priority:2;comment:会话ID"`
|
||
AssistantID *string `gorm:"column:assistant_id;type:varchar(64);index:idx_memory_items_user_asst_run_status,priority:2;comment:助手ID"`
|
||
RunID *string `gorm:"column:run_id;type:varchar(64);index:idx_memory_items_user_asst_run_status,priority:3;comment:运行ID"`
|
||
|
||
MemoryType string `gorm:"column:memory_type;type:varchar(32);not null;index:idx_memory_items_user_status_type,priority:3;index:idx_memory_items_user_type_hash,priority:2;comment:preference/constraint/fact"`
|
||
Title string `gorm:"column:title;type:varchar(128);not null;comment:记忆标题"`
|
||
Content string `gorm:"column:content;type:text;not null;comment:记忆内容"`
|
||
|
||
NormalizedContent *string `gorm:"column:normalized_content;type:text;comment:标准化内容"`
|
||
ContentHash *string `gorm:"column:content_hash;type:varchar(64);index:idx_memory_items_user_type_hash,priority:3;comment:幂等去重哈希"`
|
||
|
||
Confidence float64 `gorm:"column:confidence;type:decimal(5,4);not null;default:0.6;comment:置信度"`
|
||
Importance float64 `gorm:"column:importance;type:decimal(5,4);not null;default:0.5;comment:重要度"`
|
||
SensitivityLevel int `gorm:"column:sensitivity_level;not null;default:0;comment:敏感级别"`
|
||
|
||
SourceMessageID *int64 `gorm:"column:source_message_id;index:idx_memory_items_source_message;comment:来源消息ID"`
|
||
SourceEventID *string `gorm:"column:source_event_id;type:varchar(64);comment:来源事件ID"`
|
||
IsExplicit bool `gorm:"column:is_explicit;not null;default:false;comment:是否显式记忆"`
|
||
|
||
Status string `gorm:"column:status;type:varchar(16);not null;default:active;index:idx_memory_items_user_status_type,priority:2;index:idx_memory_items_user_conv_status,priority:3;index:idx_memory_items_user_asst_run_status,priority:4;comment:active/archived/deleted"`
|
||
|
||
TTLAt *time.Time `gorm:"column:ttl_at;index:idx_memory_items_ttl;comment:过期时间"`
|
||
LastAccessAt *time.Time `gorm:"column:last_access_at;comment:最后访问时间"`
|
||
CreatedAt *time.Time `gorm:"column:created_at;autoCreateTime"`
|
||
UpdatedAt *time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||
|
||
VectorStatus string `gorm:"column:vector_status;type:varchar(16);not null;default:pending;comment:pending/synced/failed"`
|
||
VectorID *string `gorm:"column:vector_id;type:varchar(128);comment:向量库映射ID"`
|
||
}
|
||
|
||
func (MemoryItem) TableName() string {
|
||
return "memory_items"
|
||
}
|
||
|
||
// MemoryJob 对应 memory_jobs 表,用于承接异步任务。
|
||
//
|
||
// 职责边界:
|
||
// 1. 该表是“可重试状态机”,不是业务事实库;
|
||
// 2. payload_json 只存任务执行最小上下文;
|
||
// 3. status/retry_count/next_retry_at 组合定义可重试行为。
|
||
type MemoryJob struct {
|
||
ID int64 `gorm:"column:id;primaryKey;autoIncrement"`
|
||
|
||
UserID int `gorm:"column:user_id;not null;index:idx_memory_jobs_user_created,priority:1;comment:用户ID"`
|
||
ConversationID *string `gorm:"column:conversation_id;type:varchar(64);comment:会话ID"`
|
||
SourceMessageID *int64 `gorm:"column:source_message_id;comment:来源消息ID"`
|
||
SourceEventID *string `gorm:"column:source_event_id;type:varchar(64);index:idx_memory_jobs_source_event;comment:来源事件ID"`
|
||
|
||
JobType string `gorm:"column:job_type;type:varchar(32);not null;comment:extract/embed/reconcile"`
|
||
IdempotencyKey string `gorm:"column:idempotency_key;type:varchar(128);not null;uniqueIndex:uk_memory_jobs_idempotency;comment:幂等键"`
|
||
PayloadJSON string `gorm:"column:payload_json;type:longtext;not null;comment:任务载荷JSON"`
|
||
|
||
Status string `gorm:"column:status;type:varchar(16);not null;index:idx_memory_jobs_status_next,priority:1;comment:pending/processing/success/failed/dead"`
|
||
RetryCount int `gorm:"column:retry_count;not null;default:0;comment:已重试次数"`
|
||
MaxRetry int `gorm:"column:max_retry;not null;default:6;comment:最大重试次数"`
|
||
NextRetryAt *time.Time `gorm:"column:next_retry_at;index:idx_memory_jobs_status_next,priority:2;comment:下次重试时间"`
|
||
LastError *string `gorm:"column:last_error;type:varchar(2000);comment:最后错误"`
|
||
|
||
CreatedAt *time.Time `gorm:"column:created_at;autoCreateTime;index:idx_memory_jobs_user_created,priority:2"`
|
||
UpdatedAt *time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||
}
|
||
|
||
func (MemoryJob) TableName() string {
|
||
return "memory_jobs"
|
||
}
|
||
|
||
// MemoryAuditLog 对应 memory_audit_logs 表,用于记忆变更审计。
|
||
type MemoryAuditLog struct {
|
||
ID int64 `gorm:"column:id;primaryKey;autoIncrement"`
|
||
|
||
MemoryID int64 `gorm:"column:memory_id;not null;index:idx_memory_audit_memory_id;comment:记忆ID"`
|
||
UserID int `gorm:"column:user_id;not null;index:idx_memory_audit_user_id;comment:用户ID"`
|
||
|
||
Operation string `gorm:"column:operation;type:varchar(32);not null;comment:create/update/archive/delete/restore"`
|
||
OperatorType string `gorm:"column:operator_type;type:varchar(16);not null;comment:system/user"`
|
||
Reason string `gorm:"column:reason;type:varchar(255);not null;default:'';comment:操作原因"`
|
||
|
||
BeforeJSON *string `gorm:"column:before_json;type:longtext;comment:变更前快照"`
|
||
AfterJSON *string `gorm:"column:after_json;type:longtext;comment:变更后快照"`
|
||
|
||
CreatedAt *time.Time `gorm:"column:created_at;autoCreateTime"`
|
||
}
|
||
|
||
func (MemoryAuditLog) TableName() string {
|
||
return "memory_audit_logs"
|
||
}
|
||
|
||
// MemoryUserSetting 对应 memory_user_settings 表,用于用户记忆开关控制。
|
||
type MemoryUserSetting struct {
|
||
UserID int `gorm:"column:user_id;primaryKey;comment:用户ID"`
|
||
|
||
MemoryEnabled bool `gorm:"column:memory_enabled;not null;default:true;comment:总开关"`
|
||
ImplicitMemoryEnabled bool `gorm:"column:implicit_memory_enabled;not null;default:true;comment:隐式记忆开关"`
|
||
SensitiveMemoryEnabled bool `gorm:"column:sensitive_memory_enabled;not null;default:false;comment:敏感记忆开关"`
|
||
|
||
UpdatedAt *time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||
}
|
||
|
||
func (MemoryUserSetting) TableName() string {
|
||
return "memory_user_settings"
|
||
}
|
||
|
||
// MemoryExtractRequestedPayload 是 memory.extract.requested(v1) 事件载荷。
|
||
//
|
||
// 说明:
|
||
// 1. Day1 先承载最小可执行字段;
|
||
// 2. assistant_id/run_id/source_message_id/trace_id 允许为空,后续链路补齐;
|
||
// 3. idempotency_key 必填,用于 memory_jobs 去重与无副作用消费。
|
||
type MemoryExtractRequestedPayload struct {
|
||
UserID int `json:"user_id"`
|
||
ConversationID string `json:"conversation_id"`
|
||
AssistantID string `json:"assistant_id,omitempty"`
|
||
RunID string `json:"run_id,omitempty"`
|
||
SourceMessageID int64 `json:"source_message_id,omitempty"`
|
||
SourceRole string `json:"source_role"`
|
||
SourceText string `json:"source_text"`
|
||
OccurredAt time.Time `json:"occurred_at"`
|
||
TraceID string `json:"trace_id,omitempty"`
|
||
IdempotencyKey string `json:"idempotency_key"`
|
||
}
|