- test_tool_message_output_is_string_not_list: verifies function_call_output.output is a string
- test_multiple_tool_calls_in_single_choice: verifies multiple tool calls are grouped in one choice
Fixes two bugs in the openai/responses/... completion bridge:
1. function_call_output.output must be a string, not a list
- When sending tool results back to the model, the content was being
transformed to [{type: "output_text", text: "..."}] instead of a plain string
- This caused OpenAI to reject with "Invalid value: 'output_text'"
2. Multiple tool calls must be in a single choice, not separate choices
- When the model returned multiple tool calls, each was put in its own
Choice with index 0, 1, 2... instead of all together in one Choice
- This broke the standard Chat Completions API format where all tool_calls
belong in a single message
Fixes#18201
* fix: enforce team member budget check in common_checks
- Add missing team member budget validation in common_checks() function
- Checks team membership budget when team key is used
- Raises BudgetExceededError when team member spend exceeds max_budget_in_team
- Follows same pattern as other budget checks (team, user, end_user)
- Uses cached get_team_membership() for performance
- Fix AttributeError in lowest_tpm_rpm.py
- Add null check for model_info before accessing .get() method
- Prevents 'NoneType' object has no attribute 'get' error
- Add unit tests for team member budget enforcement
- Test budget exceeded scenario
- Test within budget scenario
- Test edge cases (no budget, no membership, personal keys)
- Tests run without requiring proxy server
Fixes failing test: test_users_in_team_budget
* fix: mock get_async_httpx_client in test_langsmith_key_based_logging
- Mock get_async_httpx_client to return a mock AsyncHTTPHandler instance
- Fixes test failure where mock_post was never called
- LangsmithLogger creates its own httpx client instance via get_async_httpx_client,
so we need to mock the factory function rather than the class method
- Use MagicMock for response.raise_for_status (sync method) instead of AsyncMock
* fix: resolve linting errors (PLR0915, F401)
- Remove unused imports (datetime, ServiceLoggerPayload) from arize_phoenix.py
- Extract health ping setup logic from RedisCache.__init__ to reduce statement count
- Extract team member budget check from common_checks to reduce statement count
* fix: resolve type errors in ChatCompletionToolCallChunk construction
- Cast type field to Literal['function'] to satisfy TypedDict requirements
- Ensure arguments field is explicitly str type to match TypedDict signature
- Fixes pyright errors for incompatible types in transformation.py
* Add monitor mode support to Lakera guardrail
- Add on_flagged parameter to LakeraV2GuardrailConfigModel (default: 'block')
- Support 'monitor' mode that logs violations without blocking requests
- Support 'block' mode (default) that raises HTTPException on violations
- Update async_pre_call_hook and async_moderation_hook to check on_flagged
- Update guardrail initializer to pass on_flagged from config
- Add documentation with monitor mode examples
This allows users to tune Lakera security policies by monitoring violations
without blocking legitimate requests, similar to Pillar's on_flagged_action.
* Add tests for Lakera guardrail monitor mode
- Test monitor mode allows flagged content through (pre_call hook)
- Test block mode raises HTTPException for violations (pre_call hook)
- Test monitor mode works with during_call (moderation_hook)
These tests verify the on_flagged parameter functionality for both
monitor and block modes across different guardrail hooks.
---------
Co-authored-by: Steve <steve.giguere@lakera.ai>
* feat(litellm_content_filter.py): add support for content filtering categories
make it easy for proxy admin to prevent messages about violence, self harm or illegal weapons going through litellm
* feat: initial commit adding bias detection
allows admin to block inappropriate content about sexual orientation, etc.
* refactor: simplify content_filter.py
use a more exhaustive set of keywords, instead of guessing at potential phrases user can use
* feat(content_filter.py): add new denied topics for in-built content filter guardrails
allow user to automatically block content relating to certain categories from being sent to the LLML
* refactor(content-filter): document new params to litellm content filter
* feat(ui/): litellm content filter - select content categories on ui
* docs: update documentation
* docs(litellm_content_filter.md): document new content filters
* feat: initial commit adding support for inappropriate images via litellm content filter
* feat(content_filter.py): support blocking images containing blocked content
prevent images which contain disallowed content from being sent to the llm api
* docs(litellm_content_filter.md): document new image capabilities of litellm_content_filter
* fix: fix expected error code
* feat(litellm_content_filter.py): add support for content filtering categories
make it easy for proxy admin to prevent messages about violence, self harm or illegal weapons going through litellm
* feat: initial commit adding bias detection
allows admin to block inappropriate content about sexual orientation, etc.
* refactor: simplify content_filter.py
use a more exhaustive set of keywords, instead of guessing at potential phrases user can use
* feat(content_filter.py): add new denied topics for in-built content filter guardrails
allow user to automatically block content relating to certain categories from being sent to the LLML
* refactor(content-filter): document new params to litellm content filter
* feat(ui/): litellm content filter - select content categories on ui
* docs: update documentation
* docs(litellm_content_filter.md): document new content filters