🌐 AI搜索 & 代理 主页
Skip to content

Commit ad179d0

Browse files
committed
Merge branch 'refactor/cli-issues-types-and-select' into 'main'
fix(cli): reduce token consumption by fetching only needed issue fields See merge request postgres-ai/postgres_ai!94
2 parents c77f012 + ae3a13d commit ad179d0

File tree

5 files changed

+72
-26
lines changed

5 files changed

+72
-26
lines changed

.gitlab-ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ cli:e2e:dind:
4646
variables:
4747
DOCKER_HOST: tcp://docker:2375
4848
DOCKER_TLS_CERTDIR: ""
49+
DOCKER_API_VERSION: "1.43"
4950
GIT_STRATEGY: fetch
5051
before_script:
5152
- apk add --no-cache bash curl git coreutils docker-cli docker-compose openssl
@@ -117,6 +118,7 @@ cli:node:e2e:dind:
117118
variables:
118119
DOCKER_HOST: tcp://docker:2375
119120
DOCKER_TLS_CERTDIR: ""
121+
DOCKER_API_VERSION: "1.43"
120122
GIT_STRATEGY: fetch
121123
before_script:
122124
- corepack enable || true
@@ -139,6 +141,7 @@ cli:node:full:dind:
139141
variables:
140142
DOCKER_HOST: tcp://docker:2375
141143
DOCKER_TLS_CERTDIR: ""
144+
DOCKER_API_VERSION: "1.43"
142145
GIT_STRATEGY: fetch
143146
before_script:
144147
- corepack enable || true

cli/lib/issues.ts

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,70 @@ import * as https from "https";
22
import { URL } from "url";
33
import { maskSecret, normalizeBaseUrl } from "./util";
44

5+
export interface IssueActionItem {
6+
id: string;
7+
issue_id: string;
8+
title: string;
9+
description: string | null;
10+
severity: number;
11+
is_done: boolean;
12+
done_by: number | null;
13+
done_at: string | null;
14+
created_at: string;
15+
updated_at: string;
16+
}
17+
18+
export interface Issue {
19+
id: string;
20+
title: string;
21+
description: string | null;
22+
created_at: string;
23+
updated_at: string;
24+
status: number;
25+
url_main: string | null;
26+
urls_extra: string[] | null;
27+
data: unknown | null;
28+
author_id: number;
29+
org_id: number;
30+
project_id: number | null;
31+
is_ai_generated: boolean;
32+
assigned_to: number[] | null;
33+
labels: string[] | null;
34+
is_edited: boolean;
35+
author_display_name: string;
36+
comment_count: number;
37+
action_items: IssueActionItem[];
38+
}
39+
40+
export interface IssueComment {
41+
id: string;
42+
issue_id: string;
43+
author_id: number;
44+
parent_comment_id: string | null;
45+
content: string;
46+
created_at: string;
47+
updated_at: string;
48+
data: unknown | null;
49+
}
50+
51+
export type IssueListItem = Pick<Issue, "id" | "title" | "status" | "created_at">;
52+
53+
export type IssueDetail = Pick<Issue, "id" | "title" | "description" | "status" | "created_at" | "author_display_name">;
554
export interface FetchIssuesParams {
655
apiKey: string;
756
apiBaseUrl: string;
857
debug?: boolean;
958
}
1059

11-
export async function fetchIssues(params: FetchIssuesParams): Promise<unknown> {
60+
export async function fetchIssues(params: FetchIssuesParams): Promise<IssueListItem[]> {
1261
const { apiKey, apiBaseUrl, debug } = params;
1362
if (!apiKey) {
1463
throw new Error("API key is required");
1564
}
1665

1766
const base = normalizeBaseUrl(apiBaseUrl);
1867
const url = new URL(`${base}/issues`);
68+
url.searchParams.set("select", "id,title,status,created_at");
1969

2070
const headers: Record<string, string> = {
2171
"access-token": apiKey,
@@ -54,10 +104,10 @@ export async function fetchIssues(params: FetchIssuesParams): Promise<unknown> {
54104
}
55105
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
56106
try {
57-
const parsed = JSON.parse(data);
107+
const parsed = JSON.parse(data) as IssueListItem[];
58108
resolve(parsed);
59109
} catch {
60-
resolve(data);
110+
reject(new Error(`Failed to parse issues response: ${data}`));
61111
}
62112
} else {
63113
let errMsg = `Failed to fetch issues: HTTP ${res.statusCode}`;
@@ -88,7 +138,7 @@ export interface FetchIssueCommentsParams {
88138
debug?: boolean;
89139
}
90140

91-
export async function fetchIssueComments(params: FetchIssueCommentsParams): Promise<unknown> {
141+
export async function fetchIssueComments(params: FetchIssueCommentsParams): Promise<IssueComment[]> {
92142
const { apiKey, apiBaseUrl, issueId, debug } = params;
93143
if (!apiKey) {
94144
throw new Error("API key is required");
@@ -137,10 +187,10 @@ export async function fetchIssueComments(params: FetchIssueCommentsParams): Prom
137187
}
138188
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
139189
try {
140-
const parsed = JSON.parse(data);
190+
const parsed = JSON.parse(data) as IssueComment[];
141191
resolve(parsed);
142192
} catch {
143-
resolve(data);
193+
reject(new Error(`Failed to parse issue comments response: ${data}`));
144194
}
145195
} else {
146196
let errMsg = `Failed to fetch issue comments: HTTP ${res.statusCode}`;
@@ -170,7 +220,7 @@ export interface FetchIssueParams {
170220
debug?: boolean;
171221
}
172222

173-
export async function fetchIssue(params: FetchIssueParams): Promise<unknown> {
223+
export async function fetchIssue(params: FetchIssueParams): Promise<IssueDetail | null> {
174224
const { apiKey, apiBaseUrl, issueId, debug } = params;
175225
if (!apiKey) {
176226
throw new Error("API key is required");
@@ -181,6 +231,7 @@ export async function fetchIssue(params: FetchIssueParams): Promise<unknown> {
181231

182232
const base = normalizeBaseUrl(apiBaseUrl);
183233
const url = new URL(`${base}/issues`);
234+
url.searchParams.set("select", "id,title,description,status,created_at,author_display_name");
184235
url.searchParams.set("id", `eq.${issueId}`);
185236
url.searchParams.set("limit", "1");
186237

@@ -223,12 +274,12 @@ export async function fetchIssue(params: FetchIssueParams): Promise<unknown> {
223274
try {
224275
const parsed = JSON.parse(data);
225276
if (Array.isArray(parsed)) {
226-
resolve(parsed[0] ?? null);
277+
resolve((parsed[0] as IssueDetail) ?? null);
227278
} else {
228-
resolve(parsed);
279+
resolve(parsed as IssueDetail);
229280
}
230281
} catch {
231-
resolve(data);
282+
reject(new Error(`Failed to parse issue response: ${data}`));
232283
}
233284
} else {
234285
let errMsg = `Failed to fetch issue: HTTP ${res.statusCode}`;
@@ -260,7 +311,7 @@ export interface CreateIssueCommentParams {
260311
debug?: boolean;
261312
}
262313

263-
export async function createIssueComment(params: CreateIssueCommentParams): Promise<unknown> {
314+
export async function createIssueComment(params: CreateIssueCommentParams): Promise<IssueComment> {
264315
const { apiKey, apiBaseUrl, issueId, content, parentCommentId, debug } = params;
265316
if (!apiKey) {
266317
throw new Error("API key is required");
@@ -324,10 +375,10 @@ export async function createIssueComment(params: CreateIssueCommentParams): Prom
324375
}
325376
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
326377
try {
327-
const parsed = JSON.parse(data);
378+
const parsed = JSON.parse(data) as IssueComment;
328379
resolve(parsed);
329380
} catch {
330-
resolve(data);
381+
reject(new Error(`Failed to parse create comment response: ${data}`));
331382
}
332383
} else {
333384
let errMsg = `Failed to create issue comment: HTTP ${res.statusCode}`;

cli/lib/mcp-server.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,8 @@ export async function startMcpServer(rootOpts?: RootOptsLike, extra?: { debug?:
109109

110110
try {
111111
if (toolName === "list_issues") {
112-
const result = await fetchIssues({ apiKey, apiBaseUrl, debug });
113-
const trimmed = Array.isArray(result)
114-
? (result as any[]).map((r) => ({
115-
id: (r as any).id,
116-
title: (r as any).title,
117-
status: (r as any).status,
118-
created_at: (r as any).created_at,
119-
}))
120-
: result;
121-
return { content: [{ type: "text", text: JSON.stringify(trimmed, null, 2) }] };
112+
const issues = await fetchIssues({ apiKey, apiBaseUrl, debug });
113+
return { content: [{ type: "text", text: JSON.stringify(issues, null, 2) }] };
122114
}
123115

124116
if (toolName === "view_issue") {

cli/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postgresai",
3-
"version": "0.12.0-beta.6",
3+
"version": "0.12.0-beta.7",
44
"description": "postgres_ai CLI (Node.js)",
55
"license": "Apache-2.0",
66
"private": false,

0 commit comments

Comments
 (0)