@xuda.io/ai_module 1.1.5633 → 1.1.5634
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/index.mjs +57 -0
- package/index_ms.mjs +4 -0
- package/index_msa.mjs +4 -0
- package/package.json +5 -2
package/index.mjs
CHANGED
|
@@ -8638,6 +8638,63 @@ export const create_avatar = async function (req, job_id, headers) {
|
|
|
8638
8638
|
}
|
|
8639
8639
|
};
|
|
8640
8640
|
|
|
8641
|
+
// generate_login_screen: paid-plan alternative to uploading — AI-generate a
|
|
8642
|
+
// full-bleed landscape login background from a text prompt. Credit-gated like
|
|
8643
|
+
// avatar generation (create_image records usage). The PNG render is re-encoded to
|
|
8644
|
+
// WebP to satisfy the 5 MB spec, then handed to the shared drive writer over the
|
|
8645
|
+
// drive_module queue so it is persisted + served publicly exactly like an upload.
|
|
8646
|
+
export const generate_login_screen = async function (req, job_id, headers = {}) {
|
|
8647
|
+
const { uid, prompt } = req;
|
|
8648
|
+
const tempDir = os.tmpdir();
|
|
8649
|
+
const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
|
|
8650
|
+
const tempOutputPath = path.join(tempDir, `login_screen_${uniqueId}.webp`);
|
|
8651
|
+
try {
|
|
8652
|
+
if (!uid) throw new Error('not authorized (no uid)');
|
|
8653
|
+
if (!prompt || typeof prompt !== 'string' || !prompt.trim()) throw new Error('a prompt is required');
|
|
8654
|
+
|
|
8655
|
+
const account_profile_info = await get_active_account_profile_info(uid);
|
|
8656
|
+
|
|
8657
|
+
// credits: validate_credits_limit RETURNS an Error object when over the hard limit
|
|
8658
|
+
const credit_err = await validate_credits_limit(uid);
|
|
8659
|
+
if (credit_err) return { code: -25, data: 'AI credits reached the hard limit' };
|
|
8660
|
+
|
|
8661
|
+
const wrapped_prompt = `Create a full-bleed, decorative LANDSCAPE background image for a login screen. Subject/style: ${prompt.trim()}. It must contain no text, letters, logos, watermarks, UI elements, or human faces; use a cohesive, calm color palette with soft contrast so a login form stays readable on top. Fill the whole frame edge to edge.`;
|
|
8662
|
+
|
|
8663
|
+
// gpt-image landscape render; quality 'low' is fine for a decorative background.
|
|
8664
|
+
const base64 = await create_image(uid, wrapped_prompt, 'gpt-image-1-mini', '1536x1024', 1, 1536, 1024, { purpose: 'login_screen' }, account_profile_info, 'low');
|
|
8665
|
+
if (!base64) throw new Error('image generation failed');
|
|
8666
|
+
|
|
8667
|
+
// create_image emits PNG; re-encode to WebP to stay well under the 5 MB spec.
|
|
8668
|
+
const webp = await sharp(Buffer.from(base64, 'base64')).webp({ quality: 82 }).toBuffer();
|
|
8669
|
+
await fs.promises.writeFile(tempOutputPath, webp);
|
|
8670
|
+
|
|
8671
|
+
const file_obj = { originalname: 'login_screen.webp', path: tempOutputPath, mimetype: 'image/webp' };
|
|
8672
|
+
const store_ret = await drive_ms.store_login_screen_from_path(uid, file_obj, job_id, headers);
|
|
8673
|
+
if (store_ret.code !== 1) return store_ret;
|
|
8674
|
+
|
|
8675
|
+
const o = store_ret.data.login_screen_obj;
|
|
8676
|
+
return {
|
|
8677
|
+
code: 1,
|
|
8678
|
+
data: {
|
|
8679
|
+
login_screen: {
|
|
8680
|
+
source: 'personal',
|
|
8681
|
+
media_type: 'image',
|
|
8682
|
+
file_url: o.file_url,
|
|
8683
|
+
w: o.w,
|
|
8684
|
+
h: o.h,
|
|
8685
|
+
bytes: o.bytes,
|
|
8686
|
+
uploaded_ts: o.uploaded_ts,
|
|
8687
|
+
},
|
|
8688
|
+
},
|
|
8689
|
+
};
|
|
8690
|
+
} catch (err) {
|
|
8691
|
+
try {
|
|
8692
|
+
await fs.promises.unlink(tempOutputPath);
|
|
8693
|
+
} catch (e) {}
|
|
8694
|
+
return { code: -25, data: err.message };
|
|
8695
|
+
}
|
|
8696
|
+
};
|
|
8697
|
+
|
|
8641
8698
|
export const get_profile_avatar = async function (profile_picture, uid, prompt, account_profile_info, account_type, docType = 'account', _id, metadata = {}, business_size = 'unknown', name, email, job_id, headers) {
|
|
8642
8699
|
const tempDir = os.tmpdir();
|
|
8643
8700
|
const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
|
package/index_ms.mjs
CHANGED
|
@@ -157,6 +157,10 @@ export const create_avatar = async function (...args) {
|
|
|
157
157
|
return await broker.send_to_queue("create_avatar", ...args);
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
+
export const generate_login_screen = async function (...args) {
|
|
161
|
+
return await broker.send_to_queue("generate_login_screen", ...args);
|
|
162
|
+
};
|
|
163
|
+
|
|
160
164
|
export const get_profile_avatar = async function (...args) {
|
|
161
165
|
return await broker.send_to_queue("get_profile_avatar", ...args);
|
|
162
166
|
};
|
package/index_msa.mjs
CHANGED
|
@@ -157,6 +157,10 @@ export const create_avatar = function (...args) {
|
|
|
157
157
|
broker.send_to_queue_async("create_avatar", ...args);
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
+
export const generate_login_screen = function (...args) {
|
|
161
|
+
broker.send_to_queue_async("generate_login_screen", ...args);
|
|
162
|
+
};
|
|
163
|
+
|
|
160
164
|
export const get_profile_avatar = function (...args) {
|
|
161
165
|
broker.send_to_queue_async("get_profile_avatar", ...args);
|
|
162
166
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xuda.io/ai_module",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5634",
|
|
4
4
|
"description": "Xuda AI Module",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -31,5 +31,8 @@
|
|
|
31
31
|
"test:codex": "node tests/execute-codex-request.mjs"
|
|
32
32
|
},
|
|
33
33
|
"author": "Xuda Llc",
|
|
34
|
-
"license": "ISC"
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "restricted"
|
|
37
|
+
}
|
|
35
38
|
}
|