diff --git a/apps/scout-bot/src/index.ts b/apps/scout-bot/src/index.ts index 680dbac..e7e3e07 100644 --- a/apps/scout-bot/src/index.ts +++ b/apps/scout-bot/src/index.ts @@ -8,9 +8,18 @@ const GITHUB_TOKEN = process.env.GITHUB_TOKEN; const VIBEWORK_API_URL = process.env.VIBEWORK_API_URL || "https://agent.wooo.work/api"; const SCOUT_API_KEY = process.env.SCOUT_API_KEY; const SCOUT_AGENT_ID = process.env.SCOUT_AGENT_ID || "scout_official_1"; -const SCOUT_CRON_EXPRESSION = process.env.SCOUT_CRON_EXPRESSION || "*/10 * * * *"; -const SCOUT_ISSUE_LABEL = process.env.SCOUT_ISSUE_LABEL || "good first issue"; -const SCOUT_TARGET_REPOS_RAW = process.env.SCOUT_TARGET_REPOS || "vibe-work/test-bounty-repo"; +const SCOUT_CRON_EXPRESSION = process.env.SCOUT_CRON_EXPRESSION || "*/3 * * * *"; +const SCOUT_ISSUE_LABELS_RAW = process.env.SCOUT_ISSUE_LABELS || process.env.SCOUT_ISSUE_LABEL || ""; +const SCOUT_TARGET_REPOS_RAW = + process.env.SCOUT_TARGET_REPOS || + "vibe-work/test-bounty-repo,open-webui/open-webui,microsoft/vscode,vercel/next.js,langchain-ai/langgraph,facebook/react,microsoft/TypeScript,openai/openai-cookbook,astral-sh/ruff,sequelize/sequelize,pnpm/pnpm,prisma/prisma"; +const SCOUT_PER_PAGE = Math.min(Math.max(parseInt(process.env.SCOUT_PER_PAGE || "50", 10), 1), 100); +const SCOUT_MAX_ISSUES_PER_SCAN = Math.max(parseInt(process.env.SCOUT_MAX_ISSUES_PER_SCAN || "60", 10), 1); + +const SCOUT_ISSUE_LABELS = SCOUT_ISSUE_LABELS_RAW + .split(",") + .map((entry) => entry.trim()) + .filter(Boolean); const SCOUT_TARGET_REPOS = SCOUT_TARGET_REPOS_RAW .split(",") @@ -160,21 +169,26 @@ async function scanRepositories() { for (const target of TARGET_REPOS) { try { - const issues = await octokit.issues.listForRepo({ + const issues = await octokit.issues.listForRepo({ owner: target.owner, repo: target.repo, state: "open", - labels: SCOUT_ISSUE_LABEL, - per_page: 30 + ...(SCOUT_ISSUE_LABELS.length > 0 ? { labels: SCOUT_ISSUE_LABELS.join(",") } : {}), + per_page: SCOUT_PER_PAGE }); console.log(`Found ${issues.data.length} open issues in ${target.owner}/${target.repo}`); - for (const issue of issues.data) { + const issueCandidates = issues.data.slice(0, SCOUT_MAX_ISSUES_PER_SCAN); + for (const issue of issueCandidates) { if (!issue.pull_request) { // Ignore PRs await processIssue(target.owner, target.repo, issue); } } + + if (issues.data.length > issueCandidates.length) { + console.log(`Limited scan to first ${issueCandidates.length} issues in ${target.owner}/${target.repo}`); + } } catch (error) { console.error(`Error scanning ${target.owner}/${target.repo}:`, error); } @@ -189,7 +203,7 @@ async function bootstrap() { bootstrap(); -// Default: every 10 minutes for higher volume inbound traffic +// Default: every 3 minutes for phase-1 high-velocity inbound traffic cron.schedule(SCOUT_CRON_EXPRESSION, () => { console.log(`Running scheduled GitHub scan (${SCOUT_CRON_EXPRESSION})...`); scanRepositories(); diff --git a/docker-compose.yml b/docker-compose.yml index 820557d..4e2cb4c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,10 +66,14 @@ services: - SCOUT_API_KEY=${SCOUT_API_KEY:-super-secret-mcp-key} - SCOUT_AGENT_ID=scout_official_1 # Optional: add more discovery repos via env (comma separated "owner/repo"), e.g. openai/swarm,significant-gravitas/autogpt - - SCOUT_TARGET_REPOS=${SCOUT_TARGET_REPOS} - - SCOUT_ISSUE_LABEL=${SCOUT_ISSUE_LABEL:-good first issue} - # Higher frequency for phase-1 bootstrapping; tune this safely after data stabilizes. - - SCOUT_CRON_EXPRESSION=${SCOUT_CRON_EXPRESSION:-*/10 * * * *} + - SCOUT_TARGET_REPOS=${SCOUT_TARGET_REPOS:-vibe-work/test-bounty-repo,open-webui/open-webui,microsoft/vscode,vercel/next.js,langchain-ai/langgraph,facebook/react,microsoft/TypeScript,openai/openai-cookbook,astral-sh/ruff,sequelize/sequelize,pnpm/pnpm,prisma/prisma} + # Optional: comma-separated labels; leave unset for broad scan of all open issues + - SCOUT_ISSUE_LABELS=${SCOUT_ISSUE_LABELS} + # Keep compatibility with existing naming + - SCOUT_ISSUE_LABEL=${SCOUT_ISSUE_LABEL} + - SCOUT_CRON_EXPRESSION=${SCOUT_CRON_EXPRESSION:-*/3 * * * *} + - SCOUT_PER_PAGE=${SCOUT_PER_PAGE:-50} + - SCOUT_MAX_ISSUES_PER_SCAN=${SCOUT_MAX_ISSUES_PER_SCAN:-60} # GitHub token should be provided in deployment env for real posting. - GITHUB_TOKEN=${GITHUB_TOKEN} networks: