utilitas 2001.1.84 → 2001.1.86

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/lib/alan.mjs CHANGED
@@ -47,19 +47,19 @@ const [
47
47
  OPENAI, GOOGLE, OLLAMA, NOVA, DEEPSEEK_32, MD_CODE, CLOUD_OPUS_45, AUDIO,
48
48
  WAV, OPENAI_VOICE, GPT_REASONING_EFFORT, THINK, THINK_STR, THINK_END,
49
49
  TOOLS_STR, TOOLS_END, TOOLS, TEXT, OK, FUNC, GPT_52, GPT_51_CODEX,
50
- GPT_5_IMAGE, GEMMA_3_27B, ANTHROPIC, ais, MAX_TOOL_RECURSION, LOG, name,
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
52
  trimBeginning, GEMINI_30_PRO_IMAGE, IMAGE, JINA, JINA_DEEPSEARCH,
53
53
  SILICONFLOW, 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
- ERROR_GENERATING, GEMINI_25_FLASH_TTS, GEMINI_25_PRO_TTS, wav,
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
57
  TOP_LIMIT, ATTACHMENT, PROCESSING, CURSOR, LN1, LN2, TOP, DEEPSEEK
58
58
  ] = [
59
59
  'OpenAI', 'Google', 'Ollama', 'nova', 'deepseek-3.2-speciale', '```',
60
60
  'claude-opus-4.5', 'audio', 'wav', 'OPENAI_VOICE', 'medium', 'think',
61
61
  '<think>', '</think>', '<tools>', '</tools>', 'tools', 'text', 'OK',
62
- 'function', 'gpt-5.2', 'gpt-5.1-codex', 'gpt-5-image', 'gemma3:27b',
62
+ 'function', 'gpt-5.2', 'gpt-5.1-codex', 'gpt-image-1.5', 'gemma3:27b',
63
63
  'Anthropic', [], 30, { log: true }, 'Alan', 'user', { role: 'system' },
64
64
  { role: 'assistant' }, 'json_object', 'Prompt is required.',
65
65
  x => 1000 * x, x => x.replace(/[\.\s]*$/, ''),
@@ -70,10 +70,10 @@ const [
70
70
  '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
- 'gemini-2.5-flash-preview-tts', 'gemini-2.5-pro-tts', 'wav',
74
- 'gpt-4o-mini-tts', 'gpt-4o-transcribe', 'Invalid audio data.', 'ogg',
75
- '...', 3, 'ATTACHMENT', { processing: true }, ' █', '\n\n', '\n\n\n',
76
- 'top', 'DeepSeek',
73
+ 'gemini-2.5-flash-preview-tts', 'gemini-2.5-pro-preview-tts', 'wav',
74
+ 'png', 'gpt-4o-mini-tts', 'gpt-4o-transcribe', 'Invalid audio data.',
75
+ 'ogg', '...', 3, 'ATTACHMENT', { processing: true }, ' █', '\n\n',
76
+ '\n\n\n', 'top', 'DeepSeek',
77
77
  ];
78
78
 
79
79
  const [joinL1, joinL2]
@@ -152,13 +152,18 @@ const MODELS = {
152
152
  source: GOOGLE, maxInputTokens: 480,
153
153
  image: true, defaultProvider: GOOGLE,
154
154
  },
155
+ // [IMAGEN_4_UPSCALE]: {
156
+ // source: GOOGLE, maxInputTokens: 0, image: true,
157
+ // supportedMimeTypes: [MIME_PNG, MIME_JPEG], defaultProvider: GOOGLE,
158
+ // },
155
159
  [VEO_31]: {
156
160
  source: GOOGLE, maxInputTokens: 1024, attachmentTokenCost: 0,
157
161
  video: true, vision: true,
158
162
  supportedMimeTypes: [MIME_PNG, MIME_JPEG], defaultProvider: GOOGLE,
159
163
  },
160
- [GPT_5_IMAGE]: {
161
- ...OPENAI_RULES, label: 'gpt-image-1', image: true,
164
+ [GPT_IMAGE_15]: {
165
+ ...OPENAI_RULES, image: true, defaultProvider: OPENAI,
166
+ supportedMimeTypes: [MIME_PNG, MIME_JPEG, MIME_GIF, MIME_WEBP],
162
167
  },
163
168
  // models with code capabilities
164
169
  [GPT_51_CODEX]: { ...OPENAI_RULES },
@@ -996,11 +1001,23 @@ const promptGoogle = async (aiId, prompt, options = {}) => {
996
1001
  const target_model = options?.model || model.name;
997
1002
  const M = MODELS[target_model];
998
1003
  prompt = ensureString(prompt, { trim: true });
1004
+ // M.name === IMAGEN_4_ULTRA ||
999
1005
  assertPrompt(prompt);
1000
1006
  M.tts && (prompt = `${options?.prompt || TTS_PROMPT}: ${prompt}`);
1001
1007
  prompt = trimText(prompt, { limit: M.maxInputTokens });
1002
1008
  if (M?.image) {
1003
- var resp = await client.models.generateImages({
1009
+ var resp;
1010
+ // if (M.name === IMAGEN_4_ULTRA) {
1011
+ // resp = await client.models.upscaleImage({
1012
+ // model: M.name, prompt, config: mergeAtoB(options?.config, {
1013
+ // numberOfImages: options?.n || 4, sampleImageSize: '2K',
1014
+ // includeRaiReason: true,
1015
+ // // "1:1" (default), "3:4", "4:3", "9:16", and "16:9"
1016
+ // aspectRatio: '16:9', personGeneration: 'allow_adult',
1017
+ // }),
1018
+ // });
1019
+ // } else {
1020
+ resp = await client.models.generateImages({
1004
1021
  model: M.name, prompt, config: mergeAtoB(options?.config, {
1005
1022
  numberOfImages: options?.n || 4, sampleImageSize: '2K',
1006
1023
  includeRaiReason: true,
@@ -1008,6 +1025,7 @@ const promptGoogle = async (aiId, prompt, options = {}) => {
1008
1025
  aspectRatio: '16:9', personGeneration: 'allow_adult',
1009
1026
  }),
1010
1027
  });
1028
+ // }
1011
1029
  var generated = resp?.generatedImages;
1012
1030
  assert(!resp?.error && generated?.filter(
1013
1031
  x => !x.raiFilteredReason
@@ -1113,7 +1131,40 @@ const promptOpenAI = async (aiId, prompt, options = {}) => {
1113
1131
  const target_model = options?.model || model.name;
1114
1132
  const M = MODELS[target_model];
1115
1133
  prompt = ensureString(prompt, { trim: true });
1116
- if (M?.audio) {
1134
+ if (M?.image) {
1135
+ assertPrompt(prompt);
1136
+ prompt = trimText(prompt, { limit: M.maxInputTokens });
1137
+ var resp = await client.images.generate({
1138
+ model: M.name, moderation: 'low', output_format: 'png',
1139
+ prompt, quality: 'high', size: '1536x1024',
1140
+ // n = 1, // 1 ~ 10
1141
+ // @TODO: 支持 streaming image generation
1142
+ // https://platform.openai.com/docs/guides/image-generation?api=responses
1143
+ // partial_images: 3, stream: true,
1144
+ // @TODO: 支持 image editing {}
1145
+ ...options?.params || {},
1146
+ });
1147
+ if (!options?.raw) {
1148
+ // print(resp);
1149
+ resp = {
1150
+ text: '', images: await Promise.all(resp.data.map(
1151
+ async (x, i) => {
1152
+ const buffer = await convert(
1153
+ x.b64_json, { input: BASE64 }
1154
+ );
1155
+ return {
1156
+ data: await convert(buffer, {
1157
+ input: BUFFER, suffix: PNG_EXT, ...options || {}
1158
+ }),
1159
+ mimeType: (await getMime(
1160
+ buffer, `${i}.${resp.output_format}`
1161
+ ))?.mime || MIME_PNG,
1162
+ }
1163
+ })
1164
+ ), model: packModelId([provider, M.source, M.name]),
1165
+ };
1166
+ }
1167
+ } else if (M?.audio) {
1117
1168
  assertPrompt(prompt);
1118
1169
  const ins_prompt = options?.prompt || `${TTS_PROMPT}.`;
1119
1170
  prompt = trimText(prompt, {
@@ -1506,7 +1557,7 @@ export {
1506
1557
  GEMINI_30_FLASH,
1507
1558
  GEMINI_25_PRO_TTS,
1508
1559
  GEMINI_30_PRO_IMAGE,
1509
- GPT_5_IMAGE,
1560
+ GPT_IMAGE_15,
1510
1561
  GPT_52,
1511
1562
  IMAGEN_4_ULTRA,
1512
1563
  INSTRUCTIONS,
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": "2001.1.84",
4
+ "version": "2001.1.86",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",
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": "2001.1.84",
4
+ "version": "2001.1.86",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",