Commit a1674a5f by Archer Committed by GitHub

fix: action (#7128)

* fix: action

* perf: modal

* fix: openapi
parent 4f30121d
...@@ -119,6 +119,13 @@ jobs: ...@@ -119,6 +119,13 @@ jobs:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
if: matrix.image == 'fastgpt-agent-sandbox-proxy'
uses: docker/login-action@v3
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.FASTGPT_ALI_IMAGE_USER }}
password: ${{ secrets.FASTGPT_ALI_IMAGE_PSW }}
- name: Download digests - name: Download digests
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
...@@ -132,9 +139,20 @@ jobs: ...@@ -132,9 +139,20 @@ jobs:
- name: Set image name and tag - name: Set image name and tag
run: | run: |
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${{ matrix.tag }}" >> $GITHUB_ENV echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${{ matrix.tag }}" >> $GITHUB_ENV
if [[ "${{ matrix.image }}" == "fastgpt-agent-sandbox-proxy" ]]; then
echo "Ali_Tag=${{ secrets.FASTGPT_ALI_IMAGE_PREFIX }}/${{ matrix.image }}:${{ matrix.tag }}" >> $GITHUB_ENV
fi
- name: Create manifest list and push - name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests working-directory: ${{ runner.temp }}/digests
run: | run: |
docker buildx imagetools create -t "${Git_Tag}" \ TAGS="${Git_Tag}"
if [[ -n "${Ali_Tag:-}" ]]; then
TAGS="$(echo -e "${TAGS}\n${Ali_Tag}")"
fi
for TAG in $TAGS; do
docker buildx imagetools create -t "${TAG}" \
$(printf 'ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}@sha256:%s ' *) $(printf 'ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}@sha256:%s ' *)
sleep 5
done
...@@ -129,5 +129,21 @@ export const GetPreviewNodeQuerySchema = z.union([ ...@@ -129,5 +129,21 @@ export const GetPreviewNodeQuerySchema = z.union([
export type GetPreviewNodeQuery = z.infer<typeof GetPreviewNodeQuerySchema>; export type GetPreviewNodeQuery = z.infer<typeof GetPreviewNodeQuerySchema>;
export const GetPreviewNodeQueryOpenAPISchema = GetPreviewNodeBaseQuerySchema.extend({
versionId: z.string().optional().meta({
example: '68ad85a7463006c963799a05',
description:
'工具版本 ID,与 getLatestVersion 必须二选一。传空字符串时返回最新版节点数据,但响应中的 version 为空'
}),
getLatestVersion: BoolSchema.optional().meta({
example: true,
description:
'是否获取最新版本 ID,与 versionId 必须二选一。只能传 true,表示返回最新版节点数据并带上具体 version'
})
}).meta({
description:
'OpenAPI 文档参数模型。运行时仍由 GetPreviewNodeQuerySchema 校验 versionId/getLatestVersion 的二选一约束。'
});
export const GetPreviewNodeResponseSchema = ToolPreviewNodeResponseSchema; export const GetPreviewNodeResponseSchema = ToolPreviewNodeResponseSchema;
export type GetPreviewNodeResponse = z.infer<typeof GetPreviewNodeResponseSchema>; export type GetPreviewNodeResponse = z.infer<typeof GetPreviewNodeResponseSchema>;
import type { OpenAPIPath } from '../../../type'; import type { OpenAPIPath } from '../../../type';
import { TagsMap } from '../../../tag'; import { TagsMap } from '../../../tag';
import { import {
GetPreviewNodeQuerySchema, GetPreviewNodeQueryOpenAPISchema,
GetPreviewNodeResponseSchema, GetPreviewNodeResponseSchema,
GetSystemToolTemplatesBodySchema, GetSystemToolTemplatesBodySchema,
GetSystemToolTemplatesResponseSchema, GetSystemToolTemplatesResponseSchema,
...@@ -61,7 +61,7 @@ export const ToolPath: OpenAPIPath = { ...@@ -61,7 +61,7 @@ export const ToolPath: OpenAPIPath = {
'根据工具 ID 和版本配置生成可插入工作流画布的工具节点模板,支持系统工具和我的工具(MCP、HTTP、工作流工具)', '根据工具 ID 和版本配置生成可插入工作流画布的工具节点模板,支持系统工具和我的工具(MCP、HTTP、工作流工具)',
tags: [TagsMap.appSystemTool, TagsMap.httpTools, TagsMap.mcpTools, TagsMap.pluginTeam], tags: [TagsMap.appSystemTool, TagsMap.httpTools, TagsMap.mcpTools, TagsMap.pluginTeam],
requestParams: { requestParams: {
query: GetPreviewNodeQuerySchema query: GetPreviewNodeQueryOpenAPISchema
}, },
responses: { responses: {
200: { 200: {
......
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { openAPIDocument } from '@fastgpt/global/openapi';
import { GetPreviewNodeQuerySchema } from '@fastgpt/global/openapi/core/app/tool/api'; import { GetPreviewNodeQuerySchema } from '@fastgpt/global/openapi/core/app/tool/api';
describe('GetPreviewNodeQuerySchema', () => { describe('GetPreviewNodeQuerySchema', () => {
...@@ -51,4 +52,8 @@ describe('GetPreviewNodeQuerySchema', () => { ...@@ -51,4 +52,8 @@ describe('GetPreviewNodeQuerySchema', () => {
}).success }).success
).toBe(false); ).toBe(false);
}); });
it('keeps full OpenAPI document generation compatible with query params', () => {
expect(openAPIDocument.paths['/core/app/tool/getPreviewNode']?.get).toBeDefined();
});
}); });
import React from 'react'; import React from 'react';
import { ModalBody, useTheme, ModalFooter, Button, Box, Card, Flex, Grid } from '@chakra-ui/react'; import { useTheme, ModalFooter, Button, Box, Card, Flex, Grid } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import Avatar from '@fastgpt/web/components/common/Avatar'; import Avatar from '@fastgpt/web/components/common/Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
...@@ -9,6 +9,7 @@ import dynamic from 'next/dynamic'; ...@@ -9,6 +9,7 @@ import dynamic from 'next/dynamic';
import { type AdminFbkType } from '@fastgpt/global/core/chat/type'; import { type AdminFbkType } from '@fastgpt/global/core/chat/type';
import SelectCollections from '@/web/core/dataset/components/SelectCollections'; import SelectCollections from '@/web/core/dataset/components/SelectCollections';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
const InputDataModal = dynamic( const InputDataModal = dynamic(
() => import('@/pageComponents/dataset/detail/components/InputDataModal') () => import('@/pageComponents/dataset/detail/components/InputDataModal')
...@@ -49,7 +50,7 @@ const SelectMarkCollection = ({ ...@@ -49,7 +50,7 @@ const SelectMarkCollection = ({
isLoading={isFetching} isLoading={isFetching}
tips={t('common:core.chat.Select dataset Desc')} tips={t('common:core.chat.Select dataset Desc')}
> >
<ModalBody flex={'1 0 0'} overflowY={'auto'}> {datasets.length === 0 && <EmptyTip text={t('chat:empty_directory')}></EmptyTip>}
<Grid <Grid
display={'grid'} display={'grid'}
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']} gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']}
...@@ -79,7 +80,11 @@ const SelectMarkCollection = ({ ...@@ -79,7 +80,11 @@ const SelectMarkCollection = ({
> >
<Flex alignItems={'center'} h={'38px'}> <Flex alignItems={'center'} h={'38px'}>
<Avatar src={item.avatar} w={'2rem'} borderRadius={'sm'}></Avatar> <Avatar src={item.avatar} w={'2rem'} borderRadius={'sm'}></Avatar>
<Box ml={3}>{item.name}</Box> <MyTooltip label={item.name} showOnlyWhenOverflow>
<Box ml={3} className="textEllipsis">
{item.name}
</Box>
</MyTooltip>
</Flex> </Flex>
<Flex justifyContent={'flex-end'} alignItems={'center'} fontSize={'sm'}> <Flex justifyContent={'flex-end'} alignItems={'center'} fontSize={'sm'}>
<MyIcon mr={1} name="kbTest" w={'12px'} /> <MyIcon mr={1} name="kbTest" w={'12px'} />
...@@ -90,8 +95,6 @@ const SelectMarkCollection = ({ ...@@ -90,8 +95,6 @@ const SelectMarkCollection = ({
})() })()
)} )}
</Grid> </Grid>
{datasets.length === 0 && <EmptyTip text={t('chat:empty_directory')}></EmptyTip>}
</ModalBody>
</DatasetSelectModal> </DatasetSelectModal>
)} )}
...@@ -109,7 +112,6 @@ const SelectMarkCollection = ({ ...@@ -109,7 +112,6 @@ const SelectMarkCollection = ({
}); });
}} }}
CustomFooter={ CustomFooter={
<ModalFooter>
<Button <Button
variant={'whiteBase'} variant={'whiteBase'}
mr={2} mr={2}
...@@ -122,7 +124,6 @@ const SelectMarkCollection = ({ ...@@ -122,7 +124,6 @@ const SelectMarkCollection = ({
> >
{t('common:last_step')} {t('common:last_step')}
</Button> </Button>
</ModalFooter>
} }
/> />
)} )}
......
import { getDatasets, getDatasetPaths } from '@/web/core/dataset/api'; import { getDatasets, getDatasetPaths } from '@/web/core/dataset/api';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/v2/common/MyModal';
import React, { type Dispatch, useState } from 'react'; import React, { type Dispatch, useState } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import FolderPath from '@/components/common/folder/Path'; import FolderPath from '@/components/common/folder/Path';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import type { import type {
ParentIdType, ParentIdType,
...@@ -32,7 +31,6 @@ const DatasetSelectContainer = ({ ...@@ -32,7 +31,6 @@ const DatasetSelectContainer = ({
return ( return (
<MyModal <MyModal
iconSrc="/imgs/workflow/db.png"
title={ title={
<Box fontWeight={'normal'}> <Box fontWeight={'normal'}>
<FolderPath <FolderPath
...@@ -58,10 +56,9 @@ const DatasetSelectContainer = ({ ...@@ -58,10 +56,9 @@ const DatasetSelectContainer = ({
w={'100%'} w={'100%'}
maxW={['90vw', '900px']} maxW={['90vw', '900px']}
isCentered isCentered
isLoading={isLoading}
> >
<MyBox isLoading={isLoading} h={'100%'}>
{children} {children}
</MyBox>
</MyModal> </MyModal>
); );
}; };
......
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/v2/common/MyModal';
import FolderPath from '@/components/common/folder/Path'; import FolderPath from '@/components/common/folder/Path';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { import {
...@@ -118,7 +118,7 @@ const SelectCollections = ({ ...@@ -118,7 +118,7 @@ const SelectCollections = ({
w={'100%'} w={'100%'}
h={['90vh', '80vh']} h={['90vh', '80vh']}
isCentered isCentered
iconSrc="/imgs/modal/move.svg" isLoading={isLoading}
title={ title={
<Box> <Box>
<FolderPath <FolderPath
...@@ -148,8 +148,20 @@ const SelectCollections = ({ ...@@ -148,8 +148,20 @@ const SelectCollections = ({
/> />
</Box> </Box>
} }
footer={
CustomFooter ? (
<>{CustomFooter}</>
) : (
<Button
isLoading={isResponding}
isDisabled={type === 'collection' && selectedDatasetCollectionIds.length === 0}
onClick={mutate}
>
{type === 'folder' ? t('common:confirm_move') : t('common:Confirm')}
</Button>
)
}
> >
<ModalBody flex={'1 0 0'} overflow={'auto'}>
<Grid <Grid
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']} gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
gridGap={3} gridGap={3}
...@@ -208,21 +220,6 @@ const SelectCollections = ({ ...@@ -208,21 +220,6 @@ const SelectCollections = ({
{collections.length === 0 && ( {collections.length === 0 && (
<EmptyTip pt={'20vh'} text={t('common:no_child_folder')}></EmptyTip> <EmptyTip pt={'20vh'} text={t('common:no_child_folder')}></EmptyTip>
)} )}
<Loading loading={isLoading} fixed={false} />
</ModalBody>
{CustomFooter ? (
<>{CustomFooter}</>
) : (
<ModalFooter>
<Button
isLoading={isResponding}
isDisabled={type === 'collection' && selectedDatasetCollectionIds.length === 0}
onClick={mutate}
>
{type === 'folder' ? t('common:confirm_move') : t('common:Confirm')}
</Button>
</ModalFooter>
)}
</MyModal> </MyModal>
); );
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment