add get_issue tools
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
use debug_shell_command tool to run 'git status' and explain the result
|
summarize https://github.com/pullfrogai/scratch/issues/56, its status, and pertinent discussion on the issue
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { type } from "arktype";
|
||||||
|
import { contextualize, tool } from "./shared.ts";
|
||||||
|
|
||||||
|
export const GetIssueComments = type({
|
||||||
|
issue_number: type.number.describe("The issue number to get comments for"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const GetIssueCommentsTool = tool({
|
||||||
|
name: "get_issue_comments",
|
||||||
|
description: "Get all comments for a GitHub issue. Returns all comments including the issue body and all subsequent discussion comments.",
|
||||||
|
parameters: GetIssueComments,
|
||||||
|
execute: contextualize(async ({ issue_number }, ctx) => {
|
||||||
|
const comments = await ctx.octokit.paginate(ctx.octokit.rest.issues.listComments, {
|
||||||
|
owner: ctx.owner,
|
||||||
|
repo: ctx.name,
|
||||||
|
issue_number,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
issue_number,
|
||||||
|
comments: comments.map((comment) => ({
|
||||||
|
id: comment.id,
|
||||||
|
body: comment.body,
|
||||||
|
user: comment.user?.login,
|
||||||
|
created_at: comment.created_at,
|
||||||
|
updated_at: comment.updated_at,
|
||||||
|
html_url: comment.html_url,
|
||||||
|
author_association: comment.author_association,
|
||||||
|
reactions: comment.reactions,
|
||||||
|
})),
|
||||||
|
count: comments.length,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { type } from "arktype";
|
||||||
|
import { contextualize, tool } from "./shared.ts";
|
||||||
|
|
||||||
|
export const GetIssueEvents = type({
|
||||||
|
issue_number: type.number.describe("The issue number to get events for"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const GetIssueEventsTool = tool({
|
||||||
|
name: "get_issue_events",
|
||||||
|
description:
|
||||||
|
"Get timeline events for a GitHub issue that aren't reflected in the current state. Returns cross-references to other issues/PRs and commit references. Note: current labels, assignees, state, and milestone are already available via get_issue.",
|
||||||
|
parameters: GetIssueEvents,
|
||||||
|
execute: contextualize(async ({ issue_number }, ctx) => {
|
||||||
|
const events = await ctx.octokit.paginate(ctx.octokit.rest.issues.listEventsForTimeline, {
|
||||||
|
owner: ctx.owner,
|
||||||
|
repo: ctx.name,
|
||||||
|
issue_number,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only include events not reflected in current issue state (get_issue already has labels, assignees, state, etc.)
|
||||||
|
// Keep only relationship/reference events that show connections to other issues/PRs/commits
|
||||||
|
const relevantEventTypes = new Set(["cross_referenced", "referenced"]);
|
||||||
|
|
||||||
|
const parsedEvents = events.flatMap((event) => {
|
||||||
|
// Filter to only events with an 'event' property and relevant types
|
||||||
|
if (!("event" in event) || !relevantEventTypes.has(event.event)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseEvent: Record<string, any> = {
|
||||||
|
event: event.event,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Common fields
|
||||||
|
if ("id" in event) {
|
||||||
|
baseEvent.id = event.id;
|
||||||
|
}
|
||||||
|
if ("actor" in event && event.actor) {
|
||||||
|
baseEvent.actor = event.actor.login;
|
||||||
|
} else if ("user" in event && event.user) {
|
||||||
|
baseEvent.actor = event.user.login;
|
||||||
|
}
|
||||||
|
if ("created_at" in event) {
|
||||||
|
baseEvent.created_at = event.created_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event-specific data
|
||||||
|
if (event.event === "cross_referenced") {
|
||||||
|
if ("source" in event && event.source) {
|
||||||
|
const source = event.source as {
|
||||||
|
type?: string;
|
||||||
|
issue?: { number: number; title: string; html_url: string };
|
||||||
|
pull_request?: { number: number; title: string; html_url: string };
|
||||||
|
};
|
||||||
|
baseEvent.source = {
|
||||||
|
type: source.type,
|
||||||
|
issue: source.issue
|
||||||
|
? {
|
||||||
|
number: source.issue.number,
|
||||||
|
title: source.issue.title,
|
||||||
|
html_url: source.issue.html_url,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
pull_request: source.pull_request
|
||||||
|
? {
|
||||||
|
number: source.pull_request.number,
|
||||||
|
title: source.pull_request.title,
|
||||||
|
html_url: source.pull_request.html_url,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.event === "referenced") {
|
||||||
|
if ("commit_id" in event) {
|
||||||
|
baseEvent.commit_id = event.commit_id;
|
||||||
|
}
|
||||||
|
if ("commit_url" in event) {
|
||||||
|
baseEvent.commit_url = event.commit_url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [baseEvent];
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
issue_number,
|
||||||
|
events: parsedEvents,
|
||||||
|
count: parsedEvents.length,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { type } from "arktype";
|
||||||
|
import { contextualize, tool } from "./shared.ts";
|
||||||
|
|
||||||
|
export const IssueInfo = type({
|
||||||
|
issue_number: type.number.describe("The issue number to fetch"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const IssueInfoTool = tool({
|
||||||
|
name: "get_issue",
|
||||||
|
description: "Retrieve GitHub issue information by issue number",
|
||||||
|
parameters: IssueInfo,
|
||||||
|
execute: contextualize(async ({ issue_number }, ctx) => {
|
||||||
|
const issue = await ctx.octokit.rest.issues.get({
|
||||||
|
owner: ctx.owner,
|
||||||
|
repo: ctx.name,
|
||||||
|
issue_number,
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = issue.data;
|
||||||
|
|
||||||
|
const hints: string[] = [];
|
||||||
|
if (data.comments > 0) {
|
||||||
|
hints.push("use get_issue_comments to retrieve all comments for this issue");
|
||||||
|
}
|
||||||
|
hints.push(
|
||||||
|
"use get_issue_events to retrieve cross-references and commit references (relationships not reflected in current state)"
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
number: data.number,
|
||||||
|
url: data.html_url,
|
||||||
|
title: data.title,
|
||||||
|
body: data.body,
|
||||||
|
state: data.state,
|
||||||
|
locked: data.locked,
|
||||||
|
labels: data.labels?.map((label) => (typeof label === "string" ? label : label.name)),
|
||||||
|
assignees: data.assignees?.map((assignee) => assignee.login),
|
||||||
|
user: data.user?.login,
|
||||||
|
created_at: data.created_at,
|
||||||
|
updated_at: data.updated_at,
|
||||||
|
closed_at: data.closed_at,
|
||||||
|
comments: data.comments,
|
||||||
|
milestone: data.milestone?.title,
|
||||||
|
pull_request: data.pull_request
|
||||||
|
? {
|
||||||
|
url: data.pull_request.url,
|
||||||
|
html_url: data.pull_request.html_url,
|
||||||
|
diff_url: data.pull_request.diff_url,
|
||||||
|
patch_url: data.pull_request.patch_url,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
hints,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
@@ -12,6 +12,9 @@ import {
|
|||||||
} from "./comment.ts";
|
} from "./comment.ts";
|
||||||
import { DebugShellCommandTool } from "./debug.ts";
|
import { DebugShellCommandTool } from "./debug.ts";
|
||||||
import { IssueTool } from "./issue.ts";
|
import { IssueTool } from "./issue.ts";
|
||||||
|
import { GetIssueCommentsTool } from "./issueComments.ts";
|
||||||
|
import { GetIssueEventsTool } from "./issueEvents.ts";
|
||||||
|
import { IssueInfoTool } from "./issueInfo.ts";
|
||||||
import { PullRequestTool } from "./pr.ts";
|
import { PullRequestTool } from "./pr.ts";
|
||||||
import { PullRequestInfoTool } from "./prInfo.ts";
|
import { PullRequestInfoTool } from "./prInfo.ts";
|
||||||
import { ReviewTool } from "./review.ts";
|
import { ReviewTool } from "./review.ts";
|
||||||
@@ -64,6 +67,9 @@ export async function startMcpHttpServer(): Promise<{ url: string; close: () =>
|
|||||||
CreateWorkingCommentTool,
|
CreateWorkingCommentTool,
|
||||||
UpdateWorkingCommentTool,
|
UpdateWorkingCommentTool,
|
||||||
IssueTool,
|
IssueTool,
|
||||||
|
IssueInfoTool,
|
||||||
|
GetIssueCommentsTool,
|
||||||
|
GetIssueEventsTool,
|
||||||
PullRequestTool,
|
PullRequestTool,
|
||||||
ReviewTool,
|
ReviewTool,
|
||||||
PullRequestInfoTool,
|
PullRequestInfoTool,
|
||||||
|
|||||||
Reference in New Issue
Block a user