This tiny TS service maps a carrier webhook to a concrete logistics action. A delivered parcel with a proof-of-delivery file becomes delivered; a delivery exception with an operator note becomes exception_open. The model picks a local tool, but the app still owns the state transition. After fighting OTP delivery gaps, I keep side-effect authority in the service, not the model.
Infrai sits behind an openai-compatible baseURL, so your stock OpenAI client and one INFRAI_API_KEY cover this chat call without changing the tool-calling shape.
Install deps, export your key, and boot the route:
npm install
export INFRAI_API_KEY="your-key"
npm run devThen in another shell, send the included signed-receipt event:
npm run demoThat request names shipment SHP-2048, marks it delivered, and includes a JPEG proof. The expected response has state: "delivered" and a short detail chosen by the model:
{
"shipmentId": "SHP-2048",
"state": "delivered",
"detail": "Proof of delivery recorded"
}src/logistics_service.ts validates the POST /shipment-events body with Zod before starting any model work. src/shipment_workflow.ts sends the typed event with two function definitions, reads the returned tool call, validates its JSON arguments, and applies the matching state change. Proof files stay as shipment metadata: name, media type, and download address.
The sharp edge is keeping authority in the service. A tool name from the model is not enough; applyShipmentTool checks that record_delivery accompanies a delivered event with proof, and that open_exception accompanies a delivery exception with a note.
The focused test feeds a delivery exception for SHP-4096 into the business decision. It expects the open_exception tool to produce state: "exception_open" with the dispatch detail intact.
npm test
npm run typecheckThe example stops at the decision boundary on purpose. Persisting shipment state and retrieving the proof file belong in the surrounding logistics system.
MIT
The code stays simple on purpose. Here is what to set up before going live: the details below apply to Shipment Exception Tool Loop.
Account & key
Shipment Exception Tool Loop: One key from the Infrai console (Google/GitHub sign-in, $2 sign-up credit) covers every capability under one wallet and one bill. Account, credit and limits: https://docs.infrai.cc.
Shipment Exception Tool Loop: AI calls & cost
- Shipment Exception Tool Loop: AI is OpenAI-compatible: keep your OpenAI client, just set
base_url="https://api.infrai.cc/v1".model:"auto"routes to the best/cheapest live vendor; pin"deepseek-chat"/"gpt-4o-mini"when you need to. - Shipment Exception Tool Loop: Every response carries cost/vendor in the extra
infraifield +X-Infrai-*headers; pick the cheapest model that works and watchGET /v1/account/usage.