fix: gate Agent access until first publish (#40105)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
zyssyz123
2026-08-06 12:36:24 +00:00
committed by GitHub
co-authored by autofix-ci[bot] yyh
parent 05c7386013
commit 90d6046345
34 changed files with 442 additions and 149 deletions
+16 -16
View File
@@ -1,18 +1,18 @@
@agent-v2 @authenticated @access-point
Feature: Agent v2 Access Point
@core
Scenario: Access Point shows the available Agent v2 access surfaces
Scenario: Access Point keeps unpublished Agent v2 access unavailable
Given I am signed in as the default E2E admin
And an Agent v2 test agent has been created via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
Then I should see the Agent v2 Access Point overview
Then the unpublished Agent v2 access surfaces should be unavailable
@core @web-app-access
Scenario: Web app access URL can be copied without changing orchestration
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
Then I should see the Agent v2 Web app access URL
@@ -25,7 +25,6 @@ Feature: Agent v2 Access Point
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And the Agent v2 draft has been published via API
And Agent v2 Web app access has been enabled via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
Then I should see the Agent v2 Web app access URL
@@ -37,7 +36,7 @@ Feature: Agent v2 Access Point
Scenario: Web app Embedded configuration opens from Access Point
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I open Agent v2 Embedded configuration
@@ -48,7 +47,7 @@ Feature: Agent v2 Access Point
Scenario: Web app customization opens from Access Point
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I open Agent v2 Web app customization
@@ -59,7 +58,7 @@ Feature: Agent v2 Access Point
Scenario: Web app settings open from Access Point without changing orchestration
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I open Agent v2 Web app settings
@@ -71,15 +70,15 @@ Feature: Agent v2 Access Point
Given I am signed in as the default E2E admin
And a basic configured Agent v2 test agent has been created via API
And the Agent v2 draft has been published via API
And Agent v2 Web app access has been enabled via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I disable Agent v2 Web app access
Then Agent v2 Web app access should be out of service
When I republish the Agent v2 draft via API
And I refresh the current page
Then Agent v2 Web app access should be out of service
When I enable Agent v2 Web app access
Then Agent v2 Web app access should be in service
When I refresh the current page
Then Agent v2 Web app access should be in service
@core @prepared @workflow-reference
Scenario: Workflow access shows the referencing workflow
@@ -96,7 +95,7 @@ Feature: Agent v2 Access Point
Scenario: Backend service API endpoint can be copied
Given I am signed in as the default E2E admin
And an Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
Then I should see the Agent v2 Backend service API endpoint
@@ -107,7 +106,8 @@ Feature: Agent v2 Access Point
Scenario: Backend service API keys are managed without exposing existing secrets
Given I am signed in as the default E2E admin
And an Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled with a key via API
And the Agent v2 draft has been published via API
And an Agent v2 Backend service API key has been created via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I open Agent v2 API key management
@@ -123,7 +123,7 @@ Feature: Agent v2 Access Point
Scenario: Backend service API Reference opens from Access Point
Given I am signed in as the default E2E admin
And an Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I open the Agent v2 API Reference
@@ -133,7 +133,7 @@ Feature: Agent v2 Access Point
Scenario: Backend service API access can be disabled and restored from Access Point
Given I am signed in as the default E2E admin
And an Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled via API
And the Agent v2 draft has been published via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I disable Agent v2 Backend service API access
@@ -149,10 +149,10 @@ Feature: Agent v2 Access Point
And the Agent Builder stable chat model is available
And the Agent v2 runtime backend is available
And a runnable Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled with a key via API
When I open the Agent v2 configure page
And I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
Given an Agent v2 Backend service API key has been created via API
When I send the Agent v2 Backend service API minimal request
Then the Agent v2 Backend service API request should succeed with the normal E2E marker
@@ -163,7 +163,7 @@ Feature: Agent v2 Access Point
And the Agent v2 runtime backend is available
And a runnable Agent v2 test agent has been created via API
And the Agent v2 draft has been published via API
And Agent v2 Backend service API access has been enabled with a key via API
And an Agent v2 Backend service API key has been created via API
When I open the Agent v2 configure page from the Agent Roster
And I switch to the Agent v2 Access Point section
And I disable Agent v2 Backend service API access
+2 -2
View File
@@ -31,13 +31,13 @@ Feature: Agent v2 Knowledge Retrieval
And the Agent v2 runtime backend is available
And the Agent Builder preseeded dataset "E2E Agent Knowledge Base" is indexed and ready
And a runnable Agent v2 test agent using the agent-decision model has been created via API
And Agent v2 Backend service API access has been enabled with a key via API
When I open the Agent v2 configure page
And I add the Agent Builder knowledge base as an Agent decide Knowledge Retrieval
Then the Agent v2 Agent decide Knowledge Retrieval should be saved in the Agent v2 draft
And the Agent v2 configuration should be saved automatically
When I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
Given an Agent v2 Backend service API key has been created via API
When I send the Agent v2 Backend service API knowledge request
Then the Agent v2 Backend service API response should include the knowledge E2E marker
@@ -48,13 +48,13 @@ Feature: Agent v2 Knowledge Retrieval
And the Agent v2 runtime backend is available
And the Agent Builder preseeded dataset "E2E Agent Knowledge Base" is indexed and ready
And a runnable Agent v2 test agent has been created via API
And Agent v2 Backend service API access has been enabled with a key via API
When I open the Agent v2 configure page
And I add the Agent Builder knowledge base as a Custom query Knowledge Retrieval
Then the Agent v2 Custom query Knowledge Retrieval should be saved in the Agent v2 draft
And the Agent v2 configuration should be saved automatically
When I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
Given an Agent v2 Backend service API key has been created via API
When I send the Agent v2 Backend service API knowledge request
Then the Agent v2 Backend service API response should include the knowledge E2E marker
+3 -3
View File
@@ -18,6 +18,9 @@ Feature: Agent v2 publish
When I open the Agent v2 configure page
And I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
When I switch to the Agent v2 Access Point section
Then Agent v2 Web app access should be in service
And Agent v2 Backend service API access should be in service
@core @prepared @stable-model
Scenario: Publish action follows unpublished changes
@@ -61,7 +64,6 @@ Feature: Agent v2 publish
And the Agent Builder stable chat model is available
And the Agent v2 runtime backend is available
And a runnable Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
When I open the Agent v2 configure page
And I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
@@ -76,7 +78,6 @@ Feature: Agent v2 publish
And the Agent Builder stable chat model is available
And the Agent v2 runtime backend is available
And a runnable Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
When I open the Agent v2 configure page
And I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
@@ -95,7 +96,6 @@ Feature: Agent v2 publish
And the Agent Builder stable chat model is available
And the Agent v2 runtime backend is available
And a runnable Agent v2 test agent has been created via API
And Agent v2 Web app access has been enabled via API
When I open the Agent v2 configure page
And I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
@@ -1,6 +1,5 @@
import type { AgentAppDetailWithSite } from '@dify/contracts/api/console/agent/types.gen'
import type { ChatRequestPayloadWithUser } from '@dify/contracts/api/service/types.gen'
import type { ConsoleClient } from '../../../support/api/console-client'
import { consumeServiceApiSse, SERVICE_API_STREAM_TIMEOUT_MS } from './service-api-sse'
export type AgentServiceApiChatResult = {
@@ -41,19 +40,6 @@ export function getAgentWebAppURL(agent: AgentAppDetailWithSite): string {
return `${baseURL.replace(/\/$/, '')}/agent/${token}`
}
export async function enableAgentWebApp(client: ConsoleClient, agentId: string): Promise<string> {
const agent = await client.agent.byAgentId.get({ params: { agent_id: agentId } })
const appId = agent.app_id ?? agent.backing_app_id
if (!appId) throw new Error(`Agent v2 ${agentId} does not expose a backing app ID.`)
await client.apps.byAppId.siteEnable.post({
body: { enable_site: true },
params: { app_id: appId },
})
const updatedAgent = await client.agent.byAgentId.get({ params: { agent_id: agentId } })
return getAgentWebAppURL(updatedAgent)
}
export async function sendAgentServiceApiChatMessage({
apiKey,
query = 'Please reply with the test success marker.',
+1 -1
View File
@@ -19,10 +19,10 @@ Feature: Agent v2 tools
And the Agent Builder stable chat model is available
And the Agent Builder preseeded tool "JSON Process / JSON Replace" is available
And a runnable Agent v2 test agent with the JSON Replace tool has been created via API
And Agent v2 Backend service API access has been enabled with a key via API
When I open the Agent v2 configure page
Then the Agent v2 JSON Replace tool should be saved in the Agent v2 draft
When I publish the Agent v2 draft
Then the Agent v2 draft should be published and up to date
Given an Agent v2 Backend service API key has been created via API
When I send the Agent v2 Backend service API JSON Replace request
Then the Agent v2 Backend service API response should include the JSON Replace E2E marker
@@ -9,13 +9,10 @@ import {
import { SERVICE_API_RUNTIME_STEP_TIMEOUT_MS } from '../../agent-v2/support/service-api-sse'
import { getCurrentAgentId, getServiceApiCard } from './access-point-helpers'
async function enableAgentApiAccessWithKey(world: DifyWorld) {
async function createAgentApiKey(world: DifyWorld) {
const agentId = getCurrentAgentId(world)
const client = world.getConsoleClient()
const apiAccess = await client.agent.byAgentId.apiEnable.post({
body: { enable_api: true },
params: { agent_id: agentId },
})
const apiAccess = await client.agent.byAgentId.apiAccess.get({ params: { agent_id: agentId } })
const apiKey = await client.agent.byAgentId.apiKeys.post({ params: { agent_id: agentId } })
world.agentBuilder.accessPoint.serviceApiBaseURL = apiAccess.service_api_base_url
@@ -23,25 +20,25 @@ async function enableAgentApiAccessWithKey(world: DifyWorld) {
}
Given(
'Agent v2 Backend service API access has been enabled with a key via API',
'an Agent v2 Backend service API key has been created via API',
async function (this: DifyWorld) {
await enableAgentApiAccessWithKey(this)
await createAgentApiKey(this)
},
)
Then('I should see the Agent v2 Backend service API endpoint', async function (this: DifyWorld) {
const serviceApiCard = getServiceApiCard(this)
if (!this.agentBuilder.accessPoint.serviceApiBaseURL)
throw new Error('No Agent v2 service API endpoint found. Enable Backend service API first.')
const agentId = getCurrentAgentId(this)
const apiAccess = await this.getConsoleClient().agent.byAgentId.apiAccess.get({
params: { agent_id: agentId },
})
this.agentBuilder.accessPoint.serviceApiBaseURL = apiAccess.service_api_base_url
await expect(serviceApiCard.getByRole('heading', { name: 'Backend service API' })).toBeVisible({
timeout: 30_000,
})
await expect(serviceApiCard.getByText('Service API Endpoint')).toBeVisible()
await expect(
serviceApiCard.getByText(this.agentBuilder.accessPoint.serviceApiBaseURL),
).toBeVisible()
await expect(serviceApiCard.getByText(apiAccess.service_api_base_url)).toBeVisible()
await expect(serviceApiCard.getByLabel('Copy service API endpoint')).toBeEnabled()
})
@@ -2,6 +2,7 @@ import type { Page } from '@playwright/test'
import type { DifyWorld } from '../../support/world'
import { Then, When } from '@cucumber/cucumber'
import { expect } from '@playwright/test'
import { getAgentWebAppURL } from '../../agent-v2/support/access-point'
import { agentBuilderExpectedTokens } from '../../agent-v2/support/agent-builder-resources'
import { getCurrentAgentId, getDialog, getWebAppCard } from './access-point-helpers'
@@ -48,8 +49,9 @@ When('I launch the Agent v2 Web app', async function (this: DifyWorld) {
})
When('I open the Agent v2 Web app URL', async function (this: DifyWorld) {
const webAppURL = this.agentBuilder.accessPoint.webAppURL
if (!webAppURL) throw new Error('No Agent v2 Web app URL was recorded.')
const agentId = getCurrentAgentId(this)
const agent = await this.getConsoleClient().agent.byAgentId.get({ params: { agent_id: agentId } })
const webAppURL = this.agentBuilder.accessPoint.webAppURL ?? getAgentWebAppURL(agent)
if (!this.context) throw new Error('Playwright browser context has not been initialized.')
const webAppPage = await this.context.newPage()
@@ -2,38 +2,22 @@ import type { DifyWorld } from '../../support/world'
import type { AccessSurfaceName } from './access-point-helpers'
import { Given, Then, When } from '@cucumber/cucumber'
import { expect } from '@playwright/test'
import { enableAgentWebApp } from '../../agent-v2/support/access-point'
import { publishAgentWithPublishableDraft } from '../../agent-v2/support/agent'
import {
getAccessRegion,
getAccessSurfaceCard,
getCurrentAgentId,
getPreseededResource,
getServiceApiCard,
getWebAppCard,
} from './access-point-helpers'
Given('the Agent v2 draft has been published via API', async function (this: DifyWorld) {
await publishAgentWithPublishableDraft(this.getConsoleClient(), getCurrentAgentId(this))
})
Given(
/^Agent v2 (Web app|Backend service API) access has been enabled via API$/,
async function (this: DifyWorld, surface: AccessSurfaceName) {
if (surface === 'Web app') {
this.agentBuilder.accessPoint.webAppURL = await enableAgentWebApp(
this.getConsoleClient(),
getCurrentAgentId(this),
)
return
}
const agentId = getCurrentAgentId(this)
const apiAccess = await this.getConsoleClient().agent.byAgentId.apiEnable.post({
body: { enable_api: true },
params: { agent_id: agentId },
})
this.agentBuilder.accessPoint.serviceApiBaseURL = apiAccess.service_api_base_url
},
)
When('I republish the Agent v2 draft via API', async function (this: DifyWorld) {
await publishAgentWithPublishableDraft(this.getConsoleClient(), getCurrentAgentId(this))
})
When(
'I open the preseeded Agent v2 Access Point page for {string} from the Agent Roster',
@@ -61,34 +45,20 @@ When('I switch to the Agent v2 Access Point section', async function (this: Dify
await expect(page.getByRole('region', { name: 'Access Point' })).toBeVisible()
})
Then('I should see the Agent v2 Access Point overview', async function (this: DifyWorld) {
const accessRegion = getAccessRegion(this)
Then(
'the unpublished Agent v2 access surfaces should be unavailable',
async function (this: DifyWorld) {
const webAppCard = getWebAppCard(this)
const serviceApiCard = getServiceApiCard(this)
await expect(accessRegion).toBeVisible({ timeout: 30_000 })
await expect(accessRegion.getByRole('heading', { name: 'Access Point' })).toBeVisible()
await expect(accessRegion.getByRole('heading', { name: 'Web app' })).toBeVisible()
await expect(accessRegion.getByText('Access URL')).toBeVisible()
await expect(accessRegion.getByLabel('Copy access URL')).toBeVisible()
await expect(accessRegion.getByLabel('Toggle Web app access')).toBeVisible()
await expect(accessRegion.getByRole('link', { name: 'Launch' })).toBeVisible()
await expect(accessRegion.getByRole('button', { name: 'Embedded' })).toBeVisible()
await expect(accessRegion.getByRole('button', { name: 'Custom Frontend' })).toBeVisible()
await expect(accessRegion.getByRole('button', { name: 'Branding' })).toBeVisible()
await expect(accessRegion.getByRole('heading', { name: 'Backend service API' })).toBeVisible()
await expect(accessRegion.getByText('Service API Endpoint')).toBeVisible()
await expect(accessRegion.getByLabel('Copy service API endpoint')).toBeVisible()
await expect(accessRegion.getByLabel('Toggle Backend service API access')).toBeVisible()
await expect(accessRegion.getByRole('button', { name: /^API Key\b/ })).toBeVisible()
await expect(accessRegion.getByRole('link', { name: 'API Reference' })).toBeVisible()
await expect(accessRegion.getByText(/^(?:In|Out of) service$/i)).toHaveCount(2)
await expect(accessRegion.getByRole('heading', { name: 'Workflow access' })).toBeVisible()
await expect(accessRegion.getByRole('columnheader', { name: 'Name' })).toBeVisible()
await expect(accessRegion.getByRole('columnheader', { name: 'Version' })).toBeVisible()
await expect(accessRegion.getByRole('columnheader', { name: 'Nodes' })).toBeVisible()
await expect(accessRegion.getByRole('columnheader', { name: 'Last updated' })).toBeVisible()
await expect(accessRegion.getByRole('columnheader', { name: 'Actions' })).toBeVisible()
await expect(accessRegion.getByText('No workflow references yet.')).toBeVisible()
})
await expect(webAppCard.getByText('Out of service')).toBeVisible({ timeout: 30_000 })
await expect(webAppCard.getByLabel('Toggle Web app access')).toBeDisabled()
await expect(webAppCard.getByRole('button', { name: 'Launch' })).toBeDisabled()
await expect(serviceApiCard.getByText('Out of service')).toBeVisible()
await expect(serviceApiCard.getByLabel('Toggle Backend service API access')).toBeDisabled()
await expect(serviceApiCard.getByRole('button', { name: /^API Key\b/ })).toBeDisabled()
},
)
When(
/^I disable Agent v2 (Web app|Backend service API) access$/,