This commit is contained in:
77
app/workflows/ingestion_workflow.py
Normal file
77
app/workflows/ingestion_workflow.py
Normal file
@@ -0,0 +1,77 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
from typing import Any, Callable
|
||||
from ..nodes import deployment_node, discovery_node, generation_node, validation_node
|
||||
from ..states.ingestion_state import IngestionState
|
||||
|
||||
|
||||
class IngestionWorkflow:
|
||||
"""LangGraph StateGraph workflow runner for Content Ingestion Agent.
|
||||
|
||||
Executes the 4-phase contract: Discovery -> Validation -> Generation -> Deployment.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
scm: Any = None,
|
||||
cms: Any = None,
|
||||
allowed_sources: set[str] | None = None,
|
||||
publish_enabled: bool = False,
|
||||
require_governance_approval: bool = True,
|
||||
):
|
||||
self.nodes: dict[str, Callable[[IngestionState], dict[str, Any]]] = {
|
||||
"discovery": discovery_node,
|
||||
"validation": functools.partial(validation_node, allowed_sources=allowed_sources),
|
||||
"generation": functools.partial(generation_node, scm=scm),
|
||||
"deployment": functools.partial(
|
||||
deployment_node,
|
||||
cms=cms,
|
||||
publish_enabled=publish_enabled,
|
||||
require_governance_approval=require_governance_approval,
|
||||
),
|
||||
}
|
||||
|
||||
def invoke(self, state: IngestionState) -> IngestionState:
|
||||
"""Run the workflow sequentially through the 4 phases."""
|
||||
current_state: IngestionState = dict(state) # type: ignore
|
||||
current_state.setdefault("messages", [])
|
||||
current_state.setdefault("errors", [])
|
||||
current_state.setdefault("has_errors", False)
|
||||
current_state.setdefault("current_step", "discovery")
|
||||
current_state.setdefault("next_step", "discovery")
|
||||
|
||||
current_node_name = "discovery"
|
||||
|
||||
while current_node_name and current_node_name != "END":
|
||||
node_fn = self.nodes.get(current_node_name)
|
||||
if not node_fn:
|
||||
break
|
||||
|
||||
update = node_fn(current_state)
|
||||
current_state.update(update) # type: ignore
|
||||
|
||||
# Route based on next_step contract
|
||||
next_step = current_state.get("next_step")
|
||||
if not next_step or next_step == "END" or current_state.get("has_errors"):
|
||||
break
|
||||
|
||||
current_node_name = next_step
|
||||
|
||||
return current_state
|
||||
|
||||
|
||||
def create_ingestion_workflow(
|
||||
scm: Any = None,
|
||||
cms: Any = None,
|
||||
allowed_sources: set[str] | None = None,
|
||||
publish_enabled: bool = False,
|
||||
require_governance_approval: bool = True,
|
||||
) -> IngestionWorkflow:
|
||||
return IngestionWorkflow(
|
||||
scm=scm,
|
||||
cms=cms,
|
||||
allowed_sources=allowed_sources,
|
||||
publish_enabled=publish_enabled,
|
||||
require_governance_approval=require_governance_approval,
|
||||
)
|
||||
Reference in New Issue
Block a user