feat(agent-v2): sync nightly updates to main (#37599)

Co-authored-by: Jingyi-Dify <jingyi.qi@dify.ai>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: Bond Zhu <783504079@qq.com>
Co-authored-by: Yansong Zhang <916125788@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
This commit is contained in:
盐粒 Yanli
2026-06-18 05:03:34 +00:00
committed by GitHub
co-authored by Jingyi-Dify yyh Joel autofix-ci[bot] hjlarry Bond Zhu Yansong Zhang yyh
parent 79ab6c2ecd
commit 3f2d22ec0f
336 changed files with 26946 additions and 1282 deletions
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react'
import type { Credential, PluginPayload } from '../types'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { fireEvent, render, screen } from '@testing-library/react'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { AuthCategory, CredentialTypeEnum } from '../types'
@@ -118,6 +118,24 @@ describe('AuthorizedInNode Component', () => {
expect(screen.getByText('plugin.auth.workspaceDefault'))!.toBeInTheDocument()
})
it('should expose the workspace default credential id when requested', async () => {
const AuthorizedInNode = (await import('../authorized-in-node')).default
const onDefaultCredentialChange = vi.fn()
const pluginPayload = createPluginPayload()
render(
<AuthorizedInNode
pluginPayload={pluginPayload}
onAuthorizationItemClick={vi.fn()}
onDefaultCredentialChange={onDefaultCredentialChange}
/>,
{ wrapper: createWrapper() },
)
await waitFor(() => {
expect(onDefaultCredentialChange).toHaveBeenCalledWith('test-credential-id')
})
})
it('should render credential name when credentialId matches', async () => {
const AuthorizedInNode = (await import('../authorized-in-node')).default
const credential = createCredential({ id: 'selected-id', name: 'My Credential' })
@@ -10,6 +10,7 @@ import { RiArrowDownSLine } from '@remixicon/react'
import {
memo,
useCallback,
useEffect,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
@@ -22,11 +23,13 @@ type AuthorizedInNodeProps = {
pluginPayload: PluginPayload
onAuthorizationItemClick: (id: string) => void
credentialId?: string
onDefaultCredentialChange?: (id?: string) => void
}
const AuthorizedInNode = ({
pluginPayload,
onAuthorizationItemClick,
credentialId,
onDefaultCredentialChange,
}: AuthorizedInNodeProps) => {
const { t } = useTranslation()
const [isOpen, setIsOpen] = useState(false)
@@ -38,6 +41,12 @@ const AuthorizedInNode = ({
invalidPluginCredentialInfo,
notAllowCustomCredential,
} = usePluginAuth(pluginPayload, true, credentialId ? [credentialId] : undefined)
const defaultCredentialId = credentials.find(c => c.is_default)?.id
useEffect(() => {
onDefaultCredentialChange?.(defaultCredentialId)
}, [defaultCredentialId, onDefaultCredentialChange])
const renderTrigger = useCallback((open?: boolean) => {
let label = ''
let removed = false
@@ -108,9 +117,15 @@ const AuthorizedInNode = ({
},
]
const handleAuthorizationItemClick = useCallback((id: string) => {
onAuthorizationItemClick(id)
onAuthorizationItemClick(
id === '__workspace_default__' && onDefaultCredentialChange
? defaultCredentialId || id
: id,
)
setIsOpen(false)
}, [
defaultCredentialId,
onDefaultCredentialChange,
onAuthorizationItemClick,
setIsOpen,
])