CODEX_ADK/FRONTEND/claude.md
Svrnty 229a0698a3 Initial commit: CODEX_ADK monorepo
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>
2025-10-26 23:12:32 -04:00

5.5 KiB

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

// 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 Error Handling

Never use try-catch for API calls. Use functional Result<T>:

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:
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/:
extension AgentEndpoint on CqrsApiClient {
  Future<Result<AgentDto>> getAgent(String id) => executeQuery<AgentDto>(
    endpoint: 'agents/$id',
    query: GetAgentQuery(id: id),
    fromJson: AgentDto.fromJson,
  );
}
  1. Export from lib/api/api.dart

Configuration

// 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

# 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)