Files
encoach_backend_v4/custom_addons/encoach_ai/models/ai_log.py
Yamen Ahmad 6a62a43d61 feat: Generation Page AI workflows + AI/Vector modules + exam session fixes
Generation Page (complete rebuild):
- Full production-parity exam generation wizard with 4 IELTS modules
- Reading: AI passage gen, 5 exercise types (MCQ, Fill, Write, T/F, Match)
- Listening: 4 section types, AI context gen, TTS audio gen (ElevenLabs)
- Writing: Task 1/2, AI instruction gen, word limits, marks
- Speaking: 3 parts, AI script gen, avatar video gen (7 avatars)
- Per-module config: timer, CEFR difficulty, access, approval, rubrics
- Exam submission workflow (draft/published)

Exam Structures:
- New encoach.exam.structure model + CRUD controller
- ExamStructuresPage wired to real API

AI Module (encoach_ai):
- OpenAI service, ElevenLabs TTS, AWS Polly, ELAI avatars
- AI settings model with Odoo config parameters
- 7 generation endpoints (passage, exercises, instructions, scripts, context)

Vector Module (encoach_vector):
- pgvector integration for RAG-based content search
- Embedding service with sentence-transformers

Exam Session Fixes:
- Fixed ExamSession.tsx field mapping (question_type→type, exam_title→title)
- Fixed submit payload to include attempt_id and answers
- Fixed normalizeType to handle null/undefined

Tested: 12/12 API tests passed, browser-verified with real OpenAI calls
Made-with: Cursor
2026-04-11 14:27:03 +04:00

36 lines
1.1 KiB
Python

from odoo import fields, models
class EncoachAILog(models.Model):
_name = "encoach.ai.log"
_description = "AI Service Call Log"
_order = "create_date desc"
service = fields.Selection(
[
("openai", "OpenAI"),
("whisper", "Whisper"),
("polly", "AWS Polly"),
("elevenlabs", "ElevenLabs"),
("gptzero", "GPTZero"),
("elai", "ELAI"),
("coach", "AI Coach"),
],
required=True,
index=True,
)
action = fields.Char(index=True)
model_used = fields.Char()
prompt_tokens = fields.Integer(default=0)
completion_tokens = fields.Integer(default=0)
total_tokens = fields.Integer(default=0)
latency_ms = fields.Integer()
status = fields.Selection(
[("success", "Success"), ("error", "Error"), ("timeout", "Timeout")],
default="success",
)
error_message = fields.Text()
user_id = fields.Many2one("res.users", default=lambda self: self.env.uid)
input_preview = fields.Text()
output_preview = fields.Text()