Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>tags/1.9.0
| uv run ruff check --fix . | uv run ruff check --fix . | ||||
| # Format code | # Format code | ||||
| uv run ruff format . | uv run ruff format . | ||||
| - name: ast-grep | - name: ast-grep | ||||
| run: | | run: | | ||||
| uvx --from ast-grep-cli sg --pattern 'db.session.query($WHATEVER).filter($HERE)' --rewrite 'db.session.query($WHATEVER).where($HERE)' -l py --update-all | uvx --from ast-grep-cli sg --pattern 'db.session.query($WHATEVER).filter($HERE)' --rewrite 'db.session.query($WHATEVER).where($HERE)' -l py --update-all | ||||
| uvx --from ast-grep-cli sg --pattern 'session.query($WHATEVER).filter($HERE)' --rewrite 'session.query($WHATEVER).where($HERE)' -l py --update-all | uvx --from ast-grep-cli sg --pattern 'session.query($WHATEVER).filter($HERE)' --rewrite 'session.query($WHATEVER).where($HERE)' -l py --update-all | ||||
| - name: mdformat | - name: mdformat | ||||
| run: | | run: | | ||||
| uvx mdformat . | uvx mdformat . | ||||
| - name: Install pnpm | |||||
| uses: pnpm/action-setup@v4 | |||||
| with: | |||||
| package_json_file: web/package.json | |||||
| run_install: false | |||||
| - name: Setup NodeJS | |||||
| uses: actions/setup-node@v4 | |||||
| with: | |||||
| node-version: 22 | |||||
| cache: pnpm | |||||
| cache-dependency-path: ./web/package.json | |||||
| - name: Web dependencies | |||||
| working-directory: ./web | |||||
| run: pnpm install --frozen-lockfile | |||||
| - name: oxlint | |||||
| working-directory: ./web | |||||
| run: | | |||||
| pnpx oxlint --fix | |||||
| - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 | - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 |
| headerParams = {} | headerParams = {} | ||||
| ) { | ) { | ||||
| const headers = { | const headers = { | ||||
| ...{ | |||||
| Authorization: `Bearer ${this.apiKey}`, | Authorization: `Bearer ${this.apiKey}`, | ||||
| "Content-Type": "application/json", | "Content-Type": "application/json", | ||||
| }, | |||||
| ...headerParams | ...headerParams | ||||
| }; | }; | ||||
| params: { datasetId }, | params: { datasetId }, | ||||
| } = props | } = props | ||||
| const pathname = usePathname() | const pathname = usePathname() | ||||
| const hideSideBar = /documents\/create$/.test(pathname) | |||||
| const hideSideBar = pathname.endsWith('documents/create') | |||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { isCurrentWorkspaceDatasetOperator } = useAppContext() | const { isCurrentWorkspaceDatasetOperator } = useAppContext() | ||||
| if (draft.file) { | if (draft.file) { | ||||
| draft.file.enabled = (draft.file.allowed_file_types?.length ?? 0) > 0 | draft.file.enabled = (draft.file.allowed_file_types?.length ?? 0) > 0 | ||||
| draft.file.image = { | draft.file.image = { | ||||
| ...(draft.file.image || {}), | |||||
| ...draft.file.image, | |||||
| enabled: value, | enabled: value, | ||||
| } | } | ||||
| } | } |
| updateChatTreeNode(targetAnswerId, { | updateChatTreeNode(targetAnswerId, { | ||||
| content: chatList[index].content, | content: chatList[index].content, | ||||
| annotation: { | annotation: { | ||||
| ...(chatList[index].annotation || {}), | |||||
| ...chatList[index].annotation, | |||||
| id: '', | id: '', | ||||
| } as Annotation, | } as Annotation, | ||||
| }) | }) |
| }, [handleSave, hideConfirmAddVar]) | }, [handleSave, hideConfirmAddVar]) | ||||
| const autoAddVar = useCallback(() => { | const autoAddVar = useCallback(() => { | ||||
| onAutoAddPromptVariable?.([ | |||||
| ...notIncludeKeys.map(key => getNewVar(key, 'string')), | |||||
| ]) | |||||
| onAutoAddPromptVariable?.(notIncludeKeys.map(key => getNewVar(key, 'string'))) | |||||
| hideConfirmAddVar() | hideConfirmAddVar() | ||||
| handleSave(true) | handleSave(true) | ||||
| }, [handleSave, hideConfirmAddVar, notIncludeKeys, onAutoAddPromptVariable]) | }, [handleSave, hideConfirmAddVar, notIncludeKeys, onAutoAddPromptVariable]) |
| } | } | ||||
| else { | else { | ||||
| const href = props.href || node.properties?.href | const href = props.href || node.properties?.href | ||||
| if (href && /^#[a-zA-Z0-9_\-]+$/.test(href.toString())) { | |||||
| if (href && /^#[a-zA-Z0-9_-]+$/.test(href.toString())) { | |||||
| const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => { | const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => { | ||||
| e.preventDefault() | e.preventDefault() | ||||
| // scroll to target element if exists within the answer container | // scroll to target element if exists within the answer container |
| if (current.expand) { | if (current.expand) { | ||||
| current.expand = false | current.expand = false | ||||
| newDataList = [...dataList.filter(item => !descendantsIds.includes(item.page_id))] | |||||
| newDataList = dataList.filter(item => !descendantsIds.includes(item.page_id)) | |||||
| } | } | ||||
| else { | else { | ||||
| current.expand = true | current.expand = true | ||||
| setDataList(newDataList) | setDataList(newDataList) | ||||
| } | } | ||||
| const copyValue = new Set([...value]) | |||||
| const copyValue = new Set(value) | |||||
| const handleCheck = (index: number) => { | const handleCheck = (index: number) => { | ||||
| const current = currentDataList[index] | const current = currentDataList[index] | ||||
| const pageId = current.page_id | const pageId = current.page_id | ||||
| copyValue.add(pageId) | copyValue.add(pageId) | ||||
| } | } | ||||
| onSelect(new Set([...copyValue])) | |||||
| onSelect(new Set(copyValue)) | |||||
| } | } | ||||
| const handlePreview = (index: number) => { | const handlePreview = (index: number) => { |
| context.getReferenceProps({ | context.getReferenceProps({ | ||||
| ref, | ref, | ||||
| ...props, | ...props, | ||||
| ...(children.props || {}), | |||||
| ...children.props, | |||||
| 'data-state': context.open ? 'open' : 'closed', | 'data-state': context.open ? 'open' : 'closed', | ||||
| } as React.HTMLProps<HTMLElement>), | } as React.HTMLProps<HTMLElement>), | ||||
| ) | ) |
| return ( | return ( | ||||
| <div className='relative z-10 flex w-full grow flex-col gap-y-3 overflow-y-hidden'> | <div className='relative z-10 flex w-full grow flex-col gap-y-3 overflow-y-hidden'> | ||||
| <div className='absolute bottom-14 left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | <div className='absolute bottom-14 left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | ||||
| {[...Array.from({ length: 15 })].map((_, index) => <Slice key={index} />)} | |||||
| {Array.from({ length: 15 }).map((_, index) => <Slice key={index} />)} | |||||
| </div> | </div> | ||||
| ) | ) | ||||
| } | } |
| return ( | return ( | ||||
| <div className='relative z-10 flex grow flex-col overflow-y-hidden'> | <div className='relative z-10 flex grow flex-col overflow-y-hidden'> | ||||
| <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | ||||
| {[...Array.from({ length: 10 })].map((_, index) => { | |||||
| {Array.from({ length: 10 }).map((_, index) => { | |||||
| return ( | return ( | ||||
| <div key={index} className='flex items-start gap-x-2'> | <div key={index} className='flex items-start gap-x-2'> | ||||
| <Checkbox | <Checkbox |
| return ( | return ( | ||||
| <div className='relative z-10 flex h-full flex-col overflow-y-hidden'> | <div className='relative z-10 flex h-full flex-col overflow-y-hidden'> | ||||
| <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | ||||
| {[...Array.from({ length: 10 })].map((_, index) => { | |||||
| {Array.from({ length: 10 }).map((_, index) => { | |||||
| return ( | return ( | ||||
| <div key={index} className='flex items-start gap-x-2'> | <div key={index} className='flex items-start gap-x-2'> | ||||
| <Checkbox | <Checkbox |
| return ( | return ( | ||||
| <div className='relative z-10 flex grow flex-col overflow-y-hidden'> | <div className='relative z-10 flex grow flex-col overflow-y-hidden'> | ||||
| <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | <div className='absolute left-0 top-0 z-20 h-full w-full bg-dataset-chunk-list-mask-bg' /> | ||||
| {[...Array.from({ length: 5 })].map((_, index) => { | |||||
| {Array.from({ length: 5 }).map((_, index) => { | |||||
| return ( | return ( | ||||
| <div key={index} className='w-full px-11'> | <div key={index} className='w-full px-11'> | ||||
| <CardSkelton /> | <CardSkelton /> |
| } | } | ||||
| const onCancel = () => { | const onCancel = () => { | ||||
| setMetadataParams({ documentType: doc_type || '', metadata: { ...(docDetail?.doc_metadata || {}) } }) | |||||
| setMetadataParams({ documentType: doc_type || '', metadata: { ...docDetail?.doc_metadata } }) | |||||
| setEditStatus(!doc_type) | setEditStatus(!doc_type) | ||||
| if (!doc_type) | if (!doc_type) | ||||
| setShowDocTypes(true) | setShowDocTypes(true) |
| }, [queryPlugins, queryPluginsWithDebounced, searchText, exclude]) | }, [queryPlugins, queryPluginsWithDebounced, searchText, exclude]) | ||||
| const allPlugins = useMemo(() => { | const allPlugins = useMemo(() => { | ||||
| const allPlugins = [...collectionPlugins.filter(plugin => !exclude.includes(plugin.plugin_id))] | |||||
| const allPlugins = collectionPlugins.filter(plugin => !exclude.includes(plugin.plugin_id)) | |||||
| if (plugins?.length) { | if (plugins?.length) { | ||||
| for (let i = 0; i < plugins.length; i++) { | for (let i = 0; i < plugins.length; i++) { |
| } | } | ||||
| export const parseGitHubUrl = (url: string): GitHubUrlInfo => { | export const parseGitHubUrl = (url: string): GitHubUrlInfo => { | ||||
| const match = url.match(/^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/?$/) | |||||
| const match = url.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/?$/) | |||||
| return match ? { isValid: true, owner: match[1], repo: match[2] } : { isValid: false } | return match ? { isValid: true, owner: match[1], repo: match[2] } : { isValid: false } | ||||
| } | } | ||||
| const handleLLMParamsChange = (newParams: FormValue) => { | const handleLLMParamsChange = (newParams: FormValue) => { | ||||
| const newValue = { | const newValue = { | ||||
| ...(value?.completionParams || {}), | |||||
| ...value?.completionParams, | |||||
| completion_params: newParams, | completion_params: newParams, | ||||
| } | } | ||||
| setModel({ | setModel({ |
| const isValidUrl = (string: string) => { | const isValidUrl = (string: string) => { | ||||
| try { | try { | ||||
| const urlPattern = /^(https?:\/\/)((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3})|localhost)(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?/i | |||||
| const urlPattern = /^(https?:\/\/)((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3})|localhost)(:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?/i | |||||
| return urlPattern.test(string) | return urlPattern.test(string) | ||||
| } | } | ||||
| catch { | catch { |
| data: { | data: { | ||||
| ...NODES_INITIAL_DATA[nodeType], | ...NODES_INITIAL_DATA[nodeType], | ||||
| title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${nodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${nodeType}`), | title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${nodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${nodeType}`), | ||||
| ...(toolDefaultValue || {}), | |||||
| ...toolDefaultValue, | |||||
| selected: true, | selected: true, | ||||
| _showAddVariablePopup: (nodeType === BlockEnum.VariableAssigner || nodeType === BlockEnum.VariableAggregator) && !!prevNodeId, | _showAddVariablePopup: (nodeType === BlockEnum.VariableAssigner || nodeType === BlockEnum.VariableAggregator) && !!prevNodeId, | ||||
| _holdAddVariablePopup: false, | _holdAddVariablePopup: false, | ||||
| data: { | data: { | ||||
| ...NODES_INITIAL_DATA[nodeType], | ...NODES_INITIAL_DATA[nodeType], | ||||
| title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${nodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${nodeType}`), | title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${nodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${nodeType}`), | ||||
| ...(toolDefaultValue || {}), | |||||
| ...toolDefaultValue, | |||||
| _connectedSourceHandleIds: [], | _connectedSourceHandleIds: [], | ||||
| _connectedTargetHandleIds: [], | _connectedTargetHandleIds: [], | ||||
| selected: currentNode.data.selected, | selected: currentNode.data.selected, | ||||
| zIndex: currentNode.zIndex, | zIndex: currentNode.zIndex, | ||||
| }) | }) | ||||
| const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap( | const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap( | ||||
| [ | |||||
| ...connectedEdges.map(edge => ({ type: 'remove', edge })), | |||||
| ], | |||||
| connectedEdges.map(edge => ({ type: 'remove', edge })), | |||||
| nodes, | nodes, | ||||
| ) | ) | ||||
| const newNodes = produce(nodes, (draft) => { | const newNodes = produce(nodes, (draft) => { |
| filterVar: (varPayload: Var) => { | filterVar: (varPayload: Var) => { | ||||
| const supportVarTypes = [VarType.string, VarType.number, VarType.secret] | const supportVarTypes = [VarType.string, VarType.number, VarType.secret] | ||||
| if (isSupportFile) | if (isSupportFile) | ||||
| supportVarTypes.push(...[VarType.file, VarType.arrayFile]) | |||||
| supportVarTypes.push(VarType.file, VarType.arrayFile) | |||||
| return supportVarTypes.includes(varPayload.type) | return supportVarTypes.includes(varPayload.type) | ||||
| }, | }, |
| const schema = findPropertyWithPath(draft, path) as Field | const schema = findPropertyWithPath(draft, path) as Field | ||||
| if (schema.type === Type.object) { | if (schema.type === Type.object) { | ||||
| schema.properties = { | schema.properties = { | ||||
| ...(schema.properties || {}), | |||||
| ...schema.properties, | |||||
| '': { | '': { | ||||
| type: Type.string, | type: Type.string, | ||||
| }, | }, | ||||
| } | } | ||||
| if (schema.type === Type.array && schema.items && schema.items.type === Type.object) { | if (schema.type === Type.array && schema.items && schema.items.type === Type.object) { | ||||
| schema.items.properties = { | schema.items.properties = { | ||||
| ...(schema.items.properties || {}), | |||||
| ...schema.items.properties, | |||||
| '': { | '': { | ||||
| type: Type.string, | type: Type.string, | ||||
| }, | }, |
| data: { | data: { | ||||
| ...NODES_INITIAL_DATA[type], | ...NODES_INITIAL_DATA[type], | ||||
| title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${type}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${type}`), | title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${type}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${type}`), | ||||
| ...(toolDefaultValue || {}), | |||||
| ...toolDefaultValue, | |||||
| _isCandidate: true, | _isCandidate: true, | ||||
| }, | }, | ||||
| position: { | position: { |
| } | } | ||||
| export const fetchConversations = async (isInstalledApp: boolean, installedAppId = '', last_id?: string, pinned?: boolean, limit?: number) => { | export const fetchConversations = async (isInstalledApp: boolean, installedAppId = '', last_id?: string, pinned?: boolean, limit?: number) => { | ||||
| return getAction('get', isInstalledApp)(getUrl('conversations', isInstalledApp, installedAppId), { params: { ...{ limit: limit || 20 }, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } }) as Promise<AppConversationData> | |||||
| return getAction('get', isInstalledApp)(getUrl('conversations', isInstalledApp, installedAppId), { params: { limit: limit || 20, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } }) as Promise<AppConversationData> | |||||
| } | } | ||||
| export const pinConversation = async (isInstalledApp: boolean, installedAppId = '', id: string) => { | export const pinConversation = async (isInstalledApp: boolean, installedAppId = '', id: string) => { |
| export const formatBooleanInputs = (useInputs?: PromptVariable[] | null, inputs?: Record<string, string | number | object | boolean> | null) => { | export const formatBooleanInputs = (useInputs?: PromptVariable[] | null, inputs?: Record<string, string | number | object | boolean> | null) => { | ||||
| if(!useInputs) | if(!useInputs) | ||||
| return inputs | return inputs | ||||
| const res = { ...(inputs || {}) } | |||||
| const res = { ...inputs } | |||||
| useInputs.forEach((item) => { | useInputs.forEach((item) => { | ||||
| const isBooleanInput = item.type === 'boolean' | const isBooleanInput = item.type === 'boolean' | ||||
| if (isBooleanInput) { | if (isBooleanInput) { |