/** * RPG 运行时聊天相关共享契约。 * 将角色聊天、NPC 对话与轻量 story 请求载荷从旧 story.ts 中独立出来。 */ import type { JsonObject } from './common'; import type { SavedGameSnapshotInput } from './runtime'; export type NpcChatTurnLimitReason = 'negative_affinity'; export type NpcChatTurnClosingMode = 'free' | 'foreshadow_close'; export type NpcChatTurnTerminationMode = 'none' | 'hostile_model'; export type NpcChatTurnTerminationReason = 'hostile_breakoff' | 'player_exit'; export type NpcChatFunctionOption = { functionId: string; actionText: string; detailText?: string | null; action?: string | null; }; export type NpcChatTurnDirective = { sceneActId?: string | null; turnLimit?: number | null; remainingTurns?: number | null; limitReason?: NpcChatTurnLimitReason | null; closingMode?: NpcChatTurnClosingMode | null; forceExitAfterTurn?: boolean; terminationMode?: NpcChatTurnTerminationMode | null; terminationReason?: NpcChatTurnTerminationReason | null; isHostileChat?: boolean; functionOptions?: NpcChatFunctionOption[]; }; export type NpcChatTurnCompletionDirective = { turnLimit?: number | null; remainingTurns?: number | null; forceExit?: boolean; closingMode?: NpcChatTurnClosingMode; terminationReason?: NpcChatTurnTerminationReason | null; }; export type CharacterChatReplyRequest< TCharacter = unknown, TStoryMoment = unknown, TContext = unknown, TConversationTurn = unknown, TTargetStatus = unknown, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; playerCharacter?: TCharacter; targetCharacter: TCharacter; storyHistory?: TStoryMoment[]; context?: TContext; conversationHistory: TConversationTurn[]; conversationSummary: string; playerMessage: string; targetStatus: TTargetStatus; }; export type CharacterChatSuggestionsRequest< TCharacter = unknown, TStoryMoment = unknown, TContext = unknown, TConversationTurn = unknown, TTargetStatus = unknown, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; playerCharacter?: TCharacter; targetCharacter: TCharacter; storyHistory?: TStoryMoment[]; context?: TContext; conversationHistory: TConversationTurn[]; conversationSummary: string; targetStatus: TTargetStatus; }; export type CharacterChatSummaryRequest< TCharacter = unknown, TStoryMoment = unknown, TContext = unknown, TConversationTurn = unknown, TTargetStatus = unknown, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; playerCharacter?: TCharacter; targetCharacter: TCharacter; storyHistory?: TStoryMoment[]; context?: TContext; conversationHistory: TConversationTurn[]; previousSummary: string; targetStatus: TTargetStatus; }; export type NpcChatDialogueRequest< TCharacter = unknown, TEncounter = unknown, TMonster = unknown, TStoryMoment = unknown, TContext = unknown, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; character?: TCharacter; encounter: TEncounter; monsters?: TMonster[]; history?: TStoryMoment[]; context?: TContext; topic: string; resultSummary: string; npcInitiatesConversation?: boolean; }; export type NpcChatTurnRequest< TCharacter = unknown, TEncounter = unknown, TMonster = unknown, TStoryMoment = unknown, TContext = unknown, TConversationTurn = unknown, TCombatContext = unknown, TNpcState = unknown, TQuestOfferState = unknown, TQuestOfferEncounter = unknown, TChatDirective = NpcChatTurnDirective, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; character?: TCharacter; player?: TCharacter; encounter: TEncounter; monsters?: TMonster[]; history?: TStoryMoment[]; context?: TContext; conversationHistory?: TConversationTurn[]; dialogue?: TConversationTurn[]; combatContext?: TCombatContext | null; playerMessage: string; npcState: TNpcState; npcInitiatesConversation?: boolean; questOfferContext?: { state: TQuestOfferState; encounter: TQuestOfferEncounter; turnCount: number; } | null; chatDirective?: TChatDirective | null; }; export type NpcChatPendingQuestOffer = { quest: TQuest; introText?: string; }; export type NpcChatFunctionSuggestion = { functionId: string; actionText: string; }; export type NpcChatTurnResult = { npcReply: string; affinityDelta: number; affinityText: string; suggestions: string[]; functionSuggestions?: NpcChatFunctionSuggestion[]; pendingQuestOffer?: NpcChatPendingQuestOffer | null; chatDirective?: NpcChatTurnCompletionDirective | null; }; export type NpcRecruitDialogueRequest< TCharacter = unknown, TEncounter = unknown, TMonster = unknown, TStoryMoment = unknown, TContext = unknown, TSnapshotGameState = unknown, TSnapshotCurrentStory = unknown, > = { sessionId?: string; snapshot?: SavedGameSnapshotInput< TSnapshotGameState, string, TSnapshotCurrentStory >; worldType?: string; character?: TCharacter; encounter: TEncounter; monsters?: TMonster[]; history?: TStoryMoment[]; context?: TContext; invitationText: string; recruitSummary: string; }; export type StoryRequestOptionsPayload = { availableOptions?: JsonObject[]; optionCatalog?: JsonObject[]; }; export type StoryRequestPayload = { worldType: TWorldType; character: JsonObject; monsters?: JsonObject[]; history?: JsonObject[]; choice?: string; context: JsonObject; requestOptions?: StoryRequestOptionsPayload; }; export type PlainTextPromptRequest = { systemPrompt: string; userPrompt: string; }; export type PlainTextResponse = { text: string; };