NAME
Langertha::Tool - Immutable canonical tool definition with cross-provider format conversion
VERSION
version 0.503
classify
my $category = Langertha::Tool->classify( $tool_hash );
my $category = Langertha::Tool->classify( $tool_hash, 'responses' );
my ( $category, $wire, $label ) = Langertha::Tool->classify( $tool_hash );
Says what kind of tool definition $tool_hash is, without croaking. Use it where a tool list comes from someone else, such as a gateway that must answer a bad client request with a 400 instead of dying: from_hash, from_list and format_list croak on every category except function, and they take that decision from this method.
The category is one of:
function-
A function tool
from_hashtranslates: aLangertha::Tool, a hash withouttypethat has aname(canonical, MCP, Gemini declaration, Anthropic client tool),type => 'function'(OpenAI, nested or flat), ortype => 'custom'with aninput_schema(Anthropic's explicit client tool). server-
A known provider built-in that the provider runs, for example
web_search(Responses),web_search_20250305(Anthropic) or{ google_search => {} }(Gemini). Server-side tools of theresponseswire are carried by Langertha::ServerTool; those of the Anthropic and Gemini wires are not supported yet. client_builtin-
A known provider built-in that the client has to run and Langertha cannot, for example
local_shell,computer_use_preview,apply_patch, ashellwith a local environment, atool_searchwithexecution => 'client'(Responses),bash_20250124(Anthropic) orcomputer_use(Gemini). foreign-
Only with
$fmt: aserverorclient_builtintool whose own wire is not$fmt-- that is, for any$fmtother than the built-in's own wire (responses,anthropicorgemini), includingopenai,ollamaorhermes, which have no built-ins of their own. A$fmtoutside the knowntool_wire_formatvalues carps once per value.foreignhides whether the tool is server-side or client-executed; to learn that, callclassifyagain without$fmt. unknown-
Anything else: a
typeLangertha does not recognise (including OpenAI'scustomwithoutinput_schemaandnamespace), a hash with neithertypenorname(such as{ functionDeclarations => [...] }), or not a hash at all. A wire that takes native items verbatim (the Responses envelope) passes a typedunknownthrough to the provider.
$fmt is a tool_wire_format (responses, anthropic, gemini, ...). In list context the method also returns the wire the built-in belongs to (undef for function and unknown) and a label: the type, the Gemini key, or, for an untyped unknown, its keys. The per-wire lists are taken from the provider documentation and are not verified against live responses.
request_list
my $wire_tools = Langertha::Tool->request_list( $engine->tool_wire_format, \@tools );
Shapes a caller's tools list for one request on the wire $fmt (openai, anthropic, gemini or ollama); the Responses envelope and the hermes wire shape their own. "chat_f" in Langertha::Role::Chat and "chat_stream_realtime_f" in Langertha::Role::Chat call it. Each item is decided on its own and keeps its place:
a
Langertha::Toolor Langertha::ServerTool goes through itsto($fmt)(a server tool croaks off its own wire);a function-tool hash already in the wire's shape goes out verbatim, extras such as
function.strictandcache_controlincluded;a function-tool hash in another shape (MCP
inputSchema, canonicalinput_schema, another dialect's shape) is converted through "from_hash", keepingstrict(OpenAI and Anthropic) andcache_control(Anthropic);anything else -- a provider built-in, a typed item Langertha does not know, a Gemini
{ functionDeclarations => [...] }entry -- goes out verbatim, for the provider to judge.
On gemini every function declaration ends up in one functionDeclarations entry, where the first declaration came from; a later raw functionDeclarations or function_declarations entry is merged into it and keeps its other fields. The merged entry is spelled functionDeclarations.
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.