# src/container-runner.ts Modification Intent

## What Changed

Modified the container runner to support multiple execution modes (container, TUI, direct API) and provider abstraction.

## Changes Made

### 1. New Imports

```typescript
import {
  createExecutionProvider,
  AIProvider,
  ProviderError,
  ProviderUnavailableError,
} from './providers/index.js';
import {
  AI_PROVIDER,
  EXECUTION_MODE,
  getModelForProvider,
  FALLBACK_PROVIDER,
  FALLBACK_MODEL,
} from './config.js';
```

### 2. Provider Instance Caching

```typescript
let cachedProvider: AIProvider | null = null;

function getProvider(): AIProvider {
  if (!cachedProvider) {
    cachedProvider = createExecutionProvider(EXECUTION_MODE, AI_PROVIDER);
  }
  return cachedProvider;
}
```

### 3. Modified runInContainer()

The function now checks `EXECUTION_MODE` before deciding how to execute:

```typescript
export async function runInContainer(
  input: ContainerInput,
  group: RegisteredGroup,
): Promise<ContainerOutput> {
  switch (EXECUTION_MODE) {
    case 'direct':
      return runDirect(input);
    case 'tui':
      return runWithTUI(input);
    case 'container':
    default:
      return runInContainerProcess(input, group);
  }
}
```

### 4. Direct Execution Mode

```typescript
async function runDirect(input: ContainerInput): Promise<ContainerOutput> {
  try {
    const provider = getProvider();
    const result = await provider.execute(input.prompt, {
      model: getModelForProvider(),
      systemPrompt: buildSystemPrompt(input),
    });

    return {
      status: 'success',
      result: result.content,
    };
  } catch (error) {
    if (error instanceof ProviderError) {
      // Try fallback provider if configured
      if (FALLBACK_PROVIDER) {
        return runWithFallback(input, error);
      }
    }
    return {
      status: 'error',
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}
```

### 5. TUI Execution Mode

```typescript
async function runWithTUI(input: ContainerInput): Promise<ContainerOutput> {
  const provider = new CodingAgentProvider({
    model: getModelForProvider(),
  });

  // TUI mode spawns coding-agent process
  return runDirect(input); // Same logic, different provider
}
```

### 6. Fallback Provider Logic

```typescript
async function runWithFallback(
  input: ContainerInput,
  originalError: ProviderError,
): Promise<ContainerOutput> {
  logger.warn(
    `Primary provider failed: ${originalError.message}. Trying fallback...`,
  );

  const fallbackProvider = createExecutionProvider(
    EXECUTION_MODE,
    FALLBACK_PROVIDER,
  );

  try {
    const result = await fallbackProvider.execute(input.prompt, {
      model: FALLBACK_MODEL || getModelForProvider(FALLBACK_PROVIDER),
      systemPrompt: buildSystemPrompt(input),
    });

    return {
      status: 'success',
      result: result.content,
    };
  } catch (fallbackError) {
    logger.error(`Fallback provider also failed: ${fallbackError}`);
    return {
      status: 'error',
      error: originalError.message,
    };
  }
}
```

### 7. Environment Variable Passing

When `EXECUTION_MODE=container`, pass provider config to container:

```typescript
const envVars: Record<string, string> = {
  // ... existing vars
  AI_PROVIDER,
  EXECUTION_MODE,
  CLAUDE_MODEL,
  OPENAI_MODEL,
  GEMINI_MODEL,
};
```

## Invariants

1. **Backwards Compatibility**: Existing container-based execution is the default. No behavior change unless `EXECUTION_MODE` is explicitly set.

2. **Error Handling**: All execution modes return the same `ContainerOutput` type for consistency.

3. **Logging**: Mode selection and fallbacks are logged for debugging.

4. **Session Management**: Direct and TUI modes don't support session persistence (no sessionId returned).

5. **Security**: API keys are only passed to containers via environment, never logged.

## Execution Mode Comparison

| Mode      | Isolation          | Overhead | Features                              |
| --------- | ------------------ | -------- | ------------------------------------- |
| container | Full (jail/Docker) | Moderate | All features, session persistence     |
| tui       | Process isolation  | Low      | Interactive debugging, no persistence |
| direct    | None               | Minimal  | Fastest, no persistence, no isolation |

## Testing Considerations

1. Test each execution mode
2. Test fallback provider switching
3. Test error propagation
4. Test session handling differences
5. Test environment variable passing

## Migration Path

Existing deployments:

1. No changes required - defaults to 'container' mode
2. To use TUI mode: Set `EXECUTION_MODE=tui` and install coding-agent
3. To use direct API: Set `EXECUTION_MODE=direct`

New deployments:

1. Choose execution mode based on requirements
2. Set appropriate provider API keys
3. Configure fallback if desired
