Langertha
view release on metacpan or search on metacpan
t/65_tool_calling_vllm.t view on Meta::CPAN
#!/usr/bin/env perl
# ABSTRACT: Test MCP tool calling support for vLLM engine
use strict;
use warnings;
use Test2::Bundle::More;
use JSON::MaybeXS;
use Langertha::Engine::vLLM;
# Test: url is required
eval { Langertha::Engine::vLLM->new(model => 'test-model') };
like($@, qr/url/, 'url is required');
# Test: model defaults to 'default' (single-model server)
{
my $vllm_no_model = Langertha::Engine::vLLM->new(url => 'http://test.invalid:8000');
is($vllm_no_model->model, 'default', 'model defaults to default');
}
my $vllm = Langertha::Engine::vLLM->new(
url => 'http://test.invalid:8000',
model => 'Qwen/Qwen2.5-3B-Instruct',
);
# Test: api_key is undef (no auth needed for local server)
is($vllm->api_key, undef, 'api_key defaults to undef');
# Test: composes OpenAICompatible
ok($vllm->does('Langertha::Role::OpenAICompatible'), 'vLLM composes OpenAICompatible');
# Test: tool calling methods available
ok($vllm->can('format_tools'), 'has format_tools');
ok($vllm->can('response_tool_calls'), 'has response_tool_calls');
ok($vllm->can('extract_tool_call'), 'has extract_tool_call');
ok($vllm->can('format_tool_results'), 'has format_tool_results');
ok($vllm->can('response_text_content'), 'has response_text_content');
ok($vllm->can('chat_with_tools_f'), 'has chat_with_tools_f');
is_deeply($vllm->mcp_servers, [], 'mcp_servers defaults to empty');
is($vllm->tool_max_iterations, 10, 'tool_max_iterations defaults to 10');
# Test: format_tools (same as OpenAI)
{
my $mcp_tools = [
{
name => 'add',
description => 'Add two numbers',
inputSchema => {
type => 'object',
properties => {
a => { type => 'number' },
b => { type => 'number' },
},
required => ['a', 'b'],
},
},
];
my $formatted = $vllm->format_tools($mcp_tools);
is(scalar @$formatted, 1, 'one tool formatted');
is($formatted->[0]{type}, 'function', 'tool type is function');
is($formatted->[0]{function}{name}, 'add', 'function name');
is($formatted->[0]{function}{parameters}{type}, 'object', 'parameters type');
}
# Test: response_tool_calls (OpenAI format)
{
my $data = {
choices => [{
message => {
role => 'assistant',
content => undef,
tool_calls => [
{
id => 'call_123',
type => 'function',
function => {
name => 'add',
arguments => '{"a":7,"b":15}',
},
},
],
},
finish_reason => 'tool_calls',
}],
};
my $calls = $vllm->response_tool_calls($data);
is(scalar @$calls, 1, 'one tool call extracted');
is($calls->[0]{function}{name}, 'add', 'tool call name');
}
# Test: extract_tool_call (OpenAI format - JSON string arguments)
{
my $tc = {
id => 'call_123',
type => 'function',
function => {
name => 'add',
arguments => '{"a":7,"b":15}',
( run in 0.799 second using v1.01-cache-2.11-cpan-71847e10f99 )