Phase 5: add skillsPresentInKeptWindow — detect skill blocks in kept user messages.
Scans kept entries for expanded skill blocks so re-inject skips duplicates per SPEC §6.4. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+46
@@ -1,4 +1,5 @@
|
|||||||
import type { SessionEntry } from "@earendil-works/pi-coding-agent";
|
import type { SessionEntry } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { parseSkillBlocksFromText } from "./detect.js";
|
||||||
|
|
||||||
/** Branch slice from firstKeptEntryId through tail (SPEC §6.4). */
|
/** Branch slice from firstKeptEntryId through tail (SPEC §6.4). */
|
||||||
export function getKeptEntries(branch: SessionEntry[], firstKeptEntryId: string): SessionEntry[] {
|
export function getKeptEntries(branch: SessionEntry[], firstKeptEntryId: string): SessionEntry[] {
|
||||||
@@ -8,3 +9,48 @@ export function getKeptEntries(branch: SessionEntry[], firstKeptEntryId: string)
|
|||||||
}
|
}
|
||||||
return branch.slice(startIndex);
|
return branch.slice(startIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractUserMessageText(content: unknown): string {
|
||||||
|
if (typeof content === "string") {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
if (!Array.isArray(content)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const parts: string[] = [];
|
||||||
|
for (const part of content) {
|
||||||
|
if (!part || typeof part !== "object") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const block = part as { type?: string; text?: string };
|
||||||
|
if (block.type === "text" && typeof block.text === "string") {
|
||||||
|
parts.push(block.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Skill names already present as blocks in kept user messages (SPEC §6.4). */
|
||||||
|
export function skillsPresentInKeptWindow(
|
||||||
|
keptEntries: SessionEntry[],
|
||||||
|
skillNames: readonly string[],
|
||||||
|
): Set<string> {
|
||||||
|
const present = new Set<string>();
|
||||||
|
const namesToCheck = new Set(skillNames);
|
||||||
|
if (namesToCheck.size === 0) {
|
||||||
|
return present;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of keptEntries) {
|
||||||
|
if (entry.type !== "message" || entry.message.role !== "user") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const text = extractUserMessageText(entry.message.content);
|
||||||
|
for (const block of parseSkillBlocksFromText(text)) {
|
||||||
|
if (namesToCheck.has(block.name)) {
|
||||||
|
present.add(block.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return present;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user