{"repo": "adamllll/codeflow", "files": {"codeflow-web/src/main/resources-env/prod/application-ai.yml": {"67063e765ccacfcbf787b52ed206be1e0fd86064": {"t": 1785745244.4802022, "n": 2022, "h": "f480a35507e7a50e", "c": "net:\n proxy:\n # 代理相关信息\n - ip: 127.0.0.1\n port: 1080\n type: SOCKS\n\nai:\n maxNum:\n basic: 5 # 默认兜底策略\n wechat: 10 # 公众号用户\n star: 30 # 星球用户\n starTry: 10 # 星球用户\n invited: 0.1 # 被邀请\n inviteNum: 0.2 # 邀请人数执行策略\n starNumber: 4000 # 最大的星球编号\n historyContextCnt: 10 # 多轮对话上下文的条数,默认最多给10条\n source: # 支持的AI模型\n - CHAT_GPT_3_5\n - CHAT_GPT_4\n - PAI_AI\n - XUN_FEI_AI\n - ZHI_PU_AI\n - ALI_AI\n\n# chatgpt\nchatgpt:\n main: CHAT_GPT_3_5\n conf:\n CHAT_GPT_3_5:\n keys:\n - # 这里输入你的key\n proxy: true # 表示走上面的代理进行访问\n apiHost: https://api.openai.com/\n timeOut: 900\n maxToken: 3000\n CHAT_GPT_4:\n keys:\n -\n proxy: true\n apiHost: https://api.openai.com/\n timeOut: 900\n maxToken: 200000\n number:\n # 普通用户\n normal: 50\n vip: 100\n\n\n# 智谱 AI\nzhipu:\n apiSecretKey: ${PAICODING_ZHIPU_API_SECRET_KEY:}\n requestIdTemplate: \"paicoding-%d\"\n # 调整模型 glm-4-alltools\n model: ${PAICODING_ZHIPU_MODEL:glm-4-air-0111}\n coding:\n apiHost: ${PAICODING_ZHIPU_CODING_API_HOST:https://open.bigmodel.cn/api/coding/paas/v4}\n model: ${PAICODING_ZHIPU_CODING_MODEL:GLM-5}\n timeout: ${PAICODING_ZHIPU_CODING_TIMEOUT:120}\n maxTokens: ${PAICODING_ZHIPU_CODING_MAX_TOKENS:512}\n temperature: ${PAICODING_ZHIPU_CODING_TEMPERATURE:0.3}\n thinkingType: ${PAICODING_ZHIPU_CODING_THINKING_TYPE:disabled}\n\n# 讯飞AI\nxunfei:\n hostUrl: http://spark-api.xf-yun.com/v1/x1\n domain: \"x1\"\n appId: ${PAICODING_XUNFEI_APP_ID:}\n apiKey: ${PAICODING_XUNFEI_API_KEY:}\n apiSecret: ${PAICODING_XUNFEI_API_SECRET:}\n APIPassword: ${PAICODING_XUNFEI_API_PASSWORD:}\n\ndeepseek:\n apiHost: https://api.deepseek.com\n apiKey: ${PAICODING_DEEPSEEK_API_KEY:} # 使用自己的密钥进行替换\n model: ${PAICODING_DEEPSEEK_MODEL:deepseek-chat}\n timeout: 900 # 超时时间,单位秒\n\ndoubao:\n api-key: ${PAICODING_DOUBAO_API_KEY:} # 使用自己的密钥进行替换\n api-host: ${PAICODING_DOUBAO_API_HOST:https://ark.cn-beijing.volces.com/api/v3}\n end-point: ${PAICODING_DOUBAO_ENDPOINT:} # 使用自己创建的接入点进行替换\n"}}, "codeflow-web/src/main/resources-env/test/application-ai.yml": {"67063e765ccacfcbf787b52ed206be1e0fd86064": {"t": 1785746337.994185, "n": 820, "h": "3b2dd39b291420c3", "c": "net:\n proxy:\n # 代理相关信息\n - ip: 127.0.0.1\n port: 1080\n type: SOCKS\n\n\n\n# chatgpt\nchatgpt:\n main: CHAT_GPT_3_5\n conf:\n CHAT_GPT_3_5:\n keys:\n - # 这里输入你的key\n proxy: true # 表示走上面的代理进行访问\n apiHost: https://api.openai.com/\n timeOut: 900\n maxToken: 3000\n CHAT_GPT_4:\n keys:\n -\n proxy: true\n apiHost: https://api.openai.com/\n timeOut: 900\n maxToken: 200000\n number:\n # 普通用户\n normal: 50\n vip: 100\n\n\n\n# 讯飞AI\nxunfei:\n hostUrl: http://spark-api.xf-yun.com/v1.1/chat\n appId:\n apiKey:\n apiSecret:\n\n\ndeepseek:\n apiHost: https://api.deepseek.com\n apiKey: # 使用自己的密钥进行替换\n model: deepseek-chat\n timeout: 900 # 超时时间,单位秒\n\ndoubao:\n api-key: # 使用自己的密钥进行替换\n api-host: https://ark.cn-beijing.volces.com/api/v3\n end-point: # 使用自己创建的接入点进行替换\n"}}, "codeflow-service/src/main/java/com/github/paicoding/forum/service/chatai/config/impl/AiConfigAdminServiceImpl.java": {"67063e765ccacfcbf787b52ed206be1e0fd86064": {"t": 1786068304.520266, "n": 21813, "h": "7a11d45b1e7a511c", "c": "package com.github.paicoding.forum.service.chatai.config.impl;\n\nimport com.github.paicoding.forum.api.model.enums.ai.AISourceEnum;\nimport com.github.paicoding.forum.api.model.exception.ExceptionUtil;\nimport com.github.paicoding.forum.api.model.vo.ai.config.AiConfigAdminReq;\nimport com.github.paicoding.forum.api.model.vo.ai.config.AiConfigTestReq;\nimport com.github.paicoding.forum.api.model.vo.ai.config.dto.AiConfigAdminDTO;\nimport com.github.paicoding.forum.api.model.vo.ai.config.dto.AiConfigTestDTO;\nimport com.github.paicoding.forum.api.model.vo.chat.ChatItemVo;\nimport com.github.paicoding.forum.api.model.vo.constants.StatusEnum;\nimport com.github.paicoding.forum.core.autoconf.DynamicConfigContainer;\nimport com.github.paicoding.forum.service.chatai.ChatFacade;\nimport com.github.paicoding.forum.service.chatai.config.AiConfigAdminService;\nimport com.github.paicoding.forum.service.chatai.service.impl.ali.AliIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.chatgpt.ChatGptIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.deepseek.DeepSeekIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.doubao.DoubaoConfig;\nimport com.github.paicoding.forum.service.chatai.service.impl.doubao.DoubaoIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.pai.PaiAiDemoServiceImpl;\nimport com.github.paicoding.forum.service.chatai.service.impl.xunfei.XunFeiIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.zhipu.ZhipuCodingIntegration;\nimport com.github.paicoding.forum.service.chatai.service.impl.zhipu.ZhipuIntegration;\nimport com.github.paicoding.forum.service.config.repository.dao.ConfigDao;\nimport com.github.paicoding.forum.service.config.repository.entity.GlobalConfigDO;\nimport com.github.paicoding.forum.service.user.service.conf.AiConfig;\nimport org.apache.commons.lang3.StringUtils;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.CollectionUtils;\n\nimport javax.annotation.Resource;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * AI 配置管理服务\n *\n * @author Codex\n * @date 2026/3/23\n */\n@Service\npublic class AiConfigAdminServiceImpl implements AiConfigAdminService {\n private static final String COMMENT_PREFIX = \"AI 配置 - \";\n private static final String DEFAULT_TEST_PROMPT = \"请只回复“连接成功”四个字\";\n\n private static final String KEY_AI_SOURCE = \"ai.source\";\n\n private static final String KEY_CHATGPT_MAIN = \"chatgpt.main\";\n private static final String KEY_CHATGPT_35_KEYS = \"chatgpt.conf.CHAT_GPT_3_5.keys\";\n private static final String KEY_CHATGPT_35_PROXY = \"chatgpt.conf.CHAT_GPT_3_5.proxy\";\n private static final String KEY_CHATGPT_35_API_HOST = \"chatgpt.conf.CHAT_GPT_3_5.apiHost\";\n private static final String KEY_CHATGPT_35_TIMEOUT = \"chatgpt.conf.CHAT_GPT_3_5.timeOut\";\n private static final String KEY_CHATGPT_35_MAX_TOKEN = \"chatgpt.conf.CHAT_GPT_3_5.maxToken\";\n private static final String KEY_CHATGPT_4_KEYS = \"chatgpt.conf.CHAT_GPT_4.keys\";\n private static final String KEY_CHATGPT_4_PROXY = \"chatgpt.conf.CHAT_GPT_4.proxy\";\n private static final String KEY_CHATGPT_4_API_HOST = \"chatgpt.conf.CHAT_GPT_4.apiHost\";\n private static final String KEY_CHATGPT_4_TIMEOUT = \"chatgpt.conf.CHAT_GPT_4.timeOut\";\n private static final String KEY_CHATGPT_4_MAX_TOKEN = \"chatgpt.conf.CHAT_GPT_4.maxToken\";\n\n private static final String KEY_ZHIPU_API_SECRET = \"zhipu.apiSecretKey\";\n private static final String KEY_ZHIPU_REQUEST_ID_TEMPLATE = \"zhipu.requestIdTemplate\";\n private static final String KEY_ZHIPU_MODEL = \"zhipu.model\";\n private static final String KEY_ZHIPU_CODING_API_KEY = \"zhipu.coding.apiKey\";\n private static final String KEY_ZHIPU_CODING_API_HOST = \"zhipu.coding.apiHost\";\n private static final String KEY_ZHIPU_CODING_MODEL = \"zhipu.coding.model\";\n private static final String KEY_ZHIPU_CODING_TIMEOUT = \"zhipu.coding.timeout\";\n\n private static final String KEY_XUNFEI_HOST_URL = \"xunfei.hostUrl\";\n private static final String KEY_XUNFEI_DOMAIN = \"xunfei.domain\";\n private static final String KEY_XUNFEI_APP_ID = \"xunfei.appId\";\n private static final String KEY_XUNFEI_API_KEY = \"xunfei.apiKey\";\n private static final String KEY_XUNFEI_API_SECRET = \"xunfei.apiSecret\";\n private static final String KEY_XUNFEI_API_PASSWORD = \"xunfei.APIPassword\";\n\n private static final String KEY_DEEPSEEK_API_KEY = \"deepseek.apiKey\";\n private static final String KEY_DEEPSEEK_API_HOST = \"deepseek.apiHost\";\n private static final String KEY_DEEPSEEK_MODEL = \"deepseek.model\";\n private static final String KEY_DEEPSEEK_TIMEOUT = \"deepseek.timeout\";\n\n private static final String KEY_DOUBAO_API_KEY = \"doubao.api-key\";\n private static final String KEY_DOUBAO_API_HOST = \"doubao.api-host\";\n private static final String KEY_DOUBAO_END_POINT = \"doubao.end-point\";\n\n private static final String KEY_ALI_MODEL = \"ali.model\";\n\n @Resource\n private ConfigDao configDao;\n\n @Resource\n private DynamicConfigContainer dynamicConfigContainer;\n\n @Resource\n private ChatFacade chatFacade;\n\n @Resource\n private AiConfig aiConfig;\n\n @Resource\n private ChatGptIntegration.ChatGptConfig chatGptConfig;\n\n @Resource\n private ZhipuIntegration.ZhipuConfig zhipuConfig;\n @Resource\n private ZhipuCodingIntegration.ZhipuCodingConfig zhipuCodingConfig;\n\n @Resource\n private XunFeiIntegration.XunFeiConfig xunFeiConfig;\n\n @Resource\n private DeepSeekIntegration.DeepSeekConf deepSeekConfig;\n\n @Resource\n private DoubaoConfig doubaoConfig;\n\n @Resource\n private AliIntegration.AliConfig aliConfig;\n @Resource\n private ChatGptIntegration chatGptIntegration;\n @Resource\n private ZhipuIntegration zhipuIntegration;\n @Resource\n private ZhipuCodingIntegration zhipuCodingIntegration;\n @Resource\n private XunFeiIntegration xunFeiIntegration;\n @Resource\n private DeepSeekIntegration deepSeekIntegration;\n @Resource\n private DoubaoIntegration doubaoIntegration;\n @Resource\n private AliIntegration aliIntegration;\n @Resource\n private PaiAiDemoServiceImpl paiAiDemoService;\n\n @Override\n public AiConfigAdminDTO getConfig() {\n AiConfigAdminDTO dto = new AiConfigAdminDTO();\n dto.setSources(aiConfig.getSource() == null ? Collections.emptyList() : new ArrayList<>(aiConfig.getSource()));\n dto.setChatGpt(buildChatGptDto());\n dto.setZhipu(buildZhipuDto());\n dto.setZhipuCoding(buildZhipuCodingDto());\n dto.setXunFei(buildXunFeiDto());\n dto.setDeepSeek(buildDeepSeekDto());\n dto.setDoubao(buildDoubaoDto());\n dto.setAli(buildAliDto());\n return dto;\n }\n\n @Override\n public void save(AiConfigAdminReq req) {\n if (req == null) {\n throw ExceptionUtil.of(StatusEnum.ILLEGAL_ARGUMENTS_MIXED, \"AI 配置不能为空\");\n }\n\n saveAiSource(req.getSources());\n saveChatGpt(req.getChatGpt());\n saveZhipu(req.getZhipu());\n saveZhipuCoding(req.getZhipuCoding());\n saveXunFei(req.getXunFei());\n saveDeepSeek(req.getDeepSeek());\n saveDoubao(req.getDoubao());\n saveAli(req.getAli());\n\n dynamicConfigContainer.forceRefresh();\n chatFacade.refreshAiSourceCache(Collections.emptySet());\n }\n\n @Override\n public AiConfigTestDTO test(AiConfigTestReq req) {\n if (req == null || req.getSource() == null) {\n throw ExceptionUtil.of(StatusEnum.ILLEGAL_ARGUMENTS_MIXED, \"测试模型不能为空\");\n }\n\n long start = System.currentTimeMillis();\n String prompt = StringUtils.defaultIfBlank(req.getPrompt(), DEFAULT_TEST_PROMPT);\n AISourceEnum source = req.getSource();\n try {\n String answer = doTest(source, prompt);\n return buildTestResult(source, true, \"连通性测试成功\", answer, start);\n } catch (Exception e) {\n return buildTestResult(source, false, StringUtils.defaultIfBlank(e.getMessage(), \"连通性测试失败\"), null, start);\n }\n }\n\n private void saveAiSource(List sources) {\n if (sources == null) {\n return;\n }\n upsertConfig(KEY_AI_SOURCE, joinEnumList(sources), \"启用的 AI 模型源\");\n }\n\n private void saveChatGpt(AiConfigAdminReq.ChatGptConfig chatGpt) {\n if (chatGpt == null) {\n return;\n }\n\n if (chatGpt.getMain() != null) {\n upsertConfig(KEY_CHATGPT_MAIN, chatGpt.getMain().name(), \"ChatGPT 默认模型\");\n }\n saveGptModel(\"3.5\", chatGpt.getGpt35(), KEY_CHATGPT_35_KEYS, KEY_CHATGPT_35_PROXY,\n KEY_CHATGPT_35_API_HOST, KEY_CHATGPT_35_TIMEOUT, KEY_CHATGPT_35_MAX_TOKEN);\n saveGptModel(\"4\", chatGpt.getGpt4(), KEY_CHATGPT_4_KEYS, KEY_CHATGPT_4_PROXY,\n KEY_CHATGPT_4_API_HOST, KEY_CHATGPT_4_TIMEOUT, KEY_CHATGPT_4_MAX_TOKEN);\n }\n\n private void saveGptModel(String modelName, AiConfigAdminReq.GptModelConfig config, String keysKey,\n String proxyKey, String apiHostKey, String timeoutKey, String maxTokenKey) {\n if (config == null) {\n return;\n }\n\n if (config.getKeys() != null) {\n upsertConfig(keysKey, joinStringList(config.getKeys()), \"ChatGPT \" + modelName + \" API Keys\");\n }\n if (config.getProxy() != null) {\n upsertConfig(proxyKey, String.valueOf(config.getProxy()), \"ChatGPT \" + modelName + \" 是否启用代理\");\n }\n if (config.getApiHost() != null) {\n upsertConfig(apiHostKey, config.getApiHost(), \"ChatGPT \" + modelName + \" API Host\");\n }\n if (config.getTimeOut() != null) {\n upsertConfig(timeoutKey, String.valueOf(config.getTimeOut()), \"ChatGPT \" + modelName + \" 超时时间\");\n }\n if (config.getMaxToken() != null) {\n upsertConfig(maxTokenKey, String.valueOf(config.getMaxToken()), \"ChatGPT \" + modelName + \" 最大 Token\");\n }\n }\n\n private void saveZhipu(AiConfigAdminReq.ZhipuConfig zhipu) {\n if (zhipu == null) {\n return;\n }\n\n if (zhipu.getApiSecretKey() != null) {\n upsertConfig(KEY_ZHIPU_API_SECRET, zhipu.getApiSecretKey(), \"智谱 API Secret\");\n }\n if (zhipu.getRequestIdTemplate() != null) {\n upsertConfig(KEY_ZHIPU_REQUEST_ID_TEMPLATE, zhipu.getRequestIdTemplate(), \"智谱请求 ID 模板\");\n }\n if (zhipu.getModel() != null) {\n upsertConfig(KEY_ZHIPU_MODEL, zhipu.getModel(), \"智谱模型\");\n }\n }\n\n private void saveZhipuCoding(AiConfigAdminReq.ZhipuCodingConfig zhipuCoding) {\n if (zhipuCoding == null) {\n return;\n }\n\n if (zhipuCoding.getApiKey() != null) {\n upsertConfig(KEY_ZHIPU_CODING_API_KEY, zhipuCoding.getApiKey(), \"智谱 Coding API Key\");\n }\n if (zhipuCoding.getApiHost() != null) {\n upsertConfig(KEY_ZHIPU_CODING_API_HOST, zhipuCoding.getApiHost(), \"智谱 Coding API Host\");\n }\n if (zhipuCoding.getModel() != null) {\n upsertConfig(KEY_ZHIPU_CODING_MODEL, zhipuCoding.getModel(), \"智谱 Coding 模型\");\n }\n if (zhipuCoding.getTimeout() != null) {\n upsertConfig(KEY_ZHIPU_CODING_TIMEOUT, String.valueOf(zhipuCoding.getTimeout()), \"智谱 Coding 超时时间\");\n }\n }\n\n private void saveXunFei(AiConfigAdminReq.XunFeiConfig xunFei) {\n if (xunFei == null) {\n return;\n }\n\n if (xunFei.getHostUrl() != null) {\n upsertConfig(KEY_XUNFEI_HOST_URL, xunFei.getHostUrl(), \"讯飞 Host URL\");\n }\n if (xunFei.getDomain() != null) {\n upsertConfig(KEY_XUNFEI_DOMAIN, xunFei.getDomain(), \"讯飞领域\");\n }\n if (xunFei.getAppId() != null) {\n upsertConfig(KEY_XUNFEI_APP_ID, xunFei.getAppId(), \"讯飞 AppId\");\n }\n if (xunFei.getApiKey() != null) {\n upsertConfig(KEY_XUNFEI_API_KEY, xunFei.getApiKey(), \"讯飞 API Key\");\n }\n if (xunFei.getApiSecret() != null) {\n upsertConfig(KEY_XUNFEI_API_SECRET, xunFei.getApiSecret(), \"讯飞 API Secret\");\n }\n if (xunFei.getApiPassword() != null) {\n upsertConfig(KEY_XUNFEI_API_PASSWORD, xunFei.getApiPassword(), \"讯飞 API Password\");\n }\n }\n\n private void saveDeepSeek(AiConfigAdminReq.DeepSeekConfig deepSeek) {\n if (deepSeek == null) {\n return;\n }\n\n if (deepSeek.getApiKey() != null) {\n upsertConfig(KEY_DEEPSEEK_API_KEY, deepSeek.getApiKey(), \"DeepSeek API Key\");\n }\n if (deepSeek.getApiHost() != null) {\n upsertConfig(KEY_DEEPSEEK_API_HOST, deepSeek.getApiHost(), \"DeepSeek API Host\");\n }\n if (deepSeek.getModel() != null) {\n upsertConfig(KEY_DEEPSEEK_MODEL, deepSeek.getModel(), \"DeepSeek 模型\");\n }\n if (deepSeek.getTimeout() != null) {\n upsertConfig(KEY_DEEPSEEK_TIMEOUT, String.valueOf(deepSeek.getTimeout()), \"DeepSeek 超时时间\");\n }\n }\n\n private void saveDoubao(AiConfigAdminReq.DoubaoConfig doubao) {\n if (doubao == null) {\n return;\n }\n\n if (doubao.getApiKey() != null) {\n upsertConfig(KEY_DOUBAO_API_KEY, doubao.getApiKey(), \"豆包 API Key\");\n }\n if (doubao.getApiHost() != null) {\n upsertConfig(KEY_DOUBAO_API_HOST, doubao.getApiHost(), \"豆包 API Host\");\n }\n if (doubao.getEndPoint() != null) {\n upsertConfig(KEY_DOUBAO_END_POINT, doubao.getEndPoint(), \"豆包 EndPoint\");\n }\n }\n\n private void saveAli(AiConfigAdminReq.AliConfig ali) {\n if (ali == null) {\n return;\n }\n\n if (ali.getModel() != null) {\n upsertConfig(KEY_ALI_MODEL, ali.getModel(), \"阿里模型\");\n }\n }\n\n private void upsertConfig(String key, String value, String comment) {\n GlobalConfigDO config = configDao.getGlobalConfigByKey(key);\n if (config == null) {\n GlobalConfigDO globalConfigDO = new GlobalConfigDO();\n globalConfigDO.setKey(key);\n globalConfigDO.setValue(StringUtils.defaultString(value));\n globalConfigDO.setComment(COMMENT_PREFIX + comment);\n configDao.save(globalConfigDO);\n return;\n }\n\n config.setValue(StringUtils.defaultString(value));\n config.setComment(COMMENT_PREFIX + comment);\n configDao.updateById(config);\n }\n\n private AiConfigAdminDTO.ChatGptConfig buildChatGptDto() {\n AiConfigAdminDTO.ChatGptConfig dto = new AiConfigAdminDTO.ChatGptConfig();\n dto.setMain(chatGptConfig.getMain());\n dto.setGpt35(buildGptModelDto(chatGptConfig.getConf() == null ? null : chatGptConfig.getConf().get(AISourceEnum.CHAT_GPT_3_5)));\n dto.setGpt4(buildGptModelDto(chatGptConfig.getConf() == null ? null : chatGptConfig.getConf().get(AISourceEnum.CHAT_GPT_4)));\n return dto;\n }\n\n private AiConfigAdminDTO.GptModelConfig buildGptModelDto(ChatGptIntegration.GptConf conf) {\n AiConfigAdminDTO.GptModelConfig dto = new AiConfigAdminDTO.GptModelConfig();\n if (conf == null) {\n dto.setKeys(Collections.emptyList());\n return dto;\n }\n dto.setKeys(conf.getKeys() == null ? Collections.emptyList() : new ArrayList(conf.getKeys()));\n dto.setProxy(conf.isProxy());\n dto.setApiHost(conf.getApiHost());\n dto.setTimeOut(conf.getTimeOut());\n dto.setMaxToken(conf.getMaxToken());\n return dto;\n }\n\n private AiConfigAdminDTO.ZhipuConfig buildZhipuDto() {\n AiConfigAdminDTO.ZhipuConfig dto = new AiConfigAdminDTO.ZhipuConfig();\n dto.setApiSecretKey(zhipuConfig.getApiSecretKey());\n dto.setRequestIdTemplate(zhipuConfig.getRequestIdTemplate());\n dto.setModel(zhipuConfig.getModel());\n return dto;\n }\n\n private AiConfigAdminDTO.ZhipuCodingConfig buildZhipuCodingDto() {\n AiConfigAdminDTO.ZhipuCodingConfig dto = new AiConfigAdminDTO.ZhipuCodingConfig();\n dto.setApiKey(zhipuCodingConfig.getApiKey());\n dto.setApiHost(zhipuCodingConfig.getApiHost());\n dto.setModel(zhipuCodingConfig.getModel());\n dto.setTimeout(zhipuCodingConfig.getTimeout());\n return dto;\n }\n\n private AiConfigAdminDTO.XunFeiConfig buildXunFeiDto() {\n AiConfigAdminDTO.XunFeiConfig dto = new AiConfigAdminDTO.XunFeiConfig();\n dto.setHostUrl(xunFeiConfig.getHostUrl());\n dto.setDomain(xunFeiConfig.getDomain());\n dto.setAppId(xunFeiConfig.getAppId());\n dto.setApiKey(xunFeiConfig.getApiKey());\n dto.setApiSecret(xunFeiConfig.getApiSecret());\n dto.setApiPassword(xunFeiConfig.getAPIPassword());\n return dto;\n }\n\n private AiConfigAdminDTO.DeepSeekConfig buildDeepSeekDto() {\n AiConfigAdminDTO.DeepSeekConfig dto = new AiConfigAdminDTO.DeepSeekConfig();\n dto.setApiKey(deepSeekConfig.getApiKey());\n dto.setApiHost(deepSeekConfig.getApiHost());\n dto.setModel(deepSeekConfig.getModel());\n dto.setTimeout(deepSeekConfig.getTimeout());\n return dto;\n }\n\n private AiConfigAdminDTO.DoubaoConfig buildDoubaoDto() {\n AiConfigAdminDTO.DoubaoConfig dto = new AiConfigAdminDTO.DoubaoConfig();\n dto.setApiKey(doubaoConfig.getApiKey());\n dto.setApiHost(doubaoConfig.getApiHost());\n dto.setEndPoint(doubaoConfig.getEndPoint());\n return dto;\n }\n\n private AiConfigAdminDTO.AliConfig buildAliDto() {\n AiConfigAdminDTO.AliConfig dto = new AiConfigAdminDTO.AliConfig();\n dto.setModel(aliConfig.getModel());\n return dto;\n }\n\n private String joinEnumList(List values) {\n if (CollectionUtils.isEmpty(values)) {\n return \"\";\n }\n return values.stream().map(Enum::name).collect(Collectors.joining(\",\"));\n }\n\n private String joinStringList(List values) {\n if (CollectionUtils.isEmpty(values)) {\n return \"\";\n }\n return values.stream()\n .map(StringUtils::trimToEmpty)\n .filter(StringUtils::isNotBlank)\n .collect(Collectors.joining(\",\"));\n }\n\n private String doTest(AISourceEnum source, String prompt) {\n switch (source) {\n case CHAT_GPT_3_5:\n case CHAT_GPT_4:\n return testChatGpt(source, prompt);\n case ZHI_PU_AI:\n return testZhipu(prompt);\n case ZHIPU_CODING:\n return testZhipuCoding(prompt);\n case XUN_FEI_AI:\n return xunFeiIntegration.testConnection(prompt);\n case ALI_AI:\n return testAli(prompt);\n case DEEP_SEEK:\n return testDeepSeek(prompt);\n case DOU_BAO_AI:\n return testDoubao(prompt);\n case PAI_AI:\n return testPai(prompt);\n default:\n throw new IllegalStateException(\"暂不支持该模型的连通性测试: \" + source);\n }\n }\n\n private String testChatGpt(AISourceEnum model, String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!chatGptIntegration.directReturn(0L, item, model)) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"ChatGPT 连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testZhipu(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!zhipuIntegration.directReturn(0L, item)) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"智谱连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testZhipuCoding(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!zhipuCodingIntegration.directReturn(item)) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"智谱 Coding 连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testAli(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!aliIntegration.directReturn(0L, item)) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"阿里连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testDeepSeek(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!deepSeekIntegration.directReturn(item)) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"DeepSeek 连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testDoubao(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n if (!com.github.paicoding.forum.api.model.enums.ai.AiChatStatEnum.END.equals(doubaoIntegration.directAnswer(0L, item))) {\n throw new IllegalStateException(StringUtils.defaultIfBlank(item.getAnswer(), \"豆包连通性测试失败\"));\n }\n return item.getAnswer();\n }\n\n private String testPai(String prompt) {\n ChatItemVo item = new ChatItemVo().initQuestion(prompt);\n paiAiDemoService.doAnswer(0L, item);\n return item.getAnswer();\n }\n\n private AiConfigTestDTO buildTestResult(AISourceEnum source, boolean success, String message, String answer, long start) {\n AiConfigTestDTO dto = new AiConfigTestDTO();\n dto.setSource(source);\n dto.setSuccess(success);\n dto.setMessage(message);\n dto.setAnswer(answer);\n dto.setCostMs(System.currentTimeMillis() - start);\n return dto;\n }\n}\n"}}}}