refactor(architect): Use IPromptBuilder Interface for LLMValidator

This commit is contained in:
2026-07-19 20:31:58 +05:30
parent ee25bf4a4c
commit 7baf583b13
8 changed files with 164 additions and 60 deletions

View File

@@ -49,10 +49,12 @@ async function processIntents(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
worldState: any,
session: SimSession,
): Promise<IntentInfo[]> {
): Promise<{ intentInfos: IntentInfo[]; validatorCalls: ValidatorCall[] }> {
const intentInfos: IntentInfo[] = [];
const validatorCalls: ValidatorCall[] = [];
for (const intent of intents) {
for (let i = 0; i < intents.length; i++) {
const intent = intents[i];
const outcome = await session.architect.processIntent(worldState, intent);
const ts = worldState.clock.get().toISOString();
@@ -66,6 +68,53 @@ async function processIntents(
minutesToAdvance: outcome.timeDelta?.minutesToAdvance,
});
if (
intent.type === "action" &&
(session.architect.validator as any).lastResult
) {
const lastResult = (session.architect.validator as any).lastResult;
let usage = undefined;
if (
session.validatorProvider.lastCalls &&
session.validatorProvider.lastCalls.length > 0
) {
const valCall =
session.validatorProvider.lastCalls[
session.validatorProvider.lastCalls.length - 1
];
usage = valCall.usage;
}
validatorCalls.push({
intentIndex: i,
intentContent: intent.content,
prompt: {
systemPrompt: lastResult.systemPrompt || "",
userContext: lastResult.userContext || "",
components: lastResult.promptComponents,
},
response: {
isValid: outcome.isValid,
reason: outcome.reason,
},
usage,
});
} else {
const reason =
intent.type === "dialogue"
? "Dialogue intents represent verbal/communication actions and are automatically valid."
: "Monologue/thought intents represent internal reflections and bypass validation.";
validatorCalls.push({
intentIndex: i,
intentContent: intent.content,
response: {
isValid: true,
reason: outcome.reason || reason,
},
});
}
const actorEntry = buildBufferEntryForIntent(intent, ts, entity.locationId);
if (intent.type === "action") {
actorEntry.outcome = { isValid: outcome.isValid, reason: outcome.reason };
@@ -99,7 +148,7 @@ async function processIntents(
}
}
return intentInfos;
return { intentInfos, validatorCalls };
}
// ---------------------------------------------------------------------------
@@ -219,13 +268,21 @@ export async function processNpcTurn(
entry.decoderUsage = decoderCall.usage;
}
entry.intents = await processIntents(
const { intentInfos, validatorCalls } = await processIntents(
result.intents.intents,
info.id,
entity,
worldState,
session,
);
entry.intents = intentInfos;
entry.validatorCalls = validatorCalls;
entry.decodedIntents = result.intents.intents.map((intent) => ({
type: intent.type,
content: intent.content,
modifiers: intent.modifiers || [],
targetIds: intent.targetIds,
}));
session.log.push(entry);
session.coreRepo.saveWorldState(worldState);
@@ -303,13 +360,21 @@ export async function executePlayerAction(
entry.decoderUsage = call.usage;
}
entry.intents = await processIntents(
const { intentInfos, validatorCalls: playerValCalls } = await processIntents(
result.intents.intents,
ctx.entityId,
entity,
worldState,
session,
);
entry.intents = intentInfos;
entry.validatorCalls = playerValCalls;
entry.decodedIntents = result.intents.intents.map((intent) => ({
type: intent.type,
content: intent.content,
modifiers: intent.modifiers || [],
targetIds: intent.targetIds,
}));
session.log.push(entry);
session.coreRepo.saveWorldState(worldState);