Skip to content

Commit 854a3c2

Browse files
author
延枚
committed
优化创建评论的mcp tool
Change-Id: I540580347feb31ff06fa9cc4805e80619e815f3c
1 parent 85d0f0f commit 854a3c2

File tree

6 files changed

+130
-45
lines changed

6 files changed

+130
-45
lines changed

common/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export {
6262
// Change request comment schemas
6363
CreateChangeRequestCommentSchema,
6464
ListChangeRequestCommentsSchema,
65+
UpdateChangeRequestCommentSchema,
6566

6667
// Commit schemas
6768
ListCommitsRequestSchema,

operations/codeup/changeRequestComments.ts

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,29 @@ import {
66

77
/**
88
* 创建合并请求评论
9-
* @param organizationId
10-
* @param repositoryId
11-
* @param localId
12-
* @param comment_type
13-
* @param content
14-
* @param draft
15-
* @param resolved
16-
* @param patchset_biz_id
17-
* @param file_path
18-
* @param line_number
19-
* @param from_patchset_biz_id
20-
* @param to_patchset_biz_id
21-
* @param parent_comment_biz_id
9+
* 支持两种评论类型:
10+
* 1. GLOBAL_COMMENT - 全局评论:对整个合并请求的评论
11+
* 2. INLINE_COMMENT - 行内评论:针对特定代码行的评论
12+
*
13+
* 创建行内评论时,必须提供以下参数:
14+
* - file_path: 文件路径,例如 '/src/main/java/com/example/MyClass.java'
15+
* - line_number: 行号,例如 42
16+
* - from_patchset_biz_id: 比较的起始版本ID(通常是目标分支版本)
17+
* - to_patchset_biz_id: 比较的目标版本ID(通常是源分支版本)
18+
*
19+
* @param organizationId 组织ID,示例:'60d54f3daccf2bbd6659f3ad'
20+
* @param repositoryId 代码库ID或路径,示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'
21+
* @param localId 合并请求局部ID,示例:'1'
22+
* @param comment_type 评论类型:'GLOBAL_COMMENT' 或 'INLINE_COMMENT'
23+
* @param content 评论内容,长度1-65535,示例:'This is a comment content.'
24+
* @param draft 是否草稿评论,默认 false
25+
* @param resolved 是否标记已解决,默认 false
26+
* @param patchset_biz_id 关联版本ID,示例:'bf117304dfe44d5d9b1132f348edf92e'
27+
* @param file_path 文件路径(仅行内评论),示例:'/src/main/java/com/example/MyClass.java'
28+
* @param line_number 行号(仅行内评论),示例:42
29+
* @param from_patchset_biz_id 起始版本ID(行内评论必传),示例:'bf117304dfe44d5d9b1132f348edf92e'
30+
* @param to_patchset_biz_id 目标版本ID(行内评论必传),示例:'537367017a9841738ac4269fbf6aacbe'
31+
* @param parent_comment_biz_id 父评论ID(用于回复),示例:'1d8171cf0cc2453197fae0e0a27d5ece'
2232
*/
2333
export async function createChangeRequestCommentFunc(
2434
organizationId: string,
@@ -76,14 +86,16 @@ export async function createChangeRequestCommentFunc(
7686

7787
/**
7888
* 获取合并请求评论列表
79-
* @param organizationId
80-
* @param repositoryId
81-
* @param localId
82-
* @param patchSetBizIds
83-
* @param commentType
84-
* @param state
85-
* @param resolved
86-
* @param filePath
89+
* 支持按评论类型、状态、解决状态和文件路径进行过滤
90+
*
91+
* @param organizationId 组织ID,示例:'60d54f3daccf2bbd6659f3ad'
92+
* @param repositoryId 代码库ID或路径,示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'
93+
* @param localId 合并请求局部ID,示例:'1'
94+
* @param patchSetBizIds 版本ID列表(可选),示例:['bf117304dfe44d5d9b1132f348edf92e']
95+
* @param commentType 评论类型:'GLOBAL_COMMENT' 或 'INLINE_COMMENT',默认 'GLOBAL_COMMENT'
96+
* @param state 评论状态:'OPENED' 或 'DRAFT',默认 'OPENED'
97+
* @param resolved 是否已解决,默认 false
98+
* @param filePath 文件路径过滤(仅行内评论),示例:'/src/main/java/com/example/MyClass.java'
8799
*/
88100
export async function listChangeRequestCommentsFunc(
89101
organizationId: string,
@@ -124,4 +136,47 @@ export async function listChangeRequestCommentsFunc(
124136

125137
// 解析每个评论对象
126138
return response.map(comment => ChangeRequestCommentSchema.parse(comment));
139+
}
140+
141+
/**
142+
* 更新合并请求评论
143+
* 可以更新评论的内容和解决状态
144+
*
145+
* @param organizationId 组织ID,示例:'60d54f3daccf2bbd6659f3ad'
146+
* @param repositoryId 代码库ID或路径,示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'
147+
* @param localId 合并请求局部ID,示例:'1'
148+
* @param commentBizId 评论 bizId,示例:'bf117304dfe44d5d9b1132f348edf92e'
149+
* @param content 更新后的评论内容(可选),示例:'your new comment'
150+
* @param resolved 是否已解决(可选),示例:false
151+
*/
152+
export async function updateChangeRequestCommentFunc(
153+
organizationId: string,
154+
repositoryId: string,
155+
localId: string,
156+
commentBizId: string,
157+
content?: string,
158+
resolved?: boolean
159+
): Promise<{ result: boolean }> {
160+
const encodedRepoId = handleRepositoryIdEncoding(repositoryId);
161+
162+
const url = `/oapi/v1/codeup/organizations/${organizationId}/repositories/${encodedRepoId}/changeRequests/${localId}/comments/${commentBizId}`;
163+
164+
// 准备payload
165+
const payload: Record<string, any> = {};
166+
167+
if (content !== undefined) {
168+
payload.content = content;
169+
}
170+
171+
if (resolved !== undefined) {
172+
payload.resolved = resolved;
173+
}
174+
175+
const response = await yunxiaoRequest(url, {
176+
method: "PUT",
177+
body: payload,
178+
});
179+
180+
// 根据 swagger 文档,响应格式为 { result: boolean }
181+
return response as { result: boolean };
127182
}

operations/codeup/types.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -360,30 +360,39 @@ export const ListChangeRequestPatchSetsSchema = z.object({
360360

361361
// Codeup change request comments related Schema definitions
362362
export const CreateChangeRequestCommentSchema = z.object({
363-
organizationId: z.string().describe("Organization ID, can be found in the basic information page of the organization admin console"),
364-
repositoryId: z.string().describe("Repository ID or a combination of organization ID and repository name, for example: 2835387 or organizationId%2Frepo-name (Note: slashes need to be URL encoded as %2F)"),
365-
localId: z.string().describe("Local ID, represents the nth merge request in the repository"),
366-
comment_type: z.string().default("GLOBAL_COMMENT").describe("Comment type. Possible values: GLOBAL_COMMENT, INLINE_COMMENT"),
367-
content: z.string().describe("Comment content, length must be between 1 and 65535"),
368-
draft: z.boolean().default(false).describe("Whether it is a draft comment"),
369-
resolved: z.boolean().default(false).describe("Whether to mark as resolved"),
370-
patchset_biz_id: z.string().describe("Associated version ID, if it's INLINE_COMMENT, choose one from from_patchset_biz_id or to_patchset_biz_id"),
371-
file_path: z.string().nullable().optional().describe("File name, only for inline comments"),
372-
line_number: z.number().int().nullable().optional().describe("Line number, only for inline comments"),
373-
from_patchset_biz_id: z.string().nullable().optional().describe("Start version ID for comparison, required for INLINE_COMMENT type"),
374-
to_patchset_biz_id: z.string().nullable().optional().describe("Target version ID for comparison, required for INLINE_COMMENT type"),
375-
parent_comment_biz_id: z.string().nullable().optional().describe("Parent comment ID"),
363+
organizationId: z.string().describe("组织ID,可在组织管理后台的基本信息页面获取。示例:'60d54f3daccf2bbd6659f3ad'"),
364+
repositoryId: z.string().describe("代码库ID或者URL-Encoder编码的全路径。示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'(注意:斜杠需要URL编码为%2F"),
365+
localId: z.string().describe("局部ID,表示代码库中第几个合并请求。示例:'1' 或 '42'"),
366+
comment_type: z.enum(["GLOBAL_COMMENT", "INLINE_COMMENT"]).default("GLOBAL_COMMENT").describe("评论类型。GLOBAL_COMMENT - 全局评论(对整个合并请求的评论);INLINE_COMMENT - 行内评论(针对特定代码行的评论)。创建行内评论时,必须提供 file_path、line_number、from_patchset_biz_id 和 to_patchset_biz_id 参数"),
367+
content: z.string().min(1).max(65535).describe("评论内容,长度必须在 1 到 65535 之间。示例:'This is a comment content.' 或 '这里需要优化性能,建议使用缓存机制'"),
368+
draft: z.boolean().default(false).describe("是否草稿评论。true - 草稿评论(不会立即显示给其他人);false - 正式评论(默认值)"),
369+
resolved: z.boolean().default(false).describe("是否标记已解决。true - 已解决;false - 未解决(默认值)"),
370+
patchset_biz_id: z.string().describe("关联版本ID,具有唯一性。对于全局评论,使用最新合并源版本ID;对于行内评论,选择 from_patchset_biz_id to_patchset_biz_id 中的一个。示例:'bf117304dfe44d5d9b1132f348edf92e'"),
371+
file_path: z.string().optional().describe("文件路径,仅行内评论需要。表示评论针对的文件路径。示例:'/src/main/java/com/example/MyClass.java' 或 'src/utils/helper.ts' 或 'frontend/components/Button.tsx'"),
372+
line_number: z.number().int().positive().optional().describe("行号,仅行内评论需要。表示评论针对的代码行号,从1开始计数。示例:42 表示第42行,100 表示第100行"),
373+
from_patchset_biz_id: z.string().optional().describe("比较的起始版本ID,行内评论类型必传。表示代码比较的起始版本(通常是目标分支版本,即合并目标对应的版本)。示例:'bf117304dfe44d5d9b1132f348edf92e'"),
374+
to_patchset_biz_id: z.string().optional().describe("比较的目标版本ID,行内评论类型必传。表示代码比较的目标版本(通常是源分支版本,即合并源对应的版本)。示例:'537367017a9841738ac4269fbf6aacbe'"),
375+
parent_comment_biz_id: z.string().optional().describe("父评论ID,用于回复评论。如果这是对某个评论的回复,需要传入被回复评论的 bizId。示例:'1d8171cf0cc2453197fae0e0a27d5ece'"),
376376
});
377377

378378
export const ListChangeRequestCommentsSchema = z.object({
379-
organizationId: z.string().describe("Organization ID, can be found in the basic information page of the organization admin console"),
380-
repositoryId: z.string().describe("Repository ID or a combination of organization ID and repository name, for example: 2835387 or organizationId%2Frepo-name (Note: slashes need to be URL encoded as %2F)"),
381-
localId: z.string().describe("Change request local ID"),
382-
patchSetBizIds: z.array(z.string()).nullable().optional().describe("Associated version ID list, each comment is associated with a version, indicating which version the comment was posted on, for global comments, it's associated with the latest merge source version"),
383-
commentType: z.string().optional().default("GLOBAL_COMMENT").describe("Comment type. Possible values: GLOBAL_COMMENT, INLINE_COMMENT"),
384-
state: z.string().optional().default("OPENED").describe("Comment state. Possible values: OPENED, DRAFT"),
385-
resolved: z.boolean().optional().default(false).describe("Whether marked as resolved"),
386-
filePath: z.string().nullable().optional().describe("Filter by file path (for inline comments)"),
379+
organizationId: z.string().describe("组织ID,可在组织管理后台的基本信息页面获取。示例:'60d54f3daccf2bbd6659f3ad'"),
380+
repositoryId: z.string().describe("代码库ID或者URL-Encoder编码的全路径。示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'(注意:斜杠需要URL编码为%2F)"),
381+
localId: z.string().describe("合并请求局部ID,表示代码库中第几个合并请求。示例:'1' 或 '42'"),
382+
patchSetBizIds: z.array(z.string()).optional().describe("关联版本ID列表,每个评论都关联一个版本,表示该评论是在哪个版本上发布的。对于全局评论,关联的是最新合并源版本。示例:['bf117304dfe44d5d9b1132f348edf92e', '537367017a9841738ac4269fbf6aacbe']"),
383+
commentType: z.enum(["GLOBAL_COMMENT", "INLINE_COMMENT"]).optional().default("GLOBAL_COMMENT").describe("评论类型。GLOBAL_COMMENT - 全局评论;INLINE_COMMENT - 行内评论"),
384+
state: z.enum(["OPENED", "DRAFT"]).optional().default("OPENED").describe("评论状态。OPENED - 已发布的评论;DRAFT - 草稿评论"),
385+
resolved: z.boolean().optional().default(false).describe("是否已解决。true - 只查询已解决的评论;false - 只查询未解决的评论(默认值)"),
386+
filePath: z.string().optional().describe("文件路径过滤,仅用于行内评论。可以过滤特定文件的评论。示例:'/src/main/java/com/example/MyClass.java' 或 'src/utils/helper.ts'"),
387+
});
388+
389+
export const UpdateChangeRequestCommentSchema = z.object({
390+
organizationId: z.string().describe("组织ID,可在组织管理后台的基本信息页面获取。示例:'60d54f3daccf2bbd6659f3ad'"),
391+
repositoryId: z.string().describe("代码库ID或者URL-Encoder编码的全路径。示例:'2835387' 或 '60de7a6852743a5162b5f957%2FDemoRepo'(注意:斜杠需要URL编码为%2F)"),
392+
localId: z.string().describe("合并请求局部ID,表示代码库中第几个合并请求。示例:'1' 或 '42'"),
393+
commentBizId: z.string().describe("评论 bizId,具有唯一性,用于标识要更新的评论。示例:'bf117304dfe44d5d9b1132f348edf92e'"),
394+
content: z.string().min(1).optional().describe("评论内容,更新后的评论内容(可选)。如果提供,将更新评论的文本内容。示例:'your new comment' 或 '更新后的评论内容:这里需要优化性能,建议使用缓存机制'"),
395+
resolved: z.boolean().optional().describe("是否已解决(可选)。true - 标记为已解决;false - 标记为未解决。示例:false。如果不提供此参数,将保持原有的解决状态不变"),
387396
});
388397

389398
// Codeup commit related Schema definitions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "alibabacloud-devops-mcp-server",
3-
"version": "0.3.3",
3+
"version": "0.3.4",
44
"description": "MCP Server for using the alibabacloud-devops API: allows AI assistants to directly participate in development collaboration, helping teams optimize development processes and improve efficiency.",
55
"type": "module",
66
"license": "Apache-2.0",

tool-handlers/code-management.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,21 @@ export const handleCodeManagementTools = async (request: any) => {
275275
};
276276
}
277277

278+
case "update_change_request_comment": {
279+
const args = types.UpdateChangeRequestCommentSchema.parse(request.params.arguments);
280+
const result = await changeRequestComments.updateChangeRequestCommentFunc(
281+
args.organizationId,
282+
args.repositoryId,
283+
args.localId,
284+
args.commentBizId,
285+
args.content ?? undefined,
286+
args.resolved ?? undefined
287+
);
288+
return {
289+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
290+
};
291+
}
292+
278293
case "list_change_request_patch_sets": {
279294
const args = types.ListChangeRequestPatchSetsSchema.parse(request.params.arguments);
280295
const patchSets = await changeRequests.listChangeRequestPatchSetsFunc(

tool-registry/code-management.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,19 @@ export const getCodeManagementTools = () => [
9393
},
9494
{
9595
name: "create_change_request_comment",
96-
description: "[Code Management] Create a comment on a change request",
96+
description: "[Code Management] Create a comment on a change request. Supports two types: GLOBAL_COMMENT (global comment on the entire merge request) and INLINE_COMMENT (inline comment on specific code lines). For INLINE_COMMENT, you must provide file_path, line_number, from_patchset_biz_id, and to_patchset_biz_id parameters.",
9797
inputSchema: zodToJsonSchema(types.CreateChangeRequestCommentSchema),
9898
},
9999
{
100100
name: "list_change_request_comments",
101-
description: "[Code Management] List comments on a change request",
101+
description: "[Code Management] List comments on a change request. Supports filtering by comment type (GLOBAL_COMMENT or INLINE_COMMENT), state (OPENED or DRAFT), resolved status, and file path (for inline comments).",
102102
inputSchema: zodToJsonSchema(types.ListChangeRequestCommentsSchema),
103103
},
104+
{
105+
name: "update_change_request_comment",
106+
description: "[Code Management] Update a comment on a change request. Can update the comment content and/or resolved status.",
107+
inputSchema: zodToJsonSchema(types.UpdateChangeRequestCommentSchema),
108+
},
104109
{
105110
name: "list_change_request_patch_sets",
106111
description: "[Code Management] List patch sets for a change request",

0 commit comments

Comments
 (0)