Add voice state tags, SuperTTS configs, and demo WS log groups.

Parse leading <state> tags from LLM replies and emit response.state over the product websocket while stripping tags from TTS/text streams. Add FastGPT+Xfyun voice configs (including state-enabled preset), SuperTTS support, and context sync for interrupted turns. Refresh the voice demo with a state indicator and collapsible audio delta websocket log groups.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Xin Wang
2026-05-28 11:32:20 +08:00
parent b14ef64665
commit 9e2374f492
18 changed files with 1596 additions and 195 deletions

View File

@@ -0,0 +1,101 @@
{
"server": {
"host": "0.0.0.0",
"port": 8000,
"cors_origins": ["*"]
},
"audio": {
"sample_rate_hz": 16000,
"channels": 1,
"frame_ms": 20
},
"session": {
"inactivity_timeout_sec": 60
},
"turn": {
"vad": {
"confidence": 0.8,
"start_secs": 0.4,
"stop_secs": 0.2,
"min_volume": 0.8
},
"interruption_min_chars": 3,
"interruption_use_interim": true,
"interruption_short_replies": [
"是",
"是的",
"对",
"对的",
"嗯",
"好",
"好的",
"行",
"可以",
"没问题",
"不是",
"不",
"不行",
"不用",
"不要",
"没有",
"否",
"你好",
"在吗"
],
"user_speech_timeout_sec": 0.2
},
"agent": {
"system_prompt": "FastGPT app owns the system prompt when send_system_prompt is false.",
"greeting": "您好,这里是无锡交警,我将为您远程处理交通事故。请将人员撤离至路侧安全区域,开启危险报警双闪灯、放置三角警告牌、做好安全防护,谨防二次事故伤害。若您已经准备好了,请点击继续办理,如需人工服务,请说转人工。",
"greeting_mode": "fixed",
"response_state": {
"enabled": true,
"tag": "state",
"event_type": "response.state",
"max_prefix_chars": 256
}
},
"services": {
"stt": {
"provider": "xfyun",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://iat-api.xfyun.cn/v2/iat",
"language": "zh_cn",
"domain": "iat",
"accent": "mandarin",
"encoding": "raw",
"frame_size": 1280,
"timeout_sec": 10.0
},
"llm": {
"provider": "fastgpt",
"api_key": "fastgpt-zlLjYtWZWN0uhQHs3ZOFHG4KLGMIdr2CkbZLCSfqGm5vcdx5xIZbp",
"base_url": "http://localhost:3030",
"model": "my-voice-app",
"app_id": "691eddaa53e3f8d9f25f1370",
"chat_id": null,
"variables": {},
"detail": false,
"timeout_sec": 60.0,
"send_system_prompt": false
},
"tts": {
"provider": "xfyun_super",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://cbm01.cn-huabei-1.xf-yun.com/v1/private/mcd9m97e6",
"voice": "x5_lingxiaoxuan_flow",
"aue": "raw",
"speed": 50,
"volume": 50,
"pitch": 50,
"oral_level": "mid",
"source_sample_rate_hz": 24000,
"text_aggregation_mode": "token",
"timeout_sec": 30.0
}
}
}

View File

@@ -0,0 +1,101 @@
{
"server": {
"host": "0.0.0.0",
"port": 8000,
"cors_origins": ["*"]
},
"audio": {
"sample_rate_hz": 16000,
"channels": 1,
"frame_ms": 20
},
"session": {
"inactivity_timeout_sec": 60
},
"turn": {
"vad": {
"confidence": 0.8,
"start_secs": 0.4,
"stop_secs": 0.2,
"min_volume": 0.8
},
"interruption_min_chars": 3,
"interruption_use_interim": true,
"interruption_short_replies": [
"是",
"是的",
"对",
"对的",
"嗯",
"好",
"好的",
"行",
"可以",
"没问题",
"不是",
"不",
"不行",
"不用",
"不要",
"没有",
"否",
"你好",
"在吗"
],
"user_speech_timeout_sec": 0.2
},
"agent": {
"system_prompt": "FastGPT app owns the system prompt when send_system_prompt is false.",
"greeting": "您好,这里是无锡交警,我将为您远程处理交通事故。请将人员撤离至路侧安全区域,开启危险报警双闪灯、放置三角警告牌、做好安全防护,谨防二次事故伤害。若您已经准备好了,请点击继续办理,如需人工服务,请说转人工。",
"greeting_mode": "fixed",
"response_state": {
"enabled": true,
"tag": "state",
"event_type": "response.state",
"max_prefix_chars": 256
}
},
"services": {
"stt": {
"provider": "xfyun",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://iat-api.xfyun.cn/v2/iat",
"language": "zh_cn",
"domain": "iat",
"accent": "mandarin",
"encoding": "raw",
"frame_size": 1280,
"timeout_sec": 10.0
},
"llm": {
"provider": "fastgpt",
"api_key": "fastgpt-v1FljAxBz3tJeS0bH7HZU4yVGclsTcfiy9yK7V9Zr9126maDHQ97Xlo8n",
"base_url": "http://localhost:3030",
"model": "my-voice-app",
"app_id": "6a153aed53e3f8d9f2744905",
"chat_id": null,
"variables": {},
"detail": false,
"timeout_sec": 60.0,
"send_system_prompt": false
},
"tts": {
"provider": "xfyun_super",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://cbm01.cn-huabei-1.xf-yun.com/v1/private/mcd9m97e6",
"voice": "x5_lingxiaoxuan_flow",
"aue": "raw",
"speed": 50,
"volume": 50,
"pitch": 50,
"oral_level": "mid",
"source_sample_rate_hz": 24000,
"text_aggregation_mode": "token",
"timeout_sec": 30.0
}
}
}

View File

@@ -0,0 +1,101 @@
{
"server": {
"host": "0.0.0.0",
"port": 8000,
"cors_origins": ["*"]
},
"audio": {
"sample_rate_hz": 16000,
"channels": 1,
"frame_ms": 20
},
"session": {
"inactivity_timeout_sec": 60
},
"turn": {
"vad": {
"confidence": 0.7,
"start_secs": 0.35,
"stop_secs": 0.2,
"min_volume": 0.65
},
"interruption_min_chars": 3,
"interruption_use_interim": true,
"interruption_short_replies": [
"是",
"是的",
"对",
"对的",
"嗯",
"好",
"好的",
"行",
"可以",
"没问题",
"不是",
"不",
"不行",
"不用",
"不要",
"没有",
"否",
"你好",
"在吗"
],
"user_speech_timeout_sec": 0.2
},
"agent": {
"system_prompt": "FastGPT app owns the system prompt when send_system_prompt is false.",
"greeting": "您好,这里是无锡交警,我将为您远程处理交通事故。请将人员撤离至路侧安全区域,开启危险报警双闪灯、放置三角警告牌、做好安全防护,谨防二次事故伤害。若您已经准备好了,请点击继续办理,如需人工服务,请说转人工。",
"greeting_mode": "fixed",
"response_state": {
"enabled": true,
"tag": "state",
"event_type": "response.state",
"max_prefix_chars": 256
}
},
"services": {
"stt": {
"provider": "xfyun",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://iat-api.xfyun.cn/v2/iat",
"language": "zh_cn",
"domain": "iat",
"accent": "mandarin",
"encoding": "raw",
"frame_size": 1280,
"timeout_sec": 10.0
},
"llm": {
"provider": "fastgpt",
"api_key": "fastgpt-v1FljAxBz3tJeS0bH7HZU4yVGclsTcfiy9yK7V9Zr9126maDHQ97Xlo8n",
"base_url": "http://localhost:3030",
"model": "my-voice-app",
"app_id": "6a153aed53e3f8d9f2744905",
"chat_id": null,
"variables": {},
"detail": false,
"timeout_sec": 60.0,
"send_system_prompt": false
},
"tts": {
"provider": "xfyun_super",
"app_id": "416ce125",
"api_key": "c65342fe603126c3610031d8429bb36d",
"api_secret": "MzkyYmI5OWEyODQzN2FiN2VhN2UzYzU4",
"base_url": "wss://cbm01.cn-huabei-1.xf-yun.com/v1/private/mcd9m97e6",
"voice": "x5_lingxiaoxuan_flow",
"aue": "raw",
"speed": 50,
"volume": 50,
"pitch": 50,
"oral_level": "mid",
"source_sample_rate_hz": 24000,
"text_aggregation_mode": "token",
"timeout_sec": 30.0
}
}
}

View File

@@ -1,58 +0,0 @@
{
"server": {
"host": "0.0.0.0",
"port": 8000,
"cors_origins": ["*"]
},
"audio": {
"sample_rate_hz": 16000,
"channels": 1,
"frame_ms": 20
},
"session": {
"inactivity_timeout_sec": 60
},
"turn": {
"vad": {
"confidence": 0.7,
"start_secs": 0.2,
"stop_secs": 0.6,
"min_volume": 0.6
},
"interruption_min_chars": 3,
"interruption_use_interim": true,
"user_speech_timeout_sec": 1.0
},
"agent": {
"system_prompt": "FastGPT app owns the system prompt when send_system_prompt is false.",
"greeting": "你好",
"greeting_mode": "generated"
},
"services": {
"stt": {
"provider": "openai",
"api_key": "",
"base_url": null,
"model": "gpt-4o-mini-transcribe",
"language": "zh"
},
"llm": {
"provider": "fastgpt",
"api_key": "",
"base_url": null,
"model": "my-voice-app",
"chat_id": null,
"variables": {},
"detail": false,
"timeout_sec": 60.0,
"send_system_prompt": false
},
"tts": {
"provider": "openai",
"api_key": "",
"base_url": null,
"model": "gpt-4o-mini-tts",
"voice": "alloy"
}
}
}

View File

@@ -45,7 +45,13 @@
"agent": {
"system_prompt": "# 角色 你是一个高度集成、安全第一的交警AI接警员。正在收集事故人员伤亡情况时间地点事故原因事故车辆数量收集完成之后和用户说再见",
"greeting": "您好,这里是无锡交警,我将为您远程处理交通事故。请将人员撤离至路侧安全区域,开启危险报警双闪灯、放置三角警告牌、做好安全防护,谨防二次事故伤害。若您已经准备好了,请点击继续办理,如需人工服务,请说转人工。",
"greeting_mode": "fixed"
"greeting_mode": "fixed",
"response_state": {
"enabled": true,
"tag": "state",
"event_type": "response.state",
"max_prefix_chars": 256
}
},
"services": {
"stt": {

View File

@@ -47,7 +47,13 @@
"agent": {
"system_prompt": "You are a helpful, friendly voice assistant. Keep responses concise and natural for spoken conversation.",
"greeting": "Please introduce yourself briefly.",
"greeting_mode": "generated"
"greeting_mode": "generated",
"response_state": {
"enabled": false,
"tag": "state",
"event_type": "response.state",
"max_prefix_chars": 256
}
},
"services": {
"stt": {