Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
8.1 kB · 234 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235import type { TUI } from "@earendil-works/pi-tui";import stripAnsi from "strip-ansi";import { beforeAll, describe, expect, test, vi } from "vitest";import { COMPACTION_OUTCOME_CUSTOM_TYPE, type CustomMessage, convertToLlm, createCompactionOutcomeMessage, createManualContinuationMessage, createSessionSlashCommandMessage, createSessionSlashCommandResultMessage, isCompactionOutcomeMessage, isSessionSlashCommandMessage, isSessionSlashCommandResultMessage, MANUAL_CONTINUATION_CUSTOM_TYPE, MANUAL_CONTINUATION_PROMPT, SESSION_SLASH_COMMAND_CUSTOM_TYPE, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE,} from "../src/core/messages.js";import { parseSessionSlashCommand } from "../src/core/slash-commands.js";import { CompactionOutcomeMessageComponent } from "../src/modes/interactive/components/compaction-outcome-message.js";import { buildConversationComponents } from "../src/modes/interactive/components/conversation-components.js";import { SlashCommandMessageComponent } from "../src/modes/interactive/components/slash-command-message.js";import { SlashCommandResultMessageComponent } from "../src/modes/interactive/components/slash-command-result-message.js";import { initTheme } from "../src/modes/interactive/theme/theme.js";
const componentOptions = { ui: { requestRender: vi.fn() } as unknown as TUI, cwd: "/tmp", toolOptions: {}, getToolDefinition: () => undefined,};
function customMessage(customType: string, details?: unknown): CustomMessage { return { role: "custom", customType, content: "durable display text", display: true, details, timestamp: 123, };}
describe("session command messages", () => { beforeAll(() => { initTheme("dark"); });
test("creates and recognizes typed command and result messages", () => { const command = parseSessionSlashCommand("/goal\tship it"); expect(command).toBeDefined(); const commandMessage = createSessionSlashCommandMessage(command!, { commandEntryId: "entry-1" }, true, 123); const attemptedOverwrite = Reflect.apply(createSessionSlashCommandMessage, undefined, [ command!, { command: { name: "compact", args: "", text: "/compact" } }, ]); const resultMessage = createSessionSlashCommandResultMessage( "Goal unavailable", { command: command!, success: false, severity: "warning", error: "Goal unavailable", commandEntryId: "entry-1", }, true, 124, );
expect(commandMessage).toEqual({ role: "custom", customType: SESSION_SLASH_COMMAND_CUSTOM_TYPE, content: "/goal\tship it", display: true, details: { command: { name: "goal", args: "ship it", text: "/goal\tship it" }, commandEntryId: "entry-1", }, timestamp: 123, }); expect(isSessionSlashCommandMessage(commandMessage)).toBe(true); expect(attemptedOverwrite.details.command).toEqual(command); expect(isSessionSlashCommandResultMessage(resultMessage)).toBe(true); expect( isSessionSlashCommandResultMessage({ ...resultMessage, details: { ...resultMessage.details, command: { ...command!, text: "/compact" } }, }), ).toBe(false); expect( isSessionSlashCommandResultMessage({ ...resultMessage, details: { ...resultMessage.details, severity: "fatal" }, }), ).toBe(false); expect( isSessionSlashCommandResultMessage({ ...resultMessage, details: { ...resultMessage.details, success: "no" } }), ).toBe(false); expect( isSessionSlashCommandResultMessage({ ...resultMessage, details: { ...resultMessage.details, commandEntryId: "" }, }), ).toBe(false); expect( isSessionSlashCommandMessage({ ...commandMessage, details: { command: { ...commandMessage.details.command, name: "compact" } }, }), ).toBe(false); expect( isSessionSlashCommandMessage({ ...commandMessage, details: { command: { ...commandMessage.details.command, args: "other" } }, }), ).toBe(false); expect( isSessionSlashCommandMessage({ ...commandMessage, details: { command: { ...commandMessage.details.command, text: "/goal other" } }, }), ).toBe(false); expect(isSessionSlashCommandMessage({ ...commandMessage, timestamp: Number.NaN })).toBe(false); expect( isSessionSlashCommandMessage({ ...commandMessage, details: { ...commandMessage.details, commandEntryId: "" }, }), ).toBe(false); });
test("creates and validates typed compaction outcome messages", () => { const outcome = createCompactionOutcomeMessage( "Requested compaction skipped: too short", { reason: "requested", outcome: "skipped" }, true, 123, );
expect(outcome).toEqual({ role: "custom", customType: COMPACTION_OUTCOME_CUSTOM_TYPE, content: "Requested compaction skipped: too short", display: true, details: { reason: "requested", outcome: "skipped" }, timestamp: 123, }); expect(isCompactionOutcomeMessage(outcome)).toBe(true); expect(isCompactionOutcomeMessage({ ...outcome, details: { reason: "manual", outcome: "skipped" } })).toBe(false); expect(isCompactionOutcomeMessage({ ...outcome, details: { reason: "requested", outcome: "success" } })).toBe( false, ); expect(isCompactionOutcomeMessage({ ...outcome, timestamp: Number.NaN })).toBe(false); });
test("excludes durable command, result, and compaction outcome entries from LLM context", () => { const command = parseSessionSlashCommand("/compact"); expect(command).toBeDefined();
expect( convertToLlm([ createSessionSlashCommandMessage(command!), createSessionSlashCommandResultMessage("Skipped", { command: command!, success: false, severity: "warning", }), customMessage(SESSION_SLASH_COMMAND_CUSTOM_TYPE), customMessage(SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE), customMessage(COMPACTION_OUTCOME_CUSTOM_TYPE), ]), ).toEqual([]); });
test("converts manual continuation into hidden model context", () => { const message = createManualContinuationMessage(123);
expect(message).toEqual({ role: "custom", customType: MANUAL_CONTINUATION_CUSTOM_TYPE, content: MANUAL_CONTINUATION_PROMPT, display: false, timestamp: 123, }); expect(convertToLlm([message])).toEqual([ { role: "user", content: [{ type: "text", text: MANUAL_CONTINUATION_PROMPT }], timestamp: 123, }, ]); expect(buildConversationComponents([message], componentOptions)).toEqual([]); });
test("continues to include ordinary custom messages", () => { expect(convertToLlm([customMessage("extension_notice")])).toMatchObject([ { role: "user", content: [{ type: "text", text: "durable display text" }] }, ]); });
test("dispatches valid messages and safely diagnoses malformed reserved entries", () => { const command = parseSessionSlashCommand("/compact focus"); expect(command).toBeDefined(); const components = buildConversationComponents( [ createSessionSlashCommandMessage(command!), createSessionSlashCommandResultMessage("Compaction skipped", { command: command!, success: false, severity: "warning", }), createCompactionOutcomeMessage("Auto-compaction skipped", { reason: "threshold", outcome: "skipped", }), customMessage(SESSION_SLASH_COMMAND_CUSTOM_TYPE, { command: "not-a-command" }), customMessage(SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE, { severity: "fatal" }), customMessage(COMPACTION_OUTCOME_CUSTOM_TYPE, { reason: "manual", outcome: "skipped" }), ], componentOptions, ); const output = stripAnsi(components.flatMap((component) => component.render(80)).join("\n"));
expect(components[0]).toBeInstanceOf(SlashCommandMessageComponent); expect(components[1]).toBeInstanceOf(SlashCommandResultMessageComponent); expect(components[2]).toBeInstanceOf(CompactionOutcomeMessageComponent); expect(output).toContain("Compaction skipped"); expect(output).toContain("Auto-compaction skipped"); expect(output.match(/\[Malformed session command message\]/g)).toHaveLength(2); expect(output).toContain("[Malformed compaction outcome message]"); expect(output).not.toContain("durable display text"); });});