from . import models, controllers import logging _logger = logging.getLogger(__name__) DEFAULT_AGENTS = [ ('master', 'Routing / orchestration'), ('finance', 'Finance reporting and analysis'), ('accounting', 'Accounting, journals, reconciliation'), ('crm', 'CRM, leads, opportunities'), ('sales', 'Sales orders, quotations, customers'), ('project', 'Project management and tasks'), ('elearning', 'eLearning courses and content'), ('expenses', 'Expense reports and approvals'), ('hr', 'Human Resources, employees, time off'), ] def _ensure_default_bot_and_registry(env): """Seed an active ab.ai.bot row and the default agent registry entries.""" Bot = env['ab.ai.bot'] if not Bot.search([], limit=1): Bot.create({ 'display_name': 'ActiveBlue AI', 'agent_service_url': 'http://activeblue-agent:8001', 'privacy_mode': 'local', 'active': True, }) _logger.info('Seeded default ab.ai.bot row') Registry = env['ab.ai.agent.registry'] for name, domain in DEFAULT_AGENTS: if not Registry.search([('agent_name', '=', name)], limit=1): Registry.create({ 'agent_name': name, 'domain': domain, 'active': True, 'backend': 'ollama', }) _logger.info('Ensured %d default agent registry entries', len(DEFAULT_AGENTS)) def _ensure_ai_bot_user(env): """Create the ActiveBlue AI internal user so it appears in Discuss DM search. Skips invitation email (no_reset_password) and marks the user as already logged-in (res_users_log row) so it shows as Confirmed instead of Pending. Also ensures the external ID exists so `env.ref('activeblue_ai.partner_activeblue_ai')` resolves in the discuss.channel message override. """ User = env['res.users'].with_context(no_reset_password=True) user = User.search([('login', 'in', ('activeblue_ai_bot', 'activeblue_ai_bot@local'))], limit=1) if not user: user = User.create({ 'name': 'ActiveBlue AI', 'login': 'activeblue_ai_bot', 'groups_id': [(6, 0, [env.ref('base.group_user').id])], 'share': False, 'active': True, }) _logger.info('Created ActiveBlue AI bot user id=%d', user.id) # Ensure external ID -> partner mapping (needed by ab_ai_mail.py override) imd = env['ir.model.data'] existing = imd.search([ ('module', '=', 'activeblue_ai'), ('name', '=', 'partner_activeblue_ai'), ], limit=1) if existing: existing.write({'model': 'res.partner', 'res_id': user.partner_id.id}) else: imd.create({ 'module': 'activeblue_ai', 'name': 'partner_activeblue_ai', 'model': 'res.partner', 'res_id': user.partner_id.id, 'noupdate': True, }) # Clear "Pending Invitations" state by writing a res_users_log row. # In Odoo 18 the user state is computed from the existence of a log entry. env.cr.execute( "SELECT 1 FROM res_users_log WHERE create_uid = %s LIMIT 1", (user.id,), ) if not env.cr.fetchone(): env.cr.execute( "INSERT INTO res_users_log (create_uid, create_date, write_uid, write_date) " "VALUES (%s, NOW(), %s, NOW())", (user.id, user.id), ) _logger.info('Marked ActiveBlue AI bot user id=%d as confirmed', user.id) _ensure_default_bot_and_registry(env)