feat(outlook): 添加Outlook集成功能支持

添加完整的Outlook MCP集成,包括邮件和日历功能,通过AuthZ模式进行认证和权限管理,
支持邮箱连接、断开、状态检查和数据同步等功能。

fix(config): 统一配置文件路径从.nanobot到.beaver

将配置文件路径从/root/.nanobot统一更改为/root/.beaver,更新Dockerfile中的环境变量定义,
确保所有组件使用一致的配置目录结构。

feat(agent): 添加代理删除功能和助手身份提示

为代理注册表添加delete_agent方法,实现代理的动态删除功能;同时添加海狸助手身份提示,
确保AI助手在交互中保持一致的身份认知。

feat(engine): 增强引擎循环并添加意图决策快照

扩展AgentLoop类,添加intent_agent_decision参数用于意图驱动的代理决策,并在会话中记录
决策快照,便于后续分析和调试。

feat(authz): 扩展认证客户端功能

为AuthzClient添加设置权限、用户注册、后端注册和Outlook设置管理等新方法,增强系统
的认证和授权能力。
This commit is contained in:
2026-05-14 16:01:46 +08:00
parent 30ab74ffb2
commit ebfa242862
35 changed files with 3979 additions and 462 deletions

View File

@ -217,6 +217,7 @@ class AgentLoop:
pinned_skill_names: list[str] | None = None,
pinned_skill_contexts: list[SkillContext] | None = None,
allow_candidate_generation: bool = False,
intent_agent_decision: dict[str, Any] | None = None,
) -> AgentRunResult:
"""跑通最小 direct run 主链。
@ -265,6 +266,7 @@ class AgentLoop:
pinned_skill_names=pinned_skill_names,
pinned_skill_contexts=pinned_skill_contexts,
allow_candidate_generation=allow_candidate_generation,
intent_agent_decision=intent_agent_decision,
)
async def _process_direct_impl(
@ -301,6 +303,7 @@ class AgentLoop:
pinned_skill_names: list[str] | None = None,
pinned_skill_contexts: list[SkillContext] | None = None,
allow_candidate_generation: bool = False,
intent_agent_decision: dict[str, Any] | None = None,
) -> AgentRunResult:
"""真正执行一轮 direct run 的内部实现。
@ -381,6 +384,7 @@ class AgentLoop:
"parent_session_id": parent_session_id,
"pinned_skill_names": list(pinned_skill_names or []),
"pinned_skill_context_names": [skill.name for skill in pinned_skill_contexts or []],
"intent_agent_decision": intent_agent_decision,
},
content=task,
context_visible=False,
@ -389,6 +393,20 @@ class AgentLoop:
model=resolved_model,
user_id=user_id,
)
if intent_agent_decision:
session_manager.append_message(
resolved_session_id,
run_id=resolved_run_id,
role="system",
event_type="intent_agent_decision_snapshotted",
event_payload=dict(intent_agent_decision),
content=str(intent_agent_decision.get("choice") or ""),
context_visible=False,
source=source,
title=title,
model=resolved_model,
user_id=user_id,
)
user_message_recorded = False
iterations = 0