Skip to content

Commit 5bf86a6

Browse files
committed
Clarify workflow exception policy
1 parent 9eb2d56 commit 5bf86a6

2 files changed

Lines changed: 162 additions & 120 deletions

File tree

src/workflow.py

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66
77
Business logic remains in preprocess.py, classifier.py, and router.py. This
88
module is responsible only for Microsoft Agent Framework orchestration.
9+
10+
Exception policy:
11+
- Expected input and classifier-output validation failures are converted into
12+
WorkflowResult(status=FAILED).
13+
- Provider, router, terminal-executor, framework, and invariant exceptions
14+
propagate to the caller so programming defects and infrastructure failures
15+
are not silently hidden.
16+
- The outer CLI boundary is responsible for logging propagated exceptions and
17+
presenting a safe user-facing error.
918
"""
1019

1120
from __future__ import annotations
@@ -22,9 +31,9 @@
2231
Workflow,
2332
WorkflowBuilder,
2433
WorkflowContext,
25-
WorkflowEvent,
2634
executor,
2735
)
36+
from pydantic import ValidationError
2837
from typing_extensions import Never
2938

3039
from src.classifier import build_classification_prompt, parse_classification_response
@@ -154,7 +163,7 @@ async def classifier_response_executor(
154163
classification = parse_classification_response(
155164
response.agent_response.text
156165
)
157-
except Exception as error:
166+
except (TypeError, ValueError, ValidationError) as error:
158167
await ctx.yield_output(
159168
build_failed_result(
160169
error,
@@ -501,24 +510,11 @@ async def run_bug_triage_workflow(
501510
) -> WorkflowResult:
502511
"""Run the workflow and return its single validated output."""
503512

504-
workflow_trace = WorkflowTrace()
505513
workflow = build_bug_triage_workflow(
506514
classifier_agent,
507515
human_approval_enabled=human_approval_enabled,
508-
trace=workflow_trace,
509516
)
510-
try:
511-
run_result = await workflow.run(raw_text)
512-
except Exception as error:
513-
if workflow_trace.is_classifier_provider_boundary_active():
514-
workflow_trace.exit_classifier_provider_boundary()
515-
return build_failed_result(
516-
error,
517-
stage="classification",
518-
executor="classifier_agent",
519-
trace=workflow_trace,
520-
)
521-
raise
517+
run_result = await workflow.run(raw_text)
522518

523519
outputs = run_result.get_outputs()
524520

@@ -534,41 +530,22 @@ async def run_bug_triage_workflow(
534530
return result
535531

536532

537-
538533
async def stream_bug_triage_workflow(
539534
raw_text: str,
540535
classifier_agent: Agent,
541536
*,
542537
human_approval_enabled: bool = True,
543538
):
544-
"""Stream workflow events and convert native-agent failures to typed output."""
539+
"""Stream workflow events."""
545540

546-
workflow_trace = WorkflowTrace()
547541
workflow = build_bug_triage_workflow(
548542
classifier_agent,
549543
human_approval_enabled=human_approval_enabled,
550-
trace=workflow_trace,
551544
)
552545

553-
try:
554-
async for event in workflow.run(
555-
raw_text,
556-
stream=True,
557-
include_status_events=True,
558-
):
559-
yield event
560-
except Exception as error:
561-
if not workflow_trace.is_classifier_provider_boundary_active():
562-
raise
563-
564-
workflow_trace.exit_classifier_provider_boundary()
565-
yield WorkflowEvent(
566-
"output",
567-
executor_id="classifier_agent",
568-
data=build_failed_result(
569-
error,
570-
stage="classification",
571-
executor="classifier_agent",
572-
trace=workflow_trace,
573-
),
574-
)
546+
async for event in workflow.run(
547+
raw_text,
548+
stream=True,
549+
include_status_events=True,
550+
):
551+
yield event

0 commit comments

Comments
 (0)