Langertha

 view release on metacpan or  search on metacpan

t/60_tool_calling.t  view on Meta::CPAN

#!/usr/bin/env perl
# ABSTRACT: Test MCP tool calling support for Anthropic engine

use strict;
use warnings;

use Test2::Bundle::More;
use JSON::MaybeXS;

use Langertha::Engine::Anthropic;

my $json = JSON::MaybeXS->new->canonical(1)->utf8(1);

my $anthropic = Langertha::Engine::Anthropic->new(
  api_key => 'test-key',
  model => 'claude-sonnet-4-6',
  system_prompt => 'You are a helpful assistant',
  response_size => 1024,
);

# Test: mcp_servers defaults to empty
is_deeply($anthropic->mcp_servers, [], 'mcp_servers defaults to empty');
is($anthropic->tool_max_iterations, 10, 'tool_max_iterations defaults to 10');

# Test: format_tools converts MCP format to Anthropic format
{
  my $mcp_tools = [
    {
      name => 'echo',
      description => 'Echo the input text',
      inputSchema => {
        type => 'object',
        properties => { message => { type => 'string' } },
        required => ['message'],
      },
    },
    {
      name => 'add',
      description => 'Add two numbers',
      inputSchema => {
        type => 'object',
        properties => {
          a => { type => 'number' },
          b => { type => 'number' },
        },
        required => ['a', 'b'],
      },
    },
  ];

  my $formatted = $anthropic->format_tools($mcp_tools);
  is(scalar @$formatted, 2, 'two tools formatted');

  is($formatted->[0]{name}, 'echo', 'first tool name');
  is($formatted->[0]{description}, 'Echo the input text', 'first tool description');
  ok($formatted->[0]{input_schema}, 'input_schema present (snake_case)');
  ok(!exists $formatted->[0]{inputSchema}, 'inputSchema removed (camelCase)');
  is($formatted->[0]{input_schema}{type}, 'object', 'schema type preserved');
  is_deeply($formatted->[0]{input_schema}{required}, ['message'], 'schema required preserved');

  is($formatted->[1]{name}, 'add', 'second tool name');
}

# Test: chat_request includes tools in body
{
  my $tools = [
    { name => 'echo', description => 'Echo', input_schema => { type => 'object' } },
  ];

  my $request = $anthropic->chat_request(
    [{ role => 'user', content => 'Use the echo tool' }],
    tools => $tools,
  );

  is($request->method, 'POST', 'POST method');
  is($request->uri, 'https://api.anthropic.com/v1/messages', 'correct URI');

  my $body = $json->decode($request->content);
  ok($body->{tools}, 'tools field present in request body');
  is(scalar @{$body->{tools}}, 1, 'one tool in body');
  is($body->{tools}[0]{name}, 'echo', 'tool name in body');
  is($body->{model}, 'claude-sonnet-4-6', 'model in body');
  is($body->{max_tokens}, 1024, 'max_tokens in body');



( run in 0.408 second using v1.01-cache-2.11-cpan-71847e10f99 )