Feature/workflow history (#3432)

Co-authored-by: Shuchang Zheng <wintonzheng0325@gmail.com>
This commit is contained in:
Alex Angin
2025-09-21 02:48:27 -04:00
committed by GitHub
parent 9a9ee01253
commit 0b47482fcb
19 changed files with 1387 additions and 67 deletions

View File

@@ -1459,6 +1459,30 @@ class AgentDB:
LOG.error("SQLAlchemyError", exc_info=True)
raise
async def get_workflow_versions_by_permanent_id(
self,
workflow_permanent_id: str,
organization_id: str | None = None,
exclude_deleted: bool = True,
) -> list[Workflow]:
"""
Get all versions of a workflow by its permanent ID, ordered by version descending (newest first).
"""
try:
get_workflows_query = select(WorkflowModel).filter_by(workflow_permanent_id=workflow_permanent_id)
if exclude_deleted:
get_workflows_query = get_workflows_query.filter(WorkflowModel.deleted_at.is_(None))
if organization_id:
get_workflows_query = get_workflows_query.filter_by(organization_id=organization_id)
get_workflows_query = get_workflows_query.order_by(WorkflowModel.version.desc())
async with self.Session() as session:
workflows = (await session.scalars(get_workflows_query)).all()
return [convert_to_workflow(workflow, self.debug_enabled) for workflow in workflows]
except SQLAlchemyError:
LOG.error("SQLAlchemyError", exc_info=True)
raise
async def get_workflows_by_permanent_ids(
self,
workflow_permanent_ids: list[str],

View File

@@ -1840,6 +1840,36 @@ async def get_workflow(
)
@legacy_base_router.get(
"/workflows/{workflow_permanent_id}/versions",
response_model=list[Workflow],
tags=["agent"],
openapi_extra={
"x-fern-sdk-method-name": "get_workflow_versions",
},
)
@legacy_base_router.get(
"/workflows/{workflow_permanent_id}/versions/", response_model=list[Workflow], include_in_schema=False
)
async def get_workflow_versions(
workflow_permanent_id: str,
current_org: Organization = Depends(org_auth_service.get_current_org),
template: bool = Query(False),
) -> list[Workflow]:
"""
Get all versions of a workflow by its permanent ID.
"""
analytics.capture("skyvern-oss-agent-workflow-versions-get")
if template:
if workflow_permanent_id not in await app.STORAGE.retrieve_global_workflows():
raise InvalidTemplateWorkflowPermanentId(workflow_permanent_id=workflow_permanent_id)
return await app.WORKFLOW_SERVICE.get_workflow_versions_by_permanent_id(
workflow_permanent_id=workflow_permanent_id,
organization_id=None if template else current_org.organization_id,
)
@legacy_base_router.post(
"/suggest/{ai_suggestion_type}",
include_in_schema=False,

View File

@@ -746,6 +746,23 @@ class WorkflowService:
return workflow
async def get_workflow_versions_by_permanent_id(
self,
workflow_permanent_id: str,
organization_id: str | None = None,
exclude_deleted: bool = True,
) -> list[Workflow]:
"""
Get all versions of a workflow by its permanent ID.
Returns an empty list if no workflow is found with that permanent ID.
"""
workflows = await app.DATABASE.get_workflow_versions_by_permanent_id(
workflow_permanent_id,
organization_id=organization_id,
exclude_deleted=exclude_deleted,
)
return workflows
async def get_block_outputs_for_debug_session(
self,
workflow_permanent_id: str,