132 lines · 5.3 KB
import { z } from "zod";
import { all } from "../../db";
import { notFoundError } from "../../errors";
import { issueUrl, loadIssue } from "../../issues";
import type { IssueRow } from "../../issues";
import { limitWrite } from "../../limits";
import { markdownBody, title } from "~/lib/validation";
import { changeIssueState, insertComment, insertIssue } from "../issue-writes";
import { defineTool, repoArgs, scopedRepo, truncateText } from "./base";

const LIST_LIMIT = 50;
const MAX_COMMENTS = 100;
const number = z.number().int().positive();

const listIssuesTool = defineTool({
  name: "list_issues",
  title: "List issues",
  description: "Issues (not pull requests) in a repository, newest first.",
  input: z.object({ ...repoArgs, state: z.enum(["open", "closed", "all"]).default("open") }),
  write: false,
  async run({ caller }, args) {
    const { repo } = await scopedRepo(caller, args.owner, args.repo, "issues", "read");
    const rows = await all<IssueRow & { author: string }>(
      `SELECT i.*, a.name AS author FROM issues i JOIN accounts a ON a.id = i.author_id
       WHERE i.repo_id = ? AND i.is_pull = 0 AND (? = 'all' OR i.state = ?) ORDER BY i.number DESC LIMIT ${LIST_LIMIT}`,
      repo.id,
      args.state,
      args.state,
    );
    return {
      structured: {
        issues: rows.map((row) => ({
          number: row.number,
          title: row.title,
          state: row.state,
          author: row.author,
          comments: row.comments_count,
          html_url: issueUrl(repo, row),
        })),
      },