mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
Updating version, removing deprecated classes
This commit is contained in:
parent
a8d105430f
commit
e142647d8d
@ -625,6 +625,7 @@ public class ApplicationProperties {
|
|||||||
private String primary = "gpt-5-nano";
|
private String primary = "gpt-5-nano";
|
||||||
private String fallback = "gpt-5-mini";
|
private String fallback = "gpt-5-mini";
|
||||||
private String embedding = "text-embedding-3-small";
|
private String embedding = "text-embedding-3-small";
|
||||||
|
private String apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@ -55,6 +55,7 @@ posthog.api.key=phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq
|
|||||||
posthog.host=https://eu.i.posthog.com
|
posthog.host=https://eu.i.posthog.com
|
||||||
|
|
||||||
spring.main.allow-bean-definition-overriding=true
|
spring.main.allow-bean-definition-overriding=true
|
||||||
|
spring.ai.openai.enabled=false
|
||||||
|
|
||||||
# Set up a consistent temporary directory location
|
# Set up a consistent temporary directory location
|
||||||
java.io.tmpdir=${stirling.tempfiles.directory:${java.io.tmpdir}/stirling-pdf}
|
java.io.tmpdir=${stirling.tempfiles.directory:${java.io.tmpdir}/stirling-pdf}
|
||||||
|
|||||||
@ -102,6 +102,7 @@ premium:
|
|||||||
primary: gpt-5-nano # Default lightweight model
|
primary: gpt-5-nano # Default lightweight model
|
||||||
fallback: gpt-5-mini # Escalation model for complex prompts
|
fallback: gpt-5-mini # Escalation model for complex prompts
|
||||||
embedding: text-embedding-3-small # Embedding model for vector store usage
|
embedding: text-embedding-3-small # Embedding model for vector store usage
|
||||||
|
apiKey: '' # Provide your OpenAI-compatible API key (or use SPRING_AI_OPENAI_API_KEY env var)
|
||||||
rag:
|
rag:
|
||||||
chunkSizeTokens: 512 # Token window used when chunking text
|
chunkSizeTokens: 512 # Token window used when chunking text
|
||||||
chunkOverlapTokens: 128 # Overlap between successive chunks
|
chunkOverlapTokens: 128 # Overlap between successive chunks
|
||||||
|
|||||||
@ -52,7 +52,7 @@ dependencies {
|
|||||||
api 'org.springframework.boot:spring-boot-starter-cache'
|
api 'org.springframework.boot:spring-boot-starter-cache'
|
||||||
api 'com.github.ben-manes.caffeine:caffeine'
|
api 'com.github.ben-manes.caffeine:caffeine'
|
||||||
api 'io.swagger.core.v3:swagger-core-jakarta:2.2.38'
|
api 'io.swagger.core.v3:swagger-core-jakarta:2.2.38'
|
||||||
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter:1.0.0-M6'
|
implementation 'org.springframework.ai:spring-ai-openai'
|
||||||
implementation 'com.bucket4j:bucket4j_jdk17-core:8.15.0'
|
implementation 'com.bucket4j:bucket4j_jdk17-core:8.15.0'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
|
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
package stirling.software.proprietary.config;
|
||||||
|
|
||||||
|
import org.springframework.ai.chat.model.ChatModel;
|
||||||
|
import org.springframework.ai.embedding.EmbeddingModel;
|
||||||
|
import org.springframework.ai.openai.OpenAiChatModel;
|
||||||
|
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||||
|
import org.springframework.ai.openai.OpenAiEmbeddingModel;
|
||||||
|
import org.springframework.ai.openai.OpenAiEmbeddingOptions;
|
||||||
|
import org.springframework.ai.openai.api.OpenAiApi;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import stirling.software.proprietary.service.chatbot.ChatbotFeatureProperties;
|
||||||
|
import stirling.software.proprietary.service.chatbot.ChatbotFeatureProperties.ChatbotSettings;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
|
public class ChatbotAiConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OpenAiApi chatbotOpenAiApi(ChatbotFeatureProperties properties) {
|
||||||
|
ChatbotSettings settings = properties.current();
|
||||||
|
String apiKey = settings.models().apiKey();
|
||||||
|
if (!StringUtils.hasText(apiKey)) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"premium.proFeatures.chatbot.models.apiKey must be set (or provide SPRING_AI_OPENAI_API_KEY)");
|
||||||
|
}
|
||||||
|
return new OpenAiApi(apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ChatModel chatbotChatModel(
|
||||||
|
OpenAiApi chatbotOpenAiApi, ChatbotFeatureProperties properties) {
|
||||||
|
OpenAiChatOptions options =
|
||||||
|
OpenAiChatOptions.builder()
|
||||||
|
.withModel(properties.current().models().primary())
|
||||||
|
.build();
|
||||||
|
return new OpenAiChatModel(chatbotOpenAiApi, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EmbeddingModel chatbotEmbeddingModel(
|
||||||
|
OpenAiApi chatbotOpenAiApi, ChatbotFeatureProperties properties) {
|
||||||
|
OpenAiEmbeddingOptions options =
|
||||||
|
OpenAiEmbeddingOptions.builder()
|
||||||
|
.withModel(properties.current().models().embedding())
|
||||||
|
.build();
|
||||||
|
return new OpenAiEmbeddingModel(chatbotOpenAiApi, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package stirling.software.proprietary.controller;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
@ -32,6 +33,7 @@ import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
|||||||
@RequestMapping("/api/internal/chatbot")
|
@RequestMapping("/api/internal/chatbot")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
public class ChatbotController {
|
public class ChatbotController {
|
||||||
|
|
||||||
private final ChatbotService chatbotService;
|
private final ChatbotService chatbotService;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package stirling.software.proprietary.controller;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
@ -15,6 +16,7 @@ import stirling.software.proprietary.service.chatbot.exception.NoTextDetectedExc
|
|||||||
|
|
||||||
@RestControllerAdvice(assignableTypes = ChatbotController.class)
|
@RestControllerAdvice(assignableTypes = ChatbotController.class)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
public class ChatbotExceptionHandler {
|
public class ChatbotExceptionHandler {
|
||||||
|
|
||||||
@ExceptionHandler(NoTextDetectedException.class)
|
@ExceptionHandler(NoTextDetectedException.class)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
@ -25,6 +26,7 @@ import stirling.software.proprietary.model.chatbot.ChatbotTextChunk;
|
|||||||
import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ChatbotCacheService {
|
public class ChatbotCacheService {
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import org.springframework.ai.chat.model.ChatResponse;
|
|||||||
import org.springframework.ai.chat.prompt.Prompt;
|
import org.springframework.ai.chat.prompt.Prompt;
|
||||||
import org.springframework.ai.openai.OpenAiChatModel;
|
import org.springframework.ai.openai.OpenAiChatModel;
|
||||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
|||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
public class ChatbotConversationService {
|
public class ChatbotConversationService {
|
||||||
|
|
||||||
private final ChatModel chatModel;
|
private final ChatModel chatModel;
|
||||||
|
|||||||
@ -2,7 +2,9 @@ package stirling.software.proprietary.service.chatbot;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.model.ApplicationProperties.Premium;
|
import stirling.software.common.model.ApplicationProperties.Premium;
|
||||||
@ -13,13 +15,23 @@ import stirling.software.common.model.ApplicationProperties.Premium.ProFeatures.
|
|||||||
public class ChatbotFeatureProperties {
|
public class ChatbotFeatureProperties {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
public ChatbotFeatureProperties(ApplicationProperties applicationProperties) {
|
public ChatbotFeatureProperties(
|
||||||
|
ApplicationProperties applicationProperties, Environment environment) {
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
|
this.environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatbotSettings current() {
|
public ChatbotSettings current() {
|
||||||
Chatbot chatbot = resolveChatbot();
|
Chatbot chatbot = resolveChatbot();
|
||||||
|
String configuredKey = Optional.ofNullable(chatbot.getModels().getApiKey()).orElse("");
|
||||||
|
String fallbackKey = environment.getProperty("spring.ai.openai.api-key", "");
|
||||||
|
String apiKey =
|
||||||
|
StringUtils.hasText(configuredKey)
|
||||||
|
? configuredKey
|
||||||
|
: (StringUtils.hasText(fallbackKey) ? fallbackKey : "");
|
||||||
|
|
||||||
return new ChatbotSettings(
|
return new ChatbotSettings(
|
||||||
chatbot.isEnabled(),
|
chatbot.isEnabled(),
|
||||||
chatbot.isAlphaWarning(),
|
chatbot.isAlphaWarning(),
|
||||||
@ -28,7 +40,8 @@ public class ChatbotFeatureProperties {
|
|||||||
new ChatbotSettings.ModelSettings(
|
new ChatbotSettings.ModelSettings(
|
||||||
chatbot.getModels().getPrimary(),
|
chatbot.getModels().getPrimary(),
|
||||||
chatbot.getModels().getFallback(),
|
chatbot.getModels().getFallback(),
|
||||||
chatbot.getModels().getEmbedding()),
|
chatbot.getModels().getEmbedding(),
|
||||||
|
apiKey),
|
||||||
new ChatbotSettings.RagSettings(
|
new ChatbotSettings.RagSettings(
|
||||||
chatbot.getRag().getChunkSizeTokens(),
|
chatbot.getRag().getChunkSizeTokens(),
|
||||||
chatbot.getRag().getChunkOverlapTokens(),
|
chatbot.getRag().getChunkOverlapTokens(),
|
||||||
@ -64,7 +77,8 @@ public class ChatbotFeatureProperties {
|
|||||||
OcrSettings ocr,
|
OcrSettings ocr,
|
||||||
AuditSettings audit) {
|
AuditSettings audit) {
|
||||||
|
|
||||||
public record ModelSettings(String primary, String fallback, String embedding) {}
|
public record ModelSettings(
|
||||||
|
String primary, String fallback, String embedding, String apiKey) {}
|
||||||
|
|
||||||
public record RagSettings(int chunkSizeTokens, int chunkOverlapTokens, int topK) {}
|
public record RagSettings(int chunkSizeTokens, int chunkOverlapTokens, int topK) {}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
import org.springframework.ai.embedding.EmbeddingModel;
|
||||||
import org.springframework.ai.embedding.EmbeddingResponse;
|
import org.springframework.ai.embedding.EmbeddingResponse;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
|||||||
import stirling.software.proprietary.service.chatbot.exception.NoTextDetectedException;
|
import stirling.software.proprietary.service.chatbot.exception.NoTextDetectedException;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ChatbotIngestionService {
|
public class ChatbotIngestionService {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
import org.springframework.ai.embedding.EmbeddingModel;
|
||||||
import org.springframework.ai.embedding.EmbeddingResponse;
|
import org.springframework.ai.embedding.EmbeddingResponse;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
|||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
public class ChatbotRetrievalService {
|
public class ChatbotRetrievalService {
|
||||||
|
|
||||||
private final ChatbotCacheService cacheService;
|
private final ChatbotCacheService cacheService;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package stirling.software.proprietary.service.chatbot;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -16,6 +17,7 @@ import stirling.software.proprietary.service.AuditService;
|
|||||||
import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
import stirling.software.proprietary.service.chatbot.exception.ChatbotException;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ConditionalOnProperty(value = "premium.proFeatures.chatbot.enabled", havingValue = "true")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ChatbotService {
|
public class ChatbotService {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import com.github.jk1.license.render.*
|
|||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.5.6"
|
springBootVersion = "3.5.6"
|
||||||
springAiVersion = "1.0.0-M6"
|
springAiVersion = "1.0.3"
|
||||||
pdfboxVersion = "3.0.5"
|
pdfboxVersion = "3.0.5"
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.42"
|
lombokVersion = "1.18.42"
|
||||||
|
|||||||
@ -587,3 +587,8 @@ In your Thymeleaf templates, use the `#{key}` syntax to reference the new transl
|
|||||||
```
|
```
|
||||||
|
|
||||||
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
||||||
|
|
||||||
|
### Chatbot Feature Configuration
|
||||||
|
|
||||||
|
- The chatbot backend is disabled unless `premium.proFeatures.chatbot.enabled` is true in `configs/settings.yml`.
|
||||||
|
- Provide an OpenAI-compatible key through `premium.proFeatures.chatbot.models.apiKey` (preferred) or the `SPRING_AI_OPENAI_API_KEY` environment variable. Without a key the app still boots, but the chatbot beans are not created.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user