소스 검색

Support Video Proxy and TED Embedding (#10819)

Tao Wang 5 달 전
부모
커밋
9f195df103
2개의 변경된 파일59개의 추가작업 그리고 33개의 파일을 삭제
  1. 29 14
      api/core/tools/provider/builtin/duckduckgo/tools/ddgo_video.py
  2. 30 19
      api/core/tools/provider/builtin/duckduckgo/tools/ddgo_video.yaml

+ 29 - 14
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_video.py

@@ -1,4 +1,4 @@
-from typing import Any
+from typing import Any, ClassVar
 
 from duckduckgo_search import DDGS
 
@@ -11,6 +11,17 @@ class DuckDuckGoVideoSearchTool(BuiltinTool):
     Tool for performing a video search using DuckDuckGo search engine.
     """
 
+    IFRAME_TEMPLATE: ClassVar[str] = """
+<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; \
+max-width: 100%; border-radius: 8px;">
+    <iframe
+        style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
+        src="{src}"
+        frameborder="0"
+        allowfullscreen>
+    </iframe>
+</div>"""
+
     def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> list[ToolInvokeMessage]:
         query_dict = {
             "keywords": tool_parameters.get("query"),
@@ -26,6 +37,9 @@ class DuckDuckGoVideoSearchTool(BuiltinTool):
         # Remove None values to use API defaults
         query_dict = {k: v for k, v in query_dict.items() if v is not None}
 
+        # Get proxy URL from parameters
+        proxy_url = tool_parameters.get("proxy_url", "").strip()
+
         response = DDGS().videos(**query_dict)
 
         # Create HTML result with embedded iframes
@@ -36,20 +50,21 @@ class DuckDuckGoVideoSearchTool(BuiltinTool):
             title = res.get("title", "")
             embed_html = res.get("embed_html", "")
             description = res.get("description", "")
+            content_url = res.get("content", "")
 
-            # Modify iframe to be responsive
-            if embed_html:
-                # Replace fixed dimensions with responsive wrapper and iframe
-                embed_html = """
-<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; \
-max-width: 100%; border-radius: 8px;">
-    <iframe
-        style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
-        src="{src}"
-        frameborder="0"
-        allowfullscreen>
-    </iframe>
-</div>""".format(src=res.get("embed_url", ""))
+            # Handle TED.com videos
+            if not embed_html and "ted.com/talks" in content_url:
+                embed_url = content_url.replace("www.ted.com", "embed.ted.com")
+                if proxy_url:
+                    embed_url = f"{proxy_url}{embed_url}"
+                embed_html = self.IFRAME_TEMPLATE.format(src=embed_url)
+
+            # Original YouTube/other platform handling
+            elif embed_html:
+                embed_url = res.get("embed_url", "")
+                if proxy_url and embed_url:
+                    embed_url = f"{proxy_url}{embed_url}"
+                embed_html = self.IFRAME_TEMPLATE.format(src=embed_url)
 
             markdown_result += f"{title}\n\n"
             markdown_result += f"{embed_html}\n\n"

+ 30 - 19
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_video.yaml

@@ -1,40 +1,43 @@
 identity:
   name: ddgo_video
-  author: Assistant
+  author: Tao Wang
   label:
     en_US: DuckDuckGo Video Search
     zh_Hans: DuckDuckGo 视频搜索
 description:
   human:
-    en_US: Perform video searches on DuckDuckGo and get results with embedded videos.
-    zh_Hans: 在 DuckDuckGo 上进行视频搜索并获取可嵌入视频结果。
-  llm: Perform video searches on DuckDuckGo and get results with embedded videos.
+    en_US: Search and embedded videos.
+    zh_Hans: 搜索并嵌入视频
+  llm: Search videos on duckduckgo and embed videos in iframe
 parameters:
   - name: query
-    type: string
-    required: true
     label:
       en_US: Query String
       zh_Hans: 查询语句
+    type: string
+    required: true
     human_description:
       en_US: Search Query
-      zh_Hans: 搜索查询语句
+      zh_Hans: 搜索查询语句
     llm_description: Key words for searching
     form: llm
   - name: max_results
+    label:
+      en_US: Max Results
+      zh_Hans: 最大结果数量
     type: number
     required: true
     default: 3
     minimum: 1
     maximum: 10
-    label:
-      en_US: Max Results
-      zh_Hans: 最大结果数量
     human_description:
-      en_US: The max results (1-10).
-      zh_Hans: 最大结果数量(1-10)
+      en_US: The max results (1-10)
+      zh_Hans: 最大结果数量(1-10)
     form: form
   - name: timelimit
+    label:
+      en_US: Result Time Limit
+      zh_Hans: 结果时间限制
     type: select
     required: false
     options:
@@ -54,14 +57,14 @@ parameters:
         label:
           en_US: Current Year
           zh_Hans: 今年
-    label:
-      en_US: Result Time Limit
-      zh_Hans: 结果时间限制
     human_description:
-      en_US: Use when querying results within a specific time range only.
+      en_US: Query results within a specific time range only
       zh_Hans: 只查询一定时间范围内的结果时使用
     form: form
   - name: duration
+    label:
+      en_US: Video Duration
+      zh_Hans: 视频时长
     type: select
     required: false
     options:
@@ -77,10 +80,18 @@ parameters:
         label:
           en_US: Long (>20 minutes)
           zh_Hans: 长视频(>20分钟)
-    label:
-      en_US: Video Duration
-      zh_Hans: 视频时长
     human_description:
       en_US: Filter videos by duration
       zh_Hans: 按时长筛选视频
     form: form
+  - name: proxy_url
+    label:
+      en_US: Proxy URL
+      zh_Hans: 视频代理地址
+    type: string
+    required: false
+    default: ""
+    human_description:
+      en_US: Proxy URL
+      zh_Hans: 视频代理地址
+    form: form