NeerajRavi commited on
Commit
6b3769c
·
verified ·
1 Parent(s): 7c90822

Upload 37 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/raw_docs/train_station/EXP-TRAINS.json filter=lfs diff=lfs merge=lfs -text
37
+ data/raw_docs/train_station/PASS-TRAINS.json filter=lfs diff=lfs merge=lfs -text
38
+ data/vector_store/rules_faiss.index filter=lfs diff=lfs merge=lfs -text
39
+ data/vector_store/rules_metadata.json filter=lfs diff=lfs merge=lfs -text
Chatbot/__init__.py ADDED
File without changes
Chatbot/bot.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Main program...Combines all modules
2
+
3
+ import re
4
+ from Chatbot.router import route_query
5
+ from helpers.live_sources import retrieve_live_sources
6
+ from dotenv import load_dotenv
7
+ load_dotenv()
8
+ HIGH_CONF = 0.75
9
+ LOW_CONF = 0.45
10
+ LINK_RELEVANCE_MIN = 0.01
11
+ RELEVANCE_CLOSE_DELTA = 0.10
12
+
13
+ # Calling different modules
14
+ def call_railway_rag(query):
15
+ from modules.railway_rag.railway_base_rag import answer_with_rag
16
+ return answer_with_rag(query)
17
+ def call_live_data(query):
18
+ from modules.live_data_apis import answer_with_live_data
19
+ return answer_with_live_data(query)
20
+ def call_general(query,route,mode="module"):
21
+ from modules.general_chat import answer_general_query
22
+ return answer_general_query(query,route,mode)
23
+ def call_link_answer(query, num_of_links):
24
+ from modules.link_answer import run
25
+ src=run(query,num_of_links)
26
+ if not src:
27
+ return {"answer": None, "has_answer": False, "meta": {}}
28
+ return {
29
+ "answer": [s["url"] for s in src],
30
+ "has_answer": True,
31
+ "meta": {
32
+ "status": "ok",
33
+ "type": "links_only",
34
+ "requested": num_of_links,
35
+ "returned": len(src)
36
+ }
37
+ }
38
+
39
+ # Preliminary query check
40
+ def analyze_input_structure(query: str):
41
+ q = query.strip()
42
+ if not q:
43
+ return "empty"
44
+ if re.fullmatch(r"[^\w\s]+", q):
45
+ return "noise"
46
+ return "normal"
47
+ #Gets num of links
48
+ def extract_num_links(query, default=2, max_links=10):
49
+ match = re.search(r"\b(\d+)\b", query)
50
+ if match:
51
+ return min(int(match.group(1)), max_links)
52
+ return default
53
+ # Link adding reasons
54
+ def link_reason(reason_key: str):
55
+ return {
56
+ "rag_moderate": ("This answer is based on available railway rules. For official confirmation or additional details, please refer to:"),
57
+ "api_stale": ("The available data may be outdated. For the latest official information, please refer to:"),
58
+ "api_unknown": ("For authoritative and up-to-date information, please refer to:"),
59
+ "general_info": ("For more detailed or official information, you may also refer to:"),
60
+ "API_not_working":("The API is currently not working. For more information, please refer to:")
61
+ }.get(reason_key, "For more information, please refer to:")
62
+
63
+ # Clean links
64
+ def format_live_sources(sources, reason):
65
+ text = "\n\n" + reason + "\n"
66
+ for s in sources:
67
+ text += s["url"] + "\n"
68
+ return text
69
+
70
+ #Main
71
+ def answer_query(query):
72
+ structure = analyze_input_structure(query)
73
+ if structure == "empty":
74
+ return "Please enter a query so I can help you."
75
+ if structure == "noise":
76
+ return "I couldn’t understand the input. Please enter a clear question."
77
+ # Calls router
78
+ route = route_query(query)
79
+ if route.get("router_failed"):
80
+ return call_general(query,route,mode="failsafe")["answer"]
81
+ preferences = route["module_preferences"]
82
+ relevance_map = {m["module"]: m["relevance"] for m in preferences}
83
+ tried = set()
84
+ for pref in preferences:
85
+ module = pref["module"]
86
+ if module in tried:
87
+ continue
88
+ tried.add(module)
89
+ # Link answer(links only)
90
+ if module == "link_answer":
91
+ num_links = extract_num_links(query)
92
+ result = call_link_answer(query, num_links)
93
+ if result.get("has_answer"):
94
+ return "\n".join(result["answer"])
95
+ continue
96
+ # RAG
97
+ if module == "railway_rag":
98
+ result=call_railway_rag(query)
99
+ if result.get("has_answer")==False:
100
+ continue
101
+ conf=result.get("meta",{}).get("confidence",0.0)
102
+ if conf >= HIGH_CONF:
103
+ return result["answer"]
104
+ if LOW_CONF <= conf < HIGH_CONF:
105
+ if relevance_map.get("link_answer",0) > LINK_RELEVANCE_MIN:
106
+ links = retrieve_live_sources(query)
107
+ if links:
108
+ return (
109
+ result["answer"]
110
+ + format_live_sources(
111
+ links,
112
+ reason=link_reason("rag_moderate")
113
+ )
114
+ )
115
+ return result["answer"]
116
+ continue
117
+ # Live data(APIs)
118
+ if module == "live_data_apis":
119
+ result=call_live_data(query)
120
+ if result.get("has_answer")==False and result.get("meta",{}).get("status")=="nothing":
121
+ continue
122
+ if result.get("has_answer")==False and result.get("meta",{}).get("status")=="api_failed":
123
+ links=retrieve_live_sources(query)
124
+ reason="API_not_working"
125
+ if links:
126
+ return (format_live_sources(links,reason=link_reason(reason)))
127
+ if result.get("has_answer")==False and result.get("meta",{}).get("status")=="need_input":
128
+ FIELD_LABELS = {
129
+ "train_number": "Train number",
130
+ "from_station": "Source station",
131
+ "to_station": "Destination station",
132
+ "date": "Journey date",
133
+ "class_type": "Class (e.g., SL, 3A, 2A)",
134
+ "quota": "Quota (GN / Tatkal)",
135
+ "station_code": "Station name",
136
+ "pnr": "PNR number",
137
+ "hours": "Time window (in hours)"}
138
+ missing=result.get("meta",{}).get("missing_fields",[])
139
+ readable = [
140
+ FIELD_LABELS.get(f, f.replace("_", " ").title())
141
+ for f in missing]
142
+ return ("I need a bit more information to answer this.\n""Missing details: " + ", ".join(readable))
143
+ if result.get("has_answer")==True and result.get("meta",{}).get("status")=="ok":
144
+ freshness = result.get("meta", {}).get("freshness", "unknown")
145
+ fallback_used = result.get("meta", {}).get("fallback_used", False)
146
+ if freshness == "fresh" and not fallback_used:
147
+ return result["answer"]
148
+ if relevance_map.get("link_answer", 0) > LINK_RELEVANCE_MIN:
149
+ reason=("api_stale" if freshness == "stale" else "api_unknown")
150
+ links=retrieve_live_sources(query)
151
+ if links:
152
+ return (result["answer"]+ format_live_sources(links,reason=link_reason(reason)))
153
+ continue
154
+ # General
155
+ if module=="general":
156
+ result=call_general(query,route,mode="module")
157
+ gen_rel = relevance_map.get("general", 0)
158
+ src_rel = relevance_map.get("live_sources", 0)
159
+ if (src_rel > LINK_RELEVANCE_MIN and abs(gen_rel - src_rel) <= RELEVANCE_CLOSE_DELTA):
160
+ links = retrieve_live_sources(query)
161
+ if links:
162
+ return (result["answer"]+ format_live_sources(links,reason=link_reason("general_info")))
163
+ if result.get("has_answer"):
164
+ return result["answer"]
165
+ continue
166
+ # Last failsafe
167
+ return call_general(query,route,mode="failsafe")["answer"]
Chatbot/router.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ from openai import OpenAI
4
+ from dotenv import load_dotenv
5
+ load_dotenv()
6
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
7
+ if not client:
8
+ raise RuntimeError("OPENAI_API_KEY is not set")
9
+ MODEL_NAME = "gpt-4.1-mini"
10
+
11
+ ROUTER_SYSTEM_PROMPT = (
12
+ "You are a routing system for a multi-module assistant.\n"
13
+ "Your task is to rank ALL available modules by how suitable they are\n"
14
+ "for handling the user's input.\n\n"
15
+
16
+ "Available modules:\n"
17
+ "- railway_rag : authoritative, static, rule-based railway information such as\n"
18
+ " laws, regulations, penalties, permissions, procedures, and\n"
19
+ " official policies derived from documents.\n\n"
20
+
21
+ "- live_data_apis : dynamic or time-sensitive railway information such as\n"
22
+ " live train status, current location, delays, fares,\n"
23
+ " seat availability, PNR status, or other real-time data.\n\n"
24
+
25
+ "- general : conversational, explanatory, or contextual input such as\n"
26
+ " greetings, clarifications, follow-up questions, or general\n"
27
+ " explanations that do not require authoritative rules or live data.\n\n"
28
+
29
+ "- link_answer : providing official railway website links ONLY when the user explicitly asks for links, sources, websites, or external references, or when they request where to check information.\n\n"
30
+
31
+ "Rules:\n"
32
+ "- Rank ALL modules\n"
33
+ "- Relevance must be between 0.0 and 1.0\n"
34
+ "- Higher relevance means the module should be tried earlier\n"
35
+ "- Do NOT explain your reasoning\n"
36
+ "- Do NOT generate answers\n"
37
+ "- Respond ONLY in valid JSON\n\n"
38
+
39
+ "JSON format:\n"
40
+ "{\n"
41
+ ' "module_preferences": [\n'
42
+ ' {"module": "railway_rag", "relevance": 0.0},\n'
43
+ ' {"module": "live_data_apis", "relevance": 0.0},\n'
44
+ ' {"module": "general", "relevance": 0.0},\n'
45
+ ' {"module": "link_answer", "relevance": 0.0}\n'
46
+ " ]\n"
47
+ "}"
48
+ )
49
+
50
+ VALID_MODULES = {"railway_rag", "live_data_apis", "general", "link_answer"}
51
+
52
+ def route_query(query):
53
+ response = client.chat.completions.create(
54
+ model=MODEL_NAME,
55
+ messages=[
56
+ {"role": "system", "content": ROUTER_SYSTEM_PROMPT},
57
+ {"role": "user", "content": query}
58
+ ],
59
+ temperature=0
60
+ )
61
+ try:
62
+ parsed = json.loads(response.choices[0].message.content)
63
+ prefs = parsed["module_preferences"]
64
+ except Exception:
65
+ # Explicit router failure (no guessing)
66
+ return {
67
+ "router_failed": True,
68
+ "module_preferences": []
69
+ }
70
+ cleaned = []
71
+ seen = set()
72
+ for item in prefs:
73
+ module = item.get("module")
74
+ relevance = item.get("relevance")
75
+ if module not in VALID_MODULES:
76
+ continue
77
+ try:
78
+ relevance = float(relevance)
79
+ except Exception:
80
+ continue
81
+ relevance=max(0.0,min(relevance,1.0))
82
+ cleaned.append({"module": module, "relevance": relevance}) #Gives module name and relevance score in decreasing order
83
+ seen.add(module)
84
+ for m in VALID_MODULES:
85
+ if m not in seen:
86
+ cleaned.append({"module": m, "relevance": 0.0})
87
+ cleaned.sort(key=lambda x: x["relevance"], reverse=True)
88
+ print(cleaned)
89
+ return {
90
+ "router_failed": False,
91
+ "module_preferences": cleaned,
92
+ }
Chatbot/server.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from fastapi.responses import FileResponse
5
+ from fastapi.staticfiles import StaticFiles
6
+ import os
7
+ import traceback
8
+ from dotenv import load_dotenv
9
+ load_dotenv()
10
+ from Chatbot.bot import answer_query
11
+
12
+ app = FastAPI(title="Railway Assistant")
13
+ app.add_middleware(
14
+ CORSMiddleware,
15
+ allow_origins=["*"],
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20
+ FRONTEND_DIR = os.path.join(BASE_DIR, "frontend")
21
+
22
+ class ChatRequest(BaseModel):
23
+ query: str
24
+
25
+ class ChatResponse(BaseModel):
26
+ answer: str
27
+ confidence: str | None = None
28
+ source: str | None = None
29
+
30
+ @app.post("/chat", response_model=ChatResponse)
31
+ async def chat(request: ChatRequest):
32
+ try:
33
+ answer = answer_query(request.query)
34
+ # Defensive fallback (never return None)
35
+ if not answer:
36
+ answer = "I couldn’t process that. Please try rephrasing your question."
37
+ except Exception:
38
+ traceback.print_exc()
39
+ answer = "Something went wrong while processing your request."
40
+ return {
41
+ "answer": answer,
42
+ "confidence": None,
43
+ "source": None
44
+ }
45
+
46
+ @app.get("/")
47
+ def serve_ui():
48
+ return FileResponse(os.path.join(FRONTEND_DIR, "index.html"))
49
+
50
+ # Serve static assets (CSS, JS, images)
51
+ app.mount(
52
+ "/static",
53
+ StaticFiles(directory=FRONTEND_DIR),
54
+ name="static"
55
+ )
app.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import traceback
3
+ from Chatbot.bot import answer_query
4
+
5
+ def chat_fn(message, history):
6
+ try:
7
+ answer = answer_query(message)
8
+ if not answer:
9
+ answer = "I couldn’t process that. Please try rephrasing your question."
10
+ except Exception:
11
+ traceback.print_exc()
12
+ answer = "Something went wrong while processing your request."
13
+ history.append((message, answer))
14
+ return "", history
15
+
16
+ with gr.Blocks(
17
+ theme=gr.themes.Soft(),
18
+ title="Railway Intelligence Assistant"
19
+ ) as demo:
20
+ gr.Markdown("""
21
+ # 🚆 Railway Intelligence Assistant
22
+ **LLM-powered RAG system using FAISS, live APIs, and ChatGPT**
23
+ """)
24
+ chatbot = gr.Chatbot(height=420)
25
+ msg = gr.Textbox(
26
+ placeholder="Ask about railway rules, safety, or live train information…",
27
+ show_label=False
28
+ )
29
+ msg.submit(chat_fn, [msg, chatbot], [msg, chatbot])
30
+ demo.launch()
data/chunks/circulars_chunks.json ADDED
The diff for this file is too large to render. See raw diff
 
data/chunks/core_docs_chunks.json ADDED
The diff for this file is too large to render. See raw diff
 
data/chunks/live_sources_chunks.json ADDED
@@ -0,0 +1,730 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "chunk_id": "https:__www.indiacode.nic.in_handle_123456789_2362_pNone_s1_c1",
4
+ "document_path": "https://www.indiacode.nic.in/handle/123456789/2362",
5
+ "doc_category": "live_source",
6
+ "rule_type": "law",
7
+ "priority": 1,
8
+ "authority": "Government of India",
9
+ "is_static": false,
10
+ "effective_year": null,
11
+ "page_number": null,
12
+ "section_index": 1,
13
+ "chunk_index": 1,
14
+ "text": "Official and updated text of the Railways Act, 1989 including amendments"
15
+ },
16
+ {
17
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard__pNone_s1_c1",
18
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
19
+ "doc_category": "live_source",
20
+ "rule_type": "circular",
21
+ "priority": 2,
22
+ "authority": "Railway Board",
23
+ "is_static": false,
24
+ "effective_year": null,
25
+ "page_number": null,
26
+ "section_index": 1,
27
+ "chunk_index": 1,
28
+ "text": "Latest railway rules, circulars, policy letters and amendments issued by Railway Board"
29
+ },
30
+ {
31
+ "chunk_id": "https:__www.irctc.co.in_nget_enquiry_termsAndConditions_pNone_s1_c1",
32
+ "document_path": "https://www.irctc.co.in/nget/enquiry/termsAndConditions",
33
+ "doc_category": "live_source",
34
+ "rule_type": "passenger_rules",
35
+ "priority": 3,
36
+ "authority": "IRCTC",
37
+ "is_static": false,
38
+ "effective_year": null,
39
+ "page_number": null,
40
+ "section_index": 1,
41
+ "chunk_index": 1,
42
+ "text": "Latest passenger-facing rules including booking, cancellation, refund and TDR policies"
43
+ },
44
+ {
45
+ "chunk_id": "https:__contents.irctc.co.in_en_RefundCancellationRules.pdf_pNone_s1_c1",
46
+ "document_path": "https://contents.irctc.co.in/en/RefundCancellationRules.pdf",
47
+ "doc_category": "live_source",
48
+ "rule_type": "refund",
49
+ "priority": 3,
50
+ "authority": "IRCTC",
51
+ "is_static": false,
52
+ "effective_year": null,
53
+ "page_number": null,
54
+ "section_index": 1,
55
+ "chunk_index": 1,
56
+ "text": "Official refund and cancellation rules PDF maintained by IRCTC"
57
+ },
58
+ {
59
+ "chunk_id": "https:__railmadad.indianrailways.gov.in_pNone_s1_c1",
60
+ "document_path": "https://railmadad.indianrailways.gov.in",
61
+ "doc_category": "live_source",
62
+ "rule_type": "grievance_emergency",
63
+ "priority": 0,
64
+ "authority": "Indian Railways",
65
+ "is_static": false,
66
+ "effective_year": null,
67
+ "page_number": null,
68
+ "section_index": 1,
69
+ "chunk_index": 1,
70
+ "text": "Official grievance redressal and emergency assistance portal (includes helpline 139)"
71
+ },
72
+ {
73
+ "chunk_id": "https:__crs.gov.in_pNone_s1_c1",
74
+ "document_path": "https://crs.gov.in",
75
+ "doc_category": "live_source",
76
+ "rule_type": "safety",
77
+ "priority": 2,
78
+ "authority": "Ministry of Civil Aviation (Rail Safety)",
79
+ "is_static": false,
80
+ "effective_year": null,
81
+ "page_number": null,
82
+ "section_index": 1,
83
+ "chunk_index": 1,
84
+ "text": "Railway safety rules, accident inquiries and safety manuals"
85
+ },
86
+ {
87
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,2,287_pNone_s1_c1",
88
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,2,287",
89
+ "doc_category": "live_source",
90
+ "rule_type": "passenger_amenities",
91
+ "priority": 4,
92
+ "authority": "Railway Board",
93
+ "is_static": false,
94
+ "effective_year": null,
95
+ "page_number": null,
96
+ "section_index": 1,
97
+ "chunk_index": 1,
98
+ "text": "Official passenger amenities policies and standards at stations and trains"
99
+ },
100
+ {
101
+ "chunk_id": "https:__rct.indianrailways.gov.in_pNone_s1_c1",
102
+ "document_path": "https://rct.indianrailways.gov.in",
103
+ "doc_category": "live_source",
104
+ "rule_type": "claims_compensation",
105
+ "priority": 2,
106
+ "authority": "Government of India",
107
+ "is_static": false,
108
+ "effective_year": null,
109
+ "page_number": null,
110
+ "section_index": 1,
111
+ "chunk_index": 1,
112
+ "text": "Compensation, refund and claims procedures related to railway accidents and losses"
113
+ },
114
+ {
115
+ "chunk_id": "https:__indianrailways.gov.in_pNone_s1_c1",
116
+ "document_path": "https://indianrailways.gov.in",
117
+ "doc_category": "live_source",
118
+ "rule_type": "official_portal",
119
+ "priority": 1,
120
+ "authority": "Ministry of Railways, Government of India",
121
+ "is_static": false,
122
+ "effective_year": null,
123
+ "page_number": null,
124
+ "section_index": 1,
125
+ "chunk_index": 1,
126
+ "text": "Primary official portal for Indian Railways policies, notices, tenders and updates"
127
+ },
128
+ {
129
+ "chunk_id": "https:__www.indianrail.gov.in_pNone_s1_c1",
130
+ "document_path": "https://www.indianrail.gov.in",
131
+ "doc_category": "live_source",
132
+ "rule_type": "passenger_enquiry",
133
+ "priority": 0,
134
+ "authority": "Indian Railways",
135
+ "is_static": false,
136
+ "effective_year": null,
137
+ "page_number": null,
138
+ "section_index": 1,
139
+ "chunk_index": 1,
140
+ "text": "Passenger-facing enquiry system for schedules, routes, fares and availability"
141
+ },
142
+ {
143
+ "chunk_id": "https:__enquiry.indianrail.gov.in_pNone_s1_c1",
144
+ "document_path": "https://enquiry.indianrail.gov.in",
145
+ "doc_category": "live_source",
146
+ "rule_type": "live_train_status",
147
+ "priority": 0,
148
+ "authority": "Indian Railways",
149
+ "is_static": false,
150
+ "effective_year": null,
151
+ "page_number": null,
152
+ "section_index": 1,
153
+ "chunk_index": 1,
154
+ "text": "Official live train running status system"
155
+ },
156
+ {
157
+ "chunk_id": "https:__www.irctc.co.in_pNone_s1_c1",
158
+ "document_path": "https://www.irctc.co.in",
159
+ "doc_category": "live_source",
160
+ "rule_type": "ticketing_platform",
161
+ "priority": 0,
162
+ "authority": "IRCTC",
163
+ "is_static": false,
164
+ "effective_year": null,
165
+ "page_number": null,
166
+ "section_index": 1,
167
+ "chunk_index": 1,
168
+ "text": "Official e-ticketing, catering and tourism portal"
169
+ },
170
+ {
171
+ "chunk_id": "https:__www.irctc.co.in_nget_enquiry_contactus_pNone_s1_c1",
172
+ "document_path": "https://www.irctc.co.in/nget/enquiry/contactus",
173
+ "doc_category": "live_source",
174
+ "rule_type": "customer_support",
175
+ "priority": 2,
176
+ "authority": "IRCTC",
177
+ "is_static": false,
178
+ "effective_year": null,
179
+ "page_number": null,
180
+ "section_index": 1,
181
+ "chunk_index": 1,
182
+ "text": "Customer support, grievance and escalation information"
183
+ },
184
+ {
185
+ "chunk_id": "https:__railmadad.indianrailways.gov.in_pNone_s1_c1",
186
+ "document_path": "https://railmadad.indianrailways.gov.in",
187
+ "doc_category": "live_source",
188
+ "rule_type": "grievance_emergency",
189
+ "priority": 0,
190
+ "authority": "Indian Railways",
191
+ "is_static": false,
192
+ "effective_year": null,
193
+ "page_number": null,
194
+ "section_index": 1,
195
+ "chunk_index": 1,
196
+ "text": "Emergency assistance and grievance redressal platform (139)"
197
+ },
198
+ {
199
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard__pNone_s1_c1",
200
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
201
+ "doc_category": "live_source",
202
+ "rule_type": "policy_authority",
203
+ "priority": 1,
204
+ "authority": "Railway Board",
205
+ "is_static": false,
206
+ "effective_year": null,
207
+ "page_number": null,
208
+ "section_index": 1,
209
+ "chunk_index": 1,
210
+ "text": "Top policy-making authority issuing circulars, manuals and instructions"
211
+ },
212
+ {
213
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304_pNone_s1_c1",
214
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
215
+ "doc_category": "live_source",
216
+ "rule_type": "traffic_rules",
217
+ "priority": 2,
218
+ "authority": "Railway Board",
219
+ "is_static": false,
220
+ "effective_year": null,
221
+ "page_number": null,
222
+ "section_index": 1,
223
+ "chunk_index": 1,
224
+ "text": "Traffic, operating and commercial circulars"
225
+ },
226
+ {
227
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304,366_pNone_s1_c1",
228
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304,366",
229
+ "doc_category": "live_source",
230
+ "rule_type": "safety_policy",
231
+ "priority": 1,
232
+ "authority": "Railway Board",
233
+ "is_static": false,
234
+ "effective_year": null,
235
+ "page_number": null,
236
+ "section_index": 1,
237
+ "chunk_index": 1,
238
+ "text": "Railway safety policies, manuals and advisories"
239
+ },
240
+ {
241
+ "chunk_id": "https:__crs.gov.in_Reports.aspx_pNone_s1_c1",
242
+ "document_path": "https://crs.gov.in/Reports.aspx",
243
+ "doc_category": "live_source",
244
+ "rule_type": "accident_inquiry",
245
+ "priority": 1,
246
+ "authority": "Ministry of Civil Aviation (CRS)",
247
+ "is_static": false,
248
+ "effective_year": null,
249
+ "page_number": null,
250
+ "section_index": 1,
251
+ "chunk_index": 1,
252
+ "text": "Independent accident inquiry and safety inspection reports"
253
+ },
254
+ {
255
+ "chunk_id": "https:__prs.indianrail.gov.in_pNone_s1_c1",
256
+ "document_path": "https://prs.indianrail.gov.in",
257
+ "doc_category": "live_source",
258
+ "rule_type": "reservation_backend",
259
+ "priority": 1,
260
+ "authority": "CRIS / Indian Railways",
261
+ "is_static": false,
262
+ "effective_year": null,
263
+ "page_number": null,
264
+ "section_index": 1,
265
+ "chunk_index": 1,
266
+ "text": "Backend reservation infrastructure of Indian Railways"
267
+ },
268
+ {
269
+ "chunk_id": "https:__cris.org.in_pNone_s1_c1",
270
+ "document_path": "https://cris.org.in",
271
+ "doc_category": "live_source",
272
+ "rule_type": "railway_it",
273
+ "priority": 2,
274
+ "authority": "Ministry of Railways",
275
+ "is_static": false,
276
+ "effective_year": null,
277
+ "page_number": null,
278
+ "section_index": 1,
279
+ "chunk_index": 1,
280
+ "text": "IT organization managing PRS, NTES, FOIS and operations software"
281
+ },
282
+ {
283
+ "chunk_id": "https:__www.fois.indianrail.gov.in_pNone_s1_c1",
284
+ "document_path": "https://www.fois.indianrail.gov.in",
285
+ "doc_category": "live_source",
286
+ "rule_type": "freight_tracking",
287
+ "priority": 1,
288
+ "authority": "Indian Railways",
289
+ "is_static": false,
290
+ "effective_year": null,
291
+ "page_number": null,
292
+ "section_index": 1,
293
+ "chunk_index": 1,
294
+ "text": "Freight booking, tracking and policy portal"
295
+ },
296
+ {
297
+ "chunk_id": "https:__dfccil.com_pNone_s1_c1",
298
+ "document_path": "https://dfccil.com",
299
+ "doc_category": "live_source",
300
+ "rule_type": "freight_infrastructure",
301
+ "priority": 3,
302
+ "authority": "Ministry of Railways",
303
+ "is_static": false,
304
+ "effective_year": null,
305
+ "page_number": null,
306
+ "section_index": 1,
307
+ "chunk_index": 1,
308
+ "text": "Dedicated freight corridor operations and rules"
309
+ },
310
+ {
311
+ "chunk_id": "https:__www.indianrail.gov.in_enquiry_StaticPages_StaticEnquiry.jsp?StaticPage=station_code.html_pNone_s1_c1",
312
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=station_code.html",
313
+ "doc_category": "live_source",
314
+ "rule_type": "station_reference",
315
+ "priority": 3,
316
+ "authority": "Indian Railways",
317
+ "is_static": false,
318
+ "effective_year": null,
319
+ "page_number": null,
320
+ "section_index": 1,
321
+ "chunk_index": 1,
322
+ "text": "Official station names and station codes list"
323
+ },
324
+ {
325
+ "chunk_id": "https:__www.indianrail.gov.in_enquiry_StaticPages_StaticEnquiry.jsp?StaticPage=conc_Rules.html_pNone_s1_c1",
326
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=conc_Rules.html",
327
+ "doc_category": "live_source",
328
+ "rule_type": "passenger_concessions",
329
+ "priority": 2,
330
+ "authority": "Indian Railways",
331
+ "is_static": false,
332
+ "effective_year": null,
333
+ "page_number": null,
334
+ "section_index": 1,
335
+ "chunk_index": 1,
336
+ "text": "Eligibility and rules for passenger fare concessions"
337
+ },
338
+ {
339
+ "chunk_id": "https:__www.rrbcdg.gov.in_pNone_s1_c1",
340
+ "document_path": "https://www.rrbcdg.gov.in",
341
+ "doc_category": "live_source",
342
+ "rule_type": "recruitment",
343
+ "priority": 4,
344
+ "authority": "Railway Recruitment Board",
345
+ "is_static": false,
346
+ "effective_year": null,
347
+ "page_number": null,
348
+ "section_index": 1,
349
+ "chunk_index": 1,
350
+ "text": "Recruitment notices, exams and results"
351
+ },
352
+ {
353
+ "chunk_id": "https:__rpf.indianrailways.gov.in_pNone_s1_c1",
354
+ "document_path": "https://rpf.indianrailways.gov.in",
355
+ "doc_category": "live_source",
356
+ "rule_type": "railway_security",
357
+ "priority": 2,
358
+ "authority": "Indian Railways",
359
+ "is_static": false,
360
+ "effective_year": null,
361
+ "page_number": null,
362
+ "section_index": 1,
363
+ "chunk_index": 1,
364
+ "text": "Railway security, passenger safety and law enforcement"
365
+ },
366
+ {
367
+ "chunk_id": "https:__www.ireps.gov.in_pNone_s1_c1",
368
+ "document_path": "https://www.ireps.gov.in",
369
+ "doc_category": "live_source",
370
+ "rule_type": "tenders_procurement",
371
+ "priority": 4,
372
+ "authority": "Indian Railways",
373
+ "is_static": false,
374
+ "effective_year": null,
375
+ "page_number": null,
376
+ "section_index": 1,
377
+ "chunk_index": 1,
378
+ "text": "Official procurement and tendering platform"
379
+ },
380
+ {
381
+ "chunk_id": "https:__nair.indianrailways.gov.in_pNone_s1_c1",
382
+ "document_path": "https://nair.indianrailways.gov.in",
383
+ "doc_category": "live_source",
384
+ "rule_type": "training",
385
+ "priority": 4,
386
+ "authority": "Indian Railways",
387
+ "is_static": false,
388
+ "effective_year": null,
389
+ "page_number": null,
390
+ "section_index": 1,
391
+ "chunk_index": 1,
392
+ "text": "Officer training material and manuals"
393
+ },
394
+ {
395
+ "chunk_id": "https:__www.iricen.gov.in_pNone_s1_c1",
396
+ "document_path": "https://www.iricen.gov.in",
397
+ "doc_category": "live_source",
398
+ "rule_type": "track_engineering",
399
+ "priority": 3,
400
+ "authority": "Indian Railways",
401
+ "is_static": false,
402
+ "effective_year": null,
403
+ "page_number": null,
404
+ "section_index": 1,
405
+ "chunk_index": 1,
406
+ "text": "Track engineering manuals and technical guidance"
407
+ },
408
+ {
409
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304_pNone_s1_c1",
410
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
411
+ "doc_category": "live_source",
412
+ "rule_type": "zonal_information",
413
+ "priority": 4,
414
+ "authority": "Indian Railways",
415
+ "is_static": false,
416
+ "effective_year": null,
417
+ "page_number": null,
418
+ "section_index": 1,
419
+ "chunk_index": 1,
420
+ "text": "Links to all zonal railway websites for zone-specific rules"
421
+ },
422
+ {
423
+ "chunk_id": "https:__whereismytrain.in_pNone_s1_c1",
424
+ "document_path": "https://whereismytrain.in",
425
+ "doc_category": "live_source",
426
+ "rule_type": "live_train_tracking",
427
+ "priority": 5,
428
+ "authority": "Unofficial (Google)",
429
+ "is_static": false,
430
+ "effective_year": null,
431
+ "page_number": null,
432
+ "section_index": 1,
433
+ "chunk_index": 1,
434
+ "text": "Widely used live train tracking app and website using crowd-sourced and offline data"
435
+ },
436
+ {
437
+ "chunk_id": "https:__erail.in_pNone_s1_c1",
438
+ "document_path": "https://erail.in",
439
+ "doc_category": "live_source",
440
+ "rule_type": "train_schedule_route",
441
+ "priority": 5,
442
+ "authority": "Unofficial",
443
+ "is_static": false,
444
+ "effective_year": null,
445
+ "page_number": null,
446
+ "section_index": 1,
447
+ "chunk_index": 1,
448
+ "text": "Reliable source for train schedules, routes, stations and timetables"
449
+ },
450
+ {
451
+ "chunk_id": "https:__indiarailinfo.com_pNone_s1_c1",
452
+ "document_path": "https://indiarailinfo.com",
453
+ "doc_category": "live_source",
454
+ "rule_type": "community_updates",
455
+ "priority": 5,
456
+ "authority": "Community-driven",
457
+ "is_static": false,
458
+ "effective_year": null,
459
+ "page_number": null,
460
+ "section_index": 1,
461
+ "chunk_index": 1,
462
+ "text": "Crowdsourced train running updates, delays, spotting and route discussions"
463
+ },
464
+ {
465
+ "chunk_id": "https:__www.railyatri.in_pNone_s1_c1",
466
+ "document_path": "https://www.railyatri.in",
467
+ "doc_category": "live_source",
468
+ "rule_type": "pnr_live_status",
469
+ "priority": 5,
470
+ "authority": "Private",
471
+ "is_static": false,
472
+ "effective_year": null,
473
+ "page_number": null,
474
+ "section_index": 1,
475
+ "chunk_index": 1,
476
+ "text": "PNR status, live train status and passenger utilities"
477
+ },
478
+ {
479
+ "chunk_id": "https:__www.ixigo.com_trains_pNone_s1_c1",
480
+ "document_path": "https://www.ixigo.com/trains",
481
+ "doc_category": "live_source",
482
+ "rule_type": "train_search",
483
+ "priority": 5,
484
+ "authority": "Private",
485
+ "is_static": false,
486
+ "effective_year": null,
487
+ "page_number": null,
488
+ "section_index": 1,
489
+ "chunk_index": 1,
490
+ "text": "Train search, live status and delay analytics"
491
+ },
492
+ {
493
+ "chunk_id": "https:__www.confirmtkt.com_pNone_s1_c1",
494
+ "document_path": "https://www.confirmtkt.com",
495
+ "doc_category": "live_source",
496
+ "rule_type": "seat_prediction",
497
+ "priority": 5,
498
+ "authority": "Private",
499
+ "is_static": false,
500
+ "effective_year": null,
501
+ "page_number": null,
502
+ "section_index": 1,
503
+ "chunk_index": 1,
504
+ "text": "Seat availability prediction and PNR insights"
505
+ },
506
+ {
507
+ "chunk_id": "https:__www.trainman.in_pNone_s1_c1",
508
+ "document_path": "https://www.trainman.in",
509
+ "doc_category": "live_source",
510
+ "rule_type": "pnr_prediction",
511
+ "priority": 5,
512
+ "authority": "Private",
513
+ "is_static": false,
514
+ "effective_year": null,
515
+ "page_number": null,
516
+ "section_index": 1,
517
+ "chunk_index": 1,
518
+ "text": "PNR status prediction and train information"
519
+ },
520
+ {
521
+ "chunk_id": "https:__www.makemytrip.com_railways_pNone_s1_c1",
522
+ "document_path": "https://www.makemytrip.com/railways",
523
+ "doc_category": "live_source",
524
+ "rule_type": "ticketing_aggregator",
525
+ "priority": 5,
526
+ "authority": "Private",
527
+ "is_static": false,
528
+ "effective_year": null,
529
+ "page_number": null,
530
+ "section_index": 1,
531
+ "chunk_index": 1,
532
+ "text": "Railway ticket booking and enquiry platform"
533
+ },
534
+ {
535
+ "chunk_id": "https:__www.goibibo.com_trains_pNone_s1_c1",
536
+ "document_path": "https://www.goibibo.com/trains",
537
+ "doc_category": "live_source",
538
+ "rule_type": "ticketing_aggregator",
539
+ "priority": 5,
540
+ "authority": "Private",
541
+ "is_static": false,
542
+ "effective_year": null,
543
+ "page_number": null,
544
+ "section_index": 1,
545
+ "chunk_index": 1,
546
+ "text": "Train search and booking aggregator"
547
+ },
548
+ {
549
+ "chunk_id": "https:__paytm.com_train-tickets_pNone_s1_c1",
550
+ "document_path": "https://paytm.com/train-tickets",
551
+ "doc_category": "live_source",
552
+ "rule_type": "ticketing_aggregator",
553
+ "priority": 5,
554
+ "authority": "Private",
555
+ "is_static": false,
556
+ "effective_year": null,
557
+ "page_number": null,
558
+ "section_index": 1,
559
+ "chunk_index": 1,
560
+ "text": "Train ticket booking, PNR and live status tools"
561
+ },
562
+ {
563
+ "chunk_id": "https:__www.redbus.in_railways_pNone_s1_c1",
564
+ "document_path": "https://www.redbus.in/railways",
565
+ "doc_category": "live_source",
566
+ "rule_type": "ticketing_aggregator",
567
+ "priority": 5,
568
+ "authority": "Private",
569
+ "is_static": false,
570
+ "effective_year": null,
571
+ "page_number": null,
572
+ "section_index": 1,
573
+ "chunk_index": 1,
574
+ "text": "Rail ticket booking and enquiry features"
575
+ },
576
+ {
577
+ "chunk_id": "https:__railradar.railyatri.in_pNone_s1_c1",
578
+ "document_path": "https://railradar.railyatri.in",
579
+ "doc_category": "live_source",
580
+ "rule_type": "live_map_tracking",
581
+ "priority": 5,
582
+ "authority": "Private",
583
+ "is_static": false,
584
+ "effective_year": null,
585
+ "page_number": null,
586
+ "section_index": 1,
587
+ "chunk_index": 1,
588
+ "text": "Map-based visualization of live train movement"
589
+ },
590
+ {
591
+ "chunk_id": "https:__www.openrailwaymap.org_pNone_s1_c1",
592
+ "document_path": "https://www.openrailwaymap.org",
593
+ "doc_category": "live_source",
594
+ "rule_type": "railway_map",
595
+ "priority": 5,
596
+ "authority": "Open-source",
597
+ "is_static": false,
598
+ "effective_year": null,
599
+ "page_number": null,
600
+ "section_index": 1,
601
+ "chunk_index": 1,
602
+ "text": "Detailed open-source railway infrastructure maps"
603
+ },
604
+ {
605
+ "chunk_id": "https:__www.mapsofindia.com_railway-map_pNone_s1_c1",
606
+ "document_path": "https://www.mapsofindia.com/railway-map",
607
+ "doc_category": "live_source",
608
+ "rule_type": "railway_map",
609
+ "priority": 5,
610
+ "authority": "Private",
611
+ "is_static": false,
612
+ "effective_year": null,
613
+ "page_number": null,
614
+ "section_index": 1,
615
+ "chunk_index": 1,
616
+ "text": "Visual maps of Indian railway zones and routes"
617
+ },
618
+ {
619
+ "chunk_id": "https:__en.wikipedia.org_wiki_Indian_Railways_pNone_s1_c1",
620
+ "document_path": "https://en.wikipedia.org/wiki/Indian_Railways",
621
+ "doc_category": "live_source",
622
+ "rule_type": "encyclopedic_reference",
623
+ "priority": 5,
624
+ "authority": "Community",
625
+ "is_static": false,
626
+ "effective_year": null,
627
+ "page_number": null,
628
+ "section_index": 1,
629
+ "chunk_index": 1,
630
+ "text": "General background, history and overview of Indian Railways"
631
+ },
632
+ {
633
+ "chunk_id": "https:__www.wikidata.org_wiki_Q1442_pNone_s1_c1",
634
+ "document_path": "https://www.wikidata.org/wiki/Q1442",
635
+ "doc_category": "live_source",
636
+ "rule_type": "structured_data",
637
+ "priority": 5,
638
+ "authority": "Open knowledge",
639
+ "is_static": false,
640
+ "effective_year": null,
641
+ "page_number": null,
642
+ "section_index": 1,
643
+ "chunk_index": 1,
644
+ "text": "Structured knowledge graph for Indian Railways entities"
645
+ },
646
+ {
647
+ "chunk_id": "https:__www.ndtv.com_topic_indian-railways_pNone_s1_c1",
648
+ "document_path": "https://www.ndtv.com/topic/indian-railways",
649
+ "doc_category": "live_source",
650
+ "rule_type": "railway_news",
651
+ "priority": 5,
652
+ "authority": "Media",
653
+ "is_static": false,
654
+ "effective_year": null,
655
+ "page_number": null,
656
+ "section_index": 1,
657
+ "chunk_index": 1,
658
+ "text": "News coverage related to Indian Railways"
659
+ },
660
+ {
661
+ "chunk_id": "https:__www.thehindu.com_topic_indian_railways__pNone_s1_c1",
662
+ "document_path": "https://www.thehindu.com/topic/indian_railways/",
663
+ "doc_category": "live_source",
664
+ "rule_type": "railway_news",
665
+ "priority": 5,
666
+ "authority": "Media",
667
+ "is_static": false,
668
+ "effective_year": null,
669
+ "page_number": null,
670
+ "section_index": 1,
671
+ "chunk_index": 1,
672
+ "text": "Policy, safety and operational news on railways"
673
+ },
674
+ {
675
+ "chunk_id": "https:__www.livemint.com_industry_railways_pNone_s1_c1",
676
+ "document_path": "https://www.livemint.com/industry/railways",
677
+ "doc_category": "live_source",
678
+ "rule_type": "railway_policy_news",
679
+ "priority": 5,
680
+ "authority": "Media",
681
+ "is_static": false,
682
+ "effective_year": null,
683
+ "page_number": null,
684
+ "section_index": 1,
685
+ "chunk_index": 1,
686
+ "text": "Economic and policy analysis of Indian Railways"
687
+ },
688
+ {
689
+ "chunk_id": "https:__www.reddit.com_r_IndianRailways_pNone_s1_c1",
690
+ "document_path": "https://www.reddit.com/r/IndianRailways",
691
+ "doc_category": "live_source",
692
+ "rule_type": "community_discussion",
693
+ "priority": 5,
694
+ "authority": "Community",
695
+ "is_static": false,
696
+ "effective_year": null,
697
+ "page_number": null,
698
+ "section_index": 1,
699
+ "chunk_index": 1,
700
+ "text": "Community discussions, photos and experiences"
701
+ },
702
+ {
703
+ "chunk_id": "https:__www.quora.com_topic_Indian-Railways_pNone_s1_c1",
704
+ "document_path": "https://www.quora.com/topic/Indian-Railways",
705
+ "doc_category": "live_source",
706
+ "rule_type": "community_qna",
707
+ "priority": 5,
708
+ "authority": "Community",
709
+ "is_static": false,
710
+ "effective_year": null,
711
+ "page_number": null,
712
+ "section_index": 1,
713
+ "chunk_index": 1,
714
+ "text": "Community Q&A related to Indian Railways"
715
+ },
716
+ {
717
+ "chunk_id": "https:__www.youtube.com_results?search_query=indian+railways_pNone_s1_c1",
718
+ "document_path": "https://www.youtube.com/results?search_query=indian+railways",
719
+ "doc_category": "live_source",
720
+ "rule_type": "video_reference",
721
+ "priority": 5,
722
+ "authority": "Media / Community",
723
+ "is_static": false,
724
+ "effective_year": null,
725
+ "page_number": null,
726
+ "section_index": 1,
727
+ "chunk_index": 1,
728
+ "text": "Videos on train journeys, reviews, and railway operations"
729
+ }
730
+ ]
data/extracted_text/circulars.json ADDED
The diff for this file is too large to render. See raw diff
 
data/extracted_text/core_docs.json ADDED
The diff for this file is too large to render. See raw diff
 
data/extracted_text/live_sources.json ADDED
@@ -0,0 +1,678 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "document_name": "India Code – Railways Act, 1989",
4
+ "document_path": "https://www.indiacode.nic.in/handle/123456789/2362",
5
+ "doc_category": "live_source",
6
+ "rule_type": "law",
7
+ "priority": 1,
8
+ "authority": "Government of India",
9
+ "description": "Official and updated text of the Railways Act, 1989 including amendments",
10
+ "is_static": false,
11
+ "effective_year": null,
12
+ "page_number": null,
13
+ "text": "Official and updated text of the Railways Act, 1989 including amendments"
14
+ },
15
+ {
16
+ "document_name": "Railway Board Circulars & Orders",
17
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
18
+ "doc_category": "live_source",
19
+ "rule_type": "circular",
20
+ "priority": 2,
21
+ "authority": "Railway Board",
22
+ "description": "Latest railway rules, circulars, policy letters and amendments issued by Railway Board",
23
+ "is_static": false,
24
+ "effective_year": null,
25
+ "page_number": null,
26
+ "text": "Latest railway rules, circulars, policy letters and amendments issued by Railway Board"
27
+ },
28
+ {
29
+ "document_name": "IRCTC Rules & Policies",
30
+ "document_path": "https://www.irctc.co.in/nget/enquiry/termsAndConditions",
31
+ "doc_category": "live_source",
32
+ "rule_type": "passenger_rules",
33
+ "priority": 3,
34
+ "authority": "IRCTC",
35
+ "description": "Latest passenger-facing rules including booking, cancellation, refund and TDR policies",
36
+ "is_static": false,
37
+ "effective_year": null,
38
+ "page_number": null,
39
+ "text": "Latest passenger-facing rules including booking, cancellation, refund and TDR policies"
40
+ },
41
+ {
42
+ "document_name": "IRCTC Refund & Cancellation Rules",
43
+ "document_path": "https://contents.irctc.co.in/en/RefundCancellationRules.pdf",
44
+ "doc_category": "live_source",
45
+ "rule_type": "refund",
46
+ "priority": 3,
47
+ "authority": "IRCTC",
48
+ "description": "Official refund and cancellation rules PDF maintained by IRCTC",
49
+ "is_static": false,
50
+ "effective_year": null,
51
+ "page_number": null,
52
+ "text": "Official refund and cancellation rules PDF maintained by IRCTC"
53
+ },
54
+ {
55
+ "document_name": "RailMadad – Passenger Grievance & Emergency",
56
+ "document_path": "https://railmadad.indianrailways.gov.in",
57
+ "doc_category": "live_source",
58
+ "rule_type": "grievance_emergency",
59
+ "priority": 0,
60
+ "authority": "Indian Railways",
61
+ "description": "Official grievance redressal and emergency assistance portal (includes helpline 139)",
62
+ "is_static": false,
63
+ "effective_year": null,
64
+ "page_number": null,
65
+ "text": "Official grievance redressal and emergency assistance portal (includes helpline 139)"
66
+ },
67
+ {
68
+ "document_name": "Commissioner of Railway Safety",
69
+ "document_path": "https://crs.gov.in",
70
+ "doc_category": "live_source",
71
+ "rule_type": "safety",
72
+ "priority": 2,
73
+ "authority": "Ministry of Civil Aviation (Rail Safety)",
74
+ "description": "Railway safety rules, accident inquiries and safety manuals",
75
+ "is_static": false,
76
+ "effective_year": null,
77
+ "page_number": null,
78
+ "text": "Railway safety rules, accident inquiries and safety manuals"
79
+ },
80
+ {
81
+ "document_name": "Passenger Amenities – Indian Railways",
82
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,2,287",
83
+ "doc_category": "live_source",
84
+ "rule_type": "passenger_amenities",
85
+ "priority": 4,
86
+ "authority": "Railway Board",
87
+ "description": "Official passenger amenities policies and standards at stations and trains",
88
+ "is_static": false,
89
+ "effective_year": null,
90
+ "page_number": null,
91
+ "text": "Official passenger amenities policies and standards at stations and trains"
92
+ },
93
+ {
94
+ "document_name": "Railway Claims Tribunal",
95
+ "document_path": "https://rct.indianrailways.gov.in",
96
+ "doc_category": "live_source",
97
+ "rule_type": "claims_compensation",
98
+ "priority": 2,
99
+ "authority": "Government of India",
100
+ "description": "Compensation, refund and claims procedures related to railway accidents and losses",
101
+ "is_static": false,
102
+ "effective_year": null,
103
+ "page_number": null,
104
+ "text": "Compensation, refund and claims procedures related to railway accidents and losses"
105
+ },
106
+ {
107
+ "document_name": "Indian Railways Official Website",
108
+ "document_path": "https://indianrailways.gov.in",
109
+ "doc_category": "live_source",
110
+ "rule_type": "official_portal",
111
+ "priority": 1,
112
+ "authority": "Ministry of Railways, Government of India",
113
+ "description": "Primary official portal for Indian Railways policies, notices, tenders and updates",
114
+ "is_static": false,
115
+ "effective_year": null,
116
+ "page_number": null,
117
+ "text": "Primary official portal for Indian Railways policies, notices, tenders and updates"
118
+ },
119
+ {
120
+ "document_name": "Indian Railways Passenger Enquiry",
121
+ "document_path": "https://www.indianrail.gov.in",
122
+ "doc_category": "live_source",
123
+ "rule_type": "passenger_enquiry",
124
+ "priority": 0,
125
+ "authority": "Indian Railways",
126
+ "description": "Passenger-facing enquiry system for schedules, routes, fares and availability",
127
+ "is_static": false,
128
+ "effective_year": null,
129
+ "page_number": null,
130
+ "text": "Passenger-facing enquiry system for schedules, routes, fares and availability"
131
+ },
132
+ {
133
+ "document_name": "National Train Enquiry System (NTES)",
134
+ "document_path": "https://enquiry.indianrail.gov.in",
135
+ "doc_category": "live_source",
136
+ "rule_type": "live_train_status",
137
+ "priority": 0,
138
+ "authority": "Indian Railways",
139
+ "description": "Official live train running status system",
140
+ "is_static": false,
141
+ "effective_year": null,
142
+ "page_number": null,
143
+ "text": "Official live train running status system"
144
+ },
145
+ {
146
+ "document_name": "IRCTC Official Portal",
147
+ "document_path": "https://www.irctc.co.in",
148
+ "doc_category": "live_source",
149
+ "rule_type": "ticketing_platform",
150
+ "priority": 0,
151
+ "authority": "IRCTC",
152
+ "description": "Official e-ticketing, catering and tourism portal",
153
+ "is_static": false,
154
+ "effective_year": null,
155
+ "page_number": null,
156
+ "text": "Official e-ticketing, catering and tourism portal"
157
+ },
158
+ {
159
+ "document_name": "IRCTC Help & Customer Care",
160
+ "document_path": "https://www.irctc.co.in/nget/enquiry/contactus",
161
+ "doc_category": "live_source",
162
+ "rule_type": "customer_support",
163
+ "priority": 2,
164
+ "authority": "IRCTC",
165
+ "description": "Customer support, grievance and escalation information",
166
+ "is_static": false,
167
+ "effective_year": null,
168
+ "page_number": null,
169
+ "text": "Customer support, grievance and escalation information"
170
+ },
171
+ {
172
+ "document_name": "RailMadad Grievance Portal",
173
+ "document_path": "https://railmadad.indianrailways.gov.in",
174
+ "doc_category": "live_source",
175
+ "rule_type": "grievance_emergency",
176
+ "priority": 0,
177
+ "authority": "Indian Railways",
178
+ "description": "Emergency assistance and grievance redressal platform (139)",
179
+ "is_static": false,
180
+ "effective_year": null,
181
+ "page_number": null,
182
+ "text": "Emergency assistance and grievance redressal platform (139)"
183
+ },
184
+ {
185
+ "document_name": "Railway Board",
186
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
187
+ "doc_category": "live_source",
188
+ "rule_type": "policy_authority",
189
+ "priority": 1,
190
+ "authority": "Railway Board",
191
+ "description": "Top policy-making authority issuing circulars, manuals and instructions",
192
+ "is_static": false,
193
+ "effective_year": null,
194
+ "page_number": null,
195
+ "text": "Top policy-making authority issuing circulars, manuals and instructions"
196
+ },
197
+ {
198
+ "document_name": "Railway Board – Traffic Directorate",
199
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
200
+ "doc_category": "live_source",
201
+ "rule_type": "traffic_rules",
202
+ "priority": 2,
203
+ "authority": "Railway Board",
204
+ "description": "Traffic, operating and commercial circulars",
205
+ "is_static": false,
206
+ "effective_year": null,
207
+ "page_number": null,
208
+ "text": "Traffic, operating and commercial circulars"
209
+ },
210
+ {
211
+ "document_name": "Railway Board – Safety Directorate",
212
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304,366",
213
+ "doc_category": "live_source",
214
+ "rule_type": "safety_policy",
215
+ "priority": 1,
216
+ "authority": "Railway Board",
217
+ "description": "Railway safety policies, manuals and advisories",
218
+ "is_static": false,
219
+ "effective_year": null,
220
+ "page_number": null,
221
+ "text": "Railway safety policies, manuals and advisories"
222
+ },
223
+ {
224
+ "document_name": "Commissioner of Railway Safety Reports",
225
+ "document_path": "https://crs.gov.in/Reports.aspx",
226
+ "doc_category": "live_source",
227
+ "rule_type": "accident_inquiry",
228
+ "priority": 1,
229
+ "authority": "Ministry of Civil Aviation (CRS)",
230
+ "description": "Independent accident inquiry and safety inspection reports",
231
+ "is_static": false,
232
+ "effective_year": null,
233
+ "page_number": null,
234
+ "text": "Independent accident inquiry and safety inspection reports"
235
+ },
236
+ {
237
+ "document_name": "Passenger Reservation System (PRS)",
238
+ "document_path": "https://prs.indianrail.gov.in",
239
+ "doc_category": "live_source",
240
+ "rule_type": "reservation_backend",
241
+ "priority": 1,
242
+ "authority": "CRIS / Indian Railways",
243
+ "description": "Backend reservation infrastructure of Indian Railways",
244
+ "is_static": false,
245
+ "effective_year": null,
246
+ "page_number": null,
247
+ "text": "Backend reservation infrastructure of Indian Railways"
248
+ },
249
+ {
250
+ "document_name": "Centre for Railway Information Systems (CRIS)",
251
+ "document_path": "https://cris.org.in",
252
+ "doc_category": "live_source",
253
+ "rule_type": "railway_it",
254
+ "priority": 2,
255
+ "authority": "Ministry of Railways",
256
+ "description": "IT organization managing PRS, NTES, FOIS and operations software",
257
+ "is_static": false,
258
+ "effective_year": null,
259
+ "page_number": null,
260
+ "text": "IT organization managing PRS, NTES, FOIS and operations software"
261
+ },
262
+ {
263
+ "document_name": "Freight Operations Information System (FOIS)",
264
+ "document_path": "https://www.fois.indianrail.gov.in",
265
+ "doc_category": "live_source",
266
+ "rule_type": "freight_tracking",
267
+ "priority": 1,
268
+ "authority": "Indian Railways",
269
+ "description": "Freight booking, tracking and policy portal",
270
+ "is_static": false,
271
+ "effective_year": null,
272
+ "page_number": null,
273
+ "text": "Freight booking, tracking and policy portal"
274
+ },
275
+ {
276
+ "document_name": "Dedicated Freight Corridor Corporation",
277
+ "document_path": "https://dfccil.com",
278
+ "doc_category": "live_source",
279
+ "rule_type": "freight_infrastructure",
280
+ "priority": 3,
281
+ "authority": "Ministry of Railways",
282
+ "description": "Dedicated freight corridor operations and rules",
283
+ "is_static": false,
284
+ "effective_year": null,
285
+ "page_number": null,
286
+ "text": "Dedicated freight corridor operations and rules"
287
+ },
288
+ {
289
+ "document_name": "Station Codes Directory",
290
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=station_code.html",
291
+ "doc_category": "live_source",
292
+ "rule_type": "station_reference",
293
+ "priority": 3,
294
+ "authority": "Indian Railways",
295
+ "description": "Official station names and station codes list",
296
+ "is_static": false,
297
+ "effective_year": null,
298
+ "page_number": null,
299
+ "text": "Official station names and station codes list"
300
+ },
301
+ {
302
+ "document_name": "Passenger Concession Rules",
303
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=conc_Rules.html",
304
+ "doc_category": "live_source",
305
+ "rule_type": "passenger_concessions",
306
+ "priority": 2,
307
+ "authority": "Indian Railways",
308
+ "description": "Eligibility and rules for passenger fare concessions",
309
+ "is_static": false,
310
+ "effective_year": null,
311
+ "page_number": null,
312
+ "text": "Eligibility and rules for passenger fare concessions"
313
+ },
314
+ {
315
+ "document_name": "Railway Recruitment Boards",
316
+ "document_path": "https://www.rrbcdg.gov.in",
317
+ "doc_category": "live_source",
318
+ "rule_type": "recruitment",
319
+ "priority": 4,
320
+ "authority": "Railway Recruitment Board",
321
+ "description": "Recruitment notices, exams and results",
322
+ "is_static": false,
323
+ "effective_year": null,
324
+ "page_number": null,
325
+ "text": "Recruitment notices, exams and results"
326
+ },
327
+ {
328
+ "document_name": "Railway Protection Force",
329
+ "document_path": "https://rpf.indianrailways.gov.in",
330
+ "doc_category": "live_source",
331
+ "rule_type": "railway_security",
332
+ "priority": 2,
333
+ "authority": "Indian Railways",
334
+ "description": "Railway security, passenger safety and law enforcement",
335
+ "is_static": false,
336
+ "effective_year": null,
337
+ "page_number": null,
338
+ "text": "Railway security, passenger safety and law enforcement"
339
+ },
340
+ {
341
+ "document_name": "Indian Railways E-Procurement",
342
+ "document_path": "https://www.ireps.gov.in",
343
+ "doc_category": "live_source",
344
+ "rule_type": "tenders_procurement",
345
+ "priority": 4,
346
+ "authority": "Indian Railways",
347
+ "description": "Official procurement and tendering platform",
348
+ "is_static": false,
349
+ "effective_year": null,
350
+ "page_number": null,
351
+ "text": "Official procurement and tendering platform"
352
+ },
353
+ {
354
+ "document_name": "National Academy of Indian Railways",
355
+ "document_path": "https://nair.indianrailways.gov.in",
356
+ "doc_category": "live_source",
357
+ "rule_type": "training",
358
+ "priority": 4,
359
+ "authority": "Indian Railways",
360
+ "description": "Officer training material and manuals",
361
+ "is_static": false,
362
+ "effective_year": null,
363
+ "page_number": null,
364
+ "text": "Officer training material and manuals"
365
+ },
366
+ {
367
+ "document_name": "IRICEN Track Engineering",
368
+ "document_path": "https://www.iricen.gov.in",
369
+ "doc_category": "live_source",
370
+ "rule_type": "track_engineering",
371
+ "priority": 3,
372
+ "authority": "Indian Railways",
373
+ "description": "Track engineering manuals and technical guidance",
374
+ "is_static": false,
375
+ "effective_year": null,
376
+ "page_number": null,
377
+ "text": "Track engineering manuals and technical guidance"
378
+ },
379
+ {
380
+ "document_name": "Zonal Railways Websites Directory",
381
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
382
+ "doc_category": "live_source",
383
+ "rule_type": "zonal_information",
384
+ "priority": 4,
385
+ "authority": "Indian Railways",
386
+ "description": "Links to all zonal railway websites for zone-specific rules",
387
+ "is_static": false,
388
+ "effective_year": null,
389
+ "page_number": null,
390
+ "text": "Links to all zonal railway websites for zone-specific rules"
391
+ },
392
+ {
393
+ "document_name": "Where Is My Train",
394
+ "document_path": "https://whereismytrain.in",
395
+ "doc_category": "live_source",
396
+ "rule_type": "live_train_tracking",
397
+ "priority": 5,
398
+ "authority": "Unofficial (Google)",
399
+ "description": "Widely used live train tracking app and website using crowd-sourced and offline data",
400
+ "is_static": false,
401
+ "effective_year": null,
402
+ "page_number": null,
403
+ "text": "Widely used live train tracking app and website using crowd-sourced and offline data"
404
+ },
405
+ {
406
+ "document_name": "eRail",
407
+ "document_path": "https://erail.in",
408
+ "doc_category": "live_source",
409
+ "rule_type": "train_schedule_route",
410
+ "priority": 5,
411
+ "authority": "Unofficial",
412
+ "description": "Reliable source for train schedules, routes, stations and timetables",
413
+ "is_static": false,
414
+ "effective_year": null,
415
+ "page_number": null,
416
+ "text": "Reliable source for train schedules, routes, stations and timetables"
417
+ },
418
+ {
419
+ "document_name": "India Rail Info",
420
+ "document_path": "https://indiarailinfo.com",
421
+ "doc_category": "live_source",
422
+ "rule_type": "community_updates",
423
+ "priority": 5,
424
+ "authority": "Community-driven",
425
+ "description": "Crowdsourced train running updates, delays, spotting and route discussions",
426
+ "is_static": false,
427
+ "effective_year": null,
428
+ "page_number": null,
429
+ "text": "Crowdsourced train running updates, delays, spotting and route discussions"
430
+ },
431
+ {
432
+ "document_name": "RailYatri",
433
+ "document_path": "https://www.railyatri.in",
434
+ "doc_category": "live_source",
435
+ "rule_type": "pnr_live_status",
436
+ "priority": 5,
437
+ "authority": "Private",
438
+ "description": "PNR status, live train status and passenger utilities",
439
+ "is_static": false,
440
+ "effective_year": null,
441
+ "page_number": null,
442
+ "text": "PNR status, live train status and passenger utilities"
443
+ },
444
+ {
445
+ "document_name": "Ixigo Trains",
446
+ "document_path": "https://www.ixigo.com/trains",
447
+ "doc_category": "live_source",
448
+ "rule_type": "train_search",
449
+ "priority": 5,
450
+ "authority": "Private",
451
+ "description": "Train search, live status and delay analytics",
452
+ "is_static": false,
453
+ "effective_year": null,
454
+ "page_number": null,
455
+ "text": "Train search, live status and delay analytics"
456
+ },
457
+ {
458
+ "document_name": "ConfirmTkt",
459
+ "document_path": "https://www.confirmtkt.com",
460
+ "doc_category": "live_source",
461
+ "rule_type": "seat_prediction",
462
+ "priority": 5,
463
+ "authority": "Private",
464
+ "description": "Seat availability prediction and PNR insights",
465
+ "is_static": false,
466
+ "effective_year": null,
467
+ "page_number": null,
468
+ "text": "Seat availability prediction and PNR insights"
469
+ },
470
+ {
471
+ "document_name": "Trainman",
472
+ "document_path": "https://www.trainman.in",
473
+ "doc_category": "live_source",
474
+ "rule_type": "pnr_prediction",
475
+ "priority": 5,
476
+ "authority": "Private",
477
+ "description": "PNR status prediction and train information",
478
+ "is_static": false,
479
+ "effective_year": null,
480
+ "page_number": null,
481
+ "text": "PNR status prediction and train information"
482
+ },
483
+ {
484
+ "document_name": "MakeMyTrip Railways",
485
+ "document_path": "https://www.makemytrip.com/railways",
486
+ "doc_category": "live_source",
487
+ "rule_type": "ticketing_aggregator",
488
+ "priority": 5,
489
+ "authority": "Private",
490
+ "description": "Railway ticket booking and enquiry platform",
491
+ "is_static": false,
492
+ "effective_year": null,
493
+ "page_number": null,
494
+ "text": "Railway ticket booking and enquiry platform"
495
+ },
496
+ {
497
+ "document_name": "Goibibo Trains",
498
+ "document_path": "https://www.goibibo.com/trains",
499
+ "doc_category": "live_source",
500
+ "rule_type": "ticketing_aggregator",
501
+ "priority": 5,
502
+ "authority": "Private",
503
+ "description": "Train search and booking aggregator",
504
+ "is_static": false,
505
+ "effective_year": null,
506
+ "page_number": null,
507
+ "text": "Train search and booking aggregator"
508
+ },
509
+ {
510
+ "document_name": "Paytm Trains",
511
+ "document_path": "https://paytm.com/train-tickets",
512
+ "doc_category": "live_source",
513
+ "rule_type": "ticketing_aggregator",
514
+ "priority": 5,
515
+ "authority": "Private",
516
+ "description": "Train ticket booking, PNR and live status tools",
517
+ "is_static": false,
518
+ "effective_year": null,
519
+ "page_number": null,
520
+ "text": "Train ticket booking, PNR and live status tools"
521
+ },
522
+ {
523
+ "document_name": "redBus Railways",
524
+ "document_path": "https://www.redbus.in/railways",
525
+ "doc_category": "live_source",
526
+ "rule_type": "ticketing_aggregator",
527
+ "priority": 5,
528
+ "authority": "Private",
529
+ "description": "Rail ticket booking and enquiry features",
530
+ "is_static": false,
531
+ "effective_year": null,
532
+ "page_number": null,
533
+ "text": "Rail ticket booking and enquiry features"
534
+ },
535
+ {
536
+ "document_name": "RailRadar by RailYatri",
537
+ "document_path": "https://railradar.railyatri.in",
538
+ "doc_category": "live_source",
539
+ "rule_type": "live_map_tracking",
540
+ "priority": 5,
541
+ "authority": "Private",
542
+ "description": "Map-based visualization of live train movement",
543
+ "is_static": false,
544
+ "effective_year": null,
545
+ "page_number": null,
546
+ "text": "Map-based visualization of live train movement"
547
+ },
548
+ {
549
+ "document_name": "OpenRailwayMap",
550
+ "document_path": "https://www.openrailwaymap.org",
551
+ "doc_category": "live_source",
552
+ "rule_type": "railway_map",
553
+ "priority": 5,
554
+ "authority": "Open-source",
555
+ "description": "Detailed open-source railway infrastructure maps",
556
+ "is_static": false,
557
+ "effective_year": null,
558
+ "page_number": null,
559
+ "text": "Detailed open-source railway infrastructure maps"
560
+ },
561
+ {
562
+ "document_name": "Maps of India – Railway Map",
563
+ "document_path": "https://www.mapsofindia.com/railway-map",
564
+ "doc_category": "live_source",
565
+ "rule_type": "railway_map",
566
+ "priority": 5,
567
+ "authority": "Private",
568
+ "description": "Visual maps of Indian railway zones and routes",
569
+ "is_static": false,
570
+ "effective_year": null,
571
+ "page_number": null,
572
+ "text": "Visual maps of Indian railway zones and routes"
573
+ },
574
+ {
575
+ "document_name": "Wikipedia – Indian Railways",
576
+ "document_path": "https://en.wikipedia.org/wiki/Indian_Railways",
577
+ "doc_category": "live_source",
578
+ "rule_type": "encyclopedic_reference",
579
+ "priority": 5,
580
+ "authority": "Community",
581
+ "description": "General background, history and overview of Indian Railways",
582
+ "is_static": false,
583
+ "effective_year": null,
584
+ "page_number": null,
585
+ "text": "General background, history and overview of Indian Railways"
586
+ },
587
+ {
588
+ "document_name": "Wikidata – Indian Railways",
589
+ "document_path": "https://www.wikidata.org/wiki/Q1442",
590
+ "doc_category": "live_source",
591
+ "rule_type": "structured_data",
592
+ "priority": 5,
593
+ "authority": "Open knowledge",
594
+ "description": "Structured knowledge graph for Indian Railways entities",
595
+ "is_static": false,
596
+ "effective_year": null,
597
+ "page_number": null,
598
+ "text": "Structured knowledge graph for Indian Railways entities"
599
+ },
600
+ {
601
+ "document_name": "NDTV – Indian Railways",
602
+ "document_path": "https://www.ndtv.com/topic/indian-railways",
603
+ "doc_category": "live_source",
604
+ "rule_type": "railway_news",
605
+ "priority": 5,
606
+ "authority": "Media",
607
+ "description": "News coverage related to Indian Railways",
608
+ "is_static": false,
609
+ "effective_year": null,
610
+ "page_number": null,
611
+ "text": "News coverage related to Indian Railways"
612
+ },
613
+ {
614
+ "document_name": "The Hindu – Indian Railways",
615
+ "document_path": "https://www.thehindu.com/topic/indian_railways/",
616
+ "doc_category": "live_source",
617
+ "rule_type": "railway_news",
618
+ "priority": 5,
619
+ "authority": "Media",
620
+ "description": "Policy, safety and operational news on railways",
621
+ "is_static": false,
622
+ "effective_year": null,
623
+ "page_number": null,
624
+ "text": "Policy, safety and operational news on railways"
625
+ },
626
+ {
627
+ "document_name": "LiveMint – Railways",
628
+ "document_path": "https://www.livemint.com/industry/railways",
629
+ "doc_category": "live_source",
630
+ "rule_type": "railway_policy_news",
631
+ "priority": 5,
632
+ "authority": "Media",
633
+ "description": "Economic and policy analysis of Indian Railways",
634
+ "is_static": false,
635
+ "effective_year": null,
636
+ "page_number": null,
637
+ "text": "Economic and policy analysis of Indian Railways"
638
+ },
639
+ {
640
+ "document_name": "Reddit – r/IndianRailways",
641
+ "document_path": "https://www.reddit.com/r/IndianRailways",
642
+ "doc_category": "live_source",
643
+ "rule_type": "community_discussion",
644
+ "priority": 5,
645
+ "authority": "Community",
646
+ "description": "Community discussions, photos and experiences",
647
+ "is_static": false,
648
+ "effective_year": null,
649
+ "page_number": null,
650
+ "text": "Community discussions, photos and experiences"
651
+ },
652
+ {
653
+ "document_name": "Quora – Indian Railways",
654
+ "document_path": "https://www.quora.com/topic/Indian-Railways",
655
+ "doc_category": "live_source",
656
+ "rule_type": "community_qna",
657
+ "priority": 5,
658
+ "authority": "Community",
659
+ "description": "Community Q&A related to Indian Railways",
660
+ "is_static": false,
661
+ "effective_year": null,
662
+ "page_number": null,
663
+ "text": "Community Q&A related to Indian Railways"
664
+ },
665
+ {
666
+ "document_name": "YouTube – Indian Railways Content",
667
+ "document_path": "https://www.youtube.com/results?search_query=indian+railways",
668
+ "doc_category": "live_source",
669
+ "rule_type": "video_reference",
670
+ "priority": 5,
671
+ "authority": "Media / Community",
672
+ "description": "Videos on train journeys, reviews, and railway operations",
673
+ "is_static": false,
674
+ "effective_year": null,
675
+ "page_number": null,
676
+ "text": "Videos on train journeys, reviews, and railway operations"
677
+ }
678
+ ]
data/raw_docs/live_sources/live_sources.json ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "india_code_railways_act",
4
+ "name": "India Code – Railways Act, 1989",
5
+ "url": "https://www.indiacode.nic.in/handle/123456789/2362",
6
+ "authority": "Government of India",
7
+ "rule_type": "law",
8
+ "priority": 1,
9
+ "description": "Official and updated text of the Railways Act, 1989 including amendments"
10
+ },
11
+ {
12
+ "id": "railway_board_circulars",
13
+ "name": "Railway Board Circulars & Orders",
14
+ "url": "https://indianrailways.gov.in/railwayboard/",
15
+ "authority": "Railway Board",
16
+ "rule_type": "circular",
17
+ "priority": 2,
18
+ "description": "Latest railway rules, circulars, policy letters and amendments issued by Railway Board"
19
+ },
20
+ {
21
+ "id": "irctc_rules",
22
+ "name": "IRCTC Rules & Policies",
23
+ "url": "https://www.irctc.co.in/nget/enquiry/termsAndConditions",
24
+ "authority": "IRCTC",
25
+ "rule_type": "passenger_rules",
26
+ "priority": 3,
27
+ "description": "Latest passenger-facing rules including booking, cancellation, refund and TDR policies"
28
+ },
29
+ {
30
+ "id": "irctc_refund_rules",
31
+ "name": "IRCTC Refund & Cancellation Rules",
32
+ "url": "https://contents.irctc.co.in/en/RefundCancellationRules.pdf",
33
+ "authority": "IRCTC",
34
+ "rule_type": "refund",
35
+ "priority": 3,
36
+ "description": "Official refund and cancellation rules PDF maintained by IRCTC"
37
+ },
38
+ {
39
+ "id": "railmadad",
40
+ "name": "RailMadad – Passenger Grievance & Emergency",
41
+ "url": "https://railmadad.indianrailways.gov.in",
42
+ "authority": "Indian Railways",
43
+ "rule_type": "grievance_emergency",
44
+ "priority": 0,
45
+ "description": "Official grievance redressal and emergency assistance portal (includes helpline 139)"
46
+ },
47
+ {
48
+ "id": "crs_safety",
49
+ "name": "Commissioner of Railway Safety",
50
+ "url": "https://crs.gov.in",
51
+ "authority": "Ministry of Civil Aviation (Rail Safety)",
52
+ "rule_type": "safety",
53
+ "priority": 2,
54
+ "description": "Railway safety rules, accident inquiries and safety manuals"
55
+ },
56
+ {
57
+ "id": "indian_railways_passenger_amenities",
58
+ "name": "Passenger Amenities – Indian Railways",
59
+ "url": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,2,287",
60
+ "authority": "Railway Board",
61
+ "rule_type": "passenger_amenities",
62
+ "priority": 4,
63
+ "description": "Official passenger amenities policies and standards at stations and trains"
64
+ },
65
+ {
66
+ "id": "railway_claims_tribunal",
67
+ "name": "Railway Claims Tribunal",
68
+ "url": "https://rct.indianrailways.gov.in",
69
+ "authority": "Government of India",
70
+ "rule_type": "claims_compensation",
71
+ "priority": 2,
72
+ "description": "Compensation, refund and claims procedures related to railway accidents and losses"
73
+ },
74
+ {
75
+ "id": "indian_railways_main",
76
+ "name": "Indian Railways Official Website",
77
+ "url": "https://indianrailways.gov.in",
78
+ "authority": "Ministry of Railways, Government of India",
79
+ "rule_type": "official_portal",
80
+ "priority": 1,
81
+ "description": "Primary official portal for Indian Railways policies, notices, tenders and updates"
82
+ },
83
+ {
84
+ "id": "indian_rail_enquiry",
85
+ "name": "Indian Railways Passenger Enquiry",
86
+ "url": "https://www.indianrail.gov.in",
87
+ "authority": "Indian Railways",
88
+ "rule_type": "passenger_enquiry",
89
+ "priority": 0,
90
+ "description": "Passenger-facing enquiry system for schedules, routes, fares and availability"
91
+ },
92
+ {
93
+ "id": "ntes_live_status",
94
+ "name": "National Train Enquiry System (NTES)",
95
+ "url": "https://enquiry.indianrail.gov.in",
96
+ "authority": "Indian Railways",
97
+ "rule_type": "live_train_status",
98
+ "priority": 0,
99
+ "description": "Official live train running status system"
100
+ },
101
+ {
102
+ "id": "irctc_home",
103
+ "name": "IRCTC Official Portal",
104
+ "url": "https://www.irctc.co.in",
105
+ "authority": "IRCTC",
106
+ "rule_type": "ticketing_platform",
107
+ "priority": 0,
108
+ "description": "Official e-ticketing, catering and tourism portal"
109
+ },
110
+ {
111
+ "id": "irctc_helpdesk",
112
+ "name": "IRCTC Help & Customer Care",
113
+ "url": "https://www.irctc.co.in/nget/enquiry/contactus",
114
+ "authority": "IRCTC",
115
+ "rule_type": "customer_support",
116
+ "priority": 2,
117
+ "description": "Customer support, grievance and escalation information"
118
+ },
119
+ {
120
+ "id": "railmadad_portal",
121
+ "name": "RailMadad Grievance Portal",
122
+ "url": "https://railmadad.indianrailways.gov.in",
123
+ "authority": "Indian Railways",
124
+ "rule_type": "grievance_emergency",
125
+ "priority": 0,
126
+ "description": "Emergency assistance and grievance redressal platform (139)"
127
+ },
128
+ {
129
+ "id": "railway_board_main",
130
+ "name": "Railway Board",
131
+ "url": "https://indianrailways.gov.in/railwayboard/",
132
+ "authority": "Railway Board",
133
+ "rule_type": "policy_authority",
134
+ "priority": 1,
135
+ "description": "Top policy-making authority issuing circulars, manuals and instructions"
136
+ },
137
+ {
138
+ "id": "railway_board_traffic",
139
+ "name": "Railway Board – Traffic Directorate",
140
+ "url": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
141
+ "authority": "Railway Board",
142
+ "rule_type": "traffic_rules",
143
+ "priority": 2,
144
+ "description": "Traffic, operating and commercial circulars"
145
+ },
146
+ {
147
+ "id": "railway_board_safety",
148
+ "name": "Railway Board – Safety Directorate",
149
+ "url": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304,366",
150
+ "authority": "Railway Board",
151
+ "rule_type": "safety_policy",
152
+ "priority": 1,
153
+ "description": "Railway safety policies, manuals and advisories"
154
+ },
155
+ {
156
+ "id": "crs_reports",
157
+ "name": "Commissioner of Railway Safety Reports",
158
+ "url": "https://crs.gov.in/Reports.aspx",
159
+ "authority": "Ministry of Civil Aviation (CRS)",
160
+ "rule_type": "accident_inquiry",
161
+ "priority": 1,
162
+ "description": "Independent accident inquiry and safety inspection reports"
163
+ },
164
+ {
165
+ "id": "prs_system",
166
+ "name": "Passenger Reservation System (PRS)",
167
+ "url": "https://prs.indianrail.gov.in",
168
+ "authority": "CRIS / Indian Railways",
169
+ "rule_type": "reservation_backend",
170
+ "priority": 1,
171
+ "description": "Backend reservation infrastructure of Indian Railways"
172
+ },
173
+ {
174
+ "id": "cris_org",
175
+ "name": "Centre for Railway Information Systems (CRIS)",
176
+ "url": "https://cris.org.in",
177
+ "authority": "Ministry of Railways",
178
+ "rule_type": "railway_it",
179
+ "priority": 2,
180
+ "description": "IT organization managing PRS, NTES, FOIS and operations software"
181
+ },
182
+ {
183
+ "id": "fois_freight",
184
+ "name": "Freight Operations Information System (FOIS)",
185
+ "url": "https://www.fois.indianrail.gov.in",
186
+ "authority": "Indian Railways",
187
+ "rule_type": "freight_tracking",
188
+ "priority": 1,
189
+ "description": "Freight booking, tracking and policy portal"
190
+ },
191
+ {
192
+ "id": "dfccil_portal",
193
+ "name": "Dedicated Freight Corridor Corporation",
194
+ "url": "https://dfccil.com",
195
+ "authority": "Ministry of Railways",
196
+ "rule_type": "freight_infrastructure",
197
+ "priority": 3,
198
+ "description": "Dedicated freight corridor operations and rules"
199
+ },
200
+ {
201
+ "id": "station_codes",
202
+ "name": "Station Codes Directory",
203
+ "url": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=station_code.html",
204
+ "authority": "Indian Railways",
205
+ "rule_type": "station_reference",
206
+ "priority": 3,
207
+ "description": "Official station names and station codes list"
208
+ },
209
+ {
210
+ "id": "concession_rules",
211
+ "name": "Passenger Concession Rules",
212
+ "url": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=conc_Rules.html",
213
+ "authority": "Indian Railways",
214
+ "rule_type": "passenger_concessions",
215
+ "priority": 2,
216
+ "description": "Eligibility and rules for passenger fare concessions"
217
+ },
218
+ {
219
+ "id": "railway_recruitment",
220
+ "name": "Railway Recruitment Boards",
221
+ "url": "https://www.rrbcdg.gov.in",
222
+ "authority": "Railway Recruitment Board",
223
+ "rule_type": "recruitment",
224
+ "priority": 4,
225
+ "description": "Recruitment notices, exams and results"
226
+ },
227
+ {
228
+ "id": "rpf_portal",
229
+ "name": "Railway Protection Force",
230
+ "url": "https://rpf.indianrailways.gov.in",
231
+ "authority": "Indian Railways",
232
+ "rule_type": "railway_security",
233
+ "priority": 2,
234
+ "description": "Railway security, passenger safety and law enforcement"
235
+ },
236
+ {
237
+ "id": "indian_railways_tenders",
238
+ "name": "Indian Railways E-Procurement",
239
+ "url": "https://www.ireps.gov.in",
240
+ "authority": "Indian Railways",
241
+ "rule_type": "tenders_procurement",
242
+ "priority": 4,
243
+ "description": "Official procurement and tendering platform"
244
+ },
245
+ {
246
+ "id": "nair_training",
247
+ "name": "National Academy of Indian Railways",
248
+ "url": "https://nair.indianrailways.gov.in",
249
+ "authority": "Indian Railways",
250
+ "rule_type": "training",
251
+ "priority": 4,
252
+ "description": "Officer training material and manuals"
253
+ },
254
+ {
255
+ "id": "iricen_track",
256
+ "name": "IRICEN Track Engineering",
257
+ "url": "https://www.iricen.gov.in",
258
+ "authority": "Indian Railways",
259
+ "rule_type": "track_engineering",
260
+ "priority": 3,
261
+ "description": "Track engineering manuals and technical guidance"
262
+ },
263
+ {
264
+ "id": "zonal_railways",
265
+ "name": "Zonal Railways Websites Directory",
266
+ "url": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
267
+ "authority": "Indian Railways",
268
+ "rule_type": "zonal_information",
269
+ "priority": 4,
270
+ "description": "Links to all zonal railway websites for zone-specific rules"
271
+ },
272
+ {
273
+ "id": "where_is_my_train",
274
+ "name": "Where Is My Train",
275
+ "url": "https://whereismytrain.in",
276
+ "authority": "Unofficial (Google)",
277
+ "rule_type": "live_train_tracking",
278
+ "priority": 5,
279
+ "description": "Widely used live train tracking app and website using crowd-sourced and offline data"
280
+ },
281
+ {
282
+ "id": "erail",
283
+ "name": "eRail",
284
+ "url": "https://erail.in",
285
+ "authority": "Unofficial",
286
+ "rule_type": "train_schedule_route",
287
+ "priority": 5,
288
+ "description": "Reliable source for train schedules, routes, stations and timetables"
289
+ },
290
+ {
291
+ "id": "indiarailinfo",
292
+ "name": "India Rail Info",
293
+ "url": "https://indiarailinfo.com",
294
+ "authority": "Community-driven",
295
+ "rule_type": "community_updates",
296
+ "priority": 5,
297
+ "description": "Crowdsourced train running updates, delays, spotting and route discussions"
298
+ },
299
+ {
300
+ "id": "railyatri",
301
+ "name": "RailYatri",
302
+ "url": "https://www.railyatri.in",
303
+ "authority": "Private",
304
+ "rule_type": "pnr_live_status",
305
+ "priority": 5,
306
+ "description": "PNR status, live train status and passenger utilities"
307
+ },
308
+ {
309
+ "id": "ixigo_trains",
310
+ "name": "Ixigo Trains",
311
+ "url": "https://www.ixigo.com/trains",
312
+ "authority": "Private",
313
+ "rule_type": "train_search",
314
+ "priority": 5,
315
+ "description": "Train search, live status and delay analytics"
316
+ },
317
+ {
318
+ "id": "confirmtkt",
319
+ "name": "ConfirmTkt",
320
+ "url": "https://www.confirmtkt.com",
321
+ "authority": "Private",
322
+ "rule_type": "seat_prediction",
323
+ "priority": 5,
324
+ "description": "Seat availability prediction and PNR insights"
325
+ },
326
+ {
327
+ "id": "trainman",
328
+ "name": "Trainman",
329
+ "url": "https://www.trainman.in",
330
+ "authority": "Private",
331
+ "rule_type": "pnr_prediction",
332
+ "priority": 5,
333
+ "description": "PNR status prediction and train information"
334
+ },
335
+ {
336
+ "id": "makemytrip_trains",
337
+ "name": "MakeMyTrip Railways",
338
+ "url": "https://www.makemytrip.com/railways",
339
+ "authority": "Private",
340
+ "rule_type": "ticketing_aggregator",
341
+ "priority": 5,
342
+ "description": "Railway ticket booking and enquiry platform"
343
+ },
344
+ {
345
+ "id": "goibibo_trains",
346
+ "name": "Goibibo Trains",
347
+ "url": "https://www.goibibo.com/trains",
348
+ "authority": "Private",
349
+ "rule_type": "ticketing_aggregator",
350
+ "priority": 5,
351
+ "description": "Train search and booking aggregator"
352
+ },
353
+ {
354
+ "id": "paytm_trains",
355
+ "name": "Paytm Trains",
356
+ "url": "https://paytm.com/train-tickets",
357
+ "authority": "Private",
358
+ "rule_type": "ticketing_aggregator",
359
+ "priority": 5,
360
+ "description": "Train ticket booking, PNR and live status tools"
361
+ },
362
+ {
363
+ "id": "redbus_trains",
364
+ "name": "redBus Railways",
365
+ "url": "https://www.redbus.in/railways",
366
+ "authority": "Private",
367
+ "rule_type": "ticketing_aggregator",
368
+ "priority": 5,
369
+ "description": "Rail ticket booking and enquiry features"
370
+ },
371
+ {
372
+ "id": "railradar_railyatri",
373
+ "name": "RailRadar by RailYatri",
374
+ "url": "https://railradar.railyatri.in",
375
+ "authority": "Private",
376
+ "rule_type": "live_map_tracking",
377
+ "priority": 5,
378
+ "description": "Map-based visualization of live train movement"
379
+ },
380
+ {
381
+ "id": "openrailwaymap",
382
+ "name": "OpenRailwayMap",
383
+ "url": "https://www.openrailwaymap.org",
384
+ "authority": "Open-source",
385
+ "rule_type": "railway_map",
386
+ "priority": 5,
387
+ "description": "Detailed open-source railway infrastructure maps"
388
+ },
389
+ {
390
+ "id": "mapsofindia_railways",
391
+ "name": "Maps of India – Railway Map",
392
+ "url": "https://www.mapsofindia.com/railway-map",
393
+ "authority": "Private",
394
+ "rule_type": "railway_map",
395
+ "priority": 5,
396
+ "description": "Visual maps of Indian railway zones and routes"
397
+ },
398
+ {
399
+ "id": "wikipedia_indian_railways",
400
+ "name": "Wikipedia – Indian Railways",
401
+ "url": "https://en.wikipedia.org/wiki/Indian_Railways",
402
+ "authority": "Community",
403
+ "rule_type": "encyclopedic_reference",
404
+ "priority": 5,
405
+ "description": "General background, history and overview of Indian Railways"
406
+ },
407
+ {
408
+ "id": "wikidata_indian_railways",
409
+ "name": "Wikidata – Indian Railways",
410
+ "url": "https://www.wikidata.org/wiki/Q1442",
411
+ "authority": "Open knowledge",
412
+ "rule_type": "structured_data",
413
+ "priority": 5,
414
+ "description": "Structured knowledge graph for Indian Railways entities"
415
+ },
416
+ {
417
+ "id": "ndtv_railways",
418
+ "name": "NDTV – Indian Railways",
419
+ "url": "https://www.ndtv.com/topic/indian-railways",
420
+ "authority": "Media",
421
+ "rule_type": "railway_news",
422
+ "priority": 5,
423
+ "description": "News coverage related to Indian Railways"
424
+ },
425
+ {
426
+ "id": "the_hindu_railways",
427
+ "name": "The Hindu – Indian Railways",
428
+ "url": "https://www.thehindu.com/topic/indian_railways/",
429
+ "authority": "Media",
430
+ "rule_type": "railway_news",
431
+ "priority": 5,
432
+ "description": "Policy, safety and operational news on railways"
433
+ },
434
+ {
435
+ "id": "livemint_railways",
436
+ "name": "LiveMint – Railways",
437
+ "url": "https://www.livemint.com/industry/railways",
438
+ "authority": "Media",
439
+ "rule_type": "railway_policy_news",
440
+ "priority": 5,
441
+ "description": "Economic and policy analysis of Indian Railways"
442
+ },
443
+ {
444
+ "id": "reddit_indianrailways",
445
+ "name": "Reddit – r/IndianRailways",
446
+ "url": "https://www.reddit.com/r/IndianRailways",
447
+ "authority": "Community",
448
+ "rule_type": "community_discussion",
449
+ "priority": 5,
450
+ "description": "Community discussions, photos and experiences"
451
+ },
452
+ {
453
+ "id": "quora_indian_railways",
454
+ "name": "Quora – Indian Railways",
455
+ "url": "https://www.quora.com/topic/Indian-Railways",
456
+ "authority": "Community",
457
+ "rule_type": "community_qna",
458
+ "priority": 5,
459
+ "description": "Community Q&A related to Indian Railways"
460
+ },
461
+ {
462
+ "id": "youtube_indian_railways",
463
+ "name": "YouTube – Indian Railways Content",
464
+ "url": "https://www.youtube.com/results?search_query=indian+railways",
465
+ "authority": "Media / Community",
466
+ "rule_type": "video_reference",
467
+ "priority": 5,
468
+ "description": "Videos on train journeys, reviews, and railway operations"
469
+ }
470
+ ]
471
+
data/raw_docs/meta_data.json ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "core_docs/04_Safety_210815.pdf": {
3
+ "doc_category": "core_docs",
4
+ "rule_type": "safety",
5
+ "priority": 3,
6
+ "authority": "Indian Railways",
7
+ "description": "Safety instructions and procedures issued by Indian Railways",
8
+ "is_static": true
9
+ },
10
+
11
+ "core_docs/1416206396757-Reservation Rules.pdf": {
12
+ "doc_category": "core_docs",
13
+ "rule_type": "reservation",
14
+ "priority": 1,
15
+ "authority": "Indian Railways",
16
+ "description": "Core reservation rules governing passenger ticket booking and allocation",
17
+ "is_static": true
18
+ },
19
+
20
+ "core_docs/AA1987___54railway.pdf": {
21
+ "doc_category": "core_docs",
22
+ "rule_type": "claims_compensation",
23
+ "priority": 1,
24
+ "authority": "Government of India",
25
+ "description": "Railway Claims Tribunal Act, 1987 governing compensation and claims",
26
+ "is_static": true
27
+ },
28
+
29
+ "core_docs/Accident Protocol or Manual (Indian Railways).pdf": {
30
+ "doc_category": "core_docs",
31
+ "rule_type": "safety",
32
+ "priority": 2,
33
+ "authority": "Indian Railways",
34
+ "description": "Official accident handling and investigation procedures",
35
+ "is_static": true
36
+ },
37
+
38
+ "core_docs/Block Working Manual (Eastern Railway).pdf": {
39
+ "doc_category": "core_docs",
40
+ "rule_type": "operations",
41
+ "priority": 2,
42
+ "authority": "Indian Railways",
43
+ "description": "Rules and procedures for block working on Eastern Railway",
44
+ "is_static": true
45
+ },
46
+
47
+ "core_docs/Dedicated Freight Corridor – General Rules.pdf": {
48
+ "doc_category": "core_docs",
49
+ "rule_type": "operations",
50
+ "priority": 1,
51
+ "authority": "DFCCIL / Indian Railways",
52
+ "description": "General rules governing operations on Dedicated Freight Corridors",
53
+ "is_static": true
54
+ },
55
+
56
+ "core_docs/General Rules (South Central Railway G&SR PDF).pdf": {
57
+ "doc_category": "core_docs",
58
+ "rule_type": "operations",
59
+ "priority": 1,
60
+ "authority": "Indian Railways",
61
+ "description": "General and Subsidiary Rules applicable to South Central Railway",
62
+ "is_static": true
63
+ },
64
+
65
+ "core_docs/Indian Railways – General & Subsidiary Rules (North Western Railway).pdf": {
66
+ "doc_category": "core_docs",
67
+ "rule_type": "operations",
68
+ "priority": 1,
69
+ "authority": "Indian Railways",
70
+ "description": "General and Subsidiary Rules applicable to North Western Railway",
71
+ "is_static": true
72
+ },
73
+
74
+ "core_docs/Indian Railways – General & Subsidiary Rules(Northern Railway, 2025).pdf": {
75
+ "doc_category": "core_docs",
76
+ "rule_type": "operations",
77
+ "priority": 1,
78
+ "authority": "Indian Railways",
79
+ "description": "Latest General and Subsidiary Rules for Northern Railway (2025 edition)",
80
+ "is_static": true
81
+ },
82
+
83
+ "core_docs/Indian Railways – General rules (Southern Railway 1976 GRS).pdf": {
84
+ "doc_category": "core_docs",
85
+ "rule_type": "operations",
86
+ "priority": 1,
87
+ "authority": "Indian Railways",
88
+ "description": "Historical General Rules (1976) for Southern Railway",
89
+ "is_static": true
90
+ },
91
+
92
+ "core_docs/Indian Railways – Reservation Rules (English).pdf": {
93
+ "doc_category": "core_docs",
94
+ "rule_type": "reservation",
95
+ "priority": 1,
96
+ "authority": "Indian Railways",
97
+ "description": "Authoritative English version of Indian Railways Reservation Rules",
98
+ "is_static": true
99
+ },
100
+
101
+ "core_docs/operating manual-traffic.pdf": {
102
+ "doc_category": "core_docs",
103
+ "rule_type": "operations",
104
+ "priority": 2,
105
+ "authority": "Indian Railways",
106
+ "description": "Operating manual governing train traffic and movement",
107
+ "is_static": true
108
+ },
109
+
110
+ "core_docs/Railway Servants (Pass) Rules, 1986.pdf": {
111
+ "doc_category": "core_docs",
112
+ "rule_type": "staff_rules",
113
+ "priority": 1,
114
+ "authority": "Government of India",
115
+ "description": "Rules governing railway staff travel privileges and passes",
116
+ "is_static": true
117
+ },
118
+
119
+ "core_docs/Railway-Notices-of-and-Inquiries-into-Accidents-Rules-1998.pdf": {
120
+ "doc_category": "core_docs",
121
+ "rule_type": "safety",
122
+ "priority": 1,
123
+ "authority": "Indian Railways",
124
+ "description": "Statutory rules for railway accident notices and inquiries",
125
+ "is_static": true
126
+ },
127
+
128
+ "core_docs/Railways_Act_1989.pdf": {
129
+ "doc_category": "core_docs",
130
+ "rule_type": "law",
131
+ "priority": 1,
132
+ "authority": "Government of India",
133
+ "description": "Primary legislation governing Indian Railways",
134
+ "is_static": true
135
+ },
136
+
137
+ "core_docs/RulesAndRegulations-2013.pdf": {
138
+ "doc_category": "core_docs",
139
+ "rule_type": "passenger_rules",
140
+ "priority": 2,
141
+ "authority": "IRCTC / Indian Railways",
142
+ "description": "IRCTC rules and regulations for online ticketing (base framework)",
143
+ "is_static": true
144
+ },
145
+
146
+ "core_docs/Station Working Rules – Rupra Road (East Coast Railway).pdf": {
147
+ "doc_category": "core_docs",
148
+ "rule_type": "operations",
149
+ "priority": 2,
150
+ "authority": "Indian Railways",
151
+ "description": "Station Working Rules for Rupra Road station",
152
+ "is_static": true
153
+ },
154
+
155
+ "core_docs/Station Working Rules Chapter from NER (PDF list section).pdf": {
156
+ "doc_category": "core_docs",
157
+ "rule_type": "operations",
158
+ "priority": 2,
159
+ "authority": "Indian Railways",
160
+ "description": "Station Working Rules chapter reference from North Eastern Railway",
161
+ "is_static": true
162
+ },
163
+
164
+ "core_docs/The Railways Act, 1989 (Official PDF).pdf": {
165
+ "doc_category": "core_docs",
166
+ "rule_type": "law",
167
+ "priority": 1,
168
+ "authority": "Government of India",
169
+ "description": "Official consolidated PDF of the Railways Act, 1989",
170
+ "is_static": true
171
+ },
172
+
173
+ "circulars/2013/REFUND RULES wef 1-Jul-13.pdf": {
174
+ "doc_category": "circular",
175
+ "rule_type": "refund",
176
+ "priority": 2,
177
+ "authority": "IRCTC / Railway Board",
178
+ "description": "Refund rules effective from 1 July 2013",
179
+ "is_static": false,
180
+ "effective_year": 2013
181
+ },
182
+
183
+ "circulars/2015/CancellationRulesforIRCTCTrain.pdf": {
184
+ "doc_category": "circular",
185
+ "rule_type": "cancellation",
186
+ "priority": 2,
187
+ "authority": "IRCTC",
188
+ "description": "Cancellation rules applicable to IRCTC train tickets",
189
+ "is_static": false,
190
+ "effective_year": 2015
191
+ },
192
+
193
+ "circulars/2023/2023_11_23 Final_after_CORRIGENDUM_Signal dte amendment.pdf": {
194
+ "doc_category": "circular",
195
+ "rule_type": "signalling_rules",
196
+ "priority": 2,
197
+ "authority": "Railway Board (Signal Directorate)",
198
+ "description": "Corrigendum amending signalling-related operational rules",
199
+ "is_static": false,
200
+ "effective_year": 2023
201
+ },
202
+
203
+ "circulars/Concession Rules (General Rules for Concession).pdf": {
204
+ "doc_category": "circular",
205
+ "rule_type": "passenger_concessions",
206
+ "priority": 2,
207
+ "authority": "Indian Railways",
208
+ "description": "General rules governing passenger fare concessions",
209
+ "is_static": false
210
+ },
211
+
212
+ "circulars/IRCTC – Rules & Regulations (For Agents).pdf": {
213
+ "doc_category": "circular",
214
+ "rule_type": "agent_rules",
215
+ "priority": 2,
216
+ "authority": "IRCTC",
217
+ "description": "Rules and regulations applicable to IRCTC agents",
218
+ "is_static": false
219
+ },
220
+
221
+ "circulars/IRCTC Tatkal Booking FAQ.pdf": {
222
+ "doc_category": "circular",
223
+ "rule_type": "tatkal",
224
+ "priority": 3,
225
+ "authority": "IRCTC",
226
+ "description": "Frequently asked questions related to Tatkal ticket booking",
227
+ "is_static": false
228
+ },
229
+
230
+ "circulars/IRCTC User Guide_ Tatkal Ticket Booking (IRCTC).pdf": {
231
+ "doc_category": "circular",
232
+ "rule_type": "tatkal",
233
+ "priority": 3,
234
+ "authority": "IRCTC",
235
+ "description": "User guide explaining Tatkal ticket booking process",
236
+ "is_static": false
237
+ },
238
+
239
+ "circulars/Railway Establishment Rules.pdf": {
240
+ "doc_category": "circular",
241
+ "rule_type": "staff_rules",
242
+ "priority": 2,
243
+ "authority": "Indian Railways",
244
+ "description": "Establishment rules governing railway staff service matters",
245
+ "is_static": false
246
+ },
247
+
248
+ "circulars/Railway Track Machine Manual.pdf": {
249
+ "doc_category": "circular",
250
+ "rule_type": "engineering",
251
+ "priority": 3,
252
+ "authority": "Indian Railways",
253
+ "description": "Manual for operation and maintenance of railway track machines",
254
+ "is_static": false
255
+ },
256
+
257
+ "circulars/Tatkal Scheme (Indian Railways Board PDF).pdf": {
258
+ "doc_category": "circular",
259
+ "rule_type": "tatkal",
260
+ "priority": 2,
261
+ "authority": "Railway Board",
262
+ "description": "Official Tatkal scheme issued by Railway Board",
263
+ "is_static": false
264
+ },
265
+
266
+ "circulars/Ticket Checking Manual (West Central Railway).pdf": {
267
+ "doc_category": "circular",
268
+ "rule_type": "ticket_checking",
269
+ "priority": 2,
270
+ "authority": "Indian Railways",
271
+ "description": "Procedures and powers of ticket checking staff",
272
+ "is_static": false
273
+ },
274
+
275
+ "circulars/Unreserved Ticketing System Chapter (CAG PDF).pdf": {
276
+ "doc_category": "circular",
277
+ "rule_type": "unreserved_ticketing",
278
+ "priority": 3,
279
+ "authority": "Comptroller and Auditor General of India",
280
+ "description": "Audit chapter on Unreserved Ticketing System",
281
+ "is_static": false
282
+ }
283
+ }
data/raw_docs/train_station/EXP-TRAINS.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bd26de1acda7711b2c664f7f8b6ae0091f6b8792db086245f849f026a427e41c
3
+ size 17507111
data/raw_docs/train_station/PASS-TRAINS.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0a8f9107dbd004f043094fce79fca06bc3008b728bcaf1376311e5f2735d4eb6
3
+ size 21278197
data/raw_docs/train_station/SF-TRAINS.json ADDED
The diff for this file is too large to render. See raw diff
 
data/static_lookup/stations_lookup.json ADDED
The diff for this file is too large to render. See raw diff
 
data/static_lookup/trains_lookup.json ADDED
The diff for this file is too large to render. See raw diff
 
data/vector_store/live_faiss.index ADDED
Binary file (79.9 kB). View file
 
data/vector_store/live_metadata.json ADDED
@@ -0,0 +1,678 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "chunk_id": "https:__www.indiacode.nic.in_handle_123456789_2362_pNone_s1_c1",
4
+ "document_path": "https://www.indiacode.nic.in/handle/123456789/2362",
5
+ "doc_category": "live_source",
6
+ "rule_type": "law",
7
+ "priority": 1,
8
+ "page_number": null,
9
+ "section_index": 1,
10
+ "authority": "Government of India",
11
+ "is_static": false,
12
+ "effective_year": null,
13
+ "text": "Official and updated text of the Railways Act, 1989 including amendments"
14
+ },
15
+ {
16
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard__pNone_s1_c1",
17
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
18
+ "doc_category": "live_source",
19
+ "rule_type": "circular",
20
+ "priority": 2,
21
+ "page_number": null,
22
+ "section_index": 1,
23
+ "authority": "Railway Board",
24
+ "is_static": false,
25
+ "effective_year": null,
26
+ "text": "Latest railway rules, circulars, policy letters and amendments issued by Railway Board"
27
+ },
28
+ {
29
+ "chunk_id": "https:__www.irctc.co.in_nget_enquiry_termsAndConditions_pNone_s1_c1",
30
+ "document_path": "https://www.irctc.co.in/nget/enquiry/termsAndConditions",
31
+ "doc_category": "live_source",
32
+ "rule_type": "passenger_rules",
33
+ "priority": 3,
34
+ "page_number": null,
35
+ "section_index": 1,
36
+ "authority": "IRCTC",
37
+ "is_static": false,
38
+ "effective_year": null,
39
+ "text": "Latest passenger-facing rules including booking, cancellation, refund and TDR policies"
40
+ },
41
+ {
42
+ "chunk_id": "https:__contents.irctc.co.in_en_RefundCancellationRules.pdf_pNone_s1_c1",
43
+ "document_path": "https://contents.irctc.co.in/en/RefundCancellationRules.pdf",
44
+ "doc_category": "live_source",
45
+ "rule_type": "refund",
46
+ "priority": 3,
47
+ "page_number": null,
48
+ "section_index": 1,
49
+ "authority": "IRCTC",
50
+ "is_static": false,
51
+ "effective_year": null,
52
+ "text": "Official refund and cancellation rules PDF maintained by IRCTC"
53
+ },
54
+ {
55
+ "chunk_id": "https:__railmadad.indianrailways.gov.in_pNone_s1_c1",
56
+ "document_path": "https://railmadad.indianrailways.gov.in",
57
+ "doc_category": "live_source",
58
+ "rule_type": "grievance_emergency",
59
+ "priority": 0,
60
+ "page_number": null,
61
+ "section_index": 1,
62
+ "authority": "Indian Railways",
63
+ "is_static": false,
64
+ "effective_year": null,
65
+ "text": "Official grievance redressal and emergency assistance portal (includes helpline 139)"
66
+ },
67
+ {
68
+ "chunk_id": "https:__crs.gov.in_pNone_s1_c1",
69
+ "document_path": "https://crs.gov.in",
70
+ "doc_category": "live_source",
71
+ "rule_type": "safety",
72
+ "priority": 2,
73
+ "page_number": null,
74
+ "section_index": 1,
75
+ "authority": "Ministry of Civil Aviation (Rail Safety)",
76
+ "is_static": false,
77
+ "effective_year": null,
78
+ "text": "Railway safety rules, accident inquiries and safety manuals"
79
+ },
80
+ {
81
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,2,287_pNone_s1_c1",
82
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,2,287",
83
+ "doc_category": "live_source",
84
+ "rule_type": "passenger_amenities",
85
+ "priority": 4,
86
+ "page_number": null,
87
+ "section_index": 1,
88
+ "authority": "Railway Board",
89
+ "is_static": false,
90
+ "effective_year": null,
91
+ "text": "Official passenger amenities policies and standards at stations and trains"
92
+ },
93
+ {
94
+ "chunk_id": "https:__rct.indianrailways.gov.in_pNone_s1_c1",
95
+ "document_path": "https://rct.indianrailways.gov.in",
96
+ "doc_category": "live_source",
97
+ "rule_type": "claims_compensation",
98
+ "priority": 2,
99
+ "page_number": null,
100
+ "section_index": 1,
101
+ "authority": "Government of India",
102
+ "is_static": false,
103
+ "effective_year": null,
104
+ "text": "Compensation, refund and claims procedures related to railway accidents and losses"
105
+ },
106
+ {
107
+ "chunk_id": "https:__indianrailways.gov.in_pNone_s1_c1",
108
+ "document_path": "https://indianrailways.gov.in",
109
+ "doc_category": "live_source",
110
+ "rule_type": "official_portal",
111
+ "priority": 1,
112
+ "page_number": null,
113
+ "section_index": 1,
114
+ "authority": "Ministry of Railways, Government of India",
115
+ "is_static": false,
116
+ "effective_year": null,
117
+ "text": "Primary official portal for Indian Railways policies, notices, tenders and updates"
118
+ },
119
+ {
120
+ "chunk_id": "https:__www.indianrail.gov.in_pNone_s1_c1",
121
+ "document_path": "https://www.indianrail.gov.in",
122
+ "doc_category": "live_source",
123
+ "rule_type": "passenger_enquiry",
124
+ "priority": 0,
125
+ "page_number": null,
126
+ "section_index": 1,
127
+ "authority": "Indian Railways",
128
+ "is_static": false,
129
+ "effective_year": null,
130
+ "text": "Passenger-facing enquiry system for schedules, routes, fares and availability"
131
+ },
132
+ {
133
+ "chunk_id": "https:__enquiry.indianrail.gov.in_pNone_s1_c1",
134
+ "document_path": "https://enquiry.indianrail.gov.in",
135
+ "doc_category": "live_source",
136
+ "rule_type": "live_train_status",
137
+ "priority": 0,
138
+ "page_number": null,
139
+ "section_index": 1,
140
+ "authority": "Indian Railways",
141
+ "is_static": false,
142
+ "effective_year": null,
143
+ "text": "Official live train running status system"
144
+ },
145
+ {
146
+ "chunk_id": "https:__www.irctc.co.in_pNone_s1_c1",
147
+ "document_path": "https://www.irctc.co.in",
148
+ "doc_category": "live_source",
149
+ "rule_type": "ticketing_platform",
150
+ "priority": 0,
151
+ "page_number": null,
152
+ "section_index": 1,
153
+ "authority": "IRCTC",
154
+ "is_static": false,
155
+ "effective_year": null,
156
+ "text": "Official e-ticketing, catering and tourism portal"
157
+ },
158
+ {
159
+ "chunk_id": "https:__www.irctc.co.in_nget_enquiry_contactus_pNone_s1_c1",
160
+ "document_path": "https://www.irctc.co.in/nget/enquiry/contactus",
161
+ "doc_category": "live_source",
162
+ "rule_type": "customer_support",
163
+ "priority": 2,
164
+ "page_number": null,
165
+ "section_index": 1,
166
+ "authority": "IRCTC",
167
+ "is_static": false,
168
+ "effective_year": null,
169
+ "text": "Customer support, grievance and escalation information"
170
+ },
171
+ {
172
+ "chunk_id": "https:__railmadad.indianrailways.gov.in_pNone_s1_c1",
173
+ "document_path": "https://railmadad.indianrailways.gov.in",
174
+ "doc_category": "live_source",
175
+ "rule_type": "grievance_emergency",
176
+ "priority": 0,
177
+ "page_number": null,
178
+ "section_index": 1,
179
+ "authority": "Indian Railways",
180
+ "is_static": false,
181
+ "effective_year": null,
182
+ "text": "Emergency assistance and grievance redressal platform (139)"
183
+ },
184
+ {
185
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard__pNone_s1_c1",
186
+ "document_path": "https://indianrailways.gov.in/railwayboard/",
187
+ "doc_category": "live_source",
188
+ "rule_type": "policy_authority",
189
+ "priority": 1,
190
+ "page_number": null,
191
+ "section_index": 1,
192
+ "authority": "Railway Board",
193
+ "is_static": false,
194
+ "effective_year": null,
195
+ "text": "Top policy-making authority issuing circulars, manuals and instructions"
196
+ },
197
+ {
198
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304_pNone_s1_c1",
199
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
200
+ "doc_category": "live_source",
201
+ "rule_type": "traffic_rules",
202
+ "priority": 2,
203
+ "page_number": null,
204
+ "section_index": 1,
205
+ "authority": "Railway Board",
206
+ "is_static": false,
207
+ "effective_year": null,
208
+ "text": "Traffic, operating and commercial circulars"
209
+ },
210
+ {
211
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304,366_pNone_s1_c1",
212
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304,366",
213
+ "doc_category": "live_source",
214
+ "rule_type": "safety_policy",
215
+ "priority": 1,
216
+ "page_number": null,
217
+ "section_index": 1,
218
+ "authority": "Railway Board",
219
+ "is_static": false,
220
+ "effective_year": null,
221
+ "text": "Railway safety policies, manuals and advisories"
222
+ },
223
+ {
224
+ "chunk_id": "https:__crs.gov.in_Reports.aspx_pNone_s1_c1",
225
+ "document_path": "https://crs.gov.in/Reports.aspx",
226
+ "doc_category": "live_source",
227
+ "rule_type": "accident_inquiry",
228
+ "priority": 1,
229
+ "page_number": null,
230
+ "section_index": 1,
231
+ "authority": "Ministry of Civil Aviation (CRS)",
232
+ "is_static": false,
233
+ "effective_year": null,
234
+ "text": "Independent accident inquiry and safety inspection reports"
235
+ },
236
+ {
237
+ "chunk_id": "https:__prs.indianrail.gov.in_pNone_s1_c1",
238
+ "document_path": "https://prs.indianrail.gov.in",
239
+ "doc_category": "live_source",
240
+ "rule_type": "reservation_backend",
241
+ "priority": 1,
242
+ "page_number": null,
243
+ "section_index": 1,
244
+ "authority": "CRIS / Indian Railways",
245
+ "is_static": false,
246
+ "effective_year": null,
247
+ "text": "Backend reservation infrastructure of Indian Railways"
248
+ },
249
+ {
250
+ "chunk_id": "https:__cris.org.in_pNone_s1_c1",
251
+ "document_path": "https://cris.org.in",
252
+ "doc_category": "live_source",
253
+ "rule_type": "railway_it",
254
+ "priority": 2,
255
+ "page_number": null,
256
+ "section_index": 1,
257
+ "authority": "Ministry of Railways",
258
+ "is_static": false,
259
+ "effective_year": null,
260
+ "text": "IT organization managing PRS, NTES, FOIS and operations software"
261
+ },
262
+ {
263
+ "chunk_id": "https:__www.fois.indianrail.gov.in_pNone_s1_c1",
264
+ "document_path": "https://www.fois.indianrail.gov.in",
265
+ "doc_category": "live_source",
266
+ "rule_type": "freight_tracking",
267
+ "priority": 1,
268
+ "page_number": null,
269
+ "section_index": 1,
270
+ "authority": "Indian Railways",
271
+ "is_static": false,
272
+ "effective_year": null,
273
+ "text": "Freight booking, tracking and policy portal"
274
+ },
275
+ {
276
+ "chunk_id": "https:__dfccil.com_pNone_s1_c1",
277
+ "document_path": "https://dfccil.com",
278
+ "doc_category": "live_source",
279
+ "rule_type": "freight_infrastructure",
280
+ "priority": 3,
281
+ "page_number": null,
282
+ "section_index": 1,
283
+ "authority": "Ministry of Railways",
284
+ "is_static": false,
285
+ "effective_year": null,
286
+ "text": "Dedicated freight corridor operations and rules"
287
+ },
288
+ {
289
+ "chunk_id": "https:__www.indianrail.gov.in_enquiry_StaticPages_StaticEnquiry.jsp?StaticPage=station_code.html_pNone_s1_c1",
290
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=station_code.html",
291
+ "doc_category": "live_source",
292
+ "rule_type": "station_reference",
293
+ "priority": 3,
294
+ "page_number": null,
295
+ "section_index": 1,
296
+ "authority": "Indian Railways",
297
+ "is_static": false,
298
+ "effective_year": null,
299
+ "text": "Official station names and station codes list"
300
+ },
301
+ {
302
+ "chunk_id": "https:__www.indianrail.gov.in_enquiry_StaticPages_StaticEnquiry.jsp?StaticPage=conc_Rules.html_pNone_s1_c1",
303
+ "document_path": "https://www.indianrail.gov.in/enquiry/StaticPages/StaticEnquiry.jsp?StaticPage=conc_Rules.html",
304
+ "doc_category": "live_source",
305
+ "rule_type": "passenger_concessions",
306
+ "priority": 2,
307
+ "page_number": null,
308
+ "section_index": 1,
309
+ "authority": "Indian Railways",
310
+ "is_static": false,
311
+ "effective_year": null,
312
+ "text": "Eligibility and rules for passenger fare concessions"
313
+ },
314
+ {
315
+ "chunk_id": "https:__www.rrbcdg.gov.in_pNone_s1_c1",
316
+ "document_path": "https://www.rrbcdg.gov.in",
317
+ "doc_category": "live_source",
318
+ "rule_type": "recruitment",
319
+ "priority": 4,
320
+ "page_number": null,
321
+ "section_index": 1,
322
+ "authority": "Railway Recruitment Board",
323
+ "is_static": false,
324
+ "effective_year": null,
325
+ "text": "Recruitment notices, exams and results"
326
+ },
327
+ {
328
+ "chunk_id": "https:__rpf.indianrailways.gov.in_pNone_s1_c1",
329
+ "document_path": "https://rpf.indianrailways.gov.in",
330
+ "doc_category": "live_source",
331
+ "rule_type": "railway_security",
332
+ "priority": 2,
333
+ "page_number": null,
334
+ "section_index": 1,
335
+ "authority": "Indian Railways",
336
+ "is_static": false,
337
+ "effective_year": null,
338
+ "text": "Railway security, passenger safety and law enforcement"
339
+ },
340
+ {
341
+ "chunk_id": "https:__www.ireps.gov.in_pNone_s1_c1",
342
+ "document_path": "https://www.ireps.gov.in",
343
+ "doc_category": "live_source",
344
+ "rule_type": "tenders_procurement",
345
+ "priority": 4,
346
+ "page_number": null,
347
+ "section_index": 1,
348
+ "authority": "Indian Railways",
349
+ "is_static": false,
350
+ "effective_year": null,
351
+ "text": "Official procurement and tendering platform"
352
+ },
353
+ {
354
+ "chunk_id": "https:__nair.indianrailways.gov.in_pNone_s1_c1",
355
+ "document_path": "https://nair.indianrailways.gov.in",
356
+ "doc_category": "live_source",
357
+ "rule_type": "training",
358
+ "priority": 4,
359
+ "page_number": null,
360
+ "section_index": 1,
361
+ "authority": "Indian Railways",
362
+ "is_static": false,
363
+ "effective_year": null,
364
+ "text": "Officer training material and manuals"
365
+ },
366
+ {
367
+ "chunk_id": "https:__www.iricen.gov.in_pNone_s1_c1",
368
+ "document_path": "https://www.iricen.gov.in",
369
+ "doc_category": "live_source",
370
+ "rule_type": "track_engineering",
371
+ "priority": 3,
372
+ "page_number": null,
373
+ "section_index": 1,
374
+ "authority": "Indian Railways",
375
+ "is_static": false,
376
+ "effective_year": null,
377
+ "text": "Track engineering manuals and technical guidance"
378
+ },
379
+ {
380
+ "chunk_id": "https:__indianrailways.gov.in_railwayboard_view_section.jsp?id=0,1,304_pNone_s1_c1",
381
+ "document_path": "https://indianrailways.gov.in/railwayboard/view_section.jsp?id=0,1,304",
382
+ "doc_category": "live_source",
383
+ "rule_type": "zonal_information",
384
+ "priority": 4,
385
+ "page_number": null,
386
+ "section_index": 1,
387
+ "authority": "Indian Railways",
388
+ "is_static": false,
389
+ "effective_year": null,
390
+ "text": "Links to all zonal railway websites for zone-specific rules"
391
+ },
392
+ {
393
+ "chunk_id": "https:__whereismytrain.in_pNone_s1_c1",
394
+ "document_path": "https://whereismytrain.in",
395
+ "doc_category": "live_source",
396
+ "rule_type": "live_train_tracking",
397
+ "priority": 5,
398
+ "page_number": null,
399
+ "section_index": 1,
400
+ "authority": "Unofficial (Google)",
401
+ "is_static": false,
402
+ "effective_year": null,
403
+ "text": "Widely used live train tracking app and website using crowd-sourced and offline data"
404
+ },
405
+ {
406
+ "chunk_id": "https:__erail.in_pNone_s1_c1",
407
+ "document_path": "https://erail.in",
408
+ "doc_category": "live_source",
409
+ "rule_type": "train_schedule_route",
410
+ "priority": 5,
411
+ "page_number": null,
412
+ "section_index": 1,
413
+ "authority": "Unofficial",
414
+ "is_static": false,
415
+ "effective_year": null,
416
+ "text": "Reliable source for train schedules, routes, stations and timetables"
417
+ },
418
+ {
419
+ "chunk_id": "https:__indiarailinfo.com_pNone_s1_c1",
420
+ "document_path": "https://indiarailinfo.com",
421
+ "doc_category": "live_source",
422
+ "rule_type": "community_updates",
423
+ "priority": 5,
424
+ "page_number": null,
425
+ "section_index": 1,
426
+ "authority": "Community-driven",
427
+ "is_static": false,
428
+ "effective_year": null,
429
+ "text": "Crowdsourced train running updates, delays, spotting and route discussions"
430
+ },
431
+ {
432
+ "chunk_id": "https:__www.railyatri.in_pNone_s1_c1",
433
+ "document_path": "https://www.railyatri.in",
434
+ "doc_category": "live_source",
435
+ "rule_type": "pnr_live_status",
436
+ "priority": 5,
437
+ "page_number": null,
438
+ "section_index": 1,
439
+ "authority": "Private",
440
+ "is_static": false,
441
+ "effective_year": null,
442
+ "text": "PNR status, live train status and passenger utilities"
443
+ },
444
+ {
445
+ "chunk_id": "https:__www.ixigo.com_trains_pNone_s1_c1",
446
+ "document_path": "https://www.ixigo.com/trains",
447
+ "doc_category": "live_source",
448
+ "rule_type": "train_search",
449
+ "priority": 5,
450
+ "page_number": null,
451
+ "section_index": 1,
452
+ "authority": "Private",
453
+ "is_static": false,
454
+ "effective_year": null,
455
+ "text": "Train search, live status and delay analytics"
456
+ },
457
+ {
458
+ "chunk_id": "https:__www.confirmtkt.com_pNone_s1_c1",
459
+ "document_path": "https://www.confirmtkt.com",
460
+ "doc_category": "live_source",
461
+ "rule_type": "seat_prediction",
462
+ "priority": 5,
463
+ "page_number": null,
464
+ "section_index": 1,
465
+ "authority": "Private",
466
+ "is_static": false,
467
+ "effective_year": null,
468
+ "text": "Seat availability prediction and PNR insights"
469
+ },
470
+ {
471
+ "chunk_id": "https:__www.trainman.in_pNone_s1_c1",
472
+ "document_path": "https://www.trainman.in",
473
+ "doc_category": "live_source",
474
+ "rule_type": "pnr_prediction",
475
+ "priority": 5,
476
+ "page_number": null,
477
+ "section_index": 1,
478
+ "authority": "Private",
479
+ "is_static": false,
480
+ "effective_year": null,
481
+ "text": "PNR status prediction and train information"
482
+ },
483
+ {
484
+ "chunk_id": "https:__www.makemytrip.com_railways_pNone_s1_c1",
485
+ "document_path": "https://www.makemytrip.com/railways",
486
+ "doc_category": "live_source",
487
+ "rule_type": "ticketing_aggregator",
488
+ "priority": 5,
489
+ "page_number": null,
490
+ "section_index": 1,
491
+ "authority": "Private",
492
+ "is_static": false,
493
+ "effective_year": null,
494
+ "text": "Railway ticket booking and enquiry platform"
495
+ },
496
+ {
497
+ "chunk_id": "https:__www.goibibo.com_trains_pNone_s1_c1",
498
+ "document_path": "https://www.goibibo.com/trains",
499
+ "doc_category": "live_source",
500
+ "rule_type": "ticketing_aggregator",
501
+ "priority": 5,
502
+ "page_number": null,
503
+ "section_index": 1,
504
+ "authority": "Private",
505
+ "is_static": false,
506
+ "effective_year": null,
507
+ "text": "Train search and booking aggregator"
508
+ },
509
+ {
510
+ "chunk_id": "https:__paytm.com_train-tickets_pNone_s1_c1",
511
+ "document_path": "https://paytm.com/train-tickets",
512
+ "doc_category": "live_source",
513
+ "rule_type": "ticketing_aggregator",
514
+ "priority": 5,
515
+ "page_number": null,
516
+ "section_index": 1,
517
+ "authority": "Private",
518
+ "is_static": false,
519
+ "effective_year": null,
520
+ "text": "Train ticket booking, PNR and live status tools"
521
+ },
522
+ {
523
+ "chunk_id": "https:__www.redbus.in_railways_pNone_s1_c1",
524
+ "document_path": "https://www.redbus.in/railways",
525
+ "doc_category": "live_source",
526
+ "rule_type": "ticketing_aggregator",
527
+ "priority": 5,
528
+ "page_number": null,
529
+ "section_index": 1,
530
+ "authority": "Private",
531
+ "is_static": false,
532
+ "effective_year": null,
533
+ "text": "Rail ticket booking and enquiry features"
534
+ },
535
+ {
536
+ "chunk_id": "https:__railradar.railyatri.in_pNone_s1_c1",
537
+ "document_path": "https://railradar.railyatri.in",
538
+ "doc_category": "live_source",
539
+ "rule_type": "live_map_tracking",
540
+ "priority": 5,
541
+ "page_number": null,
542
+ "section_index": 1,
543
+ "authority": "Private",
544
+ "is_static": false,
545
+ "effective_year": null,
546
+ "text": "Map-based visualization of live train movement"
547
+ },
548
+ {
549
+ "chunk_id": "https:__www.openrailwaymap.org_pNone_s1_c1",
550
+ "document_path": "https://www.openrailwaymap.org",
551
+ "doc_category": "live_source",
552
+ "rule_type": "railway_map",
553
+ "priority": 5,
554
+ "page_number": null,
555
+ "section_index": 1,
556
+ "authority": "Open-source",
557
+ "is_static": false,
558
+ "effective_year": null,
559
+ "text": "Detailed open-source railway infrastructure maps"
560
+ },
561
+ {
562
+ "chunk_id": "https:__www.mapsofindia.com_railway-map_pNone_s1_c1",
563
+ "document_path": "https://www.mapsofindia.com/railway-map",
564
+ "doc_category": "live_source",
565
+ "rule_type": "railway_map",
566
+ "priority": 5,
567
+ "page_number": null,
568
+ "section_index": 1,
569
+ "authority": "Private",
570
+ "is_static": false,
571
+ "effective_year": null,
572
+ "text": "Visual maps of Indian railway zones and routes"
573
+ },
574
+ {
575
+ "chunk_id": "https:__en.wikipedia.org_wiki_Indian_Railways_pNone_s1_c1",
576
+ "document_path": "https://en.wikipedia.org/wiki/Indian_Railways",
577
+ "doc_category": "live_source",
578
+ "rule_type": "encyclopedic_reference",
579
+ "priority": 5,
580
+ "page_number": null,
581
+ "section_index": 1,
582
+ "authority": "Community",
583
+ "is_static": false,
584
+ "effective_year": null,
585
+ "text": "General background, history and overview of Indian Railways"
586
+ },
587
+ {
588
+ "chunk_id": "https:__www.wikidata.org_wiki_Q1442_pNone_s1_c1",
589
+ "document_path": "https://www.wikidata.org/wiki/Q1442",
590
+ "doc_category": "live_source",
591
+ "rule_type": "structured_data",
592
+ "priority": 5,
593
+ "page_number": null,
594
+ "section_index": 1,
595
+ "authority": "Open knowledge",
596
+ "is_static": false,
597
+ "effective_year": null,
598
+ "text": "Structured knowledge graph for Indian Railways entities"
599
+ },
600
+ {
601
+ "chunk_id": "https:__www.ndtv.com_topic_indian-railways_pNone_s1_c1",
602
+ "document_path": "https://www.ndtv.com/topic/indian-railways",
603
+ "doc_category": "live_source",
604
+ "rule_type": "railway_news",
605
+ "priority": 5,
606
+ "page_number": null,
607
+ "section_index": 1,
608
+ "authority": "Media",
609
+ "is_static": false,
610
+ "effective_year": null,
611
+ "text": "News coverage related to Indian Railways"
612
+ },
613
+ {
614
+ "chunk_id": "https:__www.thehindu.com_topic_indian_railways__pNone_s1_c1",
615
+ "document_path": "https://www.thehindu.com/topic/indian_railways/",
616
+ "doc_category": "live_source",
617
+ "rule_type": "railway_news",
618
+ "priority": 5,
619
+ "page_number": null,
620
+ "section_index": 1,
621
+ "authority": "Media",
622
+ "is_static": false,
623
+ "effective_year": null,
624
+ "text": "Policy, safety and operational news on railways"
625
+ },
626
+ {
627
+ "chunk_id": "https:__www.livemint.com_industry_railways_pNone_s1_c1",
628
+ "document_path": "https://www.livemint.com/industry/railways",
629
+ "doc_category": "live_source",
630
+ "rule_type": "railway_policy_news",
631
+ "priority": 5,
632
+ "page_number": null,
633
+ "section_index": 1,
634
+ "authority": "Media",
635
+ "is_static": false,
636
+ "effective_year": null,
637
+ "text": "Economic and policy analysis of Indian Railways"
638
+ },
639
+ {
640
+ "chunk_id": "https:__www.reddit.com_r_IndianRailways_pNone_s1_c1",
641
+ "document_path": "https://www.reddit.com/r/IndianRailways",
642
+ "doc_category": "live_source",
643
+ "rule_type": "community_discussion",
644
+ "priority": 5,
645
+ "page_number": null,
646
+ "section_index": 1,
647
+ "authority": "Community",
648
+ "is_static": false,
649
+ "effective_year": null,
650
+ "text": "Community discussions, photos and experiences"
651
+ },
652
+ {
653
+ "chunk_id": "https:__www.quora.com_topic_Indian-Railways_pNone_s1_c1",
654
+ "document_path": "https://www.quora.com/topic/Indian-Railways",
655
+ "doc_category": "live_source",
656
+ "rule_type": "community_qna",
657
+ "priority": 5,
658
+ "page_number": null,
659
+ "section_index": 1,
660
+ "authority": "Community",
661
+ "is_static": false,
662
+ "effective_year": null,
663
+ "text": "Community Q&A related to Indian Railways"
664
+ },
665
+ {
666
+ "chunk_id": "https:__www.youtube.com_results?search_query=indian+railways_pNone_s1_c1",
667
+ "document_path": "https://www.youtube.com/results?search_query=indian+railways",
668
+ "doc_category": "live_source",
669
+ "rule_type": "video_reference",
670
+ "priority": 5,
671
+ "page_number": null,
672
+ "section_index": 1,
673
+ "authority": "Media / Community",
674
+ "is_static": false,
675
+ "effective_year": null,
676
+ "text": "Videos on train journeys, reviews, and railway operations"
677
+ }
678
+ ]
data/vector_store/rules_faiss.index ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2711bc634f94564782bb02777e5d8a3c7aad51aaa29d402edaad5437377b271c
3
+ size 8908845
data/vector_store/rules_metadata.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:280a2346f507097a20afd84021e5687165155d57cc52fb204d8938b7dbb42a3f
3
+ size 10668067
data_pipeline/build_static_lookup.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+
4
+ INP_DIR = Path("data/raw_docs/train_station")
5
+ OUT_DIR = Path("data/static_lookup")
6
+ OUT_DIR.mkdir(parents=True, exist_ok=True)
7
+
8
+ train_lookup = {}
9
+ station_lookup = {}
10
+
11
+ STATION_EXPANSIONS = {
12
+ " JN": " JUNCTION"
13
+ }
14
+ TRAIN_EXPANSIONS = {
15
+ " SF ": " SUPERFAST ",
16
+ " EXP ": " EXPRESS ",
17
+ " E ": " EXPRESS ",
18
+ " SPL ": " SPECIAL "
19
+ }
20
+
21
+ def normalize(text: str) -> str:
22
+ return " ".join(text.upper().split())
23
+
24
+ def expand_all(name: str, expansions: dict) -> str:
25
+ expanded = f" {name} "
26
+ changed = True
27
+ while changed:
28
+ changed = False
29
+ for short, full in expansions.items():
30
+ if short in expanded:
31
+ expanded = expanded.replace(short, full)
32
+ changed = True
33
+
34
+ return normalize(expanded)
35
+
36
+ def split_station(station_str):
37
+ if not station_str or "-" not in station_str:
38
+ return None, None
39
+ name, code = station_str.rsplit("-", 1)
40
+ return normalize(name), code.strip().upper()
41
+
42
+ for file in INP_DIR.glob("*.json"):
43
+ with open(file, "r", encoding="utf-8") as f:
44
+ records = json.load(f)
45
+ for r in records:
46
+ tn = r.get("trainNumber")
47
+ tname = r.get("trainName")
48
+ if tn and tname:
49
+ original = normalize(tname)
50
+ expanded = expand_all(original, TRAIN_EXPANSIONS)
51
+ train_lookup[original.lower()] = tn
52
+ if expanded != original:
53
+ train_lookup[expanded.lower()] = tn
54
+ for stop in r.get("trainRoute", []):
55
+ raw = stop.get("stationName")
56
+ name, code = split_station(raw)
57
+ if name and code:
58
+ expanded = expand_all(name, STATION_EXPANSIONS)
59
+ station_lookup[name.lower()] = code
60
+ if expanded != name:
61
+ station_lookup[expanded.lower()] = code
62
+
63
+ with open(OUT_DIR / "trains_lookup.json", "w", encoding="utf-8") as f:
64
+ json.dump(train_lookup, f, indent=2, ensure_ascii=False)
65
+
66
+ with open(OUT_DIR / "stations_lookup.json", "w", encoding="utf-8") as f:
67
+ json.dump(station_lookup, f, indent=2, ensure_ascii=False)
68
+
69
+ print("✅ Static lookup files created")
70
+ print("Trains:", len(train_lookup))
71
+ print("Stations:", len(station_lookup))
data_pipeline/build_vector_store.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Creating embeddings, vector index & implementing FAISS(manages vector indexes)
2
+
3
+ import json
4
+ from pathlib import Path
5
+ import faiss
6
+ from sentence_transformers import SentenceTransformer
7
+
8
+ DATA_DIR = Path("data")
9
+ CHUNKS_DIR = DATA_DIR / "chunks"
10
+ VECTOR_DIR = DATA_DIR / "vector_store"
11
+ VECTOR_DIR.mkdir(parents=True, exist_ok=True)
12
+ CHUNK_FILES=[
13
+ CHUNKS_DIR/"core_docs_chunks.json",
14
+ CHUNKS_DIR/"circulars_chunks.json",
15
+ CHUNKS_DIR/"live_sources_chunks.json",
16
+ ]
17
+ RULES_FAISS_INDEX_FILE = VECTOR_DIR / "rules_faiss.index"
18
+ RULES_METADATA_FILE = VECTOR_DIR / "rules_metadata.json"
19
+ LIVE_FAISS_INDEX_FILE = VECTOR_DIR / "live_faiss.index"
20
+ LIVE_METADATA_FILE = VECTOR_DIR / "live_metadata.json"
21
+
22
+ model=SentenceTransformer("all-MiniLM-L6-v2")
23
+ rules_texts=[]
24
+ rules_metadata=[]
25
+ live_texts=[]
26
+ live_metadata=[]
27
+ for file in CHUNK_FILES:
28
+ if not file.exists():
29
+ continue
30
+ with open(file,"r",encoding="utf-8") as f:
31
+ records=json.load(f)
32
+ for rec in records:
33
+ meta = {
34
+ "chunk_id": rec["chunk_id"],
35
+ "document_path": rec["document_path"],
36
+ "doc_category": rec["doc_category"],
37
+ "rule_type": rec["rule_type"],
38
+ "priority": rec["priority"],
39
+ "page_number": rec["page_number"],
40
+ "section_index": rec["section_index"],
41
+ "authority": rec.get("authority"),
42
+ "is_static": rec.get("is_static"),
43
+ "effective_year": rec.get("effective_year"),
44
+ "text": rec.get("text")
45
+ }
46
+ if rec["doc_category"] == "live_source":
47
+ live_texts.append(rec["text"])
48
+ live_metadata.append(meta)
49
+ else:
50
+ rules_texts.append(rec["text"])
51
+ rules_metadata.append(meta)
52
+
53
+ rules_embeddings = model.encode(
54
+ rules_texts,
55
+ batch_size=32,
56
+ show_progress_bar=True,
57
+ convert_to_numpy=True,
58
+ normalize_embeddings=True
59
+ )
60
+ rules_index = faiss.IndexFlatIP(rules_embeddings.shape[1])
61
+ rules_index.add(rules_embeddings)
62
+ faiss.write_index(rules_index,str(RULES_FAISS_INDEX_FILE))
63
+ with open(RULES_METADATA_FILE, "w", encoding="utf-8") as f:
64
+ json.dump(rules_metadata, f, indent=2, ensure_ascii=False)
65
+
66
+ live_embeddings = model.encode(
67
+ live_texts,
68
+ batch_size=32,
69
+ show_progress_bar=True,
70
+ convert_to_numpy=True,
71
+ normalize_embeddings=True
72
+ )
73
+ live_index = faiss.IndexFlatIP(live_embeddings.shape[1])
74
+ live_index.add(live_embeddings)
75
+ faiss.write_index(live_index, str(LIVE_FAISS_INDEX_FILE))
76
+ with open(LIVE_METADATA_FILE,"w",encoding="utf-8") as f:
77
+ json.dump(live_metadata, f, indent=2, ensure_ascii=False)
78
+
79
+ print(f"Rules chunks loaded : {len(rules_texts)}")
80
+ print(f"Live source chunks loaded: {len(live_texts)}")
81
+ print(f"Rules FAISS index size : {rules_index.ntotal}")
82
+ print(f"Live FAISS index size : {live_index.ntotal}")
83
+ print("✅ Embeddings and FAISS index saved successfully.")
data_pipeline/chunking.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ data_dir = Path("data")
6
+ extract_dir = data_dir / "extracted_text"
7
+ chunks_dir = data_dir / "chunks"
8
+ chunks_dir.mkdir(parents=True, exist_ok=True)
9
+
10
+ input_files = {
11
+ "core_docs": extract_dir / "core_docs.json",
12
+ "circulars": extract_dir / "circulars.json",
13
+ "live_sources": extract_dir / "live_sources.json",
14
+ }
15
+
16
+ CHUNK_WORDS = 600
17
+ OVERLAP_WORDS = 120
18
+ SECTION_PATTERN = re.compile(r"(?:^|\n)\s*(\d+\.\d+)\s+")
19
+
20
+ def split_into_sections(text):
21
+ matches = list(SECTION_PATTERN.finditer(text))
22
+ if not matches:
23
+ return [text]
24
+ sections = []
25
+ for i, match in enumerate(matches):
26
+ start = match.start()
27
+ end = matches[i + 1].start() if i + 1 < len(matches) else len(text)
28
+ section_text = text[start:end].strip()
29
+ if section_text:
30
+ sections.append(section_text)
31
+ return sections
32
+
33
+ def chunk_by_words(text, chunk_size, overlap):
34
+ words = text.split()
35
+ if len(words) <= chunk_size:
36
+ return [text]
37
+ chunks = []
38
+ step = chunk_size - overlap
39
+ for start in range(0, len(words), step):
40
+ end = start + chunk_size
41
+ chunk_words = words[start:end]
42
+ if chunk_words:
43
+ chunks.append(" ".join(chunk_words))
44
+ return chunks
45
+
46
+ #Main splitting
47
+ for source_name, input_file in input_files.items():
48
+ with open(input_file, "r", encoding="utf-8") as f:
49
+ records = json.load(f)
50
+ chunked_records = []
51
+ for rec in records:
52
+ text = rec.get("text", "").strip()
53
+ if not text:
54
+ continue
55
+ sections = split_into_sections(text)
56
+ for sec_idx, section in enumerate(sections, start=1):
57
+ section_chunks = chunk_by_words(
58
+ section,
59
+ CHUNK_WORDS,
60
+ OVERLAP_WORDS
61
+ )
62
+ for chunk_idx, chunk in enumerate(section_chunks, start=1):
63
+ chunk_record = {
64
+ "chunk_id": (
65
+ f"{rec['document_path'].replace('/', '_')}"
66
+ f"_p{rec.get('page_number')}"
67
+ f"_s{sec_idx}"
68
+ f"_c{chunk_idx}"
69
+ ),
70
+ "document_path": rec.get("document_path"),
71
+ "doc_category": rec.get("doc_category"),
72
+ "rule_type": rec.get("rule_type"),
73
+ "priority": rec.get("priority"),
74
+ "authority": rec.get("authority"),
75
+ "is_static": rec.get("is_static"),
76
+ "effective_year": rec.get("effective_year"),
77
+ "page_number": rec.get("page_number"),
78
+ "section_index": sec_idx,
79
+ "chunk_index": chunk_idx,
80
+ "text": chunk
81
+ }
82
+ chunked_records.append(chunk_record)
83
+ output_file = chunks_dir / f"{source_name}_chunks.json"
84
+ with open(output_file, "w", encoding="utf-8") as f:
85
+ json.dump(chunked_records, f, indent=2, ensure_ascii=False)
86
+ print(f"✅ {source_name}: {len(chunked_records)} chunks created")
data_pipeline/extract_text.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+ from pypdf import PdfReader
5
+ import pytesseract
6
+ pytesseract.pytesseract.tesseract_cmd=r"D:\OCR\tesseract.exe" # Give correct path
7
+ import fitz
8
+ from PIL import Image
9
+ import io
10
+
11
+ base_dir=Path(__file__).parent.parent
12
+ # print(base_dir)
13
+ data=base_dir/"data"
14
+ raw_docs=data/"raw_docs"
15
+ circulars=raw_docs/"circulars"
16
+ core_docs=raw_docs/"core_docs"
17
+ live_sources_file=raw_docs/"live_sources"/"live_sources.json"
18
+ metadata_file=raw_docs/"meta_data.json"
19
+
20
+ output_dir=data/"extracted_text"
21
+ output_dir.mkdir(parents=True,exist_ok=True)
22
+
23
+ with open(metadata_file,"r",encoding="utf-8") as f: # Reads core and circular folders metadata(custom made not program generated)
24
+ file_metadata=json.load(f)
25
+ # print(file_metadata["core_docs/Railways_Act_1989.pdf"])
26
+
27
+ def clean_text(text): #Converts to cleaned str
28
+ text = re.sub(r"\n{3,}","\n\n",text)
29
+ text=re.sub(r"[ ]{2,} | \t+"," ",text)
30
+ return text.strip()
31
+
32
+ def ocr_pdf(pdf_path): #Reads images in pdfs
33
+ doc = fitz.open(pdf_path)
34
+ pages_text = []
35
+ for i, page in enumerate(doc, start=1):
36
+ pix = page.get_pixmap(dpi=300)
37
+ img = Image.open(io.BytesIO(pix.tobytes("png")))
38
+ text = pytesseract.image_to_string(img, lang="eng")
39
+ if text.strip():
40
+ pages_text.append((i, text))
41
+ return pages_text
42
+
43
+ def extract_pdf(pdf_path, relative_key):
44
+ records = []
45
+ meta = file_metadata.get(relative_key)
46
+ if not meta:
47
+ print(f"[WARNING] Metadata missing for {relative_key}")
48
+ return records
49
+ reader = PdfReader(str(pdf_path))
50
+ has_text = False
51
+ for page in reader.pages:
52
+ text = page.extract_text()
53
+ if text and text.strip():
54
+ has_text = True
55
+ break
56
+ if has_text:
57
+ for page_no, page in enumerate(reader.pages, start=1):
58
+ text = page.extract_text()
59
+ if not text:
60
+ continue
61
+ records.append({
62
+ "document_id": relative_key.replace("/", "__"),
63
+ "document_name": pdf_path.name,
64
+ "document_path": relative_key,
65
+ "doc_category": meta.get("doc_category"),
66
+ "rule_type": meta.get("rule_type"),
67
+ "priority": meta.get("priority"),
68
+ "authority": meta.get("authority"),
69
+ "description": meta.get("description"),
70
+ "is_static": meta.get("is_static"),
71
+ "effective_year": meta.get("effective_year"),
72
+ "page_number": page_no,
73
+ "text": clean_text(text),
74
+ "extraction_method": "text"
75
+ })
76
+ else:
77
+ ocr_pages = ocr_pdf(pdf_path)
78
+ if not ocr_pages:
79
+ print(f"[OCR FAILED] {relative_key}")
80
+ for page_no, ocr_text in ocr_pages:
81
+ records.append({
82
+ "document_id": relative_key.replace("/", "__"),
83
+ "document_name": pdf_path.name,
84
+ "document_path": relative_key,
85
+ "doc_category": meta.get("doc_category"),
86
+ "rule_type": meta.get("rule_type"),
87
+ "priority": meta.get("priority"),
88
+ "authority": meta.get("authority"),
89
+ "description": meta.get("description"),
90
+ "is_static": meta.get("is_static"),
91
+ "effective_year": meta.get("effective_year"),
92
+ "page_number": page_no,
93
+ "text": clean_text(ocr_text),
94
+ "extraction_method": "ocr"
95
+ })
96
+ return records
97
+
98
+
99
+ def process_folder(base_folder,category_name):
100
+ all_records=[]
101
+ for pdf_file in base_folder.rglob("*.pdf"):
102
+ relative_path=pdf_file.relative_to(base_folder).as_posix()
103
+ relative_key=f"{category_name}/{relative_path}"
104
+ print(f"Processing: {relative_key}")
105
+ records=extract_pdf(pdf_file, relative_key) #Calls extract function
106
+ if not records:
107
+ print(f"[SKIPPED] No extractable text: {relative_key}")
108
+ all_records.extend(records)
109
+ return all_records
110
+
111
+ def process_live_sources():
112
+ with open(live_sources_file,"r",encoding="utf-8") as f:
113
+ live_sources=json.load(f)
114
+ records=[]
115
+ for item in live_sources:
116
+ record={
117
+ "document_name": item.get("name"),
118
+ "document_path": item.get("url"),
119
+ "doc_category": "live_source",
120
+ "rule_type": item.get("rule_type"),
121
+ "priority": item.get("priority"),
122
+ "authority": item.get("authority"),
123
+ "description": item.get("description"),
124
+ "is_static": False,
125
+ "effective_year": None,
126
+ "page_number": None,
127
+ "text":clean_text(item.get("description",""))
128
+ }
129
+ records.append(record)
130
+ return records
131
+
132
+ if __name__=="__main__":
133
+ core_records=process_folder(core_docs,"core_docs")
134
+ circular_records=process_folder(circulars,"circulars")
135
+ live_records=process_live_sources()
136
+ with open(output_dir/"core_docs.json","w",encoding="utf-8") as f:
137
+ json.dump(core_records,f,indent=2,ensure_ascii=False)
138
+ with open(output_dir/"circulars.json","w",encoding="utf-8") as f:
139
+ json.dump(circular_records,f,indent=2,ensure_ascii=False)
140
+ with open(output_dir/"live_sources.json","w",encoding="utf-8") as f:
141
+ json.dump(live_records,f,indent=2,ensure_ascii=False)
142
+ print("\n✅ Document ingestion completed successfully.")
helpers/__init__.py ADDED
File without changes
helpers/live_sources.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Retrieves links for all modules
2
+ import json
3
+ from pathlib import Path
4
+ import faiss
5
+ from sentence_transformers import SentenceTransformer
6
+ DATA_DIR = Path("data")
7
+ VECTOR_DIR = DATA_DIR / "vector_store"
8
+ LIVE_FAISS_INDEX_PATH = VECTOR_DIR / "live_faiss.index"
9
+ LIVE_METADATA_PATH = VECTOR_DIR / "live_metadata.json"
10
+ index = faiss.read_index(str(LIVE_FAISS_INDEX_PATH))
11
+ with open(LIVE_METADATA_PATH, "r", encoding="utf-8") as f:
12
+ METADATA = json.load(f)
13
+ model = SentenceTransformer("all-MiniLM-L6-v2")
14
+ def retrieve_live_sources(
15
+ query: str,
16
+ *,
17
+ top_k: int = 2,
18
+ search_k: int = 2000
19
+ ):
20
+ query_embedding = model.encode(
21
+ [query],
22
+ normalize_embeddings=True,
23
+ convert_to_numpy=True
24
+ )
25
+ scores, indices = index.search(query_embedding, search_k)
26
+ results = []
27
+ seen_urls = set()
28
+ for score, idx in zip(scores[0], indices[0]):
29
+ meta = METADATA[idx]
30
+ url = meta.get("document_path")
31
+ if not url or url in seen_urls:
32
+ continue
33
+ seen_urls.add(url)
34
+ results.append({
35
+ "url": url,
36
+ "authority": meta.get("authority"),
37
+ "description": meta.get("text"),
38
+ "similarity": float(score)
39
+ })
40
+ if len(results) >= top_k:
41
+ break
42
+ return results
modules/__init__.py ADDED
File without changes
modules/general_chat.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # General module
2
+ import os
3
+ from openai import OpenAI
4
+
5
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
6
+ if not client:
7
+ raise RuntimeError("OPENAI_API_KEY is not set")
8
+ MODEL_NAME = "gpt-4.1-mini"
9
+ GENERAL_SYSTEM_PROMPT = (
10
+ "You are a knowledgeable, helpful AI assistant.\n"
11
+ "You can answer general questions, explain concepts clearly, "
12
+ "and respond politely in a conversational manner.\n"
13
+ "If a question is ambiguous, ask for clarification.\n"
14
+ "Do not claim access to private, real-time, or restricted systems."
15
+ )
16
+ def get_relevance(route, module_name):
17
+ for m in route.get("module_preferences", []):
18
+ if m["module"] == module_name:
19
+ return m["relevance"]
20
+ return 0.0
21
+ def answer_general_query(query,route,mode="module"):
22
+ if mode == "failsafe":
23
+ response = client.chat.completions.create(
24
+ model=MODEL_NAME,
25
+ messages=[
26
+ {"role": "system", "content": GENERAL_SYSTEM_PROMPT},
27
+ {"role": "user", "content": query}],temperature=0.6)
28
+ return {
29
+ "answer": response.choices[0].message.content.strip(),
30
+ "has_answer": True,
31
+ "meta": {"mode": "failsafe"}}
32
+ gen_rel = get_relevance(route, "general")
33
+ rag_rel = get_relevance(route, "railway_rag")
34
+ api_rel = get_relevance(route, "live_data_apis")
35
+ MIN_GENERAL_RELEVANCE = 0.30
36
+ DOMINANCE_MARGIN = 0.10
37
+ if gen_rel < MIN_GENERAL_RELEVANCE: #Check 1
38
+ return {
39
+ "answer": None,
40
+ "has_answer": False,
41
+ "meta": {}
42
+ }
43
+ if gen_rel < max(rag_rel, api_rel) + DOMINANCE_MARGIN: #Check 2
44
+ return {
45
+ "answer": None,
46
+ "has_answer": False,
47
+ "meta": {}
48
+ }
49
+ response = client.chat.completions.create(
50
+ model=MODEL_NAME,
51
+ messages=[
52
+ {"role": "system", "content": GENERAL_SYSTEM_PROMPT},
53
+ {"role": "user", "content": query}
54
+ ],
55
+ temperature=0.6
56
+ )
57
+ answer_text = response.choices[0].message.content.strip()
58
+ return {
59
+ "answer": answer_text,
60
+ "has_answer": True,
61
+ "meta": {}
62
+ }
modules/link_answer.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Link only module
2
+ from helpers.live_sources import retrieve_live_sources
3
+ from helpers.live_sources import retrieve_live_sources
4
+ def run(query, num_of_links):
5
+ sources = retrieve_live_sources(query, top_k=num_of_links)
6
+ if not sources:
7
+ return []
8
+ return [
9
+ {
10
+ "url": s["url"],
11
+ "authority": s.get("authority"),
12
+ "similarity": s.get("similarity")
13
+ }
14
+ for s in sources
15
+ if s.get("url")
16
+ ]
modules/live_data_apis.py ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #APIs
2
+ import os
3
+ import json
4
+ import requests
5
+ from openai import OpenAI
6
+ from dotenv import load_dotenv
7
+ load_dotenv()
8
+ from datetime import datetime, timezone, timedelta
9
+
10
+ with open("data/static_lookup/stations_lookup.json", "r", encoding="utf-8") as f:
11
+ STATION_LOOKUP = json.load(f)
12
+ with open("data/static_lookup/trains_lookup.json", "r", encoding="utf-8") as f:
13
+ TRAIN_LOOKUP = json.load(f)
14
+ RAPIDAPI_KEY = os.getenv("RAPIDAPI_KEY")
15
+ if not RAPIDAPI_KEY:
16
+ raise RuntimeError("RAPIDAPI_KEY is not set")
17
+ RAPIDAPI_HOST = "irctc1.p.rapidapi.com"
18
+ BASE_URL = "https://irctc1.p.rapidapi.com"
19
+ HEADERS = {
20
+ "x-rapidapi-key": RAPIDAPI_KEY,
21
+ "x-rapidapi-host": RAPIDAPI_HOST
22
+ }
23
+ llm = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
24
+ LLM_MODEL = "gpt-4.1-mini"
25
+ ENTITY_PROMPT = """
26
+ You extract structured railway-related information from user queries.
27
+
28
+ Return ONLY valid JSON.
29
+ Do NOT infer or assume missing information.
30
+ Do NOT guess defaults.
31
+ Extract a field ONLY if it is explicitly mentioned by the user.
32
+ If a value is not present, use null or an empty list as specified.
33
+
34
+ Supported intents (choose ONE):
35
+ - train_live_status (live running status of a train)
36
+ - train_schedule (timetable / schedule of a train)
37
+ - trains_between_stations (trains running between two stations)
38
+ - seat_availability (seat/berth availability enquiry)
39
+ - fare_enquiry (ticket fare enquiry)
40
+ - pnr_status (PNR booking status)
41
+ - live_station (live arrivals/departures at a station)
42
+ - trains_by_station (list of trains passing a station)
43
+ - search_train (search trains by name or number)
44
+ - search_station (search stations by name)
45
+ - unknown
46
+
47
+ JSON schema:
48
+ {
49
+ "intent": string,
50
+
51
+ "train_numbers": [string], // 5-digit train numbers only
52
+ "pnr_numbers": [string], // 10-digit PNR numbers only
53
+
54
+ "stations": [string], // station names or codes exactly as mentioned
55
+
56
+ "journey": {
57
+ "from": string | null, // source station name/code if explicitly mentioned
58
+ "to": string | null // destination station name/code if explicitly mentioned
59
+ },
60
+
61
+ "date": string | null, // travel date if mentioned (keep original format)
62
+ "class_type": string | null, // class if mentioned (e.g., 2A, 3A, SL, CC)
63
+ "quota": string | null, // quota if mentioned (e.g., GN, Tatkal)
64
+ "hours": integer | null // time window in hours if explicitly mentioned
65
+ }
66
+
67
+ Important rules:
68
+ - Do NOT convert station names to codes.
69
+ - Do NOT normalize dates or class names.
70
+ - Do NOT infer intent from missing data.
71
+ - Do NOT fill defaults.
72
+ - If multiple values exist, extract all where applicable.
73
+ """
74
+
75
+ def extract_with_llm(query):
76
+ resp = llm.chat.completions.create(
77
+ model=LLM_MODEL,
78
+ temperature=0,
79
+ messages=[
80
+ {"role": "system", "content": ENTITY_PROMPT},
81
+ {"role": "user", "content": query}
82
+ ]
83
+ )
84
+ return json.loads(resp.choices[0].message.content)
85
+
86
+ def call_api(path: str, params):
87
+ print("\n[API CALL]")
88
+ print("URL:", BASE_URL + path)
89
+ print("PARAMS:", params)
90
+ try:
91
+ r = requests.get(
92
+ BASE_URL + path,
93
+ headers=HEADERS,
94
+ params=params,
95
+ timeout=10
96
+ )
97
+ print("STATUS:", r.status_code)
98
+ print("RESPONSE:", r.text[:300])
99
+ if r.status_code != 200:
100
+ return None, r.headers
101
+ return r.json().get("data"), r.headers
102
+ except Exception as e:
103
+ print("❌ API EXCEPTION:", e)
104
+ return None, None
105
+
106
+ def resolve_train_number(value: str):
107
+ if not value:
108
+ return None
109
+ clean = value.lower().strip()
110
+ if clean.isdigit() and len(clean) == 5:
111
+ return clean
112
+ return TRAIN_LOOKUP.get(clean)
113
+ def resolve_station_code_local(name: str):
114
+ if not name:
115
+ return None
116
+ clean = name.lower().strip()
117
+ if clean in STATION_LOOKUP:
118
+ return STATION_LOOKUP[clean]
119
+ return resolve_station_code(name)
120
+
121
+ def resolve_station_code(name: str):
122
+ if not name:
123
+ return None
124
+ clean = name.lower().replace(" station", "").strip()
125
+ data, _ = call_api("/api/v1/searchStation", {"query": clean})
126
+ if not data:
127
+ return None
128
+ for s in data:
129
+ station_name = s.get("name", "").lower()
130
+ if station_name == clean:
131
+ return s.get("code")
132
+ for s in data:
133
+ station_name = s.get("name", "").lower()
134
+ if station_name.startswith(clean):
135
+ return s.get("code")
136
+ return data[0].get("code")
137
+
138
+ # Determine freshness (for additional links)
139
+ def determine_freshness(headers):
140
+ if not headers:
141
+ return "unknown"
142
+ date_header = headers.get("Date")
143
+ if not date_header:
144
+ return "unknown"
145
+ try:
146
+ response_time = datetime.strptime(
147
+ date_header, "%a, %d %b %Y %H:%M:%S GMT"
148
+ ).replace(tzinfo=timezone.utc)
149
+ except Exception:
150
+ return "unknown"
151
+ if datetime.now(timezone.utc) - response_time > timedelta(minutes=60):
152
+ return "stale"
153
+ return "fresh"
154
+
155
+ # Date format correction
156
+
157
+ def normalize_date_for_api(date_str):
158
+ for fmt in ("%d-%m-%Y", "%Y-%m-%d", "%d/%m/%Y"):
159
+ try:
160
+ return datetime.strptime(date_str,fmt).strftime("%d-%m-%Y")
161
+ except ValueError:
162
+ continue
163
+ return None
164
+
165
+ #APIs
166
+
167
+ def get_train_live_status(e):
168
+ return call_api("/api/v1/liveTrainStatus", {"trainNo": e["train_number"]})
169
+ def get_train_schedule(e):
170
+ return call_api("/api/v1/getTrainSchedule", {"trainNo": e["train_number"]})
171
+ def get_trains_between_stations(e):
172
+ return call_api("/api/v3/trainBetweenStations", {
173
+ "fromStationCode": e["from_station"],
174
+ "toStationCode": e["to_station"],
175
+ "dateOfJourney": e["date"]
176
+ })
177
+ def get_pnr_status(e):
178
+ return call_api("/api/v3/getPNRStatus", {"pnrNumber": e["pnr"]})
179
+ def get_live_station(e):
180
+ return call_api("/api/v3/getLiveStation", {
181
+ "fromStationCode": e["station_code"],
182
+ "hours": e.get("hours", 2)
183
+ })
184
+ def get_trains_by_station(e):
185
+ return call_api("/api/v3/getTrainsByStation", {"stationCode": e["station_code"]})
186
+ def search_train(e):
187
+ return call_api("/api/v1/searchTrain", {"query": e["query"]})
188
+ def search_station(e):
189
+ return call_api("/api/v1/searchStation", {"query": e["query"]})
190
+ def get_seat_availability(e):
191
+ return call_api("/api/v1/checkSeatAvailability", {
192
+ "trainNo": e["train_number"],
193
+ "fromStationCode": e["from_station"],
194
+ "toStationCode": e["to_station"],
195
+ "date": e["date"],
196
+ "classType": e["class_type"],
197
+ "quota": e.get("quota", "GN")
198
+ })
199
+ def get_seat_availability_v2(e):
200
+ return call_api("/api/v2/checkSeatAvailability", {
201
+ "trainNo": e["train_number"],
202
+ "fromStationCode": e["from_station"],
203
+ "toStationCode": e["to_station"],
204
+ "date": e["date"],
205
+ "classType": e["class_type"],
206
+ "quota": e.get("quota", "GN")
207
+ })
208
+ def get_fare(e):
209
+ return call_api("/api/v1/getFare", {
210
+ "trainNo": e["train_number"],
211
+ "fromStationCode": e["from_station"],
212
+ "toStationCode": e["to_station"],
213
+ "date": e["date"],
214
+ "classType": e["class_type"],
215
+ "quota": e.get("quota", "GN")
216
+ })
217
+
218
+ #Check whether apis match
219
+
220
+
221
+ # Calling crct API
222
+ # Mapping intent to API
223
+
224
+ INTENT_TO_API = {
225
+ "train_live_status": {
226
+ "required": ["train_number"],
227
+ "handler": get_train_live_status,
228
+ "fallback": "train_schedule"
229
+ },
230
+ "train_schedule": {
231
+ "required": ["train_number"],
232
+ "handler": get_train_schedule,
233
+ "fallback": None
234
+ },
235
+ "trains_between_stations": {
236
+ "required": ["from_station", "to_station", "date"],
237
+ "handler": get_trains_between_stations,
238
+ "fallback": None
239
+ },
240
+ "seat_availability": {
241
+ "required": ["train_number", "from_station", "to_station", "date", "class_type"],
242
+ "handler": get_seat_availability,
243
+ "fallback": "seat_availability_v2"
244
+ },
245
+ "seat_availability_v2": {
246
+ "required": ["train_number", "from_station", "to_station", "date", "class_type"],
247
+ "handler": get_seat_availability_v2,
248
+ "fallback": None
249
+ },
250
+ "fare_enquiry": {
251
+ "required": ["train_number", "from_station", "to_station", "date", "class_type"],
252
+ "handler": get_fare,
253
+ "fallback": None
254
+ },
255
+ "pnr_status": {
256
+ "required": ["pnr"],
257
+ "handler": get_pnr_status,
258
+ "fallback": None
259
+ },
260
+ "live_station": {
261
+ "required": ["station_code"],
262
+ "handler": get_live_station,
263
+ "fallback": "trains_by_station"
264
+ },
265
+ "trains_by_station": {
266
+ "required": ["station_code"],
267
+ "handler": get_trains_by_station,
268
+ "fallback": None
269
+ },
270
+ "search_train": {
271
+ "required": ["query"],
272
+ "handler": search_train,
273
+ "fallback": None
274
+ },
275
+ "search_station": {
276
+ "required": ["query"],
277
+ "handler": search_station,
278
+ "fallback": None
279
+ }
280
+ }
281
+
282
+ # Main
283
+
284
+ def answer_with_live_data(query):
285
+ parsed = extract_with_llm(query)
286
+ intent = parsed.get("intent", "unknown")
287
+ if intent not in INTENT_TO_API:
288
+ return {"answer": None, "has_answer": False, "meta": {"status":"nothing"}}
289
+ entity = {"query": query}
290
+ if parsed.get("train_numbers"):
291
+ tn = resolve_train_number(parsed["train_numbers"][0])
292
+ if tn:
293
+ entity["train_number"] = tn
294
+ if parsed.get("pnr_numbers"):
295
+ entity["pnr"] = parsed["pnr_numbers"][0]
296
+ resolved = []
297
+ for s in parsed.get("stations", []):
298
+ code = resolve_station_code_local(s)
299
+ if code:
300
+ resolved.append(code)
301
+ if len(resolved) == 1:
302
+ entity["station_code"] = resolved[0]
303
+ journey = parsed.get("journey")
304
+ if journey and journey.get("from") and journey.get("to"):
305
+ f = resolve_station_code_local(journey["from"])
306
+ t = resolve_station_code_local(journey["to"])
307
+ if f and t:
308
+ entity["from_station"] = f
309
+ entity["to_station"] = t
310
+ if parsed.get("date"):
311
+ normalized = normalize_date_for_api(parsed["date"])
312
+ if normalized:
313
+ entity["date"] = normalized
314
+ elif intent == "trains_between_stations":
315
+ entity["date"] = datetime.now(timezone.utc).strftime("%d-%m-%Y")
316
+ for k in ["class_type", "quota", "hours"]:
317
+ if parsed.get(k) is not None:
318
+ entity[k] = parsed[k]
319
+ api = INTENT_TO_API[intent]
320
+ # required, missing
321
+ required = api["required"]
322
+ missing = [k for k in required if k not in entity]
323
+ if missing:
324
+ return {
325
+ "answer": None,
326
+ "has_answer": False,
327
+ "meta": {
328
+ "status": "need_input",
329
+ "reason": "missing_required_fields",
330
+ "intent": intent,
331
+ "missing_fields": missing,
332
+ "partial_entity": entity
333
+ }
334
+ }
335
+ # Primary API call
336
+ data, headers= api["handler"](entity)
337
+ fallback_used = False
338
+ # Fallback handling
339
+ if not data and api.get("fallback"):
340
+ fb = INTENT_TO_API[api["fallback"]]
341
+ if all(k in entity for k in fb["required"]):
342
+ data, headers= fb["handler"](entity)
343
+ if data:
344
+ fallback_used = True
345
+ # Freshness detection (safe, signal only)
346
+ freshness = determine_freshness(headers)
347
+ if not data:
348
+ return {"answer": None, "has_answer": False, "meta": {"status": "api_failed","intent": intent}}
349
+ return {
350
+ "answer":data,
351
+ "has_answer": True,
352
+ "meta": {
353
+ "status": "ok",
354
+ "intent": intent,
355
+ "fallback_used": fallback_used,
356
+ "freshness": freshness,
357
+ "resolved": {
358
+ "train_number": entity.get("train_number"),
359
+ "station_code": entity.get("station_code"),
360
+ "from_station": entity.get("from_station"),
361
+ "to_station": entity.get("to_station"),
362
+ "date": entity.get("date")
363
+ }
364
+ }
365
+ }
366
+ #TEST
367
+ # if __name__ == "__main__":
368
+ # print("=" * 80)
369
+ # print("API TEST STARTED")
370
+ # print("RAPIDAPI_KEY exists:", bool(RAPIDAPI_KEY))
371
+ # print("RAPIDAPI_HOST:", RAPIDAPI_HOST)
372
+ # print("=" * 80)
373
+
374
+ # test_queries = [
375
+ # # search station (sanity check)
376
+ # "Kozhikode trains",
377
+ # # search train (sanity check)
378
+
379
+ # ]
380
+
381
+ # for q in test_queries:
382
+ # print("\n" + "-" * 60)
383
+ # print("Query:", q)
384
+
385
+ # result = answer_with_live_data(q)
386
+
387
+ # print("HAS ANSWER:", result.get("has_answer"))
388
+ # print("META:", result.get("meta"))
389
+
390
+ # if result.get("has_answer"):
391
+ # print("DATA PREVIEW:")
392
+ # print(result["answer"][:500]) # prevent huge spam
393
+ # else:
394
+ # print("❌ NO DATA RETURNED")
395
+
396
+ # print("\nAPI TEST COMPLETED")
modules/railway_rag/__init__.py ADDED
File without changes
modules/railway_rag/railway_base_rag.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Railway Rules RAG Module
2
+ import os
3
+ from openai import OpenAI
4
+ from dotenv import load_dotenv
5
+ load_dotenv()
6
+ from modules.railway_rag.retrieval_engine import retrieve_rules
7
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
8
+ if not client:
9
+ raise RuntimeError("OPENAI_API_KEY is not set")
10
+ MODEL_NAME = "gpt-4.1-mini"
11
+ SYSTEM_PROMPT = (
12
+ "You are a railway rules assistant.\n"
13
+ "You must answer the user question ONLY if the provided railway rules, clearly and directly contain the answer.\n"
14
+ "Do not use any information outside the given rules.\n"
15
+ "Do not speculate or infer missing details.\n"
16
+ "If the rules do not clearly answer the question, do not attempt to answer."
17
+ )
18
+ def build_context(chunks): #Make all chunks into one block(in dec order of similarity for chunks)
19
+ blocks = [] #Creates text out of all retrieved chunks, For llm to read it like a document
20
+ for i, c in enumerate(chunks, start=1):
21
+ blocks.append(
22
+ f"[Source {i}]\n"
23
+ f"Document: {c['document_path']}\n"
24
+ f"Authority: {c.get('authority')}\n"
25
+ f"Page: {c.get('page_number')}, "
26
+ f"Section: {c.get('section_index')}\n"
27
+ f"Text:\n{c['text']}\n"
28
+ )
29
+ return "\n\n".join(blocks)
30
+ def extract_citations(chunks): #Citations
31
+ return [
32
+ {
33
+ "document_path": c.get("document_path"),
34
+ "authority": c.get("authority"),
35
+ "rule_type": c.get("rule_type"),
36
+ "page_number": c.get("page_number"),
37
+ "section_index": c.get("section_index"),
38
+ "effective_year":c.get("effective_year")
39
+ }
40
+ for c in chunks #For each chunk
41
+ ]
42
+
43
+ def estimate_confidence(chunks): #Find Confidence
44
+ if not chunks:
45
+ return 0.0
46
+ # Collect similarities (LLM used all of them)
47
+ sims = [c.get("similarity", 0.0) for c in chunks]
48
+ # Best supporting rule
49
+ top_sim = max(sims)
50
+ # No strong rule at all → low confidence
51
+ if top_sim < 0.45:
52
+ return round(top_sim * 0.8, 2)
53
+ # Consider only chunks that genuinely support the answer
54
+ # (close enough to the best one)
55
+ support_sims = [
56
+ s for s in sims
57
+ if s >= top_sim - 0.10
58
+ ]
59
+ # Mean support from all relevant chunks
60
+ support_mean = sum(support_sims) / len(support_sims)
61
+ # Final confidence
62
+ confidence = (
63
+ 0.75 * top_sim +
64
+ 0.25 * support_mean
65
+ )
66
+ return round(min(confidence, 0.9), 2)
67
+
68
+ def answer_with_rag(query: str):
69
+ chunks = retrieve_rules(query)
70
+ if not chunks: # No chunks
71
+ return {
72
+ "answer": None,
73
+ "has_answer": False,
74
+ "meta": {"confidence": 0.0,}
75
+ }
76
+ context=build_context(chunks)
77
+ user_prompt=(
78
+ f"User question:\n{query}\n\n"
79
+ f"Relevant railway rules:\n{context}\n\n"
80
+ "Instructions:\n"
81
+ "- Answer strictly using the rules above.\n"
82
+ "- Do not add external knowledge.\n"
83
+ )
84
+ response = client.chat.completions.create(
85
+ model=MODEL_NAME,
86
+ messages=[
87
+ {"role": "system", "content": SYSTEM_PROMPT},
88
+ {"role": "user", "content": user_prompt}
89
+ ],
90
+ temperature=0.2
91
+ )
92
+ answer_text = response.choices[0].message.content.strip()
93
+ confidence=estimate_confidence(chunks)
94
+ if not answer_text:
95
+ return {
96
+ "answer": None,
97
+ "has_answer": False,
98
+ "meta": {
99
+ "confidence": confidence
100
+ }
101
+ }
102
+ return {
103
+ "answer": answer_text,
104
+ "has_answer": confidence>=0.45,
105
+ "meta": {
106
+ "confidence": confidence,
107
+ "citations": extract_citations(chunks),
108
+ "rule_types": list({c.get("rule_type") for c in chunks if c.get("rule_type")})
109
+ }
110
+ }
111
+ if __name__ == "__main__":
112
+ print("✅ Railway base RAG module ready.")
modules/railway_rag/retrieval_engine.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Helps railwaay_base_rag
2
+ import json
3
+ from pathlib import Path
4
+ import faiss
5
+ from sentence_transformers import SentenceTransformer
6
+
7
+ TOP_K_RETRIEVE = 50
8
+ TOP_K_FINAL = 10
9
+ SIMILARITY_THRESHOLD = 0.30
10
+ PRIORITY_WEIGHT = 0.15
11
+ RULE_MATCH_WEIGHT = 0.10
12
+ RECENCY_WEIGHT = 0.05
13
+ QUESTION_TYPE_WEIGHT = 0.10
14
+ DATA_DIR = Path("data")
15
+ VECTOR_DIR = DATA_DIR / "vector_store"
16
+ RULES_FAISS_INDEX_PATH = VECTOR_DIR / "rules_faiss.index"
17
+ RULES_METADATA_PATH = VECTOR_DIR / "rules_metadata.json"
18
+ index = faiss.read_index(str(RULES_FAISS_INDEX_PATH))
19
+ with open(RULES_METADATA_PATH, "r", encoding="utf-8") as f:
20
+ METADATA = json.load(f)
21
+ model = SentenceTransformer("all-MiniLM-L6-v2")
22
+ assert index.ntotal == len(METADATA), "Index and metadata size mismatch"
23
+
24
+ #Scoring helpers
25
+ def rule_match_score(query: str, rule_type: str) -> float:
26
+ if not rule_type:
27
+ return 0.0
28
+ return 1.0 if rule_type.lower() in query.lower() else 0.0
29
+ def recency_score(year):
30
+ if year is None:
31
+ return 0.0
32
+ return min((year - 2000) / 25, 1.0)
33
+ def detect_question_type(query: str) -> str:
34
+ q = query.lower()
35
+ if any(x in q for x in ["what is", "define", "meaning of"]):
36
+ return "definition"
37
+ if any(x in q for x in ["can i", "allowed", "permitted"]):
38
+ return "permission"
39
+ if any(x in q for x in ["not allowed", "prohibited", "shall not"]):
40
+ return "prohibition"
41
+ if any(x in q for x in ["how to", "procedure", "process"]):
42
+ return "procedure"
43
+ if any(x in q for x in ["penalty", "fine", "punishment", "liable"]):
44
+ return "penalty"
45
+ return "general"
46
+ def question_type_bonus(qtype: str, text: str) -> float:
47
+ t = text.lower()
48
+ if qtype == "definition" and any(x in t for x in ["means", "defined as"]):
49
+ return QUESTION_TYPE_WEIGHT
50
+ if qtype == "permission" and any(x in t for x in ["may", "permitted", "allowed"]):
51
+ return QUESTION_TYPE_WEIGHT
52
+ if qtype == "prohibition" and any(x in t for x in ["shall not", "prohibited"]):
53
+ return QUESTION_TYPE_WEIGHT
54
+ if qtype == "procedure" and any(x in t for x in ["procedure", "steps", "shall be"]):
55
+ return QUESTION_TYPE_WEIGHT
56
+ if qtype == "penalty" and any(x in t for x in ["penalty", "fine", "liable"]):
57
+ return QUESTION_TYPE_WEIGHT
58
+ return 0.0
59
+
60
+
61
+ def retrieve_rules(query: str):
62
+ query_embedding = model.encode(
63
+ [query],
64
+ normalize_embeddings=True,
65
+ convert_to_numpy=True
66
+ )
67
+ scores, indices = index.search(query_embedding, TOP_K_RETRIEVE)
68
+ qtype = detect_question_type(query)
69
+ candidates = []
70
+ for i, idx in enumerate(indices[0]):
71
+ similarity = float(scores[0][i])
72
+ if similarity < SIMILARITY_THRESHOLD:
73
+ continue
74
+ meta = METADATA[idx]
75
+ priority_bonus = (1 / meta["priority"]) * PRIORITY_WEIGHT
76
+ rule_bonus = rule_match_score(query, meta["rule_type"]) * RULE_MATCH_WEIGHT
77
+ recency_bonus = recency_score(meta.get("effective_year")) * RECENCY_WEIGHT
78
+ qtype_bonus = question_type_bonus(qtype, meta["text"])
79
+ final_score = (
80
+ similarity
81
+ + priority_bonus
82
+ + rule_bonus
83
+ + recency_bonus
84
+ + qtype_bonus
85
+ )
86
+ candidates.append({
87
+ "final_score": round(final_score, 4),
88
+ "similarity": round(similarity, 4),
89
+ "chunk_id": meta["chunk_id"],
90
+ "document_path": meta["document_path"],
91
+ "rule_type": meta["rule_type"],
92
+ "priority": meta["priority"],
93
+ "authority": meta["authority"],
94
+ "page_number": meta["page_number"],
95
+ "section_index": meta.get("section_index"),
96
+ "text": meta["text"]
97
+ })
98
+ candidates.sort(key=lambda x: x["final_score"], reverse=True)
99
+ return candidates[:TOP_K_FINAL]
requirements.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # UI
2
+ gradio
3
+
4
+ # API backend (kept for completeness)
5
+ fastapi
6
+ pydantic
7
+
8
+ # LLM & RAG
9
+ openai
10
+ faiss-cpu
11
+ sentence-transformers
12
+
13
+ # Data & utilities
14
+ requests
15
+ python-dotenv
16
+
17
+ # Document processing (PDFs)
18
+ pypdf
19
+ PyMuPDF
20
+ Pillow
runtime.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ python-3.10