Skip to content

Development: Initialize new Hyperion module for programming exercise creation assistance and migrate functionality from Iris #11047

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 35 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
46b6282
feat: Add Hyperion integration for problem statement rewriting and co…
FelixTJDietrich Jun 22, 2025
b474286
feat: Update build configuration for Edutelligence Hyperion integrati…
FelixTJDietrich Jun 24, 2025
14aaa91
feat: Add GitHub authentication for Maven repositories in Dockerfile …
FelixTJDietrich Jun 24, 2025
8f50919
feat: Implement base service for Hyperion gRPC operations with except…
FelixTJDietrich Jun 24, 2025
2bd5aaf
fix: Use secrets for GITHUB_TOKEN in Docker build args
FelixTJDietrich Jun 24, 2025
5487471
chore: trigger CI - test Hyperion integration
FelixTJDietrich Jun 24, 2025
4a2b2ac
fix: use github.token instead of secrets.GITHUB_TOKEN in reusable wor…
FelixTJDietrich Jun 24, 2025
17abce5
fix: inherit secrets for Docker build in GitHub Actions workflow
FelixTJDietrich Jun 24, 2025
0e70993
TODO: REMOVE!
FelixTJDietrich Jun 24, 2025
110571a
fix: replace reusable Docker workflow with embedded one for proper Gi…
FelixTJDietrich Jun 24, 2025
16ee5b5
fix: update Docker build process to use reusable workflow and inherit…
FelixTJDietrich Jun 24, 2025
b11dfcd
fix: update Docker build to use github.GITHUB_TOKEN for authentication
FelixTJDietrich Jun 24, 2025
07327be
fix: update Docker build to use secrets.GITHUB_TOKEN for authentication
FelixTJDietrich Jun 24, 2025
d809307
fix: refactor Docker build process to use matrix strategy and improve…
FelixTJDietrich Jun 24, 2025
edcd30e
fix: refine conditional checks for pull request repository validation…
FelixTJDietrich Jun 24, 2025
fc5cd5e
fix: enable Hyperion profile by default and remove deprecated Hyperio…
FelixTJDietrich Jun 24, 2025
a3634d7
switch from java client dependency to plugin integration with spec
FelixTJDietrich Jun 27, 2025
01bd1d6
Merge branch 'develop' into feature/hyperion/initialize-service
FelixTJDietrich Jun 27, 2025
48b97a0
add generated files and spec to module
FelixTJDietrich Jun 28, 2025
a1072be
use grpc starter
FelixTJDietrich Jun 28, 2025
b41d614
remove generated code
FelixTJDietrich Jul 8, 2025
a081337
update docs and other minor things
FelixTJDietrich Jul 8, 2025
b523016
update labeler
FelixTJDietrich Jul 8, 2025
ad6f19b
update config
FelixTJDietrich Jul 8, 2025
e0d21b6
remove accidentally restored health indicator
FelixTJDietrich Jul 8, 2025
b34ca3c
handle grpc status
FelixTJDietrich Jul 8, 2025
61da625
remove doc
FelixTJDietrich Jul 8, 2025
fc22d20
start with starter removal
FelixTJDietrich Jul 10, 2025
3af84a1
fully revert back to code without starter except for tests
FelixTJDietrich Jul 10, 2025
c5bc3ec
update docs
FelixTJDietrich Jul 10, 2025
e0aa179
cleanup
FelixTJDietrich Jul 10, 2025
87ce14d
Merge branch 'develop' into feature/hyperion/initialize-service
FelixTJDietrich Jul 10, 2025
70b8f4b
fix client
FelixTJDietrich Jul 10, 2025
2fb5621
delete api arch test
FelixTJDietrich Jul 10, 2025
7d47eff
update test config profile
FelixTJDietrich Jul 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/src/main/java/de/tum/cit/aet/artemis/atlas @ls1intum/atlas-maintainers
/src/main/java/de/tum/cit/aet/artemis/buildagent @ls1intum/programming-maintainers
/src/main/java/de/tum/cit/aet/artemis/communication @ls1intum/communication-maintainers
/src/main/java/de/tum/cit/aet/artemis/hyperion @ls1intum/hyperion-maintainers
/src/main/java/de/tum/cit/aet/artemis/iris @ls1intum/iris-maintainers
/src/main/java/de/tum/cit/aet/artemis/lecture @ls1intum/lectures-maintainers
/src/main/java/de/tum/cit/aet/artemis/lti @ls1intum/lti-maintainers
Expand All @@ -31,6 +32,7 @@
/src/main/webapp/app/atlas @ls1intum/atlas-maintainers
/src/main/webapp/app/buildagent @ls1intum/programming-maintainers
/src/main/webapp/app/communication @ls1intum/communication-maintainers
/src/main/webapp/app/hyperion @ls1intum/hyperion-maintainers
/src/main/webapp/app/iris @ls1intum/iris-maintainers
/src/main/webapp/app/lecture @ls1intum/lectures-maintainers
/src/main/webapp/app/lti @ls1intum/lti-maintainers
Expand All @@ -44,6 +46,7 @@
/src/test/java/de/tum/cit/aet/artemis/atlas @ls1intum/atlas-maintainers
/src/test/java/de/tum/cit/aet/artemis/buildagent @ls1intum/programming-maintainers
/src/test/java/de/tum/cit/aet/artemis/communication @ls1intum/communication-maintainers
/src/test/java/de/tum/cit/aet/artemis/hyperion @ls1intum/hyperion-maintainers
/src/test/java/de/tum/cit/aet/artemis/iris @ls1intum/iris-maintainers
/src/test/java/de/tum/cit/aet/artemis/lecture @ls1intum/lectures-maintainers
/src/test/java/de/tum/cit/aet/artemis/lti @ls1intum/lti-maintainers
Expand Down
6 changes: 6 additions & 0 deletions .github/issue-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ iris:
- \b(?<!\S)ai(?!\S)\b
- caseSensitive: false

hyperion:
- hyperion
- consistency check
- exercise generation
- caseSensitive: false

lecture:
- lecture
- attachment
Expand Down
7 changes: 7 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ iris:
- src/test/java/de/tum/cit/aet/artemis/iris/**/*
- src/main/webapp/app/iris/**/*

hyperion:
- changed-files:
- any-glob-to-any-file:
- src/main/java/de/tum/cit/aet/artemis/hyperion/**/*
- src/test/java/de/tum/cit/aet/artemis/hyperion/**/*
- src/main/webapp/app/hyperion/**/*

lecture:
- changed-files:
- any-glob-to-any-file:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Artemis integrates with the [EduTelligence suite](https://github.com/ls1intum/ed

* **Iris** - AI Virtual Tutor powered by Pyris for intelligent student assistance
* **Athena** - Automated assessment system for text, modeling, and programming exercises
* **Hyperion** - AI-powered programming exercise creation assistance

Additional services are available in the EduTelligence suite for advanced deployments. For detailed information about all available services, please refer to the [EduTelligence repository](https://github.com/ls1intum/edutelligence).

Expand Down Expand Up @@ -145,6 +146,7 @@ The following members of the project management team are responsible for specifi
| Atlas | Maximilian Anzinger ([@maximiliananzinger](https://github.com/maximiliananzinger)) |
| Iris | Patrick Bassner ([@bassner](https://github.com/bassner)) |
| Athena | Maximilian Sölch ([@maximiliansoelch](https://github.com/maximiliansoelch)) |
| Hyperion | Felix Dietrich ([@FelixTJDietrich](https://github.com/FelixTJDietrich)) |
| Tutorial Groups | Ramona Beinstingel ([@rabeatwork](https://github.com/rabeatwork)) |
| Plagiarism checks | Markus Paulsen ([@MarkusPaulsen](https://github.com/MarkusPaulsen)) |
| LTI | Maximilian Anzinger ([@maximiliananzinger](https://github.com/maximiliananzinger)) |
Expand Down
31 changes: 30 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ plugins {
id "org.liquibase.gradle" version "${liquibase_plugin_version}"
id "org.owasp.dependencycheck" version "12.1.3"
id "org.springframework.boot" version "${spring_boot_version}"
id "com.google.protobuf" version "${protobuf_plugin_version}"
}

group = "de.tum.cit.aet.artemis"
Expand Down Expand Up @@ -151,6 +152,23 @@ configurations.configureEach {
exclude group: "commons-configuration", module: "commons-configuration"
}

// Protobuf Configuration for gRPC Integration
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protobuf_version}"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpc_version}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}

dependencies {

// Required by Spring cloud
Expand Down Expand Up @@ -284,6 +302,13 @@ dependencies {
// Avoid outdated version of netty to prevent security issues
implementation("net.minidev:json-smart") { version {strictly "2.5.2" } }

// gRPC Client Dependencies
implementation platform("io.grpc:grpc-bom:${grpc_version}")
implementation 'io.grpc:grpc-protobuf'
implementation 'io.grpc:grpc-stub'
implementation 'io.grpc:grpc-netty-shaded'
implementation "com.google.protobuf:protobuf-java:${protobuf_version}"
implementation 'javax.annotation:javax.annotation-api:1.3.2'

// Required for synchronization between nodes and build agents (LocalCI)
implementation "com.hazelcast:hazelcast:${hazelcast_version}"
Expand Down Expand Up @@ -406,8 +431,8 @@ dependencies {
runtimeOnly "commons-beanutils:commons-beanutils:1.11.0"
checkstyle "commons-beanutils:commons-beanutils:1.11.0"


implementation "com.google.errorprone:error_prone_annotations:2.39.0"
implementation "io.grpc:grpc-services:${grpc_services_version}"

// NOTE: we want to keep the same unique version for all configurations, implementation and annotationProcessor
implementation("net.bytebuddy:byte-buddy") { version { strictly byte_buddy_version } }
Expand Down Expand Up @@ -451,6 +476,10 @@ dependencies {
testImplementation "org.apache.maven.surefire:surefire-report-parser:3.5.3"
testImplementation "io.zonky.test:embedded-database-spring-test:2.6.0"

// gRPC testing dependencies
testImplementation "io.grpc:grpc-inprocess:${grpc_services_version}"
testImplementation "io.grpc:grpc-services:${grpc_services_version}"

testImplementation "com.tngtech.archunit:archunit:1.4.1"
testImplementation "org.skyscreamer:jsonassert:1.5.3"

Expand Down
2 changes: 1 addition & 1 deletion docs/dev/development-process/development-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Naming Conventions for GitHub Pull Requests

1. Possible feature tags are: ``Programming exercises``, ``Integrated code lifecycle``, ``Quiz exercises``, ``Modeling exercises``, ``Text exercises``, ``File upload exercises``, ``Exam mode``,
``Grading``, ``Assessment``, ``Communication``, ``Notifications``, ``Team exercises``, ``Lectures``, ``Integrated markdown editor``, ``Plagiarism checks``, ``Learning analytics``,
``Adaptive learning``, ``Learning path``, ``Tutorial groups``, ``Iris``, ``Scalability``, ``Usability``, ``Performance``, ``Infrastructure``, ``Mobile apps``.
``Adaptive learning``, ``Learning path``, ``Tutorial groups``, ``Iris``, ``Hyperion``, ``Scalability``, ``Usability``, ``Performance``, ``Infrastructure``, ``Mobile apps``.
2. If the change is not visible to end users, or it is a pure development or test improvement, we use the term ``Development``:.
3. Everything else belongs to the ``General`` category.

Expand Down
58 changes: 58 additions & 0 deletions docs/dev/setup/server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ You only need to modify them if your specific work or production environments re
athena:
# If you want to use Athena, refer to the dedicated configuration section. Under Administration Guide, Setup of Extension Services.

hyperion:
# If you want to use Hyperion for programming exercise creation assistance, configure the service connection below.
# For production, enable TLS and configure certificates. See Hyperion Service section below.
host: localhost
port: 50051
use-tls: false

**Note:**
If you use a password for authentication, update it in ``gradle/liquibase.gradle``.

Expand Down Expand Up @@ -106,6 +113,8 @@ module replacement in the client.
``dev,jenkins,localvc,artemis,scheduling,core,atlas,local``.
* **Artemis (Server, LocalVC & LocalCI, Athena):** The server will be started separated from the client with ``athena`` profile and Local VC / CI enabled
(see `Athena Service <#athena-service>`__).
* **Artemis (Server, LocalVC & LocalCI, Hyperion):** The server will be started separated from the client with ``hyperion`` profile and Local VC / CI enabled
(see `Hyperion Service <#hyperion-service>`__).
* **Artemis (Server, LocalVC & LocalCI, Theia):** The server will be started separated from the client with ``theia`` profile and Local VC / CI enabled.
* **Artemis (BuildAgent):** The server will be started separated from the client with the profiles ``buildagent,local``.
This configuration is used to run the build agent for the local CI. This configuration is rarely needed for development.
Expand Down Expand Up @@ -250,3 +259,52 @@ sure to pass the active profiles to the ``gradlew`` command like this:
.. code:: bash

./gradlew bootRun --args='--spring.profiles.active=dev,jenkins,localvc,artemis,scheduling'

.. _hyperion-service:

Hyperion Service
^^^^^^^^^^^^^^^^

Hyperion is an AI-powered Edutelligence microservice for programming exercise creation assistance. To enable Hyperion:

1. **Setup Hyperion Service** (external dependency)

- Deploy Hyperion service separately (see Hyperion documentation)
- Ensure it's accessible from Artemis server

2. **Configure Connection**

Update ``application-local.yml`` (for development):

.. code-block:: yaml

artemis:
hyperion:
host: localhost # Hyperion service host
port: 50051 # Hyperion gRPC port
use-tls: false # Disable TLS for development

For production, enable TLS in ``application-artemis.yml``:

.. code-block:: yaml

artemis:
hyperion:
host: hyperion.domain.com
port: 50051
use-tls: true
client-cert-path: "/certs/artemis-client.crt"
client-key-path: "/certs/artemis-client.key"
server-ca-path: "/certs/hyperion-ca.crt"

3. **Enable Profile**

Add ``hyperion`` to active profiles:

.. code-block:: bash

./gradlew bootRun --args='--spring.profiles.active=dev,localci,localvc,artemis,hyperion'

4. **Verify Setup**

Check health endpoint: ``http://localhost:8080/actuator/health/hyperion``
6 changes: 6 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ netty_version=4.1.118.Final
mysql_version=9.3.0
micrometer_version=1.15.1

# protobuf and gRPC versions for Edutelligence integration
protobuf_plugin_version=0.9.5
protobuf_version=4.31.1
grpc_version=1.73.0
grpc_services_version=1.71.0

# testing
# make sure both versions are compatible
junit_version=5.13.2
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.tum.cit.aet.artemis;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_HYPERION;
import static de.tum.cit.aet.artemis.core.config.Constants.UPLOADS_FILE_PATH_DEFAULT;
import static de.tum.cit.aet.artemis.core.config.Constants.UPLOADS_FILE_PATH_PROPERTY_NAME;
import static tech.jhipster.config.JHipsterConstants.SPRING_PROFILE_DEVELOPMENT;
Expand Down Expand Up @@ -78,6 +79,8 @@ public void initApplication() {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(ArtemisApp.class);
DefaultProfileUtil.addDefaultProfile(app);
// Enable Hyperion profile by default TODO: REMOVE!!!!!!!!!!!!!!!!!!!!!!!!!!
app.setAdditionalProfiles(PROFILE_HYPERION);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO REMOVE

var context = app.run(args);
Environment env = context.getEnvironment();
String fileUploadPath = env.getProperty(UPLOADS_FILE_PATH_PROPERTY_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ public final class Constants {
*/
public static final String PROFILE_ATHENA = "athena";

/**
* The name of the Spring profile used for Hyperion functionality.
*/
public static final String PROFILE_HYPERION = "hyperion";

/**
* The name of the Spring profile used for Athena functionality.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package de.tum.cit.aet.artemis.hyperion.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

/**
* Configuration properties for Hyperion gRPC client.
*/
@Configuration
@ConfigurationProperties(prefix = "artemis.hyperion")
@Lazy
public class HyperionConfigurationProperties {

private String host = "localhost";

private int port = 50051;

private boolean useTls = false;

// mTLS client certificate authentication - required when TLS is enabled
private String clientCertPath = "";

private String clientKeyPath = "";

private String serverCaPath = "";

private int defaultTimeoutSeconds = 60;

private int consistencyCheckTimeoutSeconds = 300;

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public int getPort() {
return port;
}

public void setPort(int port) {
this.port = port;
}

public boolean isUseTls() {
return useTls;
}

public void setUseTls(boolean useTls) {
this.useTls = useTls;
}

public String getClientCertPath() {
return clientCertPath;
}

public void setClientCertPath(String clientCertPath) {
this.clientCertPath = clientCertPath;
}

public String getClientKeyPath() {
return clientKeyPath;
}

public void setClientKeyPath(String clientKeyPath) {
this.clientKeyPath = clientKeyPath;
}

public String getServerCaPath() {
return serverCaPath;
}

public void setServerCaPath(String serverCaPath) {
this.serverCaPath = serverCaPath;
}

public int getDefaultTimeoutSeconds() {
return defaultTimeoutSeconds;
}

public void setDefaultTimeoutSeconds(int defaultTimeoutSeconds) {
this.defaultTimeoutSeconds = defaultTimeoutSeconds;
}

public int getConsistencyCheckTimeoutSeconds() {
return consistencyCheckTimeoutSeconds;
}

public void setConsistencyCheckTimeoutSeconds(int consistencyCheckTimeoutSeconds) {
this.consistencyCheckTimeoutSeconds = consistencyCheckTimeoutSeconds;
}

@Override
public String toString() {
return "HyperionConfigurationProperties{" + "host='" + host + '\'' + ", port=" + port + ", useTls=" + useTls + ", clientCertPath='"
+ (clientCertPath != null && !clientCertPath.isEmpty() ? "[CONFIGURED]" : "not set") + '\'' + ", clientKeyPath='"
+ (clientKeyPath != null && !clientKeyPath.isEmpty() ? "[CONFIGURED]" : "not set") + '\'' + ", serverCaPath='"
+ (serverCaPath != null && !serverCaPath.isEmpty() ? "[CONFIGURED]" : "not set") + '\'' + ", defaultTimeoutSeconds=" + defaultTimeoutSeconds
+ ", consistencyCheckTimeoutSeconds=" + consistencyCheckTimeoutSeconds + '}';
}

/**
* Validates that when TLS is enabled, all certificate paths are configured.
* For production, mTLS with client certificates is required when TLS is enabled.
*
* @return true if TLS configuration is valid, false otherwise
*/
public boolean isValidTlsConfiguration() {
if (!useTls) {
return true; // No TLS, no cert requirements
}

// When TLS is enabled, require all certificate paths for mTLS
return clientCertPath != null && !clientCertPath.isEmpty() && clientKeyPath != null && !clientKeyPath.isEmpty() && serverCaPath != null && !serverCaPath.isEmpty();
}
}
Loading
Loading