@omniyat/aimodule 1.0.4 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -297,4 +297,4 @@ async function(e,t,n){const o=new Ye;let i;i=n.data instanceof Blob?JSON.parse(a
297
297
  * @license
298
298
  * Copyright 2025 Google LLC
299
299
  * SPDX-License-Identifier: Apache-2.0
300
- */e.ApiError=pn,e.Batches=Gt,e.Caches=Yt,e.CancelTuningJobResponse=Ue,e.Chat=on,e.Chats=nn,e.ComputeTokensResponse=Pe,e.ContentReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTENT",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.ControlReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTROL",referenceImage:this.referenceImage,referenceId:this.referenceId,controlImageConfig:this.config}}},e.CountTokensResponse=Ne,e.CreateFileResponse=je,e.DeleteCachedContentResponse=xe,e.DeleteFileResponse=Ve,e.DeleteModelResponse=we,e.EditImageResponse=Ae,e.EmbedContentResponse=_e,e.Files=An,e.FunctionResponse=class{},e.FunctionResponseBlob=class{},e.FunctionResponseFileData=class{},e.FunctionResponsePart=class{},e.GenerateContentResponse=Ie,e.GenerateContentResponsePromptFeedback=class{},e.GenerateContentResponseUsageMetadata=class{},e.GenerateImagesResponse=Se,e.GenerateVideosOperation=Me,e.GenerateVideosResponse=class{},e.GoogleGenAI=class{get interactions(){var e;if(void 0!==this._interactions)return this._interactions;if(console.warn("GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions."),this.vertexai)throw new Error("This version of the GenAI SDK does not support Vertex AI API for interactions.");const t=this.httpOptions;(null==t?void 0:t.extraBody)&&console.warn("GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.");const n=new Fo({baseURL:this.apiClient.getBaseUrl(),apiKey:this.apiKey,apiVersion:this.apiClient.getApiVersion(),clientAdapter:this.apiClient,defaultHeaders:this.apiClient.getDefaultHeaders(),timeout:null==t?void 0:t.timeout,maxRetries:null===(e=null==t?void 0:t.retryOptions)||void 0===e?void 0:e.attempts});return this._interactions=n.interactions,this._interactions}constructor(e){var t;if(null==e.apiKey)throw new Error(`An API Key must be set when running in an unspecified environment.\n + ${gn().message}`);this.vertexai=null!==(t=e.vertexai)&&void 0!==t&&t,this.apiKey=e.apiKey,this.apiVersion=e.apiVersion,this.httpOptions=e.httpOptions;const n=new dr(this.apiKey);this.apiClient=new fn({auth:n,apiVersion:this.apiVersion,apiKey:this.apiKey,vertexai:this.vertexai,httpOptions:this.httpOptions,userAgentExtra:"gl-node/cross",uploader:new En,downloader:new yn}),this.models=new Xi(this.apiClient),this.live=new Bi(this.apiClient,n,new _n),this.chats=new nn(this.models,this.apiClient),this.batches=new Gt(this.apiClient),this.caches=new Yt(this.apiClient),this.files=new An(this.apiClient),this.operations=new Qi(this.apiClient),this.authTokens=new nr(this.apiClient),this.tunings=new cr(this.apiClient),this.fileSearchStores=new Rn(this.apiClient)}},e.HttpResponse=Te,e.ImportFileOperation=Fe,e.ImportFileResponse=class{},e.InlinedEmbedContentResponse=class{},e.InlinedResponse=class{},e.ListBatchJobsResponse=Je,e.ListCachedContentsResponse=Le,e.ListDocumentsResponse=ke,e.ListFileSearchStoresResponse=qe,e.ListFilesResponse=He,e.ListModelsResponse=Re,e.ListTuningJobsResponse=De,e.Live=Bi,e.LiveClientToolResponse=class{},e.LiveMusicServerMessage=Ye,e.LiveSendToolResponseParameters=class{constructor(){this.functionResponses=[]}},e.LiveServerMessage=$e,e.MaskReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_MASK",referenceImage:this.referenceImage,referenceId:this.referenceId,maskImageConfig:this.config}}},e.Models=Xi,e.Operations=Qi,e.Pager=qt,e.RawReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_RAW",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.RecontextImageResponse=Oe,e.RegisterFilesResponse=Be,e.ReplayResponse=class{},e.SegmentImageResponse=be,e.Session=$i,e.SingleEmbedContentResponse=class{},e.StyleReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_STYLE",referenceImage:this.referenceImage,referenceId:this.referenceId,styleImageConfig:this.config}}},e.SubjectReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_SUBJECT",referenceImage:this.referenceImage,referenceId:this.referenceId,subjectImageConfig:this.config}}},e.Tokens=nr,e.UploadToFileSearchStoreOperation=Ke,e.UploadToFileSearchStoreResponse=class{},e.UploadToFileSearchStoreResumableResponse=Ge,e.UpscaleImageResponse=Ce,e.createFunctionResponsePartFromBase64=function(e,t){return{inlineData:{data:e,mimeType:t}}},e.createFunctionResponsePartFromUri=function(e,t){return{fileData:{fileUri:e,mimeType:t}}},e.createModelContent=function(e){return{role:"model",parts:Ee(e)}},e.createPartFromBase64=function(e,t,n){return Object.assign({inlineData:{data:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createPartFromCodeExecutionResult=function(e,t){return{codeExecutionResult:{outcome:e,output:t}}},e.createPartFromExecutableCode=function(e,t){return{executableCode:{code:e,language:t}}},e.createPartFromFunctionCall=function(e,t){return{functionCall:{name:e,args:t}}},e.createPartFromFunctionResponse=function(e,t,n,o=[]){return{functionResponse:Object.assign({id:e,name:t,response:n},o.length>0&&{parts:o})}},e.createPartFromText=ye,e.createPartFromUri=function(e,t,n){return Object.assign({fileData:{fileUri:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createUserContent=function(e){return{role:"user",parts:Ee(e)}},e.mcpToTool=function(...e){if(Li=!0,0===e.length)throw new Error("No MCP clients provided");const t=e[e.length-1];return null!==(n=t)&&"object"==typeof n&&"listTools"in n&&"function"==typeof n.listTools?Hi.create(e,{}):Hi.create(e.slice(0,e.length-1),t);var n},e.setDefaultBaseUrls=function(e){e.geminiUrl,e.vertexUrl}}(y)),y}function A(){if(c)return u;return c=1,u={getExtractionPrompt:function(){return'\nTu es un moteur d\'extraction et de classification spécialisé dans les factures du secteur mécanique automobile.\n\nTa tâche est d’analyser le texte fourni.\n\nIMPORTANT :\n- Si le document n’est PAS clairement une facture, retourne STRICTEMENT : null\n- Sinon retourne UNIQUEMENT un JSON valide correspondant au schéma.\nLe JSON doit respecter STRICTEMENT cette structure :\n\n{\n "reference": string | null,\n "date": string | null,\n "supplier": string | null,\n "customer": string | null,\n "totalAmount": number | null,\n "currency": string | null,\n "address": string | null,\n "items": [\n {\n "description": string,\n "quantity": number | null,\n "unitPrice": number | null,\n "totalPrice": number | null,\n "category": string | null\n }\n ],\n "taxAmount": number | null,\n "language": string | null\n}\n\nCATEGORIES AUTORISÉES (liste fermée) :\n\n- carrosserie\n- depannage\n- entretien_preventif\n- reparation_curative\n- diagnostic_electronique\n- autre\n\nRÈGLES DE CLASSIFICATION :\n\nAnalyse la description de chaque article et classe-le dans UNE SEULE catégorie :\n\n- carrosserie → peinture, tôle, choc, pare-chocs, aile, redressage\n- depannage → remorquage, dépannage route, batterie à plat\n- entretien_preventif → vidange, filtres, révision, entretien périodique\n- reparation_curative → remplacement pièce, réparation moteur, frein, embrayage\n- diagnostic_electronique → valise, scanner OBD, diagnostic calculateur\n\nSi aucune catégorie ne correspond clairement → "autre".\n\nRÈGLES GÉNÉRALES :\n\n1. Retourne UNIQUEMENT :\n - soit null\n - soit un JSON valide.\n2. Aucun texte explicatif.\n3. Aucun markdown.\n4. Si une donnée est absente → null.\n5. Les montants doivent être des NOMBRES.\n6. Utilise "." comme séparateur décimal.\n7. Date format YYYY-MM-DD ou null.\n8. Devise normalisée (EUR, USD, MAD...).\n9. Ne déduis aucune information absente explicitement.\n10. Une seule catégorie par item.\n\nAnalyse maintenant le texte suivant :\n'},getTasksCreationPrompt:function(e,t){return`\n CONTEXTE: Creation de tâches dans une solution de fleet management system.\n Tu es le responsable de park en maintenance de flottes(automobiles, camions, vehicules). \n Les taches sont le moyen de communiquer entre les personnes impliquées dans la gestion de resolution de l'intervention.\n Tu reçois les signalement des chauffeurs sur l'état de leurs véhicules. \n\n À partir de l'intervention, génère un tableau JSON de tâches détaillées et structurées.\n Tu pourrais recevoir un audio ou une photo descriptive de l'intervention ou de la panne.\n Il faudra les analyser pour en extraire des informations utiles à la création des tâches.\n Genere uniquement des taches principales relatives à la resolution de l'intervention.'\n \n **Titre :** ${e}\n **Description :** ${t}\n Réponds UNIQUEMENT avec un tableau JSON valide (sans markdown, sans explication), en suivant exactement ce format :\n [\n {\n "title": "Titre de la tâche",\n "description": "Description détaillée",\n "category": "catégorie de la tache(exemple: mécanique, electric, pneumatique,..)"\n }\n ]`},cleanJsonResponse:function(e){return e.replace(/```json/g,"").replace(/```/g,"").trim()},getMimeType:function(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp",mp3:"audio/mpeg",wav:"audio/wav"}[e.replace(".","").toLowerCase()]}}}var C=t(function(){if(g)return m;g=1;const{GoogleGenAI:t}=S(),{extractFromBase64:n}=function(){if(d)return p;d=1;const{fromBuffer:t}=e,{getExtractionPrompt:n}=A();return p={extractFromBase64:async function(e,o,i){if(!i)return null;if(!e)throw new Error("InvoiceExtractor not initialized. Call init() first.");let r,s=i;const l=i.match(/^data:(.*);base64,(.*)$/);if(l)r=l[1],s=l[2];else{const e=Buffer.from(i,"base64"),n=await t(e);if(!n)throw new Error("Unable to detect file type");r=n.mime}const a=await e.models.generateContent({model:o,contents:[{role:"user",parts:[{inlineData:{mimeType:r,data:s}},{text:n()}]}]});if(!a?.text)return null;const u=a.text.replace(/```json|```/g,"").trim();return JSON.parse(u)}}}(),{generateTasks:o}=function(){if(f)return h;f=1;const{cleanJsonResponse:e,getMimeType:t,getTasksCreationPrompt:n}=A();return h={generateTasks:async function(o,i,r,s,l,a){if(!r||!s)throw new Error("Le titre et la description sont obligatoires.");if(!o)throw new Error("TasksGenerator not initialized. Call init() first.");const u=[];l&&u.push({inlineData:{mimeType:t(l.extension),data:Buffer.from(l.buffer).toString("base64")}}),a&&u.push({inlineData:{mimeType:t(a.extension),data:Buffer.from(a.buffer).toString("base64")}}),u.push({text:n(r,s)});const c=await o.models.generateContent({model:i,contents:[{role:"user",parts:u}],generationConfig:{maxOutputTokens:2048,temperature:.2}}),p=c.candidates?.[0]?.content?.parts?.[0]?.text?.trim();if(!p)throw new Error("Réponse vide du modèle.");const d=JSON.parse(e(p));if(!Array.isArray(d))throw new Error("La réponse n'est pas un tableau JSON.");return d}}}();return m=new class{#e;#t;init({apiKey:e,model:n}={}){const o=e??process.env.AI_API_KEY,i=n??process.env.AI_MODEL??"gemini-2.5-flash";if(!o)throw new Error("API key is required. Provide it via init() or AI_API_KEY env variable.");return this.#e=new t({apiKey:o}),this.#t=i,this}extract(e){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return n(this.#e,this.#t,e)}generateTasks(e,t,n,i){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return o(this.#e,this.#t,e,t,n,i)}}}());module.exports=C;
300
+ */e.ApiError=pn,e.Batches=Gt,e.Caches=Yt,e.CancelTuningJobResponse=Ue,e.Chat=on,e.Chats=nn,e.ComputeTokensResponse=Pe,e.ContentReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTENT",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.ControlReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTROL",referenceImage:this.referenceImage,referenceId:this.referenceId,controlImageConfig:this.config}}},e.CountTokensResponse=Ne,e.CreateFileResponse=je,e.DeleteCachedContentResponse=xe,e.DeleteFileResponse=Ve,e.DeleteModelResponse=we,e.EditImageResponse=Ae,e.EmbedContentResponse=_e,e.Files=An,e.FunctionResponse=class{},e.FunctionResponseBlob=class{},e.FunctionResponseFileData=class{},e.FunctionResponsePart=class{},e.GenerateContentResponse=Ie,e.GenerateContentResponsePromptFeedback=class{},e.GenerateContentResponseUsageMetadata=class{},e.GenerateImagesResponse=Se,e.GenerateVideosOperation=Me,e.GenerateVideosResponse=class{},e.GoogleGenAI=class{get interactions(){var e;if(void 0!==this._interactions)return this._interactions;if(console.warn("GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions."),this.vertexai)throw new Error("This version of the GenAI SDK does not support Vertex AI API for interactions.");const t=this.httpOptions;(null==t?void 0:t.extraBody)&&console.warn("GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.");const n=new Fo({baseURL:this.apiClient.getBaseUrl(),apiKey:this.apiKey,apiVersion:this.apiClient.getApiVersion(),clientAdapter:this.apiClient,defaultHeaders:this.apiClient.getDefaultHeaders(),timeout:null==t?void 0:t.timeout,maxRetries:null===(e=null==t?void 0:t.retryOptions)||void 0===e?void 0:e.attempts});return this._interactions=n.interactions,this._interactions}constructor(e){var t;if(null==e.apiKey)throw new Error(`An API Key must be set when running in an unspecified environment.\n + ${gn().message}`);this.vertexai=null!==(t=e.vertexai)&&void 0!==t&&t,this.apiKey=e.apiKey,this.apiVersion=e.apiVersion,this.httpOptions=e.httpOptions;const n=new dr(this.apiKey);this.apiClient=new fn({auth:n,apiVersion:this.apiVersion,apiKey:this.apiKey,vertexai:this.vertexai,httpOptions:this.httpOptions,userAgentExtra:"gl-node/cross",uploader:new En,downloader:new yn}),this.models=new Xi(this.apiClient),this.live=new Bi(this.apiClient,n,new _n),this.chats=new nn(this.models,this.apiClient),this.batches=new Gt(this.apiClient),this.caches=new Yt(this.apiClient),this.files=new An(this.apiClient),this.operations=new Qi(this.apiClient),this.authTokens=new nr(this.apiClient),this.tunings=new cr(this.apiClient),this.fileSearchStores=new Rn(this.apiClient)}},e.HttpResponse=Te,e.ImportFileOperation=Fe,e.ImportFileResponse=class{},e.InlinedEmbedContentResponse=class{},e.InlinedResponse=class{},e.ListBatchJobsResponse=Je,e.ListCachedContentsResponse=Le,e.ListDocumentsResponse=ke,e.ListFileSearchStoresResponse=qe,e.ListFilesResponse=He,e.ListModelsResponse=Re,e.ListTuningJobsResponse=De,e.Live=Bi,e.LiveClientToolResponse=class{},e.LiveMusicServerMessage=Ye,e.LiveSendToolResponseParameters=class{constructor(){this.functionResponses=[]}},e.LiveServerMessage=$e,e.MaskReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_MASK",referenceImage:this.referenceImage,referenceId:this.referenceId,maskImageConfig:this.config}}},e.Models=Xi,e.Operations=Qi,e.Pager=qt,e.RawReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_RAW",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.RecontextImageResponse=Oe,e.RegisterFilesResponse=Be,e.ReplayResponse=class{},e.SegmentImageResponse=be,e.Session=$i,e.SingleEmbedContentResponse=class{},e.StyleReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_STYLE",referenceImage:this.referenceImage,referenceId:this.referenceId,styleImageConfig:this.config}}},e.SubjectReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_SUBJECT",referenceImage:this.referenceImage,referenceId:this.referenceId,subjectImageConfig:this.config}}},e.Tokens=nr,e.UploadToFileSearchStoreOperation=Ke,e.UploadToFileSearchStoreResponse=class{},e.UploadToFileSearchStoreResumableResponse=Ge,e.UpscaleImageResponse=Ce,e.createFunctionResponsePartFromBase64=function(e,t){return{inlineData:{data:e,mimeType:t}}},e.createFunctionResponsePartFromUri=function(e,t){return{fileData:{fileUri:e,mimeType:t}}},e.createModelContent=function(e){return{role:"model",parts:Ee(e)}},e.createPartFromBase64=function(e,t,n){return Object.assign({inlineData:{data:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createPartFromCodeExecutionResult=function(e,t){return{codeExecutionResult:{outcome:e,output:t}}},e.createPartFromExecutableCode=function(e,t){return{executableCode:{code:e,language:t}}},e.createPartFromFunctionCall=function(e,t){return{functionCall:{name:e,args:t}}},e.createPartFromFunctionResponse=function(e,t,n,o=[]){return{functionResponse:Object.assign({id:e,name:t,response:n},o.length>0&&{parts:o})}},e.createPartFromText=ye,e.createPartFromUri=function(e,t,n){return Object.assign({fileData:{fileUri:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createUserContent=function(e){return{role:"user",parts:Ee(e)}},e.mcpToTool=function(...e){if(Li=!0,0===e.length)throw new Error("No MCP clients provided");const t=e[e.length-1];return null!==(n=t)&&"object"==typeof n&&"listTools"in n&&"function"==typeof n.listTools?Hi.create(e,{}):Hi.create(e.slice(0,e.length-1),t);var n},e.setDefaultBaseUrls=function(e){e.geminiUrl,e.vertexUrl}}(y)),y}function A(){if(c)return u;return c=1,u={getExtractionPrompt:function(){return'\nRôle :\nTu es un agent d\'extraction de données OCR haute précision, spécialisé exclusivement dans les factures du secteur automobile (garages, concessions, centres de réparation).\nDirectives de sortie strictes :\nTon analyse doit être binaire : soit un objet JSON, soit le mot null.\nNe produis AUCUN texte avant ou après le JSON (pas de "Voici le résultat", pas de blocs de code Markdown ```json).\nSi le texte fourni n\'est pas une facture automobile identifiable, réponds uniquement : null.\nSchéma JSON cible :\n{\n "reference": string | null,\n "date": "YYYY-MM-DD" | null,\n "supplier": string | null,\n "customer": string | null,\n "totalAmount": number | null,\n "currency": "ISO_CODE" | null,\n "address": string | null,\n "items": [\n {\n "description": string,\n "quantity": number | null,\n "unitPrice": number | null,\n "totalPrice": number | null,\n "category": "carrosserie" | "depannage" | "entretien_preventif" | "reparation_curative" | "diagnostic_electronique" | "autre"\n }\n ],\n "taxAmount": number | null,\n "language": "ISO_639-1" | null\n}\nLogique de classification des items (Priorité absolue) :\nClasse chaque ligne de service/pièce selon ces mots-clés :\ncarrosserie : peinture, tôle, choc, débosselage, redressage, aile, pare-chocs.\ndepannage : remorquage, assistance, transport véhicule, batterie (si dépannage sur place).\nentretien_preventif : vidange, révision, remplacement filtres (air/huile/habitacle), niveaux, bougies.\nreparation_curative : freinage (plaquettes/disques), embrayage, distribution, cardan, amortisseurs, moteur, boîte de vitesse.\ndiagnostic_electronique : passage valise, lecture codes défaut, programmation, reset voyant.\nautre : frais de dossier, recyclage déchets, main d\'œuvre non spécifiée.\nRègles de formatage des données :\nNombres : Utilise exclusivement le point . comme séparateur décimal. Pas de séparateur de milliers.\nDates : Normalise impérativement au format YYYY-MM-DD.\nDevise : Utilise le code ISO 4217 (ex: EUR, MAD, USD).\nIntégrité : Si une valeur est incertaine ou absente, utilise null. Ne devine jamais une information.\n'},getTasksCreationPrompt:function({driverName:e,brand:t,model:n,firstCirculationDate:o,licensePlate:i,mileage:r,lastInterventionDate:s=null,interventionType:l,interventionDescription:a,attachments:u=[]}){return`\nCONTEXTE:\nTu es un expert en maintenance de flottes automobiles.\nTu génères des tâches opérationnelles TECHNIQUES et PRÉCISES pour résoudre une intervention sur un véhicule.\n\nACTEURS DISPONIBLES:\n- Chauffeur : conduit et remet le véhicule\n- Responsable de parc : supervise et valide les interventions\n- Mécanicien : réalise les interventions techniques\n- Garage : structure physique de réparation\n- Admin : gestion documentaire et système\n\nRÈGLES STRICTES:\n1. Génère UNIQUEMENT les tâches techniques directement liées aux problèmes décrits.\n2. Chaque tâche doit être SPÉCIFIQUE à la panne/intervention décrite, pas générique.\n3. Les tâches administratives (devis, approbation) ne sont à inclure QUE si l'intervention est complexe ou coûteuse.\n4. Évite les doublons : une tâche "diagnostic" ne doit pas être répétée dans "réparation".\n5. Maximum 5 à 6 tâches. Priorise les actions techniques concrètes.\n6. Le champ "description" doit mentionner les éléments techniques précis issus de la description de l'intervention (ex: type de panne, organe concerné).\n7. Ne jamais inventer ou extrapoler des données non fournies (ex: kilométrage de révision).\n\n---\n\nDEMANDE D'INTERVENTION:\n\nConducteur / Demandeur : ${e}\n\nVéhicule\n - Marque : ${t}\n - Modèle : ${n}\n - 1ère mise en circulation : ${o}\n - Immatriculation : ${i}\n - Kilométrage actuel : ${r} km\n ${s?`- Dernière intervention : ${s}`:""}\n\nIntervention\n - Type : ${l}\n - Description précise : ${a}\n ${u.length>0?`- Pièces jointes : ${u.join(", ")} — analyser pour extraire des informations techniques complémentaires`:""}\n\n---\n\nFORMAT DE RÉPONSE:\nRéponds UNIQUEMENT avec un tableau JSON valide.\nSans markdown, sans explication, sans texte avant ou après.\n\n[\n {\n "title": "Titre court, technique et spécifique à la panne",\n "description": "Action concrète que l'acteur doit réaliser, avec les éléments techniques précis de la panne (organe, symptôme, opération attendue)",\n "category": "Catégorie technique précise (ex: Freinage, Moteur, Entretien périodique, Électronique...)",\n "acteur": "Acteur exact parmi la liste",\n "order": 1\n }\n]\n`},cleanJsonResponse:function(e){return e.replace(/```json/g,"").replace(/```/g,"").trim()},getMimeType:function(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp",mp3:"audio/mpeg",wav:"audio/wav"}[e.replace(".","").toLowerCase()]},safeParseJSON:function(e){if(!e)return null;let t=e.replace(/```json/gi,"").replace(/```/g,"").trim();if("null"===t)return null;const n=t.match(/\{[\s\S]*\}/);return n?(t=n[0],t=t.replace(/,\s*([\]}])/g,"$1"),t=t.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),JSON.parse(t)):null}}}var C=t(function(){if(g)return m;g=1;const{GoogleGenAI:t}=S(),{extractFromBase64:n}=function(){if(d)return p;d=1;const{fromBuffer:t}=e,{getExtractionPrompt:n}=A(),{safeParseJSON:o}=A(),{Type:i}=S();return p={extractFromBase64:async function(e,r,s){if(!s)return null;if(!e)throw new Error("InvoiceExtractor not initialized. Call init() first.");let l,a=s;const u=s.match(/^data:(.*);base64,(.*)$/);if(u)l=u[1],a=u[2];else{const e=Buffer.from(s,"base64"),n=await t(e);if(!n)throw new Error("Unable to detect file type");l=n.mime}const c=await e.models.generateContent({model:r,contents:[{role:"user",parts:[{inlineData:{mimeType:l,data:a}},{text:n()}]}],config:{responseMimeType:"application/json",responseSchema:{type:i.OBJECT,properties:{reference:{type:i.STRING,nullable:!0},date:{type:i.STRING,nullable:!0},supplier:{type:i.STRING,nullable:!0},customer:{type:i.STRING,nullable:!0},totalAmount:{type:i.NUMBER,nullable:!0},currency:{type:i.STRING,nullable:!0},address:{type:i.STRING,nullable:!0},taxAmount:{type:i.NUMBER,nullable:!0},language:{type:i.STRING,nullable:!0},items:{type:i.ARRAY,items:{type:i.OBJECT,properties:{description:{type:i.STRING},quantity:{type:i.NUMBER,nullable:!0},unitPrice:{type:i.NUMBER,nullable:!0},totalPrice:{type:i.NUMBER,nullable:!0},category:{type:i.STRING,enum:["carrosserie","depannage","entretien_preventif","reparation_curative","diagnostic_electronique","autre"]}}}}}}}});return c?.text?o(c.text):null}}}(),{generateTasks:o}=function(){if(f)return h;f=1;const{cleanJsonResponse:e,getMimeType:t,getTasksCreationPrompt:n}=A();return h={generateTasks:async function(o,i,r,s,l){if(!r?.driverName||!r?.interventionDescription)throw new Error("Le nom du conducteur et la description de l'intervention sont obligatoires.");if(!o)throw new Error("TasksGenerator not initialized. Call init() first.");const a=[];s&&a.push({inlineData:{mimeType:t(s.extension),data:Buffer.from(s.buffer).toString("base64")}}),l&&a.push({inlineData:{mimeType:t(l.extension),data:Buffer.from(l.buffer).toString("base64")}}),a.push({text:n(r)});const u=await o.models.generateContent({model:i,contents:[{role:"user",parts:a}],generationConfig:{maxOutputTokens:2048,temperature:.2}}),c=u.candidates?.[0]?.content?.parts?.[0]?.text?.trim();if(!c)throw new Error("Réponse vide du modèle.");const p=JSON.parse(e(c));if(!Array.isArray(p))throw new Error("La réponse n'est pas un tableau JSON.");return p}}}();return m=new class{#e;#t;init({apiKey:e,model:n}={}){const o=e??process.env.AI_API_KEY,i=n??process.env.AI_MODEL??"gemini-2.5-flash";if(!o)throw new Error("API key is required. Provide it via init() or AI_API_KEY env variable.");return this.#e=new t({apiKey:o}),this.#t=i,this}extract(e){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return n(this.#e,this.#t,e)}generateTasks(e,t,n){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return o(this.#e,this.#t,e,t,n)}}}());module.exports=C;
package/dist/index.mjs CHANGED
@@ -297,4 +297,4 @@ async function(e,t,n){const o=new Ye;let i;i=n.data instanceof Blob?JSON.parse(a
297
297
  * @license
298
298
  * Copyright 2025 Google LLC
299
299
  * SPDX-License-Identifier: Apache-2.0
300
- */e.ApiError=pn,e.Batches=Gt,e.Caches=Yt,e.CancelTuningJobResponse=Ue,e.Chat=on,e.Chats=nn,e.ComputeTokensResponse=Pe,e.ContentReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTENT",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.ControlReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTROL",referenceImage:this.referenceImage,referenceId:this.referenceId,controlImageConfig:this.config}}},e.CountTokensResponse=Ne,e.CreateFileResponse=je,e.DeleteCachedContentResponse=xe,e.DeleteFileResponse=Ve,e.DeleteModelResponse=we,e.EditImageResponse=Ae,e.EmbedContentResponse=_e,e.Files=An,e.FunctionResponse=class{},e.FunctionResponseBlob=class{},e.FunctionResponseFileData=class{},e.FunctionResponsePart=class{},e.GenerateContentResponse=Ie,e.GenerateContentResponsePromptFeedback=class{},e.GenerateContentResponseUsageMetadata=class{},e.GenerateImagesResponse=Se,e.GenerateVideosOperation=Me,e.GenerateVideosResponse=class{},e.GoogleGenAI=class{get interactions(){var e;if(void 0!==this._interactions)return this._interactions;if(console.warn("GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions."),this.vertexai)throw new Error("This version of the GenAI SDK does not support Vertex AI API for interactions.");const t=this.httpOptions;(null==t?void 0:t.extraBody)&&console.warn("GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.");const n=new Fo({baseURL:this.apiClient.getBaseUrl(),apiKey:this.apiKey,apiVersion:this.apiClient.getApiVersion(),clientAdapter:this.apiClient,defaultHeaders:this.apiClient.getDefaultHeaders(),timeout:null==t?void 0:t.timeout,maxRetries:null===(e=null==t?void 0:t.retryOptions)||void 0===e?void 0:e.attempts});return this._interactions=n.interactions,this._interactions}constructor(e){var t;if(null==e.apiKey)throw new Error(`An API Key must be set when running in an unspecified environment.\n + ${gn().message}`);this.vertexai=null!==(t=e.vertexai)&&void 0!==t&&t,this.apiKey=e.apiKey,this.apiVersion=e.apiVersion,this.httpOptions=e.httpOptions;const n=new dr(this.apiKey);this.apiClient=new fn({auth:n,apiVersion:this.apiVersion,apiKey:this.apiKey,vertexai:this.vertexai,httpOptions:this.httpOptions,userAgentExtra:"gl-node/cross",uploader:new En,downloader:new yn}),this.models=new Xi(this.apiClient),this.live=new Bi(this.apiClient,n,new _n),this.chats=new nn(this.models,this.apiClient),this.batches=new Gt(this.apiClient),this.caches=new Yt(this.apiClient),this.files=new An(this.apiClient),this.operations=new Qi(this.apiClient),this.authTokens=new nr(this.apiClient),this.tunings=new cr(this.apiClient),this.fileSearchStores=new Rn(this.apiClient)}},e.HttpResponse=Te,e.ImportFileOperation=Fe,e.ImportFileResponse=class{},e.InlinedEmbedContentResponse=class{},e.InlinedResponse=class{},e.ListBatchJobsResponse=Je,e.ListCachedContentsResponse=Le,e.ListDocumentsResponse=ke,e.ListFileSearchStoresResponse=qe,e.ListFilesResponse=He,e.ListModelsResponse=Re,e.ListTuningJobsResponse=De,e.Live=Bi,e.LiveClientToolResponse=class{},e.LiveMusicServerMessage=Ye,e.LiveSendToolResponseParameters=class{constructor(){this.functionResponses=[]}},e.LiveServerMessage=$e,e.MaskReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_MASK",referenceImage:this.referenceImage,referenceId:this.referenceId,maskImageConfig:this.config}}},e.Models=Xi,e.Operations=Qi,e.Pager=qt,e.RawReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_RAW",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.RecontextImageResponse=Oe,e.RegisterFilesResponse=Be,e.ReplayResponse=class{},e.SegmentImageResponse=be,e.Session=$i,e.SingleEmbedContentResponse=class{},e.StyleReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_STYLE",referenceImage:this.referenceImage,referenceId:this.referenceId,styleImageConfig:this.config}}},e.SubjectReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_SUBJECT",referenceImage:this.referenceImage,referenceId:this.referenceId,subjectImageConfig:this.config}}},e.Tokens=nr,e.UploadToFileSearchStoreOperation=Ke,e.UploadToFileSearchStoreResponse=class{},e.UploadToFileSearchStoreResumableResponse=Ge,e.UpscaleImageResponse=Ce,e.createFunctionResponsePartFromBase64=function(e,t){return{inlineData:{data:e,mimeType:t}}},e.createFunctionResponsePartFromUri=function(e,t){return{fileData:{fileUri:e,mimeType:t}}},e.createModelContent=function(e){return{role:"model",parts:Ee(e)}},e.createPartFromBase64=function(e,t,n){return Object.assign({inlineData:{data:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createPartFromCodeExecutionResult=function(e,t){return{codeExecutionResult:{outcome:e,output:t}}},e.createPartFromExecutableCode=function(e,t){return{executableCode:{code:e,language:t}}},e.createPartFromFunctionCall=function(e,t){return{functionCall:{name:e,args:t}}},e.createPartFromFunctionResponse=function(e,t,n,o=[]){return{functionResponse:Object.assign({id:e,name:t,response:n},o.length>0&&{parts:o})}},e.createPartFromText=ye,e.createPartFromUri=function(e,t,n){return Object.assign({fileData:{fileUri:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createUserContent=function(e){return{role:"user",parts:Ee(e)}},e.mcpToTool=function(...e){if(Li=!0,0===e.length)throw new Error("No MCP clients provided");const t=e[e.length-1];return null!==(n=t)&&"object"==typeof n&&"listTools"in n&&"function"==typeof n.listTools?Hi.create(e,{}):Hi.create(e.slice(0,e.length-1),t);var n},e.setDefaultBaseUrls=function(e){e.geminiUrl,e.vertexUrl}}(y)),y}function A(){if(c)return u;return c=1,u={getExtractionPrompt:function(){return'\nTu es un moteur d\'extraction et de classification spécialisé dans les factures du secteur mécanique automobile.\n\nTa tâche est d’analyser le texte fourni.\n\nIMPORTANT :\n- Si le document n’est PAS clairement une facture, retourne STRICTEMENT : null\n- Sinon retourne UNIQUEMENT un JSON valide correspondant au schéma.\nLe JSON doit respecter STRICTEMENT cette structure :\n\n{\n "reference": string | null,\n "date": string | null,\n "supplier": string | null,\n "customer": string | null,\n "totalAmount": number | null,\n "currency": string | null,\n "address": string | null,\n "items": [\n {\n "description": string,\n "quantity": number | null,\n "unitPrice": number | null,\n "totalPrice": number | null,\n "category": string | null\n }\n ],\n "taxAmount": number | null,\n "language": string | null\n}\n\nCATEGORIES AUTORISÉES (liste fermée) :\n\n- carrosserie\n- depannage\n- entretien_preventif\n- reparation_curative\n- diagnostic_electronique\n- autre\n\nRÈGLES DE CLASSIFICATION :\n\nAnalyse la description de chaque article et classe-le dans UNE SEULE catégorie :\n\n- carrosserie → peinture, tôle, choc, pare-chocs, aile, redressage\n- depannage → remorquage, dépannage route, batterie à plat\n- entretien_preventif → vidange, filtres, révision, entretien périodique\n- reparation_curative → remplacement pièce, réparation moteur, frein, embrayage\n- diagnostic_electronique → valise, scanner OBD, diagnostic calculateur\n\nSi aucune catégorie ne correspond clairement → "autre".\n\nRÈGLES GÉNÉRALES :\n\n1. Retourne UNIQUEMENT :\n - soit null\n - soit un JSON valide.\n2. Aucun texte explicatif.\n3. Aucun markdown.\n4. Si une donnée est absente → null.\n5. Les montants doivent être des NOMBRES.\n6. Utilise "." comme séparateur décimal.\n7. Date format YYYY-MM-DD ou null.\n8. Devise normalisée (EUR, USD, MAD...).\n9. Ne déduis aucune information absente explicitement.\n10. Une seule catégorie par item.\n\nAnalyse maintenant le texte suivant :\n'},getTasksCreationPrompt:function(e,t){return`\n CONTEXTE: Creation de tâches dans une solution de fleet management system.\n Tu es le responsable de park en maintenance de flottes(automobiles, camions, vehicules). \n Les taches sont le moyen de communiquer entre les personnes impliquées dans la gestion de resolution de l'intervention.\n Tu reçois les signalement des chauffeurs sur l'état de leurs véhicules. \n\n À partir de l'intervention, génère un tableau JSON de tâches détaillées et structurées.\n Tu pourrais recevoir un audio ou une photo descriptive de l'intervention ou de la panne.\n Il faudra les analyser pour en extraire des informations utiles à la création des tâches.\n Genere uniquement des taches principales relatives à la resolution de l'intervention.'\n \n **Titre :** ${e}\n **Description :** ${t}\n Réponds UNIQUEMENT avec un tableau JSON valide (sans markdown, sans explication), en suivant exactement ce format :\n [\n {\n "title": "Titre de la tâche",\n "description": "Description détaillée",\n "category": "catégorie de la tache(exemple: mécanique, electric, pneumatique,..)"\n }\n ]`},cleanJsonResponse:function(e){return e.replace(/```json/g,"").replace(/```/g,"").trim()},getMimeType:function(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp",mp3:"audio/mpeg",wav:"audio/wav"}[e.replace(".","").toLowerCase()]}}}var C=t(function(){if(g)return m;g=1;const{GoogleGenAI:t}=S(),{extractFromBase64:n}=function(){if(d)return p;d=1;const{fromBuffer:t}=e,{getExtractionPrompt:n}=A();return p={extractFromBase64:async function(e,o,i){if(!i)return null;if(!e)throw new Error("InvoiceExtractor not initialized. Call init() first.");let r,s=i;const l=i.match(/^data:(.*);base64,(.*)$/);if(l)r=l[1],s=l[2];else{const e=Buffer.from(i,"base64"),n=await t(e);if(!n)throw new Error("Unable to detect file type");r=n.mime}const a=await e.models.generateContent({model:o,contents:[{role:"user",parts:[{inlineData:{mimeType:r,data:s}},{text:n()}]}]});if(!a?.text)return null;const u=a.text.replace(/```json|```/g,"").trim();return JSON.parse(u)}}}(),{generateTasks:o}=function(){if(f)return h;f=1;const{cleanJsonResponse:e,getMimeType:t,getTasksCreationPrompt:n}=A();return h={generateTasks:async function(o,i,r,s,l,a){if(!r||!s)throw new Error("Le titre et la description sont obligatoires.");if(!o)throw new Error("TasksGenerator not initialized. Call init() first.");const u=[];l&&u.push({inlineData:{mimeType:t(l.extension),data:Buffer.from(l.buffer).toString("base64")}}),a&&u.push({inlineData:{mimeType:t(a.extension),data:Buffer.from(a.buffer).toString("base64")}}),u.push({text:n(r,s)});const c=await o.models.generateContent({model:i,contents:[{role:"user",parts:u}],generationConfig:{maxOutputTokens:2048,temperature:.2}}),p=c.candidates?.[0]?.content?.parts?.[0]?.text?.trim();if(!p)throw new Error("Réponse vide du modèle.");const d=JSON.parse(e(p));if(!Array.isArray(d))throw new Error("La réponse n'est pas un tableau JSON.");return d}}}();return m=new class{#e;#t;init({apiKey:e,model:n}={}){const o=e??process.env.AI_API_KEY,i=n??process.env.AI_MODEL??"gemini-2.5-flash";if(!o)throw new Error("API key is required. Provide it via init() or AI_API_KEY env variable.");return this.#e=new t({apiKey:o}),this.#t=i,this}extract(e){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return n(this.#e,this.#t,e)}generateTasks(e,t,n,i){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return o(this.#e,this.#t,e,t,n,i)}}}());export{C as default};
300
+ */e.ApiError=pn,e.Batches=Gt,e.Caches=Yt,e.CancelTuningJobResponse=Ue,e.Chat=on,e.Chats=nn,e.ComputeTokensResponse=Pe,e.ContentReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTENT",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.ControlReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_CONTROL",referenceImage:this.referenceImage,referenceId:this.referenceId,controlImageConfig:this.config}}},e.CountTokensResponse=Ne,e.CreateFileResponse=je,e.DeleteCachedContentResponse=xe,e.DeleteFileResponse=Ve,e.DeleteModelResponse=we,e.EditImageResponse=Ae,e.EmbedContentResponse=_e,e.Files=An,e.FunctionResponse=class{},e.FunctionResponseBlob=class{},e.FunctionResponseFileData=class{},e.FunctionResponsePart=class{},e.GenerateContentResponse=Ie,e.GenerateContentResponsePromptFeedback=class{},e.GenerateContentResponseUsageMetadata=class{},e.GenerateImagesResponse=Se,e.GenerateVideosOperation=Me,e.GenerateVideosResponse=class{},e.GoogleGenAI=class{get interactions(){var e;if(void 0!==this._interactions)return this._interactions;if(console.warn("GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions."),this.vertexai)throw new Error("This version of the GenAI SDK does not support Vertex AI API for interactions.");const t=this.httpOptions;(null==t?void 0:t.extraBody)&&console.warn("GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.");const n=new Fo({baseURL:this.apiClient.getBaseUrl(),apiKey:this.apiKey,apiVersion:this.apiClient.getApiVersion(),clientAdapter:this.apiClient,defaultHeaders:this.apiClient.getDefaultHeaders(),timeout:null==t?void 0:t.timeout,maxRetries:null===(e=null==t?void 0:t.retryOptions)||void 0===e?void 0:e.attempts});return this._interactions=n.interactions,this._interactions}constructor(e){var t;if(null==e.apiKey)throw new Error(`An API Key must be set when running in an unspecified environment.\n + ${gn().message}`);this.vertexai=null!==(t=e.vertexai)&&void 0!==t&&t,this.apiKey=e.apiKey,this.apiVersion=e.apiVersion,this.httpOptions=e.httpOptions;const n=new dr(this.apiKey);this.apiClient=new fn({auth:n,apiVersion:this.apiVersion,apiKey:this.apiKey,vertexai:this.vertexai,httpOptions:this.httpOptions,userAgentExtra:"gl-node/cross",uploader:new En,downloader:new yn}),this.models=new Xi(this.apiClient),this.live=new Bi(this.apiClient,n,new _n),this.chats=new nn(this.models,this.apiClient),this.batches=new Gt(this.apiClient),this.caches=new Yt(this.apiClient),this.files=new An(this.apiClient),this.operations=new Qi(this.apiClient),this.authTokens=new nr(this.apiClient),this.tunings=new cr(this.apiClient),this.fileSearchStores=new Rn(this.apiClient)}},e.HttpResponse=Te,e.ImportFileOperation=Fe,e.ImportFileResponse=class{},e.InlinedEmbedContentResponse=class{},e.InlinedResponse=class{},e.ListBatchJobsResponse=Je,e.ListCachedContentsResponse=Le,e.ListDocumentsResponse=ke,e.ListFileSearchStoresResponse=qe,e.ListFilesResponse=He,e.ListModelsResponse=Re,e.ListTuningJobsResponse=De,e.Live=Bi,e.LiveClientToolResponse=class{},e.LiveMusicServerMessage=Ye,e.LiveSendToolResponseParameters=class{constructor(){this.functionResponses=[]}},e.LiveServerMessage=$e,e.MaskReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_MASK",referenceImage:this.referenceImage,referenceId:this.referenceId,maskImageConfig:this.config}}},e.Models=Xi,e.Operations=Qi,e.Pager=qt,e.RawReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_RAW",referenceImage:this.referenceImage,referenceId:this.referenceId}}},e.RecontextImageResponse=Oe,e.RegisterFilesResponse=Be,e.ReplayResponse=class{},e.SegmentImageResponse=be,e.Session=$i,e.SingleEmbedContentResponse=class{},e.StyleReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_STYLE",referenceImage:this.referenceImage,referenceId:this.referenceId,styleImageConfig:this.config}}},e.SubjectReferenceImage=class{toReferenceImageAPI(){return{referenceType:"REFERENCE_TYPE_SUBJECT",referenceImage:this.referenceImage,referenceId:this.referenceId,subjectImageConfig:this.config}}},e.Tokens=nr,e.UploadToFileSearchStoreOperation=Ke,e.UploadToFileSearchStoreResponse=class{},e.UploadToFileSearchStoreResumableResponse=Ge,e.UpscaleImageResponse=Ce,e.createFunctionResponsePartFromBase64=function(e,t){return{inlineData:{data:e,mimeType:t}}},e.createFunctionResponsePartFromUri=function(e,t){return{fileData:{fileUri:e,mimeType:t}}},e.createModelContent=function(e){return{role:"model",parts:Ee(e)}},e.createPartFromBase64=function(e,t,n){return Object.assign({inlineData:{data:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createPartFromCodeExecutionResult=function(e,t){return{codeExecutionResult:{outcome:e,output:t}}},e.createPartFromExecutableCode=function(e,t){return{executableCode:{code:e,language:t}}},e.createPartFromFunctionCall=function(e,t){return{functionCall:{name:e,args:t}}},e.createPartFromFunctionResponse=function(e,t,n,o=[]){return{functionResponse:Object.assign({id:e,name:t,response:n},o.length>0&&{parts:o})}},e.createPartFromText=ye,e.createPartFromUri=function(e,t,n){return Object.assign({fileData:{fileUri:e,mimeType:t}},n&&{mediaResolution:{level:n}})},e.createUserContent=function(e){return{role:"user",parts:Ee(e)}},e.mcpToTool=function(...e){if(Li=!0,0===e.length)throw new Error("No MCP clients provided");const t=e[e.length-1];return null!==(n=t)&&"object"==typeof n&&"listTools"in n&&"function"==typeof n.listTools?Hi.create(e,{}):Hi.create(e.slice(0,e.length-1),t);var n},e.setDefaultBaseUrls=function(e){e.geminiUrl,e.vertexUrl}}(y)),y}function A(){if(c)return u;return c=1,u={getExtractionPrompt:function(){return'\nRôle :\nTu es un agent d\'extraction de données OCR haute précision, spécialisé exclusivement dans les factures du secteur automobile (garages, concessions, centres de réparation).\nDirectives de sortie strictes :\nTon analyse doit être binaire : soit un objet JSON, soit le mot null.\nNe produis AUCUN texte avant ou après le JSON (pas de "Voici le résultat", pas de blocs de code Markdown ```json).\nSi le texte fourni n\'est pas une facture automobile identifiable, réponds uniquement : null.\nSchéma JSON cible :\n{\n "reference": string | null,\n "date": "YYYY-MM-DD" | null,\n "supplier": string | null,\n "customer": string | null,\n "totalAmount": number | null,\n "currency": "ISO_CODE" | null,\n "address": string | null,\n "items": [\n {\n "description": string,\n "quantity": number | null,\n "unitPrice": number | null,\n "totalPrice": number | null,\n "category": "carrosserie" | "depannage" | "entretien_preventif" | "reparation_curative" | "diagnostic_electronique" | "autre"\n }\n ],\n "taxAmount": number | null,\n "language": "ISO_639-1" | null\n}\nLogique de classification des items (Priorité absolue) :\nClasse chaque ligne de service/pièce selon ces mots-clés :\ncarrosserie : peinture, tôle, choc, débosselage, redressage, aile, pare-chocs.\ndepannage : remorquage, assistance, transport véhicule, batterie (si dépannage sur place).\nentretien_preventif : vidange, révision, remplacement filtres (air/huile/habitacle), niveaux, bougies.\nreparation_curative : freinage (plaquettes/disques), embrayage, distribution, cardan, amortisseurs, moteur, boîte de vitesse.\ndiagnostic_electronique : passage valise, lecture codes défaut, programmation, reset voyant.\nautre : frais de dossier, recyclage déchets, main d\'œuvre non spécifiée.\nRègles de formatage des données :\nNombres : Utilise exclusivement le point . comme séparateur décimal. Pas de séparateur de milliers.\nDates : Normalise impérativement au format YYYY-MM-DD.\nDevise : Utilise le code ISO 4217 (ex: EUR, MAD, USD).\nIntégrité : Si une valeur est incertaine ou absente, utilise null. Ne devine jamais une information.\n'},getTasksCreationPrompt:function({driverName:e,brand:t,model:n,firstCirculationDate:o,licensePlate:i,mileage:r,lastInterventionDate:s=null,interventionType:l,interventionDescription:a,attachments:u=[]}){return`\nCONTEXTE:\nTu es un expert en maintenance de flottes automobiles.\nTu génères des tâches opérationnelles TECHNIQUES et PRÉCISES pour résoudre une intervention sur un véhicule.\n\nACTEURS DISPONIBLES:\n- Chauffeur : conduit et remet le véhicule\n- Responsable de parc : supervise et valide les interventions\n- Mécanicien : réalise les interventions techniques\n- Garage : structure physique de réparation\n- Admin : gestion documentaire et système\n\nRÈGLES STRICTES:\n1. Génère UNIQUEMENT les tâches techniques directement liées aux problèmes décrits.\n2. Chaque tâche doit être SPÉCIFIQUE à la panne/intervention décrite, pas générique.\n3. Les tâches administratives (devis, approbation) ne sont à inclure QUE si l'intervention est complexe ou coûteuse.\n4. Évite les doublons : une tâche "diagnostic" ne doit pas être répétée dans "réparation".\n5. Maximum 5 à 6 tâches. Priorise les actions techniques concrètes.\n6. Le champ "description" doit mentionner les éléments techniques précis issus de la description de l'intervention (ex: type de panne, organe concerné).\n7. Ne jamais inventer ou extrapoler des données non fournies (ex: kilométrage de révision).\n\n---\n\nDEMANDE D'INTERVENTION:\n\nConducteur / Demandeur : ${e}\n\nVéhicule\n - Marque : ${t}\n - Modèle : ${n}\n - 1ère mise en circulation : ${o}\n - Immatriculation : ${i}\n - Kilométrage actuel : ${r} km\n ${s?`- Dernière intervention : ${s}`:""}\n\nIntervention\n - Type : ${l}\n - Description précise : ${a}\n ${u.length>0?`- Pièces jointes : ${u.join(", ")} — analyser pour extraire des informations techniques complémentaires`:""}\n\n---\n\nFORMAT DE RÉPONSE:\nRéponds UNIQUEMENT avec un tableau JSON valide.\nSans markdown, sans explication, sans texte avant ou après.\n\n[\n {\n "title": "Titre court, technique et spécifique à la panne",\n "description": "Action concrète que l'acteur doit réaliser, avec les éléments techniques précis de la panne (organe, symptôme, opération attendue)",\n "category": "Catégorie technique précise (ex: Freinage, Moteur, Entretien périodique, Électronique...)",\n "acteur": "Acteur exact parmi la liste",\n "order": 1\n }\n]\n`},cleanJsonResponse:function(e){return e.replace(/```json/g,"").replace(/```/g,"").trim()},getMimeType:function(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp",mp3:"audio/mpeg",wav:"audio/wav"}[e.replace(".","").toLowerCase()]},safeParseJSON:function(e){if(!e)return null;let t=e.replace(/```json/gi,"").replace(/```/g,"").trim();if("null"===t)return null;const n=t.match(/\{[\s\S]*\}/);return n?(t=n[0],t=t.replace(/,\s*([\]}])/g,"$1"),t=t.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),JSON.parse(t)):null}}}var C=t(function(){if(g)return m;g=1;const{GoogleGenAI:t}=S(),{extractFromBase64:n}=function(){if(d)return p;d=1;const{fromBuffer:t}=e,{getExtractionPrompt:n}=A(),{safeParseJSON:o}=A(),{Type:i}=S();return p={extractFromBase64:async function(e,r,s){if(!s)return null;if(!e)throw new Error("InvoiceExtractor not initialized. Call init() first.");let l,a=s;const u=s.match(/^data:(.*);base64,(.*)$/);if(u)l=u[1],a=u[2];else{const e=Buffer.from(s,"base64"),n=await t(e);if(!n)throw new Error("Unable to detect file type");l=n.mime}const c=await e.models.generateContent({model:r,contents:[{role:"user",parts:[{inlineData:{mimeType:l,data:a}},{text:n()}]}],config:{responseMimeType:"application/json",responseSchema:{type:i.OBJECT,properties:{reference:{type:i.STRING,nullable:!0},date:{type:i.STRING,nullable:!0},supplier:{type:i.STRING,nullable:!0},customer:{type:i.STRING,nullable:!0},totalAmount:{type:i.NUMBER,nullable:!0},currency:{type:i.STRING,nullable:!0},address:{type:i.STRING,nullable:!0},taxAmount:{type:i.NUMBER,nullable:!0},language:{type:i.STRING,nullable:!0},items:{type:i.ARRAY,items:{type:i.OBJECT,properties:{description:{type:i.STRING},quantity:{type:i.NUMBER,nullable:!0},unitPrice:{type:i.NUMBER,nullable:!0},totalPrice:{type:i.NUMBER,nullable:!0},category:{type:i.STRING,enum:["carrosserie","depannage","entretien_preventif","reparation_curative","diagnostic_electronique","autre"]}}}}}}}});return c?.text?o(c.text):null}}}(),{generateTasks:o}=function(){if(f)return h;f=1;const{cleanJsonResponse:e,getMimeType:t,getTasksCreationPrompt:n}=A();return h={generateTasks:async function(o,i,r,s,l){if(!r?.driverName||!r?.interventionDescription)throw new Error("Le nom du conducteur et la description de l'intervention sont obligatoires.");if(!o)throw new Error("TasksGenerator not initialized. Call init() first.");const a=[];s&&a.push({inlineData:{mimeType:t(s.extension),data:Buffer.from(s.buffer).toString("base64")}}),l&&a.push({inlineData:{mimeType:t(l.extension),data:Buffer.from(l.buffer).toString("base64")}}),a.push({text:n(r)});const u=await o.models.generateContent({model:i,contents:[{role:"user",parts:a}],generationConfig:{maxOutputTokens:2048,temperature:.2}}),c=u.candidates?.[0]?.content?.parts?.[0]?.text?.trim();if(!c)throw new Error("Réponse vide du modèle.");const p=JSON.parse(e(c));if(!Array.isArray(p))throw new Error("La réponse n'est pas un tableau JSON.");return p}}}();return m=new class{#e;#t;init({apiKey:e,model:n}={}){const o=e??process.env.AI_API_KEY,i=n??process.env.AI_MODEL??"gemini-2.5-flash";if(!o)throw new Error("API key is required. Provide it via init() or AI_API_KEY env variable.");return this.#e=new t({apiKey:o}),this.#t=i,this}extract(e){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return n(this.#e,this.#t,e)}generateTasks(e,t,n){if(!this.#e)throw new Error("AiModule not initialized. Call init() first.");return o(this.#e,this.#t,e,t,n)}}}());export{C as default};
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@omniyat/aimodule",
3
- "version": "1.0.4",
3
+ "version": "1.0.8",
4
4
  "description": "A Node.js package that extract invoice from file and generate tasksGoogle GenAI API.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.cjs",
7
7
  "scripts": {
8
8
  "build": "rollup -c rollup.config.cjs",
9
9
  "prepare": "npm run build",
10
- "publish": "npm publish --access=public",
10
+ "deploy": "npm run build && npm publish --access public",
11
11
  "lint": "eslint .",
12
12
  "test": "node --env-file=.env src/tests/index.js"
13
13
  },