mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 09:40:58 +00:00
[feat] add support for OpenRouter AI provider (#3439)
Signed-off-by: Yang Chen <1597081640@qq.com> Co-authored-by: tomsun28 <tomsun28@outlook.com> Co-authored-by: aias00 <liuhongyu@apache.org> Co-authored-by: Jast <shenghang@apache.org>
This commit is contained in:
co-authored by
tomsun28
aias00
Jast
parent
8065b63057
commit
199466cd59
+29
-1
@@ -142,12 +142,40 @@ public interface AiConstants {
|
||||
float TEMPERATURE = 0.7f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ollama constants
|
||||
*/
|
||||
interface OllamaConstants {
|
||||
/**
|
||||
* request role param
|
||||
*/
|
||||
String REQUEST_ROLE = "user";
|
||||
|
||||
/**
|
||||
* The model outputs the maximum tokens, with a maximum output of 8192 and a default value of 3072
|
||||
*/
|
||||
Integer MAX_TOKENS = 3072;
|
||||
|
||||
/**
|
||||
* The sampling temperature, which controls the randomness of the output, must be positive
|
||||
* The value ranges from 0.0 to 1.0, and cannot be equal to 0. The default value is 0.95. The larger the value,
|
||||
* the more random and creative the output will be. The smaller the value, the more stable or certain the output will be
|
||||
* You are advised to adjust top_p or temperature parameters based on application scenarios, but do not adjust the two parameters at the same time
|
||||
*/
|
||||
float TEMPERATURE = 0.7f;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenRouter constants
|
||||
*/
|
||||
interface OpenRouterConstants {
|
||||
/**
|
||||
* OpenRouter Ai URL
|
||||
*/
|
||||
String URL = "https://openrouter.ai/api/v1/chat/completions";
|
||||
|
||||
/**
|
||||
* request role param
|
||||
*/
|
||||
|
||||
+5
-1
@@ -47,8 +47,12 @@ public enum AiTypeEnum {
|
||||
/**
|
||||
* Ollama AI
|
||||
*/
|
||||
ollama;
|
||||
ollama,
|
||||
|
||||
/**
|
||||
* OpenRouter
|
||||
*/
|
||||
openRouter;
|
||||
|
||||
/**
|
||||
* get type
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.hertzbeat.manager.service.ai;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.common.constants.AiConstants;
|
||||
import org.apache.hertzbeat.common.constants.AiTypeEnum;
|
||||
import org.apache.hertzbeat.manager.config.AiProperties;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.AiMessage;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.OpenAiRequestParamDTO;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.OpenAiResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.ServerSentEvent;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* OpenRouter service
|
||||
*/
|
||||
@Service("OpenRouterServiceImpl")
|
||||
@ConditionalOnProperty(prefix = "ai", name = "type", havingValue = "openRouter")
|
||||
@Slf4j
|
||||
public class OpenRouterServiceImpl implements AiService {
|
||||
|
||||
@Autowired
|
||||
private AiProperties aiProperties;
|
||||
|
||||
private WebClient webClient;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
this.webClient = WebClient.builder()
|
||||
.baseUrl(AiConstants.OpenRouterConstants.URL)
|
||||
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + aiProperties.getApiKey())
|
||||
.exchangeStrategies(ExchangeStrategies.builder()
|
||||
.codecs(item -> item.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiTypeEnum getType() {
|
||||
return AiTypeEnum.openRouter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ServerSentEvent<String>> requestAi(String text) {
|
||||
checkParam(text, aiProperties.getModel(), aiProperties.getApiKey());
|
||||
OpenAiRequestParamDTO openRouterParam = OpenAiRequestParamDTO.builder()
|
||||
.model(aiProperties.getModel())
|
||||
.stream(Boolean.TRUE)
|
||||
.maxTokens(AiConstants.OpenRouterConstants.MAX_TOKENS)
|
||||
.temperature(AiConstants.OpenRouterConstants.TEMPERATURE)
|
||||
.messages(List.of(new AiMessage(AiConstants.OpenRouterConstants.REQUEST_ROLE, text)))
|
||||
.build();
|
||||
|
||||
return webClient.post()
|
||||
.body(BodyInserters.fromValue(openRouterParam))
|
||||
.retrieve()
|
||||
.bodyToFlux(String.class)
|
||||
.filter(aiResponse -> !"[DONE]".equals(aiResponse))
|
||||
.map(OpenAiResponse::convertToResponse)
|
||||
.doOnError(error -> log.info("OpenRouterAiServiceImpl.requestAi exception:{}", error.getMessage()));
|
||||
}
|
||||
|
||||
private void checkParam(String param, String model, String apiKey) {
|
||||
Assert.notNull(param, "text is null");
|
||||
Assert.notNull(model, "model is null");
|
||||
Assert.notNull(apiKey, "ai.api-key is null");
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ grafana:
|
||||
|
||||
# See the documentation for details : https://hertzbeat.apache.org/zh-cn/docs/help/aiConfig
|
||||
ai:
|
||||
# AI Type:zhiPu、alibabaAi、kimiAi、sparkDesk、ollama
|
||||
# AI Type:zhiPu、alibabaAi、kimiAi、sparkDesk、ollama、openRouter
|
||||
type:
|
||||
# Model name:glm-4、qwen-turboo、moonshot-v1-8k、generalv3.5
|
||||
model:
|
||||
|
||||
@@ -69,3 +69,13 @@ QuickStart: <https://github.com/ollama/ollama/tree/main/docs>
|
||||
| type | ollama (must be exactly the same as example) | |
|
||||
| model | deepseek-r1:latest、qwen3:latest、llama4:16x17b | <https://ollama.com/search> |
|
||||
| api-url | <http://127.0.0.1:11434/v1/chat/completions> | |
|
||||
|
||||
#### OpenRouter
|
||||
|
||||
QuickStart: <https://openrouter.ai/docs/quickstart>
|
||||
|
||||
| Name of the parameter | Example | Link |
|
||||
|-----------------------|------------------------------------------------|-----------------------------------------|
|
||||
| type | openRouter (must be exactly the same as example) | |
|
||||
| model | openai/gpt-4o, anthropic/claude-sonnet-4 | <https://openrouter.ai/models> |
|
||||
| api-key | xxxxxxxxxxx | <https://openrouter.ai/settings/provisioning-keys> |
|
||||
|
||||
@@ -69,3 +69,13 @@ keywords: [人工智能 AI]
|
||||
| type | ollama (必须和示例完全相同) | |
|
||||
| model | deepseek-r1:latest、qwen3:latest、llama4:16x17b | <https://ollama.com/search> |
|
||||
| api-url | <http://127.0.0.1:11434/v1/chat/completions> | |
|
||||
|
||||
#### OpenRouter
|
||||
|
||||
快速入门: <https://openrouter.ai/docs/quickstart>
|
||||
|
||||
| 参数名称 | 示例 | 链接 |
|
||||
|---------|------------------------------------------|----------------------------------------------------|
|
||||
| type | openRouter (必须和示例完全相同) | |
|
||||
| model | openai/gpt-4o, anthropic/claude-sonnet-4 | <https://openrouter.ai/models> |
|
||||
| api-key | xxxxxxxxxxx | <https://openrouter.ai/settings/provisioning-keys> |
|
||||
|
||||
Reference in New Issue
Block a user