Spaces:
Running
Running
Update service env names
Browse files- .env.example +2 -2
- README.md +2 -2
- agent_base/provider_compat.py +9 -1
- agent_base/tools/README.md +3 -3
- agent_base/tools/tool_web.py +6 -6
- agent_base/tools/tooling.py +2 -2
- agent_base/utils.py +2 -2
- docs/tutorial_en.md +2 -2
- docs/tutorial_zh.md +2 -2
.env.example
CHANGED
|
@@ -2,8 +2,8 @@
|
|
| 2 |
API_KEY="your_openai_compatible_key" # API key for your OpenAI-compatible LLM provider.
|
| 3 |
API_BASE="https://your-openai-compatible-endpoint/v1" # Base URL for the OpenAI-compatible chat-completions endpoint.
|
| 4 |
MODEL_NAME="gpt-5.5" # Main model used by the agent and WebFetch summarization.
|
| 5 |
-
|
| 6 |
-
|
| 7 |
MINERU_TOKEN="your_mineru_token" # https://mineru.net/
|
| 8 |
|
| 9 |
# Optional
|
|
|
|
| 2 |
API_KEY="your_openai_compatible_key" # API key for your OpenAI-compatible LLM provider.
|
| 3 |
API_BASE="https://your-openai-compatible-endpoint/v1" # Base URL for the OpenAI-compatible chat-completions endpoint.
|
| 4 |
MODEL_NAME="gpt-5.5" # Main model used by the agent and WebFetch summarization.
|
| 5 |
+
SERPER_KEY="your_serper_key" # https://serper.dev/
|
| 6 |
+
JINA_KEY="your_jina_key" # https://jina.ai/
|
| 7 |
MINERU_TOKEN="your_mineru_token" # https://mineru.net/
|
| 8 |
|
| 9 |
# Optional
|
README.md
CHANGED
|
@@ -30,8 +30,8 @@ Configure these as Hugging Face Space secrets before starting the app:
|
|
| 30 |
| `API_KEY` | API key for your OpenAI-compatible LLM provider. |
|
| 31 |
| `API_BASE` | OpenAI-compatible `/v1` endpoint. |
|
| 32 |
| `MODEL_NAME` | Main model used by ResearchHarness. |
|
| 33 |
-
| `
|
| 34 |
-
| `
|
| 35 |
| `MINERU_TOKEN` | ReadPDF key from <https://mineru.net/>. |
|
| 36 |
|
| 37 |
## Optional Runtime Variables
|
|
|
|
| 30 |
| `API_KEY` | API key for your OpenAI-compatible LLM provider. |
|
| 31 |
| `API_BASE` | OpenAI-compatible `/v1` endpoint. |
|
| 32 |
| `MODEL_NAME` | Main model used by ResearchHarness. |
|
| 33 |
+
| `SERPER_KEY` | WebSearch / ScholarSearch key from <https://serper.dev/>. |
|
| 34 |
+
| `JINA_KEY` | WebFetch key from <https://jina.ai/>. |
|
| 35 |
| `MINERU_TOKEN` | ReadPDF key from <https://mineru.net/>. |
|
| 36 |
|
| 37 |
## Optional Runtime Variables
|
agent_base/provider_compat.py
CHANGED
|
@@ -13,6 +13,14 @@ def model_rejects_sampling_params(model_name: str) -> bool:
|
|
| 13 |
return any(part.startswith("claude") for part in parts)
|
| 14 |
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
def apply_sampling_params(
|
| 17 |
request_kwargs: dict[str, Any],
|
| 18 |
*,
|
|
@@ -27,5 +35,5 @@ def apply_sampling_params(
|
|
| 27 |
request_kwargs["temperature"] = temperature
|
| 28 |
if top_p is not None:
|
| 29 |
request_kwargs["top_p"] = top_p
|
| 30 |
-
if presence_penalty is not None:
|
| 31 |
request_kwargs["presence_penalty"] = presence_penalty
|
|
|
|
| 13 |
return any(part.startswith("claude") for part in parts)
|
| 14 |
|
| 15 |
|
| 16 |
+
def model_rejects_presence_penalty(model_name: str) -> bool:
|
| 17 |
+
normalized = str(model_name or "").strip().casefold()
|
| 18 |
+
if not normalized:
|
| 19 |
+
return False
|
| 20 |
+
parts = [part for part in _MODEL_NAME_SPLIT_RE.split(normalized) if part]
|
| 21 |
+
return any(part.startswith("gpt-5.5") for part in parts)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
def apply_sampling_params(
|
| 25 |
request_kwargs: dict[str, Any],
|
| 26 |
*,
|
|
|
|
| 35 |
request_kwargs["temperature"] = temperature
|
| 36 |
if top_p is not None:
|
| 37 |
request_kwargs["top_p"] = top_p
|
| 38 |
+
if presence_penalty is not None and not model_rejects_presence_penalty(model_name):
|
| 39 |
request_kwargs["presence_penalty"] = presence_penalty
|
agent_base/tools/README.md
CHANGED
|
@@ -290,7 +290,7 @@ Arguments:
|
|
| 290 |
Behavior:
|
| 291 |
|
| 292 |
- Calls Serper's Google Search endpoint.
|
| 293 |
-
- Reads `
|
| 294 |
|
| 295 |
Returns:
|
| 296 |
|
|
@@ -312,7 +312,7 @@ Arguments:
|
|
| 312 |
Behavior:
|
| 313 |
|
| 314 |
- Calls Serper's Google Scholar endpoint.
|
| 315 |
-
- Reads `
|
| 316 |
|
| 317 |
Returns:
|
| 318 |
|
|
@@ -341,7 +341,7 @@ Behavior:
|
|
| 341 |
|
| 342 |
Dependencies:
|
| 343 |
|
| 344 |
-
- `
|
| 345 |
- `API_KEY`
|
| 346 |
- `API_BASE`
|
| 347 |
- `MODEL_NAME`
|
|
|
|
| 290 |
Behavior:
|
| 291 |
|
| 292 |
- Calls Serper's Google Search endpoint.
|
| 293 |
+
- Reads `SERPER_KEY` at runtime.
|
| 294 |
|
| 295 |
Returns:
|
| 296 |
|
|
|
|
| 312 |
Behavior:
|
| 313 |
|
| 314 |
- Calls Serper's Google Scholar endpoint.
|
| 315 |
+
- Reads `SERPER_KEY` at runtime.
|
| 316 |
|
| 317 |
Returns:
|
| 318 |
|
|
|
|
| 341 |
|
| 342 |
Dependencies:
|
| 343 |
|
| 344 |
+
- `JINA_KEY`
|
| 345 |
- `API_KEY`
|
| 346 |
- `API_BASE`
|
| 347 |
- `MODEL_NAME`
|
agent_base/tools/tool_web.py
CHANGED
|
@@ -130,9 +130,9 @@ class WebSearch(ToolBase):
|
|
| 130 |
"gl": "us",
|
| 131 |
"hl": "en",
|
| 132 |
}
|
| 133 |
-
serper_key = os.getenv("
|
| 134 |
if not serper_key:
|
| 135 |
-
return "[WebSearch]
|
| 136 |
headers = {
|
| 137 |
"X-API-KEY": serper_key,
|
| 138 |
"Content-Type": "application/json",
|
|
@@ -229,9 +229,9 @@ class ScholarSearch(ToolBase):
|
|
| 229 |
|
| 230 |
def google_scholar_with_serp(self, query: str):
|
| 231 |
payload = {"q": query}
|
| 232 |
-
serper_key = os.getenv("
|
| 233 |
if not serper_key:
|
| 234 |
-
return "[ScholarSearch]
|
| 235 |
headers = {
|
| 236 |
"X-API-KEY": serper_key,
|
| 237 |
"Content-Type": "application/json",
|
|
@@ -449,9 +449,9 @@ class WebFetch(ToolBase):
|
|
| 449 |
def jina_readpage(self, url: str, runtime_deadline: Optional[float] = None) -> str:
|
| 450 |
max_retries = 3
|
| 451 |
timeout = 50
|
| 452 |
-
jina_api_key = os.getenv("
|
| 453 |
if not jina_api_key:
|
| 454 |
-
return "[WebFetch]
|
| 455 |
|
| 456 |
last_error = "unknown page-fetch error"
|
| 457 |
for attempt in range(max_retries):
|
|
|
|
| 130 |
"gl": "us",
|
| 131 |
"hl": "en",
|
| 132 |
}
|
| 133 |
+
serper_key = os.getenv("SERPER_KEY", "").strip()
|
| 134 |
if not serper_key:
|
| 135 |
+
return "[WebSearch] SERPER_KEY is not set."
|
| 136 |
headers = {
|
| 137 |
"X-API-KEY": serper_key,
|
| 138 |
"Content-Type": "application/json",
|
|
|
|
| 229 |
|
| 230 |
def google_scholar_with_serp(self, query: str):
|
| 231 |
payload = {"q": query}
|
| 232 |
+
serper_key = os.getenv("SERPER_KEY", "").strip()
|
| 233 |
if not serper_key:
|
| 234 |
+
return "[ScholarSearch] SERPER_KEY is not set."
|
| 235 |
headers = {
|
| 236 |
"X-API-KEY": serper_key,
|
| 237 |
"Content-Type": "application/json",
|
|
|
|
| 449 |
def jina_readpage(self, url: str, runtime_deadline: Optional[float] = None) -> str:
|
| 450 |
max_retries = 3
|
| 451 |
timeout = 50
|
| 452 |
+
jina_api_key = os.getenv("JINA_KEY", "").strip()
|
| 453 |
if not jina_api_key:
|
| 454 |
+
return "[WebFetch] JINA_KEY is not set."
|
| 455 |
|
| 456 |
last_error = "unknown page-fetch error"
|
| 457 |
for attempt in range(max_retries):
|
agent_base/tools/tooling.py
CHANGED
|
@@ -65,8 +65,8 @@ BLOCKED_COMMAND_PATTERNS: list[tuple[re.Pattern[str], str]] = [
|
|
| 65 |
]
|
| 66 |
SENSITIVE_ENV_EXACT = {
|
| 67 |
"API_KEY",
|
| 68 |
-
"
|
| 69 |
-
"
|
| 70 |
"MINERU_TOKEN",
|
| 71 |
"OPENAI_API_KEY",
|
| 72 |
"ANTHROPIC_API_KEY",
|
|
|
|
| 65 |
]
|
| 66 |
SENSITIVE_ENV_EXACT = {
|
| 67 |
"API_KEY",
|
| 68 |
+
"SERPER_KEY",
|
| 69 |
+
"JINA_KEY",
|
| 70 |
"MINERU_TOKEN",
|
| 71 |
"OPENAI_API_KEY",
|
| 72 |
"ANTHROPIC_API_KEY",
|
agent_base/utils.py
CHANGED
|
@@ -16,8 +16,8 @@ REQUIRED_ENV_VARS = (
|
|
| 16 |
"API_KEY",
|
| 17 |
"API_BASE",
|
| 18 |
"MODEL_NAME",
|
| 19 |
-
"
|
| 20 |
-
"
|
| 21 |
"MINERU_TOKEN",
|
| 22 |
)
|
| 23 |
IMAGE_INPUT_REL_DIR = Path("inputs") / "images"
|
|
|
|
| 16 |
"API_KEY",
|
| 17 |
"API_BASE",
|
| 18 |
"MODEL_NAME",
|
| 19 |
+
"SERPER_KEY",
|
| 20 |
+
"JINA_KEY",
|
| 21 |
"MINERU_TOKEN",
|
| 22 |
)
|
| 23 |
IMAGE_INPUT_REL_DIR = Path("inputs") / "images"
|
docs/tutorial_en.md
CHANGED
|
@@ -32,8 +32,8 @@ Required variables:
|
|
| 32 |
| `API_KEY` | API key for your OpenAI-compatible LLM provider. |
|
| 33 |
| `API_BASE` | Base URL for the OpenAI-compatible chat-completions endpoint. |
|
| 34 |
| `MODEL_NAME` | Main model used by ResearchHarness. |
|
| 35 |
-
| `
|
| 36 |
-
| `
|
| 37 |
| `MINERU_TOKEN` | MinerU token for `ReadPDF`: https://mineru.net/ |
|
| 38 |
|
| 39 |
Optional variables:
|
|
|
|
| 32 |
| `API_KEY` | API key for your OpenAI-compatible LLM provider. |
|
| 33 |
| `API_BASE` | Base URL for the OpenAI-compatible chat-completions endpoint. |
|
| 34 |
| `MODEL_NAME` | Main model used by ResearchHarness. |
|
| 35 |
+
| `SERPER_KEY` | Serper key for `WebSearch` and `ScholarSearch`: https://serper.dev/ |
|
| 36 |
+
| `JINA_KEY` | Jina key for `WebFetch`: https://jina.ai/ |
|
| 37 |
| `MINERU_TOKEN` | MinerU token for `ReadPDF`: https://mineru.net/ |
|
| 38 |
|
| 39 |
Optional variables:
|
docs/tutorial_zh.md
CHANGED
|
@@ -30,8 +30,8 @@ python3 -m pip install -r requirements.txt
|
|
| 30 |
| `API_KEY` | OpenAI-compatible LLM 服务的 API key。 |
|
| 31 |
| `API_BASE` | OpenAI-compatible chat-completions endpoint 的 base URL。 |
|
| 32 |
| `MODEL_NAME` | ResearchHarness 使用的主模型。 |
|
| 33 |
-
| `
|
| 34 |
-
| `
|
| 35 |
| `MINERU_TOKEN` | `ReadPDF` 使用的 MinerU token:https://mineru.net/ |
|
| 36 |
|
| 37 |
可选变量:
|
|
|
|
| 30 |
| `API_KEY` | OpenAI-compatible LLM 服务的 API key。 |
|
| 31 |
| `API_BASE` | OpenAI-compatible chat-completions endpoint 的 base URL。 |
|
| 32 |
| `MODEL_NAME` | ResearchHarness 使用的主模型。 |
|
| 33 |
+
| `SERPER_KEY` | `WebSearch` 和 `ScholarSearch` 使用的 Serper key:https://serper.dev/ |
|
| 34 |
+
| `JINA_KEY` | `WebFetch` 使用的 Jina key:https://jina.ai/ |
|
| 35 |
| `MINERU_TOKEN` | `ReadPDF` 使用的 MinerU token:https://mineru.net/ |
|
| 36 |
|
| 37 |
可选变量:
|