guantao 1 неделя назад
Родитель
Сommit
45f73eb9b9
2 измененных файлов с 50 добавлено и 15 удалено
  1. 24 4
      agent/llm/openrouter.py
  2. 26 11
      examples/how/run.py

+ 24 - 4
agent/llm/openrouter.py

@@ -19,6 +19,7 @@ import json
 import asyncio
 import logging
 import httpx
+from pathlib import Path
 from typing import List, Dict, Any, Optional
 
 from .usage import TokenUsage, create_usage_from_response
@@ -131,10 +132,29 @@ def _to_anthropic_content(content: Any) -> Any:
                     },
                 })
             else:
-                result.append({
-                    "type": "image",
-                    "source": {"type": "url", "url": url},
-                })
+                # 检测本地文件路径,自动转 base64
+                local_path = Path(url)
+                if local_path.exists() and local_path.is_file():
+                    import base64 as b64mod
+                    import mimetypes
+                    mime_type, _ = mimetypes.guess_type(str(local_path))
+                    mime_type = mime_type or "image/png"
+                    raw = local_path.read_bytes()
+                    b64_data = b64mod.b64encode(raw).decode("ascii")
+                    logger.info(f"[OpenRouter] 本地图片自动转 base64: {url} ({len(raw)} bytes)")
+                    result.append({
+                        "type": "image",
+                        "source": {
+                            "type": "base64",
+                            "media_type": mime_type,
+                            "data": b64_data,
+                        },
+                    })
+                else:
+                    result.append({
+                        "type": "image",
+                        "source": {"type": "url", "url": url},
+                    })
         else:
             result.append(block)
     return result

+ 26 - 11
examples/how/run.py

@@ -42,21 +42,36 @@ from agent.llm import create_openrouter_llm_call
 
 
 # ===== 非阻塞 stdin 检测 =====
+if sys.platform == 'win32':
+    import msvcrt
 
 def check_stdin() -> str | None:
     """
-    非阻塞检查 stdin 是否有输入。
-
-    使用 select 轮询,不开后台线程,因此不会与交互菜单的 input() 抢 stdin。
+    跨平台非阻塞检查 stdin 输入。
+    Windows: 使用 msvcrt.kbhit()
+    macOS/Linux: 使用 select.select()
     """
-    ready, _, _ = select.select([sys.stdin], [], [], 0)
-    if ready:
-        line = sys.stdin.readline().strip().lower()
-        if line in ('p', 'pause'):
-            return 'pause'
-        if line in ('q', 'quit'):
-            return 'quit'
-    return None
+    if sys.platform == 'win32':
+        # 检查是否有按键按下
+        if msvcrt.kbhit():
+            # 读取按下的字符(msvcrt.getwch 是非阻塞读取宽字符)
+            ch = msvcrt.getwch().lower()
+            if ch == 'p':
+                return 'pause'
+            if ch == 'q':
+                return 'quit'
+            # 如果是其他按键,可以选择消耗掉或者忽略
+        return None
+    else:
+        # Unix/Mac 逻辑
+        ready, _, _ = select.select([sys.stdin], [], [], 0)
+        if ready:
+            line = sys.stdin.readline().strip().lower()
+            if line in ('p', 'pause'):
+                return 'pause'
+            if line in ('q', 'quit'):
+                return 'quit'
+        return None
 
 
 # ===== 交互菜单 =====