utilitas 2001.1.87 โ 2001.1.89
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 +87 -47
- package/lib/manifest.mjs +1 -1
- package/package.json +1 -1
package/lib/alan.mjs
CHANGED
|
@@ -49,12 +49,13 @@ const [
|
|
|
49
49
|
TOOLS_STR, TOOLS_END, TOOLS, TEXT, OK, FUNC, GPT_52, GPT_51_CODEX,
|
|
50
50
|
GPT_IMAGE_15, GEMMA_3_27B, ANTHROPIC, ais, MAX_TOOL_RECURSION, LOG, name,
|
|
51
51
|
user, system, assistant, JSON_OBJECT, PROMPT_IS_REQUIRED, k, trimTailing,
|
|
52
|
-
trimBeginning, GEMINI_30_PRO_IMAGE, IMAGE, JINA,
|
|
53
|
-
|
|
52
|
+
trimBeginning, GEMINI_30_PRO_IMAGE, IMAGE, JINA, SILICONFLOW,
|
|
53
|
+
SF_DEEPSEEK_32, OPENROUTER_API, OPENROUTER, AUTO, TOOL, ONLINE,
|
|
54
54
|
GEMINI_30_PRO, GEMINI_30_FLASH, IMAGEN_4_ULTRA, VEO_31, IMAGEN_4_UPSCALE,
|
|
55
55
|
ERROR_GENERATING, GEMINI_25_FLASH_TTS, GEMINI_25_PRO_TTS, wav, PNG_EXT,
|
|
56
56
|
GPT_4O_MIMI_TTS, GPT_4O_TRANSCRIBE, INVALID_AUDIO, OGG_EXT, ELLIPSIS,
|
|
57
|
-
TOP_LIMIT, ATTACHMENT, PROCESSING, CURSOR, LN1, LN2, TOP, DEEPSEEK
|
|
57
|
+
TOP_LIMIT, ATTACHMENT, PROCESSING, CURSOR, LN1, LN2, TOP, DEEPSEEK,
|
|
58
|
+
DEEP_RESEARCH_PRO,
|
|
58
59
|
] = [
|
|
59
60
|
'OpenAI', 'Google', 'Ollama', 'nova', 'deepseek-3.2-speciale', '```',
|
|
60
61
|
'claude-opus-4.5', 'audio', 'wav', 'OPENAI_VOICE', 'medium', 'think',
|
|
@@ -64,16 +65,15 @@ const [
|
|
|
64
65
|
{ role: 'assistant' }, 'json_object', 'Prompt is required.',
|
|
65
66
|
x => 1000 * x, x => x.replace(/[\.\s]*$/, ''),
|
|
66
67
|
x => x.replace(/^[\.\s]*/, ''), 'gemini-3-pro-image-preview', 'image',
|
|
67
|
-
'Jina', '
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'gemini-3-pro-preview', 'gemini-3-flash-preview',
|
|
68
|
+
'Jina', 'SiliconFlow', 'deepseek-ai/DeepSeek-V3.2-exp',
|
|
69
|
+
'https://openrouter.ai/api/v1', 'OpenRouter', 'openrouter/auto', 'tool',
|
|
70
|
+
':online', 'gemini-3-pro-preview', 'gemini-3-flash-preview',
|
|
71
71
|
'imagen-4.0-ultra-generate-001', 'veo-3.1-generate-preview',
|
|
72
72
|
'imagen-4.0-upscale-preview', 'Error generating content.',
|
|
73
73
|
'gemini-2.5-flash-preview-tts', 'gemini-2.5-pro-preview-tts', 'wav',
|
|
74
74
|
'png', 'gpt-4o-mini-tts', 'gpt-4o-transcribe', 'Invalid audio data.',
|
|
75
75
|
'ogg', '...', 3, 'ATTACHMENT', { processing: true }, ' โ', '\n\n',
|
|
76
|
-
'\n\n\n', 'top', 'DeepSeek',
|
|
76
|
+
'\n\n\n', 'top', 'DeepSeek', 'deep-research-pro-preview-12-2025',
|
|
77
77
|
];
|
|
78
78
|
|
|
79
79
|
const [joinL1, joinL2]
|
|
@@ -97,12 +97,12 @@ const m = x => k(k(x));
|
|
|
97
97
|
const [MAX_TOKENS, ATTACHMENT_TOKEN_COST] = [m(1), k(10)];
|
|
98
98
|
|
|
99
99
|
const MODEL_ICONS = {
|
|
100
|
-
[OPENROUTER]: '๐', [OPENAI]: 'โ๏ธ', [
|
|
100
|
+
[OPENROUTER]: '๐', [OPENAI]: 'โ๏ธ', [GOOGLE]: 'โ๏ธ', // [JINA]: 'โด๏ธ',
|
|
101
101
|
[OLLAMA]: '๐ฆ', [ANTHROPIC]: 'โณ๏ธ', [SILICONFLOW]: '๐งฌ', [DEEPSEEK]: '๐ฌ',
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
const FEATURE_ICONS = {
|
|
105
|
-
audio: '๐',
|
|
105
|
+
audio: '๐', 'deep-research': '๐', fast: 'โก๏ธ', hearing: '๐', hidden: '๐',
|
|
106
106
|
image: '๐จ', reasoning: '๐ง ', structured: '๐', tools: '๐งฐ', video: '๐ฌ',
|
|
107
107
|
vision: '๐๏ธ', // finetune: '๐ง',
|
|
108
108
|
};
|
|
@@ -191,12 +191,10 @@ const MODELS = {
|
|
|
191
191
|
source: OPENAI, maxInputTokens: 0,
|
|
192
192
|
hearing: true, fast: true, hidden: true, defaultProvider: OPENAI,
|
|
193
193
|
},
|
|
194
|
-
//
|
|
195
|
-
[
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
supportedMimeTypes: [MIME_PNG, MIME_JPEG, MIME_TEXT, MIME_WEBP, MIME_PDF],
|
|
199
|
-
defaultProvider: JINA,
|
|
194
|
+
// agents with deep-research capabilities
|
|
195
|
+
[DEEP_RESEARCH_PRO]: {
|
|
196
|
+
source: GOOGLE, contextWindow: m(1.05), maxOutputTokens: k(65.5),
|
|
197
|
+
'deep-research': true, reasoning: true, defaultProvider: GOOGLE,
|
|
200
198
|
},
|
|
201
199
|
// best Chinese models
|
|
202
200
|
[DEEPSEEK_32]: DEEPSEEK_32_RULES,
|
|
@@ -252,7 +250,7 @@ for (const n in MODELS) {
|
|
|
252
250
|
// }
|
|
253
251
|
// // for other features, if any model supports it, then AUTO supports it
|
|
254
252
|
// for (const key of [
|
|
255
|
-
// 'structured', 'reasoning', 'tools', 'vision', 'fast', '
|
|
253
|
+
// 'structured', 'reasoning', 'tools', 'vision', 'fast', 'deep-research', 'image',
|
|
256
254
|
// ]) {
|
|
257
255
|
// MODELS[AUTO][key] = MODELS[AUTO][key] || MODELS[n][key];
|
|
258
256
|
// }
|
|
@@ -266,7 +264,6 @@ for (const n in MODELS) {
|
|
|
266
264
|
const DEFAULT_MODELS = {
|
|
267
265
|
[OPENROUTER]: GEMINI_30_FLASH,
|
|
268
266
|
[SILICONFLOW]: SF_DEEPSEEK_32,
|
|
269
|
-
[JINA]: JINA_DEEPSEARCH,
|
|
270
267
|
[OLLAMA]: GEMMA_3_27B,
|
|
271
268
|
[OPENAI_VOICE]: NOVA,
|
|
272
269
|
};
|
|
@@ -275,7 +272,7 @@ let _tools;
|
|
|
275
272
|
|
|
276
273
|
const unifyProvider = provider => {
|
|
277
274
|
assert(provider = (provider || '').trim(), 'AI provider is required.');
|
|
278
|
-
for (let type of [OPENROUTER, GOOGLE, OPENAI,
|
|
275
|
+
for (let type of [OPENROUTER, GOOGLE, OPENAI, OLLAMA, SILICONFLOW]) { // JINA,
|
|
279
276
|
if (insensitiveCompare(provider, type)) { return type; }
|
|
280
277
|
}
|
|
281
278
|
throwError(`Invalid AI provider: ${provider}.`);
|
|
@@ -443,17 +440,6 @@ const init = async (options = {}) => {
|
|
|
443
440
|
});
|
|
444
441
|
}
|
|
445
442
|
break;
|
|
446
|
-
case JINA:
|
|
447
|
-
assertApiKey(provider, options);
|
|
448
|
-
var { client } = await OpenAI({
|
|
449
|
-
baseURL: 'https://deepsearch.jina.ai/v1/', ...options,
|
|
450
|
-
});
|
|
451
|
-
for (let model of models) {
|
|
452
|
-
setupAi({
|
|
453
|
-
provider, model, client, prompt: promptOpenRouter, priority,
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
break;
|
|
457
443
|
case OLLAMA:
|
|
458
444
|
// https://github.com/ollama/ollama/blob/main/docs/openai.md
|
|
459
445
|
const baseURL = 'http://localhost:11434/v1/';
|
|
@@ -687,7 +673,7 @@ const packResp = async (resp, options) => {
|
|
|
687
673
|
// "title": "ๅจ็ทๆ้- ็ฎๅๆ้- ็ทไธๆ้- ๆ้็ทไธ - ้ฌง้",
|
|
688
674
|
// "url": "https://naozhong.tw/shijian/",
|
|
689
675
|
// "content": "- [้ฌง้](https://naozhong.tw/)\n- [่จๆๅจ](https://naozhong.tw/jishiqi/)\n- [็ขผ้ถ](https://naozhong.tw/miaobiao/)\n- [ๆ้](https://naozhong.tw/shijian/)\n\n# ็พๅจๆ้\n\nๅ ๅ
ฅ\n\n- [็ทจ่ผฏ](javascript:;)\n- [็งป่ณ้ ็ซฏ](javascript:;)\n- [ไธ็งป](javascript:;)\n- [ไธ็งป](javascript:;)\n- [ๅช้ค](javascript:;)\n\n# ๆๅธธ็จ\n\n| | |\n| --- | --- |\n| [ๅฐๅ](https://naozhong.tw/shijian/%E5%8F%B0%E5%8C%97/) | 10:09:14 |\n| [ๅไบฌ๏ผไธญๅ](https://naozhong.tw/shijian/%E5%8C%97%E4%BA%AC-%E4%B8%AD%E5%9C%8B/) | 10:09:14 |\n| [ไธๆตท๏ผไธญๅ](https://naozhong.tw/shijian/%E4%B8%8A%E6%B5%B7-%E4%B8%AD%E5%9C%8B/) | 10:09:14 |\n| [็้ญฏๆจ้ฝ๏ผไธญๅ](https://naozhong.tw/shijian/%E7%83%8F%E9%AD%AF%",
|
|
690
|
-
// "dateTime": "2025-03-13 06:48:01" // jina
|
|
676
|
+
// "dateTime": "2025-03-13 06:48:01" // jina deep-research only
|
|
691
677
|
// }
|
|
692
678
|
// },
|
|
693
679
|
// ];
|
|
@@ -700,21 +686,21 @@ const packResp = async (resp, options) => {
|
|
|
700
686
|
).join('\n');
|
|
701
687
|
}
|
|
702
688
|
txt = txt.split('\n');
|
|
703
|
-
const [reJinaStr, reJinaEnd]
|
|
704
|
-
|
|
705
|
-
const fixJina = [];
|
|
706
|
-
for (let l of txt) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
689
|
+
// const [reJinaStr, reJinaEnd]
|
|
690
|
+
// = [`^\s*(${THINK_STR})`, `(${THINK_END})\s*$`].map(x => new RegExp(x));
|
|
691
|
+
// const fixJina = [];
|
|
692
|
+
// for (let l of txt) {
|
|
693
|
+
// let catched = false;
|
|
694
|
+
// if (reJinaStr.test(l)) {
|
|
695
|
+
// fixJina.push(THINK_STR);
|
|
696
|
+
// l = l.replace(reJinaStr, '');
|
|
697
|
+
// }
|
|
698
|
+
// if (reJinaEnd.test(l)) {
|
|
699
|
+
// l = l.replace(reJinaEnd, '');
|
|
700
|
+
// catched = true;
|
|
701
|
+
// }
|
|
702
|
+
// fixJina.push(l, ...catched ? [THINK_END, ''] : []);
|
|
703
|
+
// }
|
|
718
704
|
txt = fixJina;
|
|
719
705
|
for (let i in txt) {
|
|
720
706
|
switch (txt[i]) {
|
|
@@ -732,7 +718,7 @@ const packResp = async (resp, options) => {
|
|
|
732
718
|
...audio ? { audio } : {}, ...images?.length ? { images } : {},
|
|
733
719
|
processing: !!options?.processing,
|
|
734
720
|
model: packModelId([
|
|
735
|
-
options
|
|
721
|
+
options?.provider, options?.router?.provider,
|
|
736
722
|
options?.router?.model || options?.model,
|
|
737
723
|
]),
|
|
738
724
|
};
|
|
@@ -1117,6 +1103,60 @@ const promptGoogle = async (aiId, prompt, options = {}) => {
|
|
|
1117
1103
|
}, model: packModelId([provider, M.source, M.name]),
|
|
1118
1104
|
};
|
|
1119
1105
|
}
|
|
1106
|
+
} else if (M?.['deep-research']) {
|
|
1107
|
+
const pkgOptions = { ...options || {}, provider, model: M.name };
|
|
1108
|
+
let interactionId, last_event_id, isComplete = false;
|
|
1109
|
+
let [thought, text, result] = ['', '', ''];
|
|
1110
|
+
var resp;
|
|
1111
|
+
// Helper to handle the event logic
|
|
1112
|
+
const handleStream = async (stream) => {
|
|
1113
|
+
for await (const chunk of stream) {
|
|
1114
|
+
chunk.event_type === 'interaction.start'
|
|
1115
|
+
&& (interactionId = chunk.interaction.id);
|
|
1116
|
+
chunk.event_id && (last_event_id = chunk.event_id);
|
|
1117
|
+
let deltaThought = '', deltaText = '', delta = '';
|
|
1118
|
+
if (chunk.event_type === 'content.delta') {
|
|
1119
|
+
if (chunk.delta.type === 'text') {
|
|
1120
|
+
thought && (deltaThought = `${THINK_END}\n\n`);
|
|
1121
|
+
text += (deltaText = chunk.delta.text);
|
|
1122
|
+
} else if (chunk.delta.type === 'thought_summary') {
|
|
1123
|
+
deltaThought = chunk.delta.content.text;
|
|
1124
|
+
thought || (deltaThought = `${THINK_STR}\n${deltaThought}`);
|
|
1125
|
+
thought += deltaThought;
|
|
1126
|
+
}
|
|
1127
|
+
result += (delta = deltaThought + deltaText);
|
|
1128
|
+
await streamResp({
|
|
1129
|
+
text: options.delta ? delta : result,
|
|
1130
|
+
}, pkgOptions);
|
|
1131
|
+
} else if (chunk.event_type === 'interaction.complete') {
|
|
1132
|
+
isComplete = true;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
// 1. Start the task with streaming
|
|
1137
|
+
resp = await client.interactions.create({
|
|
1138
|
+
input: prompt, agent: M.name, background: true, store: true,
|
|
1139
|
+
stream: true, // tools: [],
|
|
1140
|
+
agent_config: { type: 'deep-research', thinking_summaries: 'auto' },
|
|
1141
|
+
previous_interaction_id: options?.previous_interaction_id,
|
|
1142
|
+
});
|
|
1143
|
+
await handleStream(resp);
|
|
1144
|
+
// 2. Reconnect Loop
|
|
1145
|
+
while (!isComplete && interactionId) {
|
|
1146
|
+
log(`[DRS] Reconnecting to interaction ${interactionId} from event ${last_event_id}...`);
|
|
1147
|
+
try {
|
|
1148
|
+
resp = await client.interactions.get(interactionId, {
|
|
1149
|
+
stream: true, last_event_id,
|
|
1150
|
+
});
|
|
1151
|
+
await handleStream(resp);
|
|
1152
|
+
} catch (e) {
|
|
1153
|
+
log('[DRS] Reconnection failed, retrying in 2s...');
|
|
1154
|
+
await timeout(2000);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
// 3. Return response
|
|
1158
|
+
options?.raw || (resp = await packResp({ text: result }, pkgOptions));
|
|
1159
|
+
return resp;
|
|
1120
1160
|
} else {
|
|
1121
1161
|
throwError('Unsupported model.');
|
|
1122
1162
|
}
|
package/lib/manifest.mjs
CHANGED