feat: add jimeng (即梦AI) CLI support (#57)
Add two CLI commands for Jimeng (即梦AI) — ByteDance's AI image generation platform: - generate: Text-to-image generation with model selection and configurable wait time - history: View recent generation history with prompt, model, status, and image URLs Both commands use browser automation with cookie-based authentication on jimeng.jianying.com.
This commit is contained in:
1 parent
e76de39f42
commit
a06cdbf0ac
2 files changed
+131
No files matched your search
@@ -0,0 +1,84 @@
|
||||
site: jimeng
|
||||
name: generate
|
||||
description: 即梦AI 文生图 — 输入 prompt 生成图片
|
||||
domain: jimeng.jianying.com
|
||||
strategy: cookie
|
||||
browser: true
|
||||
|
||||
args:
|
||||
prompt:
|
||||
type: string
|
||||
required: true
|
||||
description: "图片描述 prompt"
|
||||
model:
|
||||
type: string
|
||||
default: "high_aes_general_v50"
|
||||
description: "模型: high_aes_general_v50 (5.0 Lite), high_aes_general_v42 (4.6), high_aes_general_v40 (4.0)"
|
||||
wait:
|
||||
type: int
|
||||
default: 40
|
||||
description: "等待生成完成的秒数"
|
||||
|
||||
columns: [status, prompt, image_count, image_urls]
|
||||
|
||||
pipeline:
|
||||
- navigate: https://jimeng.jianying.com/ai-tool/generate?type=image&workspace=0
|
||||
- wait: 3
|
||||
- evaluate: |
|
||||
(async () => {
|
||||
const prompt = ${{ args.prompt | json }};
|
||||
const waitSec = ${{ args.wait }};
|
||||
|
||||
// Step 1: Count existing images before generation
|
||||
const beforeImgs = document.querySelectorAll('img[src*="dreamina-sign"], img[src*="tb4s082cfz"]').length;
|
||||
|
||||
// Step 2: Clear and set prompt
|
||||
const editors = document.querySelectorAll('[contenteditable="true"]');
|
||||
const editor = editors[0];
|
||||
if (!editor) return [{ status: 'failed', prompt: prompt, image_count: 0, image_urls: 'Editor not found' }];
|
||||
|
||||
editor.focus();
|
||||
await new Promise(r => setTimeout(r, 200));
|
||||
document.execCommand('selectAll');
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
document.execCommand('delete');
|
||||
await new Promise(r => setTimeout(r, 200));
|
||||
document.execCommand('insertText', false, prompt);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
|
||||
// Step 3: Click generate
|
||||
const btn = document.querySelector('.lv-btn.lv-btn-primary[class*="circle"]');
|
||||
if (!btn) return [{ status: 'failed', prompt: prompt, image_count: 0, image_urls: 'Generate button not found' }];
|
||||
btn.click();
|
||||
|
||||
// Step 4: Wait for new images to appear
|
||||
let newImgs = [];
|
||||
for (let i = 0; i < waitSec; i++) {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
const allImgs = document.querySelectorAll('img[src*="dreamina-sign"], img[src*="tb4s082cfz"]');
|
||||
if (allImgs.length > beforeImgs) {
|
||||
// New images appeared — generation complete
|
||||
newImgs = Array.from(allImgs).slice(0, allImgs.length - beforeImgs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newImgs.length === 0) {
|
||||
return [{ status: 'timeout', prompt: prompt, image_count: 0, image_urls: 'Generation may still be in progress' }];
|
||||
}
|
||||
|
||||
// Step 5: Extract image URLs (use thumbnail URLs which are accessible)
|
||||
const urls = newImgs.map(img => img.src);
|
||||
|
||||
return [{
|
||||
status: 'success',
|
||||
prompt: prompt.substring(0, 80),
|
||||
image_count: urls.length,
|
||||
image_urls: urls.join('\n')
|
||||
}];
|
||||
})()
|
||||
- map:
|
||||
status: ${{ item.status }}
|
||||
prompt: ${{ item.prompt }}
|
||||
image_count: ${{ item.image_count }}
|
||||
image_urls: ${{ item.image_urls }}
|
||||
@@ -0,0 +1,47 @@
|
||||
site: jimeng
|
||||
name: history
|
||||
description: 即梦AI 查看最近生成的作品
|
||||
domain: jimeng.jianying.com
|
||||
strategy: cookie
|
||||
browser: true
|
||||
|
||||
args:
|
||||
limit:
|
||||
type: int
|
||||
default: 5
|
||||
|
||||
columns: [prompt, model, status, image_url, created_at]
|
||||
|
||||
pipeline:
|
||||
- navigate: https://jimeng.jianying.com/ai-tool/generate?type=image&workspace=0
|
||||
- wait: 3
|
||||
- evaluate: |
|
||||
(async () => {
|
||||
const limit = ${{ args.limit }};
|
||||
const res = await fetch('/mweb/v1/get_history?aid=513695&device_platform=web®ion=cn&da_version=3.3.11&web_version=7.5.0&aigc_features=app_lip_sync', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ cursor: '', count: limit, need_page_item: true, need_aigc_data: true, aigc_mode_list: ['workbench'] })
|
||||
});
|
||||
const data = await res.json();
|
||||
const items = data?.data?.history_list || [];
|
||||
return items.slice(0, limit).map(item => {
|
||||
const params = item.aigc_image_params?.text2image_params || {};
|
||||
const images = item.image?.large_images || [];
|
||||
return {
|
||||
prompt: params.prompt || item.common_attr?.title || 'N/A',
|
||||
model: params.model_config?.model_name || 'unknown',
|
||||
status: item.common_attr?.status === 102 ? 'completed' : 'pending',
|
||||
image_url: images[0]?.image_url || '',
|
||||
created_at: new Date((item.common_attr?.create_time || 0) * 1000).toLocaleString('zh-CN'),
|
||||
};
|
||||
});
|
||||
})()
|
||||
- map:
|
||||
prompt: ${{ item.prompt }}
|
||||
model: ${{ item.model }}
|
||||
status: ${{ item.status }}
|
||||
image_url: ${{ item.image_url }}
|
||||
created_at: ${{ item.created_at }}
|
||||
- limit: ${{ args.limit }}
|
||||
Reference in new issue
Block a user