fix: P1 fixes + TUI dashboard improvements
- StateGraph: checkpoint now saves next node (prevents re-execution on resume) - Engine: pre-build node_map dict (O(1) lookup, was O(N²)) - Reranker: replace deprecated asyncio.get_event_loop() with get_running_loop() - Executor: use collections.deque for O(1) popleft (was list.pop(0)) - Dashboard: increase SSH timeouts (8s connect, 15s total), fold long columns, add macOS RAM detection, wider console (160 cols min) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Ajouté (2026-03-27)
|
||||||
|
- **Voice bridge rewrite** (f673822): pont audio OPUS ESP32-S3-BOX-3 vers mascarade (+441 lignes), routage hint `[HINT:puzzle:level]` vers le moteur de hints mascarade.
|
||||||
|
- **scenario_manager** (f673822): module `scenario_manager.cpp/.h` — gestionnaire d'état scénario centralisé, transitions validées, hooks pré/post-transition, persistence NVS.
|
||||||
|
- **P0 fixes**: correction du crash audio DMA sur cold boot BOX-3, fix du timeout WebSocket reconnect (backoff exponentiel 1-30s), correction du double-free dans `voice_pipeline` sur abort rapide.
|
||||||
|
|
||||||
|
### Corrigé (2026-03-27)
|
||||||
|
- **VAD hint routing** (f87820e): le routage des hints via VAD ne déclenchait pas correctement le moteur mascarade.
|
||||||
|
- **Session leak** (f87820e): fuite mémoire dans les sessions WebSocket non fermées proprement.
|
||||||
|
- **YAML regex** (f87820e): regex de parsing scénario corrigée pour les caractères spéciaux.
|
||||||
|
- **Markdown rendering** (f87820e): correction de l'affichage markdown dans le dashboard.
|
||||||
|
- **UTF-8 encoding** (f87820e): encodage des réponses hints en UTF-8 (accents français).
|
||||||
|
|
||||||
### Ajouté
|
### Ajouté
|
||||||
- Runtime 3 : compilateur (`tools/scenario/compile_runtime3.py`) et simulateur (`tools/scenario/simulate_runtime3.py`) pour le moteur de scénarios V2.
|
- Runtime 3 : compilateur (`tools/scenario/compile_runtime3.py`) et simulateur (`tools/scenario/simulate_runtime3.py`) pour le moteur de scénarios V2.
|
||||||
- Studio visuel React + Blockly dans `frontend-scratch-v2/` pour l'édition graphique des scénarios.
|
- Studio visuel React + Blockly dans `frontend-scratch-v2/` pour l'édition graphique des scénarios.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ enum class StoryEventType : uint8_t {
|
|||||||
kButton,
|
kButton,
|
||||||
kEspNow,
|
kEspNow,
|
||||||
kAction,
|
kAction,
|
||||||
|
kVoice,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class StoryTransitionTrigger : uint8_t {
|
enum class StoryTransitionTrigger : uint8_t {
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ StoryEventType parseEventType(const char* value) {
|
|||||||
if (strcmp(value, "action") == 0) {
|
if (strcmp(value, "action") == 0) {
|
||||||
return StoryEventType::kAction;
|
return StoryEventType::kAction;
|
||||||
}
|
}
|
||||||
|
if (strcmp(value, "voice") == 0 || strcmp(value, "voice_bridge") == 0) {
|
||||||
|
return StoryEventType::kVoice;
|
||||||
|
}
|
||||||
return StoryEventType::kNone;
|
return StoryEventType::kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class ScenarioManager {
|
|||||||
bool notifySerialEvent(const char* event_name, uint32_t now_ms);
|
bool notifySerialEvent(const char* event_name, uint32_t now_ms);
|
||||||
bool notifyTimerEvent(const char* event_name, uint32_t now_ms);
|
bool notifyTimerEvent(const char* event_name, uint32_t now_ms);
|
||||||
bool notifyActionEvent(const char* event_name, uint32_t now_ms);
|
bool notifyActionEvent(const char* event_name, uint32_t now_ms);
|
||||||
|
bool notifyVoiceEvent(const char* event_name, uint32_t now_ms);
|
||||||
bool gotoScene(const char* scene_id, uint32_t now_ms, const char* source);
|
bool gotoScene(const char* scene_id, uint32_t now_ms, const char* source);
|
||||||
|
|
||||||
ScenarioSnapshot snapshot() const;
|
ScenarioSnapshot snapshot() const;
|
||||||
|
|||||||
@@ -361,6 +361,12 @@ bool ScenarioManager::notifyActionEvent(const char* event_name, uint32_t now_ms)
|
|||||||
return dispatchEvent(StoryEventType::kAction, name, now_ms, "action_event");
|
return dispatchEvent(StoryEventType::kAction, name, now_ms, "action_event");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScenarioManager::notifyVoiceEvent(const char* event_name, uint32_t now_ms) {
|
||||||
|
const char* name = (event_name != nullptr && event_name[0] != '\0') ? event_name : "VOICE_EVENT";
|
||||||
|
Serial.printf("[ScenarioManager] Voice event received: %s\n", name);
|
||||||
|
return dispatchEvent(StoryEventType::kVoice, name, now_ms, "voice_event");
|
||||||
|
}
|
||||||
|
|
||||||
bool ScenarioManager::gotoScene(const char* scene_id, uint32_t now_ms, const char* source) {
|
bool ScenarioManager::gotoScene(const char* scene_id, uint32_t now_ms, const char* source) {
|
||||||
if (scenario_ == nullptr || scene_id == nullptr || scene_id[0] == '\0') {
|
if (scenario_ == nullptr || scene_id == nullptr || scene_id[0] == '\0') {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user