@shipfox/api-integration-github 12.3.0 → 12.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +11 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +7 -4
- package/dist/api/client.js.map +1 -1
- package/dist/api/installation-token-envelope.d.ts +5 -1
- package/dist/api/installation-token-envelope.d.ts.map +1 -1
- package/dist/api/installation-token-envelope.js +16 -5
- package/dist/api/installation-token-envelope.js.map +1 -1
- package/dist/api/shared-installation-token-cache.d.ts.map +1 -1
- package/dist/api/shared-installation-token-cache.js +10 -4
- package/dist/api/shared-installation-token-cache.js.map +1 -1
- package/dist/core/agent-tools.d.ts +11 -4
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent-tools.js +182 -17
- package/dist/core/agent-tools.js.map +1 -1
- package/dist/core/github-agent-tool-catalog.js +1 -1
- package/dist/core/github-agent-tool-catalog.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/api/client.test.ts +41 -5
- package/src/api/client.ts +22 -2
- package/src/api/installation-token-envelope.ts +24 -2
- package/src/api/shared-installation-token-cache.test.ts +28 -0
- package/src/api/shared-installation-token-cache.ts +7 -0
- package/src/core/agent-tools.test.ts +862 -8
- package/src/core/agent-tools.ts +271 -19
- package/src/core/github-agent-tool-catalog.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/dist/core/agent-tools.js
CHANGED
|
@@ -1,9 +1,44 @@
|
|
|
1
1
|
import { Octokit } from 'octokit';
|
|
2
|
+
import { mapGithubError } from '#api/client.js';
|
|
2
3
|
import { createGithubInstallationTokenProvider } from '#api/installation-token-provider.js';
|
|
3
4
|
import { normalizedGithubApiBaseUrl } from '#config.js';
|
|
4
5
|
import { GithubIntegrationProviderError } from './errors.js';
|
|
5
6
|
import { githubAgentToolCatalog, githubAgentToolSelectionCatalog } from './github-agent-tool-catalog.js';
|
|
6
7
|
export { buildGithubAgentToolSelectionCatalog, DEFAULT_JOB_LOG_TAIL_LINES, githubAgentToolCatalog, githubAgentToolSelectionCatalog } from './github-agent-tool-catalog.js';
|
|
8
|
+
const GITHUB_GRAPHQL_ROUTE = 'POST /graphql';
|
|
9
|
+
const GITHUB_ARTIFACT_ARCHIVE_FORMAT = 'zip';
|
|
10
|
+
const GITHUB_ARTIFACT_DOWNLOAD_ROUTE = `GET /repos/{owner}/{repo}/actions/artifacts/{resource_id}/${GITHUB_ARTIFACT_ARCHIVE_FORMAT}`;
|
|
11
|
+
const GITHUB_ARTIFACT_DOWNLOAD_TIMEOUT_MS = 30_000;
|
|
12
|
+
const NO_PENDING_REVIEW_MESSAGE = 'No pending pull request review found for the authenticated GitHub user.';
|
|
13
|
+
const LATEST_PENDING_REVIEW_QUERY = `
|
|
14
|
+
query LatestPendingPullRequestReview($owner: String!, $repo: String!, $pullNumber: Int!) {
|
|
15
|
+
viewer {
|
|
16
|
+
login
|
|
17
|
+
}
|
|
18
|
+
repository(owner: $owner, name: $repo) {
|
|
19
|
+
pullRequest(number: $pullNumber) {
|
|
20
|
+
reviews(last: 100, states: [PENDING]) {
|
|
21
|
+
nodes {
|
|
22
|
+
id
|
|
23
|
+
author {
|
|
24
|
+
login
|
|
25
|
+
}
|
|
26
|
+
createdAt
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
const ADD_PENDING_REVIEW_COMMENT_MUTATION = `
|
|
34
|
+
mutation AddCommentToPendingReview($input: AddPullRequestReviewThreadInput!) {
|
|
35
|
+
addPullRequestReviewThread(input: $input) {
|
|
36
|
+
thread {
|
|
37
|
+
id
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
7
42
|
export class GithubAgentToolsProvider {
|
|
8
43
|
constructor(options = {}){
|
|
9
44
|
this.options = options;
|
|
@@ -39,13 +74,17 @@ export class GithubAgentToolsProvider {
|
|
|
39
74
|
return githubToolError('GitHub installation token is missing permission for this operation');
|
|
40
75
|
}
|
|
41
76
|
const client = (this.options.createClient ?? createOctokitClient)(token.token);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
77
|
+
const method = typeof call.arguments.method === 'string' ? call.arguments.method : undefined;
|
|
78
|
+
if (operation.kind === 'graphql') {
|
|
79
|
+
const data = await mapGithubError(()=>addCommentToPendingReview(client, operation.parameters));
|
|
80
|
+
return data === undefined ? githubToolError(NO_PENDING_REVIEW_MESSAGE) : githubToolResult(tool.id, data);
|
|
81
|
+
}
|
|
82
|
+
const operationParameters = await mapGithubError(()=>resolvePendingReviewParameters(client, operation.parameters, tool.id, method));
|
|
83
|
+
if (operationParameters === undefined) {
|
|
84
|
+
return githubToolError(NO_PENDING_REVIEW_MESSAGE);
|
|
48
85
|
}
|
|
86
|
+
const response = await mapGithubError(()=>client.request(operation.route, operationParameters));
|
|
87
|
+
return githubToolResult(tool.id, response.data, response, operationParameters, operation.route);
|
|
49
88
|
}
|
|
50
89
|
};
|
|
51
90
|
}
|
|
@@ -59,7 +98,26 @@ function createOctokitClient(token) {
|
|
|
59
98
|
}
|
|
60
99
|
});
|
|
61
100
|
return {
|
|
62
|
-
request: async (route, parameters)=>
|
|
101
|
+
request: async (route, parameters)=>{
|
|
102
|
+
if (route !== GITHUB_ARTIFACT_DOWNLOAD_ROUTE) {
|
|
103
|
+
return await octokit.request(route, parameters);
|
|
104
|
+
}
|
|
105
|
+
const abortController = new AbortController();
|
|
106
|
+
const timeout = setTimeout(()=>abortController.abort(), GITHUB_ARTIFACT_DOWNLOAD_TIMEOUT_MS);
|
|
107
|
+
try {
|
|
108
|
+
return await octokit.request(route, {
|
|
109
|
+
...parameters,
|
|
110
|
+
request: {
|
|
111
|
+
redirect: 'manual',
|
|
112
|
+
parseSuccessResponseBody: false,
|
|
113
|
+
signal: abortController.signal
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
} finally{
|
|
117
|
+
clearTimeout(timeout);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
graphql: async (query, variables)=>await octokit.graphql(query, variables)
|
|
63
121
|
};
|
|
64
122
|
}
|
|
65
123
|
function resolveGithubOperation(tool, call) {
|
|
@@ -74,10 +132,11 @@ function resolveGithubOperation(tool, call) {
|
|
|
74
132
|
const route = githubOperationRoute(toolId, method, params);
|
|
75
133
|
return route === undefined ? undefined : {
|
|
76
134
|
route,
|
|
77
|
-
parameters: projectGithubOperationParameters(toolId, method, params)
|
|
135
|
+
parameters: projectGithubOperationParameters(toolId, method, params),
|
|
136
|
+
kind: route === GITHUB_GRAPHQL_ROUTE ? 'graphql' : 'rest'
|
|
78
137
|
};
|
|
79
138
|
}
|
|
80
|
-
function githubOperationRoute(toolId, method, args) {
|
|
139
|
+
export function githubOperationRoute(toolId, method, args) {
|
|
81
140
|
const owner = '{owner}';
|
|
82
141
|
const repo = '{repo}';
|
|
83
142
|
const issue = '{issue_number}';
|
|
@@ -114,7 +173,7 @@ function githubOperationRoute(toolId, method, args) {
|
|
|
114
173
|
case 'sub_issue_write.remove':
|
|
115
174
|
return `DELETE ${repoPath}/issues/${issue}/sub_issues/{sub_issue_id}`;
|
|
116
175
|
case 'sub_issue_write.reprioritize':
|
|
117
|
-
return `PATCH ${repoPath}/issues/${issue}/sub_issues/
|
|
176
|
+
return `PATCH ${repoPath}/issues/${issue}/sub_issues/priority`;
|
|
118
177
|
case 'pull_request_read.get':
|
|
119
178
|
return `GET ${repoPath}/pulls/${pull}`;
|
|
120
179
|
case 'pull_request_read.get_diff':
|
|
@@ -142,7 +201,7 @@ function githubOperationRoute(toolId, method, args) {
|
|
|
142
201
|
case 'update_pull_request.':
|
|
143
202
|
return `PATCH ${repoPath}/pulls/${pull}`;
|
|
144
203
|
case 'add_reply_to_pull_request_comment.':
|
|
145
|
-
return `POST ${repoPath}/pulls/{comment_id}/replies`;
|
|
204
|
+
return args.reaction !== undefined && args.body === undefined ? `POST ${repoPath}/pulls/comments/{comment_id}/reactions` : `POST ${repoPath}/pulls/${pull}/comments/{comment_id}/replies`;
|
|
146
205
|
case 'merge_pull_request.':
|
|
147
206
|
return `PUT ${repoPath}/pulls/${pull}/merge`;
|
|
148
207
|
case 'update_pull_request_branch.':
|
|
@@ -154,7 +213,7 @@ function githubOperationRoute(toolId, method, args) {
|
|
|
154
213
|
case 'pull_request_review_write.delete_pending':
|
|
155
214
|
return `DELETE ${repoPath}/pulls/${pull}/reviews/{review_id}`;
|
|
156
215
|
case 'add_comment_to_pending_review.':
|
|
157
|
-
return
|
|
216
|
+
return GITHUB_GRAPHQL_ROUTE;
|
|
158
217
|
case 'actions_list.list_workflows':
|
|
159
218
|
return `GET ${repoPath}/actions/workflows`;
|
|
160
219
|
case 'actions_list.list_workflow_runs':
|
|
@@ -170,7 +229,7 @@ function githubOperationRoute(toolId, method, args) {
|
|
|
170
229
|
case 'actions_get.get_workflow_job':
|
|
171
230
|
return `GET ${repoPath}/actions/jobs/${resource}`;
|
|
172
231
|
case 'actions_get.download_workflow_run_artifact':
|
|
173
|
-
return
|
|
232
|
+
return GITHUB_ARTIFACT_DOWNLOAD_ROUTE;
|
|
174
233
|
case 'actions_get.get_workflow_run_usage':
|
|
175
234
|
return `GET ${repoPath}/actions/runs/${resource}/timing`;
|
|
176
235
|
case 'actions_get.get_workflow_run_logs_url':
|
|
@@ -191,7 +250,54 @@ function githubOperationRoute(toolId, method, args) {
|
|
|
191
250
|
return undefined;
|
|
192
251
|
}
|
|
193
252
|
}
|
|
194
|
-
function
|
|
253
|
+
async function addCommentToPendingReview(client, args) {
|
|
254
|
+
if (client.graphql === undefined) {
|
|
255
|
+
throw new GithubIntegrationProviderError('malformed-provider-response', 'GitHub client does not support GraphQL operations');
|
|
256
|
+
}
|
|
257
|
+
const reviewLookup = await client.graphql(LATEST_PENDING_REVIEW_QUERY, {
|
|
258
|
+
owner: args.owner,
|
|
259
|
+
repo: args.repo,
|
|
260
|
+
pullNumber: args.pull_number
|
|
261
|
+
});
|
|
262
|
+
const reviewId = latestPendingReviewNodeId(reviewLookup);
|
|
263
|
+
if (reviewId === undefined) return undefined;
|
|
264
|
+
const input = {
|
|
265
|
+
pullRequestReviewId: reviewId,
|
|
266
|
+
path: args.path,
|
|
267
|
+
body: args.body,
|
|
268
|
+
subjectType: args.subject_type
|
|
269
|
+
};
|
|
270
|
+
if (args.line !== undefined) input.line = args.line;
|
|
271
|
+
if (args.side !== undefined) input.side = args.side;
|
|
272
|
+
if (args.start_line !== undefined) input.startLine = args.start_line;
|
|
273
|
+
if (args.start_side !== undefined) input.startSide = args.start_side;
|
|
274
|
+
return await client.graphql(ADD_PENDING_REVIEW_COMMENT_MUTATION, {
|
|
275
|
+
input
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
function latestPendingReviewNodeId(data) {
|
|
279
|
+
if (!isRecord(data)) return undefined;
|
|
280
|
+
const viewer = isRecord(data.viewer) ? data.viewer.login : undefined;
|
|
281
|
+
if (typeof viewer !== 'string') return undefined;
|
|
282
|
+
const repository = isRecord(data.repository) ? data.repository : undefined;
|
|
283
|
+
const pullRequest = repository && isRecord(repository.pullRequest) ? repository.pullRequest : undefined;
|
|
284
|
+
const reviews = pullRequest && isRecord(pullRequest.reviews) ? pullRequest.reviews : undefined;
|
|
285
|
+
const nodes = reviews && Array.isArray(reviews.nodes) ? reviews.nodes : [];
|
|
286
|
+
let latest;
|
|
287
|
+
for (const node of nodes){
|
|
288
|
+
if (!isRecord(node)) continue;
|
|
289
|
+
const author = isRecord(node.author) ? node.author.login : undefined;
|
|
290
|
+
const id = node.id;
|
|
291
|
+
const createdAt = node.createdAt;
|
|
292
|
+
if (author !== viewer || typeof id !== 'string' || typeof createdAt !== 'string') continue;
|
|
293
|
+
if (latest === undefined || createdAt > latest.createdAt) latest = {
|
|
294
|
+
createdAt,
|
|
295
|
+
id
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
return latest?.id;
|
|
299
|
+
}
|
|
300
|
+
export function projectGithubOperationParameters(toolId, method, args) {
|
|
195
301
|
const parameters = {
|
|
196
302
|
...args
|
|
197
303
|
};
|
|
@@ -207,8 +313,48 @@ function projectGithubOperationParameters(toolId, method, args) {
|
|
|
207
313
|
}
|
|
208
314
|
return parameters;
|
|
209
315
|
}
|
|
210
|
-
function
|
|
211
|
-
|
|
316
|
+
async function resolvePendingReviewParameters(client, parameters, toolId, method) {
|
|
317
|
+
if (!isPendingReviewOperation(toolId, method)) return parameters;
|
|
318
|
+
const reviewId = await latestPendingReviewId(client, parameters);
|
|
319
|
+
return reviewId === undefined ? undefined : {
|
|
320
|
+
...parameters,
|
|
321
|
+
review_id: reviewId
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function isPendingReviewOperation(toolId, method) {
|
|
325
|
+
return toolId === 'pull_request_review_write' && (method === 'submit_pending' || method === 'delete_pending');
|
|
326
|
+
}
|
|
327
|
+
async function latestPendingReviewId(client, parameters) {
|
|
328
|
+
const perPage = 100;
|
|
329
|
+
let page = 1;
|
|
330
|
+
let reviewId;
|
|
331
|
+
while(true){
|
|
332
|
+
const response = await client.request('GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews', {
|
|
333
|
+
owner: parameters.owner,
|
|
334
|
+
repo: parameters.repo,
|
|
335
|
+
pull_number: parameters.pull_number,
|
|
336
|
+
per_page: perPage,
|
|
337
|
+
page
|
|
338
|
+
});
|
|
339
|
+
if (!Array.isArray(response.data)) return undefined;
|
|
340
|
+
reviewId = latestPendingReviewIdOnPage(response.data) ?? reviewId;
|
|
341
|
+
if (response.data.length < perPage) return reviewId;
|
|
342
|
+
page += 1;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function latestPendingReviewIdOnPage(data) {
|
|
346
|
+
for(let index = data.length - 1; index >= 0; index -= 1){
|
|
347
|
+
const review = data[index];
|
|
348
|
+
if (!isRecord(review) || review.state !== 'PENDING') continue;
|
|
349
|
+
if (typeof review.id === 'number' && Number.isSafeInteger(review.id)) return review.id;
|
|
350
|
+
}
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
function githubToolResult(toolId, data, response, parameters, route) {
|
|
354
|
+
const structuredContent = projectGithubToolOutput(toolId, data, response, parameters, route);
|
|
355
|
+
if (structuredContent === undefined) {
|
|
356
|
+
return githubToolError('GitHub artifact download did not return a download URL');
|
|
357
|
+
}
|
|
212
358
|
return {
|
|
213
359
|
content: [
|
|
214
360
|
{
|
|
@@ -219,7 +365,10 @@ function githubToolResult(toolId, data) {
|
|
|
219
365
|
structuredContent
|
|
220
366
|
};
|
|
221
367
|
}
|
|
222
|
-
function projectGithubToolOutput(toolId, data) {
|
|
368
|
+
function projectGithubToolOutput(toolId, data, response, parameters, route) {
|
|
369
|
+
if (route === GITHUB_ARTIFACT_DOWNLOAD_ROUTE) {
|
|
370
|
+
return projectGithubArtifactDownloadOutput(response, parameters);
|
|
371
|
+
}
|
|
223
372
|
switch(toolId){
|
|
224
373
|
case 'list_issue_types':
|
|
225
374
|
return {
|
|
@@ -256,6 +405,22 @@ function projectGithubToolOutput(toolId, data) {
|
|
|
256
405
|
};
|
|
257
406
|
}
|
|
258
407
|
}
|
|
408
|
+
function projectGithubArtifactDownloadOutput(response, parameters) {
|
|
409
|
+
if (response === undefined) return undefined;
|
|
410
|
+
const downloadUrl = response.headers?.location;
|
|
411
|
+
if (typeof downloadUrl !== 'string' || downloadUrl.length === 0) return undefined;
|
|
412
|
+
const output = {
|
|
413
|
+
archive_format: GITHUB_ARTIFACT_ARCHIVE_FORMAT,
|
|
414
|
+
download_url: downloadUrl
|
|
415
|
+
};
|
|
416
|
+
if (typeof parameters?.resource_id === 'string') output.artifact_id = parameters.resource_id;
|
|
417
|
+
const contentType = response.headers?.['content-type'];
|
|
418
|
+
if (typeof contentType === 'string') output.content_type = contentType;
|
|
419
|
+
const contentLength = response.headers?.['content-length'];
|
|
420
|
+
const sizeBytes = typeof contentLength === 'number' ? contentLength : Number(contentLength);
|
|
421
|
+
if (Number.isSafeInteger(sizeBytes) && sizeBytes >= 0) output.size_bytes = sizeBytes;
|
|
422
|
+
return output;
|
|
423
|
+
}
|
|
259
424
|
function githubSearchItems(data) {
|
|
260
425
|
return isRecord(data) ? data.items : data;
|
|
261
426
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/agent-tools.ts"],"sourcesContent":["import type {\n AgentToolCallInput,\n AgentToolCatalogEntry,\n AgentToolSelectionCatalog,\n AgentToolSession,\n AgentToolsProvider,\n IntegrationConnection,\n OpenAgentToolsSessionInput,\n} from '@shipfox/api-integration-spi';\nimport {Octokit} from 'octokit';\nimport {\n createGithubInstallationTokenProvider,\n type GithubInstallationTokenProvider,\n} from '#api/installation-token-provider.js';\nimport {normalizedGithubApiBaseUrl} from '#config.js';\nimport type {GithubInstallation} from '#db/installations.js';\nimport {GithubIntegrationProviderError} from './errors.js';\nimport {\n type GithubAgentToolCatalogEntry,\n type GithubAgentToolId,\n type GithubAgentToolRequiredScope,\n githubAgentToolCatalog,\n githubAgentToolSelectionCatalog,\n} from './github-agent-tool-catalog.js';\n\nexport type {\n GithubAgentToolCatalogEntry,\n GithubAgentToolCategory,\n GithubAgentToolId,\n GithubAgentToolPermission,\n GithubAgentToolPermissionAccess,\n GithubAgentToolRequiredPermission,\n GithubAgentToolRequiredScope,\n GithubAgentToolSensitivity,\n} from './github-agent-tool-catalog.js';\nexport {\n buildGithubAgentToolSelectionCatalog,\n DEFAULT_JOB_LOG_TAIL_LINES,\n githubAgentToolCatalog,\n githubAgentToolSelectionCatalog,\n} from './github-agent-tool-catalog.js';\n\ntype GithubIntegrationConnection = IntegrationConnection<'github'>;\n\ntype GithubToolCallResult = {\n isError?: boolean | undefined;\n content: readonly {type: 'text'; text: string}[];\n structuredContent?: Record<string, unknown> | undefined;\n};\n\nexport class GithubAgentToolsProvider\n implements\n AgentToolsProvider<\n GithubIntegrationConnection,\n GithubAgentToolRequiredScope,\n unknown,\n GithubToolCallResult\n >\n{\n private readonly tokenProvider: GithubInstallationTokenProvider;\n\n constructor(private readonly options: GithubAgentToolsProviderOptions = {}) {\n this.tokenProvider = options.tokenProvider ?? createGithubInstallationTokenProvider();\n }\n\n catalog(): readonly GithubAgentToolCatalogEntry[] {\n return githubAgentToolCatalog;\n }\n\n selectionCatalog(): AgentToolSelectionCatalog {\n return githubAgentToolSelectionCatalog;\n }\n\n async openSession(\n input: OpenAgentToolsSessionInput<GithubIntegrationConnection, GithubAgentToolRequiredScope>,\n ): Promise<AgentToolSession<GithubToolCallResult>> {\n const installation = await this.options.getInstallationByConnectionId?.(input.connection.id);\n if (!installation) {\n throw new GithubIntegrationProviderError(\n 'installation-not-found',\n 'GitHub installation is not connected to this integration',\n );\n }\n const installationId = Number(installation.installationId);\n if (!Number.isSafeInteger(installationId) || installationId < 1) {\n throw new GithubIntegrationProviderError(\n 'malformed-provider-response',\n 'GitHub installation has an invalid installation ID',\n );\n }\n let tokenPromise:\n | ReturnType<GithubInstallationTokenProvider['getInstallationAccessToken']>\n | undefined;\n\n return {\n call: async (call) => {\n const tool = input.tools.find((candidate) => candidate.id === call.toolId);\n if (!tool) return githubToolError(`Unknown GitHub tool: ${call.toolId}`);\n const operation = resolveGithubOperation(tool, call);\n if (operation === undefined) return githubToolError('Unknown GitHub tool operation');\n const validationError = validateGithubToolArguments(tool, call.arguments);\n if (validationError) return githubToolError(validationError);\n tokenPromise ??= this.tokenProvider.getInstallationAccessToken(installationId);\n const token = await tokenPromise;\n if (!hasGrantedPermissions(token.permissions ?? {}, tool, call)) {\n return githubToolError(\n 'GitHub installation token is missing permission for this operation',\n );\n }\n const client = (this.options.createClient ?? createOctokitClient)(token.token);\n\n try {\n const response = await client.request(operation.route, operation.parameters);\n return githubToolResult(tool.id as GithubAgentToolId, response.data);\n } catch (error) {\n if (error instanceof GithubIntegrationProviderError)\n return githubToolError(error.message);\n throw error;\n }\n },\n };\n }\n}\n\nexport interface GithubAgentToolsProviderOptions {\n getInstallationByConnectionId?:\n | ((connectionId: string) => Promise<GithubInstallation | undefined>)\n | undefined;\n tokenProvider?: GithubInstallationTokenProvider | undefined;\n createClient?: GithubToolClientFactory | undefined;\n}\n\nexport interface GithubToolClient {\n request(route: string, parameters: Record<string, unknown>): Promise<{data: unknown}>;\n}\n\nexport type GithubToolClientFactory = (token: string) => GithubToolClient;\n\ninterface GithubToolOperation {\n route: string;\n parameters: Record<string, unknown>;\n}\n\nfunction createOctokitClient(token: string): GithubToolClient {\n const octokit = new Octokit({\n auth: token,\n baseUrl: normalizedGithubApiBaseUrl(),\n retry: {enabled: false},\n });\n return {\n request: async (route, parameters) => await octokit.request(route, parameters),\n };\n}\n\nfunction resolveGithubOperation(\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n call: AgentToolCallInput,\n): GithubToolOperation | undefined {\n const args = call.arguments;\n const method = typeof args.method === 'string' ? args.method : undefined;\n const params = {...args};\n delete params.method;\n\n if (tool.methods && !tool.methods.some((candidate) => candidate.id === method)) return undefined;\n\n const toolId = tool.id as GithubAgentToolId;\n const route = githubOperationRoute(toolId, method, params);\n return route === undefined\n ? undefined\n : {route, parameters: projectGithubOperationParameters(toolId, method, params)};\n}\n\nfunction githubOperationRoute(\n toolId: GithubAgentToolId,\n method: string | undefined,\n args: Record<string, unknown>,\n): string | undefined {\n const owner = '{owner}';\n const repo = '{repo}';\n const issue = '{issue_number}';\n const pull = '{pull_number}';\n const run = '{run_id}';\n const resource = '{resource_id}';\n const repoPath = `/repos/${owner}/${repo}`;\n\n switch (`${toolId}.${method ?? ''}`) {\n case 'issue_read.get':\n return `GET ${repoPath}/issues/${issue}`;\n case 'issue_read.get_comments':\n return `GET ${repoPath}/issues/${issue}/comments`;\n case 'issue_read.get_sub_issues':\n return `GET ${repoPath}/issues/${issue}/sub_issues`;\n case 'issue_read.get_parent':\n return `GET ${repoPath}/issues/${issue}/parent`;\n case 'issue_read.get_labels':\n return `GET ${repoPath}/issues/${issue}/labels`;\n case 'list_issue_types.':\n return args.repo === undefined\n ? 'GET /orgs/{owner}/issue-types'\n : `GET ${repoPath}/issue-types`;\n case 'list_issues.':\n return `GET ${repoPath}/issues`;\n case 'search_issues.':\n return 'GET /search/issues';\n case 'add_issue_comment.':\n if (args.comment_id !== undefined)\n return `POST ${repoPath}/issues/comments/{comment_id}/reactions`;\n return args.reaction !== undefined && args.body === undefined\n ? `POST ${repoPath}/issues/${issue}/reactions`\n : `POST ${repoPath}/issues/${issue}/comments`;\n case 'issue_write.create':\n return `POST ${repoPath}/issues`;\n case 'issue_write.update':\n return `PATCH ${repoPath}/issues/${issue}`;\n case 'sub_issue_write.add':\n return `POST ${repoPath}/issues/${issue}/sub_issues`;\n case 'sub_issue_write.remove':\n return `DELETE ${repoPath}/issues/${issue}/sub_issues/{sub_issue_id}`;\n case 'sub_issue_write.reprioritize':\n return `PATCH ${repoPath}/issues/${issue}/sub_issues/{sub_issue_id}`;\n case 'pull_request_read.get':\n return `GET ${repoPath}/pulls/${pull}`;\n case 'pull_request_read.get_diff':\n return `GET ${repoPath}/pulls/${pull}`;\n case 'pull_request_read.get_status':\n return `GET ${repoPath}/commits/{ref}/status`;\n case 'pull_request_read.get_files':\n return `GET ${repoPath}/pulls/${pull}/files`;\n case 'pull_request_read.get_commits':\n return `GET ${repoPath}/pulls/${pull}/commits`;\n case 'pull_request_read.get_review_comments':\n return `GET ${repoPath}/pulls/${pull}/comments`;\n case 'pull_request_read.get_reviews':\n return `GET ${repoPath}/pulls/${pull}/reviews`;\n case 'pull_request_read.get_comments':\n return `GET ${repoPath}/issues/${pull}/comments`;\n case 'pull_request_read.get_check_runs':\n return `GET ${repoPath}/commits/{ref}/check-runs`;\n case 'list_pull_requests.':\n return `GET ${repoPath}/pulls`;\n case 'search_pull_requests.':\n return 'GET /search/issues';\n case 'create_pull_request.':\n return `POST ${repoPath}/pulls`;\n case 'update_pull_request.':\n return `PATCH ${repoPath}/pulls/${pull}`;\n case 'add_reply_to_pull_request_comment.':\n return `POST ${repoPath}/pulls/{comment_id}/replies`;\n case 'merge_pull_request.':\n return `PUT ${repoPath}/pulls/${pull}/merge`;\n case 'update_pull_request_branch.':\n return `PUT ${repoPath}/pulls/${pull}/update-branch`;\n case 'pull_request_review_write.create':\n return `POST ${repoPath}/pulls/${pull}/reviews`;\n case 'pull_request_review_write.submit_pending':\n return `POST ${repoPath}/pulls/${pull}/reviews/{review_id}/events`;\n case 'pull_request_review_write.delete_pending':\n return `DELETE ${repoPath}/pulls/${pull}/reviews/{review_id}`;\n case 'add_comment_to_pending_review.':\n return `POST ${repoPath}/pulls/${pull}/comments`;\n case 'actions_list.list_workflows':\n return `GET ${repoPath}/actions/workflows`;\n case 'actions_list.list_workflow_runs':\n return `GET ${repoPath}/actions/workflows/${resource}/runs`;\n case 'actions_list.list_workflow_jobs':\n return `GET ${repoPath}/actions/runs/${resource}/jobs`;\n case 'actions_list.list_workflow_run_artifacts':\n return `GET ${repoPath}/actions/runs/${resource}/artifacts`;\n case 'actions_get.get_workflow':\n return `GET ${repoPath}/actions/workflows/${resource}`;\n case 'actions_get.get_workflow_run':\n return `GET ${repoPath}/actions/runs/${resource}`;\n case 'actions_get.get_workflow_job':\n return `GET ${repoPath}/actions/jobs/${resource}`;\n case 'actions_get.download_workflow_run_artifact':\n return `GET ${repoPath}/actions/artifacts/${resource}/{archive_format}`;\n case 'actions_get.get_workflow_run_usage':\n return `GET ${repoPath}/actions/runs/${resource}/timing`;\n case 'actions_get.get_workflow_run_logs_url':\n return `GET ${repoPath}/actions/runs/${resource}/logs`;\n case 'actions_run_trigger.run_workflow':\n return `POST ${repoPath}/actions/workflows/{workflow_id}/dispatches`;\n case 'actions_run_trigger.rerun_workflow_run':\n return `POST ${repoPath}/actions/runs/${run}/rerun`;\n case 'actions_run_trigger.rerun_failed_jobs':\n return `POST ${repoPath}/actions/runs/${run}/rerun-failed-jobs`;\n case 'actions_run_trigger.cancel_workflow_run':\n return `POST ${repoPath}/actions/runs/${run}/cancel`;\n case 'actions_run_trigger.delete_workflow_run_logs':\n return `DELETE ${repoPath}/actions/runs/${run}/logs`;\n case 'get_job_logs.':\n return `GET ${repoPath}/actions/jobs/{job_id}/logs`;\n default:\n return undefined;\n }\n}\n\nfunction projectGithubOperationParameters(\n toolId: GithubAgentToolId,\n method: string | undefined,\n args: Record<string, unknown>,\n): Record<string, unknown> {\n const parameters = {...args};\n if (toolId === 'add_issue_comment' && parameters.reaction !== undefined) {\n parameters.content = parameters.reaction;\n delete parameters.reaction;\n if (parameters.body === undefined) delete parameters.body;\n }\n if (toolId === 'pull_request_read' && method === 'get_diff') {\n parameters.headers = {accept: 'application/vnd.github.diff'};\n }\n return parameters;\n}\n\nfunction githubToolResult(toolId: GithubAgentToolId, data: unknown): GithubToolCallResult {\n const structuredContent = projectGithubToolOutput(toolId, data);\n return {\n content: [{type: 'text', text: JSON.stringify(structuredContent)}],\n structuredContent,\n };\n}\n\nfunction projectGithubToolOutput(\n toolId: GithubAgentToolId,\n data: unknown,\n): Record<string, unknown> {\n switch (toolId) {\n case 'list_issue_types':\n return {issue_types: data};\n case 'list_issues':\n return {issues: data};\n case 'search_issues':\n return {issues: githubSearchItems(data)};\n case 'list_pull_requests':\n return {pull_requests: data};\n case 'search_pull_requests':\n return {pull_requests: githubSearchItems(data)};\n case 'create_pull_request':\n case 'update_pull_request':\n return {pull_request: data};\n case 'merge_pull_request':\n return {merge: data};\n default:\n return isRecord(data) ? data : {result: data};\n }\n}\n\nfunction githubSearchItems(data: unknown): unknown {\n return isRecord(data) ? data.items : data;\n}\n\nfunction githubToolError(message: string): GithubToolCallResult {\n return {isError: true, content: [{type: 'text', text: message}]};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction validateGithubToolArguments(\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n arguments_: Record<string, unknown>,\n): string | undefined {\n const required = Array.isArray(tool.inputSchema.required) ? tool.inputSchema.required : [];\n for (const name of required) {\n if (typeof name === 'string' && arguments_[name] === undefined) {\n return `Missing required parameter: ${name}`;\n }\n }\n\n const methodRequired = methodRequiredParameters(tool.inputSchema, arguments_);\n for (const name of methodRequired) {\n if (arguments_[name] === undefined) return `Missing required parameter: ${name}`;\n }\n\n const properties = tool.inputSchema.properties;\n if (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n return undefined;\n }\n const propertySchemas = properties as Record<string, unknown>;\n for (const [name, value] of Object.entries(arguments_)) {\n const schema = propertySchemas[name];\n if (typeof schema !== 'object' || schema === null || Array.isArray(schema)) continue;\n const type = (schema as {type?: unknown}).type;\n if (type === 'integer' && (!Number.isInteger(value) || typeof value !== 'number')) {\n return `Parameter ${name} must be an integer`;\n }\n if (type === 'array' && !Array.isArray(value)) return `Parameter ${name} must be an array`;\n }\n return undefined;\n}\n\nfunction methodRequiredParameters(\n inputSchema: AgentToolCatalogEntry<GithubAgentToolRequiredScope>['inputSchema'],\n arguments_: Record<string, unknown>,\n): string[] {\n const method = arguments_.method;\n if (typeof method !== 'string' || !Array.isArray(inputSchema.oneOf)) return [];\n\n for (const candidate of inputSchema.oneOf) {\n if (!isRecord(candidate) || !isRecord(candidate.properties)) continue;\n const methodSchema = candidate.properties.method;\n if (!isRecord(methodSchema) || methodSchema.const !== method) continue;\n return Array.isArray(candidate.required)\n ? candidate.required.filter((name): name is string => typeof name === 'string')\n : [];\n }\n\n return [];\n}\n\nfunction hasGrantedPermissions(\n granted: Record<string, 'read' | 'write' | 'admin'>,\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n call: AgentToolCallInput,\n): boolean {\n const method = typeof call.arguments.method === 'string' ? call.arguments.method : undefined;\n const required =\n tool.methods?.find((candidate) => candidate.id === method)?.requiredScope ?? tool.requiredScope;\n return required.every(({permission, access}) => {\n const actual = granted[permission];\n return actual === 'write' || actual === 'admin' || actual === access;\n });\n}\n"],"names":["Octokit","createGithubInstallationTokenProvider","normalizedGithubApiBaseUrl","GithubIntegrationProviderError","githubAgentToolCatalog","githubAgentToolSelectionCatalog","buildGithubAgentToolSelectionCatalog","DEFAULT_JOB_LOG_TAIL_LINES","GithubAgentToolsProvider","options","tokenProvider","catalog","selectionCatalog","openSession","input","installation","getInstallationByConnectionId","connection","id","installationId","Number","isSafeInteger","tokenPromise","call","tool","tools","find","candidate","toolId","githubToolError","operation","resolveGithubOperation","undefined","validationError","validateGithubToolArguments","arguments","getInstallationAccessToken","token","hasGrantedPermissions","permissions","client","createClient","createOctokitClient","response","request","route","parameters","githubToolResult","data","error","message","octokit","auth","baseUrl","retry","enabled","args","method","params","methods","some","githubOperationRoute","projectGithubOperationParameters","owner","repo","issue","pull","run","resource","repoPath","comment_id","reaction","body","content","headers","accept","structuredContent","projectGithubToolOutput","type","text","JSON","stringify","issue_types","issues","githubSearchItems","pull_requests","pull_request","merge","isRecord","result","items","isError","value","Array","isArray","arguments_","required","inputSchema","name","methodRequired","methodRequiredParameters","properties","propertySchemas","Object","entries","schema","isInteger","oneOf","methodSchema","const","filter","granted","requiredScope","every","permission","access","actual"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/agent-tools.ts"],"sourcesContent":["import type {\n AgentToolCallInput,\n AgentToolCatalogEntry,\n AgentToolSelectionCatalog,\n AgentToolSession,\n AgentToolsProvider,\n IntegrationConnection,\n OpenAgentToolsSessionInput,\n} from '@shipfox/api-integration-spi';\nimport {Octokit} from 'octokit';\nimport {mapGithubError} from '#api/client.js';\nimport {\n createGithubInstallationTokenProvider,\n type GithubInstallationTokenProvider,\n} from '#api/installation-token-provider.js';\nimport {normalizedGithubApiBaseUrl} from '#config.js';\nimport type {GithubInstallation} from '#db/installations.js';\nimport {GithubIntegrationProviderError} from './errors.js';\nimport {\n type GithubAgentToolCatalogEntry,\n type GithubAgentToolId,\n type GithubAgentToolRequiredScope,\n githubAgentToolCatalog,\n githubAgentToolSelectionCatalog,\n} from './github-agent-tool-catalog.js';\n\nexport type {\n GithubAgentToolCatalogEntry,\n GithubAgentToolCategory,\n GithubAgentToolId,\n GithubAgentToolPermission,\n GithubAgentToolPermissionAccess,\n GithubAgentToolRequiredPermission,\n GithubAgentToolRequiredScope,\n GithubAgentToolSensitivity,\n} from './github-agent-tool-catalog.js';\nexport {\n buildGithubAgentToolSelectionCatalog,\n DEFAULT_JOB_LOG_TAIL_LINES,\n githubAgentToolCatalog,\n githubAgentToolSelectionCatalog,\n} from './github-agent-tool-catalog.js';\n\ntype GithubIntegrationConnection = IntegrationConnection<'github'>;\n\ntype GithubToolCallResult = {\n isError?: boolean | undefined;\n content: readonly {type: 'text'; text: string}[];\n structuredContent?: Record<string, unknown> | undefined;\n};\n\nconst GITHUB_GRAPHQL_ROUTE = 'POST /graphql';\nconst GITHUB_ARTIFACT_ARCHIVE_FORMAT = 'zip';\nconst GITHUB_ARTIFACT_DOWNLOAD_ROUTE = `GET /repos/{owner}/{repo}/actions/artifacts/{resource_id}/${GITHUB_ARTIFACT_ARCHIVE_FORMAT}`;\nconst GITHUB_ARTIFACT_DOWNLOAD_TIMEOUT_MS = 30_000;\nconst NO_PENDING_REVIEW_MESSAGE =\n 'No pending pull request review found for the authenticated GitHub user.';\n\nconst LATEST_PENDING_REVIEW_QUERY = `\n query LatestPendingPullRequestReview($owner: String!, $repo: String!, $pullNumber: Int!) {\n viewer {\n login\n }\n repository(owner: $owner, name: $repo) {\n pullRequest(number: $pullNumber) {\n reviews(last: 100, states: [PENDING]) {\n nodes {\n id\n author {\n login\n }\n createdAt\n }\n }\n }\n }\n }\n`;\n\nconst ADD_PENDING_REVIEW_COMMENT_MUTATION = `\n mutation AddCommentToPendingReview($input: AddPullRequestReviewThreadInput!) {\n addPullRequestReviewThread(input: $input) {\n thread {\n id\n }\n }\n }\n`;\n\nexport class GithubAgentToolsProvider\n implements\n AgentToolsProvider<\n GithubIntegrationConnection,\n GithubAgentToolRequiredScope,\n unknown,\n GithubToolCallResult\n >\n{\n private readonly tokenProvider: GithubInstallationTokenProvider;\n\n constructor(private readonly options: GithubAgentToolsProviderOptions = {}) {\n this.tokenProvider = options.tokenProvider ?? createGithubInstallationTokenProvider();\n }\n\n catalog(): readonly GithubAgentToolCatalogEntry[] {\n return githubAgentToolCatalog;\n }\n\n selectionCatalog(): AgentToolSelectionCatalog {\n return githubAgentToolSelectionCatalog;\n }\n\n async openSession(\n input: OpenAgentToolsSessionInput<GithubIntegrationConnection, GithubAgentToolRequiredScope>,\n ): Promise<AgentToolSession<GithubToolCallResult>> {\n const installation = await this.options.getInstallationByConnectionId?.(input.connection.id);\n if (!installation) {\n throw new GithubIntegrationProviderError(\n 'installation-not-found',\n 'GitHub installation is not connected to this integration',\n );\n }\n const installationId = Number(installation.installationId);\n if (!Number.isSafeInteger(installationId) || installationId < 1) {\n throw new GithubIntegrationProviderError(\n 'malformed-provider-response',\n 'GitHub installation has an invalid installation ID',\n );\n }\n let tokenPromise:\n | ReturnType<GithubInstallationTokenProvider['getInstallationAccessToken']>\n | undefined;\n\n return {\n call: async (call) => {\n const tool = input.tools.find((candidate) => candidate.id === call.toolId);\n if (!tool) return githubToolError(`Unknown GitHub tool: ${call.toolId}`);\n const operation = resolveGithubOperation(tool, call);\n if (operation === undefined) return githubToolError('Unknown GitHub tool operation');\n const validationError = validateGithubToolArguments(tool, call.arguments);\n if (validationError) return githubToolError(validationError);\n tokenPromise ??= this.tokenProvider.getInstallationAccessToken(installationId);\n const token = await tokenPromise;\n if (!hasGrantedPermissions(token.permissions ?? {}, tool, call)) {\n return githubToolError(\n 'GitHub installation token is missing permission for this operation',\n );\n }\n const client = (this.options.createClient ?? createOctokitClient)(token.token);\n const method =\n typeof call.arguments.method === 'string' ? call.arguments.method : undefined;\n\n if (operation.kind === 'graphql') {\n const data = await mapGithubError(() =>\n addCommentToPendingReview(client, operation.parameters),\n );\n return data === undefined\n ? githubToolError(NO_PENDING_REVIEW_MESSAGE)\n : githubToolResult(tool.id as GithubAgentToolId, data);\n }\n\n const operationParameters = await mapGithubError(() =>\n resolvePendingReviewParameters(\n client,\n operation.parameters,\n tool.id as GithubAgentToolId,\n method,\n ),\n );\n if (operationParameters === undefined) {\n return githubToolError(NO_PENDING_REVIEW_MESSAGE);\n }\n const response = await mapGithubError(() =>\n client.request(operation.route, operationParameters),\n );\n return githubToolResult(\n tool.id as GithubAgentToolId,\n response.data,\n response,\n operationParameters,\n operation.route,\n );\n },\n };\n }\n}\n\nexport interface GithubAgentToolsProviderOptions {\n getInstallationByConnectionId?:\n | ((connectionId: string) => Promise<GithubInstallation | undefined>)\n | undefined;\n tokenProvider?: GithubInstallationTokenProvider | undefined;\n createClient?: GithubToolClientFactory | undefined;\n}\n\nexport interface GithubToolResponse {\n data: unknown;\n headers?: Record<string, string | number | undefined> | undefined;\n status?: number | undefined;\n url?: string | undefined;\n}\n\nexport interface GithubToolClient {\n request(route: string, parameters: Record<string, unknown>): Promise<GithubToolResponse>;\n graphql?: ((query: string, variables: Record<string, unknown>) => Promise<unknown>) | undefined;\n}\n\nexport type GithubToolClientFactory = (token: string) => GithubToolClient;\n\ninterface GithubToolOperation {\n route: string;\n parameters: Record<string, unknown>;\n kind: 'rest' | 'graphql';\n}\n\nfunction createOctokitClient(token: string): GithubToolClient {\n const octokit = new Octokit({\n auth: token,\n baseUrl: normalizedGithubApiBaseUrl(),\n retry: {enabled: false},\n });\n return {\n request: async (route, parameters) => {\n if (route !== GITHUB_ARTIFACT_DOWNLOAD_ROUTE) {\n return await octokit.request(route, parameters);\n }\n\n const abortController = new AbortController();\n const timeout = setTimeout(\n () => abortController.abort(),\n GITHUB_ARTIFACT_DOWNLOAD_TIMEOUT_MS,\n );\n try {\n return await octokit.request(route, {\n ...parameters,\n request: {\n redirect: 'manual',\n parseSuccessResponseBody: false,\n signal: abortController.signal,\n },\n });\n } finally {\n clearTimeout(timeout);\n }\n },\n graphql: async (query, variables) => await octokit.graphql(query, variables),\n };\n}\n\nfunction resolveGithubOperation(\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n call: AgentToolCallInput,\n): GithubToolOperation | undefined {\n const args = call.arguments;\n const method = typeof args.method === 'string' ? args.method : undefined;\n const params = {...args};\n delete params.method;\n\n if (tool.methods && !tool.methods.some((candidate) => candidate.id === method)) return undefined;\n\n const toolId = tool.id as GithubAgentToolId;\n const route = githubOperationRoute(toolId, method, params);\n return route === undefined\n ? undefined\n : {\n route,\n parameters: projectGithubOperationParameters(toolId, method, params),\n kind: route === GITHUB_GRAPHQL_ROUTE ? 'graphql' : 'rest',\n };\n}\n\nexport function githubOperationRoute(\n toolId: GithubAgentToolId,\n method: string | undefined,\n args: Record<string, unknown>,\n): string | undefined {\n const owner = '{owner}';\n const repo = '{repo}';\n const issue = '{issue_number}';\n const pull = '{pull_number}';\n const run = '{run_id}';\n const resource = '{resource_id}';\n const repoPath = `/repos/${owner}/${repo}`;\n\n switch (`${toolId}.${method ?? ''}`) {\n case 'issue_read.get':\n return `GET ${repoPath}/issues/${issue}`;\n case 'issue_read.get_comments':\n return `GET ${repoPath}/issues/${issue}/comments`;\n case 'issue_read.get_sub_issues':\n return `GET ${repoPath}/issues/${issue}/sub_issues`;\n case 'issue_read.get_parent':\n return `GET ${repoPath}/issues/${issue}/parent`;\n case 'issue_read.get_labels':\n return `GET ${repoPath}/issues/${issue}/labels`;\n case 'list_issue_types.':\n return args.repo === undefined\n ? 'GET /orgs/{owner}/issue-types'\n : `GET ${repoPath}/issue-types`;\n case 'list_issues.':\n return `GET ${repoPath}/issues`;\n case 'search_issues.':\n return 'GET /search/issues';\n case 'add_issue_comment.':\n if (args.comment_id !== undefined)\n return `POST ${repoPath}/issues/comments/{comment_id}/reactions`;\n return args.reaction !== undefined && args.body === undefined\n ? `POST ${repoPath}/issues/${issue}/reactions`\n : `POST ${repoPath}/issues/${issue}/comments`;\n case 'issue_write.create':\n return `POST ${repoPath}/issues`;\n case 'issue_write.update':\n return `PATCH ${repoPath}/issues/${issue}`;\n case 'sub_issue_write.add':\n return `POST ${repoPath}/issues/${issue}/sub_issues`;\n case 'sub_issue_write.remove':\n return `DELETE ${repoPath}/issues/${issue}/sub_issues/{sub_issue_id}`;\n case 'sub_issue_write.reprioritize':\n return `PATCH ${repoPath}/issues/${issue}/sub_issues/priority`;\n case 'pull_request_read.get':\n return `GET ${repoPath}/pulls/${pull}`;\n case 'pull_request_read.get_diff':\n return `GET ${repoPath}/pulls/${pull}`;\n case 'pull_request_read.get_status':\n return `GET ${repoPath}/commits/{ref}/status`;\n case 'pull_request_read.get_files':\n return `GET ${repoPath}/pulls/${pull}/files`;\n case 'pull_request_read.get_commits':\n return `GET ${repoPath}/pulls/${pull}/commits`;\n case 'pull_request_read.get_review_comments':\n return `GET ${repoPath}/pulls/${pull}/comments`;\n case 'pull_request_read.get_reviews':\n return `GET ${repoPath}/pulls/${pull}/reviews`;\n case 'pull_request_read.get_comments':\n return `GET ${repoPath}/issues/${pull}/comments`;\n case 'pull_request_read.get_check_runs':\n return `GET ${repoPath}/commits/{ref}/check-runs`;\n case 'list_pull_requests.':\n return `GET ${repoPath}/pulls`;\n case 'search_pull_requests.':\n return 'GET /search/issues';\n case 'create_pull_request.':\n return `POST ${repoPath}/pulls`;\n case 'update_pull_request.':\n return `PATCH ${repoPath}/pulls/${pull}`;\n case 'add_reply_to_pull_request_comment.':\n return args.reaction !== undefined && args.body === undefined\n ? `POST ${repoPath}/pulls/comments/{comment_id}/reactions`\n : `POST ${repoPath}/pulls/${pull}/comments/{comment_id}/replies`;\n case 'merge_pull_request.':\n return `PUT ${repoPath}/pulls/${pull}/merge`;\n case 'update_pull_request_branch.':\n return `PUT ${repoPath}/pulls/${pull}/update-branch`;\n case 'pull_request_review_write.create':\n return `POST ${repoPath}/pulls/${pull}/reviews`;\n case 'pull_request_review_write.submit_pending':\n return `POST ${repoPath}/pulls/${pull}/reviews/{review_id}/events`;\n case 'pull_request_review_write.delete_pending':\n return `DELETE ${repoPath}/pulls/${pull}/reviews/{review_id}`;\n case 'add_comment_to_pending_review.':\n return GITHUB_GRAPHQL_ROUTE;\n case 'actions_list.list_workflows':\n return `GET ${repoPath}/actions/workflows`;\n case 'actions_list.list_workflow_runs':\n return `GET ${repoPath}/actions/workflows/${resource}/runs`;\n case 'actions_list.list_workflow_jobs':\n return `GET ${repoPath}/actions/runs/${resource}/jobs`;\n case 'actions_list.list_workflow_run_artifacts':\n return `GET ${repoPath}/actions/runs/${resource}/artifacts`;\n case 'actions_get.get_workflow':\n return `GET ${repoPath}/actions/workflows/${resource}`;\n case 'actions_get.get_workflow_run':\n return `GET ${repoPath}/actions/runs/${resource}`;\n case 'actions_get.get_workflow_job':\n return `GET ${repoPath}/actions/jobs/${resource}`;\n case 'actions_get.download_workflow_run_artifact':\n return GITHUB_ARTIFACT_DOWNLOAD_ROUTE;\n case 'actions_get.get_workflow_run_usage':\n return `GET ${repoPath}/actions/runs/${resource}/timing`;\n case 'actions_get.get_workflow_run_logs_url':\n return `GET ${repoPath}/actions/runs/${resource}/logs`;\n case 'actions_run_trigger.run_workflow':\n return `POST ${repoPath}/actions/workflows/{workflow_id}/dispatches`;\n case 'actions_run_trigger.rerun_workflow_run':\n return `POST ${repoPath}/actions/runs/${run}/rerun`;\n case 'actions_run_trigger.rerun_failed_jobs':\n return `POST ${repoPath}/actions/runs/${run}/rerun-failed-jobs`;\n case 'actions_run_trigger.cancel_workflow_run':\n return `POST ${repoPath}/actions/runs/${run}/cancel`;\n case 'actions_run_trigger.delete_workflow_run_logs':\n return `DELETE ${repoPath}/actions/runs/${run}/logs`;\n case 'get_job_logs.':\n return `GET ${repoPath}/actions/jobs/{job_id}/logs`;\n default:\n return undefined;\n }\n}\n\nasync function addCommentToPendingReview(\n client: GithubToolClient,\n args: Record<string, unknown>,\n): Promise<unknown | undefined> {\n if (client.graphql === undefined) {\n throw new GithubIntegrationProviderError(\n 'malformed-provider-response',\n 'GitHub client does not support GraphQL operations',\n );\n }\n\n const reviewLookup = await client.graphql(LATEST_PENDING_REVIEW_QUERY, {\n owner: args.owner,\n repo: args.repo,\n pullNumber: args.pull_number,\n });\n const reviewId = latestPendingReviewNodeId(reviewLookup);\n if (reviewId === undefined) return undefined;\n\n const input: Record<string, unknown> = {\n pullRequestReviewId: reviewId,\n path: args.path,\n body: args.body,\n subjectType: args.subject_type,\n };\n if (args.line !== undefined) input.line = args.line;\n if (args.side !== undefined) input.side = args.side;\n if (args.start_line !== undefined) input.startLine = args.start_line;\n if (args.start_side !== undefined) input.startSide = args.start_side;\n\n return await client.graphql(ADD_PENDING_REVIEW_COMMENT_MUTATION, {input});\n}\n\nfunction latestPendingReviewNodeId(data: unknown): string | undefined {\n if (!isRecord(data)) return undefined;\n\n const viewer = isRecord(data.viewer) ? data.viewer.login : undefined;\n if (typeof viewer !== 'string') return undefined;\n\n const repository = isRecord(data.repository) ? data.repository : undefined;\n const pullRequest =\n repository && isRecord(repository.pullRequest) ? repository.pullRequest : undefined;\n const reviews = pullRequest && isRecord(pullRequest.reviews) ? pullRequest.reviews : undefined;\n const nodes = reviews && Array.isArray(reviews.nodes) ? reviews.nodes : [];\n\n let latest: {createdAt: string; id: string} | undefined;\n for (const node of nodes) {\n if (!isRecord(node)) continue;\n const author = isRecord(node.author) ? node.author.login : undefined;\n const id = node.id;\n const createdAt = node.createdAt;\n if (author !== viewer || typeof id !== 'string' || typeof createdAt !== 'string') continue;\n if (latest === undefined || createdAt > latest.createdAt) latest = {createdAt, id};\n }\n\n return latest?.id;\n}\n\nexport function projectGithubOperationParameters(\n toolId: GithubAgentToolId,\n method: string | undefined,\n args: Record<string, unknown>,\n): Record<string, unknown> {\n const parameters = {...args};\n if (toolId === 'add_issue_comment' && parameters.reaction !== undefined) {\n parameters.content = parameters.reaction;\n delete parameters.reaction;\n if (parameters.body === undefined) delete parameters.body;\n }\n if (toolId === 'pull_request_read' && method === 'get_diff') {\n parameters.headers = {accept: 'application/vnd.github.diff'};\n }\n return parameters;\n}\n\nasync function resolvePendingReviewParameters(\n client: GithubToolClient,\n parameters: Record<string, unknown>,\n toolId: GithubAgentToolId,\n method: string | undefined,\n): Promise<Record<string, unknown> | undefined> {\n if (!isPendingReviewOperation(toolId, method)) return parameters;\n\n const reviewId = await latestPendingReviewId(client, parameters);\n return reviewId === undefined ? undefined : {...parameters, review_id: reviewId};\n}\n\nfunction isPendingReviewOperation(toolId: GithubAgentToolId, method: string | undefined): boolean {\n return (\n toolId === 'pull_request_review_write' &&\n (method === 'submit_pending' || method === 'delete_pending')\n );\n}\n\nasync function latestPendingReviewId(\n client: GithubToolClient,\n parameters: Record<string, unknown>,\n): Promise<number | undefined> {\n const perPage = 100;\n let page = 1;\n let reviewId: number | undefined;\n\n while (true) {\n const response = await client.request('GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews', {\n owner: parameters.owner,\n repo: parameters.repo,\n pull_number: parameters.pull_number,\n per_page: perPage,\n page,\n });\n if (!Array.isArray(response.data)) return undefined;\n\n reviewId = latestPendingReviewIdOnPage(response.data) ?? reviewId;\n if (response.data.length < perPage) return reviewId;\n page += 1;\n }\n}\n\nfunction latestPendingReviewIdOnPage(data: readonly unknown[]): number | undefined {\n for (let index = data.length - 1; index >= 0; index -= 1) {\n const review = data[index];\n if (!isRecord(review) || review.state !== 'PENDING') continue;\n if (typeof review.id === 'number' && Number.isSafeInteger(review.id)) return review.id;\n }\n\n return undefined;\n}\n\nfunction githubToolResult(\n toolId: GithubAgentToolId,\n data: unknown,\n response?: GithubToolResponse,\n parameters?: Record<string, unknown>,\n route?: string,\n): GithubToolCallResult {\n const structuredContent = projectGithubToolOutput(toolId, data, response, parameters, route);\n if (structuredContent === undefined) {\n return githubToolError('GitHub artifact download did not return a download URL');\n }\n return {\n content: [{type: 'text', text: JSON.stringify(structuredContent)}],\n structuredContent,\n };\n}\n\nfunction projectGithubToolOutput(\n toolId: GithubAgentToolId,\n data: unknown,\n response?: GithubToolResponse,\n parameters?: Record<string, unknown>,\n route?: string,\n): Record<string, unknown> | undefined {\n if (route === GITHUB_ARTIFACT_DOWNLOAD_ROUTE) {\n return projectGithubArtifactDownloadOutput(response, parameters);\n }\n\n switch (toolId) {\n case 'list_issue_types':\n return {issue_types: data};\n case 'list_issues':\n return {issues: data};\n case 'search_issues':\n return {issues: githubSearchItems(data)};\n case 'list_pull_requests':\n return {pull_requests: data};\n case 'search_pull_requests':\n return {pull_requests: githubSearchItems(data)};\n case 'create_pull_request':\n case 'update_pull_request':\n return {pull_request: data};\n case 'merge_pull_request':\n return {merge: data};\n default:\n return isRecord(data) ? data : {result: data};\n }\n}\n\nfunction projectGithubArtifactDownloadOutput(\n response: GithubToolResponse | undefined,\n parameters: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (response === undefined) return undefined;\n const downloadUrl = response.headers?.location;\n if (typeof downloadUrl !== 'string' || downloadUrl.length === 0) return undefined;\n\n const output: Record<string, unknown> = {\n archive_format: GITHUB_ARTIFACT_ARCHIVE_FORMAT,\n download_url: downloadUrl,\n };\n if (typeof parameters?.resource_id === 'string') output.artifact_id = parameters.resource_id;\n\n const contentType = response.headers?.['content-type'];\n if (typeof contentType === 'string') output.content_type = contentType;\n\n const contentLength = response.headers?.['content-length'];\n const sizeBytes = typeof contentLength === 'number' ? contentLength : Number(contentLength);\n if (Number.isSafeInteger(sizeBytes) && sizeBytes >= 0) output.size_bytes = sizeBytes;\n\n return output;\n}\n\nfunction githubSearchItems(data: unknown): unknown {\n return isRecord(data) ? data.items : data;\n}\n\nfunction githubToolError(message: string): GithubToolCallResult {\n return {isError: true, content: [{type: 'text', text: message}]};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction validateGithubToolArguments(\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n arguments_: Record<string, unknown>,\n): string | undefined {\n const required = Array.isArray(tool.inputSchema.required) ? tool.inputSchema.required : [];\n for (const name of required) {\n if (typeof name === 'string' && arguments_[name] === undefined) {\n return `Missing required parameter: ${name}`;\n }\n }\n\n const methodRequired = methodRequiredParameters(tool.inputSchema, arguments_);\n for (const name of methodRequired) {\n if (arguments_[name] === undefined) return `Missing required parameter: ${name}`;\n }\n\n const properties = tool.inputSchema.properties;\n if (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n return undefined;\n }\n const propertySchemas = properties as Record<string, unknown>;\n for (const [name, value] of Object.entries(arguments_)) {\n const schema = propertySchemas[name];\n if (typeof schema !== 'object' || schema === null || Array.isArray(schema)) continue;\n const type = (schema as {type?: unknown}).type;\n if (type === 'integer' && (!Number.isInteger(value) || typeof value !== 'number')) {\n return `Parameter ${name} must be an integer`;\n }\n if (type === 'array' && !Array.isArray(value)) return `Parameter ${name} must be an array`;\n }\n return undefined;\n}\n\nfunction methodRequiredParameters(\n inputSchema: AgentToolCatalogEntry<GithubAgentToolRequiredScope>['inputSchema'],\n arguments_: Record<string, unknown>,\n): string[] {\n const method = arguments_.method;\n if (typeof method !== 'string' || !Array.isArray(inputSchema.oneOf)) return [];\n\n for (const candidate of inputSchema.oneOf) {\n if (!isRecord(candidate) || !isRecord(candidate.properties)) continue;\n const methodSchema = candidate.properties.method;\n if (!isRecord(methodSchema) || methodSchema.const !== method) continue;\n return Array.isArray(candidate.required)\n ? candidate.required.filter((name): name is string => typeof name === 'string')\n : [];\n }\n\n return [];\n}\n\nfunction hasGrantedPermissions(\n granted: Record<string, 'read' | 'write' | 'admin'>,\n tool: AgentToolCatalogEntry<GithubAgentToolRequiredScope>,\n call: AgentToolCallInput,\n): boolean {\n const method = typeof call.arguments.method === 'string' ? call.arguments.method : undefined;\n const required =\n tool.methods?.find((candidate) => candidate.id === method)?.requiredScope ?? tool.requiredScope;\n return required.every(({permission, access}) => {\n const actual = granted[permission];\n return actual === 'write' || actual === 'admin' || actual === access;\n });\n}\n"],"names":["Octokit","mapGithubError","createGithubInstallationTokenProvider","normalizedGithubApiBaseUrl","GithubIntegrationProviderError","githubAgentToolCatalog","githubAgentToolSelectionCatalog","buildGithubAgentToolSelectionCatalog","DEFAULT_JOB_LOG_TAIL_LINES","GITHUB_GRAPHQL_ROUTE","GITHUB_ARTIFACT_ARCHIVE_FORMAT","GITHUB_ARTIFACT_DOWNLOAD_ROUTE","GITHUB_ARTIFACT_DOWNLOAD_TIMEOUT_MS","NO_PENDING_REVIEW_MESSAGE","LATEST_PENDING_REVIEW_QUERY","ADD_PENDING_REVIEW_COMMENT_MUTATION","GithubAgentToolsProvider","options","tokenProvider","catalog","selectionCatalog","openSession","input","installation","getInstallationByConnectionId","connection","id","installationId","Number","isSafeInteger","tokenPromise","call","tool","tools","find","candidate","toolId","githubToolError","operation","resolveGithubOperation","undefined","validationError","validateGithubToolArguments","arguments","getInstallationAccessToken","token","hasGrantedPermissions","permissions","client","createClient","createOctokitClient","method","kind","data","addCommentToPendingReview","parameters","githubToolResult","operationParameters","resolvePendingReviewParameters","response","request","route","octokit","auth","baseUrl","retry","enabled","abortController","AbortController","timeout","setTimeout","abort","redirect","parseSuccessResponseBody","signal","clearTimeout","graphql","query","variables","args","params","methods","some","githubOperationRoute","projectGithubOperationParameters","owner","repo","issue","pull","run","resource","repoPath","comment_id","reaction","body","reviewLookup","pullNumber","pull_number","reviewId","latestPendingReviewNodeId","pullRequestReviewId","path","subjectType","subject_type","line","side","start_line","startLine","start_side","startSide","isRecord","viewer","login","repository","pullRequest","reviews","nodes","Array","isArray","latest","node","author","createdAt","content","headers","accept","isPendingReviewOperation","latestPendingReviewId","review_id","perPage","page","per_page","latestPendingReviewIdOnPage","length","index","review","state","structuredContent","projectGithubToolOutput","type","text","JSON","stringify","projectGithubArtifactDownloadOutput","issue_types","issues","githubSearchItems","pull_requests","pull_request","merge","result","downloadUrl","location","output","archive_format","download_url","resource_id","artifact_id","contentType","content_type","contentLength","sizeBytes","size_bytes","items","message","isError","value","arguments_","required","inputSchema","name","methodRequired","methodRequiredParameters","properties","propertySchemas","Object","entries","schema","isInteger","oneOf","methodSchema","const","filter","granted","requiredScope","every","permission","access","actual"],"mappings":"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"}
|
|
@@ -575,7 +575,7 @@ export const githubAgentToolCatalog = [
|
|
|
575
575
|
tool({
|
|
576
576
|
id: 'add_comment_to_pending_review',
|
|
577
577
|
category: 'pull_requests',
|
|
578
|
-
description: "Add review comment to the requester's latest pending pull request review.
|
|
578
|
+
description: "Add a review comment to the requester's latest pending pull request review. The comment remains part of that pending review until it is submitted; a pending review needs to already exist to call this.",
|
|
579
579
|
sensitivity: 'write',
|
|
580
580
|
sensitive: false,
|
|
581
581
|
requiredScope: scopes.pullRequestsWrite,
|