← back to Norma
agents/reddit-agent/skills/report.js
134 lines
/**
* Reddit Report Skill
*
* Gathers agent stats and recent actions, then pushes to Pulse.
*/
const { logAction, getActionSummary } = require('../../shared/audit-logger');
const { reportAgentStatus } = require('../../shared/pulse-reporter');
const { hasCredentials, SUBREDDITS } = require('../lib/reddit');
const { query: dbQuery } = require('../../shared/db');
const AGENT = 'reddit-agent';
const PLATFORM = 'reddit';
/**
* @param {Object} body - Request body
* @param {number} [body.hours_back=24] - How many hours back to report
* @returns {Promise<Object>}
*/
module.exports = async function report(body) {
const hoursBack = body.hours_back || 24;
// Get action summary
const actionSummary = await getActionSummary(AGENT, hoursBack);
// Get monitor stats
let monitorStats = { total: 0, active: 0, totalItemsFound: 0 };
try {
const { rows } = await dbQuery(
`SELECT
COUNT(*)::int as total,
COUNT(*) FILTER (WHERE is_active = true)::int as active,
COALESCE(SUM(items_found), 0)::int as total_items_found
FROM sdcc_agent_monitors
WHERE agent = $1 AND platform = $2`,
[AGENT, PLATFORM]
);
if (rows[0]) {
monitorStats = {
total: rows[0].total,
active: rows[0].active,
totalItemsFound: rows[0].total_items_found,
};
}
} catch (err) {
console.error(`[${AGENT}] Failed to get monitor stats:`, err.message);
}
// Get recent post/reply actions
let recentActions = [];
try {
const { rows } = await dbQuery(
`SELECT target_id, target_url, content, action_type,
channel, response_data, created_at
FROM sdcc_agent_actions
WHERE agent = $1 AND platform = $2
AND action_type IN ('post', 'reply')
AND status = 'success'
ORDER BY created_at DESC
LIMIT 10`,
[AGENT, PLATFORM]
);
recentActions = rows;
} catch (err) {
console.error(`[${AGENT}] Failed to get recent actions:`, err.message);
}
// Get campaign stats
let campaignStats = { total: 0, active: 0, totalPosts: 0, totalReplies: 0 };
try {
const { rows } = await dbQuery(
`SELECT
COUNT(*)::int as total,
COUNT(*) FILTER (WHERE status = 'active')::int as active,
COALESCE(SUM(total_posts), 0)::int as total_posts,
COALESCE(SUM(total_replies), 0)::int as total_replies
FROM sdcc_petition_campaigns
WHERE 'reddit' = ANY(target_platforms)`
);
if (rows[0]) {
campaignStats = {
total: rows[0].total,
active: rows[0].active,
totalPosts: rows[0].total_posts,
totalReplies: rows[0].total_replies,
};
}
} catch (err) {
console.error(`[${AGENT}] Failed to get campaign stats:`, err.message);
}
const reportData = {
agent: AGENT,
platform: PLATFORM,
credentials_configured: hasCredentials(),
target_subreddits: SUBREDDITS,
period_hours: hoursBack,
actions: actionSummary,
monitors: monitorStats,
campaigns: campaignStats,
recent_actions: recentActions,
uptime: process.uptime(),
reported_at: new Date().toISOString(),
};
// Push to Pulse
const pulseResult = await reportAgentStatus(AGENT, {
state: hasCredentials() ? 'running' : 'idle',
uptime: process.uptime(),
lastAction: actionSummary.length > 0 ? actionSummary[0] : null,
stats: {
monitors: monitorStats,
campaigns: campaignStats,
credentialsConfigured: hasCredentials(),
targetSubreddits: SUBREDDITS.length,
actionsInPeriod: actionSummary.reduce((sum, a) => sum + a.count, 0),
},
});
// Log the report action
await logAction({
agent: AGENT,
actionType: 'report',
platform: PLATFORM,
responseData: reportData,
status: 'success',
});
return {
...reportData,
pulse_response: pulseResult,
};
};