mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 21:26:39 +00:00
feat: add API Route setup wizard preset (#6579)
* feat: add API Route setup wizard preset Signed-off-by: dennyho0917 <dennyho0917@gmail.com> * fix: address API Route wizard review feedback Signed-off-by: dennyho0917 <dennyho0917@gmail.com> --------- Signed-off-by: dennyho0917 <dennyho0917@gmail.com> Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
parent
829edac602
commit
513c03e8c0
@ -328,6 +328,13 @@ streams simulate chunks from a non-streaming response, while no-tool streams sta
|
||||
api_key: $OPPER_API_KEY
|
||||
base_url: https://api.opper.ai/v3/compat
|
||||
|
||||
- name: api-route-gpt-6.1-sol
|
||||
display_name: GPT 6.1 Sol (API Route)
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-6.1-sol
|
||||
api_key: $API_ROUTE_API_KEY
|
||||
base_url: https://global.api-route.com/v1
|
||||
|
||||
- name: gpt-5-responses
|
||||
display_name: GPT-5 (Responses API)
|
||||
use: langchain_openai:ChatOpenAI
|
||||
@ -351,6 +358,8 @@ streams simulate chunks from a non-streaming response, while no-tool streams sta
|
||||
|
||||
OpenRouter and similar OpenAI-compatible gateways should be configured with `langchain_openai:ChatOpenAI` plus `base_url`. If you prefer a provider-specific environment variable name, point `api_key` at that variable explicitly (for example `api_key: $OPENROUTER_API_KEY`).
|
||||
|
||||
[API Route](https://www.api-route.com) is also available in the setup wizard. It saves your key as `API_ROUTE_API_KEY` and uses the Chat Completions endpoint above. Model availability depends on your key's group and permissions; check the authenticated `GET https://global.api-route.com/v1/models` catalog before replacing the model in `config.yaml`, and use its returned ID unchanged without an upstream provider prefix.
|
||||
|
||||
The `write_file` tool's output-budget hint uses the active model's effective `max_tokens`. Missing or unusable limits, including YAML `.inf`, `-.inf`, `.nan`, and values too large for the character estimate, omit this hint without failing tool assembly; provider-specific model validation still applies.
|
||||
|
||||
To route OpenAI models through `/v1/responses`, keep using `langchain_openai:ChatOpenAI` and set `use_responses_api: true` with `output_version: responses/v1`.
|
||||
|
||||
@ -179,6 +179,13 @@ YAML 同名模型优先,已有任务保留原配置快照。托管模型使用
|
||||
api_key: $OPPER_API_KEY
|
||||
base_url: https://api.opper.ai/v3/compat
|
||||
|
||||
- name: api-route-gpt-6.1-sol
|
||||
display_name: GPT 6.1 Sol (API Route)
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-6.1-sol
|
||||
api_key: $API_ROUTE_API_KEY
|
||||
base_url: https://global.api-route.com/v1
|
||||
|
||||
- name: gpt-5-responses
|
||||
display_name: GPT-5 (Responses API)
|
||||
use: langchain_openai:ChatOpenAI
|
||||
@ -202,6 +209,8 @@ YAML 同名模型优先,已有任务保留原配置快照。托管模型使用
|
||||
|
||||
OpenRouter 以及类似的 OpenAI 兼容网关,建议通过 `langchain_openai:ChatOpenAI` 配合 `base_url` 来配置。如果你更想用 provider 自己的环境变量名,也可以直接把 `api_key` 指向对应变量,例如 `api_key: $OPENROUTER_API_KEY`。
|
||||
|
||||
Setup Wizard 也支持 [API Route](https://www.api-route.com),会将密钥保存为 `API_ROUTE_API_KEY`,并使用上面的 Chat Completions 端点。可用模型取决于密钥所属组别和权限;修改 `config.yaml` 中的模型前,请先查询需要认证的 `GET https://global.api-route.com/v1/models` 模型目录,并原样使用返回的模型 ID,不要添加上游 provider 前缀。
|
||||
|
||||
如果要让 OpenAI 模型走 `/v1/responses`,继续使用 `langchain_openai:ChatOpenAI`,并设置 `use_responses_api: true` 和 `output_version: responses/v1`。
|
||||
|
||||
如果某个模型的 provider 约定与 DeerFlow 通用的 thinking/effort 假设不同,可以为该模型声明 `reasoning:` 块(thinking 为 `unsupported`/`optional`/`required`、允许的 effort 取值及别名和默认值、payload 方言、推理历史要求)。Setup Wizard 内置的 Z.AI GLM-5.3-Flash 配置就使用了它:前台和后台调用都会保持 thinking 开启,effort 选择器只提供该模型自己的 `low`/`high`/`max` 档位。未声明该块的配置行为保持不变。具体格式与等价的手动配置见 `config.example.yaml`。
|
||||
|
||||
57
backend/tests/test_api_route_setup_wizard.py
Normal file
57
backend/tests/test_api_route_setup_wizard.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""API Route setup uses the existing OpenAI-compatible wizard path."""
|
||||
|
||||
import yaml
|
||||
from wizard.providers import LLM_PROVIDERS
|
||||
from wizard.steps import llm as llm_step
|
||||
from wizard.writer import build_minimal_config
|
||||
|
||||
|
||||
def api_route_provider():
|
||||
provider = next((p for p in LLM_PROVIDERS if p.name == "api_route"), None)
|
||||
assert provider is not None
|
||||
return provider
|
||||
|
||||
|
||||
def test_api_route_uses_versioned_chat_endpoint_and_bare_model_id():
|
||||
provider = api_route_provider()
|
||||
assert provider.use == "langchain_openai:ChatOpenAI"
|
||||
assert provider.package == "langchain-openai"
|
||||
assert provider.env_var == "API_ROUTE_API_KEY"
|
||||
assert provider.models == ["gpt-6.1-sol"]
|
||||
assert provider.default_model == "gpt-6.1-sol"
|
||||
assert provider.extra_config["base_url"] == "https://global.api-route.com/v1"
|
||||
|
||||
|
||||
def test_api_route_generated_config_preserves_key_reference_and_model():
|
||||
provider = api_route_provider()
|
||||
config = yaml.safe_load(
|
||||
build_minimal_config(
|
||||
provider_use=provider.use,
|
||||
model_name=provider.default_model,
|
||||
display_name=provider.display_name,
|
||||
api_key_field=provider.api_key_field,
|
||||
env_var=provider.env_var,
|
||||
extra_model_config=provider.extra_config_for(provider.default_model),
|
||||
)
|
||||
)
|
||||
model = config["models"][0]
|
||||
assert model["model"] == "gpt-6.1-sol"
|
||||
assert model["api_key"] == "$API_ROUTE_API_KEY"
|
||||
assert model["base_url"] == "https://global.api-route.com/v1"
|
||||
assert model["use"] == "langchain_openai:ChatOpenAI"
|
||||
assert model["temperature"] == 0.7
|
||||
assert "use_responses_api" not in model
|
||||
assert not model.get("supports_vision", False)
|
||||
assert not model.get("supports_thinking", False)
|
||||
|
||||
|
||||
def test_api_route_wizard_selects_preset_and_collects_key(monkeypatch):
|
||||
provider = api_route_provider()
|
||||
monkeypatch.setattr(llm_step, "LLM_PROVIDERS", [provider])
|
||||
monkeypatch.setattr(llm_step, "ask_choice", lambda *_args, **_kwargs: 0)
|
||||
monkeypatch.setattr(llm_step, "ask_secret", lambda prompt: "test-api-route-key" if prompt == "API_ROUTE_API_KEY" else None)
|
||||
result = llm_step.run_llm_step()
|
||||
assert result.model_name == "gpt-6.1-sol"
|
||||
assert result.provider.extra_config["base_url"] == "https://global.api-route.com/v1"
|
||||
assert result.provider.env_var == "API_ROUTE_API_KEY"
|
||||
assert result.api_key == "test-api-route-key"
|
||||
@ -512,6 +512,23 @@ LLM_PROVIDERS: list[LLMProvider] = [
|
||||
"temperature": 0.7,
|
||||
},
|
||||
),
|
||||
LLMProvider(
|
||||
name="api_route",
|
||||
display_name="API Route",
|
||||
description="OpenAI-compatible gateway (models depend on your API key)",
|
||||
use="langchain_openai:ChatOpenAI",
|
||||
models=["gpt-6.1-sol"],
|
||||
default_model="gpt-6.1-sol",
|
||||
env_var="API_ROUTE_API_KEY",
|
||||
package="langchain-openai",
|
||||
extra_config={
|
||||
"base_url": "https://global.api-route.com/v1",
|
||||
"request_timeout": 600.0,
|
||||
"max_retries": 2,
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
},
|
||||
),
|
||||
LLMProvider(
|
||||
name="vllm",
|
||||
display_name="vLLM",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user