Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/any_llm/providers/fireworks/fireworks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FireworksProvider(BaseOpenAIProvider):
SUPPORTS_COMPLETION_STREAMING = True
SUPPORTS_COMPLETION = True
SUPPORTS_RESPONSES = True
SUPPORTS_COMPLETION_REASONING = False
SUPPORTS_COMPLETION_REASONING = True
SUPPORTS_COMPLETION_PDF = False
SUPPORTS_EMBEDDING = False
SUPPORTS_LIST_MODELS = True
Expand Down
7 changes: 4 additions & 3 deletions src/any_llm/providers/fireworks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,23 @@
def extract_reasoning_from_response(response: Response) -> Response:
"""Extract <think> content from Fireworks response and set reasoning field.

Fireworks Responses API includes reasoning content within <think></think> tags.
Fireworks Responses API may include reasoning content within <think></think> tags.
This function extracts that content and moves it to the reasoning field.

Args:
response: The Response object to process

Returns:
The modified Response object with reasoning extracted
"""
if response.reasoning:
return response

if not response.output or not response.output[-1].content:
return response

content_text = response.output[-1].content[0].text
if "<think>" in content_text and "</think>" in content_text:
reasoning = content_text.split("<think>")[1].split("</think>")[0].strip()
# Skip case where reasoning is empty but tags are present
if reasoning:
response.reasoning = Reasoning(content=reasoning) # type: ignore[assignment]
response.output[-1].content[0].text = content_text.split("</think>")[1].strip()
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def provider_reasoning_model_map() -> dict[LLMProvider, str]:
LLMProvider.GEMINI: "gemini-2.5-flash",
LLMProvider.VERTEXAI: "gemini-2.5-flash",
LLMProvider.GROQ: "openai/gpt-oss-20b",
LLMProvider.FIREWORKS: "accounts/fireworks/models/deepseek-r1",
LLMProvider.FIREWORKS: "accounts/fireworks/models/gpt-oss-20b",
LLMProvider.OPENAI: "gpt-5-nano",
LLMProvider.MISTRAL: "magistral-small-latest",
LLMProvider.XAI: "grok-3-mini-latest",
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ async def test_responses_async(
llm = AnyLLM.create(provider, **provider_client_config.get(provider, {}))
if not llm.SUPPORTS_RESPONSES:
pytest.skip(f"{provider.value} does not support responses, skipping")
if provider == LLMProvider.FIREWORKS:
pytest.skip(
"Fireworks responses API not returning reasoning field - known bug awaiting their fix (contact Nathan Brake for the email chain)"
)
model_id = provider_reasoning_model_map[provider]
result = await llm.aresponses(
model_id,
Expand Down