Move to GPT for API consistency
This commit is contained in:
@@ -18,11 +18,8 @@ GCS_BUCKET=your-bucket-name
|
|||||||
# How long (seconds) before a node is marked offline if no checkin received
|
# How long (seconds) before a node is marked offline if no checkin received
|
||||||
NODE_OFFLINE_THRESHOLD=90
|
NODE_OFFLINE_THRESHOLD=90
|
||||||
|
|
||||||
# OpenAI Whisper — for audio transcription
|
# OpenAI — for transcription (Whisper), intelligence extraction, embeddings, and summaries
|
||||||
OPENAI_API_KEY=
|
OPENAI_API_KEY=
|
||||||
|
|
||||||
# Gemini — for intelligence extraction, embeddings, and incident summaries
|
|
||||||
GEMINI_API_KEY=
|
|
||||||
SUMMARY_INTERVAL_MINUTES=15
|
SUMMARY_INTERVAL_MINUTES=15
|
||||||
CORRELATION_WINDOW_HOURS=4
|
CORRELATION_WINDOW_HOURS=4
|
||||||
EMBEDDING_SIMILARITY_THRESHOLD=0.82
|
EMBEDDING_SIMILARITY_THRESHOLD=0.82
|
||||||
|
|||||||
@@ -113,20 +113,14 @@ def _sync_extract(
|
|||||||
system_id: Optional[str],
|
system_id: Optional[str],
|
||||||
segments: Optional[list[dict]],
|
segments: Optional[list[dict]],
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Call Gemini Flash and parse the JSON response."""
|
"""Call GPT-4o mini and parse the JSON response."""
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
import google.generativeai as genai
|
from openai import OpenAI
|
||||||
|
|
||||||
if not settings.gemini_api_key:
|
if not settings.openai_api_key:
|
||||||
logger.warning("GEMINI_API_KEY not set — intelligence extraction disabled.")
|
logger.warning("OPENAI_API_KEY not set — intelligence extraction disabled.")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
genai.configure(api_key=settings.gemini_api_key)
|
|
||||||
model = genai.GenerativeModel(
|
|
||||||
"gemini-2.5-flash-lite",
|
|
||||||
generation_config={"response_mime_type": "application/json"},
|
|
||||||
)
|
|
||||||
|
|
||||||
tg = f"{talkgroup_name} (TGID {talkgroup_id})" if talkgroup_id else (talkgroup_name or "unknown")
|
tg = f"{talkgroup_name} (TGID {talkgroup_id})" if talkgroup_id else (talkgroup_name or "unknown")
|
||||||
prompt = _PROMPT_TEMPLATE.format(
|
prompt = _PROMPT_TEMPLATE.format(
|
||||||
transcript_block=_build_transcript_block(transcript, segments),
|
transcript_block=_build_transcript_block(transcript, segments),
|
||||||
@@ -135,13 +129,18 @@ def _sync_extract(
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = model.generate_content(prompt)
|
client = OpenAI(api_key=settings.openai_api_key)
|
||||||
return json.loads(response.text)
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o-mini",
|
||||||
|
messages=[{"role": "user", "content": prompt}],
|
||||||
|
response_format={"type": "json_object"},
|
||||||
|
)
|
||||||
|
return json.loads(response.choices[0].message.content)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
logger.warning(f"Gemini returned non-JSON: {e}")
|
logger.warning(f"GPT-4o mini returned non-JSON: {e}")
|
||||||
return {}
|
return {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Gemini extraction failed: {e}")
|
logger.warning(f"GPT-4o mini extraction failed: {e}")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,14 +76,11 @@ async def _summarize_incident(inc: dict) -> None:
|
|||||||
|
|
||||||
def _sync_summarize(inc: dict, transcripts: list[str]) -> Optional[str]:
|
def _sync_summarize(inc: dict, transcripts: list[str]) -> Optional[str]:
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
import google.generativeai as genai
|
from openai import OpenAI
|
||||||
|
|
||||||
if not settings.gemini_api_key:
|
if not settings.openai_api_key:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
genai.configure(api_key=settings.gemini_api_key)
|
|
||||||
model = genai.GenerativeModel("gemini-2.5-flash-lite")
|
|
||||||
|
|
||||||
inc_type = inc.get("type", "unknown")
|
inc_type = inc.get("type", "unknown")
|
||||||
location = inc.get("location") or "unknown location"
|
location = inc.get("location") or "unknown location"
|
||||||
tg_ids = ", ".join(inc.get("talkgroup_ids", [])) or "unknown"
|
tg_ids = ", ".join(inc.get("talkgroup_ids", [])) or "unknown"
|
||||||
@@ -107,8 +104,12 @@ Write a concise factual summary of this incident in 2-4 sentences. Include:
|
|||||||
Be factual. Do not speculate beyond what the transcripts say. Do not use bullet points."""
|
Be factual. Do not speculate beyond what the transcripts say. Do not use bullet points."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = model.generate_content(prompt)
|
client = OpenAI(api_key=settings.openai_api_key)
|
||||||
return response.text.strip() or None
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o-mini",
|
||||||
|
messages=[{"role": "user", "content": prompt}],
|
||||||
|
)
|
||||||
|
return response.choices[0].message.content.strip() or None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Gemini summary failed: {e}")
|
logger.warning(f"GPT-4o mini summary failed: {e}")
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user