diff --git a/api/services/app_generate_service.py b/api/services/app_generate_service.py index 17a112136d..06fc51bddc 100644 --- a/api/services/app_generate_service.py +++ b/api/services/app_generate_service.py @@ -133,17 +133,13 @@ class AppGenerateService: from services.workflow.virtual_workflow import VirtualWorkflowSynthesizer try: - virtual_workflow = VirtualWorkflowSynthesizer.synthesize(app_model) + workflow = VirtualWorkflowSynthesizer.ensure_workflow(app_model) logger.info( - "[AGENT_V2_UPGRADE] Transparent upgrade for app %s (mode=%s)", + "[AGENT_V2_UPGRADE] Transparent upgrade for app %s (mode=%s), wf=%s", app_model.id, effective_mode, + workflow.id, ) - workflow_id_arg = args.get("workflow_id") - if not workflow_id_arg: - workflow = virtual_workflow - else: - workflow = cls._get_workflow(app_model, invoke_from, workflow_id_arg) if streaming: with rate_limit_context(rate_limit, request_id): diff --git a/api/services/workflow/virtual_workflow.py b/api/services/workflow/virtual_workflow.py index 6167f01349..fdcffaa506 100644 --- a/api/services/workflow/virtual_workflow.py +++ b/api/services/workflow/virtual_workflow.py @@ -73,6 +73,36 @@ class VirtualWorkflowSynthesizer: return workflow + @staticmethod + def ensure_workflow(app: App) -> Any: + """Ensure the old app has a workflow, creating one if needed. + + On first call for a legacy app, synthesizes a workflow from its + AppModelConfig and persists it as a draft. On subsequent calls, + returns the existing draft. This is a one-time lazy upgrade: + the app gets a real workflow that can be edited in the workflow editor. + + The app's workflow_id is NOT updated (preserving its legacy state), + but the workflow is findable via app_id + version="draft". + """ + from models.workflow import Workflow + + from extensions.ext_database import db + + existing = db.session.query(Workflow).filter_by( + app_id=app.id, version="draft" + ).first() + if existing: + return existing + + workflow = VirtualWorkflowSynthesizer.synthesize(app) + workflow.version = "draft" + + db.session.add(workflow) + db.session.commit() + logger.info("Created draft workflow %s for legacy app %s", workflow.id, app.id) + return workflow + def _extract_model_config(config: AppModelConfig) -> dict[str, Any]: if config.model: