mirror of
https://github.com/langchain-ai/deepagents.git
synced 2026-07-21 17:25:26 -04:00
feat(code): support Fireworks /routers model ids (#4591)
Fireworks router model ids (`accounts/fireworks/routers/...`) now display compactly in the status bar and support `/effort` reasoning controls, matching individual Fireworks model ids. --- Fireworks exposes two fully-qualified model-id forms: individual models (`accounts/fireworks/models/...`) and routers that dispatch across models (`accounts/fireworks/routers/...`, e.g. `accounts/fireworks/routers/glm-5p1-fast`; see [models.dev](https://models.dev/providers/fireworks-ai/)). Previously only the `models/` form was recognized, so router ids rendered with the full prefix in the status bar and never qualified for reasoning-effort controls. This teaches the two places that key off the qualified prefix to accept both forms: - `ModelLabel`'s `PROVIDER_PREFIX_STRIPS` now strips the `routers/` prefix for compact status-bar display. - `_classify_reasoning_provider` gates `/effort` on a shared `_FIREWORKS_MODEL_ID_PREFIXES` tuple covering both forms, so router models get the same family-based effort support as individual models. The model-family logic (Kimi/GLM/DeepSeek) is substring-based and already works for either form. Made by [Open SWE](https://openswe.vercel.app/agents/29503e81-c1ee-65e7-b10d-56661b75aa89) --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
@@ -13,6 +13,12 @@ from typing import Final
|
||||
DEFAULT_AGENT_NAME: Final[str] = "agent"
|
||||
"""Default agent / assistant identifier when no `-a` flag is given."""
|
||||
|
||||
FIREWORKS_MODEL_ID_PREFIXES: Final[tuple[str, ...]] = (
|
||||
"accounts/fireworks/models/",
|
||||
"accounts/fireworks/routers/",
|
||||
)
|
||||
"""Fully-qualified prefixes for Fireworks model and router IDs."""
|
||||
|
||||
SYSTEM_MESSAGE_PREFIX: Final[str] = "[SYSTEM]"
|
||||
"""Prefix for synthetic human messages (e.g. interrupt cancellation notices).
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Literal, NamedTuple, TypeAlias, get_args
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
from deepagents_code._constants import FIREWORKS_MODEL_ID_PREFIXES
|
||||
from deepagents_code.model_config import CODEX_PROVIDER, ModelSpec
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -456,7 +457,7 @@ def _classify_reasoning_provider(provider: str, model: str) -> ReasoningProvider
|
||||
return "anthropic"
|
||||
if provider == "google_genai" and model_lower.startswith("gemini-3"):
|
||||
return "google_genai"
|
||||
if provider == "fireworks" and model_lower.startswith("accounts/fireworks/models/"):
|
||||
if provider == "fireworks" and model_lower.startswith(FIREWORKS_MODEL_ID_PREFIXES):
|
||||
return "fireworks"
|
||||
if provider == "xai" and _is_xai_grok_45(model_lower):
|
||||
return "xai"
|
||||
|
||||
@@ -14,6 +14,7 @@ from textual.reactive import reactive
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Static
|
||||
|
||||
from deepagents_code._constants import FIREWORKS_MODEL_ID_PREFIXES
|
||||
from deepagents_code._env_vars import HIDE_CWD, HIDE_GIT_BRANCH, is_env_truthy
|
||||
from deepagents_code.config import get_glyphs
|
||||
from deepagents_code.tui.widgets.loading import Spinner
|
||||
@@ -27,11 +28,11 @@ if TYPE_CHECKING:
|
||||
from textual.timer import Timer
|
||||
|
||||
PROVIDER_PREFIX_STRIPS: dict[str, tuple[str, ...]] = {
|
||||
"fireworks": ("accounts/fireworks/models/",),
|
||||
"fireworks": FIREWORKS_MODEL_ID_PREFIXES,
|
||||
}
|
||||
"""Some providers (e.g. Fireworks) require fully-qualified IDs like
|
||||
`accounts/fireworks/models/...` that crowd out the rest of the status bar;
|
||||
strip the registered prefixes before display."""
|
||||
`accounts/fireworks/models/...` or `accounts/fireworks/routers/...` that crowd
|
||||
out the rest of the status bar; strip the registered prefixes before display."""
|
||||
|
||||
ConnectionState = Literal["", "connecting", "reconnecting", "resuming"]
|
||||
"""Connection states the status bar can display (`''` means cleared)."""
|
||||
|
||||
@@ -94,6 +94,12 @@ def _restore_settings() -> Iterator[None]:
|
||||
("low", "medium", "high"),
|
||||
),
|
||||
("fireworks:accounts/fireworks/models/glm-5p2", ("none", "high", "max")),
|
||||
# Fireworks routers (`accounts/fireworks/routers/...`) are gated the same
|
||||
# as individual models, so effort support keys off the model family.
|
||||
(
|
||||
"fireworks:accounts/fireworks/routers/glm-5p1-fast",
|
||||
("none", "high", "max"),
|
||||
),
|
||||
# Recognized provider, wrong model family: the per-provider prefix
|
||||
# guards in `_classify_reasoning_provider` (and the Fireworks family
|
||||
# check) must reject these rather than fall through to an effort set.
|
||||
@@ -103,6 +109,9 @@ def _restore_settings() -> Iterator[None]:
|
||||
("google_genai:gemini-2.5-flash", ()),
|
||||
("xai:grok-4", ()),
|
||||
("fireworks:accounts/fireworks/models/llama-v3p1-70b-instruct", ()),
|
||||
# Same guard for the router prefix: a recognized router whose id carries
|
||||
# no known family token must also fall through to no efforts.
|
||||
("fireworks:accounts/fireworks/routers/llama-v3p1-70b-instruct", ()),
|
||||
],
|
||||
)
|
||||
def test_supported_efforts_for_model(model_spec: str, efforts: tuple[str, ...]) -> None:
|
||||
@@ -133,6 +142,8 @@ def test_supported_efforts_for_model(model_spec: str, efforts: tuple[str, ...])
|
||||
("fireworks:accounts/fireworks/models/deepseek-v4-pro", "high"),
|
||||
("fireworks:accounts/fireworks/models/glm-5p2", "max"),
|
||||
("fireworks:accounts/fireworks/models/kimi-k2p7-code", None),
|
||||
# Routers reach the same family-based default lookup as models.
|
||||
("fireworks:accounts/fireworks/routers/deepseek-v4-pro", "high"),
|
||||
("ollama:llama3.1", None),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -542,6 +542,17 @@ class TestModelLabelPrefixStripping:
|
||||
assert "fireworks:kimi-k2p6" in rendered
|
||||
assert "accounts/fireworks/models/" not in rendered
|
||||
|
||||
async def test_fireworks_routers_prefix_stripped(self) -> None:
|
||||
"""The fireworks routers prefix is stripped before rendering."""
|
||||
async with StatusBarApp().run_test() as pilot:
|
||||
label = pilot.app.query_one("#model-display", ModelLabel)
|
||||
label.provider = "fireworks"
|
||||
label.model = "accounts/fireworks/routers/glm-5p1-fast"
|
||||
await pilot.pause()
|
||||
rendered = str(label.render())
|
||||
assert "fireworks:glm-5p1-fast" in rendered
|
||||
assert "accounts/fireworks/routers/" not in rendered
|
||||
|
||||
async def test_get_content_width_uses_stripped_name(self) -> None:
|
||||
"""`get_content_width` sizes to the stripped name, not the raw model."""
|
||||
async with StatusBarApp().run_test() as pilot:
|
||||
|
||||
Reference in New Issue
Block a user