Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions components/voicelife_application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
idf_component_register(
SRCS "src/interaction_orchestrator.cc"
INCLUDE_DIRS "include"
REQUIRES voicelife_contracts voicelife_voice
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include <string>
#include <string_view>

#include "voicelife/contracts/status.h"
#include "voicelife/voice/voice_interaction_controller.h"

namespace voicelife::application {

/** @brief 一次交互编排请求的稳定输入模型,不携带 ESP-IDF 或 FreeRTOS 类型。 */
struct InteractionEvent {
voice::VoiceInteractionEvent voice_event = voice::VoiceInteractionEvent::kBootCompleted;
std::string_view wake_word;
};

/** @brief 一次合法状态迁移产生的、可由平台适配器执行的语义动作。 */
struct InteractionAction {
voice::VoiceInteractionEvent source = voice::VoiceInteractionEvent::kBootCompleted;
voice::VoiceInteractionState state = voice::VoiceInteractionState::kBooting;
voice::VoiceInteractionAction directive = voice::VoiceInteractionAction::kNone;
std::string wake_word;

friend bool operator==(const InteractionAction& lhs, const InteractionAction& rhs) {
return lhs.source == rhs.source && lhs.state == rhs.state && lhs.directive == rhs.directive &&
lhs.wake_word == rhs.wake_word;
}
};

/** @brief Runtime Adapter 实现的动作接收端口。 */
class InteractionActionSink {
public:
/** @brief 虚析构函数。 */
virtual ~InteractionActionSink() = default;
/**
* @brief 接收一个应用层编排动作。
* @param action 要执行的语义动作。
* @return 动作投影结果。
*/
virtual Status Submit(InteractionAction action) = 0;
};

/**
* @brief 平台无关的交互应用服务。
*
* 该服务拥有平台无关的交互状态机,并将合法状态迁移交给 Runtime Adapter
* 执行。FreeRTOS 队列、任务和定时器仍属于 ESP Runtime Adapter。
*/
class InteractionOrchestrator {
public:
/**
* @brief 将一个交互事件映射为状态和确定的 Runtime Adapter 动作。
* @param event 要编排的跨域交互事件。
* @param actions 用于记录或执行动作的 Runtime Adapter 端口。
* @return 状态机接受事件且动作投影成功时返回成功状态。
*/
Status Handle(InteractionEvent event, InteractionActionSink& actions);

/** @brief 返回最后一个已接受事件后的交互状态。 @return 当前交互状态。 */
[[nodiscard]] voice::VoiceInteractionState state() const;

private:
voice::VoiceInteractionController controller_;
};

} // namespace voicelife::application
18 changes: 18 additions & 0 deletions components/voicelife_application/src/interaction_orchestrator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "voicelife/application/interaction_orchestrator.h"

namespace voicelife::application {

Status InteractionOrchestrator::Handle(InteractionEvent event, InteractionActionSink& actions) {
const auto transition = controller_.Handle(event.voice_event);
if (!transition.ok()) {
return transition.status;
}
return actions.Submit({.source = event.voice_event,
.state = transition.value->state,
.directive = transition.value->action,
.wake_word = std::string(event.wake_word)});
}

voice::VoiceInteractionState InteractionOrchestrator::state() const { return controller_.state(); }

} // namespace voicelife::application
17 changes: 2 additions & 15 deletions components/voicelife_runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
idf_component_register(
SRCS "src/runtime.cc" "src/bootstrap/storage_bootstrap.cc" "src/im_runtime_bootstrap.cc"
"src/linx_mcp_bridge.cc" "src/linx_ota_bootstrap.cc" "src/wifi_provisioning.cc"
"src/wifi_provisioning_esp.cc"
"src/im_binding_mcp_tools.cc" "src/im_binding_presentation.cc"
INCLUDE_DIRS "include" "src"
REQUIRES voicelife_contracts
PRIV_REQUIRES voicelife_mcp voicelife_voice voicelife_linx voicelife_linx_esp voicelife_audio_esp
voicelife_display_esp voicelife_schedule voicelife_im voicelife_storage_fatfs
voicelife_storage_sqlite nvs_flash nvs_sec_provider esp_timer esp_http_client esp-tls esp_wifi
esp_netif lwip esp_event esp_http_server spi_flash esp_partition esp_psram esp_app_format esp_driver_gpio
esp_driver_usb_serial_jtag led_strip
INCLUDE_DIRS "include"
REQUIRES voicelife_contracts voicelife_voice
)

if(NOT CONFIG_VOICELIFE_STORAGE_FATFS OR NOT CONFIG_VOICELIFE_STORAGE_SQLITE)
message(FATAL_ERROR "Runtime 日程持久化必须同时启用 VOICELIFE_STORAGE_FATFS 和 VOICELIFE_STORAGE_SQLITE")
endif()
Loading
Loading