АРЧ АП11 - Добавить state transition owner для assistant runtime
This commit is contained in:
parent
89bcaccda8
commit
5f628f427f
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
265
llm_normalizer/backend/dist/services/assistantStateTransitionRuntimeAdapter.js
vendored
Normal file
265
llm_normalizer/backend/dist/services/assistantStateTransitionRuntimeAdapter.js
vendored
Normal 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
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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";
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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: {
|
||||||
|
|
|
||||||
|
|
@ -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 });
|
||||||
|
|
|
||||||
|
|
@ -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", () => {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue