ForgeTotal.js 5
el

Total.js 5

Συζητήστε με μοντέλα γλωσσών με AIMODEL(), NEWAIMODel() και AIPARSER()

Total.js 5 · total5@0.0.19 aillmintegrations Εκτελέστηκε με το Total.js 5

Το total5 δεν περιλαμβάνει σύνδεση με κανέναν πάροχο. Σας δίνει τρία κομμάτια που λειτουργούν μαζί:

  • Το NEWAIMODEL('name', config, driver) καταχωρίζει τον driver ενός ή περισσότερων μοντέλων (το 'a,b' καταχωρίζει τον ίδιο driver για δύο ονόματα). Ο driver είναι function(ai, done): το ai.payload έχει model, messages, tools, prompt και think, το ai.config είναι η ρύθμιση και το ai.options.stream είναι η συνάρτηση που πέρασε ο καλών στο stream() (ή undefined). Απαντήστε με done(error, response).
  • Το AIMODEL('name') ξεκινά ένα αίτημα για ένα καταχωρισμένο μοντέλο και επιστρέφει έναν builder. Τα system(text), user(text) και assistant(text) προσθέτουν ένα μήνυμα, τα prompt(text), tool(definition) και think() συμπληρώνουν το υπόλοιπο payload και το configure({ ... }) προσθέτει στο ai.config μόνο για αυτή την κλήση. Ολοκληρώστε το με callback(fn), await promise($) ή stream(fn)· ο driver εκτελείται μετά τον τρέχοντα γύρο, οπότε μπορείτε πρώτα να αλυσοδέσετε τα πάντα.
  • Το AIPARSER(provider) επιστρέφει έναν parser για την απάντηση ροής ενός παρόχου (ο πηγαίος κώδικας του total5 γνωρίζει τα openai, claude/anthropic, gemini/google, ollama και openai_responses και διαβάζει οποιοδήποτε άλλο όνομα ως γενική μορφή· παρακάτω εκτελείται μόνο το openai). Το write(chunk) δέχεται κομμάτια της ροής (κρατά τις ατελείς γραμμές μέχρι το επόμενο κομμάτι), το end() την ολοκληρώνει και τα δύο επιστρέφουν { content, thinking, tools, reasoning }. Το parser.on('content', fn) καλείται με κάθε μέρος του κειμένου καθώς φτάνει.

Ένα μοντέλο που δεν έχει καταχωριστεί απαντά με το σφάλμα AI model not found.. Το παράδειγμα καταγράφει έναν τοπικό οδηγό που επιστρέφει μια απάντηση από τα μηνύματα που παρέχονται.

definitions/ai.js
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 });
});
controllers/ai.js
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 });
}