Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

269 lines
8.9 KiB
TypeScript

/**
* Creative-draft tests pin the owner-voice artifact contract before live voice
* memo scenarios exercise it through the model loop.
*/
import { describe, expect, it } from "vitest";
import {
applyCreativeDraftRevision,
buildCreativeDraftPrompt,
buildOwnerVoiceStyleCard,
type CreativeMemoTranscript,
createCreativeDraftArtifact,
type OwnerVoiceSource,
scoreOwnerVoiceFidelity,
} from "../src/lifeops/creative-draft/index.js";
const ownerSources: OwnerVoiceSource[] = [
{
id: "essay-1",
source: "essay",
text: "Look, I think the point is simple. We should say the hard thing plainly because the audience can feel when we sand the edges off.",
},
{
id: "mail-1",
source: "sent_mail",
text: "I think the useful version is direct and specific. What matters is keeping the heat where the heat belongs.",
},
{
id: "thread-1",
source: "thread",
text: "Look, I want the piece to move fast. The point is not polish; the point is nerve.",
},
];
const memos: CreativeMemoTranscript[] = [
{
id: "memo-anger",
transcript:
"The second section needs to stay angry. They wasted six months and then asked everyone else to call it strategy.",
affect: "angry",
toneDirective: "Keep the anger in the second section.",
capturedAt: "2026-07-06T10:00:00.000Z",
},
{
id: "memo-hope",
transcript:
"End by saying we can still build the honest version if we stop hiding behind process.",
affect: "reflective",
capturedAt: "2026-07-06T10:04:00.000Z",
},
];
describe("creative draft owner-voice primitives", () => {
it("builds a style card from owner-authored examples", () => {
const card = buildOwnerVoiceStyleCard(ownerSources);
expect(card.sourceIds).toEqual(["essay-1", "mail-1", "thread-1"]);
expect(card.stanceMarkers).toEqual(
expect.arrayContaining(["I think", "look", "the point is"]),
);
expect(card.signaturePhrases).toContain("the point");
expect(card.avoidPhrases).toContain("leverage synergies");
});
it("maps memo affect into draft sections and prompt payload", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const request = {
title: "Honest Strategy Essay",
targetForm: "essay" as const,
ownerAsk: "Turn these memos into an essay in my voice.",
requestedVoice: "my voice, not consultant voice",
};
const draft = createCreativeDraftArtifact({
request,
memos,
styleCard,
nowIso: "2026-07-06T10:10:00.000Z",
});
const prompt = buildCreativeDraftPrompt({
request,
memos,
styleCard,
currentDraft: draft,
});
expect(draft.sourceMemoIds).toEqual(["memo-anger", "memo-hope"]);
expect(draft.sections[0]).toMatchObject({
memoId: "memo-anger",
affect: "angry",
directive: "Keep the anger in the second section.",
});
expect(prompt).toContain('"task": "creative_draft"');
expect(prompt).toContain("not like a consultant");
expect(prompt).toContain("Keep the anger in the second section.");
expect(prompt).toContain('"acceptedEdits": []');
});
it("scores owner-like copy above a generic consultant baseline", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const ownerLike =
"Look, I think the point is simple. What matters is keeping the heat where the heat belongs.";
const generic =
"This best-in-class framework will unlock value and leverage synergies across a robust operating model.";
expect(scoreOwnerVoiceFidelity(ownerLike, styleCard)).toBeGreaterThan(
scoreOwnerVoiceFidelity(generic, styleCard),
);
});
it("revisions preserve accepted edits and vetoed phrases across turns", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const request = {
title: "Launch Narrative",
targetForm: "launch_thread" as const,
ownerAsk: "Make this sound like me on a good day.",
};
const initial = createCreativeDraftArtifact({
request,
memos,
styleCard,
nowIso: "2026-07-06T10:10:00.000Z",
});
const revised = applyCreativeDraftRevision(initial, {
instruction: "Keep the sharper opening; never say best-in-class.",
acceptedEdit: "Sharper opening approved.",
vetoedPhrase: "best-in-class",
replacementText: "Look, the honest version starts by naming the waste.",
revisedAt: "2026-07-06T10:20:00.000Z",
});
expect(revised.id).toBe(initial.id);
expect(revised.acceptedEdits).toEqual(["Sharper opening approved."]);
expect(revised.vetoedPhrases).toEqual(["best-in-class"]);
expect(revised.sections[0]?.text).toBe(
"Look, the honest version starts by naming the waste.",
);
expect(revised.sections[1]).toEqual(initial.sections[1]);
});
it("revises a non-first section by sectionIndex", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const initial = createCreativeDraftArtifact({
request: {
title: "Two-part memo",
targetForm: "memo" as const,
ownerAsk: "Draft this.",
},
memos,
styleCard,
nowIso: "2026-07-06T10:10:00.000Z",
});
const revised = applyCreativeDraftRevision(initial, {
instruction: "Soften the closing.",
sectionIndex: 1,
replacementText: "We can still build the honest version.",
revisedAt: "2026-07-06T10:30:00.000Z",
});
// The first section is untouched; only the targeted second section changes.
expect(revised.sections[0]).toEqual(initial.sections[0]);
expect(revised.sections[1]?.text).toBe(
"We can still build the honest version.",
);
});
it("revises a non-first section by sectionId regardless of position", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const initial = createCreativeDraftArtifact({
request: {
title: "Two-part memo",
targetForm: "memo" as const,
ownerAsk: "Draft this.",
},
memos,
styleCard,
nowIso: "2026-07-06T10:10:00.000Z",
});
const targetSection = initial.sections[1];
if (!targetSection) throw new Error("expected a second section");
const revised = applyCreativeDraftRevision(initial, {
instruction: "Rewrite the hopeful close.",
sectionId: targetSection.id,
replacementText: "Stop hiding behind process and ship the honest one.",
revisedAt: "2026-07-06T10:35:00.000Z",
});
expect(revised.sections[0]).toEqual(initial.sections[0]);
expect(revised.sections[1]?.text).toBe(
"Stop hiding behind process and ship the honest one.",
);
});
it("rejects a revision whose target section does not exist", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const initial = createCreativeDraftArtifact({
request: {
title: "Two-part memo",
targetForm: "memo" as const,
ownerAsk: "Draft this.",
},
memos,
styleCard,
nowIso: "2026-07-06T10:10:00.000Z",
});
expect(() =>
applyCreativeDraftRevision(initial, {
instruction: "Edit a section that isn't there.",
sectionIndex: 9,
replacementText: "orphan text",
revisedAt: "2026-07-06T10:40:00.000Z",
}),
).toThrow(/unknown section/u);
expect(() =>
applyCreativeDraftRevision(initial, {
instruction: "Edit by a bogus id.",
sectionId: "section_does_not_exist",
replacementText: "orphan text",
revisedAt: "2026-07-06T10:41:00.000Z",
}),
).toThrow(/unknown section/u);
});
it("sources instructions through OptimizedPromptService when a runtime is supplied", () => {
const styleCard = buildOwnerVoiceStyleCard(ownerSources);
const request = {
title: "Optimized Draft",
targetForm: "essay" as const,
ownerAsk: "Draft in my voice.",
};
const optimizedInstructions =
"OPTIMIZED creative_draft instructions — write in the owner's voice.";
const runtime = {
getService(name: string) {
if (name !== "optimized_prompt") return null;
return {
getPrompt(task: string) {
return task === "creative_draft"
? { prompt: optimizedInstructions, optimizerSource: "gepa" }
: null;
},
};
},
};
const optimizedPrompt = buildCreativeDraftPrompt({
request,
memos,
styleCard,
runtime,
});
const baselinePrompt = buildCreativeDraftPrompt({
request,
memos,
styleCard,
});
expect(optimizedPrompt).toContain(optimizedInstructions);
expect(optimizedPrompt).not.toContain("not like a consultant");
// Absent a runtime, the inline baseline is used unchanged.
expect(baselinePrompt).toContain("not like a consultant");
// The structured data payload is composed around the resolved instructions
// in both cases.
expect(optimizedPrompt).toContain('"task": "creative_draft"');
});
});