@mostajs/auto-pilot
v0.1.0
Published
Modélisation assistée : langue naturelle → forme d'étude (StudyForm, un dialecte par forme) → problème typé → optimisation. Chaînon entre @mostajs/chat-stack (NL/tool-use) et @mostajs/ro-pla (solveurs). Solveur et LLM injectés (DI), outils chatbot study_c
Maintainers
Readme
@mostajs/auto-pilot
Auteur : Dr Hamid MADANI [email protected] · Licence : AGPL-3.0-or-later
Modélisation assistée : langue naturelle → forme d'étude → problème typé → optimisation. Chaînon
entre @mostajs/chat-stack (NL / tool-use) et @mostajs/ro-pla
(solveurs). Le solveur et le LLM sont injectés (DI) ; auto-pilot ne réinvente ni l'un ni l'autre, il
les compose.
Idée
Une StudyForm est un « dialecte de modélisation » (même patron que l'ORM / ro-pla) :
study_catalog → propose_model (brouillon) → [validation humaine] → solve (solveur) → explainExemple — affecter des guichets à des tickets (fil rouge TicketFlow)
import { createAutoPilot } from "@mostajs/auto-pilot";
import { solve as roSolve } from "@mostajs/ro-pla"; // solveur injecté
const pilot = createAutoPilot({ solver: roSolve, defaults: { timeoutMs: 1000 } });
const res = await pilot.solve("assignment", {
cost: [[4, 1], [2, 3]],
rows: ["Guichet 1", "Guichet 2"],
cols: ["Ticket A", "Ticket B"],
});
console.log(res.explanation);
// Affectation optimale (coût total 3) :
// • Guichet 1 → Ticket B (coût 1)
// • Guichet 2 → Ticket A (coût 2)Mapping des formes → algorithmes
Chaque StudyForm porte un kind qui auto-sélectionne le dialecte de @mostajs/ro-pla via
solve({ kind, ... }). Le mapping livré :
| Forme (StudyForm) | kind | Dialecte ro-pla | Algorithme | Quand l'utiliser |
|---|---|---|---|---|
| assignment | assignment | hungarian | Kuhn-Munkres O(n³) | Affecter N agents à N tâches (1↔1), coût total minimal |
| production | lp / milp | simplex / branch-and-bound | Simplexe 2 phases / séparation-évaluation | Max/min d'un objectif linéaire sous contraintes (continu, ou entier si integers) |
| queue-sizing | queue | mmc | M/M/c (Erlang C) + dimensionnement | Combien de guichets/serveurs pour tenir un objectif d'attente |
| decision | decision | mdp | Itération de la valeur | Politique optimale de décision séquentielle (« Markov qui décide ») |
| csp | csp | backtrack-csp | Backtracking + coupe | Variables sous contraintes (planning, coloration, sans conflit) |
| flow | flow | min-cost-flow | Plus courts chemins successifs (SPFA) | Router un flot source→puits sous capacités (généralise l'affectation, N≠M) |
| markov | markov | markov | Système linéaire / matrice fondamentale | Régime stationnaire, régime pas-à-pas, temps/probas d'absorption |
| tsp | metaheuristic | anneal | Recuit simulé | Tournée ~minimale (voyageur de commerce) depuis une matrice de distances |
| queue-simulation | simulation | monte-carlo | Simulation à événements discrets | Estimer l'attente M/M/c par simulation (valide la formule fermée) |
| lagrangian | lp* | lagrangian | Relaxation + sous-gradient | Borner un LP par décomposition (contraintes liantes + sous-système) |
*
lagrangianpartage lekindlpavecsimplex; la forme portedialect:"lagrangian"pour forcer le bon dialecte (le pilote le transmet ensolver(problem, { dialect })). Ajouter une forme = un fichier danssrc/forms/(déclarerkeywordspour le routagepickForm, etdialectsi lekindest ambigu).
Utiliser les formes
Toujours via pilot.solve("<forme>", <champs>) (ou pilot.propose("<forme>", <champs>) pour un aperçu
sans résoudre). Les champs attendus de chaque forme sont exposés par pilot.catalog() (ou l'outil
study_catalog). pilot.solve renvoie { form, model, problem, solution, explanation }.
assignment — affectation 1↔1
Voir l'exemple ci-dessus. Matrice carrée des coûts ; rows/cols optionnels (libellés). N≠M → forme flow (à venir).
production — optimisation linéaire (lp / milp)
await pilot.solve("production", {
objective: "max", variables: ["A", "B"], c: [3, 2],
constraints: [
{ coeffs: [1, 1], relation: "<=", rhs: 4 },
{ coeffs: [1, 3], relation: "<=", rhs: 6 },
],
// integers: [0, 1], // ← variables entières → PLNE (branch & bound)
});
// → "Solution optimale (objectif maximal = 12) : • A = 4 • B = 0"queue-sizing — dimensionnement M/M/c
await pilot.solve("queue-sizing", { lambda: 1.6, mu: 1, maxWait: 1, unit: "guichet" });
// → "Il faut 3 guichet(s) pour tenir l'objectif. • attente moyenne ≈ 0.196 · P(attendre) ≈ 27.4 % · occupation ≈ 53 %"lambda = arrivées / unité de temps, mu = service / serveur ; objectif maxWait et/ou maxProbWait (au moins un).
decision — politique optimale (MDP)
await pilot.solve("decision", {
transition: [[[1, 0], [0, 1]], [[0, 1], [1, 0]]], // transition[état][action][état']
reward: [[0, 0], [1, 1]], // reward[état][action]
gamma: 0.9,
states: ["Repos", "Service"], actions: ["rester", "aller"],
});
// → "Politique optimale : • Repos → aller (valeur 9.000) • Service → rester (valeur 10.000)"csp — satisfaction de contraintes
await pilot.solve("csp", {
variables: ["A", "B", "C"],
domains: [[1, 2, 3], [1, 2, 3], [1, 2, 3]],
constraints: [
{ kind: "allDifferent", vars: [0, 1, 2] },
{ kind: "relation", a: 0, b: 1, op: "<" }, // A < B
{ kind: "relation", a: 1, b: 2, op: "<" }, // B < C
],
});
// → "Affectation valide : • A = 1 • B = 2 • C = 3"Contraintes déclaratives : allDifferent (indices) ou relation (a op b, op ∈ < <= > >= = !=).
flow — flot de coût minimal
await pilot.solve("flow", {
arcs: [{ from: 0, to: 1, capacity: 5, cost: 2 }, { from: 1, to: 2, capacity: 5, cost: 3 }],
source: 0, sink: 2, value: 4, nodeLabels: ["entrée", "relais", "sortie"],
});
// → "Flot optimal = 4, coût total = 20 • entrée → relais : 4 (coût/u 2) • relais → sortie : 4 (coût/u 3)"Sans value : flot maximal au moindre coût. Généralise l'affectation (capacités > 1, N≠M).
markov — chaîne de Markov
await pilot.solve("markov", { P: [[0.9, 0.1], [0.5, 0.5]], query: "stationary", states: ["Calme", "Affluence"] });
// → "Distribution stationnaire : • Calme : 0.8333 • Affluence : 0.1667"
// query: "step" (régime après `steps` depuis `initial`) | "absorbing" (temps/probas d'absorption)tsp — tournée minimale (voyageur de commerce)
await pilot.solve("tsp", {
distance: [[0, 1, 2, 1], [1, 0, 1, 2], [2, 1, 0, 1], [1, 2, 1, 0]],
cities: ["A", "B", "C", "D"], steps: 20000, seed: 1,
});
// → "Tournée (longueur ≈ 4.000) : A → B → C → D → A" (métaheuristique : ~optimal, RNG seedé)queue-simulation — M/M/c par simulation
await pilot.solve("queue-simulation", { lambda: 0.5, mu: 1, c: 1, customers: 4000, trials: 40, seed: 7 });
// → "Attente moyenne en file (simulée) ≈ 1.0xx ± 0.0xx (M/M/1, λ=0.5, μ=1, 40 exécutions × 4000 clients)"
// Croise/valide la formule fermée de la forme queue-sizing.lagrangian — relaxation lagrangienne (décomposition)
await pilot.solve("lagrangian", {
objective: "max", c: [1, 1],
linking: [{ coeffs: [1, 1], rhs: 4 }], // contrainte LIANTE (relâchée)
sub: [{ coeffs: [1, 0], rhs: 3 }, { coeffs: [0, 1], rhs: 3 }], // sous-système borné
iters: 3000,
});
// → "Borne lagrangienne (max) ≈ 4.000x en 3000 itérations. Multiplicateurs μ = [1.00x] · point associé : x1=…, x2=…"Routage automatique (langue naturelle → forme)
import { pickForm } from "@mostajs/auto-pilot";
pickForm("combien de guichets pour réduire l'attente ?"); // → { name: "queue-sizing", score, scores }
pickForm("quelle politique de décision adopter ?"); // → { name: "decision", ... }Côté chatbot, l'outil suggest_form expose ce routage.
Intégration chatbot (@mostajs/chatbot)
import { createAutoPilot, makeAutoPilotTools } from "@mostajs/auto-pilot";
import { solve as roSolve } from "@mostajs/ro-pla";
import { registerTool } from "@mostajs/chatbot";
const pilot = createAutoPilot({ solver: roSolve });
for (const tool of makeAutoPilotTools({ pilot, permission: "study.run" })) registerTool(tool);
// Le copilote peut désormais : lister les formes (study_catalog), proposer un modèle (propose_model),
// et résoudre après confirmation humaine (solve).Scripts
| Commande | Effet |
|---|---|
| npm test | build TS + suite mjs-unit (forme assignment, bout-en-bout via ro-pla). |
| npm run report | génère test-report.html (preuve de test). |
Statut
0.1.0 — 10 formes (une par dialecte @mostajs/ro-pla) : assignment, production, queue-sizing,
decision, csp, flow, markov, tsp, queue-simulation, lagrangian. Pipeline + outils chatbot
(study_catalog/suggest_form/propose_model/solve) + pickForm(nl), 35/35 tests. Voir llms.txt et docs/.
