conversation ai

Signed-off-by: sirivarma <siri.varma@outlook.com>
This commit is contained in:
sirivarma 2025-08-02 22:29:54 -07:00
parent 90e65314af
commit 795e1cd697
15 changed files with 1125 additions and 1 deletions

View File

@ -17,6 +17,7 @@ import com.google.common.base.Strings;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.Empty;
import com.google.protobuf.Message;
import io.dapr.client.domain.ActorMetadata;
import io.dapr.client.domain.AppConnectionPropertiesHealthMetadata;
import io.dapr.client.domain.AppConnectionPropertiesMetadata;
@ -27,10 +28,22 @@ import io.dapr.client.domain.BulkPublishResponseFailedEntry;
import io.dapr.client.domain.CloudEvent;
import io.dapr.client.domain.ComponentMetadata;
import io.dapr.client.domain.ConfigurationItem;
import io.dapr.client.domain.ConversationFunction;
import io.dapr.client.domain.ConversationInput;
import io.dapr.client.domain.ConversationInputAlpha2;
import io.dapr.client.domain.ConversationMessage;
import io.dapr.client.domain.ConversationMessageContent;
import io.dapr.client.domain.ConversationOutput;
import io.dapr.client.domain.ConversationRequest;
import io.dapr.client.domain.ConversationRequestAlpha2;
import io.dapr.client.domain.ConversationResponse;
import io.dapr.client.domain.ConversationResponseAlpha2;
import io.dapr.client.domain.ConversationResultAlpha2;
import io.dapr.client.domain.ConversationResultChoices;
import io.dapr.client.domain.ConversationResultMessage;
import io.dapr.client.domain.ConversationToolCalls;
import io.dapr.client.domain.ConversationToolCallsFunction;
import io.dapr.client.domain.ConversationTools;
import io.dapr.client.domain.DaprMetadata;
import io.dapr.client.domain.DeleteJobRequest;
import io.dapr.client.domain.DeleteStateRequest;
@ -100,6 +113,7 @@ import reactor.util.context.ContextView;
import reactor.util.retry.Retry;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
@ -1628,6 +1642,193 @@ public class DaprClientImpl extends AbstractDaprClient {
}
}
/**
* {@inheritDoc}
*/
@Override
public Mono<ConversationResponseAlpha2> converseAlpha2(ConversationRequestAlpha2 conversationRequestAlpha2) {
try {
validateConversationRequestAlpha2(conversationRequestAlpha2);
DaprProtos.ConversationRequestAlpha2.Builder protosConversationRequestBuilder =
DaprProtos.ConversationRequestAlpha2
.newBuilder()
.setTemperature(conversationRequestAlpha2.getTemperature())
.setScrubPii(conversationRequestAlpha2.isScrubPii())
.setName(conversationRequestAlpha2.getName());
if (conversationRequestAlpha2.getContextId() != null) {
protosConversationRequestBuilder.setContextId(conversationRequestAlpha2.getContextId());
}
if (conversationRequestAlpha2.getToolChoice() != null) {
protosConversationRequestBuilder.setToolChoice(conversationRequestAlpha2.getToolChoice());
}
if (conversationRequestAlpha2.getTools() != null) {
for (ConversationTools tool : conversationRequestAlpha2.getTools()) {
ConversationFunction conversationFunction = tool.getFunction();
Map<String, Any> protosConversationToolFunctionParameters = conversationFunction.getParameters()
.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> Any.pack((Message) e.getValue())
));
DaprProtos.ConversationToolsFunction protosConversationToolsFunction =
DaprProtos.ConversationToolsFunction.newBuilder()
.setName(conversationFunction.getName())
.setDescription(conversationFunction.getDescription())
.putAllParameters(protosConversationToolFunctionParameters)
.build();
DaprProtos.ConversationTools conversationTool = DaprProtos.ConversationTools.newBuilder()
.setFunction(protosConversationToolsFunction).build();
protosConversationRequestBuilder.addTools(conversationTool);
}
}
for (ConversationInputAlpha2 input : conversationRequestAlpha2.getInputs()) {
DaprProtos.ConversationInputAlpha2.Builder conversationInputBuilder = DaprProtos.ConversationInputAlpha2
.newBuilder()
.setScrubPii(input.isScrubPii());
if (input.getMessages() != null) {
for (ConversationMessage conversationMessage : input.getMessages()) {
DaprProtos.ConversationMessage.Builder messageBuilder =
DaprProtos.ConversationMessage.newBuilder();
ConversationMessage.Role role = conversationMessage.getRole();
switch (role) {
case TOOL:
messageBuilder.setOfTool(DaprProtos.ConversationMessageOfTool.newBuilder()
.setToolId(conversationMessage.getToolId())
.setName(conversationMessage.getName())
.addAllContent(getConversationMessageContent(conversationMessage)).build());
break;
case USER:
messageBuilder.setOfUser(DaprProtos.ConversationMessageOfUser.newBuilder()
.setName(conversationMessage.getName())
.addAllContent(getConversationMessageContent(conversationMessage)).build());
break;
case ASSISTANT:
messageBuilder.setOfAssistant(DaprProtos.ConversationMessageOfAssistant.newBuilder()
.setName(conversationMessage.getName())
.addAllToolCalls(getConversationToolCalls(conversationMessage))
.addAllContent(getConversationMessageContent(conversationMessage)).build());
break;
case DEVELOPER:
messageBuilder.setOfDeveloper(DaprProtos.ConversationMessageOfDeveloper.newBuilder()
.setName(conversationMessage.getName())
.addAllContent(getConversationMessageContent(conversationMessage)).build());
break;
case SYSTEM:
messageBuilder.setOfSystem(DaprProtos.ConversationMessageOfSystem.newBuilder()
.setName(conversationMessage.getName())
.addAllContent(getConversationMessageContent(conversationMessage)).build());
break;
default: throw new IllegalArgumentException("No role of type " + role + " found");
}
conversationInputBuilder.addMessages(messageBuilder.build());
}
}
protosConversationRequestBuilder.addInputs(conversationInputBuilder.build());
}
Mono<DaprProtos.ConversationResponseAlpha2> conversationResponseMono = Mono.deferContextual(
context -> this.createMono(
it -> intercept(context, asyncStub)
.converseAlpha2(protosConversationRequestBuilder.build(), it)
)
);
return conversationResponseMono.map(conversationResponse -> {
List<ConversationResultAlpha2> results = new ArrayList<>();
for (DaprProtos.ConversationResultAlpha2 result : conversationResponse.getOutputsList()) {
List<ConversationResultChoices> choices = new ArrayList<>();
for (DaprProtos.ConversationResultChoices choice : result.getChoicesList()) {
ConversationResultMessage message = null;
if (choice.hasMessage()) {
List<ConversationToolCalls> toolCalls = new ArrayList<>();
for (DaprProtos.ConversationToolCalls toolCall : choice.getMessage().getToolCallsList()) {
ConversationToolCallsFunction function = null;
if (toolCall.hasFunction()) {
function = new ConversationToolCallsFunction(
toolCall.getFunction().getName(),
toolCall.getFunction().getArguments()
);
}
toolCalls.add(new ConversationToolCalls(toolCall.getId(), function));
}
message = new ConversationResultMessage(
choice.getMessage().getContent(),
toolCalls
);
}
choices.add(new ConversationResultChoices(choice.getFinishReason(), choice.getIndex(), message));
}
results.add(new ConversationResultAlpha2(choices));
}
return new ConversationResponseAlpha2(conversationResponse.getContextId(), results);
});
} catch (Exception ex) {
return DaprException.wrapMono(ex);
}
}
private List<DaprProtos.ConversationMessageContent> getConversationMessageContent(
ConversationMessage conversationMessage) {
List<DaprProtos.ConversationMessageContent> conversationMessageContents = new ArrayList<>();
for (ConversationMessageContent conversationMessageContent: conversationMessage.getContent()) {
conversationMessageContents.add(DaprProtos.ConversationMessageContent.newBuilder()
.setText(conversationMessageContent.getText())
.build());
}
return conversationMessageContents;
}
private List<DaprProtos.ConversationToolCalls> getConversationToolCalls(
ConversationMessage conversationMessage) {
List<DaprProtos.ConversationToolCalls> conversationToolCalls = new ArrayList<>();
for (ConversationToolCalls conversationToolCall: conversationMessage.getToolCalls()) {
conversationToolCalls.add(DaprProtos.ConversationToolCalls.newBuilder()
.setId(conversationToolCall.getId())
.setFunction(DaprProtos.ConversationToolCallsOfFunction.newBuilder()
.setName(conversationToolCall.getFunction().getName())
.setArguments(conversationToolCall.getFunction().getArguments())
.build())
.build());
}
return conversationToolCalls;
}
private void validateConversationRequestAlpha2(ConversationRequestAlpha2 conversationRequest) {
if ((conversationRequest.getName() == null) || (conversationRequest.getName().trim().isEmpty())) {
throw new IllegalArgumentException("LLM name cannot be null or empty.");
}
if ((conversationRequest.getInputs() == null) || (conversationRequest.getInputs().isEmpty())) {
throw new IllegalArgumentException("Conversation inputs cannot be null or empty.");
}
}
private DaprMetadata buildDaprMetadata(DaprProtos.GetMetadataResponse response) throws IOException {
String id = response.getId();
String runtimeVersion = response.getRuntimeVersion();

View File

@ -18,7 +18,9 @@ import io.dapr.client.domain.BulkPublishRequest;
import io.dapr.client.domain.BulkPublishResponse;
import io.dapr.client.domain.BulkPublishResponseFailedEntry;
import io.dapr.client.domain.ConversationRequest;
import io.dapr.client.domain.ConversationRequestAlpha2;
import io.dapr.client.domain.ConversationResponse;
import io.dapr.client.domain.ConversationResponseAlpha2;
import io.dapr.client.domain.DeleteJobRequest;
import io.dapr.client.domain.GetJobRequest;
import io.dapr.client.domain.GetJobResponse;
@ -314,4 +316,12 @@ public interface DaprPreviewClient extends AutoCloseable {
* @return {@link ConversationResponse}.
*/
public Mono<ConversationResponse> converse(ConversationRequest conversationRequest);
/*
* Converse with an LLM using Alpha2 API.
*
* @param conversationRequestAlpha2 request to be passed to the LLM with Alpha2 features.
* @return {@link ConversationResponseAlpha2}.
*/
public Mono<ConversationResponseAlpha2> converseAlpha2(ConversationRequestAlpha2 conversationRequestAlpha2);
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.Map;
/**
* Represents a function definition for conversation tools.
*/
public class ConversationFunction {
private final String name;
private final String description;
private final Map<String, Object> parameters;
/**
* Constructor.
*
* @param name the function name
* @param description the function description
* @param parameters the function parameters schema
*/
public ConversationFunction(String name, String description, Map<String, Object> parameters) {
this.name = name;
this.description = description;
this.parameters = parameters;
}
/**
* Gets the function name.
*
* @return the function name
*/
public String getName() {
return name;
}
/**
* Gets the function description.
*
* @return the function description
*/
public String getDescription() {
return description;
}
/**
* Gets the function parameters schema.
*
* @return the function parameters
*/
public Map<String, Object> getParameters() {
return parameters;
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
/**
* Represents an Alpha2 input for conversation with enhanced message support.
*/
public class ConversationInputAlpha2 {
private final List<ConversationMessage> messages;
private boolean scrubPii;
/**
* Constructor.
*
* @param messages the list of conversation messages
*/
public ConversationInputAlpha2(List<ConversationMessage> messages) {
this.messages = List.copyOf(messages);
}
/**
* Gets the list of conversation messages.
*
* @return the list of messages
*/
public List<ConversationMessage> getMessages() {
return messages;
}
/**
* Checks if Personally Identifiable Information (PII) should be scrubbed before sending to the LLM.
*
* @return {@code true} if PII should be scrubbed, {@code false} otherwise.
*/
public boolean isScrubPii() {
return scrubPii;
}
/**
* Enable obfuscation of sensitive information present in the content field. Optional
*
* @param scrubPii A boolean indicating whether to remove PII.
* @return this.
*/
public ConversationInputAlpha2 setScrubPii(boolean scrubPii) {
this.scrubPii = scrubPii;
return this;
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
/**
* Represents a conversation message with role-specific content.
* Supports different message types: system, user, assistant, developer, and tool.
*/
public class ConversationMessage {
/**
* Enum representing the different roles a message can have.
*/
public enum Role {
SYSTEM,
USER,
ASSISTANT,
DEVELOPER,
TOOL
}
private final Role role;
private final String name;
private final List<ConversationMessageContent> content;
private final List<ConversationToolCalls> toolCalls;
private final String toolId;
/**
* Constructor for creating a message with basic content.
*
* @param role the role of the message sender
* @param content the content of the message
*/
public ConversationMessage(Role role, List<ConversationMessageContent> content) {
this(role, null, content, null, null);
}
/**
* Constructor for creating a message with name and content.
*
* @param role the role of the message sender
* @param name the name of the participant (optional)
* @param content the content of the message
*/
public ConversationMessage(Role role, String name, List<ConversationMessageContent> content) {
this(role, name, content, null, null);
}
/**
* Full constructor for creating a message with all properties.
*
* @param role the role of the message sender
* @param name the name of the participant (optional)
* @param content the content of the message
* @param toolCalls tool calls for assistant messages (optional)
* @param toolId tool ID for tool messages (optional)
*/
public ConversationMessage(Role role, String name, List<ConversationMessageContent> content,
List<ConversationToolCalls> toolCalls, String toolId) {
this.role = role;
this.name = name;
this.content = content != null ? List.copyOf(content) : null;
this.toolCalls = toolCalls != null ? List.copyOf(toolCalls) : null;
this.toolId = toolId;
}
/**
* Gets the role of the message sender.
*
* @return the message role
*/
public Role getRole() {
return role;
}
/**
* Gets the name of the participant in the message.
*
* @return the participant name, or null if not specified
*/
public String getName() {
return name;
}
/**
* Gets the content of the message.
*
* @return the message content
*/
public List<ConversationMessageContent> getContent() {
return content;
}
/**
* Gets the tool calls generated by the model (for assistant messages).
*
* @return the tool calls, or null if none
*/
public List<ConversationToolCalls> getToolCalls() {
return toolCalls;
}
/**
* Gets the tool ID (for tool messages).
*
* @return the tool ID, or null if not a tool message
*/
public String getToolId() {
return toolId;
}
/**
* Checks if this message has tool calls.
*
* @return true if the message has tool calls, false otherwise
*/
public boolean hasToolCalls() {
return toolCalls != null && !toolCalls.isEmpty();
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
/**
* Represents the content of a conversation message.
*/
public class ConversationMessageContent {
private final String text;
/**
* Constructor.
*
* @param text the text content of the message
*/
public ConversationMessageContent(String text) {
this.text = text;
}
/**
* Gets the text content of the message.
*
* @return the text content
*/
public String getText() {
return text;
}
}

View File

@ -0,0 +1,209 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
import java.util.Map;
/**
* Represents the Alpha2 conversation configuration with enhanced features including
* tools, improved message handling, and better compatibility with OpenAI ChatCompletion API.
*/
public class ConversationRequestAlpha2 {
private final String name;
private final List<ConversationInputAlpha2> inputs;
private String contextId;
private boolean scrubPii;
private double temperature;
private List<ConversationTools> tools;
private String toolChoice;
private Map<String, Object> parameters;
private Map<String, String> metadata;
/**
* Constructs a ConversationRequestAlpha2 with a component name and conversation inputs.
*
* @param name The name of the Dapr conversation component. See a list of all available conversation components
* @see <a href="https://docs.dapr.io/reference/components-reference/supported-conversation/"></a>
* @param inputs the list of Dapr conversation inputs (Alpha2 format)
*/
public ConversationRequestAlpha2(String name, List<ConversationInputAlpha2> inputs) {
this.name = name;
this.inputs = inputs;
}
/**
* Gets the conversation component name.
*
* @return the conversation component name
*/
public String getName() {
return name;
}
/**
* Gets the list of Dapr conversation input (Alpha2 format).
*
* @return the list of conversation input
*/
public List<ConversationInputAlpha2> getInputs() {
return inputs;
}
/**
* Gets the context identifier.
*
* @return the context identifier
*/
public String getContextId() {
return contextId;
}
/**
* Sets the context identifier.
*
* @param contextId the context identifier to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setContextId(String contextId) {
this.contextId = contextId;
return this;
}
/**
* Checks if PII scrubbing is enabled.
*
* @return true if PII scrubbing is enabled, false otherwise
*/
public boolean isScrubPii() {
return scrubPii;
}
/**
* Enable obfuscation of sensitive information returning from the LLM. Optional.
*
* @param scrubPii whether to enable PII scrubbing
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setScrubPii(boolean scrubPii) {
this.scrubPii = scrubPii;
return this;
}
/**
* Gets the temperature of the model. Used to optimize for consistency and creativity. Optional
*
* @return the temperature value
*/
public double getTemperature() {
return temperature;
}
/**
* Sets the temperature of the model. Used to optimize for consistency and creativity. Optional
*
* @param temperature the temperature value to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setTemperature(double temperature) {
this.temperature = temperature;
return this;
}
/**
* Gets the tools available to be used by the LLM during the conversation.
*
* @return the list of tools
*/
public List<ConversationTools> getTools() {
return tools;
}
/**
* Sets the tools available to be used by the LLM during the conversation.
* These are sent on a per request basis.
*
* @param tools the tools to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setTools(List<ConversationTools> tools) {
this.tools = tools;
return this;
}
/**
* Gets the tool choice setting which controls which (if any) tool is called by the model.
*
* @return the tool choice setting
*/
public String getToolChoice() {
return toolChoice;
}
/**
* Sets the tool choice setting which controls which (if any) tool is called by the model.
* - "none" means the model will not call any tool and instead generates a message
* - "auto" means the model can pick between generating a message or calling one or more tools
* - "required" requires one or more functions to be called
* - Alternatively, a specific tool name may be used here
*
* @param toolChoice the tool choice setting to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setToolChoice(String toolChoice) {
this.toolChoice = toolChoice;
return this;
}
/**
* Gets the parameters for all custom fields.
*
* @return the parameters map
*/
public Map<String, Object> getParameters() {
return parameters;
}
/**
* Sets the parameters for all custom fields.
*
* @param parameters the parameters to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setParameters(Map<String, Object> parameters) {
this.parameters = parameters;
return this;
}
/**
* Gets the metadata passing to conversation components.
*
* @return the metadata map
*/
public Map<String, String> getMetadata() {
return metadata;
}
/**
* Sets the metadata passing to conversation components.
*
* @param metadata the metadata to set
* @return the current instance of {@link ConversationRequestAlpha2}
*/
public ConversationRequestAlpha2 setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
return this;
}
}

View File

@ -13,7 +13,6 @@ limitations under the License.
package io.dapr.client.domain;
import java.util.Collections;
import java.util.List;
/**

View File

@ -0,0 +1,54 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
/**
* Alpha2 response from the Dapr Conversation API with enhanced features.
*/
public class ConversationResponseAlpha2 {
private final String contextId;
private final List<ConversationResultAlpha2> outputs;
/**
* Constructor.
*
* @param contextId context id supplied to LLM.
* @param outputs outputs from the LLM (Alpha2 format).
*/
public ConversationResponseAlpha2(String contextId, List<ConversationResultAlpha2> outputs) {
this.contextId = contextId;
this.outputs = List.copyOf(outputs);
}
/**
* The ID of an existing chat (like in ChatGPT).
*
* @return String identifier.
*/
public String getContextId() {
return this.contextId;
}
/**
* Get list of conversation outputs (Alpha2 format).
*
* @return List{@link ConversationResultAlpha2}.
*/
public List<ConversationResultAlpha2> getOutputs() {
return this.outputs;
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
/**
* Alpha2 result for conversation output with enhanced choice-based structure.
*/
public class ConversationResultAlpha2 {
private final List<ConversationResultChoices> choices;
/**
* Constructor.
*
* @param choices the list of conversation result choices.
*/
public ConversationResultAlpha2(List<ConversationResultChoices> choices) {
this.choices = List.copyOf(choices);
}
/**
* Gets the list of conversation result choices.
*
* @return the list of conversation result choices
*/
public List<ConversationResultChoices> getChoices() {
return choices;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
/**
* Represents a conversation result choice with finish reason, index, and message.
*/
public class ConversationResultChoices {
private final String finishReason;
private final long index;
private final ConversationResultMessage message;
/**
* Constructor.
*
* @param finishReason the reason the model stopped generating tokens
* @param index the index of the choice in the list of choices
* @param message the result message
*/
public ConversationResultChoices(String finishReason, long index, ConversationResultMessage message) {
this.finishReason = finishReason;
this.index = index;
this.message = message;
}
/**
* Gets the reason the model stopped generating tokens.
* This will be "stop" if the model hit a natural stop point or a provided stop sequence,
* "length" if the maximum number of tokens specified in the request was reached,
* "content_filter" if content was omitted due to a flag from content filters,
* "tool_calls" if the model called a tool.
*
* @return the finish reason
*/
public String getFinishReason() {
return finishReason;
}
/**
* Gets the index of the choice in the list of choices.
*
* @return the index
*/
public long getIndex() {
return index;
}
/**
* Gets the result message.
*
* @return the message
*/
public ConversationResultMessage getMessage() {
return message;
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
import java.util.List;
/**
* Represents a conversation result message with content and optional tool calls.
*/
public class ConversationResultMessage {
private final String content;
private final List<ConversationToolCalls> toolCalls;
/**
* Constructor.
*
* @param content the contents of the message
* @param toolCalls the tool calls generated by the model (optional)
*/
public ConversationResultMessage(String content, List<ConversationToolCalls> toolCalls) {
this.content = content;
this.toolCalls = toolCalls != null ? List.copyOf(toolCalls) : null;
}
/**
* Constructor for message without tool calls.
*
* @param content the contents of the message
*/
public ConversationResultMessage(String content) {
this(content, null);
}
/**
* Gets the contents of the message.
*
* @return the message content
*/
public String getContent() {
return content;
}
/**
* Gets the tool calls generated by the model.
*
* @return the tool calls, or null if none
*/
public List<ConversationToolCalls> getToolCalls() {
return toolCalls;
}
/**
* Checks if the message has tool calls.
*
* @return true if there are tool calls, false otherwise
*/
public boolean hasToolCalls() {
return toolCalls != null && !toolCalls.isEmpty();
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
/**
* Represents a tool call request sent from the LLM to the client to execute.
*/
public class ConversationToolCalls {
private final String id;
private final ConversationToolCallsFunction function;
/**
* Constructor.
*
* @param id the unique identifier for the tool call (optional)
* @param function the function to call
*/
public ConversationToolCalls(String id, ConversationToolCallsFunction function) {
this.id = id;
this.function = function;
}
/**
* Constructor without ID.
*
* @param function the function to call
*/
public ConversationToolCalls(ConversationToolCallsFunction function) {
this(null, function);
}
/**
* Gets the unique identifier for the tool call.
*
* @return the tool call ID, or null if not provided
*/
public String getId() {
return id;
}
/**
* Gets the function to call.
*
* @return the function details
*/
public ConversationToolCallsFunction getFunction() {
return function;
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
/**
* Represents a function call within a tool call.
*/
public class ConversationToolCallsFunction {
private final String name;
private final String arguments;
/**
* Constructor.
*
* @param name the name of the function to call
* @param arguments the arguments to call the function with, as generated by the model in JSON format
*/
public ConversationToolCallsFunction(String name, String arguments) {
this.name = name;
this.arguments = arguments;
}
/**
* Gets the name of the function to call.
*
* @return the function name
*/
public String getName() {
return name;
}
/**
* Gets the arguments to call the function with, as generated by the model in JSON format.
* Note that the model does not always generate valid JSON, and may hallucinate parameters
* not defined by your function schema. Validate the arguments in your code before calling your function.
*
* @return the function arguments in JSON format
*/
public String getArguments() {
return arguments;
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.client.domain;
/**
* Represents tool definitions that can be used during conversation.
*/
public class ConversationTools {
private final String type;
private final ConversationFunction function;
/**
* Constructor.
*
* @param type the type of tool (e.g., "function")
* @param function the function definition
*/
public ConversationTools(String type, ConversationFunction function) {
this.type = type;
this.function = function;
}
/**
* Gets the tool type.
*
* @return the tool type
*/
public String getType() {
return type;
}
/**
* Gets the function definition.
*
* @return the function definition
*/
public ConversationFunction getFunction() {
return function;
}
}