Basementup commited on
Commit
0cea02d
ยท
verified ยท
1 Parent(s): bf31833

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -41
app.py CHANGED
@@ -14,6 +14,8 @@ from gtts import gTTS
14
  DATA_FILE = "legislation_rules.json"
15
  RULINGS_FILE = "rulings_log.json"
16
 
 
 
17
  def load_data(file_path):
18
  if os.path.exists(file_path):
19
  with open(file_path, 'r') as f:
@@ -34,7 +36,6 @@ def extract_text_from_any(file_obj):
34
  if file_obj is None: return ""
35
  file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
36
  if not os.path.exists(file_path): return ""
37
-
38
  ext = os.path.splitext(file_path)[1].lower()
39
  text = ""
40
  try:
@@ -74,12 +75,10 @@ def process_rule_document(file_obj, act_name):
74
  return add_rule_manually(act_name, os.path.basename(file_obj.name), text, f"File: {os.path.basename(file_obj.name)}")
75
 
76
  def generate_tts(text):
77
- """Generates an audio file from text using gTTS."""
78
- if not text or len(text) < 5:
79
- return None
80
  try:
81
  clean_text = text.replace("#", "").replace("*", "").replace("`", "")
82
- tts = gTTS(text=clean_text[:1500], lang='en') # Limit to first 1500 chars for speed
83
  filename = f"ruling_audio_{int(datetime.now().timestamp())}.mp3"
84
  tts.save(filename)
85
  return filename
@@ -90,31 +89,11 @@ def generate_tts(text):
90
  def rule_on_issue(issue_description, issue_file, llm_endpoint, llm_key, llm_model):
91
  file_text = extract_text_from_any(issue_file)
92
  combined_issue = f"{issue_description}\n\n[EXTRACTED FROM DOCUMENT]:\n{file_text}".strip()
93
-
94
- if not combined_issue:
95
- return "Error: No issue description or document provided.", "", None
96
-
97
  rules = load_data(DATA_FILE)
98
- if not rules:
99
- return "Error: Dataset is empty. Add rules (CRA, FCA, etc.) first.", "", None
100
-
101
  context = "\n".join([f"[{r['act']} - {r['section_title']}]: {r['text'][:600]}..." for r in rules[:20]])
102
-
103
- prompt = f"""
104
- You are a Regulatory Ruling Engine.
105
- ISSUE TO ANALYZE:
106
- {combined_issue}
107
-
108
- DETERMINISTIC REFERENCE RULES:
109
- {context}
110
-
111
- TASK:
112
- 1. Identify applicable rules.
113
- 2. Provide a 'Formal Ruling' (Compliant/Non-Compliant/Warning).
114
- 3. Cite Rule Titles and Deterministic IDs.
115
- 4. Provide forensic justification.
116
- """
117
-
118
  ruling_text = "LLM Inference required for automated ruling."
119
  if llm_endpoint and llm_key:
120
  try:
@@ -122,23 +101,12 @@ def rule_on_issue(issue_description, issue_file, llm_endpoint, llm_key, llm_mode
122
  payload = {"model": llm_model, "messages": [{"role": "user", "content": prompt}], "temperature": 0}
123
  response = requests.post(f"{llm_endpoint.rstrip('/')}/v1/chat/completions", json=payload, headers=headers, timeout=45)
124
  ruling_text = response.json()['choices'][0]['message']['content']
125
- except Exception as e:
126
- ruling_text = f"Inference Error: {str(e)}"
127
-
128
- # Generate Audio for the Ruling
129
  audio_file = generate_tts(ruling_text)
130
-
131
- # Log the ruling
132
  rulings_log = load_data(RULINGS_FILE)
133
- new_ruling = {
134
- "timestamp": datetime.now().isoformat(),
135
- "issue_summary": combined_issue[:200],
136
- "ruling": ruling_text,
137
- "ruling_hash": hashlib.sha256(ruling_text.encode()).hexdigest()
138
- }
139
  rulings_log.append(new_ruling)
140
  save_data(rulings_log, RULINGS_FILE)
141
-
142
  return ruling_text, f"Ruling Logged (ID: {new_ruling['ruling_hash'][:8]})", audio_file
143
 
144
  def sync_all(token, dataset_id):
@@ -158,6 +126,25 @@ def view_stats():
158
  for r in data: acts[r['act']] = acts.get(r['act'], 0) + 1
159
  return "\n".join([f"{k}: {v}" for k,v in acts.items()])
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
162
  gr.Markdown("# โš–๏ธ Legislation & FCA Ruling Manager")
163
 
@@ -193,10 +180,18 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
193
  stats_out = gr.Textbox(label="Dataset Inventory", value=view_stats())
194
  refresh_btn = gr.Button("Refresh Inventory")
195
 
 
 
 
 
 
196
  with gr.Tab("โ˜๏ธ Sync & Audit"):
197
  hf_t = gr.Textbox(label="HF Token", type="password"); hf_d = gr.Textbox(label="Dataset ID")
198
  s_btn = gr.Button("Sync Everything to Dataset")
199
  s_out = gr.Textbox(label="Sync Status")
 
 
 
200
 
201
  rule_btn.click(fn=rule_on_issue, inputs=[issue_desc, issue_file, end, key, mod], outputs=[ruling_out, log_status, audio_out])
202
  doc_btn.click(fn=process_rule_document, inputs=[doc_in, doc_act], outputs=op_status)
 
14
  DATA_FILE = "legislation_rules.json"
15
  RULINGS_FILE = "rulings_log.json"
16
 
17
+ # --- CORE LOGIC ---
18
+
19
  def load_data(file_path):
20
  if os.path.exists(file_path):
21
  with open(file_path, 'r') as f:
 
36
  if file_obj is None: return ""
37
  file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
38
  if not os.path.exists(file_path): return ""
 
39
  ext = os.path.splitext(file_path)[1].lower()
40
  text = ""
41
  try:
 
75
  return add_rule_manually(act_name, os.path.basename(file_obj.name), text, f"File: {os.path.basename(file_obj.name)}")
76
 
77
  def generate_tts(text):
78
+ if not text or len(text) < 5: return None
 
 
79
  try:
80
  clean_text = text.replace("#", "").replace("*", "").replace("`", "")
81
+ tts = gTTS(text=clean_text[:1500], lang='en')
82
  filename = f"ruling_audio_{int(datetime.now().timestamp())}.mp3"
83
  tts.save(filename)
84
  return filename
 
89
  def rule_on_issue(issue_description, issue_file, llm_endpoint, llm_key, llm_model):
90
  file_text = extract_text_from_any(issue_file)
91
  combined_issue = f"{issue_description}\n\n[EXTRACTED FROM DOCUMENT]:\n{file_text}".strip()
92
+ if not combined_issue: return "Error: No issue description or document provided.", "", None
 
 
 
93
  rules = load_data(DATA_FILE)
94
+ if not rules: return "Error: Dataset is empty. Add rules (CRA, FCA, etc.) first.", "", None
 
 
95
  context = "\n".join([f"[{r['act']} - {r['section_title']}]: {r['text'][:600]}..." for r in rules[:20]])
96
+ prompt = f"You are a Regulatory Ruling Engine.\nISSUE TO ANALYZE:\n{combined_issue}\nDETERMINISTIC REFERENCE RULES:\n{context}\nTASK:\n1. Identify applicable rules.\n2. Provide a 'Formal Ruling' (Compliant/Non-Compliant/Warning).\n3. Cite Rule Titles and Deterministic IDs.\n4. Provide forensic justification."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  ruling_text = "LLM Inference required for automated ruling."
98
  if llm_endpoint and llm_key:
99
  try:
 
101
  payload = {"model": llm_model, "messages": [{"role": "user", "content": prompt}], "temperature": 0}
102
  response = requests.post(f"{llm_endpoint.rstrip('/')}/v1/chat/completions", json=payload, headers=headers, timeout=45)
103
  ruling_text = response.json()['choices'][0]['message']['content']
104
+ except Exception as e: ruling_text = f"Inference Error: {str(e)}"
 
 
 
105
  audio_file = generate_tts(ruling_text)
 
 
106
  rulings_log = load_data(RULINGS_FILE)
107
+ new_ruling = {"timestamp": datetime.now().isoformat(), "issue_summary": combined_issue[:200], "ruling": ruling_text, "ruling_hash": hashlib.sha256(ruling_text.encode()).hexdigest()}
 
 
 
 
 
108
  rulings_log.append(new_ruling)
109
  save_data(rulings_log, RULINGS_FILE)
 
110
  return ruling_text, f"Ruling Logged (ID: {new_ruling['ruling_hash'][:8]})", audio_file
111
 
112
  def sync_all(token, dataset_id):
 
126
  for r in data: acts[r['act']] = acts.get(r['act'], 0) + 1
127
  return "\n".join([f"{k}: {v}" for k,v in acts.items()])
128
 
129
+ # --- GRADIO UI ---
130
+
131
+ USER_MANUAL_MD = """
132
+ # โš–๏ธ Legislation & FCA Ruling Manager: User Manual
133
+
134
+ ## ๐Ÿ› ๏ธ Building Your Rulebase
135
+ 1. **Manual Entry**: Go to **Manage Rules** to paste specific sections from acts.
136
+ 2. **Document Ingestion**: Upload **PDF, DOCX, or TXT** files of internal policies or acts.
137
+ 3. **FCA Automation**: Use the **FCA Guidelines** tab to pull the **12 Principles for Businesses (PRIN)**.
138
+
139
+ ## ๐Ÿ›๏ธ Ruling on Issues
140
+ 1. **Describing the Issue**: Go to **Rule on Issues**. Upload an **Issue Document** or type a description.
141
+ 2. **Generating the Ruling**: Ensure your **Inference Settings** are configured, then click **Generate Formal Ruling**.
142
+ 3. **Audible Delivery (TTS)**: Click play on the **Audio Player** to hear the ruling read aloud.
143
+
144
+ ## โ˜๏ธ Sync & Audit
145
+ - Go to **Sync & Audit**, enter your **HF Write Token** and **Dataset ID**, and click **Sync Everything**.
146
+ """
147
+
148
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
149
  gr.Markdown("# โš–๏ธ Legislation & FCA Ruling Manager")
150
 
 
180
  stats_out = gr.Textbox(label="Dataset Inventory", value=view_stats())
181
  refresh_btn = gr.Button("Refresh Inventory")
182
 
183
+ with gr.Tab("๐Ÿฆ FCA Guidelines"):
184
+ gr.Markdown("### ๐Ÿ› ๏ธ FCA Handbook Automation")
185
+ fca_btn = gr.Button("Ingest FCA PRIN Principles", variant="secondary")
186
+ fca_status = gr.Textbox(label="FCA Ingestion Status")
187
+
188
  with gr.Tab("โ˜๏ธ Sync & Audit"):
189
  hf_t = gr.Textbox(label="HF Token", type="password"); hf_d = gr.Textbox(label="Dataset ID")
190
  s_btn = gr.Button("Sync Everything to Dataset")
191
  s_out = gr.Textbox(label="Sync Status")
192
+
193
+ with gr.Tab("๐Ÿ“– User Manual"):
194
+ gr.Markdown(USER_MANUAL_MD)
195
 
196
  rule_btn.click(fn=rule_on_issue, inputs=[issue_desc, issue_file, end, key, mod], outputs=[ruling_out, log_status, audio_out])
197
  doc_btn.click(fn=process_rule_document, inputs=[doc_in, doc_act], outputs=op_status)