Skip to main content

zeph_bench/loaders/tau2_bench/envs/
tools.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Tool definitions for tau2-bench retail and airline domains.
5//!
6//! Each domain exposes a set of structured tools the agent can invoke.
7//! Definitions follow the schemars 1.x pattern used by `zeph-tools`.
8
9// Param structs exist solely for schemars schema derivation; their fields are
10// intentionally not read by Rust code — they are read by the LLM via JSON schema.
11#![allow(dead_code)]
12
13use schemars::JsonSchema;
14use serde::{Deserialize, Serialize};
15use zeph_tools::registry::{InvocationHint, ToolDef};
16
17// ─── Airline nested types ────────────────────────────────────────────────────
18
19/// A single flight leg in a reservation (flight number + departure date).
20#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
21pub struct FlightSegment {
22    /// IATA or internal flight number (e.g. `"AA123"`).
23    pub flight_number: String,
24    /// Departure date in `YYYY-MM-DD` format.
25    pub date: String,
26}
27
28/// Passenger identity data required when booking or updating a reservation.
29#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
30pub struct Passenger {
31    /// Passenger's given name.
32    pub first_name: String,
33    /// Passenger's family name.
34    pub last_name: String,
35    /// Date of birth in `YYYY-MM-DD` format.
36    pub dob: String,
37}
38
39// ─── Retail shared params ────────────────────────────────────────────────────
40
41#[derive(Debug, Deserialize, JsonSchema)]
42pub(super) struct CalculateParams {
43    /// Mathematical expression to evaluate (e.g. `"1 + 2 * 3"`).
44    pub expression: String,
45}
46
47#[derive(Debug, Deserialize, JsonSchema)]
48pub(super) struct CancelPendingOrderParams {
49    /// Order id (e.g. `"#W1234567"`).
50    pub order_id: String,
51    /// Reason for cancellation: one of `no_longer_needed`, `ordered_by_mistake`.
52    pub reason: String,
53}
54
55#[derive(Debug, Deserialize, JsonSchema)]
56pub(super) struct ExchangeDeliveredOrderItemsParams {
57    /// Order id (e.g. `"#W1234567"`).
58    pub order_id: String,
59    /// List of item ids to exchange.
60    pub item_ids: Vec<String>,
61    /// New item ids to exchange into.
62    pub new_item_ids: Vec<String>,
63    /// Payment method id to charge any delta.
64    pub payment_method_id: String,
65}
66
67#[derive(Debug, Deserialize, JsonSchema)]
68pub(super) struct FindUserIdByEmailParams {
69    /// User's email address.
70    pub email: String,
71}
72
73#[derive(Debug, Deserialize, JsonSchema)]
74pub(super) struct FindUserIdByNameZipParams {
75    /// User's first name.
76    pub first_name: String,
77    /// User's last name.
78    pub last_name: String,
79    /// User's ZIP code.
80    pub zip: String,
81}
82
83#[derive(Debug, Deserialize, JsonSchema)]
84pub(super) struct GetOrderDetailsParams {
85    /// Order id (e.g. `"#W1234567"`).
86    pub order_id: String,
87}
88
89#[derive(Debug, Deserialize, JsonSchema)]
90pub(super) struct GetProductDetailsParams {
91    /// Product id.
92    pub product_id: String,
93}
94
95#[derive(Debug, Deserialize, JsonSchema)]
96pub(super) struct GetItemDetailsParams {
97    /// Item id (variant id).
98    pub item_id: String,
99}
100
101#[derive(Debug, Deserialize, JsonSchema)]
102pub(super) struct GetUserDetailsParams {
103    /// User id.
104    pub user_id: String,
105}
106
107#[derive(Debug, Deserialize, JsonSchema)]
108pub(super) struct ModifyPendingOrderAddressParams {
109    /// Order id.
110    pub order_id: String,
111    /// New address line 1.
112    pub address1: String,
113    /// New address line 2.
114    pub address2: String,
115    /// City.
116    pub city: String,
117    /// State.
118    pub state: String,
119    /// ZIP code.
120    pub zip: String,
121    /// Country.
122    pub country: String,
123}
124
125#[derive(Debug, Deserialize, JsonSchema)]
126pub(super) struct ModifyPendingOrderItemsParams {
127    /// Order id.
128    pub order_id: String,
129    /// Item ids to remove.
130    pub item_ids: Vec<String>,
131    /// New item ids to add.
132    pub new_item_ids: Vec<String>,
133    /// Payment method id to charge any delta.
134    pub payment_method_id: String,
135}
136
137#[derive(Debug, Deserialize, JsonSchema)]
138pub(super) struct ModifyPendingOrderPaymentParams {
139    /// Order id.
140    pub order_id: String,
141    /// New payment method id.
142    pub payment_method_id: String,
143}
144
145#[derive(Debug, Deserialize, JsonSchema)]
146pub(super) struct ModifyUserAddressParams {
147    /// User id.
148    pub user_id: String,
149    /// New address line 1.
150    pub address1: String,
151    /// New address line 2.
152    pub address2: String,
153    /// City.
154    pub city: String,
155    /// State.
156    pub state: String,
157    /// ZIP code.
158    pub zip: String,
159    /// Country.
160    pub country: String,
161}
162
163#[derive(Debug, Deserialize, JsonSchema)]
164pub(super) struct ReturnDeliveredOrderItemsParams {
165    /// Order id.
166    pub order_id: String,
167    /// List of item ids to return.
168    pub item_ids: Vec<String>,
169    /// Payment method id for refund.
170    pub payment_method_id: String,
171}
172
173#[derive(Debug, Deserialize, JsonSchema)]
174pub(super) struct TransferToHumanAgentsParams {
175    /// Reason for transfer.
176    pub summary: String,
177}
178
179/// Empty-object schema for tools that take no parameters.
180///
181/// LLM providers require `type: "object"` even for no-arg tools; `schemars::schema_for!(())`
182/// produces `type: "null"` which most providers reject.
183fn empty_object_schema() -> schemars::Schema {
184    serde_json::from_value(serde_json::json!({"type": "object", "properties": {}}))
185        .expect("static schema is valid")
186}
187
188/// Return all tool definitions for the retail domain.
189#[must_use]
190#[allow(clippy::too_many_lines)]
191pub fn retail_definitions() -> Vec<ToolDef> {
192    vec![
193        ToolDef {
194            id: "calculate".into(),
195            description: "Calculate the result of a mathematical expression.".into(),
196            schema: schemars::schema_for!(CalculateParams),
197            invocation: InvocationHint::ToolCall,
198            output_schema: None,
199            server_id: None,
200        },
201        ToolDef {
202            id: "cancel_pending_order".into(),
203            description: "Cancel a pending order. Returns updated order details.".into(),
204            schema: schemars::schema_for!(CancelPendingOrderParams),
205            invocation: InvocationHint::ToolCall,
206            output_schema: None,
207            server_id: None,
208        },
209        ToolDef {
210            id: "exchange_delivered_order_items".into(),
211            description: "Exchange items in a delivered order.".into(),
212            schema: schemars::schema_for!(ExchangeDeliveredOrderItemsParams),
213            invocation: InvocationHint::ToolCall,
214            output_schema: None,
215            server_id: None,
216        },
217        ToolDef {
218            id: "find_user_id_by_email".into(),
219            description: "Look up a user ID by email address.".into(),
220            schema: schemars::schema_for!(FindUserIdByEmailParams),
221            invocation: InvocationHint::ToolCall,
222            output_schema: None,
223            server_id: None,
224        },
225        ToolDef {
226            id: "find_user_id_by_name_zip".into(),
227            description: "Look up a user ID by first name, last name, and ZIP code.".into(),
228            schema: schemars::schema_for!(FindUserIdByNameZipParams),
229            invocation: InvocationHint::ToolCall,
230            output_schema: None,
231            server_id: None,
232        },
233        ToolDef {
234            id: "get_order_details".into(),
235            description: "Get details of an order by order ID.".into(),
236            schema: schemars::schema_for!(GetOrderDetailsParams),
237            invocation: InvocationHint::ToolCall,
238            output_schema: None,
239            server_id: None,
240        },
241        ToolDef {
242            id: "get_product_details".into(),
243            description: "Get all variants and pricing for a product.".into(),
244            schema: schemars::schema_for!(GetProductDetailsParams),
245            invocation: InvocationHint::ToolCall,
246            output_schema: None,
247            server_id: None,
248        },
249        ToolDef {
250            id: "get_item_details".into(),
251            description: "Get details of a specific item variant.".into(),
252            schema: schemars::schema_for!(GetItemDetailsParams),
253            invocation: InvocationHint::ToolCall,
254            output_schema: None,
255            server_id: None,
256        },
257        ToolDef {
258            id: "get_user_details".into(),
259            description: "Get details of a user by user ID.".into(),
260            schema: schemars::schema_for!(GetUserDetailsParams),
261            invocation: InvocationHint::ToolCall,
262            output_schema: None,
263            server_id: None,
264        },
265        ToolDef {
266            id: "list_all_product_types".into(),
267            description: "List all available product type names.".into(),
268            schema: empty_object_schema(),
269            invocation: InvocationHint::ToolCall,
270            output_schema: None,
271            server_id: None,
272        },
273        ToolDef {
274            id: "modify_pending_order_address".into(),
275            description: "Modify the shipping address of a pending order.".into(),
276            schema: schemars::schema_for!(ModifyPendingOrderAddressParams),
277            invocation: InvocationHint::ToolCall,
278            output_schema: None,
279            server_id: None,
280        },
281        ToolDef {
282            id: "modify_pending_order_items".into(),
283            description: "Modify items in a pending order.".into(),
284            schema: schemars::schema_for!(ModifyPendingOrderItemsParams),
285            invocation: InvocationHint::ToolCall,
286            output_schema: None,
287            server_id: None,
288        },
289        ToolDef {
290            id: "modify_pending_order_payment".into(),
291            description: "Change the payment method for a pending order.".into(),
292            schema: schemars::schema_for!(ModifyPendingOrderPaymentParams),
293            invocation: InvocationHint::ToolCall,
294            output_schema: None,
295            server_id: None,
296        },
297        ToolDef {
298            id: "modify_user_address".into(),
299            description: "Update the address on file for a user.".into(),
300            schema: schemars::schema_for!(ModifyUserAddressParams),
301            invocation: InvocationHint::ToolCall,
302            output_schema: None,
303            server_id: None,
304        },
305        ToolDef {
306            id: "return_delivered_order_items".into(),
307            description: "Return items from a delivered order and issue a refund.".into(),
308            schema: schemars::schema_for!(ReturnDeliveredOrderItemsParams),
309            invocation: InvocationHint::ToolCall,
310            output_schema: None,
311            server_id: None,
312        },
313        ToolDef {
314            id: "transfer_to_human_agents".into(),
315            description: "Escalate the conversation to a human agent.".into(),
316            schema: schemars::schema_for!(TransferToHumanAgentsParams),
317            invocation: InvocationHint::ToolCall,
318            output_schema: None,
319            server_id: None,
320        },
321    ]
322}
323
324// ─── Airline params ──────────────────────────────────────────────────────────
325
326#[derive(Debug, Deserialize, JsonSchema)]
327pub(super) struct BookReservationParams {
328    /// User id of the passenger.
329    pub user_id: String,
330    /// Origin airport code.
331    pub origin: String,
332    /// Destination airport code.
333    pub destination: String,
334    /// Flight type: `one_way` or `round_trip`.
335    pub flight_type: String,
336    /// Cabin class: `basic_economy`, `economy`, `business`.
337    pub cabin: String,
338    /// List of flights to include.
339    pub flights: Vec<FlightSegment>,
340    /// List of passengers.
341    pub passengers: Vec<Passenger>,
342    /// Payment method id.
343    pub payment_method_id: String,
344    /// Total number of checked bags.
345    pub total_baggages: u32,
346    /// Number of non-free (charged) bags.
347    pub nonfree_baggages: u32,
348    /// Whether travel insurance is included: `yes` or `no`.
349    pub insurance: String,
350}
351
352#[derive(Debug, Deserialize, JsonSchema)]
353pub(super) struct CancelReservationParams {
354    /// Reservation id.
355    pub reservation_id: String,
356}
357
358#[derive(Debug, Deserialize, JsonSchema)]
359pub(super) struct GetReservationDetailsParams {
360    /// Reservation id.
361    pub reservation_id: String,
362}
363
364#[derive(Debug, Deserialize, JsonSchema)]
365pub(super) struct GetAirlineUserDetailsParams {
366    /// User id.
367    pub user_id: String,
368}
369
370#[derive(Debug, Deserialize, JsonSchema)]
371pub(super) struct SearchDirectFlightParams {
372    /// Origin airport code.
373    pub origin: String,
374    /// Destination airport code.
375    pub destination: String,
376    /// Departure date (YYYY-MM-DD).
377    pub date: String,
378}
379
380#[derive(Debug, Deserialize, JsonSchema)]
381pub(super) struct SearchOnestopFlightParams {
382    /// Origin airport code.
383    pub origin: String,
384    /// Destination airport code.
385    pub destination: String,
386    /// Departure date (YYYY-MM-DD).
387    pub date: String,
388}
389
390#[derive(Debug, Deserialize, JsonSchema)]
391pub(super) struct SendCertificateParams {
392    /// User id to send the certificate to.
393    pub user_id: String,
394    /// Dollar amount of the certificate.
395    pub amount: f64,
396}
397
398#[derive(Debug, Deserialize, JsonSchema)]
399pub(super) struct UpdateReservationBaggagesParams {
400    /// Reservation id.
401    pub reservation_id: String,
402    /// New total number of bags.
403    pub total_baggages: u32,
404    /// New number of non-free bags.
405    pub nonfree_baggages: u32,
406    /// Payment method id to charge extra bag fees.
407    pub payment_method_id: String,
408}
409
410#[derive(Debug, Deserialize, JsonSchema)]
411pub(super) struct UpdateReservationFlightsParams {
412    /// Reservation id.
413    pub reservation_id: String,
414    /// Cabin class for the updated flights.
415    pub cabin: String,
416    /// New list of flights.
417    pub flights: Vec<FlightSegment>,
418    /// Payment method id.
419    pub payment_method_id: String,
420}
421
422#[derive(Debug, Deserialize, JsonSchema)]
423pub(super) struct UpdateReservationPassengersParams {
424    /// Reservation id.
425    pub reservation_id: String,
426    /// Updated passenger list.
427    pub passengers: Vec<Passenger>,
428}
429
430#[derive(Debug, Deserialize, JsonSchema)]
431pub(super) struct GetFlightStatusParams {
432    /// Flight number.
433    pub flight_number: String,
434    /// Flight date (YYYY-MM-DD).
435    pub date: String,
436}
437
438/// Return all tool definitions for the airline domain.
439#[must_use]
440#[allow(clippy::too_many_lines)]
441pub fn airline_definitions() -> Vec<ToolDef> {
442    vec![
443        ToolDef {
444            id: "book_reservation".into(),
445            description: "Book a new flight reservation for a user.".into(),
446            schema: schemars::schema_for!(BookReservationParams),
447            invocation: InvocationHint::ToolCall,
448            output_schema: None,
449            server_id: None,
450        },
451        ToolDef {
452            id: "calculate".into(),
453            description: "Calculate the result of a mathematical expression.".into(),
454            schema: schemars::schema_for!(CalculateParams),
455            invocation: InvocationHint::ToolCall,
456            output_schema: None,
457            server_id: None,
458        },
459        ToolDef {
460            id: "cancel_reservation".into(),
461            description: "Cancel an existing flight reservation and process refund.".into(),
462            schema: schemars::schema_for!(CancelReservationParams),
463            invocation: InvocationHint::ToolCall,
464            output_schema: None,
465            server_id: None,
466        },
467        ToolDef {
468            id: "get_reservation_details".into(),
469            description: "Get details of a reservation by reservation ID.".into(),
470            schema: schemars::schema_for!(GetReservationDetailsParams),
471            invocation: InvocationHint::ToolCall,
472            output_schema: None,
473            server_id: None,
474        },
475        ToolDef {
476            id: "get_user_details".into(),
477            description: "Get details of a user by user ID.".into(),
478            schema: schemars::schema_for!(GetAirlineUserDetailsParams),
479            invocation: InvocationHint::ToolCall,
480            output_schema: None,
481            server_id: None,
482        },
483        ToolDef {
484            id: "list_all_airports".into(),
485            description: "List all airports with their city, country, and code.".into(),
486            schema: empty_object_schema(),
487            invocation: InvocationHint::ToolCall,
488            output_schema: None,
489            server_id: None,
490        },
491        ToolDef {
492            id: "search_direct_flight".into(),
493            description: "Search for direct flights between two airports on a given date.".into(),
494            schema: schemars::schema_for!(SearchDirectFlightParams),
495            invocation: InvocationHint::ToolCall,
496            output_schema: None,
497            server_id: None,
498        },
499        ToolDef {
500            id: "search_onestop_flight".into(),
501            description: "Search for one-stop flights between two airports on a given date.".into(),
502            schema: schemars::schema_for!(SearchOnestopFlightParams),
503            invocation: InvocationHint::ToolCall,
504            output_schema: None,
505            server_id: None,
506        },
507        ToolDef {
508            id: "send_certificate".into(),
509            description: "Send a travel certificate to a user as compensation.".into(),
510            schema: schemars::schema_for!(SendCertificateParams),
511            invocation: InvocationHint::ToolCall,
512            output_schema: None,
513            server_id: None,
514        },
515        ToolDef {
516            id: "transfer_to_human_agents".into(),
517            description: "Escalate the conversation to a human agent.".into(),
518            schema: schemars::schema_for!(TransferToHumanAgentsParams),
519            invocation: InvocationHint::ToolCall,
520            output_schema: None,
521            server_id: None,
522        },
523        ToolDef {
524            id: "update_reservation_baggages".into(),
525            description: "Update the baggage allowance on a reservation.".into(),
526            schema: schemars::schema_for!(UpdateReservationBaggagesParams),
527            invocation: InvocationHint::ToolCall,
528            output_schema: None,
529            server_id: None,
530        },
531        ToolDef {
532            id: "update_reservation_flights".into(),
533            description: "Change the flights on an existing reservation.".into(),
534            schema: schemars::schema_for!(UpdateReservationFlightsParams),
535            invocation: InvocationHint::ToolCall,
536            output_schema: None,
537            server_id: None,
538        },
539        ToolDef {
540            id: "update_reservation_passengers".into(),
541            description: "Update passenger information on a reservation.".into(),
542            schema: schemars::schema_for!(UpdateReservationPassengersParams),
543            invocation: InvocationHint::ToolCall,
544            output_schema: None,
545            server_id: None,
546        },
547        ToolDef {
548            id: "get_flight_status".into(),
549            description: "Get the status of a flight by flight number and date.".into(),
550            schema: schemars::schema_for!(GetFlightStatusParams),
551            invocation: InvocationHint::ToolCall,
552            output_schema: None,
553            server_id: None,
554        },
555    ]
556}