# CrewAI Specialist Implementation Guide

## Name Sensitivity
A lot of the required functionality to implement specialists has been automated. This automation is based on naming
conventions. So ... names of variables, attributes, ... needs to be precise, or you'll get into problems.

## Base Class: CrewAIBaseSpecialistExecutor

The base class for defining new CrewAI based Specialists is CrewAIBaseSpecialistExecutor. This class implements a lot of
functionality out of the box, making the full development process easier to manage:

- Before the specialist execution
  - Retrieval of context (RAG Retrieval)
  - Build up of historic context (memory)
  - Initialisation of Agents, Tasks and tools (defined in the specialist configuration)
  - Initialisation of specialist state, based on historic context
- During specialist execution
  - Updates to the history (ChatSession and Interaction)
  - Formatting of the results

It enables the following functionality:

- Logging when requested (_log_tuning)
- Sending progress updates (ept)
- ...

### Naming Conventions
- tasks are referenced by using the lower case name of the configured task. Their names should always end on "_task"
- agents idem dito, but their names should end on "_agent"
- tools idem dito, but their names will end on "_tools"

## Implementation

### Step 1 - Code location

The implementation of a specialist should be placed in the specialists folder. If the specialist is a global specialist
(i.e. it can be used by all tenants), it will be in the globals folder. If it is created for a specific partner, we will
place it in the folder for that partner (lower_case)

The naming of the implementation is dependent on the version of the specialist we are creating. If we implement a
version 1.0, the implementation will be called "1_0.py". This implementation is also used for specialists with different
patch versions (e.g. 1.0.1, 1.0.4, ...)

### Step 2: type and type_version properties

- Adapt the type and type_version properties to define the correct specialist. This refers to the actual specialist configuration!

### Step 3: Specialist Setup 

#### Specialising init

Use specialisisation of the init method to define the crews you require, and if needed, additional initialisation code.

#### configuring the specialist

- _config_task_agents
  - Link each task to the agent that will perform the task
  - use _add_task_agent for each of the tasks
- _config_pytdantic_outputs
  - Link each task to a specific output (Pydantic)
  - use _add_pydantic_output for each of the tasks
- _config_state_result_relations
  - Zorg dat er een automatische overdracht kan zijn van state naar result
  - use _add_state_result_relation om zo'n relatie toe te voegen
  - when you give the attributes in the state and result the same names, this becomes quite obvious and easy to maintain

### Step 4: Implement specialist execution

This is the entry method invoked to actually implement specialist logic.

#### Available data

- arguments: the arguments passed in the specialist invocation
- formatted_context: the documents retrieved for the specialist
- citations: the citations found in the retrieval process
- self._formatted_history: a build-up of the history of the conversation
- self._cached_session: the complete cached session
- self.flow.state: the current flow state

#### Implementation guidelines

- allways use self.flow.state to update elements required to have available in consecutive calls, or elements you want to persist in the results
- use the phase (defined in the state) to distinguish between phases in the specialist execution
- Use "SelectionResult.create_for_type(self.type, self.type_version)" to return results. 

### Step 5: Define Implementation Classes

- Define the Pydantic Output Classes to ensure structured outputs
- Define an Input class, containing all potential inputs required for flows and crews to perform their activities
- Define a FlowState (derived from EveAIFlowState) to maintain state throughout specialist execution
- Define a Result (derived from SpecialistResult) to define all information that needs to be stored in the session
- Define the Flow (derived from EveAICrewAIFlow) with the FlowState class