mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 13:16:24 +00:00
fix(config): correct Gemini official endpoint reasoning example (#6161)
* fix(config): correct Gemini official endpoint reasoning example * docs: clarify official Gemini endpoint heading
This commit is contained in:
parent
23b366a101
commit
759136e074
@ -121,6 +121,9 @@ Optional per-model [`request_admission`](backend/docs/CONFIGURATION.md#model-req
|
||||
paces requests to help stay within provider request-per-minute limits.
|
||||
It is disabled by default; see the linked guide to enable it.
|
||||
|
||||
For Google's official Gemini OpenAI-compatible endpoint, use the
|
||||
[Gemini reasoning profile](backend/docs/CONFIGURATION.md#gemini-via-googles-openai-compatible-endpoint).
|
||||
|
||||
1. **Clone the DeerFlow repository**
|
||||
|
||||
```bash
|
||||
|
||||
@ -269,7 +269,7 @@ models:
|
||||
type: enabled
|
||||
```
|
||||
|
||||
**Gemini with thinking via OpenAI-compatible gateway**:
|
||||
#### Gemini via Google's OpenAI-compatible endpoint
|
||||
|
||||
When routing Gemini through an OpenAI-compatible proxy (Vertex AI OpenAI compat endpoint, AI Studio, or third-party gateways) with thinking enabled, the API attaches a `thought_signature` to each tool-call object returned in the response. Every subsequent request that replays those assistant messages **must** echo those signatures back on the tool-call entries or the API returns:
|
||||
|
||||
@ -282,22 +282,24 @@ Standard `langchain_openai:ChatOpenAI` silently drops `thought_signature` when s
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: gemini-2.5-pro-thinking
|
||||
display_name: Gemini 2.5 Pro (Thinking)
|
||||
- name: gemini-3.1-pro-preview
|
||||
display_name: Gemini 3.1 Pro (Thinking)
|
||||
use: deerflow.models.patched_openai:PatchedChatOpenAI
|
||||
model: google/gemini-2.5-pro-preview # model name as expected by your gateway
|
||||
model: gemini-3.1-pro-preview
|
||||
api_key: $GEMINI_API_KEY
|
||||
base_url: https://<your-openai-compat-gateway>/v1
|
||||
base_url: https://generativelanguage.googleapis.com/v1beta/openai/
|
||||
max_tokens: 16384
|
||||
supports_thinking: true
|
||||
supports_vision: true
|
||||
when_thinking_enabled:
|
||||
extra_body:
|
||||
thinking:
|
||||
type: enabled
|
||||
reasoning:
|
||||
thinking: required
|
||||
dialect: none
|
||||
effort:
|
||||
values: [minimal, low, medium, high]
|
||||
```
|
||||
|
||||
For Gemini accessed **without** thinking (e.g. via OpenRouter where thinking is not activated), the plain `langchain_openai:ChatOpenAI` with `supports_thinking: false` is sufficient and no patch is needed.
|
||||
This example targets Google's official endpoint. Its [OpenAI compatibility API](https://ai.google.dev/gemini-api/docs/openai#thinking) accepts `reasoning_effort`; `extra_body.thinking` becomes an unsupported top-level `thinking` field and causes HTTP 400. Gemini 3.1 Pro cannot disable thinking, so `thinking: required` keeps it enabled even when a caller requests otherwise, while `dialect: none` prevents a provider-specific thinking toggle. Omitting effort uses the model's default.
|
||||
|
||||
If you copied the previous example, replace its `supports_thinking`, `when_thinking_enabled`, and `when_thinking_disabled` settings with the `reasoning` block above. Third-party gateways may require different model IDs and reasoning parameters; follow that gateway's documentation instead of reusing Google's profile unchanged.
|
||||
|
||||
**MiMo with thinking via OpenAI-compatible API**:
|
||||
|
||||
|
||||
@ -39,21 +39,8 @@ class PatchedChatOpenAI(ChatOpenAI):
|
||||
from ``AIMessage.additional_kwargs["tool_calls"]`` into the serialised
|
||||
request payload before it is sent to the API.
|
||||
|
||||
Usage in ``config.yaml``::
|
||||
|
||||
- name: gemini-2.5-pro-thinking
|
||||
display_name: Gemini 2.5 Pro (Thinking)
|
||||
use: deerflow.models.patched_openai:PatchedChatOpenAI
|
||||
model: google/gemini-2.5-pro-preview
|
||||
api_key: $GEMINI_API_KEY
|
||||
base_url: https://<your-openai-compat-gateway>/v1
|
||||
max_tokens: 16384
|
||||
supports_thinking: true
|
||||
supports_vision: true
|
||||
when_thinking_enabled:
|
||||
extra_body:
|
||||
thinking:
|
||||
type: enabled
|
||||
See the Gemini example in ``config.example.yaml`` for Google's official
|
||||
OpenAI-compatible endpoint and its reasoning configuration.
|
||||
"""
|
||||
|
||||
def _get_request_payload(
|
||||
|
||||
41
backend/tests/test_gemini_config_example.py
Normal file
41
backend/tests/test_gemini_config_example.py
Normal file
@ -0,0 +1,41 @@
|
||||
"""Exercise the shipped Gemini example through the model factory and OpenAI SDK."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from deerflow.config.app_config import AppConfig
|
||||
from deerflow.config.model_config import ModelConfig
|
||||
from deerflow.config.sandbox_config import SandboxConfig
|
||||
from deerflow.models.factory import create_chat_model
|
||||
|
||||
|
||||
@pytest.mark.parametrize("thinking_enabled,effort", [(True, None), (True, "medium"), (True, "high"), (False, "minimal")])
|
||||
def test_gemini_example_request(thinking_enabled, effort):
|
||||
example = (Path(__file__).resolve().parents[2] / "config.example.yaml").read_text(encoding="utf-8")
|
||||
block = example.split(" # Example: Gemini model via ", 1)[1].split("\n\n", 1)[0]
|
||||
lines = block[block.index(" # - name:") :].splitlines()
|
||||
settings = yaml.safe_load("\n".join(line.removeprefix(" # ") for line in lines))[0]
|
||||
settings["api_key"] = "test-key"
|
||||
config = AppConfig(models=[ModelConfig(**settings)], sandbox=SandboxConfig(use="deerflow.sandbox.local:LocalSandboxProvider"))
|
||||
requests = []
|
||||
|
||||
def respond(request):
|
||||
requests.append(request)
|
||||
return httpx.Response(200, json={"id": "test", "object": "chat.completion", "created": 0, "model": settings["model"], "choices": [{"index": 0, "message": {"role": "assistant", "content": "OK"}, "finish_reason": "stop"}]})
|
||||
|
||||
with httpx.Client(transport=httpx.MockTransport(respond)) as client:
|
||||
model = create_chat_model(app_config=config, attach_tracing=False, thinking_enabled=thinking_enabled, reasoning_effort=effort, http_client=client)
|
||||
assert model.invoke("Hello").content == "OK"
|
||||
|
||||
assert len(requests) == 1
|
||||
payload = json.loads(requests[0].content)
|
||||
assert "thinking" not in payload
|
||||
assert payload.get("reasoning_effort") == effort
|
||||
if effort is None:
|
||||
assert "reasoning_effort" not in payload
|
||||
assert payload["model"] == "gemini-3.1-pro-preview"
|
||||
assert str(requests[0].url) == "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions"
|
||||
@ -430,31 +430,30 @@ models:
|
||||
# context_window: 1048576
|
||||
# supports_vision: true
|
||||
|
||||
# Example: Gemini model via OpenAI-compatible gateway (with thinking support)
|
||||
# Example: Gemini model via Google's official OpenAI-compatible endpoint
|
||||
# Use PatchedChatOpenAI so that tool-call thought_signature values on tool_calls
|
||||
# are preserved across multi-turn tool-call conversations — required by the
|
||||
# Gemini API when thinking is enabled. See:
|
||||
# https://docs.cloud.google.com/vertex-ai/generative-ai/docs/thought-signatures
|
||||
# - name: gemini-2.5-pro-thinking
|
||||
# display_name: Gemini 2.5 Pro (Thinking)
|
||||
# Google accepts reasoning_effort, not extra_body.thinking. Gemini 3.1 Pro
|
||||
# cannot disable thinking; dialect: none avoids emitting a thinking toggle.
|
||||
# https://ai.google.dev/gemini-api/docs/openai#thinking
|
||||
# - name: gemini-3.1-pro-preview
|
||||
# display_name: Gemini 3.1 Pro (Thinking)
|
||||
# use: deerflow.models.patched_openai:PatchedChatOpenAI
|
||||
# model: google/gemini-2.5-pro-preview # model name as expected by your gateway
|
||||
# model: gemini-3.1-pro-preview
|
||||
# api_key: $GEMINI_API_KEY
|
||||
# base_url: https://<your-openai-compat-gateway>/v1
|
||||
# base_url: https://generativelanguage.googleapis.com/v1beta/openai/
|
||||
# request_timeout: 600.0
|
||||
# max_retries: 2
|
||||
# max_tokens: 16384
|
||||
# context_window: 1048576
|
||||
# supports_thinking: true
|
||||
# supports_vision: true
|
||||
# when_thinking_enabled:
|
||||
# extra_body:
|
||||
# thinking:
|
||||
# type: enabled
|
||||
# when_thinking_disabled:
|
||||
# extra_body:
|
||||
# thinking:
|
||||
# type: disabled
|
||||
# reasoning:
|
||||
# thinking: required
|
||||
# dialect: none
|
||||
# effort:
|
||||
# values: [minimal, low, medium, high]
|
||||
|
||||
# Example: Xiaomi MiMo model (with thinking support)
|
||||
# MiMo thinking mode returns reasoning_content and requires that field to be
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user