Skip to content

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
  1. forward 0.99
  2. do_task 0.007
  3. fyi_only 0.001

Open in playground

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
  1. yes 0.991
  2. unclear 0.006
  3. no 0.003

Open in playground

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
email

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
  1. orders 1
  2. product 0
  3. payments 0

Open in playground

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
  1. cancel_order 0.999
  2. return_item 0
  3. track_order 0

Open in playground

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
  1. yes 1
  2. no 0

Open in playground

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.