utilitas 1999.1.18 → 1999.1.20
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/README.md +1 -1
- package/dist/utilitas.lite.mjs +1 -1
- package/dist/utilitas.lite.mjs.map +1 -1
- package/lib/alan.mjs +89 -87
- package/lib/manifest.mjs +1 -1
- package/package.json +1 -1
package/lib/alan.mjs
CHANGED
|
@@ -54,38 +54,37 @@ const [
|
|
|
54
54
|
];
|
|
55
55
|
|
|
56
56
|
const [
|
|
57
|
-
OPENAI, GEMINI,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
JINA_EMBEDDING, JINA_CLIP,
|
|
57
|
+
OPENAI, GEMINI, OPENAI_TRAINING, OLLAMA, GPT_4O_MINI, GPT_4O, GPT_O1,
|
|
58
|
+
GPT_O3_MINI, GEMINI_20_FLASH, GEMINI_20_FLASH_THINKING, GEMINI_20_PRO, NOVA,
|
|
59
|
+
DEEPSEEK_R1, MD_CODE, TEXT_EMBEDDING_3_SMALL, TEXT_EMBEDDING_3_LARGE,
|
|
60
|
+
CLOUD_37_SONNET, AUDIO, WAV, ATTACHMENTS, CHAT, OPENAI_VOICE, MEDIUM, LOW,
|
|
61
|
+
HIGH, GPT_REASONING_EFFORT, THINK, THINK_STR, THINK_END, AZURE, TOOLS_STR,
|
|
62
|
+
TOOLS_END, TOOLS, TEXT, THINKING, OK, FUNC, GPT_45, REDACTED_THINKING,
|
|
63
|
+
GEMMA_3_27B, AZURE_OPENAI, ANTHROPIC, VERTEX_ANTHROPIC, GEMMA327B, v8k, ais,
|
|
64
|
+
MAX_TOOL_RECURSION, LOG, name, user, system, assistant, MODEL, JSON_OBJECT,
|
|
65
|
+
TOOL, silent, GEMINI_EMBEDDING_M, INVALID_FILE, tokenSafeRatio,
|
|
66
|
+
GPT_QUERY_LIMIT, CONTENT_IS_REQUIRED, OPENAI_HI_RES_SIZE, k, kT, m, minute,
|
|
67
|
+
hour, gb, trimTailing, EBD, GEMINI_20_FLASH_EXP, IMAGE, JINA,
|
|
68
|
+
JINA_DEEPSEARCH, JINA_CLIP,
|
|
70
69
|
] = [
|
|
71
|
-
'OpenAI', 'Gemini', '
|
|
72
|
-
'
|
|
73
|
-
'gemini-2.0-flash', 'gemini-2.0-
|
|
74
|
-
'
|
|
75
|
-
'text-embedding-3-
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'</
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
|
|
82
|
-
'
|
|
70
|
+
'OpenAI', 'Gemini', 'OPENAI_TRAINING', 'Ollama', 'gpt-4o-mini',
|
|
71
|
+
'gpt-4o', 'o1', 'o3-mini', 'gemini-2.0-flash',
|
|
72
|
+
'gemini-2.0-flash-thinking-exp', 'gemini-2.0-pro-exp', 'nova',
|
|
73
|
+
'deepseek-r1', '```', 'text-embedding-3-small',
|
|
74
|
+
'text-embedding-3-large', 'claude-3-7-sonnet@20250219', 'audio', 'wav',
|
|
75
|
+
'[ATTACHMENTS]', 'CHAT', 'OPENAI_VOICE', 'medium', 'low', 'high',
|
|
76
|
+
'medium', 'think', '<think>', '</think>', 'AZURE', '<tools>',
|
|
77
|
+
'</tools>', 'tools', 'text', 'thinking', 'OK', 'function',
|
|
78
|
+
'gpt-4.5-preview', 'redacted_thinking', 'gemma-3-27b-it',
|
|
79
|
+
'Azure Openai', 'Anthropic', 'Vertex Anthropic', 'gemma3:27b',
|
|
80
|
+
7680 * 4320, [], 10, { log: true }, 'Alan', 'user', 'system',
|
|
81
|
+
'assistant', 'model', 'json_object', 'tool', true,
|
|
83
82
|
'gemini-embedding-exp-03-07', 'Invalid file data.', 1.1, 100,
|
|
84
83
|
'Content is required.', 2000 * 768, x => 1024 * x, x => 1000 * x,
|
|
85
84
|
x => 1024 * 1024 * x, x => 60 * x, x => 60 * 60 * x,
|
|
86
85
|
x => 1024 * 1024 * 1024 * x, x => x.replace(/[\.\s]*$/, ''),
|
|
87
86
|
{ embedding: true }, 'gemini-2.0-flash-exp', 'image', 'Jina',
|
|
88
|
-
'jina-deepsearch-v1', '
|
|
87
|
+
'jina-deepsearch-v1', 'jina-clip-v2',
|
|
89
88
|
];
|
|
90
89
|
|
|
91
90
|
const [tool, messages, text]
|
|
@@ -102,6 +101,7 @@ const log = (cnt, opt) => _log(cnt, import.meta.url, { time: 1, ...opt || {} });
|
|
|
102
101
|
const assertContent = content => assert(content.length, CONTENT_IS_REQUIRED);
|
|
103
102
|
const countToolCalls = r => r?.split('\n').filter(x => x === TOOLS_STR).length;
|
|
104
103
|
const assertApiKey = (p, o) => assert(o?.apiKey, `${p} api key is required.`);
|
|
104
|
+
const getProviderIcon = provider => PROVIDER_ICONS[provider] || '🔮';
|
|
105
105
|
const libOpenAi = async opts => await need('openai', { ...opts, raw: true });
|
|
106
106
|
const OpenAI = async opts => new (await libOpenAi(opts)).OpenAI(opts);
|
|
107
107
|
const AzureOpenAI = async opts => new (await libOpenAi(opts)).AzureOpenAI(opts);
|
|
@@ -167,8 +167,8 @@ const MODELS = {
|
|
|
167
167
|
[JINA_DEEPSEARCH]: {
|
|
168
168
|
contextWindow: Infinity, maxInputTokens: Infinity,
|
|
169
169
|
maxOutputTokens: Infinity, imageCostTokens: 0, maxImageSize: Infinity,
|
|
170
|
-
supportedMimeTypes: [png, jpeg, MIME_TEXT, webp, pdf],
|
|
171
|
-
|
|
170
|
+
supportedMimeTypes: [png, jpeg, MIME_TEXT, webp, pdf], reasoning: true,
|
|
171
|
+
json: true, vision: true, deepsearch: true, defaultProvider: JINA,
|
|
172
172
|
},
|
|
173
173
|
[DEEPSEEK_R1]: {
|
|
174
174
|
contextWindow: kT(128), maxOutputTokens: k(32),
|
|
@@ -226,12 +226,25 @@ const DEFAULT_MODELS = {
|
|
|
226
226
|
[JINA]: JINA_DEEPSEARCH,
|
|
227
227
|
[OLLAMA]: GEMMA327B,
|
|
228
228
|
[OPENAI_VOICE]: NOVA,
|
|
229
|
-
[OPENAI_EMBEDDING]: TEXT_EMBEDDING_3_SMALL,
|
|
230
|
-
[GEMINI_EMEDDING]: GEMINI_EMBEDDING_M,
|
|
231
|
-
[JINA_EMBEDDING]: JINA_CLIP,
|
|
232
229
|
[OPENAI_TRAINING]: GPT_4O_MINI, // https://platform.openai.com/docs/guides/fine-tuning
|
|
233
230
|
};
|
|
234
|
-
|
|
231
|
+
|
|
232
|
+
const DEFAULT_EMBEDDING = {
|
|
233
|
+
[OPENAI]: TEXT_EMBEDDING_3_SMALL,
|
|
234
|
+
[GEMINI]: GEMINI_EMBEDDING_M,
|
|
235
|
+
[JINA]: JINA_CLIP,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const PROVIDER_ICONS = {
|
|
239
|
+
[OPENAI]: '⚛️', [AZURE_OPENAI]: '⚛️',
|
|
240
|
+
[ANTHROPIC]: '✳️', [VERTEX_ANTHROPIC]: '✳️',
|
|
241
|
+
[GEMINI]: '♊️', [AZURE]: '☁️', [OLLAMA]: '🦙', [JINA]: '✴️',
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const FEATURE_ICONS = {
|
|
245
|
+
audio: '📣', deepsearch: '🔍', fast: '⚡️', image: '🎨',
|
|
246
|
+
json: '📊', reasoning: '🧠', tools: '🧰', vision: '👁️',
|
|
247
|
+
};
|
|
235
248
|
|
|
236
249
|
const tokenRatioByWords = Math.min(
|
|
237
250
|
100 / 75, // ChatGPT: https://platform.openai.com/tokenizer
|
|
@@ -353,6 +366,22 @@ const buildAiId = (provider, model) => [provider, model].map(
|
|
|
353
366
|
x => ensureString(x, { case: 'SNAKE' })
|
|
354
367
|
).join('_');
|
|
355
368
|
|
|
369
|
+
const setupAi = ai => {
|
|
370
|
+
const id = buildAiId(ai.provider, ai.model.name);
|
|
371
|
+
const icon = getProviderIcon(ai.provider);
|
|
372
|
+
const features = Object.entries(FEATURE_ICONS).map(
|
|
373
|
+
x => ai.model[x[0]] ? x[1] : ''
|
|
374
|
+
).join('');
|
|
375
|
+
ais.push({
|
|
376
|
+
id, name: `${icon} ${ai.provider} (${ai.model.name})`,
|
|
377
|
+
features, initOrder: ais.length,
|
|
378
|
+
priority: DEFAULT_MODELS[ai.provider] === ai.model.name ? -1 : 0,
|
|
379
|
+
modelEmbedding: MODELS[DEFAULT_EMBEDDING[ai.provider]], ...ai,
|
|
380
|
+
prompt: ai.prompt && (async (c, o) => await ai.prompt(id, c, o)),
|
|
381
|
+
embedding: ai.embedding && (async (c, o) => await ai.embedding(id, c, o)),
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
|
|
356
385
|
const init = async (options = {}) => {
|
|
357
386
|
const provider = unifyProvider(options?.provider);
|
|
358
387
|
let models;
|
|
@@ -372,11 +401,9 @@ const init = async (options = {}) => {
|
|
|
372
401
|
assertApiKey(provider, options);
|
|
373
402
|
var client = await OpenAI(options);
|
|
374
403
|
for (let model of models) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
prompt: async (cnt, opts) => await promptOpenAI(id, cnt, opts),
|
|
379
|
-
embedding: async (i, o) => await createOpenAIEmbedding(id, i, o),
|
|
404
|
+
setupAi({
|
|
405
|
+
provider, model, client,
|
|
406
|
+
prompt: promptOpenAI, embedding: createOpenAIEmbedding,
|
|
380
407
|
});
|
|
381
408
|
}
|
|
382
409
|
break;
|
|
@@ -389,33 +416,23 @@ const init = async (options = {}) => {
|
|
|
389
416
|
apiVersion: '2025-01-01-preview',
|
|
390
417
|
deployment: model.name, ...options,
|
|
391
418
|
});
|
|
392
|
-
|
|
393
|
-
ais.push({
|
|
394
|
-
id, provider, model, priority: 0, initOrder: ais.length, client,
|
|
395
|
-
prompt: async (cnt, opts) => await promptOpenAI(id, cnt, opts),
|
|
396
|
-
});
|
|
419
|
+
setupAi({ provider, model, client, prompt: promptOpenAI });
|
|
397
420
|
break;
|
|
398
421
|
case AZURE:
|
|
399
422
|
assertApiKey(provider, options);
|
|
400
423
|
assert(options.baseURL, `${provider} api endpoint is required.`);
|
|
401
424
|
var model = models[0];
|
|
402
425
|
var client = await OpenAI(options);
|
|
403
|
-
|
|
404
|
-
ais.push({
|
|
405
|
-
id, provider, model, priority: 0, initOrder: ais.length, client,
|
|
406
|
-
prompt: async (cnt, opts) => await promptOpenAI(id, cnt, opts),
|
|
407
|
-
});
|
|
426
|
+
setupAi({ provider, model, client, prompt: promptOpenAI });
|
|
408
427
|
break;
|
|
409
428
|
case GEMINI:
|
|
410
429
|
assertApiKey(provider, options);
|
|
411
430
|
const { GoogleGenerativeAI } = await need('@google/generative-ai');
|
|
412
431
|
var client = new GoogleGenerativeAI(options.apiKey);
|
|
413
432
|
for (let model of models) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
prompt: async (cnt, opts) => await promptGemini(id, cnt, opts),
|
|
418
|
-
embedding: async (i, o) => await createGeminiEmbedding(id, i, o),
|
|
433
|
+
setupAi({
|
|
434
|
+
provider, model, client,
|
|
435
|
+
prompt: promptGemini, embedding: createGeminiEmbedding,
|
|
419
436
|
});
|
|
420
437
|
}
|
|
421
438
|
break;
|
|
@@ -425,11 +442,7 @@ const init = async (options = {}) => {
|
|
|
425
442
|
await need('@anthropic-ai/sdk')
|
|
426
443
|
).Anthropic)(options)
|
|
427
444
|
for (let model of models) {
|
|
428
|
-
|
|
429
|
-
ais.push({
|
|
430
|
-
id, provider, model, priority: 0, initOrder: ais.length, client,
|
|
431
|
-
prompt: async (cnt, opts) => await promptAnthropic(id, cnt, opts),
|
|
432
|
-
});
|
|
445
|
+
setupAi({ provider, model, client, prompt: promptAnthropic });
|
|
433
446
|
}
|
|
434
447
|
break;
|
|
435
448
|
case VERTEX_ANTHROPIC:
|
|
@@ -441,25 +454,19 @@ const init = async (options = {}) => {
|
|
|
441
454
|
var client = new ((
|
|
442
455
|
await need('@anthropic-ai/vertex-sdk')
|
|
443
456
|
).AnthropicVertex)({ region: options?.region || 'us-east5' });
|
|
444
|
-
|
|
445
|
-
ais.push({
|
|
446
|
-
id, provider, model, priority: 0, initOrder: ais.length, client: client,
|
|
447
|
-
prompt: async (cnt, opts) => await promptAnthropic(id, cnt, opts),
|
|
448
|
-
});
|
|
457
|
+
setupAi({ provider, model, client, prompt: promptAnthropic });
|
|
449
458
|
break;
|
|
450
459
|
case JINA:
|
|
451
460
|
assertApiKey(provider, options);
|
|
452
|
-
var [client,
|
|
461
|
+
var [client, clientEmbedding] = [await OpenAI({
|
|
453
462
|
baseURL: 'https://deepsearch.jina.ai/v1/', ...options,
|
|
454
463
|
}), await OpenAI({
|
|
455
464
|
baseURL: 'https://api.jina.ai/v1/', ...options,
|
|
456
465
|
})];
|
|
457
466
|
for (let model of models) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
prompt: async (cnt, opts) => await promptOpenAI(id, cnt, opts),
|
|
462
|
-
embedding: async (i, o) => await createJinaEmbedding(ebd, i, o),
|
|
467
|
+
setupAi({
|
|
468
|
+
provider, model, client, clientEmbedding,
|
|
469
|
+
prompt: promptOpenAI, embedding: createOpenAIEmbedding,
|
|
463
470
|
});
|
|
464
471
|
}
|
|
465
472
|
break;
|
|
@@ -469,11 +476,7 @@ const init = async (options = {}) => {
|
|
|
469
476
|
const phLog = m => log(`Ollama preheat: ${m?.message || m}`);
|
|
470
477
|
var client = await OpenAI({ baseURL, apiKey: 'ollama', ...options });
|
|
471
478
|
for (let model of models) {
|
|
472
|
-
|
|
473
|
-
ais.push({
|
|
474
|
-
id, provider, model, priority: 0, initOrder: ais.length, client,
|
|
475
|
-
prompt: async (cnt, opts) => await promptOpenAI(id, cnt, opts),
|
|
476
|
-
});
|
|
479
|
+
setupAi({ provider, model, client, prompt: promptOpenAI });
|
|
477
480
|
ignoreErrFunc(async () => {
|
|
478
481
|
phLog(await (await fetch(`${baseURL}completions`, {
|
|
479
482
|
method: 'POST', body: JSON.stringify({
|
|
@@ -492,8 +495,10 @@ const init = async (options = {}) => {
|
|
|
492
495
|
|
|
493
496
|
const packAi = (ais, options = {}) => {
|
|
494
497
|
const res = options.basic ? ais.map(x => ({
|
|
495
|
-
id: x.id,
|
|
496
|
-
initOrder: x.initOrder,
|
|
498
|
+
id: x.id, name: x.name, features: x.features,
|
|
499
|
+
initOrder: x.initOrder, priority: x.priority,
|
|
500
|
+
provider: x.provider, model: x.model, modelEmbedding: x.modelEmbedding,
|
|
501
|
+
prompt: !!x.prompt, embedding: !!x.embedding,
|
|
497
502
|
})) : ais;
|
|
498
503
|
return options.all ? res : res[0];
|
|
499
504
|
};
|
|
@@ -1216,7 +1221,7 @@ const checkEmbeddingInput = async (input, model) => {
|
|
|
1216
1221
|
return getInput();
|
|
1217
1222
|
};
|
|
1218
1223
|
|
|
1219
|
-
const createOpenAIEmbedding = async (
|
|
1224
|
+
const createOpenAIEmbedding = async (aiId, input, options) => {
|
|
1220
1225
|
// args from vertex embedding may be useful uere
|
|
1221
1226
|
// https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-text-embeddings
|
|
1222
1227
|
// task_type Description
|
|
@@ -1225,23 +1230,20 @@ const createOpenAIEmbedding = async (client, input, options) => {
|
|
|
1225
1230
|
// SEMANTIC_SIMILARITY Specifies the given text will be used for Semantic Textual Similarity(STS).
|
|
1226
1231
|
// CLASSIFICATION Specifies that the embeddings will be used for classification.
|
|
1227
1232
|
// CLUSTERING Specifies that the embeddings will be used for clustering.
|
|
1228
|
-
|
|
1229
|
-
const model = options?.model ||
|
|
1230
|
-
const resp = await client.embeddings.create({
|
|
1233
|
+
let { client, modelEmbedding, clientEmbedding } = await getAi(aiId);
|
|
1234
|
+
const model = options?.model || modelEmbedding.name;
|
|
1235
|
+
const resp = await (clientEmbedding || client).embeddings.create({
|
|
1231
1236
|
model, input: await checkEmbeddingInput(input, model),
|
|
1232
1237
|
});
|
|
1233
1238
|
return options?.raw ? resp : resp?.data[0].embedding;
|
|
1234
1239
|
};
|
|
1235
1240
|
|
|
1236
|
-
const createJinaEmbedding = async (client, input, options) =>
|
|
1237
|
-
await createOpenAIEmbedding(client, input, {
|
|
1238
|
-
model: DEFAULT_MODELS[JINA_EMBEDDING], ...options || {}
|
|
1239
|
-
});
|
|
1240
|
-
|
|
1241
1241
|
const createGeminiEmbedding = async (aiId, input, options) => {
|
|
1242
|
-
const { client } = await getAi(aiId);
|
|
1243
|
-
const model = options?.model ||
|
|
1244
|
-
const resp = await
|
|
1242
|
+
const { client, modelEmbedding, clientEmbedding } = await getAi(aiId);
|
|
1243
|
+
const model = options?.model || modelEmbedding.name;
|
|
1244
|
+
const resp = await (
|
|
1245
|
+
clientEmbedding || client
|
|
1246
|
+
).getGenerativeModel({ model }).embedContent(
|
|
1245
1247
|
await checkEmbeddingInput(input, model)
|
|
1246
1248
|
);
|
|
1247
1249
|
return options?.raw ? resp : resp?.embedding.values;
|
package/lib/manifest.mjs
CHANGED