diff --git a/CHANGELOG.md b/CHANGELOG.md index d0c7a3d2..f12ef193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## [10.6.0] - 2024-xx-xx + +### ✨ New features + +### 🎨 Enhancements + +- [#873](https://github.com/estruyf/vscode-front-matter/issues/873): Add retry logic to get the AI model for calling GitHub Copilot + +### ⚡️ Optimizations + +### 🐞 Fixes + ## [10.5.0] - 2024-10-21 - [Release notes](https://beta.frontmatter.codes/updates/v10.5.0) ### 🎨 Enhancements diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index bc356a01..15369a25 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -115,7 +115,12 @@ export class DataListener extends BaseListener { } private static async copilotSuggestTitle(command: string, requestId?: string, title?: string) { - if (!command || !requestId || !title) { + if (!command || !requestId) { + return; + } + + if (!title) { + this.sendRequestError(command, requestId, 'No title provided'); return; } diff --git a/src/services/Copilot.ts b/src/services/Copilot.ts index e1123553..1a07b212 100644 --- a/src/services/Copilot.ts +++ b/src/services/Copilot.ts @@ -4,7 +4,8 @@ import { LanguageModelChatResponse, extensions, lm, - version as VscodeVersion + version as VscodeVersion, + LanguageModelChat } from 'vscode'; import { Logger, Settings, TaxonomyHelper } from '../helpers'; import { @@ -14,6 +15,7 @@ import { } from '../constants'; import { TagType } from '../panelWebView/TagType'; import { TaxonomyType } from '../models'; +import { sleep } from '../utils'; export class Copilot { private static personality = @@ -51,7 +53,7 @@ export class Copilot { LanguageModelChatMessage.User(`The title of the blog post is """${title}""".`) ]; - const chatResponse = await this.getChatResponse(messages); + const chatResponse = await Copilot.getChatResponse(messages); if (!chatResponse) { return; } @@ -100,7 +102,7 @@ Response format: a single string wrapped in double quotes, e.g., "Boost your web ); } - const chatResponse = await this.getChatResponse(messages); + const chatResponse = await Copilot.getChatResponse(messages); if (!chatResponse) { return; @@ -179,7 +181,7 @@ Example: SEO, website optimization, digital marketing.` ); } - const chatResponse = await this.getChatResponse(messages); + const chatResponse = await Copilot.getChatResponse(messages); if (!chatResponse) { return; @@ -211,6 +213,9 @@ Example: SEO, website optimization, digital marketing.` try { const model = await this.getModel(); + if (!model) { + return; + } chatResponse = await model.sendRequest(messages, {}, new CancellationTokenSource().token); } catch (err) { Logger.error(`Copilot:getChatResponse:: ${(err as Error).message}`); @@ -229,7 +234,7 @@ Example: SEO, website optimization, digital marketing.` * Retrieves the chat model for the Copilot service. * @returns A Promise that resolves to the chat model. */ - private static async getModel() { + private static async getModel(retry = 0): Promise { // const models = await lm.selectChatModels(); // console.log(models); const [model] = await lm.selectChatModels({ @@ -237,6 +242,11 @@ Example: SEO, website optimization, digital marketing.` family: Settings.get(SETTING_COPILOT_FAMILY) || 'gpt-4o-mini' }); + if ((!model || !model.sendRequest) && retry <= 5) { + await sleep(1000); + return Copilot.getModel(retry + 1); + } + return model; } } diff --git a/src/utils/index.ts b/src/utils/index.ts index b7802850..f1013c87 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -20,6 +20,7 @@ export * from './readdirAsync'; export * from './renameAsync'; export * from './rmdirAsync'; export * from './sentryInit'; +export * from './sleep'; export * from './sortPages'; export * from './unlinkAsync'; export * from './writeFileAsync'; diff --git a/src/utils/sleep.ts b/src/utils/sleep.ts new file mode 100644 index 00000000..fe57bb62 --- /dev/null +++ b/src/utils/sleep.ts @@ -0,0 +1 @@ +export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));