From bd5d9040583079dcf93158bae1537c7f8d3b0699 Mon Sep 17 00:00:00 2001 From: 0007 <0007@qq.com> Date: Wed, 27 Aug 2025 19:57:38 +0800 Subject: [PATCH] Add File --- .../llm/chatglm/ChatglmLlmUtil.java | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 agents-flex-llm/agents-flex-llm-chatglm/src/main/java/com/agentsflex/llm/chatglm/ChatglmLlmUtil.java diff --git a/agents-flex-llm/agents-flex-llm-chatglm/src/main/java/com/agentsflex/llm/chatglm/ChatglmLlmUtil.java b/agents-flex-llm/agents-flex-llm-chatglm/src/main/java/com/agentsflex/llm/chatglm/ChatglmLlmUtil.java new file mode 100644 index 0000000..64014c5 --- /dev/null +++ b/agents-flex-llm/agents-flex-llm-chatglm/src/main/java/com/agentsflex/llm/chatglm/ChatglmLlmUtil.java @@ -0,0 +1,117 @@ +/* + * 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.chatglm; + +import com.agentsflex.core.llm.ChatOptions; +import com.agentsflex.core.message.HumanMessage; +import com.agentsflex.core.message.Message; +import com.agentsflex.core.message.MessageStatus; +import com.agentsflex.core.parser.AiMessageParser; +import com.agentsflex.core.parser.impl.DefaultAiMessageParser; +import com.agentsflex.core.prompt.DefaultPromptFormat; +import com.agentsflex.core.prompt.Prompt; +import com.agentsflex.core.prompt.PromptFormat; +import com.agentsflex.core.util.Maps; +import com.agentsflex.core.util.MessageUtil; +import com.alibaba.fastjson.JSON; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.MacAlgorithm; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class ChatglmLlmUtil { + + private static final PromptFormat promptFormat = new DefaultPromptFormat(); + + private static final String id = "HS256"; + private static final String jcaName = "HmacSHA256"; + private static final MacAlgorithm macAlgorithm; + + static { + try { + //create a custom MacAlgorithm with a custom minKeyBitLength + int minKeyBitLength = 128; + Class c = Class.forName("io.jsonwebtoken.impl.security.DefaultMacAlgorithm"); + Constructor ctor = c.getDeclaredConstructor(String.class, String.class, int.class); + ctor.setAccessible(true); + macAlgorithm = (MacAlgorithm) ctor.newInstance(id, jcaName, minKeyBitLength); + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + public static String createAuthorizationToken(ChatglmLlmConfig config) { + Map headers = new HashMap<>(); + headers.put("alg", "HS256"); + headers.put("sign_type", "SIGN"); + + long nowMillis = System.currentTimeMillis(); + String[] idAndSecret = config.getApiKey().split("\\."); + + Map payloadMap = new HashMap<>(); + payloadMap.put("api_key", idAndSecret[0]); + payloadMap.put("exp", nowMillis + 3600000); + payloadMap.put("timestamp", nowMillis); + String payloadJsonString = JSON.toJSONString(payloadMap); + + byte[] bytes = idAndSecret[1].getBytes(); + SecretKey secretKey = new SecretKeySpec(bytes, jcaName); + + JwtBuilder builder = Jwts.builder() + .content(payloadJsonString) + .header().add(headers).and() + .signWith(secretKey, macAlgorithm); + return builder.compact(); + } + + public static AiMessageParser getAiMessageParser(boolean isStream) { + return DefaultAiMessageParser.getChatGPTMessageParser(isStream); + } + + + public static String promptToPayload(Prompt prompt, ChatglmLlmConfig config, boolean withStream, ChatOptions options) { + List messages = prompt.toMessages(); + HumanMessage message = MessageUtil.findLastHumanMessage(messages); + return Maps.of("model", Optional.ofNullable(options.getModel()).orElse(config.getModel())) + .set("messages", promptFormat.toMessagesJsonObject(messages)) + .setIf(withStream, "stream", true) + .setIfNotEmpty("tools", promptFormat.toFunctionsJsonObject(message)) + .setIfContainsKey("tools", "tool_choice", MessageUtil.getToolChoice(message)) + .setIfNotNull("top_p", options.getTopP()) + .setIfNotEmpty("stop", options.getStop()) + .setIf(map -> !map.containsKey("tools") && options.getTemperature() > 0, "temperature", options.getTemperature()) + .setIf(map -> !map.containsKey("tools") && options.getMaxTokens() != null, "max_tokens", options.getMaxTokens()) + .setIfNotEmpty(options.getExtra()) + .toJSON(); + } + + + public static MessageStatus parseMessageStatus(String status) { + return "stop".equals(status) ? MessageStatus.END : MessageStatus.MIDDLE; + } + + +}