NAME

Langertha::ServerTool - Provider-native server-side tool definition, pinned to one wire format

VERSION

version 0.503

SYNOPSIS

use Langertha::ServerTool;

# Wrap a provider-native server tool for the Responses wire
my $search = Langertha::ServerTool->new(
    wire => 'responses',
    spec => { type => 'web_search' },
);

# Per request, mixed with function tools
my $response = await $engine->chat_f(
    messages => [ { role => 'user', content => 'Current Perl release?' } ],
    tools    => [ $search, $mcp_tool_hash ],
);

# Or once on the engine, for every request (Langertha::Role::ServerTools)
my $engine = Langertha::Engine::OpenAIResponses->new(
    model        => 'gpt-5.6-luna',
    server_tools => [ { type => 'web_search' } ],
);

# Recognise a hash without croaking; undef when it is no server tool
my $st = Langertha::ServerTool->from_hash( responses => $hash );

DESCRIPTION

A server-side tool is one the provider runs itself during a single request: web search, file search, a code interpreter, remote MCP. Its definition is a provider contract, not a portable function tool -- web_search on the Responses wire, web_search_20250305 on Anthropic and google_search on Gemini are three different things. So this value object does not translate: it carries the provider-native hash ("spec") verbatim, is keyed by the tool_wire_format it belongs to ("wire"), and "to" refuses every other wire. It is the server-side sibling of Langertha::Tool, which takes function tools only.

Which hashes count as server tools is decided by "classify" in Langertha::Tool, the one classifier. A type Langertha does not list yet can still be sent by vouching for it with unlisted => 1.

Supported wires: responses (OpenAI's /v1/responses). Anthropic and Gemini server tools are not supported yet; the constructor croaks for them.

Server-side calls the provider reports back land on "server_tool_calls" in Langertha::Response as Langertha::ServerToolCall, never on "tool_calls" in Langertha::Response: the client must not execute them. See ADR 0030.

wire

The tool_wire_format the tool belongs to (responses). Required.

spec

The provider-native tool hash, for example { type => 'mcp', server_label => 'docs', server_url => '...', require_approval => 'never' }. Required. A shallow copy is taken at construction; use "to" to read it.

unlisted

Set to 1 to send a type that Langertha's table does not list yet, when you know the provider runs it. Function, custom and namespace tools and known client-executed built-ins are refused even then.

type

The type of the native hash, for example web_search.

from_hash

my $st = Langertha::ServerTool->from_hash( $fmt, $hash );

Returns a Langertha::ServerTool when $hash is a known server tool of the wire $fmt, else undef. Never croaks and never sniffs: the wire is given, as for "extract" in Langertha::ToolCall. A Langertha::ServerTool is returned unchanged.

to

my $hash = $st->to('responses');

Returns a copy of the native hash for the wire the tool belongs to, and croaks for any other wire. A remote mcp tool on the responses wire also croaks unless it says require_approval => 'never': the provider default asks the client to approve each call, and Langertha has no approval flow. The check lives here so that every path -- an engine request and "format_list" in Langertha::Tool alike -- enforces it.

check_engine

Langertha::ServerTool->check_engine( $engine, \@tools );

Croaks when @tools holds a Langertha::ServerTool and $engine does not supports('server_tools'), so the tool never reaches a wire that cannot take it. "chat_f" in Langertha::Role::Chat calls it before building a request. Plain hashes are left alone: a provider-shaped hash still goes out as the engine sends it today.

to_hash

Returns { wire, spec } (plus unlisted when set).

TO_JSON

Delegates to "to_hash", for JSON encoders with convert_blessed.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.