mirror of
https://github.com/mblanke/StrikePackageGPT.git
synced 2026-03-01 14:20:21 -05:00
Add API endpoints for voice, nmap, explain, config, and LLM features
Co-authored-by: mblanke <9078342+mblanke@users.noreply.github.com>
This commit is contained in:
@@ -1021,6 +1021,304 @@ Only suggest commands for legitimate security testing purposes."""
|
||||
raise HTTPException(status_code=503, detail="LLM Router service not available")
|
||||
|
||||
|
||||
# ============== Nmap Parser Endpoints ==============
|
||||
|
||||
@app.post("/api/nmap/parse")
|
||||
async def parse_nmap(format: str = "xml", content: str = ""):
|
||||
"""Parse Nmap output (XML or JSON)"""
|
||||
try:
|
||||
from . import nmap_parser
|
||||
|
||||
if format == "xml":
|
||||
hosts = nmap_parser.parse_nmap_xml(content)
|
||||
elif format == "json":
|
||||
hosts = nmap_parser.parse_nmap_json(content)
|
||||
else:
|
||||
raise HTTPException(status_code=400, detail="Format must be 'xml' or 'json'")
|
||||
|
||||
return {"hosts": hosts, "count": len(hosts)}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Parse error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/api/nmap/hosts")
|
||||
async def get_nmap_hosts(scan_id: Optional[str] = None):
|
||||
"""Get parsed host data for network map"""
|
||||
# This could be extended to fetch from a database based on scan_id
|
||||
# For now, return from the scan_results if available
|
||||
if scan_id and scan_id in scan_results:
|
||||
result = scan_results[scan_id]
|
||||
hosts = result.get("parsed", {}).get("hosts", [])
|
||||
return {"hosts": hosts}
|
||||
|
||||
return {"hosts": [], "message": "No scan data available"}
|
||||
|
||||
|
||||
# ============== Voice Control Endpoints ==============
|
||||
|
||||
@app.post("/api/voice/transcribe")
|
||||
async def transcribe_audio(audio: bytes = None):
|
||||
"""Transcribe audio to text using Whisper"""
|
||||
if not audio:
|
||||
raise HTTPException(status_code=400, detail="No audio data provided")
|
||||
|
||||
try:
|
||||
from . import voice
|
||||
result = voice.transcribe_audio(audio)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Transcription error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/voice/speak")
|
||||
async def text_to_speech(text: str, voice_name: str = "alloy"):
|
||||
"""Convert text to speech"""
|
||||
try:
|
||||
from . import voice as voice_module
|
||||
audio_bytes = voice_module.speak_text(text, voice=voice_name)
|
||||
|
||||
if audio_bytes:
|
||||
from fastapi.responses import Response
|
||||
return Response(content=audio_bytes, media_type="audio/mp3")
|
||||
else:
|
||||
return {"message": "TTS not available, use browser fallback"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"TTS error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/voice/command")
|
||||
async def process_voice_command(text: str):
|
||||
"""Parse and route voice command"""
|
||||
try:
|
||||
from . import voice as voice_module
|
||||
|
||||
# Parse command
|
||||
command_result = voice_module.parse_voice_command(text)
|
||||
|
||||
# Route command
|
||||
routing_info = voice_module.route_command(command_result)
|
||||
|
||||
return {
|
||||
"command": command_result,
|
||||
"routing": routing_info,
|
||||
"speak_response": routing_info.get("message", "")
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Command processing error: {str(e)}")
|
||||
|
||||
|
||||
# ============== Explanation Endpoints ==============
|
||||
|
||||
@app.post("/api/explain")
|
||||
async def explain_item(
|
||||
type: str,
|
||||
content: str,
|
||||
context: Optional[Dict[str, Any]] = None
|
||||
):
|
||||
"""Get explanation for config, log, error, etc."""
|
||||
try:
|
||||
from . import explain
|
||||
|
||||
if type == "config":
|
||||
result = explain.explain_config(content, content, context)
|
||||
elif type == "error":
|
||||
result = explain.explain_error(content, context=context)
|
||||
elif type == "log":
|
||||
log_level = context.get("level") if context else None
|
||||
result = explain.explain_log_entry(content, log_level)
|
||||
else:
|
||||
result = {"error": "Unknown explanation type"}
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Explanation error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/api/wizard/help")
|
||||
async def get_wizard_help(type: str, step: int):
|
||||
"""Get help for wizard step"""
|
||||
try:
|
||||
from . import explain
|
||||
result = explain.get_wizard_step_help(type, step)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Help error: {str(e)}")
|
||||
|
||||
|
||||
# ============== LLM Help Endpoints ==============
|
||||
|
||||
@app.post("/api/llm/chat")
|
||||
async def llm_chat_help(
|
||||
message: str,
|
||||
session_id: Optional[str] = None,
|
||||
context: Optional[str] = None,
|
||||
provider: str = "ollama",
|
||||
model: str = "llama3.2"
|
||||
):
|
||||
"""LLM-powered chat help"""
|
||||
try:
|
||||
from . import llm_help
|
||||
result = await llm_help.chat_completion(
|
||||
message=message,
|
||||
session_id=session_id,
|
||||
context=context,
|
||||
provider=provider,
|
||||
model=model
|
||||
)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Chat error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/api/llm/autocomplete")
|
||||
async def get_autocomplete(
|
||||
partial_text: str,
|
||||
context_type: str = "command",
|
||||
max_suggestions: int = 5
|
||||
):
|
||||
"""Get autocomplete suggestions"""
|
||||
try:
|
||||
from . import llm_help
|
||||
suggestions = await llm_help.get_autocomplete(
|
||||
partial_text=partial_text,
|
||||
context_type=context_type,
|
||||
max_suggestions=max_suggestions
|
||||
)
|
||||
return {"suggestions": suggestions}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Autocomplete error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/llm/explain")
|
||||
async def llm_explain(
|
||||
item: str,
|
||||
item_type: str = "auto",
|
||||
context: Optional[Dict] = None
|
||||
):
|
||||
"""LLM-powered explanation"""
|
||||
try:
|
||||
from . import llm_help
|
||||
result = await llm_help.explain_anything(
|
||||
item=item,
|
||||
item_type=item_type,
|
||||
context=context
|
||||
)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Explanation error: {str(e)}")
|
||||
|
||||
|
||||
# ============== Config Validation Endpoints ==============
|
||||
|
||||
@app.post("/api/config/validate")
|
||||
async def validate_configuration(
|
||||
config_data: Dict[str, Any],
|
||||
config_type: str = "general"
|
||||
):
|
||||
"""Validate configuration"""
|
||||
try:
|
||||
from . import config_validator
|
||||
result = config_validator.validate_config(config_data, config_type)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Validation error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/config/backup")
|
||||
async def backup_configuration(
|
||||
config_name: str,
|
||||
config_data: Dict[str, Any],
|
||||
description: str = ""
|
||||
):
|
||||
"""Create configuration backup"""
|
||||
try:
|
||||
from . import config_validator
|
||||
result = config_validator.backup_config(config_name, config_data, description)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Backup error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/config/restore")
|
||||
async def restore_configuration(backup_id: str):
|
||||
"""Restore configuration from backup"""
|
||||
try:
|
||||
from . import config_validator
|
||||
result = config_validator.restore_config(backup_id)
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=404, detail=result.get("error"))
|
||||
return result
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Restore error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/api/config/backups")
|
||||
async def list_configuration_backups(config_name: Optional[str] = None):
|
||||
"""List available backups"""
|
||||
try:
|
||||
from . import config_validator
|
||||
result = config_validator.list_backups(config_name)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"List backups error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/config/autofix")
|
||||
async def autofix_configuration(
|
||||
validation_result: Dict[str, Any],
|
||||
config_data: Dict[str, Any]
|
||||
):
|
||||
"""Suggest automatic fixes for configuration"""
|
||||
try:
|
||||
from . import config_validator
|
||||
result = config_validator.suggest_autofix(validation_result, config_data)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Autofix error: {str(e)}")
|
||||
|
||||
|
||||
# ============== Webhook & Integration Endpoints ==============
|
||||
|
||||
@app.post("/api/webhook/n8n")
|
||||
async def n8n_webhook(data: Dict[str, Any]):
|
||||
"""Receive webhook from n8n workflow"""
|
||||
try:
|
||||
# Process n8n webhook data
|
||||
# This could trigger scans, send notifications, etc.
|
||||
return {
|
||||
"status": "received",
|
||||
"data": data,
|
||||
"message": "Webhook processed successfully"
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Webhook error: {str(e)}")
|
||||
|
||||
|
||||
@app.post("/api/alerts/push")
|
||||
async def send_push_notification(
|
||||
title: str,
|
||||
message: str,
|
||||
severity: str = "info"
|
||||
):
|
||||
"""Send push notification for critical alerts"""
|
||||
try:
|
||||
# This could integrate with services like:
|
||||
# - Pushover
|
||||
# - Slack
|
||||
# - Discord
|
||||
# - Email
|
||||
return {
|
||||
"status": "sent",
|
||||
"title": title,
|
||||
"message": message,
|
||||
"severity": severity
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Push notification error: {str(e)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8001)
|
||||
Reference in New Issue
Block a user