feat(agent): add structured outputs and media archive support
This commit is contained in:
148
tests/lib/agent-structured-output.test.ts
Normal file
148
tests/lib/agent-structured-output.test.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { normalizeAgentStructuredOutput } from "@/lib/agent-run-contract";
|
||||
|
||||
describe("normalizeAgentStructuredOutput", () => {
|
||||
it("preserves valid structured fields and compatibility body", () => {
|
||||
const normalized = normalizeAgentStructuredOutput(
|
||||
{
|
||||
title: " Launch Post ",
|
||||
channel: " linkedin ",
|
||||
artifactType: " social-post ",
|
||||
previewText: " Hook-first launch post. ",
|
||||
sections: [
|
||||
{
|
||||
id: " headline ",
|
||||
label: " Headline ",
|
||||
content: " Ship faster with LemonSpace. ",
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
language: " en ",
|
||||
tags: [" launch ", "saas", ""],
|
||||
},
|
||||
qualityChecks: [" concise ", "concise", "channel-fit"],
|
||||
body: " Legacy flat content ",
|
||||
},
|
||||
{
|
||||
title: "Fallback Title",
|
||||
channel: "fallback-channel",
|
||||
artifactType: "fallback-artifact",
|
||||
},
|
||||
);
|
||||
|
||||
expect(normalized).toEqual({
|
||||
title: "Launch Post",
|
||||
channel: "linkedin",
|
||||
artifactType: "social-post",
|
||||
previewText: "Hook-first launch post.",
|
||||
sections: [
|
||||
{
|
||||
id: "headline",
|
||||
label: "Headline",
|
||||
content: "Ship faster with LemonSpace.",
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
language: "en",
|
||||
tags: ["launch", "saas"],
|
||||
},
|
||||
qualityChecks: ["concise", "channel-fit"],
|
||||
body: "Legacy flat content",
|
||||
});
|
||||
});
|
||||
|
||||
it("removes blank or malformed section entries", () => {
|
||||
const normalized = normalizeAgentStructuredOutput(
|
||||
{
|
||||
sections: [
|
||||
{
|
||||
id: "intro",
|
||||
label: "Intro",
|
||||
content: "Keep this section.",
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
label: "",
|
||||
content: "",
|
||||
},
|
||||
{
|
||||
id: "missing-content",
|
||||
label: "Missing Content",
|
||||
content: " ",
|
||||
},
|
||||
null,
|
||||
"bad-shape",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Fallback Title",
|
||||
channel: "fallback-channel",
|
||||
artifactType: "fallback-artifact",
|
||||
},
|
||||
);
|
||||
|
||||
expect(normalized.sections).toEqual([
|
||||
{
|
||||
id: "intro",
|
||||
label: "Intro",
|
||||
content: "Keep this section.",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("derives previewText deterministically from first valid section when missing", () => {
|
||||
const normalized = normalizeAgentStructuredOutput(
|
||||
{
|
||||
sections: [
|
||||
{
|
||||
id: "hook",
|
||||
label: "Hook",
|
||||
content: "First section content.",
|
||||
},
|
||||
{
|
||||
id: "cta",
|
||||
label: "CTA",
|
||||
content: "Second section content.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Fallback Title",
|
||||
channel: "fallback-channel",
|
||||
artifactType: "fallback-artifact",
|
||||
},
|
||||
);
|
||||
|
||||
expect(normalized.previewText).toBe("First section content.");
|
||||
});
|
||||
|
||||
it("derives deterministic legacy body from sections when body is missing", () => {
|
||||
const normalized = normalizeAgentStructuredOutput(
|
||||
{
|
||||
previewText: "Preview should not override section flattening",
|
||||
sections: [
|
||||
{
|
||||
id: "hook",
|
||||
label: "Hook",
|
||||
content: "Lead with a bold claim.",
|
||||
},
|
||||
{
|
||||
id: "cta",
|
||||
label: "CTA",
|
||||
content: "Invite replies with a concrete question.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Fallback Title",
|
||||
channel: "fallback-channel",
|
||||
artifactType: "fallback-artifact",
|
||||
},
|
||||
);
|
||||
|
||||
expect(normalized.body).toBe(
|
||||
"Hook:\nLead with a bold claim.\n\nCTA:\nInvite replies with a concrete question.",
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user