Files
diegosouzapw--omniroute/tests/unit/chatcore-memory-extraction.test.ts
2026-07-13 13:39:12 +08:00

137 lines
4.8 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
extractMemoryTextFromResponse,
extractMemoryTextFromRequestBody,
resolveMemoryOwnerId,
} from "../../open-sse/handlers/chatCore/memoryExtraction.ts";
test("extractMemoryTextFromResponse reads OpenAI choices[0].message.content (trimmed)", () => {
assert.equal(
extractMemoryTextFromResponse({ choices: [{ message: { content: " hi " } }] }),
"hi"
);
});
test("extractMemoryTextFromResponse joins Claude content text blocks and skips non-text", () => {
assert.equal(
extractMemoryTextFromResponse({
content: [
{ type: "text", text: " a " },
{ type: "image" },
{ type: "text", text: "b" },
],
}),
"a\nb"
);
});
test("extractMemoryTextFromResponse falls back to Responses output_text", () => {
assert.equal(extractMemoryTextFromResponse({ output_text: " out " }), "out");
});
test("extractMemoryTextFromResponse returns empty string for null/empty/no-text shapes", () => {
assert.equal(extractMemoryTextFromResponse(null), "");
assert.equal(extractMemoryTextFromResponse(undefined), "");
assert.equal(extractMemoryTextFromResponse({}), "");
// content array with no text parts -> contentText is "" -> falls through to ""
assert.equal(extractMemoryTextFromResponse({ content: [{ type: "image" }] }), "");
});
test("extractMemoryTextFromResponse prefers OpenAI content over output_text", () => {
assert.equal(
extractMemoryTextFromResponse({
choices: [{ message: { content: "openai" } }],
output_text: "responses",
}),
"openai"
);
});
test("extractMemoryTextFromRequestBody returns the LAST user message (string content)", () => {
const body = {
messages: [
{ role: "user", content: "first" },
{ role: "assistant", content: "ignored" },
{ role: "user", content: "second" },
],
};
assert.equal(extractMemoryTextFromRequestBody(body), "second");
});
test("extractMemoryTextFromRequestBody joins array content parts of the last user message", () => {
const body = {
messages: [
{
role: "user",
content: [
{ type: "input_text", text: " a " },
{ text: "b" },
{ type: "image_url" },
],
},
],
};
assert.equal(extractMemoryTextFromRequestBody(body), "a\nb");
});
test("extractMemoryTextFromRequestBody reads Responses-style input items", () => {
const inputBody = {
input: [{ role: "user", type: "message", content: [{ type: "input_text", text: "hey" }] }],
};
assert.equal(extractMemoryTextFromRequestBody(inputBody), "hey");
});
test("extractMemoryTextFromRequestBody reads a string-content input item", () => {
const inputBody = {
input: [{ role: "user", type: "message", content: " plain " }],
};
assert.equal(extractMemoryTextFromRequestBody(inputBody), "plain");
});
test("extractMemoryTextFromRequestBody scans input items from the end and returns the last user text", () => {
// The primary input scan walks from the end and returns immediately on the
// last item whose role is user (or unset) and type is message (or unset).
const inputBody = {
input: [
{ type: "reasoning", content: "thinking" }, // itemType !== "message" -> skipped
{ role: "user", content: "alpha" }, // matches, but an earlier item from the end wins
{ role: "user", content: "beta" }, // last matching item -> returned
],
};
assert.equal(extractMemoryTextFromRequestBody(inputBody), "beta");
});
test("extractMemoryTextFromRequestBody skips assistant input items but accepts the prior user item", () => {
const inputBody = {
input: [
{ role: "user", type: "message", content: "the question" },
{ role: "assistant", type: "message", content: "the answer" }, // role !== user -> skipped
],
};
assert.equal(extractMemoryTextFromRequestBody(inputBody), "the question");
});
test("extractMemoryTextFromRequestBody returns empty for null/empty/no-user bodies", () => {
assert.equal(extractMemoryTextFromRequestBody(null), "");
assert.equal(extractMemoryTextFromRequestBody(undefined), "");
assert.equal(extractMemoryTextFromRequestBody({}), "");
// only an assistant message -> no user text
assert.equal(
extractMemoryTextFromRequestBody({ messages: [{ role: "assistant", content: "x" }] }),
""
);
});
test("resolveMemoryOwnerId returns the id when present, null otherwise", () => {
assert.equal(resolveMemoryOwnerId({ id: "key_123" }), "key_123");
// whitespace-only id is rejected
assert.equal(resolveMemoryOwnerId({ id: " " }), null);
// non-string id is rejected
assert.equal(resolveMemoryOwnerId({ id: 7 } as unknown as Record<string, unknown>), null);
// missing id / null info
assert.equal(resolveMemoryOwnerId({}), null);
assert.equal(resolveMemoryOwnerId(null), null);
});