import { forwardRef, Module } from '@nestjs/common'; import { CommandsModule } from '../commands/commands.module.js'; import { HarnessModule } from '../harness/harness.module.js'; import { HarnessRegistry } from '../harness/harness.registry.js'; import { HARNESS_CONVERSATION_SERVICE, HARNESS_REGISTRY, type HarnessConversationServiceBinding, } from '../harness/harness.tokens.js'; import type { HarnessConversationService } from '@mosaicstack/types'; import { ChatGateway } from './chat.gateway.js'; import { ChatController } from './chat.controller.js'; import { ChatRuntimeRouter } from './chat-runtime-router.js'; import { EmbeddedChatRuntime } from './embedded-chat.runtime.js'; import { HarnessChatRuntime } from './harness-chat.runtime.js'; /** * Task Five wiring. The exclusive {@link ChatRuntimeRouter} is the single chat-execution * authority: the controller and gateway inject only the router, never `AgentService`, * `RoutingEngineService`, or a session/`piSession` handle. The router resolves exactly one * runtime at module init — {@link EmbeddedChatRuntime} in legacy mode, {@link HarnessChatRuntime} * in `pi-rpc` — over the REAL {@link HarnessModule} registry and conversation-service binding. * * The router and the harness runtime are constructed through factories because their * dependencies are interface/union types with no runtime injection token (the registry and * conversation-service arrive via the string tokens exported by `HarnessModule`); the embedded * runtime injects the class-typed `AgentService` and is provided directly. */ @Module({ imports: [forwardRef(() => CommandsModule), HarnessModule], controllers: [ChatController], providers: [ ChatGateway, EmbeddedChatRuntime, { provide: HarnessChatRuntime, useFactory: (conversationService: HarnessConversationServiceBinding) => new HarnessChatRuntime(conversationService as HarnessConversationService), inject: [HARNESS_CONVERSATION_SERVICE], }, { provide: ChatRuntimeRouter, useFactory: ( registry: HarnessRegistry, conversationService: HarnessConversationServiceBinding, embedded: EmbeddedChatRuntime, harness: HarnessChatRuntime, ) => new ChatRuntimeRouter(registry, conversationService, embedded, harness), inject: [ HARNESS_REGISTRY, HARNESS_CONVERSATION_SERVICE, EmbeddedChatRuntime, HarnessChatRuntime, ], }, ], exports: [ChatGateway, ChatRuntimeRouter], }) export class ChatModule {}