fix(resume): harden transcript backfill (#1082)
This commit is contained in:
105
src/tests/cli/prepareMessageHistory.test.ts
Normal file
105
src/tests/cli/prepareMessageHistory.test.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import type { Message } from "@letta-ai/letta-client/resources/agents/messages";
|
||||
import { prepareMessageHistory } from "../../agent/check-approval";
|
||||
|
||||
function msg(
|
||||
type: string,
|
||||
id: string,
|
||||
dateMs: number,
|
||||
extra?: Record<string, unknown>,
|
||||
): Message {
|
||||
return {
|
||||
id,
|
||||
message_type: type,
|
||||
date: new Date(dateMs).toISOString(),
|
||||
...(extra ?? {}),
|
||||
} as unknown as Message;
|
||||
}
|
||||
|
||||
describe("prepareMessageHistory", () => {
|
||||
test("primaryOnly returns only primary message types", () => {
|
||||
const base = 1_700_000_000_000;
|
||||
const messages: Message[] = [
|
||||
msg("user_message", "u1", base + 1),
|
||||
msg("tool_call_message", "tc1", base + 2),
|
||||
msg("approval_request_message", "ar1", base + 3),
|
||||
msg("tool_return_message", "tr1", base + 4),
|
||||
msg("assistant_message", "a1", base + 5),
|
||||
msg("reasoning_message", "r1", base + 6),
|
||||
msg("approval_response_message", "ap1", base + 7),
|
||||
msg("event_message", "e1", base + 8),
|
||||
msg("summary_message", "s1", base + 9),
|
||||
];
|
||||
|
||||
const out = prepareMessageHistory(messages, { primaryOnly: true });
|
||||
expect(out.map((m) => m.message_type)).toEqual([
|
||||
"user_message",
|
||||
"assistant_message",
|
||||
"event_message",
|
||||
"summary_message",
|
||||
]);
|
||||
});
|
||||
|
||||
test("primaryOnly includes most recent assistant even if last N primary messages lack it", () => {
|
||||
const base = 1_700_000_000_000;
|
||||
const messages: Message[] = [];
|
||||
|
||||
// An older assistant message, then many user/event messages.
|
||||
messages.push(msg("assistant_message", "a1", base + 1));
|
||||
for (let i = 0; i < 30; i += 1) {
|
||||
messages.push(msg("user_message", `u${i}`, base + 10 + i));
|
||||
}
|
||||
|
||||
const out = prepareMessageHistory(messages, { primaryOnly: true });
|
||||
expect(out.some((m) => m.message_type === "assistant_message")).toBe(true);
|
||||
expect(
|
||||
out.every((m) =>
|
||||
[
|
||||
"user_message",
|
||||
"assistant_message",
|
||||
"event_message",
|
||||
"summary_message",
|
||||
].includes(m.message_type as string),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("primaryOnly falls back to reasoning when no primary messages exist", () => {
|
||||
const base = 1_700_000_000_000;
|
||||
const messages: Message[] = [
|
||||
msg("tool_return_message", "tr1", base + 1),
|
||||
msg("reasoning_message", "r1", base + 2),
|
||||
msg("tool_return_message", "tr2", base + 3),
|
||||
msg("reasoning_message", "r2", base + 4),
|
||||
];
|
||||
|
||||
const out = prepareMessageHistory(messages, { primaryOnly: true });
|
||||
expect(out.map((m) => m.message_type)).toEqual([
|
||||
"reasoning_message",
|
||||
"reasoning_message",
|
||||
]);
|
||||
});
|
||||
|
||||
test("primaryOnly returns [] when no primary or reasoning messages exist", () => {
|
||||
const base = 1_700_000_000_000;
|
||||
const messages: Message[] = [
|
||||
msg("tool_return_message", "tr1", base + 1),
|
||||
msg("approval_request_message", "ar1", base + 2),
|
||||
msg("approval_response_message", "ap1", base + 3),
|
||||
];
|
||||
|
||||
const out = prepareMessageHistory(messages, { primaryOnly: true });
|
||||
expect(out).toEqual([]);
|
||||
});
|
||||
|
||||
test("non-primaryOnly skips orphaned leading tool_return_message", () => {
|
||||
const base = 1_700_000_000_000;
|
||||
const messages: Message[] = [
|
||||
msg("tool_return_message", "tr1", base + 1),
|
||||
msg("assistant_message", "a1", base + 2),
|
||||
];
|
||||
|
||||
const out = prepareMessageHistory(messages);
|
||||
expect(out[0]?.message_type).toBe("assistant_message");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user