feat: 引入可选的双层架构(Steering Loop + AgentMessage)#1224
Closed
xzq-xu wants to merge 4 commits intoHKUDS:nightlyfrom
Closed
feat: 引入可选的双层架构(Steering Loop + AgentMessage)#1224xzq-xu wants to merge 4 commits intoHKUDS:nightlyfrom
xzq-xu wants to merge 4 commits intoHKUDS:nightlyfrom
Conversation
3ba3a28 to
ed21299
Compare
This was referenced Mar 3, 2026
2a1b08d to
276a59f
Compare
2922f6d to
e59e17f
Compare
2ba9355 to
9e48703
Compare
Closed
53ec63e to
7ba54bc
Compare
7ba54bc to
df77ee4
Compare
50ca97d to
8222022
Compare
8222022 to
80403d3
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Mar 30, 2026
Reimplement PR HKUDS#1224 Level-1 steering (inject user messages before LLM call via _LoopHook.before_iteration) and PR HKUDS#2219 incremental session save (persist after each tool-using iteration via after_iteration hook) on the new AgentRunner/AgentHook architecture. Made-with: Cursor
e9b8c11 to
1a16b43
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Mar 31, 2026
- steering.py: add SteeringHook(AgentHook) with before_iteration drain - loop.py: add extra_hooks param to _run_agent_loop/_process_message/process_direct - _dispatch: create per-session InterruptionChecker + SteeringHook - run(): route interruptions to active session checkers - messages.py: AgentMessage data model for dual-layer architecture - config: add context_budget_tokens setting Made-with: Cursor
341d810 to
99ab041
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Apr 1, 2026
Sync nanobot with upstream/nightly while preserving nobot-specific features: Upstream features merged: - Dream memory system (Consolidator + Dream two-stage architecture) - cached_tokens tracking (Anthropic / OpenAI-compat providers) - iMessage / Discord channel support - /dream, /dream-log slash commands - StreamRenderer improvements (force_terminal, stop_for_input) - /status cache hit rate display Preserved nobot features (by PR): - HKUDS#1224: Steering two-layer architecture (SteeringHook, InterruptionChecker, AgentMessage) - HKUDS#2219: Incremental session saving - HKUDS#2205: Tool definitions cache - HKUDS#2262: Cron tz+at support - HKUDS#2667: Feishu _resuming fix - HKUDS#1838: Cron run history tracking Preserved DeskClaw platform adaptation: - _is_win_gui_command (Windows shell support) Made-with: Cursor
ec3b3af to
5af0c60
Compare
88792b0 to
fdc1dd5
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Apr 7, 2026
Major upstream features: - Jinja2 template system for agent prompts - OpenAI Responses API support - Built-in grep/glob search tools - Microsoft Teams channel - Runtime hardening (checkpoints, retry, empty response handling) - GPT-5, GitHub Copilot, Xiaomi MiMo, Qianfan providers - GitStore moved to utils/gitstore.py - Retry-after mechanism, SSRF whitelist - Tool class refactor (@tool_parameters decorator) - Various channel improvements (telegram, weixin, whatsapp, discord) - New dependencies: jinja2, msteams (PyJWT, cryptography) Nobot features preserved via rebased upstream PRs: - PR HKUDS#1224: Steering dual-layer architecture - PR HKUDS#2205: Tool definitions cache - PR HKUDS#2243: Fast preflight trim (replaces on_iteration_complete) - PR HKUDS#2706: Feishu streaming tool hints + _resuming Additional nobot features manually preserved: - Cron tz+at timezone support - Cron job history API - Windows GUI command exit code normalization - Version suffix +nobot Made-with: Cursor
6190ec0 to
0d6f3ba
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Apr 8, 2026
Upstream changes (80+ commits): - feat: tool hints extracted to utils/tool_hints.py with path abbreviation - feat: shell sandbox (bwrap), bash -l -c, minimal env, _kill_process - feat: feishu bot open_id, _resolve_mentions, done_emoji (HKUDS#2899) - feat: dream enhancement with date/char context (HKUDS#2887) - feat: cron job name parameter (HKUDS#2680) - feat: ${VAR} env interpolation in config secrets - feat: voice transcription unification (OpenAI/Groq Whisper) - fix: runner empty-response retry (_MAX_EMPTY_RETRIES=2) - fix: shell CancelledError subprocess cleanup - security: bind api port to localhost, prevent env leak - refactor: hook CompositeHook._for_each_hook_safe DRY - Various channel fixes (matrix, telegram, whatsapp, email) Preserved nobot features (5 upstream PRs): - PR HKUDS#1224: Steering Loop (InterruptionChecker, SteeringHook, extra_hooks) - PR HKUDS#2205: ToolRegistry definitions cache (_definitions_cache) - PR HKUDS#2219: Incremental session save (on_turn_saved) — re-applied - PR HKUDS#2243: Fast preflight trim (fast_trim_if_needed, archive_trimmed_chunk) - PR HKUDS#2706: Feishu streaming resuming + inline tool hints (_resuming, tool_hint_len) Other nobot features preserved: - _is_win_gui_command (shell.py) - context_budget_tokens (schema.py) - cron tz+at timezone fix Gateway: no changes needed (registry_patch.py interfaces unchanged). Made-with: Cursor
8130cd9 to
6eed049
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Apr 10, 2026
Upstream changes: - feat(channels): add WebSocket server channel - feat(session): add unified_session config - feat(exec): support allowed_env_keys - fix(agent): deliver LLM errors to streaming channels - fix(providers): enforce role alternation for non-Claude - feat(channel): add proxy support for Discord - Remove msteams channel Merge resolution: - Keep local HKUDS#1224 (steering/extra_hooks) and HKUDS#2219 (incremental save) - Integrate upstream unified_session alongside local steering logic - Update _run_agent_loop to return 4-tuple (add stop_reason) Made-with: Cursor
…age) Adapted for the new AgentHook/runner architecture in nightly. - Steering Loop: when enable_steering is true, interruptions arriving during tool execution are injected via after_iteration hook instead of inline loop logic. - AgentMessage model: rich message wrapper with application-layer metadata (artifacts, tags) and optional context transform hooks. - InterruptionChecker: thread-safe signaling between dispatch and running agent tasks. Both layers are fully opt-in. Default behavior is identical to the original loop with zero overhead. Made-with: Cursor
- Module docstrings → one-liners matching project style - Remove unused InterruptionChecker.check() method - Remove section comments in messages.py Made-with: Cursor
…n only Remove before_tool_call hook and _execute_tools_with_hook since the upstream runner uses asyncio.gather for concurrent tool execution, making sequential per-tool interruption checks impractical. Steering now only injects user messages before each LLM call via before_iteration, which is sufficient for dynamic direction changes. Made-with: Cursor
Move interruption injection logic from _LoopHook into a standalone SteeringHook(AgentHook) that plugs into the hooks system. Steering is now always active — InterruptionChecker is created per-dispatch and SteeringHook is passed as an extra hook. When no interruptions arrive, drain_all() returns empty and the hook is a no-op. Removes enable_steering from AgentDefaults config, CLI wiring, and AgentLoop.__init__. Removes transform_context/convert_to_llm params that were unused after the per-tool cancellation drop. Made-with: Cursor
6eed049 to
455734c
Compare
xzq-xu
added a commit
to xzq-xu/nanobot
that referenced
this pull request
Apr 13, 2026
- steering.py: InterruptionChecker + SteeringHook for mid-conversation user interruptions (per-tool checking with CANCELLED fill) - messages.py: AgentMessage structured model for dual-layer architecture - loop.py: _process_message and _run_agent_loop accept per-call extra_hooks (merged with instance-level hooks via CompositeHook) DeskClaw gateway passes SteeringHook as extra_hooks for WebSocket sessions. Ref: upstream PR HKUDS#1224 Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
实现 #1181 提出的可选双层架构,为 Agent Runtime 增加两项核心能力。所有新功能均为 opt-in,默认配置下行为与现有 main 分支完全一致。
A. Steering Loop(动态任务中断)
开启
enable_steering: true后,用户在 Agent 执行工具链期间发送的新消息会合并到当前对话,而非排队等待。中断检查点(两处):
CANCELLED: User interrupted结果以维持 OpenAI 消息格式),然后注入新消息中断 vs 新任务的区分:
bus.publish_inbound()重新排队为新任务(独立处理)实现细节:
InterruptionChecker(异步队列),跨会话零干扰_dispatch()的finally块负责 checker 生命周期管理和孤儿消息回收B. AgentMessage 模型(结构化上下文钩子)
AgentMessage数据类在标准 LLM dict 之上封装应用层元数据:msg_type、tags、artifact、metadataAgentLoop新增两个可选钩子:transform_context:LLM 调用前的语义裁剪(如"保留最近 3 个 artifact")convert_to_llm:自定义 AgentMessage → LLM dict 转换list[dict],零开销变更文件
nanobot/agent/messages.pyAgentMessage、ArtifactInfo、MessageType数据模型及查询方法nanobot/agent/steering.pyInterruptionChecker异步信号/排空队列nanobot/agent/loop.pyrun()中的中断路由、_dispatch()中的 checker 生命周期管理与孤儿消息回收、_run_agent_loop()中的逐工具中断检查与上下文钩子;已适配上游chat_with_retry重试机制nanobot/config/schema.pyAgentDefaults新增enable_steering: bool = Falsenanobot/cli/commands.pyAgentLoop实例化传入enable_steering向后兼容性
所有新代码路径均由
if self.enable_steering或if self._transform_context守卫。默认配置下:provider.chat_with_retry()接收的 messages 与现有主分支完全一致测试验证
enable_steering=false:gateway 正常启动,消息顺序处理,无回归enable_steering=true:发送多工具任务,执行期间发送中断消息——中断在工具执行前被捕获,剩余工具以 CANCELLED 结果填充,LLM 动态响应合并后的上下文与 PR #1233 的关系
本 PR 借鉴了 #1233 的逐工具中断检查和 CANCELLED 填充策略,同时保留了以下差异设计:
InterruptionChecker),而非 bus 层,保持关注点分离<SYS_EVENT>system message,让 LLM 获得更多决策信息待后续完善
本 PR 完成了双层架构的核心框架和接口层,以下能力已预留数据模型和方法,但尚未端到端打通:
ArtifactInfo模型已定义,但工具执行结果未自动标记为 artifactget_latest_artifacts(n)、filter_by_type()等查询方法已就绪,但未提供开箱即用的transform_context实现InterruptionChecker实现Closes #1181