ci(triage): issue-triage automation (stale + on-open label/dedup + backfill) - #2224
Open
BenTaylorDev wants to merge 5 commits into
Open
ci(triage): issue-triage automation (stale + on-open label/dedup + backfill)#2224BenTaylorDev wants to merge 5 commits into
BenTaylorDev wants to merge 5 commits into
Conversation
…+ backfill)
Port of the CopilotKit issue-triage automation, adapted to ag-ui's label
taxonomy. Three workflows sharing one analysis module (scripts/triage/analyze.js;
repo-agnostic via context.repo):
- triage-stale.yml daily cron, no LLM. Marks needs-info issues stale after
14d silence, closes at +7d. Exempts Roadmap/proposal;
PRs untouched. (Needs a needs-info label created to act.)
- triage-on-open.yml issues:opened. One combined LLM call classifies + flags
duplicates. Applies allow-listed labels (>=0.75) and an
advisory dup comment (>=0.8). Never closes.
- triage-backfill.yml manual, dry-run by default. Same analysis over the
existing backlog, capped by max_issues.
Allow-list holds ag-ui's real content labels only: bug, enhancement,
documentation, question, Integration, SDK, framework, Agent Framework.
Curation/disposition labels (proposal, Roadmap, good first issue, help wanted…)
excluded. Safety: default-deny allow-list, confidence gates, flag-never-close,
spam/low-signal cost gate, SHA-pinned actions w/ persist-credentials:false,
clean-skip when ANTHROPIC_API_KEY absent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Python Preview PackagesVersion
Install with uvAdd the TestPyPI index to your [[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = trueThen install the packages you need: # Core SDK
uv add 'ag-ui-protocol==0.0.0.dev1784820006' --index testpypi
# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1784820006' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1784820006' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==0.0.0.dev1784820006' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1784820006' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1784820006' --index testpypiInstall with pippip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
ag-ui-protocol==0.0.0.dev1784820006
Commit: 7323f60 |
@ag-ui/a2a-middleware
@ag-ui/a2ui-middleware
@ag-ui/event-throttle-middleware
@ag-ui/mcp-apps-middleware
@ag-ui/mcp-middleware
@ag-ui/a2a
@ag-ui/adk
@ag-ui/ag2
@ag-ui/agno
@ag-ui/aws-strands
@ag-ui/claude-agent-sdk
@ag-ui/crewai
@ag-ui/langchain
@ag-ui/langgraph
@ag-ui/llamaindex
@ag-ui/mastra
@ag-ui/pydantic-ai
@ag-ui/vercel-ai-sdk
@ag-ui/watsonx
@ag-ui/a2ui-toolkit
create-ag-ui-app
@ag-ui/client
@ag-ui/core
@ag-ui/encoder
@ag-ui/proto
commit: |
…te injection)
ag-ui runs zizmor via GitHub Advanced Security without CopilotKit's suppression
config, so it surfaces findings CK's check hid. Address them at the source:
- excessive-permissions (error): move `issues: write` from workflow level to the
job, with an explanatory comment (also clears undocumented-permissions).
- anonymous-definition: give each job a `name:`.
- template-injection: pass workflow_dispatch inputs (dry_run/max_issues) via env
and read from process.env instead of interpolating ${{ }} into the script.
- secrets-outside-env (warning): inline-ignore with justification — a single
read-only classification key doesn't warrant a dedicated GH Environment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rred, Anthropic fallback) analyze.js gains a small provider abstraction selected by env: - Azure OpenAI / Foundry: AZURE_OPENAI_API_KEY (secret) + AZURE_OPENAI_ENDPOINT / AZURE_OPENAI_DEPLOYMENT (repo Variables); AZURE_OPENAI_API_VERSION optional. - Anthropic: ANTHROPIC_API_KEY (secret); ANTHROPIC_MODEL optional. - TRIAGE_PROVIDER forces one; else inferred from present creds (Azure wins if both). Both providers get the same prompt and return JSON-as-text, extracted uniformly, so the whole Foundry catalog (GPT/Llama/…) works. Workflows pass the new env through (non-secret Azure config via vars); backfill guard now checks providerConfigured(). Lets triage runs draw on shared Azure credits and drops the Anthropic spend-cap item. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…point pin)
From a 3-front security audit (Actions supply-chain, LLM prompt-injection, secrets)
against current best practices. The LLM/output surface was already contained; these
close the runner/cost-layer gaps:
- Harden-Runner (SHA-pinned) as the first step in every job, egress-policy: audit —
baseline the network, then flip to block with the commented allow-list so the model
key can only reach GitHub + the model host (the tj-actions lesson: pinning alone
doesn't stop a bumped/transitive dep from exfiltrating with unrestricted egress).
- Least privilege: top-level `permissions: {}` default + job-scoped
`contents: read` (needed by checkout) + `issues: write`. Nothing else.
- `timeout-minutes` on every job (a hung model fetch shouldn't burn the 6h default).
- analyze.js refuses to POST the key to any non-*.azure.com host (guards the
mutable endpoint Variable); Anthropic host is already hardcoded.
Already covered, not re-added: zizmor in CI + Renovate exist in both repos.
Operator follow-ups (documented in README): provider spend cap, flip egress to
block after baseline, confirm Renovate doesn't auto-merge action bumps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d-permissions) Per-scope rationale comments on the job permissions blocks so the GHAS/zizmor undocumented-permissions notices clear — a truly clean static-analysis pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Port of the CopilotKit issue-triage automation (CopilotKit/CopilotKit#6094), adapted to ag-ui's label taxonomy. Three GitHub Actions workflows sharing one analysis module. This is the issues-first slice of the OSS backlog maintenance plan; PR automation is a later, deferred arc.
Everything is advisory, high-confidence, and reopen-friendly — nothing closes an issue on an LLM's say-so.
triage-stale.ymlneeds-infoissues stale after 14d of silence, closes at +7d. Scoped toneeds-infoonly so it never touches active issues. ExemptsRoadmap,proposal. PRs untouched.triage-on-open.ymlissues: openedtriage-backfill.ymlmax_issues.scripts/triage/analyze.jsis the single source of truth for the LLM logic (candidate search → one combined Anthropic call → structured proposals). It's repo-agnostic (context.repo), so it's identical to the CopilotKit copy.ag-ui-specific tailoring
bug, enhancement, documentation, question, Integration, SDK, framework, Agent Framework.enhancementis this repo's canonical feature type (78 open issues); the rarely-usedFeature Requestsynonym is deliberately omitted so the classifier can't waffle between the two. Curation/disposition labels (proposal,Roadmap,good first issue,help wanted…) are excluded — human calls.Roadmap,proposal(the roadmap-track labels).Rollout
triage-staleneeds aneeds-infolabel created before it does anything — this repo doesn't have one yet. Until then it's a clean no-op.AZURE_OPENAI_API_KEY+ repo VariablesAZURE_OPENAI_ENDPOINT/AZURE_OPENAI_DEPLOYMENT.ANTHROPIC_API_KEY.TRIAGE_PROVIDERforces one; otherwise inferred from present creds (Azure wins if both).triage-backfillwith dry-run on + a smallmax_issuesto eyeball proposals before anything applies.Safety model
persist-credentials: false; job-scopedissues: write; inputs viaenv(no template injection) — passes zizmor/GHAS.callModel()speaks Anthropic or any Azure OpenAI-compatible deployment; keys are secrets, endpoint/deployment are non-secret Variables.Testing
node --check scripts/triage/analyze.js→ syntax OK.🤖 Generated with Claude Code