Skip to content

Wire up AI Bridge to runtime (end-to-end AI agent demo) #11

Wire up AI Bridge to runtime (end-to-end AI agent demo)

Wire up AI Bridge to runtime (end-to-end AI agent demo) #11

Workflow file for this run

name: AI Issue Triage
on:
issues:
types: [opened]
permissions:
issues: write
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Classify and label issue
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = issue.title.toLowerCase();
const body = (issue.body || '').toLowerCase();
const labels = [];
// Classify by type
if (title.includes('[bug]') || body.includes('steps to reproduce')) {
labels.push('bug');
} else if (title.includes('[feature]') || body.includes('proposed solution')) {
labels.push('enhancement');
}
// Classify by module
const modules = {
'compiler': ['compiler', 'parser', 'codegen', 'transpil'],
'runtime': ['runtime', 'render', 'layout', 'window', 'taffy', 'tiny-skia'],
'dom': ['dom', 'document', 'element', 'event', 'css'],
'ai-bridge': ['ai-bridge', 'ai bridge', 'accessibility', 'a11y', 'screenshot'],
'cli': ['cli', 'w3cos build', 'w3cos run', 'w3cos init'],
'system': ['iso', 'buildroot', 'qemu', 'boot', 'kernel'],
};
for (const [label, keywords] of Object.entries(modules)) {
if (keywords.some(k => title.includes(k) || body.includes(k))) {
labels.push(`module:${label}`);
}
}
// Estimate difficulty
const hardKeywords = ['gpu', 'vello', 'swc', 'reactive', 'signal', 'kernel'];
const easyKeywords = ['example', 'typo', 'documentation', 'readme', 'init'];
if (easyKeywords.some(k => title.includes(k) || body.includes(k))) {
labels.push('difficulty:low');
labels.push('good first issue');
} else if (hardKeywords.some(k => title.includes(k) || body.includes(k))) {
labels.push('difficulty:hard');
} else {
labels.push('difficulty:medium');
}
// Mark as ai-ready if it has clear acceptance criteria
if (body.includes('acceptance criteria') || body.includes('## description')) {
labels.push('ai-ready');
}
if (labels.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: labels,
});
}
// Post triage comment
const labelList = labels.map(l => `\`${l}\``).join(', ');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: [
`**AI Triage** — Auto-classified this issue.`,
'',
`Labels: ${labelList || '_none applied_'}`,
'',
labels.includes('ai-ready')
? '> This issue is marked `ai-ready` and can be picked up by an AI contributor agent.'
: '> To make this issue AI-ready, add clear acceptance criteria and expected behavior.',
'',
'_This comment was generated by the W3C OS Management AI. See [AI_DEVELOPMENT.md](../blob/main/AI_DEVELOPMENT.md) for details._',
].join('\n'),
});