This commit is contained in:
shrey-berri 2026-09-30 21:38:55 -04:00 • committed by GitHub
commit 5b0f29c70f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 352 additions and 11 deletions

View file

@ -25553,7 +25553,7 @@
},
"/cursor/models": {
"get": {
"description": "OpenAI-compatible model listing for the Cursor BYOK base URL.\n\nClients pointed at `<proxy>/cursor` as an OpenAI-compatible base URL resolve and\nverify models via `GET {base}/models` (the OpenAI SDK contract). Without this\nroute those requests fall through to the Cursor Cloud Agents passthrough, which\ndemands a Cursor API key and 401s, so key verification silently fails before any\nchat request is ever sent. Delegates to the standard `/v1/models` handler.",
"description": "OpenAI-compatible model listing for the Cursor BYOK base URL.\n\nClients pointed at `<proxy>/cursor` as an OpenAI-compatible base URL resolve and\nverify models via `GET {base}/models` (the OpenAI SDK contract). Without this\nroute those requests fall through to the Cursor Cloud Agents passthrough, which\ndemands a Cursor API key and 401s, so key verification silently fails before any\nchat request is ever sent. Delegates to the standard `/v1/models` handler with\nwildcard routes left out, since Cursor offers every listed id as a callable model.",
"operationId": "cursor_model_list_cursor_models_get",
"responses": {
"200": {
@ -25578,7 +25578,7 @@
},
"/cursor/v1/models": {
"get": {
"description": "OpenAI-compatible model listing for the Cursor BYOK base URL.\n\nClients pointed at `<proxy>/cursor` as an OpenAI-compatible base URL resolve and\nverify models via `GET {base}/models` (the OpenAI SDK contract). Without this\nroute those requests fall through to the Cursor Cloud Agents passthrough, which\ndemands a Cursor API key and 401s, so key verification silently fails before any\nchat request is ever sent. Delegates to the standard `/v1/models` handler.",
"description": "OpenAI-compatible model listing for the Cursor BYOK base URL.\n\nClients pointed at `<proxy>/cursor` as an OpenAI-compatible base URL resolve and\nverify models via `GET {base}/models` (the OpenAI SDK contract). Without this\nroute those requests fall through to the Cursor Cloud Agents passthrough, which\ndemands a Cursor API key and 401s, so key verification silently fails before any\nchat request is ever sent. Delegates to the standard `/v1/models` handler with\nwildcard routes left out, since Cursor offers every listed id as a callable model.",
"operationId": "cursor_model_list_cursor_v1_models_get",
"responses": {
"200": {

View file

@ -2871,6 +2871,15 @@ class ConfigGeneralSettings(LiteLLMPydanticObjectBase):
"hidden model can still be called."
),
)
model_list_return_wildcard_routes: bool | None = Field(
None,
description=(
"When true, `/v1/models` lists wildcard routes such as `openai/*` next to the models they "
"expand to, without the caller passing `return_wildcard_routes=true`. A request that passes "
"`return_wildcard_routes=false` still leaves them out, as do the dashboard's model pickers "
"and `/cursor/v1/models`."
),
)
alerting: list | None = Field(
None,
description="List of alerting integrations - e.g. `alerting: ['slack', 'webhook', 'email']`. 'slack' posts Slack-format messages to any Slack-compatible webhook (Slack, Rocket.Chat, Mattermost); 'webhook' posts structured JSON budget alerts to WEBHOOK_URL",

View file

@ -11498,6 +11498,16 @@ async def _deployment_hidden_by_listing_callbacks(deployment: Deployment, user_a
return listed_name in await _names_hidden_by_listing_callbacks(user_api_key_dict, (listed_name,))
def _includes_wildcard_routes(return_wildcard_routes: bool | None, settings: Mapping[str, object]) -> bool:
"""Whether a listing or lookup includes wildcard routes such as `openai/*`. A request's
own `return_wildcard_routes` wins; without one, `model_list_return_wildcard_routes`
counts as on exactly when the admin UI's switch shows it on (`true` or `"true"`)."""
if return_wildcard_routes is not None:
return return_wildcard_routes
configured: Final = settings.get("model_list_return_wildcard_routes")
return configured is True or configured == "true"
@router.get("/v1/models", dependencies=[Depends(user_api_key_auth)], tags=["model management"])
@router.get(
"/models", dependencies=[Depends(user_api_key_auth)], tags=["model management"]
@ -11505,7 +11515,7 @@ async def _deployment_hidden_by_listing_callbacks(deployment: Deployment, user_a
async def model_list(
request: Request = None, # pyright: ignore[reportArgumentType] # FastAPI always injects the Request; the None default only serves direct in-process callers
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
return_wildcard_routes: bool | None = False,
return_wildcard_routes: bool | None = None,
team_id: str | None = None,
include_model_access_groups: bool | None = False,
only_model_access_groups: bool | None = False,
@ -11520,6 +11530,10 @@ async def model_list(
This is just for compatibility with openai projects like aider.
Query Parameters:
- return_wildcard_routes: When true, also list wildcard routes (e.g. `openai/*`)
next to the models they expand to. Defaults to
`general_settings.model_list_return_wildcard_routes`, which is
false unless set; pass `false` to leave them out regardless.
- include_metadata: Include additional metadata in the response with fallback information
- fallback_type: Type of fallbacks to include ("general", "context_window", "content_policy")
Defaults to "general" when include_metadata=true
@ -11608,6 +11622,8 @@ async def model_list(
hidden_names: Final = blocked_names | unhealthy_names
include_wildcard_routes: Final = _includes_wildcard_routes(return_wildcard_routes, settings)
# If scope=expand and user has admin privileges, return all proxy models
if should_expand_scope:
# Get all proxy models as if user is a proxy admin
@ -11631,7 +11647,7 @@ async def model_list(
proxy_model_list=proxy_model_list,
user_model=None,
infer_model_from_keys=False,
return_wildcard_routes=return_wildcard_routes or False,
return_wildcard_routes=include_wildcard_routes,
llm_router=llm_router,
model_access_groups=model_access_groups,
include_model_access_groups=include_model_access_groups or False,
@ -11691,7 +11707,7 @@ async def model_list(
team_id=team_id,
include_model_access_groups=include_model_access_groups or False,
only_model_access_groups=only_model_access_groups or False,
return_wildcard_routes=return_wildcard_routes or False,
return_wildcard_routes=include_wildcard_routes,
user_api_key_cache=user_api_key_cache,
)
@ -11755,6 +11771,7 @@ async def model_info(
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
team_id: str | None = None,
healthy_only: bool | None = False,
return_wildcard_routes: bool | None = None,
):
"""
Retrieve information about a specific model accessible to your API key.
@ -11789,7 +11806,7 @@ async def model_info(
team_id=team_id,
include_model_access_groups=False,
only_model_access_groups=False,
return_wildcard_routes=False,
return_wildcard_routes=_includes_wildcard_routes(return_wildcard_routes, settings),
user_api_key_cache=user_api_key_cache,
)
@ -18176,6 +18193,7 @@ _GENERAL_SETTINGS_CONFIG_LIST_FIELD_TYPES: Final[Mapping[str, str]] = MappingPro
"apply_user_budget_to_team_keys": "Boolean",
"user_api_key_cache_max_size": "Integer",
"transcribe_media_buckets": "List",
"model_list_return_wildcard_routes": "Boolean",
}
)

View file

@ -478,11 +478,12 @@ async def cursor_model_list(
verify models via `GET {base}/models` (the OpenAI SDK contract). Without this
route those requests fall through to the Cursor Cloud Agents passthrough, which
demands a Cursor API key and 401s, so key verification silently fails before any
chat request is ever sent. Delegates to the standard `/v1/models` handler.
chat request is ever sent. Delegates to the standard `/v1/models` handler with
wildcard routes left out, since Cursor offers every listed id as a callable model.
"""
from litellm.proxy.proxy_server import model_list
return await model_list(user_api_key_dict=user_api_key_dict)
return await model_list(user_api_key_dict=user_api_key_dict, return_wildcard_routes=False)
@router.post(

View file

@ -73,6 +73,7 @@
- {id: mgmt.callback.list.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "callback_management_endpoints.py", rationale: "Callback config (smoke)"}
- {id: mgmt.cost_tracking.estimate.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "cost_tracking_settings.py", rationale: "Cost estimate (smoke)"}
- {id: mgmt.router_settings.update.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "router_settings_endpoints.py", rationale: "Router config (smoke)"}
- {id: mgmt.general_settings.model_list_return_wildcard_routes.persists, module: mgmt, tier: P1, surface: api, assertions: [persists], source: "proxy_server.py:model_list", rationale: "The admin-set default lists wildcard routes in /v1/models on every replica, and return_wildcard_routes=false still leaves them out"}
- {id: mgmt.jwt_key_mapping.new.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "jwt_key_mapping_endpoints.py", rationale: "JWT->key mapping (smoke)"}
- {id: mgmt.compliance.gdpr.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "compliance_endpoints.py", rationale: "GDPR ops (smoke)"}
- {id: mgmt.tool_management.list.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "tool_management_endpoints.py", rationale: "Tool inventory (smoke)"}

View file

@ -0,0 +1,127 @@
"""Live e2e: `general_settings.model_list_return_wildcard_routes`, the proxy-wide
default for whether GET /v1/models lists a wildcard route such as `openai/*` next to
the models it expands to.
The setting is written through /config/field/update, the route behind the admin UI's
General Settings toggle, and teardown puts back whatever the database held before, so
the shared proxy ends the test the way it started. The other listings the suites run either pass
return_wildcard_routes explicitly or only check that a named model is present, so the
window with the setting on changes none of them. The wildcard deployment gets a unique prefix instead of `openai/*`, which would
claim every `openai/...` request the other suites send.
"""
from __future__ import annotations
from typing import Final, Literal
import pytest
from pydantic import BaseModel, ConfigDict, JsonValue, RootModel
from e2e_config import unique_marker
from e2e_http import NoBody, Success, unwrap
from lifecycle import ResourceManager
from management_client import ManagementClient
from models import ConfigListParams, LiteLLMParamsBody, ModelsListParams, ModelsListResponse
pytestmark = pytest.mark.e2e
_SETTING: Final = "model_list_return_wildcard_routes"
_DUMMY_API_KEY: Final = "e2e-dummy-key"
class ConfigFieldUpdateBody(BaseModel):
field_name: str
field_value: JsonValue
config_type: str = "general_settings"
class ConfigFieldDeleteBody(BaseModel):
field_name: str
config_type: str = "general_settings"
class StoredField(BaseModel):
model_config = ConfigDict(extra="ignore")
field_name: str
field_value: JsonValue = None
source: Literal["config", "db", "env", "default", "unset"] = "unset"
class StoredFieldList(RootModel[tuple[StoredField, ...]]):
pass
def _write_setting(client: ManagementClient, value: JsonValue) -> None:
_ = unwrap(
client.proxy.transport.post(
"/config/field/update",
headers=client.proxy.transport.master,
json=ConfigFieldUpdateBody(field_name=_SETTING, field_value=value),
response_type=NoBody,
)
)
def _delete_setting(client: ManagementClient) -> None:
_ = unwrap(
client.proxy.transport.post(
"/config/field/delete",
headers=client.proxy.transport.master,
json=ConfigFieldDeleteBody(field_name=_SETTING),
response_type=NoBody,
)
)
def _stored_setting(client: ManagementClient) -> StoredField | None:
fields: Final = unwrap(
client.proxy.transport.get(
"/config/list",
headers=client.proxy.transport.master,
params=ConfigListParams(config_type="general_settings"),
response_type=StoredFieldList,
)
).root
return next((field for field in fields if field.field_name == _SETTING and field.source == "db"), None)
def _restore_setting(client: ManagementClient, stored: StoredField | None) -> None:
if stored is None:
_delete_setting(client)
return
_write_setting(client, stored.field_value)
def _await_listing(client: ManagementClient, pattern: str, query: BaseModel, *, listed: bool) -> None:
"""Poll /v1/models under `query` on every replica until each one lists `pattern`,
or each one leaves it out, per `listed`."""
_ = client.proxy.read_back_everywhere(
"/v1/models",
params=query,
response_type=ModelsListResponse,
converged=lambda result: (
isinstance(result, Success) and any(entry.id == pattern for entry in result.data.data) is listed
),
)
class TestModelListWildcardRoutesSetting:
@pytest.mark.covers("mgmt.general_settings.model_list_return_wildcard_routes.persists")
def test_setting_lists_wildcard_route_unless_request_opts_out(
self, client: ManagementClient, resources: ResourceManager
) -> None:
pattern = f"e2e-wildcard-{unique_marker()}/*"
model_id = client.proxy.create_model(pattern, LiteLLMParamsBody(model="openai/*", api_key=_DUMMY_API_KEY))
resources.defer(lambda: client.proxy.delete_model(model_id))
stored: Final = _stored_setting(client)
resources.defer(lambda: _restore_setting(client, stored))
_write_setting(client, False)
_await_listing(client, pattern, NoBody(), listed=False)
_write_setting(client, True)
_await_listing(client, pattern, NoBody(), listed=True)
_await_listing(client, pattern, ModelsListParams(return_wildcard_routes=False), listed=False)
_delete_setting(client)
_await_listing(client, pattern, NoBody(), listed=False)

View file

@ -1351,6 +1351,9 @@ def test_cursor_models_route_delegates_to_model_list():
assert response.status_code == 200, f"{path}: {response.text}"
assert response.json() == model_payload
assert mock_model_list.call_count == 2
assert all(call.kwargs["return_wildcard_routes"] is False for call in mock_model_list.call_args_list), (
"Cursor offers every listed id, so model_list_return_wildcard_routes must not reach it"
)
finally:
app.dependency_overrides.pop(user_api_key_auth, None)

View file

@ -3108,3 +3108,139 @@ def test_get_litellm_model_info(data):
):
get_litellm_model_info(model=model)
get_info_mock.assert_called_once_with(data["expected"])
@pytest.fixture
def openai_wildcard_router(monkeypatch: pytest.MonkeyPatch) -> litellm.Router:
router = litellm.Router(
model_list=[
{"model_name": "gpt-4o", "litellm_params": {"model": "openai/gpt-4o", "api_key": "sk-fake"}},
{"model_name": "openai/*", "litellm_params": {"model": "openai/*", "api_key": "sk-fake"}},
]
)
monkeypatch.setattr(litellm.proxy.proxy_server, "llm_router", router)
monkeypatch.setattr(litellm.proxy.proxy_server, "llm_model_list", router.model_list)
monkeypatch.setattr(litellm.proxy.proxy_server, "prisma_client", None)
monkeypatch.setattr(litellm.proxy.proxy_server, "user_model", None)
return router
async def _listed_model_ids(
monkeypatch: pytest.MonkeyPatch,
general_settings: dict[str, object],
user_role: LitellmUserRoles,
**query: str | bool,
) -> list[str]:
monkeypatch.setattr(litellm.proxy.proxy_server, "general_settings", general_settings)
response = await litellm.proxy.proxy_server.model_list(
user_api_key_dict=UserAPIKeyAuth(api_key="sk-test", user_role=user_role), **query
)
return [model["id"] for model in response["data"]]
@pytest.mark.parametrize("setting", [True, "true"])
@pytest.mark.parametrize(
"user_role, query",
[(LitellmUserRoles.INTERNAL_USER, {}), (LitellmUserRoles.PROXY_ADMIN, {"scope": "expand"})],
)
@pytest.mark.asyncio
async def test_model_list_return_wildcard_routes_setting_matches_query_param(
openai_wildcard_router, monkeypatch, user_role, query, setting
):
requested = await _listed_model_ids(monkeypatch, {}, user_role, return_wildcard_routes=True, **query)
from_setting = await _listed_model_ids(
monkeypatch, {"model_list_return_wildcard_routes": setting}, user_role, **query
)
assert "openai/*" in from_setting, from_setting
assert from_setting == requested
@pytest.mark.parametrize(
"general_settings, query",
[
({}, {}),
({"model_list_return_wildcard_routes": "false"}, {}),
({"model_list_return_wildcard_routes": "True"}, {}),
({"model_list_return_wildcard_routes": 1}, {}),
({"model_list_return_wildcard_routes": True}, {"return_wildcard_routes": False}),
],
)
@pytest.mark.asyncio
async def test_model_list_leaves_out_wildcard_routes_unless_enabled(
openai_wildcard_router, monkeypatch, general_settings, query
):
listed = await _listed_model_ids(monkeypatch, general_settings, LitellmUserRoles.INTERNAL_USER, **query)
assert "gpt-4o" in listed, listed
assert "openai/*" not in listed, listed
async def _model_info_resolves(model_id: str, **query: bool) -> bool:
from fastapi import HTTPException
try:
response = await litellm.proxy.proxy_server.model_info(
model_id=model_id,
user_api_key_dict=UserAPIKeyAuth(api_key="sk-test", user_role=LitellmUserRoles.INTERNAL_USER),
**query,
)
except HTTPException as e:
if e.status_code != 404:
raise
return False
return response["id"] == model_id
@pytest.mark.parametrize(
"general_settings, query, wildcard_listed",
[
({}, {}, False),
({"model_list_return_wildcard_routes": True}, {}, True),
({"model_list_return_wildcard_routes": "true"}, {}, True),
({"model_list_return_wildcard_routes": True}, {"return_wildcard_routes": False}, False),
({}, {"return_wildcard_routes": True}, True),
],
)
@pytest.mark.asyncio
async def test_model_info_resolves_exactly_the_ids_model_list_lists(
openai_wildcard_router, monkeypatch, general_settings, query, wildcard_listed
):
listed = await _listed_model_ids(monkeypatch, general_settings, LitellmUserRoles.INTERNAL_USER, **query)
resolvable = [model_id for model_id in ("gpt-4o", "openai/*") if await _model_info_resolves(model_id, **query)]
assert ("openai/*" in listed) is wildcard_listed, listed
assert resolvable == [model_id for model_id in ("gpt-4o", "openai/*") if model_id in listed], (listed, resolvable)
@pytest.mark.asyncio
async def test_model_list_return_wildcard_routes_is_an_admin_ui_toggle(openai_wildcard_router, monkeypatch):
stored_general_settings: Final = {"model_list_return_wildcard_routes": True}
config_table: Final = MagicMock()
config_table.find_first = AsyncMock(
side_effect=lambda where: (
MagicMock(param_value=stored_general_settings) if where["param_name"] == "general_settings" else None
)
)
ui_prisma_client: Final = MagicMock()
ui_prisma_client.db.litellm_config = config_table
monkeypatch.setattr(litellm.proxy.proxy_server, "general_settings", {})
monkeypatch.setattr(litellm.proxy.proxy_server, "proxy_config", ProxyConfig())
await litellm.proxy.proxy_server.proxy_config._update_general_settings(stored_general_settings)
monkeypatch.setattr(litellm.proxy.proxy_server, "prisma_client", ui_prisma_client)
ui_fields: Final = {
field.field_name: field
for field in await litellm.proxy.proxy_server.get_config_list(
config_type="general_settings",
user_api_key_dict=UserAPIKeyAuth(api_key="sk-test", user_role=LitellmUserRoles.PROXY_ADMIN),
)
}
monkeypatch.setattr(litellm.proxy.proxy_server, "prisma_client", None)
response: Final = await litellm.proxy.proxy_server.model_list(
user_api_key_dict=UserAPIKeyAuth(api_key="sk-test", user_role=LitellmUserRoles.INTERNAL_USER)
)
toggle: Final = ui_fields["model_list_return_wildcard_routes"]
assert (toggle.field_type, toggle.field_value, toggle.stored_in_db) == ("Boolean", True, True)
assert "openai/*" in [model["id"] for model in response["data"]]

View file

@ -157,6 +157,35 @@ describe("modelInfoCall", () => {
});
});
describe("modelAvailableCall", () => {
let currentFetch: typeof global.fetch;
beforeEach(() => {
currentFetch = global.fetch;
});
afterEach(() => {
global.fetch = currentFetch;
});
it.each([
[undefined, "False"],
[false, "False"],
[true, "True"],
])("sends return_wildcard_routes=%s as %s", async (returnWildcardRoutes, sent) => {
const mockFetch = vi
.fn()
.mockResolvedValue({ ok: true, text: vi.fn().mockResolvedValue(JSON.stringify({ data: [] })) } as any);
global.fetch = mockFetch as any;
await Networking.modelAvailableCall("token", "user", "Admin", returnWildcardRoutes);
const parsed = new URL(mockFetch.mock.calls[0][0] as string, "http://example.com");
expect(parsed.pathname).toBe("/models");
expect(parsed.searchParams.get("return_wildcard_routes")).toBe(sent);
});
});
describe("daily activity helpers", () => {
const startTime = new Date("2025-02-12T00:00:00.000Z");
const endTime = new Date("2025-02-19T00:00:00.000Z");

View file

@ -1916,7 +1916,7 @@ export const modelAvailableCall = async (
accessToken,
query: {
include_model_access_groups: "True",
return_wildcard_routes: return_wildcard_routes === true ? "True" : undefined,
return_wildcard_routes: return_wildcard_routes === true ? "True" : "False",
only_model_access_groups: only_model_access_groups === true ? "True" : undefined,
team_id: teamID || undefined,
scope: scope || undefined,

View file

@ -3761,7 +3761,8 @@ export interface paths {
* verify models via `GET {base}/models` (the OpenAI SDK contract). Without this
* route those requests fall through to the Cursor Cloud Agents passthrough, which
* demands a Cursor API key and 401s, so key verification silently fails before any
* chat request is ever sent. Delegates to the standard `/v1/models` handler.
* chat request is ever sent. Delegates to the standard `/v1/models` handler with
* wildcard routes left out, since Cursor offers every listed id as a callable model.
*/
get: operations["cursor_model_list_cursor_models_get"];
put?: never;
@ -3787,7 +3788,8 @@ export interface paths {
* verify models via `GET {base}/models` (the OpenAI SDK contract). Without this
* route those requests fall through to the Cursor Cloud Agents passthrough, which
* demands a Cursor API key and 401s, so key verification silently fails before any
* chat request is ever sent. Delegates to the standard `/v1/models` handler.
* chat request is ever sent. Delegates to the standard `/v1/models` handler with
* wildcard routes left out, since Cursor offers every listed id as a callable model.
*/
get: operations["cursor_model_list_cursor_v1_models_get"];
put?: never;
@ -10086,6 +10088,10 @@ export interface paths {
* This is just for compatibility with openai projects like aider.
*
* Query Parameters:
* - return_wildcard_routes: When true, also list wildcard routes (e.g. `openai/*`)
* next to the models they expand to. Defaults to
* `general_settings.model_list_return_wildcard_routes`, which is
* false unless set; pass `false` to leave them out regardless.
* - include_metadata: Include additional metadata in the response with fallback information
* - fallback_type: Type of fallbacks to include ("general", "context_window", "content_policy")
* Defaults to "general" when include_metadata=true
@ -20502,6 +20508,10 @@ export interface paths {
* This is just for compatibility with openai projects like aider.
*
* Query Parameters:
* - return_wildcard_routes: When true, also list wildcard routes (e.g. `openai/*`)
* next to the models they expand to. Defaults to
* `general_settings.model_list_return_wildcard_routes`, which is
* false unless set; pass `false` to leave them out regardless.
* - include_metadata: Include additional metadata in the response with fallback information
* - fallback_type: Type of fallbacks to include ("general", "context_window", "content_policy")
* Defaults to "general" when include_metadata=true
@ -28973,6 +28983,11 @@ export interface components {
* @description When true, `/models`, `/v1/models/{id}` and `/model/info` hide models whose backing deployments are all unhealthy, for every caller, without needing `healthy_only=true` per request. Requires `background_health_checks: true`, and keeps deployment health state cached without turning on `enable_health_check_routing`, so routing is unaffected. With no health state nothing is hidden. Hiding is presentation-only, a hidden model can still be called.
*/
model_list_healthy_only?: boolean | null;
/**
* Model List Return Wildcard Routes
* @description When true, `/v1/models` lists wildcard routes such as `openai/*` next to the models they expand to, without the caller passing `return_wildcard_routes=true`. A request that passes `return_wildcard_routes=false` still leaves them out, as do the dashboard's model pickers and `/cursor/v1/models`.
*/
model_list_return_wildcard_routes?: boolean | null;
/**
* Otel
* @description [BETA] OpenTelemetry support - this might change, use with caution.
@ -62172,6 +62187,7 @@ export interface operations {
query?: {
team_id?: string | null;
healthy_only?: boolean | null;
return_wildcard_routes?: boolean | null;
};
header?: never;
path: {
@ -75764,6 +75780,7 @@ export interface operations {
query?: {
team_id?: string | null;
healthy_only?: boolean | null;
return_wildcard_routes?: boolean | null;
};
header?: never;
path: {