function createAgentsService({ db, ai, memory, skills, workflowHistory, metricsAutomation, briefing }) {
  const BUILTIN_KEYS = new Set(['qa_auditor', 'metrics_strategist', 'treasury_collector', 'night_metrics_collector']);
  const CUSTOM_AGENT_ICONS = ['fa-robot', 'fa-brain', 'fa-envelope', 'fa-chart-line', 'fa-sitemap', 'fa-coins', 'fa-shield-alt', 'fa-headset', 'fa-bullhorn', 'fa-cogs'];

  function nowIso() {
    return new Date().toISOString();
  }

  function getToday() {
    return nowIso().slice(0, 10);
  }

  function normalizeRunMode(value) {
    return value === 'scheduled' ? 'scheduled' : 'manual';
  }

  function normalizeTime(value) {
    const raw = String(value || '').trim();
    return /^\d{2}:\d{2}$/.test(raw) ? raw : '';
  }

  function normalizeScopeType(value) {
    return value === 'general' ? 'general' : 'division';
  }

  function getAgent(agentId) {
    return db.prepare('SELECT * FROM agents WHERE id = ?').get(agentId);
  }

  function listAgentsForDivision(divisionId) {
    return db.prepare(`
      SELECT a.*,
             (SELECT COUNT(*) FROM agent_runs r WHERE r.agent_id = a.id) AS run_count,
             (SELECT r.created_at FROM agent_runs r WHERE r.agent_id = a.id ORDER BY r.id DESC LIMIT 1) AS last_run_at
      FROM agents a
      WHERE a.status != 'archived'
        AND (a.scope_type = 'general' OR a.division_id = ?)
      ORDER BY CASE WHEN a.scope_type = 'general' THEN 0 ELSE 1 END, lower(a.name) ASC, a.id ASC
    `).all(divisionId);
  }

  function getRunsForDivision(divisionId, limit = 80) {
    return db.prepare(`
      SELECT r.*, a.name AS agent_name, a.scope_type, a.division_id AS agent_division_id, a.icon, a.accent_color
      FROM agent_runs r
      JOIN agents a ON a.id = r.agent_id
      WHERE a.scope_type = 'general' OR a.division_id = ?
      ORDER BY r.id DESC
      LIMIT ?
    `).all(divisionId, limit);
  }

  function ensureGeneralCreationAllowed(requestedByDivisionId, scopeType) {
    if (scopeType === 'general' && Number(requestedByDivisionId) !== 8) {
      throw new Error('Only ED can create general agents');
    }
  }

  function ensureMutableAgent(agent, requestedByDivisionId) {
    if (!agent) throw new Error('Agent not found');
    if (agent.scope_type === 'general' && Number(requestedByDivisionId) !== 8) {
      throw new Error('Only ED can modify general agents');
    }
    if (agent.scope_type === 'division' && Number(agent.division_id) !== Number(requestedByDivisionId) && Number(requestedByDivisionId) !== 8) {
      throw new Error('You can only modify agents for your current division');
    }
  }

  function ensureAgentConversation(divisionId) {
    const now = nowIso();
    let conversation = db.prepare('SELECT * FROM ai_conversations WHERE division_id = ? AND title = ? ORDER BY id DESC LIMIT 1').get(divisionId, '[Agent] Updates');
    if (!conversation) {
      const result = db.prepare('INSERT INTO ai_conversations (division_id, title, created_at, updated_at) VALUES (?, ?, ?, ?)').run(divisionId, '[Agent] Updates', now, now);
      conversation = { id: result.lastInsertRowid, division_id: divisionId, title: '[Agent] Updates', created_at: now, updated_at: now };
    }
    return conversation.id;
  }

  function postAgentMessageToAdvisor(divisionId, agentName, content) {
    if (!divisionId || !content) return;
    const conversationId = ensureAgentConversation(divisionId);
    const now = nowIso();
    const message = `<b>${agentName}</b><br>${content.replace(/\n/g, '<br>')}`;
    db.prepare('INSERT INTO ai_messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)').run(conversationId, 'assistant', message, now);
    db.prepare('UPDATE ai_conversations SET updated_at = ? WHERE id = ?').run(now, conversationId);
  }

  function findWorkflowForAction(divisionId, workflowTitle) {
    const title = String(workflowTitle || '').trim();
    if (!title) return null;
    return db.prepare(`
      SELECT * FROM items
      WHERE division_id = ?
        AND (lower(title) = lower(?) OR lower(title) LIKE lower(?))
      ORDER BY id DESC
      LIMIT 1
    `).get(divisionId, title, `%${title}%`);
  }

  function ensureAgentWorkflowCard(divisionId, agentName) {
    const title = `⚡ ${agentName}`;
    let item = db.prepare('SELECT * FROM items WHERE division_id = ? AND title = ? ORDER BY id DESC LIMIT 1').get(divisionId, title);
    if (!item) {
      const itemId = workflowHistory.createItem({
        divisionId,
        title,
        magicLink: null,
        workDate: getToday()
      });
      item = db.prepare('SELECT * FROM items WHERE id = ?').get(itemId);
    }
    return item;
  }

  function addAgentTodo(divisionId, agentName, text, workflowTitle = '') {
    if (!divisionId || !text) return null;
    const targetItem = findWorkflowForAction(divisionId, workflowTitle) || ensureAgentWorkflowCard(divisionId, agentName);
    const existing = db.prepare(`
      SELECT id FROM todos
      WHERE item_id = ? AND division_id = ? AND done = 0 AND lower(text) = lower(?)
      ORDER BY id DESC LIMIT 1
    `).get(targetItem.id, divisionId, text.trim());
    if (existing) return existing.id;
    return workflowHistory.addTodo({
      itemId: targetItem.id,
      divisionId,
      text: text.trim().substring(0, 180),
      workDate: getToday()
    });
  }

  function addAgentBattlePlan(divisionId, period, title) {
    const normalizedPeriod = ['yearly', 'monthly', 'weekly', 'daily'].includes(period) ? period : 'daily';
    const trimmed = String(title || '').trim().substring(0, 200);
    if (!divisionId || !trimmed) return null;
    const today = getToday();
    const existing = db.prepare(`
      SELECT id FROM battle_plans
      WHERE division_id = ? AND period = ? AND lower(title) = lower(?) AND substr(created_at, 1, 10) = ?
      ORDER BY id DESC LIMIT 1
    `).get(divisionId, normalizedPeriod, trimmed, today);
    if (existing) return existing.id;
    const createdAt = nowIso();
    const result = db.prepare('INSERT INTO battle_plans (division_id, period, title, created_at) VALUES (?, ?, ?, ?)').run(divisionId, normalizedPeriod, trimmed, createdAt);
    return result.lastInsertRowid;
  }

  function createRunRecord(agent, divisionId, triggerMode, status, summary, actions) {
    const createdAt = nowIso();
    const result = db.prepare(`
      INSERT INTO agent_runs (agent_id, division_id, trigger_mode, status, summary, actions_json, created_at)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run(agent.id, divisionId || null, triggerMode, status, summary || '', JSON.stringify(actions || []), createdAt);
    db.prepare('UPDATE agents SET updated_at = ? WHERE id = ?').run(createdAt, agent.id);
    return result.lastInsertRowid;
  }

  function parseAgentJson(rawText, fallback = {}) {
    if (!rawText) return fallback;
    try {
      const parsed = ai.parseJsonResponse(rawText);
      return parsed && typeof parsed === 'object' ? parsed : fallback;
    } catch (_error) {
      return fallback;
    }
  }

  function buildDivisionSnapshot(divisionId) {
    const division = db.prepare('SELECT * FROM divisions WHERE id = ?').get(divisionId);
    const items = db.prepare('SELECT id, title, work_date FROM items WHERE division_id = ? ORDER BY id DESC LIMIT 8').all(divisionId);
    const openOrders = db.prepare('SELECT title, body, priority, status, due_date FROM executive_orders WHERE target_division_id = ? AND status != ? ORDER BY id DESC LIMIT 5').all(divisionId, 'done');
    const openPlans = db.prepare('SELECT period, title FROM battle_plans WHERE division_id = ? AND done = 0 ORDER BY id DESC LIMIT 6').all(divisionId);
    const itemLines = items.map((item) => {
      const pending = db.prepare('SELECT text FROM todos WHERE item_id = ? AND division_id = ? AND done = 0 ORDER BY id ASC LIMIT 4').all(item.id, divisionId);
      return {
        id: item.id,
        title: item.title,
        work_date: item.work_date,
        pending_todos: pending.map((row) => row.text)
      };
    });
    return { division, items: itemLines, openOrders, openPlans };
  }

  function buildCompactDivisionContext(snapshot) {
    const divisionLine = snapshot?.division
      ? `${snapshot.division.name}: ${snapshot.division.subtitle || ''}. VFP: ${snapshot.division.vfp || '—'}`
      : 'No division context available.';
    const itemLines = (snapshot?.items || []).slice(0, 5).map((item) => {
      const todoLine = (item.pending_todos || []).slice(0, 3).join(' | ') || 'no open todos';
      return `- ${item.title} [${item.work_date || 'no date'}] -> ${todoLine}`;
    }).join('\n') || '- No active workflow cards';
    const orders = (snapshot?.openOrders || []).slice(0, 4).map((order) => {
      return `- ${order.title} (${order.priority || 'medium'}, ${order.status || 'open'})`;
    }).join('\n') || '- No open executive orders';
    const plans = (snapshot?.openPlans || []).slice(0, 4).map((plan) => `- ${plan.period}: ${plan.title}`).join('\n') || '- No open battle plans';
    return `Division\n${divisionLine}\n\nWorkflows\n${itemLines}\n\nExecutive Orders\n${orders}\n\nBattle Plans\n${plans}`;
  }

  async function executeCustomAgent(agent, requestedDivisionId) {
    const settings = db.prepare('SELECT * FROM settings WHERE id = 1').get();
    const targetDivisionId = agent.scope_type === 'division'
      ? Number(agent.division_id)
      : Number(requestedDivisionId || agent.division_id || 8);
    const division = db.prepare('SELECT * FROM divisions WHERE id = ?').get(targetDivisionId) || db.prepare('SELECT * FROM divisions WHERE id = 8').get();
    const relevantMemory = await memory.searchMemory(`${agent.name}. ${agent.description}. ${agent.instructions}`, settings, targetDivisionId, 8);
    const memoryContext = relevantMemory.slice(0, 4).map((entry) => `- [${entry.type}] ${entry.content}`).join('\n') || 'No relevant memory.';
    const snapshot = buildDivisionSnapshot(targetDivisionId);
    const skillsContext = targetDivisionId ? await skills.buildSkillsContext(`${agent.name} ${agent.description}`, settings, targetDivisionId) : '';
    const compactSkills = String(skillsContext || '').slice(0, 1800) || 'No relevant skills loaded.';
    const compactSnapshot = buildCompactDivisionContext(snapshot);

    const prompt = `You are executing one internal Org Board AI agent.

Agent
- Name: ${agent.name}
- Scope: ${agent.scope_type}
- Division: ${division?.name || 'Executive'}
- Description: ${agent.description}

Instructions
${agent.instructions}

Relevant memory
${memoryContext}

Division context
${compactSnapshot}

Relevant skills
${compactSkills}

Return ONLY valid JSON:
{
  "summary": "short summary",
  "actions": [
    {
      "type": "add_todo" | "create_battle_plan" | "advisor_message" | "log_memory",
      "division_id": ${targetDivisionId},
      "workflow_title": "optional workflow title",
      "text": "for add_todo",
      "period": "for create_battle_plan",
      "title": "for create_battle_plan",
      "content": "for advisor_message or log_memory"
    }
  ]
}

Rules:
- Maximum 3 actions.
- Only use the supported action types above.
- If no action is needed, return an empty actions array.
- Prefer one specific todo over vague summaries.
- Never invent external systems, code execution, APIs, or browser actions.
- Use short, concrete English.
- If uncertain, create no action and explain it in summary.`;

    let parsed = { summary: `${agent.name} completed a scan without new action.`, actions: [] };
    try {
      const raw = await ai.callAIWithFallback(
        prompt,
        settings,
        `You are a disciplined internal operations planner. Output strict JSON only. Favor small, concrete actions that fit the current division. ${ai.buildLanguageInstruction(settings, { json: true })}`
      );
      parsed = parseAgentJson(raw.content, parsed);
    } catch (error) {
      parsed = {
        summary: `${agent.name} could not use AI planning right now, so it logged a standby note instead.`,
        actions: [{ type: 'log_memory', division_id: targetDivisionId, content: `${agent.name} run fell back because AI planning was unavailable.` }]
      };
    }
    const actions = Array.isArray(parsed.actions) ? parsed.actions.slice(0, 4) : [];
    const actionResults = [];

    actions.forEach((action) => {
      const actionDivisionId = Number(action.division_id || targetDivisionId || division?.id || 8);
      if (action.type === 'add_todo' && action.text) {
        const todoId = addAgentTodo(actionDivisionId, agent.name, String(action.text), action.workflow_title || '');
        if (todoId) actionResults.push({ type: 'add_todo', division_id: actionDivisionId, text: String(action.text) });
      }
      if (action.type === 'create_battle_plan' && action.title) {
        const planId = addAgentBattlePlan(actionDivisionId, action.period || 'daily', String(action.title));
        if (planId) actionResults.push({ type: 'create_battle_plan', division_id: actionDivisionId, title: String(action.title), period: action.period || 'daily' });
      }
      if (action.type === 'advisor_message' && action.content && actionDivisionId) {
        postAgentMessageToAdvisor(actionDivisionId, agent.name, String(action.content));
        actionResults.push({ type: 'advisor_message', division_id: actionDivisionId, content: String(action.content) });
      }
      if (action.type === 'log_memory' && action.content) {
        memory.logMemory(actionDivisionId, 'agent_action', `${agent.name}: ${String(action.content)}`);
        actionResults.push({ type: 'log_memory', division_id: actionDivisionId, content: String(action.content) });
      }
    });

    const summary = String(parsed.summary || `${agent.name} completed a scan.`).trim();
    if (agent.scope_type === 'division' && targetDivisionId) {
      postAgentMessageToAdvisor(targetDivisionId, agent.name, `${summary}${actionResults.length ? `<br><br>${actionResults.map((action) => `• ${action.type.replace(/_/g, ' ')}${action.text ? `: ${action.text}` : action.title ? `: ${action.title}` : ''}`).join('<br>')}` : ''}`);
    }
    memory.logMemory(targetDivisionId, 'agent_action', `${agent.name}: ${summary}`);
    return { summary, actions: actionResults };
  }

  function executeAuditorAgent(agent) {
    const actions = [];
    const now = nowIso();
    const items = db.prepare('SELECT id, title FROM items WHERE division_id = 5 ORDER BY id DESC').all();
    items.forEach((item) => {
      const incompleteTodos = db.prepare('SELECT COUNT(*) AS c FROM todos WHERE item_id = ? AND division_id = 5 AND done = 0').get(item.id).c;
      const failedChecks = db.prepare("SELECT COUNT(*) AS c FROM qa_checks WHERE item_id = ? AND status IN ('pending', 'failed')").get(item.id).c;
      if (incompleteTodos > 0 || failedChecks > 0) return;
      const text = `Prepare Division 6 handoff for "${item.title}"`;
      const todoId = addAgentTodo(6, agent.name, text, item.title);
      if (!todoId) return;
      actions.push({ type: 'add_todo', division_id: 6, text });
      memory.logMemory(5, 'agent_action', `${agent.name}: QA passed and Division 6 handoff opened for '${item.title}'.`);
    });
    const summary = actions.length
      ? `${agent.name} opened ${actions.length} delivery follow-up task(s).`
      : `${agent.name} found no QA-complete work that needed a new handoff.`;
    db.prepare('UPDATE agents SET updated_at = ? WHERE id = ?').run(now, agent.id);
    return { summary, actions };
  }

  function executeStrategistAgent(agent) {
    const today = getToday();
    const yesterday = new Date(`${today}T12:00:00`);
    yesterday.setDate(yesterday.getDate() - 1);
    const yesterdayStr = yesterday.toISOString().slice(0, 10);
    const actions = [];
    [2, 3, 4, 6, 7, 8].forEach((divisionId) => {
      const hasRealData = db.prepare('SELECT COUNT(*) AS c FROM metrics_data WHERE division_id = ? AND date = ? AND is_mock = 0').get(divisionId, yesterdayStr).c;
      if (hasRealData) return;
      const division = db.prepare('SELECT name FROM divisions WHERE id = ?').get(divisionId);
      const text = `Log missing real metrics for ${yesterdayStr}`;
      const todoId = addAgentTodo(divisionId, agent.name, text);
      if (!todoId) return;
      actions.push({ type: 'add_todo', division_id: divisionId, text: `${division?.name || `Division ${divisionId}`}: ${text}` });
      memory.logMemory(divisionId, 'agent_action', `${agent.name}: missing metrics follow-up created for ${yesterdayStr}.`);
    });
    const summary = actions.length
      ? `${agent.name} created ${actions.length} metrics accountability task(s).`
      : `${agent.name} found no missing metrics follow-up work.`;
    return { summary, actions };
  }

  function executeCollectorAgent(agent) {
    const actions = [];
    const openCases = db.prepare(`
      SELECT tc.client_name, tc.stage, tc.amount_due, i.title AS workflow_title
      FROM treasury_cases tc
      LEFT JOIN items i ON i.id = tc.item_id
      WHERE tc.division_id = 3
        AND tc.stage IN ('deposit_pending', 'invoice_sent', 'follow_up', 'overdue')
      ORDER BY tc.id DESC
      LIMIT 12
    `).all();
    openCases.forEach((row) => {
      const text = row.stage === 'deposit_pending'
        ? `Collect deposit for "${row.client_name}" (${row.amount_due || 0})`
        : `Follow up payment for "${row.client_name}"`;
      const todoId = addAgentTodo(3, agent.name, text, row.workflow_title || row.client_name);
      if (!todoId) return;
      actions.push({ type: 'add_todo', division_id: 3, text });
      memory.logMemory(3, 'agent_action', `${agent.name}: treasury follow-up task created for '${row.client_name}'.`);
    });
    const summary = actions.length
      ? `${agent.name} created ${actions.length} treasury follow-up task(s).`
      : `${agent.name} found no new treasury follow-up actions.`;
    return { summary, actions };
  }

  function executeNightMetricsCollector(agent) {
    const result = metricsAutomation.collectForDate(getToday());
    briefing.invalidateBriefingCache();
    const updates = result?.updates || [];
    const summary = `${agent.name} collected ${updates.length} derived metric value(s) for ${getToday()}.`;
    memory.logMemory(8, 'agent_action', summary);
    return {
      summary,
      actions: updates.slice(0, 20).map((row) => ({
        type: 'metrics_update',
        division_id: row.division_id,
        metric_key: row.metric_key,
        value: row.value
      }))
    };
  }

  async function executeAgent(agent, requestedDivisionId, triggerMode = 'manual') {
    let result;
    if (agent.system_key === 'qa_auditor') result = executeAuditorAgent(agent);
    else if (agent.system_key === 'metrics_strategist') result = executeStrategistAgent(agent);
    else if (agent.system_key === 'treasury_collector') result = executeCollectorAgent(agent);
    else if (agent.system_key === 'night_metrics_collector') result = executeNightMetricsCollector(agent);
    else result = await executeCustomAgent(agent, requestedDivisionId);

    createRunRecord(agent, requestedDivisionId || agent.division_id || null, triggerMode, 'success', result.summary, result.actions);
    return result;
  }

  async function runAgent(agentId, requestedDivisionId = null, triggerMode = 'manual') {
    const agent = getAgent(agentId);
    if (!agent) throw new Error('Agent not found');
    if (agent.status !== 'active') throw new Error('Agent is not active');
    return executeAgent(agent, requestedDivisionId, triggerMode);
  }

  async function runAgentsForDivision(divisionId, { includeScheduled = false, triggerMode = 'manual' } = {}) {
    const agents = listAgentsForDivision(divisionId)
      .filter((agent) => agent.status === 'active')
      .filter((agent) => includeScheduled || agent.run_mode === 'manual' || BUILTIN_KEYS.has(agent.system_key));
    const results = [];
    for (const agent of agents) {
      results.push({ agent, ...(await executeAgent(agent, divisionId, triggerMode)) });
    }
    return results;
  }

  async function runDueScheduledAgents(referenceDate = new Date()) {
    const hh = String(referenceDate.getHours()).padStart(2, '0');
    const mm = String(referenceDate.getMinutes()).padStart(2, '0');
    const time = `${hh}:${mm}`;
    const today = referenceDate.toISOString().slice(0, 10);
    const dueAgents = db.prepare(`
      SELECT * FROM agents
      WHERE status = 'active'
        AND run_mode = 'scheduled'
        AND run_time = ?
        AND NOT EXISTS (
          SELECT 1 FROM agent_runs r
          WHERE r.agent_id = agents.id
            AND substr(r.created_at, 1, 10) = ?
        )
      ORDER BY id ASC
    `).all(time, today);
    const results = [];
    for (const agent of dueAgents) {
      results.push({ agent, ...(await executeAgent(agent, agent.division_id || 8, 'scheduled')) });
    }
    return results;
  }

  async function generateAgentSpec({ requestedByDivisionId, divisionId, scopeType, brief, runMode, runTime }) {
    const normalizedScope = normalizeScopeType(scopeType);
    ensureGeneralCreationAllowed(requestedByDivisionId, normalizedScope);
    const targetDivisionId = normalizedScope === 'division' ? Number(divisionId || requestedByDivisionId) : null;
    const settings = db.prepare('SELECT * FROM settings WHERE id = 1').get();
    const division = targetDivisionId ? db.prepare('SELECT * FROM divisions WHERE id = ?').get(targetDivisionId) : db.prepare('SELECT * FROM divisions WHERE id = 8').get();
    const prompt = `Design one safe internal platform agent from this brief:

Brief: ${brief}
Scope type: ${normalizedScope}
Target division: ${division?.name || 'General'}

Return ONLY valid JSON:
{
  "name": "short clear agent name",
  "description": "one sentence",
  "instructions": "precise operating instructions for what it should watch and do inside the platform",
  "icon": "one of ${CUSTOM_AGENT_ICONS.join(', ')}",
  "accent_color": "#hexcolor"
}

Rules:
- Keep the name short and strong.
- Make the description concrete.
- Instructions must fit this platform only: memory-aware, can create tasks, battle plans, advisor messages, and memory logs.
- Do not mention arbitrary external tools, code execution, browsing, email sending, or API calls.
- Keep instructions short enough for a small local model to follow reliably.
- English only.`;

    let parsed = {};
    try {
      const raw = await ai.callAIWithFallback(prompt, settings, `You create safe internal platform agents. Output JSON only. Prefer compact instructions and narrow scope. ${ai.buildLanguageInstruction(settings, { json: true })}`);
      parsed = parseAgentJson(raw.content, {});
    } catch (_error) {
      parsed = {};
    }
    const fallbackName = String(brief || 'New Agent').trim().split(/\s+/).slice(0, 4).join(' ') || 'New Agent';
    const now = nowIso();
    const result = db.prepare(`
      INSERT INTO agents (scope_type, division_id, name, description, instructions, run_mode, run_time, status, created_by_division_id, icon, accent_color, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?, ?)
    `).run(
      normalizedScope,
      targetDivisionId,
      String(parsed.name || fallbackName).trim().substring(0, 80),
      String(parsed.description || brief || 'Custom platform agent').trim().substring(0, 220),
      String(parsed.instructions || brief || 'Watch the division and create the next useful operating action.').trim().substring(0, 5000),
      normalizeRunMode(runMode),
      normalizeRunMode(runMode) === 'scheduled' ? normalizeTime(runTime) : '',
      Number(requestedByDivisionId) || 8,
      CUSTOM_AGENT_ICONS.includes(parsed.icon) ? parsed.icon : 'fa-robot',
      /^#[0-9a-fA-F]{6}$/.test(parsed.accent_color || '') ? parsed.accent_color : '#8b5cf6',
      now,
      now
    );
    return getAgent(result.lastInsertRowid);
  }

  function updateAgent(agentId, requestedByDivisionId, patch) {
    const agent = getAgent(agentId);
    ensureMutableAgent(agent, requestedByDivisionId);
    const nextScope = normalizeScopeType(patch.scope_type || agent.scope_type);
    ensureGeneralCreationAllowed(requestedByDivisionId, nextScope);
    const updatedAt = nowIso();
    db.prepare(`
      UPDATE agents
      SET scope_type = ?,
          division_id = ?,
          name = ?,
          description = ?,
          instructions = ?,
          run_mode = ?,
          run_time = ?,
          status = ?,
          icon = ?,
          accent_color = ?,
          updated_at = ?
      WHERE id = ?
    `).run(
      nextScope,
      nextScope === 'division' ? Number(patch.division_id || agent.division_id || requestedByDivisionId) : null,
      String(patch.name || agent.name).trim().substring(0, 80),
      String(patch.description ?? agent.description).trim().substring(0, 220),
      String(patch.instructions ?? agent.instructions).trim().substring(0, 5000),
      normalizeRunMode(patch.run_mode || agent.run_mode),
      normalizeRunMode(patch.run_mode || agent.run_mode) === 'scheduled' ? normalizeTime(patch.run_time || agent.run_time) : '',
      ['active', 'paused', 'archived'].includes(patch.status) ? patch.status : agent.status,
      CUSTOM_AGENT_ICONS.includes(patch.icon) ? patch.icon : agent.icon,
      /^#[0-9a-fA-F]{6}$/.test(patch.accent_color || '') ? patch.accent_color : agent.accent_color,
      updatedAt,
      agentId
    );
    return getAgent(agentId);
  }

  function deleteAgent(agentId, requestedByDivisionId) {
    const agent = getAgent(agentId);
    ensureMutableAgent(agent, requestedByDivisionId);
    if (agent.system_key) throw new Error('Built-in agents cannot be deleted');
    db.prepare('DELETE FROM agents WHERE id = ?').run(agentId);
    return { success: true };
  }

  async function runAgentsInternal(divisionId = 8) {
    const results = await runAgentsForDivision(divisionId, { includeScheduled: true, triggerMode: 'manual' });
    return results.map((result) => `${result.agent.name}: ${result.summary}`);
  }

  return {
    listAgentsForDivision,
    getRunsForDivision,
    generateAgentSpec,
    updateAgent,
    deleteAgent,
    runAgent,
    runAgentsForDivision,
    runDueScheduledAgents,
    runAgentsInternal
  };
}

module.exports = { createAgentsService };
