-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Description
There is an issue where a second message added to the conversation immediately ends without any output text.
Adding another message then causes Not the same number of function calls and responses error.
With this Testcase I can reproduce it consistently.
<?php
namespace Tests\Feature\Mcp;
use Partitech\PhpMistral\Clients\Mistral\MistralAgent;
use Partitech\PhpMistral\Clients\Mistral\MistralAgentClient;
use Partitech\PhpMistral\Clients\Mistral\MistralConversation;
use Partitech\PhpMistral\Clients\Mistral\MistralConversationClient;
use Partitech\PhpMistral\Mcp\McpConfig;
use Tests\TestCase;
class MCPToolStreamingTest extends TestCase
{
protected string $apiKey;
protected string $model;
protected function setUp(): void
{
parent::setUp();
$this->apiKey = getenv('MISTRAL_API_KEY');
$this->model = 'mistral-small-latest';
}
public function test_php_mistral_streaming_call_tool_multiple(): void
{
if (empty($this->apiKey)) {
$this->markTestSkipped('MISTRAL_API_KEY not set.');
}
if (! shell_exec('which docker')) {
$this->markTestSkipped('Docker not available.');
}
srand(1337); // Make the test deterministic
$apiKey = $this->apiKey;
$model = $this->model;
$numbers1 = [];
$numbers2 = [];
$numbers1[0] = rand(1, 100);
$numbers1[1] = rand(1, 100);
$numbers2[0] = rand(1, 100);
$numbers2[1] = rand(1, 100);
$expected = ($numbers1[0] + $numbers1[1]) + ($numbers2[0] + $numbers2[1]);
$configArray = [
'mcp' => [
'servers' => [
'test' => [
'command' => 'docker',
'args' => [
'run',
'-i',
'--rm',
'mcp/everything',
],
],
],
],
];
$mcpConfig = new McpConfig(
$configArray
);
$conversation = (new MistralConversation)
->setModel($model)
->setName('Test')
->setDescription('Conversation used for testing')
->setTools($mcpConfig);
$conversationClient = new MistralConversationClient($apiKey);
$userMessage = "Use the tool 'add' to add the numbers ({$numbers1[0]} and {$numbers1[1]} as Number1) and ({$numbers2[0]} and {$numbers2[1]} as Number2), finally use the tool 'add' to add Number1 and Number2 with eachother and only return the resulting number with nothing else. If you encounter any issues explain them instead of returning the number.";
$messages = $conversationClient
->getMessages()
->addAssistantMessage('Do as the user requests')
->addUserMessage($userMessage);
/** @var Response $chunk */
$text = null;
$done = false;
foreach ($conversationClient->conversation(
conversation: $conversation,
messages : $messages,
store : true,
stream : true
) as $chunk) {
if ($chunk->getType() !== 'conversation.response.done') {
$text .= $chunk->getChunk();
}
if ($chunk->getType() === 'conversation.response.done') {
$conversation->setId($chunk->getId());
$done = true;
}
}
$this->assertTrue($done);
$this->assertNotEmpty($text);
$this->assertEquals($expected, (int) $text);
$conversationClient = new MistralConversationClient($apiKey);
$conversation = $conversationClient->getConversation($conversation->getId());
$userMessage = "Use the tool 'add' to add the numbers ({$numbers1[0]} and {$numbers1[1]} as Number1) and ({$numbers2[0]} and {$numbers2[1]} as Number2), finally use the tool 'add' to add Number1 and Number2 with eachother and only return the resulting number with nothing else. If you encounter any issues explain them instead of returning the number.";
$messages = $conversationClient
->getMessages()
->addAssistantMessage('Do as the user requests')
->addUserMessage($userMessage);
/** @var Response $chunk */
$text = null;
$done = false;
foreach ($conversationClient->appendConversation(
conversation: $conversation,
messages : $messages,
store : true,
stream : true
) as $chunk) {
if ($chunk->getType() !== 'conversation.response.done') {
$text .= $chunk->getChunk();
}
if ($chunk->getType() === 'conversation.response.done') {
$conversation->setId($chunk->getId());
$done = true;
}
}
$this->assertTrue($done);
// Already fails here as the stream immediately ends
// Commented out to highlight the "Not the same number of function calls and responses" issue
// $this->assertNotEmpty($text);
// $this->assertEquals($expected, (int) $text);
$conversationClient = new MistralConversationClient($apiKey);
$conversation = $conversationClient->getConversation($conversation->getId());
$userMessage = 'Ping!';
$messages = $conversationClient
->getMessages()
->addUserMessage($userMessage);
/** @var Response $chunk */
$text = null;
$done = false;
foreach ($conversationClient->appendConversation(
conversation: $conversation,
messages : $messages,
store : true,
stream : true
) as $chunk) {
if ($chunk->getType() !== 'conversation.response.done') {
$text .= $chunk->getChunk();
}
if ($chunk->getType() === 'conversation.response.done') {
$conversation->setId($chunk->getId());
$done = true;
}
}
$this->assertTrue($done);
$this->assertNotEmpty($text);
$this->assertStringContainsString('Pong', (string) $text);
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels