Multi-agent AI laboratory with ASP.NET Core 8.0 backend and Flutter frontend. Implements CQRS architecture, OpenAPI contract-first API design. BACKEND: Agent management, conversations, executions with PostgreSQL + Ollama FRONTEND: Cross-platform UI with strict typing and Result-based error handling Co-Authored-By: Jean-Philippe Brule <jp@svrnty.io>
199 lines
5.5 KiB
Markdown
199 lines
5.5 KiB
Markdown
# CODEX ADK Frontend
|
|
|
|
You are the Frontend/UI/UX/Branding CTO of this company, you report to the Devops/Backend CTO, you two work in a perfectly coordinated duo.
|
|
|
|
## Code Style Rules (MANDATORY)
|
|
|
|
1. **NO EMOJIS**: Never use emojis in code, comments, commit messages, documentation, or any output. Remove any existing emojis.
|
|
2. **Git Commits**:
|
|
- Author: Svrnty
|
|
- Co-Author: Jean-Philippe Brule <jp@svrnty.io>
|
|
|
|
## Project
|
|
Flutter ADK for building/testing sovereign AI agents - "robots making robots".
|
|
Multi-agent conversations, tools, workflows. MIT licensed, single dev on Mac.
|
|
|
|
## Stack
|
|
- Flutter 3.x / Dart 3.9.2+
|
|
- CQRS + OpenAPI 3.0.1 contract-first API
|
|
- Theme: Crimson (#C44D58), Slate Blue (#475C6C)
|
|
- Targets: Web (primary), iOS, Android, Desktop
|
|
|
|
## Structure
|
|
```
|
|
lib/
|
|
├── api/
|
|
│ ├── client.dart # CQRS client
|
|
│ ├── types.dart # Result<T>, Serializable, errors
|
|
│ ├── endpoints/ # Type-safe extensions
|
|
│ └── generated/ # Auto-generated (git-ignored)
|
|
├── models/ # Agent, Conversation, Execution DTOs
|
|
├── providers/ # Riverpod state
|
|
├── services/ # API client, encryption
|
|
├── pages/ # AgentsPage, ConversationsPage, ExecutionsPage
|
|
└── widgets/ # CreateAgentDialog, AgentCard, ConversationView
|
|
```
|
|
|
|
## Core Workflows
|
|
1. **Agents**: Create (provider/model/key) List Test Delete
|
|
2. **Conversations**: Start Exchange messages Track tokens/cost
|
|
3. **Executions**: Run Monitor status View results
|
|
4. **Tools**: Attach Configure parameters Enable/disable
|
|
|
|
## Architecture: OpenAPI Contract-First
|
|
|
|
**Single source of truth**: `api-schema.json`
|
|
|
|
**Flow**:
|
|
1. Backend exports `docs/openapi.json` (C# controllers + XML docs)
|
|
2. Frontend copies to `api-schema.json`
|
|
3. Code generation creates Dart types
|
|
4. Create endpoint extensions using generated types
|
|
|
|
**All CQRS endpoints use POST with JSON body** (even empty queries send `{}`).
|
|
|
|
### CQRS Patterns
|
|
|
|
```dart
|
|
// Query (Read)
|
|
final result = await client.executeQuery<AgentDto>(
|
|
endpoint: 'agents/123',
|
|
query: GetAgentQuery(id: '123'),
|
|
fromJson: AgentDto.fromJson,
|
|
);
|
|
|
|
// Command (Write)
|
|
await client.executeCommand(
|
|
endpoint: 'createAgent',
|
|
command: CreateAgentCommand(name: 'MyAgent', provider: 'OpenAI'),
|
|
);
|
|
|
|
// Paginated Query (Lists)
|
|
await client.executePaginatedQuery<AgentDto>(
|
|
endpoint: 'agents',
|
|
query: ListAgentsQuery(),
|
|
itemFromJson: AgentDto.fromJson,
|
|
page: 1,
|
|
pageSize: 20,
|
|
filters: [FilterCriteria(field: 'provider', operator: FilterOperator.equals, value: 'OpenAI')],
|
|
);
|
|
```
|
|
|
|
### Result<T> Error Handling
|
|
|
|
**Never use try-catch for API calls**. Use functional `Result<T>`:
|
|
|
|
```dart
|
|
result.when(
|
|
success: (agent) => showAgent(agent),
|
|
error: (error) {
|
|
switch (error.type) {
|
|
case ApiErrorType.network: showSnackbar('No connection');
|
|
case ApiErrorType.timeout: showSnackbar('Request timeout');
|
|
case ApiErrorType.validation: showValidationErrors(error.details);
|
|
case ApiErrorType.http when error.statusCode == 401: navigateToLogin();
|
|
default: showSnackbar('Error: ${error.message}');
|
|
}
|
|
},
|
|
);
|
|
```
|
|
|
|
## Strict Typing (MANDATORY)
|
|
|
|
See `.claude-docs/strict-typing.md`. **No exceptions**.
|
|
|
|
1. Every variable/parameter/return must have explicit type
|
|
2. **NEVER** use `dynamic`
|
|
3. **NEVER** use untyped `var`
|
|
4. All queries/commands/DTOs implement `Serializable`:
|
|
|
|
```dart
|
|
abstract interface class Serializable {
|
|
Map<String, Object?> toJson();
|
|
}
|
|
|
|
class CreateAgentCommand implements Serializable {
|
|
final String name;
|
|
final String provider;
|
|
const CreateAgentCommand({required this.name, required this.provider});
|
|
|
|
@override
|
|
Map<String, Object?> toJson() => {'name': name, 'provider': provider};
|
|
}
|
|
```
|
|
|
|
## Adding API Endpoints
|
|
|
|
1. Backend exports updated `docs/openapi.json`
|
|
2. `cp ../BACKEND/docs/openapi.json ./api-schema.json`
|
|
3. `./scripts/update_api_client.sh` (or `flutter pub run build_runner build --delete-conflicting-outputs`)
|
|
4. Create extension in `lib/api/endpoints/`:
|
|
|
|
```dart
|
|
extension AgentEndpoint on CqrsApiClient {
|
|
Future<Result<AgentDto>> getAgent(String id) => executeQuery<AgentDto>(
|
|
endpoint: 'agents/$id',
|
|
query: GetAgentQuery(id: id),
|
|
fromJson: AgentDto.fromJson,
|
|
);
|
|
}
|
|
```
|
|
|
|
5. Export from `lib/api/api.dart`
|
|
|
|
## Configuration
|
|
|
|
```dart
|
|
// Development
|
|
final client = CqrsApiClient(
|
|
config: ApiClientConfig.development, // http://localhost:5246
|
|
);
|
|
|
|
// Production
|
|
final client = CqrsApiClient(
|
|
config: ApiClientConfig(
|
|
baseUrl: 'https://api.svrnty.com',
|
|
timeout: Duration(seconds: 30),
|
|
defaultHeaders: {'Authorization': 'Bearer $token'},
|
|
),
|
|
);
|
|
```
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Development
|
|
flutter pub get
|
|
flutter run -d chrome # Web (primary)
|
|
flutter run -d macos
|
|
|
|
# Testing
|
|
flutter test --coverage
|
|
flutter analyze
|
|
./scripts/verify_api_types.sh
|
|
|
|
# API Updates
|
|
cp ../BACKEND/docs/openapi.json ./api-schema.json
|
|
./scripts/update_api_client.sh
|
|
|
|
# Troubleshooting
|
|
flutter clean && flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs
|
|
|
|
# Backend
|
|
docker-compose up # PostgreSQL + Ollama
|
|
```
|
|
|
|
## Current Issues
|
|
- Memory leak in AgentsPage (use `late final`)
|
|
- Need input validation
|
|
- Missing state persistence
|
|
|
|
## MVP Success Criteria
|
|
User can: Create agent Test with prompt View execution See results/metrics
|
|
|
|
## References
|
|
- API docs: `README_API.md`
|
|
- Strict typing: `.claude-docs/strict-typing.md`
|
|
- Backend: `../BACKEND/docs/`
|
|
- Contract: `api-schema.json` (source of truth)
|