fix(compaction): harden continuation directive markers
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import {
|
||||
OMO_INTERNAL_INITIATOR_MARKER,
|
||||
createInternalAgentTextPart,
|
||||
stripInternalInitiatorMarkers,
|
||||
} from "./internal-initiator-marker"
|
||||
|
||||
describe("internal-initiator-marker", () => {
|
||||
describe("createInternalAgentTextPart", () => {
|
||||
test("#given clean text #when creating an internal agent text part #then appends exactly one marker", () => {
|
||||
// given
|
||||
const text = "Hello world"
|
||||
|
||||
// when
|
||||
const part = createInternalAgentTextPart(text)
|
||||
|
||||
// then
|
||||
expect(part.type).toBe("text")
|
||||
expect(part.text).toBe(`Hello world\n${OMO_INTERNAL_INITIATOR_MARKER}`)
|
||||
})
|
||||
|
||||
test("#given text already ending with the marker #when creating a text part #then does not duplicate the marker", () => {
|
||||
// given
|
||||
const text = `Already marked\n${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const part = createInternalAgentTextPart(text)
|
||||
|
||||
// then
|
||||
const markerCount = part.text.split(OMO_INTERNAL_INITIATOR_MARKER).length - 1
|
||||
expect(markerCount).toBe(1)
|
||||
expect(part.text).toBe(`Already marked\n${OMO_INTERNAL_INITIATOR_MARKER}`)
|
||||
})
|
||||
|
||||
test("#given text containing multiple embedded markers #when creating a text part #then collapses to a single trailing marker", () => {
|
||||
// given
|
||||
const text = `First\n${OMO_INTERNAL_INITIATOR_MARKER}\nSecond\n${OMO_INTERNAL_INITIATOR_MARKER}\nThird\n${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const part = createInternalAgentTextPart(text)
|
||||
|
||||
// then
|
||||
const markerCount = part.text.split(OMO_INTERNAL_INITIATOR_MARKER).length - 1
|
||||
expect(markerCount).toBe(1)
|
||||
expect(part.text.endsWith(OMO_INTERNAL_INITIATOR_MARKER)).toBe(true)
|
||||
})
|
||||
|
||||
test("#given text with embedded markers between content #when creating a text part #then strips embedded markers and keeps content", () => {
|
||||
// given
|
||||
const text = `Line one\n${OMO_INTERNAL_INITIATOR_MARKER}\nLine two\n${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const part = createInternalAgentTextPart(text)
|
||||
|
||||
// then
|
||||
expect(part.text).toContain("Line one")
|
||||
expect(part.text).toContain("Line two")
|
||||
const markerCount = part.text.split(OMO_INTERNAL_INITIATOR_MARKER).length - 1
|
||||
expect(markerCount).toBe(1)
|
||||
})
|
||||
|
||||
test("#given empty text #when creating a text part #then still appends a single marker", () => {
|
||||
// given
|
||||
const text = ""
|
||||
|
||||
// when
|
||||
const part = createInternalAgentTextPart(text)
|
||||
|
||||
// then
|
||||
expect(part.text).toBe(`\n${OMO_INTERNAL_INITIATOR_MARKER}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("stripInternalInitiatorMarkers", () => {
|
||||
test("#given text with no markers #when stripping #then returns text trimmed at the end", () => {
|
||||
// given
|
||||
const text = "No markers here"
|
||||
|
||||
// when
|
||||
const result = stripInternalInitiatorMarkers(text)
|
||||
|
||||
// then
|
||||
expect(result).toBe("No markers here")
|
||||
})
|
||||
|
||||
test("#given text with one trailing marker #when stripping #then removes the marker", () => {
|
||||
// given
|
||||
const text = `Content\n${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const result = stripInternalInitiatorMarkers(text)
|
||||
|
||||
// then
|
||||
expect(result).toBe("Content")
|
||||
})
|
||||
|
||||
test("#given text with multiple stacked markers #when stripping #then removes all of them", () => {
|
||||
// given
|
||||
const text = `Content\n${OMO_INTERNAL_INITIATOR_MARKER}\n${OMO_INTERNAL_INITIATOR_MARKER}\n${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const result = stripInternalInitiatorMarkers(text)
|
||||
|
||||
// then
|
||||
expect(result).toBe("Content")
|
||||
})
|
||||
|
||||
test("#given text with markers on consecutive lines without separators #when stripping #then removes all markers", () => {
|
||||
// given
|
||||
const text = `${OMO_INTERNAL_INITIATOR_MARKER}${OMO_INTERNAL_INITIATOR_MARKER}${OMO_INTERNAL_INITIATOR_MARKER}`
|
||||
|
||||
// when
|
||||
const result = stripInternalInitiatorMarkers(text)
|
||||
|
||||
// then
|
||||
expect(result).toBe("")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,11 +1,18 @@
|
||||
export const OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->"
|
||||
|
||||
const INTERNAL_INITIATOR_MARKER_PATTERN = /\n*<!--\s*OMO_INTERNAL_INITIATOR\s*-->\s*/g
|
||||
|
||||
export function stripInternalInitiatorMarkers(text: string): string {
|
||||
return text.replace(INTERNAL_INITIATOR_MARKER_PATTERN, "").trimEnd()
|
||||
}
|
||||
|
||||
export function createInternalAgentTextPart(text: string): {
|
||||
type: "text"
|
||||
text: string
|
||||
} {
|
||||
const cleanText = stripInternalInitiatorMarkers(text)
|
||||
return {
|
||||
type: "text",
|
||||
text: `${text}\n${OMO_INTERNAL_INITIATOR_MARKER}`,
|
||||
text: `${cleanText}\n${OMO_INTERNAL_INITIATOR_MARKER}`,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,50 @@ const x = 1;
|
||||
const directive = ` ${createSystemDirective("TEST")}`
|
||||
expect(isSystemDirective(directive)).toBe(true)
|
||||
})
|
||||
|
||||
test("#given a ralph-loop ULW continuation prefixed with 'ultrawork ' #when checking system directive #then returns true", () => {
|
||||
// given
|
||||
const directive = `ultrawork ${createSystemDirective("RALPH LOOP 2/500")}\n\nYour previous attempt did not output the completion promise.`
|
||||
|
||||
// when
|
||||
const result = isSystemDirective(directive)
|
||||
|
||||
// then
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
test("#given a continuation prefixed with 'ulw ' shorthand #when checking system directive #then returns true", () => {
|
||||
// given
|
||||
const directive = `ulw ${createSystemDirective("ULTRAWORK LOOP VERIFICATION 1/500")}\n\nYou already emitted <promise>DONE</promise>.`
|
||||
|
||||
// when
|
||||
const result = isSystemDirective(directive)
|
||||
|
||||
// then
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
test("#given a continuation prefixed with uppercase 'ULTRAWORK ' #when checking system directive #then returns true", () => {
|
||||
// given
|
||||
const directive = `ULTRAWORK ${createSystemDirective("RALPH LOOP 5/500")}`
|
||||
|
||||
// when
|
||||
const result = isSystemDirective(directive)
|
||||
|
||||
// then
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
test("#given user text that legitimately starts with 'ultrawork' word #when no directive follows #then returns false", () => {
|
||||
// given
|
||||
const text = "ultrawork is a great mode but I have a question about it"
|
||||
|
||||
// when
|
||||
const result = isSystemDirective(text)
|
||||
|
||||
// then
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("integration with keyword detection", () => {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
export const SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: OH-MY-OPENCODE"
|
||||
|
||||
const SYSTEM_DIRECTIVE_LEADING_KEYWORD_PATTERN = /^\s*(?:ultrawork|ulw)\s+/i
|
||||
|
||||
/**
|
||||
* Creates a system directive header with the given type.
|
||||
* @param type - The directive type (e.g., "TODO CONTINUATION", "RALPH LOOP")
|
||||
@@ -23,7 +25,12 @@ export function createSystemDirective(type: string): string {
|
||||
* @returns true if the message is a system directive
|
||||
*/
|
||||
export function isSystemDirective(text: string): boolean {
|
||||
return text.trimStart().startsWith(SYSTEM_DIRECTIVE_PREFIX)
|
||||
const trimmed = text.trimStart()
|
||||
if (trimmed.startsWith(SYSTEM_DIRECTIVE_PREFIX)) {
|
||||
return true
|
||||
}
|
||||
const withoutLeadingKeyword = trimmed.replace(SYSTEM_DIRECTIVE_LEADING_KEYWORD_PATTERN, "")
|
||||
return withoutLeadingKeyword.startsWith(SYSTEM_DIRECTIVE_PREFIX)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user