# Then Chaining Implementation Specification

## Overview
This document specifies the expected behavior for `then` chaining functionality in the Alloy language, as demonstrated by the failing tests in `tests/test_interpreter.py`.

## Basic Syntax
```alloy
result = operation1() then operation2 then operation3
result, error = operation1() then operation2 then operation3
```

## Expected Behavior

### 1. Data Flow
- The result from the left operation becomes the input to the right operation
- Each operation returns a `(result, error)` tuple
- If `error` is not `None`, the chain stops and returns the error immediately

### 2. Basic Chaining
```alloy
tool double takes x returns result {
    result = x * 2
    return result
}

tool add_ten takes x returns result {
    result = x + 10  
    return result
}

final_result, error = double(5) then add_ten
# Expected: final_result = 20, error = None
# Computation: (5 * 2) + 10 = 20
```

### 3. Multiple Chaining
```alloy
result = tool1(input) then tool2 then tool3 then tool4
# Each tool receives the result from the previous tool
```

### 4. Error Propagation
```alloy
tool failing_tool takes x returns result {
    result = (null, "Tool failed")
    return result
}

tool success_tool takes x returns result {
    result = x + "_processed"
    return result
}

final_result, error = success_tool("test") then failing_tool then success_tool
# Expected: final_result = null, error = "Tool failed"
# Chain stops at first error
```

### 5. Mixed Operations
```alloy
# Tools and agent commands can be chained together
result = prepare_data("input") then claude Analyze then format_output
```

### 6. Agent Chaining
```alloy
claude = agent "claude-3.5-sonnet"
result = claude Research "topic" then process_analysis
```

## Implementation Requirements

The current `_visit_chain` method in `interpreter.py` needs to be fixed to:

1. **Pass results correctly**: The result from the left operation should be passed as input to the right operation
2. **Handle error propagation**: If any operation returns an error, stop the chain and return the error
3. **Support all operation types**: Handle both tool calls and agent commands in chains
4. **Maintain tuple consistency**: Always return `(result, error)` tuples

## Current Implementation Issues

The current implementation:
```python
def _visit_chain(self, node: tuple, env: Environment) -> Any:
    """Execute a chain operation"""
    left_node, right_node = node[1], node[2]
    res1, err1 = self.visit(left_node, env)
    
    if err1:
        return None, err1
    
    res2, err2 = self.visit(right_node, env)  # PROBLEM: doesn't pass res1 to right_node
    return res2, err2
```

### Problems:
1. Doesn't pass `res1` to `right_node`
2. Doesn't handle the case where `right_node` needs to receive `res1` as input
3. Doesn't properly handle different node types in chains

## Test Coverage

The failing tests cover:
- ✅ Basic chaining (`test_then_chaining_basic`)
- ✅ Multiple chaining (`test_then_chaining_multiple`)  
- ✅ Data flow (`test_then_chaining_data_flow`)
- ✅ Error propagation (`test_then_chaining_error_propagation`)
- ✅ Agent chaining (`test_then_chaining_with_agents`)
- ✅ Agent to tool chaining (`test_then_chaining_agent_to_tool`)
- ✅ Complex pipelines (`test_then_chaining_complex_pipeline`)
- ✅ Nested calls (`test_then_chaining_with_nested_calls`)
- ✅ Error in middle (`test_then_chaining_error_in_middle`)
- ✅ Single assignment (`test_then_chaining_single_assignment`)

## Next Steps

1. **Fix the parser**: Ensure chaining operations are parsed correctly
2. **Implement proper `_visit_chain`**: Pass results between operations
3. **Add support for mixed operations**: Handle tools and agents in chains
4. **Implement error handling**: Proper error propagation
5. **Test iteratively**: Run the failing tests to guide implementation

All tests should pass once the chaining functionality is correctly implemented.