
Agents for Humans: Building a Durable Route Repair Agent with Strands, AgentCore, and Amazon Location
A technical deep dive into how RoutePatch combines Strands Agents, Amazon Bedrock AgentCore, Amazon Location, OR-Tools, DynamoDB, and async AWS services to safely repair live logistics routes.
Agents for Humans: Building a Durable Route Repair Agent with Strands, AgentCore, and Amazon Location
RoutePatch started as a route-repair idea. It became a full AWS-hosted operational system with an agentic control layer, deterministic optimization, durable state, and a live map-first product.
RoutePatch helps community logistics teams recover when an active route plan breaks.
A vehicle becomes unavailable.
An urgent pickup appears.
A stop is cancelled.
A receiving window changes.
An urgent pickup appears.
A stop is cancelled.
A receiving window changes.
Instead of manually rebuilding the entire day, RoutePatch repairs only the unfinished portion of the operation, validates the new plan, and commits it safely.
This post is a technical walkthrough of the AWS architecture behind it.
π Live product: https://judge.d1hjlmux26gpdn.amplifyapp.com
π» Source code: https://github.com/jpablortiz96/routepatch
π₯ Demo: https://youtu.be/qlRenRrnOms
π Build journey: https://builder.aws.com/content/3JKCu4Y2HteSWMCLFcOo2E0ree6/agents-for-humans-routepatch-when-the-route-breaks-the-food-still-arrives
π‘οΈ Safety & bounded autonomy deep-dive: https://builder.aws.com/content/3JKDTbuxDODX6RmXPFK8lDMgjNc/agents-for-humans-why-routepatch-lets-an-agent-ask-but-never-decide-what-is-true
π» Source code: https://github.com/jpablortiz96/routepatch
π₯ Demo: https://youtu.be/qlRenRrnOms
π Build journey: https://builder.aws.com/content/3JKCu4Y2HteSWMCLFcOo2E0ree6/agents-for-humans-routepatch-when-the-route-breaks-the-food-still-arrives
π‘οΈ Safety & bounded autonomy deep-dive: https://builder.aws.com/content/3JKDTbuxDODX6RmXPFK8lDMgjNc/agents-for-humans-why-routepatch-lets-an-agent-ask-but-never-decide-what-is-true
Operational scenarios are synthetic. Geography is public. AWS infrastructure is live.
ποΈ The architecture goal
I wanted RoutePatch to satisfy five things at the same time:
- Agentic workflow coordination
- Real road routing
- Deterministic operational safety
- Durable state
- A public product experience
The difficult part was not connecting services.
The difficult part was deciding which service or component should own which kind of truth.
The final design separates the system into two major zones:
Probabilistic coordination
Handled by:
- Strands Agents SDK
- Amazon Bedrock AgentCore Runtime
- Amazon Nova Pro
Deterministic / authoritative operations
Handled by:
- Amazon Location Routes V2
- OR-Tools
- Independent Validator
- DynamoDB transactional commit
That split is the backbone of the system.
πΊοΈ 1. RoutePatch Web App
The public product is a React + TypeScript application rendered with MapLibre GL JS.
It is hosted through AWS Amplify Hosting.
The product is map-first rather than chat-first.
Operators can see:
- routes;
- vehicles;
- stops;
- execution progress;
- incidents;
- route health;
- before/after plan geometry;
- validation status.
Insert screenshot here: operations.png
Caption: RoutePatch Live Operations β the map is the primary product surface.
The frontend never calculates the operational route itself.
It consumes authoritative state from the RoutePatch API.
π 2. FastAPI behind API Gateway
The product API is implemented in FastAPI and runs through AWS Lambda behind Amazon API Gateway.
A key design choice was making the API asynchronous.
Agent workflows can take several seconds.
I did not want a browser request sitting open while AgentCore, routing, optimization, and validation completed.
So the public flow is:
1
2
3
4
5
6
7
POST disruption
β
Persist workflow as QUEUED
β
Invoke worker asynchronously
β
Return HTTP 202 immediatelyThe browser then polls durable workflow state.
This changed the UX completely.
The operator sees:
- incident accepted;
- repair in progress;
- human decision required;
- validated plan committed;
without pretending the model is instant.
β‘ 3. Async worker
A dedicated Lambda worker processes RoutePatch workflows.
Its payload is intentionally small:
- session ID;
- workflow ID;
- action: START or RESUME.
The worker reloads authoritative state from DynamoDB rather than trusting a large message body.
For a new workflow, it invokes AgentCore.
For a resumed HITL workflow, it reloads the saved runtime session and interrupt metadata and continues the same process.
Duplicate worker deliveries are idempotently ignored.
This matters because async systems should assume retries can happen.
π€ 4. Strands inside Amazon Bedrock AgentCore Runtime
The RoutePatch agent runs inside Amazon Bedrock AgentCore Runtime.
The model is Amazon Nova Pro via Bedrock.
Strands coordinates high-level workflow behavior such as:
- trusted event flow;
- ambiguous natural-language reports;
- clarification;
- HITL interrupt/resume;
- repair invocation;
- terminal outcome handling.
The agent does not receive low-level mutation tools.
Instead, it works with high-level capabilities such as:
- submit event proposal;
- get authoritative clarification options;
- create attestation;
- resume from human decision;
- repair attested event.
That keeps orchestration agentic without exposing raw operational mutation primitives.
π€ 5. Genuine HITL with durable resume
One of the most important cloud proofs was this input:
βOne of our vans broke down.β
The workflow cannot safely continue because the vehicle is unknown.
Inside AgentCore, Strands issues a real interrupt.
The frontend receives a pending decision.
DynamoDB stores:
- runtime session ID;
- interrupt ID;
- decision type;
- authoritative options;
- workflow binding.
Insert screenshot here: hitl.png
Caption: Strands pauses only when a real-world fact is missing.
The operator selects a vehicle.
The RoutePatch API validates the decision.
The worker then invokes AgentCore again with the same runtime session ID and the real interrupt response.
The same logical workflow resumes.
This is not a new chat pretending to continue the old one.
π 6. Amazon Location Routes V2
Once an event is attested, RoutePatch needs real road travel information.
I implemented a provider-neutral routing interface and then connected it to Amazon Location Routes V2 using
geo-routes.Amazon Location supplies:
- route matrices;
- travel duration;
- distance;
- real road geometry.
The optimizer does not know anything about AWS response structures.
The adapter normalizes AWS routing data into RoutePatch's internal matrix contract.
That means the deterministic core stays provider-neutral.
π§ 7. Real road geometry
RoutePatch also uses CalculateRoutes to persist route geometry for the product experience.
Each route can contain:
- ordered stops;
- legs;
- distance;
- duration;
- road-following geometry;
- provider timestamp;
- geometry digest.
The browser receives persisted geometry.
It does not call routing APIs directly.
This lets the UI render:
- previous plan;
- repaired plan;
- completed segments;
- future segments;
- disrupted segments;
- route direction.
Insert screenshot here: repair.png
Caption: The map transitions from the previous route geometry to the validated repaired plan.
βοΈ 8. OR-Tools owns route repair
The actual repair is deterministic.
RoutePatch uses Google OR-Tools to search for a feasible minimal repair.
The objective is lexicographic rather than a single opaque weighted score.
Conceptually, RoutePatch prefers to:
- minimize future-stop reassignment;
- minimize added travel;
- protect time-window slack;
- reduce imbalance;
- apply a deterministic tie-break.
Completed or in-progress work is not available for reassignment.
That rule is especially important after the operation has started.
π 9. Plan state vs ExecutionState
A route plan describes what should happen.
Execution state describes what already happened.
RoutePatch stores these separately.
Example:
1
2
3
4
5
Plan v7:
Stop 06 β Route 02
ExecutionState:
Stop 06 β COMPLETEDIf Vehicle 02 later becomes unavailable, the repair snapshot knows that Stop 06 is locked.
The optimizer may move future work.
It cannot move Stop 06.
Insert screenshot here: live-execution.png
Caption: Completed work becomes immutable operational truth.
This separation is what turned RoutePatch from a planning proof into a running-operations product.
β 10. Independent validation
A candidate route is not trusted just because OR-Tools generated it.
A separate deterministic validator checks hard constraints.
Examples include:
- resources are registered and available;
- no assignment overlap;
- capacity;
- hard windows;
- mandatory unfinished stops served exactly once;
- cancelled stops absent;
- completed/in-progress work immutable;
- pickup-before-delivery;
- shift limits;
- reference/version bindings.
Only a
VALID candidate can move toward commit.ποΈ 11. DynamoDB as operational truth
RoutePatch uses Amazon DynamoDB for durable state.
The table stores items such as:
- session metadata;
- active plan pointer;
- immutable plan versions;
- events;
- attestations;
- validations;
- commit truth;
- idempotency records;
- workflows;
- pending human decisions;
- execution state.
Synthetic public sessions use TTL.
The in-memory store still exists for offline testing, but product mode fails closed if DynamoDB is unavailable or misconfigured.
No silent fallback to memory.
π 12. Transactional CAS commit
The most important state mutation is the plan commit.
RoutePatch uses TransactWriteItems and conditional checks to enforce compare-and-swap semantics.
Conceptually:
1
2
3
4
5
6
7
8
9
10
11
IF active_version == candidate.base_version
AND validation == VALID
AND attestation is authoritative
AND idempotency key is consistent
THEN atomically:
create immutable new plan
update active pointer
record commit truth
record idempotency truth
update workflow dispositionIf another writer advances the active plan first:
VERSION_CONFLICTThe stale candidate does not become v9.
There is no silent automatic retry.
π 13. Durable idempotency
DynamoDB supports request-token idempotency, but RoutePatch does not depend on that alone.
The application stores its own durable idempotency record.
That means:
same key + same canonical request
β reconstruct original result
same key + changed canonical request
β
IDEMPOTENCY_CONFLICTI explicitly tested a βlost responseβ case:
- commit succeeded;
- caller simulated losing the response;
- same request was retried;
- RoutePatch recovered the original v8 result;
- no v9 was created.
That is the kind of behavior an operational API needs.
π 14. Deterministic Route Health
RoutePatch derives Route Health from known operational state.
Statuses include:
HEALTHYAT_RISKINTERRUPTEDCOMPLETEDUNKNOWN
Inputs can include:
- route progress;
- remaining work;
- next stop;
- resource availability;
- known capacity;
- time-window slack.
Insert screenshot here: route-health.png
Caption: Route Health is deterministic awareness, not a predictive AI score.
This distinction is intentional.
If the system lacks a required input, it can return
UNKNOWN rather than generating confidence.π 15. Architecture at a glance
Insert image here: architecture.png
Caption: RoutePatch separates probabilistic coordination from deterministic operational authority.
The complete flow is approximately:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Operator
β
React + MapLibre
β
FastAPI / API Gateway
β
DynamoDB workflow state
β
Async Lambda worker
β
AgentCore Runtime
β
Strands + Nova Pro
β
Attestation / HITL
β
Amazon Location Routes V2
β
OR-Tools
β
Independent Validator
β
DynamoDB CAS commit
β
Authoritative plan
β
Map transitionAmazon Location Maps V2 provides the read-only browser basemap.
π§ͺ 16. What we proved
Across the approved RoutePatch architecture:
- β 20 / 20 deterministic scenario contracts passed
- β 16 / 16 approved HITL workflow benchmark cases passed
- β real AgentCore deployment
- β real Amazon Location route matrix
- β real route geometry
- β real DynamoDB transactional commit
- β real public async API
- β real public React product
- β 0 unsafe commits
- β 0 unattested commits
- β 0 commits after version conflict
- β 0 completed stops moved during execution-aware repair testing
These are synthetic engineering evaluation results, not claims about real-world nonprofit impact.
π‘ What surprised me most
The architecture became stronger every time I removed an unnecessary responsibility from the model.
The model did not need to:
- optimize;
- validate;
- commit;
- own resource truth;
- own completed-work truth.
Once those responsibilities moved to deterministic systems, Strands became more useful at what agents are good at:
- understanding messy situations;
- coordinating multi-step workflows;
- deciding when a human is needed;
- pausing;
- resuming;
- connecting the pieces.
That was the biggest architectural lesson from RoutePatch.
π Try the full system
Live product:
https://judge.d1hjlmux26gpdn.amplifyapp.com
https://judge.d1hjlmux26gpdn.amplifyapp.com
Source code:
https://github.com/jpablortiz96/routepatch
https://github.com/jpablortiz96/routepatch
Demo video:
https://youtu.be/qlRenRrnOms
https://youtu.be/qlRenRrnOms
Suggested path:
- Open the live product.
- Start a route.
- Complete a stop.
- Report Vehicle 02 unavailable.
- Watch the unfinished operation repair.
- Verify completed work remains locked.
- Compare Before / After.
- Try an ambiguous human-decision workflow.
No login required.
β€οΈ Closing
For me, RoutePatch became an example of what an operational agent can look like when AI is not asked to own every part of the system.
The result is not less agentic.
It is more deliberate.
Strands coordinates the uncertainty.
AWS provides the durable runtime and infrastructure.
Deterministic systems prove what can safely change.
And the human appears only when reality contains a fact the system cannot know on its own.
When the route breaks, the food still arrives.
Built for the Good Neighbor Agents track of the AWS Agents for Humans Hackathon.
Operational scenarios are synthetic. Geography is public. AWS execution is live.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article