| | |
| | | import sys |
| | | import json |
| | | import argparse |
| | | from pathlib import Path |
| | | from typing import List, Dict, Any, Optional |
| | | |
| | | |
| | | def get_tavily_key_from_env_file() -> Optional[str]: |
| | | """Read Tavily API key from ~/.openclaw/.env file. |
| | | |
| | | Expected format: {"env": {"TAVILY_API_KEY": "your_key"}} |
| | | """ |
| | | env_file = Path.home() / ".openclaw" / ".env" |
| | | if not env_file.exists(): |
| | | return None |
| | | |
| | | try: |
| | | with open(env_file, 'r', encoding='utf-8') as f: |
| | | env_data = json.load(f) |
| | | # Support nested structure: {"env": {"TAVILY_API_KEY": "..."}} |
| | | if "env" in env_data: |
| | | return env_data["env"].get("TAVILY_API_KEY") |
| | | # Fallback to flat structure: {"TAVILY_API_KEY": "..."} |
| | | return env_data.get("TAVILY_API_KEY") |
| | | except (json.JSONDecodeError, IOError): |
| | | return None |
| | | |
| | | |
| | | def get_api_key(api_key: Optional[str] = None) -> str: |
| | | """Get Tavily API key from various sources.""" |
| | | # Priority: parameter > env var > .env file |
| | | """Get Tavily API key from environment variable or parameter.""" |
| | | # Priority: parameter > environment variable |
| | | if api_key: |
| | | return api_key |
| | | |
| | |
| | | if env_key: |
| | | return env_key |
| | | |
| | | env_file_key = get_tavily_key_from_env_file() |
| | | if env_file_key: |
| | | return env_file_key |
| | | |
| | | raise ValueError( |
| | | "Tavily API key required. Set via one of:\n" |
| | | " 1. TAVILY_API_KEY environment variable\n" |
| | | " 2. ~/.openclaw/.env file (JSON format: {\"env\": {\"TAVILY_API_KEY\": \"...\"}})\n" |
| | | " 3. Pass as api_key parameter\n" |
| | | "Tavily API key required. Set via:\n" |
| | | " 1. Environment variable: export TAVILY_API_KEY=your_key\n" |
| | | " (Add to ~/.bashrc or ~/.zshrc for persistence)\n" |
| | | " 2. Direct parameter: pass api_key when calling the function\n" |
| | | "\nGet your API key at: https://tavily.com" |
| | | ) |
| | | |