mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-26 18:06:43 +01:00
* Chat sessions URI handler * Type change * Update src/extension/chatSessions/vscode/chatSessionsUriHandler.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/extension/chatSessions/vscode/chatSessionsUriHandler.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
213 lines
5.0 KiB
TypeScript
213 lines
5.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { ILogService } from '../../log/common/logService';
|
|
import { IFetcherService } from '../../networking/common/fetcherService';
|
|
import { ITelemetryService } from '../../telemetry/common/telemetry';
|
|
|
|
export interface PullRequestSearchItem {
|
|
id: string;
|
|
number: number;
|
|
title: string;
|
|
state: string;
|
|
url: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
author: {
|
|
login: string;
|
|
} | null;
|
|
repository: {
|
|
owner: {
|
|
login: string;
|
|
};
|
|
name: string;
|
|
};
|
|
additions: number;
|
|
deletions: number;
|
|
fullDatabaseId: number;
|
|
headRefOid: number;
|
|
}
|
|
|
|
export interface PullRequestSearchResult {
|
|
search: {
|
|
nodes: PullRequestSearchItem[];
|
|
pageInfo: {
|
|
hasNextPage: boolean;
|
|
endCursor: string | null;
|
|
};
|
|
issueCount: number;
|
|
};
|
|
}
|
|
|
|
export interface SessionInfo {
|
|
id: string;
|
|
name: string;
|
|
user_id: number;
|
|
agent_id: number;
|
|
logs: string;
|
|
logs_blob_id: string;
|
|
state: 'completed' | 'in_progress' | 'failed' | 'queued';
|
|
owner_id: number;
|
|
repo_id: number;
|
|
resource_type: string;
|
|
resource_id: number;
|
|
last_updated_at: string;
|
|
created_at: string;
|
|
completed_at: string;
|
|
event_type: string;
|
|
workflow_run_id: number;
|
|
premium_requests: number;
|
|
error: string | null;
|
|
}
|
|
|
|
export async function makeGitHubAPIRequest(
|
|
fetcherService: IFetcherService,
|
|
logService: ILogService,
|
|
telemetry: ITelemetryService,
|
|
host: string,
|
|
routeSlug: string,
|
|
method: 'GET' | 'POST',
|
|
token: string | undefined,
|
|
body?: { [key: string]: any },
|
|
version?: string,
|
|
type: 'json' | 'text' = 'json',
|
|
userAgent?: string) {
|
|
const headers: any = {
|
|
'Accept': 'application/vnd.github+json',
|
|
};
|
|
if (token) {
|
|
headers['Authorization'] = `Bearer ${token}`;
|
|
}
|
|
if (version) {
|
|
headers['X-GitHub-Api-Version'] = version;
|
|
}
|
|
if (userAgent) {
|
|
headers['User-Agent'] = userAgent;
|
|
}
|
|
|
|
const response = await fetcherService.fetch(`${host}/${routeSlug}`, {
|
|
method,
|
|
headers,
|
|
body: body ? JSON.stringify(body) : undefined
|
|
});
|
|
if (!response.ok) {
|
|
return undefined;
|
|
}
|
|
|
|
try {
|
|
const result = type === 'json' ? await response.json() : await response.text();
|
|
const rateLimit = Number(response.headers.get('x-ratelimit-remaining'));
|
|
const logMessage = `[RateLimit] REST rate limit remaining: ${rateLimit}, ${routeSlug}`;
|
|
if (rateLimit < 1000) {
|
|
// Danger zone
|
|
logService.warn(logMessage);
|
|
telemetry.sendMSFTTelemetryEvent('githubAPI.approachingRateLimit', { rateLimit: rateLimit.toString() });
|
|
} else {
|
|
logService.debug(logMessage);
|
|
}
|
|
return result;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
export async function makeGitHubGraphQLRequest(fetcherService: IFetcherService, logService: ILogService, telemetry: ITelemetryService, host: string, query: string, token: string | undefined, variables?: { [key: string]: any }) {
|
|
const headers: any = {
|
|
'Accept': 'application/vnd.github+json',
|
|
'Content-Type': 'application/json',
|
|
};
|
|
if (token) {
|
|
headers['Authorization'] = `Bearer ${token}`;
|
|
}
|
|
|
|
const body = JSON.stringify({
|
|
query,
|
|
variables
|
|
});
|
|
|
|
const response = await fetcherService.fetch(`${host}/graphql`, {
|
|
method: 'POST',
|
|
headers,
|
|
body
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return undefined;
|
|
}
|
|
|
|
try {
|
|
const result = await response.json();
|
|
const rateLimit = Number(response.headers.get('x-ratelimit-remaining'));
|
|
const logMessage = `[RateLimit] GraphQL rate limit remaining: ${rateLimit}, query: ${query}`;
|
|
if (rateLimit < 1000) {
|
|
// Danger zone
|
|
logService.warn(logMessage);
|
|
telemetry.sendMSFTTelemetryEvent('githubAPI.approachingRateLimit', { rateLimit: rateLimit.toString() });
|
|
} else {
|
|
logService.debug(logMessage);
|
|
}
|
|
return result;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
export async function makeSearchGraphQLRequest(
|
|
fetcherService: IFetcherService,
|
|
logService: ILogService,
|
|
telemetry: ITelemetryService,
|
|
host: string,
|
|
token: string | undefined,
|
|
searchQuery: string,
|
|
first: number = 20,
|
|
): Promise<PullRequestSearchItem[]> {
|
|
const query = `
|
|
query FetchCopilotAgentPullRequests($searchQuery: String!, $first: Int!, $after: String) {
|
|
search(query: $searchQuery, type: ISSUE, first: $first, after: $after) {
|
|
nodes {
|
|
... on PullRequest {
|
|
number
|
|
id
|
|
fullDatabaseId
|
|
headRefOid
|
|
title
|
|
state
|
|
url
|
|
createdAt
|
|
updatedAt
|
|
additions
|
|
deletions
|
|
author {
|
|
login
|
|
}
|
|
repository {
|
|
owner {
|
|
login
|
|
}
|
|
name
|
|
}
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
endCursor
|
|
}
|
|
issueCount
|
|
}
|
|
}
|
|
`;
|
|
|
|
logService.debug(`[FolderRepositoryManager+0] Fetch pull request category ${searchQuery}`);
|
|
|
|
const variables = {
|
|
searchQuery,
|
|
first
|
|
};
|
|
|
|
const result = await makeGitHubGraphQLRequest(fetcherService, logService, telemetry, host, query, token, variables);
|
|
|
|
return result ? result.data.search.nodes : [];
|
|
}
|