Initial commit with translated description
This commit is contained in:
100
SKILL.md
Normal file
100
SKILL.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
name: ai-picture-book
|
||||
description: "使用百度AI生成静态或动态绘本视频。"
|
||||
metadata: { "openclaw": { "emoji": "📔", "requires": { "bins": ["python3"], "env":["BAIDU_API_KEY"]},"primaryEnv":"BAIDU_API_KEY" } }
|
||||
---
|
||||
|
||||
# AI Picture Book
|
||||
|
||||
Generate picture book videos from stories or descriptions.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Create Task**: Submit story + type → get task ID
|
||||
2. **Poll Status**: Query every 5-10s until completion
|
||||
3. **Get Results**: Retrieve video URLs when status = 2
|
||||
|
||||
## Book Types
|
||||
|
||||
| Type | Method | Description |
|
||||
|------|--------|-------------|
|
||||
| Static | 9 | Static picture book |
|
||||
| Dynamic | 10 | Dynamic picture book |
|
||||
|
||||
**Required**: User must specify type (static/9 or dynamic/10). If not provided, ask them to choose.
|
||||
|
||||
## Status Codes
|
||||
|
||||
| Code | Status | Action |
|
||||
|-------|---------|---------|
|
||||
| 0, 1, 3 | In Progress | Continue polling |
|
||||
| 2 | Completed | Return results |
|
||||
| Other | Failed | Show error |
|
||||
|
||||
## APIs
|
||||
|
||||
### Create Task
|
||||
|
||||
**Endpoint**: `POST /v2/tools/ai_picture_book/task_create`
|
||||
|
||||
**Parameters**:
|
||||
- `method` (required): `9` for static, `10` for dynamic
|
||||
- `content` (required): Story or description
|
||||
|
||||
**Example**:
|
||||
```bash
|
||||
python3 scripts/ai_picture_book_task_create.py 9 "A brave cat explores the world."
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{ "task_id": "uuid-string" }
|
||||
```
|
||||
|
||||
### Query Task
|
||||
|
||||
**Endpoint**: `GET /v2/tools/ai_picture_book/query`
|
||||
|
||||
**Parameters**:
|
||||
- `task_id` (required): Task ID from create endpoint
|
||||
|
||||
**Example**:
|
||||
```bash
|
||||
python3 scripts/ai_picture_book_task_query.py "task-id-here"
|
||||
```
|
||||
|
||||
**Response** (Completed):
|
||||
```json
|
||||
{
|
||||
"status": 2,
|
||||
"video_bos_url": "https://...",
|
||||
}
|
||||
```
|
||||
|
||||
## Polling Strategy
|
||||
|
||||
### Auto Polling (Recommended)
|
||||
```bash
|
||||
python3 scripts/ai_picture_book_poll.py <task_id> [max_attempts] [interval_seconds]
|
||||
```
|
||||
|
||||
**Examples**:
|
||||
```bash
|
||||
# Default: 20 attempts, 5s intervals
|
||||
python3 scripts/ai_picture_book_poll.py "task-id-here"
|
||||
|
||||
# Custom: 30 attempts, 10s intervals
|
||||
python3 scripts/ai_picture_book_poll.py "task-id-here" 30 10
|
||||
```
|
||||
|
||||
### Manual Polling
|
||||
1. Create task → store `task_id`
|
||||
2. Query every 5-10s until status = 2
|
||||
3. Timeout after 2-3 minutes
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Invalid content: "Content cannot be empty"
|
||||
- Invalid type: "Invalid type. Use 9 (static) or 10 (dynamic)"
|
||||
- Processing error: "Failed to generate picture book"
|
||||
- Timeout: "Task timed out. Try again later"
|
||||
6
_meta.json
Normal file
6
_meta.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ownerId": "kn7akgt520t01vgs2tzx7yk6m180kt26",
|
||||
"slug": "ai-picture-book",
|
||||
"version": "1.1.0",
|
||||
"publishedAt": 1770956044079
|
||||
}
|
||||
125
scripts/ai_picture_book_poll.py
Normal file
125
scripts/ai_picture_book_poll.py
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Picture Book - Poll Task
|
||||
Automatically poll task until completion with progress updates.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
from typing import Dict, Any
|
||||
|
||||
STATUS_CODES = {
|
||||
0: "in_progress",
|
||||
1: "in_progress",
|
||||
2: "completed",
|
||||
3: "in_progress",
|
||||
}
|
||||
|
||||
|
||||
def query_task(api_key: str, task_id: str) -> Dict[str, Any]:
|
||||
"""Query task status."""
|
||||
url = "https://qianfan.baidubce.com/v2/tools/ai_picture_book/query"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"X-Appbuilder-From": "openclaw",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
params = {"task_ids": [task_id]}
|
||||
|
||||
response = requests.post(url, headers=headers, json=params, timeout=5)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
if "errno" in result and result["errno"] != 0:
|
||||
raise RuntimeError(result.get("errmsg", "Unknown error"))
|
||||
|
||||
return result["data"]
|
||||
|
||||
|
||||
def poll_task(api_key: str, task_id: str, max_attempts: int = 20, interval: int = 5):
|
||||
"""Poll task until completion or timeout.
|
||||
|
||||
Args:
|
||||
api_key: Baidu API key
|
||||
task_id: Task ID
|
||||
max_attempts: Maximum poll attempts (default 20)
|
||||
interval: Seconds between polls (default 5)
|
||||
|
||||
Returns:
|
||||
Final task data
|
||||
"""
|
||||
data = None
|
||||
for attempt in range(max_attempts):
|
||||
try:
|
||||
data = query_task(api_key, task_id)
|
||||
if not data or len(data) == 0:
|
||||
print(f"\n✗ No task data returned")
|
||||
return data
|
||||
|
||||
status = data[0].get("status")
|
||||
result = data[0].get("result", {})
|
||||
if result and "video_bos_url" in result:
|
||||
result = {"video_bos_url": result["video_bos_url"]}
|
||||
|
||||
if status == 2:
|
||||
print("\n" + "=" * 50)
|
||||
print("✓ PICTURE BOOK GENERATED SUCCESSFULLY")
|
||||
print("=" * 50)
|
||||
print(json.dumps(result, indent=2, ensure_ascii=False))
|
||||
return data
|
||||
|
||||
elif status in [0, 1, 3]:
|
||||
print(f"[{attempt + 1}/{max_attempts}] Processing...")
|
||||
time.sleep(interval)
|
||||
|
||||
else:
|
||||
print(f"\n✗ Task failed: status={status}")
|
||||
print(json.dumps(data, indent=2, ensure_ascii=False))
|
||||
return data
|
||||
|
||||
except RuntimeError as e:
|
||||
print(f"\n✗ Error: {str(e)}")
|
||||
return data
|
||||
except Exception as e:
|
||||
if attempt == max_attempts - 1:
|
||||
print(f"\n✗ Unexpected error: {str(e)}")
|
||||
return data
|
||||
time.sleep(interval)
|
||||
|
||||
print(f"\n✗ Timeout after {max_attempts * interval} seconds")
|
||||
print("Task may still be running. Try querying manually:")
|
||||
print(f" python scripts/ai_picture_book_task_query.py {task_id}")
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print(json.dumps({
|
||||
"error": "Missing task ID",
|
||||
"usage": "python ai_picture_book_poll.py <task_id> [max_attempts] [interval_seconds]"
|
||||
}, indent=2))
|
||||
sys.exit(1)
|
||||
|
||||
task_id = sys.argv[1]
|
||||
max_attempts = int(sys.argv[2]) if len(sys.argv) > 2 else 20
|
||||
interval = int(sys.argv[3]) if len(sys.argv) > 3 else 5
|
||||
|
||||
api_key = os.getenv("BAIDU_API_KEY")
|
||||
if not api_key:
|
||||
print(json.dumps({
|
||||
"error": "BAIDU_API_KEY environment variable not set"
|
||||
}, indent=2))
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Polling task: {task_id}")
|
||||
print(f"Max attempts: {max_attempts}, Interval: {interval}s")
|
||||
print("-" * 50)
|
||||
|
||||
poll_task(api_key, task_id, max_attempts, interval)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
49
scripts/ai_picture_book_task_create.py
Normal file
49
scripts/ai_picture_book_task_create.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import os
|
||||
import sys
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
def ai_picture_book_task_create(api_key: str, method: int, content):
|
||||
url = "https://qianfan.baidubce.com/v2/tools/ai_picture_book/task_create"
|
||||
headers = {
|
||||
"Authorization": "Bearer %s" % api_key,
|
||||
"X-Appbuilder-From": "openclaw",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
params = {
|
||||
"method": method,
|
||||
"input_type": "1",
|
||||
"input_content": content,
|
||||
}
|
||||
response = requests.post(url, headers=headers, json=params)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
if "code" in result:
|
||||
raise RuntimeError(result["detail"])
|
||||
if "errno" in result and result["errno"] != 0:
|
||||
raise RuntimeError(result["errmsg"])
|
||||
return result["data"]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python ai_picture_book_task_create.py <method> <content>")
|
||||
sys.exit(1)
|
||||
|
||||
method = int(sys.argv[1])
|
||||
if method not in [9, 10]:
|
||||
print("Error: method must be 9 or 10.")
|
||||
sys.exit(1)
|
||||
content = sys.argv[2]
|
||||
|
||||
api_key = os.getenv("BAIDU_API_KEY")
|
||||
if not api_key:
|
||||
print("Error: BAIDU_API_KEY must be set in environment.")
|
||||
sys.exit(1)
|
||||
try:
|
||||
results = ai_picture_book_task_create(api_key, method, content)
|
||||
print(json.dumps(results, ensure_ascii=False, indent=2))
|
||||
except Exception as e:
|
||||
print(f"Error: {str(e)}")
|
||||
sys.exit(1)
|
||||
52
scripts/ai_picture_book_task_query.py
Normal file
52
scripts/ai_picture_book_task_query.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import os
|
||||
import sys
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
def ai_picture_book_task_query(api_key: str, task_id: str):
|
||||
url = "https://qianfan.baidubce.com/v2/tools/ai_picture_book/query"
|
||||
headers = {
|
||||
"Authorization": "Bearer %s" % api_key,
|
||||
"X-Appbuilder-From": "openclaw",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
task_ids = task_id.split(",")
|
||||
params = {
|
||||
"task_ids": task_ids,
|
||||
}
|
||||
response = requests.post(url, headers=headers, json=params)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
datas = []
|
||||
if "code" in result:
|
||||
raise RuntimeError(result["detail"])
|
||||
if "errno" in result and result["errno"] != 0:
|
||||
raise RuntimeError(result["errmsg"])
|
||||
if "data" in result and len(result["data"]) > 0:
|
||||
for item in result["data"]:
|
||||
if item["result"]:
|
||||
bosUrl = item["result"].get("video_bos_url", "")
|
||||
del item["result"]
|
||||
item["video_bos_url"] = bosUrl
|
||||
datas.append(item)
|
||||
return datas
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python ai_picture_book_task_query.py <task_ids>")
|
||||
sys.exit(1)
|
||||
|
||||
task_ids = sys.argv[1]
|
||||
|
||||
api_key = os.getenv("BAIDU_API_KEY")
|
||||
if not api_key:
|
||||
print("Error: BAIDU_API_KEY must be set in environment.")
|
||||
sys.exit(1)
|
||||
try:
|
||||
results = ai_picture_book_task_query(api_key, task_ids)
|
||||
print(json.dumps(results, ensure_ascii=False, indent=2))
|
||||
except Exception as e:
|
||||
print(f"Error: {str(e)}")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user