Skip to content

Commit f5e8aa1

Browse files
Merge pull request #50387 from ozangunalp/dev_ui_build_actions_optional_parameter
Allow marking parameters optional in Dev UI buildtime actions
2 parents 7ab0375 + ffb637f commit f5e8aa1

File tree

6 files changed

+85
-15
lines changed

6 files changed

+85
-15
lines changed

extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/buildtime/BuildTimeActionBuildItem.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,17 @@ public ActionBuilder parameter(String name, String description) {
132132
return parameter(name, String.class, description);
133133
}
134134

135+
public ActionBuilder parameter(String name, String description, boolean required) {
136+
return parameter(name, String.class, description, required);
137+
}
138+
135139
public ActionBuilder parameter(String name, Class<?> type, String description) {
136-
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description));
140+
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description, true));
141+
return this;
142+
}
143+
144+
public ActionBuilder parameter(String name, Class<?> type, String description, boolean required) {
145+
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description, required));
137146
return this;
138147
}
139148

@@ -217,8 +226,17 @@ public SubscriptionBuilder parameter(String name, String description) {
217226
return parameter(name, String.class, description);
218227
}
219228

229+
public SubscriptionBuilder parameter(String name, String description, boolean required) {
230+
return parameter(name, String.class, description, required);
231+
}
232+
220233
public SubscriptionBuilder parameter(String name, Class<?> type, String description) {
221-
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description));
234+
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description, true));
235+
return this;
236+
}
237+
238+
public SubscriptionBuilder parameter(String name, Class<?> type, String description, boolean required) {
239+
this.parameters.put(name, new AbstractJsonRpcMethod.Parameter(type, description, required));
222240
return this;
223241
}
224242

extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/buildtime/jsonrpc/AbstractJsonRpcMethod.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,25 @@ public void setParameters(Map<String, Parameter> parameters) {
6464
public void addParameter(String name, String description) {
6565
if (this.parameters == null)
6666
this.parameters = new LinkedHashMap<>();
67-
this.parameters.put(name, new Parameter(String.class, description));
67+
this.parameters.put(name, new Parameter(String.class, description, true));
68+
}
69+
70+
public void addParameter(String name, String description, boolean required) {
71+
if (this.parameters == null)
72+
this.parameters = new LinkedHashMap<>();
73+
this.parameters.put(name, new Parameter(String.class, description, required));
6874
}
6975

7076
public void addParameter(String name, Class<?> type, String description) {
7177
if (this.parameters == null)
7278
this.parameters = new LinkedHashMap<>();
73-
this.parameters.put(name, new Parameter(type, description));
79+
this.parameters.put(name, new Parameter(type, description, true));
80+
}
81+
82+
public void addParameter(String name, Class<?> type, String description, boolean required) {
83+
if (this.parameters == null)
84+
this.parameters = new LinkedHashMap<>();
85+
this.parameters.put(name, new Parameter(type, description, required));
7486
}
7587

7688
public boolean hasParameters() {
@@ -96,14 +108,24 @@ public void setMcpEnabledByDefault(boolean mcpEnabledByDefault) {
96108
public static class Parameter {
97109
private Class<?> type;
98110
private String description;
111+
private boolean required;
99112

100113
public Parameter() {
101114

102115
}
103116

104-
public Parameter(Class<?> type, String description) {
117+
public Parameter(Class<?> type, String description, boolean required) {
105118
this.type = type;
106119
this.description = description;
120+
this.required = required;
121+
}
122+
123+
public boolean isRequired() {
124+
return required;
125+
}
126+
127+
public void setRequired(boolean required) {
128+
this.required = required;
107129
}
108130

109131
public Class<?> getType() {

extensions/devui/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
4545
import io.quarkus.arc.deployment.BeanContainerBuildItem;
4646
import io.quarkus.arc.processor.BuiltinScope;
47+
import io.quarkus.arc.processor.DotNames;
4748
import io.quarkus.bootstrap.BootstrapConstants;
4849
import io.quarkus.deployment.Capabilities;
4950
import io.quarkus.deployment.Capability;
@@ -388,7 +389,12 @@ void findAllJsonRPCMethods(BuildProducer<JsonRPCRuntimeMethodsBuildItem> jsonRPC
388389
Map<String, AbstractJsonRpcMethod.Parameter> parameters = new LinkedHashMap<>(); // Keep the order
389390
for (int i = 0; i < method.parametersCount(); i++) {
390391
String description = null;
392+
boolean required = true;
391393
Type parameterType = method.parameterType(i);
394+
if (DotNames.OPTIONAL.equals(parameterType.name())) {
395+
required = false;
396+
parameterType = parameterType.asParameterizedType().arguments().get(0);
397+
}
392398
AnnotationInstance jsonRpcDescriptionAnnotation = method.parameters().get(i)
393399
.annotation(descriptionAnnotation);
394400
if (jsonRpcDescriptionAnnotation != null) {
@@ -399,7 +405,8 @@ void findAllJsonRPCMethods(BuildProducer<JsonRPCRuntimeMethodsBuildItem> jsonRPC
399405
}
400406
Class<?> parameterClass = toClass(parameterType);
401407
String parameterName = method.parameterName(i);
402-
parameters.put(parameterName, new AbstractJsonRpcMethod.Parameter(parameterClass, description));
408+
parameters.put(parameterName,
409+
new AbstractJsonRpcMethod.Parameter(parameterClass, description, required));
403410
}
404411

405412
// Look for @JsonRpcUsage annotation
@@ -548,7 +555,8 @@ private JsonRpcMethod toJsonRpcMethod(AbstractJsonRpcMethod i) {
548555
o.setMcpEnabledByDefault(i.isMcpEnabledByDefault());
549556
if (i.hasParameters()) {
550557
for (Map.Entry<String, AbstractJsonRpcMethod.Parameter> ip : i.getParameters().entrySet()) {
551-
o.addParameter(ip.getKey(), ip.getValue().getType(), ip.getValue().getDescription());
558+
o.addParameter(ip.getKey(), ip.getValue().getType(), ip.getValue().getDescription(),
559+
ip.getValue().isRequired());
552560
}
553561
}
554562

extensions/devui/resources/src/main/resources/dev-ui/qwc/qwc-dev-mcp-tools.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ export class QwcDevMCPTools extends QwcHotReloadElement {
212212
label="${key}"
213213
helper-text="${prop.inputSchema.properties[key].description}"
214214
placeholder="${prop.inputSchema.properties[key].type}"
215+
?required="${(prop.inputSchema.required ?? []).includes(key)}"
215216
@input=${(e) => this._updateSelectedValue(prop.name, key, e)}
216217
@blur=${(e) => this._updateSelectedValue(prop.name, key, e)}
217218
></vaadin-text-field>

extensions/devui/runtime/src/main/java/io/quarkus/devui/runtime/jsonrpc/JsonRpcMethod.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,25 @@ public void setParameters(Map<String, Parameter> parameters) {
9696
public void addParameter(String name, String description) {
9797
if (this.parameters == null)
9898
this.parameters = new LinkedHashMap<>();
99-
this.parameters.put(name, new Parameter(String.class, description));
99+
this.parameters.put(name, new Parameter(String.class, description, true));
100+
}
101+
102+
public void addParameter(String name, String description, boolean required) {
103+
if (this.parameters == null)
104+
this.parameters = new LinkedHashMap<>();
105+
this.parameters.put(name, new Parameter(String.class, description, required));
100106
}
101107

102108
public void addParameter(String name, Class<?> type, String description) {
103109
if (this.parameters == null)
104110
this.parameters = new LinkedHashMap<>();
105-
this.parameters.put(name, new Parameter(type, description));
111+
this.parameters.put(name, new Parameter(type, description, true));
112+
}
113+
114+
public void addParameter(String name, Class<?> type, String description, boolean required) {
115+
if (this.parameters == null)
116+
this.parameters = new LinkedHashMap<>();
117+
this.parameters.put(name, new Parameter(type, description, required));
106118
}
107119

108120
public boolean hasParameters() {
@@ -152,14 +164,12 @@ public boolean isReturningCompletableFuture() {
152164
public static class Parameter {
153165
private Class<?> type;
154166
private String description;
167+
private boolean required;
155168

156-
public Parameter() {
157-
158-
}
159-
160-
public Parameter(Class<?> type, String description) {
169+
public Parameter(Class<?> type, String description, boolean required) {
161170
this.type = type;
162171
this.description = description;
172+
this.required = required;
163173
}
164174

165175
public Class<?> getType() {
@@ -177,6 +187,15 @@ public String getDescription() {
177187
public void setDescription(String description) {
178188
this.description = description;
179189
}
190+
191+
public boolean isRequired() {
192+
return required;
193+
}
194+
195+
public void setRequired(boolean required) {
196+
this.required = required;
197+
}
198+
180199
}
181200

182201
private static final String UNDERSCORE = "_";

extensions/devui/runtime/src/main/java/io/quarkus/devui/runtime/mcp/McpToolsService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ private Tool toTool(JsonRpcMethod jsonRpcMethod) {
115115
if (p.getDescription() != null && !p.getDescription().isBlank()) {
116116
prop.put("description", p.getDescription());
117117
}
118-
required.add(parameter.getKey()); // TODO: Check for optional here
118+
if (p.isRequired()) {
119+
required.add(parameter.getKey());
120+
}
119121
props.put(parameter.getKey(), prop);
120122

121123
}

0 commit comments

Comments
 (0)