ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"experiment": "phone-agent-webrtc",
|
||||
"executed_at_utc": "2026-07-31T11:24:42.453962+00:00",
|
||||
"control": "fixed parameters -> browser microphone RTP -> ASR -> real LLM dialogue -> TTS RTP",
|
||||
"treatment": "natural task -> real LLM ReAct plan -> browser microphone RTP -> ASR -> real LLM dialogue -> TTS RTP",
|
||||
"checks": {
|
||||
"same_browser_aiortc_webrtc_transport": true,
|
||||
"no_pstn_or_e164": true,
|
||||
"direct_required_fixed_parameters": true,
|
||||
"react_accepted_only_natural_language_task": true,
|
||||
"react_detected_missing_information": true,
|
||||
"react_has_observe_reason_act_trace": true,
|
||||
"react_used_real_external_planner": true,
|
||||
"both_used_microphone_rtp_asr": true,
|
||||
"both_used_real_downlink_tts": true,
|
||||
"both_used_external_post_asr_dialogue": true,
|
||||
"data_channel_never_supplied_user_semantics": true,
|
||||
"both_completed_all_audio_gates": true,
|
||||
"both_saved_confirmed_structured_fields": true
|
||||
},
|
||||
"passed": true,
|
||||
"conclusion": "Both arms completed the same real bidirectional browser/aiortc audio path. The treatment additionally used an external ARK ReAct planning receipt to detect missing facts; the control used fixed parameters."
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
{
|
||||
"schema_version": 3,
|
||||
"experiment": "phone-agent-webrtc",
|
||||
"call_id": "rtc_794c4b8e0481466fbf23",
|
||||
"created_at_utc": "2026-07-31T11:23:09.666702+00:00",
|
||||
"finished_at_utc": "2026-07-31T11:23:53.431450+00:00",
|
||||
"status": "completed",
|
||||
"mode": "direct",
|
||||
"input_contract": {
|
||||
"fields_supplied_by_caller": [
|
||||
"callee_name",
|
||||
"goal",
|
||||
"context",
|
||||
"instructions"
|
||||
],
|
||||
"natural_language_task": ""
|
||||
},
|
||||
"plan": {
|
||||
"mode": "direct",
|
||||
"callee_name": "Jane Doe",
|
||||
"goal": "Collect and confirm Jane Doe's preferred dental-checkup time and confirmation code.",
|
||||
"context": "Tuesday afternoon from 2pm to 4pm is available; the user must supply the exact time and code by voice.",
|
||||
"instructions": "Ask for one exact time and a confirmation code. Repeat both, require explicit confirmation, then call complete_task with only the ASR-confirmed details.",
|
||||
"opening_line": "Hello Jane Doe. Please state the exact appointment time and confirmation code, then explicitly confirm both.",
|
||||
"missing_information": [],
|
||||
"trace": [
|
||||
{
|
||||
"stage": "observation",
|
||||
"summary": "Caller supplied all call parameters."
|
||||
},
|
||||
{
|
||||
"stage": "action",
|
||||
"summary": "Open a WebRTC voice session with the fixed parameters."
|
||||
}
|
||||
],
|
||||
"planner_model": null
|
||||
},
|
||||
"models": {
|
||||
"planner": null,
|
||||
"dialogue_models": [
|
||||
"ark:doubao-seed-1-6-flash-250615"
|
||||
],
|
||||
"llm_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"purpose": "post_asr_dialogue",
|
||||
"execution": "real_external_llm",
|
||||
"provider": "ark",
|
||||
"requested_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_response_id": "0217854970227438de59cc126156ef9419088f6fa2f8da927049f",
|
||||
"finish_reason": "stop",
|
||||
"usage": {
|
||||
"completion_tokens": 181,
|
||||
"prompt_tokens": 392,
|
||||
"total_tokens": 573,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 84
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
},
|
||||
"started_at_utc": "2026-07-31T11:23:42.156339+00:00",
|
||||
"finished_at_utc": "2026-07-31T11:23:44.170815+00:00",
|
||||
"latency_seconds": 2.014451,
|
||||
"request": {
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are the voice Agent in a short local browser call. The user text below came only from ASR over the browser microphone RTP track. Return only JSON with assistant_message, explicit_confirmation_observed (boolean), should_complete (boolean), and completion containing result, appointment_time, confirmation_number, notes. If the user states an exact time, a confirmation code, and explicitly confirms both, set should_complete=true, normalize obvious spoken code words/digits into a concise code, and repeat both details in assistant_message. Otherwise ask only for what is missing. Never say booked, arranged, scheduled, or imply an external action occurred. For a completed turn, completion.result must be exactly 'Local confirmation recorded.' and completion.notes must be exactly 'No external organization was contacted or booking made.' Goal: Collect and confirm Jane Doe's preferred dental-checkup time and confirmation code.\nContext: Tuesday afternoon from 2pm to 4pm is available; the user must supply the exact time and code by voice.\nInstructions: Ask for one exact time and a confirmation code. Repeat both, require explicit confirmation, then call complete_task with only the ASR-confirmed details."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "{\"latest_user_asr_transcript\":\"Confirmation called as Maple 7. I explicitly confirm Tuesday at 3pm and confirmation code Maple 7.\",\"prior_audio_transcript\":[{\"purpose\":\"missing_field_clarification\",\"source\":\"tts.webrtc_downlink\",\"speaker\":\"agent\",\"text\":\"Hello Jane Doe. Please state the exact appointment time and confirmation code, then explicitly confirm both.\",\"utterance_id\":\"tts_01\"}]}"
|
||||
}
|
||||
],
|
||||
"response_format": {
|
||||
"type": "json_object"
|
||||
},
|
||||
"temperature": 0,
|
||||
"max_tokens": 700
|
||||
},
|
||||
"request_sha256": "625905fa5da9a4cdc0bd711793201abc585ea5434e62f2a03024a128a3cd40d5",
|
||||
"raw_response": {
|
||||
"id": "0217854970227438de59cc126156ef9419088f6fa2f8da927049f",
|
||||
"choices": [
|
||||
{
|
||||
"finish_reason": "stop",
|
||||
"index": 0,
|
||||
"message": {
|
||||
"content": "{\"assistant_message\": \"Confirmed appointment time: Tuesday at 3pm, Confirmation code: Maple 7. Explicit confirmation observed: true\", \"explicit_confirmation_observed\": true, \"should_complete\": true, \"completion\": {\"result\": \"Local confirmation recorded.\", \"appointment_time\": \"Tuesday at 3pm\", \"confirmation_number\": \"Maple 7\", \"notes\": \"No external organization was contacted or booking made.\"}}",
|
||||
"role": "assistant",
|
||||
"reasoning_content": "Got it, let's see. The user provided the exact time as Tuesday at 3pm and the confirmation code as Maple 7, and explicitly confirmed both. So I need to construct the JSON with assistant_message repeating the details, explicit_confirmation_observed as true, should_complete as true, and completion with result \"Local confirmation recorded.\" and notes \"No external organization was contacted or booking made.\""
|
||||
}
|
||||
}
|
||||
],
|
||||
"created": 1785497024,
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"object": "chat.completion",
|
||||
"service_tier": "default",
|
||||
"usage": {
|
||||
"completion_tokens": 181,
|
||||
"prompt_tokens": 392,
|
||||
"total_tokens": 573,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 84
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"raw_response_sha256": "d2fb0d5702e0cf7905675047a5bc9ed7330a9d1ac02f6f219f8442ad29794fe8",
|
||||
"response_content": "{\"assistant_message\": \"Confirmed appointment time: Tuesday at 3pm, Confirmation code: Maple 7. Explicit confirmation observed: true\", \"explicit_confirmation_observed\": true, \"should_complete\": true, \"completion\": {\"result\": \"Local confirmation recorded.\", \"appointment_time\": \"Tuesday at 3pm\", \"confirmation_number\": \"Maple 7\", \"notes\": \"No external organization was contacted or booking made.\"}}",
|
||||
"response_content_sha256": "5cec9a348fdd2a028db79b95024befc152676fd85169a254ca2007888b571897",
|
||||
"external_request_completed": true,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"credential_fields_retained": false
|
||||
}
|
||||
],
|
||||
"asr_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "asr",
|
||||
"execution": "real_local_inference",
|
||||
"provider": "local OpenAI Whisper",
|
||||
"model": "whisper-tiny",
|
||||
"checkpoint_name": "tiny.pt",
|
||||
"checkpoint_sha256": "65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9",
|
||||
"runtime": {
|
||||
"python": "3.11.4",
|
||||
"torch": "2.4.0",
|
||||
"openai_whisper": "20231106"
|
||||
},
|
||||
"input_source": "browser_microphone_rtp",
|
||||
"input_sample_rate_hz": 16000,
|
||||
"input_channels": 1,
|
||||
"input_pcm_bytes": 774368,
|
||||
"input_wav_bytes": 774412,
|
||||
"input_wav_sha256": "bc5072b92d30d382b7439f56b1453946cbaa5f9de80c7a24eb98a1f8615c1d34",
|
||||
"input_duration_seconds": 24.199,
|
||||
"language": "en",
|
||||
"transcript": "Confirmation called as Maple 7. I explicitly confirm Tuesday at 3pm and confirmation code Maple 7.",
|
||||
"transcript_sha256": "e34b0bd2ddd7f005484a59cc83d36b5c4147762c45e1ffb7f1fd2c9f0e8e428e",
|
||||
"model_load_seconds": 0.314312,
|
||||
"inference_seconds": 0.446881,
|
||||
"latency_seconds": 1.789071,
|
||||
"retained_safe_fixture_path": "media/direct/microphone_rtp_asr_input.wav",
|
||||
"external_request": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false
|
||||
}
|
||||
],
|
||||
"tts_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 8000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 52080,
|
||||
"duration_seconds": 6.51,
|
||||
"wav_bytes": 104238,
|
||||
"wav_sha256": "c94a2a0b563c9ac55fe472c79b0f94adcb72bdaccd7ecc424f172c35b5af8378",
|
||||
"pcm_sha256": "de63bfbfc726731f84522f16a33357e13dbb34ab6c21596055503d17d039db40",
|
||||
"latency_seconds": 0.972527,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"utterance_id": "tts_01",
|
||||
"purpose": "missing_field_clarification",
|
||||
"retained_safe_fixture_path": "media/direct/agent_01.wav",
|
||||
"text_sha256": "b89b930d8884dec9a8261e6c4952e430f7146bbdcde40423fe8eecede205bec4",
|
||||
"enqueued_on_webrtc_track": true,
|
||||
"transmitted_samples": 52080,
|
||||
"delivery_complete": true,
|
||||
"delivered_pcm_sha256": "de63bfbfc726731f84522f16a33357e13dbb34ab6c21596055503d17d039db40"
|
||||
},
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 8000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 66036,
|
||||
"duration_seconds": 8.2545,
|
||||
"wav_bytes": 132150,
|
||||
"wav_sha256": "8dbef003ff03b50e7c29dce5aad788b74500d6b2882c39388a7712cc5c52081d",
|
||||
"pcm_sha256": "a6acdc60071259f46379dc98d4eaec583dbcb0f0b3c5ed60587e8f743a22a5dc",
|
||||
"latency_seconds": 0.97609,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"utterance_id": "tts_02",
|
||||
"purpose": "confirmed_completion",
|
||||
"retained_safe_fixture_path": "media/direct/agent_02.wav",
|
||||
"text_sha256": "7021250895bc4dbad83d3cc06ebe120bcc15175baa9fa6cf5d760fd3b1682254",
|
||||
"enqueued_on_webrtc_track": true,
|
||||
"transmitted_samples": 66036,
|
||||
"delivery_complete": true,
|
||||
"delivered_pcm_sha256": "a6acdc60071259f46379dc98d4eaec583dbcb0f0b3c5ed60587e8f743a22a5dc"
|
||||
}
|
||||
]
|
||||
},
|
||||
"transport": {
|
||||
"kind": "webrtc",
|
||||
"pstn_used": false,
|
||||
"e164_required": false,
|
||||
"sdp_negotiated": true,
|
||||
"offer_sha256": "1bc7eaf0f30f4e506782cfcf80ff1108b6a0a7500e1ee6bbfa3c7faf853c5373",
|
||||
"answer_sha256": "7e7b70627489f0bdd3aa17890a32af0c498fc25c861b5d947d448d57265116b7",
|
||||
"ice_connection_state": "connected",
|
||||
"ice_connected_observed": true,
|
||||
"data_channel_open": true,
|
||||
"local_audio_track": true,
|
||||
"remote_audio_track": true,
|
||||
"rtc_stats": {
|
||||
"inbound_packets": 1869,
|
||||
"inbound_bytes": 188849,
|
||||
"outbound_packets": 1869,
|
||||
"outbound_bytes": 76286
|
||||
},
|
||||
"server_received_audio_frames": 1865,
|
||||
"server_received_audio_samples": 1790400,
|
||||
"server_received_audio_pcm_bytes": 1193568,
|
||||
"server_sent_tts_samples": 118116
|
||||
},
|
||||
"privacy": {
|
||||
"safe_synthetic_acceptance": true,
|
||||
"private_audio_retained": false,
|
||||
"private_transcripts_retained": false,
|
||||
"safe_synthetic_media_retained": true
|
||||
},
|
||||
"event_counts": {
|
||||
"client.audio.commit": 1,
|
||||
"rtc.ready": 6,
|
||||
"rtc.stats": 51
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"speaker": "agent",
|
||||
"text": "Hello Jane Doe. Please state the exact appointment time and confirmation code, then explicitly confirm both.",
|
||||
"source": "tts.webrtc_downlink",
|
||||
"utterance_id": "tts_01",
|
||||
"purpose": "missing_field_clarification"
|
||||
},
|
||||
{
|
||||
"speaker": "user",
|
||||
"text": "Confirmation called as Maple 7. I explicitly confirm Tuesday at 3pm and confirmation code Maple 7.",
|
||||
"source": "asr.microphone_rtp",
|
||||
"asr_receipt_index": 0
|
||||
},
|
||||
{
|
||||
"speaker": "agent",
|
||||
"text": "Confirmed appointment time: Tuesday at 3pm, Confirmation code: Maple 7. Explicit confirmation observed: true",
|
||||
"source": "tts.webrtc_downlink",
|
||||
"utterance_id": "tts_02",
|
||||
"purpose": "confirmed_completion"
|
||||
}
|
||||
],
|
||||
"explicit_confirmation_observed": true,
|
||||
"completion": {
|
||||
"result": "Local confirmation recorded.",
|
||||
"appointment_time": "Tuesday at 3pm",
|
||||
"confirmation_number": "Maple 7",
|
||||
"notes": "No external organization was contacted or booking made.",
|
||||
"saved_at_utc": "2026-07-31T11:23:45.149157+00:00",
|
||||
"tool": "complete_task"
|
||||
},
|
||||
"errors": [],
|
||||
"acceptance": {
|
||||
"checks": {
|
||||
"sdp_offer_answer_negotiated": true,
|
||||
"ice_connected": true,
|
||||
"data_channel_open": true,
|
||||
"browser_microphone_track": true,
|
||||
"server_downlink_audio_track": true,
|
||||
"outbound_audio_rtp": true,
|
||||
"inbound_audio_rtp": true,
|
||||
"server_buffered_microphone_rtp": true,
|
||||
"real_asr_consumed_microphone_audio": true,
|
||||
"external_react_planner_or_fixed_direct_control": true,
|
||||
"real_external_post_asr_dialogue": true,
|
||||
"real_tts_assets_synthesized": true,
|
||||
"tts_audio_transmitted_on_downlink": true,
|
||||
"media_is_canonical_transcript_source": true,
|
||||
"data_channel_is_control_and_caption_only": true,
|
||||
"missing_fields_were_clarified_aloud": true,
|
||||
"explicit_confirmation_observed": true,
|
||||
"structured_completion_saved": true,
|
||||
"no_mock_probe_or_fallback": true,
|
||||
"privacy_boundary_preserved": true
|
||||
},
|
||||
"passed": true
|
||||
},
|
||||
"finish_reason": "automated_safe_acceptance"
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"experiment": "phone-agent-webrtc",
|
||||
"run_id": "phone-agent-webrtc-audio-20260731-v1",
|
||||
"generated_at_utc": "2026-07-31T11:24:42.523874+00:00",
|
||||
"result": "passed",
|
||||
"execution": "live_browser_aiortc_asr_external_llm_tts_webrtc",
|
||||
"canonical_safe_synthetic_fixture": true,
|
||||
"pstn_used": false,
|
||||
"e164_required": false,
|
||||
"credentials_saved": false,
|
||||
"private_audio_or_transcripts_saved": false,
|
||||
"safe_fixture_provenance": {
|
||||
"direct": {
|
||||
"kind": "safe_synthetic_browser_microphone_fixture",
|
||||
"contains_private_data": false,
|
||||
"sample_rate_hz": 16000,
|
||||
"duration_seconds": 15.730625,
|
||||
"wav_bytes": 503424,
|
||||
"wav_sha256": "0def429a125a2cc14f0461c9361a138b88d9cc0103040a9f018ef8fea2f2d46a",
|
||||
"leading_silence_seconds": 4.0,
|
||||
"trailing_silence_seconds": 3.0,
|
||||
"synthesis": {
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 16000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 139690,
|
||||
"duration_seconds": 8.730625,
|
||||
"wav_bytes": 279458,
|
||||
"wav_sha256": "795fc97e299ecb3bed310e3bde26f1500bf08b9da32d6a276ecadb9dd29b5103",
|
||||
"pcm_sha256": "74690f7b0ee36186bd8e6cf378c40644219f71c96b8f199185ce5e136bf99d63",
|
||||
"latency_seconds": 0.962707,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false
|
||||
},
|
||||
"artifact_path": "fixtures/direct_microphone.wav",
|
||||
"text_sha256": "b1c6b73a17ff9a5afcee66cfc2944dd4b8e9d3019d362a1907eeeb4ba0a0705d"
|
||||
},
|
||||
"react": {
|
||||
"kind": "safe_synthetic_browser_microphone_fixture",
|
||||
"contains_private_data": false,
|
||||
"sample_rate_hz": 16000,
|
||||
"duration_seconds": 15.440375,
|
||||
"wav_bytes": 494136,
|
||||
"wav_sha256": "df1acb0b3db90e2fed6814cb880dabb028cd73d0a1837efc8493a97071f0e7f9",
|
||||
"leading_silence_seconds": 4.0,
|
||||
"trailing_silence_seconds": 3.0,
|
||||
"synthesis": {
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 16000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 135046,
|
||||
"duration_seconds": 8.440375,
|
||||
"wav_bytes": 270170,
|
||||
"wav_sha256": "c23d3bb0b6f14be7f690ee1a4499b1a84d4edf0b3d3c3cadad5212b0e70a8552",
|
||||
"pcm_sha256": "fa9f85699e9d3016eae17acd751dbefce05e3eddf980a842d4d638fe9a5d0928",
|
||||
"latency_seconds": 0.956989,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false
|
||||
},
|
||||
"artifact_path": "fixtures/react_microphone.wav",
|
||||
"text_sha256": "001812c3c3bf8a0372be1399852e155a940d8c57fc04ccbc9fe7ac30a86cc725"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"platform": "macOS-26.3-arm64-arm-64bit",
|
||||
"python": "3.11.4",
|
||||
"chrome_version": "Google Chrome 150.0.7871.188",
|
||||
"chrome_executable_sha256": "2837ae0a82f64cf541af357ce554cc7d0c62d119da2b6b5f3eb64ce7f3d63d4e",
|
||||
"planner_provider": "ark",
|
||||
"planner_model": "doubao-seed-1-6-flash-250615",
|
||||
"dialogue_model": "doubao-seed-1-6-flash-250615",
|
||||
"media_peer": "aiortc",
|
||||
"packages": {
|
||||
"aiortc": "1.15.0",
|
||||
"av": "17.1.0",
|
||||
"openai": "2.48.0",
|
||||
"playwright": "1.61.0"
|
||||
}
|
||||
},
|
||||
"source_sha256": {
|
||||
"chapter6/phone-agent/agent.py": "fa73bfe9182f39d22243065edc02565da33b5957c6f17a9f886fc65ea42561f3",
|
||||
"chapter6/phone-agent/speech.py": "ca959ce60eabd6b629a6a238ceef1b8c6bd955f6921cfc8a273a5c86bb00e008",
|
||||
"chapter6/phone-agent/webrtc_app.py": "260ab64d9ba61a1dcf00cb4f034bcfd115755c11ce0558dc8b610f239f9ed25b",
|
||||
"chapter6/phone-agent/run_acceptance.py": "c33346520fba6a8d8b6385ff0e3052b3c51be7d1ff2fd4f5fbbbf831a02ba012",
|
||||
"chapter6/phone-agent/verify_acceptance.py": "83b459e48f337e4457237b629e4f308694fa491893cb41826128df6f6bab02a7",
|
||||
"chapter6/phone-agent/demo.py": "45ef0878b524ae39faf85693b4ea302746ff2e9ee80ce9aced104e2dbfa67e18",
|
||||
"chapter6/phone-agent/direct_call.py": "74c96ba2811aa81c9d7fabad9f7177df84a6544300ab26513e3a39f8fccf7f59",
|
||||
"chapter6/phone-agent/env.example": "ae6ec336e02041e10f10df39846b63aff1a8a125610e7a2069e3ea4d1e193182",
|
||||
"chapter6/phone-agent/requirements.txt": "451102c65e1b3084096aa59e10816a7a74be20c32d6f3ceb426a73c1c2c6788d",
|
||||
"chapter6/phone-agent/test_agent.py": "8f77744dc6c38e0617b479aff2941bc1b3dcfa78cfac93ccba47702ae8022ad4",
|
||||
"chapter6/phone-agent/test_speech.py": "03a64e7c1f8182f94364c109bf1a640f1609f8cdae1ba3d0f34ccfd41900512c",
|
||||
"chapter6/phone-agent/test_webrtc_app.py": "cf5c2f9f14a65a8fcbd643657d48c9c1d315229609094e30a7642315a1079227",
|
||||
"chapter6/phone-agent/test_verify_acceptance.py": "b2082309ed3409875dac310147894fea50bba9b3909928e2de21b37ed9390912",
|
||||
"chapter6/phone-agent/static/index.html": "fc6020510e90eed59d517139b4cc291bb6aa72be4c16d05714ca134cf3a821f8",
|
||||
"chapter6/phone-agent/static/app.js": "dc1ba08f21bccafc43a5dcc79e57af2dca2bc350fb0021b7e458ce5654e6d04d",
|
||||
"chapter6/phone-agent/static/style.css": "1586e93230ec1a77a5141e05f72c560e193cebbfe43115e26ba81ebd06f00908",
|
||||
"chapter6/phone-agent/README.md": "ad6e93082358a1694b8dc3d73af82feed8d1948efb3a96fde115ac1b1a8e9358",
|
||||
"chapter6/README.md": "84803cef75fc522d21ee9086ce9d8471b1eec99394513a232d420130cfeb580f",
|
||||
"book/chapter6.md": "8e1859fb1b163c3620dac7da4d7560f5d0dce06613f025aa90140e31955d5d73",
|
||||
"pyproject.toml": "b04778d69977f0843def0c26930ab6c5f32706746733495e95647e83c19c2a1b",
|
||||
"uv.lock": "d25d18bb7c0a5d93c888547f19a420dc50719357a3dba813094a6c233140691c"
|
||||
},
|
||||
"artifact_sha256": {
|
||||
"comparison.json": "5b73934cbc776c01cc3aac5d29dbd7026d454a7d7b9d7654c9834339a4bc5a49",
|
||||
"direct.json": "360c613574692e9d01d60e6aefb3faac34a1cf38dc9a14f1bd3b354055db2912",
|
||||
"fixtures/direct_microphone.wav": "0def429a125a2cc14f0461c9361a138b88d9cc0103040a9f018ef8fea2f2d46a",
|
||||
"fixtures/react_microphone.wav": "df1acb0b3db90e2fed6814cb880dabb028cd73d0a1837efc8493a97071f0e7f9",
|
||||
"media/direct/agent_01.wav": "c94a2a0b563c9ac55fe472c79b0f94adcb72bdaccd7ecc424f172c35b5af8378",
|
||||
"media/direct/agent_02.wav": "8dbef003ff03b50e7c29dce5aad788b74500d6b2882c39388a7712cc5c52081d",
|
||||
"media/direct/microphone_rtp_asr_input.wav": "bc5072b92d30d382b7439f56b1453946cbaa5f9de80c7a24eb98a1f8615c1d34",
|
||||
"media/react/agent_01.wav": "36569fa63273d1ed2e7ff1eec9e3be7fc5e878e935bd58e7ea25bc5a6011b473",
|
||||
"media/react/agent_02.wav": "e8a227f303baa45cdcdaa20700c58f2405adf06725394eafb9364b12079ea936",
|
||||
"media/react/microphone_rtp_asr_input.wav": "d13d43693d8af1b579ff7a5f458f7bf0940fbf0daec9ddebc9f279ed1317d73a",
|
||||
"react.json": "5889cf6582b04ea93b81a46a474fc6fbd4e8e8b4590f100c1bd056be91e3907f",
|
||||
"server.log": "1b6cafe4291015cda74a79e49ef5fcad2c485fc7a4882312b183eefd97bbc85e"
|
||||
},
|
||||
"redaction": {
|
||||
"scanned_file_count": 12,
|
||||
"environment_credential_value_matches": [],
|
||||
"passed": true
|
||||
},
|
||||
"cleanup": {
|
||||
"browser_contexts_closed": true,
|
||||
"server_process_terminated": true,
|
||||
"raw_private_media_created": false
|
||||
},
|
||||
"acceptance": {
|
||||
"direct": {
|
||||
"checks": {
|
||||
"sdp_offer_answer_negotiated": true,
|
||||
"ice_connected": true,
|
||||
"data_channel_open": true,
|
||||
"browser_microphone_track": true,
|
||||
"server_downlink_audio_track": true,
|
||||
"outbound_audio_rtp": true,
|
||||
"inbound_audio_rtp": true,
|
||||
"server_buffered_microphone_rtp": true,
|
||||
"real_asr_consumed_microphone_audio": true,
|
||||
"external_react_planner_or_fixed_direct_control": true,
|
||||
"real_external_post_asr_dialogue": true,
|
||||
"real_tts_assets_synthesized": true,
|
||||
"tts_audio_transmitted_on_downlink": true,
|
||||
"media_is_canonical_transcript_source": true,
|
||||
"data_channel_is_control_and_caption_only": true,
|
||||
"missing_fields_were_clarified_aloud": true,
|
||||
"explicit_confirmation_observed": true,
|
||||
"structured_completion_saved": true,
|
||||
"no_mock_probe_or_fallback": true,
|
||||
"privacy_boundary_preserved": true
|
||||
},
|
||||
"passed": true
|
||||
},
|
||||
"react": {
|
||||
"checks": {
|
||||
"sdp_offer_answer_negotiated": true,
|
||||
"ice_connected": true,
|
||||
"data_channel_open": true,
|
||||
"browser_microphone_track": true,
|
||||
"server_downlink_audio_track": true,
|
||||
"outbound_audio_rtp": true,
|
||||
"inbound_audio_rtp": true,
|
||||
"server_buffered_microphone_rtp": true,
|
||||
"real_asr_consumed_microphone_audio": true,
|
||||
"external_react_planner_or_fixed_direct_control": true,
|
||||
"real_external_post_asr_dialogue": true,
|
||||
"real_tts_assets_synthesized": true,
|
||||
"tts_audio_transmitted_on_downlink": true,
|
||||
"media_is_canonical_transcript_source": true,
|
||||
"data_channel_is_control_and_caption_only": true,
|
||||
"missing_fields_were_clarified_aloud": true,
|
||||
"explicit_confirmation_observed": true,
|
||||
"structured_completion_saved": true,
|
||||
"no_mock_probe_or_fallback": true,
|
||||
"privacy_boundary_preserved": true
|
||||
},
|
||||
"passed": true
|
||||
},
|
||||
"comparison_passed": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
{
|
||||
"schema_version": 3,
|
||||
"experiment": "phone-agent-webrtc",
|
||||
"call_id": "rtc_f8c984610b434ce4abf7",
|
||||
"created_at_utc": "2026-07-31T11:24:00.115961+00:00",
|
||||
"finished_at_utc": "2026-07-31T11:24:40.071438+00:00",
|
||||
"status": "completed",
|
||||
"mode": "react",
|
||||
"input_contract": {
|
||||
"fields_supplied_by_caller": [
|
||||
"task"
|
||||
],
|
||||
"natural_language_task": "Call me to arrange a dental checkup for Jane Doe. I forgot to include the exact time and confirmation code, so identify both as missing, ask me for them by voice, and save only what I explicitly confirm."
|
||||
},
|
||||
"plan": {
|
||||
"mode": "react",
|
||||
"callee_name": "Jane Doe",
|
||||
"goal": "Arrange a dental checkup",
|
||||
"context": "User forgot to include exact appointment time and confirmation code",
|
||||
"instructions": "Repeat the missing appointment time and confirmation code, obtain explicit confirmation from the user, and only complete the task with the confirmed values",
|
||||
"opening_line": "Could you please provide the exact appointment time for Jane Doe's dental checkup and the confirmation code?",
|
||||
"missing_information": [
|
||||
"appointment time",
|
||||
"confirmation code"
|
||||
],
|
||||
"trace": [
|
||||
{
|
||||
"stage": "observation",
|
||||
"summary": "Call me to arrange a dental checkup for Jane Doe. I forgot to include the exact time and confirmation code, so identify both as missing, ask me for them by voice, and save only what I explicitly confirm."
|
||||
},
|
||||
{
|
||||
"stage": "reason",
|
||||
"summary": "Requesting the user to explicitly confirm the dental checkup time and confirmation code as they were previously omitted"
|
||||
},
|
||||
{
|
||||
"stage": "action",
|
||||
"summary": "Open a WebRTC call and collect the missing facts by voice."
|
||||
}
|
||||
],
|
||||
"planner_model": "ark:doubao-seed-1-6-flash-250615"
|
||||
},
|
||||
"models": {
|
||||
"planner": "ark:doubao-seed-1-6-flash-250615",
|
||||
"dialogue_models": [
|
||||
"ark:doubao-seed-1-6-flash-250615"
|
||||
],
|
||||
"llm_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"purpose": "react_planning",
|
||||
"execution": "real_external_llm",
|
||||
"provider": "ark",
|
||||
"requested_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_response_id": "021785497038047251fb4d9d2b64b7e0912e9d9de0a598cecf2cc",
|
||||
"finish_reason": "stop",
|
||||
"usage": {
|
||||
"completion_tokens": 262,
|
||||
"prompt_tokens": 222,
|
||||
"total_tokens": 484,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 113
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
},
|
||||
"started_at_utc": "2026-07-31T11:23:57.805430+00:00",
|
||||
"finished_at_utc": "2026-07-31T11:24:00.114900+00:00",
|
||||
"latency_seconds": 2.309437,
|
||||
"request": {
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "Plan a local browser WebRTC voice call. Observe the user's task, identify every missing task-critical fact, reason briefly about what must be collected, and choose the call action. Never invent facts. Return only JSON with callee_name, goal, context, instructions, opening_line, missing_information (array), and decision_summary. opening_line must ask aloud for the missing appointment time and confirmation code. instructions must require the voice Agent to repeat the facts, obtain explicit confirmation, and complete_task only with confirmed values. This local experiment records a confirmation but performs no external booking."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Call me to arrange a dental checkup for Jane Doe. I forgot to include the exact time and confirmation code, so identify both as missing, ask me for them by voice, and save only what I explicitly confirm."
|
||||
}
|
||||
],
|
||||
"response_format": {
|
||||
"type": "json_object"
|
||||
},
|
||||
"temperature": 0,
|
||||
"max_tokens": 700
|
||||
},
|
||||
"request_sha256": "276ca473bec3303ba5356765d1fd4b5e3c8c9e82e1960e4b9b19ad726b8e8c90",
|
||||
"raw_response": {
|
||||
"id": "021785497038047251fb4d9d2b64b7e0912e9d9de0a598cecf2cc",
|
||||
"choices": [
|
||||
{
|
||||
"finish_reason": "stop",
|
||||
"index": 0,
|
||||
"message": {
|
||||
"content": "{\n \"callee_name\": \"Jane Doe\",\n \"goal\": \"Arrange a dental checkup\",\n \"context\": \"User forgot to include exact appointment time and confirmation code\",\n \"instructions\": \"Repeat the missing appointment time and confirmation code, obtain explicit confirmation from the user, and only complete the task with the confirmed values\",\n \"opening_line\": \"Could you please provide the exact appointment time for Jane Doe's dental checkup and the confirmation code?\",\n \"missing_information\": [\"appointment time\", \"confirmation code\"],\n \"decision_summary\": \"Requesting the user to explicitly confirm the dental checkup time and confirmation code as they were previously omitted\"\n}",
|
||||
"role": "assistant",
|
||||
"reasoning_content": "So, let's see. I need to structure the JSON according to the user's request. First, callee_name is Jane Doe. The goal is to arrange a dental checkup. Context is that the user forgot the exact time and confirmation code, so those are missing. Instructions should tell the voice Agent to repeat the facts, get explicit confirmation. Opening line needs to ask aloud for the missing appointment time and confirmation code. Missing_information should list time and confirmation code. Decision_summary is about requesting the user to provide the time and confirmation code."
|
||||
}
|
||||
}
|
||||
],
|
||||
"created": 1785497040,
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"object": "chat.completion",
|
||||
"service_tier": "default",
|
||||
"usage": {
|
||||
"completion_tokens": 262,
|
||||
"prompt_tokens": 222,
|
||||
"total_tokens": 484,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 113
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"raw_response_sha256": "2b02efd3ca007ca45bec6d2be83978d630a064d5f23ac15e0a1058979770760d",
|
||||
"response_content": "{\n \"callee_name\": \"Jane Doe\",\n \"goal\": \"Arrange a dental checkup\",\n \"context\": \"User forgot to include exact appointment time and confirmation code\",\n \"instructions\": \"Repeat the missing appointment time and confirmation code, obtain explicit confirmation from the user, and only complete the task with the confirmed values\",\n \"opening_line\": \"Could you please provide the exact appointment time for Jane Doe's dental checkup and the confirmation code?\",\n \"missing_information\": [\"appointment time\", \"confirmation code\"],\n \"decision_summary\": \"Requesting the user to explicitly confirm the dental checkup time and confirmation code as they were previously omitted\"\n}",
|
||||
"response_content_sha256": "13c94bdc67acc4f47d52ad737b445cb82598d02f9036e0afe14f57f9030dcb96",
|
||||
"external_request_completed": true,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"credential_fields_retained": false
|
||||
},
|
||||
{
|
||||
"schema_version": 1,
|
||||
"purpose": "post_asr_dialogue",
|
||||
"execution": "real_external_llm",
|
||||
"provider": "ark",
|
||||
"requested_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_model": "doubao-seed-1-6-flash-250615",
|
||||
"provider_response_id": "021785497071624d9018183c34bd269dc45b9a10b892d56f50515",
|
||||
"finish_reason": "stop",
|
||||
"usage": {
|
||||
"completion_tokens": 168,
|
||||
"prompt_tokens": 366,
|
||||
"total_tokens": 534,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 75
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
},
|
||||
"started_at_utc": "2026-07-31T11:24:31.373004+00:00",
|
||||
"finished_at_utc": "2026-07-31T11:24:33.913565+00:00",
|
||||
"latency_seconds": 2.54053,
|
||||
"request": {
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are the voice Agent in a short local browser call. The user text below came only from ASR over the browser microphone RTP track. Return only JSON with assistant_message, explicit_confirmation_observed (boolean), should_complete (boolean), and completion containing result, appointment_time, confirmation_number, notes. If the user states an exact time, a confirmation code, and explicitly confirms both, set should_complete=true, normalize obvious spoken code words/digits into a concise code, and repeat both details in assistant_message. Otherwise ask only for what is missing. Never say booked, arranged, scheduled, or imply an external action occurred. For a completed turn, completion.result must be exactly 'Local confirmation recorded.' and completion.notes must be exactly 'No external organization was contacted or booking made.' Goal: Arrange a dental checkup\nContext: User forgot to include exact appointment time and confirmation code\nInstructions: Repeat the missing appointment time and confirmation code, obtain explicit confirmation from the user, and only complete the task with the confirmed values"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "{\"latest_user_asr_transcript\":\"Confirmation called a Cedar 8. I explicitly confirm Tuesday at 3 p.m. and confirmation called Cedar 8.\",\"prior_audio_transcript\":[{\"purpose\":\"missing_field_clarification\",\"source\":\"tts.webrtc_downlink\",\"speaker\":\"agent\",\"text\":\"Could you please provide the exact appointment time for Jane Doe's dental checkup and the confirmation code?\",\"utterance_id\":\"tts_01\"}]}"
|
||||
}
|
||||
],
|
||||
"response_format": {
|
||||
"type": "json_object"
|
||||
},
|
||||
"temperature": 0,
|
||||
"max_tokens": 700
|
||||
},
|
||||
"request_sha256": "926acff71159d1659a957a45a8244a1f2d6eeefbf78987a155bd0e8aa6660378",
|
||||
"raw_response": {
|
||||
"id": "021785497071624d9018183c34bd269dc45b9a10b892d56f50515",
|
||||
"choices": [
|
||||
{
|
||||
"finish_reason": "stop",
|
||||
"index": 0,
|
||||
"message": {
|
||||
"content": "{\"assistant_message\": \"Appointment time confirmed as Tuesday at 3 p.m. and confirmation number confirmed as Cedar 8.\", \"explicit_confirmation_observed\": true, \"should_complete\": true, \"completion\": {\"result\": \"Local confirmation recorded.\", \"appointment_time\": \"Tuesday at 3 p.m.\", \"confirmation_number\": \"Cedar 8\", \"notes\": \"No external organization was contacted or booking made.\"}}",
|
||||
"role": "assistant",
|
||||
"reasoning_content": "Got it, let's see. The user mentioned Tuesday at 3 p.m. as the appointment time and confirmed the confirmation code as Cedar 8. So now I need to structure the JSON with assistant_message repeating the details, explicit_confirmation_observed as true, should_complete as true, and completion with result, appointment_time, confirmation_number, notes."
|
||||
}
|
||||
}
|
||||
],
|
||||
"created": 1785497074,
|
||||
"model": "doubao-seed-1-6-flash-250615",
|
||||
"object": "chat.completion",
|
||||
"service_tier": "default",
|
||||
"usage": {
|
||||
"completion_tokens": 168,
|
||||
"prompt_tokens": 366,
|
||||
"total_tokens": 534,
|
||||
"completion_tokens_details": {
|
||||
"reasoning_tokens": 75
|
||||
},
|
||||
"prompt_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"raw_response_sha256": "26440ed69dcb1f77178a284fdd0571e6f90cca9c776402bcf4e8ffcb56bfa994",
|
||||
"response_content": "{\"assistant_message\": \"Appointment time confirmed as Tuesday at 3 p.m. and confirmation number confirmed as Cedar 8.\", \"explicit_confirmation_observed\": true, \"should_complete\": true, \"completion\": {\"result\": \"Local confirmation recorded.\", \"appointment_time\": \"Tuesday at 3 p.m.\", \"confirmation_number\": \"Cedar 8\", \"notes\": \"No external organization was contacted or booking made.\"}}",
|
||||
"response_content_sha256": "589e901f03635305e84094cd8a1e6619643fb554bf6ce175550feaf22b0246c3",
|
||||
"external_request_completed": true,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"credential_fields_retained": false
|
||||
}
|
||||
],
|
||||
"asr_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "asr",
|
||||
"execution": "real_local_inference",
|
||||
"provider": "local OpenAI Whisper",
|
||||
"model": "whisper-tiny",
|
||||
"checkpoint_name": "tiny.pt",
|
||||
"checkpoint_sha256": "65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9",
|
||||
"runtime": {
|
||||
"python": "3.11.4",
|
||||
"torch": "2.4.0",
|
||||
"openai_whisper": "20231106"
|
||||
},
|
||||
"input_source": "browser_microphone_rtp",
|
||||
"input_sample_rate_hz": 16000,
|
||||
"input_channels": 1,
|
||||
"input_pcm_bytes": 733408,
|
||||
"input_wav_bytes": 733452,
|
||||
"input_wav_sha256": "d13d43693d8af1b579ff7a5f458f7bf0940fbf0daec9ddebc9f279ed1317d73a",
|
||||
"input_duration_seconds": 22.919,
|
||||
"language": "en",
|
||||
"transcript": "Confirmation called a Cedar 8. I explicitly confirm Tuesday at 3 p.m. and confirmation called Cedar 8.",
|
||||
"transcript_sha256": "cabe012d1165ad25d56167aa5b898fa029facf739a658df6d8580ddfaa6715d5",
|
||||
"model_load_seconds": 0.314773,
|
||||
"inference_seconds": 0.511034,
|
||||
"latency_seconds": 1.865804,
|
||||
"retained_safe_fixture_path": "media/react/microphone_rtp_asr_input.wav",
|
||||
"external_request": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false
|
||||
}
|
||||
],
|
||||
"tts_receipts": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 8000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 43638,
|
||||
"duration_seconds": 5.45475,
|
||||
"wav_bytes": 87354,
|
||||
"wav_sha256": "36569fa63273d1ed2e7ff1eec9e3be7fc5e878e935bd58e7ea25bc5a6011b473",
|
||||
"pcm_sha256": "cc573183930ba8f3640ff06dfa7462d5575d30a01685b3fc2d1f6591f1aace06",
|
||||
"latency_seconds": 0.959548,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"utterance_id": "tts_01",
|
||||
"purpose": "missing_field_clarification",
|
||||
"retained_safe_fixture_path": "media/react/agent_01.wav",
|
||||
"text_sha256": "8210e199a83fcf3de8179059a226e38ad88463493c974beb40460683b21fb785",
|
||||
"enqueued_on_webrtc_track": true,
|
||||
"transmitted_samples": 43638,
|
||||
"delivery_complete": true,
|
||||
"delivered_pcm_sha256": "cc573183930ba8f3640ff06dfa7462d5575d30a01685b3fc2d1f6591f1aace06"
|
||||
},
|
||||
{
|
||||
"schema_version": 1,
|
||||
"operation": "tts",
|
||||
"execution": "real_speech_synthesis",
|
||||
"provider": "macOS say",
|
||||
"model": "operating-system speech synthesizer",
|
||||
"voice": "Samantha",
|
||||
"sample_rate_hz": 8000,
|
||||
"channels": 1,
|
||||
"sample_width_bytes": 2,
|
||||
"sample_count": 41491,
|
||||
"duration_seconds": 5.186375,
|
||||
"wav_bytes": 83060,
|
||||
"wav_sha256": "e8a227f303baa45cdcdaa20700c58f2405adf06725394eafb9364b12079ea936",
|
||||
"pcm_sha256": "1686b19c8c3c73b3629c7aeac74029bc70d59d1f326ad47524b81bee3794ac28",
|
||||
"latency_seconds": 0.954852,
|
||||
"engine": {
|
||||
"name": "say",
|
||||
"sha256": "2bf4b7a6950c8365f3b51c1345d82b40595f4581c9bd50700e1ea485851e022d"
|
||||
},
|
||||
"decoder": {
|
||||
"name": "ffmpeg",
|
||||
"sha256": "5a4899a648370eccc8e73af934a8724d7af9195018eed29125432c782548f00a"
|
||||
},
|
||||
"network_used": false,
|
||||
"mock": false,
|
||||
"probe_only": false,
|
||||
"fallback_used": false,
|
||||
"utterance_id": "tts_02",
|
||||
"purpose": "confirmed_completion",
|
||||
"retained_safe_fixture_path": "media/react/agent_02.wav",
|
||||
"text_sha256": "5ba502a0adcb8198267792ac32cb50f475009bb1a0cfff839ac2c94f41df8cca",
|
||||
"enqueued_on_webrtc_track": true,
|
||||
"transmitted_samples": 41491,
|
||||
"delivery_complete": true,
|
||||
"delivered_pcm_sha256": "1686b19c8c3c73b3629c7aeac74029bc70d59d1f326ad47524b81bee3794ac28"
|
||||
}
|
||||
]
|
||||
},
|
||||
"transport": {
|
||||
"kind": "webrtc",
|
||||
"pstn_used": false,
|
||||
"e164_required": false,
|
||||
"sdp_negotiated": true,
|
||||
"offer_sha256": "a08ac0b87d92b1e92cb28fbb1b23d71a845dec2b6fcddd3b916ccd00c778ad69",
|
||||
"answer_sha256": "94bef0859b07a728240bf7699c0c9982744e1145783c3522c31a304a613d013c",
|
||||
"ice_connection_state": "connected",
|
||||
"ice_connected_observed": true,
|
||||
"data_channel_open": true,
|
||||
"local_audio_track": true,
|
||||
"remote_audio_track": true,
|
||||
"rtc_stats": {
|
||||
"inbound_packets": 1679,
|
||||
"inbound_bytes": 147402,
|
||||
"outbound_packets": 1679,
|
||||
"outbound_bytes": 69386
|
||||
},
|
||||
"server_received_audio_frames": 1675,
|
||||
"server_received_audio_samples": 1608000,
|
||||
"server_received_audio_pcm_bytes": 1071968,
|
||||
"server_sent_tts_samples": 85129
|
||||
},
|
||||
"privacy": {
|
||||
"safe_synthetic_acceptance": true,
|
||||
"private_audio_retained": false,
|
||||
"private_transcripts_retained": false,
|
||||
"safe_synthetic_media_retained": true
|
||||
},
|
||||
"event_counts": {
|
||||
"client.audio.commit": 1,
|
||||
"rtc.ready": 6,
|
||||
"rtc.stats": 46
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"speaker": "agent",
|
||||
"text": "Could you please provide the exact appointment time for Jane Doe's dental checkup and the confirmation code?",
|
||||
"source": "tts.webrtc_downlink",
|
||||
"utterance_id": "tts_01",
|
||||
"purpose": "missing_field_clarification"
|
||||
},
|
||||
{
|
||||
"speaker": "user",
|
||||
"text": "Confirmation called a Cedar 8. I explicitly confirm Tuesday at 3 p.m. and confirmation called Cedar 8.",
|
||||
"source": "asr.microphone_rtp",
|
||||
"asr_receipt_index": 0
|
||||
},
|
||||
{
|
||||
"speaker": "agent",
|
||||
"text": "Appointment time confirmed as Tuesday at 3 p.m. and confirmation number confirmed as Cedar 8.",
|
||||
"source": "tts.webrtc_downlink",
|
||||
"utterance_id": "tts_02",
|
||||
"purpose": "confirmed_completion"
|
||||
}
|
||||
],
|
||||
"explicit_confirmation_observed": true,
|
||||
"completion": {
|
||||
"result": "Local confirmation recorded.",
|
||||
"appointment_time": "Tuesday at 3 p.m.",
|
||||
"confirmation_number": "Cedar 8",
|
||||
"notes": "No external organization was contacted or booking made.",
|
||||
"saved_at_utc": "2026-07-31T11:24:34.870657+00:00",
|
||||
"tool": "complete_task"
|
||||
},
|
||||
"errors": [],
|
||||
"acceptance": {
|
||||
"checks": {
|
||||
"sdp_offer_answer_negotiated": true,
|
||||
"ice_connected": true,
|
||||
"data_channel_open": true,
|
||||
"browser_microphone_track": true,
|
||||
"server_downlink_audio_track": true,
|
||||
"outbound_audio_rtp": true,
|
||||
"inbound_audio_rtp": true,
|
||||
"server_buffered_microphone_rtp": true,
|
||||
"real_asr_consumed_microphone_audio": true,
|
||||
"external_react_planner_or_fixed_direct_control": true,
|
||||
"real_external_post_asr_dialogue": true,
|
||||
"real_tts_assets_synthesized": true,
|
||||
"tts_audio_transmitted_on_downlink": true,
|
||||
"media_is_canonical_transcript_source": true,
|
||||
"data_channel_is_control_and_caption_only": true,
|
||||
"missing_fields_were_clarified_aloud": true,
|
||||
"explicit_confirmation_observed": true,
|
||||
"structured_completion_saved": true,
|
||||
"no_mock_probe_or_fallback": true,
|
||||
"privacy_boundary_preserved": true
|
||||
},
|
||||
"passed": true
|
||||
},
|
||||
"finish_reason": "automated_safe_acceptance"
|
||||
}
|
||||
Reference in New Issue
Block a user