Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions prompto-lab-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.github.timemachinelab.sfchain.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 描述: AI操作注解
* 用于标识AI操作类,并指定操作类型和默认模型
* @author suifeng
* 日期: 2025/8/11
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AIOp {

/**
* 操作类型标识
* 例如: "POSITION_BASIC_INFO_PARSE_OP"
*/
String value();

/**
* 默认使用的模型名称
* 如果不指定,将使用操作映射配置中的模型
*/
String defaultModel() default "";

/**
* 操作描述
*/
String description() default "";

/**
* 是否启用该操作
*/
boolean enabled() default true;

/**
* 支持的模型列表(可选)
* 如果指定,将限制该操作只能使用这些模型
*/
String[] supportedModels() default {};

/**
* 是否需要JSON输出
*/
boolean requireJsonOutput() default true;

/**
* 是否自动修复JSON格式错误
* 当requireJsonOutput为true且AI返回的JSON格式有误时,自动调用JSON修复操作
*/
boolean autoRepairJson() default true;

/**
* 是否支持思考模式
*/
boolean supportThinking() default false;

/**
* 默认最大token数
*/
int defaultMaxTokens() default 4096;

/**
* 默认温度参数
*/
double defaultTemperature() default 0.7;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.github.timemachinelab.sfchain.config;

import io.github.timemachinelab.sfchain.core.AIModel;
import io.github.timemachinelab.sfchain.core.openai.OpenAIModelConfig;
import io.github.timemachinelab.sfchain.core.openai.OpenAIModelFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* 描述: OpenAI兼容模型自动配
* @author suifeng
* 日期: 2025/8/11
*/
@Slf4j
@Configuration
@EnableConfigurationProperties(OpenAIModelsConfig.class)
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "ai.openai-models", name = "enabled", havingValue = "true", matchIfMissing = true)
public class OpenAIAutoConfiguration {

private final OpenAIModelsConfig openAIModelsConfig;

/**
* 创建OpenAI模型工厂
*/
@Bean
@Primary
public OpenAIModelFactory openAIModelFactory() {
OpenAIModelFactory factory = new OpenAIModelFactory();

// 注册配置文件中的模型
Map<String, OpenAIModelConfig> modelConfigs = openAIModelsConfig.getValidModelConfigs();
modelConfigs.forEach((name, config) -> {
try {
factory.registerModel(config);
log.info("成功注册模型: {} ({})", config.getModelName(), config.getProvider());
} catch (Exception e) {
log.error("注册模型失败: {} - {}", config.getModelName(), e.getMessage());
}
});

return factory;
}

/**
* 创建AI模型列表,供ModelRegistry使用
*/
@Bean
public List<AIModel> aiModels(OpenAIModelFactory factory) {
List<AIModel> models = new ArrayList<>();

// 为每个注册的模型创建实例
factory.getRegisteredModelNames().forEach(modelName -> {
try {
AIModel model = factory.createModel(modelName);
models.add(model);
log.info("创建AI模型实例: {}", modelName);
} catch (Exception e) {
log.error("创建模型实例失败: {} - {}", modelName, e.getMessage());
}
});

return models;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package io.github.timemachinelab.sfchain.config;

import io.github.timemachinelab.sfchain.core.openai.OpenAIModelConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
* 描述: OpenAI兼容模型配置
* @author suifeng
* 日期: 2025/8/11
*/
@Data
@Component
@ConfigurationProperties(prefix = "ai.openai-models")
public class OpenAIModelsConfig {

/**
* 模型配置映射
* key: 模型名称
* value: 模型配置
*/
private Map<String, ModelConfigProperties> models = new HashMap<>();

/**
* 模型配置属性
*/
@Data
public static class ModelConfigProperties {
/**
* 模型名称
*/
private String modelName;

/**
* API基础URL
*/
private String baseUrl;

/**
* API密钥
*/
private String apiKey;

/**
* 默认最大token数
*/
private Integer defaultMaxTokens = 4096;

/**
* 默认温度参数
*/
private Double defaultTemperature = 0.7;

/**
* 是否支持流式输出
*/
private Boolean supportStream = false;

/**
* 是否支持JSON格式输出
*/
private Boolean supportJsonOutput = false;

/**
* 是否支持思考模式
*/
private Boolean supportThinking = false;

/**
* 额外的HTTP请求头
*/
private Map<String, String> additionalHeaders = new HashMap<>();

/**
* 模型描述
*/
private String description;

/**
* 模型提供商
*/
private String provider;

/**
* 是否启用
*/
private Boolean enabled = true;

/**
* 转换为OpenAIModelConfig
*/
public OpenAIModelConfig toOpenAIModelConfig() {
return OpenAIModelConfig.builder()
.modelName(modelName)
.baseUrl(baseUrl)
.apiKey(apiKey)
.defaultMaxTokens(defaultMaxTokens)
.defaultTemperature(defaultTemperature)
.supportStream(supportStream)
.supportJsonOutput(supportJsonOutput)
.supportThinking(supportThinking)
.additionalHeaders(additionalHeaders)
.description(description)
.provider(provider)
.enabled(enabled)
.build();
}
}

/**
* 获取所有有效的模型配置
*/
public Map<String, OpenAIModelConfig> getValidModelConfigs() {
Map<String, OpenAIModelConfig> validConfigs = new HashMap<>();

models.forEach((key, properties) -> {
if (properties.getModelName() == null) {
properties.setModelName(key);
}

OpenAIModelConfig config = properties.toOpenAIModelConfig();
if (config.isValid() && Boolean.TRUE.equals(config.getEnabled())) {
validConfigs.put(key, config);
}
});

return validConfigs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.timemachinelab.sfchain.constants;

/**
* 描述: AI操作常量定义
* 定义所有AI操作的标识符
*
* @author suifeng
* 日期: 2025/8/11
*/
public class AIOperationConstant {

/**
* JSON修复操作
*/
public static final String JSON_REPAIR_OP = "JSON_REPAIR_OP";

/**
* 文本分类操作
*/
public static final String TEXT_CLASSIFICATION_OP = "TEXT_CLASSIFICATION";

/**
* 模型验证操作
*/
public static final String MODEL_VALIDATION_OP = "MODEL_VALIDATION_OP";

/**
* 私有构造函数,防止实例化
*/
private AIOperationConstant() {
throw new UnsupportedOperationException("常量类不允许实例化");
}
}
Loading
Loading