Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions WORKFLOW-TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# Interactive Workflow Testing Guide

This guide shows how to test the new Phase 4 (Loop) and Phase 5 (Interactive) workflow features.

## Quick Start

```bash
cd /Users/layne/Development/genai/dev3
pnpm dev
```

Once Codi starts, try these commands:

---

## Test 1: List Available Workflows

```
/workflow list
```

Should show:
- test-conditional
- test-interactive
- test-interactive-comprehensive
- test-interactive-enhanced
- test-loop
- test-model-switch
- test-switch-demo

---

## Test 2: Show Workflow Details

### Simple Interactive Workflow
```
/workflow show test-interactive
```

Should display:
- Description
- Step count
- Individual step details

### Enhanced Interactive Workflow
```
/workflow show test-interactive-enhanced
```

Should show advanced features like:
- Multiple input types (confirm, choice, text)
- Timeout configurations
- Validation patterns
- Default values

### Loop Workflow
```
/workflow show test-loop
```

Should show:
- Loop step with iteration logic
- Condition for loop execution
- maxIterations safety limit

---

## Test 3: Validate Workflow Syntax

```
/workflow validate test-interactive
```

Should report: βœ… Workflow is valid

```
/workflow validate test-interactive-enhanced
```

Should report: βœ… Workflow is valid (with enhanced features)

```
/workflow validate test-loop
```

Should report: βœ… Workflow is valid

---

## Test 4: Run Simple Workflow

```
/workflow-run test-interactive
```

Expected behavior:
1. Step 1 (shell): Welcome message
2. Step 2 (interactive): Prompt for confirmation
3. Step 3 (shell): Completion message

---

## Test 5: Run Enhanced Workflow

```
/workflow-run test-interactive-enhanced
```

Expected behavior:
1. Welcome message
2. Interactive confirmation with timeout
3. User preferences with choice input
4. Multiple interactive interactions
5. Completion message

---

## Test 6: Run Loop Workflow

```
/workflow-run test-loop
```

Expected behavior:
1. Initialize loop variables
2. Execute loop body with iteration tracking
3. Check condition for repeat
4. Respect maxIterations limit
5. Complete when condition fails

---

## Test 7: Comprehensive Test

```
/workflow-run test-interactive-comprehensive
```

This workflow has:
- 7 total steps
- 3 interactive steps
- Shell commands between interactions
Demonstrates a real-world workflow pattern

---

## Expected Features

### Phase 4 - Loop Support βœ“
- Execute steps in iteration
- Loop condition checking
- maxIterations safety limit
- Iteration counting in state

### Phase 5 - Interactive Features βœ“
- Multiple input types:
- `text` - plain text input
- `password` - masked input
- `confirm` - yes/no confirmation
- `choice` - select from options
- `multiline` - multi-line text
- Timeout handling (`timeoutMs`)
- Default values (`defaultValue`)
- Validation patterns (`validationPattern`)
- Choice options (`choices` array)

---

## Troubleshooting

If workflows don't work:

1. Check workflow files exist:
```bash
ls -la workflows/
```

2. Verify build:
```bash
pnpm build
```

3. Run tests:
```bash
pnpm test workflow
```

4. Check integration:
```bash
grep "interactive" src/workflow/steps/index.ts
grep "loop" src/workflow/steps/index.ts
```

---

## Verification Summary

From automated checks:

| Workflow | Steps | Interactive | Loop | Status |
|----------|-------|-------------|------|--------|
| test-interactive | 3 | 1 | 0 | βœ… |
| test-interactive-enhanced | 8 | 5 | 0 | βœ… |
| test-interactive-comprehensive | 7 | 3 | 0 | βœ… |
| test-loop | 4 | 0 | 1 | βœ… |

All workflows validated and ready for testing! πŸš€
85 changes: 85 additions & 0 deletions src/workflow/steps/ai-prompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2026 Layne Penney
// SPDX-License-Identifier: AGPL-3.0-or-later

import type { WorkflowStep, WorkflowState, AiPromptActionStep } from '../types.js';

export interface AiPromptResult {
response: string;
usage?: {
inputTokens: number;
outputTokens: number;
};
metadata?: Record<string, any>;
}

/**
* Execute an AI prompt action step
*/
export async function executeAiPromptActionStep(
step: AiPromptActionStep,
state: WorkflowState,
agent: any
): Promise<AiPromptResult> {
if (!agent) {
throw new Error('AI prompt action requires agent context');
}

// Expand state variables in prompt
let prompt = step.prompt;
const variables = state.variables || {};

// Replace {{variable}} patterns
prompt = prompt.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
return variables[varName] !== undefined ? String(variables[varName]) : match;
});

try {
// Use the agent's current model, or override with step-specific model
const model = step.model || agent.currentModel;

// Set model if specified
if (step.model) {
await agent.switchModel(step.model);
}

// Execute the prompt and get response
const response = await agent.chat(prompt);

const result: AiPromptResult = {
response: response.text || response.response || 'No response generated',
metadata: {
model: model,
prompt: prompt
}
};

// Store the result in variables for future steps
state.variables = state.variables || {};
state.variables[`${step.id}_response`] = result.response;
state.variables[`${step.id}_metadata`] = result.metadata;

return result;

} catch (error) {
throw new Error(`AI prompt execution failed: ${error instanceof Error ? error.message : String(error)}`);
}
}

/**
* Validate an AI prompt action step
*/
export function validateAiPromptActionStep(step: AiPromptActionStep): void {
if (!step.prompt || typeof step.prompt !== 'string') {
throw new Error('AI prompt action must have a prompt');
}

// Validate prompt length
if (step.prompt.trim().length === 0) {
throw new Error('AI prompt cannot be empty');
}

// If model is specified, validate it
if (step.model && typeof step.model !== 'string') {
throw new Error('AI prompt model must be a string');
}
}
Loading