Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr-title-check.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: PR Title Check

on:
pull_request:
pull_request_target:
types: [opened, edited, synchronize]

permissions:
Expand Down
43 changes: 43 additions & 0 deletions examples/fel-spring-example/01-model/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.fitframework.example</groupId>
<artifactId>fel-spring-example-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>chat-model-spring-example</artifactId>

<dependencies>
<!-- FEL Spring Boot Starter -->
<dependency>
<groupId>org.fitframework.fel</groupId>
<artifactId>fel-spring-boot-starter</artifactId>
<version>${fel.version}</version>
</dependency>

<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- WebFlux:流式响应需要 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2024 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.example.ai.chat.model;

import modelengine.fel.core.chat.ChatMessage;
import modelengine.fel.core.chat.ChatModel;
import modelengine.fel.core.chat.ChatOption;
import modelengine.fel.core.chat.support.ChatMessages;
import modelengine.fel.core.chat.support.HumanMessage;
import modelengine.fitframework.flowable.Choir;
import reactor.adapter.JdkFlowAdapter;
import reactor.core.publisher.Flux;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
* 聊天模型样例控制器(Spring Boot 版本)。
*
* @author 黄可欣
* @since 2025-01-20
*/
@RestController
@RequestMapping("/ai/example")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public class ChatModelExampleController {
private final ChatModel chatModel;
@Value("${example.model}")
private String modelName;

public ChatModelExampleController(ChatModel chatModel) {
this.chatModel = chatModel;
}

/**
* 聊天接口。
*
* @param query 表示用户输入查询的 {@link String}。
* @return 表示聊天模型生成的回复的 Map。
*/
@GetMapping("/chat")
public Object chat(@RequestParam("query") String query) {
ChatOption option = ChatOption.custom().model(this.modelName).stream(false).build();
ChatMessage aiMessage =
this.chatModel.generate(ChatMessages.from(new HumanMessage(query)), option).first().block().get();
return java.util.Map.of("content", aiMessage.text(), "toolCalls", aiMessage.toolCalls());
}

/**
* 流式聊天接口。
*
* @param query 表示用户输入查询的 {@link String}。
* @return 表示聊天模型生成的流式回复的 Choir。
*/
@GetMapping(value = "/chat-stream", produces = "text/event-stream;charset=UTF-8")
public Flux<Map<String, Object>> chatStream(@RequestParam("query") String query) {
ChatOption option = ChatOption.custom().model(this.modelName).stream(true).build();
Choir<ChatMessage> choir = this.chatModel.generate(ChatMessages.from(new HumanMessage(query)), option);
return JdkFlowAdapter.flowPublisherToFlux(choir.map(chatMessage -> Map.of("content", chatMessage.text())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2024 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.example.ai.chat.model;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* 启动程序(Spring Boot 版本)。
*
* @author 黄可欣
* @since 2025-01-20
*/
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
spring:
application:
name: chat-model-example

fel:
openai:
api-base:'${api-base}'
api-key:'${your-api-key}'
example:
model:'${model-name}'
37 changes: 37 additions & 0 deletions examples/fel-spring-example/02-template/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.fitframework.example</groupId>
<artifactId>fel-spring-example-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>chat-template-spring-example</artifactId>

<dependencies>
<!-- FEL Spring Boot Starter -->
<dependency>
<groupId>org.fitframework.fel</groupId>
<artifactId>fel-spring-boot-starter</artifactId>
<version>${fel.version}</version>
</dependency>

<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2024 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.example.ai.chat.template;

import modelengine.fel.core.chat.ChatMessage;
import modelengine.fel.core.chat.ChatModel;
import modelengine.fel.core.chat.ChatOption;
import modelengine.fel.core.chat.support.ChatMessages;
import modelengine.fel.core.template.MessageTemplate;
import modelengine.fel.core.template.support.HumanMessageTemplate;
import modelengine.fel.core.util.Tip;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
* 聊天模板样例控制器(Spring Boot 版本)。
*
* @author 黄可欣
* @since 2025-01-20
*/
@RestController
@RequestMapping("/ai/example")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public class ChatTemplateExampleController {
private final ChatModel chatModel;
private final MessageTemplate template;
@Value("${example.model}")
private String modelName;

public ChatTemplateExampleController(ChatModel chatModel) {
this.chatModel = chatModel;
this.template = new HumanMessageTemplate("给我讲个关于{{adjective}}的{{content}}。");
}

/**
* 聊天接口。
*
* @param adjective 表示主题的 {@link String}。
* @param content 表示内容的 {@link String}。
* @return 表示聊天模型生成的回复的 Map。
*/
@GetMapping("/chat")
public Object chat(@RequestParam("adjective") String adjective, @RequestParam("content") String content) {
ChatOption option = ChatOption.custom().model(this.modelName).stream(false).build();
ChatMessage aiMessage = this.chatModel.generate(ChatMessages.from(this.template.render(Tip.from("adjective", adjective)
.add("content", content)
.freeze())), option).first().block().get();
return java.util.Map.of(
"content", aiMessage.text(),
"toolCalls", aiMessage.toolCalls()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2024 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.example.ai.chat.template;

import modelengine.fitframework.starter.spring.annotation.EnableFitProxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* 启动程序(Spring Boot 版本)。
*
* @author 黄可欣
* @since 2025-01-20
*/
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
spring:
application:
name: chat-template-example
fel:
openai:
api-base:'${api-base}'
api-key:'${your-api-key}'
example:
model:'${model-name}'
37 changes: 37 additions & 0 deletions examples/fel-spring-example/03-memory/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.fitframework.example</groupId>
<artifactId>fel-spring-example-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>chat-memory-spring-example</artifactId>

<dependencies>
<!-- FEL Spring Boot Starter -->
<dependency>
<groupId>org.fitframework.fel</groupId>
<artifactId>fel-spring-boot-starter</artifactId>
<version>${fel.version}</version>
</dependency>

<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2024 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.example.ai.chat.memory;

import modelengine.fel.core.chat.ChatMessage;
import modelengine.fel.core.chat.ChatModel;
import modelengine.fel.core.chat.ChatOption;
import modelengine.fel.core.chat.support.ChatMessages;
import modelengine.fel.core.chat.support.HumanMessage;
import modelengine.fel.core.memory.Memory;
import modelengine.fel.core.memory.support.CacheMemory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
* 聊天记忆样例控制器(Spring Boot 版本)。
*
* @author 黄可欣
* @since 2025-01-20
*/
@RestController
@RequestMapping("/ai/example")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public class ChatMemoryExampleController {
private final ChatModel chatModel;
private final Memory memory = new CacheMemory();
@Value("${example.model}")
private String modelName;

public ChatMemoryExampleController(ChatModel chatModel) {
this.chatModel = chatModel;
}

/**
* 聊天接口。
*
* @param query 表示用户输入查询的 {@link String}。
* @return 表示聊天模型生成的回复的 Map。
*/
@GetMapping("/chat")
public Object chat(@RequestParam("query") String query) {
ChatOption option = ChatOption.custom().model(this.modelName).stream(false).build();
this.memory.add(new HumanMessage(query));
ChatMessage aiMessage =
this.chatModel.generate(ChatMessages.from(this.memory.messages()), option).first().block().get();
this.memory.add(aiMessage);
return java.util.Map.of(
"content", aiMessage.text(),
"toolCalls", aiMessage.toolCalls()
);
}
}
Loading
Loading