Save progress
This commit is contained in:
1
agent/.sdkmanrc
Normal file
1
agent/.sdkmanrc
Normal file
@@ -0,0 +1 @@
|
||||
java=21.0.4-tem
|
||||
@@ -35,10 +35,32 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<!-- Ensure core Spring Context is present for IDE builds -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<!-- SQLite JDBC driver -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.46.0.0</version>
|
||||
</dependency>
|
||||
<!-- Hibernate community dialects (includes SQLiteDialect) -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-community-dialects</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- OpenAPI/Swagger UI via springdoc -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-starter-core</artifactId>
|
||||
@@ -63,6 +85,48 @@
|
||||
<artifactId>spring-modulith-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/io.projectreactor/reactor-core -->
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<version>3.7.9</version>
|
||||
</dependency>
|
||||
|
||||
<!-- LLM and agent orchestration -->
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
|
||||
<version>1.3.0-beta9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-spring-boot-starter</artifactId>
|
||||
<version>1.3.0-beta9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-reactor</artifactId>
|
||||
<version>1.3.0-beta9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.bsc.langgraph4j</groupId>-->
|
||||
<!-- <artifactId>langgraph4j-core</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-ollama</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -78,6 +142,27 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Enforce building with JDK 21 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-java</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireJavaVersion>
|
||||
<version>[21,)</version>
|
||||
</requireJavaVersion>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
public class AgentApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataDirectoryInitializer.createDataDirectory();
|
||||
SpringApplication.run(AgentApplication.class, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.clortox.agent;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Ensures the application's data directory exists before Spring Boot starts.
|
||||
*/
|
||||
public final class DataDirectoryInitializer {
|
||||
|
||||
private static final String DATA_DIR = "data";
|
||||
|
||||
private DataDirectoryInitializer() {}
|
||||
|
||||
public static void createDataDirectory() {
|
||||
Path path = Paths.get(DATA_DIR);
|
||||
try {
|
||||
if (Files.notExists(path)) {
|
||||
Files.createDirectories(path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to create data directory: " + path.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
agent/src/main/java/com/clortox/agent/agent/IAgent.java
Normal file
4
agent/src/main/java/com/clortox/agent/agent/IAgent.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package com.clortox.agent.agent;
|
||||
|
||||
public interface IAgent {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.clortox.agent.agent.controllers;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController("Agent")
|
||||
public class AgentController {
|
||||
|
||||
|
||||
@GetMapping(path = "/assistant")
|
||||
public ResponseEntity<?> get(String message) {
|
||||
return ResponseEntity.status(HttpStatus.OK).body("lol");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.clortox.agent.agent.llm;
|
||||
|
||||
import dev.langchain4j.http.client.HttpClientBuilder;
|
||||
import dev.langchain4j.http.client.spring.restclient.SpringRestClient;
|
||||
import dev.langchain4j.http.client.spring.restclient.SpringRestClientBuilder;
|
||||
import dev.langchain4j.model.chat.Capability;
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import dev.langchain4j.model.ollama.OllamaChatModel;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.http.client.HttpClientSettings;
|
||||
import org.springframework.boot.http.client.JdkHttpClientBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.util.Set;
|
||||
|
||||
@Configuration
|
||||
public class LLMConfiguration {
|
||||
|
||||
@Bean
|
||||
public ChatModel getOllama(
|
||||
@Value("${agent.ollama.baseUrl}") String baseUrl,
|
||||
@Value("${agent.ollama.model}") String model,
|
||||
@Value("${agent.ollama.temp}") Double temp
|
||||
) {
|
||||
|
||||
RestClient.Builder restClientBuilder = RestClient.builder()
|
||||
.requestFactory(new HttpComponentsClientHttpRequestFactory());
|
||||
|
||||
SpringRestClientBuilder springRestClientBuilder = SpringRestClient.builder()
|
||||
.restClientBuilder(restClientBuilder)
|
||||
.streamingRequestExecutor(new VirtualThreadTaskExecutor());
|
||||
|
||||
return OllamaChatModel.builder()
|
||||
.baseUrl(baseUrl)
|
||||
.httpClientBuilder(springRestClientBuilder)
|
||||
.modelName(model)
|
||||
.temperature(temp)
|
||||
.maxRetries(3)
|
||||
.returnThinking(false)
|
||||
.logResponses(true)
|
||||
.logResponses(true)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.clortox.agent.agent.memory;
|
||||
|
||||
import dev.langchain4j.data.message.ChatMessage;
|
||||
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PersistentChatMemoryStore implements ChatMemoryStore {
|
||||
|
||||
@Override
|
||||
public List<ChatMessage> getMessages(Object memoryId) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMessages(Object memoryId) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.clortox.agent.agent.memory.persistence;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "message")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Message {
|
||||
|
||||
@Id
|
||||
@Getter
|
||||
@Setter
|
||||
@Column(name = "ID", nullable = false, updatable = false)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "conversationId", nullable = false, updatable = false)
|
||||
private String conversationId;
|
||||
|
||||
@Column(name = "content", nullable = false, updatable = false)
|
||||
private String content;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.clortox.agent.agent.service;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class Agent {
|
||||
|
||||
private final ChatModel model;
|
||||
|
||||
@Autowired
|
||||
public Agent(
|
||||
ChatModel model
|
||||
) {
|
||||
|
||||
this.model = model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.clortox.agent.starters;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class StarterListener {
|
||||
|
||||
@EventListener
|
||||
public void onApplicationReady(ApplicationReadyEvent event) {
|
||||
|
||||
printBanner();
|
||||
|
||||
}
|
||||
|
||||
private void printBanner() {
|
||||
log.info(" █████╗ ██████╗ ███████╗███╗ ██╗████████╗");
|
||||
log.info("██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝");
|
||||
log.info("███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║");
|
||||
log.info("██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║");
|
||||
log.info("██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║");
|
||||
log.info("╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝");
|
||||
|
||||
log.info("Welcome to the local agent!");
|
||||
|
||||
log.info("View documentation at http://localhost:{}/swagger-ui/index.html", 8080);
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
spring.application.name=agent
|
||||
37
agent/src/main/resources/application.yml
Normal file
37
agent/src/main/resources/application.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:sqlite:${SQLITE_DB_LOCATION:./data/agent.db}
|
||||
driver-class-name: org.sqlite.JDBC
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.community.dialect.SQLiteDialect
|
||||
format_sql: true
|
||||
open-in-view: false
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.hibernate.SQL: warn
|
||||
org.hibernate.type.descriptor.sql.BasicBinder: warn
|
||||
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
path: /swagger-ui
|
||||
|
||||
|
||||
agent:
|
||||
ollama:
|
||||
baseUrl: "${OLLAMA_BASEURL:http://10.0.3.2:8080}"
|
||||
model: "${OLLAMA_MODEL:llama3.2}"
|
||||
temp: "${OLLAMA_TEMP:0.2}"
|
||||
|
||||
#langchain4j:
|
||||
# ollama:
|
||||
# chat-model:
|
||||
# base-url: "${OLLAMA_BASEURL:http://10.0.3.2:8080}"
|
||||
# model-name: "${OLLAMA_MODEL:llama3.2}"
|
||||
# log-requests: true
|
||||
# log-responses: true
|
||||
# return-thinking: false
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE TABLE message (
|
||||
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
conversationId VARCHAR(32) NOT NULL,
|
||||
content VARCHAR(4096) NOT NULL
|
||||
)
|
||||
12
agent/src/test/java/com/clortox/agent/ModularityTest.java
Normal file
12
agent/src/test/java/com/clortox/agent/ModularityTest.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.clortox.agent;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.modulith.core.ApplicationModules;
|
||||
|
||||
public class ModularityTest {
|
||||
|
||||
@Test
|
||||
public void verify() {
|
||||
ApplicationModules.of(AgentApplication.class).verify();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user