mcp
This commit is contained in:
@@ -128,6 +128,58 @@ describe('AssistantService', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('extracts the final assistant message from multi-completion responses', async () => {
|
||||||
|
const providerResponse = {
|
||||||
|
id: 'chatcmpl-test',
|
||||||
|
object: 'chat.multi_completion',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: 'assistant',
|
||||||
|
index: 0,
|
||||||
|
content: '',
|
||||||
|
tool_calls: [
|
||||||
|
{
|
||||||
|
id: 'call-1',
|
||||||
|
type: 'function',
|
||||||
|
function: {
|
||||||
|
name: 'listify_list_existing_lists',
|
||||||
|
arguments: '{"includeItems": false}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'tool',
|
||||||
|
index: 1,
|
||||||
|
content: [{ type: 'text', text: '{"lists":[]}' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'assistant',
|
||||||
|
index: 2,
|
||||||
|
content: 'Hier sind deine bestehenden Listen.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
finish_reason: 'stop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
mockMistralResponse(providerResponse);
|
||||||
|
|
||||||
|
const result = await service.chat('user-1', {
|
||||||
|
messages: [{ role: 'user', content: 'Welche Listen habe ich?' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.message.content).toBe('Hier sind deine bestehenden Listen.');
|
||||||
|
expect(chatLogsRepository.save).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
responsePayload: providerResponse,
|
||||||
|
assistantContent: 'Hier sind deine bestehenden Listen.',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('fails clearly when the api key is missing', async () => {
|
it('fails clearly when the api key is missing', async () => {
|
||||||
delete process.env.MISTRAL_API_KEY;
|
delete process.env.MISTRAL_API_KEY;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ interface MistralAgentCompletionResponse {
|
|||||||
message?: {
|
message?: {
|
||||||
content?: string | null;
|
content?: string | null;
|
||||||
};
|
};
|
||||||
|
messages?: Array<{
|
||||||
|
role?: string;
|
||||||
|
content?: string | null | unknown[];
|
||||||
|
}>;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +40,7 @@ export class AssistantService {
|
|||||||
): Promise<AssistantChatResponse> {
|
): Promise<AssistantChatResponse> {
|
||||||
const messages = this.normalizeMessages(request.messages);
|
const messages = this.normalizeMessages(request.messages);
|
||||||
const response = await this.callMistralAgent(userId, messages);
|
const response = await this.callMistralAgent(userId, messages);
|
||||||
const content = response.choices?.[0]?.message?.content?.trim();
|
const content = this.extractAssistantContent(response);
|
||||||
|
|
||||||
if (!content) {
|
if (!content) {
|
||||||
throw new ServiceUnavailableException('Mistral response was empty.');
|
throw new ServiceUnavailableException('Mistral response was empty.');
|
||||||
@@ -149,7 +153,28 @@ export class AssistantService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = responsePayload as MistralAgentCompletionResponse;
|
const response = responsePayload as MistralAgentCompletionResponse;
|
||||||
return response.choices?.[0]?.message?.content?.trim() ?? null;
|
const directContent = response.choices?.[0]?.message?.content?.trim();
|
||||||
|
|
||||||
|
if (directContent) {
|
||||||
|
return directContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const choice of response.choices ?? []) {
|
||||||
|
const assistantMessages = (choice.messages ?? [])
|
||||||
|
.filter((message) => message.role === 'assistant')
|
||||||
|
.reverse();
|
||||||
|
|
||||||
|
for (const message of assistantMessages) {
|
||||||
|
const content =
|
||||||
|
typeof message.content === 'string' ? message.content.trim() : '';
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async recordChatLog(input: {
|
private async recordChatLog(input: {
|
||||||
|
|||||||
Reference in New Issue
Block a user