fix: issues with pagination not resolving correct url templates

This commit is contained in:
2026-05-31 03:18:07 -05:00
parent 2aca1a3aa3
commit 0438688e32
14 changed files with 287 additions and 467 deletions
+27 -57
View File
@@ -1,57 +1,45 @@
import { writeFileSync } from "node:fs";
import { join } from "node:path";
import { type } from "arktype";
import type { PullReviewComment } from "@go-gitea/sdk.js";
import { stripExistingFooter } from "../utils/buildShockbotFooter.ts";
import { log } from "../utils/log.ts";
import type { ToolContext } from "./server.ts";
import { execute, tool } from "./shared.ts";
export const GetReviewComments = type({
pull_number: type.number.describe("The pull request number to get review comments for"),
});
interface GiteaReview { id: number; user?: { login: string }; state?: string; body?: string; submitted_at?: string; commit_id?: string }
interface GiteaReviewComment { id: number; body?: string; path?: string; diff_hunk?: string; original_position?: number; position?: number; pull_request_review_id?: number; user?: { login: string } }
export const GetReviewComments = type({ pull_number: type.number });
export function GetReviewCommentsTool(ctx: ToolContext) {
return tool({
name: "get_review_comments",
description:
"Get all inline review comments for a pull request. " +
"Example: `get_review_comments({ pull_number: 1234 })`.",
description: "Get all inline review comments for a pull request. Example: `get_review_comments({ pull_number: 1234 })`.",
parameters: GetReviewComments,
execute: execute(async ({ pull_number }) => {
ctx.toolState.issueNumber = pull_number;
const reviewsR = await ctx.gitea.request(
"GET /repos/{owner}/{repo}/pulls/{index}/reviews",
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, limit: 50 }
);
const reviews = reviewsR.data as GiteaReview[];
// Get all reviews, then collect their comments
const reviews = await ctx.gitea.paginate(ctx.gitea.rest.repository.repoListPullReviews, {
owner: ctx.repo.owner,
repo: ctx.repo.name,
index: pull_number,
});
const allComments: PullReviewComment[] = [];
const allComments: GiteaReviewComment[] = [];
for (const review of reviews) {
if (!review.id) continue;
try {
const commentsResult = await ctx.gitea.rest.repository.repoGetPullReviewComments({
owner: ctx.repo.owner,
repo: ctx.repo.name,
index: pull_number,
id: review.id,
});
allComments.push(...commentsResult.data);
} catch {
// best-effort
}
const cr = await ctx.gitea.request(
"GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments",
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, id: review.id }
);
allComments.push(...(cr.data as GiteaReviewComment[]));
} catch { /* best-effort */ }
}
const tempDir = process.env.SHOCKBOT_TEMP_DIR;
let filePath: string | undefined;
const rendered = allComments.map((c) => ({
id: c.id,
path: c.path,
// PullReviewComment uses `position` for the diff offset; Gitea doesn't
// expose separate new_position/old_position on GET — use original_position as fallback
id: c.id, path: c.path,
line: c.original_position ?? c.position,
side: "RIGHT" as const,
body: stripExistingFooter(c.body ?? ""),
@@ -65,45 +53,27 @@ export function GetReviewCommentsTool(ctx: ToolContext) {
writeFileSync(filePath, JSON.stringify(rendered, null, 2));
log.debug(`wrote review comments to ${filePath}`);
}
return {
pull_number,
comments: rendered,
count: rendered.length,
...(filePath ? { filePath } : {}),
};
return { pull_number, comments: rendered, count: rendered.length, ...(filePath ? { filePath } : {}) };
}),
});
}
export const ListPullRequestReviews = type({
pull_number: type.number.describe("The pull request number"),
});
export const ListPullRequestReviews = type({ pull_number: type.number });
export function ListPullRequestReviewsTool(ctx: ToolContext) {
return tool({
name: "list_pull_request_reviews",
description:
"List all reviews submitted on a pull request. " +
"Example: `list_pull_request_reviews({ pull_number: 1234 })`.",
description: "List all reviews submitted on a pull request. Example: `list_pull_request_reviews({ pull_number: 1234 })`.",
parameters: ListPullRequestReviews,
execute: execute(async ({ pull_number }) => {
const reviews = await ctx.gitea.paginate(ctx.gitea.rest.repository.repoListPullReviews, {
owner: ctx.repo.owner,
repo: ctx.repo.name,
index: pull_number,
});
const r = await ctx.gitea.request(
"GET /repos/{owner}/{repo}/pulls/{index}/reviews",
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, limit: 50 }
);
const reviews = r.data as GiteaReview[];
return {
pull_number,
reviews: reviews.map((r) => ({
id: r.id,
user: r.user?.login,
state: r.state,
body: r.body,
submitted_at: r.submitted_at,
commit_id: r.commit_id,
})),
reviews: reviews.map((r) => ({ id: r.id, user: r.user?.login, state: r.state, body: r.body, submitted_at: r.submitted_at, commit_id: r.commit_id })),
count: reviews.length,
};
}),