V4.9.6 feature (#4565)

* Dashboard submenu (#4545)

* add app submenu (#4452)

* add app submenu

* fix

* width & i18n

* optimize submenu code (#4515)

* optimize submenu code

* fix

* fix

* fix

* fix ts

* perf: dashboard sub menu

* doc

---------

Co-authored-by: heheer <heheer@sealos.io>

* feat: value format test

* doc

* Mcp export (#4555)

* feat: mcp server

* feat: mcp server

* feat: mcp server build

* update doc

* perf: path selector (#4556)

* perf: path selector

* fix: docker file path

* perf: add image endpoint to dataset search (#4557)

* perf: add image endpoint to dataset search

* fix: mcp_server url

* human in loop (#4558)

* Support interactive nodes for loops, and enhance the function of merging nested and loop node history messages. (#4552)

* feat: add LoopInteractive definition

* feat: Support LoopInteractive type and update related logic

* fix: Refactor loop handling logic and improve output value initialization

* feat: Add mergeSignId to dispatchLoop and dispatchRunAppNode responses

* feat: Enhance mergeChatResponseData to recursively merge plugin details and improve response handling

* refactor: Remove redundant comments in mergeChatResponseData for clarity

* perf: loop interactive

* perf: human in loop

---------

Co-authored-by: Theresa <63280168+sd0ric4@users.noreply.github.com>

* mcp server ui

* integrate mcp (#4549)

* integrate mcp

* delete unused code

* fix ts

* bug fix

* fix

* support whole mcp tools

* add try catch

* fix

* fix

* fix ts

* fix test

* fix ts

* fix: interactive in v1 completions

* doc

* fix: router path

* fix mcp integrate (#4563)

* fix mcp integrate

* fix ui

* fix: mcp ux

* feat: mcp call title

* remove repeat loading

* fix mcp tools avatar (#4564)

* fix

* fix avatar

* fix update version

* update doc

* fix: value format

* close server and remove cache

* perf: avatar

---------

Co-authored-by: heheer <heheer@sealos.io>
Co-authored-by: Theresa <63280168+sd0ric4@users.noreply.github.com>
This commit is contained in:
Archer
2025-04-16 22:18:51 +08:00
committed by GitHub
parent ab799e13cd
commit 952412f648
166 changed files with 6318 additions and 1263 deletions

View File

@@ -12,7 +12,7 @@ import { useRouter } from 'next/router';
import { useMemo } from 'react';
const WorkOrderShowRouter: { [key: string]: boolean } = {
'/app/list': true,
'/dashboard/apps': true,
'/dataset/list': true,
'/toolkit': true
};

View File

@@ -55,8 +55,14 @@ const Navbar = ({ unread }: { unread: number }) => {
label: t('common:navbar.Studio'),
icon: 'core/app/aiLight',
activeIcon: 'core/app/aiFill',
link: `/app/list`,
activeLink: ['/app/list', '/app/detail']
link: `/dashboard/apps`,
activeLink: [
'/dashboard/apps',
'/app/detail',
'/dashboard/templateMarket',
'/dashboard/[pluginGroupId]',
'/dashboard/mcpServer'
]
},
{
label: t('common:navbar.Datasets'),
@@ -65,13 +71,6 @@ const Navbar = ({ unread }: { unread: number }) => {
link: `/dataset/list`,
activeLink: ['/dataset/list', '/dataset/detail']
},
{
label: t('common:navbar.Toolkit'),
icon: 'phoneTabbar/tool',
activeIcon: 'phoneTabbar/toolFill',
link: `/toolkit`,
activeLink: ['/toolkit']
},
{
label: t('common:navbar.Account'),
icon: 'support/user/userLight',
@@ -125,6 +124,7 @@ const Navbar = ({ unread }: { unread: number }) => {
<Box flex={1}>
{navbarList.map((item) => {
const isActive = item.activeLink.includes(router.pathname);
return (
<Box
key={item.link}

View File

@@ -24,8 +24,14 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
label: t('common:navbar.Studio'),
icon: 'core/app/aiLight',
activeIcon: 'core/app/aiFill',
link: `/app/list`,
activeLink: ['/app/list', '/app/detail'],
link: `/dashboard/apps`,
activeLink: [
'/dashboard/apps',
'/app/detail',
'/dashboard/templateMarket',
'/dashboard/[pluginGroupId]',
'/dashboard/mcpServer'
],
unread: 0
},
{
@@ -36,14 +42,6 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
activeLink: ['/dataset/list', '/dataset/detail'],
unread: 0
},
{
label: t('common:navbar.Toolkit'),
icon: 'phoneTabbar/tool',
activeIcon: 'phoneTabbar/toolFill',
link: `/toolkit`,
activeLink: ['/toolkit'],
unread: 0
},
{
label: t('common:navbar.Account'),
icon: 'support/user/userLight',

View File

@@ -11,6 +11,7 @@ const FolderPath = (props: {
onClick: (parentId: string) => void;
fontSize?: string;
hoverStyle?: BoxProps;
forbidLastClick?: boolean;
}) => {
const { t } = useTranslation();
const {
@@ -19,7 +20,8 @@ const FolderPath = (props: {
FirstPathDom,
onClick,
fontSize,
hoverStyle
hoverStyle,
forbidLastClick = false
} = props;
const concatPaths = useMemo(
@@ -37,41 +39,46 @@ const FolderPath = (props: {
<>{FirstPathDom}</>
) : (
<Flex flex={1}>
{concatPaths.map((item, i) => (
<Flex key={item.parentId || i} alignItems={'center'}>
<Box
fontSize={['xs', fontSize || 'sm']}
py={0.5}
px={1.5}
borderRadius={'md'}
maxW={'45vw'}
className={'textEllipsis'}
{...(i === concatPaths.length - 1 && concatPaths.length > 1
? {
cursor: 'default',
color: 'myGray.700',
fontWeight: 'bold'
}
: {
cursor: 'pointer',
fontWeight: 'medium',
color: 'myGray.500',
_hover: {
bg: 'myGray.100',
...hoverStyle
},
onClick: () => {
onClick(item.parentId);
{concatPaths.map((item, i) => {
const clickStyles = {
cursor: 'pointer',
_hover: {
bg: 'myGray.100',
...hoverStyle
},
onClick: () => {
onClick(item.parentId);
}
};
return (
<Flex key={item.parentId || i} alignItems={'center'}>
<Box
fontSize={['xs', fontSize || 'sm']}
py={0.5}
px={1.5}
borderRadius={'md'}
maxW={'45vw'}
className={'textEllipsis'}
{...(i === concatPaths.length - 1 && concatPaths.length > 1
? {
color: 'myGray.700',
fontWeight: 'bold'
}
})}
>
{item.parentName}
</Box>
{i !== concatPaths.length - 1 && (
<MyIcon name={'common/line'} color={'myGray.500'} mx={1} width={'5px'} />
)}
</Flex>
))}
: {
fontWeight: 'medium',
color: 'myGray.500',
...clickStyles
})}
{...(i === concatPaths.length - 1 && !forbidLastClick && clickStyles)}
>
{item.parentName}
</Box>
{i !== concatPaths.length - 1 && (
<MyIcon name={'common/line'} color={'myGray.500'} mx={1} width={'5px'} />
)}
</Flex>
);
})}
</Flex>
);
};

View File

@@ -55,7 +55,7 @@ export const useChatBox = () => {
`;
} else if (item.type === ChatItemValueTypeEnum.tool) {
return `
\`\`\`Toll
\`\`\`Tool
${JSON.stringify(item.tools, null, 2)}
\`\`\`
`;

View File

@@ -66,6 +66,7 @@ import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import TimeBox from './components/TimeBox';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
import { valueTypeFormat } from '@fastgpt/global/core/workflow/runtime/utils';
const ResponseTags = dynamic(() => import('./components/ResponseTags'));
const FeedbackModal = dynamic(() => import('./components/FeedbackModal'));
@@ -440,12 +441,13 @@ const ChatBox = ({
// Only declared variables are kept
const requestVariables: Record<string, any> = {};
allVariableList?.forEach((item) => {
requestVariables[item.key] =
const val =
variables[item.key] === '' ||
variables[item.key] === undefined ||
variables[item.key] === null
? item.defaultValue
: variables[item.key];
requestVariables[item.key] = valueTypeFormat(val, item.valueType);
});
const responseChatId = getNanoid(24);

View File

@@ -438,6 +438,9 @@ export const WholeResponseContent = ({
label={t('workflow:tool_params.tool_params_result')}
value={activeModule?.toolParamsResult}
/>
{/* tool */}
<Row label={t('workflow:tool.tool_result')} value={activeModule?.toolRes} />
</Box>
) : null;
};