АРЧ АП11 - Добавить state transition owner для assistant runtime

This commit is contained in:
dctouch 2026-04-15 23:27:33 +03:00
parent 89bcaccda8
commit 5f628f427f
12 changed files with 853 additions and 8 deletions

View File

@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.runAssistantAddressLaneResponseRuntime = runAssistantAddressLaneResponseRuntime; exports.runAssistantAddressLaneResponseRuntime = runAssistantAddressLaneResponseRuntime;
const assistantAddressTurnFinalizeRuntimeAdapter_1 = require("./assistantAddressTurnFinalizeRuntimeAdapter"); const assistantAddressTurnFinalizeRuntimeAdapter_1 = require("./assistantAddressTurnFinalizeRuntimeAdapter");
const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver"); const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver");
const assistantStateTransitionRuntimeAdapter_1 = require("./assistantStateTransitionRuntimeAdapter");
const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter"); const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter");
function toRecordObject(value) { function toRecordObject(value) {
if (!value || typeof value !== "object") { if (!value || typeof value !== "object") {
@ -197,6 +198,10 @@ function runAssistantAddressLaneResponseRuntime(input) {
addressRuntimeMeta: input.llmPreDecomposeMeta, addressRuntimeMeta: input.llmPreDecomposeMeta,
replyType: normalizeAddressReplyType(input.addressLane.reply_type) replyType: normalizeAddressReplyType(input.addressLane.reply_type)
}); });
const debugWithStateTransition = (0, assistantStateTransitionRuntimeAdapter_1.attachAssistantStateTransition)(debugWithTruthAnswerPolicy, {
addressRuntimeMeta: input.llmPreDecomposeMeta,
replyType: normalizeAddressReplyType(input.addressLane.reply_type)
});
const finalization = finalizeAddressTurnSafe({ const finalization = finalizeAddressTurnSafe({
sessionId: input.sessionId, sessionId: input.sessionId,
userMessage: input.userMessage, userMessage: input.userMessage,
@ -204,7 +209,7 @@ function runAssistantAddressLaneResponseRuntime(input) {
assistantReply: safeAddressReply, assistantReply: safeAddressReply,
replyType: normalizeAddressReplyType(input.addressLane.reply_type), replyType: normalizeAddressReplyType(input.addressLane.reply_type),
addressLaneDebug: normalizeAddressLaneDebug(input.addressLane.debug), addressLaneDebug: normalizeAddressLaneDebug(input.addressLane.debug),
debug: debugWithTruthAnswerPolicy, debug: debugWithStateTransition,
carryoverMeta: normalizeCarryoverMeta(input.carryoverMeta), carryoverMeta: normalizeCarryoverMeta(input.carryoverMeta),
llmPreDecomposeMeta: normalizeLlmPreDecomposeMeta(input.llmPreDecomposeMeta), llmPreDecomposeMeta: normalizeLlmPreDecomposeMeta(input.llmPreDecomposeMeta),
appendItem: input.appendItem, appendItem: input.appendItem,
@ -216,6 +221,6 @@ function runAssistantAddressLaneResponseRuntime(input) {
}); });
return { return {
response: finalization.response, response: finalization.response,
debug: debugWithTruthAnswerPolicy debug: debugWithStateTransition
}; };
} }

View File

@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.buildDeepAnalysisDebugPayload = buildDeepAnalysisDebugPayload; exports.buildDeepAnalysisDebugPayload = buildDeepAnalysisDebugPayload;
const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver"); const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver");
const assistantStateTransitionRuntimeAdapter_1 = require("./assistantStateTransitionRuntimeAdapter");
const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter"); const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter");
const assistantStage4AnswerContractAudit_1 = require("./assistantStage4AnswerContractAudit"); const assistantStage4AnswerContractAudit_1 = require("./assistantStage4AnswerContractAudit");
function toAnalysisContext(input) { function toAnalysisContext(input) {
@ -99,7 +100,13 @@ function buildDeepAnalysisDebugPayload(input) {
addressRuntimeMeta: input.addressRuntimeMetaForDeep, addressRuntimeMeta: input.addressRuntimeMetaForDeep,
groundingStatus: input.groundingCheck.status groundingStatus: input.groundingCheck.status
}); });
return (0, assistantTruthAnswerPolicyRuntimeAdapter_1.attachAssistantTruthAnswerPolicy)(debugWithRuntimeContracts, { const debugWithTruthAnswerPolicy = (0, assistantTruthAnswerPolicyRuntimeAdapter_1.attachAssistantTruthAnswerPolicy)(debugWithRuntimeContracts, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep,
groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport,
replyType: "deep_analysis"
});
return (0, assistantStateTransitionRuntimeAdapter_1.attachAssistantStateTransition)(debugWithTruthAnswerPolicy, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep, addressRuntimeMeta: input.addressRuntimeMetaForDeep,
groundingStatus: input.groundingCheck.status, groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport, coverageReport: input.coverageReport,

View File

@ -0,0 +1,265 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveAssistantStateTransitionRuntime = resolveAssistantStateTransitionRuntime;
exports.buildAssistantStateTransitionRuntimeFields = buildAssistantStateTransitionRuntimeFields;
exports.attachAssistantStateTransition = attachAssistantStateTransition;
const assistantRuntimeContracts_1 = require("../types/assistantRuntimeContracts");
const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver");
const assistantRuntimeContractRegistry_1 = require("./assistantRuntimeContractRegistry");
const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter");
function toRecordObject(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return null;
}
return value;
}
function toNonEmptyString(value) {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function uniqueStrings(values) {
return Array.from(new Set(values.filter((item) => item.trim().length > 0)));
}
function baseStateActions() {
return {
living_mode_state: "none",
root_frame_state: "none",
selected_object_frame_state: "none",
meta_frame_state: "none",
clarification_state: "none",
coverage_gate_state: "none",
answer_context_state: "none"
};
}
function stateActionsFor(transitionId) {
const actions = baseStateActions();
if (!transitionId) {
return actions;
}
actions.living_mode_state = "update";
actions.coverage_gate_state = "create";
if (transitionId === "T1") {
return {
...actions,
root_frame_state: "create",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T2") {
return {
...actions,
root_frame_state: "update",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T3") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "create",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T4" || transitionId === "T5") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "reuse",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T6") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T7") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "none",
clarification_state: "update",
answer_context_state: "none"
};
}
if (transitionId === "T8") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "create",
clarification_state: "none",
answer_context_state: "reuse"
};
}
if (transitionId === "T9") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "create",
clarification_state: "none",
coverage_gate_state: "preserve",
answer_context_state: "reuse"
};
}
return {
...actions,
root_frame_state: "none",
selected_object_frame_state: "clear",
meta_frame_state: "none",
clarification_state: "none",
coverage_gate_state: "block",
answer_context_state: "none"
};
}
function applicationStatusFor(input) {
if (!input.transitionId) {
return "unresolved";
}
if (input.coverageGateState.truth_mode === "clarification_required") {
return "clarification_required";
}
if (input.transitionId === "T10" || input.coverageGateState.coverage_status === "blocked" || input.coverageGateState.truth_mode === "unsupported") {
return "blocked";
}
return "applied";
}
function effectiveCarryoverDepthFor(input) {
if (input.status === "unresolved" || input.status === "blocked") {
return "none";
}
if (!input.declared) {
return input.truthGate;
}
if (input.status === "clarification_required") {
return input.declared === "full" ? "full" : input.truthGate;
}
if (input.truthGate === "none") {
return "none";
}
if (input.declared === "full") {
return input.truthGate;
}
if (input.truthGate === "full") {
return input.declared;
}
return input.declared === input.truthGate ? input.declared : "none";
}
function resolveShadow(input, debug) {
return (input.runtimeContractShadow ??
toRecordObject(debug.assistant_runtime_contract_v1) ??
(0, assistantRuntimeContractResolver_1.resolveAssistantRuntimeContractShadow)({
addressDebug: debug,
addressRuntimeMeta: input.addressRuntimeMeta,
groundingStatus: input.groundingStatus
}));
}
function resolveTruthPolicy(input, debug) {
return (input.truthAnswerPolicy ??
toRecordObject(debug.assistant_truth_answer_policy_v1) ??
(0, assistantTruthAnswerPolicyRuntimeAdapter_1.resolveAssistantTruthAnswerPolicyRuntime)({
addressDebug: debug,
addressRuntimeMeta: input.addressRuntimeMeta,
groundingStatus: input.groundingStatus,
coverageReport: input.coverageReport,
replyType: input.replyType
}));
}
function reasonCodesFor(input) {
return uniqueStrings([
`transition_status_${input.applicationStatus}`,
...(input.transitionId ? [`transition_${input.transitionId}`] : ["transition_unresolved"]),
...input.shadow.transition_contract_reason,
...input.shadow.capability_contract_reason,
...input.truthPolicy.truth_gate.reason_codes
]).slice(0, 40);
}
function resolveAssistantStateTransitionRuntime(input) {
const debug = toRecordObject(input.addressDebug) ?? {};
const shadow = resolveShadow(input, debug);
const truthPolicy = resolveTruthPolicy(input, debug);
const transitionId = shadow.transition_contract_id;
const transition = transitionId ? (0, assistantRuntimeContractRegistry_1.getAssistantTransitionContract)(transitionId) : null;
const status = applicationStatusFor({
transitionId,
coverageGateState: truthPolicy.truth_gate
});
const effectiveCarryoverDepth = effectiveCarryoverDepthFor({
declared: transition?.allowed_carryover_depth ?? null,
truthGate: truthPolicy.truth_gate.carryover_eligibility,
status
});
const forbiddenCarryover = uniqueStrings([
...(transition?.forbidden_carryover ?? []),
...(status === "blocked" ? ["blocked_as_confirmed_factual_answer"] : []),
...(effectiveCarryoverDepth === "none" ? ["implicit_followup_reuse"] : [])
]);
return {
schema_version: assistantRuntimeContracts_1.ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION,
state_owner: "assistantStateTransitionRuntimeAdapter",
transition_id: transitionId,
transition_title: transition?.title ?? shadow.transition_contract_title,
application_status: status,
declared_carryover_depth: transition?.allowed_carryover_depth ?? null,
truth_gate_carryover_depth: truthPolicy.truth_gate.carryover_eligibility,
effective_carryover_depth: effectiveCarryoverDepth,
required_prior_state: transition?.required_prior_state ?? [],
expected_answer_mode: transition?.expected_answer_mode ?? null,
state_mutations: transition?.state_mutations ?? [],
forbidden_carryover: forbiddenCarryover,
state_actions: stateActionsFor(transitionId),
coverage_gate_state: {
coverage_status: truthPolicy.truth_gate.coverage_status,
evidence_grade: truthPolicy.truth_gate.evidence_grade,
grounding_status: truthPolicy.truth_gate.grounding_status,
truth_mode: truthPolicy.truth_gate.truth_mode,
carryover_eligibility: truthPolicy.truth_gate.carryover_eligibility,
reason_codes: truthPolicy.truth_gate.reason_codes
},
reason_codes: reasonCodesFor({
shadow,
truthPolicy,
transitionId,
applicationStatus: status
})
};
}
function buildAssistantStateTransitionRuntimeFields(input) {
const transition = resolveAssistantStateTransitionRuntime(input);
return {
assistant_state_transition_v1: transition,
state_transition_contract: transition,
state_transition_id: transition.transition_id,
state_transition_status: transition.application_status,
effective_carryover_depth: transition.effective_carryover_depth
};
}
function attachAssistantStateTransition(debugPayload, input) {
return {
...debugPayload,
...buildAssistantStateTransitionRuntimeFields({
...input,
addressDebug: debugPayload
})
};
}

View File

@ -1,5 +1,6 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = exports.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = void 0; exports.ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION = exports.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = exports.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = void 0;
exports.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = "assistant_runtime_contracts_v1"; exports.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = "assistant_runtime_contracts_v1";
exports.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = "assistant_truth_answer_policy_runtime_v1"; exports.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = "assistant_truth_answer_policy_runtime_v1";
exports.ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION = "assistant_state_transition_runtime_v1";

View File

@ -8,6 +8,7 @@ import {
type FinalizeAssistantAddressTurnInput type FinalizeAssistantAddressTurnInput
} from "./assistantAddressTurnFinalizeRuntimeAdapter"; } from "./assistantAddressTurnFinalizeRuntimeAdapter";
import { attachAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver"; import { attachAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver";
import { attachAssistantStateTransition } from "./assistantStateTransitionRuntimeAdapter";
import { attachAssistantTruthAnswerPolicy } from "./assistantTruthAnswerPolicyRuntimeAdapter"; import { attachAssistantTruthAnswerPolicy } from "./assistantTruthAnswerPolicyRuntimeAdapter";
export interface RunAssistantAddressLaneResponseRuntimeInput<ResponseType = AssistantMessageResponsePayload> { export interface RunAssistantAddressLaneResponseRuntimeInput<ResponseType = AssistantMessageResponsePayload> {
@ -256,6 +257,10 @@ export function runAssistantAddressLaneResponseRuntime<ResponseType = AssistantM
addressRuntimeMeta: input.llmPreDecomposeMeta, addressRuntimeMeta: input.llmPreDecomposeMeta,
replyType: normalizeAddressReplyType(input.addressLane.reply_type) replyType: normalizeAddressReplyType(input.addressLane.reply_type)
}); });
const debugWithStateTransition = attachAssistantStateTransition(debugWithTruthAnswerPolicy, {
addressRuntimeMeta: input.llmPreDecomposeMeta,
replyType: normalizeAddressReplyType(input.addressLane.reply_type)
});
const finalization = finalizeAddressTurnSafe({ const finalization = finalizeAddressTurnSafe({
sessionId: input.sessionId, sessionId: input.sessionId,
userMessage: input.userMessage, userMessage: input.userMessage,
@ -263,7 +268,7 @@ export function runAssistantAddressLaneResponseRuntime<ResponseType = AssistantM
assistantReply: safeAddressReply, assistantReply: safeAddressReply,
replyType: normalizeAddressReplyType(input.addressLane.reply_type), replyType: normalizeAddressReplyType(input.addressLane.reply_type),
addressLaneDebug: normalizeAddressLaneDebug(input.addressLane.debug), addressLaneDebug: normalizeAddressLaneDebug(input.addressLane.debug),
debug: debugWithTruthAnswerPolicy, debug: debugWithStateTransition,
carryoverMeta: normalizeCarryoverMeta(input.carryoverMeta), carryoverMeta: normalizeCarryoverMeta(input.carryoverMeta),
llmPreDecomposeMeta: normalizeLlmPreDecomposeMeta(input.llmPreDecomposeMeta), llmPreDecomposeMeta: normalizeLlmPreDecomposeMeta(input.llmPreDecomposeMeta),
appendItem: input.appendItem, appendItem: input.appendItem,
@ -276,6 +281,6 @@ export function runAssistantAddressLaneResponseRuntime<ResponseType = AssistantM
return { return {
response: finalization.response as ResponseType, response: finalization.response as ResponseType,
debug: debugWithTruthAnswerPolicy debug: debugWithStateTransition
}; };
} }

View File

@ -24,6 +24,7 @@ import type {
TemporalGuardAudit TemporalGuardAudit
} from "./assistantRuntimeGuards"; } from "./assistantRuntimeGuards";
import { attachAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver"; import { attachAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver";
import { attachAssistantStateTransition } from "./assistantStateTransitionRuntimeAdapter";
import { attachAssistantTruthAnswerPolicy } from "./assistantTruthAnswerPolicyRuntimeAdapter"; import { attachAssistantTruthAnswerPolicy } from "./assistantTruthAnswerPolicyRuntimeAdapter";
import { buildStage4AnswerContractAuditV1 } from "./assistantStage4AnswerContractAudit"; import { buildStage4AnswerContractAuditV1 } from "./assistantStage4AnswerContractAudit";
@ -179,7 +180,13 @@ export function buildDeepAnalysisDebugPayload(input: DeepAnalysisDebugPayloadInp
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined, addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status groundingStatus: input.groundingCheck.status
}); });
return attachAssistantTruthAnswerPolicy(debugWithRuntimeContracts, { const debugWithTruthAnswerPolicy = attachAssistantTruthAnswerPolicy(debugWithRuntimeContracts, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport as unknown as Record<string, unknown>,
replyType: "deep_analysis"
});
return attachAssistantStateTransition(debugWithTruthAnswerPolicy, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined, addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status, groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport as unknown as Record<string, unknown>, coverageReport: input.coverageReport as unknown as Record<string, unknown>,

View File

@ -0,0 +1,331 @@
import {
ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION,
type AssistantCarryoverDepth,
type AssistantCoverageGateState,
type AssistantRuntimeContractShadowDecision,
type AssistantStateTransitionApplicationStatus,
type AssistantStateTransitionRuntimeContract,
type AssistantTruthAnswerPolicyRuntimeContract,
type AssistantTransitionClassId
} from "../types/assistantRuntimeContracts";
import { resolveAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver";
import { getAssistantTransitionContract } from "./assistantRuntimeContractRegistry";
import { resolveAssistantTruthAnswerPolicyRuntime } from "./assistantTruthAnswerPolicyRuntimeAdapter";
export interface ResolveAssistantStateTransitionRuntimeInput {
addressDebug?: Record<string, unknown> | null;
addressRuntimeMeta?: Record<string, unknown> | null;
groundingStatus?: unknown;
coverageReport?: Record<string, unknown> | null;
replyType?: unknown;
runtimeContractShadow?: AssistantRuntimeContractShadowDecision | null;
truthAnswerPolicy?: AssistantTruthAnswerPolicyRuntimeContract | null;
}
export interface AssistantStateTransitionRuntimeFields {
assistant_state_transition_v1: AssistantStateTransitionRuntimeContract;
state_transition_contract: AssistantStateTransitionRuntimeContract;
state_transition_id: AssistantTransitionClassId | null;
state_transition_status: AssistantStateTransitionApplicationStatus;
effective_carryover_depth: AssistantCarryoverDepth;
}
function toRecordObject(value: unknown): Record<string, unknown> | null {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return null;
}
return value as Record<string, unknown>;
}
function toNonEmptyString(value: unknown): string | null {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function uniqueStrings(values: string[]): string[] {
return Array.from(new Set(values.filter((item) => item.trim().length > 0)));
}
function baseStateActions(): AssistantStateTransitionRuntimeContract["state_actions"] {
return {
living_mode_state: "none",
root_frame_state: "none",
selected_object_frame_state: "none",
meta_frame_state: "none",
clarification_state: "none",
coverage_gate_state: "none",
answer_context_state: "none"
};
}
function stateActionsFor(transitionId: AssistantTransitionClassId | null): AssistantStateTransitionRuntimeContract["state_actions"] {
const actions = baseStateActions();
if (!transitionId) {
return actions;
}
actions.living_mode_state = "update";
actions.coverage_gate_state = "create";
if (transitionId === "T1") {
return {
...actions,
root_frame_state: "create",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T2") {
return {
...actions,
root_frame_state: "update",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T3") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "create",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T4" || transitionId === "T5") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "reuse",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T6") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "clear",
meta_frame_state: "clear",
clarification_state: "clear",
answer_context_state: "create"
};
}
if (transitionId === "T7") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "none",
clarification_state: "update",
answer_context_state: "none"
};
}
if (transitionId === "T8") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "create",
clarification_state: "none",
answer_context_state: "reuse"
};
}
if (transitionId === "T9") {
return {
...actions,
root_frame_state: "preserve",
selected_object_frame_state: "preserve",
meta_frame_state: "create",
clarification_state: "none",
coverage_gate_state: "preserve",
answer_context_state: "reuse"
};
}
return {
...actions,
root_frame_state: "none",
selected_object_frame_state: "clear",
meta_frame_state: "none",
clarification_state: "none",
coverage_gate_state: "block",
answer_context_state: "none"
};
}
function applicationStatusFor(input: {
transitionId: AssistantTransitionClassId | null;
coverageGateState: AssistantCoverageGateState;
}): AssistantStateTransitionApplicationStatus {
if (!input.transitionId) {
return "unresolved";
}
if (input.coverageGateState.truth_mode === "clarification_required") {
return "clarification_required";
}
if (input.transitionId === "T10" || input.coverageGateState.coverage_status === "blocked" || input.coverageGateState.truth_mode === "unsupported") {
return "blocked";
}
return "applied";
}
function effectiveCarryoverDepthFor(input: {
declared: AssistantCarryoverDepth | null;
truthGate: AssistantCarryoverDepth;
status: AssistantStateTransitionApplicationStatus;
}): AssistantCarryoverDepth {
if (input.status === "unresolved" || input.status === "blocked") {
return "none";
}
if (!input.declared) {
return input.truthGate;
}
if (input.status === "clarification_required") {
return input.declared === "full" ? "full" : input.truthGate;
}
if (input.truthGate === "none") {
return "none";
}
if (input.declared === "full") {
return input.truthGate;
}
if (input.truthGate === "full") {
return input.declared;
}
return input.declared === input.truthGate ? input.declared : "none";
}
function resolveShadow(
input: ResolveAssistantStateTransitionRuntimeInput,
debug: Record<string, unknown>
): AssistantRuntimeContractShadowDecision {
return (
input.runtimeContractShadow ??
(toRecordObject(debug.assistant_runtime_contract_v1) as AssistantRuntimeContractShadowDecision | null) ??
resolveAssistantRuntimeContractShadow({
addressDebug: debug,
addressRuntimeMeta: input.addressRuntimeMeta,
groundingStatus: input.groundingStatus
})
);
}
function resolveTruthPolicy(
input: ResolveAssistantStateTransitionRuntimeInput,
debug: Record<string, unknown>
): AssistantTruthAnswerPolicyRuntimeContract {
return (
input.truthAnswerPolicy ??
(toRecordObject(debug.assistant_truth_answer_policy_v1) as AssistantTruthAnswerPolicyRuntimeContract | null) ??
resolveAssistantTruthAnswerPolicyRuntime({
addressDebug: debug,
addressRuntimeMeta: input.addressRuntimeMeta,
groundingStatus: input.groundingStatus,
coverageReport: input.coverageReport,
replyType: input.replyType
})
);
}
function reasonCodesFor(input: {
shadow: AssistantRuntimeContractShadowDecision;
truthPolicy: AssistantTruthAnswerPolicyRuntimeContract;
transitionId: AssistantTransitionClassId | null;
applicationStatus: AssistantStateTransitionApplicationStatus;
}): string[] {
return uniqueStrings([
`transition_status_${input.applicationStatus}`,
...(input.transitionId ? [`transition_${input.transitionId}`] : ["transition_unresolved"]),
...input.shadow.transition_contract_reason,
...input.shadow.capability_contract_reason,
...input.truthPolicy.truth_gate.reason_codes
]).slice(0, 40);
}
export function resolveAssistantStateTransitionRuntime(
input: ResolveAssistantStateTransitionRuntimeInput
): AssistantStateTransitionRuntimeContract {
const debug = toRecordObject(input.addressDebug) ?? {};
const shadow = resolveShadow(input, debug);
const truthPolicy = resolveTruthPolicy(input, debug);
const transitionId = shadow.transition_contract_id;
const transition = transitionId ? getAssistantTransitionContract(transitionId) : null;
const status = applicationStatusFor({
transitionId,
coverageGateState: truthPolicy.truth_gate
});
const effectiveCarryoverDepth = effectiveCarryoverDepthFor({
declared: transition?.allowed_carryover_depth ?? null,
truthGate: truthPolicy.truth_gate.carryover_eligibility,
status
});
const forbiddenCarryover = uniqueStrings([
...(transition?.forbidden_carryover ?? []),
...(status === "blocked" ? ["blocked_as_confirmed_factual_answer"] : []),
...(effectiveCarryoverDepth === "none" ? ["implicit_followup_reuse"] : [])
]);
return {
schema_version: ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION,
state_owner: "assistantStateTransitionRuntimeAdapter",
transition_id: transitionId,
transition_title: transition?.title ?? shadow.transition_contract_title,
application_status: status,
declared_carryover_depth: transition?.allowed_carryover_depth ?? null,
truth_gate_carryover_depth: truthPolicy.truth_gate.carryover_eligibility,
effective_carryover_depth: effectiveCarryoverDepth,
required_prior_state: transition?.required_prior_state ?? [],
expected_answer_mode: transition?.expected_answer_mode ?? null,
state_mutations: transition?.state_mutations ?? [],
forbidden_carryover: forbiddenCarryover,
state_actions: stateActionsFor(transitionId),
coverage_gate_state: {
coverage_status: truthPolicy.truth_gate.coverage_status,
evidence_grade: truthPolicy.truth_gate.evidence_grade,
grounding_status: truthPolicy.truth_gate.grounding_status,
truth_mode: truthPolicy.truth_gate.truth_mode,
carryover_eligibility: truthPolicy.truth_gate.carryover_eligibility,
reason_codes: truthPolicy.truth_gate.reason_codes
},
reason_codes: reasonCodesFor({
shadow,
truthPolicy,
transitionId,
applicationStatus: status
})
};
}
export function buildAssistantStateTransitionRuntimeFields(
input: ResolveAssistantStateTransitionRuntimeInput
): AssistantStateTransitionRuntimeFields {
const transition = resolveAssistantStateTransitionRuntime(input);
return {
assistant_state_transition_v1: transition,
state_transition_contract: transition,
state_transition_id: transition.transition_id,
state_transition_status: transition.application_status,
effective_carryover_depth: transition.effective_carryover_depth
};
}
export function attachAssistantStateTransition<T extends Record<string, unknown>>(
debugPayload: T,
input: Omit<ResolveAssistantStateTransitionRuntimeInput, "addressDebug">
): T & AssistantStateTransitionRuntimeFields {
return {
...debugPayload,
...buildAssistantStateTransitionRuntimeFields({
...input,
addressDebug: debugPayload
})
};
}

View File

@ -20,6 +20,8 @@ import type { AddressNavigationState } from "./addressNavigation";
import type { import type {
AssistantAnswerShapeKind, AssistantAnswerShapeKind,
AssistantRuntimeContractShadowDecision, AssistantRuntimeContractShadowDecision,
AssistantStateTransitionApplicationStatus,
AssistantStateTransitionRuntimeContract,
AssistantTruthAnswerPolicyRuntimeContract, AssistantTruthAnswerPolicyRuntimeContract,
AssistantTruthMode, AssistantTruthMode,
AssistantTransitionClassId AssistantTransitionClassId
@ -463,6 +465,11 @@ export interface AssistantDebugPayload {
truth_mode?: AssistantTruthMode; truth_mode?: AssistantTruthMode;
carryover_eligibility?: AssistantTruthAnswerPolicyRuntimeContract["truth_gate"]["carryover_eligibility"]; carryover_eligibility?: AssistantTruthAnswerPolicyRuntimeContract["truth_gate"]["carryover_eligibility"];
answer_shape?: AssistantAnswerShapeKind; answer_shape?: AssistantAnswerShapeKind;
assistant_state_transition_v1?: AssistantStateTransitionRuntimeContract;
state_transition_contract?: AssistantStateTransitionRuntimeContract;
state_transition_id?: AssistantTransitionClassId | null;
state_transition_status?: AssistantStateTransitionApplicationStatus;
effective_carryover_depth?: AssistantStateTransitionRuntimeContract["effective_carryover_depth"];
execution_lane?: "address_query" | "deep_analysis"; execution_lane?: "address_query" | "deep_analysis";
llm_decomposition_applied?: boolean; llm_decomposition_applied?: boolean;
llm_decomposition_attempted?: boolean; llm_decomposition_attempted?: boolean;

View File

@ -2,6 +2,7 @@ import type { AddressIntent } from "./addressQuery";
export const ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = "assistant_runtime_contracts_v1" as const; export const ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION = "assistant_runtime_contracts_v1" as const;
export const ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = "assistant_truth_answer_policy_runtime_v1" as const; export const ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION = "assistant_truth_answer_policy_runtime_v1" as const;
export const ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION = "assistant_state_transition_runtime_v1" as const;
export type AssistantLivingMode = "address_data" | "assistant_data_scope" | "chat" | "meta_followup" | "clarification"; export type AssistantLivingMode = "address_data" | "assistant_data_scope" | "chat" | "meta_followup" | "clarification";
export type AssistantFrameStatus = "active" | "suspended" | "closed" | "blocked"; export type AssistantFrameStatus = "active" | "suspended" | "closed" | "blocked";
@ -36,6 +37,8 @@ export type AssistantAnswerShapeKind =
| "blocked_no_answer" | "blocked_no_answer"
| "unknown"; | "unknown";
export type AssistantAnswerShapeReplyType = "factual" | "partial_coverage" | "deep_analysis" | "unknown"; export type AssistantAnswerShapeReplyType = "factual" | "partial_coverage" | "deep_analysis" | "unknown";
export type AssistantStateTransitionApplicationStatus = "applied" | "clarification_required" | "blocked" | "unresolved";
export type AssistantStateFrameAction = "create" | "update" | "preserve" | "reuse" | "clear" | "block" | "none";
export interface AssistantDateScopeState { export interface AssistantDateScopeState {
as_of_date: string | null; as_of_date: string | null;
@ -115,6 +118,32 @@ export interface AssistantTruthAnswerPolicyRuntimeContract {
answer_shape: AssistantAnswerShapeRuntimeContract; answer_shape: AssistantAnswerShapeRuntimeContract;
} }
export interface AssistantStateTransitionRuntimeContract {
schema_version: typeof ASSISTANT_STATE_TRANSITION_RUNTIME_SCHEMA_VERSION;
state_owner: "assistantStateTransitionRuntimeAdapter";
transition_id: AssistantTransitionClassId | null;
transition_title: string | null;
application_status: AssistantStateTransitionApplicationStatus;
declared_carryover_depth: AssistantCarryoverDepth | null;
truth_gate_carryover_depth: AssistantCarryoverDepth;
effective_carryover_depth: AssistantCarryoverDepth;
required_prior_state: AssistantStateSlice[];
expected_answer_mode: AssistantAnswerMode | null;
state_mutations: string[];
forbidden_carryover: string[];
state_actions: {
living_mode_state: AssistantStateFrameAction;
root_frame_state: AssistantStateFrameAction;
selected_object_frame_state: AssistantStateFrameAction;
meta_frame_state: AssistantStateFrameAction;
clarification_state: AssistantStateFrameAction;
coverage_gate_state: AssistantStateFrameAction;
answer_context_state: AssistantStateFrameAction;
};
coverage_gate_state: AssistantCoverageGateState;
reason_codes: string[];
}
export interface AssistantSessionAggregateState { export interface AssistantSessionAggregateState {
schema_version: typeof ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION; schema_version: typeof ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION;
living_mode_state: { living_mode_state: {

View File

@ -74,6 +74,13 @@ describe("assistant address lane response runtime adapter", () => {
}), }),
answer_shape_contract: expect.objectContaining({ answer_shape_contract: expect.objectContaining({
reply_type: "factual" reply_type: "factual"
}),
assistant_state_transition_v1: expect.objectContaining({
schema_version: "assistant_state_transition_runtime_v1",
state_owner: "assistantStateTransitionRuntimeAdapter"
}),
state_transition_contract: expect.objectContaining({
schema_version: "assistant_state_transition_runtime_v1"
}) })
}) })
); );
@ -128,10 +135,17 @@ describe("assistant address lane response runtime adapter", () => {
answer_shape: "blocked_no_answer", answer_shape: "blocked_no_answer",
reply_type: "partial_coverage" reply_type: "partial_coverage"
}), }),
assistant_state_transition_v1: expect.objectContaining({
application_status: "unresolved",
effective_carryover_depth: "none"
}),
transition_contract_id: null, transition_contract_id: null,
capability_contract_id: null, capability_contract_id: null,
truth_gate_contract_status: "unknown", truth_gate_contract_status: "unknown",
carryover_eligibility: "none" carryover_eligibility: "none",
state_transition_id: null,
state_transition_status: "unresolved",
effective_carryover_depth: "none"
}) })
); );
expect(runtime.response).toEqual({ ok: true }); expect(runtime.response).toEqual({ ok: true });

View File

@ -134,6 +134,18 @@ describe("assistant debug payload assembler", () => {
reply_type: "deep_analysis" reply_type: "deep_analysis"
}) })
); );
expect(payload.assistant_state_transition_v1).toEqual(
expect.objectContaining({
schema_version: "assistant_state_transition_runtime_v1",
state_owner: "assistantStateTransitionRuntimeAdapter",
application_status: "unresolved"
})
);
expect(payload.state_transition_contract).toEqual(
expect.objectContaining({
effective_carryover_depth: "none"
})
);
}); });
it("omits optional fields when they are not provided", () => { it("omits optional fields when they are not provided", () => {

View File

@ -0,0 +1,162 @@
import { describe, expect, it } from "vitest";
import {
attachAssistantStateTransition,
resolveAssistantStateTransitionRuntime
} from "../src/services/assistantStateTransitionRuntimeAdapter";
describe("assistant state transition runtime adapter", () => {
it("applies root entry as a root-frame create and selected-object clear", () => {
const transition = resolveAssistantStateTransitionRuntime({
addressDebug: {
capability_id: "confirmed_inventory_on_hand_as_of_date",
detected_intent: "inventory_on_hand_as_of_date",
rows_matched: 4,
route_expectation_status: "matched"
},
groundingStatus: "grounded",
replyType: "factual"
});
expect(transition).toEqual(
expect.objectContaining({
schema_version: "assistant_state_transition_runtime_v1",
state_owner: "assistantStateTransitionRuntimeAdapter",
transition_id: "T1",
transition_title: "Root Query Entry",
application_status: "applied",
declared_carryover_depth: "none",
truth_gate_carryover_depth: "root_only",
effective_carryover_depth: "none",
expected_answer_mode: "confirmed"
})
);
expect(transition.state_actions).toEqual(
expect.objectContaining({
root_frame_state: "create",
selected_object_frame_state: "clear",
coverage_gate_state: "create",
answer_context_state: "create"
})
);
expect(transition.coverage_gate_state.truth_mode).toBe("confirmed");
});
it("keeps selected-object short follow-ups object-scoped", () => {
const transition = resolveAssistantStateTransitionRuntime({
addressDebug: {
capability_id: "inventory_inventory_purchase_provenance_for_item",
detected_intent: "inventory_purchase_provenance_for_item",
rows_matched: 1,
route_expectation_status: "matched"
},
addressRuntimeMeta: {
dialogContinuationContract: {
decision: "continue_previous",
target_intent: "inventory_purchase_provenance_for_item"
}
},
groundingStatus: "grounded",
replyType: "factual"
});
expect(transition.transition_id).toBe("T4");
expect(transition.application_status).toBe("applied");
expect(transition.effective_carryover_depth).toBe("object_only");
expect(transition.state_actions.selected_object_frame_state).toBe("reuse");
expect(transition.state_actions.root_frame_state).toBe("preserve");
expect(transition.forbidden_carryover).toEqual(
expect.arrayContaining(["generic_chat_fallback", "data_scope_selection_fallback", "object_focus_reset"])
);
});
it("turns missing-anchor cases into clarification state transitions", () => {
const transition = resolveAssistantStateTransitionRuntime({
addressDebug: {
capability_id: "inventory_inventory_purchase_provenance_for_item",
missing_required_filters: ["item"],
limited_reason_category: "missing_anchor"
},
replyType: "partial_coverage"
});
expect(transition.transition_id).toBe("T7");
expect(transition.application_status).toBe("clarification_required");
expect(transition.effective_carryover_depth).toBe("full");
expect(transition.state_actions.clarification_state).toBe("update");
expect(transition.coverage_gate_state.truth_mode).toBe("clarification_required");
});
it("blocks route expectation failures and forbids implicit follow-up reuse", () => {
const transition = resolveAssistantStateTransitionRuntime({
addressDebug: {
capability_id: "confirmed_inventory_on_hand_as_of_date",
route_expectation_status: "mismatch"
},
groundingStatus: "route_mismatch_blocked",
replyType: "partial_coverage"
});
expect(transition.transition_id).toBe("T10");
expect(transition.application_status).toBe("blocked");
expect(transition.effective_carryover_depth).toBe("none");
expect(transition.state_actions.coverage_gate_state).toBe("block");
expect(transition.forbidden_carryover).toEqual(
expect.arrayContaining(["blocked_as_confirmed_factual_answer", "implicit_followup_reuse"])
);
});
it("attaches compact debug fields and preserves the nested transition contract", () => {
const debug = attachAssistantStateTransition(
{
assistant_runtime_contract_v1: {
schema_version: "assistant_runtime_contracts_v1",
transition_contract_id: "T8",
transition_contract_title: "Meta Follow-Up Over Answer Object",
transition_contract_reason: ["capability_meta_followup_tool_gate_reason"],
capability_contract_id: "confirmed_inventory_on_hand_as_of_date",
capability_contract_reason: ["intent_matched_capability_contract"],
truth_gate_contract_status: "partial_supported",
carryover_eligibility: "meta_only"
},
assistant_truth_answer_policy_v1: {
schema_version: "assistant_truth_answer_policy_runtime_v1",
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
truth_gate: {
schema_version: "assistant_truth_answer_policy_runtime_v1",
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
coverage_status: "partial",
evidence_grade: "weak",
grounding_status: "partial",
truth_mode: "limited",
carryover_eligibility: "meta_only",
reason_codes: ["truth_gate_partial_supported"],
source_truth_gate_status: "partial_supported",
blocked_or_limited_explanation: "evidence_or_coverage_is_partial"
},
answer_shape: {
schema_version: "assistant_truth_answer_policy_runtime_v1",
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
answer_shape: "limited_with_reason",
reply_type: "deep_analysis",
capability_contract_id: "confirmed_inventory_on_hand_as_of_date",
transition_contract_id: "T8",
may_state_confirmed_facts: true,
must_include_limitation: true,
may_power_followup: true,
required_sections: ["direct_answer", "evidence_window", "limitations"],
downgrade_only: true
}
}
},
{
replyType: "deep_analysis"
}
);
expect(debug.state_transition_id).toBe("T8");
expect(debug.state_transition_status).toBe("applied");
expect(debug.effective_carryover_depth).toBe("meta_only");
expect(debug.assistant_state_transition_v1.state_actions.meta_frame_state).toBe("create");
expect(debug.state_transition_contract.state_actions.answer_context_state).toBe("reuse");
});
});