fix: verdict death — plan→teach seam inferred from first nodeId-tagged quiz
The Accept/Decline verdict gate is gone (owner ruling 2026-09-26): presenting the plan ends the teacher's turn; the learner's next message is a natural reply. Teaching begins at the first quiz call tagged with a nodeId (probe quizzes carry none) — both folds (view phaseAt3, native phaseAt3Lh) advance on the call itself, and the teach divider renders before that whole assistant block. No backwards compat: verdict markers, the verdict input event, optimistic appends, composer buttons, and projection all deleted; prompts and docs rewritten to the natural flow.
This commit is contained in:
@@ -13,13 +13,13 @@
|
||||
* built client-side exactly as today; a dismissal is an answer
|
||||
* carrying its flag). Server-side this becomes the call's
|
||||
* native tool result — fork 1's normal agent history.
|
||||
* verdict — the plan verdict (accept/decline); an optional note is the
|
||||
* learner's own real user message, sent first, exactly the
|
||||
* two-real-messages scheme.
|
||||
* continue — run the next turn on the current record (mount
|
||||
* continuations, job-settle re-syncs: the record ends at an
|
||||
* answered question with no teacher reaction yet).
|
||||
*
|
||||
* (The plan verdict input died 2026-09-26 with the verdict itself — the
|
||||
* learner's post-plan reply is a natural text message.)
|
||||
*
|
||||
* Server-originated delivery (the wake pipeline's steers) is NOT a client
|
||||
* input — the handler accepts it on the same path (TurnInput) so every
|
||||
* turn rides one composition.
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
danglingQuestionOf,
|
||||
newAnswerResult,
|
||||
newUserMessage,
|
||||
newVerdictMessage,
|
||||
} from "./native-messages.ts";
|
||||
import { QUESTION_TOOLS } from "./pending.ts";
|
||||
|
||||
@@ -39,7 +38,6 @@ import { QUESTION_TOOLS } from "./pending.ts";
|
||||
export type ChatInput =
|
||||
| { type: "text"; text: string }
|
||||
| { type: "answer"; toolCallId: string; answer: QuestionAnswerData }
|
||||
| { type: "verdict"; accepted: boolean; note?: string }
|
||||
| { type: "continue" };
|
||||
|
||||
/** A wake-pipeline steer delivery — same turn composition, server-origin.
|
||||
@@ -73,12 +71,6 @@ export function parseChatInput(input: unknown): ChatInput {
|
||||
throw new ChatInputError("answer input requires the graded answer object");
|
||||
}
|
||||
return { type: "answer", toolCallId: i.toolCallId, answer: i.answer as QuestionAnswerData };
|
||||
case "verdict":
|
||||
if (typeof i.accepted !== "boolean") throw new ChatInputError("verdict input requires accepted");
|
||||
if (i.note !== undefined && typeof i.note !== "string") {
|
||||
throw new ChatInputError("verdict note must be a string");
|
||||
}
|
||||
return { type: "verdict", accepted: i.accepted, note: i.note as string | undefined };
|
||||
case "continue":
|
||||
return { type: "continue" };
|
||||
default:
|
||||
@@ -106,14 +98,6 @@ export function inputAppends(record: { messages: LhMessage[] }, input: ChatInput
|
||||
}
|
||||
return [newAnswerResult(input.toolCallId, pending.tool, input.answer)];
|
||||
}
|
||||
case "verdict": {
|
||||
const appends: LhMessage[] = [];
|
||||
if (input.note && input.note.trim().length > 0) {
|
||||
appends.push(newUserMessage(input.note));
|
||||
}
|
||||
appends.push(newVerdictMessage(input.accepted, new Date().toISOString()));
|
||||
return appends;
|
||||
}
|
||||
case "continue":
|
||||
return [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user