From 27c04f3808eb77d01765c4aac8db14cd7dc04f84 Mon Sep 17 00:00:00 2001 From: 0007 <0007@qq.com> Date: Wed, 27 Aug 2025 19:57:26 +0800 Subject: [PATCH] Add File --- .../llm/siliconflow/SiliconflowLlm.java | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 agents-flex-llm/agents-flex-llm-siliconflow/src/main/java/com/agentsflex/llm/siliconflow/SiliconflowLlm.java diff --git a/agents-flex-llm/agents-flex-llm-siliconflow/src/main/java/com/agentsflex/llm/siliconflow/SiliconflowLlm.java b/agents-flex-llm/agents-flex-llm-siliconflow/src/main/java/com/agentsflex/llm/siliconflow/SiliconflowLlm.java new file mode 100644 index 0000000..79fd750 --- /dev/null +++ b/agents-flex-llm/agents-flex-llm-siliconflow/src/main/java/com/agentsflex/llm/siliconflow/SiliconflowLlm.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.agentsflex.llm.siliconflow; + +import com.agentsflex.core.document.Document; +import com.agentsflex.core.llm.BaseLlm; +import com.agentsflex.core.llm.ChatOptions; +import com.agentsflex.core.llm.StreamResponseListener; +import com.agentsflex.core.llm.client.BaseLlmClientListener; +import com.agentsflex.core.llm.client.HttpClient; +import com.agentsflex.core.llm.client.LlmClient; +import com.agentsflex.core.llm.client.LlmClientListener; +import com.agentsflex.core.llm.client.impl.SseClient; +import com.agentsflex.core.llm.embedding.EmbeddingOptions; +import com.agentsflex.core.llm.response.AiMessageResponse; +import com.agentsflex.core.parser.AiMessageParser; +import com.agentsflex.core.prompt.Prompt; +import com.agentsflex.core.store.VectorData; +import com.agentsflex.core.util.LogUtil; +import com.agentsflex.core.util.StringUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +/** + * @author daxian1218 + */ +public class SiliconflowLlm extends BaseLlm { + + private final Map headers = new HashMap<>(); + private final HttpClient httpClient = new HttpClient(); + private final AiMessageParser aiMessageParser = SiliconflowLlmUtil.getAiMessageParser(false); + private final AiMessageParser streamMessageParser = SiliconflowLlmUtil.getAiMessageParser(true); + + public SiliconflowLlm(SiliconflowConfig config) { + super(config); + headers.put("Content-Type", "application/json"); + headers.put("Accept", "application/json"); + headers.put("Authorization", "Bearer " + getConfig().getApiKey()); + } + + public static SiliconflowLlm of(String apiKey) { + SiliconflowConfig config = new SiliconflowConfig(); + config.setApiKey(apiKey); + return new SiliconflowLlm(config); + } + + @Override + public AiMessageResponse chat(Prompt prompt, ChatOptions options) { + + Consumer> headersConfig = config.getHeadersConfig(); + if (headersConfig != null) { + headersConfig.accept(headers); + } + + String payload = SiliconflowLlmUtil.promptToPayload(prompt, config, options, false); + String endpoint = config.getEndpoint(); + String response = httpClient.post(endpoint + "/chat/completions", headers, payload); + + if (config.isDebug()) { + LogUtil.println(">>>>receive payload:" + response); + } + + if (StringUtil.noText(response)) { + return AiMessageResponse.error(prompt, response, "no content for response."); + } + + if (response.startsWith("{")) { + JSONObject jsonObject = JSON.parseObject(response); + Integer code = jsonObject.getInteger("code"); + if (code != null) { + return AiMessageResponse.error(prompt, response, jsonObject.getString("message")); + } + + + return new AiMessageResponse(prompt, response, aiMessageParser.parse(jsonObject)); + } + + return AiMessageResponse.error(prompt, response, response); + } + + @Override + public void chatStream(Prompt prompt, StreamResponseListener streamResponseListener, ChatOptions chatOptions) { + LlmClient llmClient = new SseClient(); + String payload = SiliconflowLlmUtil.promptToPayload(prompt, config, chatOptions, true); + String endpoint = config.getEndpoint(); + LlmClientListener clientListener = new BaseLlmClientListener(this, llmClient, streamResponseListener, prompt, streamMessageParser); + llmClient.start(endpoint + "/chat/completions", headers, payload, clientListener, config); + } + + @Override + public void chatStream(Prompt prompt, StreamResponseListener streamResponseListener) { + chatStream(prompt, streamResponseListener, ChatOptions.DEFAULT); + } + + @Override + public VectorData embed(Document document, EmbeddingOptions embeddingOptions) { + Consumer> headersConfig = config.getHeadersConfig(); + if (headersConfig != null) { + headersConfig.accept(headers); + } + + String payload = SiliconflowLlmUtil.documentToPayload(document, config, embeddingOptions); + String endpoint = config.getEndpoint(); + String response = httpClient.post(endpoint + "/embeddings", headers, payload); + + if (config.isDebug()) { + LogUtil.println(">>>>receive payload:" + response); + } + + if (StringUtil.noText(response)) { + return null; + } + + if (response.startsWith("{")) { + JSONObject jsonObject = JSON.parseObject(response); + Integer code = jsonObject.getInteger("code"); + if (code != null) { + return null; + } + VectorData vectorData = new VectorData(); + vectorData.setVector(JSONPath.read(response, "$.data[0].embedding", double[].class)); + + return vectorData; + } + + return null; + } +}