Files
smartmate/backend/newAgent/model/state_store.go
Losita d8280cc647 Version: 0.9.26.dev.260417
后端:
1. Prompt 层从 execute 专属骨架重构为全节点统一四段式 buildUnifiedStageMessages
  - 新增 unified_context.go:定义 StageMessagesConfig + buildUnifiedStageMessages 统一骨架,所有节点(Chat/Plan/Execute/Deliver/DeepAnswer)共用同一套 msg0~msg3 拼装逻辑
  - 新增 conversation_view.go:通用对话历史渲染 buildConversationHistoryMessage,各节点复用,不再各自维护提取逻辑
  - 新增 chat_context.go / plan_context.go / deliver_context.go:各节点自行渲染 msg1(对话视图)和 msg2(工作区),统一层只负责"怎么拼",不再替节点决定"放什么"
  - Chat/Plan/Deliver/Execute 的 BuildXXXMessages 全部从 buildStageMessages 切到 buildUnifiedStageMessages,移除旧路径
  - 删除 execute_pinned.go:execute 记忆渲染合并到统一层 renderUnifiedMemoryContext
  - Plan prompt 不再在 user prompt 中拼装任务类 ID 列表和 renderStateSummary,改为依赖 msg2 规划工作区;Chat 粗排判断从"上下文有任务类 ID"改为"批量调度需求"
  - Deliver prompt 新增 IsAborted/IsExhaustedTerminal 区分,支持粗排收口和主动终止场景
2. Execute ReAct 上下文简化——移除归档搬运、窗口裁剪和重复工具压缩
  - 移除 splitExecuteLoopRecordsByBoundary、findLatestExecuteBoundaryMarker、tailExecuteLoops、compressExecuteLoopObservationsByTool、buildEarlyExecuteReactSummary、trimExecuteMessage1ByBudget 等六个函数
  - 移除 executeLoopWindowLimit / executeConversationTurnLimit / executeMessage1MaxRunes 等预算常量
  - msg1 不再从历史中归档上一轮 ReAct 结果,只保留真实对话流(user + assistant speak),全量注入
  - msg2 不再按 loop_closed / step_advanced 边界切分"归档/活跃",直接全量注入全部 ReAct Loop 记录
  - token 预算由统一压缩层兜底,prompt 层不再做提前裁剪
3. 压缩层从 Execute 专属提升为全节点通用 UnifiedCompact
  - 删除 execute_compact.go(Execute 专属压缩文件)
  - 新增 unified_compact.go:UnifiedCompactInput 参数化,各节点(Plan/Chat/Deliver/Execute)构造时从自己的 NodeInput 提取公共字段,消除对 Execute 的直接依赖
  - CompactionStore 接口扩展 LoadStageCompaction / SaveStageCompaction,各节点按 stageKey 独立维护压缩状态互不覆盖
  - 非 4 段式消息时退化成按角色汇总统计,确保 context_token_stats 仍然刷新
4. Retry 重试机制全面下线
  - dao/agent.go:saveChatHistoryCore / SaveChatHistory / SaveChatHistoryInTx 移除 retry_group_id / retry_index /
  retry_from_user_message_id / retry_from_assistant_message_id 四个参数,修复乱码注释
  - dao/agent-cache.go:移除 ApplyRetrySeed 和 extractMessageHistoryID 两个方法
  - conv/agent.go:ToEinoMessages 不再回灌 retry_* 字段到运行期上下文
  - service/agentsvc/agent.go:移除 chatRetryMeta 及 resolveRetryGroupID / buildRetrySeed 等全部重试逻辑
  - service/agentsvc/agent_quick_note.go:整个文件删除(retry 快速补写路径已无用)
  - service/events/chat_history_persist.go:移除 retry 参数传递
5. 节点层瘦身 + 可见消息逐条持久化
  - agent_nodes.go 大幅简化:Chat/Plan/Execute/Deliver 节点方法移除 ToolSchema 注入、状态摘要渲染等逻辑,只做参数转发和状态落盘
  - 新增 visible_message.go:persistVisibleAssistantMessage 统一处理可见 assistant speak 的实时持久化,失败仅记日志不中断主流程
  - 新增 llm_debug.go:logNodeLLMContext 统一打印 LLM 上下文调试日志
  - graph_run_state.go 新增 PersistVisibleMessageFunc 类型 + AgentGraphDeps.PersistVisibleMessage 字段
  - service/agentsvc/agent_newagent.go 精简主循环,注入 PersistVisibleMessage 回调;agent_history.go 精简历史构建
  - token_budget.go 移除 Execute 专属预算检查,统一到通用预算

前端:
1. 移除 retry 相关 UI 和类型
  - agent.ts 移除 retry_group_id / retry_index / retry_total 字段及 normalize 逻辑
  - AssistantPanel.vue 移除 retry 相关 UI 和交互代码(约 700 行精简)
  - dashboard.ts 移除 retry 相关类型定义
  - AssistantView.vue 微调
2. ContextWindowMeter 压缩次数展示和数值格式优化
  - 新增 formatCompactCount 工具函数,千位以上用 k 单位压缩(如 80k)
  - 新增压缩次数显示
3.修复了新对话发消息时,user和assistant消息被自动调换的bug

仓库:无
2026-04-17 22:19:38 +08:00

97 lines
4.9 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 model
import (
"context"
schedule "github.com/LoveLosita/smartflow/backend/newAgent/tools/schedule"
)
// AgentStateSnapshot 是需要持久化的 agent 运行态最小快照。
//
// 设计说明:
// 1. 只保存恢复执行所需的 RuntimeState 和 ConversationContext
// 2. 不保存 Request每轮请求级天然不跨连接
// 3. 不保存 Deps依赖注入每次由 Service 层重建);
// 4. 不保存 ToolSchemas每次请求由 Service 层重新注入)。
type AgentStateSnapshot struct {
RuntimeState *AgentRuntimeState `json:"runtime_state"`
ConversationContext *ConversationContext `json:"conversation_context"`
ScheduleState *schedule.ScheduleState `json:"schedule_state,omitempty"`
OriginalScheduleState *schedule.ScheduleState `json:"original_schedule_state,omitempty"`
}
// AgentStateStore 定义 agent 状态持久化的最小接口。
//
// 职责边界:
// 1. 只负责"存 / 取 / 删"三个原子操作;
// 2. 不负责序列化细节(由实现层决定 JSON / protobuf
// 3. 不负责业务级状态校验,校验仍在 node / graph 层完成。
//
// 实现层:
// 1. dao/cache.go 上的 CacheDAO 隐式实现该接口Go duck typing
// 2. newAgent 包不直接 import dao由 Service 层在组装 Deps 时注入。
type AgentStateStore interface {
// Save 序列化并保存一份 agent 状态快照。
//
// 语义:
// 1. 同一 conversationID 被覆盖写入,保证 Redis 里始终只有最新快照;
// 2. 实现层应设 TTL避免已完成的任务快照永不清理。
Save(ctx context.Context, conversationID string, snapshot *AgentStateSnapshot) error
// Load 读取并反序列化 agent 状态快照。
//
// 返回值语义:
// 1. (snapshot, true, nil):命中快照,正常返回;
// 2. (nil, false, nil):未命中,不是错误,调用方应走新建对话路径;
// 3. (nil, false, error):真正的存储层错误。
Load(ctx context.Context, conversationID string) (*AgentStateSnapshot, bool, error)
// Delete 删除指定会话的 agent 状态快照。
//
// 语义:
// 1. 删除是幂等的key 不存在也视为成功;
// 2. 典型调用时机Deliver 节点任务完成后清理。
Delete(ctx context.Context, conversationID string) error
}
// ScheduleStateProvider 定义加载 ScheduleState 的接口。
// 由 DAO 层或 Service 层实现,注入到 AgentGraphDeps 中。
// 使用接口而非具体 DAO 类型,避免 model → dao 的循环依赖。
type ScheduleStateProvider interface {
LoadScheduleState(ctx context.Context, userID int) (*schedule.ScheduleState, error)
// LoadTaskClassMetas 只加载指定任务类的约束元数据,供 Plan 节点提前消费。
LoadTaskClassMetas(ctx context.Context, userID int, taskClassIDs []int) ([]schedule.TaskClassMeta, error)
}
// ScopedScheduleStateProvider 定义“按本轮任务类范围加载 ScheduleState”的可选增强接口。
//
// 设计说明:
// 1. 负责:在 Execute / RoughBuild 首次加载状态时,把 DayMapping、TaskClasses 与 pending 任务限定在本轮 task_class_ids 相关窗口;
// 2. 不负责:改变既有 ScheduleStateProvider 的基础能力,老实现仍可只实现 LoadScheduleState
// 3. 兜底策略:若调用方拿到的 provider 不实现该接口,则回退到全量 LoadScheduleState再走工具层 scope 裁剪。
type ScopedScheduleStateProvider interface {
LoadScheduleStateForTaskClasses(ctx context.Context, userID int, taskClassIDs []int) (*schedule.ScheduleState, error)
}
// SchedulePersistor 定义持久化 ScheduleState 变更的接口。
// 由 Service 层或 DAO 层实现,注入到 AgentGraphDeps 中。
// 使用接口而非具体 DAO 类型,避免 model → dao 的循环依赖。
type SchedulePersistor interface {
PersistScheduleChanges(ctx context.Context, original, modified *schedule.ScheduleState, userID int) error
}
// CompactionStore 定义上下文压缩的持久化接口。
// 由 Service 层实现(组合 DAO + Redis Cache注入到各阶段 NodeInput。
type CompactionStore interface {
LoadCompaction(ctx context.Context, userID int, chatID string) (summary string, watermark int, err error)
SaveCompaction(ctx context.Context, userID int, chatID string, summary string, watermark int) error
SaveContextTokenStats(ctx context.Context, userID int, chatID string, statsJSON string) error
// LoadStageCompaction 按 stageKey 加载压缩摘要和水位线。
// stageKey 区分不同节点(如 "execute"/"plan"/"chat"/"deliver"
// 使各节点可以独立维护各自的压缩状态,互不覆盖。
LoadStageCompaction(ctx context.Context, userID int, chatID string, stageKey string) (summary string, watermark int, err error)
// SaveStageCompaction 按 stageKey 保存压缩摘要和水位线。
SaveStageCompaction(ctx context.Context, userID int, chatID string, stageKey string, summary string, watermark int) error
}