[!IMPORTANT] Every fixture, rulebook, and calculator output in this lab is synthetic and non-binding. Nothing here represents an actual Desjardins product, rate, or policy, and no regulator or insurer has reviewed or endorsed this material.
Overview
| Item | Value |
|---|---|
| Duration | 30 minutes |
| Level | Intermediate |
| Prerequisites | Lab 06 |
Learning Objectives
By the end of this lab, you will be able to:
- Run the agent’s CLI end to end against a fixture, with no Azure or hosted Foundry call
- Confirm the applicant-facing message never includes an amount, a rulebook table, or a reviewer-only field
- Act as the human reviewer against the same
ApprovalRepository, before meeting the reviewer interface in Lab 13 - Confirm an invalid case reference produces a bounded rejection message instead of a raised exception
Exercises
Exercise 7.1: Run the CLI Against a Known Fixture
python src/quote-preparation-agent/main.py CASE-SYN-001
Expected result: a JSON object with en-CA and fr-CA keys, each holding a bilingual sentence telling the applicant their request was submitted for employee review. No dollar amount, rulebook field, or reviewer identifier appears anywhere in the output.
Before the JSON, two log lines on stderr show the agent calling both MCP tools from Labs 04 and 05:
get_application('CASE-SYN-001') -> found
get_rulebook('RULEBOOK-SYN-ON') -> found
[!TIP] If you get
ModuleNotFoundError: No module named 'langgraph', the terminal is not using the workshop virtual environment. Run./.venv/Scripts/Activate.ps1from the repository root (see Lab 00), then retry.
Exercise 7.2 (Hands-on): Confirm the Workflow State Directly
The CLI only prints the applicant message. Call run_case directly to inspect the full state, including workflow_state.
python -c "
import sys
sys.path.insert(0, 'src/quote-preparation-agent')
from main import run_case
final_state = run_case('CASE-SYN-001')
print('workflow_state:', final_state['workflow_state'])
print('draft_case_id:', final_state['draft_case_id'])
print('applicant_message:', final_state['applicant_message'])
"
Expected result: workflow_state is PENDING_REVIEW. The case was created and submitted for review, but nothing in the agent’s own code approved or rejected it.
Exercise 7.3 (Hands-on): Act as the Human Reviewer
A reviewer acts here directly against ApprovalRepository, one layer below any user interface. Share one repository instance between the agent run and your reviewer step so they operate on the same case.
Lab 13 performs this same transition through the reviewer application, against a persistent case store and a verified Entra identity. Doing it in Python first makes the later lab easier to read, because you will already know which call the button is making.
python -c "
import sys
sys.path.insert(0, 'src/quote-preparation-agent')
sys.path.insert(0, 'apps/workshop')
from main import run_case
from approval_repository import ApprovalRepository
repo = ApprovalRepository()
final_state = run_case('CASE-SYN-001', repository=repo, preparer_id='AGENT-INTAKE')
print('after agent run:', final_state['workflow_state'])
record = repo.approve(final_state['draft_case_id'], reviewer_id='EMP-REVIEWER-01')
print('after human review:', record.state)
"
Expected result: the state moves from PENDING_REVIEW to APPROVED, and the reviewer ID (EMP-REVIEWER-01) differs from the preparer ID (AGENT-INTAKE) used by the agent.
Exercise 7.4: Run Against an Invalid Case Reference
python src/quote-preparation-agent/main.py "NOT-A-VALID-CASE-ID"
Expected result: a bilingual message stating the request could not be processed because the case reference was invalid, with no exception raised and no case created in the approval repository.
Validation Checklist
- Exercise 7.1 prints a bilingual message with no dollar amount
- Exercise 7.2 confirms
workflow_stateisPENDING_REVIEWimmediately after the agent runs - Exercise 7.3 approves the case as a distinct reviewer, moving it to
APPROVED - Exercise 7.4 returns the bounded rejection message for an invalid case reference
Knowledge Check
- Why does the agent stop at
PENDING_REVIEWinstead of deciding the case itself? - What would happen in Exercise 7.3 if you called
repo.approvewithreviewer_id='AGENT-INTAKE'instead of a distinct reviewer?
Next Steps
Continue to Lab 08: Evaluation Suite.