From 3cc0774858a14c23dfc1490d0214d506bc45d116 Mon Sep 17 00:00:00 2001 From: zlei9 Date: Sun, 29 Mar 2026 09:46:44 +0800 Subject: [PATCH] Initial commit with translated description --- SKILL.md | 117 ++++++++++++++++++++++++++++ _meta.json | 6 ++ scripts/ai_notes_poll.py | 133 ++++++++++++++++++++++++++++++++ scripts/ai_notes_task_create.py | 94 ++++++++++++++++++++++ scripts/ai_notes_task_query.py | 45 +++++++++++ 5 files changed, 395 insertions(+) create mode 100644 SKILL.md create mode 100644 _meta.json create mode 100644 scripts/ai_notes_poll.py create mode 100644 scripts/ai_notes_task_create.py create mode 100644 scripts/ai_notes_task_query.py diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..a6c4d13 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,117 @@ +--- +name: ai-notes-ofvideo +description: "从视频生成AI驱动的笔记(文档、大纲或图文格式)。" +metadata: { "openclaw": { "emoji": "📺", "requires": { "bins": ["python3"], "env":["BAIDU_API_KEY"]},"primaryEnv":"BAIDU_API_KEY" } } +--- + +# AI Video Notes + +Generate structured notes from video URLs using Baidu AI. Supports three note formats. + +## Workflow + +1. **Create Task**: Submit video URL → get task ID +2. **Poll Status**: Query task every 3-5 seconds until completion +3. **Get Results**: Retrieve generated notes when status = 10002 + +## Status Codes + +| Code | Status | Action | +|-------|---------|---------| +| 10000 | In Progress | Continue polling | +| 10002 | Completed | Return results | +| Other | Failed | Show error | + +## Note Types + +| Type | Description | +|------|-------------| +| 1 | Document notes | +| 2 | Outline notes | +| 3 | Graphic-text notes | + +## APIs + +### Create Task + +**Endpoint**: `POST /v2/tools/ai_note/task_create` + +**Parameters**: +- `video_url` (required): Public video URL + +**Example**: +```bash +python3 scripts/ai_notes_task_create.py 'https://example.com/video.mp4' +``` + +**Response**: +```json +{ + "task_id": "uuid-string" +} +``` + +### Query Task + +**Endpoint**: `GET /v2/tools/ai_note/query` + +**Parameters**: +- `task_id` (required): Task ID from create endpoint + +**Example**: +```bash +python3 scripts/ai_notes_task_query.py "task-id-here" +``` + +**Response** (Completed): +```json +{ + "status": 10002, + "notes": [ + { + "tpl_no": "1", + "contents: ["Note content..."] + } + ] +} +``` + +## Polling Strategy + +### Option 1: Manual Polling +1. Create task → store `task_id` +2. Query every 3-5 seconds: + ```bash + python3 scripts/ai_notes_task_query.py + ``` +3. Show progress updates: + - Status 10000: Processing... + - Status 10002: Completed +4. Stop after 30-60 seconds (video length dependent) + +### Option 2: Auto Polling (Recommended) +Use the polling script for automatic status updates: + +```bash +python3 scripts/ai_notes_poll.py [max_attempts] [interval_seconds] +``` + +**Examples**: +```bash +# Default: 20 attempts, 3-second intervals +python3 scripts/ai_notes_poll.py "task-id-here" + +# Custom: 30 attempts, 5-second intervals +python3 scripts/ai_notes_poll.py "task-id-here" 30 5 +``` + +**Output**: +- Shows real-time progress: `[1/20] Processing... 25%` +- Auto-stops when complete +- Returns formatted notes with type labels + +## Error Handling + +- Invalid URL: "Video URL not accessible" +- Processing error: "Failed to parse video" +- Timeout: "Video too long, try again later" diff --git a/_meta.json b/_meta.json new file mode 100644 index 0000000..afcfd44 --- /dev/null +++ b/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7akgt520t01vgs2tzx7yk6m180kt26", + "slug": "ai-notes-ofvideo", + "version": "1.1.0", + "publishedAt": 1770955841859 +} \ No newline at end of file diff --git a/scripts/ai_notes_poll.py b/scripts/ai_notes_poll.py new file mode 100644 index 0000000..ef89528 --- /dev/null +++ b/scripts/ai_notes_poll.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +""" +AI Video Notes - 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 = { + 10000: "processing", + 10002: "completed", +} + + +def query_task(api_key: str, task_id: str) -> Dict[str, Any]: + """Query task status.""" + url = "https://qianfan.baidubce.com/v2/tools/ai_note/query" + headers = { + "Authorization": f"Bearer {api_key}", + "X-Appbuilder-From": "openclaw", + "Content-Type": "application/json" + } + params = {"task_id": task_id} + + response = requests.get(url, headers=headers, params=params, timeout=30) + response.raise_for_status() + result = response.json() + return result + + +def poll_task(api_key: str, task_id: str, max_attempts: int = 20, interval: int = 3): + """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 3) + + Returns: + Final task data + """ + data = None + for attempt in range(max_attempts): + try: + data = query_task(api_key, task_id) + if "errno" in data and data["errno"] == 10000: + errno = data["errno"] + error_msg = data["show_msg"] + print(f"[{attempt + 1}/{max_attempts}] Processing...(task status code: {errno}, message: {error_msg})") + time.sleep(interval) + continue + if "errno" in data and data["errno"] != 0: + raise RuntimeError(data.get("show_msg", "Unknown error")) + data = data.get("data", {}) + aiNotesList = data.get("list", []) + status_code = 0 + for note in aiNotesList: + status_code = note.get("detail", {}).get("status", 0) + if status_code != 10002: + break + + if status_code == 10002: + notes = [] + for note in data.get("list", []): + tpl_no = note.get("tpl_no") + notes.append({ + "type": tpl_no, + "contents": note.get("detail", {}).get("contents", []) + }) + + print("\n" + "=" * 50) + print("✓ NOTES GENERATED SUCCESSFULLY") + print("=" * 50) + print(json.dumps(notes, indent=2, ensure_ascii=False)) + return data + + elif status_code == 10000: + print(f"[{attempt + 1}/{max_attempts}] Processing...") + time.sleep(interval) + continue + else: + print(f"\n✗ Task failed, with status code: {status_code}") + 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_notes_task_query.py {task_id}") + return data + + +def main(): + if len(sys.argv) < 2: + print(json.dumps({ + "error": "Missing task ID", + "usage": "python ai_notes_poll.py [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 3 + + 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() diff --git a/scripts/ai_notes_task_create.py b/scripts/ai_notes_task_create.py new file mode 100644 index 0000000..9d405e0 --- /dev/null +++ b/scripts/ai_notes_task_create.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +""" +AI Video Notes - Create Task +Submit a video URL for AI note generation. +""" + +import os +import sys +import json +import requests +from typing import Dict, Any + + +def create_note_task(api_key: str, video_url: str) -> Dict[str, Any]: + """Create an AI note generation task. + + Args: + api_key: Baidu API key + video_url: Public video URL + + Returns: + Task data with task_id + + Raises: + RuntimeError: If API returns error + """ + url = "https://qianfan.baidubce.com/v2/tools/ai_note/task_create" + headers = { + "Authorization": f"Bearer {api_key}", + "X-Appbuilder-From": "openclaw", + "Content-Type": "application/json" + } + data = {"url": video_url} + + try: + response = requests.post(url, headers=headers, json=data, timeout=30) + response.raise_for_status() + result = response.json() + + if "code" in result: + raise RuntimeError(result.get("detail", "API error")) + if "errno" in result and result["errno"] != 0: + raise RuntimeError(result.get("errmsg", "Unknown error")) + + return result["data"] + + except requests.exceptions.Timeout: + raise RuntimeError("Request timeout. Video URL may be inaccessible.") + except requests.exceptions.RequestException as e: + raise RuntimeError(f"Network error: {str(e)}") + + +def main(): + if len(sys.argv) < 2: + print(json.dumps({ + "error": "Missing video URL", + "usage": "python ai_notes_task_create.py " + }, indent=2)) + sys.exit(1) + + video_url = sys.argv[1] + 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) + + try: + task_data = create_note_task(api_key, video_url) + print(json.dumps({ + "status": "success", + "message": "Task created successfully", + "task_id": task_data.get("task_id"), + "next_step": f"Query task status: python ai_notes_task_query.py {task_data.get('task_id')}" + }, indent=2)) + + except RuntimeError as e: + print(json.dumps({ + "status": "error", + "error": str(e) + }, indent=2)) + sys.exit(1) + except Exception as e: + print(json.dumps({ + "status": "error", + "error": f"Unexpected error: {str(e)}" + }, indent=2)) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/ai_notes_task_query.py b/scripts/ai_notes_task_query.py new file mode 100644 index 0000000..a33105a --- /dev/null +++ b/scripts/ai_notes_task_query.py @@ -0,0 +1,45 @@ +import os +import sys +import requests +import json + + +def ai_notes_task_query(api_key: str, task_id: str): + url = "https://qianfan.baidubce.com/v2/tools/ai_note/query" + headers = { + "Authorization": "Bearer %s" % api_key, + "Content-Type": "application/json" + } + params = { + "task_id": task_id, + } + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() + result = response.json() + if "code" in result: + raise RuntimeError(result["detail"]) + if "errno" in result and result["errno"] == 10000: + print("task status code: %s, message: %s" % (result["errno"], result["show_msg"])) + return {} + if "errno" in result and result["errno"] != 0: + raise RuntimeError(result["show_msg"]) + return result.get("data", {}) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: python ai_notes_task_create.py ") + sys.exit(1) + + task_id = 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_notes_task_query(api_key, task_id) + print(json.dumps(results, ensure_ascii=False, indent=2)) + except Exception as e: + print(f"Error: {str(e)}") + sys.exit(1)