Open-source adapters
Support
The support adapters sort what arrives in an inbox or a support queue: what type of message it is, what it asks for, whether a team must act, and who should handle it. Most of them take your own categories, teams and rules as context or as labels, so the same function serves an office manager's inbox, a council team's mailbox and an online shop's help desk. The page ends with the trading desk adapter, which applies a desk's written rules to the market in the same way.
Each example below uses an input written for this page and shows the answer returned by the live API. To run one yourself, set JEFF_API_KEY as in the Quick start.
Shared inbox triage
Shared inbox triage triages a message using the inbox's own message types, routing table and rules: what it is, what action it needs, how urgent it is and who should handle it. Each of those is a separate function; this example asks what an architecture practice's office manager should do with a supplier's invoice:
Context
- recipient
- name: Lena Brandt address: lena.brandt@hollowayarch.example role: Office manager organisation: Holloway Architects
- message_kinds
- invoice: A supplier's bill or a question about one booking: Meeting room, travel or event bookings it_problem: Something broken with computers, phones or the network newsletter: Bulk mail and marketing
- routing_table
- - {"key":"finance","name":"Finance team","address":"finance@hollowayarch.example","topics":"Supplier invoices, payments, expenses"} - {"key":"it","name":"IT support","address":"it@hollowayarch.example","topics":"Computers, phones, printers, network and accounts"}
- routing_rules
- - Anything about a client project's fees goes to the partner on the project, never to finance.
- now
- Monday 2 November 2026, 09:40
Input
channel: email from: billing@greenleafplants.example to: lena.brandt@hollowayarch.example cc: received: Monday 2 November 2026, 08:55 subject: Invoice GL-5520 for October plant care body: Hello Lena, please find attached our invoice GL-5520 for October's plant care at your Bristol office, 240.00. Could you arrange payment within 30 days? Kind regards, Greenleaf Plants
- Answer (JSON)
- value forward, confidence 0.99
- Top options
- forward 0.99
- do_task 0.007
- fyi_only 0.001
import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client: decide = client.function("jeff.support.message-triage.action_needed", context={ "recipient": { "name": "Lena Brandt", "address": "lena.brandt@hollowayarch.example", "role": "Office manager", "organisation": "Holloway Architects", }, "message_kinds": { "invoice": "A supplier's bill or a question about one", "booking": "Meeting room, travel or event bookings", "it_problem": "Something broken with computers, phones or the network", "newsletter": "Bulk mail and marketing", }, "routing_table": [ { "key": "finance", "name": "Finance team", "address": "finance@hollowayarch.example", "topics": "Supplier invoices, payments, expenses", }, { "key": "it", "name": "IT support", "address": "it@hollowayarch.example", "topics": "Computers, phones, printers, network and accounts", }, ], "routing_rules": [ "Anything about a client project's fees goes to the partner on the project, never to finance.", ], "now": "Monday 2 November 2026, 09:40", }) decision = decide({ "channel": "email", "from": "billing@greenleafplants.example", "to": "lena.brandt@hollowayarch.example", "cc": "", "received": "Monday 2 November 2026, 08:55", "subject": "Invoice GL-5520 for October plant care", "body": "Hello Lena, please find attached our invoice GL-5520 for October's plant care at your Bristol office, 240.00. Could you arrange payment within 30 days? Kind regards, Greenleaf Plants", }) print(decision.value, decision.confidence)
forward means a team in the routing table should deal with it and is not yet on the message: here the finance
team, which handles supplier invoices.
Team action and escalation check
Team action and escalation check reads a message against a team's policy and decides whether the team must act on it, and whether it must be escalated: yes, no or unclear. Here a council's highways team receives a report of a pothole:
Context
- team
- organisation: Westmoor Borough Council name: Highways team
- policy
- - The team handles potholes, damaged road signs, blocked drains on roads and broken street lights. - Any report of an immediate danger to people (for example an exposed cable or a collapsed road) must be escalated to the duty officer. - Bin collections and parking fines belong to other teams.
Input
from: r.osei@mailbox.example to: highways@westmoor.example date: 2 November 2026 subject: Pothole on Mill Lane body: There's a deep pothole outside number 14 Mill Lane, right where cyclists come down the hill. Could someone take a look?
- Answer (JSON)
- value yes, confidence 0.991
- Top options
- yes 0.991
- unclear 0.006
- no 0.003
import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client: decide = client.function("jeff.support.requires-action.requires_action", context={ "team": { "organisation": "Westmoor Borough Council", "name": "Highways team", }, "policy": [ "The team handles potholes, damaged road signs, blocked drains on roads and broken street lights.", "Any report of an immediate danger to people (for example an exposed cable or a collapsed road) must be escalated to the duty officer.", "Bin collections and parking fines belong to other teams.", ], }) decision = decide({ "from": "r.osei@mailbox.example", "to": "highways@westmoor.example", "date": "2 November 2026", "subject": "Pothole on Mill Lane", "body": "There's a deep pothole outside number 14 Mill Lane, right where cyclists come down the hill. Could someone take a look?", }) print(decision.value, decision.confidence)
yes means the team is responsible for acting on the message: potholes are on its list.
Support ticket triage
Support ticket triage routes a support ticket or email to a team and scores its urgency, sentiment and need for a person. This example asks for the team, from the teams you pass as labels:
Context
- company
- An online shop selling outdoor clothing and camping gear across Europe.
- channel
Input
Subject: Wrong item in my parcel Hi, my order 88213 arrived today but the parcel had a large Alpine shell jacket instead of the medium I ordered. Please exchange it and send the medium before Saturday. Thanks, Marta
Labels (the options)
- orders
- Orders, deliveries, returns and exchanges
- payments
- Payments, refunds and invoices
- product
- Product questions, sizing advice and stock
- account
- Customer accounts, passwords and newsletters
- Answer (JSON)
- value orders, confidence 1
- Top options
- orders 1
- product 0
- payments 0
import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client: decide = client.function("jeff.support.triage.route", context={ "company": "An online shop selling outdoor clothing and camping gear across Europe.", "channel": "email", }, labels={ "orders": "Orders, deliveries, returns and exchanges", "payments": "Payments, refunds and invoices", "product": "Product questions, sizing advice and stock", "account": "Customer accounts, passwords and newsletters", }) decision = decide("Subject: Wrong item in my parcel\nHi, my order 88213 arrived today but the parcel had a large Alpine shell jacket instead of the medium I ordered. Please exchange it and send the medium before Saturday. Thanks, Marta") print(decision.value, decision.confidence)
orders is the key of the team to send it to: exchanging an incorrect item is an orders matter, not a payments issue.
Customer request classification
Customer request classification names what a customer or assistant user is
asking for, from a fixed list of requests such as cancel_order or track_refund. Here a shop's chat receives a
message about an order placed yesterday:
Context
- service
- Customer support chat of an online shop
Input
hi, i changed my mind about the boots i ordered yesterday, can i still stop the order before it ships?
Labels (the options)
- cancel_order
- Cancel an order that has not been delivered yet
- track_order
- Find out where an order is
- change_address
- Change the delivery address of an order
- return_item
- Return an item that was delivered
- track_refund
- Find out the status of a refund
- Answer (JSON)
- value cancel_order, confidence 0.999
- Top options
- cancel_order 0.999
- return_item 0
- track_order 0
import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client: decide = client.function("jeff.support.support-intents.intent", context={ "service": "Customer support chat of an online shop", }, labels={ "cancel_order": "Cancel an order that has not been delivered yet", "track_order": "Find out where an order is", "change_address": "Change the delivery address of an order", "return_item": "Return an item that was delivered", "track_refund": "Find out the status of a refund", }) decision = decide("hi, i changed my mind about the boots i ordered yesterday, can i still stop the order before it ships?") print(decision.value, decision.confidence)
cancel_order is the request to act on: the boots have not shipped, so this is a cancellation, not a return.
Trading desk decisions
Trading desk decisions applies a trading desk's written rules to the live order book and decides whether to buy, sell or hold, the size and venue, how to handle open orders, and when to go risk-off. This example asks only whether a risk-off trigger has fired:
Context
- desk
- Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
- market_context
- Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.
Input
Time 13:12:05. Mid 40.31, 20-minute average 40.88. Spread 5 bp. Order-flow imbalance -0.42. Realised volatility (5 min) 38% annualised. Position: long 2,500 shares, average price 41.35. Day P&L on this stock: -26,400. Open orders: none. News: none flagged.
- Answer (JSON)
- value yes, confidence 1
- Top options
- yes 1
- no 0
import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client: decide = client.function("jeff.finance.trading-desk.risk_off", context={ "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).", "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.", }) decision = decide("Time 13:12:05. Mid 40.31, 20-minute average 40.88. Spread 5 bp.\nOrder-flow imbalance -0.42. Realised volatility (5 min) 38% annualised.\nPosition: long 2,500 shares, average price 41.35. Day P&L on this stock: -26,400.\nOpen orders: none. News: none flagged.") print(decision.value, decision.confidence)
yes means the desk should go risk-off: the day's loss on this stock (26,400) is beyond the 25,000 limit the rules
set, whatever the price signal says.