Skip to content

Commit f726c51

Browse files
authored
Responses api - ensure proper storage of tool messages (#851)
* improve logic for converting input to db messages * improved and added tests for tool message logic
1 parent 5ea37b2 commit f726c51

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

packages/mongodb-chatbot-server/src/routes/responses/createResponse.test.ts

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
Conversation,
66
ConversationsService,
77
SomeMessage,
8+
ToolMessage,
89
} from "mongodb-rag-core";
910
import { type AppConfig } from "../../app";
1011
import {
@@ -386,15 +387,66 @@ describe("POST /responses", () => {
386387

387388
it("Should store function_call messages when `store: true`", async () => {
388389
const store = true;
389-
const functionCallType = "function_call";
390+
const functionCallName = "my_function";
391+
const functionCallArguments = `{"query": "value"}`;
390392
const functionCallOutputType = "function_call_output";
393+
const functionCallOutput = `{"result": "success"}`;
391394
const requestBody: Partial<CreateResponseRequest["body"]> = {
392395
store,
393396
input: [
394397
{
395-
type: functionCallType,
398+
type: "function_call",
396399
call_id: "call123",
397-
name: "my_function",
400+
name: functionCallName,
401+
arguments: functionCallArguments,
402+
status: "in_progress",
403+
},
404+
{
405+
type: functionCallOutputType,
406+
call_id: "call123",
407+
output: functionCallOutput,
408+
status: "completed",
409+
},
410+
{
411+
role: "user",
412+
content: "What is MongoDB?",
413+
},
414+
],
415+
};
416+
const stream = await makeClientAndRequest(requestBody);
417+
418+
const results = await expectValidResponses({ requestBody, stream });
419+
420+
const updatedConversation = await conversations.findByMessageId({
421+
messageId: getMessageIdFromResults(results),
422+
});
423+
if (!updatedConversation) {
424+
return expect(updatedConversation).not.toBeNull();
425+
}
426+
const messages = updatedConversation.messages as Array<ToolMessage>;
427+
428+
expect(updatedConversation.storeMessageContent).toEqual(store);
429+
430+
expect(messages[0].role).toEqual("tool");
431+
expect(messages[0].name).toEqual(functionCallName);
432+
expect(messages[0].content).toEqual(functionCallArguments);
433+
434+
expect(messages[1].role).toEqual("tool");
435+
expect(messages[1].name).toEqual(functionCallOutputType);
436+
expect(messages[1].content).toEqual(functionCallOutput);
437+
});
438+
439+
it("Should not store function_call message content when `store: false`", async () => {
440+
const store = false;
441+
const functionCallName = "my_function";
442+
const functionCallOutputType = "function_call_output";
443+
const requestBody: Partial<CreateResponseRequest["body"]> = {
444+
store,
445+
input: [
446+
{
447+
type: "function_call",
448+
call_id: "call123",
449+
name: functionCallName,
398450
arguments: `{"query": "value"}`,
399451
status: "in_progress",
400452
},
@@ -420,16 +472,17 @@ describe("POST /responses", () => {
420472
if (!updatedConversation) {
421473
return expect(updatedConversation).not.toBeNull();
422474
}
475+
const messages = updatedConversation.messages as Array<ToolMessage>;
423476

424477
expect(updatedConversation.storeMessageContent).toEqual(store);
425478

426-
expect(updatedConversation.messages[0].role).toEqual("system");
427-
expect(updatedConversation.messages[0].content).toEqual(functionCallType);
479+
expect(messages[0].role).toEqual("tool");
480+
expect(messages[0].name).toEqual(functionCallName);
481+
expect(messages[0].content).toEqual("");
428482

429-
expect(updatedConversation.messages[1].role).toEqual("system");
430-
expect(updatedConversation.messages[1].content).toEqual(
431-
functionCallOutputType
432-
);
483+
expect(messages[1].role).toEqual("tool");
484+
expect(messages[1].name).toEqual(functionCallOutputType);
485+
expect(messages[1].content).toEqual("");
433486
});
434487
});
435488

packages/mongodb-chatbot-server/src/routes/responses/createResponse.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -511,16 +511,17 @@ const convertInputToDBMessages = (
511511
}
512512

513513
return input.map((message) => {
514-
// set default role and content for function tool calls and outputs
515-
let role: MessagesParam[number]["role"] = "system";
516-
let content = message.type ?? "";
517-
// set role and content for all other messages
518-
if (message.type === "message") {
519-
role = message.role;
520-
content = formatUserMessageContent(message.content);
514+
if (isInputMessage(message)) {
515+
const role = message.role;
516+
const content = formatUserMessageContent(message.content);
517+
return formatMessage({ role, content }, store, metadata);
521518
}
522-
523-
return formatMessage({ role, content }, store, metadata);
519+
// handle function tool calls and outputs
520+
const role = "tool";
521+
const name = message.type === "function_call" ? message.name : message.type;
522+
const content =
523+
message.type === "function_call" ? message.arguments : message.output;
524+
return formatMessage({ role, name, content }, store, metadata);
524525
});
525526
};
526527

0 commit comments

Comments
 (0)