1
This commit is contained in:
@@ -1,17 +1,29 @@
|
||||
import type { QuestGenerationRequest } from '../../../packages/shared/src/contracts/story.js';
|
||||
import {
|
||||
QUEST_INTIMACY_LEVELS,
|
||||
QUEST_NARRATIVE_TYPES,
|
||||
QUEST_OBJECTIVE_KINDS,
|
||||
QUEST_REWARD_THEMES,
|
||||
QUEST_URGENCY_LEVELS,
|
||||
} from '../../../packages/shared/src/contracts/story.js';
|
||||
import { parseJsonResponseText } from '../../../packages/shared/src/llm/parsers.js';
|
||||
import {
|
||||
buildFallbackQuestIntent,
|
||||
compileQuestIntentToQuest,
|
||||
evaluateQuestOpportunity,
|
||||
} from '../../../src/data/questFlow.js';
|
||||
import { parseJsonResponseText } from '../../../src/services/llmParsers.js';
|
||||
import { buildQuestGenerationContextFromState } from '../../../src/services/questDirector.js';
|
||||
import { buildQuestIntentPrompt, QUEST_INTENT_SYSTEM_PROMPT } from '../../../src/services/questPrompt.js';
|
||||
import type { QuestIntent, QuestPreviewRequest } from '../../../src/services/questTypes.js';
|
||||
import type { GameState } from '../../../src/types/game.js';
|
||||
import type { Encounter } from '../../../src/types/scene.js';
|
||||
import type { QuestLogEntry } from '../../../src/types/story.js';
|
||||
buildQuestGenerationContextFromState,
|
||||
buildQuestIntentPrompt,
|
||||
QUEST_INTENT_SYSTEM_PROMPT,
|
||||
} from '../bridges/legacyQuestRuntimeBridge.js';
|
||||
import type { UpstreamLlmClient } from './llmClient.js';
|
||||
|
||||
type QuestPreviewRequest = Parameters<typeof evaluateQuestOpportunity>[0];
|
||||
type QuestIntent = ReturnType<typeof buildFallbackQuestIntent>;
|
||||
type QuestGenerationInput = Parameters<typeof buildQuestGenerationContextFromState>[0];
|
||||
type QuestGenerationState = QuestGenerationInput['state'];
|
||||
type QuestGenerationEncounter = QuestGenerationInput['encounter'];
|
||||
type QuestLogEntry = ReturnType<typeof compileQuestIntentToQuest>;
|
||||
|
||||
function coerceString(value: unknown, fallback: string) {
|
||||
return typeof value === 'string' && value.trim() ? value.trim() : fallback;
|
||||
}
|
||||
@@ -41,7 +53,7 @@ function sanitizeQuestIntent(rawIntent: unknown, fallback: QuestIntent): QuestIn
|
||||
summary: coerceString(intent.summary, fallback.summary),
|
||||
narrativeType:
|
||||
typeof intent.narrativeType === 'string' &&
|
||||
['bounty', 'escort', 'investigation', 'retrieval', 'relationship', 'trial'].includes(intent.narrativeType)
|
||||
QUEST_NARRATIVE_TYPES.includes(intent.narrativeType)
|
||||
? (intent.narrativeType as QuestIntent['narrativeType'])
|
||||
: fallback.narrativeType,
|
||||
dramaticNeed: coerceString(intent.dramaticNeed, fallback.dramaticNeed),
|
||||
@@ -51,29 +63,20 @@ function sanitizeQuestIntent(rawIntent: unknown, fallback: QuestIntent): QuestIn
|
||||
recommendedObjectiveKinds: coerceStringArray(
|
||||
intent.recommendedObjectiveKinds,
|
||||
fallback.recommendedObjectiveKinds,
|
||||
).filter((kind) =>
|
||||
[
|
||||
'defeat_hostile_npc',
|
||||
'inspect_treasure',
|
||||
'spar_with_npc',
|
||||
'talk_to_npc',
|
||||
'reach_scene',
|
||||
'deliver_item',
|
||||
].includes(kind),
|
||||
) as QuestIntent['recommendedObjectiveKinds'],
|
||||
).filter((kind) => QUEST_OBJECTIVE_KINDS.includes(kind)) as QuestIntent['recommendedObjectiveKinds'],
|
||||
urgency:
|
||||
typeof intent.urgency === 'string' &&
|
||||
['low', 'medium', 'high'].includes(intent.urgency)
|
||||
QUEST_URGENCY_LEVELS.includes(intent.urgency)
|
||||
? (intent.urgency as QuestIntent['urgency'])
|
||||
: fallback.urgency,
|
||||
intimacy:
|
||||
typeof intent.intimacy === 'string' &&
|
||||
['transactional', 'cooperative', 'trust_based'].includes(intent.intimacy)
|
||||
QUEST_INTIMACY_LEVELS.includes(intent.intimacy)
|
||||
? (intent.intimacy as QuestIntent['intimacy'])
|
||||
: fallback.intimacy,
|
||||
rewardTheme:
|
||||
typeof intent.rewardTheme === 'string' &&
|
||||
['currency', 'resource', 'relationship', 'intel', 'rare_item'].includes(intent.rewardTheme)
|
||||
QUEST_REWARD_THEMES.includes(intent.rewardTheme)
|
||||
? (intent.rewardTheme as QuestIntent['rewardTheme'])
|
||||
: fallback.rewardTheme,
|
||||
followupHooks: coerceStringArray(intent.followupHooks, fallback.followupHooks),
|
||||
@@ -82,10 +85,7 @@ function sanitizeQuestIntent(rawIntent: unknown, fallback: QuestIntent): QuestIn
|
||||
|
||||
export async function generateQuestForNpcEncounter(
|
||||
llmClient: UpstreamLlmClient,
|
||||
params: {
|
||||
state: GameState;
|
||||
encounter: Encounter;
|
||||
},
|
||||
params: QuestGenerationRequest<QuestGenerationState, QuestGenerationEncounter>,
|
||||
): Promise<QuestLogEntry | null> {
|
||||
const { state, encounter } = params;
|
||||
const issuerNpcId = encounter.id ?? encounter.npcName;
|
||||
@@ -95,7 +95,7 @@ export async function generateQuestForNpcEncounter(
|
||||
roleText: encounter.context,
|
||||
scene: state.currentScenePreset,
|
||||
worldType: state.worldType,
|
||||
currentQuests: state.quests.map((quest: QuestLogEntry) => ({
|
||||
currentQuests: state.quests.map((quest) => ({
|
||||
id: quest.id,
|
||||
issuerNpcId: quest.issuerNpcId,
|
||||
status: quest.status,
|
||||
|
||||
Reference in New Issue
Block a user