fix(e2e): restore shellctl external runtime (#38968)

This commit is contained in:
yyh 2026-07-15 11:26:55 +08:00 committed by GitHub
parent 571e50175e
commit 1e6d73fdb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 7 additions and 4 deletions

View File

@ -38,6 +38,7 @@ jobs:
- '.github/workflows/web-e2e.yml'
- '.github/actions/setup-web/**'
- 'dify-agent/**'
- 'dify-agent-runtime/**'
- 'api/clients/agent_backend/**'
- 'api/core/app/apps/agent_app/**'
- 'api/core/workflow/nodes/agent_v2/**'

View File

@ -164,7 +164,7 @@ Agent Builder preflight is read-only. It checks long-lived seed resources and re
Treat preseeded Agent Builder resources as environment contracts. Preflight can report that a stable model, dataset, Skill, Tool credential, fixed Agent, published Web app, or workflow reference is missing, inactive, not indexed, or drifted, but it must not repair that drift during a scenario. Seed scripts, CI bootstrap, or the documented environment maintenance flow own creating and keeping those resources valid.
Use `the Agent v2 runtime backend is available` before scenarios tagged `@agent-backend-runtime`. The step checks the standalone `dify-agent` run server through `E2E_AGENT_BACKEND_URL`, `AGENT_BACKEND_BASE_URL`, or the default `http://127.0.0.1:5050` when `E2E_START_AGENT_BACKEND=1`. The E2E runner starts this service with `uv run --project dify-agent --extra server uvicorn dify_agent.server.app:app --host 127.0.0.1 --port 5050` only when `E2E_START_AGENT_BACKEND=1` is explicit. Because Agent App runtime always carries the `dify.config` layer and that layer depends on `dify.shell`, the same runner path also starts the `dify-agent/docker/local-sandbox` shellctl container on `E2E_SHELLCTL_PORT` (default `5004`) and injects `DIFY_AGENT_SHELLCTL_ENTRYPOINT` into the Agent backend. Missing or unreachable runtime backend or shellctl sandbox should be reported as a blocked precondition, not discovered later as a `/build-chat/finalize` 400 or Web app response timeout.
Use `the Agent v2 runtime backend is available` before scenarios tagged `@agent-backend-runtime`. The step checks the standalone `dify-agent` run server through `E2E_AGENT_BACKEND_URL`, `AGENT_BACKEND_BASE_URL`, or the default `http://127.0.0.1:5050` when `E2E_START_AGENT_BACKEND=1`. The E2E runner starts this service with `uv run --project dify-agent --extra server uvicorn dify_agent.server.app:app --host 127.0.0.1 --port 5050` only when `E2E_START_AGENT_BACKEND=1` is explicit. Because Agent App runtime always carries the `dify.config` layer and that layer depends on `dify.shell`, the same runner path also starts the `dify-agent-runtime/docker` shellctl container on `E2E_SHELLCTL_PORT` (default `5004`) and injects `DIFY_AGENT_SHELLCTL_ENTRYPOINT` into the Agent backend. Missing or unreachable runtime backend or shellctl sandbox should be reported as a blocked precondition, not discovered later as a `/build-chat/finalize` 400 or Web app response timeout.
Use `the Agent Builder stable chat model is available` before scenarios that need a real Agent Soul model configuration. This includes true runtime scenarios, model-backed build-mode assertions, and Workflow Agent v2 node setup because the backend rejects Agent nodes without model config. Do not add the model preflight to pure navigation or identity checks unless the setup API itself requires model config. `E2E_STABLE_MODEL_PROVIDER`, `E2E_STABLE_MODEL_NAME`, and optional `E2E_STABLE_MODEL_TYPE` are selectors for a model already configured in the workspace; they are not provider credentials. The step defaults to `openai` / `gpt-5-nano` / `llm`, verifies the selected model is present and `active` through `/console/api/workspaces/current/models/model-types/{type}`, then stores it on `DifyWorld.agentBuilder.preflight.stableModel`.

View File

@ -33,6 +33,7 @@ export const rootDir = fileURLToPath(new URL('../..', import.meta.url))
export const e2eDir = path.join(rootDir, 'e2e')
export const apiDir = path.join(rootDir, 'api')
export const difyAgentDir = path.join(rootDir, 'dify-agent')
export const difyAgentRuntimeDir = path.join(rootDir, 'dify-agent-runtime')
export const dockerDir = path.join(rootDir, 'docker')
export const webDir = path.join(rootDir, 'web')

View File

@ -184,7 +184,7 @@ const main = async () => {
try {
const shellctlPort = process.env.E2E_SHELLCTL_PORT || '5004'
await Promise.race([
waitForUrl(`http://127.0.0.1:${shellctlPort}/openapi.json`, 180_000, 1_000),
waitForUrl(`http://127.0.0.1:${shellctlPort}/healthz`, 180_000, 1_000),
waitForUnexpectedProcessExit(shellctlProcess, () => !waitingForShellctl),
])
} catch (error) {

View File

@ -6,6 +6,7 @@ import {
apiDir,
apiEnvExampleFile,
difyAgentDir,
difyAgentRuntimeDir,
dockerDir,
e2eDir,
e2eWebEnvOverrides,
@ -376,12 +377,12 @@ const ensureShellctlSandboxImage = async () => {
args: [
'build',
'-f',
path.join(difyAgentDir, 'docker', 'local-sandbox', 'Dockerfile'),
path.join(difyAgentRuntimeDir, 'docker', 'Dockerfile'),
'-t',
shellctlImage,
'.',
],
cwd: difyAgentDir,
cwd: difyAgentRuntimeDir,
})
}