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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/event-service/resources/Railway/event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def __init__(self):

# Optional: Customize Event Uniqueness
def get_unique_fields(self, data):
id_event = data["data"].get("id_event")
id_train = data["data"].get("id_train")
event_type = data["data"].get("event_type")
return {"id_train": id_train, "event_type": event_type}
return {"id_event": id_event, "id_train": id_train, "event_type": event_type}
1 change: 1 addition & 0 deletions backend/event-service/resources/Railway/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class MetadataSchemaRailway(MetadataSchema):
agent_id = String(allow_none=True, required=True)
event_type = String(required=True)
id_event = String(allow_none=True, required=True)
agent_position = List(
Integer(allow_none=True), allow_none=True, default=None
)
Expand Down
48 changes: 35 additions & 13 deletions backend/recommendation-service/resources/Railway/manager.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
# backend/recommendation-service/resources/Railway/manager.py

import json
from api.manager.base_manager import BaseRecommendationManager
from .mockRecommendations.mockRecommendations import RECOMMENDATION_CATALOG

import logging

logger = logging.getLogger(__name__)

class RailwayManager(BaseRecommendationManager):
def __init__(self):
super().__init__()

def _transform_recommendation(self, reco_json):
"""Transform a recommendation from catalog to output format."""
reco = json.loads(reco_json)
return {
"title": reco["data"]["title"],
"description": reco["data"]["description"],
"use_case": reco["data"]["use_case"],
"agent_type": reco["data"]["agent_type"],
"actions": [{}],
"kpis": reco["data"]["kpis"],
}

def get_recommendation(self, request_data):
"""
Override to provide recommendations specific to the RTE use case.
Override to provide recommendations specific to the Railway use case.

This method generates and returns recommendations tailored for RTE.
This method generates and returns recommendations tailored for Railway events.
"""
action_dict = {}

output_json = {
"title": "recommendation",
"description": "description",
"use_case": "Railway",
"agent_type": "agent_type",
"actions": [action_dict],
}
event_data = request_data.get("event", {})
event_id = str(event_data.get("id_event", "1"))

logger.info(f"Processing event_id: {event_id}")

# Get recommendations from catalog
if event_id == "1":
recommendations = RECOMMENDATION_CATALOG.get(event_id, RECOMMENDATION_CATALOG["1"])
elif event_id == "2":
recommendations = RECOMMENDATION_CATALOG.get(event_id, RECOMMENDATION_CATALOG["1"])
elif event_id == "3":
recommendations = RECOMMENDATION_CATALOG.get(event_id, RECOMMENDATION_CATALOG["1"])
# Transform each recommendation to output format
return [self._transform_recommendation(reco) for reco in recommendations]


return [output_json]
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@

import json


################################################################
######### Event 1 Recommendations ##############################
################################################################

Reco11 = json.dumps({
"data": {
"title": "Stay at the St Pierre des Corps station",
"description" : "Hold the train in the St Pierre des Corps station until traffic resumes.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "78",
"nb_impacted_passengers" : "468",
"total_cost" : "32838",
"delay" : "1h30",
"best": "True",
}

}
}
)

Reco12 = json.dumps({
"data": {
"title": "Delay",
"description" : "Hold the train on the track until traffic resumes. Arrangements for passenger support.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "87",
"nb_impacted_passengers" : "398",
"total_cost" : "34626",
"delay" : "1h30",
"best": "False",
}

}
}
)


Reco13 = json.dumps({
"data": {
"title": "Reroute",
"description" : "Reroute the trains. Passengers traveling to and from Poitiers are being assisted.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "102",
"nb_impacted_passengers" : "350",
"total_cost" : "35700",
"delay" : "1h40",
"best": "False",
}

}
}
)


Reco14 = json.dumps({
"data": {
"title": "Cancel",
"description" : "Train services are cancelled. Passengers are advised to postpone their journey.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "233",
"nb_impacted_passengers" : "468",
"total_cost" : "109044",
"delay" : "1h45",
"best": "False",
}

}
}
)

################################################################
######### Event 2 Recommendations ##############################
################################################################


Reco21 = json.dumps({
"data": {
"title": "Stay at the station",
"description" : "Hold the train in the Poitiers station until traffic resumes.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "123",
"nb_impacted_passengers" : "459",
"total_cost" : "56457",
"delay" : "1h05",
"best": "False",
}

}
}
)





Reco22 = json.dumps({
"data": {
"title": "Delay",
"description" : "Hold the train on the track until traffic resumes. Arrangements for passenger support.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "129",
"nb_impacted_passengers" : "459",
"total_cost" : "59211",
"delay" : "1h00",
"best": "False",
}

}
}
)

Reco23 = json.dumps({
"data": {
"title": "Reroute",
"description" : "Diversion and rerouting of trains to the standard line between Angoulême and Poitiers. ",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "73",
"nb_impacted_passengers" : "459",
"total_cost" : "33507",
"delay" : "1h00",
"best": "True",
}

}
}
)


Reco24 = json.dumps({
"data": {
"title": "Cancel",
"description" : "Train services are cancelled. Passengers are advised to postpone their journey.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "221",
"nb_impacted_passengers" : "459",
"total_cost" : "101439",
"delay" : "1h00",
"best": "False",
}

}
}
)


################################################################
######### Event 3 Recommendations ##############################
################################################################

Reco31 = json.dumps({
"data": {
"title": "Wait at the Bordeaux station",
"description" : "Hold the train at the station until traffic resumes.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "94",
"nb_impacted_passengers" : "348",
"total_cost" : "32712",
"delay" : "00h30",
"best": "True",
}

}
}
)


Reco32 = json.dumps({
"data": {
"title": "Delay",
"description" : "Hold the train on the track until traffic resumes. Arrangements for passenger support.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "94",
"nb_impacted_passengers" : "347",
"total_cost" : "32618",
"delay" : "00h53",
"best": "False",
}

}
}
)


Reco33 = json.dumps({
"data": {
"title": "Rerouting from Bordeaux to Angoulême ",
"description" : "Diversion and rerouting of trains to the standard line between Angoulême and Poitiers.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "95",
"nb_impacted_passengers" : "348",
"total_cost" : "33060",
"delay" : "1h24",
"best": "False",
}

}
}
)

Reco34 = json.dumps({
"data": {
"title": "Supprimer",
"description" : "Train services are cancelled. Passengers are advised to postpone their journey.",
"use_case": "Railway",
"agent_type": "AI",
"kpis": {
"cost" : "257",
"nb_impacted_passengers" : "348",
"total_cost" : "89436",
"delay" : "00h40",
"best": "False",
}

}
}
)


RECOMMENDATION_CATALOG = {
"1": [Reco11, Reco12, Reco13, Reco14],
"2": [Reco21, Reco22, Reco23, Reco24],
"3": [Reco31, Reco32, Reco33, Reco34],
}
27 changes: 25 additions & 2 deletions frontend/src/api/services.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import http from '@/plugins/http'
import { useAppStore } from '@/stores/app'
import { useCardsStore } from '@/stores/cards'
import { useServicesStore } from '@/stores/services'
import type { Card } from '@/types/cards'
import type { Action, Context, Entity } from '@/types/entities'
import type { Procedure } from '@/types/procedure'
import type { FullContext, Recommendation, Trace } from '@/types/services'
import { recordTraceForSession } from '@/utils/traceSessionExport'

export function getRecommendation<E extends Entity = Entity>(payload: {
event: Card<E>['data']['metadata']
Expand All @@ -18,10 +20,31 @@ export function getContext<E extends Entity = Entity>() {
}

export function sendTrace(payload: Trace) {
return http.post<Required<Trace>>('/cabhistoric/api/v1/traces', {
if (payload.step === 'ASKFORHELP' && typeof payload.data === 'object' && payload.data !== null) {
const cardId = (payload.data as { id?: unknown }).id
if (typeof cardId === 'string') {
const cardsStore = useCardsStore()
const card = cardsStore._cards.find((item) => item.id === cardId)
recordTraceForSession({
use_case: payload.use_case,
step: 'EVENT',
data: {
card_id: cardId,
process_instance_id: card?.processInstanceId,
start_date: card?.startDate ? new Date(card.startDate).toISOString() : undefined,
metadata: card?.data.metadata
},
date: new Date().toISOString()
})
}
}

const tracePayload = {
...payload,
date: new Date().toISOString()
})
}
recordTraceForSession(tracePayload)
return http.post<Required<Trace>>('/cabhistoric/api/v1/traces', tracePayload)
}

export function applyRecommendation<E extends Entity = Entity>(data: Action<E>) {
Expand Down
Loading
Loading