feat: support direct import of Claude workflows#33508
feat: support direct import of Claude workflows#33508xi-zhao wants to merge 5 commits intolanggenius:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Dify platform by enabling direct import of Claude workflows. It introduces a new backend pipeline that validates Claude workflow YAML against a defined schema, compiles it into Dify's native DSL, and then processes the import. This streamlines the process for users who wish to migrate or utilize workflows designed in the Claude format, providing a more integrated and user-friendly experience for workflow management. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces support for importing Claude workflows by compiling them into the native Dify DSL. The implementation includes a new schema, a compiler, and an import service, along with updates to the API and frontend to handle the new import path and its specific error conditions. The code is well-structured and thoroughly tested. I have a few suggestions to enhance error handling and code clarity, particularly around database transaction management, exception specificity, and schema validation to prevent unhandled server errors.
| for index, edge in enumerate(document.edges): | ||
| if edge.target not in node_ids: | ||
| issues.append( | ||
| ClaudeWorkflowValidationIssue( | ||
| code=ClaudeWorkflowSchemaErrorCode.UNKNOWN_EDGE_TARGET, | ||
| path=("edges", index, "target"), | ||
| message=f"Unknown edge target: {edge.target}", | ||
| ) | ||
| ) |
There was a problem hiding this comment.
The cross-reference validation correctly checks edge.target, but it misses validation for edge.source. An invalid edge.source (one that is not 'start' or a valid node ID) will cause the compiler to fail with an unhandled StopIteration, leading to a 500 Internal Server Error. You should add validation for edge.source to ensure a clean 400 Bad Request is returned for invalid workflows. You might also consider adding a new UNKNOWN_EDGE_SOURCE error code for more precise error reporting.
for index, edge in enumerate(document.edges):
if edge.source not in valid_sources:
issues.append(
ClaudeWorkflowValidationIssue(
code=ClaudeWorkflowSchemaErrorCode.UNKNOWN_EDGE_TARGET,
path=("edges", index, "source"),
message=f"Unknown edge source: {edge.source}",
)
)
if edge.target not in node_ids:
issues.append(
ClaudeWorkflowValidationIssue(
code=ClaudeWorkflowSchemaErrorCode.UNKNOWN_EDGE_TARGET,
path=("edges", index, "target"),
message=f"Unknown edge target: {edge.target}",
)
)| app_id=args.app_id, | ||
| ) | ||
| except ClaudeWorkflowImportExecutionError as exc: | ||
| session.commit() |
There was a problem hiding this comment.
This session.commit() call within the except block is unnecessary and potentially misleading. Since the ClaudeWorkflowImportExecutionError is raised before any database modifications are made within the import service, there is nothing to commit. The with Session(...) context manager will correctly handle the transaction. Removing this line will make the code clearer and avoid potential issues if the service logic changes in the future.
| response = ssrf_proxy.get(yaml_url.strip(), follow_redirects=True, timeout=(10, 10)) | ||
| response.raise_for_status() | ||
| content = response.content.decode() | ||
| except Exception: |
There was a problem hiding this comment.
Catching a bare Exception is generally discouraged as it can hide unexpected errors and even catch system-level exceptions like KeyboardInterrupt. It would be safer to catch more specific exceptions related to the HTTP request (e.g., from the ssrf_proxy library). If a broad exception is necessary, consider capturing and logging it (e.g., except Exception as e:) to aid in debugging.
Summary
/apps/importscan acceptkind: claude-workflowYAML and compile it into native Dify workflow DSLTest Plan
uv run --project api pytest api/tests/unit_tests/services/claude_workflow/test_schema.py api/tests/unit_tests/services/claude_workflow/test_compiler.py api/tests/unit_tests/services/claude_workflow/test_import_service.py api/tests/unit_tests/controllers/console/app/test_claude_workflow_import_api.py -q --override-ini addopts=''pnpm test hooks/use-import-dsl.spec.tsx app/components/app/create-from-dsl-modal/index.spec.tsxpnpm lint hooks/use-import-dsl.ts service/apps.ts app/components/app/create-from-dsl-modal/index.tsx app/components/app/create-from-dsl-modal/index.spec.tsx hooks/use-import-dsl.spec.tsx