Skip to content

Commit 66e18ea

Browse files
tommaso-moroCopilot
andcommitted
Add fields param to six more list/search tools
Extend the optional `fields` response-filtering parameter (gated behind the `fields_param` feature flag, with adoption/savings telemetry) to six more read tools, following the dual-variant pattern already used by search_code and get_file_contents: - list_issues, list_pull_requests, list_commits, list_releases - search_issues, search_pull_requests For each tool, `X` is the flag-enabled variant that advertises `fields` and filters each result item to the requested subset, while `LegacyX` exposes the original schema and never filters, acting as a kill switch when the flag is off. Exactly one variant survives inventory filtering for any flag state via mutually exclusive FeatureFlagEnable / FeatureFlagDisable annotations. Wrapped responses (list_issues, search_issues, search_pull_requests) preserve their count / pagination envelope and only filter the item list; bare-array responses keep their array shape. Filtering reuses the shared filterEachField helper. A new fieldsSchemaProperty helper builds the `fields` schema (search_code and get_file_contents now use it too), and a shared recordFieldsUsageFor helper centralizes the telemetry full-size computation. Each field enum lists only the JSON fields the specific tool actually emits: list_commits omits stats/files (requested without per-file detail) and list_issues lists only the fields its GraphQL fragment populates. Adds per-tool field-filtering, telemetry, and Legacy definition tests, extends the mutual-exclusivity gating test to all eight gated tools, and regenerates the `_ff_fields_param` toolsnaps and feature-flag docs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent a877d9c commit 66e18ea

20 files changed

Lines changed: 1755 additions & 109 deletions

docs/feature-flags.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,54 @@ runtime behavior (such as output formatting) won't appear here.
345345
- `repo`: Repository name (string, required)
346346
- `sha`: Accepts optional commit SHA. If specified, it will be used instead of ref (string, optional)
347347

348+
- **list_commits** - List commits
349+
- **Required OAuth Scopes**: `repo`
350+
- `author`: Author username or email address to filter commits by (string, optional)
351+
- `fields`: Subset of fields to return for each commit. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields, e.g. just 'sha' and 'html_url'. (string[], optional)
352+
- `owner`: Repository owner (string, required)
353+
- `page`: Page number for pagination (min 1) (number, optional)
354+
- `path`: Only commits containing this file path will be returned (string, optional)
355+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
356+
- `repo`: Repository name (string, required)
357+
- `sha`: Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA. (string, optional)
358+
- `since`: Only commits after this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD) (string, optional)
359+
- `until`: Only commits before this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD) (string, optional)
360+
361+
- **list_issues** - List issues
362+
- **Required OAuth Scopes**: `repo`
363+
- `after`: Cursor for pagination. Use the cursor from the previous response. (string, optional)
364+
- `direction`: Order direction. If provided, the 'orderBy' also needs to be provided. (string, optional)
365+
- `field_filters`: Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date). (object[], optional)
366+
- `fields`: Subset of fields to return for each issue. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' and 'field_values' in particular drops the largest per-result data. (string[], optional)
367+
- `labels`: Filter by labels (string[], optional)
368+
- `orderBy`: Order issues by field. If provided, the 'direction' also needs to be provided. (string, optional)
369+
- `owner`: Repository owner (string, required)
370+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
371+
- `repo`: Repository name (string, required)
372+
- `since`: Filter by date (ISO 8601 timestamp) (string, optional)
373+
- `state`: Filter by state, by default both open and closed issues are returned when not provided (string, optional)
374+
375+
- **list_pull_requests** - List pull requests
376+
- **Required OAuth Scopes**: `repo`
377+
- `base`: Filter by base branch (string, optional)
378+
- `direction`: Sort direction (string, optional)
379+
- `fields`: Subset of fields to return for each pull request. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-result data. (string[], optional)
380+
- `head`: Filter by head user/org and branch (string, optional)
381+
- `owner`: Repository owner (string, required)
382+
- `page`: Page number for pagination (min 1) (number, optional)
383+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
384+
- `repo`: Repository name (string, required)
385+
- `sort`: Sort by (string, optional)
386+
- `state`: Filter by state (string, optional)
387+
388+
- **list_releases** - List releases
389+
- **Required OAuth Scopes**: `repo`
390+
- `fields`: Subset of fields to return for each release. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-release data. (string[], optional)
391+
- `owner`: Repository owner (string, required)
392+
- `page`: Page number for pagination (min 1) (number, optional)
393+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
394+
- `repo`: Repository name (string, required)
395+
348396
- **search_code** - Search code
349397
- **Required OAuth Scopes**: `repo`
350398
- `fields`: Subset of fields to return for each code search result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'repository' and 'text_matches' in particular drops the largest per-result data. (string[], optional)
@@ -354,4 +402,26 @@ runtime behavior (such as output formatting) won't appear here.
354402
- `query`: Search query (GitHub code search REST). Implicit AND between terms; supports `OR`, `NOT`, and `"quoted phrase"` for exact match. Qualifiers: `repo:owner/repo`, `org:`, `user:`, `language:`, `path:dir` (prefix match), `filename:exact.ext`, `extension:`, `in:file`, `in:path`, `size:`, `is:archived`, `is:fork`. Max 256 chars. Examples: `WithContext language:go org:github`; `"package main" repo:o/r`; `func extension:go path:cmd repo:o/r`; `NOT TODO language:go repo:o/r`. (string, required)
355403
- `sort`: Sort field ('indexed' only) (string, optional)
356404

405+
- **search_issues** - Search issues
406+
- **Required OAuth Scopes**: `repo`
407+
- `fields`: Subset of fields to return for each issue result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
408+
- `order`: Sort order (string, optional)
409+
- `owner`: Optional repository owner. If provided with repo, only issues for this repository are listed. (string, optional)
410+
- `page`: Page number for pagination (min 1) (number, optional)
411+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
412+
- `query`: Search query using GitHub issues search syntax (string, required)
413+
- `repo`: Optional repository name. If provided with owner, only issues for this repository are listed. (string, optional)
414+
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
415+
416+
- **search_pull_requests** - Search pull requests
417+
- **Required OAuth Scopes**: `repo`
418+
- `fields`: Subset of fields to return for each pull request result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
419+
- `order`: Sort order (string, optional)
420+
- `owner`: Optional repository owner. If provided with repo, only pull requests for this repository are listed. (string, optional)
421+
- `page`: Page number for pagination (min 1) (number, optional)
422+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
423+
- `query`: Search query using GitHub pull request search syntax (string, required)
424+
- `repo`: Optional repository name. If provided with owner, only pull requests for this repository are listed. (string, optional)
425+
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
426+
357427
<!-- END AUTOMATED FEATURE FLAG TOOLS -->
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"annotations": {
3+
"idempotentHint": false,
4+
"readOnlyHint": true,
5+
"title": "List commits"
6+
},
7+
"description": "Get list of commits of a branch in a GitHub repository. Returns at least 30 results per page by default, but can return more if specified using the perPage parameter (up to 100).",
8+
"inputSchema": {
9+
"properties": {
10+
"author": {
11+
"description": "Author username or email address to filter commits by",
12+
"type": "string"
13+
},
14+
"fields": {
15+
"description": "Subset of fields to return for each commit. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields, e.g. just 'sha' and 'html_url'.",
16+
"items": {
17+
"enum": [
18+
"sha",
19+
"html_url",
20+
"commit",
21+
"author",
22+
"committer"
23+
],
24+
"type": "string"
25+
},
26+
"type": "array"
27+
},
28+
"owner": {
29+
"description": "Repository owner",
30+
"type": "string"
31+
},
32+
"page": {
33+
"description": "Page number for pagination (min 1)",
34+
"minimum": 1,
35+
"type": "number"
36+
},
37+
"path": {
38+
"description": "Only commits containing this file path will be returned",
39+
"type": "string"
40+
},
41+
"perPage": {
42+
"description": "Results per page for pagination (min 1, max 100)",
43+
"maximum": 100,
44+
"minimum": 1,
45+
"type": "number"
46+
},
47+
"repo": {
48+
"description": "Repository name",
49+
"type": "string"
50+
},
51+
"sha": {
52+
"description": "Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA.",
53+
"type": "string"
54+
},
55+
"since": {
56+
"description": "Only commits after this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD)",
57+
"type": "string"
58+
},
59+
"until": {
60+
"description": "Only commits before this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD)",
61+
"type": "string"
62+
}
63+
},
64+
"required": [
65+
"owner",
66+
"repo"
67+
],
68+
"type": "object"
69+
},
70+
"name": "list_commits"
71+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"annotations": {
3+
"idempotentHint": false,
4+
"readOnlyHint": true,
5+
"title": "List issues"
6+
},
7+
"description": "List issues in a GitHub repository. For pagination, use the 'endCursor' from the previous response's 'pageInfo' in the 'after' parameter.",
8+
"inputSchema": {
9+
"properties": {
10+
"after": {
11+
"description": "Cursor for pagination. Use the cursor from the previous response.",
12+
"type": "string"
13+
},
14+
"direction": {
15+
"description": "Order direction. If provided, the 'orderBy' also needs to be provided.",
16+
"enum": [
17+
"ASC",
18+
"DESC"
19+
],
20+
"type": "string"
21+
},
22+
"field_filters": {
23+
"description": "Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date).",
24+
"items": {
25+
"properties": {
26+
"field_name": {
27+
"description": "Name of the custom field (e.g. \"Priority\"). Case-insensitive.",
28+
"type": "string"
29+
},
30+
"value": {
31+
"description": "Value to filter on. For single-select fields, the option name (e.g. \"P1\"). For dates, YYYY-MM-DD. For numbers, the numeric value as a string. For text, the text value.",
32+
"type": "string"
33+
}
34+
},
35+
"required": [
36+
"field_name",
37+
"value"
38+
],
39+
"type": "object"
40+
},
41+
"type": "array"
42+
},
43+
"fields": {
44+
"description": "Subset of fields to return for each issue. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' and 'field_values' in particular drops the largest per-result data.",
45+
"items": {
46+
"enum": [
47+
"number",
48+
"title",
49+
"body",
50+
"state",
51+
"user",
52+
"labels",
53+
"comments",
54+
"created_at",
55+
"updated_at",
56+
"field_values"
57+
],
58+
"type": "string"
59+
},
60+
"type": "array"
61+
},
62+
"labels": {
63+
"description": "Filter by labels",
64+
"items": {
65+
"type": "string"
66+
},
67+
"type": "array"
68+
},
69+
"orderBy": {
70+
"description": "Order issues by field. If provided, the 'direction' also needs to be provided.",
71+
"enum": [
72+
"CREATED_AT",
73+
"UPDATED_AT",
74+
"COMMENTS"
75+
],
76+
"type": "string"
77+
},
78+
"owner": {
79+
"description": "Repository owner",
80+
"type": "string"
81+
},
82+
"perPage": {
83+
"description": "Results per page for pagination (min 1, max 100)",
84+
"maximum": 100,
85+
"minimum": 1,
86+
"type": "number"
87+
},
88+
"repo": {
89+
"description": "Repository name",
90+
"type": "string"
91+
},
92+
"since": {
93+
"description": "Filter by date (ISO 8601 timestamp)",
94+
"type": "string"
95+
},
96+
"state": {
97+
"description": "Filter by state, by default both open and closed issues are returned when not provided",
98+
"enum": [
99+
"OPEN",
100+
"CLOSED"
101+
],
102+
"type": "string"
103+
}
104+
},
105+
"required": [
106+
"owner",
107+
"repo"
108+
],
109+
"type": "object"
110+
},
111+
"name": "list_issues"
112+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
"annotations": {
3+
"idempotentHint": false,
4+
"readOnlyHint": true,
5+
"title": "List pull requests"
6+
},
7+
"description": "List pull requests in a GitHub repository. If the user specifies an author, then DO NOT use this tool and use the search_pull_requests tool instead.",
8+
"inputSchema": {
9+
"properties": {
10+
"base": {
11+
"description": "Filter by base branch",
12+
"type": "string"
13+
},
14+
"direction": {
15+
"description": "Sort direction",
16+
"enum": [
17+
"asc",
18+
"desc"
19+
],
20+
"type": "string"
21+
},
22+
"fields": {
23+
"description": "Subset of fields to return for each pull request. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-result data.",
24+
"items": {
25+
"enum": [
26+
"number",
27+
"title",
28+
"body",
29+
"state",
30+
"draft",
31+
"merged",
32+
"mergeable_state",
33+
"html_url",
34+
"user",
35+
"labels",
36+
"assignees",
37+
"requested_reviewers",
38+
"merged_by",
39+
"head",
40+
"base",
41+
"additions",
42+
"deletions",
43+
"changed_files",
44+
"commits",
45+
"comments",
46+
"created_at",
47+
"updated_at",
48+
"closed_at",
49+
"merged_at",
50+
"milestone"
51+
],
52+
"type": "string"
53+
},
54+
"type": "array"
55+
},
56+
"head": {
57+
"description": "Filter by head user/org and branch",
58+
"type": "string"
59+
},
60+
"owner": {
61+
"description": "Repository owner",
62+
"type": "string"
63+
},
64+
"page": {
65+
"description": "Page number for pagination (min 1)",
66+
"minimum": 1,
67+
"type": "number"
68+
},
69+
"perPage": {
70+
"description": "Results per page for pagination (min 1, max 100)",
71+
"maximum": 100,
72+
"minimum": 1,
73+
"type": "number"
74+
},
75+
"repo": {
76+
"description": "Repository name",
77+
"type": "string"
78+
},
79+
"sort": {
80+
"description": "Sort by",
81+
"enum": [
82+
"created",
83+
"updated",
84+
"popularity",
85+
"long-running"
86+
],
87+
"type": "string"
88+
},
89+
"state": {
90+
"description": "Filter by state",
91+
"enum": [
92+
"open",
93+
"closed",
94+
"all"
95+
],
96+
"type": "string"
97+
}
98+
},
99+
"required": [
100+
"owner",
101+
"repo"
102+
],
103+
"type": "object"
104+
},
105+
"name": "list_pull_requests"
106+
}

0 commit comments

Comments
 (0)