收紧story与custom world迁移能力边界

This commit is contained in:
2026-04-20 12:06:04 +00:00
parent cdda334f62
commit c3bfd86b53
12 changed files with 189 additions and 200 deletions

View File

@@ -2,7 +2,6 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import type { CustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import {
buildPendingClarifications,
evaluateCreatorIntentReadiness,
@@ -15,8 +14,13 @@ import { CustomWorldAgentOrchestrator } from './customWorldAgentOrchestrator.js'
import { CustomWorldAgentSessionStore } from './customWorldAgentSessionStore.js';
import { createTestCustomWorldAgentSingleTurnLlmClient } from './customWorldAgentTestHelpers.js';
import { listCustomWorldWorkSummaries } from './customWorldWorkSummaryService.js';
import type {
CustomWorldSessionCapability,
CustomWorldWorkSummaryCapability,
} from './runtimeCapabilities.js';
function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
function createRuntimeRepositoryStub(): CustomWorldSessionCapability &
CustomWorldWorkSummaryCapability {
const sessionsByUser = new Map<
string,
Map<string, CustomWorldSessionRecord>
@@ -35,51 +39,9 @@ function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
};
return {
async getSnapshot(_userId) {
return null;
},
async putSnapshot(_userId, _payload) {
throw new Error('not implemented');
},
async deleteSnapshot(_userId) {
return undefined;
},
async getSettings() {
return {
musicVolume: 0.42,
platformTheme: 'light',
};
},
async putSettings(_userId, settings) {
return settings;
},
async listCustomWorldProfiles(userId) {
return [...(profilesByUser.get(userId) ?? [])];
},
async upsertCustomWorldProfile(userId, profileId, profile) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
current.unshift({
...profile,
id: profileId,
});
profilesByUser.set(userId, current);
return current;
},
async deleteCustomWorldProfile(userId, profileId) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
profilesByUser.set(userId, current);
return current;
},
async listProfileSaveArchives() {
return [];
},
async resumeProfileSaveArchive() {
return null;
},
async listCustomWorldSessions(userId) {
return [...getSessionBucket(userId).values()];
},

View File

@@ -2,13 +2,17 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import type { CustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import { CustomWorldAgentOrchestrator } from './customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './customWorldAgentSessionStore.js';
import { createTestCustomWorldAgentSingleTurnLlmClient } from './customWorldAgentTestHelpers.js';
import { listCustomWorldWorkSummaries } from './customWorldWorkSummaryService.js';
import type {
CustomWorldSessionCapability,
CustomWorldWorkSummaryCapability,
} from './runtimeCapabilities.js';
function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
function createRuntimeRepositoryStub(): CustomWorldSessionCapability &
CustomWorldWorkSummaryCapability {
const sessionsByUser = new Map<
string,
Map<string, CustomWorldSessionRecord>
@@ -27,51 +31,9 @@ function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
};
return {
async getSnapshot(_userId) {
return null;
},
async putSnapshot(_userId, _payload) {
throw new Error('not implemented');
},
async deleteSnapshot(_userId) {
return undefined;
},
async getSettings() {
return {
musicVolume: 0.42,
platformTheme: 'light',
};
},
async putSettings(_userId, settings) {
return settings;
},
async listCustomWorldProfiles(userId) {
return [...(profilesByUser.get(userId) ?? [])];
},
async upsertCustomWorldProfile(userId, profileId, profile) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
current.unshift({
...profile,
id: profileId,
});
profilesByUser.set(userId, current);
return current;
},
async deleteCustomWorldProfile(userId, profileId) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
profilesByUser.set(userId, current);
return current;
},
async listProfileSaveArchives() {
return [];
},
async resumeProfileSaveArchive() {
return null;
},
async listCustomWorldSessions(userId) {
return [...getSessionBucket(userId).values()];
},

View File

@@ -2,14 +2,18 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import type { CustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import { normalizeFoundationDraftProfile } from './customWorldAgentDraftCompiler.js';
import { CustomWorldAgentOrchestrator } from './customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './customWorldAgentSessionStore.js';
import { createTestCustomWorldAgentSingleTurnLlmClient } from './customWorldAgentTestHelpers.js';
import { listCustomWorldWorkSummaries } from './customWorldWorkSummaryService.js';
import type {
CustomWorldSessionCapability,
CustomWorldWorkSummaryCapability,
} from './runtimeCapabilities.js';
function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
function createRuntimeRepositoryStub(): CustomWorldSessionCapability &
CustomWorldWorkSummaryCapability {
const sessionsByUser = new Map<
string,
Map<string, CustomWorldSessionRecord>
@@ -28,51 +32,9 @@ function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
};
return {
async getSnapshot(_userId) {
return null;
},
async putSnapshot(_userId, _payload) {
throw new Error('not implemented');
},
async deleteSnapshot(_userId) {
return undefined;
},
async getSettings() {
return {
musicVolume: 0.42,
platformTheme: 'light',
};
},
async putSettings(_userId, settings) {
return settings;
},
async listCustomWorldProfiles(userId) {
return [...(profilesByUser.get(userId) ?? [])];
},
async upsertCustomWorldProfile(userId, profileId, profile) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
current.unshift({
...profile,
id: profileId,
});
profilesByUser.set(userId, current);
return current;
},
async deleteCustomWorldProfile(userId, profileId) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
profilesByUser.set(userId, current);
return current;
},
async listProfileSaveArchives() {
return [];
},
async resumeProfileSaveArchive() {
return null;
},
async listCustomWorldSessions(userId) {
return [...getSessionBucket(userId).values()];
},

View File

@@ -2,18 +2,17 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import type { CustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import { normalizeFoundationDraftProfile } from './customWorldAgentDraftCompiler.js';
import { CustomWorldAgentOrchestrator } from './customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './customWorldAgentSessionStore.js';
import { createTestCustomWorldAgentSingleTurnLlmClient } from './customWorldAgentTestHelpers.js';
import type { CustomWorldSessionCapability } from './runtimeCapabilities.js';
function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
function createRuntimeRepositoryStub(): CustomWorldSessionCapability {
const sessionsByUser = new Map<
string,
Map<string, CustomWorldSessionRecord>
>();
const profilesByUser = new Map<string, Record<string, unknown>[]>();
const getSessionBucket = (userId: string) => {
const existing = sessionsByUser.get(userId);
@@ -27,51 +26,6 @@ function createRuntimeRepositoryStub(): RuntimeRepositoryPort {
};
return {
async getSnapshot() {
return null;
},
async putSnapshot(_userId, payload) {
return payload;
},
async deleteSnapshot() {
return undefined;
},
async getSettings() {
return {
musicVolume: 0.42,
platformTheme: 'light',
};
},
async putSettings(_userId, settings) {
return settings;
},
async listCustomWorldProfiles(userId) {
return [...(profilesByUser.get(userId) ?? [])];
},
async upsertCustomWorldProfile(userId, profileId, profile) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
current.unshift({
...profile,
id: profileId,
});
profilesByUser.set(userId, current);
return current;
},
async deleteCustomWorldProfile(userId, profileId) {
const current = [...(profilesByUser.get(userId) ?? [])].filter(
(item) => String(item.id ?? '') !== profileId,
);
profilesByUser.set(userId, current);
return current;
},
async listProfileSaveArchives() {
return [];
},
async resumeProfileSaveArchive() {
return null;
},
async listCustomWorldSessions(userId) {
return [...getSessionBucket(userId).values()];
},

View File

@@ -13,7 +13,6 @@ import type {
EightAnchorContent,
} from '../../../packages/shared/src/contracts/customWorldAgent.js';
import type { CustomWorldSessionRecord as LegacyCustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import {
buildPendingClarifications,
evaluateCreatorIntentReadiness,
@@ -33,6 +32,7 @@ import {
estimateProgressPercentFromAnchorContent,
normalizeEightAnchorContent,
} from './eightAnchorCompatibilityService.js';
import type { CustomWorldSessionCapability } from './runtimeCapabilities.js';
export const CUSTOM_WORLD_AGENT_SESSION_ID_PREFIX =
'custom-world-agent-session-';
@@ -565,7 +565,7 @@ function toSnapshot(
}
export class CustomWorldAgentSessionStore {
constructor(private readonly runtimeRepository: RuntimeRepositoryPort) {}
constructor(private readonly runtimeRepository: CustomWorldSessionCapability) {}
private async persist(record: CustomWorldAgentSessionRecord) {
await this.runtimeRepository.upsertCustomWorldSession(

View File

@@ -7,7 +7,7 @@ import type {
CustomWorldSessionRecord,
CustomWorldSessionStatus,
} from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import type { CustomWorldSessionCapability } from './runtimeCapabilities.js';
export type CustomWorldSession = {
sessionId: string;
@@ -111,7 +111,7 @@ function buildClarificationQuestions(
export class CustomWorldSessionStore {
constructor(
private readonly runtimeRepository: RuntimeRepositoryPort,
private readonly runtimeRepository: CustomWorldSessionCapability,
) {}
async create(

View File

@@ -6,7 +6,6 @@ import type {
CustomWorldLibraryEntry,
CustomWorldProfileRecord,
} from '../../../packages/shared/src/contracts/runtime.js';
import type { RuntimeRepositoryPort } from '../repositories/runtimeRepository.js';
import { resolveCustomWorldCoverPresentation } from '../repositories/customWorldLibraryMetadata.js';
import { normalizeFoundationDraftProfile } from './customWorldAgentDraftCompiler.js';
import {
@@ -26,6 +25,7 @@ import {
buildDraftSummaryFromEightAnchorContent,
buildDraftTitleFromEightAnchorContent,
} from './eightAnchorCompatibilityService.js';
import type { CustomWorldWorkSummaryCapability } from './runtimeCapabilities.js';
function toText(value: unknown) {
return typeof value === 'string' ? value.trim() : '';
@@ -171,7 +171,7 @@ function isLibraryEntry(
export async function listCustomWorldWorkSummaries(
userId: string,
dependencies: {
runtimeRepository: RuntimeRepositoryPort;
runtimeRepository: CustomWorldWorkSummaryCapability;
customWorldAgentSessions: CustomWorldAgentSessionStore;
},
) {

View File

@@ -0,0 +1,53 @@
import type { CustomWorldProfileRecord, CustomWorldSessionRecord } from '../../../packages/shared/src/contracts/runtime.js';
import type {
RuntimeRepositoryPort,
SavedSnapshot,
} from '../repositories/runtimeRepository.js';
export type RuntimeSnapshotCapability = Pick<
RuntimeRepositoryPort,
'getSnapshot' | 'putSnapshot'
>;
export type CustomWorldProfileCapability = Pick<
RuntimeRepositoryPort,
'listCustomWorldProfiles'
>;
export type CustomWorldSessionCapability = {
listCustomWorldSessions(userId: string): Promise<CustomWorldSessionRecord[]>;
getCustomWorldSession(
userId: string,
sessionId: string,
): Promise<CustomWorldSessionRecord | null>;
upsertCustomWorldSession(
userId: string,
sessionId: string,
session: CustomWorldSessionRecord,
): Promise<CustomWorldSessionRecord>;
};
export type RuntimeStoryCapability = RuntimeSnapshotCapability;
export type CustomWorldWorkSummaryCapability = CustomWorldProfileCapability;
export function createRuntimeSnapshotCapability(
runtimeRepository: RuntimeRepositoryPort,
): RuntimeSnapshotCapability {
return runtimeRepository;
}
export function createCustomWorldSessionCapability(
runtimeRepository: RuntimeRepositoryPort,
): CustomWorldSessionCapability {
return runtimeRepository;
}
export function createCustomWorldProfileCapability(
runtimeRepository: RuntimeRepositoryPort,
): CustomWorldProfileCapability {
return runtimeRepository;
}
export type RuntimeStorySnapshot = SavedSnapshot;
export type RuntimeCustomWorldProfile = CustomWorldProfileRecord;