From 700f17702306e95924440cb006ee3138dbeaf579 Mon Sep 17 00:00:00 2001 From: Junjie Li Date: Wed, 4 Sep 2024 19:11:12 +0800 Subject: [PATCH 01/21] docs: changelog new features sep --- packages/vscode-extension/PRERELEASE.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/vscode-extension/PRERELEASE.md b/packages/vscode-extension/PRERELEASE.md index c5085e678b..95b1d3dc4b 100644 --- a/packages/vscode-extension/PRERELEASE.md +++ b/packages/vscode-extension/PRERELEASE.md @@ -4,6 +4,15 @@ > Note: This changelog only includes the changes for the pre-release versions of Teams Toolkit. For the changelog of stable versions, please refer to the [Teams Toolkit Changelog](https://github.com/OfficeDev/TeamsFx/blob/dev/packages/vscode-extension/CHANGELOG.md). +### September 12, 2024 + +#### New Features +- **Author Instructions for Declarative Copilot via an External File**: Developers can now use an external file to author instructions for their declarative copilots and reference it in the manifest file. This has significantly imporved the authoring experience for long instructions comparing to using json files for authoring. +![External File](https://github.com/user-attachments/assets/fa13711c-fe8c-4155-bd7f-9e0a8e0ed606) + +- **Add a Plugin to Declarative Copilot**: Temas Toolkit now offers the capability for developers to add a plugin as a skill to the declarative copilot. Developers can either add a new API plugin using OpenAPI description document, or reference an existing API plugin via its manifest file. +![Add Plugin](https://github.com/user-attachments/assets/009a63d0-8bc0-4449-8ba6-cef25779c140) + ### August 14, 2024 #### New Features From 18bb2f16ac8451df794f3b6f787b9415e051cb27 Mon Sep 17 00:00:00 2001 From: Yuqi Zhou Date: Thu, 5 Sep 2024 11:31:53 +0800 Subject: [PATCH 02/21] refactor: feature flag --- packages/cli/src/commands/models/add.ts | 7 +------ packages/cli/src/commands/models/create.ts | 21 +++++++++---------- packages/fx-core/src/common/featureFlags.ts | 8 +------ packages/fx-core/src/question/constants.ts | 8 +++---- packages/fx-core/src/question/create.ts | 16 ++------------ packages/vscode-extension/package.json | 2 +- packages/vscode-extension/src/config.ts | 4 ---- .../src/treeview/account/m365Node.ts | 9 ++------ 8 files changed, 21 insertions(+), 54 deletions(-) diff --git a/packages/cli/src/commands/models/add.ts b/packages/cli/src/commands/models/add.ts index 89d7962022..11ea6d5622 100644 --- a/packages/cli/src/commands/models/add.ts +++ b/packages/cli/src/commands/models/add.ts @@ -4,14 +4,9 @@ import { CLICommand } from "@microsoft/teamsfx-api"; import { commands } from "../../resource"; import { addSPFxWebpartCommand } from "./addSPFxWebpart"; import { addPluginCommand } from "./addPlugin"; -import { isCopilotExtensionEnabled } from "@microsoft/teamsfx-core"; const adjustCommands = (): CLICommand[] => { - if (isCopilotExtensionEnabled()) { - return [addSPFxWebpartCommand, addPluginCommand]; - } else { - return [addSPFxWebpartCommand]; - } + return [addSPFxWebpartCommand, addPluginCommand]; }; export function addCommand(): CLICommand { return { diff --git a/packages/cli/src/commands/models/create.ts b/packages/cli/src/commands/models/create.ts index 73be9b2bdc..8cf606f934 100644 --- a/packages/cli/src/commands/models/create.ts +++ b/packages/cli/src/commands/models/create.ts @@ -14,7 +14,6 @@ import { CliQuestionName, CreateProjectInputs, CreateProjectOptions, - isCopilotExtensionEnabled, MeArchitectureOptions, QuestionNames, } from "@microsoft/teamsfx-core"; @@ -45,16 +44,16 @@ function adjustOptions(options: CLICommandOption[]) { } } - if (!isCopilotExtensionEnabled()) { - //skip Copilot extension questions if the feature flag is not enabled. - const questionsToDelete = [ - QuestionNames.ApiPluginType, - QuestionNames.WithPlugin, - QuestionNames.PluginManifestFilePath, - QuestionNames.PluginOpenApiSpecFilePath, - ]; - options = options.filter((option) => !questionsToDelete.includes(option.name as QuestionNames)); - } + // if (!isCopilotExtensionEnabled()) { + // //skip Copilot extension questions if the feature flag is not enabled. + // const questionsToDelete = [ + // QuestionNames.ApiPluginType, + // QuestionNames.WithPlugin, + // QuestionNames.PluginManifestFilePath, + // QuestionNames.PluginOpenApiSpecFilePath, + // ]; + // options = options.filter((option) => !questionsToDelete.includes(option.name as QuestionNames)); + // } return options; } diff --git a/packages/fx-core/src/common/featureFlags.ts b/packages/fx-core/src/common/featureFlags.ts index 3babe55cba..a1fdbe08f7 100644 --- a/packages/fx-core/src/common/featureFlags.ts +++ b/packages/fx-core/src/common/featureFlags.ts @@ -15,7 +15,6 @@ export class FeatureFlagName { static readonly OfficeAddin = "TEAMSFX_OFFICE_ADDIN"; static readonly CopilotExtension = "DEVELOP_COPILOT_EXTENSION"; static readonly CopilotPlugin = "DEVELOP_COPILOT_PLUGIN"; - static readonly DeclarativeCopilot = "TEAMSFX_DECLARATIVE_COPILOT"; static readonly SampleConfigBranch = "TEAMSFX_SAMPLE_CONFIG_BRANCH"; static readonly TestTool = "TEAMSFX_TEST_TOOL"; static readonly METestTool = "TEAMSFX_ME_TEST_TOOL"; @@ -49,10 +48,6 @@ export class FeatureFlags { name: FeatureFlagName.CopilotPlugin, defaultValue: "false", }; // old feature flag. Keep it for backwards compatibility. - static readonly DeclarativeCopilot = { - name: FeatureFlagName.DeclarativeCopilot, - defaultValue: "false", - }; // old feature flag. Keep it for backwards compatibility. static readonly TestTool = { name: FeatureFlagName.TestTool, defaultValue: "true" }; static readonly METestTool = { name: FeatureFlagName.METestTool, defaultValue: "true" }; static readonly OfficeAddin = { name: FeatureFlagName.OfficeAddin, defaultValue: "false" }; @@ -99,8 +94,7 @@ export class FeatureFlags { export function isCopilotExtensionEnabled(): boolean { return ( featureFlagManager.getBooleanValue(FeatureFlags.CopilotExtension) || - featureFlagManager.getBooleanValue(FeatureFlags.CopilotPlugin) || - featureFlagManager.getBooleanValue(FeatureFlags.DeclarativeCopilot) + featureFlagManager.getBooleanValue(FeatureFlags.CopilotPlugin) ); } diff --git a/packages/fx-core/src/question/constants.ts b/packages/fx-core/src/question/constants.ts index a46374a19d..f02f013e57 100644 --- a/packages/fx-core/src/question/constants.ts +++ b/packages/fx-core/src/question/constants.ts @@ -604,8 +604,10 @@ export class CapabilityOptions { static copilotExtensions(inputs?: Inputs): OptionItem[] { if (inputs && getRuntime(inputs) === RuntimeOptions.DotNet().id) { return [CapabilityOptions.apiPlugin()]; - } else { + } else if (isCopilotExtensionEnabled()) { return [CapabilityOptions.apiPlugin(), CapabilityOptions.declarativeCopilot()]; + } else { + return [CapabilityOptions.declarativeCopilot()]; } } @@ -655,9 +657,7 @@ export class CapabilityOptions { ...CapabilityOptions.tabs(), ...CapabilityOptions.collectMECaps(), ]; - if (isCopilotExtensionEnabled()) { - capabilityOptions.push(...CapabilityOptions.copilotExtensions()); - } + capabilityOptions.push(...CapabilityOptions.copilotExtensions()); capabilityOptions.push(...CapabilityOptions.customCopilots()); if (featureFlagManager.getBooleanValue(FeatureFlags.TdpTemplateCliTest)) { // test templates that are used by TDP integration only diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index 4d52801cd1..6b6ccffd93 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -25,11 +25,7 @@ import * as os from "os"; import * as path from "path"; import { ConstantString, SpecParserSource } from "../common/constants"; import { Correlator } from "../common/correlator"; -import { - FeatureFlags, - featureFlagManager, - isCopilotExtensionEnabled, -} from "../common/featureFlags"; +import { FeatureFlags, featureFlagManager } from "../common/featureFlags"; import { createContext } from "../common/globalVars"; import { getLocalizedString } from "../common/localizeUtils"; import { sampleProvider } from "../common/samples"; @@ -103,10 +99,7 @@ export function projectTypeQuestion(): SingleSelectQuestion { staticOptions: staticOptions, dynamicOptions: (inputs: Inputs) => { const staticOptions: OptionItem[] = []; - - if (isCopilotExtensionEnabled()) { - staticOptions.push(ProjectTypeOptions.copilotExtension(inputs.platform)); - } + staticOptions.push(ProjectTypeOptions.copilotExtension(inputs.platform)); if (getRuntime(inputs) === RuntimeOptions.NodeJS().id) { staticOptions.push(ProjectTypeOptions.customCopilot(inputs.platform)); @@ -1752,11 +1745,6 @@ export function createProjectCliHelpNode(): IQTreeNode { if (!featureFlagManager.getBooleanValue(FeatureFlags.CLIDotNet)) { deleteNames.push(QuestionNames.Runtime); } - if (!isCopilotExtensionEnabled()) { - deleteNames.push(QuestionNames.ApiPluginType); - deleteNames.push(QuestionNames.WithPlugin); - deleteNames.push(QuestionNames.ImportPlugin); - } trimQuestionTreeForCliHelp(node, deleteNames); return node; } diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index be8c64a722..ff5c75b084 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1536,7 +1536,7 @@ "fx-extension.developCopilotPlugin": { "type": "boolean", "default": false, - "markdownDescription": "Enable to develop Copilot extension (Reload Visual Studio Code after changing this setting to take effect). Get more info from [How to Extend Microsoft 365 Copilot](https://aka.ms/teamsfx-copilot-plugin)." + "markdownDescription": "Enable to develop Copilot plugin (Reload Visual Studio Code after changing this setting to take effect). Get more info from [How to Extend Microsoft 365 Copilot](https://aka.ms/teamsfx-copilot-plugin)." }, "fx-extension.logLevel": { "type": "string", diff --git a/packages/vscode-extension/src/config.ts b/packages/vscode-extension/src/config.ts index 7adfdeac6d..f1acc90db4 100644 --- a/packages/vscode-extension/src/config.ts +++ b/packages/vscode-extension/src/config.ts @@ -36,10 +36,6 @@ export class ConfigManager { ConfigurationKey.CopilotExtensionEnable, false ).toString(); - process.env["TEAMSFX_DECLARATIVE_COPILOT"] = this.getConfiguration( - ConfigurationKey.CopilotExtensionEnable, - false - ).toString(); } loadLogLevel() { const logLevel = this.getConfiguration(ConfigurationKey.LogLevel, "Info") as string; diff --git a/packages/vscode-extension/src/treeview/account/m365Node.ts b/packages/vscode-extension/src/treeview/account/m365Node.ts index 5237df3e43..86129fbddd 100644 --- a/packages/vscode-extension/src/treeview/account/m365Node.ts +++ b/packages/vscode-extension/src/treeview/account/m365Node.ts @@ -71,11 +71,7 @@ export class M365AccountNode extends DynamicNode { this.sideloadingNode.token = token; refreshSideloading = true; } - if ( - featureFlagManager.getBooleanValue(FxCoreFeatureFlags.CopilotExtension) && - copilot && - this.copilotNode !== undefined - ) { + if (copilot && this.copilotNode !== undefined) { this.copilotNode.token = token; refreshCopilot = true; } @@ -91,8 +87,7 @@ export class M365AccountNode extends DynamicNode { } public override getChildren(): vscode.ProviderResult { - return featureFlagManager.getBooleanValue(FxCoreFeatureFlags.CopilotExtension) && - this.copilotNode !== undefined + return this.copilotNode !== undefined ? [this.sideloadingNode, this.copilotNode] : [this.sideloadingNode]; } From c0f621ac5cfed35455b3d1d5dcaa51e68be7d90d Mon Sep 17 00:00:00 2001 From: Yuqi Zhou Date: Thu, 5 Sep 2024 14:03:45 +0800 Subject: [PATCH 03/21] refactor: skip single --- packages/api/src/qm/question.ts | 2 +- packages/fx-core/src/question/create.ts | 4 +++- packages/fx-core/src/ui/visitor.ts | 23 ++++++++++++++--------- packages/vscode-ui/src/visitor.ts | 24 ++++++++++++++++++++---- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/api/src/qm/question.ts b/packages/api/src/qm/question.ts index 9b2c7b87ca..4b0e04b210 100644 --- a/packages/api/src/qm/question.ts +++ b/packages/api/src/qm/question.ts @@ -226,7 +226,7 @@ export interface SingleSelectQuestion extends UserInputQuestion { * if true: single select question will be automatically answered with the single option; * if false: use still need to do the selection manually even there is no other choice. */ - skipSingleOption?: boolean; + skipSingleOption?: boolean | LocalFunc; /** * the command is only for CLI option description diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index 6b6ccffd93..f413557e93 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -259,7 +259,9 @@ export function capabilityQuestion(): SingleSelectQuestion { return getLocalizedString("core.createCapabilityQuestion.placeholder"); }, forgetLastValue: true, - skipSingleOption: true, + skipSingleOption: (inputs: Inputs): boolean => { + return isFromDevPortal(inputs); + }, }; } diff --git a/packages/fx-core/src/ui/visitor.ts b/packages/fx-core/src/ui/visitor.ts index d4e2e96431..4d9c42a996 100644 --- a/packages/fx-core/src/ui/visitor.ts +++ b/packages/fx-core/src/ui/visitor.ts @@ -31,14 +31,18 @@ import { } from "../error"; import { getValidationFunction, validate, validationUtils } from "./validationUtils"; -export function isAutoSkipSelect(q: Question): boolean { +async function isAutoSkipSelect(q: Question, inputs: Inputs): Promise { + let skipSingle = false; if (q.type === "singleSelect" || q.type === "multiSelect") { - const select = q; - if (select.skipSingleOption && select.staticOptions.length === 1) { - return true; + if (q.skipSingleOption !== undefined) { + if (typeof q.skipSingleOption === "function") { + skipSingle = await q.skipSingleOption(inputs); + } else { + skipSingle = q.skipSingleOption; + } } } - return false; + return skipSingle; } export function getSingleOption( @@ -104,11 +108,12 @@ export const questionVisitor: QuestionTreeVisitor = async function ( return ok({ type: "skip", result: inputs[question.name] }); } + const skipSingle = await isAutoSkipSelect(question, inputs); // non-interactive mode if (inputs.nonInteractive) { // first priority: use single option as value if (question.type === "singleSelect" || question.type === "multiSelect") { - if (question.skipSingleOption) { + if (skipSingle) { const options = await loadOptions(question, inputs); if (options.length === 0) { return err(new EmptyOptionError(question.name, "questionVisitor")); @@ -196,7 +201,7 @@ export const questionVisitor: QuestionTreeVisitor = async function ( if (!question.staticOptions || question.staticOptions.length === 0) { return err(new EmptyOptionError(question.name, "questionVisitor")); } - if (question.skipSingleOption && question.staticOptions.length === 1) { + if (skipSingle && question.staticOptions.length === 1) { const returnResult = getSingleOption(question, question.staticOptions); return ok({ type: "skip", result: returnResult }); } @@ -218,7 +223,7 @@ export const questionVisitor: QuestionTreeVisitor = async function ( totalSteps: totalSteps, buttons: question.buttons, validation: validationFunc, - skipSingleOption: question.skipSingleOption, + skipSingleOption: skipSingle, }); } else { const validationFunc = question.validation @@ -236,7 +241,7 @@ export const questionVisitor: QuestionTreeVisitor = async function ( step: step, totalSteps: totalSteps, validation: validationFunc, - skipSingleOption: question.skipSingleOption, + skipSingleOption: skipSingle, }); } } else if (question.type === "multiFile") { diff --git a/packages/vscode-ui/src/visitor.ts b/packages/vscode-ui/src/visitor.ts index 98be7f68d5..f9136518d2 100644 --- a/packages/vscode-ui/src/visitor.ts +++ b/packages/vscode-ui/src/visitor.ts @@ -28,6 +28,20 @@ import { import { DefaultLocalizer, Localizer } from "./localize"; import { getValidationFunction, validate, validationUtils } from "./validationUtils"; +async function isAutoSkipSelect(q: Question, inputs: Inputs): Promise { + let skipSingle = false; + if (q.type === "singleSelect" || q.type === "multiSelect") { + if (q.skipSingleOption !== undefined) { + if (typeof q.skipSingleOption === "function") { + skipSingle = await q.skipSingleOption(inputs); + } else { + skipSingle = q.skipSingleOption; + } + } + } + return skipSingle; +} + export class QuestionModelEngine { localizer: Localizer; constructor(localizer?: Localizer) { @@ -56,11 +70,13 @@ export class QuestionModelEngine { return ok({ type: "skip", result: inputs[question.name] }); } + const skipSingle = await isAutoSkipSelect(question, inputs); + // non-interactive mode if (inputs.nonInteractive) { // first priority: use single option as value if (question.type === "singleSelect" || question.type === "multiSelect") { - if (question.skipSingleOption) { + if (skipSingle) { const options = await loadOptions(question, inputs); if (options.length === 0) { return err(new EmptyOptionsError(question.name, "questionVisitor")); @@ -167,7 +183,7 @@ export class QuestionModelEngine { ) ); } - if (question.skipSingleOption && question.staticOptions.length === 1) { + if (skipSingle && question.staticOptions.length === 1) { const returnResult = getSingleOption(question, question.staticOptions); return ok({ type: "skip", result: returnResult }); } @@ -189,7 +205,7 @@ export class QuestionModelEngine { totalSteps: totalSteps, buttons: question.buttons, validation: validationFunc, - skipSingleOption: question.skipSingleOption, + skipSingleOption: skipSingle, }); } else { const validationFunc = question.validation @@ -207,7 +223,7 @@ export class QuestionModelEngine { step: step, totalSteps: totalSteps, validation: validationFunc, - skipSingleOption: question.skipSingleOption, + skipSingleOption: skipSingle, }); } } else if (question.type === "multiFile") { From 1c58403d374b5ff644a83e94e83db33fc09a7774 Mon Sep 17 00:00:00 2001 From: QinghuiMeng-M Date: Thu, 5 Sep 2024 13:27:30 +0800 Subject: [PATCH 04/21] remove confict dependency (#12336) --- templates/js/custom-copilot-rag-azure-ai-search/package.json.tpl | 1 - templates/js/custom-copilot-rag-customize/package.json.tpl | 1 - templates/js/custom-copilot-rag-microsoft365/package.json.tpl | 1 - .../ts/custom-copilot-assistant-assistants-api/package.json.tpl | 1 - templates/ts/custom-copilot-assistant-new/package.json.tpl | 1 - templates/ts/custom-copilot-basic/package.json.tpl | 1 - templates/ts/custom-copilot-rag-azure-ai-search/package.json.tpl | 1 - templates/ts/custom-copilot-rag-customize/package.json.tpl | 1 - templates/ts/custom-copilot-rag-microsoft365/package.json.tpl | 1 - 9 files changed, 9 deletions(-) diff --git a/templates/js/custom-copilot-rag-azure-ai-search/package.json.tpl b/templates/js/custom-copilot-rag-azure-ai-search/package.json.tpl index dc442456d7..d73deb7d08 100644 --- a/templates/js/custom-copilot-rag-azure-ai-search/package.json.tpl +++ b/templates/js/custom-copilot-rag-azure-ai-search/package.json.tpl @@ -30,7 +30,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/js/custom-copilot-rag-customize/package.json.tpl b/templates/js/custom-copilot-rag-customize/package.json.tpl index 9bf2fbfd81..b5b6bf642d 100644 --- a/templates/js/custom-copilot-rag-customize/package.json.tpl +++ b/templates/js/custom-copilot-rag-customize/package.json.tpl @@ -28,7 +28,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/js/custom-copilot-rag-microsoft365/package.json.tpl b/templates/js/custom-copilot-rag-microsoft365/package.json.tpl index 002cdca69d..f1a9f2b25b 100644 --- a/templates/js/custom-copilot-rag-microsoft365/package.json.tpl +++ b/templates/js/custom-copilot-rag-microsoft365/package.json.tpl @@ -29,7 +29,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-assistant-assistants-api/package.json.tpl b/templates/ts/custom-copilot-assistant-assistants-api/package.json.tpl index 4522c4ddc9..7e9278decc 100644 --- a/templates/ts/custom-copilot-assistant-assistants-api/package.json.tpl +++ b/templates/ts/custom-copilot-assistant-assistants-api/package.json.tpl @@ -29,7 +29,6 @@ "dependencies": { "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-assistant-new/package.json.tpl b/templates/ts/custom-copilot-assistant-new/package.json.tpl index d643e4dda6..d581a2ee3c 100644 --- a/templates/ts/custom-copilot-assistant-new/package.json.tpl +++ b/templates/ts/custom-copilot-assistant-new/package.json.tpl @@ -28,7 +28,6 @@ "dependencies": { "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-basic/package.json.tpl b/templates/ts/custom-copilot-basic/package.json.tpl index d643e4dda6..d581a2ee3c 100644 --- a/templates/ts/custom-copilot-basic/package.json.tpl +++ b/templates/ts/custom-copilot-basic/package.json.tpl @@ -28,7 +28,6 @@ "dependencies": { "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-rag-azure-ai-search/package.json.tpl b/templates/ts/custom-copilot-rag-azure-ai-search/package.json.tpl index e49f60335c..575055b1bf 100644 --- a/templates/ts/custom-copilot-rag-azure-ai-search/package.json.tpl +++ b/templates/ts/custom-copilot-rag-azure-ai-search/package.json.tpl @@ -31,7 +31,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-rag-customize/package.json.tpl b/templates/ts/custom-copilot-rag-customize/package.json.tpl index c59a3f97cf..2989836c72 100644 --- a/templates/ts/custom-copilot-rag-customize/package.json.tpl +++ b/templates/ts/custom-copilot-rag-customize/package.json.tpl @@ -29,7 +29,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { diff --git a/templates/ts/custom-copilot-rag-microsoft365/package.json.tpl b/templates/ts/custom-copilot-rag-microsoft365/package.json.tpl index 024aec6337..36cd8871b5 100644 --- a/templates/ts/custom-copilot-rag-microsoft365/package.json.tpl +++ b/templates/ts/custom-copilot-rag-microsoft365/package.json.tpl @@ -30,7 +30,6 @@ "@azure/search-documents": "^12.0.0", "@microsoft/teams-ai": "^1.1.0", "botbuilder": "^4.20.0", - "openai": "~4.28.4", "restify": "^10.0.0" }, "devDependencies": { From d1b5ef18e23372884f737754e1947f087103a2d5 Mon Sep 17 00:00:00 2001 From: Yuqi Zhou Date: Thu, 5 Sep 2024 14:32:40 +0800 Subject: [PATCH 05/21] test: fix ut test: ut test: ut test: ut --- packages/cli/tests/unit/commands.tests.ts | 34 ------------------- packages/fx-core/src/question/constants.ts | 7 ++-- .../driver/teamsApp/createAppPackage.test.ts | 2 -- packages/fx-core/tests/core/FxCore.test.ts | 8 +++++ .../fx-core/tests/question/create.test.ts | 13 ++++--- packages/fx-core/tests/ui/qm.visitor.test.ts | 34 +++++++++++++++++++ .../test/treeview/account/m365Node.test.ts | 4 +-- packages/vscode-ui/tests/qm.test.ts | 34 +++++++++++++++++++ 8 files changed, 89 insertions(+), 47 deletions(-) diff --git a/packages/cli/tests/unit/commands.tests.ts b/packages/cli/tests/unit/commands.tests.ts index 4a1528caf7..b108eb2c3e 100644 --- a/packages/cli/tests/unit/commands.tests.ts +++ b/packages/cli/tests/unit/commands.tests.ts @@ -99,40 +99,6 @@ describe("CLI commands", () => { telemetryProperties: {}, }; - const filteredQuestionNames = [ - QuestionNames.WithPlugin.toString(), - QuestionNames.ApiPluginType.toString(), - ]; - assert.isTrue( - ctx.command.options?.filter((o) => filteredQuestionNames.includes(o.name)).length === 0 - ); - - const res = await getCreateCommand().handler!(ctx); - assert.isTrue(res.isOk()); - }); - - it("createProjectOptions - need to adjust options when feature flag is enabled", async () => { - mockedEnvRestore = mockedEnv({ - [FeatureFlags.CopilotExtension.name]: "true", - }); - sandbox.stub(activate, "getFxCore").returns(new FxCore({} as any)); - sandbox.stub(FxCore.prototype, "createProject").resolves(ok({ projectPath: "..." })); - - const ctx: CLIContext = { - command: { ...getCreateCommand(), fullName: "new" }, - optionValues: {}, - globalOptionValues: {}, - argumentValues: [], - telemetryProperties: {}, - }; - - const filteredQuestionNames = [ - QuestionNames.WithPlugin.toString(), - QuestionNames.ApiPluginType.toString(), - ]; - assert.isTrue( - ctx.command.options?.filter((o) => filteredQuestionNames.includes(o.name)).length === 2 - ); const res = await getCreateCommand().handler!(ctx); assert.isTrue(res.isOk()); }); diff --git a/packages/fx-core/src/question/constants.ts b/packages/fx-core/src/question/constants.ts index f02f013e57..cb8b9b50cb 100644 --- a/packages/fx-core/src/question/constants.ts +++ b/packages/fx-core/src/question/constants.ts @@ -601,7 +601,10 @@ export class CapabilityOptions { return items; } - static copilotExtensions(inputs?: Inputs): OptionItem[] { + static copilotExtensions(inputs?: Inputs, isStatic?: boolean): OptionItem[] { + if (isStatic) { + return [CapabilityOptions.apiPlugin(), CapabilityOptions.declarativeCopilot()]; + } if (inputs && getRuntime(inputs) === RuntimeOptions.DotNet().id) { return [CapabilityOptions.apiPlugin()]; } else if (isCopilotExtensionEnabled()) { @@ -637,7 +640,7 @@ export class CapabilityOptions { ...CapabilityOptions.bots(inputs), ...CapabilityOptions.tabs(), ...CapabilityOptions.collectMECaps(), - ...CapabilityOptions.copilotExtensions(inputs), + ...CapabilityOptions.copilotExtensions(inputs, true), ...CapabilityOptions.customCopilots(), ...CapabilityOptions.tdpIntegrationCapabilities(), ]; diff --git a/packages/fx-core/tests/component/driver/teamsApp/createAppPackage.test.ts b/packages/fx-core/tests/component/driver/teamsApp/createAppPackage.test.ts index 3111741355..652d0d8688 100644 --- a/packages/fx-core/tests/component/driver/teamsApp/createAppPackage.test.ts +++ b/packages/fx-core/tests/component/driver/teamsApp/createAppPackage.test.ts @@ -14,7 +14,6 @@ import { MockedUserInteraction, } from "../../../plugins/solution/util"; import { FileNotFoundError, JSONSyntaxError } from "../../../../src/error/common"; -import { FeatureFlagName } from "../../../../src/common/featureFlags"; import { manifestUtils } from "../../../../src/component/driver/teamsApp/utils/ManifestUtils"; import { ok, Platform, PluginManifestSchema, TeamsAppManifest } from "@microsoft/teamsfx-api"; import AdmZip from "adm-zip"; @@ -35,7 +34,6 @@ describe("teamsApp/createAppPackage", async () => { const openapiServerPlaceholder = "TEAMSFX_TEST_API_URL"; beforeEach(() => { mockedEnvRestore = mockedEnv({ - [FeatureFlagName.CopilotExtension]: "true", ["CONFIG_TEAMS_APP_NAME"]: "fakeName", [openapiServerPlaceholder]: fakeUrl, ["APP_NAME_SUFFIX"]: "test", diff --git a/packages/fx-core/tests/core/FxCore.test.ts b/packages/fx-core/tests/core/FxCore.test.ts index 0ccb642b5a..14703ba55b 100644 --- a/packages/fx-core/tests/core/FxCore.test.ts +++ b/packages/fx-core/tests/core/FxCore.test.ts @@ -2015,6 +2015,10 @@ describe("getQuestions", async () => { "spfx-webpart-name", "spfx-folder", "me-architecture", + "with-plugin", + "api-plugin-type", + "plugin-manifest-path", + "plugin-opeanapi-spec-path", "api-auth", "custom-copilot-rag", "openapi-spec-location", @@ -2054,6 +2058,10 @@ describe("getQuestions", async () => { "spfx-webpart-name", "spfx-folder", "me-architecture", + "with-plugin", + "api-plugin-type", + "plugin-manifest-path", + "plugin-opeanapi-spec-path", "api-auth", "custom-copilot-rag", "openapi-spec-location", diff --git a/packages/fx-core/tests/question/create.test.ts b/packages/fx-core/tests/question/create.test.ts index f841b2db57..d5c07c3879 100644 --- a/packages/fx-core/tests/question/create.test.ts +++ b/packages/fx-core/tests/question/create.test.ts @@ -162,7 +162,7 @@ describe("scaffold question", () => { if (question.name === QuestionNames.ProjectType) { const select = question as SingleSelectQuestion; const options = await select.dynamicOptions!(inputs); - assert.isTrue(options.length === 5); + assert.isTrue(options.length === 6); assert.isUndefined((options as OptionItem[])[0].groupName); return ok({ type: "success", result: ProjectTypeOptions.bot().id }); } else if (question.name === QuestionNames.Capabilities) { @@ -217,7 +217,7 @@ describe("scaffold question", () => { if (question.name === QuestionNames.ProjectType) { const select = question as SingleSelectQuestion; const options = await select.dynamicOptions!(inputs); - assert.isTrue(options.length === 5); + assert.isTrue(options.length === 6); assert.isFalse((options[2] as OptionItem).detail?.includes("Copilot")); return ok({ type: "success", result: ProjectTypeOptions.me().id }); } else if (question.name === QuestionNames.Capabilities) { @@ -3104,10 +3104,9 @@ describe("scaffold question", () => { setTools(tools); beforeEach(() => { mockedEnvRestore = mockedEnv({ - [FeatureFlagName.CopilotExtension]: "true", + [FeatureFlagName.CopilotExtension]: "false", }); }); - afterEach(() => { if (mockedEnvRestore) { mockedEnvRestore(); @@ -3138,7 +3137,7 @@ describe("scaffold question", () => { } else if (question.name === QuestionNames.Capabilities) { const select = question as SingleSelectQuestion; const options = await select.dynamicOptions!(inputs); - assert.isTrue(options.length === 2); + assert.isTrue(options.length === 1); const title = typeof question.title === "function" ? await question.title(inputs) : question.title; assert.equal( @@ -3189,7 +3188,7 @@ describe("scaffold question", () => { } else if (question.name === QuestionNames.Capabilities) { const select = question as SingleSelectQuestion; const options = await select.dynamicOptions!(inputs); - assert.isTrue(options.length === 2); + assert.isTrue(options.length === 1); return ok({ type: "success", result: CapabilityOptions.declarativeCopilot().id }); } else if (question.name === QuestionNames.WithPlugin) { @@ -3421,7 +3420,7 @@ describe("scaffold question", () => { if (question.name === QuestionNames.ProjectType) { const select = question as SingleSelectQuestion; const options = await select.dynamicOptions!(inputs); - assert.isTrue(options.length === 6); + assert.isTrue(options.length === 7); assert.equal( getLocalizedString("core.createProjectQuestion.projectType.createGroup.title"), (options as OptionItem[])[0].groupName diff --git a/packages/fx-core/tests/ui/qm.visitor.test.ts b/packages/fx-core/tests/ui/qm.visitor.test.ts index 709c1a3a95..7aa33a4e87 100644 --- a/packages/fx-core/tests/ui/qm.visitor.test.ts +++ b/packages/fx-core/tests/ui/qm.visitor.test.ts @@ -250,6 +250,40 @@ describe("Question Model - Visitor Test", () => { assert.sameOrderedMembers(expectedSequence, actualSequence); }); + it("success: auto skip single option select with skipSingleOption being a function ", async () => { + const actualSequence: string[] = []; + sandbox.stub(mockUI, "selectOption").callsFake(async (config: SingleSelectConfig) => { + actualSequence.push(config.name); + return ok({ type: "success", result: `mocked value of ${config.name}` }); + }); + const root: IQTreeNode = { + data: { type: "group" }, + children: [], + }; + const num = 10; + const expectedSequence: string[] = []; + for (let i = 1; i <= num; ++i) { + const name = `${i}`; + const question = createSingleSelectQuestion(name); + if (i % 2 === 0) question.staticOptions = [`mocked value of ${name}`]; + else { + question.staticOptions = [`mocked value of ${name}`, `mocked value of ${name} - 2`]; + expectedSequence.push(name); + } + question.skipSingleOption = () => { + return true; + }; + root.children!.push({ data: question }); + } + const inputs = createInputs(); + const res = await traverse(root, inputs, mockUI); + assert.isTrue(res.isOk()); + for (let i = 1; i <= num; ++i) { + assert.isTrue(inputs[`${i}`] === `mocked value of ${i}`); + } + assert.sameOrderedMembers(expectedSequence, actualSequence); + }); + it("success: flat sequence with back operation", async () => { const actualSequence: string[] = []; let backed = false; diff --git a/packages/vscode-extension/test/treeview/account/m365Node.test.ts b/packages/vscode-extension/test/treeview/account/m365Node.test.ts index 05c0cbb43c..175b00a011 100644 --- a/packages/vscode-extension/test/treeview/account/m365Node.test.ts +++ b/packages/vscode-extension/test/treeview/account/m365Node.test.ts @@ -66,10 +66,10 @@ describe("m365Node", () => { const m365Node = new M365AccountNode(eventEmitter); m365Node.updateChecks("test token", false, false); chai.assert.isDefined(m365Node.getChildren()); - chai.assert.equal(1, (m365Node.getChildren() as any).length); + chai.assert.equal(2, (m365Node.getChildren() as any).length); m365Node.updateChecks("test token", true, false); chai.assert.isDefined(m365Node.getChildren()); - chai.assert.equal(1, (m365Node.getChildren() as any).length); + chai.assert.equal(2, (m365Node.getChildren() as any).length); sandbox.stub(featureFlagManager, "getBooleanValue").returns(true); const m365NodeWithCopilot = new M365AccountNode(eventEmitter); m365NodeWithCopilot.updateChecks("test token", false, true); diff --git a/packages/vscode-ui/tests/qm.test.ts b/packages/vscode-ui/tests/qm.test.ts index dab676b38b..b4054194de 100644 --- a/packages/vscode-ui/tests/qm.test.ts +++ b/packages/vscode-ui/tests/qm.test.ts @@ -258,6 +258,40 @@ describe("Question Model - Visitor Test", () => { assert.sameOrderedMembers(expectedSequence, actualSequence); }); + it("success: auto skip single option select with skipSingleOption being a function", async () => { + const actualSequence: string[] = []; + sandbox.stub(mockUI, "selectOption").callsFake(async (config: SingleSelectConfig) => { + actualSequence.push(config.name); + return ok({ type: "success", result: `mocked value of ${config.name}` }); + }); + const root: IQTreeNode = { + data: { type: "group" }, + children: [], + }; + const num = 10; + const expectedSequence: string[] = []; + for (let i = 1; i <= num; ++i) { + const name = `${i}`; + const question = createSingleSelectQuestion(name); + if (i % 2 === 0) question.staticOptions = [`mocked value of ${name}`]; + else { + question.staticOptions = [`mocked value of ${name}`, `mocked value of ${name} - 2`]; + expectedSequence.push(name); + } + question.skipSingleOption = () => { + return true; + }; + root.children!.push({ data: question }); + } + const inputs = createInputs(); + const res = await engine.traverse(root, inputs, mockUI); + assert.isTrue(res.isOk()); + for (let i = 1; i <= num; ++i) { + assert.isTrue(inputs[`${i}`] === `mocked value of ${i}`); + } + assert.sameOrderedMembers(expectedSequence, actualSequence); + }); + it("success: flat sequence with back operation", async () => { const actualSequence: string[] = []; let backed = false; From 636bd7a3b9f0719d1e26b90563b7d49af17939fc Mon Sep 17 00:00:00 2001 From: Yuqi Zhou Date: Fri, 6 Sep 2024 11:03:41 +0800 Subject: [PATCH 06/21] fix: instruction.txt --- .../{ => appPackage}/instruction.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename templates/ts/api-plugin-from-scratch-oauth/{ => appPackage}/instruction.txt (100%) diff --git a/templates/ts/api-plugin-from-scratch-oauth/instruction.txt b/templates/ts/api-plugin-from-scratch-oauth/appPackage/instruction.txt similarity index 100% rename from templates/ts/api-plugin-from-scratch-oauth/instruction.txt rename to templates/ts/api-plugin-from-scratch-oauth/appPackage/instruction.txt From bae2c2943578b25e94a64ed5b258ac19e23c02dd Mon Sep 17 00:00:00 2001 From: frankqianms Date: Fri, 6 Sep 2024 11:33:00 +0800 Subject: [PATCH 07/21] refactor: remove preview tag for Python templates --- packages/fx-core/src/question/create.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index f413557e93..319e9db92c 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -587,12 +587,7 @@ export function getLanguageOptions(inputs: Inputs): OptionItem[] { return [ { id: ProgrammingLanguage.JS, label: "JavaScript" }, { id: ProgrammingLanguage.TS, label: "TypeScript" }, - { - id: ProgrammingLanguage.PY, - label: "Python", - detail: "", - description: getLocalizedString("core.createProjectQuestion.option.description.preview"), - }, + { id: ProgrammingLanguage.PY, label: "Python" }, ]; } else { // other cases From 10b53e735cfc63e9b7bcb1b09f43a908fca38460 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Fri, 6 Sep 2024 12:51:46 +0800 Subject: [PATCH 08/21] fix(kiota): add auth actions in yaml files --- .../component/generator/apiSpec/generator.ts | 25 ++++ .../generator/apiSpecGenerator.test.ts | 122 ++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/packages/fx-core/src/component/generator/apiSpec/generator.ts b/packages/fx-core/src/component/generator/apiSpec/generator.ts index 0f3b4355fb..b50911e8ad 100644 --- a/packages/fx-core/src/component/generator/apiSpec/generator.ts +++ b/packages/fx-core/src/component/generator/apiSpec/generator.ts @@ -27,6 +27,7 @@ import { ResponseTemplatesFolderName, Result, SystemError, + UserError, Warning, err, ok, @@ -56,6 +57,7 @@ import { generateScaffoldingSummary, getEnvName, getParserOptions, + listOperations, updateForCustomApi, } from "./helper"; import { copilotGptManifestUtils } from "../../driver/teamsApp/utils/CopilotGptManifestUtils"; @@ -167,6 +169,29 @@ export class SpecGenerator extends DefaultTemplateGenerator { [telemetryProperties.templateName]: getTemplateInfosState.templateName, [telemetryProperties.isDeclarativeCopilot]: isDeclarativeCopilot.toString(), }); + + // For Kiota integration, we need to get auth info here + if ( + featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && + inputs[QuestionNames.ApiPluginManifestPath] + ) { + const operationsResult = await listOperations( + context, + inputs[QuestionNames.ApiSpecLocation], + inputs + ); + if (operationsResult.isErr()) { + const msg = operationsResult.error.map((e) => e.content).join("\n"); + return err(new UserError("generator", "ListOperationsFailed", msg)); + } + + const operations = operationsResult.value; + const authApi = operations.find((api) => !!api.data.authName); + if (authApi) { + authData = authApi.data; + } + } + const appName = inputs[QuestionNames.AppName]; let language = inputs[QuestionNames.ProgrammingLanguage] as ProgrammingLanguage; if (getTemplateInfosState.templateName !== forCustomCopilotRagCustomApi) { diff --git a/packages/fx-core/tests/component/generator/apiSpecGenerator.test.ts b/packages/fx-core/tests/component/generator/apiSpecGenerator.test.ts index 6a2df5377b..fb5e76b10c 100644 --- a/packages/fx-core/tests/component/generator/apiSpecGenerator.test.ts +++ b/packages/fx-core/tests/component/generator/apiSpecGenerator.test.ts @@ -60,6 +60,7 @@ import * as pluginGeneratorHelper from "../../../src/component/generator/apiSpec import mockedEnv, { RestoreFn } from "mocked-env"; import { FeatureFlagName } from "../../../src/common/featureFlags"; import * as commonUtils from "../../../src/common/utils"; +import * as helper from "../../../src/component/generator/apiSpec/helper"; const teamsManifest: TeamsAppManifest = { name: { @@ -1514,6 +1515,127 @@ describe("SpecGenerator", async () => { assert.equal(res.value[0].language, ProgrammingLanguage.CSharp); } }); + + it("happy path for kiota integration with auth", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.EnvFileFunc]: "true", + [FeatureFlagName.KiotaIntegration]: "true", + }); + const generator = new SpecGenerator(); + const context = createContext(); + const inputs: Inputs = { + platform: Platform.CLI, + projectPath: "./", + [QuestionNames.Capabilities]: CapabilityOptions.apiPlugin().id, + [QuestionNames.ApiPluginType]: ApiPluginStartOptions.apiSpec().id, + [QuestionNames.AppName]: "testapp", + [QuestionNames.ApiPluginManifestPath]: "ai-plugin.json", + }; + inputs[QuestionNames.ApiSpecLocation] = "test.yaml"; + sandbox.stub(helper, "listOperations").resolves( + ok([ + { + id: "operation1", + label: "operation1", + groupName: "1", + data: { + serverUrl: "https://server1", + authName: "auth", + authType: "apiKey", + }, + }, + ]) + ); + const res = await generator.getTemplateInfos(context, inputs, "."); + assert.isTrue(res.isOk()); + if (res.isOk()) { + assert.equal(res.value.length, 1); + assert.equal(res.value[0].templateName, "api-plugin-existing-api"); + assert.equal(res.value[0].replaceMap!["DeclarativeCopilot"], ""); + + let filterResult = res.value[0].filterFn!("declarativeCopilot.json.tpl"); + assert.isFalse(filterResult); + filterResult = res.value[0].filterFn!("test.json"); + assert.isTrue(filterResult); + filterResult = res.value[0].filterFn!("instruction.txt"); + assert.isFalse(filterResult); + } + }); + + it("happy path for kiota integration without auth", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.EnvFileFunc]: "true", + [FeatureFlagName.KiotaIntegration]: "true", + }); + const generator = new SpecGenerator(); + const context = createContext(); + const inputs: Inputs = { + platform: Platform.CLI, + projectPath: "./", + [QuestionNames.Capabilities]: CapabilityOptions.apiPlugin().id, + [QuestionNames.ApiPluginType]: ApiPluginStartOptions.apiSpec().id, + [QuestionNames.AppName]: "testapp", + [QuestionNames.ApiPluginManifestPath]: "ai-plugin.json", + }; + inputs[QuestionNames.ApiSpecLocation] = "test.yaml"; + sandbox.stub(helper, "listOperations").resolves( + ok([ + { + id: "operation1", + label: "operation1", + groupName: "1", + data: { + serverUrl: "https://server1", + }, + }, + ]) + ); + const res = await generator.getTemplateInfos(context, inputs, "."); + assert.isTrue(res.isOk()); + if (res.isOk()) { + assert.equal(res.value.length, 1); + assert.equal(res.value[0].templateName, "api-plugin-existing-api"); + assert.equal(res.value[0].replaceMap!["DeclarativeCopilot"], ""); + + let filterResult = res.value[0].filterFn!("declarativeCopilot.json.tpl"); + assert.isFalse(filterResult); + filterResult = res.value[0].filterFn!("test.json"); + assert.isTrue(filterResult); + filterResult = res.value[0].filterFn!("instruction.txt"); + assert.isFalse(filterResult); + } + }); + + it("parse failed for kiota integration", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.EnvFileFunc]: "true", + [FeatureFlagName.KiotaIntegration]: "true", + }); + const generator = new SpecGenerator(); + const context = createContext(); + const inputs: Inputs = { + platform: Platform.CLI, + projectPath: "./", + [QuestionNames.Capabilities]: CapabilityOptions.apiPlugin().id, + [QuestionNames.ApiPluginType]: ApiPluginStartOptions.apiSpec().id, + [QuestionNames.AppName]: "testapp", + [QuestionNames.ApiPluginManifestPath]: "ai-plugin.json", + }; + inputs[QuestionNames.ApiSpecLocation] = "test.yaml"; + sandbox.stub(helper, "listOperations").resolves( + err([ + { + type: ErrorType.SpecNotValid, + content: "test", + }, + ]) + ); + const res = await generator.getTemplateInfos(context, inputs, "."); + assert.isTrue(res.isErr()); + if (res.isErr()) { + assert.equal(res.error.name, "ListOperationsFailed"); + } + }); }); describe("SpecGenerator: post", function () { From dbc3d152f06a2173f3afc074fd0774ba51cc75c4 Mon Sep 17 00:00:00 2001 From: Junjie Li Date: Fri, 6 Sep 2024 18:36:11 +0800 Subject: [PATCH 09/21] docs: add bug fix for sep changelog --- packages/vscode-extension/PRERELEASE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/vscode-extension/PRERELEASE.md b/packages/vscode-extension/PRERELEASE.md index 95b1d3dc4b..b5d03c685f 100644 --- a/packages/vscode-extension/PRERELEASE.md +++ b/packages/vscode-extension/PRERELEASE.md @@ -13,6 +13,10 @@ - **Add a Plugin to Declarative Copilot**: Temas Toolkit now offers the capability for developers to add a plugin as a skill to the declarative copilot. Developers can either add a new API plugin using OpenAPI description document, or reference an existing API plugin via its manifest file. ![Add Plugin](https://github.com/user-attachments/assets/009a63d0-8bc0-4449-8ba6-cef25779c140) +#### Bug Fixes: +- Upgraded axios dependency used in Teams Toolkit to v1.7.6 to fix vulunerability issue. [#12306](https://github.com/OfficeDev/teams-toolkit/pull/12306) +- Changed a string when creating `AI Agent` without Assistant API for better clarity. [#12266](https://github.com/OfficeDev/teams-toolkit/pull/12266) + ### August 14, 2024 #### New Features From 0449b1213a6ad110bb62cd2b066c34b6a1770c86 Mon Sep 17 00:00:00 2001 From: Junjie Li Date: Fri, 6 Sep 2024 18:39:02 +0800 Subject: [PATCH 10/21] update language with copilot --- packages/vscode-extension/PRERELEASE.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/vscode-extension/PRERELEASE.md b/packages/vscode-extension/PRERELEASE.md index b5d03c685f..cfa67cfc78 100644 --- a/packages/vscode-extension/PRERELEASE.md +++ b/packages/vscode-extension/PRERELEASE.md @@ -7,15 +7,16 @@ ### September 12, 2024 #### New Features -- **Author Instructions for Declarative Copilot via an External File**: Developers can now use an external file to author instructions for their declarative copilots and reference it in the manifest file. This has significantly imporved the authoring experience for long instructions comparing to using json files for authoring. +- **External File Support for Declarative Copilot Instructions**: Developers now have the ability to use an external file to author instructions for their declarative copilots and reference it in the manifest file. This greatly improves the authoring experience for longer instructions compared to using JSON files. ![External File](https://github.com/user-attachments/assets/fa13711c-fe8c-4155-bd7f-9e0a8e0ed606) -- **Add a Plugin to Declarative Copilot**: Temas Toolkit now offers the capability for developers to add a plugin as a skill to the declarative copilot. Developers can either add a new API plugin using OpenAPI description document, or reference an existing API plugin via its manifest file. +- **Plugin Integration for Declarative Copilot**: Teams Toolkit now allows developers to add a plugin as a skill to the declarative copilot. Developers can either add a new API plugin using an OpenAPI description document or reference an existing API plugin via its manifest file. ![Add Plugin](https://github.com/user-attachments/assets/009a63d0-8bc0-4449-8ba6-cef25779c140) #### Bug Fixes: -- Upgraded axios dependency used in Teams Toolkit to v1.7.6 to fix vulunerability issue. [#12306](https://github.com/OfficeDev/teams-toolkit/pull/12306) -- Changed a string when creating `AI Agent` without Assistant API for better clarity. [#12266](https://github.com/OfficeDev/teams-toolkit/pull/12266) +- Upgraded the axios dependency used in Teams Toolkit to version 1.7.6 to fix a vulnerability issue. [#12306](https://github.com/OfficeDev/teams-toolkit/pull/12306) +- Changed a string for better clarity when creating an `AI Agent` without Assistant API. [#12266](https://github.com/OfficeDev/teams-toolkit/pull/12266) + ### August 14, 2024 From cce629f8d33815ffecc21f83ecf5abf3d3e179d7 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Fri, 6 Sep 2024 16:17:58 +0800 Subject: [PATCH 11/21] perf(kiota): add dc support for kiota integration --- packages/api/src/types.ts | 2 +- packages/fx-core/src/component/constants.ts | 5 ++ .../src/component/coordinator/index.ts | 13 ++- packages/fx-core/src/index.ts | 1 + packages/fx-core/src/question/create.ts | 36 +++++--- .../coordinator/coordinator.create.test.ts | 27 +++++- .../fx-core/tests/question/create.test.ts | 81 +++++++++++++++++ packages/vscode-extension/package.nls.json | 2 +- .../createPluginWithManifestHandler.ts | 21 ++++- .../src/handlers/lifecycleHandlers.ts | 5 +- .../createPluginWithManifestHandler.test.ts | 89 +++++++++++++++++-- .../test/handlers/lifecycleHandlers.test.ts | 6 +- 12 files changed, 252 insertions(+), 36 deletions(-) diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts index e4e5fa3a72..eae92190db 100644 --- a/packages/api/src/types.ts +++ b/packages/api/src/types.ts @@ -153,7 +153,7 @@ export interface CreateProjectResult { warnings?: Warning[]; shouldInvokeTeamsAgent?: boolean; projectId?: string; - createProjectForKiota?: boolean; + lastCommand?: string; } export interface TeamsAppInputs extends InputsWithProjectPath { diff --git a/packages/fx-core/src/component/constants.ts b/packages/fx-core/src/component/constants.ts index 0b13915dfb..2439ec8bb8 100644 --- a/packages/fx-core/src/component/constants.ts +++ b/packages/fx-core/src/component/constants.ts @@ -110,3 +110,8 @@ export enum BotScenario { export const AadConstants = { DefaultTemplateFileName: "aad.manifest.json", }; + +export const KiotaLastCommands = { + createPluginWithManifest: "createPluginWithManifest", + createDeclarativeCopilotWithManifest: "createDeclarativeCopilotWithManifest", +}; diff --git a/packages/fx-core/src/component/coordinator/index.ts b/packages/fx-core/src/component/coordinator/index.ts index b61f8b7536..f52dbd58af 100644 --- a/packages/fx-core/src/component/coordinator/index.ts +++ b/packages/fx-core/src/component/coordinator/index.ts @@ -41,13 +41,14 @@ import { LifeCycleUndefinedError } from "../../error/yml"; import { ApiPluginStartOptions, AppNamePattern, + CapabilityOptions, ProjectTypeOptions, QuestionNames, ScratchOptions, } from "../../question/constants"; import { ExecutionError, ExecutionOutput, ILifecycle } from "../configManager/interface"; import { Lifecycle } from "../configManager/lifecycle"; -import { CoordinatorSource } from "../constants"; +import { CoordinatorSource, KiotaLastCommands } from "../constants"; import { deployUtils } from "../deployUtils"; import { developerPortalScaffoldUtils } from "../developerPortalScaffoldUtils"; import { DriverContext } from "../driver/interface/commonArgs"; @@ -97,9 +98,15 @@ class Coordinator { inputs.platform === Platform.VSCode && featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.apiSpec().id && - !inputs[QuestionNames.ApiPluginManifestPath] + !inputs[QuestionNames.ApiPluginManifestPath] && + (inputs[QuestionNames.Capabilities] === CapabilityOptions.apiPlugin().id || + inputs[QuestionNames.Capabilities] === CapabilityOptions.declarativeCopilot().id) ) { - return ok({ projectPath: "", createProjectForKiota: true }); + const lastCommand = + inputs[QuestionNames.Capabilities] === CapabilityOptions.apiPlugin().id + ? KiotaLastCommands.createPluginWithManifest + : KiotaLastCommands.createDeclarativeCopilotWithManifest; + return ok({ projectPath: "", lastCommand: lastCommand }); } let folder = inputs["folder"] as string; diff --git a/packages/fx-core/src/index.ts b/packages/fx-core/src/index.ts index 17e544ac75..eda2caa269 100644 --- a/packages/fx-core/src/index.ts +++ b/packages/fx-core/src/index.ts @@ -107,3 +107,4 @@ export * from "./question/options"; export * from "./component/middleware/actionExecutionMW"; export { TemplateInfo } from "./component/generator/templates/templateInfo"; export { AadSet } from "./common/globalVars"; +export { KiotaLastCommands } from "./component/constants"; diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index 319e9db92c..d83d8a01a2 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -1545,10 +1545,18 @@ export function capabilitySubTree(): IQTreeNode { // from API spec condition: (inputs: Inputs) => { return ( - !featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && (inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.apiSpec().id || inputs[QuestionNames.MeArchitectureType] === MeArchitectureOptions.apiSpec().id || - inputs[QuestionNames.CustomCopilotRag] === CustomCopilotRagOptions.customApi().id) + inputs[QuestionNames.CustomCopilotRag] === CustomCopilotRagOptions.customApi().id) && + !( + // Only skip this project when need to rediect to Kiota: 1. Feature flag enabled 2. Creating plugin/declarative copilot from existing spec + ( + featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && + inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.apiSpec().id && + (inputs[QuestionNames.Capabilities] === CapabilityOptions.apiPlugin().id || + inputs[QuestionNames.Capabilities] === CapabilityOptions.declarativeCopilot().id) + ) + ) ); }, data: { type: "group", name: QuestionNames.FromExistingApi }, @@ -1638,11 +1646,13 @@ export function capabilitySubTree(): IQTreeNode { // root folder data: folderQuestion(), condition: (inputs: Inputs) => { - // Only skip this project when need to rediect to Kiota: 1. Feature flag enabled 2. Creating plugin from existing spec 3. No plugin manifest path - return ( - !featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) || - inputs[QuestionNames.ApiPluginType] !== ApiPluginStartOptions.apiSpec().id || - !!inputs[QuestionNames.ApiPluginManifestPath] + // Only skip this project when need to rediect to Kiota: 1. Feature flag enabled 2. Creating plugin/declarative copilot from existing spec 3. No plugin manifest path + return !( + featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && + inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.apiSpec().id && + (inputs[QuestionNames.Capabilities] === CapabilityOptions.apiPlugin().id || + inputs[QuestionNames.Capabilities] === CapabilityOptions.declarativeCopilot().id) && + !inputs[QuestionNames.ApiPluginManifestPath] ); }, }, @@ -1650,11 +1660,13 @@ export function capabilitySubTree(): IQTreeNode { // app name data: appNameQuestion(), condition: (inputs: Inputs) => { - // Only skip this project when need to rediect to Kiota: 1. Feature flag enabled 2. Creating plugin from existing spec 3. No plugin manifest path - return ( - !featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) || - inputs[QuestionNames.ApiPluginType] !== ApiPluginStartOptions.apiSpec().id || - !!inputs[QuestionNames.ApiPluginManifestPath] + // Only skip this project when need to rediect to Kiota: 1. Feature flag enabled 2. Creating plugin/declarative copilot from existing spec 3. No plugin manifest path + return !( + featureFlagManager.getBooleanValue(FeatureFlags.KiotaIntegration) && + inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.apiSpec().id && + (inputs[QuestionNames.Capabilities] === CapabilityOptions.apiPlugin().id || + inputs[QuestionNames.Capabilities] === CapabilityOptions.declarativeCopilot().id) && + !inputs[QuestionNames.ApiPluginManifestPath] ); }, }, diff --git a/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts b/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts index 855590a7e4..a422adb8c3 100644 --- a/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts +++ b/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts @@ -791,11 +791,10 @@ describe("coordinator create", () => { assert.isTrue(res.isErr()); }); - it("success for kiota integration", async () => { + it("success for kiota integration: plugin", async () => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.KiotaIntegration]: "true", }); - sandbox.stub(SPFxGeneratorNew.prototype, "run").resolves(ok({})); sandbox.stub(fs, "pathExists").resolves(true); sandbox.stub(coordinator, "ensureTrackingId").resolves(ok("mock-id")); const inputs: Inputs = { @@ -808,7 +807,29 @@ describe("coordinator create", () => { const res = await coordinator.create(context, inputs); assert.isTrue(res.isOk()); if (res.isOk()) { - assert.equal(res.value.createProjectForKiota, true); + assert.isNotNull(res.value.lastCommand); + assert.equal(res.value.projectPath, ""); + } + }); + + it("success for kiota integration: declarative copilot", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.KiotaIntegration]: "true", + }); + sandbox.stub(fs, "pathExists").resolves(true); + sandbox.stub(coordinator, "ensureTrackingId").resolves(ok("mock-id")); + const inputs: Inputs = { + platform: Platform.VSCode, + [QuestionNames.ProjectType]: ProjectTypeOptions.copilotExtension().id, + [QuestionNames.Capabilities]: CapabilityOptions.declarativeCopilot().id, + [QuestionNames.ApiPluginType]: ApiPluginStartOptions.apiSpec().id, + [QuestionNames.WithPlugin]: "yes", + }; + const context = createContext(); + const res = await coordinator.create(context, inputs); + assert.isTrue(res.isOk()); + if (res.isOk()) { + assert.isNotNull(res.value.lastCommand); assert.equal(res.value.projectPath, ""); } }); diff --git a/packages/fx-core/tests/question/create.test.ts b/packages/fx-core/tests/question/create.test.ts index d5c07c3879..7393ce2cf9 100644 --- a/packages/fx-core/tests/question/create.test.ts +++ b/packages/fx-core/tests/question/create.test.ts @@ -1699,6 +1699,43 @@ describe("scaffold question", () => { ]); }); + it("traverse in vscode Declarative Copilot from Kiota", async () => { + const inputs: Inputs = { + platform: Platform.VSCode, + }; + inputs[QuestionNames.Capabilities] = CapabilityOptions.declarativeCopilot().id; + inputs[QuestionNames.ApiSpecLocation] = "api-spec-path"; + inputs[QuestionNames.ApiPluginManifestPath] = "api-plugin-manifest-path"; + inputs[QuestionNames.ApiPluginType] = ApiPluginStartOptions.apiSpec().id; + inputs[QuestionNames.ApiOperation] = "api-plugin-manifest-path"; + inputs[QuestionNames.ProjectType] = ProjectTypeOptions.copilotExtension().id; + const questions: string[] = []; + const visitor: QuestionTreeVisitor = async ( + question: Question, + ui: UserInteraction, + inputs: Inputs, + step?: number, + totalSteps?: number + ) => { + questions.push(question.name); + await callFuncs(question, inputs); + if (question.name === QuestionNames.Folder) { + return ok({ type: "success", result: "./" }); + } else if (question.name === QuestionNames.AppName) { + return ok({ type: "success", result: "test001" }); + } + return ok({ type: "success", result: undefined }); + }; + await traverse(createProjectQuestionNode(), inputs, ui, undefined, visitor); + assert.deepEqual(questions, [ + QuestionNames.ProjectType, + QuestionNames.Capabilities, + QuestionNames.ApiSpecLocation, + QuestionNames.Folder, + QuestionNames.AppName, + ]); + }); + it("traverse in vscode Copilot Plugin to Kiota", async () => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.KiotaIntegration]: "true", @@ -1740,6 +1777,50 @@ describe("scaffold question", () => { ]); }); + it("traverse in vscode Declarative Copilot to Kiota", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.KiotaIntegration]: "true", + }); + const inputs: Inputs = { + platform: Platform.VSCode, + }; + + const questions: string[] = []; + const visitor: QuestionTreeVisitor = async ( + question: Question, + ui: UserInteraction, + inputs: Inputs, + step?: number, + totalSteps?: number + ) => { + questions.push(question.name); + await callFuncs(question, inputs); + if (question.name === QuestionNames.ProjectType) { + const select = question as SingleSelectQuestion; + const options = await select.dynamicOptions!(inputs); + assert.isTrue(options.length === 6); + return ok({ type: "success", result: ProjectTypeOptions.copilotExtension().id }); + } else if (question.name === QuestionNames.Capabilities) { + const select = question as SingleSelectQuestion; + const options = await select.dynamicOptions!(inputs); + assert.isTrue(options.length === 2); + return ok({ type: "success", result: CapabilityOptions.declarativeCopilot().id }); + } else if (question.name === QuestionNames.ApiPluginType) { + return ok({ type: "success", result: ApiPluginStartOptions.apiSpec().id }); + } else if (question.name === QuestionNames.WithPlugin) { + return ok({ type: "success", result: "yes" }); + } + return ok({ type: "success", result: undefined }); + }; + await traverse(createProjectQuestionNode(), inputs, ui, undefined, visitor); + assert.deepEqual(questions, [ + QuestionNames.ProjectType, + QuestionNames.Capabilities, + QuestionNames.WithPlugin, + QuestionNames.ApiPluginType, + ]); + }); + it("traverse in vscode Copilot Plugin from new API with API Key authentication", async () => { const inputs: Inputs = { platform: Platform.VSCode, diff --git a/packages/vscode-extension/package.nls.json b/packages/vscode-extension/package.nls.json index 67cab3527a..2cfc99f6a1 100644 --- a/packages/vscode-extension/package.nls.json +++ b/packages/vscode-extension/package.nls.json @@ -552,6 +552,6 @@ "teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppResources.title": "Intelligent App Resources", "teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppResources.description": "Explore these resources to build intelligent apps and enhance your development projects\n🗒️ [Generative AI for Beginners](https://github.com/microsoft/generative-ai-for-beginners/tree/main)\n✨ [Retrieval Augmented Generation (RAG)](https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview)\n📚 [AI Learning and Community Hub](https://learn.microsoft.com/en-us/ai/)", "teamstoolkit.m365.needSignIn.message": "You need to sign in your Microsoft 365 account.", - "teamstoolkit.handler.createPluginWithManifest.error.missingParameter": "Missing parameter in the createPluginWithManifest command. Usage: createPluginWithManifest(API_SPEC_PATH:string, PLUGIN_MANIFEST_PATH: string, OUTPUT_FOLDER: string).", + "teamstoolkit.handler.createPluginWithManifest.error.missingParameter": "Invalid parameter in the createPluginWithManifest command. Usage: createPluginWithManifest(API_SPEC_PATH:string, PLUGIN_MANIFEST_PATH: string, { lastCommand: string }, OUTPUT_FOLDER?: string). Valid values for LAST_COMMAND: createPluginWithManifest, createDeclarativeCopilotWithManifest.", "teamstoolkit.error.KiotaNotInstalled": "You need to install Microsoft Kiota extension to use this feature." } diff --git a/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts b/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts index 31f75e083a..742330001d 100644 --- a/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts +++ b/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts @@ -14,6 +14,7 @@ import { getSystemInputs } from "../utils/systemEnvUtils"; import { ApiPluginStartOptions, CapabilityOptions, + KiotaLastCommands, ProjectTypeOptions, QuestionNames, } from "@microsoft/teamsfx-core"; @@ -35,10 +36,16 @@ export async function createPluginWithManifest(args?: any[]): Promise 3) { + if ( + !args || + args.length < 3 || + args.length > 4 || + !args[2].lastCommand || + !Object.values(KiotaLastCommands).includes(args[2].lastCommand) + ) { const error = new UserError( ExtensionSource, - "missingParameter", + "invlaidParameter", localize("teamstoolkit.handler.createPluginWithManifest.error.missingParameter") ); ExtTelemetry.sendTelemetryErrorEvent(TelemetryEvent.CreatePluginWithManifest, error); @@ -47,10 +54,16 @@ export async function createPluginWithManifest(args?: any[]): Promise { const core = new MockCore(); sandbox.stub(globalVariables, "core").value(core); const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); - const res = await createPluginWithManifest(["specPath", "pluginManifestPath"]); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + lastCommand: "createPluginWithManifest", + }, + ]); + chai.assert.isTrue(res.isOk()); + chai.assert.isTrue(openFolder.calledOnce); + }); + + it("happy path: successfullly create declarative copilot project", async () => { + const core = new MockCore(); + sandbox.stub(globalVariables, "core").value(core); + const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + lastCommand: "createDeclarativeCopilotWithManifest", + }, + ]); chai.assert.isTrue(res.isOk()); chai.assert.isTrue(openFolder.calledOnce); }); @@ -37,12 +58,19 @@ describe("createPluginWithManifestHandler", () => { const core = new MockCore(); sandbox.stub(globalVariables, "core").value(core); const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); - const res = await createPluginWithManifest(["specPath", "pluginManifestPath", "folder"]); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + lastCommand: "createPluginWithManifest", + }, + "folder", + ]); chai.assert.isTrue(res.isOk()); chai.assert.isTrue(openFolder.calledOnce); }); - it("should throw error if args length is less than 2", async () => { + it("should throw error if args length is less than 3", async () => { const core = new MockCore(); sandbox.stub(globalVariables, "core").value(core); const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); @@ -50,24 +78,63 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "missingParameter"); + chai.assert.equal(res.error.name, "invlaidParameter"); } }); - it("should throw error if args length is bigger than 3", async () => { + it("should throw error if args length is bigger than 4", async () => { const core = new MockCore(); sandbox.stub(globalVariables, "core").value(core); const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); const res = await createPluginWithManifest([ "specPath", "pluginManifestPath", + { + lastCommand: "createPluginWithManifest", + }, "folder", "extra", ]); chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "missingParameter"); + chai.assert.equal(res.error.name, "invlaidParameter"); + } + }); + + it("should throw error if command name missing", async () => { + const core = new MockCore(); + sandbox.stub(globalVariables, "core").value(core); + const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + test: "test", + }, + ]); + chai.assert.isTrue(res.isErr()); + chai.assert.isTrue(openFolder.notCalled); + if (res.isErr()) { + chai.assert.equal(res.error.name, "invlaidParameter"); + } + }); + + it("should throw error if command name invalid", async () => { + const core = new MockCore(); + sandbox.stub(globalVariables, "core").value(core); + const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + lastCommand: "test", + }, + ]); + chai.assert.isTrue(res.isErr()); + chai.assert.isTrue(openFolder.notCalled); + if (res.isErr()) { + chai.assert.equal(res.error.name, "invlaidParameter"); } }); @@ -79,7 +146,7 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "missingParameter"); + chai.assert.equal(res.error.name, "invlaidParameter"); } }); @@ -90,7 +157,13 @@ describe("createPluginWithManifestHandler", () => { .stub(globalVariables.core, "createProject") .resolves(err(new UserError("core", "fakeError", "fakeErrorMessage"))); const openFolder = sandbox.stub(workspaceUtils, "openFolder").resolves(); - const res = await createPluginWithManifest(["specPath", "pluginManifestPath", true]); + const res = await createPluginWithManifest([ + "specPath", + "pluginManifestPath", + { + lastCommand: "createPluginWithManifest", + }, + ]); chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { diff --git a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts index 79f9739f88..8db027c3c6 100644 --- a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts +++ b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts @@ -131,7 +131,7 @@ describe("Lifecycle handlers", () => { sandbox.stub(shared, "runCommand").resolves( ok({ projectPath: "", - createProjectForKiota: true, + lastCommand: "command", }) ); sandbox.stub(vscode.extensions, "getExtension").returns({ @@ -159,7 +159,7 @@ describe("Lifecycle handlers", () => { sandbox.stub(shared, "runCommand").resolves( ok({ projectPath: "", - createProjectForKiota: true, + lastCommand: "command", }) ); sandbox.stub(vscode.extensions, "getExtension").returns(undefined); @@ -184,7 +184,7 @@ describe("Lifecycle handlers", () => { sandbox.stub(shared, "runCommand").resolves( ok({ projectPath: "", - createProjectForKiota: true, + lastCommand: "command", }) ); sandbox.stub(vscode.extensions, "getExtension").returns(undefined); From 0cb49e0f9f4e9bfc347a0644024930e992233471 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Mon, 9 Sep 2024 09:45:42 +0800 Subject: [PATCH 12/21] fix: fix typo --- .../src/handlers/createPluginWithManifestHandler.ts | 2 +- .../handlers/createPluginWithManifestHandler.test.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts b/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts index 742330001d..268905c6b5 100644 --- a/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts +++ b/packages/vscode-extension/src/handlers/createPluginWithManifestHandler.ts @@ -45,7 +45,7 @@ export async function createPluginWithManifest(args?: any[]): Promise { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "invlaidParameter"); + chai.assert.equal(res.error.name, "invalidParameter"); } }); @@ -98,7 +98,7 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "invlaidParameter"); + chai.assert.equal(res.error.name, "invalidParameter"); } }); @@ -116,7 +116,7 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "invlaidParameter"); + chai.assert.equal(res.error.name, "invalidParameter"); } }); @@ -134,7 +134,7 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "invlaidParameter"); + chai.assert.equal(res.error.name, "invalidParameter"); } }); @@ -146,7 +146,7 @@ describe("createPluginWithManifestHandler", () => { chai.assert.isTrue(res.isErr()); chai.assert.isTrue(openFolder.notCalled); if (res.isErr()) { - chai.assert.equal(res.error.name, "invlaidParameter"); + chai.assert.equal(res.error.name, "invalidParameter"); } }); From c1144dc2db7602a75bd5f6f16a84a8993ca46d16 Mon Sep 17 00:00:00 2001 From: Ning Tang Date: Mon, 9 Sep 2024 17:16:18 +0800 Subject: [PATCH 13/21] fix: remove single quote from secret variable in template file --- .../env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../js/custom-copilot-assistant-new/env/.env.dev.user.tpl | 4 ++-- .../js/custom-copilot-assistant-new/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-assistant-new/env/.env.testtool.user.tpl | 4 ++-- templates/js/custom-copilot-basic/env/.env.dev.user.tpl | 4 ++-- templates/js/custom-copilot-basic/env/.env.local.user.tpl | 4 ++-- templates/js/custom-copilot-basic/env/.env.testtool.user.tpl | 4 ++-- .../custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../js/custom-copilot-rag-custom-api/env/.env.dev.user.tpl | 4 ++-- .../js/custom-copilot-rag-custom-api/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-custom-api/env/.env.testtool.user.tpl | 4 ++-- .../js/custom-copilot-rag-customize/env/.env.dev.user.tpl | 4 ++-- .../js/custom-copilot-rag-customize/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-customize/env/.env.testtool.user.tpl | 4 ++-- .../js/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl | 4 ++-- .../custom-copilot-rag-microsoft365/env/.env.local.user.tpl | 4 ++-- .../env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../python/custom-copilot-assistant-new/env/.env.dev.user.tpl | 4 ++-- .../custom-copilot-assistant-new/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-assistant-new/env/.env.testtool.user.tpl | 4 ++-- templates/python/custom-copilot-basic/env/.env.dev.user.tpl | 4 ++-- templates/python/custom-copilot-basic/env/.env.local.user.tpl | 4 ++-- .../python/custom-copilot-basic/env/.env.testtool.user.tpl | 4 ++-- .../custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../custom-copilot-rag-custom-api/env/.env.dev.user.tpl | 4 ++-- .../custom-copilot-rag-custom-api/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-custom-api/env/.env.testtool.user.tpl | 4 ++-- .../python/custom-copilot-rag-customize/env/.env.dev.user.tpl | 4 ++-- .../custom-copilot-rag-customize/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-customize/env/.env.testtool.user.tpl | 4 ++-- .../env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../ts/custom-copilot-assistant-new/env/.env.dev.user.tpl | 4 ++-- .../ts/custom-copilot-assistant-new/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-assistant-new/env/.env.testtool.user.tpl | 4 ++-- templates/ts/custom-copilot-basic/env/.env.dev.user.tpl | 4 ++-- templates/ts/custom-copilot-basic/env/.env.local.user.tpl | 4 ++-- templates/ts/custom-copilot-basic/env/.env.testtool.user.tpl | 4 ++-- .../custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl | 4 ++-- .../env/.env.local.user.tpl | 4 ++-- .../env/.env.testtool.user.tpl | 4 ++-- .../ts/custom-copilot-rag-custom-api/env/.env.dev.user.tpl | 4 ++-- .../ts/custom-copilot-rag-custom-api/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-custom-api/env/.env.testtool.user.tpl | 4 ++-- .../ts/custom-copilot-rag-customize/env/.env.dev.user.tpl | 4 ++-- .../ts/custom-copilot-rag-customize/env/.env.local.user.tpl | 4 ++-- .../custom-copilot-rag-customize/env/.env.testtool.user.tpl | 4 ++-- .../ts/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl | 4 ++-- .../custom-copilot-rag-microsoft365/env/.env.local.user.tpl | 4 ++-- 58 files changed, 116 insertions(+), 116 deletions(-) diff --git a/templates/js/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl b/templates/js/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl index 211ba5f5e8..ae99167809 100644 --- a/templates/js/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl b/templates/js/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl index a6c58d7cd0..525783967c 100644 --- a/templates/js/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -14,7 +14,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl b/templates/js/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl index 485a252c33..451b283240 100644 --- a/templates/js/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-assistant-new/env/.env.dev.user.tpl b/templates/js/custom-copilot-assistant-new/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/js/custom-copilot-assistant-new/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-assistant-new/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-assistant-new/env/.env.local.user.tpl b/templates/js/custom-copilot-assistant-new/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/js/custom-copilot-assistant-new/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-assistant-new/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-assistant-new/env/.env.testtool.user.tpl b/templates/js/custom-copilot-assistant-new/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/js/custom-copilot-assistant-new/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-assistant-new/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-basic/env/.env.dev.user.tpl b/templates/js/custom-copilot-basic/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/js/custom-copilot-basic/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-basic/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-basic/env/.env.local.user.tpl b/templates/js/custom-copilot-basic/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/js/custom-copilot-basic/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-basic/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-basic/env/.env.testtool.user.tpl b/templates/js/custom-copilot-basic/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/js/custom-copilot-basic/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-basic/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl index ab2e2bf50d..01aefcf275 100644 --- a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl index 13f3ff0b84..80191ab303 100644 --- a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl index 744a906306..d9e4ce6cac 100644 --- a/templates/js/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-custom-api/env/.env.dev.user.tpl b/templates/js/custom-copilot-rag-custom-api/env/.env.dev.user.tpl index aaef66ac22..7fb61bca30 100644 --- a/templates/js/custom-copilot-rag-custom-api/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-rag-custom-api/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/js/custom-copilot-rag-custom-api/env/.env.local.user.tpl b/templates/js/custom-copilot-rag-custom-api/env/.env.local.user.tpl index 7b66fcda20..130067d8f7 100644 --- a/templates/js/custom-copilot-rag-custom-api/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-rag-custom-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/js/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl b/templates/js/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl index 33ed92af0b..a3a088a32f 100644 --- a/templates/js/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/js/custom-copilot-rag-customize/env/.env.dev.user.tpl b/templates/js/custom-copilot-rag-customize/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/js/custom-copilot-rag-customize/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-rag-customize/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-customize/env/.env.local.user.tpl b/templates/js/custom-copilot-rag-customize/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/js/custom-copilot-rag-customize/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-rag-customize/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-customize/env/.env.testtool.user.tpl b/templates/js/custom-copilot-rag-customize/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/js/custom-copilot-rag-customize/env/.env.testtool.user.tpl +++ b/templates/js/custom-copilot-rag-customize/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl b/templates/js/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl index dace77c5df..359598d266 100644 --- a/templates/js/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl +++ b/templates/js/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_AAD_APP_CLIENT_SECRET= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/js/custom-copilot-rag-microsoft365/env/.env.local.user.tpl b/templates/js/custom-copilot-rag-microsoft365/env/.env.local.user.tpl index f68ff06c67..cf092c4d7c 100644 --- a/templates/js/custom-copilot-rag-microsoft365/env/.env.local.user.tpl +++ b/templates/js/custom-copilot-rag-microsoft365/env/.env.local.user.tpl @@ -6,7 +6,7 @@ SECRET_BOT_PASSWORD= SECRET_AAD_APP_CLIENT_SECRET= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -14,7 +14,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl b/templates/python/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl index 0926bdea03..8cc879724b 100644 --- a/templates/python/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl b/templates/python/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl index 659ce8519a..fcbaa5e54b 100644 --- a/templates/python/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -14,7 +14,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl b/templates/python/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl index 31a7c4faa2..96d776fae4 100644 --- a/templates/python/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-new/env/.env.dev.user.tpl b/templates/python/custom-copilot-assistant-new/env/.env.dev.user.tpl index 10cd616ae1..c66755fafb 100644 --- a/templates/python/custom-copilot-assistant-new/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-assistant-new/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-new/env/.env.local.user.tpl b/templates/python/custom-copilot-assistant-new/env/.env.local.user.tpl index 6a63206dbb..fa08219041 100644 --- a/templates/python/custom-copilot-assistant-new/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-assistant-new/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-assistant-new/env/.env.testtool.user.tpl b/templates/python/custom-copilot-assistant-new/env/.env.testtool.user.tpl index 76d74f19c2..5c30bfc29d 100644 --- a/templates/python/custom-copilot-assistant-new/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-assistant-new/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-basic/env/.env.dev.user.tpl b/templates/python/custom-copilot-basic/env/.env.dev.user.tpl index 10cd616ae1..c66755fafb 100644 --- a/templates/python/custom-copilot-basic/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-basic/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-basic/env/.env.local.user.tpl b/templates/python/custom-copilot-basic/env/.env.local.user.tpl index 6a63206dbb..fa08219041 100644 --- a/templates/python/custom-copilot-basic/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-basic/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-basic/env/.env.testtool.user.tpl b/templates/python/custom-copilot-basic/env/.env.testtool.user.tpl index 76d74f19c2..5c30bfc29d 100644 --- a/templates/python/custom-copilot-basic/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-basic/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl index 7af9d54b91..7dc0ba198f 100644 --- a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl index 14169d1be3..4d3158bced 100644 --- a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl index 14169d1be3..4d3158bced 100644 --- a/templates/python/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-custom-api/env/.env.dev.user.tpl b/templates/python/custom-copilot-rag-custom-api/env/.env.dev.user.tpl index 7b66fcda20..130067d8f7 100644 --- a/templates/python/custom-copilot-rag-custom-api/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-rag-custom-api/env/.env.dev.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/python/custom-copilot-rag-custom-api/env/.env.local.user.tpl b/templates/python/custom-copilot-rag-custom-api/env/.env.local.user.tpl index 7b66fcda20..130067d8f7 100644 --- a/templates/python/custom-copilot-rag-custom-api/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-rag-custom-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/python/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl b/templates/python/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl index 33ed92af0b..a3a088a32f 100644 --- a/templates/python/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/python/custom-copilot-rag-customize/env/.env.dev.user.tpl b/templates/python/custom-copilot-rag-customize/env/.env.dev.user.tpl index 10cd616ae1..c66755fafb 100644 --- a/templates/python/custom-copilot-rag-customize/env/.env.dev.user.tpl +++ b/templates/python/custom-copilot-rag-customize/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-customize/env/.env.local.user.tpl b/templates/python/custom-copilot-rag-customize/env/.env.local.user.tpl index 6a63206dbb..fa08219041 100644 --- a/templates/python/custom-copilot-rag-customize/env/.env.local.user.tpl +++ b/templates/python/custom-copilot-rag-customize/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/python/custom-copilot-rag-customize/env/.env.testtool.user.tpl b/templates/python/custom-copilot-rag-customize/env/.env.testtool.user.tpl index 76d74f19c2..5c30bfc29d 100644 --- a/templates/python/custom-copilot-rag-customize/env/.env.testtool.user.tpl +++ b/templates/python/custom-copilot-rag-customize/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl index 211ba5f5e8..ae99167809 100644 --- a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl index a6c58d7cd0..525783967c 100644 --- a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -14,7 +14,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl index 485a252c33..451b283240 100644 --- a/templates/ts/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-assistant-assistants-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ OPENAI_ASSISTANT_ID= # See README.md for how to fill in this value. {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-new/env/.env.dev.user.tpl b/templates/ts/custom-copilot-assistant-new/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/ts/custom-copilot-assistant-new/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-assistant-new/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-new/env/.env.local.user.tpl b/templates/ts/custom-copilot-assistant-new/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/ts/custom-copilot-assistant-new/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-assistant-new/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-assistant-new/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-assistant-new/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/ts/custom-copilot-assistant-new/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-assistant-new/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-basic/env/.env.dev.user.tpl b/templates/ts/custom-copilot-basic/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/ts/custom-copilot-basic/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-basic/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-basic/env/.env.local.user.tpl b/templates/ts/custom-copilot-basic/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/ts/custom-copilot-basic/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-basic/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-basic/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-basic/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/ts/custom-copilot-basic/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-basic/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl index ab2e2bf50d..01aefcf275 100644 --- a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl index 13f3ff0b84..80191ab303 100644 --- a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl index 744a906306..d9e4ce6cac 100644 --- a/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-rag-azure-ai-search/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-custom-api/env/.env.dev.user.tpl b/templates/ts/custom-copilot-rag-custom-api/env/.env.dev.user.tpl index aaef66ac22..7fb61bca30 100644 --- a/templates/ts/custom-copilot-rag-custom-api/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-rag-custom-api/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/ts/custom-copilot-rag-custom-api/env/.env.local.user.tpl b/templates/ts/custom-copilot-rag-custom-api/env/.env.local.user.tpl index 7b66fcda20..130067d8f7 100644 --- a/templates/ts/custom-copilot-rag-custom-api/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-rag-custom-api/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/ts/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl index 33ed92af0b..a3a088a32f 100644 --- a/templates/ts/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-rag-custom-api/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY=' ' @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY=' ' {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY=' ' diff --git a/templates/ts/custom-copilot-rag-customize/env/.env.dev.user.tpl b/templates/ts/custom-copilot-rag-customize/env/.env.dev.user.tpl index c151624340..0aa24da955 100644 --- a/templates/ts/custom-copilot-rag-customize/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-rag-customize/env/.env.dev.user.tpl @@ -3,7 +3,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -11,7 +11,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-customize/env/.env.local.user.tpl b/templates/ts/custom-copilot-rag-customize/env/.env.local.user.tpl index b1c0fc39f2..68fde0c24b 100644 --- a/templates/ts/custom-copilot-rag-customize/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-rag-customize/env/.env.local.user.tpl @@ -5,7 +5,7 @@ SECRET_BOT_PASSWORD= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -13,7 +13,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-customize/env/.env.testtool.user.tpl b/templates/ts/custom-copilot-rag-customize/env/.env.testtool.user.tpl index 8beb393d16..02cf7e15f1 100644 --- a/templates/ts/custom-copilot-rag-customize/env/.env.testtool.user.tpl +++ b/templates/ts/custom-copilot-rag-customize/env/.env.testtool.user.tpl @@ -4,7 +4,7 @@ # Secrets. Keys prefixed with `SECRET_` will be masked in Teams Toolkit logs. {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl b/templates/ts/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl index dace77c5df..359598d266 100644 --- a/templates/ts/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl +++ b/templates/ts/custom-copilot-rag-microsoft365/env/.env.dev.user.tpl @@ -4,7 +4,7 @@ SECRET_AAD_APP_CLIENT_SECRET= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -12,7 +12,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= diff --git a/templates/ts/custom-copilot-rag-microsoft365/env/.env.local.user.tpl b/templates/ts/custom-copilot-rag-microsoft365/env/.env.local.user.tpl index f68ff06c67..cf092c4d7c 100644 --- a/templates/ts/custom-copilot-rag-microsoft365/env/.env.local.user.tpl +++ b/templates/ts/custom-copilot-rag-microsoft365/env/.env.local.user.tpl @@ -6,7 +6,7 @@ SECRET_BOT_PASSWORD= SECRET_AAD_APP_CLIENT_SECRET= {{#useOpenAI}} {{#openAIKey}} -SECRET_OPENAI_API_KEY='{{{openAIKey}}}' +SECRET_OPENAI_API_KEY={{{openAIKey}}} {{/openAIKey}} {{^openAIKey}} SECRET_OPENAI_API_KEY= @@ -14,7 +14,7 @@ SECRET_OPENAI_API_KEY= {{/useOpenAI}} {{#useAzureOpenAI}} {{#azureOpenAIKey}} -SECRET_AZURE_OPENAI_API_KEY='{{{azureOpenAIKey}}}' +SECRET_AZURE_OPENAI_API_KEY={{{azureOpenAIKey}}} {{/azureOpenAIKey}} {{^azureOpenAIKey}} SECRET_AZURE_OPENAI_API_KEY= From 12ddf0a235c67179b139b516994c9c8665e20fed Mon Sep 17 00:00:00 2001 From: Yuqi Zhou Date: Mon, 9 Sep 2024 17:09:26 +0800 Subject: [PATCH 14/21] fix: tab-bot template deploy refactor: minor --- templates/js/non-sso-tab-default-bot/teamsapp.yml.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/js/non-sso-tab-default-bot/teamsapp.yml.tpl b/templates/js/non-sso-tab-default-bot/teamsapp.yml.tpl index 3a85743bcb..b1ba70f02e 100644 --- a/templates/js/non-sso-tab-default-bot/teamsapp.yml.tpl +++ b/templates/js/non-sso-tab-default-bot/teamsapp.yml.tpl @@ -91,7 +91,7 @@ deploy: - uses: cli/runNpxCommand name: deploy to Azure Static Web Apps with: - args: '@azure/static-web-apps-cli deploy ./build -d ${{SECRET_TAB_SWA_DEPLOYMENT_TOKEN}} --env production' + args: '@azure/static-web-apps-cli deploy tab/build -d ${{SECRET_TAB_SWA_DEPLOYMENT_TOKEN}} --env production' # Deploy your application to Azure App Service using the zip deploy feature. # For additional details, refer to https://aka.ms/zip-deploy-to-app-services. - uses: azureAppService/zipDeploy From 1135096c172dfad715466a968a56980b45c5e665 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Mon, 9 Sep 2024 15:34:44 +0800 Subject: [PATCH 15/21] perf(kiota): add version check and vsc setting for kiota --- packages/vscode-extension/package.json | 5 ++ packages/vscode-extension/package.nls.json | 2 +- packages/vscode-extension/src/config.ts | 5 ++ packages/vscode-extension/src/constants.ts | 4 ++ .../src/handlers/lifecycleHandlers.ts | 27 +++++-- .../test/handlers/lifecycleHandlers.test.ts | 72 ++++++++++++++++++- 6 files changed, 108 insertions(+), 7 deletions(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index ff5c75b084..a8f4c4bb6b 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1547,6 +1547,11 @@ ], "default": "Info", "markdownDescription": "Set the log level of Teams Toolkit. The default value is `Info`. The available values are `Debug`, `Verbose`, `Info`. The definitions of the log levels are:\n\n`Debug`:\n\n- HTTP request and response details from Teams Toolkit to external services such as Azure, Microsoft 365, and Teams Developer Portal.\n- Information related to Microsoft 365 and Azure accounts and access permissions.\n- Debugging information for each Teams Toolkit command execution, such as stack trace, ARM deployment information, etc.\n\n`Verbose`:\n\n- Progress information when executing lifecycle commands defined in the YAML file.\n- Execution details of each action that defined in the YAML file, including outcomes, result summaries, diagnostic information, etc.\n\n`Info`: Teams Toolkit command execution summaries.\n" + }, + "fx-extension.enableMicrosoftKiota": { + "type": "boolean", + "default": false, + "markdownDescription": "Use Microsoft Kiota to generate API Plugin from a local OpenAPI description or search for public APIs. If you don't have Microsoft Kiota installed, please install [here](https://marketplace.visualstudio.com/items?itemName=ms-graph.kiota)" } } }, diff --git a/packages/vscode-extension/package.nls.json b/packages/vscode-extension/package.nls.json index 2cfc99f6a1..d2f06e13ed 100644 --- a/packages/vscode-extension/package.nls.json +++ b/packages/vscode-extension/package.nls.json @@ -553,5 +553,5 @@ "teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppResources.description": "Explore these resources to build intelligent apps and enhance your development projects\n🗒️ [Generative AI for Beginners](https://github.com/microsoft/generative-ai-for-beginners/tree/main)\n✨ [Retrieval Augmented Generation (RAG)](https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview)\n📚 [AI Learning and Community Hub](https://learn.microsoft.com/en-us/ai/)", "teamstoolkit.m365.needSignIn.message": "You need to sign in your Microsoft 365 account.", "teamstoolkit.handler.createPluginWithManifest.error.missingParameter": "Invalid parameter in the createPluginWithManifest command. Usage: createPluginWithManifest(API_SPEC_PATH:string, PLUGIN_MANIFEST_PATH: string, { lastCommand: string }, OUTPUT_FOLDER?: string). Valid values for LAST_COMMAND: createPluginWithManifest, createDeclarativeCopilotWithManifest.", - "teamstoolkit.error.KiotaNotInstalled": "You need to install Microsoft Kiota extension to use this feature." + "teamstoolkit.error.KiotaNotInstalled": "You need to install Microsoft Kiota extension with minimum version %s to use this feature." } diff --git a/packages/vscode-extension/src/config.ts b/packages/vscode-extension/src/config.ts index f1acc90db4..5e38f74eb8 100644 --- a/packages/vscode-extension/src/config.ts +++ b/packages/vscode-extension/src/config.ts @@ -6,6 +6,7 @@ import VsCodeLogInstance from "./commonlib/log"; import { LogLevel } from "@microsoft/teamsfx-api"; import { ExtTelemetry } from "./telemetry/extTelemetry"; import { TelemetryEvent } from "./telemetry/extTelemetryEvents"; +import { FeatureFlags } from "@microsoft/teamsfx-core"; export class ConfigManager { registerConfigChangeCallback() { @@ -36,6 +37,10 @@ export class ConfigManager { ConfigurationKey.CopilotExtensionEnable, false ).toString(); + process.env[FeatureFlags.KiotaIntegration.name] = this.getConfiguration( + ConfigurationKey.EnableMicrosoftKiota, + false + ).toString(); } loadLogLevel() { const logLevel = this.getConfiguration(ConfigurationKey.LogLevel, "Info") as string; diff --git a/packages/vscode-extension/src/constants.ts b/packages/vscode-extension/src/constants.ts index 4916859074..e914ac7a94 100644 --- a/packages/vscode-extension/src/constants.ts +++ b/packages/vscode-extension/src/constants.ts @@ -5,6 +5,7 @@ export enum ConfigurationKey { BicepEnvCheckerEnable = "prerequisiteCheck.bicep", CopilotExtensionEnable = "developCopilotPlugin", LogLevel = "logLevel", + EnableMicrosoftKiota = "enableMicrosoftKiota", } export const AzurePortalUrl = "https://portal.azure.com"; @@ -71,3 +72,6 @@ export const DeveloperPortalHomeLink = "https://dev.teams.microsoft.com/home"; export const TerminalName = "Teams Toolkit"; export const InstallCopilotChatLink = "https://aka.ms/install-github-copilot-chat"; + +export const KiotaExtensionId = "ms-graph.kiota"; +export const KiotaMinVersion = "1.19.100000001"; diff --git a/packages/vscode-extension/src/handlers/lifecycleHandlers.ts b/packages/vscode-extension/src/handlers/lifecycleHandlers.ts index a652e76911..84f2cf1ffc 100644 --- a/packages/vscode-extension/src/handlers/lifecycleHandlers.ts +++ b/packages/vscode-extension/src/handlers/lifecycleHandlers.ts @@ -41,6 +41,9 @@ import { invokeTeamsAgent } from "./copilotChatHandlers"; import { runCommand } from "./sharedOpts"; import { ExtensionSource } from "../error/error"; import VsCodeLogInstance from "../commonlib/log"; +import * as versionUtil from "../utils/versionUtil"; +import { KiotaExtensionId, KiotaMinVersion } from "../constants"; +import * as stringUtil from "util"; export async function createNewProjectHandler(...args: any[]): Promise> { ExtTelemetry.sendTelemetryEvent(TelemetryEvent.CreateProjectStart, getTriggerFromProperty(args)); @@ -243,10 +246,10 @@ function handleTriggerKiotaCommand( args: any[], result: CreateProjectResult ): Result { - if (!vscode.extensions.getExtension("ms-graph.kiota")) { + if (!validateKiotaInstallation()) { void vscode.window .showInformationMessage( - localize("teamstoolkit.error.KiotaNotInstalled"), + stringUtil.format(localize("teamstoolkit.error.KiotaNotInstalled"), KiotaMinVersion), "Install Kiota", "Cancel" ) @@ -262,7 +265,7 @@ function handleTriggerKiotaCommand( new UserError( ExtensionSource, "KiotaNotInstalled", - localize("teamstoolkit.error.KiotaNotInstalled") + stringUtil.format(localize("teamstoolkit.error.KiotaNotInstalled"), KiotaMinVersion) ) ); } @@ -272,7 +275,9 @@ function handleTriggerKiotaCommand( [TelemetryProperty.KiotaInstalled]: "No", ...getTriggerFromProperty(args), }); - VsCodeLogInstance.error(localize("teamstoolkit.error.KiotaNotInstalled")); + VsCodeLogInstance.error( + stringUtil.format(localize("teamstoolkit.error.KiotaNotInstalled"), KiotaMinVersion) + ); return ok({ projectPath: "" }); } else { void vscode.commands.executeCommand("kiota.openApiExplorer.searchOrOpenApiDescription", { @@ -290,3 +295,17 @@ function handleTriggerKiotaCommand( return ok(result); } } + +function validateKiotaInstallation(): boolean { + const installed = vscode.extensions.getExtension(KiotaExtensionId); + if (!installed) { + return false; + } + + const kiotaVersion = installed.packageJSON.version; + if (!kiotaVersion) { + return false; + } + + return versionUtil.compare(kiotaVersion, KiotaMinVersion) !== -1; +} diff --git a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts index 8db027c3c6..f1d62d9b28 100644 --- a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts +++ b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts @@ -124,7 +124,7 @@ describe("Lifecycle handlers", () => { assert.isTrue(openFolder.calledOnce); }); - it("kiota integration: kiota installed", async () => { + it("kiota integration: kiota installed release version", async () => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.KiotaIntegration]: "true", }); @@ -141,7 +141,39 @@ describe("Lifecycle handlers", () => { extensionPath: "mockedPath", extensionKind: vscode.ExtensionKind.UI, exports: {}, - packageJSON: {}, + packageJSON: { + version: "1.19.100000001", + }, + activate: () => Promise.resolve(), + }); + const executeCommand = sandbox.stub(vscode.commands, "executeCommand").resolves(); + const logError = sandbox.stub(VsCodeLogInstance, "error").resolves(); + const res = await createNewProjectHandler(); + assert.isTrue(res.isOk()); + assert.isTrue(executeCommand.calledOnce); + assert.isTrue(logError.notCalled); + }); + + it("kiota integration: kiota installed pre-release version", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.KiotaIntegration]: "true", + }); + sandbox.stub(shared, "runCommand").resolves( + ok({ + projectPath: "", + lastCommand: "command", + }) + ); + sandbox.stub(vscode.extensions, "getExtension").returns({ + id: "mockedId", + extensionUri: vscode.Uri.parse("file://mockedUri"), + isActive: true, + extensionPath: "mockedPath", + extensionKind: vscode.ExtensionKind.UI, + exports: {}, + packageJSON: { + version: "1.20.24090901", + }, activate: () => Promise.resolve(), }); const executeCommand = sandbox.stub(vscode.commands, "executeCommand").resolves(); @@ -177,6 +209,42 @@ describe("Lifecycle handlers", () => { assert.isTrue(logError.calledOnce); }); + it("kiota integration: kiota version not match and click install", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.KiotaIntegration]: "true", + }); + sandbox.stub(shared, "runCommand").resolves( + ok({ + projectPath: "", + lastCommand: "command", + }) + ); + sandbox.stub(vscode.extensions, "getExtension").returns({ + id: "mockedId", + extensionUri: vscode.Uri.parse("file://mockedUri"), + isActive: true, + extensionPath: "mockedPath", + extensionKind: vscode.ExtensionKind.UI, + exports: {}, + packageJSON: { + version: "1.18.100000001", + }, + activate: () => Promise.resolve(), + }); + const showMessageStub = sandbox + .stub(vscode.window, "showInformationMessage") + .callsFake((title: string, ...items: any[]) => { + return Promise.resolve(items[0]); + }); + const executeCommand = sandbox.stub(vscode.commands, "executeCommand").resolves(); + const logError = sandbox.stub(VsCodeLogInstance, "error").resolves(); + const res = await createNewProjectHandler(); + assert.isTrue(res.isOk()); + assert.isTrue(showMessageStub.calledOnce); + assert.isTrue(executeCommand.calledOnce); + assert.isTrue(logError.calledOnce); + }); + it("kiota integration: kiota not installed and click cancel", async () => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.KiotaIntegration]: "true", From 9dc9cc7d6a470b60b31fd58d768dc671ed1b2101 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Mon, 9 Sep 2024 15:47:49 +0800 Subject: [PATCH 16/21] test: add ut --- .../test/handlers/lifecycleHandlers.test.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts index f1d62d9b28..2e1c16c971 100644 --- a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts +++ b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts @@ -245,6 +245,40 @@ describe("Lifecycle handlers", () => { assert.isTrue(logError.calledOnce); }); + it("kiota integration: no kiota version and click install", async () => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.KiotaIntegration]: "true", + }); + sandbox.stub(shared, "runCommand").resolves( + ok({ + projectPath: "", + lastCommand: "command", + }) + ); + sandbox.stub(vscode.extensions, "getExtension").returns({ + id: "mockedId", + extensionUri: vscode.Uri.parse("file://mockedUri"), + isActive: true, + extensionPath: "mockedPath", + extensionKind: vscode.ExtensionKind.UI, + exports: {}, + packageJSON: {}, + activate: () => Promise.resolve(), + }); + const showMessageStub = sandbox + .stub(vscode.window, "showInformationMessage") + .callsFake((title: string, ...items: any[]) => { + return Promise.resolve(items[0]); + }); + const executeCommand = sandbox.stub(vscode.commands, "executeCommand").resolves(); + const logError = sandbox.stub(VsCodeLogInstance, "error").resolves(); + const res = await createNewProjectHandler(); + assert.isTrue(res.isOk()); + assert.isTrue(showMessageStub.calledOnce); + assert.isTrue(executeCommand.calledOnce); + assert.isTrue(logError.calledOnce); + }); + it("kiota integration: kiota not installed and click cancel", async () => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.KiotaIntegration]: "true", From 6bebf006bbf59b9c5fb132f426f631fd29f833d5 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Tue, 10 Sep 2024 09:10:52 +0800 Subject: [PATCH 17/21] perf: update kiota version --- packages/vscode-extension/src/constants.ts | 2 +- .../vscode-extension/test/handlers/lifecycleHandlers.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vscode-extension/src/constants.ts b/packages/vscode-extension/src/constants.ts index e914ac7a94..f7076ee5f0 100644 --- a/packages/vscode-extension/src/constants.ts +++ b/packages/vscode-extension/src/constants.ts @@ -74,4 +74,4 @@ export const TerminalName = "Teams Toolkit"; export const InstallCopilotChatLink = "https://aka.ms/install-github-copilot-chat"; export const KiotaExtensionId = "ms-graph.kiota"; -export const KiotaMinVersion = "1.19.100000001"; +export const KiotaMinVersion = "1.18.100000002"; diff --git a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts index 2e1c16c971..68551672f1 100644 --- a/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts +++ b/packages/vscode-extension/test/handlers/lifecycleHandlers.test.ts @@ -142,7 +142,7 @@ describe("Lifecycle handlers", () => { extensionKind: vscode.ExtensionKind.UI, exports: {}, packageJSON: { - version: "1.19.100000001", + version: "1.18.100000002", }, activate: () => Promise.resolve(), }); @@ -172,7 +172,7 @@ describe("Lifecycle handlers", () => { extensionKind: vscode.ExtensionKind.UI, exports: {}, packageJSON: { - version: "1.20.24090901", + version: "1.19.24090901", }, activate: () => Promise.resolve(), }); From 828a8f9f4341c17c43860eb1fa2675fea7f087a4 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Tue, 10 Sep 2024 15:44:08 +0800 Subject: [PATCH 18/21] docs: update message --- packages/vscode-extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index a8f4c4bb6b..e8d2b4d9dc 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1551,7 +1551,7 @@ "fx-extension.enableMicrosoftKiota": { "type": "boolean", "default": false, - "markdownDescription": "Use Microsoft Kiota to generate API Plugin from a local OpenAPI description or search for public APIs. If you don't have Microsoft Kiota installed, please install [here](https://marketplace.visualstudio.com/items?itemName=ms-graph.kiota)" + "markdownDescription": "Use Microsoft Kiota to generate an API Plugin from a local OpenAPI description or search for public APIs. If Microsoft Kiota isn't installed, install it from the [Visual Studio Marketplace] (https://marketplace.visualstudio.com/items?itemName=ms-graph.kiota)" } } }, From a3126b10813e936fb26db33aefae69225ba04307 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Wed, 11 Sep 2024 09:14:57 +0800 Subject: [PATCH 19/21] docs(kiota): update message --- packages/vscode-extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index e8d2b4d9dc..af5e3c18ad 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1551,7 +1551,7 @@ "fx-extension.enableMicrosoftKiota": { "type": "boolean", "default": false, - "markdownDescription": "Use Microsoft Kiota to generate an API Plugin from a local OpenAPI description or search for public APIs. If Microsoft Kiota isn't installed, install it from the [Visual Studio Marketplace] (https://marketplace.visualstudio.com/items?itemName=ms-graph.kiota)" + "markdownDescription": "Use Microsoft Kiota to generate an API Plugin from a local OpenAPI description or search for public APIs. If Microsoft Kiota isn't installed, install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-graph.kiota)" } } }, From 5981fd5fec6d51309ec1430c751b55fed6d29a25 Mon Sep 17 00:00:00 2001 From: Yimin-Jin Date: Wed, 11 Sep 2024 10:05:13 +0800 Subject: [PATCH 20/21] fix: fix api-key template always return empty --- .../src/functions/repair.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/js/api-plugin-from-scratch-bearer/src/functions/repair.js b/templates/js/api-plugin-from-scratch-bearer/src/functions/repair.js index 856a379b60..88b431d335 100644 --- a/templates/js/api-plugin-from-scratch-bearer/src/functions/repair.js +++ b/templates/js/api-plugin-from-scratch-bearer/src/functions/repair.js @@ -22,11 +22,14 @@ async function repairs(req, context) { }; } + // Get the repair records from the data.json file. + const repairRecords = require("../repairsData.json"); + // Initialize response. const res = { status: 200, jsonBody: { - results: [], + results: repairRecords, }, }; @@ -38,9 +41,6 @@ async function repairs(req, context) { return res; } - // Get the repair records from the data.json file. - const repairRecords = require("../repairsData.json"); - // Filter the repair records by the assignedTo query parameter. const repairs = repairRecords.filter((item) => { const query = assignedTo.trim().toLowerCase(); From 69ad155599dc29938dfc695b4196a66aa9be3bfd Mon Sep 17 00:00:00 2001 From: Hui Miao Date: Wed, 11 Sep 2024 14:52:55 +0800 Subject: [PATCH 21/21] fix: hide the AAD in copilot extensions --- packages/fx-core/src/common/featureFlags.ts | 5 +++ packages/fx-core/src/question/create.ts | 10 ++--- .../fx-core/tests/question/create.test.ts | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/packages/fx-core/src/common/featureFlags.ts b/packages/fx-core/src/common/featureFlags.ts index a1fdbe08f7..a37bc0ccbd 100644 --- a/packages/fx-core/src/common/featureFlags.ts +++ b/packages/fx-core/src/common/featureFlags.ts @@ -30,6 +30,7 @@ export class FeatureFlagName { static readonly SyncManifest = "TEAMSFX_SYNC_MANIFEST"; static readonly EnvFileFunc = "TEAMSFX_ENV_FILE_FUNC"; static readonly KiotaIntegration = "TEAMSFX_KIOTA_INTEGRATION"; + static readonly ApiPluginAAD = "TEAMSFX_API_PLUGIN_AAD"; } export interface FeatureFlag { @@ -89,6 +90,10 @@ export class FeatureFlags { name: FeatureFlagName.KiotaIntegration, defaultValue: "false", }; + static readonly ApiPluginAAD = { + name: FeatureFlagName.ApiPluginAAD, + defaultValue: "false", + }; } export function isCopilotExtensionEnabled(): boolean { diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index d83d8a01a2..a3ee86446a 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -1045,11 +1045,11 @@ export function apiAuthQuestion(): SingleSelectQuestion { if (inputs[QuestionNames.MeArchitectureType] === MeArchitectureOptions.newApi().id) { options.push(ApiAuthOptions.apiKey(), ApiAuthOptions.microsoftEntra()); } else if (inputs[QuestionNames.ApiPluginType] === ApiPluginStartOptions.newApi().id) { - options.push( - ApiAuthOptions.apiKey(), - ApiAuthOptions.microsoftEntra(), - ApiAuthOptions.oauth() - ); + options.push(ApiAuthOptions.apiKey()); + if (featureFlagManager.getBooleanValue(FeatureFlags.ApiPluginAAD)) { + options.push(ApiAuthOptions.microsoftEntra()); + } + options.push(ApiAuthOptions.oauth()); } return options; }, diff --git a/packages/fx-core/tests/question/create.test.ts b/packages/fx-core/tests/question/create.test.ts index 7393ce2cf9..df31c6ea2e 100644 --- a/packages/fx-core/tests/question/create.test.ts +++ b/packages/fx-core/tests/question/create.test.ts @@ -1595,6 +1595,7 @@ describe("scaffold question", () => { beforeEach(() => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.CopilotExtension]: "true", + [FeatureFlagName.ApiPluginAAD]: "true", }); }); @@ -1943,6 +1944,7 @@ describe("scaffold question", () => { it("traverse in cli", async () => { mockedEnvRestore = mockedEnv({ TEAMSFX_CLI_DOTNET: "false", + [FeatureFlagName.ApiPluginAAD]: "true", }); const inputs: Inputs = { @@ -4174,6 +4176,7 @@ describe("scaffold question", () => { beforeEach(() => { mockedEnvRestore = mockedEnv({ [FeatureFlagName.CopilotExtension]: "true", + [FeatureFlagName.ApiPluginAAD]: "true", }); }); @@ -4217,4 +4220,38 @@ describe("scaffold question", () => { } }); }); + describe("api plugin auth question (AAD disabled)", () => { + let mockedEnvRestore: RestoreFn; + const tools = new MockTools(); + setTools(tools); + beforeEach(() => { + mockedEnvRestore = mockedEnv({ + [FeatureFlagName.CopilotExtension]: "true", + [FeatureFlagName.ApiPluginAAD]: "false", + }); + }); + + afterEach(() => { + if (mockedEnvRestore) { + mockedEnvRestore(); + } + }); + + it("api plugin from scratch without AAD enabled", async () => { + const question = apiAuthQuestion(); + const inputs: Inputs = { + platform: Platform.VSCode, + }; + inputs[QuestionNames.ApiPluginType] = ApiPluginStartOptions.newApi().id; + assert.isDefined(question.dynamicOptions); + if (question.dynamicOptions) { + const options = (await question.dynamicOptions(inputs)) as OptionItem[]; + assert.deepEqual(options, [ + ApiAuthOptions.none(), + ApiAuthOptions.apiKey(), + ApiAuthOptions.oauth(), + ]); + } + }); + }); });