The desktop main window has a chat panel on its right side. This reference describes ChatWidget, TaskCard, and the task model in src/cluster_erp/desktop/widgets/chat/: how a typed message becomes an answer, a navigation, or a guided record creation. The intent engine that the panel uses is documented on intent assistant. The web client's chat screens are on assistant and chat screens.
Scope and source¶
- Defined in:
ChatWidget(src/cluster_erp/desktop/widgets/chat/chat_widget.py:795),TaskCard(src/cluster_erp/desktop/widgets/chat/task_card.py:33),ChatTask,TaskField, andbuild_task_fields(src/cluster_erp/desktop/widgets/chat/chat_task.py:12-316). - Count: three Python files with code (2,827, 1,040, and 316 lines) and two background images in
assets/, counted by listing the folder.
Placement and signals¶
MainWindow places the panel as the third column of its splitter. The chat button of the sidebar (key sidebar.chat) and the panel's own close button toggle its width between zero and the last width, 380 pixels by default (src/cluster_erp/desktop/widgets/main_window.py:103-122, src/cluster_erp/desktop/widgets/main_window.py:217-229).
| Signal | Arguments | Received by | Source |
|---|---|---|---|
close_requested |
none | MainWindow._toggle_chat |
src/cluster_erp/desktop/widgets/chat/chat_widget.py:796, src/cluster_erp/desktop/widgets/main_window.py:111 |
navigation_requested |
module, section | MainWindow._on_navigate |
src/cluster_erp/desktop/widgets/chat/chat_widget.py:797, src/cluster_erp/desktop/widgets/main_window.py:112 |
Intent engine¶
The panel creates an IntentEngine from cluster_erp.ai.intent_engine and loads it 100 ms after construction (src/cluster_erp/desktop/widgets/chat/chat_widget.py:47, src/cluster_erp/desktop/widgets/chat/chat_widget.py:818-819). IntentEngine.load reads the en and tr intent corpora from files and fits one vectoriser per language (src/cluster_erp/ai/intent_engine.py:364-394). Recognition therefore runs inside the desktop process. The panel does not call the server's chat routes; a search of the folder for /chat paths returns no match.
Message flow¶
_on_send adds the user's message and any picked files to the conversation, then decides in this order (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1379-1493):
- While a task card is active, a cancel word cancels it, and any other text asks the user to use the card (
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1393-1418). - Small talk is answered from fixed phrase lists in ten categories: help, name, company, identity, permissions, time, mood, thanks, farewell, and greeting (
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1115-1135,src/cluster_erp/desktop/widgets/chat/chat_widget.py:1472-1476). - A message with several requests is split, and the parts are processed one after the other (
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1238-1300,src/cluster_erp/desktop/widgets/chat/chat_widget.py:1479-1493). _process_intentshows a typing indicator and starts recognition (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1495-1499).
_do_recognize_inner asks the engine for the five best matches (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1534-1535). With no match it answers with the text of chat.no_intent_found. When the best confidence is below 0.60, it lists the three best candidates and asks the user to rephrase (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1552-1576). Otherwise it dispatches the best match:
| Match | Response | Source |
|---|---|---|
action hint count |
GET of the list path with limit 1, then the total |
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1590-1592, src/cluster_erp/desktop/widgets/chat/chat_widget.py:1637-1683 |
GET list path and a navigation word in the text |
navigation to the entity's section | src/cluster_erp/desktop/widgets/chat/chat_widget.py:1594-1598, src/cluster_erp/desktop/widgets/chat/chat_widget.py:2222-2244 |
GET list path |
GET with limit 10 and the extracted filters and search term, then the rows |
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1600-1602, src/cluster_erp/desktop/widgets/chat/chat_widget.py:1739-1760 |
POST with create in the intent id |
a task card for the entity | src/cluster_erp/desktop/widgets/chat/chat_widget.py:1604-1606, src/cluster_erp/desktop/widgets/chat/chat_widget.py:2363-2418 |
DELETE, PUT, PATCH, or delete or update in the intent id |
a message that a record is needed, and an offer to open the section | src/cluster_erp/desktop/widgets/chat/chat_widget.py:1608-1633 |
| anything else | an answer from the action hint | src/cluster_erp/desktop/widgets/chat/chat_widget.py:1635, src/cluster_erp/desktop/widgets/chat/chat_widget.py:2246-2266 |
A question with a time expression prefers a list match of the same entity over a single-record match (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1583-1588). The map from entity to sidebar section is built from the metadata (src/cluster_erp/desktop/widgets/chat/chat_widget.py:2189-2220).
Task cards¶
build_task_fields turns the entity's form metadata into a list of steps. It skips read-only fields, hidden scope fields, and auto-generated fields, and keeps choices, the foreign-key source of each field, defaults, limits, conditions, and nested keys (src/cluster_erp/desktop/widgets/chat/chat_task.py:190-316, src/cluster_erp/desktop/widgets/chat/chat_task.py:12-30).
ChatTask walks the steps:
| Member | Behaviour | Source |
|---|---|---|
validate_value |
Checks required, maximum length, and minimum and maximum value, with translated messages | src/cluster_erp/desktop/widgets/chat/chat_task.py:72-89 |
can_skip, skip_current |
Only fields that are not required can be skipped | src/cluster_erp/desktop/widgets/chat/chat_task.py:99-108 |
advance, go_back, go_to, enter_summary |
Move between steps and the summary | src/cluster_erp/desktop/widgets/chat/chat_task.py:110-134 |
collect_data |
Builds the request body, drops fields whose condition does not hold, uses defaults for skipped fields, and nests fields by nested_key |
src/cluster_erp/desktop/widgets/chat/chat_task.py:139-164 |
TaskCard shows one step at a time. A foreign-key step searches the source list with limit 5 (src/cluster_erp/desktop/widgets/chat/task_card.py:465-480). On submit it posts the body to the intent's path with an EntityDescriptor, so the usual change signal follows (src/cluster_erp/desktop/widgets/chat/task_card.py:735-765). After success the panel opens the entity's section (src/cluster_erp/desktop/widgets/chat/chat_widget.py:2435-2451).
Files and voice¶
Files can be picked or dropped onto the panel and appear in the user's message (src/cluster_erp/desktop/widgets/chat/chat_widget.py:2461-2516, src/cluster_erp/desktop/widgets/chat/chat_widget.py:2600-2616). The only post( call in the folder is the task card submit (src/cluster_erp/desktop/widgets/chat/task_card.py:758), and no /attachments path appears, so picked files are not uploaded. The record button runs a timer and, when stopped, adds a voice message with empty content. The folder imports no audio module (src/cluster_erp/desktop/widgets/chat/chat_widget.py:2519-2551).
Constraints and validation¶
- List and count queries and the task card submit call
ApiClientdirectly on the GUI thread, without a worker (src/cluster_erp/desktop/widgets/chat/chat_widget.py:1651,src/cluster_erp/desktop/widgets/chat/chat_widget.py:1758,src/cluster_erp/desktop/widgets/chat/task_card.py:757-764). - The server applies the user's permissions to every call the panel makes; the panel shows the user's permission list only as an answer to a small-talk question (
src/cluster_erp/desktop/widgets/chat/chat_widget.py:1206-1207). - The background image is chosen by theme from
assets/chat_bg_dark.pngorassets/chat_bg_light.png(src/cluster_erp/desktop/widgets/chat/chat_widget.py:2653-2654).
Discrepancies¶
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| chat panel | ChatWidget |
The right-hand desktop panel that answers typed requests with the local intent engine. | sohbet paneli | src/cluster_erp/desktop/widgets/chat/chat_widget.py:795 |
| task card | TaskCard |
A step-by-step form in the conversation, built from metadata for a create intent, that creates one record. | görev kartı | src/cluster_erp/desktop/widgets/chat/task_card.py:33 |
| chat task | ChatTask |
The state of one guided record creation: steps, values, and status. | sohbet görevi | src/cluster_erp/desktop/widgets/chat/chat_task.py:33 |
Related pages¶
Verified against commit 92f8051 on 2026-11-13.