Skip to content

Commit 3d4f273

Browse files
Address more review comments
1 parent 3656419 commit 3d4f273

File tree

3 files changed

+68
-48
lines changed

3 files changed

+68
-48
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/InferenceFeatureSetUsage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public int hashCode() {
6666
return Objects.hashCode(modelStats);
6767
}
6868

69-
public Collection<ModelStats> modelStats() {
69+
Collection<ModelStats> modelStats() {
7070
return modelStats;
7171
}
7272
}

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/action/TransportInferenceUsageAction.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.elasticsearch.cluster.metadata.Metadata;
2020
import org.elasticsearch.cluster.service.ClusterService;
2121
import org.elasticsearch.common.Strings;
22-
import org.elasticsearch.core.Nullable;
2322
import org.elasticsearch.inference.ModelConfigurations;
2423
import org.elasticsearch.inference.TaskType;
2524
import org.elasticsearch.injection.guice.Inject;
@@ -100,6 +99,10 @@ private InferenceFeatureSetUsage collectUsage(List<ModelConfigurations> endpoint
10099
return new InferenceFeatureSetUsage(endpointStats.values());
101100
}
102101

102+
/**
103+
* Returns a map whose keys are the inference service and task_type and the values are maps of index names to inference fields.
104+
* Inference fields in system or hidden indices are excluded.
105+
*/
103106
private static Map<ServiceAndTaskType, Map<String, List<InferenceFieldMetadata>>> mapInferenceFieldsByIndexServiceAndTask(
104107
Iterable<IndexMetadata> indicesMetadata,
105108
List<ModelConfigurations> endpoints
@@ -128,6 +131,11 @@ private static Map<ServiceAndTaskType, Map<String, List<InferenceFieldMetadata>>
128131
return inferenceFieldByIndexServiceAndTask;
129132
}
130133

134+
/**
135+
* Adds inference usage stats for each service and task type combination.
136+
* In addition, adds aggregate usage stats per task type across all services.
137+
* Those aggregate stats have "_all" as the service name.
138+
*/
131139
private static void addStatsByServiceAndTask(
132140
Map<ServiceAndTaskType, Map<String, List<InferenceFieldMetadata>>> inferenceFieldsByIndexServiceAndTask,
133141
List<ModelConfigurations> endpoints,
@@ -187,6 +195,12 @@ private static void addSemanticTextStats(Map<String, List<InferenceFieldMetadata
187195
stat.semanticTextStats().setInferenceIdCount(inferenceIds.size());
188196
}
189197

198+
/**
199+
* Adds stats for default models. In particular, default models are considered models that are
200+
* associated with default inference endpoints as per the {@code ModelRegistry}. The service name
201+
* for default model stats is "_{service}_{modelId}". Each of those stats contains usage for all
202+
* endpoints that use that model, including non-default endpoints.
203+
*/
190204
private void addStatsForDefaultModels(
191205
Map<ServiceAndTaskType, Map<String, List<InferenceFieldMetadata>>> inferenceFieldsByIndexServiceAndTask,
192206
List<ModelConfigurations> endpoints,
@@ -202,6 +216,8 @@ private void addStatsForDefaultModels(
202216
new ServiceAndTaskType(statKey.service, statKey.taskType),
203217
Map.of()
204218
);
219+
// Now that we have all inference fields for this service and task type, we want to keep only the ones that
220+
// reference the current default model.
205221
fieldsByIndex = filterFields(fieldsByIndex, f -> statKey.modelId.equals(endpointIdToModelId.get(f.getInferenceId())));
206222
ModelStats stats = new ModelStats(statKey.toString(), statKey.taskType, defaultModelStatsKeyToEndpointCount.getValue());
207223
addSemanticTextStats(fieldsByIndex, stats);
@@ -210,6 +226,9 @@ private void addStatsForDefaultModels(
210226
}
211227

212228
private Map<DefaultModelStatsKey, Long> createDefaultStatsKeysWithEndpointCounts(List<ModelConfigurations> endpoints) {
229+
// We consider models to be default if they are associated with a default inference endpoint.
230+
// Note that endpoints could have a null model id, in which case we don't consider them default as this
231+
// may only happen for external services.
213232
Set<String> modelIds = endpoints.stream()
214233
.filter(endpoint -> modelRegistry.containsDefaultConfigId(endpoint.getInferenceEntityId()))
215234
.filter(endpoint -> endpoint.getServiceSettings().modelId() != null)
@@ -242,8 +261,7 @@ private static Map<String, List<InferenceFieldMetadata>> filterFields(
242261
return filtered;
243262
}
244263

245-
@Nullable
246-
private static String stripLinuxSuffix(@Nullable String modelId) {
264+
private static String stripLinuxSuffix(String modelId) {
247265
if (modelId.endsWith(MODEL_ID_LINUX_SUFFIX)) {
248266
return modelId.substring(0, modelId.length() - MODEL_ID_LINUX_SUFFIX.length());
249267
}

x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/action/TransportInferenceUsageActionTests.java

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565

6666
public class TransportInferenceUsageActionTests extends ESTestCase {
6767

68+
private static final SemanticTextStats EMPTY_SEMANTIC_TEXT_STATS = new SemanticTextStats();
69+
6870
private Client client;
6971
private ModelRegistry modelRegistry;
7072
private ClusterState clusterState;
@@ -110,14 +112,14 @@ public void testGivenServices_NoInferenceFields() throws Exception {
110112
XContentSource response = executeAction();
111113

112114
assertThat(response.getValue("models"), hasSize(8));
113-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
114-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
115-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
116-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 3, new SemanticTextStats()));
117-
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 3, new SemanticTextStats()));
118-
assertStats(response, 5, new ModelStats("hugging_face_elser", TaskType.SPARSE_EMBEDDING, 2, new SemanticTextStats()));
119-
assertStats(response, 6, new ModelStats("openai", TaskType.SPARSE_EMBEDDING, 1, new SemanticTextStats()));
120-
assertStats(response, 7, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 3, new SemanticTextStats()));
115+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
116+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
117+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
118+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 3, EMPTY_SEMANTIC_TEXT_STATS));
119+
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 3, EMPTY_SEMANTIC_TEXT_STATS));
120+
assertStats(response, 5, new ModelStats("hugging_face_elser", TaskType.SPARSE_EMBEDDING, 2, EMPTY_SEMANTIC_TEXT_STATS));
121+
assertStats(response, 6, new ModelStats("openai", TaskType.SPARSE_EMBEDDING, 1, EMPTY_SEMANTIC_TEXT_STATS));
122+
assertStats(response, 7, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 3, EMPTY_SEMANTIC_TEXT_STATS));
121123
}
122124

123125
public void testGivenFieldRefersToMissingInferenceEndpoint() throws Exception {
@@ -127,11 +129,11 @@ public void testGivenFieldRefersToMissingInferenceEndpoint() throws Exception {
127129
XContentSource response = executeAction();
128130

129131
assertThat(response.getValue("models"), hasSize(5));
130-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
131-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
132-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
133-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
134-
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 0, new SemanticTextStats()));
132+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
133+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
134+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
135+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
136+
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
135137
}
136138

137139
public void testGivenVariousServicesAndInferenceFields() throws Exception {
@@ -175,9 +177,9 @@ public void testGivenVariousServicesAndInferenceFields() throws Exception {
175177
XContentSource response = executeAction();
176178

177179
assertThat(response.getValue("models"), hasSize(8));
178-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
179-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
180-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
180+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
181+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
182+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
181183
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
182184
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 5, new SemanticTextStats(9, 3, 4)));
183185
assertStats(response, 5, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 3, new SemanticTextStats(3, 3, 2)));
@@ -220,9 +222,9 @@ public void testGivenServices_InferenceFieldsReferencingDefaultModels() throws E
220222
XContentSource response = executeAction();
221223

222224
assertThat(response.getValue("models"), hasSize(12));
223-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
224-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
225-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
225+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
226+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
227+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
226228
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 2, new SemanticTextStats(4, 2, 2)));
227229
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 3, new SemanticTextStats(6, 2, 2)));
228230
assertStats(response, 5, new ModelStats("_eis__model-id-001", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
@@ -231,7 +233,7 @@ public void testGivenServices_InferenceFieldsReferencingDefaultModels() throws E
231233
assertStats(response, 8, new ModelStats("eis", TaskType.SPARSE_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
232234
assertStats(response, 9, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
233235
assertStats(response, 10, new ModelStats("openai", TaskType.SPARSE_EMBEDDING, 1, new SemanticTextStats(3, 2, 1)));
234-
assertStats(response, 11, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats()));
236+
assertStats(response, 11, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 1, EMPTY_SEMANTIC_TEXT_STATS));
235237
}
236238

237239
public void testGivenDefaultModelWithLinuxSuffix() throws Exception {
@@ -262,10 +264,10 @@ public void testGivenDefaultModelWithLinuxSuffix() throws Exception {
262264
XContentSource response = executeAction();
263265

264266
assertThat(response.getValue("models"), hasSize(7));
265-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
266-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
267-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
268-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
267+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
268+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
269+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
270+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
269271
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
270272
assertStats(response, 5, new ModelStats("_eis__model-id-001", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
271273
assertStats(response, 6, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
@@ -299,10 +301,10 @@ public void testGivenSameDefaultModelWithAndWithoutLinuxSuffix() throws Exceptio
299301
XContentSource response = executeAction();
300302

301303
assertThat(response.getValue("models"), hasSize(7));
302-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
303-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
304-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
305-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
304+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
305+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
306+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
307+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
306308
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
307309
assertStats(response, 5, new ModelStats("_eis__model-id-001", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
308310
assertStats(response, 6, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(6, 2, 2)));
@@ -315,10 +317,10 @@ public void testGivenExternalServiceModelIsNull() throws Exception {
315317
XContentSource response = executeAction();
316318

317319
assertThat(response.getValue("models"), hasSize(6));
318-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
319-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
320-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
321-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
320+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
321+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
322+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
323+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
322324
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
323325
assertStats(response, 5, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
324326
}
@@ -347,10 +349,10 @@ public void testGivenDuplicateServices() throws Exception {
347349
XContentSource response = executeAction();
348350

349351
assertThat(response.getValue("models"), hasSize(6));
350-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
351-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
352-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
353-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
352+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
353+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
354+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
355+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
354356
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(5, 2, 2)));
355357
assertStats(response, 5, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(5, 2, 2)));
356358
}
@@ -381,10 +383,10 @@ public void testShouldExcludeSystemIndexFields() throws Exception {
381383
XContentSource response = executeAction();
382384

383385
assertThat(response.getValue("models"), hasSize(7));
384-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
385-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
386-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
387-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
386+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
387+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
388+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
389+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
388390
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(2, 1, 2)));
389391
assertStats(response, 5, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
390392
assertStats(response, 6, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
@@ -416,10 +418,10 @@ public void testShouldExcludeHiddenIndexFields() throws Exception {
416418
XContentSource response = executeAction();
417419

418420
assertThat(response.getValue("models"), hasSize(7));
419-
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, new SemanticTextStats()));
420-
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, new SemanticTextStats()));
421-
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, new SemanticTextStats()));
422-
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, new SemanticTextStats()));
421+
assertStats(response, 0, new ModelStats("_all", TaskType.CHAT_COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
422+
assertStats(response, 1, new ModelStats("_all", TaskType.COMPLETION, 0, EMPTY_SEMANTIC_TEXT_STATS));
423+
assertStats(response, 2, new ModelStats("_all", TaskType.RERANK, 0, EMPTY_SEMANTIC_TEXT_STATS));
424+
assertStats(response, 3, new ModelStats("_all", TaskType.SPARSE_EMBEDDING, 0, EMPTY_SEMANTIC_TEXT_STATS));
423425
assertStats(response, 4, new ModelStats("_all", TaskType.TEXT_EMBEDDING, 2, new SemanticTextStats(2, 1, 2)));
424426
assertStats(response, 5, new ModelStats("eis", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));
425427
assertStats(response, 6, new ModelStats("openai", TaskType.TEXT_EMBEDDING, 1, new SemanticTextStats(1, 1, 1)));

0 commit comments

Comments
 (0)