mirror of
https://github.com/Rarebuffalo/securelens-backend.git
synced 2026-06-19 07:00:30 +00:00
added cli installer ]
This commit is contained in:
77
cli/securelens/ai/__init__.py
Normal file
77
cli/securelens/ai/__init__.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
AI Client
|
||||
=========
|
||||
Thin, model-agnostic wrapper around LiteLLM.
|
||||
The CLI uses this instead of directly calling litellm
|
||||
so we have one place to handle retries, logging, and key injection.
|
||||
"""
|
||||
|
||||
import json
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def call_ai(
|
||||
prompt: str,
|
||||
api_key: str,
|
||||
model: str,
|
||||
temperature: float = 0.3,
|
||||
json_mode: bool = False,
|
||||
conversation_history: Optional[list] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Single entry-point for all AI calls in the CLI.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
prompt : The prompt to send (added as last user message)
|
||||
api_key : LiteLLM-compatible API key
|
||||
model : LiteLLM model string (e.g. "gemini/gemini-2.0-flash")
|
||||
temperature : Creativity (0=deterministic, 1=creative)
|
||||
json_mode : Ask the model to respond with valid JSON only
|
||||
conversation_history : Optional list of {"role": ..., "content": ...} dicts
|
||||
for multi-turn chat sessions
|
||||
"""
|
||||
import litellm
|
||||
|
||||
litellm.suppress_debug_info = True
|
||||
|
||||
messages = list(conversation_history or [])
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
|
||||
kwargs: dict = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
"temperature": temperature,
|
||||
"api_key": api_key if api_key else None,
|
||||
}
|
||||
|
||||
if json_mode:
|
||||
kwargs["response_format"] = {"type": "json_object"}
|
||||
|
||||
try:
|
||||
response = await litellm.acompletion(**kwargs)
|
||||
return response.choices[0].message.content or ""
|
||||
except Exception as e:
|
||||
logger.error(f"AI call failed [{model}]: {e}")
|
||||
return ""
|
||||
|
||||
|
||||
async def call_ai_json(
|
||||
prompt: str,
|
||||
api_key: str,
|
||||
model: str,
|
||||
temperature: float = 0.2,
|
||||
) -> Optional[dict]:
|
||||
"""Convenience wrapper — calls AI in JSON mode and parses the result."""
|
||||
raw = await call_ai(prompt, api_key, model, temperature=temperature, json_mode=True)
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
return json.loads(raw)
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"JSON parse failed: {e}\nRaw: {raw[:300]}")
|
||||
return None
|
||||
76
cli/securelens/ai/prompts.py
Normal file
76
cli/securelens/ai/prompts.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
All AI prompts for the CLI agent — kept in one place so they're easy to tune.
|
||||
"""
|
||||
|
||||
|
||||
def triage_prompt(file_list: str, max_files: int) -> str:
|
||||
return (
|
||||
"You are a Senior Application Security Engineer. "
|
||||
"I have a local codebase with the following files:\n"
|
||||
f"{file_list}\n\n"
|
||||
f"Select the {max_files} most critical files to review for security vulnerabilities. "
|
||||
"Focus on: authentication logic, database access, API routes, config files, "
|
||||
"secret/credential handling, input validation, and file upload handlers.\n"
|
||||
"Also prioritise any file that contains the words: secret, password, token, key, "
|
||||
"auth, login, admin, cred, jwt, session, crypto, hash.\n"
|
||||
"Return a JSON object with a single key 'critical_files' containing the list of "
|
||||
"exact file paths. Do not select more than "
|
||||
f"{max_files} files."
|
||||
)
|
||||
|
||||
|
||||
def analysis_prompt(file_path: str, content: str) -> str:
|
||||
return (
|
||||
f"Review the following code from '{file_path}' for security vulnerabilities.\n"
|
||||
"Focus on OWASP Top 10:\n"
|
||||
" A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection,\n"
|
||||
" A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable Components,\n"
|
||||
" A07 Auth Failures, A08 Integrity Failures, A09 Logging Failures, A10 SSRF.\n"
|
||||
"Also check for: hardcoded secrets/API keys, debug flags left on, insecure defaults.\n\n"
|
||||
f"CODE:\n{content}\n\n"
|
||||
"Return a JSON object with key 'vulnerabilities' — a list of objects, each with:\n"
|
||||
" 'severity' : Critical | High | Medium | Low\n"
|
||||
" 'issue' : Short title of the vulnerability\n"
|
||||
" 'explanation' : 1-2 sentences explaining the risk\n"
|
||||
" 'suggested_fix' : Concrete code snippet or clear instruction to fix it\n"
|
||||
" 'line_number' : Integer line number, or null if not applicable\n"
|
||||
"If no vulnerabilities are found, return {\"vulnerabilities\": []}."
|
||||
)
|
||||
|
||||
|
||||
def summary_prompt(target: str, issues_json: str) -> str:
|
||||
return (
|
||||
"You are a Senior AppSec Manager writing an executive security report.\n"
|
||||
f"Target: {target}\n\n"
|
||||
"Here are all vulnerabilities found in the automated scan:\n"
|
||||
f"{issues_json}\n\n"
|
||||
"Write a 2-3 paragraph executive summary of the overall security posture. "
|
||||
"Highlight the most critical risks, explain what an attacker could do with them, "
|
||||
"and recommend the top 3 immediate priorities. "
|
||||
"Keep it professional, direct, and actionable — avoid generic fluff."
|
||||
)
|
||||
|
||||
|
||||
def chat_prompt(target: str, scan_context: str, user_question: str) -> str:
|
||||
return (
|
||||
"You are SecureLens AI, an expert cybersecurity assistant embedded in a CLI tool.\n"
|
||||
f"The developer just scanned: {target}\n\n"
|
||||
"Here are the full scan results:\n"
|
||||
f"{scan_context}\n\n"
|
||||
f"Developer's question: {user_question}\n\n"
|
||||
"Answer clearly and practically. Reference specific findings from the scan when relevant. "
|
||||
"If asked about a fix, show concrete code where possible."
|
||||
)
|
||||
|
||||
|
||||
def web_summary_prompt(url: str, issues_json: str, score: int, grade: str) -> str:
|
||||
return (
|
||||
"You are SecureLens AI, a web security expert.\n"
|
||||
f"I just ran a security scan on: {url}\n"
|
||||
f"Overall score: {score}/100 Grade: {grade}\n\n"
|
||||
"Issues found:\n"
|
||||
f"{issues_json}\n\n"
|
||||
"Write a concise 2-paragraph summary: first explain what the key risks are and how "
|
||||
"an attacker could exploit them; second, give the top 3 most impactful fixes. "
|
||||
"Be direct — the reader is a developer, not a manager."
|
||||
)
|
||||
Reference in New Issue
Block a user