Files
dify/e2e/features/step-definitions/agent-v2/knowledge.steps.ts
yyh 1b3e8e9943 chore(agent-v2): sync daily changes (#38298)
Signed-off-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: zyssyz123 <916125788@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: 盐粒 Yanli <yanli@dify.ai>
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
2026-07-05 08:09:38 +00:00

264 lines
8.8 KiB
TypeScript

import type { Locator } from '@playwright/test'
import type { DifyWorld } from '../../support/world'
import { Given, Then, When } from '@cucumber/cucumber'
import { expect } from '@playwright/test'
import {
createConfiguredTestAgent,
getAgentComposerDraft,
} from '../../agent-v2/support/agent'
import { agentBuilderFixedInputs, agentBuilderPreseededResources } from '../../agent-v2/support/agent-builder-resources'
import {
createAgentSoulConfigWithKnowledgeDataset,
normalAgentSoulConfig,
} from '../../agent-v2/support/agent-soul'
import { asArray, asRecord } from '../../agent-v2/support/preflight/common'
import { getCurrentAgentId } from './configure-helpers'
const getPreseededKnowledgeBase = (world: DifyWorld) => {
const resource = world.agentBuilder.preflight.preseededResources[
agentBuilderPreseededResources.agentKnowledgeBase
]
if (!resource || resource.kind !== 'dataset') {
throw new Error(
`Preseeded dataset "${agentBuilderPreseededResources.agentKnowledgeBase}" is not available. Run the matching preflight step first.`,
)
}
return resource
}
const getKnowledgeSection = (world: DifyWorld) =>
world.getPage().getByRole('region', { name: 'Knowledge Retrieval' })
const getKnowledgeSets = async (agentId: string) => {
const draft = await getAgentComposerDraft(agentId)
return asArray(asRecord(draft.agent_soul?.knowledge).sets)
}
const openNewKnowledgeRetrievalDialog = async (world: DifyWorld) => {
const knowledgeSection = getKnowledgeSection(world)
await expect(knowledgeSection).toBeVisible({ timeout: 30_000 })
await knowledgeSection.getByRole('button', { name: 'Add knowledge retrieval' }).click()
const dialog = world.getPage().getByRole('dialog', {
name: 'Knowledge Retrieval · Agent decide',
})
await expect(dialog).toBeVisible()
return dialog
}
const selectPreseededKnowledgeBase = async (
world: DifyWorld,
dialog: Locator,
) => {
const knowledgeBase = getPreseededKnowledgeBase(world)
const page = world.getPage()
await dialog.getByRole('button', { name: 'Add Knowledge' }).click()
const selectorDialog = page.getByRole('dialog', { name: 'Select reference Knowledge' })
await expect(selectorDialog).toBeVisible()
await selectorDialog.getByRole('button').filter({ hasText: knowledgeBase.name }).click()
await selectorDialog.getByRole('button', { name: 'Add' }).click()
}
const openKnowledgeRetrievalSettings = async (world: DifyWorld, name: string) => {
const knowledgeSection = getKnowledgeSection(world)
await expect(knowledgeSection.getByText(name, { exact: true }))
.toBeVisible({ timeout: 30_000 })
await knowledgeSection.getByText(name, { exact: true }).hover()
await knowledgeSection.getByRole('button', {
exact: true,
name: `Edit ${name}`,
}).click()
const dialog = world.getPage().getByRole('dialog', {
name: 'Knowledge Retrieval · Agent decide',
})
await expect(dialog).toBeVisible()
return dialog
}
const expectKnowledgeRetrievalDraft = async (
world: DifyWorld,
expected: {
mode: 'generated_query' | 'user_query'
value?: string
},
) => {
const agentId = getCurrentAgentId(world)
const knowledgeBase = getPreseededKnowledgeBase(world)
await expect.poll(
async () => {
const knowledgeSets = await getKnowledgeSets(agentId)
const knowledgeSet = asRecord(knowledgeSets[0])
const datasets = asArray(knowledgeSet.datasets)
const query = asRecord(knowledgeSet.query)
const retrieval = asRecord(knowledgeSet.retrieval)
return {
datasetNames: datasets.map(dataset => asRecord(dataset).name),
mode: query.mode,
name: knowledgeSet.name,
retrievalMode: retrieval.mode,
value: query.value ?? undefined,
}
},
{ timeout: 30_000 },
).toEqual({
datasetNames: expect.arrayContaining([knowledgeBase.name]),
mode: expected.mode,
name: 'Retrieval 1',
retrievalMode: 'multiple',
value: expected.value,
})
}
Given(
'a knowledge-backed Agent v2 test agent has been created via API',
async function (this: DifyWorld) {
const knowledgeBase = getPreseededKnowledgeBase(this)
const agent = await createConfiguredTestAgent({
agentSoul: createAgentSoulConfigWithKnowledgeDataset(
normalAgentSoulConfig,
{
id: knowledgeBase.id,
name: knowledgeBase.name,
},
),
})
this.createdAgentIds.push(agent.id)
this.lastCreatedAgentName = agent.name
this.lastCreatedAgentRole = agent.role ?? undefined
},
)
When(
'I add the Agent Builder knowledge base as an Agent decide Knowledge Retrieval',
async function (this: DifyWorld) {
const dialog = await openNewKnowledgeRetrievalDialog(this)
await expect(dialog.getByRole('radio', { name: 'Agent decide' })).toBeChecked()
await selectPreseededKnowledgeBase(this, dialog)
await expect(dialog.getByText(getPreseededKnowledgeBase(this).name, { exact: true }))
.toBeVisible()
await this.getPage().keyboard.press('Escape')
await expect(dialog).toBeHidden()
},
)
When(
'I add the Agent Builder knowledge base as a Custom query Knowledge Retrieval',
async function (this: DifyWorld) {
const dialog = await openNewKnowledgeRetrievalDialog(this)
await dialog.getByRole('radio', { name: 'Custom query' }).click()
await dialog
.getByRole('textbox', { name: 'Custom query text' })
.fill(agentBuilderFixedInputs.customKnowledgeQuery)
await selectPreseededKnowledgeBase(this, dialog)
await expect(dialog.getByText(getPreseededKnowledgeBase(this).name, { exact: true }))
.toBeVisible()
await this.getPage().keyboard.press('Escape')
await expect(dialog).toBeHidden()
},
)
Then('I should see the Agent v2 Knowledge Retrieval {string}', async function (this: DifyWorld, name: string) {
const knowledgeSection = getKnowledgeSection(this)
await expect(knowledgeSection).toBeVisible({ timeout: 30_000 })
await expect(knowledgeSection.getByText(name, { exact: true })).toBeVisible()
})
Then(
'the Agent v2 Agent decide Knowledge Retrieval should be saved in the Agent v2 draft',
async function (this: DifyWorld) {
await expectKnowledgeRetrievalDraft(this, {
mode: 'generated_query',
})
},
)
Then(
'the Agent v2 Custom query Knowledge Retrieval should be saved in the Agent v2 draft',
async function (this: DifyWorld) {
await expectKnowledgeRetrievalDraft(this, {
mode: 'user_query',
value: agentBuilderFixedInputs.customKnowledgeQuery,
})
},
)
Then(
'I should see the Agent v2 Agent decide Knowledge Retrieval settings',
async function (this: DifyWorld) {
const dialog = await openKnowledgeRetrievalSettings(this, 'Retrieval 1')
await expect(dialog.getByRole('radio', { name: 'Agent decide' })).toBeChecked()
await expect(dialog.getByText(getPreseededKnowledgeBase(this).name, { exact: true }))
.toBeVisible()
await expect(dialog.getByRole('button', { name: 'Disabled' })).toBeVisible()
},
)
Then(
'I should see the Agent v2 Custom query Knowledge Retrieval settings',
async function (this: DifyWorld) {
const dialog = await openKnowledgeRetrievalSettings(this, 'Retrieval 1')
await expect(dialog.getByRole('radio', { name: 'Custom query' })).toBeChecked()
await expect(dialog.getByRole('textbox', { name: 'Custom query text' }))
.toHaveValue(agentBuilderFixedInputs.customKnowledgeQuery)
await expect(dialog.getByText(getPreseededKnowledgeBase(this).name, { exact: true }))
.toBeVisible()
await expect(dialog.getByRole('button', { name: 'Disabled' })).toBeVisible()
},
)
When('I remove the Agent v2 Knowledge Retrieval {string}', async function (this: DifyWorld, name: string) {
const knowledgeSection = getKnowledgeSection(this)
await expect(knowledgeSection).toBeVisible({ timeout: 30_000 })
await knowledgeSection.getByText(name, { exact: true }).hover()
await knowledgeSection.getByRole('button', {
exact: true,
name: `Remove ${name}`,
}).click()
})
Then(
'the Agent v2 draft should no longer reference the Agent Builder knowledge base',
async function (this: DifyWorld) {
const agentId = getCurrentAgentId(this)
const knowledgeBase = getPreseededKnowledgeBase(this)
await expect.poll(
async () => {
const knowledgeSets = await getKnowledgeSets(agentId)
return knowledgeSets.some(set => asArray(asRecord(set).datasets).some((dataset) => {
const record = asRecord(dataset)
return record.id === knowledgeBase.id || record.name === knowledgeBase.name
}))
},
{ timeout: 30_000 },
).toBe(false)
},
)
Then('I should not see the Agent v2 Knowledge Retrieval {string}', async function (this: DifyWorld, name: string) {
const knowledgeSection = getKnowledgeSection(this)
await expect(knowledgeSection).toBeVisible({ timeout: 30_000 })
await expect(knowledgeSection.getByText(name, { exact: true })).not.toBeVisible()
})