2026-03-10 19:19:23 +00:00
|
|
|
import type { FeedItem } from "@aelis/core"
|
2026-03-05 02:01:30 +00:00
|
|
|
|
|
|
|
|
import type { EnhancementResult } from "./schema.ts"
|
|
|
|
|
|
2026-03-14 23:51:41 +00:00
|
|
|
const ENHANCEMENT_SOURCE_ID = "aelis.enhancement"
|
|
|
|
|
|
2026-03-05 02:01:30 +00:00
|
|
|
/**
|
|
|
|
|
* Merges an EnhancementResult into feed items.
|
|
|
|
|
*
|
|
|
|
|
* - Writes slot content from slotFills into matching items
|
|
|
|
|
* - Appends synthetic items to the list
|
|
|
|
|
* - Returns a new array (no mutation)
|
|
|
|
|
* - Ignores fills for items/slots that don't exist
|
|
|
|
|
*/
|
2026-03-14 23:51:41 +00:00
|
|
|
export function mergeEnhancement(
|
|
|
|
|
items: FeedItem[],
|
|
|
|
|
result: EnhancementResult,
|
|
|
|
|
currentTime: Date,
|
|
|
|
|
): FeedItem[] {
|
2026-03-05 02:01:30 +00:00
|
|
|
const merged = items.map((item) => {
|
|
|
|
|
const fills = result.slotFills[item.id]
|
|
|
|
|
if (!fills || !item.slots) return item
|
|
|
|
|
|
|
|
|
|
const mergedSlots = { ...item.slots }
|
|
|
|
|
let changed = false
|
|
|
|
|
|
|
|
|
|
for (const [slotName, content] of Object.entries(fills)) {
|
|
|
|
|
if (slotName in mergedSlots && content !== null) {
|
|
|
|
|
mergedSlots[slotName] = { ...mergedSlots[slotName]!, content }
|
|
|
|
|
changed = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed ? { ...item, slots: mergedSlots } : item
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
for (const synthetic of result.syntheticItems) {
|
|
|
|
|
merged.push({
|
|
|
|
|
id: synthetic.id,
|
2026-03-14 23:51:41 +00:00
|
|
|
sourceId: ENHANCEMENT_SOURCE_ID,
|
2026-03-05 02:01:30 +00:00
|
|
|
type: synthetic.type,
|
|
|
|
|
timestamp: currentTime,
|
|
|
|
|
data: { text: synthetic.text },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return merged
|
|
|
|
|
}
|