feat: add lda report workflow example
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from wf_api.models import RawWorkflowPlan
|
||||
from wf_authoring import WorkflowBuilder
|
||||
from wf_core import Workflow
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
WORKFLOW_OUTPUT = [
|
||||
{"path": "state.approved", "target": "approved"},
|
||||
{"path": "state.final_markdown", "target": "markdown"},
|
||||
{"path": "state.created_issues", "target": "created_issues"},
|
||||
{"path": "state.selected_issue_ids", "target": "selected_issue_ids"},
|
||||
]
|
||||
|
||||
|
||||
def build_workflow() -> Workflow:
|
||||
"""Build the demo workflow with the public authoring API.
|
||||
|
||||
`WorkflowBuilder` does not yet expose a workflow-output setter, so this
|
||||
module adds the final output projection in `_with_workflow_output()` after
|
||||
compiling the graph. Keep that seam small and validated.
|
||||
"""
|
||||
builder = WorkflowBuilder(
|
||||
name="lda_report_case_study",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"selected_documents": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"board_path": {"type": "string"},
|
||||
},
|
||||
"required": ["selected_documents", "board_path"],
|
||||
},
|
||||
state_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documents": {"type": "array"},
|
||||
"analysis": {"type": "array"},
|
||||
"report": {"type": "object"},
|
||||
"report_markdown": {"type": "string"},
|
||||
"proposed_issues": {"type": "array"},
|
||||
"selected_issue_ids": {"type": "array"},
|
||||
"approval_comment": {"type": "string"},
|
||||
"approved": {"type": "boolean"},
|
||||
"created_issues": {"type": "array"},
|
||||
"final_markdown": {"type": "string"},
|
||||
},
|
||||
},
|
||||
output_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"approved": {"type": "boolean"},
|
||||
"markdown": {"type": "string"},
|
||||
"created_issues": {"type": "array"},
|
||||
"selected_issue_ids": {"type": "array"},
|
||||
},
|
||||
},
|
||||
outcomes=["completed", "cancelled"],
|
||||
)
|
||||
|
||||
read_docs = builder.use_ref(
|
||||
"local.lda_docs.read_documents",
|
||||
id="read_docs",
|
||||
input=[{"path": "input.selected_documents", "target": "names"}],
|
||||
output=[{"source": "documents", "target": "state.documents"}],
|
||||
)
|
||||
analyze = builder.use_ref(
|
||||
"local.lda_report.analyze_documents",
|
||||
id="analyze",
|
||||
input=[{"path": "state.documents", "target": "documents"}],
|
||||
output=[{"source": "analysis", "target": "state.analysis"}],
|
||||
)
|
||||
build_report = builder.use_ref(
|
||||
"local.lda_report.build_report",
|
||||
id="build_report",
|
||||
input=[{"path": "state.analysis", "target": "analysis"}],
|
||||
output=[
|
||||
{"source": "report", "target": "state.report"},
|
||||
{"source": "markdown", "target": "state.report_markdown"},
|
||||
],
|
||||
)
|
||||
draft_issues = builder.use_ref(
|
||||
"local.lda_report.create_issue_drafts",
|
||||
id="draft_issues",
|
||||
input=[{"path": "state.report", "target": "report"}],
|
||||
output=[{"source": "issues", "target": "state.proposed_issues"}],
|
||||
)
|
||||
review_issues = builder.interrupt(
|
||||
id="review_issues",
|
||||
kind="issue_review",
|
||||
request=[
|
||||
{"path": "state.report_markdown", "target": "report_markdown"},
|
||||
{"path": "state.proposed_issues", "target": "proposed_issues"},
|
||||
],
|
||||
resume=[
|
||||
{"source": "approved", "target": "state.approved"},
|
||||
{"source": "selected_issue_ids", "target": "state.selected_issue_ids"},
|
||||
{"source": "comment", "target": "state.approval_comment"},
|
||||
],
|
||||
outcomes=["submitted", "cancelled"],
|
||||
request_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"report_markdown": {"type": "string"},
|
||||
"proposed_issues": {"type": "array"},
|
||||
},
|
||||
"required": ["report_markdown", "proposed_issues"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
resume_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"approved": {"type": "boolean"},
|
||||
"selected_issue_ids": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"comment": {"type": "string"},
|
||||
},
|
||||
"required": ["approved", "selected_issue_ids"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
)
|
||||
create_issues = builder.use_ref(
|
||||
"local.issue_board.create_issues",
|
||||
id="create_issues",
|
||||
input=[
|
||||
{"path": "state.proposed_issues", "target": "issues"},
|
||||
{"path": "state.selected_issue_ids", "target": "selected_issue_ids"},
|
||||
{"path": "input.board_path", "target": "board_path"},
|
||||
],
|
||||
output=[{"source": "created_issues", "target": "state.created_issues"}],
|
||||
)
|
||||
finalise = builder.use_ref(
|
||||
"local.lda_report.finalise_report",
|
||||
id="finalise",
|
||||
input=[
|
||||
{"path": "state.report", "target": "report"},
|
||||
{"path": "state.created_issues", "target": "created_issues"},
|
||||
{"path": "state.approved", "target": "approved"},
|
||||
{"path": "state.selected_issue_ids", "target": "selected_issue_ids"},
|
||||
{"path": "state.approval_comment", "target": "comment"},
|
||||
],
|
||||
output=[{"source": "markdown", "target": "state.final_markdown"}],
|
||||
)
|
||||
revision_requested = builder.use_ref(
|
||||
"local.lda_report.record_revision_request",
|
||||
id="revision_requested",
|
||||
input=[{"path": "state.approval_comment", "target": "comment"}],
|
||||
output=[
|
||||
{"source": "approved", "target": "state.approved"},
|
||||
{"source": "markdown", "target": "state.final_markdown"},
|
||||
{"source": "created_issues", "target": "state.created_issues"},
|
||||
{"source": "selected_issue_ids", "target": "state.selected_issue_ids"},
|
||||
],
|
||||
)
|
||||
end_completed = builder.end("completed", id="end_completed")
|
||||
end_cancelled = builder.end("cancelled", id="end_cancelled")
|
||||
|
||||
builder.set_entry_point(read_docs)
|
||||
builder.connect(read_docs, "ok", analyze)
|
||||
builder.connect(analyze, "ok", build_report)
|
||||
builder.connect(build_report, "ok", draft_issues)
|
||||
builder.connect(draft_issues, "ok", review_issues)
|
||||
builder.branch(
|
||||
review_issues,
|
||||
{
|
||||
"submitted": create_issues,
|
||||
"cancelled": revision_requested,
|
||||
},
|
||||
)
|
||||
builder.connect(create_issues, "ok", finalise)
|
||||
builder.connect(finalise, "ok", end_completed)
|
||||
builder.connect(revision_requested, "ok", end_cancelled)
|
||||
return _with_workflow_output(builder.compile())
|
||||
|
||||
|
||||
def _with_workflow_output(workflow: Workflow) -> Workflow:
|
||||
payload = workflow.model_dump(mode="json", by_alias=True)
|
||||
payload["output"] = WORKFLOW_OUTPUT
|
||||
return Workflow.model_validate(payload)
|
||||
|
||||
|
||||
def workflow_plan_payload() -> dict[str, Any]:
|
||||
payload = build_workflow().model_dump(mode="json", by_alias=True)
|
||||
payload.pop("node_defs", None)
|
||||
RawWorkflowPlan.model_validate(payload)
|
||||
return payload
|
||||
|
||||
|
||||
def write_plan(path: Path = HERE / "workflow.plan.json") -> None:
|
||||
payload = workflow_plan_payload()
|
||||
path.write_text(
|
||||
json.dumps(payload, indent=2, sort_keys=True) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
write_plan()
|
||||
Reference in New Issue
Block a user