New — Sohay now answers WooCommerce product, policy & cart questions. See how →

Adding your own chat tool

Register a callback the chatbot can invoke, and the things that decide whether it ever gets called.

Giving the chatbot a new capability means registering a tool: a description the model reads, a schema for its input, and a callback that does the work.

The shape

add_action( 'sohaychat_abilities_api_init', function () {
    sohaychat_register_ability(
        'acme/check-order-status',
        array(
            'label'               => 'Check order status',
            'description'         => 'Look up the delivery status of an order by its number.',
            'category'            => 'acme',
            'input_schema'        => array(
                'type'                 => 'object',
                'properties'           => array(
                    'order_number' => array(
                        'type'        => 'string',
                        'description' => 'The order number, as printed on the confirmation email.',
                    ),
                ),
                'required'             => array( 'order_number' ),
                'additionalProperties' => false,
            ),
            'permission_callback' => function () {
                return is_user_logged_in();
            },
            'execute_callback'    => function ( $input ) {
                return array( 'status' => acme_lookup( $input['order_number'] ) );
            },
        )
    );
} );

The description is the interface

The model chooses tools by reading their descriptions. That makes the description the most important line you write — more than the schema, more than the code.

Describe when to use it, not what it does internally. “Look up the delivery status of an order by its number” gets called at the right moment; “Order lookup” does not.

The same goes for each property’s description. A model that knows an order number is on the confirmation email can ask the visitor for it properly.

Take no input? Omit properties entirely

A tool with no input should declare:

'input_schema' => array(
    'type'                 => 'object',
    'additionalProperties' => false,
),

Do not pass an empty object as properties. WordPress’s schema validator iterates it as an array and fatals on an object. Leaving the key out is both correct and sufficient to reject unexpected input.

What the callback should return

An array, which is serialised for the model. Keep it small and flat — every field costs tokens on every call, and a field the model does not need is a field it can misread.

Return only what answers the question. A full record where a status string would do makes replies worse, not better.

Two things that decide whether it is ever called

The permission callback runs before execution, but the tool is still described to the model. If a capability should not even be advertised, remove it from sohaychat_tools instead — see The tools registry for the distinction.

Names are constrained by the providers. Stick to letters, numbers, underscores and hyphens, plus one slash as a namespace separator. The slash is rewritten before the model sees it.

Testing it

Ask the chatbot something that should trigger it, then check Sohay → Diagnostics and the tool activity log to see whether it was actually called.

A tool that never fires is almost always a description problem, not a registration one. Rewrite the description as the sentence a visitor would say, and try again.

Where to go next

The tools registry for the surrounding hooks.

Mithun B.
Mithun B.

More articles by Mithun B..

View all posts

Give your website an assistant that answers from your content

Grounded answers, a team inbox, and store-aware tools — free on WordPress.org.

Add Sohay — Free

Free plugin · You bring your OpenAI key · Works with any theme