6f54d765c4
La reponse embarquait la definition EasyBuilder complete, au-dela du seuil de
rejet du client MCP (~70 000 caracteres, D24). Deux parametres de fenetre au
schema (D23) : max_data_chars (defaut 20 000) et data_offset (defaut 0). Les
metadonnees du workflow restent completes dans chaque tranche ; seul `data`
est fenetre, et dataTotalChars est porte par toute reponse.
La tranche est verbatim -- decoupe de chaine, rien d'autre. Ne jamais resumer
ni parser ce blob : la concatenation des tranches doit reconstituer la
definition a l'octet pres. Verifie : 20 000 + 20 000 + 20 000 + 11 512 =
71 512, concatenation identique au blob d'origine (premiers et derniers
caracteres compris).
Mesures avant/apres (protocole, LIMAGRAIN, longueur de content[0].text) :
StackerCrane_LocationIsAccessibleByExtractor_PR 79 092 -> 23 117
(blob data : 71 512, desormais annonce par dataTotalChars)
CST_SendRejectContainersToPK (CustomApp) 101 816 -> 23 023
(blob data : 92 362)
StackerCrane_LoadMovementForOutboundTask_PR 10 587 -> 10 652
(blob de 9 013 : sous le defaut, objet workflow identique a l'octet pres,
ni truncated ni hint -- les +65 caracteres sont les trois champs de
fenetre, contrat "total toujours porte" de D24)
Gardes de valeur dans le code de l'outil, pas dans le wrapper (D23 ne valide
que les noms) : data_offset: -5 et max_data_chars: 1.5 echouent avant tout
appel reseau avec un message nommant l'attendu.
Baseline preservee : 23 outils, 6 resources.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
168 lines
8.7 KiB
Markdown
168 lines
8.7 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.2 — Garde de taille sur les outils de requête
|
|
|
|
Une ligne Writing = un agrégat complet sérialisé (95 288 caractères là où la
|
|
même ligne Reading en fait ~4 500) ; 200 lignes Reading = ~957 000 ; `search_wms_data`
|
|
= ~848 000. Garde de taille commune sur `query_wms_entities`, `call_query_api`
|
|
et `search_wms_data` : lignes entières écartées, `truncated`/`returned`/`omitted`/`hint`
|
|
(D24). Ne pas réduire `MAX_QUERY_ROWS` ni les limites par défaut.
|
|
|
|
### 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).
|