guanghulab/scripts/agent-checkin.js

179 lines
5.7 KiB
JavaScript
Raw Normal View History

/**
* scripts/agent-checkin.js
* 人格体每日签到脚本
*
* 逻辑
* 1. 读取 agent-registry.json 获取所有注册小兵列表
* 2. 对每个小兵查询 GitHub Actions API 获取该 workflow 今日最新一次 run 的结果
* 3. 结果为 success 且时间在今天 10:00 之前 标记为 已签到
* 4. 结果为 failure 或无今日 run 标记为 未签到
* 5. 更新 checkin-board.json 的所有记录
* 6. 生成 summary总数/已签到/缺席/缺席名单
*/
'use strict';
const fs = require('fs');
const path = require('path');
const https = require('https');
const ROOT = path.resolve(__dirname, '..');
const BRAIN_DIR = path.join(ROOT, '.github/persona-brain');
const REGISTRY_PATH = path.join(BRAIN_DIR, 'agent-registry.json');
const BOARD_PATH = path.join(BRAIN_DIR, 'checkin-board.json');
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const REPO = process.env.GITHUB_REPOSITORY || 'qinfendebingshuo/guanghulab';
const today = new Date().toISOString().split('T')[0];
const todayStart = new Date(today + 'T00:00:00Z');
console.log(`📋 人格体每日签到开始 · ${today}`);
// ── GitHub API helper ─────────────────────────────────────────────────────
function githubApi(urlPath) {
return new Promise((resolve, reject) => {
const options = {
hostname: 'api.github.com',
path: urlPath,
method: 'GET',
headers: {
'User-Agent': 'zhuyuan-agent-checkin',
'Accept': 'application/vnd.github.v3+json',
},
};
if (GITHUB_TOKEN) {
options.headers['Authorization'] = `Bearer ${GITHUB_TOKEN}`;
}
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => { data += chunk; });
res.on('end', () => {
try {
resolve(JSON.parse(data));
} catch {
resolve(null);
}
});
});
req.on('error', (err) => {
console.error(` ⚠️ API 请求失败: ${err.message}`);
resolve(null);
});
req.end();
});
}
// ── 获取 workflow 今日最新 run ────────────────────────────────────────────
async function getLatestRun(workflowFile) {
const urlPath = `/repos/${REPO}/actions/workflows/${encodeURIComponent(workflowFile)}/runs?per_page=1&created=${encodeURIComponent('>=' + today)}`;
const data = await githubApi(urlPath);
if (!data || !data.workflow_runs || data.workflow_runs.length === 0) {
return null;
}
const run = data.workflow_runs[0];
return {
status: run.status,
conclusion: run.conclusion,
created_at: run.created_at,
updated_at: run.updated_at,
};
}
// ── 主签到流程 ────────────────────────────────────────────────────────────
async function main() {
// 1. 读取注册表
if (!fs.existsSync(REGISTRY_PATH)) {
console.error('❌ agent-registry.json 不存在');
process.exit(1);
}
const registry = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf8'));
// 2. 构建签到记录(仅检查 daily_checkin_required === true 的 Agent
const records = [];
let checkedIn = 0;
const missingAgents = [];
let skipped = 0;
for (const agent of registry.agents) {
// 跳过无需每日签到的 Agent事件触发型、已暂停等
if (agent.daily_checkin_required === false) {
skipped++;
continue;
}
console.log(` 🔍 检查 ${agent.id} (${agent.workflow})...`);
const run = await getLatestRun(agent.workflow);
const record = {
agent_id: agent.id,
agent_name: agent.name,
status: 'pending',
checkin_time: null,
last_run: null,
last_run_result: null,
note: '',
};
if (run && run.conclusion === 'success') {
record.status = '✅ 已签到';
record.checkin_time = run.updated_at;
record.last_run = run.updated_at;
record.last_run_result = 'success';
checkedIn++;
console.log(` ✅ 已签到 (${run.updated_at})`);
} else if (run) {
record.status = '❌ 未签到';
record.last_run = run.updated_at;
record.last_run_result = run.conclusion || run.status;
record.note = `最近运行结果: ${run.conclusion || run.status}`;
missingAgents.push(agent.id);
console.log(` ❌ 未签到 (结果: ${run.conclusion || run.status})`);
} else {
record.status = '❌ 未签到';
record.note = '今日无运行记录';
missingAgents.push(agent.id);
console.log(` ❌ 未签到 (今日无运行记录)`);
}
records.push(record);
}
console.log(`\n📋 跳过 ${skipped} 个无需签到的 Agent`);
// 3. 构建签到板
const board = {
board_version: 'v1.0',
checkin_deadline: '10:00+08:00',
inspection_time: '12:00+08:00',
date: today,
records: records,
summary: {
total: records.length,
checked_in: checkedIn,
missing: records.length - checkedIn,
missing_agents: missingAgents,
},
};
// 4. 写入签到板
fs.writeFileSync(BOARD_PATH, JSON.stringify(board, null, 2));
console.log(`\n📊 签到汇总:`);
console.log(` 总数: ${board.summary.total}`);
console.log(` 已签到: ${board.summary.checked_in}`);
console.log(` 缺席: ${board.summary.missing}`);
if (missingAgents.length > 0) {
console.log(` 缺席名单: ${missingAgents.join(', ')}`);
}
console.log(`\n✅ 签到记录已写入 checkin-board.json`);
}
main().catch((err) => {
console.error('❌ 签到脚本异常:', err.message);
process.exit(1);
});