utilitas 1999.1.20 → 1999.1.22
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 +75 -69
- package/lib/manifest.mjs +12 -12
- package/package.json +12 -12
package/lib/alan.mjs
CHANGED
|
@@ -38,7 +38,7 @@ You may be provided with some tools(functions) to help you gather information an
|
|
|
38
38
|
- Unless otherwise specified to require the original result, in most cases, you may reorganize the information obtained after using the tool to solve the problem as needed.`;
|
|
39
39
|
|
|
40
40
|
const _NEED = [
|
|
41
|
-
'@anthropic-ai/sdk', '@anthropic-ai/vertex-sdk', '@google/
|
|
41
|
+
'@anthropic-ai/sdk', '@anthropic-ai/vertex-sdk', '@google/genai',
|
|
42
42
|
'js-tiktoken', 'OpenAI',
|
|
43
43
|
];
|
|
44
44
|
|
|
@@ -65,7 +65,7 @@ const [
|
|
|
65
65
|
TOOL, silent, GEMINI_EMBEDDING_M, INVALID_FILE, tokenSafeRatio,
|
|
66
66
|
GPT_QUERY_LIMIT, CONTENT_IS_REQUIRED, OPENAI_HI_RES_SIZE, k, kT, m, minute,
|
|
67
67
|
hour, gb, trimTailing, EBD, GEMINI_20_FLASH_EXP, IMAGE, JINA,
|
|
68
|
-
JINA_DEEPSEARCH, JINA_CLIP,
|
|
68
|
+
JINA_DEEPSEARCH, JINA_CLIP, VERTEX,
|
|
69
69
|
] = [
|
|
70
70
|
'OpenAI', 'Gemini', 'OPENAI_TRAINING', 'Ollama', 'gpt-4o-mini',
|
|
71
71
|
'gpt-4o', 'o1', 'o3-mini', 'gemini-2.0-flash',
|
|
@@ -84,7 +84,7 @@ const [
|
|
|
84
84
|
x => 1024 * 1024 * x, x => 60 * x, x => 60 * 60 * x,
|
|
85
85
|
x => 1024 * 1024 * 1024 * x, x => x.replace(/[\.\s]*$/, ''),
|
|
86
86
|
{ embedding: true }, 'gemini-2.0-flash-exp', 'image', 'Jina',
|
|
87
|
-
'jina-deepsearch-v1', 'jina-clip-v2',
|
|
87
|
+
'jina-deepsearch-v1', 'jina-clip-v2', 'Vertex',
|
|
88
88
|
];
|
|
89
89
|
|
|
90
90
|
const [tool, messages, text]
|
|
@@ -236,9 +236,9 @@ const DEFAULT_EMBEDDING = {
|
|
|
236
236
|
};
|
|
237
237
|
|
|
238
238
|
const PROVIDER_ICONS = {
|
|
239
|
-
[OPENAI]: '⚛️', [AZURE_OPENAI]: '⚛️',
|
|
239
|
+
[OPENAI]: '⚛️', [AZURE_OPENAI]: '⚛️', [AZURE]: '☁️', [JINA]: '✴️',
|
|
240
|
+
[GEMINI]: '♊️', [VERTEX]: '📖', [OLLAMA]: '🦙',
|
|
240
241
|
[ANTHROPIC]: '✳️', [VERTEX_ANTHROPIC]: '✳️',
|
|
241
|
-
[GEMINI]: '♊️', [AZURE]: '☁️', [OLLAMA]: '🦙', [JINA]: '✴️',
|
|
242
242
|
};
|
|
243
243
|
|
|
244
244
|
const FEATURE_ICONS = {
|
|
@@ -261,7 +261,7 @@ let tokeniser;
|
|
|
261
261
|
|
|
262
262
|
const unifyProvider = provider => {
|
|
263
263
|
assert(provider = (provider || '').trim(), 'AI provider is required.');
|
|
264
|
-
for (let type of [OPENAI, AZURE_OPENAI, AZURE, GEMINI, ANTHROPIC,
|
|
264
|
+
for (let type of [OPENAI, AZURE_OPENAI, AZURE, GEMINI, VERTEX, ANTHROPIC,
|
|
265
265
|
VERTEX_ANTHROPIC, JINA, OLLAMA]) {
|
|
266
266
|
if (insensitiveCompare(provider, type)) { return type; }
|
|
267
267
|
}
|
|
@@ -347,18 +347,18 @@ const toolsClaude = async () => (await toolsOpenAI()).map(x => ({
|
|
|
347
347
|
}
|
|
348
348
|
}));
|
|
349
349
|
|
|
350
|
-
const toolsGemini = async () => (await toolsOpenAI()).map(x => ({
|
|
350
|
+
const toolsGemini = async (options) => (await toolsOpenAI()).map(x => ({
|
|
351
351
|
...x, def: {
|
|
352
|
-
name: x.def.function.name,
|
|
353
|
-
description: x.def.function.description,
|
|
352
|
+
name: x.def.function.name, description: x.def.function.description,
|
|
354
353
|
parameters: {
|
|
355
354
|
type: 'object',
|
|
356
355
|
properties: x.def.function.parameters.properties,
|
|
357
356
|
required: x.def.function.parameters.required,
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
357
|
+
}, ...options?.provider === 'VERTEX' ? {
|
|
358
|
+
response: x.def.function?.response ?? {
|
|
359
|
+
type: 'string', description: 'It could be a string or JSON',
|
|
360
|
+
}
|
|
361
|
+
} : {},
|
|
362
362
|
}
|
|
363
363
|
}));
|
|
364
364
|
|
|
@@ -426,9 +426,24 @@ const init = async (options = {}) => {
|
|
|
426
426
|
setupAi({ provider, model, client, prompt: promptOpenAI });
|
|
427
427
|
break;
|
|
428
428
|
case GEMINI:
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
var client = new
|
|
429
|
+
assert(options.apiKey, `${provider} api key is required.`);
|
|
430
|
+
var { GoogleGenAI } = await need('@google/genai');
|
|
431
|
+
var client = new GoogleGenAI(options);
|
|
432
|
+
for (let model of models) {
|
|
433
|
+
setupAi({
|
|
434
|
+
provider, model, client,
|
|
435
|
+
prompt: promptGemini, embedding: createGeminiEmbedding,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
break;
|
|
439
|
+
case VERTEX:
|
|
440
|
+
assert(options.credentials && options.project,
|
|
441
|
+
`${provider} credentials and project id are required.`);
|
|
442
|
+
process.env['GOOGLE_APPLICATION_CREDENTIALS'] = options.credentials;
|
|
443
|
+
var { GoogleGenAI } = await need('@google/genai');
|
|
444
|
+
var client = new GoogleGenAI({
|
|
445
|
+
vertexai: true, location: 'us-east5', ...options
|
|
446
|
+
});
|
|
432
447
|
for (let model of models) {
|
|
433
448
|
setupAi({
|
|
434
449
|
provider, model, client,
|
|
@@ -447,7 +462,8 @@ const init = async (options = {}) => {
|
|
|
447
462
|
break;
|
|
448
463
|
case VERTEX_ANTHROPIC:
|
|
449
464
|
// https://github.com/anthropics/anthropic-sdk-typescript/tree/main/packages/vertex-sdk
|
|
450
|
-
assert(options
|
|
465
|
+
assert(options.credentials && options.projectId,
|
|
466
|
+
`${provider} credentials and project id are required.`);
|
|
451
467
|
process.env['GOOGLE_APPLICATION_CREDENTIALS'] = options.credentials;
|
|
452
468
|
process.env['ANTHROPIC_VERTEX_PROJECT_ID'] = options.projectId;
|
|
453
469
|
var model = models[0];
|
|
@@ -506,7 +522,7 @@ const packAi = (ais, options = {}) => {
|
|
|
506
522
|
const getAi = async (id, options = {}) => {
|
|
507
523
|
if (id) {
|
|
508
524
|
const ai = ais.find(x => x.id === id);
|
|
509
|
-
assert(
|
|
525
|
+
assert(ai, `AI not found: ${id}.`);
|
|
510
526
|
return options?.client ? ai?.client : ai;
|
|
511
527
|
} else if (options?.select) {
|
|
512
528
|
const res = [];
|
|
@@ -795,6 +811,8 @@ const buildPrompts = async (model, input, options = {}) => {
|
|
|
795
811
|
history.push(buildClaudeMessage(x.response, _assistant));
|
|
796
812
|
break;
|
|
797
813
|
case GEMINI:
|
|
814
|
+
// https://github.com/google/generative-ai-js/blob/main/samples/node/advanced-chat.js
|
|
815
|
+
// Google's bug: history is not allowed while using inline_data?
|
|
798
816
|
if (options.attachments?.length) { return; }
|
|
799
817
|
history.push(buildGeminiHistory(x.request, _user));
|
|
800
818
|
history.push(buildGeminiHistory(x.response, { role: MODEL }));
|
|
@@ -826,9 +844,9 @@ const buildPrompts = async (model, input, options = {}) => {
|
|
|
826
844
|
}
|
|
827
845
|
};
|
|
828
846
|
msgBuilder();
|
|
829
|
-
await trimPrompt(() => [systemPrompt, history,
|
|
830
|
-
if (options.messages
|
|
831
|
-
options.messages
|
|
847
|
+
await trimPrompt(() => [systemPrompt, history, content], () => {
|
|
848
|
+
if (options.messages?.length) {
|
|
849
|
+
options.messages?.shift();
|
|
832
850
|
msgBuilder();
|
|
833
851
|
} else {
|
|
834
852
|
content = trimTailing(trimTailing(content).slice(0, -1)) + '...';
|
|
@@ -1110,15 +1128,6 @@ const deleteFile = async (aiId, file_id, options) => {
|
|
|
1110
1128
|
return await client.files.del(file_id);
|
|
1111
1129
|
};
|
|
1112
1130
|
|
|
1113
|
-
const generationConfig = options => ({
|
|
1114
|
-
generationConfig: {
|
|
1115
|
-
responseMimeType: options.jsonMode ? MIME_JSON : MIME_TEXT,
|
|
1116
|
-
responseModalities: options.modalities
|
|
1117
|
-
|| (options.imageMode ? [TEXT, IMAGE] : undefined),
|
|
1118
|
-
...options?.generationConfig || {},
|
|
1119
|
-
},
|
|
1120
|
-
});
|
|
1121
|
-
|
|
1122
1131
|
const packGeminiReferences = (chunks, supports) => {
|
|
1123
1132
|
let references = null;
|
|
1124
1133
|
if (chunks?.length && supports?.length) {
|
|
@@ -1133,9 +1142,9 @@ const packGeminiReferences = (chunks, supports) => {
|
|
|
1133
1142
|
};
|
|
1134
1143
|
|
|
1135
1144
|
const promptGemini = async (aiId, content, options = {}) => {
|
|
1136
|
-
let { client, model } = await getAi(aiId);
|
|
1137
|
-
let [result, references, functionCalls, responded, images]
|
|
1138
|
-
|
|
1145
|
+
let { provider, client, model } = await getAi(aiId);
|
|
1146
|
+
let [event, result, references, functionCalls, responded, images] =
|
|
1147
|
+
[null, options.result ?? '', null, [], false, []];
|
|
1139
1148
|
options.model = options.model || model.name;
|
|
1140
1149
|
model?.image === true && (options.imageMode = true);
|
|
1141
1150
|
assert(!(options.imageMode && !model.image), 'Image mode is not supported.');
|
|
@@ -1146,43 +1155,44 @@ const promptGemini = async (aiId, content, options = {}) => {
|
|
|
1146
1155
|
}
|
|
1147
1156
|
const { systemPrompt: systemInstruction, history, prompt }
|
|
1148
1157
|
= await buildPrompts(model, content, { ...options, flavor: GEMINI });
|
|
1149
|
-
const
|
|
1150
|
-
model: options.model,
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1158
|
+
const chat = client.chats.create({
|
|
1159
|
+
model: options.model, history, config: {
|
|
1160
|
+
responseMimeType: options.jsonMode ? MIME_JSON : MIME_TEXT,
|
|
1161
|
+
systemInstruction, responseModalities: options.modalities || (
|
|
1162
|
+
options.imageMode ? [TEXT, IMAGE] : undefined
|
|
1163
|
+
), ...options?.config || {}, ...model?.tools && !options.jsonMode
|
|
1164
|
+
&& options.model !== GEMINI_20_FLASH_EXP ? (options.tools ?? {
|
|
1165
|
+
tools: [
|
|
1166
|
+
// @todo: Gemini will failed when using these tools together.
|
|
1167
|
+
// https://ai.google.dev/gemini-api/docs/function-calling
|
|
1168
|
+
// { codeExecution: {} },
|
|
1169
|
+
// { googleSearch: {} },
|
|
1170
|
+
{
|
|
1171
|
+
functionDeclarations: (
|
|
1172
|
+
await toolsGemini({ provider })
|
|
1173
|
+
).map(x => x.def)
|
|
1174
|
+
},
|
|
1175
|
+
], toolConfig: { functionCallingConfig: { mode: 'AUTO' } },
|
|
1176
|
+
}) : {},
|
|
1177
|
+
},
|
|
1166
1178
|
});
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1179
|
+
const resp = await chat.sendMessageStream({ message: prompt });
|
|
1180
|
+
for await (const chunk of resp) {
|
|
1181
|
+
event = chunk.candidates[0];
|
|
1182
|
+
let [deltaText, deltaImages] = ['', []];
|
|
1183
|
+
event?.content?.parts?.map(x => {
|
|
1184
|
+
if (x.text) { deltaText = x.text; }
|
|
1185
|
+
else if (x.functionCall) { functionCalls.push(x); }
|
|
1186
|
+
else if (x.inlineData?.mimeType === png) {
|
|
1187
|
+
deltaImages.push(x.inlineData);
|
|
1188
|
+
images.push(x.inlineData);
|
|
1189
|
+
}
|
|
1178
1190
|
});
|
|
1179
|
-
functionCalls || (functionCalls = chunk.functionCalls);
|
|
1180
1191
|
const rfc = packGeminiReferences(
|
|
1181
|
-
|
|
1182
|
-
|
|
1192
|
+
event?.groundingMetadata?.groundingChunks,
|
|
1193
|
+
event?.groundingMetadata?.groundingSupports
|
|
1183
1194
|
);
|
|
1184
1195
|
rfc && (references = rfc);
|
|
1185
|
-
let deltaText = chunk?.text?.() || '';
|
|
1186
1196
|
options.result && deltaText
|
|
1187
1197
|
&& (responded = responded || (deltaText = `\n\n${deltaText}`));
|
|
1188
1198
|
result += deltaText;
|
|
@@ -1191,10 +1201,6 @@ const promptGemini = async (aiId, content, options = {}) => {
|
|
|
1191
1201
|
images: options.delta ? deltaImages : images,
|
|
1192
1202
|
}, options);
|
|
1193
1203
|
}
|
|
1194
|
-
const _resp = await resp.response;
|
|
1195
|
-
functionCalls = (
|
|
1196
|
-
functionCalls() || _resp.functionCalls() || []
|
|
1197
|
-
).map(x => ({ functionCall: x }));
|
|
1198
1204
|
const { toolsResult, toolsResponse } = await handleToolsCall(
|
|
1199
1205
|
{ role: MODEL, parts: functionCalls },
|
|
1200
1206
|
{ ...options, result, flavor: GEMINI }
|
package/lib/manifest.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const manifest = {
|
|
2
2
|
"name": "utilitas",
|
|
3
3
|
"description": "Just another common utility for JavaScript.",
|
|
4
|
-
"version": "1999.1.
|
|
4
|
+
"version": "1999.1.22",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/Leask/utilitas",
|
|
7
7
|
"main": "index.mjs",
|
|
@@ -19,7 +19,7 @@ const manifest = {
|
|
|
19
19
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"file-type": "^20.4.
|
|
22
|
+
"file-type": "^20.4.1",
|
|
23
23
|
"mathjs": "^14.3.1",
|
|
24
24
|
"uuid": "^11.1.0"
|
|
25
25
|
},
|
|
@@ -28,14 +28,14 @@ const manifest = {
|
|
|
28
28
|
"@anthropic-ai/vertex-sdk": "^0.7.0",
|
|
29
29
|
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
30
30
|
"@ffprobe-installer/ffprobe": "^2.1.2",
|
|
31
|
-
"@google-cloud/speech": "^
|
|
31
|
+
"@google-cloud/speech": "^7.0.0",
|
|
32
32
|
"@google-cloud/storage": "^7.15.2",
|
|
33
|
-
"@google-cloud/text-to-speech": "^
|
|
34
|
-
"@google-cloud/vision": "^
|
|
35
|
-
"@google/
|
|
33
|
+
"@google-cloud/text-to-speech": "^6.0.0",
|
|
34
|
+
"@google-cloud/vision": "^5.0.0",
|
|
35
|
+
"@google/genai": "^0.4.0",
|
|
36
36
|
"@mozilla/readability": "github:mozilla/readability",
|
|
37
|
-
"@sentry/node": "^9.
|
|
38
|
-
"@sentry/profiling-node": "^9.
|
|
37
|
+
"@sentry/node": "^9.6.0",
|
|
38
|
+
"@sentry/profiling-node": "^9.6.0",
|
|
39
39
|
"acme-client": "^5.4.0",
|
|
40
40
|
"browserify-fs": "^1.0.0",
|
|
41
41
|
"buffer": "^6.0.3",
|
|
@@ -53,9 +53,9 @@ const manifest = {
|
|
|
53
53
|
"node-mailjet": "^6.0.8",
|
|
54
54
|
"node-polyfill-webpack-plugin": "^4.1.0",
|
|
55
55
|
"office-text-extractor": "^3.0.3",
|
|
56
|
-
"openai": "^4.87.
|
|
57
|
-
"pdfjs-dist": "^
|
|
58
|
-
"pg": "^8.14.
|
|
56
|
+
"openai": "^4.87.4",
|
|
57
|
+
"pdfjs-dist": "^5.0.375",
|
|
58
|
+
"pg": "^8.14.1",
|
|
59
59
|
"pgvector": "^0.2.0",
|
|
60
60
|
"ping": "^0.4.4",
|
|
61
61
|
"process": "^0.11.10",
|
|
@@ -68,7 +68,7 @@ const manifest = {
|
|
|
68
68
|
"url": "github:Leask/node-url",
|
|
69
69
|
"webpack-cli": "^6.0.1",
|
|
70
70
|
"whisper-node": "^1.1.1",
|
|
71
|
-
"wrangler": "^
|
|
71
|
+
"wrangler": "^4.1.0",
|
|
72
72
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz",
|
|
73
73
|
"youtube-transcript": "^1.2.1"
|
|
74
74
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "utilitas",
|
|
3
3
|
"description": "Just another common utility for JavaScript.",
|
|
4
|
-
"version": "1999.1.
|
|
4
|
+
"version": "1999.1.22",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/Leask/utilitas",
|
|
7
7
|
"main": "index.mjs",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"file-type": "^20.4.
|
|
33
|
+
"file-type": "^20.4.1",
|
|
34
34
|
"mathjs": "^14.3.1",
|
|
35
35
|
"uuid": "^11.1.0"
|
|
36
36
|
},
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
"@anthropic-ai/vertex-sdk": "^0.7.0",
|
|
40
40
|
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
41
41
|
"@ffprobe-installer/ffprobe": "^2.1.2",
|
|
42
|
-
"@google-cloud/speech": "^
|
|
42
|
+
"@google-cloud/speech": "^7.0.0",
|
|
43
43
|
"@google-cloud/storage": "^7.15.2",
|
|
44
|
-
"@google-cloud/text-to-speech": "^
|
|
45
|
-
"@google-cloud/vision": "^
|
|
46
|
-
"@google/
|
|
44
|
+
"@google-cloud/text-to-speech": "^6.0.0",
|
|
45
|
+
"@google-cloud/vision": "^5.0.0",
|
|
46
|
+
"@google/genai": "^0.4.0",
|
|
47
47
|
"@mozilla/readability": "github:mozilla/readability",
|
|
48
|
-
"@sentry/node": "^9.
|
|
49
|
-
"@sentry/profiling-node": "^9.
|
|
48
|
+
"@sentry/node": "^9.6.0",
|
|
49
|
+
"@sentry/profiling-node": "^9.6.0",
|
|
50
50
|
"acme-client": "^5.4.0",
|
|
51
51
|
"browserify-fs": "^1.0.0",
|
|
52
52
|
"buffer": "^6.0.3",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"node-mailjet": "^6.0.8",
|
|
65
65
|
"node-polyfill-webpack-plugin": "^4.1.0",
|
|
66
66
|
"office-text-extractor": "^3.0.3",
|
|
67
|
-
"openai": "^4.87.
|
|
68
|
-
"pdfjs-dist": "^
|
|
69
|
-
"pg": "^8.14.
|
|
67
|
+
"openai": "^4.87.4",
|
|
68
|
+
"pdfjs-dist": "^5.0.375",
|
|
69
|
+
"pg": "^8.14.1",
|
|
70
70
|
"pgvector": "^0.2.0",
|
|
71
71
|
"ping": "^0.4.4",
|
|
72
72
|
"process": "^0.11.10",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"url": "github:Leask/node-url",
|
|
80
80
|
"webpack-cli": "^6.0.1",
|
|
81
81
|
"whisper-node": "^1.1.1",
|
|
82
|
-
"wrangler": "^
|
|
82
|
+
"wrangler": "^4.1.0",
|
|
83
83
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz",
|
|
84
84
|
"youtube-transcript": "^1.2.1"
|
|
85
85
|
}
|