Skip to content

MelisAIEngine ​

Il motore AI astratto — contratto del provider, runtime agente/scenario, archivio delle conversazioni, ponte MCP/tool e tutte le tabelle del database AI, oltre ai componenti React di chat condivisi che alimentano il back-office v6. Pacchetto melisplatform/melis-ai-engine.

Scopo ​

MelisAIEngine è la chiave di volta della suite MelisAI. Definisce il contratto astratto del provider (MelisAIEngineModelService) implementato da Claude e Gemini, esegue gli agenti attraverso flussi di lavoro a più passaggi (scenario), gestisce il ponte MCP/tool-calling e possiede tutte le tabelle del database melis_ai_*. Non dispone di alcun tool autonomo proprio — è il motore di chat invisibile del back-office. In v6 (React) fornisce inoltre il componente React condiviso AiChatContainer e il backend di chat /melis/react-api/ai-engine/* che il modulo MelisAI monta nei propri tool visibili.

Abilitazione ​

Aggiungi a config/melis.module.load.php:

php
return [
    'MelisAIEngine',
];

Dipendenze Composer richieste: melisplatform/melis-core e melisplatform/melis-document-upload. Per le chiamate reali ai modelli deve essere installato almeno un modulo provider (MelisAIEngineClaude o MelisAIEngineGemini); senza un provider attivo per l'azienda del modello, la chat segnala "The AI company module is not active."

Servizi principali ​

Alias del servizioRuolo
MelisAIEngineModelServiceContratto astratto del provider. Estendi questa classe per aggiungere un nuovo provider AI (§ Contratto del provider).
MelisAIEngineServiceRegistro/factory: getActiveInstance(), getActiveAgent(), getActiveModel(), getActiveModelClass() (selezione del provider), getActiveAITools(), saveDailyUsage().
MelisAIEngineAgentServiceRuntime dello scenario: runAgent($postValues, $files) percorre i passaggi dell'agente e pilota MelisAIEngineModelService::send().
MelisAIEngineMcpServicePonte MCP/tool-calling: gestione dei server, comunicazione JSON-RPC, circuit breaker, getAvailableTools(), isMcpTool(), invokeTool(), formatToolsForAI(), getToolSchema().
MelisAIEngineConversationStoreStato persistente delle conversazioni multi-turno in melis_ai_conversation_state: get(), has(), set(), delete(). Garbage collection automatico dopo 48 ore.
MelisAIEngineFunctionServiceImplementazioni dei tool integrati (non-MCP), ad es. get_table_structure, create_database_table.
MelisAIEngineFileServicePulizia per retention dei documenti caricati dall'AI: deleteAIDocUploads().
MelisAIEngineGeneralServiceBase con gestione degli eventi: sendEvent(), makeArrayFromParameters().

Contratto del provider ​

MelisAIEngineModelService (src/Service/MelisAIEngineModelService.php) è la classe astratta che ogni provider deve estendere. Costruttore: (ServiceManager $serviceManager, int $modelId, int $agentId).

Metodi astratti che un provider deve implementare:

php
abstract public function setClient();
abstract public function addToolsToPayload($payload);
abstract public function addContentToPayload($payload, $role, $prompt, $files=[], $content=[]);
abstract public function constructContent($role, $prompt, $files=[]);
abstract public function getMessageKey(): string;            // 'messages' (Claude) | 'contents' (Gemini)
abstract public function sendCustomAI(?array $payload = []): array;
abstract public function getAllowedMimetypes(): array;
abstract public function setPromptTokenCount($responseData);
abstract public function setResponseTokenCount($responseData);
abstract public function setTotalTokenCount($responseData);
abstract public function processFiles($filesArr): array;
abstract public function processContextFiles($filesArr): array;

Il ciclo di vita del metodo base send(array $contextArr): array è fisso: addToolsToPayload() → addContentToPayload() per ogni voce del contesto → sendCustomAI() → conteggio dei token → restituisce ['request','responseData','result','errors','needs_continuation','session_id','continuation_context','tool_results'].

Helper forniti dalla classe base: getModel(), getAgentFunctions(), getToolDeclarationByName(), getter dei token, uploadDocument(), extractTextFromDocx(), extractTextFromXlsx(), getMimeType().

Selezione del provider ​

MelisAIEngineService::getActiveModelClass($company, $modelId, $agentId) seleziona il provider in base al nome dell'azienda del modello:

php
if (strpos($company, 'Google') !== false) {
    // builds MelisAIEngineModelGeminiService — requires MelisAIEngineGemini module
} elseif (strpos($company, 'Anthropic') !== false) {
    // builds MelisAIEngineModelClaudeService — requires MelisAIEngineClaude module
}

Per aggiungere un nuovo provider (ad es. OpenAI): estendi MelisAIEngineModelService, implementa i metodi astratti, registralo come servizio e aggiungi qui un ramo basato sul nome dell'azienda. I provider Ollama e OCI seguono lo stesso contratto.

Sistema MCP / tool-calling ​

I tool sono dichiarati in due punti: config['plugins']['melisaiengine']['datas']['function_declarations'] (nome, descrizione, schema JSON, booleano mcp) e la tabella melis_ai_tools. Un agente sceglie di usare i tool tramite maa_agent_tools.

Al momento della chiamata: getAgentFunctions() restituisce le dichiarazioni consentite → addToolsToPayload() le inietta → in caso di chiamata a un tool il provider instrada tramite MelisAIEngineMcpService::isMcpTool($name): i tool MCP vanno a invokeTool() (JSON-RPC su stdio, protetto da circuit breaker); i tool integrati vanno a MelisAIEngineFunctionService. I risultati vengono reimmessi e la conversazione prosegue finché il modello non segnala il completamento o non si raggiunge un limite di sicurezza.

I server MCP sono configurati sotto config['mcp']['servers'][<name>] = {enabled, command, args, tools, timeout}; MelisAIEngineMcpService li avvia tramite proc_open e comunica in JSON-RPC 2.0 (tools/list, invocazione dei tool).

Tabelle del database ​

Tutte le tabelle melis_ai_* sono possedute da questo modulo (dbdeploy: true):

TabellaContenuto
melis_ai_modelsModelli dei provider (azienda, mam_generative_model, collegamento alla chiave API).
melis_ai_companiesAziende AI (Google, Anthropic…).
melis_ai_platform_keysChiavi API per piattaforma.
melis_ai_agentsAgenti (maa_name, collegamento al modello, JSON maa_agent_tools, interruttori dei file).
melis_ai_agents_toolsAssegnazione agente ↔ tool.
melis_ai_toolsCatalogo dei tool (mat_name, mat_desc, JSON mat_config).
melis_ai_instances / melis_ai_instance_transDistribuzioni denominate (istanze) e relative traduzioni.
melis_ai_scenario_steps / …_datas / …_datas_entryexitPassaggi dello scenario, i loro dati e i parametri di ingresso/uscita.
melis_ai_return_typesDefinizioni dei tipi di ritorno dei passaggi.
melis_ai_filesFile allegati ai passaggi/contesto.
melis_ai_daily_usageConteggi di token e chiamate per modello/agente/istanza/giorno.
melis_ai_conversation_stateStato persistente delle conversazioni (macs_key, JSON, GC automatico).

Componenti React di chat ​

MelisAIEngine non ha alcun brick né una voce di menu /melis-react. Per il back-office React espone una libreria di componenti solo sorgente sotto ui-react/src/, importata dai consumatori tramite l'alias Vite @melis-ai-engine (mappato a melis-ai-engine/ui-react/src). Rende l'intera superficie di chat; l'LLM effettivo è sempre fornito da un modulo provider.

ExportRuolo
AiChatContainer (default)Componente orchestratore: esegue l'intero ciclo init → run → (continue×N) → validate, mantiene lo stato della chat, collega i sotto-componenti. È questo da montare.
ChatHistory, TypingIndicator, StepInterfaceElenco scorrevole dei messaggi (markdown tramite window.marked se presente), indicatore di elaborazione, schede di interfaccia per passaggio.
ChatFormBoxBarra di input inferiore: textarea, invia/valida, menu + → caricamento file (user_file_upload[]) o Media Library (userMediaFiles[], MoxieManager), overlay drag-drop.
ChatDebugPanel, DebugEntryVista di debug: payload della richiesta (→) e risposta grezza del modello (←) come blocchi JSON (solo quando debugMode).
MelisPlanPanel, extractMelisPlan, looksLikeMelisPlanRende un "Melis plan" strutturato proposto dall'AI (ad es. un elenco di campi di form) come tabella.
aiEngineInit/Run/Continue/Validate/RestartClient tipizzato per gli endpoint ai-engine (§ Backend di chat).
parseResultActionString, dispatchResultAction, dispatchToolResultsDispatcher di navigazione a ciclo chiuso JS_ACTION (§ Navigazione a ciclo chiuso).

Contratto di montaggio — AiChatContainerProps:

tsx
type AiChatContainerProps = {
  maiInstanceId: string                        // required — e.g. "agenttool" or "newscontentcreator|42"
  agentId?: number | null                      // override the instance's default agent
  extraEntryParams?: Record<string, unknown>   // → extra_entry_param[key] context
  entryParamForm?: Record<string, string>      // → entry_param_form[key]
  debugMode?: boolean
  exitParamArr?: ExitParamArr
  showCloseButton?: boolean
  needExitParam?: boolean
  showHideButton?: boolean
  showHeader?: boolean
  clearSession?: boolean                        // clear the server session on init (fresh conversation)
  autoRun?: boolean                             // start the agent immediately after init
  initialMessage?: string                       // first user_chat when autoRun
  onClose?: () => void
  onHide?: () => void
  className?: string
  style?: React.CSSProperties
}

Il container limita la continuazione a MAX_CONTINUATION_HOPS = 20. Per aggiungere una chat AI a un tool React, importa AiChatContainer e montalo con un maiInstanceId — non è necessario alcun lavoro sul backend, gli endpoint esistono già. I consumatori incrementano una key sull'elemento montato per forzare una nuova sessione lato server al rilancio.

Dove appare ​

Non vedi mai MelisAIEngine come voce di menu; la sua chat compare all'interno del modulo MelisAI, che monta l'identico AiChatContainer in tre punti (cambiano solo maiInstanceId / agentId):

  • AI Assistant — l'overlay dell'assistente fluttuante (chat generica in grado di agire sul back-office, avviata con autoRun).
  • Chat Dev Tool — uno spazio di prova per sviluppatori per avviare qualsiasi agente/istanza e dialogarci.
  • Scheda "Run" dell'agente — test di un agente dal tool degli agenti MelisAI (maiInstanceId="agenttool").

Backend di chat — gli endpoint ai-engine ​

Le rotte sono dichiarate in config/module.config.php (non un react-api.php), con alias del controller MelisAIEngine\Controller\React\MelisReactApiAiEngine → MelisReactApiAiEngineController. Ogni azione è protetta da denyUnlessAuthenticated() (401 senza un'identità MelisCore — nessun controllo di capacità per tool, trattandosi di un motore condiviso). Envelope di risposta uniforme: { success, data, error? }. Questi endpoint rispecchiano il legacy AIController (/melis/MelisAIEngine/AI/*) e chiamano lo stesso MelisAIEngineAgentService.

Metodo e URLFunzione clientScopo
GET /melis/react-api/ai-engine/initaiEngineInitValida istanza→agente→modello→provider; restituisce label, finalInstanceId, agentId, isFileUploadActivated, isMediaLibraryActivated, hasExitParameter (oppure errorType/errorMessage).
POST /melis/react-api/ai-engine/runaiEngineRunAvvia/fa avanzare un turno. JSON per il testo, multipart/form-data quando sono allegati file → runAgent().
POST /melis/react-api/ai-engine/continueaiEngineContinueRiprende un turno multi-hop (needs_continuation=true) → continueConversation(sessionId, continuationContext).
POST /melis/react-api/ai-engine/validateaiEngineValidateAccetta la risposta dell'AI, avanza al passaggio dei parametri di uscita, restituisce exitParams per la callback host → validateAnswer().
POST /melis/react-api/ai-engine/restartaiEngineRestartCancella la sessione, restituisce lo stesso finalInstanceId pronto al riutilizzo.

Il RunResult include chatHist, needs_continuation, session_id, continuation_context, payload/response (debug), exitParams, tool_results.

Turno di testo minimo:

ts
import { aiEngineInit, aiEngineRun } from '@melis-ai-engine'

const cfg = await aiEngineInit({ maiInstanceId: 'agenttool', clearSession: true })
if (cfg.errorType) throw new Error(cfg.errorMessage)   // instance/agent/model/companyModule/exitParam

const res = await aiEngineRun({
  agentId:    cfg.agentId,
  instanceId: cfg.finalInstanceId,
  userText:   'Create a news article about our new store',
})
// res.chatHist, res.needs_continuation, res.session_id, res.tool_results …

Il motore si limita a fare dispatch: nav-actions.ts estrae le stringhe di callback JS_ACTION::action::k=v&… dai tool_results di una risposta e chiama window.melisReactActionMap[action](args). La shell host (melis-core) registra quegli handler e possiede la navigazione React-Router e la percezione del DOM. Un handler può restituire un'osservazione Promise<string>, che dispatchToolResults attende e reimmette come continuationContext.clientObservation — fornendo il grounding per il turno successivo del modello. Ciò mantiene disaccoppiati i due bundle costruiti in modo indipendente: solo il contratto window li collega.

Esempio (view helper legacy) ​

Il classico helper con rendering lato server continua a funzionare per contesti non-React (.phtml):

php
// Render the chat box for a named instance
echo $this->AIChatViewHelper($maiInstanceId);

Registra un server MCP personalizzato e dichiara i suoi tool affinché un agente possa chiamarli:

php
// In a module's config — register the MCP server
'mcp' => [
    'servers' => [
        'my-mcp-server' => [
            'enabled' => true,
            'command' => 'node',
            'args'    => ['/path/to/server.js'],
            'tools'   => ['my_tool'],
            'timeout' => 30,
        ],
    ],
],
// Declare the tool with mcp: true
'plugins' => [
    'melisaiengine' => [
        'datas' => [
            'function_declarations' => [
                [
                    'name'        => 'my_tool',
                    'description' => 'Does something useful',
                    'mcp'         => true,
                    // JSON schema for parameters…
                ],
            ],
        ],
    ],
],

File principali ​

AmbitoPercorso
Contratto del provider (astratto)vendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineModelService.php
Registro + selezione del providervendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineService.php
Runtime agente/scenariovendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineAgentService.php
Ponte MCP/toolvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineMcpService.php
Archivio persistente delle conversazionivendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineConversationStore.php
Funzioni integratevendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineFunctionService.php
Controller di chat legacyvendor/melisplatform/melis-ai-engine/src/Controller/AIController.php
Backend di chat Reactvendor/melisplatform/melis-ai-engine/src/Controller/React/MelisReactApiAiEngineController.php
Libreria React di chat condivisavendor/melisplatform/melis-ai-engine/ui-react/src/ (AiChatContainer.tsx, api.ts, nav-actions.ts…)
Modelli delle tabelle del databasevendor/melisplatform/melis-ai-engine/src/Model/Tables/
Config del modulovendor/melisplatform/melis-ai-engine/config/module.config.php

Vedi anche: MelisAI, MelisAIEngineClaude, MelisAIEngineGemini, MelisAIToolCreator.