Initial commit with translated description

This commit is contained in:
2026-03-29 09:46:52 +08:00
commit bff465f5c6
5 changed files with 332 additions and 0 deletions

100
SKILL.md Normal file
View 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
View File

@@ -0,0 +1,6 @@
{
"ownerId": "kn7akgt520t01vgs2tzx7yk6m180kt26",
"slug": "ai-picture-book",
"version": "1.1.0",
"publishedAt": 1770956044079
}

View 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()

View 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)

View 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)