[真实流程计时]:完成完整链路耗时输出,包含命令时间、LLM发送时间和阶段响应耗时

This commit is contained in:
mkbk
2026-06-18 00:45:10 +08:00
parent b9b501cf74
commit 39da9dd09f
7 changed files with 351 additions and 61 deletions
@@ -266,6 +266,23 @@ Playback drain semantics are intentionally split by transport type:
`_drain_input_after_playback()` therefore always calls `flush_input()` once after actual playback. If `OWNER_POST_PLAYBACK_DRAIN_MS=0`, it returns immediately and does not perform any timed read/drop loop. If the value is positive, the positive window is treated as an explicit user tuning and the runtime reads and discards only that configured duration before a final flush. When `OWNER_WAKE_ACK_TEXT` is empty and no ACK playback occurs, the runtime skips playback drain entirely.
## Real Provider Timing Observability
`owner_voice_pet real-live-check` is also the repeatable latency diagnostic entry for the full chain. The command records timing at three levels:
1. Command lifecycle: `started_at`, `finished_at`, epoch millisecond timestamps, and total `duration_ms`.
2. Preparation phases: `prepare_config`, `generate_fixture_audio`, `build_pipeline`, and `pipeline_run`, each with start offset and duration.
3. Pipeline events: every emitted stage event is recorded with turn id, ISO timestamp, command-relative offset, and message. Derived `stage_timings` pair stable stage boundaries such as `wake_listening -> wake_detected`, `capture_started -> speech_started`, `speech_started -> speech_ended`, `stt_started -> transcript_final`, `llm_started -> tts_started`, `tts_started -> playback_finished`, and `wake_listening -> standby_resumed`.
The real LLM provider is wrapped by `RecordingLlmProvider`. For every cloud LLM call it records:
1. `sent_at` and `sent_offset_ms`, captured immediately before delegating to the OpenAI-compatible provider.
2. `first_delta_at` and `first_delta_ms`, captured when the first non-empty text delta is yielded.
3. `finished_at` and `duration_ms`, captured when the stream ends or unwinds through an error.
4. `message_count` and `last_user_preview`, enough to correlate the request with a turn without serializing credentials or full request payloads.
Timing output is diagnostic metadata only. It SHALL NOT include `OWNER_LLM_API_KEY`, raw audio, denoised audio, full provider request headers, or any other secret-bearing configuration.
## Migration
No database migration. Users should run: