Copilote roster: outils d'action (marquer_indisponibilite + reassigner_job)

Le copilote peut désormais CHANGER les dispos en langage naturel ('marque Simon malade
aujourd'hui' → crée une Tech Availability approuvée) et réassigner un Dispatch Job, sur
instruction explicite, avec confirmation. Testé OK end-to-end. (SMS client + escalade = suite.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-06-04 11:57:33 -04:00
parent 79d160b9f1
commit 412b6f49a6

View File

@ -101,11 +101,44 @@ const TOOLS = [
parameters: { type: 'object', properties: { technicien_id: { type: 'string' }, date: { type: 'string', description: 'AAAA-MM-JJ' } }, required: ['technicien_id', 'date'] },
},
},
{
type: 'function',
function: {
name: 'marquer_indisponibilite',
description: "ACTION : rend un technicien indisponible (maladie/congé) pour une date — crée une absence APPROUVÉE qui le retire du planning. À utiliser UNIQUEMENT sur instruction explicite (ex: « Simon est malade aujourd'hui, marque-le »).",
parameters: { type: 'object', properties: { technicien_id: { type: 'string' }, date: { type: 'string', description: 'AAAA-MM-JJ' }, type: { type: 'string', enum: ['Maladie', 'Congé', 'Indisponible', 'Pause'], description: 'défaut Maladie' } }, required: ['technicien_id', 'date'] },
},
},
{
type: 'function',
function: {
name: 'reassigner_job',
description: "ACTION : réassigne un rendez-vous/installation (Dispatch Job) à un autre technicien. UNIQUEMENT sur instruction explicite (ex: « réassigne DJ-… à TECH-… »).",
parameters: { type: 'object', properties: { job: { type: 'string' }, technicien_id: { type: 'string' } }, required: ['job', 'technicien_id'] },
},
},
]
// ── Outils d'ACTION (écriture, sur instruction explicite) ───────────────────
async function tool_marquer_indispo ({ technicien_id, date, type }) {
const r = await erp.create('Tech Availability', {
technician: technicien_id, from_date: date, to_date: date,
availability_type: type || 'Maladie', status: 'Approuvé', reason: 'Copilote',
})
if (r && r.ok === false) return { error: r.error || 'échec' }
return { ok: true, message: `${technicien_id} marqué ${type || 'Maladie'} le ${date} (absence approuvée — retiré du planning)` }
}
async function tool_reassigner ({ job, technicien_id }) {
const r = await erp.update('Dispatch Job', job, { assigned_tech: technicien_id })
if (r && r.ok === false) return { error: r.error || 'échec' }
return { ok: true, message: `${job} réassigné à ${technicien_id}` }
}
async function execTool (name, args) {
try {
if (name === 'etat_equipe') return await tool_etat_equipe(args)
if (name === 'jobs_du_technicien') return await tool_jobs_du_technicien(args)
if (name === 'marquer_indisponibilite') return await tool_marquer_indispo(args)
if (name === 'reassigner_job') return await tool_reassigner(args)
return { error: 'outil inconnu' }
} catch (e) { return { error: String(e.message || e) } }
}
@ -137,7 +170,7 @@ RÈGLES :
- Quand on signale un tech absent/malade : appelle etat_equipe(date) pour repérer le tech (par son nom) et la dispo des autres, puis jobs_du_technicien(id, date) pour l'impact.
- Propose CONCRÈTEMENT : pour chaque job touché, suggère 12 techniciens candidats (Disponible, compétences compatibles, charge faible le même jour) OU un report. Mentionne les ids/noms réels.
- Si tu ne trouves pas le tech nommé, dis-le et liste les techniciens proches.
- Tu PROPOSES seulement c'est le superviseur qui confirmera (réassignation, SMS au client, escalade). N'invente pas d'actions effectuées.
- Par défaut tu ANALYSES et PROPOSES. Mais tu peux EXÉCUTER sur instruction explicite : marquer_indisponibilite (rendre un tech absent un jour donné, ex « marque Simon malade aujourd'hui ») et reassigner_job (changer le tech d'un RDV, ex « réassigne DJ- à Jean-Pierre »). Confirme TOUJOURS l'action réalisée (id + date). N'invente jamais une action non effectuée. (SMS client de report + escalade superviseur = à venir.)
- Réponds en français, bref et actionnable (puces).`
}