从流事件构建 AI 回复。如果流中断(没收到 message_stop),标记为未完成。 对应源码: conversation.rs:353-390 fn build_assistant_message(events) { ... if !finished { return Err("assistant stream ended without a message stop event"); } if blocks.is_empty
(events: list[dict])
| 363 | |
| 364 | |
| 365 | def build_assistant_message(events: list[dict]) -> AssistantMessage: |
| 366 | """ |
| 367 | 从流事件构建 AI 回复。如果流中断(没收到 message_stop),标记为未完成。 |
| 368 | |
| 369 | 对应源码: conversation.rs:353-390 |
| 370 | fn build_assistant_message(events) { |
| 371 | ... |
| 372 | if !finished { |
| 373 | return Err("assistant stream ended without a message stop event"); |
| 374 | } |
| 375 | if blocks.is_empty() { |
| 376 | return Err("assistant stream produced no content"); |
| 377 | } |
| 378 | } |
| 379 | """ |
| 380 | text = "" |
| 381 | text_blocks = [] |
| 382 | tool_calls = [] |
| 383 | finished = False |
| 384 | |
| 385 | for event in events: |
| 386 | if event["type"] == "text_delta": |
| 387 | text += event["text"] |
| 388 | elif event["type"] == "tool_use": |
| 389 | if text: |
| 390 | text_blocks.append(text) |
| 391 | text = "" |
| 392 | tool_calls.append({ |
| 393 | "id": event["id"], |
| 394 | "name": event["name"], |
| 395 | "input": event["input"], |
| 396 | }) |
| 397 | elif event["type"] == "message_stop": |
| 398 | finished = True |
| 399 | |
| 400 | if text: |
| 401 | text_blocks.append(text) |
| 402 | |
| 403 | return AssistantMessage( |
| 404 | text_blocks=text_blocks, |
| 405 | tool_calls=tool_calls, |
| 406 | finished=finished, |
| 407 | ) |
| 408 | |
| 409 | |
| 410 | def run_turn_with_recovery(api_fn, tool_executor, max_iterations=10): |
no test coverage detected