From a554891bbdc086ecfce813c0486c680d58bef009 Mon Sep 17 00:00:00 2001 From: FFXN <31929997+FFXN@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:08:12 +0800 Subject: [PATCH] fix: snippet history detail includes input fields (#37797) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../console/snippets/snippet_workflow.py | 15 +++++- api/openapi/markdown/console-openapi.md | 11 ++++- .../console/snippets/test_snippet_workflow.py | 49 +++++++++++++++++++ .../api/console/snippets/types.gen.ts | 28 ++--------- .../generated/api/console/snippets/zod.gen.ts | 29 ++--------- 5 files changed, 79 insertions(+), 53 deletions(-) diff --git a/api/controllers/console/snippets/snippet_workflow.py b/api/controllers/console/snippets/snippet_workflow.py index 5af885ab91b..0b8dc264a68 100644 --- a/api/controllers/console/snippets/snippet_workflow.py +++ b/api/controllers/console/snippets/snippet_workflow.py @@ -80,6 +80,13 @@ class SnippetDraftConfigResponse(BaseModel): parallel_depth_limit: int +class SnippetWorkflowPaginationResponse(BaseModel): + items: list[SnippetWorkflowResponse] + page: int + limit: int + has_more: bool + + register_schema_models( console_ns, SnippetDraftSyncPayload, @@ -98,6 +105,7 @@ register_response_schema_models( SimpleResultResponse, SnippetDraftConfigResponse, SnippetWorkflowResponse, + SnippetWorkflowPaginationResponse, WorkflowPublishResponse, WorkflowPaginationResponse, WorkflowRestoreResponse, @@ -329,7 +337,7 @@ class SnippetPublishedAllWorkflowApi(Resource): @console_ns.response( 200, "Published workflows retrieved successfully", - console_ns.models[WorkflowPaginationResponse.__name__], + console_ns.models[SnippetWorkflowPaginationResponse.__name__], ) @setup_required @login_required @@ -350,7 +358,7 @@ class SnippetPublishedAllWorkflowApi(Resource): limit=args.limit, ) - return WorkflowPaginationResponse.model_validate( + response = SnippetWorkflowPaginationResponse.model_validate( { "items": workflows, "page": args.page, @@ -359,6 +367,9 @@ class SnippetPublishedAllWorkflowApi(Resource): }, from_attributes=True, ).model_dump(mode="json") + for item in response["items"]: + item["input_fields"] = snippet.input_fields_list + return response @console_ns.route("/snippets//workflows//restore") diff --git a/api/openapi/markdown/console-openapi.md b/api/openapi/markdown/console-openapi.md index c600984c089..bb40c8b48b0 100644 --- a/api/openapi/markdown/console-openapi.md +++ b/api/openapi/markdown/console-openapi.md @@ -8159,7 +8159,7 @@ Get all published workflows for a snippet | Code | Description | Schema | | ---- | ----------- | ------ | -| 200 | Published workflows retrieved successfully | **application/json**: [WorkflowPaginationResponse](#workflowpaginationresponse)
| +| 200 | Published workflows retrieved successfully | **application/json**: [SnippetWorkflowPaginationResponse](#snippetworkflowpaginationresponse)
| ### [GET] /snippets/{snippet_id}/workflows/default-workflow-block-configs **Get default block configurations for snippet workflow** @@ -19417,6 +19417,15 @@ Query parameters for listing snippet published workflows. | limit | integer,
**Default:** 10 | | No | | page | integer,
**Default:** 1 | | No | +#### SnippetWorkflowPaginationResponse + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| has_more | boolean | | Yes | +| items | [ [SnippetWorkflowResponse](#snippetworkflowresponse) ] | | Yes | +| limit | integer | | Yes | +| page | integer | | Yes | + #### SnippetWorkflowResponse | Name | Type | Description | Required | diff --git a/api/tests/unit_tests/controllers/console/snippets/test_snippet_workflow.py b/api/tests/unit_tests/controllers/console/snippets/test_snippet_workflow.py index 11916c87b68..b20dd3e30a7 100644 --- a/api/tests/unit_tests/controllers/console/snippets/test_snippet_workflow.py +++ b/api/tests/unit_tests/controllers/console/snippets/test_snippet_workflow.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json from datetime import datetime from inspect import unwrap from types import SimpleNamespace @@ -199,6 +200,54 @@ def test_default_block_configs_delegates_to_service(app: Flask, monkeypatch: pyt get_default_block_configs.assert_called_once() +def test_list_published_snippet_workflows_includes_input_fields(app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: + workflow = SimpleNamespace( + id="workflow-1", + graph_dict={"nodes": [], "edges": []}, + features_dict={}, + unique_hash="hash-1", + version="2024-01-01 00:00:00", + marked_name="", + marked_comment="", + created_by_account=None, + created_at=datetime(2024, 1, 1), + updated_by_account=None, + updated_at=datetime(2024, 1, 1), + tool_published=False, + environment_variables=[], + conversation_variables=[], + rag_pipeline_variables=[], + ) + input_fields = [{"variable": "query", "type": "text"}] + snippet = _snippet(input_fields=json.dumps(input_fields)) + + class SessionContext: + def __init__(self, engine): + self.engine = engine + + def __enter__(self): + return Mock() + + def __exit__(self, exc_type, exc, tb): + return False + + monkeypatch.setattr(snippet_workflow_module, "Session", SessionContext) + monkeypatch.setattr(snippet_workflow_module, "db", SimpleNamespace(engine=object())) + monkeypatch.setattr( + snippet_workflow_module, + "SnippetService", + lambda: SimpleNamespace(get_all_published_workflows=Mock(return_value=([workflow], False))), + ) + + api = snippet_workflow_module.SnippetPublishedAllWorkflowApi() + handler = unwrap(api.get) + + with app.test_request_context("/snippets/snippet-1/workflows?page=1&limit=20"): + response = handler(api, snippet=snippet) + + assert response["items"][0]["input_fields"] == input_fields + + def test_restore_published_snippet_workflow_to_draft_success(app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: workflow = SimpleNamespace( unique_hash="restored-hash", diff --git a/packages/contracts/generated/api/console/snippets/types.gen.ts b/packages/contracts/generated/api/console/snippets/types.gen.ts index d46a6389a52..631da7bace8 100644 --- a/packages/contracts/generated/api/console/snippets/types.gen.ts +++ b/packages/contracts/generated/api/console/snippets/types.gen.ts @@ -37,9 +37,9 @@ export type WorkflowRunNodeExecutionListResponse = { data: Array } -export type WorkflowPaginationResponse = { +export type SnippetWorkflowPaginationResponse = { has_more: boolean - items: Array + items: Array limit: number page: number } @@ -235,28 +235,6 @@ export type SimpleEndUser = { type: string } -export type WorkflowResponse = { - conversation_variables: Array - created_at: number - created_by?: SimpleAccount | null - environment_variables: Array - features: { - [key: string]: unknown - } - graph: { - [key: string]: unknown - } - hash: string - id: string - marked_comment: string - marked_name: string - rag_pipeline_variables: Array - tool_published: boolean - updated_at: number - updated_by?: SimpleAccount | null - version: string -} - export type WorkflowConversationVariableResponse = { description: string id: string @@ -417,7 +395,7 @@ export type GetSnippetsBySnippetIdWorkflowsData = { } export type GetSnippetsBySnippetIdWorkflowsResponses = { - 200: WorkflowPaginationResponse + 200: SnippetWorkflowPaginationResponse } export type GetSnippetsBySnippetIdWorkflowsResponse diff --git a/packages/contracts/generated/api/console/snippets/zod.gen.ts b/packages/contracts/generated/api/console/snippets/zod.gen.ts index 1c861084434..85e5b961547 100644 --- a/packages/contracts/generated/api/console/snippets/zod.gen.ts +++ b/packages/contracts/generated/api/console/snippets/zod.gen.ts @@ -300,32 +300,11 @@ export const zSnippetWorkflowResponse = z.object({ }) /** - * WorkflowResponse + * SnippetWorkflowPaginationResponse */ -export const zWorkflowResponse = z.object({ - conversation_variables: z.array(zWorkflowConversationVariableResponse), - created_at: z.int(), - created_by: zSimpleAccount.nullish(), - environment_variables: z.array(zWorkflowEnvironmentVariableResponse), - features: z.record(z.string(), z.unknown()), - graph: z.record(z.string(), z.unknown()), - hash: z.string(), - id: z.string(), - marked_comment: z.string(), - marked_name: z.string(), - rag_pipeline_variables: z.array(zPipelineVariableResponse), - tool_published: z.boolean(), - updated_at: z.int(), - updated_by: zSimpleAccount.nullish(), - version: z.string(), -}) - -/** - * WorkflowPaginationResponse - */ -export const zWorkflowPaginationResponse = z.object({ +export const zSnippetWorkflowPaginationResponse = z.object({ has_more: z.boolean(), - items: z.array(zWorkflowResponse), + items: z.array(zSnippetWorkflowResponse), limit: z.int(), page: z.int(), }) @@ -443,7 +422,7 @@ export const zGetSnippetsBySnippetIdWorkflowsQuery = z.object({ /** * Published workflows retrieved successfully */ -export const zGetSnippetsBySnippetIdWorkflowsResponse = zWorkflowPaginationResponse +export const zGetSnippetsBySnippetIdWorkflowsResponse = zSnippetWorkflowPaginationResponse export const zGetSnippetsBySnippetIdWorkflowsDefaultWorkflowBlockConfigsPath = z.object({ snippet_id: z.uuid(),