157 lines
5.2 KiB
PHP
157 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ContextPaging\Tests;
|
|
|
|
use ContextPaging\OpenAICompatibleClient;
|
|
use ContextPaging\ToolCallMode;
|
|
use ContextPaging\ToolFormatter;
|
|
use ContextPaging\ToolCallParser;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Tests for OpenAICompatibleClient using a real SmolLM3 endpoint.
|
|
*/
|
|
class OpenAICompatibleClientTest extends TestCase
|
|
{
|
|
private OpenAICompatibleClient $client;
|
|
private string $model = 'HuggingFaceTB/SmolLM3-3B';
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->client = new OpenAICompatibleClient(
|
|
baseUrl: 'http://95.179.247.150/v1',
|
|
apiKey: null,
|
|
timeout: 120,
|
|
verifySsl: false
|
|
);
|
|
}
|
|
|
|
public function testBasicChatCompletion(): void
|
|
{
|
|
$messages = [
|
|
['role' => 'user', 'content' => 'Say "test successful" exactly.'],
|
|
];
|
|
|
|
$response = $this->client->chat($messages, ['model' => $this->model, 'max_tokens' => 20]);
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
|
|
$body = json_decode($response->getBody()->getContents(), true);
|
|
|
|
$this->assertArrayHasKey('choices', $body);
|
|
$this->assertCount(1, $body['choices']);
|
|
$this->assertArrayHasKey('message', $body['choices'][0]);
|
|
$this->assertEquals('assistant', $body['choices'][0]['message']['role']);
|
|
$this->assertNotEmpty($body['choices'][0]['message']['content']);
|
|
}
|
|
|
|
public function testUsageStatsReturned(): void
|
|
{
|
|
$messages = [
|
|
['role' => 'user', 'content' => 'Hello'],
|
|
];
|
|
|
|
$response = $this->client->chat($messages, ['model' => $this->model, 'max_tokens' => 20]);
|
|
$body = json_decode($response->getBody()->getContents(), true);
|
|
|
|
$this->assertArrayHasKey('usage', $body);
|
|
$this->assertArrayHasKey('prompt_tokens', $body['usage']);
|
|
$this->assertArrayHasKey('completion_tokens', $body['usage']);
|
|
$this->assertArrayHasKey('total_tokens', $body['usage']);
|
|
|
|
$this->assertGreaterThan(0, $body['usage']['prompt_tokens']);
|
|
$this->assertGreaterThan(0, $body['usage']['completion_tokens']);
|
|
}
|
|
|
|
public function testMultiTurnConversation(): void
|
|
{
|
|
$messages = [
|
|
['role' => 'user', 'content' => 'My name is TestBot.'],
|
|
['role' => 'assistant', 'content' => 'Nice to meet you, TestBot!'],
|
|
['role' => 'user', 'content' => 'What is my name?'],
|
|
];
|
|
|
|
$response = $this->client->chat($messages, ['model' => $this->model, 'max_tokens' => 50]);
|
|
$body = json_decode($response->getBody()->getContents(), true);
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$content = strtolower($body['choices'][0]['message']['content']);
|
|
$this->assertStringContainsString('testbot', $content);
|
|
}
|
|
|
|
public function testListModels(): void
|
|
{
|
|
$response = $this->client->listModels();
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
$body = json_decode($response->getBody()->getContents(), true);
|
|
$this->assertArrayHasKey('data', $body);
|
|
$this->assertIsArray($body['data']);
|
|
}
|
|
|
|
public function testRawToolFormatting(): void
|
|
{
|
|
$formatter = new ToolFormatter(ToolCallMode::RAW);
|
|
|
|
$messages = [
|
|
['role' => 'system', 'content' => 'You are a helpful assistant.'],
|
|
['role' => 'user', 'content' => 'Test'],
|
|
];
|
|
|
|
$tools = [ToolFormatter::FETCH_MESSAGE_TOOL];
|
|
|
|
$payload = $formatter->buildPayload($messages, ['model' => $this->model], $tools, ToolCallMode::RAW);
|
|
|
|
$this->assertArrayNotHasKey('tools', $payload);
|
|
|
|
$this->assertEquals('system', $payload['messages'][0]['role']);
|
|
$systemContent = $payload['messages'][0]['content'];
|
|
|
|
$this->assertStringContainsString('<tools>', $systemContent);
|
|
$this->assertStringContainsString('fetch_message', $systemContent);
|
|
}
|
|
|
|
public function testToolCallParserDetectsRawMode(): void
|
|
{
|
|
$parser = new ToolCallParser(ToolCallMode::AUTO);
|
|
|
|
$response = [
|
|
'choices' => [
|
|
[
|
|
'message' => [
|
|
'role' => 'assistant',
|
|
'content' => '<tool_call>{"name": "fetch_message", "arguments": {"md5": "abc123"}}</tool_call>',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$detected = $parser->detectMode($response);
|
|
$this->assertEquals(ToolCallMode::RAW, $detected);
|
|
}
|
|
|
|
public function testToolCallParserExtractsRawToolCall(): void
|
|
{
|
|
$parser = new ToolCallParser(ToolCallMode::RAW);
|
|
|
|
$response = [
|
|
'choices' => [
|
|
[
|
|
'message' => [
|
|
'role' => 'assistant',
|
|
'content' => '<tool_call>{"name": "fetch_message", "arguments": {"md5": "abc123def456"}}</tool_call>',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$toolCalls = $parser->extract($response);
|
|
|
|
$this->assertNotNull($toolCalls);
|
|
$this->assertCount(1, $toolCalls);
|
|
$this->assertEquals('fetch_message', $toolCalls[0]['name']);
|
|
$this->assertEquals('abc123def456', $toolCalls[0]['arguments']['md5']);
|
|
}
|
|
}
|