Include labels in formatContext() output for issues and PRs (#1298)

The formatted_context block sent to the agent omitted labels for both
issues and pull requests, even though the GraphQL queries already
fetched them. This caused agents to incorrectly report "no labels"
when labels existed, breaking any workflow that routes on label state
(e.g., drift-fix routing on drift:* labels in a Drift Watcher pattern).

Changes:
- Add 'PR Labels:' line to PR context output
- Add 'Issue Labels:' line to issue context output
- Both emit 'none' when no labels are present (explicit > omitted)
- Bump labels(first: 1) → labels(first: 100) in both queries; the
  previous cap meant only one label would appear even after the
  formatter fix
- Update existing tests + add 'with labels' tests for both PR and
  issue branches

Discovered while building a GitHub Actions workflow that uses this
action for drift-watcher routing in an internal seed framework
(joshpayne-joby/slim-routines#6). The agent self-diagnosed the gap
by inspecting this action's source — a satisfying full-loop.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joshpayne-joby 2026-06-11 21:19:15 -07:00 committed by GitHub
parent 9441a7fe22
commit 24b915648e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 4 deletions

View File

@ -25,7 +25,7 @@ export const PR_QUERY = `
additions additions
deletions deletions
state state
labels(first: 1) { labels(first: 100) {
nodes { nodes {
name name
} }
@ -113,7 +113,7 @@ export const ISSUE_QUERY = `
updatedAt updatedAt
lastEditedAt lastEditedAt
state state
labels(first: 1) { labels(first: 100) {
nodes { nodes {
name name
} }

View File

@ -8,6 +8,11 @@ import type {
import type { GitHubFileWithSHA } from "./fetcher"; import type { GitHubFileWithSHA } from "./fetcher";
import { sanitizeContent } from "../utils/sanitizer"; import { sanitizeContent } from "../utils/sanitizer";
function formatLabels(labelNodes: Array<{ name: string }>): string {
if (labelNodes.length === 0) return "none";
return labelNodes.map((l) => l.name).join(", ");
}
export function formatContext( export function formatContext(
contextData: GitHubPullRequest | GitHubIssue, contextData: GitHubPullRequest | GitHubIssue,
isPR: boolean, isPR: boolean,
@ -19,6 +24,7 @@ export function formatContext(
PR Author: ${prData.author.login} PR Author: ${prData.author.login}
PR Branch: ${prData.headRefName} -> ${prData.baseRefName} PR Branch: ${prData.headRefName} -> ${prData.baseRefName}
PR State: ${prData.state} PR State: ${prData.state}
PR Labels: ${formatLabels(prData.labels.nodes)}
PR Additions: ${prData.additions} PR Additions: ${prData.additions}
PR Deletions: ${prData.deletions} PR Deletions: ${prData.deletions}
Total Commits: ${prData.commits.totalCount} Total Commits: ${prData.commits.totalCount}
@ -28,7 +34,8 @@ Changed Files: ${prData.files.nodes.length} files`;
const sanitizedTitle = sanitizeContent(issueData.title); const sanitizedTitle = sanitizeContent(issueData.title);
return `Issue Title: ${sanitizedTitle} return `Issue Title: ${sanitizedTitle}
Issue Author: ${issueData.author.login} Issue Author: ${issueData.author.login}
Issue State: ${issueData.state}`; Issue State: ${issueData.state}
Issue Labels: ${formatLabels(issueData.labels.nodes)}`;
} }
} }

View File

@ -54,6 +54,53 @@ describe("formatContext", () => {
PR Author: test-user PR Author: test-user
PR Branch: feature/test -> main PR Branch: feature/test -> main
PR State: OPEN PR State: OPEN
PR Labels: none
PR Additions: 50
PR Deletions: 30
Total Commits: 3
Changed Files: 2 files`,
);
});
test("formats PR context with labels", () => {
const prData: GitHubPullRequest = {
title: "Test PR",
body: "PR body",
author: { login: "test-user" },
baseRefName: "main",
headRefName: "feature/test",
headRefOid: "abc123",
isCrossRepository: false,
headRepository: { owner: { login: "testowner" }, name: "testrepo" },
createdAt: "2023-01-01T00:00:00Z",
additions: 50,
deletions: 30,
state: "OPEN",
labels: {
nodes: [{ name: "bug" }, { name: "enhancement" }],
},
commits: {
totalCount: 3,
nodes: [],
},
files: {
nodes: [{} as GitHubFile, {} as GitHubFile],
},
comments: {
nodes: [],
},
reviews: {
nodes: [],
},
};
const result = formatContext(prData, true);
expect(result).toBe(
`PR Title: Test PR
PR Author: test-user
PR Branch: feature/test -> main
PR State: OPEN
PR Labels: bug, enhancement
PR Additions: 50 PR Additions: 50
PR Deletions: 30 PR Deletions: 30
Total Commits: 3 Total Commits: 3
@ -80,7 +127,36 @@ Changed Files: 2 files`,
expect(result).toBe( expect(result).toBe(
`Issue Title: Test Issue `Issue Title: Test Issue
Issue Author: test-user Issue Author: test-user
Issue State: OPEN`, Issue State: OPEN
Issue Labels: none`,
);
});
test("formats Issue context with labels", () => {
const issueData: GitHubIssue = {
title: "Test Issue",
body: "Issue body",
author: { login: "test-user" },
createdAt: "2023-01-01T00:00:00Z",
state: "OPEN",
labels: {
nodes: [
{ name: "architecture" },
{ name: "agent-sdk" },
{ name: "drift:functional" },
],
},
comments: {
nodes: [],
},
};
const result = formatContext(issueData, false);
expect(result).toBe(
`Issue Title: Test Issue
Issue Author: test-user
Issue State: OPEN
Issue Labels: architecture, agent-sdk, drift:functional`,
); );
}); });
}); });