抽离custom world运行时provider工厂

This commit is contained in:
2026-04-20 12:50:18 +00:00
parent 164ead0681
commit 3f92380ec9
6 changed files with 79 additions and 25 deletions

View File

@@ -90,6 +90,8 @@
1.`story/custom world` 的 service 依赖从大仓储接口改成最小 capability
2.`AppContext -> route -> service` 的注入链路同步改成 capability wiring
3.`custom world` 增加统一 provider 工厂,收口 session / agent / works 的构造入口
4. provider 工厂只负责收口构造,不允许改变既有 `LLM / single turn / session store` 注入语义
本轮不做:

View File

@@ -12,7 +12,7 @@ import type { AppConfig } from './config.ts';
import { prepareEventStreamResponse } from './http.ts';
import { requestIdMiddleware } from './middleware/requestId.ts';
import { createAppContext } from './server.ts';
import { CustomWorldAgentOrchestrator } from './services/customWorldAgentOrchestrator.js';
import { createCustomWorldRuntimeProvider } from './services/customWorldRuntimeProvider.js';
import { createTestCustomWorldAgentSingleTurnLlmClient } from './services/customWorldAgentTestHelpers.js';
import { httpRequest, type TestRequestInit } from './testHttp.ts';
@@ -32,13 +32,18 @@ type TestConfigOverrides = Partial<
type TestAppContext = Awaited<ReturnType<typeof createAppContext>>;
function installTestCustomWorldAgentSingleTurnLlm(context: TestAppContext) {
context.customWorldAgentOrchestrator = new CustomWorldAgentOrchestrator(
context.customWorldAgentSessions,
null,
{
singleTurnLlmClient: createTestCustomWorldAgentSingleTurnLlmClient(),
},
);
const testLlmClient = createTestCustomWorldAgentSingleTurnLlmClient();
context.customWorldRuntime = createCustomWorldRuntimeProvider({
customWorldSessionCapability: context.customWorldSessionCapability,
customWorldProfileCapability: context.customWorldProfileCapability,
llmClient: context.llmClient,
runtimeLlmClient: testLlmClient,
singleTurnLlmClient: testLlmClient,
});
context.customWorldAgentSessions = context.customWorldRuntime.customWorldAgentSessions;
context.customWorldSessions = context.customWorldRuntime.customWorldSessions;
context.customWorldAgentOrchestrator =
context.customWorldRuntime.customWorldAgentOrchestrator;
}
function createTestConfig(
@@ -3215,7 +3220,10 @@ test('custom world agent generate_landmarks action appends landmark cards over h
};
assert.equal(sessionResponse.status, 200);
assert.ok((sessionPayload.draftProfile?.landmarks?.length ?? 0) >= 6);
assert.ok(
(sessionPayload.draftProfile?.landmarks?.length ?? 0) >=
baselineLandmarkCount + 2,
);
assert.ok(
sessionPayload.draftCards.filter((card) => card.kind === 'landmark')
.length >=

View File

@@ -10,6 +10,7 @@ import { SmsAuthEventRepository } from './repositories/smsAuthEventRepository.js
import { UserRepository } from './repositories/userRepository.js';
import { UserSessionRepository } from './repositories/userSessionRepository.js';
import { CaptchaChallengeStore } from './services/captchaChallengeStore.js';
import type { CustomWorldRuntimeProvider } from './services/customWorldRuntimeProvider.js';
import { CustomWorldAgentOrchestrator } from './services/customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './services/customWorldAgentSessionStore.js';
import { CustomWorldSessionStore } from './services/customWorldSessionStore.js';
@@ -37,6 +38,7 @@ export type AppContext = {
runtimeStoryCapability: RuntimeStoryCapability;
customWorldSessionCapability: CustomWorldSessionCapability;
customWorldProfileCapability: CustomWorldProfileCapability;
customWorldRuntime: CustomWorldRuntimeProvider;
llmClient: UpstreamLlmClient;
customWorldSessions: CustomWorldSessionStore;
customWorldAgentSessions: CustomWorldAgentSessionStore;

View File

@@ -555,8 +555,7 @@ export function createRuntimeRoutes(context: AppContext) {
asyncHandler(async (request, response) => {
sendApiResponse<ListCustomWorldWorksResponse>(response, {
items: await listCustomWorldWorkSummaries(request.userId!, {
runtimeRepository: context.customWorldProfileCapability,
customWorldAgentSessions: context.customWorldAgentSessions,
...context.customWorldRuntime.customWorldWorkSummaryDependencies,
}),
});
}),

View File

@@ -13,9 +13,7 @@ import { SmsAuthEventRepository } from './repositories/smsAuthEventRepository.js
import { UserRepository } from './repositories/userRepository.js';
import { UserSessionRepository } from './repositories/userSessionRepository.js';
import { CaptchaChallengeStore } from './services/captchaChallengeStore.js';
import { CustomWorldAgentOrchestrator } from './services/customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './services/customWorldAgentSessionStore.js';
import { CustomWorldSessionStore } from './services/customWorldSessionStore.js';
import { createCustomWorldRuntimeProvider } from './services/customWorldRuntimeProvider.js';
import { UpstreamLlmClient } from './services/llmClient.js';
import {
createCustomWorldProfileCapability,
@@ -94,9 +92,12 @@ export async function createAppContext(config: AppConfig = loadConfig()) {
const customWorldProfileCapability = createCustomWorldProfileCapability(
runtimeRepository,
);
const customWorldAgentSessions = new CustomWorldAgentSessionStore(
const llmClient = new UpstreamLlmClient(config, logger);
const customWorldRuntime = createCustomWorldRuntimeProvider({
customWorldSessionCapability,
);
customWorldProfileCapability,
llmClient,
});
const context: AppContext = {
config,
logger,
@@ -111,15 +112,11 @@ export async function createAppContext(config: AppConfig = loadConfig()) {
runtimeStoryCapability,
customWorldSessionCapability,
customWorldProfileCapability,
llmClient: new UpstreamLlmClient(config, logger),
customWorldSessions: new CustomWorldSessionStore(customWorldSessionCapability),
customWorldAgentSessions,
customWorldAgentOrchestrator: new CustomWorldAgentOrchestrator(
customWorldAgentSessions,
config.llm.apiKey.trim()
? new UpstreamLlmClient(config, logger)
: null,
),
customWorldRuntime,
llmClient,
customWorldSessions: customWorldRuntime.customWorldSessions,
customWorldAgentSessions: customWorldRuntime.customWorldAgentSessions,
customWorldAgentOrchestrator: customWorldRuntime.customWorldAgentOrchestrator,
smsVerificationService: createSmsVerificationService(config, logger),
wechatAuthService: createWechatAuthService(config, logger),
wechatAuthStates: new WechatAuthStateStore(),

View File

@@ -0,0 +1,46 @@
import type { CustomWorldProfileCapability, CustomWorldSessionCapability } from './runtimeCapabilities.js';
import { CustomWorldAgentOrchestrator } from './customWorldAgentOrchestrator.js';
import { CustomWorldAgentSessionStore } from './customWorldAgentSessionStore.js';
import { CustomWorldSessionStore } from './customWorldSessionStore.js';
import type { UpstreamLlmClient } from './llmClient.js';
export type CustomWorldRuntimeProvider = {
customWorldSessions: CustomWorldSessionStore;
customWorldAgentSessions: CustomWorldAgentSessionStore;
customWorldAgentOrchestrator: CustomWorldAgentOrchestrator;
customWorldWorkSummaryDependencies: {
runtimeRepository: CustomWorldProfileCapability;
customWorldAgentSessions: CustomWorldAgentSessionStore;
};
};
export function createCustomWorldRuntimeProvider(params: {
customWorldSessionCapability: CustomWorldSessionCapability;
customWorldProfileCapability: CustomWorldProfileCapability;
llmClient: UpstreamLlmClient | null;
runtimeLlmClient?: UpstreamLlmClient | null;
singleTurnLlmClient?: UpstreamLlmClient | null;
}) {
const customWorldSessions = new CustomWorldSessionStore(
params.customWorldSessionCapability,
);
const customWorldAgentSessions = new CustomWorldAgentSessionStore(
params.customWorldSessionCapability,
);
return {
customWorldSessions,
customWorldAgentSessions,
customWorldAgentOrchestrator: new CustomWorldAgentOrchestrator(
customWorldAgentSessions,
params.runtimeLlmClient ?? params.llmClient,
{
singleTurnLlmClient: params.singleTurnLlmClient,
},
),
customWorldWorkSummaryDependencies: {
runtimeRepository: params.customWorldProfileCapability,
customWorldAgentSessions,
},
} satisfies CustomWorldRuntimeProvider;
}