From de8d390532f86b0cec11ba2fef01ea06dc5e3a5e Mon Sep 17 00:00:00 2001 From: Bilgin Ibryam Date: Fri, 7 Nov 2025 17:15:26 +0000 Subject: [PATCH] fix broken commands, updated output with tool calling and add Java quickstart Signed-off-by: Bilgin Ibryam --- .../quickstarts/conversation-quickstart.md | 710 +++++++++++++++--- 1 file changed, 599 insertions(+), 111 deletions(-) diff --git a/daprdocs/content/en/getting-started/quickstarts/conversation-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/conversation-quickstart.md index bad1868415f..b4c35fd5af4 100644 --- a/daprdocs/content/en/getting-started/quickstarts/conversation-quickstart.md +++ b/daprdocs/content/en/getting-started/quickstarts/conversation-quickstart.md @@ -23,6 +23,8 @@ Currently, you can only use JavaScript for the quickstart sample using HTTP, not ## Run the app with the template file +Select your preferred language-specific Dapr SDK before proceeding with the Quickstart. + {{< tabpane text=true >}} @@ -61,12 +63,13 @@ pip3 install -r requirements.txt ### Step 3: Launch the conversation service -Navigate back to the `sdk` directory and start the conversation service with the following command: ```bash dapr run -f . ``` +> **Note**: Since Python3.exe is not defined in Windows, you may need to use `python app.py` instead of `python3 app.py`. + **Expected output** ``` @@ -78,7 +81,7 @@ dapr run -f . When you ran `dapr init` during Dapr install, the [`dapr.yaml` Multi-App Run template file]({{% ref "#dapryaml-multi-app-run-template-file" %}}) was generated in the `.dapr/components` directory. -Running `dapr run -f .` in this Quickstart started [conversation.go]({{% ref "#programcs-conversation-app" %}}). +Running `dapr run -f .` in this Quickstart started [app.py]({{% ref "#programcs-conversation-app" %}}). #### `dapr.yaml` Multi-App Run template file @@ -118,27 +121,23 @@ In the application code: ```python from dapr.clients import DaprClient -from dapr.clients.grpc._request import ConversationInput +from dapr.clients.grpc.conversation import ConversationInputAlpha2, ConversationMessage, ConversationMessageContent, ConversationMessageOfUser with DaprClient() as d: - inputs = [ - ConversationInput(content="What is dapr?", role='user', scrub_pii=True), - ] - - metadata = { - 'model': 'modelname', - 'key': 'authKey', - 'cacheTTL': '10m', - } + text_input = "What is dapr?" + provider_component = "echo" + + inputs = [ + ConversationInputAlpha2(messages=[ConversationMessage(of_user=ConversationMessageOfUser(content=[ConversationMessageContent(text=text_input)]))], + scrub_pii=True), + ] - print('Input sent: What is dapr?') + print(f'Input sent: {text_input}') - response = d.converse_alpha1( - name='echo', inputs=inputs, temperature=0.7, context_id='chat-123', metadata=metadata - ) + response = d.converse_alpha2(name=provider_component, inputs=inputs, temperature=0.7, context_id='chat-123') - for output in response.outputs: - print(f'Output response: {output.result}') + for output in response.outputs: + print(f'Output response: {output.choices[0].message.content}') ``` {{% /tab %}} @@ -188,8 +187,12 @@ dapr run -f . **Expected output** ``` -== APP - conversation == Input sent: What is dapr? +== APP - conversation == Conversation input sent: What is dapr? == APP - conversation == Output response: What is dapr? +== APP - conversation == Tool calling input sent: What is the weather like in San Francisco in celsius? +== APP - conversation == Output message: { outputs: [ { choices: [Array] } ] } +== APP - conversation == Output message: What is the weather like in San Francisco in celsius? +== APP - conversation == Tool calls detected: [{"id":"0","function":{"name":"get_weather","arguments":"location,unit"}}] ``` ### What happened? @@ -231,50 +234,138 @@ To interface with a real LLM, swap out the mock component with one of [the suppo #### `index.js` conversation app -In the application code: +In the first part of the application code: - The app sends an input "What is dapr?" to the echo mock LLM component. - The mock LLM echoes "What is dapr?". ```javascript -const conversationComponentName = "echo"; +const daprHost = process.env.DAPR_HOST || "http://localhost"; +const daprHttpPort = process.env.DAPR_HTTP_PORT || "3500"; -async function main() { - const daprHost = process.env.DAPR_HOST || "http://localhost"; - const daprHttpPort = process.env.DAPR_HTTP_PORT || "3500"; +const reqURL = `${daprHost}:${daprHttpPort}/v1.0-alpha2/conversation/${conversationComponentName}/converse`; - const inputBody = { - name: "echo", - inputs: [{ message: "What is dapr?" }], +// Plain conversation +try { + const converseInputBody = { + inputs: [ + { + messages: [ + { + ofUser: { + content: [ + { + text: "What is dapr?", + }, + ], + }, + }, + ], + }, + ], parameters: {}, metadata: {}, }; + const response = await fetch(reqURL, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(converseInputBody), + }); + + console.log("Conversation input sent: What is dapr?"); + + const data = await response.json(); + const result = data.outputs[0].choices[0].message.content; + console.log("Output response:", result); +} catch (error) { + console.error("Error:", error.message); + process.exit(1); +} +``` - const reqURL = `${daprHost}:${daprHttpPort}/v1.0-alpha2/conversation/${conversationComponentName}/converse`; +In the second part of the application code: +- The app sends an input "What is the weather like in San Francisco in celsius" together with the definition of a tool that is available `get_weather`. +- The mock LLM echoes "What is the weather like in San Francisco in celsius?" and the function definition, which is detected in the response. - try { - const response = await fetch(reqURL, { - method: "POST", - headers: { - "Content-Type": "application/json", +```javascript +try { + const toolCallingInputBody = { + inputs: [ + { + messages: [ + { + ofUser: { + content: [ + { + text: "What is the weather like in San Francisco in celsius?", + }, + ], + }, + }, + ], + scrubPii: false, }, - body: JSON.stringify(inputBody), - }); - - console.log("Input sent: What is dapr?"); - - const data = await response.json(); - const result = data.outputs[0].result; - console.log("Output response:", result); - } catch (error) { - console.error("Error:", error.message); - process.exit(1); + ], + metadata: { + api_key: "test-key", + version: "1.0", + }, + scrubPii: false, + temperature: 0.7, + tools: [ + { + function: { + name: "get_weather", + description: "Get the current weather for a location", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "The city and state, e.g. San Francisco, CA", + }, + unit: { + type: "string", + enum: ["celsius", "fahrenheit"], + description: "The temperature unit to use", + }, + }, + required: ["location"], + }, + }, + }, + ], + toolChoice: "auto", + }; + const response = await fetch(reqURL, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(toolCallingInputBody), + }); + + console.log( + "Tool calling input sent: What is the weather like in San Francisco in celsius?" + ); + + const data = await response.json(); + + const result = data?.outputs?.[0]?.choices?.[0]?.message?.content; + console.log("Output message:", result); + + if (data?.outputs?.[0]?.choices?.[0]?.message?.toolCalls) { + console.log( + "Tool calls detected:", + JSON.stringify(data.outputs[0].choices[0].message?.toolCalls) + ); + } else { + console.log("No tool calls in response"); } -} - -main().catch((error) => { - console.error("Unhandled error:", error); +} catch (error) { + console.error("Error:", error.message); process.exit(1); -}); ``` {{% /tab %}} @@ -318,8 +409,14 @@ dapr run -f . **Expected output** ``` -== APP - conversation == Input sent: What is dapr? +== APP - conversation == Conversation input sent: What is dapr? == APP - conversation == Output response: What is dapr? +== APP - conversation == Tool calling input sent: What is the weather like in San Francisco in celsius? +== APP - conversation == Output message: What is the weather like in San Francisco in celsius? +== APP - conversation == Tool calls detected: +== APP - conversation == Tool call: {"id":0,"function":{"name":"get_weather","arguments":"location,unit"}} +== APP - conversation == Function name: get_weather +== APP - conversation == Function arguments: location,unit ``` ### What happened? @@ -364,44 +461,246 @@ To interface with a real LLM, swap out the mock component with one of [the suppo In the application code: - The app sends an input "What is dapr?" to the echo mock LLM component. - The mock LLM echoes "What is dapr?". +- The app sends an input “What is the weather like in San Francisco in celsius” together with the definition of a tool that is available `get_weather`. +- The mock LLM echoes “What is the weather like in San Francisco in celsius?” and the function definition, which is detected in the response. + ```csharp +using System.Text.Json; using Dapr.AI.Conversation; +using Dapr.AI.Conversation.ConversationRoles; using Dapr.AI.Conversation.Extensions; +using Dapr.AI.Conversation.Tools; -class Program -{ - private const string ConversationComponentName = "echo"; +const string conversationComponentName = "echo"; +const string conversationText = "What is dapr?"; +const string toolCallInput = "What is the weather like in San Francisco in celsius?"; - static async Task Main(string[] args) - { - const string prompt = "What is dapr?"; +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddDaprConversationClient(); +var app = builder.Build(); - var builder = WebApplication.CreateBuilder(args); - builder.Services.AddDaprConversationClient(); - var app = builder.Build(); +// +// Setup - //Instantiate Dapr Conversation Client - var conversationClient = app.Services.GetRequiredService(); +var conversationClient = app.Services.GetRequiredService(); - try - { - // Send a request to the echo mock LLM component - var response = await conversationClient.ConverseAsync(ConversationComponentName, [new(prompt, DaprConversationRole.Generic)]); - Console.WriteLine("Input sent: " + prompt); - - if (response != null) - { - Console.Write("Output response:"); - foreach (var resp in response.Outputs) +var conversationOptions = new ConversationOptions(conversationComponentName) +{ + ScrubPII = false, + ToolChoice = ToolChoice.Auto, + Temperature = 0.7, + Tools = [ + new ToolFunction("function") { - Console.WriteLine($" {resp.Result}"); - } - } - } - catch (Exception ex) + Name = "get_weather", + Description = "Get the current weather for a location", + Parameters = JsonSerializer.Deserialize>(""" + { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA" + }, + "unit": { + "type": "string", + "enum": ["celsius", "fahrenheit"], + "description": "The temperature unit to use" + } + }, + "required": ["location"] + } + """) ?? throw new("Unable to parse tool function parameters."), + }, + ], +}; + +// +// Simple Conversation + +var conversationResponse = await conversationClient.ConverseAsync( + [new ConversationInput(new List + { + new UserMessage { + Name = "TestUser", + Content = [ + new MessageContent(conversationText), + ], + }, + })], + conversationOptions +); + +Console.WriteLine($"Conversation input sent: {conversationText}"); +Console.WriteLine($"Output response: {conversationResponse.Outputs.First().Choices.First().Message.Content}"); + +// +// Tool Calling + +var toolCallResponse = await conversationClient.ConverseAsync( + [new ConversationInput(new List { - Console.WriteLine("Error: " + ex.Message); + new UserMessage { + Name = "TestUser", + Content = [ + new MessageContent(toolCallInput), + ], + }, + })], + conversationOptions +); + +Console.WriteLine($"Tool calling input sent: {toolCallInput}"); +Console.WriteLine($"Output message: {toolCallResponse.Outputs.First().Choices.First().Message.Content}"); +Console.WriteLine("Tool calls detected:"); + +var functionToolCall = toolCallResponse.Outputs.First().Choices.First().Message.ToolCalls.First() as CalledToolFunction + ?? throw new("Unexpected tool call type for demo."); + +var toolCallJson = JsonSerializer.Serialize(new +{ + id = 0, + function = new + { + name = functionToolCall.Name, + arguments = functionToolCall.JsonArguments, + }, +}); +Console.WriteLine($"Tool call: {toolCallJson}"); +Console.WriteLine($"Function name: {functionToolCall.Name}"); +Console.WriteLine($"Function arguments: {functionToolCall.JsonArguments}"); +``` + +{{% /tab %}} + + + + +{{% tab "Java" %}} + + +### Step 1: Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- Java JDK 17 (or greater): + - [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or + - OpenJDK +- [Apache Maven](https://maven.apache.org/install.html), version 3.x. + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 2: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +From the root of the Quickstarts directory, navigate into the conversation directory: + +```bash +cd conversation/java/sdk/conversation +``` + +Install the dependencies: + +```bash +mvn clean install +``` + +### Step 3: Launch the conversation service + +Navigate back to the sdk directory and start the conversation service with the following command: + +```bash +dapr run -f . +``` + +**Expected output** + +``` +== APP - conversation == Input: What is Dapr? +== APP - conversation == Output response: What is Dapr? +``` + +### What happened? + +When you ran `dapr init` during Dapr install, the [`dapr.yaml` Multi-App Run template file]({{% ref "#dapryaml-multi-app-run-template-file" %}}) was generated in the `.dapr/components` directory. + +Running `dapr run -f .` in this Quickstart started [Conversation.java]({{% ref "#programcs-conversation-app" %}}). + +#### `dapr.yaml` Multi-App Run template file + +Running the [Multi-App Run template file]({{% ref multi-app-dapr-run %}}) with `dapr run -f .` starts all applications in your project. This Quickstart has only one application, so the `dapr.yaml` file contains the following: + +```yml +version: 1 +common: + resourcesPath: ../../components +apps: + - appID: conversation + appDirPath: ./conversation/target + command: ["java", "-jar", "ConversationAIService-0.0.1-SNAPSHOT.jar"] +``` + +#### Echo mock LLM component + +In [`conversation/components`](https://github.com/dapr/quickstarts/tree/master/conversation/components) directly of the quickstart, the [`conversation.yaml` file](https://github.com/dapr/quickstarts/tree/master/conversation/components/conversation.yaml) configures the echo LLM component. + +```yml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: echo +spec: + type: conversation.echo + version: v1 +``` + +To interface with a real LLM, swap out the mock component with one of [the supported conversation components]({{% ref "supported-conversation" %}}). For example, to use an OpenAI component, see the [example in the conversation how-to guide]({{% ref "howto-conversation-layer#use-the-openai-component" %}}) + +#### `Conversation.java` conversation app + +In the application code: +- The app sends an input "What is dapr?" to the echo mock LLM component. +- The mock LLM echoes "What is dapr?". + +```java +package com.service; + +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.domain.ConversationInput; +import io.dapr.client.domain.ConversationRequest; +import io.dapr.client.domain.ConversationResponse; +import reactor.core.publisher.Mono; + +import java.util.List; + +public class Conversation { + + public static void main(String[] args) { + String prompt = "What is Dapr?"; + + try (DaprPreviewClient client = new DaprClientBuilder().buildPreviewClient()) { + System.out.println("Input: " + prompt); + + ConversationInput daprConversationInput = new ConversationInput(prompt); + + // Component name is the name provided in the metadata block of the conversation.yaml file. + Mono responseMono = client.converse(new ConversationRequest("echo", + List.of(daprConversationInput)) + .setContextId("contextId") + .setScrubPii(true).setTemperature(1.1d)); + ConversationResponse response = responseMono.block(); + System.out.printf("Output response: %s", response.getConversationOutputs().get(0).getResult()); + } catch (Exception e) { + throw new RuntimeException(e); } } } @@ -448,8 +747,11 @@ dapr run -f . **Expected output** ``` -== APP - conversation == Input sent: What is dapr? -== APP - conversation == Output response: What is dapr? +== APP - conversation-sdk == Input sent: What is dapr? +== APP - conversation-sdk == Output response: What is dapr? +== APP - conversation-sdk == Tool calling input sent: What is the weather like in San Francisco in celsius?' +== APP - conversation-sdk == Tool Call: Name: getWeather - Arguments: location,unit +== APP - conversation-sdk == Tool Call Output: The weather in San Francisco is 25 degrees Celsius ``` ### What happened? @@ -493,43 +795,163 @@ To interface with a real LLM, swap out the mock component with one of [the suppo In the application code: - The app sends an input "What is dapr?" to the echo mock LLM component. -- The mock LLM echoes "What is dapr?". +- The mock LLM echoes "What is dapr?". +- The app sends an input “What is the weather like in San Francisco in celsius” together with the definition of a tool that is available `get_weather`. +- The mock LLM echoes “What is the weather like in San Francisco in celsius?” and the function definition, which is detected in the response. ```go -package main - import ( - "context" - "fmt" - "log" + "context" + "encoding/json" + "fmt" + "log" + "strings" + + "github.com/invopop/jsonschema" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/structpb" - dapr "github.com/dapr/go-sdk/client" + dapr "github.com/dapr/go-sdk/client" ) +// createMapOfArgsForEcho is a helper function to deal with the issue with the echo component not returning args as a map but in csv format +func createMapOfArgsForEcho(s string) ([]byte, error) { + m := map[string]any{} + for _, p := range strings.Split(s, ",") { + m[p] = p + } + return json.Marshal(m) +} + +// getWeatherInLocation is an example function to use as a tool call +func getWeatherInLocation(request GetDegreesWeatherRequest, defaultValues GetDegreesWeatherRequest) string { + location := request.Location + unit := request.Unit + if location == "location" { + location = defaultValues.Location + } + if unit == "unit" { + unit = defaultValues.Unit + } + return fmt.Sprintf("The weather in %s is 25 degrees %s", location, unit) +} + +type GetDegreesWeatherRequest struct { + Location string `json:"location" jsonschema:"title=Location,description=The location to look up the weather for"` + Unit string `json:"unit" jsonschema:"enum=celsius,enum=fahrenheit,description=Unit"` +} + +// GenerateFunctionTool helper method to create jsonschema input +func GenerateFunctionTool[T any](name, description string) (*dapr.ConversationToolsAlpha2, error) { + reflector := jsonschema.Reflector{ + AllowAdditionalProperties: false, + DoNotReference: true, + } + var v T + + schema := reflector.Reflect(v) + + schemaBytes, err := schema.MarshalJSON() + if err != nil { + return nil, err + } + + var protoStruct structpb.Struct + if err := protojson.Unmarshal(schemaBytes, &protoStruct); err != nil { + return nil, fmt.Errorf("converting jsonschema to proto Struct: %w", err) + } + + return (*dapr.ConversationToolsAlpha2)(&dapr.ConversationToolsFunctionAlpha2{ + Name: name, + Description: &description, + Parameters: &protoStruct, + }), nil +} + +// createUserMessageInput is a helper method to create user messages in expected proto format +func createUserMessageInput(msg string) *dapr.ConversationInputAlpha2 { + return &dapr.ConversationInputAlpha2{ + Messages: []*dapr.ConversationMessageAlpha2{ + { + ConversationMessageOfUser: &dapr.ConversationMessageOfUserAlpha2{ + Content: []*dapr.ConversationMessageContentAlpha2{ + { + Text: &msg, + }, + }, + }, + }, + }, + } +} + func main() { - client, err := dapr.NewClient() - if err != nil { - panic(err) - } + client, err := dapr.NewClient() + if err != nil { + panic(err) + } - input := dapr.ConversationInput{ - Message: "What is dapr?", - // Role: nil, // Optional - // ScrubPII: nil, // Optional - } + inputMsg := "What is dapr?" + conversationComponent := "echo" - fmt.Println("Input sent:", input.Message) + request := dapr.ConversationRequestAlpha2{ + Name: conversationComponent, + Inputs: []*dapr.ConversationInputAlpha2{createUserMessageInput(inputMsg)}, + } - var conversationComponent = "echo" + fmt.Println("Input sent:", inputMsg) - request := dapr.NewConversationRequest(conversationComponent, []dapr.ConversationInput{input}) + resp, err := client.ConverseAlpha2(context.Background(), request) + if err != nil { + log.Fatalf("err: %v", err) + } + + fmt.Println("Output response:", resp.Outputs[0].Choices[0].Message.Content) - resp, err := client.ConverseAlpha1(context.Background(), request) - if err != nil { - log.Fatalf("err: %v", err) - } + tool, err := GenerateFunctionTool[GetDegreesWeatherRequest]("getWeather", "get weather from a location in the given unit") + if err != nil { + log.Fatalf("err: %v", err) + } - fmt.Println("Output response:", resp.Outputs[0].Result) + weatherMessage := "Tool calling input sent: What is the weather like in San Francisco in celsius?'" + requestWithTool := dapr.ConversationRequestAlpha2{ + Name: conversationComponent, + Inputs: []*dapr.ConversationInputAlpha2{createUserMessageInput(weatherMessage)}, + Tools: []*dapr.ConversationToolsAlpha2{tool}, + } + + resp, err = client.ConverseAlpha2(context.Background(), requestWithTool) + if err != nil { + log.Fatalf("err: %v", err) + } + + fmt.Println(resp.Outputs[0].Choices[0].Message.Content) + for _, toolCalls := range resp.Outputs[0].Choices[0].Message.ToolCalls { + fmt.Printf("Tool Call: Name: %s - Arguments: %v\n", toolCalls.ToolTypes.Name, toolCalls.ToolTypes.Arguments) + + // parse the arguments and execute tool + args := []byte(toolCalls.ToolTypes.Arguments) + if conversationComponent == "echo" { + // The echo component does not return a compliant tool calling response in json format but rather returns a csv + args, err = createMapOfArgsForEcho(toolCalls.ToolTypes.Arguments) + if err != nil { + log.Fatalf("err: %v", err) + } + } + + // find the tool (only one in this case) and execute + for _, toolInfo := range requestWithTool.Tools { + if toolInfo.Name == toolCalls.ToolTypes.Name && toolInfo.Name == "getWeather" { + var reqArgs GetDegreesWeatherRequest + if err = json.Unmarshal(args, &reqArgs); err != nil { + log.Fatalf("err: %v", err) + } + // execute tool + toolExecutionOutput := getWeatherInLocation(reqArgs, GetDegreesWeatherRequest{Location: "San Francisco", Unit: "Celsius"}) + fmt.Printf("Tool Call Output: %s\n", toolExecutionOutput) + } + } + } } ``` @@ -630,17 +1052,19 @@ npm install ### Step 3: Launch the conversation service -Navigate back to the `http` directory and start the conversation service with the following command: ```bash -dapr run --app-id conversation --resources-path ../../../components/ -- npm run start +dapr run --app-id conversation --resources-path ../../../components -- npm run start ``` **Expected output** ``` -== APP - conversation == Input sent: What is dapr? -== APP - conversation == Output response: What is dapr? +== APP == Conversation input sent: What is dapr? +== APP == Output response: What is dapr? +== APP == Tool calling input sent: What is the weather like in San Francisco in celsius? +== APP == Output message: What is the weather like in San Francisco in celsius? +== APP == Tool calls detected: [{"id":"0","function":{"name":"get_weather","arguments":"location,unit"}}] ``` {{% /tab %}} @@ -690,8 +1114,68 @@ dapr run --app-id conversation --resources-path ../../../components/ -- dotnet r **Expected output** ``` -== APP - conversation == Input sent: What is dapr? -== APP - conversation == Output response: What is dapr? +== APP == Conversation input sent: What is dapr? +== APP == Output response: What is dapr? +== APP == Tool calling input sent: What is the weather like in San Francisco in celsius? +== APP == Output message: What is the weather like in San Francisco in celsius? +== APP == Tool calls detected: +== APP == Tool call: {"id":0,"function":{"name":"get_weather","arguments":"location,unit"}} +== APP == Function name: get_weather +== APP == Function arguments: location,unit +``` + +{{% /tab %}} + + +{{% tab "Java" %}} + + +### Step 1: Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- Java JDK 17 (or greater): + - [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or + - OpenJDK +- [Apache Maven](https://maven.apache.org/install.html), version 3.x. + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 2: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +From the root of the Quickstarts directory, navigate into the conversation directory: + +```bash +cd conversation/java/sdk/conversation +``` + +Install the dependencies: + +```bash +mvn clean install +``` + +### Step 3: Launch the conversation service + +Start the conversation service with the following command: + +```bash +dapr run --app-id conversation --resources-path ../../../components/ -- java -jar target/ConversationAIService-0.0.1-SNAPSHOT.jar com.service.Conversation +``` + +**Expected output** + +``` +== APP == Input: What is Dapr? +== APP == Output response: What is Dapr? ``` {{% /tab %}} @@ -741,8 +1225,12 @@ dapr run --app-id conversation --resources-path ../../../components/ -- go run . **Expected output** ``` -== APP - conversation == Input sent: What is dapr? -== APP - conversation == Output response: What is dapr? +== APP == dapr client initializing for: 127.0.0.1:53826 +== APP == Input sent: What is dapr? +== APP == Output response: What is dapr? +== APP == Tool calling input sent: What is the weather like in San Francisco in celsius?' +== APP == Tool Call: Name: getWeather - Arguments: location,unit +== APP == Tool Call Output: The weather in San Francisco is 25 degrees Celsius ``` {{% /tab %}}