Skip to content

Commit 57fad34

Browse files
committed
fxi things
Signed-off-by: siri-varma <siri.varma@outlook.com>
1 parent 3c79ce8 commit 57fad34

File tree

2 files changed

+387
-0
lines changed

2 files changed

+387
-0
lines changed
Lines changed: 386 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,386 @@
1+
/*
2+
* Copyright 2025 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.it.testcontainers.conversations;
15+
16+
import io.dapr.client.DaprPreviewClient;
17+
import io.dapr.client.domain.AssistantMessage;
18+
import io.dapr.client.domain.ConversationInputAlpha2;
19+
import io.dapr.client.domain.ConversationMessage;
20+
import io.dapr.client.domain.ConversationMessageContent;
21+
import io.dapr.client.domain.ConversationRequestAlpha2;
22+
import io.dapr.client.domain.ConversationResponseAlpha2;
23+
import io.dapr.client.domain.ConversationResultAlpha2;
24+
import io.dapr.client.domain.ConversationResultChoices;
25+
import io.dapr.client.domain.ConversationToolCalls;
26+
import io.dapr.client.domain.ConversationToolCallsOfFunction;
27+
import io.dapr.client.domain.ConversationTools;
28+
import io.dapr.client.domain.ConversationToolsFunction;
29+
import io.dapr.client.domain.DeveloperMessage;
30+
import io.dapr.client.domain.SystemMessage;
31+
import io.dapr.client.domain.ToolMessage;
32+
import io.dapr.client.domain.UserMessage;
33+
import io.dapr.it.testcontainers.DaprPreviewClientConfiguration;
34+
import io.dapr.testcontainers.Component;
35+
import io.dapr.testcontainers.DaprContainer;
36+
import io.dapr.testcontainers.DaprLogLevel;
37+
import org.junit.jupiter.api.BeforeEach;
38+
import org.junit.jupiter.api.Tag;
39+
import org.junit.jupiter.api.Test;
40+
import org.springframework.beans.factory.annotation.Autowired;
41+
import org.springframework.boot.test.context.SpringBootTest;
42+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
43+
import org.springframework.test.context.DynamicPropertyRegistry;
44+
import org.springframework.test.context.DynamicPropertySource;
45+
import org.testcontainers.containers.Network;
46+
import org.testcontainers.junit.jupiter.Container;
47+
import org.testcontainers.junit.jupiter.Testcontainers;
48+
49+
import java.util.ArrayList;
50+
import java.util.HashMap;
51+
import java.util.List;
52+
import java.util.Map;
53+
import java.util.Random;
54+
55+
import static io.dapr.it.testcontainers.ContainerConstants.DAPR_RUNTIME_IMAGE_TAG;
56+
import static org.junit.jupiter.api.Assertions.assertEquals;
57+
import static org.junit.jupiter.api.Assertions.assertNotNull;
58+
import static org.junit.jupiter.api.Assertions.assertTrue;
59+
60+
@SpringBootTest(
61+
webEnvironment = WebEnvironment.RANDOM_PORT,
62+
classes = {
63+
DaprPreviewClientConfiguration.class,
64+
TestConversationApplication.class
65+
}
66+
)
67+
@Testcontainers
68+
@Tag("testcontainers")
69+
public class DaprConversationAlpha2IT {
70+
71+
private static final Network DAPR_NETWORK = Network.newNetwork();
72+
private static final Random RANDOM = new Random();
73+
private static final int PORT = RANDOM.nextInt(1000) + 8000;
74+
75+
@Container
76+
private static final DaprContainer DAPR_CONTAINER = new DaprContainer(DAPR_RUNTIME_IMAGE_TAG)
77+
.withAppName("conversation-alpha2-dapr-app")
78+
.withComponent(new Component("echo", "conversation.echo", "v1", new HashMap<>()))
79+
.withNetwork(DAPR_NETWORK)
80+
.withDaprLogLevel(DaprLogLevel.DEBUG)
81+
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
82+
.withAppChannelAddress("host.testcontainers.internal")
83+
.withAppPort(PORT);
84+
85+
/**
86+
* Expose the Dapr port to the host.
87+
*
88+
* @param registry the dynamic property registry
89+
*/
90+
@DynamicPropertySource
91+
static void daprProperties(DynamicPropertyRegistry registry) {
92+
registry.add("dapr.http.endpoint", DAPR_CONTAINER::getHttpEndpoint);
93+
registry.add("dapr.grpc.endpoint", DAPR_CONTAINER::getGrpcEndpoint);
94+
registry.add("server.port", () -> PORT);
95+
}
96+
97+
@Autowired
98+
private DaprPreviewClient daprPreviewClient;
99+
100+
@BeforeEach
101+
public void setUp() {
102+
org.testcontainers.Testcontainers.exposeHostPorts(PORT);
103+
}
104+
105+
@Test
106+
public void testConverseAlpha2WithUserMessage() {
107+
// Create a user message
108+
UserMessage userMessage = new UserMessage(List.of(new ConversationMessageContent("Hello, how are you?")));
109+
userMessage.setName("TestUser");
110+
111+
// Create input with the message
112+
ConversationInputAlpha2 input = new ConversationInputAlpha2(List.of(userMessage));
113+
114+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
115+
116+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
117+
118+
assertNotNull(response);
119+
assertNotNull(response.getOutputs());
120+
assertEquals(1, response.getOutputs().size());
121+
122+
ConversationResultAlpha2 result = response.getOutputs().get(0);
123+
assertNotNull(result.getChoices());
124+
assertTrue(result.getChoices().size() > 0);
125+
126+
ConversationResultChoices choice = result.getChoices().get(0);
127+
assertNotNull(choice.getMessage());
128+
assertNotNull(choice.getMessage().getContent());
129+
}
130+
131+
@Test
132+
public void testConverseAlpha2WithAllMessageTypes() {
133+
List<ConversationMessage> messages = new ArrayList<>();
134+
135+
// System message
136+
SystemMessage systemMsg = new SystemMessage(List.of(new ConversationMessageContent("You are a helpful assistant.")));
137+
systemMsg.setName("system");
138+
messages.add(systemMsg);
139+
140+
// User message
141+
UserMessage userMsg = new UserMessage(List.of(new ConversationMessageContent("Hello!")));
142+
userMsg.setName("user");
143+
messages.add(userMsg);
144+
145+
// Assistant message
146+
AssistantMessage assistantMsg = new AssistantMessage(List.of(new ConversationMessageContent("Hi there!")),
147+
List.of(new ConversationToolCalls(
148+
new ConversationToolCallsOfFunction("get_weather", "{\"location\": \"New York\"}"))));
149+
assistantMsg.setName("assistant");
150+
messages.add(assistantMsg);
151+
152+
// Tool message
153+
ToolMessage toolMsg = new ToolMessage(List.of(new ConversationMessageContent("Weather data: 72F")));
154+
toolMsg.setName("tool");
155+
messages.add(toolMsg);
156+
157+
// Developer message
158+
DeveloperMessage devMsg = new DeveloperMessage(List.of(new ConversationMessageContent("Debug info")));
159+
devMsg.setName("developer");
160+
messages.add(devMsg);
161+
162+
ConversationInputAlpha2 input = new ConversationInputAlpha2(messages);
163+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
164+
165+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
166+
167+
assertNotNull(response);
168+
assertNotNull(response.getOutputs());
169+
assertTrue(response.getOutputs().size() > 0);
170+
}
171+
172+
@Test
173+
public void testConverseAlpha2WithScrubPII() {
174+
// Create a user message with PII
175+
UserMessage userMessage = new UserMessage(List.of(new ConversationMessageContent("My email is test@example.com and phone is +1234567890")));
176+
177+
ConversationInputAlpha2 input = new ConversationInputAlpha2(List.of(userMessage));
178+
input.setScrubPii(true);
179+
180+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
181+
request.setScrubPii(true);
182+
183+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
184+
185+
assertNotNull(response);
186+
assertNotNull(response.getOutputs());
187+
assertTrue(response.getOutputs().size() > 0);
188+
189+
// Verify response structure (actual PII scrubbing depends on echo component implementation)
190+
ConversationResultChoices choice = response.getOutputs().get(0).getChoices().get(0);
191+
assertNotNull(choice.getMessage());
192+
assertNotNull(choice.getMessage().getContent());
193+
}
194+
195+
@Test
196+
public void testConverseAlpha2WithTools() {
197+
// Create a tool function
198+
Map<String, Object> parameters = new HashMap<>();
199+
parameters.put("location", "string");
200+
parameters.put("unit", "celsius");
201+
ConversationToolsFunction function = new ConversationToolsFunction("get_weather", parameters);
202+
function.setDescription("Get current weather information");
203+
204+
ConversationTools tool = new ConversationTools(function);
205+
206+
// Create user message
207+
UserMessage userMessage = new UserMessage(List.of(new ConversationMessageContent("What's the weather like?")));
208+
209+
ConversationInputAlpha2 input = new ConversationInputAlpha2(List.of(userMessage));
210+
211+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
212+
request.setTools(List.of(tool));
213+
request.setToolChoice("auto");
214+
215+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
216+
217+
assertNotNull(response);
218+
assertNotNull(response.getOutputs());
219+
assertTrue(response.getOutputs().size() > 0);
220+
}
221+
222+
@Test
223+
public void testConverseAlpha2WithMetadataAndParameters() {
224+
UserMessage userMessage = new UserMessage(List.of(new ConversationMessageContent("Hello world")));
225+
226+
ConversationInputAlpha2 input = new ConversationInputAlpha2(List.of(userMessage));
227+
228+
// Set metadata and parameters
229+
Map<String, String> metadata = new HashMap<>();
230+
metadata.put("request-id", "test-123");
231+
metadata.put("source", "integration-test");
232+
233+
Map<String, Object> parameters = new HashMap<>();
234+
parameters.put("max_tokens", "1000");
235+
parameters.put("temperature", "0.7");
236+
237+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
238+
request.setContextId("test-context-123");
239+
request.setTemperature(0.8);
240+
request.setMetadata(metadata);
241+
request.setParameters(parameters);
242+
243+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
244+
245+
assertNotNull(response);
246+
assertNotNull(response.getOutputs());
247+
assertTrue(response.getOutputs().size() > 0);
248+
249+
// Verify context ID is handled properly
250+
// Note: actual context ID behavior depends on echo component implementation
251+
assertNotNull(response.getContextId());
252+
}
253+
254+
@Test
255+
public void testConverseAlpha2WithAssistantToolCalls() {
256+
// Create a tool call
257+
ConversationToolCallsOfFunction toolFunction =
258+
new ConversationToolCallsOfFunction("get_weather", "{\"location\": \"New York\"}");
259+
ConversationToolCalls toolCall = new ConversationToolCalls(toolFunction);
260+
toolCall.setId("call_123");
261+
262+
// Create assistant message with tool calls
263+
AssistantMessage assistantMsg = new AssistantMessage(List.of(new ConversationMessageContent("Hi there!")),
264+
List.of(new ConversationToolCalls(
265+
new ConversationToolCallsOfFunction("get_weather", "{\"location\": \"New York\"}")))); // Note: Current implementation doesn't support setting tool calls in constructor
266+
// This tests the structure and ensures no errors occur
267+
268+
ConversationInputAlpha2 input = new ConversationInputAlpha2(List.of(assistantMsg));
269+
270+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
271+
272+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
273+
274+
assertNotNull(response);
275+
assertNotNull(response.getOutputs());
276+
assertTrue(response.getOutputs().size() > 0);
277+
}
278+
279+
@Test
280+
public void testConverseAlpha2WithComplexScenario() {
281+
List<ConversationMessage> messages = new ArrayList<>();
282+
283+
// System message setting context
284+
SystemMessage systemMsg = new SystemMessage(List.of(new ConversationMessageContent("You are a helpful weather assistant.")));
285+
systemMsg.setName("WeatherBot");
286+
messages.add(systemMsg);
287+
288+
// User asking for weather
289+
UserMessage userMsg = new UserMessage(List.of(new ConversationMessageContent("What's the weather in San Francisco?")));
290+
userMsg.setName("User123");
291+
messages.add(userMsg);
292+
293+
// Assistant response
294+
AssistantMessage assistantMsg = new AssistantMessage(List.of(new ConversationMessageContent("Hi there!")),
295+
List.of(new ConversationToolCalls(
296+
new ConversationToolCallsOfFunction("get_weather", "{\"location\": \"New York\"}"))));
297+
assistantMsg.setName("WeatherBot");
298+
messages.add(assistantMsg);
299+
300+
// Tool response
301+
ToolMessage toolMsg = new ToolMessage(List.of(new ConversationMessageContent("{\"temperature\": \"68F\", \"condition\": \"sunny\"}")));
302+
toolMsg.setName("weather_api");
303+
messages.add(toolMsg);
304+
305+
ConversationInputAlpha2 input = new ConversationInputAlpha2(messages);
306+
input.setScrubPii(false);
307+
308+
// Create tools
309+
Map<String, Object> functionParams = new HashMap<>();
310+
functionParams.put("location", "string");
311+
functionParams.put("unit", "fahrenheit");
312+
ConversationToolsFunction weatherFunction = new ConversationToolsFunction("get_current_weather",
313+
functionParams);
314+
weatherFunction.setDescription("Get current weather for a location");
315+
316+
317+
ConversationTools weatherTool = new ConversationTools(weatherFunction);
318+
319+
// Set up complete request
320+
Map<String, String> metadata = new HashMap<>();
321+
metadata.put("conversation-type", "weather-query");
322+
metadata.put("user-session", "session-456");
323+
324+
Map<String, Object> parameters = new HashMap<>();
325+
parameters.put("max_tokens", "2000");
326+
parameters.put("response_format", "json");
327+
328+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", List.of(input));
329+
request.setContextId("weather-conversation-789");
330+
request.setTemperature(0.7);
331+
request.setScrubPii(false);
332+
request.setTools(List.of(weatherTool));
333+
request.setToolChoice("auto");
334+
request.setMetadata(metadata);
335+
request.setParameters(parameters);
336+
337+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
338+
339+
assertNotNull(response);
340+
assertNotNull(response.getOutputs());
341+
assertTrue(response.getOutputs().size() > 0);
342+
343+
ConversationResultAlpha2 result = response.getOutputs().get(0);
344+
assertNotNull(result.getChoices());
345+
assertTrue(result.getChoices().size() > 0);
346+
347+
ConversationResultChoices choice = result.getChoices().get(0);
348+
assertNotNull(choice.getFinishReason());
349+
assertTrue(choice.getIndex() >= 0);
350+
351+
if (choice.getMessage() != null) {
352+
assertNotNull(choice.getMessage().getContent());
353+
}
354+
}
355+
356+
@Test
357+
public void testConverseAlpha2MultipleInputs() {
358+
// Create multiple conversation inputs
359+
List<ConversationInputAlpha2> inputs = new ArrayList<>();
360+
361+
// First input - greeting
362+
UserMessage greeting = new UserMessage(List.of(new ConversationMessageContent("Hello!")));
363+
ConversationInputAlpha2 input1 = new ConversationInputAlpha2(List.of(greeting));
364+
inputs.add(input1);
365+
366+
// Second input - question
367+
UserMessage question = new UserMessage(List.of(new ConversationMessageContent("How are you?")));
368+
ConversationInputAlpha2 input2 = new ConversationInputAlpha2(List.of(question));
369+
input2.setScrubPii(true);
370+
inputs.add(input2);
371+
372+
ConversationRequestAlpha2 request = new ConversationRequestAlpha2("echo", inputs);
373+
374+
ConversationResponseAlpha2 response = daprPreviewClient.converseAlpha2(request).block();
375+
376+
assertNotNull(response);
377+
assertNotNull(response.getOutputs());
378+
assertTrue(response.getOutputs().size() > 0);
379+
380+
// Should handle multiple inputs appropriately
381+
for (ConversationResultAlpha2 result : response.getOutputs()) {
382+
assertNotNull(result.getChoices());
383+
assertTrue(result.getChoices().size() > 0);
384+
}
385+
}
386+
}

sdk-tests/src/test/java/io/dapr/it/testcontainers/conversations/DaprConversationIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,4 @@ public void testConversationSDKShouldScrubPIIOnlyForTheInputWhereScrubPIIIsSet()
132132
response.getConversationOutputs().get(1).getResult());
133133
}
134134
}
135+

0 commit comments

Comments
 (0)