Repository: clearfeed/quix
Pull request #218: chore(github): Remove deprecated `issuesAndPullRequests` method
Author: login: imkhateeb
Created: 2025-05-20T10:46:48Z | Merged: 2025-05-27T05:20:25Z

## Describe your changes

This change replaces the deprecated `issuesAndPullRequests` endpoint with the `.request()` method, which will automatically be overridden to use advanced search starting from September 4th. After this date, there will be no need to include the `advanced_search` parameter, as all issue queries will default to advanced search. Our code will remain unaffected by this transition.

- Renamed the handler from `searchIssues` to `searchIssuesOrPullRequests`, as it will now serve as the unified handler for searching both issues and pull requests.
- Removed the redundant `listIssues` and `listPullRequests` handlers, along with their associated tools and types.
- Added support for additional filters such as `label` and `assignee` to improve search precision.
- Limited `per_page` results to 5, as the response output is truncated after a certain size, which could result in incomplete data being shown.
- Included a pagination message to enable the LLM to prompt the user for the next page of results when applicable.

Relevant Docs Links - [Github Search issues and pull request API](https://docs.github.com/en/rest/search/search?apiVersion=2022-11-28#search-issues-and-pull-requests) , [the GitHub blog](https://github.blog/changelog/2025-03-06-github-issues-projects-api-support-for-issues-advanced-search-and-more/).

## How has this been tested?

After this change, I was successfully getting issues and pull requests with different filters.

## Screenshots (if appropriate):
`search_issues_or_pull_requests`
![Screenshot 2025-05-20 160520](https://github.com/user-attachments/assets/3a6925dc-5fa6-404c-a9f5-5ff046d45d57)
![Screenshot 2025-05-20 160616](https://github.com/user-attachments/assets/f5797c53-a263-489c-bc06-9d76c57375a5)

`search_issues_global`
![Screenshot 2025-05-20 160039](https://github.com/user-attachments/assets/f27ce8a9-fa3a-4214-8191-2d1cfdf8c3a6)
![Screenshot 2025-05-20 160244](https://github.com/user-attachments/assets/7790276c-b4fd-40b6-b7a0-8f848ea5801f)

List issues test after removing `list_issues` tool:
![Screenshot 2025-05-23 110936](https://github.com/user-attachments/assets/bc77e6b8-7e22-4828-a54c-ccde3d36804d)
![Screenshot 2025-05-23 111223](https://github.com/user-attachments/assets/cd946175-3f1f-49a3-95c6-c593e7f4679d)
![Screenshot 2025-05-23 112441](https://github.com/user-attachments/assets/f6f4989e-3ca7-46fc-8be0-2c731d9cd2b4)

List PRs test after removing `list_pull_requests` tool:
![Screenshot 2025-05-23 111914](https://github.com/user-attachments/assets/6aa19b92-45e9-4c46-a0e7-dfe0d2994d85)
![Screenshot 2025-05-23 111814](https://github.com/user-attachments/assets/ba4cc51f-080a-48a6-96bb-a0dbf77c94fd)
![Screenshot 2025-05-23 111501](https://github.com/user-attachments/assets/dfea3d0f-b60c-44f2-ab63-f4e7b1933595)


Diff:
diff --git a/agent-packages/packages/github/package.json b/agent-packages/packages/github/package.json
index a7ccecc0..e1959e11 100644
--- a/agent-packages/packages/github/package.json
+++ b/agent-packages/packages/github/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@clearfeed-ai/quix-github-agent",
-  "version": "1.2.10",
+  "version": "1.2.11",
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
   "files": [
diff --git a/agent-packages/packages/github/src/index.ts b/agent-packages/packages/github/src/index.ts
index 7e6a3176..f1b82e62 100644
--- a/agent-packages/packages/github/src/index.ts
+++ b/agent-packages/packages/github/src/index.ts
@@ -1,8 +1,6 @@
 import { BaseResponse, BaseService } from '@clearfeed-ai/quix-common-agent';
 import {
   GitHubConfig,
-  SearchIssuesParams,
-  SearchIssuesResponse,
   CreateOrUpdateFileParams,
   SearchRepositoriesParams,
   CreateRepositoryParams,
@@ -10,19 +8,18 @@ import {
   CreatePullRequestParams,
   CreateBranchParams,
   ListCommitsParams,
-  ListIssuesParams,
   UpdateIssueParams,
   AddIssueCommentParams,
   SearchUsersParams,
   PullRequestParams,
-  ListPullRequestsParams,
   CreatePullRequestReviewParams,
   MergePullRequestParams,
   UpdatePullRequestBranchParams,
   SearchCodeParams,
   SearchCodeResponse,
   SearchIssuesGlobalParams,
-  SearchPullRequestsResponse
+  SearchIssuesOrPullRequestsParams,
+  SearchIssuesOrPullRequestsResponse
 } from './types';
 import { CodeSearchParams, CreateIssueParams } from './types/index';
 import type { OctokitType, RestEndpointMethodTypes } from './types/oktokit';
@@ -93,28 +90,33 @@ export class GitHubService implements BaseService<GitHubConfig> {
     }
   }
 
-  async searchIssues(
-    params: SearchIssuesParams
-  ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
+  async searchIssuesOrPullRequests(
+    params: SearchIssuesOrPullRequestsParams
+  ): Promise<BaseResponse<SearchIssuesOrPullRequestsResponse['data']>> {
     try {
-      const { repo, owner, keyword, type, reporter, status } = params;
+      const { repo, owner, keyword, type, reporter, status, sort, order, label, page, assignee } =
+        params;
       let query = `repo:${owner}/${repo} is:${type}`;
 
       if (keyword) query += ` in:title,body ${keyword}`;
       if (reporter) query += ` author:${reporter}`;
       if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+      if (assignee) query += ` assignee:${assignee}`;
 
-      const response = await this.client.search.issuesAndPullRequests({
+      const response = await this.client.request('GET /search/issues', {
         q: query,
-        per_page: 10,
-        sort: 'updated',
-        order: 'desc'
+        per_page: 5,
+        sort,
+        order,
+        page
       });
 
       return {
         success: true,
         data: {
-          issues: response.data.items
+          pagination: `Showing ${response.data.items.length} of ${response.data.total_count} results of page ${page}. Ask the user if they want to see more results.`,
+          issuesOrPullRequests: response.data.items
         }
       };
     } catch (error) {
@@ -460,32 +462,6 @@ export class GitHubService implements BaseService<GitHubConfig> {
     }
   }
 
-  async listIssues(
-    params: ListIssuesParams
-  ): Promise<BaseResponse<RestEndpointMethodTypes['issues']['listForRepo']['response']['data']>> {
-    try {
-      const { owner, repo, state, sort, direction, since, page, per_page, labels } = params;
-      const response = await this.client.issues.listForRepo({
-        owner,
-        repo,
-        state,
-        sort,
-        direction,
-        since,
-        page,
-        per_page,
-        labels: labels?.join(',')
-      });
-      return { success: true, data: response.data };
-    } catch (error) {
-      console.error('Error listing GitHub issues:', error);
-      return {
-        success: false,
-        error: error instanceof Error ? error.message : 'Failed to list GitHub issues'
-      };
-    }
-  }
-
   async updateIssue(
     params: UpdateIssueParams
   ): Promise<BaseResponse<RestEndpointMethodTypes['issues']['update']['response']['data']>> {
@@ -576,38 +552,6 @@ export class GitHubService implements BaseService<GitHubConfig> {
     }
   }
 
-  async listPullRequests(
-    params: ListPullRequestsParams
-  ): Promise<BaseResponse<SearchPullRequestsResponse['data']>> {
-    try {
-      const { owner, repo, state, author, keyword, sort, order, per_page, page } = params;
-      let query = `repo:${owner}/${repo} is:pr`;
-
-      if (keyword) query += ` in:title,body ${keyword}`;
-      if (author) query += ` author:${author}`;
-      if (state) query += ` state:${state}`;
-      const response = await this.client.search.issuesAndPullRequests({
-        q: query,
-        sort,
-        order,
-        per_page,
-        page
-      });
-      return {
-        success: true,
-        data: {
-          pullRequests: response.data.items
-        }
-      };
-    } catch (error) {
-      console.error('Error listing GitHub pull requests:', error);
-      return {
-        success: false,
-        error: error instanceof Error ? error.message : 'Failed to list GitHub pull requests'
-      };
-    }
-  }
-
   async createPullRequestReview(
     params: CreatePullRequestReviewParams
   ): Promise<BaseResponse<RestEndpointMethodTypes['pulls']['createReview']['response']['data']>> {
@@ -787,19 +731,29 @@ export class GitHubService implements BaseService<GitHubConfig> {
 
   async searchIssuesGlobal(
     params: SearchIssuesGlobalParams
-  ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
+  ): Promise<BaseResponse<SearchIssuesOrPullRequestsResponse['data']>> {
     try {
-      const response = await this.client.rest.search.issuesAndPullRequests({
-        q: params.q,
-        sort: params.sort,
-        order: params.order,
-        per_page: params.per_page,
-        page: params.page
+      const { type, keyword, status, sort, order, label, page, assignee, reporter } = params;
+
+      let query = `is:${type}`;
+      if (keyword) query += ` in:title,body ${keyword}`;
+      if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+      if (assignee) query += ` assignee:${assignee}`;
+      if (reporter) query += ` author:${reporter}`;
+
+      const response = await this.client.request('GET /search/issues', {
+        q: query,
+        per_page: 5,
+        sort,
+        order,
+        page
       });
       return {
         success: true,
         data: {
-          issues: response.data.items
+          pagination: `Showing ${response.data.items.length} of ${response.data.total_count} results of page ${page}. Ask the user if they want to see more results.`,
+          issuesOrPullRequests: response.data.items
         }
       };
     } catch (error) {
diff --git a/agent-packages/packages/github/src/schema.ts b/agent-packages/packages/github/src/schema.ts
new file mode 100644
index 00000000..7c2f5fbe
--- /dev/null
+++ b/agent-packages/packages/github/src/schema.ts
@@ -0,0 +1,42 @@
+import { z } from 'zod';
+
+export const baseSearchIssuesOrPullRequestsSchema = z.object({
+  type: z
+    .enum(['issue', 'pr'])
+    .describe(
+      'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
+    ),
+  keyword: z
+    .string()
+    .describe(
+      'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
+    )
+    .optional(),
+  reporter: z
+    .string()
+    .describe(
+      'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
+    )
+    .optional(),
+  assignee: z
+    .string()
+    .describe('GitHub username of the person who is assigned to the issue/PR.')
+    .optional(),
+  status: z
+    .enum(['open', 'closed'])
+    .describe('Filter issues by their status (open or closed)')
+    .optional(),
+  sort: z
+    .enum(['comments', 'reactions', 'created', 'updated'])
+    .describe('Sort by: number of comments, reactions, creation date, or last update')
+    .optional(),
+  order: z
+    .enum(['asc', 'desc'])
+    .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)')
+    .optional(),
+  label: z
+    .string()
+    .describe('Filter issues by their labels. Can include multiple labels separated by commas')
+    .optional(),
+  page: z.number().describe('Page number for pagination, starting at 1')
+});
diff --git a/agent-packages/packages/github/src/tools.ts b/agent-packages/packages/github/src/tools.ts
index 7397b88f..c94ac238 100644
--- a/agent-packages/packages/github/src/tools.ts
+++ b/agent-packages/packages/github/src/tools.ts
@@ -2,7 +2,6 @@ import { ToolConfig } from '@clearfeed-ai/quix-common-agent';
 import { GitHubService } from './index';
 import {
   GitHubConfig,
-  SearchIssuesParams,
   CreateOrUpdateFileParams,
   SearchRepositoriesParams,
   CreateRepositoryParams,
@@ -10,21 +9,21 @@ import {
   CreatePullRequestParams,
   CreateBranchParams,
   ListCommitsParams,
-  ListIssuesParams,
   UpdateIssueParams,
   AddIssueCommentParams,
   SearchUsersParams,
   PullRequestParams,
-  ListPullRequestsParams,
   CreatePullRequestReviewParams,
   MergePullRequestParams,
   UpdatePullRequestBranchParams,
   SearchCodeParams,
+  SearchIssuesOrPullRequestsParams,
   SearchIssuesGlobalParams
 } from './types';
 import { DynamicStructuredTool } from '@langchain/core/tools';
 import { z } from 'zod';
 import { CodeSearchParams, CreateIssueParams } from './types/index';
+import { baseSearchIssuesOrPullRequestsSchema } from './schema';
 
 const GITHUB_TOOL_SELECTION_PROMPT = `
 For GitHub-related queries, consider using GitHub tools when the user wants to:
@@ -51,10 +50,10 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
 
   const tools: DynamicStructuredTool<any>[] = [
     new DynamicStructuredTool({
-      name: 'search_repository_issues',
+      name: 'search_issues_or_pull_requests',
       description:
         'Search issues or PRs within a specific repository based on status, keywords, and reporter',
-      schema: z.object({
+      schema: baseSearchIssuesOrPullRequestsSchema.extend({
         repo: config.repo
           ? z
               .string()
@@ -80,29 +79,10 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
               .string()
               .describe(
                 'Username or organization that owns the repository. This is the first part of the repository URL (required)'
-              ),
-        type: z
-          .enum(['issue', 'pull-request'])
-          .describe(
-            'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
-          ),
-        keyword: z
-          .string()
-          .describe(
-            'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
-          ),
-        reporter: z
-          .string()
-          .describe(
-            'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
-          )
-          .optional(),
-        status: z
-          .enum(['open', 'closed'])
-          .describe('Filter issues by their status (open or closed)')
-          .optional()
+              )
       }),
-      func: async (args: SearchIssuesParams) => service.searchIssues(args)
+      func: async (args: SearchIssuesOrPullRequestsParams) =>
+        service.searchIssuesOrPullRequests(args)
     }),
     new DynamicStructuredTool({
       name: 'get_github_issue',
@@ -436,55 +416,6 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
       }),
       func: async (params: ListCommitsParams) => service.listCommits(params)
     }),
-    new DynamicStructuredTool({
-      name: 'list_issues',
-      description: 'List and filter issues in a GitHub repository',
-      schema: z.object({
-        owner: config.owner
-          ? z
-              .string()
-              .describe('Username or organization that owns the repository')
-              .optional()
-              .default(config.owner)
-          : z.string().describe('Username or organization that owns the repository'),
-        repo: config.repo
-          ? z
-              .string()
-              .describe('Name of the repository to list issues from')
-              .optional()
-              .default(config.repo)
-          : z.string().describe('Name of the repository to list issues from'),
-        state: z
-          .enum(['open', 'closed', 'all'])
-          .describe('Filter issues by their state: open, closed, or all')
-          .optional(),
-        sort: z
-          .enum(['created', 'updated', 'comments'])
-          .describe('How to sort issues: by creation date, last update, or number of comments')
-          .optional(),
-        direction: z
-          .enum(['asc', 'desc'])
-          .describe('Sort direction: ascending (oldest first) or descending (newest first)')
-          .optional(),
-        since: z
-          .string()
-          .describe('ISO 8601 timestamp to filter issues updated after this date')
-          .optional(),
-        page: z.number().describe('Page number for pagination, starting at 1').optional(),
-        per_page: z
-          .number()
-          .int('Page size must be an integer')
-          .min(1, 'Page size must be at least 1')
-          .max(100, 'GitHub API limits page size to maximum of 100')
-          .describe('Number of items per page (min: 1, max: 100)')
-          .optional(),
-        labels: z
-          .array(z.string())
-          .describe('Filter issues by label names (e.g., ["bug", "high-priority"])')
-          .optional()
-      }),
-      func: async (params: ListIssuesParams) => service.listIssues(params)
-    }),
     new DynamicStructuredTool({
       name: 'update_issue',
       description: 'Update an existing issue in a GitHub repository',
@@ -588,33 +519,6 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
       }),
       func: async (params: PullRequestParams) => service.getPullRequest(params)
     }),
-    new DynamicStructuredTool({
-      name: 'list_pull_requests',
-      description: 'List and filter repository pull requests',
-      schema: z.object({
-        owner: config.owner ? z.string().optional().default(config.owner) : z.string(),
-        repo: config.repo ? z.string().optional().default(config.repo) : z.string(),
-        state: z.enum(['open', 'closed', 'all']).optional(),
-        author: z.string().describe('Filter by author username').optional(),
-        sort: z.enum(['created', 'updated', 'comments', 'interactions', 'reactions']).optional(),
-        order: z.enum(['asc', 'desc']).optional(),
-        keyword: z
-          .string()
-          .describe(
-            'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
-          )
-          .optional(),
-        per_page: z
-          .number()
-          .int('Page size must be an integer')
-          .min(1, 'Page size must be at least 1')
-          .max(100, 'GitHub API limits page size to maximum of 100')
-          .describe('Number of items per page (min: 1, max: 100)')
-          .default(100),
-        page: z.number().optional()
-      }),
-      func: async (params: ListPullRequestsParams) => service.listPullRequests(params)
-    }),
     new DynamicStructuredTool({
       name: 'create_pull_request_review',
       description: 'Create a review on a pull request with comments and approval status',
@@ -725,30 +629,7 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
     new DynamicStructuredTool({
       name: 'search_issues_global',
       description: 'Search for issues and pull requests across all GitHub repositories',
-      schema: z.object({
-        q: z
-          .string()
-          .describe(
-            'Search query using GitHub issues search syntax. Can include is:issue/pr, state:open/closed, label:name, etc.'
-          ),
-        sort: z
-          .enum(['comments', 'reactions', 'created', 'updated'])
-          .describe('Sort by: number of comments, reactions, creation date, or last update')
-          .optional(),
-        order: z
-          .enum(['asc', 'desc'])
-          .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)')
-          .optional(),
-        page: z.number().describe('Page number for pagination, starting at 1').optional(),
-        per_page: z
-          .number()
-          .int('Page size must be an integer')
-          .min(1, 'Page size must be at least 1')
-          .max(100, 'GitHub API limits page size to maximum of 100')
-          .describe('Number of results per page (min: 1, max: 100)')
-          .default(100)
-          .optional()
-      }),
+      schema: baseSearchIssuesOrPullRequestsSchema,
       func: async (params: SearchIssuesGlobalParams) => service.searchIssuesGlobal(params)
     }),
     new DynamicStructuredTool({
diff --git a/agent-packages/packages/github/src/types.ts b/agent-packages/packages/github/src/types.ts
index e0d20e6f..4bd173e6 100644
--- a/agent-packages/packages/github/src/types.ts
+++ b/agent-packages/packages/github/src/types.ts
@@ -1,6 +1,8 @@
 import { BaseConfig, BaseResponse } from '@clearfeed-ai/quix-common-agent';
 import type { RestEndpointMethodTypes } from './types/oktokit';
 import type { Endpoints } from '@octokit/types';
+import { baseSearchIssuesOrPullRequestsSchema } from './schema';
+import { z } from 'zod';
 
 export interface GitHubConfig extends BaseConfig {
   token: string;
@@ -16,30 +18,19 @@ export interface SearchCodeParams {
   per_page?: number;
 }
 
-export interface SearchIssuesGlobalParams {
-  q: string;
-  sort?: 'comments' | 'reactions' | 'created' | 'updated';
-  order?: 'asc' | 'desc';
-  page?: number;
-  per_page?: number;
-}
+export type SearchIssuesGlobalParams = z.infer<typeof baseSearchIssuesOrPullRequestsSchema>;
 
-export interface SearchIssuesParams {
+export type SearchIssuesOrPullRequestsParams = z.infer<
+  typeof baseSearchIssuesOrPullRequestsSchema
+> & {
   repo: string;
   owner: string;
-  type: 'issue' | 'pull-request';
-  keyword: string;
-  reporter?: string;
-  status?: 'open' | 'closed';
-}
+};
 
 export type SearchCodeResponse = Endpoints['GET /search/code']['response']['data'];
-export type SearchIssuesResponse = BaseResponse<{
-  issues: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
-}>;
-
-export type SearchPullRequestsResponse = BaseResponse<{
-  pullRequests: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
+export type SearchIssuesOrPullRequestsResponse = BaseResponse<{
+  issuesOrPullRequests: Endpoints['GET /search/issues']['response']['data']['items'];
+  pagination: string;
 }>;
 
 type SearchResultItem =
@@ -112,18 +103,6 @@ export interface ListCommitsParams {
   perPage?: number;
 }
 
-export interface ListIssuesParams {
-  owner: string;
-  repo: string;
-  state?: 'open' | 'closed' | 'all';
-  sort?: 'created' | 'updated' | 'comments';
-  direction?: 'asc' | 'desc';
-  since?: string;
-  page?: number;
-  per_page?: number;
-  labels?: string[];
-}
-
 export interface UpdateIssueParams {
   owner: string;
   repo: string;
@@ -157,18 +136,6 @@ export interface PullRequestParams {
   pull_number: number;
 }
 
-export interface ListPullRequestsParams {
-  owner: string;
-  repo: string;
-  state?: 'open' | 'closed' | 'all';
-  author?: string;
-  sort?: 'created' | 'updated' | 'comments' | 'interactions' | 'reactions';
-  order?: 'asc' | 'desc';
-  per_page: number;
-  page?: number;
-  keyword?: string;
-}
-
 export interface CreatePullRequestReviewParams extends PullRequestParams {
   body: string;
   event: 'APPROVE' | 'REQUEST_CHANGES' | 'COMMENT';
diff --git a/package.json b/package.json
index 5d26fe32..cd56a0e7 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
   },
   "dependencies": {
     "@clearfeed-ai/quix-common-agent": "^1.1.5",
-    "@clearfeed-ai/quix-github-agent": "^1.2.10",
+    "@clearfeed-ai/quix-github-agent": "^1.2.11",
     "@clearfeed-ai/quix-hubspot-agent": "^1.1.9",
     "@clearfeed-ai/quix-jira-agent": "^1.2.15",
     "@clearfeed-ai/quix-okta-agent": "^1.0.1",
diff --git a/yarn.lock b/yarn.lock
index 729a0e60..b0879750 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -365,10 +365,10 @@
   dependencies:
     zod "^3.24.2"
 
-"@clearfeed-ai/quix-github-agent@^1.2.10":
-  version "1.2.10"
-  resolved "https://registry.yarnpkg.com/@clearfeed-ai/quix-github-agent/-/quix-github-agent-1.2.10.tgz#0cabb27ce829e88dee1ebb36dc52c83ab5e560d9"
-  integrity sha512-ByfB5brHEVMSBjJQYV/U6flloMHXhW7ZOOtnCv0QkaBjQZARrIrcdLaKxyoVM6YpVIZJP6WuCxcakWyoZ1Pe+w==
+"@clearfeed-ai/quix-github-agent@^1.2.11":
+  version "1.2.11"
+  resolved "https://registry.yarnpkg.com/@clearfeed-ai/quix-github-agent/-/quix-github-agent-1.2.11.tgz#3b7a6ba1407b52fcd81138a9fad12cff396f0671"
+  integrity sha512-yYX03LgUH+Or64yeTmmiu0PItE0YNJNLEeJQXj8g/FTp6wRoG/aBOMfbMa5Nl/ZqTRyLZaZKvPUMxYjIYQid6g==
   dependencies:
     "@octokit/rest" "^21.1.1"
 


Reviews:
user: login: gemini-code-assist[bot]
body: Hello @imkhateeb, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

## Summary of Changes
Hello team,

Gemini here, providing a summary of this pull request by @imkhateeb. The primary goal of this PR is to address the deprecation of the `issuesAndPullRequests` method in the GitHub API. To achieve this, the PR replaces the deprecated method with the more general `.request()` method, which is designed to handle the upcoming changes in GitHub's search API more gracefully.

Beyond the direct API replacement, this PR also consolidates the functionality for searching issues and pull requests into a single handler and tool, removing the previously separate `listIssues` and `listPullRequests` handlers. It also enhances the search capabilities by adding support for `label` and `assignee` filters and adjusts the default `per_page` limit to 5, adding a pagination message to guide users on retrieving more results.

### Highlights
* **API Deprecation**: Replaced the deprecated `issuesAndPullRequests` method with the `.request()` method to ensure compatibility with upcoming GitHub API changes.
* **Handler Consolidation**: Unified the `searchIssues` handler and tool into a single `searchIssuesOrPullRequests` handler/tool that can search for both issues and pull requests.
* **Redundant Code Removal**: Removed the separate `listIssues` and `listPullRequests` handlers and their associated tools and types, as their functionality is now covered by the unified search.
* **Enhanced Search Filters**: Added support for filtering search results by `label` and `assignee` in both the repository-specific and global search tools.
* **Pagination Adjustment**: Limited the default `per_page` results to 5 for search queries and included a pagination message in the response to inform the user about additional results.

### Changelog
<details>
<summary>Click here to see the changelog</summary>

* **agent-packages/packages/github/package.json**
  * Bumped package version from 1.2.10 to 1.2.11.
* **agent-packages/packages/github/src/index.ts**
  * Removed imports for deprecated/removed types (`SearchIssuesParams`, `ListIssuesParams`, `ListPullRequestsParams`, `SearchPullRequestsResponse`).
  * Added import for the new unified type `SearchIssuesOrPullRequestsParams`.
  * Renamed `searchIssues` method to `searchIssuesOrPullRequests`.
  * Updated `searchIssuesOrPullRequests` signature to use `SearchIssuesOrPullRequestsParams`.
  * Changed API call in `searchIssuesOrPullRequests` from `client.search.issuesAndPullRequests` to `client.request('GET /search/issues', ...)`.
  * Added logic to include `label` and `assignee` filters in the search query for `searchIssuesOrPullRequests`.
  * Reduced `per_page` from 10 to 5 in `searchIssuesOrPullRequests`.
  * Added a `pagination` string to the success response data in `searchIssuesOrPullRequests`.
  * Removed the `listIssues` method.
  * Removed the `listPullRequests` method.
  * Changed API call in `searchIssuesGlobal` from `client.rest.search.issuesAndPullRequests` to `client.request('GET /search/issues', ...)`.
  * Modified query construction in `searchIssuesGlobal` to use individual parameters (`type`, `keyword`, `status`, `label`) instead of a single `q` string.
  * Reduced `per_page` to 5 in `searchIssuesGlobal`.
  * Added a `pagination` string to the success response data in `searchIssuesGlobal`.
* **agent-packages/packages/github/src/tools.ts**
  * Removed imports for deprecated/removed types (`SearchIssuesParams`, `ListIssuesParams`, `ListPullRequestsParams`).
  * Added import for the new unified type `SearchIssuesOrPullRequestsParams`.
  * Renamed the tool `search_repository_issues` to `search_issues_or_pull_requests`.
  * Updated the schema for `search_issues_or_pull_requests` to use `SearchIssuesOrPullRequestsParams`.
  * Updated the `type` enum in `search_issues_or_pull_requests` schema from `pull-request` to `pr`.
  * Made the `keyword` parameter optional in `search_issues_or_pull_requests` schema.
  * Added `assignee`, `label`, `sort`, `order`, and `page` parameters to the `search_issues_or_pull_requests` schema.
  * Updated the `func` for `search_issues_or_pull_requests` to call `service.searchIssuesOrPullRequests`.
  * Removed the `list_issues` tool definition.
  * Removed the `list_pull_requests` tool definition.
  * Updated the schema for `search_issues_global` to replace the `q` parameter with `type`, `keyword`, `status`, and `label`.
  * Removed the `per_page` parameter from the `search_issues_global` schema and made `page` required.
  * Updated the `func` for `search_issues_global` to call `service.searchIssuesGlobal`.
* **agent-packages/packages/github/src/types.ts**
  * Modified `SearchIssuesGlobalParams` to replace `q` with `type`, `keyword`, `status`, and `label`.
  * Made `page` required and removed `per_page` from `SearchIssuesGlobalParams`.
  * Renamed `SearchIssuesParams` to `SearchIssuesOrPullRequestsParams`.
  * Modified `SearchIssuesOrPullRequestsParams` to change `type` enum from `pull-request` to `pr`, make `keyword` optional, add `assignee`, `sort`, `order`, and `label`, and make `page` required.
  * Removed the `SearchPullRequestsResponse` type.
  * Modified `SearchIssuesResponse` to include a `pagination` string property.
  * Removed the `ListIssuesParams` type.
  * Removed the `ListPullRequestsParams` type.

</details>


<details>

<summary><b>Using Gemini Code Assist</b></summary>
<br>

The full guide for Gemini Code Assist can be found on our [documentation page](https://developers.google.com/gemini-code-assist/docs/review-github-code), here are some quick tips.

<b>Invoking Gemini</b>

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either `/gemini <command>` or `@gemini-code-assist <command>`. Below is a summary of the supported commands.

Feature | Command | Description
--- | --- | ---
Code Review | `/gemini review` | Performs a code review for the current pull request in its current state.
Pull Request Summary | `/gemini summary` | Provides a summary of the current pull request in its current state.
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments.
Help | `/gemini help` | Displays a list of available commands.

<b>Customization</b>

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a `.gemini/` folder in the base of the repository. Detailed instructions can be found [here](https://developers.google.com/gemini-code-assist/docs/customize-gemini-behavior-github).

<b>Limitations & Feedback</b>

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments to provide feedback.

</details>

<b>You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the [Gemini Code Assist IDE Extension](https://cloud.google.com/products/gemini/code-assist).</b>


[^1]: Review the [Privacy Notices](https://policies.google.com/privacy), [Generative AI Prohibited Use Policy](https://policies.google.com/terms/generative-ai/use-policy), [Terms of Service](https://policies.google.com/terms), and learn how to configure Gemini Code Assist in GitHub [here](https://developers.google.com/gemini-code-assist/docs/review-github-code). Gemini can make mistakes, so double check it and [use code with caution](https://support.google.com/legal/answer/13505487).

---

> An old API, it must retire,
> A new request, sets code afire.
> Issues and PRs, now unified,
> With filters new, where bugs can hide.


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:47:29Z
user: login: gemini-code-assist[bot]
body: ## Code Review
This pull request successfully addresses the deprecation of the `issuesAndPullRequests` endpoint by migrating to the `.request()` method. The consolidation of issue and pull request search functionality into a single handler (`searchIssuesOrPullRequests`) and tool is a good improvement for maintainability and aligns with the API changes. The addition of `label` and `assignee` filters enhances the search capabilities. The inclusion of a pagination message is also helpful for the LLM interaction.

However, I've identified a few areas related to parameter handling, type clarity, and potential breaking changes that should be reviewed before merging. Overall, the direction of the changes is positive.

### Summary of Findings
* **Hardcoded `per_page`**: The `per_page` parameter is hardcoded to `5` in both `searchIssuesOrPullRequests` and `searchIssuesGlobal` methods. This limits the number of results returned per page and removes control from the tool consumer. Consider making this parameter configurable or controllable via the tool schema.
* **Breaking change in `type` enum**: The `type` enum value for pull requests has been changed from `'pull-request'` to `'pr'` in the `SearchIssuesOrPullRequestsParams` type and the corresponding tool schema. This is a breaking change for existing users and should be documented.
* **Missing `.optional()` for `order` parameter**: The `order` parameter in the `search_issues_or_pull_requests` tool schema is missing `.optional()`, although the API defaults to `desc`. Making it optional would provide more flexibility.
* **Deprecated type name usage**: The `SearchIssuesResponse` type still references `RestEndpointMethodTypes['search']['issuesAndPullRequests']`, which is based on a deprecated endpoint name. Consider using a more generic or locally defined type for clarity and maintainability.
* **Minor logging/error message inconsistency**: The error logging and messages in the `searchIssuesOrPullRequests` method still refer specifically to 'GitHub PRs' instead of 'issues or PRs'. (Note: This was a low-severity finding and no specific comment was added per review settings).

### Merge Readiness
This pull request implements necessary changes to address a deprecated GitHub API endpoint and improves the search functionality. However, there are several medium-severity issues identified related to parameter handling (hardcoded `per_page`), type clarity, and a potential breaking change in the `type` enum value. These issues should be addressed to ensure the tool is robust, flexible, and maintains backward compatibility where possible, or clearly documents breaking changes. Therefore, I recommend requesting changes before merging. I am unable to approve the pull request; please have other reviewers decide on the merge readiness after the suggested changes are made.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:48:10Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:53:58Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:54:07Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:55:02Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:57:07Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:57:53Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T11:04:43Z
user: login: batflarrow
body: Always link the docs of the API when making changes like these
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T03:51:44Z
user: login: batflarrow
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T03:55:17Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T04:33:26Z
user: login: batflarrow
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T04:57:54Z
user: login: batflarrow
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T05:00:36Z
user: login: imkhateeb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T05:08:48Z

Review comments:
diff_hunk: @@ -93,27 +90,32 @@ export class GitHubService implements BaseService<GitHubConfig> {
     }
   }
 
-  async searchIssues(
-    params: SearchIssuesParams
+  async searchIssuesOrPullRequests(
+    params: SearchIssuesOrPullRequestsParams
   ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
     try {
-      const { repo, owner, keyword, type, reporter, status } = params;
+      const { repo, owner, keyword, type, reporter, status, sort, order, label, page, assignee } =
+        params;
       let query = `repo:${owner}/${repo} is:${type}`;
 
       if (keyword) query += ` in:title,body ${keyword}`;
       if (reporter) query += ` author:${reporter}`;
       if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+      if (assignee) query += ` assignee:${assignee}`;
 
-      const response = await this.client.search.issuesAndPullRequests({
+      const response = await this.client.request('GET /search/issues', {
         q: query,
-        per_page: 10,
-        sort: 'updated',
-        order: 'desc'
+        per_page: 5,
path: agent-packages/packages/github/src/index.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

The `per_page` parameter is hardcoded to `5` here. While the PR description mentions limiting results due to truncation, hardcoding this value removes the ability for the tool consumer (the LLM) to control the page size. Is this intended behavior, or should `per_page` be a parameter in the `SearchIssuesOrPullRequestsParams` interface and the corresponding tool schema?
created_at: 2025-05-20T10:48:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -789,16 +733,24 @@ export class GitHubService implements BaseService<GitHubConfig> {
     params: SearchIssuesGlobalParams
   ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
     try {
-      const response = await this.client.rest.search.issuesAndPullRequests({
-        q: params.q,
-        sort: params.sort,
-        order: params.order,
-        per_page: params.per_page,
-        page: params.page
+      const { type, keyword, status, label, sort, order, page } = params;
+
+      let query = `is:${type}`;
+      if (keyword) query += ` in:title,body ${keyword}`;
+      if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+
+      const response = await this.client.request('GET /search/issues', {
+        q: query,
+        per_page: 5,
path: agent-packages/packages/github/src/index.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

Similar to the `searchIssuesOrPullRequests` method, the `per_page` parameter is hardcoded to `5` in the `searchIssuesGlobal` method. This limits the number of results returned per page for global searches. Given that the previous implementation allowed `per_page` up to 100 via the tool parameter, this change significantly reduces the amount of data the tool can retrieve in a single call. Is this limitation intentional for global searches as well, or should `per_page` be added back to the `SearchIssuesGlobalParams` interface and the tool schema?
created_at: 2025-05-20T10:48:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,27 +80,47 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
                 'Username or organization that owns the repository. This is the first part of the repository URL (required)'
               ),
         type: z
-          .enum(['issue', 'pull-request'])
+          .enum(['issue', 'pr'])
path: agent-packages/packages/github/src/tools.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

The `type` enum value for pull requests has been changed from `'pull-request'` to `'pr'`. This is a breaking change for any existing users of the `search_repository_issues` tool (now `search_issues_or_pull_requests`) who might be using the `'pull-request'` value. Was this change intentional? If so, it should be clearly documented as a breaking change, and the description here should reflect the new accepted value (`'pr'`).
created_at: 2025-05-20T10:48:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,27 +80,47 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
                 'Username or organization that owns the repository. This is the first part of the repository URL (required)'
               ),
         type: z
-          .enum(['issue', 'pull-request'])
+          .enum(['issue', 'pr'])
           .describe(
             'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
           ),
         keyword: z
           .string()
           .describe(
             'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
-          ),
+          )
+          .optional(),
         reporter: z
           .string()
           .describe(
             'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
           )
           .optional(),
+        assignee: z
+          .string()
+          .describe('GitHub username of the person who is assigned to the issue/PR.')
+          .optional(),
         status: z
           .enum(['open', 'closed'])
           .describe('Filter issues by their status (open or closed)')
-          .optional()
+          .optional(),
+        sort: z
+          .enum(['comments', 'reactions', 'created', 'updated'])
+          .describe('Sort by: number of comments, reactions, creation date, or last update')
+          .optional(),
+        order: z
+          .enum(['asc', 'desc'])
+          .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)'),
path: agent-packages/packages/github/src/tools.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

The `order` parameter in the `search_issues_or_pull_requests` tool schema is missing `.optional()`. The GitHub API defaults to `desc` for search results. Making this parameter optional in the schema would allow the LLM to omit it when the default descending order is desired, providing more flexibility.

```suggestion
          .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)')
          .optional()
```
created_at: 2025-05-20T10:48:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
-  q: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
+  status?: 'open' | 'closed';
+  label?: string;
   sort?: 'comments' | 'reactions' | 'created' | 'updated';
   order?: 'asc' | 'desc';
-  page?: number;
-  per_page?: number;
+  page: number;
 }
 
-export interface SearchIssuesParams {
+export interface SearchIssuesOrPullRequestsParams {
   repo: string;
   owner: string;
-  type: 'issue' | 'pull-request';
-  keyword: string;
+  type: 'issue' | 'pr';
path: agent-packages/packages/github/src/types.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

The `type` enum value for pull requests has been changed from `'pull-request'` to `'pr'`. This change is reflected in the tool schema as well. This is a breaking change for consumers of this type and the associated tool. Please ensure this change is intentional and documented.
created_at: 2025-05-20T10:48:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
-  q: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
+  status?: 'open' | 'closed';
+  label?: string;
   sort?: 'comments' | 'reactions' | 'created' | 'updated';
   order?: 'asc' | 'desc';
-  page?: number;
-  per_page?: number;
+  page: number;
 }
 
-export interface SearchIssuesParams {
+export interface SearchIssuesOrPullRequestsParams {
   repo: string;
   owner: string;
-  type: 'issue' | 'pull-request';
-  keyword: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
   reporter?: string;
+  assignee?: string;
   status?: 'open' | 'closed';
+  sort?: 'comments' | 'reactions' | 'created' | 'updated';
+  order?: 'asc' | 'desc';
+  label?: string;
+  page: number;
 }
 
 export type SearchCodeResponse = Endpoints['GET /search/code']['response']['data'];
 export type SearchIssuesResponse = BaseResponse<{
   issues: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
-}>;
-
-export type SearchPullRequestsResponse = BaseResponse<{
-  pullRequests: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
+  pagination: string;
 }>;
path: agent-packages/packages/github/src/types.ts
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

The `SearchIssuesResponse` type still uses `RestEndpointMethodTypes['search']['issuesAndPullRequests']` for the `issues` array, which refers to the deprecated endpoint name. While the data structure might be compatible, using a type named after a deprecated endpoint can be confusing and potentially brittle if the underlying Octokit types are updated. Consider creating a local type alias for the item structure or using a more generic type if available to decouple from the deprecated endpoint name.
created_at: 2025-05-20T10:48:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -93,27 +90,32 @@ export class GitHubService implements BaseService<GitHubConfig> {
     }
   }
 
-  async searchIssues(
-    params: SearchIssuesParams
+  async searchIssuesOrPullRequests(
+    params: SearchIssuesOrPullRequestsParams
   ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
     try {
-      const { repo, owner, keyword, type, reporter, status } = params;
+      const { repo, owner, keyword, type, reporter, status, sort, order, label, page, assignee } =
+        params;
       let query = `repo:${owner}/${repo} is:${type}`;
 
       if (keyword) query += ` in:title,body ${keyword}`;
       if (reporter) query += ` author:${reporter}`;
       if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+      if (assignee) query += ` assignee:${assignee}`;
 
-      const response = await this.client.search.issuesAndPullRequests({
+      const response = await this.client.request('GET /search/issues', {
         q: query,
-        per_page: 10,
-        sort: 'updated',
-        order: 'desc'
+        per_page: 5,
path: agent-packages/packages/github/src/index.ts
user: login: imkhateeb
body: Limited per_page results to 5 by hardcoding it, as the response output is truncated after a certain size, which could result in incomplete data being shown.
created_at: 2025-05-20T10:53:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -789,16 +733,24 @@ export class GitHubService implements BaseService<GitHubConfig> {
     params: SearchIssuesGlobalParams
   ): Promise<BaseResponse<SearchIssuesResponse['data']>> {
     try {
-      const response = await this.client.rest.search.issuesAndPullRequests({
-        q: params.q,
-        sort: params.sort,
-        order: params.order,
-        per_page: params.per_page,
-        page: params.page
+      const { type, keyword, status, label, sort, order, page } = params;
+
+      let query = `is:${type}`;
+      if (keyword) query += ` in:title,body ${keyword}`;
+      if (status) query += ` state:${status}`;
+      if (label) query += ` label:${label}`;
+
+      const response = await this.client.request('GET /search/issues', {
+        q: query,
+        per_page: 5,
path: agent-packages/packages/github/src/index.ts
user: login: imkhateeb
body: Limited per_page results to 5 by hardcoding it, as the response output is truncated after a certain size, which could result in incomplete data being shown.
created_at: 2025-05-20T10:54:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,27 +80,47 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
                 'Username or organization that owns the repository. This is the first part of the repository URL (required)'
               ),
         type: z
-          .enum(['issue', 'pull-request'])
+          .enum(['issue', 'pr'])
path: agent-packages/packages/github/src/tools.ts
user: login: imkhateeb
body: Yes, this is an intended change and we will work on the documentation later.
created_at: 2025-05-20T10:55:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,27 +80,47 @@ export async function createGitHubToolsExport(config: GitHubConfig): Promise<Too
                 'Username or organization that owns the repository. This is the first part of the repository URL (required)'
               ),
         type: z
-          .enum(['issue', 'pull-request'])
+          .enum(['issue', 'pr'])
           .describe(
             'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
           ),
         keyword: z
           .string()
           .describe(
             'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
-          ),
+          )
+          .optional(),
         reporter: z
           .string()
           .describe(
             'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
           )
           .optional(),
+        assignee: z
+          .string()
+          .describe('GitHub username of the person who is assigned to the issue/PR.')
+          .optional(),
         status: z
           .enum(['open', 'closed'])
           .describe('Filter issues by their status (open or closed)')
-          .optional()
+          .optional(),
+        sort: z
+          .enum(['comments', 'reactions', 'created', 'updated'])
+          .describe('Sort by: number of comments, reactions, creation date, or last update')
+          .optional(),
+        order: z
+          .enum(['asc', 'desc'])
+          .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)'),
path: agent-packages/packages/github/src/tools.ts
user: login: imkhateeb
body: Aah, missed it. It should be optional
created_at: 2025-05-20T10:57:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
-  q: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
+  status?: 'open' | 'closed';
+  label?: string;
   sort?: 'comments' | 'reactions' | 'created' | 'updated';
   order?: 'asc' | 'desc';
-  page?: number;
-  per_page?: number;
+  page: number;
 }
 
-export interface SearchIssuesParams {
+export interface SearchIssuesOrPullRequestsParams {
   repo: string;
   owner: string;
-  type: 'issue' | 'pull-request';
-  keyword: string;
+  type: 'issue' | 'pr';
path: agent-packages/packages/github/src/types.ts
user: login: imkhateeb
body: See https://github.com/clearfeed/quix/pull/218#discussion_r2097657204
created_at: 2025-05-20T10:57:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
-  q: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
+  status?: 'open' | 'closed';
+  label?: string;
   sort?: 'comments' | 'reactions' | 'created' | 'updated';
   order?: 'asc' | 'desc';
-  page?: number;
-  per_page?: number;
+  page: number;
 }
 
-export interface SearchIssuesParams {
+export interface SearchIssuesOrPullRequestsParams {
   repo: string;
   owner: string;
-  type: 'issue' | 'pull-request';
-  keyword: string;
+  type: 'issue' | 'pr';
+  keyword?: string;
   reporter?: string;
+  assignee?: string;
   status?: 'open' | 'closed';
+  sort?: 'comments' | 'reactions' | 'created' | 'updated';
+  order?: 'asc' | 'desc';
+  label?: string;
+  page: number;
 }
 
 export type SearchCodeResponse = Endpoints['GET /search/code']['response']['data'];
 export type SearchIssuesResponse = BaseResponse<{
   issues: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
-}>;
-
-export type SearchPullRequestsResponse = BaseResponse<{
-  pullRequests: RestEndpointMethodTypes['search']['issuesAndPullRequests']['response']['data']['items'];
+  pagination: string;
 }>;
path: agent-packages/packages/github/src/types.ts
user: login: imkhateeb
body: Changed to valid type
created_at: 2025-05-20T11:04:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
path: agent-packages/packages/github/src/types.ts
user: login: batflarrow
body: Whenever we are updating code, please use the zod schema to infer types. Let's use the zod schema
created_at: 2025-05-23T03:55:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,29 +17,33 @@ export interface SearchCodeParams {
 }
 
 export interface SearchIssuesGlobalParams {
path: agent-packages/packages/github/src/types.ts
user: login: imkhateeb
body: Okay, will change manually defined types to zod schema types
created_at: 2025-05-23T04:33:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+import { z } from 'zod';
+
+export const baseSearchIssuesOrPullRequestsSchema = z.object({
+  type: z
+    .enum(['issue', 'pr'])
+    .describe(
+      'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
+    ),
+  keyword: z
+    .string()
+    .describe(
+      'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
+    )
+    .optional(),
+  reporter: z
+    .string()
+    .describe(
+      'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
+    )
+    .optional(),
+  assignee: z
+    .string()
+    .describe('GitHub username of the person who is assigned to the issue/PR.')
+    .optional(),
+  status: z
+    .enum(['open', 'closed'])
+    .describe('Filter issues by their status (open or closed)')
+    .optional(),
+  sort: z
+    .enum(['comments', 'reactions', 'created', 'updated'])
+    .describe('Sort by: number of comments, reactions, creation date, or last update')
+    .optional(),
+  order: z
+    .enum(['asc', 'desc'])
+    .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)')
+    .optional(),
+  label: z
+    .string()
+    .describe('Filter issues by their labels. Can include multiple labels separated by commas')
+    .optional(),
+  page: z.number().describe('Page number for pagination, starting at 1')
+});
+
+export const searchIssuesOrPullRequestsSchema = baseSearchIssuesOrPullRequestsSchema.extend({
path: agent-packages/packages/github/src/schema.ts
user: login: batflarrow
body: We are already extending https://github.com/clearfeed/quix/blob/b195e8080c7f288a942b813da6c3f1fc5b328009/agent-packages/packages/github/src/tools.ts#L55-L69 why do we need to extend the same schema twice?
Just extend it in the tools file?
created_at: 2025-05-27T04:57:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,55 @@
+import { z } from 'zod';
+
+export const baseSearchIssuesOrPullRequestsSchema = z.object({
+  type: z
+    .enum(['issue', 'pr'])
+    .describe(
+      'Specify whether to search for issues or pull requests. Both are tracked the same way in GitHub'
+    ),
+  keyword: z
+    .string()
+    .describe(
+      'Text to search for in issue titles and descriptions. Can include multiple words or phrases'
+    )
+    .optional(),
+  reporter: z
+    .string()
+    .describe(
+      'GitHub username of the person who created the issue/PR. Filters results to show only their submissions'
+    )
+    .optional(),
+  assignee: z
+    .string()
+    .describe('GitHub username of the person who is assigned to the issue/PR.')
+    .optional(),
+  status: z
+    .enum(['open', 'closed'])
+    .describe('Filter issues by their status (open or closed)')
+    .optional(),
+  sort: z
+    .enum(['comments', 'reactions', 'created', 'updated'])
+    .describe('Sort by: number of comments, reactions, creation date, or last update')
+    .optional(),
+  order: z
+    .enum(['asc', 'desc'])
+    .describe('Sort order: ascending (oldest/least first) or descending (newest/most first)')
+    .optional(),
+  label: z
+    .string()
+    .describe('Filter issues by their labels. Can include multiple labels separated by commas')
+    .optional(),
+  page: z.number().describe('Page number for pagination, starting at 1')
+});
+
+export const searchIssuesOrPullRequestsSchema = baseSearchIssuesOrPullRequestsSchema.extend({
path: agent-packages/packages/github/src/schema.ts
user: login: imkhateeb
body: Ooh yea, We could do this instead,
```
export type SearchIssuesOrPullRequestsParams = z.infer<
  typeof baseSearchIssuesOrPullRequestsSchema
> & {
  repo: string;
  owner: string;
};
```
created_at: 2025-05-27T05:08:48Z
author_association: CONTRIBUTOR

PR comments:
user: login: cubic-dev-ai[bot]
created_at: 2025-05-20T10:46:51Z
body: Your cubic subscription is currently inactive. Please [reactivate your subscription](https://cubic.dev/settings?tab=subscription) to receive AI reviews and use cubic.
author_association: CONTRIBUTOR
user: login: batflarrow
created_at: 2025-05-23T04:00:13Z
body: > Removed the redundant listIssues and listPullRequests handlers, along with their associated tools and types.

Listing and searching are two different operations. Why have we removed the list tools?
In the tests I don't see tests like

`List all issues of test repository`
`List all pull requests of test repository`

Unless we validate that the `search_issues_or_pull_requests` tool can do these tasks we can't remove these tools. Ask ChatGPT to come up with some valid test cases for the list tools that have been removed and make sure they are working with the new tool
author_association: CONTRIBUTOR
user: login: imkhateeb
created_at: 2025-05-23T06:55:34Z
body: > Always link the docs of the API when making changes like these

> Listing and searching are two different operations. Why have we removed the list tools?
> In the tests I don't see tests like
> 
> List all issues of test repository
> List all pull requests of test repository
> 
> Unless we validate that the search_issues_or_pull_requests tool can do these tasks we can't remove these tools. Ask ChatGPT to come up with some valid test cases for the list tools that have been removed and make sure they are working with the new tool

Relevant docs links and Listing operations test results are added in the description.
author_association: CONTRIBUTOR