Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/fx-core/resource/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
"error.generator.FetchSampleInfoError": "Unable to fetch sample info",
"error.generator.DownloadSampleApiLimitError": "Unable to download sample due to rate limitation. Try again in an hour after rate limit reset or you can manually clone the repo from %s.",
"error.generator.DownloadSampleNetworkError": "Unable to download sample due to network error. Check your network connection and try again or you can manually clone the repo from %s",
"error.generator.UnknownPolicy": "Unknown auth policy: %s",
"error.copilotPlugin.apiSpecNotUsedInPlugin": "\"%s\" is not used in the plugin.",
"error.apime.noExtraAPICanBeAdded": "Unable to add API because only GET and POST methods are supported, with a maximum of 5 required parameters and no authentication. Also, methods defined in the manifest are not listed.",
"error.copilot.noExtraAPICanBeAdded": "Unable to add API because no authentication is supported. Also, methods defined in the current OpenAPI description document are not listed.",
Expand Down Expand Up @@ -320,6 +321,7 @@
"core.copilotPlugin.scaffold.summary.warning.generate.ac.failed": "Failed to create the adaptive card for API '%s': %s. Mitigation: Not required but you can manually add it to the adaptiveCards folder.",
"core.createCapabilityQuestion.titleNew": "Capabilities",
"core.createProjectQuestion.option.description.preview": "Preview",
"core.createProjectQuestion.option.description.previewOnWindow": "Preview on Windows",
"core.createProjectQuestion.option.description.worksInOutlook": "Works in Teams and Outlook",
"core.createProjectQuestion.option.description.worksInOutlookM365": "Works in Teams, Outlook, and the Microsoft 365 application",
"core.createProjectQuestion.projectType.bot.detail": "Create instant, engaging chat experiences that automate tasks seamlessly",
Expand Down Expand Up @@ -367,6 +369,7 @@
"core.createProjectQuestion.capability.knowledgeEmbeddedKnowledge.detail": "Embed files directly as grounding information.",
"core.createProjectQuestion.oneDriveSharePointItem.title": "OneDrive or SharePoint Content",
"core.createProjectQuestion.oneDriveSharePointItem.placeholder": "Enter a URL to OneDrive or SharePoint",
"core.createProjectQuestion.oneDriveSharePointItem.confirm": "Confirm your selection",
"core.createProjectQuestion.log.fail.validateOneDriveSharePointItem": "Failed to validate OneDrive/SharePoint URL: %s",
"core.createProjectQuestion.log.fail.invalidOneDriveSharePointURL": "The OneDrive/SharePoint URL is invalid.",
"core.createProjectQuestion.llmService.title": "Service for Large Language Model (LLM)",
Expand Down Expand Up @@ -1055,6 +1058,7 @@
"core.addKnowledgeQuestion.searchType.oneDriveSharepoint": "Search all content within your organization",
"core.addKnowledgeQuestion.searchType.url": "Search by URL",
"driver.typeSpec.compile.start": "Executing action %s",
"driver.typeSpec.compile.description": "Compile TypeSpec project",
"driver.typespec.error.noSpecError": "No OpenApi spec found. Please make sure your TypeSpec files are valid and try again.",
"driver.typespec.error.multipleActionError": "More than one action found in declarativeAgent.json. Please make sure your TypeSpec files are valid and try again.",
"driver.typeSpec.progressBar": "Compiling and generating files...",
Expand Down
35 changes: 13 additions & 22 deletions packages/fx-core/src/question/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { Inputs, OptionItem } from "@microsoft/teamsfx-api";
import { Inputs, OptionItem, Platform } from "@microsoft/teamsfx-api";
import { FeatureFlags, featureFlagManager } from "../common/featureFlags";
import { getLocalizedString } from "../common/localizeUtils";
export { QuestionNames } from "./questionNames";
Expand Down Expand Up @@ -292,36 +292,24 @@ export class CustomCopilotRagOptions {
static customize(): OptionItem {
return {
id: "custom-copilot-rag-customize",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomizeOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomizeOption.detail"
),
label: getLocalizedString("template.teams.rag.source.customize.label"),
detail: getLocalizedString("template.teams.rag.source.customize.detail"),
};
}

static azureAISearch(): OptionItem {
return {
id: "custom-copilot-rag-azureAISearch",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.detail"
),
label: getLocalizedString("template.teams.rag.source.azureAISearch.label"),
detail: getLocalizedString("template.teams.rag.source.azureAISearch.detail"),
};
}

static customApi(): OptionItem {
return {
id: "custom-copilot-rag-customApi",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomApiOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomApiOption.detail"
),
label: getLocalizedString("template.teams.rag.source.customApi.label"),
detail: getLocalizedString("template.teams.rag.source.customApi.detail"),
description: getLocalizedString("core.createProjectQuestion.option.description.preview"),
};
}
Expand Down Expand Up @@ -503,8 +491,8 @@ export class ActionStartOptions {
static mcp(): OptionItem {
return {
id: "mcp",
label: getLocalizedString("core.createProjectQuestion.mcpForDa.label"),
detail: getLocalizedString("core.createProjectQuestion.mcpForDa.detail"),
label: getLocalizedString("template.createProjectQuestion.mcpForDa.label"),
detail: getLocalizedString("template.createProjectQuestion.mcpForDa.detail"),
};
}

Expand All @@ -517,7 +505,10 @@ export class ActionStartOptions {
static all(inputs: Inputs, doesProjectExists?: boolean): OptionItem[] {
if (doesProjectExists) {
const options: OptionItem[] = [ActionStartOptions.apiSpec()];
if (featureFlagManager.getBooleanValue(FeatureFlags.MCPForDA)) {
if (
featureFlagManager.getBooleanValue(FeatureFlags.MCPForDA) &&
inputs.platform !== Platform.VSCode
) {
options.push(ActionStartOptions.mcp());
}
return options;
Expand Down
4 changes: 1 addition & 3 deletions packages/fx-core/src/question/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1015,9 +1015,7 @@ function customCopilotRagQuestion(): SingleSelectQuestion {
type: "singleSelect",
name: QuestionNames.CustomCopilotRag,
title: getLocalizedString("core.createProjectQuestion.capability.customCopilotRag.title"),
placeholder: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRag.placeholder"
),
placeholder: getLocalizedString("template.teams.rag.source.placeholder"),
staticOptions: CustomCopilotRagOptions.all(),
dynamicOptions: () => CustomCopilotRagOptions.all(),
default: CustomCopilotRagOptions.customize().id,
Expand Down
64 changes: 18 additions & 46 deletions packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@ export class CustomEngineAgentOptions {
static basicCustomEngineAgent(): OptionItem {
return {
id: "basic-custom-engine-agent",
label: getLocalizedString(
"core.createProjectQuestion.capability.basicCustomEngineAgentOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.basicCustomEngineAgentOption.detail"
),
label: getLocalizedString("template.customEngineAgent.basic.label"),
detail: getLocalizedString("template.customEngineAgent.basic.detail"),
data: TemplateNames.BasicCustomEngineAgent,
};
}

static weatherAgent(): OptionItem {
return {
id: "weather-agent",
label: getLocalizedString("core.createProjectQuestion.capability.weatherAgentOption.label"),
detail: getLocalizedString("core.createProjectQuestion.capability.weatherAgentOption.detail"),
label: getLocalizedString("template.customEngineAgent.weather.label"),
detail: getLocalizedString("template.customEngineAgent.weather.detail"),
data: TemplateNames.WeatherAgent,
};
}
Expand Down Expand Up @@ -100,12 +96,8 @@ export class TeamsAgentCapabilityOptions {
: undefined;
return {
id: "custom-copilot-basic",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotBasicOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotBasicOption.detail"
),
label: getLocalizedString("template.teams.general.label"),
detail: getLocalizedString("template.teams.general.detail"),
description: description,
data: TemplateNames.CustomCopilotBasic,
};
Expand All @@ -117,25 +109,17 @@ export class TeamsAgentCapabilityOptions {
: undefined;
return {
id: "custom-copilot-rag",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagOption.detail"
),
label: getLocalizedString("template.teams.rag.label"),
detail: getLocalizedString("template.teams.rag.detail"),
description: description,
};
}

static collaboratorAgent(): OptionItem {
return {
id: "teams-collaborator-agent",
label: getLocalizedString(
"core.createProjectQuestion.capability.teamsAgent.collaborator.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.teamsAgent.collaborator.detail"
),
label: getLocalizedString("template.teams.collaboratorAgent.label"),
detail: getLocalizedString("template.teams.collaboratorAgent.detail"),
data: TemplateNames.TeamsCollaboratorAgent,
};
}
Expand All @@ -146,8 +130,8 @@ export class TeamsAgentCapabilityOptions {
: undefined;
return {
id: "others",
label: getLocalizedString("core.createProjectQuestion.capability.teamsAgent.others.label"),
detail: getLocalizedString("core.createProjectQuestion.capability.teamsAgent.others.detail"),
label: getLocalizedString("template.teams.others.label"),
detail: getLocalizedString("template.teams.others.detail"),
description: description,
};
}
Expand All @@ -173,38 +157,26 @@ export class CustomCopilotRagOptions {
static customize(): OptionItem {
return {
id: "custom-copilot-rag-customize",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomizeOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomizeOption.detail"
),
label: getLocalizedString("template.teams.rag.source.customize.label"),
detail: getLocalizedString("template.teams.rag.source.customize.detail"),
data: TemplateNames.CustomCopilotRagCustomize,
};
}

static azureAISearch(): OptionItem {
return {
id: "custom-copilot-rag-azureAISearch",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.detail"
),
label: getLocalizedString("template.teams.rag.source.azureAISearch.label"),
detail: getLocalizedString("template.teams.rag.source.azureAISearch.detail"),
data: TemplateNames.CustomCopilotRagAzureAISearch,
};
}

static customApi(): OptionItem {
return {
id: "custom-copilot-rag-customApi",
label: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomApiOption.label"
),
detail: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagCustomApiOption.detail"
),
label: getLocalizedString("template.teams.rag.source.customApi.label"),
detail: getLocalizedString("template.teams.rag.source.customApi.detail"),
description: getLocalizedString("core.createProjectQuestion.option.description.preview"),
data: TemplateNames.CustomCopilotRagCustomApi,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,8 @@ export function customCopilotRagNode(): IQTreeNode {
data: {
type: "singleSelect",
name: QuestionNames.CustomCopilotRag,
title: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRagOption.label"
),
placeholder: getLocalizedString(
"core.createProjectQuestion.capability.customCopilotRag.placeholder"
),
title: getLocalizedString("template.teams.rag.label"),
placeholder: getLocalizedString("template.teams.rag.source.placeholder"),
staticOptions: [
CustomCopilotRagOptions.customize(),
CustomCopilotRagOptions.azureAISearch(),
Expand Down
62 changes: 62 additions & 0 deletions packages/fx-core/tests/question/question.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1813,3 +1813,65 @@ describe("updateActionWithMCP", async () => {
// function1 should not be included (wrong runtime type)
});
});

describe("ActionStartOptions", () => {
const sandbox = sinon.createSandbox();
afterEach(() => {
sandbox.restore();
});

describe("all()", () => {
it("should not include MCP option on VSCode platform even when MCPForDA is enabled", () => {
sandbox.stub(featureFlagManager, "getBooleanValue").callsFake((flag) => {
if (flag === FeatureFlags.MCPForDA) return true;
return false;
});
const inputs: Inputs = { platform: Platform.VSCode };
const options = ActionStartOptions.all(inputs, true);
assert.isFalse(options.some((o) => o.id === ActionStartOptions.mcp().id));
assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id));
});

it("should include MCP option on CLI platform when MCPForDA is enabled", () => {
sandbox.stub(featureFlagManager, "getBooleanValue").callsFake((flag) => {
if (flag === FeatureFlags.MCPForDA) return true;
return false;
});
const inputs: Inputs = { platform: Platform.CLI };
const options = ActionStartOptions.all(inputs, true);
assert.isTrue(options.some((o) => o.id === ActionStartOptions.mcp().id));
assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id));
});

it("should not include MCP option on CLI platform when MCPForDA is disabled", () => {
sandbox.stub(featureFlagManager, "getBooleanValue").returns(false);
const inputs: Inputs = { platform: Platform.CLI };
const options = ActionStartOptions.all(inputs, true);
assert.isFalse(options.some((o) => o.id === ActionStartOptions.mcp().id));
});

it("should return newApi and apiSpec when doesProjectExists is false", () => {
const inputs: Inputs = { platform: Platform.VSCode };
const options = ActionStartOptions.all(inputs, false);
assert.equal(options.length, 2);
assert.isTrue(options.some((o) => o.id === ActionStartOptions.newApi().id));
assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id));
});
});

describe("staticAll()", () => {
it("should include apiSpec and mcp when doesProjectExists is true", () => {
const options = ActionStartOptions.staticAll(true);
assert.equal(options.length, 2);
assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id));
assert.isTrue(options.some((o) => o.id === ActionStartOptions.mcp().id));
});

it("should include newApi and apiSpec when doesProjectExists is false", () => {
const options = ActionStartOptions.staticAll(false);
assert.equal(options.length, 2);
assert.isTrue(options.some((o) => o.id === ActionStartOptions.newApi().id));
assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id));
});
});
});
Loading