Release Date: 2026-03-08
Version: v1.0.0
v1.0.0 是 Sage 企业级智能体平台的正式版发布,标志着产品从实验阶段进入生产就绪阶段。本版本从两个核心维度进行了重大升级:
- SAgents Agent 内核: 全新的 Session 管理体系、AgentFlow 编排引擎、全局 SessionManager
- App 应用层: 可视化工作台系统、跨平台桌面端、实时协作增强
核心文件: sagents/session_runtime.py
- 引入全局
SessionManager统一管理会话生命周期 - 支持父子会话关联追踪
- 自动扫描所有会话(根会话 + 子会话),建立 ID 到 workspace 的映射
- 子会话按需加载,不常驻内存
class SessionManager:
def __init__(self, session_root_space: str, enable_obs: bool = True):
self._sessions: Dict[str, Session] = {} # 根会话缓存
self._all_session_paths: Dict[str, str] = {} # 全局路径索引新路径结构:
{session_root_space}/
├── {session_id}/ # 根会话
│ ├── session_context.json # 统一配置文件
│ ├── messages.json # 消息历史
│ └── sub_sessions/ # 子会话目录
│ └── {sub_session_id}/
│ ├── session_context.json
│ └── messages.json
关键变更:
- 会话路径从
workspace改为sessions - Agent 工作空间独立为
agents/{agent_id} - 统一使用
session_context.json替代旧版多文件配置
核心方法:
run_stream_with_flow(): 基于 Flow 的执行引擎_ensure_session_context(): 自动合并保存的 system_contextconfigure_runtime(): 运行时签名检测,配置变更时自动重置 Agent 缓存
核心文件: sagents/flow/schema.py
支持节点类型:
| 节点类型 | 类名 | 用途 |
|---|---|---|
| Agent | AgentNode |
执行单个 Agent |
| Sequence | SequenceNode |
顺序执行一组节点 |
| If | IfNode |
条件分支 |
| Switch | SwitchNode |
多路分支(用于 agent_mode 选择) |
| Loop | LoopNode |
循环执行,带安全熔断 |
核心文件: sagents/sagents.py -> _build_default_flow()
Standard Hybrid Flow:
├── AgentNode: task_router # 任务路由
├── IfNode: is_deep_thinking # 深度思考(可选)
│ └── AgentNode: task_analysis
├── SwitchNode: agent_mode # 模式选择
│ ├── "fibre" -> AgentNode: fibre
│ ├── "simple" -> simple_agent_body
│ └── "multi" -> multi_agent_full
└── IfNode: enable_more_suggest # 更多建议(可选)
└── AgentNode: query_suggest
核心文件: sagents/flow/executor.py
- 递归解析并执行 AgentFlow
- 集成 ConditionRegistry 条件判断
- 自动注册 ToDoTool 用于多智能体任务检查
- 支持 Agent 动态获取和配置覆盖
核心文件: sagents/agent/fibre/orchestrator.py
Fibre 模式采用全新的 Agent Definition + Session Runtime 分离架构:
FibreOrchestrator
├── sub_agents: Dict[str, AgentDefinition] # Agent 定义(配置层)
├── session_manager: SessionManager # 全局会话管理
└── output_queue: asyncio.Queue # 流式输出队列
1. 动态子智能体生成
sys_spawn_agent(): 动态创建领域专家子智能体- 支持自定义 System Prompt(不少于 300 字结构化定义)
- 自动命名冲突解决(
agent_id_1,agent_id_2...) - Agent Definition 纯配置化,可复用、可序列化
2. 并行任务委派
sys_delegate_task(): 支持同时委派多个任务并行执行- 自动 Session ID 生成(
{parent_session_id}_sub_{n}) - 任务结果自动聚合,统一返回给父智能体
- 支持任务命名和原始任务追溯
3. 层级深度控制
- 最大层级限制:4 级(防止无限递归)
- 深度检测:
_get_session_depth()实时计算 - 自委派防护:禁止智能体将任务委派给自己
4. 长时任务支持
- 小时级任务执行:支持持续运行数小时的复杂任务
- 会话状态持久化:
session_context.save()自动保存 - 断点续执行:通过 Session ID 恢复未完成的任务
- 任务工作空间隔离:每个子任务独立目录结构
{virtual_workspace}/
├── tasks/
│ └── {task_name}/
│ ├── execution/ # 执行过程文件
│ ├── results/ # 最终结果
│ └── sub_tasks/ # 子任务目录
5. 递归编排能力
- 任何子智能体都可成为编排者
- 子智能体可继续创建自己的子智能体
- 层级树状管理:
get_session_hierarchy()获取完整会话树 - 级联中断:
interrupt_session()中断会话及其所有子会话
核心文件: sagents/agent/fibre/tools.py
| 工具 | 功能 | 使用场景 |
|---|---|---|
sys_spawn_agent |
创建子智能体 | 需要领域专家时 |
sys_delegate_task |
委派任务 | 任务可并行化时 |
sys_finish_task |
报告结果 | 子任务完成时 |
核心文件: sagents/prompts/fibre_agent_prompts.py
主智能体(Orchestrator):
- 职责:规划、分解、委派
- 决策逻辑:简单任务自行处理,复杂任务分解委派
- 并行策略:最大化并行执行效率
子智能体(Strand):
- 职责:执行具体任务
- 递归能力:复杂子任务可继续委派
- 强制报告:必须通过
sys_finish_task报告结果
简单任务(自行处理):
├── 1-3 步可完成
├── 仅需标准工具
└── 线性执行路径
复杂任务(委派):
├── >3 个阶段
├── 需领域专业知识
├── 可并行化
└── 开放式需求
1. 会话隔离
- 每个子智能体独立 Session
- 独立 ToolManager 和 SkillManager
- 继承父会话配置,支持自定义覆盖
2. 结果汇总机制
- 优先使用
sys_finish_task标准接口 - 降级方案:AI 自动总结执行日志
- 专业汇报格式:执行摘要 + 关键产出 + 分析结论
3. 错误处理
- 任务验证:前置检查所有任务参数
- 会话冲突检测:防止重复绑定
- 异常捕获:详细错误日志和堆栈跟踪
业务影响:
- 支持复杂多步骤任务(如完整项目开发、系统重构)
- 多智能体并行工作,显著提升效率
- 长时任务可靠执行,支持断点续传
- 层级管理清晰,便于任务追踪和调试
核心文件: sagents/sagents.py -> SAgent.run_stream()
参数变更:
async def run_stream(
self,
input_messages: Union[List[Dict], List[MessageChunk]],
model: Any,
model_config: Dict[str, Any],
system_prefix: str,
agent_workspace: str, # 新增:Agent 工作空间
default_memory_type: str, # 新增:默认记忆类型
tool_manager: Optional[ToolManager] = None,
skill_manager: Optional[SkillManager] = None,
session_id: Optional[str] = None,
user_id: Optional[str] = None,
deep_thinking: Optional[Union[bool, str]] = None,
max_loop_count: int = 50,
agent_mode: Optional[str] = None, # 新增:Agent 模式
more_suggest: bool = False,
force_summary: bool = False,
system_context: Optional[Dict[str, Any]] = None,
available_workflows: Optional[Dict[str, Any]] = None,
context_budget_config: Optional[Dict[str, Any]] = None,
custom_sub_agents: Optional[List[Dict[str, Any]]] = None,
custom_flow: Optional[AgentFlow] = None, # 新增:自定义流程
) -> AsyncGenerator[List[MessageChunk], None]关键特性:
- 参数校验强化(必填参数检查)
- 自动注入 session_id 到消息
- 支持自定义 AgentFlow
- 性能计时日志(首个内容耗时、完整执行耗时)
核心文件: sagents/session_runtime.py -> Session._agent_registry
| Agent Key | 类名 | 用途 |
|---|---|---|
| simple | SimpleAgent |
简单模式 Agent |
| task_analysis | TaskAnalysisAgent |
任务分析 |
| task_decompose | TaskDecomposeAgent |
任务分解 |
| task_executor | TaskExecutorAgent |
任务执行 |
| task_observation | TaskObservationAgent |
任务观察 |
| task_completion_judge | TaskCompletionJudgeAgent |
完成判断 |
| task_planning | TaskPlanningAgent |
任务规划 |
| task_summary | TaskSummaryAgent |
任务总结 |
| workflow_select | WorkflowSelectAgent |
工作流选择 |
| query_suggest | QuerySuggestAgent |
查询建议 |
| task_router | TaskRouterAgent |
任务路由 |
| fibre | FibreAgent |
Fibre 编排 Agent |
核心文件: sagents/utils/lock_manager.py
- 会话级锁隔离
- 安全释放机制
safe_release() - 自动清理会话锁
# 使用示例
lock = get_session_run_lock(session_id)
async with lock:
# 执行会话逻辑
pass核心文件: sagents/session_runtime.py
_session_id_var: contextvars.ContextVar[Optional[str]] = contextvars.ContextVar("session_id", default=None)
@contextmanager
def session_scope(session_id: Optional[str]):
token = _session_id_var.set(session_id)
try:
yield session_id
finally:
_session_id_var.reset(token)- 自动追踪 Agent 执行
- 集成 OpenTelemetry
- Token 使用统计
init_user_memory_context耗时监控load_recent_skill_to_context耗时监控set_session_history_context耗时监控
核心组件:
| 组件 | 路径 | 功能 |
|---|---|---|
| WorkbenchPreview | components/chat/WorkbenchPreview.vue |
工作台主容器 |
| WorkbenchTimeline | components/chat/workbench/WorkbenchTimeline.vue |
时间轴导航 |
| WorkbenchItemRenderer | components/chat/workbench/WorkbenchItemRenderer.vue |
项渲染器 |
| workbench Store | stores/workbench.js |
Pinia 状态管理 |
核心文件: app/desktop/ui/src/stores/workbench.js
// State
const items = ref([]) // 所有工作台项
const currentIndex = ref(0) // 当前选中索引
const isRealtime = ref(true) // 实时模式
const isListView = ref(false) // 列表/单例模式
const currentSessionId = ref(null) // 当前会话ID
// 会话隔离
const filteredItems = computed(() => {
if (!currentSessionId.value) return items.value
return items.value.filter(item => item.sessionId === currentSessionId.value)
})| 类型 | 数据结构 | 去重策略 |
|---|---|---|
| file | {filePath, fileName} |
按 filePath 去重 |
| code | {language, code} |
按 code 内容去重 |
| tool_call | {id, function} |
按 tool_call_id 去重 |
渲染器列表:
PdfRenderer.vue- PDF 文档DocxRenderer.vue- Word 文档PptxRenderer.vue- PPT 演示XlsxRenderer.vue- Excel 表格ImageRenderer.vue- 图片文件CodeRenderer.vue- 代码文件MarkdownRenderer.vue- MarkdownHtmlRenderer.vue- HTML 文件ExcalidrawRenderer.vue- 手绘图TextRenderer.vue- 纯文本
核心文件: app/desktop/ui/src/components/chat/MessageRenderer.vue
双机制处理:
// 1. onMounted - 处理初始工具调用
onMounted(() => {
if (props.message.tool_calls) {
props.message.tool_calls.forEach((toolCall) => {
workbenchStore.addItem({ type: 'tool_call', data: toolCall })
})
}
})
// 2. watch - 处理实时更新的工具结果
watch(() => props.message, (newMessage) => {
if (newMessage?.tool_calls) {
newMessage.tool_calls.forEach((toolCall) => {
const toolResult = getParsedToolResult(toolCall)
if (toolResult) {
workbenchStore.updateToolResult(toolCall.id, toolResult)
}
})
}
}, { deep: true })function extractFileReferences(content) {
const markdownRegex = /\[([^\]]+)\]\(([^)]+)\)/g
// 提取 file:// 路径和绝对路径
// 过滤文件夹路径
}function extractCodeBlocks(content) {
const codeRegex = /```(\w+)?\n([\s\S]*?)```/g
// 提取语言类型和代码内容
}核心配置: app/desktop/tauri/tauri.conf.json
支持平台:
| 平台 | 架构 | 构建目标 | 安装包 |
|---|---|---|---|
| macOS | Intel | x86_64-apple-darwin |
DMG |
| macOS | Apple Silicon | aarch64-apple-darwin |
DMG |
| Windows | x86_64 | x86_64-pc-windows-msvc |
NSIS |
| Linux | x86_64 | x86_64-unknown-linux-gnu |
DEB |
macOS (main.rs):
#[cfg(target_os = "macos")]
fn set_activation_policy_accessory() {
unsafe {
let app = NSApp();
app.setActivationPolicy_(
NSApplicationActivationPolicy::NSApplicationActivationPolicyAccessory,
);
}
}Windows (main.rs):
#[cfg(target_os = "windows")]
{
use std::os::windows::process::CommandExt;
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
}| 脚本 | 平台 | 功能 |
|---|---|---|
build.sh |
macOS/Linux | 并行构建(前端 + Sidecar) |
build_windows.ps1 |
Windows | PowerShell 构建 |
release-desktop.yml |
CI/CD | GitHub Actions 多平台构建 |
核心文件: app/desktop/core/services/chat/stream_manager.py
- 单例模式管理所有活跃会话
- 支持断线重连 (
/api/stream/resume/{session_id}) - 客户端断开检测和自动清理
核心文件: app/desktop/core/routers/chat.py
| 接口 | 方法 | 功能 |
|---|---|---|
/api/chat |
POST | 标准流式聊天 |
/api/web-stream |
POST | Web 端流式(带鉴权) |
/api/stream/resume/{session_id} |
GET | 断线重连 |
/api/stream/active_sessions |
GET | 活跃会话列表 |
async def stream_api_with_disconnect_check(generator, request: Request, lock: asyncio.Lock, session_id: str):
try:
async for chunk in generator:
if await request.is_disconnected():
raise GeneratorExit
yield chunk
except (asyncio.CancelledError, GeneratorExit):
await interrupt_session(session_id, "客户端断开连接")
raise
finally:
# 清理资源
await safe_release(lock, session_id, "流结束清理")核心文件: app/desktop/core/routers/mcp.py
| 接口 | 功能 |
|---|---|
POST /api/mcp/add |
添加 MCP 服务器 |
GET /api/mcp/list |
获取服务器列表 |
DELETE /api/mcp/{name} |
删除服务器 |
POST /api/mcp/{name}/refresh |
刷新连接 |
支持协议:
streamable_http- HTTP 流式sse- Server-Sent Eventsstdio- 标准输入输出
| 问题 | 修复方案 | 文件 |
|---|---|---|
| Session 路径混乱 | 统一路径结构,分离 session_space 和 agent_workspace | session_runtime.py |
| 子会话管理困难 | 引入全局 SessionManager,自动扫描所有会话 | session_runtime.py |
| Agent 执行流程硬编码 | 引入 AgentFlow 声明式编排 | flow/schema.py, flow/executor.py |
| 并发锁冲突 | 引入 LockManager 全局锁管理 | utils/lock_manager.py |
| 会话状态丢失 | 统一使用 session_context.json 持久化 | session_context.py |
| 问题 | 修复方案 | 文件 |
|---|---|---|
| 实时消息文件引用丢失 | watch 监听消息变化,动态提取 |
MessageRenderer.vue |
| 工作台项 ID 冲突 | 引入计数器生成唯一 ID | workbench.js |
| 切换 Session 状态残留 | Session ID 变化时调用 resetState |
WorkbenchPreview.vue |
| 工具结果不更新 | 分离工具调用和结果处理逻辑 | MessageRenderer.vue |
| 客户端断开未清理 | 添加断开检测和资源清理 | chat.py |
-
Session 路径变更
- 旧:
{workspace}/{session_id}/ - 新:
{session_root_space}/{session_id}/ - Agent 工作空间:
{sage_home}/agents/{agent_id}/
- 旧:
-
SAgent.run_stream 参数变更
- 新增必填参数:
agent_workspace,default_memory_type - 移除参数:
tool_manager,skill_manager从签名中移除(通过 SessionContext 传递) - 新增可选参数:
custom_flow,agent_mode
- 新增必填参数:
-
Session 持久化格式
- 旧:
session_status_*.json+agent_config.json - 新: 统一
session_context.json
- 旧:
-
工作台状态管理
- 工作台项现在严格按 Session ID 隔离
- 切换会话时自动清空工作台
-
MessageRenderer 逻辑重构
watch深度监听消息变化- 文件引用和代码块提取时机变化
sagents/
├── sagents.py # SAgent 主入口
├── session_runtime.py # SessionRuntime + SessionManager
├── flow/
│ ├── schema.py # AgentFlow 定义
│ ├── executor.py # Flow 执行器
│ └── conditions.py # 条件判断注册表
├── context/
│ ├── session_context.py # SessionContext
│ └── messages/
│ └── message_manager.py # 消息管理
└── utils/
└── lock_manager.py # 锁管理
app/desktop/
├── core/
│ ├── routers/
│ │ ├── chat.py # 流式聊天接口
│ │ └── mcp.py # MCP 管理接口
│ └── services/
│ └── chat/
│ ├── manager.py # 会话管理
│ └── stream_manager.py # 流管理
├── ui/src/
│ ├── stores/
│ │ └── workbench.js # 工作台状态
│ └── components/chat/
│ ├── WorkbenchPreview.vue # 工作台主组件
│ ├── MessageRenderer.vue # 消息渲染
│ └── workbench/ # 工作台渲染器
└── tauri/
├── src/main.rs # Rust 主入口
└── tauri.conf.json # Tauri 配置
| 维度 | 亮点 |
|---|---|
| Session 管理 | 全局 SessionManager,支持父子会话嵌套 |
| Agent 编排 | AgentFlow 声明式流程引擎 |
| 工作台 | 20+ 渲染组件,支持 15+ 文件格式 |
| 跨平台 | macOS/Windows/Linux 全平台桌面端 |
| 实时协作 | 消息流优化,断线重连支持 |
| MCP 协议 | 标准化工具集成协议 |
| 稳定性 | 生产就绪,多会话隔离 |
感谢所有为 v1.0.0 做出贡献的开发者、测试人员和用户。
核心贡献:
- SAgents 内核: Session 管理体系重构,AgentFlow 编排引擎
- App 应用层: 可视化工作台系统,跨平台桌面端
- 实时系统: 消息流处理,断线重连机制
- MCP 协议: 标准化工具集成
Full Changelog: https://github.com/ZHangZHengEric/Sage/compare/v0.9.9...v1.0.0