54a6849563
Aucune borne de VOLUME n'existait sur query_wms_entities, call_query_api et
search_wms_data -- seulement une borne de LIGNES (MAX_QUERY_ROWS). Le modele
Writing serialise l'agregat complet (navigations, $id) : une seule ligne
Products y pese 95 288 caracteres, la ou la meme ligne Reading en fait ~4 500.
Toutes ces reponses depassaient le seuil de rejet du client MCP (D24), qui
renvoie un echec opaque plutot qu'un resultat partiel.
Plafond commun MAX_QUERY_RESPONSE_CHARS (defaut 25 000, meme ordre de grandeur
que MAX_LOG_SEARCH_CHARS), applique par src/services/response-limit.js : on
ecarte des LIGNES ENTIERES, jamais coupees au milieu, et on signale avec le
vocabulaire D24 (truncated / returned / omitted / hint). Le helper est partage
parce que les trois outils partagent le meme mecanisme -- ce que les mecanismes
de get_system_parameters et search_logs, eux, ne font pas. La recherche
dichotomique evite 200 reconstructions d'une charge utile de ~1 Mo.
Mesures avant/apres (protocole, LIMAGRAIN, longueur de content[0].text) :
query_wms_entities Products limit 200 957 234 -> 24 432
count 200, returned 5, omitted 195, truncated
search_wms_data "PAL" 847 543 -> 22 992
totalFound 150, returned 4, omitted 146 ; reparti en tourniquet :
Products 2, Containers 1, Tasks 1 -- sans quoi Products, en tete,
consommerait tout le budget et les deux autres reviendraient a zero
resultat sans que rien ne le dise
call_query_api Products query_type 1 95 288 -> 738
cas limite : returned 0, omitted 1, truncated, hint expliquant le
volume Writing et renvoyant vers Reading
Sous le plafond, rien ne change -- verifie identique OCTET POUR OCTET contre
la version precedente :
query_wms_entities Container limit 1 4 476 -> 4 476
call_query_api Products limit 2 9 671 -> 9 671
get_entity_schema Container 11 172 -> 11 172
search_wms_data sous plafond 11 767 -> 11 767
count_wms_entities Products 120 -> 120 (non concerne)
MAX_QUERY_ROWS et les limites par defaut des outils sont inchanges : le
correctif est le bornage signale, pas une reduction silencieuse. L'avertissement
de volume rejoint la description du parametre query_type (D25) de
query_wms_entities et call_query_api, pas celle de count_wms_entities dont la
reponse est un scalaire.
Baseline preservee : 23 outils, 6 resources.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
160 lines
8.3 KiB
Markdown
160 lines
8.3 KiB
Markdown
# Roadmap
|
|
|
|
Travaux planifiés, par lot. Chaque lot est livrable indépendamment.
|
|
|
|
Constats issus de la session de diagnostic du **24/08/2026** (profil `LIMAGRAIN`,
|
|
host `10.255.255.2`, tenant `LIMAGRAI2512`), déclenchée par un rapport d'usage
|
|
d'une session Cowork. Toutes les anomalies ci-dessous ont été **reproduites**
|
|
contre le WMS réel — ce ne sont pas des hypothèses.
|
|
|
|
Les décisions actées vivent dans [DECISIONS.md](DECISIONS.md) ; ce fichier ne
|
|
contient que ce qui reste à faire.
|
|
|
|
---
|
|
|
|
## Lot 4 — Modèle de données et applications
|
|
|
|
Deux angles morts constatés le 24/08/2026, plus larges que les lots 2 et 3. Les
|
|
chiffres ci-dessous sont mesurés sur le tenant `LIMAGRAI2512`.
|
|
|
|
### L4.1 (reliquat) — Explorer le contexte Metrics
|
|
|
|
L'exposition de `query_type` est livrée (D25). Reste l'investigation : le
|
|
contexte `Metrics` (`QueryType: 3`, `ApplicationMetricDataContext`) mérite une
|
|
exploration à part — c'est probablement là que vivent les données agrégées
|
|
produites par les jobs `MetricGatherer`. Livrable : un rapport, pas du code
|
|
(même phase d'investigation que L4.4).
|
|
|
|
### L4.3 — Identifier le MCP dans les logs du WMS
|
|
|
|
Les requêtes du MCP apparaissent dans les logs du WMS sous
|
|
`Execute error. Client: GNA` — le client OAuth partagé — donc indistinguables de
|
|
celles du vrai client GNA.
|
|
|
|
**La piste `ClientModule` est invalidée** (mesuré le 24/08/2026, lot 1) : le
|
|
champ est bien accepté par `QueryExecute` (pas d'erreur), mais il est **sans
|
|
effet observable**. Une requête en échec envoyée avec
|
|
`ClientModule: "MCP-WMS"` est tracée `Execute error. Client: GNA`, et ni
|
|
`MCP-WMS` ni `ClientModule` n'apparaissent nulle part dans
|
|
`ApplicationService.log` ni `HttpResponseTime.log`. Le `Client:` des logs vient
|
|
du client OAuth, pas du payload — le champ n'a donc **pas** été renseigné.
|
|
|
|
Piste restante (non vérifiée) : un client OAuth dédié au MCP côté EasySTS
|
|
changerait le `Client:` des logs, mais suppose une configuration côté WMS.
|
|
|
|
### L4.4 — Historique d'exécution des workflows par API
|
|
|
|
`ApplicationService` expose une API `WorkflowLog` que le MCP n'utilise pas :
|
|
|
|
| Endpoint | Usage |
|
|
|---|---|
|
|
| `GET /WorkflowLog/GetInstances?processDefinitionId=&skip=&take=&startDateFrom=&startDateTo=` | instances d'un workflow sur une plage de dates, filtrables par attribut |
|
|
| `GET /WorkflowLog/GetInstance?processId=` | une instance |
|
|
| `GET /WorkflowLog/GetLogs?processId=&skip=&take=&logDateFrom=&logDateTo=` | journal d'exécution d'une instance |
|
|
| `GET /WorkflowLog/Validate?applicationName=&processDefinitionId=` | validation d'une définition |
|
|
|
|
Endpoints joignables et fonctionnels — `Validate` renvoie
|
|
`{"Success":true,"ErrorMessage":null,"Warnings":[]}`. `GetInstances` répond `[]`
|
|
sur le workflow testé : à confirmer sur un workflow ayant réellement tourné, la
|
|
journalisation n'étant pas forcément active partout.
|
|
|
|
**Peut remettre en cause D16** (historique des shipment templates jugé hors de
|
|
portée faute de logs fichier) : si l'historique d'exécution est disponible par
|
|
API, la conclusion change. À vérifier avant d'écrire quoi que ce soit.
|
|
|
|
### L4.5 — Champs de `QueryExecute` inexploités
|
|
|
|
La référence de l'API documente des champs que le MCP n'envoie jamais :
|
|
|
|
| Champ | Intérêt |
|
|
|---|---|
|
|
| `Parameters` | requêtes **paramétrées** (dictionnaire `nom -> {TypeName, Value}`) — supprimerait toute concaténation de chaîne dans les filtres, et pourrait débloquer D13 (`Select`) |
|
|
| `CommandTimeout` | timeout par requête, au lieu du timeout HTTP global de 30 s |
|
|
| `QueryId` + `POST /QueryCancel` | annulation d'une requête longue |
|
|
| `POST /QueryExecuteStream` | résultats en flux — piste long terme pour les sorties volumineuses, au-delà du bornage signalé de D24 |
|
|
|
|
Autres endpoints jamais utilisés, à évaluer : `QueryEvents`, `QueryCommands`,
|
|
`QueryCorrelationEvents`, `QuerySnapshots` (event sourcing — utile en debug),
|
|
`GET /Metadata/Commands|Events|Aggregates` et leurs variantes `…All`,
|
|
`GET /configuration/applications` (liste les applications **avec leur version**,
|
|
plus riche que `/AD/api/Application/GetAll`), `GET /healthcheck?tenantCode=` et
|
|
`GET /ready?tenantCode=` (sondes de disponibilité, répondent 200).
|
|
|
|
---
|
|
|
|
---
|
|
|
|
## Lot 5 — Clore la famille D24 (rejets client sur sorties volumineuses)
|
|
|
|
Mesures du 25/08/2026 (protocole, LIMAGRAIN), toutes au-dessus du seuil de
|
|
rejet client (~70 000 caractères, D24) :
|
|
|
|
| Appel | Taille |
|
|
|---|---:|
|
|
| `query_wms_entities("Products", limit: 200)` — Reading ordinaire | **957 234** |
|
|
| `search_wms_data("PAL")` | **847 543** |
|
|
| `get_workflow_details(CST_SendRejectContainersToPK)` | ~101 800 |
|
|
| `call_query_api("Products", query_type: 1, limit: 1)` — **une seule ligne** Writing | **95 288** |
|
|
|
|
### L5.3 — Champ `tool` absent des erreurs construites localement
|
|
|
|
Les `catch` locaux d'`api-tools.js` renvoient `{ success: false, error }` sans
|
|
le champ `tool` du contrat (convention 3) — antérieur au lot 4. Balayer tous
|
|
les modules d'outils pour le même motif.
|
|
|
|
### L5.4 — Rendre les autres applications découvrables depuis `search_workflows`
|
|
|
|
Cas réel (25/08/2026, session Cowork sur LIMAGRAIN) : une session cherchant
|
|
des workflows `CST_*` sans passer `application: "CustomApp"` a conclu à tort
|
|
« l'AD contient 4 012 workflows, aucun CST_ » — alors que
|
|
`CST_PickingTasksSequencing_PR` et `CST_ChooseDestinationFromPS` existent bien
|
|
dans CustomApp (vérifié en révision). Le paramètre `application` (D26) existe,
|
|
mais rien dans la **réponse** ne signale qu'on n'a regardé qu'une application.
|
|
|
|
Ajouter aux réponses de `search_workflows` (et `search_ad_elements`) un rappel
|
|
peu coûteux : l'application interrogée, et — quand la recherche renvoie peu ou
|
|
pas de résultats — un hint listant les autres applications (la liste allégée
|
|
d'`Application/GetAll` est déjà en cache, D26) avec renvoi vers le paramètre
|
|
`application`. Aucun préchargement des autres applications (D26).
|
|
|
|
---
|
|
|
|
## Écarté
|
|
|
|
| Proposition | Raison |
|
|
|---|---|
|
|
| Uniformiser les noms de paramètres (`entity_type` / `query` partout) | Casse les usages existants ; les alias de transition doublent la surface à maintenir. La cause réelle est traitée par L2.2. |
|
|
| Exposer un `indexStatus` sur `generic_search` | `TotalDocuments: 0` est déjà le signal. Le MCP n'a aucun moyen d'interroger l'état de l'index de recherche. |
|
|
| Outil dédié `get_query_syntax_help` | L'information doit se trouver dans le message d'erreur, là où elle est lue (L2.1), pas dans un outil qu'il faut penser à appeler. |
|
|
|
|
---
|
|
|
|
## Points ouverts (hors lots)
|
|
|
|
- **Profil `AD` : tenant introuvable** (mesuré le 24/08/2026). `npm test -- --all`
|
|
échoue 0/4 sur ce profil ; le STS de `10.255.255.2` répond
|
|
`400 {"error":"invalid_request","error_description":"Tenant not found"}` pour
|
|
le tenant `AD`. L'hôte et le STS fonctionnent (LIMAGRAIN, même hôte, passe
|
|
4/4) : c'est la valeur `AD_TENANT` du `.env` qui ne correspond plus à un
|
|
tenant existant. Correction côté propriétaire du dépôt (mettre à jour ou
|
|
retirer le profil) — pas un bug du code. Depuis L3.2, le corps de la réponse
|
|
du STS (`Tenant not found`) remonte dans les erreurs d'outils et du smoke
|
|
test.
|
|
- **Bascule de profil concurrente aux appels en vol** (mesuré le 25/08/2026,
|
|
révision du lot 2). Le serveur traite les `tools/call` **en concurrence** :
|
|
en envoyant une rafale de requêtes dans une même session, les réponses
|
|
reviennent dans le désordre, et un `switch_wms_profile` émis pendant que des
|
|
requêtes sont en vol les fait partir sur le nouveau profil (observé : une
|
|
requête destinée à EUROTRAFIC exécutée sur l'hôte `10.255.255.2` après la
|
|
bascule suivante). Conséquence du singleton d'état global (D8). Sans gravité
|
|
pour un usage conversationnel séquentiel, mais Claude peut émettre des appels
|
|
d'outils **en parallèle** : à traiter si un cas réel de mélange de profils
|
|
est observé (piste : sérialiser les `tools/call` ou figer le profil résolu au
|
|
début de chaque appel).
|
|
- **`select_expression`** : les projections via le paramètre `Select` provoquent
|
|
des erreurs de compilation côté serveur (D13). Irritant principal restant.
|
|
- **Déploiement SSH sur la VM** : l'exécutable est validé, la configuration SSH
|
|
reste à faire.
|
|
- **Historique des shipment templates** : hors de portée, les logs concernés
|
|
n'existent pas sur l'hôte joignable (D16).
|