fix cross-process scenario switching and stale flights on scenario change
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
2026-04-16 01:42:10 -03:00
parent 22c924d3b0
commit e03ac3982a
5 changed files with 13 additions and 9 deletions

View File

@@ -12,8 +12,9 @@ from fastmcp import Client
def _env() -> dict: def _env() -> dict:
"""Forward LLM-related env vars to MCP server subprocesses.""" """Forward LLM-related env vars and active scenario to MCP server subprocesses."""
import os import os
from mcp_servers.data.scenarios.manager import scenario_manager
env = {} env = {}
for key in ( for key in (
@@ -27,6 +28,7 @@ def _env() -> dict:
val = os.getenv(key) val = os.getenv(key)
if val: if val:
env[key] = val env[key] = val
env["ACTIVE_SCENARIO"] = scenario_manager.active_id
return env return env

View File

@@ -22,9 +22,10 @@ case "${1:-rsync}" in
echo "=== Building and restarting on server ===" echo "=== Building and restarting on server ==="
ssh "$SERVER" << 'EOF' ssh "$SERVER" << 'EOF'
cd ~/unt cd ~/unt
docker build -t nova-api -f ctrl/Dockerfile.api . docker build -t registry.mcrn.ar/unt/api:latest -f ctrl/Dockerfile.api .
docker build -t nova-ui -f ctrl/Dockerfile.ui . docker build -t registry.mcrn.ar/unt/ui:latest -f ctrl/Dockerfile.ui .
cd ctrl/edge cd ctrl/edge
[ -f .env ] || cp .env.example .env
docker compose up -d --remove-orphans docker compose up -d --remove-orphans
docker image prune -f docker image prune -f
docker compose ps docker compose ps

View File

@@ -1,5 +1,5 @@
services: services:
nova-api: api:
image: registry.mcrn.ar/unt/api:latest image: registry.mcrn.ar/unt/api:latest
container_name: nova-api container_name: nova-api
restart: unless-stopped restart: unless-stopped
@@ -12,7 +12,7 @@ services:
container_name: nova-ui container_name: nova-ui
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- nova-api - api
networks: networks:
- gateway - gateway

View File

@@ -15,7 +15,8 @@ class ScenarioManager:
"""Manages the active scenario. Singleton — all MCP servers share one instance.""" """Manages the active scenario. Singleton — all MCP servers share one instance."""
def __init__(self) -> None: def __init__(self) -> None:
self._active_id: str = "weather_disruption_ord" import os
self._active_id: str = os.getenv("ACTIVE_SCENARIO") or os.getenv("DEFAULT_SCENARIO") or "weather_disruption_ord"
self._cache: dict[str, Any] = {} self._cache: dict[str, Any] = {}
@property @property

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch, inject } from 'vue' import { ref, onMounted, watch, inject, type Ref } from 'vue'
import { Panel, SplitPane, LogRenderer } from 'soleprint-ui' import { Panel, SplitPane, LogRenderer } from 'soleprint-ui'
import NotificationCard from '../components/NotificationCard.vue' import NotificationCard from '../components/NotificationCard.vue'
import HandoverBrief from '../components/HandoverBrief.vue' import HandoverBrief from '../components/HandoverBrief.vue'
@@ -12,7 +12,7 @@ const fceStatus = ref<'idle' | 'processing' | 'live' | 'error'>('idle')
const handoverStatus = ref<'idle' | 'processing' | 'live' | 'error'>('idle') const handoverStatus = ref<'idle' | 'processing' | 'live' | 'error'>('idle')
const notification = ref<any>(null) const notification = ref<any>(null)
const handoverBrief = ref<any>(null) const handoverBrief = ref<any>(null)
const scenarioVersion = inject<any>('scenarioVersion') const scenarioVersion = inject<Ref<number>>('scenarioVersion', ref(0))
const showOps = inject<any>('showOps') const showOps = inject<any>('showOps')
const showInternals = inject<any>('showInternals') const showInternals = inject<any>('showInternals')
@@ -21,7 +21,7 @@ const { agentStatus, entries, graphNodes, currentRun, connect } = useAgentEvents
// Connect WebSocket immediately so we don't miss events // Connect WebSocket immediately so we don't miss events
onMounted(connect) onMounted(connect)
watch(scenarioVersion, () => { watch(() => scenarioVersion.value, () => {
loadFlights() loadFlights()
notification.value = null notification.value = null
handoverBrief.value = null handoverBrief.value = null