Merge origin/master into codex/wechat
This commit is contained in:
@@ -9,6 +9,7 @@ export interface CreationAgentDocumentInputPayload {
|
||||
contentType?: string | null;
|
||||
sizeBytes: number;
|
||||
text: string;
|
||||
sourceAssetId?: string | null;
|
||||
}
|
||||
|
||||
export interface ParseCreationAgentDocumentInputResponse {
|
||||
|
||||
53
packages/shared/src/contracts/creationAudio.ts
Normal file
53
packages/shared/src/contracts/creationAudio.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
export type CreationAudioGenerationKind =
|
||||
| 'background_music'
|
||||
| 'sound_effect';
|
||||
|
||||
export interface CreationAudioAsset {
|
||||
taskId: string;
|
||||
provider: string;
|
||||
assetObjectId?: string | null;
|
||||
assetKind?: string | null;
|
||||
audioSrc: string;
|
||||
prompt?: string | null;
|
||||
title?: string | null;
|
||||
updatedAt?: string | null;
|
||||
}
|
||||
|
||||
export interface CreateBackgroundMusicRequest {
|
||||
prompt: string;
|
||||
title: string;
|
||||
tags?: string | null;
|
||||
model?: string | null;
|
||||
}
|
||||
|
||||
export interface CreateSoundEffectRequest {
|
||||
prompt: string;
|
||||
duration?: number | null;
|
||||
seed?: number | null;
|
||||
}
|
||||
|
||||
export interface AudioGenerationTaskResponse {
|
||||
kind: CreationAudioGenerationKind;
|
||||
taskId: string;
|
||||
provider: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface PublishGeneratedAudioAssetRequest {
|
||||
entityKind: string;
|
||||
entityId: string;
|
||||
slot: string;
|
||||
assetKind: string;
|
||||
profileId?: string | null;
|
||||
storagePrefix?: 'puzzle_assets' | 'match3d_assets' | 'custom_world_scenes' | null;
|
||||
}
|
||||
|
||||
export interface GeneratedAudioAssetResponse {
|
||||
kind: CreationAudioGenerationKind;
|
||||
taskId: string;
|
||||
provider: string;
|
||||
status: string;
|
||||
assetObjectId?: string | null;
|
||||
assetKind?: string | null;
|
||||
audioSrc?: string | null;
|
||||
}
|
||||
244
packages/shared/src/contracts/creativeAgent.ts
Normal file
244
packages/shared/src/contracts/creativeAgent.ts
Normal file
@@ -0,0 +1,244 @@
|
||||
import type { PuzzleResultDraft } from './puzzleAgentDraft';
|
||||
import type { PuzzleAgentSessionSnapshot } from './puzzleAgentSession';
|
||||
import type {
|
||||
PuzzleCreativeTemplateProtocol,
|
||||
PuzzleCreativeTemplateSelection,
|
||||
PuzzleDraftFieldPatch,
|
||||
PuzzleImageGenerationPlan,
|
||||
PuzzleTemplateCostRange,
|
||||
} from './puzzleCreativeTemplate';
|
||||
|
||||
export type CreativeAgentStage =
|
||||
| 'idle'
|
||||
| 'perceiving'
|
||||
| 'thinking'
|
||||
| 'remembering'
|
||||
| 'selecting_puzzle_template'
|
||||
| 'waiting_template_confirmation'
|
||||
| 'planning_puzzle_levels'
|
||||
| 'acting'
|
||||
| 'reflecting'
|
||||
| 'collaborating'
|
||||
| 'target_ready'
|
||||
| 'waiting_user'
|
||||
| 'failed';
|
||||
|
||||
export type CreativeAgentEntryContext =
|
||||
| 'creation_home'
|
||||
| 'puzzle_workspace'
|
||||
| 'gallery_remix'
|
||||
| 'draft_restore';
|
||||
|
||||
export type CreativeAgentMessageRole = 'user' | 'assistant' | 'system';
|
||||
|
||||
export type CreativeAgentMessageKind =
|
||||
| 'chat'
|
||||
| 'stage'
|
||||
| 'action_result'
|
||||
| 'warning';
|
||||
|
||||
export type CreativeAgentInputPart =
|
||||
| {
|
||||
type: 'input_text';
|
||||
text: string;
|
||||
}
|
||||
| {
|
||||
type: 'input_image';
|
||||
imageUrl: string;
|
||||
assetId?: string | null;
|
||||
thumbnailUrl?: string | null;
|
||||
};
|
||||
|
||||
export interface CreativeImageInput {
|
||||
assetId: string;
|
||||
readUrl: string;
|
||||
thumbnailUrl?: string | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
}
|
||||
|
||||
export interface CreativeImageSummary {
|
||||
assetId: string | null;
|
||||
readUrl: string | null;
|
||||
thumbnailUrl: string | null;
|
||||
width: number | null;
|
||||
height: number | null;
|
||||
summary: string | null;
|
||||
}
|
||||
|
||||
export type CreativeUnsupportedPlayType =
|
||||
| 'rpg'
|
||||
| 'match3d'
|
||||
| 'big_fish'
|
||||
| 'square_hole';
|
||||
|
||||
export interface CreativeUnsupportedCapability {
|
||||
playType: CreativeUnsupportedPlayType;
|
||||
title: string;
|
||||
status: 'unsupported';
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export interface CreativeInputSummary {
|
||||
text: string | null;
|
||||
entryContext: CreativeAgentEntryContext;
|
||||
images: CreativeImageSummary[];
|
||||
materialSummary: string | null;
|
||||
unsupportedCapabilities: CreativeUnsupportedCapability[];
|
||||
}
|
||||
|
||||
export interface CreativeAgentMessage {
|
||||
id: string;
|
||||
role: CreativeAgentMessageRole;
|
||||
kind: CreativeAgentMessageKind;
|
||||
text: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface CreativeTargetSessionBinding {
|
||||
playType: 'puzzle';
|
||||
targetSessionId: string;
|
||||
targetStage: 'puzzle-agent-workspace' | 'puzzle-result' | 'puzzle-runtime';
|
||||
resultProfileId: string | null;
|
||||
}
|
||||
|
||||
export interface CreativeAgentSessionSnapshot {
|
||||
sessionId: string;
|
||||
stage: CreativeAgentStage;
|
||||
inputSummary: CreativeInputSummary;
|
||||
messages: CreativeAgentMessage[];
|
||||
puzzleTemplateCatalog: PuzzleCreativeTemplateProtocol[];
|
||||
puzzleTemplateSelection: PuzzleCreativeTemplateSelection | null;
|
||||
puzzleImageGenerationPlan: PuzzleImageGenerationPlan | null;
|
||||
targetBinding: CreativeTargetSessionBinding | null;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CreateCreativeAgentSessionRequest {
|
||||
text?: string | null;
|
||||
images?: CreativeImageInput[];
|
||||
entryContext?: CreativeAgentEntryContext;
|
||||
}
|
||||
|
||||
export interface CreativeAgentSessionResponse {
|
||||
session: CreativeAgentSessionSnapshot;
|
||||
}
|
||||
|
||||
export interface StreamCreativeAgentMessageRequest {
|
||||
clientMessageId: string;
|
||||
content: CreativeAgentInputPart[];
|
||||
}
|
||||
|
||||
export interface ConfirmCreativePuzzleTemplateRequest {
|
||||
selection: PuzzleCreativeTemplateSelection;
|
||||
}
|
||||
|
||||
export interface CreativeDraftEditStreamRequest {
|
||||
clientMessageId: string;
|
||||
instruction: string;
|
||||
targetPuzzleSessionId: string;
|
||||
currentDraft: PuzzleResultDraft;
|
||||
}
|
||||
|
||||
export interface CreativeDraftEditResult {
|
||||
editInstructions: PuzzleDraftFieldPatch[];
|
||||
session: CreativeAgentSessionSnapshot;
|
||||
puzzleSession: PuzzleAgentSessionSnapshot;
|
||||
}
|
||||
|
||||
export interface CreativeAgentStageEvent {
|
||||
sessionId: string;
|
||||
stage: CreativeAgentStage;
|
||||
}
|
||||
|
||||
export interface CreativeAgentMessageDeltaEvent {
|
||||
sessionId: string;
|
||||
messageId: string;
|
||||
role: CreativeAgentMessageRole;
|
||||
kind: CreativeAgentMessageKind;
|
||||
textDelta: string;
|
||||
}
|
||||
|
||||
export interface CreativeAgentThoughtSummaryDeltaEvent {
|
||||
sessionId: string;
|
||||
thoughtId: string;
|
||||
textDelta: string;
|
||||
}
|
||||
|
||||
export interface CreativeAgentTemplateCatalogEvent {
|
||||
sessionId: string;
|
||||
templates: PuzzleCreativeTemplateProtocol[];
|
||||
}
|
||||
|
||||
export interface CreativeAgentTemplateSelectionEvent {
|
||||
sessionId: string;
|
||||
selection: PuzzleCreativeTemplateSelection;
|
||||
}
|
||||
|
||||
export interface CreativeAgentCostRangeEvent {
|
||||
sessionId: string;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
}
|
||||
|
||||
export interface CreativeAgentLevelPlanEvent {
|
||||
sessionId: string;
|
||||
plan: PuzzleImageGenerationPlan;
|
||||
}
|
||||
|
||||
export interface CreativeAgentToolEvent {
|
||||
sessionId: string;
|
||||
toolCallId: string;
|
||||
toolName: string;
|
||||
summary: string | null;
|
||||
}
|
||||
|
||||
export interface CreativeAgentReflectionEvent {
|
||||
sessionId: string;
|
||||
pass: boolean;
|
||||
summary: string;
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
export interface CreativeAgentTargetSessionEvent {
|
||||
sessionId: string;
|
||||
binding: CreativeTargetSessionBinding;
|
||||
}
|
||||
|
||||
export interface CreativeAgentErrorEvent {
|
||||
sessionId: string | null;
|
||||
code: string;
|
||||
message: string;
|
||||
recoverable: boolean;
|
||||
}
|
||||
|
||||
export interface CreativeAgentDoneEvent {
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export type CreativeAgentSseEvent =
|
||||
| { event: 'stage'; data: CreativeAgentStageEvent }
|
||||
| { event: 'agent_message_delta'; data: CreativeAgentMessageDeltaEvent }
|
||||
| {
|
||||
event: 'thought_summary_delta';
|
||||
data: CreativeAgentThoughtSummaryDeltaEvent;
|
||||
}
|
||||
| {
|
||||
event: 'puzzle_template_catalog';
|
||||
data: CreativeAgentTemplateCatalogEvent;
|
||||
}
|
||||
| {
|
||||
event: 'puzzle_template_selection';
|
||||
data: CreativeAgentTemplateSelectionEvent;
|
||||
}
|
||||
| { event: 'puzzle_cost_range'; data: CreativeAgentCostRangeEvent }
|
||||
| { event: 'puzzle_level_plan'; data: CreativeAgentLevelPlanEvent }
|
||||
| { event: 'tool_started'; data: CreativeAgentToolEvent }
|
||||
| { event: 'tool_completed'; data: CreativeAgentToolEvent }
|
||||
| { event: 'reflection'; data: CreativeAgentReflectionEvent }
|
||||
| { event: 'target_session'; data: CreativeAgentTargetSessionEvent }
|
||||
| {
|
||||
event: 'session';
|
||||
data: { session: CreativeAgentSessionSnapshot };
|
||||
}
|
||||
| { event: 'error'; data: CreativeAgentErrorEvent }
|
||||
| { event: 'done'; data: CreativeAgentDoneEvent };
|
||||
89
packages/shared/src/contracts/edutainmentBabyObject.ts
Normal file
89
packages/shared/src/contracts/edutainmentBabyObject.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
export const BABY_OBJECT_MATCH_TEMPLATE_ID = 'baby-object-match';
|
||||
export const BABY_OBJECT_MATCH_TEMPLATE_NAME = '宝贝识物';
|
||||
export const BABY_OBJECT_MATCH_EDUTAINMENT_TAG = '寓教于乐';
|
||||
|
||||
export type BabyObjectMatchTemplateId =
|
||||
typeof BABY_OBJECT_MATCH_TEMPLATE_ID;
|
||||
|
||||
export type BabyObjectMatchAssetProvider =
|
||||
| 'vector-engine-gpt-image-2'
|
||||
| 'placeholder';
|
||||
|
||||
export type BabyObjectMatchPublicationStatus = 'draft' | 'published';
|
||||
|
||||
export type BabyObjectMatchItemAsset = {
|
||||
itemId: string;
|
||||
itemName: string;
|
||||
imageSrc: string;
|
||||
assetObjectId: string | null;
|
||||
generationProvider: BabyObjectMatchAssetProvider;
|
||||
prompt: string;
|
||||
};
|
||||
|
||||
export type BabyObjectMatchDraft = {
|
||||
draftId: string;
|
||||
profileId: string;
|
||||
templateId: BabyObjectMatchTemplateId;
|
||||
templateName: typeof BABY_OBJECT_MATCH_TEMPLATE_NAME;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
itemNames: [string, string];
|
||||
itemAssets: [BabyObjectMatchItemAsset, BabyObjectMatchItemAsset];
|
||||
themeTags: string[];
|
||||
publicationStatus: BabyObjectMatchPublicationStatus;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
};
|
||||
|
||||
export type CreateBabyObjectMatchDraftRequest = {
|
||||
itemAName: string;
|
||||
itemBName: string;
|
||||
};
|
||||
|
||||
export type BabyObjectMatchDraftResponse = {
|
||||
draft: BabyObjectMatchDraft;
|
||||
};
|
||||
|
||||
export type SaveBabyObjectMatchDraftRequest = {
|
||||
draft: BabyObjectMatchDraft;
|
||||
};
|
||||
|
||||
export type BabyObjectMatchPublishRequest = {
|
||||
draft: BabyObjectMatchDraft;
|
||||
};
|
||||
|
||||
export type BabyObjectMatchPublishResponse = {
|
||||
draft: BabyObjectMatchDraft;
|
||||
publicWorkCode: string;
|
||||
};
|
||||
|
||||
export function normalizeBabyObjectMatchItemName(value: string) {
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
export function normalizeBabyObjectMatchTags(tags: string[]) {
|
||||
return [
|
||||
...new Set([
|
||||
BABY_OBJECT_MATCH_EDUTAINMENT_TAG,
|
||||
...tags.map((tag) => tag.trim()).filter(Boolean),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
export function hasBabyObjectMatchRequiredTag(tags: string[]) {
|
||||
return tags.some((tag) => tag === BABY_OBJECT_MATCH_EDUTAINMENT_TAG);
|
||||
}
|
||||
|
||||
export function validateBabyObjectMatchItemNames(
|
||||
payload: CreateBabyObjectMatchDraftRequest,
|
||||
) {
|
||||
const itemAName = normalizeBabyObjectMatchItemName(payload.itemAName);
|
||||
const itemBName = normalizeBabyObjectMatchItemName(payload.itemBName);
|
||||
|
||||
return {
|
||||
itemAName,
|
||||
itemBName,
|
||||
valid: Boolean(itemAName && itemBName),
|
||||
};
|
||||
}
|
||||
75
packages/shared/src/contracts/hyper3d.ts
Normal file
75
packages/shared/src/contracts/hyper3d.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
export type Hyper3dGenerationMode = 'text-to-model' | 'image-to-model';
|
||||
|
||||
export type Hyper3dTextToModelRequest = {
|
||||
prompt: string;
|
||||
negativePrompt?: string | null;
|
||||
seed?: number | null;
|
||||
geometryFileFormat?: string | null;
|
||||
material?: string | null;
|
||||
quality?: string | null;
|
||||
meshMode?: string | null;
|
||||
addons?: string[];
|
||||
bboxCondition?: number[] | null;
|
||||
previewRender?: boolean | null;
|
||||
};
|
||||
|
||||
export type Hyper3dImageToModelRequest = {
|
||||
imageDataUrls?: string[];
|
||||
imageUrls?: string[];
|
||||
prompt?: string | null;
|
||||
conditionMode?: string | null;
|
||||
seed?: number | null;
|
||||
geometryFileFormat?: string | null;
|
||||
material?: string | null;
|
||||
quality?: string | null;
|
||||
meshMode?: string | null;
|
||||
addons?: string[];
|
||||
bboxCondition?: number[] | null;
|
||||
previewRender?: boolean | null;
|
||||
};
|
||||
|
||||
export type Hyper3dTaskSubmitResponse = {
|
||||
ok: boolean;
|
||||
provider: string;
|
||||
mode: Hyper3dGenerationMode;
|
||||
taskUuid: string;
|
||||
subscriptionKey: string;
|
||||
jobUuids: string[];
|
||||
message?: string | null;
|
||||
tier: string;
|
||||
};
|
||||
|
||||
export type Hyper3dTaskStatusRequest = {
|
||||
subscriptionKey: string;
|
||||
};
|
||||
|
||||
export type Hyper3dJobStatusPayload = {
|
||||
uuid?: string | null;
|
||||
status: string;
|
||||
progress?: number | null;
|
||||
message?: string | null;
|
||||
};
|
||||
|
||||
export type Hyper3dTaskStatusResponse = {
|
||||
ok: boolean;
|
||||
provider: string;
|
||||
status: string;
|
||||
jobs: Hyper3dJobStatusPayload[];
|
||||
raw: unknown;
|
||||
};
|
||||
|
||||
export type Hyper3dDownloadRequest = {
|
||||
taskUuid: string;
|
||||
};
|
||||
|
||||
export type Hyper3dDownloadFilePayload = {
|
||||
name: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
export type Hyper3dDownloadResponse = {
|
||||
ok: boolean;
|
||||
provider: string;
|
||||
files: Hyper3dDownloadFilePayload[];
|
||||
raw: unknown;
|
||||
};
|
||||
5
packages/shared/src/contracts/index.ts
Normal file
5
packages/shared/src/contracts/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export type * from './creativeAgent';
|
||||
export type * from './creationAudio';
|
||||
export type * from './hyper3d';
|
||||
export type * from './puzzleCreativeTemplate';
|
||||
export type * from './visualNovel';
|
||||
@@ -2,6 +2,8 @@
|
||||
* 抓大鹅 Match3D 创作 Agent 共享契约。
|
||||
* 字段按 HTTP facade 的 camelCase DTO 命名,后端领域层 snake_case 字段由 facade 映射。
|
||||
*/
|
||||
import type { Match3DGeneratedItemAsset } from './match3dWorks';
|
||||
|
||||
export type Match3DCreationStage =
|
||||
| 'collecting'
|
||||
| 'collecting_config'
|
||||
@@ -29,6 +31,9 @@ export interface CreateMatch3DAgentSessionRequest {
|
||||
referenceImageSrc?: string | null;
|
||||
clearCount?: number;
|
||||
difficulty?: number;
|
||||
assetStyleId?: string | null;
|
||||
assetStyleLabel?: string | null;
|
||||
assetStylePrompt?: string | null;
|
||||
}
|
||||
|
||||
export type CreateMatch3DSessionRequest = CreateMatch3DAgentSessionRequest;
|
||||
@@ -72,6 +77,9 @@ export interface Match3DCreatorConfig {
|
||||
referenceImageSrc?: string | null;
|
||||
clearCount: number;
|
||||
difficulty: number;
|
||||
assetStyleId?: string | null;
|
||||
assetStyleLabel?: string | null;
|
||||
assetStylePrompt?: string | null;
|
||||
}
|
||||
|
||||
export interface Match3DResultDraft {
|
||||
@@ -88,6 +96,7 @@ export interface Match3DResultDraft {
|
||||
totalItemCount?: number;
|
||||
publishReady?: boolean;
|
||||
blockers?: string[];
|
||||
generatedItemAssets?: Match3DGeneratedItemAsset[];
|
||||
}
|
||||
|
||||
export interface Match3DAgentMessage {
|
||||
|
||||
@@ -2,8 +2,38 @@
|
||||
* 抓大鹅 Match3D 作品读写共享契约。
|
||||
* 首版作品发布必须补齐游戏名称、标签、封面、题材、消除次数和难度。
|
||||
*/
|
||||
import type { CreationAudioAsset } from './creationAudio';
|
||||
|
||||
export type Match3DWorkPublicationStatus = 'draft' | 'published' | string;
|
||||
|
||||
export type Match3DGeneratedItemAssetStatus =
|
||||
| 'pending'
|
||||
| 'image_ready'
|
||||
| 'model_generating'
|
||||
| 'model_ready'
|
||||
| 'failed'
|
||||
| string;
|
||||
|
||||
export interface Match3DGeneratedItemAsset {
|
||||
itemId: string;
|
||||
itemName: string;
|
||||
imageSrc?: string | null;
|
||||
imageObjectKey?: string | null;
|
||||
modelSrc?: string | null;
|
||||
modelObjectKey?: string | null;
|
||||
modelFileName?: string | null;
|
||||
taskUuid?: string | null;
|
||||
subscriptionKey?: string | null;
|
||||
backgroundMusic?: CreationAudioAsset | null;
|
||||
clickSound?: CreationAudioAsset | null;
|
||||
status: Match3DGeneratedItemAssetStatus;
|
||||
error?: string | null;
|
||||
}
|
||||
|
||||
export interface PutMatch3DAudioAssetsRequest {
|
||||
generatedItemAssets: Match3DGeneratedItemAsset[];
|
||||
}
|
||||
|
||||
export interface PutMatch3DWorkRequest {
|
||||
gameName: string;
|
||||
themeText?: string;
|
||||
@@ -15,6 +45,15 @@ export interface PutMatch3DWorkRequest {
|
||||
difficulty: number;
|
||||
}
|
||||
|
||||
export interface GenerateMatch3DWorkTagsRequest {
|
||||
gameName: string;
|
||||
themeText: string;
|
||||
}
|
||||
|
||||
export interface GenerateMatch3DWorkTagsResponse {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export interface Match3DWorkSummary {
|
||||
workId: string;
|
||||
profileId: string;
|
||||
@@ -33,6 +72,7 @@ export interface Match3DWorkSummary {
|
||||
updatedAt: string;
|
||||
publishedAt?: string | null;
|
||||
publishReady: boolean;
|
||||
generatedItemAssets?: Match3DGeneratedItemAsset[];
|
||||
}
|
||||
|
||||
export interface Match3DWorkProfile extends Match3DWorkSummary {}
|
||||
|
||||
@@ -4,6 +4,7 @@ export type PuzzleAgentSuggestedActionType =
|
||||
| 'request_summary'
|
||||
| 'compile_puzzle_draft'
|
||||
| 'generate_puzzle_images'
|
||||
| 'generate_puzzle_tags'
|
||||
| 'publish_puzzle_work';
|
||||
|
||||
export interface PuzzleAgentSuggestedAction {
|
||||
@@ -16,6 +17,7 @@ export type PuzzleAgentActionType =
|
||||
| 'save_puzzle_form_draft'
|
||||
| 'compile_puzzle_draft'
|
||||
| 'generate_puzzle_images'
|
||||
| 'generate_puzzle_tags'
|
||||
| 'select_puzzle_image'
|
||||
| 'publish_puzzle_work';
|
||||
|
||||
@@ -46,7 +48,9 @@ export type PuzzleAgentActionRequest =
|
||||
workTitle?: string;
|
||||
workDescription?: string;
|
||||
pictureDescription?: string;
|
||||
referenceImageSrc?: string | null;
|
||||
imageModel?: string | null;
|
||||
aiRedraw?: boolean;
|
||||
}
|
||||
| {
|
||||
action: 'compile_puzzle_draft';
|
||||
@@ -56,6 +60,7 @@ export type PuzzleAgentActionRequest =
|
||||
pictureDescription?: string;
|
||||
referenceImageSrc?: string | null;
|
||||
imageModel?: string | null;
|
||||
aiRedraw?: boolean;
|
||||
candidateCount?: number;
|
||||
}
|
||||
| {
|
||||
@@ -64,6 +69,7 @@ export type PuzzleAgentActionRequest =
|
||||
promptText?: string | null;
|
||||
referenceImageSrc?: string | null;
|
||||
imageModel?: string | null;
|
||||
aiRedraw?: boolean;
|
||||
candidateCount?: number;
|
||||
workTitle?: string;
|
||||
workDescription?: string;
|
||||
@@ -71,6 +77,15 @@ export type PuzzleAgentActionRequest =
|
||||
themeTags?: string[];
|
||||
levelsJson?: string;
|
||||
}
|
||||
| {
|
||||
action: 'generate_puzzle_tags';
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
levelName?: string;
|
||||
summary?: string;
|
||||
themeTags?: string[];
|
||||
levelsJson?: string;
|
||||
}
|
||||
| {
|
||||
action: 'select_puzzle_image';
|
||||
levelId?: string | null;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { JsonObject } from './common';
|
||||
import type { CreationAudioAsset } from './creationAudio';
|
||||
|
||||
export type PuzzleAnchorStatus =
|
||||
| 'missing'
|
||||
@@ -46,6 +47,8 @@ export interface PuzzleDraftLevel {
|
||||
levelId: string;
|
||||
levelName: string;
|
||||
pictureDescription: string;
|
||||
pictureReference?: string | null;
|
||||
backgroundMusic?: CreationAudioAsset | null;
|
||||
candidates: PuzzleGeneratedImageCandidate[];
|
||||
selectedCandidateId: string | null;
|
||||
coverImageSrc: string | null;
|
||||
|
||||
@@ -51,6 +51,7 @@ export interface CreatePuzzleAgentSessionRequest {
|
||||
pictureDescription?: string;
|
||||
referenceImageSrc?: string | null;
|
||||
imageModel?: string | null;
|
||||
aiRedraw?: boolean;
|
||||
}
|
||||
|
||||
export interface CreatePuzzleAgentSessionResponse {
|
||||
|
||||
103
packages/shared/src/contracts/puzzleCreativeTemplate.ts
Normal file
103
packages/shared/src/contracts/puzzleCreativeTemplate.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
export type PuzzleTemplatePricingUnit = 'point';
|
||||
|
||||
export type PuzzleSupportedLevelMode =
|
||||
| 'single'
|
||||
| 'multi'
|
||||
| 'single_or_multi';
|
||||
|
||||
export type PuzzleLevelGenerationMode = 'single_level' | 'multi_level';
|
||||
|
||||
export interface PuzzleTemplateCostRange {
|
||||
minPoints: number;
|
||||
maxPoints: number;
|
||||
pricingUnit: PuzzleTemplatePricingUnit;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export type PuzzleDraftEditableFieldPath =
|
||||
| 'workTitle'
|
||||
| 'workDescription'
|
||||
| 'workTags'
|
||||
| 'levels[].levelName'
|
||||
| 'levels[].pictureDescription'
|
||||
| 'levels[].pictureReference';
|
||||
|
||||
export interface PuzzleTemplateImageGenerationPolicy {
|
||||
allowUploadedImageDirectly: boolean;
|
||||
allowGeneratedImages: boolean;
|
||||
allowPerLevelReferenceImage: boolean;
|
||||
defaultCandidateCountPerLevel: number;
|
||||
}
|
||||
|
||||
export interface PuzzleCreativeTemplateProtocol {
|
||||
templateId: string;
|
||||
title: string;
|
||||
summary: string;
|
||||
previewImageSrc: string | null;
|
||||
supportedLevelMode: PuzzleSupportedLevelMode;
|
||||
minLevelCount: number;
|
||||
maxLevelCount: number;
|
||||
defaultLevelCount: number;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
requiredDraftFields: PuzzleDraftEditableFieldPath[];
|
||||
imagePolicy: PuzzleTemplateImageGenerationPolicy;
|
||||
}
|
||||
|
||||
export interface PuzzleCreativeTemplateSelection {
|
||||
templateId: string;
|
||||
title: string;
|
||||
reason: string;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
supportedLevelMode: PuzzleSupportedLevelMode;
|
||||
selectedLevelMode: PuzzleLevelGenerationMode;
|
||||
plannedLevelCount: number;
|
||||
requiresUserConfirmation: true;
|
||||
}
|
||||
|
||||
export interface CreativePuzzleLevelDraftInput {
|
||||
levelName: string;
|
||||
pictureDescription: string;
|
||||
/**
|
||||
* 任务 A 冻结:Phase 1 采用正式字段方案,后续拼图草稿落地需补正式 pictureReference 字段。
|
||||
*/
|
||||
pictureReference?: string | null;
|
||||
}
|
||||
|
||||
export interface CreativePuzzleDraftToolInput {
|
||||
templateId: string;
|
||||
templateCostRange: PuzzleTemplateCostRange;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
levels: CreativePuzzleLevelDraftInput[];
|
||||
}
|
||||
|
||||
export interface PuzzleImageGenerationPlanLevel {
|
||||
levelId: string;
|
||||
levelName: string;
|
||||
pictureDescription: string;
|
||||
imagePrompt: string;
|
||||
pictureReference?: string | null;
|
||||
candidateCount: number;
|
||||
}
|
||||
|
||||
export interface PuzzleImageGenerationPlan {
|
||||
mode: PuzzleLevelGenerationMode;
|
||||
templateId: string;
|
||||
estimatedCostRange: PuzzleTemplateCostRange;
|
||||
levels: PuzzleImageGenerationPlanLevel[];
|
||||
}
|
||||
|
||||
export type PuzzleDraftFieldPatchOperation =
|
||||
| 'set'
|
||||
| 'append'
|
||||
| 'replace'
|
||||
| 'remove';
|
||||
|
||||
export interface PuzzleDraftFieldPatch {
|
||||
fieldPath: PuzzleDraftEditableFieldPath;
|
||||
operation: PuzzleDraftFieldPatchOperation;
|
||||
levelId?: string | null;
|
||||
value: unknown;
|
||||
rationale: string;
|
||||
}
|
||||
16
packages/shared/src/contracts/puzzleOnboarding.ts
Normal file
16
packages/shared/src/contracts/puzzleOnboarding.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { PuzzleDraftLevel } from './puzzleAgentDraft';
|
||||
import type { PuzzleWorkSummary } from './puzzleWorkSummary';
|
||||
|
||||
export interface PuzzleOnboardingGenerateRequest {
|
||||
promptText: string;
|
||||
}
|
||||
|
||||
export interface PuzzleOnboardingGenerateResponse {
|
||||
item: PuzzleWorkSummary;
|
||||
level: PuzzleDraftLevel;
|
||||
}
|
||||
|
||||
export interface PuzzleOnboardingSaveRequest {
|
||||
promptText: string;
|
||||
item: PuzzleWorkSummary;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ export interface PuzzleLeaderboardEntry {
|
||||
rank: number;
|
||||
nickname: string;
|
||||
elapsedMs: number;
|
||||
visibleTags?: string[];
|
||||
isCurrentPlayer?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ export type ProfileWalletLedgerEntry = {
|
||||
| 'asset_operation_consume'
|
||||
| 'asset_operation_refund'
|
||||
| 'redeem_code_reward'
|
||||
| 'puzzle_author_incentive_claim';
|
||||
| 'puzzle_author_incentive_claim'
|
||||
| 'daily_task_reward';
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
@@ -142,6 +143,39 @@ export type CreateProfileRechargeOrderResponse = {
|
||||
center: ProfileRechargeCenterResponse;
|
||||
};
|
||||
|
||||
export type ProfileFeedbackStatus = 'open';
|
||||
|
||||
export type ProfileFeedbackEvidenceItemInput = {
|
||||
fileName: string;
|
||||
contentType: string;
|
||||
sizeBytes: number;
|
||||
dataUrl: string;
|
||||
};
|
||||
|
||||
export type SubmitProfileFeedbackRequest = {
|
||||
description: string;
|
||||
contactPhone?: string | null;
|
||||
evidenceItems: ProfileFeedbackEvidenceItemInput[];
|
||||
};
|
||||
|
||||
export type ProfileFeedbackEvidenceItem = {
|
||||
evidenceId: string;
|
||||
fileName: string;
|
||||
contentType: string;
|
||||
sizeBytes: number;
|
||||
};
|
||||
|
||||
export type ProfileFeedbackSubmission = {
|
||||
feedbackId: string;
|
||||
status: ProfileFeedbackStatus;
|
||||
createdAt: string;
|
||||
evidenceItems: ProfileFeedbackEvidenceItem[];
|
||||
};
|
||||
|
||||
export type SubmitProfileFeedbackResponse = {
|
||||
feedback: ProfileFeedbackSubmission;
|
||||
};
|
||||
|
||||
export type ProfileReferralInviteCenterResponse = {
|
||||
inviteCode: string;
|
||||
inviteLinkPath: string;
|
||||
@@ -186,19 +220,157 @@ export type RedeemProfileRewardCodeResponse = {
|
||||
ledgerEntry: ProfileWalletLedgerEntry;
|
||||
};
|
||||
|
||||
export type ProfileTaskCycle = 'daily';
|
||||
export type TrackingScopeKind = 'site' | 'work' | 'module' | 'user';
|
||||
export type AnalyticsGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';
|
||||
export type ProfileTaskStatus =
|
||||
| 'incomplete'
|
||||
| 'claimable'
|
||||
| 'claimed'
|
||||
| 'disabled';
|
||||
|
||||
export type ProfileTaskItem = {
|
||||
taskId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
eventKey: string;
|
||||
cycle: ProfileTaskCycle;
|
||||
threshold: number;
|
||||
progressCount: number;
|
||||
rewardPoints: number;
|
||||
status: ProfileTaskStatus;
|
||||
dayKey: number;
|
||||
claimedAt: string | null;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ProfileTaskCenterResponse = {
|
||||
dayKey: number;
|
||||
walletBalance: number;
|
||||
tasks: ProfileTaskItem[];
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ClaimProfileTaskRewardResponse = {
|
||||
taskId: string;
|
||||
dayKey: number;
|
||||
rewardPoints: number;
|
||||
walletBalance: number;
|
||||
ledgerEntry: ProfileWalletLedgerEntry;
|
||||
center: ProfileTaskCenterResponse;
|
||||
};
|
||||
|
||||
export type ProfileTaskConfigAdminResponse = {
|
||||
taskId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
eventKey: string;
|
||||
cycle: ProfileTaskCycle;
|
||||
scopeKind: TrackingScopeKind;
|
||||
threshold: number;
|
||||
rewardPoints: number;
|
||||
enabled: boolean;
|
||||
sortOrder: number;
|
||||
createdBy: string;
|
||||
createdAt: string;
|
||||
updatedBy: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ProfileTaskConfigAdminListResponse = {
|
||||
entries: ProfileTaskConfigAdminResponse[];
|
||||
};
|
||||
|
||||
export type AnalyticsMetricQueryRequest = {
|
||||
eventKey: string;
|
||||
scopeKind: TrackingScopeKind;
|
||||
scopeId: string;
|
||||
granularity: AnalyticsGranularity;
|
||||
};
|
||||
|
||||
export type AnalyticsBucketMetric = {
|
||||
bucketKey: string;
|
||||
bucketStartDateKey: number;
|
||||
bucketEndDateKey: number;
|
||||
value: number;
|
||||
};
|
||||
|
||||
export type AnalyticsMetricQueryResponse = {
|
||||
buckets: AnalyticsBucketMetric[];
|
||||
};
|
||||
|
||||
export type AdminUpsertProfileTaskConfigRequest = {
|
||||
taskId: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
eventKey: string;
|
||||
cycle: ProfileTaskCycle;
|
||||
scopeKind: TrackingScopeKind;
|
||||
threshold: number;
|
||||
rewardPoints: number;
|
||||
enabled?: boolean;
|
||||
sortOrder?: number;
|
||||
};
|
||||
|
||||
export type AdminDisableProfileTaskConfigRequest = {
|
||||
taskId: string;
|
||||
};
|
||||
|
||||
export type ProfileRedeemCodeMode = 'public' | 'unique' | 'private';
|
||||
|
||||
export type ProfileRedeemCodeAdminResponse = {
|
||||
code: string;
|
||||
mode: ProfileRedeemCodeMode;
|
||||
rewardPoints: number;
|
||||
maxUses: number;
|
||||
globalUsedCount: number;
|
||||
enabled: boolean;
|
||||
allowedUserIds: string[];
|
||||
createdBy: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ProfileRedeemCodeAdminListResponse = {
|
||||
entries: ProfileRedeemCodeAdminResponse[];
|
||||
};
|
||||
|
||||
export type AdminUpsertProfileRedeemCodeRequest = {
|
||||
code: string;
|
||||
mode: ProfileRedeemCodeMode;
|
||||
rewardPoints: number;
|
||||
maxUses: number;
|
||||
enabled?: boolean;
|
||||
allowedUserIds?: string[];
|
||||
allowedPublicUserCodes?: string[];
|
||||
};
|
||||
|
||||
export type AdminDisableProfileRedeemCodeRequest = {
|
||||
code: string;
|
||||
};
|
||||
|
||||
export type AdminUpsertProfileInviteCodeRequest = {
|
||||
inviteCode: string;
|
||||
metadata?: Record<string, unknown> | null;
|
||||
startsAt?: string | null;
|
||||
expiresAt?: string | null;
|
||||
};
|
||||
|
||||
export type ProfileInviteCodeAdminResponse = {
|
||||
userId: string;
|
||||
inviteCode: string;
|
||||
metadata: Record<string, unknown>;
|
||||
startsAt?: string | null;
|
||||
expiresAt?: string | null;
|
||||
status: 'pending' | 'active' | 'expired';
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ProfileInviteCodeAdminListResponse = {
|
||||
entries: ProfileInviteCodeAdminResponse[];
|
||||
};
|
||||
|
||||
export type ProfilePlayedWorkSummary = {
|
||||
worldKey: string;
|
||||
ownerUserId: string | null;
|
||||
@@ -253,6 +425,38 @@ export type CustomWorldThemeMode =
|
||||
|
||||
export type CustomWorldProfileRecord = JsonObject & {
|
||||
id?: string;
|
||||
openingCg?: CustomWorldOpeningCgProfile | null;
|
||||
};
|
||||
|
||||
export type CustomWorldOpeningCgStatus =
|
||||
| 'not_started'
|
||||
| 'storyboard_generating'
|
||||
| 'video_generating'
|
||||
| 'ready'
|
||||
| 'failed';
|
||||
|
||||
export type CustomWorldOpeningCgProfile = {
|
||||
id: string;
|
||||
status: CustomWorldOpeningCgStatus;
|
||||
storyboardImageSrc?: string | null;
|
||||
storyboardAssetId?: string | null;
|
||||
videoSrc?: string | null;
|
||||
videoAssetId?: string | null;
|
||||
posterImageSrc?: string | null;
|
||||
posterAssetId?: string | null;
|
||||
storyboardPrompt?: string | null;
|
||||
videoPrompt?: string | null;
|
||||
imageModel: 'gpt-image-2';
|
||||
videoModel: string;
|
||||
aspectRatio: '16:9';
|
||||
imageSize: '2k';
|
||||
videoResolution: '480p';
|
||||
durationSeconds: 15;
|
||||
pointCost: 80;
|
||||
estimatedWaitMinutes: 10;
|
||||
generatedAt?: string | null;
|
||||
updatedAt: string;
|
||||
errorMessage?: string | null;
|
||||
};
|
||||
|
||||
export type CustomWorldLibraryEntry<TProfile = CustomWorldProfileRecord> = {
|
||||
|
||||
130
packages/shared/src/contracts/squareHoleAgent.ts
Normal file
130
packages/shared/src/contracts/squareHoleAgent.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* 方洞挑战创作 Agent 共享契约。
|
||||
* 字段按 HTTP facade 的 camelCase DTO 命名,后端领域层 snake_case 字段由 facade 映射。
|
||||
*/
|
||||
export type SquareHoleCreationStage =
|
||||
| 'collecting_config'
|
||||
| 'draft_ready'
|
||||
| string;
|
||||
|
||||
export type SquareHoleAnchorStatus =
|
||||
| 'confirmed'
|
||||
| 'missing'
|
||||
| 'inferred'
|
||||
| string;
|
||||
|
||||
export interface CreateSquareHoleSessionRequest {
|
||||
seedText?: string;
|
||||
themeText?: string;
|
||||
twistRule?: string;
|
||||
shapeCount?: number;
|
||||
difficulty?: number;
|
||||
}
|
||||
|
||||
export interface SendSquareHoleMessageRequest {
|
||||
clientMessageId: string;
|
||||
text: string;
|
||||
quickFillRequested?: boolean;
|
||||
}
|
||||
|
||||
export interface ExecuteSquareHoleActionRequest {
|
||||
action: string;
|
||||
gameName?: string;
|
||||
summary?: string;
|
||||
tags?: string[];
|
||||
coverImageSrc?: string | null;
|
||||
regenerateVisualAssets?: boolean;
|
||||
visualAssetSlot?: 'cover' | 'background' | 'shape' | string | null;
|
||||
visualAssetOptionId?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleShapeOption {
|
||||
optionId: string;
|
||||
shapeKind: string;
|
||||
label: string;
|
||||
targetHoleId: string;
|
||||
imagePrompt: string;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleHoleOption {
|
||||
holeId: string;
|
||||
holeKind: string;
|
||||
label: string;
|
||||
imagePrompt: string;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleAnchorItemResponse {
|
||||
key: string;
|
||||
label: string;
|
||||
value: string;
|
||||
status: SquareHoleAnchorStatus;
|
||||
}
|
||||
|
||||
export interface SquareHoleAnchorPackResponse {
|
||||
theme: SquareHoleAnchorItemResponse;
|
||||
twistRule: SquareHoleAnchorItemResponse;
|
||||
shapeCount: SquareHoleAnchorItemResponse;
|
||||
difficulty: SquareHoleAnchorItemResponse;
|
||||
}
|
||||
|
||||
export interface SquareHoleCreatorConfig {
|
||||
themeText: string;
|
||||
twistRule: string;
|
||||
shapeCount: number;
|
||||
difficulty: number;
|
||||
shapeOptions: SquareHoleShapeOption[];
|
||||
holeOptions: SquareHoleHoleOption[];
|
||||
backgroundPrompt: string;
|
||||
coverImageSrc?: string | null;
|
||||
backgroundImageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleResultDraft {
|
||||
profileId: string;
|
||||
gameName: string;
|
||||
themeText: string;
|
||||
twistRule: string;
|
||||
summary: string;
|
||||
tags: string[];
|
||||
coverImageSrc?: string | null;
|
||||
backgroundPrompt: string;
|
||||
backgroundImageSrc?: string | null;
|
||||
shapeOptions: SquareHoleShapeOption[];
|
||||
holeOptions: SquareHoleHoleOption[];
|
||||
shapeCount: number;
|
||||
difficulty: number;
|
||||
publishReady: boolean;
|
||||
blockers: string[];
|
||||
}
|
||||
|
||||
export interface SquareHoleAgentMessage {
|
||||
id: string;
|
||||
role: 'user' | 'assistant' | 'system' | string;
|
||||
kind: 'chat' | 'summary' | 'action_result' | 'warning' | string;
|
||||
text: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface SquareHoleSessionSnapshot {
|
||||
sessionId: string;
|
||||
currentTurn: number;
|
||||
progressPercent: number;
|
||||
stage: SquareHoleCreationStage;
|
||||
anchorPack: SquareHoleAnchorPackResponse;
|
||||
config: SquareHoleCreatorConfig;
|
||||
draft?: SquareHoleResultDraft | null;
|
||||
messages: SquareHoleAgentMessage[];
|
||||
lastAssistantReply?: string | null;
|
||||
publishedProfileId?: string | null;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface SquareHoleSessionResponse {
|
||||
session: SquareHoleSessionSnapshot;
|
||||
}
|
||||
|
||||
export interface SquareHoleActionResponse {
|
||||
session: SquareHoleSessionSnapshot;
|
||||
}
|
||||
103
packages/shared/src/contracts/squareHoleRuntime.ts
Normal file
103
packages/shared/src/contracts/squareHoleRuntime.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 方洞挑战运行态共享契约。
|
||||
* 后端负责当前形状、洞口兼容、胜负和连击真相;前端只提交洞口选择并渲染快照。
|
||||
*/
|
||||
export type SquareHoleRunStatus =
|
||||
| 'running'
|
||||
| 'won'
|
||||
| 'failed'
|
||||
| 'stopped'
|
||||
| string;
|
||||
export type SquareHoleShapeKind =
|
||||
| 'square'
|
||||
| 'circle'
|
||||
| 'triangle'
|
||||
| 'star'
|
||||
| 'arch'
|
||||
| 'diamond'
|
||||
| string;
|
||||
export type SquareHoleHoleKind =
|
||||
| 'square'
|
||||
| 'circle'
|
||||
| 'triangle'
|
||||
| 'star'
|
||||
| 'arch'
|
||||
| 'diamond'
|
||||
| string;
|
||||
export type SquareHoleDropRejectReason =
|
||||
| 'run_not_active'
|
||||
| 'snapshot_version_mismatch'
|
||||
| 'hole_not_found'
|
||||
| 'incompatible'
|
||||
| 'time_up'
|
||||
| string;
|
||||
|
||||
export interface SquareHoleShapeSnapshot {
|
||||
shapeId: string;
|
||||
shapeKind: SquareHoleShapeKind;
|
||||
label: string;
|
||||
targetHoleId: string;
|
||||
color: string;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleHoleSnapshot {
|
||||
holeId: string;
|
||||
holeKind: SquareHoleHoleKind;
|
||||
label: string;
|
||||
x: number;
|
||||
y: number;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleRunSnapshot {
|
||||
runId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
status: SquareHoleRunStatus;
|
||||
snapshotVersion: number;
|
||||
startedAtMs: number;
|
||||
durationLimitMs: number;
|
||||
remainingMs: number;
|
||||
totalShapeCount: number;
|
||||
completedShapeCount: number;
|
||||
combo: number;
|
||||
bestCombo: number;
|
||||
score: number;
|
||||
ruleLabel: string;
|
||||
backgroundImageSrc?: string | null;
|
||||
currentShape?: SquareHoleShapeSnapshot | null;
|
||||
holes: SquareHoleHoleSnapshot[];
|
||||
lastFeedback?: SquareHoleDropFeedback | null;
|
||||
}
|
||||
|
||||
export interface StartSquareHoleRunRequest {
|
||||
profileId: string;
|
||||
}
|
||||
|
||||
export interface DropSquareHoleShapeRequest {
|
||||
runId?: string;
|
||||
holeId: string;
|
||||
clientSnapshotVersion: number;
|
||||
clientEventId: string;
|
||||
droppedAtMs: number;
|
||||
}
|
||||
|
||||
export interface StopSquareHoleRunRequest {
|
||||
clientActionId: string;
|
||||
}
|
||||
|
||||
export interface SquareHoleDropFeedback {
|
||||
accepted: boolean;
|
||||
rejectReason?: SquareHoleDropRejectReason | null;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface SquareHoleDropResponse {
|
||||
feedback: SquareHoleDropFeedback;
|
||||
run: SquareHoleRunSnapshot;
|
||||
}
|
||||
|
||||
export interface SquareHoleRunResponse {
|
||||
run: SquareHoleRunSnapshot;
|
||||
}
|
||||
80
packages/shared/src/contracts/squareHoleWorks.ts
Normal file
80
packages/shared/src/contracts/squareHoleWorks.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 方洞挑战作品读写共享契约。
|
||||
* 作品字段只表达结果页可编辑信息;运行规则真相由后端 runtime 快照负责。
|
||||
*/
|
||||
export type SquareHoleWorkPublicationStatus = 'draft' | 'published' | string;
|
||||
|
||||
export interface SquareHoleShapeOption {
|
||||
optionId: string;
|
||||
shapeKind: string;
|
||||
label: string;
|
||||
targetHoleId: string;
|
||||
imagePrompt: string;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleHoleOption {
|
||||
holeId: string;
|
||||
holeKind: string;
|
||||
label: string;
|
||||
imagePrompt: string;
|
||||
imageSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface PutSquareHoleWorkRequest {
|
||||
gameName: string;
|
||||
themeText?: string;
|
||||
twistRule: string;
|
||||
summary: string;
|
||||
tags: string[];
|
||||
coverImageSrc?: string | null;
|
||||
backgroundPrompt?: string;
|
||||
backgroundImageSrc?: string | null;
|
||||
shapeOptions?: SquareHoleShapeOption[];
|
||||
holeOptions?: SquareHoleHoleOption[];
|
||||
shapeCount: number;
|
||||
difficulty: number;
|
||||
}
|
||||
|
||||
export interface RegenerateSquareHoleWorkImageRequest {
|
||||
visualAssetSlot: 'cover' | 'background' | 'shape' | 'hole' | string;
|
||||
visualAssetOptionId?: string | null;
|
||||
}
|
||||
|
||||
export interface SquareHoleWorkSummary {
|
||||
workId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
sourceSessionId?: string | null;
|
||||
gameName: string;
|
||||
themeText: string;
|
||||
twistRule: string;
|
||||
summary: string;
|
||||
tags: string[];
|
||||
coverImageSrc?: string | null;
|
||||
backgroundPrompt: string;
|
||||
backgroundImageSrc?: string | null;
|
||||
shapeOptions: SquareHoleShapeOption[];
|
||||
holeOptions: SquareHoleHoleOption[];
|
||||
shapeCount: number;
|
||||
difficulty: number;
|
||||
publicationStatus: SquareHoleWorkPublicationStatus;
|
||||
playCount: number;
|
||||
updatedAt: string;
|
||||
publishedAt?: string | null;
|
||||
publishReady: boolean;
|
||||
}
|
||||
|
||||
export interface SquareHoleWorkProfile extends SquareHoleWorkSummary {}
|
||||
|
||||
export interface SquareHoleWorksResponse {
|
||||
items: SquareHoleWorkSummary[];
|
||||
}
|
||||
|
||||
export interface SquareHoleWorkDetailResponse {
|
||||
item: SquareHoleWorkProfile;
|
||||
}
|
||||
|
||||
export interface SquareHoleWorkMutationResponse {
|
||||
item: SquareHoleWorkProfile;
|
||||
}
|
||||
452
packages/shared/src/contracts/visualNovel.ts
Normal file
452
packages/shared/src/contracts/visualNovel.ts
Normal file
@@ -0,0 +1,452 @@
|
||||
export type VisualNovelSourceMode = 'idea' | 'document' | 'blank';
|
||||
|
||||
export type VisualNovelCharacterRole =
|
||||
| 'protagonist'
|
||||
| 'main'
|
||||
| 'supporting'
|
||||
| 'antagonist'
|
||||
| 'background';
|
||||
|
||||
export type VisualNovelAssetSource =
|
||||
| 'platform_asset'
|
||||
| 'generated'
|
||||
| 'external';
|
||||
|
||||
export type VisualNovelAudioGenerationKind =
|
||||
| 'background_music'
|
||||
| 'sound_effect';
|
||||
|
||||
export type VisualNovelSceneAvailability =
|
||||
| 'opening'
|
||||
| 'always'
|
||||
| 'phase_locked';
|
||||
|
||||
export type VisualNovelAttributePanelMode =
|
||||
| 'off'
|
||||
| 'platform_whitelist'
|
||||
| 'template_config';
|
||||
|
||||
export type VisualNovelValidationSeverity = 'error' | 'warning';
|
||||
|
||||
export type VisualNovelAgentStatus =
|
||||
| 'collecting'
|
||||
| 'drafting'
|
||||
| 'ready'
|
||||
| 'failed';
|
||||
|
||||
export type VisualNovelAgentMessageRole = 'user' | 'assistant' | 'system';
|
||||
|
||||
export type VisualNovelAgentMessageKind =
|
||||
| 'chat'
|
||||
| 'summary'
|
||||
| 'action_result'
|
||||
| 'warning';
|
||||
|
||||
export type VisualNovelAgentActionKind =
|
||||
| 'generate_draft'
|
||||
| 'patch_world'
|
||||
| 'patch_character'
|
||||
| 'patch_scene'
|
||||
| 'patch_story_phase'
|
||||
| 'generate_scene_image'
|
||||
| 'generate_character_image'
|
||||
| 'compile_work_profile';
|
||||
|
||||
export type VisualNovelAgentPhase =
|
||||
| 'perception'
|
||||
| 'reasoning'
|
||||
| 'drafting'
|
||||
| 'reflection'
|
||||
| 'finalizing';
|
||||
|
||||
export type VisualNovelRunMode = 'test' | 'play';
|
||||
|
||||
export type VisualNovelRunStatus = 'active' | 'completed' | 'failed';
|
||||
|
||||
export type VisualNovelRuntimeActionKind = 'choice' | 'free_text' | 'continue';
|
||||
|
||||
export type VisualNovelTransitionKind = 'fade' | 'cut' | 'flash' | 'none';
|
||||
|
||||
export type VisualNovelHistorySource = 'player' | 'assistant' | 'system';
|
||||
|
||||
export type VisualNovelFlagValue = string | number | boolean;
|
||||
|
||||
export interface VisualNovelDraftPatch {
|
||||
path: string;
|
||||
op: 'add' | 'replace' | 'remove';
|
||||
value?: unknown;
|
||||
}
|
||||
|
||||
export interface VisualNovelValidationIssue {
|
||||
issueId: string;
|
||||
code: string;
|
||||
severity: VisualNovelValidationSeverity;
|
||||
path: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelChoiceDraft {
|
||||
choiceId: string;
|
||||
text: string;
|
||||
actionHint?: string | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelCharacterImageAsset {
|
||||
assetId: string;
|
||||
imageSrc: string;
|
||||
expression?: string | null;
|
||||
source: VisualNovelAssetSource;
|
||||
}
|
||||
|
||||
export interface VisualNovelWorldDraft {
|
||||
title: string;
|
||||
summary: string;
|
||||
background: string;
|
||||
premise: string;
|
||||
literaryStyle: string;
|
||||
playerRole: string;
|
||||
defaultTone: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelCharacterDraft {
|
||||
characterId: string;
|
||||
name: string;
|
||||
gender: string | null;
|
||||
role: VisualNovelCharacterRole;
|
||||
appearance: string;
|
||||
personality: string;
|
||||
tone: string;
|
||||
background: string;
|
||||
relationshipToPlayer: string;
|
||||
imageAssets: VisualNovelCharacterImageAsset[];
|
||||
defaultExpression: string | null;
|
||||
isPlayerVisible: boolean;
|
||||
}
|
||||
|
||||
export interface VisualNovelSceneDraft {
|
||||
sceneId: string;
|
||||
name: string;
|
||||
description: string;
|
||||
backgroundImageSrc: string | null;
|
||||
musicSrc: string | null;
|
||||
ambientSoundSrc: string | null;
|
||||
availability: VisualNovelSceneAvailability;
|
||||
phaseIds: string[];
|
||||
}
|
||||
|
||||
export interface VisualNovelStoryPhaseDraft {
|
||||
phaseId: string;
|
||||
title: string;
|
||||
goal: string;
|
||||
summary: string;
|
||||
entryCondition: string;
|
||||
exitCondition: string;
|
||||
sceneIds: string[];
|
||||
characterIds: string[];
|
||||
suggestedChoices: string[];
|
||||
}
|
||||
|
||||
export interface VisualNovelOpeningDraft {
|
||||
sceneId: string | null;
|
||||
narration: string;
|
||||
speakerCharacterId: string | null;
|
||||
firstDialogue: string | null;
|
||||
initialChoices: VisualNovelChoiceDraft[];
|
||||
}
|
||||
|
||||
export interface VisualNovelRuntimeConfigDraft {
|
||||
textModeEnabled: boolean;
|
||||
defaultTextMode: boolean;
|
||||
maxHistoryEntries: number;
|
||||
maxAssistantStepCountPerTurn: number;
|
||||
allowFreeTextAction: boolean;
|
||||
allowHistoryRegeneration: boolean;
|
||||
attributePanelMode: VisualNovelAttributePanelMode;
|
||||
saveArchiveEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface VisualNovelResultDraft {
|
||||
profileId: string | null;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
coverImageSrc: string | null;
|
||||
sourceMode: VisualNovelSourceMode;
|
||||
sourceAssetIds: string[];
|
||||
world: VisualNovelWorldDraft;
|
||||
characters: VisualNovelCharacterDraft[];
|
||||
scenes: VisualNovelSceneDraft[];
|
||||
storyPhases: VisualNovelStoryPhaseDraft[];
|
||||
opening: VisualNovelOpeningDraft;
|
||||
runtimeConfig: VisualNovelRuntimeConfigDraft;
|
||||
publishReady: boolean;
|
||||
validationIssues: VisualNovelValidationIssue[];
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelAgentMessage {
|
||||
id: string;
|
||||
role: VisualNovelAgentMessageRole;
|
||||
kind: VisualNovelAgentMessageKind;
|
||||
text: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelAgentPendingAction {
|
||||
actionId: string;
|
||||
kind: VisualNovelAgentActionKind;
|
||||
label: string;
|
||||
targetId?: string | null;
|
||||
payload?: unknown;
|
||||
}
|
||||
|
||||
export interface VisualNovelAgentSessionSnapshot {
|
||||
sessionId: string;
|
||||
ownerUserId: string;
|
||||
sourceMode: VisualNovelSourceMode;
|
||||
status: VisualNovelAgentStatus;
|
||||
messages: VisualNovelAgentMessage[];
|
||||
draft: VisualNovelResultDraft | null;
|
||||
pendingAction: VisualNovelAgentPendingAction | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CreateVisualNovelSessionRequest {
|
||||
sourceMode: VisualNovelSourceMode;
|
||||
seedText?: string | null;
|
||||
sourceAssetIds?: string[];
|
||||
}
|
||||
|
||||
export interface VisualNovelSessionResponse {
|
||||
session: VisualNovelAgentSessionSnapshot;
|
||||
}
|
||||
|
||||
export interface VisualNovelWorkSummary {
|
||||
runtimeKind: 'visual-novel';
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
coverImageSrc: string | null;
|
||||
tags: string[];
|
||||
publishStatus: string;
|
||||
publishReady: boolean;
|
||||
playCount: number;
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelWorkDetail {
|
||||
workId: string;
|
||||
summary: VisualNovelWorkSummary;
|
||||
sourceSessionId: string | null;
|
||||
authorDisplayName: string;
|
||||
sourceAssetIds: string[];
|
||||
draft: VisualNovelResultDraft;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelWorksResponse {
|
||||
works: VisualNovelWorkSummary[];
|
||||
}
|
||||
|
||||
export interface VisualNovelWorkResponse {
|
||||
work: VisualNovelWorkDetail;
|
||||
}
|
||||
|
||||
export interface UpdateVisualNovelWorkRequest {
|
||||
draft: VisualNovelResultDraft;
|
||||
}
|
||||
|
||||
export interface VisualNovelCompileResponse {
|
||||
session: VisualNovelAgentSessionSnapshot;
|
||||
work: VisualNovelWorkDetail;
|
||||
}
|
||||
|
||||
export interface CreateVisualNovelBackgroundMusicRequest {
|
||||
prompt: string;
|
||||
title: string;
|
||||
tags?: string | null;
|
||||
model?: string | null;
|
||||
}
|
||||
|
||||
export interface CreateVisualNovelSoundEffectRequest {
|
||||
prompt: string;
|
||||
duration?: number | null;
|
||||
seed?: number | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelAudioGenerationTaskResponse {
|
||||
kind: VisualNovelAudioGenerationKind;
|
||||
taskId: string;
|
||||
provider: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface PublishVisualNovelGeneratedAudioAssetRequest {
|
||||
sceneId: string;
|
||||
profileId?: string | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelGeneratedAudioAssetResponse {
|
||||
kind: VisualNovelAudioGenerationKind;
|
||||
taskId: string;
|
||||
provider: string;
|
||||
status: string;
|
||||
assetObjectId?: string | null;
|
||||
assetKind?: string | null;
|
||||
audioSrc?: string | null;
|
||||
}
|
||||
|
||||
export interface SendVisualNovelMessageRequest {
|
||||
clientMessageId: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface ExecuteVisualNovelAgentActionRequest {
|
||||
actionId?: string | null;
|
||||
kind: VisualNovelAgentActionKind;
|
||||
targetId?: string | null;
|
||||
payload?: unknown;
|
||||
}
|
||||
|
||||
export interface CompileVisualNovelWorkProfileRequest {
|
||||
draft: VisualNovelResultDraft;
|
||||
}
|
||||
|
||||
export type VisualNovelAgentStreamEvent =
|
||||
| { type: 'start'; sessionId: string }
|
||||
| { type: 'phase'; phase: VisualNovelAgentPhase }
|
||||
| { type: 'text_delta'; text: string }
|
||||
| { type: 'draft_patch'; patch: VisualNovelDraftPatch }
|
||||
| { type: 'action_required'; action: VisualNovelAgentPendingAction }
|
||||
| { type: 'complete'; session: VisualNovelAgentSessionSnapshot }
|
||||
| { type: 'error'; message: string; retryable: boolean }
|
||||
| { type: 'done' };
|
||||
|
||||
export interface VisualNovelSceneChangeStep {
|
||||
type: 'scene_change';
|
||||
sceneId: string;
|
||||
backgroundImageSrc: string | null;
|
||||
musicSrc: string | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelNarrationStep {
|
||||
type: 'narration';
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelDialogueStep {
|
||||
type: 'dialogue';
|
||||
characterId: string;
|
||||
characterName: string;
|
||||
expression: string | null;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelTransitionStep {
|
||||
type: 'transition';
|
||||
transitionKind: VisualNovelTransitionKind;
|
||||
text: string | null;
|
||||
}
|
||||
|
||||
export interface VisualNovelChoiceStep {
|
||||
type: 'choice';
|
||||
choices: VisualNovelChoiceDraft[];
|
||||
}
|
||||
|
||||
export interface VisualNovelFlagStep {
|
||||
type: 'flag';
|
||||
key: string;
|
||||
value: VisualNovelFlagValue;
|
||||
}
|
||||
|
||||
export interface VisualNovelMetricStep {
|
||||
type: 'metric';
|
||||
key: string;
|
||||
delta: number;
|
||||
}
|
||||
|
||||
export type VisualNovelRuntimeStep =
|
||||
| VisualNovelSceneChangeStep
|
||||
| VisualNovelNarrationStep
|
||||
| VisualNovelDialogueStep
|
||||
| VisualNovelTransitionStep
|
||||
| VisualNovelChoiceStep
|
||||
| VisualNovelFlagStep
|
||||
| VisualNovelMetricStep;
|
||||
|
||||
export interface VisualNovelHistoryEntry {
|
||||
entryId: string;
|
||||
runId: string;
|
||||
turnIndex: number;
|
||||
source: VisualNovelHistorySource;
|
||||
actionText: string | null;
|
||||
steps: VisualNovelRuntimeStep[];
|
||||
snapshotBeforeHash: string | null;
|
||||
snapshotAfterHash: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelRunSnapshot {
|
||||
runId: string;
|
||||
ownerUserId: string;
|
||||
profileId: string;
|
||||
mode: VisualNovelRunMode;
|
||||
status: VisualNovelRunStatus;
|
||||
currentSceneId: string | null;
|
||||
currentPhaseId: string | null;
|
||||
visibleCharacterIds: string[];
|
||||
flags: Record<string, VisualNovelFlagValue>;
|
||||
metrics: Record<string, number>;
|
||||
history: VisualNovelHistoryEntry[];
|
||||
availableChoices: VisualNovelChoiceDraft[];
|
||||
textModeEnabled: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelRuntimeActionRequest {
|
||||
actionKind: VisualNovelRuntimeActionKind;
|
||||
choiceId?: string;
|
||||
text?: string;
|
||||
clientEventId: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelStartRunRequest {
|
||||
profileId: string;
|
||||
mode: VisualNovelRunMode;
|
||||
}
|
||||
|
||||
export interface VisualNovelRunResponse {
|
||||
run: VisualNovelRunSnapshot;
|
||||
}
|
||||
|
||||
export interface VisualNovelHistoryResponse {
|
||||
history: VisualNovelHistoryEntry[];
|
||||
}
|
||||
|
||||
export interface VisualNovelRegenerateRequest {
|
||||
historyEntryId: string;
|
||||
clientEventId: string;
|
||||
}
|
||||
|
||||
export interface VisualNovelSaveArchiveState {
|
||||
runtimeKind: 'visual-novel';
|
||||
profileId: string;
|
||||
runId: string;
|
||||
currentSceneId: string | null;
|
||||
currentPhaseId: string | null;
|
||||
historyCursor: number;
|
||||
snapshotHash: string | null;
|
||||
}
|
||||
|
||||
export type VisualNovelRuntimeStreamEvent =
|
||||
| { type: 'start'; runId: string }
|
||||
| { type: 'raw_text'; text: string }
|
||||
| { type: 'step'; step: VisualNovelRuntimeStep }
|
||||
| { type: 'snapshot'; run: VisualNovelRunSnapshot }
|
||||
| { type: 'complete'; run: VisualNovelRunSnapshot }
|
||||
| { type: 'error'; message: string; retryable: boolean }
|
||||
| { type: 'done' };
|
||||
@@ -3,13 +3,19 @@ export * from './contracts/auth';
|
||||
export type * from './contracts/bigFish';
|
||||
export * from './contracts/common';
|
||||
export type * from './contracts/creationAgentDocumentInput';
|
||||
export type * from './contracts/creationAudio';
|
||||
export type * from './contracts/creativeAgent';
|
||||
export type * from './contracts/customWorldAgent';
|
||||
export * from './contracts/edutainmentBabyObject';
|
||||
export type * from './contracts/hyper3d';
|
||||
export * from './contracts/match3dAgent';
|
||||
export * from './contracts/match3dRuntime';
|
||||
export * from './contracts/match3dWorks';
|
||||
export * from './contracts/puzzleAgentActions';
|
||||
export * from './contracts/puzzleAgentDraft';
|
||||
export * from './contracts/puzzleAgentSession';
|
||||
export type * from './contracts/puzzleCreativeTemplate';
|
||||
export * from './contracts/puzzleOnboarding';
|
||||
export * from './contracts/puzzleResultPreview';
|
||||
export * from './contracts/puzzleRuntimeSession';
|
||||
export * from './contracts/puzzleWorkSummary';
|
||||
@@ -26,7 +32,22 @@ export * from './contracts/rpgRuntimeQuestAssist';
|
||||
export * from './contracts/rpgRuntimeStoryAction';
|
||||
export * from './contracts/rpgRuntimeStoryState';
|
||||
export * from './contracts/runtime';
|
||||
export * from './contracts/squareHoleAgent';
|
||||
export * from './contracts/squareHoleRuntime';
|
||||
export type {
|
||||
PutSquareHoleWorkRequest,
|
||||
RegenerateSquareHoleWorkImageRequest,
|
||||
SquareHoleWorkDetailResponse,
|
||||
SquareHoleHoleOption as SquareHoleWorkHoleOption,
|
||||
SquareHoleWorkMutationResponse,
|
||||
SquareHoleWorkProfile,
|
||||
SquareHoleWorkPublicationStatus,
|
||||
SquareHoleShapeOption as SquareHoleWorkShapeOption,
|
||||
SquareHoleWorksResponse,
|
||||
SquareHoleWorkSummary,
|
||||
} from './contracts/squareHoleWorks';
|
||||
export type * from './contracts/story';
|
||||
export type * from './contracts/visualNovel';
|
||||
export * from './http';
|
||||
export * from './llm/narrativeLanguage';
|
||||
export * from './llm/parsers';
|
||||
|
||||
Reference in New Issue
Block a user