对应源码: conversation.rs:34-36 → trait ApiClient { fn stream(...) } conversation.rs:38-39 → trait ToolExecutor { fn execute(...) } permissions.rs:39-41 → trait PermissionPrompter { fn decide(...) } 这三个 trait (Rust 的叫法) 就是 Python 的 ABC (Abstract Base Class)。 它们定义了 "你必
()
| 35 | # ============================================================ |
| 36 | |
| 37 | def lesson_1_interface(): |
| 38 | """ |
| 39 | 对应源码: |
| 40 | conversation.rs:34-36 → trait ApiClient { fn stream(...) } |
| 41 | conversation.rs:38-39 → trait ToolExecutor { fn execute(...) } |
| 42 | permissions.rs:39-41 → trait PermissionPrompter { fn decide(...) } |
| 43 | |
| 44 | 这三个 trait (Rust 的叫法) 就是 Python 的 ABC (Abstract Base Class)。 |
| 45 | 它们定义了 "你必须实现这些方法", 但不关心你怎么实现。 |
| 46 | |
| 47 | 为什么? 因为 ConversationRuntime 不应该知道: |
| 48 | - API 调用是走 HTTP 还是假数据 (测试时) |
| 49 | - 工具是执行 Bash 还是读文件 |
| 50 | - 权限提示是 CLI 弹窗还是 IDE 对话框 |
| 51 | |
| 52 | 日常类比: USB 接口 |
| 53 | ───────────── |
| 54 | USB 口不管你插的是鼠标、键盘还是 U盘——只要你有 USB 插头就行。 |
| 55 | "USB 接口" = trait/ABC, "鼠标" = 一个具体实现。 |
| 56 | """ |
| 57 | print("=" * 60) |
| 58 | print("第一课: 接口 (ABC) — 签合同, 不管你怎么干活") |
| 59 | print("=" * 60) |
| 60 | |
| 61 | # ---- 步骤 1: 定义接口 (对应 Rust 的 trait) ---- |
| 62 | |
| 63 | # 对应 conversation.rs:34-36 |
| 64 | # pub trait ApiClient { |
| 65 | # fn stream(&mut self, request: ApiRequest) -> Result<Vec<AssistantEvent>, RuntimeError>; |
| 66 | # } |
| 67 | class ApiClient(ABC): |
| 68 | """API 客户端接口: 你必须能发送请求并返回事件流""" |
| 69 | @abstractmethod |
| 70 | def stream(self, messages: list[dict]) -> list[dict]: |
| 71 | """发送消息, 返回 assistant 事件列表""" |
| 72 | ... |
| 73 | |
| 74 | # 对应 conversation.rs:38-39 |
| 75 | # pub trait ToolExecutor { |
| 76 | # fn execute(&mut self, tool_name: &str, input: &str) -> Result<String, ToolError>; |
| 77 | # } |
| 78 | class ToolExecutor(ABC): |
| 79 | """工具执行器接口: 你必须能按名字执行工具""" |
| 80 | @abstractmethod |
| 81 | def execute(self, tool_name: str, tool_input: str) -> str: |
| 82 | ... |
| 83 | |
| 84 | # 对应 permissions.rs:39-41 |
| 85 | # pub trait PermissionPrompter { |
| 86 | # fn decide(&mut self, request: &PermissionRequest) -> PermissionPromptDecision; |
| 87 | # } |
| 88 | class PermissionPrompter(ABC): |
| 89 | """权限提示器接口: 你必须能做出允许/拒绝决定""" |
| 90 | @abstractmethod |
| 91 | def decide(self, tool_name: str, tool_input: str) -> bool: |
| 92 | ... |
| 93 | |
| 94 | # ---- 步骤 2: 多种实现 ---- |
no test coverage detected