Skip to content

Commit c75ca06

Browse files
committed
feat: Add new fields to conversation api
Signed-off-by: Javier Aliaga <javier@diagrid.io>
1 parent f6c5400 commit c75ca06

11 files changed

+397
-10
lines changed

sdk/src/main/java/io/dapr/client/DaprClientImpl.java

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@
4242
import io.dapr.client.domain.ConversationResponseAlpha2;
4343
import io.dapr.client.domain.ConversationResultAlpha2;
4444
import io.dapr.client.domain.ConversationResultChoices;
45+
import io.dapr.client.domain.ConversationResultCompletionUsage;
46+
import io.dapr.client.domain.ConversationResultCompletionUsageDetails;
4547
import io.dapr.client.domain.ConversationResultMessage;
48+
import io.dapr.client.domain.ConversationResultPromptUsageDetails;
4649
import io.dapr.client.domain.ConversationToolCalls;
4750
import io.dapr.client.domain.ConversationToolCallsOfFunction;
4851
import io.dapr.client.domain.ConversationTools;
@@ -1793,6 +1796,7 @@ public Mono<ConversationResponseAlpha2> converseAlpha2(ConversationRequestAlpha2
17931796
DaprAiProtos.ConversationResponseAlpha2 conversationResponse = conversationResponseMono.block();
17941797

17951798
assert conversationResponse != null;
1799+
17961800
List<ConversationResultAlpha2> results = buildConversationResults(conversationResponse.getOutputsList());
17971801
return Mono.just(new ConversationResponseAlpha2(conversationResponse.getContextId(), results));
17981802
} catch (Exception ex) {
@@ -1857,6 +1861,33 @@ private DaprAiProtos.ConversationRequestAlpha2 buildConversationRequestProto(Con
18571861

18581862
builder.addInputs(inputBuilder.build());
18591863
}
1864+
1865+
if (request.getResponseFormat() != null) {
1866+
Map<String, Value> responseParams = request.getResponseFormat()
1867+
.entrySet().stream()
1868+
.collect(Collectors.toMap(
1869+
Map.Entry::getKey,
1870+
e -> {
1871+
try {
1872+
return ProtobufValueHelper.toProtobufValue(e.getValue());
1873+
} catch (IOException ex) {
1874+
throw new RuntimeException(ex);
1875+
}
1876+
}
1877+
));
1878+
1879+
builder.setResponseFormat(Struct.newBuilder().putAllFields(responseParams).build());
1880+
}
1881+
1882+
if (request.getPromptCacheRetention() != null) {
1883+
Duration javaDuration = request.getPromptCacheRetention();
1884+
builder.setPromptCacheRetention(
1885+
com.google.protobuf.Duration.newBuilder()
1886+
.setSeconds(javaDuration.getSeconds())
1887+
.setNanos(javaDuration.getNano())
1888+
.build()
1889+
);
1890+
}
18601891

18611892
return builder.build();
18621893
}
@@ -1974,14 +2005,38 @@ private List<ConversationResultAlpha2> buildConversationResults(
19742005
for (DaprAiProtos.ConversationResultChoices protoChoice : protoResult.getChoicesList()) {
19752006
ConversationResultMessage message = buildConversationResultMessage(protoChoice);
19762007
choices.add(new ConversationResultChoices(protoChoice.getFinishReason(), protoChoice.getIndex(), message));
1977-
}
2008+
}
19782009

1979-
results.add(new ConversationResultAlpha2(choices));
2010+
results.add(new ConversationResultAlpha2(
2011+
choices,
2012+
protoResult.getModel(),
2013+
getConversationResultCompletionUsage(protoResult))
2014+
);
19802015
}
19812016

19822017
return results;
19832018
}
19842019

2020+
private static ConversationResultCompletionUsage getConversationResultCompletionUsage(
2021+
DaprAiProtos.ConversationResultAlpha2 protoResult) {
2022+
var usage = new ConversationResultCompletionUsage(
2023+
protoResult.getUsage().getCompletionTokens(),
2024+
protoResult.getUsage().getPromptTokens(),
2025+
protoResult.getUsage().getTotalTokens());
2026+
2027+
usage.setCompletionTokenDetails(new ConversationResultCompletionUsageDetails(
2028+
protoResult.getUsage().getCompletionTokensDetails().getAcceptedPredictionTokens(),
2029+
protoResult.getUsage().getCompletionTokensDetails().getAudioTokens(),
2030+
protoResult.getUsage().getCompletionTokensDetails().getReasoningTokens(),
2031+
protoResult.getUsage().getCompletionTokensDetails().getRejectedPredictionTokens()));
2032+
2033+
usage.setPromptTokenDetails(new ConversationResultPromptUsageDetails(
2034+
protoResult.getUsage().getPromptTokensDetails().getAudioTokens(),
2035+
protoResult.getUsage().getPromptTokensDetails().getCachedTokens()
2036+
));
2037+
return usage;
2038+
}
2039+
19852040
private ConversationResultMessage buildConversationResultMessage(DaprAiProtos.ConversationResultChoices protoChoice) {
19862041
if (!protoChoice.hasMessage()) {
19872042
return null;

sdk/src/main/java/io/dapr/client/DaprPreviewClient.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,15 @@
1717
import io.dapr.client.domain.BulkPublishRequest;
1818
import io.dapr.client.domain.BulkPublishResponse;
1919
import io.dapr.client.domain.BulkPublishResponseFailedEntry;
20-
import io.dapr.client.domain.CloudEvent;
2120
import io.dapr.client.domain.ConversationRequest;
2221
import io.dapr.client.domain.ConversationRequestAlpha2;
2322
import io.dapr.client.domain.ConversationResponse;
2423
import io.dapr.client.domain.ConversationResponseAlpha2;
2524
import io.dapr.client.domain.DecryptRequestAlpha1;
26-
import io.dapr.client.domain.DeleteJobRequest;
2725
import io.dapr.client.domain.EncryptRequestAlpha1;
28-
import io.dapr.client.domain.GetJobRequest;
29-
import io.dapr.client.domain.GetJobResponse;
3026
import io.dapr.client.domain.LockRequest;
3127
import io.dapr.client.domain.QueryStateRequest;
3228
import io.dapr.client.domain.QueryStateResponse;
33-
import io.dapr.client.domain.ScheduleJobRequest;
3429
import io.dapr.client.domain.UnlockRequest;
3530
import io.dapr.client.domain.UnlockResponseStatus;
3631
import io.dapr.client.domain.query.Query;

sdk/src/main/java/io/dapr/client/domain/ConversationOutput.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
package io.dapr.client.domain;
1515

16-
import java.util.Collections;
1716
import java.util.Map;
1817

1918
/**

sdk/src/main/java/io/dapr/client/domain/ConversationRequestAlpha2.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package io.dapr.client.domain;
1515

16+
import java.time.Duration;
1617
import java.util.List;
1718
import java.util.Map;
1819

@@ -31,6 +32,8 @@ public class ConversationRequestAlpha2 {
3132
private String toolChoice;
3233
private Map<String, Object> parameters;
3334
private Map<String, String> metadata;
35+
private Map<String, Object> responseFormat;
36+
private Duration promptCacheRetention;
3437

3538
/**
3639
* Constructs a ConversationRequestAlpha2 with a component name and conversation inputs.
@@ -206,4 +209,22 @@ public ConversationRequestAlpha2 setMetadata(Map<String, String> metadata) {
206209
this.metadata = metadata;
207210
return this;
208211
}
212+
213+
public Map<String, Object> getResponseFormat() {
214+
return responseFormat;
215+
}
216+
217+
public ConversationRequestAlpha2 setResponseFormat(Map<String, Object> responseFormat) {
218+
this.responseFormat = responseFormat;
219+
return this;
220+
}
221+
222+
public Duration getPromptCacheRetention() {
223+
return promptCacheRetention;
224+
}
225+
226+
public ConversationRequestAlpha2 setPromptCacheRetention(Duration promptCacheRetention) {
227+
this.promptCacheRetention = promptCacheRetention;
228+
return this;
229+
}
209230
}

sdk/src/main/java/io/dapr/client/domain/ConversationResponse.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
package io.dapr.client.domain;
1515

16-
import java.util.Collections;
1716
import java.util.List;
1817

1918
/**

sdk/src/main/java/io/dapr/client/domain/ConversationResultAlpha2.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,22 @@
2121
public class ConversationResultAlpha2 {
2222

2323
private final List<ConversationResultChoices> choices;
24+
private final String model;
25+
private final ConversationResultCompletionUsage usage;
2426

2527
/**
2628
* Constructor.
2729
*
2830
* @param choices the list of conversation result choices.
31+
* @param model the model used for the conversation.
32+
* @param usage the usage of the model.
2933
*/
30-
public ConversationResultAlpha2(List<ConversationResultChoices> choices) {
34+
public ConversationResultAlpha2(List<ConversationResultChoices> choices,
35+
String model,
36+
ConversationResultCompletionUsage usage) {
3137
this.choices = List.copyOf(choices);
38+
this.model = model;
39+
this.usage = usage;
3240
}
3341

3442
/**
@@ -39,4 +47,22 @@ public ConversationResultAlpha2(List<ConversationResultChoices> choices) {
3947
public List<ConversationResultChoices> getChoices() {
4048
return choices;
4149
}
50+
51+
/**
52+
* Gets the model used for the conversation.
53+
*
54+
* @return the model used for the conversation.
55+
*/
56+
public String getModel() {
57+
return model;
58+
}
59+
60+
/**
61+
* Gets the usage of the model.
62+
*
63+
* @return the usage of the model.
64+
*/
65+
public ConversationResultCompletionUsage getUsage() {
66+
return usage;
67+
}
4268
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2026 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.client.domain;
15+
16+
public class ConversationResultCompletionUsage {
17+
private final long completionTokens;
18+
private final long promptTokens;
19+
private final long totalTokens;
20+
21+
private ConversationResultCompletionUsageDetails completionTokenDetails;
22+
private ConversationResultPromptUsageDetails promptTokenDetails;
23+
24+
/**
25+
* Constructor.
26+
*
27+
* @param completionTokens completion tokens used.
28+
* @param promptTokens prompt tokens used.
29+
* @param totalTokens total tokens used.
30+
*/
31+
public ConversationResultCompletionUsage(long completionTokens, long promptTokens, long totalTokens) {
32+
this.completionTokens = completionTokens;
33+
this.promptTokens = promptTokens;
34+
this.totalTokens = totalTokens;
35+
}
36+
37+
/**
38+
* Completion tokens used.
39+
*
40+
* @return completion tokens used.
41+
*/
42+
public long getCompletionTokens() {
43+
return completionTokens;
44+
}
45+
46+
/**
47+
* Prompt tokens used.
48+
*
49+
* @return prompt tokens used.
50+
*/
51+
public long getPromptTokens() {
52+
return promptTokens;
53+
}
54+
55+
/**
56+
* Total tokens used.
57+
*
58+
* @return total tokens used.
59+
*/
60+
public long getTotalTokens() {
61+
return totalTokens;
62+
}
63+
64+
/**
65+
* Completion token details.
66+
*
67+
* @return the completionTokenDetails
68+
*/
69+
public ConversationResultCompletionUsageDetails getCompletionTokenDetails() {
70+
return completionTokenDetails;
71+
}
72+
73+
/**
74+
* Completion token details.
75+
*
76+
* @param completionTokenDetails the completionTokenDetails to set
77+
*/
78+
public void setCompletionTokenDetails(ConversationResultCompletionUsageDetails completionTokenDetails) {
79+
this.completionTokenDetails = completionTokenDetails;
80+
}
81+
82+
/**
83+
* Prompt token details.
84+
*
85+
* @return the promptTokenDetails
86+
*/
87+
public ConversationResultPromptUsageDetails getPromptTokenDetails() {
88+
return promptTokenDetails;
89+
}
90+
91+
/**
92+
* Prompt token details.
93+
*
94+
* @param promptTokenDetails the promptTokenDetails to set
95+
*/
96+
public void setPromptTokenDetails(ConversationResultPromptUsageDetails promptTokenDetails) {
97+
this.promptTokenDetails = promptTokenDetails;
98+
}
99+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2026 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.client.domain;
15+
16+
public class ConversationResultCompletionUsageDetails {
17+
private final long acceptedPredictionTokens;
18+
private final long audioTokens;
19+
private final long reasoningTokens;
20+
private final long rejectedPredictionTokens;
21+
22+
/**
23+
* Constructor.
24+
*
25+
* @param acceptedPredictionTokens accepted prediction tokens used.
26+
* @param audioTokens audio tokens used.
27+
* @param reasoningTokens reasoning tokens used.
28+
* @param rejectedPredictionTokens rejected prediction tokens used.
29+
*/
30+
public ConversationResultCompletionUsageDetails(long acceptedPredictionTokens, long audioTokens,
31+
long reasoningTokens, long rejectedPredictionTokens) {
32+
this.acceptedPredictionTokens = acceptedPredictionTokens;
33+
this.audioTokens = audioTokens;
34+
this.reasoningTokens = reasoningTokens;
35+
this.rejectedPredictionTokens = rejectedPredictionTokens;
36+
}
37+
38+
/**
39+
* Accepted prediction tokens used.
40+
*
41+
* @return accepted prediction tokens used.
42+
*/
43+
public long getAcceptedPredictionTokens() {
44+
return acceptedPredictionTokens;
45+
}
46+
47+
/**
48+
* Audio tokens used.
49+
*
50+
* @return audio tokens used.
51+
*/
52+
public long getAudioTokens() {
53+
return audioTokens;
54+
}
55+
56+
/**
57+
* Reasoning tokens used.
58+
*
59+
* @return reasoning tokens used.
60+
*/
61+
public long getReasoningTokens() {
62+
return reasoningTokens;
63+
}
64+
65+
/**
66+
* Rejected prediction tokens used.
67+
*
68+
* @return rejected prediction tokens used.
69+
*/
70+
public long getRejectedPredictionTokens() {
71+
return rejectedPredictionTokens;
72+
}
73+
}

0 commit comments

Comments
 (0)