README.md
  1  # DriftKit Workflow Engine Agents
  2  
  3  This module provides the LLMAgent framework for simplified AI interactions within DriftKit workflows.
  4  
  5  ## Overview
  6  
  7  The LLMAgent framework offers a high-level, type-safe API for AI operations that can be seamlessly integrated with the DriftKit workflow engine. It simplifies complex ModelClient interactions while providing powerful features like tool calling, structured output, and agent composition patterns.
  8  
  9  ## Key Features
 10  
 11  - **Simplified API**: Clean `execute*()` methods for common AI operations
 12  - **Type Safety**: `AgentResponse<T>` wrapper for typed results
 13  - **Tool Calling**: Both manual and automatic execution modes
 14  - **Structured Output**: JSON schema-based extraction
 15  - **Multi-modal Support**: Text + images in single interface
 16  - **Agent Patterns**: LoopAgent for iteration, SequentialAgent for pipelines
 17  - **Memory Management**: Built-in conversation history
 18  - **Prompt Templates**: Integration with DriftKit's prompt service
 19  
 20  ## Integration with Workflow Engine
 21  
 22  ### Using LLMAgent in Workflow Steps
 23  
 24  ```java
 25  @Component
 26  public class AIWorkflowSteps {
 27      private final LLMAgent agent;
 28      
 29      public AIWorkflowSteps(ModelClient modelClient) {
 30          this.agent = LLMAgent.builder()
 31              .modelClient(modelClient)
 32              .systemMessage("You are a helpful assistant")
 33              .temperature(0.7)
 34              .build();
 35      }
 36      
 37      @Step("analyze-content")
 38      public StepResult<ContentAnalysis> analyzeContent(String content, WorkflowContext ctx) {
 39          AgentResponse<ContentAnalysis> response = agent.executeStructured(
 40              content, 
 41              ContentAnalysis.class
 42          );
 43          return StepResult.success(response.getStructuredData());
 44      }
 45      
 46      @Step("generate-response")
 47      public StepResult<String> generateResponse(ContentAnalysis analysis, WorkflowContext ctx) {
 48          String prompt = "Based on this analysis: " + analysis.getSummary() + 
 49                         ", generate a helpful response.";
 50          return StepResult.success(agent.executeText(prompt).getText());
 51      }
 52  }
 53  ```
 54  
 55  ### Building Workflows with AI Steps
 56  
 57  ```java
 58  public class CustomerSupportWorkflow {
 59      
 60      public Workflow<CustomerQuery, SupportResponse> build() {
 61          AIWorkflowSteps aiSteps = new AIWorkflowSteps(modelClient);
 62          SupportSteps supportSteps = new SupportSteps();
 63          
 64          return WorkflowBuilder.define("customer-support", CustomerQuery.class, SupportResponse.class)
 65              .then(supportSteps::validateQuery)
 66              .then(aiSteps::analyzeContent)
 67              .branch(ctx -> ctx.step("analyze-content").output(ContentAnalysis.class)
 68                  .map(a -> a.getIntent() == Intent.COMPLAINT).orElse(false),
 69                  complaintFlow -> complaintFlow
 70                      .then(supportSteps::escalateToHuman)
 71                      .then(aiSteps::generateEscalationResponse),
 72                  normalFlow -> normalFlow
 73                      .then(aiSteps::generateResponse)
 74                      .then(supportSteps::formatResponse)
 75              )
 76              .build();
 77      }
 78  }
 79  ```
 80  
 81  ## Agent Composition Patterns
 82  
 83  ### Loop Pattern for Iterative Refinement
 84  
 85  ```java
 86  // Create a loop agent for content generation with quality control
 87  LoopAgent contentGenerator = LoopAgent.builder()
 88      .worker(LLMAgent.builder()
 89          .modelClient(modelClient)
 90          .systemMessage("Generate engaging blog posts")
 91          .build())
 92      .evaluator(LLMAgent.builder()
 93          .modelClient(modelClient)
 94          .systemMessage("Evaluate content quality. Return {\"status\": \"COMPLETE\"} if excellent.")
 95          .build())
 96      .stopCondition(LoopStatus.COMPLETE)
 97      .maxIterations(3)
 98      .build();
 99  
100  // Use in workflow
101  @Step("generate-blog-post")
102  public StepResult<String> generateBlogPost(String topic, WorkflowContext ctx) {
103      String result = contentGenerator.execute("Write about: " + topic);
104      return StepResult.success(result);
105  }
106  ```
107  
108  ### Sequential Pattern for Multi-Stage Processing
109  
110  ```java
111  // Create a pipeline for document processing
112  SequentialAgent documentProcessor = SequentialAgent.builder()
113      .agent(extractorAgent)    // Extract key information
114      .agent(summarizerAgent)   // Summarize content
115      .agent(formatterAgent)    // Format for output
116      .build();
117  
118  // Use in workflow
119  @Step("process-document")
120  public StepResult<ProcessedDocument> processDocument(String rawText, WorkflowContext ctx) {
121      String result = documentProcessor.execute(rawText);
122      return StepResult.success(new ProcessedDocument(result));
123  }
124  ```
125  
126  ## Tool Integration
127  
128  ### Registering Tools with Agents
129  
130  ```java
131  // Define a tool
132  @Component
133  public class WeatherTool implements Tool<WeatherRequest, WeatherResponse> {
134      @Override
135      public WeatherResponse execute(WeatherRequest request) {
136          // Implementation
137      }
138  }
139  
140  // Register with agent
141  LLMAgent weatherAgent = LLMAgent.builder()
142      .modelClient(modelClient)
143      .systemMessage("Help users with weather information")
144      .build();
145  
146  weatherAgent.registerTool("getWeather", weatherTool, "Get current weather");
147  
148  // Use in workflow
149  @Step("weather-query")
150  public StepResult<String> handleWeatherQuery(String query, WorkflowContext ctx) {
151      AgentResponse<List<ToolExecutionResult>> response = 
152          weatherAgent.executeWithTools(query);
153      
154      // Process tool results
155      return StepResult.success(formatWeatherResponse(response.getToolResults()));
156  }
157  ```
158  
159  ## Best Practices
160  
161  1. **Agent Reuse**: Create agents as Spring beans and inject them into workflow steps
162  2. **Error Handling**: Wrap agent calls in try-catch blocks within workflow steps
163  3. **Context Passing**: Use WorkflowContext to pass data between AI and non-AI steps
164  4. **Type Safety**: Leverage structured output for type-safe data extraction
165  5. **Memory Management**: Configure appropriate token windows for conversation history
166  
167  ## Migration from workflows-core
168  
169  If you're migrating from the old `driftkit-workflows-core` module:
170  
171  1. Update your dependencies:
172  ```xml
173  <!-- Remove -->
174  <dependency>
175      <groupId>ai.driftkit</groupId>
176      <artifactId>driftkit-workflows-core</artifactId>
177  </dependency>
178  
179  <!-- Add -->
180  <dependency>
181      <groupId>ai.driftkit</groupId>
182      <artifactId>driftkit-workflow-engine-agents</artifactId>
183  </dependency>
184  ```
185  
186  2. Update imports:
187  ```java
188  // Old
189  import ai.driftkit.workflows.core.agent.*;
190  
191  // New
192  import ai.driftkit.workflow.engine.agent.*;
193  ```
194  
195  3. No API changes required - the agent interfaces remain the same!
196  
197  ## Examples
198  
199  See the `src/test/java` directory for comprehensive examples of:
200  - Basic agent usage
201  - Tool integration
202  - Agent composition patterns
203  - Workflow integration
204  - Error handling strategies