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_hash translates: a Langertha::Tool, a hash without type that has a name (canonical, MCP, Gemini declaration, Anthropic client tool), type => 'function' (OpenAI, nested or flat), or type => 'custom' with an input_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 the responses wire 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, a shell with a local environment, a tool_search with execution => 'client' (Responses), bash_20250124 (Anthropic) or computer_use (Gemini).

foreign

Only with $fmt: a server or client_builtin tool whose own wire is not $fmt -- that is, for any $fmt other than the built-in's own wire (responses, anthropic or gemini), including openai, ollama or hermes, which have no built-ins of their own. A $fmt outside the known tool_wire_format values carps once per value. foreign hides whether the tool is server-side or client-executed; to learn that, call classify again without $fmt.

unknown

Anything else: a type Langertha does not recognise (including OpenAI's custom without input_schema and namespace), a hash with neither type nor name (such as { functionDeclarations => [...] }), or not a hash at all. A wire that takes native items verbatim (the Responses envelope) passes a typed unknown through 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::Tool or Langertha::ServerTool goes through its to($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.strict and cache_control included;

  • a function-tool hash in another shape (MCP inputSchema, canonical input_schema, another dialect's shape) is converted through "from_hash", keeping strict (OpenAI and Anthropic) and cache_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.