Conflict nodes stay server-owned; the Agent writes the question and option copy so users can tap instead of typing through an interrogation. Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
/**
|
|
* Public interview projection for the Case GET payload.
|
|
*
|
|
* The tap card is shown only after the Agent writes prompt/A/B onto the
|
|
* active focus. The server still owns C/D/stop chrome and the discriminator frame.
|
|
*/
|
|
|
|
import { projectRectificationChoiceCard } from "./method-followup";
|
|
import { refinementFromDecisionReceipt } from "./refinement-packet";
|
|
import {
|
|
internalObservationsFromWindowScan,
|
|
windowScanFromDecisionReceipt,
|
|
} from "./varga-observations";
|
|
import type { RectificationChoiceCard } from "./choice-card";
|
|
|
|
export function choiceCardFromCaseDossier(dossier: {
|
|
evidence: readonly Readonly<{
|
|
status: string;
|
|
domain: string;
|
|
datePrecision: string;
|
|
occurredFrom: string | null;
|
|
occurredTo: string | null;
|
|
}>[];
|
|
conversationSummary: {
|
|
activeFocus: {
|
|
intent: string;
|
|
targetDomain: string | null;
|
|
targetKind: string | null;
|
|
expectedAnswerSchema?: Readonly<Record<string, unknown>> | null;
|
|
} | null;
|
|
declinedSkippedTopics: readonly Readonly<Record<string, unknown>>[];
|
|
};
|
|
latestResult: {
|
|
decisionReceipt: Readonly<Record<string, unknown>> | null;
|
|
} | null;
|
|
case: {
|
|
acceptedTime: string | null;
|
|
};
|
|
}): RectificationChoiceCard | null {
|
|
const windowScan = windowScanFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
|
|
const observations = internalObservationsFromWindowScan(windowScan);
|
|
const refinement = refinementFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
|
|
return projectRectificationChoiceCard({
|
|
evidence: dossier.evidence,
|
|
activeFocus: dossier.conversationSummary.activeFocus,
|
|
declinedTopics: dossier.conversationSummary.declinedSkippedTopics,
|
|
observations,
|
|
sessionOutcome: dossier.case.acceptedTime ? "adopt_representative" : "collect_evidence",
|
|
precisionStage: refinement.precision_stage?.current,
|
|
nakshatraBoundary: refinement.nakshatra_boundary,
|
|
oosBlindPrompts: refinement.oos_blind_prompts,
|
|
accepted: Boolean(dossier.case.acceptedTime),
|
|
});
|
|
}
|