Skip to content

Commit ec58dac

Browse files
committed
refactor ParallelizationWorkflow
1 parent 01a54cc commit ec58dac

File tree

10 files changed

+324
-130
lines changed

10 files changed

+324
-130
lines changed

core/src/main/java/com/javaaidev/agenticpatterns/core/AbstractAgenticWorkflow.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44
import com.javaaidev.agenticpatterns.core.observation.WorkflowExecutionObservationContext;
55
import com.javaaidev.agenticpatterns.core.observation.WorkflowExecutionObservationDocumentation;
66
import io.micrometer.observation.ObservationRegistry;
7+
import java.util.Objects;
78
import org.jspecify.annotations.Nullable;
89

910
public abstract class AbstractAgenticWorkflow<Request, Response> implements
1011
AgenticWorkflow<Request, Response> {
1112

12-
@Nullable
1313
protected String name;
1414
@Nullable
1515
protected ObservationRegistry observationRegistry;
1616

1717
protected AbstractAgenticWorkflow(@Nullable String name,
1818
@Nullable ObservationRegistry observationRegistry) {
19-
this.name = name;
19+
this.name = Objects.requireNonNullElseGet(name, () -> this.getClass().getSimpleName());
2020
this.observationRegistry = observationRegistry;
2121
}
2222

2323
@Override
2424
public String getName() {
25-
return this.name != null ? this.name : this.getClass().getSimpleName();
25+
return this.name;
2626
}
2727

2828
@Override

examples/src/main/java/com/javaaidev/agenticpatterns/examples/parallelizationworkflow/AlgorithmArticleGenerationAgent.java

Lines changed: 0 additions & 75 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,91 @@
11
package com.javaaidev.agenticpatterns.examples.parallelizationworkflow;
22

3+
import com.javaaidev.agenticpatterns.core.AgentUtils;
4+
import com.javaaidev.agenticpatterns.parallelizationworkflow.DefaultResponseAssembler;
5+
import com.javaaidev.agenticpatterns.parallelizationworkflow.ParallelizationWorkflow;
6+
import com.javaaidev.agenticpatterns.parallelizationworkflow.SubtaskCreationRequest;
7+
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
38
import io.micrometer.observation.ObservationRegistry;
9+
import java.util.List;
10+
import java.util.Map;
11+
import java.util.stream.Collectors;
412
import org.springframework.ai.chat.client.ChatClient;
513
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
14+
import org.springframework.beans.factory.annotation.Qualifier;
615
import org.springframework.context.annotation.Bean;
716
import org.springframework.context.annotation.Configuration;
17+
import org.springframework.util.CollectionUtils;
818

919
@Configuration
1020
public class AlgorithmArticleGenerationConfiguration {
1121

1222
@Bean
13-
public AlgorithmArticleGenerationAgent algorithmArticleGenerationAgent(
23+
@Qualifier("algorithmArticleGenerationWorkflow")
24+
public ParallelizationWorkflow<AlgorithmArticleGenerationRequest, AlgorithmArticleGenerationResponse> algorithmArticleGenerationWorkflow(
1425
ChatClient.Builder chatClientBuilder,
1526
SimpleLoggerAdvisor simpleLoggerAdvisor,
16-
ObservationRegistry observationRegistry) {
17-
return new AlgorithmArticleGenerationAgent(
18-
chatClientBuilder.defaultAdvisors(simpleLoggerAdvisor).build(),
19-
observationRegistry);
27+
ObservationRegistry observationRegistry
28+
) {
29+
var chatClient = chatClientBuilder.defaultAdvisors(simpleLoggerAdvisor).build();
30+
return ParallelizationWorkflow.<AlgorithmArticleGenerationRequest, AlgorithmArticleGenerationResponse>builder()
31+
.subtasksCreator(request -> {
32+
var languages = AgentUtils.safeGet(request,
33+
AlgorithmArticleGenerationRequest::languages, List.<String>of());
34+
if (CollectionUtils.isEmpty(languages)) {
35+
return List.of();
36+
}
37+
return languages.stream().map(
38+
language -> new SubtaskCreationRequest<>(language,
39+
TaskExecutionAgent.<SampleCodeGenerationRequest, AlgorithmArticleGenerationResponse>defaultBuilder()
40+
.promptTemplate("""
41+
Write {language} code to meet the requirement.
42+
{description}
43+
"""
44+
)
45+
.responseType(SampleCodeGenerationResponse.class)
46+
.name("CodeGeneration_" + language)
47+
.chatClient(chatClient)
48+
.observationRegistry(observationRegistry)
49+
.build(),
50+
(AlgorithmArticleGenerationRequest req) -> new SampleCodeGenerationRequest(
51+
language,
52+
"Implement algorithm " + req.algorithm()))).toList();
53+
})
54+
.responseAssembler(
55+
DefaultResponseAssembler.<AlgorithmArticleGenerationRequest, AlgorithmArticleGenerationResponse>builder()
56+
.promptTemplate(
57+
"""
58+
Goal: Write an article about {algorithm}.
59+
60+
Requirements:
61+
- Start with a brief introduction.
62+
- Include only sample code listed below.
63+
- Output the article in markdown.
64+
65+
{sample_code}
66+
""")
67+
.responseType(AlgorithmArticleGenerationResponse.class)
68+
.promptTemplateContextProvider(input -> {
69+
var request = input.request();
70+
var results = input.results();
71+
var algorithm = AgentUtils.safeGet(request,
72+
AlgorithmArticleGenerationRequest::algorithm, "");
73+
var sampleCode = results.allSuccessfulResults().entrySet().stream()
74+
.map(entry -> """
75+
Language: %s
76+
Code:
77+
%s
78+
""".formatted(entry.getKey(),
79+
((SampleCodeGenerationResponse) entry.getValue()).code()))
80+
.collect(Collectors.joining("==========\n", "\n----------\n", "=========="));
81+
return Map.of("algorithm", algorithm, "sample_code", sampleCode);
82+
})
83+
.name("AlgorithmArticleGeneration")
84+
.chatClient(chatClient)
85+
.observationRegistry(observationRegistry)
86+
.build())
87+
.name("algorithmArticleGenerationWorkflow")
88+
.observationRegistry(observationRegistry)
89+
.build();
2090
}
2191
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.javaaidev.agenticpatterns.examples.parallelizationworkflow;
22

3+
import com.javaaidev.agenticpatterns.parallelizationworkflow.ParallelizationWorkflow;
4+
import org.springframework.beans.factory.annotation.Qualifier;
35
import org.springframework.web.bind.annotation.PostMapping;
46
import org.springframework.web.bind.annotation.RequestBody;
57
import org.springframework.web.bind.annotation.RequestMapping;
@@ -9,15 +11,17 @@
911
@RequestMapping("/algorithm_article")
1012
public class AlgorithmArticleGenerationController {
1113

12-
private final AlgorithmArticleGenerationAgent agent;
14+
private final ParallelizationWorkflow<AlgorithmArticleGenerationRequest, AlgorithmArticleGenerationResponse> workflow;
1315

14-
public AlgorithmArticleGenerationController(AlgorithmArticleGenerationAgent agent) {
15-
this.agent = agent;
16+
public AlgorithmArticleGenerationController(
17+
@Qualifier("algorithmArticleGenerationWorkflow") ParallelizationWorkflow<AlgorithmArticleGenerationRequest, AlgorithmArticleGenerationResponse> workflow) {
18+
this.workflow = workflow;
1619
}
1720

21+
1822
@PostMapping
1923
public AlgorithmArticleGenerationResponse generateAlgorithmArticle(
2024
@RequestBody AlgorithmArticleGenerationRequest request) {
21-
return agent.call(request);
25+
return workflow.execute(request);
2226
}
2327
}

examples/src/main/java/com/javaaidev/agenticpatterns/examples/parallelizationworkflow/SampleCodeGenerationAgent.java

Lines changed: 0 additions & 43 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.javaaidev.agenticpatterns.examples.parallelizationworkflow;
2+
3+
public record SampleCodeGenerationRequest(String language, String description) {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.javaaidev.agenticpatterns.examples.parallelizationworkflow;
2+
3+
public record SampleCodeGenerationResponse(String code) {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.javaaidev.agenticpatterns.parallelizationworkflow;
2+
3+
import com.javaaidev.agenticpatterns.parallelizationworkflow.DefaultResponseAssembler.AssemblingInput;
4+
import com.javaaidev.agenticpatterns.taskexecution.AbstractTaskExecutionAgentBuilder;
5+
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
6+
import io.micrometer.observation.ObservationRegistry;
7+
import java.lang.reflect.Type;
8+
import java.util.Map;
9+
import java.util.function.Consumer;
10+
import java.util.function.Function;
11+
import org.jspecify.annotations.Nullable;
12+
import org.springframework.ai.chat.client.ChatClient;
13+
import org.springframework.ai.chat.client.ChatClient.ChatClientRequestSpec;
14+
15+
public class DefaultResponseAssembler<Request, Response> extends
16+
TaskExecutionAgent<AssemblingInput<Request>, Response> implements
17+
ResponseAssembler<Request, Response> {
18+
19+
public DefaultResponseAssembler(ChatClient chatClient,
20+
String promptTemplate, @Nullable Type responseType,
21+
@Nullable Function<AssemblingInput<Request>, Map<String, Object>> promptTemplateContextProvider,
22+
@Nullable Consumer<ChatClientRequestSpec> chatClientRequestSpecUpdater,
23+
@Nullable String name,
24+
@Nullable ObservationRegistry observationRegistry) {
25+
super(chatClient, promptTemplate, responseType, promptTemplateContextProvider,
26+
chatClientRequestSpecUpdater, name, observationRegistry);
27+
}
28+
29+
@Override
30+
public Response assemble(@Nullable Request request, TaskExecutionResults results) {
31+
return this.call(new AssemblingInput<>(request, results));
32+
}
33+
34+
public static <Request, Response> Builder<Request, Response> builder() {
35+
return new Builder<>();
36+
}
37+
38+
public record AssemblingInput<Request>(@Nullable Request request,
39+
TaskExecutionResults results) {
40+
41+
}
42+
43+
public static class Builder<Request, Response> extends
44+
AbstractTaskExecutionAgentBuilder<AssemblingInput<Request>, Response, Builder<Request, Response>> {
45+
46+
@Override
47+
public DefaultResponseAssembler<Request, Response> build() {
48+
return new DefaultResponseAssembler<>(
49+
chatClient,
50+
promptTemplate,
51+
responseType,
52+
promptTemplateContextProvider,
53+
chatClientRequestSpecUpdater,
54+
name,
55+
observationRegistry
56+
);
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)