Vedika commited on
Commit
a795e9f
·
verified ·
1 Parent(s): 9b19acf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -652
app.py CHANGED
@@ -1,672 +1,92 @@
1
- """
2
- =========================================================================================
3
- ARJUN 2.O - ENTERPRISE BACKEND ARCHITECTURE
4
- =========================================================================================
5
- Author: Abhay Kumar
6
- Architecture: Microservices Pattern within Monolith
7
- Compatibility: Docker, Hugging Face Spaces, AWS, GCP
8
- Description: Highly robust, scalable, and fail-safe Flask backend serving LLM capabilities,
9
- advanced multimodal payload formatting, Edge-TTS synthesis, and system diagnostics.
10
- =========================================================================================
11
- """
12
-
13
  import os
14
- import sys
15
- import json
16
  import time
17
- import uuid
18
  import logging
19
- import asyncio
20
- import tempfile
21
- import threading
22
- import traceback
23
  import requests
24
- import dataclasses
25
- from datetime import datetime
26
- from functools import wraps
27
- from typing import Dict, Any, List, Optional, Generator, Union, Callable
28
-
29
- from flask import (
30
- Flask,
31
- request,
32
- Response,
33
- stream_with_context,
34
- render_template_string,
35
- send_file,
36
- jsonify,
37
- make_response,
38
- g
39
- )
40
-
41
- import edge_tts
42
-
43
- # =========================================================================================
44
- # MODULE 1: ENTERPRISE LOGGING & TELEMETRY
45
- # =========================================================================================
46
-
47
- class EnterpriseFormatter(logging.Formatter):
48
- """
49
- Advanced logging formatter providing color-coded, heavily structured console output
50
- to track complex asynchronous events and HTTP requests effectively.
51
- """
52
- CYAN = "\x1b[36;20m"
53
- GREY = "\x1b[38;20m"
54
- YELLOW = "\x1b[33;20m"
55
- RED = "\x1b[31;20m"
56
- BOLD_RED = "\x1b[31;1m"
57
- GREEN = "\x1b[32;20m"
58
- RESET = "\x1b[0m"
59
-
60
- FORMAT_TEMPLATE = "%(asctime)s | %(levelname)-8s | [ARJUN-CORE] | %(module)s:%(lineno)d | %(message)s"
61
-
62
- FORMATS = {
63
- logging.DEBUG: CYAN + FORMAT_TEMPLATE + RESET,
64
- logging.INFO: GREEN + FORMAT_TEMPLATE + RESET,
65
- logging.WARNING: YELLOW + FORMAT_TEMPLATE + RESET,
66
- logging.ERROR: RED + FORMAT_TEMPLATE + RESET,
67
- logging.CRITICAL: BOLD_RED + FORMAT_TEMPLATE + RESET
68
- }
69
-
70
- def format(self, record: logging.LogRecord) -> str:
71
- log_fmt = self.FORMATS.get(record.levelno, self.FORMAT_TEMPLATE)
72
- formatter = logging.Formatter(log_fmt, datefmt='%Y-%m-%d %H:%M:%S.%f')
73
- return formatter.format(record)
74
-
75
- def setup_enterprise_logger() -> logging.Logger:
76
- """Initializes the global telemetry and logging system."""
77
- logger = logging.getLogger("ArjunEnterprise")
78
- logger.setLevel(logging.DEBUG)
79
-
80
- # Prevent duplicate handlers if module is reloaded
81
- if not logger.handlers:
82
- console_handler = logging.StreamHandler()
83
- console_handler.setFormatter(EnterpriseFormatter())
84
- logger.addHandler(console_handler)
85
-
86
- return logger
87
-
88
- logger = setup_enterprise_logger()
89
-
90
- # =========================================================================================
91
- # MODULE 2: EXCEPTION HIERARCHY
92
- # =========================================================================================
93
-
94
- class ArjunSystemException(Exception):
95
- """Base exception for all Arjun Core related faults."""
96
- def __init__(self, message: str, status_code: int = 500, payload: dict = None):
97
- super().__init__(message)
98
- self.message = message
99
- self.status_code = status_code
100
- self.payload = payload or {}
101
-
102
- class EnvironmentConfigurationFault(ArjunSystemException):
103
- """Raised when critical deployment secrets are missing."""
104
- pass
105
-
106
- class UpstreamGatewayTimeout(ArjunSystemException):
107
- """Raised when the Hugging Face / LLM provider takes too long to respond."""
108
- pass
109
-
110
- class PayloadFormattingError(ArjunSystemException):
111
- """Raised when the incoming JSON cannot be transformed into API-compliant schema."""
112
- pass
113
-
114
- # =========================================================================================
115
- # MODULE 3: DEPLOYMENT SECRETS & CONFIGURATION MANAGER
116
- # =========================================================================================
117
-
118
- @dataclasses.dataclass
119
- class SystemState:
120
- boot_time: float = time.time()
121
- total_requests_served: int = 0
122
- total_errors_caught: int = 0
123
-
124
- state = SystemState()
125
-
126
- class ConfigurationManager:
127
- """
128
- Singleton pattern configuration manager. Secures runtime variables and ensures
129
- zero hardcoded credentials exist within the executable code.
130
- """
131
- _instance = None
132
-
133
- def __new__(cls):
134
- if cls._instance is None:
135
- cls._instance = super(ConfigurationManager, cls).__new__(cls)
136
- cls._instance._initialize()
137
- return cls._instance
138
-
139
- def _initialize(self):
140
- logger.info("Bootstrapping Configuration Manager...")
141
-
142
- self.api_key = os.environ.get("YOUR_VEDIKA_API_KEY", "")
143
- self.base_url = os.environ.get("BASE_URL", "")
144
- self.model_id = os.environ.get("MODEL_ID", "")
145
-
146
- self.invoke_url = self._build_secure_endpoint(self.base_url)
147
- self.verify_integrity()
148
-
149
- def _build_secure_endpoint(self, base: str) -> str:
150
- """Constructs the exact completion endpoint avoiding double slashes."""
151
- if not base:
152
- return ""
153
- base = base.strip()
154
- if not base.endswith("/chat/completions"):
155
- return f"{base.rstrip('/')}/chat/completions"
156
- return base
157
-
158
- def verify_integrity(self) -> bool:
159
- """Audits the environment. Will not crash, but logs critical warnings."""
160
- missing_vars = []
161
- if not self.api_key: missing_vars.append("YOUR_VEDIKA_API_KEY")
162
- if not self.base_url: missing_vars.append("BASE_URL")
163
- if not self.model_id: missing_vars.append("MODEL_ID")
164
-
165
- if missing_vars:
166
- logger.critical(f"ENVIRONMENT AUDIT FAILED. Missing Secrets: {', '.join(missing_vars)}")
167
- return False
168
-
169
- logger.info(f"Environment Audit Passed. Target Model: {self.model_id}")
170
- return True
171
-
172
- config = ConfigurationManager()
173
-
174
- # =========================================================================================
175
- # MODULE 4: CIRCUIT BREAKER & RETRY MECHANISMS
176
- # =========================================================================================
177
-
178
- def with_retry(max_retries: int = 3, backoff_factor: float = 1.5):
179
- """
180
- Enterprise decorator: Automatically retries failing network requests.
181
- Prevents the backend from failing immediately due to micro-outages.
182
- """
183
- def decorator(func: Callable):
184
- @wraps(func)
185
- def wrapper(*args, **kwargs):
186
- retries = 0
187
- while retries < max_retries:
188
- try:
189
- return func(*args, **kwargs)
190
- except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
191
- retries += 1
192
- logger.warning(f"Network fault detected ({str(e)}). Retry {retries}/{max_retries} executing...")
193
- time.sleep(backoff_factor * retries)
194
- logger.error("Maximum retries exhausted. Circuit Breaker triggered.")
195
- raise UpstreamGatewayTimeout("Upstream AI Matrix is currently unreachable.", 504)
196
- return wrapper
197
- return decorator
198
-
199
- # =========================================================================================
200
- # MODULE 5: TEMPORARY ASSET & GARBAGE COLLECTION SYSTEM
201
- # =========================================================================================
202
-
203
- class AssetGarbageCollector:
204
- """
205
- Manages temporary files (like synthesized audio) to ensure Docker instances
206
- and Hugging Face spaces do not run out of ephemeral storage over time.
207
- """
208
- def __init__(self):
209
- self.storage_directory = tempfile.gettempdir()
210
- self.registry = set()
211
- logger.info(f"Garbage Collector initialized at virtual mount: {self.storage_directory}")
212
-
213
- def allocate_file(self, prefix: str = "arjun_asset_", extension: str = ".tmp") -> str:
214
- """Allocates a cryptographically unique file path."""
215
- file_id = uuid.uuid4().hex
216
- secure_path = os.path.join(self.storage_directory, f"{prefix}{file_id}{extension}")
217
- self.registry.add(secure_path)
218
- return secure_path
219
-
220
- def schedule_demolition(self, target_path: str, lifespan_seconds: int = 120):
221
- """Asynchronously wipes files from disk after they are served to the client."""
222
- def _demolish():
223
- time.sleep(lifespan_seconds)
224
- try:
225
- if os.path.exists(target_path):
226
- os.remove(target_path)
227
- logger.debug(f"[GC] Securely wiped temporary asset: {target_path}")
228
- if target_path in self.registry:
229
- self.registry.remove(target_path)
230
- except Exception as e:
231
- logger.error(f"[GC] Failed to wipe asset {target_path}: {str(e)}")
232
-
233
- demolition_thread = threading.Thread(target=_demolish, daemon=True)
234
- demolition_thread.start()
235
-
236
- gc_system = AssetGarbageCollector()
237
-
238
- # =========================================================================================
239
- # MODULE 6: NEURAL ACOUSTIC ENGINE (EDGE TTS WRAPPER)
240
- # =========================================================================================
241
-
242
- class NeuralAcousticEngine:
243
- """
244
- Bridges Flask's synchronous architecture with Edge-TTS asynchronous nature.
245
- Utilizes isolated event loops to prevent thread blocking and server hangs.
246
- """
247
- def __init__(self):
248
- # Default Voice: Christopher for English, but dynamically handled usually
249
- self.default_voice = "en-US-ChristopherNeural"
250
- self.default_pitch = "+0%"
251
- self.default_rate = "+0%"
252
- logger.info("Neural Acoustic Engine (Edge-TTS) armed and ready.")
253
-
254
- def synthesize_speech(self, text: str, output_path: str, lang_code: str = 'en') -> bool:
255
- """Executes the synthesis in an isolated asyncio loop."""
256
- sanitized_text = self._sanitize_text(text)
257
- if not sanitized_text:
258
- logger.warning("TTS aborted: Text was empty post-sanitization.")
259
- return False
260
-
261
- # Dynamic voice selection based on detected or requested language
262
- target_voice = "hi-IN-MadhurNeural" if lang_code == 'hi' else self.default_voice
263
-
264
- logger.info(f"Initiating acoustic synthesis. Length: {len(sanitized_text)} chars. Voice: {target_voice}")
265
-
266
- async def _async_compile():
267
- try:
268
- communicator = edge_tts.Communicate(
269
- text=sanitized_text,
270
- voice=target_voice,
271
- pitch=self.default_pitch,
272
- rate=self.default_rate
273
- )
274
- await communicator.save(output_path)
275
- return True
276
- except Exception as e:
277
- logger.error(f"TTS Compilation Failure: {str(e)}")
278
- return False
279
-
280
- # Isolated Event Loop Execution
281
- isolated_loop = asyncio.new_event_loop()
282
- asyncio.set_event_loop(isolated_loop)
283
- try:
284
- success = isolated_loop.run_until_complete(_async_compile())
285
- return success
286
- except Exception as err:
287
- logger.error(f"Event Loop Integrity Failure during TTS: {str(err)}")
288
- return False
289
- finally:
290
- isolated_loop.close()
291
-
292
- def _sanitize_text(self, raw_text: str) -> str:
293
- """Strips markdown, code blocks, and reasoning tags before passing to audio generator."""
294
- import re
295
- text = re.sub(r'```.*?
296
- ```', ' Code block omitted for audio. ', raw_text, flags=re.DOTALL)
297
- text = re.sub(r'!\[.*?\]\(.*?\)', '', text)
298
- text = re.sub(r'\[.*?\]\(.*?\)', '', text)
299
- text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
300
- text = text.replace('*', '').replace('_', '').replace('`', '').replace('#', '')
301
- return text.strip()
302
-
303
- acoustic_engine = NeuralAcousticEngine()
304
-
305
- # =========================================================================================
306
- # MODULE 7: LLM PAYLOAD ARCHITECT & STREAM MANAGER
307
- # =========================================================================================
308
 
309
- class LLMGateway:
310
- """
311
- The core logic hub for interacting with upstream Hugging Face Inference endpoints.
312
- Responsible for intelligent payload morphing based on attachment presence.
313
- """
314
- def __init__(self, config_ref: ConfigurationManager):
315
- self.cfg = config_ref
316
 
317
- def format_history(self, history: List[Dict]) -> List[Dict]:
318
- """Ensures the history strictly matches OpenAI/HF specs (user/assistant)."""
319
- formatted = []
320
- for msg in history:
321
- # Map frontend 'bot' to standard 'assistant'
322
- role = "assistant" if msg.get("role") == "bot" else "user"
323
- content = str(msg.get("content", ""))
324
- if content.strip():
325
- formatted.append({"role": role, "content": content})
326
- return formatted
327
 
328
- def build_payload(self, user_msg: str, attachments: List[Dict], sys_prompt: str, history: List[Dict]) -> List[Dict]:
329
- """
330
- CRITICAL LOGIC: Morphs the payload based on context.
331
- If no attachments exist, 'content' MUST be a string to avoid 400 Bad Requests on standard text models.
332
- If attachments exist, 'content' becomes a multimodal List[Dict].
333
- """
334
- messages = []
 
 
 
 
 
 
 
 
335
 
336
- # 1. System Directive
337
- if sys_prompt and sys_prompt.strip():
338
- messages.append({"role": "system", "content": sys_prompt.strip()})
339
-
340
- # 2. Historical Context
341
- messages.extend(self.format_history(history))
342
-
343
- # 3. Current Turn Analysis
344
- if not attachments:
345
- # STANDARD TEXT MODE (Prevents API crashes)
346
- safe_text = user_msg.strip() if user_msg.strip() else "Hello."
347
- messages.append({"role": "user", "content": safe_text})
348
- logger.debug("Payload formulated as STRICT TEXT (No attachments).")
349
- else:
350
- # MULTIMODAL MODE (Vision / Audio capable endpoints)
351
- content_array = []
352
- if user_msg.strip():
353
- content_array.append({"type": "text", "text": user_message.strip()})
354
-
355
- for att in attachments:
356
- att_type = att.get("type")
357
- b64_data = att.get("data")
358
-
359
- if not b64_data: continue
360
-
361
- if att_type == "image":
362
- content_array.append({
363
- "type": "image_url",
364
- "image_url": {"url": f"data:image/jpeg;base64,{b64_data}"}
365
- })
366
- elif att_type in ["audio", "file", "document", "video"]:
367
- # Depending on backend capability, we append it.
368
- # Note: Many endpoints ignore audio, but we construct it properly anyway.
369
- content_array.append({
370
- "type": "input_audio",
371
- "input_audio": {"data": b64_data, "format": "wav"}
372
- })
373
 
374
- if not content_array:
375
- content_array.append({"type": "text", "text": "Hello."})
376
-
377
- messages.append({"role": "user", "content": content_array})
378
- logger.debug(f"Payload formulated as MULTIMODAL. Items: {len(content_array)}")
379
-
 
 
 
380
  return messages
381
 
382
- def execute_stream(self, api_payload: Dict[str, Any]) -> Generator[str, None, None]:
383
- """
384
- Opens a persistent connection to the Upstream LLM, reads the stream chunk by chunk,
385
- and yields it directly back to the Flask client.
386
- """
387
- headers = {
388
- "Authorization": f"Bearer {self.cfg.api_key}",
389
- "Accept": "text/event-stream",
390
- "Content-Type": "application/json"
391
- }
392
-
393
- logger.info(f"Opening Streaming Vector to: {self.cfg.invoke_url}")
394
-
395
- try:
396
- with requests.post(
397
- self.cfg.invoke_url,
398
- headers=headers,
399
- json=api_payload,
400
- stream=True,
401
- timeout=180 # Extended timeout for massive reasoning models
402
- ) as response:
403
-
404
- if response.status_code != 200:
405
- err_txt = response.text
406
- logger.error(f"Upstream API Failure [{response.status_code}]: {err_txt}")
407
- error_json = json.dumps({"choices": [{"delta": {"content": f"\n\n**CRITICAL UPSTREAM ERROR {response.status_code}:**\nThe AI Provider rejected the payload. Ensure your model supports the requested features.\n\n`{err_txt[:200]}`"}}]})
408
- yield f"data: {error_json}\n\n"
409
- yield "data: [DONE]\n\n"
410
- return
411
-
412
- # Successfully connected. Begin data relay.
413
- for raw_bytes in response.iter_lines():
414
- if raw_bytes:
415
- decoded_string = raw_bytes.decode("utf-8")
416
- if decoded_string.startswith("data: "):
417
- yield decoded_string + "\n\n"
418
-
419
- except requests.exceptions.Timeout:
420
- logger.error("Upstream Gateway Timeout.")
421
- yield f"data: {json.dumps({'choices': [{'delta': {'content': '**System Alert:** Connection to the AI matrix timed out.'}}]})}\n\n"
422
- yield "data: [DONE]\n\n"
423
-
424
- except requests.exceptions.RequestException as e:
425
- logger.error(f"Upstream Network Disconnect: {str(e)}")
426
- yield f"data: {json.dumps({'choices': [{'delta': {'content': '**System Alert:** Network disconnect detected.'}}]})}\n\n"
427
- yield "data: [DONE]\n\n"
428
-
429
- except Exception as e:
430
- logger.error(f"Stream Interpreter Crash: {str(e)}")
431
- traceback.print_exc()
432
- yield f"data: {json.dumps({'choices': [{'delta': {'content': '**System Alert:** Internal processing failure during stream.'}}]})}\n\n"
433
- yield "data: [DONE]\n\n"
434
-
435
- llm_gateway = LLMGateway(config)
436
-
437
- # =========================================================================================
438
- # MODULE 8: FLASK APPLICATION & ROUTING ARCHITECTURE
439
- # =========================================================================================
440
-
441
- app = Flask(__name__)
442
- app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50 MB Max upload size limitation
443
-
444
- @app.before_request
445
- def intercept_request():
446
- """Middleware: Analytics and Security Checks"""
447
- g.start_time = time.time()
448
- logger.debug(f"Intercepted Request: {request.method} {request.path}")
449
-
450
- @app.after_request
451
- def inject_security_headers(response):
452
- """Middleware: Injects Cross-Origin Resource Sharing and Security Headers"""
453
- response.headers["Access-Control-Allow-Origin"] = "*"
454
- response.headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
455
- response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
456
- response.headers["X-Powered-By"] = "Arjun Intelligence Core"
457
- response.headers["X-Frame-Options"] = "SAMEORIGIN"
458
-
459
- if hasattr(g, 'start_time'):
460
- latency = (time.time() - g.start_time) * 1000
461
- logger.debug(f"Request resolved in {latency:.2f}ms")
462
-
463
- return response
464
-
465
- # -----------------------------------------------------------------------------------------
466
- # ENDPOINT: FRONTEND SERVING
467
- # -----------------------------------------------------------------------------------------
468
- @app.route('/', methods=['GET'])
469
- def render_interface():
470
- """Serves the primary monolithic HTML application."""
471
- logger.info("Serving Application Interface.")
472
- try:
473
- base_dir = os.path.dirname(os.path.abspath(__file__))
474
- html_path = os.path.join(base_dir, 'index.html')
475
- with open(html_path, 'r', encoding='utf-8') as file:
476
- return render_template_string(file.read())
477
- except FileNotFoundError:
478
- logger.critical("Primary UI file 'index.html' is missing from the directory.")
479
- return make_response(
480
- "<h1>Fatal Error 404</h1><p>The core UI file 'index.html' could not be located on the server disk.</p>",
481
- 404
482
- )
483
- except Exception as e:
484
- logger.error(f"Template Rendering Failure: {str(e)}")
485
- return make_response(f"<h1>Server Fault 500</h1><p>{str(e)}</p>", 500)
486
-
487
- # -----------------------------------------------------------------------------------------
488
- # ENDPOINT: LLM CHAT PROCESSING
489
- # -----------------------------------------------------------------------------------------
490
- @app.route('/api/chat', methods=['POST', 'OPTIONS'])
491
- def process_chat_transaction():
492
- """
493
- Main Gateway Endpoint. Receives JSON from frontend, builds appropriate payload,
494
- and proxies the streaming response back to the client.
495
- """
496
- if request.method == 'OPTIONS':
497
- return Response(status=200)
498
-
499
- state.total_requests_served += 1
500
-
501
- # Configuration Guard
502
- if not config.api_key or not config.invoke_url or not config.model_id:
503
- logger.critical("Transaction blocked. System configuration invalid.")
504
- return jsonify({"error": "Backend misconfigured. API Keys missing."}), 500
505
-
506
- # JSON Parsing Guard
507
- try:
508
- payload_data = request.get_json() or {}
509
- except Exception as e:
510
- logger.error(f"Malformed JSON intercepted: {str(e)}")
511
- return jsonify({"error": "Payload must be strictly valid JSON."}), 400
512
-
513
- user_text = payload_data.get("message", "")
514
- attachments = payload_data.get("attachments", [])
515
- system_prompt = payload_data.get("system_prompt", "")
516
- history = payload_data.get("history", [])
517
- max_tokens = payload_data.get("max_tokens", 4096)
518
- temperature = payload_data.get("temperature", 0.75)
519
-
520
- logger.info(f"Processing transaction. History Length: {len(history)} | Attachments: {len(attachments)}")
521
-
522
- # Construct the highly-optimized payload
523
- try:
524
- mapped_messages = llm_gateway.build_payload(user_text, attachments, system_prompt, history)
525
- except Exception as e:
526
- logger.error(f"Payload Compilation Error: {str(e)}")
527
- traceback.print_exc()
528
- return jsonify({"error": "Internal Error formatting LLM payload."}), 500
529
-
530
- api_dispatch_json = {
531
- "model": config.model_id,
532
- "messages": mapped_messages,
533
- "max_tokens": int(max_tokens),
534
- "temperature": float(temperature),
535
- "top_p": 0.85, # Slightly broadened for better code generation
536
- "stream": True
537
- }
538
-
539
- # Execute stream relay
540
- return Response(
541
- stream_with_context(llm_gateway.execute_stream(api_dispatch_json)),
542
- mimetype='text/event-stream'
543
- )
544
-
545
- # -----------------------------------------------------------------------------------------
546
- # ENDPOINT: NATIVE TTS FALLBACK (EDGE-TTS)
547
- # -----------------------------------------------------------------------------------------
548
- @app.route('/api/tts', methods=['POST', 'OPTIONS'])
549
- def synthesize_audio():
550
- """
551
- Fallback TTS Endpoint.
552
- Though frontend uses Gradio primarily, this remains as an internal fallback
553
- and microservice utility. Converts text to speech locally.
554
- """
555
- if request.method == 'OPTIONS':
556
- return Response(status=200)
557
-
558
  try:
559
- data = request.get_json() or {}
560
- text_content = data.get("text", "").strip()
561
- lang_mode = data.get("lang", "en") # 'en' or 'hi'
 
 
 
 
562
  except Exception as e:
563
- logger.error(f"Malformed JSON in TTS request: {str(e)}")
564
- return jsonify({"error": "Invalid payload format"}), 400
565
-
566
- if not text_content:
567
- return jsonify({"error": "Empty text payload provided."}), 400
568
-
569
- logger.info(f"TTS requested for {len(text_content)} characters. Lang: {lang_mode}")
 
570
 
571
- output_path = gc_system.allocate_file(prefix="arjun_tts_", extension=".mp3")
572
-
573
- # Synchronously await asynchronous compilation
574
- success = acoustic_engine.synthesize_speech(text_content, output_path, lang_code=lang_mode)
575
-
576
- if not success or not os.path.exists(output_path):
577
- logger.error("Acoustic engine failed to finalize the asset.")
578
- return jsonify({"error": "Acoustic generation failed."}), 500
579
-
580
- logger.info(f"Acoustic asset finalized: {output_path}")
581
 
582
- # Fire-and-forget destruction timer
583
- gc_system.schedule_demolition(output_path, lifespan_seconds=90)
 
 
 
 
584
 
585
- try:
586
- return send_file(
587
- output_path,
588
- mimetype="audio/mpeg",
589
- as_attachment=False,
590
- download_name="arjun_transmission.mp3"
591
- )
592
- except Exception as e:
593
- logger.error(f"Transmission failure of acoustic asset: {str(e)}")
594
- return jsonify({"error": "Failed to transmit binary audio data."}), 500
595
 
596
- # -----------------------------------------------------------------------------------------
597
- # ENDPOINT: SYSTEM DIAGNOSTICS & HEALTH
598
- # -----------------------------------------------------------------------------------------
599
  @app.route('/health', methods=['GET'])
600
- def system_health_check():
601
- """Detailed health check endpoint for Load Balancers and Docker health checks."""
602
- uptime_seconds = time.time() - state.boot_time
603
-
604
- health_report = {
605
- "status": "OPERATIONAL",
606
- "system_name": "Arjun Core Version 2.0",
607
- "author": "Abhay Kumar",
608
- "diagnostics": {
609
- "uptime_seconds": round(uptime_seconds, 2),
610
- "requests_processed": state.total_requests_served,
611
- "temporary_assets_tracked": len(gc_system.registry),
612
- "configuration_status": "Valid" if config.verify_integrity() else "Compromised"
613
- },
614
- "timestamp_utc": datetime.utcnow().isoformat()
615
- }
616
- return jsonify(health_report), 200
617
-
618
-
619
- # =========================================================================================
620
- # MODULE 9: GLOBAL ERROR HANDLERS
621
- # =========================================================================================
622
- @app.errorhandler(404)
623
- def handle_404(error):
624
- state.total_errors_caught += 1
625
- logger.warning(f"Unmatched Route Requested: {request.path}")
626
- return jsonify({"error": "Endpoint not found within the Arjun routing matrix."}), 404
627
-
628
- @app.errorhandler(405)
629
- def handle_405(error):
630
- return jsonify({"error": "Method Not Allowed."}), 405
631
-
632
- @app.errorhandler(500)
633
- def handle_500(error):
634
- state.total_errors_caught += 1
635
- logger.error(f"Unhandled Server Exception Triggered on {request.path}")
636
- return jsonify({"error": "Internal Server Failure. Check logs."}), 500
637
-
638
- # =========================================================================================
639
- # MODULE 10: EXECUTION BOOTSTRAP
640
- # =========================================================================================
641
- def display_terminal_splash():
642
- """Prints an impressive ASCII art splash screen to the standard output upon boot."""
643
- splash_text = """
644
- =======================================================================
645
- █████╗ ██████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ ██████╗
646
- ██╔══██╗██╔══██╗ ██║██║ ██║████╗ ██║ ╚════██╗ ██╔═══██╗
647
- ███████║██████╔╝ ██║██║ ██║██╔██╗ ██║ █████╔╝ ██║ ██║
648
- ██╔══██║██╔══██╗██ ██║██║ ██║██║╚██╗██║ ██╔═══╝ ██║ ██║
649
- ██║ ██║██║ ██║╚█████╔╝╚██████╔╝██║ ╚████║ ███████╗ ╚██████╔╝
650
- ╚═╝ ╚═╝╚═╝ ╚═╝ ╚════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚══════╝ ╚═════╝
651
- =======================================================================
652
- Architecture : Enterprise AI Matrix
653
- Author : Abhay Kumar
654
- Version : 2.0 (Production Stable)
655
- Protocols : Edge-TTS, Dynamic Context Mapping, Secure Streams
656
- =======================================================================
657
- """
658
- # Print securely
659
- print("\x1b[36;1m" + splash_text + "\x1b[0m", flush=True)
660
 
661
  if __name__ == '__main__':
662
- # Initialize terminal visuals
663
- display_terminal_splash()
664
-
665
- # Retrieve port bindings (Default 7860 for Hugging Face Spaces compatibility)
666
- target_port = int(os.environ.get("PORT", 7860))
667
-
668
- logger.info(f"Ignition sequence initiated. Binding server to 0.0.0.0:{target_port}")
669
-
670
- # Using Flask's threaded server.
671
- # For hardcore production on AWS/GCP, wrap this with Gunicorn: gunicorn -w 4 -k gevent app:app
672
- app.run(host='0.0.0.0', port=target_port, threaded=True, debug=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
 
 
2
  import time
3
+ import json
4
  import logging
 
 
 
 
5
  import requests
6
+ import traceback
7
+ from typing import Dict, Any, List, Generator
8
+ from flask import Flask, request, Response, stream_with_context, jsonify
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ # --- सेटअप: लॉगिंग और कॉन्फिग ---
11
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - ARJUN-CORE-V3 - %(levelname)s - %(message)s')
12
+ logger = logging.getLogger("ArjunCoreV3")
 
 
 
 
13
 
14
+ app = Flask(__name__)
 
 
 
 
 
 
 
 
 
15
 
16
+ # कॉन्फ़िगरेशन मैनेजमेंट (बिना किसी हार्डकोडिंग के)
17
+ class Config:
18
+ API_KEY = os.environ.get("YOUR_VEDIKA_API_KEY")
19
+ ENDPOINT = os.environ.get("BASE_URL")
20
+ MODEL_ID = os.environ.get("MODEL_ID")
21
+
22
+ @classmethod
23
+ def is_ready(cls):
24
+ return all([cls.API_KEY, cls.ENDPOINT, cls.MODEL_ID])
25
+
26
+ # --- पेलोड बिल्डर: मॉडल की ज़रूरत के अनुसार डेटा बनाना ---
27
+ class PayloadBuilder:
28
+ @staticmethod
29
+ def construct(user_msg: str, history: List[Dict], system_prompt: str, attachments: List[Dict]):
30
+ messages = [{"role": "system", "content": system_prompt or "You are a helpful assistant."}]
31
 
32
+ # हिस्ट्री जोड़ना
33
+ for h in history:
34
+ messages.append({"role": h.get("role", "user"), "content": h.get("content", "")})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
+ # मल्टीमॉडल या टेक्स्ट पेलोड का चयन
37
+ if attachments:
38
+ content = [{"type": "text", "text": user_msg}]
39
+ for att in attachments:
40
+ if att.get("type") == "image":
41
+ content.append({"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{att.get('data')}"}})
42
+ messages.append({"role": "user", "content": content})
43
+ else:
44
+ messages.append({"role": "user", "content": user_msg})
45
  return messages
46
 
47
+ # --- स्ट्रीम हैंडलर: LLM से रिस्पॉन्स लाना ---
48
+ def stream_llm_response(payload: Dict):
49
+ headers = {"Authorization": f"Bearer {Config.API_KEY}", "Content-Type": "application/json"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  try:
51
+ with requests.post(Config.ENDPOINT, headers=headers, json=payload, stream=True, timeout=60) as r:
52
+ if r.status_code != 200:
53
+ yield f"data: {json.dumps({'error': 'API Error', 'code': r.status_code})}\n\n"
54
+ return
55
+ for line in r.iter_lines():
56
+ if line:
57
+ yield line.decode('utf-8') + "\n\n"
58
  except Exception as e:
59
+ logger.error(f"Stream Error: {e}")
60
+ yield f"data: {json.dumps({'error': 'Connection Lost'})}\n\n"
61
+
62
+ # --- API रूट्स ---
63
+ @app.route('/api/chat', methods=['POST'])
64
+ def chat():
65
+ if not Config.is_ready():
66
+ return jsonify({"error": "Server not configured"}), 500
67
 
68
+ data = request.json
69
+ messages = PayloadBuilder.construct(
70
+ data.get("message", ""),
71
+ data.get("history", []),
72
+ data.get("system_prompt", ""),
73
+ data.get("attachments", [])
74
+ )
 
 
 
75
 
76
+ payload = {
77
+ "model": Config.MODEL_ID,
78
+ "messages": messages,
79
+ "stream": True,
80
+ "temperature": data.get("temperature", 0.7)
81
+ }
82
 
83
+ return Response(stream_with_context(stream_llm_response(payload)), mimetype='text/event-stream')
 
 
 
 
 
 
 
 
 
84
 
 
 
 
85
  @app.route('/health', methods=['GET'])
86
+ def health():
87
+ return jsonify({"status": "Arjun Core V3 Online", "timestamp": time.time()})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  if __name__ == '__main__':
90
+ port = int(os.environ.get("PORT", 7860))
91
+ logger.info(f"Arjun Core V3 starting on port {port}...")
92
+ app.run(host='0.0.0.0', port=port, threaded=True)