WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 64813b6

Browse files
sarahsCopilot
andauthored
Refactor ai-tools CLI (#58580)
Co-authored-by: Copilot <[email protected]>
1 parent c9a50c6 commit 64813b6

File tree

4 files changed

+407
-118
lines changed

4 files changed

+407
-118
lines changed

src/ai-tools/lib/call-models-api.ts

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,111 @@ interface ChatCompletionResponse {
3434
}
3535
}
3636

37-
export async function callModelsApi(promptWithContent: ChatCompletionRequest): Promise<string> {
37+
export async function callModelsApi(
38+
promptWithContent: ChatCompletionRequest,
39+
verbose = false,
40+
): Promise<string> {
3841
let aiResponse: ChatCompletionChoice
3942

43+
// Set default model if none specified
44+
if (!promptWithContent.model) {
45+
promptWithContent.model = 'openai/gpt-4o'
46+
if (verbose) {
47+
console.log('⚠️ No model specified, using default: openai/gpt-4o')
48+
}
49+
}
50+
4051
try {
52+
// Create an AbortController for timeout handling
53+
const controller = new AbortController()
54+
const timeoutId = setTimeout(() => controller.abort(), 180000) // 3 minutes
55+
56+
const startTime = Date.now()
57+
if (verbose) {
58+
console.log(`🚀 Making API request to GitHub Models using ${promptWithContent.model}...`)
59+
}
60+
4161
const response = await fetch(modelsCompletionsEndpoint, {
4262
method: 'post',
4363
body: JSON.stringify(promptWithContent),
4464
headers: {
4565
'Content-Type': 'application/json',
4666
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
4767
'X-GitHub-Api-Version': '2022-11-28',
48-
Accept: 'Accept: application/vnd.github+json',
68+
Accept: 'application/vnd.github+json',
4969
},
70+
signal: controller.signal,
5071
})
5172

73+
const fetchTime = Date.now() - startTime
74+
if (verbose) {
75+
console.log(`⏱️ API response received in ${fetchTime}ms`)
76+
}
77+
78+
clearTimeout(timeoutId)
79+
80+
if (!response.ok) {
81+
let errorMessage = `HTTP error! status: ${response.status} - ${response.statusText}`
82+
83+
// Try to get more detailed error information
84+
try {
85+
const errorBody = await response.json()
86+
if (errorBody.error && errorBody.error.message) {
87+
errorMessage += ` - ${errorBody.error.message}`
88+
}
89+
} catch {
90+
// If we can't parse error body, continue with basic error
91+
}
92+
93+
// Add helpful hints for common errors
94+
if (response.status === 401) {
95+
errorMessage += ' (Check your GITHUB_TOKEN)'
96+
} else if (response.status === 400) {
97+
errorMessage += ' (This may be due to an invalid model or malformed request)'
98+
} else if (response.status === 429) {
99+
errorMessage += ' (Rate limit exceeded - try again later)'
100+
}
101+
102+
throw new Error(errorMessage)
103+
}
104+
52105
const data: ChatCompletionResponse = await response.json()
106+
107+
if (!data.choices || data.choices.length === 0) {
108+
throw new Error('No response choices returned from API')
109+
}
110+
53111
aiResponse = data.choices[0]
112+
113+
if (verbose) {
114+
const totalTime = Date.now() - startTime
115+
console.log(`✅ Total API call completed in ${totalTime}ms`)
116+
117+
if (data.usage) {
118+
console.log(
119+
`📊 Tokens: ${data.usage.prompt_tokens} prompt + ${data.usage.completion_tokens} completion = ${data.usage.total_tokens} total`,
120+
)
121+
}
122+
}
54123
} catch (error) {
55-
console.error('Error calling GitHub Models REST API')
124+
if (error instanceof Error) {
125+
if (error.name === 'AbortError') {
126+
throw new Error('API call timed out after 3 minutes')
127+
}
128+
console.error('Error calling GitHub Models REST API:', error.message)
129+
}
56130
throw error
57131
}
58132

59-
return aiResponse.message.content
133+
return cleanAIResponse(aiResponse.message.content)
134+
}
135+
136+
// Helper function to clean up AI response content
137+
function cleanAIResponse(content: string): string {
138+
// Remove markdown code blocks
139+
return content
140+
.replace(/^```[\w]*\n/gm, '') // Remove opening code blocks
141+
.replace(/\n```$/gm, '') // Remove closing code blocks at end
142+
.replace(/\n```\n/gm, '\n') // Remove standalone closing code blocks
143+
.trim()
60144
}

src/ai-tools/prompts/intro.md

Lines changed: 37 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,20 @@ You are an expert SEO content optimizer specializing in GitHub documentation.
22
Your task is to analyze a GitHub Docs content file and generate or optimize
33
the intro frontmatter property following Google's meta description best practices.
44

5-
## Your mission
6-
7-
Generate a single, concise intro (one simple sentence maximum - NO colons, NO detailed explanations) that:
8-
9-
* Starts with an action verb (e.g., "Learn," "Discover," "Access," "Explore," "Configure," "Set up," "Build")
10-
* **Uses developer-friendly, direct language** - avoid marketing jargon and corporate buzzwords
11-
* **Prioritizes conciseness over completeness** - cut unnecessary words ruthlessly
12-
* Accurately summarizes the content's core value proposition
13-
* Includes relevant keywords naturally without stuffing
14-
* Follows Google's snippet guidelines (descriptive, informative, compelling)
15-
* Is version-agnostic (no {% ifversion %} blocks, but {% data variables.* %} and {% data reusables.* %} are acceptable)
16-
* Matches the content type (article/category/mapTopic) requirements
17-
* **Goes beyond title restatement** - summarizes the complete article value, not just rephrasing the title
18-
* **Lists concrete steps or outcomes** - what users will actually do or accomplish
19-
* **Limits lists to 2-3 items maximum** - avoid long comma-separated sequences that feel overwhelming
20-
21-
## SEO scoring criteria (1-10 scale)
22-
23-
**10-9 (Excellent)**: Strong action verb, comprehensive content summary, optimal keyword density, clear unique value beyond title, perfect length
24-
**8-7 (Good)**: Action verb present, good content representation, decent keywords, some unique value, appropriate length
25-
**6-5 (Fair)**: Weak action verb or missing, partial content coverage, basic keywords, minimal value beyond title
26-
**4-3 (Poor)**: No action verb, limited content representation, few relevant keywords, mostly restates title
27-
**2-1 (Very Poor)**: Vague or misleading, no clear value proposition, poor keyword usage, completely redundant with title
28-
29-
## Analysis process
30-
31-
1. **Content resolution**: Keep {% data variables.* %} and {% data reusables.* %} but avoid {% ifversion %} blocks
32-
2. **Content analysis**: Identify the article's purpose, target audience, key concepts, and user outcomes
33-
3. **Category detection**: For index pages, analyze child content themes and collective value
34-
35-
4. **SEO optimization**: Use strong action verbs, developer-friendly language, concrete outcomes, and relevant keywords while avoiding corporate buzzwords
5+
## Core Requirements
6+
7+
**Primary constraints (must-haves):**
8+
* Start with action verb ("Learn," "Access," "Explore," "Configure," "Set up," "Build")
9+
* One sentence maximum - NO colons, NO detailed explanations
10+
* Avoid buzzwords: "leverage," "optimize," "maximize," "enhance," "streamline," "empower," "revolutionize," "seamlessly," "comprehensive," "enterprise-grade," "cutting-edge," "innovative," "game-changing," "next-generation," "world-class," "best-in-class," "state-of-the-art," "industry-leading," "robust," "scalable," "mission-critical," "synergistic," "holistic," "strategic," "transformative"
11+
* Different approach than title - don't start with same words/phrases
12+
* Lists 2-3 concrete outcomes maximum
13+
14+
**Secondary optimizations (nice-to-haves):**
15+
* Include relevant keywords naturally
16+
* Version-agnostic ({% data variables.* %} OK, avoid {% ifversion %})
17+
* Follow Google snippet guidelines
18+
* Cut unnecessary words ruthlessly
3619

3720
**Content Summarization vs. Title Restatement**:
3821

@@ -47,32 +30,21 @@ Generate a single, concise intro (one simple sentence maximum - NO colons, NO de
4730
- Better: "Use {% data variables.product.prodname_copilot %} chat and code completion to research syntax, practice coding, and master new programming languages faster"
4831

4932
**Use concise, developer-friendly language ({% data variables.* %} OK)**:
50-
- Better intro: "Evaluate use cases, configure security settings, and run pilot trials to successfully deploy {% data variables.copilot.copilot_coding_agent %} in your org"
33+
- Better intro: "Evaluate use cases, configure security settings, and run pilot trials to deploy {% data variables.copilot.copilot_coding_agent %} in your org"
5134

5235
**Avoid overly long lists and colon constructions**:
5336
- Too long: "Scope issues, pick suitable tasks, iterate via PR comments, add repo instructions, enable MCP tools, and preinstall dependencies"
5437
- Colon problem: "Learn a new programming language with {% data variables.product.prodname_copilot %}: use {% data variables.copilot.copilot_chat_short %} to research syntax and tooling, build and explain small programs with {% data variables.product.prodname_copilot_short %} code completion, and translate familiar code to compare patterns"
5538
- Better: "Scope tasks, configure custom instructions, and iterate on pull requests to improve {% data variables.copilot.copilot_coding_agent %} performance"
5639
- Better: "Use {% data variables.product.prodname_copilot %} features like chat and code completion to research syntax, build programs, and learn new programming languages faster"
5740

58-
**Tone Guidelines**:
59-
- **Developer-friendly**: Use direct, practical language
60-
- **Concise over complete**: Cut words ruthlessly
61-
- **Action-oriented**: List what users will actually do
62-
- **Avoid buzzwords**: Skip marketing language and corporate jargon
63-
- **Use concrete verbs**: Instead of "maximize/optimize/enhance" → use "improve," "boost," "increase," or just describe the outcome directly
64-
- **Limit lists**: Maximum 2-3 items in comma-separated lists - prefer flowing sentences over exhaustive enumerations
65-
- **Avoid colon constructions**: Don't use "Do X: detailed explanation of A, B, and C" format - keep it simple and direct
66-
- **Avoid title similarity**: Don't start with the same words/phrases as the article title - approach the topic from a different angle
67-
68-
The intro should answer: "What specific steps will I take?" rather than "What will this comprehensive solution provide?"
69-
70-
## Analysis Process
41+
## Quality Checklist
7142

72-
1. **First Draft**: Generate an initial improved intro following all guidelines above
73-
2. **Title Check**: Compare your draft to the article title - if it starts with similar words, rewrite with a different approach
74-
3. **Self-Review**: Evaluate your draft against the SEO scoring criteria and tone guidelines
75-
4. **Refinement**: If the draft contains buzzwords, weak verbs, title similarity, or scores below 8/10, create a refined version
43+
**Structure**: Action verb + 2-3 concrete outcomes + under 350 characters
44+
**Language**: Direct, practical developer language (no marketing jargon)
45+
**Focus**: What users will DO, not what solution "provides"
46+
**Uniqueness**: Different angle from article title
47+
**Simplicity**: No colons, no complex lists, flowing sentences
7648

7749
## Output format
7850

@@ -84,27 +56,12 @@ Title: "[Article title from frontmatter]"
8456
8557
Original intro: "[Current intro from the article, or "No intro" if none exists]"
8658
87-
88-
Original SEO score: [X]/10
89-
------------------------
90-
91-
Improved intro: "[Single, concise intro that summarizes the article's full content value, not just restating the title]"
92-
93-
94-
Improved SEO score: [X]/10
59+
SEO-friendly alternative: "[Single, concise intro that summarizes the article's full content value, not just restating the title]"
9560
------------------------
9661
```
9762

98-
Note: The improved score should reflect your best attempt after internal refinement.
99-
10063
## Character limits by content type
10164

102-
**Priority: Conciseness over character limits**
103-
- Focus on being as concise as possible while maintaining clarity
104-
- Cut every unnecessary word before considering length
105-
- Developer-friendly brevity trumps hitting character targets
106-
107-
**Technical limits** (for reference):
10865
- **Articles**: Maximum 354 characters
10966
- **Categories**: Maximum 362 characters
11067
- **Map Topics**: Maximum 362 characters
@@ -124,4 +81,18 @@ Note: The improved score should reflect your best attempt after internal refinem
12481
- {% data variables.product.prodname_copilot %} = "GitHub Copilot"
12582
- {% data variables.copilot.copilot_coding_agent %} = "Copilot Coding Agent"
12683

127-
Focus on creating intros that would make sense to someone discovering this content through Google search, clearly communicating the value and relevance of the article.
84+
Focus on creating intros that would make sense to someone discovering this content through Google search, clearly communicating the value and relevance of the article.
85+
86+
<!-- IF_WRITE_MODE -->
87+
88+
## WRITE MODE INSTRUCTIONS
89+
90+
**CRITICAL**: You are in write mode. Output ONLY the YAML frontmatter property to update.
91+
92+
- Return just: `intro: "your improved intro text"`
93+
- Do NOT include analysis, scoring, explanations, or formatting
94+
- Do NOT wrap in markdown code blocks or ```yaml
95+
- Do NOT include the analysis format shown above
96+
- Just return the clean YAML property line
97+
98+
<!-- END_WRITE_MODE -->

src/ai-tools/prompts/prompt-template.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ messages:
66
content: >-
77
Review this content file according to the provided system prompt.
88
{{input}}
9-
model: openai/gpt-5
9+
model: openai/gpt-4o # Reliable model that works
10+
temperature: 0.3 # Lower temperature for consistent results
11+
max_completion_tokens: 4000 # Maximum response length

0 commit comments

Comments
 (0)