Files

81 lines
2.7 KiB
Python

from json.decoder import JSONDecodeError
from logging import getLogger
from requests.exceptions import RequestException
from odoo import api, fields, models, modules
from odoo.exceptions import UserError
from odoo.addons.ai.utils.llm_api_service import LLMApiService
_logger = getLogger(__name__)
class VoipCall(models.Model):
_inherit = "voip.call"
transcript = fields.Text()
transcription_status = fields.Selection(
[
("pending", "Pending"), # waiting for cron
("queued", "Queued"), # picked by cron, might get stuck in this state
("done", "Done"), # success
("error", "Error"), # API failure
("too_big_to_process", "Too long to process"), # >25 MB
("no_audio", "No audio"), # attachment missing
],
default="no_audio",
copy=False,
index=True,
)
summary = fields.Char(string="Summary", copy=False)
@api.model
def _cron_transcribe_recent_voip_call(self):
call = self.search(
[("transcription_status", "=", "pending")],
order="create_date desc",
limit=1,
)
if not call:
return
call.transcription_status = "queued"
if not modules.module.current_test:
self.env.cr.commit()
domain = [
("res_model", "=", "voip.call"),
("res_id", "=", call.id),
("mimetype", "=", "audio/ogg"),
]
recordings = self.env["ir.attachment"].search(domain, order="create_date desc")
if not recordings:
call.transcription_status = "no_audio"
return
if len(recordings) > 1:
_logger.warning(
"Call %s has multiple recordings; processing only the newest one (%s).", call.id, recordings[0].id
)
recording = recordings[0]
try:
text = LLMApiService(self.env).get_transcription(recording.raw, "audio/ogg")
except (RequestException, JSONDecodeError, UserError):
_logger.exception("Call %s: transcription failed", call.id)
call.transcription_status = "error"
return
call.transcript = (call.transcript or "") + text
call.transcription_status = "done"
# Generate one-liner summary
try:
ai_agent = self.env.ref('voip_ai.voip_call_summary_agent', raise_if_not_found=False)
if call.transcript:
summary_response = ai_agent.get_direct_response(prompt=call.transcript)
if summary_response:
call.summary = summary_response[0]
except (RequestException, JSONDecodeError, UserError):
_logger.exception("Call %s: one-liner summary generation failed", call.id)