From a17efa1c8e13d28d5f00d6a4fc5ba515d845313f Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 5 Feb 2026 14:43:48 -0800 Subject: [PATCH 1/3] Add soft_budget to team table and create update endpoints --- .../litellm_proxy_extras/schema.prisma | 1 + litellm/proxy/_types.py | 2 + .../management_endpoints/team_endpoints.py | 46 +++ litellm/proxy/schema.prisma | 1 + schema.prisma | 1 + .../test_team_endpoints.py | 285 ++++++++++++++++++ 6 files changed, 336 insertions(+) diff --git a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma index dc49036cb1..e713e6ca87 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma +++ b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma @@ -113,6 +113,7 @@ model LiteLLM_TeamTable { members_with_roles Json @default("{}") metadata Json @default("{}") max_budget Float? + soft_budget Float? spend Float @default(0.0) models String[] max_parallel_requests Int? diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 131a6caab0..5b697249a4 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1488,6 +1488,7 @@ class TeamBase(LiteLLMPydanticObjectBase): # Budget fields max_budget: Optional[float] = None + soft_budget: Optional[float] = None budget_duration: Optional[str] = None models: list = [] @@ -1559,6 +1560,7 @@ class UpdateTeamRequest(LiteLLMPydanticObjectBase): tpm_limit: Optional[int] = None rpm_limit: Optional[int] = None max_budget: Optional[float] = None + soft_budget: Optional[float] = None models: Optional[list] = None blocked: Optional[bool] = None budget_duration: Optional[str] = None diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index 63db2d72fe..8e903180ac 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -685,6 +685,7 @@ async def new_team( # noqa: PLR0915 - rpm_limit_type: Optional[Literal["guaranteed_throughput", "best_effort_throughput"]] - The type of RPM limit enforcement. Use "guaranteed_throughput" to raise an error if overallocating RPM, or "best_effort_throughput" for best effort enforcement. - tpm_limit_type: Optional[Literal["guaranteed_throughput", "best_effort_throughput"]] - The type of TPM limit enforcement. Use "guaranteed_throughput" to raise an error if overallocating TPM, or "best_effort_throughput" for best effort enforcement. - max_budget: Optional[float] - The maximum budget allocated to the team - all keys for this team_id will have at max this max_budget + - soft_budget: Optional[float] - The soft budget threshold for the team. If max_budget is set, soft_budget must be strictly lower than max_budget. Can be set independently if max_budget is not set. - budget_duration: Optional[str] - The duration of the budget for the team. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) - models: Optional[list] - A list of models associated with the team - all keys for this team_id will have at most, these models. If empty, assumes all models are allowed. - blocked: bool - Flag indicating if the team is blocked or not - will stop all calls from keys with this team_id. @@ -760,6 +761,22 @@ async def new_team( # noqa: PLR0915 status_code=400, detail={"error": f"team_member_budget cannot be negative. Received: {data.team_member_budget}"} ) + if data.soft_budget is not None and data.soft_budget < 0: + raise HTTPException( + status_code=400, + detail={"error": f"soft_budget cannot be negative. Received: {data.soft_budget}"} + ) + + if data.soft_budget is not None: + if data.max_budget is not None: + # If max_budget is set, soft_budget must be strictly lower than max_budget + if data.soft_budget >= data.max_budget: + raise HTTPException( + status_code=400, + detail={ + "error": f"soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({data.max_budget})" + } + ) # Check if license is over limit total_teams = await prisma_client.db.litellm_teamtable.count() @@ -1226,6 +1243,7 @@ async def update_team( # noqa: PLR0915 - tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for this team - all keys with this team_id will have at max this TPM limit - rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for this team - all keys associated with this team_id will have at max this RPM limit - max_budget: Optional[float] - The maximum budget allocated to the team - all keys for this team_id will have at max this max_budget + - soft_budget: Optional[float] - The soft budget threshold for the team. If max_budget is set (either in the request or existing), soft_budget must be strictly lower than max_budget. Can be set independently if max_budget is not set. - budget_duration: Optional[str] - The duration of the budget for the team. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) - models: Optional[list] - A list of models associated with the team - all keys for this team_id will have at most, these models. If empty, assumes all models are allowed. - prompts: Optional[List[str]] - List of prompts that the team is allowed to use. @@ -1302,6 +1320,11 @@ async def update_team( # noqa: PLR0915 status_code=400, detail={"error": f"team_member_budget cannot be negative. Received: {data.team_member_budget}"} ) + if data.soft_budget is not None and data.soft_budget < 0: + raise HTTPException( + status_code=400, + detail={"error": f"soft_budget cannot be negative. Received: {data.soft_budget}"} + ) existing_team_row = await prisma_client.db.litellm_teamtable.find_unique( where={"team_id": data.team_id} @@ -1312,6 +1335,29 @@ async def update_team( # noqa: PLR0915 status_code=404, detail={"error": f"Team not found, passed team_id={data.team_id}"}, ) + + if data.soft_budget is not None: + max_budget_to_check = data.max_budget if data.max_budget is not None else existing_team_row.max_budget + if max_budget_to_check is not None: + if data.soft_budget >= max_budget_to_check: + raise HTTPException( + status_code=400, + detail={ + "error": f"soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({max_budget_to_check})" + } + ) + + if data.max_budget is not None: + existing_soft_budget = getattr(existing_team_row, 'soft_budget', None) + soft_budget_to_check = data.soft_budget if data.soft_budget is not None else existing_soft_budget + if soft_budget_to_check is not None and isinstance(soft_budget_to_check, (int, float)): + if data.max_budget <= soft_budget_to_check: + raise HTTPException( + status_code=400, + detail={ + "error": f"max_budget ({data.max_budget}) must be strictly greater than soft_budget ({soft_budget_to_check})" + } + ) if ( data.organization_id is not None and len(data.organization_id) > 0 diff --git a/litellm/proxy/schema.prisma b/litellm/proxy/schema.prisma index b118400b62..a6a573836b 100644 --- a/litellm/proxy/schema.prisma +++ b/litellm/proxy/schema.prisma @@ -113,6 +113,7 @@ model LiteLLM_TeamTable { members_with_roles Json @default("{}") metadata Json @default("{}") max_budget Float? + soft_budget Float? spend Float @default(0.0) models String[] max_parallel_requests Int? diff --git a/schema.prisma b/schema.prisma index 03b910db85..240e0dfea4 100644 --- a/schema.prisma +++ b/schema.prisma @@ -113,6 +113,7 @@ model LiteLLM_TeamTable { members_with_roles Json @default("{}") metadata Json @default("{}") max_budget Float? + soft_budget Float? spend Float @default(0.0) models String[] max_parallel_requests Int? diff --git a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py index 467ee3661d..7e351e2916 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py @@ -4931,6 +4931,291 @@ async def test_update_team_negative_team_member_budget(): assert request.team_member_budget == -15.0 +# Parametrized tests for soft_budget in create endpoint +@pytest.mark.parametrize( + "soft_budget,max_budget,should_succeed,expected_soft_budget,expected_max_budget,error_message", + [ + # Test 1: Soft budget only - success + soft budget set + (50.0, None, True, 50.0, None, None), + # Test 2: Soft budget with higher max budget, success with both set + (50.0, 100.0, True, 50.0, 100.0, None), + # Test 3: Soft budget with lower max budget, fail + (100.0, 50.0, False, None, None, "soft_budget (100.0) must be strictly lower than max_budget (50.0)"), + # Test 4: Soft budget equal to max budget, fail + (100.0, 100.0, False, None, None, "soft_budget (100.0) must be strictly lower than max_budget (100.0)"), + ], +) +@pytest.mark.asyncio +async def test_new_team_soft_budget_validation( + soft_budget, max_budget, should_succeed, expected_soft_budget, expected_max_budget, error_message +): + """ + Test soft_budget validation in /team/new endpoint. + + Covers: + - Soft budget only - success + soft budget set + - Soft budget with higher max budget, success with both set + - Soft budget with lower max budget, fail + """ + from fastapi import Request + + from litellm.proxy._types import NewTeamRequest, ProxyException, UserAPIKeyAuth + from litellm.proxy.management_endpoints.team_endpoints import new_team + + # Create admin user to bypass user budget checks + admin_user = UserAPIKeyAuth( + user_role=LitellmUserRoles.PROXY_ADMIN, + user_id="admin-user", + models=[], + ) + + # Create team request with soft_budget and optionally max_budget + team_request = NewTeamRequest( + team_alias="test-soft-budget-team", + soft_budget=soft_budget, + max_budget=max_budget, + ) + + dummy_request = MagicMock(spec=Request) + + with patch("litellm.proxy.proxy_server.prisma_client") as mock_prisma, patch( + "litellm.proxy.proxy_server.user_api_key_cache" + ) as mock_cache, patch( + "litellm.proxy.proxy_server._license_check" + ) as mock_license, patch( + "litellm.proxy.proxy_server.litellm_proxy_admin_name", "admin" + ), patch( + "litellm.proxy.proxy_server.create_audit_log_for_update", new=AsyncMock() + ) as mock_audit: + + # Setup mocks + mock_prisma.db.litellm_teamtable.count = AsyncMock(return_value=0) + mock_license.is_team_count_over_limit.return_value = False + mock_prisma.jsonify_team_object = lambda db_data: db_data + mock_prisma.get_data = AsyncMock(return_value=None) + mock_prisma.update_data = AsyncMock() + + # Mock user cache + from litellm.proxy._types import LiteLLM_UserTable + mock_user_obj = LiteLLM_UserTable( + user_id="admin-user", + max_budget=None, # Admin has no budget limit + ) + mock_cache.async_get_cache = AsyncMock(return_value=mock_user_obj) + + # Mock team creation + mock_created_team = MagicMock() + mock_created_team.team_id = "test-team-123" + mock_created_team.team_alias = "test-soft-budget-team" + mock_created_team.soft_budget = expected_soft_budget + mock_created_team.max_budget = expected_max_budget + mock_created_team.members_with_roles = [] + mock_created_team.metadata = None + mock_created_team.model_dump.return_value = { + "team_id": "test-team-123", + "team_alias": "test-soft-budget-team", + "soft_budget": expected_soft_budget, + "max_budget": expected_max_budget, + "members_with_roles": [], + } + mock_prisma.db.litellm_teamtable.create = AsyncMock(return_value=mock_created_team) + mock_prisma.db.litellm_teamtable.update = AsyncMock(return_value=mock_created_team) + + # Mock model table + mock_prisma.db.litellm_modeltable = MagicMock() + mock_prisma.db.litellm_modeltable.create = AsyncMock(return_value=MagicMock(id="model123")) + + # Mock user table operations + mock_user = MagicMock() + mock_user.user_id = "admin-user" + mock_user.model_dump.return_value = {"user_id": "admin-user", "teams": ["test-team-123"]} + mock_prisma.db.litellm_usertable = MagicMock() + mock_prisma.db.litellm_usertable.upsert = AsyncMock(return_value=mock_user) + mock_prisma.db.litellm_usertable.update = AsyncMock(return_value=mock_user) + + # Mock team membership table + mock_membership = MagicMock() + mock_membership.model_dump.return_value = { + "team_id": "test-team-123", + "user_id": "admin-user", + "budget_id": None, + } + mock_prisma.db.litellm_teammembership = MagicMock() + mock_prisma.db.litellm_teammembership.create = AsyncMock(return_value=mock_membership) + + if should_succeed: + # Should NOT raise an exception + result = await new_team( + data=team_request, + http_request=dummy_request, + user_api_key_dict=admin_user, + ) + + # Verify the team was created successfully with correct values + assert result is not None + assert result["team_id"] == "test-team-123" + if expected_soft_budget is not None: + assert result["soft_budget"] == expected_soft_budget + if expected_max_budget is not None: + assert result["max_budget"] == expected_max_budget + else: + # Should raise ProxyException + with pytest.raises(ProxyException) as exc_info: + await new_team( + data=team_request, + http_request=dummy_request, + user_api_key_dict=admin_user, + ) + + # Verify exception details + assert exc_info.value.code == '400' + if error_message: + assert error_message in str(exc_info.value.message) + + +# Parametrized tests for soft_budget in update endpoint +@pytest.mark.parametrize( + "existing_soft_budget,existing_max_budget,update_soft_budget,update_max_budget,should_succeed,expected_soft_budget,expected_max_budget,error_message", + [ + # Test 1: Soft budget only (no previous max_budget) - success with soft budget set + (None, None, 50.0, None, True, 50.0, None, None), + # Test 2: Soft budget with max budget - success if soft budget is strictly lower than max budget + (None, None, 50.0, 100.0, True, 50.0, 100.0, None), + # Test 3: Soft budget with max budget - fail if soft budget >= max budget + (None, None, 100.0, 50.0, False, None, None, "soft_budget (100.0) must be strictly lower than max_budget (50.0)"), + # Test 4: Only max budget with existing soft_budget, success with max_budget strictly greater + (50.0, None, None, 100.0, True, 50.0, 100.0, None), + # Test 5: Only max budget with existing soft_budget, fail if max_budget <= soft_budget + (50.0, None, None, 50.0, False, None, None, "max_budget (50.0) must be strictly greater than soft_budget (50.0)"), + # Test 6: Update both soft_budget and max_budget - success if soft < max + (30.0, 100.0, 40.0, 80.0, True, 40.0, 80.0, None), + # Test 7: Update both soft_budget and max_budget - fail if soft >= max + (30.0, 100.0, 80.0, 40.0, False, None, None, "soft_budget (80.0) must be strictly lower than max_budget (40.0)"), + ], +) +@pytest.mark.asyncio +async def test_update_team_soft_budget_validation( + existing_soft_budget, existing_max_budget, update_soft_budget, update_max_budget, + should_succeed, expected_soft_budget, expected_max_budget, error_message +): + """ + Test soft_budget validation in /team/update endpoint. + + Covers: + - Soft budget only (no previous max_budget) - success with soft budget set + - Soft budget with max budget - success if soft budget is strictly lower than max budget, fail otherwise + - Only max budget with existing soft_budget, success with max_budget strictly greater, fail otherwise + """ + from fastapi import Request + + from litellm.proxy._types import ( + LiteLLM_UserTable, + ProxyException, + UpdateTeamRequest, + UserAPIKeyAuth, + ) + from litellm.proxy.management_endpoints.team_endpoints import update_team + + # Create admin user to bypass user budget checks + admin_user = UserAPIKeyAuth( + user_role=LitellmUserRoles.PROXY_ADMIN, + user_id="admin-user", + models=[], + ) + + # Create update request + update_request = UpdateTeamRequest( + team_id="test-team-123", + soft_budget=update_soft_budget, + max_budget=update_max_budget, + ) + + dummy_request = MagicMock(spec=Request) + + with patch("litellm.proxy.proxy_server.prisma_client") as mock_prisma, patch( + "litellm.proxy.proxy_server.user_api_key_cache" + ) as mock_cache, patch( + "litellm.proxy.proxy_server.litellm_proxy_admin_name", "admin" + ), patch( + "litellm.proxy.proxy_server.create_audit_log_for_update", new=AsyncMock() + ) as mock_audit: + + # Mock existing team with existing budgets + mock_existing_team = MagicMock() + mock_existing_team.team_id = "test-team-123" + mock_existing_team.organization_id = None + mock_existing_team.soft_budget = existing_soft_budget + mock_existing_team.max_budget = existing_max_budget + mock_existing_team.model_dump.return_value = { + "team_id": "test-team-123", + "organization_id": None, + "soft_budget": existing_soft_budget, + "max_budget": existing_max_budget, + } + mock_prisma.db.litellm_teamtable.find_unique = AsyncMock(return_value=mock_existing_team) + + # Mock user cache + mock_user_obj = LiteLLM_UserTable( + user_id="admin-user", + max_budget=None, # Admin has no budget limit + ) + mock_cache.async_get_cache = AsyncMock(return_value=mock_user_obj) + + # Mock updated team - preserve existing values if not being updated + final_soft_budget = update_soft_budget if update_soft_budget is not None else existing_soft_budget + final_max_budget = update_max_budget if update_max_budget is not None else existing_max_budget + + mock_updated_team = MagicMock() + mock_updated_team.team_id = "test-team-123" + mock_updated_team.organization_id = None + mock_updated_team.soft_budget = final_soft_budget + mock_updated_team.max_budget = final_max_budget + mock_updated_team.model_dump.return_value = { + "team_id": "test-team-123", + "organization_id": None, + "soft_budget": final_soft_budget, + "max_budget": final_max_budget, + } + mock_prisma.db.litellm_teamtable.update = AsyncMock(return_value=mock_updated_team) + mock_prisma.jsonify_team_object = lambda db_data: db_data + mock_cache.async_set_cache = AsyncMock() # Mock cache set for _cache_team_object + + if should_succeed: + # Should NOT raise an exception + result = await update_team( + data=update_request, + http_request=dummy_request, + user_api_key_dict=admin_user, + ) + + # Verify the team was updated successfully with correct values + assert result is not None + assert result["data"].team_id == "test-team-123" + # Verify soft_budget matches expected value (or final computed value if expected is None) + if expected_soft_budget is not None: + assert result["data"].soft_budget == expected_soft_budget + else: + assert result["data"].soft_budget == final_soft_budget + # Verify max_budget matches expected value (or final computed value if expected is None) + if expected_max_budget is not None: + assert result["data"].max_budget == expected_max_budget + else: + assert result["data"].max_budget == final_max_budget + else: + # Should raise ProxyException + with pytest.raises(ProxyException) as exc_info: + await update_team( + data=update_request, + http_request=dummy_request, + user_api_key_dict=admin_user, + ) + + # Verify exception details + assert exc_info.value.code == '400' + if error_message: + assert error_message in str(exc_info.value.message) + + @pytest.mark.asyncio async def test_new_team_positive_budgets_accepted(): """ From 8b0d0b2610ec880d367569693f192faeae79c089 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 5 Feb 2026 14:46:38 -0800 Subject: [PATCH 2/3] =?UTF-8?q?bump:=20version=200.4.30=20=E2=86=92=200.4.?= =?UTF-8?q?31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- litellm-proxy-extras/pyproject.toml | 4 ++-- pyproject.toml | 2 +- requirements.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/litellm-proxy-extras/pyproject.toml b/litellm-proxy-extras/pyproject.toml index d43b591686..0e72cd9081 100644 --- a/litellm-proxy-extras/pyproject.toml +++ b/litellm-proxy-extras/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm-proxy-extras" -version = "0.4.30" +version = "0.4.31" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." authors = ["BerriAI"] readme = "README.md" @@ -22,7 +22,7 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "0.4.30" +version = "0.4.31" version_files = [ "pyproject.toml:version", "../requirements.txt:litellm-proxy-extras==", diff --git a/pyproject.toml b/pyproject.toml index 40ca400401..768a41d2e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ boto3 = { version = "1.40.76", optional = true } redisvl = {version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'"} mcp = {version = ">=1.25.0,<2.0.0", optional = true, python = ">=3.10"} a2a-sdk = {version = "^0.3.22", optional = true, python = ">=3.10"} -litellm-proxy-extras = {version = "0.4.30", optional = true} +litellm-proxy-extras = {version = "0.4.31", optional = true} rich = {version = "13.7.1", optional = true} litellm-enterprise = {version = "0.1.27", optional = true} diskcache = {version = "^5.6.1", optional = true} diff --git a/requirements.txt b/requirements.txt index aca27bf284..1fb8a22cc9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -50,7 +50,7 @@ sentry_sdk==2.21.0 # for sentry error handling detect-secrets==1.5.0 # Enterprise - secret detection / masking in LLM requests cryptography==44.0.1 tzdata==2025.1 # IANA time zone database -litellm-proxy-extras==0.4.30 # for proxy extras - e.g. prisma migrations +litellm-proxy-extras==0.4.31 # for proxy extras - e.g. prisma migrations llm-sandbox==0.3.31 # for skill execution in sandbox ### LITELLM PACKAGE DEPENDENCIES python-dotenv==1.0.1 # for env From 45c638266741076b4ec29b37731a56a10799c547 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 5 Feb 2026 14:47:11 -0800 Subject: [PATCH 3/3] cz bump + builds --- ...litellm_proxy_extras-0.4.31-py3-none-any.whl | Bin 0 -> 51624 bytes .../dist/litellm_proxy_extras-0.4.31.tar.gz | Bin 0 -> 23846 bytes .../migration.sql | 3 +++ 3 files changed, 3 insertions(+) create mode 100644 litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31-py3-none-any.whl create mode 100644 litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31.tar.gz create mode 100644 litellm-proxy-extras/litellm_proxy_extras/migrations/20260205144610_add_soft_budget_to_team_table/migration.sql diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..90b36bd78ac19e1f00a49ce5fb3d9c35cb9ad625 GIT binary patch literal 51624 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 a`SdR$WH7vqMK3}_jmqJb%Dqzb*Z%<1pY$>S literal 0 HcmV?d00001 diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.31.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..64607235479efeaea303c3fe519c55ee88629a26 GIT binary patch literal 23846 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 Z(T{%gqaXd~M?dR-{(r~;($)az0{~WDY4!jB literal 0 HcmV?d00001 diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260205144610_add_soft_budget_to_team_table/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260205144610_add_soft_budget_to_team_table/migration.sql new file mode 100644 index 0000000000..a64f1de342 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260205144610_add_soft_budget_to_team_table/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "LiteLLM_TeamTable" ADD COLUMN "soft_budget" DOUBLE PRECISION; +