| 279 | |
| 280 | |
| 281 | class ConversationRuntime: |
| 282 | def __init__( |
| 283 | self, |
| 284 | session: Session, |
| 285 | api_client, # ApiClient Protocol |
| 286 | tool_executor: ToolExecutor, |
| 287 | permission_policy: PermissionPolicy, |
| 288 | system_prompt: list[str], |
| 289 | hook_runner: Optional[HookRunner] = None, |
| 290 | ): |
| 291 | """源码: conversation.rs:117-133""" |
| 292 | self._session = session |
| 293 | self._api_client = api_client |
| 294 | self._tool_executor = tool_executor |
| 295 | self._permission_policy = permission_policy |
| 296 | self._system_prompt = system_prompt |
| 297 | self._hook_runner = hook_runner or HookRunner() |
| 298 | self._max_iterations = DEFAULT_MAX_ITERATIONS |
| 299 | self._usage_tracker = UsageTracker() |
| 300 | self._auto_compact_threshold = DEFAULT_AUTO_COMPACT_THRESHOLD |
| 301 | |
| 302 | # -------------------------------------------------------- |
| 303 | # Builder 方法 — 链式配置 |
| 304 | # 源码: conversation.rs:158-168 |
| 305 | # -------------------------------------------------------- |
| 306 | |
| 307 | def with_max_iterations(self, n: int) -> "ConversationRuntime": |
| 308 | """源码: conversation.rs:158-162""" |
| 309 | self._max_iterations = n |
| 310 | return self |
| 311 | |
| 312 | def with_auto_compact_threshold(self, threshold: int) -> "ConversationRuntime": |
| 313 | """源码: conversation.rs:164-168""" |
| 314 | self._auto_compact_threshold = threshold |
| 315 | return self |
| 316 | |
| 317 | # -------------------------------------------------------- |
| 318 | # run_turn — 核心 agentic loop |
| 319 | # 源码: conversation.rs:170-283 |
| 320 | # |
| 321 | # 这就是那个著名的循环: |
| 322 | # 用户输入 → [API → 提取 tool_use → 权限 → hook → 执行 → loop] → 返回 |
| 323 | # |
| 324 | # 注意: 一个 turn 可能包含多轮 API 调用 (当 LLM 需要多次工具调用时)。 |
| 325 | # iterations 计数的是 API 调用次数,不是用户交互次数。 |
| 326 | # -------------------------------------------------------- |
| 327 | |
| 328 | def run_turn( |
| 329 | self, |
| 330 | user_input: str, |
| 331 | prompter: Optional[PermissionPrompter] = None, |
| 332 | ) -> TurnSummary: |
| 333 | """源码: conversation.rs:170-283""" |
| 334 | # 推入用户消息 — conversation.rs:175-176 |
| 335 | self._session.messages.append(Message.user_text(user_input)) |
| 336 | |
| 337 | assistant_messages: list[Message] = [] |
| 338 | tool_results: list[Message] = [] |