Files
Genarrative/packages/shared/src/contracts/rpgRuntimeChat.ts
2026-04-29 11:51:04 +08:00

256 lines
6.3 KiB
TypeScript

/**
* 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<TQuest = unknown> = {
quest: TQuest;
introText?: string;
};
export type NpcChatFunctionSuggestion = {
functionId: string;
actionText: string;
};
export type NpcChatTurnResult<TQuest = unknown> = {
npcReply: string;
affinityDelta: number;
affinityText: string;
suggestions: string[];
functionSuggestions?: NpcChatFunctionSuggestion[];
pendingQuestOffer?: NpcChatPendingQuestOffer<TQuest> | 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<TWorldType extends string = string> = {
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;
};