ai-git-tools 2.0.44 → 2.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-git-tools",
3
- "version": "2.0.44",
3
+ "version": "2.0.46",
4
4
  "description": "AI-powered Git automation tools for commit messages and PR generation",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -42,6 +42,15 @@ export async function autodevCommand(issueInput, cliOptions = {}) {
42
42
  commitOnly: cliOptions.commitOnly ?? false,
43
43
  };
44
44
 
45
+ // 永遠顯示啟動設定,方便確認
46
+ console.log('📋 autodev 啟動設定:');
47
+ console.log(` AI 模型 : ${config.aiModel}`);
48
+ console.log(` 重試次數 : ${config.maxRetries}`);
49
+ console.log(` 測試框架 : ${options.framework ?? '自動偵測'}`);
50
+ console.log(` Commit : ${options.skipAll || options.skipCommit ? '跳過' : '自動'}`);
51
+ console.log(` PR : ${options.skipAll || options.skipPr || options.commitOnly ? '跳過' : '自動'}`);
52
+ if (options.dryRun) console.log(' ⚠️ 乾運行模式(不實際執行)');
53
+
45
54
  const workflow = new AutodevWorkflow(config);
46
55
  await workflow.execute(issueInput, options);
47
56
  } catch (error) {
@@ -7,39 +7,52 @@ import { CopilotClient } from '@github/copilot-sdk';
7
7
 
8
8
  export class AIClient {
9
9
  /**
10
- * 發送 prompt 並等待回應(帶重試機制和超時保護)
10
+ * 發送 prompt 並等待回應(帶重試機制)
11
+ *
12
+ * @param {string} prompt
13
+ * @param {string} model
14
+ * @param {number} maxRetries
15
+ * @param {number} timeout - 毫秒,會直接傳給 SDK 的 sendAndWait
11
16
  */
12
- static async sendAndWait(prompt, model = 'gpt-4.1', maxRetries = 3, timeout = 60000) {
17
+ static async sendAndWait(prompt, model = 'claude-sonnet-4.5', maxRetries = 3, timeout = 60000) {
13
18
  let lastError = null;
14
19
 
15
20
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
16
21
  const client = new CopilotClient();
22
+ let session = null;
17
23
  try {
18
- const session = await client.createSession({ model });
19
-
20
- // 使用 Promise.race 實現超時控制
21
- const responsePromise = session.sendAndWait({ prompt });
22
- const timeoutPromise = new Promise((_, reject) => {
23
- setTimeout(() => reject(new Error(`AI 請求超時 (${timeout}ms)`)), timeout);
24
+ session = await client.createSession({ model });
25
+
26
+ // 收集 session.error 事件(讓 lastError 包含細節)
27
+ session.on('session.error', (event) => {
28
+ lastError = new Error(event.data?.message || JSON.stringify(event.data));
24
29
  });
25
30
 
26
- const response = await Promise.race([responsePromise, timeoutPromise]);
31
+ // timeout 直接傳給 SDK,讓 SDK 管理逾時
32
+ const response = await session.sendAndWait({ prompt }, timeout);
33
+
34
+ // response 為 undefined 表示 session 結束但沒有助理回訊(通常是錯誤)
35
+ if (!response) {
36
+ throw new Error(`AI 未回傳任何訊息(model: ${model})`);
37
+ }
27
38
 
28
39
  const content = response?.data?.content || '';
40
+ if (!content) {
41
+ throw new Error('AI 回傳空內容');
42
+ }
29
43
  return content.trim();
44
+
30
45
  } catch (error) {
31
46
  lastError = error;
32
47
  if (attempt < maxRetries) {
33
- console.log(`⚠️ AI 請求失敗,重試第 ${attempt}/${maxRetries} 次...`);
48
+ console.log(`⚠️ AI 請求失敗,重試第 ${attempt}/${maxRetries} 次... (${error.message})`);
34
49
  await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
35
50
  }
36
51
  } finally {
37
- // 確保每次都關閉 client,無論成功或失敗
38
- try {
39
- await client.stop();
40
- } catch (e) {
41
- // 忽略關閉錯誤
52
+ if (session) {
53
+ try { await session.destroy(); } catch (_e) { /* 忽略 */ }
42
54
  }
55
+ try { await client.stop(); } catch (_e) { /* 忽略 */ }
43
56
  }
44
57
  }
45
58
 
@@ -197,7 +197,7 @@ export async function loadAutodevConfig() {
197
197
  verbose: false,
198
198
  projectRoot: process.cwd(),
199
199
  // AI 設定(可被 autodev 子區塊或全域 ai 區塊覆蓋)
200
- aiModel: 'gpt-4.1',
200
+ aiModel: 'claude-sonnet-4.5',
201
201
  maxRetries: 3,
202
202
  };
203
203
 
@@ -28,11 +28,15 @@ export class CodeGenerator {
28
28
  async generateCodeFiles(issueData, projectRoot = process.cwd()) {
29
29
  const prompt = this._buildPrompt(issueData, projectRoot);
30
30
 
31
- console.log(' 🤖 調用 AI 生成代碼框架(最多等待 3 分鐘)...');
31
+ const VALID_MODELS = ['gpt-4.1', 'gpt-4o', 'claude-haiku-4.5', 'claude-sonnet-4.5', 'o3', 'o4-mini'];
32
+ if (!VALID_MODELS.includes(this.model)) {
33
+ console.warn(` ⚠️ model「${this.model}」可能無效!支援的模型:${VALID_MODELS.join(', ')}`);
34
+ }
35
+ console.log(` 🤖 調用 AI 生成代碼框架(model: ${this.model},最多等待 3 分鐘)...`);
32
36
 
33
37
  let response;
34
38
  try {
35
- // 代碼生成需要較長時間,使用 180 秒 timeout
39
+ // 代碼生成需要較長時間,使用 180 秒 timeout(直接傳給 SDK)
36
40
  response = await AIClient.sendAndWait(
37
41
  prompt,
38
42
  this.model,
@@ -40,9 +44,11 @@ export class CodeGenerator {
40
44
  180_000
41
45
  );
42
46
  } catch (error) {
43
- // 顯示完整錯誤訊息方便除錯
44
- console.warn(` ⚠️ AI 調用失敗:${error.message}`);
45
- if (error.cause) console.warn(` 原因:${error.cause}`);
47
+ console.warn(` ❌ AI 調用最終失敗:${error.message}`);
48
+ console.warn(' 💡 排查建議:');
49
+ console.warn(` 1. 確認 model「${this.model}」已在你的 Copilot 方案中啟用`);
50
+ console.warn(' 2. 嘗試改用 gpt-4.1:在 .ai-git-config 的 autodev.aiModel 改為 "gpt-4.1"');
51
+ console.warn(' 3. 確認 gh auth status 有登入 GitHub');
46
52
  return [];
47
53
  }
48
54