chore: merge mcp components (#7167)
* take1 * depreacate stdio and sse mcp components * optionals * rodrigo fixes * session management * update init * mcp component integration test * broken * [autofix.ci] apply automated fixes * fix url input name * upated MCP * Update mcp_component.py * [autofix.ci] apply automated fixes * update to the MCP component * [autofix.ci] apply automated fixes * mostly working * [autofix.ci] apply automated fixes * Update mcp_component.py * [autofix.ci] apply automated fixes * update component * [autofix.ci] apply automated fixes * Update mcp_component.py * rename component because Simon * icon and description for simon * fix integration test * fix test * Update mcp_component.py * update and basic QoL * [autofix.ci] apply automated fixes * refactor clients to util and use flow names not IDs in mcp.py * integration test * take out traces * ✨ (edit-tools.spec.ts): add test for user to be able to edit tools in the frontend application. * session fix * fix content output * ♻️ (util.py): remove redundant constant HTTP_TEMPORARY_REDIRECT and replace its usage with httpx.codes.TEMPORARY_REDIRECT for better code readability and maintainability * [autofix.ci] apply automated fixes * 🐛 (utils.ts): fix potential null pointer error when converting words to title case by adding null check before accessing properties * 🐛 (genericIconComponent/index.tsx): Fix issue with optional chaining in mapping function 🐛 (renderIconComponent/index.tsx): Fix issue with optional chaining in mapping function 🐛 (button.tsx): Fix issue with optional chaining in mapping function 🐛 (utils.ts): Fix issue with optional chaining in mapping functions * 🐛 (language-select.tsx): Fix potential null pointer error when mapping over allLanguages array * ✨ (constants.ts): add support for multiple languages in the application by defining an array of language options ♻️ (audio-settings-dialog.tsx, language-select.tsx): refactor to import the array of all languages from constants.ts instead of duplicating it in each file * ✅ (auto-login-off.spec.ts): add a 2-second delay before continuing the test to ensure proper loading and rendering of elements on the page * ⬆️ (filterEdge-shard-0.spec.ts): reduce wait time for page interactions to improve test performance ⬆️ (playground.spec.ts): optimize wait times for page interactions to enhance test efficiency --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
parent
4527c473be
commit
59b2ed7765
25 changed files with 1200 additions and 331 deletions
1
src/frontend/package-lock.json
generated
1
src/frontend/package-lock.json
generated
|
|
@ -706,6 +706,7 @@
|
|||
},
|
||||
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
|
||||
"version": "1.3.0",
|
||||
"extraneous": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const ForwardedIconComponent = memo(
|
|||
nodeIconsLucide[
|
||||
name
|
||||
?.split("-")
|
||||
?.map((x) => String(x[0]).toUpperCase() + String(x).slice(1))
|
||||
?.map((x) => String(x[0])?.toUpperCase() + String(x).slice(1))
|
||||
?.join("")
|
||||
];
|
||||
if (!TargetIcon) {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default function RenderKey({
|
|||
className={cn(tableRender ? "h-4 w-4" : "h-3 w-3")}
|
||||
/>
|
||||
) : (
|
||||
<span>{value.toUpperCase()}</span>
|
||||
<span>{value?.toUpperCase()}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -61,9 +61,11 @@ export interface ButtonProps
|
|||
|
||||
function toTitleCase(text: string) {
|
||||
return text
|
||||
.split(" ")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join(" ");
|
||||
?.split(" ")
|
||||
?.map(
|
||||
(word) => word?.charAt(0)?.toUpperCase() + word?.slice(1)?.toLowerCase(),
|
||||
)
|
||||
?.join(" ");
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
|
|
|
|||
|
|
@ -1022,3 +1022,18 @@ export const IS_AUTO_LOGIN =
|
|||
|
||||
export const AUTO_LOGIN_RETRY_DELAY = 2000;
|
||||
export const AUTO_LOGIN_MAX_RETRY_DELAY = 60000;
|
||||
|
||||
export const ALL_LANGUAGES = [
|
||||
{ value: "en-US", name: "English (US)" },
|
||||
{ value: "en-GB", name: "English (UK)" },
|
||||
{ value: "it-IT", name: "Italian" },
|
||||
{ value: "fr-FR", name: "French" },
|
||||
{ value: "es-ES", name: "Spanish" },
|
||||
{ value: "de-DE", name: "German" },
|
||||
{ value: "ja-JP", name: "Japanese" },
|
||||
{ value: "pt-BR", name: "Portuguese (Brazil)" },
|
||||
{ value: "zh-CN", name: "Chinese (Simplified)" },
|
||||
{ value: "ru-RU", name: "Russian" },
|
||||
{ value: "ar-SA", name: "Arabic" },
|
||||
{ value: "hi-IN", name: "Hindi" },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -21,21 +21,6 @@ import LanguageSelect from "./components/language-select";
|
|||
import MicrophoneSelect from "./components/microphone-select";
|
||||
import VoiceSelect from "./components/voice-select";
|
||||
|
||||
const ALL_LANGUAGES = [
|
||||
{ value: "en-US", name: "English (US)" },
|
||||
{ value: "en-GB", name: "English (UK)" },
|
||||
{ value: "it-IT", name: "Italian" },
|
||||
{ value: "fr-FR", name: "French" },
|
||||
{ value: "es-ES", name: "Spanish" },
|
||||
{ value: "de-DE", name: "German" },
|
||||
{ value: "ja-JP", name: "Japanese" },
|
||||
{ value: "pt-BR", name: "Portuguese (Brazil)" },
|
||||
{ value: "zh-CN", name: "Chinese (Simplified)" },
|
||||
{ value: "ru-RU", name: "Russian" },
|
||||
{ value: "ar-SA", name: "Arabic" },
|
||||
{ value: "hi-IN", name: "Hindi" },
|
||||
];
|
||||
|
||||
interface SettingsVoiceModalProps {
|
||||
children?: React.ReactNode;
|
||||
userOpenaiApiKey?: string;
|
||||
|
|
@ -415,7 +400,6 @@ const SettingsVoiceModal = ({
|
|||
<LanguageSelect
|
||||
language={currentLanguage}
|
||||
handleSetLanguage={handleSetLanguage}
|
||||
allLanguages={ALL_LANGUAGES}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ALL_LANGUAGES } from "@/constants/constants";
|
||||
import IconComponent from "../../../../../../../../../../components/common/genericIconComponent";
|
||||
import ShadTooltip from "../../../../../../../../../../components/common/shadTooltipComponent";
|
||||
import {
|
||||
|
|
@ -12,13 +13,11 @@ import {
|
|||
interface LanguageSelectProps {
|
||||
language: string;
|
||||
handleSetLanguage: (value: string) => void;
|
||||
allLanguages: { value: string; name: string }[];
|
||||
}
|
||||
|
||||
const LanguageSelect = ({
|
||||
language,
|
||||
handleSetLanguage,
|
||||
allLanguages,
|
||||
}: LanguageSelectProps) => {
|
||||
return (
|
||||
<div className="grid w-full items-center gap-2">
|
||||
|
|
@ -41,7 +40,7 @@ const LanguageSelect = ({
|
|||
</SelectTrigger>
|
||||
<SelectContent className="max-h-[200px]">
|
||||
<SelectGroup>
|
||||
{allLanguages.map((lang) => (
|
||||
{ALL_LANGUAGES?.map((lang) => (
|
||||
<SelectItem key={lang?.value} value={lang?.value}>
|
||||
<div className="max-w-[220px] truncate text-left">
|
||||
{lang?.name}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ export function toNormalCase(str: string): string {
|
|||
.split("_")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
return word[0]?.toUpperCase() + word.slice(1)?.toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
return word?.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
|
|
@ -57,9 +57,9 @@ export function toNormalCase(str: string): string {
|
|||
.split("-")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
return word[0]?.toUpperCase() + word.slice(1)?.toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
return word?.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
|
|
@ -69,11 +69,11 @@ export function normalCaseToSnakeCase(str: string): string {
|
|||
.split(" ")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
return word[0]?.toUpperCase() + word.slice(1)?.toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
return word?.toLowerCase();
|
||||
})
|
||||
.join("_");
|
||||
?.join("_");
|
||||
}
|
||||
|
||||
export function toTitleCase(
|
||||
|
|
@ -82,41 +82,41 @@ export function toTitleCase(
|
|||
): string {
|
||||
if (!str) return "";
|
||||
let result = str
|
||||
.split("_")
|
||||
.map((word, index) => {
|
||||
?.split("_")
|
||||
?.map((word, index) => {
|
||||
if (isNodeField) return word;
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
||||
word[0]?.toUpperCase() + word.slice(1)?.toLowerCase(),
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
return checkUpperWords(word?.toLowerCase());
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
return result
|
||||
.split("-")
|
||||
.map((word, index) => {
|
||||
?.split("-")
|
||||
?.map((word, index) => {
|
||||
if (isNodeField) return word;
|
||||
if (index === 0) {
|
||||
return checkUpperWords(
|
||||
word[0].toUpperCase() + word.slice(1).toLowerCase(),
|
||||
word[0]?.toUpperCase() + word.slice(1)?.toLowerCase(),
|
||||
);
|
||||
}
|
||||
return checkUpperWords(word.toLowerCase());
|
||||
return checkUpperWords(word?.toLowerCase());
|
||||
})
|
||||
.join(" ");
|
||||
?.join(" ");
|
||||
}
|
||||
|
||||
export const upperCaseWords: string[] = ["llm", "uri"];
|
||||
export function checkUpperWords(str: string): string {
|
||||
const words = str.split(" ").map((word) => {
|
||||
return upperCaseWords.includes(word.toLowerCase())
|
||||
? word.toUpperCase()
|
||||
: word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
const words = str?.split(" ")?.map((word) => {
|
||||
return upperCaseWords.includes(word?.toLowerCase())
|
||||
? word?.toUpperCase()
|
||||
: word[0]?.toUpperCase() + word.slice(1)?.toLowerCase();
|
||||
});
|
||||
|
||||
return words.join(" ");
|
||||
return words?.join(" ");
|
||||
}
|
||||
|
||||
export function buildInputs(): string {
|
||||
|
|
|
|||
|
|
@ -215,6 +215,8 @@ test(
|
|||
).isVisible(),
|
||||
);
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await awaitBootstrapTest(page, { skipGoto: true });
|
||||
|
||||
await page.getByTestId("side_nav_options_all-templates").click();
|
||||
|
|
|
|||
|
|
@ -73,9 +73,11 @@ test(
|
|||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await visibleElementHandle.hover().then(async () => {
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(
|
||||
page.getByText("Drag to connect compatible outputs").first(),
|
||||
).toBeVisible();
|
||||
|
|
@ -105,7 +107,11 @@ test(
|
|||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await visibleElementHandle.hover().then(async () => {
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(
|
||||
page.getByText("Drag to connect compatible outputs").first(),
|
||||
).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -164,13 +164,21 @@ test(
|
|||
await page.getByTestId("chat-message-User-session_after_delete").click();
|
||||
await expect(page.getByTestId("session-selector")).toBeVisible();
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// check helpful button
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await page.getByTestId("helpful-button").click();
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbUpIconCustom")).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("helpful-button").click();
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbUpIconCustom")).toBeVisible({
|
||||
|
|
@ -178,26 +186,38 @@ test(
|
|||
visible: false,
|
||||
});
|
||||
// check not helpful button
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await page.getByTestId("not-helpful-button").click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbDownIconCustom")).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
await page.getByTestId("not-helpful-button").click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbDownIconCustom")).toBeVisible({
|
||||
timeout: 10000,
|
||||
visible: false,
|
||||
});
|
||||
// check switch feedback
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await page.getByTestId("helpful-button").click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbUpIconCustom")).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
await page.getByTestId("not-helpful-button").click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("chat-message-AI-session_after_delete").hover();
|
||||
await expect(page.getByTestId("icon-ThumbDownIconCustom")).toBeVisible({
|
||||
timeout: 10000,
|
||||
|
|
|
|||
76
src/frontend/tests/extended/features/edit-tools.spec.ts
Normal file
76
src/frontend/tests/extended/features/edit-tools.spec.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
|
||||
test(
|
||||
"user should be able to edit tools",
|
||||
{ tag: ["@release"] },
|
||||
async ({ page }) => {
|
||||
await awaitBootstrapTest(page);
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
|
||||
await page.getByTestId("sidebar-search-input").click();
|
||||
await page.getByTestId("sidebar-search-input").fill("api request");
|
||||
|
||||
await page.waitForSelector('[data-testid="dataAPI Request"]', {
|
||||
timeout: 3000,
|
||||
});
|
||||
|
||||
await page
|
||||
.getByTestId("dataAPI Request")
|
||||
.hover()
|
||||
.then(async () => {
|
||||
await page.getByTestId("add-component-button-api-request").click();
|
||||
});
|
||||
|
||||
await page.waitForSelector(
|
||||
'[data-testid="generic-node-title-arrangement"]',
|
||||
{
|
||||
timeout: 3000,
|
||||
},
|
||||
);
|
||||
|
||||
await page.getByTestId("generic-node-title-arrangement").click();
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("tool-mode-button").click();
|
||||
|
||||
await page.locator('[data-testid="icon-Hammer"]').nth(1).waitFor({
|
||||
timeout: 3000,
|
||||
state: "visible",
|
||||
});
|
||||
|
||||
await page.getByTestId("icon-Hammer").nth(1).click();
|
||||
|
||||
await page.waitForSelector("text=edit tools", { timeout: 30000 });
|
||||
|
||||
const rowsCount = await page.getByRole("gridcell").count();
|
||||
|
||||
expect(rowsCount).toBeGreaterThan(3);
|
||||
|
||||
expect(await page.getByRole("switch").nth(0).isChecked()).toBe(true);
|
||||
|
||||
await page.getByRole("switch").nth(0).click();
|
||||
|
||||
expect(await page.getByRole("switch").nth(0).isChecked()).toBe(false);
|
||||
|
||||
await page.getByText("Save").last().click();
|
||||
|
||||
await page.waitForSelector(
|
||||
'[data-testid="generic-node-title-arrangement"]',
|
||||
{
|
||||
timeout: 3000,
|
||||
},
|
||||
);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.getByTestId("icon-Hammer").nth(1).click();
|
||||
|
||||
await page.waitForSelector("text=edit tools", { timeout: 30000 });
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
expect(await page.getByRole("switch").nth(0).isChecked()).toBe(false);
|
||||
},
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue