type) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
index 5ca715a2f688..5efb75e76ea0 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
@@ -49,13 +49,7 @@ public abstract class IrisSettings extends DomainObject {
public abstract void setIrisLectureIngestionSettings(IrisLectureIngestionSubSettings irisLectureIngestionSettings);
- public abstract IrisHestiaSubSettings getIrisHestiaSettings();
-
- public abstract void setIrisHestiaSettings(IrisHestiaSubSettings irisHestiaSettings);
-
public abstract IrisCompetencyGenerationSubSettings getIrisCompetencyGenerationSettings();
public abstract void setIrisCompetencyGenerationSettings(IrisCompetencyGenerationSubSettings irisCompetencyGenerationSubSettings);
-
- public abstract boolean isValid();
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
index 16588cf448a5..5288c247e891 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
@@ -26,7 +26,6 @@
* IrisSubSettings is an abstract super class for the specific sub settings types.
* Sub Settings are settings for a specific feature of Iris.
* {@link IrisChatSubSettings} are used to specify settings for the chat feature.
- * {@link IrisHestiaSubSettings} are used to specify settings for the Hestia integration.
* {@link IrisCompetencyGenerationSubSettings} are used to specify settings for the competency generation feature.
*
* Also see {@link de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService} for more information.
@@ -41,7 +40,6 @@
@JsonSubTypes({
@JsonSubTypes.Type(value = IrisChatSubSettings.class, name = "chat"),
@JsonSubTypes.Type(value = IrisLectureIngestionSubSettings.class, name = "lecture-ingestion"),
- @JsonSubTypes.Type(value = IrisHestiaSubSettings.class, name = "hestia"),
@JsonSubTypes.Type(value = IrisCompetencyGenerationSubSettings.class, name = "competency-generation")
})
// @formatter:on
@@ -51,13 +49,12 @@ public abstract class IrisSubSettings extends DomainObject {
@Column(name = "enabled")
private boolean enabled = false;
- @Column(name = "allowed_models")
- @Convert(converter = IrisModelListConverter.class)
- private SortedSet allowedModels = new TreeSet<>();
+ @Column(name = "allowed_variants", nullable = false)
+ @Convert(converter = IrisListConverter.class)
+ private SortedSet allowedVariants = new TreeSet<>();
- @Nullable
- @Column(name = "preferred_model")
- private String preferredModel;
+ @Column(name = "selected_variant", nullable = false)
+ private String selectedVariant;
public boolean isEnabled() {
return enabled;
@@ -67,20 +64,20 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
- public SortedSet getAllowedModels() {
- return allowedModels;
+ public SortedSet getAllowedVariants() {
+ return allowedVariants;
}
- public void setAllowedModels(SortedSet allowedModels) {
- this.allowedModels = allowedModels;
+ public void setAllowedVariants(SortedSet allowedVariants) {
+ this.allowedVariants = allowedVariants;
}
@Nullable
- public String getPreferredModel() {
- return preferredModel;
+ public String getSelectedVariant() {
+ return selectedVariant;
}
- public void setPreferredModel(@Nullable String preferredModel) {
- this.preferredModel = preferredModel;
+ public void setSelectedVariant(@Nullable String selectedVariant) {
+ this.selectedVariant = selectedVariant;
}
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
index d938134f4555..2a8270d420bc 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
@@ -1,5 +1,5 @@
package de.tum.cit.aet.artemis.iris.domain.settings;
public enum IrisSubSettingsType {
- CHAT, HESTIA, COMPETENCY_GENERATION, LECTURE_INGESTION
+ CHAT, COMPETENCY_GENERATION, LECTURE_INGESTION
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
index 72d8e599ed70..c5589e824507 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
@@ -6,10 +6,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedChatSubSettingsDTO(boolean enabled, Integer rateLimit, Integer rateLimitTimeframeHours, @Nullable Set allowedModels,
- @Nullable String preferredModel, @Nullable IrisTemplate template) {
+public record IrisCombinedChatSubSettingsDTO(boolean enabled, Integer rateLimit, Integer rateLimitTimeframeHours, @Nullable Set allowedVariants,
+ @Nullable String selectedVariant) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
index 18ffcbc17b50..414b422e0f64 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
@@ -6,9 +6,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedCompetencyGenerationSubSettingsDTO(boolean enabled, @Nullable Set allowedModels, @Nullable String preferredModel,
- @Nullable IrisTemplate template) {
+public record IrisCombinedCompetencyGenerationSubSettingsDTO(boolean enabled, @Nullable Set allowedVariants, @Nullable String selectedVariant) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java
deleted file mode 100644
index c70ce4825a92..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.tum.cit.aet.artemis.iris.dto;
-
-import java.util.Set;
-
-import jakarta.annotation.Nullable;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedHestiaSubSettingsDTO(boolean enabled, @Nullable Set allowedModels, @Nullable String preferredModel, @Nullable IrisTemplate template) {
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
index 9353757c782e..355b05ae551a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
@@ -4,5 +4,5 @@
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record IrisCombinedSettingsDTO(IrisCombinedChatSubSettingsDTO irisChatSettings, IrisCombinedLectureIngestionSubSettingsDTO irisLectureIngestionSettings,
- IrisCombinedHestiaSubSettingsDTO irisHestiaSettings, IrisCombinedCompetencyGenerationSubSettingsDTO irisCompetencyGenerationSettings) {
+ IrisCombinedCompetencyGenerationSubSettingsDTO irisCompetencyGenerationSettings) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java
deleted file mode 100644
index 22a14bd98bd7..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package de.tum.cit.aet.artemis.iris.repository;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.util.List;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-
-/**
- * Repository interface for managing {@link IrisHestiaSession} entities.
- * Provides custom queries for finding hestia sessions based on different criteria.
- */
-@Repository
-@Profile(PROFILE_IRIS)
-public interface IrisHestiaSessionRepository extends ArtemisJpaRepository {
-
- /**
- * Finds a list of {@link IrisHestiaSession} based on the exercise and user IDs.
- *
- * @param codeHintId The ID of the code hint.
- * @return A list of hestia sessions sorted by creation date in descending order.
- */
- List findByCodeHintIdOrderByCreationDateDesc(Long codeHintId);
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
index 8c4ffd56068e..4dd037d54c77 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
@@ -29,7 +29,6 @@ public interface IrisSettingsRepository extends ArtemisJpaRepository findAllGlobalSettings();
@@ -43,7 +42,6 @@ default IrisGlobalSettings findGlobalSettingsElseThrow() {
FROM IrisCourseSettings irisSettings
LEFT JOIN FETCH irisSettings.irisChatSettings
LEFT JOIN FETCH irisSettings.irisLectureIngestionSettings
- LEFT JOIN FETCH irisSettings.irisHestiaSettings
LEFT JOIN FETCH irisSettings.irisCompetencyGenerationSettings
WHERE irisSettings.course.id = :courseId
""")
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java
deleted file mode 100644
index 2b1a930d7aef..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.tum.cit.aet.artemis.iris.repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-/**
- * Spring Data repository for the IrisTemplate entity.
- */
-public interface IrisTemplateRepository extends ArtemisJpaRepository {
-
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java
deleted file mode 100644
index 2a4757596bf1..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package de.tum.cit.aet.artemis.iris.service;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.core.io.Resource;
-import org.springframework.stereotype.Service;
-
-import de.tum.cit.aet.artemis.core.service.ResourceLoaderService;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-/**
- * Service that loads default Iris templates from the resources/templates/iris folder.
- */
-@Profile(PROFILE_IRIS)
-@Service
-public class IrisDefaultTemplateService {
-
- private static final Logger log = LoggerFactory.getLogger(IrisDefaultTemplateService.class);
-
- private final ResourceLoaderService resourceLoaderService;
-
- public IrisDefaultTemplateService(ResourceLoaderService resourceLoaderService) {
- this.resourceLoaderService = resourceLoaderService;
- }
-
- /**
- * Loads the default Iris template with the given file name.
- * For example, "chat.hbs" will load the template from "resources/templates/iris/chat.hbs".
- *
- * @param templateFileName The file name of the template to load.
- * @return The loaded Iris template, or an empty template if an IO error occurred.
- */
- public IrisTemplate load(String templateFileName) {
- Path filePath = Path.of("templates", "iris", templateFileName);
- Resource resource = resourceLoaderService.getResource(filePath);
- try {
- String fileContent = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
- return new IrisTemplate(fileContent);
- }
- catch (IOException e) {
- log.error("Error while loading Iris template from file: {}", filePath, e);
- return new IrisTemplate("");
- }
- }
-
- /**
- * Loads the global template version from the "resources/templates/iris/template-version.txt" file.
- *
- * @return an Optional containing the version loaded from the file, or an empty Optional if there was an error.
- */
- public Optional loadGlobalTemplateVersion() {
- Path filePath = Path.of("templates", "iris", "template-version.txt");
- Resource resource = resourceLoaderService.getResource(filePath);
- try {
- String fileContent = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
- int version = Integer.parseInt(fileContent.trim());
- return Optional.of(version);
- }
- catch (IOException e) {
- log.error("Error while loading global template version from file: {}", filePath, e);
- }
- catch (NumberFormatException e) {
- log.error("Content of {} was not a parseable int!", filePath, e);
- }
- return Optional.empty();
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
index 41fa1247b739..c37844d9740a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
@@ -14,12 +14,10 @@
import de.tum.cit.aet.artemis.iris.domain.message.IrisMessage;
import de.tum.cit.aet.artemis.iris.domain.session.IrisCourseChatSession;
import de.tum.cit.aet.artemis.iris.domain.session.IrisExerciseChatSession;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
import de.tum.cit.aet.artemis.iris.domain.session.IrisSession;
import de.tum.cit.aet.artemis.iris.service.session.IrisChatBasedFeatureInterface;
import de.tum.cit.aet.artemis.iris.service.session.IrisCourseChatSessionService;
import de.tum.cit.aet.artemis.iris.service.session.IrisExerciseChatSessionService;
-import de.tum.cit.aet.artemis.iris.service.session.IrisHestiaSessionService;
import de.tum.cit.aet.artemis.iris.service.session.IrisRateLimitedFeatureInterface;
import de.tum.cit.aet.artemis.iris.service.session.IrisSubFeatureInterface;
@@ -36,14 +34,11 @@ public class IrisSessionService {
private final IrisCourseChatSessionService irisCourseChatSessionService;
- private final IrisHestiaSessionService irisHestiaSessionService;
-
public IrisSessionService(UserRepository userRepository, IrisExerciseChatSessionService irisExerciseChatSessionService,
- IrisCourseChatSessionService irisCourseChatSessionService, IrisHestiaSessionService irisHestiaSessionService) {
+ IrisCourseChatSessionService irisCourseChatSessionService) {
this.userRepository = userRepository;
this.irisExerciseChatSessionService = irisExerciseChatSessionService;
this.irisCourseChatSessionService = irisCourseChatSessionService;
- this.irisHestiaSessionService = irisHestiaSessionService;
}
/**
@@ -138,7 +133,6 @@ private IrisSubFeatureWrapper getIrisSessionSubServic
return switch (session) {
case IrisExerciseChatSession chatSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisExerciseChatSessionService, chatSession);
case IrisCourseChatSession courseChatSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisCourseChatSessionService, courseChatSession);
- case IrisHestiaSession hestiaSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisHestiaSessionService, hestiaSession);
case null, default -> throw new BadRequestException("Unknown Iris session type " + session.getClass().getSimpleName());
};
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
index 785fc59b9ed7..f41de6b6c97d 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
@@ -19,10 +19,11 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.exception.IrisException;
import de.tum.cit.aet.artemis.iris.exception.IrisForbiddenException;
import de.tum.cit.aet.artemis.iris.exception.IrisInternalPyrisErrorException;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.lectureingestionwebhook.PyrisWebhookLectureIngestionExecutionDTO;
import de.tum.cit.aet.artemis.iris.web.open.PublicPyrisStatusUpdateResource;
@@ -50,13 +51,14 @@ public PyrisConnectorService(@Qualifier("pyrisRestTemplate") RestTemplate restTe
}
/**
- * Requests all available models from Pyris
+ * Requests all available variants from Pyris for a feature
*
- * @return A list of available Models as IrisModelDTO
+ * @param feature The feature to get the variants for
+ * @return A list of available Models as IrisVariantDTO
*/
- public List getOfferedModels() throws PyrisConnectorException {
+ public List getOfferedVariants(IrisSubSettingsType feature) throws PyrisConnectorException {
try {
- var response = restTemplate.getForEntity(pyrisUrl + "/api/v1/models", PyrisModelDTO[].class);
+ var response = restTemplate.getForEntity(pyrisUrl + "/api/v1/pipelines/" + feature.name() + "/variants", PyrisVariantDTO[].class);
if (!response.getStatusCode().is2xxSuccessful() || !response.hasBody()) {
throw new PyrisConnectorException("Could not fetch offered models");
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
similarity index 67%
rename from src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java
rename to src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
index 705fada64870..ccfbecf7ee9a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
@@ -3,5 +3,5 @@
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record PyrisModelDTO(String id, String name, String description) {
+public record PyrisVariantDTO(String id, String name, String description) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
index a2c404b13103..6dea7a728ca6 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
@@ -116,7 +116,8 @@ public void checkRateLimit(User user) {
*/
@Override
public void requestAndHandleResponse(IrisCourseChatSession session) {
- requestAndHandleResponse(session, "default", null);
+ var variant = irisSettingsService.getCombinedIrisSettingsFor(session.getCourse(), false).irisChatSettings().selectedVariant();
+ requestAndHandleResponse(session, variant, null);
}
private void requestAndHandleResponse(IrisCourseChatSession session, String variant, CompetencyJol competencyJol) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
index cec0a9322134..47e0da357ea9 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
@@ -146,9 +146,8 @@ public void requestAndHandleResponse(IrisExerciseChatSession session) {
var exercise = programmingExerciseRepository.findByIdWithTemplateAndSolutionParticipationElseThrow(chatSession.getExercise().getId());
var latestSubmission = getLatestSubmissionIfExists(exercise, chatSession.getUser());
- // TODO: Use settings to determine the variant
- // var irisSettings = irisSettingsService.getCombinedIrisSettingsFor(chatSession.getExercise(), false);
- pyrisPipelineService.executeExerciseChatPipeline("default", latestSubmission, exercise, chatSession);
+ var variant = irisSettingsService.getCombinedIrisSettingsFor(session.getExercise(), false).irisChatSettings().selectedVariant();
+ pyrisPipelineService.executeExerciseChatPipeline(variant, latestSubmission, exercise, chatSession);
}
private Optional getLatestSubmissionIfExists(ProgrammingExercise exercise, User user) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java
deleted file mode 100644
index 6762b6d23d43..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package de.tum.cit.aet.artemis.iris.service.session;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.time.ZonedDateTime;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Service;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.core.domain.User;
-import de.tum.cit.aet.artemis.core.security.Role;
-import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
-import de.tum.cit.aet.artemis.iris.repository.IrisHestiaSessionRepository;
-import de.tum.cit.aet.artemis.iris.repository.IrisSessionRepository;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
-import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
-import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
-
-/**
- * Service to handle the Hestia integration of Iris.
- */
-@Service
-@Profile(PROFILE_IRIS)
-public class IrisHestiaSessionService implements IrisButtonBasedFeatureInterface {
-
- private static final Logger log = LoggerFactory.getLogger(IrisHestiaSessionService.class);
-
- private final IrisSettingsService irisSettingsService;
-
- private final AuthorizationCheckService authCheckService;
-
- private final IrisSessionRepository irisSessionRepository;
-
- private final IrisHestiaSessionRepository irisHestiaSessionRepository;
-
- public IrisHestiaSessionService(PyrisConnectorService pyrisConnectorService, IrisSettingsService irisSettingsService, AuthorizationCheckService authCheckService,
- IrisSessionRepository irisSessionRepository, IrisHestiaSessionRepository irisHestiaSessionRepository) {
- this.irisSettingsService = irisSettingsService;
- this.authCheckService = authCheckService;
- this.irisSessionRepository = irisSessionRepository;
- this.irisHestiaSessionRepository = irisHestiaSessionRepository;
- }
-
- /**
- * Creates a new Iris session for the given code hint.
- * If there is already an existing session for the code hint from the last hour, it will be returned instead.
- *
- * @param codeHint The code hint to create the session for
- * @return The Iris session for the code hint
- */
- public IrisHestiaSession getOrCreateSession(CodeHint codeHint) {
- var existingSessions = irisHestiaSessionRepository.findByCodeHintIdOrderByCreationDateDesc(codeHint.getId());
- // Return the newest session if there is one and it is not older than 1 hour
- if (!existingSessions.isEmpty() && existingSessions.getFirst().getCreationDate().plusHours(1).isAfter(ZonedDateTime.now())) {
- checkHasAccessTo(null, existingSessions.getFirst());
- return existingSessions.getFirst();
- }
-
- // Otherwise create a new session
- var irisSession = new IrisHestiaSession();
- irisSession.setCodeHint(codeHint);
- checkHasAccessTo(null, irisSession);
- irisSession = irisSessionRepository.save(irisSession);
- return irisSession;
- }
-
- @JsonInclude(JsonInclude.Include.NON_EMPTY)
- record HestiaDTO(CodeHint codeHint, IrisHestiaSession session, ProgrammingExercise exercise) {
- }
-
- /**
- * Generates the description and content for a code hint.
- * It does not directly save the code hint, but instead returns it with the generated description and content.
- * This way the instructor can still modify the code hint before saving it or discard the changes.
- *
- * @param session The Iris session to generate the description for
- * @return The code hint with the generated description and content
- */
- @Override
- public CodeHint executeRequest(IrisHestiaSession session) {
- // TODO: Re-add in a future PR. Remember to reenable the test cases!
- return null;
- }
-
- /**
- * Checks if the user has at least the given role for the exercise of the code hint.
- *
- * @param user The user to check the access for
- * @param session The Iris session to check the access for
- */
- @Override
- public void checkHasAccessTo(User user, IrisHestiaSession session) {
- var exercise = session.getCodeHint().getExercise();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, exercise, user);
- }
-
- /**
- * Not supported for Iris Hestia sessions.
- *
- * @param session The session to get a message for
- */
- @Override
- public void checkIsFeatureActivatedFor(IrisHestiaSession session) {
- irisSettingsService.isEnabledForElseThrow(IrisSubSettingsType.HESTIA, session.getCodeHint().getExercise());
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
index 39bb14ff31cd..bf9d4a8d35d3 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
@@ -9,7 +9,8 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
-import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.function.Supplier;
import org.springframework.boot.context.event.ApplicationReadyEvent;
@@ -24,20 +25,17 @@
import de.tum.cit.aet.artemis.core.exception.ConflictException;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.exercise.domain.Exercise;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisChatSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisGlobalSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedSettingsDTO;
import de.tum.cit.aet.artemis.iris.repository.IrisSettingsRepository;
-import de.tum.cit.aet.artemis.iris.service.IrisDefaultTemplateService;
/**
* Service for managing {@link IrisSettings}.
@@ -54,34 +52,14 @@ public class IrisSettingsService {
private final IrisSubSettingsService irisSubSettingsService;
- private final IrisDefaultTemplateService irisDefaultTemplateService;
-
private final AuthorizationCheckService authCheckService;
- public IrisSettingsService(IrisSettingsRepository irisSettingsRepository, IrisSubSettingsService irisSubSettingsService, IrisDefaultTemplateService irisDefaultTemplateService,
- AuthorizationCheckService authCheckService) {
+ public IrisSettingsService(IrisSettingsRepository irisSettingsRepository, IrisSubSettingsService irisSubSettingsService, AuthorizationCheckService authCheckService) {
this.irisSettingsRepository = irisSettingsRepository;
this.irisSubSettingsService = irisSubSettingsService;
- this.irisDefaultTemplateService = irisDefaultTemplateService;
this.authCheckService = authCheckService;
}
- private Optional loadGlobalTemplateVersion() {
- return irisDefaultTemplateService.loadGlobalTemplateVersion();
- }
-
- private IrisTemplate loadDefaultChatTemplate() {
- return irisDefaultTemplateService.load("chat.hbs");
- }
-
- private IrisTemplate loadDefaultHestiaTemplate() {
- return irisDefaultTemplateService.load("hestia.hbs");
- }
-
- private IrisTemplate loadDefaultCompetencyGenerationTemplate() {
- return irisDefaultTemplateService.load("competency-generation.hbs");
- }
-
/**
* Hooks into the {@link ApplicationReadyEvent} and creates or updates the global IrisSettings object on startup.
*
@@ -98,10 +76,6 @@ public void execute(ApplicationReadyEvent event) throws Exception {
if (allGlobalSettings.size() > 1) {
var maxIdSettings = allGlobalSettings.stream().max(Comparator.comparingLong(IrisSettings::getId)).orElseThrow();
allGlobalSettings.stream().filter(settings -> !Objects.equals(settings.getId(), maxIdSettings.getId())).forEach(irisSettingsRepository::delete);
- autoUpdateGlobalSettings(maxIdSettings);
- }
- else {
- autoUpdateGlobalSettings(allGlobalSettings.stream().findFirst().get());
}
}
@@ -110,46 +84,20 @@ public void execute(ApplicationReadyEvent event) throws Exception {
*/
private void createInitialGlobalSettings() {
var settings = new IrisGlobalSettings();
- settings.setCurrentVersion(loadGlobalTemplateVersion().orElse(0));
initializeIrisChatSettings(settings);
initializeIrisLectureIngestionSettings(settings);
- initializeIrisHestiaSettings(settings);
initializeIrisCompetencyGenerationSettings(settings);
irisSettingsRepository.save(settings);
}
- /**
- * Auto updates the global IrisSettings object if the current version is outdated.
- *
- * @param settings The global IrisSettings object to update
- */
- private void autoUpdateGlobalSettings(IrisGlobalSettings settings) {
- Optional globalVersion = loadGlobalTemplateVersion();
- if (globalVersion.isEmpty() || settings.getCurrentVersion() < globalVersion.get()) {
- if (settings.isEnableAutoUpdateChat() || settings.getIrisChatSettings() == null) {
- initializeIrisChatSettings(settings);
- }
- if (settings.isEnableAutoUpdateLectureIngestion() || settings.getIrisLectureIngestionSettings() == null) {
- initializeIrisLectureIngestionSettings(settings);
- }
- if (settings.isEnableAutoUpdateHestia() || settings.getIrisHestiaSettings() == null) {
- initializeIrisHestiaSettings(settings);
- }
- if (settings.isEnableAutoUpdateCompetencyGeneration() || settings.getIrisCompetencyGenerationSettings() == null) {
- initializeIrisCompetencyGenerationSettings(settings);
- }
-
- globalVersion.ifPresent(settings::setCurrentVersion);
- saveIrisSettings(settings);
- }
- }
-
private static T initializeSettings(T settings, Supplier constructor) {
if (settings == null) {
settings = constructor.get();
settings.setEnabled(false);
+ settings.setAllowedVariants(new TreeSet<>(Set.of("default")));
+ settings.setSelectedVariant("default");
}
return settings;
}
@@ -157,7 +105,6 @@ private static T initializeSettings(T settings, Supp
private void initializeIrisChatSettings(IrisGlobalSettings settings) {
var irisChatSettings = settings.getIrisChatSettings();
irisChatSettings = initializeSettings(irisChatSettings, IrisChatSubSettings::new);
- irisChatSettings.setTemplate(loadDefaultChatTemplate());
settings.setIrisChatSettings(irisChatSettings);
}
@@ -167,17 +114,9 @@ private void initializeIrisLectureIngestionSettings(IrisGlobalSettings settings)
settings.setIrisLectureIngestionSettings(irisLectureIngestionSettings);
}
- private void initializeIrisHestiaSettings(IrisGlobalSettings settings) {
- var irisHestiaSettings = settings.getIrisHestiaSettings();
- irisHestiaSettings = initializeSettings(irisHestiaSettings, IrisHestiaSubSettings::new);
- irisHestiaSettings.setTemplate(loadDefaultHestiaTemplate());
- settings.setIrisHestiaSettings(irisHestiaSettings);
- }
-
private void initializeIrisCompetencyGenerationSettings(IrisGlobalSettings settings) {
var irisCompetencyGenerationSettings = settings.getIrisCompetencyGenerationSettings();
irisCompetencyGenerationSettings = initializeSettings(irisCompetencyGenerationSettings, IrisCompetencyGenerationSubSettings::new);
- irisCompetencyGenerationSettings.setTemplate(loadDefaultCompetencyGenerationTemplate());
settings.setIrisCompetencyGenerationSettings(irisCompetencyGenerationSettings);
}
@@ -214,9 +153,6 @@ private T saveNewIrisSettings(T settings) {
if (settings instanceof IrisGlobalSettings) {
throw new BadRequestAlertException("You can not create new global settings", "IrisSettings", "notGlobal");
}
- if (!settings.isValid()) {
- throw new BadRequestAlertException("New Iris settings are not valid", "IrisSettings", "notValid");
- }
if (settings instanceof IrisCourseSettings courseSettings && irisSettingsRepository.findCourseSettings(courseSettings.getCourse().getId()).isPresent()) {
throw new ConflictException("Iris settings for this course already exist", "IrisSettings", "alreadyExists");
}
@@ -241,9 +177,6 @@ private T updateIrisSettings(long existingSettingsId, T
if (!Objects.equals(existingSettingsId, settingsUpdate.getId())) {
throw new ConflictException("Existing Iris settings ID does not match update ID", "IrisSettings", "idMismatch");
}
- if (!settingsUpdate.isValid()) {
- throw new BadRequestAlertException("Updated Iris settings are not valid", "IrisSettings", "notValid");
- }
var existingSettings = irisSettingsRepository.findByIdElseThrow(existingSettingsId);
@@ -269,17 +202,9 @@ else if (existingSettings instanceof IrisExerciseSettings exerciseSettings && se
* @return The updated global Iris settings
*/
private IrisGlobalSettings updateGlobalSettings(IrisGlobalSettings existingSettings, IrisGlobalSettings settingsUpdate) {
- existingSettings.setCurrentVersion(settingsUpdate.getCurrentVersion());
-
- existingSettings.setEnableAutoUpdateChat(settingsUpdate.isEnableAutoUpdateChat());
- existingSettings.setEnableAutoUpdateLectureIngestion(settingsUpdate.isEnableAutoUpdateLectureIngestion());
- existingSettings.setEnableAutoUpdateHestia(settingsUpdate.isEnableAutoUpdateHestia());
- existingSettings.setEnableAutoUpdateCompetencyGeneration(settingsUpdate.isEnableAutoUpdateCompetencyGeneration());
-
existingSettings.setIrisLectureIngestionSettings(
irisSubSettingsService.update(existingSettings.getIrisLectureIngestionSettings(), settingsUpdate.getIrisLectureIngestionSettings(), null, GLOBAL));
existingSettings.setIrisChatSettings(irisSubSettingsService.update(existingSettings.getIrisChatSettings(), settingsUpdate.getIrisChatSettings(), null, GLOBAL));
- existingSettings.setIrisHestiaSettings(irisSubSettingsService.update(existingSettings.getIrisHestiaSettings(), settingsUpdate.getIrisHestiaSettings(), null, GLOBAL));
existingSettings.setIrisCompetencyGenerationSettings(
irisSubSettingsService.update(existingSettings.getIrisCompetencyGenerationSettings(), settingsUpdate.getIrisCompetencyGenerationSettings(), null, GLOBAL));
@@ -299,8 +224,6 @@ private IrisCourseSettings updateCourseSettings(IrisCourseSettings existingSetti
irisSubSettingsService.update(existingSettings.getIrisChatSettings(), settingsUpdate.getIrisChatSettings(), parentSettings.irisChatSettings(), COURSE));
existingSettings.setIrisLectureIngestionSettings(irisSubSettingsService.update(existingSettings.getIrisLectureIngestionSettings(),
settingsUpdate.getIrisLectureIngestionSettings(), parentSettings.irisLectureIngestionSettings(), COURSE));
- existingSettings.setIrisHestiaSettings(
- irisSubSettingsService.update(existingSettings.getIrisHestiaSettings(), settingsUpdate.getIrisHestiaSettings(), parentSettings.irisHestiaSettings(), COURSE));
existingSettings.setIrisCompetencyGenerationSettings(irisSubSettingsService.update(existingSettings.getIrisCompetencyGenerationSettings(),
settingsUpdate.getIrisCompetencyGenerationSettings(), parentSettings.irisCompetencyGenerationSettings(), COURSE));
@@ -382,8 +305,7 @@ public IrisCombinedSettingsDTO getCombinedIrisGlobalSettings() {
settingsList.add(getGlobalSettings());
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, false),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, false), irisSubSettingsService.combineHestiaSettings(settingsList, false),
- irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, false));
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, false), irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, false));
}
/**
@@ -402,7 +324,7 @@ public IrisCombinedSettingsDTO getCombinedIrisSettingsFor(Course course, boolean
settingsList.add(irisSettingsRepository.findCourseSettings(course.getId()).orElse(null));
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, minimal),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal), irisSubSettingsService.combineHestiaSettings(settingsList, minimal),
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal),
irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, minimal));
}
@@ -423,7 +345,7 @@ public IrisCombinedSettingsDTO getCombinedIrisSettingsFor(Exercise exercise, boo
settingsList.add(getRawIrisSettingsFor(exercise));
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, minimal),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal), irisSubSettingsService.combineHestiaSettings(settingsList, minimal),
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal),
irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, minimal));
}
@@ -450,7 +372,6 @@ public IrisCourseSettings getDefaultSettingsFor(Course course) {
settings.setCourse(course);
settings.setIrisLectureIngestionSettings(new IrisLectureIngestionSubSettings());
settings.setIrisChatSettings(new IrisChatSubSettings());
- settings.setIrisHestiaSettings(new IrisHestiaSubSettings());
settings.setIrisCompetencyGenerationSettings(new IrisCompetencyGenerationSubSettings());
return settings;
}
@@ -523,7 +444,6 @@ public void deleteSettingsFor(Exercise exercise) {
private boolean isFeatureEnabledInSettings(IrisCombinedSettingsDTO settings, IrisSubSettingsType type) {
return switch (type) {
case CHAT -> settings.irisChatSettings().enabled();
- case HESTIA -> settings.irisHestiaSettings().enabled();
case COMPETENCY_GENERATION -> settings.irisCompetencyGenerationSettings().enabled();
case LECTURE_INGESTION -> settings.irisLectureIngestionSettings().enabled();
};
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
index dfd555bb59c5..5a3c20b4c810 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
@@ -15,18 +15,15 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisChatSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettingsType;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedChatSubSettingsDTO;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedCompetencyGenerationSubSettingsDTO;
-import de.tum.cit.aet.artemis.iris.dto.IrisCombinedHestiaSubSettingsDTO;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedLectureIngestionSubSettingsDTO;
/**
@@ -76,10 +73,9 @@ public IrisChatSubSettings update(IrisChatSubSettings currentSettings, IrisChatS
currentSettings.setRateLimit(newSettings.getRateLimit());
currentSettings.setRateLimitTimeframeHours(newSettings.getRateLimitTimeframeHours());
}
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
+ currentSettings.setAllowedVariants(selectAllowedVariants(currentSettings.getAllowedVariants(), newSettings.getAllowedVariants()));
+ currentSettings.setSelectedVariant(validateSelectedVariant(currentSettings.getSelectedVariant(), newSettings.getSelectedVariant(), currentSettings.getAllowedVariants(),
+ parentSettings != null ? parentSettings.allowedVariants() : null));
return currentSettings;
}
@@ -114,40 +110,6 @@ public IrisLectureIngestionSubSettings update(IrisLectureIngestionSubSettings cu
return currentSettings;
}
- /**
- * Updates a Hestia sub settings object.
- * If the new settings are null, the current settings will be deleted (except if the parent settings are null == if the settings are global).
- * Special notes:
- * - If the user is not an admin the allowed models will not be updated.
- * - If the user is not an admin the preferred model will only be updated if it is included in the allowed models.
- *
- * @param currentSettings Current Hestia sub settings.
- * @param newSettings Updated Hestia sub settings.
- * @param parentSettings Parent Hestia sub settings.
- * @param settingsType Type of the settings the sub settings belong to.
- * @return Updated Hestia sub settings.
- */
- public IrisHestiaSubSettings update(IrisHestiaSubSettings currentSettings, IrisHestiaSubSettings newSettings, IrisCombinedHestiaSubSettingsDTO parentSettings,
- IrisSettingsType settingsType) {
- if (newSettings == null) {
- if (parentSettings == null) {
- throw new IllegalArgumentException("Cannot delete the Hestia settings");
- }
- return null;
- }
- if (currentSettings == null) {
- currentSettings = new IrisHestiaSubSettings();
- }
- if (settingsType == IrisSettingsType.EXERCISE || authCheckService.isAdmin()) {
- currentSettings.setEnabled(newSettings.isEnabled());
- }
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
- return currentSettings;
- }
-
/**
* Updates a Competency Generation sub settings object.
* If the new settings are null, the current settings will be deleted (except if the parent settings are null == if the settings are global).
@@ -174,11 +136,10 @@ public IrisCompetencyGenerationSubSettings update(IrisCompetencyGenerationSubSet
}
if (authCheckService.isAdmin()) {
currentSettings.setEnabled(newSettings.isEnabled());
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
+ currentSettings.setAllowedVariants(selectAllowedVariants(currentSettings.getAllowedVariants(), newSettings.getAllowedVariants()));
}
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
+ currentSettings.setSelectedVariant(validateSelectedVariant(currentSettings.getSelectedVariant(), newSettings.getSelectedVariant(), currentSettings.getAllowedVariants(),
+ parentSettings != null ? parentSettings.allowedVariants() : null));
return currentSettings;
}
@@ -187,12 +148,12 @@ public IrisCompetencyGenerationSubSettings update(IrisCompetencyGenerationSubSet
* If the user is an admin, all models are allowed.
* Otherwise, only models that are allowed by the parent settings or the current settings are allowed.
*
- * @param allowedModels The allowed models of the current settings.
- * @param updatedAllowedModels The allowed models of the updated settings.
+ * @param allowedVariants The allowed models of the current settings.
+ * @param updatedAllowedVariants The allowed models of the updated settings.
* @return The filtered allowed models.
*/
- private SortedSet selectAllowedModels(SortedSet allowedModels, SortedSet updatedAllowedModels) {
- return authCheckService.isAdmin() ? updatedAllowedModels : allowedModels;
+ private SortedSet selectAllowedVariants(SortedSet allowedVariants, SortedSet updatedAllowedVariants) {
+ return authCheckService.isAdmin() ? updatedAllowedVariants : allowedVariants;
}
/**
@@ -200,23 +161,23 @@ private SortedSet selectAllowedModels(SortedSet allowedModels, S
* If the user is an admin, all models are allowed.
* Otherwise, only models that are allowed by the current settings are allowed.
*
- * @param preferredModel The preferred model of the current settings.
- * @param newPreferredModel The preferred model of the updated settings.
- * @param allowedModels The allowed models of the current settings.
- * @param parentAllowedModels The allowed models of the parent settings.
+ * @param selectedVariant The preferred model of the current settings.
+ * @param newSelectedVariant The preferred model of the updated settings.
+ * @param allowedVariants The allowed models of the current settings.
+ * @param parentAllowedVariants The allowed models of the parent settings.
* @return The validated preferred model.
*/
- private String validatePreferredModel(String preferredModel, String newPreferredModel, Set allowedModels, Set parentAllowedModels) {
- if (newPreferredModel == null || newPreferredModel.isBlank()) {
+ private String validateSelectedVariant(String selectedVariant, String newSelectedVariant, Set allowedVariants, Set parentAllowedVariants) {
+ if (newSelectedVariant == null || newSelectedVariant.isBlank()) {
return null;
}
- var canChangePreferredModel = authCheckService.isAdmin() || (allowedModels != null && !allowedModels.isEmpty() && allowedModels.contains(newPreferredModel))
- || ((allowedModels == null || allowedModels.isEmpty()) && parentAllowedModels != null && parentAllowedModels.contains(newPreferredModel));
- if (canChangePreferredModel) {
- return newPreferredModel;
+ var canChangeSelectedVariant = authCheckService.isAdmin() || (allowedVariants != null && !allowedVariants.isEmpty() && allowedVariants.contains(newSelectedVariant))
+ || ((allowedVariants == null || allowedVariants.isEmpty()) && parentAllowedVariants != null && parentAllowedVariants.contains(newSelectedVariant));
+ if (canChangeSelectedVariant) {
+ return newSelectedVariant;
}
- return preferredModel;
+ return selectedVariant;
}
/**
@@ -231,10 +192,9 @@ private String validatePreferredModel(String preferredModel, String newPreferred
public IrisCombinedChatSubSettingsDTO combineChatSettings(ArrayList settingsList, boolean minimal) {
var enabled = getCombinedEnabled(settingsList, IrisSettings::getIrisChatSettings);
var rateLimit = getCombinedRateLimit(settingsList);
- var allowedModels = minimal ? getCombinedAllowedModels(settingsList, IrisSettings::getIrisChatSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(settingsList, IrisSettings::getIrisChatSettings) : null;
- var template = minimal ? getCombinedTemplate(settingsList, IrisSettings::getIrisChatSettings, IrisChatSubSettings::getTemplate) : null;
- return new IrisCombinedChatSubSettingsDTO(enabled, rateLimit, null, allowedModels, preferredModel, template);
+ var allowedVariants = !minimal ? getCombinedAllowedVariants(settingsList, IrisSettings::getIrisChatSettings) : null;
+ var selectedVariant = !minimal ? getCombinedSelectedVariant(settingsList, IrisSettings::getIrisChatSettings) : null;
+ return new IrisCombinedChatSubSettingsDTO(enabled, rateLimit, null, allowedVariants, selectedVariant);
}
/**
@@ -251,24 +211,6 @@ public IrisCombinedLectureIngestionSubSettingsDTO combineLectureIngestionSubSett
return new IrisCombinedLectureIngestionSubSettingsDTO(enabled);
}
- /**
- * Combines the Hestia settings of multiple {@link IrisSettings} objects.
- * If minimal is true, the returned object will only contain the enabled field.
- * The minimal version can safely be sent to students.
- *
- * @param settingsList List of {@link IrisSettings} objects to combine.
- * @param minimal Whether to return a minimal version of the combined settings.
- * @return Combined Hestia settings.
- */
- public IrisCombinedHestiaSubSettingsDTO combineHestiaSettings(ArrayList settingsList, boolean minimal) {
- var actualSettingsList = settingsList.stream().filter(settings -> !(settings instanceof IrisExerciseSettings)).toList();
- var enabled = getCombinedEnabled(actualSettingsList, IrisSettings::getIrisHestiaSettings);
- var allowedModels = minimal ? getCombinedAllowedModels(actualSettingsList, IrisSettings::getIrisHestiaSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(actualSettingsList, IrisSettings::getIrisHestiaSettings) : null;
- var template = minimal ? getCombinedTemplate(actualSettingsList, IrisSettings::getIrisHestiaSettings, IrisHestiaSubSettings::getTemplate) : null;
- return new IrisCombinedHestiaSubSettingsDTO(enabled, allowedModels, preferredModel, template);
- }
-
/**
* Combines the Competency Generation settings of multiple {@link IrisSettings} objects.
* If minimal is true, the returned object will only contain the enabled field.
@@ -281,11 +223,9 @@ public IrisCombinedHestiaSubSettingsDTO combineHestiaSettings(ArrayList settingsList, boolean minimal) {
var actualSettingsList = settingsList.stream().filter(settings -> !(settings instanceof IrisExerciseSettings)).toList();
var enabled = getCombinedEnabled(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings);
- var allowedModels = minimal ? getCombinedAllowedModels(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
- var template = minimal ? getCombinedTemplate(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings, IrisCompetencyGenerationSubSettings::getTemplate)
- : null;
- return new IrisCombinedCompetencyGenerationSubSettingsDTO(enabled, allowedModels, preferredModel, template);
+ var allowedVariants = !minimal ? getCombinedAllowedVariants(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
+ var selectedVariant = !minimal ? getCombinedSelectedVariant(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
+ return new IrisCombinedCompetencyGenerationSubSettingsDTO(enabled, allowedVariants, selectedVariant);
}
/**
@@ -322,43 +262,28 @@ private Integer getCombinedRateLimit(List settingsList) {
}
/**
- * Combines the allowedModels field of multiple {@link IrisSettings} objects.
- * Simply takes the last allowedModels.
+ * Combines the allowedVariants field of multiple {@link IrisSettings} objects.
+ * Simply takes the last allowedVariants.
*
* @param settingsList List of {@link IrisSettings} objects to combine.
* @param subSettingsFunction Function to get the sub settings from an IrisSettings object.
- * @return Combined allowedModels field.
+ * @return Combined allowedVariants field.
*/
- private Set getCombinedAllowedModels(List settingsList, Function subSettingsFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getAllowedModels).filter(Objects::nonNull)
+ private Set getCombinedAllowedVariants(List settingsList, Function subSettingsFunction) {
+ return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getAllowedVariants).filter(Objects::nonNull)
.filter(models -> !models.isEmpty()).reduce((first, second) -> second).orElse(new TreeSet<>());
}
/**
- * Combines the preferredModel field of multiple {@link IrisSettings} objects.
- * Simply takes the last preferredModel.
- * TODO
+ * Combines the selectedVariant field of multiple {@link IrisSettings} objects.
+ * Simply takes the last selectedVariant.
*
* @param settingsList List of {@link IrisSettings} objects to combine.
* @param subSettingsFunction Function to get the sub settings from an IrisSettings object.
- * @return Combined preferredModel field.
+ * @return Combined selectedVariant field.
*/
- private String getCombinedPreferredModel(List settingsList, Function subSettingsFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getPreferredModel)
+ private String getCombinedSelectedVariant(List settingsList, Function subSettingsFunction) {
+ return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getSelectedVariant)
.filter(model -> model != null && !model.isBlank()).reduce((first, second) -> second).orElse(null);
}
-
- /**
- * Combines the template field of multiple {@link IrisSettings} objects.
- * Simply takes the last template.
- *
- * @param settingsList List of {@link IrisSettings} objects to combine.
- * @param templateFunction Function to get the template from the sub settings from an IrisSettings object.
- * @return Combined template field.
- */
- private IrisTemplate getCombinedTemplate(List settingsList, Function subSettingsFunction,
- Function templateFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(templateFunction)
- .filter(template -> template != null && template.getContent() != null && !template.getContent().isBlank()).reduce((first, second) -> second).orElse(null);
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java
deleted file mode 100644
index ae4bedb82493..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.tum.cit.aet.artemis.iris.web;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.util.List;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
-
-/**
- * REST controller for managing the models Pyris provides.
- */
-@Profile(PROFILE_IRIS)
-@RestController
-@RequestMapping("api/")
-public class IrisModelsResource {
-
- private final PyrisConnectorService pyrisConnectorService;
-
- public IrisModelsResource(PyrisConnectorService pyrisConnectorService) {
- this.pyrisConnectorService = pyrisConnectorService;
- }
-
- /**
- * GET iris/models: Retrieve all available models offered by Pyris
- *
- * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body a List of the models
- */
- @GetMapping("iris/models")
- @EnforceAtLeastEditor
- public ResponseEntity> getAllModels() {
- try {
- var models = pyrisConnectorService.getOfferedModels();
- return ResponseEntity.ok(models);
- }
- catch (PyrisConnectorException e) {
- throw new InternalServerErrorException("Could not fetch available Iris models");
- }
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
index 32676da073bb..a4f51180b159 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
@@ -14,9 +14,13 @@
import de.tum.cit.aet.artemis.core.repository.CourseRepository;
import de.tum.cit.aet.artemis.core.repository.UserRepository;
import de.tum.cit.aet.artemis.core.security.Role;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastEditorInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastInstructorInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastStudentInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastEditorInExercise;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastInstructorInExercise;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastStudentInExercise;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
@@ -71,10 +75,9 @@ public ResponseEntity getGlobalSettings() {
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@GetMapping("courses/{courseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastEditorInCourse
public ResponseEntity getRawCourseSettings(@PathVariable Long courseId) {
var course = courseRepository.findByIdElseThrow(courseId);
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, null);
var irisSettings = irisSettingsService.getRawIrisSettingsFor(course);
return ResponseEntity.ok(irisSettings);
}
@@ -86,7 +89,7 @@ public ResponseEntity getRawCourseSettings(@PathVariable Long cour
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the exercise could not be found.
*/
@GetMapping("programming-exercises/{exerciseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastEditorInExercise
public ResponseEntity getRawProgrammingExerciseSettings(@PathVariable Long exerciseId) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
@@ -103,11 +106,10 @@ public ResponseEntity getRawProgrammingExerciseSettings(@PathVaria
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@GetMapping("courses/{courseId}/iris-settings")
- @EnforceAtLeastStudent
+ @EnforceAtLeastStudentInCourse
public ResponseEntity getCourseSettings(@PathVariable Long courseId) {
var course = courseRepository.findByIdElseThrow(courseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.STUDENT, course, user);
// Editors can see the full settings, students only the reduced settings
var getReduced = !authCheckService.isAtLeastEditorInCourse(course, user);
@@ -122,11 +124,10 @@ public ResponseEntity getCourseSettings(@PathVariable L
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the exercise could not be found.
*/
@GetMapping("programming-exercises/{exerciseId}/iris-settings")
- @EnforceAtLeastStudent
+ @EnforceAtLeastStudentInExercise
public ResponseEntity getProgrammingExerciseSettings(@PathVariable Long exerciseId) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.STUDENT, exercise, user);
var combinedIrisSettings = irisSettingsService.getCombinedIrisSettingsFor(exercise, irisSettingsService.shouldShowMinimalSettings(exercise, user));
return ResponseEntity.ok(combinedIrisSettings);
@@ -140,10 +141,9 @@ public ResponseEntity getProgrammingExerciseSettings(@P
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the updated settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@PutMapping("courses/{courseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastInstructorInCourse
public ResponseEntity updateCourseSettings(@PathVariable Long courseId, @RequestBody IrisCourseSettings settings) {
var course = courseRepository.findByIdElseThrow(courseId);
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, null);
settings.setCourse(course);
var updatedSettings = irisSettingsService.saveIrisSettings(settings);
return ResponseEntity.ok(updatedSettings);
@@ -158,11 +158,9 @@ public ResponseEntity updateCourseSettings(@PathVariable Lon
* found.
*/
@PutMapping("programming-exercises/{exerciseId}/raw-iris-settings")
- @EnforceAtLeastInstructor
+ @EnforceAtLeastInstructorInExercise
public ResponseEntity updateProgrammingExerciseSettings(@PathVariable Long exerciseId, @RequestBody IrisExerciseSettings settings) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
- var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.INSTRUCTOR, exercise, user);
settings.setExercise(exercise);
var updatedSettings = irisSettingsService.saveIrisSettings(settings);
return ResponseEntity.ok(updatedSettings);
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java
new file mode 100644
index 000000000000..9342d1522023
--- /dev/null
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java
@@ -0,0 +1,56 @@
+package de.tum.cit.aet.artemis.iris.web;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Profile;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException;
+import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
+import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
+import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
+
+/**
+ * REST controller for managing the variants Pyris provides.
+ */
+@Profile("iris")
+@RestController
+@RequestMapping("api/")
+public class IrisVariantsResource {
+
+ private static final Logger log = LoggerFactory.getLogger(IrisVariantsResource.class);
+
+ private final PyrisConnectorService pyrisConnectorService;
+
+ public IrisVariantsResource(PyrisConnectorService pyrisConnectorService) {
+ this.pyrisConnectorService = pyrisConnectorService;
+ }
+
+ /**
+ * GET iris/variants/{feature}: Retrieve all available variants offered by Pyris for a certain feature
+ *
+ * @param featureRaw the feature for which to retrieve the variants
+ * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body a List of the variants
+ */
+ @GetMapping("iris/variants/{feature}")
+ @EnforceAtLeastEditor
+ public ResponseEntity> getAllVariants(@PathVariable("feature") String featureRaw) {
+ var feature = IrisSubSettingsType.valueOf(featureRaw.toUpperCase().replace("-", "_"));
+ try {
+ var variants = pyrisConnectorService.getOfferedVariants(feature);
+ return ResponseEntity.ok(variants);
+ }
+ catch (PyrisConnectorException e) {
+ log.error("Could not fetch available variants for feature {}", feature, e);
+ throw new InternalServerErrorException("Could not fetch available variants for feature " + feature);
+ }
+ }
+}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
index ac73fae28454..f04de8a56db9 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
@@ -13,8 +13,6 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.core.exception.BadRequestAlertException;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-import de.tum.cit.aet.artemis.iris.service.session.IrisHestiaSessionService;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseSolutionEntry;
@@ -29,17 +27,14 @@ public class CodeHintService {
private static final Logger log = LoggerFactory.getLogger(CodeHintService.class);
- private final Optional irisHestiaSessionService;
-
private final CodeHintRepository codeHintRepository;
private final ProgrammingExerciseTaskRepository taskRepository;
private final ProgrammingExerciseSolutionEntryRepository solutionEntryRepository;
- public CodeHintService(Optional irisHestiaSessionService, CodeHintRepository codeHintRepository, ProgrammingExerciseTaskRepository taskRepository,
+ public CodeHintService(CodeHintRepository codeHintRepository, ProgrammingExerciseTaskRepository taskRepository,
ProgrammingExerciseSolutionEntryRepository solutionEntryRepository) {
- this.irisHestiaSessionService = irisHestiaSessionService;
this.codeHintRepository = codeHintRepository;
this.taskRepository = taskRepository;
this.solutionEntryRepository = solutionEntryRepository;
@@ -189,17 +184,4 @@ public void updateSolutionEntriesForCodeHint(CodeHint hint) {
codeHintRepository.save(hint);
}
-
- /**
- * Generates a description and content for a code hint using the Iris subsystem.
- * See {@link IrisHestiaSessionService#executeRequest(IrisHestiaSession)} for more information.
- *
- * @param codeHint The code hint to be generated
- * @return The code hint with description and content
- */
- public CodeHint generateDescriptionWithIris(CodeHint codeHint) {
- var irisService = irisHestiaSessionService.orElseThrow();
- var session = irisService.getOrCreateSession(codeHint);
- return irisService.executeRequest(session);
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java b/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
index 297e784f1e2b..122aa11b7a17 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
@@ -1,11 +1,9 @@
package de.tum.cit.aet.artemis.programming.web.hestia;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
@@ -23,8 +21,6 @@
import de.tum.cit.aet.artemis.core.exception.AccessForbiddenException;
import de.tum.cit.aet.artemis.core.exception.ConflictException;
import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastEditorInExercise;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
-import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
@@ -50,15 +46,12 @@ public class CodeHintResource {
private final CodeHintService codeHintService;
- private final Optional irisSettingsService;
-
public CodeHintResource(ProgrammingExerciseRepository programmingExerciseRepository, ProgrammingExerciseSolutionEntryRepository solutionEntryRepository,
- CodeHintRepository codeHintRepository, CodeHintService codeHintService, Optional irisSettingsService) {
+ CodeHintRepository codeHintRepository, CodeHintService codeHintService) {
this.programmingExerciseRepository = programmingExerciseRepository;
this.solutionEntryRepository = solutionEntryRepository;
this.codeHintRepository = codeHintRepository;
this.codeHintService = codeHintService;
- this.irisSettingsService = irisSettingsService;
}
/**
@@ -98,41 +91,6 @@ public ResponseEntity> generateCodeHintsForExercise(@PathVariable
return ResponseEntity.ok(codeHints);
}
- /**
- * {@code POST programming-exercises/:exerciseId/code-hints/:codeHintId/generate-description} : Generate a description for a code hint using Iris.
- *
- * @param exerciseId The id of the exercise of the code hint
- * @param codeHintId The id of the code hint
- * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the updated code hint
- */
- // TODO: move into some IrisResource
- @Profile(PROFILE_IRIS)
- @PostMapping("programming-exercises/{exerciseId}/code-hints/{codeHintId}/generate-description")
- @EnforceAtLeastEditorInExercise
- public ResponseEntity generateDescriptionForCodeHint(@PathVariable Long exerciseId, @PathVariable Long codeHintId) {
- log.debug("REST request to generate description with Iris for CodeHint: {}", codeHintId);
-
- ProgrammingExercise exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
- irisSettingsService.orElseThrow().isEnabledForElseThrow(IrisSubSettingsType.HESTIA, exercise);
-
- // Hints for exam exercises are not supported at the moment
- if (exercise.isExamExercise()) {
- throw new AccessForbiddenException("Code hints for exams are currently not supported");
- }
-
- var codeHint = codeHintRepository.findByIdWithSolutionEntriesElseThrow(codeHintId);
- if (!Objects.equals(codeHint.getExercise().getId(), exercise.getId())) {
- throw new ConflictException("The code hint does not belong to the exercise", "CodeHint", "codeHintExerciseConflict");
- }
-
- if (codeHint.getSolutionEntries().isEmpty()) {
- throw new ConflictException("The code hint does not have any solution entries", "CodeHint", "codeHintNoSolutionEntries");
- }
-
- codeHint = codeHintService.generateDescriptionWithIris(codeHint);
- return ResponseEntity.ok(codeHint);
- }
-
/**
* {@code DELETE programming-exercises/:exerciseId/code-hints/:codeHintId/solution-entries/:solutionEntryId} :
* Removes a solution entry from a code hint.
diff --git a/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml b/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml
new file mode 100644
index 000000000000..3ae7fd7ea038
--- /dev/null
+++ b/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DELETE FROM iris_sub_settings WHERE discriminator = 'HESTIA';
+
+
+
+
+
+
+
+
+
+
+ UPDATE iris_sub_settings
+ SET allowed_variants = 'default', selected_variant = 'default'
+ WHERE id IN (
+ SELECT iris_chat_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ UNION
+ SELECT iris_competency_generation_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ UNION
+ SELECT iris_lecture_ingestion_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ );
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DELETE FROM iris_json_message_content WHERE id IN (
+ SELECT iris_message_content.id FROM iris_message_content
+ JOIN iris_message ON iris_message_content.message_id = iris_message.id
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_text_message_content WHERE id IN (
+ SELECT iris_message_content.id FROM iris_message_content
+ JOIN iris_message ON iris_message_content.message_id = iris_message.id
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_message_content WHERE message_id IN (
+ SELECT iris_message.id FROM iris_message
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_message WHERE session_id IN (
+ SELECT id FROM iris_session WHERE discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_session WHERE discriminator = 'HESTIA';
+
+
+
+
+
+
+
diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml
index 49f3eeee4d63..b560fb1047fe 100644
--- a/src/main/resources/config/liquibase/master.xml
+++ b/src/main/resources/config/liquibase/master.xml
@@ -22,6 +22,7 @@
+
diff --git a/src/main/webapp/app/course/manage/detail/course-detail.component.ts b/src/main/webapp/app/course/manage/detail/course-detail.component.ts
index 5954f3c0b7c0..29858e79b334 100644
--- a/src/main/webapp/app/course/manage/detail/course-detail.component.ts
+++ b/src/main/webapp/app/course/manage/detail/course-detail.component.ts
@@ -50,7 +50,6 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
communicationEnabled: boolean;
irisEnabled = false;
irisChatEnabled = false;
- irisHestiaEnabled = false;
ltiEnabled = false;
isAthenaEnabled = false;
tutorialEnabled = false;
@@ -96,7 +95,6 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
if (this.irisEnabled) {
const irisSettings = await firstValueFrom(this.irisSettingsService.getGlobalSettings());
this.irisChatEnabled = irisSettings?.irisChatSettings?.enabled ?? false;
- this.irisHestiaEnabled = irisSettings?.irisHestiaSettings?.enabled ?? false;
}
this.route.data.subscribe(({ course }) => {
if (course) {
diff --git a/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts b/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
index 017c3ea2cffa..ab7f3b475908 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
@@ -1,10 +1,5 @@
import { BaseEntity } from 'app/shared/model/base-entity';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
export enum IrisSettingsType {
GLOBAL = 'global',
@@ -17,21 +12,14 @@ export abstract class IrisSettings implements BaseEntity {
type: IrisSettingsType;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
export class IrisGlobalSettings implements IrisSettings {
id?: number;
type = IrisSettingsType.GLOBAL;
- currentVersion?: number;
- enableAutoUpdateChat?: boolean;
- enableAutoUpdateLectureIngestion?: boolean;
- enableAutoUpdateHestia?: boolean;
- enableAutoUpdateCompetencyGeneration?: boolean;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
@@ -41,7 +29,6 @@ export class IrisCourseSettings implements IrisSettings {
courseId?: number;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts b/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
index 8848394f1350..626155a43555 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
@@ -1,9 +1,7 @@
import { BaseEntity } from 'app/shared/model/base-entity';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
export enum IrisSubSettingsType {
CHAT = 'chat',
- HESTIA = 'hestia',
COMPETENCY_GENERATION = 'competency-generation',
LECTURE_INGESTION = 'lecture-ingestion',
}
@@ -12,13 +10,12 @@ export abstract class IrisSubSettings implements BaseEntity {
id?: number;
type: IrisSubSettingsType;
enabled = false;
- allowedModels?: string[];
- preferredModel?: string;
+ allowedVariants?: string[];
+ selectedVariant?: string;
}
export class IrisChatSubSettings extends IrisSubSettings {
type = IrisSubSettingsType.CHAT;
- template?: IrisTemplate;
rateLimit?: number;
rateLimitTimeframeHours?: number;
}
@@ -28,12 +25,6 @@ export class IrisLectureIngestionSubSettings extends IrisSubSettings {
autoIngestOnLectureAttachmentUpload: boolean;
}
-export class IrisHestiaSubSettings extends IrisSubSettings {
- type = IrisSubSettingsType.HESTIA;
- template?: IrisTemplate;
-}
-
export class IrisCompetencyGenerationSubSettings extends IrisSubSettings {
type = IrisSubSettingsType.COMPETENCY_GENERATION;
- template?: IrisTemplate;
}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-template.ts b/src/main/webapp/app/entities/iris/settings/iris-template.ts
deleted file mode 100644
index eb0c8a90041c..000000000000
--- a/src/main/webapp/app/entities/iris/settings/iris-template.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { BaseEntity } from 'app/shared/model/base-entity';
-
-export class IrisTemplate implements BaseEntity {
- id?: number;
- content = '';
-}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-model.ts b/src/main/webapp/app/entities/iris/settings/iris-variant.ts
similarity index 69%
rename from src/main/webapp/app/entities/iris/settings/iris-model.ts
rename to src/main/webapp/app/entities/iris/settings/iris-variant.ts
index 94a7f9202d92..3fbecfee8c49 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-variant.ts
@@ -1,4 +1,4 @@
-export class IrisModel {
+export class IrisVariant {
id: string;
name: string;
description: string;
diff --git a/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html b/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
index 5c80f6e0c868..6bf170d0bac9 100644
--- a/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
+++ b/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
@@ -45,21 +45,6 @@
- @if (exerciseHint.type === HintType.CODE && irisSettings?.irisHestiaSettings?.enabled) {
-
- Generate description
-
-
- }
diff --git a/src/main/webapp/app/iris/iris.module.ts b/src/main/webapp/app/iris/iris.module.ts
index 5473966d0275..aacdbd0b64cf 100644
--- a/src/main/webapp/app/iris/iris.module.ts
+++ b/src/main/webapp/app/iris/iris.module.ts
@@ -14,7 +14,6 @@ import { IrisCommonSubSettingsUpdateComponent } from './settings/iris-settings-u
import { IrisCourseSettingsUpdateComponent } from 'app/iris/settings/iris-course-settings-update/iris-course-settings-update.component';
import { IrisExerciseSettingsUpdateComponent } from 'app/iris/settings/iris-exercise-settings-update/iris-exercise-settings-update.component';
import { IrisLogoComponent } from './iris-logo/iris-logo.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from './settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { IrisExerciseChatbotButtonComponent } from 'app/iris/exercise-chatbot/exercise-chatbot-button.component';
import { IrisChatbotWidgetComponent } from 'app/iris/exercise-chatbot/widget/chatbot-widget.component';
import { IrisEnabledComponent } from 'app/iris/settings/shared/iris-enabled.component';
@@ -36,7 +35,6 @@ import { CourseChatbotComponent } from 'app/iris/course-chatbot/course-chatbot.c
IrisExerciseSettingsUpdateComponent,
IrisCommonSubSettingsUpdateComponent,
IrisLogoComponent,
- IrisGlobalAutoupdateSettingsUpdateComponent,
IrisEnabledComponent,
ChatStatusBarComponent,
IrisLogoButtonComponent,
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
index 4132e9fab587..95238efecaf9 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
@@ -24,39 +24,62 @@
jhiTranslate="artemisApp.iris.settings.subSettings.enabled.off"
>
-
- :
+
+ :
@if (parentSubSettings) {
}
+ :
+
+
+
+ {{ getSelectedVariantName() ?? ('artemisApp.iris.settings.subSettings.variants.selectedVariant.inherit' | artemisTranslate) }}
+
+
+ @if (parentSubSettings) {
+
+ {{ 'artemisApp.iris.settings.subSettings.variants.selectedVariant.inherit' | artemisTranslate }}
+
+ }
+ @for (model of allowedVariants; track model) {
+
+ {{ model.name }}
+
+ }
+
+
+ @if (!subSettings?.selectedVariant) {
+
{{ getSelectedVariantNameParent() }}
+ }
+
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
index 723b8ddb21a9..ba5bd6573691 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
@@ -1,10 +1,11 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { IrisSubSettings, IrisSubSettingsType } from 'app/entities/iris/settings/iris-sub-settings.model';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
import { AccountService } from 'app/core/auth/account.service';
import { ButtonType } from 'app/shared/components/button.component';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
+import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
@Component({
selector: 'jhi-iris-common-sub-settings-update',
@@ -17,9 +18,6 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
@Input()
parentSubSettings?: IrisSubSettings;
- @Input()
- allIrisModels: IrisModel[];
-
@Input()
settingsType: IrisSettingsType;
@@ -28,9 +26,11 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
isAdmin: boolean;
- inheritAllowedModels: boolean;
+ inheritAllowedVariants: boolean;
+
+ availableVariants: IrisVariant[] = [];
- allowedIrisModels: IrisModel[];
+ allowedVariants: IrisVariant[] = [];
enabled: boolean;
@@ -42,49 +42,62 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
// Icons
faTrash = faTrash;
- constructor(accountService: AccountService) {
+ constructor(
+ accountService: AccountService,
+ private irisSettingsService: IrisSettingsService,
+ ) {
this.isAdmin = accountService.isAdmin();
}
ngOnInit() {
this.enabled = this.subSettings?.enabled ?? false;
- this.allowedIrisModels = this.getAvailableModels();
- this.inheritAllowedModels = !!(!this.subSettings?.allowedModels && this.parentSubSettings);
+ this.loadVariants();
+ this.inheritAllowedVariants = !!(!this.subSettings?.allowedVariants && this.parentSubSettings);
}
ngOnChanges(changes: SimpleChanges): void {
- if (changes.allIrisModels) {
- this.allowedIrisModels = this.getAvailableModels();
+ if (changes.availableVariants) {
+ this.allowedVariants = this.getAllowedVariants();
}
if (changes.subSettings) {
this.enabled = this.subSettings?.enabled ?? false;
}
}
- getAvailableModels(): IrisModel[] {
- return this.allIrisModels.filter((model) => (this.subSettings?.allowedModels ?? this.parentSubSettings?.allowedModels ?? []).includes(model.id));
+ loadVariants(): void {
+ if (!this.subSettings?.type) {
+ return;
+ }
+ this.irisSettingsService.getVariantsForFeature(this.subSettings?.type).subscribe((variants) => {
+ this.availableVariants = variants ?? this.availableVariants;
+ this.allowedVariants = this.getAllowedVariants();
+ });
+ }
+
+ getAllowedVariants(): IrisVariant[] {
+ return this.availableVariants.filter((variant) => (this.subSettings?.allowedVariants ?? this.parentSubSettings?.allowedVariants ?? []).includes(variant.id));
}
- getPreferredModelName(): string | undefined {
- return this.allIrisModels.find((model) => model.id === this.subSettings?.preferredModel)?.name ?? this.subSettings?.preferredModel;
+ getSelectedVariantName(): string | undefined {
+ return this.availableVariants.find((variant) => variant.id === this.subSettings?.selectedVariant)?.name ?? this.subSettings?.selectedVariant;
}
- getPreferredModelNameParent(): string | undefined {
- return this.allIrisModels.find((model) => model.id === this.parentSubSettings?.preferredModel)?.name ?? this.parentSubSettings?.preferredModel;
+ getSelectedVariantNameParent(): string | undefined {
+ return this.availableVariants.find((variant) => variant.id === this.parentSubSettings?.selectedVariant)?.name ?? this.parentSubSettings?.selectedVariant;
}
- onAllowedIrisModelsSelectionChange(model: IrisModel) {
- this.inheritAllowedModels = false;
- if (this.allowedIrisModels.includes(model)) {
- this.allowedIrisModels = this.allowedIrisModels.filter((m) => m !== model);
+ onAllowedIrisVariantsSelectionChange(variant: IrisVariant) {
+ this.inheritAllowedVariants = false;
+ if (this.allowedVariants.map((variant) => variant.id).includes(variant.id)) {
+ this.allowedVariants = this.allowedVariants.filter((m) => m.id !== variant.id);
} else {
- this.allowedIrisModels.push(model);
+ this.allowedVariants.push(variant);
}
- this.subSettings!.allowedModels = this.allowedIrisModels.map((model) => model.id);
+ this.subSettings!.allowedVariants = this.allowedVariants.map((variant) => variant.id);
}
- setModel(model: IrisModel | undefined) {
- this.subSettings!.preferredModel = model?.id;
+ setVariant(variant: IrisVariant | undefined) {
+ this.subSettings!.selectedVariant = variant?.id;
}
onEnabledChange() {
@@ -101,12 +114,12 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
this.onEnabledChange();
}
- onInheritAllowedModelsChange() {
- if (this.inheritAllowedModels) {
- this.subSettings!.allowedModels = undefined;
- this.allowedIrisModels = this.getAvailableModels();
+ onInheritAllowedVariantsChange() {
+ if (this.inheritAllowedVariants) {
+ this.subSettings!.allowedVariants = undefined;
+ this.allowedVariants = this.getAllowedVariants();
} else {
- this.subSettings!.allowedModels = this.allowedIrisModels.map((model) => model.id);
+ this.subSettings!.allowedVariants = this.allowedVariants.map((variant) => variant.id);
}
}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html
deleted file mode 100644
index efb780138e8c..000000000000
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html
+++ /dev/null
@@ -1,20 +0,0 @@
-@if (irisSettings) {
-
-}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts
deleted file mode 100644
index 404132633566..000000000000
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
-import { IrisSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
-
-@Component({
- selector: 'jhi-iris-global-autoupdate-settings-update',
- templateUrl: './iris-global-autoupdate-settings-update.component.html',
-})
-export class IrisGlobalAutoupdateSettingsUpdateComponent {
- @Input()
- irisSettings?: IrisGlobalSettings;
-
- @Output()
- onChanges = new EventEmitter();
-}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
index b28a3a4c690c..c1e15d609c1f 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
@@ -11,18 +11,11 @@
@if (irisSettings) {
- @if (settingsType === GLOBAL) {
-
-
-
-
- }
@@ -34,33 +27,21 @@
-
- }
- @if (settingsType === COURSE) {
-
-
-
-
- }
- @if (settingsType !== EXERCISE) {
-
-
-
-
+
+
+ @if (settingsType === COURSE) {
+
+
+
+
+ }
}
@if (settingsType !== EXERCISE) {
@@ -70,7 +51,6 @@
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
index 5bde2f10f791..aa9adac6be64 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
@@ -6,15 +6,9 @@ import { Observable } from 'rxjs';
import { AlertService } from 'app/core/util/alert.service';
import { ButtonType } from 'app/shared/components/button.component';
import { faRotate, faSave } from '@fortawesome/free-solid-svg-icons';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
import { ComponentCanDeactivate } from 'app/shared/guard/can-deactivate.model';
import { cloneDeep, isEqual } from 'lodash-es';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { AccountService } from 'app/core/auth/account.service';
@Component({
@@ -30,7 +24,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
public exerciseId?: number;
public irisSettings?: IrisSettings;
public parentIrisSettings?: IrisSettings;
- public allIrisModels?: IrisModel[];
originalIrisSettings?: IrisSettings;
@@ -77,13 +70,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
return !this.isDirty;
}
- loadIrisModels(): void {
- this.irisSettingsService.getIrisModels().subscribe((models) => {
- this.allIrisModels = models;
- this.isLoading = false;
- });
- }
-
loadIrisSettings(): void {
this.isLoading = true;
this.loadIrisSettingsObservable().subscribe((settings) => {
@@ -116,9 +102,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
if (!this.irisSettings.irisLectureIngestionSettings) {
this.irisSettings.irisLectureIngestionSettings = new IrisLectureIngestionSubSettings();
}
- if (!this.irisSettings.irisHestiaSettings) {
- this.irisSettings.irisHestiaSettings = new IrisHestiaSubSettings();
- }
if (!this.irisSettings.irisCompetencyGenerationSettings) {
this.irisSettings.irisCompetencyGenerationSettings = new IrisCompetencyGenerationSubSettings();
}
diff --git a/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts b/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
index ef8d44419841..be64bd5d856b 100644
--- a/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
+++ b/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
@@ -56,9 +56,6 @@ export class IrisEnabledComponent implements OnInit {
case IrisSubSettingsType.CHAT:
this.irisSubSettings = this.irisSettings?.irisChatSettings;
break;
- case IrisSubSettingsType.HESTIA:
- this.irisSubSettings = this.irisSettings?.irisHestiaSettings;
- break;
case IrisSubSettingsType.COMPETENCY_GENERATION:
this.irisSubSettings = this.irisSettings?.irisCompetencyGenerationSettings;
break;
diff --git a/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts b/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
index 475540bad156..7273e5958cf6 100644
--- a/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
+++ b/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
@@ -3,7 +3,8 @@ import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { IrisCourseSettings, IrisExerciseSettings, IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
+import { IrisSubSettingsType } from 'app/entities/iris/settings/iris-sub-settings.model';
/**
* Service for calling the Iris settings endpoints on the server
@@ -90,9 +91,11 @@ export class IrisSettingsService {
}
/**
- * Get the global Iris settings
+ * Get the available variants for a feature
*/
- getIrisModels(): Observable
{
- return this.http.get(`${this.resourceUrl}/iris/models`, { observe: 'response' }).pipe(map((res: HttpResponse) => res.body ?? []));
+ getVariantsForFeature(feature: IrisSubSettingsType): Observable {
+ return this.http
+ .get(`${this.resourceUrl}/iris/variants/${feature}`, { observe: 'response' })
+ .pipe(map((res: HttpResponse) => res.body ?? []));
}
}
diff --git a/src/main/webapp/i18n/de/iris.json b/src/main/webapp/i18n/de/iris.json
index 34572e7581bd..4044841119d8 100644
--- a/src/main/webapp/i18n/de/iris.json
+++ b/src/main/webapp/i18n/de/iris.json
@@ -28,14 +28,14 @@
"hestiaSettings": "Hestia Einstellungen",
"competencyGenerationSettings": "Kompetenzgenerierung Einstellungen",
"enabled-disabled": "Aktiviert/Deaktiviert",
- "models": {
- "title": "Modelle",
- "allowedModels": {
- "title": "Erlaubte Modelle",
- "inheritSwitch": "Erbe erlaubte Modelle"
+ "variants": {
+ "title": "Varianten",
+ "allowedVariants": {
+ "title": "Erlaubte Varianten",
+ "inheritSwitch": "Erbe erlaubte Varianten"
},
- "preferredModel": {
- "title": "Präferiertes Modell",
+ "selectedVariant": {
+ "title": "Genuzte Variante",
"inherit": "Erben"
}
},
@@ -63,21 +63,13 @@
"global": "Globale Iris Einstellungen",
"course": "Kurs Iris Einstellungen",
"programmingExercise": "Programmieraufgabe Iris Einstellungen"
- },
- "autoUpdate": {
- "title": "Auto Update Einstellungen",
- "tooltip": "Wenn aktiviert, werden die spezifischen globalen Iris Einstellungen automatisch aktualisiert, wenn eine neue Version von Artemis neue Iris Einstellungen bereitstellt.",
- "chatLabel": "Auto Update der Chat Einstellungen",
- "hestiaLabel": "Auto Update der Hestia Einstellungen",
- "lectureIngestionLabel": "Auto Update der Vorlesungen Erfassung Einstellungen",
- "competencyGenerationLabel": "Auto Update der Kompetenzgenerierung Einstellungen"
}
},
"error": {
"forbidden": "Artemis ist nicht konfiguriert, um Iris zu verwenden. (Ungültiges Token)",
"internalPyrisError": "Ein interner Fehler beim Kommunizieren mit dem LLM ist aufgetreten. Die Fehlermeldung lautet: {{ pyrisErrorMessage }}.",
"invalidTemplate": "Die Vorlage ist ungültig. Die Fehlermeldung lautet: {{ pyrisErrorMessage }}.",
- "noModelAvailable": "Das Modell {{ model }} steht nicht zur Verfügung. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
+ "noVariantAvailable": "Die Variante {{ variant }} steht nicht zur Verfügung. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
"noResponse": "Es wurde keine Antwort von Iris empfangen. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
"parseResponse": "Ein Fehler ist beim Parsen der Antwort von Iris aufgetreten. Ursache: {{ cause }}"
},
diff --git a/src/main/webapp/i18n/en/iris.json b/src/main/webapp/i18n/en/iris.json
index 6afbb928d5c9..21aed4b477e7 100644
--- a/src/main/webapp/i18n/en/iris.json
+++ b/src/main/webapp/i18n/en/iris.json
@@ -28,14 +28,14 @@
"hestiaSettings": "Hestia Settings",
"competencyGenerationSettings": "Competency Generation Settings",
"enabled-disabled": "Enabled/Disabled",
- "models": {
- "title": "Models",
- "allowedModels": {
- "title": "Allowed Models",
- "inheritSwitch": "Inherit Allowed Models"
+ "variants": {
+ "title": "Variants",
+ "allowedVariants": {
+ "title": "Allowed Variants",
+ "inheritSwitch": "Inherit Allowed Variants"
},
- "preferredModel": {
- "title": "Preferred Model",
+ "selectedVariant": {
+ "title": "Selected Variant",
"inherit": "Inherit"
}
},
@@ -63,21 +63,13 @@
"global": "Global Iris Settings",
"course": "Course Iris Settings",
"exercise": "Exercise Iris Settings"
- },
- "autoUpdate": {
- "title": "Auto Update Settings",
- "tooltip": "If enabled, the specific global Iris settings will be automatically updated when a new release of Artemis provides new Iris settings.",
- "chatLabel": "Auto Update Chat Settings",
- "hestiaLabel": "Auto Update Hestia Settings",
- "lectureIngestionLabel": "Auto Update Lecture Ingestion Settings",
- "competencyGenerationLabel": "Auto Update Competency Generation Settings"
}
},
"error": {
"forbidden": "Artemis is not configured to use Iris. (Invalid token)",
"internalPyrisError": "An internal error when communicating with the LLM occurred. Error message is: {{ pyrisErrorMessage }}.",
"invalidTemplate": "The template is invalid. Error message is: {{ pyrisErrorMessage }}.",
- "noModelAvailable": "Model {{ model }} is not available to use. Please contact your administrator if this problem persists.",
+ "noVariantAvailable": "Variant {{ variant }} is not available to use. Please contact your administrator if this problem persists.",
"noResponse": "No response from Iris was received.",
"parseResponse": "An error occurred while parsing the response from Iris. Cause: {{ cause }}"
},
diff --git a/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java b/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
index 4c7146242014..2e4506485ead 100644
--- a/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
+++ b/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
@@ -28,8 +28,9 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisHealthStatusDTO;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.chat.exercise.PyrisExerciseChatPipelineExecutionDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.competency.PyrisCompetencyExtractionPipelineExecutionDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.lectureingestionwebhook.PyrisWebhookLectureIngestionExecutionDTO;
@@ -52,8 +53,8 @@ public class IrisRequestMockProvider {
@Value("${artemis.iris.url}/api/v1/webhooks")
private URL webhooksApiURL;
- @Value("${artemis.iris.url}/api/v1/models")
- private URL modelsApiURL;
+ @Value("${artemis.iris.url}/api/v1/pipelines/")
+ private String variantsApiBaseURL;
@Value("${artemis.iris.url}/api/v1/health/")
private URL healthApiURL;
@@ -139,11 +140,11 @@ public void mockIngestionWebhookRunError(int httpStatus) {
// @formatter:on
}
- public void mockModelsResponse() throws JsonProcessingException {
- var irisModelDTO = new PyrisModelDTO("TEST_MODEL", "Test model", "Test description");
- var irisModelDTOArray = new PyrisModelDTO[] { irisModelDTO };
+ public void mockVariantsResponse(IrisSubSettingsType feature) throws JsonProcessingException {
+ var irisModelDTO = new PyrisVariantDTO("TEST_MODEL", "Test model", "Test description");
+ var irisModelDTOArray = new PyrisVariantDTO[] { irisModelDTO };
// @formatter:off
- mockServer.expect(ExpectedCount.once(), requestTo(modelsApiURL.toString()))
+ mockServer.expect(ExpectedCount.once(), requestTo(variantsApiBaseURL + feature.name() + "/variants"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(mapper.writeValueAsString(irisModelDTOArray), MediaType.APPLICATION_JSON));
// @formatter:on
@@ -169,9 +170,9 @@ public void mockStatusResponses() throws JsonProcessingException {
/**
* Mocks a get model error from the Pyris models endpoint
*/
- public void mockModelsError() {
+ public void mockVariantsError(IrisSubSettingsType feature) {
// @formatter:off
- mockServer.expect(ExpectedCount.once(), requestTo(modelsApiURL.toString()))
+ mockServer.expect(ExpectedCount.once(), requestTo(variantsApiBaseURL + feature.name() + "/variants"))
.andExpect(method(HttpMethod.GET))
.andRespond(withRawStatus(418));
// @formatter:on
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
index 34337b170baf..28cf037fa204 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
@@ -18,7 +18,6 @@
import de.tum.cit.aet.artemis.core.connector.IrisRequestMockProvider;
import de.tum.cit.aet.artemis.core.domain.Course;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.repository.IrisSettingsRepository;
import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
@@ -60,7 +59,6 @@ void tearDown() throws Exception {
protected void activateIrisGlobally() {
var globalSettings = irisSettingsService.getGlobalSettings();
activateSubSettings(globalSettings.getIrisChatSettings());
- activateSubSettings(globalSettings.getIrisHestiaSettings());
activateSubSettings(globalSettings.getIrisLectureIngestionSettings());
activateSubSettings(globalSettings.getIrisCompetencyGenerationSettings());
irisSettingsRepository.save(globalSettings);
@@ -73,21 +71,16 @@ protected void activateIrisGlobally() {
*/
private void activateSubSettings(IrisSubSettings settings) {
settings.setEnabled(true);
- settings.setPreferredModel(null);
- settings.setAllowedModels(new TreeSet<>(Set.of("dummy")));
+ settings.setSelectedVariant("default");
+ settings.setAllowedVariants(new TreeSet<>(Set.of("default")));
}
protected void activateIrisFor(Course course) {
var courseSettings = irisSettingsService.getDefaultSettingsFor(course);
activateSubSettings(courseSettings.getIrisChatSettings());
- courseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
-
- activateSubSettings(courseSettings.getIrisHestiaSettings());
- courseSettings.getIrisHestiaSettings().setTemplate(createDummyTemplate());
activateSubSettings(courseSettings.getIrisCompetencyGenerationSettings());
- courseSettings.getIrisCompetencyGenerationSettings().setTemplate(createDummyTemplate());
activateSubSettings(courseSettings.getIrisLectureIngestionSettings());
@@ -97,14 +90,9 @@ protected void activateIrisFor(Course course) {
protected void activateIrisFor(ProgrammingExercise exercise) {
var exerciseSettings = irisSettingsService.getDefaultSettingsFor(exercise);
activateSubSettings(exerciseSettings.getIrisChatSettings());
- exerciseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
irisSettingsRepository.save(exerciseSettings);
}
- protected IrisTemplate createDummyTemplate() {
- return new IrisTemplate("Hello World");
- }
-
/**
* Verify that the given messages were sent through the websocket for the given user and topic.
*
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
index 413b0b77c046..de726729a035 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
@@ -5,12 +5,13 @@
import java.util.stream.Stream;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.exception.IrisForbiddenException;
import de.tum.cit.aet.artemis.iris.exception.IrisInternalPyrisErrorException;
import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
@@ -49,20 +50,22 @@ void testExceptionIngestionV2(int httpStatus, Class> exceptionClass) {
assertThatThrownBy(() -> pyrisConnectorService.executeLectureWebhook("fullIngestion", null)).isInstanceOf(exceptionClass);
}
- @Test
- void testOfferedModels() throws Exception {
- irisRequestMockProvider.mockModelsResponse();
+ @ParameterizedTest
+ @EnumSource(IrisSubSettingsType.class)
+ void testOfferedModels(IrisSubSettingsType feature) throws Exception {
+ irisRequestMockProvider.mockVariantsResponse(feature);
- var offeredModels = pyrisConnectorService.getOfferedModels();
+ var offeredModels = pyrisConnectorService.getOfferedVariants(feature);
assertThat(offeredModels).hasSize(1);
assertThat(offeredModels.getFirst().id()).isEqualTo("TEST_MODEL");
}
- @Test
- void testOfferedModelsError() {
- irisRequestMockProvider.mockModelsError();
+ @ParameterizedTest
+ @EnumSource(IrisSubSettingsType.class)
+ void testOfferedModelsError(IrisSubSettingsType feature) {
+ irisRequestMockProvider.mockVariantsError(feature);
- assertThatThrownBy(() -> pyrisConnectorService.getOfferedModels()).isInstanceOf(PyrisConnectorException.class);
+ assertThatThrownBy(() -> pyrisConnectorService.getOfferedVariants(feature)).isInstanceOf(PyrisConnectorException.class);
}
}
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
index 402f6501a3c0..211b0d122d55 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
@@ -17,7 +17,6 @@
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedSettingsDTO;
@@ -56,7 +55,7 @@ void getMissingSettingsForCourse() throws Exception {
assertThat(loadedSettings2).isNotNull().usingRecursiveComparison().ignoringFieldsOfTypes(HashSet.class, TreeSet.class).ignoringActualNullFields()
.isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, false));
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison()
- .ignoringFields("id", "course", "irisChatSettings.id", "iris_lecture_ingestion_settings_id", "irisHestiaSettings.id", "irisCompetencyGenerationSettings.id")
+ .ignoringFields("id", "course", "irisChatSettings.id", "iris_lecture_ingestion_settings_id", "irisCompetencyGenerationSettings.id")
.isEqualTo(irisSettingsService.getDefaultSettingsFor(course));
}
@@ -71,8 +70,8 @@ void getCourseSettings() throws Exception {
var loadedSettings2 = request.get("/api/courses/" + course.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison()
- .ignoringFields("id", "course", "irisChatSettings.id", "irisLectureIngestionSettings.id", "irisHestiaSettings.id", "irisCompetencyGenerationSettings.id")
- .ignoringExpectedNullFields().isEqualTo(loadedSettings2);
+ .ignoringFields("id", "course", "irisChatSettings.id", "irisLectureIngestionSettings.id", "irisCompetencyGenerationSettings.id").ignoringExpectedNullFields()
+ .isEqualTo(loadedSettings2);
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("course")
.isEqualTo(irisSettingsRepository.findCourseSettings(course.getId()).orElseThrow());
}
@@ -87,10 +86,9 @@ void getCourseSettingsAsUser() throws Exception {
request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.FORBIDDEN, IrisSettings.class);
var loadedSettings = request.get("/api/courses/" + course.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
- assertThat(loadedSettings)
- .isNotNull().usingRecursiveComparison().ignoringCollectionOrderInFields("irisChatSettings.allowedModels", "irisLectureIngestionSettings.allowedModels",
- "irisCompetencyGenerationSettings.allowedModels", "irisHestiaSettings.allowedModels")
- .ignoringFields("id").isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, true));
+ assertThat(loadedSettings).isNotNull().usingRecursiveComparison().ignoringCollectionOrderInFields("irisChatSettings.allowedVariants",
+ "irisLectureIngestionSettings.allowedVariants", "irisCompetencyGenerationSettings.allowedVariants").ignoringFields("id")
+ .isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, true));
}
@Test
@@ -103,7 +101,6 @@ void updateCourseSettings1() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
loadedSettings1.getIrisChatSettings().setEnabled(false);
- loadedSettings1.getIrisHestiaSettings().setEnabled(false);
loadedSettings1.getIrisCompetencyGenerationSettings().setEnabled(false);
loadedSettings1.getIrisLectureIngestionSettings().setEnabled(false);
@@ -115,7 +112,6 @@ void updateCourseSettings1() throws Exception {
assertThat(updatedSettings.getId()).isEqualTo(loadedSettings1.getId());
assertThat(updatedSettings.getIrisLectureIngestionSettings().getId()).isEqualTo(loadedSettings1.getIrisLectureIngestionSettings().getId());
assertThat(updatedSettings.getIrisChatSettings().getId()).isEqualTo(loadedSettings1.getIrisChatSettings().getId());
- assertThat(updatedSettings.getIrisHestiaSettings().getId()).isEqualTo(loadedSettings1.getIrisHestiaSettings().getId());
assertThat(updatedSettings.getIrisCompetencyGenerationSettings().getId()).isEqualTo(loadedSettings1.getIrisCompetencyGenerationSettings().getId());
}
@@ -129,12 +125,10 @@ void updateCourseSettings2() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
var chatSubSettingsId = loadedSettings1.getIrisChatSettings().getId();
- var hestiaSubSettingsId = loadedSettings1.getIrisHestiaSettings().getId();
var competencyGenerationSubSettingsId = loadedSettings1.getIrisCompetencyGenerationSettings().getId();
var lectureIngestionSubSettingsId = loadedSettings1.getIrisLectureIngestionSettings().getId();
loadedSettings1.setIrisLectureIngestionSettings(null);
loadedSettings1.setIrisChatSettings(null);
- loadedSettings1.setIrisHestiaSettings(null);
loadedSettings1.setIrisCompetencyGenerationSettings(null);
var updatedSettings = request.putWithResponseBody("/api/courses/" + course.getId() + "/raw-iris-settings", loadedSettings1, IrisSettings.class, HttpStatus.OK);
@@ -145,7 +139,6 @@ void updateCourseSettings2() throws Exception {
// Original subsettings should not exist anymore
assertThat(irisSubSettingsRepository.findById(lectureIngestionSubSettingsId)).isEmpty();
assertThat(irisSubSettingsRepository.findById(chatSubSettingsId)).isEmpty();
- assertThat(irisSubSettingsRepository.findById(hestiaSubSettingsId)).isEmpty();
assertThat(irisSubSettingsRepository.findById(competencyGenerationSubSettingsId)).isEmpty();
}
@@ -159,18 +152,11 @@ void updateCourseSettings3() throws Exception {
courseSettings.setCourse(course);
courseSettings.setIrisChatSettings(new IrisChatSubSettings());
courseSettings.getIrisChatSettings().setEnabled(true);
- courseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisChatSettings().setPreferredModel(null);
-
- courseSettings.setIrisHestiaSettings(new IrisHestiaSubSettings());
- courseSettings.getIrisHestiaSettings().setEnabled(true);
- courseSettings.getIrisHestiaSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisHestiaSettings().setPreferredModel(null);
+ courseSettings.getIrisChatSettings().setSelectedVariant(null);
courseSettings.setIrisCompetencyGenerationSettings(new IrisCompetencyGenerationSubSettings());
courseSettings.getIrisCompetencyGenerationSettings().setEnabled(true);
- courseSettings.getIrisCompetencyGenerationSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisCompetencyGenerationSettings().setPreferredModel(null);
+ courseSettings.getIrisCompetencyGenerationSettings().setSelectedVariant(null);
courseSettings.setIrisLectureIngestionSettings(new IrisLectureIngestionSubSettings());
courseSettings.getIrisLectureIngestionSettings().setEnabled(true);
@@ -179,10 +165,8 @@ void updateCourseSettings3() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
assertThat(updatedSettings).usingRecursiveComparison().ignoringFields("course").isEqualTo(loadedSettings1);
- assertThat(loadedSettings1)
- .usingRecursiveComparison().ignoringFields("id", "course", "irisChatSettings.id", "irisChatSettings.template.id", "irisLectureIngestionSettings.id",
- "irisHestiaSettings.id", "irisHestiaSettings.template.id", "irisCompetencyGenerationSettings.id", "irisCompetencyGenerationSettings.template.id")
- .isEqualTo(courseSettings);
+ assertThat(loadedSettings1).usingRecursiveComparison().ignoringFields("id", "course", "irisChatSettings.id", "irisChatSettings.template.id",
+ "irisLectureIngestionSettings.id", "irisCompetencyGenerationSettings.id", "irisCompetencyGenerationSettings.template.id").isEqualTo(courseSettings);
}
@Test
@@ -214,7 +198,6 @@ void getProgrammingExerciseSettings() throws Exception {
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("id", "exercise", "irisChatSettings.id").ignoringExpectedNullFields()
.isEqualTo(loadedSettings2);
- assertThat(loadedSettings1.getIrisHestiaSettings()).isNull();
assertThat(loadedSettings1.getIrisCompetencyGenerationSettings()).isNull();
assertThat(loadedSettings1.getIrisLectureIngestionSettings()).isNull();
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("exercise")
@@ -233,7 +216,7 @@ void getProgrammingExerciseSettingsAsUser() throws Exception {
var loadedSettings = request.get("/api/programming-exercises/" + programmingExercise.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
assertThat(loadedSettings).isNotNull().usingRecursiveComparison().ignoringFields("id")
- .ignoringCollectionOrderInFields("irisChatSettings.allowedModels", "irisCompetencyGenerationSettings.allowedModels", "irisHestiaSettings.allowedModels")
+ .ignoringCollectionOrderInFields("irisChatSettings.allowedVariants", "irisCompetencyGenerationSettings.allowedVariants")
.isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(programmingExercise, true));
}
@@ -271,7 +254,6 @@ void updateProgrammingExerciseSettings2() throws Exception {
var chatSubSettingsId = loadedSettings1.getIrisChatSettings().getId();
loadedSettings1.setIrisChatSettings(null);
- loadedSettings1.setIrisHestiaSettings(null);
var updatedSettings = request.putWithResponseBody("/api/programming-exercises/" + programmingExercise.getId() + "/raw-iris-settings", loadedSettings1, IrisSettings.class,
HttpStatus.OK);
@@ -294,8 +276,7 @@ void updateProgrammingExerciseSettings3() throws Exception {
exerciseSettings.setExercise(programmingExercise);
exerciseSettings.setIrisChatSettings(new IrisChatSubSettings());
exerciseSettings.getIrisChatSettings().setEnabled(true);
- exerciseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
- exerciseSettings.getIrisChatSettings().setPreferredModel(null);
+ exerciseSettings.getIrisChatSettings().setSelectedVariant(null);
var updatedSettings = request.putWithResponseBody("/api/programming-exercises/" + programmingExercise.getId() + "/raw-iris-settings", exerciseSettings, IrisSettings.class,
HttpStatus.OK);
diff --git a/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
index 0a3bf65f8433..2b36487e4576 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
@@ -1,39 +1,43 @@
import { ArtemisTestModule } from '../../../test.module';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
import { IrisChatSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import { MockDirective, MockPipe } from 'ng-mocks';
import { SimpleChange, SimpleChanges } from '@angular/core';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { mockModels } from './mock-settings';
+import { mockVariants } from './mock-settings';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
+import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
+import { of } from 'rxjs';
function baseSettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const irisSubSettings = new IrisChatSubSettings();
irisSubSettings.id = 2;
irisSubSettings.enabled = true;
- const allowedModels = mockModels();
- allowedModels.pop();
- irisSubSettings.allowedModels = allowedModels.map((model) => model.id!);
- irisSubSettings.preferredModel = allowedModels[0].id!;
+ const allowedVariants = mockVariants();
+ allowedVariants.pop();
+ irisSubSettings.allowedVariants = allowedVariants.map((model) => model.id!);
+ irisSubSettings.selectedVariant = allowedVariants[0].id!;
return irisSubSettings;
}
describe('IrisCommonSubSettingsUpdateComponent Component', () => {
let comp: IrisCommonSubSettingsUpdateComponent;
let fixture: ComponentFixture;
+ let getVariantsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ArtemisTestModule, FormsModule, MockDirective(NgbTooltip), MockPipe(ArtemisTranslatePipe)],
declarations: [IrisCommonSubSettingsUpdateComponent],
- }).compileComponents();
+ })
+ .compileComponents()
+ .then(() => {
+ const irisSettingsService = TestBed.inject(IrisSettingsService);
+ getVariantsSpy = jest.spyOn(irisSettingsService, 'getVariantsForFeature').mockReturnValue(of(mockVariants()));
+ });
fixture = TestBed.createComponent(IrisCommonSubSettingsUpdateComponent);
comp = fixture.componentInstance;
});
@@ -45,28 +49,29 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
it('child setup works', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
+ expect(getVariantsSpy).toHaveBeenCalledOnce();
expect(comp.enabled).toBeTrue();
- expect(comp.inheritAllowedModels).toBeFalse();
- expect(comp.allowedIrisModels).toEqual([mockModels()[0]]);
+ expect(comp.inheritAllowedVariants).toBeFalse();
+ expect(comp.allowedVariants).toEqual([mockVariants()[0]]);
});
it('parent setup works', () => {
const subSettings = baseSettings();
- subSettings.allowedModels = undefined;
- subSettings.preferredModel = undefined;
+ subSettings.allowedVariants = undefined;
+ subSettings.selectedVariant = undefined;
comp.subSettings = subSettings;
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
expect(comp.enabled).toBeTrue();
- expect(comp.inheritAllowedModels).toBeTrue();
- expect(comp.allowedIrisModels).toEqual([mockModels()[0]]);
+ expect(comp.inheritAllowedVariants).toBeTrue();
+ expect(comp.allowedVariants).toEqual([mockVariants()[0]]);
});
it('prevents enabling chat settings if the parent chat settings disabled', () => {
@@ -75,7 +80,7 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
comp.parentSubSettings.enabled = false;
comp.isAdmin = true;
comp.settingsType = IrisSettingsType.EXERCISE;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
fixture.detectChanges();
expect(comp.inheritDisabled).toBeTrue();
@@ -88,7 +93,7 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
comp.parentSubSettings.enabled = false;
comp.isAdmin = true;
comp.settingsType = IrisSettingsType.COURSE;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
fixture.detectChanges();
expect(comp.inheritDisabled).toBeTrue();
@@ -96,34 +101,34 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
});
it('change allowed model', () => {
- const allIrisModels = mockModels();
+ const availableVariants = mockVariants();
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = allIrisModels;
+ comp.availableVariants = availableVariants;
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.onAllowedIrisModelsSelectionChange(allIrisModels[1]);
- expect(comp.allowedIrisModels).toEqual([allIrisModels[0], allIrisModels[1]]);
- comp.onAllowedIrisModelsSelectionChange(allIrisModels[0]);
- expect(comp.allowedIrisModels).toEqual([allIrisModels[1]]);
+ comp.onAllowedIrisVariantsSelectionChange(availableVariants[1]);
+ expect(comp.allowedVariants).toEqual([availableVariants[0], availableVariants[1]]);
+ comp.onAllowedIrisVariantsSelectionChange(availableVariants[0]);
+ expect(comp.allowedVariants).toEqual([availableVariants[1]]);
});
it('change preferred model', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.setModel(mockModels()[1]);
- expect(comp.subSettings!.preferredModel).toBe(mockModels()[1].id);
+ comp.setVariant(mockVariants()[1]);
+ expect(comp.subSettings!.selectedVariant).toBe(mockVariants()[1].id);
});
it('change enabled', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
@@ -139,41 +144,41 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
it('change inherit allowed models', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.inheritAllowedModels = true;
- comp.onInheritAllowedModelsChange();
- expect(comp.subSettings!.allowedModels).toBeUndefined();
- expect(comp.allowedIrisModels).toEqual(comp.getAvailableModels());
+ comp.inheritAllowedVariants = true;
+ comp.onInheritAllowedVariantsChange();
+ expect(comp.subSettings!.allowedVariants).toBeUndefined();
+ expect(comp.allowedVariants).toEqual(comp.getAllowedVariants());
- comp.inheritAllowedModels = false;
- comp.onInheritAllowedModelsChange();
- expect(comp.subSettings!.allowedModels).toEqual(comp.allowedIrisModels.map((model) => model.id));
+ comp.inheritAllowedVariants = false;
+ comp.onInheritAllowedVariantsChange();
+ expect(comp.subSettings!.allowedVariants).toEqual(comp.allowedVariants.map((model) => model.id));
});
it('ngOnChanges works', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
const newSubSettings = baseSettings();
newSubSettings.enabled = false;
- const newModels = mockModels();
+ const newModels = mockVariants();
newModels.pop();
const changes: SimpleChanges = {
subSettings: new SimpleChange(comp.subSettings, newSubSettings, false),
- allIrisModels: new SimpleChange(comp.allIrisModels, newModels, false),
+ availableVariants: new SimpleChange(comp.availableVariants, newModels, false),
};
comp.subSettings = newSubSettings;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.ngOnChanges(changes);
expect(comp.enabled).toBeFalse();
- expect(comp.allowedIrisModels).toEqual(newModels);
+ expect(comp.allowedVariants).toEqual(newModels);
});
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
index 87c4fcb5989d..d31ecbaba114 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { BehaviorSubject, of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockEmptySettings, mockSettings } from './mock-settings';
import { ActivatedRoute, Params, provideRouter } from '@angular/router';
import { NgModel } from '@angular/forms';
@@ -23,7 +22,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
const route = { parent: { params: routeParamsSubject.asObservable() } } as ActivatedRoute;
let paramsSpy: jest.SpyInstance;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
let getParentSettingsSpy: jest.SpyInstance;
beforeEach(() => {
@@ -33,7 +31,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
IrisCourseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -49,7 +46,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
getParentSettingsSpy = jest.spyOn(irisSettingsService, 'getGlobalSettings').mockReturnValue(of(irisSettings));
});
fixture = TestBed.createComponent(IrisCourseSettingsUpdateComponent);
@@ -66,11 +62,9 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
expect(comp.courseId).toBe(1);
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledWith(1);
- //expect(getModelsSpy).toHaveBeenCalledOnce();
expect(getParentSettingsSpy).toHaveBeenCalledOnce();
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeFalsy();
- expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(4);
+ expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(3);
});
it('Can deactivate correctly', () => {
@@ -99,7 +93,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
comp.settingsUpdateComponent!.fillEmptyIrisSubSettings();
expect(comp.settingsUpdateComponent!.irisSettings.irisChatSettings).toBeTruthy();
expect(comp.settingsUpdateComponent!.irisSettings.irisLectureIngestionSettings).toBeTruthy();
- expect(comp.settingsUpdateComponent!.irisSettings.irisHestiaSettings).toBeTruthy();
expect(comp.settingsUpdateComponent!.irisSettings.irisCompetencyGenerationSettings).toBeTruthy();
});
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
index f4aba8617eee..c47b91fdd5b1 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
@@ -47,7 +47,7 @@ describe('IrisEnabledComponent', () => {
expect(comp).toBeDefined();
});
- it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.HESTIA, IrisSubSettingsType.COMPETENCY_GENERATION])('should load exercise', async (subSettingstype) => {
+ it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.COMPETENCY_GENERATION])('should load exercise', async (subSettingstype) => {
const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedProgrammingExerciseSettings').mockReturnValue(of(irisSettings));
comp.exercise = exercise;
comp.irisSubSettingsType = subSettingstype;
@@ -58,19 +58,16 @@ describe('IrisEnabledComponent', () => {
expect(comp.irisSubSettings).toBeDefined();
});
- it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.HESTIA, IrisSubSettingsType.COMPETENCY_GENERATION, IrisSubSettingsType.LECTURE_INGESTION])(
- 'should load course',
- async (subSettingstype) => {
- const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
- comp.course = course;
- comp.irisSubSettingsType = subSettingstype;
- fixture.detectChanges();
- expect(getExerciseSettingsSpy).toHaveBeenCalledOnce();
- await Promise.resolve();
- expect(comp.irisSettings).toBe(irisSettings);
- expect(comp.irisSubSettings).toBeDefined();
- },
- );
+ it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.COMPETENCY_GENERATION, IrisSubSettingsType.LECTURE_INGESTION])('should load course', async (subSettingstype) => {
+ const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
+ comp.course = course;
+ comp.irisSubSettingsType = subSettingstype;
+ fixture.detectChanges();
+ expect(getExerciseSettingsSpy).toHaveBeenCalledOnce();
+ await Promise.resolve();
+ expect(comp.irisSettings).toBe(irisSettings);
+ expect(comp.irisSubSettings).toBeDefined();
+ });
it('should set exercise enabled', async () => {
const setSettingsSpy = jest.spyOn(irisSettingsService, 'setProgrammingExerciseSettings').mockReturnValue(of(new HttpResponse({ body: null as any as IrisSettings })));
@@ -89,8 +86,8 @@ describe('IrisEnabledComponent', () => {
const setSettingsSpy = jest.spyOn(irisSettingsService, 'setCourseSettings').mockReturnValue(of(new HttpResponse({ body: null as any as IrisSettings })));
comp.course = course;
comp.irisSettings = irisSettings;
- comp.irisSubSettingsType = IrisSubSettingsType.HESTIA;
- comp.irisSubSettings = irisSettings.irisHestiaSettings;
+ comp.irisSubSettingsType = IrisSubSettingsType.CHAT;
+ comp.irisSubSettings = irisSettings.irisChatSettings;
comp.setEnabled(true);
expect(setSettingsSpy).toHaveBeenCalledOnce();
diff --git a/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
index 98d0ff3f8770..140940787933 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { BehaviorSubject, of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockSettings } from './mock-settings';
import { IrisExerciseSettingsUpdateComponent } from 'app/iris/settings/iris-exercise-settings-update/iris-exercise-settings-update.component';
import { ActivatedRoute, Params, provideRouter } from '@angular/router';
@@ -23,7 +22,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
const route = { parent: { params: routeParamsSubject.asObservable() } } as ActivatedRoute;
let paramsSpy: jest.SpyInstance;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
let getParentSettingsSpy: jest.SpyInstance;
beforeEach(() => {
@@ -33,7 +31,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
IrisExerciseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -49,7 +46,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedProgrammingExerciseSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
getParentSettingsSpy = jest.spyOn(irisSettingsService, 'getCombinedCourseSettings').mockReturnValue(of(irisSettings));
});
fixture = TestBed.createComponent(IrisExerciseSettingsUpdateComponent);
@@ -67,10 +63,8 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
expect(comp.exerciseId).toBe(2);
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledWith(2);
- //expect(getModelsSpy).toHaveBeenCalledOnce();
expect(getParentSettingsSpy).toHaveBeenCalledWith(1);
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeFalsy();
expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(1);
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
index a00353681299..44783963ac05 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockSettings } from './mock-settings';
import { NgModel } from '@angular/forms';
import { IrisGlobalSettingsUpdateComponent } from 'app/iris/settings/iris-global-settings-update/iris-global-settings-update.component';
@@ -19,7 +18,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
let fixture: ComponentFixture;
let irisSettingsService: IrisSettingsService;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -28,7 +26,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
IrisGlobalSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -41,7 +38,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
// Setup
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getGlobalSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
});
fixture = TestBed.createComponent(IrisGlobalSettingsUpdateComponent);
comp = fixture.componentInstance;
@@ -55,10 +51,8 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
fixture.detectChanges();
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledOnce();
- //expect(getModelsSpy).toHaveBeenCalledOnce();
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeTruthy();
- expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(4);
+ expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(3);
});
it('Can deactivate correctly', () => {
diff --git a/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
index 1c3a6fb751b4..4fe2f213f845 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
@@ -2,12 +2,11 @@ import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testin
import { By } from '@angular/platform-browser';
import { IrisSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-settings-update.component';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
-import { mockSettings } from './mock-settings';
+import { mockSettings, mockVariants } from './mock-settings';
import { ArtemisTestModule } from '../../../test.module';
import { NgModel } from '@angular/forms';
import { MockComponent, MockDirective, MockPipe, MockProvider } from 'ng-mocks';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
import { of } from 'rxjs';
@@ -17,12 +16,12 @@ import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
describe('IrisSettingsUpdateComponent', () => {
let component: IrisSettingsUpdateComponent;
let fixture: ComponentFixture;
+ let getVariantsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ArtemisTestModule],
declarations: [
- IrisGlobalAutoupdateSettingsUpdateComponent,
IrisCourseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
IrisCommonSubSettingsUpdateComponent,
@@ -42,15 +41,12 @@ describe('IrisSettingsUpdateComponent', () => {
.then(() => {
fixture = TestBed.createComponent(IrisSettingsUpdateComponent);
component = fixture.componentInstance;
+
+ const irisSettingsService = TestBed.inject(IrisSettingsService);
+ getVariantsSpy = jest.spyOn(irisSettingsService, 'getVariantsForFeature').mockReturnValue(of(mockVariants()));
});
});
- it('should display global auto-update settings only if settingsType is GLOBAL', () => {
- component.irisSettings = mockSettings();
- component.settingsType = IrisSettingsType.GLOBAL;
- fixture.detectChanges();
- const globalSettingsElement = fixture.debugElement.query(By.css('jhi-iris-global-autoupdate-settings-update'));
- expect(globalSettingsElement).toBeTruthy();
- });
+
it('should display the checkbox for lecture ingestion when settingsType is COURSE', fakeAsync(() => {
component.irisSettings = mockSettings();
component.settingsType = IrisSettingsType.COURSE;
@@ -65,5 +61,6 @@ describe('IrisSettingsUpdateComponent', () => {
expect(lectureIngestionElement).not.toBeNull();
expect(checkboxElement).toBeTruthy();
expect(labelElement).toBeTruthy();
+ expect(getVariantsSpy).toHaveBeenCalled();
}));
});
diff --git a/src/test/javascript/spec/component/iris/settings/mock-settings.ts b/src/test/javascript/spec/component/iris/settings/mock-settings.ts
index f9338cd78cc4..6c542caf9a91 100644
--- a/src/test/javascript/spec/component/iris/settings/mock-settings.ts
+++ b/src/test/javascript/spec/component/iris/settings/mock-settings.ts
@@ -1,51 +1,33 @@
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
export function mockSettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const mockChatSettings = new IrisChatSubSettings();
mockChatSettings.id = 1;
- mockChatSettings.template = mockTemplate;
mockChatSettings.enabled = true;
const mockLectureIngestionSettings = new IrisLectureIngestionSubSettings();
mockLectureIngestionSettings.id = 7;
mockLectureIngestionSettings.enabled = true;
mockLectureIngestionSettings.autoIngestOnLectureAttachmentUpload = true;
- const mockHestiaSettings = new IrisHestiaSubSettings();
- mockHestiaSettings.id = 2;
- mockHestiaSettings.template = mockTemplate;
- mockHestiaSettings.enabled = true;
const mockCompetencyGenerationSettings = new IrisCompetencyGenerationSubSettings();
mockCompetencyGenerationSettings.id = 5;
mockCompetencyGenerationSettings.enabled = false;
const irisSettings = new IrisGlobalSettings();
irisSettings.id = 1;
irisSettings.irisChatSettings = mockChatSettings;
- irisSettings.irisHestiaSettings = mockHestiaSettings;
irisSettings.irisCompetencyGenerationSettings = mockCompetencyGenerationSettings;
irisSettings.irisLectureIngestionSettings = mockLectureIngestionSettings;
return irisSettings;
}
export function mockEmptySettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const irisSettings = new IrisGlobalSettings();
irisSettings.id = 1;
return irisSettings;
}
-export function mockModels() {
+export function mockVariants() {
return [
{
id: '1',
@@ -57,5 +39,5 @@ export function mockModels() {
name: 'Model 2',
description: 'Model 2 Description',
},
- ] as IrisModel[];
+ ] as IrisVariant[];
}