Skip to content
Snippets Groups Projects
Commit 0dfbf6e0 authored by Claude AI's avatar Claude AI
Browse files

Issue #3515885: Fix coding standards in OpenAiChatMessageIterator implementation

- Remove unused use statement for IteratorAggregate (use FQN reference instead)
- Fix whitespace issues throughout the code
- Ensure newline at end of file in test class
- Fix formatting to meet Drupal coding standards

:robot: Generated with [Claude Code](https://claude.ai/code

)

Co-Authored-By: default avatarClaude <noreply@anthropic.com>
parent b2c8c442
No related tags found
1 merge request!27Issue #3515885: Add missing getTools() method to OpenAiChatMessageIterator
......@@ -6,7 +6,6 @@ use Drupal\Component\Serialization\Json;
use Drupal\ai\OperationType\Chat\StreamedChatMessage;
use Drupal\ai\OperationType\Chat\StreamedChatMessageIterator;
use Drupal\ai\OperationType\Chat\Tools\ToolsFunctionOutput;
use IteratorAggregate;
/**
* OpenAI Chat message iterator.
......@@ -59,14 +58,14 @@ class OpenAiChatMessageIterator extends StreamedChatMessageIterator {
],
];
}
// Append function arguments if they exist.
if (isset($toolCallDelta->function->arguments)) {
$this->toolCalls[$toolCallDelta->index]['function']['arguments'] .= $toolCallDelta->function->arguments;
}
}
}
// Yield the message content.
yield new StreamedChatMessage(
$data->choices[0]->delta->role ?? '',
......@@ -86,14 +85,14 @@ class OpenAiChatMessageIterator extends StreamedChatMessageIterator {
if (empty($this->toolCalls)) {
return NULL;
}
$tools = [];
foreach ($this->toolCalls as $toolCall) {
// Skip incomplete tool calls.
if (empty($toolCall['id']) || empty($toolCall['function']['name'])) {
continue;
}
try {
$arguments = Json::decode($toolCall['function']['arguments']);
}
......@@ -101,7 +100,7 @@ class OpenAiChatMessageIterator extends StreamedChatMessageIterator {
// If JSON decoding fails, try with an empty object.
$arguments = new \stdClass();
}
// Only create tool outputs if we have chat tools from the input.
if ($this->chatTools && ($function = $this->chatTools->getFunctionByName($toolCall['function']['name']))) {
$tools[] = new ToolsFunctionOutput(
......@@ -111,7 +110,7 @@ class OpenAiChatMessageIterator extends StreamedChatMessageIterator {
);
}
}
return !empty($tools) ? $tools : NULL;
}
......
......@@ -6,7 +6,6 @@ use Drupal\ai\OperationType\Chat\Tools\ChatFunction;
use Drupal\ai\OperationType\Chat\Tools\ChatTools;
use Drupal\ai_provider_openai\OpenAiChatMessageIterator;
use Drupal\Tests\UnitTestCase;
use IteratorAggregate;
/**
* Test the OpenAI chat message iterator.
......@@ -21,31 +20,31 @@ class OpenAiChatMessageIteratorTest extends UnitTestCase {
public function testToolCallsCollection() {
// Set up a mock stream of OpenAI responses.
$responseParts = $this->getStreamedToolCallResponse();
$streamIterator = $this->createMock(\IteratorAggregate::class);
$streamIterator = $this->createMock('\IteratorAggregate');
$streamIterator->method('getIterator')
->willReturn(new \ArrayIterator($responseParts));
// Create a test tool function.
$chatTools = $this->createMock(ChatTools::class);
$testFunction = $this->createMock(ChatFunction::class);
// The function will be looked up by name.
$chatTools->method('getFunctionByName')
->with('get_weather')
->willReturn($testFunction);
// Create the iterator with the mock stream and tools.
$iterator = new OpenAiChatMessageIterator($streamIterator, $chatTools);
// Exhaust the iterator to process the stream.
$content = '';
foreach ($iterator as $message) {
$content .= $message->getText();
}
// Check that content is collected.
$this->assertEquals("I'll get the weather for you.", $content);
// Check that tools are collected.
$tools = $iterator->getTools();
$this->assertNotNull($tools);
......@@ -61,7 +60,7 @@ class OpenAiChatMessageIteratorTest extends UnitTestCase {
*/
protected function getStreamedToolCallResponse() {
$parts = [];
// First chunk with content.
$part1 = new \stdClass();
$part1->choices = [
......@@ -71,7 +70,7 @@ class OpenAiChatMessageIteratorTest extends UnitTestCase {
$part1->choices[0]->delta->role = 'assistant';
$part1->choices[0]->delta->content = "I'll get the weather for you.";
$parts[] = $part1;
// First chunk with tool call.
$part2 = new \stdClass();
$part2->choices = [
......@@ -89,7 +88,7 @@ class OpenAiChatMessageIteratorTest extends UnitTestCase {
$part2->choices[0]->delta->tool_calls[0]->function->name = 'get_weather';
$part2->choices[0]->delta->tool_calls[0]->function->arguments = '{"location":"';
$parts[] = $part2;
// Second chunk with more arguments.
$part3 = new \stdClass();
$part3->choices = [
......@@ -104,8 +103,8 @@ class OpenAiChatMessageIteratorTest extends UnitTestCase {
$part3->choices[0]->delta->tool_calls[0]->function = new \stdClass();
$part3->choices[0]->delta->tool_calls[0]->function->arguments = 'San Francisco"}';
$parts[] = $part3;
return $parts;
}
}
\ No newline at end of file
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment