Skip to content

Commit cf823f8

Browse files
committed
Add autocomplete hints for ESQL function parameters
1 parent 7b36f9e commit cf823f8

File tree

7 files changed

+107
-39
lines changed

7 files changed

+107
-39
lines changed

docs/reference/query-languages/esql/_snippets/functions/examples/text_embedding.md

Lines changed: 2 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/text_embedding.json

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/docs/functions/text_embedding.md

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,24 +610,52 @@ public static String normalizeName(String name) {
610610
}
611611

612612
public static class ArgSignature {
613+
614+
public record AutocompleteHint(String entityType, Map<String, String> constraints) {}
615+
613616
protected final String name;
614617
protected final String[] type;
615618
protected final String description;
616619
protected final boolean optional;
617620
protected final boolean variadic;
618621
protected final DataType targetDataType;
619-
620-
public ArgSignature(String name, String[] type, String description, boolean optional, boolean variadic, DataType targetDataType) {
622+
protected final AutocompleteHint autocompleteHint;
623+
624+
public ArgSignature(
625+
String name,
626+
String[] type,
627+
String description,
628+
boolean optional,
629+
boolean variadic,
630+
AutocompleteHint autocompleteHint,
631+
DataType targetDataType
632+
) {
621633
this.name = name;
622634
this.type = type;
623635
this.description = description;
624636
this.optional = optional;
625637
this.variadic = variadic;
626638
this.targetDataType = targetDataType;
639+
this.autocompleteHint = autocompleteHint;
640+
}
641+
642+
public ArgSignature(
643+
String name,
644+
String[] type,
645+
String description,
646+
boolean optional,
647+
AutocompleteHint autocompleteHint,
648+
boolean variadic
649+
) {
650+
this(name, type, description, optional, variadic, autocompleteHint, UNSUPPORTED);
651+
}
652+
653+
public ArgSignature(String name, String[] type, String description, boolean optional, boolean variadic, DataType targetDataType) {
654+
this(name, type, description, optional, variadic, null, targetDataType);
627655
}
628656

629657
public ArgSignature(String name, String[] type, String description, boolean optional, boolean variadic) {
630-
this(name, type, description, optional, variadic, UNSUPPORTED);
658+
this(name, type, description, optional, variadic, null, UNSUPPORTED);
631659
}
632660

633661
public String name() {
@@ -810,7 +838,25 @@ public static ArgSignature param(Param param, boolean variadic) {
810838
String[] type = removeUnderConstruction(param.type());
811839
String desc = param.description().replace('\n', ' ');
812840
DataType targetDataType = getTargetType(type);
813-
return new EsqlFunctionRegistry.ArgSignature(param.name(), type, desc, param.optional(), variadic, targetDataType);
841+
ArgSignature.AutocompleteHint autocompleteHint = null;
842+
if (param.autocompleteHint() != null && param.autocompleteHint().entityType() != Param.AutocompleteHint.ENTITY_TYPE.NONE) {
843+
Map<String, String> constraints = Arrays.stream(param.autocompleteHint().constraints())
844+
.collect(Collectors.toMap(Param.AutocompleteHint.Constraint::name, Param.AutocompleteHint.Constraint::value));
845+
autocompleteHint = new ArgSignature.AutocompleteHint(
846+
param.autocompleteHint().entityType().name().toLowerCase(Locale.ROOT),
847+
constraints
848+
);
849+
}
850+
851+
return new EsqlFunctionRegistry.ArgSignature(
852+
param.name(),
853+
type,
854+
desc,
855+
param.optional(),
856+
variadic,
857+
autocompleteHint,
858+
targetDataType
859+
);
814860
}
815861

816862
public static ArgSignature mapParam(MapParam mapParam) {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/Param.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package org.elasticsearch.xpack.esql.expression.function;
99

10+
import org.elasticsearch.core.Nullable;
11+
1012
import java.lang.annotation.ElementType;
1113
import java.lang.annotation.Retention;
1214
import java.lang.annotation.RetentionPolicy;
@@ -25,4 +27,28 @@
2527
String description() default "";
2628

2729
boolean optional() default false;
30+
31+
@Nullable
32+
AutocompleteHint autocompleteHint() default @AutocompleteHint(entityType = AutocompleteHint.ENTITY_TYPE.NONE);
33+
34+
@Retention(RetentionPolicy.RUNTIME)
35+
@Target(ElementType.PARAMETER)
36+
@interface AutocompleteHint {
37+
enum ENTITY_TYPE {
38+
NONE,
39+
INFERENCE_ENDPOINT,
40+
}
41+
42+
ENTITY_TYPE entityType();
43+
44+
Constraint[] constraints() default {};
45+
46+
@Retention(RetentionPolicy.RUNTIME)
47+
@Target(ElementType.PARAMETER)
48+
@interface Constraint {
49+
String name();
50+
51+
String value();
52+
}
53+
}
2854
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/inference/TextEmbedding.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,7 @@ public class TextEmbedding extends InferenceFunction<TextEmbedding> {
4848
preview = true,
4949
examples = {
5050
@Example(
51-
description = "Basic text embedding generation from a text string using an inference endpoint.",
52-
file = "text-embedding",
53-
tag = "text-embedding-eval"
54-
),
55-
@Example(
56-
description = "Generate text embeddings and store them in a variable for reuse in KNN vector search queries.",
57-
file = "text-embedding",
58-
tag = "text-embedding-knn"
59-
),
60-
@Example(
61-
description = "Directly embed text within a KNN query for streamlined vector search without intermediate variables.",
51+
description = "Generate text embeddings using the 'test_dense_inference' inference endpoint.",
6252
file = "text-embedding",
6353
tag = "text-embedding-knn-inline"
6454
) }
@@ -75,7 +65,11 @@ public TextEmbedding(
7565
type = { "keyword" },
7666
description = "Identifier of an existing inference endpoint the that will generate the embeddings. "
7767
+ "The inference endpoint must have the `text_embedding` task type and should use the same model "
78-
+ "that was used to embed your indexed data."
68+
+ "that was used to embed your indexed data.",
69+
autocompleteHint = @Param.AutocompleteHint(
70+
entityType = Param.AutocompleteHint.ENTITY_TYPE.INFERENCE_ENDPOINT,
71+
constraints = { @Param.AutocompleteHint.Constraint(name = "task_type", value = "text_embedding") }
72+
)
7973
) Expression inferenceId
8074
) {
8175
super(source, List.of(inputText, inferenceId));
@@ -109,7 +103,7 @@ public boolean foldable() {
109103

110104
@Override
111105
public DataType dataType() {
112-
return inputText.dataType() == DataType.NULL ? DataType.NULL : DataType.DENSE_VECTOR;
106+
return DataType.DENSE_VECTOR;
113107
}
114108

115109
@Override

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ private void renderDocs(FunctionDefinition definition) throws Exception {
622622
trueValue.type(),
623623
"The value that’s returned when no condition evaluates to `true`.",
624624
true,
625+
null,
625626
true
626627
);
627628
description = new EsqlFunctionRegistry.FunctionDescription(
@@ -1382,6 +1383,18 @@ void renderKibanaFunctionDefinition(
13821383
builder.field("optional", arg.optional());
13831384
String cleanedParamDesc = removeAppliesToBlocks(arg.description());
13841385
builder.field("description", cleanedParamDesc);
1386+
if (arg.autocompleteHint != null) {
1387+
builder.startObject("autocompleteHint");
1388+
builder.field("entityType", arg.autocompleteHint.entityType());
1389+
if (arg.autocompleteHint.constraints() != null && arg.autocompleteHint.constraints().size() > 0) {
1390+
builder.startObject("constraints");
1391+
for (Map.Entry<String, String> constraint : arg.autocompleteHint.constraints().entrySet()) {
1392+
builder.field(constraint.getKey(), constraint.getValue());
1393+
}
1394+
builder.endObject();
1395+
}
1396+
builder.endObject();
1397+
}
13851398
builder.endObject();
13861399
}
13871400
builder.endArray();

0 commit comments

Comments
 (0)