66
77Business logic remains in preprocess.py, classifier.py, and router.py. This
88module 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
1120from __future__ import annotations
2231 Workflow ,
2332 WorkflowBuilder ,
2433 WorkflowContext ,
25- WorkflowEvent ,
2634 executor ,
2735)
36+ from pydantic import ValidationError
2837from typing_extensions import Never
2938
3039from 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-
538533async 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