Habla con modelos de lenguaje con AIMODEL(), NEWAIMODEL() y AIPARSER()
total5 no envía una conexión a ningún proveedor. Te ofrece tres piezas que funcionan juntas:
NEWAIMODEL('name', config, driver)registra el controlador de uno o más modelos ('a,b'registra el mismo controlador para dos nombres). El controlador esfunction(ai, done):ai.payloadtienemodel,messages,tools,promptythink,ai.configes la configuración yai.options.streames la función. la persona que llama pasó astream()(oundefined). Responda condone(error, response).AIMODEL('name')inicia una solicitud de un modelo registrado y devuelve un constructor.system(text),user(text)yassistant(text)agregan un mensaje,prompt(text),tool(definition)ythink()completan el resto de la carga útil, yconfigure({ ... })agrega aai.configsolo para esta llamada. Termínelo concallback(fn),await promise($)ostream(fn); el conductor corre después del giro actual, por lo que puedes encadenar todo primero.AIPARSER(provider)devuelve un analizador para la respuesta transmitida de un proveedor (la fuente detotal5conoceopenai,claude/anthropic,gemini/google,ollamayopenai_responses, y lee cualquier otro nombre como formato genérico, a continuación solo se ejecutaopenai).write(chunk)toma partes de la secuencia (mantiene líneas incompletas hasta la siguiente pieza),end()la finaliza y ambos devuelven{ content, thinking, tools, reasoning }.parser.on('content', fn)se llama con cada parte del texto a medida que llega.
Un modelo que no estaba registrado responde con el error AI model not found.. El ejemplo registra un controlador local que devuelve una respuesta de los mensajes proporcionados.
NEWAIMODEL('echo', { prefix: 'Echo' }, function(ai, done) {
const last = ai.payload.messages.filter(n => n.role === 'user').pop();
const text = ai.config.prefix + ': ' + (last ? last.content : '');
// A real driver would send ai.payload to the provider and send the pieces to ai.options.stream
if (ai.options.stream) {
for (const word of text.split(' '))
ai.options.stream(word + ' ');
}
done(null, { content: text, roles: ai.payload.messages.map(n => n.role), tools: ai.payload.tools.length, think: !!ai.payload.think });
});exports.install = function() {
ROUTE('POST /ask/', ask);
ROUTE('GET /ask-config/', askconfig);
ROUTE('GET /ask-stream/', askstream);
ROUTE('GET /ask-missing/', missing);
ROUTE('GET /parse/', parse);
};
async function ask($) {
const response = await AIMODEL('echo').system('You are brief.').user($.body.question).tool({ name: 'weather' }).think().promise($);
$.json(response);
}
function askconfig($) {
AIMODEL('echo').user('hello').configure({ prefix: 'Custom' }).callback($.callback());
}
function askstream($) {
const parts = [];
AIMODEL('echo').user('one two three').stream(part => parts.push(part)).callback(function(err, response) {
$.json({ parts: parts, content: response.content });
});
}
function missing($) {
AIMODEL('nobody').user('hi').callback($.callback());
}
function parse($) {
const parser = AIPARSER('openai');
const events = [];
parser.on('content', e => events.push(e.delta));
// the second piece starts in the middle of a line
parser.write('data: {"choices":[{"delta":{"content":"Hel"}}]}\n\ndata: {"choices":[{"delta":{"con');
parser.write('tent":"lo"}}]}\n\ndata: [DONE]\n');
const output = parser.end();
$.json({ output: output, events: events });
}