'fetch_message', 'description' => 'Retrieve a message', 'parameters' => [ 'type' => 'object', 'properties' => [ 'md5' => ['type' => 'string'], ], 'required' => ['md5'], ], ], ]; $result = $formatter->formatForRequest($tools); $this->assertArrayHasKey('tools', $result); $this->assertArrayHasKey('tool_choice', $result); $this->assertEquals('auto', $result['tool_choice']); $this->assertCount(1, $result['tools']); $this->assertEquals('function', $result['tools'][0]['type']); $this->assertEquals('fetch_message', $result['tools'][0]['function']['name']); } /** * Test raw format returns empty array (tools go in system prompt). */ public function testFormatRaw(): void { $formatter = new ToolFormatter(ToolCallMode::RAW); $tools = [ [ 'name' => 'test_tool', 'description' => 'A test tool', 'parameters' => [ 'type' => 'object', 'properties' => [ 'query' => ['type' => 'string', 'description' => 'Search query'], ], 'required' => ['query'], ], ], ]; $result = $formatter->formatForRequest($tools); // Raw format returns empty array - tools are injected via buildPayload $this->assertEmpty($result); // Verify tools get injected into system prompt via buildPayload $messages = [ ['role' => 'system', 'content' => 'You are a helpful assistant.'], ]; $modifiedMessages = $formatter->injectToolsIntoMessages($messages, $tools); $this->assertStringContainsString('## Tools', $modifiedMessages[0]['content']); $this->assertStringContainsString('test_tool', $modifiedMessages[0]['content']); } /** * Test buildPayload with native mode. */ public function testBuildPayloadNative(): void { $formatter = new ToolFormatter(ToolCallMode::NATIVE); $messages = [ ['role' => 'user', 'content' => 'Hello'], ]; $options = ['model' => 'gpt-4']; $tools = [ToolFormatter::FETCH_MESSAGE_TOOL]; $payload = $formatter->buildPayload($messages, $options, $tools); $this->assertEquals($messages, $payload['messages']); $this->assertEquals('gpt-4', $payload['model']); $this->assertArrayHasKey('tools', $payload); $this->assertEquals('fetch_message', $payload['tools'][0]['function']['name']); } /** * Test buildPayload with raw mode injects into system prompt. */ public function testBuildPayloadRaw(): void { $formatter = new ToolFormatter(ToolCallMode::RAW); $messages = [ ['role' => 'system', 'content' => 'You are helpful.'], ['role' => 'user', 'content' => 'Hello'], ]; $options = ['model' => 'test-model']; $tools = [ToolFormatter::FETCH_MESSAGE_TOOL]; $payload = $formatter->buildPayload($messages, $options, $tools); // Raw mode does NOT add tools key $this->assertArrayNotHasKey('tools', $payload); // Instead, tools are injected into the system message $this->assertStringContainsString('fetch_message', $payload['messages'][0]['content']); $this->assertStringContainsString('You are helpful.', $payload['messages'][0]['content']); } /** * Test FETCH_MESSAGE_TOOL constant. */ public function testFetchMessageToolDefinition(): void { $tool = ToolFormatter::FETCH_MESSAGE_TOOL; $this->assertEquals('fetch_message', $tool['name']); $this->assertArrayHasKey('md5', $tool['parameters']['properties']); $this->assertEquals(['md5'], $tool['parameters']['required']); } }