mirror of
https://github.com/langgenius/dify.git
synced 2026-08-28 22:36:52 +08:00
fix(agent): return empty build-draft state instead of 404 for new agents
Fixes #40733 A freshly-created agent has no DEBUG_BUILD row yet. The `GET /console/api/agent/{id}/build-draft` endpoint calls `AgentComposerService.load_agent_app_build_draft`, which raised `AgentVersionNotFoundError("Agent config version not found")` when the build draft was missing. The front-end toasted this as a version error on the agent configure page (Flask-RESTX also appended "did you mean ..."), preventing the normal draft view from loading. Treat a missing build-draft as an empty state, not a 404. Return a payload that preserves the existing schema contract (`variant`, `draft`, `agent_soul`) with `draft` and `agent_soul` set to None, so the UI can render a fresh draft screen without a toast. Same pattern as `load_workflow_composer`, which returns `_empty_workflow_state` when the binding is missing instead of erroring. The `apply_agent_app_build_draft` and `discard_agent_app_build_draft` methods keep their existing behaviour (apply still 404s on a missing build draft since you can't apply nothing; discard already no-ops on a missing build draft). Only the load path needed the empty-state treatment. Added regression test asserting the fix returns the empty state on a missing build draft and doesn't commit/delete anything.
This commit is contained in:
parent
6e974e1a1c
commit
8829bdc0c1
@ -813,7 +813,11 @@ class AgentComposerService:
|
||||
account_id=account_id,
|
||||
)
|
||||
if build_draft is None:
|
||||
raise AgentVersionNotFoundError()
|
||||
# A freshly-created agent has no DEBUG_BUILD row yet. Return an
|
||||
# empty build-draft state (keeps the existing schema
|
||||
# contract: variant, draft, agent_soul) so the UI can stay on
|
||||
# the normal draft screen instead of toasting a 404.
|
||||
return cls._empty_build_draft_state()
|
||||
return cls._serialize_build_draft_state(build_draft)
|
||||
|
||||
@classmethod
|
||||
@ -2243,6 +2247,18 @@ class AgentComposerService:
|
||||
"agent_soul": draft.config_snapshot_dict,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _empty_build_draft_state(cls) -> dict[str, Any]:
|
||||
# Empty payload for a not-yet-created DEBUG_BUILD draft. Keeps
|
||||
# the AgentBuildDraftResponse schema (variant/draft/agent_soul) so
|
||||
# the front-end can render a fresh draft screen without a 404
|
||||
# toast. Regression for #40733.
|
||||
return {
|
||||
"variant": ComposerVariant.AGENT_APP.value,
|
||||
"draft": None,
|
||||
"agent_soul": None,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _get_draft_workflow(cls, *, session: Session, tenant_id: str, app_id: str) -> Workflow:
|
||||
workflow = session.scalar(
|
||||
|
||||
@ -2170,8 +2170,36 @@ def test_agent_app_build_draft_apply_marks_unpublished_when_build_draft_differs(
|
||||
)
|
||||
|
||||
|
||||
def test_load_agent_app_build_draft_returns_empty_state_when_missing(
|
||||
monkeypatch: pytest.MonkeyPatch, sqlite_session: Session
|
||||
):
|
||||
"""Regression for #40733: a freshly-created agent has no DEBUG_BUILD row.
|
||||
|
||||
GET /agent/<id>/build-draft used to return 404 "Agent config version
|
||||
not found" and the front-end toasted it as a version error. The fix
|
||||
returns an empty build-draft state so the UI stays on the normal
|
||||
draft screen with no toast.
|
||||
"""
|
||||
session = sqlite_session
|
||||
monkeypatch.setattr(AgentComposerService, "_get_agent_draft", lambda **kwargs: None)
|
||||
|
||||
result = AgentComposerService.load_agent_app_build_draft(
|
||||
session=session,
|
||||
tenant_id="tenant-1",
|
||||
agent_id="agent-1",
|
||||
account_id="account-1",
|
||||
)
|
||||
|
||||
# Schema contract (variant/draft/agent_soul) preserved; draft and
|
||||
# agent_soul are None so the UI can render an empty draft.
|
||||
assert result["variant"] == "agent_app"
|
||||
assert result["draft"] is None
|
||||
assert result["agent_soul"] is None
|
||||
|
||||
|
||||
def test_agent_app_composer_candidates_and_impact(monkeypatch: pytest.MonkeyPatch, sqlite_session: Session):
|
||||
session = sqlite_session
|
||||
|
||||
bindings = [
|
||||
WorkflowAgentNodeBinding(
|
||||
tenant_id="tenant-1",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user