Accept concrete clarification requests without question punctuation

This commit is contained in:
Dotta 2026-09-11 14:58:51 -05:00
parent 6dc0efd6db
commit 6b26534610
2 changed files with 30 additions and 1 deletions

View File

@ -9,6 +9,7 @@ import {
collectChatRunEvidence,
readRunningChatLog,
readChatOutputDocument,
isChatClarificationReply,
isResetRun,
type ChatIssue,
type ChatRun,
@ -44,6 +45,25 @@ const run: ChatRun = {
startedAt: "2026-09-11T10:00:01Z",
};
describe("chat acceptance contracts", () => {
it("accepts concrete information requests without requiring question punctuation", () => {
expect(isChatClarificationReply("What is the club name?")).toBe(true);
expect(
isChatClarificationReply(
"Before assigning the welcome-note work, please share:\n\n1. Club name and intended readers.\n2. Format, length, and tone.\n3. Required details, sender, and deadline.",
),
).toBe(true);
expect(
isChatClarificationReply("Tell me the intended audience and format."),
).toBe(true);
expect(isChatClarificationReply("Please share:")).toBe(false);
expect(
isChatClarificationReply("Asked the user clarifying questions about their club."),
).toBe(false);
expect(
isChatClarificationReply("I created the task and started writing the welcome note."),
).toBe(false);
});
it("keeps chat markers literal across rich-text and Markdown boundaries", () => {
for (const prefix of ["CHAT", "DRAFT", "OLDCONTEXT"] as const) {
expect(chatMarker(prefix, "abc123-1")).toBe(`${prefix}abc1231`);

View File

@ -48,6 +48,15 @@ type Comment = {
type Plan = { body: string; latestRevisionId: string; updatedAt: string };
type ChatOutputDocument = Plan & { id: string; issueId: string; key: string };
/** Clarification may request information imperatively rather than end in a question mark. */
export function isChatClarificationReply(body: string): boolean {
if (body.includes("?")) return true;
const request = body.match(
/\b(?:please\s+(?:share|provide|clarify|confirm)|tell me|let me know)\b([\s\S]*)/i,
);
return Boolean(request?.[1].replace(/[\s:*-]/g, ""));
}
/** A requested output document may have a descriptive key; a copied plan is not output. */
export async function readChatOutputDocument(
api: Pick<RunnerApi, "get">,
@ -446,7 +455,7 @@ export async function runChatFlow(input: {
expect(
Boolean(pendingQuestions?.length) ||
(await comments()).some(
(c) => c.authorAgentId && c.body.includes("?"),
(c) => c.authorAgentId && isChatClarificationReply(c.body),
),
).toBe(true);
const clarification = `It is the garden club; use the existing Garden ${nonce} project. Make one assigned task for yourself to write a two-sentence welcome note. Include ${marker} in that note, save it as the output document, and finish that execution task. Please get it started now.`;