-
-
Five coded agents, six stages, two human gates — one swappable PlatformPort (local ⇄ UiPath)
-
CaseWeaver — agentic mortgage underwriting on UiPath Maestro Case (cover)
-
Clean file, real run: DTI 29% / LTV 80% / 760 → straight-through approval
-
Borderline 44% DTI rescued by compensating factors → Gate A + Gate B → conditional approve
-
Gate A — the underwriter sees the agent's full reasoning before deciding
-
The loan-officer desk: metrics, rationale, conditions, and policy citations
-
Durable, cross-process human-in-the-loop — suspends and resumes like Maestro
-
Same agent code runs on UiPath; validated uipath pack → valid .nupkg (no tenant)
-
Built with Claude Code — 72 tests, 93% coverage, 0 open Critical/High
-
Exceptions: conflicting data → human verify; AML hit → escalate to compliance
Inspiration
We kept hearing the same thing about agentic AI: the magic isn't a clever prompt on a laptop — it's operating and governing agents in production, where work is messy, things fail, and a human has to stay accountable. Mortgage underwriting is the perfect crucible for that. Most loan files are routine, but the long tail is brutal: missing documents, low-confidence OCR, conflicting data, marginal debt ratios, appraisal gaps, and fraud. Rigid RPA snaps on those exceptions; a raw LLM has no business making a regulated credit decision on its own.
That tension — autonomy where it helps, humans where it matters — is exactly the shape of UiPath Maestro Case. So we set out to build a real, exception-heavy underwriting case where coded agents do the reasoning, robots do the mechanical work, and humans hold authority at every credit decision.
What it does
CaseWeaver runs a loan application through a six-stage Maestro Case with two human gates and a table-driven exception lane:
Intake → Document Verification → Income Analysis → Credit & Risk Adjudication → Conditions/Compliance → Human-Approved Decision
- Five coded agents coordinate the case; each emits an auditable timeline entry.
- Document Understanding extracts fields; a
redigitizeretry fixes low-confidence OCR before escalating to a human. - Adjudication computes the real underwriting math and applies policy:
$$\text{DTI}_{\text{back}}=\frac{\text{debts}+\text{housing}}{\text{income}}\le 0.43,\qquad \text{LTV}=\frac{\text{loan}}{\min(\text{appraisal},\text{price})}\le 0.97$$
A file landing in the borderline band ($0.43 < \text{DTI} \le 0.46$) isn't auto-declined — it's routed to a human with the agent's full reasoning and any compensating factors (reserves, credit depth, equity).
- Two human gates: Gate A is underwriter decision-support (borderline files only); Gate B is final authority on every approve/decline.
- Exceptions are the product: an AML watchlist hit is a hard stop that escalates to compliance; conflicting employer data routes to a human; transient bureau failures retry with backoff.
Four personas demo every path end-to-end — clean_approve, conditional_approve, decline, and fraud_exception — each reaching the correct terminal state.
How we built it
The whole project was built by Claude Code (Claude Opus 4.8) through UiPath for Coding Agents, driven as a small multi-agent "AI project agency" (plan → build → test → security → docs).
The architectural keystone is one seam — a PlatformPort interface:
- Agents are real LangGraph graphs and never import the UiPath SDK directly.
RUNTIME_MODE=localinjects aLocalAdapter(deterministic mocks + a SQLite "Action Inbox" + a durable checkpointer).RUNTIME_MODE=uipathinjects aUiPathAdaptermapping each capability to the real platform: human gates →interrupt(CreateTask | CreateEscalation)(Action Center), secrets → Orchestrator assets, documents → Document Understanding, LLM → UiPath LLM Gateway.
So the exact same graph runs offline-mocked and on UiPath Automation Cloud. Two more deliberate choices:
- Decisions are deterministic and policy-driven; the LLM only narrates — reproducible, testable, and safe for a regulated decision (offline by default via a stub).
- Durable suspend/resume via a SQLite-backed LangGraph checkpointer mirrors Maestro: a case pauses at a gate in one process and resumes in another. An external framework (CrewAI) runs a "Credit Analyst vs Risk Officer" panel for borderline files — inside the governed graph, feature-flagged with a deterministic fallback.
We then validated the cloud path for real: uipath init + uipath pack produce a valid .nupkg without a tenant, with a clean CaseInput/CaseOutput contract.
Challenges we ran into
- No tenant during the build. This is what forced the dual-mode
PlatformPort— and it turned out to be the best decision we made. - LangGraph 1.x specifics. We probed the live
interrupt/CommandAPI and verified cross-process Pydantic-state persistence through SQLite before building on it, and added a module-scoped msgpack deserialization allowlist to keep it safe and warning-free. - The UiPath graph loader imports the entry module by file path (no package context), which broke relative imports — fixed by making the orchestrator use absolute imports while siblings stay relative.
- A 64 KB entry-points schema. Exposing the full internal state made an ugly contract; introducing explicit
input_schema/output_schemashrank it to ~29 KB and made the deployed agent's I/O meaningful. - Producing the demo video headlessly — Chrome
--headless=newhung onfile://; classic--headlessexits cleanly, which let us render real-data scenes into a narrated MP4.
Accomplishments that we're proud of
- One codebase, two worlds: the same agents run locally and on UiPath, proven by a packaged
.nupkg. - Durable, cross-process human-in-the-loop that genuinely survives interruptions — the capability the hackathon asks for.
- Exception handling as a first-class, auditable feature (seven routes in one policy table, all tested).
- Production-grade rigor: 72 tests, ~93% coverage,
ruff+mypyclean, and a STRIDE security audit with 0 open Critical/High findings. - A narrated 3-minute demo where every number on screen is real program output.
- The whole thing was built by a coding agent, with the git history (every commit co-authored) as the receipt.
What we learned
- The seam is the product. A clean port between agent logic and platform is what makes "runs on my laptop" and "runs governed in the cloud" the same artifact.
- Keep the LLM out of the verdict. In regulated work, agents should reason and narrate; the decision belongs to deterministic policy and an accountable human.
- Probe, don't guess. Inspecting the installed
uipathSDK and LangGraph APIs live saved us from a pile of plausible-but-wrong code. - Coding agents shine on the unglamorous 80% — adapters, tests, packaging, exception tables, docs — which is exactly the "last mile to production" the platform is about.
What's next for CaseWeaver — Mortgage Underwriting Agents
- Go live on UiPath Labs: publish the coded agent, wire the Maestro Case canvas from
case_definition.yaml, and connect Action Center gates. - Real connectors: swap the mocked bureau/AML services for API Workflows and run Document Understanding on actual PDFs.
- Escalation memory: feed resolved gate outcomes back so the agents learn from underwriter decisions over time.
- Broaden the case templates to adjacent exception-heavy domains — disputes, KYC remediation, claims — reusing the same governed, human-in-the-loop pattern.
Built With
- anthropic
- claude
- claude-code
- crewai
- css
- document-understanding
- fastapi
- ffmpeg
- html
- jinja
- langchain
- langgraph
- maestro-case
- mypy
- pillow
- pydantic
- pytest
- python
- ruff
- sqlite
- typer
- uipath
- uipath-action-center
- uipath-automation-cloud
- uipath-cli
- uipath-coded-agents
- uipath-langchain
- uipath-llm-gateway
- uipath-maestro
- uipath-orchestrator
- uv
Log in or sign up for Devpost to join the conversation.