抽离custom world运行时provider工厂
This commit is contained in:
@@ -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` 注入语义
|
||||
|
||||
本轮不做:
|
||||
|
||||
|
||||
@@ -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 >=
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
});
|
||||
}),
|
||||
|
||||
@@ -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(),
|
||||
|
||||
46
server-node/src/services/customWorldRuntimeProvider.ts
Normal file
46
server-node/src/services/customWorldRuntimeProvider.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user