feat(workflow-generator): enhance the AI auto-creation flow end-to-end#38175
Merged
Conversation
Implements the stage 1–5 program from #38174 (3.1 dropped per request). Backend (api/) - New POST /workflow-generate/suggestions: short, workspace-grounded example instructions generated on the tenant default model; soft-fails to {suggestions: []}. - New POST /workflow-generate/stream: SSE plan-first generation that emits the planner result (plan) then the built graph (result), reusing the existing planner/builder/validate stages — the streamed result provably equals the blocking /workflow-generate return. - mode:"auto" on both generate endpoints; a lightweight classifier resolves the concrete mode before planning and it is echoed back as `mode`. Frontend (web/) - Remove the low-value "Ideal output" field from the modal. - Replace the static example chips with AI-generated, workspace-grounded suggestions (cached per session per mode, ↻ refresh, silent static fallback). - Plan-first streaming: show the planner outline as it lands, then the graph (replaces the guessed phase timer) via an isolated SSE consumer that reuses the existing cookie-auth/CSRF/abort setup without touching handleStream. - Review stage: planner metadata header (icon + name), an actionable error panel (Regenerate / Install tools / affected node), a /refine diff summary, and a post-apply nudge toward cmd+k /refine. - Entry & input: ⌘/Ctrl+Enter to generate, autofocus, palette inline capture (`/create workflow <text>`), an "Auto" submenu option, and last-instruction resume across opens. i18n keys added across all 23 locales. New tests cover the suggestions component (fetch → fallback → refresh), the graph diff util, and the updated /create command. Refs #38174 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Pyrefly Type Coverage
|
Contributor
Pyrefly Diffbase → PR--- /tmp/pyrefly_base.txt 2026-06-30 12:19:09.602412859 +0000
+++ /tmp/pyrefly_pr.txt 2026-06-30 12:18:55.184299325 +0000
@@ -4378,6 +4378,14 @@
--> tests/unit_tests/core/llm_generator/output_parser/test_structured_output.py:192:16
ERROR `in` is not supported between `str` and `None` [not-iterable]
--> tests/unit_tests/core/llm_generator/output_parser/test_structured_output.py:203:16
+ERROR Class member `MockService.get_draft_workflow` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
+ --> tests/unit_tests/core/llm_generator/test_llm_generator_missing.py:152:17
+ERROR Method `get_draft_workflow` inherited from class `WorkflowServiceInterface` has no implementation and cannot be accessed via `super()` [missing-attribute]
+ --> tests/unit_tests/core/llm_generator/test_llm_generator_missing.py:153:24
+ERROR Class member `MockService.get_node_last_run` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
+ --> tests/unit_tests/core/llm_generator/test_llm_generator_missing.py:155:17
+ERROR Method `get_node_last_run` inherited from class `WorkflowServiceInterface` has no implementation and cannot be accessed via `super()` [missing-attribute]
+ --> tests/unit_tests/core/llm_generator/test_llm_generator_missing.py:156:24
ERROR Object of class `MockAccount` has no attribute `id` [missing-attribute]
--> tests/unit_tests/core/logging/test_filters.py:201:9
ERROR Object of class `MockAccount` has no attribute `current_tenant_id` [missing-attribute]
@@ -5591,8 +5599,20 @@
--> tests/unit_tests/core/workflow/generator/test_runner.py:2438:16
ERROR Cannot index into `str` [bad-index]
--> tests/unit_tests/core/workflow/generator/test_runner.py:2439:16
+ERROR Argument `str` is not assignable to parameter `mode` with type `Literal['advanced-chat', 'workflow']` in function `core.workflow.generator.runner.WorkflowGenerator.generate_workflow_graph_stream` [bad-argument-type]
+ --> tests/unit_tests/core/workflow/generator/test_runner.py:3064:111
+ERROR Argument `str` is not assignable to parameter `mode` with type `Literal['advanced-chat', 'workflow']` in function `core.workflow.generator.runner.WorkflowGenerator.generate_workflow_graph` [bad-argument-type]
+ --> tests/unit_tests/core/workflow/generator/test_runner.py:3066:103
+ERROR Class member `MockGenerator._collect_refs_in_data` overrides parent class `WorkflowGenerator` in an inconsistent manner [bad-override-param-name]
+ --> tests/unit_tests/core/workflow/generator/test_runner_missing.py:112:13
+ERROR Class member `MockGenerator._collect_refs_in_data` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
+ --> tests/unit_tests/core/workflow/generator/test_runner_missing.py:112:13
+ERROR Argument `dict[str, list[dict[str, str]]]` is not assignable to parameter `graph` with type `GraphDict` in function `core.workflow.generator.runner.WorkflowGenerator._collect_edge_cycle_errors` [bad-argument-type]
+ --> tests/unit_tests/core/workflow/generator/test_runner_missing.py:124:65
+ERROR Argument `dict[str, list[dict[str, str | dict[str, str]]] | list[Unknown]]` is not assignable to parameter `graph` with type `GraphDict` in function `core.workflow.generator.runner.WorkflowGenerator._validate_structure` [bad-argument-type]
+ --> tests/unit_tests/core/workflow/generator/test_runner_missing.py:185:58
ERROR Argument `None` is not assignable to parameter `plugin_id` with type `str` in function `_make_plugin_provider` [bad-argument-type]
- --> tests/unit_tests/core/workflow/generator/test_tool_catalogue.py:344:55
+ --> tests/unit_tests/core/workflow/generator/test_tool_catalogue.py:352:55
ERROR Default `str` is not assignable to parameter `node_type` with type `BuiltinNodeTypes` [bad-function-definition]
--> tests/unit_tests/core/workflow/graph_engine/layers/test_llm_quota.py:48:50
ERROR Argument `str` is not assignable to parameter `node_type` with type `BuiltinNodeTypes` in function `_build_node` [bad-argument-type]
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #38175 +/- ##
==========================================
+ Coverage 85.36% 85.40% +0.04%
==========================================
Files 4970 4973 +3
Lines 258774 259157 +383
Branches 49076 49133 +57
==========================================
+ Hits 220893 221339 +446
+ Misses 33576 33515 -61
+ Partials 4305 4303 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
pyrefly rejected flask.stream_with_context called with a generator (constrained AnyStr overload — "no-matching-overload"), failing the Python type-check CI. Switch the streaming endpoint to the repo's established SSE helper compact_generate_response (which wraps _stream_with_request_context), so it type-checks and still preserves request context during iteration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- jsonc/sort-keys (CI TS Common): the new i18n keys were appended at the end; re-sort them into ascending order across all locales via eslint --fix. - knip (CI Web Style): WorkflowGenPlanNode / WorkflowGenPlanInput are only used inside debug.ts, so stop exporting them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a render test for GenerationPlan (planning state vs. plan outline + building state), covering the previously-untested new component and improving patch coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5 tasks
…38202) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- web/service/base.spec.ts: replace require() with ESM import, add eslint-disable for no-restricted-imports - web/service/debug.spec.ts: fix trailing commas, trailing spaces, if-newline, no-explicit-any, and import order - api/tests/.../test_runner_missing.py: remove invalid node_ids kwarg from _validate_structure call Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…proof The TestBuildToolCatalogue cases patch `isinstance` and route the provider class checks through `_patched_isinstance`, which compared `cls` by identity (`is`) against a fresh import of Builtin/PluginToolProviderController. In the full API unit-test suite (parallel xdist), a sibling test that reloads or stubs `core.tools.*.provider` via sys.modules hands the catalogue a class object that differs by identity from a fresh import here — the `is` checks miss, every fake provider falls through to the real isinstance, and build_tool_catalogue returns empty. That flaked 6 cases in CI (`assert [] == [...]`) while passing in isolation. Match the provider classes by `__name__`, which is immune to reloads. Test-only; passes in isolation and under a broad core sweep. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Post Root-cause fix for the API Unit Tests failure: TestBuildSuggestionContext stubbed `core.workflow.generator.tool_catalogue` in sys.modules and then `del`-ed it instead of restoring the original. Under xdist that evicted the real module, so a sibling test (test_tool_catalogue) that imported `build_tool_catalogue` at collection time diverged from a freshly re-imported module and its @patch targets stopped applying — 6 catalogue tests came back empty. Reproduced locally (polluter→victim) and fixed by restoring via monkeypatch.setitem. Also add a sseGeneratorPost unit test (plan/result streaming, chunk-split reassembly, non-2xx + rejected-fetch error paths) to cover the SSE consumer, which was the largest patch-coverage gap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hand-rolled planner preview markup with existing Dify UI widgets: - swap the bespoke numbered step badges for the shared workflow BlockIcon so each plan step shows the same icon it will have on the canvas - swap the bare centred "Planning…" spinner for the shared Skeleton primitives, shaped like the node list so the pane fills in place instead of jumping Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hjlarry
approved these changes
Jul 1, 2026
iamjoel
approved these changes
Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Enhances the AI auto-creation flow — the
⌘K→/createand/refineworkflow/chatflow generator (behindENABLE_FEATURE_PREVIEW) — end-to-end, implementing the stage 1–5 program tracked in #38174. Also folds in the two concrete refinements that started this work: dropping the low-value "Ideal output" field and replacing the static example chips with AI-generated, workspace-grounded suggestions.Closes #38174 (item 3.1 intentionally dropped; see Deferred below).
Osmo.2026-06-30T12-53-31Z.mp4
What changed
Backend (
api/)POST /workflow-generate/suggestions— returns a few short, buildable example instructions for the generator's "ideas" chips, grounded in the tenant's real knowledge bases + installed tools. Runs on the tenant default model (works before the user picks one) and soft-fails to{ "suggestions": [] }so the UI silently falls back.POST /workflow-generate/stream(SSE) — plan-first generation: emits aplanevent the moment the planner finishes, then aresultevent after the builder + validation. Reuses the existing planner/builder/validate stages through one shared generator, so the streamedresultprovably equals the blocking/workflow-generatereturn (parity test included).mode: "auto"on both generate endpoints — a tiny classifier resolves Workflow vs Chatflow before planning; the concrete mode is echoed back asmodeand never leaks"auto"./workflow-generateis unchanged except its response now also carriesmode.Frontend (
web/)Stage 1 — entry & input
/create workflow summarize a URLpre-fills the modal; "Auto" submenu option opens auto-mode.Stage 2 — generation
sseGeneratorPostconsumer that reuses the cookie-auth/CSRF/abort setup without touching the sharedhandleStream. Falls back to the single-shot endpoint if the stream can't start.Stage 3 — review (3.1 dropped)
UNKNOWN_TOOL) Install tools.Stage 4 — apply
/refinediff summary (added / removed / changed) computed client-side from the base vs. generated graph.⌘K → /refine.Stage 5 — history
i18n
New keys added across all 23 locales (
workflow.json+app.json); en-US authoritative, zh-Hans/zh-Hant translated, others English pending the translate bot.Tests
/createcommand (inline capture + auto option + threading).type-checkclean;eslint --quiet(CI posture) reports no new errors.Deferred (follow-ups, tracked in #38174)
ENABLE_FEATURE_PREVIEWthe cmd+k entry suffices; lands with GA.Notes
🤖 Generated with Claude Code