fix(oss-ts): preserve message roles in extraction input so assistant facts aren't attributed to the user (#5643)

This commit is contained in:
Haochen
2026-06-19 11:47:52 +08:00
committed by GitHub
parent 5b4478458b
commit 6b744845c3
2 changed files with 23 additions and 1 deletions
+7 -1
View File
@@ -750,7 +750,13 @@ export class Memory {
// getLastMessages not supported — proceed without context
}
}
const parsedMessages = messages.map((m) => m.content).join("\n");
// Preserve role on the messages being extracted so the prompt's role-aware
// logic and the required `attributed_to` output have the speaker to work
// with. Matches the Python oss `parse_messages` helper (`role: content`);
// without this, assistant statements get attributed to the user.
const parsedMessages = messages
.map((m) => `${m.role}: ${m.content}`)
.join("\n");
// Phase 1: Existing memory retrieval
const queryEmbedding = await this.embedder.embed(parsedMessages);
+16
View File
@@ -126,6 +126,22 @@ describe("Memory - add()", () => {
expect(result.results.length).toBeGreaterThan(0);
});
test("preserves message roles in the extraction prompt (## New Messages)", async () => {
// The OpenAI LLM mock echoes the `## New Messages` section of the prompt back
// as the extracted text, so the stored memory reveals what the LLM received.
// Roles must survive into that section, otherwise the prompt's role-aware
// logic and required `attributed_to` output have no speaker to attribute to
// and assistant statements get stored as user facts.
const messages = [
{ role: "user", content: "I want to sleep earlier." },
{ role: "assistant", content: "Aim for 00:30 sleep / 08:30 wake." },
];
const result: SearchResult = await memory.add(messages, { userId });
const seen = result.results.map((r) => r.memory).join("\n");
expect(seen).toContain("user: I want to sleep earlier.");
expect(seen).toContain("assistant: Aim for 00:30 sleep / 08:30 wake.");
});
test("works with agentId instead of userId", async () => {
const result: SearchResult = await memory.add("test", {
agentId: "agent_1",