init with react+axum+spacetimedb
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-26 18:06:23 +08:00
commit cbc27bad4a
20199 changed files with 883714 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
import type { EightAnchorContent } from '../../packages/shared/src/contracts/customWorldAgent';
import { normalizeCustomWorldCreatorIntent } from './customWorldCreatorIntent';
import type { CustomWorldProfile } from '../types';
export type CustomWorldFoundationEntryId =
| 'world-promise'
| 'player-fantasy'
| 'theme-boundary'
| 'player-entry-point'
| 'core-conflict'
| 'key-relationships'
| 'hidden-lines'
| 'iconic-elements';
export type CustomWorldFoundationEntry = {
id: CustomWorldFoundationEntryId;
label: string;
value: string;
};
export function compactFoundationTextList(
values: Array<string | null | undefined>,
) {
return values.map((value) => value?.trim()).filter(Boolean) as string[];
}
export function parseFoundationTagText(value: string) {
return value
.split(/[;]/u)
.map((item) => item.trim())
.filter(Boolean);
}
function toText(value: unknown) {
return typeof value === 'string' ? value.trim() : '';
}
function toRecord(value: unknown) {
return value && typeof value === 'object' && !Array.isArray(value)
? (value as Record<string, unknown>)
: null;
}
function compactAnchorValue(value: unknown): string | null {
const text = toText(value);
if (text) {
return text;
}
if (Array.isArray(value)) {
const compacted = compactFoundationTextList(
value.map((item) => compactAnchorValue(item)),
).join('');
return compacted || null;
}
const record = toRecord(value);
if (record) {
const compacted = compactFoundationTextList(
Object.values(record).map((item) => compactAnchorValue(item)),
).join('');
return compacted || null;
}
return null;
}
function buildRelationshipSeedText(value: unknown) {
const record = toRecord(value);
if (!record) {
return '';
}
return compactFoundationTextList([
toText(record.name),
toText(record.role),
toText(record.relationToPlayer)
? `与玩家:${toText(record.relationToPlayer)}`
: '',
toText(record.hiddenHook) ? `代价/暗线:${toText(record.hiddenHook)}` : '',
]).join('');
}
function buildAnchorContentFromProfileFallback(
profile: CustomWorldProfile,
): EightAnchorContent {
const creatorIntent = normalizeCustomWorldCreatorIntent(profile.creatorIntent);
const relationshipSeed = creatorIntent?.keyCharacters[0] ?? null;
return {
worldPromise: compactFoundationTextList([
creatorIntent?.worldHook ||
profile.anchorPack?.worldSummary ||
profile.summary,
profile.subtitle || profile.settingText,
creatorIntent?.toneDirectives.join('、') || profile.tone,
]).join('') || null,
playerFantasy: compactFoundationTextList([
creatorIntent?.playerPremise || profile.playerGoal,
profile.playerGoal,
relationshipSeed?.hiddenHook ||
creatorIntent?.coreConflicts[0] ||
profile.coreConflicts[0] ||
'',
]).join('') || null,
themeBoundary: compactFoundationTextList([
creatorIntent?.themeKeywords.join('、') || '',
creatorIntent?.toneDirectives.join('、') || '',
profile.tone,
profile.subtitle,
creatorIntent?.forbiddenDirectives.length
? `避免:${creatorIntent.forbiddenDirectives.join('、')}`
: '',
]).join('') || null,
playerEntryPoint: compactFoundationTextList([
creatorIntent?.playerPremise || '',
creatorIntent?.openingSituation || profile.coreConflicts[0] || '',
profile.playerGoal,
]).join('') || null,
coreConflict: compactFoundationTextList([
(creatorIntent?.coreConflicts.length
? creatorIntent.coreConflicts
: profile.coreConflicts
).join('、'),
relationshipSeed?.hiddenHook || profile.summary || profile.settingText,
creatorIntent?.openingSituation || profile.coreConflicts[0] || profile.playerGoal,
]).join('') || null,
keyRelationships: relationshipSeed
? compactFoundationTextList([
relationshipSeed.name,
relationshipSeed.role,
relationshipSeed.relationToPlayer,
relationshipSeed.hiddenHook ? `代价/秘密:${relationshipSeed.hiddenHook}` : '',
]).join('')
: null,
hiddenLines: compactFoundationTextList([
relationshipSeed?.hiddenHook || '',
profile.summary,
profile.subtitle,
profile.majorFactions[0] || '',
creatorIntent?.openingSituation || profile.coreConflicts[0] || profile.playerGoal,
]).join('') || null,
iconicElements: compactFoundationTextList([
(creatorIntent?.iconicElements.length
? creatorIntent.iconicElements
: [
profile.anchorPack?.motifDirectives.join('、') || '',
profile.landmarks[0]?.name || '',
]
).join('、'),
profile.camp?.name || '',
profile.majorFactions[0] || '',
profile.playerGoal,
profile.coreConflicts[0] || '',
]).join('') || null,
} satisfies EightAnchorContent;
}
export function getCustomWorldFoundationAnchorContent(
profile: CustomWorldProfile,
) {
const anchorContentRecord = profile.anchorContent;
if (!anchorContentRecord) {
return buildAnchorContentFromProfileFallback(profile);
}
return {
worldPromise: compactAnchorValue(anchorContentRecord.worldPromise),
playerFantasy: compactAnchorValue(anchorContentRecord.playerFantasy),
themeBoundary: compactAnchorValue(anchorContentRecord.themeBoundary),
playerEntryPoint: compactAnchorValue(anchorContentRecord.playerEntryPoint),
coreConflict: compactAnchorValue(anchorContentRecord.coreConflict),
keyRelationships: compactAnchorValue(anchorContentRecord.keyRelationships),
hiddenLines: compactAnchorValue(anchorContentRecord.hiddenLines),
iconicElements: compactAnchorValue(anchorContentRecord.iconicElements),
} satisfies EightAnchorContent;
}
export function buildCustomWorldFoundationEntries(
profile: CustomWorldProfile,
): CustomWorldFoundationEntry[] {
const creatorIntent = normalizeCustomWorldCreatorIntent(profile.creatorIntent);
const anchorContent = getCustomWorldFoundationAnchorContent(profile);
const fallbackRelationshipText =
buildRelationshipSeedText(creatorIntent?.keyCharacters[0]) ||
profile.playableNpcs[0]?.relationshipHooks.join('') ||
profile.storyNpcs[0]?.relationshipHooks.join('') ||
'';
return [
{
id: 'world-promise',
label: '世界承诺',
value: anchorContent.worldPromise || '',
},
{
id: 'player-fantasy',
label: '玩家幻想',
value: anchorContent.playerFantasy || '',
},
{
id: 'theme-boundary',
label: '主题边界',
value: anchorContent.themeBoundary || '',
},
{
id: 'player-entry-point',
label: '玩家切入口',
value: anchorContent.playerEntryPoint || '',
},
{
id: 'core-conflict',
label: '核心冲突',
value: anchorContent.coreConflict || '',
},
{
id: 'key-relationships',
label: '关键关系',
value: anchorContent.keyRelationships || fallbackRelationshipText,
},
{
id: 'hidden-lines',
label: '暗线与揭示',
value: anchorContent.hiddenLines || '',
},
{
id: 'iconic-elements',
label: '标志元素',
value: anchorContent.iconicElements || '',
},
];
}