Ctrl K
ComunidadGuías…

backend-ts/src/app-weixin-mcp-services.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { Db } from './db/db.js';
import type { AppConfig } from './config/app-config.js';
import type { PathSandbox } from './harness/safety/path-sandbox.js';
import type { MysqlUserRepository } from './user/user.repository.js';
import type { MysqlAgentRepository } from './agent/agent.repository.js';
import type { SystemSettingService } from './settings/settings.service.js';
import type { AppContext } from './create-app.js';
import type { WeixinBotConfig } from './weixin/types.js';
import type { MysqlFeishuBindingRepository } from './feishu/binding.repository.js';

import { DEFAULT_WEIXIN_BOT_CONFIG } from './weixin/types.js';
import { WeixinAccountRepository } from './weixin/account.repository.js';
import { MysqlFeishuBotRepository } from './feishu/feishu_bot.repository.js';
import { ContextTokenRepository } from './weixin/context-token.repository.js';
import { WeixinSessionPeerRepository } from './weixin/session-peer.repository.js';
import { configureWeixinSessionPeerStore } from './weixin/session-peer.js';
import { WeixinSendService } from './weixin/send.service.js';
import { WeixinMediaUploadService } from './weixin/media-upload.service.js';
import { WeixinMediaService } from './weixin/media.service.js';
import { WeixinMediaToolSupport } from './weixin/media-tool-support.js';
import { createWechatToolBridges } from './weixin/wechat-tool-bridge.js';
import { McpSecretCipher } from './harness/mcp/crypto/mcp-secret-cipher.js';
import { McpServerMapper, UserMcpPreferenceMapper } from './harness/mcp/mapper/mcp-server.mapper.js';
import { UserMcpPreferenceService } from './harness/mcp/preference/service/user-mcp-preference.service.js';
import { McpServerService } from './harness/mcp/service/mcp-server.service.js';
import { McpClientManager } from './harness/mcp/mcp-client-manager.js';
import { McpToolsRegistry } from './harness/mcp/local/mcp-tools-registry.js';
import { UserMcpLoadModeService } from './harness/mcp/preference/service/user-mcp-load-mode.service.js';
import { UserMcpLoadModeMapper } from './harness/mcp/mapper/user-mcp-load-mode.mapper.js';
import { McpLoadModeResolver } from './harness/mcp/workingset/mcp-load-mode.js';
import { McpSyncService } from './harness/mcp/local/mcp-sync-service.js';

export interface WeixinMcpServicesDeps {
  db: Db;
  cfg: AppConfig;
  ctx: AppContext;
  pathSandbox: PathSandbox;
  userRepo: MysqlUserRepository;
  agentRepo: MysqlAgentRepository;
  settingService: SystemSettingService;
  earlyFeishuBinding: MysqlFeishuBindingRepository;
}

export interface WeixinMcpServicesResult {
  weixinConfig: WeixinBotConfig;
  weixinAccounts: WeixinAccountRepository;
  feishuBots: MysqlFeishuBotRepository;
  feishuBinding: MysqlFeishuBindingRepository;
  weixinTokens: ContextTokenRepository;
  weixinSend: WeixinSendService;
  weixinUpload: WeixinMediaUploadService;
  weixinMedia: WeixinMediaService;
  weixinToolSupport: WeixinMediaToolSupport;
  wechatBridges: { toolSupport: any; uploadService: any; sendService: any };
  mcpCipher: McpSecretCipher;
  mcpMapper: McpServerMapper;
  mcpPref: UserMcpPreferenceService;
  mcpServerService: McpServerService;
  mcpClient: McpClientManager;
  mcpToolsRegistry: McpToolsRegistry;
  userMcpLoadModeService: UserMcpLoadModeService;
  mcpLoadModeResolver: McpLoadModeResolver;
  mcpSync: McpSyncService;
}

export function assembleWeixinMcpServices(deps: WeixinMcpServicesDeps): WeixinMcpServicesResult {
  const { db, cfg, ctx, pathSandbox, userRepo, agentRepo, settingService, earlyFeishuBinding } = deps;

  const weixinConfig: WeixinBotConfig = {
    ...DEFAULT_WEIXIN_BOT_CONFIG,
    enabled: cfg.weixin.bot.enabled,
    voiceReply: cfg.weixin.bot.voiceReply,
    silkEncoderPath: cfg.weixin.bot.silkEncoderPath,
    ffmpegPath: cfg.weixin.bot.ffmpegPath,
    voiceMaxSeconds: cfg.weixin.bot.voiceMaxSeconds,
    ilinkBaseUrl: cfg.weixin.bot.ilinkBaseUrl,
    cdnBaseUrl: cfg.weixin.bot.cdnBaseUrl || DEFAULT_WEIXIN_BOT_CONFIG.cdnBaseUrl,
    maxInboundFileMb: cfg.weixin.bot.maxInboundFileMb,
    monitor: cfg.weixin.bot.monitor,
    mergeWindowMs: cfg.weixin.bot.mergeWindowMs,
  };
  const weixinAccounts = new WeixinAccountRepository(db);
  const feishuBots = new MysqlFeishuBotRepository(db);
  const feishuBinding = earlyFeishuBinding;
  const weixinTokens = new ContextTokenRepository(db);
  const weixinPeerRepo = new WeixinSessionPeerRepository(db);
  configureWeixinSessionPeerStore({
    save: (sessionId, wxUserId) => weixinPeerRepo.save(sessionId, wxUserId),
    load: (sessionId) => weixinPeerRepo.findBySessionId(sessionId),
  });
  const weixinSend = new WeixinSendService(weixinAccounts, weixinTokens);
  const weixinUpload = new WeixinMediaUploadService(weixinConfig);
  const weixinMedia = new WeixinMediaService(weixinConfig);
  const weixinToolSupport = new WeixinMediaToolSupport(weixinAccounts, weixinTokens, pathSandbox);
  const wechatBridges = createWechatToolBridges(
    weixinToolSupport, weixinUpload, weixinSend, weixinAccounts, weixinTokens,
  );

  const mcpCipher = new McpSecretCipher(cfg.app.mcp.secretKey);
  const mcpMapper = new McpServerMapper(db);
  const mcpPref = new UserMcpPreferenceService(new UserMcpPreferenceMapper(db));
  const mcpServerService = new McpServerService(mcpMapper, mcpCipher, mcpPref, userRepo, {
    selectById: (id) => agentRepo.findById(id),
    listAll: () => agentRepo.selectList(null, true),
    selectList: () => agentRepo.selectList(null, true),
  });
  const mcpClient = new McpClientManager(cfg.app.mcp.clientTimeoutSeconds);
  const mcpToolsRegistry = new McpToolsRegistry();
  const userMcpLoadModeService = new UserMcpLoadModeService(new UserMcpLoadModeMapper(db));
  const mcpLoadModeResolver = new McpLoadModeResolver({
    userLoadMode: userMcpLoadModeService,
    systemSettingService: settingService,
  });
  const mcpSync = new McpSyncService(mcpMapper, mcpServerService, mcpToolsRegistry, mcpPref);
  ctx.mcpSyncRef = mcpSync;

  return {
    weixinConfig, weixinAccounts, feishuBots, feishuBinding, weixinTokens,
    weixinSend, weixinUpload, weixinMedia, weixinToolSupport, wechatBridges,
    mcpCipher, mcpMapper, mcpPref, mcpServerService, mcpClient, mcpToolsRegistry,
    userMcpLoadModeService, mcpLoadModeResolver, mcpSync,
  };
}