Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/decay/__tests__/prompts.test.ts

Raw
import { describe, expect, it } from "vitest";
import type { AllocatedAtom, SourceChunk } from "../core";
import {
	buildClassifierContext,
	buildSummarizerContext,
	CLASSIFIER_TOOL,
	MAX_PRIOR_CATALOG_TOKENS,
} from "../prompts";

const chunk: SourceChunk = {
	chunk: 1,
	of: 1,
	source: "history",
	firstPosition: 0,
	lastPosition: 0,
	text: "untrusted source",
	estimatedTokens: 4,
};

const atom: AllocatedAtom = {
	key: "decision",
	text: "Use stdlib",
	kind: "decision",
	firstSeen: 1,
	lastSeen: 2,
	seenCount: 2,
	status: "active",
	sourcePosition: 3,
	allocation: 40,
	weight: 2,
	protected: true,
	recurring: true,
};

describe("Decay model contracts", () => {
	it("offers exactly one prefer-strict constrained classifier tool", () => {
		const context = buildClassifierContext([chunk], [atom], "focus here");
		expect(context.tools).toEqual([CLASSIFIER_TOOL]);
		expect(CLASSIFIER_TOOL.name).toBe("record_chunk");
		expect(CLASSIFIER_TOOL.constrainedSampling).toEqual({
			type: "json_schema",
			strict: "prefer",
		});
		expect(
			(CLASSIFIER_TOOL.parameters as { additionalProperties?: unknown })
				.additionalProperties,
		).toBe(false);
		expect(JSON.stringify(CLASSIFIER_TOOL.parameters)).not.toContain(
			"sourcePosition",
		);
		expect(context.systemPrompt).toContain("Never increase recurrence");
		expect(context.systemPrompt).toContain("reuse that catalog key exactly");
		const payload = JSON.parse(
			(context.messages[0]!.content as Array<{ text: string }>)[0]!.text,
		);
		expect(payload).toEqual({
			oneRunFocus: "focus here",
			priorCatalog: [
				{
					key: "decision",
					text: "Use stdlib",
					kind: "decision",
					status: "active",
				},
			],
			chunks: [expect.objectContaining({ chunk: 1, text: "untrusted source" })],
		});
	});

	it("uses an evidence-relevant token budget for the prior catalog", () => {
		const prior = Array.from({ length: 200 }, (_, index) => ({
			...atom,
			key: `key-${index}`,
			text: `fact-${index}-${"x".repeat(600)}`,
			lastSeen: index,
		}));
		const context = buildClassifierContext(
			[{ ...chunk, text: "key-0 needs identity continuity" }],
			prior,
		);
		const payload = JSON.parse(
			(context.messages[0]!.content as Array<{ text: string }>)[0]!.text,
		);
		expect(
			Math.ceil(JSON.stringify(payload.priorCatalog).length / 4),
		).toBeLessThanOrEqual(MAX_PRIOR_CATALOG_TOKENS);
		expect(payload.priorCatalog[0].key).toBe("key-0");
	});

	it("counts JSON brackets and delimiters for tiny catalog entries", () => {
		const context = buildClassifierContext(
			[chunk],
			Array.from({ length: 200 }, (_, index) => ({
				...atom,
				key: `k${index}`,
				text: "xx",
				kind: "context" as const,
			})),
		);
		const payload = JSON.parse(
			(context.messages[0]!.content as Array<{ text: string }>)[0]!.text,
		);
		const serialized = JSON.stringify(payload.priorCatalog);
		expect(payload.priorCatalog).toHaveLength(132);
		expect(Math.ceil(serialized.length / 4)).toBeLessThanOrEqual(
			MAX_PRIOR_CATALOG_TOKENS,
		);
	});

	it("includes an exact serialized catalog boundary but not its next entry", () => {
		const boundary = {
			key: "boundary",
			text: "",
			kind: "decision" as const,
			status: "active" as const,
		};
		const text = "x".repeat(8_190 - JSON.stringify(boundary).length);
		const context = buildClassifierContext(
			[chunk],
			[
				{ ...atom, ...boundary, text, lastSeen: 2 },
				{ ...atom, key: "next", text: "x", kind: "context", lastSeen: 1 },
			],
		);
		const payload = JSON.parse(
			(context.messages[0]!.content as Array<{ text: string }>)[0]!.text,
		);
		expect(payload.priorCatalog).toEqual([{ ...boundary, text }]);
		expect(Math.ceil(JSON.stringify(payload.priorCatalog).length / 4)).toBe(
			MAX_PRIOR_CATALOG_TOKENS,
		);
	});

	it("retains lexical identity candidates including tail evidence and superseded rules", () => {
		const context = buildClassifierContext(
			[
				{
					...chunk,
					text: `${"noise ".repeat(4_096)}release ci tag retry semantics`,
				},
			],
			[
				{
					...atom,
					key: "release-tag-failure-retry-semantics",
					text: "Retry release tag after failure",
					kind: "decision",
					status: "superseded",
					lastSeen: 1,
				},
				{
					...atom,
					key: "release-ci-tag-retry-semantics",
					text: "Do not retry CI release tag",
					kind: "decision",
					status: "active",
					lastSeen: 2,
				},
			],
		);
		const payload = JSON.parse(
			(context.messages[0]!.content as Array<{ text: string }>)[0]!.text,
		);
		expect(
			payload.priorCatalog.map((entry: { key: string }) => entry.key),
		).toEqual([
			"release-ci-tag-retry-semantics",
			"release-tag-failure-retry-semantics",
		]);
		expect(context.systemPrompt).toContain("including for paraphrases");
		expect(context.systemPrompt).toContain(
			"explicitly replaces or invalidates",
		);
	});

	it("keeps permanent policy in system text and one-run focus in untrusted payload", () => {
		const context = buildSummarizerContext([atom], "only this run");
		expect(context.systemPrompt).toContain("Local code has already decided");
		expect(context.systemPrompt).not.toContain("only this run");
		const text = (context.messages[0]!.content as Array<{ text: string }>)[0]!
			.text;
		expect(text).toContain('"oneRunFocus":"only this run"');
		expect(text).toContain('"allocation":40');
		expect(text).toContain("## Critical Context");
	});
});