# Agent API Integration - Complete Guide

**Status:** ✅ **READY FOR USE** (Phase 1 Complete)
**Last Updated:** 2025-10-26
**Backend Version:** v1.0.0-mvp

---

## Quick Start

### 1. Import the API Client

```dart
import 'package:console/api/api.dart';
```

### 2. Create an Agent

```dart
final CqrsApiClient client = CqrsApiClient(
  config: ApiClientConfig.development,
);

final Result<void> result = await client.createAgent(
  CreateAgentCommand(
    name: 'Code Generator',
    description: 'AI agent for code generation',
    type: AgentType.codeGenerator,
    modelProvider: 'ollama',
    modelName: 'phi',
    providerType: ModelProviderType.localEndpoint,
    modelEndpoint: 'http://localhost:11434',
    systemPrompt: 'You are a code generation assistant',
    temperature: 0.7,
    maxTokens: 4000,
  ),
);

result.when(
  success: (_) => print('Agent created!'),
  error: (error) => print('Error: ${error.message}'),
);
```

### 3. Get Agent Details

```dart
final Result<AgentDto> result = await client.getAgent('agent-uuid');

result.when(
  success: (agent) {
    print('Name: ${agent.name}');
    print('Status: ${agent.status.value}');
    print('Model: ${agent.modelProvider}/${agent.modelName}');
  },
  error: (error) => print('Error: ${error.message}'),
);
```

---

## Available Operations

### Commands (Write Operations)

#### Create Agent
```dart
Future<Result<void>> createAgent(CreateAgentCommand command)
```

**Required Fields:**
- `name` (String) - Display name
- `description` (String) - Purpose and capabilities
- `type` (AgentType) - Agent type enum
- `modelProvider` (String) - e.g., "ollama", "openai", "anthropic"
- `modelName` (String) - e.g., "phi", "gpt-4o", "claude-3.5-sonnet"
- `providerType` (ModelProviderType) - CloudApi, LocalEndpoint, or Custom
- `systemPrompt` (String) - Behavior instructions

**Optional Fields:**
- `modelEndpoint` (String?) - Required for LocalEndpoint
- `apiKey` (String?) - Required for CloudApi (encrypted by backend)
- `temperature` (double) - Default: 0.7, Range: 0.0-2.0
- `maxTokens` (int) - Default: 4000
- `enableMemory` (bool) - Default: true
- `conversationWindowSize` (int) - Default: 10, Range: 1-100

#### Update Agent
```dart
Future<Result<void>> updateAgent(UpdateAgentCommand command)
```

**Required Fields:**
- `id` (String) - Agent UUID

**Optional Fields:** All other fields from CreateAgentCommand plus:
- `status` (AgentStatus?) - Active, Inactive, or Error

**Note:** Only provide fields you want to update. Omit fields to keep existing values.

#### Delete Agent
```dart
Future<Result<void>> deleteAgent(DeleteAgentCommand command)
```

Performs soft-delete (agent not removed from database, just marked as deleted).

### Queries (Read Operations)

#### Get Agent
```dart
Future<Result<AgentDto>> getAgent(String id)
```

Returns full agent details including configuration and timestamps.

---

## Enums Reference

### AgentType
```dart
enum AgentType {
  codeGenerator,  // 'CodeGenerator'
  codeReviewer,   // 'CodeReviewer'
  debugger,       // 'Debugger'
  documenter,     // 'Documenter'
  custom,         // 'Custom'
}
```

### AgentStatus
```dart
enum AgentStatus {
  active,    // 'Active'
  inactive,  // 'Inactive'
  error,     // 'Error'
}
```

### ModelProviderType
```dart
enum ModelProviderType {
  cloudApi,       // 'CloudApi' - OpenAI, Anthropic, etc.
  localEndpoint,  // 'LocalEndpoint' - Ollama, local models
  custom,         // 'Custom' - Custom endpoints
}
```

---

## Response Types

### AgentDto
```dart
class AgentDto {
  final String id;
  final String name;
  final String description;
  final AgentType type;
  final String modelProvider;
  final String modelName;
  final ModelProviderType providerType;
  final String? modelEndpoint;
  final double temperature;
  final int maxTokens;
  final String systemPrompt;
  final bool enableMemory;
  final int conversationWindowSize;
  final AgentStatus status;
  final DateTime createdAt;
  final DateTime updatedAt;
}
```

---

## Error Handling

### Using when()
```dart
result.when(
  success: (agent) {
    // Handle success
  },
  error: (error) {
    switch (error.type) {
      case ApiErrorType.network:
        // No internet connection
      case ApiErrorType.timeout:
        // Request took too long
      case ApiErrorType.http:
        if (error.statusCode == 404) {
          // Agent not found
        } else if (error.statusCode == 401) {
          // Unauthorized (JWT missing/invalid)
        } else if (error.statusCode == 400) {
          // Validation error
        }
      case ApiErrorType.validation:
        // Backend validation failed
      case ApiErrorType.serialization:
        // JSON parsing error
      case ApiErrorType.unknown:
        // Unexpected error
    }
  },
);
```

### Using Switch Expression
```dart
final String message = switch (result) {
  ApiSuccess(value: final agent) => 'Success: ${agent.name}',
  ApiError(error: final err) when err.statusCode == 404 => 'Agent not found',
  ApiError(error: final err) => 'Error: ${err.message}',
};
```

---

## Common Use Cases

### Local Ollama Agent
```dart
await client.createAgent(
  CreateAgentCommand(
    name: 'Local Code Reviewer',
    description: 'Reviews code using local Ollama',
    type: AgentType.codeReviewer,
    modelProvider: 'ollama',
    modelName: 'codellama:7b',
    providerType: ModelProviderType.localEndpoint,
    modelEndpoint: 'http://localhost:11434',
    systemPrompt: 'You are a code review expert.',
    temperature: 0.5,
  ),
);
```

### Cloud API Agent (OpenAI)
```dart
await client.createAgent(
  CreateAgentCommand(
    name: 'GPT-4 Debugger',
    description: 'Advanced debugging with GPT-4',
    type: AgentType.debugger,
    modelProvider: 'openai',
    modelName: 'gpt-4o',
    providerType: ModelProviderType.cloudApi,
    apiKey: 'sk-...', // Will be encrypted by backend
    systemPrompt: 'You are an expert debugger.',
    temperature: 0.3,
    maxTokens: 8000,
  ),
);
```

### Update Agent Status
```dart
await client.updateAgent(
  UpdateAgentCommand(
    id: agentId,
    status: AgentStatus.inactive,
  ),
);
```

### Update Multiple Fields
```dart
await client.updateAgent(
  UpdateAgentCommand(
    id: agentId,
    name: 'Updated Name',
    temperature: 0.8,
    maxTokens: 6000,
    status: AgentStatus.active,
  ),
);
```

---

## Configuration

### Development (localhost)
```dart
final client = CqrsApiClient(
  config: ApiClientConfig.development, // http://localhost:5246
);
```

### Android Emulator
```dart
final client = CqrsApiClient(
  config: ApiClientConfig(
    baseUrl: 'http://10.0.2.2:5246', // Special emulator IP
    timeout: Duration(seconds: 30),
  ),
);
```

### Production
```dart
final client = CqrsApiClient(
  config: ApiClientConfig(
    baseUrl: 'https://api.svrnty.com',
    timeout: Duration(seconds: 30),
    defaultHeaders: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer $jwtToken', // Add JWT when ready
    },
  ),
);
```

---

## Testing

### Run Tests
```bash
flutter test
```

### Analyze Code
```bash
flutter analyze lib/api/endpoints/agent_endpoint.dart
```

### Verify API Connection
```dart
// Check backend health first
final healthResult = await client.checkHealth();
healthResult.when(
  success: (isHealthy) => print('Backend ready: $isHealthy'),
  error: (error) => print('Backend not reachable: ${error.message}'),
);
```

---

## Files Reference

### Implementation Files
- `lib/api/endpoints/agent_endpoint.dart` - Agent CRUD operations
- `lib/api/api.dart` - Main API export file
- `lib/api/client.dart` - CQRS client implementation
- `lib/api/types.dart` - Core types (Result, errors, pagination)

### Examples
- `lib/api/examples/agent_example.dart` - Complete usage examples

### Backend Contract
- `api-schema.json` - OpenAPI specification (source of truth)
- `../BACKEND/docs/openapi.json` - Backend source (copy to update)
- `../BACKEND/docs/COMPLETE-API-REFERENCE.md` - Full API docs

---

## Important Notes

### Strict Typing
All code follows **strict typing rules** from `CLAUDE.md`:
- ✅ Every variable has explicit type annotation
- ✅ Every function parameter is typed
- ✅ Every function return value is typed
- ❌ No `dynamic` types
- ❌ No untyped `var` declarations

### CQRS Pattern
All endpoints follow CQRS:
- **Commands** return `Result<void>` (no data on success)
- **Queries** return `Result<T>` with typed data
- All requests use **POST** with JSON body (even empty `{}`)

### Functional Error Handling
- ✅ Use `Result<T>` pattern matching
- ✅ Use `when()` or switch expressions
- ❌ Never use try-catch for API calls

### Security
- API keys are **encrypted** by backend (AES-256)
- JWT authentication **not yet implemented** (v2)
- CORS configured for localhost development

---

## Backend Changelog Monitoring

Always check backend changes before updating:

```bash
# View backend changelog
cat ../BACKEND/docs/CHANGELOG.md

# Update API schema when backend changes
cp ../BACKEND/docs/openapi.json ./api-schema.json

# Regenerate if needed (future)
flutter pub run build_runner build --delete-conflicting-outputs
```

---

## Next Steps

### Phase 2 (Coming Soon)
- Conversation endpoints (create, get, list)
- Agent execution endpoints (start, complete, get)
- Real-time execution updates

### Phase 3 (Future)
- JWT authentication integration
- List/pagination endpoints
- Advanced filtering and sorting

---

## Support

- **Questions?** Check `README_API.md` for CQRS architecture
- **Backend Docs:** `../BACKEND/docs/COMPLETE-API-REFERENCE.md`
- **OpenAPI Spec:** `api-schema.json` (source of truth)
- **Examples:** `lib/api/examples/agent_example.dart`

---

**Status:** ✅ **Production-ready for Agent CRUD operations**
**Last Tested:** 2025-10-26 with backend v1.0.0-mvp
