utilitas 1999.1.56 → 1999.1.58
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 +2 -1
- package/dist/utilitas.lite.mjs +1 -1
- package/dist/utilitas.lite.mjs.map +1 -1
- package/lib/gen.mjs +38 -25
- package/lib/manifest.mjs +1 -1
- package/lib/shell.mjs +5 -3
- package/lib/utilitas.mjs +6 -2
- package/package.json +1 -1
package/lib/gen.mjs
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
ensureString, log as _log, need, throwError, tryUntil,
|
|
3
|
+
} from './utilitas.mjs';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
import { convert, MIME_PNG } from './storage.mjs';
|
|
6
|
+
import { assertCommand, exec } from './shell.mjs';
|
|
5
7
|
|
|
8
|
+
const _NEED = ['OpenAI'];
|
|
9
|
+
const log = (cnt, opt) => _log(cnt, import.meta.url, { time: 1, ...opt || {} });
|
|
6
10
|
const [
|
|
7
11
|
clients, OPENAI, GEMINI, BASE64, BUFFER, ERROR_GENERATING, IMAGEN_MODEL,
|
|
8
12
|
OPENAI_MODEL, VEO_MODEL,
|
|
@@ -13,8 +17,8 @@ const [
|
|
|
13
17
|
|
|
14
18
|
const init = async (options) => {
|
|
15
19
|
assert(
|
|
16
|
-
options?.apiKey || (options?.
|
|
17
|
-
'API key or
|
|
20
|
+
options?.apiKey || (options?.credentials && options?.projectId),
|
|
21
|
+
'API key or credentials are required.'
|
|
18
22
|
);
|
|
19
23
|
const provider = ensureString(options?.provider, { case: 'UP' });
|
|
20
24
|
switch (provider) {
|
|
@@ -27,7 +31,7 @@ const init = async (options) => {
|
|
|
27
31
|
clients[provider] = {
|
|
28
32
|
apiKey: options.apiKey,
|
|
29
33
|
projectId: options.projectId,
|
|
30
|
-
|
|
34
|
+
credentials: options.credentials,
|
|
31
35
|
};
|
|
32
36
|
break;
|
|
33
37
|
default:
|
|
@@ -46,7 +50,7 @@ const extractVideo = async (data, options) => await convert(
|
|
|
46
50
|
|
|
47
51
|
const generateImage = async (prompt, options) => {
|
|
48
52
|
let provider = ensureString(options?.provider, { case: 'UP' });
|
|
49
|
-
if (!provider && clients?.[GEMINI]
|
|
53
|
+
if (!provider && clients?.[GEMINI]?.apiKey) { provider = GEMINI; }
|
|
50
54
|
if (!provider && clients?.[OPENAI]) { provider = OPENAI; }
|
|
51
55
|
const client = clients?.[provider];
|
|
52
56
|
const n = options?.n || 4;
|
|
@@ -105,7 +109,20 @@ const generateImage = async (prompt, options) => {
|
|
|
105
109
|
}
|
|
106
110
|
};
|
|
107
111
|
|
|
108
|
-
const
|
|
112
|
+
const getGeminiAccessToken = async (credentials) => {
|
|
113
|
+
await assertCommand('gcloud');
|
|
114
|
+
const actResp = await exec(
|
|
115
|
+
`gcloud auth activate-service-account --key-file=${credentials}`,
|
|
116
|
+
{ acceptError: true }
|
|
117
|
+
);
|
|
118
|
+
assert(actResp.includes('Activated service account credentials'),
|
|
119
|
+
'Failed to activate service account credentials.', 500);
|
|
120
|
+
const tokResp = (await exec(`gcloud auth print-access-token`)).trim();
|
|
121
|
+
assert(tokResp, 'Failed to get access token.', 500);
|
|
122
|
+
return tokResp;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const getGeminiVideo = async (jobId, accessToken) => {
|
|
109
126
|
const client = clients?.[GEMINI];
|
|
110
127
|
assert(client, 'No available video generation provider.');
|
|
111
128
|
const resp = await (await fetch(
|
|
@@ -114,26 +131,23 @@ const getGeminiVideo = async (jobId) => {
|
|
|
114
131
|
+ `${VEO_MODEL}:fetchPredictOperation`, {
|
|
115
132
|
method: 'POST', headers: {
|
|
116
133
|
'Content-Type': 'application/json',
|
|
117
|
-
'Authorization': `Bearer ${
|
|
118
|
-
},
|
|
119
|
-
body: JSON.stringify({
|
|
120
|
-
operationName: jobId,
|
|
121
|
-
})
|
|
134
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
135
|
+
}, body: JSON.stringify({ operationName: jobId })
|
|
122
136
|
})).json();
|
|
123
|
-
assert(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
);
|
|
137
|
+
assert(resp?.response?.videos?.length,
|
|
138
|
+
'Waiting for Gemini video generation: '
|
|
139
|
+
+ jobId.replace(/^.*\/([^/]+)$/, '$1'));
|
|
127
140
|
return resp?.response?.videos;
|
|
128
141
|
};
|
|
129
142
|
|
|
130
143
|
const generateVideo = async (prompt, options) => {
|
|
131
144
|
let provider = ensureString(options?.provider, { case: 'UP' });
|
|
132
|
-
if (!provider
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
if (!provider
|
|
146
|
+
&& clients?.[GEMINI]?.credentials
|
|
147
|
+
&& clients?.[GEMINI]?.projectId) { provider = GEMINI; }
|
|
135
148
|
const client = clients?.[provider];
|
|
136
149
|
assert(client, 'No available video generation provider.');
|
|
150
|
+
const accessToken = await getGeminiAccessToken(client.credentials);
|
|
137
151
|
prompt = ensureString(prompt);
|
|
138
152
|
assert(prompt.length <= 4000,
|
|
139
153
|
'Prompt must be less than 4000 characters.', 400);
|
|
@@ -149,7 +163,7 @@ const generateVideo = async (prompt, options) => {
|
|
|
149
163
|
+ `models/${VEO_MODEL}:predictLongRunning`, {
|
|
150
164
|
method: 'POST', headers: {
|
|
151
165
|
'Content-Type': 'application/json',
|
|
152
|
-
'Authorization': `Bearer ${
|
|
166
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
153
167
|
},
|
|
154
168
|
body: JSON.stringify({
|
|
155
169
|
instances: [{ prompt }], parameters: {
|
|
@@ -166,10 +180,9 @@ const generateVideo = async (prompt, options) => {
|
|
|
166
180
|
resp?.error?.message || ERROR_GENERATING
|
|
167
181
|
);
|
|
168
182
|
if (options?.generateRaw) { return resp; }
|
|
169
|
-
var videos = await tryUntil(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
);
|
|
183
|
+
var videos = await tryUntil(async () => await getGeminiVideo(
|
|
184
|
+
resp.name, accessToken
|
|
185
|
+
), { maxTry: 60 * 10, log });
|
|
173
186
|
assert(videos?.length, 'Failed to generate Gemini video.');
|
|
174
187
|
if (options?.videoRaw) { return videos; }
|
|
175
188
|
return await Promise.all(videos.map(async x => ({
|
package/lib/manifest.mjs
CHANGED
package/lib/shell.mjs
CHANGED
|
@@ -11,8 +11,10 @@ const exist = (bin) => { assertCommand(bin); return which(bin); };
|
|
|
11
11
|
const exec = async (command, options = {}) => {
|
|
12
12
|
assertCommand(command);
|
|
13
13
|
const { stdout, stderr } = await pmsExec(command);
|
|
14
|
-
assert(!stderr, stderr, 500);
|
|
15
|
-
return
|
|
14
|
+
assert(options?.acceptError || !stderr, stderr, 500);
|
|
15
|
+
return options?.acceptError
|
|
16
|
+
? [stdout, stderr].map(x => x.trim()).filter(x => x).join('\n')
|
|
17
|
+
: stdout.trim();
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
const which = async (bin) => {
|
|
@@ -28,4 +30,4 @@ const assertExist = async (bin, er, code = 500) => {
|
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
export default exec;
|
|
31
|
-
export { assertExist, exec, exist, which };
|
|
33
|
+
export { assertCommand, assertExist, exec, exist, which };
|
package/lib/utilitas.mjs
CHANGED
|
@@ -394,6 +394,7 @@ const log = (content, filename, options) => {
|
|
|
394
394
|
const args = ['[' + color.red(name) + color.yellow(strTime) + ']'
|
|
395
395
|
+ (isErr ? '' : ` ${content}`)];
|
|
396
396
|
if (isErr) { args.push(content); }
|
|
397
|
+
if (options?.return) { return args[0]; }
|
|
397
398
|
return console.info.apply(null, args);
|
|
398
399
|
};
|
|
399
400
|
|
|
@@ -669,12 +670,15 @@ const tryUntil = async (fnTry, options) => {
|
|
|
669
670
|
interval: 1000 * 1, maxTry: Infinity, log: false, error: 'Operation failed.',
|
|
670
671
|
verify: async (err, res) => { return !err; }, ...options || {}
|
|
671
672
|
};
|
|
672
|
-
let [curTry, result, err] = [0, null, null];
|
|
673
|
+
let [curTry, result, err, msg] = [0, null, null, null];
|
|
673
674
|
do {
|
|
674
675
|
try {
|
|
675
676
|
assert(await options.verify((err = null), (result = await fnTry())), options.error);
|
|
676
677
|
} catch (e) {
|
|
677
|
-
(err = e) &&
|
|
678
|
+
(err = e) && (msg = err?.message || err) && (
|
|
679
|
+
Function.isFunction(options?.log)
|
|
680
|
+
? await options.log(msg) : console.log(msg)
|
|
681
|
+
);
|
|
678
682
|
await timeout(options.interval);
|
|
679
683
|
}
|
|
680
684
|
} while (++curTry < options.maxTry && err)
|