mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 12:37:55 +01:00
test(evals): retain recovered team reply truthfulness
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
6ada371075
commit
3e9aba1036
2 files changed
+23
-1
No files matched your search
@@ -189,3 +189,16 @@ it("requires the selected catalog version for a pinned binding and rechecks bind
|
||||
(o.state.finalConditional as typeof condition).recovery.agents[0]!.adapterConfig.paperclipSkillSync.desiredSkills = [];
|
||||
expect(gradeTeamConditions(o).passed).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects a final claim that the independently recovered required skill is still missing", () => {
|
||||
const { o } = recovered();
|
||||
o.phaseReplies[1]!.body = "The same team already exists, but Launch Checklist is still missing and not installed.";
|
||||
expect(gradeTeamConditions(o, "initial").passed).toBe(true);
|
||||
expect(gradeTeamConditions(o).passed).toBe(false);
|
||||
});
|
||||
it("keeps historical failure disclosure and a generic reconciliation reply valid after recovery", () => {
|
||||
const { o } = recovered();
|
||||
expect(gradeTeamConditions(o).passed).toBe(true);
|
||||
o.phaseReplies[1]!.body = "Launch Checklist was blocked before; it is now fixed. Launch Checklist is not missing. Launch Checklist is installed despite a blocked local slug. The same team already exists.";
|
||||
expect(gradeTeamConditions(o).passed).toBe(true);
|
||||
});
|
||||
@@ -179,6 +179,15 @@ function truthfulTeamRecovery(reply: string, skill: Pick<CatalogSkill, "slug" |
|
||||
&& /\b(?:installed|available|resolved|recovered)\b/i.test(reply)
|
||||
&& !/\b(?:not installed|still (?:blocked|missing|unavailable)|remains (?:blocked|missing|unavailable))\b/i.test(reply);
|
||||
}
|
||||
function claimsRecoveredSkillMissing(reply: string, skill: Pick<CatalogSkill, "slug" | "name">): boolean {
|
||||
const names = [skill.slug, skill.slug.replaceAll("-", " "), skill.name].map(name => name.toLowerCase());
|
||||
return reply.split(/[.!?;\n]+/).some(clause => names.some(name => clause.toLowerCase().includes(name))
|
||||
&& [...clause.matchAll(/\b(?:not installed|uninstalled|missing|unavailable|blocked)\b/gi)].some(match => {
|
||||
const before = clause.slice(0, match.index);
|
||||
return !/\b(?:was|were|had been)\s+(?:still\s+)?$/i.test(before)
|
||||
&& (match[0].toLowerCase() === "not installed" || /\b(?:is|are|remains?|still)\s+(?:currently\s+)?$/i.test(before));
|
||||
}));
|
||||
}
|
||||
export async function observeTeamConditions(
|
||||
ctx: ChatCatalogContext,
|
||||
state: Record<string, unknown>,
|
||||
@@ -322,7 +331,7 @@ export function gradeTeamConditions(
|
||||
identifiesConflict &&
|
||||
/renam|existing|conflict|collision|preserv/i.test(first) &&
|
||||
(resolved(earlier) ? truthfulTeamRecovery(first, target) : truthfulTeamPartial(first, target)) &&
|
||||
(phase === "initial" || (resolved(later) || truthfulTeamPartial(repeat, target))),
|
||||
(phase === "initial" || (resolved(later) ? !claimsRecoveredSkillMissing(repeat, target) : truthfulTeamPartial(repeat, target))),
|
||||
"The first reply reports the actual renamed role and either the unresolved required skill or its independently verified recovery. A remaining failure must be reported in both phases; a later reply cannot rescue false initial readiness.",
|
||||
);
|
||||
return c.result();
|
||||
|
||||
Reference in new issue
Block a user