brand renaming, scenario reloads flight
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"united-ops-shared": {
|
"stellar-ops-shared": {
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": ["run", "python", "-m", "mcp_servers.shared"]
|
"args": ["run", "python", "-m", "mcp_servers.shared"]
|
||||||
},
|
},
|
||||||
"united-ops-internal": {
|
"stellar-ops-internal": {
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": ["run", "python", "-m", "mcp_servers.ops"]
|
"args": ["run", "python", "-m", "mcp_servers.ops"]
|
||||||
},
|
},
|
||||||
"united-ops-passenger": {
|
"stellar-ops-passenger": {
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": ["run", "python", "-m", "mcp_servers.passenger"]
|
"args": ["run", "python", "-m", "mcp_servers.passenger"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ from typing import Any
|
|||||||
from agents.shared.mcp_client import MCPMultiClient
|
from agents.shared.mcp_client import MCPMultiClient
|
||||||
|
|
||||||
|
|
||||||
async def run_efhas(
|
async def run_fce(
|
||||||
flight_id: str,
|
flight_id: str,
|
||||||
mcp: MCPMultiClient,
|
mcp: MCPMultiClient,
|
||||||
on_event: Any = None,
|
on_event: Any = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Run the EFHaS agent for a single flight.
|
"""Run the FCE agent for a single flight.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
flight_id: The flight to generate a notification for.
|
flight_id: The flight to generate a notification for.
|
||||||
@@ -29,7 +29,7 @@ SERVERS = {
|
|||||||
|
|
||||||
# Agent profiles — which servers each agent connects to
|
# Agent profiles — which servers each agent connects to
|
||||||
AGENT_PROFILES = {
|
AGENT_PROFILES = {
|
||||||
"efhas": ["shared", "ops", "passenger"],
|
"fce": ["shared", "ops", "passenger"],
|
||||||
"handover": ["shared", "ops"],
|
"handover": ["shared", "ops"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
api/main.py
@@ -10,7 +10,7 @@ from fastapi import FastAPI, WebSocket, WebSocketDisconnect
|
|||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from agents.efhas import run_efhas
|
from agents.fce import run_fce
|
||||||
from agents.handover import run_handover
|
from agents.handover import run_handover
|
||||||
from agents.shared.mcp_client import connect_servers
|
from agents.shared.mcp_client import connect_servers
|
||||||
from mcp_servers.data.scenarios.manager import scenario_manager
|
from mcp_servers.data.scenarios.manager import scenario_manager
|
||||||
@@ -66,7 +66,7 @@ app.add_middleware(
|
|||||||
|
|
||||||
# ── Request/Response models ──
|
# ── Request/Response models ──
|
||||||
|
|
||||||
class EFHaSRequest(BaseModel):
|
class FCERequest(BaseModel):
|
||||||
flight_id: str
|
flight_id: str
|
||||||
|
|
||||||
class HandoverRequest(BaseModel):
|
class HandoverRequest(BaseModel):
|
||||||
@@ -78,15 +78,15 @@ class ScenarioUpdate(BaseModel):
|
|||||||
|
|
||||||
# ── Agent routes ──
|
# ── Agent routes ──
|
||||||
|
|
||||||
@app.post("/agents/efhas")
|
@app.post("/agents/fce")
|
||||||
async def trigger_efhas(req: EFHaSRequest):
|
async def trigger_fce(req: FCERequest):
|
||||||
run_id = str(uuid.uuid4())[:8]
|
run_id = str(uuid.uuid4())[:8]
|
||||||
runs[run_id] = {"status": "running", "agent": "efhas", "flight_id": req.flight_id}
|
runs[run_id] = {"status": "running", "agent": "fce", "flight_id": req.flight_id}
|
||||||
|
|
||||||
async def _run():
|
async def _run():
|
||||||
await event_hub.broadcast({
|
await event_hub.broadcast({
|
||||||
"type": "agent_start", "run_id": run_id,
|
"type": "agent_start", "run_id": run_id,
|
||||||
"agent": "efhas", "flight_id": req.flight_id,
|
"agent": "fce", "flight_id": req.flight_id,
|
||||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -95,10 +95,10 @@ async def trigger_efhas(req: EFHaSRequest):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
async with connect_servers(["shared", "ops", "passenger"]) as mcp:
|
async with connect_servers(["shared", "ops", "passenger"]) as mcp:
|
||||||
result = await run_efhas(req.flight_id, mcp, on_event=on_event)
|
result = await run_fce(req.flight_id, mcp, on_event=on_event)
|
||||||
runs[run_id] = {"status": "completed", "agent": "efhas", "result": result}
|
runs[run_id] = {"status": "completed", "agent": "fce", "result": result}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
runs[run_id] = {"status": "error", "agent": "efhas", "error": str(e)}
|
runs[run_id] = {"status": "error", "agent": "fce", "error": str(e)}
|
||||||
|
|
||||||
asyncio.create_task(_run())
|
asyncio.create_task(_run())
|
||||||
return {"run_id": run_id, "status": "running"}
|
return {"run_id": run_id, "status": "running"}
|
||||||
|
|||||||
@@ -16,4 +16,5 @@ RUN pnpm install && pnpm run build
|
|||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
COPY --from=build /ui/app/dist /usr/share/nginx/html
|
COPY --from=build /ui/app/dist /usr/share/nginx/html
|
||||||
|
COPY docs/ /usr/share/nginx/docs/
|
||||||
COPY ctrl/nginx.conf /etc/nginx/conf.d/default.conf
|
COPY ctrl/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ server {
|
|||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /docs/ {
|
||||||
|
alias /usr/share/nginx/docs/;
|
||||||
|
}
|
||||||
|
|
||||||
location /agents {
|
location /agents {
|
||||||
proxy_pass http://api:8000;
|
proxy_pass http://api:8000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: data_flow Pages: 1 -->
|
<!-- Title: data_flow Pages: 1 -->
|
||||||
<svg width="661pt" height="685pt"
|
<svg style="background:#0a0e17" width="1323pt" height="1371pt"
|
||||||
viewBox="0.00 0.00 661.00 685.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 1323.00 1371.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 681.25)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 681.25)">
|
||||||
<title>data_flow</title>
|
<title>data_flow</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-681.25 657.38,-681.25 657.38,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-681.25 657.38,-681.25 657.38,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="326.69" y="-659.95" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Data Flow — Real vs Mock</text>
|
<text xml:space="preserve" text-anchor="middle" x="326.69" y="-659.95" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Data Flow — Real vs Mock</text>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: deployment Pages: 1 -->
|
<!-- Title: deployment Pages: 1 -->
|
||||||
<svg width="748pt" height="1083pt"
|
<svg style="background:#0a0e17" width="1496pt" height="2167pt"
|
||||||
viewBox="0.00 0.00 748.00 1083.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 1496.00 2167.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1079.34)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 1079.34)">
|
||||||
<title>deployment</title>
|
<title>deployment</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-1079.34 744,-1079.34 744,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-1079.34 744,-1079.34 744,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="370" y="-1058.04" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Deployment — Kind Cluster (dev) / EC2 (prod)</text>
|
<text xml:space="preserve" text-anchor="middle" x="370" y="-1058.04" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Deployment — Kind Cluster (dev) / EC2 (prod)</text>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: efhas_agent Pages: 1 -->
|
<!-- Title: efhas_agent Pages: 1 -->
|
||||||
<svg width="696pt" height="932pt"
|
<svg style="background:#0a0e17" width="1392pt" height="1864pt"
|
||||||
viewBox="0.00 0.00 696.00 932.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 1392.00 1864.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 927.94)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 927.94)">
|
||||||
<title>efhas_agent</title>
|
<title>efhas_agent</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-927.94 691.94,-927.94 691.94,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-927.94 691.94,-927.94 691.94,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="343.97" y="-906.64" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">FCE Agent — Behind Every Departure</text>
|
<text xml:space="preserve" text-anchor="middle" x="343.97" y="-906.64" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">FCE Agent — Behind Every Departure</text>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: handover_agent Pages: 1 -->
|
<!-- Title: handover_agent Pages: 1 -->
|
||||||
<svg width="851pt" height="776pt"
|
<svg style="background:#0a0e17" width="1702pt" height="1552pt"
|
||||||
viewBox="0.00 0.00 851.00 776.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 1702.00 1552.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 771.79)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 771.79)">
|
||||||
<title>handover_agent</title>
|
<title>handover_agent</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-771.79 847,-771.79 847,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-771.79 847,-771.79 847,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="421.5" y="-750.49" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Shift Handover Agent</text>
|
<text xml:space="preserve" text-anchor="middle" x="421.5" y="-750.49" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Shift Handover Agent</text>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -5,7 +5,7 @@ digraph mcp_servers {
|
|||||||
node [fontname="Helvetica" fontsize=10 style=filled color="#1e2a4a" fontcolor="#e8eaf0"]
|
node [fontname="Helvetica" fontsize=10 style=filled color="#1e2a4a" fontcolor="#e8eaf0"]
|
||||||
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
|
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
|
||||||
|
|
||||||
label="MCP Server Topology — Tools · Resources · Prompts"
|
label="MCP Server Topology"
|
||||||
labelloc=t
|
labelloc=t
|
||||||
fontsize=14
|
fontsize=14
|
||||||
fontcolor="#0066ff"
|
fontcolor="#0066ff"
|
||||||
@@ -16,129 +16,59 @@ digraph mcp_servers {
|
|||||||
style=dashed
|
style=dashed
|
||||||
color="#1e2a4a"
|
color="#1e2a4a"
|
||||||
fontcolor="#8892a8"
|
fontcolor="#8892a8"
|
||||||
efhas [label="FCE\nAgent" fillcolor="#1a1a3a" shape=box]
|
fce [label="FCE Agent\n(passenger)" fillcolor="#1a1a3a" shape=box]
|
||||||
handover [label="Handover\nAgent" fillcolor="#1a1a3a" shape=box]
|
handover [label="Handover Agent\n(ops)" fillcolor="#1a1a3a" shape=box]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared server
|
// Shared server
|
||||||
subgraph cluster_shared {
|
subgraph cluster_shared {
|
||||||
label="united-ops-shared"
|
label="stellar-ops-shared"
|
||||||
color="#0066ff"
|
color="#0066ff"
|
||||||
fontcolor="#0066ff"
|
fontcolor="#0066ff"
|
||||||
style=rounded
|
style=rounded
|
||||||
|
|
||||||
subgraph cluster_shared_tools {
|
st [label="Tools\nget_flight_status\nget_flight_details\nget_irregular_ops\nget_route_weather ★\nget_hub_forecasts ★\nget_airport_status ★\nget_airport_congestion\nget_maintenance_flags" fillcolor="#0d1a33" shape=box fontsize=9]
|
||||||
label="Tools"
|
sr [label="Resources\nops://hubs/\u007Bcode\u007D\nops://scenarios/active" fillcolor="#1a1a2a" shape=note fontsize=9]
|
||||||
color="#1e2a4a"
|
sp [label="Prompts\ndelay_explainer" fillcolor="#2a1a2a" shape=cds fontsize=9]
|
||||||
fontcolor="#4a5568"
|
|
||||||
st1 [label="get_flight_status" fillcolor="#0d1a33" shape=box]
|
|
||||||
st2 [label="get_flight_details" fillcolor="#0d1a33" shape=box]
|
|
||||||
st3 [label="get_irregular_ops" fillcolor="#0d1a33" shape=box]
|
|
||||||
st4 [label="get_route_weather\n★ LIVE" fillcolor="#0d2a0d" shape=box fontcolor="#00c853"]
|
|
||||||
st5 [label="get_hub_forecasts\n★ LIVE" fillcolor="#0d2a0d" shape=box fontcolor="#00c853"]
|
|
||||||
st6 [label="get_airport_status\n★ LIVE" fillcolor="#0d2a0d" shape=box fontcolor="#00c853"]
|
|
||||||
st7 [label="get_airport_congestion\n★ HYBRID" fillcolor="#0d2a0d" shape=box fontcolor="#ffc107"]
|
|
||||||
st8 [label="get_maintenance_flags" fillcolor="#0d1a33" shape=box]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_shared_res {
|
|
||||||
label="Resources"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
sr1 [label="ops://hubs/{code}" fillcolor="#1a1a2a" shape=note]
|
|
||||||
sr2 [label="ops://scenarios/active" fillcolor="#1a1a2a" shape=note]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_shared_prompts {
|
|
||||||
label="Prompts"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
sp1 [label="delay_explainer\n(cause_code, audience)" fillcolor="#2a1a2a" shape=cds]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ops server
|
// Ops server
|
||||||
subgraph cluster_ops {
|
subgraph cluster_ops {
|
||||||
label="united-ops-internal"
|
label="stellar-ops-internal"
|
||||||
color="#ff3d00"
|
color="#ff3d00"
|
||||||
fontcolor="#ff3d00"
|
fontcolor="#ff3d00"
|
||||||
style=rounded
|
style=rounded
|
||||||
|
|
||||||
subgraph cluster_ops_tools {
|
ot [label="Tools\nget_crew_notes\nget_crew_duty_status\nget_pending_rebookings\ngenerate_narrative" fillcolor="#0d1a33" shape=box fontsize=9]
|
||||||
label="Tools"
|
or [label="Resources\nops://crew/roster\nops://handover/latest" fillcolor="#1a1a2a" shape=note fontsize=9]
|
||||||
color="#1e2a4a"
|
op [label="Prompts\nhandover_brief" fillcolor="#2a1a2a" shape=cds fontsize=9]
|
||||||
fontcolor="#4a5568"
|
|
||||||
ot1 [label="get_crew_notes" fillcolor="#0d1a33" shape=box]
|
|
||||||
ot2 [label="get_crew_duty_status" fillcolor="#0d1a33" shape=box]
|
|
||||||
ot3 [label="get_pending_rebookings" fillcolor="#0d1a33" shape=box]
|
|
||||||
ot4 [label="generate_narrative" fillcolor="#0d1a33" shape=box]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_ops_res {
|
|
||||||
label="Resources"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
or1 [label="ops://crew/roster" fillcolor="#1a1a2a" shape=note]
|
|
||||||
or2 [label="ops://handover/latest" fillcolor="#1a1a2a" shape=note]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_ops_prompts {
|
|
||||||
label="Prompts"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
op1 [label="handover_brief\n(hub, shift_time)" fillcolor="#2a1a2a" shape=cds]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passenger server
|
// Passenger server
|
||||||
subgraph cluster_pax {
|
subgraph cluster_pax {
|
||||||
label="united-ops-passenger"
|
label="stellar-ops-passenger"
|
||||||
color="#00c853"
|
color="#00c853"
|
||||||
fontcolor="#00c853"
|
fontcolor="#00c853"
|
||||||
style=rounded
|
style=rounded
|
||||||
|
|
||||||
subgraph cluster_pax_tools {
|
pt [label="Tools\ngenerate_notification" fillcolor="#0d1a33" shape=box fontsize=9]
|
||||||
label="Tools"
|
pr [label="Resources\nops://flights/\u007Bid\u007D/manifest" fillcolor="#1a1a2a" shape=note fontsize=9]
|
||||||
color="#1e2a4a"
|
pp [label="Prompts\npassenger_notification" fillcolor="#2a1a2a" shape=cds fontsize=9]
|
||||||
fontcolor="#4a5568"
|
|
||||||
pt1 [label="generate_notification" fillcolor="#0d1a33" shape=box]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_pax_res {
|
|
||||||
label="Resources"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
pr1 [label="ops://flights/{id}/manifest" fillcolor="#1a1a2a" shape=note]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_pax_prompts {
|
|
||||||
label="Prompts"
|
|
||||||
color="#1e2a4a"
|
|
||||||
fontcolor="#4a5568"
|
|
||||||
pp1 [label="passenger_notification\n(tone)" fillcolor="#2a1a2a" shape=cds]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connections
|
// Tool calls (solid)
|
||||||
efhas -> st1 [color="#0066ff"]
|
fce -> st [color="#0066ff"]
|
||||||
efhas -> st2 [color="#0066ff"]
|
fce -> pt [color="#00c853"]
|
||||||
efhas -> st4 [color="#0066ff"]
|
handover -> st [color="#0066ff"]
|
||||||
efhas -> st6 [color="#0066ff"]
|
handover -> ot [color="#ff3d00"]
|
||||||
efhas -> st7 [color="#0066ff"]
|
|
||||||
efhas -> st8 [color="#0066ff"]
|
|
||||||
efhas -> pt1 [color="#00c853"]
|
|
||||||
efhas -> sr1 [color="#0066ff" style=dashed]
|
|
||||||
efhas -> pp1 [color="#00c853" style=dotted]
|
|
||||||
|
|
||||||
handover -> st3 [color="#0066ff"]
|
// Resource reads (dashed)
|
||||||
handover -> st5 [color="#0066ff"]
|
fce -> sr [color="#0066ff" style=dashed]
|
||||||
handover -> st6 [color="#0066ff"]
|
fce -> pr [color="#00c853" style=dashed]
|
||||||
handover -> st8 [color="#0066ff"]
|
handover -> or [color="#ff3d00" style=dashed]
|
||||||
handover -> ot1 [color="#ff3d00"]
|
|
||||||
handover -> ot2 [color="#ff3d00"]
|
// Prompt gets (dotted)
|
||||||
handover -> ot3 [color="#ff3d00"]
|
fce -> pp [color="#00c853" style=dotted]
|
||||||
handover -> ot4 [color="#ff3d00"]
|
handover -> op [color="#ff3d00" style=dotted]
|
||||||
handover -> or1 [color="#ff3d00" style=dashed]
|
handover -> sp [color="#0066ff" style=dotted]
|
||||||
handover -> or2 [color="#ff3d00" style=dashed]
|
|
||||||
handover -> op1 [color="#ff3d00" style=dotted]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,353 +4,186 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: mcp_servers Pages: 1 -->
|
<!-- Title: mcp_servers Pages: 1 -->
|
||||||
<svg width="381pt" height="1577pt"
|
<svg style="background:#0a0e17" width="708pt" height="1469pt"
|
||||||
viewBox="0.00 0.00 381.00 1577.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 708.00 1469.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1573.25)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 730.25)">
|
||||||
<title>mcp_servers</title>
|
<title>mcp_servers</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-1573.25 377,-1573.25 377,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-730.25 350,-730.25 350,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="186.5" y="-1551.95" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">MCP Server Topology — Tools · Resources · Prompts</text>
|
<text xml:space="preserve" text-anchor="middle" x="173" y="-708.95" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">MCP Server Topology</text>
|
||||||
<g id="clust1" class="cluster">
|
<g id="clust1" class="cluster">
|
||||||
<title>cluster_clients</title>
|
<title>cluster_clients</title>
|
||||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="34.62,-851 34.62,-982 143.62,-982 143.62,-851 34.62,-851"/>
|
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="8,-262 8,-393 118.75,-393 118.75,-262 8,-262"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="89.12" y="-964.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8892a8">Agent Clients</text>
|
<text xml:space="preserve" text-anchor="middle" x="63.38" y="-375.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8892a8">Agent Clients</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="clust2" class="cluster">
|
<g id="clust2" class="cluster">
|
||||||
<title>cluster_shared</title>
|
<title>cluster_shared</title>
|
||||||
<path fill="#0a0e17" stroke="#0066ff" d="M173.62,-816C173.62,-816 312.38,-816 312.38,-816 318.38,-816 324.38,-822 324.38,-828 324.38,-828 324.38,-1524 324.38,-1524 324.38,-1530 318.38,-1536 312.38,-1536 312.38,-1536 173.62,-1536 173.62,-1536 167.62,-1536 161.62,-1530 161.62,-1524 161.62,-1524 161.62,-828 161.62,-828 161.62,-822 167.62,-816 173.62,-816"/>
|
<path fill="#0a0e17" stroke="#0066ff" d="M168,-428C168,-428 308.75,-428 308.75,-428 314.75,-428 320.75,-434 320.75,-440 320.75,-440 320.75,-681 320.75,-681 320.75,-687 314.75,-693 308.75,-693 308.75,-693 168,-693 168,-693 162,-693 156,-687 156,-681 156,-681 156,-440 156,-440 156,-434 162,-428 168,-428"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1518.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">united-ops-shared</text>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-675.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">stellar-ops-shared</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="clust3" class="cluster">
|
<g id="clust3" class="cluster">
|
||||||
<title>cluster_shared_tools</title>
|
<title>cluster_ops</title>
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M182.38,-824C182.38,-824 303.62,-824 303.62,-824 309.62,-824 315.62,-830 315.62,-836 315.62,-836 315.62,-1267 315.62,-1267 315.62,-1273 309.62,-1279 303.62,-1279 303.62,-1279 182.38,-1279 182.38,-1279 176.38,-1279 170.38,-1273 170.38,-1267 170.38,-1267 170.38,-836 170.38,-836 170.38,-830 176.38,-824 182.38,-824"/>
|
<path fill="#0a0e17" stroke="#ff3d00" d="M178.38,-8C178.38,-8 299.38,-8 299.38,-8 305.38,-8 311.38,-14 311.38,-20 311.38,-20 311.38,-215 311.38,-215 311.38,-221 305.38,-227 299.38,-227 299.38,-227 178.38,-227 178.38,-227 172.38,-227 166.38,-221 166.38,-215 166.38,-215 166.38,-20 166.38,-20 166.38,-14 172.38,-8 178.38,-8"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1261.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Tools</text>
|
<text xml:space="preserve" text-anchor="middle" x="238.88" y="-209.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#ff3d00">stellar-ops-internal</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="clust4" class="cluster">
|
<g id="clust4" class="cluster">
|
||||||
<title>cluster_shared_res</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M186.12,-1287C186.12,-1287 299.88,-1287 299.88,-1287 305.88,-1287 311.88,-1293 311.88,-1299 311.88,-1299 311.88,-1406 311.88,-1406 311.88,-1412 305.88,-1418 299.88,-1418 299.88,-1418 186.12,-1418 186.12,-1418 180.12,-1418 174.12,-1412 174.12,-1406 174.12,-1406 174.12,-1299 174.12,-1299 174.12,-1293 180.12,-1287 186.12,-1287"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1400.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Resources</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust5" class="cluster">
|
|
||||||
<title>cluster_shared_prompts</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M181.62,-1426C181.62,-1426 304.38,-1426 304.38,-1426 310.38,-1426 316.38,-1432 316.38,-1438 316.38,-1438 316.38,-1491 316.38,-1491 316.38,-1497 310.38,-1503 304.38,-1503 304.38,-1503 181.62,-1503 181.62,-1503 175.62,-1503 169.62,-1497 169.62,-1491 169.62,-1491 169.62,-1438 169.62,-1438 169.62,-1432 175.62,-1426 181.62,-1426"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1485.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Prompts</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust6" class="cluster">
|
|
||||||
<title>cluster_ops</title>
|
|
||||||
<path fill="#0a0e17" stroke="#ff3d00" d="M171.38,-8C171.38,-8 314.62,-8 314.62,-8 320.62,-8 326.62,-14 326.62,-20 326.62,-20 326.62,-500 326.62,-500 326.62,-506 320.62,-512 314.62,-512 314.62,-512 171.38,-512 171.38,-512 165.38,-512 159.38,-506 159.38,-500 159.38,-500 159.38,-20 159.38,-20 159.38,-14 165.38,-8 171.38,-8"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-494.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#ff3d00">united-ops-internal</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust7" class="cluster">
|
|
||||||
<title>cluster_ops_tools</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M179.38,-16C179.38,-16 306.62,-16 306.62,-16 312.62,-16 318.62,-22 318.62,-28 318.62,-28 318.62,-243 318.62,-243 318.62,-249 312.62,-255 306.62,-255 306.62,-255 179.38,-255 179.38,-255 173.38,-255 167.38,-249 167.38,-243 167.38,-243 167.38,-28 167.38,-28 167.38,-22 173.38,-16 179.38,-16"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-237.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Tools</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust8" class="cluster">
|
|
||||||
<title>cluster_ops_res</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M187.62,-263C187.62,-263 298.38,-263 298.38,-263 304.38,-263 310.38,-269 310.38,-275 310.38,-275 310.38,-382 310.38,-382 310.38,-388 304.38,-394 298.38,-394 298.38,-394 187.62,-394 187.62,-394 181.62,-394 175.62,-388 175.62,-382 175.62,-382 175.62,-275 175.62,-275 175.62,-269 181.62,-263 187.62,-263"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-376.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Resources</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust9" class="cluster">
|
|
||||||
<title>cluster_ops_prompts</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M198.88,-402C198.88,-402 287.12,-402 287.12,-402 293.12,-402 299.12,-408 299.12,-414 299.12,-414 299.12,-467 299.12,-467 299.12,-473 293.12,-479 287.12,-479 287.12,-479 198.88,-479 198.88,-479 192.88,-479 186.88,-473 186.88,-467 186.88,-467 186.88,-414 186.88,-414 186.88,-408 192.88,-402 198.88,-402"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-461.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Prompts</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust10" class="cluster">
|
|
||||||
<title>cluster_pax</title>
|
<title>cluster_pax</title>
|
||||||
<path fill="#0a0e17" stroke="#00c853" d="M167.62,-520C167.62,-520 318.38,-520 318.38,-520 324.38,-520 330.38,-526 330.38,-532 330.38,-532 330.38,-796 330.38,-796 330.38,-802 324.38,-808 318.38,-808 318.38,-808 167.62,-808 167.62,-808 161.62,-808 155.62,-802 155.62,-796 155.62,-796 155.62,-532 155.62,-532 155.62,-526 161.62,-520 167.62,-520"/>
|
<path fill="#0a0e17" stroke="#00c853" d="M150.75,-235C150.75,-235 326,-235 326,-235 332,-235 338,-241 338,-247 338,-247 338,-408 338,-408 338,-414 332,-420 326,-420 326,-420 150.75,-420 150.75,-420 144.75,-420 138.75,-414 138.75,-408 138.75,-408 138.75,-247 138.75,-247 138.75,-241 144.75,-235 150.75,-235"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-790.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#00c853">united-ops-passenger</text>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-402.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#00c853">stellar-ops-passenger</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="clust11" class="cluster">
|
<!-- fce -->
|
||||||
<title>cluster_pax_tools</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M187.25,-528C187.25,-528 298.75,-528 298.75,-528 304.75,-528 310.75,-534 310.75,-540 310.75,-540 310.75,-593 310.75,-593 310.75,-599 304.75,-605 298.75,-605 298.75,-605 187.25,-605 187.25,-605 181.25,-605 175.25,-599 175.25,-593 175.25,-593 175.25,-540 175.25,-540 175.25,-534 181.25,-528 187.25,-528"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-587.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Tools</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust12" class="cluster">
|
|
||||||
<title>cluster_pax_res</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M175.62,-613C175.62,-613 310.38,-613 310.38,-613 316.38,-613 322.38,-619 322.38,-625 322.38,-625 322.38,-678 322.38,-678 322.38,-684 316.38,-690 310.38,-690 310.38,-690 175.62,-690 175.62,-690 169.62,-690 163.62,-684 163.62,-678 163.62,-678 163.62,-625 163.62,-625 163.62,-619 169.62,-613 175.62,-613"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-672.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Resources</text>
|
|
||||||
</g>
|
|
||||||
<g id="clust13" class="cluster">
|
|
||||||
<title>cluster_pax_prompts</title>
|
|
||||||
<path fill="#0a0e17" stroke="#1e2a4a" d="M183.88,-698C183.88,-698 302.12,-698 302.12,-698 308.12,-698 314.12,-704 314.12,-710 314.12,-710 314.12,-763 314.12,-763 314.12,-769 308.12,-775 302.12,-775 302.12,-775 183.88,-775 183.88,-775 177.88,-775 171.88,-769 171.88,-763 171.88,-763 171.88,-710 171.88,-710 171.88,-704 177.88,-698 183.88,-698"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-757.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#4a5568">Prompts</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas -->
|
|
||||||
<g id="node1" class="node">
|
<g id="node1" class="node">
|
||||||
<title>efhas</title>
|
<title>fce</title>
|
||||||
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="115.62,-949 61.62,-949 61.62,-913 115.62,-913 115.62,-949"/>
|
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="100.25,-360 26.5,-360 26.5,-324 100.25,-324 100.25,-360"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="88.62" y="-934.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">FCE</text>
|
<text xml:space="preserve" text-anchor="middle" x="63.38" y="-345.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">FCE Agent</text>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="88.62" y="-921.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">Agent</text>
|
<text xml:space="preserve" text-anchor="middle" x="63.38" y="-332.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">(passenger)</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- st1 -->
|
<!-- st -->
|
||||||
<g id="node3" class="node">
|
<g id="node3" class="node">
|
||||||
<title>st1</title>
|
<title>st</title>
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="291.5,-1192 194.5,-1192 194.5,-1156 291.5,-1156 291.5,-1192"/>
|
<polygon fill="#0d1a33" stroke="#1e2a4a" points="298.88,-599.62 177.88,-599.62 177.88,-490.38 298.88,-490.38 298.88,-599.62"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1170.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_flight_status</text>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-587.08" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Tools</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-575.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_flight_status</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-564.58" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_flight_details</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-553.33" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_irregular_ops</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-542.08" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_route_weather ★</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-530.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_hub_forecasts ★</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-519.58" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_airport_status ★</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-508.32" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_airport_congestion</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-497.07" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_maintenance_flags</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- efhas->st1 -->
|
<!-- fce->st -->
|
||||||
<g id="edge1" class="edge">
|
<g id="edge1" class="edge">
|
||||||
<title>efhas->st1</title>
|
<title>fce->st</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M89.78,-949.5C91.16,-990.83 100.35,-1091.37 155.62,-1147 163.27,-1154.69 173.07,-1160.2 183.31,-1164.14"/>
|
<path fill="none" stroke="#0066ff" d="M70.8,-360.47C81.42,-388.94 104.86,-444.12 138.75,-481 147.35,-490.36 157.6,-498.95 168.19,-506.59"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="182.04,-1167.41 192.63,-1167.23 184.24,-1160.76 182.04,-1167.41"/>
|
<polygon fill="#0066ff" stroke="#0066ff" points="166.09,-509.4 176.3,-512.2 170.07,-503.64 166.09,-509.4"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- st2 -->
|
<!-- sr -->
|
||||||
<g id="node4" class="node">
|
<g id="node4" class="node">
|
||||||
<title>st2</title>
|
<title>sr</title>
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="293,-1246 193,-1246 193,-1210 293,-1210 293,-1246"/>
|
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="306.75,-659.88 164,-659.88 164,-618.12 312.75,-618.12 312.75,-653.88 306.75,-659.88"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1224.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_flight_details</text>
|
<polyline fill="none" stroke="#1e2a4a" points="306.75,-659.88 306.75,-653.88"/>
|
||||||
|
<polyline fill="none" stroke="#1e2a4a" points="312.75,-653.88 306.75,-653.88"/>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-647.33" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Resources</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-636.08" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">ops://hubs/u007Bcodeu007D</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-624.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">ops://scenarios/active</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- efhas->st2 -->
|
<!-- fce->sr -->
|
||||||
<g id="edge2" class="edge">
|
|
||||||
<title>efhas->st2</title>
|
|
||||||
<path fill="none" stroke="#0066ff" d="M91.75,-949.27C98.43,-1003.77 120.7,-1163.79 155.62,-1201 162.81,-1208.66 172.13,-1214.15 181.98,-1218.1"/>
|
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="180.78,-1221.39 191.37,-1221.31 183.04,-1214.76 180.78,-1221.39"/>
|
|
||||||
</g>
|
|
||||||
<!-- st4 -->
|
|
||||||
<g id="node6" class="node">
|
|
||||||
<title>st4</title>
|
|
||||||
<polygon fill="#0d2a0d" stroke="#1e2a4a" points="296.75,-1084 189.25,-1084 189.25,-1048 296.75,-1048 296.75,-1084"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1069.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">get_route_weather</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1056.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">★ LIVE</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas->st4 -->
|
|
||||||
<g id="edge3" class="edge">
|
|
||||||
<title>efhas->st4</title>
|
|
||||||
<path fill="none" stroke="#0066ff" d="M96.16,-949.49C105.6,-973.56 125.31,-1015.34 155.62,-1039 162.34,-1044.24 170.09,-1048.47 178.13,-1051.89"/>
|
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="176.8,-1055.13 187.39,-1055.39 179.28,-1048.58 176.8,-1055.13"/>
|
|
||||||
</g>
|
|
||||||
<!-- st6 -->
|
|
||||||
<g id="node8" class="node">
|
|
||||||
<title>st6</title>
|
|
||||||
<polygon fill="#0d2a0d" stroke="#1e2a4a" points="295.25,-976 190.75,-976 190.75,-940 295.25,-940 295.25,-976"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-961.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">get_airport_status</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-948.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">★ LIVE</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas->st6 -->
|
|
||||||
<g id="edge4" class="edge">
|
|
||||||
<title>efhas->st6</title>
|
|
||||||
<path fill="none" stroke="#0066ff" d="M115.82,-935.64C133.29,-938.74 157.04,-942.95 179.22,-946.88"/>
|
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="178.35,-950.28 188.8,-948.57 179.57,-943.38 178.35,-950.28"/>
|
|
||||||
</g>
|
|
||||||
<!-- st7 -->
|
|
||||||
<g id="node9" class="node">
|
|
||||||
<title>st7</title>
|
|
||||||
<polygon fill="#0d2a0d" stroke="#1e2a4a" points="306.88,-1138 179.12,-1138 179.12,-1102 306.88,-1102 306.88,-1138"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1123.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#ffc107">get_airport_congestion</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1110.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#ffc107">★ HYBRID</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas->st7 -->
|
|
||||||
<g id="edge5" class="edge">
|
<g id="edge5" class="edge">
|
||||||
<title>efhas->st7</title>
|
<title>fce->sr</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M91.97,-949.44C97.2,-982.89 112.92,-1053.74 155.62,-1093 159.61,-1096.66 164.08,-1099.83 168.84,-1102.56"/>
|
<path fill="none" stroke="#0066ff" stroke-dasharray="5,2" d="M63.85,-360.46C63.54,-408.41 69.49,-538.09 138.75,-609 143.13,-613.48 148.15,-617.3 153.56,-620.55"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="167.09,-1105.6 177.6,-1106.92 170.21,-1099.33 167.09,-1105.6"/>
|
<polygon fill="#0066ff" stroke="#0066ff" points="151.84,-623.6 162.32,-625.11 155.07,-617.39 151.84,-623.6"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- st8 -->
|
<!-- pt -->
|
||||||
|
<g id="node9" class="node">
|
||||||
|
<title>pt</title>
|
||||||
|
<polygon fill="#0d1a33" stroke="#1e2a4a" points="294.38,-279 182.38,-279 182.38,-243 294.38,-243 294.38,-279"/>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-263.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Tools</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-252.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">generate_notification</text>
|
||||||
|
</g>
|
||||||
|
<!-- fce->pt -->
|
||||||
|
<g id="edge2" class="edge">
|
||||||
|
<title>fce->pt</title>
|
||||||
|
<path fill="none" stroke="#00c853" d="M100.67,-326.99C107.03,-323.54 113.34,-319.53 118.75,-315 130.2,-305.41 126.43,-296.44 138.75,-288 148.46,-281.35 159.76,-276.34 171.17,-272.55"/>
|
||||||
|
<polygon fill="#00c853" stroke="#00c853" points="172.07,-275.94 180.65,-269.72 170.07,-269.23 172.07,-275.94"/>
|
||||||
|
</g>
|
||||||
|
<!-- pr -->
|
||||||
<g id="node10" class="node">
|
<g id="node10" class="node">
|
||||||
<title>st8</title>
|
<title>pr</title>
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="307.62,-1030 178.38,-1030 178.38,-994 307.62,-994 307.62,-1030"/>
|
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="324,-333 146.75,-333 146.75,-297 330,-297 330,-327 324,-333"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1008.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_maintenance_flags</text>
|
<polyline fill="none" stroke="#1e2a4a" points="324,-333 324,-327"/>
|
||||||
|
<polyline fill="none" stroke="#1e2a4a" points="330,-327 324,-327"/>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-317.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Resources</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-306.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">ops://flights/u007Bidu007D/manifest</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- efhas->st8 -->
|
<!-- fce->pr -->
|
||||||
<g id="edge6" class="edge">
|
<g id="edge6" class="edge">
|
||||||
<title>efhas->st8</title>
|
<title>fce->pr</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M108.13,-949.43C120.64,-961.02 138.03,-975.52 155.62,-985 159.48,-987.08 163.52,-989.03 167.67,-990.84"/>
|
<path fill="none" stroke="#00c853" stroke-dasharray="5,2" d="M100.64,-336.34C110.96,-334.73 122.73,-332.89 134.95,-330.99"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="166.13,-994 176.71,-994.53 168.77,-987.51 166.13,-994"/>
|
<polygon fill="#00c853" stroke="#00c853" points="135.42,-334.45 144.76,-329.45 134.34,-327.54 135.42,-334.45"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- sr1 -->
|
<!-- pp -->
|
||||||
<g id="node11" class="node">
|
<g id="node11" class="node">
|
||||||
<title>sr1</title>
|
<title>pp</title>
|
||||||
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="288.88,-1331 191.12,-1331 191.12,-1295 294.88,-1295 294.88,-1325 288.88,-1331"/>
|
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="285.38,-381 179.38,-381 179.38,-357 285.38,-357 297.38,-369 285.38,-381"/>
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="288.88,-1331 288.88,-1325"/>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-371.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Prompts</text>
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="294.88,-1325 288.88,-1325"/>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-360.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">passenger_notification</text>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1309.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">ops://hubs/{code}</text>
|
|
||||||
</g>
|
</g>
|
||||||
<!-- efhas->sr1 -->
|
<!-- fce->pp -->
|
||||||
<g id="edge8" class="edge">
|
<g id="edge8" class="edge">
|
||||||
<title>efhas->sr1</title>
|
<title>fce->pp</title>
|
||||||
<path fill="none" stroke="#0066ff" stroke-dasharray="5,2" d="M90.69,-949.46C94.79,-1014.51 111.6,-1231.88 155.62,-1283 162.32,-1290.77 171.14,-1296.53 180.58,-1300.8"/>
|
<path fill="none" stroke="#00c853" stroke-dasharray="1,5" d="M100.64,-347.66C120.14,-350.7 144.85,-354.56 167.89,-358.15"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="179.01,-1303.95 189.59,-1304.32 181.55,-1297.42 179.01,-1303.95"/>
|
<polygon fill="#00c853" stroke="#00c853" points="167.11,-361.58 177.53,-359.66 168.19,-354.66 167.11,-361.58"/>
|
||||||
</g>
|
|
||||||
<!-- pt1 -->
|
|
||||||
<g id="node21" class="node">
|
|
||||||
<title>pt1</title>
|
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="302.75,-572 183.25,-572 183.25,-536 302.75,-536 302.75,-572"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-550.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">generate_notification</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas->pt1 -->
|
|
||||||
<g id="edge7" class="edge">
|
|
||||||
<title>efhas->pt1</title>
|
|
||||||
<path fill="none" stroke="#00c853" d="M115.89,-924.23C126.32,-920.14 137.31,-913.77 143.62,-904 161.44,-876.45 139.26,-637.43 155.62,-609 162.83,-596.48 174.17,-586.36 186.29,-578.39"/>
|
|
||||||
<polygon fill="#00c853" stroke="#00c853" points="188.07,-581.4 194.81,-573.23 184.45,-575.41 188.07,-581.4"/>
|
|
||||||
</g>
|
|
||||||
<!-- pp1 -->
|
|
||||||
<g id="node23" class="node">
|
|
||||||
<title>pp1</title>
|
|
||||||
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="294.12,-736 179.88,-736 179.88,-712 294.12,-712 306.12,-724 294.12,-736"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-727.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">passenger_notification</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-714.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">(tone)</text>
|
|
||||||
</g>
|
|
||||||
<!-- efhas->pp1 -->
|
|
||||||
<g id="edge9" class="edge">
|
|
||||||
<title>efhas->pp1</title>
|
|
||||||
<path fill="none" stroke="#00c853" stroke-dasharray="1,5" d="M115.98,-923.68C126.16,-919.54 136.94,-913.27 143.62,-904 165.68,-873.41 139.65,-854.16 155.62,-820 168.39,-792.7 191.56,-767.6 210.69,-749.92"/>
|
|
||||||
<polygon fill="#00c853" stroke="#00c853" points="212.91,-752.63 218.02,-743.35 208.24,-747.42 212.91,-752.63"/>
|
|
||||||
</g>
|
</g>
|
||||||
<!-- handover -->
|
<!-- handover -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
<title>handover</title>
|
<title>handover</title>
|
||||||
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="120.25,-895 57,-895 57,-859 120.25,-859 120.25,-895"/>
|
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="110.75,-306 16,-306 16,-270 110.75,-270 110.75,-306"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="88.62" y="-880.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">Handover</text>
|
<text xml:space="preserve" text-anchor="middle" x="63.38" y="-291.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">Handover Agent</text>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="88.62" y="-867.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">Agent</text>
|
<text xml:space="preserve" text-anchor="middle" x="63.38" y="-278.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">(ops)</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- st3 -->
|
<!-- handover->st -->
|
||||||
|
<g id="edge3" class="edge">
|
||||||
|
<title>handover->st</title>
|
||||||
|
<path fill="none" stroke="#0066ff" d="M110.49,-306.27C113.62,-308.83 116.44,-311.73 118.75,-315 161.62,-375.7 99.43,-417.94 138.75,-481 146.16,-492.89 156.69,-503.01 168.13,-511.44"/>
|
||||||
|
<polygon fill="#0066ff" stroke="#0066ff" points="165.99,-514.22 176.22,-517 169.96,-508.45 165.99,-514.22"/>
|
||||||
|
</g>
|
||||||
|
<!-- sp -->
|
||||||
<g id="node5" class="node">
|
<g id="node5" class="node">
|
||||||
<title>st3</title>
|
<title>sp</title>
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="293.38,-922 192.62,-922 192.62,-886 293.38,-886 293.38,-922"/>
|
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="269.25,-466 195.5,-466 195.5,-442 269.25,-442 281.25,-454 269.25,-466"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-900.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_irregular_ops</text>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-456.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Prompts</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-445.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">delay_explainer</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- handover->st3 -->
|
<!-- handover->sp -->
|
||||||
<g id="edge10" class="edge">
|
<g id="edge10" class="edge">
|
||||||
<title>handover->st3</title>
|
<title>handover->sp</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M120.46,-882.46C137.93,-885.56 160.4,-889.54 181.26,-893.24"/>
|
<path fill="none" stroke="#0066ff" stroke-dasharray="1,5" d="M110.27,-306.43C113.45,-308.96 116.34,-311.8 118.75,-315 148.39,-354.34 105.96,-387.25 138.75,-424 150.38,-437.04 167.48,-444.49 184.19,-448.73"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="180.37,-896.63 190.82,-894.93 181.59,-889.74 180.37,-896.63"/>
|
<polygon fill="#0066ff" stroke="#0066ff" points="183.06,-452.07 193.57,-450.75 184.54,-445.22 183.06,-452.07"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- st5 -->
|
<!-- ot -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>ot</title>
|
||||||
|
<polygon fill="#0d1a33" stroke="#1e2a4a" points="301.88,-80.12 174.88,-80.12 174.88,-15.88 301.88,-15.88 301.88,-80.12"/>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-67.58" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Tools</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-56.33" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_crew_notes</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-45.08" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_crew_duty_status</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-33.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">get_pending_rebookings</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-22.57" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">generate_narrative</text>
|
||||||
|
</g>
|
||||||
|
<!-- handover->ot -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>handover->ot</title>
|
||||||
|
<path fill="none" stroke="#ff3d00" d="M66.33,-269.79C71.37,-231.41 88.19,-141.43 138.75,-89 145.98,-81.5 154.79,-75.32 164.13,-70.24"/>
|
||||||
|
<polygon fill="#ff3d00" stroke="#ff3d00" points="165.66,-73.39 173.07,-65.81 162.56,-67.11 165.66,-73.39"/>
|
||||||
|
</g>
|
||||||
|
<!-- or -->
|
||||||
<g id="node7" class="node">
|
<g id="node7" class="node">
|
||||||
<title>st5</title>
|
<title>or</title>
|
||||||
<polygon fill="#0d2a0d" stroke="#1e2a4a" points="295.62,-868 190.38,-868 190.38,-832 295.62,-832 295.62,-868"/>
|
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="288,-139.88 182.75,-139.88 182.75,-98.12 294,-98.12 294,-133.88 288,-139.88"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-853.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">get_hub_forecasts</text>
|
<polyline fill="none" stroke="#1e2a4a" points="288,-139.88 288,-133.88"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-840.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#00c853">★ LIVE</text>
|
<polyline fill="none" stroke="#1e2a4a" points="294,-133.88 288,-133.88"/>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-127.33" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Resources</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-116.08" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">ops://crew/roster</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-104.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">ops://handover/latest</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- handover->st5 -->
|
<!-- handover->or -->
|
||||||
<g id="edge11" class="edge">
|
<g id="edge7" class="edge">
|
||||||
<title>handover->st5</title>
|
<title>handover->or</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M120.46,-871.54C137.19,-868.57 158.49,-864.8 178.58,-861.24"/>
|
<path fill="none" stroke="#ff3d00" stroke-dasharray="5,2" d="M69.19,-269.75C77.97,-240.04 99.4,-181.3 138.75,-149 148.28,-141.17 159.83,-135.39 171.61,-131.11"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="179.18,-864.69 188.41,-859.5 177.96,-857.79 179.18,-864.69"/>
|
<polygon fill="#ff3d00" stroke="#ff3d00" points="172.58,-134.48 181.01,-128.06 170.42,-127.82 172.58,-134.48"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- handover->st6 -->
|
<!-- op -->
|
||||||
<g id="edge12" class="edge">
|
<g id="node8" class="node">
|
||||||
<title>handover->st6</title>
|
<title>op</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M120.64,-888.01C128.88,-892.06 137.25,-897.33 143.62,-904 152.7,-913.49 145.82,-922.26 155.62,-931 162.55,-937.17 170.87,-941.93 179.57,-945.6"/>
|
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="268.12,-188 196.62,-188 196.62,-164 268.12,-164 280.12,-176 268.12,-188"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="178.3,-948.86 188.9,-949.03 180.72,-942.29 178.3,-948.86"/>
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-178.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">Prompts</text>
|
||||||
|
<text xml:space="preserve" text-anchor="middle" x="238.38" y="-167.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#e8eaf0">handover_brief</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- handover->st8 -->
|
<!-- handover->op -->
|
||||||
<g id="edge13" class="edge">
|
<g id="edge9" class="edge">
|
||||||
<title>handover->st8</title>
|
<title>handover->op</title>
|
||||||
<path fill="none" stroke="#0066ff" d="M120.75,-886.43C129.4,-890.51 137.97,-896.19 143.62,-904 164.98,-933.47 131.97,-957.34 155.62,-985 159.2,-989.18 163.42,-992.73 168.03,-995.73"/>
|
<path fill="none" stroke="#ff3d00" stroke-dasharray="1,5" d="M86.54,-269.66C101.01,-258.03 120.53,-242.97 138.75,-231 155.6,-219.93 174.82,-208.88 191.79,-199.62"/>
|
||||||
<polygon fill="#0066ff" stroke="#0066ff" points="166.19,-998.71 176.65,-1000.43 169.55,-992.57 166.19,-998.71"/>
|
<polygon fill="#ff3d00" stroke="#ff3d00" points="193.02,-202.94 200.16,-195.11 189.7,-196.77 193.02,-202.94"/>
|
||||||
</g>
|
|
||||||
<!-- ot1 -->
|
|
||||||
<g id="node14" class="node">
|
|
||||||
<title>ot1</title>
|
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="289.25,-168 196.75,-168 196.75,-132 289.25,-132 289.25,-168"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-146.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_crew_notes</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->ot1 -->
|
|
||||||
<g id="edge14" class="edge">
|
|
||||||
<title>handover->ot1</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" d="M90.15,-858.84C93.34,-754.24 111.39,-231.6 155.62,-177 163.19,-167.66 173.96,-161.49 185.33,-157.43"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="186.3,-160.79 194.89,-154.58 184.3,-154.08 186.3,-160.79"/>
|
|
||||||
</g>
|
|
||||||
<!-- ot2 -->
|
|
||||||
<g id="node15" class="node">
|
|
||||||
<title>ot2</title>
|
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="304.25,-222 181.75,-222 181.75,-186 304.25,-186 304.25,-222"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-200.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_crew_duty_status</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->ot2 -->
|
|
||||||
<g id="edge15" class="edge">
|
|
||||||
<title>handover->ot2</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" d="M89.49,-858.71C89.11,-767.6 91.15,-362.97 155.62,-259 163.46,-246.36 175.41,-236.11 187.93,-228.03"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="189.48,-231.18 196.27,-223.05 185.89,-225.17 189.48,-231.18"/>
|
|
||||||
</g>
|
|
||||||
<!-- ot3 -->
|
|
||||||
<g id="node16" class="node">
|
|
||||||
<title>ot3</title>
|
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="310.62,-60 175.38,-60 175.38,-24 310.62,-24 310.62,-60"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-38.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">get_pending_rebookings</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->ot3 -->
|
|
||||||
<g id="edge16" class="edge">
|
|
||||||
<title>handover->ot3</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" d="M89.91,-858.71C91.86,-744.55 104.63,-132.75 155.62,-69 158.47,-65.44 161.78,-62.35 165.41,-59.65"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="167.04,-62.76 173.72,-54.53 163.37,-56.79 167.04,-62.76"/>
|
|
||||||
</g>
|
|
||||||
<!-- ot4 -->
|
|
||||||
<g id="node17" class="node">
|
|
||||||
<title>ot4</title>
|
|
||||||
<polygon fill="#0d1a33" stroke="#1e2a4a" points="297.5,-114 188.5,-114 188.5,-78 297.5,-78 297.5,-114"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-92.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">generate_narrative</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->ot4 -->
|
|
||||||
<g id="edge17" class="edge">
|
|
||||||
<title>handover->ot4</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" d="M90.03,-858.52C92.59,-748.47 108.05,-182.12 155.62,-123 161.44,-115.78 169.16,-110.45 177.6,-106.53"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="178.72,-109.85 186.77,-102.96 176.18,-103.33 178.72,-109.85"/>
|
|
||||||
</g>
|
|
||||||
<!-- or1 -->
|
|
||||||
<g id="node18" class="node">
|
|
||||||
<title>or1</title>
|
|
||||||
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="285.5,-307 194.5,-307 194.5,-271 291.5,-271 291.5,-301 285.5,-307"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="285.5,-307 285.5,-301"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="291.5,-301 285.5,-301"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-285.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">ops://crew/roster</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->or1 -->
|
|
||||||
<g id="edge18" class="edge">
|
|
||||||
<title>handover->or1</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" stroke-dasharray="5,2" d="M89.21,-858.63C87.59,-771.57 85.03,-401.1 155.62,-316 162.85,-307.29 172.84,-301.35 183.47,-297.3"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="184.34,-300.7 192.8,-294.31 182.21,-294.03 184.34,-300.7"/>
|
|
||||||
</g>
|
|
||||||
<!-- or2 -->
|
|
||||||
<g id="node19" class="node">
|
|
||||||
<title>or2</title>
|
|
||||||
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="296.38,-361 183.62,-361 183.62,-325 302.38,-325 302.38,-355 296.38,-361"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="296.38,-361 296.38,-355"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="302.38,-355 296.38,-355"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-339.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">ops://handover/latest</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->or2 -->
|
|
||||||
<g id="edge19" class="edge">
|
|
||||||
<title>handover->or2</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" stroke-dasharray="5,2" d="M90.13,-858.58C92.57,-780.41 105.2,-476.61 155.62,-398 163.66,-385.48 175.66,-375.27 188.19,-367.19"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="189.74,-370.35 196.52,-362.21 186.14,-364.34 189.74,-370.35"/>
|
|
||||||
</g>
|
|
||||||
<!-- op1 -->
|
|
||||||
<g id="node20" class="node">
|
|
||||||
<title>op1</title>
|
|
||||||
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="279.12,-440 194.88,-440 194.88,-416 279.12,-416 291.12,-428 279.12,-440"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-431.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">handover_brief</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-418.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">(hub, shift_time)</text>
|
|
||||||
</g>
|
|
||||||
<!-- handover->op1 -->
|
|
||||||
<g id="edge20" class="edge">
|
|
||||||
<title>handover->op1</title>
|
|
||||||
<path fill="none" stroke="#ff3d00" stroke-dasharray="1,5" d="M89.63,-858.66C90.34,-804.5 97.51,-641.67 155.62,-524 168.97,-496.98 192.11,-471.87 211.09,-454.11"/>
|
|
||||||
<polygon fill="#ff3d00" stroke="#ff3d00" points="213.3,-456.83 218.34,-447.51 208.59,-451.65 213.3,-456.83"/>
|
|
||||||
</g>
|
|
||||||
<!-- sr2 -->
|
|
||||||
<g id="node12" class="node">
|
|
||||||
<title>sr2</title>
|
|
||||||
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="297.88,-1385 182.12,-1385 182.12,-1349 303.88,-1349 303.88,-1379 297.88,-1385"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="297.88,-1385 297.88,-1379"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="303.88,-1379 297.88,-1379"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1363.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">ops://scenarios/active</text>
|
|
||||||
</g>
|
|
||||||
<!-- sp1 -->
|
|
||||||
<g id="node13" class="node">
|
|
||||||
<title>sp1</title>
|
|
||||||
<polygon fill="#2a1a2a" stroke="#1e2a4a" points="296.38,-1464 177.62,-1464 177.62,-1440 296.38,-1440 308.38,-1452 296.38,-1464"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1455.25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">delay_explainer</text>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-1442.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">(cause_code, audience)</text>
|
|
||||||
</g>
|
|
||||||
<!-- pr1 -->
|
|
||||||
<g id="node22" class="node">
|
|
||||||
<title>pr1</title>
|
|
||||||
<polygon fill="#1a1a2a" stroke="#1e2a4a" points="308.38,-657 171.62,-657 171.62,-621 314.38,-621 314.38,-651 308.38,-657"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="308.38,-657 308.38,-651"/>
|
|
||||||
<polyline fill="none" stroke="#1e2a4a" points="314.38,-651 308.38,-651"/>
|
|
||||||
<text xml:space="preserve" text-anchor="middle" x="243" y="-635.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">ops://flights/{id}/manifest</text>
|
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 14 KiB |
@@ -10,7 +10,7 @@ digraph repo_structure {
|
|||||||
fontsize=14
|
fontsize=14
|
||||||
fontcolor="#0066ff"
|
fontcolor="#0066ff"
|
||||||
|
|
||||||
root [label="united-ops/" fillcolor="#0066ff" fontcolor="white"]
|
root [label="stellar-ops/" fillcolor="#0066ff" fontcolor="white"]
|
||||||
|
|
||||||
mcp [label="mcp_servers/" fillcolor="#121829"]
|
mcp [label="mcp_servers/" fillcolor="#121829"]
|
||||||
agents [label="agents/" fillcolor="#121829"]
|
agents [label="agents/" fillcolor="#121829"]
|
||||||
@@ -27,7 +27,7 @@ digraph repo_structure {
|
|||||||
mcp_data [label="data/\nmodels.py\nreal/ (openmeteo, faa)\nmock/\nscenarios/ (4 scenarios)" fillcolor="#0d1a33" shape=box]
|
mcp_data [label="data/\nmodels.py\nreal/ (openmeteo, faa)\nmock/\nscenarios/ (4 scenarios)" fillcolor="#0d1a33" shape=box]
|
||||||
|
|
||||||
// Agents subtree
|
// Agents subtree
|
||||||
ag_efhas [label="efhas.py\nFCE agent" fillcolor="#1a1a3a" shape=box]
|
ag_efhas [label="fce.py\nFCE agent" fillcolor="#1a1a3a" shape=box]
|
||||||
ag_handover [label="handover.py\nHandover agent" fillcolor="#1a1a3a" shape=box]
|
ag_handover [label="handover.py\nHandover agent" fillcolor="#1a1a3a" shape=box]
|
||||||
ag_shared [label="shared/\nmcp_client.py\nllm.py" fillcolor="#1a1a3a" shape=box]
|
ag_shared [label="shared/\nmcp_client.py\nllm.py" fillcolor="#1a1a3a" shape=box]
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: repo_structure Pages: 1 -->
|
<!-- Title: repo_structure Pages: 1 -->
|
||||||
<svg width="2207pt" height="249pt"
|
<svg style="background:#0a0e17" width="4414pt" height="498pt"
|
||||||
viewBox="0.00 0.00 2207.00 249.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 4414.00 498.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 245)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 245)">
|
||||||
<title>repo_structure</title>
|
<title>repo_structure</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-245 2203,-245 2203,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-245 2203,-245 2203,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="1099.5" y="-223.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Repository Structure</text>
|
<text xml:space="preserve" text-anchor="middle" x="1099.5" y="-223.7" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#0066ff">Repository Structure</text>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<g id="node1" class="node">
|
<g id="node1" class="node">
|
||||||
<title>root</title>
|
<title>root</title>
|
||||||
<polygon fill="#0066ff" stroke="#1e2a4a" points="1454.75,-215.75 1451.75,-219.75 1430.75,-219.75 1427.75,-215.75 1384,-215.75 1384,-179.75 1454.75,-179.75 1454.75,-215.75"/>
|
<polygon fill="#0066ff" stroke="#1e2a4a" points="1454.75,-215.75 1451.75,-219.75 1430.75,-219.75 1427.75,-215.75 1384,-215.75 1384,-179.75 1454.75,-179.75 1454.75,-215.75"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="1419.38" y="-194.62" font-family="Helvetica,sans-Serif" font-size="10.00" fill="white">united-ops/</text>
|
<text xml:space="preserve" text-anchor="middle" x="1419.38" y="-194.62" font-family="Helvetica,sans-Serif" font-size="10.00" fill="white">stellar-ops/</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- mcp -->
|
<!-- mcp -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
<g id="node13" class="node">
|
<g id="node13" class="node">
|
||||||
<title>ag_efhas</title>
|
<title>ag_efhas</title>
|
||||||
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="698.12,-53.88 632.62,-53.88 632.62,-17.88 698.12,-17.88 698.12,-53.88"/>
|
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="698.12,-53.88 632.62,-53.88 632.62,-17.88 698.12,-17.88 698.12,-53.88"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="665.38" y="-39.12" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">efhas.py</text>
|
<text xml:space="preserve" text-anchor="middle" x="665.38" y="-39.12" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">fce.py</text>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="665.38" y="-26.38" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">FCE agent</text>
|
<text xml:space="preserve" text-anchor="middle" x="665.38" y="-26.38" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#e8eaf0">FCE agent</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- agents->ag_efhas -->
|
<!-- agents->ag_efhas -->
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@@ -4,9 +4,9 @@
|
|||||||
<!-- Generated by graphviz version 14.1.2 (0)
|
<!-- Generated by graphviz version 14.1.2 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: system_architecture Pages: 1 -->
|
<!-- Title: system_architecture Pages: 1 -->
|
||||||
<svg width="1298pt" height="662pt"
|
<svg style="background:#0a0e17" width="2596pt" height="1324pt"
|
||||||
viewBox="0.00 0.00 1298.00 662.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 2596.00 1324.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 657.85)">
|
<g id="graph0" class="graph" transform="scale(2 2) rotate(0) translate(4 657.85)">
|
||||||
<title>system_architecture</title>
|
<title>system_architecture</title>
|
||||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-657.85 1294,-657.85 1294,4 -4,4"/>
|
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-657.85 1294,-657.85 1294,4 -4,4"/>
|
||||||
<text xml:space="preserve" text-anchor="middle" x="645" y="-634.65" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">System Architecture</text>
|
<text xml:space="preserve" text-anchor="middle" x="645" y="-634.65" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">System Architecture</text>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -144,6 +144,30 @@
|
|||||||
.legend .mock::before { background: #ffc107; }
|
.legend .mock::before { background: #ffc107; }
|
||||||
.legend .mcp::before { background: #0066ff; }
|
.legend .mcp::before { background: #0066ff; }
|
||||||
.legend .ops::before { background: #ff3d00; }
|
.legend .ops::before { background: #ff3d00; }
|
||||||
|
|
||||||
|
.graph-container a { display: block; }
|
||||||
|
.graph-container img { max-width: 100%; height: auto; }
|
||||||
|
|
||||||
|
/* Repo tree */
|
||||||
|
.tree-container {
|
||||||
|
background: #0a0e17;
|
||||||
|
border: 1px solid #1e2a4a;
|
||||||
|
padding: 24px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.repo-tree {
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: #8892a8;
|
||||||
|
}
|
||||||
|
.t-root { color: #0066ff; font-weight: 600; font-size: 15px; }
|
||||||
|
.t-dir { color: #e8eaf0; font-weight: 500; }
|
||||||
|
.t-mcp { color: #0066ff; font-weight: 500; }
|
||||||
|
.t-ops { color: #ff3d00; font-weight: 500; }
|
||||||
|
.t-pax { color: #00c853; font-weight: 500; }
|
||||||
|
.t-live { color: #00c853; }
|
||||||
|
.t-comment { color: #4a5568; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -171,7 +195,7 @@
|
|||||||
<h2>SYSTEM ARCHITECTURE</h2>
|
<h2>SYSTEM ARCHITECTURE</h2>
|
||||||
<p>End-to-end view: Vue UI → Kong gateway → FastAPI → MCP servers → live and scenario data sources. Langfuse traces every agent run.</p>
|
<p>End-to-end view: Vue UI → Kong gateway → FastAPI → MCP servers → live and scenario data sources. Langfuse traces every agent run.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/system_architecture.svg" alt="System Architecture">
|
<a href="viewer.html?src=graphs/system_architecture.svg"><img src="graphs/system_architecture.svg" alt="System Architecture"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<span class="live">Live API</span>
|
<span class="live">Live API</span>
|
||||||
@@ -184,20 +208,25 @@
|
|||||||
<h2>MCP SERVER TOPOLOGY</h2>
|
<h2>MCP SERVER TOPOLOGY</h2>
|
||||||
<p>Three servers scoped by access domain. Each exposes tools, resources, and prompts. FCE connects to shared + passenger. Handover connects to shared + ops.</p>
|
<p>Three servers scoped by access domain. Each exposes tools, resources, and prompts. FCE connects to shared + passenger. Handover connects to shared + ops.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/mcp_servers.svg" alt="MCP Servers">
|
<a href="viewer.html?src=graphs/mcp_servers.svg"><img src="graphs/mcp_servers.svg" alt="MCP Servers"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<span class="mcp">Shared server</span>
|
<span class="mcp">Shared server</span>
|
||||||
<span class="ops">Ops server</span>
|
<span class="ops">Ops server</span>
|
||||||
<span class="live">Passenger server</span>
|
<span class="live">Passenger server</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="legend" style="margin-top: 8px;">
|
||||||
|
<span style="color:#8892a8">── solid = tool calls</span>
|
||||||
|
<span style="color:#8892a8">╌╌ dashed = resource reads</span>
|
||||||
|
<span style="color:#8892a8">··· dotted = prompt gets</span>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="efhas" class="graph-section">
|
<section id="efhas" class="graph-section">
|
||||||
<h2>FCE AGENT — BEHIND EVERY DEPARTURE</h2>
|
<h2>FCE AGENT — BEHIND EVERY DEPARTURE</h2>
|
||||||
<p>Passenger notification agent. Triages flight status, gathers context from 5 parallel tool calls (including live weather and FAA data), synthesizes an empathetic notification.</p>
|
<p>Passenger notification agent. Triages flight status, gathers context from 5 parallel tool calls (including live weather and FAA data), synthesizes an empathetic notification.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/efhas_agent.svg" alt="FCE Agent">
|
<a href="viewer.html?src=graphs/efhas_agent.svg"><img src="graphs/efhas_agent.svg" alt="FCE Agent"></a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -205,7 +234,7 @@
|
|||||||
<h2>SHIFT HANDOVER AGENT</h2>
|
<h2>SHIFT HANDOVER AGENT</h2>
|
||||||
<p>Ops briefing agent. Scans all hubs in parallel, scores issues by severity × time sensitivity, categorizes into IMMEDIATE / MONITOR / FYI, generates a structured brief.</p>
|
<p>Ops briefing agent. Scans all hubs in parallel, scores issues by severity × time sensitivity, categorizes into IMMEDIATE / MONITOR / FYI, generates a structured brief.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/handover_agent.svg" alt="Handover Agent">
|
<a href="viewer.html?src=graphs/handover_agent.svg"><img src="graphs/handover_agent.svg" alt="Handover Agent"></a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -213,7 +242,7 @@
|
|||||||
<h2>DATA FLOW — REAL vs MOCK</h2>
|
<h2>DATA FLOW — REAL vs MOCK</h2>
|
||||||
<p>Weather and FAA airport status are live (no API key). Flight, crew, passenger, and maintenance data are scenario-based fixtures switchable from the UI.</p>
|
<p>Weather and FAA airport status are live (no API key). Flight, crew, passenger, and maintenance data are scenario-based fixtures switchable from the UI.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/data_flow.svg" alt="Data Flow">
|
<a href="viewer.html?src=graphs/data_flow.svg"><img src="graphs/data_flow.svg" alt="Data Flow"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<span class="live">Live data (no API key)</span>
|
<span class="live">Live data (no API key)</span>
|
||||||
@@ -225,15 +254,50 @@
|
|||||||
<h2>DEPLOYMENT</h2>
|
<h2>DEPLOYMENT</h2>
|
||||||
<p>Kind cluster for dev (Tilt), docker-compose for quick start, EC2 for production demo. Entry point: localhost:8040.</p>
|
<p>Kind cluster for dev (Tilt), docker-compose for quick start, EC2 for production demo. Entry point: localhost:8040.</p>
|
||||||
<div class="graph-container">
|
<div class="graph-container">
|
||||||
<img src="graphs/deployment.svg" alt="Deployment">
|
<a href="viewer.html?src=graphs/deployment.svg"><img src="graphs/deployment.svg" alt="Deployment"></a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="repo" class="graph-section">
|
<section id="repo" class="graph-section">
|
||||||
<h2>REPOSITORY STRUCTURE</h2>
|
<h2>REPOSITORY STRUCTURE</h2>
|
||||||
<p>Monorepo: MCP servers, agents, IRROP engine, API, Vue UI (with shared component framework), and deployment configs.</p>
|
<p>Monorepo: MCP servers, agents, IRROP engine, API, Vue UI (with shared component framework), and deployment configs.</p>
|
||||||
<div class="graph-container">
|
<div class="tree-container">
|
||||||
<img src="graphs/repo_structure.svg" alt="Repository Structure">
|
<pre class="repo-tree"><span class="t-root">stellar-ops/</span>
|
||||||
|
├── <span class="t-dir">mcp_servers/</span>
|
||||||
|
│ ├── <span class="t-mcp">shared/</span> <span class="t-comment">server.py — tools/ resources/ prompts/</span>
|
||||||
|
│ │ └── tools: <span class="t-live">get_route_weather</span> · <span class="t-live">get_hub_forecasts</span> · <span class="t-live">get_airport_status</span>
|
||||||
|
│ │ get_flight_status · get_flight_details · get_irregular_ops
|
||||||
|
│ │ get_airport_congestion · get_maintenance_flags
|
||||||
|
│ ├── <span class="t-ops">ops/</span> <span class="t-comment">server.py — tools/ resources/ prompts/</span>
|
||||||
|
│ │ └── tools: get_crew_notes · get_crew_duty_status · get_pending_rebookings
|
||||||
|
│ │ generate_narrative
|
||||||
|
│ ├── <span class="t-pax">passenger/</span> <span class="t-comment">server.py — tools/ resources/ prompts/</span>
|
||||||
|
│ │ └── tools: generate_notification
|
||||||
|
│ └── <span class="t-dir">data/</span>
|
||||||
|
│ ├── models.py <span class="t-comment">FlightData, CrewMember, Passenger, MELItem, HubInfo</span>
|
||||||
|
│ ├── real/ <span class="t-live">openmeteo.py · faa.py</span>
|
||||||
|
│ └── scenarios/ <span class="t-comment">normal_ops · weather_disruption_ord</span>
|
||||||
|
│ <span class="t-comment">maintenance_delay_sfo · crew_swap_ewr</span>
|
||||||
|
├── <span class="t-dir">agents/</span>
|
||||||
|
│ ├── fce.py <span class="t-comment">FCE — "Behind Every Departure"</span>
|
||||||
|
│ ├── handover.py <span class="t-comment">Shift Handover agent</span>
|
||||||
|
│ └── shared/ <span class="t-comment">mcp_client.py · llm.py (Bedrock/Anthropic)</span>
|
||||||
|
├── <span class="t-dir">irrop/</span> <span class="t-comment">Disruption Recovery Engine (Project 3)</span>
|
||||||
|
│ ├── models/ <span class="t-comment">flight · passenger · crew · recovery</span>
|
||||||
|
│ ├── rules/ <span class="t-comment">faa_part117 · rebooking · compensation</span>
|
||||||
|
│ └── pipeline/ <span class="t-comment">ingest → triage → rebook → compensate</span>
|
||||||
|
├── <span class="t-dir">api/</span>
|
||||||
|
│ └── main.py <span class="t-comment">FastAPI + WebSocket + scenario data API</span>
|
||||||
|
├── <span class="t-dir">ui/</span>
|
||||||
|
│ ├── framework/ <span class="t-comment">soleprint-ui (shared component library)</span>
|
||||||
|
│ └── app/ <span class="t-comment">Vue 3 SPA — Operations · Internals · Data</span>
|
||||||
|
├── <span class="t-dir">ctrl/</span>
|
||||||
|
│ ├── Dockerfile.api/ui <span class="t-comment">Container builds</span>
|
||||||
|
│ ├── k8s/ <span class="t-comment">base/ + overlays/dev/ (Kustomize)</span>
|
||||||
|
│ ├── Tiltfile <span class="t-comment">Dev environment (Kind cluster: unt)</span>
|
||||||
|
│ └── docker-compose.yml <span class="t-comment">Simple alternative</span>
|
||||||
|
├── <span class="t-dir">docs/</span> <span class="t-comment">Architecture graphs (this page)</span>
|
||||||
|
└── .mcp.json <span class="t-comment">Claude Code integration — 3 servers</span></pre>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -248,6 +312,7 @@ function show(id) {
|
|||||||
document.getElementById(id).classList.add('active');
|
document.getElementById(id).classList.add('active');
|
||||||
event.currentTarget.classList.add('active');
|
event.currentTarget.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
101
docs/viewer.html
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Graph Viewer</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
background: #0a0e17;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
#container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
#container.dragging { cursor: grabbing; }
|
||||||
|
img {
|
||||||
|
transform-origin: 0 0;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<img id="img" />
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var src = new URLSearchParams(location.search).get('src');
|
||||||
|
var img = document.getElementById('img');
|
||||||
|
var container = document.getElementById('container');
|
||||||
|
|
||||||
|
img.src = src;
|
||||||
|
|
||||||
|
var scale = 1;
|
||||||
|
var x = 0, y = 0;
|
||||||
|
var dragging = false;
|
||||||
|
var startX, startY, startPanX, startPanY;
|
||||||
|
|
||||||
|
function apply() {
|
||||||
|
img.style.transform = 'translate(' + x + 'px,' + y + 'px) scale(' + scale + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fit to screen on load
|
||||||
|
img.onload = function() {
|
||||||
|
var sw = window.innerWidth / img.naturalWidth;
|
||||||
|
var sh = window.innerHeight / img.naturalHeight;
|
||||||
|
scale = Math.min(sw, sh) * 0.95;
|
||||||
|
x = (window.innerWidth - img.naturalWidth * scale) / 2;
|
||||||
|
y = (window.innerHeight - img.naturalHeight * scale) / 2;
|
||||||
|
apply();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wheel zoom toward cursor
|
||||||
|
container.addEventListener('wheel', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var factor = e.deltaY < 0 ? 1.12 : 0.89;
|
||||||
|
var rect = container.getBoundingClientRect();
|
||||||
|
var mx = e.clientX - rect.left;
|
||||||
|
var my = e.clientY - rect.top;
|
||||||
|
x = mx - (mx - x) * factor;
|
||||||
|
y = my - (my - y) * factor;
|
||||||
|
scale *= factor;
|
||||||
|
apply();
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
// Pan
|
||||||
|
container.addEventListener('mousedown', function(e) {
|
||||||
|
if (e.button !== 0) return;
|
||||||
|
dragging = true;
|
||||||
|
startX = e.clientX;
|
||||||
|
startY = e.clientY;
|
||||||
|
startPanX = x;
|
||||||
|
startPanY = y;
|
||||||
|
container.classList.add('dragging');
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', function(e) {
|
||||||
|
if (!dragging) return;
|
||||||
|
x = startPanX + (e.clientX - startX);
|
||||||
|
y = startPanY + (e.clientY - startY);
|
||||||
|
apply();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mouseup', function() {
|
||||||
|
dragging = false;
|
||||||
|
container.classList.remove('dragging');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Double-click to reset
|
||||||
|
container.addEventListener('dblclick', function() {
|
||||||
|
img.onload();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -12,7 +12,7 @@ from fastmcp import FastMCP
|
|||||||
from mcp_servers.data.scenarios.manager import scenario_manager
|
from mcp_servers.data.scenarios.manager import scenario_manager
|
||||||
|
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"united-ops-internal",
|
"stellar-ops-internal",
|
||||||
instructions=(
|
instructions=(
|
||||||
"Internal operations tools — crew duty status, pending rebookings, "
|
"Internal operations tools — crew duty status, pending rebookings, "
|
||||||
"and ops-audience narrative generation. Restricted to ops-facing clients."
|
"and ops-audience narrative generation. Restricted to ops-facing clients."
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from mcp_servers.data.models import MPStatus
|
|||||||
from mcp_servers.data.scenarios.manager import scenario_manager
|
from mcp_servers.data.scenarios.manager import scenario_manager
|
||||||
|
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"united-ops-passenger",
|
"stellar-ops-passenger",
|
||||||
instructions=(
|
instructions=(
|
||||||
"Passenger-facing tools — notification narrative generation "
|
"Passenger-facing tools — notification narrative generation "
|
||||||
"and flight manifest access. Restricted to customer-facing clients."
|
"and flight manifest access. Restricted to customer-facing clients."
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ from mcp_servers.data.real import faa, openmeteo
|
|||||||
from mcp_servers.data.scenarios.manager import scenario_manager
|
from mcp_servers.data.scenarios.manager import scenario_manager
|
||||||
|
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"united-ops-shared",
|
"stellar-ops-shared",
|
||||||
instructions=(
|
instructions=(
|
||||||
"Shared operational data tools for Stellar Air operations. "
|
"Shared operational data tools for Stellar Air NOVA operations. "
|
||||||
"Covers: flight status, weather (live OpenMeteo), airport status "
|
"Covers: flight status, weather (live OpenMeteo), airport status "
|
||||||
"(live FAA), and maintenance flags. Used by all agent clients."
|
"(live FAA), and maintenance flags. Used by all agent clients."
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "united-ops"
|
name = "stellar-ops"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "united-ops-ui",
|
"name": "stellar-ops-ui",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref, provide } from 'vue'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import ScenarioSelector from './components/ScenarioSelector.vue'
|
import ScenarioSelector from './components/ScenarioSelector.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const scenarioVersion = ref(0)
|
||||||
|
|
||||||
|
function onScenarioChange() {
|
||||||
|
scenarioVersion.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
provide('scenarioVersion', scenarioVersion)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -18,8 +25,9 @@ const route = useRoute()
|
|||||||
<router-link to="/" :class="{ active: route.path === '/' }">Operations</router-link>
|
<router-link to="/" :class="{ active: route.path === '/' }">Operations</router-link>
|
||||||
<router-link to="/internals" :class="{ active: route.path === '/internals' }">Internals</router-link>
|
<router-link to="/internals" :class="{ active: route.path === '/internals' }">Internals</router-link>
|
||||||
<router-link to="/data" :class="{ active: route.path === '/data' }">Data</router-link>
|
<router-link to="/data" :class="{ active: route.path === '/data' }">Data</router-link>
|
||||||
|
<a href="/docs/" class="docs-link" target="_blank">Docs</a>
|
||||||
</nav>
|
</nav>
|
||||||
<ScenarioSelector />
|
<ScenarioSelector @change="onScenarioChange" />
|
||||||
</header>
|
</header>
|
||||||
<main class="app-main">
|
<main class="app-main">
|
||||||
<router-view />
|
<router-view />
|
||||||
@@ -85,6 +93,11 @@ const route = useRoute()
|
|||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-nav .docs-link {
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
.app-main {
|
.app-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
const emit = defineEmits<{ change: [id: string] }>()
|
||||||
|
|
||||||
const scenarios = ref<any[]>([])
|
const scenarios = ref<any[]>([])
|
||||||
const active = ref('')
|
const active = ref('')
|
||||||
|
|
||||||
@@ -19,6 +21,7 @@ async function switchScenario(id: string) {
|
|||||||
body: JSON.stringify({ scenario_id: id }),
|
body: JSON.stringify({ scenario_id: id }),
|
||||||
})
|
})
|
||||||
active.value = id
|
active.value = id
|
||||||
|
emit('change', id)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(loadScenarios)
|
onMounted(loadScenarios)
|
||||||
|
|||||||
@@ -1,40 +1,41 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, watch, inject } from 'vue'
|
||||||
import { Panel } from 'soleprint-ui'
|
import { Panel } 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'
|
||||||
|
|
||||||
const flights = ref<any[]>([])
|
const flights = ref<any[]>([])
|
||||||
const selectedFlight = ref('')
|
const selectedFlight = ref('')
|
||||||
const efhasStatus = ref<'idle' | 'processing' | 'live' | 'error'>('idle')
|
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')
|
||||||
|
|
||||||
|
watch(scenarioVersion, () => {
|
||||||
|
loadFlights()
|
||||||
|
notification.value = null
|
||||||
|
handoverBrief.value = null
|
||||||
|
fceStatus.value = 'idle'
|
||||||
|
handoverStatus.value = 'idle'
|
||||||
|
})
|
||||||
|
|
||||||
async function loadFlights() {
|
async function loadFlights() {
|
||||||
// Load flights from active scenario via a simple status check on known IDs
|
const res = await fetch('/scenarios/data/flights')
|
||||||
const res = await fetch('/scenarios/active')
|
const data = await res.json()
|
||||||
const scenario = await res.json()
|
flights.value = data.map((f: any) => ({
|
||||||
// Fetch flights by triggering the shared MCP server isn't exposed directly
|
id: f.flight_id,
|
||||||
// so we'll use a hardcoded list per scenario for now
|
label: `${f.flight_id} ${f.origin}→${f.destination}${f.status !== 'ON_TIME' ? ' (' + f.status + ')' : ''}`,
|
||||||
// TODO: expose flight list via API
|
}))
|
||||||
flights.value = [
|
|
||||||
{ id: 'UA432', label: 'UA432 ORD→SFO' },
|
|
||||||
{ id: 'UA881', label: 'UA881 ORD→LAX' },
|
|
||||||
{ id: 'UA233', label: 'UA233 ORD→DEN' },
|
|
||||||
{ id: 'UA094', label: 'UA094 ORD→EWR' },
|
|
||||||
{ id: 'UA517', label: 'UA517 ORD→IAH (CANCELLED)' },
|
|
||||||
{ id: 'UA1220', label: 'UA1220 ORD→IAD (on-time)' },
|
|
||||||
]
|
|
||||||
selectedFlight.value = flights.value[0]?.id || ''
|
selectedFlight.value = flights.value[0]?.id || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runEfhas() {
|
async function runFce() {
|
||||||
if (!selectedFlight.value) return
|
if (!selectedFlight.value) return
|
||||||
efhasStatus.value = 'processing'
|
fceStatus.value = 'processing'
|
||||||
notification.value = null
|
notification.value = null
|
||||||
|
|
||||||
const res = await fetch('/agents/efhas', {
|
const res = await fetch('/agents/fce', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ flight_id: selectedFlight.value }),
|
body: JSON.stringify({ flight_id: selectedFlight.value }),
|
||||||
@@ -48,10 +49,10 @@ async function runEfhas() {
|
|||||||
if (data.status === 'completed') {
|
if (data.status === 'completed') {
|
||||||
clearInterval(poll)
|
clearInterval(poll)
|
||||||
notification.value = data.result
|
notification.value = data.result
|
||||||
efhasStatus.value = 'live'
|
fceStatus.value = 'live'
|
||||||
} else if (data.status === 'error') {
|
} else if (data.status === 'error') {
|
||||||
clearInterval(poll)
|
clearInterval(poll)
|
||||||
efhasStatus.value = 'error'
|
fceStatus.value = 'error'
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
@@ -86,20 +87,20 @@ onMounted(loadFlights)
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="ops-page">
|
<div class="ops-page">
|
||||||
<Panel title="FCE — Behind Every Departure" :status="efhasStatus">
|
<Panel title="FCE — Behind Every Departure" :status="fceStatus">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<select v-model="selectedFlight" class="flight-select">
|
<select v-model="selectedFlight" class="flight-select">
|
||||||
<option v-for="f in flights" :key="f.id" :value="f.id">{{ f.label }}</option>
|
<option v-for="f in flights" :key="f.id" :value="f.id">{{ f.label }}</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="run-btn" @click="runEfhas" :disabled="efhasStatus === 'processing'">
|
<button class="run-btn" @click="runFce" :disabled="fceStatus === 'processing'">
|
||||||
{{ efhasStatus === 'processing' ? 'Running...' : 'Run FCE' }}
|
{{ fceStatus === 'processing' ? 'Running...' : 'Run FCE' }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div v-if="notification" class="result-area">
|
<div v-if="notification" class="result-area">
|
||||||
<NotificationCard :data="notification" />
|
<NotificationCard :data="notification" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="efhasStatus === 'processing'" class="loading">
|
<div v-else-if="fceStatus === 'processing'" class="loading">
|
||||||
Running agent... gathering flight data, weather, crew notes...
|
Running agent... gathering flight data, weather, crew notes...
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="empty">
|
<div v-else class="empty">
|
||||||
|
|||||||