gigafibre-fsm/services/targo-hub/lib/agent-tools.json
louispaulb 0ec7a8cbba feat(assistant): check_signal — live signal parity with F ("Do Stuff get")
The staff Assistant reported "signal non mesurable à distance" for fibre modems
because check_service only reads passive status (TR-069 + local SNMP poller),
which has no signal for tech-3 XGS-PON ONUs (olt3/172.17.x). F gets it live via
the n8n dostuff GET — the assistant just never called it.

New read tool check_signal (parity with F's live "get"):
- fibre: dostuffStatus (n8n, OLT live → Rx/Tx dBm, distance, uptime, VoIP/IPTV/
  WAN/firmware); tech-2 fallback to olt-snmp getOnuBySerial.
- sans-fil (airOS): airosSignal via the F bridge (signal/signal-AP/CCQ/TX-RX
  rate/airMAX capacity).
- resolves the customer's equipment from Service Equipment (prefers ONU w/ olt_ip,
  else CPE w/ ip_address). Quality advice (fibre Rx thresholds, airOS dBm).
- check_service now points at check_signal when signal is null; system prompt
  forbids concluding "non mesurable" without calling check_signal first.

Verified live on the reported case (Frédérick Séguin C-710816574555903 →
TPLGA1E7FA90 @ OLT 172.17.0.7): Rx -16.74 / Tx -11.77 dBm, "bon", distance 2024 m.
check_signal registered in staff tools.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 18:18:47 -04:00

40 lines
24 KiB
JSON

[
{ "type": "function", "function": { "name": "get_customer_info", "description": "Get customer account information: name, type, territory, contact details, flags", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "description": "Customer ID (e.g. C-LPB4)" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "get_subscriptions", "description": "Get active service subscriptions: plan names, prices, billing frequency, status", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "get_invoices", "description": "Get recent invoices: amounts, dates, payment status, outstanding balance", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" }, "limit": { "type": "number", "description": "Max invoices (default 5)" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "get_outstanding_balance", "description": "Get total outstanding (unpaid) balance across all invoices", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "get_service_locations", "description": "Get service locations (addresses) with connection type", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "get_equipment", "description": "Get equipment (routers, ONTs) installed: serial numbers, MAC, status", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "check_device_status", "description": "Quick snapshot of device status via TR-069 + SNMP. Returns online/offline, uptime, signal levels. NOTE: if the device appears offline, do NOT tell the customer it is offline — instead call start_connection_check to run a thorough background verification.", "parameters": { "type": "object", "properties": { "serial_number": { "type": "string", "description": "Device serial number" } }, "required": ["serial_number"] } } },
{ "type": "function", "function": { "name": "check_onu_status", "description": "Check ONU status from OLT SNMP: online/offline, signal levels, last offline cause (Dying Gasp, Branch Fiber Cut, LOSi), recent events history.", "parameters": { "type": "object", "properties": { "serial_number": { "type": "string", "description": "Device serial number (ONU serial)" } }, "required": ["serial_number"] } } },
{ "type": "function", "function": { "name": "start_connection_check", "description": "IMPORTANT: Use this tool instead of telling the customer their connection is offline. Launches a background verification that polls the device 3 times over ~90 seconds via both TR-069 and OLT SNMP, then automatically sends the diagnostic result to the customer. Tell the customer 'Nous vérifions votre connexion, un instant...' while the check runs. Do NOT announce the device as offline before this check completes.", "parameters": { "type": "object", "properties": { "serial_number": { "type": "string", "description": "Device serial number" }, "customer_id": { "type": "string", "description": "Customer ID" } }, "required": ["serial_number", "customer_id"] } } },
{ "type": "function", "function": { "name": "analyze_outage", "description": "Analyze a device outage by correlating with other ONUs on the same OLT port. Determines if the problem is isolated (single customer) or widespread (multiple customers affected). Returns severity, cause type (power outage, fiber cut, backbone issue), recommended action (none/simple_tech/fiber_splicer/escalate_noc). Use this after check_onu_status shows a device offline to understand the scope.", "parameters": { "type": "object", "properties": { "serial_number": { "type": "string", "description": "Device serial number (ONU serial)" } }, "required": ["serial_number"] } } },
{ "type": "function", "function": { "name": "get_open_tickets", "description": "Get open support tickets: subject, status, priority, date", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": ["customer_id"] } } },
{ "type": "function", "function": { "name": "create_ticket", "description": "Create a support ticket when customer reports a problem needing agent follow-up", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" }, "subject": { "type": "string" }, "description": { "type": "string" }, "priority": { "type": "string", "enum": ["Low", "Medium", "High", "Urgent"] } }, "required": ["customer_id", "subject"] } } },
{ "type": "function", "function": { "name": "get_chat_link", "description": "Get the web chat link for this conversation so the customer can continue chatting in a browser instead of SMS", "parameters": { "type": "object", "properties": {} } } },
{ "type": "function", "function": { "name": "create_dispatch_job", "description": "Create an emergency dispatch job and auto-assign to the nearest available technician. Use when: device offline with fiber issue (Rx power < -25 dBm, Branch Fiber Cut), customer reports no internet and troubleshooting fails, or any situation requiring on-site technician.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "description": "Customer ID (e.g. C-LPB4)" }, "service_location": { "type": "string", "description": "Service Location name (from get_service_locations)" }, "subject": { "type": "string", "description": "Job description (e.g. 'Branch Fiber Cut - 691 rue des Hirondelles')" }, "priority": { "type": "string", "enum": ["low", "medium", "high"], "description": "Job priority (default: high for emergencies)" }, "job_type": { "type": "string", "enum": ["Installation", "Réparation", "Maintenance", "Retrait", "Dépannage", "Autre"], "description": "Type of work (default: Dépannage)" }, "notes": { "type": "string", "description": "Additional context (signal levels, error details, customer complaint)" } }, "required": ["customer_id", "subject"] } } },
{ "audience": "staff", "mode": "read", "title": "Lister les techniciens", "type": "function", "function": { "name": "list_technicians", "description": "STAFF/dispatch. Liste les techniciens (id, nom, statut, compétences). Sert à RÉSOUDRE un technicien par son nom (« Simon » → TECH-4693) avant d'assigner/planifier. Filtre optionnel par nom partiel et/ou compétence.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Nom partiel du technicien (optionnel)" }, "skill": { "type": "string", "description": "Compétence requise (optionnel), ex. fibre, monteur, sans-fil" } }, "required": [] } } },
{ "audience": "staff", "mode": "read", "title": "Détails du job", "type": "function", "function": { "name": "get_job", "description": "STAFF/dispatch. Détails d'un Dispatch Job (sujet, statut, technicien assigné, date/heure, client, lieu, durée). Sert à vérifier un job avant de le modifier/réassigner/reporter.", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job, ex. DJ-2026-0001 ou LEG-253958" } }, "required": ["job"] } } },
{ "audience": "staff", "mode": "read", "title": "Compétence requise (diagnostic)", "type": "function", "function": { "name": "resolve_skill", "description": "STAFF/dispatch. DIAGNOSTIC : à partir de la RAISON décrite en langage naturel (ex. « voir signal fibre », « pas d'internet », « installation », « ajout TV ») → détermine la/les COMPÉTENCE(S) terrain requise(s) + la confiance. LECTURE. À appeler AVANT de créer/assigner une intervention, pour cibler la ressource ; enchaîne ensuite find_slot (avec la compétence) pour la disponibilité. Si la raison est vague, pose UNE question avant.", "parameters": { "type": "object", "properties": { "text": { "type": "string", "description": "La raison / le problème décrit par l'utilisateur ou le client" }, "department": { "type": "string", "description": "Département/motif si déjà connu (optionnel)" } }, "required": ["text"] } } },
{ "audience": "staff", "mode": "read", "title": "Trouver un créneau", "type": "function", "function": { "name": "find_slot", "description": "STAFF/dispatch. Propose les meilleurs créneaux disponibles (technicien + date + heure) selon la durée et la compétence requise. LECTURE — ne réserve rien ; présente les options à l'utilisateur.", "parameters": { "type": "object", "properties": { "duration_h": { "type": "number", "description": "Durée en heures (défaut 1)" }, "skill": { "type": "string", "description": "Compétence requise (optionnel)" }, "after_date": { "type": "string", "description": "Chercher à partir de cette date AAAA-MM-JJ (défaut aujourd'hui)" } }, "required": [] } } },
{ "audience": "staff", "mode": "read", "title": "Ressources disponibles", "type": "function", "function": { "name": "resource_availability", "description": "STAFF/dispatch. DIAGNOSTIC : combien de techniciens QUALIFIÉS pour une compétence sont DISPONIBLES sur une période, et combien d'heures libres. LECTURE. À appeler après resolve_skill pour répondre « a-t-on la ressource ? » avant de proposer ; find_slot donnera ensuite les créneaux précis.", "parameters": { "type": "object", "properties": { "skill": { "type": "string", "description": "Compétence requise (issue de resolve_skill), ex. réparation, installation" }, "after_date": { "type": "string", "description": "Dès cette date AAAA-MM-JJ (défaut aujourd'hui)" }, "days": { "type": "number", "description": "Fenêtre en jours (défaut 7)" } }, "required": [] } } },
{ "audience": "staff", "mode": "read", "title": "État du service (modem/signal)", "type": "function", "function": { "name": "check_service", "description": "STAFF/dispatch. DIAGNOSTIC À DISTANCE : état LIVE du service d'un client — modem/ONU en ligne ou hors ligne, puissance du signal (Rx dBm) si connue, abonnement. RAPIDE (statut passif). LECTURE. À utiliser AVANT de proposer un déplacement pour un problème de connexion : si l'équipement est EN LIGNE, propose d'abord un correctif à distance (redémarrage) ; s'il est HORS LIGNE avec signal faible/nul, un déplacement (réparation) est justifié. Si tu as besoin de la FORCE du signal et qu'elle est absente ici, appelle check_signal. Fournis customer (id C-xxxx) ou query (nom/adresse/téléphone/courriel).", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client (C-xxxx) si connu" }, "query": { "type": "string", "description": "Sinon : nom / adresse / téléphone / courriel du client" } }, "required": [] } } },
{ "audience": "staff", "mode": "read", "title": "Signal en direct (comme F)", "type": "function", "function": { "name": "check_signal", "description": "STAFF. MESURE LE SIGNAL EN DIRECT de l'équipement d'un client — parité avec le « Do Stuff get » de F. FIBRE : interroge l'OLT → Rx/Tx dBm, distance, uptime. SANS-FIL (airOS) : signal + signal AP (dBm), CCQ, débit TX/RX, capacité airMAX du CPE. LENT (~10-30 s : interrogation en direct) → préviens « un instant, je mesure le signal… ». À appeler dès qu'on veut la QUALITÉ/FORCE du signal, ou si check_service ne l'a pas. NE conclus JAMAIS « signal non mesurable » sans avoir appelé cet outil. Fournis customer (id C-xxxx) ou serial.", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx (via find_customer)" }, "serial": { "type": "string", "description": "N° de série de l'équipement (optionnel si customer fourni)" } }, "required": [] } } },
{ "audience": "staff", "mode": "read", "title": "Trouver un client", "type": "function", "function": { "name": "find_customer", "description": "STAFF. Recherche un client par nom / adresse / téléphone / courriel et renvoie les CANDIDATS probables. LECTURE. À appeler dès qu'un client n'est PAS déjà identifié par son id (C-xxxx) : UN seul candidat → prends son id et continue ; PLUSIEURS → NE DEVINE PAS, demande brièvement « lequel ? » — l'interface affiche la liste cliquable des candidats, ne les réénumère donc pas tous en texte. Enchaîne l'action avec l'id choisi.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Nom, adresse, téléphone ou courriel (même partiel)" } }, "required": ["query"] } } },
{ "audience": "staff", "mode": "read", "title": "Aperçu client (360)", "type": "function", "function": { "name": "customer_overview", "description": "STAFF. Aperçu 360 d'un client : identité, SOLDE du compte, abonnements actifs, tickets ouverts. LECTURE. Utilise pour « c'est qui ? », « résume le compte », l'état général. Fournis customer (id C-xxxx obtenu via find_customer).", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx (via find_customer)" } }, "required": ["customer"] } } },
{ "audience": "staff", "mode": "read", "title": "Solde et factures", "type": "function", "function": { "name": "customer_balance", "description": "STAFF. SOLDE du compte (montant total dû) + factures récentes (montants, dates, statut de paiement). LECTURE. Utilise pour « quel est le solde / le montant dû », « factures impayées ». Fournis customer (id C-xxxx).", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx" } }, "required": ["customer"] } } },
{ "audience": "staff", "mode": "read", "title": "Abonnements client", "type": "function", "function": { "name": "customer_subscriptions", "description": "STAFF. Abonnements / services du client : forfaits, prix, fréquence de facturation, statut. LECTURE. Fournis customer (id C-xxxx).", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx" } }, "required": ["customer"] } } },
{ "audience": "staff", "mode": "read", "title": "Équipement client", "type": "function", "function": { "name": "customer_equipment", "description": "STAFF. Équipement installé (ONU / modem / routeur) : n° de série, MAC, statut. LECTURE. Fournis customer (id C-xxxx). Pour l'état LIVE (en ligne / signal), utilise plutôt check_service.", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx" } }, "required": ["customer"] } } },
{ "audience": "staff", "mode": "read", "title": "Historique / problèmes client", "type": "function", "function": { "name": "customer_history", "description": "STAFF. Historique des tickets du client (tous statuts, récents d'abord) → répond « un problème est-il DÉJÀ survenu chez ce client ? ». LECTURE. Fournis customer (id C-xxxx).", "parameters": { "type": "object", "properties": { "customer": { "type": "string", "description": "ID client C-xxxx" } }, "required": ["customer"] } } },
{ "audience": "staff", "mode": "write", "permission": "create_jobs", "title": "Créer un job", "type": "function", "function": { "name": "create_job", "description": "STAFF/dispatch. Crée un Dispatch Job (intervention). ÉCRITURE — proposée puis confirmée par l'utilisateur avant exécution. auto_assign=true assigne au meilleur tech disponible.", "parameters": { "type": "object", "properties": { "subject": { "type": "string", "description": "Description du travail" }, "customer_id": { "type": "string", "description": "ID client (optionnel)" }, "service_location": { "type": "string", "description": "Nom du lieu de service (optionnel)" }, "address": { "type": "string", "description": "Adresse civique de l'intervention (texte libre, ex. « 2338 rue Ste-Clotilde ») — si aucun lieu de service lié" }, "priority": { "type": "string", "enum": ["low", "medium", "high"], "description": "Priorité (défaut high pour urgence, medium sinon)" }, "job_type": { "type": "string", "enum": ["Installation", "Réparation", "Maintenance", "Retrait", "Dépannage", "Autre"], "description": "Type de travail (défaut Dépannage)" }, "notes": { "type": "string", "description": "Contexte additionnel" }, "auto_assign": { "type": "boolean", "description": "Assigner automatiquement au meilleur tech dispo (défaut true)" } }, "required": ["subject"] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Assigner un technicien", "type": "function", "function": { "name": "assign_tech", "description": "STAFF/dispatch. Assigne OU réassigne un Dispatch Job à un technicien (pose aussi l'heure au premier trou libre du quart). ÉCRITURE — confirmée avant exécution. Résous d'abord le tech via list_technicians pour obtenir tech_id.", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job" }, "tech_id": { "type": "string", "description": "id du technicien (TECH-xxxx), via list_technicians" }, "date": { "type": "string", "description": "Date AAAA-MM-JJ (optionnel)" }, "start": { "type": "string", "description": "Heure HH:MM (optionnel)" } }, "required": ["job", "tech_id"] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Ajouter un assistant", "type": "function", "function": { "name": "add_assistant", "description": "STAFF/dispatch. Ajoute un technicien en renfort (assistant) sur un job — le tech assigné (lead) reste inchangé. ÉCRITURE — confirmée avant exécution.", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job" }, "tech_id": { "type": "string", "description": "id du technicien assistant (TECH-xxxx)" }, "tech_name": { "type": "string", "description": "Nom du technicien (optionnel, pour l'affichage)" } }, "required": ["job", "tech_id"] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Changer le statut", "type": "function", "function": { "name": "set_job_status", "description": "STAFF/dispatch. Change le statut d'un Dispatch Job. ÉCRITURE — confirmée avant exécution. Cancelled = annuler l'intervention (conséquent).", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job" }, "status": { "type": "string", "enum": ["open", "On Hold", "Cancelled", "assigned"], "description": "Nouveau statut" } }, "required": ["job", "status"] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Reporter le rendez-vous", "type": "function", "function": { "name": "reschedule_job", "description": "STAFF/dispatch. Reporte un Dispatch Job à une nouvelle date (et heure). Conserve le technicien assigné si possible. ÉCRITURE — confirmée avant exécution.", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job" }, "date": { "type": "string", "description": "Nouvelle date AAAA-MM-JJ" }, "start": { "type": "string", "description": "Nouvelle heure HH:MM (optionnel)" } }, "required": ["job", "date"] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Proposer un RDV au client", "type": "function", "function": { "name": "proposer_rdv_client", "description": "STAFF/dispatch. Envoie au CLIENT un lien (par texto) pour qu'il choisisse LUI-MÊME son rendez-vous : soit il prend un créneau proposé (réservé 5 min), soit il propose ses 3 disponibilités. À utiliser après un diagnostic quand une intervention est requise mais qu'on laisse le client choisir l'heure, plutôt que d'assigner soi-même un technicien. ÉCRITURE — confirmée avant exécution. Requiert un Dispatch Job OUVERT : fournis job, ou ticket (Issue source), ou customer_id pour le retrouver.", "parameters": { "type": "object", "properties": { "job": { "type": "string", "description": "Identifiant du Dispatch Job (optionnel si ticket/customer_id fourni)" }, "ticket": { "type": "string", "description": "Ticket/Issue source (optionnel) — retrouve le job ouvert lié" }, "customer_id": { "type": "string", "description": "ID client (optionnel) — retrouve son dernier job ouvert" }, "message": { "type": "string", "description": "Message texto personnalisé (optionnel)" } }, "required": [] } } },
{ "audience": "staff", "mode": "write", "permission": "assign_jobs", "title": "Créer un horaire récurrent", "type": "function", "function": { "name": "create_recurring_shift", "description": "STAFF/planification. Définit le QUART RÉCURRENT (horaire hebdomadaire) d'un technicien — matérialisé automatiquement en assignations sur l'horizon. ÉCRITURE — confirmée avant exécution. days = jours travaillés parmi mon,tue,wed,thu,fri,sat,sun. « jours de semaine » = mon,tue,wed,thu,fri ; retire les exceptions demandées (ex. « sauf le vendredi » → mon,tue,wed,thu). « fin de semaine » = sat,sun. Convertis « 8-16h » en start 08:00 / end 16:00.", "parameters": { "type": "object", "properties": { "technicien_id": { "type": "string", "description": "id du technicien (TECH-xxxx), via list_technicians" }, "days": { "type": "array", "items": { "type": "string" }, "description": "Jours travaillés: mon,tue,wed,thu,fri,sat,sun" }, "start": { "type": "string", "description": "Heure de début HH:MM, ex. 08:00" }, "end": { "type": "string", "description": "Heure de fin HH:MM, ex. 16:00" } }, "required": ["technicien_id", "days", "start", "end"] } } },
{ "audience": "staff", "mode": "write", "title": "Suivre", "type": "function", "function": { "name": "follow_doc", "description": "STAFF. (Dé)suivre un job ou un ticket pour recevoir les notifications de mise à jour (l'utilisateur connecté devient abonné). ÉCRITURE légère — confirmée avant exécution.", "parameters": { "type": "object", "properties": { "doctype": { "type": "string", "enum": ["Dispatch Job", "Issue"], "description": "Type de document à suivre" }, "name": { "type": "string", "description": "Identifiant du job ou du ticket" }, "follow": { "type": "boolean", "description": "true = suivre (défaut), false = ne plus suivre" } }, "required": ["doctype", "name"] } } },
{ "audience": "staff", "mode": "write", "permission": "reboot_provision", "title": "Action équipement (OLT)", "type": "function", "function": { "name": "device_action", "description": "STAFF/réseau (Do Stuff). Opération à distance sur l'ONU/modem d'un client via l'OLT. ÉCRITURE RÉSEAU — proposée avec un APERÇU (effet, cible, avertissements) puis CONFIRMÉE avant exécution ; idempotente ; l'acteur est journalisé. À utiliser après check_service pour un CORRECTIF À DISTANCE avant d'envoyer un technicien (ex. redémarrer un modem en ligne). Actions : reboot (redémarrer l'ONU) · speed (changer le forfait / profil de ligne, l'ONU redémarre) · suspend (couper l'internet, bascule VLAN) · unsuspend (rétablir l'internet) · activate (provisionner l'ONU) · replace (remplacer le n° de série) · remove (retirer / désactiver l'ONU). Fournis serial (n° de série ONU) OU customer_id (on résout l'ONU du client). profileid requis pour activate / speed ; new_sn requis pour replace.", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": ["reboot", "speed", "suspend", "unsuspend", "activate", "replace", "remove"], "description": "Opération à exécuter sur l'ONU" }, "serial": { "type": "string", "description": "Numéro de série de l'ONU (ex. TPLGxxxx, RCMGxxxx)" }, "customer_id": { "type": "string", "description": "ID client (C-xxxx) — si le serial est inconnu, on résout l'ONU du client" }, "profileid": { "type": "string", "description": "N° de profil de ligne (requis pour activate et speed)" }, "new_sn": { "type": "string", "description": "Nouveau numéro de série (requis pour replace)" } }, "required": ["action"] } } }
]