Skip to content

Commit 180b6ef

Browse files
CopilotNewFutureCopilot
authored
feat(ci): use JSON format and auto-convert file references to URLs in issue replies (#597)
* Initial plan * feat(ci): improve auto-reply-issue with JSON format and URL conversion - Update system prompt to request JSON response format instead of text tag - Add JSON parsing with fallback to legacy format for backward compatibility - Add automatic URL conversion for markdown doc references (doc/*.md -> https://ddns.newfuture.cc/doc/*.html) - Add automatic URL conversion for code file references (ddns/*.py -> GitHub links) - Add response_format: json_object to API request for structured responses - Add comprehensive file reference guidelines in system prompt Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(ci): remove redundant URL conversion mentions from AI prompt The URL conversion is handled in the workflow code, so the AI prompt should only instruct to use backticks with relative paths, not mention the post-processing conversion. Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> * refactor(ci): let AI generate markdown links directly in response Simplify workflow logic by having AI output markdown links directly instead of post-processing. This makes the code simpler and reduces complexity in the workflow. Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> Co-authored-by: New Future <NewFuture@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 5d16946 commit 180b6ef

2 files changed

Lines changed: 70 additions & 17 deletions

File tree

.github/prompts/issue-assistant.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,54 @@ Your role is to provide friendly, informative responses to GitHub issues.
1212
- Uses Python standard library only (no external dependencies)
1313
- Supports Python 2.7 and 3.x
1414

15-
## Issue Classification
15+
## Response Format
1616

17-
**IMPORTANT**: You must classify each issue into ONE of these categories:
17+
**IMPORTANT**: You must return your response as a JSON object with the following structure:
18+
19+
```json
20+
{
21+
"classification": "bug|feature|question",
22+
"response": "Your detailed response here..."
23+
}
24+
```
25+
26+
### Classification Categories
27+
28+
Classify each issue into ONE of these categories:
1829
- **bug**: Software defects, errors, crashes, or unexpected behavior
1930
- **feature**: New feature requests, enhancements, or improvements
2031
- **question**: Questions about usage, configuration, documentation, or general inquiries
2132

22-
Return your classification at the START of your response using ONE of the following formats:
23-
```
33+
### Response Content Guidelines
34+
35+
When writing the "response" field:
36+
- **Respond in the same language as the issue title and content** (detect and match the user's language - Chinese, English, or other languages)
37+
- Keep responses concise but helpful
38+
- Use proper markdown formatting for code blocks and inline code
39+
- Reference files and documentation using markdown links
40+
41+
### File References
42+
43+
When referencing files in your response, use these formats:
44+
1. **Documentation files**: Use markdown links that convert `.md` to `.html` URLs
45+
- Format: `[doc/providers/aliesa.md](https://ddns.newfuture.cc/doc/providers/aliesa.html)`
46+
- Format: `[doc/config/cli.md](https://ddns.newfuture.cc/doc/config/cli.html)`
47+
2. **Code files**: Use markdown links to GitHub repository
48+
- Format: `[ddns/provider/_base.py](https://github.com/NewFuture/DDNS/blob/master/ddns/provider/_base.py)`
49+
- Format: `[tests/test_cache.py](https://github.com/NewFuture/DDNS/blob/master/tests/test_cache.py)`
50+
3. **Code blocks**: Use proper markdown code fences with language identifiers:
51+
````markdown
52+
```python
53+
# Your code here
54+
```
55+
````
56+
4. **Inline code**: Use backticks for commands and code snippets: `` `ddns --debug` `` or `` `variable_name` ``
2457

2558
## Response Guidelines
2659

2760
When responding to issues:
28-
1. Start with the classification tag in the exact format above
29-
2. Be welcoming and professional
30-
3. **Respond in the same language as the issue title and content** (detect and match the user's language - Chinese, English, or other languages)
31-
4. Keep responses concise but helpful
61+
1. Be welcoming and professional
62+
2. Be specific and actionable in your guidance
3263

3364
### Response Strategy by Classification
3465

.github/workflows/auto-reply-issue.yml

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ jobs:
134134
],
135135
temperature: 1,
136136
max_completion_tokens: 2000,
137+
response_format: { type: "json_object" }
137138
})
138139
});
139140
@@ -157,21 +158,42 @@ jobs:
157158
return;
158159
}
159160
160-
const aiResponse = data.choices[0].message.content.trim();
161+
let aiResponse = data.choices[0].message.content.trim();
161162
162-
// Extract classification from response
163-
const classificationMatch = aiResponse.match(/\[CLASSIFICATION:\s*(bug|feature|question)\]/i);
163+
// Try to parse JSON response
164164
let classification = null;
165165
let commentBody = aiResponse;
166166
167-
if (classificationMatch) {
168-
classification = classificationMatch[1].toLowerCase();
169-
// Remove classification tag from the comment body
170-
commentBody = aiResponse.replace(/\[CLASSIFICATION:\s*(bug|feature|question)\]\s*/i, '').trim();
171-
console.log(`Issue classified as: ${classification}`);
167+
try {
168+
// Remove markdown code fences if present
169+
let jsonContent = aiResponse;
170+
if (aiResponse.startsWith('```json') || aiResponse.startsWith('```')) {
171+
jsonContent = aiResponse.replace(/^```(?:json)?\s*\n/, '').replace(/\n```\s*$/, '').trim();
172+
}
173+
174+
const parsedResponse = JSON.parse(jsonContent);
175+
176+
if (parsedResponse.classification && parsedResponse.response) {
177+
classification = parsedResponse.classification.toLowerCase();
178+
commentBody = parsedResponse.response;
179+
console.log(`Issue classified as: ${classification} (JSON format)`);
180+
} else {
181+
console.log('JSON response missing required fields, falling back to text format');
182+
}
183+
} catch (jsonError) {
184+
console.log(`Failed to parse JSON response: ${jsonError.message}`);
185+
console.log('Falling back to legacy text format extraction');
186+
187+
// Fallback: Try legacy format with classification tag
188+
const classificationMatch = aiResponse.match(/\[CLASSIFICATION:\s*(bug|feature|question)\]/i);
189+
if (classificationMatch) {
190+
classification = classificationMatch[1].toLowerCase();
191+
commentBody = aiResponse.replace(/\[CLASSIFICATION:\s*(bug|feature|question)\]\s*/i, '').trim();
192+
console.log(`Issue classified as: ${classification} (legacy format)`);
193+
}
172194
}
173195
174-
// Post the response as a comment (without classification tag)
196+
// Post the response as a comment
175197
await github.rest.issues.createComment({
176198
owner: context.repo.owner,
177199
repo: context.repo.repo,

0 commit comments

Comments
 (0)