fix(session): ignore internal synthetic turns

This commit is contained in:
YeonGyu-Kim
2026-05-15 23:16:05 +09:00
parent e8de8b79a8
commit c580b8f2ce
14 changed files with 464 additions and 80 deletions
+59
View File
@@ -1,7 +1,66 @@
export const OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->"
const INTERNAL_INITIATOR_MARKER_DETECT_PATTERN = /<!--\s*OMO_INTERNAL_INITIATOR\s*-->/
const INTERNAL_INITIATOR_MARKER_PATTERN = /\n*<!--\s*OMO_INTERNAL_INITIATOR\s*-->\s*/g
export type InternalInitiatorTextPartLike = {
type?: string
text?: string
synthetic?: boolean
}
export type InternalInitiatorMessageLike = {
role?: string
info?: { role?: string }
parts?: readonly InternalInitiatorTextPartLike[]
}
export function hasInternalInitiatorMarker(text: string): boolean {
return INTERNAL_INITIATOR_MARKER_DETECT_PATTERN.test(text)
}
export function isTextPartLike(
part: InternalInitiatorTextPartLike
): part is InternalInitiatorTextPartLike & { type: "text"; text: string } {
return part.type === "text" && typeof part.text === "string"
}
export function isSyntheticOrInternalTextPart(
part: InternalInitiatorTextPartLike
): boolean {
return (
isTextPartLike(part) &&
(part.synthetic === true || hasInternalInitiatorMarker(part.text))
)
}
export function isRealUserTextPart(
part: InternalInitiatorTextPartLike
): part is InternalInitiatorTextPartLike & { type: "text"; text: string } {
return isTextPartLike(part) && !isSyntheticOrInternalTextPart(part)
}
export function isSyntheticOrInternalOnlyTextParts(
parts: readonly InternalInitiatorTextPartLike[] | undefined
): boolean {
const textParts = (parts ?? []).filter(isTextPartLike)
return textParts.length > 0 && textParts.every(isSyntheticOrInternalTextPart)
}
export function isSyntheticOrInternalUserMessage(
message: InternalInitiatorMessageLike
): boolean {
const role = message.info?.role ?? message.role
return role === "user" && isSyntheticOrInternalOnlyTextParts(message.parts)
}
export function isRealUserMessage(
message: InternalInitiatorMessageLike
): boolean {
const role = message.info?.role ?? message.role
return role === "user" && !isSyntheticOrInternalUserMessage(message)
}
export function stripInternalInitiatorMarkers(text: string): string {
return text.replace(INTERNAL_INITIATOR_MARKER_PATTERN, "").trimEnd()
}