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('', $systemContent); $this->assertStringContainsString('fetch_message', $systemContent); } public function testToolCallParserDetectsRawMode(): void { $parser = new ToolCallParser(ToolCallMode::AUTO); $response = [ 'choices' => [ [ 'message' => [ 'role' => 'assistant', 'content' => '{"name": "fetch_message", "arguments": {"md5": "abc123"}}', ], ], ], ]; $detected = $parser->detectMode($response); $this->assertEquals(ToolCallMode::RAW, $detected); } public function testToolCallParserExtractsRawToolCall(): void { $parser = new ToolCallParser(ToolCallMode::RAW); $response = [ 'choices' => [ [ 'message' => [ 'role' => 'assistant', 'content' => '{"name": "fetch_message", "arguments": {"md5": "abc123def456"}}', ], ], ], ]; $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']); } }