Commit Graph
28 Commits
Author SHA1 Message Date
Charles Yao c90b35d363 fix(builder): type task control owners and canonical test fixtures 2026-10-23 17:13:32 -07:00
Charles Yao 8c52a91ea0 feat(builder): fence task stop and synchronize safe resume 2026-10-23 16:40:43 -07:00
Charles Yao 186deb854d feat(builder): unify native test controls with session actions 2026-10-22 19:19:47 -07:00
Charles Yao 231e423431 Integrate validated Builder backend testing and CI repairs
Track backend integration, Ruff cleanup and migration reconciliation in ENG-1271. Retain required copy contracts without implementing frontend interactions.
2026-10-20 15:40:06 -07:00
twwu 4c1c41c2ea fix(builder): support initial Chatflow builds (ENG-1242)
Recognize initial templates, generate graphs in the app mode, and replace default nodes atomically after approval.

Normalize node ordering in execution revisions to prevent false 409 conflicts, with frontend and backend regression coverage.
2026-10-19 16:44:09 +08:00
twwu c899d8c2c0 fix(builder): align conflict checks across execution layers
Share revision exemptions between service admission and queued workers while
retaining fixture and session fences. Use executable graph normalization for
execution admission and native node bindings.

Keep recovery classification separate from handler execution, refresh cached
offers before continuing, and reject drift during rebasing. Add service-to-native
regression coverage and fix JSON execution context typing.
2026-10-15 16:56:57 +08:00
twwu 89504b7dce refactor(builder): localize fixed copy on the frontend
Move fixed copy into the difyBuilder i18n namespace and resolve scene IDs
using reply_language. Preserve dynamic streaming, historical receipts,
and submitted values.

Show fixed replies immediately with a short transition, detect language
before initial progress, and retire new notices and recovery messages.
Keep recovery and publication validation in place.

Update generated contracts and regression coverage, including progress
snapshot and execution context expectations and test type annotations.
2026-10-14 17:10:20 +08:00
twwu 802ed06a37 fix(builder): restore session progress after reconnect
Restore cumulative worker progress before live SSE updates and recover missed terminal state on idle heartbeats. Keep submitted interactions hidden while the command runs and record reconnect state in trace exports.
2026-10-14 16:50:00 +08:00
Charles Yao c6c7dc5eea fix(builder): localize structured decisions and interaction receipts 2026-10-13 13:11:22 -07:00
Charles YaoandClaude Opus 5.5 9323e60724 fix: give one worker exclusive lease ownership and settle terminal confirmed grants
Worker activation now swaps the dispatch token for a unique owner value, so a
duplicate delivery of a running command can neither run nor release the
winner's lease. Terminal worker failures clear pending confirmed references and
settle the worker's own reloaded grant; the sweeper repairs, in a bounded pass,
reserved grants whose command already reached review/FAILED but whose
settlement write failed, never while a lease is live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:48:57 -07:00
Charles YaoandClaude Opus 5.5 391d1a9c49 feat: launch confirmed Tool tests through native Builder Runs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:58:50 -07:00
Charles Yao 625fdfd8d1 fix(builder): discover installed tools needing setup 2026-10-11 02:01:36 -07:00
Charles Yao 6bcc64d4ca fix(dify-builder): validate generation and gate publication on durable verification 2026-10-09 19:14:43 -07:00
Wu Tianwei b3e3540c43 refactor: improve Dify Builder session UX (#42760) 2026-09-24 15:18:32 +08:00
twwu d5ca5ea8ef fix(dify-builder): stream native test runs after canvas refresh
Run workflow streaming inside the Builder worker to avoid queue deadlocks. Forward native events to shared editor callbacks and wait for graph refresh before retesting repairs.

Keep command cleanup stable, preserve batched canvas events, and allow failed or unfinished historical runs to refresh again.
2026-09-21 15:12:22 +08:00
Charles YaoandClaude Opus 5 a3c2e7fca5 feat(dify-builder): tell the canvas which run to show
Streaming the test run gives the user a live progress bar but no results:
NodeEvent carries node_id/title/status/error and nothing else, so a client
watching the stream learns which node is running, never what it produced.
The results already exist -- the run is a normal InvokeFrom.DEBUGGER draft
run, its node executions are in the database, and the editor's canvas
already knows how to render exactly that view. It was simply never told
which run to open.

So put the Dify run id where a client can reach it:

- NodeEvent gains run_id, filled from the streaming frame. Every non-ping
  frame is stamped with workflow_run_id, so this arrives with the FIRST
  node event -- while the run is still going, which is the point.
- The node SSE frame publishes it alongside the existing fields.
- mark_test_success / mark_test_error carry dify_run_id in both the Build
  and Edit flows, so the terminal state names its run too.

This is what makes per-node results land on the graph, where a node's
inputs and outputs already have a home, instead of only as a JSON blob on
a conversation card.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 17:16:41 -07:00
Charles YaoandClaude Opus 5 65a47018b4 feat(dify-builder): say the app's name once when the build lands
Spec N4 has the build-complete card headline read "<App name> is ready", with
the annotation 名字只在回复句里念一次;记录卡上不出现 -- said once, in that
sentence, and never repeated on the completion receipt. We said it nowhere: the
card was titled "Build plan" and the engine had no app name to say.

DifyBuilderContext now carries app_name, seeded at session creation through a
get_app_name_fn seam alongside the existing revision/authorize ones. Env.rename_app
returns the name the database actually took rather than None, so the refine
records what landed instead of what it proposed -- the service normalizes after
the engine hands off, and the two can differ.

The headline is interpolated, so it gets a strings.py template or it would
survive localization untranslated. That pattern matches almost anything ending
in "is ready", so it sits last and every more specific template gets first
refusal.

The receipt already omitted the name; there is now a test pinning that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 18:09:23 -07:00
Charles YaoandClaude Opus 5 aa2b4fe4ab feat(dify-builder): name apps from their prompt, and turn gate actions into card options
Two App Builder spec changes that share the Builder session contract.

Naming (spec N1-N3): an app created from the homepage prompt is no longer named
by the user. core/dify_builder/naming.py cuts the prompt's opening clause at
create time -- instant and infallible, since it runs inside POST /apps -- and
CreateAppPayload.name becomes optional alongside a new prompt field. The Builder
then refines that name once during goal analysis, where a model and the detected
reply language are already in hand, so the judgement calls that are
English-shaped in pure Python (dropping an imperative lead-in, spotting a
contentless prompt) work in any language. Plan approval freezes the name.

Card options: SessionView gains a Decision carrying the gate's choice as options
inside the card plus a fixed confirm/cancel pair, replacing a button row whose
shape changed at every state. Option ids are the old action ids untouched, so
resolve_action_kind and the per-state legality check are unchanged, and
SessionView.actions keeps being populated -- the deployed web client goes on
working until it reads decision instead.

The regenerated console OpenAPI doc also picks up ErrorCard.diagnostics, missed
when cc9ca8b1dd landed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:55:38 -07:00
Charles YaoandClaude Opus 4.8 9b4e095e71 refactor(dify-builder): promote model_or_none to the agent protocol
Follow-up to the reply-language feature. `_model_or_none` was private to
LlmBuilderAgent, so the advance-task wiring reached it via a fragile
`getattr(agent, "_model_or_none", lambda: None)`. Make it part of the
DifyBuilderAgent protocol (typed `object | None` to keep the pure port free of
any model-runtime import) and implement it on every conforming agent
(LlmBuilderAgent renames the private method public; PlaceholderAgent and the
test doubles return None). The Localizer wiring now uses `agent.model_or_none`
directly. Also drops the useless-return ruff nit in the wiring test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 16:34:29 -07:00
Charles YaoandClaude Opus 4.8 bd8951fbd6 feat(dify-builder): wire Localizer into the advance task (M2)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 15:57:55 -07:00
Wu Tianwei 8b52c102a3 feat(dify-builder): add live progress and conversation streaming (#41778) 2026-09-04 18:30:44 +08:00
twwu 4893c5e621 refactor(dify-builder): separate reasoning from execution progress 2026-09-04 13:43:16 +08:00
twwu eb25c2d8ee feat(dify-builder): add live progress and conversation streaming 2026-09-04 10:16:50 +08:00
Charles YaoandClaude Opus 4.8 de8a5745ea fix(dify_builder): always emit a terminal SSE frame so held version can't go stale
Two paths ended a streaming advance without a terminal `state`/`error`
frame, leaving the SSE client stalled to the deadline with a stale held
version -> its next action 409s:

1. advance_session published the terminal `state` frame outside the
   try/finally and unguarded. If the post-advance view projection
   (get_session_view -> read_graph) or the publish itself raised after a
   SUCCESSFUL advance, the exception escaped and no terminal frame was
   sent. Guard it and fall back to a terminal `error` frame.

2. submit_action_stream emitted a terminal `state` frame on settle only
   for `message`. `update_model` also settles synchronously while bumping
   the version, so it now emits one too -- otherwise the FE keeps the old
   version and 409s on its next action.

Adds regression tests for both (projection-failure -> error frame;
update_model -> state frame).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 08:48:23 +08:00
twwu 3eacff14a6 feat: add typed SSE interactions to Dify Builder 2026-09-03 08:48:23 +08:00
Charles YaoandClaude Opus 4.8 390eea61fb feat(dify-builder): terminal state frame carries the full SessionView
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-31 22:18:42 -07:00
Charles YaoandClaude Opus 4.8 02a5f01f84 feat(dify-builder): DIFY_BUILDER_AGENT_MODE gate + factory/task model wiring
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-27 22:51:27 -07:00
Charles YaoandClaude Opus 4.8 7e83264330 refactor: rename Workflow Copilot → Dify Builder
Project rename across api/ + web/: modules, symbols, routes
(/console/api/dify-builder/*), feature flag (DIFY_BUILDER_ENABLED),
Celery queue/tasks, the 7 DB tables (via migration df1b0114de40),
and regenerated contract artifacts. Behavior unchanged; 430 tests green,
ruff clean. Branch renamed feat/copilot-py-backend → dify-builder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-23 11:18:35 -07:00