forked from iarv/vscode-front-matter
Compare commits
3 Commits
main
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d3378896e | ||
|
|
37f248d13f | ||
|
|
3e4d17b2fc |
@@ -139,11 +139,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"frontMatter.sponsors.ai.enabled": {
|
||||
"frontMatter.ai.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "%setting.frontMatter.sponsors.ai.enabled.markdownDescription%",
|
||||
"scope": "Sponsors"
|
||||
"default": true,
|
||||
"markdownDescription": "%setting.frontMatter.ai.enabled.markdownDescription%"
|
||||
},
|
||||
"frontMatter.extensibility.scripts": {
|
||||
"type": "array",
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"setting.frontMatter.projects.markdownDescription": "Specify the list of projects to load in the Front Matter CMS. [Local](https://file%2B.vscode-resource.vscode-cdn.net/Users/eliostruyf/nodejs/frontmatter-test-projects/astro-blog/test.html) - [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.projects) - [View in VS Code](vscode://simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.projects%22%5D)",
|
||||
"setting.frontMatter.projects.items.properties.name.markdownDescription": "Specify the name of the project.",
|
||||
"setting.frontMatter.projects.items.properties.default.markdownDescription": "Specify if this project is the default project to load.",
|
||||
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "Specify if you want to enable AI suggestions. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.sponsors.ai.enabled%22%5D)",
|
||||
"setting.frontMatter.ai.enabled.markdownDescription": "Specify if you want to enable AI suggestions (requires GitHub Copilot extension). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.ai.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.ai.enabled%22%5D)",
|
||||
"setting.frontMatter.extensibility.scripts.markdownDescription": "Specify the list of scripts to load in the Front Matter CMS. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.extensibility.scripts%22%5D)",
|
||||
"setting.frontMatter.experimental.markdownDescription": "Specify if you want to enable the experimental features. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.experimental%22%5D)",
|
||||
"setting.frontMatter.extends.markdownDescription": "Specify the list of paths/URLs to extend the Front Matter CMS config. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extends) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.extends%22%5D)",
|
||||
|
||||
@@ -117,14 +117,10 @@ export const SETTING_SNIPPETS_WRAPPER = 'snippets.wrapper.enabled';
|
||||
export const SETTING_WEBSITE_URL = 'website.host';
|
||||
|
||||
export const SETTING_COPILOT_FAMILY = 'copilot.family';
|
||||
export const SETTING_AI_ENABLED = 'ai.enabled';
|
||||
|
||||
export const SETTING_LOGGING = 'logging';
|
||||
|
||||
/**
|
||||
* Sponsors only settings
|
||||
*/
|
||||
export const SETTING_SPONSORS_AI_ENABLED = 'sponsors.ai.enabled';
|
||||
|
||||
/**
|
||||
* Project override support
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
SETTING_GLOBAL_TIMEZONE,
|
||||
SETTING_PANEL_ACTIONS_DISABLED,
|
||||
SETTING_SPONSORS_AI_ENABLED,
|
||||
SETTING_AI_ENABLED,
|
||||
SETTING_WEBSITE_URL
|
||||
} from './../constants/settings';
|
||||
import { workspace } from 'vscode';
|
||||
@@ -52,7 +52,7 @@ export class PanelSettings {
|
||||
|
||||
try {
|
||||
return {
|
||||
aiEnabled: Settings.get<boolean>(SETTING_SPONSORS_AI_ENABLED) || false,
|
||||
aiEnabled: Settings.get<boolean>(SETTING_AI_ENABLED) !== false,
|
||||
copilotEnabled: await Copilot.isInstalled(),
|
||||
git: await GitListener.getSettings(),
|
||||
seo: {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { authentication, QuickPickItem, QuickPickItemKind, window } from 'vscode';
|
||||
import { Folders } from '../commands/Folders';
|
||||
import { SETTING_SPONSORS_AI_ENABLED } from '../constants';
|
||||
import { SETTING_AI_ENABLED } from '../constants';
|
||||
import { ContentType } from './ContentType';
|
||||
import { Notifications } from './Notifications';
|
||||
import { Settings } from './SettingsHelper';
|
||||
import { Logger } from './Logger';
|
||||
import { SponsorAi } from '../services/SponsorAI';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../localization';
|
||||
import { ContentFolder } from '../models';
|
||||
@@ -40,56 +39,30 @@ export class Questions {
|
||||
* @returns
|
||||
*/
|
||||
public static async ContentTitle(showWarning = true): Promise<string | undefined> {
|
||||
const aiEnabled = Settings.get<boolean>(SETTING_SPONSORS_AI_ENABLED);
|
||||
const aiEnabled = Settings.get<boolean>(SETTING_AI_ENABLED);
|
||||
let title: string | undefined = '';
|
||||
const isCopilotInstalled = await Copilot.isInstalled();
|
||||
|
||||
let aiTitles: string[] | undefined;
|
||||
|
||||
if (aiEnabled || isCopilotInstalled) {
|
||||
if (isCopilotInstalled) {
|
||||
title = await window.showInputBox({
|
||||
title: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputTitle),
|
||||
prompt: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPrompt),
|
||||
placeHolder: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPlaceholder),
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
// Only show AI suggestions if both the setting is enabled and Copilot is installed
|
||||
if (aiEnabled !== false && isCopilotInstalled) {
|
||||
title = await window.showInputBox({
|
||||
title: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputTitle),
|
||||
prompt: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPrompt),
|
||||
placeHolder: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPlaceholder),
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
|
||||
if (title) {
|
||||
try {
|
||||
aiTitles = await Copilot.suggestTitles(title);
|
||||
} catch (e) {
|
||||
Logger.error((e as Error).message);
|
||||
Notifications.error(
|
||||
l10n.t(LocalizationKey.helpersQuestionsContentTitleCopilotInputFailed)
|
||||
);
|
||||
title = undefined;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const githubAuth = await authentication.getSession('github', ['read:user'], {
|
||||
silent: true
|
||||
});
|
||||
|
||||
if (githubAuth && githubAuth.account.label) {
|
||||
title = await window.showInputBox({
|
||||
title: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputTitle),
|
||||
prompt: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPrompt),
|
||||
placeHolder: l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputPlaceholder),
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
|
||||
if (title) {
|
||||
try {
|
||||
aiTitles = await SponsorAi.getTitles(githubAuth.accessToken, title);
|
||||
} catch (e) {
|
||||
Logger.error((e as Error).message);
|
||||
Notifications.error(
|
||||
l10n.t(LocalizationKey.helpersQuestionsContentTitleAiInputFailed)
|
||||
);
|
||||
title = undefined;
|
||||
}
|
||||
}
|
||||
if (title) {
|
||||
try {
|
||||
aiTitles = await Copilot.suggestTitles(title);
|
||||
} catch (e) {
|
||||
Logger.error((e as Error).message);
|
||||
Notifications.error(
|
||||
l10n.t(LocalizationKey.helpersQuestionsContentTitleCopilotInputFailed)
|
||||
);
|
||||
title = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Folders } from '../../commands/Folders';
|
||||
import { Command } from '../../panelWebView/Command';
|
||||
import { CommandToCode } from '../../panelWebView/CommandToCode';
|
||||
import { BaseListener } from './BaseListener';
|
||||
import { Uri, authentication, commands, window } from 'vscode';
|
||||
import { Uri, commands, window } from 'vscode';
|
||||
import {
|
||||
ArticleHelper,
|
||||
Extension,
|
||||
@@ -40,7 +40,6 @@ import {
|
||||
import { encodeEmoji, fieldWhenClause, getTitleField } from '../../utils';
|
||||
import { PanelProvider } from '../../panelWebView/PanelProvider';
|
||||
import { MessageHandlerData } from '@estruyf/vscode';
|
||||
import { SponsorAi } from '../../services/SponsorAI';
|
||||
import { Terminal } from '../../services';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
@@ -102,9 +101,6 @@ export class DataListener extends BaseListener {
|
||||
case CommandToCode.getDataEntries:
|
||||
this.getDataFileEntries(msg.command, msg.requestId || '', msg.payload);
|
||||
break;
|
||||
case CommandToCode.aiSuggestDescription:
|
||||
this.aiSuggestTaxonomy(msg.command, msg.requestId);
|
||||
break;
|
||||
case CommandToCode.copilotSuggestDescription:
|
||||
this.copilotSuggestDescription(msg.command, msg.requestId);
|
||||
break;
|
||||
@@ -179,68 +175,6 @@ export class DataListener extends BaseListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggests taxonomy using AI.
|
||||
* @param command - The command string.
|
||||
* @param requestId - The optional request ID.
|
||||
*/
|
||||
private static async aiSuggestTaxonomy(command: string, requestId?: string) {
|
||||
if (!command || !requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extPath = Extension.getInstance().extensionPath;
|
||||
const panel = PanelProvider.getInstance(extPath);
|
||||
|
||||
const editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelDataListenerAiSuggestTaxonomyNoEditorError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
const article = ArticleHelper.getFrontMatter(editor);
|
||||
if (!article || !article.data) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelDataListenerAiSuggestTaxonomyNoDataError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
const githubAuth = await authentication.getSession('github', ['read:user'], { silent: true });
|
||||
if (!githubAuth || !githubAuth.accessToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
const titleField = getTitleField();
|
||||
|
||||
const suggestion = await SponsorAi.getDescription(
|
||||
githubAuth.accessToken,
|
||||
article.data[titleField] || '',
|
||||
article.content || ''
|
||||
);
|
||||
|
||||
if (!suggestion) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelDataListenerAiSuggestTaxonomyNoDataError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
payload: suggestion || []
|
||||
} as MessageHandlerData<string>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the information about the registered folders and its files
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { CommandToCode } from '../../panelWebView/CommandToCode';
|
||||
import { TagType } from '../../panelWebView/TagType';
|
||||
import { BaseListener } from './BaseListener';
|
||||
import { authentication, window } from 'vscode';
|
||||
import { window } from 'vscode';
|
||||
import { ArticleHelper, Extension, Settings, TaxonomyHelper } from '../../helpers';
|
||||
import { BlockFieldData, CustomTaxonomyData, PostMessageData, TaxonomyType } from '../../models';
|
||||
import { DataListener } from '.';
|
||||
import { SponsorAi } from '../../services/SponsorAI';
|
||||
import { PanelProvider } from '../../panelWebView/PanelProvider';
|
||||
import { MessageHandlerData } from '@estruyf/vscode';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
@@ -60,9 +59,6 @@ export class TaxonomyListener extends BaseListener {
|
||||
case CommandToCode.addToCustomTaxonomy:
|
||||
this.addCustomTaxonomy(msg.payload);
|
||||
break;
|
||||
case CommandToCode.aiSuggestTaxonomy:
|
||||
this.aiSuggestTaxonomy(msg.command, msg.requestId, msg.payload);
|
||||
break;
|
||||
case CommandToCode.copilotSuggestTaxonomy:
|
||||
this.copilotSuggestTaxonomy(msg.command, msg.requestId, msg.payload);
|
||||
break;
|
||||
@@ -120,73 +116,6 @@ export class TaxonomyListener extends BaseListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggests taxonomy based on the provided command, request ID, and tag type.
|
||||
*
|
||||
* @param command - The command to execute.
|
||||
* @param requestId - The ID of the request.
|
||||
* @param type - The type of tag.
|
||||
* @returns A Promise that resolves to void.
|
||||
*/
|
||||
private static async aiSuggestTaxonomy(command: string, requestId?: string, type?: TagType) {
|
||||
if (!command || !requestId || !type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extPath = Extension.getInstance().extensionPath;
|
||||
const panel = PanelProvider.getInstance(extPath);
|
||||
|
||||
const editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelTaxonomyListenerAiSuggestTaxonomyNoDataError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
const article = ArticleHelper.getFrontMatter(editor);
|
||||
if (!article || !article.data) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelTaxonomyListenerAiSuggestTaxonomyNoEditorError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
const githubAuth = await authentication.getSession('github', ['read:user'], { silent: true });
|
||||
if (!githubAuth || !githubAuth.accessToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
const titleField = getTitleField();
|
||||
const descriptionField = getDescriptionField();
|
||||
|
||||
const suggestions = await SponsorAi.getTaxonomySuggestions(
|
||||
githubAuth.accessToken,
|
||||
article.data[titleField] || '',
|
||||
article.data[descriptionField] || '',
|
||||
type
|
||||
);
|
||||
|
||||
if (!suggestions) {
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
error: l10n.t(LocalizationKey.listenersPanelTaxonomyListenerAiSuggestTaxonomyNoDataError)
|
||||
} as MessageHandlerData<string>);
|
||||
return;
|
||||
}
|
||||
|
||||
panel.getWebview()?.postMessage({
|
||||
command,
|
||||
requestId,
|
||||
payload: suggestions || []
|
||||
} as MessageHandlerData<string[]>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tags in the current document
|
||||
* @param tagType
|
||||
|
||||
@@ -40,8 +40,6 @@ export enum CommandToCode {
|
||||
getDataEntries = 'get-data-entries',
|
||||
generateSlug = 'generate-slug',
|
||||
stopServer = 'stop-server',
|
||||
aiSuggestTaxonomy = 'ai-suggest-taxonomy',
|
||||
aiSuggestDescription = 'ai-suggest-description',
|
||||
copilotSuggestTitle = 'copilot-suggest-title',
|
||||
copilotSuggestDescription = 'copilot-suggest-description',
|
||||
copilotSuggestTaxonomy = 'copilot-suggest-taxonomy',
|
||||
|
||||
@@ -260,13 +260,11 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
}
|
||||
|
||||
const suggestTaxonomy = useCallback(
|
||||
(aiType: 'ai' | 'copilot', type: TagType) => {
|
||||
(type: TagType) => {
|
||||
setLoading(localize(LocalizationKey.panelTagPickerAiGenerating));
|
||||
|
||||
const command =
|
||||
aiType === 'ai' ? CommandToCode.aiSuggestTaxonomy : CommandToCode.copilotSuggestTaxonomy;
|
||||
messageHandler
|
||||
.request<string[]>(command, type)
|
||||
.request<string[]>(CommandToCode.copilotSuggestTaxonomy, type)
|
||||
.then((values) => {
|
||||
setLoading(undefined);
|
||||
updateTaxonomy(values)
|
||||
@@ -311,22 +309,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{settings?.aiEnabled && (
|
||||
<button
|
||||
className="metadata_field__title__action"
|
||||
title={localize(
|
||||
LocalizationKey.panelTagPickerAiSuggest,
|
||||
label?.toLowerCase() || type.toLowerCase()
|
||||
)}
|
||||
type="button"
|
||||
onClick={() => suggestTaxonomy('ai', type)}
|
||||
disabled={!!loading}
|
||||
>
|
||||
<SparklesIcon />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{settings?.copilotEnabled && (
|
||||
{settings?.aiEnabled && settings?.copilotEnabled && (
|
||||
<button
|
||||
className="metadata_field__title__action"
|
||||
title={localize(
|
||||
@@ -334,7 +317,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
label?.toLowerCase() || type.toLowerCase()
|
||||
)}
|
||||
type="button"
|
||||
onClick={() => suggestTaxonomy('copilot', type)}
|
||||
onClick={() => suggestTaxonomy(type)}
|
||||
disabled={!!loading}
|
||||
>
|
||||
<CopilotIcon />
|
||||
|
||||
@@ -105,13 +105,11 @@ export const TextField: React.FunctionComponent<ITextFieldProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const suggestDescription = (type: 'ai' | 'copilot') => {
|
||||
const suggestDescription = () => {
|
||||
setLoading(localize(LocalizationKey.panelFieldsTextFieldAiGenerate));
|
||||
|
||||
messageHandler
|
||||
.request<string>(
|
||||
type === 'copilot' ? CommandToCode.copilotSuggestDescription : CommandToCode.aiSuggestDescription
|
||||
)
|
||||
.request<string>(CommandToCode.copilotSuggestDescription)
|
||||
.then((suggestion) => {
|
||||
setLoading(undefined);
|
||||
|
||||
@@ -132,24 +130,12 @@ export const TextField: React.FunctionComponent<ITextFieldProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{settings?.aiEnabled && settings.seo.descriptionField === name && (
|
||||
<button
|
||||
className="metadata_field__title__action inline-block text-[var(--vscode-editor-foreground)] disabled:opacity-50"
|
||||
title={localize(LocalizationKey.panelFieldsTextFieldAiMessage, label?.toLowerCase())}
|
||||
type="button"
|
||||
onClick={() => suggestDescription('ai')}
|
||||
disabled={!!loading}
|
||||
>
|
||||
<SparklesIcon />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{settings?.copilotEnabled && (
|
||||
{settings?.aiEnabled && settings?.copilotEnabled && (
|
||||
<button
|
||||
className="metadata_field__title__action inline-block text-[var(--vscode-editor-foreground)] disabled:opacity-50"
|
||||
title={localize(LocalizationKey.panelFieldsTextFieldCopilotMessage, label?.toLowerCase())}
|
||||
type="button"
|
||||
onClick={() => settings.seo.descriptionField === name ? suggestDescription('copilot') : suggestTitle()}
|
||||
onClick={() => settings.seo.descriptionField === name ? suggestDescription() : suggestTitle()}
|
||||
disabled={!!loading}
|
||||
>
|
||||
<CopilotIcon />
|
||||
|
||||
@@ -2,5 +2,4 @@ export * from './Credentials';
|
||||
export * from './ModeSwitch';
|
||||
export * from './PagesParser';
|
||||
export * from './PinnedItems';
|
||||
export * from './SponsorAI';
|
||||
export * from './Terminal';
|
||||
|
||||
Reference in New Issue
Block a user