Skip to content

Commit c4edfd8

Browse files
Introduce new assistant module and added openapi as an example usage
Signed-off-by: Phillip Kruger <[email protected]>
1 parent 60ae080 commit c4edfd8

File tree

17 files changed

+638
-9
lines changed

17 files changed

+638
-9
lines changed

bom/application/pom.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,16 @@
594594
</dependency>
595595

596596
<!-- Quarkus libraries -->
597-
597+
<dependency>
598+
<groupId>io.quarkus</groupId>
599+
<artifactId>quarkus-assistant</artifactId>
600+
<version>${project.version}</version>
601+
</dependency>
602+
<dependency>
603+
<groupId>io.quarkus</groupId>
604+
<artifactId>quarkus-assistant-deployment</artifactId>
605+
<version>${project.version}</version>
606+
</dependency>
598607
<dependency>
599608
<groupId>io.quarkus</groupId>
600609
<artifactId>quarkus-caffeine</artifactId>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>quarkus-assistant-parent</artifactId>
7+
<groupId>io.quarkus</groupId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>quarkus-assistant-deployment</artifactId>
13+
<name>Quarkus - Assistant - Deployment</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>io.quarkus</groupId>
18+
<artifactId>quarkus-assistant</artifactId>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>io.quarkus</groupId>
23+
<artifactId>quarkus-core-deployment</artifactId>
24+
</dependency>
25+
26+
<!-- Test -->
27+
<dependency>
28+
<groupId>io.quarkus</groupId>
29+
<artifactId>quarkus-junit5-internal</artifactId>
30+
<scope>test</scope>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.assertj</groupId>
34+
<artifactId>assertj-core</artifactId>
35+
<scope>test</scope>
36+
</dependency>
37+
</dependencies>
38+
39+
<build>
40+
<plugins>
41+
<plugin>
42+
<artifactId>maven-compiler-plugin</artifactId>
43+
<executions>
44+
<execution>
45+
<id>default-compile</id>
46+
<configuration>
47+
<annotationProcessorPaths>
48+
<path>
49+
<groupId>io.quarkus</groupId>
50+
<artifactId>quarkus-extension-processor</artifactId>
51+
<version>${project.version}</version>
52+
</path>
53+
</annotationProcessorPaths>
54+
</configuration>
55+
</execution>
56+
</executions>
57+
</plugin>
58+
</plugins>
59+
</build>
60+
</project>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.quarkus.assistant.deployment;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Optional;
7+
import java.util.concurrent.CompletionStage;
8+
9+
/**
10+
* This is the Assistant for Quarkus Dev Mode. The actual implementation will be provided by another extension (eg. Chappie)
11+
* If there is an extension that provide a concrete implementation of this, it will be available in the AssistantBuildItem,
12+
* so to use it, add Optional<AssistantBuildItem> assistantBuildItem in your BuildStep.
13+
*/
14+
public interface Assistant {
15+
// Exception
16+
default <T> CompletionStage<T> exception(String userMessage, String stacktrace, Path path) {
17+
return exception(Optional.empty(), userMessage, stacktrace, path);
18+
}
19+
20+
public <T> CompletionStage<T> exception(Optional<String> systemMessage, String userMessage, String stacktrace,
21+
Path path);
22+
23+
// Generic assist
24+
default <T> CompletionStage<T> assist(String userMessage) {
25+
return assist(Optional.empty(), userMessage, Map.of());
26+
}
27+
28+
default <T> CompletionStage<T> assist(Optional<String> systemMessage, String userMessage) {
29+
return assist(systemMessage, userMessage, Map.of());
30+
}
31+
32+
default <T> CompletionStage<T> assist(String userMessageTemplate, Map<String, String> variables) {
33+
return assist(Optional.empty(), userMessageTemplate, variables);
34+
}
35+
36+
default <T> CompletionStage<T> assist(Optional<String> systemMessageTemplate, String userMessageTemplate,
37+
Map<String, String> variables) {
38+
return assist(systemMessageTemplate, userMessageTemplate, variables, List.of());
39+
}
40+
41+
/**
42+
* Assist the developer with something
43+
*
44+
* @param <T> The response
45+
* @param systemMessageTemplate System wide context
46+
* @param userMessageTemplate User specific context
47+
* @param variables variables that can be used in the templates
48+
* @param paths Paths to workspace files (optional)
49+
* @return
50+
*/
51+
public <T> CompletionStage<T> assist(Optional<String> systemMessageTemplate,
52+
String userMessageTemplate,
53+
Map<String, String> variables, List<Path> paths);
54+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.quarkus.assistant.deployment;
2+
3+
import io.quarkus.builder.item.SimpleBuildItem;
4+
5+
/**
6+
* If available, a handle on the Assistant
7+
*
8+
* This is intended for use in dev mode to enable AI-enhanced development
9+
*/
10+
public final class AssistantBuildItem extends SimpleBuildItem {
11+
private final Assistant assistant;
12+
13+
public AssistantBuildItem(Assistant assistant) {
14+
this.assistant = assistant;
15+
}
16+
17+
public Assistant getAssistant() {
18+
return assistant;
19+
}
20+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package io.quarkus.assistant.deployment;
2+
3+
import java.util.Map;
4+
import java.util.Optional;
5+
import java.util.concurrent.CompletionStage;
6+
import java.util.function.Function;
7+
import java.util.function.Supplier;
8+
9+
import io.quarkus.builder.item.MultiBuildItem;
10+
import io.quarkus.deployment.console.ConsoleCommand;
11+
import io.quarkus.deployment.dev.testing.MessageFormat;
12+
13+
/**
14+
* Add a menu item in the Assistant console menu
15+
*/
16+
public final class AssistantConsoleBuildItem extends MultiBuildItem {
17+
private final ConsoleCommand consoleCommand;
18+
19+
private final String description;
20+
private final char key;
21+
private final Optional<String> systemMessage;
22+
private final String userMessage;
23+
private final Supplier<String> colorSupplier;
24+
private final Supplier<String> stateSupplier;
25+
private final Map<String, String> variables;
26+
private final Optional<Function<Assistant, CompletionStage<?>>> function;
27+
28+
public AssistantConsoleBuildItem(ConsoleCommand consoleCommand) {
29+
this.consoleCommand = consoleCommand;
30+
this.function = Optional.empty();
31+
this.description = consoleCommand.getDescription();
32+
this.key = consoleCommand.getKey();
33+
this.systemMessage = Optional.empty();
34+
this.userMessage = null;
35+
this.colorSupplier = consoleCommand.getHelpState().getColorSupplier();
36+
this.stateSupplier = consoleCommand.getHelpState().getStateSupplier();
37+
this.variables = Map.of();
38+
}
39+
40+
private AssistantConsoleBuildItem(Builder builder) {
41+
this.description = builder.description;
42+
this.key = builder.key;
43+
this.systemMessage = builder.systemMessage;
44+
this.userMessage = builder.userMessage;
45+
this.colorSupplier = builder.colorSupplier;
46+
this.stateSupplier = builder.stateSupplier;
47+
this.variables = builder.variables;
48+
this.consoleCommand = null;
49+
this.function = builder.function;
50+
}
51+
52+
public static Builder builder() {
53+
return new Builder();
54+
}
55+
56+
public static class Builder {
57+
private String description;
58+
private char key = Character.MIN_VALUE;
59+
private Optional<String> systemMessage = Optional.empty();
60+
private String userMessage;
61+
private Supplier<String> colorSupplier = new Supplier<String>() {
62+
@Override
63+
public String get() {
64+
return MessageFormat.RESET;
65+
}
66+
};
67+
private Supplier<String> stateSupplier = null;
68+
private Map<String, String> variables = Map.of();
69+
private Optional<Function<Assistant, CompletionStage<?>>> function = Optional.empty();
70+
71+
public Builder description(String description) {
72+
this.description = description;
73+
return this;
74+
}
75+
76+
public Builder key(char key) {
77+
this.key = key;
78+
return this;
79+
}
80+
81+
public Builder systemMessage(String systemMessage) {
82+
this.systemMessage = Optional.of(systemMessage);
83+
return this;
84+
}
85+
86+
public Builder userMessage(String userMessage) {
87+
this.userMessage = userMessage;
88+
return this;
89+
}
90+
91+
public Builder colorSupplier(Supplier<String> colorSupplier) {
92+
this.colorSupplier = colorSupplier;
93+
return this;
94+
}
95+
96+
public Builder stateSupplier(Supplier<String> stateSupplier) {
97+
this.stateSupplier = stateSupplier;
98+
return this;
99+
}
100+
101+
public Builder variables(Map<String, String> variables) {
102+
this.variables = variables;
103+
return this;
104+
}
105+
106+
public Builder function(Function<Assistant, CompletionStage<?>> function) {
107+
this.function = Optional.of(function);
108+
return this;
109+
}
110+
111+
public AssistantConsoleBuildItem build() {
112+
if (key == Character.MIN_VALUE) {
113+
throw new IllegalStateException(
114+
"You have to specify a key. This is the key the user will press to get to your function");
115+
}
116+
if (description == null || description.isBlank()) {
117+
throw new IllegalStateException(
118+
"You have to specify a description. This is what the user will see in the console menu");
119+
}
120+
if (userMessage == null && !function.isPresent()) {
121+
throw new IllegalStateException(
122+
"You have to specify userMessage that will be send to AI, or implement your own using the function");
123+
}
124+
125+
return new AssistantConsoleBuildItem(this);
126+
}
127+
}
128+
129+
public ConsoleCommand getConsoleCommand() {
130+
return consoleCommand;
131+
}
132+
133+
public String getDescription() {
134+
return consoleCommand != null ? consoleCommand.getDescription() : description;
135+
}
136+
137+
public char getKey() {
138+
return key;
139+
}
140+
141+
public Optional<String> getSystemMessage() {
142+
return systemMessage;
143+
}
144+
145+
public String getUserMessage() {
146+
return userMessage;
147+
}
148+
149+
public Supplier<String> getColorSupplier() {
150+
return consoleCommand != null ? consoleCommand.getHelpState().getColorSupplier() : colorSupplier;
151+
}
152+
153+
public Supplier<String> getStateSupplier() {
154+
return consoleCommand != null ? consoleCommand.getHelpState().getStateSupplier() : stateSupplier;
155+
}
156+
157+
public Map<String, String> getVariables() {
158+
return variables;
159+
}
160+
161+
public Optional<Function<Assistant, CompletionStage<?>>> getFunction() {
162+
return function;
163+
}
164+
}

extensions/assistant/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>quarkus-extensions-parent</artifactId>
7+
<groupId>io.quarkus</groupId>
8+
<version>999-SNAPSHOT</version>
9+
<relativePath>../pom.xml</relativePath>
10+
</parent>
11+
<modelVersion>4.0.0</modelVersion>
12+
13+
<artifactId>quarkus-assistant-parent</artifactId>
14+
<name>Quarkus - Assistant</name>
15+
<packaging>pom</packaging>
16+
<modules>
17+
<module>deployment</module>
18+
<module>runtime</module>
19+
</modules>
20+
21+
</project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>quarkus-assistant-parent</artifactId>
7+
<groupId>io.quarkus</groupId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>quarkus-assistant</artifactId>
13+
<name>Quarkus - Assistant - Runtime</name>
14+
<description>AI Assistant for Quarkus Dev mode</description>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>io.quarkus</groupId>
19+
<artifactId>quarkus-core</artifactId>
20+
</dependency>
21+
</dependencies>
22+
23+
<build>
24+
<plugins>
25+
<plugin>
26+
<groupId>io.quarkus</groupId>
27+
<artifactId>quarkus-extension-maven-plugin</artifactId>
28+
<configuration>
29+
<capabilities>
30+
<provides>io.quarkus.assistant</provides>
31+
</capabilities>
32+
</configuration>
33+
</plugin>
34+
<plugin>
35+
<artifactId>maven-compiler-plugin</artifactId>
36+
<executions>
37+
<execution>
38+
<id>default-compile</id>
39+
<configuration>
40+
<annotationProcessorPaths>
41+
<path>
42+
<groupId>io.quarkus</groupId>
43+
<artifactId>quarkus-extension-processor</artifactId>
44+
<version>${project.version}</version>
45+
</path>
46+
</annotationProcessorPaths>
47+
</configuration>
48+
</execution>
49+
</executions>
50+
</plugin>
51+
</plugins>
52+
</build>
53+
</project>

0 commit comments

Comments
 (0)