AI: Get Fields
code
ai['result'] = record._ai_tool_get_fields(model_name, include_description)
Lists ONLY searchable fields for a single model that can be used in domain filters and grouping.
Essential for building valid domains - if a field isn't listed here, it CANNOT be used.
Returns format:
```
field_name|display_name|type|sortable|groupable|description
partner_id|Customer|many2one(res.partner)|true|true|Customer for this order
date_order|Order Date|datetime|true|true|Date when order was placed
order_line|Order Lines|one2many(sale.order.line)|false|false|Lines in this order
state|Status|selection|true|true|Order status
```
Key points:
- ⚠️ Only returns SEARCHABLE fields - others cannot be used in domains
- For relationships: Shows related model in parentheses (many2one, one2many, many2many)
- Only relationship fields can be used to traverse to other models
- Literal fields such as char/text/float CANNOT be used for traversal
- 'sortable' indicates if field can be used in order_by parameter
- 'groupable' indicates if field can be used for grouping when not available in search view
💡 Performance tip: When exploring multiple models, call this tool multiple times in ONE message
Example: Exploring sale.order, product.product, and res.partner? Make 3 parallel calls.
{
"type": "object",
"properties": {
"model_name": {
"type": "string",
"description": "Technical model name (e.g., 'sale.order', 'product.product', 'res.partner')"
},
"include_description": {
"type": "boolean",
"description": "Include field help text in output (default: true)"
}
},
"required": ["model_name"]
}
AI: Compute Report Measures
code
ai['result'] = record._ai_tool_compute_report_measures(action_id, model_name)
Lists numeric fields (measures) available for aggregation in pivot/graph views.
MUST be called before using measures in open_menu_pivot() or open_menu_graph().
Returns CSV with pipe (|) delimiter:
```
field_name|display_name|type|aggregator|sortable
__count|Count|integer||true
amount_total|Total|monetary|sum|true
margin|Margin|float|sum|true
quantity|Quantity|float|sum|true
```
Key points:
- __count is always available (counts records)
- Only numeric fields with aggregators are returned
- Use field_name in measures parameter
- For rankings in pivot: Add ordering (e.g., "amount_total desc")
- Call multiple times in parallel if comparing different menus
{
"type": "object",
"properties": {
"action_id": {
"type": "number",
"description": "Action ID - the id of the action linked to a menu or available in the current view context."
},
"model_name": {
"type": "string",
"description": "Model name - must match the action's model"
}
},
"required": ["action_id", "model_name"]
}
AI: Adjust Search
code
ai['result'] = record._ai_tool_adjust_search(model_name, remove_facets, toggle_filters, toggle_groupbys, apply_searches, measures, mode, order, stacked, cumulated, custom_domain, switch_view_type)
The user can continue on asking questions and if you think that the current search can just be adjusted without opening a different menu, you can use this tool.
Provided in the prompt's <session_info_context> is a current view info which contains the active search facets.
A facet can be a group of `OR`ed filters, a group of groupbys, or a group of `OR`ed search terms.
**Understanding the parameters**:
- `remove_facets` - Removing a facet removes the whole group of filters/groupbys/search terms. Removing a filter or a search facet reduces the constraints.
- `toggle_filters` - Toggling a filter will add/remove a filter from an active filter facet.
- `toggle_groupbys` - Toggling a groupby will add/remove a groupby from the active groupbys facet.
- `apply_searches` - Applying a search will `OR` the search term on an active search facet containing the same field. E.g., if there is a field facet of "name=John" and you provide search "name=Jane", the resulting search will be "name=John OR name=Jane".
- `measures` - Specifying measures will activate the selected measures in the current view if it's a pivot or a graph view.
- `mode` - Graph view only: This is the chart type. Choose from "line", "bar", or "pie" to change the chart type in the current graph view.
- `order` - Graph view only: Specifying the order will change the sorting of the results in the current graph view.
- `stacked` - Graph view only: Specifying stacked will change the stacking of the results in the current graph view.
- `cumulated` - Graph view only: Specifying cumulated will change the accumulation of the results in the current graph view.
- `custom_domain` - The search view elements may not be sufficient to express the needed domain. In that case, you can provide a custom domain as a JSON string.
- `switch_view_type` - Switching the view type will change the current view to the specified type. Select from the available view types in the current view info.
{
"type": "object",
"properties": {
"model_name": {
"type": "string",
"description": "The model linked to the current view."
},
"remove_facets": {
"type": "array",
"items": {"type": "number"},
"description": "List of facet group IDs to be removed from the search view."
},
"toggle_filters": {
"type": "array",
"items": {"type": "string"},
"description": "Filter names from menu's available filters. See list from the searchable fields from the search view. Example: ['my_sale_orders', 'draft']. If a filter is already applied, it will be removed; otherwise, it will be added. Empty array [] for no filters. "
},
"toggle_groupbys": {
"type": "array",
"items": {"type": "string"},
"description": "Field names to add/remove from grouping. Priority: 1) Use group_by_field values from search view, 2) If needed field not in search view, use groupable fields from get_fields tool. Example: ['user_id', 'partner_id']. Empty array [] for no grouping changes."
},
"apply_searches": {
"type": "array",
"items": {"type": "string"},
"description": "Array of field=text strings for searching multiple fields. Each string uses format 'field_name=search_text' where field_name is from menu's searchable_fields. Examples: ['partner_id=Azure', 'product_id=laptop'], ['name=SO-001'], or [] for no search."
},
"measures": {
"type": "array",
"items": {"type": "string"},
"description": "List of measures to be activated. Can be multiple items in pivot view but only one item in graph view."
},
"mode": {
"type": "string",
"description": "For graph view: Chart type: 'bar' for comparisons, 'line' for trends, 'pie' for proportions"
},
"order": {
"type": "string",
"description": "For graph view: Sort direction: 'DESC' for highest first, 'ASC' for lowest first"
},
"stacked": {
"type": "boolean",
"description": "For graph view: Stack bars/areas on top of each other (default: false)"
},
"cumulated": {
"type": "boolean",
"description": "For graph view: Show cumulative values over time (default: false)"
},
"custom_domain": {
"type": "string",
"description": "Optional custom domain as JSON string when search view elements are insufficient."
},
"switch_view_type": {
"type": "string",
"description": "The view type to switch to. Must be one of the available view types. Empty string for no switch."
},
"__end_message": {
"type": "string",
"description": "The message that will be shown to the user. Provide a short summary of what you wanted to adjust in the search view when calling this tool."
}
},
"required": ["model_name"]
}
AI: Search
code
ai['result'] = record._ai_tool_search(model_name, domain, fields, offset, limit, order)
Searches a particular model using a domain. The provided domain must be in valid JSON format.
{
"type": "object",
"properties": {
"model_name": {
"type": "string",
"description": "Technical model name (e.g., 'sale.order', 'product.product', 'res.partner')"
},
"domain": {
"type": "string",
"description": "A search domain. Use an empty list to match all records. The domain must be a JSON parsable string."
},
"fields": {
"type": "array",
"description": "a collection of field names to fetch, or None for all accessible fields marked with prefetch=True",
"items": {
"type": "string"
}
},
"offset": {
"type": "number",
"description": "number of results to ignore (default: none)"
},
"limit": {
"type": "number",
"description": "optional max number of records to return (default: all)"
},
"order": {
"type": "string",
"description": "Optional 'order by' specification. This field should have the form `field_name DESC` (or ASC for ascending order)"
}
},
"required": ["model_name", "domain"]
}
AI: Read group
code
ai['result'] = record._ai_tool_read_group(model_name, domain, groupby, aggregates, having, offset, limit, order)
Searches a particular model using a domain. The provided domain must be in valid JSON format.
{
"type": "object",
"properties": {
"model_name": {
"type": "string",
"description": "Technical model name (e.g., 'sale.order', 'product.product', 'res.partner')"
},
"domain": {
"type": "string",
"description": "A search domain. Use an empty list to match all records. The domain MUST be a valid JSON string."
},
"groupby": {
"type": "array",
"description": "list of groupby descriptions by which the records will be grouped. A groupby description is either a field (then it will be grouped by that field) or a string `'field:granularity'`. Right now, the only supported granularities are `'day'`, `'week'`, `'month'`, `'quarter'` or `'year'`, and they only make sense for date/datetime fields. Additionally integer date parts are also supported: `'year_number'`, `'quarter_number'`, `'month_number'`, `'iso_week_number'`, `'day_of_year'`, `'day_of_month'`, 'day_of_week', 'hour_number', 'minute_number' and 'second_number'.",
"items": {
"type": "string"
}
},
"aggregates": {
"type": "array",
"description": "list of aggregates specification. Each element is `'field:agg'` (aggregate field with aggregation function `'agg'`). The possible aggregation functions are the ones provided by `PostgreSQL`, `'count_distinct'` with the expected meaning and `'recordset'` to act like `'array_agg'` converted into a recordset.",
"items": {
"type": "string"
}
},
"having": {
"type": "string",
"description": "A domain where the valid 'fields' are the aggregates. The provided field names must exist in the aggregate elements. The having MUST be a valid JSON string. Example '[[\"amount_total:sum\", \">\", 1000]]"
},
"offset": {
"type": "number",
"description": "optional number of groups to skip"
},
"limit": {
"type": "number",
"description": "optional max number of groups to return"
},
"order": {
"type": "string",
"description": "optional 'order by' specification, for overriding the natural sort ordering of the groups. The order must be a valid PostgreSQL group by, it must use a valid `aggregate` or `groupby element. The provided fields must exist in the group by or aggregate elements."
}
},
"required": ["model_name", "domain"]
}