mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
The two semantic guards describe defects the ENGINE ACCEPTS: a new branch wired into a variable-aggregator that was never told about it, an array re-sent with an element quietly dropped. Both drafts start, both run green, and neither produces a `DraftWouldNotStartError` for `apply_repair` to veto. So the guards had one hole left, and it was in the agent's own fallback: `build_edit_intents` spent its corrective re-prompt on the guard's reason and then, if the retry yielded nothing usable, returned the FIRST attempt's applicable intents -- the very batch the guard had condemned. The guard fired and the silently-wrong draft was written anyway. `vet_intents` now carries `would_run_wrong` alongside `rejections`: the subset of refusals the engine does not make. The two kinds fail differently and a caller has to tell them apart without reading the text -- a structural refusal DROPPED its intent, so what survives is a batch nobody judged wrong and keeping it is a deliberate choice; a semantic verdict drops nothing and condemns what remains. Reading that off the prose would be the same mistake as keying control flow on the model's prose. `build_edit_intents` therefore raises `ProposalWouldRunWrongError` instead of returning a batch still carrying one, whichever attempt it came from. Nothing is written and nothing is attempted. `handle_plan_approval` catches it into the same `_change_not_applied` recovery a refused write gets: the plan stays at its gate, the reason goes on an error card and into `last_edit_rejection` for the next attempt. Surfacing is a real exit now and not the dead end it would have been before this plan: Task 7 gave the gate a revert and a keep-adjusting action, and Task 6 carries the refusal into the next proposal, so the user can change the rules and the retry is not blind. `ProposalWouldRunWrongError` is deliberately neither a `DraftWouldNotStartError` nor a `ValueError`: the draft WOULD start, and a broad `except ValueError` around a port write must not swallow it as if the write had been attempted. `_change_not_applied` takes the activity to mark failed, defaulting to the write where the usual refusal happens. This exit gives up during "prepare", so failing the write would have shown a LATER step failed while an earlier one was still running, with the step between never resolving. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
"""Dify Builder domain errors.
|
|
|
|
Port of dify-enterprise/server/pkg/enterprise/biz/dify_builder/errors.go. Go
|
|
models these as sentinel ``error`` values (``errors.New(...)``); Python has
|
|
no sentinel-error idiom, so each becomes an ``Exception`` subclass that the
|
|
``Repository``/``Runner`` layers raise and callers catch by type.
|
|
"""
|
|
|
|
|
|
class ConflictError(Exception):
|
|
"""Raised when compare_and_advance loses the version race (stale base_version)."""
|
|
|
|
|
|
class NotFoundError(Exception):
|
|
"""Raised when a session/checkpoint/run does not exist."""
|
|
|
|
|
|
class BusyError(Exception):
|
|
"""Raised when a session already has an Advance in flight.
|
|
|
|
The per-session gate is held, so a concurrent SubmitAction is rejected.
|
|
"""
|
|
|
|
|
|
class BadRequestError(Exception):
|
|
"""A client-supplied value is invalid (e.g. an unresolvable model_config).
|
|
|
|
Maps to HTTP 400 in services.dify_builder.wiring.dify_builder_error_response.
|
|
"""
|
|
|
|
|
|
class ModelUnavailableError(BadRequestError):
|
|
"""The chosen or default Builder model cannot be used with its current configuration."""
|
|
|
|
|
|
class DraftWouldNotStartError(ValueError):
|
|
"""Raised by the Dify port when the graph it was asked to write would fail
|
|
at Graph.init, so nothing was written.
|
|
|
|
Handlers catch it to say "the workflow can't start" rather than "the
|
|
change no longer applies". A ``ValueError`` so older ``except ValueError``
|
|
guards around the port's writes still catch it.
|
|
"""
|
|
|
|
|
|
class ProposalWouldRunWrongError(Exception):
|
|
"""Raised by an agent that has judged its OWN final proposal wrong, so it
|
|
refuses to hand it on to be written.
|
|
|
|
The sibling of ``DraftWouldNotStartError``, for the defects the engine
|
|
cannot see. A draft that wires a new branch into a variable-aggregator
|
|
without extending that aggregator's ``variables``, or that re-sends an
|
|
array having quietly dropped an element the user configured, passes
|
|
``Graph.init`` and every node-data check and then runs green while
|
|
producing nothing or the wrong thing -- so there is no engine refusal for a
|
|
handler to catch and nothing for the write chokepoint to veto.
|
|
|
|
Deliberately NOT a ``DraftWouldNotStartError`` and not a ``ValueError``:
|
|
the draft WOULD start, and a broad ``except ValueError`` around a port
|
|
write must not swallow this as if the write had been attempted. Nothing has
|
|
been written when it is raised; the message is the engine-grounded reason,
|
|
which handlers show at the gate and carry into the next attempt.
|
|
"""
|