Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend operations center begin (#208) #209

Merged
merged 1 commit into from
Aug 2, 2024
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
3 changes: 3 additions & 0 deletions .devcontainer/postStart.sh
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
cp .devcontainer/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

echo "Let's go for a dRAGon ride! 🐉"
2 changes: 2 additions & 0 deletions .devcontainer/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
gradle pnpmLint checkstyleMain checkstyleTest --no-daemon --quiet
10 changes: 8 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ jobs:
- name: Set Frontend Version
run: pnpm version from-git --no-git-tag-version --prefix frontend

- name: Lint Frontend
run: gradle pnpmInstall pnpmLint

- name: Lint Backend
run: gradle checkstyleMain checkstyleTest

- name: Test dRAGon
run: gradle pnpmInstall pnpmLint checkstyleMain checkstyleTest test --stacktrace
run: gradle test

- name: Build dRAGon
- name: Package dRAGon
run: gradle bootJar -Pversion=$(gradle cV -q -Prelease.quiet)

- name: Upload coverage reports to Codecov
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ bin
.vscode
.DS_Store
*.class
.pnpm-store
.pnpm-store
.env.local
3 changes: 2 additions & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build
build
.env.local
5 changes: 1 addition & 4 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dependencies {

implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
implementation 'org.jobrunr:jobrunr-spring-boot-3-starter:7.2.2'
implementation 'me.paulschwarz:spring-dotenv:4.0.0'

testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'org.awaitility:awaitility:4.2.1'
Expand Down Expand Up @@ -130,10 +131,6 @@ tasks.register("bootProdRun") {
}
}

jacoco {
toolVersion = "0.8.12"
}

tasks.register('copyWebApp', Copy) {
dependsOn(':frontend:pnpmBuild')
from "$rootDir/frontend/dist"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ai.dragon.controller;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ErrorHandlerController implements ErrorController {
// We are using a SPA (Single Page Application) so we need to output the
// index.html file when an error occurs :
@RequestMapping("/error")
public @ResponseBody byte[] getImage() throws IOException {
InputStream in = getClass().getResourceAsStream("/static/index.html");
if (in == null) {
throw new IOException("index.html not found");
}
return IOUtils.toByteArray(in);
}

public String getErrorPath() {
return "/error";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ai.dragon.controller.api.app;

import java.util.List;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ai.dragon.dto.api.GenericApiResponse;
import ai.dragon.dto.api.SuccessApiResponse;
import ai.dragon.dto.api.app.auth.LoginAuthAppApiData;
import ai.dragon.dto.api.app.auth.UserInfoAuthAppApiData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/api/app/auth")
@Tag(name = "Authentication", description = "Authentication API Endpoints")
public class AuthAppApiController {
@PostMapping("/login")
@Operation(summary = "Login", description = "Login to the application.")
public GenericApiResponse login() {
return SuccessApiResponse.builder().data(LoginAuthAppApiData
.builder()
.token("TOKEN_WILL_BE_HERE")
.refreshToken("REFRESH_TOKEN_WILL_BE_HERE")
.build())
.build();
}

@GetMapping("/getUserInfo")
@Operation(summary = "Get User Info", description = "Get user info.")
public GenericApiResponse getUserInfo() {
return SuccessApiResponse.builder().data(UserInfoAuthAppApiData
.builder()
.userId("TODO")
.userName("dRAGon")
.roles(List.of("R_SUPER"))
.build())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ai.dragon.controller.api.app;

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

import ai.dragon.dto.api.GenericApiResponse;
import ai.dragon.dto.api.SuccessApiResponse;
import ai.dragon.dto.api.app.dashboard.NumbersDashboardAppApiData;
import ai.dragon.repository.DocumentRepository;
import ai.dragon.repository.FarmRepository;
import ai.dragon.repository.SiloRepository;
import ai.dragon.service.SystemMonitoringService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/api/app/dashboard")
@Tag(name = "Operations Center", description = "Dashboard API Endpoints")
public class DashboardAppApiController {
@Autowired
private SiloRepository siloRepository;

@Autowired
private FarmRepository farmRepository;

@Autowired
private DocumentRepository documentRepository;

@Autowired
private SystemMonitoringService systemMonitoringService;

@GetMapping("/numbers")
@Operation(summary = "Get Dashboard main numbers", description = "Returns the main numbers of the dashboard.")
public GenericApiResponse numbers() {
return SuccessApiResponse.builder().data(NumbersDashboardAppApiData
.builder()
.silos(siloRepository.countAll())
.farms(farmRepository.countAll())
.documents(documentRepository.countAll())
.systemLoadAverage(systemMonitoringService.getSystemLoadAverage())
.availableProcessors(systemMonitoringService.getAvailableProcessors())
.arch(systemMonitoringService.getArch())
.usedMemory(systemMonitoringService.getUsedMemory())
.totalMemory(systemMonitoringService.getTotalMemory())
.freeMemory(systemMonitoringService.getFreeMemory())
.usedMemoryPercentage(systemMonitoringService.getUsedMemoryPercentage())
.freeMemoryPercentage(systemMonitoringService.getFreeMemoryPercentage())
.uptime(systemMonitoringService.getUptime())
.heapMemoryUsage(systemMonitoringService.getHeapMemoryUsage())
.heapMemoryUsagePercentage(systemMonitoringService.getHeapMemoryUsagePercentage())
.nonHeapMemoryUsage(systemMonitoringService.getNonHeapMemoryUsage())
.heapMemoryMax(systemMonitoringService.getHeapMemoryMax())
.heapMemoryCommitted(systemMonitoringService.getHeapMemoryCommitted())
.nonHeapMemoryCommitted(systemMonitoringService.getNonHeapMemoryCommitted())
.heapMemoryInit(systemMonitoringService.getHeapMemoryInit())
.nonHeapMemoryInit(systemMonitoringService.getNonHeapMemoryInit())
.build())
.build();
}
}
5 changes: 5 additions & 0 deletions backend/src/main/java/ai/dragon/dto/api/GenericApiData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ai.dragon.dto.api;

public interface GenericApiData {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ai.dragon.dto.api;

public interface GenericApiResponse {
public GenericApiData getData();
public String getCode();
public String getMsg();
}
17 changes: 17 additions & 0 deletions backend/src/main/java/ai/dragon/dto/api/SuccessApiResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ai.dragon.dto.api;

import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class SuccessApiResponse implements GenericApiResponse {
@Builder.Default
private GenericApiData data = null;

@Builder.Default
private String code = "0000";

@Builder.Default
private String msg = "OK";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ai.dragon.dto.api.app.auth;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class LoginAuthAppApiData implements GenericApiData {
private String token;
private String refreshToken;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ai.dragon.dto.api.app.auth;

import java.util.List;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class UserInfoAuthAppApiData implements GenericApiData {
private String userId;
private String userName;
private List<String> roles;
private List<String> buttons;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ai.dragon.dto.api.app.dashboard;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class NumbersDashboardAppApiData implements GenericApiData {
private Long silos;
private Long farms;
private Long documents;
private Double systemLoadAverage;
private Integer availableProcessors;
private String arch;
private Long usedMemory;
private Long totalMemory;
private Long freeMemory;
private Long usedMemoryPercentage;
private Long freeMemoryPercentage;
private Long uptime;
private Long heapMemoryUsage;
private Long heapMemoryUsagePercentage;
private Long nonHeapMemoryUsage;
private Long heapMemoryMax;
private Long heapMemoryCommitted;
private Long nonHeapMemoryCommitted;
private Long heapMemoryInit;
private Long nonHeapMemoryInit;
}
15 changes: 11 additions & 4 deletions backend/src/main/java/ai/dragon/service/RaagService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
import ai.dragon.dto.openai.completion.OpenAiRequest;
import ai.dragon.dto.openai.model.OpenAiModel;
import ai.dragon.entity.FarmEntity;
import ai.dragon.entity.SiloEntity;
import ai.dragon.properties.embedding.LanguageModelSettings;
import ai.dragon.properties.raag.RetrievalAugmentorSettings;
import ai.dragon.repository.FarmRepository;
import ai.dragon.repository.SiloRepository;
import ai.dragon.util.KVSettingUtil;
import ai.dragon.util.ai.AiAssistant;
import ai.dragon.util.spel.MetadataHeaderFilterExpressionParserUtil;
Expand Down Expand Up @@ -60,6 +62,9 @@ public class RaagService {
@Autowired
private FarmRepository farmRepository;

@Autowired
private SiloRepository siloRepository;

@Autowired
private ChatMessageService chatMessageService;

Expand Down Expand Up @@ -106,18 +111,20 @@ public List<ContentRetriever> buildRetrieverList(FarmEntity farm, HttpServletReq
}
farm.getSilos().forEach(siloUuid -> {
try {
this.buildRetriever(siloUuid, servletRequest).ifPresent(retrievers::add);
SiloEntity silo = siloRepository.getByUuid(siloUuid).orElseThrow();
this.buildSiloRetriever(silo, servletRequest).ifPresent(retrievers::add);
} catch (Exception ex) {
logger.error("Error building Content Retriever for Silo '{}'", siloUuid, ex);
}
});
// TODO Granaries
return retrievers;
}

public Optional<ContentRetriever> buildRetriever(UUID siloUuid, HttpServletRequest servletRequest)
public Optional<ContentRetriever> buildSiloRetriever(SiloEntity silo, HttpServletRequest servletRequest)
throws Exception {
EmbeddingModel embeddingModel = embeddingModelService.modelForSilo(siloUuid);
EmbeddingStore<TextSegment> embeddingStore = embeddingStoreService.retrieveEmbeddingStore(siloUuid);
EmbeddingModel embeddingModel = embeddingModelService.modelForSilo(silo.getUuid());
EmbeddingStore<TextSegment> embeddingStore = embeddingStoreService.retrieveEmbeddingStore(silo.getUuid());
return Optional.of(EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
Expand Down
Loading