Skip to content
jeff.agents.tool-routev1.4.0

Agent tool selection from a menu

Selects the next tool from a menu included in the request, using the conversation for context. Can also indicate that no tool is needed or that the user must supply missing information.

Open in playground

Example

Context

app
Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices and clients and emails invoices on request.
today
Monday 2 November 2026
tools
def find_invoice(client: str, month: str) -> dict: """Finds the studio's invoice for a client and month.""" def send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict: """Emails an invoice to a recipient, with optional copies.""" def create_invoice(client: str, items: list[dict]) -> dict: """Creates a new draft invoice."""
conversation
- {"role":"user","content":"Morning! Can you send the October invoice for Orbit Print?"} - {"role":"assistant","content":"I found it, INV-2026-0412 for 2,350.00, still unpaid. Who at Orbit Print should receive it?"}

Input

Send it to their accounts address, accounts@orbitprint.example, and copy me.

Labels (the options)

find_invoice
Finds the studio's invoice for a client and month.
send_invoice
Emails an invoice to a recipient, with optional copies.
create_invoice
Creates a new draft invoice.
none
No tool is needed, or no tool on the menu can do what the user asks.
ask_user
A tool fits, but a required detail is missing and the agent must ask the user.
Answer (JSON)
value send_invoice, confidence 0.998
Top options
  1. send_invoice 0.998
  2. ask_user 0.002
  3. find_invoice 0

The user has given the last detail the agent needed, so the next tool to call is send_invoice.

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.agents.tool-route.tool", context={        "app": "Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices and clients and emails invoices on request.",        "today": "Monday 2 November 2026",        "tools": "def find_invoice(client: str, month: str) -> dict:\n    \"\"\"Finds the studio's invoice for a client and month.\"\"\"\ndef send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict:\n    \"\"\"Emails an invoice to a recipient, with optional copies.\"\"\"\ndef create_invoice(client: str, items: list[dict]) -> dict:\n    \"\"\"Creates a new draft invoice.\"\"\"",        "conversation": [            {                "role": "user",                "content": "Morning! Can you send the October invoice for Orbit Print?",            },            {                "role": "assistant",                "content": "I found it, INV-2026-0412 for 2,350.00, still unpaid. Who at Orbit Print should receive it?",            },        ],    }, labels={        "find_invoice": "Finds the studio's invoice for a client and month.",        "send_invoice": "Emails an invoice to a recipient, with optional copies.",        "create_invoice": "Creates a new draft invoice.",        "none": "No tool is needed, or no tool on the menu can do what the user asks.",        "ask_user": "A tool fits, but a required detail is missing and the agent must ask the user.",    })     decision = decide("Send it to their accounts address, accounts@orbitprint.example, and copy me.")     print(decision.value, decision.confidence)

More examples

  • Look up an invoiceanswer find_invoice · confidence 0.811

    Context

    app
    Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.
    today
    Monday 2 November 2026
    tools
    def find_invoice(client: str, month: str) -> dict: """Finds the studio's invoice for a client and month.""" def send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict: """Emails an invoice to a recipient, with optional copies.""" def create_invoice(client: str, items: list[dict]) -> dict: """Creates a new draft invoice."""
    conversation

    Input

    How much did we bill Moss & Gale in September 2026?

    Labels (the options)

    find_invoice
    Finds the studio's invoice for a client and month.
    send_invoice
    Emails an invoice to a recipient, with optional copies.
    create_invoice
    Creates a new draft invoice.
    none
    No tool is needed, or no tool on the menu can do what the user asks.
    ask_user
    A tool fits, but a required detail is missing and the agent must ask the user.
    Answer (JSON)
    value find_invoice, confidence 0.811
    Top options
    1. find_invoice 0.811
    2. none 0.166
    3. ask_user 0.018

    The user asks what was billed to a client in a given month, so the tool to call is find_invoice.

    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.agents.tool-route.tool", context={        "app": "Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.",        "today": "Monday 2 November 2026",        "tools": "def find_invoice(client: str, month: str) -> dict:\n    \"\"\"Finds the studio's invoice for a client and month.\"\"\"\ndef send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict:\n    \"\"\"Emails an invoice to a recipient, with optional copies.\"\"\"\ndef create_invoice(client: str, items: list[dict]) -> dict:\n    \"\"\"Creates a new draft invoice.\"\"\"",        "conversation": [],    }, labels={        "find_invoice": "Finds the studio's invoice for a client and month.",        "send_invoice": "Emails an invoice to a recipient, with optional copies.",        "create_invoice": "Creates a new draft invoice.",        "none": "No tool is needed, or no tool on the menu can do what the user asks.",        "ask_user": "A tool fits, but a required detail is missing and the agent must ask the user.",    })     decision = decide("How much did we bill Moss & Gale in September 2026?")     print(decision.value, decision.confidence)
  • Send an invoice, but which one?answer ask_user · confidence 0.991

    Context

    app
    Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.
    today
    Monday 2 November 2026
    tools
    def find_invoice(client: str, month: str) -> dict: """Finds the studio's invoice for a client and month.""" def send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict: """Emails an invoice to a recipient, with optional copies.""" def create_invoice(client: str, items: list[dict]) -> dict: """Creates a new draft invoice."""
    conversation

    Input

    Send the invoice to the client, please.

    Labels (the options)

    find_invoice
    Finds the studio's invoice for a client and month.
    send_invoice
    Emails an invoice to a recipient, with optional copies.
    create_invoice
    Creates a new draft invoice.
    none
    No tool is needed, or no tool on the menu can do what the user asks.
    ask_user
    A tool fits, but a required detail is missing and the agent must ask the user.
    Answer (JSON)
    value ask_user, confidence 0.991
    Top options
    1. ask_user 0.991
    2. send_invoice 0.004
    3. find_invoice 0.002

    The user wants an invoice sent but names neither the invoice nor the client, so the agent must ask_user.

    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.agents.tool-route.tool", context={        "app": "Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.",        "today": "Monday 2 November 2026",        "tools": "def find_invoice(client: str, month: str) -> dict:\n    \"\"\"Finds the studio's invoice for a client and month.\"\"\"\ndef send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict:\n    \"\"\"Emails an invoice to a recipient, with optional copies.\"\"\"\ndef create_invoice(client: str, items: list[dict]) -> dict:\n    \"\"\"Creates a new draft invoice.\"\"\"",        "conversation": [],    }, labels={        "find_invoice": "Finds the studio's invoice for a client and month.",        "send_invoice": "Emails an invoice to a recipient, with optional copies.",        "create_invoice": "Creates a new draft invoice.",        "none": "No tool is needed, or no tool on the menu can do what the user asks.",        "ask_user": "A tool fits, but a required detail is missing and the agent must ask the user.",    })     decision = decide("Send the invoice to the client, please.")     print(decision.value, decision.confidence)
  • The user says thanksanswer none · confidence 1

    Context

    app
    Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.
    today
    Monday 2 November 2026
    tools
    def find_invoice(client: str, month: str) -> dict: """Finds the studio's invoice for a client and month.""" def send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict: """Emails an invoice to a recipient, with optional copies.""" def create_invoice(client: str, items: list[dict]) -> dict: """Creates a new draft invoice."""
    conversation
    - {"role":"user","content":"Send the October invoice for Orbit Print to accounts@orbitprint.example."} - {"role":"assistant","content":"Done, INV-2026-0412 has been sent to accounts@orbitprint.example."}

    Input

    Perfect, thank you!

    Labels (the options)

    find_invoice
    Finds the studio's invoice for a client and month.
    send_invoice
    Emails an invoice to a recipient, with optional copies.
    create_invoice
    Creates a new draft invoice.
    none
    No tool is needed, or no tool on the menu can do what the user asks.
    ask_user
    A tool fits, but a required detail is missing and the agent must ask the user.
    Answer (JSON)
    value none, confidence 1
    Top options
    1. none 1
    2. ask_user 0
    3. send_invoice 0

    The user is only saying thank you, so no tool is needed and the answer is none.

    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.agents.tool-route.tool", context={        "app": "Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.",        "today": "Monday 2 November 2026",        "tools": "def find_invoice(client: str, month: str) -> dict:\n    \"\"\"Finds the studio's invoice for a client and month.\"\"\"\ndef send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict:\n    \"\"\"Emails an invoice to a recipient, with optional copies.\"\"\"\ndef create_invoice(client: str, items: list[dict]) -> dict:\n    \"\"\"Creates a new draft invoice.\"\"\"",        "conversation": [            {                "role": "user",                "content": "Send the October invoice for Orbit Print to accounts@orbitprint.example.",            },            {                "role": "assistant",                "content": "Done, INV-2026-0412 has been sent to accounts@orbitprint.example.",            },        ],    }, labels={        "find_invoice": "Finds the studio's invoice for a client and month.",        "send_invoice": "Emails an invoice to a recipient, with optional copies.",        "create_invoice": "Creates a new draft invoice.",        "none": "No tool is needed, or no tool on the menu can do what the user asks.",        "ask_user": "A tool fits, but a required detail is missing and the agent must ask the user.",    })     decision = decide("Perfect, thank you!")     print(decision.value, decision.confidence)
  • Draft a new invoice with its itemsanswer create_invoice · confidence 0.821

    Context

    app
    Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.
    today
    Monday 2 November 2026
    tools
    def find_invoice(client: str, month: str) -> dict: """Finds the studio's invoice for a client and month.""" def send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict: """Emails an invoice to a recipient, with optional copies.""" def create_invoice(client: str, items: list[dict]) -> dict: """Creates a new draft invoice."""
    conversation

    Input

    Make a new invoice for Harbour Lane Cafe for the menu design, 2 days at 450.00 a day.

    Labels (the options)

    find_invoice
    Finds the studio's invoice for a client and month.
    send_invoice
    Emails an invoice to a recipient, with optional copies.
    create_invoice
    Creates a new draft invoice.
    none
    No tool is needed, or no tool on the menu can do what the user asks.
    ask_user
    A tool fits, but a required detail is missing and the agent must ask the user.
    Answer (JSON)
    value create_invoice, confidence 0.821
    Top options
    1. create_invoice 0.821
    2. ask_user 0.168
    3. none 0.006

    The user gives the client, the work and the price for a new invoice, so the tool to call is create_invoice.

    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.agents.tool-route.tool", context={        "app": "Pinecrest Books, a bookkeeping assistant for a small design studio. It keeps the studio's invoices, clients and supplier bills, emails invoices and pays bills on request.",        "today": "Monday 2 November 2026",        "tools": "def find_invoice(client: str, month: str) -> dict:\n    \"\"\"Finds the studio's invoice for a client and month.\"\"\"\ndef send_invoice(invoice_id: str, to: str, cc: list[str] = []) -> dict:\n    \"\"\"Emails an invoice to a recipient, with optional copies.\"\"\"\ndef create_invoice(client: str, items: list[dict]) -> dict:\n    \"\"\"Creates a new draft invoice.\"\"\"",        "conversation": [],    }, labels={        "find_invoice": "Finds the studio's invoice for a client and month.",        "send_invoice": "Emails an invoice to a recipient, with optional copies.",        "create_invoice": "Creates a new draft invoice.",        "none": "No tool is needed, or no tool on the menu can do what the user asks.",        "ask_user": "A tool fits, but a required detail is missing and the agent must ask the user.",    })     decision = decide("Make a new invoice for Harbour Lane Cafe for the menu design, 2 days at 450.00 a day.")     print(decision.value, decision.confidence)

Use when

  • Your tool menu is supplied as text, function signatures or schemas in the request.
  • You need a tool-selection decision with a probability.

Avoid when

  • You need to generate tool arguments; this adapter selects a tool without constructing the call.

Context and input

FieldKindDescription
request
inputThe user's latest message.
app
contextThe application the agent works in: its name and a description of what it does and for whom.
today
contextToday's date, written out (for example 'Wednesday 23 June 2027').
tools
contextThe tool menu, in any common format (Python signatures, JSON schemas and so on).
conversation
contextThe conversation so far, a list of messages (user, assistant, tool calls and tool results).

Functions

KeyInterfaceInstructionsLabels
toolrouteWhat should the agent do next with the user's latest message? Choose the tool on the menu that should be called now when that tool can do what the user asks and the request and the conversation give every detail it requires (details the agent can take from earlier in the conversation count). Choose none when no tool is needed or none fits: the user is chatting or thanking, asks something the conversation already answers, or asks for something no tool on the menu can do. Choose ask_user when a tool fits but a required detail is missing and cannot be taken from the conversation, or when the request could mean two different records or actions and the agent must ask which. Read the tool names and descriptions carefully: similar tools do different things.from the caller

How it was measured

Test accuracy: the share of test rows whose top answer was right.

  • 71.6% on When2Call, a public function-calling benchmark (questions and tools from the Berkeley Function Calling Leaderboard) (3,646 rows). public benchmark
  • 98.2% on the in-house test (2,000 rows). in-house: same generator as the training data
  • 96.7% on a second in-house test of unseen cases (2,000 rows). in-house: same generator as the training data

When confident

From the calibration set: at or above the threshold confidence, how often the answer is right, and how often the adapter is that confident. Below it, escalate.

FunctionRight when confidentConfident onThresholdCalibration rows
tool98.5%100.0%0.412,000

Base: Jeff v1.4. Adapter trained: 25 October 2026.

Base

jeff-base v1.4

Call it

jeff.agents.tool-route.tool, with placeholders for its input and context.

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.agents.tool-route.tool", context={        "app": "<app>",        "today": "<today>",        "tools": "<tools>",        "conversation": "<conversation>",    })     decision = decide("<request>")     print(decision.value, decision.confidence)

Download

Weights: mstrasser/jeff-adapter-tool-route (v1.4)

Licence: Apache-2.0