refactor(sdk): move SDKCaptureHook to agent/hook.py

Colocate the capture hook with the rest of the hook infrastructure
instead of inlining it in the top-level facade module.
This commit is contained in:
chengyongru 2026-05-04 23:26:20 +08:00 committed by Xubin Ren
parent ca7877f272
commit d97e177981
2 changed files with 21 additions and 21 deletions

View File

@ -102,3 +102,22 @@ class CompositeHook(AgentHook):
for h in self._hooks: for h in self._hooks:
content = h.finalize_content(context, content) content = h.finalize_content(context, content)
return content return content
class SDKCaptureHook(AgentHook):
"""Record tool names and the final message list for ``RunResult``.
The runner mutates ``context.messages`` in place across iterations, so the
snapshot is refreshed on every ``after_iteration`` call; the last call
reflects the end-of-turn state the SDK caller cares about.
"""
def __init__(self) -> None:
super().__init__()
self.tools_used: list[str] = []
self.messages: list[dict[str, Any]] = []
async def after_iteration(self, context: AgentHookContext) -> None:
for call in context.tool_calls:
self.tools_used.append(call.name)
self.messages = list(context.messages)

View File

@ -6,7 +6,7 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from nanobot.agent.hook import AgentHook, AgentHookContext from nanobot.agent.hook import AgentHook, SDKCaptureHook
from nanobot.agent.loop import AgentLoop from nanobot.agent.loop import AgentLoop
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
@ -104,7 +104,7 @@ class Nanobot:
Different keys get independent history. Different keys get independent history.
hooks: Optional lifecycle hooks for this run. hooks: Optional lifecycle hooks for this run.
""" """
capture = _SDKCaptureHook() capture = SDKCaptureHook()
prev = self._loop._extra_hooks prev = self._loop._extra_hooks
base_hooks = list(hooks) if hooks is not None else list(prev or []) base_hooks = list(hooks) if hooks is not None else list(prev or [])
self._loop._extra_hooks = [capture, *base_hooks] self._loop._extra_hooks = [capture, *base_hooks]
@ -123,25 +123,6 @@ class Nanobot:
) )
class _SDKCaptureHook(AgentHook):
"""Record tool names and the final message list for ``RunResult``.
The runner mutates ``context.messages`` in place across iterations, so the
snapshot is refreshed on every ``after_iteration`` call; the last call
reflects the end-of-turn state the SDK caller cares about.
"""
def __init__(self) -> None:
super().__init__()
self.tools_used: list[str] = []
self.messages: list[dict[str, Any]] = []
async def after_iteration(self, context: AgentHookContext) -> None:
for call in context.tool_calls:
self.tools_used.append(call.name)
self.messages = list(context.messages)
def _make_provider(config: Any) -> Any: def _make_provider(config: Any) -> Any:
"""Create the LLM provider from config (extracted from CLI).""" """Create the LLM provider from config (extracted from CLI)."""
from nanobot.providers.factory import make_provider from nanobot.providers.factory import make_provider