merge: integrate remote speech capabilities into feature/N7Web

This commit is contained in:
minghanchen
2026-09-01 17:01:50 +08:00
39 changed files with 6869 additions and 52 deletions
+44 -5
View File
@@ -7556,18 +7556,21 @@ function naturalLanguageRequestBody(
{
executionMode = state.executionMode,
clientType = "web_console",
provider = state.provider,
speechUtteranceId = null,
} = {},
) {
const driverOnlyCh1 = isDriverOnlyCh1Runtime();
return {
utterance,
client_type: clientType,
provider: state.provider,
provider,
conversation_id: state.conversationId,
vehicle_id: state.vehicleId || state.runtime?.default_vehicle_id,
execution_mode: executionMode,
control_transport: state.controlTransport,
...(state.provider === "openai" ? { reasoning_effort: state.reasoningEffort } : {}),
...(provider === "openai" ? { reasoning_effort: state.reasoningEffort } : {}),
...(speechUtteranceId ? { speech_utterance_id: speechUtteranceId } : {}),
...(executionMode === "hardware"
&& state.controlTransport !== "wireless_mqtt"
&& !driverOnlyCh1
@@ -7584,6 +7587,8 @@ async function requestNaturalLanguageControl(
{
executionMode = state.executionMode,
clientType = "web_console",
provider = state.provider,
speechUtteranceId = null,
previewOnly = false,
onControlPhaseEvent = null,
onPreview = null,
@@ -7593,8 +7598,10 @@ async function requestNaturalLanguageControl(
const requestBody = naturalLanguageRequestBody(utterance, {
executionMode,
clientType,
provider,
speechUtteranceId,
});
const usePreview = previewOnly || state.provider === "openai";
const usePreview = previewOnly || provider === "openai";
if (!usePreview) {
const payload = await postControlPhase(
"/api/requests",
@@ -7623,7 +7630,7 @@ async function requestNaturalLanguageControl(
`/api/requests/${preview.request_id}/supplement`,
{
client_type: clientType,
provider: state.provider,
provider,
reasoning_effort: state.reasoningEffort,
...(executionMode === "hardware"
&& state.controlTransport !== "wireless_mqtt"
@@ -7712,7 +7719,14 @@ async function executeCanCommands(canCommands, { deviceName = "车辆设备" } =
async function submitRequest(event) {
event.preventDefault();
const utterance = $("#utterance").value.trim();
const utteranceInput = $("#utterance");
const utterance = utteranceInput.value.trim();
const speechSubmission = (
utteranceInput.dataset.speechExecutionEligible === "true"
&& utteranceInput.dataset.speechValue === utterance
&& Boolean(utteranceInput.dataset.speechUtteranceId)
);
const requestProvider = speechSubmission ? "local" : state.provider;
const submittedModeProfileId = state.pendingModeProfileId;
state.pendingModeProfileId = null;
if (!utterance) {
@@ -7720,6 +7734,20 @@ async function submitRequest(event) {
showToast("请输入车舱控制请求");
return;
}
if (
utteranceInput.dataset.speechExecutionEligible === "false"
&& utteranceInput.dataset.speechValue === utterance
) {
if (submittedModeProfileId) setModeExecutionState(submittedModeProfileId, "failed");
const speechStatus = utteranceInput.dataset.speechSemanticStatus;
const message = speechStatus === "recognized_unsupported"
? "语音意图已识别,但当前车辆能力不支持执行"
: speechStatus === "incomplete"
? "语音控制参数不完整,请补充后再执行"
: "语音结果存在歧义,请修改确认后再执行";
showToast(message);
return;
}
const driverOnlyCh1 = isDriverOnlyCh1Runtime();
if (state.executionMode === "hardware"
&& state.controlTransport !== "wireless_mqtt"
@@ -7757,6 +7785,10 @@ async function submitRequest(event) {
const { payload, supplementWarning } = await requestNaturalLanguageControl(
utterance,
{
provider: requestProvider,
speechUtteranceId: speechSubmission
? utteranceInput.dataset.speechUtteranceId
: null,
onControlPhaseEvent,
onPreview: (preview) => {
renderResult(preview);
@@ -7771,6 +7803,13 @@ async function submitRequest(event) {
if (!payload) return;
renderResult(payload);
completedResult = payload;
if (speechSubmission) {
delete utteranceInput.dataset.speechUtteranceId;
delete utteranceInput.dataset.speechExecutionEligible;
delete utteranceInput.dataset.speechSemanticStatus;
delete utteranceInput.dataset.speechValue;
delete utteranceInput.dataset.speechUncertain;
}
const peripheralRoute = String(payload.orchestration_route || "")
.startsWith("nfc_peripheral");
if (state.executionMode === "hardware" && !peripheralRoute) {