director — Cross-feature transition coordinator
Director
Director
Coordinator of transitions between features (scenes).
Instantiated in the handler for each incoming request. Stores the request context (user_id, chat_id, state) and passes itself to orchestrators as an argument — no mutable state in the orchestrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container
|
ContainerProtocol
|
Project's DI container with a |
required |
state
|
FSMContext | None
|
FSM context of the current user. |
None
|
user_id
|
int | None
|
Telegram ID of the user. |
None
|
chat_id
|
int | None
|
Target chat ID. |
None
|
trigger_id
|
int | None
|
ID of the trigger message (e.g., /start) for subsequent deletion. |
None
|
Example
director = Director(
container=container,
state=state,
user_id=callback.from_user.id,
chat_id=callback.message.chat.id,
)
view = await director.set_scene(feature="booking", payload=None)
await sender.send(view)
Source code in src/codex_bot/director/director.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
Functions
set_scene(feature, payload=None)
async
Cross-feature transition: changes FSM state and calls the feature orchestrator.
Algorithm:
1. Retrieves the orchestrator by key from container.features.
2. Sets the FSM state if the orchestrator has declared it.
3. Passes itself to handle_entry(director=self, payload=payload).
4. Enriches the result with chat_id and session_key as a fallback.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature
|
str
|
Orchestrator key in |
required |
payload
|
Any
|
Data to pass to |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
UnifiedViewDTO or any orchestrator result. None if the feature is not found. |
Source code in src/codex_bot/director/director.py
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
Protocols
OrchestratorProtocol
Bases: Protocol
Minimum contract for a stateless feature orchestrator.
The Director works through this protocol without knowing about specific classes. BaseBotOrchestrator implements it automatically.
The orchestrator must be stateless — it does not store user state.
Context is passed via the director argument on each call.
Source code in src/codex_bot/director/protocols.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
Functions
handle_entry(director, payload=None)
async
Entry point into the feature.
Source code in src/codex_bot/director/protocols.py
53 54 55 56 57 58 59 | |
render(payload, director)
async
Renders content for the passed payload.
Source code in src/codex_bot/director/protocols.py
49 50 51 | |
ContainerProtocol
Bases: Protocol
Minimum contract for the project's DI container.
The Director only requires the features attribute — a dictionary of orchestrators.
The specific BotContainer of the project must provide this attribute.
Attributes:
| Name | Type | Description |
|---|---|---|
features |
dict[str, OrchestratorProtocol]
|
Dictionary of |
Example
class BotContainer:
def __init__(self):
self.features: dict[str, Any] = {}
Source code in src/codex_bot/director/protocols.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
SceneConfig
Bases: NamedTuple
Scene configuration: FSM state + entry-point service key.
Used in the project's SCENE_ROUTES to describe cross-feature transitions.
Attributes:
| Name | Type | Description |
|---|---|---|
fsm_state |
State
|
Aiogram State set when entering the scene. |
entry_service |
str
|
Orchestrator key in the container registry (e.g., |
Example
SCENE_ROUTES = {
"booking": SceneConfig(
fsm_state=BookingStates.main,
entry_service="booking",
),
}
Source code in src/codex_bot/director/protocols.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |