- Add UTM params to all cloud-bound links across README, CLI, and error messages
- Rewrite README Open Source vs Cloud section: position cloud browsers as
recommended pairing for OSS users, remove separate Use Both section
- Rewrite error messages for use_cloud=True and ChatBrowserUse() to clearly
state what is wrong and what to do next
- Add missing URLs: invalid API key now links to key page, insufficient
credits now links to billing page
- Add cloud browser nudge on captcha detection (logger.warning)
- Add cloud browser nudge on local browser launch failure
litellm versions 1.82.7 and 1.82.8 were backdoored on March 24, 2026
by TeamPCP via a compromised Trivy CI/CD pipeline. browser-use 0.12.3
shipped litellm>=1.82.2 (unpinned) as a core dependency, exposing
~6,900 users to the backdoored versions during the 4-hour window.
This commit:
- Removes litellm entirely from pyproject.toml (core and optional)
- Keeps ChatLiteLLM wrapper intact with a docstring noting
`pip install litellm` is required separately
- litellm is already lazy-imported inside methods, so users who
don't use ChatLiteLLM are never affected
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OpenAI's completion_tokens already includes reasoning_tokens as a subset,
so adding them again was incorrectly inflating token counts by ~2x for
all reasoning models (o1, o3, o4-mini, etc.).
This aligns with other OpenAI-compatible providers (OpenRouter, Vercel,
Cerebras, Groq) which use completion_tokens directly.
Note: This is different from Google Gemini where thinking_tokens ARE
reported separately and need to be added.
Fixes#4065
Fix indentation so structured-output request executes even when add_schema_to_system_prompt is false; add regression tests for choices=null in both structured and non-structured paths.
Avoid indexing response.choices[0] when proxies return choices=null/empty; raise a clear ModelProviderError (with base_url hint) and use the validated first choice for content/finish_reason
- agent/views.py: Move RateLimitError import inside format_error() function
to avoid loading openai SDK (~800ms) at module level
- llm/messages.py: Replace openai.BaseModel with pydantic.BaseModel directly
to remove unnecessary openai dependency
- filesystem/file_system.py: Move reportlab imports inside sync_to_disk_sync()
to avoid ~40ms startup cost when PDF generation is not used
- utils.py: Convert OpenAIBadRequestError and GroqBadRequestError to lazy
loaders to avoid loading SDKs at module level
This improves import time for users who don't use OpenAI provider,
especially when using Anthropic, Google, or other providers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Content blocks are dictionaries at runtime despite type annotations
indicating Pydantic models. Added type: ignore comments to allow
dictionary-style .get() access which works correctly at runtime.
Previously, cache_control was applied to every content block and tool call
in a message, which could exceed Anthropic's limit of 4 cache breakpoints
per request. This fix ensures cache_control is only applied to the last
block in each message type:
- Last text block in UserMessage/AssistantMessage content
- Last tool_use block when AssistantMessage has tool calls
- Only the last overall block when AssistantMessage has both content and tools
This prevents exceeding the cache breakpoint limit while maintaining
correct caching behavior.